CompressFloat.h

Go to the documentation of this file.
00001 //# CompressFloat.h: Virtual column engine to scale a table float array
00002 //# Copyright (C) 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$
00027 
00028 #ifndef TABLES_COMPRESSFLOAT_H
00029 #define TABLES_COMPRESSFLOAT_H
00030 
00031 //# Includes
00032 #include <casacore/casa/aips.h>
00033 #include <casacore/tables/DataMan/BaseMappedArrayEngine.h>
00034 #include <casacore/tables/Tables/ScalarColumn.h>
00035 #include <casacore/casa/Arrays/Array.h>
00036 
00037 
00038 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00039 
00040 // <summary>
00041 // Virtual column engine to scale a table float array
00042 // </summary>
00043 
00044 // <use visibility=export>
00045 
00046 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tCompressFloat.cc">
00047 // </reviewed>
00048 
00049 // <prerequisite>
00050 //# Classes you should understand before using this one.
00051 //   <li> VirtualColumnEngine
00052 //   <li> VirtualArrayColumn
00053 // </prerequisite>
00054 
00055 // <synopsis> 
00056 // CompressFloat is a virtual column engine which scales an array
00057 // of one type to another type to save disk storage.
00058 // This resembles the classic AIPS compress method which scales the
00059 // data from float to short.
00060 // The scale factor and offset values can be given in two ways:
00061 // <ul>
00062 //  <li> As a fixed values which is used for all arrays in the column.
00063 //       These values have to be given when constructing of the engine.
00064 //  <li> As the name of a column. In this way each array in the
00065 //         column has its own scale and offset value.
00066 //         By default it uses auto-scaling (see below).
00067 //         Otherwise the scale and offset value in a row must be put
00068 //         before the array is put and should not be changed anymore.
00069 // </ul>
00070 // Auto-scaling means that the engine will determine the scale
00071 // and offset value itself when an array (or a slice) is put.
00072 // It does it by mapping the values in the array to the range [-32767,32767].
00073 // At each put the scale/offset values are changed as needed.
00074 // Note that with auto-scaling <src>putSlice</src> can be somewhat
00075 // slower, because the entire array might need to be rescaled.
00076 //
00077 // As in FITS the scale and offset values are used as:
00078 // <br><src> True_value = Stored_value * scale + offset; </src>
00079 //
00080 // An engine object should be used for one column only, because the stored
00081 // column name is part of the engine. If it would be used for more than
00082 // one column, they would all share the same stored column.
00083 // When the engine is bound to a column, it is checked if the name
00084 // of that column matches the given virtual column name.
00085 //
00086 // The engine can be used for a column containing any kind of array
00087 // (thus direct or indirect, fixed or variable shaped)) as long as the
00088 // virtual array can be stored in the stored array. Thus a fixed shaped
00089 // virtual can use a variable shaped stored, but not vice versa.
00090 // A fixed shape indirect virtual can use a stored with direct arrays.
00091 //
00092 // This class can also serve as an example of how to implement
00093 // a virtual column engine.
00094 // </synopsis> 
00095 
00096 // <motivation>
00097 // This class allows to store data in a smaller representation.
00098 // It is needed to resemble the classic AIPS compress option.
00099 //
00100 // Because the engine can serve only one column, it was possible to
00101 // combine the engine and the column functionality in one class.
00102 // </motivation>
00103 
00104 // <example>
00105 // <srcblock>
00106 // // Create the table description and 2 columns with indirect arrays in it.
00107 // // The Int column will be stored, while the double will be
00108 // // used as virtual.
00109 // TableDesc tableDesc ("", TableDesc::Scratch);
00110 // tableDesc.addColumn (ArrayColumnDesc<Short> ("storedArray"));
00111 // tableDesc.addColumn (ArrayColumnDesc<Float> ("virtualArray"));
00112 // tableDesc.addColumn (ScalarColumnDesc<Float> ("scale"));
00113 // tableDesc.addColumn (ScalarColumnDesc<Float> ("offset"));
00114 //
00115 // // Create a new table using the table description.
00116 // SetupNewTable newtab (tableDesc, "tab.data", Table::New);
00117 //
00118 // // Create the array scaling engine (with auto-scale)
00119 // // and bind it to the float column.
00120 // CompressFloat scalingEngine("virtualArray", "storedArray",
00121 //                             "scale", "offset");
00122 // newtab.bindColumn ("virtualArray", scalingEngine);
00123 // // Create the table.
00124 // Table table (newtab);
00125 //
00126 // // Store a 3-D array (with dim. 2,3,4) into each row of the column.
00127 // // The shape of each array in the column is implicitly set by the put
00128 // // function. This will also set the shape of the underlying Int array.
00129 // ArrayColumn data (table, "virtualArray");
00130 // Array<double> someArray(IPosition(4,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 class CompressFloat : public BaseMappedArrayEngine<Float, Short>
00140 {
00141 public:
00142 
00143   // Construct an engine to scale all arrays in a column with
00144   // the given offset and scale factor.
00145   // StoredColumnName is the name of the column where the scaled
00146   // data will be put and must have data type Short.
00147   // The virtual column using this engine must have data type Float.
00148   CompressFloat (const String& virtualColumnName,
00149                  const String& storedColumnName,
00150                  Float scale,
00151                  Float offset = 0);
00152 
00153   // Construct an engine to scale the arrays in a column.
00154   // The scale and offset values are taken from a column with
00155   // the given names. In that way each array has its own scale factor
00156   // and offset value.
00157   // An exception is thrown if these columns do not exist.
00158   // VirtualColumnName is the name of the virtual column and is used to
00159   // check if the engine gets bound to the correct column.
00160   // StoredColumnName is the name of the column where the scaled
00161   // data will be put and must have data type Short.
00162   // The virtual column using this engine must have data type Float.
00163   CompressFloat (const String& virtualColumnName,
00164                  const String& storedColumnName,
00165                  const String& scaleColumnName,
00166                  const String& offsetColumnName,
00167                  Bool autoScale = True);
00168 
00169   // Construct from a record specification as created by getmanagerSpec().
00170   CompressFloat (const Record& spec);
00171 
00172   // Destructor is mandatory.
00173   ~CompressFloat();
00174 
00175   // Return the type name of the engine (i.e. its class name).
00176   virtual String dataManagerType() const;
00177 
00178   // Get the name given to the engine (is the virtual column name).
00179   virtual String dataManagerName() const;
00180   
00181   // Record a record containing data manager specifications.
00182   virtual Record dataManagerSpec() const;
00183 
00184   // Return the name of the class.
00185   // This includes the names of the template arguments.
00186   static String className();
00187 
00188   // Register the class name and the static makeObject "constructor".
00189   // This will make the engine known to the table system.
00190   static void registerClass();
00191 
00192 private:
00193   // Copy constructor is only used by clone().
00194   // (so it is made private).
00195   CompressFloat (const CompressFloat&);
00196 
00197   // Assignment is not needed and therefore forbidden
00198   // (so it is made private and not implemented).
00199   CompressFloat& operator= (const CompressFloat&);
00200 
00201   // Clone the engine object.
00202   virtual DataManager* clone() const;
00203 
00204   // Initialize the object for a new table.
00205   // It defines the keywords containing the engine parameters.
00206   virtual void create (uInt initialNrrow);
00207 
00208   // Preparing consists of setting the writable switch and
00209   // adding the initial number of rows in case of create.
00210   // Furthermore it reads the keywords containing the engine parameters.
00211   virtual void prepare();
00212 
00213   // Reopen the engine for read/write access.
00214   // It makes the column writable if the underlying column is writable.
00215   virtual void reopenRW();
00216 
00217   // Add rows to the table.
00218   // If auto-scaling, it initializes the scale column with 0
00219   // to indicate that no data has been processed yet.
00220   virtual void addRowInit (uInt startRow, uInt nrrow);
00221 
00222   // Get an array in the given row.
00223   // This will scale and offset from the underlying array.
00224   virtual void getArray (uInt rownr, Array<Float>& array);
00225 
00226   // Put an array in the given row.
00227   // This will scale and offset to the underlying array.
00228   virtual void putArray (uInt rownr, const Array<Float>& array);
00229 
00230   // Get a section of the array in the given row.
00231   // This will scale and offset from the underlying array.
00232   virtual void getSlice (uInt rownr, const Slicer& slicer,
00233                          Array<Float>& array);
00234 
00235   // Put into a section of the array in the given row.
00236   // This will scale and offset to the underlying array.
00237   virtual void putSlice (uInt rownr, const Slicer& slicer,
00238                          const Array<Float>& array);
00239 
00240   // Get an entire column.
00241   // This will scale and offset from the underlying array.
00242   virtual void getArrayColumn (Array<Float>& array);
00243 
00244   // Put an entire column.
00245   // This will scale and offset to the underlying array.
00246   virtual void putArrayColumn (const Array<Float>& array);
00247 
00248   // Get some array values in the column.
00249   // This will scale and offset from the underlying array.
00250   virtual void getArrayColumnCells (const RefRows& rownrs,
00251                                     Array<Float>& data);
00252 
00253   // Put some array values in the column.
00254   // This will scale and offset to the underlying array.
00255   virtual void putArrayColumnCells (const RefRows& rownrs,
00256                                     const Array<Float>& data);
00257 
00258   // Get a section of all arrays in the column.
00259   // This will scale and offset from the underlying array.
00260   virtual void getColumnSlice (const Slicer& slicer, Array<Float>& array);
00261 
00262   // Put a section of all arrays in the column.
00263   // This will scale and offset to the underlying array.
00264   virtual void putColumnSlice (const Slicer& slicer, 
00265                                const Array<Float>& array);
00266 
00267   // Get a section of some arrays in the column.
00268   // This will scale and offset from the underlying array.
00269   virtual void getColumnSliceCells (const RefRows& rownrs,
00270                                     const Slicer& slicer,
00271                                     Array<Float>& data);
00272 
00273   // Put into a section of some arrays in the column.
00274   // This will scale and offset to the underlying array.
00275   virtual void putColumnSliceCells (const RefRows& rownrs,
00276                                     const Slicer& slicer,
00277                                     const Array<Float>& data);
00278 
00279   // Scale and/or offset target to array.
00280   // This is meant when reading an array from the stored column.
00281   // It optimizes for scale=1 and/or offset=0.
00282   void scaleOnGet (Float scale, Float offset,
00283                    Array<Float>& array,
00284                    const Array<Short>& target);
00285 
00286   // Scale and/or offset array to target.
00287   // This is meant when writing an array into the stored column.
00288   // It optimizes for scale=1 and/or offset=0.
00289   void scaleOnPut (Float scale, Float offset,
00290                    const Array<Float>& array,
00291                    Array<Short>& target);
00292 
00293   // Scale and/or offset target to array for the entire column.
00294   // When the scale and offset are fixed, it will do the entire array.
00295   // Otherwise it iterates through the array and applies the scale
00296   // and offset per row.
00297   void scaleColumnOnGet (Array<Float>& array,
00298                          const Array<Short>& target);
00299 
00300   // Scale and/or offset array to target for the entire column.
00301   // When the scale and offset are fixed, it will do the entire array.
00302   // Otherwise it iterates through the array and applies the scale
00303   // and offset per row.
00304   void scaleColumnOnPut (const Array<Float>& array,
00305                          Array<Short>& target);
00306 
00307 
00308   //# Now define the data members.
00309   String         scaleName_p;          //# name of scale column
00310   String         offsetName_p;         //# name of offset column
00311   Float          scale_p;              //# fixed scale factor
00312   Float          offset_p;             //# fixed offset value
00313   Bool           fixed_p;              //# scale/offset is fixed
00314   Bool           autoScale_p;          //# determine scale/offset automatically
00315   ScalarColumn<Float>* scaleColumn_p;  //# column with scale value
00316   ScalarColumn<Float>* offsetColumn_p; //# column with offset value
00317   Array<Short>   buffer_p;             //# buffer to avoid Array constructions
00318 
00319   // Get the scale value for this row.
00320   Float getScale (uInt rownr);
00321 
00322   // Get the offset value for this row.
00323   Float getOffset (uInt rownr);
00324 
00325   // Find minimum and maximum from the array data.
00326   // NaN and infinite values are ignored. If no values are finite,
00327   // minimum and maximum are set to NaN.
00328   void findMinMax (Float& minVal, Float& maxVal,
00329                    const Array<Float>& array) const;
00330 
00331   // Make scale and offset from the minimum and maximum of the array data.
00332   // If minVal is NaN, scale is set to 0.
00333   void makeScaleOffset (Float& scale, Float& offset,
00334                         Float minVal, Float maxVal) const;
00335 
00336   // Put a part of an array in a row using given scale/offset values.
00337   void putPart (uInt rownr, const Slicer& slicer,
00338                 const Array<Float>& array,
00339                 Float scale, Float offset);
00340 
00341   // Fill the array part into the full array and put it using the
00342   // given min/max values.
00343   void putFullPart (uInt rownr, const Slicer& slicer,
00344                     Array<Float>& fullArray,
00345                     const Array<Float>& partArray,
00346                     Float minVal, Float maxVal);
00347 
00348 public:
00349   // Define the "constructor" to construct this engine when a
00350   // table is read back.
00351   // This "constructor" has to be registered by the user of the engine.
00352   // If the engine is commonly used, its registration can be added
00353   // to the registerAllCtor function in DataManager.cc. 
00354   // That function gets automatically invoked by the table system.
00355   static DataManager* makeObject (const String& dataManagerType,
00356                                   const Record& spec);
00357 };
00358 
00359 
00360 inline Float CompressFloat::getScale (uInt rownr)
00361 {
00362   return (fixed_p  ?  scale_p : (*scaleColumn_p)(rownr));
00363 }
00364 inline Float CompressFloat::getOffset (uInt rownr)
00365 {
00366   return (fixed_p  ?  offset_p : (*offsetColumn_p)(rownr));
00367 }
00368 
00369 
00370 
00371 } //# NAMESPACE CASACORE - END
00372 
00373 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1