casa
$Rev:20696$
|
00001 //# DiskShape.h: 00002 //# Copyright (C) 1998,1999,2000 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 addressed 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: DiskShape.h 21130 2011-10-18 07:39:05Z gervandiepen $ 00028 00029 #ifndef COMPONENTS_DISKSHAPE_H 00030 #define COMPONENTS_DISKSHAPE_H 00031 00032 #include <casa/aips.h> 00033 #include <casa/BasicSL/Complex.h> 00034 #include <components/ComponentModels/ComponentType.h> 00035 #include <components/ComponentModels/TwoSidedShape.h> 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 class MDirection; 00040 class MVAngle; 00041 template <class Qtype> class Quantum; 00042 template <class T> class Matrix; 00043 template <class T> class Vector; 00044 00045 // <summary>A disk model for the spatial distribution of emission</summary> 00046 00047 // <use visibility=export> 00048 00049 // <reviewed reviewer="" date="yyyy/mm/dd" tests="tDiskShape" demos="dTwoSidedShape"> 00050 // </reviewed> 00051 00052 // <prerequisite> 00053 // <li> <linkto class=TwoSidedShape>TwoSidedShape</linkto> 00054 // </prerequisite> 00055 00056 // <synopsis> 00057 00058 // A DiskShape models the spatial distribution of radiation from the sky as a 00059 // using a uniform brightness elliptical disk with user specified major axis 00060 // width, minor axis width and position angle. 00061 00062 // This class like the other component shapes becomes more useful when used 00063 // through the <linkto class=SkyComponent>SkyComponent</linkto> class, which 00064 // incorperates the flux and spectral variation of the emission, or through the 00065 // <linkto class=ComponentList>ComponentList</linkto> class, which handles 00066 // groups of SkyComponent objects. 00067 00068 // The reference direction is defined in celestial co-ordinates, using a 00069 // <linkto class=MDirection>MDirection</linkto> object. It indicates where the 00070 // centre of the disk is on the sky. The direction can be specified both in 00071 // the constructor or with the <src>setRefDirection</src> function. 00072 00073 // The width of the disk is defined as the angular diameter along the specified 00074 // axis. The major axis has the larger width and is aligned North-South when 00075 // the position angle is zero. A positive position angle moves the Northern 00076 // side of the disk to the East. The axial ratio is the ratio of the 00077 // minor to major axis widths. The major axis MUST not be smaller than the 00078 // minor axis otherwise an AipsError is thrown. 00079 00080 // These parameters of the disk (width, position angle, direction etc.) can be 00081 // specified at construction time, using the <src>*inRad</src> functions or 00082 // through functions, in the base classes. The base classes also implement 00083 // functions for inter-converting this object into a record representation. 00084 00085 // The flux, or integrated intensity, is always normalised to one. This class 00086 // does not model the actual flux or its variation with frequency. It solely 00087 // models the way the emission varies with position on the sky. 00088 00089 // The <src>sample</src> member function is used to sample the component at any 00090 // point on the sky. The scale factor calculated by this function is the 00091 // proportion of the flux that is within a specified pixel size centered on the 00092 // specified direction. This is not accurate for pixels which are partially 00093 // covered by the disk. Ultimately this function will integrate the emission 00094 // from the disk over the entire pixel but currently the returned flux will be 00095 // either zero or a constant value with the returned value depending on whether 00096 // the centre of the pixel in within the disk or not. This inaccuracy becomes 00097 // more important when the pixel size become large compared to the disk width. 00098 00099 // This class contains functions that return the Fourier transform of the 00100 // disk at a specified spatial frequency. There are described more fully 00101 // in the description of the <src>visibility</src> functions below. 00102 // </synopsis> 00103 00104 // <example> 00105 // Shown below is code to construct a disk shaped model whose direction is 00106 // always centred on the disk of Jupiter. Note that it is necessary to specify 00107 // the observation time in order for the DiskShape class to be able to do the 00108 // conversion into J2000 coordinates. This example is also available in the 00109 // <src>dTwoSidedShape.cc</src> file. 00110 // <srcblock> 00111 // { // construct a model for Jupiter. 00112 // Quantity clk_time; MVTime::read(clk_time, "01-10-2000/12:59"); 00113 // MEpoch obs_epoch(clk_time, MEpoch::UTC); 00114 // MeasFrame obs_frame(obs_epoch); 00115 // MDirection jupiter_dir(MVDirection(0), 00116 // MDirection::Ref(MDirection::JUPITER, obs_frame)); 00117 // DiskShape jupiter_shape; 00118 // jupiter_shape.setRefDirection(jupiter_dir); 00119 // jupiter_shape.setWidth(Quantity(4,"arcmin"), Quantity(3.9,"arcmin"), 00120 // Quantity(3, "deg")); 00121 // printShape(jupiter_shape); 00122 // MDirection sample_dir(MVDirection(1.218, 0.37), MDirection::J2000); 00123 // if (jupiter_shape.sample(sample_dir, MVAngle(0.1)) > 0.0) { 00124 // cout << "The position in J2000 coordinates is near: " 00125 // << sample_dir.getAngle("deg") << endl; 00126 // } 00127 // } 00128 // </srcblock> 00129 // The printShape function is the example shown for the TwoSidedShape class. 00130 // </example> 00131 // 00132 // <todo asof="1999/11/12"> 00133 // <li> Use Measures & Quanta in the interface to the visibility functions. 00134 // <li> Use a better way of integrating over the pixel area in the sample 00135 // function. 00136 // <li> Ensure that the position angle is always between zero and 180 00137 // degrees, and that the widths are always positive. 00138 // </todo> 00139 00140 // <linkfrom anchor="GaussianShape" classes="ComponentShape TwoSidedShape PointShape GaussianShape"> 00141 // <here>DiskShape</here> - a uniform brightness disk shape. 00142 // </linkfrom> 00143 00144 00145 class DiskShape: public TwoSidedShape 00146 { 00147 public: 00148 // The default GaussianShape is at the J2000 North Pole with a width of 1 00149 // arc-min on both axes. 00150 DiskShape(); 00151 00152 // Construct a disk shape centred in the specified direction, specifying 00153 // the widths & position angle. 00154 // <group> 00155 DiskShape(const MDirection& direction, 00156 const Quantum<Double>& majorAxis, 00157 const Quantum<Double>& minorAxis, 00158 const Quantum<Double>& positionAngle); 00159 DiskShape(const MDirection& direction, const Quantum<Double>& width, 00160 const Double axialRatio, 00161 const Quantum<Double>& positionAngle); 00162 // </group> 00163 00164 // The copy constructor uses copy semantics. 00165 DiskShape(const DiskShape& other); 00166 00167 // The destructor does nothing special. 00168 virtual ~DiskShape(); 00169 00170 // The assignment operator uses copy semantics. 00171 DiskShape& operator=(const DiskShape& other); 00172 00173 // get the type of the shape. This function always returns 00174 // ComponentType::DISK. 00175 virtual ComponentType::Shape type() const; 00176 00177 // set or return the width and orientation of the disk. All numerical 00178 // values are in radians. There are also functions in the base class for 00179 // doing this with other angular units. 00180 // <group> 00181 virtual void setWidthInRad(const Double majorAxis, 00182 const Double minorAxis, 00183 const Double positionAngle); 00184 virtual Double majorAxisInRad() const; 00185 virtual Double minorAxisInRad() const; 00186 virtual Double positionAngleInRad() const; 00187 // </group> 00188 00189 // Calculate the proportion of the flux that is in a pixel of specified size 00190 // centered in the specified direction. The returned value will always be 00191 // between zero and one (inclusive). 00192 virtual Double sample(const MDirection& direction, 00193 const MVAngle& pixelLatSize, 00194 const MVAngle& pixelLongSize) const; 00195 00196 // Same as the previous function except that many directions can be sampled 00197 // at once. The reference frame and pixel size must be the same for all the 00198 // specified directions. 00199 virtual void sample(Vector<Double>& scale, 00200 const Vector<MDirection::MVType>& directions, 00201 const MDirection::Ref& refFrame, 00202 const MVAngle& pixelLatSize, 00203 const MVAngle& pixelLongSize) const; 00204 00205 // Return the Fourier transform of the component at the specified point in 00206 // the spatial frequency domain. The point is specified by a 3 element vector 00207 // (u,v,w) that has units of meters and the frequency of the observation, in 00208 // Hertz. These two quantities can be used to derive the required spatial 00209 // frequency <src>(s = uvw*freq/c)</src>. The w component is not used in 00210 // these functions. 00211 00212 // The reference position for the transform is the direction of the 00213 // component. As this component is symmetric about this point the transform 00214 // is always a real value. 00215 virtual DComplex visibility(const Vector<Double>& uvw, 00216 const Double& frequency) const; 00217 00218 // Same as the previous function except that many (u,v,w) points can be 00219 // sampled at once. The uvw Matrix must have a first dimension of three, and 00220 // a second dimension that is the same as the length of the scale 00221 // Vector. Otherwise and exception is thrown (when compiled in debug mode). 00222 virtual void visibility(Vector<DComplex>& scale, const Matrix<Double>& uvw, 00223 const Double& frequency) const; 00224 00225 //same as above except with many frequencies 00226 virtual void visibility(Matrix<DComplex>& scale, const Matrix<Double>& uvw, 00227 const Vector<Double>& frequency) const; 00228 00229 // Return a pointer to a copy of this object upcast to a ComponentShape 00230 // object. The class that uses this function is responsible for deleting the 00231 // pointer. This is used to implement a virtual copy constructor. 00232 virtual ComponentShape* clone() const; 00233 00234 // Function which checks the internal data of this class for correct 00235 // dimensionality and consistent values. Returns True if everything is fine 00236 // otherwise returns False. 00237 virtual Bool ok() const; 00238 00239 // return a pointer to this object. 00240 virtual const ComponentShape* getPtr() const; 00241 00242 virtual String sizeToString() const; 00243 00244 private: 00245 Double calcSample(const MDirection::MVType& compDirValue, 00246 const MDirection::MVType& dirVal, 00247 const Double majRad, const Double minRad, 00248 const Double pixValue) const; 00249 Double calcVis(Double u, Double v, const Double factor) const; 00250 static void rotateVis(Double& u, Double& v, 00251 const Double cpa, const Double spa); 00252 00253 //# The parameters of the disk 00254 // <group> 00255 Double itsMajValue; 00256 Double itsMinValue; 00257 Double itsPaValue; 00258 Double itsHeight; 00259 // </group> 00260 }; 00261 00262 00263 } //# NAMESPACE CASA - END 00264 00265 #endif