Attachment 'stcschan-demo1.c'

Download

   1 /* Name:
   2       stcschan-demo1.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 an STC-S description from a disk file, and
  11       tests a given position to see if it is inside or outside the 
  12       AstroCoordsArea specified by the STC-S description.
  13 
  14    Usage:
  15       % stcschan-demo1 <stcs-file> <axis1> <axis2> ...
  16 
  17       <stcs-file>: The path to the disk file containing the STC-S
  18       description.
  19 
  20       <axis1> <axis2> ...: The axis values at the position to be tested.   
  21       If insufficient values are supplied, a message describing the
  22       required values is displayed (label, units, etc).
  23 
  24    Example:
  25       % stcschan-demo1 stcs-ex1.txt 1996-01-01T00:00:15 11:56:00 -11:30:00 \
  26                        1420.4 1000 
  27 
  28    To compile and link:
  29       Assuming your starlink distribution is in "/star":
  30 
  31       % gcc -o stcschan-demo1 stcschan-demo1.c -L/star/lib \
  32             -I/star/include `ast_link`
  33 */
  34 
  35 /* Include system headers. */
  36 #include <stdio.h>
  37 #include <string.h>
  38 
  39 /* Include the AST library header. */
  40 #include "ast.h"
  41 
  42 /* Maximum number of axes in an STC-S AstroCoordSystem. */
  43 #define MAX_AXES 5
  44 
  45 /* Maximum allowed length for a single line of text form the disk file. */
  46 #define MAX_LINE_LEN 500
  47 
  48 /* Prototype for the function that reads text from the disk file. */
  49 const char *source( void );
  50 
  51 
  52 int main( int argc, char **argv ){
  53 
  54 /* Local variables: */
  55    AstKeyMap *warnings;
  56    AstObject *object;
  57    AstRegion *region;
  58    AstStcsChan *channel;
  59    FILE *fd;
  60    char attrib[ 9 ];
  61    char key[ 15 ];
  62    const char *message;
  63    double inpos[ MAX_AXES ];
  64    double outpos[ MAX_AXES ];
  65    int axis;
  66    int iwarn;
  67    int naxis;
  68    int nc;
  69    int status;
  70 
  71 /* Initialised the returned system status to indicate success. */
  72    status = 0;
  73 
  74 /* Check a file was specified on the command line, and attempt to open it
  75    for read access. */
  76    if( argc < 2 ) {
  77       printf( "Usage: stcschan-demo1 <stcs-file> <axis1> <axis2> ...\n" );
  78       status = 1;
  79    } else {
  80       fd = fopen( argv[ 1 ], "r" );
  81       if( !fd ) {
  82          printf("Failed to open input file '%s'.\n", argv[ 1 ] );
  83          status = 1;
  84       }
  85    }
  86 
  87 /* If a disk file was opened successfully... */
  88    if( !status ) {
  89 
  90 /* Start an AST object context. This means we do not need to annull 
  91    each AST Object individually. Instead, all Objects created within 
  92    this context will be annulled automatically by the corresponding
  93    invocation of astEnd. */
  94       astBegin;
  95 
  96 /* Create an StcsChan. This is the object that converts external STC-S
  97    descriptions into corresponding AST Objects. Tell it to use the
  98    "source" function for obtaining lines of text from the disk file. Also
  99    tell it to store all warnings generated by the conversion for later
 100    use. Other attributes of the StcsChan class retain their default
 101    values. */
 102       channel = astStcsChan( source, NULL, "ReportLevel=3" );
 103   
 104 /* Associate the descriptor for the input disk file with the StcsChan.
 105    This makes it available to the "source" function. Since this
 106    application is single threaded, we could instead have made "fd" a 
 107    global variable, but the ChannelData facility is used here to illustrate 
 108    how to pass data to a source or sink function safely in a multi-threaded 
 109    application. */
 110       astPutChannelData( channel, fd );
 111 
 112 /* The default behaviour of the astRead function when used on an StcsChan is 
 113    to read and return the AstroCoordArea as an AST Region. This behaviour
 114    can be changed by assigning appropriate values to the StcsChan attributes
 115    "StcsArea", "StcsCoords" and "StcsProps". Options exist to return the 
 116    AstroCoords as an AST PointList, and/or to return the individual
 117    property values read from the STC-S text in the form of an AST KeyMap
 118    (a sort of hashmap). For now, just take the default action of reading the 
 119    AstroCoordsArea. */
 120       object = astRead( channel );
 121 
 122 /* The astRead function is a generic function and so returns a generic
 123    AstObject pointer. Check an Object was created successfully. */
 124       if( !object ) {
 125          printf( "Failed to read an AST Object from file '%s'.\n", 
 126                  argv[ 1 ] );
 127          status = 1;
 128 
 129 /* Now check that the object read is actually an AST Region, rather than
 130    some other class of AST Object. */
 131       } else if( !astIsARegion( object ) ) {      
 132          printf( "Expected a Region but read a %s from file '%s'.\n", 
 133                  astGetC( object, "Class" ), argv[ 1 ] );
 134          status = 1;
 135 
 136 /* We now now know we have a Region so it is safe to use the pointer
 137    returned by astRead as a Region pointer. Do the cast now to avoid
 138    repeated casting in future. */
 139       } else {
 140          region = (AstRegion *) object;      
 141 
 142 /* Get the number of axes in the AstroCoordSystem, and check it is not
 143    larger than expected. */
 144          naxis = astGetI( region, "Naxes" );
 145          if( naxis > MAX_AXES ) {
 146             printf( "The coordinate system read from file '%s' has "
 147                     "too many axes (%d). Up to %d axes are allowed.\n", 
 148                     argv[ 1 ], naxis, MAX_AXES );
 149             status = 1;
 150 
 151 /* Now check that the correct number of axis values were supplied on the
 152    command line. If not, issue a warning message and give details of the
 153    label and units for each axis. Note, AST axis indices are one-based, 
 154    in the range 1 to "Naxes". */
 155          } else if( argc != 2 + naxis ) {
 156             printf( "The coordinate system read from file '%s' has "
 157                     "%d axes, but %d axis values were supplied on the "
 158                     "command line. ", argv[ 1 ], naxis, argc - 2 );
 159 
 160             printf( "Values are required for the following axes:\n");
 161 
 162             for( axis = 1; axis <= naxis; axis++ ) {
 163                sprintf( attrib, "Label(%d)", axis );
 164                printf( "   Axis %d: %s ", axis, astGetC( region, attrib ) );
 165                sprintf( attrib, "Unit(%d)", axis );
 166                printf( "(%s)\n",  astGetC( region, attrib ) );
 167             }
 168 
 169             status = 1;
 170 
 171 /* If the correct number of axis values was supplied on the command line,
 172    convert the supplied strings into floating point axis values. Each
 173    class of axis has its own formatting and unformatting rules that are
 174    controlled by various attributes such as "Format" and "Digits". Values
 175    for these attributes could be stored in the Region if different
 176    unformatting conventions were preferred. */
 177          } else {
 178 
 179             for( axis = 1; axis <= naxis; axis++ ) {
 180 
 181                nc = astUnformat( region, axis, argv[ axis + 1 ], 
 182                                  inpos + axis - 1 );
 183 
 184                if( nc != strlen( argv[ axis + 1 ] ) ) {
 185                   sprintf( attrib, "Label(%d)", axis );
 186                   printf( "Failed to interpret '%s' as a value for axis "
 187                           "%d (%s).\n", argv[ axis + 1 ], axis,
 188                           astGetC( region, attrib ) );
 189                   status = 1;
 190                   break;
 191                } else {
 192                   printf("%g ", inpos[ axis - 1 ] );
 193                }
 194             }
 195             printf("\n");
 196          }
 197 
 198 /* If we have obtained a full set of floating point axis values, use the
 199    Region as a Mapping to transform the supplied position. When a Region
 200    is used as a Mapping, the transformation leaves all axis values
 201    unchanged for interior positions, but assigns the magic value AST__BAD 
 202    to all axes for exterior positions. */
 203          if( !status ) {
 204             astTranN( region, 1, naxis, 1, inpos, 1, naxis, 1, outpos );
 205 
 206 /* Issue a message describing the position tested and indicating if it is
 207    inside or outside the AstroCoordsArea. */
 208             printf( "\nThe position ( %s=%s", astGetC( region, "Symbol(1)" ),
 209                     argv[ 2 ] );
 210 
 211             for( axis = 2; axis <= naxis; axis++ ) {
 212                sprintf( attrib, "Symbol(%d)", axis );
 213                printf(", %s=%s", astGetC( region, attrib ), argv[ axis + 1 ] );
 214             }
 215 
 216             printf( " ) is " );
 217 
 218             if( outpos[ 0 ] == AST__BAD ) {            
 219                printf( "OUTSIDE" );
 220             } else {
 221                printf( "INSIDE" );
 222             }
 223 
 224             printf( " the region read from file '%s'.\n\n", argv[ 1 ] );
 225 
 226          }
 227       }
 228 
 229 /* We asked the StcsChan to record any warnings that were generated
 230    whilst converting the STC-S description into a corresponding AST
 231    Object (a Region in this case). We now see if any such warnings were
 232    generated by the earlier call to astRead. */
 233       warnings = astWarnings( channel );
 234 
 235 /* If any warnings were generated, and if no other error has occurred so
 236    far, display the warnings. */
 237       if( warnings && !status && astOK ) {
 238          printf( "\nThe following warnings were issued reading file "
 239                  "'%s':\n", argv[ 1 ] );
 240 
 241 /* The warnings are stored in an AST KeyMap (a sort of hashmap). Each
 242    warning message is associated with a key of the form "Warning_1",
 243    "Warning_2", etc. Loop round successive keys, obtaining a value for
 244    each key from the warnings KeyMap, and displaying it. */
 245          iwarn = 1;
 246          while( astOK ) {
 247             sprintf( key, "Warning_%d", iwarn++ );
 248             if( astMapGet0C( warnings, key, &message ) ) {
 249                printf( "\n- %s\n", message );
 250             } else {
 251                break;
 252             }
 253          }             
 254       }
 255 
 256 /* End the AST Object context. All Objects created since the
 257    corresponding invocation of astbegin will be annulled automatically. */
 258       astEnd;
 259 
 260 /* Close the disk file. */
 261       (void) fclose( fd );
 262    }
 263 
 264 /* If an error occurred in the AST library, set the retiurns system
 265    status non-zero. */
 266    if( !astOK ) status = 1;
 267    return status;
 268 }
 269 
 270 
 271 
 272 
 273 
 274 
 275 
 276 /* This is a function that reads a line of text from the disk file and
 277    returns it to the AST library. It is called from within the astRead
 278    function. */
 279 const char *source( void ){
 280    static char buffer[ MAX_LINE_LEN + 2 ];
 281    FILE *fd = astChannelData;
 282    return fgets( buffer, MAX_LINE_LEN + 2, fd );
 283 }
 284 
 285 
 286 
 287 
 288 
 289 

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.