casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
RetypedArrayEngine.h
Go to the documentation of this file.
00001 //# RetypedArrayEngine.h: Virtual column engine to retype and reshape arrays
00002 //# Copyright (C) 1995,1996,1999,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: RetypedArrayEngine.h 20932 2010-07-08 09:06:37Z gervandiepen $
00027 
00028 #ifndef TABLES_RETYPEDARRAYENGINE_H
00029 #define TABLES_RETYPEDARRAYENGINE_H
00030 
00031 //# Includes
00032 #include <tables/Tables/BaseMappedArrayEngine.h>
00033 #include <tables/Tables/TableRecord.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 //# Forward Declarations
00038 
00039 
00040 // <summary>
00041 // Virtual column engine to retype and reshape arrays.
00042 // </summary>
00043 
00044 // <use visibility=export>
00045 
00046 // <reviewed reviewer="Brian Glendenning" date="1995/12/20" tests="dRetypedArrayEngine.cc" demos=dRetypedArrayEngine.h>
00047 // </reviewed>
00048 
00049 // <prerequisite>
00050 //# Classes you should understand before using this one.
00051 //   <li> <linkto class=BaseMappedArrayEngine>BaseMappedArrayEngine</linkto>
00052 // </prerequisite>
00053 
00054 // <synopsis> 
00055 // RetypedArrayEngine maps a virtual column containing arrays of objects
00056 // to a stored column containing arrays of data of another type. Usually
00057 // the dimensionality of the arrays get smaller during this mapping process.
00058 // The engine makes it possible to store an array of any type in a table.
00059 // <br>
00060 // For example, a column with 2D arrays of StokesVector's can be mapped to
00061 // a column with 3D arrays of floats (of which the first axes has, say,
00062 // length 4). Another example is mapping a 2D array of StokesMatrix's
00063 // to a 4D array of floats.
00064 // <p>
00065 // The mapping process has to be done by a (static) set and get
00066 // function in the VirtualType class. When a RetypedArrayEngine object is
00067 // constructed, it is possible to pass information in a TableRecord. This
00068 // TableRecord is indirectly passed to the set/get functions. This is done by
00069 // means of the function newCopyInfo, which can preprocess the information
00070 // in the TableRecord and store it in another object. That object is passed to
00071 // the set and get functions. At the end a function deleteCopyInfo is called
00072 // to delete the object. Of course, it is not needed to allocate such
00073 // an object; newCopyInfo can return a null pointer.
00074 // <note role=tip> Because the variables have to be generic and because of
00075 // limitations in the CFront compiler, several variables have to be
00076 // passed as void* and need to be casted in the set/get functions.
00077 // </note>
00078 //
00079 // The virtual column data type class has to contain several functions.
00080 // The example shows how they can be implemented.
00081 // <dl>
00082 //  <dt> <src>static String dataTypeId();</src>
00083 //  <dd> has to give the (unique) name of the class.
00084 //  <dt> <src>static IPosition shape();</src>
00085 //  <dd> This has to return the full shape of the elements in the virtual.
00086 //       E.g. StokesVector will return [4]. StokesMatrix will return [4,4].
00087 //  <dt> <src>static void* newCopyInfo (const TableRecord& record,
00088 //                                  const IPosition& virtualElementShape);</src>
00089 //  <dd> This function has to setup the set/get functions by preprocessing the
00090 //       information contained in the TableRecord and storing it in a so-called
00091 //       "copyInfo" object. A pointer to that object has to be returned, which
00092 //       is kept by the engine and passed to the set/get functions.
00093 //       The "copyInfo" class can be a nested class in the VirtualType
00094 //       (as shown in the StokesVector example), but it can also
00095 //       be an independent class.
00096 //       <br>
00097 //       The supplied TableRecord is the TableRecord given when
00098 //       constructing the engine.
00099 //       When no TableRecord was given, it will be empty.
00100 //       The supplied shape is the shape of a virtual element as given to
00101 //       the constructor of the engine. This can be a full or partial shape.
00102 //       E.g. for a StokesVector it will usually be [4], but it can also,
00103 //       say, [1] if only U is used.
00104 //       The function could check if the information in the TableRecord
00105 //       and the shape match.
00106 //       <br>
00107 //       Of course, a VirtualType may not need any extra information.
00108 //       Therefore it is possible to return a null "copyInfo" pointer.
00109 //  <dt> <src>static void deleteCopyInfo (void* copyInfo);</src>
00110 //  <dd> This function has to delete the "copyInfo" object allocated
00111 //       by newCopyInfo. To do so, it needs to cast the pointer to the
00112 //       correct type.
00113 //  <dt> <src>static void set (void* copyInfo, void* out,
00114 //                             const Array<StoredType>& in,
00115 //                             const IPosition& virtualElementShape);</src>
00116 //  <dd> This function is called when an <src>Array<VirtualType></src> is read.
00117 //       It has to convert the StoredType array to the VirtualType array.
00118 //       In principle, there are two different cases (which can be deduced
00119 //       from the given shape):
00120 //       <ol>
00121 //       <li> The stored information is complete. For example: suppose the
00122 //            VirtualType is a StokesVector object (containing I, Q, U and V),
00123 //            When the stored array contains 4 values per StokesVector,
00124 //            it is complete.
00125 //            <br>
00126 //            In this case the entire virtual array can be directly copied from
00127 //            the stored array when the VirtualType object contains no
00128 //            virtual functions and the data are directly contained in it.
00129 //            The function
00130 //            <br>
00131 //            <linkto group=RetypedArraySetGet.h#RetypedArrayEngineSetGet>
00132 //            <src>
00133 //            retypedArrayEngineSet (Array<VirtualType>& out,
00134 //                                   const Array<StoredType>& in);
00135 //            </src></linkto><br>
00136 //            can be used for this purpose.
00137 //       <li> When in the example above the stored array contains less
00138 //            than 4 values per StokesVector, the stored information
00139 //            is incomplete. In this case the set function has to
00140 //            fill the data in one way or another. The information
00141 //            in the "copyInfo" object can assist in it.
00142 //            <br>
00143 //            Each VirtualType element has to be set individually, so
00144 //            a loop through the array is required. To assist in this,
00145 //            the loop has been implemented in the function
00146 //            <br>
00147 //            <linkto group=RetypedArraySetGet.h#RetypedArrayEngineSetGet>
00148 //            <src>
00149 //            retypedArrayEngineSet (Array<VirtualType>& out,
00150 //                                   const Array<StoredType>& in,
00151 //                                   const void* extraArgument);
00152 //            </src></linkto>
00153 //            <br> It calls the VirtualType function
00154 //            <srcblock>
00155 //             void setElem (const StoredType* data, const IPosition& shape,
00156 //                           const void* extraArgument);
00157 //            </srcblock>
00158 //            for each VirtualType element. This set function has to
00159 //            fill the VirtualType object from the data. It can use the
00160 //            shape and the extraArgument to know how it should do it.
00161 //            <br>
00162 //            Note that the 3-argument function retypedArrayEngineSet is
00163 //            only a convenience function. For optimal performance it may
00164 //            be needed to handcode the loop instead of using this function.
00165 //       </ol>
00166 //       <note role=warning> Note that the given virtual element shape does
00167 //       not need to match the shape given to the constructor of the engine.
00168 //       It is possible that the user sets the shape of the stored array
00169 //       before putting the virtual array. In that case the system uses the
00170 //       relevant part of the stored array shape as the virtual element shape.
00171 //       </note>
00172 //       <note role=tip> If the out argument is declared (as it should be) as
00173 //       <src>Array<VirtualType>& out</src>,
00174 //       the CFront compiler complains about unknown size of
00175 //       VirtualType when instantiating Array<VirtualType>.
00176 //       Therefore it has to be declared as void* and the set function
00177 //       needs to cast it to <src>Array<VirtualType>*</src>.
00178 //       </note>
00179 //  <dt> <src>static void get (void* copyInfo, Array<float>& out,
00180 //                             const void* in,
00181 //                             const IPosition& virtualElementShape);</src>
00182 //  <dd> This function is similar to the set function described above, but
00183 //       is called when an <src>Array<VirtualType></src> is written.
00184 //       It has to convert the VirtualType array to the StoredType array.
00185 // </dl>
00186 //
00187 // <br>E.g.: A StokesVector has 4 float elements.
00188 // <srcblock>
00189 //    // Construct the column object for the Stokes column.
00190 //    ArrayColumn<StokesVector> stokesColumn (table, "StokesVirtualColumn");
00191 //    // Put an array of StokesVector's with shape 512,512.
00192 //    // This will implicitly set the shape of the underlying
00193 //    // data column to 4,512,512.
00194 //    // This put is very quick (it can copy all data in one go).
00195 //    Array<StokesVector> stokesData (IPosition(2,512,512));
00196 //    stokesColumn.put (rownr, stokesData);
00197 //
00198 //    // Get the column object for the Data column.
00199 //    // Set its shape explicitly to 1,512,512,
00200 //    ArrayColumn<float> dataColumn (table, "DataColumn");
00201 //    dataColumn.setShape (rownr, IPosition(3,1,512,512));
00202 //    // Now a put of the data results in calling the StokesVector::getElem
00203 //    // function for each element with an IPosition(1,1); i.e. the
00204 //    // data array needs only one value for each StokesVector.
00205 //    stokesColumn.put (rownr, stokesData);
00206 // </srcblock>
00207 //
00208 // When reading a table back, the engine has to be registered.
00209 // Otherwise it will be unknown to the table system.
00210 // Similarly, the appropriate ArrayColumnDesc object has to be registered.
00211 // This can be done as follows:
00212 // <pre>
00213 //    RetypedArrayEngine<StokesVector,float>::registerClass();
00214 //    ArrayColumnDesc<StokesVector> tmp(ColumnDesc::registerMap);
00215 // </pre>
00216 // When they are not registered, the open of the table will fail
00217 // telling which class could not be found.
00218 // </synopsis> 
00219 
00220 // <motivation>
00221 // This class allows one to store arrays of arbitrary objects in a table.
00222 // It also allows it to be done it in a very efficient way.
00223 // <p>
00224 // The class had to be doubly templated. There were 2 reasons:
00225 // <ol>
00226 //  <li> The typedef trick described on page 321 in Barton/Nackman
00227 //       did not work with the CFront-based ObjectCenter compiler.
00228 //  <li> It was needed to allow derivation from BaseMappedArrayEngine.
00229 // </ol>
00230 // <p>
00231 // Originally it was the idea to have a mandatory nested CopyInfo class in the
00232 // VirtualType class and use syntax like VirtualType::CopyInfo to access
00233 // functions in it and to keep a pointer to such an object. Alas, the
00234 // CFront compiler could not handle this.
00235 // <p>
00236 // Because the engine can serve only one column, it was possible to
00237 // combine the engine and the column functionality in one class.
00238 // This has been achieved using multiple inheritance.
00239 // The advantage of this is that only one templated class is used,
00240 // so fewer template instantiations are needed.
00241 // </motivation>
00242 
00243 // <example>
00244 // The following example shows how a StokesVector could be implemented.
00245 // It doesn't check whether the mask is correct.
00246 // Two more examples are contained in the demo/test program
00247 // <a href="../../../../code/aips/implement/Tables/test/dRetypedArrayEngine.h">
00248 // dRetypedArrayEngine.h</a> and its
00249 // <a href="../../../../code/aips/implement/Tables/test/dRetypedArrayEngine.cc">
00250 // .cc file</a>. Their second example (class RetypedArrayEx2) is similar to
00251 // the StokesVector example below, but contains more extensive checking.
00252 // <srcblock>
00253 // //# Forward Declarations
00254 // template<class T> class Array;
00255 // template<class T> class Vector;
00256 //
00257 // class StokesVector
00258 // {
00259 // public:
00260 //     StokesVector(): I_p(0), Q_p(0), U_p(0), V_p(0) {}
00261 //     StokesVector(double i, double q, double u, double v)
00262 //          : I_p(i), Q_p(q), U_p(u), V_p(v) {}
00263 //     StokesVector(const StokesVector& that): I_p(that.I_p), Q_p(that.Q_p),
00264 //                                             U_p(that.U_p), V_p(that.V_p) {}
00265 //     StokesVector& operator= (const StokesVector& that)
00266 //        { I_p=that.I_p; Q_p=that.Q_p; U_p=that.U_p; V_p=that.V_p;
00267 //          return *this; }
00268 //
00269 //     static String dataTypeId()
00270 //         { return "StokesVector"; }
00271 //
00272 //     // A StokesVector is 1-dim and contains 4 elements.
00273 //     static IPosition shape()
00274 //         { return IPosition (1,4); }
00275 //
00276 //     // Preprocess possible information in the TableRecord.
00277 //     static void* newCopyInfo (const TableRecord& record,
00278 //                               const IPosition& shape)
00279 //         { return new CopyInfo(record, shape); }
00280 //
00281 //     // Delete the object containing preprocessed information.
00282 //     static void* deleteSetDet (void* copyInfo)
00283 //         { delete (CopyInfo*)copyInfo; }
00284 //
00285 //     // Convert a StoredType array to a VirtualType array.
00286 //     // Do this in a CopyInfo function to use its preprocessed information.
00287 //     static void set (void* copyInfo, void* out,
00288 //                      const Array<double>& in, const IPosition& shape)
00289 //         { ((CopyInfo*)copyInfo)->set (out, in, shape); }
00290 //
00291 //     // Convert a VirtualType array to a StoredType array.
00292 //     // Do this in a CopyInfo function to use its preprocessed information.
00293 //     static void get (void* copyInfo, Array<double>& out,
00294 //                      const void* in, const IPosition& shape)
00295 //         { ((CopyInfo*)copyInfo)->get (out, in, shape); }
00296 //
00297 //     // This nested class is used to hold preprocessed information. It
00298 //     // holds a mask extracted from the TableRecord supplied to the engine.
00299 //     // One can imagine that it could also extract a flag telling
00300 //     // whether the stored data is stored as I,Q,U,V or as XX,YY,XY,YX
00301 //     // (although such a conversion would probably be better handled
00302 //     // by a separate virtual column engine).
00303 //     class CopyInfo {
00304 //     public:
00305 //         // The constructor extracts the mask from the record.
00306 //         void CopyInfo (const TableRecord& record)
00307 //             {
00308 //                 RORecordFieldRef<Array<Bool> > field (record, 0);
00309 //                 mask_p = new Vector<Bool>;
00310 //                 *mask_p = *field;
00311 //             }
00312 //         // The set function fills the StokesVector.
00313 //         // It uses the general functions for that purpose.
00314 //         void set (void* vout, const Array<double>& in,
00315 //                   const IPosition& shape)
00316 //             {
00317 //                 Array<StokesVector>& out = *(Array<StokesVector>*)vout;
00318 //                 if (shape.nelements() == 1  &&  shape(0) == 4) {
00319 //                     // All values available, copy in one go.
00320 //                     // This can be done because a StokesVector object
00321 //                     // only contains 4 double values (and no virtual
00322 //                     // function table).
00323 //                     retypedArrayEngineSet (out, in);
00324 //                 }else{
00325 //                     // Only some values available. Fill each
00326 //                     // StokesVector object using the shape and mask.
00327 //                     // The set function below is called for each object.
00328 //                     retypedArrayEngineSet (out, in, shape, (void*)mask_p);
00329 //                 }
00330 //             }
00331 //         // get is the opposite of set.
00332 //         void get (Array<double>& out, const void* vin,
00333 //                   const IPosition& shape)
00334 //             {
00335 //                 const Array<StokesVector>& in =
00336 //                                          *(const Array<StokesVector>*)vin;
00337 //                 if (shape.nelements() == 1  &&  shape(0) == 4) {
00338 //                     retypedArrayEngineGet (out, in);
00339 //                 }else{
00340 //                     retypedArrayEngineGet (out, in, shape, (void*)mask_p);
00341 //                 }
00342 //     private:
00343 //         Vector<Bool>* mask_p;
00344 //     };
00345 //
00346 //     // Set values of StokesVector using the mask.
00347 //     // The shape is not used here.
00348 //     void setElem (const double* data, const IPosition&, const void* maskPtr)
00349 //         {
00350 //              const Vector<Bool>& mask = *(const Vector<Bool>*)maskPtr;
00351 //              I_p = Q_p = U_p = V_p = 0;
00352 //              if (mask(0)) {
00353 //                  I_p = *data++;
00354 //              }
00355 //              if (mask(1)) {
00356 //                  Q_p = *data++;
00357 //              }
00358 //              if (mask(2)) {
00359 //                  U_p = *data++;
00360 //              }
00361 //              if (mask(3)) {
00362 //                  V_p = *data;
00363 //              }
00364 //         }
00365 //     // Get values of StokesVector using the mask (opposite of setElem).
00366 //     void getElem (double* data, const IPosition&, const void* maskPtr);
00367 // private:
00368 //    double I_p, Q_p, U_p, V_p;
00369 // };
00370 //
00371 // main() {
00372 //    // First register the virtual column engine.
00373 //    RetypedArrayEngine<StokesVector,double>::registerClass();
00374 //    // Add ArrayColumnDesc<StokesVector> to column type map.
00375 //    ArrayColumnDesc<StokesVector> tmp(ColumnDesc::registerMap);
00376 //
00377 //    // Build the table description.
00378 //    TableDesc td("", "1", TableDesc::Scratch);
00379 //    td.addColumn (ArrayColumnDesc<double> ("Data"));
00380 //    td.addColumn (ArrayColumnDesc<StokesVector> ("Stokes"));
00381 //
00382 //    // Now create a new table from the description.
00383 //    SetupNewTable newtab("tRetypedArrayEngine_tmp.data", td, Table::New);
00384 //    // Create the virtual column engine with the stored columns Data.
00385 //    RetypedArrayEngine<StokesVector,double> engine ("Stokes", "Data");
00386 //    newtab.bindColumn ("Stokes", engine);
00387 //    Table tab(newtab, 50);
00388 //
00389 //    // Fill the table via the virtual columns.
00390 //    ArrayColumn<StokesVector> stokesColumn (tab, "Stokes");
00391 //    Vector<StokesVector> vec(10);
00392 //    uInt i;
00393 //    for (i=0; i<tab.nrow(); i++) {
00394 //        stokesColumn.put (i, vec);
00395 //    }
00396 // }
00397 // </srcblock>
00398 // <note role=caution>
00399 // Due to instantiation problems with the CFront-based ObjectCenter compiler
00400 // (and probably other CFront-based compilers as well) the Array and
00401 // Vector have to be forward declared. Array.h and Vector.h should
00402 // NOT be included in this StokesVector.h, thus the implementations
00403 // should not be inlined (they are too large anyway), but put in a
00404 // separate .cc file where Array.h and Vector.h can be included.
00405 // </note>
00406 // <p>
00407 // Another compiler problem is that the variable mask_p is not
00408 // automatically converted to a void*, so an explicit cast has to be done.
00409 // </example>
00410 
00411 // <templating arg=VirtualType>
00412 //  <li> default constructor
00413 //  <li> copy constructor
00414 //  <li> assignment operator
00415 //  <li> <src>static String dataTypeId();</src>
00416 //  <li> <src>static IPosition shape();</src>
00417 //  <li> <src>static void* newCopyInfo (const TableRecord& record, const IPosition& virtualElementShape);</src>
00418 //  <li> <src>static void deleteCopyInfo (void* copyInfo);</src>
00419 //  <li> <src>static void set (void* copyInfo, void* out,
00420 //                             const Array<StoredType>& in,
00421 //                             const IPosition& shape);</src>
00422 //  <li> <src>static void get (void* copyInfo, Array<float>& out,
00423 //                             const void* in, const IPosition& shape);</src>
00424 //  <li> <src>void setElem (const StoredType* data, const IPosition& shape,
00425 //                          const void* extraArgument);</src>
00426 //       <br>when global function retypedArrayEngineSet is used.
00427 //  <li> <src>void getElem (StoredType* data, const IPosition& shape,
00428 //                          const void* extraArgument) const;</src>
00429 //       <br>when global function retypedArrayEngineGet is used.
00430 // </templating>
00431 // <templating arg=StoredType>
00432 //  <li> Default constructor
00433 //  <li> Copy constructor
00434 //  <li> Assignment operator
00435 // </templating>
00436 
00437 //# <todo asof="1995/12/29">
00438 //# </todo>
00439 
00440 
00441 template<class VirtualType, class StoredType> class RetypedArrayEngine : public BaseMappedArrayEngine<VirtualType,StoredType>
00442 {
00443   //# Make members of parent class known.
00444 public:
00445   using BaseMappedArrayEngine<VirtualType,StoredType>::virtualName;
00446 protected:
00447   using BaseMappedArrayEngine<VirtualType,StoredType>::storedName;
00448   using BaseMappedArrayEngine<VirtualType,StoredType>::table;
00449   using BaseMappedArrayEngine<VirtualType,StoredType>::roColumn;
00450   using BaseMappedArrayEngine<VirtualType,StoredType>::rwColumn;
00451   using BaseMappedArrayEngine<VirtualType,StoredType>::setNames;
00452 
00453 public:
00454 
00455     // Construct an engine to map a virtual column containing arrays with
00456     // an arbitrary data type to arrays in a stored column.
00457     // StoredColumnName is the name of the column where the converted
00458     // data will be put and must have data type StoredType.
00459     // The virtual column using this engine must have data type VirtualType.
00460     RetypedArrayEngine (const String& virtualColumnName,
00461                         const String& storedColumnName);
00462 
00463     // Construct an engine to map a virtual column containing arrays with
00464     // an arbitrary data type to arrays in a stored column.
00465     // StoredColumnName is the name of the column where the converted
00466     // data will be put and must have data type StoredType.
00467     // The virtual column using this engine must have data type VirtualType.
00468     // The shape and record provided is handed to the newCopyInfo function
00469     // in the VirtualType class. It can be used to determine how an element
00470     // has to be handled when the stored data is incomplete.
00471     RetypedArrayEngine (const String& virtualColumnName,
00472                         const String& storedColumnName,
00473                         const IPosition& virtualElementShape,
00474                         const TableRecord& extraInformation);
00475 
00476     // Construct from a record specification as created by getmanagerSpec().
00477     RetypedArrayEngine (const Record& spec);
00478 
00479     // Destructor is mandatory.
00480     ~RetypedArrayEngine();
00481 
00482     // Return the type name of the engine (i.e. its class name).
00483     virtual String dataManagerType() const;
00484 
00485     // Get the name given to the engine (is the virtual column name).
00486     virtual String dataManagerName() const;
00487   
00488     // Record a record containing data manager specifications.
00489     virtual Record dataManagerSpec() const;
00490 
00491     // Return the name of the class.
00492     // This includes the names of the template arguments.
00493     static String className();
00494 
00495     // Register the class name and the static makeObject "constructor".
00496     // This will make the engine known to the table system.
00497     // The automatically invoked registration function in DataManReg.cc
00498     // contains RetypedArrayEngine<double,Int>.
00499     // Any other instantiation of this class must be registered "manually"
00500     // (or added to DataManReg.cc).
00501     static void registerClass();
00502 
00503 private:
00504     // Copy constructor is only used by clone().
00505     // (so it is made private).
00506     RetypedArrayEngine (const RetypedArrayEngine<VirtualType,StoredType>&);
00507 
00508     // Assignment is not needed and therefore forbidden
00509     // (so it is made private and not implemented).
00510     RetypedArrayEngine<VirtualType,StoredType>& operator=
00511                         (const RetypedArrayEngine<VirtualType,StoredType>&);
00512 
00513     // Clone the engine object.
00514     DataManager* clone() const;
00515 
00516     // Initialize the object for a new table.
00517     // It defines the keywords containing the engine parameters.
00518     void create (uInt initialNrrow);
00519 
00520     // Preparing consists of setting the writable switch and
00521     // adding the initial number of rows in case of create.
00522     // Furthermore it reads the keywords containing the engine parameters
00523     // and allocates a CopyInfo object for the VirtualType.
00524     void prepare();
00525 
00526     // Set the shape of the FixedShape arrays in the column.
00527     // This function only gets called if the column has FixedShape arrays.
00528     // The shape gets saved and used to set the shape of the arrays
00529     // in the stored in case the stored has non-FixedShape arrays.
00530     void setShapeColumn (const IPosition& shape);
00531 
00532     // Define the shape of the array in the given row.
00533     // When the shape of the (underlying) stored array has already been
00534     // defined, it checks whether its latter dimensions match the given
00535     // virtual shape. When matching, nothing will be done.
00536     // When mismatching or when the stored shape has not been defined
00537     // yet, the stored shape will be defined from the virtual shape and
00538     // the virtual element shape.
00539     // E.g. in case of a StokesVector a virtual shape of (512,512)
00540     // results in a stored shape of (4,512,512).
00541     void setShape (uInt rownr, const IPosition& shape);
00542 
00543     // Get the dimensionality of the array in the given row.
00544     uInt ndim (uInt rownr);
00545 
00546     // Get the shape of the array in the given row.
00547     // This is done by stripping the first dimension(s) from the shape
00548     // of the underlying stored array.
00549     IPosition shape (uInt rownr);
00550 
00551     // Check if the shapes of virtual and stored match.
00552     // Determine the shape of the virtual elements in the stored.
00553     IPosition checkShape (const Array<VirtualType>& source,
00554                           const Array<StoredType>& target);
00555 
00556     // Map the virtual shape to the stored shape.
00557     // By default is returns the virtual shape.
00558     virtual IPosition getStoredShape (uInt rownr,
00559                                       const IPosition& virtualShape);
00560 
00561     // Convert the Slicer for a virtual to a Slicer for the stored.
00562     virtual Slicer getStoredSlicer (const Slicer& virtualSlicer) const;
00563 
00564     // Copy the stored array to the virtual array.
00565     // It tries to optimize as much as possible.
00566     virtual void mapOnGet (Array<VirtualType>& array,
00567                            const Array<StoredType>& stored);
00568 
00569     // Copy the virtual array to the stored array.
00570     // It tries to optimize as much as possible.
00571     virtual void mapOnPut (const Array<VirtualType>& array,
00572                            Array<StoredType>& stored);
00573 
00574     //# Now define the data members.
00575     IPosition shape_p;             //# shape of a virtual element in the stored
00576     IPosition virtualFixedShape_p; //# The shape in case virtual has FixedShape
00577     Bool      isVirtualFixedShape_p;
00578     TableRecord  record_p;
00579 //#    VirtualType::CopyInfo* copyInfo_p; //# object used to set/get arrays
00580     void* copyInfo_p;             //# CFront compiler does not accept above
00581 
00582 
00583 public:
00584     //*display 4
00585     // Define the "constructor" to construct this engine when a
00586     // table is read back.
00587     // This "constructor" has to be registered by the user of the engine.
00588     // If the engine is commonly used, its registration can be added
00589     // to the registerAllCtor function in DataManReg.cc. 
00590     // That function gets automatically invoked by the table system.
00591     static DataManager* makeObject (const String& dataManagerType,
00592                                     const Record& spec);
00593 };
00594 
00595 
00596 
00597 } //# NAMESPACE CASA - END
00598 
00599 #ifndef CASACORE_NO_AUTO_TEMPLATES
00600 #include <tables/Tables/RetypedArrayEngine.tcc>
00601 #endif //# CASACORE_NO_AUTO_TEMPLATES
00602 #endif