casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ScaledComplexData.h
Go to the documentation of this file.
00001 //# ScaledComplexData.h: Templated virtual column engine to scale a complex table array
00002 //# Copyright (C) 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: ScaledComplexData.h 21298 2012-12-07 14:53:03Z gervandiepen $
00027 
00028 #ifndef TABLES_SCALEDCOMPLEXDATA_H
00029 #define TABLES_SCALEDCOMPLEXDATA_H
00030 
00031 
00032 //# Includes
00033 #include <tables/Tables/BaseMappedArrayEngine.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 //# Forward Declarations
00038 template<class T> class ScalarColumn;
00039 
00040 
00041 // <summary>
00042 // Templated virtual column engine to scale a complex table array
00043 // </summary>
00044 
00045 // <use visibility=export>
00046 
00047 // <reviewed reviewer="Gareth Hunt" date="94Nov17" tests="">
00048 // </reviewed>
00049 
00050 // <prerequisite>
00051 //# Classes you should understand before using this one.
00052 //   <li> VirtualColumnEngine
00053 //   <li> VirtualArrayColumn
00054 // </prerequisite>
00055 
00056 // <synopsis> 
00057 // ScaledComplexData is a virtual column engine which scales an array
00058 // of a complex type to 2 values of another type (to save disk storage).
00059 // For example, <src>ScaledComplexData<Complex,Short></src> resembles the
00060 // classic AIPS compress method which scales the data from float to short.
00061 // The (complex) scale factor and offset value can be given in two ways:
00062 // <ul>
00063 //  <li> As a fixed value which is used for all arrays in the column.
00064 //  <li> As the name of a column. In this way each array in a
00065 //         column can have its own scale and offset value.
00066 //         The scale and offset value in a row must be put before
00067 //         the array is put and should not be changed anymore.
00068 // </ul>
00069 // It is also possible to have a variable scale factor with a fixed offset
00070 // value.
00071 // As in FITS the scale and offset values are used as:
00072 // <br><src> True_value = Stored_value * scale + offset; </src>
00073 //
00074 // An engine object should be used for one column only, because the stored
00075 // column name is part of the engine. If it would be used for more than
00076 // one column, they would all share the same stored column.
00077 // When the engine is bound to a column, it is checked if the name
00078 // of that column matches the given virtual column name.
00079 //
00080 // The engine can be used for a column containing any kind of array
00081 // (thus direct or indirect, fixed or variable shaped)) as long as the
00082 // virtual array can be stored in the stored array. Thus a fixed shaped
00083 // virtual can use a variable shaped stored, but not vice versa.
00084 // A fixed shape indirect virtual can use a stored with direct arrays.
00085 //
00086 // This class can also serve as an example of how to implement
00087 // a virtual column engine.
00088 // </synopsis> 
00089 
00090 // <motivation>
00091 // This class allows to store data in a smaller representation.
00092 // It is needed to resemble the classic AIPS compress option.
00093 // It adds the scale and offset value on a per row basis.
00094 //
00095 // Because the engine can serve only one column, it was possible to
00096 // combine the engine and the column functionality in one class.
00097 // This has been achieved using multiple inheritance.
00098 // The advantage of this is that only one templated class is used,
00099 // so less template instantiations are needed.
00100 //
00101 // Class ScaledArrayEngine could not be used, because complex integer
00102 // types are not supported in the tabe system.
00103 // </motivation>
00104 
00105 // <example>
00106 // <srcblock>
00107 // // Create the table description and 2 columns with indirect arrays in it.
00108 // // The Int column will be stored, while the double will be
00109 // // used as virtual.
00110 // TableDesc tableDesc ("", TableDesc::Scratch);
00111 // tableDesc.addColumn (ArrayColumnDesc<Short> ("storedArray"));
00112 // tableDesc.addColumn (ArrayColumnDesc<Complex> ("virtualArray"));
00113 //
00114 // // Create a new table using the table description.
00115 // SetupNewTable newtab (tableDesc, "tab.data", Table::New);
00116 //
00117 // // Create the array scaling engine to scale from double to Int
00118 // // and bind it to the double column.
00119 // // Create the table.
00120 // ScaledComplexData<Complex,Short> scalingEngine("virtualArray",
00121 //                                                "storedArray", 10);
00122 // newtab.bindColumn ("virtualArray", scalingEngine);
00123 // Table table (newtab);
00124 //
00125 // // Store a 2-D array (with dim. 3,4) into each row of the column.
00126 // // The shape of each array in the column is implicitly set by the put
00127 // // function. This will also set the shape of the underlying Int array
00128 // // (as a 3-D array with shape 2,3,4).
00129 // ArrayColumn data (table, "virtualArray");
00130 // Array<DComplex> someArray(IPosition(2,3,4));
00131 // someArray = 0;
00132 // for (uInt i=0, i<10; i++) {          // table will have 10 rows
00133 //     table.addRow();
00134 //     data.put (i, someArray)
00135 // }
00136 // </srcblock>
00137 // </example>
00138 
00139 // <templating arg=VirtualType>
00140 //  <li> only complex data types
00141 // </templating>
00142 // <templating arg=StoredType>
00143 //  <li> only built-in numerics data types
00144 // </templating>
00145 
00146 template<class VirtualType, class StoredType>
00147 class ScaledComplexData : public BaseMappedArrayEngine<VirtualType, StoredType>
00148 {
00149   //# Make members of parent class known.
00150 public:
00151   using BaseMappedArrayEngine<VirtualType,StoredType>::virtualName;
00152 protected:
00153   using BaseMappedArrayEngine<VirtualType,StoredType>::storedName;
00154   using BaseMappedArrayEngine<VirtualType,StoredType>::table;
00155   using BaseMappedArrayEngine<VirtualType,StoredType>::roColumn;
00156   using BaseMappedArrayEngine<VirtualType,StoredType>::rwColumn;
00157   using BaseMappedArrayEngine<VirtualType,StoredType>::setNames;
00158 
00159 public:
00160     // Construct an engine to scale all arrays in a column with
00161     // the given offset and scale factor.
00162     // StoredColumnName is the name of the column where the scaled
00163     // data will be put and must have data type StoredType.
00164     // The virtual column using this engine must have data type VirtualType.
00165     ScaledComplexData (const String& virtualColumnName,
00166                        const String& storedColumnName,
00167                        VirtualType scale,
00168                        VirtualType offset = 0);
00169 
00170     // Construct an engine to scale the arrays in a column.
00171     // The scale and offset values are taken from a column with
00172     // the given names. In that way each array has its own scale factor
00173     // and offset value.
00174     // An exception is thrown if these columns do not exist.
00175     // VirtualColumnName is the name of the virtual column and is used to
00176     // check if the engine gets bound to the correct column.
00177     // StoredColumnName is the name of the column where the scaled
00178     // data will be put and must have data type StoredType.
00179     // The virtual column using this engine must have data type VirtualType.
00180     // <group>
00181     ScaledComplexData (const String& virtualColumnName,
00182                        const String& storedColumnName,
00183                        const String& scaleColumnName,
00184                        VirtualType offset = 0);
00185     ScaledComplexData (const String& virtualColumnName,
00186                        const String& storedColumnName,
00187                        const String& scaleColumnName,
00188                        const String& offsetColumnName);
00189     // </group>
00190 
00191     // Construct from a record specification as created by getmanagerSpec().
00192     ScaledComplexData (const Record& spec);
00193 
00194     // Destructor is mandatory.
00195     ~ScaledComplexData();
00196 
00197     // Return the type name of the engine (i.e. its class name).
00198     String dataManagerType() const;
00199 
00200     // Record a record containing data manager specifications.
00201     virtual Record dataManagerSpec() const;
00202 
00203     // Return the name of the class.
00204     // This includes the names of the template arguments.
00205     static String className();
00206 
00207     // The engine can access column cells.
00208     virtual Bool canAccessArrayColumnCells (Bool& reask) const;
00209 
00210     // Register the class name and the static makeObject "constructor".
00211     // This will make the engine known to the table system.
00212     // The automatically invoked registration function in DataManReg.cc
00213     // contains ScaledComplexData<double,Int>.
00214     // Any other instantiation of this class must be registered "manually"
00215     // (or added to DataManReg.cc).
00216     static void registerClass();
00217 
00218 private:
00219     // The default constructor is required for reconstruction of the
00220     // engine when a table is read back.
00221     ScaledComplexData();
00222 
00223     // Copy constructor is only used by clone().
00224     // (so it is made private).
00225     ScaledComplexData (const ScaledComplexData<VirtualType,StoredType>&);
00226 
00227     // Assignment is not needed and therefore forbidden
00228     // (so it is made private and not implemented).
00229     ScaledComplexData<VirtualType,StoredType>& operator=
00230                            (const ScaledComplexData<VirtualType,StoredType>&);
00231 
00232     // Clone the engine object.
00233     virtual DataManager* clone() const;
00234 
00235     // Initialize the object for a new table.
00236     // It defines the keywords containing the engine parameters.
00237     virtual void create (uInt initialNrrow);
00238 
00239     // Preparing consists of setting the writable switch and
00240     // adding the initial number of rows in case of create.
00241     // Furthermore it reads the keywords containing the engine parameters.
00242     virtual void prepare();
00243 
00244     // Set the shape of the FixedShape arrays in the column.
00245     // This function only gets called if the column has FixedShape arrays.
00246     // The shape gets saved and used to set the shape of the arrays
00247     // in the stored in case the stored has non-FixedShape arrays.
00248     virtual void setShapeColumn (const IPosition& shape);
00249 
00250     // Define the shape of the array in the given row.
00251     // When the shape of the (underlying) stored array has already been
00252     // defined, it checks whether its latter dimensions match the given
00253     // virtual shape. When matching, nothing will be done.
00254     // When mismatching or when the stored shape has not been defined
00255     // yet, the stored shape will be defined from the virtual shape and
00256     // the virtual element shape.
00257     // E.g. in case of a StokesVector a virtual shape of (512,512)
00258     // results in a stored shape of (4,512,512).
00259     virtual void setShape (uInt rownr, const IPosition& shape);
00260 
00261     // Get the dimensionality of the array in the given row.
00262     virtual uInt ndim (uInt rownr);
00263 
00264     // Get the shape of the array in the given row.
00265     // This is done by stripping the first dimension from the shape
00266     // of the underlying stored array.
00267     virtual IPosition shape (uInt rownr);
00268 
00269     // Get an array in the given row.
00270     // This will scale and offset from the underlying array.
00271     virtual void getArray (uInt rownr, Array<VirtualType>& array);
00272 
00273     // Put an array in the given row.
00274     // This will scale and offset to the underlying array.
00275     virtual void putArray (uInt rownr, const Array<VirtualType>& array);
00276 
00277     // Get a section of the array in the given row.
00278     // This will scale and offset from the underlying array.
00279     virtual void getSlice (uInt rownr, const Slicer& slicer,
00280                            Array<VirtualType>& array);
00281 
00282     // Put into a section of the array in the given row.
00283     // This will scale and offset to the underlying array.
00284     virtual void putSlice (uInt rownr, const Slicer& slicer,
00285                            const Array<VirtualType>& array);
00286 
00287     // Get an entire column.
00288     // This will scale and offset from the underlying array.
00289     virtual void getArrayColumn (Array<VirtualType>& array);
00290 
00291     // Put an entire column.
00292     // This will scale and offset to the underlying array.
00293     virtual void putArrayColumn (const Array<VirtualType>& array);
00294 
00295     // Get some array values in the column.
00296     // This will scale and offset from the underlying array.
00297     virtual void getArrayColumnCells (const RefRows& rownrs,
00298                                       Array<VirtualType>& data);
00299 
00300     // Put some array values in the column.
00301     // This will scale and offset to the underlying array.
00302     virtual void putArrayColumnCells (const RefRows& rownrs,
00303                                       const Array<VirtualType>& data);
00304 
00305     // Get a section of all arrays in the column.
00306     // This will scale and offset from the underlying array.
00307     virtual void getColumnSlice (const Slicer& slicer,
00308                                  Array<VirtualType>& array);
00309 
00310     // Put a section of all arrays in the column.
00311     // This will scale and offset to the underlying array.
00312     virtual void putColumnSlice (const Slicer& slicer,
00313                                  const Array<VirtualType>& array);
00314 
00315     // Get a section of some arrays in the column.
00316     // This will scale and offset from the underlying array.
00317     virtual void getColumnSliceCells (const RefRows& rownrs,
00318                                       const Slicer& slicer,
00319                                       Array<VirtualType>& data);
00320 
00321     // Put into a section of some arrays in the column.
00322     // This will scale and offset to the underlying array.
00323     virtual void putColumnSliceCells (const RefRows& rownrs,
00324                                       const Slicer& slicer,
00325                                       const Array<VirtualType>& data);
00326 
00327     // Scale and/or offset stored to array.
00328     // This is meant when reading an array from the stored column.
00329     // It optimizes for scale=1 and/or offset=0.
00330     void scaleOnGet (VirtualType scale, VirtualType offset,
00331                      Array<VirtualType>& array,
00332                      const Array<StoredType>& stored);
00333 
00334     // Scale and/or offset array to stored.
00335     // This is meant when writing an array into the stored column.
00336     // It optimizes for scale=1 and/or offset=0.
00337     void scaleOnPut (VirtualType scale, VirtualType offset,
00338                      const Array<VirtualType>& array,
00339                      Array<StoredType>& stored);
00340 
00341     // Scale and/or offset stored to array for the entire column.
00342     // When the scale and offset are fixed, it will do the entire array.
00343     // Otherwise it iterates through the array and applies the scale
00344     // and offset per row.
00345     void scaleColumnOnGet (Array<VirtualType>& array,
00346                            const Array<StoredType>& stored);
00347 
00348     // Scale and/or offset array to stored for the entire column.
00349     // When the scale and offset are fixed, it will do the entire array.
00350     // Otherwise it iterates through the array and applies the scale
00351     // and offset per row.
00352     void scaleColumnOnPut (const Array<VirtualType>& array,
00353                            Array<StoredType>& stored);
00354 
00355     // Scale and/or offset stored to array for some cells in the column.
00356     // When the scale and offset are fixed, it will do the entire array.
00357     // Otherwise it iterates through the array and applies the scale
00358     // and offset per row.
00359     void scaleCellsOnGet (Array<VirtualType>& array,
00360                           const Array<StoredType>& stored,
00361                           const RefRows& rownrs);
00362 
00363     // Scale and/or offset array to stored for some cells in the column.
00364     // When the scale and offset are fixed, it will do the entire array.
00365     // Otherwise it iterates through the array and applies the scale
00366     // and offset per row.
00367     void scaleCellsOnPut (const Array<VirtualType>& array,
00368                           Array<StoredType>& stored,
00369                           const RefRows& rownrs);
00370 
00371     // Determine the shape of an array in the stored column.
00372     IPosition storedShape (const IPosition& virtualShape) const
00373       { return IPosition(1,2).concatenate (virtualShape); }
00374 
00375     // Convert the Slicer for a virtual to a Slicer for the stored.
00376     Slicer storedSlicer (const Slicer& virtualSlicer) const;
00377 
00378     //# Now define the data members.
00379     String         scaleName_p;          //# name of scale column
00380     String         offsetName_p;         //# name of offset column
00381     VirtualType    scale_p;              //# scale factor
00382     VirtualType    offset_p;             //# offset value
00383     Bool           fixedScale_p;         //# scale is a fixed column
00384     Bool           fixedOffset_p;        //# offset is a fixed column
00385     ScalarColumn<VirtualType>* scaleColumn_p;  //# column with scale value
00386     ScalarColumn<VirtualType>* offsetColumn_p; //# column with offset value
00387 
00388     // Get the scale value for this row.
00389     VirtualType getScale (uInt rownr);
00390 
00391     // Get the offset value for this row.
00392     VirtualType getOffset (uInt rownr);
00393 
00394 public:
00395     // Define the "constructor" to construct this engine when a
00396     // table is read back.
00397     // This "constructor" has to be registered by the user of the engine.
00398     // If the engine is commonly used, its registration can be added
00399     // to the registerAllCtor function in DataManReg.cc. 
00400     // That function gets automatically invoked by the table system.
00401     static DataManager* makeObject (const String& dataManagerType,
00402                                     const Record& spec);
00403 };
00404 
00405 
00406 
00407 } //# NAMESPACE CASA - END
00408 
00409 #ifndef CASACORE_NO_AUTO_TEMPLATES
00410 #include <tables/Tables/ScaledComplexData.tcc>
00411 #endif //# CASACORE_NO_AUTO_TEMPLATES
00412 #endif