CFBuffer.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //# CFBuffer.h: Definition of the CFBuffer class
00003 //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003
00004 //# Associated Universities, Inc. Washington DC, USA.
00005 //#
00006 //# This library is free software; you can redistribute it and/or modify it
00007 //# under the terms of the GNU Library General Public License as published by
00008 //# the Free Software Foundation; either version 2 of the License, or (at your
00009 //# option) any later version.
00010 //#
00011 //# This library is distributed in the hope that it will be useful, but WITHOUT
00012 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 //# License for more details.
00015 //#
00016 //# You should have received a copy of the GNU Library General Public License
00017 //# along with this library; if not, write to the Free Software Foundation,
00018 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00019 //#
00020 //# Correspondence concerning AIPS++ should be addressed as follows:
00021 //#        Internet email: aips2-request@nrao.edu.
00022 //#        Postal address: AIPS++ Project Office
00023 //#                        National Radio Astronomy Observatory
00024 //#                        520 Edgemont Road
00025 //#                        Charlottesville, VA 22903-2475 USA
00026 //#
00027 //# $Id$
00028 #ifndef SYNTHESIS_TRANSFORM2_CFBUFFER_H
00029 #define SYNTHESIS_TRANSFORM2_CFBUFFER_H
00030 #include <synthesis/TransformMachines/SynthesisError.h>
00031 #include <coordinates/Coordinates/CoordinateSystem.h>
00032 #include <synthesis/TransformMachines2/CFDefs.h>
00033 #include <synthesis/TransformMachines/CFCell.h>
00034 #include <synthesis/TransformMachines2/Utils.h>
00035 #include <images/Images/ImageInterface.h>
00036 #include <casa/Utilities/CountedPtr.h>
00037 #include <casa/Utilities/Sort.h>
00038 #include <casa/Logging/LogOrigin.h>
00039 #include <msvis/MSVis/VisBuffer2.h>
00040 #include <casa/Logging/LogSink.h>
00041 #include <casa/Logging/LogIO.h>
00042 
00043 //
00044 // <summary> defines interface for the storage for convolution functions </summary>
00045 // <use visibility=export>
00046 //
00047 // <prerequisite>
00048 // </prerequisite>
00049 //
00050 // <etymology> 
00051 //
00052 //  CFBuffer is the basic in-memory storage for convolution functions
00053 //  as a function of polarization, W-value and frequency at a
00054 //  particular value of Parallactic Angle and baseline type.
00055 //
00056 //</etymology>
00057 //
00058 // <synopsis> 
00059 //
00060 // The CFBuffer class encapsulates the storage and associated
00061 // auxillary information required for the convolution functions.  The
00062 // <linto class=CFStore>CFStore</linkto> class is a collection of
00063 // CFBuffer objects.  A collection of CFStore objects is held and
00064 // managed by the <linto class=FTMachine>FTMachine</linkto> and the
00065 // appropriate one, depending on the Time/PA value, polarization and
00066 // frequency of the data in the <linkto
00067 // class=VisBuffer2>VisBuffer2</linkto>, is supplied to the <linkto
00068 // class=VisibilityResampler>VisibilityResampler</linkto> object for
00069 // re-sampling the data onto a grid (or vice versa).
00070 //
00071 // Conceptually, this object holds the convolution functions
00072 // parameterized by the properties of the electromagnetic radiation
00073 // (polarization state, frequency and the w-value which is the Fresnel
00074 // term and implicitly a function of the frequency).  The <linkto
00075 // class=CFStore>CFStore</linkto> object holds a list of this object
00076 // index by the telescope related parameters (antenna1,
00077 // antenna2, Parallactic Angle or Time, etc.).
00078 //
00079 //</synopsis>
00080 //
00081 // <example>
00082 // </example>
00083 //
00084 // <motivation>
00085 //
00086 // To factor out the details of effecient in-memory storage of the
00087 // convolution functions into a separate class.  This class can then
00088 // be optmized by specializations for various types of convolution
00089 // functions and imaging algorithms without the need to change the
00090 // imaging framework.
00091 //
00092 // </motivation>
00093 //
00094 
00095 using namespace std;
00096 using namespace casa::vi;
00097 namespace casa { //# NAMESPACE CASA - BEGIN
00098   //  template <class T>
00099   typedef Complex TT;
00100   namespace refim{
00101     using namespace CFDefs;
00102 
00103   struct CFBStruct {
00104     CFCStruct *CFBStorage;
00105     int shape[3];
00106     Double *freqValues, *wValues, *pointingOffset;
00107     Double fIncr, wIncr;
00108     Int **muellerElementsIndex, **muellerElements, 
00109       **conjMuellerElementsIndex, **conjMuellerElements,
00110       **conjFreqNdxMap, **freqNdxMap;
00111     Int nMueller;
00112     
00113 
00114     CFCStruct* getCFB(int i, int j, int k)
00115     { return &(CFBStorage[i + (shape[1]-1)*j + (shape[1]-1)*(shape[2]-1)*k]);}
00116     //    { return &(CFBStorage[i + (shape[1]-1)*j + (shape[2]-1)*k]);}
00117   } ;
00118 
00119   class CFBuffer
00120   {
00121   public:
00122     //
00123     //========================= Administrative Parts ==========================
00124     //------------------------------------------------------------------
00125     //
00126     CFBuffer(): wValues_p(), maxXSupport_p(-1), maxYSupport_p(-1), pointingOffset_p(), cfHitsStats(),
00127                 freqNdxMapsReady_p(False), freqNdxMap_p(), conjFreqNdxMap_p()
00128     {};
00129     
00130     CFBuffer(Int maxXSup, Int maxYSup):
00131       wValues_p(), maxXSupport_p(maxXSup), maxYSupport_p(maxYSup), pointingOffset_p(), cfHitsStats(),
00132       freqNdxMapsReady_p(False), freqNdxMap_p(), conjFreqNdxMap_p()
00133     {
00134       // storage_p.resize(1,1,1); 
00135       // storage_p(0,0,0) = new Array<TT>(dataPtr);
00136       // coordSys_p.resize(1,1,1); 
00137       // coordSys_p(0,0,0) = cs;
00138     };
00139     
00140     ~CFBuffer() 
00141     {
00142       //cerr << "############### " << "~CFBuffer() called" << endl;
00143       // LogIO log_l(LogOrigin("CFBuffer","~CFBuffer[R&D]"));
00144       // log_l << "CF Hits stats gathered: " << cfHitsStats << endl;
00145     };
00146     
00147     CountedPtr<CFBuffer> clone();
00148     void allocCells(const Cube<CountedPtr<CFCell> >& cells);
00149     void setParams(const CFBuffer& other);
00150     //
00151     //============================= Functional Parts ============================
00152     //------------------------------------------------------------------
00153     //
00154     //    CFBuffer& operator=(const CFBuffer& other);
00155     //
00156     // Get the single convolution function as an Array<T> for the
00157     // supplied value of the frequency and the muellerElement.
00158     // Mueller element is essentially the polarization product, but
00159     // can be any of the of 16 elements of the outer product.
00160     //
00161     //-------------------------------------------------------------------------
00162     //
00163     inline Int nChan() {return nChan_p;}
00164     inline Int nW() {return nW_p;}
00165     inline Int nMuellerElements() {return nPol_p;}
00166     inline IPosition shape() {IPosition shp(3,nChan_p, nW_p, nPol_p); return shp;}
00167     
00168     inline Vector<Double> getFreqList() {return freqValues_p;};
00169     inline Vector<Double> getWList() {return wValues_p;};
00170     
00171     CFCell& getCFCell(const Double& freqVal, const Double& wValue, 
00172                       const Int & muellerElement); 
00173     // muellerElement: (i,j) of the Mueller Matrix
00174     CountedPtr<CFCell>& getCFCellPtr(const Double& freqVal, const Double& wValue, 
00175                                      const Int & muellerElement); 
00176     CFCell& operator()(const Int& i, const Int& j, const Int& k) {return *cfCells_p(i,j,k);}
00177     CFCell& getCFCell(const Int& i, const Int& j, const Int& k);
00178 
00179     CountedPtr<CFCell >& getCFCellPtr(const Int& i, const Int& j, const Int& k);
00180     
00181     //=========================================================================
00182     Array<TT>& getCF(const Double& freqVal, const Double& wValue, 
00183                      const Int & muellerElement)
00184     {return *(getCFCell(freqVal, wValue, muellerElement).storage_p);}
00185     // muellerElement: (i,j) of the Mueller Matrix
00186     
00187     CountedPtr<Array<TT> >& getCFPtr(const Double& freqVal, const Double& wValue, 
00188                                      const Int & muellerElement) 
00189     {return getCFCellPtr(freqVal, wValue, muellerElement)->storage_p;}
00190     
00191     Array<TT>& getCF(const Int& i, const Int& j, const Int& k)
00192     {return *(getCFCell(i,j,k).storage_p);}
00193     
00194     CountedPtr<Array<TT> >& getCFPtr(const Int& i, const Int& j, const Int& k)
00195     {return getCFCellPtr(i,j,k)->storage_p;}
00196     
00197     
00198     //
00199     // Get the parameters of a the CFs indexed by values.  The version
00200     // which returns also the Coordinate System associated with the
00201     // CFs are slow (CoordinateSystem::operator=() is surprisingly
00202     // expensive!).  So do not use this in tight loops.  If it is
00203     // required, use the version without the co-ordinate system below.
00204     //
00205     void getParams(CoordinateSystem& cs, Float& sampling, 
00206                    Int& xSupport, Int& ySupport, 
00207                    const Double& freqVal, const Double& wValue, 
00208                    const Int& muellerElement);
00209     //-------------------------------------------------------------------------
00210     // Get CF by directly indexing in the list of CFs (data vector)
00211     inline void getParams(CoordinateSystem& cs, Float& sampling, 
00212                           Int& xSupport, Int& ySupport, 
00213                           const Int& i, const Int& j, const Int& k)
00214     {
00215       cs = cfCells_p(i,j,k)->coordSys_p;
00216       sampling = cfCells_p(i,j,k)->sampling_p;
00217       xSupport = cfCells_p(i,j,k)->xSupport_p;
00218       ySupport = cfCells_p(i,j,k)->ySupport_p;
00219     }
00220     void getParams(Double& freqVal, Float& sampling, 
00221                    Int& xSupport, Int& ySupport, 
00222                    const Int& iFreq, const Int& iW, const Int& iPol)
00223     {
00224       sampling = cfCells_p(iFreq,iW,iPol)->sampling_p;
00225       xSupport = cfCells_p(iFreq,iW,iPol)->xSupport_p;
00226       ySupport = cfCells_p(iFreq,iW,iPol)->ySupport_p;
00227       freqVal = freqValues_p(iFreq);
00228     }
00229     
00230     inline void getCoordList(Vector<Double>& freqValues, Vector<Double>& wValues,
00231                              PolMapType& muellerElementsIndex, PolMapType& muellerElements, 
00232                              PolMapType& conjMuellerElementsIndex, PolMapType& conjMuellerElements, 
00233                              Double& fIncr, Double& wIncr)
00234     {
00235       freqValues.assign(freqValues_p);wValues.assign(wValues_p);
00236       muellerElements.assign(muellerElements_p);         muellerElementsIndex.assign(muellerElementsIndex_p);
00237       conjMuellerElements.assign(conjMuellerElements_p); conjMuellerElementsIndex.assign(conjMuellerElementsIndex_p);
00238       fIncr = freqValIncr_p; wIncr = wValIncr_p;
00239     }
00240     
00241     Int nearestNdx(const Double& val, const Vector<Double>& valList, const Double& incr);
00242     
00243     Int nearestFreqNdx(const Double& freqVal) ;
00244     
00245     inline Int nearestWNdx(const Double& wVal) 
00246     {
00247       //      return SynthesisUtils::nint(sqrt(wValIncr_p*abs(wVal)));
00248       return max(0,min((int)(sqrt(wValIncr_p*abs(wVal))),wValues_p.nelements())-1);
00249       // Int ndx=(int)(sqrt(wValIncr_p*abs(wVal)));
00250       // if ((uInt)ndx >= wValues_p.nelements())
00251       //        cerr << endl << endl << ndx << " " <<  wVal << " " << wValIncr_p << endl << endl;
00252       // return min(ndx,wValues_p.nelements()-1);
00253     }
00254     
00255     Double nearest(Bool& found, const Double& val, const Vector<Double>& valList, const Double& incr);
00256     
00257     inline Double nearestFreq(Bool& found, const Double& freqVal)
00258     {return nearest(found, freqVal, freqValues_p, freqValIncr_p);}
00259     
00260     inline Double nearestWVal(Bool& found, const Double& wVal)
00261     {return nearest(found, wVal, wValues_p, wValIncr_p);}
00262     
00263     //-------------------------------------------------------------------------
00264     //
00265     // Generate a map for the given frequency and Mueller element list
00266     // to the index in the internal list of CFs.  This can be used in
00267     // tight loops to get get direct access to the required CF.
00268     //
00269     void makeCFBufferMap(const Vector<Double>& freqVals, 
00270                          const Vector<Double>& wValues,
00271                          const MuellerMatrixType& muellerElements);
00272     //-------------------------------------------------------------------------
00273     //
00274     // Add a Convolution Function with associated parameters.
00275     //
00276     void addCF(Array<TT>*, //dataPtr, 
00277                CoordinateSystem&,// cs, 
00278                Float& ,//sampling, 
00279                Int& ,//xSupport, 
00280                Int& ,//ySupport,
00281                Double& ,//freqValue, 
00282                Double& ,//wValue, 
00283                Int& //muellerElement
00284                )
00285     {throw(AipsError("CFBuffer::addCF called"));}
00286     //-------------------------------------------------------------------------
00287     //
00288     void resize(const IPosition& size) {cfCells_p.resize(size);};
00289     void resize(const Double& wIncr, const Double& freqIncr,
00290                 const Vector<Double>& wValues, 
00291                 const Vector<Double>& freqValues,
00292                 const PolMapType& muellerElements,
00293                 const PolMapType& muellerElementsIndex,
00294                 const PolMapType& conjMuellerElements,
00295                 const PolMapType& conjMuellerElementsIndex);
00296     Int noOfMuellerElements(const PolMapType& muellerElements);
00297     //-------------------------------------------------------------------------
00298     // Set only the CF parameters.  Return to index of the CF that was set.
00299     //
00300     RigidVector<Int, 3> setParams(const Int& i, const Int& j, const Int& ipx, const Int& ipy,
00301                                   CoordinateSystem& cs, Float& sampling,
00302                                   Int& xSupport, Int& ySupport,
00303                                   const Double& freqValue, const Double& wValue, 
00304                                   const Int& muellerElement,
00305                                   const String& fileName=String(),
00306                                   const Double& conjFreq=0.0,
00307                                   const Int& conjPol=-1,
00308                                   const String& telescopeName=String(),
00309                                   const Float& diameter=25.0);
00310     // RigidVector<Int, 3> setParams(const Int& inu, const Int& iw, const Int& muellerElement,
00311     //                            const TableRecord& miscInfo);
00312     void setPointingOffset(const Vector<Double>& offset) 
00313     {pointingOffset_p.assign(offset);};
00314     Vector<Double> getPointingOffset() {return pointingOffset_p;};
00315     //
00316     // Also set the size of the CF in x and y.
00317     //
00318     void setParams(Int& nx, Int& ny, CoordinateSystem& cs, Float& sampling, 
00319                    Int& xSupport, Int& ySupport, 
00320                    const Double& freqVal, const Double& wValue, 
00321                    const Int& muellerElement,
00322                    const String& fileName);
00323     void setPA(Float& pa);
00324     RigidVector<Int,3> getIndex(const Double& freqVal, const Double& wValue, 
00325                                 const Int& muellerElement);
00326     //-------------------------------------------------------------------------
00327     //
00328     // Copy just the parameters from other to this.
00329     //
00330     void copyParams(const CFBuffer& other)
00331     {
00332       cfCells_p = other.cfCells_p;
00333       // coordSys_p = other.coordSys_p; sampling_p.assign(other.sampling_p); 
00334       // xSupport_p.assign(other.xSupport_p); ySupport_p.assign(other.ySupport_p);
00335       maxXSupport_p=other.maxXSupport_p;  maxYSupport_p=other.maxYSupport_p; 
00336     }
00337     //-------------------------------------------------------------------------
00338     //
00339     // Write the description of the storage on the supplied ostream.
00340     // Used mostly for debugging, but might be useful for user
00341     // feedback/logging.
00342     //
00343     void show(const char *Mesg=NULL,ostream &os=cerr);
00344     //
00345     // Returns True if the internal storage is not yet initialized.
00346     //
00347     Bool null() {return (cfCells_p.nelements() == 0);};
00348     
00349     Cube<CountedPtr<CFCell> >& getStorage() {return cfCells_p;};
00350     void makePersistent(const char *dir, const char *cfName="");
00351     
00352     void primeTheCache();
00353     void initMaps(const VisBuffer2& vb,const Matrix<Double>& freqSelection,const Double& imRefFreq);
00354     void initPolMaps(PolMapType& polMap, PolMapType& conjPolMap);
00355     //
00356     // For CUDA kernel
00357     //
00358     void getFreqNdxMaps(Vector<Vector<Int> >& freqNdx, Vector<Vector<Int> >& conjFreqNdx);
00359     inline Int nearestFreqNdx(const Int& spw, const Int& chan, const Bool conj=False)
00360     {
00361       if (conj) return conjFreqNdxMap_p[spw][chan];
00362       else  return freqNdxMap_p[spw][chan];
00363     }
00364     
00365     void getAsStruct(CFBStruct& st);
00366     
00367     static void initCFBStruct(CFBStruct& cfbSt) 
00368     {
00369       cfbSt.CFBStorage=NULL;
00370       cfbSt.freqValues=NULL;
00371       cfbSt.wValues=NULL;
00372       cfbSt.muellerElementsIndex=NULL;
00373       cfbSt.muellerElements=NULL;
00374       cfbSt.conjMuellerElementsIndex=NULL;
00375       cfbSt.conjMuellerElements=NULL;
00376       cfbSt.shape[0]=cfbSt.shape[1]=cfbSt.shape[2]=0;
00377       cfbSt.fIncr=cfbSt.wIncr=0.0;
00378     }
00379     void fill(const Int& nx, const Int& ny, 
00380               const Vector<Double>& freqValues,
00381               const Vector<Double>& wValues,
00382               const PolMapType& muellerElements);
00383     
00384     IPosition getShape() {return cfCells_p.shape();}
00385     //
00386     //============================= Protected Parts ============================
00387     //------------------------------------------------------------------
00388     //
00389   protected:
00390     //
00391     // The storage buffer for the pixel values in CFCell is Array<T>
00392     // rather than Matrix<T> to accomodate rotationally symmetric CFs
00393     // (like the Prolate Spheroidal) which can be held as a Vector of
00394     // values.
00395     //
00396     Cube<CountedPtr<CFCell> > cfCells_p;// freqValues x wValues x muellerElements
00397     Vector<Double> wValues_p, freqValues_p;
00398     PolMapType muellerElements_p, muellerElementsIndex_p,conjMuellerElements_p,conjMuellerElementsIndex_p; 
00399     Double wValIncr_p, freqValIncr_p;
00400     MuellerMatrixType muellerMask_p;
00401     
00402     Int nPol_p, nChan_p, nW_p, maxXSupport_p, maxYSupport_p;
00403     Vector<Double> pointingOffset_p;
00404     Cube<Int> cfHitsStats;
00405     Bool freqNdxMapsReady_p;
00406     Vector<Vector<Int> > freqNdxMap_p, conjFreqNdxMap_p;
00407     void ASSIGNVVofI(Int** &target,Vector<Vector<Int> >& source, Bool& doAlloc);
00408   };
00409 
00410   // declare a commonly used template extern
00411     //    extern template class Array<CountedPtr<CFBuffer> >;
00412   
00413   } //# NAMESPACE CASA - END
00414 }
00415 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1