예제 #1
0
int main( int argc, char **argv ){

/* Local variables: */
   AstBox *pixbox;
   AstFitsChan *fchan;
   AstFrame *pixfrm;
   AstFrame *wcsfrm;
   AstFrameSet *frameset;
   AstKeyMap *warnings;
   AstMapping *pix2wcs;
   AstObject *object;
   AstRegion *wcsbox;
   AstStcsChan *schan;
   FILE *fd;
   char key[ 15 ];
   char keyword[ 9 ];
   const char *message;
   double p1[ MAX_AXES ];
   double p2[ MAX_AXES ];
   int axis;
   int iwarn;
   int naxis;
   int status;

/* Initialised the returned system status to indicate success. */
   status = 0;

/* Check a file was specified on the command line, and attempt to open it
   for read access. */
   if( argc < 2 ) {
      printf( "Usage: stcschan-demo2 <header-file>\n" );
      status = 1;
   } else {
      fd = fopen( argv[ 1 ], "r" );
      if( !fd ) {
         printf("Failed to open input file '%s'.\n", argv[ 1 ] );
         status = 1;
      }
   }

/* If a disk file was opened successfully... */
   if( !status ) {

/* Start an AST object context. This means we do not need to annull
   each AST Object individually. Instead, all Objects created within
   this context will be annulled automatically by the corresponding
   invocation of astEnd. */
      astBegin;

/* Create a FitsChan. This is the object that converts external FITS
   headers into corresponding AST Objects. Tell it to use the "source"
   function for obtaining lines of text from the disk file. */
      fchan = astFitsChan( source, NULL, " " );

/* Associate the descriptor for the input disk file with the StcsChan.
   This makes it available to the "source" function. Since this
   application is single threaded, we could instead have made "fd" a
   global variable, but the ChannelData facility is used here to illustrate
   how to pass data to a source or sink function safely in a multi-threaded
   application. */
      astPutChannelData( fchan, fd );

/* Attempt to read the FITS heades and convert them into an AST FrameSet. */
      object = astRead( fchan );

/* The astRead function is a generic function and so returns a generic
   AstObject pointer. Check an Object was created successfully. */
      if( !object ) {
         printf( "Failed to read an AST Object from file '%s'.\n",
                 argv[ 1 ] );
         status = 1;

/* Now check that the object read is actually an AST FrameSet, rather than
   some other class of AST Object. */
      } else if( !astIsAFrameSet( object ) ) {
         printf( "Expected a FrameSet but read a %s from file '%s'.\n",
                 astGetC( object, "Class" ), argv[ 1 ] );
         status = 1;

/* We now know we have a FrameSet so it is safe to use the pointer
   returned by astRead as a FrameSet pointer. Do the cast now to avoid
   repeated casting in future. */
      } else {
         frameset = (AstFrameSet *) object;

/* Get a pointer to the Frame that describes the attributes of the FITS
   world coordinate system. This is the current Frame in the FrameSet
   read from the FITS headers. */
         wcsfrm = astGetFrame( frameset, AST__CURRENT );

/* Get a pointer to the Frame that describes the attributes of the FITS
   pixel coordinate system. This is the base Frame in the FrameSet
   read from the FITS headers. */
         pixfrm = astGetFrame( frameset, AST__BASE );

/* Get the Mapping that transforms pixel positions into WCS positions.
   The is the Mapping from base to current Frame in the  FrameSet read
   from the FITS headers. */
         pix2wcs = astGetMapping( frameset, AST__BASE, AST__CURRENT );

/* Get the number of axes in ther pixel Frame. */
         naxis = astGetI( pixfrm, "Naxes" );

/* For each pixel axis, form the name of the corresponding NAXISi
   keyword. */
         for( axis = 0; axis < naxis; axis++ ) {
            sprintf( keyword, "NAXIS%d", axis + 1 );

/* Store the pixel coordinate on the current axis at the lower left corner
   of the first pixel. */
            p1[ axis ] = 0.5;

/* Get the NAXISi value for the current axis from the FITS header, and
   store it in array "p2". Report an error if NAXISi is not found. */
            if( !astGetFitsF( fchan, keyword, p2 + axis ) ){
               printf("Keyword '%s' not found in header\n", keyword );
               status = 1;
               break;

/* If it is found, modify "p2" so that it holds the pixel coordinate on
   the current axis at the upper right corner of the last pixel. */
            } else {
               p2[ axis ] += 0.5;
            }
         }
      }

/* If all has gone well, create an AST Region (a Box) describing the
   rectangular region of pixel coordinates covered by the pixel array. */
      if( !status ) {
         pixbox = astBox( pixfrm, 1, p1, p2, NULL, " " );

/* Map this box into the FITS world coordinate system. The Mapping is
   specified by "pix2wcs", and the attributes of the resulting axes is
   described by "wcsfrm". */
         wcsbox = astMapRegion( pixbox, pix2wcs, wcsfrm );

/* Create an StcsChan. This is the object that converts (either way)
   between external STC-S descriptions and their corresponding AST Objects.
   Tell it to use the "source" function for obtaining lines of text from
   the disk file. Also tell it to store all warnings generated by the
   conversion for later use. Other attributes of the StcsChan class retain
   their default values. */
         schan = astStcsChan( NULL, NULL, "ReportLevel=3" );

/* Attempt to write out the Region describing the pixel array (in WCS)
   as an STC-S description. Report an error if this fails. */
         if( ! astWrite( schan, wcsbox ) && astOK ) {
            printf( "Failed to convert the Region into an STC-S "
                    "description.\n" );
         }
      }

/* We asked the StcsChan to record any warnings that were generated
   whilst converting the AST Region into a corresponding STC-S description.
   We now see if any such warnings were generated by the earlier call to
   astWrite. */
      warnings = astWarnings( schan );

/* If any warnings were generated, and if no other error has occurred so
   far, display the warnings. */
      if( warnings && !status && astOK ) {
         printf( "\nThe following warnings were issued:\n" );

/* The warnings are stored in an AST KeyMap (a sort of hashmap). Each
   warning message is associated with a key of the form "Warning_1",
   "Warning_2", etc. Loop round successive keys, obtaining a value for
   each key from the warnings KeyMap, and displaying it. */
         iwarn = 1;
         while( astOK ) {
            sprintf( key, "Warning_%d", iwarn++ );
            if( astMapGet0C( warnings, key, &message ) ) {
               printf( "\n- %s\n", message );
            } else {
               break;
            }
         }
      }

/* End the AST Object context. All Objects created since the
   corresponding invocation of astbegin will be annulled automatically. */
      astEnd;

/* Close the disk file. */
      (void) fclose( fd );
   }

/* If an error occurred in the AST library, set the retiurns system
   status non-zero. */
   if( !astOK ) status = 1;
   return status;
}
예제 #2
0
Hero *  Hero::constructFromFitsFile(const QString &fname)
{
    FitsParser parser;
    bool parsedOk = parser.loadFile( FitsFileLocation::fromLocal( fname));
    if( ! parsedOk) {
        dbg(1) << "Parser failed to load " << fname;
        Hero * heroPtr = new Hero;
        heroPtr-> addError( "FitsParser failed to load the file");
        return heroPtr;
    }

    // alias hdr
    auto & hdr = parser.getHeaderInfo().headerLines;

    Hero * heroPtr = new Hero;
    Hero & hero = * heroPtr;
    AstErrorGuard guard( heroPtr);
    AstGCGuard gcGuard;

    // set naxes in case AST fails to read this file
    hero.m_ast.naxes = parser.getHeaderInfo().naxis;

    // set up bunit
    {
        hero.m_bunit = parser.getHeaderInfo().bunit;
    }
    // and the nicer version of bunit
    {
        QString u = hero.m_bunit.simplified();
        if( u.toLower() == "kelvin") {
            hero.m_bunitNiceHtml = "K";
        }
        else {
            hero.m_bunitNiceHtml = u;
        }
    }

    // Create a FitsChan and feed it the fits header
    AstFitsChan *fitschan;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-zero-length"
    fitschan = astFitsChan( NULL, NULL, "" );
#pragma GCC diagnostic pop

    std::cout << "astOK = " << astOK << "\n";

    // feed the header lines one by one and check for errors
    for( const QString & s : hdr) {
        std::string stdstr = s.toStdString();
        astPutFits( fitschan, stdstr.c_str(), 1);
        if( ! astOK) {
            astClearStatus;
            QString ss = s.trimmed();
            std::cout << "Skipping bad card: " << ss << "\n";
            hero.addError( "Skipping card: " + ss);
        }
    }
    // reposition to the beginning of the channel (ast thing, it's required, hmmmkey)
    astClear( fitschan, "Card" );

    std::cout << "astOK = " << astOK << "\n";

    std::cout << "Here\n";

    auto encoding = AstWrappers::getC( fitschan, "Encoding" );
    std::cout << "Encoding = " << encoding << "\n";

    // do we have warnings?
    AstKeyMap * warnings = static_cast<AstKeyMap *>( astWarnings( fitschan));

    if( warnings && astOK ) {
        std::cout << "Warnings:\n";

        int iwarn = 1;
        while( astOK ) {
            std::string key = QString("Warning_%1").arg( iwarn).toStdString();
            const char * message = nullptr;
            if( astMapGet0C( warnings, key.c_str(), & message ) ) {
                printf( "\n- %s\n", message );
                hero.addError( QString( "Warning: %1").arg( message));
            } else {
                break;
            }
        }
    }
    else {
        std::cout << "No warnings\n";
    }

    // create a frameset for this file
    AstFrameSet * wcsinfo = static_cast<AstFrameSet *> ( astRead( fitschan ));
    std::cout << "astOK = " << astOK << "\n";

    if ( ! astOK ) {
        std::cout << "astOK is not ok\n";
        hero.addError( "astRead failed");
        astClearStatus;
        return heroPtr;
    }
    else if ( wcsinfo == AST__NULL ) {
        hero.addError( "No WCS found in the fits file");
        std::cout << "No WCS found\n";
        return heroPtr;
    }
    else if ( AstWrappers::getC( wcsinfo, "Class" ) != "FrameSet") {
        std::cout << "Some other weird error occured\n";
        hero.addError( "AstLib returned non-frame-set");
        return heroPtr;
    }        

    // frame was read in OK, save it
    hero.m_ast.origWcsInfo = wcsinfo;
    astExempt( hero.m_ast.origWcsInfo);
    hero.m_ast.currWcsInfo = astClone( hero.m_ast.origWcsInfo);
    astExempt( hero.m_ast.currWcsInfo);

    astShow( wcsinfo);

    // extract the current sky system
    // TODO: this assumes axis1 is a skycs
    QString skysys = AstWrappers::getC( wcsinfo, "System(1)");
    hero.m_currentSkyCs = string2skycs( skysys);
    hero.m_originalSkyCs = hero.m_currentSkyCs;

    // extract the labels/etc for axes
    hero.m_ast.naxes = AstWrappers::getI( wcsinfo, "Naxes" );
    hero.parseAxesInfo();

    return heroPtr;
}