Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://www.atnf.csiro.au/people/mcalabre/WCS/wcslib/fortran.html
Дата изменения: Unknown Дата индексирования: Sun Apr 10 18:37:39 2016 Кодировка: Поисковые слова: moon |
WCSLIB
5.15
|
The Fortran subdirectory contains wrappers, written in C, that allow Fortran programs to use WCSLIB.
A prerequisite for using the wrappers is an understanding of the usage of the associated C routines, in particular the data structures they are based on. The principle difficulty in creating the wrappers was the need to manage these C structs from within Fortran, particularly as they contain pointers to allocated memory, pointers to C functions, and other structs that themselves contain similar entities.
To this end, routines have been provided to set and retrieve values of the various structs, for example WCSPUT
and WCSGET
for the wcsprm struct, and CELPUT
and CELGET
for the celprm struct. These must be used in conjunction with wrappers on the routines provided to manage the structs in C, for example WCSINI
, WCSSUB
, WCSCOPY
, WCSFREE
, and WCSPRT
which wrap wcsini(), wcssub(), wcscopy(), wcsfree(), and wcsprt().
The various *PUT
and *GET
routines are based on codes defined in Fortran include files (*.inc), if your Fortran compiler does not support the INCLUDE
statement then you will need to include these manually wherever necessary. Codes are defined as parameters with names like WCS_CRPIX
which refers to wcsprm::crpix (if your Fortran compiler does not support long symbolic names then you will need to rename these).
The include files also contain parameters, such as WCSLEN
, that define the length of an INTEGER
array that must be declared to hold the struct. This length may differ for different platforms depending on how the C compiler aligns data within the structs. A test program for the C library, twcs, prints the size of the struct in sizeof(int) units and the values in the Fortran include files must equal or exceed these. On some platforms, such as Suns, it is important that the start of the INTEGER
array be aligned on a DOUBLE
PRECISION
boundary, otherwise a BUS
error may result. This may be achieved via an EQUIVALENCE
with a DOUBLE
PRECISION
variable, or by sequencing variables in a COMMON
block so that the INTEGER
array follows immediately after a DOUBLE
PRECISION
variable.
The *PUT
routines set only one element of an array at a time; the final one or two integer arguments of these routines specify 1-relative array indices (N.B. not 0-relative as in C). The one exception is the prjprm::pv array.
The *PUT
routines also reset the flag element to signal that the struct needs to be reinitialized. Therefore, if you wanted to set wcsprm::flag itself to -1 prior to the first call to WCSINI
, for example, then that WCSPUT
must be the last one before the call.
The *GET
routines retrieve whole arrays at a time and expect array arguments of the appropriate length where necessary. Note that they do not initialize the structs.
A basic coding fragment is
INTEGER LNGIDX, STATUS CHARACTER CTYPE1*72 INCLUDE 'wcs.inc' * WCSLEN is defined as a parameter in wcs.inc. INTEGER WCS(WCSLEN) DOUBLE PRECISION DUMMY EQUIVALENCE (WCS, DUMMY) * Allocate memory and set default values for 2 axes. STATUS = WCSPUT (WCS, WCS_FLAG, -1, 0, 0) STATUS = WCSINI (2, WCS) * Set CRPIX1, and CRPIX2; WCS_CRPIX is defined in wcs.inc. STATUS = WCSPUT (WCS, WCS_CRPIX, 512D0, 1, 0) STATUS = WCSPUT (WCS, WCS_CRPIX, 512D0, 2, 0) * Set PC1_2 to 5.0 (I = 1, J = 2). STATUS = WCSPUT (WCS, WCS_PC, 5D0, 1, 2) * Set CTYPE1 to 'RA---SIN'; N.B. must be given as CHARACTER*72. CTYPE1 = 'RA---SIN' STATUS = WCSPUT (WCS, WCS_CTYPE, CTYPE1, 1, 0) * Set PV1_3 to -1.0 (I = 1, M = 3). STATUS = WCSPUT (WCS, WCS_PV, -1D0, 1, 3) etc. * Initialize. STATUS = WCSSET (WCS) IF (STATUS.NE.0) THEN CALL FLUSH(6) STATUS = WCSPERR(WCS, CHAR(0)) ENDIF * Find the "longitude" axis. STATUS = WCSGET (WCS, WCS_LNG, LNGIDX) * Free memory. STATUS = WCSFREE (WCS)
Refer to the various Fortran test programs for further programming examples. In particular, twcs and twcsmix show how to retrieve elements of the celprm and prjprm structs contained within the wcsprm struct.
Note that the data type of the third argument to the *PUT
and *GET
routines differs depending on the data type of the corresponding C struct member, be it int, double, or char[]. It is essential that the Fortran data type match that of the C struct for int and double types, and be a CHARACTER
variable of the correct length for char[] types. Compilers (e.g. g77) may warn of inconsistent usage of this argument but this can (usually) be safely ignored. If these warnings become annoying, type-specific variants are provided for each of the *PUT
routines, *PTI
, *PTD
, and *PTC
for int, double, or char[] and likewise *GTI
, *GTD
, and *GTC
for the *GET
routines.
When calling wrappers for C functions that print to stdout, such as WCSPRT
, and WCSPERR
, or that may print to stderr, such as WCSPIH
, WCSBTH
, WCSULEXE
, or WCSUTRNE
, it may be necessary to flush the Fortran I/O buffers beforehand so that the output appears in the correct order. The wrappers for these functions do call fflush(NULL)
, but depending on the particular system, this may not succeed in flushing the Fortran I/O buffers. Most Fortran compilers provide the non-standard intrinsic FLUSH()
, which is called with unit number 6 to flush stdout (as in the example above), and unit 0 for stderr.
A basic assumption made by the wrappers is that an INTEGER
variable is no less than half the size of a DOUBLE
PRECISION
.