casa
$Rev:20696$
|
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