00001 //# SpectralIndex.h: Models the spectral variation with a spectral index 00002 //# Copyright (C) 2010 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: TabularSpectrum.h 21282 2012-11-05 11:04:19Z gervandiepen $ 00027 00028 #ifndef COMPONENTS_TABULARSPECTRUM_H 00029 #define COMPONENTS_TABULARSPECTRUM_H 00030 00031 #include <casa/aips.h> 00032 #include <components/ComponentModels/ComponentType.h> 00033 #include <components/ComponentModels/SpectralModel.h> 00034 #include <components/ComponentModels/Flux.h> 00035 namespace casa { //# NAMESPACE CASA - BEGIN 00036 00037 class MFrequency; 00038 class RecordInterface; 00039 class String; 00040 template <class T> class Vector; 00041 00042 // <summary>Models the spectral variation with a spectral index</summary> 00043 00044 // <use visibility=export> 00045 00046 // <reviewed reviewer="" date="yyyy/mm/dd" tests="tSpectralIndex" demos="dSpectralModel"> 00047 // </reviewed> 00048 00049 // <prerequisite> 00050 // <li> <linkto class="SpectralModel">SpectralModel</linkto> 00051 // </prerequisite> 00052 // 00053 // <synopsis> 00054 00055 // This class models the spectral variation of a component with measured 00056 // values at given frequencies. The values are interpolated in betweenm 00057 00058 // This class like the other spectral models becomes more useful when used 00059 // through the <linkto class=SkyComponent>SkyComponent</linkto> class, which 00060 // incorperates the flux and spatial variation of the emission, or through the 00061 // <linkto class=ComponentList>ComponentList</linkto> class, which handles 00062 // groups of SkyComponent objects. 00063 00064 00065 // As with all classes derived from SpectralModel the basic operation of this 00066 // class is to model the flux as a function of frequency. This class does not 00067 // know what the flux is at the reference frequency. Instead the sample 00068 // functions return factors that are used to scale the flux and calculate the 00069 // amount of flux at a specified frequency. 00070 00071 // Besides the reference frequency this class has one parameter; the spectral 00072 // index. This parameter can be set & queried using the general purpose 00073 // <src>parameters</src> functions or the class specific <src>index</src> 00074 // functions. 00075 00076 // This class also contains functions (<src>toRecord</src> & 00077 // <src>fromRecord</src>) which perform the conversion between Records and 00078 // SpectralIndex objects. These functions define how a SpectralIndex 00079 // object is represented in glish. The format of the record that is generated 00080 // and accepted by these functions is: 00081 // <srcblock> 00082 // c = {'type' : 'tabular', 00083 // 'frequency' : {'type' : 'frequency', 00084 // refer : 'lsr', 00085 // m0 :{'value' : [1,1.1, 1.2, 1.3, 1.4], 'unit' : 'GHz'} 00086 // }, 00087 00088 // 'flux' : {'value' : [1.0,1.1, 1.2, 1.3, 1.4], 'unit' : 'Jy'} 00089 // } 00090 // </srcblock> 00091 // The frequency field contains a record representation of a vector frequency 00092 // measure 00093 // and its format is defined in the Measures module. Its refer field defines 00094 // the reference frame for the direction and the m0 field defines the value of 00095 // the reference frequency. The parsing of the type field is case 00096 // insensitive. The index field contains the spectral index. 00097 // </synopsis> 00098 00099 // 00100 // <example> 00101 // These examples are coded in the tSpectralModel.h file. 00102 // <h4>Example 1:</h4> 00103 // In this example a SpectralIndex object is created and used to calculate the 00104 // flux at a number of frequencies. 00105 // <srcblock> 00106 // SpectralIndex siModel; 00107 // siModel.setRefFrequency(MFrequency(Quantity(1.0, "GHz"))); 00108 // siModel.setIndex(1.0, Stokes::I); 00109 // siModel.setIndex(0.5, Stokes::Q); 00110 // siModel.setIndex(0.5, Stokes::U); 00111 // siModel.setIndex(-1.0, Stokes::V); 00112 // const Flux<Double> LBandFlux(1.0, 1.0, 1.0, 1.0); 00113 // const MVFrequency step(Quantity(100.0, "MHz")); 00114 // MVFrequency sampleFreq = siModel.refFrequency().getValue(); 00115 // Flux<Double> sampleFlux; 00116 // cout << "Frequency\t I-Flux\t Q-Flux\t U-Flux\t V-Flux\n"; 00117 // for (uInt i = 0; i < 11; i++) { 00118 // sampleFlux = LBandFlux.copy(); 00119 // sampleFlux.convertPol(ComponentType::LINEAR); 00120 // sampleFlux.convertUnit(Unit("WU")); 00121 // siModel.sample(sampleFlux, 00122 // MFrequency(sampleFreq, siModel.refFrequency().getRef())); 00123 // cout << setprecision(3) << sampleFreq.get("GHz") 00124 // << "\t\t " << sampleFlux.value(0u).re 00125 // << "\t " << sampleFlux.value(1u).re 00126 // << "\t " << sampleFlux.value(2u).re 00127 // << "\t " << sampleFlux.value(3u).re 00128 // << " " << sampleFlux.unit().getName() << endl; 00129 // sampleFreq += step; 00130 // } 00131 // </srcblock> 00132 // </example> 00133 // 00134 // <motivation> A Spectral Index frequency variation is the most widely used 00135 // model in radio astronomy. In particular the NFRA package 'newstar' uses it 00136 // extensively. 00137 // </motivation> 00138 // 00139 // <todo asof="1999/11/23"> 00140 // <li> Nothing I hope 00141 // </todo> 00142 00143 // <linkfrom anchor="SpectralIndex" classes="SpectralModel ConstantSpectrum"> 00144 // <here>SpectralIndex</here> - Uses a spectral index to model the spectrum 00145 // </linkfrom> 00146 00147 class TabularSpectrum: public SpectralModel 00148 { 00149 public: 00150 // The default SpectralIndex has a reference frequency of 1 GHz in the LSR 00151 // frame and a spectral index of zero. As such it is no different from the 00152 // ConstantSpectrum class (except slower). 00153 TabularSpectrum(); 00154 00155 // Construct a Tabular values with I and f specified 00156 // exponent. 00157 TabularSpectrum(const MFrequency& refFreq, const Vector<MFrequency::MVType>& freq, 00158 const Vector<Flux<Double> >& flux, const MFrequency::Ref& refFrame); 00159 00160 // The copy constructor uses copy semantics 00161 TabularSpectrum(const TabularSpectrum& other); 00162 00163 // The destructor does nothing special. 00164 virtual ~TabularSpectrum(); 00165 00166 // The assignment operator uses copy semantics. 00167 TabularSpectrum& operator=(const TabularSpectrum& other); 00168 00169 // return the actual spectral type ie., ComponentType::TABULAR_SPECTRUM 00170 virtual ComponentType::SpectralShape type() const; 00171 00172 virtual void setRefFrequency(const MFrequency& newRefFreq); 00173 // set/get the Tabular values 00174 // <group> 00175 void values(Vector<MFrequency::MVType>& freq, Vector<Flux<Double> >& flux) const; 00176 void setValues(const Vector<MFrequency::MVType>& frequencies, const Vector<Flux<Double> >& flux, const MFrequency::Ref& refFrame); 00177 // </group> 00178 00179 // Return the scaling factor that indicates what proportion of the flux is at 00180 // the specified frequency. ie. if the centreFrequency argument is the 00181 // reference frequency then this function will always return one. At other 00182 // frequencies it will return a non-negative number. 00183 virtual Double sample(const MFrequency& centerFrequency) const; 00184 virtual void sampleStokes(const MFrequency& centerFrequency, Vector<Double>& iquv) const; 00185 // Same as the previous function except that many frequencies can be sampled 00186 // at once. The reference frame must be the same for all the specified 00187 // frequencies. Uses a customised implementation for improved speed. 00188 virtual void sample(Vector<Double>& scale, 00189 const Vector<MFrequency::MVType>& frequencies, 00190 const MFrequency::Ref& refFrame) const; 00191 00192 virtual void sampleStokes(Vector<Vector<Double> >& iquv, 00193 const Vector<MFrequency::MVType>& frequencies, 00194 const MFrequency::Ref& refFrame) const; 00195 00196 // Return a pointer to a copy of this object upcast to a SpectralModel 00197 // object. The class that uses this function is responsible for deleting the 00198 // pointer. This is used to implement a virtual copy constructor. 00199 virtual SpectralModel* clone() const; 00200 00201 // return the number of parameters. There is one parameter for this spectral 00202 // model, namely the spectral index. So you supply a unit length vector when 00203 // using these functions. Otherwise an exception (AipsError) may be thrown. 00204 // <group> 00205 virtual uInt nParameters() const; 00206 virtual void setParameters(const Vector<Double>& newSpectralParms); 00207 virtual Vector<Double> parameters() const; 00208 virtual void setErrors(const Vector<Double>& newSpectralErrs); 00209 virtual Vector<Double> errors() const; 00210 // </group> 00211 00212 // These functions convert between a Record and a SpectralIndex. These 00213 // functions define how a SpectralIndex object is represented in glish and 00214 // this is detailed in the synopsis above. These functions return False if 00215 // the record is malformed and append an error message to the supplied string 00216 // giving the reason. 00217 // <group> 00218 virtual Bool fromRecord(String& errorMessage, const RecordInterface& record); 00219 virtual Bool toRecord(String& errorMessage, RecordInterface& record) const; 00220 // </group> 00221 00222 // Convert the parameters of the spectral index object to the specified 00223 // units. Only one field of the supplied record is used, namely 'index'. This 00224 // field is optional as the spectral index is a unitless quantity. If the 00225 // index field is specified it must have the empty string as its value. This 00226 // function always returns True unless the index field is specified and does 00227 // not contain an empty string. 00228 virtual Bool convertUnit(String& errorMessage, 00229 const RecordInterface& record); 00230 00231 // Function which checks the internal data of this class for consistant 00232 // values. Returns True if everything is fine otherwise returns False. 00233 virtual Bool ok() const; 00234 00235 private: 00236 00237 MFrequency::Ref freqRef_p; 00238 Vector<Double> tabFreqVal_p; 00239 Vector<Flux<Double> > flux_p; 00240 Vector<Double> ival_p, qval_p, uval_p, vval_p; 00241 Vector<Double> refVal_p; 00242 Double referenceFreq_p; 00243 Double maxFreq_p; 00244 Double minFreq_p; 00245 00246 }; 00247 00248 } //# NAMESPACE CASA - END 00249 00250 #endif