casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ArrayQuantColumn.h
Go to the documentation of this file.
00001 //# ArrayQuantColumn.h: Access to an Array Quantum Column in a table.
00002 //# Copyright (C) 1997,1998,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: ArrayQuantColumn.h 21298 2012-12-07 14:53:03Z gervandiepen $
00027 
00028 #ifndef MEASURES_ARRAYQUANTCOLUMN_H
00029 #define MEASURES_ARRAYQUANTCOLUMN_H
00030 
00031 //# Includes
00032 #include <casa/Arrays/Vector.h>
00033 #include <casa/Quanta/Quantum.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 //# Forward Declarations
00038 class Table;
00039 template <class T> class ArrayColumn;
00040 template <class T> class ScalarColumn;
00041 class String;
00042 
00043 
00044 // <summary>
00045 // Provides read-only access to Array Quantum columns in Tables.
00046 // </summary>
00047 
00048 // <use visibility=export>
00049 
00050 // <reviewed reviewer="Bob Garwood" date="1999/12/23" tests="tTableQuantum.cc">
00051 // </reviewed>
00052 
00053 // <prerequisite>
00054 //# Classes you should understand before using this one.
00055 //   <li> <linkto class=TableQuantumDesc>TableQuantumDesc</linkto>
00056 //   <li> <linkto class=Table>Table</linkto>
00057 //   <li> <linkto class=ArrayColumn>ArrayColumn</linkto>
00058 //   <li> <linkto class=Quantum>Quantum</linkto>
00059 // </prerequisite>
00060 
00061 // <synopsis>
00062 // The ROArrayQuantColumn class provides read-only access to quanta
00063 // stored in a array Quantum Table column.  The Quantum column should
00064 // already exist in the table and would have been defined by means of a
00065 // <linkto class=TableQuantumDesc>TableQuantumDesc object</linkto>.
00066 // In addition,
00067 // for a ROArrayQuantColumn object to be useful the column should
00068 // contain Quanta.  Inserting Quanta into a column requires the use of a
00069 // <linkto class=ArrayQuantColumn">ArrayQuantColumn</linkto>
00070 // object.<br>
00071 //
00072 // The ROArrayQuantColumn class is the array version
00073 // of the <linkto class=ROScalarQuantColumn>ROScalarQuantColumn</linkto>
00074 // class.
00075 //
00076 // <h3>Quantum Units</h3></A>
00077 // Quanta retrieved from the column will normally have the Unit that was
00078 // specified when the Quantum column was defined.
00079 // However, it is possible to override the default column Unit by
00080 // supplying a Unit in the ROArrayQuantColumn constructor.
00081 // When constructed in this fashion the retrieved Quanta will by
00082 // default be retrieved in this unit, i.e. they will by default be
00083 // converted to this unit.
00084 // <br>
00085 // By giving a unit (as a Unit or Quantum object) to a get function,
00086 // the data can be retrieved in another unit than the default.
00087 // </synopsis>
00088 
00089 // <example>
00090 // (See <linkto class=TableQuantumDesc>TableQuantumDesc</linkto> class
00091 // for an example of how to define a Quantum column).
00092 // <srcblock>
00093 //    // Create the column object with default units "deg".
00094 //    // It gets the quantum array from row 0 and prints it to stdout.
00095 //    ROArrayQuantColumn<Double> roaqCol(qtab, "ArrQuantDouble", "deg");
00096 //    cout << roaqCol(0) << endl;
00097 //    // This retrieves the same array with units converted to "m/s".   
00098 //    cout << roaqCol(0, "m/s") << endl;
00099 // </srcblock>
00100 // </example>
00101 
00102 // <motivation>
00103 // Add support for Quanta in the Tables system.
00104 // </motivation>
00105 
00106 // <thrown>
00107 //    <li>TableInvOper if the Table column is null.
00108 // </thrown>
00109 
00110 // <todo asof="$DATE:$">
00111 //# A List of bugs, limitations, extensions or planned refinements.
00112 // <li> Support for fixed unit per array element (e.g. for positions)
00113 //      In that case #units should match first array dimension.
00114 // <li> Functions like getColumn, getSlice.
00115 // <li> get as <src>Quantum<Array<T>></src>.
00116 // <li> optimize when converting when units are the same for entire array.
00117 // </todo>
00118 
00119 
00120 template<class T> class ROArrayQuantColumn
00121 {
00122 public:
00123   // The default constructor creates a null object. It is useful for creating
00124   // arrays of ROArrayQuantColumn objects. Attempting to use a null object
00125   // will produce a segmentation fault so care needs to be taken to
00126   // initialize the objects by using the attach() member before any attempt
00127   // is made to use the object.  The isNull() member can be used to test
00128   // if a ROArrayQuantColumn object is null.
00129   ROArrayQuantColumn();
00130 
00131   // Create the ROArrayQuantColumn from the supplied table and column name.
00132   // The default unit for data retrieved is the unit in which they were stored.
00133   ROArrayQuantColumn (const Table& tab, const String& columnName);
00134 
00135   // Create the ROArrayQuantColumn from the supplied table and column name.
00136   // The default unit for data retrieved is the given unit (the data is
00137   // converted as needed).
00138   // <group>
00139   ROArrayQuantColumn (const Table& tab, const String& columnName,
00140                       const Unit&);
00141   ROArrayQuantColumn (const Table& tab, const String& columnName,
00142                       const Vector<Unit>&);
00143   // </group>
00144 
00145   // Copy constructor (copy semantics).
00146   ROArrayQuantColumn (const ROArrayQuantColumn<T>& that);
00147 
00148   ~ROArrayQuantColumn();
00149 
00150   // Make this object reference the column in "that".
00151   void reference (const ROArrayQuantColumn<T>& that);
00152 
00153   // Attach a column to the object. Optionally supply a default unit.
00154   // which has the same meaning as the constructor unit argument.
00155   // <group name="attach">
00156   void attach (const Table& tab, const String& columnName);
00157   void attach (const Table& tab, const String& columnName,
00158                const Unit&);
00159   void attach (const Table& tab, const String& columnName,
00160                const Vector<Unit>&);
00161   // </group>
00162 
00163   // Get the quantum array in the specified row.
00164   // If resize is True the resulting array is resized if its shape
00165   // is not correct. Otherwise a "conformance exception" is thrown
00166   // if the array is not empty and its shape mismatches.
00167   // <group name="get">
00168   void get (uInt rownr, Array<Quantum<T> >& q, Bool resize = False) const;
00169   // Get the quantum array in the specified row. Each quantum is
00170   // converted to the given unit.
00171   void get (uInt rownr, Array<Quantum<T> >& q,
00172             const Unit&, Bool resize = False) const;
00173   // Get the quantum array in the specified row. Each quantum is
00174   // converted to the given units.
00175   void get (uInt rownr, Array<Quantum<T> >& q,
00176             const Vector<Unit>&, Bool resize = False) const;
00177   // Get the quantum array in the specified row. Each quantum is
00178   // converted to the unit in other.
00179   void get (uInt rownr, Array<Quantum<T> >& q,
00180             const Quantum<T>& other, Bool resize = False) const;
00181   // </group>
00182 
00183   // Return the quantum array stored in the specified row.
00184   // <group>
00185   Array<Quantum<T> > operator() (uInt rownr) const;
00186   // Return the quantum array stored in the specified row, converted
00187   // to the given unit.
00188   Array<Quantum<T> > operator() (uInt rownr, const Unit&) const;
00189   // Return the quantum array stored in the specified row, converted
00190   // to the given units.
00191   Array<Quantum<T> > operator() (uInt rownr, const Vector<Unit>&) const;
00192   // Return the quantum array stored in the specified row, converted
00193   // to the unit in other.
00194   Array<Quantum<T> > operator() (uInt rownr, const Quantum<T>& other) const;
00195   // </group>
00196 
00197   // Test whether the Quantum column has variable units
00198   Bool isUnitVariable() const
00199     { return (itsArrUnitsCol || itsScaUnitsCol); }
00200 
00201   // Returns the column's units as a vector of strings.
00202   // An empty vector is returned if the column has no fixed units.
00203   Vector<String> getUnits() const;
00204 
00205   // Test if the object is null.
00206   Bool isNull() const
00207     { return (itsDataCol == 0); }
00208 
00209   // Throw an exception if the object is null.
00210   void throwIfNull() const;
00211 
00212 protected:
00213   //# Quantum column's units (if units not variable)
00214   Vector<Unit> itsUnit;                         
00215 
00216   // Get access to itsUnitsCol.
00217   // <group>
00218   const ArrayColumn<String>* arrUnitsCol() const
00219     { return itsArrUnitsCol; }
00220   const ScalarColumn<String>* scaUnitsCol() const
00221     { return itsScaUnitsCol; }
00222   // </group>
00223 
00224 
00225 private:
00226   //# The underlying data column stores the quantum column's data.
00227   ArrayColumn<T>* itsDataCol;
00228   //# Variable units array column if applicable.
00229   ArrayColumn<String>*  itsArrUnitsCol;
00230   //# Variable units scalar column if applicable.
00231   ScalarColumn<String>* itsScaUnitsCol;
00232   //# Units to retrieve the data in.
00233   Vector<Unit> itsUnitOut;
00234   //# Convert unit when getting data?
00235   Bool itsConvOut;
00236 
00237 
00238   // Initialize the ROArrayQuantColumn from the specified table and column.
00239   void init (const Table& tab, const String& columnName);
00240 
00241   // Deletes allocated memory etc. Called by ~tor and any member which needs
00242   // to reallocate data.
00243   void cleanUp();
00244 
00245   // Get the data without possible conversion.
00246   void getData (uInt rownr, Array<Quantum<T> >& q, Bool resize) const;
00247 
00248   // Assignment makes no sense in a read only class.
00249   // Declaring this operator private makes it unusable.
00250   ROArrayQuantColumn& operator= (const ROArrayQuantColumn<T>& that);
00251 
00252   // Comparison is not defined, since its semantics are unclear.
00253   Bool operator== (const ROArrayQuantColumn<T>& that);
00254 };
00255 
00256 
00257 
00258 // <summary>
00259 // Provides read/write access to Array Quantum columns in Tables.
00260 // </summary>
00261 
00262 // <use visibility=export>
00263 
00264 // <reviewed reviewer="Bob Garwood" date="1999/12/23" tests="tTableQuantum.cc">
00265 // </reviewed>
00266 
00267 // <prerequisite>
00268 //# Classes you should understand before using this one.
00269 //   <li> <linkto class=TableQuantumDesc>TableQuantumDesc</linkto>
00270 //   <li> <linkto class=Table>Table</linkto>
00271 //   <li> <linkto class=ArrayColumn>ArrayColumn</linkto>
00272 //   <li> <linkto class=Quantum>Quantum</linkto>
00273 // </prerequisite>
00274 
00275 // <synopsis>
00276 // The ArrayQuantColumn class provides read/write access to Quanta
00277 // stored in a Quantum Table column.  The column should previously have
00278 // been defined as a Quantum column by means of the
00279 // <linkto class=TableQuantumDesc>TableQuantumDesc</linkto> object.
00280 // In addition to the operations provided by its read-only partner,
00281 // <linkto class=ROArrayQuantColumn>ROArrayQuantColumn</linkto>, use
00282 // of a ArrayQuantColumn object allows the insertion of Quanta into a column.
00283 // <br>
00284 //
00285 // <h3>Quantum Units</h3></A>
00286 // The underlying Quantum column will have been defined to have either
00287 // variable or fixed Units. A variable unit can be variable per row
00288 // (thus the same for an entire array in that row) or it can be variable
00289 // per array element.
00290 // If the Quantum column's Unit is fixed then writing quanta converts
00291 // the data to that unit. If the column's unit is variable, the data is
00292 // written unconverted and the unit is written into the unit column
00293 // defined in the TableQuantumDesc object.
00294 // <br>See
00295 // <linkto class=TableQuantumDesc>TableQuantumDesc</linkto> for more details.
00296 // </synopsis>
00297 
00298 // <example>
00299 // (See <linkto class=TableQuantumDesc>TableQuantumDesc</linkto> class
00300 // for an example of how to define a Quantum column).
00301 // <srcblock>
00302 //    // This creates the Quantum array object.
00303 //    ArrayQuantColumn<Double> aqCol(qtab, "ArrQuantDouble");
00304 //
00305 //    // Test if the column has variable of fixed units
00306 //    if (aqCol.isUnitVariable()) {
00307 //        cout << "Quantum column supports variable units!" << endl;
00308 //    } else {
00309 //        cout << "Unit for the column is: ", << aqCol.getUnits() << endl;
00310 //    }
00311 //
00312 //    // need an array of Quanta.
00313 //    IPosition shape(2, 3, 2);
00314 //    Array<Quantum<Double> > qArr(shape);
00315 //    Bool deleteIt;
00316 //    Quantum<Double>* q_p = qArr.getStorage(deleteIt);
00317 //    q_p->setValue(1.41212);
00318 //    q_p->setUnit("GHz");
00319 //    q_p++;
00320 //    q_p->setValue(1.4921);
00321 //    q_p->setUnit("deg");
00322 //    q_p++;
00323 //    q_p->setValue(1.4111);
00324 //    q_p->setUnit("ms-1");
00325 //    q_p++;
00326 //    q_p->setValue(1.4003);
00327 //    q_p->setUnit("Jy");
00328 //    q_p++;
00329 //    q_p->setValue(1.22);
00330 //    q_p->setUnit("GHz");
00331 //    q_p++;
00332 //    q_p->setValue(1.090909);
00333 //    q_p->setUnit("g");        
00334 //    qArr.putStorage(q_p, deleteIt);
00335 //      
00336 //    // put the quantum array in the column at row 0.  If the column has
00337 //    // fixed units the Unit component of each quantum will be lost.  Just
00338 //    // their values will be stored.
00339 //    aqCol.put(0, qArr);
00340 // </srcblock>
00341 // </example>
00342 
00343 // <motivation>
00344 // Add support for Quanta in the Tables system.
00345 // </motivation>
00346 
00347 // <thrown>
00348 //    <li>TableInvOper if the Table column is null.
00349 // </thrown>
00350 
00351 // <todo asof="$DATE:$">
00352 //# A List of bugs, limitations, extensions or planned refinements.
00353 // <li> Functions like putColumn, putSlice
00354 // </todo>
00355 
00356 
00357 template<class T> class ArrayQuantColumn : public ROArrayQuantColumn<T>
00358 {
00359 public:
00360   // The default constructor creates a null object.  Useful for creating
00361   // arrays of ArrayQuantColumn objects.  Attempting to use a null object
00362   // will produce a segmentation fault, so care needs to be taken to
00363   // initialize the objects by using the attach() member before any attempt
00364   // is made to use the object.  The isNull() member can be used to test
00365   // if a ArrayQuantColumn object is null.
00366   ArrayQuantColumn();
00367 
00368   // Create the ArrayQuantColumn from the supplied table and column name.
00369   // The default unit for data retrieved is the unit in which they were stored.
00370   ArrayQuantColumn (const Table& tab, const String& columnName);
00371 
00372   // Copy constructor (copy semantics).
00373   ArrayQuantColumn (const ArrayQuantColumn<T>& that);
00374 
00375   ~ArrayQuantColumn();
00376 
00377   // Make this object reference the column in "that".
00378   void reference(const ArrayQuantColumn<T>& that);
00379 
00380   // Attach a column to the object.
00381   // <group name="attach">
00382   void attach (const Table& tab, const String& columnName);
00383   // </group>
00384 
00385   // Put an array of quanta into the specified row of the table.
00386   // If the column supports variable units, the units are stored as well.
00387   // Otherwise the quanta are converted to the column's units.
00388   void put (uInt rownr, const Array<Quantum<T> >& q);
00389 
00390 private:
00391   //# The underlying data column stores the quantum column's data.
00392   ArrayColumn<T>* itsDataCol;
00393   //# Variable units array column if applicable.
00394   ArrayColumn<String>*  itsArrUnitsCol;
00395   //# Variable units scalar column if applicable.
00396   ScalarColumn<String>* itsScaUnitsCol;
00397 
00398 
00399   // reference() can be used for assignment.
00400   // Declaring this operator private makes it unusable.
00401   ArrayQuantColumn& operator= (const ArrayQuantColumn<T>& that);
00402 
00403   // Comparison is not defined, since its semantics are unclear.
00404   Bool operator== (const ArrayQuantColumn<T>& that);
00405 
00406   // Deletes allocated memory etc. Called by destructor and any member 
00407   // which needs to reallocate data.
00408   void cleanUp();
00409 
00410   //# Make members of parent class known.
00411 protected:
00412   using ROArrayQuantColumn<T>::arrUnitsCol;
00413   using ROArrayQuantColumn<T>::scaUnitsCol;
00414   using ROArrayQuantColumn<T>::itsUnit;
00415 };
00416 
00417 
00418 
00419 
00420 } //# NAMESPACE CASA - END
00421 
00422 #ifndef CASACORE_NO_AUTO_TEMPLATES
00423 #include <measures/TableMeasures/ArrayQuantColumn.tcc>
00424 #endif //# CASACORE_NO_AUTO_TEMPLATES
00425 #endif