casa
$Rev:20696$
|
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