casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
DiskShape.h
Go to the documentation of this file.
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