casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
StIndArray.h
Go to the documentation of this file.
00001 //# StIndArray.h: Read/write indirect arrays
00002 //# Copyright (C) 1994,1995,1996,1997,1999,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: StIndArray.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef TABLES_STINDARRAY_H
00029 #define TABLES_STINDARRAY_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <tables/Tables/StArrayFile.h>
00034 #include <casa/Arrays/IPosition.h>
00035 #include <casa/BasicSL/Complex.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 //# Forward Declarations
00040 class Slicer;
00041 template<class T> class Array;
00042 
00043 
00044 // <summary>
00045 // Read/write indirect arrays
00046 // </summary>
00047 
00048 // <use visibility=local>
00049 
00050 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00051 // </reviewed>
00052 
00053 // <prerequisite>
00054 //# Classes you should understand before using this one.
00055 //   <li> StManArrayFile
00056 // </prerequisite>
00057 
00058 // <etymology>
00059 // StIndArray stores indirect arrays on behalf of a storage manager.
00060 // </etymology>
00061 
00062 // <synopsis> 
00063 // StIndArray is a helper class for accessing indirect table arrays.
00064 // It is the interface between a storage manager like StManAipsIO
00065 // (in particular its indirect array column class
00066 // <linkto class="StManColumnIndArrayAipsIO:description">
00067 // StManColumnIndArrayAipsIO</linkto>)
00068 // and the data storage class
00069 // <linkto class="StManArrayFile:description">StManArrayFile</linkto>
00070 // which represents the file holding the shapes and data of the arrays.
00071 // This file holds the data in canonical format.
00072 //
00073 // StIndArray holds information about an array in the file.
00074 // <ol>
00075 // <li> Offset of the array in the file. This points to the array shape.
00076 //  This is stored by storage managers and serves as the mapping between
00077 //  row number and array.
00078 // <li> Array data offset, i.e. the length of the shape in the file.
00079 //  Because the data is stored in canonical format, the length of the
00080 //  shape in the file is not directly known but has to be supplied this way.
00081 // <li> The actual shape of the array
00082 // </ol>
00083 // The storage manager creates an StIndArray object for each row.
00084 // When an array is accessed for the first time,
00085 // the array data offset and the shape will be filled in by StIndArray.
00086 // In this way it serves as a cache for the array shape.
00087 //
00088 // StIndArray implements all necessary functions to get/put an array or
00089 // an array slice from/into file supplied by the given StManArrayFile object.
00090 // The StManArrayFile object itself has to be created by the storage manager
00091 // and given to the StIndArray functions.
00092 // </synopsis> 
00093 
00094 // <motivation>
00095 // This helper class makes it possible to share equal functionality
00096 // between various storage managers handling indirect arrays.
00097 // At the moment it is used by StmanColumnIndArrayAipsIO and
00098 // StManColumnIndArrayMirAIO (the AipsIO and Miriad-like storage
00099 // manager, resp.), but it is not limited to them. It can equally
00100 // well be used for any other storage manager storing (indirect) arrays
00101 // via an StManArrayFile object.
00102 // </motivation>
00103 
00104 // <example>
00105 // Note that the following example is not really useful.
00106 // StIndArray is an internal class and should not be used by a casual user.
00107 // The example may however give a bit of insight.
00108 // <srcblock>
00109 // Array<Float> array(...);
00110 // // Create an StManArrayFile object to hold the arrays.
00111 // StManArrayFile stmanFile ("some.name", ByteIO::New);
00112 // // Create a still empty StIndArray object for an array.
00113 // StIndArray arrayRef(0);
00114 // // Define the shape and allocate a Float array.
00115 // // Put the array data.
00116 // arrayRef.setShape (stmanFile, TpFloat, array.shape());
00117 // arrayRef.putArrayfloatV (stmanFile, &array);
00118 // // Get the file offset of the array (for later use).
00119 // Int64 offset = arrayRef.fileOffset();
00120 // // Create an StIndArray object to read the array back.
00121 // // Of course, the same object could have been used for that purpose,
00122 // // but this shows how to create one for an existing file.
00123 // StIndArray arrayRef2(offset);
00124 // arrayRef2.getShape (stmanFile);             // read shape
00125 // Array<float> array2(arrayRef2.shape());     // create with correct size
00126 // arrayRef2.getArrayfloatV (stmanFile, &array2);
00127 // </srcblock>
00128 // </example>
00129 
00130 // <todo asof="$DATE:$">
00131 //# A List of bugs, limitations, extensions or planned refinements.
00132 //   <li> Reuse file storage when an array gets reshaped.
00133 //        This could be done when the array does not grow.
00134 //        It also requires a change in StManArrayFile.
00135 //   <li> Be smarter when accessing slices by not accessing a vector
00136 //        at a time, but by determining and accessing the largest
00137 //        possible consecutive area.
00138 // </todo>
00139 
00140 
00141 class StIndArray
00142 {
00143 public:
00144     // Construct the object with the given file offset.
00145     // A zero file offset means that no array has been defined yet.
00146     // That may be filled in later by setShape.
00147     StIndArray (Int64 fileOffset);
00148 
00149     // Copy constructor.
00150     StIndArray (const StIndArray&);
00151 
00152     // Assignment.
00153     StIndArray& operator= (const StIndArray&);
00154 
00155     ~StIndArray();
00156 
00157     // Get the shape.
00158     const IPosition& shape() const
00159         {return shape_p;}
00160 
00161     // Get the file offset.
00162     Int64 fileOffset() const
00163         {return fileOffset_p;}
00164 
00165     // Set the shape and allocate the array in the file.
00166     // This will define the array and fill in the file offset.
00167     // If the shape is already defined and does not change,
00168     // nothing is done and a False value is returned.
00169     // When the shape changes, the old file space is lost.
00170     Bool setShape (StManArrayFile&, int dataType, const IPosition& shape);
00171 
00172     // Read the shape if not read yet.
00173     void getShape (StManArrayFile& ios);
00174 
00175     // Get the reference count.
00176     uInt refCount (StManArrayFile& ios);
00177 
00178     // Increment the reference count.
00179     void incrementRefCount (StManArrayFile& ios);
00180 
00181     // Decrement the reference count.
00182     void decrementRefCount (StManArrayFile& ios);
00183 
00184     // Copy the data from another array.
00185     // An exception if thrown if the shapes do not match.
00186     void copyData (StManArrayFile& ios, int dataType, const StIndArray& other);
00187 
00188     // Get an array value from the file at the offset held in this object.
00189     // The buffer pointed to by dataPtr has to have the correct length
00190     // (which is guaranteed by the ArrayColumn get function).
00191     // <group>
00192     void getArrayBoolV     (StManArrayFile&, Array<Bool>* dataPtr);
00193     void getArrayuCharV    (StManArrayFile&, Array<uChar>* dataPtr);
00194     void getArrayShortV    (StManArrayFile&, Array<Short>* dataPtr);
00195     void getArrayuShortV   (StManArrayFile&, Array<uShort>* dataPtr);
00196     void getArrayIntV      (StManArrayFile&, Array<Int>* dataPtr);
00197     void getArrayuIntV     (StManArrayFile&, Array<uInt>* dataPtr);
00198     void getArrayfloatV    (StManArrayFile&, Array<float>* dataPtr);
00199     void getArraydoubleV   (StManArrayFile&, Array<double>* dataPtr);
00200     void getArrayComplexV  (StManArrayFile&, Array<Complex>* dataPtr);
00201     void getArrayDComplexV (StManArrayFile&, Array<DComplex>* dataPtr);
00202     void getArrayStringV   (StManArrayFile&, Array<String>* dataPtr);
00203     // </group>
00204 
00205     // Put an array value into the file at the offset held in this object.
00206     // The buffer pointed to by dataPtr has to have the correct length
00207     // (which is guaranteed by the ArrayColumn put function).
00208     // <group>
00209     void putArrayBoolV     (StManArrayFile&, const Array<Bool>* dataPtr);
00210     void putArrayuCharV    (StManArrayFile&, const Array<uChar>* dataPtr);
00211     void putArrayShortV    (StManArrayFile&, const Array<Short>* dataPtr);
00212     void putArrayuShortV   (StManArrayFile&, const Array<uShort>* dataPtr);
00213     void putArrayIntV      (StManArrayFile&, const Array<Int>* dataPtr);
00214     void putArrayuIntV     (StManArrayFile&, const Array<uInt>* dataPtr);
00215     void putArrayfloatV    (StManArrayFile&, const Array<float>* dataPtr);
00216     void putArraydoubleV   (StManArrayFile&, const Array<double>* dataPtr);
00217     void putArrayComplexV  (StManArrayFile&, const Array<Complex>* dataPtr);
00218     void putArrayDComplexV (StManArrayFile&, const Array<DComplex>* dataPtr);
00219     void putArrayStringV   (StManArrayFile&, const Array<String>* dataPtr);
00220     // </group>
00221 
00222     // Get a section of the array from the file at the offset held in
00223     // this object.
00224     // The buffer pointed to by dataPtr has to have the correct length
00225     // (which is guaranteed by the ArrayColumn getSlice function).
00226     // <group>
00227     void getSliceBoolV     (StManArrayFile&, const Slicer&,
00228                             Array<Bool>* dataPtr);
00229     void getSliceuCharV    (StManArrayFile&, const Slicer&,
00230                             Array<uChar>* dataPtr);
00231     void getSliceShortV    (StManArrayFile&, const Slicer&,
00232                             Array<Short>* dataPtr);
00233     void getSliceuShortV   (StManArrayFile&, const Slicer&,
00234                             Array<uShort>* dataPtr);
00235     void getSliceIntV      (StManArrayFile&, const Slicer&,
00236                             Array<Int>* dataPtr);
00237     void getSliceuIntV     (StManArrayFile&, const Slicer&,
00238                             Array<uInt>* dataPtr);
00239     void getSlicefloatV    (StManArrayFile&, const Slicer&,
00240                             Array<float>* dataPtr);
00241     void getSlicedoubleV   (StManArrayFile&, const Slicer&,
00242                             Array<double>* dataPtr);
00243     void getSliceComplexV  (StManArrayFile&, const Slicer&,
00244                             Array<Complex>* dataPtr);
00245     void getSliceDComplexV (StManArrayFile&, const Slicer&,
00246                             Array<DComplex>* dataPtr);
00247     void getSliceStringV   (StManArrayFile&, const Slicer&,
00248                             Array<String>* dataPtr);
00249     // </group>
00250 
00251     // Put a section of the array into the file at the offset held in
00252     // this object.
00253     // The buffer pointed to by dataPtr has to have the correct length
00254     // (which is guaranteed by the ArrayColumn putSlice function).
00255     // <group>
00256     void putSliceBoolV     (StManArrayFile&, const Slicer&,
00257                             const Array<Bool>* dataPtr);
00258     void putSliceuCharV    (StManArrayFile&, const Slicer&,
00259                             const Array<uChar>* dataPtr);
00260     void putSliceShortV    (StManArrayFile&, const Slicer&,
00261                             const Array<Short>* dataPtr);
00262     void putSliceuShortV   (StManArrayFile&, const Slicer&,
00263                             const Array<uShort>* dataPtr);
00264     void putSliceIntV      (StManArrayFile&, const Slicer&,
00265                             const Array<Int>* dataPtr);
00266     void putSliceuIntV     (StManArrayFile&, const Slicer&,
00267                             const Array<uInt>* dataPtr);
00268     void putSlicefloatV    (StManArrayFile&, const Slicer&,
00269                             const Array<float>* dataPtr);
00270     void putSlicedoubleV   (StManArrayFile&, const Slicer&,
00271                             const Array<double>* dataPtr);
00272     void putSliceComplexV  (StManArrayFile&, const Slicer&,
00273                             const Array<Complex>* dataPtr);
00274     void putSliceDComplexV (StManArrayFile&, const Slicer&,
00275                             const Array<DComplex>* dataPtr);
00276     void putSliceStringV   (StManArrayFile&, const Slicer&,
00277                             const Array<String>* dataPtr);
00278     // </group>
00279 
00280 private:
00281     Int64     fileOffset_p;      //# offset of shape in StManArrayFile
00282     uInt      arrOffset_p;       //# extra offset to the array
00283     //#                              0 = arrOffset and shape not known yet
00284     IPosition shape_p;           //# shape of the array
00285 
00286     // Get sliced data, i.e. get a section of an array.
00287     // This function is used by getSliceXXXV to have common functionality
00288     // in one function. It calls the given getVec function for each
00289     // chunk of data. In this way the bulk of type-independent code
00290     // is concentrated in getSliceData resulting in small
00291     // type-dependent functions.
00292     void getSliceData (StManArrayFile&, const Slicer& ns, void* value,
00293                        const IPosition& userArrayShape,
00294                        void (*getVec) (StManArrayFile&,
00295                                        Int64, uInt, uInt, uInt, uInt,
00296                                        void* dataPtr));
00297 
00298     // Get a (type-dependent) vector part of a slice.
00299     // This function is called for each chunk by putSliceData.
00300     // <group>
00301     static void getVecBoolV     (StManArrayFile&,
00302                                  Int64 fileOffset, uInt arrayStart,
00303                                  uInt length, uInt increment,
00304                                  uInt valueIndex, void* value);
00305     static void getVecuCharV    (StManArrayFile&,
00306                                  Int64 fileOffset, uInt arrayStart,
00307                                  uInt length, uInt increment,
00308                                  uInt valueIndex, void* value);
00309     static void getVecShortV    (StManArrayFile&,
00310                                  Int64 fileOffset, uInt arrayStart,
00311                                  uInt length, uInt increment,
00312                                  uInt valueIndex, void* value);
00313     static void getVecuShortV   (StManArrayFile&,
00314                                  Int64 fileOffset, uInt arrayStart,
00315                                  uInt length, uInt increment,
00316                                  uInt valueIndex, void* value);
00317     static void getVecIntV      (StManArrayFile&,
00318                                  Int64 fileOffset, uInt arrayStart,
00319                                  uInt length, uInt increment,
00320                                  uInt valueIndex, void* value);
00321     static void getVecuIntV     (StManArrayFile&,
00322                                  Int64 fileOffset, uInt arrayStart,
00323                                  uInt length, uInt increment,
00324                                  uInt valueIndex, void* value);
00325     static void getVecfloatV    (StManArrayFile&,
00326                                  Int64 fileOffset, uInt arrayStart,
00327                                  uInt length, uInt increment,
00328                                  uInt valueIndex, void* value);
00329     static void getVecdoubleV   (StManArrayFile&,
00330                                  Int64 fileOffset, uInt arrayStart,
00331                                  uInt length, uInt increment,
00332                                  uInt valueIndex, void* value);
00333     static void getVecComplexV  (StManArrayFile&,
00334                                  Int64 fileOffset, uInt arrayStart,
00335                                  uInt length, uInt increment,
00336                                  uInt valueIndex, void* value);
00337     static void getVecDComplexV (StManArrayFile&,
00338                                  Int64 fileOffset, uInt arrayStart,
00339                                  uInt length, uInt increment,
00340                                  uInt valueIndex, void* value);
00341     static void getVecStringV   (StManArrayFile&,
00342                                  Int64 fileOffset, uInt arrayStart,
00343                                  uInt length, uInt increment,
00344                                  uInt valueIndex, void* value);
00345     // </group>
00346 
00347     // Put sliced data, i.e. put a section of an array.
00348     // This function is used by putSlice to have common functionality
00349     // in one function. It calls the given in putVec function for
00350     // chunk of data. In this way the bulk of type-independent code
00351     // is concentrated in putSliceData resulting in small
00352     // type-dependent functions.
00353     void putSliceData (StManArrayFile&, const Slicer& ns, const void* value,
00354                        const IPosition& userArrayShape,
00355                        void (*putVec) (StManArrayFile&,
00356                                        Int64, uInt, uInt, uInt, uInt,
00357                                        const void* dataPtr));
00358 
00359     // Put a (type-dependent) vector part of a slice.
00360     // This function is called for each chunk by putSliceData.
00361     // <group>
00362     static void putVecBoolV     (StManArrayFile&,
00363                                  Int64 fileOffset, uInt arrayStart,
00364                                  uInt length, uInt increment,
00365                                  uInt valueIndex, const void* value);
00366     static void putVecuCharV    (StManArrayFile&,
00367                                  Int64 fileOffset, uInt arrayStart,
00368                                  uInt length, uInt increment,
00369                                  uInt valueIndex, const void* value);
00370     static void putVecShortV    (StManArrayFile&,
00371                                  Int64 fileOffset, uInt arrayStart,
00372                                  uInt length, uInt increment,
00373                                  uInt valueIndex, const void* value);
00374     static void putVecuShortV   (StManArrayFile&,
00375                                  Int64 fileOffset, uInt arrayStart,
00376                                  uInt length, uInt increment,
00377                                  uInt valueIndex, const void* value);
00378     static void putVecIntV      (StManArrayFile&,
00379                                  Int64 fileOffset, uInt arrayStart,
00380                                  uInt length, uInt increment,
00381                                  uInt valueIndex, const void* value);
00382     static void putVecuIntV     (StManArrayFile&,
00383                                  Int64 fileOffset, uInt arrayStart,
00384                                  uInt length, uInt increment,
00385                                  uInt valueIndex, const void* value);
00386     static void putVecfloatV    (StManArrayFile&,
00387                                  Int64 fileOffset, uInt arrayStart,
00388                                  uInt length, uInt increment,
00389                                  uInt valueIndex, const void* value);
00390     static void putVecdoubleV   (StManArrayFile&,
00391                                  Int64 fileOffset, uInt arrayStart,
00392                                  uInt length, uInt increment,
00393                                  uInt valueIndex, const void* value);
00394     static void putVecComplexV  (StManArrayFile&,
00395                                  Int64 fileOffset, uInt arrayStart,
00396                                  uInt length, uInt increment,
00397                                  uInt valueIndex, const void* value);
00398     static void putVecDComplexV (StManArrayFile&,
00399                                  Int64 fileOffset, uInt arrayStart,
00400                                  uInt length, uInt increment,
00401                                  uInt valueIndex, const void* value);
00402     static void putVecStringV   (StManArrayFile&,
00403                                  Int64 fileOffset, uInt arrayStart,
00404                                  uInt length, uInt increment,
00405                                  uInt valueIndex, const void* value);
00406     // </group>
00407         
00408     // Throw an exception if the shape of the given array and the table
00409     // array (slice) are not equal.
00410     void checkShape (const IPosition& userArrayShape,
00411                      const IPosition& tableArrayShape) const;
00412 };
00413 
00414 
00415 
00416 
00417 } //# NAMESPACE CASA - END
00418 
00419 #endif