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