casa
$Rev:20696$
|
00001 //# Convolver.h: this defines Convolver a class for doing convolution 00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,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 //# 00027 //# $Id: LatticeConvolver.h 20229 2008-01-29 15:19:06Z gervandiepen $ 00028 00029 #ifndef LATTICES_LATTICECONVOLVER_H 00030 #define LATTICES_LATTICECONVOLVER_H 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <scimath/Mathematics/NumericTraits.h> 00035 #include <lattices/Lattices/TempLattice.h> 00036 #include <casa/Arrays/IPosition.h> 00037 00038 namespace casa { //# NAMESPACE CASA - BEGIN 00039 00040 //# Forward Declarations 00041 //template <class T> class LatticeConvolver; 00042 class IPosition; 00043 00044 // <summary>Lists the different types of Convolutions that can be done</summary> 00045 // <synopsis>This enumerator is brought out as a separate class because g++ 00046 // currently cannot handle enumerators in a templated class. When it can this 00047 // class will go away and this enumerator moved into the Convolver 00048 // class</synopsis> 00049 class ConvEnums { 00050 public: 00051 enum ConvType { 00052 // Linear convolution 00053 LINEAR, 00054 // Circular Convolution 00055 CIRCULAR 00056 //# Assume the point spread function is symmetric 00057 //#REALSYMMETRIC 00058 }; 00059 }; 00060 00061 // <summary>A class for doing multi-dimensional convolution</summary> 00062 00063 // <use visibility=export> 00064 00065 // <reviewed reviewer="" date="yyyy/mm/dd" tests="tLatticeConvolver"> 00066 // </reviewed> 00067 00068 // <prerequisite> 00069 // <li> The mathematical concept of convolution 00070 // </prerequisite> 00071 // 00072 // <etymology> 00073 // The LatticeConvolver class will convolve Lattices. This class 00074 // complements the Convolver class which will convolve Arrays. 00075 // </etymology> 00076 // 00077 // <synopsis> 00078 // This class performs linear or circular convolution on Lattices. See the 00079 // <linkto class="Convolver">Convolver</linkto> class description of the 00080 // difference between linear and circular convolution. 00081 00082 // This class does convolutions by multiplying the Fourier transforms of the 00083 // supplied Lattices and returning the inverse transform of the product. This 00084 // is the best algorithm to use when the point spread function is large. This 00085 // class does all the padding with zeros necessary to implement this 00086 // algorithm. Hence the 00087 00088 // </synopsis> 00089 // 00090 // <example> 00091 // <srcblock> 00092 // 00093 // </srcblock> 00094 // </example> 00095 // 00096 // <motivation> 00097 // </motivation> 00098 // 00099 // <thrown> 00100 // <li> AipsError: if psf and model have a differing numbers of dimensions 00101 // </thrown> 00102 // 00103 // <todo asof="yyyy/mm/dd"> 00104 // <li> the class should detect if the psf or image is small and do the 00105 // convolution directly rather than use the Fourier domain 00106 // <li> Allow the psf to be specified with a 00107 // <linkto class=Function>Function</linkto>. 00108 // </todo> 00109 00110 template<class T> class LatticeConvolver 00111 { 00112 public: 00113 // The default constructor creates a LatticeConvolver that will convolve your 00114 // data with a point spread function (psf) that zero everywhere except at the 00115 // centre where it is one. Convolving with this psf will not change your 00116 // data. 00117 LatticeConvolver(); 00118 00119 // Create a convolver that is initialised to do circular convolution with the 00120 // specified point spread function. It is assumed that the supplied model 00121 // will be the same shape as the point spread function. 00122 LatticeConvolver(const Lattice<T> & psf, Bool doFast=False); 00123 00124 // Create a convolver that is initialised to do linear convolution with the 00125 // specified point spread function. The size of the model you will convolve 00126 // with must be specified. 00127 LatticeConvolver(const Lattice<T> & psf, const IPosition & modelShape, 00128 Bool doFast=False); 00129 00130 // Create a convolver that is initialised to do the specified type of 00131 // convolution with the specified point spread function. The size of the 00132 // model you expect to convolve with must be specified. 00133 LatticeConvolver(const Lattice<T> & psf, const IPosition & modelShape, 00134 ConvEnums::ConvType type, Bool doFast=False); 00135 00136 // The copy constructor uses reference semantics 00137 LatticeConvolver(const LatticeConvolver<T> & other); 00138 00139 // The assignment operator also uses reference semantics 00140 LatticeConvolver<T> & operator=(const LatticeConvolver<T> & other); 00141 00142 // The destructor does nothing special. 00143 ~LatticeConvolver(); 00144 00145 // Perform linear convolution of the model with the previously specified 00146 // psf. The supplied Lattices must be the same shape. 00147 void linear(Lattice<T> & result, const Lattice<T> & model); 00148 00149 // Perform in-place linear convolution of the model with the previously 00150 // specified psf. Return the result in the same Lattice as the 00151 // model. 00152 void linear(Lattice<T> & modelAndResult); 00153 00154 // Perform circular convolution of the model with the previously 00155 // specified psf. Return the answer in result. 00156 void circular(Lattice<T> & result, const Lattice<T> & model); 00157 00158 // Perform in-place linear convolution of the model with the previously 00159 // specified psf. Return the result in the same Lattice as the model. 00160 void circular(Lattice<T> & modelAndResult); 00161 00162 // Perform convolution on the specified model using the currently initialised 00163 // convolution type (linear or circular). These functions will not resize the 00164 // LatticeConvolver if the supplied Lattice is the wrong shape. 00165 // 00166 // If the LatticeConvolver is setup for circular Convolution then the size of 00167 // the supplied model must be less than or equal to the shape returned by the 00168 // fftshape() function, which is usually the same as the shape of the psf. 00169 // 00170 // If the LatticeConvolver is setup to do linear convolution the the 00171 // input and output Lattices must have the same shape as the result from the 00172 // shape() member function. The convolution may be either in-place or not. 00173 // <group> 00174 void convolve(Lattice<T> & modelAndResult) const; 00175 void convolve(Lattice<T> & result, const Lattice<T> & model) const; 00176 // </group> 00177 00178 // Return the psf currently used by this convolver. The supplied Lattice must 00179 // be the correct shape ie., the same as returned by the psfShape member 00180 // function. 00181 void getPsf(Lattice<T> & psf) const; 00182 00183 // Resize the LatticeConvolver to do convolutions of the specified type and 00184 // shape. The supplied function must always have the same number of 00185 // dimensions as the internal point spread function (which can be found using 00186 // the shape member function). The LatticeConvolver will be set up to do 00187 // circular or linear convolutions depending on the supplied type 00188 void resize(const IPosition & modelShape, ConvEnums::ConvType type); 00189 00190 // Returns the shape of the Lattices that the convolver will convolve. This 00191 // shape will always have as many dimensions as the psf that was used to 00192 // initialise the LatticeConvolver. If the LatticeConvolver is setup to do 00193 // circular convolutions then every axis of the returned IPosition will be 00194 // zero length. If the LatticeConvolver is setup to do linear convolutions 00195 // then the returned IPosition will have a positive values on each axis that 00196 // indicate the expected shape of the input model. 00197 IPosition shape() const; 00198 00199 // Returns the shape of the point spread function that the LatticeConvolver 00200 // was initialised with. 00201 IPosition psfShape() const; 00202 00203 // Returns the type of convolution the LatticeConvolver is currently set up 00204 // to do. 00205 ConvEnums::ConvType type() const; 00206 00207 // Returns the shape of the FFT's that the LatticeConvolver will do when 00208 // performing the convolution. Not really useful except as a diagnostic 00209 // tool. If the shape contains a lot of poorly factorisable lengths then the 00210 // convolution will be slow. 00211 IPosition fftShape() const; 00212 00213 // Set usage of fast convolve with lesser flips 00214 void setFastConvolve(); 00215 00216 private: 00217 //# The following functions are used in various places in the code and are 00218 //# documented in the .cc file. Static functions are used when the functions 00219 //# do not use the object state. They ensure that implicit assumptions 00220 //# about the current state and implicit side-effects are not possible 00221 //# because all information must be suplied in the input arguments 00222 static void pad(Lattice<T> & paddedLat, const Lattice<T> & inLat); 00223 static void unpad(Lattice<T> & result, const Lattice<T> & paddedResult); 00224 void makeXfr(const Lattice<T> & psf); 00225 void makePsf(Lattice<T> & psf) const; 00226 static IPosition calcFFTShape(const IPosition & psfShape, 00227 const IPosition & modelShape, 00228 ConvEnums::ConvType type); 00229 00230 IPosition itsPsfShape; 00231 IPosition itsModelShape; 00232 ConvEnums::ConvType itsType; 00233 IPosition itsFFTShape; 00234 TempLattice<typename NumericTraits<T>::ConjugateType>* itsXfr; 00235 TempLattice<T>* itsPsf; 00236 Bool itsCachedPsf; 00237 Bool doFast_p; 00238 }; 00239 00240 } //# NAMESPACE CASA - END 00241 00242 #ifndef CASACORE_NO_AUTO_TEMPLATES 00243 #include <lattices/Lattices/LatticeConvolver.tcc> 00244 #endif //# CASACORE_NO_AUTO_TEMPLATES 00245 #endif 00246