00001 //# LatticeExpr.h: LatticeExpr.h 00002 //# Copyright (C) 1997,1998,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 //# $Id$ 00027 00028 #ifndef LATTICES_LATTICEEXPR_H 00029 #define LATTICES_LATTICEEXPR_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/lattices/Lattices/MaskedLattice.h> 00035 #include <casacore/lattices/LEL/LatticeExprNode.h> 00036 #include <casacore/lattices/LRegions/LatticeRegion.h> 00037 #include <casacore/casa/Arrays/Slicer.h> 00038 00039 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00040 00041 //# Forward Declarations 00042 template <class T> class Array; 00043 template <class T> class LELArray; 00044 00045 00046 // <summary> Class to allow C++ expressions involving lattices </summary> 00047 00048 // <use visibility=export> 00049 00050 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00051 // </reviewed> 00052 00053 // <prerequisite> 00054 // <li> <linkto class="Lattice"> Lattice</linkto> 00055 // <li> <linkto class="LatticeExprNode"> LatticeExprNode</linkto> 00056 // 00057 // </prerequisite> 00058 // 00059 // <etymology> 00060 // The name is derived from the fact that this class provides 00061 // an expression interface to the user which s/he may use to 00062 // write C++ expressions involving Lattices. 00063 // </etymology> 00064 // 00065 // <synopsis> 00066 // This class provides an interface which allows the C++ programmer 00067 // to enter expressions such as "sin(a)+b" where "a" and "b" 00068 // are Lattices. 00069 // 00070 // This class is termed an envelope class, and inside it are the 00071 // letter classes which do the real work. In reality, the letter 00072 // classes are actually accessed via a bridging class called 00073 // LatticeExprNode, which exists to handle type conversions. 00074 // The letter classes iterate through the Lattices and evaluate the 00075 // expression for each chunk of the iteration (usually a tile shape). 00076 // 00077 // It is in the LatticeExprNode class that all the available expression 00078 // operations are defined, so you should look there to see what 00079 // functionality is available. 00080 // 00081 // A description of the implementation details of these classes can 00082 // be found in 00083 // <a href="../notes/216.html">Note 216</a> 00084 // </synopsis> 00085 // 00086 // <example> 00087 // <srcblock> 00088 // ArrayLattice<Float> f1(IPosition (2,nx,ny)); 00089 // ArrayLattice<Float> f2(IPosition (2,nx,ny)); 00090 // f2.set(2.0); 00091 // f1.copyData(2*f2+f2); 00092 // </srcblock> 00093 // 00094 // In this example, the values of the pixels in Lattice f1 are set 00095 // to the values resulting from the expression "2*f2 + f2" 00096 // I.e. the expression is evaluated for each pixel in the Lattices 00097 // 00098 // Note that : 00099 // 1) the Lattice::copyData function is expecting a Lattice argument. 00100 // 2) LatticeExpr inherits from Lattice and therefore a LatticeExpr 00101 // object is a valid argument object type 00102 // 3) The expression in the copyData call is automatically converted to 00103 // a LatticeExprNode by the constructors and operators in LatticeExprNode 00104 // 4) The LatticeExprNode object so created is automatically converted 00105 // to a LatticeExpr by casting functions in LatticeExprNode. 00106 // </example> 00107 // 00108 // <example> 00109 // <srcblock> 00110 // ArrayLattice<Float> f1(IPosition (2,nx,ny)); 00111 // ArrayLattice<Float> f2(IPosition (2,nx,ny)); 00112 // ArrayLattice<Double> d(IPosition (2,nx,ny)); 00113 // ArrayLattice<Complex> c(IPosition (2,nx,ny)); 00114 // ArrayLattice<Bool> b(IPosition (2,nx,ny)); 00115 // 00116 // f2.set(1.0); d.set(2.0); c.set(Complex(2.0,3.0)); b.set(True); 00117 // f1.copyData( (3.5*f2) + (cos(d)) - (10/min(d,f2)*(-abs(c))*ntrue(b)) - (C::pi) ); 00118 // </srcblock> 00119 // 00120 // In this rather silly example, we fill Lattice "f1" with the result of the 00121 // expression. The expression shows the use of constants, unary operations, 00122 // binary operations, 1D and 2D functions. It also shows how mixed types can 00123 // be handled. The output Lattice is a Float, whereas mixed into the 00124 // expression are subexpressions involving Float, Double, Complex and Bool 00125 // Lattices. 00126 // 00127 // </example> 00128 // 00129 // <motivation> 00130 // The Lattice expression classes enable the C++ programmer much simpler 00131 // handling of mathematical expressions involving lattices. In addition, 00132 // these classes provide the infrastructure on top of which we can build 00133 // an image calculator for Glish users 00134 // </motivation> 00135 00136 // <todo asof="1997/01/15"> 00137 // <li> masks 00138 // <li> regions 00139 // </todo> 00140 00141 00142 template <class T> class LatticeExpr : public MaskedLattice<T> 00143 { 00144 public: 00145 00146 // Default constructor 00147 LatticeExpr(); 00148 00149 // Constructor from an arbitrary LatticeExprNode expression object. 00150 // An exception is thrown if the expression data type cannot be 00151 // converted to the template data type. 00152 // The shape argument is mandatory if the expression has no shape. 00153 // If the expression has a shape and if shape is given, it is checked 00154 // if they are equal. 00155 LatticeExpr (const LatticeExprNode& expr); 00156 LatticeExpr (const LatticeExprNode& expr, const IPosition& latticeShape); 00157 00158 // Copy constructor (reference semantics) 00159 LatticeExpr (const LatticeExpr<T>& other); 00160 00161 // Destructor, does nothing 00162 virtual ~LatticeExpr(); 00163 00164 // Assignment (reference semantics) 00165 LatticeExpr<T>& operator=(const LatticeExpr<T>& other); 00166 00167 // Make a copy of the derived object (reference semantics). 00168 virtual MaskedLattice<T>* cloneML() const; 00169 00170 // Has the object really a mask? 00171 virtual Bool isMasked() const; 00172 00173 // Get the region used (always returns 0). 00174 virtual const LatticeRegion* getRegionPtr() const; 00175 00176 // Returns False, as the LatticeExpr lattice is not writable. 00177 virtual Bool isWritable() const; 00178 00179 // Handle locking of the LatticeExpr which is delegated to all of its parts. 00180 // <br>hasLock() is True if all parts of the expression return True. 00181 // <br>It is strongly recommended to use class 00182 // <linkto class=LatticeLocker>LatticeLocker</linkto> to 00183 // handle lattice locking. It also contains a more detailed 00184 // explanation of the locking process. 00185 // <group> 00186 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00187 virtual void unlock(); 00188 virtual Bool hasLock (FileLocker::LockType) const; 00189 // </group> 00190 00191 // Resynchronize the Lattice object with the lattice file. 00192 // This function is only useful if no read-locking is used, ie. 00193 // if the table lock option is UserNoReadLocking or AutoNoReadLocking. 00194 // In that cases the table system does not acquire a read-lock, thus 00195 // does not synchronize itself automatically. 00196 // <br>By default the function does not do anything at all. 00197 virtual void resync(); 00198 00199 // Returns the shape of the Lattice including all degenerate axes 00200 // (i.e. axes with a length of one) 00201 virtual IPosition shape() const; 00202 00203 // Return the best cursor shape. 00204 virtual IPosition doNiceCursorShape (uInt maxPixels) const; 00205 00206 // Returns the coordinates of the lattice expression. 00207 virtual LELCoordinates lelCoordinates() const; 00208 00209 // Do the actual get of the data. 00210 // The return value is always False, thus the buffer does not reference 00211 // another array. 00212 virtual Bool doGetSlice (Array<T>& buffer, const Slicer& section); 00213 00214 // Do the actual get of the mask data. 00215 // The return value is always False, thus the buffer does not reference 00216 // another array. 00217 virtual Bool doGetMaskSlice (Array<Bool>& buffer, const Slicer& section); 00218 00219 // An expression is not writable so this functions throws an exception. 00220 virtual void doPutSlice (const Array<T>& sourceBuffer, 00221 const IPosition& where, 00222 const IPosition& stride); 00223 00224 // Copy the data from this lattice to the given lattice. 00225 virtual void copyDataTo (Lattice<T>& to) const; 00226 00227 // Handle the Math operators (+=, -=, *=, /=). 00228 // They work similarly to copyData(To). 00229 // However, they are not defined for Bool types, thus specialized below. 00230 virtual void handleMathTo (Lattice<T>& to, int oper) const; 00231 00232 private: 00233 // Initialize the object from the expression. 00234 void init (const LatticeExprNode& expr); 00235 00236 00237 LatticeExprNode expr_p; //# its shape can be undefined 00238 IPosition shape_p; //# this shape is always defined 00239 LELArray<T>* lastChunkPtr_p; 00240 Slicer lastSlicer_p; 00241 }; 00242 00243 00244 template<> inline 00245 void LatticeExpr<Bool>::handleMathTo (Lattice<Bool>&, int) const 00246 { throwBoolMath(); } 00247 00248 00249 00250 } //# NAMESPACE CASACORE - END 00251 00252 #ifndef CASACORE_NO_AUTO_TEMPLATES 00253 #include <casacore/lattices/LEL/LatticeExpr.tcc> 00254 #endif //# CASACORE_NO_AUTO_TEMPLATES 00255 #endif