casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
FTMachine.h
Go to the documentation of this file.
00001 //# FTMachine.h: Definition for FTMachine
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
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_FTMACHINE_H
00030 #define SYNTHESIS_FTMACHINE_H
00031 
00032 #include <measures/Measures/Measure.h>
00033 #include <measures/Measures/MDirection.h>
00034 #include <measures/Measures/MPosition.h>
00035 #include <casa/Arrays/Array.h>
00036 #include <casa/Arrays/Vector.h>
00037 #include <casa/Arrays/Matrix.h>
00038 #include <casa/Logging/LogIO.h>
00039 #include <casa/Logging/LogSink.h>
00040 #include <casa/Logging/LogMessage.h>
00041 #include <casa/Containers/RecordInterface.h>
00042 #include <casa/Containers/Block.h>
00043 #include <images/Images/TempImage.h>
00044 #include <coordinates/Coordinates/SpectralCoordinate.h>
00045 #include <scimath/Mathematics/InterpolateArray1D.h>
00046 #include <synthesis/TransformMachines/CFCache.h>
00047 #include <synthesis/TransformMachines/CFStore2.h>
00048 
00049 #include <synthesis/TransformMachines/ConvolutionFunction.h>
00050 #include <synthesis/TransformMachines/PolOuterProduct.h>
00051 
00052 #include <images/Images/ImageInterface.h>
00053 #include <images/Images/SubImage.h>
00054 #include <synthesis/TransformMachines/StokesImageUtil.h>
00055 
00056 
00057 namespace casa { //# NAMESPACE CASA - BEGIN
00058 
00059   class VisSet;
00060   class VisBuffer;
00061   class ROVisibilityIterator;
00062   class UVWMachine;
00063   class VisModelData;
00064 
00065 // <summary> defines interface for the Fourier Transform Machine </summary>
00066 
00067 // <use visibility=export>
00068 
00069 // <reviewed reviewer="" date="" tests="" demos="">
00070 
00071 // <prerequisite>
00072 //   <li> <linkto class=SkyModel>SkyModel</linkto> module
00073 //   <li> <linkto class=SkyEquation>SkyEquation</linkto> module
00074 //   <li> <linkto class=VisBuffer>VisBuffer</linkto> module
00075 // </prerequisite>
00076 //
00077 // <etymology>
00078 // FTMachine is a Machine for Fourier Transforms
00079 // </etymology>
00080 //
00081 // <synopsis> 
00082 // The <linkto class=SkyEquation>SkyEquation</linkto> needs to be able
00083 // to perform Fourier transforms on visibility data. FTMachine
00084 // allows efficient Fourier Transform processing using a 
00085 // <linkto class=VisBuffer>VisBuffer</linkto> which encapsulates
00086 // a chunk of visibility (typically all baselines for one time)
00087 // together with all the information needed for processing
00088 // (e.g. UVW coordinates).
00089 // </synopsis> 
00090 //
00091 // <example>
00092 // A simple example of a FTMachine is found in 
00093 // <linkto class=GridFT>GridFT</linkto>.
00094 // See the example for <linkto class=SkyModel>SkyModel</linkto>.
00095 // </example>
00096 //
00097 // <motivation>
00098 // Define an interface to allow efficient processing of chunks of 
00099 // visibility data
00100 //
00101 // Note that the image must be Complex. It must contain the
00102 // Complex Stokes values (e.g. RR,RL,LR,LL). FTMachine
00103 // uses the image coordinate system to determine mappings
00104 // between the polarization and frequency values in the
00105 // PagedImage and in the VisBuffer.
00106 //
00107 // </motivation>
00108 //
00109 // <todo asof="97/10/01">
00110 // </todo>
00111 
00112 class FTMachine {
00113 public:
00114 
00115   //# Enumerations
00116   // Types of known Images that may be made using the makeImage method 
00117   enum Type {
00118     OBSERVED=0,         // From OBSERVED visibility data (default)
00119     MODEL,              // From MODEL visibility data
00120     CORRECTED,          // From CORRECTED visibility data
00121     RESIDUAL,           // From RESIDUAL (OBSERVED-MODEL) visibility data
00122     PSF,                // POINT SPREAD FUNCTION
00123     COVERAGE,           // COVERAGE (SD only)
00124     N_types,            // Number of types
00125     DEFAULT=OBSERVED
00126   };
00127 
00128   FTMachine();
00129 
00130 
00131   FTMachine(CountedPtr<CFCache>& cfcache,CountedPtr<ConvolutionFunction>& cfctor);
00132 
00133   FTMachine(const FTMachine& other);
00134 
00135   FTMachine& operator=(const FTMachine& other);
00136 
00137   void setBasePrivates(const FTMachine& other){FTMachine::operator=(other);}
00138 
00139   virtual ~FTMachine();
00140   
00141   // Initialize transform to Visibility plane
00142   virtual void initializeToVis(ImageInterface<Complex>& image, const VisBuffer& vb) = 0;
00143 
00144   // Vectorized InitializeToVis
00145   virtual void initializeToVis(Block<CountedPtr<ImageInterface<Complex> > > & compImageVec,
00146                                PtrBlock<SubImage<Float> *> & modelImageVec, 
00147                                PtrBlock<SubImage<Float> *>& weightImageVec, 
00148                                PtrBlock<SubImage<Float> *>& fluxScaleVec, 
00149                                Block<Matrix<Float> >& weightsVec,
00150                                const VisBuffer& vb);
00151 
00152   //-------------------------------------------------------------------------------------
00153   // Finalize transform to Visibility plane
00154   // This is mostly a no-op, and is not-even called from CubeSkyEquation.
00155   virtual void finalizeToVis() = 0;
00156 
00157   // Note : No vectorized form of finalizeToVis yet.....
00158 
00159   //-------------------------------------------------------------------------------------
00160   // Initialize transform to Sky plane
00161   virtual void initializeToSky(ImageInterface<Complex>& image,
00162                                Matrix<Float>& weight, const VisBuffer& vb) = 0;
00163 
00164   // Vectorized InitializeToSky
00165   virtual void initializeToSky(Block<CountedPtr<ImageInterface<Complex> > > & compImageVec,
00166                                Block<Matrix<Float> >& weightsVec, 
00167                                const VisBuffer& vb, 
00168                                const Bool dopsf);
00169 
00170   //-------------------------------------------------------------------------------------
00171   // Finalize transform to Sky plane
00172   virtual void finalizeToSky() = 0;
00173 
00174   virtual void finalizeToSky(ImageInterface<Complex>& iimage){(void)iimage;};
00175 
00176   // Vectorized finalizeToSky
00177   virtual void finalizeToSky(Block<CountedPtr<ImageInterface<Complex> > > & compImageVec, 
00178                              PtrBlock<SubImage<Float> *> & resImageVec, 
00179                              PtrBlock<SubImage<Float> *>& weightImageVec, 
00180                              PtrBlock<SubImage<Float> *>& fluxScaleVec, 
00181                              Bool dopsf, 
00182                              Block<Matrix<Float> >& weightsVec);
00183 
00184   //-------------------------------------------------------------------------------------
00185 
00186   // Get actual coherence from grid
00187   virtual void get(VisBuffer& vb, Int row=-1) = 0;
00188 
00189 
00190   // Put coherence to grid
00191   virtual void put(const VisBuffer& vb, Int row=-1, Bool dopsf=False, 
00192                    FTMachine::Type type= FTMachine::OBSERVED)=0;
00193 
00194   // Non const vb version - so that weights can be modified in-place
00195   // Currently, used only by MultiTermFT
00196   virtual void put(VisBuffer& vb, Int row=-1, Bool dopsf=False, 
00197                    FTMachine::Type type= FTMachine::OBSERVED)
00198                     {put((const VisBuffer&)vb,row,dopsf,type);};
00199 
00200   //-------------------------------------------------------------------------------------
00201   virtual void correlationToStokes(ImageInterface<Complex>& compImage, 
00202                                    ImageInterface<Float>& resImage, 
00203                                    const Bool dopsf);
00204  
00205   virtual void stokesToCorrelation(ImageInterface<Float>& modelImage,
00206                                    ImageInterface<Complex>& compImage);
00207 
00208   /*
00209   virtual void normalizeSumWeight(ImageInterface<Float>& inOutImage, 
00210                                ImageInterface<Float>& weightImage, 
00211                                const Bool dopsf);
00212   */
00213 
00214   virtual void normalizeImage(Lattice<Complex>&,//skyImage,
00215                               const Matrix<Double>&,// sumOfWts,
00216                               Lattice<Float>&,// sensitivityImage,
00217                               Bool /*fftNorm*/){return;};
00218 
00219   virtual void normalizeImage(ImageInterface<Float>& skyImage,
00220                               Matrix<Float>& sumOfWts,
00221                               ImageInterface<Float>& sensitivityImage,
00222                               Bool dopsf, Float pblimit, Int normtype);
00223 
00224   //-------------------------------------------------------------------------------------
00225 
00226   // Get the final image
00227   virtual ImageInterface<Complex>& getImage(Matrix<Float>&, Bool normalize=True) = 0;
00228 
00229   virtual void findConvFunction(const ImageInterface<Complex>&,// image,
00230                                 const VisBuffer& /*vb*/) {};
00231   // Get the final weights image
00232   virtual void getWeightImage(ImageInterface<Float>& weightImage, Matrix<Float>& weights) = 0;
00233 
00234   // Get a flux (divide by this to get a flux density correct image) 
00235   // image if there is one
00236   virtual void getFluxImage(ImageInterface<Float>& image){(void)image;};
00237 
00238   // Make the entire image
00239   virtual void makeImage(FTMachine::Type type,
00240                          VisSet& vs,
00241                          ImageInterface<Complex>& image,
00242                          Matrix<Float>& weight);
00243   // Make the entire image using a ROVisIter
00244   virtual void makeImage(FTMachine::Type type,
00245                          ROVisibilityIterator& vi,
00246                          ImageInterface<Complex>& image,
00247                          Matrix<Float>& weight);
00248 
00249   //-------------------------------------------------------------------------------------
00250 
00251   // Rotate the uvw from the observed phase center to the
00252   // desired phase center.
00253   void rotateUVW(Matrix<Double>& uvw, Vector<Double>& dphase,
00254                  const VisBuffer& vb);
00255 
00256   // Refocus on a finite distance
00257   void refocus(Matrix<Double>& uvw, const Vector<Int>& ant1,
00258                const Vector<Int>& ant2,
00259                Vector<Double>& dphase, const VisBuffer& vb);
00260 
00261   //helper function for openmp to call ...no private dependency
00262   static void locateuvw(const Double*& uvw, const Double*&dphase, const Double*& freq, const Int& nchan, const Double*& scale, const Double*& offset,  const Int& sampling, Int*& loc,Int*& off, Complex*& phasor, const Int& row, const Bool& doW=False); 
00263                  
00264 
00265   // Save and restore the FTMachine to and from a record
00266   virtual Bool toRecord(String& error, RecordInterface& outRecord, 
00267                         Bool withImage=False);
00268   virtual Bool fromRecord(String& error, const RecordInterface& inRecord);
00269 
00270   // Has this operator changed since the last application?
00271   virtual Bool changed(const VisBuffer& vb);
00272 
00273   // Can this FTMachine be represented by Fourier convolutions?
00274   virtual Bool isFourier() {return False;}
00275 
00276   //set  spw for cube that will be used;
00277   Bool setSpw(Vector<Int>& spw, Bool validFrame);
00278 
00279   //return whether the ftmachine is using a double precision grid
00280   virtual Bool doublePrecGrid();
00281 
00282   // To make sure no padding is used in certain gridders
00283   virtual void setNoPadding(Bool nopad){(void)nopad;};
00284   
00285   // Return the name of the machine
00286 
00287   virtual String name() const =0;// { return "None";};
00288  
00289   // set and get the location used for frame 
00290   void setLocation(const MPosition& loc);
00291   MPosition& getLocation();
00292 
00293   // set a moving source aka planets or comets =>  adjust phase center
00294   // on the fly for gridding 
00295   virtual void setMovingSource(const String& sourcename);
00296   virtual void setMovingSource(const MDirection& mdir);
00297 
00298   //reset stuff in an FTMachine
00299   virtual void reset(){};
00300 
00301   //set frequency interpolation type
00302   virtual void setFreqInterpolation(const String& method);
00303 
00304   //tell ftmachine which Pointing table column to use for Direction
00305   //Mosaic or Single dish ft use this for example
00306   virtual void setPointingDirColumn(const String& column="DIRECTION");
00307 
00308   virtual String getPointingDirColumnInUse();
00309 
00310   virtual void setSpwChanSelection(const Cube<Int>& spwchansels);
00311   virtual void setSpwFreqSelection(const Matrix<Double>& spwfreqs);
00312 
00313   // set the order of the Taylor term for MFS this is to tell
00314   // A-Projection to qualify the accumulated avgPB for each Taylor
00315   // term in the CFCache.
00316   virtual void setMiscInfo(const Int qualifier)=0;
00317 
00318   virtual void setCanComputeResiduals(Bool& b) {canComputeResiduals_p=b;};
00319   virtual Bool canComputeResiduals() {return canComputeResiduals_p;};
00320   //
00321   // Make the VB and VBStore interefaces for the interim re-factoring
00322   // work.  Finally removed the VB interface.
00323   virtual void ComputeResiduals(VisBuffer&vb, Bool useCorrected) = 0;
00324   virtual Float getPBLimit() {return pbLimit_p;};
00325   //virtual void ComputeResiduals(VBStore& vb)=0;
00326   //get and set numthreads
00327   void setnumthreads(Int n);
00328   Int getnumthreads();
00329 
00330   String getCacheDir() { return cfCache_p->getCacheDir(); };
00331 
00332 protected:
00333 
00334   friend class VisModelData;
00335   friend class MultiTermFT;
00336   LogIO logIO_p;
00337 
00338   LogIO& logIO();
00339 
00340   ImageInterface<Complex>* image;
00341 
00342   UVWMachine* uvwMachine_p;
00343 
00344   MeasFrame mFrame_p;
00345 
00346   // Direction of desired tangent plane
00347   Bool tangentSpecified_p;
00348   MDirection mTangent_p;
00349 
00350   MDirection mImage_p;
00351 
00352   // moving source stuff
00353   MDirection movingDir_p;
00354   Bool fixMovingSource_p;
00355   MDirection firstMovingDir_p;
00356     
00357 
00358   Double distance_p;
00359 
00360   uInt nAntenna_p;
00361 
00362   Int lastFieldId_p;
00363   Int lastMSId_p;
00364   //Use douple precision grid in gridding process
00365   Bool useDoubleGrid_p;
00366 
00367   virtual void initMaps(const VisBuffer& vb);
00368   virtual void initPolInfo(const VisBuffer& vb);
00369 
00370 
00371   // Sum of weights per polarization and per chan
00372   Matrix<Double> sumWeight, sumCFWeight;
00373 
00374   // Sizes
00375   Int nx, ny, npol, nchan, nvischan, nvispol;
00376 
00377   // Maps of channels and polarization
00378   Vector<Int> chanMap, polMap;
00379 
00380   // Is Stokes I only? iso XX,XY,YX,YY or LL,LR,RL,RR.
00381   Bool isIOnly;
00382 
00383   // Default Position used for phase rotations
00384   MPosition mLocation_p;
00385 
00386   // Set if uvwrotation is necessary
00387 
00388   Bool doUVWRotation_p;
00389   virtual void ok();
00390 
00391   // check if image is big enough for gridding
00392   
00393   virtual void gridOk (Int gridsupport);
00394 
00395   // setup multiple spectral window for cubes
00396   Block <Vector <Int> > multiChanMap_p;
00397   Vector<Int> selectedSpw_p;
00398   Vector<Int> nVisChan_p;
00399   Bool matchChannel(const Int& spw, 
00400                     const VisBuffer& vb);
00401 
00402   //redo all spw chan match especially if ms has changed underneath 
00403   Bool matchAllSpwChans(const VisBuffer& vb);
00404 
00405   //interpolate visibility data of vb to grid frequency definition
00406   //flag will be set the one as described in interpolateArray1D
00407   //return False if no interpolation is done...for e.g for nearest case
00408   virtual Bool interpolateFrequencyTogrid(const VisBuffer& vb, 
00409                                           const Matrix<Float>& wt,
00410                                           Cube<Complex>& data, 
00411                                           Cube<Int>& flag,
00412                                           Matrix<Float>& weight,
00413                                           FTMachine::Type type=FTMachine::OBSERVED ); 
00414   //degridded data interpolated back onto visibilities
00415   virtual Bool interpolateFrequencyFromgrid(VisBuffer& vb, 
00416                                             Cube<Complex>& data,
00417                                             FTMachine::Type type=FTMachine::MODEL );
00418   
00419 
00420   //Interpolate visibilities to be degridded upon
00421   virtual void getInterpolateArrays(const VisBuffer& vb,
00422                                     Cube<Complex>& data, Cube<Int>& flag);
00423 
00424 
00425   void setSpectralFlag(const VisBuffer& vb, Cube<Bool>& modflagcube); 
00426 
00427   //helper to save Measures in a record
00428   Bool saveMeasure(RecordInterface& rec, const String& name, String& error, const Measure& ms);
00429 
00430   // Private variables needed for spectral frame conversion 
00431   SpectralCoordinate spectralCoord_p;
00432   Vector<Bool> doConversion_p;
00433   Bool freqFrameValid_p;
00434   Vector<Double> imageFreq_p;
00435   //Vector of float lsrfreq needed for regridding
00436   Vector<Double> lsrFreq_p;
00437   Vector<Double> interpVisFreq_p;
00438   InterpolateArray1D<Double,Complex>::InterpolationMethod freqInterpMethod_p;
00439   String pointingDirCol_p;
00440   Cube<Int> spwChanSelFlag_p;
00441   Matrix<Double> spwFreqSel_p, expandedSpwFreqSel_p,expandedSpwConjFreqSel_p;
00442   Vector<Int> cfStokes_p;
00443   Int polInUse_p;
00444   CountedPtr<CFCache> cfCache_p;
00445   CFStore cfs_p, cfwts_p;
00446   CFStore2 cfs2_p, cfwts2_p;
00447 
00448   CountedPtr<ConvolutionFunction> convFuncCtor_p;
00449   CountedPtr<PolOuterProduct> pop_p;
00450 
00451   Bool canComputeResiduals_p;
00452   Bool toVis_p;
00453   Int numthreads_p;
00454 
00455   Float pbLimit_p;
00456 
00457  private:
00458   //Some temporary wasteful function for swapping axes because we don't 
00459   //Interpolation along the second axis...will need to implement 
00460   //interpolation on y axis of a cube. 
00461   
00462   void swapyz(Cube<Complex>& out, const Cube<Complex>& in);
00463   void swapyz(Cube<Bool>& out, const Cube<Bool>& in);
00464   void convUVW(Double& dphase, Vector<Double>& thisrow);
00465   //A holder for the complex image if nobody else is keeping it
00466   CountedPtr<ImageInterface<Complex> > cmplxImage_p;
00467 };
00468 
00469 } //# NAMESPACE CASA - END
00470 
00471 #endif
00472 
00473 
00474