wcslib (8.2.2)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>WCSLIB: WCSLIB Fortran wrappers</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">WCSLIB<span id="projectnumber"> 8.2.2</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="index.html">WCSLIB 8.2.2 and PGSBOX 8.2.2</a></li> </ul>
</div>
</div><!-- top -->
<div><div class="header">
<div class="headertitle"><div class="title">WCSLIB Fortran wrappers</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>The Fortran subdirectory contains wrappers, written in C, that allow Fortran programs to use WCSLIB. The wrappers have no associated C header files, nor C function prototypes, as they are only meant to be called by Fortran code. Hence the C code must be consulted directly to determine the argument lists. This resides in files with names of the form <code>*_f</code>.c. However, there are associated Fortran <code>INCLUDE</code> files that declare function return types and various parameter definitions. There are also <code>BLOCK</code> <code>DATA</code> modules, in files with names of the form <code>*_data</code>.f, used solely to initialise error message strings.</p>
<p>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.</p>
<p>To this end, routines have been provided to set and retrieve values of the various structs, for example <code>WCSPUT</code> and <code>WCSGET</code> for the wcsprm struct, and <code>CELPUT</code> and <code>CELGET</code> for the celprm struct. These must be used in conjunction with wrappers on the routines provided to manage the structs in C, for example <code>WCSINIT</code>, <code>WCSSUB</code>, <code>WCSCOPY</code>, <code>WCSFREE</code>, and <code>WCSPRT</code> which wrap <a class="el" href="wcs_8h.html#aab11243b60b10065fc85347bb3efa912" title="Default constructor for the wcsprm struct.">wcsinit()</a>, <a class="el" href="wcs_8h.html#a864c99fef9f3eee29085ce42d0ee0d64" title="Subimage extraction routine for the wcsprm struct.">wcssub()</a>, <a class="el" href="wcs_8h.html#ac55946dadc53ac592cb686275902ae7b" title="Copy routine for the wcsprm struct.">wcscopy()</a>, <a class="el" href="wcs_8h.html#a4ab38bc642c4656f62c43acf84a849f1" title="Destructor for the wcsprm struct.">wcsfree()</a>, and <a class="el" href="wcs_8h.html#ab9aeb8cf1afb1bfb22e989580d90fca8" title="Print routine for the wcsprm struct.">wcsprt()</a>.</p>
<p>Compilers (e.g. gfortran) may warn of inconsistent usage of the third argument in the various <code>*PUT</code> and <code>*GET</code> routines, and as of gfortran 10, these warnings have been promoted to errors. Thus, type-specific variants are provided for each of the <code>*PUT</code> routines, <code>*PTI</code>, <code>*PTD</code>, and <code>*PTC</code> for <em>int</em>, <em>double</em>, or <em>char</em>[], and likewise <code>*GTI</code>, <code>*GTD</code>, and <code>*GTC</code> for the <code>*GET</code> routines. While, for brevity, we will here continue to refer to the <code>*PUT</code> and <code>*GET</code> routines, as compilers are generally becoming stricter, use of the type-specific variants is recommended.</p>
<p>The various <code>*PUT</code> and <code>*GET</code> routines are based on codes defined in Fortran include files (*.inc). If your Fortran compiler does not support the <code>INCLUDE</code> statement then you will need to include these manually in your code as necessary. Codes are defined as parameters with names like <code>WCS_CRPIX</code> which refers to <a class="el" href="structwcsprm.html#aadad828f07e3affd1511e533b00da19f">wcsprm::crpix</a> (if your Fortran compiler does not support long symbolic names then you will need to rename these).</p>
<p>The include files also contain parameters, such as <code>WCSLEN</code>, that define the length of an <code>INTEGER</code> 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, <em>twcs</em>, prints the size of the struct in <em>sizeof(int)</em> 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 <code>INTEGER</code> array be <em><b>aligned on a <code>DOUBLE</code> <code>PRECISION</code> boundary</b></em>, otherwise a mysterious <code>BUS</code> error may result. This may be achieved via an <code>EQUIVALENCE</code> with a <code>DOUBLE</code> <code>PRECISION</code> variable, or by sequencing variables in a <code>COMMON</code> block so that the <code>INTEGER</code> array follows immediately after a <code>DOUBLE</code> <code>PRECISION</code> variable.</p>
<p>The <code>*PUT</code> 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 <a class="el" href="structprjprm.html#a46d6928a9026e7b3376dcf0d3f91db64">prjprm::pv</a> array.</p>
<p>The <code>*PUT</code> routines also reset the <em>flag</em> element to signal that the struct needs to be reinitialized. Therefore, if you wanted to set <a class="el" href="structwcsprm.html#a35bff8de85e5a8892e1b68db69ca7a68">wcsprm::flag</a> itself to -1 prior to the first call to <code>WCSINIT</code>, for example, then that <code>WCSPUT</code> must be the last one before the call.</p>
<p>The <code>*GET</code> 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, i.e. via <a class="el" href="wcs_8h.html#ae5cc3f5d249755583403cdf54d2ebb91" title="Setup routine for the wcsprm struct.">wcsset()</a>, <a class="el" href="prj_8h.html#ad43dbc765c63162d0af2b9285b8a434f" title="Generic setup routine for the prjprm struct.">prjset()</a>, or whatever.</p>
<p>A basic coding fragment is</p>
<pre class="fragment"> 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 = WCSPTI (WCS, WCS_FLAG, -1, 0, 0)
STATUS = WCSINI (2, WCS)
* Set CRPIX1, and CRPIX2; WCS_CRPIX is defined in wcs.inc.
STATUS = WCSPTD (WCS, WCS_CRPIX, 512D0, 1, 0)
STATUS = WCSPTD (WCS, WCS_CRPIX, 512D0, 2, 0)
* Set PC1_2 to 5.0 (I = 1, J = 2).
STATUS = WCSPTD (WCS, WCS_PC, 5D0, 1, 2)
* Set CTYPE1 to 'RA---SIN'; N.B. must be given as CHARACTER*72.
CTYPE1 = 'RA---SIN'
STATUS = WCSPTC (WCS, WCS_CTYPE, CTYPE1, 1, 0)
* Use an alternate method to set CTYPE2.
STATUS = WCSPTC (WCS, WCS_CTYPE, 'DEC--SIN'//CHAR(0), 2, 0)
* Set PV1_3 to -1.0 (I = 1, M = 3).
STATUS = WCSPTD (WCS, WCS_PV, -1D0, 1, 3)
etc.
* Initialize.
STATUS = WCSSET (WCS)
IF (STATUS.NE.0) THEN
CALL FLUSH (6)
STATUS = WCSPERR (WCS, 'EXAMPLE: '//CHAR(0))
ENDIF
* Find the "longitude" axis.
STATUS = WCSGTI (WCS, WCS_LNG, LNGIDX)
* Free memory.
STATUS = WCSFREE (WCS)
</pre><p>Refer to the various Fortran test programs for further programming examples. In particular, <em>twcs</em> and <em>twcsmix</em> show how to retrieve elements of the celprm and prjprm structs contained within the wcsprm struct.</p>
<p>Treatment of <code>CHARACTER</code> arguments in wrappers such as <code>SPCTYPE</code>, <code>SPECX</code>, and <code>WCSSPTR</code>, depends on whether they are given or returned. Where a <code>CHARACTER</code> variable is returned, its length must match the declared length in the definition of the C wrapper. The terminating null character in the C string, and all following it up to the declared length, are replaced with blanks. If the Fortran <code>CHARACTER</code> variable were shorter than the declared length, an out-of-bounds memory access error would result. If longer, the excess, uninitialized, characters could contain garbage.</p>
<p>If the <code>CHARACTER</code> argument is given, a null-terminated <code>CHARACTER</code> variable may be provided as input, e.g. constructed using the Fortran <code>CHAR(0)</code> intrinsic as in the example code above. The wrapper makes a character-by-character copy, searching for a NULL character in the process. If it finds one, the copy terminates early, resulting in a valid C string. In this case any trailing blanks before the <code>NULL</code> character are preserved if it makes sense to do so, such as in setting a prefix for use by the <code>*PERR</code> wrappers, such as <code>WCSPERR</code> in the example above. If a NULL is not found, then the <code>CHARACTER</code> argument must be at least as long as the declared length, and any trailing blanks are stripped off. Should a <code>CHARACTER</code> argument exceed the declared length, the excess characters are ignored.</p>
<p>There is one exception to the above caution regarding <code>CHARACTER</code> arguments. The <code>WCSLIB_VERSION</code> wrapper is unusual in that it provides for the length of its <code>CHARACTER</code> argument to be specified, and only so many characters as fit within that length are returned.</p>
<p>Note that the data type of the third argument to the <code>*PUT</code> (or <code>*PTI</code>, <code>*PTD</code>, or <code>*PTC</code>) and <code>*GET</code> (or <code>*GTI</code>, <code>*GTD</code>, or <code>*GTC</code>) routines differs depending on the data type of the corresponding C struct member, be it <em>int</em>, <em>double</em>, or <em>char</em>[]. It is essential that the Fortran data type match that of the C struct for <em>int</em> and <em>double</em> types, and be a <code>CHARACTER</code> variable of the correct length for <em>char</em>[] types, or else be null-terminated, as in the coding example above. As a further example, in the two equivalent calls</p>
<pre class="fragment"> STATUS = PRJGET (PRJ, PRJ_NAME, NAME)
STATUS = PRJGTC (PRJ, PRJ_NAME, NAME)
</pre><p>which return a character string, <code>NAME</code> must be a <code>CHARACTER</code> variable of length 40, as declared in the prjprm struct, no less and no more, the comments above pertaining to wrappers that contain <code>CHARACTER</code> arguments also applying here. However, a few exceptions have been made to simplify coding. The relevant <code>*PUT</code> (or <code>*PTC</code>) wrappers allow unterminated <code>CHARACTER</code> variables of less than the declared length for the following: <code><a class="el" href="structprjprm.html#a4f3c364f16d0b6498d7e11e6bb67239c">prjprm::code</a></code> (3 characters), <code><a class="el" href="structspcprm.html#a387d74de3215763d7e22c222b19a2c44">spcprm::type</a></code> (4 characters), <code><a class="el" href="structspcprm.html#a5f9a48a52144f8ced93baaffc107a3a6">spcprm::code</a></code> (3 characters), and <code><a class="el" href="structfitskeyid.html#a9c19a56e7a92c1728bebd92e5370b9c7">fitskeyid::name</a></code> (8 characters). It doesn't hurt to specify longer <code>CHARACTER</code> variables, but the trailing characters will be ignored. Notwithstanding this simplification, the length of the corresponding variables in the <code>*GET</code> (or <code>*GTC</code>) wrappers must match the length declared in the struct.</p>
<p>When calling wrappers for C functions that print to <em>stdout</em>, such as <code>WCSPRT</code>, and <code>WCSPERR</code>, or that may print to <em>stderr</em>, such as <code>WCSPIH</code>, <code>WCSBTH</code>, <code>WCSULEXE</code>, or <code>WCSUTRNE</code>, 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 <code>fflush(NULL)</code>, 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 <code>FLUSH()</code>, which is called with unit number 6 to flush <em>stdout</em> (as in the example above), and unit 0 for <em>stderr</em>.</p>
<p>A basic assumption made by the wrappers is that an <code>INTEGER</code> variable is no less than half the size of a <code>DOUBLE</code> <code>PRECISION</code>. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Wed Nov 29 2023 19:09:57 for WCSLIB by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>