Attachment 'stcschan-demo5.c'

Download

   1 /* Name:
   2       stcschan-demo5.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 two STC-S descriptions from two disk files, and
  11       writes a new STC-S description to standard output. The new STC-S 
  12       covers the same region as the first STC-S, but expressed in the
  13       coordinate system of the second STC-S.
  14 
  15    Usage:
  16       % stcschan-demo5 <stcs-file1> <stcs-file2> 
  17 
  18       <stcs-file1>: The path to the disk file containing the first STC-S
  19       description.
  20 
  21       <stcs-file2>: The path to the disk file containing the second STC-S
  22       description.
  23 
  24    Example:
  25       % stcschan-demo5 stcs-ex1.txt stcs-ex2.txt
  26 
  27    To compile and link:
  28       Assuming your starlink distribution is in "/star":
  29 
  30       % gcc -o stcschan-demo5 stcschan-demo5.c -L/star/lib \
  31             -I/star/include `ast_link`
  32 */
  33 
  34 /* Include system headers. */
  35 #include <stdio.h>
  36 #include <string.h>
  37 
  38 /* Include the AST library header. */
  39 #include "ast.h"
  40 
  41 /* Maximum number of axes in an STC-S AstroCoordSystem. */
  42 #define MAX_AXES 5
  43 
  44 /* Maximum allowed length for a single line of text form the disk file. */
  45 #define MAX_LINE_LEN 500
  46 
  47 /* Prototypes: */
  48 const char *source( void );
  49 AstRegion *ReadStcs( AstStcsChan *chan, const char *file, int *status );
  50 void ReportWarnings( AstStcsChan *chan, const char *file, int *status );
  51 
  52 int main( int argc, char **argv ){
  53 
  54 /* Local variables: */
  55    AstFrameSet *fs;
  56    AstFrame *frame;
  57    AstMapping *map;
  58    AstRegion *region1;
  59    AstRegion *region2;
  60    AstRegion *region3;
  61    AstStcsChan *channel;
  62    int status;
  63 
  64 /* Initialised the returned system status to indicate success. */
  65    status = 0;
  66 
  67 /* Check two files were specified on the command line. */
  68    if( argc < 3 ) {
  69       printf( "Usage: stcschan-demo5 <stcs-file1> <stcs-file2> \n" );
  70       status = 1;
  71    } 
  72 
  73 /* Start an AST object context. This means we do not need to annull 
  74    each AST Object individually. Instead, all Objects created within 
  75    this context will be annulled automatically by the corresponding
  76    invocation of astEnd. */
  77    astBegin;
  78 
  79 /* Create an StcsChan. This is the object that converts between external 
  80    STC-S descriptions and the corresponding AST Objects. Tell it to use the
  81    "source" function for obtaining lines of text from the disk file. We
  82    supply a NULL pointer for the "sink" function so that objects written out
  83    through the channel will appear on standard output. Also tell it to 
  84    store all warnings generated by the conversion for later use. Other 
  85    attributes of the StcsChan class retain their default values. */
  86    channel = astStcsChan( source, NULL, "ReportLevel=3" );
  87   
  88 /* Attempt to read the STC-S description from the first file, and produce
  89    a corresponding AST Region object. The conversion is performed by the
  90    StcsChan created above. */
  91    region1 = ReadStcs( channel, argv[ 1 ], &status );
  92 
  93 /* Now attempt to read the STC-S description from the second file,
  94    producing a corresponding AST Region object. We re-use the StcsChan 
  95    created above. */
  96    region2 = ReadStcs( channel, argv[ 2 ], &status );
  97 
  98 /* If we have two Regions, get the mapping from the coordinate system of
  99    the first Region to the coordinate system of the second Region. If
 100    successful, this returns a FrameSet object that encapsulates both the 
 101    Mapping and the two coordinate Frames. */
 102    if( region1 && region2 ) {
 103       fs = astConvert( region1, region2, "" );
 104 
 105 /* Issue a warning if the conversion cannot be done. */
 106       if( ! fs ) {
 107          printf( "Cannot determine the transformation from the first "
 108                  "coordinate system to the second coordinate system\n");
 109          status = 1;
 110 
 111 /* Otherwise, extract the Mapping from the FrameSet, and then extract the
 112    Frame that describes the required coordinate system (it will be the
 113    current Frame in the FrameSet). */
 114       } else {
 115          map = astGetMapping( fs, AST__BASE, AST__CURRENT );
 116          frame = astGetFrame( fs, AST__CURRENT );
 117  
 118 /* Create a new Region my mapping the first supplied Region using the
 119    above Mapping. Also supply the above Frame to indicate the nature of 
 120    the axis values produced by the Mapping (the new Region will be
 121    defined within this Frame). */
 122          region3 = astMapRegion( region1, map, frame );
 123 
 124 /* Attempt to write out this new Region as an STC-S description. Report an 
 125    error if this fails. The channel writes text to standard output
 126    because no "sink" function was supplied when it was created above. */
 127          if( ! astWrite( channel, region3 ) && astOK ) {
 128             printf( "Failed to convert the new Region into an STC-S "
 129                     "description.\n" );
 130 
 131 /* Report any warnings that were generated during the conversion to
 132    STC-S. */
 133          } else {
 134             ReportWarnings( channel, NULL, &status );
 135          }
 136       }
 137    }
 138 
 139 /* End the AST Object context. All Objects created since the
 140    corresponding invocation of astbegin will be annulled automatically. */
 141    astEnd;
 142 
 143 /* If an error occurred in the AST library, set the retiurns system
 144    status non-zero. */
 145    if( !astOK ) status = 1;
 146    return status;
 147 }
 148 
 149 
 150 
 151 
 152 
 153 
 154 
 155 /* This is a function that reads a line of text from the disk file and
 156    returns it to the AST library. It is called from within the astRead
 157    function. */
 158 const char *source( void ){
 159    static char buffer[ MAX_LINE_LEN + 2 ];
 160    FILE *fd = astChannelData;
 161    return fgets( buffer, MAX_LINE_LEN + 2, fd );
 162 }
 163 
 164 
 165 
 166 
 167 
 168 /* -------------------------------------------------------------------
 169  * This function reads an STC-S description from a given text file,
 170  * and attempts to convert them into an AST Region. If successful, a
 171  * pointer to the Region is returned. A NULL pointer is returned if
 172  * anything goes wrong. 
 173 */
 174 
 175 AstRegion *ReadStcs( AstStcsChan *chan, const char *file, int *status ){
 176    AstObject *object;
 177    AstRegion *result;
 178    FILE *fd;
 179 
 180 /* Initialise the returned pointer to indicate that no Region has yet
 181    been read. */
 182    result = NULL;
 183 
 184 /* If an error has already occurred, return without action. */
 185    if( *status != 0 ) return result;
 186 
 187 /* Attempt to open the STC-S file */
 188    fd = fopen( file, "r" );
 189    if( !fd ) {
 190       printf("Failed to open STC-S descrption file '%s'.\n", file );
 191 
 192 /* If successful... */
 193    } else {
 194 
 195 /* Associate the descriptor for the input disk file with the StcsChan.
 196    This makes it available to the "source" function. Since this
 197    application is single threaded, we could instead have made "fd" a 
 198    global variable, but the ChannelData facility is used here to illustrate 
 199    how to pass data to a source or sink function safely in a multi-threaded 
 200    application. */
 201       astPutChannelData( chan, fd );
 202 
 203 /* The default behaviour of the astRead function when used on an StcsChan is 
 204    to read and return the AstroCoordArea as an AST Region. This behaviour
 205    can be changed by assigning appropriate values to the StcsChan attributes
 206    "StcsArea", "StcsCoords" and "StcsProps". Options exist to return the 
 207    AstroCoords as an AST PointList, and/or to return the individual
 208    property values read from the STC-S text in the form of an AST KeyMap
 209    (a sort of hashmap). For now, just take the default action of reading the 
 210    AstroCoordsArea. */
 211       object = astRead( chan );
 212       
 213 /* The astRead function is a generic function and so returns a generic
 214    AstObject pointer. Check an Object was created successfully. */
 215       if( !object ) {
 216          printf( "Failed to read an AST Object from STC-S description "
 217                  "file '%s'.\n", file );
 218 
 219 /* Now check that the object read is actually an AST Region, rather than
 220    some other class of AST Object. */
 221       } else if( !astIsARegion( object ) ) {      
 222          printf( "Expected a Region but read a %s from STC-S description "
 223                  "file '%s'.\n", astGetC( object, "Class" ), file );
 224 
 225 /* If the Object is a Region, return the Region pointer. */
 226       } else {
 227          result = (AstRegion *) object;
 228       }
 229 
 230 /* Close the file. */
 231       fclose( fd );
 232 
 233 /* If the StcsChan recorded any warnings that were generated whilst 
 234    converting the STC-S description into a corresponding AST Object,
 235    we now display them. */
 236       ReportWarnings( chan, file, status );
 237    }
 238 
 239    return result;
 240 }
 241 
 242 /* -------------------------------------------------------------------
 243  * This function extracts any warnings stored in the supplied Channel as
 244  * a result of he previous read or write operation, and displays them on
 245  * standard output. 
 246 */
 247 
 248 void ReportWarnings( AstStcsChan *chan, const char *file, int *status ){
 249    AstKeyMap *warnings;
 250    char key[ 15 ];
 251    const char *message;
 252    int iwarn;
 253 
 254 /* If an error has already occurred, return without action. */
 255    if( *status != 0 ) return;
 256 
 257 /* If the StcsChan records any warnings that are generated whilst 
 258    converting between STC-S descriptions and corresponding AST Objects,
 259    display them. First test the ReportLevel attribute value to see
 260    if warnings were recored. */
 261    if( astGetI( chan, "ReportLevel" ) > 0 ) {
 262 
 263 /* Any warnings recorded during the conversion performed by the previous
 264    invocation of astRead or astWrite are returned by the astWarnings method, 
 265    in the form of an AST "KeyMap" (a type of hash map ). */
 266       warnings = astWarnings( chan );
 267 
 268 /* If any warnings were generated, and if no other error has occurred so
 269    far, display the warnings. */
 270       if( warnings && !status && astOK ) {
 271 
 272 /* Indicate the context to the user. Assume we were reading an STC-S
 273    description if "file" was supplied, and writing an STC-S desciprion
 274    otherwise. */
 275          if( file ) {
 276             printf( "\nThe following warnings were issued reading file "
 277                     "'%s':\n", file );
 278          } else {
 279             printf( "\nThe following warnings were issued converting an "
 280                     "AST Region into an STC-S description:\n" );
 281          }
 282 
 283 /* The warnings are stored in an AST KeyMap (a sort of hashmap). Each
 284    warning message is associated with a key of the form "Warning_1",
 285    "Warning_2", etc. Loop round successive keys, obtaining a value for
 286    each key from the warnings KeyMap, and displaying it. */
 287          iwarn = 1;
 288          while( astOK ) {
 289             sprintf( key, "Warning_%d", iwarn++ );
 290             if( astMapGet0C( warnings, key, &message ) ) {
 291                printf( "\n- %s\n", message );
 292             } else {
 293                break;
 294             }
 295          }             
 296       }
 297    }
 298 }
 299 
 300 
 301 

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.