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