Magnitudes.hxx

Go to the documentation of this file.
00001 
00002 
00003 
00004 //-----------------------------------------------------------------------------
00005 // SVN: $Id: Magnitudes.hxx 5292 2008-11-21 16:38:11Z RossCollins $
00006 //-----------------------------------------------------------------------------
00007 #ifndef MAGNITUDES_H
00008 #define MAGNITUDES_H
00009 
00010 #include <float.h>
00011 
00012 #include "Constants.h"
00013 #include "DataMethod.hxx"
00014 #include "FitsFile.h"
00015 #include "StringOps.h"
00016 #include "IllumTable.hxx"
00017 //-----------------------------------------------------------------------------
00023 template<typename DataType>
00024 class CalibratedMagnitude : public DataMethod<DataType>
00025 {
00026 public:
00031   CalibratedMagnitude(const FitsFile& aCatFile, IllumTable& anIllum)
00032     : mCatFile(aCatFile)
00033     { 
00034       DataMethod<DataType>::methodName = "CalibratedMagnitude"; 
00035       mIllum = &anIllum;
00036     }
00037 
00039   virtual ~CalibratedMagnitude() { }
00040 
00042   void setSource(IntMap& tbls, IntMap& cols, StringMap units)
00043   {
00044     mExtnumColno = cols[0];
00045     mFluxColno = cols[1];
00046     mXColno = cols[2];
00047     mYColno = cols[3];
00048     mExtnumTblno = tbls[0];
00049     mFluxTblno = tbls[1];
00050     mXTblno = tbls[2];
00051     mYTblno = tbls[3];
00052     if (mFluxColno < 0)
00053     {
00054       throw DataMethodException("CalibratedMagnitude method: cannot source");
00055     }
00056   }
00057 
00059   void setTarget(IntMap& cols, StringMap units) { mMagColno = cols[0]; }
00060 
00065   void doit2(TableData<DataType>& inpData, TableData<DataType>& data, int row1, int row2)
00066   {
00067     double pi = M_PI;
00068     double flux2mag = 2.5/M_LN10;
00069     double amss[4], amse[4];
00070     double zpmag[4], zperr[4];
00071     double extinct[4];
00072     double exptime[4];
00073     std::string ctype1[4],ctype2[4];
00074     double crpix1[4],crpix2[4],cd11[4],cd12[4],cd21[4],cd22[4];
00075     double pv21[4],pv23[4];
00076 
00077     // get frame type
00078     std::string frameType = DataOps::getFrameType(mCatFile.getFileName());
00079     
00080     // Get observation data from file
00081     for (int hduNo = 2; hduNo <= mCatFile.getNumHdus(); ++hduNo)
00082     {
00083       int extNo = hduNo - 2;
00084       // Move to extension on the FITS file
00085       mCatFile.movabsHdu(hduNo);
00086 
00087       // Read the airmass values
00088       mCatFile.readKey(FitsFile::cAMSTART, amss[extNo]);
00089       mCatFile.readKey(FitsFile::cAMEND, amse[extNo]);
00090 
00091       // Read the zero point
00092       mCatFile.readKey(FitsFile::cMAGZPT, zpmag[extNo]);
00093       mCatFile.readKey(FitsFile::cMAGZRR, zperr[extNo]);
00094 
00095       // Read the extinction
00096       mCatFile.readKey(FitsFile::cEXTINCT, extinct[extNo]);
00097 
00098       // Read the exposure time
00099       mCatFile.readKey(FitsFile::cEXP_TIME, exptime[extNo]);
00100       
00101       // Read in the astrometry values
00102       mCatFile.readKey(FitsFile::cCTYPE1 ,ctype1[extNo]);
00103       mCatFile.readKey(FitsFile::cCTYPE2 ,ctype2[extNo]);
00104       mCatFile.readKey(FitsFile::cCRPIX1, crpix1[extNo]);
00105       mCatFile.readKey(FitsFile::cCRPIX2, crpix2[extNo]);
00106       mCatFile.readKey(FitsFile::cCD11, cd11[extNo]);
00107       mCatFile.readKey(FitsFile::cCD21, cd21[extNo]);
00108       mCatFile.readKey(FitsFile::cCD12, cd12[extNo]);
00109       mCatFile.readKey(FitsFile::cCD22, cd22[extNo]);
00110       if (ctype1[extNo].find("ZPN")==5 && ctype2[extNo].find("ZPN")==5) 
00111       {
00112           mCatFile.readKey(FitsFile::cPV21, pv21[extNo]);
00113           mCatFile.readKey(FitsFile::cPV23, pv23[extNo]);
00114       }
00115       else
00116       {
00117           pv21[extNo]=1.;
00118           pv23[extNo]=0.;
00119       }
00120     }
00121     for (int rowNo = row1; rowNo < row2; ++rowNo)
00122     {
00123       Numeric value;
00124       data.value(mExtnumColno, rowNo, value);
00125       int extNum = (int)value - 2;
00126       
00127       // Read the "flux"
00128       double flux;
00129       inpData.value(mFluxColno, rowNo, flux);
00130 
00131       // Read the x-position 
00132       double xpos;
00133       inpData.value(mXColno, rowNo, xpos);
00134 
00135       // Read the y-position 
00136       double ypos;
00137       inpData.value(mYColno, rowNo, ypos);
00138 
00139       // Calculate xi and eta
00140       double xi = (cd11[extNum]*pi/180.)*(xpos-crpix1[extNum]) + 
00141                   (cd12[extNum]*pi/180.)*(ypos-crpix2[extNum]);
00142       double eta = (cd21[extNum]*pi/180.)*(xpos-crpix1[extNum]) + 
00143                    (cd22[extNum]*pi/180.)*(ypos-crpix2[extNum]);
00144       double rad = sqrt(xi*xi+eta*eta);
00145 
00146       // Read Aperture correction (written into AperMag1-7)
00147       double aperCor = 0.0;
00148       if (data.isDefined(mMagColno, rowNo))
00149       {
00150         data.value(mMagColno, rowNo, aperCor);
00151       }
00152       // Instrumental magnitude corresponding to this flux
00153       // Need to put in Luptitudes - very rough for now
00154       //if (flux > FLT_EPSILON) {
00155       if (inpData.isDefined(mFluxColno, rowNo) && flux > FLT_EPSILON)
00156       {
00157         double instMag = -flux2mag * log(flux);
00158 
00159         // Correction calculations
00160         // Extinction correction
00161         double extCorr = -extinct[extNum] 
00162                          * ((amss[extNum]+amse[extNum])/2.0 - 1.);
00163 
00164         // Exposure time correction
00165         double texpCorr = flux2mag * log(exptime[extNum]);
00166 
00167         // Distortion correction
00168         double distortCorr;
00169         if (frameType.find(PreSuffixNames::mosaSuffix) != string::npos)
00170         {
00171           // don't apply to mosaics
00172           distortCorr = 0.0;
00173         }
00174         else
00175         {
00176           if (ctype1[extNum].find("ZPN")!=std::string::npos && 
00177               ctype2[extNum].find("ZPN")!=std::string::npos)
00178           {
00179             distortCorr = 1.0 + 3.0*pv23[extNum]*rad*rad/pv21[extNum];
00180             distortCorr *= 1.0 + pv23[extNum]*rad*rad/pv21[extNum];
00181           } else if (ctype1[extNum].find("TAN")!=std::string::npos && 
00182                      ctype2[extNum].find("TAN")!=std::string::npos) {
00183             if (rad==0.)
00184             {
00185               distortCorr = 1.0;
00186             } else {
00187               distortCorr = 1.0/(1.0+tan(rad)*tan(rad));
00188               distortCorr *= atan(rad)/rad;
00189             }
00190           } else {
00191             distortCorr = 1.0;
00192           }
00193             
00194           distortCorr = flux2mag * log(distortCorr);
00195         }
00196         
00197         // Illumination correction
00198         double illumCorr;
00199         if (frameType.find(PreSuffixNames::deepSuffix) != string::npos)
00200         {
00201           // don't apply to deep images
00202           illumCorr = 0.0;
00203         }
00204         else
00205         {
00206           Intervall xiIntervall, etaIntervall;
00207           mIllum->setXiIntervall(xi);
00208           mIllum->setEtaIntervall(eta);
00209           xiIntervall = mIllum->getXiIntervall();
00210           etaIntervall = mIllum->getEtaIntervall();
00211           double f1=0.0, f2=0.0, f3=0.0, f4=0.0, d1=0.0, d2=0.0;
00212           d1 = xiIntervall.val2 - xiIntervall.val1;
00213           d2 = etaIntervall.val2 - etaIntervall.val1;
00214           if (d1 == 0.0 and d2 != 0.0)
00215           {
00216             f1 = mIllum->getMag(xiIntervall.x1, etaIntervall.x1);
00217             f2 = mIllum->getMag(xiIntervall.x1, etaIntervall.x2) - f1;
00218             f2 *= (eta - etaIntervall.val1)/d2;
00219             illumCorr = f1 + f2;
00220           }
00221           else if (d2 == 0.0 and d1 != 0.0)
00222           {
00223             f1 = mIllum->getMag(xiIntervall.x1, etaIntervall.x1);
00224             f2 = mIllum->getMag(xiIntervall.x2, etaIntervall.x1) - f1;
00225             f2 *= (xi - xiIntervall.val1)/d1;
00226             illumCorr = f1 + f2;
00227           }
00228           else if (d1 == 0.0 and d2 == 0.0)
00229           {
00230             illumCorr = mIllum->getMag(xiIntervall.x1, etaIntervall.x1);
00231           }
00232           else
00233           {
00234             f1 = mIllum->getMag(xiIntervall.x1, etaIntervall.x1);
00235             f1 *= (xiIntervall.val2 - xi);
00236             f2 = mIllum->getMag(xiIntervall.x2, etaIntervall.x1);
00237             f2 *= (xi - xiIntervall.val1);
00238             illumCorr = (f1 + f2) * (etaIntervall.val2 - eta);
00239             f3 = mIllum->getMag(xiIntervall.x1, etaIntervall.x2);
00240             f3 *= (xiIntervall.val2 - xi);
00241             f4 = mIllum->getMag(xiIntervall.x2, etaIntervall.x2);
00242             f4 *= (xi - xiIntervall.val1);
00243             illumCorr += (f3 + f4) * (eta - etaIntervall.val1);
00244             illumCorr /= (d1 * d2);
00245           }
00246         }
00247         
00248         // Calibrated magnitude
00249         double calMag = instMag + zpmag[extNum] 
00250           + extCorr + texpCorr - aperCor 
00251           + distortCorr + illumCorr;
00252         
00253         data.assign(mMagColno, rowNo, calMag);
00254       }
00255       else
00256       {
00257         data.assign(mMagColno, rowNo, DefaultValues::realdef);
00258       }
00259     }
00260   }
00261 
00262   // No simple data model available
00263   void doit(TableData<DataType>& data, int row1, int row2) { }
00264 
00265 private:
00266   FitsFile mCatFile;
00267   IllumTable* mIllum;
00268   int mExtnumColno;
00269   int mFluxColno;
00270   int mXColno;
00271   int mYColno;
00272   int mMagColno;
00273   int mExtnumTblno, mFluxTblno, mXTblno, mYTblno;
00274 };
00275 //-----------------------------------------------------------------------------
00278 template<typename DataType>
00279 class MagnitudeError : public DataMethod<DataType>
00280 {
00281 public:
00283   MagnitudeError() { DataMethod<DataType>::methodName = "MagnitudeError"; }
00284 
00286   virtual ~MagnitudeError() { }
00287 
00289   void setSource(IntMap& tbls, IntMap& cols, StringMap units)
00290   {
00291     mFluxColno = cols[0];
00292     mFluxErrColno = cols[1];
00293     mFluxTblno = tbls[0];
00294     mFluxErrTblno = tbls[1];
00295     if (mFluxColno < 0 || mFluxErrColno < 0)
00296     {
00297       throw DataMethodException("MagnitudeError method : cannot source");
00298     }
00299   }
00300 
00302   void setTarget(IntMap& cols, StringMap units) { mMagErrColno = cols[0]; }
00303 
00305   void doit2(TableData<DataType>& inpData, TableData<DataType>& data, int row1, int row2)
00306   {
00307     double mag2flux = M_LN10/2.5;
00308     for (int rowNo = row1; rowNo < row2; ++rowNo)
00309     {
00310       // Read the "flux" and error in the flux
00311       double flux, eflux;
00312       inpData.value(mFluxColno, rowNo, flux);
00313       inpData.value(mFluxErrColno, rowNo, eflux);
00314 
00315       // Error in magnitude
00316       if (inpData.isDefined(mFluxColno, rowNo) &&
00317           inpData.isDefined(mFluxErrColno, rowNo) &&
00318           flux > FLT_EPSILON)
00319       {
00320         double merr = eflux / (mag2flux * flux);
00321         data.assign(mMagErrColno, rowNo, merr);
00322       }
00323       else
00324       {
00325         data.assign(mMagErrColno, rowNo, DefaultValues::realdef);
00326       }
00327     }
00328   }
00329 
00330   // No simple data model available
00331    void doit(TableData<DataType>& data, int row1, int row2) { }
00332 
00333 private:
00334   int mFluxColno;
00335   int mFluxErrColno;
00336   int mMagErrColno;
00337   int mFluxTblno, mFluxErrTblno;
00338 };
00339 //-----------------------------------------------------------------------------
00342 template<typename DataType>
00343 class ColourIndex : public DataMethod<DataType>
00344 {
00345 public:
00347   ColourIndex() { DataMethod<DataType>::methodName = "ColourIndex"; }
00348 
00350   virtual ~ColourIndex() { }
00351 
00354   void setSource(IntMap& tbls, IntMap& cols, StringMap units)
00355   {
00356     mag1Colno = cols[0];
00357     mag2Colno = cols[1];
00358     if (mag1Colno < 0 || mag2Colno < 0)
00359     {
00360       throw DataMethodException("ColourIndex method : cannot source; "
00361                                 + StringOps::NumToString(mag1Colno) + ";"
00362                                 + StringOps::NumToString(mag2Colno));
00363     }
00364   }
00365 
00367   void setTarget(IntMap& cols, StringMap units) { ciColno = cols[0]; }
00368 
00369   void doit(TableData<DataType>& data, int row1, int row2)
00370   {
00371     for (int rowNo = row1; rowNo < row2; ++rowNo)
00372     {
00373       // Do the calculation if both magnitudes are defined - otherwise
00374       // leave them and a default will be assigned later.
00375       if (data.isDefined(mag1Colno,rowNo) && data.isDefined(mag2Colno,rowNo))
00376       {
00377         // Read the two magnitudes
00378         Numeric mag1, mag2;
00379         data.value(mag1Colno, rowNo, mag1);
00380         data.value(mag2Colno, rowNo, mag2);
00381 
00382         // Assign the colour index only if both magnitudes are not default:
00383         if (mag1 > DefaultValues::realdef/2.0 &&
00384             mag2 > DefaultValues::realdef/2.0)
00385         {
00386           data.assign(ciColno, rowNo, mag1 - mag2);
00387         }
00388       }
00389     }
00390   }
00391 
00392   // No data from raw data included
00393   void doit2(TableData<DataType>& inpData, TableData<DataType>& data, int row1, int row2) { }
00394 
00395 private:
00396   int mag1Colno;
00397   int mag2Colno;
00398   int ciColno;
00399 };
00400 //-----------------------------------------------------------------------------
00403 template<typename DataType>
00404 class ColourIndexError : public DataMethod<DataType>
00405 {
00406 public:
00408   ColourIndexError() { DataMethod<DataType>::methodName = "ColourIndexError"; }
00409 
00411   virtual ~ColourIndexError() { }
00412 
00415   void setSource(IntMap& tbls, IntMap& cols, StringMap units)
00416   {
00417     err1Colno = cols[0];
00418     err2Colno = cols[1];
00419     if (err1Colno < 0 || err2Colno < 0)
00420     {
00421       throw DataMethodException("ColourIndexError method : cannot source");
00422     }
00423   }
00424 
00426   void setTarget(IntMap& cols, StringMap units) { ciErrColno = cols[0]; }
00427 
00429   void doit(TableData<DataType>& data, int row1, int row2)
00430   {
00431     for (int rowNo = row1; rowNo < row2; ++rowNo)
00432     {
00433       // Do the calculation if both magnitude errors are defined
00434       if (data.isDefined(err1Colno,rowNo) &&
00435           data.isDefined(err2Colno,rowNo))
00436       {
00437         // Read the two magnitudes
00438         Numeric err1, err2;
00439         data.value(err1Colno, rowNo, err1);
00440         data.value(err2Colno, rowNo, err2);
00441 
00442         // Assign the colour index error which is simply the quadratic
00443         // sum of the errors in the individual errors if both errors are not
00444         // default:
00445         if (err1 > DefaultValues::realdef/2.0 &&
00446             err2 > DefaultValues::realdef/2.0)
00447         {
00448           Numeric err = sqrt(err1 * err1 + err2 * err2);
00449           data.assign(ciErrColno, rowNo, err);
00450         }
00451       }
00452     }
00453   }
00454 
00455   // No data from raw data included
00456   void doit2(TableData<DataType>& inpData, TableData<DataType>& data, int row1, int row2) { }
00457 
00458 private:
00459   int err1Colno;
00460   int err2Colno;
00461   int ciErrColno;
00462 };
00463 //-----------------------------------------------------------------------------
00464 #endif
00465 //-----------------------------------------------------------------------------
00466 // Change log:
00467 //
00468 // 27-May-2004,  IAB: Original version.
00469 //  6-Sep-2004,  NCH: Added this header text; fixed bugs in colour index
00470 //                    member functions where only first colour checked for
00471 //                    defined values.
00472 // 10-Mar-2005, ETWS: Included default value from Constants for magnitudes
00473 // 28-Apr-2005, ETWS: Included extinction, zeropoint, and exposure time
00474 //                    corrections
00475 //  6-Jun-2005,  NCH: Made ColourIndex and ColourIndexError default if
00476 //                    either of the source quantities used in the calculation
00477 //                    are defaults.
00478 // 22-Aug-2005, ETWS: Included aperture correction in Magnitude calculation.
00479 //  7-Dec-2005, ETWS: Included move of Fits Keys into class FitsFile
00480 //  7-Apr-2008, ETWS: Upgraded to use new detection table layout.
00481 // 17-Apr-2008, ETWS: Included illumination correction.
00482 //  5-Jun-2008, ETWS: Fixed illumination correction for cases where linear 
00483 //                    interpolation is needed.

Generated on Thu Apr 2 21:52:16 2009 for WfcamSrc by  doxygen 1.5.2