casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
GaussianShape.h
Go to the documentation of this file.
00001 //# GaussianShape.h:
00002 //# Copyright (C) 1998,1999,2000,2001,2002
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: GaussianShape.h 21130 2011-10-18 07:39:05Z gervandiepen $
00028 
00029 #ifndef COMPONENTS_GAUSSIANSHAPE_H
00030 #define COMPONENTS_GAUSSIANSHAPE_H
00031 
00032 #include <casa/aips.h>
00033 #include <scimath/Functionals/Gaussian2D.h>
00034 #include <casa/BasicSL/Complex.h>
00035 #include <components/ComponentModels/ComponentType.h>
00036 #include <components/ComponentModels/TwoSidedShape.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 class MDirection;
00041 class MVAngle;
00042 template <class Qtype> class Quantum;
00043 template <class T> class Matrix;
00044 template <class T> class Vector;
00045 
00046 // <summary>A Gaussian model for the spatial distribution of emission</summary>
00047 
00048 // <use visibility=export> 
00049 
00050 // <reviewed reviewer="" date="yyyy/mm/dd" tests="tGaussianShape" demos="dTwoSidedShape">
00051 // </reviewed>
00052 
00053 // <prerequisite>
00054 //   <li> <linkto class=TwoSidedShape>TwoSidedShape</linkto>
00055 // </prerequisite>
00056 
00057 // <synopsis> 
00058 
00059 // A GaussianShape models the spatial distribution of radiation from the sky as
00060 // a two-dimensional Gaussian function with user specified major axis width,
00061 // minor axis width and position angle.
00062 
00063 // This class like the other component shapes becomes more useful when used
00064 // through the <linkto class=SkyComponent>SkyComponent</linkto> class, which
00065 // incorperates the flux and spectral variation of the emission, or through the
00066 // <linkto class=ComponentList>ComponentList</linkto> class, which handles
00067 // groups of SkyComponent objects.
00068 
00069 // The reference direction is defined in celestial co-ordinates, using a
00070 // <linkto class=MDirection>MDirection</linkto> object. It indicates where the
00071 // centre of the Gaussian is on the sky. The direction can be specified both in
00072 // the constructor or with the <src>setRefDirection</src> function.
00073 
00074 // The width of the Gaussian is defined as the angle subtended by the full
00075 // width at half maximum of the Gaussian. The major axis has the larger width
00076 // and is aligned North-South when the position angle is zero. A positive
00077 // position angle moves the Northern side of the component to the East.  The
00078 // axial ratio is the ratio of the minor to major axis widths. The major axis
00079 // MUST not be smaller than the minor axis otherwise an exception (AipsError)
00080 // is thrown.
00081 
00082 // These parameters of the Gaussian (width, position angle, direction etc.) can
00083 // be specified at construction time, using the <src>*inRad</src> functions or
00084 // through functions in the base classes (TwoSidedShape & ComponentShape). The
00085 // base classes also implement functions for inter-converting this object into
00086 // a record representation. 
00087 
00088 // The flux, or integrated intensity, is always normalised to one. This class
00089 // does not model the actual flux or its variation with frequency. It solely
00090 // models the way the emission varies with position on the sky.
00091 
00092 // The <src>scale</src> member function is used to sample the component at any
00093 // point on the sky. The scale factor calculated by this function is the
00094 // proportion of the flux that is within a specified pixel size centered on the
00095 // specified direction. Ultimatly this function will integrate the emission
00096 // from the Gaussian over the entire pixel but currently it just assumes the
00097 // flux can be calculated by the height of the Gaussian at the centre of the
00098 // pixel scaled by the pixel area. This is <em>NOT</em> accurate for Gaussians
00099 // whose width is small compared with the pixel size.
00100 
00101 // This class contains functions that return the Fourier transform of the
00102 // component at a specified spatial frequency. There are described more fully
00103 // in the description of the <src>visibility</src> functions below.
00104 // </synopsis>
00105 
00106 // <example>
00107 // Suppose I had an image of a region of the sky and we wanted to subtract
00108 // a extended source from it. This could be done as follows:
00109 // <ul>
00110 // <li> Construct a SkyComponent with a Gaussian of width that is similar to
00111 //      the extended source.
00112 // <li> Project the component onto an image
00113 // <li> Convolve the image by the point spread function
00114 // <li> subtract the convolved model from the dirty image.
00115 // </ul>
00116 // Shown below is the code to perform the first step in this process, ie
00117 // construct the SkyComponent. This example is also available in the
00118 // <src>dTwoSidedShape.cc</src> file.  Note that it is more accurate to do
00119 // subtraction of components in the (u,v) domain.
00120 // <srcblock>
00121 // { // Construct a Gaussian shape
00122 //   MDirection blob_dir;
00123 //   { // get the right direction into blob_dir
00124 //     Quantity blob_ra; MVAngle::read(blob_ra, "19:39:");
00125 //     Quantity blob_dec; MVAngle::read(blob_dec, "-63.43.");
00126 //     blob_dir = MDirection(blob_ra, blob_dec, MDirection::J2000);
00127 //   }
00128 //   {
00129 //     const Flux<Double> flux(6.28, 0.1, 0.15, 0.01);
00130 //     const GaussianShape shape(blob_dir,
00131 //                         Quantity(30, "arcmin"), 
00132 //                         Quantity(2000, "mas"), 
00133 //                         Quantity(C::pi_2, "rad"));
00134 //     const ConstantSpectrum spectrum;
00135 //     SkyComponent component(flux, shape, spectrum);
00136 //     printShape(shape);
00137 //   }
00138 // }
00139 // </srcblock>
00140 // The printShape function is the example shown for the TwoSidedShape class.
00141 // </example>
00142 //
00143 // <todo asof="1999/11/12">
00144 //   <li> Use Measures & Quanta in the interface to the visibility functions.
00145 //   <li> Use a better way of integrating over the pixel area in the sample
00146 //   function. 
00147 // </todo>
00148 
00149 // <linkfrom anchor="GaussianShape" classes="ComponentShape TwoSidedShape PointShape DiskShape">
00150 //  <here>GaussianShape</here> - a Gaussian variation in the sky brightness
00151 // </linkfrom>
00152 
00153 
00154 class GaussianShape: public TwoSidedShape
00155 {
00156 public:
00157   // The default GaussianShape is at the J2000 North Pole. with a full width at
00158   // half maximum (FWHM) on both axes of 1 arc-min.
00159   GaussianShape();
00160 
00161   // Construct a Gaussian shape centred in the specified direction, specifying
00162   // the widths & position angle.
00163   // <group>
00164   GaussianShape(const MDirection& direction,
00165                 const Quantum<Double>& majorAxis,
00166                 const Quantum<Double>& minorAxis,
00167                 const Quantum<Double>& positionAngle);
00168   GaussianShape(const MDirection& direction, const Quantum<Double>& width,
00169                 const Double axialRatio,
00170                 const Quantum<Double>& positionAngle);
00171   // </group>
00172 
00173   // The copy constructor uses copy semantics.
00174   GaussianShape(const GaussianShape& other);
00175 
00176   // The destructor does nothing special.
00177   virtual ~GaussianShape();
00178 
00179   // The assignment operator uses copy semantics.
00180   GaussianShape& operator=(const GaussianShape& other);
00181 
00182   // get the type of the shape. This function always returns
00183   // ComponentType::GAUSSIAN.
00184   virtual ComponentType::Shape type() const;
00185 
00186   // set or return the width and orientation of the Gaussian. All numerical
00187   // values are in radians. There are also functions in the base class for
00188   // doing this with other angular units.
00189   // <group>
00190   virtual void setWidthInRad(const Double majorAxis,
00191                              const Double minorAxis, 
00192                              const Double positionAngle);
00193   virtual Double majorAxisInRad() const;
00194   virtual Double minorAxisInRad() const;
00195   virtual Double positionAngleInRad() const;
00196   virtual Double axialRatio() const;
00197   // </group>
00198 
00199   // Calculate the proportion of the flux that is in a pixel of specified size
00200   // centered in the specified direction. The returned value will always be
00201   // between zero and one (inclusive).
00202   virtual Double sample(const MDirection& direction, 
00203                         const MVAngle& pixelLatSize,
00204                         const MVAngle& pixelLongSize) const;
00205 
00206   // Same as the previous function except that many directions can be sampled
00207   // at once. The reference frame and pixel size must be the same for all the
00208   // specified directions.
00209   virtual void sample(Vector<Double>& scale, 
00210                       const Vector<MDirection::MVType>& directions, 
00211                       const MDirection::Ref& refFrame,
00212                       const MVAngle& pixelLatSize,
00213                       const MVAngle& pixelLongSize) const;
00214 
00215   // Return the Fourier transform of the component at the specified point in
00216   // the spatial frequency domain. The point is specified by a 3 element vector
00217   // (u,v,w) that has units of meters and the frequency of the observation, in
00218   // Hertz. These two quantities can be used to derive the required spatial
00219   // frequency <src>(s = uvw*freq/c)</src>. The w component is not used in
00220   // these functions.
00221 
00222   // The reference position for the transform is the direction of the
00223   // component. As this component is symmetric about this point the transform
00224   // is always a real value.
00225   virtual DComplex visibility(const Vector<Double>& uvw,
00226                               const Double& frequency) const;
00227 
00228   // Same as the previous function except that many (u,v,w) points can be
00229   // sampled at once. The uvw Matrix must have a first dimension of three, and
00230   // a second dimension that is the same as the length of the scale
00231   // Vector. Otherwise and exception is thrown (when compiled in debug mode).
00232   virtual void visibility(Vector<DComplex>& scale, const Matrix<Double>& uvw,
00233                           const Double& frequency) const;
00234 
00235   // as above but with many frequencies
00236   virtual void visibility(Matrix<DComplex>& scale, const Matrix<Double>& uvw,
00237                           const Vector<Double>& frequency) const;
00238 
00239   // Return a pointer to a copy of this object upcast to a ComponentShape
00240   // object. The class that uses this function is responsible for deleting the
00241   // pointer. This is used to implement a virtual copy constructor.
00242   virtual ComponentShape* clone() const;
00243 
00244   // Function which checks the internal data of this class for correct
00245   // dimensionality and consistent values. Returns True if everything is fine
00246   // otherwise returns False.
00247   virtual Bool ok() const;
00248 
00249   // return a pointer to this object.
00250   virtual const ComponentShape* getPtr() const; 
00251 
00252   // TODO This probably should be made a pure virtual method in TwoSidedShape
00253   // Return the effective area of the Gaussian (pi/(4*ln(2))*maj*min.
00254   // Units of the returned Quantity are steradians.
00255   virtual Quantity getArea() const;
00256 
00257   virtual String sizeToString() const;
00258 
00259 private:
00260   //# Updates the parameters of the itsFT object
00261   void updateFT();
00262   //# A generic Gaussian function
00263   Gaussian2D<Double> itsShape;
00264   //# The FT of a Gaussian is also a Gaussian. Its parameters are stored here
00265   Gaussian2D<Double> itsFT;
00266 };
00267 
00268 } //# NAMESPACE CASA - END
00269 
00270 #endif