SpectralCoordinate.h

Go to the documentation of this file.
00001 //# SpectralCoordinate.h: Interconvert between pixel and frequency.
00002 //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2004
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 //#
00027 //# $Id$
00028 
00029 
00030 #ifndef COORDINATES_SPECTRALCOORDINATE_H
00031 #define COORDINATES_SPECTRALCOORDINATE_H
00032 
00033 #include <casacore/casa/aips.h>
00034 #include <casacore/casa/Arrays/Vector.h>
00035 #include <casacore/coordinates/Coordinates/Coordinate.h>
00036 #include <casacore/coordinates/Coordinates/ObsInfo.h>
00037 #include <casacore/measures/Measures/MFrequency.h>
00038 #include <casacore/measures/Measures/MDoppler.h>
00039 #include <casacore/measures/Measures/MDirection.h>
00040 #include <casacore/measures/Measures/MPosition.h>
00041 #include <casacore/measures/Measures/MEpoch.h>
00042 #include <casacore/casa/Quanta/Quantum.h>
00043 #include <casacore/casa/Utilities/PtrHolder.h>
00044 
00045 #include <wcslib/wcs.h>
00046 
00047 
00048 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00049 
00050 
00051 class TabularCoordinate;
00052 class LogIO;
00053 class MVFrequency;
00054 class VelocityMachine;
00055 template<class T> class Quantum;
00056 
00057 
00058 // <summary>
00059 // Interconvert pixel and frequency values.
00060 // </summary>
00061 
00062 // <use visibility=export>
00063 
00064 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tSpectralCoordinate">
00065 // </reviewed>
00066 //
00067 // <prerequisite>
00068 //   <li> <linkto class=Coordinate>Coordinate</linkto>
00069 //   <li> <linkto class=MFrequency>MFrequency</linkto>,
00070 //        <linkto class=MDoppler>MDoppler</linkto> and
00071 //        <linkto class=VelocityMachine>VelocityMachine</linkto> 
00072 //        classes if you want radial velocities.
00073 // </prerequisite>
00074 //
00075 // <synopsis>
00076 // This class performs the mapping from pixel to frequency. 
00077 // This can be done via a Tabular lookup or via an algorithmic
00078 // implementation which may be linear or non-linear.  The latter
00079 // is implemented via the WCS library.
00080 // 
00081 // </synopsis>
00082 //
00083 
00084 // <note role=caution>
00085 // All pixels coordinates are zero relative.
00086 // </note>
00087 //
00088 // <example>
00089 // Let us make a linear SpectralCoordinate first
00090 // <srcblock>
00091 //   Double restfreq = 1.420405752E9;
00092 //   Double crpix = 10.0;
00093 //   Double crval = 1.4e9;
00094 //   Double cdelt = 1.0e6;
00095 //   SpectralCoordinate sc(MFrequency::TOPO, crval, cdelt, crpix, restfreq);
00096 //
00097 //   Double world, pixel;
00098 //   pixel = 12.1;
00099 //   if (!sc.toWorld(world, pixel)) {
00100 //      cerr << "Error : " << sc.errorMessage() << endl;
00101 //   } else {
00102 //      cerr << "pixel, world = " << pixel << ", " << world << endl;
00103 //   }
00104 //
00105 // </srcblock>
00106 // </example>
00107 //
00108 // <example>
00109 // Now we make a non-linear SpectralCoordinate 
00110 // <srcblock>
00111 //   Vector<Double> freqs(5);
00112 //   freqs(0) = 1.4e9; freqs(1) = 1.41e9;
00113 //   freqs(2) = 1.43e9; freqs(3) = 1.44e9;
00114 //   freqs(4) = 1.47e9;
00115 //   SpectralCoordinate sc(MFrequency::LSRK, freqs, restfreq);
00116 //
00117 //   Double world, pixel;
00118 //   world = 1.42e9;
00119 //   if (!sc.toPixel(pixel, world)) {
00120 //      cerr << "Error : " << sc.errorMessage() << endl;
00121 //   } else {
00122 //      cerr << "world, pixel = " << world << ", " << pixel << endl;
00123 //   }
00124 //
00125 // </srcblock>
00126 // </example>
00127 //
00128 // <motivation>
00129 //  Spectral-line astronomy requires a specialized SpectralCoordinate.
00130 // </motivation>
00131 
00132 // <todo asof="2000/01/01">
00133 //   <li> Allow other than linear interpolations for frequency lookup.
00134 // </todo>
00135 // 
00136 
00137 class SpectralCoordinate : public Coordinate
00138 {
00139 public:
00140          enum SpecType { // taken from the FITS spectral coordinate type codes
00141                  FREQ,
00142                  VRAD,
00143                  VOPT,
00144                  BETA,
00145                  WAVE,
00146                  AWAV
00147          };
00148 
00149          // Default constructor.    It is equivalent to doing
00150     // SpectralCoordinate(MFrequency::TOPO, 0.0, 1.0, 0.0)
00151     SpectralCoordinate();
00152 
00153     // Create a linear frequency axis SpectralCoordinate
00154     // <src>f0</src> is the frequency of the reference pixel, <src>inc</src> is the pixel increment,
00155     // <src>refPix</src> is the reference pixel. You can
00156     // optionally store the rest frequency for later use in calculating radial
00157     // velocities.  Use 0 for restFrequency if continuum.
00158     //
00159     // Frequencies and increments initially in Hz.
00160     SpectralCoordinate(MFrequency::Types type, Double f0, Double inc, 
00161                        Double refPix, Double restFrequency = 0.0);
00162 
00163     // Create linear frequency axis SpectralCoordinate with Quantum-based interface. 
00164     // Parameters are the same as above.
00165     // Regardless of the units of the Quanta, the initial units
00166     // of the SpectralCoordinate will be Hz.  You can change it to 
00167     // something else with the setWorldAxisUnits method later if you want.
00168     // Use 0 for restFrequency if continuum.
00169     SpectralCoordinate(MFrequency::Types type, const Quantum<Double>& f0, 
00170                        const Quantum<Double>& inc, Double refPix, 
00171                        const Quantum<Double>& restFrequency = Quantum<Double>(0.0,"Hz"));
00172 
00173     // Construct a SpectralCoordinate with the specified frequencies (in Hz).
00174     // This axis can be nonlinear; the increments and related 
00175     // functions return the <src>average</src> values
00176     // (calculated from the first and last pixel's frequencies).
00177     //
00178     // A linear interpolation/extrapolation is used for pixels which are
00179     // not supplied. The reference pixel is chosen to be 0.
00180     // The frequencies must increase or decrease monotonically (otherwise
00181     // the toPixel lookup would not be possible).
00182     // Use 0 for restFrequency if continuum.
00183     SpectralCoordinate(MFrequency::Types type, const Vector<Double> &freqs,
00184                        Double restFrequency = 0.0);
00185     
00186     // Construct a SpectralCoordinate with the specified frequencies
00187     // with Quantum-based interface. 
00188     // Parameters are the same as above.
00189     // Regardless of the units of the Quanta, the initial units
00190     // of the SpectralCoordinate will be Hz.
00191     // Use 0 for restFrequency if continuum.
00192     SpectralCoordinate(MFrequency::Types type, const Quantum<Vector<Double> >& freqs,
00193                        const Quantum<Double>& restFrequency = Quantum<Double>(0.0,"Hz"));
00194 
00195     // Construct a SpectralCoordinate with the specified velocities (in km/s).
00196     // They will be converted to Hz and the SpectralCoordinate constructed.
00197     // This axis can be nonlinear; the increments and related 
00198     // functions return the <src>average</src> values
00199     // (calculated from the first and last pixel's frequencies).
00200     //
00201     // A linear interpolation/extrapolation is used for pixels which are
00202     // not supplied. The reference pixel is chosen to be 0.
00203     // The velocities must increase or decrease monotonically (otherwise
00204     // the toPixel lookup would not be possible).
00205     SpectralCoordinate(MFrequency::Types freqType, MDoppler::Types velType, 
00206                        const Vector<Double>& velocities,  const String& velUnit,
00207                        Double restFrequency = 0.0);
00208 
00209     // Construct a SpectralCoordinate with the specified wavelengths (in mm).
00210     // They will be converted to Hz and the SpectralCoordinate constructed.
00211     // This axis can be nonlinear; the increments and related 
00212     // functions return the <src>average</src> values
00213     // (calculated from the first and last pixel's frequencies).
00214     // If inAir is True, the input wavelengths are assumed to be Air Wavelengths.
00215     // They are converted to vacuum frequency using the refractive index
00216     // which is calculated based on the mean input air wavelength.
00217     //
00218     // A linear interpolation/extrapolation is used for pixels which are
00219     // not supplied. The reference pixel is chosen to be 0.
00220     // The wavelengths must increase or decrease monotonically (otherwise
00221     // the toPixel lookup would not be possible).
00222     SpectralCoordinate(MFrequency::Types freqType,     
00223                        const Vector<Double>& wavelengths,  const String& waveUnit,
00224                        Double restFrequency = 0.0, Bool inAir = False);
00225 
00226     // Construct from wcs structure.  Must hold only a spectral wcs structure
00227     // Specify whether the absolute pixel coordinates in the wcs structure
00228     // are 0- or 1-relative.  The coordinate is always constructed with 0-relative
00229     // pixel coordinates
00230     SpectralCoordinate(MFrequency::Types freqType, const ::wcsprm& wcs, Bool oneRel=True);
00231     
00232     // Copy constructor (copy semantics).
00233     SpectralCoordinate(const SpectralCoordinate &other);
00234 
00235     // Assignment (copy semantics).
00236     SpectralCoordinate &operator=(const SpectralCoordinate &other);
00237 
00238     // Destructor.
00239     virtual ~SpectralCoordinate();
00240 
00241     // Always returns Coordinate::SPECTRAL.
00242     virtual Coordinate::Type type() const;
00243 
00244     // Always returns the String "Spectral".
00245     virtual String showType() const;
00246 
00247     // Always returns 1.
00248     // <group>
00249     virtual uInt nPixelAxes() const;
00250     virtual uInt nWorldAxes() const;
00251     // </group>
00252 
00253     // Set extra conversion layer.  Whenever a conversion from pixel to world is done,
00254     // the world value is then further converted to this MFrequency::Types value.
00255     // For example, your SpectralCoordinate may be defined in LSRK.
00256     // You can use this to get the world values out in say BARY. You must
00257     // specify the position on earth, the epoch and the direction for the conversions
00258     // and it is your responsibility to ensure they are viable.
00259     // Similarly, whenever you convert from world to pixel, the world
00260     // value is assumed to be that appropriate to the setReferenceConversion type.
00261     // It is first converted to the MFrequency::Types with which the
00262     // SpectralCoordinate was constructed and from there to pixel.
00263     // If you don't call this function, or you set the same type
00264     // for which the SpectralCoordinate was constructed, no extra
00265     // conversions occur.   Some conversions will fail.  These are the
00266     // ones that require extra frame information (radial velocity) such
00267     // as to REST. This will be added later.  In this case this function
00268     // returns False (and the conversion parameters are all left as they were),
00269    //  else it returns True.
00270     // <group>
00271     Bool setReferenceConversion (MFrequency::Types type,
00272                                  const MEpoch& epoch, const MPosition& position,
00273                                  const MDirection& direction);
00274     void getReferenceConversion (MFrequency::Types& type,
00275                                  MEpoch& epoch, MPosition& position,
00276                                  MDirection& direction) const
00277        {type = conversionType_p; epoch=epoch_p; 
00278         position=position_p; direction=direction_p;};
00279     // </group>
00280 
00281     // Convert a pixel to a world coordinate or vice versa. Returns True
00282     // if the conversion succeeds, otherwise it returns False and
00283     // <src>errorMessage()</src> contains an error message.  The input vectors
00284     // must be of length one and the output vectors are resized if they are not
00285     // already of length one.
00286     // if <src>useConversionFrame</src>, if the coordinate has a conversion
00287     // layer frame, it is used. Else, the native frame is used for the conversion.
00288     // <group>
00289     virtual Bool toWorld(Vector<Double> &world, 
00290                          const Vector<Double> &pixel, Bool useConversionFrame=True) const;
00291     virtual Bool toPixel(Vector<Double> &pixel, 
00292                          const Vector<Double> &world) const;
00293     Bool toWorld(Double& world, const Double& pixel) const;
00294     Bool toPixel(Double& pixel, const Double& world) const;
00295     // </group>
00296 
00297     // Convert a pixel (channel number) into an MFrequency or MVFrequency and vice 
00298     // versa. Usually you will do
00299     // this for calculating velocities or converting frequencies from one frame
00300     // to another.
00301     // <group>
00302     Bool toWorld(MFrequency &world,
00303                  Double pixel) const;
00304     Bool toPixel(Double& pixel, const MFrequency &world) const;
00305     Bool toWorld(MVFrequency &world,
00306                  Double pixel) const;
00307     Bool toPixel(Double& pixel, const MVFrequency &world) const;
00308     // </group>
00309 
00310     // Batch up a lot of transformations. The first (most rapidly varying) axis
00311     // of the matrices contain the coordinates. Returns False if any conversion
00312     // failed  and  <src>errorMessage()</src> will hold a message.
00313     // The <src>failures</src> array (True for fail, False for success)
00314     // is the length of the number of conversions and
00315     // holds an error status for each conversion.  
00316     // <group>
00317     virtual Bool toWorldMany(Matrix<Double>& world,
00318                               const Matrix<Double>& pixel,
00319                               Vector<Bool>& failures) const;
00320     virtual Bool toPixelMany(Matrix<Double>& pixel,
00321                              const Matrix<Double>& world,   
00322                              Vector<Bool>& failures) const;
00323     // </group>
00324 
00325     // Set the state that is used for conversions from pixel and frequency to velocity
00326     // or wavelength. The SpectralCoordinate is constructed  with 
00327     // <src>MDoppler::RADIO</src> and <src>km/s</src> as the velocity conversion state
00328     // and <src>mm</src> as the wavelength conversion state.
00329     // The functions in this class which use this state are those that convert
00330     // to or from velocity.  Also, function <src>format</src> uses the Doppler
00331     // state set here.  If the function returns False it means the unit was 
00332     // not valid.  There will be an error message in function <src>errorMessage</src>
00333     // <group>
00334     Bool setVelocity (const String& velUnit=String("km/s"),
00335                       MDoppler::Types velType=MDoppler::RADIO);
00336 
00337     MDoppler::Types velocityDoppler () const {return velType_p;};
00338     String velocityUnit () const {return velUnit_p;};
00339     //
00340     Bool setWavelengthUnit (const String& waveUnit=String("mm"));
00341     String wavelengthUnit () const {return waveUnit_p;};
00342     //
00343     Bool setNativeType (const SpectralCoordinate::SpecType spcType);
00344     SpectralCoordinate::SpecType nativeType() const {return nativeType_p;}
00345 
00346     // </group>
00347     // Functions to convert to velocity (uses the current active
00348     // rest frequency) or wavelength.  There is no reference frame
00349     // change but you can specify the velocity Doppler and the output
00350     // units of the velocity with function <src>setVelocity</src>
00351     // or <src>setWavelength</src> respectively. When the input is a frequency stored 
00352     // as a Double it must be in the current units of the SpectralCoordinate.  
00353     // 
00354     // Note that the extra conversion layer (see function <src>setReferenceConversion</src>)
00355     // is active in the <src>pixelToVelocity</src> functions (because internally
00356     // the use <src>toWorld</src>) but not in the <src>frequencyToVelocity</src> 
00357     // or <src>frequencyToWavelength</src> functions.
00358     // <group>  
00359     Bool pixelToVelocity (Quantum<Double>& velocity, Double pixel) const;
00360     Bool pixelToVelocity (Double& velocity, Double pixel) const;
00361     Bool pixelToVelocity (Vector<Double>& velocity, const Vector<Double>& pixel) const;
00362     //
00363     Bool frequencyToVelocity (Quantum<Double>& velocity, Double frequency) const;
00364     Bool frequencyToVelocity (Quantum<Double>& velocity, const MFrequency& frequency) const;
00365     Bool frequencyToVelocity (Quantum<Double>& velocity, const MVFrequency& frequency) const;
00366     Bool frequencyToVelocity (Double& velocity, Double frequency) const;
00367     Bool frequencyToVelocity (Vector<Double>& velocity, const Vector<Double>& frequency) const;
00368     //
00369     Bool frequencyToWavelength (Vector<Double>& wavelength, const Vector<Double>& frequency) const;
00370     Bool frequencyToAirWavelength (Vector<Double>& wavelength, const Vector<Double>& frequency) const;
00371     // The refractive index of air (argument can be wavelength or airwavelength)
00372     // according to Greisen et al., 2006, A&A, 464, 746.
00373     // If airwavelength is used there is an error of the order of 1E-9.
00374     // Argument must be in micrometers!  
00375     //static Double refractiveIndex(const Double& lambda_um);
00376     // </group>
00377 
00378     // Functions to convert from velocity (uses the current active
00379     // rest frequency) or wavelength.  There is no reference frame
00380     // change but you can specify the velocity Doppler and the output
00381     // units of the velocity with function <src>setVelocity</src>
00382     // and those of the wavelength with <src>setWavelength</src>. 
00383     // When the input is a frequency stored 
00384     // as a Double it must be  in the current units of the SpectralCoordinate.  
00385     //
00386     // Note that the extra conversion layer (see function <src>setReferenceConversion</src>)
00387     // is active in the <src>pixelToVelocity</src> functions (because internally
00388     // the use <src>toPixel</src>) but not in the <src>frequencyToVelocity</src> functions.
00389     // <group>  
00390     Bool velocityToPixel (Double& pixel, Double velocity) const;
00391     Bool velocityToPixel (Vector<Double>& pixel, const Vector<Double>& velocity) const;
00392     // 
00393     Bool velocityToFrequency (Double& frequency, Double velocity) const;
00394     Bool velocityToFrequency (Vector<Double>& frequency, const Vector<Double>& velocity) const;
00395     //
00396     Bool wavelengthToFrequency (Vector<Double>& frequency, const Vector<Double>& wavelength) const;
00397     Bool airWavelengthToFrequency (Vector<Double>& frequency, const Vector<Double>& wavelength) const;
00398     // </group>
00399 
00400     // The SpectralCoordinate can maintain a list of rest frequencies
00401     // (e.g. multiple lines within a band).  However, only
00402     // one of them is active (e.g. for velocity conversions) at any 
00403     // one time.  Function <src>restFrequency</src> returns that
00404     // frequency.    Function <src>restFrequencies</src> returns   
00405     // all of the possible restfrequencies.
00406     //
00407     // When you construct the SpectralCoordinate, you give it one rest frequency
00408     // and it is the active one.  Thereafter you can add a new restfrequency
00409     // with function <src>setRestFrequency</src> (<src>append=True</src>) and 
00410     // that frequency will become the active one.    With this function
00411     // and <src>append=False</src>, the current active restfrequency will
00412     // be replaced by the one you give.
00413     //
00414     // You can change the list of
00415     // restfrequencies with function <src>setRestFrequencies</src>. When
00416     // you do so, you can either replace the list of rest frequencies or append to it.
00417     // You specify which frequency of the new (appended) list
00418     // becomes active.  
00419     //
00420     // You can also select the active rest frequency either by an index into
00421     // the current list (exception if out of range) given by
00422     // <src>restFrequencies()</src> or by the value in the list
00423     // nearest to the frequency you give.
00424     //
00425     // Whenever you change the active rest frequency, the class internals
00426     // are adjusted (e.g. the velocity machine is updated).
00427     // <group>
00428     Double restFrequency() const;
00429     const Vector<Double>& restFrequencies() const;
00430     Bool setRestFrequency(Double newFrequency, Bool append=False);
00431     void setRestFrequencies(const Vector<Double>& newFrequencies, uInt which=0,
00432                             Bool append=False);
00433     void selectRestFrequency(uInt which);
00434     void selectRestFrequency(Double frequency);
00435     String formatRestFrequencies () const;
00436     // </group>
00437   
00438     // Retrieve/set the frequency system.  Note that setting the
00439     // frequency system just changes the internal value of the
00440     // frequency system.  In addition, it will reset the internal
00441     // conversion frequency system to the new type and delete any
00442     // conversion machines.  
00443     // <group>
00444     MFrequency::Types frequencySystem(Bool showConversion=False) const;
00445     void setFrequencySystem(MFrequency::Types type, Bool verbose=True);
00446 
00447     // Transform the SpectralCoordinate to a different native reference frame
00448     // keeping the conversion layer as is
00449     Bool transformFrequencySystem(MFrequency::Types type, 
00450                                   const MEpoch& epoch,
00451                                   const MPosition& position,
00452                                   const MDirection& direction);
00453     // </group>
00454 
00455     // Report the value of the requested attribute.
00456     // <group>
00457     virtual Vector<String> worldAxisNames() const;
00458     virtual Vector<Double> referencePixel() const;
00459     virtual Matrix<Double> linearTransform() const;
00460     virtual Vector<Double> increment() const;
00461     virtual Vector<Double> referenceValue() const;
00462     // </group>
00463 
00464     // Set the value of the requested attribute. Note that these just
00465     // change the internal values, they do not cause any recomputation.
00466     // <group>
00467     virtual Bool setWorldAxisNames(const Vector<String> &names);
00468     virtual Bool setReferencePixel(const Vector<Double> &refPix);
00469     virtual Bool setLinearTransform(const Matrix<Double> &xform);
00470     virtual Bool setIncrement(const Vector<Double> &inc) ;
00471     virtual Bool setReferenceValue(const Vector<Double> &refval);
00472     // </group>
00473 
00474     // Get the table, i.e. the pixel and world values. The length of these
00475     // Vectors will be zero if this axis is pure linear (i.e. if the
00476     // channel and frequencies are related through an increment and offset).
00477     // <group>
00478     Vector<Double> pixelValues() const;
00479     Vector<Double> worldValues() const;
00480     // </group>
00481 
00482     // Set/get the unit. Adjust the increment and
00483     // reference value by the ratio of the old and new units.
00484     // The unit must be compatible with  frequency.
00485     //<group>
00486     virtual Bool setWorldAxisUnits(const Vector<String> &units);
00487     virtual Vector<String> worldAxisUnits() const;
00488     //</group>
00489 
00490     // Comparison function. Any private Double data members are compared
00491     // with the specified fractional tolerance.  Don't compare on the specified 
00492     // axes in the Coordinate.  If the comparison returns False, 
00493     // <src>errorMessage()</src> contains a message about why.
00494     // <group>
00495     virtual Bool near(const Coordinate& other, 
00496                       Double tol=1e-6) const;
00497     virtual Bool near(const Coordinate& other, 
00498                       const Vector<Int>& excludeAxes,
00499                       Double tol=1e-6) const;
00500     // </group>
00501 
00502 
00503     // Find the Coordinate for when we Fourier Transform ourselves.  This pointer
00504     // must be deleted by the caller. Axes specifies which axes of the Coordinate
00505     // you wish to transform.   Shape specifies the shape of the image
00506     // associated with all the axes of the Coordinate.   Currently the
00507     // output reference pixel is always shape/2.  Cannot transform tabular
00508     // coordinates.  If the pointer returned is 0, it failed with a message
00509     // in <src>errorMessage</src>
00510     virtual Coordinate* makeFourierCoordinate (const Vector<Bool>& axes,
00511                                                const Vector<Int>& shape) const;
00512 
00513 
00514     // Format a SpectralCoordinate coordinate world value nicely through the
00515     // common format interface.  See <linkto class=Coordinate>Coordinate</linkto>
00516     // for basics.
00517     //
00518     // Format types SCIENTIFIC, FIXED, MIXED and DEFAULT are supported.
00519     // DEFAULT will use MIXED.
00520     //
00521     // The world value must always be given in native frequency units.
00522     // Use argument <src>unit</src> to determine what it will be 
00523     // converted to for formatting. If <src>unit</src> is given, it 
00524     // must be dimensionally consistent with Hz, m, or m/s.   
00525     // If you give a unit consistent with m/s then the
00526     // appropriate velocity Doppler type is taken from that set by
00527     // function <src>setVelocity</src>.  There is no frame conversion.
00528     // If <src>unit</src> is empty, the unit given by <src>setFormatUnit</src> 
00529     // is used.  If this is turn empty, then native units are used.
00530     virtual String format(String& unit,
00531                           Coordinate::formatType format,
00532                           Double worldValue,  
00533                           uInt worldAxis,
00534                           Bool isAbsolute=True,
00535                           Bool showAsAbsolute=True,
00536                           Int precision=-1, Bool usePrecForFixed=False) const;
00537 
00538     // Set the default formatter unit (which is initialized to empty).  Must 
00539     // be consistent with Hz or km/s.  
00540     // If the given unit is illegal, False is returned and the internal state unchanged.
00541     // This unit is used by the function <src>format</src> when the given
00542     // unit is empty.  
00543     // <group>
00544     String formatUnit () const {return formatUnit_p;}
00545     Bool setFormatUnit (const String& unit);
00546     // </group>
00547 
00548     // Convert to FITS header record.  When writing the FITS record,
00549     // the fields "ctype, crval, crpix", and "cdelt" must already be created. Other header
00550     // words are created as needed.  Use <src>oneRelative=True</src> to
00551     // convert zero-relative SpectralCoordinate pixel coordinates to 
00552     // one-relative FITS coordinates, and vice-versa.  If <src>preferVelocity=True</src>
00553     // the primary axis type will be velocity, if <src>preferWavelength=True</src> it will
00554     // be wavelength, else frequency. For a velocity axis, if <src>opticalVelDef=False</src>,
00555     // the radio velocity definition will be used, else optical definition. Similarly for a
00556     // wavelength axis, if <src>airWaveDef=True</src> air wavelength will be used, the
00557     // default is vacuum wavelength.
00558     //<group>
00559     void toFITS(RecordInterface &header, uInt whichAxis, 
00560                 LogIO &logger, Bool oneRelative=True,
00561                 Bool preferVelocity=True, Bool opticalVelDef=True,
00562                 Bool preferWavelength=False, Bool airWaveDef=False) const;
00563 
00564 // Old interface.  Handled by wcs in new interface in FITSCoordinateUtil.cc
00565 //    static Bool fromFITSOld(SpectralCoordinate &out, String &error,
00566 //                       const RecordInterface &header, 
00567 //                       uInt whichAxis,
00568 //                       LogIO &logger, Bool oneRelative=True);
00569     //</group>
00570 
00571     // Save the SpectralCoordinate into the supplied record using the supplied field name.
00572     // The field must not exist, otherwise <src>False</src> is returned.
00573     virtual Bool save(RecordInterface &container,
00574                     const String &fieldName) const;
00575 
00576     // Recover the SpectralCoordinate from a record.
00577     // A null pointer means that the restoration did not succeed.
00578     static SpectralCoordinate* restore(const RecordInterface &container,
00579                                        const String &fieldName);
00580 
00581     // Convert from String to spectral type and vice versa.
00582     static Bool specTypetoString(String &stypeString, const SpecType &specType);
00583     static Bool stringtoSpecType(SpecType &specType, const String &stypeString);
00584 
00585     // Make a copy of the SpectralCoordinate using new. The caller is responsible for calling
00586     // delete.
00587     virtual Coordinate* clone() const;
00588 
00589     ostream& print(ostream& os) const;
00590 
00591     // is this a tabular coordinate?
00592     Bool isTabular() const;
00593 
00594 private:
00595 
00596     SPtrHolder<TabularCoordinate> _tabular;            // Tabular coordinate OR
00597     mutable ::wcsprm wcs_p;                            // wcs structure is used 
00598     Double to_hz_p;                                    // Convert from current world units to Hz
00599     Double to_m_p;                                     // Convert from current wavelength units to m
00600 //
00601     MFrequency::Types type_p, conversionType_p;        // Frequency system and conversion system
00602     Vector<Double> restfreqs_p;                        // List of possible rest frequencies
00603     uInt restfreqIdx_p;                                // Current active rest frequency index
00604 
00605                                                                // Conversion machines; for pixel<->world conversions only.
00606     mutable MFrequency::Convert* pConversionMachineTo_p;       // For type_p -> conversionType_p
00607     mutable MFrequency::Convert* pConversionMachineFrom_p;     // For conversionType_p -> type_p
00608 
00609     VelocityMachine* pVelocityMachine_p;           // The velocity machine does all conversions between world & velocity.
00610     MDoppler::Types velType_p;                     // Velocity Doppler
00611     String velUnit_p;                              // Velocity unit
00612 //
00613     String waveUnit_p;                             // Wavelength unit for conversions between world & wavelength
00614     SpectralCoordinate::SpecType nativeType_p;     // The native spectral type
00615 //
00616     Unit unit_p;                                   // World axis unit
00617     String axisName_p;                             // The axis name
00618     String formatUnit_p;                           // The default unit for the format function
00619 // 
00620     MDirection direction_p;                // These are a part of the frame set for
00621     MPosition position_p;                  // the reference conversions machines
00622     MEpoch epoch_p;                        // They are only private so we can save their state
00623 
00624 // Format checker
00625     void checkFormat(Coordinate::formatType& format,
00626                      const Bool ) const;
00627 
00628 // Copy private data
00629    void copy (const SpectralCoordinate& other);
00630 
00631 // Convert to and from conversion reference type
00632     virtual void convertTo (Vector<Double>& world) const;
00633     virtual void convertFrom (Vector<Double>& world) const;
00634 
00635 // Deletes and sets pointer to 0
00636     void deleteVelocityMachine ();
00637 
00638 // Deletes and sets pointers to 0
00639     void deleteConversionMachines ();
00640 
00641 // Set up pixel<->world conversion machines
00642 // Returns: 3 (machines were noOPs, machines deleted)
00643 //          2 (types the same, machines deleted), 
00644 //          1 (machines created and functioning)
00645 //         -1 (machines could not make trial conversion, machines deleted)
00646     Int makeConversionMachines (MFrequency::Types type,  MFrequency::Types conversionType,
00647                                  const MEpoch& epoch, 
00648                                  const MPosition& position, 
00649                                  const MDirection& direction);
00650 
00651 // Create velocity<->frequency machine 
00652     void makeVelocityMachine (const String& velUnit,                  
00653                               MDoppler::Types velType,
00654                               const Unit& freqUnit,
00655                               MFrequency::Types freqType,
00656                               Double restFreq);
00657 
00658 // Make spectral wcs structure (items in Hz)
00659    static void makeWCS(wcsprm& wcs, const String& ctype, Double refPix, Double refVal, 
00660                        Double inc, Double pc, Double restFreq);
00661 
00662 // Record restoration handling
00663 // <group>
00664    static SpectralCoordinate* restoreVersion1 (const RecordInterface& container);
00665    static SpectralCoordinate* restoreVersion2 (const RecordInterface& container);
00666    static void restoreVelocity (SpectralCoordinate*& pSpectral,
00667                                 const RecordInterface& subrec);
00668    static void restoreRestFrequencies (SpectralCoordinate*& pSpectral,
00669                                        const RecordInterface& subrec,
00670                                        Double restFreq);
00671    static void restoreConversion (SpectralCoordinate*& pSpectral,
00672                                   const RecordInterface& subrec);
00673 
00674 // </group>
00675 
00676 // Interconvert between the current units and wcs units (Hz)
00677 // <group>
00678     void toCurrent(Vector<Double>& value) const;
00679     void fromCurrent(Vector<Double>& value) const;
00680 // </group>
00681 
00682 // Return unit conversion vector for converting to current units
00683    const Vector<Double> toCurrentFactors () const;
00684 
00685 // Update Velocity Machine
00686    void updateVelocityMachine (const String& velUnit, 
00687                                MDoppler::Types velType);
00688 // Restore wcs stuff from Record
00689    static Bool wcsRestore (Double& crval, Double& crpix, Double& cdelt,
00690                            Double& pc, String& ctype,
00691                            const RecordInterface& rec);
00692 
00693 // Save wcs stuff into Record
00694    Bool wcsSave (RecordInterface& rec, const wcsprm& wcs,
00695                  const String& fieldName) const;
00696 
00697    void _setTabulatedFrequencies(const Vector<Double>& freqs);
00698 
00699 };
00700 
00701 ostream &operator<<(ostream &os, const SpectralCoordinate& spcoord);
00702 
00703 } //# NAMESPACE CASACORE - END
00704 
00705 
00706 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1