casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
AntennaResponses.h
Go to the documentation of this file.
00001 //# AntennaResponses.h: AntennaResponses provides access to antenna response data
00002 //# Copyright (C) 1995-1999,2000-2004
00003 //# Associated Universities, Inc. Washington DC, USA
00004 //# Copyright by ESO (in the framework of the ALMA collaboration)
00005 //#
00006 //# This library is free software; you can redistribute it and/or modify it
00007 //# under the terms of the GNU Library General Public License as published by
00008 //# the Free Software Foundation; either version 2 of the License, or (at your
00009 //# option) any later version.
00010 //#
00011 //# This library is distributed in the hope that it will be useful, but WITHOUT
00012 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 //# License for more details.
00015 //#
00016 //# You should have received a copy of the GNU Library General Public License
00017 //# along with this library; if not, write to the Free Software Foundation,
00018 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00019 //#
00020 //# Correspondence concerning CASA should be addressed as follows:
00021 //#        Internet email: aips2-request@nrao.edu.
00022 //#        Postal address: CASA Project Office
00023 //#                        National Radio Astronomy Observatory
00024 //#                        520 Edgemont Road
00025 //#                        Charlottesville, VA 22903-2475 USA
00026 //#
00027 //#
00028 //# $Id: $
00029 
00030 #ifndef IMAGES_ANTENNARESPONSES_H
00031 #define IMAGES_ANTENNARESPONSES_H
00032 
00033 //# Includes
00034 #include <casa/aips.h>
00035 #include <casa/Arrays/Vector.h>
00036 #include <casa/Exceptions/Error.h>
00037 #include <measures/Measures/MPosition.h>
00038 #include <measures/Measures/MDirection.h>
00039 #include <measures/Measures/MEpoch.h>
00040 #include <measures/Measures/MFrequency.h>
00041 #include <measures/Measures/MeasFrame.h>
00042 #include <measures/Measures/MeasRef.h>
00043 #include <measures/Measures/MeasTable.h>
00044 #include <images/Images/TempImage.h>
00045 #include <casa/OS/Time.h>
00046 #include <casa/Quanta/MVAngle.h>
00047 #include <casa/System/AipsrcValue.h>
00048 #include <casa/BasicSL/String.h>
00049 #include <casa/iostream.h>
00050 
00051 namespace casa { //# NAMESPACE CASA - BEGIN
00052 
00053 
00054 // <summary>
00055 // AntennaResponses provides access to antenna response data
00056 // </summary>
00057 
00058 // <use visibility=local>
00059 
00060 // <reviewed reviewer="Ger van Diepen, Max Voronkov, Dirk Petry, Remy Indebetouw" date="Jan 2011" tests="tAntennaResponses" demos="">
00061 // </reviewed>
00062 
00063 // <prerequisite>
00064 //   <li> <linkto class=Measure>Measure</linkto> class 
00065 // </prerequisite>
00066 //
00067 // <etymology>
00068 // 
00069 // </etymology>
00070 //
00071 // <synopsis>
00072 //  The location of the AntennaResponses table for a given observatory is set
00073 //  in the column String ANTENNA_RESPONSES in the "Observatories" table (accessed
00074 //  via the MeasTable class).
00075 //
00076 //  The detailed rules of how the location and name of the table is derived
00077 //  from the string found in ANTENNA_RESPONSES is described further down
00078 //  in the comment to the initAntennaResponses() method. 
00079 //
00080 //  E.g., for ALMA, the location of the table would be
00081 //
00082 //          data/alma/AntennaResponses
00083 //
00084 //  and the entry in the Observatories table would be simply "alma/AntennaResponses".
00085 // 
00086 //  "AntennaResponses" is the recommended name of the table but in principle any
00087 //  name can be used. That name will then have to be given in the Observatories table.
00088 //
00089 //  Contents of the AntennaResponses table:
00090 //
00091 //    column 0: Int BEAM_ID (a unique number in the table for the given observatory name)
00092 //    column 1: String NAME (name of the observatory as in the observatory table)
00093 //    column 2: Int BEAM_NUMBER (for observataories which support several simultaneous beams, zero-based)
00094 //    column 3: Double START_TIME (a Measure, the time from which onwards this table row is valid)
00095 //    column 4: String ANTENNA_TYPE (for ALMA: "DV", "DA", "PM", or "CM")
00096 //    column 5: String RECEIVER_TYPE (for ALMA this will not be filled, at least for the moment)
00097 //    column 6: Int NUM_SUBBANDS (number of response frequency sub-bands)
00098 //    column 7: Array String (size set by NUM_SUBBANDS) BAND_NAME (for ALMA: "1", "2" etc.)
00099 //                            (if there is more than one sub-band per band, the band name repeats)
00100 //    column 8: Array Double (a Quantum, size set by NUM_SUBBANDS) SUBBAND_MIN_FREQ
00101 //    column 9: Array Double (a Quantum, size set by NUM_SUBBANDS) SUBBAND_MAX_FREQ
00102 //    column 10: MDirection CENTER (the nominal center sky position where this row is valid, default (0.,90.) AZEL)
00103 //    column 11: MDirection VALID_CENTER_MIN (sky position validity range min values, default (0.,0.) AZEL)
00104 //    column 12: MDirection VALID_CENTER_MAX (sky position validity range max values, default (360.,90.) AZEL)
00105 //    column 13: Array Int (size set by NUM_SUBBANDS) FUNCTION_TYPE
00106 //                      (uses enum FuncTypes defined below:
00107 //                       EFP = complex electric field pattern image,
00108 //                       VP = voltage pattern image,
00109 //                       AIF = complex aperture illumination function image,
00110 //                       NA = the function is not yet available,
00111 //              here other codes can be easily added, e.g.
00112 //              VPMAN = the function is available in casa via the vp manager (details t.b.d.),
00113 //              INTERNAL = the function is generated on the fly internally
00114 //                       using ray-tracing as for the EVLA)
00115 //    column 14: Array String (size set by NUM_SUBBANDS) FUNCTION_NAME
00116 //                   (names of the images as paths relative to the directory
00117 //                    where this table is located,
00118 //                    empty string if no image is available for the band, e.g.
00119 //                    "ticra_efield_patterns/melco12m_band6_efp.im")
00120 //    column 15: Array uInt (size set by NUM_SUBBANDS) FUNCTION_CHANNEL
00121 //                   (the spectral image channel to use, can be different from 0 in the case
00122 //                    that several antenna responses are stored in one image file)
00123 //    column 16: Array Double (a Quantum, size set by NUM_SUBBANDS) NOMINAL_FREQ
00124 //                    (the nominal frequency of the channel given by FUNCTION_CHANNEL)
00125 //    column 17: Array Double (a Quantum, size set by NUM_SUBBANDS) RESPONSE_ROTATION_OFFSET
00126 //                    (the angle of an additional constant rotation of the response image)
00127 //                     project-dependent implementation) 
00128 //
00129 //  It is assured by the table filling code that columns 10, 11, and 12 use the same MDirection type.
00130 // </synopsis>
00131 //
00132 // <example>
00133 // 
00134 // </example>
00135 //
00136 // <motivation>
00137 // Information on receiver bands and corresponding primary beams
00138 // (in whatever form) for different antenna types needs to be made
00139 // available to the CASA code in a place where imaging code
00140 // can pick it up.
00141 // </motivation>
00142 //
00143 // <todo asof="2001/01/17">
00144 //   <li>
00145 // </todo>
00146 
00147 class AntennaResponses {
00148 
00149 public:
00150 
00151   enum FuncTypes{
00152     NA, // not available
00153     AIF, // complex aperture illumination function
00154     EFP, // complex electric field pattern
00155     VP, // real voltage pattern
00156     VPMAN, // the function is available in casa via the vp manager (details t.b.d.)
00157     INTERNAL, // the function is generated on the fly internally
00158     N_FuncTypes,
00159     ANY, // used in requests
00160     INVALID
00161   };
00162   // this can of course be extended for additional types if necessary
00163 
00164   // Constructor, does not call init()
00165   AntennaResponses(){}; 
00166 
00167   // Constructor, calls init()
00168   AntennaResponses(const String& path); 
00169 
00170   // Takes the path (as taken from the new ANTENNA_RESPONSES column of the Observatories table)
00171   // and uses it as the name and location of the AntennaResponses table, and then initializes 
00172   // the member vectors;
00173   // can be called repeatedly with different paths;
00174   // each call will overwrite the vectors.
00175   // If the path is an empty string, the member vectors will be reset to empty, i.e.
00176   // this is interpreted to mean that there is no AntennaResponses table on disk.
00177   // Returns True unless for some reason the initialisation fails (other than path=="").
00178   Bool init(const String& path="");
00179 
00180   // As init but does not overwrite the table (member vectors) in memory.
00181   // Instead it appends to the vectors.
00182   // Returns False if the path was already read before.
00183   Bool append(const String& path);
00184 
00185   // returns True if paths_p has at least one member
00186   Bool isInit(); 
00187 
00188   // returns True if path is a member element of paths_p, i.e. the contents of path was read
00189   Bool isInit(const String& path); 
00190 
00191   // find the row containing the information pertinent to the given parameters
00192   // (this is also the index in the member vectors)
00193   // and the index (subband) to the frequency channel of the response
00194   // return false if no matching row could be found
00195   Bool getRowAndIndex(uInt& row, uInt& subBand,
00196                       const String& obsName,
00197                       const MEpoch& obsTime,
00198                       const MFrequency& freq, // if requFType==INTERNAL, a frequency value of 0 (zero) will return the first row and band found
00199                       const FuncTypes& requFType = ANY, // the requested function type
00200                       const String& antennaType = "",
00201                       const MDirection& center = MDirection(Quantity( 0., "deg"), // the center to be matched with the CENTER column,
00202                                                             Quantity(90., "deg"), // default is the Zenith
00203                                                             MDirection::AZEL), // the center to be matched with the CENTER column
00204                       const String& receiverType = "",
00205                       const Int& beamNumber = 0);
00206 
00207   // overloaded method: as previous method but using beamId
00208   // (instead of obs. time, ant. type,  rec. type, center, and beam number)
00209   Bool getRowAndIndex(uInt& row, uInt& subBand,
00210                       const String& obsName,
00211                       const Int& beamId,
00212                       const MFrequency& freq);
00213 
00214   // getRowAndIndex is then used by the following methods
00215 
00216   // Access methods for the response images: takes an observatory name, 
00217   // an observation time, the antenna type (e.g. "DV"), the receiverType,
00218   // a frequency, a function type (enum FuncTypes, can be ANY, i.e. take the first available),
00219   // a direction, and a beam number and finds the appropriate image in the AntennaResponses table
00220   // which contains the image of the requested type and returns
00221   // the path, the channel to use, the frequency of that channel, and the FuncType of the image.
00222   // The image will contain a spectral axis even if degenerate.
00223   // The direction axis pair of the stored images is set as follows:
00224   // The axes are parallel to the ones given by the coordinate system type of the CENTER column
00225   // of the AntennaReponses table. The center of the image is that given by the CENTER column.
00226   // Furthermore, the images contain a Stokes axis (even if degenerate) to express the
00227   // beams for the different polarizations or polarization products.
00228   // Returns false if no appropriate image could be found.
00229   Bool getImageName(String& functionImageName, // the path to the image
00230                     uInt& funcChannel, // the channel to use in the image  
00231                     MFrequency& nomFreq, // nominal frequency of the image (in the given channel)
00232                     FuncTypes& fType, // the function type of the image
00233                     MVAngle& rotAngOffset, // the response rotation angle offset
00234                     const String& obsName, // (the observatory name, e.g. "ALMA" or "ACA")
00235                     const MEpoch& obsTime,
00236                     const MFrequency& freq,
00237                     const FuncTypes& requFType = ANY, // the requested function type
00238                     const String& antennaType = "",
00239                     const MDirection& center = MDirection(Quantity( 0., "deg"), // the center to be matched with the CENTER column,
00240                                                           Quantity(90., "deg"), // default is the Zenith
00241                                                           MDirection::AZEL), 
00242                     const String& receiverType = "",
00243                     const Int& beamNumber=0);   
00244                 
00245   // Overloaded method: as previous method but using beamId
00246   // (instead of obs. time, ant. type,  rec. type, center, and functype)
00247   Bool getImageName(String& functionImageName,
00248                     uInt& funcChannel, // the channel to use in the image  
00249                     MFrequency& nomFreq, // nominal frequency of the image (at the given channel) 
00250                     FuncTypes& fType, // the function type of the image
00251                     MVAngle& rotAngOffset, // the response rotation angle offset
00252                     const String& obsName, // (the observatory name, e.g. "ALMA" or "ACA")
00253                     const Int& beamId,
00254                     const MFrequency& freq);
00255 
00256   // Get a vector containing all unique antenna type strings for the given constraints
00257   Bool getAntennaTypes(Vector<String>& antTypes,
00258                        const String& obsName, // (the observatory name, e.g. "ALMA" or "ACA")
00259                        const MEpoch& obsTime,
00260                        const MFrequency& freq,
00261                        const FuncTypes& requFType = ANY, // the requested function type
00262                        const MDirection& center = MDirection(Quantity( 0., "deg"), // the center to be matched with the CENTER column,
00263                                                              Quantity(90., "deg"), // default is the Zenith
00264                                                              MDirection::AZEL), 
00265                        const String& receiverType = "",
00266                        const Int& beamNumber=0);
00267 
00268 
00269   // Put the given row into the present antenna reponses table (in memory).
00270   // If the row exists at the position given by uInt row, it is overwritten.
00271   // If it doesn't exist, the table is resized by one in memory and the new
00272   // row is added at the last position. The variable "row" then contains the
00273   // actual row that was filled.
00274   // Returns false, if the table was not initialised or the given data was
00275   // not consistent.
00276   // Consistency checks: 
00277   //   - all vectors have same dimension which is then used to set numSubbands
00278   //   - beamId is unique for the given observatory
00279   //   - center, validCenterMin, and validCenterMax have the same MDirection type
00280   Bool putRow(uInt& row,
00281               const String& obsName,
00282               const Int& beamId,
00283               const Vector<String>& bandName,
00284               const Vector<MVFrequency>& subbandMinFreq,
00285               const Vector<MVFrequency>& subbandMaxFreq,
00286               const Vector<FuncTypes>& funcType,
00287               const Vector<String>& funcName,
00288               const Vector<uInt>& funcChannel, 
00289               const Vector<MVFrequency>& nomFreq,
00290               const Vector<MVAngle>& rotAngOffset, 
00291               const String& antennaType = "",
00292               const MEpoch& startTime = MEpoch(MVEpoch(Quantity(40588., "d")), MEpoch::UTC), // beginning of 1970
00293               const MDirection& center = MDirection(Quantity( 0., "deg"), // the center to be matched with the CENTER column,
00294                                                     Quantity(90., "deg"), // default is the Zenith
00295                                                     MDirection::AZEL), 
00296               const MDirection& validCenterMin = MDirection(Quantity( 0., "deg"), 
00297                                                             Quantity( 0., "deg"), 
00298                                                             MDirection::AZEL),  
00299               const MDirection& validCenterMax = MDirection(Quantity( 360., "deg"),
00300                                                             Quantity( 90., "deg"),
00301                                                             MDirection::AZEL),  
00302               const String& receiverType = "",
00303               const Int& beamNumber = 0);
00304 
00305   // Create an new AntennaReponses table on disk at the given path
00306   // and fill it with the table contents presently in memory.
00307   // Throw exceptions if there are problems writing the table. 
00308   void create(const String& path);
00309 
00310   // Convert from Int to FuncType
00311   FuncTypes FuncType(Int i);
00312 
00313   // Convert from String to FuncType
00314   static FuncTypes FuncType(const String& sftyp);
00315 
00316   // get the name of the band corresponding to the frequency (in the rest frame of the observatory)
00317   Bool getBandName(String& bandName,
00318                    const String& obsName, 
00319                    const MVFrequency& freq);
00320 
00321 private:
00322 
00323   // after initialization, this contains the name of the path where the 
00324   // AntennaResponses table was read from;
00325   // if append was used to read additional tables in the memory table,
00326   // then this vector has several elements representing the different tables
00327   Vector<String> paths_p; 
00328 
00329   // here a complete copy of the AntennaResponses table is stored
00330   uInt numRows_p;
00331   Vector<String> ObsName_p;
00332   Vector<MEpoch> StartTime_p;
00333   Vector<String> AntennaType_p;
00334   Vector<String> ReceiverType_p;
00335   Vector<Int> BeamId_p;
00336   Vector<Int> BeamNumber_p;
00337   Vector<MDirection> ValidCenter_p;
00338   Vector<MDirection> ValidCenterMin_p;
00339   Vector<MDirection> ValidCenterMax_p;
00340   Vector<uInt> NumSubbands_p;
00341   Vector<Vector<String> > BandName_p;
00342   Vector<Vector<MVFrequency> > SubbandMinFreq_p;
00343   Vector<Vector<MVFrequency> > SubbandMaxFreq_p;
00344   Vector<Vector<FuncTypes> > FuncType_p;
00345   Vector<Vector<String> > FuncName_p;
00346   Vector<Vector<uInt> > FuncChannel_p;
00347   Vector<Vector<MVFrequency> > NomFreq_p;
00348   Vector<Vector<MVAngle> > RotAngOffset_p;
00349 
00350   // not part of the table but same number of elements:
00351   // memory of the path from which the row was read (index to paths_p)
00352   Vector<uInt> pathIndex_p; 
00353 
00354 };
00355 
00356 
00357 } //# NAMESPACE CASA - END
00358 
00359 #endif