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