casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
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_CFBUFFER_H
00029 #define SYNTHESIS_CFBUFFER_H
00030 #include <synthesis/TransformMachines/SynthesisError.h>
00031 #include <coordinates/Coordinates/CoordinateSystem.h>
00032 #include <synthesis/TransformMachines/CFDefs.h>
00033 #include <synthesis/TransformMachines/CFCell.h>
00034 #include <synthesis/TransformMachines/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 <synthesis/MSVis/VisBuffer.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 
00046 // <prerequisite>
00047 // </prerequisite>
00048 //
00049 // <etymology> 
00050 //
00051 //  CFBuffer is basic in-memory storage for convolution functions
00052 //  as a function of polarization and frequency at a particular value
00053 //  of Parallactic Angle.
00054 //
00055 //</etymology>
00056 //
00057 // <synopsis> 
00058 //
00059 // The CFBuffer class encapsulates the storage and associated
00060 // auxillary information required for the convolution functions.  The
00061 // <linto class=CFStore>CFStore</linkto> class is a collection of
00062 // CFBuffer objects.  A collection of CFStore objects is held and
00063 // managed by the <linto class=FTMachine>FTMachine</linkto> and the
00064 // appropriate one, depending on the Time/PA value, polarization and
00065 // frequency of the data in the <linkto
00066 // class=VisBuffer>VisBuffer</linkto>, is supplied to the <linkto
00067 // class=VisibilityResampler>VisibilityResampler</linkto> object of
00068 // re-sampling the data onto a grid (or vice versa).
00069 //
00070 // This buffer holds the convolution functions for the required range
00071 // of frequencies and polarizations at a particular Parallactic Angle
00072 // (or time), for one W-value and for a single baseline (antenna
00073 // pair).
00074 //
00075 // Conceptually, this object holds the convolution functions
00076 // parameterized by the properties of the electromagnetic radiation
00077 // (polarization state, frequency and the w-value which is the Fresnel
00078 // term and implicitly a function of the frequency).  The <linkto
00079 // class=CFStore>CFStore</linkto> object holds a list of this object
00080 // index by the telescope related parameters (antenna1,
00081 // antenna2, Parallactic Angle or Time, etc.).
00082 //
00083 //</synopsis>
00084 //
00085 // <example>
00086 // </example>
00087 //
00088 // <motivation>
00089 //
00090 // To factor out the details of effecient in-memory storage of the
00091 // convolution functions into a separate class.  This class can then
00092 // be optmized by specializations for various types of convolution
00093 // functions and imaging algorithms without the need to change the
00094 // imaging framework.
00095 //
00096 // </motivation>
00097 //
00098 using namespace casa::CFDefs;
00099 using namespace std;
00100 namespace casa { //# NAMESPACE CASA - BEGIN
00101   //  template <class T>
00102   typedef Complex TT;
00103   class CFBuffer
00104   {
00105   public:
00106     //
00107     //========================= Administrative Parts ==========================
00108     //------------------------------------------------------------------
00109     //
00110     CFBuffer(): wValues_p(), maxXSupport_p(-1), maxYSupport_p(-1), pointingOffset_p(), cfHitsStats(),
00111                 freqNdxMapsReady_p(False), freqNdxMap_p(), conjFreqNdxMap_p()
00112     {};
00113 
00114     CFBuffer(Int maxXSup, Int maxYSup):
00115       wValues_p(), maxXSupport_p(maxXSup), maxYSupport_p(maxYSup), pointingOffset_p(), cfHitsStats(),
00116       freqNdxMapsReady_p(False), freqNdxMap_p(), conjFreqNdxMap_p()
00117     {
00118       // storage_p.resize(1,1,1); 
00119       // storage_p(0,0,0) = new Array<TT>(dataPtr);
00120       // coordSys_p.resize(1,1,1); 
00121       // coordSys_p(0,0,0) = cs;
00122     };
00123 
00124     ~CFBuffer() 
00125     {
00126       LogIO log_l(LogOrigin("CFBuffer","~CFBuffer[R&D]"));
00127       log_l << "CF Hits stats gathered: " << cfHitsStats << endl;
00128     };
00129 
00130     CountedPtr<CFBuffer> clone();
00131     void allocCells(const Cube<CountedPtr<CFCell> >& cells);
00132     void setParams(const CFBuffer& other);
00133     //
00134     //============================= Functional Parts ============================
00135     //------------------------------------------------------------------
00136     //
00137     //    CFBuffer& operator=(const CFBuffer& other);
00138     //
00139     // Get the single convolution function as an Array<T> for the
00140     // supplied value of the frequency and the muellerElement.
00141     // Mueller element is essentially the polarization product, but
00142     // can be any of the of 16 elements of the outer product.
00143     //
00144     //-------------------------------------------------------------------------
00145     //
00146     inline Int nChan() {return nChan_p;}
00147     inline Int nW() {return nW_p;}
00148     inline Int nMuellerElements() {return nPol_p;}
00149     inline IPosition shape() {IPosition shp(3,nChan_p, nW_p, nPol_p); return shp;}
00150 
00151     inline Vector<Double> getFreqList() {return freqValues_p;};
00152     inline Vector<Double> getWList() {return wValues_p;};
00153 
00154     CFCell& getCFCell(const Double& freqVal, const Double& wValue, 
00155                       const Int & muellerElement); 
00156     // muellerElement: (i,j) of the Mueller Matrix
00157     CountedPtr<CFCell>& getCFCellPtr(const Double& freqVal, const Double& wValue, 
00158                                      const Int & muellerElement); 
00159     CFCell& getCFCell(const Int& i, const Int& j, const Int& k);
00160     CountedPtr<CFCell >& getCFCellPtr(const Int& i, const Int& j, const Int& k);
00161 
00162     //=========================================================================
00163     Array<TT>& getCF(const Double& freqVal, const Double& wValue, 
00164                      const Int & muellerElement)
00165     {return *(getCFCell(freqVal, wValue, muellerElement).storage_p);}
00166     // muellerElement: (i,j) of the Mueller Matrix
00167 
00168     CountedPtr<Array<TT> >& getCFPtr(const Double& freqVal, const Double& wValue, 
00169                                      const Int & muellerElement) 
00170     {return getCFCellPtr(freqVal, wValue, muellerElement)->storage_p;}
00171 
00172     Array<TT>& getCF(const Int& i, const Int& j, const Int& k)
00173     {return *(getCFCell(i,j,k).storage_p);}
00174     
00175     CountedPtr<Array<TT> >& getCFPtr(const Int& i, const Int& j, const Int& k)
00176     {return getCFCellPtr(i,j,k)->storage_p;}
00177 
00178 
00179     //
00180     // Get the parameters of a the CFs indexed by values.  The version
00181     // which returns also the Coordinate System associated with the
00182     // CFs are slow (CoordinateSystem::operator=() is surprisingly
00183     // expensive!).  So do not use this in tight loops.  If it is
00184     // required, use the version without the co-ordinate system below.
00185     //
00186     void getParams(CoordinateSystem& cs, Float& sampling, 
00187                    Int& xSupport, Int& ySupport, 
00188                    const Double& freqVal, const Double& wValue, 
00189                    const Int& muellerElement);
00190     //-------------------------------------------------------------------------
00191     // Get CF by directly indexing in the list of CFs (data vector)
00192     inline void getParams(CoordinateSystem& cs, Float& sampling, 
00193                           Int& xSupport, Int& ySupport, 
00194                           const Int& i, const Int& j, const Int& k)
00195     {
00196       cs = cfCells_p(i,j,k)->coordSys_p;
00197       sampling = cfCells_p(i,j,k)->sampling_p;
00198       xSupport = cfCells_p(i,j,k)->xSupport_p;
00199       ySupport = cfCells_p(i,j,k)->ySupport_p;
00200     }
00201     void getParams(Double& freqVal, Float& sampling, 
00202                    Int& xSupport, Int& ySupport, 
00203                    const Int& iFreq, const Int& iW, const Int& iPol)
00204     {
00205       sampling = cfCells_p(iFreq,iW,iPol)->sampling_p;
00206       xSupport = cfCells_p(iFreq,iW,iPol)->xSupport_p;
00207       ySupport = cfCells_p(iFreq,iW,iPol)->ySupport_p;
00208       freqVal = freqValues_p(iFreq);
00209     }
00210 
00211     inline void getCoordList(Vector<Double>& freqValues, Vector<Double>& wValues,
00212                              PolMapType& muellerElementsIndex, PolMapType& muellerElements, 
00213                              PolMapType& conjMuellerElementsIndex, PolMapType& conjMuellerElements, 
00214                              Double& fIncr, Double& wIncr)
00215     {
00216       freqValues.assign(freqValues_p);wValues.assign(wValues_p);
00217       muellerElements.assign(muellerElements_p);         muellerElementsIndex.assign(muellerElementsIndex_p);
00218       conjMuellerElements.assign(conjMuellerElements_p); conjMuellerElementsIndex.assign(conjMuellerElementsIndex_p);
00219       fIncr = freqValIncr_p; wIncr = wValIncr_p;
00220     }
00221 
00222     Int nearestNdx(const Double& val, const Vector<Double>& valList, const Double& incr);
00223 
00224     Int nearestFreqNdx(const Double& freqVal) ;
00225 
00226     inline Int nearestWNdx(const Double& wVal) 
00227     {
00228       //      return SynthesisUtils::nint(sqrt(wValIncr_p*abs(wVal)));
00229       return (int)(sqrt(wValIncr_p*abs(wVal)));
00230     }
00231 
00232     Double nearest(Bool& found, const Double& val, const Vector<Double>& valList, const Double& incr);
00233 
00234     inline Double nearestFreq(Bool& found, const Double& freqVal)
00235     {return nearest(found, freqVal, freqValues_p, freqValIncr_p);}
00236 
00237     inline Double nearestWVal(Bool& found, const Double& wVal)
00238     {return nearest(found, wVal, wValues_p, wValIncr_p);}
00239 
00240     //-------------------------------------------------------------------------
00241     //
00242     // Generate a map for the given frequency and Mueller element list
00243     // to the index in the internal list of CFs.  This can be used in
00244     // tight loops to get get direct access to the required CF.
00245     //
00246     void makeCFBufferMap(const Vector<Double>& freqVals, 
00247                          const Vector<Double>& wValues,
00248                          const MuellerMatrixType& muellerElements);
00249     //-------------------------------------------------------------------------
00250     //
00251     // Add a Convolution Function with associated parameters.
00252     //
00253     void addCF(Array<TT>*, //dataPtr, 
00254                CoordinateSystem&,// cs, 
00255                Float& ,//sampling, 
00256                Int& ,//xSupport, 
00257                Int& ,//ySupport,
00258                Double& ,//freqValue, 
00259                Double& ,//wValue, 
00260                Int& //muellerElement
00261                )
00262     {throw(AipsError("CFBuffer::addCF called"));}
00263     //-------------------------------------------------------------------------
00264     //
00265     void resize(const IPosition& size) {cfCells_p.resize(size);};
00266     void resize(const Double& wIncr, const Double& freqIncr,
00267                 const Vector<Double>& wValues, 
00268                 const Vector<Double>& freqValues,
00269                 const PolMapType& muellerElements,
00270                 const PolMapType& muellerElementsIndex,
00271                 const PolMapType& conjMuellerElements,
00272                 const PolMapType& conjMuellerElementsIndex);
00273     Int noOfMuellerElements(const PolMapType& muellerElements);
00274     //-------------------------------------------------------------------------
00275     // Set only the CF parameters.  Return to index of the CF that was set.
00276     //
00277     RigidVector<Int, 3> setParams(const Int& i, const Int& j, const Int& ipx, const Int& ipy,
00278                                   CoordinateSystem& cs, Float& sampling,
00279                                   Int& xSupport, Int& ySupport,
00280                                   const Double& freqValue, const Double& wValue, 
00281                                   const Int& muellerElement);
00282     void setPointingOffset(const Vector<Double>& offset) 
00283     {pointingOffset_p.assign(offset);};
00284     Vector<Double> getPointingOffset() {return pointingOffset_p;};
00285     //
00286     // Also set the size of the CF in x and y.
00287     //
00288     void setParams(Int& nx, Int& ny, CoordinateSystem& cs, Float& sampling, 
00289                    Int& xSupport, Int& ySupport, 
00290                    const Double& freqVal, const Double& wValue, 
00291                    const Int& muellerElement);
00292     RigidVector<Int,3> getIndex(const Double& freqVal, const Double& wValue, 
00293                                 const Int& muellerElement);
00294     //-------------------------------------------------------------------------
00295     //
00296     // Copy just the parameters from other to this.
00297     //
00298     void copyParams(const CFBuffer& other)
00299     {
00300       cfCells_p = other.cfCells_p;
00301       // coordSys_p = other.coordSys_p; sampling_p.assign(other.sampling_p); 
00302       // xSupport_p.assign(other.xSupport_p); ySupport_p.assign(other.ySupport_p);
00303       maxXSupport_p=other.maxXSupport_p;  maxYSupport_p=other.maxYSupport_p; 
00304     }
00305     //-------------------------------------------------------------------------
00306     //
00307     // Write the description of the storage on the supplied ostream.
00308     // Used mostly for debugging, but might be useful for user
00309     // feedback/logging.
00310     //
00311     void show(const char *Mesg=NULL,ostream &os=cerr);
00312     //
00313     // Returns True if the internal storage is not yet initialized.
00314     //
00315     Bool null() {return (cfCells_p.nelements() == 0);};
00316 
00317     Cube<CountedPtr<CFCell> >& getStorage() {return cfCells_p;};
00318     void makePersistent(const char *dir);
00319 
00320     void initMaps(const VisBuffer& vb,const Matrix<Double>& freqSelection,const Double& imRefFreq);
00321 
00322     inline Int nearestFreqNdx(const Int& spw, const Int& chan, const Bool conj=False)
00323     {
00324       if (conj) return conjFreqNdxMap_p[spw][chan];
00325       else  return freqNdxMap_p[spw][chan];
00326     }
00327     //
00328     //============================= Protected Parts ============================
00329     //------------------------------------------------------------------
00330     //
00331   protected:
00332     //
00333     // The storage buffer for the pixel values in CFCell is Array<T>
00334     // rather than Matrix<T> to accomodate rotationally symmetric CFs
00335     // (like the Prolate Spheroidal) which can be held as a Vector of
00336     // values.
00337     //
00338     Cube<CountedPtr<CFCell> > cfCells_p;// freqValues x wValues x muellerElements
00339     Vector<Double> wValues_p, freqValues_p;
00340     PolMapType muellerElements_p, muellerElementsIndex_p,conjMuellerElements_p,conjMuellerElementsIndex_p; 
00341     Double wValIncr_p, freqValIncr_p;
00342     MuellerMatrixType muellerMask_p;
00343 
00344     Int nPol_p, nChan_p, nW_p, maxXSupport_p, maxYSupport_p;
00345     Vector<Double> pointingOffset_p;
00346     Cube<Int> cfHitsStats;
00347     Bool freqNdxMapsReady_p;
00348     Vector<Vector<Int> > freqNdxMap_p, conjFreqNdxMap_p;
00349   };
00350 } //# NAMESPACE CASA - END
00351 #endif