Line data Source code
1 : //# TableQuantumDesc.h: Defines a Quantum column in a Table.
2 : //# Copyright (C) 1997,1998,1999,2000,2001
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: aips2-request@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 :
26 : #ifndef MEASURES_TABLEQUANTUMDESC_H
27 : #define MEASURES_TABLEQUANTUMDESC_H
28 :
29 : //# Includes
30 : #include <casacore/casa/aips.h>
31 : #include <casacore/casa/Arrays/Vector.h>
32 : #include <casacore/casa/BasicSL/String.h>
33 :
34 : namespace casacore { //# NAMESPACE CASACORE - BEGIN
35 :
36 : //# Forward Declarations
37 : class TableDesc;
38 : class Table;
39 : class TableRecord;
40 : class TableColumn;
41 : class Unit;
42 :
43 :
44 : // <summary>
45 : // A class for defining Quantum columns in Tables.
46 : // </summary>
47 :
48 : // <use visibility=export>
49 :
50 : // <reviewed reviewer="Bob Garwood" date="1999/12/23" tests="tTableQuantum.cc">
51 : // </reviewed>
52 :
53 : // <prerequisite>
54 : //# Classes you should understand before using this one.
55 : // <li> <linkto class=Table>Table</linkto>
56 : // <li> <linkto class=Quantum>Quantum</linkto>
57 : // </prerequisite>
58 :
59 : // <synopsis>
60 : // A TableQuantumDesc object is used to define a Quantum column in a Table.
61 : // The use of this object and the associated Scalar- and ArrayQuantColumn
62 : // objects make it possible to store (and retrieve) Quanta in Tables.<br>
63 : //
64 : // TableQuantumDesc objects are analogous to ColumnDesc objects in that they
65 : // add information, describing the characteristics of a column, to the Table
66 : // Descriptor before the Table is created. However, rather than
67 : // replacing the use of a ColumnDesc object, a TableQuantumDesc is
68 : // used in conjunction with a ColumnDesc in the definition of
69 : // Quantum columns.<br>
70 : //
71 : // <note role=caution>
72 : // A good understanding of the Table system is essential
73 : // before attempting to use this class.
74 : // </note>
75 : //
76 : // Defining a Quantum column requires the following steps:
77 : // <ol>
78 : // <li> Use a normal Scalar- or ArrayColumnDesc to define a column to use for
79 : // the Quanta.
80 : // <li> If needed (see
81 : // <A HREF="#TableQuantumDesc:Quantum Units">below</A>) define a column
82 : // for the Quantum Units.
83 : // <li> Add the columns to the Table Descriptor.
84 : // <li> Declare a TableQuantumDesc to associate the column defined in step 1
85 : // and the Unit column from step 2 and update the Table Descriptor.
86 : // <li> Setup and create the Table.
87 : // </ol>
88 : // It is also possible to define a Quantum column after the table is created.
89 : // which is useful when columns (to be used for quanta) are added to
90 : // an already existing table. <br>
91 : //
92 : // The type of the quantum columns must match the type of the underlying
93 : // Quanta that are to be stored in the column. Hence, for a column of
94 : // Quantum<Complex> a ScalarColumnDesc<Complex> must be used.<br>
95 : //
96 : // As with standard Table Columns Quanta can be stored in Scalar and Array
97 : // columns. This must be specified in advance by using either a
98 : // Scalar- or ArrayColumnDesc.<br>
99 : //
100 : // After the Table has be created a Quantum column can be accessed for writing
101 : // and reading of Quanta via the
102 : // <linkto class="ScalarQuantColumn">(RO)ScalarQuantColumn<T></linkto>
103 : // and
104 : // <linkto class="ArrayQuantColumn">(RO)ArrayQuantColumn<T></linkto>
105 : // objects.
106 : //
107 : // <ANCHOR NAME="TableQuantumDesc:Quantum Units">
108 : // <h3>Quantum Units</h3></ANCHOR>
109 : // The treatment of the Unit component of a Quantum in the TableQuantumDesc
110 : // class varies depending on your needs. The main consideration
111 : // is whether the Quanta to be stored in a specific column are to have the
112 : // same Unit or whether their Units could differ. In the simple case,
113 : // where the
114 : // Quanta have the same unit, a TableQuantumDesc is declared with the
115 : // Unit value specified as a parameter. The following defines a Quantum
116 : // column with units "deg":
117 : //
118 : // <srcblock>
119 : // ScalarColumnDesc<Double> scd("QuantumCol");
120 : // ...
121 : // // defines QuantumCol as a Quantum column with fix Units "deg"
122 : // TableQuantumDesc tqd(td, "QuantumCol", Unit("deg"));
123 : // </srcblock>
124 : //
125 : // This constructor stores the value for the Unit as a
126 : // column keyword. In situations, however, where it is necessary to
127 : // store a distinct Unit with each Quantum, it is necessary to define
128 : // an additional column for storing the Unit component of each Quantum.
129 : // The TableQuantumDesc constructor for this takes the name of
130 : // the Unit column as
131 : // a parameter. Hence an additional column must be defined for storing the
132 : // Units and its type must be string. The following
133 : // example shows how to set up a Quantum column with support for Quantum
134 : // unit variability:
135 : //
136 : // <srcblock>
137 : // // the quanta values stored here
138 : // ScalarColumnDesc<Double> scd("QuantumCol");
139 : // // a String column for the Units
140 : // ScalarColumnDesc<String> scd("QuantumUnitCol");
141 : // ...
142 : // TableQuantumDesc tqd(td, "QuantumCol", "QuantumUnitCol");
143 : // </srcblock>
144 : //
145 : // One further consideration is that for Array Quantum Columns it is
146 : // necessary to
147 : // decide on a level of granularity for the Unit storage you would like.
148 : // In Array Quantum columns it is possible to store a distinct Unit per row or
149 : // per array element per row. This distinction is established when the
150 : // Unit column is declared. Defining a ScalarColumn for Units specifies per
151 : // row variability, that is, each row in an array column of Quanta will
152 : // have the same unit. Alternatively, use of an ArrayColumn for the Unit
153 : // column
154 : // specifies that every Quantum stored will have its unit stored as well.
155 : // In both cases the Unit column's type must be String. The following
156 : // defines an Array Quantum Column with per row Unit storage:
157 : //
158 : // <srcblock>
159 : // // for the Quanta values
160 : // ArrayColumnDesc<Double> scd("ArrayQuantumCol");
161 : // // per row storage of units
162 : // ScalarColumnDesc<String> scd("QuantumUnitCol");
163 : // ...
164 : // TableQuantumDesc tqd(td, "ArrayQuantumCol", "QuantumUnitCol");
165 : // </srcblock>
166 : //
167 : // And finally, an array Quantum Column with an Array Unit Column:
168 : //
169 : // <srcblock>
170 : // // for Quanta values
171 : // ArrayColumnDesc<Double> scd("ArrayQuantumCol");
172 : // // per element storage of Units
173 : // ArrayColumnDesc<String> scd("ArrayUnitCol");
174 : // ...
175 : // TableQuantumDesc tqd(td, "ArrayQuantumCol", "ArrayUnitCol");
176 : // </srcblock>
177 : //
178 : //
179 : // After constructing an TableQuantumDesc object use of the write() member
180 : // updates the Table Descriptor or Table object.
181 : // <linkto class="ScalarQuantColumn">(RO)ScalarQuantColumn<T></linkto>
182 : // and
183 : // <linkto class="ArrayQuantColumn">(RO)ArrayQuantColumn<T></linkto>
184 : // are subsequently used to read-only and read/write access the Quantum
185 : // Columns.
186 : // </synopsis>
187 : //
188 : // <example>
189 : // <srcblock>
190 : // // create a table descriptor as normal
191 : // TableDesc td("measTD", "1", TableDesc::New);
192 : // td.comment() = "A table containing measures and quantums";
193 : //
194 : // // This example sets up a Quantum<Complex> column but any valid Quantum
195 : // // type can be specified. However, the type of the Quantums to be
196 : // // stored must match the type of the underlying table column.
197 : // ScalarColumnDesc<Complex> tcdQCplx("Quant", "A quantum complex column");
198 : //
199 : // // For a Quantum array column an ArrayColumnDesc is first defined
200 : // ArrayColumnDesc<Double> tcdQDoub("QuantArray", "A quantum array col");
201 : //
202 : // // The QuantumArray column has variable units. A string is needed
203 : // // for these. This could be done in two ways depending on what is
204 : // // wanted. Units can vary per element of array per row or
205 : // // just per row. In the first instance an ArrayColumn<String> would be
206 : // // require. Here we want to vary units only per row.
207 : // ScalarColumnDesc<String> tcdUnits("VarQuantUnits", "Quantum units");
208 : //
209 : // // Add the columns to the Table Descriptor
210 : // td.addColumn(tcdQplx);
211 : // td.addColumn(tcdQDoub);
212 : // td.addColumn(tcdUnits);
213 : //
214 : // // Create the TableQuantumDesc with units "deg" and an Array Quantum
215 : // // Column with per row Unit granularity
216 : // TableQuantumDesc tqdS(td, "Quant", unit("deg"));
217 : // TableQuantumDesc tqdA(td, "QuantArray", "VarQuantUnits");
218 : //
219 : // // Update the Table Descriptor
220 : // tqdA.write(td);
221 : // tqdS.write(td);
222 : //
223 : // // Setup and create the new table as usual.
224 : // SetupNewTable newtab("mtab", td, Table::New);
225 : // Table qtab(newtab);
226 : //
227 : // // Now ScalarQuantColumn and ArrayQuantColumn objects could be
228 : // // constructed to access the columns...
229 : // </srcblock>
230 : // Note that writing the Quantum description could also be done
231 : // after the table is created. It is meaningless in this case, but
232 : // it is useful when columns (to be used for quanta) are added to
233 : // an already existing table.
234 : // be used as
235 : // <srcblock>
236 : // // Setup and create the new table as usual.
237 : // SetupNewTable newtab("mtab", td, Table::New);
238 : // Table qtab(newtab);
239 : //
240 : // // Update the Table Descriptor
241 : // tqdA.write(qtab);
242 : // tqdS.write(qtab);
243 : // </srcblock>
244 : // </example>
245 :
246 : // <motivation>
247 : // This class assists in the definition of a Quantum Table Column.
248 : // </motivation>
249 :
250 : // <thrown>
251 : // <li>AipsError during construction if the column doesn't exist.
252 : // <li>AipsError during construction if the unit's column doesn't
253 : // exist (when variable units).
254 : // <li>AipsError during construction if the type of the variable unit's
255 : // column is not String.
256 : // <li>AipsError during a reconstruct if the column doesn't have a Unit.
257 : // </thrown>
258 :
259 : //# <todo asof="$DATE:$">
260 : //# A List of bugs, limitations, extensions or planned refinements.
261 : //# </todo>
262 :
263 : class TableQuantumDesc
264 : {
265 : public:
266 : // Constructs a Quantum column descriptor with null units (Unit == "").
267 : // The column should have already been added to the TableDesc.
268 : // An exception is thrown if the column doesn't exist.
269 : TableQuantumDesc (const TableDesc& td, const String& column);
270 :
271 : // Constructs a Quantum column descriptor with the specified Quantum unit.
272 : // The column should have already been added to the TableDesc.
273 : // An exception is thrown if the column doesn't exist.
274 : TableQuantumDesc (const TableDesc& td, const String& column, const Unit&);
275 :
276 : // Constructs a Quantum column descriptor with the specified Quantum units.
277 : // The column should have already been added to the TableDesc.
278 : // An exception is thrown if the column doesn't exist.
279 : // <group>
280 : TableQuantumDesc (const TableDesc& td, const String& column,
281 : const Vector<String>& unitNames);
282 : TableQuantumDesc (const TableDesc& td, const String& column,
283 : const Vector<Unit>&);
284 : // </group>
285 :
286 : // Constructs a Quantum column descriptor with variable units stored in
287 : // unitCol. Both the quantum and unit column should exist in the
288 : // TableDesc.
289 : //# Note that the Char* constructor is needed, otherwise the compiler
290 : //# cannot choose between String and Unit.
291 : //<group>
292 : TableQuantumDesc (const TableDesc& td, const String& column,
293 : const String& unitCol);
294 : TableQuantumDesc (const TableDesc& td, const String& column,
295 : const Char* unitCol);
296 : //</group>
297 :
298 : // Copy constructor (copy semantics).
299 : TableQuantumDesc (const TableQuantumDesc& that);
300 :
301 : ~TableQuantumDesc();
302 :
303 : // Reconstructs a previously constructed TableQuantumDesc.
304 : static TableQuantumDesc* reconstruct (const TableDesc& td,
305 : const String& column);
306 :
307 : // Assignment.
308 : TableQuantumDesc& operator= (const TableQuantumDesc& that);
309 :
310 : // Returns the Quantum column descriptor's units. A empty vector is
311 : // returned if units have not been specified. This could be because the null
312 : // unit constructor was used or because the units are variable.
313 15426133 : const Vector<String>& getUnits() const
314 15426133 : { return itsUnitsName; }
315 :
316 : // Returns True if descriptor set for variable units (one per row)
317 15426815 : Bool isUnitVariable() const
318 15426815 : { return (! itsUnitsColName.empty()); }
319 :
320 : // Returns the name of the quantum column.
321 : const String& columnName() const
322 : { return itsColName; }
323 :
324 : // Returns the name of the units column (an empty String is returned
325 : // if the units are not variable).
326 682 : const String& unitColumnName() const
327 682 : { return itsUnitsColName; }
328 :
329 : // Makes the TableQuantumDesc persistent (updates the Table Descriptor).
330 : // <group>
331 : void write (TableDesc&);
332 : void write (Table&);
333 : // </group>
334 :
335 : // Does this column contain table quanta?
336 : static Bool hasQuanta (const TableColumn& column);
337 :
338 : private:
339 : // Name of column which stores the Quantum's values.
340 : String itsColName;
341 : // The Quantum's unit as a string.
342 : Vector<String> itsUnitsName;
343 : // Name of units column if units are variable.
344 : String itsUnitsColName;
345 :
346 :
347 : // Write the actual keywords.
348 : void writeKeys (TableRecord& columnKeyset);
349 :
350 : // Throw an exception if the quantum column doesn't exist.
351 : void checkColumn (const TableDesc& td) const;
352 :
353 : // Throw an exception if the variable units column isn't a string column.
354 : void checkUnitsColumn (const TableDesc& td) const;
355 : };
356 :
357 :
358 :
359 : } //# NAMESPACE CASACORE - END
360 :
361 : #endif
|