00001 //# MeasurementSet.h: A Table to hold astronomical data (a set of Measurements) 00002 //# Copyright (C) 1996,1997,1999,2000,2001,2003 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts 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 //# 00027 //# $Id$ 00028 00029 #ifndef MS_MEASUREMENTSET_H 00030 #define MS_MEASUREMENTSET_H 00031 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/ms/MeasurementSets/MSTable.h> 00034 #include <casacore/ms/MeasurementSets/MSMainEnums.h> 00035 #include <casacore/ms/MeasurementSets/MSAntenna.h> 00036 #include <casacore/ms/MeasurementSets/MSDataDescription.h> 00037 #include <casacore/ms/MeasurementSets/MSDoppler.h> 00038 #include <casacore/ms/MeasurementSets/MSFeed.h> 00039 #include <casacore/ms/MeasurementSets/MSField.h> 00040 #include <casacore/ms/MeasurementSets/MSFlagCmd.h> 00041 #include <casacore/ms/MeasurementSets/MSFreqOffset.h> 00042 #include <casacore/ms/MeasurementSets/MSHistory.h> 00043 #include <casacore/ms/MeasurementSets/MSObservation.h> 00044 #include <casacore/ms/MeasurementSets/MSPointing.h> 00045 #include <casacore/ms/MeasurementSets/MSPolarization.h> 00046 #include <casacore/ms/MeasurementSets/MSProcessor.h> 00047 #include <casacore/ms/MeasurementSets/MSSource.h> 00048 #include <casacore/ms/MeasurementSets/MSSpectralWindow.h> 00049 #include <casacore/ms/MeasurementSets/MSState.h> 00050 #include <casacore/ms/MeasurementSets/MSSysCal.h> 00051 #include <casacore/ms/MeasurementSets/MSWeather.h> 00052 #include <set> 00053 00054 00055 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00056 00057 class MrsEligibility { // Memory Resident Subtable (Mrs) Eligibility (no pun intended) 00058 00059 public: 00060 00061 typedef MSMainEnums::PredefinedKeywords SubtableId; 00062 00063 friend MrsEligibility operator- (const MrsEligibility & a, SubtableId subtableId); 00064 friend MrsEligibility operator+ (const MrsEligibility & a, SubtableId subtableId); 00065 friend MrsEligibility operator- (const MrsEligibility & a, const MrsEligibility & b); 00066 friend MrsEligibility operator+ (const MrsEligibility & a, const MrsEligibility & b); 00067 00068 // Returns true if the specified subtable is in the set of subtables 00069 // eligible for memory residency. 00070 Bool isEligible (SubtableId subtableId) const; 00071 00072 // Factory methods to create MrsEligibility sets. The two variable argument methods 00073 // require that the list be terminated by using the id MSMainEnums::UNDEFINED_KEYWORD. 00074 // 00075 static MrsEligibility allEligible (); 00076 static MrsEligibility defaultEligible (); 00077 static MrsEligibility noneEligible (); 00078 static MrsEligibility eligibleSubtables (SubtableId subtableId, ...); 00079 static MrsEligibility allButTheseSubtables (SubtableId ineligibleSubtableId, ...); 00080 00081 private: 00082 00083 typedef std::set<MSMainEnums::PredefinedKeywords> Eligible; 00084 00085 Eligible eligible_p; 00086 00087 static const MrsEligibility allSubtables_p; 00088 00089 static Bool isSubtable (SubtableId subtableId); 00090 }; 00091 00092 // Creates a new MrsEligibilitySet by adding or removing the specified subtable or 00093 // the specified set of subtables. 00094 MrsEligibility operator- (const MrsEligibility & a, MrsEligibility::SubtableId subtableId); 00095 MrsEligibility operator+ (const MrsEligibility & a, MrsEligibility::SubtableId subtableId); 00096 MrsEligibility operator- (const MrsEligibility & a, const MrsEligibility & b); 00097 MrsEligibility operator+ (const MrsEligibility & a, const MrsEligibility & b); 00098 00099 //# Forward Declarations, more could be if they weren't part of the 00100 //# static classes 00101 class SetupNewTable; 00102 template <class T> class Block; 00103 class MDirection; 00104 class MEpoch; 00105 class MFrequency; 00106 class MPosition; 00107 class Record; 00108 00109 //# forward declared so that the following typedef is up-front 00110 class MeasurementSet; 00111 00112 // MeasurementSet is too cumbersome for a number of common uses, 00113 // so we give a typedef here. 00114 typedef MeasurementSet MS; 00115 00116 // <summary> 00117 // A Table intended to hold astronomical data (a set of Measurements). 00118 // </summary> 00119 00120 // <use visibility=export> 00121 00122 // <reviewed reviewer="Bob Garwood" date="1997/02/01" tests="tMeasurementSet.cc" demos=""> 00123 00124 // <prerequisite> 00125 // <li> <linkto module="Tables:description">Tables</linkto> module 00126 // <li> <linkto class="MSTable">MSTable</linkto> 00127 // </prerequisite> 00128 // 00129 // <etymology> 00130 // The MeasurementSet is where all data are ultimately to be found 00131 // in Casacore. Since, this is a collection of 00132 // measurements (either actual or simulated), the term MeasurementSet 00133 // seems appropriate. 00134 // </etymology> 00135 // 00136 // <synopsis> 00137 // A MeasurementSet is a Table. Most operations on a MeasurementSet are 00138 // Table operations. See the <linkto module="Tables:description">Tables</linkto> 00139 // module for a list of those operations. The member functions provided by this 00140 // class are primarily convenience functions to help users follow the 00141 // agreed upon column and keyword naming conventions. They are useful when 00142 // creating a Table following the MeasurementSet conventions from 00143 // scratch as well as when creating the column objects to access those 00144 // columns. 00145 // 00146 // The standard way of accessing 00147 // table columns is through Strings. Mistakes in typing the column 00148 // name will not be caught at compile time (and may not be caught at 00149 // run time). We have therefore decided to use an enumeration 00150 // to specify columns so that many mistakes will be caught at compile 00151 // time. This requires functions to map to and from this enumeration 00152 // to the strings that are ultimately used. 00153 // 00154 // Upon destruction, the table is checked to see that the 00155 // MeasurementSet remains valid, i.e., all required columns are present 00156 // An exception is thrown if not all required columns are present 00157 // Nevertheless, the table will be flushed to disk if it is writable - 00158 // preserving its state. 00159 // 00160 // A MeasurementSet has a number of required subtables. These are stored 00161 // as keywords in the Table. Access to these subtables is provided via 00162 // member functions (e.g. antenna() for the ANTENNA table). All subtables 00163 // have associated MeasurementSet-like classes defined for them (MSAntenna 00164 // for the ANTENNA table) which provide analogous column and keyword mapping 00165 // as provided here. 00166 // 00167 // While the class name, MeasurementSet, is descriptive, it is often 00168 // too long for many common uses. The typedef MS is provided as 00169 // a convenient shorthand for MeasurementSet. The example below uses this 00170 // typedef. 00171 // 00172 // Due to the inheritance scheme, it was necessary to separate the enumerations 00173 // used by MeasurementSet into a separate class, 00174 // <linkto class=MSMainEnums>MSMainEnums</linkto>. 00175 // 00176 // </synopsis> 00177 // 00178 // <example> 00179 // This example illustrates a simple use of the MeasurementSet class. 00180 // <srcblock> 00181 // // create the table descriptor 00182 // TableDesc simpleDesc = MS::requiredTableDesc(); 00183 // // set up a new table 00184 // SetupNewTable newTab("simpleTab", simpleDesc, Table::New); 00185 // // create the MeasurementSet 00186 // MeasurementSet simpleMS(newTab); 00187 // // now we need to define all required subtables 00188 // // the following call does this for us if we don't need to 00189 // // specify details of Storage Managers for columns. 00190 // simpleMS.createDefaultSubtables(Table::New); 00191 // // fill MeasurementSet via its Table interface 00192 // // For example, construct one of the columns 00193 // TableColumn feed(simpleMS, MS::columnName(MS::FEED1)); 00194 // uInt rownr = 0; 00195 // // add a row 00196 // simpleMS.addRow(); 00197 // // set the values in that row, e.g. the feed column 00198 // feed.putScalar(rownr,1); 00199 // // Access a subtable 00200 // ArrayColumn<Double> antpos(simpleMS.antenna(), 00201 // MSAntenna::columnName(MSAntenna::POSITION)); 00202 // simpleMS.antenna().addRow(); 00203 // Array<Double> position(3); 00204 // position(0)=1.; position(1)=2.; position(2)=3.; 00205 // antpos.put(0,position); 00206 // // etc. 00207 // </srcblock> 00208 // 00209 // </example> 00210 // 00211 // <motivation> 00212 // The Table module is more than adequate as a container of data. 00213 // However, in order for applications to be useful with data from 00214 // different sources, some conventions need to be adopted in the use 00215 // of Tables to store data. The MeasurementSet is 00216 // where those conventions are defined and, to some extent, enforced. 00217 // 00218 // There are a number of reasons why MeasurementSet is more 00219 // than just a Table. 00220 // <ul> 00221 // <li> To provide one location where the column and keyword names, data 00222 // types, and table comment strings are found. 00223 // <li> To provide one location where the required table descriptor for 00224 // the MeasurementSet is found. 00225 // <li> To provide a means of verifying the validity of a MeasurementSet 00226 // at construction and destruction. 00227 // <li> To allow application programmers to catch name or data type 00228 // mistakes at compile time rather than at run time. 00229 // </ul> 00230 // 00231 // </motivation> 00232 // 00233 // <todo asof="1996/2/22"> 00234 // <li> referenceCopy() should be more flexible with the storage managers used 00235 // for the columns which are not merely references. 00236 // <li> When ForwardColumnEngine is fixed so that it can deal with 00237 // tables already in the cache, modify the test program. It may also 00238 // be necessary to modify referenceCopy(). 00239 // </todo> 00240 00241 class MeasurementSet : public MSTable<MSMainEnums::PredefinedColumns, 00242 MSMainEnums::PredefinedKeywords>, 00243 public MSMainEnums 00244 { 00245 00246 public: 00247 // This constructs an empty MeasurementSet, only useful to assign to 00248 // (it is not a valid MS yet). 00249 MeasurementSet (); 00250 00251 // These constructors mirror the Table ones with additional checking 00252 // on validity (verifying that the MS will have the required columns 00253 // and keywords) 00254 // An exception is thrown if the constructed Table is not a valid MS 00255 // <thrown> 00256 // <li> AipsError 00257 // </thrown> 00258 // <group name=tableLikeConstructors> 00259 00260 MeasurementSet (const String &tableName, TableOption = Table::Old); 00261 MeasurementSet (const String &tableName, const TableLock& lockOptions, 00262 TableOption = Table::Old); 00263 00264 MeasurementSet (const String &tableName, const TableLock& lockOptions, 00265 bool doNotLockSubtables, TableOption = Table::Old); 00266 // Allows keeping subtables unlocked/read-locked independent of lock 00267 // mode of main table. 00268 00269 MeasurementSet (const String &tableName, const String &tableDescName, 00270 TableOption = Table::Old); 00271 MeasurementSet (const String &tableName, const String &tableDescName, 00272 const TableLock& lockOptions, TableOption = Table::Old); 00273 MeasurementSet (SetupNewTable &newTab, uInt nrrow = 0, 00274 Bool initialize = False); 00275 MeasurementSet (SetupNewTable &newTab, const TableLock& lockOptions, 00276 uInt nrrow = 0, Bool initialize = False); 00277 MeasurementSet (const Table &table, const MeasurementSet * otherMs = NULL); 00278 MeasurementSet (const MeasurementSet &other); 00279 // </group> 00280 00281 // As with tables, the destructor writes the table if necessary. 00282 // Additional checking is done here to verify that all required 00283 // columns are still present. 00284 // If it is NOT valid, it will write the table and then throw an exception. 00285 // <thrown> 00286 // <li> AipsError 00287 // </thrown> 00288 virtual ~MeasurementSet(); 00289 00290 // Assignment operator, reference semantics 00291 MeasurementSet& operator=(const MeasurementSet&); 00292 00293 // Make a special copy of this MS which references all columns from 00294 // this MS except those mentioned; those are empty and writable. 00295 // Each forwarded column has the same writable status as the underlying 00296 // column. The mentioned columns all use the AipsIO storage manager. 00297 // The main use of this is for the synthesis package where corrected and 00298 // model visibilities are stored as new DATA columns in an MS which 00299 // references the raw MS for the other columns. Except for these special 00300 // cases, the use of this function will be rare. 00301 MeasurementSet referenceCopy(const String& newTableName, 00302 const Block<String>& writableColumns) const; 00303 00304 // Converts the MS to make the specified set of subtables memory resident. 00305 void 00306 setMemoryResidentSubtables (const MrsEligibility & mrsEligibility); 00307 00308 // Return the name of each of the subtables. This should be used by the 00309 // filler to create the subtables in the correct location. 00310 // <group> 00311 String antennaTableName() const; 00312 String dataDescriptionTableName() const; 00313 String dopplerTableName() const; 00314 String feedTableName() const; 00315 String fieldTableName() const; 00316 String flagCmdTableName() const; 00317 String freqOffsetTableName() const; 00318 String historyTableName() const; 00319 String observationTableName() const; 00320 String pointingTableName() const; 00321 String polarizationTableName() const; 00322 String processorTableName() const; 00323 String sourceTableName() const; 00324 String spectralWindowTableName() const; 00325 String stateTableName() const; 00326 String sysCalTableName() const; 00327 String weatherTableName() const; 00328 // </group> 00329 00330 // Access functions for the subtables, using the MS-like interface for each 00331 // <group> 00332 MSAntenna& antenna() {return antenna_p;} 00333 MSDataDescription& dataDescription() {return dataDesc_p;} 00334 MSDoppler& doppler() {return doppler_p;} 00335 MSFeed& feed() {return feed_p;} 00336 MSField& field() {return field_p;} 00337 MSFlagCmd& flagCmd() {return flagCmd_p;} 00338 MSFreqOffset& freqOffset() {return freqOffset_p;} 00339 MSHistory& history() {return history_p;} 00340 MSObservation& observation() {return observation_p;} 00341 MSPointing& pointing() {return pointing_p;} 00342 MSPolarization& polarization() {return polarization_p;} 00343 MSProcessor& processor() {return processor_p;} 00344 MSSource& source() {return source_p;} 00345 MSSpectralWindow& spectralWindow() {return spectralWindow_p;} 00346 MSState& state() {return state_p;} 00347 MSSysCal& sysCal() {return sysCal_p;} 00348 MSWeather& weather() {return weather_p;} 00349 const MSAntenna& antenna() const {return antenna_p;} 00350 const MSDataDescription& dataDescription() const {return dataDesc_p;} 00351 const MSDoppler& doppler() const {return doppler_p;} 00352 const MSFeed& feed() const {return feed_p;} 00353 const MSField& field() const {return field_p;} 00354 const MSFlagCmd& flagCmd() const {return flagCmd_p;} 00355 const MSFreqOffset& freqOffset() const {return freqOffset_p;} 00356 const MSHistory& history() const {return history_p;} 00357 const MSObservation& observation() const {return observation_p;} 00358 const MSPointing& pointing() const {return pointing_p;} 00359 const MSPolarization& polarization() const {return polarization_p;} 00360 const MSProcessor& processor() const {return processor_p;} 00361 const MSSource& source() const {return source_p;} 00362 const MSSpectralWindow& spectralWindow() const {return spectralWindow_p;} 00363 const MSState& state() const {return state_p;} 00364 const MSSysCal& sysCal() const {return sysCal_p;} 00365 const MSWeather& weather() const {return weather_p;} 00366 // </group> 00367 00368 MrsEligibility getMrsEligibility () const; 00369 00370 // Initialize the references to the subtables. You need to call 00371 // this only if you assign new subtables to the table keywords. 00372 // This also checks for validity of the table and its subtables. 00373 // Set clear to True to clear the subtable references (used in assignment) 00374 void initRefs(Bool clear=False); 00375 00376 // Create default subtables: fills the required subtable keywords with 00377 // tables of the correct type, mainly for testing and as an example of 00378 // how to do this for specific fillers. In practice these tables will 00379 // often have more things specified, like dimensions of arrays and 00380 // storage managers for the various columns. 00381 void createDefaultSubtables(Table::TableOption option=Table::Scratch); 00382 00383 // Initialize the statics appropriately. This does not need to be 00384 // called by users, it is called by the implementation class 00385 // MSTableImpl. 00386 static void init(); 00387 00388 // Create DATA column from existing FLOAT_DATA column. Noop if DATA already 00389 // exists or neither exists (returns False in that case). 00390 Bool makeComplexData(); 00391 00392 // Validate Measure references - check that all Measure columns have their 00393 // reference value set, report the ones that don't. 00394 Bool validateMeasureRefs(); 00395 00396 // Flush all the tables and subtables associated with this 00397 // MeasurementSet. This function calls the Table::flush() function on the 00398 // main table and all the standard subtables including optional 00399 // subtables. See the Table class for a description of the sync argument. 00400 void flush(Bool sync=False); 00401 00402 // Return a record of the indices that the msselection selection selected 00403 Record msseltoindex(const String& spw="", const String& field="", 00404 const String& baseline="", const String& time="", 00405 const String& scan="", const String& uvrange="", 00406 const String& observation="", const String& poln="", 00407 const String& taql=""); 00408 00409 protected: 00410 00411 00412 // Clears all of the subtable components of this object (i.e., set to 00413 // value of subtable's default constructor). 00414 void clearSubtables (); 00415 00416 // Assigns one subtable to another if the original subtable (otherSubtable) 00417 // is not null and is also memory resident 00418 void copySubtable (const Table & otherSubtable, Table & subTable); 00419 00420 // Copies (assigns) all of the non-null subtables from the other MS into this one. 00421 void copySubtables (const MeasurementSet & other); 00422 00423 // Returns true if the named subtable is eligible for memory residency. 00424 Bool isEligibleForMemoryResidency (const String & subtableName) const; 00425 00426 // Opens all of the eligible subtables in memory resident form 00427 void openMrSubtables (); 00428 00429 // The top level name for MRS related CASARC settings 00430 static String getMrsAipsRcBase () 00431 { 00432 return "MemoryResidentSubtables"; 00433 } 00434 00435 private: 00436 00437 // temporary function to add the CATEGORY keyword to the FLAG_CATEGORY 00438 // column if it isn't there yet. 2000/08/22 00439 // remove this and the calls next MS update 00440 void addCat(); 00441 00442 // check that the MS is the latest version (2.0) 00443 void checkVersion(); 00444 00445 // Opens a single subtable as memory resident (if permitted). 00446 template <typename Subtable> 00447 void 00448 openMrSubtable (Subtable & subtable, const String & subtableName); 00449 00450 // Opens a single subtable if not present in MS object but defined in on-disk MS 00451 template <typename Subtable> 00452 void 00453 openSubtable (Subtable & subtable, const String & subtableName, Bool useLock); 00454 00455 // keep references to the subtables 00456 MSAntenna antenna_p; 00457 MSDataDescription dataDesc_p; 00458 MSDoppler doppler_p; //optional 00459 MSFeed feed_p; 00460 MSField field_p; 00461 MSFlagCmd flagCmd_p; 00462 MSFreqOffset freqOffset_p; //optional 00463 MSHistory history_p; 00464 MSObservation observation_p; 00465 MSPointing pointing_p; 00466 MSPolarization polarization_p; 00467 MSProcessor processor_p; 00468 MSSource source_p; //optional 00469 MSSpectralWindow spectralWindow_p; 00470 MSState state_p; 00471 MSSysCal sysCal_p; //optional 00472 MSWeather weather_p; //optional 00473 00474 bool doNotLockSubtables_p; // used to prevent subtable locking to allow parallel interprocess sharing 00475 int mrsDebugLevel_p; // logging level currently enabled 00476 Bool hasBeenDestroyed_p; // required by the need to throw an exception in the destructor 00477 TableLock mainLock_p; 00478 Bool memoryResidentSubtables_p; // true if memory resident subtables are enabled 00479 MrsEligibility mrsEligibility_p; // subtables which can be made memory resident 00480 00481 }; 00482 00483 00484 } //# NAMESPACE CASACORE - END 00485 00486 #endif