casa
$Rev:20696$
|
00001 //# TableDesc.h: specify structure of aips++ tables 00002 //# Copyright (C) 1994,1995,1996,1997,1999,2000,2001,2002 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: TableDesc.h 20739 2009-09-29 01:15:15Z Malte.Marquarding $ 00027 00028 #ifndef TABLES_TABLEDESC_H 00029 #define TABLES_TABLEDESC_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <tables/Tables/ColDescSet.h> 00035 #include <casa/IO/AipsIO.h> 00036 #include <casa/iosfwd.h> 00037 00038 namespace casa { //# NAMESPACE CASA - BEGIN 00039 00040 //# Forward Declarations 00041 class TableRecord; 00042 class TableAttr; 00043 class TabPath; 00044 template<class T> class Vector; 00045 00046 // <summary> 00047 // Define the structure of an AIPS++ table 00048 // </summary> 00049 00050 // <use visibility=export> 00051 00052 // <reviewed reviewer="Paul Shannon" date="1994/08/11" tests="none"> 00053 // </reviewed> 00054 00055 // <prerequisite> 00056 // <li> column description classes 00057 // <li> TableRecord 00058 // </prerequisite> 00059 00060 // <synopsis> 00061 // A TableDesc object contains the description, or structure, of a table. 00062 // This description is required for the creation of a new table. 00063 // Descriptions are subsequently associated with every table and 00064 // embedded in them. 00065 // 00066 // A table description consists of the following items: 00067 // <ul> 00068 // <li> Name, which cannot be blank if the description is saved in a file. 00069 // The file name will be this name followed by .tabdsc. 00070 // <li> Version, which defaults to a blank string. 00071 // It serves merely as information for the user. 00072 // <li> Comment, which defaults to an empty string. 00073 // This serves purely as an informational string for the user. 00074 // <li> A set of column descriptions which has to be added to the 00075 // table description. A column description can be created using 00076 // the classes ScalarColumnDesc, etc.. 00077 // At table creation it is determined by the user if a column 00078 // has to be stored using a storage manager or calculated 00079 // on-the-fly using a so-called virtual column engine. 00080 // <li> A keyword set, which is by default empty. 00081 // When a table is created from the description, it gets 00082 // a copy of this keyword set as its initial keyword set. 00083 // </ul> 00084 // 00085 // A TableDesc object can be constructed with one of the following 00086 // options: 00087 // <ul> 00088 // <li> Old 00089 // Open an existing table description file as readonly. 00090 // <li> Update 00091 // Open an existing table description file as read/write 00092 // The TableDesc destructor will rewrite the possibly changed 00093 // description. 00094 // <li> New 00095 // Create a new table description file. 00096 // The TableDesc destructor will write the table description into the file. 00097 // <li> NewNoReplace 00098 // As option New, but an exception will be thrown if the table 00099 // description file already exists. 00100 // <li> Scratch 00101 // Create a temporary table description. The table description will 00102 // be lost when the TableDesc object is destructed. 00103 // This is useful to create a Table object without storing the 00104 // description separately. 00105 // Note that the Table object maintains its own description (i.e. it 00106 // copies the description when being constructed). 00107 // <li> Delete 00108 // Delete the table description file. This gets done by the destructor. 00109 // </ul> 00110 // 00111 // More information is provided in the Tables module documentation. 00112 // </synopsis> 00113 00114 // <example> 00115 // <srcblock> 00116 // // First build the new description of a subtable. 00117 // // Define columns ra and dec (double). 00118 // TableDesc subTableDesc("tTableDesc_sub", "1", TableDesc::New); 00119 // subTableDesc.addColumn (ScalarColumnDesc<double>("ra")); 00120 // subTableDesc.addColumn (ScalarColumnDesc<double>("dec")); 00121 // 00122 // // Now create a new table description 00123 // // Define a comment for the table description. 00124 // // Define a double keyword. 00125 // ColumnDesc colDesc1, colDesc2; 00126 // TableDesc td("tTableDesc", "1", TableDesc::New); 00127 // td.comment() = "A test of class TableDesc"; 00128 // td.rwKeywordSet().define ("equinox", 1950.0); 00129 // 00130 // // Define an integer column ab using the TableDesc::addColumn 00131 // // function which creates a scalar column description. 00132 // td.addColumn (ScalarColumnDesc<Int>("ab", "Comment for column ab")); 00133 // 00134 // // Add a scalar integer column ac, define keywords for it 00135 // // and define a default value 0. 00136 // // Overwrite the value of keyword unit. 00137 // ScalarColumnDesc<Int> acColumn("ac"); 00138 // acColumn.rwKeywordSet().define ("scale", Complex(0.0f)); 00139 // acColumn.rwKeywordSet().define ("unit", ""); 00140 // acColumn.setDefault (0); 00141 // td.addColumn (acColumn); 00142 // td["ac"].rwKeywordSet().define ("unit", "DEG"); 00143 // 00144 // // Add a scalar string column ad and define its comment string. 00145 // td.addColumn (ScalarColumnDesc<String>("ad","comment for ad")); 00146 // 00147 // // Now define array columns. 00148 // // This one is indirect and has no dimensionality mentioned yet. 00149 // td.addColumn (ArrayColumnDesc<Complex>("Arr1","comment for Arr1")); 00150 // // This one is indirect and has 3-dim arrays. 00151 // td.addColumn (ArrayColumnDesc<Int>("A2r1","comment for Arr1",3)); 00152 // // This one is direct and has 2-dim arrays with axes length 4 and 7. 00153 // td.addColumn (ArrayColumnDesc<uInt>("Arr3","comment for Arr1", 00154 // IPosition(2,4,7), 00155 // ColumnDesc::Direct)); 00156 // 00157 // // Add a columns containing tables. 00158 // td.addColumn (SubTableDesc("sub1", "subtable by name", 00159 // "tTableDesc_sub")); 00160 // 00161 // // Define hypercolumn "dataCube". 00162 // td.addColumn (ArrayColumnDesc<Complex>("data",2)); 00163 // td.addColumn (ArrayColumnDesc<Int>("pol",1)); 00164 // td.addColumn (ArrayColumnDesc<float>("freq",1)); 00165 // td.addColumn (ScalarColumnDesc<float>("time")); 00166 // td.addColumn (ScalarColumnDesc<float>("baseline")); 00167 // td.defineHypercolumn ("dataCube", 4, 00168 // stringToVector ("data"), 00169 // stringToVector ("pol,freq,time,baseline")); 00170 // } 00171 // </srcblock> 00172 // </example> 00173 00174 // <motivation> 00175 // A table description specifies the structure, but not the contents, 00176 // of an aips++ table. Since many tables will have identical structure 00177 // and different content, it makes good sense to separate structure 00178 // ("description") from content. 00179 // </motivation> 00180 00181 //# <todo asof="$DATE:$"> 00182 //# A List of bugs, limitations, extensions or planned refinements. 00183 //# </todo> 00184 00185 00186 class TableDesc 00187 { 00188 public: 00189 00190 //# Enumerate the possible options for TableDesc. 00191 enum TDOption {Old=1, New, NewNoReplace, Scratch, Update, Delete}; 00192 00193 // The default constructor creates a table description with 00194 // option = Scratch and a blank name. 00195 TableDesc(); 00196 00197 // Create a table description object with the given name. 00198 // This name can be seen as the table type in the same way as a 00199 // class name is the data type of an object. 00200 // The name can only be blank when option=Scratch. 00201 // The default table description path is used for the description file. 00202 TableDesc (const String& type, TDOption = Old); 00203 00204 // Create a table description object with the given name (i.e. table type) 00205 // and version. 00206 // The name can only be blank when option=Scratch. 00207 // The default table description path is used for the description file. 00208 TableDesc (const String& type, const String& version, TDOption = Old); 00209 00210 // Create a table description object. 00211 // The given table description path is used for the description file. 00212 // The name can only be blank with option=Scratch. 00213 TableDesc (const String& type, const String& version, 00214 const TabPath&, TDOption = Old); 00215 00216 // Create a table description object with the given name (i.e. table type) 00217 // and version by copying the input table description. 00218 // If the given name or version is blank, it will be copied from 00219 // the input table description. 00220 // The default table description path is used for the description file. 00221 // The only options allowed are New, NewNoReplace and Scratch. 00222 TableDesc (const TableDesc&, const String& type, const String& version, 00223 TDOption, Bool copyColumns=True); 00224 00225 // Create a table description object with the given name (i.e. table type) 00226 // and version by copying the input table description. 00227 // If the given name or version is blank, it will be copied from 00228 // the input table description. 00229 // The given table description path is used for the description file. 00230 // The only options allowed are New, NewNoReplace and Scratch. 00231 TableDesc (const TableDesc&, const String& type, const String& version, 00232 const TabPath&, TDOption, Bool copyColumns=True); 00233 00234 // This copy constructor makes a copy of the table description 00235 // maintaining its name and version. By default a Scratch copy is made. 00236 // It serves as a shorthand for the constructor: 00237 // <br><src> TableDesc (const TableDesc&, "", "", TDOption); </src> 00238 TableDesc (const TableDesc&, TDOption = Scratch); 00239 00240 // The destructor writes the table description if changed. 00241 ~TableDesc(); 00242 00243 // Test if a description file exists (i.e. isReadable). 00244 static Bool isReadable (const String& tableDescName); 00245 00246 // Get access to the set of column descriptions. 00247 // In this way const <linkto class=ColumnDescSet>ColumnDescSet</linkto> 00248 // functions (e.g. isDisjoint) can be used. 00249 const ColumnDescSet& columnDescSet() const; 00250 00251 // Add another table description to this table description. 00252 // It merges the column descriptions, the special keywordSet 00253 // (containing hypercolumn definitions) and the user keywordSet 00254 // (this last one is not added if the flag is False). 00255 // The two table descriptions have to be disjoint, i.e. no column 00256 // nor keyword should already exist. Otherwise an TableInvOper 00257 // exception is thrown and nothing gets added. 00258 void add (const TableDesc& other, Bool addKeywordSet = True); 00259 00260 // Get access to the keyword set. 00261 // <group> 00262 TableRecord& rwKeywordSet(); 00263 const TableRecord& keywordSet() const; 00264 // </group> 00265 00266 // Get readonly access to the private set of keywords. 00267 const TableRecord& privateKeywordSet() const; 00268 00269 // Add a column to the table description. 00270 // An exception is thrown if a keyword or column with this name 00271 // already exists. 00272 // Although this function has a <src>ColumnDesc</src> as argument, 00273 // it is usually needed to construct a more specialized object like 00274 // <src>ArrayColumnDesc<float></src>. A <src>ColumnDesc</src> 00275 // constructor converts that automatically to a <src>ColumnDesc</src> 00276 // object. 00277 // <srcblock> 00278 // tableDesc.addColumn (ArrayColumnDesc<float> ("NAME")); 00279 // </srcblock> 00280 // On the other hand this function can also be used to add a 00281 // column description from another table as in: 00282 // <srcblock> 00283 // tableDesc.addColumn (otherTableDesc.columnDesc("NAME")); 00284 // </srcblock> 00285 ColumnDesc& addColumn (const ColumnDesc&); 00286 00287 // Add a column to the table description and give it another name. 00288 // This may be useful to use a description of another column. 00289 ColumnDesc& addColumn (const ColumnDesc&, const String& newname); 00290 00291 // Remove a column. 00292 // An exception is thrown if the column does not exist. 00293 void removeColumn (const String& name); 00294 00295 // Rename a column. 00296 // An exception is thrown if the old name does not exist or 00297 // if the name already exists. 00298 // <note role=caution> 00299 // Renaming a column should be done with care, because other 00300 // columns may be referring this column. Also a hypercolumn definition 00301 // might be using the old name. 00302 // </note> 00303 void renameColumn (const String& newname, const String& oldname); 00304 00305 // Get number of columns. 00306 uInt ncolumn() const; 00307 00308 // Test if a column with this name exists. 00309 Bool isColumn (const String& name) const; 00310 00311 // Get a vector containing all column names. 00312 Vector<String> columnNames() const; 00313 00314 // Get the column description by name or by index. 00315 // An exception is thrown if the column does not exist. 00316 // Function isColumn should be used to test if a column exists. 00317 // <group> 00318 const ColumnDesc& columnDesc (const String& name) const; 00319 const ColumnDesc& operator[] (const String& name) const; 00320 const ColumnDesc& columnDesc (uInt index) const; 00321 const ColumnDesc& operator[] (uInt index) const; 00322 ColumnDesc& rwColumnDesc (const String& name); 00323 ColumnDesc& rwColumnDesc (uInt index); 00324 // </group> 00325 00326 // Get comment string. 00327 const String& comment() const; 00328 00329 // Get comment string (allowing it to be changed). 00330 String& comment(); 00331 00332 // Show the table description on cout. 00333 void show() const; 00334 00335 // Show the table description. 00336 void show (ostream& os) const; 00337 00338 // Get the table type (i.e. name of table description). 00339 const String& getType() const; 00340 00341 // Get the table description version. 00342 const String& version() const; 00343 00344 // Define a hypercolumn. 00345 // A hypercolumn is a group of one or more data columns of which 00346 // the data is treated as one or more (regular) hypercubes. 00347 // The hypercolumn has coordinate axes (e.g. time, frequency) 00348 // which are columns in the table. 00349 // When the entire hypercolumn consists of multiple hypercubes, 00350 // ID-columns can be defined, which uniquely determine the 00351 // hypercube to be used. 00352 // Note that only <linkto class=TiledDataStMan>TiledDataStMan</linkto> 00353 // requires the use of ID-columns. 00354 // A hypercolumn definition is needed to be able to use a Tiled 00355 // Storage Manager. 00356 // 00357 // The following has to be specified: 00358 // <dl> 00359 // <dt> Hypercolumn name 00360 // <dd> which is the name used to refer to the hypercolumn. 00361 // <dt> ndim 00362 // <dd> defining the dimensionality of the hypercolumn (and 00363 // of its hypercube(s)). 00364 // <dt> Data column names 00365 // <dd> which are the columns containing the hypercube data. 00366 // When multiple columns are used, the shapes of the data 00367 // in their cells must be the same in the same row. 00368 // All data columns must contain numeric or Bool scalars or arrays. 00369 // <dl> 00370 // <dt> array: 00371 // <dd> Its dimensionality has to be less than or equal to the 00372 // dimensionality of the hypercolumn. If equal, the 00373 // array itself already forms the hypercube. That would 00374 // mean that each row is a hypercube. 00375 // If less, the arrays from multiple rows form a hypercube, 00376 // adding one or more dimensions to the array dimensionality. 00377 // <dt> scalar: 00378 // <dd> The data from multiple rows form a hypercube. 00379 // Not all tiled storage managers support scalars. 00380 // </dl> 00381 // <dt> Coordinate column names (optional) 00382 // <dd> which are the columns containing the coordinates of the 00383 // hypercubes. They must be (u)Int, float, double or (D)Complex. 00384 // When given, the number of coordinate columns must match the 00385 // dimensionality of the hypercolumn. 00386 // <br> 00387 // When the data column cells contain arrays, the first N coordinate 00388 // columns must contain vector values, where N is the dimensionality 00389 // of the data arrays. 00390 // The remaining coordinate columns must contain scalar values. 00391 // <dt> Id column names (optional) 00392 // <dd> have to be given when a hypercolumn can consist of multiple 00393 // hypercubes. They define the column(s) determining which 00394 // hypercube has to be used for a data array. 00395 // The id columns must contain scalar values ((u)Int, float, 00396 // double, (D)Complex, String and/or Bool). 00397 // </dl> 00398 // It will be checked if the given columns exists and have 00399 // an appropriate type. 00400 // <br> 00401 // The default data manager type of the columns involved will be set 00402 // to TiledColumnStMan if all data columns have a fixed shape. 00403 // Otherwise they are set to TiledShapeStMan. 00404 // The storage manager group of all columns involved will be set to 00405 // the hypercolumn name. In that way binding columns to storage managers 00406 // during the table creation process is easier because a simple 00407 // <code>bindGroup</code> can be used. 00408 // <p> 00409 // For example:<br> 00410 // A table contains data matrices with axes pol and freq. 00411 // Those axes are defined in columns pol and freq containing 00412 // vectors with the same length as the corresponding axis. 00413 // The table also contains scalar columns time and baseline, which 00414 // superimpose dimensions upon the data. So the data will be stored 00415 // in a 4-d hypercube with axes pol,freq,time,baseline. 00416 // It would be defined as follows: 00417 // <srcblock> 00418 // tableDesc.defineHypercolumn ("dataCube", 4, 00419 // stringToVector ("data"), 00420 // stringToVector ("pol,freq,time,baseline")); 00421 // </srcblock> 00422 // Note that the function <linkto group="ArrayUtil.h#stringToVector"> 00423 // stringToVector</linkto> is very convenient for creating a vector 00424 // of Strings. 00425 // <group name=defineHypercolumn> 00426 void defineHypercolumn (const String& hypercolumnName, 00427 uInt ndim, 00428 const Vector<String>& dataColumnNames); 00429 void defineHypercolumn (const String& hypercolumnName, 00430 uInt ndim, 00431 const Vector<String>& dataColumnNames, 00432 const Vector<String>& coordColumnNames); 00433 void defineHypercolumn (const String& hypercolumnName, 00434 uInt ndim, 00435 const Vector<String>& dataColumnNames, 00436 const Vector<String>& coordColumnNames, 00437 const Vector<String>& idColumnNames); 00438 // </group> 00439 00440 // Test if the given hypercolumn exists. 00441 Bool isHypercolumn (const String& hypercolumnName) const; 00442 00443 // Get the names of all hypercolumns. 00444 Vector<String> hypercolumnNames() const; 00445 00446 // Get the columns involved in a hypercolumn. 00447 // It returns the dimensionality of the hypercolumn. 00448 // An exception is thrown if the hypercolumn does not exist. 00449 uInt hypercolumnDesc (const String& hypercolumnName, 00450 Vector<String>& dataColumnNames, 00451 Vector<String>& coordColumnNames, 00452 Vector<String>& idColumnNames) const; 00453 00454 // Adjust the hypercolumn definitions (for a RefTable). 00455 // It removes and/or renames columns as necessary. 00456 // Column names which are not part of the map are removed if 00457 // <src>keepUnknown==False</src>. 00458 // If all data columns of a hypercolumn are removed, the entire 00459 // hypercolumn is removed. 00460 void adjustHypercolumns (const SimpleOrderedMap<String,String>& old2new, 00461 Bool keepUnknownData = False, 00462 Bool keepUnknownCoord = False, 00463 Bool keppUnknownId = False); 00464 00465 // Remove ID-columns from the given hypercolumn definitions 00466 // and set their default data manager type to IncrementalStMan 00467 // and group to ISM_TSM. 00468 void removeIDhypercolumns (const Vector<String>& hcNames); 00469 00470 // Remove given hypercolumn definition. 00471 // An exception is thrown if it is not a hypercolumn. 00472 void removeHypercolumnDesc (const String& hypercolumnName); 00473 00474 // Check recursively if the descriptions of all subtables are known. 00475 void checkSubTableDesc() const; 00476 00477 void renameHypercolumn (const String& newHypercolumnName, 00478 const String& hypercolumnName); 00479 00480 00481 private: 00482 String name_p; //# name of table description 00483 String vers_p; //# version of table description 00484 String dir_p; //# directory 00485 String comm_p; //# comment 00486 TableRecord* key_p; //# user set of keywords 00487 TableRecord* privKey_p; //# Private set of keywords 00488 ColumnDescSet col_p; //# set of column names + indices 00489 Bool swwrite_p; //# True = description can be written 00490 TDOption option_p; //# Table desc. open option 00491 AipsIO iofil_p; //# File 00492 00493 // Assignment is not supported, because it is impossible to define 00494 // its semantics. Does the data need to be written into a file 00495 // before being overwritten? 00496 // Declaring it private, makes it unusable. 00497 TableDesc& operator= (const TableDesc&); 00498 00499 // Initialize the table description. 00500 void init (const TabPath&); 00501 00502 // Initialize and copy a table description. 00503 void copy (const TableDesc&, const TabPath&, Bool copyColumns); 00504 00505 // Throw an invalid hypercolumn exception. 00506 void throwHypercolumn (const String& hyperColumnName, 00507 const String& message); 00508 00509 00510 public: 00511 // Put the table description into the file. 00512 // The name can be used to write the TableDesc from a Table and 00513 // is used to set the names of subtables correctly. 00514 void putFile (AipsIO&, const TableAttr&) const; 00515 00516 // Get the table description from the file. 00517 void getFile (AipsIO&, const TableAttr&); 00518 }; 00519 00520 00521 //# Get number of columns. 00522 inline uInt TableDesc::ncolumn () const 00523 { return col_p.ncolumn(); } 00524 00525 //# Test if column exists. 00526 inline Bool TableDesc::isColumn (const String& name) const 00527 { return col_p.isDefined(name); } 00528 00529 //# Get a column description. 00530 inline const ColumnDesc& TableDesc::columnDesc (const String& name) const 00531 { return col_p[name]; } 00532 inline const ColumnDesc& TableDesc::operator[] (const String& name) const 00533 { return col_p[name]; } 00534 inline const ColumnDesc& TableDesc::columnDesc (uInt index) const 00535 { return col_p[index]; } 00536 inline const ColumnDesc& TableDesc::operator[] (uInt index) const 00537 { return col_p[index]; } 00538 inline ColumnDesc& TableDesc::rwColumnDesc (const String& name) 00539 { return col_p[name]; } 00540 inline ColumnDesc& TableDesc::rwColumnDesc (uInt index) 00541 { return col_p[index]; } 00542 00543 00544 //# Return the name (ie. type) of the table description. 00545 inline const String& TableDesc::getType () const 00546 { return name_p; } 00547 00548 //# Return the version of the table description. 00549 inline const String& TableDesc::version () const 00550 { return vers_p; } 00551 00552 //# Get access to the sets of keywords. 00553 inline TableRecord& TableDesc::rwKeywordSet () 00554 { return *key_p; } 00555 inline const TableRecord& TableDesc::keywordSet () const 00556 { return *key_p; } 00557 inline const TableRecord& TableDesc::privateKeywordSet () const 00558 { return *privKey_p; } 00559 00560 //# Get the set of columns. 00561 inline const ColumnDescSet& TableDesc::columnDescSet() const 00562 { return col_p; } 00563 00564 //# Add a column. 00565 inline ColumnDesc& TableDesc::addColumn (const ColumnDesc& column) 00566 { return col_p.addColumn (column); } 00567 00568 inline ColumnDesc& TableDesc::addColumn (const ColumnDesc& column, 00569 const String& newname) 00570 { return col_p.addColumn (column, newname); } 00571 00572 //# Remove a column. 00573 inline void TableDesc::removeColumn (const String& name) 00574 { col_p.remove (name); } 00575 00576 //# Access the comment. 00577 inline const String& TableDesc::comment () const 00578 { return comm_p; } 00579 00580 inline String& TableDesc::comment () 00581 { return comm_p; } 00582 00583 inline void TableDesc::checkSubTableDesc () const 00584 { col_p.checkSubTableDesc(); } 00585 00586 00587 00588 00589 } //# NAMESPACE CASA - END 00590 00591 #endif 00592