//# SkyCompBase.h: Base class for model components of the sky brightness //# Copyright (C) 1996,1997,1998,1999,2000,2003 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# //# $Id: SkyCompBase.h 18093 2004-11-30 17:51:10Z ddebonis $ #ifndef COMPONENTS_SKYCOMPBASE_H #define COMPONENTS_SKYCOMPBASE_H #include <casacore/casa/aips.h> #include <components/ComponentModels/ComponentType.h> #include <casacore/casa/Utilities/RecordTransformable.h> #include <casacore/casa/BasicSL/Complexfwd.h> #include <casacore/casa/Arrays/ArrayFwd.h> namespace casacore{ class MFrequency; class MVFrequency; class MDirection; class MVDirection; class MVAngle; class RecordInterface; class String; class Unit; template <class Ms> class MeasRef; } namespace casa { //# NAMESPACE CASA - BEGIN class ComponentShape; class SpectralModel; template <class T> class Flux; // <summary>Base class for model components of the sky brightness</summary> // <use visibility=export> // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> // </reviewed> // <prerequisite> // <li> <linkto class=Flux>Flux</linkto> // <li> <linkto class=ComponentShape>ComponentShape</linkto> // <li> <linkto class=SpectralModel>SpectralModel</linkto> // </prerequisite> // // <synopsis> // This abstract base class defines the interface for classes that model the // sky brightness. // A model of the sky brightness is defined by three properties. // <dl> // <dt><em>A Flux</em> // <dd> This is the integrated brightness of the component. // <dt><em>A Shape</em> // <dd> This defines how the sky brightness varies as a function of position on // the sky. Currently two shapes are supported, // <linkto class=PointShape>points</linkto> and // <linkto class=GaussianShape>Gaussians</linkto>. // <dt><em>A Spectrum</em> // <dd> This defines how the component flux varies as a function of frequency. // Currently two spectral models are supported. The simplest assumes the // spectrum is <linkto class=ConstantSpectrum>constant</linkto> with // frequency. Alternatively a // <linkto class=SpectralIndex>spectral index</linkto> model can be used. // </dl> // These three properties of a component can be obtained using the // <src>flux</src>, <src>shape</src> or <src>spectrum</src> functions defined // in this interface. Each of these properties is represented by an object that // contains functions for manipulating the parameters associated with that // property. eg. to set the direction of the component you would use: // <srcblock> SkyComponent comp; comp.shape().setRefDirection(newDirection); // </srcblock> See the <linkto class=Flux>Flux</linkto>, // <linkto class=ComponentShape>ComponentShape</linkto> or // <linkto class=SpectralModel>SpectralModel</linkto> classes for more // information on these properties and how to manipulate them. // Besides these three properties the <src>label</src> functions are provided // to associate a text string with the component. // A model of the sky brightness is by itself not very useful unless you can do // something with it. This class contains functions for deriving information // from the components. These functions are: // <dl> // <dt><src>sample</src> // <dd> This function will return the the flux in an specified pixel, at a // specified direction at a specified frequency. // <dt><src>project</src> // <dd> This function will generate an image of the component, given a user // specified casacore::ImageInterface object. // <dt><src>visibility</src> // <dd> This function will return the visibility (spatial coherence) that would // be measured if the component was at the field centre of an // interferometer with a specified (u,v,w) coordinates and observation // frequency. // </dl> // The <src>toRecord</src> & <src>fromRecord</src> functions are used to // convert between a SkyCompBase object and a record representation. This is // primarily so that a component can be represented in Glish. // </synopsis> // <example> // Because SpectralModel is an abstract base class, an actual instance of this // class cannot be constructed. However the interface it defines can be used // inside a function. This is always recommended as it allows functions which // have SkyCompBase's as arguments to work for any derived class. // These examples are coded in the dSkyCompBase.cc file. // <h4>Example 1:</h4> // In this example the printComp function prints out the some basic information // on the spatial, spectral and flux properties of the component. // <srcblock> // void printComponent(const SkyCompBase & comp) { // cout << "This component has a flux of " // << comp.flux().value() // << " " << comp.flux().unit().getName() << endl; // cout << "and a " << ComponentType::name(comp.flux().pol()) // << " polarisation" << endl; // cout << "This component has a " // << ComponentType::name(comp.shape().type()) << " shape" << endl; // cout << "with a reference direction of " // << comp.shape().refDirection().getAngle("deg") << endl; // cout << "This component has a " // << ComponentType::name(comp.spectrum().type()) << " spectrum" << endl; // cout << "with a reference frequency of " // << comp.spectrum().refFrequency().get("GHz") << endl; // } // </srcblock> // </example> // // <motivation> // I wanted to force the interfaces of the SkyCompRep and the SkyComponent // classes to be the same. The best way I found was the introduction of a // base class that these other classes would derive from. // </motivation> // <todo asof="1998/05/20"> // <li> Nothing I hope! // </todo> class SkyCompBase: public casacore::RecordTransformable { public: // The destructor does not anything virtual ~SkyCompBase(); // return a reference to the flux of the component. Because this is a // reference, manipulation of the flux values is performed through the // functions in the Flux class. eg., // <src>comp.flux().setValue(newVal)</src>. If the component flux varies with // frequency then the flux set using this function is the value at the // reference frequency. // <group> virtual const Flux<casacore::Double>& flux() const = 0; virtual Flux<casacore::Double>& flux() = 0; // </group> // return a reference to the shape of the component. Because this is a // reference, manipulation of the shape of the component is performed through // the functions in the ComponentShape (or derived) class. eg., // <src>comp.shape().setRefDirection(newVal)</src>. To change the shape to a // different type you must use the <src>setShape</src> function. // <group> virtual const ComponentShape& shape() const = 0; virtual ComponentShape& shape() = 0; virtual void setShape(const ComponentShape& newShape) = 0; // </group> // return a reference to the spectrum of the component. Because this is a // reference, manipulation of the spectrum of the component is performed // through the functions in the SpectralModel (or derived) class. eg., // <src>refFreq = comp.spectrum().refFrequency()</src>. Touse a different // spectral model you must use the <src>setSpectrum</src> function. // <group> virtual const SpectralModel& spectrum() const = 0; virtual SpectralModel& spectrum() = 0; virtual void setSpectrum(const SpectralModel& newSpectrum) = 0; // </group> // return a reference to the label associated with this component. The label // is a text string for general use. // <group> virtual casacore::String& label() = 0; virtual const casacore::String& label() const = 0; // </group> // return a reference to the label associated with this component. The label // is a text string for general use. // <group> virtual casacore::Vector<casacore::Double>& optionalParameters() = 0; virtual const casacore::Vector<casacore::Double>& optionalParameters() const = 0; // </group> // Return true if the component parameters are physically plausable. This // checks that I, Q, U, & V are all real numbers and if // I^2 >= Q^2 + U^2 + U^2 virtual casacore::Bool isPhysical() const = 0; // Calculate the flux at the specified direction & frequency, in a pixel of // specified x & y size. virtual Flux<casacore::Double> sample(const casacore::MDirection& direction, const casacore::MVAngle& pixelLatSize, const casacore::MVAngle& pixelLongSize, const casacore::MFrequency& centerFrequency) const = 0; // Same as the previous function except that many directions & frequencies // are done at once. The flux is added into the values supplied in the // samples argument and this cube must have dimensions of [4, nDirs, // nFreqs]. The polarisations are always [I, Q, U, V] and units of the flux // added are specified with the reqUnits arguments. virtual void sample(casacore::Cube<casacore::Double>& samples, const casacore::Unit& reqUnit, const casacore::Vector<casacore::MVDirection>& directions, const casacore::MeasRef<casacore::MDirection>& dirRef, const casacore::MVAngle& pixelLatSize, const casacore::MVAngle& pixelLongSize, const casacore::Vector<casacore::MVFrequency>& frequencies, const casacore::MeasRef<casacore::MFrequency>& freqRef) const = 0; // Return the Fourier transform of the component at the specified point in // the spatial frequency domain. The point is specified by a 3-element vector // (u,v,w) that has units of meters and the frequency of the observation, in // Hertz. These two quantities can be used to derive the required spatial // frequency <src>(s = uvw*freq/c)</src>. The w component is not used in // these functions. // The "origin" of the transform is the reference direction of the // component. This means, for symmetric components where the reference // direction is at the centre, that the Fourier transform will always be // real. virtual Flux<casacore::Double> visibility(const casacore::Vector<casacore::Double>& uvw, const casacore::Double& frequency) const = 0; // Same as the previous function except that many (u,v,w) points are done at // once. The visibilities are returned in the first argument which must have // dimensions of [4, nChan, nVis]. The points to sample are specified in the // second argument which must have dimensions of [3, nVis], and the // frequencies to sample are specified by the third argument which must have // a length of nChan. The units and polarisation of the returned visibilities // are the same as the flux of this object, and can be queried using the // <src>flux().units()</src> & <src>flux().pol()</src> functions. virtual void visibility(casacore::Cube<casacore::DComplex>& visibilities, const casacore::Matrix<casacore::Double>& uvws, const casacore::Vector<casacore::Double>& frequencies) const = 0; // This functions convert between a record and a component. Derived classes // can interpret fields in the record in a class specific way. These // functions define how a component is represented in glish. They return // false if the record is malformed and append an error message to the // supplied string giving the reason. // <group> virtual casacore::Bool fromRecord(casacore::String& errorMessage, const casacore::RecordInterface& record) = 0; virtual casacore::Bool toRecord(casacore::String& errorMessage, casacore::RecordInterface& record) const = 0; // </group> // casacore::Function which checks the internal data of this class for correct // dimensionality and consistant values. Returns true if everything is fine // otherwise returns false. virtual casacore::Bool ok() const = 0; }; } //# NAMESPACE CASA - END #endif