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   // copy direction info from that object to this object
00170   void copyDirectionInfo(const ComponentShape& that);
00171 
00172   // Calculate the proportion of the flux that is in a pixel of specified size
00173   // centered in the specified direction. The returned value will always be
00174   // between zero and one (inclusive).
00175   virtual Double sample(const MDirection& direction,
00176                         const MVAngle& pixelLatSize, 
00177                         const MVAngle& pixelLongSize) const = 0;
00178 
00179   // Same as the previous function except that many directions can be sampled
00180   // at once. The reference frame and pixel size must be the same for all the
00181   // specified directions. A default implementation of this function is
00182   // available that uses the single pixel sample function described above.
00183   // However customised versions of this function will be more efficient as
00184   // intermediate values only need to be computed once.
00185   virtual void sample(Vector<Double>& scale, 
00186                       const Vector<MDirection::MVType>& directions, 
00187                       const MDirection::Ref& refFrame,
00188                       const MVAngle& pixelLatSize,
00189                       const MVAngle& pixelLongSize) const = 0;
00190 
00191   // Return the Fourier transform of the component at the specified point in
00192   // the spatial frequency domain. The point is specified by a 3-element vector
00193   // (u,v,w) that has units of meters and the frequency of the observation, in
00194   // Hertz. These two quantities can be used to derive the required spatial
00195   // frequency <src>(s = uvw*freq/c)</src>. The w component is not used in
00196   // these functions.  The scale factor returned by this function can be used
00197   // to scale the flux at the origin of the Fourier plane in order to determine
00198   // the visibility at the specified point.
00199 
00200   // The "origin" of the transform is the reference direction of the
00201   // component. This means for symmetric components, where the reference
00202   // direction is at the centre, that the Fourier transform will always be
00203   // real.
00204   virtual DComplex visibility(const Vector<Double>& uvw,
00205                               const Double& frequency) const = 0;
00206 
00207   // Same as the previous function except that many (u,v,w) points can be
00208   // sampled at once. The observation frequency is the same for all the
00209   // specified points. The uvw Matrix must have first dimension of three and
00210   // the second dimension must match the length of the scale vector. A default
00211   // implementation of this function is available that uses the single point
00212   // visibility function described above.  However customised versions of this
00213   // function may be more efficient as intermediate values only need to be
00214   // computed once.
00215   virtual void visibility(Vector<DComplex>& scale, const Matrix<Double>& uvw,
00216                           const Double& frequency) const = 0;
00217 
00218   //Same as above except for lots of frequencies too...scale rows is uvw points, columns
00219   // is frequency values
00220   virtual void visibility(Matrix<DComplex>& scale, const Matrix<Double>& uvw,
00221                           const Vector<Double>& frequency) const = 0;
00222 
00223   // determine whether the shape is symmetric or not. If it is then all the
00224   // scale factors returned by the visibility functions will be real numbers.
00225   virtual Bool isSymmetric() const = 0;
00226 
00227   // Return a pointer to a copy of the derived object upcast to a
00228   // ComponentShape object. The class that uses this function is responsible
00229   // for deleting the pointer. This is used to implement a virtual copy
00230   // constructor.
00231   virtual ComponentShape* clone() const = 0;
00232 
00233   // return the number of parameters in this shape and set/get them. The error
00234   // functions provide a way to set/get the error (nominally 1-sigma in an
00235   // implicit Gaussian distribution) in the corresponding parameter.
00236   // <group>
00237   virtual uInt nParameters() const = 0;
00238   virtual void setParameters(const Vector<Double>& newParms) = 0;
00239   virtual Vector<Double> parameters() const = 0;
00240   virtual void setErrors(const Vector<Double>& newErrs) = 0;
00241   virtual Vector<Double> errors() const = 0;
00242   virtual Vector<Double> optParameters() const = 0;
00243   virtual void setOptParameters(const Vector<Double>& newOptParms) = 0;
00244   // </group>
00245 
00246   // These functions convert between a record and a ComponentShape. This way
00247   // derived classes can interpret fields in the record in a class specific
00248   // way. They return False if the record is malformed and append an error
00249   // message to the supplied string giving the reason.  These functions define
00250   // how the shape is represented in glish. All records should have 'type' &
00251   // 'direction' fields which contain respectively; a string indicating which
00252   // shape is actually used, and a record representation of a direction
00253   // measure.  The interpretation of all other fields depends on the specific
00254   // component shape used.
00255   // <group>
00256   virtual Bool fromRecord(String& errorMessage, 
00257                           const RecordInterface& record) = 0;
00258   virtual Bool toRecord(String& errorMessage,
00259                         RecordInterface& record) const = 0;
00260   // </group>
00261 
00262   // Convert the parameters of the shape to the specified units. The Record
00263   // must contain the same fields that the to/from Record functions have (with
00264   // the exception of the direction & type fields). These fields will contain
00265   // strings (and not record representations of Quantums) that specify the new
00266   // units for these parameters. The new units must have the same dimensions as
00267   // the existing ones. If there is any problem parsing the record then an
00268   // error message is appended to the supplied string and the function returns
00269   // False.
00270   virtual Bool convertUnit(String& errorMessage,
00271                            const RecordInterface& record) = 0;
00272   
00273   // Return the shape that the supplied record represents. The
00274   // shape is determined by parsing a 'type' field in the supplied
00275   // record. Returns ComponentType::UNKNOWN_SHAPE if the type field
00276   // (which contains a string) could not be translated into a known
00277   // shape. It then appends an appropriate error message to the errorMessage
00278   // String.
00279   static ComponentType::Shape getType(String& errorMessage,
00280                                       const RecordInterface& record);
00281 
00282   // Convert component shape to absolute pixels.  The returned
00283   // vector is the longitude and latitude location in absolute pixels.
00284   virtual Vector<Double> toPixel (const DirectionCoordinate& dirCoord) const;
00285 
00286   // Fill the shape direction from the vector (longitude and latitude
00287   // in absolute pixels).  The return value is always True.
00288   virtual Bool fromPixel (const Vector<Double>& parameters,
00289                           const DirectionCoordinate& dirCoord);
00290 
00291   // Function which checks the internal data of this class for correct
00292   // dimensionality and consistant values. Returns True if everything is fine
00293   // otherwise returns False.
00294   virtual Bool ok() const;
00295 
00296   // Return a pointer to the object. All subclasses must implement. 
00297   virtual const ComponentShape* getPtr() const = 0;
00298 
00299   // Return a nicely formatted string describing the component's size.
00300   // All subclasses must implement.
00301   virtual String sizeToString() const = 0;
00302 
00303 protected:
00304   // The constructors and assignment operator are protected as only derived
00305   // classes should use them.
00306   // <group>
00307   //# The default ComponentShape direction is at the J2000 North Pole.
00308   ComponentShape();
00309 
00310   //# Construct a ComponentShape at the specified direction.
00311   ComponentShape(const MDirection& direction);
00312 
00313   //# The copy constructor uses copy semantics.
00314   ComponentShape(const ComponentShape& other);
00315 
00316   //# The assignment operator uses copy semantics.
00317   ComponentShape& operator=(const ComponentShape& other);
00318   // </group>
00319 
00320   //# Try and decide if the two reference directions are different, as the
00321   //# MeasRef<T>::operator== function is too restrictive.
00322   static Bool differentRefs(const MeasRef<MDirection>& ref1,
00323                             const MeasRef<MDirection>& ref2);
00324 
00325   // returns True if the quantum is not a non-negative angular quantity
00326   static Bool badError(const Quantum<Double>& quantum);
00327 
00328   // Turns the specified field in the specified record into an Quantum 
00329   // with angular units
00330   static Bool fromAngQRecord(Quantum<Double>& returnValue, 
00331                              String& errorMessage,
00332                              const String& fieldString, 
00333                              const RecordInterface& record);
00334 
00335 private:
00336   //# The reference direction of the component
00337   MDirection itsDir;
00338   //# The errors in the reference direction of the component in radians
00339   Quantum<Double> itsDirErrLat;
00340   Quantum<Double> itsDirErrLong;
00341 };
00342 
00343 } //# NAMESPACE CASA - END
00344 
00345 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1