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