00001 //# FrequenctAligner.h: Align spectra in frequency space 00002 //# Copyright (C) 1998,1999,2000,2001,2003 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$ 00027 00028 #ifndef COORDINATES_FREQUENCYALIGNER_H 00029 #define COORDINATES_FREQUENCYALIGNER_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/coordinates/Coordinates/SpectralCoordinate.h> 00035 #include <casacore/measures/Measures/MFrequency.h> 00036 #include <casacore/measures/Measures/MeasRef.h> 00037 #include <casacore/measures/Measures/MeasConvert.h> 00038 #include <casacore/scimath/Mathematics/InterpolateArray1D.h> 00039 00040 namespace casacore { 00041 00042 //# Forward Declarations 00043 class MEpoch; 00044 class MDirection; 00045 class MPosition; 00046 class String; 00047 00048 00049 00050 // <summary> 00051 // Aligns spectra in frequency space 00052 // </summary> 00053 // 00054 // <use visibility=export> 00055 // 00056 // <reviewed reviewer="" date="" tests="tFrequencyAligner.cc"> 00057 // </reviewed> 00058 // 00059 // <prerequisite> 00060 // <li> <linkto class=InterpolateArray1D>InterpoateArray1D</linkto> 00061 // <li> <linkto class=Array>Array</linkto> 00062 // </prerequisite> 00063 00064 // <synopsis> 00065 // Spectra are converted to the specified reference frame and aligned at 00066 // a specified instant in time. 00067 // 00068 // You should not try to convert from, say, a SpectralCoordinate::TOPO to 00069 // MFrequency::TOPO as this would be meaningless. This class is designed 00070 // mainly to convert say from a SpectralCoordinate::TOPO to say, a BARY 00071 // frame and align. 00072 // </synopsis> 00073 // 00074 // <motivation> 00075 // Required for ASAP single-dish package 00076 // </motivation> 00077 // 00078 // <todo asof="2004/11/01"> 00079 // </todo> 00080 00081 00082 template <class T> class FrequencyAligner 00083 { 00084 public: 00085 00086 // Default constructor (object not viable) 00087 FrequencyAligner(); 00088 00089 // Constructor specifies a SpectralCoordinate (any extra reference conversion 00090 // frame set in it will be ignored), the number of pixels in the spectra to 00091 // be aligned, a reference epoch to which all spectra will 00092 // be aligned, a direction on the sky, a position on the earth (the observatory), 00093 // and desired frequency system to align in. 00094 FrequencyAligner(const SpectralCoordinate& specCoord, uInt nPixels, 00095 const MEpoch& refEpoch, const MDirection& dir, 00096 const MPosition& pos, MFrequency::Types freqSystem); 00097 00098 // Copy constructor (copy semantics) 00099 FrequencyAligner (const FrequencyAligner<T>& other); 00100 00101 // Assignment (copy semantics) 00102 FrequencyAligner& operator=(const FrequencyAligner<T>& other); 00103 00104 // Destructor 00105 ~FrequencyAligner(); 00106 00107 // Set a tolerance (in pixels) to trigger regridding (function <src>align</src>). 00108 // If the maximum abcissa difference for the current spectrum abcissa compared 00109 // to the reference abcissa is greater than <src>tol (pixels)</src> then a 00110 // regrid is triggered. Otherwise the input is just copied to the output when 00111 // function <src>align</src> is called. Set to 0 to turn this tolerance 00112 // assessment off. This function may be not really worth using. 00113 void setTolerance (Double tol) {itsDiffTol = abs(tol);}; 00114 00115 // Align (via regridding) one spectrum taken at the specified epoch to 00116 // the reference epoch. Your provide the ordinate and mask (True==Good) 00117 // for the spectrum. The lengths of these vectors must be the same 00118 // as <src>nPixels</src> given in the constructor. The output vectors 00119 // are resized as needed. 00120 // You can use the last cached abcissa (computed by 00121 // this function) rather than recompute it if you have more than one spectrum 00122 // at the same epoch to convert (e.g. different polarizations). 00123 // If you do this, it is your responsibility to make sure that you 00124 // have called this function at least once with <src>useCachedAbcissa=False</src>. 00125 // If <src>extrapolate</src> is True, the regridding process is allowed 00126 // to extrapolate outside of the abcissa domain. Otherwise masked pixels will result. 00127 // Returns True if a regrid triggered, else False if just copied (see function 00128 // <src>setTolerance</src>. 00129 Bool align (Vector<T>& yOut, Vector<Bool>& maskOut, 00130 const Vector<T>& yIn, const Vector<Bool>& maskIn, 00131 const MEpoch& epoch, Bool useCachedAbcissa, 00132 typename InterpolateArray1D<Double,T>::InterpolationMethod method, 00133 Bool extrapolate=False); 00134 00135 // This function is the same as the previous except that you can specify the input abcissa as well 00136 // as the data and mask. The input abcissa must be in the same units as the Construction 00137 // SpectralCoordinate. The abcissa values must be in the same base reference frame 00138 // as the Construction SpectralCoordinate. So instead of the abcissa (in the 00139 // output reference frame) being computed from the Construction SC, you get to specify 00140 // the abcissa directly. This might be useful if you have more than one set of 00141 // spectra to align, all in the same Frame, but with different attributes such 00142 // as reference value/pixel etc. The output spectrum is still regridded to the 00143 // abcissa at the reference time generated at construction. 00144 // from the current 00145 Bool align (Vector<T>& yOut, Vector<Bool>& maskOut, 00146 const Vector<Double>& xIn, const Vector<T>& yIn, const Vector<Bool>& maskIn, 00147 const MEpoch& epoch, Bool useCachedAbcissa, 00148 typename InterpolateArray1D<Double,T>::InterpolationMethod method, 00149 Bool extrapolate=False); 00150 00151 // Align many spectra stored in an Array along the specified axis. All spectra are aligned 00152 // to the same frequency abcissa (as described in previous function). If any alignment 00153 // returns False, then the return value will be False, otherwise True is returned. 00154 Bool alignMany (Array<T>& yOut, Array<Bool>& maskOut, 00155 const Array<T>& yIn, const Array<Bool>& maskIn, 00156 uInt axis, const MEpoch& epoch, 00157 typename InterpolateArray1D<Double,T>::InterpolationMethod method, 00158 Bool extrapolate=False); 00159 00160 // Get the reference abcissa (as a frequency in the axis units set in the SpectralCoordinate) at the reference epoch 00161 void getReferenceAbcissa (Vector<Double>& xOut) const; 00162 00163 // Get the abcissa (as a frequency in the axis units set in the SpectralCoordinate) last cached by function <src>align</src> 00164 void getAbcissa (Vector<Double>& xOut) const; 00165 00166 // Get new aligned SpectralCoordinate. It is probably non-linear, but if you would 00167 // like a linear approximation, use the doLinear argument. 00168 SpectralCoordinate alignedSpectralCoordinate (Bool doLinear=True) const; 00169 00170 private: 00171 SpectralCoordinate itsSpecCoord; 00172 MFrequency::Convert itsMachine; 00173 MFrequency::Ref itsRefOut; // Need this as there is no easy way to update 00174 // the conversion machines epoch otherwise 00175 MFrequency::Types itsFreqSystem; 00176 // 00177 Vector<Double> itsRefFreqX; // Reference frequency abcissa 00178 Vector<Double> itsFreqX; // Frequency abcissa 00179 00180 Double itsDiffTol; // Tolerance which triggers a regrid 00181 00182 // Internal copy 00183 void copyOther (const FrequencyAligner<T>& other); 00184 00185 // Create the Conversion machine 00186 void makeMachine (const MEpoch& refEpoch, 00187 const MDirection& dir, 00188 const MPosition& pos, 00189 MFrequency::Types freqSystem, 00190 const Unit& unit); 00191 00192 // Generate an abcissa with the machine 00193 Double makeAbcissa (Vector<Double>& f, Bool doMaxDiff); 00194 00195 // Regrid one spectrum 00196 Bool regrid (Vector<T>& yOut, Vector<Bool>& maskOut, 00197 const Vector<Double>& xOut, 00198 const Vector<Double>& xIn, 00199 const Vector<T>& yIn, const Vector<Bool>& maskIn, 00200 typename InterpolateArray1D<Double,T>::InterpolationMethod method, 00201 Bool extrapolate, Double maxDiff) const; 00202 }; 00203 00204 00205 } //# End namespace casacore 00206 #ifndef CASACORE_NO_AUTO_TEMPLATES 00207 #include <casacore/coordinates/Coordinates/FrequencyAligner.tcc> 00208 #endif //# CASACORE_NO_AUTO_TEMPLATES 00209 #endif