00001 //# TableMeasRefDesc.h: Definition of a Measure Reference in a Table. 00002 //# Copyright (C) 1997,1999,2000,2001 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 //# $Id$ 00027 00028 #ifndef MEASURES_TABLEMEASREFDESC_H 00029 #define MEASURES_TABLEMEASREFDESC_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/measures/TableMeasures/TableMeasOffsetDesc.h> 00034 #include <casacore/casa/Quanta/Unit.h> 00035 #include <casacore/casa/Arrays/Vector.h> 00036 #include <casacore/casa/BasicSL/String.h> 00037 00038 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00039 00040 //# Forward Declarations 00041 class TableMeasDescBase; 00042 class Table; 00043 class TableDesc; 00044 class TableRecord; 00045 00046 00047 // <summary> 00048 // Definition of a Measure Reference in a Table. 00049 // </summary> 00050 00051 // <use visibility=export> 00052 00053 // <reviewed reviewer="Bob Garwood" date="1999/12/23" tests="tTableMeasures.cc"> 00054 // </reviewed> 00055 00056 // <prerequisite> 00057 //# Classes you should understand before using this one. 00058 // <li> <linkto module=Measures>Measures</linkto> 00059 // <li> <linkto module=Tables>Tables</linkto> 00060 // <li> <linkto class=TableMeasDesc>TableMeasDesc</linkto> 00061 // </prerequisite> 00062 00063 // <synopsis> 00064 // TableMeasRefDesc is a class for setting up the MeasRef 00065 // component of a TableMeasDesc in the TableMeasures system. With the aid 00066 // of a 00067 // TableMeasRefDesc the following possibilities for defining a Measure 00068 // column's reference exist: 00069 // <ul> 00070 // <li> a fixed, non-variable, reference code, where all Measures in a 00071 // column are to have the same reference code. 00072 // <li> a unique (and probably different) reference code stored in each row. 00073 // <li> a unique reference code stored in each array element per 00074 // (Array)column row. 00075 // </ul> 00076 // For each of the above options an offset component can be specified 00077 // along with a reference code. When a Measure offset is required a 00078 // <linkto class="TableMeasOffsetDesc">TableMeasOffsetDesc</linkto> is 00079 // supplied as an argument to the TableMeasRefDesc constructor. 00080 // With references containing an offset component either component can be set 00081 // to be variable or fixed independently of the other. 00082 // 00083 // <note role=tip> 00084 // It is not necessary to specify a Reference when defining a 00085 // Measure column. In such cases the Measures retrieved from the column 00086 // will have the default reference for the type of Measure stored in the 00087 // column. 00088 // </note> 00089 // 00090 // A fixed reference code is trivially stored as part of the column 00091 // keywords in the Measure column but a variable reference code requires 00092 // its own column. A Scalar or Array column can be used dependent on your 00093 // needs but its type must always be either Int or String. Note that it is 00094 // legal to specify a Scalar 00095 // reference column for use with an ArrayMeasColumn. In such cases a single 00096 // reference code will be stored per array (row) of Measures. However, 00097 // attempting to associate an Array column for references with a 00098 // ScalarMeasColumn will generate an exception. 00099 // <note> 00100 // Because the reference codes stored are the enums defined in the Measures 00101 // classes, it is possible that they change over time. The type strings, 00102 // however, wille never change. Therefore the reference codes and types 00103 // valid at the time of the table creation, are stored in the column keywords 00104 // if the reference codes are kept in an integer column. 00105 // <br> 00106 // This has only been added in March 2007, but is fully backward compatible. 00107 // Older tables will get the codes and types stored when accessed for 00108 // read/write. 00109 // </note> 00110 // 00111 // <note role=caution> 00112 // When storing Measures into a Measure column with a fixed reference code 00113 // the reference code component of the Measures stored is 00114 // ignored. 00115 // </note> 00116 // </synopsis> 00117 00118 // <example> 00119 //<ol> 00120 // <li>Simplest kind of TableMeasRefDesc (apart from not specifying one at 00121 // all) is a fixed reference code. All Measures subsequently 00122 // retrieved from the column will have the reference MEpoch::LAST. 00123 // <srcblock> 00124 // // measure reference column 00125 // TableMeasRefDesc reference(MEpoch::LAST); 00126 // </srcblock> 00127 // <li>A variable reference code requires its own Int column. 00128 // <srcblock> 00129 // // An int column for the variable references. 00130 // ScalarColumnDesc<Int> cdRefCol("refCol", "Measure reference column"); 00131 // td.addColumn(cdRefCol); 00132 // ... 00133 // // create the Measure reference descriptor 00134 // TableMeasRefDesc varRef(td, "refCol"); 00135 // </srcblock> 00136 // <li>A fix Measure reference code with a fixed Offset 00137 // <srcblock> 00138 // // Create the Offset descriptor 00139 // MEpoch offset(MVEpoch(MVTime(1996, 5, 17, (8+18./60.)/24.)) 00140 // TableMeasOffsetDesc offsetDesc(offset); 00141 // // create the Measure reference descriptor 00142 // TableMeasRefDesc varRef(MEpoch::LAST, offsetDesc); 00143 // </srcblock> 00144 //</ol> 00145 // For an example of the use of a TableMeasRefDesc in the context of a full 00146 // TableMeasDesc declaration see class 00147 // <linkto class="TableMeasDesc">TableMeasDesc</linkto>. 00148 // </example> 00149 00150 // <motivation> 00151 // Creating the required keyword for the definition of a Measure 00152 // in a Table is somewhat complicated. This class assists in that 00153 // process. 00154 // </motivation> 00155 // 00156 // <thrown> 00157 // <li>AipsError if the specified column doesn't exist or its type is 00158 // not Int or String. 00159 // </thrown> 00160 // 00161 00162 //# <todo asof="$DATE:$"> 00163 //# A List of bugs, limitations, extensions or planned refinements. 00164 //# </todo> 00165 00166 00167 class TableMeasRefDesc 00168 { 00169 public: 00170 // Define a fixed MeasRef by supplying its reference code 00171 // Optionally a Measure offset can be specified. 00172 // The reference code and offset should not need a reference frame. 00173 // <group> 00174 explicit TableMeasRefDesc (uInt refCode = 0); 00175 TableMeasRefDesc (uInt refCode, const TableMeasOffsetDesc&); 00176 // </group> 00177 00178 // Define a variable reference by supplying the name of the column 00179 // in which the reference is to be stored. Either an <src>Int</src> or 00180 // <src>String</src> column can be specified. This determines how 00181 // references are stored. <src>Int</src> columns are likely to be 00182 // faster but storing 00183 // references as <src>Strings</src> may be useful if there is a need to 00184 // browse tables manually. Optionally supply a Measure offset. 00185 // The reference code and offset should not need a reference frame. 00186 // <group> 00187 TableMeasRefDesc (const TableDesc&, const String& column); 00188 TableMeasRefDesc (const TableDesc&, const String& column, 00189 const TableMeasOffsetDesc&); 00190 // </group> 00191 00192 // Reconstruct the object from the MEASINFO record. 00193 // Not useful for the public. 00194 TableMeasRefDesc (const TableRecord& measInfo, 00195 const Table&, 00196 const MeasureHolder& measHolder, 00197 const TableMeasDescBase&); 00198 00199 // Copy constructor (copy semantics) 00200 TableMeasRefDesc (const TableMeasRefDesc& that); 00201 00202 ~TableMeasRefDesc(); 00203 00204 // Assignment operator (copy semantics). 00205 TableMeasRefDesc& operator= (const TableMeasRefDesc& that); 00206 00207 // Return the reference code. 00208 uInt getRefCode() const 00209 { return itsRefCode; } 00210 00211 // Is the reference variable? 00212 Bool isRefCodeVariable() const 00213 { return (! itsColumn.empty()); } 00214 00215 // Return the name of its variable reference code column. 00216 const String& columnName() const 00217 { return itsColumn; } 00218 00219 // Is the reference code variable and stored in an integer column? 00220 Bool isRefCodeColumnInt() const 00221 { return itsRefCodeColInt; } 00222 00223 // Do the keywords contain the reference codes and types. 00224 // For old tables this might not be the case. 00225 Bool hasRefTab() const 00226 { return itsHasRefTab; } 00227 00228 // Returns True if the reference has an offset. 00229 Bool hasOffset() const 00230 { return (itsOffset != 0); } 00231 00232 // Returns True if the offset is variable. 00233 Bool isOffsetVariable() const 00234 { return (itsOffset != 0 ? itsOffset->isVariable() : False); } 00235 00236 // Returns True is the offset is variable and it is an ArrayMeasColumn. 00237 Bool isOffsetArray() const 00238 { return (itsOffset != 0 ? itsOffset->isArray() : False); } 00239 00240 // Return the fixed Measure offset. 00241 // It does not test if the offset is defined; hasOffset() should be used 00242 // for that purpose. 00243 const Measure& getOffset() const 00244 { return itsOffset->getOffset(); } 00245 00246 // Return the name of the Measure offset column. 00247 // An empty string is returned if no variable offset is used. 00248 const String& offsetColumnName() const 00249 { return itsOffset->columnName(); } 00250 00251 // Reset the refCode or offset. 00252 // It overwrites the value used when defining the TableMeasDesc. 00253 // It is only possible if it was defined as fixed for the entire column. 00254 // <group> 00255 void resetRefCode (uInt refCode); 00256 void resetOffset (const Measure& offset); 00257 // </group> 00258 00259 // Make the Measure value descriptor persistent. Normally would not be 00260 // called by the user directly. 00261 // <group> 00262 void write (TableDesc&, TableRecord& measInfo, const TableMeasDescBase&); 00263 void write (Table&, TableRecord& measInfo, const TableMeasDescBase&); 00264 // </group> 00265 00266 // Initialize the table reference codes and types and 00267 // the maps (mapping a code onto itself). 00268 void initTabRef (const MeasureHolder& measHolder); 00269 00270 // Reference codes can be persistent in tables. 00271 // Because their enum values can change, a mapping of current table 00272 // to table value is maintained. The mapping is created using their 00273 // never-changing string representations. 00274 // These functions convert current refcode to and from table refcode. 00275 // <group> 00276 uInt tab2cur (uInt tabRefCode) const; 00277 uInt cur2tab (uInt curRefCode) const; 00278 // </group> 00279 00280 // Set the function used to get all reference codes for a MeasureHolder. 00281 // This is not really needed for normal practice, but makes it possible 00282 // to add extra codes when testing. 00283 // <br> The default function simply calls MeasureHolder.asMeasure.allTypes. 00284 // <group> 00285 typedef void TypesFunc (Vector<String>& types, 00286 Vector<uInt>& codes, const MeasureHolder&); 00287 static void setTypesFunc (TypesFunc* func) 00288 { theirTypesFunc = func; } 00289 static void defaultTypesFunc (Vector<String>& types, 00290 Vector<uInt>& codes, const MeasureHolder&); 00291 static TypesFunc* theirTypesFunc; 00292 // </group> 00293 00294 private: 00295 uInt itsRefCode; 00296 // The name of column containing its variable references. 00297 String itsColumn; 00298 // Is the reference code column a string column? 00299 Bool itsRefCodeColInt; 00300 // Do the keywords contain the reference codes and types? 00301 Bool itsHasRefTab; 00302 //# Its reference offset. 00303 TableMeasOffsetDesc* itsOffset; 00304 //# Define the vectors holding the measref codes and types. 00305 //# These are the codes as used in the table, which might be different 00306 //# from the current values. 00307 Vector<String> itsTabRefTypes; 00308 Vector<uInt> itsTabRefCodes; 00309 //# Define the mappings of table measref codes to current ones and back. 00310 //# There are only filled in and used if a variable reference code is used. 00311 Block<Int> itsTab2Cur; 00312 Block<Int> itsCur2Tab; 00313 00314 // Fill the reference code mappings for table<->current. 00315 // <group> 00316 void initTabRefMap(); 00317 void fillTabRefMap (const MeasureHolder& measHolder); 00318 uInt fillMap (Block<Int>& f2t, 00319 const Vector<uInt>& codesf, 00320 const Vector<String>& typesf, 00321 Vector<uInt>& codest, 00322 Vector<String>& typest, 00323 Int maxnr); 00324 // </group> 00325 00326 // Write the actual keywords. 00327 void writeKeys (TableRecord& measInfo, 00328 const TableMeasDescBase& measDesc); 00329 00330 // Throw an exception if the column doesn't exist or is of the 00331 // wrong type. 00332 void checkColumn (const TableDesc& td); 00333 }; 00334 00335 00336 00337 } //# NAMESPACE CASACORE - END 00338 00339 #endif