Attachment 'stcschan-demo2.c'

Download

   1 /* Name:
   2       stcschan-demo2.c
   3 
   4    Purpose:
   5       A demonstration of the facilities provided by the AST library 
   6       for reading STC metadata encoded using the STC-S linear string 
   7       format.
   8 
   9    Description:
  10       This program reads a set of FITS-WCS headers from a text file, and
  11       writes an STC-S description of the region covered by the FITS
  12       file to standard output.
  13 
  14    Notes:
  15       - The simple approach used in this demonstration will report an
  16       error if the FITS headers describe a WCS in which some pixels have
  17       invalid WCS axis values (such as most all sky maps, for instance).
  18 
  19    Usage:
  20       % stcschan-demo2 <header-file> 
  21 
  22       <header-file>: The path to a text file containing a set of FITS-WCS
  23       headers.
  24 
  25    Example:
  26       % stcschan-demo2 m31.head
  27 
  28    To compile and link:
  29       Assuming your starlink distribution is in "/star":
  30 
  31       % gcc -o stcschan-demo2 stcschan-demo2.c -L/star/lib \
  32             -I/star/include `ast_link`
  33 
  34 */
  35 
  36 /* Include system headers. */
  37 #include <stdio.h>
  38 #include <string.h>
  39 
  40 /* Include the AST library header. */
  41 #include "ast.h"
  42 
  43 /* Maximum number of axes in an STC-S AstroCoordSystem. */
  44 #define MAX_AXES 5
  45 
  46 /* Maximum allowed length for a single line of text from the disk file. */
  47 #define MAX_LINE_LEN 100
  48 
  49 /* Prototype for the function that reads text from the disk file. */
  50 const char *source( void );
  51 
  52 
  53 
  54 int main( int argc, char **argv ){
  55 
  56 /* Local variables: */
  57    AstBox *pixbox;
  58    AstFitsChan *fchan;
  59    AstFrame *pixfrm;
  60    AstFrame *wcsfrm;
  61    AstFrameSet *frameset;
  62    AstKeyMap *warnings;
  63    AstMapping *pix2wcs;
  64    AstObject *object;
  65    AstRegion *wcsbox;
  66    AstStcsChan *schan;
  67    FILE *fd;
  68    char key[ 15 ];
  69    char keyword[ 9 ];
  70    const char *message;
  71    double p1[ MAX_AXES ];
  72    double p2[ MAX_AXES ];
  73    int axis;
  74    int iwarn;
  75    int naxis;
  76    int status;
  77 
  78 /* Initialised the returned system status to indicate success. */
  79    status = 0;
  80 
  81 /* Check a file was specified on the command line, and attempt to open it
  82    for read access. */
  83    if( argc < 2 ) {
  84       printf( "Usage: stcschan-demo2 <header-file>\n" );
  85       status = 1;
  86    } else {
  87       fd = fopen( argv[ 1 ], "r" );
  88       if( !fd ) {
  89          printf("Failed to open input file '%s'.\n", argv[ 1 ] );
  90          status = 1;
  91       }
  92    }
  93 
  94 /* If a disk file was opened successfully... */
  95    if( !status ) {
  96 
  97 /* Start an AST object context. This means we do not need to annull 
  98    each AST Object individually. Instead, all Objects created within 
  99    this context will be annulled automatically by the corresponding
 100    invocation of astEnd. */
 101       astBegin;
 102 
 103 /* Create a FitsChan. This is the object that converts external FITS
 104    headers into corresponding AST Objects. Tell it to use the "source" 
 105    function for obtaining lines of text from the disk file. */
 106       fchan = astFitsChan( source, NULL, " " );
 107 
 108 /* Associate the descriptor for the input disk file with the StcsChan.
 109    This makes it available to the "source" function. Since this
 110    application is single threaded, we could instead have made "fd" a 
 111    global variable, but the ChannelData facility is used here to illustrate 
 112    how to pass data to a source or sink function safely in a multi-threaded 
 113    application. */
 114       astPutChannelData( fchan, fd );
 115 
 116 /* Attempt to read the FITS heades and convert them into an AST FrameSet. */
 117       object = astRead( fchan );
 118       
 119 /* The astRead function is a generic function and so returns a generic
 120    AstObject pointer. Check an Object was created successfully. */
 121       if( !object ) {
 122          printf( "Failed to read an AST Object from file '%s'.\n", 
 123                  argv[ 1 ] );
 124          status = 1;
 125 
 126 /* Now check that the object read is actually an AST FrameSet, rather than
 127    some other class of AST Object. */
 128       } else if( !astIsAFrameSet( object ) ) {      
 129          printf( "Expected a FrameSet but read a %s from file '%s'.\n", 
 130                  astGetC( object, "Class" ), argv[ 1 ] );
 131          status = 1;
 132 
 133 /* We now know we have a FrameSet so it is safe to use the pointer
 134    returned by astRead as a FrameSet pointer. Do the cast now to avoid
 135    repeated casting in future. */
 136       } else {
 137          frameset = (AstFrameSet *) object;      
 138 
 139 /* Get a pointer to the Frame that describes the attributes of the FITS 
 140    world coordinate system. This is the current Frame in the FrameSet
 141    read from the FITS headers. */
 142          wcsfrm = astGetFrame( frameset, AST__CURRENT );
 143 
 144 /* Get a pointer to the Frame that describes the attributes of the FITS 
 145    pixel coordinate system. This is the base Frame in the FrameSet
 146    read from the FITS headers. */
 147          pixfrm = astGetFrame( frameset, AST__BASE );
 148 
 149 /* Get the Mapping that transforms pixel positions into WCS positions.
 150    The is the Mapping from base to current Frame in the  FrameSet read 
 151    from the FITS headers. */
 152          pix2wcs = astGetMapping( frameset, AST__BASE, AST__CURRENT );
 153 
 154 /* Get the number of axes in ther pixel Frame. */
 155          naxis = astGetI( pixfrm, "Naxes" );
 156 
 157 /* For each pixel axis, form the name of the corresponding NAXISi
 158    keyword. */
 159          for( axis = 0; axis < naxis; axis++ ) { 
 160             sprintf( keyword, "NAXIS%d", axis + 1 );
 161 
 162 /* Store the pixel coordinate on the current axis at the lower left corner 
 163    of the first pixel. */
 164             p1[ axis ] = 0.5;
 165 
 166 /* Get the NAXISi value for the current axis from the FITS header, and
 167    store it in array "p2". Report an error if NAXISi is not found. */
 168             if( !astGetFitsF( fchan, keyword, p2 + axis ) ){
 169                printf("Keyword '%s' not found in header\n", keyword );
 170                status = 1;
 171                break;
 172 
 173 /* If it is found, modify "p2" so that it holds the pixel coordinate on
 174    the current axis at the upper right corner of the last pixel. */
 175             } else {
 176                p2[ axis ] += 0.5;
 177             }
 178          }
 179       }
 180 
 181 /* If all has gone well, create an AST Region (a Box) describing the
 182    rectangular region of pixel coordinates covered by the pixel array. */
 183       if( !status ) {
 184          pixbox = astBox( pixfrm, 1, p1, p2, NULL, " " );
 185 
 186 /* Map this box into the FITS world coordinate system. The Mapping is
 187    specified by "pix2wcs", and the attributes of the resulting axes is
 188    described by "wcsfrm". */
 189          wcsbox = astMapRegion( pixbox, pix2wcs, wcsfrm );
 190 
 191 /* Create an StcsChan. This is the object that converts (either way)
 192    between external STC-S descriptions and their corresponding AST Objects. 
 193    Tell it to use the "source" function for obtaining lines of text from 
 194    the disk file. Also tell it to store all warnings generated by the 
 195    conversion for later use. Other attributes of the StcsChan class retain 
 196    their default values. */
 197          schan = astStcsChan( NULL, NULL, "ReportLevel=3" );
 198 
 199 /* Attempt to write out the Region describing the pixel array (in WCS) 
 200    as an STC-S description. Report an error if this fails. */
 201          if( ! astWrite( schan, wcsbox ) && astOK ) {
 202             printf( "Failed to convert the Region into an STC-S "
 203                     "description.\n" );
 204          }
 205       }
 206 
 207 /* We asked the StcsChan to record any warnings that were generated
 208    whilst converting the AST Region into a corresponding STC-S description.
 209    We now see if any such warnings were generated by the earlier call to 
 210    astWrite. */
 211       warnings = astWarnings( schan );
 212 
 213 /* If any warnings were generated, and if no other error has occurred so
 214    far, display the warnings. */
 215       if( warnings && !status && astOK ) {
 216          printf( "\nThe following warnings were issued:\n" );
 217 
 218 /* The warnings are stored in an AST KeyMap (a sort of hashmap). Each
 219    warning message is associated with a key of the form "Warning_1",
 220    "Warning_2", etc. Loop round successive keys, obtaining a value for
 221    each key from the warnings KeyMap, and displaying it. */
 222          iwarn = 1;
 223          while( astOK ) {
 224             sprintf( key, "Warning_%d", iwarn++ );
 225             if( astMapGet0C( warnings, key, &message ) ) {
 226                printf( "\n- %s\n", message );
 227             } else {
 228                break;
 229             }
 230          }             
 231       }
 232 
 233 /* End the AST Object context. All Objects created since the
 234    corresponding invocation of astbegin will be annulled automatically. */
 235       astEnd;
 236 
 237 /* Close the disk file. */
 238       (void) fclose( fd );
 239    }
 240 
 241 /* If an error occurred in the AST library, set the retiurns system
 242    status non-zero. */
 243    if( !astOK ) status = 1;
 244    return status;
 245 }
 246 
 247 
 248 
 249 
 250 
 251 /* This is a function that reads a line of text from the disk file and
 252    returns it to the AST library. It is called from within the astRead
 253    function. */
 254 const char *source( void ){
 255    static char buffer[ MAX_LINE_LEN + 2 ];
 256    FILE *fd = astChannelData;
 257    return fgets( buffer, MAX_LINE_LEN + 2, fd );
 258 }
 259 
 260 
 261 
 262 
 263 
 264 

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.