QuantitiesByAst.hxx

Go to the documentation of this file.
00001 
00002 
00003 
00004 //-----------------------------------------------------------------------------
00005 // SVN: $Id: QuantitiesByAst.hxx 4813 2008-05-29 22:55:39Z RossCollins $
00006 //-----------------------------------------------------------------------------
00007 #ifndef QUANTITIES_HXX
00008 #define QUANTITIES_HXX
00009 
00010 // We will make use of AST for operations involving WCS
00011 extern "C"
00012 {
00013   #include "ast.h"
00014 }
00015 
00016 #include <cmath>
00017 #include <string>
00018 
00019 #include "Constants.h"
00020 #include "Converter.h"
00021 #include "FitsFile.h"
00022 #include "Logger.h"
00023 #include "DataMethod.hxx"
00024 #include "DataOps.h"
00025 #include "StringOps.h"
00026 //-----------------------------------------------------------------------------
00034 template<typename DataType>
00035 class QuantitiesByAst : public DataMethod<DataType>
00036 {
00037 public:
00039   QuantitiesByAst(const FitsFile& aFile)
00040     : mFile(aFile)
00041     { DataMethod<DataType>::methodName = "QuantitiesByAst"; }
00042 
00044   virtual ~QuantitiesByAst() { }
00045 
00048   void setSource(IntMap& tbls, IntMap& cols, StringMap units)
00049     { extnumColno = cols[0]; }
00050 
00052   void setTarget(IntMap& cols, StringMap units)
00053   {
00054     raColno     = cols[0];
00055     decColno    = cols[1];
00056     posangColno = cols[2];
00057     extentColno = cols[3];
00058     xsizeColno  = cols[4];
00059     ysizeColno  = cols[5];
00060     minRaColno  = cols[6];
00061     minDecColno = cols[7];
00062     maxRaColno  = cols[8];
00063     maxDecColno = cols[9];
00064 
00065     // AST will calculate angles in radians, so we need the conversion
00066     // factors for the required units in the schema
00067     Converter conv;
00068     raFact     = conv.getFactor("RADIANS", units[0]);
00069     decFact    = conv.getFactor("RADIANS", units[1]);
00070     posangFact = conv.getFactor("RADIANS", units[2]);
00071     extentFact = conv.getFactor("RADIANS", units[3]);
00072     xsizeFact  = conv.getFactor("RADIANS", units[4]);
00073     ysizeFact  = conv.getFactor("RADIANS", units[5]);
00074     minRaFact  = conv.getFactor("RADIANS", units[6]);
00075     minDecFact = conv.getFactor("RADIANS", units[7]);
00076     maxRaFact  = conv.getFactor("RADIANS", units[8]);
00077     maxDecFact = conv.getFactor("RADIANS", units[9]);
00078   }
00079 
00081   void doit(TableData<DataType>& data, int row1, int row2)
00082   {
00083     std::string filename = mFile.getFileName();
00084     double crval1[4],crval2[4];
00085     int npixx[4], npixy[4];
00086 
00087     // Use these arrays for AST input
00088     double xpix[5], ypix[5], xsky[5], ysky[5];
00089 
00090     // Set up AST
00091     astBegin;
00092 
00093     // Create a new AST fits channel
00094     AstFitsChan *fitschan = astFitsChan( NULL, NULL, "" );
00095     AstFrameSet *wcsinfo0 = 0;
00096     AstFrameSet *wcsinfo1 = 0;
00097     AstFrameSet *wcsinfo2 = 0;
00098     AstFrameSet *wcsinfo3 = 0;
00099 
00100     // Get AST data from file
00101     for (int hduNo = 2; hduNo <= mFile.getNumHdus(); ++hduNo)
00102     {
00103       int ext = hduNo - 2;
00104       // Move to this extension on the FITS file
00105       mFile.movabsHdu(hduNo);
00106 
00107       // Put all cards in the header of this extension into the AST
00108       // fits channel
00109       int ncards = mFile.getNumCards();
00110       for (int n = 0; n < ncards; ++n) {
00111           char card[80];
00112           mFile.readCard(n, card);
00113           astPutFits(fitschan, card, 0);
00114       }
00115       // Make AST wcsinfo object
00116       astClear( fitschan, "Card" );
00117       mFile.readKey(FitsFile::cCRVAL1,crval1[ext]);
00118       mFile.readKey(FitsFile::cCRVAL2,crval2[ext]);
00119       if (crval1[ext] == 0 && crval2[ext] == 0) {
00120           log.addError("Could not read WCS info for " + filename);
00121       } else {
00122         if (ext == 0) {
00123           wcsinfo0 = (AstFrameSet*)astRead(fitschan);
00124         } else if (ext == 1) {
00125           wcsinfo1 = (AstFrameSet*)astRead(fitschan);
00126         } else if (ext == 2) {
00127           wcsinfo2 = (AstFrameSet*)astRead(fitschan);
00128         } else if (ext == 3) {
00129           wcsinfo3 = (AstFrameSet*)astRead(fitschan);
00130         }
00131         // Centre of image in pixel coordinates
00132 
00133         if (mFile.hasKey("ZIMAGE"))
00134         {
00135           mFile.readKey(FitsFile::ZNAXIS1, npixx[ext]);
00136           mFile.readKey(FitsFile::ZNAXIS2, npixy[ext]);
00137         }
00138         else
00139         {
00140           mFile.readKey(FitsFile::NAXIS1, npixx[ext]);
00141           mFile.readKey(FitsFile::NAXIS2, npixy[ext]);
00142         }
00143       }
00144     }
00145 
00146     for (int rowNo = row1; rowNo < row2; ++rowNo)
00147     {
00148       // Get the FITS extension number for the data in this row. Note
00149       // that the extension number is assumed to be in the fitsio
00150       // convention
00151       Numeric value;
00152       data.value(extnumColno, rowNo, value);
00153       int extNum = (int)value - 2;
00154 
00155       if (crval1[extNum] != 0 || crval2[extNum] != 0)
00156       {
00157         // Not sure how pixel coordinates are defined. What is (x,y) of the
00158         // centre of the first pixel?
00159         xpix[0] = (double)npixx[extNum] / 2;
00160         ypix[0] = (double)npixy[extNum] / 2;
00161 
00162         // Pixel coordinates of the four corners
00163         xpix[1] = 0;
00164         ypix[1] = 0;
00165         xpix[2] = npixx[extNum];
00166         ypix[2] = 0;
00167         xpix[3] = 0;
00168         ypix[3] = npixy[extNum];
00169         xpix[4] = npixx[extNum];
00170         ypix[4] = npixy[extNum];
00171 
00172         // Get the sky coordinates for the array of pixel coordinates. Note
00173         // these will be in radians. Angles can also be negative
00174         if (extNum == 0) {
00175           astTran2(wcsinfo0, 5, xpix, ypix, 1, xsky, ysky);
00176         } else if (extNum == 1) {
00177           astTran2(wcsinfo1, 5, xpix, ypix, 1, xsky, ysky);
00178         } else if (extNum == 2) {
00179           astTran2(wcsinfo2, 5, xpix, ypix, 1, xsky, ysky);
00180         } else if (extNum == 3) {
00181           astTran2(wcsinfo3, 5, xpix, ypix, 1, xsky, ysky);
00182         }
00183 
00184         // Make sure all RAs are in the range 0 to 2*pi
00185         for (int n = 0; n < 5; ++n)
00186         {
00187           if (xsky[n] < 0)
00188           {
00189             xsky[n] += 2*M_PI;
00190           }
00191         }
00192         // Get the central ra and dec in units as required in the schema
00193         Numeric raCen  = raFact * xsky[0];
00194         Numeric decCen = decFact * ysky[0];
00195 
00196         // Calculate max and min of RA and DEC from xsky, ysky
00197         // first find max and min values
00198         double xskyMin = 9999.999;
00199         double xskyMax = -9999.999;
00200         double yskyMin = 9999.999;
00201         double yskyMax = -9999.999;
00202         for (int n = 1; n < 5; ++n)
00203         {
00204           if (xsky[n] < xskyMin) xskyMin = xsky[n];
00205           if (xsky[n] > xskyMax) xskyMax = xsky[n];
00206           if (ysky[n] < yskyMin) yskyMin = ysky[n];
00207           if (ysky[n] > yskyMax) yskyMax = ysky[n];
00208         }
00209         // then project RA in 0 to 3*pi for fields crossing RA=0
00210         double h = 0.0;
00211         if (xskyMax - xskyMin > M_PI)
00212         {
00213           h = xskyMax;
00214           xskyMax = xskyMin + 2*M_PI;
00215           xskyMin = h;
00216         }
00217         Numeric raMin  = minRaFact * xskyMin;
00218         Numeric decMin = minDecFact * yskyMin;
00219         Numeric raMax  = maxRaFact * xskyMax;
00220         Numeric decMax = maxDecFact * yskyMax;
00221 
00222         // Find angular separation between the centre and each of the
00223         // four corners and find the maximum of these
00224         double maxsep = 0;
00225         for (int n = 0; n < 5; ++n)
00226         {
00227           double ang = DataOps::calcAngsep(xsky[0], ysky[0],
00228                                             xsky[n], ysky[n]);
00229           if (ang > maxsep) maxsep = ang;
00230         }
00231         // Take image extent as maximum separation and put in required units
00232         Numeric imageExtent = maxsep * extentFact;
00233 
00234         // Find the posAngle
00235         // Define N-S line by incrementing the ysky coordinate (usually dec)
00236         // by a small amount
00237         xsky[1] = xsky[0];
00238         ysky[1] = ysky[0] + 0.01;
00239         // Find equiavelent pixel corrinates for the N-S point
00240         if (extNum == 0) {
00241           astTran2(wcsinfo0, 5, xsky, ysky, 0, xpix, ypix);
00242         } else if (extNum == 1) {
00243           astTran2(wcsinfo1, 5, xsky, ysky, 0, xpix, ypix);
00244         } else if (extNum == 2) {
00245           astTran2(wcsinfo2, 5, xsky, ysky, 0, xpix, ypix);
00246         } else if (extNum == 3) {
00247           astTran2(wcsinfo3, 5, xsky, ysky, 0, xpix, ypix);
00248         }
00249         // Determine angle between N-S line and positive x-axis with origin
00250         // at the centre of the image
00251         Numeric posAng = posangFact * atan2(ypix[1] - ypix[0],
00252                                             xpix[1] - xpix[0]);
00253 
00254         // X and Y pixel size is calculated by incrementing the
00255         // respective pixel sizes at the image centre
00256         xpix[1] = xpix[0] + 1;
00257         ypix[1] = ypix[0];
00258         xpix[2] = xpix[0];
00259         ypix[2] = ypix[0] + 1;
00260         if (extNum == 0) {
00261           astTran2(wcsinfo0, 5, xpix, ypix, 1, xsky, ysky);
00262         } else if (extNum == 1) {
00263           astTran2(wcsinfo1, 5, xpix, ypix, 1, xsky, ysky);
00264         } else if (extNum == 2) {
00265           astTran2(wcsinfo2, 5, xpix, ypix, 1, xsky, ysky);
00266         } else if (extNum == 3) {
00267           astTran2(wcsinfo3, 5, xpix, ypix, 1, xsky, ysky);
00268         }
00269         Numeric xPixSize = xsizeFact * DataOps::calcAngsep(xsky[0], ysky[0],
00270                                                            xsky[1], ysky[1]);
00271         Numeric yPixSize = ysizeFact * DataOps::calcAngsep(xsky[0], ysky[0],
00272                                                            xsky[2], ysky[2]);
00273 
00274         data.assign(raColno, rowNo, raCen);
00275         data.assign(decColno, rowNo, decCen);
00276         data.assign(minRaColno, rowNo, raMin);
00277         data.assign(minDecColno, rowNo, decMin);
00278         data.assign(maxRaColno, rowNo, raMax);
00279         data.assign(maxDecColno, rowNo, decMax);
00280         data.assign(extentColno, rowNo, imageExtent);
00281         data.assign(posangColno, rowNo, posAng);
00282         data.assign(xsizeColno, rowNo, xPixSize);
00283         data.assign(ysizeColno, rowNo, yPixSize);
00284       }
00285     }
00286     // Finshed with AST
00287     astEnd;
00288   }
00289   // No data from raw data included
00290   void doit2(TableData<DataType>& rawData, TableData<DataType>& data, int row1, int row2) { }
00291 
00292 private:
00293   FitsFile mFile;
00294   Logger log;
00295 
00296   int extnumColno, raColno, decColno, posangColno;
00297   int extentColno, xsizeColno, ysizeColno;
00298   int minRaColno,maxRaColno,minDecColno,maxDecColno;
00299   double raFact, decFact, posangFact, extentFact, xsizeFact, ysizeFact;
00300   double minRaFact, maxRaFact, minDecFact, maxDecFact;
00301 };
00302 //-----------------------------------------------------------------------------
00303 #endif
00304 //-----------------------------------------------------------------------------
00305 // Change log:
00306 //
00307 //  7-Jun-2005, ETWS: Original version.
00308 // 22-Mar-2007, RSC:  Robustified against dodgy WCS values.
00309 //  2-May-2007,  RSC: Reverted to original design of allowing dodgy WCS values.
00310 //  7-Apr-2008, ETWS: Upgraded to use new detection table layout.

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