casacore
SpectralCoordinate.h
Go to the documentation of this file.
1 //# SpectralCoordinate.h: Interconvert between pixel and frequency.
2 //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2004
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //#
27 //# $Id$
28 
29 
30 #ifndef COORDINATES_SPECTRALCOORDINATE_H
31 #define COORDINATES_SPECTRALCOORDINATE_H
32 
33 #include <casacore/casa/aips.h>
34 #include <casacore/casa/Arrays/Vector.h>
35 #include <casacore/coordinates/Coordinates/Coordinate.h>
36 #include <casacore/coordinates/Coordinates/ObsInfo.h>
37 #include <casacore/measures/Measures/MFrequency.h>
38 #include <casacore/measures/Measures/MDoppler.h>
39 #include <casacore/measures/Measures/MDirection.h>
40 #include <casacore/measures/Measures/MPosition.h>
41 #include <casacore/measures/Measures/MEpoch.h>
42 #include <casacore/casa/Quanta/Quantum.h>
43 #include <casacore/casa/Utilities/PtrHolder.h>
44 
45 #include <wcslib/wcs.h>
46 
47 
48 namespace casacore { //# NAMESPACE CASACORE - BEGIN
49 
50 
51 class TabularCoordinate;
52 class LogIO;
53 class MVFrequency;
54 class VelocityMachine;
55 template<class T> class Quantum;
56 
57 
58 // <summary>
59 // Interconvert pixel and frequency values.
60 // </summary>
61 
62 // <use visibility=export>
63 
64 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tSpectralCoordinate">
65 // </reviewed>
66 //
67 // <prerequisite>
68 // <li> <linkto class=Coordinate>Coordinate</linkto>
69 // <li> <linkto class=MFrequency>MFrequency</linkto>,
70 // <linkto class=MDoppler>MDoppler</linkto> and
71 // <linkto class=VelocityMachine>VelocityMachine</linkto>
72 // classes if you want radial velocities.
73 // </prerequisite>
74 //
75 // <synopsis>
76 // This class performs the mapping from pixel to frequency.
77 // This can be done via a Tabular lookup or via an algorithmic
78 // implementation which may be linear or non-linear. The latter
79 // is implemented via the WCS library.
80 //
81 // </synopsis>
82 //
83 
84 // <note role=caution>
85 // All pixels coordinates are zero relative.
86 // </note>
87 //
88 // <example>
89 // Let us make a linear SpectralCoordinate first
90 // <srcblock>
91 // Double restfreq = 1.420405752E9;
92 // Double crpix = 10.0;
93 // Double crval = 1.4e9;
94 // Double cdelt = 1.0e6;
95 // SpectralCoordinate sc(MFrequency::TOPO, crval, cdelt, crpix, restfreq);
96 //
97 // Double world, pixel;
98 // pixel = 12.1;
99 // if (!sc.toWorld(world, pixel)) {
100 // cerr << "Error : " << sc.errorMessage() << endl;
101 // } else {
102 // cerr << "pixel, world = " << pixel << ", " << world << endl;
103 // }
104 //
105 // </srcblock>
106 // </example>
107 //
108 // <example>
109 // Now we make a non-linear SpectralCoordinate
110 // <srcblock>
111 // Vector<Double> freqs(5);
112 // freqs(0) = 1.4e9; freqs(1) = 1.41e9;
113 // freqs(2) = 1.43e9; freqs(3) = 1.44e9;
114 // freqs(4) = 1.47e9;
115 // SpectralCoordinate sc(MFrequency::LSRK, freqs, restfreq);
116 //
117 // Double world, pixel;
118 // world = 1.42e9;
119 // if (!sc.toPixel(pixel, world)) {
120 // cerr << "Error : " << sc.errorMessage() << endl;
121 // } else {
122 // cerr << "world, pixel = " << world << ", " << pixel << endl;
123 // }
124 //
125 // </srcblock>
126 // </example>
127 //
128 // <motivation>
129 // Spectral-line astronomy requires a specialized SpectralCoordinate.
130 // </motivation>
131 
132 // <todo asof="2000/01/01">
133 // <li> Allow other than linear interpolations for frequency lookup.
134 // </todo>
135 //
136 
138 {
139 public:
140  enum SpecType { // taken from the FITS spectral coordinate type codes
146  AWAV
147  };
148 
149  // Default constructor. It is equivalent to doing
150  // SpectralCoordinate(MFrequency::TOPO, 0.0, 1.0, 0.0)
152 
153  // Create a linear frequency axis SpectralCoordinate
154  // <src>f0</src> is the frequency of the reference pixel, <src>inc</src> is the pixel increment,
155  // <src>refPix</src> is the reference pixel. You can
156  // optionally store the rest frequency for later use in calculating radial
157  // velocities. Use 0 for restFrequency if continuum.
158  //
159  // Frequencies and increments initially in Hz.
161  Double refPix, Double restFrequency = 0.0);
162 
163  // Create linear frequency axis SpectralCoordinate with Quantum-based interface.
164  // Parameters are the same as above.
165  // Regardless of the units of the Quanta, the initial units
166  // of the SpectralCoordinate will be Hz. You can change it to
167  // something else with the setWorldAxisUnits method later if you want.
168  // Use 0 for restFrequency if continuum.
170  const Quantum<Double>& inc, Double refPix,
171  const Quantum<Double>& restFrequency = Quantum<Double>(0.0,"Hz"));
172 
173  // Construct a SpectralCoordinate with the specified frequencies (in Hz).
174  // This axis can be nonlinear; the increments and related
175  // functions return the <src>average</src> values
176  // (calculated from the first and last pixel's frequencies).
177  //
178  // A linear interpolation/extrapolation is used for pixels which are
179  // not supplied. The reference pixel is chosen to be 0.
180  // The frequencies must increase or decrease monotonically (otherwise
181  // the toPixel lookup would not be possible).
182  // Use 0 for restFrequency if continuum.
184  Double restFrequency = 0.0);
185 
186  // Construct a SpectralCoordinate with the specified frequencies
187  // with Quantum-based interface.
188  // Parameters are the same as above.
189  // Regardless of the units of the Quanta, the initial units
190  // of the SpectralCoordinate will be Hz.
191  // Use 0 for restFrequency if continuum.
193  const Quantum<Double>& restFrequency = Quantum<Double>(0.0,"Hz"));
194 
195  // Construct a SpectralCoordinate with the specified velocities (in km/s).
196  // They will be converted to Hz and the SpectralCoordinate constructed.
197  // This axis can be nonlinear; the increments and related
198  // functions return the <src>average</src> values
199  // (calculated from the first and last pixel's frequencies).
200  //
201  // A linear interpolation/extrapolation is used for pixels which are
202  // not supplied. The reference pixel is chosen to be 0.
203  // The velocities must increase or decrease monotonically (otherwise
204  // the toPixel lookup would not be possible).
206  const Vector<Double>& velocities, const String& velUnit,
207  Double restFrequency = 0.0);
208 
209  // Construct a SpectralCoordinate with the specified wavelengths (in mm).
210  // They will be converted to Hz and the SpectralCoordinate constructed.
211  // This axis can be nonlinear; the increments and related
212  // functions return the <src>average</src> values
213  // (calculated from the first and last pixel's frequencies).
214  // If inAir is True, the input wavelengths are assumed to be Air Wavelengths.
215  // They are converted to vacuum frequency using the refractive index
216  // which is calculated based on the mean input air wavelength.
217  //
218  // A linear interpolation/extrapolation is used for pixels which are
219  // not supplied. The reference pixel is chosen to be 0.
220  // The wavelengths must increase or decrease monotonically (otherwise
221  // the toPixel lookup would not be possible).
223  const Vector<Double>& wavelengths, const String& waveUnit,
224  Double restFrequency = 0.0, Bool inAir = False);
225 
226  // Construct from wcs structure. Must hold only a spectral wcs structure
227  // Specify whether the absolute pixel coordinates in the wcs structure
228  // are 0- or 1-relative. The coordinate is always constructed with 0-relative
229  // pixel coordinates
230  SpectralCoordinate(MFrequency::Types freqType, const ::wcsprm& wcs, Bool oneRel=True);
231 
232  // Copy constructor (copy semantics).
234 
235  // Assignment (copy semantics).
237 
238  // Destructor.
240 
241  // Always returns Coordinate::SPECTRAL.
242  virtual Coordinate::Type type() const;
243 
244  // Always returns the String "Spectral".
245  virtual String showType() const;
246 
247  // Always returns 1.
248  // <group>
249  virtual uInt nPixelAxes() const;
250  virtual uInt nWorldAxes() const;
251  // </group>
252 
253  // Set extra conversion layer. Whenever a conversion from pixel to world is done,
254  // the world value is then further converted to this MFrequency::Types value.
255  // For example, your SpectralCoordinate may be defined in LSRK.
256  // You can use this to get the world values out in say BARY. You must
257  // specify the position on earth, the epoch and the direction for the conversions
258  // and it is your responsibility to ensure they are viable.
259  // Similarly, whenever you convert from world to pixel, the world
260  // value is assumed to be that appropriate to the setReferenceConversion type.
261  // It is first converted to the MFrequency::Types with which the
262  // SpectralCoordinate was constructed and from there to pixel.
263  // If you don't call this function, or you set the same type
264  // for which the SpectralCoordinate was constructed, no extra
265  // conversions occur. Some conversions will fail. These are the
266  // ones that require extra frame information (radial velocity) such
267  // as to REST. This will be added later. In this case this function
268  // returns False (and the conversion parameters are all left as they were),
269  // else it returns True.
270  // <group>
272  const MEpoch& epoch, const MPosition& position,
273  const MDirection& direction);
275  MEpoch& epoch, MPosition& position,
276  MDirection& direction) const
277  {type = conversionType_p; epoch=epoch_p;
278  position=position_p; direction=direction_p;};
279  // </group>
280 
281  // Convert a pixel to a world coordinate or vice versa. Returns True
282  // if the conversion succeeds, otherwise it returns False and
283  // <src>errorMessage()</src> contains an error message. The input vectors
284  // must be of length one and the output vectors are resized if they are not
285  // already of length one.
286  // if <src>useConversionFrame</src>, if the coordinate has a conversion
287  // layer frame, it is used. Else, the native frame is used for the conversion.
288  // <group>
289  virtual Bool toWorld(Vector<Double> &world,
290  const Vector<Double> &pixel, Bool useConversionFrame=True) const;
291  virtual Bool toPixel(Vector<Double> &pixel,
292  const Vector<Double> &world) const;
293  Bool toWorld(Double& world, const Double& pixel) const;
294  Bool toPixel(Double& pixel, const Double& world) const;
295  // </group>
296 
297  // Convert a pixel (channel number) into an MFrequency or MVFrequency and vice
298  // versa. Usually you will do
299  // this for calculating velocities or converting frequencies from one frame
300  // to another.
301  // <group>
303  Double pixel) const;
304  Bool toPixel(Double& pixel, const MFrequency &world) const;
306  Double pixel) const;
307  Bool toPixel(Double& pixel, const MVFrequency &world) const;
308  // </group>
309 
310  // Batch up a lot of transformations. The first (most rapidly varying) axis
311  // of the matrices contain the coordinates. Returns False if any conversion
312  // failed and <src>errorMessage()</src> will hold a message.
313  // The <src>failures</src> array (True for fail, False for success)
314  // is the length of the number of conversions and
315  // holds an error status for each conversion.
316  // <group>
318  const Matrix<Double>& pixel,
319  Vector<Bool>& failures) const;
321  const Matrix<Double>& world,
322  Vector<Bool>& failures) const;
323  // </group>
324 
325  // Set the state that is used for conversions from pixel and frequency to velocity
326  // or wavelength. The SpectralCoordinate is constructed with
327  // <src>MDoppler::RADIO</src> and <src>km/s</src> as the velocity conversion state
328  // and <src>mm</src> as the wavelength conversion state.
329  // The functions in this class which use this state are those that convert
330  // to or from velocity. Also, function <src>format</src> uses the Doppler
331  // state set here. If the function returns False it means the unit was
332  // not valid. There will be an error message in function <src>errorMessage</src>
333  // <group>
334  Bool setVelocity (const String& velUnit=String("km/s"),
336 
338  String velocityUnit () const {return velUnit_p;};
339  //
340  Bool setWavelengthUnit (const String& waveUnit=String("mm"));
341  String wavelengthUnit () const {return waveUnit_p;};
342  //
345 
346  // </group>
347  // Functions to convert to velocity (uses the current active
348  // rest frequency) or wavelength. There is no reference frame
349  // change but you can specify the velocity Doppler and the output
350  // units of the velocity with function <src>setVelocity</src>
351  // or <src>setWavelength</src> respectively. When the input is a frequency stored
352  // as a Double it must be in the current units of the SpectralCoordinate.
353  //
354  // Note that the extra conversion layer (see function <src>setReferenceConversion</src>)
355  // is active in the <src>pixelToVelocity</src> functions (because internally
356  // the use <src>toWorld</src>) but not in the <src>frequencyToVelocity</src>
357  // or <src>frequencyToWavelength</src> functions.
358  // <group>
359  Bool pixelToVelocity (Quantum<Double>& velocity, Double pixel) const;
360  Bool pixelToVelocity (Double& velocity, Double pixel) const;
361  Bool pixelToVelocity (Vector<Double>& velocity, const Vector<Double>& pixel) const;
362  //
363  Bool frequencyToVelocity (Quantum<Double>& velocity, Double frequency) const;
364  Bool frequencyToVelocity (Quantum<Double>& velocity, const MFrequency& frequency) const;
365  Bool frequencyToVelocity (Quantum<Double>& velocity, const MVFrequency& frequency) const;
366  Bool frequencyToVelocity (Double& velocity, Double frequency) const;
367  Bool frequencyToVelocity (Vector<Double>& velocity, const Vector<Double>& frequency) const;
368  //
369  Bool frequencyToWavelength (Vector<Double>& wavelength, const Vector<Double>& frequency) const;
370  Bool frequencyToAirWavelength (Vector<Double>& wavelength, const Vector<Double>& frequency) const;
371  // The refractive index of air (argument can be wavelength or airwavelength)
372  // according to Greisen et al., 2006, A&A, 464, 746.
373  // If airwavelength is used there is an error of the order of 1E-9.
374  // Argument must be in micrometers!
375  //static Double refractiveIndex(const Double& lambda_um);
376  // </group>
377 
378  // Functions to convert from velocity (uses the current active
379  // rest frequency) or wavelength. There is no reference frame
380  // change but you can specify the velocity Doppler and the output
381  // units of the velocity with function <src>setVelocity</src>
382  // and those of the wavelength with <src>setWavelength</src>.
383  // When the input is a frequency stored
384  // as a Double it must be in the current units of the SpectralCoordinate.
385  //
386  // Note that the extra conversion layer (see function <src>setReferenceConversion</src>)
387  // is active in the <src>pixelToVelocity</src> functions (because internally
388  // the use <src>toPixel</src>) but not in the <src>frequencyToVelocity</src> functions.
389  // <group>
390  Bool velocityToPixel (Double& pixel, Double velocity) const;
391  Bool velocityToPixel (Vector<Double>& pixel, const Vector<Double>& velocity) const;
392  //
393  Bool velocityToFrequency (Double& frequency, Double velocity) const;
394  Bool velocityToFrequency (Vector<Double>& frequency, const Vector<Double>& velocity) const;
395  //
396  Bool wavelengthToFrequency (Vector<Double>& frequency, const Vector<Double>& wavelength) const;
397  Bool airWavelengthToFrequency (Vector<Double>& frequency, const Vector<Double>& wavelength) const;
398  // </group>
399 
400  // The SpectralCoordinate can maintain a list of rest frequencies
401  // (e.g. multiple lines within a band). However, only
402  // one of them is active (e.g. for velocity conversions) at any
403  // one time. Function <src>restFrequency</src> returns that
404  // frequency. Function <src>restFrequencies</src> returns
405  // all of the possible restfrequencies.
406  //
407  // When you construct the SpectralCoordinate, you give it one rest frequency
408  // and it is the active one. Thereafter you can add a new restfrequency
409  // with function <src>setRestFrequency</src> (<src>append=True</src>) and
410  // that frequency will become the active one. With this function
411  // and <src>append=False</src>, the current active restfrequency will
412  // be replaced by the one you give.
413  //
414  // You can change the list of
415  // restfrequencies with function <src>setRestFrequencies</src>. When
416  // you do so, you can either replace the list of rest frequencies or append to it.
417  // You specify which frequency of the new (appended) list
418  // becomes active.
419  //
420  // You can also select the active rest frequency either by an index into
421  // the current list (exception if out of range) given by
422  // <src>restFrequencies()</src> or by the value in the list
423  // nearest to the frequency you give.
424  //
425  // Whenever you change the active rest frequency, the class internals
426  // are adjusted (e.g. the velocity machine is updated).
427  // <group>
430  Bool setRestFrequency(Double newFrequency, Bool append=False);
431  void setRestFrequencies(const Vector<Double>& newFrequencies, uInt which=0,
432  Bool append=False);
434  void selectRestFrequency(Double frequency);
436  // </group>
437 
438  // Retrieve/set the frequency system. Note that setting the
439  // frequency system just changes the internal value of the
440  // frequency system. In addition, it will reset the internal
441  // conversion frequency system to the new type and delete any
442  // conversion machines.
443  // <group>
446 
447  // Transform the SpectralCoordinate to a different native reference frame
448  // keeping the conversion layer as is
450  const MEpoch& epoch,
451  const MPosition& position,
452  const MDirection& direction);
453  // </group>
454 
455  // Report the value of the requested attribute.
456  // <group>
460  virtual Vector<Double> increment() const;
462  // </group>
463 
464  // Set the value of the requested attribute. Note that these just
465  // change the internal values, they do not cause any recomputation.
466  // <group>
467  virtual Bool setWorldAxisNames(const Vector<String> &names);
468  virtual Bool setReferencePixel(const Vector<Double> &refPix);
469  virtual Bool setLinearTransform(const Matrix<Double> &xform);
470  virtual Bool setIncrement(const Vector<Double> &inc) ;
471  virtual Bool setReferenceValue(const Vector<Double> &refval);
472  // </group>
473 
474  // Get the table, i.e. the pixel and world values. The length of these
475  // Vectors will be zero if this axis is pure linear (i.e. if the
476  // channel and frequencies are related through an increment and offset).
477  // <group>
480  // </group>
481 
482  // Set/get the unit. Adjust the increment and
483  // reference value by the ratio of the old and new units.
484  // The unit must be compatible with frequency.
485  //<group>
486  virtual Bool setWorldAxisUnits(const Vector<String> &units);
488  //</group>
489 
490  // Comparison function. Any private Double data members are compared
491  // with the specified fractional tolerance. Don't compare on the specified
492  // axes in the Coordinate. If the comparison returns False,
493  // <src>errorMessage()</src> contains a message about why.
494  // <group>
495  virtual Bool near(const Coordinate& other,
496  Double tol=1e-6) const;
497  virtual Bool near(const Coordinate& other,
498  const Vector<Int>& excludeAxes,
499  Double tol=1e-6) const;
500  // </group>
501 
502 
503  // Find the Coordinate for when we Fourier Transform ourselves. This pointer
504  // must be deleted by the caller. Axes specifies which axes of the Coordinate
505  // you wish to transform. Shape specifies the shape of the image
506  // associated with all the axes of the Coordinate. Currently the
507  // output reference pixel is always shape/2. Cannot transform tabular
508  // coordinates. If the pointer returned is 0, it failed with a message
509  // in <src>errorMessage</src>
511  const Vector<Int>& shape) const;
512 
513 
514  // Format a SpectralCoordinate coordinate world value nicely through the
515  // common format interface. See <linkto class=Coordinate>Coordinate</linkto>
516  // for basics.
517  //
518  // Format types SCIENTIFIC, FIXED, MIXED and DEFAULT are supported.
519  // DEFAULT will use MIXED.
520  //
521  // The world value must always be given in native frequency units.
522  // Use argument <src>unit</src> to determine what it will be
523  // converted to for formatting. If <src>unit</src> is given, it
524  // must be dimensionally consistent with Hz, m, or m/s.
525  // If you give a unit consistent with m/s then the
526  // appropriate velocity Doppler type is taken from that set by
527  // function <src>setVelocity</src>. There is no frame conversion.
528  // If <src>unit</src> is empty, the unit given by <src>setFormatUnit</src>
529  // is used. If this is turn empty, then native units are used.
530  virtual String format(String& unit,
532  Double worldValue,
533  uInt worldAxis,
534  Bool isAbsolute=True,
535  Bool showAsAbsolute=True,
536  Int precision=-1, Bool usePrecForFixed=False) const;
537 
538  // Set the default formatter unit (which is initialized to empty). Must
539  // be consistent with Hz or km/s.
540  // If the given unit is illegal, False is returned and the internal state unchanged.
541  // This unit is used by the function <src>format</src> when the given
542  // unit is empty.
543  // <group>
544  String formatUnit () const {return formatUnit_p;}
545  Bool setFormatUnit (const String& unit);
546  // </group>
547 
548  // Convert to FITS header record. When writing the FITS record,
549  // the fields "ctype, crval, crpix", and "cdelt" must already be created. Other header
550  // words are created as needed. Use <src>oneRelative=True</src> to
551  // convert zero-relative SpectralCoordinate pixel coordinates to
552  // one-relative FITS coordinates, and vice-versa. If <src>preferVelocity=True</src>
553  // the primary axis type will be velocity, if <src>preferWavelength=True</src> it will
554  // be wavelength, else frequency. For a velocity axis, if <src>opticalVelDef=False</src>,
555  // the radio velocity definition will be used, else optical definition. Similarly for a
556  // wavelength axis, if <src>airWaveDef=True</src> air wavelength will be used, the
557  // default is vacuum wavelength.
558  //<group>
559  void toFITS(RecordInterface &header, uInt whichAxis,
560  LogIO &logger, Bool oneRelative=True,
561  Bool preferVelocity=True, Bool opticalVelDef=True,
562  Bool preferWavelength=False, Bool airWaveDef=False) const;
563 
564 // Old interface. Handled by wcs in new interface in FITSCoordinateUtil.cc
565 // static Bool fromFITSOld(SpectralCoordinate &out, String &error,
566 // const RecordInterface &header,
567 // uInt whichAxis,
568 // LogIO &logger, Bool oneRelative=True);
569  //</group>
570 
571  // Save the SpectralCoordinate into the supplied record using the supplied field name.
572  // The field must not exist, otherwise <src>False</src> is returned.
573  virtual Bool save(RecordInterface &container,
574  const String &fieldName) const;
575 
576  // Recover the SpectralCoordinate from a record.
577  // A null pointer means that the restoration did not succeed.
578  static SpectralCoordinate* restore(const RecordInterface &container,
579  const String &fieldName);
580 
581  // Convert from String to spectral type and vice versa.
582  static Bool specTypetoString(String &stypeString, const SpecType &specType);
583  static Bool stringtoSpecType(SpecType &specType, const String &stypeString);
584 
585  // Make a copy of the SpectralCoordinate using new. The caller is responsible for calling
586  // delete.
587  virtual Coordinate* clone() const;
588 
589  ostream& print(ostream& os) const;
590 
591  // is this a tabular coordinate?
592  Bool isTabular() const;
593 
594 private:
595 
596  SPtrHolder<TabularCoordinate> _tabular; // Tabular coordinate OR
597  mutable ::wcsprm wcs_p; // wcs structure is used
598  Double to_hz_p; // Convert from current world units to Hz
599  Double to_m_p; // Convert from current wavelength units to m
600 //
601  MFrequency::Types type_p, conversionType_p; // Frequency system and conversion system
602  Vector<Double> restfreqs_p; // List of possible rest frequencies
603  uInt restfreqIdx_p; // Current active rest frequency index
604 
605  // Conversion machines; for pixel<->world conversions only.
606  mutable MFrequency::Convert* pConversionMachineTo_p; // For type_p -> conversionType_p
607  mutable MFrequency::Convert* pConversionMachineFrom_p; // For conversionType_p -> type_p
608 
609  VelocityMachine* pVelocityMachine_p; // The velocity machine does all conversions between world & velocity.
610  MDoppler::Types velType_p; // Velocity Doppler
611  String velUnit_p; // Velocity unit
612 //
613  String waveUnit_p; // Wavelength unit for conversions between world & wavelength
614  SpectralCoordinate::SpecType nativeType_p; // The native spectral type
615 //
616  Unit unit_p; // World axis unit
617  String axisName_p; // The axis name
618  String formatUnit_p; // The default unit for the format function
619 //
620  MDirection direction_p; // These are a part of the frame set for
621  MPosition position_p; // the reference conversions machines
622  MEpoch epoch_p; // They are only private so we can save their state
623 
624 // Format checker
626  const Bool ) const;
627 
628 // Copy private data
629  void copy (const SpectralCoordinate& other);
630 
631 // Convert to and from conversion reference type
632  virtual void convertTo (Vector<Double>& world) const;
633  virtual void convertFrom (Vector<Double>& world) const;
634 
635 // Deletes and sets pointer to 0
637 
638 // Deletes and sets pointers to 0
640 
641 // Set up pixel<->world conversion machines
642 // Returns: 3 (machines were noOPs, machines deleted)
643 // 2 (types the same, machines deleted),
644 // 1 (machines created and functioning)
645 // -1 (machines could not make trial conversion, machines deleted)
647  const MEpoch& epoch,
648  const MPosition& position,
649  const MDirection& direction);
650 
651 // Create velocity<->frequency machine
652  void makeVelocityMachine (const String& velUnit,
653  MDoppler::Types velType,
654  const Unit& freqUnit,
655  MFrequency::Types freqType,
656  Double restFreq);
657 
658 // Make spectral wcs structure (items in Hz)
659  static void makeWCS(wcsprm& wcs, const String& ctype, Double refPix, Double refVal,
660  Double inc, Double pc, Double restFreq);
661 
662 // Record restoration handling
663 // <group>
666  static void restoreVelocity (SpectralCoordinate*& pSpectral,
667  const RecordInterface& subrec);
668  static void restoreRestFrequencies (SpectralCoordinate*& pSpectral,
669  const RecordInterface& subrec,
670  Double restFreq);
671  static void restoreConversion (SpectralCoordinate*& pSpectral,
672  const RecordInterface& subrec);
673 
674 // </group>
675 
676 // Interconvert between the current units and wcs units (Hz)
677 // <group>
680 // </group>
681 
682 // Return unit conversion vector for converting to current units
684 
685 // Update Velocity Machine
686  void updateVelocityMachine (const String& velUnit,
687  MDoppler::Types velType);
688 // Restore wcs stuff from Record
689  static Bool wcsRestore (Double& crval, Double& crpix, Double& cdelt,
690  Double& pc, String& ctype,
691  const RecordInterface& rec);
692 
693 // Save wcs stuff into Record
694  Bool wcsSave (RecordInterface& rec, const wcsprm& wcs,
695  const String& fieldName) const;
696 
698 
699 };
700 
701 ostream &operator<<(ostream &os, const SpectralCoordinate& spcoord);
702 
703 } //# NAMESPACE CASACORE - END
704 
705 
706 #endif
Hold and delete pointers not deleted by object destructors.
Definition: PtrHolder.h:198
Type
This enum lists the types of the derived classes.
Definition: Coordinate.h:144
formatType
This enum is used for formatting world values into Strings.
Definition: Coordinate.h:162
Types
Types of known MDopplers Warning: The order defines the order in the translation matrix FromTo in th...
Definition: MDoppler.h:149
Types
Types of known MFrequencies Warning: The order defines the order in the translation matrix FromTo in...
Definition: MFrequency.h:176
static void makeWCS(wcsprm &wcs, const String &ctype, Double refPix, Double refVal, Double inc, Double pc, Double restFreq)
Make spectral wcs structure (items in Hz)
const Vector< Double > toCurrentFactors() const
Return unit conversion vector for converting to current units.
Bool velocityToFrequency(Vector< Double > &frequency, const Vector< Double > &velocity) const
Bool frequencyToAirWavelength(Vector< Double > &wavelength, const Vector< Double > &frequency) const
Vector< Double > pixelValues() const
Get the table, i.e.
SpectralCoordinate(MFrequency::Types freqType, const Vector< Double > &wavelengths, const String &waveUnit, Double restFrequency=0.0, Bool inAir=False)
Construct a SpectralCoordinate with the specified wavelengths (in mm).
static SpectralCoordinate * restoreVersion2(const RecordInterface &container)
virtual void convertTo(Vector< Double > &world) const
Convert to and from conversion reference type.
virtual Coordinate * clone() const
Make a copy of the SpectralCoordinate using new.
SpectralCoordinate(MFrequency::Types type, const Vector< Double > &freqs, Double restFrequency=0.0)
Construct a SpectralCoordinate with the specified frequencies (in Hz).
Bool wcsSave(RecordInterface &rec, const wcsprm &wcs, const String &fieldName) const
Save wcs stuff into Record.
virtual void convertFrom(Vector< Double > &world) const
Bool velocityToPixel(Vector< Double > &pixel, const Vector< Double > &velocity) const
SpectralCoordinate(const SpectralCoordinate &other)
Copy constructor (copy semantics).
SpectralCoordinate(MFrequency::Types type, const Quantum< Double > &f0, const Quantum< Double > &inc, Double refPix, const Quantum< Double > &restFrequency=Quantum< Double >(0.0,"Hz"))
Create linear frequency axis SpectralCoordinate with Quantum-based interface.
Bool transformFrequencySystem(MFrequency::Types type, const MEpoch &epoch, const MPosition &position, const MDirection &direction)
Transform the SpectralCoordinate to a different native reference frame keeping the conversion layer a...
virtual Bool setWorldAxisNames(const Vector< String > &names)
Set the value of the requested attribute.
Bool toWorld(MFrequency &world, Double pixel) const
Convert a pixel (channel number) into an MFrequency or MVFrequency and vice versa.
Bool pixelToVelocity(Quantum< Double > &velocity, Double pixel) const
Functions to convert to velocity (uses the current active rest frequency) or wavelength.
virtual Bool toWorldMany(Matrix< Double > &world, const Matrix< Double > &pixel, Vector< Bool > &failures) const
Batch up a lot of transformations.
virtual Coordinate::Type type() const
Always returns Coordinate::SPECTRAL.
ostream & print(ostream &os) const
virtual Vector< String > worldAxisUnits() const
Bool frequencyToVelocity(Quantum< Double > &velocity, Double frequency) const
static void restoreVelocity(SpectralCoordinate *&pSpectral, const RecordInterface &subrec)
static void restoreRestFrequencies(SpectralCoordinate *&pSpectral, const RecordInterface &subrec, Double restFreq)
Bool frequencyToVelocity(Double &velocity, Double frequency) const
Bool pixelToVelocity(Vector< Double > &velocity, const Vector< Double > &pixel) const
String formatUnit() const
Set the default formatter unit (which is initialized to empty).
MFrequency::Convert * pConversionMachineTo_p
Conversion machines; for pixel<->world conversions only.
static SpectralCoordinate * restore(const RecordInterface &container, const String &fieldName)
Recover the SpectralCoordinate from a record.
Bool wavelengthToFrequency(Vector< Double > &frequency, const Vector< Double > &wavelength) const
Bool toPixel(Double &pixel, const Double &world) const
SpectralCoordinate()
Default constructor.
virtual Vector< String > worldAxisNames() const
Report the value of the requested attribute.
Bool toPixel(Double &pixel, const MVFrequency &world) const
Double restFrequency() const
The SpectralCoordinate can maintain a list of rest frequencies (e.g.
void selectRestFrequency(Double frequency)
virtual Bool setReferencePixel(const Vector< Double > &refPix)
virtual Vector< Double > increment() const
SpectralCoordinate(MFrequency::Types type, Double f0, Double inc, Double refPix, Double restFrequency=0.0)
Create a linear frequency axis SpectralCoordinate f0 is the frequency of the reference pixel,...
static Bool stringtoSpecType(SpecType &specType, const String &stypeString)
Bool frequencyToVelocity(Quantum< Double > &velocity, const MVFrequency &frequency) const
virtual Bool toPixelMany(Matrix< Double > &pixel, const Matrix< Double > &world, Vector< Bool > &failures) const
void toCurrent(Vector< Double > &value) const
Interconvert between the current units and wcs units (Hz)
static Bool specTypetoString(String &stypeString, const SpecType &specType)
Convert from String to spectral type and vice versa.
void setRestFrequencies(const Vector< Double > &newFrequencies, uInt which=0, Bool append=False)
SpectralCoordinate(MFrequency::Types freqType, MDoppler::Types velType, const Vector< Double > &velocities, const String &velUnit, Double restFrequency=0.0)
Construct a SpectralCoordinate with the specified velocities (in km/s).
String formatRestFrequencies() const
SpectralCoordinate(MFrequency::Types type, const Quantum< Vector< Double > > &freqs, const Quantum< Double > &restFrequency=Quantum< Double >(0.0,"Hz"))
Construct a SpectralCoordinate with the specified frequencies with Quantum-based interface.
virtual Vector< Double > referenceValue() const
Bool setFormatUnit(const String &unit)
virtual String format(String &unit, Coordinate::formatType format, Double worldValue, uInt worldAxis, Bool isAbsolute=True, Bool showAsAbsolute=True, Int precision=-1, Bool usePrecForFixed=False) const
Format a SpectralCoordinate coordinate world value nicely through the common format interface.
VelocityMachine * pVelocityMachine_p
void _setTabulatedFrequencies(const Vector< Double > &freqs)
Bool setWavelengthUnit(const String &waveUnit=String("mm"))
void makeVelocityMachine(const String &velUnit, MDoppler::Types velType, const Unit &freqUnit, MFrequency::Types freqType, Double restFreq)
Create velocity<->frequency machine
const Vector< Double > & restFrequencies() const
virtual Bool save(RecordInterface &container, const String &fieldName) const
Old interface.
void setFrequencySystem(MFrequency::Types type, Bool verbose=True)
static void restoreConversion(SpectralCoordinate *&pSpectral, const RecordInterface &subrec)
Bool airWavelengthToFrequency(Vector< Double > &frequency, const Vector< Double > &wavelength) const
SPtrHolder< TabularCoordinate > _tabular
Int makeConversionMachines(MFrequency::Types type, MFrequency::Types conversionType, const MEpoch &epoch, const MPosition &position, const MDirection &direction)
Set up pixel<->world conversion machines Returns: 3 (machines were noOPs, machines deleted) 2 (types ...
virtual uInt nWorldAxes() const
virtual String showType() const
Always returns the String "Spectral".
static Bool wcsRestore(Double &crval, Double &crpix, Double &cdelt, Double &pc, String &ctype, const RecordInterface &rec)
Restore wcs stuff from Record.
virtual Bool setReferenceValue(const Vector< Double > &refval)
SpectralCoordinate & operator=(const SpectralCoordinate &other)
Assignment (copy semantics).
SpectralCoordinate::SpecType nativeType() const
Bool frequencyToWavelength(Vector< Double > &wavelength, const Vector< Double > &frequency) const
Bool frequencyToVelocity(Vector< Double > &velocity, const Vector< Double > &frequency) const
Bool velocityToFrequency(Double &frequency, Double velocity) const
void getReferenceConversion(MFrequency::Types &type, MEpoch &epoch, MPosition &position, MDirection &direction) const
virtual Bool toWorld(Vector< Double > &world, const Vector< Double > &pixel, Bool useConversionFrame=True) const
Convert a pixel to a world coordinate or vice versa.
MFrequency::Types frequencySystem(Bool showConversion=False) const
Retrieve/set the frequency system.
virtual Bool setWorldAxisUnits(const Vector< String > &units)
Set/get the unit.
void selectRestFrequency(uInt which)
void deleteConversionMachines()
Deletes and sets pointers to 0.
Vector< Double > worldValues() const
Bool setRestFrequency(Double newFrequency, Bool append=False)
Bool setVelocity(const String &velUnit=String("km/s"), MDoppler::Types velType=MDoppler::RADIO)
Set the state that is used for conversions from pixel and frequency to velocity or wavelength.
Bool pixelToVelocity(Double &velocity, Double pixel) const
virtual Bool near(const Coordinate &other, Double tol=1e-6) const
Comparison function.
virtual Coordinate * makeFourierCoordinate(const Vector< Bool > &axes, const Vector< Int > &shape) const
Find the Coordinate for when we Fourier Transform ourselves.
virtual Bool setIncrement(const Vector< Double > &inc)
Bool isTabular() const
is this a tabular coordinate?
void toFITS(RecordInterface &header, uInt whichAxis, LogIO &logger, Bool oneRelative=True, Bool preferVelocity=True, Bool opticalVelDef=True, Bool preferWavelength=False, Bool airWaveDef=False) const
Convert to FITS header record.
virtual ~SpectralCoordinate()
Destructor.
void checkFormat(Coordinate::formatType &format, const Bool) const
Format checker.
virtual Bool toPixel(Vector< Double > &pixel, const Vector< Double > &world) const
Bool setNativeType(const SpectralCoordinate::SpecType spcType)
Bool toWorld(MVFrequency &world, Double pixel) const
SpectralCoordinate(MFrequency::Types freqType, const ::wcsprm &wcs, Bool oneRel=True)
Construct from wcs structure.
Bool velocityToPixel(Double &pixel, Double velocity) const
The refractive index of air (argument can be wavelength or airwavelength) according to Greisen et al....
void fromCurrent(Vector< Double > &value) const
virtual Bool near(const Coordinate &other, const Vector< Int > &excludeAxes, Double tol=1e-6) const
MDoppler::Types velocityDoppler() const
virtual Matrix< Double > linearTransform() const
Bool setReferenceConversion(MFrequency::Types type, const MEpoch &epoch, const MPosition &position, const MDirection &direction)
Set extra conversion layer.
void updateVelocityMachine(const String &velUnit, MDoppler::Types velType)
Update Velocity Machine.
SpectralCoordinate::SpecType nativeType_p
void deleteVelocityMachine()
Deletes and sets pointer to 0.
Bool toPixel(Double &pixel, const MFrequency &world) const
virtual Vector< Double > referencePixel() const
virtual Bool setLinearTransform(const Matrix< Double > &xform)
Bool toWorld(Double &world, const Double &pixel) const
void copy(const SpectralCoordinate &other)
Copy private data.
virtual uInt nPixelAxes() const
Always returns 1.
Bool frequencyToVelocity(Quantum< Double > &velocity, const MFrequency &frequency) const
MFrequency::Convert * pConversionMachineFrom_p
static SpectralCoordinate * restoreVersion1(const RecordInterface &container)
Record restoration handling.
String: the storage and methods of handling collections of characters.
Definition: String.h:225
const Double e
e and functions thereof:
this file contains all the compiler specific defines
Definition: mainpage.dox:28
const Bool False
Definition: aipstype.h:44
unsigned int uInt
Definition: aipstype.h:51
TableExprNode shape(const TableExprNode &array)
Function operating on any scalar or array resulting in a Double array containing the shape.
Definition: ExprNode.h:1987
int Int
Definition: aipstype.h:50
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
ostream & operator<<(ostream &os, const IComplex &)
Show on ostream.
const Bool True
Definition: aipstype.h:43
double Double
Definition: aipstype.h:55