00001 //# PBMath1D.h: Definitions of interface for 1-D PBMath objects 00002 //# Copyright (C) 1996,1997,1998,1999,2000,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_PBMATH1D_H 00030 #define SYNTHESIS_PBMATH1D_H 00031 00032 #include <casa/aips.h> 00033 #include <synthesis/TransformMachines/PBMathInterface.h> 00034 00035 namespace casa { //# NAMESPACE CASA - BEGIN 00036 00037 //#forward 00038 class Table; 00039 class SkyComponent; 00040 class ImageRegion; 00041 class CoordinateSystem; 00042 00043 // <summary> base class for 1D PBMath objects </summary> 00044 00045 00046 // <use visibility=export> 00047 00048 // <reviewed reviewer="" date="" tests="" demos=""> 00049 00050 // <prerequisite> 00051 // <li> <linkto class="SkyJones">SkyJones</linkto> class 00052 // <li> <linkto class="BeamSkyJones">BeamSkyJones</linkto> class 00053 // <li> <linkto class="PBMathInterface">PBMathInterface</linkto> class 00054 // </prerequisite> 00055 // 00056 // <etymology> 00057 // PBMath types do the mathematical operations of the PB's or VP's. 00058 // This is the base class for the 1D (ie, rotationally symmetric) PB's. 00059 // </etymology> 00060 // 00061 // <synopsis> 00062 // PBMath1D, the virtual base class for 1D PBMath objects, is 00063 // derived from PBMathInterface. Its cousin, PBMath2D, can deal with 00064 // inherently 2D voltage patterns or primary beams. PBMath1D can deal 00065 // with beam squint, (ie, the offset of the LL and RR beams on opposite 00066 // sides of the pointing center) which rotates on the sky with parallactic angle. 00067 // 00068 // The 1D PB philosophy is to specify the Voltage pattern or Primary Beam 00069 // via a small number of 00070 // parameters via one of the derived types (PBMath1DGauss, for example). The 00071 // derived type knows how to instantiate itself from a row in a beam subTable, 00072 // and how to convert itself into a lookup vector. The lookup vector is 00073 // fine enough that no interpolation need be done when finding the nearest 00074 // PB or VP value for a particular pixel (currently, there are 1e+4 elements 00075 // in the lookup vector, so on average, an error on order of 1e-4 is made 00076 // when applying the primary beam). 00077 // 00078 // There are two ways of creating the derived PB types: 00079 // 1) explicitly create one of the babies. You have control 00080 // over the details such as PB size and total extent, the reference 00081 // frequency at which this size is true (the size scales inversely 00082 // with wavelength), the squint orientation, and whether a mean 00083 // symmetrized beam will be calculated from the squinted beam. 00084 // (Nice defaults can reduce the arguments in most cases.) 00085 // <example> 00086 // <srcblock> 00087 // PBMath1DGauss myPB (Quantity(1.0, "'"), Quantity(3.0, "'"), Quantity(1.0, "GHz"), 00088 // False, // these are PB parameters, not VP 00089 // BeamSquint(MDirection(Quantity(2.0, "\""), 00090 // Quantity(0.0, "\""), 00091 // MDirection::Ref(MDirection::AZEL)), 00092 // Quantity(2.0, "GHz")), 00093 // False); 00094 // PBMath1DGauss myPB2 (Quantity(1.0, "'"), Quantity(3.0, "'"), Quantity(1.0, "GHz")); 00095 // 00096 // </srcblock> 00097 // </example> 00098 // 2) via the envelope class PBMath's enumerated CommonPB type. This is much simpler, 00099 // and will deal with a majority of the cases required: 00100 // <example> 00101 // <srcblock> 00102 // PBMath wsrtPB(PBMath::WSRT); 00103 // PBMath vla_LPB(PBMath::VLA_L); // has L band squint built in 00104 // </srcblock> 00105 // </example> 00106 // 00107 // The main thing you want to do with a primary beam or voltage pattern is 00108 // to apply it to an image. The top level "apply" methods are defined in 00109 // PBMathInterface. They are applyPB, applyPB2, applyVP. These top level 00110 // apply's then call a lower level private polymorphic apply, which are defined 00111 // in PBMath1D and in PBMath2D. These two different apply's deal with the 00112 // different details of 1D and 2D primary beam application. 00113 // <example> 00114 // <srcblock> 00115 // 00116 // PagedImage<Float> in; 00117 // PagedImage<Complex> out; 00118 // MDirection pointingDir(Quantity(135.0, "deg"), Quantity(60.0, "deg"), 00119 // MDirection::Ref(MDirection::J2000)); 00120 // Quantity parallacticAngle(26.5, "deg"); 00121 // PBMath wsrtPB(PBMath::WSRT_LOW); 00122 // wsrtPB.applyPB(in, out, pointingDir); // multiply by primary beam 00123 // wsrtPB.applyPB(in, out, pointingDir, parallacticAngle, BeamSquint::GOFIGURE, 00124 // True, 0.02); // divide by primary beam 00125 // wsrtPB.applyVP(in, out, pointingDir); // multiply by voltage pattern 00126 // 00127 // </srcblock> 00128 // </example> 00129 // </synopsis> 00130 // 00131 // <motivation> 00132 // All of the 1-D PB types have everything in common except for the 00133 // details of their parameterization. 00134 // </motivation> 00135 // 00136 // lower level helping apply methods: reduce code by this bundling 00137 // <thrown> 00138 // <li> AipsError - in apply(Image...), if in and out images are 00139 // inconsistent in shape or coordinates 00140 // <li> AipsError - in apply(SkyComponent...), if doSqiont==RR or LL 00141 // </thrown> 00142 // <todo asof="98/010/21"> 00143 // <li> SymmetrizeBeam doesn't do anything yet. (It should calculate 00144 // the mean symmetric beam about the pointing center when 00145 // squint is present, slightly larger than the symmetric beam 00146 // about the squint position. 00147 // </todo> 00148 00149 00150 class PBMath1D : public PBMathInterface { 00151 public: 00152 00153 // required so PBMath can see the protected "apply" method 00154 // Other derivatives of PBMathInterface, such as PBMath2D, will 00155 // also require friend class PBMath; 00156 friend class PBMath; 00157 00158 PBMath1D(Quantity maximumRadius, 00159 Quantity refFreq, 00160 Bool isThisVP, 00161 BeamSquint squint, 00162 Bool useSymmetricBeam); 00163 00164 virtual ~PBMath1D() = 0; 00165 00166 // Get the PB in a vector to look at 00167 // Concerning n_elements: they are evenly spaced between 0 and maxradius. 00168 // r is in units of arcminutes at 1 GHz 00169 void viewPB(Vector<Float>& r, Vector<Float>& PB, Int n_elements, const Double freq=1.0e9); 00170 00171 // Summarize the Voltage Pattern; 00172 // For PBMath1D, list nValues worth of the VP array 00173 virtual void summary(Int nValues=0); 00174 00175 // Is state of PBMath OK? 00176 virtual Bool ok(); 00177 00178 // Get the ImageRegion of the primary beam on an Image for a given pointing 00179 // Note: ImageRegion is not necesarily constrained to lie within the 00180 // image region (for example, if the pointing center is near the edge of the 00181 // image). fPad: extra fractional padding, beyond Primary Beam support 00182 // (note: we do not properly treat squint yet, this will cover it for now) 00183 // iChan: frequency channel to take: lowest frequency channel is safe for all 00184 // 00185 // Potential problem: this ImageRegion includes all Stokes and Frequency Channels 00186 // present in the input image. 00187 ImageRegion* extent (const ImageInterface<Complex>& in, 00188 const MDirection& pointing, 00189 const Int irow, 00190 const Float fPad, 00191 const Int iChan, 00192 const SkyJones::SizeType sizeType); 00193 ImageRegion* extent (const ImageInterface<Float>& in, 00194 const MDirection& pointing, 00195 const Int irow, 00196 const Float fPad, 00197 const Int iChan, 00198 const SkyJones::SizeType sizeType); 00199 00200 00201 virtual Int support(const CoordinateSystem& cs); 00202 00203 00204 protected: 00205 00206 // Protect default constructor: this will do you no good 00207 PBMath1D(); 00208 00209 // calculate the limited box of the Primary Beam model's support, 00210 // return in blc and trc (which are NOT contrained to be inside 00211 // the image 00212 void extentguts (const CoordinateSystem& coords, const MDirection& pointing, 00213 const Float fPad, const Int iChan, Vector<Float> &blc, Vector<Float>& trc); 00214 00215 // push blc lower, trc higher such that they define an image which is 00216 // a power of 2 in size. 00217 00218 // Adjust blc and trc such that they are within the image and such that they 00219 // create an image with power of 2 (SkyJones::POWEROF2) shape or 00220 // composite number (SkyJones::COMPOSITE) shape 00221 void refineSize(Vector<Float>& blc, Vector<Float>& trc, 00222 const IPosition& shape, SkyJones::SizeType); 00223 00224 00225 ImageInterface<Complex>& apply(const ImageInterface<Complex>& in, 00226 ImageInterface<Complex>& out, 00227 const MDirection& sp, 00228 const Quantity parAngle, 00229 const BeamSquint::SquintType doSquint, 00230 Bool inverse, 00231 Bool conjugate, 00232 Int ipower, // ie, 1=VP, 2=PB, 4=PB^2 00233 Float cutoff, 00234 Bool forward); 00235 00236 00237 ImageInterface<Float>& apply(const ImageInterface<Float>& in, 00238 ImageInterface<Float>& out, 00239 const MDirection& sp, 00240 const Quantity parAngle, 00241 const BeamSquint::SquintType doSquint, 00242 Float cutoff, 00243 const Int ipower=4); //only 2 values allowed 2 and 4 00244 //PB and PB^2 00245 00246 SkyComponent& apply(SkyComponent& in, 00247 SkyComponent& out, 00248 const MDirection& sp, 00249 const Quantity frequency, 00250 const Quantity parAngle, 00251 const BeamSquint::SquintType doSquint, 00252 Bool inverse, 00253 Bool conjugate, 00254 Int ipower, // ie, 1=VP, 2=PB, 4=PB^2 00255 Float cutoff, 00256 Bool forward); 00257 00258 00259 // Fill in PB_p array from construction parameters, rescale construction 00260 // parameters to the 1 GHz internal reference frequency 00261 // Eventually: create it as its needed; we've got 4 arrays to fill; 00262 // only create and store as they are required 00263 // Right now: just construct all arrays 00264 virtual void fillPBArray()=0; 00265 00267 00268 virtual void nearestVPArray(Double freq); 00269 00270 00271 // Helper method to fit a circularly symmetric beam to the 00272 // squinted RR + LL beam. Called upon construction. Build this later. 00273 // PB' = azimuthal fit to: ( VP(x+s)**2 + VP(x-s)**2 )/2 00274 // VP' = sqrt(PB') 00275 void symmetrizeSquintedBeam(); 00276 00277 void applyXLine(const Complex*& in, Complex*& out, Float*& rx2, Complex*& vp, const Float ry2, const Int ipower, const Bool conjugate, const Bool inverse, const Bool forward, const Int nx, const Int iy, const Double rmax2, const Double factor, const Double inverseIncrementRadius, const Float cutoff); 00278 // The parameterized representation is for the VP, not the PB. 00279 // Internally, a reference frequency of 1 GHz is used, and the 00280 // radius is in units of arcminutes. 00281 // That said, you can specify the voltage pattern in any 00282 // units, at any frequency, but they will be converted 00283 // into (1 GHz * arcminutes) for storage and internal use. 00284 // We fill in the lookup vectors VP, PB, esVP, esPB, 00285 // as they are asked for 00286 // <group> 00287 // Tabulated voltage pattern 00288 Vector<Complex> vp_p; 00289 00290 // Tabulated effective az-symmetrical voltage pattern 00291 // ( optional, depending upon useSymmetric_p ) 00292 Vector<Complex> esvp_p; 00293 // </group> 00294 00295 // Tabulated voltage pattern for wide band feed 00296 // First axis is radius, 2nd axis is frequency 00297 Matrix<Complex> wbvp_p; 00298 00299 // Switch to use wideband beam fits 00300 Bool wideFit_p; 00301 00302 // Wideband beam fit frequencies. 00303 // Equally spaced beam fits across frequency range of the feed 00304 Vector<Double> wFreqs_p; 00305 00306 // Maximum radius allowed in tabulated model 00307 Quantity maximumRadius_p; 00308 00309 // reference frequency: used for squint and other 00310 // beam paramaters such as width, found in derived types. 00311 // Internally, we rescale everything 00312 // to a reference frequency of 1 GHz 00313 Quantity refFreq_p; 00314 00315 // internal scaling from refFreq_p to 1GHz; used during construction 00316 Double fScale_p; 00317 00318 // Increment in radius 00319 Double inverseIncrementRadius_p; 00320 00321 // Scale to convert to tabulated units 00322 Double scale_p; 00323 00324 // CompositeNumber (for beam application and the like) 00325 CompositeNumber composite_p; 00326 00327 private: 00328 00329 }; 00330 00331 00332 } //# NAMESPACE CASA - END 00333 00334 #endif