00001 //# TableQuantumDesc.h: Defines a 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$ 00027 00028 #ifndef MEASURES_TABLEQUANTUMDESC_H 00029 #define MEASURES_TABLEQUANTUMDESC_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/casa/Arrays/Vector.h> 00034 #include <casacore/casa/BasicSL/String.h> 00035 00036 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00037 00038 //# Forward Declarations 00039 class TableDesc; 00040 class Table; 00041 class TableRecord; 00042 class TableColumn; 00043 class Unit; 00044 00045 00046 // <summary> 00047 // A class for defining Quantum columns in Tables. 00048 // </summary> 00049 00050 // <use visibility=export> 00051 00052 // <reviewed reviewer="Bob Garwood" date="1999/12/23" tests="tTableQuantum.cc"> 00053 // </reviewed> 00054 00055 // <prerequisite> 00056 //# Classes you should understand before using this one. 00057 // <li> <linkto class=Table>Table</linkto> 00058 // <li> <linkto class=Quantum>Quantum</linkto> 00059 // </prerequisite> 00060 00061 // <synopsis> 00062 // A TableQuantumDesc object is used to define a Quantum column in a Table. 00063 // The use of this object and the associated Scalar- and ArrayQuantColumn 00064 // objects make it possible to store (and retrieve) Quanta in Tables.<br> 00065 // 00066 // TableQuantumDesc objects are analogous to ColumnDesc objects in that they 00067 // add information, describing the characteristics of a column, to the Table 00068 // Descriptor before the Table is created. However, rather than 00069 // replacing the use of a ColumnDesc object, a TableQuantumDesc is 00070 // used in conjunction with a ColumnDesc in the definition of 00071 // Quantum columns.<br> 00072 // 00073 // <note role=caution> 00074 // A good understanding of the Table system is essential 00075 // before attempting to use this class. 00076 // </note> 00077 // 00078 // Defining a Quantum column requires the following steps: 00079 // <ol> 00080 // <li> Use a normal Scalar- or ArrayColumnDesc to define a column to use for 00081 // the Quanta. 00082 // <li> If needed (see 00083 // <A HREF="#TableQuantumDesc:Quantum Units">below</A>) define a column 00084 // for the Quantum Units. 00085 // <li> Add the columns to the Table Descriptor. 00086 // <li> Declare a TableQuantumDesc to associate the column defined in step 1 00087 // and the Unit column from step 2 and update the Table Descriptor. 00088 // <li> Setup and create the Table. 00089 // </ol> 00090 // It is also possible to define a Quantum column after the table is created. 00091 // which is useful when columns (to be used for quanta) are added to 00092 // an already existing table. <br> 00093 // 00094 // The type of the quantum columns must match the type of the underlying 00095 // Quanta that are to be stored in the column. Hence, for a column of 00096 // Quantum<Complex> a ScalarColumnDesc<Complex> must be used.<br> 00097 // 00098 // As with standard Table Columns Quanta can be stored in Scalar and Array 00099 // columns. This must be specified in advance by using either a 00100 // Scalar- or ArrayColumnDesc.<br> 00101 // 00102 // After the Table has be created a Quantum column can be accessed for writing 00103 // and reading of Quanta via the 00104 // <linkto class="ScalarQuantColumn">(RO)ScalarQuantColumn<T></linkto> 00105 // and 00106 // <linkto class="ArrayQuantColumn">(RO)ArrayQuantColumn<T></linkto> 00107 // objects. 00108 // 00109 // <ANCHOR NAME="TableQuantumDesc:Quantum Units"> 00110 // <h3>Quantum Units</h3></ANCHOR> 00111 // The treatment of the Unit component of a Quantum in the TableQuantumDesc 00112 // class varies depending on your needs. The main consideration 00113 // is whether the Quanta to be stored in a specific column are to have the 00114 // same Unit or whether their Units could differ. In the simple case, 00115 // where the 00116 // Quanta have the same unit, a TableQuantumDesc is declared with the 00117 // Unit value specified as a parameter. The following defines a Quantum 00118 // column with units "deg": 00119 // 00120 // <srcblock> 00121 // ScalarColumnDesc<Double> scd("QuantumCol"); 00122 // ... 00123 // // defines QuantumCol as a Quantum column with fix Units "deg" 00124 // TableQuantumDesc tqd(td, "QuantumCol", Unit("deg")); 00125 // </srcblock> 00126 // 00127 // This constructor stores the value for the Unit as a 00128 // column keyword. In situations, however, where it is necessary to 00129 // store a distinct Unit with each Quantum, it is necessary to define 00130 // an additional column for storing the Unit component of each Quantum. 00131 // The TableQuantumDesc constructor for this takes the name of 00132 // the Unit column as 00133 // a parameter. Hence an additional column must be defined for storing the 00134 // Units and its type must be string. The following 00135 // example shows how to set up a Quantum column with support for Quantum 00136 // unit variability: 00137 // 00138 // <srcblock> 00139 // // the quanta values stored here 00140 // ScalarColumnDesc<Double> scd("QuantumCol"); 00141 // // a String column for the Units 00142 // ScalarColumnDesc<String> scd("QuantumUnitCol"); 00143 // ... 00144 // TableQuantumDesc tqd(td, "QuantumCol", "QuantumUnitCol"); 00145 // </srcblock> 00146 // 00147 // One further consideration is that for Array Quantum Columns it is 00148 // necessary to 00149 // decide on a level of granularity for the Unit storage you would like. 00150 // In Array Quantum columns it is possible to store a distinct Unit per row or 00151 // per array element per row. This distinction is established when the 00152 // Unit column is declared. Defining a ScalarColumn for Units specifies per 00153 // row variability, that is, each row in an array column of Quanta will 00154 // have the same unit. Alternatively, use of an ArrayColumn for the Unit 00155 // column 00156 // specifies that every Quantum stored will have its unit stored as well. 00157 // In both cases the Unit column's type must be String. The following 00158 // defines an Array Quantum Column with per row Unit storage: 00159 // 00160 // <srcblock> 00161 // // for the Quanta values 00162 // ArrayColumnDesc<Double> scd("ArrayQuantumCol"); 00163 // // per row storage of units 00164 // ScalarColumnDesc<String> scd("QuantumUnitCol"); 00165 // ... 00166 // TableQuantumDesc tqd(td, "ArrayQuantumCol", "QuantumUnitCol"); 00167 // </srcblock> 00168 // 00169 // And finally, an array Quantum Column with an Array Unit Column: 00170 // 00171 // <srcblock> 00172 // // for Quanta values 00173 // ArrayColumnDesc<Double> scd("ArrayQuantumCol"); 00174 // // per element storage of Units 00175 // ArrayColumnDesc<String> scd("ArrayUnitCol"); 00176 // ... 00177 // TableQuantumDesc tqd(td, "ArrayQuantumCol", "ArrayUnitCol"); 00178 // </srcblock> 00179 // 00180 // 00181 // After constructing an TableQuantumDesc object use of the write() member 00182 // updates the Table Descriptor or Table object. 00183 // <linkto class="ScalarQuantColumn">(RO)ScalarQuantColumn<T></linkto> 00184 // and 00185 // <linkto class="ArrayQuantColumn">(RO)ArrayQuantColumn<T></linkto> 00186 // are subsequently used to read-only and read/write access the Quantum 00187 // Columns. 00188 // </synopsis> 00189 // 00190 // <example> 00191 // <srcblock> 00192 // // create a table descriptor as normal 00193 // TableDesc td("measTD", "1", TableDesc::New); 00194 // td.comment() = "A table containing measures and quantums"; 00195 // 00196 // // This example sets up a Quantum<Complex> column but any valid Quantum 00197 // // type can be specified. However, the type of the Quantums to be 00198 // // stored must match the type of the underlying table column. 00199 // ScalarColumnDesc<Complex> tcdQCplx("Quant", "A quantum complex column"); 00200 // 00201 // // For a Quantum array column an ArrayColumnDesc is first defined 00202 // ArrayColumnDesc<Double> tcdQDoub("QuantArray", "A quantum array col"); 00203 // 00204 // // The QuantumArray column has variable units. A string is needed 00205 // // for these. This could be done in two ways depending on what is 00206 // // wanted. Units can vary per element of array per row or 00207 // // just per row. In the first instance an ArrayColumn<String> would be 00208 // // require. Here we want to vary units only per row. 00209 // ScalarColumnDesc<String> tcdUnits("VarQuantUnits", "Quantum units"); 00210 // 00211 // // Add the columns to the Table Descriptor 00212 // td.addColumn(tcdQplx); 00213 // td.addColumn(tcdQDoub); 00214 // td.addColumn(tcdUnits); 00215 // 00216 // // Create the TableQuantumDesc with units "deg" and an Array Quantum 00217 // // Column with per row Unit granularity 00218 // TableQuantumDesc tqdS(td, "Quant", unit("deg")); 00219 // TableQuantumDesc tqdA(td, "QuantArray", "VarQuantUnits"); 00220 // 00221 // // Update the Table Descriptor 00222 // tqdA.write(td); 00223 // tqdS.write(td); 00224 // 00225 // // Setup and create the new table as usual. 00226 // SetupNewTable newtab("mtab", td, Table::New); 00227 // Table qtab(newtab); 00228 // 00229 // // Now ScalarQuantColumn and ArrayQuantColumn objects could be 00230 // // constructed to access the columns... 00231 // </srcblock> 00232 // Note that writing the Quantum description could also be done 00233 // after the table is created. It is meaningless in this case, but 00234 // it is useful when columns (to be used for quanta) are added to 00235 // an already existing table. 00236 // be used as 00237 // <srcblock> 00238 // // Setup and create the new table as usual. 00239 // SetupNewTable newtab("mtab", td, Table::New); 00240 // Table qtab(newtab); 00241 // 00242 // // Update the Table Descriptor 00243 // tqdA.write(qtab); 00244 // tqdS.write(qtab); 00245 // </srcblock> 00246 // </example> 00247 00248 // <motivation> 00249 // This class assists in the definition of a Quantum Table Column. 00250 // </motivation> 00251 00252 // <thrown> 00253 // <li>AipsError during construction if the column doesn't exist. 00254 // <li>AipsError during construction if the unit's column doesn't 00255 // exist (when variable units). 00256 // <li>AipsError during construction if the type of the variable unit's 00257 // column is not String. 00258 // <li>AipsError during a reconstruct if the column doesn't have a Unit. 00259 // </thrown> 00260 00261 //# <todo asof="$DATE:$"> 00262 //# A List of bugs, limitations, extensions or planned refinements. 00263 //# </todo> 00264 00265 class TableQuantumDesc 00266 { 00267 public: 00268 // Constructs a Quantum column descriptor with null units (Unit == ""). 00269 // The column should have already been added to the TableDesc. 00270 // An exception is thrown if the column doesn't exist. 00271 TableQuantumDesc (const TableDesc& td, const String& column); 00272 00273 // Constructs a Quantum column descriptor with the specified Quantum unit. 00274 // The column should have already been added to the TableDesc. 00275 // An exception is thrown if the column doesn't exist. 00276 TableQuantumDesc (const TableDesc& td, const String& column, const Unit&); 00277 00278 // Constructs a Quantum column descriptor with the specified Quantum units. 00279 // The column should have already been added to the TableDesc. 00280 // An exception is thrown if the column doesn't exist. 00281 // <group> 00282 TableQuantumDesc (const TableDesc& td, const String& column, 00283 const Vector<String>& unitNames); 00284 TableQuantumDesc (const TableDesc& td, const String& column, 00285 const Vector<Unit>&); 00286 // </group> 00287 00288 // Constructs a Quantum column descriptor with variable units stored in 00289 // unitCol. Both the quantum and unit column should exist in the 00290 // TableDesc. 00291 //# Note that the Char* constructor is needed, otherwise the compiler 00292 //# cannot choose between String and Unit. 00293 //<group> 00294 TableQuantumDesc (const TableDesc& td, const String& column, 00295 const String& unitCol); 00296 TableQuantumDesc (const TableDesc& td, const String& column, 00297 const Char* unitCol); 00298 //</group> 00299 00300 // Copy constructor (copy semantics). 00301 TableQuantumDesc (const TableQuantumDesc& that); 00302 00303 ~TableQuantumDesc(); 00304 00305 // Reconstructs a previously constructed TableQuantumDesc. 00306 static TableQuantumDesc* reconstruct (const TableDesc& td, 00307 const String& column); 00308 00309 // Assignment. 00310 TableQuantumDesc& operator= (const TableQuantumDesc& that); 00311 00312 // Returns the Quantum column descriptor's units. A empty vector is 00313 // returned if units have not been specified. This could be because the null 00314 // unit constructor was used or because the units are variable. 00315 const Vector<String>& getUnits() const 00316 { return itsUnitsName; } 00317 00318 // Returns True if descriptor set for variable units (one per row) 00319 Bool isUnitVariable() const 00320 { return (! itsUnitsColName.empty()); } 00321 00322 // Returns the name of the quantum column. 00323 const String& columnName() const 00324 { return itsColName; } 00325 00326 // Returns the name of the units column (an empty String is returned 00327 // if the units are not variable). 00328 const String& unitColumnName() const 00329 { return itsUnitsColName; } 00330 00331 // Makes the TableQuantumDesc persistent (updates the Table Descriptor). 00332 // <group> 00333 void write (TableDesc&); 00334 void write (Table&); 00335 // </group> 00336 00337 // Does this column contain table quanta? 00338 static Bool hasQuanta (const TableColumn& column); 00339 00340 private: 00341 // Name of column which stores the Quantum's values. 00342 String itsColName; 00343 // The Quantum's unit as a string. 00344 Vector<String> itsUnitsName; 00345 // Name of units column if units are variable. 00346 String itsUnitsColName; 00347 00348 00349 // Write the actual keywords. 00350 void writeKeys (TableRecord& columnKeyset); 00351 00352 // Throw an exception if the quantum column doesn't exist. 00353 void checkColumn (const TableDesc& td) const; 00354 00355 // Throw an exception if the variable units column isn't a string column. 00356 void checkUnitsColumn (const TableDesc& td) const; 00357 }; 00358 00359 00360 00361 } //# NAMESPACE CASACORE - END 00362 00363 #endif