casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MSFitsInput.h
Go to the documentation of this file.
00001 //# MSFitsInput:  simple uvfits (random group) to MeasurementSet conversion
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This program is free software; you can redistribute it and/or modify
00006 //# it under the terms of the GNU General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or
00008 //# (at your option) any later version.
00009 //#
00010 //# This program is distributed in the hope that it will be useful,
00011 //# but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //# GNU General Public License for more details.
00014 //#
00015 //# You should have received a copy of the GNU General Public License
00016 //# along with this program; if not, write to the Free Software
00017 //# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: MSFitsInput.h 20739 2009-09-29 01:15:15Z Malte.Marquarding $
00027 
00028 #ifndef MS_MSFITSINPUT_H
00029 #define MS_MSFITSINPUT_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/Arrays/Matrix.h>
00033 #include <casa/Arrays/Vector.h>
00034 #include <casa/Containers/Block.h>
00035 #include <casa/Containers/Record.h>
00036 #include <fits/FITS/fits.h>
00037 #include <fits/FITS/hdu.h>
00038 #include <casa/Logging/LogIO.h>
00039 #include <ms/MeasurementSets/MeasurementSet.h>
00040 #include <measures/Measures/MDirection.h>
00041 #include <measures/Measures/MFrequency.h>
00042 #include <casa/BasicSL/String.h>
00043 #include <ms/MeasurementSets/MSTileLayout.h>
00044 #include <tables/Tables/BaseTable.h>
00045 
00046 namespace casa { //# NAMESPACE CASA - BEGIN
00047 
00048 class FitsInput;
00049 class BinaryTable;
00050 class MSColumns;
00051 
00052 // <summary>
00053 // A helper class for MSFitsInput
00054 // </summary>
00055 // <use visibility=local>
00056 // <etymology>
00057 // This class can hold a primary array of several datatypes
00058 // </etymology>
00059 // <synopsis>
00060 // This is a helper class to avoid cumbersome switch statements on the
00061 // template type of the primary array 
00062 // It forwards all the PrimaryArray member functions we need in the filler.
00063 // </synopsis>
00064 class MSPrimaryTableHolder
00065 {
00066   // This is a helper class to avoid cumbersome switch statements on the
00067   // template type of the primary array
00068   // It forwards all the PrimaryTable member function we need in the filler.
00069 public:
00070   // Construct an empty holder, used to attach to later
00071   MSPrimaryTableHolder();
00072 
00073   // Construct from an input file containing a FITS primary group hdu.
00074   // Throws an exception if the datatype is not Short, FitsLong or Float
00075   MSPrimaryTableHolder(FitsInput& infile);
00076 
00077   ~MSPrimaryTableHolder();
00078 
00079   // Attach to the input file, create the appropriate PrimaryArray.
00080   // Throws an exception if the datatype is not Short, FitsLong or Float
00081   void attach(FitsInput& infile);
00082 
00083   // Detach from the input file
00084   void detach();
00085 
00086   //# forwarding functions
00087 
00088   // Number of dimensions
00089   Int dims()
00090   {return hdu_p->dims();}
00091 
00092   // Length of i'th axis
00093   Int dim(Int i)
00094   {return hdu_p->dim(i);}
00095 
00096   // Coordinate type
00097   Char* ctype(Int i)
00098   { return pf ? pf->ctype(i) : (pl ? pl->ctype(i) : ps->ctype(i));}
00099 
00100   // Coordinate reference value
00101   Double crval(Int i)
00102   { return pf ? pf->crval(i) : (pl ? pl->crval(i) : ps->crval(i));}
00103 
00104   // Coordinate reference pixel
00105   Double crpix(Int i)
00106   { return pf ? pf->crpix(i) : (pl ? pl->crpix(i) : ps->crpix(i));}
00107 
00108   // Coordinate delta
00109   Double cdelt(Int i)
00110   { return pf ? pf->cdelt(i) : (pl ? pl->cdelt(i) : ps->cdelt(i));}
00111 
00112   // Keyword of given type
00113   const FitsKeyword* kw(const FITS::ReservedName& n)
00114   { return hdu_p->kw(n);}
00115 
00116   // All keywords
00117   ConstFitsKeywordList& kwlist()
00118   { return hdu_p->kwlist();}
00119 
00120   // Advance to next keyword
00121   const FitsKeyword* nextkw()
00122   { return hdu_p->nextkw();}
00123 
00124   // Read the next group
00125   Int read() {
00126      if (pf) return pf->read(); 
00127      else if (pl) return pl->read(); 
00128      else if (ps) return ps->read(); 
00129      else if (pb) return pb->read(); 
00130      else cout << "can not read the table" << endl;
00131      return 0;
00132   }
00133 
00134 private:
00135   HeaderDataUnit* hdu_p;
00136   PrimaryTable<Short>* ps;
00137   PrimaryTable<FitsLong>* pl;
00138   PrimaryTable<Float>* pf;
00139   PrimaryTable<uChar>* pb;
00140 };
00141 
00142 // <summary>
00143 // A helper class for MSFitsInput
00144 // </summary>
00145 // <use visibility=local>
00146 // <etymology>
00147 // This class can hold a primary group of several datatypes
00148 // </etymology>
00149 // <synopsis>
00150 // This is a helper class to avoid cumbersome switch statements on the
00151 // template type of the primary group
00152 // It forwards all the PrimaryGroup member functions we need in the filler.
00153 // </synopsis>
00154 class MSPrimaryGroupHolder
00155 {
00156   // This is a helper class to avoid cumbersome switch statements on the
00157   // template type of the primary group
00158   // It forwards all the PrimaryGroup member function we need in the filler.
00159 public:
00160   // Construct an empty holder, used to attach to later
00161   MSPrimaryGroupHolder();
00162 
00163   // Construct from an input file containing a FITS primary group hdu.
00164   // Throws an exception if the datatype is not Short, FitsLong or Float
00165   MSPrimaryGroupHolder(FitsInput& infile);
00166 
00167   ~MSPrimaryGroupHolder();
00168 
00169   // Attach to the input file, create the appropriate PrimaryGroup.
00170   // Throws an exception if the datatype is not Short, FitsLong or Float
00171   void attach(FitsInput& infile);
00172 
00173   // Detach from the input file
00174   void detach();
00175 
00176   //# forwarding functions
00177 
00178   // Number of dimensions
00179   Int dims()
00180   {return hdu_p->dims();}
00181 
00182   // Length of i'th axis
00183   Int dim(Int i)
00184   {return hdu_p->dim(i);}
00185 
00186   // Coordinate type
00187   Char* ctype(Int i)
00188   { return pf ? pf->ctype(i) : (pl ? pl->ctype(i) : ps->ctype(i));}
00189 
00190   // Coordinate reference value
00191   Double crval(Int i)
00192   { return pf ? pf->crval(i) : (pl ? pl->crval(i) : ps->crval(i));}
00193 
00194   // Coordinate reference pixel
00195   Double crpix(Int i)
00196   { return pf ? pf->crpix(i) : (pl ? pl->crpix(i) : ps->crpix(i));}
00197 
00198   // Coordinate delta
00199   Double cdelt(Int i)
00200   { return pf ? pf->cdelt(i) : (pl ? pl->cdelt(i) : ps->cdelt(i));}
00201 
00202   // Keyword of given type
00203   const FitsKeyword* kw(const FITS::ReservedName& n)
00204   { return hdu_p->kw(n);}
00205 
00206   // All keywords
00207   ConstFitsKeywordList& kwlist()
00208   { return hdu_p->kwlist();}
00209 
00210   // Advance to next keyword
00211   const FitsKeyword* nextkw()
00212   { return hdu_p->nextkw();}
00213 
00214   // Number of groups
00215   Int gcount() const
00216   { return pf ? pf->gcount() : ( pl ? pl->gcount() : ps->gcount());}
00217 
00218   // Number of parameters
00219   Int pcount() const
00220   { return pf ? pf->pcount() : ( pl ? pl->pcount() : ps->pcount());}
00221 
00222   // Parameter type
00223   Char* ptype(Int i) const
00224   { return pf ? pf->ptype(i) : ( pl ? pl->ptype(i) : ps->ptype(i));}
00225 
00226   // Read the next group
00227   Int read()
00228   { return pf ? pf->read() : ( pl ? pl->read() : ps->read());}
00229 
00230   // Get i'th parameter
00231   Double parm(Int i)
00232   { return pf ? pf->parm(i) : ( pl ? pl->parm(i) : ps->parm(i));}
00233 
00234   // Get group data with index i, scaled and converted to Double
00235   Double operator () (Int i) const
00236   { return pf ? (*pf)(i) : ( pl ? (*pl)(i) : (*ps)(i));}
00237 
00238 private:
00239   HeaderDataUnit* hdu_p;
00240   PrimaryGroup<Short>* ps;
00241   PrimaryGroup<FitsLong>* pl;
00242   PrimaryGroup<Float>* pf;
00243 };
00244 
00245 // <summary>
00246 // UV FITS to MeasurementSet filler
00247 // </summary>
00248 
00249 // <use visibility=export>
00250 
00251 // <prerequisite>
00252 //   <li> MeasurementSet
00253 //   <li> FITS classes
00254 // </prerequisite>
00255 //
00256 // <etymology>
00257 // MSFitsInput handles the conversion of FITS files to MeasurementSets
00258 // </etymology>
00259 //
00260 // <synopsis>
00261 // UV FITS to MeasurementSet filler. This can handle single source fits and
00262 // multi source fits as written by classic AIPS. Also copes with multiple
00263 // arrays (i.e. multiple AN tables) but doesn't correct for 5 day offsets
00264 // introduced by DBCON.
00265 // </synopsis>
00266 
00267 class MSFitsInput
00268 {
00269   // This is an implementation helper class used to store 'local' data
00270   // during the filling process.
00271 public:
00272   // Create from output and input file names. This function opens the input
00273   // file, and checks the output file is writable.
00274   MSFitsInput(const String& msFile, const String& fitsFile, const Bool NewNameStyle=False);
00275 
00276   // The destructor is fairly trivial.
00277   ~MSFitsInput();
00278 
00279   // Read all the data from the FITS file and create the MeasurementSet. Throws
00280   // an exception when it has severe trouble interpreting the FITS file.
00281   // 
00282   void readFitsFile(Int obsType = MSTileLayout::Standard);
00283 
00284 protected:
00285 
00286   // Check that the input is a UV fits file with required contents.
00287   // Returns False if not ok.
00288   Bool checkInput(FitsInput& infile);
00289 
00290   // Read the axis info of the primary group, throws an exception if required
00291   // axes are missing.
00292   void getPrimaryGroupAxisInfo();
00293 
00294   // Set up the MeasurementSet, including StorageManagers and fixed columns.
00295   // If useTSM is True, the Tiled Storage Manager will be used to store
00296   // DATA, FLAG and WEIGHT_SPECTRUM. Use obsType to choose the tiling
00297   // scheme.
00298   void setupMeasurementSet(const String& MSFileName, Bool useTSM=True,
00299                Int obsType = MSTileLayout::Standard);
00300 
00302   // Read a binary table extension of type AIPS AN and create an antenna table
00303   void fillAntennaTable(BinaryTable& bt);
00304 
00305   // Read a binary table extension and update history table
00306   void fillHistoryTable(ConstFitsKeywordList& kwl);
00307 
00308   // Read a binary table extension and update history table
00309   void fillObservationTable(ConstFitsKeywordList& kwl);
00310 
00311   //extract axis information
00312   void getAxisInfo(ConstFitsKeywordList&);
00313 
00314   //extract axis information
00315   void sortPolarizations();
00316 
00317   void fillPolarizationTable();
00318 
00319   //verify that the fits contains visibility data
00320   void checkRequiredAxis();
00321 
00322   void fillSpectralWindowTable(BinaryTable& bt);
00323 
00324   // fill Field table 
00325   void fillFieldTable(BinaryTable& bt);
00326   void fillFieldTable(double, double, String);
00327 
00328   void fillMSMainTable(BinaryTable& bt);
00329 
00330   void fillPointingTable();
00331 
00332   void fillSourceTable();
00333 
00334   // fill the Feed table with minimal info needed for synthesis processing
00335   void fillFeedTable();
00336 
00338   // Fill the Observation and ObsLog tables
00339   void fillObsTables();
00340 
00341   // Fill the main table from the Primary group data
00342   // if we have enough memory try to do it in mem
00343   void fillMSMainTableColWise(Int& nField, Int& nSpW);
00344   //else do it row by row
00345   void fillMSMainTable(Int& nField, Int& nSpW);
00346 
00347   // fill spectralwindow table from FITS FQ table + header info
00348   void fillSpectralWindowTable(BinaryTable& bt, Int nSpW);
00349 
00350   // fill spectralwindow table from header
00351   void fillSpectralWindowTable();
00352 
00353   // fill Field table from FITS SU table
00354   void fillFieldTable(BinaryTable& bt, Int nField);
00355 
00356   // fill Field table from header (single source fits)
00357   void fillFieldTable(Int nField);
00358 
00359   // fill the Pointing table (from Field table, all antennas are assumed
00360   // to point in the field direction) and possibly the Source table.
00361   void fillExtraTables();
00362 
00363   // fix up the EPOCH MEASURE_REFERENCE keywords using the value found
00364   // in the (last) AN table
00365   void fixEpochReferences();
00366 
00367   // Returns the Direction Measure reference for UVW and other appropriate columns
00368   // in msc_p (which must exist but have empty columns before you can set it!).
00369   MDirection::Types getDirectionFrame(Double epoch);
00370   
00371   // Check the frame if there is an SU table
00372   void setFreqFrameVar(BinaryTable& binTab);
00373   // update a the Spectral window post filling if necessary
00374   void updateSpectralWindowTable();
00375 
00376   void readRandomGroupUVFits(Int obsType);
00377   void readPrimaryTableUVFits(Int obsType);
00378 
00379 
00380 private:
00381   //# The default constructor is private and undefined
00382   MSFitsInput();
00383   //# The copy constructor is private and undefined
00384   MSFitsInput(const MSFitsInput& other);
00385   //# The assignment operator is private and undefined
00386   MSFitsInput& operator=(const MSFitsInput& other);
00387 
00388 
00389   FitsInput* infile_p;
00390   String msFile_p;
00391   MSPrimaryGroupHolder priGroup_p;
00392   MSPrimaryTableHolder priTable_p;
00393   MeasurementSet ms_p;
00394   MSColumns* msc_p;
00395   Int nIF_p;
00396   Vector<Int> nPixel_p,corrType_p;
00397   Block<Int> corrIndex_p;
00398   Matrix<Int> corrProduct_p;
00399   Vector<String> coordType_p;
00400   Vector<Double> refVal_p, refPix_p, delta_p;
00401   String array_p,object_p,timsys_p;
00402   Double epoch_p;
00403   MDirection::Types epochRef_p; // This is a direction measure reference code
00404                                 // determined by epoch_p, hence the name and type.
00405   Int nAnt_p;
00406   Int nArray_p;
00407   Vector<Double> receptorAngle_p;
00408   MFrequency::Types freqsys_p;
00409   Double restfreq_p;
00410   Bool addSourceTable_p;
00411   LogIO itsLog;
00412   Record header;
00413   Double refFreq_p;
00414   Bool useAltrval;
00415   Vector<Double> chanFreq_p;
00416   Bool newNameStyle;
00417   Vector<Double> obsTime;
00418 };
00419 
00420 
00421 } //# NAMESPACE CASA - END
00422 
00423 #endif