00001 //# BeamSkyJones.h: Definitions of interface for BeamSkyJones 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_TRANSFORM2_BEAMSKYJONES_H 00030 #define SYNTHESIS_TRANSFORM2_BEAMSKYJONES_H 00031 00032 #include <casa/aips.h> 00033 #include <casa/Containers/Block.h> 00034 #include <casa/Exceptions/Error.h> 00035 #include <measures/Measures/MDirection.h> 00036 #include <measures/Measures.h> 00037 #include <measures/Measures/Stokes.h> 00038 #include <synthesis/TransformMachines2/SkyJones.h> 00039 #include <synthesis/TransformMachines/PBMath.h> 00040 00041 00042 namespace casa{ 00043 //#forward 00044 //# Need forward declaration for Solve in the Jones Matrices 00045 00046 class SkyModel; 00047 class ImageRegion; 00048 00049 namespace refim { //# namespace for refactoring 00050 00051 00052 // <summary> beam-like sky-plane effects for the SkyEquation </summary> 00053 00054 // <use visibility=export> 00055 00056 // <reviewed reviewer="" date="" tests="" demos=""> 00057 00058 // <prerequisite> 00059 // <li> <linkto class="SkyEquation">SkyEquation</linkto> class 00060 // <li> <linkto class="SkyJones">SkyJones</linkto> class 00061 // <li> <linkto class="PBMathInterface">PBMathInterface</linkto> class 00062 // </prerequisite> 00063 // 00064 // <etymology> 00065 // BeamSkyJones, derived from SkyJones, describes an interface to 00066 // beam-based SkyJones objects. Like SkyJones, it too is an Abstract 00067 // Base Class, but implements the beam-related methods. 00068 // </etymology> 00069 // 00070 // <synopsis> 00071 // 00072 // <motivation> 00073 // The properties of sky-plane based calibration effects must be described 00074 // for the <linkto class="SkyEquation">SkyEquation</linkto>; this class 00075 // encapsulates the antenna beam-based aspects which are present in at least 00076 // a few other specific SkyJones (VPSkyJones and DBeamSkyJones). 00077 // </motivation> 00078 // 00079 // <todo asof="98/11/01"> 00080 // <li> Solvable part needs implementation: we need to derive an 00081 // image of gradients of the elements of the Jones matrix. See VisJones 00082 // for how to do this. 00083 // <li> The MS, version II, will have a beam subtable, which will have PBMaths 00084 // for each antenna. Until this becomes available, we need to do some 00085 // fudging; for example, we 00086 // </todo> 00087 00088 class BeamSkyJones : virtual public SkyJones { 00089 00090 public: 00091 00092 // Eventually, the MS will have all the beam information in its Beam Subtable. 00093 // Till then, we either guess the PB to use or explicitly define it upon construction. 00094 // Construct from a Measurement Set, figure out the most appropriate PBMath object 00095 // from MS information 00096 BeamSkyJones(const Quantity ¶llacticAngleIncrement = Quantity(720.0, "deg"), // def= 1 PA interval 00097 BeamSquint::SquintType doSquint = BeamSquint::NONE, // def= no beam squint offsets 00098 const Quantity &skyPositionThreshold = Quantity(180,"deg")); // def= assume there is no change of 00099 // this operator due to position offset 00100 00101 00102 // Virtual destructor (this is a virtual base class) 00103 virtual ~BeamSkyJones() = 0; 00104 00105 // Print out information concerning the state of this object 00106 virtual void showState(LogIO& os); 00107 00108 // Apply Jones matrix to an image (and adjoint) 00109 // No "applyInverse" is available from the SkyJones classes, 00110 // you can get them directly from PBMath or you can get 00111 // the equivalent effect by dividing by grad grad Chi^2 00112 // in ImageSkyModel. 00113 // <group> 00114 ImageInterface<Complex>& apply(const ImageInterface<Complex>& in, 00115 ImageInterface<Complex>& out, 00116 const vi::VisBuffer2& vb, Int row, 00117 Bool forward=True); 00118 ImageInterface<Float>& apply(const ImageInterface<Float>& in, 00119 ImageInterface<Float>& out, 00120 const vi::VisBuffer2& vb, Int row); 00121 00122 ImageInterface<Float>& applySquare(const ImageInterface<Float>& in, 00123 ImageInterface<Float>& out, 00124 const vi::VisBuffer2& vb, Int row); 00125 // </group> 00126 00127 // Apply Jones matrix to a sky component (and adjoint) 00128 // <group> 00129 SkyComponent& apply(SkyComponent& in, 00130 SkyComponent& out, 00131 const vi::VisBuffer2& vb, Int row, 00132 Bool forward = True); 00133 SkyComponent& applySquare(SkyComponent& in, 00134 SkyComponent& out, 00135 const vi::VisBuffer2& vb, Int row); 00136 // </group> 00137 00138 // Understand if things have changed since last PB application 00139 // <group> 00140 00141 // Reset to pristine state 00142 virtual void reset(); 00143 00144 // Has this operator changed since the last Application? 00145 // (or more properly, since the last update() ) 00146 virtual Bool changed(const vi::VisBuffer2& vb, Int row); 00147 00148 // Does the operator change in this visbuffer or since the last call? 00149 // May not be useful -- check it out: m.a.h. Dec 30 1999 00150 virtual Bool change(const vi::VisBuffer2& vb); 00151 00152 // Does this operator changed in this VisBuffer, 00153 // starting with row1? 00154 // If yes, we return in row2, the last row that has the 00155 // same SkyJones as row1. 00156 // NOTE: need to first call changed(const VisBuffer& vb, Int row) and 00157 // shield the user from the case where the fieldID has changed 00158 // (which only changes in blocks) 00159 virtual Bool changedBuffer(const vi::VisBuffer2& vb, Int row1, Int& row2); 00160 00161 // Update the FieldID, Telescope, pointingDirection, Parallactic angle info 00162 void update(const vi::VisBuffer2& vb, Int row); 00163 00164 // if (changed) {update()} 00165 virtual void assure (const vi::VisBuffer2& vb, Int row); 00166 // </group> 00167 00168 // Return the type of this Jones matrix (actual type of derived class). 00169 virtual casa::SkyJones::Type type() {return casa::SkyJones::E;}; 00170 00171 // Apply gradient 00172 virtual ImageInterface<Complex>& 00173 applyGradient(ImageInterface<Complex>& result, const vi::VisBuffer2& vb, 00174 Int row); 00175 00176 virtual SkyComponent& 00177 applyGradient(SkyComponent& result, const vi::VisBuffer2& vb, 00178 Int row); 00179 00180 // Is this solveable? 00181 virtual Bool isSolveable() {return False;}; 00182 00183 // Initialize for gradient search 00184 virtual void initializeGradients(); 00185 00186 // Finalize for gradient search 00187 virtual void finalizeGradients(); 00188 00189 // Add to Gradient Chisq 00190 virtual void addGradients(const vi::VisBuffer2& vb, Int row, const Float sumwt, 00191 const Float chisq, const Matrix<Complex>& c, 00192 const Matrix<Float>& f); 00193 00194 // Solve 00195 //virtual Bool solve (SkyEquation& se); 00196 00197 // Manage the PBMath objects 00198 // <group> 00199 // set the PB based on telescope name, antennaID and feedID 00200 // If antennaID or feedID is -1, the PBMath object is set for 00201 // all antennae or feeds, respectively. These are the default 00202 // values to retain the previous interface. 00203 // 00204 // Note. It would be nice to change the interface and make antennaID 00205 // and feedID the second and the third parameter, respectively. 00206 void setPBMath(const String &telescope, PBMath &myPBmath, 00207 const Int &antennaID = -1, const Int &feedID = -1); 00208 00209 // get the PBMath object; returns False if that one doesn't exist, 00210 // True if it does exist and is OK 00211 // whichAnt is an index into an array of PBMaths, which is different 00212 // for all telescope/antenna/feed combinations 00213 // Not sure why we need such a low-level method declared as public, 00214 // retained to preserve old interface 00215 Bool getPBMath(uInt whichAnt, PBMath &myPBMath) const; 00216 00217 // get the PBMath object; returns False if that one doesn't exist, 00218 // True if it does exist and is OK 00219 // antennaID and feedID default to -1 to preserve the old interface 00220 // TODO: change the interface and make antennaID and feedID the 00221 // second and third parameter respectively to have a better looking code 00222 Bool getPBMath(const String &telescope, PBMath &myPBMath, 00223 const Int &antennaID = -1, const Int &feedID = -1) const; 00224 00225 Quantity getPAIncrement() {return Quantity(parallacticAngleIncrement_p,"rad");} 00226 00227 Quantity getSkyPositionThreshold() {return Quantity(skyPositionThreshold_p,"rad");} 00228 00229 // Return true if all antennas share a common VP 00230 Bool isHomogeneous() const; 00231 //</group> 00232 00233 // Get the ImageRegion of the primary beam on an Image for a given pointing 00234 // Note: ImageRegion is not necesarily constrained to lie within the 00235 // image region (for example, if the pointing center is near the edge of the 00236 // image). fPad: extra padding over the primary beam supporrt, 00237 // fractional (ie, 1.2 for 20% padding), in all directions. 00238 // (note: we do not properly treat squint yet, this will cover it for now) 00239 // iChan: frequency channel to take: lowest frequency channel is safe for all 00240 // 00241 // Potential problem: this ImageRegion includes all Stokes and Frequency Channels 00242 // present in the input image. 00243 //COMMENTING out for now as this depend on PBMathInterface and which depends 00244 //back on SkyJones::sizeType 00245 ImageRegion* extent (const ImageInterface<Complex>& im, 00246 const vi::VisBuffer2& vb, 00247 const Int irow=-1, 00248 const Float fPad=1.2, 00249 const Int iChan=0, 00250 const casa::SkyJones::SizeType sizeType=casa::SkyJones::COMPOSITE); 00251 00252 ImageRegion* extent (const ImageInterface<Float>& im, 00253 const vi::VisBuffer2& vb, const Int irow=-1, 00254 const Float fPad=1.2, const Int iChan=0, 00255 const casa::SkyJones::SizeType sizeType=casa::SkyJones::COMPOSITE); 00256 00257 // summarize the PBMaths contained here. 00258 // n = -1 => terse table 00259 // n = 0 => table plus constructor values 00260 // n = m => plot m samples of the PB profile 00261 virtual void summary(Int n=0); 00262 00263 //return the telescope it is on at this state 00264 String telescope(); 00265 00266 //Get an idea of the support of the PB in number of pixels 00267 virtual Int support(const vi::VisBuffer2& vb, const casa::CoordinateSystem& cs); 00268 00269 private: 00270 00271 00272 String telescope_p; 00273 00274 Int lastFieldId_p; 00275 00276 Int lastArrayId_p; 00277 00278 Int lastMSId_p; 00279 00280 BeamSquint::SquintType doSquint_p; 00281 00282 Double parallacticAngleIncrement_p; // a parallactic angle threshold 00283 // beyond which the operator is considered to be 00284 // changed (in radians) 00285 Double skyPositionThreshold_p; // a sky position threshold beyond 00286 // which the operator is considered to be changed 00287 // (in radians) 00288 Block<Double> lastParallacticAngles_p; // a cache of parallactic angles 00289 // used when the operator was applied last time. 00290 // One value in radians for each beam model in PBMaths. 00291 // A zero-length block means that the operator 00292 // has never been applied 00293 Block<MDirection> lastDirections_p; // a chache of directions 00294 // used when the operator was applied last time. 00295 // One element for each beam model in PBMaths. 00296 // A zero-length block means that the operator 00297 // has never been applied 00298 00299 // One or more PBMaths (a common one for the 00300 // entire array, or one for each antenna) 00301 // This requires some sorting out for heterogeneous arrays! 00302 Block<PBMath> myPBMaths_p; 00303 // Names of telescopes (parralel with PBMaths 00304 Block<String> myTelescopes_p; 00305 00306 // Antenna IDs (parallel with PBMaths) 00307 Block<Int> myAntennaIDs_p; 00308 // Feed IDs (parallel with PBMaths) 00309 Block<Int> myFeedIDs_p; 00310 00311 // cache of the indices to the PBMaths container for antenna/feed 1 and 2 00312 mutable CountedPtr<vi::VisBuffer2> lastUpdateVisBuffer_p; // to ensure that the cache 00313 // is filled for the correct 00314 // VisBuffer. The value is used 00315 // for comparison only 00316 mutable Int lastUpdateRow_p; // to ensure that the cache is filled for 00317 // correct row in the VisBuffer 00318 mutable Int lastUpdateIndex1_p; // index of the first antenna/feed 00319 mutable Int lastUpdateIndex2_p; // index of the second antenna/feed 00320 // 00321 00322 mutable Bool hasBeenApplied; // True if the operator has been applied at least once 00323 00324 // update the indices cache. This method could be made protected in the 00325 // future (need access functions for lastUpdateIndex?_p to benefit from it) 00326 // Cache will be valid for a given VisBuffer and row 00327 void updatePBMathIndices(const vi::VisBuffer2 &vb, Int row) const; 00328 00329 protected: 00330 // return True if two directions are close enough to consider the 00331 // operator unchanged, False otherwise 00332 Bool directionsCloseEnough(const MDirection &dir1, 00333 const MDirection &dir2) const throw(AipsError); 00334 00335 // return index of compareTelescope, compareAntenna and compareFeed in 00336 // myTelescopes_p, myAntennaIDs and myFeedIDs; -1 if not found 00337 // if compareAntenna or compareTelescope is -1, this means that the 00338 // PBMath class is the same for all antennae/feeds. An exception will 00339 // be raised, if separate PBMath objects have been assigned by setPBMath 00340 // for different feeds/antennae but -1 is used for query. 00341 // 00342 // It would be good to rename this function to indexBeams as this name 00343 // is more appropriate. 00344 // 00345 Int indexTelescope(const String & compareTelescope, 00346 const Int &compareAntenna=-1, 00347 const Int &compareFeed=-1) const; 00348 00349 }; 00350 00351 } //# end of namespace refim 00352 } //# end of namespace casa 00353 00354 #endif 00355