casa
$Rev:20696$
|
00001 //# BitFlagsEngine.h: Templated virtual column engine to map bit flags to a Bool 00002 //# Copyright (C) 2009 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: BitFlagsEngine.h 20839 2009-12-01 10:15:16Z gervandiepen $ 00027 00028 #ifndef TABLES_BITFLAGSENGINE_H 00029 #define TABLES_BITFLAGSENGINE_H 00030 00031 //# Includes 00032 #include <tables/Tables/BaseMappedArrayEngine.h> 00033 00034 namespace casa { //# NAMESPACE CASA - BEGIN 00035 00036 00037 // <summary> Non-templated Helper class to handle the mask. </summary> 00038 // <use visibility=local> 00039 class BFEngineMask 00040 { 00041 public: 00042 // Form the mask as given. 00043 explicit BFEngineMask (uInt mask=0xffffffff); 00044 00045 // Form the mask from the given keywords defining the bits. 00046 BFEngineMask (const Array<String>& keys, uInt defaultMask); 00047 00048 // Make the mask from the given keywords defining the bits. 00049 void makeMask (const ROTableColumn& column); 00050 00051 // Form the read mask from the specification. 00052 // If keywords are given, the mask is formed from them. 00053 void fromRecord (const RecordInterface& spec, const ROTableColumn& column, 00054 const String& prefix); 00055 00056 // Store the info in a Record. 00057 void toRecord (RecordInterface& spec, const String& prefix) const; 00058 00059 // Get the mask. 00060 uInt getMask() const 00061 { return itsMask; } 00062 00063 // Get the mask keywords. 00064 const Array<String>& getKeys() const 00065 { return itsMaskKeys; } 00066 00067 private: 00068 Array<String> itsMaskKeys; 00069 uInt itsMask; 00070 }; 00071 00072 00073 // <summary> 00074 // Templated virtual column engine to map bit flags to a Bool. 00075 // </summary> 00076 00077 // <use visibility=export> 00078 00079 // <reviewed reviewer="Gareth Hunt" date="94Nov17" tests=""> 00080 // </reviewed> 00081 00082 // <prerequisite> 00083 //# Classes you should understand before using this one. 00084 // <li> VirtualColumnEngine 00085 // <li> VirtualArrayColumn 00086 // </prerequisite> 00087 00088 // <synopsis> 00089 // BitFlagsEngine is a virtual column engine which maps an integer column 00090 // containing flag bits to a Bool column. It can be used in a MeasurementSet 00091 // to have multiple flag categories, yet use all existing software that 00092 // deals with the Bool FLAG column. 00093 // 00094 // The engine support read as well as write access. 00095 // For both cases a mask can be defined telling which bits have to be taken 00096 // into account. For example, when writing to the Bool FLAG column, the data 00097 // in the bitflags column twill be or-ed with the bits as defined in the 00098 // writemask. Similary when reading FLAG, only the bits of the readmask are 00099 // taken into account. 00100 // 00101 // The masks can be defined in two ways: 00102 // <ul> 00103 // <li> The mask can be given directly as an integer value. 00104 // The default write mask is 1 (thus only bit 0), while the default 00105 // read mask is all bits. 00106 // <li> Symbolic names for mask bits can be defined as keywords in the 00107 // flagbits column. They define the bit value, not the bit number. 00108 // It makes it possible to combine bits in a keyword. 00109 // The keywords are stored in a subrecord of keyword FLAGSETS. 00110 // Example of keyword and their values could be: 00111 // <br>RFI=1, CAL=2, CLIP=4, OTHER=8, RFICAL=3 00112 // <br>Note that in this example RFICAL is defined such that it 00113 // contains RFI and CAL. 00114 // </ul> 00115 // A mask can be set at construction time, but it can be changed at runtime 00116 // using the <src>setProperties</src> function. 00117 // The masks are kept in special keywords (which are different from the 00118 // keywords defining the flag bits), so it is possible to change a mask 00119 // by changing those keywords before opening a table. However, that is 00120 // not recommended. 00121 // 00122 // BitFlagsEngine is known to the table system for data types uChar, Short, 00123 // and Int. 00124 // </synopsis> 00125 00126 // <motivation> 00127 // The FLAG_CATEGORY defined the Measurement does not work because adding 00128 // an extra flag means resizing the entire array which is slow. 00129 // This class makes it possible to use an integer column to store flags 00130 // and map it directly to a Bool column. 00131 // </motivation> 00132 00133 // <example> 00134 // <srcblock> 00135 // // Create the table description and 2 columns with indirect arrays in it. 00136 // // The Int column will be stored, while the Bool will be used as virtual. 00137 // TableDesc tableDesc ("", TableDesc::Scratch); 00138 // tableDesc.addColumn (ArrayColumnDesc<Int> ("BitBlags")); 00139 // tableDesc.addColumn (ArrayColumnDesc<Bool> ("FLAG")); 00140 // 00141 // // Create a new table using the table description. 00142 // SetupNewTable newtab (tableDesc, "tab.data", Table::New); 00143 // 00144 // // Create the engine and bind the FLAG column to it. 00145 // BitFlagsEngine<Int> flagsEngine("FLAG", "BitFlags"); 00146 // newtab.bindColumn ("FLAG", flagsEngine); 00147 // // Create the table. 00148 // Table table (newtab); 00149 // 00150 // // Store a 3-D array (with dim. 2,3,4) into each row of the column. 00151 // // The shape of each array in the column is implicitly set by the put 00152 // // function. This will also set the shape of the underlying Int array. 00153 // ArrayColumn data (table, "virtualArray"); 00154 // Array<Bool> someArray(IPosition(4,2,3,4)); 00155 // someArray = True; 00156 // for (uInt i=0, i<10; i++) { // table will have 10 rows 00157 // table.addRow(); 00158 // data.put (i, someArray) 00159 // } 00160 // </srcblock> 00161 // The underlying integer array will be stored according to the writemask 00162 // which defaults to 1. 00163 // </example> 00164 00165 // <templating arg=StoredType> 00166 // <li> only suited for built-in integer data types 00167 // </templating> 00168 00169 template<typename StoredType> class BitFlagsEngine : public BaseMappedArrayEngine<Bool, StoredType> 00170 { 00171 //# Make members of parent class known. 00172 public: 00173 using BaseMappedArrayEngine<Bool,StoredType>::virtualName; 00174 protected: 00175 using BaseMappedArrayEngine<Bool,StoredType>::storedName; 00176 using BaseMappedArrayEngine<Bool,StoredType>::table; 00177 using BaseMappedArrayEngine<Bool,StoredType>::roColumn; 00178 using BaseMappedArrayEngine<Bool,StoredType>::rwColumn; 00179 using BaseMappedArrayEngine<Bool,StoredType>::setNames; 00180 00181 public: 00182 // Construct an engine to map integer arrays in a column to Bool arrays. 00183 // StoredColumnName is the name of the column where the integer 00184 // data will be put and must have data type StoredType. 00185 // The virtual column using this engine must have data type Bool. 00186 // <br>A mask can be given that specifies which bits to use in the mapping 00187 // from StoredType to Bool. Similarly a mask can be given defining which 00188 // bits to set when mapping from Bool to StoredType. 00189 BitFlagsEngine (const String& virtualColumnName, 00190 const String& storedColumnName, 00191 StoredType readMask=StoredType(0xffffffff), 00192 StoredType writeMask=1); 00193 00194 // Construct an engine to map integer arrays in a column to Bool arrays. 00195 // StoredColumnName is the name of the column where the scaled 00196 // data will be put and must have data type StoredType. 00197 // The virtual column using this engine must have data type Bool. 00198 // <br>A mask can be given that specifies which bits to use in the mapping 00199 // from StoredType to Bool. Similarly a mask can be given defining which 00200 // bits to set when mapping from Bool to StoredType. 00201 // The masks are given using the values of keywords in the stored column. 00202 // Each keyword should be an integer defining one or more bits and can be 00203 // seen as a symbolic name. The keyword values are or-ed to form the mask. 00204 // The keywords are stored in a subrecord of keyword FLAGSETS. 00205 BitFlagsEngine (const String& virtualColumnName, 00206 const String& storedColumnName, 00207 const Array<String>& readMaskKeys, 00208 const Array<String>& writeMaskKeys); 00209 00210 // Construct from a record specification as created by dataManagerSpec(). 00211 BitFlagsEngine (const Record& spec); 00212 00213 // Destructor is mandatory. 00214 ~BitFlagsEngine(); 00215 00216 // Return the type name of the engine (i.e. its class name). 00217 virtual String dataManagerType() const; 00218 00219 // Get the name given to the engine (is the virtual column name). 00220 virtual String dataManagerName() const; 00221 00222 // Record a record containing data manager specifications. 00223 virtual Record dataManagerSpec() const; 00224 00225 // Get data manager properties that can be modified. 00226 // These are ReadMask, WriteMask, ReadMaskKeys, and WriteMaskKeys. 00227 // It is a subset of the data manager specification. 00228 virtual Record getProperties() const; 00229 00230 // Modify data manager properties. 00231 // These are ReadMask, WriteMask, ReadMaskKeys, and/or WriteMaskKeys. 00232 // Mask keys should be given as an array of strings giving the keyword 00233 // names defining mask bits (similar to the constructor). Mask keys are 00234 // only used if not empty. 00235 virtual void setProperties (const Record& spec); 00236 00237 // Return the name of the class. 00238 // This includes the names of the template arguments. 00239 static String className(); 00240 00241 // Register the class name and the static makeObject "constructor". 00242 // This will make the engine known to the table system. 00243 // The automatically invoked registration function in DataManReg.cc 00244 // contains BitFlagsEngine<Int>. 00245 // Any other instantiation of this class must be registered "manually" 00246 // (or added to DataManReg.cc). 00247 static void registerClass(); 00248 00249 private: 00250 // Copy constructor is only used by clone(). 00251 // (so it is made private). 00252 BitFlagsEngine (const BitFlagsEngine<StoredType>&); 00253 00254 // Assignment is not needed and therefore forbidden 00255 // (so it is made private and not implemented). 00256 BitFlagsEngine<StoredType>& operator= (const BitFlagsEngine<StoredType>&); 00257 00258 // Clone the engine object. 00259 DataManager* clone() const; 00260 00261 // Initialize the object for a new table. 00262 // It defines the keywords containing the engine parameters. 00263 void create (uInt initialNrrow); 00264 00265 // Preparing consists of setting the writable switch and 00266 // adding the initial number of rows in case of create. 00267 // Furthermore it reads the keywords containing the engine parameters. 00268 void prepare(); 00269 00270 // Get an array in the given row. 00271 // This will scale and offset from the underlying array. 00272 void getArray (uInt rownr, Array<Bool>& array); 00273 00274 // Put an array in the given row. 00275 // This will scale and offset to the underlying array. 00276 void putArray (uInt rownr, const Array<Bool>& array); 00277 00278 // Get a section of the array in the given row. 00279 // This will scale and offset from the underlying array. 00280 void getSlice (uInt rownr, const Slicer& slicer, Array<Bool>& 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 void putSlice (uInt rownr, const Slicer& slicer, 00285 const Array<Bool>& array); 00286 00287 // Get an entire column. 00288 // This will scale and offset from the underlying array. 00289 void getArrayColumn (Array<Bool>& array); 00290 00291 // Put an entire column. 00292 // This will scale and offset to the underlying array. 00293 void putArrayColumn (const Array<Bool>& 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<Bool>& 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<Bool>& data); 00304 00305 // Get a section of all arrays in the column. 00306 // This will scale and offset from the underlying array. 00307 void getColumnSlice (const Slicer& slicer, Array<Bool>& array); 00308 00309 // Put a section of all arrays in the column. 00310 // This will scale and offset to the underlying array. 00311 void putColumnSlice (const Slicer& slicer, const Array<Bool>& array); 00312 00313 // Get a section of some arrays in the column. 00314 // This will scale and offset from the underlying array. 00315 virtual void getColumnSliceCells (const RefRows& rownrs, 00316 const Slicer& slicer, 00317 Array<Bool>& data); 00318 00319 // Put into a section of some arrays in the column. 00320 // This will scale and offset to the underlying array. 00321 virtual void putColumnSliceCells (const RefRows& rownrs, 00322 const Slicer& slicer, 00323 const Array<Bool>& data); 00324 00325 // Map bit flags array to Bool array. 00326 // This is meant when reading an array from the stored column. 00327 void mapOnGet (Array<Bool>& array, 00328 const Array<StoredType>& stored); 00329 00330 // Map Bool array to bit flags array. 00331 // This is meant when writing an array into the stored column. 00332 void mapOnPut (const Array<Bool>& array, 00333 Array<StoredType>& stored); 00334 00335 // Functor to and an array and mask and convert to Bool. 00336 struct FlagsToBool : public std::unary_function<StoredType,Bool> 00337 { 00338 explicit FlagsToBool(StoredType readMask) : itsMask(readMask) {} 00339 Bool operator() (StoredType value) const 00340 { return (value & itsMask) != 0; } 00341 private: 00342 StoredType itsMask; 00343 }; 00344 // Functor to convert Bools to flags using a mask. 00345 // By default only bit 0 is set. 00346 // Flag bits not affected are kept. 00347 struct BoolToFlags : public std::binary_function<Bool,StoredType,StoredType> 00348 { 00349 explicit BoolToFlags(StoredType writeMask) : itsMask(writeMask) {} 00350 StoredType operator() (Bool flag, StoredType value) const 00351 { return (flag ? value&itsMask : value); } 00352 private: 00353 StoredType itsMask; 00354 }; 00355 00356 public: 00357 // Define the "constructor" to construct this engine when a 00358 // table is read back. 00359 // This "constructor" has to be registered by the user of the engine. 00360 // If the engine is commonly used, its registration can be added 00361 // to the registerAllCtor function in DataManReg.cc. 00362 // That function gets automatically invoked by the table system. 00363 static DataManager* makeObject (const String& dataManagerType, 00364 const Record& spec); 00365 00366 private: 00367 BFEngineMask itsBFEReadMask; 00368 BFEngineMask itsBFEWriteMask; 00369 StoredType itsReadMask; 00370 StoredType itsWriteMask; 00371 Bool itsIsNew; //# True = new table 00372 }; 00373 00374 00375 } //# NAMESPACE CASA - END 00376 00377 #ifndef CASACORE_NO_AUTO_TEMPLATES 00378 #include <tables/Tables/BitFlagsEngine.tcc> 00379 #endif //# CASACORE_NO_AUTO_TEMPLATES 00380 #endif