casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ComponentShape.h
Go to the documentation of this file.
00001 //# ComponentShape.h: Base class for component shapes
00002 //# Copyright (C) 1998,1999,2000,2001
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 //# $Id: ComponentShape.h 21130 2011-10-18 07:39:05Z gervandiepen $
00027 
00028 #ifndef COMPONENTS_COMPONENTSHAPE_H
00029 #define COMPONENTS_COMPONENTSHAPE_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/BasicSL/Complexfwd.h>
00033 #include <measures/Measures/MDirection.h>
00034 #include <casa/Quanta/Quantum.h>
00035 #include <casa/Utilities/RecordTransformable.h>
00036 #include <components/ComponentModels/ComponentType.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 class DirectionCoordinate;
00041 class MVAngle;
00042 class RecordInterface;
00043 class String;
00044 template <class T> class Matrix;
00045 template <class T> class MeasRef;
00046 template <class T> class Vector;
00047 
00048 // <summary>Base class for component shapes</summary>
00049 
00050 // <use visibility=export>
00051 
00052 // <reviewed reviewer="" date="yyyy/mm/dd" tests="tComponentShape" demos="dPointShape">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //   <li> <linkto class=MDirection>MDirection</linkto>
00057 // </prerequisite>
00058 //
00059 // <synopsis>
00060 
00061 // This abstract base class defines the interface for classes which
00062 // define the shape of a component. The most fundamental derived class is the
00063 // <linkto class=PointShape>point</linkto> shape class but the 
00064 // <linkto class=GaussianShape>Gaussian</linkto> shape,
00065 // <linkto class=DiskShape>disk</linkto> shape and 
00066 // <linkto class=LimbDarkenedDiskShape>limbdarkeneddisk classes are also
00067 // available. These classes model the spatial distribution of emission from the
00068 // sky. 
00069 
00070 // Classes derived from the <linkto class=SpectralModel>SpectralModel</linkto>
00071 // class are used to model the spectral characteristics and the 
00072 // <linkto class=Flux>Flux</linkto> class is used to model the flux. The
00073 // <linkto class=SkyComponent>SkyComponent</linkto> class incorporates these
00074 // three characteristics (flux, shape & spectrum) and the 
00075 // <linkto class=ComponentList>ComponentList</linkto> class handles groups of
00076 // SkyComponent objects.
00077 
00078 // This base class parameterises shapes with two quantities.
00079 // <dl>
00080 // <dt><em> A reference direction.</em>
00081 // <dd> This is specified using an <linkto class=MDirection>MDirection</linkto>
00082 //      object and indicates the direction on a defined reference point
00083 //      within the shape. Usually this reference point is the centre of the
00084 //      shape. 
00085 // <dt> <em>A Vector of parameters.</em>
00086 // <dd> This contains other parameters that the are defined differently for
00087 //      different shapes. The length of the vector may vary for different
00088 //      component shapes. 
00089 // </dl>
00090 // 
00091 // The basic operation of classes using this interface is to model the flux as
00092 // a function of direction on the sky. Classes derived from this one do not
00093 // know what the flux of the component. Instead the sample and visibility
00094 // functions return factors that are used to scale the flux and calculate the
00095 // amount of flux at a specified point on the sky or on the (u,v) plane.
00096 
00097 // Any allowed direction reference frame can be used. However the reference
00098 // frame must be adequately specified in order to allow conversions to other
00099 // reference frames. For example if the reference frame code for a component is
00100 // MDirection::AZEL then the reference frame must also contain the time and
00101 // position, on the earth, that the specified azimuth and elevation to refer
00102 // to. This way the sample functions can convert the direction to a value in
00103 // the J2000 reference frame (if you specify the sample direction in the J2000
00104 // frame).
00105 
00106 // </synopsis>
00107 
00108 // <example> 
00109 
00110 // Because this is an abstract base class, an actual instance of this class
00111 // cannot be constructed. However the interface it defines can be used inside a
00112 // function. This is always recommended as it allows functions which have
00113 // ComponentShapes as arguments to work for any derived class.
00114 
00115 // In this example the printShape function prints out the type of model it is
00116 // working with and the reference direction of that model. This example is also
00117 // available in the <src>dPointShape.cc</src> file.
00118 
00119 // <srcblock>
00120 // void printShape(const ComponentShape& theShape) {
00121 //   cout << "This is a " << ComponentType::name(theShape.type())
00122 //        << " shape " << endl 
00123 //        << "with a reference direction of "
00124 //        << theShape.refDirection() << endl;
00125 // }
00126 // </srcblock>
00127 // </example>
00128 
00129 // <motivation>
00130 // The Shape base class was split from the SkyCompRep base class so that mixing
00131 // components with different spatial and spectral shapes did not result in a
00132 // combinatorial explosion in the number of classes required.
00133 // </motivation>
00134 //
00135 // <todo asof="1999/11/11">
00136 //   <li> Use Measures & Quanta in the interface to the visibility functions.
00137 // </todo>
00138 
00139 class ComponentShape: public RecordTransformable
00140 {
00141 public:
00142   // a virtual destructor is needed so that the actual destructor in the
00143   // derived class will be used.
00144   virtual ~ComponentShape();
00145 
00146   // return the actual shape. The ident function returns it as a String.
00147   // <group>
00148   virtual ComponentType::Shape type() const = 0;
00149   virtual const String& ident() const;
00150   // </group>
00151 
00152   // set/get the reference direction
00153   // <group>
00154   void setRefDirection(const MDirection& newRefDir);
00155   const MDirection& refDirection() const;
00156   // </group>
00157 
00158   // set/get the error in the reference direction. Values must be positive
00159   // angular quantities otherwise an AipsError exception is thrown. The errors
00160   // are usually interpreted as the 1-sigma bounds in latitude/longitude and
00161   // implicitly assume a Gaussian distribution.
00162   // <group>
00163   void setRefDirectionError(const Quantum<Double>& newRefDirErrLat, 
00164                             const Quantum<Double>& newRefDirErrLong);
00165   const Quantum<Double>& refDirectionErrorLat() const;
00166   const Quantum<Double>& refDirectionErrorLong() const;
00167   // </group>
00168 
00169   // Calculate the proportion of the flux that is in a pixel of specified size
00170   // centered in the specified direction. The returned value will always be
00171   // between zero and one (inclusive).
00172   virtual Double sample(const MDirection& direction,
00173                         const MVAngle& pixelLatSize, 
00174                         const MVAngle& pixelLongSize) const = 0;
00175 
00176   // Same as the previous function except that many directions can be sampled
00177   // at once. The reference frame and pixel size must be the same for all the
00178   // specified directions. A default implementation of this function is
00179   // available that uses the single pixel sample function described above.
00180   // However customised versions of this function will be more efficient as
00181   // intermediate values only need to be computed once.
00182   virtual void sample(Vector<Double>& scale, 
00183                       const Vector<MDirection::MVType>& directions, 
00184                       const MDirection::Ref& refFrame,
00185                       const MVAngle& pixelLatSize,
00186                       const MVAngle& pixelLongSize) const = 0;
00187 
00188   // Return the Fourier transform of the component at the specified point in
00189   // the spatial frequency domain. The point is specified by a 3-element vector
00190   // (u,v,w) that has units of meters and the frequency of the observation, in
00191   // Hertz. These two quantities can be used to derive the required spatial
00192   // frequency <src>(s = uvw*freq/c)</src>. The w component is not used in
00193   // these functions.  The scale factor returned by this function can be used
00194   // to scale the flux at the origin of the Fourier plane in order to determine
00195   // the visibility at the specified point.
00196 
00197   // The "origin" of the transform is the reference direction of the
00198   // component. This means for symmetric components, where the reference
00199   // direction is at the centre, that the Fourier transform will always be
00200   // real.
00201   virtual DComplex visibility(const Vector<Double>& uvw,
00202                               const Double& frequency) const = 0;
00203 
00204   // Same as the previous function except that many (u,v,w) points can be
00205   // sampled at once. The observation frequency is the same for all the
00206   // specified points. The uvw Matrix must have first dimension of three and
00207   // the second dimension must match the length of the scale vector. A default
00208   // implementation of this function is available that uses the single point
00209   // visibility function described above.  However customised versions of this
00210   // function may be more efficient as intermediate values only need to be
00211   // computed once.
00212   virtual void visibility(Vector<DComplex>& scale, const Matrix<Double>& uvw,
00213                           const Double& frequency) const = 0;
00214 
00215   //Same as above except for lots of frequencies too...scale rows is uvw points, columns
00216   // is frequency values
00217   virtual void visibility(Matrix<DComplex>& scale, const Matrix<Double>& uvw,
00218                           const Vector<Double>& frequency) const = 0;
00219 
00220   // determine whether the shape is symmetric or not. If it is then all the
00221   // scale factors returned by the visibility functions will be real numbers.
00222   virtual Bool isSymmetric() const = 0;
00223 
00224   // Return a pointer to a copy of the derived object upcast to a
00225   // ComponentShape object. The class that uses this function is responsible
00226   // for deleting the pointer. This is used to implement a virtual copy
00227   // constructor.
00228   virtual ComponentShape* clone() const = 0;
00229 
00230   // return the number of parameters in this shape and set/get them. The error
00231   // functions provide a way to set/get the error (nominally 1-sigma in an
00232   // implicit Gaussian distribution) in the corresponding parameter.
00233   // <group>
00234   virtual uInt nParameters() const = 0;
00235   virtual void setParameters(const Vector<Double>& newParms) = 0;
00236   virtual Vector<Double> parameters() const = 0;
00237   virtual void setErrors(const Vector<Double>& newErrs) = 0;
00238   virtual Vector<Double> errors() const = 0;
00239   virtual Vector<Double> optParameters() const = 0;
00240   virtual void setOptParameters(const Vector<Double>& newOptParms) = 0;
00241   // </group>
00242 
00243   // These functions convert between a record and a ComponentShape. This way
00244   // derived classes can interpret fields in the record in a class specific
00245   // way. They return False if the record is malformed and append an error
00246   // message to the supplied string giving the reason.  These functions define
00247   // how the shape is represented in glish. All records should have 'type' &
00248   // 'direction' fields which contain respectively; a string indicating which
00249   // shape is actually used, and a record representation of a direction
00250   // measure.  The interpretation of all other fields depends on the specific
00251   // component shape used.
00252   // <group>
00253   virtual Bool fromRecord(String& errorMessage, 
00254                           const RecordInterface& record) = 0;
00255   virtual Bool toRecord(String& errorMessage,
00256                         RecordInterface& record) const = 0;
00257   // </group>
00258 
00259   // Convert the parameters of the shape to the specified units. The Record
00260   // must contain the same fields that the to/from Record functions have (with
00261   // the exception of the direction & type fields). These fields will contain
00262   // strings (and not record representations of Quantums) that specify the new
00263   // units for these parameters. The new units must have the same dimensions as
00264   // the existing ones. If there is any problem parsing the record then an
00265   // error message is appended to the supplied string and the function returns
00266   // False.
00267   virtual Bool convertUnit(String& errorMessage,
00268                            const RecordInterface& record) = 0;
00269   
00270   // Return the shape that the supplied record represents. The
00271   // shape is determined by parsing a 'type' field in the supplied
00272   // record. Returns ComponentType::UNKNOWN_SHAPE if the type field
00273   // (which contains a string) could not be translated into a known
00274   // shape. It then appends an appropriate error message to the errorMessage
00275   // String.
00276   static ComponentType::Shape getType(String& errorMessage,
00277                                       const RecordInterface& record);
00278 
00279   // Convert component shape to absolute pixels.  The returned
00280   // vector is the longitude and latitude location in absolute pixels.
00281   virtual Vector<Double> toPixel (const DirectionCoordinate& dirCoord) const;
00282 
00283   // Fill the shape direction from the vector (longitude and latitude
00284   // in absolute pixels).  The return value is always True.
00285   virtual Bool fromPixel (const Vector<Double>& parameters,
00286                           const DirectionCoordinate& dirCoord);
00287 
00288   // Function which checks the internal data of this class for correct
00289   // dimensionality and consistant values. Returns True if everything is fine
00290   // otherwise returns False.
00291   virtual Bool ok() const;
00292 
00293   // Return a pointer to the object. All subclasses must implement. 
00294   virtual const ComponentShape* getPtr() const = 0;
00295 
00296   // Return a nicely formatted string describing the component's size.
00297   // All subclasses must implement.
00298   virtual String sizeToString() const = 0;
00299 
00300 protected:
00301   // The constructors and assignment operator are protected as only derived
00302   // classes should use them.
00303   // <group>
00304   //# The default ComponentShape direction is at the J2000 North Pole.
00305   ComponentShape();
00306 
00307   //# Construct a ComponentShape at the specified direction.
00308   ComponentShape(const MDirection& direction);
00309 
00310   //# The copy constructor uses copy semantics.
00311   ComponentShape(const ComponentShape& other);
00312 
00313   //# The assignment operator uses copy semantics.
00314   ComponentShape& operator=(const ComponentShape& other);
00315   // </group>
00316 
00317   //# Try and decide if the two reference directions are different, as the
00318   //# MeasRef<T>::operator== function is too restrictive.
00319   static Bool differentRefs(const MeasRef<MDirection>& ref1,
00320                             const MeasRef<MDirection>& ref2);
00321 
00322   // returns True if the quantum is not a non-negative angular quantity
00323   static Bool badError(const Quantum<Double>& quantum);
00324 
00325   // Turns the specified field in the specified record into an Quantum 
00326   // with angular units
00327   static Bool fromAngQRecord(Quantum<Double>& returnValue, 
00328                              String& errorMessage,
00329                              const String& fieldString, 
00330                              const RecordInterface& record);
00331 
00332 private:
00333   //# The reference direction of the component
00334   MDirection itsDir;
00335   //# The errors in the reference direction of the component in radians
00336   Quantum<Double> itsDirErrLat;
00337   Quantum<Double> itsDirErrLong;
00338 };
00339 
00340 } //# NAMESPACE CASA - END
00341 
00342 #endif