casa
$Rev:20696$
|
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