casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ConvolutionEquation.h
Go to the documentation of this file.
00001 //# ConvolutionEquation.h: this defines ConvolutionEquation
00002 //# Copyright (C) 1996,1997,1999,2000,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$
00028 
00029 #ifndef SYNTHESIS_CONVOLUTIONEQUATION_H
00030 #define SYNTHESIS_CONVOLUTIONEQUATION_H
00031 
00032 
00033 #include <casa/aips.h>
00034 #include <synthesis/MeasurementEquations/LinearEquation.h>
00035 #include <synthesis/MeasurementEquations/LinearModel.h>
00036 #include <casa/Arrays/MaskedArray.h>
00037 #include <scimath/Mathematics/Convolver.h>
00038 #include <casa/Arrays/Array.h>
00039 #include <casa/Arrays/IPosition.h>
00040 
00041 namespace casa { //# NAMESPACE CASA - BEGIN
00042 
00043 // <summary> Implements the convolution equation </summary>
00044 
00045 // <use visibility=local>
00046 
00047 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00048 // </reviewed>
00049 
00050 // <prerequisite> 
00051 // <li> <linkto class="HogbomCleanModel">HogbomCleanModel</linkto> 
00052 //       (or similar classes) 
00053 // <li> LinearModel/LinearEquation Paradigm 
00054 // </prerequisite>
00055 //
00056 // <etymology>
00057 // This class implements convolution within the LinearEquation framework.
00058 // </etymology>
00059 //
00060 // <synopsis>
00061 // This class is used in conjunction with classes like HogbomCleanModel to
00062 // implement deconvolution algorithms. This class contains the point spread
00063 // function (psf) and the convolved data (dirty image), and is able to
00064 // convolve a supplied model with the psf to produce a predicted output
00065 // (using the evaluate() function), or to subtract the convolved data and
00066 // produce a residual (using the residual() function).
00067 //
00068 // See the documentation for 
00069 // <linkto class=HogbomCleanModel>HogbomCleanModel</linkto> 
00070 // for an example of how this class can be used to perform deconvolution.
00071 //
00072 // This class also contains specialised functions (like the version of
00073 // evaluate() for a point source model) that speed up the calculation of the
00074 // convolution. This specialised version of evaluate() does not need to
00075 // actually perform the convolution and instead returns a suitable part of
00076 // the psf (zero padded if necessary). When this function is called this
00077 // class will get the psf from the convolver and cache it, on the assumption
00078 // that many evaluations of this function will be requested (as occurs in
00079 // Clean algorithms). 
00080 // 
00081 // The size and shape of the psf and the supplied model may be different. The
00082 // only restriction is that the dimension of the psf must be less than or
00083 // equal to the dimension of the model. If the dimension of the
00084 // model is larger than the dimension of the psf then the convolution
00085 // will be repeated along the slowest moving (last) axis. The dirty image
00086 // and the supplied model must be the same size and shape. 
00087 //
00088 // This class can also operate on MaskedArrays (and models representable by
00089 // MaskedArrays). But the mask is currently discarded and the convolution
00090 // performed on the entire supplied model. This may change in the future.
00091 //
00092 // </synopsis>
00093 //
00094 // <example>
00095 // <srcblock>
00096 // Matrix<Float> psf(4,4), dirty(20,20), model(20,20);
00097 // .... put some meaningful values into these Arrays....
00098 // // create a convolution equation, and an array model
00099 // ConvolutionEquation convEqn(psf, dirty);
00100 // ArrayModel<Float> myModel(model);
00101 // // now calculate the convolution of the model and the psf
00102 // Matrix<Float> prediction;
00103 // convEqn.evaluate(myModel, prediction);
00104 // // and calculate the difference between the predicted and actual convolution
00105 // Matrix<Float> residual;
00106 // convEqn.residual(mymodel, residual)
00107 // </srcblock>
00108 // </example>
00109 //
00110 // <motivation>
00111 // This class was designed with deconvolution in mind. 
00112 // </motivation>
00113 //
00114 // <todo asof="1990/05/03">
00115 //   <li> Fix up the way this class works for other data types. 
00116 //        It currently can handle Arrays of Floats only.
00117 //        I do not intend to extend it to handle Double, Complex, & DComplex
00118 //        until there is a demand.
00119 //   <li> This class is not templated. If necessary I would use templating
00120 //        to produce a Double Precision Version.
00121 // </todo>
00122 
00123 class ConvolutionEquation: 
00124   public LinearEquation< Array<Float>, Array<Float> >
00125 {
00126 public:
00127   // Construct the ConvolutionEquation. Until I write some functions for
00128   // setting the private data the default constructor is essentially useless
00129   ConvolutionEquation();
00130 
00131   // Construct the ConvolutionEquation setting the psf and measured data
00132   ConvolutionEquation(const Array<Float> & psf, 
00133                       const Array<Float> & dirtyImage);
00134 
00135   // Construct the ConvolutionEquation setting the psf and measured data
00136   // Even though a MaskedArray is used as an arguement the mask is discarded
00137   // internally and hence not used by residual().
00138   ConvolutionEquation(const Array<Float> & psf, 
00139                       const MaskedArray<Float> & dirtyImage);
00140 
00141   // Somewhere I read that a destructor should alway be defined even if it
00142   // does nothing (as this one does).
00143   ~ConvolutionEquation();
00144   
00145   // Do the convolution of the model supplied by the LinearModel class with
00146   // the internal psf. Return the answer in result .
00147   virtual Bool evaluate(Array<Float> & result, 
00148                         const LinearModel< Array<Float> > & model);
00149 
00150   // Do the convolution of the model supplied by the LinearModel class with
00151   // the internal psf. Return the answer in result. This version 
00152   // uses Masked arrays. but the mask is currently discarded internally. 
00153   Bool evaluate(Array<Float> & result, 
00154                 const LinearModel< MaskedArray<Float> > & model);
00155 
00156   // Do the convolution of the model supplied by the LinearModel class with
00157   // the internal psf. Return the answer in result. This version 
00158   // uses MaskedArrays,  but the mask is not currently used. However
00159   // the model mask is transfered to the result unchanged.
00160   Bool evaluate(MaskedArray<Float> & result, 
00161                 const LinearModel< MaskedArray<Float> > & model);
00162 
00163   // Do the convolution of the a point source model at position 'position'
00164   // with amplitude 'amplitude' and the internal psf. Return the answer in
00165   // result. 
00166   Bool evaluate(Array<Float> & result, const IPosition & position, 
00167                 const Float amplitude, 
00168                 const IPosition & modelShape);
00169 
00170   // Calculate the convolution of the model (supplied by the LinearModel
00171   // class) and the psf and the difference between this and the supplied
00172   // (presumably measured) convolution.  
00173   virtual Bool residual(Array<Float> & result, 
00174                         const LinearModel< Array<Float> > & model);
00175 
00176 
00177   // Calculate the convolution of the model (supplied by the LinearModel
00178   // class) and the psf and the difference between this and the supplied
00179   // (presumably measured) convolution.   Also return chisq.
00180   virtual Bool residual( Array<Float> & result, Float & chisq, 
00181                         const LinearModel< Array<Float> > & model);
00182 
00183   // Calculate the convolution of the model (supplied by the LinearModel
00184   // class) and the psf and the difference between this and the supplied
00185   // (presumably measured) convolution.   Also return chisq,
00186   // considering a mask image
00187   virtual Bool residual( Array<Float> & result, Float & chisq, 
00188                          Array<Float> & mask,
00189                          const LinearModel< Array<Float> > & model);
00190 
00191   // Calculate the convolution of the model (supplied by the LinearModel
00192   // class) and the psf and the difference between this and the supplied
00193   // (presumably measured) convolution. This version 
00194   // uses Masked arrays. but the mask is currently discarded internally.
00195   Bool residual(Array<Float> & result, 
00196                 const LinearModel< MaskedArray<Float> > & model);
00197 
00198   // Calculate the convolution of the model (supplied by the LinearModel
00199   // class) and the psf and the difference between this and the supplied
00200   // (presumably measured) convolution. This version 
00201   // uses Masked arrays. but the mask is currently discarded in the
00202   // calculations and transfered unchanged from the model to the result.
00203   Bool residual(MaskedArray<Float> & result, 
00204                 const LinearModel< MaskedArray<Float> > & model);
00205 
00206   // return the psf size used in the convolution. The returned size does not
00207   // include any zero padding  
00208   IPosition psfSize();
00209   // release the storage associated with the cached psf. The psf can 
00210   // however still be recovered from the Convolver object
00211   void flushPsf();
00212 
00213 private:
00214   Array<Float> theMeas;
00215   Array<Float> thePsf;
00216   IPosition theRealPsfSize;
00217   IPosition thePsfOrigin;
00218   Convolver<Float> theConv;
00219 };
00220 
00221 
00222 } //# NAMESPACE CASA - END
00223 
00224 #endif