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$ 00027 00028 #ifndef TABLES_RETYPEDARRAYENGINE_H 00029 #define TABLES_RETYPEDARRAYENGINE_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/tables/DataMan/BaseMappedArrayEngine.h> 00034 #include <casacore/tables/Tables/TableRecord.h> 00035 00036 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00037 00038 //# Forward Declarations 00039 00040 00041 // <summary> 00042 // Virtual column engine to retype and reshape arrays. 00043 // </summary> 00044 00045 // <use visibility=export> 00046 00047 // <reviewed reviewer="Brian Glendenning" date="1995/12/20" tests="dRetypedArrayEngine.cc" demos=dRetypedArrayEngine.h> 00048 // </reviewed> 00049 00050 // <prerequisite> 00051 //# Classes you should understand before using this one. 00052 // <li> <linkto class=BaseMappedArrayEngine>BaseMappedArrayEngine</linkto> 00053 // </prerequisite> 00054 00055 // <synopsis> 00056 // RetypedArrayEngine maps a virtual column containing arrays of objects 00057 // to a stored column containing arrays of data of another type. Usually 00058 // the dimensionality of the arrays get smaller during this mapping process. 00059 // The engine makes it possible to store an array of any type in a table. 00060 // <br> 00061 // For example, a column with 2D arrays of StokesVector's can be mapped to 00062 // a column with 3D arrays of floats (of which the first axes has, say, 00063 // length 4). Another example is mapping a 2D array of StokesMatrix's 00064 // to a 4D array of floats. 00065 // <p> 00066 // The mapping process has to be done by a (static) set and get 00067 // function in the VirtualType class. When a RetypedArrayEngine object is 00068 // constructed, it is possible to pass information in a TableRecord. This 00069 // TableRecord is indirectly passed to the set/get functions. This is done by 00070 // means of the function newCopyInfo, which can preprocess the information 00071 // in the TableRecord and store it in another object. That object is passed to 00072 // the set and get functions. At the end a function deleteCopyInfo is called 00073 // to delete the object. Of course, it is not needed to allocate such 00074 // an object; newCopyInfo can return a null pointer. 00075 // <note role=tip> Because the variables have to be generic and because of 00076 // limitations in the CFront compiler, several variables have to be 00077 // passed as void* and need to be casted in the set/get functions. 00078 // </note> 00079 // 00080 // The virtual column data type class has to contain several functions. 00081 // The example shows how they can be implemented. 00082 // <dl> 00083 // <dt> <src>static String dataTypeId();</src> 00084 // <dd> has to give the (unique) name of the class. 00085 // <dt> <src>static IPosition shape();</src> 00086 // <dd> This has to return the full shape of the elements in the virtual. 00087 // E.g. StokesVector will return [4]. StokesMatrix will return [4,4]. 00088 // <dt> <src>static void* newCopyInfo (const TableRecord& record, 00089 // const IPosition& virtualElementShape);</src> 00090 // <dd> This function has to setup the set/get functions by preprocessing the 00091 // information contained in the TableRecord and storing it in a so-called 00092 // "copyInfo" object. A pointer to that object has to be returned, which 00093 // is kept by the engine and passed to the set/get functions. 00094 // The "copyInfo" class can be a nested class in the VirtualType 00095 // (as shown in the StokesVector example), but it can also 00096 // be an independent class. 00097 // <br> 00098 // The supplied TableRecord is the TableRecord given when 00099 // constructing the engine. 00100 // When no TableRecord was given, it will be empty. 00101 // The supplied shape is the shape of a virtual element as given to 00102 // the constructor of the engine. This can be a full or partial shape. 00103 // E.g. for a StokesVector it will usually be [4], but it can also, 00104 // say, [1] if only U is used. 00105 // The function could check if the information in the TableRecord 00106 // and the shape match. 00107 // <br> 00108 // Of course, a VirtualType may not need any extra information. 00109 // Therefore it is possible to return a null "copyInfo" pointer. 00110 // <dt> <src>static void deleteCopyInfo (void* copyInfo);</src> 00111 // <dd> This function has to delete the "copyInfo" object allocated 00112 // by newCopyInfo. To do so, it needs to cast the pointer to the 00113 // correct type. 00114 // <dt> <src>static void set (void* copyInfo, void* out, 00115 // const Array<StoredType>& in, 00116 // const IPosition& virtualElementShape);</src> 00117 // <dd> This function is called when an <src>Array<VirtualType></src> is read. 00118 // It has to convert the StoredType array to the VirtualType array. 00119 // In principle, there are two different cases (which can be deduced 00120 // from the given shape): 00121 // <ol> 00122 // <li> The stored information is complete. For example: suppose the 00123 // VirtualType is a StokesVector object (containing I, Q, U and V), 00124 // When the stored array contains 4 values per StokesVector, 00125 // it is complete. 00126 // <br> 00127 // In this case the entire virtual array can be directly copied from 00128 // the stored array when the VirtualType object contains no 00129 // virtual functions and the data are directly contained in it. 00130 // The function 00131 // <br> 00132 // <linkto group=RetypedArraySetGet.h#RetypedArrayEngineSetGet> 00133 // <src> 00134 // retypedArrayEngineSet (Array<VirtualType>& out, 00135 // const Array<StoredType>& in); 00136 // </src></linkto><br> 00137 // can be used for this purpose. 00138 // <li> When in the example above the stored array contains less 00139 // than 4 values per StokesVector, the stored information 00140 // is incomplete. In this case the set function has to 00141 // fill the data in one way or another. The information 00142 // in the "copyInfo" object can assist in it. 00143 // <br> 00144 // Each VirtualType element has to be set individually, so 00145 // a loop through the array is required. To assist in this, 00146 // the loop has been implemented in the function 00147 // <br> 00148 // <linkto group=RetypedArraySetGet.h#RetypedArrayEngineSetGet> 00149 // <src> 00150 // retypedArrayEngineSet (Array<VirtualType>& out, 00151 // const Array<StoredType>& in, 00152 // const void* extraArgument); 00153 // </src></linkto> 00154 // <br> It calls the VirtualType function 00155 // <srcblock> 00156 // void setElem (const StoredType* data, const IPosition& shape, 00157 // const void* extraArgument); 00158 // </srcblock> 00159 // for each VirtualType element. This set function has to 00160 // fill the VirtualType object from the data. It can use the 00161 // shape and the extraArgument to know how it should do it. 00162 // <br> 00163 // Note that the 3-argument function retypedArrayEngineSet is 00164 // only a convenience function. For optimal performance it may 00165 // be needed to handcode the loop instead of using this function. 00166 // </ol> 00167 // <note role=warning> Note that the given virtual element shape does 00168 // not need to match the shape given to the constructor of the engine. 00169 // It is possible that the user sets the shape of the stored array 00170 // before putting the virtual array. In that case the system uses the 00171 // relevant part of the stored array shape as the virtual element shape. 00172 // </note> 00173 // <note role=tip> If the out argument is declared (as it should be) as 00174 // <src>Array<VirtualType>& out</src>, 00175 // the CFront compiler complains about unknown size of 00176 // VirtualType when instantiating Array<VirtualType>. 00177 // Therefore it has to be declared as void* and the set function 00178 // needs to cast it to <src>Array<VirtualType>*</src>. 00179 // </note> 00180 // <dt> <src>static void get (void* copyInfo, Array<float>& out, 00181 // const void* in, 00182 // const IPosition& virtualElementShape);</src> 00183 // <dd> This function is similar to the set function described above, but 00184 // is called when an <src>Array<VirtualType></src> is written. 00185 // It has to convert the VirtualType array to the StoredType array. 00186 // </dl> 00187 // 00188 // <br>E.g.: A StokesVector has 4 float elements. 00189 // <srcblock> 00190 // // Construct the column object for the Stokes column. 00191 // ArrayColumn<StokesVector> stokesColumn (table, "StokesVirtualColumn"); 00192 // // Put an array of StokesVector's with shape 512,512. 00193 // // This will implicitly set the shape of the underlying 00194 // // data column to 4,512,512. 00195 // // This put is very quick (it can copy all data in one go). 00196 // Array<StokesVector> stokesData (IPosition(2,512,512)); 00197 // stokesColumn.put (rownr, stokesData); 00198 // 00199 // // Get the column object for the Data column. 00200 // // Set its shape explicitly to 1,512,512, 00201 // ArrayColumn<float> dataColumn (table, "DataColumn"); 00202 // dataColumn.setShape (rownr, IPosition(3,1,512,512)); 00203 // // Now a put of the data results in calling the StokesVector::getElem 00204 // // function for each element with an IPosition(1,1); i.e. the 00205 // // data array needs only one value for each StokesVector. 00206 // stokesColumn.put (rownr, stokesData); 00207 // </srcblock> 00208 // 00209 // When reading a table back, the engine has to be registered. 00210 // Otherwise it will be unknown to the table system. 00211 // Similarly, the appropriate ArrayColumnDesc object has to be registered. 00212 // This can be done as follows: 00213 // <pre> 00214 // RetypedArrayEngine<StokesVector,float>::registerClass(); 00215 // ArrayColumnDesc<StokesVector> tmp(ColumnDesc::registerMap); 00216 // </pre> 00217 // When they are not registered, the open of the table will fail 00218 // telling which class could not be found. 00219 // </synopsis> 00220 00221 // <motivation> 00222 // This class allows one to store arrays of arbitrary objects in a table. 00223 // It also allows it to be done it in a very efficient way. 00224 // <p> 00225 // The class had to be doubly templated. There were 2 reasons: 00226 // <ol> 00227 // <li> The typedef trick described on page 321 in Barton/Nackman 00228 // did not work with the CFront-based ObjectCenter compiler. 00229 // <li> It was needed to allow derivation from BaseMappedArrayEngine. 00230 // </ol> 00231 // <p> 00232 // Originally it was the idea to have a mandatory nested CopyInfo class in the 00233 // VirtualType class and use syntax like VirtualType::CopyInfo to access 00234 // functions in it and to keep a pointer to such an object. Alas, the 00235 // CFront compiler could not handle this. 00236 // <p> 00237 // Because the engine can serve only one column, it was possible to 00238 // combine the engine and the column functionality in one class. 00239 // This has been achieved using multiple inheritance. 00240 // The advantage of this is that only one templated class is used, 00241 // so fewer template instantiations are needed. 00242 // </motivation> 00243 00244 // <example> 00245 // The following example shows how a StokesVector could be implemented. 00246 // It doesn't check whether the mask is correct. 00247 // Two more examples are contained in the demo/test program 00248 // <a href="../../../../code/aips/implement/Tables/test/dRetypedArrayEngine.h"> 00249 // dRetypedArrayEngine.h</a> and its 00250 // <a href="../../../../code/aips/implement/Tables/test/dRetypedArrayEngine.cc"> 00251 // .cc file</a>. Their second example (class RetypedArrayEx2) is similar to 00252 // the StokesVector example below, but contains more extensive checking. 00253 // <srcblock> 00254 // //# Forward Declarations 00255 // template<class T> class Array; 00256 // template<class T> class Vector; 00257 // 00258 // class StokesVector 00259 // { 00260 // public: 00261 // StokesVector(): I_p(0), Q_p(0), U_p(0), V_p(0) {} 00262 // StokesVector(double i, double q, double u, double v) 00263 // : I_p(i), Q_p(q), U_p(u), V_p(v) {} 00264 // StokesVector(const StokesVector& that): I_p(that.I_p), Q_p(that.Q_p), 00265 // U_p(that.U_p), V_p(that.V_p) {} 00266 // StokesVector& operator= (const StokesVector& that) 00267 // { I_p=that.I_p; Q_p=that.Q_p; U_p=that.U_p; V_p=that.V_p; 00268 // return *this; } 00269 // 00270 // static String dataTypeId() 00271 // { return "StokesVector"; } 00272 // 00273 // // A StokesVector is 1-dim and contains 4 elements. 00274 // static IPosition shape() 00275 // { return IPosition (1,4); } 00276 // 00277 // // Preprocess possible information in the TableRecord. 00278 // static void* newCopyInfo (const TableRecord& record, 00279 // const IPosition& shape) 00280 // { return new CopyInfo(record, shape); } 00281 // 00282 // // Delete the object containing preprocessed information. 00283 // static void* deleteSetDet (void* copyInfo) 00284 // { delete (CopyInfo*)copyInfo; } 00285 // 00286 // // Convert a StoredType array to a VirtualType array. 00287 // // Do this in a CopyInfo function to use its preprocessed information. 00288 // static void set (void* copyInfo, void* out, 00289 // const Array<double>& in, const IPosition& shape) 00290 // { ((CopyInfo*)copyInfo)->set (out, in, shape); } 00291 // 00292 // // Convert a VirtualType array to a StoredType array. 00293 // // Do this in a CopyInfo function to use its preprocessed information. 00294 // static void get (void* copyInfo, Array<double>& out, 00295 // const void* in, const IPosition& shape) 00296 // { ((CopyInfo*)copyInfo)->get (out, in, shape); } 00297 // 00298 // // This nested class is used to hold preprocessed information. It 00299 // // holds a mask extracted from the TableRecord supplied to the engine. 00300 // // One can imagine that it could also extract a flag telling 00301 // // whether the stored data is stored as I,Q,U,V or as XX,YY,XY,YX 00302 // // (although such a conversion would probably be better handled 00303 // // by a separate virtual column engine). 00304 // class CopyInfo { 00305 // public: 00306 // // The constructor extracts the mask from the record. 00307 // void CopyInfo (const TableRecord& record) 00308 // { 00309 // RORecordFieldRef<Array<Bool> > field (record, 0); 00310 // mask_p = new Vector<Bool>; 00311 // *mask_p = *field; 00312 // } 00313 // // The set function fills the StokesVector. 00314 // // It uses the general functions for that purpose. 00315 // void set (void* vout, const Array<double>& in, 00316 // const IPosition& shape) 00317 // { 00318 // Array<StokesVector>& out = *(Array<StokesVector>*)vout; 00319 // if (shape.nelements() == 1 && shape(0) == 4) { 00320 // // All values available, copy in one go. 00321 // // This can be done because a StokesVector object 00322 // // only contains 4 double values (and no virtual 00323 // // function table). 00324 // retypedArrayEngineSet (out, in); 00325 // }else{ 00326 // // Only some values available. Fill each 00327 // // StokesVector object using the shape and mask. 00328 // // The set function below is called for each object. 00329 // retypedArrayEngineSet (out, in, shape, (void*)mask_p); 00330 // } 00331 // } 00332 // // get is the opposite of set. 00333 // void get (Array<double>& out, const void* vin, 00334 // const IPosition& shape) 00335 // { 00336 // const Array<StokesVector>& in = 00337 // *(const Array<StokesVector>*)vin; 00338 // if (shape.nelements() == 1 && shape(0) == 4) { 00339 // retypedArrayEngineGet (out, in); 00340 // }else{ 00341 // retypedArrayEngineGet (out, in, shape, (void*)mask_p); 00342 // } 00343 // private: 00344 // Vector<Bool>* mask_p; 00345 // }; 00346 // 00347 // // Set values of StokesVector using the mask. 00348 // // The shape is not used here. 00349 // void setElem (const double* data, const IPosition&, const void* maskPtr) 00350 // { 00351 // const Vector<Bool>& mask = *(const Vector<Bool>*)maskPtr; 00352 // I_p = Q_p = U_p = V_p = 0; 00353 // if (mask(0)) { 00354 // I_p = *data++; 00355 // } 00356 // if (mask(1)) { 00357 // Q_p = *data++; 00358 // } 00359 // if (mask(2)) { 00360 // U_p = *data++; 00361 // } 00362 // if (mask(3)) { 00363 // V_p = *data; 00364 // } 00365 // } 00366 // // Get values of StokesVector using the mask (opposite of setElem). 00367 // void getElem (double* data, const IPosition&, const void* maskPtr); 00368 // private: 00369 // double I_p, Q_p, U_p, V_p; 00370 // }; 00371 // 00372 // main() { 00373 // // First register the virtual column engine. 00374 // RetypedArrayEngine<StokesVector,double>::registerClass(); 00375 // // Add ArrayColumnDesc<StokesVector> to column type map. 00376 // ArrayColumnDesc<StokesVector> tmp(ColumnDesc::registerMap); 00377 // 00378 // // Build the table description. 00379 // TableDesc td("", "1", TableDesc::Scratch); 00380 // td.addColumn (ArrayColumnDesc<double> ("Data")); 00381 // td.addColumn (ArrayColumnDesc<StokesVector> ("Stokes")); 00382 // 00383 // // Now create a new table from the description. 00384 // SetupNewTable newtab("tRetypedArrayEngine_tmp.data", td, Table::New); 00385 // // Create the virtual column engine with the stored columns Data. 00386 // RetypedArrayEngine<StokesVector,double> engine ("Stokes", "Data"); 00387 // newtab.bindColumn ("Stokes", engine); 00388 // Table tab(newtab, 50); 00389 // 00390 // // Fill the table via the virtual columns. 00391 // ArrayColumn<StokesVector> stokesColumn (tab, "Stokes"); 00392 // Vector<StokesVector> vec(10); 00393 // uInt i; 00394 // for (i=0; i<tab.nrow(); i++) { 00395 // stokesColumn.put (i, vec); 00396 // } 00397 // } 00398 // </srcblock> 00399 // <note role=caution> 00400 // Due to instantiation problems with the CFront-based ObjectCenter compiler 00401 // (and probably other CFront-based compilers as well) the Array and 00402 // Vector have to be forward declared. Array.h and Vector.h should 00403 // NOT be included in this StokesVector.h, thus the implementations 00404 // should not be inlined (they are too large anyway), but put in a 00405 // separate .cc file where Array.h and Vector.h can be included. 00406 // </note> 00407 // <p> 00408 // Another compiler problem is that the variable mask_p is not 00409 // automatically converted to a void*, so an explicit cast has to be done. 00410 // </example> 00411 00412 // <templating arg=VirtualType> 00413 // <li> default constructor 00414 // <li> copy constructor 00415 // <li> assignment operator 00416 // <li> <src>static String dataTypeId();</src> 00417 // <li> <src>static IPosition shape();</src> 00418 // <li> <src>static void* newCopyInfo (const TableRecord& record, const IPosition& virtualElementShape);</src> 00419 // <li> <src>static void deleteCopyInfo (void* copyInfo);</src> 00420 // <li> <src>static void set (void* copyInfo, void* out, 00421 // const Array<StoredType>& in, 00422 // const IPosition& shape);</src> 00423 // <li> <src>static void get (void* copyInfo, Array<float>& out, 00424 // const void* in, const IPosition& shape);</src> 00425 // <li> <src>void setElem (const StoredType* data, const IPosition& shape, 00426 // const void* extraArgument);</src> 00427 // <br>when global function retypedArrayEngineSet is used. 00428 // <li> <src>void getElem (StoredType* data, const IPosition& shape, 00429 // const void* extraArgument) const;</src> 00430 // <br>when global function retypedArrayEngineGet is used. 00431 // </templating> 00432 // <templating arg=StoredType> 00433 // <li> Default constructor 00434 // <li> Copy constructor 00435 // <li> Assignment operator 00436 // </templating> 00437 00438 //# <todo asof="1995/12/29"> 00439 //# </todo> 00440 00441 00442 template<class VirtualType, class StoredType> class RetypedArrayEngine : public BaseMappedArrayEngine<VirtualType,StoredType> 00443 { 00444 //# Make members of parent class known. 00445 public: 00446 using BaseMappedArrayEngine<VirtualType,StoredType>::virtualName; 00447 protected: 00448 using BaseMappedArrayEngine<VirtualType,StoredType>::storedName; 00449 using BaseMappedArrayEngine<VirtualType,StoredType>::table; 00450 using BaseMappedArrayEngine<VirtualType,StoredType>::column; 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 CASACORE - END 00598 00599 #ifndef CASACORE_NO_AUTO_TEMPLATES 00600 #include <casacore/tables/DataMan/RetypedArrayEngine.tcc> 00601 #endif //# CASACORE_NO_AUTO_TEMPLATES 00602 #endif