casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CompressFloat.h
Go to the documentation of this file.
1 //# CompressFloat.h: Virtual column engine to scale a table float array
2 //# Copyright (C) 2001,2002
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef TABLES_COMPRESSFLOAT_H
29 #define TABLES_COMPRESSFLOAT_H
30 
31 //# Includes
32 #include <casacore/casa/aips.h>
36 
37 
38 namespace casacore { //# NAMESPACE CASACORE - BEGIN
39 
40 // <summary>
41 // Virtual column engine to scale a table float array
42 // </summary>
43 
44 // <use visibility=export>
45 
46 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tCompressFloat.cc">
47 // </reviewed>
48 
49 // <prerequisite>
50 //# Classes you should understand before using this one.
51 // <li> VirtualColumnEngine
52 // <li> VirtualArrayColumn
53 // </prerequisite>
54 
55 // <synopsis>
56 // CompressFloat is a virtual column engine which scales an array
57 // of one type to another type to save disk storage.
58 // This resembles the classic AIPS compress method which scales the
59 // data from float to short.
60 // The scale factor and offset values can be given in two ways:
61 // <ul>
62 // <li> As a fixed values which is used for all arrays in the column.
63 // These values have to be given when constructing of the engine.
64 // <li> As the name of a column. In this way each array in the
65 // column has its own scale and offset value.
66 // By default it uses auto-scaling (see below).
67 // Otherwise the scale and offset value in a row must be put
68 // before the array is put and should not be changed anymore.
69 // </ul>
70 // Auto-scaling means that the engine will determine the scale
71 // and offset value itself when an array (or a slice) is put.
72 // It does it by mapping the values in the array to the range [-32767,32767].
73 // At each put the scale/offset values are changed as needed.
74 // Note that with auto-scaling <src>putSlice</src> can be somewhat
75 // slower, because the entire array might need to be rescaled.
76 //
77 // As in FITS the scale and offset values are used as:
78 // <br><src> True_value = Stored_value * scale + offset; </src>
79 //
80 // An engine object should be used for one column only, because the stored
81 // column name is part of the engine. If it would be used for more than
82 // one column, they would all share the same stored column.
83 // When the engine is bound to a column, it is checked if the name
84 // of that column matches the given virtual column name.
85 //
86 // The engine can be used for a column containing any kind of array
87 // (thus direct or indirect, fixed or variable shaped)) as long as the
88 // virtual array can be stored in the stored array. Thus a fixed shaped
89 // virtual can use a variable shaped stored, but not vice versa.
90 // A fixed shape indirect virtual can use a stored with direct arrays.
91 //
92 // This class can also serve as an example of how to implement
93 // a virtual column engine.
94 // </synopsis>
95 
96 // <motivation>
97 // This class allows to store data in a smaller representation.
98 // It is needed to resemble the classic AIPS compress option.
99 //
100 // Because the engine can serve only one column, it was possible to
101 // combine the engine and the column functionality in one class.
102 // </motivation>
103 
104 // <example>
105 // <srcblock>
106 // // Create the table description and 2 columns with indirect arrays in it.
107 // // The Int column will be stored, while the double will be
108 // // used as virtual.
109 // TableDesc tableDesc ("", TableDesc::Scratch);
110 // tableDesc.addColumn (ArrayColumnDesc<Short> ("storedArray"));
111 // tableDesc.addColumn (ArrayColumnDesc<Float> ("virtualArray"));
112 // tableDesc.addColumn (ScalarColumnDesc<Float> ("scale"));
113 // tableDesc.addColumn (ScalarColumnDesc<Float> ("offset"));
114 //
115 // // Create a new table using the table description.
116 // SetupNewTable newtab (tableDesc, "tab.data", Table::New);
117 //
118 // // Create the array scaling engine (with auto-scale)
119 // // and bind it to the float column.
120 // CompressFloat scalingEngine("virtualArray", "storedArray",
121 // "scale", "offset");
122 // newtab.bindColumn ("virtualArray", scalingEngine);
123 // // Create the table.
124 // Table table (newtab);
125 //
126 // // Store a 3-D array (with dim. 2,3,4) into each row of the column.
127 // // The shape of each array in the column is implicitly set by the put
128 // // function. This will also set the shape of the underlying Int array.
129 // ArrayColumn data (table, "virtualArray");
130 // Array<double> someArray(IPosition(4,2,3,4));
131 // someArray = 0;
132 // for (rownr_t i=0, i<10; i++) { // table will have 10 rows
133 // table.addRow();
134 // data.put (i, someArray)
135 // }
136 // </srcblock>
137 // </example>
138 
139 class CompressFloat : public BaseMappedArrayEngine<Float, Short>
140 {
141 public:
142 
143  // Construct an engine to scale all arrays in a column with
144  // the given offset and scale factor.
145  // StoredColumnName is the name of the column where the scaled
146  // data will be put and must have data type Short.
147  // The virtual column using this engine must have data type Float.
148  CompressFloat (const String& virtualColumnName,
149  const String& storedColumnName,
150  Float scale,
151  Float offset = 0);
152 
153  // Construct an engine to scale the arrays in a column.
154  // The scale and offset values are taken from a column with
155  // the given names. In that way each array has its own scale factor
156  // and offset value.
157  // An exception is thrown if these columns do not exist.
158  // VirtualColumnName is the name of the virtual column and is used to
159  // check if the engine gets bound to the correct column.
160  // StoredColumnName is the name of the column where the scaled
161  // data will be put and must have data type Short.
162  // The virtual column using this engine must have data type Float.
163  CompressFloat (const String& virtualColumnName,
164  const String& storedColumnName,
165  const String& scaleColumnName,
166  const String& offsetColumnName,
167  Bool autoScale = True);
168 
169  // Construct from a record specification as created by getmanagerSpec().
170  CompressFloat (const Record& spec);
171 
172  // Destructor is mandatory.
173  ~CompressFloat();
174 
175  // Return the type name of the engine (i.e. its class name).
176  virtual String dataManagerType() const;
177 
178  // Get the name given to the engine (is the virtual column name).
179  virtual String dataManagerName() const;
180 
181  // Record a record containing data manager specifications.
182  virtual Record dataManagerSpec() const;
183 
184  // Return the name of the class.
185  // This includes the names of the template arguments.
186  static String className();
187 
188  // Register the class name and the static makeObject "constructor".
189  // This will make the engine known to the table system.
190  static void registerClass();
191 
192 private:
193  // Copy constructor is only used by clone().
194  // (so it is made private).
195  CompressFloat (const CompressFloat&);
196 
197  // Assignment is not needed and therefore forbidden
198  // (so it is made private and not implemented).
200 
201  // Clone the engine object.
202  virtual DataManager* clone() const;
203 
204  // Initialize the object for a new table.
205  // It defines the keywords containing the engine parameters.
206  virtual void create64 (rownr_t initialNrrow);
207 
208  // Preparing consists of setting the writable switch and
209  // adding the initial number of rows in case of create.
210  // Furthermore it reads the keywords containing the engine parameters.
211  virtual void prepare();
212 
213  // Reopen the engine for read/write access.
214  // It makes the column writable if the underlying column is writable.
215  virtual void reopenRW();
216 
217  // Add rows to the table.
218  // If auto-scaling, it initializes the scale column with 0
219  // to indicate that no data has been processed yet.
220  virtual void addRowInit (rownr_t startRow, rownr_t nrrow);
221 
222  // Get an array in the given row.
223  // This will scale and offset from the underlying array.
224  virtual void getArray (rownr_t rownr, Array<Float>& array);
225 
226  // Put an array in the given row.
227  // This will scale and offset to the underlying array.
228  virtual void putArray (rownr_t rownr, const Array<Float>& array);
229 
230  // Get a section of the array in the given row.
231  // This will scale and offset from the underlying array.
232  virtual void getSlice (rownr_t rownr, const Slicer& slicer,
233  Array<Float>& array);
234 
235  // Put into a section of the array in the given row.
236  // This will scale and offset to the underlying array.
237  virtual void putSlice (rownr_t rownr, const Slicer& slicer,
238  const Array<Float>& array);
239 
240  // Get an entire column.
241  // This will scale and offset from the underlying array.
242  virtual void getArrayColumn (Array<Float>& array);
243 
244  // Put an entire column.
245  // This will scale and offset to the underlying array.
246  virtual void putArrayColumn (const Array<Float>& array);
247 
248  // Get some array values in the column.
249  // This will scale and offset from the underlying array.
250  virtual void getArrayColumnCells (const RefRows& rownrs,
251  Array<Float>& data);
252 
253  // Put some array values in the column.
254  // This will scale and offset to the underlying array.
255  virtual void putArrayColumnCells (const RefRows& rownrs,
256  const Array<Float>& data);
257 
258  // Get a section of all arrays in the column.
259  // This will scale and offset from the underlying array.
260  virtual void getColumnSlice (const Slicer& slicer, Array<Float>& array);
261 
262  // Put a section of all arrays in the column.
263  // This will scale and offset to the underlying array.
264  virtual void putColumnSlice (const Slicer& slicer,
265  const Array<Float>& array);
266 
267  // Get a section of some arrays in the column.
268  // This will scale and offset from the underlying array.
269  virtual void getColumnSliceCells (const RefRows& rownrs,
270  const Slicer& slicer,
271  Array<Float>& data);
272 
273  // Put into a section of some arrays in the column.
274  // This will scale and offset to the underlying array.
275  virtual void putColumnSliceCells (const RefRows& rownrs,
276  const Slicer& slicer,
277  const Array<Float>& data);
278 
279  // Scale and/or offset target to array.
280  // This is meant when reading an array from the stored column.
281  // It optimizes for scale=1 and/or offset=0.
282  void scaleOnGet (Float scale, Float offset,
283  Array<Float>& array,
284  const Array<Short>& target);
285 
286  // Scale and/or offset array to target.
287  // This is meant when writing an array into the stored column.
288  // It optimizes for scale=1 and/or offset=0.
289  void scaleOnPut (Float scale, Float offset,
290  const Array<Float>& array,
291  Array<Short>& target);
292 
293  // Scale and/or offset target to array for the entire column.
294  // When the scale and offset are fixed, it will do the entire array.
295  // Otherwise it iterates through the array and applies the scale
296  // and offset per row.
297  void scaleColumnOnGet (Array<Float>& array,
298  const Array<Short>& target);
299 
300  // Scale and/or offset array to target for the entire column.
301  // When the scale and offset are fixed, it will do the entire array.
302  // Otherwise it iterates through the array and applies the scale
303  // and offset per row.
304  void scaleColumnOnPut (const Array<Float>& array,
305  Array<Short>& target);
306 
307 
308  //# Now define the data members.
309  String scaleName_p; //# name of scale column
310  String offsetName_p; //# name of offset column
311  Float scale_p; //# fixed scale factor
312  Float offset_p; //# fixed offset value
313  Bool fixed_p; //# scale/offset is fixed
314  Bool autoScale_p; //# determine scale/offset automatically
315  ScalarColumn<Float>* scaleColumn_p; //# column with scale value
316  ScalarColumn<Float>* offsetColumn_p; //# column with offset value
317  Array<Short> buffer_p; //# buffer to avoid Array constructions
318 
319  // Get the scale value for this row.
320  Float getScale (rownr_t rownr);
321 
322  // Get the offset value for this row.
323  Float getOffset (rownr_t rownr);
324 
325  // Find minimum and maximum from the array data.
326  // NaN and infinite values are ignored. If no values are finite,
327  // minimum and maximum are set to NaN.
328  void findMinMax (Float& minVal, Float& maxVal,
329  const Array<Float>& array) const;
330 
331  // Make scale and offset from the minimum and maximum of the array data.
332  // If minVal is NaN, scale is set to 0.
333  void makeScaleOffset (Float& scale, Float& offset,
334  Float minVal, Float maxVal) const;
335 
336  // Put a part of an array in a row using given scale/offset values.
337  void putPart (rownr_t rownr, const Slicer& slicer,
338  const Array<Float>& array,
339  Float scale, Float offset);
340 
341  // Fill the array part into the full array and put it using the
342  // given min/max values.
343  void putFullPart (rownr_t rownr, const Slicer& slicer,
344  Array<Float>& fullArray,
345  const Array<Float>& partArray,
346  Float minVal, Float maxVal);
347 
348 public:
349  // Define the "constructor" to construct this engine when a
350  // table is read back.
351  // This "constructor" has to be registered by the user of the engine.
352  // If the engine is commonly used, its registration can be added
353  // to the registerAllCtor function in DataManager.cc.
354  // That function gets automatically invoked by the table system.
355  static DataManager* makeObject (const String& dataManagerType,
356  const Record& spec);
357 };
358 
359 
361 {
362  return (fixed_p ? scale_p : (*scaleColumn_p)(rownr));
363 }
365 {
366  return (fixed_p ? offset_p : (*offsetColumn_p)(rownr));
367 }
368 
369 
370 
371 } //# NAMESPACE CASACORE - END
372 
373 #endif
virtual DataManager * clone() const
Clone the engine object.
Array< Short > buffer_p
ScalarColumn< Float > * scaleColumn_p
virtual void getColumnSliceCells(const RefRows &rownrs, const Slicer &slicer, Array< Float > &data)
Get a section of some arrays in the column.
~CompressFloat()
Destructor is mandatory.
TableExprNode array(const TableExprNode &values, const TableExprNodeSet &shape)
Create an array of the given shape and fill it with the values.
Definition: ExprNode.h:1929
Templated virtual column engine for a table array of any type.
CompressFloat & operator=(const CompressFloat &)
Assignment is not needed and therefore forbidden (so it is made private and not implemented).
virtual void addRowInit(rownr_t startRow, rownr_t nrrow)
Add rows to the table.
void putFullPart(rownr_t rownr, const Slicer &slicer, Array< Float > &fullArray, const Array< Float > &partArray, Float minVal, Float maxVal)
Fill the array part into the full array and put it using the given min/max values.
void scaleOnPut(Float scale, Float offset, const Array< Float > &array, Array< Short > &target)
Scale and/or offset array to target.
virtual String dataManagerName() const
Get the name given to the engine (is the virtual column name).
virtual void putArrayColumn(const Array< Float > &array)
Put an entire column.
Virtual column engine to scale a table float array.
virtual void getArray(rownr_t rownr, Array< Float > &array)
Get an array in the given row.
virtual void getSlice(rownr_t rownr, const Slicer &slicer, Array< Float > &array)
Get a section of the array in the given row.
virtual void putColumnSlice(const Slicer &slicer, const Array< Float > &array)
Put a section of all arrays in the column.
static void registerClass()
Register the class name and the static makeObject &quot;constructor&quot;.
virtual void reopenRW()
Reopen the engine for read/write access.
virtual void putSlice(rownr_t rownr, const Slicer &slicer, const Array< Float > &array)
Put into a section of the array in the given row.
CompressFloat(const String &virtualColumnName, const String &storedColumnName, Float scale, Float offset=0)
Construct an engine to scale all arrays in a column with the given offset and scale factor...
virtual void create64(rownr_t initialNrrow)
Initialize the object for a new table.
Float getOffset(rownr_t rownr)
Get the offset value for this row.
void findMinMax(Float &minVal, Float &maxVal, const Array< Float > &array) const
Find minimum and maximum from the array data.
ScalarColumn< Float > * offsetColumn_p
virtual String dataManagerType() const
Return the type name of the engine (i.e.
void scaleColumnOnPut(const Array< Float > &array, Array< Short > &target)
Scale and/or offset array to target for the entire column.
virtual void getColumnSlice(const Slicer &slicer, Array< Float > &array)
Get a section of all arrays in the column.
Class holding the row numbers in a RefTable.
Definition: RefRows.h:85
virtual void putArray(rownr_t rownr, const Array< Float > &array)
Put an array in the given row.
static DataManager * makeObject(const String &dataManagerType, const Record &spec)
Define the &quot;constructor&quot; to construct this engine when a table is read back.
A hierarchical collection of named fields of various types.
Definition: Record.h:180
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
virtual void putColumnSliceCells(const RefRows &rownrs, const Slicer &slicer, const Array< Float > &data)
Put into a section of some arrays in the column.
virtual void getArrayColumnCells(const RefRows &rownrs, Array< Float > &data)
Get some array values in the column.
float Float
Definition: aipstype.h:54
virtual void prepare()
Preparing consists of setting the writable switch and adding the initial number of rows in case of cr...
virtual void putArrayColumnCells(const RefRows &rownrs, const Array< Float > &data)
Put some array values in the column.
Specify which elements to extract from an n-dimensional array.
Definition: Slicer.h:288
uInt64 rownr_t
Define the type of a row number in a table.
Definition: aipsxtype.h:46
virtual void getArrayColumn(Array< Float > &array)
Get an entire column.
virtual Record dataManagerSpec() const
Record a record containing data manager specifications.
void scaleOnGet(Float scale, Float offset, Array< Float > &array, const Array< Short > &target)
Scale and/or offset target to array.
Abstract base class for a data manager.
Definition: DataManager.h:220
void makeScaleOffset(Float &scale, Float &offset, Float minVal, Float maxVal) const
Make scale and offset from the minimum and maximum of the array data.
static String className()
Return the name of the class.
String: the storage and methods of handling collections of characters.
Definition: String.h:225
void putPart(rownr_t rownr, const Slicer &slicer, const Array< Float > &array, Float scale, Float offset)
Put a part of an array in a row using given scale/offset values.
void scaleColumnOnGet(Array< Float > &array, const Array< Short > &target)
Scale and/or offset target to array for the entire column.
Float getScale(rownr_t rownr)
Get the scale value for this row.
const Bool True
Definition: aipstype.h:43