casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
BaseMappedArrayEngine.h
Go to the documentation of this file.
00001 //# BaseMappedArrayEngine.h: Abstract virtual column engine for virtual->stored mapping
00002 //# Copyright (C) 1995,1996,1997,1999,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: BaseMappedArrayEngine.h 21298 2012-12-07 14:53:03Z gervandiepen $
00027 
00028 #ifndef TABLES_BASEMAPPEDARRAYENGINE_H
00029 #define TABLES_BASEMAPPEDARRAYENGINE_H
00030 
00031 //# Includes
00032 #include <tables/Tables/VirtColEng.h>
00033 #include <tables/Tables/VirtArrCol.h>
00034 #include <casa/Arrays/IPosition.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 //# Forward Declarations
00039 template<class T> class ArrayColumn;
00040 class TableColumn;
00041 
00042 
00043 // <summary>
00044 // Templated virtual column engine for a table array of any type.
00045 // </summary>
00046 
00047 // <use visibility=export>
00048 
00049 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00050 // </reviewed>
00051 
00052 // <prerequisite>
00053 //# Classes you should understand before using this one.
00054 //   <li> <linkto class=VirtualColumnEngine>VirtualColumnEngine</linkto>
00055 //   <li> <linkto class=VirtualArrayColumn>VirtualArrayColumn</linkto>
00056 // </prerequisite>
00057 
00058 // <etymology>
00059 // BaseMappedArrayEngine contains for the 1-1 mapping of a virtual
00060 // column to a stored column (both containing arrays). 
00061 // </etymology>
00062 
00063 // <synopsis> 
00064 // BaseMappedArrayEngine is an abstract base class for virtual column engines
00065 // which map data from the arrays in the virtual column to
00066 // the arrays in the stored column. Note the the stored column does not need
00067 // to be stored; it can be another virtual column, but usually it will be a
00068 // stored column.
00069 // Examples of classes using this base class are
00070 // <linkto class=ScaledArrayEngine>ScaledArrayEngine</linkto> and
00071 // <linkto class=RetypedArrayEngine>RetypedArrayEngine</linkto>.
00072 //
00073 // The virtual column has to be bound to the virtual column engine used
00074 // for it. The stored column will usually be bound to a storage manager,
00075 // but any other suitable data manager is possible. E.g. it is
00076 // possible to use <src>MappedArrayEngine<StokesVector,float></src>
00077 // to map a StokesVector to a float column, which in its turn uses
00078 // <src>ScaledArrayEngine<float,Int></src> to store it as integers.
00079 // Note that the names of the virtual and stored column have to be different,
00080 // otherwise the table system cannot distinguish them.
00081 //
00082 // This base class does several tasks for the derived classes.
00083 // The main one is to keep and handle the information about the virtual
00084 // and stored column. The name of the stored column is written as a keyword
00085 // in the virtual column. In this way the stored column is known when
00086 // a table is read back. It also creates <src>(RO)ArrayColumn<T></src>
00087 // objects to access the stored column. The function roColumn gives
00088 // read access, while rwColumn gives write access.
00089 //
00090 // An engine object should be used for one column only, because the stored
00091 // column name is part of the engine. If it would be used for more than
00092 // one column, they would all share the same stored column.
00093 // When the engine is bound to a column, it is checked if the name
00094 // of that column matches the given virtual column name.
00095 //
00096 // The engine can be used for a column containing any kind of array
00097 // (thus direct or indirect, fixed or variable shaped)) as long as the
00098 // virtual array can be stored in the stored array. Thus a fixed shaped
00099 // virtual can use a variable shaped stored, but not vice versa.
00100 // A fixed shape indirect virtual can use a stored with direct arrays.
00101 //
00102 // The DataManager framework contains various virtual functions.
00103 // This class implements several, but not all of them. Furthermore
00104 // some implementations may not be optimal or correct for derived classes.
00105 // Hereafter follows a list of functions which may need implementation
00106 // in derived classes. The classes mentioned in the examples below show
00107 // implementations of these functions.
00108 // <ul>
00109 // <li>
00110 // The following (virtual) functions have to be implemented:
00111 // <dl>
00112 // <dt><src>
00113 //       ~... (the destructor)
00114 // </src>
00115 // <dt><src>
00116 //        DataManager* clone() const;
00117 // </src>
00118 // <dt><src>
00119 //        String dataManagerType() const;
00120 // </src>
00121 // <dt><src>
00122 //        static void registerClass();
00123 // </src>
00124 // <dt><src>
00125 //        static DataManager* makeObject (const String& dataManagerType);
00126 // </src>
00127 // <dt><src>
00128 //        void getArray (uInt rownr, Array<T>& data);
00129 // </src>
00130 // <dt><src>
00131 //        void putArray (uInt rownr, const Array<T>& data);
00132 // </src>
00133 // (only if the virtual column is writable).
00134 // </dl>
00135 // <li>
00136 // For efficiency reasons it could be better to implement the following
00137 // functions:
00138 // <dl>
00139 // <dt><src>
00140 //        void getSlice (uInt rownr, const Slicer& slicer, Array<T>& data);
00141 // </src>
00142 // <dt><src>
00143 //        void putSlice (uInt rownr, const Slicer& slicer,
00144 //                       const Array<T>& data);
00145 // </src>
00146 // <dt><src>
00147 //        void getArrayColumn (Array<T>& data);
00148 // </src>
00149 // <dt><src>
00150 //        void putArrayColumn (const Array<T>& data);
00151 // </src>
00152 // <dt><src>
00153 //        void getColumnSlice (const Slicer& slicer, Array<T>& data);
00154 // </src>
00155 // <dt><src>
00156 //        void putColumnSlice (const Slicer& slicer, const Array<T>& data);
00157 // </src>
00158 // </dl>
00159 // <li>
00160 // The following functions have to be implemented when the shapes
00161 // of the virtual and stored arrays are not the same.
00162 // <dl>
00163 // <dt><src>
00164 //    void setShapeColumn (const IPosition& shape);
00165 // </src>
00166 // <dt><src>
00167 //    void setShape (uInt rownr, const IPosition& shape);
00168 // </src>
00169 // <dt><src>
00170 //    uInt ndim (uInt rownr);
00171 // </src>
00172 // <dt><src>
00173 //    IPosition shape (uInt rownr);
00174 // </src>
00175 // </dl>
00176 // <li>
00177 // The following functions deal with the initialization and persistence
00178 // of engine specific variables. When the class has variables of its
00179 // own, these functions may need to be implemented. Implementations of
00180 // create and prepare have to call the similar functions in this base class.
00181 // <dl>
00182 // <dt><src>
00183 //    void close (AipsIO& ios);
00184 // </src>
00185 // <dt><src>
00186 //    void create (uInt nrrow);
00187 // </src>
00188 // <dt><src>
00189 //    void open (uInt nrrow, AipsIO& ios);
00190 // </src>
00191 // <dt><src>
00192 //    void prepare();
00193 // </src>
00194 // </dl>
00195 // <li>
00196 // The following functions do not need to be declared and implemented
00197 // in derived classes unless it is a very special case.
00198 // <dl>
00199 // <dt><src>
00200 //    String dataManagerName() const;
00201 // </src>
00202 // <dt><src>
00203 //    Bool canAddRow() const;
00204 // </src>
00205 // <dt><src>
00206 //    Bool canRemoveRow() const;
00207 // </src>
00208 // <dt><src>
00209 //    void addRow (uInt nrrow);
00210 // </src>
00211 // <dt><src>
00212 //    void removeRow (uInt rownr);
00213 // </src>
00214 // <dt><src>
00215 //    DataManagerColumn* makeDirArrColumn (const String& columnName,
00216 //                                               int dataType,
00217 //                                               const String& dataTypeId);
00218 // </src>
00219 // <dt><src>
00220 //    DataManagerColumn* makeIndArrColumn (const String& columnName,
00221 //                                               int dataType,
00222 //                                               const String& dataTypeId);
00223 // </src>
00224 // <dt><src>
00225 //    Bool isWritable() const;
00226 // </src>
00227 // <dt><src>
00228 //    Bool isShapeDefined (uInt rownr);
00229 // </src>
00230 // </dl>
00231 // </ul>
00232 // </synopsis>
00233 
00234 // <example>
00235 // The derived classes
00236 // <linkto class=ScaledArrayEngine>ScaledArrayEngine</linkto> and
00237 // <linkto class=RetypedArrayEngine>RetypedArrayEngine</linkto>
00238 // are two examples of how to derive a class from this base class.
00239 // Note that ScaledArrayEngine does not need to implement functions
00240 // dealing with shapes, because it can use them from this base class.
00241 // On the other hand they need to be implemented in RetypedArrayEngine.
00242 // </example>
00243 
00244 // <motivation>
00245 // This base class implements several functions making the implementation
00246 // of derived classes simpler. Many details are implemented here, so often
00247 // only the basic mapping functions (get, put) need to be implemented
00248 // in a derived class.
00249 // </motivation>
00250 
00251 // <templating arg=VirtualType>
00252 //  <li> default constructor
00253 //  <li> copy constructor
00254 //  <li> assignment operator
00255 //  <li> <src>static String dataTypeId();   // unique name of the class</src>
00256 // </templating>
00257 // <templating arg=StoredType>
00258 //  <li> Default constructor
00259 //  <li> Copy constructor
00260 //  <li> Assignment operator
00261 // </templating>
00262 
00263 
00264 template<class VirtualType, class StoredType> class BaseMappedArrayEngine : public VirtualColumnEngine, public VirtualArrayColumn<VirtualType>
00265 {
00266 public:
00267     // Get the virtual column name.
00268     const String& virtualName() const;
00269 
00270     // Get the stored column name.
00271     const String& storedName() const;
00272 
00273     // The column is writable if the underlying stored column is writable.
00274     virtual Bool isWritable() const;
00275 
00276 protected:
00277 
00278     // Construct an engine to convert the virtual column to the stored column.
00279     // StoredColumnName is the name of the column where the converted
00280     // data will be put and must have data type StoredType.
00281     // The virtual column using this engine must have data type VirtualType.
00282     // By default the virtual column is assumed to be writable.
00283     // Use setWritable to unset it.
00284     BaseMappedArrayEngine (const String& virtualColumnName,
00285                            const String& storedColumnName);
00286 
00287     // Destructor is mandatory.
00288     ~BaseMappedArrayEngine();
00289 
00290     // The default constructor is required for reconstruction of the
00291     // engine when a table is read back.
00292     BaseMappedArrayEngine();
00293 
00294     // Copy constructor is only used by copy constructor of derived classes.
00295     // (so it is made protected).
00296     BaseMappedArrayEngine
00297                       (const BaseMappedArrayEngine<VirtualType, StoredType>&);
00298 
00299     // Set if the column is writable or not.
00300     void setWritable (Bool isWritable);
00301 
00302     // Set the virtual and stored column name.
00303     void setNames (const String& virtualName, const String& storedName);
00304 
00305     // Give readonly access to the stored column.
00306     // This can be used by the derived classes to get data.
00307     inline ArrayColumn<StoredType>& roColumn();
00308 
00309     // Give read/write access to the stored column.
00310     // This can be used by the derived classes to put data.
00311     inline ArrayColumn<StoredType>& rwColumn();
00312 
00313     // Create the column object for the array column in this engine.
00314     // It will check if the given column name matches the virtual
00315     // column name. This assures that the engine is bound to the
00316     // correct column.
00317     virtual DataManagerColumn* makeIndArrColumn (const String& columnName,
00318                                                  int dataType,
00319                                                  const String& dataTypeId);
00320 
00321     // Initialize the object for a new table.
00322     // It defines a virtual column keyword telling the stored column name.
00323     // Initially the table has the given number of rows.
00324     // A derived class can have its own create function, but that should
00325     // always call this create function.
00326     virtual void create (uInt initialNrrow);
00327 
00328     // Preparing consists of setting the writable switch and
00329     // adding the initial number of rows in case of create.
00330     // It reads the stored column name from the virtual column keywords.
00331     // A derived class can have its own prepare function, but that should
00332     // always call this prepare function.
00333     virtual void prepare();
00334 
00335     // Do the 2 stages of the prepare (define columns and adding rows).
00336     // <group>
00337     void prepare1();
00338     void prepare2();
00339     // </group>
00340 
00341     // Rows are added to the end of the table.
00342     // If the virtual column has FixedShape arrays and the stored not,
00343     // the shape in each stored row will be set.
00344     // This assures that the arrays are properly defined in each row,
00345     // so putSlice can be used without problems.
00346     // <br>The second version is used by prepare2, because in case a column is
00347     // added to an already existing table, table.nrow() gives the existing
00348     // number of columns instead of 0.
00349     // <group>
00350     virtual void addRow (uInt nrrow);
00351     virtual void addRowInit (uInt startRow, uInt nrrow);
00352     // </group>
00353 
00354     // Set the shape of the FixedShape arrays in the column.
00355     // This function only gets called if the column has FixedShape arrays.
00356     // The shape gets saved and used to set the shape of the arrays
00357     // in the stored in case the stored has non-FixedShape arrays.
00358     // This implementation assumes the shape of virtual and stored arrays
00359     // are the same. If not, it has to be overidden in a derived class.
00360     virtual void setShapeColumn (const IPosition& shape);
00361 
00362     // Define the shape of the array in the given row.
00363     // It will define the shape of the (underlying) array.
00364     // This implementation assumes the shape of virtual and stored arrays
00365     // are the same. If not, it has to be overidden in a derived class.
00366     virtual void setShape (uInt rownr, const IPosition& shape);
00367 
00368     // Test if the (underlying) array is defined in the given row.
00369     virtual Bool isShapeDefined (uInt rownr);
00370 
00371     // Get the dimensionality of the (underlying) array in the given row.
00372     // This implementation assumes the dimensionality of virtual and
00373     // stored arrays are the same. If not, it has to be overidden in a
00374     // derived class.
00375     virtual uInt ndim (uInt rownr);
00376 
00377     // Get the shape of the (underlying) array in the given row.
00378     // This implementation assumes the shape of virtual and stored arrays
00379     // are the same. If not, it has to be overidden in a derived class.
00380     virtual IPosition shape (uInt rownr);
00381 
00382     // The data manager can handle changing the shape of an existing array
00383     // when the underlying stored column can do it.
00384     virtual Bool canChangeShape() const;
00385 
00386     // Make a table column object for the given column.
00387     // This has to be used in the create function, otherwise it could not
00388     // create a TableColumn object to store data in the column keywords.
00389     TableColumn makeTableColumn (const String& columnName);
00390 
00391     // Get an array in the given row.
00392     // This will scale and offset from the underlying array.
00393     virtual void getArray (uInt rownr, Array<VirtualType>& array);
00394 
00395     // Put an array in the given row.
00396     // This will scale and offset to the underlying array.
00397     virtual void putArray (uInt rownr, const Array<VirtualType>& array);
00398 
00399     // Get a section of the array in the given row.
00400     // This will scale and offset from the underlying array.
00401     virtual void getSlice (uInt rownr, const Slicer& slicer,
00402                            Array<VirtualType>& array);
00403 
00404     // Put into a section of the array in the given row.
00405     // This will scale and offset to the underlying array.
00406     virtual void putSlice (uInt rownr, const Slicer& slicer,
00407                            const Array<VirtualType>& array);
00408 
00409     // Get an entire column.
00410     // This will scale and offset from the underlying array.
00411     virtual void getArrayColumn (Array<VirtualType>& array);
00412 
00413     // Put an entire column.
00414     // This will scale and offset to the underlying array.
00415     virtual void putArrayColumn (const Array<VirtualType>& array);
00416 
00417     // Get some array values in the column.
00418     // This will scale and offset from the underlying array.
00419     virtual void getArrayColumnCells (const RefRows& rownrs,
00420                                       Array<VirtualType>& data);
00421 
00422     // Put some array values in the column.
00423     // This will scale and offset to the underlying array.
00424     virtual void putArrayColumnCells (const RefRows& rownrs,
00425                                       const Array<VirtualType>& data);
00426 
00427     // Get a section of all arrays in the column.
00428     // This will scale and offset from the underlying array.
00429     void getColumnSlice (const Slicer& slicer, Array<VirtualType>& array);
00430 
00431     // Put a section of all arrays in the column.
00432     // This will scale and offset to the underlying array.
00433     void putColumnSlice (const Slicer& slicer, const Array<VirtualType>& array);
00434 
00435     // Get a section of some arrays in the column.
00436     // This will scale and offset from the underlying array.
00437     virtual void getColumnSliceCells (const RefRows& rownrs,
00438                                       const Slicer& slicer,
00439                                       Array<VirtualType>& data);
00440 
00441     // Put into a section of some arrays in the column.
00442     // This will scale and offset to the underlying array.
00443     virtual void putColumnSliceCells (const RefRows& rownrs,
00444                                       const Slicer& slicer,
00445                                       const Array<VirtualType>& data);
00446 
00447     // Map the virtual shape to the stored shape.
00448     // By default is returns the virtual shape.
00449     virtual IPosition getStoredShape (uInt rownr,
00450                                       const IPosition& virtualShape);
00451 
00452     // Map the slicerfor a virtual shape to a stored shape.
00453     // By default it returns the virtualinput slicer.
00454     virtual Slicer getStoredSlicer (const Slicer& virtualSlicer) const;
00455 
00456     // Map StoredType array to VirtualType array.
00457     // This is meant when reading an array from the stored column.
00458     // The default implementation throws an exception.
00459     virtual void mapOnGet (Array<VirtualType>& array,
00460                            const Array<StoredType>& stored);
00461 
00462     // Map Bool array to bit flags array.
00463     // This is meant when writing an array into the stored column.
00464     // The default implementation throws an exception.
00465     virtual void mapOnPut (const Array<VirtualType>& array,
00466                            Array<StoredType>& stored);
00467 
00468 
00469 private:
00470     // Assignment is not needed and therefore forbidden
00471     // (so it is made private and not implemented).
00472     BaseMappedArrayEngine<VirtualType, StoredType>& operator=
00473                      (const BaseMappedArrayEngine<VirtualType, StoredType>&);
00474 
00475 
00476     //# Now define the data members.
00477     String         virtualName_p;        //# virtual column name
00478     String         storedName_p;         //# stored column name
00479     Bool           isWritable_p;         //# is virtual column writable?
00480     Bool           tempWritable_p;       //# True =  create phase, so column
00481     //#                                              is temporarily writable
00482     //#                                      False = asks stored column
00483     uInt           initialNrrow_p;       //# initial #rows in case of create
00484     Bool           arrayIsFixed_p;       //# True = virtual is FixedShape array
00485     IPosition      shapeFixed_p;         //# shape in case FixedShape array
00486     ArrayColumn<StoredType>* column_p;   //# the stored column
00487 };
00488 
00489 
00490 
00491 template<class VirtualType, class StoredType>
00492 inline const String&
00493 BaseMappedArrayEngine<VirtualType, StoredType>::virtualName() const
00494     { return virtualName_p; }
00495 
00496 template<class VirtualType, class StoredType>
00497 inline const String&
00498 BaseMappedArrayEngine<VirtualType, StoredType>::storedName() const
00499     { return storedName_p; }
00500 
00501 template<class VirtualType, class StoredType>
00502 inline void
00503 BaseMappedArrayEngine<VirtualType, StoredType>::setNames
00504                     (const String& virtualName, const String& storedName)
00505 {
00506     virtualName_p = virtualName;
00507     storedName_p  = storedName;
00508 }
00509 
00510 template<class VirtualType, class StoredType>
00511 inline void
00512 BaseMappedArrayEngine<VirtualType, StoredType>::setWritable (Bool isWritable)
00513     { isWritable_p = isWritable; }
00514 
00515 template<class VirtualType, class StoredType>
00516 inline ArrayColumn<StoredType>&
00517 BaseMappedArrayEngine<VirtualType, StoredType>::roColumn()
00518     { return *column_p; }
00519 
00520 template<class VirtualType, class StoredType>
00521 inline ArrayColumn<StoredType>&
00522 BaseMappedArrayEngine<VirtualType, StoredType>::rwColumn()
00523     { return *column_p; }
00524 
00525 
00526 
00527 } //# NAMESPACE CASA - END
00528 
00529 #ifndef CASACORE_NO_AUTO_TEMPLATES
00530 #include <tables/Tables/BaseMappedArrayEngine.tcc>
00531 #endif //# CASACORE_NO_AUTO_TEMPLATES
00532 #endif