Esempio n. 1
0
bool FileFormatInstance::Extract( FITSKeywordArray& keywords )
{
   try
   {
      keywords.Clear();

      if ( (*API->FileFormat->BeginKeywordExtraction)( handle ) == api_false )
         return false;

      for ( size_type i = 0, count = (*API->FileFormat->GetKeywordCount)( handle ); i < count; ++i )
      {
         IsoString name, value, comment;
         name.Reserve( 96 );
         value.Reserve( 96 );
         comment.Reserve( 96 );

         if ( (*API->FileFormat->GetNextKeyword)( handle,
                  name.Begin(), value.Begin(), comment.Begin(), 81 ) == api_false )
            throw APIFunctionError( "GetNextKeyword" );

         name.ResizeToNullTerminated();
         value.ResizeToNullTerminated();
         comment.ResizeToNullTerminated();

         keywords.Add( FITSHeaderKeyword( name, value, comment ) );
      }

      (*API->FileFormat->EndKeywordExtraction)( handle );
      return true;
   }
   catch ( ... )
   {
      (*API->FileFormat->EndKeywordExtraction)( handle );
      throw;
   }
}
   static void Apply( GenericImage<P>& img, const View& view, const FluxCalibrationInstance& instance )
   {
      FITSKeywordArray inputKeywords;
      view.Window().GetKeywords( inputKeywords );

      if ( KeywordExists( inputKeywords, "FLXMIN" ) ||
           KeywordExists( inputKeywords, "FLXRANGE" ) ||
           KeywordExists( inputKeywords, "FLX2DN" ) )
      {
         throw Error( "Already calibrated image" );
      }

      if ( img.IsColor() )
         throw Error( "Can't calibrate a color image" );

      float Wc       =             instance.p_wavelength.GetValue( inputKeywords );
      float Tr       =  Max( 1.0F, instance.p_transmissivity.GetValue( inputKeywords ) );
      float Delta    =             instance.p_filterWidth.GetValue( inputKeywords );
      float Ap       =             instance.p_aperture.GetValue( inputKeywords ) / 10; // mm -> cm
      float Cobs     =  Max( 0.0F, instance.p_centralObstruction.GetValue( inputKeywords ) ) / 10; // mm -> cm
      float ExpT     =             instance.p_exposureTime.GetValue( inputKeywords );
      float AtmE     =  Max( 0.0F, instance.p_atmosphericExtinction.GetValue( inputKeywords ) );
      float G        =  Max( 1.0F, instance.p_sensorGain.GetValue( inputKeywords ) );
      float QEff     =  Max( 1.0F, instance.p_quantumEfficiency.GetValue( inputKeywords ) );

      if ( Wc <= 0 )
         throw Error( "Invalid filter wavelength" );

      if ( Tr <= 0 || Tr > 1 )
         throw Error( "Invalid filter transmissivity" );

      if ( Delta <= 0 )
         throw Error( "Invalid filter width" );

      if ( Ap <= 0 )
         throw Error( "Invalid aperture" );

      if ( Cobs < 0 || Cobs >= Ap )
         throw Error( "Invalid central obstruction area" );

      if ( ExpT <= 0 )
         throw Error( "Invalid exposure time" );

      if ( AtmE < 0 || AtmE >= 1 )
         throw Error( "Invalid atmospheric extinction" );

      if ( G <= 0 )
         throw Error( "Invalid sensor gain" );

      if ( QEff <= 0 || QEff > 1 )
         throw Error( "Invalid quantum efficiency" );

      FITSKeywordArray keywords;
      float pedestal = 0;
      bool  foundPedestal = false;
      for ( FITSKeywordArray::const_iterator i = inputKeywords.Begin(); i != inputKeywords.End(); ++i )
         if ( i->name == "PEDESTAL" )
         {
            if ( i->value.TryToFloat( pedestal ) )
               foundPedestal = true;
            pedestal /= 65535; // 2^16-1 maximum value of a 16bit CCD.
         }
         else
            keywords.Add( *i );

      if ( foundPedestal )
         Console().NoteLn( "<end><cbr><br>* FluxCalibration: PEDESTAL keyword found: " + view.FullId() );

      // double F = Wc * inv_ch * (1 - Tr) * Delta * Ap * Cobs * ExpT * AtmE * G * QEff;
      double F = Wc * inv_ch * (1 - AtmE) * Delta * ( Const<double>::pi() / 4 * ( Ap*Ap - Cobs*Cobs  ) ) * ExpT * Tr * G * QEff;

      size_type N = img.NumberOfPixels();
            typename P::sample* f   = img.PixelData( 0 );
      const typename P::sample* fN  = f + N;

      double flxMin = DBL_MAX;
      double flxMax = 0;
      for ( ; f < fN; ++f, ++img.Status() )
      {
         double I; P::FromSample( I, *f );
         I = (I - pedestal)/F;
         *f = P::ToSample( I );
         if ( I < flxMin )
            flxMin = I;
         if ( I > flxMax )
            flxMax = I;
      }

      img.Rescale();

      keywords.Add( FITSHeaderKeyword( "FLXMIN",
                                       IsoString().Format( "%.8e", flxMin ),
                                       "" ) );
      keywords.Add( FITSHeaderKeyword( "FLXRANGE",
                                       IsoString().Format( "%.8e", flxMax - flxMin ),
                                       "FLXRANGE*pixel_value + FLXMIN = erg/cm^2/s/nm" ) );
      keywords.Add( FITSHeaderKeyword( "FLX2DN",
                                       IsoString().Format( "%.8e", F*65535 ),
                                       "(FLXRANGE*pixel_value + FLXMIN)*FLX2DN = DN" ) );

      view.Window().SetKeywords( keywords );
   }