casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ArrayColumn.h
Go to the documentation of this file.
00001 //# ArrayColumn.h: access to an array table column with arbitrary data type
00002 //# Copyright (C) 1994,1995,1996,1997,1998,2001
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: ArrayColumn.h 21298 2012-12-07 14:53:03Z gervandiepen $
00027 
00028 #ifndef TABLES_ARRAYCOLUMN_H
00029 #define TABLES_ARRAYCOLUMN_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <tables/Tables/TableColumn.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 //# Forward Declarations
00039 class RefRows;
00040 template<class T> class Array;
00041 template<class T> class BaseSlicesFunctor;
00042 class IPosition;
00043 class Slice;
00044 class Slicer;
00045 class String;
00046 
00047 
00048 // <summary>
00049 // Read and write access to an array table column with arbitrary data type
00050 // </summary>
00051 
00052 // <use visibility=export>
00053 
00054 // <reviewed reviewer="dschieb" date="1994/08/10" tests="none">
00055 // </reviewed>
00056 
00057 // <prerequisite>
00058 //   <li> Table
00059 //   <li> TableColumn
00060 // </prerequisite>
00061 
00062 // <etymology>
00063 // ArrayColumn<T> gives read and write access to an column in a table
00064 // containing an array with data type T.
00065 // </etymology>
00066 
00067 // <synopsis> 
00068 // The class ArrayColumn allows readonly access to a column
00069 // containing arrays with an arbitrary data type. It can handle direct
00070 // as well as indirect arrays.
00071 // It is possible to get the data in an individual cell (i.e. table row);
00072 // either the whole array or a slice of the array can be accessed.
00073 // It is also possible to get the column as a whole if the arrays
00074 // in all cells of the column have the same shape (which is always true
00075 // for direct arrays). As in the case of individual cells it is possible
00076 // to get the entire arrays or a slice of the arrays.
00077 //
00078 // A default constructor is defined to allow construction of an array
00079 // of ArrayColumn objects. However, this constructs an object not
00080 // referencing a column. Functions like get, etc. will fail (i.e. result
00081 // in a segmentation fault) when used on such objects. The functions
00082 // isNull and throwIfNull can be used to test on this.
00083 // The functions attach and reference can fill in the object.
00084 //
00085 // The assignment operator is not defined for this class, because it was
00086 // felt it would be too confusing. Instead the function reference can
00087 // be used to do assignment with reference semantics. An assignment
00088 // with copy semantics makes no sense for a readonly column.
00089 // </synopsis>
00090 
00091 // <templating arg=T>
00092 //  <li> Default constructor
00093 //  <li> Copy constructor
00094 //  <li> Assignment operator
00095 // </templating>
00096 
00097 // <example>
00098 // See module <linkto module="Tables#open">Tables</linkto>.
00099 // </example>
00100 
00101 
00102 template<class T>
00103 class ArrayColumn : public TableColumn
00104 {
00105 public:
00106 
00107     // The default constructor creates a null object, i.e. it
00108     // does not reference a table column.
00109     // The sole purpose of this constructor is to allow construction
00110     // of an array of ArrayColumn objects.
00111     // The functions reference and attach can be used to make a null object
00112     // reference a column.
00113     // Note that get functions, etc. will cause a segmentation fault
00114     // when operating on a null object. It was felt it was too expensive
00115     // to test on null over and over again. The user should use the isNull
00116     // or throwIfNull function in case of doubt.
00117     ArrayColumn();
00118 
00119     // Construct for the given column in the given table.
00120     ArrayColumn (const Table&, const String& columnName);
00121 
00122     // Construct from the given table column.
00123     // This constructor is useful if first a table column was constructed,
00124     // its type is determined and thereafter used to construct the
00125     // correct column object.
00126     explicit ArrayColumn (const TableColumn&);
00127 
00128     // Copy constructor (reference semantics).
00129     ArrayColumn (const ArrayColumn<T>&);
00130 
00131     ~ArrayColumn();
00132 
00133     // Clone the object.
00134     virtual TableColumn* clone() const;
00135 
00136     // Assignment uses reference semantics, thus works the same
00137     // as function reference.
00138     ArrayColumn<T>& operator= (const ArrayColumn<T>&);
00139 
00140     // Change the reference to another column.
00141     // This is in fact an assignment operator with reference semantics.
00142     // It removes the reference to the current column and creates
00143     // a reference to the column referenced in the other object.
00144     // It will handle null objects correctly.
00145     void reference (const ArrayColumn<T>&);
00146 
00147     // Attach a column to the object.
00148     // This is in fact only a shorthand for 
00149     // <br><src> reference (ArrayColumn<T> (table, columnName)); </src>
00150     void attach (const Table& table, const String& columnName)
00151         { reference (ArrayColumn<T> (table, columnName)); }
00152 
00153     // Get the #dimensions of an array in a particular cell.
00154     // If the cell does not contain an array, 0 is returned.
00155     // Use the function isDefined to test if the cell contains an array.
00156     uInt ndim (uInt rownr) const
00157         { TABLECOLUMNCHECKROW(rownr); return baseColPtr_p->ndim (rownr); }
00158 
00159     // Get the shape of an array in a particular cell.
00160     // If the cell does not contain an array, a 0-dim shape is returned.
00161     // Use the function isDefined to test if the cell contains an array.
00162     IPosition shape (uInt rownr) const
00163         { TABLECOLUMNCHECKROW(rownr); return baseColPtr_p->shape (rownr); }
00164 
00165     // Get the array value in a particular cell (i.e. table row).
00166     // The row numbers count from 0 until #rows-1.
00167     // <group>
00168     // According to the assignment rules of class Array, the destination
00169     // array must be empty or its shape must conform the table array shape.
00170     // However, if the resize flag is set the destination array will be
00171     // resized if not conforming.
00172     void get (uInt rownr, Array<T>& array, Bool resize = False) const;
00173     Array<T> get (uInt rownr) const;
00174     Array<T> operator() (uInt rownr) const;
00175     // </group>
00176 
00177     // Get a slice of an N-dimensional array in a particular cell
00178     // (i.e. table row).
00179     // The row numbers count from 0 until #rows-1.
00180     // The dimensionality of the slice must match the dimensionality
00181     // of the table array and the slice definition should not exceed
00182     // the shape of the table array.
00183     // <group>
00184     // According to the assignment rules of class Array, the destination
00185     // array must be empty or its shape must conform the shape of the
00186     // table array slice.
00187     // However, if the resize flag is set the destination array will be
00188     // resized if not conforming.
00189     void getSlice (uInt rownr, const Slicer& arraySection, Array<T>& array,
00190                    Bool resize = False) const;
00191     Array<T> getSlice (uInt rownr, const Slicer& arraySection) const;
00192     // </group>
00193 
00194     // Get an irregular slice of an N-dimensional array in a particular cell
00195     // (i.e. table row)  as given by the vectors of Slice objects.
00196     // The outer vector represents the array axes.
00197     // A missing or empty axis means the entire axis.
00198     // The inner vector represents the slices to take for each axis.
00199     // For example, to get slices from 2-dim arrays:
00200     // <srcblock>
00201     // Vector<Vector<Slice> > slices(2);      // 2-dim
00202     // slices[1].resize (3);                  // 3 slices in 2nd dim
00203     // slices[1][0] = Slice(100,20);
00204     // slices[1][1] = Slice(200,18);
00205     // slices[1][2] = Slice(538,30,2);
00206     // // Get data. Vector of first axis is empty, thus entire axis is read.
00207     // Array<Complex> data = dataCol.getColumn (slices);
00208     // </srcblock>
00209     // If the column contains n-dim arrays, the resulting array is (n+1)-dim.
00210     // with the last dimension representing the number of rows and the
00211     // other dimensions representing the shape of the slice.
00212     // The arrays in the column must have the same shape in all cells.
00213     // <group>
00214     // According to the assignment rules of class Array, the destination
00215     // array must be empty or its shape must conform the resulting (n+1)-dim
00216     // array.
00217     // However, if the resize flag is set the destination array will be
00218     // resized if not conforming.
00219     void getSlice (uInt rownr,
00220                    const Vector<Vector<Slice> >& arraySlices,
00221                    Array<T>& arr, Bool resize = False) const;
00222     Array<T> getSlice (uInt rownr,
00223                        const Vector<Vector<Slice> >& arraySlices) const;
00224     // </group>
00225 
00226     // Get the array of all values in a column.
00227     // If the column contains n-dim arrays, the resulting array is (n+1)-dim
00228     // with the last dimension representing the number of rows.
00229     // The arrays in the column must have the same shape in all cells.
00230     // <group>
00231     // According to the assignment rules of class Array, the destination
00232     // array must be empty or its shape must conform the resulting (n+1)-dim
00233     // array.
00234     // However, if the resize flag is set the destination array will be
00235     // resized if not conforming.
00236     void getColumn (Array<T>& array, Bool resize = False) const;
00237     Array<T> getColumn() const;
00238     // </group>
00239 
00240     // Get regular slices from all arrays in the column.
00241     // If the column contains n-dim arrays, the resulting array is (n+1)-dim.
00242     // with the last dimension representing the number of rows and the
00243     // other dimensions representing the shape of the slice.
00244     // The arrays in the column must have the same shape in all cells.
00245     // <group>
00246     // According to the assignment rules of class Array, the destination
00247     // array must be empty or its shape must conform the resulting (n+1)-dim
00248     // array.
00249     // However, if the resize flag is set the destination array will be
00250     // resized if not conforming.
00251     void getColumn (const Slicer& arraySection, Array<T>& array,
00252                     Bool resize = False) const;
00253     Array<T> getColumn (const Slicer& arraySection) const;
00254     // </group>
00255 
00256     // Get irregular slices from all arrays in the column as given by the
00257     // vectors of Slice objects. The outer vector represents the array axes.
00258     // A missing or empty axis means the entire axis.
00259     // The inner vector represents the slices to take for each axis.
00260     // For example, to get slices from 2-dim arrays:
00261     // <srcblock>
00262     // Vector<Vector<Slice> > slices(2);      // 2-dim
00263     // slices[1].resize (3);                  // 3 slices in 2nd dim
00264     // slices[1][0] = Slice(100,20);
00265     // slices[1][1] = Slice(200,18);
00266     // slices[1][2] = Slice(538,30,2);
00267     // // Get data. Vector of first axis is empty, thus entire axis is read.
00268     // Array<Complex> data = dataCol.getColumn (slices);
00269     // </srcblock>
00270     // If the column contains n-dim arrays, the resulting array is (n+1)-dim.
00271     // with the last dimension representing the number of rows and the
00272     // other dimensions representing the shape of the slice.
00273     // The arrays in the column must have the same shape in all cells.
00274     // <group>
00275     // According to the assignment rules of class Array, the destination
00276     // array must be empty or its shape must conform the resulting (n+1)-dim
00277     // array.
00278     // However, if the resize flag is set the destination array will be
00279     // resized if not conforming.
00280     void getColumn (const Vector<Vector<Slice> >& arraySection, Array<T>& array,
00281                     Bool resize = False) const;
00282     Array<T> getColumn (const Vector<Vector<Slice> >& arraySection) const;
00283     // </group>
00284 
00285     // Get the array of some values in a column.
00286     // The Slicer object can be used to specify start, end (or length),
00287     // and stride of the rows to get.
00288     // If the column contains n-dim arrays, the resulting array is (n+1)-dim
00289     // with the last dimension representing the number of rows in the slicer.
00290     // The arrays in the column must have the same shape in all those cells.
00291     // According to the assignment rules of class Array, the destination
00292     // array must be empty or its shape must conform the resulting (n+1)-dim
00293     // array.
00294     // However, if the resize flag is set the destination array will be
00295     // resized if not conforming.
00296     // <group>
00297     void getColumnRange (const Slicer& rowRange, Array<T>& arr,
00298                          Bool resize = False) const;
00299     Array<T> getColumnRange (const Slicer& rowRange) const;
00300     void getColumnCells (const RefRows& rownrs, Array<T>& arr,
00301                          Bool resize = False) const;
00302     Array<T> getColumnCells (const RefRows& rownrs) const;
00303     // </group>
00304 
00305     // Get slices from some arrays in a column.
00306     // The first Slicer object can be used to specify start, end (or length),
00307     // and stride of the rows to get. The second Slicer object can be
00308     // used to specify the slice to take from each array.
00309     // If the column contains n-dim arrays, the resulting array is (n+1)-dim
00310     // with the last dimension representing the number of rows in the slicer.
00311     // The arrays in the column must have the same shape in all those cells.
00312     // According to the assignment rules of class Array, the destination
00313     // array must be empty or its shape must conform the resulting (n+1)-dim
00314     // array.
00315     // However, if the resize flag is set the destination array will be
00316     // resized if not conforming.
00317     // <group>
00318     void getColumnRange (const Slicer& rowRange,
00319                          const Slicer& arraySection, Array<T>& arr,
00320                          Bool resize = False) const;
00321     Array<T> getColumnRange (const Slicer& rowRange,
00322                              const Slicer& arraySection) const;
00323     void getColumnCells (const RefRows& rownrs,
00324                          const Slicer& arraySection, Array<T>& arr,
00325                          Bool resize = False) const;
00326     Array<T> getColumnCells (const RefRows& rownrs,
00327                              const Slicer& arraySection) const;
00328     // </group>
00329 
00330     // Similar to getColumn (arraySlices, arr, resize) except it
00331     // gets the slices for the given rows instead of all rows.
00332     void getColumnCells (const RefRows& rows,
00333                          const Vector<Vector<Slice> >& arraySlices,
00334                          Array<T>& arr,
00335                          Bool resize = False) const;
00336     void getSliceForRows (const RefRows& rows,
00337                           const Vector<Vector<Slice> >& arraySlices,
00338                           Array<T>& destination) const
00339       { getColumnCells (rows, arraySlices, destination, True); }
00340  
00341     // The get() function like above which does not check shapes, etc.
00342     // It is faster and can be used for performance reasons if one
00343     // knows for sure that the arguments are correct.
00344     // E.g. it is used internally in virtual column engines.
00345     void baseGet (uInt rownr, Array<T>& array) const
00346       { baseColPtr_p->get (rownr, &array); }
00347 
00348     // Set the shape of the array in the given row.
00349     // Setting the shape is needed if the array is put in slices,
00350     // otherwise the table system would not know the shape.
00351     // <group>
00352     void setShape (uInt rownr, const IPosition& shape);
00353 
00354     // Try to store the array in a tiled way using the given tile shape.
00355     void setShape (uInt rownr, const IPosition& shape,
00356                    const IPosition& tileShape);
00357     // </group>
00358 
00359     // Put the array in a particular cell (i.e. table row).
00360     // The row numbers count from 0 until #rows-1.
00361     // If the shape of the table array in that cell has not already been
00362     // defined, it will be defined implicitly.
00363     void put (uInt rownr, const Array<T>& array);
00364 
00365     // Copy the value of a cell of that column to a cell of this column.
00366     // The data types of both columns must be the same, otherwise an
00367     // exception is thrown.
00368     // <group>
00369     // Use the same row numbers for both cells.
00370     void put (uInt rownr, const ArrayColumn<T>& that)
00371         { put (rownr, that, rownr); }
00372     // Use possibly different row numbers for that (i.e. input) and
00373     // and this (i.e. output) cell.
00374     void put (uInt thisRownr, const ArrayColumn<T>& that, uInt thatRownr);
00375     // </group>
00376 
00377     // Copy the value of a cell of that column to a cell of this column.
00378     // This function uses a generic TableColumn object as input.
00379     // The data types of both columns must be the same, otherwise an
00380     // exception is thrown.
00381     // <group>
00382     // Use the same row numbers for both cells.
00383     void put (uInt rownr, const TableColumn& that)
00384         { put (rownr, that, rownr); }
00385     // Use possibly different row numbers for that (i.e. input) and
00386     // and this (i.e. output) cell.
00387     void put (uInt thisRownr, const TableColumn& that, uInt thatRownr);
00388     // </group>
00389 
00390     // Put into a slice of an N-dimensional array in a particular cell.
00391     // The row numbers count from 0 until #rows-1.
00392     // The shape of the table array must have been defined.
00393     // The dimensionality of the slice must match the dimensionality
00394     // of the table array and the slice definition should not exceed
00395     // the shape of the table array.
00396     void putSlice (uInt rownr, const Slicer& arraySection,
00397                    const Array<T>& array);
00398 
00399     void putSlice (uInt rownr, const Vector<Vector<Slice> >& arraySlices,
00400                    const Array<T>& arr);
00401 
00402     // Put the array of all values in the column.
00403     // If the column contains n-dim arrays, the source array must be (n+1)-dim
00404     // with the last dimension representing the number of rows.
00405     void putColumn (const Array<T>& array);
00406 
00407     // Put into subsections of the table arrays in the entire column.
00408     // If the column contains n-dim arrays, the source array is (n+1)-dim
00409     // with the last dimension representing the number of rows and
00410     // other dimensions representing the shape of the slice.
00411     // The dimensionality of the slice must match the dimensionality
00412     // of the table array, thus must be n-dim. Also the slice definition
00413     // should not exceed the shape of the table arrays.
00414     void putColumn (const Slicer& arraySection, const Array<T>& array);
00415 
00416     void putColumn (const Vector<Vector<Slice> >& arraySlices,
00417                     const Array<T>& arr);
00418 
00419     // Put the array of some values in the column.
00420     // The Slicer object can be used to specify start, end (or length),
00421     // and stride of the rows to put.
00422     // If the column contains n-dim arrays, the source array must be (n+1)-dim
00423     // with the last dimension representing the number of rows in the slicer.
00424     // <group>
00425     void putColumnRange (const Slicer& rowRange, const Array<T>& arr);
00426     void putColumnCells (const RefRows& rownrs, const Array<T>& arr);
00427     // </group>
00428 
00429     // Put into subsection of the table arrays in some rows of the column.
00430     // The first Slicer object can be used to specify start, end (or length),
00431     // and stride of the rows to put. The second Slicer object can be
00432     // used to specify the slice to take from each array.
00433     // If the column contains n-dim arrays, the source array must be (n+1)-dim
00434     // with the last dimension representing the number of rows in the slicer.
00435     // <group>
00436     void putColumnRange (const Slicer& rowRange,
00437                          const Slicer& arraySection, const Array<T>& arr);
00438     void putColumnCells (const RefRows& rownrs,
00439                          const Slicer& arraySection, const Array<T>& arr);
00440     // </group>
00441 
00442     // Same as putColumn(arraySlices, arr) except that it puts for the given
00443     // rows instead of all rows.
00444     // <group>
00445     void putColumnCells (const RefRows& rows,
00446                          const Vector<Vector<Slice> >& arraySlices,
00447                          const Array<T>& arr);
00448     void putSliceFromRows (const RefRows& rows,
00449                            const Vector<Vector<Slice> >& arraySlices,
00450                            const Array<T>& source)
00451       { putColumnCells (rows, arraySlices, source); }
00452     // </group>
00453 
00454     // Put the same value in all cells of the column.
00455     void fillColumn (const Array<T>& value);
00456 
00457     // Put the contents of a column with the same data type into this column.
00458     // To put the contents of a column with a different data type into
00459     // this column, the function TableColumn::putColumn can be used
00460     // (provided the data type promotion is possible).
00461     // In fact, this function is an assignment operator with copy semantics.
00462     void putColumn (const ArrayColumn<T>& that);
00463 
00464     // The put() function like above which does not check shapes, etc.
00465     // It is faster and can be used for performance reasons if one
00466     // knows for sure that the arguments are correct.
00467     // E.g. it is used internally in virtual column engines.
00468     void basePut (uInt rownr, const Array<T>& array)
00469       { baseColPtr_p->put (rownr, &array); }
00470 
00471 private:
00472     // Check if the data type matches the column data type.
00473     void checkDataType() const;
00474 
00475     // Check the shape of the array. If the array is empty or if
00476     // <src>resize=True</src>, the array is resized if needed.
00477     // An exception is thrown if not conforming.
00478     void checkShape (const IPosition& shp,
00479                      Array<T>& arr, Bool resize,
00480                      const String& where) const;
00481 
00482 protected:
00483     // A common function used by all functions that can get or put irregular
00484     // array slices. The functor performs the get or put operation.
00485     void handleSlices (const Vector<Vector<Slice> >& slices,
00486                        BaseSlicesFunctor<T>& functor,
00487                        const Slicer& slicer,
00488                        IPosition& arrEnd,
00489                        Array<T>& array) const;
00490 
00491     // Keep switches to determine if a slice or an entire column can
00492     // be accessed or the change of an array can be changed.
00493     // True = yes;  False = no.
00494     mutable Bool canAccessSlice_p;
00495     mutable Bool canAccessColumn_p;
00496     mutable Bool canAccessColumnSlice_p;
00497     // Keep switches to know if access knowledge is permanent or has
00498     // to be asked again the next time.
00499     mutable Bool reaskAccessSlice_p;
00500     mutable Bool reaskAccessColumn_p;
00501     mutable Bool reaskAccessColumnSlice_p;
00502 };
00503 
00504 
00505 } //# NAMESPACE CASA - END
00506 
00507 
00508 //# Make old name ROArrayColumn still available.
00509 #define ROArrayColumn ArrayColumn
00510 
00511 
00512 #ifndef CASACORE_NO_AUTO_TEMPLATES
00513 #include <tables/Tables/ArrayColumn.tcc>
00514 #endif //# CASACORE_NO_AUTO_TEMPLATES
00515 #endif