casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TableMeasRefDesc.h
Go to the documentation of this file.
00001 //# TableMeasRefDesc.h: Definition of a Measure Reference in a Table.
00002 //# Copyright (C) 1997,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: TableMeasRefDesc.h 20019 2007-03-13 21:40:09Z gervandiepen $
00027 
00028 #ifndef MEASURES_TABLEMEASREFDESC_H
00029 #define MEASURES_TABLEMEASREFDESC_H
00030 
00031 //# Includes
00032 #include <measures/TableMeasures/TableMeasOffsetDesc.h>
00033 #include <casa/Quanta/Unit.h>
00034 #include <casa/Arrays/Vector.h>
00035 #include <casa/BasicSL/String.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 //# Forward Declarations
00040 class TableMeasDescBase;
00041 class Table;
00042 class TableDesc;
00043 class TableRecord;
00044 
00045 
00046 // <summary>
00047 // Definition of a Measure Reference in a Table.
00048 // </summary>
00049 
00050 // <use visibility=export>
00051 
00052 // <reviewed reviewer="Bob Garwood" date="1999/12/23" tests="tTableMeasures.cc">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //# Classes you should understand before using this one.
00057 //   <li> <linkto module=Measures>Measures</linkto>
00058 //   <li> <linkto module=Tables>Tables</linkto>
00059 //   <li> <linkto class=TableMeasDesc>TableMeasDesc</linkto>
00060 // </prerequisite>
00061 
00062 // <synopsis>
00063 // TableMeasRefDesc is a class for setting up the MeasRef
00064 // component of a TableMeasDesc in the TableMeasures system.   With the aid
00065 // of a
00066 // TableMeasRefDesc the following possibilities for defining a Measure
00067 // column's reference exist:
00068 // <ul>
00069 //   <li> a fixed, non-variable, reference code, where all Measures in a
00070 //      column are to have the same reference code.
00071 //   <li> a unique (and probably different) reference code stored in each row.
00072 //   <li> a unique reference code stored in each array element per
00073 //      (Array)column row.
00074 // </ul>
00075 // For each of the above options an offset component can be specified
00076 // along with a reference code.  When a Measure offset is required a
00077 // <linkto class="TableMeasOffsetDesc">TableMeasOffsetDesc</linkto> is
00078 // supplied as an argument to the TableMeasRefDesc constructor.
00079 // With references containing an offset component either component can be set
00080 // to be variable or fixed independently of the other.
00081 //
00082 //   <note role=tip>
00083 //      It is not necessary to specify a Reference when defining a
00084 //      Measure column. In such cases the Measures retrieved from the column
00085 //      will have the default reference for the type of Measure stored in the
00086 //      column.
00087 //   </note>
00088 //
00089 // A fixed reference code is trivially stored as part of the column
00090 // keywords in the Measure column but a variable reference code requires
00091 // its own column.  A Scalar or Array column can be used dependent on your
00092 // needs but its type must always be either Int or String. Note that it is
00093 // legal to specify a Scalar
00094 // reference column for use with an ArrayMeasColumn. In such cases a single
00095 // reference code will be stored per array (row) of Measures.  However,
00096 // attempting to associate an Array column for references with a
00097 // ScalarMeasColumn will generate an exception.
00098 // <note>
00099 //  Because the reference codes stored are the enums defined in the Measures
00100 //  classes, it is possible that they change over time. The type strings,
00101 //  however, wille never change. Therefore the reference codes and types
00102 //  valid at the time of the table creation, are stored in the column keywords
00103 //  if the reference codes are kept in an integer column.
00104 //  <br>
00105 //  This has only been added in March 2007, but is fully backward compatible.
00106 //  Older tables will get the codes and types stored when accessed for
00107 //  read/write.
00108 // </note>
00109 //
00110 // <note role=caution>
00111 //  When storing Measures into a Measure column with a fixed reference code
00112 //  the reference code component of the Measures stored is
00113 //  ignored.
00114 // </note>
00115 // </synopsis>
00116 
00117 // <example>
00118 //<ol>
00119 // <li>Simplest kind of TableMeasRefDesc (apart from not specifying one at
00120 //     all) is a fixed reference code.  All Measures subsequently
00121 //     retrieved from the column will have the reference MEpoch::LAST.
00122 // <srcblock>
00123 //    // measure reference column
00124 //    TableMeasRefDesc reference(MEpoch::LAST);
00125 // </srcblock>
00126 // <li>A variable reference code requires its own Int column.
00127 // <srcblock>
00128 //    // An int column for the variable references.
00129 //    ScalarColumnDesc<Int> cdRefCol("refCol", "Measure reference column");
00130 //    td.addColumn(cdRefCol);
00131 //    ...
00132 //    // create the Measure reference descriptor
00133 //    TableMeasRefDesc varRef(td, "refCol");
00134 // </srcblock>
00135 // <li>A fix Measure reference code with a fixed Offset
00136 // <srcblock>
00137 //    // Create the Offset descriptor
00138 //    MEpoch offset(MVEpoch(MVTime(1996, 5, 17, (8+18./60.)/24.))
00139 //    TableMeasOffsetDesc offsetDesc(offset);
00140 //    // create the Measure reference descriptor
00141 //    TableMeasRefDesc varRef(MEpoch::LAST, offsetDesc);
00142 // </srcblock>
00143 //</ol>
00144 // For an example of the use of a TableMeasRefDesc in the context of a full
00145 // TableMeasDesc declaration see class
00146 // <linkto class="TableMeasDesc">TableMeasDesc</linkto>.
00147 // </example>
00148 
00149 // <motivation>
00150 // Creating the required keyword for the definition of a Measure
00151 // in a Table is somewhat complicated. This class assists in that
00152 // process.
00153 // </motivation>
00154 //
00155 // <thrown>
00156 //    <li>AipsError if the specified column doesn't exist or its type is
00157 //        not Int or String.
00158 // </thrown>
00159 //
00160 
00161 //# <todo asof="$DATE:$">
00162 //# A List of bugs, limitations, extensions or planned refinements.
00163 //# </todo>
00164 
00165 
00166 class TableMeasRefDesc
00167 {
00168 public:
00169   // Define a fixed MeasRef by supplying its reference code
00170   // Optionally a Measure offset can be specified.
00171   // The reference code and offset should not need a reference frame.
00172   // <group>
00173   explicit TableMeasRefDesc (uInt refCode = 0);
00174   TableMeasRefDesc (uInt refCode, const TableMeasOffsetDesc&);
00175   // </group>
00176 
00177   // Define a variable reference by supplying the name of the column
00178   // in which the reference is to be stored.  Either an <src>Int</src> or
00179   // <src>String</src> column can be specified.  This determines how
00180   // references are stored.  <src>Int</src> columns are likely to be
00181   // faster but storing
00182   // references as <src>Strings</src> may be useful if there is a need to
00183   // browse tables manually.  Optionally supply a Measure offset.
00184   // The reference code and offset should not need a reference frame.
00185   // <group>
00186   TableMeasRefDesc (const TableDesc&, const String& column);
00187   TableMeasRefDesc (const TableDesc&, const String& column,
00188                     const TableMeasOffsetDesc&);
00189   // </group>
00190 
00191   // Reconstruct the object from the MEASINFO record.
00192   // Not useful for the public.
00193   TableMeasRefDesc (const TableRecord& measInfo,
00194                     const Table&,
00195                     const MeasureHolder& measHolder,
00196                     const TableMeasDescBase&);
00197 
00198   // Copy constructor (copy semantics)
00199   TableMeasRefDesc (const TableMeasRefDesc& that);
00200 
00201   ~TableMeasRefDesc();
00202 
00203   // Assignment operator (copy semantics).
00204   TableMeasRefDesc& operator= (const TableMeasRefDesc& that);
00205 
00206   // Return the reference code.
00207   uInt getRefCode() const
00208     { return itsRefCode; }
00209 
00210   // Is the reference variable?
00211   Bool isRefCodeVariable() const
00212     { return (! itsColumn.empty()); }
00213 
00214   // Return the name of its variable reference code column.
00215   const String& columnName() const
00216     { return itsColumn; }
00217 
00218   // Is the reference code variable and stored in an integer column?
00219   Bool isRefCodeColumnInt() const
00220     { return itsRefCodeColInt; }
00221 
00222   // Do the keywords contain the reference codes and types.
00223   // For old tables this might not be the case.
00224   Bool hasRefTab() const
00225     { return itsHasRefTab; }
00226 
00227   // Returns True if the reference has an offset.
00228   Bool hasOffset() const
00229     { return (itsOffset != 0); }
00230 
00231   // Returns True if the offset is variable.
00232   Bool isOffsetVariable() const
00233     { return (itsOffset != 0  ?  itsOffset->isVariable() : False); }
00234 
00235   // Returns True is the offset is variable and it is an ArrayMeasColumn.
00236   Bool isOffsetArray() const
00237     { return (itsOffset != 0  ?  itsOffset->isArray() : False); }
00238 
00239   // Return the fixed Measure offset.
00240   // It does not test if the offset is defined; hasOffset() should be used
00241   // for that purpose.
00242   const Measure& getOffset() const
00243     { return itsOffset->getOffset(); }
00244 
00245   // Return the name of the Measure offset column.
00246   // An empty string is returned if no variable offset is used.
00247   const String& offsetColumnName() const
00248     { return itsOffset->columnName(); }
00249 
00250   // Reset the refCode or offset.
00251   // It overwrites the value used when defining the TableMeasDesc.
00252   // It is only possible if it was defined as fixed for the entire column.
00253   // <group>
00254   void resetRefCode (uInt refCode);
00255   void resetOffset (const Measure& offset);
00256   // </group>
00257 
00258   // Make the Measure value descriptor persistent.  Normally would not be
00259   // called by the user directly.
00260   // <group>
00261   void write (TableDesc&, TableRecord& measInfo, const TableMeasDescBase&);
00262   void write (Table&, TableRecord& measInfo, const TableMeasDescBase&);
00263   // </group>
00264 
00265   // Initialize the table reference codes and types and
00266   // the maps (mapping a code onto itself).
00267   void initTabRef (const MeasureHolder& measHolder);
00268 
00269   // Reference codes can be persistent in tables.
00270   // Because their enum values can change, a mapping of current table
00271   // to table value is maintained. The mapping is created using their
00272   // never-changing string representations.
00273   // These functions convert current refcode to and from table refcode.
00274   // <group>
00275   uInt tab2cur (uInt tabRefCode) const;
00276   uInt cur2tab (uInt curRefCode) const;
00277   // </group>
00278 
00279   // Set the function used to get all reference codes for a MeasureHolder.
00280   // This is not reaaly needed for normal practice, but makes it possible
00281   // to add extra codes when testing.
00282   // <br> The default function simply calls MeasureHolder.asMeasure.allTypes.
00283   // <group>
00284   typedef void TypesFunc (Vector<String>& types,
00285                           Vector<uInt>& codes, const MeasureHolder&);
00286   static void setTypesFunc (TypesFunc* func)
00287     { theirTypesFunc = func; }
00288   static void defaultTypesFunc (Vector<String>& types,
00289                                 Vector<uInt>& codes, const MeasureHolder&);
00290   static TypesFunc* theirTypesFunc;
00291   // </group>
00292 
00293 private:
00294   uInt itsRefCode;
00295   // The name of column containing its variable references.
00296   String itsColumn;
00297   // Is the reference code column a string column?
00298   Bool   itsRefCodeColInt;
00299   // Do the keywords contain the reference codes and types?
00300   Bool   itsHasRefTab;
00301   //# Its reference offset.
00302   TableMeasOffsetDesc* itsOffset;       
00303   //# Define the vectors holding the measref codes and types.
00304   //# These are the codes as used in the table, which might be different
00305   //# from the current values.
00306   Vector<String> itsTabRefTypes;
00307   Vector<uInt>   itsTabRefCodes;
00308   //# Define the mappings of table measref codes to current ones and back.
00309   //# There are only filled in and used if a variable reference code is used.
00310   Block<Int> itsTab2Cur;
00311   Block<Int> itsCur2Tab;
00312 
00313   // Fill the reference code mappings for table<->current.
00314   // <group>
00315   void initTabRefMap();
00316   void fillTabRefMap (const MeasureHolder& measHolder);
00317   uInt fillMap (Block<Int>& f2t,
00318                 const Vector<uInt>& codesf,
00319                 const Vector<String>& typesf,
00320                 Vector<uInt>& codest,
00321                 Vector<String>& typest,
00322                 Int maxnr);
00323   // </group>
00324 
00325   // Write the actual keywords.
00326   void writeKeys (TableRecord& measInfo, 
00327                   const TableMeasDescBase& measDesc);
00328 
00329   // Throw an exception if the column doesn't exist or is of the
00330   // wrong type.
00331   void checkColumn (const TableDesc& td);
00332 };
00333 
00334 
00335 
00336 } //# NAMESPACE CASA - END
00337 
00338 #endif