casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
WProjectFT.h
Go to the documentation of this file.
00001 //# WProjectFT.h: Definition for WProjectFT
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2002
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 adressed 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 //#
00027 //# $Id$
00028 
00029 #ifndef SYNTHESIS_WPROJECTFT_H
00030 #define SYNTHESIS_WPROJECTFT_H
00031 
00032 #include <synthesis/TransformMachines/FTMachine.h>
00033 #include <casa/Arrays/Matrix.h>
00034 #include <scimath/Mathematics/FFTServer.h>
00035 #include <synthesis/MSVis/VisBuffer.h>
00036 #include <images/Images/ImageInterface.h>
00037 #include <images/Images/ImageInterface.h>
00038 #include <casa/Containers/Block.h>
00039 #include <casa/Arrays/Array.h>
00040 #include <casa/Arrays/Vector.h>
00041 #include <casa/Arrays/Matrix.h>
00042 #include <scimath/Mathematics/ConvolveGridder.h>
00043 #include <lattices/Lattices/LatticeCache.h>
00044 #include <lattices/Lattices/ArrayLattice.h>
00045 #include <ms/MeasurementSets/MSColumns.h>
00046 #include <measures/Measures/Measure.h>
00047 #include <measures/Measures/MDirection.h>
00048 #include <measures/Measures/MPosition.h>
00049 #include <coordinates/Coordinates/DirectionCoordinate.h>
00050 
00051 namespace casa { //# NAMESPACE CASA - BEGIN
00052 
00053 
00054 template <class K, class V> class SimpleOrderedMap;
00055 template <class T> class PtrBlock;
00056 template <class T> class CountedPtr;
00057 class   WPConvFunc; 
00058 
00059 // <summary>  An FTMachine for Gridded Fourier transforms </summary>
00060 
00061 // <use visibility=export>
00062 
00063 // <reviewed reviewer="" date="" tests="" demos="">
00064 
00065 // <prerequisite>
00066 //   <li> <linkto class=FTMachine>FTMachine</linkto> module
00067 //   <li> <linkto class=SkyEquation>SkyEquation</linkto> module
00068 //   <li> <linkto class=VisBuffer>VisBuffer</linkto> module
00069 // </prerequisite>
00070 //
00071 // <etymology>
00072 // FTMachine is a Machine for Fourier Transforms. WProjectFT does
00073 // Grid-based Fourier transforms.
00074 // </etymology>
00075 //
00076 // <synopsis> 
00077 // The <linkto class=SkyEquation>SkyEquation</linkto> needs to be able
00078 // to perform Fourier transforms on visibility data. WProjectFT
00079 // allows efficient Fourier Transform processing using a 
00080 // <linkto class=VisBuffer>VisBuffer</linkto> which encapsulates
00081 // a chunk of visibility (typically all baselines for one time)
00082 // together with all the information needed for processing
00083 // (e.g. UVW coordinates).
00084 //
00085 // Gridding and degridding in WProjectFT are performed using a
00086 // novel sort-less algorithm. In this approach, the gridded plane is
00087 // divided into small patches, a cache of which is maintained in memory
00088 // using a general-purpose <linkto class=LatticeCache>LatticeCache</linkto> class. As the (time-sorted)
00089 // visibility data move around slowly in the Fourier plane, patches are
00090 // swapped in and out as necessary. Thus, optimally, one would keep at
00091 // least one patch per baseline.  
00092 //
00093 // A grid cache is defined on construction. If the gridded uv plane is smaller
00094 // than this, it is kept entirely in memory and all gridding and
00095 // degridding is done entirely in memory. Otherwise a cache of tiles is
00096 // kept an paged in and out as necessary. Optimally the cache should be
00097 // big enough to hold all polarizations and frequencies for all
00098 // baselines. The paging rate will then be small. As the cache size is
00099 // reduced below this critical value, paging increases. The algorithm will
00100 // work for only one patch but it will be very slow!
00101 //
00102 // This scheme works well for arrays having a moderate number of
00103 // antennas since the saving in space goes as the ratio of
00104 // baselines to image size. For the ATCA, VLBA and WSRT, this ratio is
00105 // quite favorable. For the VLA, one requires images of greater than
00106 // about 200 pixels on a side to make it worthwhile.
00107 //
00108 // The FFT step is done plane by plane for images having less than
00109 // 1024 * 1024 pixels on each plane, and line by line otherwise.
00110 //
00111 // The gridding and degridding steps are implemented in Fortran
00112 // for speed. In gridding, the visibilities are added onto the
00113 // grid points in the neighborhood using a weighting function.
00114 // In degridding, the value is derived by a weight summ of the
00115 // same points, using the same weighting function.
00116 // </synopsis> 
00117 //
00118 // <example>
00119 // See the example for <linkto class=SkyModel>SkyModel</linkto>.
00120 // </example>
00121 //
00122 // <motivation>
00123 // Define an interface to allow efficient processing of chunks of 
00124 // visibility data
00125 // </motivation>
00126 //
00127 // <todo asof="97/10/01">
00128 // <ul> Deal with large VLA spectral line case 
00129 // </todo>
00130 
00131 class WProjectFT : public FTMachine {
00132 public:
00133 
00134   // Constructor: cachesize is the size of the cache in words
00135   // (e.g. a few million is a good number), tilesize is the
00136   // size of the tile used in gridding (cannot be less than
00137   // 12, 16 works in most cases). 
00138   // <group>
00139   WProjectFT(
00140            Int nFacets, Long cachesize, Int tilesize=16, 
00141            Bool usezero=True, Bool useDoublePrec=False);
00142   //Constructor without tangent direction
00143   WProjectFT(Int nFacets, MPosition mLocation,
00144              Long cachesize, Int tilesize=16, 
00145              Bool usezero=True, Float padding=1.0, Bool useDoublePrec=False);
00146   //Deprecated no longer need ms in constructor
00147   WProjectFT(
00148              Int nFacets, MDirection mTangent, MPosition mLocation,
00149              Long cachesize, Int tilesize=16, 
00150              Bool usezero=True, Float padding=1.0, Bool useDoublePrec=False);
00151   // </group>
00152 
00153   // Construct from a Record containing the WProjectFT state
00154   WProjectFT(const RecordInterface& stateRec);
00155 
00156   // Copy constructor
00157   WProjectFT(const WProjectFT &other);
00158 
00159   // Assignment operator
00160   WProjectFT &operator=(const WProjectFT &other);
00161 
00162   ~WProjectFT();
00163 
00164   // Initialize transform to Visibility plane using the image
00165   // as a template. The image is loaded and Fourier transformed.
00166   void initializeToVis(ImageInterface<Complex>& image,
00167                        const VisBuffer& vb);
00168   // This version returns the gridded vis...should be used in conjunction 
00169   
00170   // Finalize transform to Visibility plane: flushes the image
00171   // cache and shows statistics if it is being used.
00172   void finalizeToVis();
00173 
00174   // Initialize transform to Sky plane: initializes the image
00175   void initializeToSky(ImageInterface<Complex>& image,  Matrix<Float>& weight,
00176                        const VisBuffer& vb);
00177 
00178   // Finalize transform to Sky plane: flushes the image
00179   // cache and shows statistics if it is being used. DOES NOT
00180   // DO THE FINAL TRANSFORM!
00181   void finalizeToSky();
00182 
00183   // Get actual coherence from grid by degridding
00184   void get(VisBuffer& vb, Int row=-1);
00185 
00186 
00187   // Put coherence to grid by gridding.
00188   void put(const VisBuffer& vb, Int row=-1, Bool dopsf=False,
00189            FTMachine::Type type=FTMachine::OBSERVED);
00190 
00191   // Make the entire image
00192   void makeImage(FTMachine::Type type,
00193                  VisSet& vs,
00194                  ImageInterface<Complex>& image,
00195                  Matrix<Float>& weight);
00196   
00197   // Get the final image: do the Fourier transform and
00198   // grid-correct, then optionally normalize by the summed weights
00199   ImageInterface<Complex>& getImage(Matrix<Float>&, Bool normalize=True);
00200   virtual void normalizeImage(Lattice<Complex>& /*skyImage*/,
00201                               const Matrix<Double>& /*sumOfWts*/,
00202                               Lattice<Float>& /*sensitivityImage*/,
00203                               Bool /*fftNorm*/)
00204     {throw(AipsError("WProjectFT::normalizeImage() called"));}
00205  
00206   // Get the final weights image
00207   void getWeightImage(ImageInterface<Float>&, Matrix<Float>&);
00208 
00209   // Save and restore the WProjectFT to and from a record
00210   Bool toRecord(String& error, RecordInterface& outRec, 
00211                 Bool withImage=False);
00212   Bool fromRecord(String& error, const RecordInterface& inRec);
00213   
00214   // Can this FTMachine be represented by Fourier convolutions?
00215   Bool isFourier() {return True;}
00216 
00217 
00218   // Return name of this machine
00219 
00220   String name() const;
00221 
00222   // Copy convolution function etc to another FT machine
00223   // necessary if ft and ift are distinct but can share convfunctions
00224 
00225   void setConvFunc(CountedPtr<WPConvFunc>& pbconvFunc);
00226   CountedPtr<WPConvFunc>& getConvFunc();
00227   virtual void setMiscInfo(const Int qualifier){(void)qualifier;};
00228   virtual void ComputeResiduals(VisBuffer& /*vb*/, Bool /*useCorrected*/) {};
00229 
00230 protected:
00231 
00232   // Padding in FFT
00233   Float padding_p;
00234 
00235   Int nint(Double val) {return Int(floor(val+0.5));};
00236 
00237   // Find the convolution function
00238   void findConvFunction(const ImageInterface<Complex>& image,
00239                         const VisBuffer& vb);
00240 
00241   Int nWPlanes_p;
00242 
00243   // Get the appropriate data pointer
00244   Array<Complex>* getDataPointer(const IPosition&, Bool);
00245 
00246   void ok();
00247 
00248   void init();
00249 
00250   void prepGridForDegrid();
00251   // Is this record on Grid? check both ends. This assumes that the
00252   // ends bracket the middle
00253   Bool recordOnGrid(const VisBuffer& vb, Int rownr) const;
00254 
00255   // Image cache
00256   LatticeCache<Complex> * imageCache;
00257 
00258   // Sizes
00259   Long cachesize;
00260   Int tilesize;
00261 
00262   // Gridder
00263   ConvolveGridder<Double, Complex>* gridder;
00264 
00265   // Is this tiled?
00266   Bool isTiled;
00267 
00268   // Array lattice
00269   CountedPtr<Lattice<Complex> > arrayLattice;
00270 
00271   // Lattice. For non-tiled gridding, this will point to arrayLattice,
00272   //  whereas for tiled gridding, this points to the image
00273   CountedPtr<Lattice<Complex> > lattice;
00274 
00275   Float maxAbsData;
00276 
00277   // Useful IPositions
00278   IPosition centerLoc, offsetLoc;
00279 
00280   // Image Scaling and offset
00281   Vector<Double> uvScale, uvOffset;
00282   Double savedWScale_p;
00283 
00284   // Array for non-tiled gridding
00285   Array<Complex> griddedData;
00286   Array<DComplex> griddedData2;
00287 
00288 
00289   // Grid/degrid zero spacing points?
00290   Bool usezero_p;
00291 
00292   Cube<Complex> convFunc;
00293   Int convSampling;
00294   Int convSize;
00295   Vector<Int> convSupport;
00296 
00297   Vector<Int> convSizes_p;
00298 
00299 
00300   Int wConvSize;
00301 
00302   Int lastIndex_p;
00303 
00304   Int getIndex(const ROMSPointingColumns& mspc, const Double& time,
00305                const Double& interval);
00306 
00307   String machineName_p;
00308 
00309   CountedPtr<WPConvFunc> wpConvFunc_p;
00310 
00311 };
00312 
00313 } //# NAMESPACE CASA - END
00314 
00315 #endif