00001 //# ArrayMeasColumn.h: Access to array Measure columns in Tables. 00002 //# Copyright (C) 1997,1998,1999,2000 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_ARRAYMEASCOLUMN_H 00029 #define MEASURES_ARRAYMEASCOLUMN_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/measures/TableMeasures/TableMeasColumn.h> 00034 #include <casacore/measures/Measures/MeasRef.h> 00035 00036 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00037 00038 //# Forward Declarations 00039 template <class T> class ArrayColumn; 00040 template <class T> class ScalarColumn; 00041 template <class T> class Array; 00042 template <class M> class ScalarMeasColumn; 00043 00044 00045 // <summary> 00046 // Read only access to table array Measure columns. 00047 // </summary> 00048 00049 // <use visibility=export> 00050 00051 // <reviewed reviewer="Bob Garwood" date="1999/12/23" tests="tTableMeasures.cc"> 00052 // </reviewed> 00053 00054 // <prerequisite> 00055 // <li> <linkto module=Measures>Measures</linkto> 00056 // <li> <linkto module=Tables>Tables</linkto> 00057 // <li> TableMeasDesc 00058 // </prerequisite> 00059 00060 // <synopsis> 00061 // ArrayMeasColumn objects can be used to access array Measure Columns 00062 // in tables, both for reading and writing (if the table is writable). 00063 // 00064 // Before a column can be accessed it must have previously been defined as 00065 // a Measure column by use of the 00066 // <linkto class="TableMeasDesc">TableMeasDesc</linkto> object. 00067 // 00068 // The ArrayMeasColumn class is templated on Measure type and MeasValue 00069 // type but typedefs exist for making declaration less long winded. The 00070 // Measure classes (like MEpoch) have typedefs <src>ArrayColumn</src> 00071 // to assist in creating ArrayMeasColumn objects. 00072 // 00073 // Constructing array Measure column objects using these typedefs looks like 00074 // this: 00075 // <srcblock> 00076 // // Read/write MEpoch array column 00077 // MEpoch::ArrayColumn ec(table, "ColumnName); 00078 // </srcblock> 00079 // 00080 // <h3>Reading and writing Measures</h3> 00081 // 00082 // The reading and writing of Measures columns is very similar to reading and 00083 // writing of "ordinary" Table columns. 00084 // <linkto class="ArrayMeasColumn#get">get()</linkto> 00085 // and <linkto class="ArrayMeasColumn#get">operator()</linkto> 00086 // exist for reading Measures and the 00087 // <linkto class="ArrayMeasColumn#put">put()</linkto> member for adding 00088 // Measures to a column. (put() is obviously not defined for 00089 // ScalarMeasColumn objects.) Each of these members accepts a row number 00090 // as an argument. 00091 // 00092 // Care needs to be taken when adding Measures to a column. The user needs 00093 // to be aware that Measures are not checked for consistency, with respect to 00094 // a Measure's reference, between the Measures being added to a column and 00095 // the column's predefined Measure reference. This is only an issue if the 00096 // Measure column was defined to have a fixed reference. For such columns 00097 // the reference component of Measures added to a column is silently 00098 // ignored, that is, there is no warning nor is there any sort of conversion 00099 // to the column's reference should the reference of the added Measure be 00100 // different from the column's reference. The functions 00101 // <linkto class="TableMeasDescBase#isRefCodeVariable()"> 00102 // TableMeasDescBase::isRefVariable()</linkto> 00103 // and 00104 // <linkto class="ArrayMeasColumn#getMeasRef()"> 00105 // ArrayMeasColumn::getMeasRef()</linkto> can be 00106 // used to discover a Measure column's Measure reference characteristics. 00107 // </synopsis> 00108 00109 // <example> 00110 // <srcblock> 00111 // // create an MEpoch array column object 00112 // ArrayMeasColumn<MEpoch> arrayCol; 00113 // 00114 // // should be null. Can test this and attach a real MEpoch column 00115 // // The column Time1Arr should exist in the table and would have been 00116 // // defined by using a TableMeasDesc 00117 // if (arrayCol.isNull()) { 00118 // arrayCol.attach(tab, "Time1Arr"); 00119 // } 00120 // 00121 // // This would throw an Exception if the object is still null....but 00122 // // hopefully won't 00123 // arrayCol.throwIfNull(); 00124 // 00125 // // create a vector of MEpochs 00126 // MEpoch last(Quantity(13.45, "h"), MEpoch::Ref(MEpoch::TAI)); 00127 // Vector<MEpoch> ev(10); 00128 // for (uInt i=0; i<10; i++) { 00129 // last.set(Quantity(13.45 + i, "h")); 00130 // ev(i) = last; 00131 // } 00132 // 00133 // // before adding something check the isDefined() member 00134 // if (!arrayCol.isDefined(0)) { 00135 // cout << "PASS - nothing in the measure array column row yet\n"; 00136 // } else { 00137 // cout << "FAIL - there shouldn't be a valid value in the row!\n"; 00138 // } 00139 // 00140 // // add the MEpoch vector to the array Measure column at row 0 00141 // arrayCol.put(0, ev); 00142 // 00143 // // now read the array from the row. Could use same object to do this 00144 // // but here we'll create a ArrayMeasColumn<MEpoch> to do this 00145 // ArrayMeasColumn<MEpoch> roArrCol(tab, "Time1Arr"); 00146 // 00147 // // need a vector to put the MEpochs into 00148 // Vector<MEpoch> ew; 00149 // 00150 // // setting the resize parameter to True automatically sets ew to the 00151 // // same shape as the array contained in the row 00152 // arrayCol.get(0, ew, True); 00153 // </srcblock> 00154 // </example> 00155 00156 // <motivation> 00157 // The standard Casacore Table system does not support array Measure columns. 00158 // This class overcomes this limitation. 00159 // </motivation> 00160 00161 // <thrown> 00162 // <li>ArrayConformanceError during get() if supplied array is the wrong 00163 // shape. 00164 // </thrown> 00165 00166 //# <todo asof="$DATE:$"> 00167 //# A List of bugs, limitations, extensions or planned refinements. 00168 //# </todo> 00169 00170 00171 template<class M> class ArrayMeasColumn : public TableMeasColumn 00172 { 00173 public: 00174 // The default constructor creates a null object. Useful for creating 00175 // arrays of ArrayMeasColumn objects. Attempting to use a null object 00176 // will produce a segmentation fault so care needs to be taken to 00177 // initialise the objects by using the attach() member before any attempt 00178 // is made to use the object. A ArrayMeasColumn object can be tested 00179 // if it is null by using the isNull() member. 00180 ArrayMeasColumn(); 00181 00182 // Create the ArrayMeasColumn from the table and column Name. 00183 ArrayMeasColumn (const Table& tab, const String& columnName); 00184 00185 // Copy constructor (copy semantics). 00186 ArrayMeasColumn (const ArrayMeasColumn<M>& that); 00187 00188 virtual ~ArrayMeasColumn(); 00189 00190 // Change the reference to another column. 00191 void reference (const ArrayMeasColumn<M>& that); 00192 00193 // Attach a column to the object. 00194 void attach (const Table& tab, const String& columnName); 00195 00196 // Get the Measure array in the specified row. For get() the supplied 00197 // array's shape should match the shape in the row unless resize is True. 00198 // <group name=get> 00199 void get (uInt rownr, Array<M>& meas, Bool resize = False) const; 00200 Array<M> operator() (uInt rownr) const; 00201 // </group> 00202 00203 // Get the Measure array contained in the specified row and convert 00204 // it to the reference and offset found in the given measure. 00205 Array<M> convert (uInt rownr, const M& meas) const 00206 { return convert (rownr, meas.getRef()); } 00207 00208 // Get the Measure array contained in the specified row and convert 00209 // it to the given reference. 00210 // <group> 00211 Array<M> convert (uInt rownr, const MeasRef<M>& measRef) const; 00212 Array<M> convert (uInt rownr, uInt refCode) const; 00213 // </group> 00214 00215 // Get the column's reference. 00216 const MeasRef<M>& getMeasRef() const 00217 { return itsMeasRef; } 00218 00219 // Reset the refCode, offset, or units. 00220 // It overwrites the value used when defining the TableMeasDesc. 00221 // Resetting the refCode and offset can only be done if they were 00222 // defined as fixed in the description. 00223 // <note role=tip> 00224 // In principle the functions can only be used if the table is empty, 00225 // otherwise already written values have thereafter the incorrect 00226 // reference, offset, or unit. 00227 // However, it is possible that part of the table is already 00228 // written and that the entire measure column is filled in later. 00229 // In that case the reference, offset, or units can be set by using 00230 // a False <src>tableMustBeEmpty</src> argument. 00231 // </note> 00232 // <group> 00233 void setDescRefCode (uInt refCode, Bool tableMustBeEmpty=True); 00234 void setDescOffset (const Measure& offset, Bool tableMustBeEmpty=True); 00235 void setDescUnits (const Vector<Unit>& units, Bool tableMustBeEmpty=True); 00236 // </group> 00237 00238 // Add a Measure array to the specified row. 00239 // <group name=put> 00240 void put (uInt rownr, const Array<M>&); 00241 // </group> 00242 00243 protected: 00244 //# Its measure reference when the MeasRef is constant per row. 00245 MeasRef<M> itsMeasRef; 00246 00247 private: 00248 //# Column which contains the Measure's actual data. 00249 ArrayColumn<Double>* itsDataCol; 00250 //# Its MeasRef code column when references are variable. 00251 ScalarColumn<Int>* itsRefIntCol; 00252 ArrayColumn<Int>* itsArrRefIntCol; 00253 //# Its MeasRef column when references are variable and stored as Strings. 00254 ScalarColumn<String>* itsRefStrCol; 00255 ArrayColumn<String>* itsArrRefStrCol; 00256 //# Column containing its variable offsets. Only applicable if the 00257 //# measure references have offsets and they are variable. 00258 ScalarMeasColumn<M>* itsOffsetCol; 00259 ArrayMeasColumn<M>* itsArrOffsetCol; 00260 00261 00262 // Assignment makes no sense in a read only class. 00263 // Declaring this operator private makes it unusable. 00264 ArrayMeasColumn& operator= (const ArrayMeasColumn<M>& that); 00265 00266 // Deletes allocated memory etc. Called by ~tor and any member which needs 00267 // to reallocate data. 00268 void cleanUp(); 00269 00270 // Get the data and convert using conversion engine. 00271 Array<M> doConvert (uInt rownr, typename M::Convert& conv) const; 00272 }; 00273 00274 00275 } //# NAMESPACE CASACORE - END 00276 00277 00278 //# Make old name ROArrayMeasColumn still available. 00279 #define ROArrayMeasColumn ArrayMeasColumn 00280 00281 00282 #ifndef CASACORE_NO_AUTO_TEMPLATES 00283 #include <casacore/measures/TableMeasures/ArrayMeasColumn.tcc> 00284 #endif //# CASACORE_NO_AUTO_TEMPLATES 00285 #endif