casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SkyEquation.h
Go to the documentation of this file.
00001 //# SkyEquation.h: SkyEquation definition
00002 //# Copyright (C) 1996,1997,1998,1999,2000,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_SKYEQUATION_H
00030 #define SYNTHESIS_SKYEQUATION_H
00031 
00032 #include <casa/aips.h>
00033 #include <casa/Arrays/Matrix.h>
00034 #include <casa/BasicSL/Complex.h>
00035 #include <casa/Logging/LogMessage.h>
00036 #include <casa/Logging/LogSink.h>
00037 #include <synthesis/TransformMachines/FTMachine.h>
00038 #include <synthesis/MSVis/VisBuffer.h>
00039 #include <ms/MeasurementSets/MSMainEnums.h>
00040 
00041 namespace casa { //# NAMESPACE CASA - BEGIN
00042 
00043 // <summary> Relate Sky brightness to the visibility </summary>
00044 
00045 // <use visibility=export>
00046 
00047 // <reviewed reviewer="" date="" tests="" demos="">
00048 
00049 // <prerequisite>
00050 //   <li> <linkto module="MeasurementComponents">MeasurementComponents</linkto> module
00051 // </prerequisite>
00052 //
00053 // <etymology>
00054 // Sky Equation encapsulates the equation between the sky brightness
00055 // and the visibility (or coherence) measured by a generic instrument
00056 // </etymology>
00057 //
00058 // <synopsis> 
00059 // This is responsible for the Sky-based part of Measurement Equation of the Generic
00060 // Interferometer due to Hamaker, Bregman and Sault and later extended
00061 // by Noordam, and Cornwell.
00062 //
00063 // See <linkto module="MeasurementEquations">MeasurementEquations</linkto>
00064 // for more details of the form of the SkyEquation.
00065 //
00066 // The principal use of SkyEquation is that, as described in 
00067 // <linkto module="MeasurementEquations">MeasurementEquations</linkto>,
00068 // the gradients of chi-squared may be calculated and returned
00069 // as an image.
00070 //
00071 // The following components can be plugged into SkyEquation
00072 // <ul>
00073 // <li> Antenna-based direction-dependent terms: <linkto class="SkyJones">SkyJones</linkto>
00074 // <li> Sky brightness model: <linkto class="SkyModel">SkyModel</linkto>
00075 // <li> Fourier transform machine: <linkto class="FTMachine">FTMachine</linkto>
00076 // </ul>
00077 // </synopsis> 
00078 //
00079 // <example>
00080 // <srcblock>
00081 //
00082 //      // Read the VisSet from disk
00083 //      VisSet vs("3c84.MS");
00084 //
00085 //      PagedImage<Float> im("3c84.modelImage");
00086 //
00087 //      // Create an ImageSkyModel from an image on disk
00088 //      ImageSkyModel ism(im);
00089 //
00090 //      // FTMachine
00091 //      GridFT ft;
00092 //
00093 //      SkyEquation se(ism, vs, ft);
00094 //
00095 //      // Make a Clean Image and write it out
00096 //      HogbomCleanImageSkyModel csm(ism);
00097 //      if (csm.solveSkyModel()) {
00098 //        PagedImage<Float> cleanImage=csm.getImage();
00099 //        cleanImage.setName("3c84.cleanImage");
00100 //      }
00101 //
00102 // </srcblock>
00103 // </example>
00104 //
00105 // <motivation>
00106 // SkyEquation is needed to encapsulate part of the measurement equation for 
00107 // both single dish and synthesis observations. The idea is that the structure of many
00108 // imaging algorithms is much the same for many different types of telescope.
00109 // SkyEquation is part of a framework of classes that are
00110 // designed for synthesis and single dish imaging. The others are the 
00111 // <linkto module=MeasurementComponents>MeasurementComponents</linkto>.
00112 //
00113 // </motivation>
00114 //
00115 // <todo asof="98/2/17">
00116 // <li> Implement SkyJones
00117 // </todo>
00118 
00119 // Forward declarations
00120 class SkyJones;
00121 class SkyModel;
00122 class VisSet;
00123 class FTMachine;
00124 class SkyComponent;
00125 class ComponentList;
00126 class ComponentFTMachine;
00127 class UVWMachine;
00128 class ROVisibilityIterator;
00129 class VisibilityIterator;
00130 
00131 template <class T> class ImageInterface;
00132 template <class T> class TempImage;
00133 
00134 class SkyEquation {
00135 public:
00136 
00137   // Define a SkyEquation linking a VisSet vs with a SkyModel sm
00138   // using an FTMachine ft for transforms in both directions
00139   SkyEquation(SkyModel& sm, VisSet& vs, FTMachine& ft);
00140   
00141   // Define a SkyEquation linking a VisSet vs with a SkyModel sm
00142   // using an FTMachine ft for transforms in both directions and
00143   // a ComponentFTMachine for the component lists
00144   SkyEquation(SkyModel& sm, VisSet& vs, FTMachine& ft,
00145               ComponentFTMachine& cft,  Bool noModelcol=False);
00146 
00147 
00148   //SkyEquation with ROVisIter
00149   SkyEquation(SkyModel& sm, ROVisibilityIterator& vi, FTMachine& ft,
00150               ComponentFTMachine& cft, Bool noModelCol);
00151 
00152   // Define a SkyEquation linking a VisSet vs with a SkyModel sm
00153   // using an FTMachine ft for Sky->Vis and ift for Vis->Sky
00154   SkyEquation(SkyModel& sm, VisSet& vs, FTMachine& ft, FTMachine& ift);
00155 
00156   // Define a SkyEquation linking a VisSet vs with a SkyModel sm
00157   // using an FTMachine ft for Sky->Vis and ift for Vis->Sky and
00158   // a ComponentFTMachine for the component lists
00159   // Default make use of MODEL_DATA Column of ms 
00160   SkyEquation(SkyModel& sm, VisSet& vs, FTMachine& ft, FTMachine& ift,
00161               ComponentFTMachine& cft);
00162 
00163 
00164   // Return the SkyModel used by this SkyEquation
00165   SkyModel& skyModel() {return *sm_;};
00166 
00167   // Return the VisSet used by this SkyEquation
00168   VisSet& visSet() {return *vs_;};
00169 
00170   // Return the (Sky->Vis) FTMachine used by this SkyEquation
00171   FTMachine& fTMachine() {return *ft_;};
00172   
00173   // Return the (Vis->Sky) FTMachine used by this SkyEquation
00174   FTMachine& iFTMachine() {return *ift_;};
00175   
00176   // Return the (Sky->Vis) ComponentFTMachine used by this SkyEquation
00177   ComponentFTMachine& componentFTMachine() {return *cft_;};
00178   
00179   // Destructor
00180   virtual ~SkyEquation();
00181 
00182   // Assignment operator
00183   SkyEquation& operator=(const SkyEquation& other);
00184 
00185   // Copy constructor
00186   SkyEquation(const SkyEquation& other);
00187 
00188   // Add Jones matrices to be used for Gain calculations. Each SkyJones
00189   // knows what type it is and therefore where to slot in.
00190   void setSkyJones(SkyJones& j);
00191 
00192   // Make an approximate PSF for each model. The PSF is approximate
00193   // in the sense that it is a shift-invariant approximation
00194   virtual void makeApproxPSF(Int model, ImageInterface<Float>& PSF);
00195 
00196   // make all the approx psfs in one go
00197   virtual void makeApproxPSF(PtrBlock<ImageInterface<Float> *>& PSFs);
00198 
00199   // Make complex XFRs needed for incrementGradientChiSquared
00200   virtual void makeComplexXFRs();
00201 
00202   // Predict model coherence for the SkyModel. If this is
00203   // incremental then the model visibilities are not reset
00204   // but are simply added to
00205   //virtual void predict(Bool incremental=False);
00206   virtual void predict(Bool incremental=False, MS::PredefinedColumns Type=MS::MODEL_DATA);
00207 
00208   // Find sum of weights, Chi-squared, and the first and second derivatives
00209   // by transforming to the measurements. 
00210   // <group>
00211   virtual void gradientsChiSquared(const Matrix<Bool>& required, SkyJones& sj);
00212   virtual void gradientsChiSquared(Bool incremental, Bool commitToMS=False);
00213   // </group>
00214 
00215   // Solve for variables. Both the SkyModel and the SkyJones can in
00216   // principle be solved for.
00217   // <group>
00218   virtual Bool solveSkyModel();
00219   virtual Bool solveSkyJones(SkyJones& sj);
00220   // </group>
00221 
00222   // Set image plane weighting
00223   void setImagePlaneWeighting(const String& type, const Float minPB, 
00224                               const Float constPB)
00225     {scaleType_p = type; minPB_p = minPB; constPB_p = constPB;}
00226 
00227   // Lock and unlock the underlying MeasurementSet
00228   virtual void lock();
00229   virtual void unlock();
00230   
00231   // Return the name of the underlying MeasurementSet
00232   virtual String associatedMSName();
00233 
00234 
00235   //assign  the flux scale that the ftmachines have if they have
00236   virtual void getCoverageImage(Int model, ImageInterface<Float>& im);
00237   //Set this to true if the residual image for mosaic is to be in
00238   //pb^2 units (optimum mode for clean search for centimetric imaging)
00239   virtual void doFlatNoise(Bool doFlat=False){doflat_p=doFlat;};
00240   
00241   //get the weight image from the ftmachines
00242   virtual void getWeightImage(const Int, ImageInterface<Float>&){};
00243 
00244   virtual Bool isNewFTM(){return False;}
00245 
00246  protected:
00247 
00248   // Increment gradientsChiSquared. The image of SkyModel must contain
00249   // the increment to the image. For each model, a collection of
00250   // complex transfer functions are used to avoid gridding and
00251   // degridding all the visibilities.
00252   virtual void incrementGradientsChiSquared();
00253 
00254   // Do the full calculation - this must be called if the FTMachine 
00255   // cannot be represented by a Fourier transform
00256 
00257   virtual void fullGradientsChiSquared(Bool incremental=False);
00258 
00259   SkyEquation() {};
00260   
00261   // Check for validity
00262   Bool ok();
00263   
00264   // Apply Sky Jones to an image, also adjoint operation
00265   // <group>
00266   virtual void initializeGet(const VisBuffer& vb, Int row, Int model,
00267                              Bool incremental);
00268   
00269 
00270   virtual VisBuffer& get(VisBuffer& vb, Int model, Bool incremental, MS::PredefinedColumns Type=MS::MODEL_DATA);
00271   virtual void finalizeGet();
00272   virtual void initializePut(const VisBuffer &vb, Int model);
00273   
00274   virtual void put(const VisBuffer& vb, Int model, Bool dopsf=False, FTMachine::Type col=FTMachine::OBSERVED);
00275   
00276   virtual void finalizePut(const VisBuffer& vb, Int Model);
00277  
00278   // This encapsulates all of the change logic we should have to deal
00279   // with (short of returning a range of rows that has the same
00280   // SkyJones).  First we look to see if the first row of the VB
00281   // requires a new SkyJones; then we determine if there are
00282   // internal SkyJones changes in the VB which require going
00283   // row by row in the get/put formalism.
00284   virtual void changedSkyJonesLogic(const VisBuffer& vb, 
00285                                     Bool& firstOneChanges,
00286                                     Bool& internalChanges);
00287 
00288   // Have the SkyJones changed since their last application?
00289   virtual Bool changedSkyJones(const VisBuffer& vb, Int row);
00290 
00291   // Has the FTMachine changed since  last application?
00292   // <group>
00293   virtual Bool changedFTMachine(const VisBuffer& vb);
00294   virtual Bool changedIFTMachine(const VisBuffer& vb);
00295   // </group>
00296 
00297   // Do the Sky Jones change in this Visbuffer, starting from row1?
00298   // Returns row2, the last row with the same skyJones
00299   virtual Bool changedSkyJonesBuffer(const VisBuffer& vb, Int row1, Int& row2);
00300 
00301   virtual void resetSkyJones();
00302   virtual void assertSkyJones(const VisBuffer& vb, Int row);
00303   virtual ImageInterface<Complex>& applySkyJones(const VisBuffer& vb, Int row,
00304                                                  ImageInterface<Float>& in,
00305                                                  ImageInterface<Complex>& out);
00306   virtual void applySkyJonesInv(const VisBuffer& vb, Int row,
00307                                 ImageInterface<Complex>& in,
00308                                 ImageInterface<Float>& work,
00309                                 ImageInterface<Float>& out);
00310   virtual void applySkyJonesSquare(const VisBuffer& vb, Int row,
00311                                    Matrix<Float>& weights, 
00312                                    ImageInterface<Float>& work,
00313                                    ImageInterface<Float>& ggS);
00314   // </group>
00315 
00316   // Puts for calculating the complex XFRs
00317   // <group>
00318   virtual void initializePutXFR(const VisBuffer &vb, Int model, Int numXFR);
00319   virtual void putXFR(const VisBuffer& vb, Int model, Int& numXFR);
00320   virtual void finalizePutXFR(const VisBuffer& vb, Int Model, Int numXFR);
00321   // </group>
00322 
00323   // Puts for calculating the complex convolutions
00324   // <group>
00325   virtual void initializePutConvolve(const VisBuffer &vb, Int model,
00326                                      Int numXFR);
00327   virtual void putConvolve(const VisBuffer& vb, Int model, Int& numXFR);
00328   virtual void finalizePutConvolve(const VisBuffer& vb, Int Model, Int numXFR);
00329   // </group>
00330 
00331   // Get, etc. for a SkyComponent is much simpler
00332   // <group>
00333   virtual VisBuffer& get(VisBuffer& vb, const SkyComponent& component);
00334   virtual VisBuffer& get(VisBuffer& vb, const ComponentList& components);
00335   // Do the sum of the gets for all the models for this visbuffer
00336   
00337   SkyComponent& applySkyJones(SkyComponent& corruptedComponent,
00338                               const VisBuffer& vb,
00339                               Int row);
00340   // </group>
00341 
00342   // Modify the ggS and Create the imageScale
00343   virtual void fixImageScale();
00344 
00345   // Deal with scaling or unscaling image or deltaImage
00346   // <group>
00347   virtual void scaleImage(Int model, Bool incremental);
00348   virtual void unScaleImage(Int model, Bool incremental);
00349   virtual void scaleImage(Int model=0);
00350   virtual void unScaleImage(Int model=0);
00351   virtual void scaleDeltaImage(Int model=0);
00352   virtual void unScaleDeltaImage(Int model=0);
00353   // </group>
00354 
00355   // Check the VisIter chunck size...force a more reasonable chunk 
00356   // if default is  too small 
00357 
00358   virtual void checkVisIterNumRows(ROVisibilityIterator& vi);
00359 
00360   //virtual void predictComponents(Bool& incremental, Bool& initialized);
00361   virtual void predictComponents(Bool& incremental, Bool& initialized,  MS::PredefinedColumns Type=MS::MODEL_DATA);
00362 
00363   
00364   // SkyModel
00365   SkyModel* sm_;
00366 
00367   // VisSet
00368   VisSet* vs_;
00369   //Visibilityiterators
00370   VisibilityIterator* wvi_p;
00371   ROVisibilityIterator* rvi_p;
00372 
00373 
00374   // FTMachine objects
00375   // <group>
00376   FTMachine* ft_;
00377   FTMachine* ift_;
00378   ComponentFTMachine* cft_;
00379   // </group>
00380 
00381   // List of terms in left to right order
00382   // <group>
00383   SkyJones* ej_;
00384   SkyJones* dj_;
00385   SkyJones* tj_;
00386   SkyJones* fj_;
00387   // </group>
00388 
00389   // Workspace
00390   // <group>
00391   Float chisq, sumwt;
00392   Float ggSMax_p;
00393   // </group>
00394 
00395   LogSink logSink_p;
00396   LogSink& logSink() {return logSink_p;};
00397 
00398   Int iDebug_p;
00399   
00400   // Previous VisBuffer, used to determine how to apply
00401   // SkyJones;  
00402   // Set in initializePut and initializePutXFR,
00403   // Used in finalizePut and finalizePutXFR
00404 
00405   mutable VisBufferAutoPtr vb_p;
00406 
00407   Float minPB_p;   // ignore model flux below this level in the generalized PB
00408   Float constPB_p; // make the fluxscale constant for PB above this level
00409   String scaleType_p;  // types:  NONE, or SAULT
00410 
00411   Bool isPSFWork_p; // working for PSF estimation
00412 
00413   Bool noModelCol_p;
00414 
00415   Vector<Bool> modelIsEmpty_p;
00416 
00417   //SkyJones::changed returns a True the first time its called
00418   //We have to ignore this at the very begining and first call to 'changed'
00419   //and not call finalizePut
00420   Bool isBeginingOfSkyJonesCache_p;
00421   Bool doflat_p;
00422 };
00423 
00424 } //# NAMESPACE CASA - END
00425 
00426 #endif
00427 
00428 
00429 
00430 
00431