casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
BitFlagsEngine.h
Go to the documentation of this file.
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