LatticeExprNode.h

Go to the documentation of this file.
00001 //# LatticeExprNode.h:  LatticeExprNode.h
00002 //# Copyright (C) 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 //# $Id$
00027 
00028 #ifndef LATTICES_LATTICEEXPRNODE_H
00029 #define LATTICES_LATTICEEXPRNODE_H
00030 
00031 
00032 //# Includes
00033 #include <casacore/casa/aips.h>
00034 #include <casacore/lattices/LEL/LELInterface.h>
00035 #include <casacore/lattices/LEL/LELAttribute.h>
00036 #include <casacore/lattices/LEL/LELBinaryEnums.h>
00037 #include <casacore/lattices/LEL/LELUnaryEnums.h>
00038 #include <casacore/lattices/LEL/LELFunctionEnums.h>
00039 #include <casacore/casa/Arrays/IPosition.h>
00040 #include <casacore/casa/Utilities/CountedPtr.h>
00041 #include <casacore/casa/Utilities/DataType.h>
00042 
00043 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00044 
00045 //# Forward Declarations
00046 template <class T> class LatticeExpr;
00047 template <class T> class Lattice;
00048 template <class T> class MaskedLattice;
00049 template <class T> class Array;
00050 template <class T> class Block;
00051 class LCRegion;
00052 class Slicer;
00053 class LattRegionHolder;
00054 class LatticeExprNode;
00055 
00056 // Global functions operating on a LatticeExprNode.
00057 // <group name=GlobalLatticeExprNode>
00058   // Unary functions.
00059   // <group>
00060    LatticeExprNode operator+ (const LatticeExprNode& expr);
00061    LatticeExprNode operator- (const LatticeExprNode& expr);
00062    LatticeExprNode operator! (const LatticeExprNode& expr);
00063   // </group>
00064 
00065   // Numerical binary operators
00066   // <group>
00067    LatticeExprNode operator+ (const LatticeExprNode& left,
00068                               const LatticeExprNode& right);
00069    LatticeExprNode operator- (const LatticeExprNode& left,
00070                               const LatticeExprNode& right);
00071    LatticeExprNode operator* (const LatticeExprNode& left,
00072                               const LatticeExprNode& right);
00073    LatticeExprNode operator/ (const LatticeExprNode& left,
00074                               const LatticeExprNode& right);
00075    LatticeExprNode operator% (const LatticeExprNode& left,
00076                               const LatticeExprNode& right);
00077    LatticeExprNode operator^ (const LatticeExprNode& left,
00078                               const LatticeExprNode& right);
00079   // </group>
00080 
00081   // Relational binary operators
00082   // <group>
00083    LatticeExprNode operator== (const LatticeExprNode& left,
00084                                const LatticeExprNode& right);
00085    LatticeExprNode operator>  (const LatticeExprNode& left,
00086                                const LatticeExprNode& right);
00087    LatticeExprNode operator>= (const LatticeExprNode& left,
00088                                const LatticeExprNode& right);
00089    LatticeExprNode operator<  (const LatticeExprNode& left,
00090                                const LatticeExprNode& right);
00091    LatticeExprNode operator<= (const LatticeExprNode& left,
00092                                const LatticeExprNode& right);
00093    LatticeExprNode operator!= (const LatticeExprNode& left,
00094                                const LatticeExprNode& right);
00095   // </group>
00096 
00097   // Logical binary operators
00098   // <group>
00099    LatticeExprNode operator&& (const LatticeExprNode& left,
00100                                const LatticeExprNode& right);
00101    LatticeExprNode operator|| (const LatticeExprNode& left,
00102                                const LatticeExprNode& right);
00103   // </group>
00104 
00105   // Numerical 1-argument functions
00106   // <group>
00107    LatticeExprNode sin  (const LatticeExprNode& expr);
00108    LatticeExprNode sinh (const LatticeExprNode& expr);
00109    LatticeExprNode asin (const LatticeExprNode& expr);
00110    LatticeExprNode cos  (const LatticeExprNode& expr);
00111    LatticeExprNode cosh (const LatticeExprNode& expr);
00112    LatticeExprNode acos (const LatticeExprNode& expr);
00113    LatticeExprNode tan  (const LatticeExprNode& expr);
00114    LatticeExprNode tanh (const LatticeExprNode& expr);
00115    LatticeExprNode atan (const LatticeExprNode& expr);
00116    LatticeExprNode exp  (const LatticeExprNode& expr);
00117    LatticeExprNode log  (const LatticeExprNode& expr);
00118    LatticeExprNode log10(const LatticeExprNode& expr);
00119    LatticeExprNode sqrt (const LatticeExprNode& expr);
00120    LatticeExprNode sign (const LatticeExprNode& expr);
00121    LatticeExprNode round(const LatticeExprNode& expr);
00122    LatticeExprNode ceil (const LatticeExprNode& expr);
00123    LatticeExprNode floor(const LatticeExprNode& expr);
00124    LatticeExprNode conj (const LatticeExprNode& expr);
00125   // </group>
00126 
00127   // Numerical 2-argument functions
00128   // <group>
00129    LatticeExprNode atan2 (const LatticeExprNode& left,
00130                           const LatticeExprNode& right);
00131    LatticeExprNode pow  (const LatticeExprNode& left,
00132                          const LatticeExprNode& right);
00133    LatticeExprNode fmod (const LatticeExprNode& left,
00134                          const LatticeExprNode& right);
00135    LatticeExprNode min  (const LatticeExprNode& left,
00136                          const LatticeExprNode& right);
00137    LatticeExprNode max  (const LatticeExprNode& left,
00138                          const LatticeExprNode& right);
00139   // </group>
00140 
00141   // Form a complex number from two real numbers.
00142    LatticeExprNode formComplex (const LatticeExprNode& left,
00143                                 const LatticeExprNode& right);
00144 
00145   // Numerical 1-argument functions which result in a real number
00146   // regardless of input expression type
00147   // <group>
00148    LatticeExprNode abs  (const LatticeExprNode& expr);
00149    LatticeExprNode arg  (const LatticeExprNode& expr);
00150    LatticeExprNode real (const LatticeExprNode& expr);
00151    LatticeExprNode imag (const LatticeExprNode& expr);
00152   // </group>
00153 
00154   // 1-argument functions operating on a numeric expression resulting 
00155   // in a scalar
00156   // <group>
00157    LatticeExprNode min      (const LatticeExprNode& expr);
00158    LatticeExprNode max      (const LatticeExprNode& expr);
00159    LatticeExprNode sum      (const LatticeExprNode& expr);
00160    LatticeExprNode median   (const LatticeExprNode& expr);
00161    LatticeExprNode mean     (const LatticeExprNode& expr);
00162    LatticeExprNode variance (const LatticeExprNode& expr);
00163    LatticeExprNode stddev   (const LatticeExprNode& expr);
00164    LatticeExprNode avdev    (const LatticeExprNode& expr);
00165   // </group>
00166 
00167   // Determine the value of the element at the part <src>fraction</src>
00168   // from the beginning of the given lattice.
00169   // Thus <src>fraction=0.5</src> is equal to the median.
00170    LatticeExprNode fractile (const LatticeExprNode& expr,
00171                              const LatticeExprNode& fraction);
00172 
00173   // Determine the value range of the elements at the part <src>fraction1</src>
00174   // and fraction2 from the beginning of the given lattice. Both fractions
00175   // must be >=0 and <=1 and fraction1 must be <= fraction2.
00176   // By default <src>fraction2</src> is equal to <src>1-fraction1</src>.
00177   // Thus <src>fraction=0.25</src> gives the quartile range of the lattice.
00178   // <group>
00179    LatticeExprNode fractileRange (const LatticeExprNode& expr,
00180                                   const LatticeExprNode& fraction1,
00181                                   const LatticeExprNode& fraction2);
00182    LatticeExprNode fractileRange (const LatticeExprNode& expr,
00183                                   const LatticeExprNode& fraction);
00184   // </group>
00185 
00186   // 1-argument function to get the number of elements in a lattice.
00187   // If the lattice is masked, only the True elements are counted.
00188   // Results in a scalar Double.
00189    LatticeExprNode nelements (const LatticeExprNode& expr);
00190 
00191   // 1-argument function to get the dimensionality of a lattice.
00192   // 0 is returned if it is a scalar.
00193   // Results in a scalar Float.
00194    LatticeExprNode ndim (const LatticeExprNode& expr);
00195 
00196   // 2-argument function to get the length of an axis.
00197   // Results in a scalar Float.
00198   // The 2nd expression (giving the axis number) has to be a real scalar.
00199   // <note role=caution>
00200   // Axes start counting at 0.
00201   // If the axis is a number < 0, an exception is thrown.
00202   // If the axis is a number exceeding the dimensionality, 1 is returned.
00203   // </note>
00204    LatticeExprNode length (const LatticeExprNode& expr,
00205                            const LatticeExprNode& axis);
00206 
00207   // 2-argument function telling per pixel if its index on the given axis
00208   // is contained in the 2nd argument. The 2nd argument should be a boolean
00209   // vector where True means that the index is contained.
00210   // For indices >= vector_length, the 2nd argument defaults to False.
00211   // Results in a Bool array.
00212   // <note role=caution>
00213   // Axes start counting at 0.
00214   // If the axis is a number < 0 or >= ndim, an exception is thrown.
00215   // </note>
00216    LatticeExprNode indexin (const LatticeExprNode& axis,
00217                             const LatticeExprNode& indexFlags);
00218 
00219   // 2-argument function rebinning Lattice by given factors. The 2nd argument
00220   // should be a vector (preferably Float - really Int but Int not well
00221   // supported in LEL yet).  Results in a T array.
00222    LatticeExprNode rebin (const LatticeExprNode& expr,
00223                           const LatticeExprNode& bin);
00224 
00225 // Test if a value is a NaN.
00226    LatticeExprNode isNaN (const LatticeExprNode& expr);
00227 
00228   // Functions operating on a logical expression resulting in a scalar;
00229   // Functions "any" (are any pixels "True") and "all" (are all pixels
00230   // "True") result in a Bool; functions "ntrue" and "nfalse" result 
00231   // in a Double.
00232   // <group>
00233    LatticeExprNode any   (const LatticeExprNode& expr);
00234    LatticeExprNode all   (const LatticeExprNode& expr);
00235    LatticeExprNode ntrue (const LatticeExprNode& expr);
00236    LatticeExprNode nfalse(const LatticeExprNode& expr);
00237   // </group>
00238 
00239   // This function returns the mask of the given expression.
00240   // If it has no mask, the result is an array with all True values.
00241    LatticeExprNode mask (const LatticeExprNode& expr);
00242 
00243   // This function returns the value of the expression without a mask.
00244    LatticeExprNode value (const LatticeExprNode& expr);
00245 
00246   // This function finds <src>sqrt(left^2+right^2)</src>.  This
00247   // could be used to find the (biased) polarized intensity if
00248   // left and right are images of Stokes Q and U.
00249    LatticeExprNode amp (const LatticeExprNode& left,
00250                         const LatticeExprNode& right);
00251 
00252   // This function finds <src>180/pi*atan2(left,right)/2</src>.  This could be 
00253   // used to find the position of linear polarization if left 
00254   // and right are images of Stokes U and Q, respectively.
00255    LatticeExprNode pa (const LatticeExprNode& left,
00256                        const LatticeExprNode& right);
00257 
00258   // This function finds the spectral index
00259   // <src>alpha = log(s1/s2) / log(f1/f2)</src>.
00260    LatticeExprNode spectralindex (const LatticeExprNode& left,
00261                                   const LatticeExprNode& right);
00262 
00263   // Function resembling the ternary <src>?:</src> construct in C++.
00264   // The argument "condition" has to be a Bool scalar or lattice.
00265   // If an element in "condition" is True, the corresponding element from
00266   // "arg1" is taken, otherwise it is taken from "arg2".
00267    LatticeExprNode iif (const LatticeExprNode& condition,
00268                         const LatticeExprNode& arg1,
00269                         const LatticeExprNode& arg2);
00270 
00271   // This function replaces every masked-off element in the first argument
00272   // with the corresponding element from the second argument.
00273   // The first argument has to be a lattice (expression), the second can
00274   // be a scalar or lattice. The mask of the first argument is not changed.
00275   // If the first argument does not have a mask, this function does nothing.
00276    LatticeExprNode replace (const LatticeExprNode& arg1,
00277                             const LatticeExprNode& arg2);
00278 
00279   // Functions to convert to the given data type.  These are mostly 
00280   // meaningful for down-conversions (e.g. double to float),
00281   // since up-conversions are automatically done to get matching data types
00282   // when needed.  Note that some conversions are not supported, such
00283   // as Complex to Double or Float.
00284   // <br>The conversion to Bool is useful to convert a region to a
00285   // boolean lattice, which is only possible if the region is given
00286   // in world coordinates. Otherwise an exception is thrown.
00287   // <group>
00288    LatticeExprNode toFloat   (const LatticeExprNode& expr);
00289    LatticeExprNode toDouble  (const LatticeExprNode& expr);
00290    LatticeExprNode toComplex (const LatticeExprNode& expr);
00291    LatticeExprNode toDComplex(const LatticeExprNode& expr);
00292    LatticeExprNode toBool    (const LatticeExprNode& expr);
00293    LatticeExprNode convertType (const LatticeExprNode& expr, const Float*);
00294    LatticeExprNode convertType (const LatticeExprNode& expr, const Double*);
00295    LatticeExprNode convertType (const LatticeExprNode& expr, const Complex*);
00296    LatticeExprNode convertType (const LatticeExprNode& expr, const DComplex*);
00297    LatticeExprNode convertType (const LatticeExprNode& expr, const Bool*);
00298   // </group>
00299 // </group>
00300 
00301 
00302 
00303 // <summary>
00304 // Bridging class to allow C++ expressions involving lattices
00305 // </summary>
00306 //
00307 // <use visibility=export>
00308 //
00309 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00310 // </reviewed>
00311 //
00312 // <prerequisite>
00313 //   <li> <linkto class="Lattice"> Lattice</linkto>
00314 //   <li> <linkto class="LatticeExpr"> LatticeExpr</linkto>
00315 //   <li> <linkto class="LELInterface"> LELInterface</linkto>
00316 // </prerequisite>
00317 //
00318 // <etymology>
00319 // The name is derived from the fact that this class provides
00320 // an expression interface to the user which s/he may use to
00321 // write C++ expressions involving Lattices.  This class actually
00322 // constructs the nodes of the expression tree, hence its name.
00323 // It is used by the envelope class LatticeExpr and provides a 
00324 // bridge to the letter classes derived from LELInterface.
00325 // </etymology>
00326 //
00327 // <synopsis>
00328 //    This class is part of the interface which allows the C++ programmer
00329 //    to enter mathematical expressions involving Lattices. It is
00330 //    is part of a Letter/envelope scheme.  It's actually a bridge
00331 //    between the envelope class (LatticeExpr) and the letter classes
00332 //    (derived from LELInterface) and it exists largely to handle
00333 //    type conversions.  In a single type environment, the envelope
00334 //    class could have directly called the letter classes.
00335 //
00336 //    The envelope and bridge provide the interface which the programmer
00337 //    sees.  The letter classes do the real work and are hidden from
00338 //    the programmer.
00339 //
00340 //    All the expression manipulation functionality that the user has 
00341 //    access to is viewable in this class; it is here that the operators,
00342 //    functions and constructors are defined.  These allow the programmer
00343 //    to write mathematical expressions which involve Lattices.  The
00344 //    letter classes take care of the optimal traversal of the Lattice
00345 //    and the memory mangement thereof.  Thus the Lattices are iterated
00346 //    through and the expressions evaluated for each chunk (usually 
00347 //    a tile shape) of the iteration.
00348 //
00349 //    A description of the implementation details of these classes can
00350 //    be found in
00351 //    <a href="../notes/216.html">Note 216</a>
00352 //
00353 //    The available functionality is defined by the global friend functions
00354 //    and operators, plus the public constructors.  The other public members
00355 //    functions are generally not of interest to the user of this class.
00356 //
00357 //    Generally, if one writes an expression such as <src>a.copyData(sin(b))</src>,
00358 //    the expression is automatically converted first to a LatticeExprNode and
00359 //    then to a LatticeExpr (which is a Lattice) before evaluation occurs.
00360 //    However, it may occur that you wish to build an expression from
00361 //    subexpressions.  To do this, you must explcitly create objects of 
00362 //    class LatticeExprNode.  You cannot manipulate subexpressions of type
00363 //    LatticeExpr<T>.  See below for an example.
00364 // </synopsis> 
00365 //
00366 // <example>
00367 // <srcblock>
00368 //  ArrayLattice<Float>   f1(IPosition (2,nx,ny));
00369 //  ArrayLattice<Float>   f2(IPosition (2,nx,ny));
00370 //  f2.set(2.0);
00371 //  f1.copyData(2*f2+f2);
00372 // </srcblock>
00373 //  In this example, the values of the pixels in Lattice f1 are set
00374 //  to the values resulting from the expression "2*f2 + f2"
00375 //  I.e. the expression is evaluated for each pixel in the Lattices
00376 //
00377 //  Note that :
00378 //
00379 //  1) the Lattice::copyData function is expecting a Lattice argument.  
00380 //  2) LatticeExpr inherits from Lattice and therefore a LatticeExpr
00381 //     object is a valid argument object type
00382 //  3) The expression in the copyData call is automatically converted to 
00383 //     a LatticeExprNode by the constructors and operators in LatticeExprNode
00384 //  4) The LatticeExprNode object so created is automatically converted
00385 //     to a LatticeExpr by casting functions in LatticeExprNode.
00386 //
00387 // </example>
00388 //
00389 // <example>
00390 // <srcblock>
00391 //  ArrayLattice<Float>   f1(IPosition (2,nx,ny));
00392 //  ArrayLattice<Float>   f2(IPosition (2,nx,ny));
00393 //  ArrayLattice<Double>  d(IPosition (2,nx,ny));
00394 //  ArrayLattice<Complex> c(IPosition (2,nx,ny));
00395 //  ArrayLattice<Bool>    b(IPosition (2,nx,ny));
00396 //
00397 //  f2.set(1.0); d.set(2.0); c.set(Complex(2.0,3.0)); b.set(True);
00398 //  f1.copyData( (3.5*f2) + (cos(d)) - (10/min(d,f2)*(-abs(c))*ntrue(b)) - (C::pi) );
00399 // </srcblock>
00400 //  
00401 //  In this rather silly example, we fill Lattice "f1" with the result of the
00402 //  expression.  The expression shows the use of constants, unary operations, 
00403 //  binary operations, 1D and 2D functions.  It also shows how mixed types can 
00404 //  be handled.  The output Lattice is a Float, whereas  mixed into the 
00405 //  expression are subexpressions involving Float, Double, Complex and Bool
00406 //  Lattices.
00407 //
00408 // </example>
00409 //
00410 // <example>
00411 // <srcblock>
00412 //  ArrayLattice<Float>   f1(IPosition (2,nx,ny));
00413 //  ArrayLattice<Float>   f2(IPosition (2,nx,ny));
00414 //  f2.set(2.0);
00415 //  LatticeExprNode exp1(sin(f2));
00416 //  LatticeExprNode exp2(pow(f2,2.0));
00417 //  f1.copyData(exp1+exp2);
00418 // </srcblock>
00419 //  In this example, the expression is "sin(f2) + pow(f2,2.0)",
00420 //  but we have put it together from two subexpressions contained
00421 //  in LatticeExprNode objects exp1 and exp2.  Again the LatticeExprNode
00422 //  object formed from summing exp1 and exp2 is automatically converted
00423 //  to a LatticeExpr for consumption by copyData
00424 //
00425 // </example>
00426 //
00427 // <motivation>
00428 //  The Lattice expression classes enable the C++ programmer much simpler 
00429 //  handling of mathematical expressions involving lattices.  In addition, 
00430 //  these classes provide the infrastructure on top of which we can build 
00431 //  an image calculator for Glish users
00432 // </motivation>
00433 //
00434 // <todo asof="1997/01/15">
00435 //   <li> masks
00436 //   <li> regions
00437 // </todo>
00438 
00439 
00440 class LatticeExprNode
00441 {
00442 // All global functions need to be declared as friends.
00443 // <group>
00444    friend LatticeExprNode operator+ (const LatticeExprNode& expr);
00445    friend LatticeExprNode operator- (const LatticeExprNode& expr);
00446    friend LatticeExprNode operator! (const LatticeExprNode& expr);
00447    friend LatticeExprNode operator+ (const LatticeExprNode& left,
00448                                      const LatticeExprNode& right);
00449    friend LatticeExprNode operator- (const LatticeExprNode& left,
00450                                      const LatticeExprNode& right);
00451    friend LatticeExprNode operator* (const LatticeExprNode& left,
00452                                      const LatticeExprNode& right);
00453    friend LatticeExprNode operator/ (const LatticeExprNode& left,
00454                                      const LatticeExprNode& right);
00455    friend LatticeExprNode operator% (const LatticeExprNode& left,
00456                                      const LatticeExprNode& right);
00457    friend LatticeExprNode operator^ (const LatticeExprNode& left,
00458                                      const LatticeExprNode& right);
00459    friend LatticeExprNode operator== (const LatticeExprNode& left,
00460                                       const LatticeExprNode& right);
00461    friend LatticeExprNode operator>  (const LatticeExprNode& left,
00462                                       const LatticeExprNode& right);
00463    friend LatticeExprNode operator>= (const LatticeExprNode& left,
00464                                       const LatticeExprNode& right);
00465    friend LatticeExprNode operator<  (const LatticeExprNode& left,
00466                                       const LatticeExprNode& right);
00467    friend LatticeExprNode operator<= (const LatticeExprNode& left,
00468                                       const LatticeExprNode& right);
00469    friend LatticeExprNode operator!= (const LatticeExprNode& left,
00470                                       const LatticeExprNode& right);
00471    friend LatticeExprNode operator&& (const LatticeExprNode& left,
00472                                       const LatticeExprNode& right);
00473    friend LatticeExprNode operator|| (const LatticeExprNode& left,
00474                                       const LatticeExprNode& right);
00475    friend LatticeExprNode sin  (const LatticeExprNode& expr);
00476    friend LatticeExprNode sinh (const LatticeExprNode& expr);
00477    friend LatticeExprNode asin (const LatticeExprNode& expr);
00478    friend LatticeExprNode cos  (const LatticeExprNode& expr);
00479    friend LatticeExprNode cosh (const LatticeExprNode& expr);
00480    friend LatticeExprNode acos (const LatticeExprNode& expr);
00481    friend LatticeExprNode tan  (const LatticeExprNode& expr);
00482    friend LatticeExprNode tanh (const LatticeExprNode& expr);
00483    friend LatticeExprNode atan (const LatticeExprNode& expr);
00484    friend LatticeExprNode exp  (const LatticeExprNode& expr);
00485    friend LatticeExprNode log  (const LatticeExprNode& expr);
00486    friend LatticeExprNode log10(const LatticeExprNode& expr);
00487    friend LatticeExprNode sqrt (const LatticeExprNode& expr);
00488    friend LatticeExprNode sign (const LatticeExprNode& expr);
00489    friend LatticeExprNode round(const LatticeExprNode& expr);
00490    friend LatticeExprNode ceil (const LatticeExprNode& expr);
00491    friend LatticeExprNode floor(const LatticeExprNode& expr);
00492    friend LatticeExprNode conj (const LatticeExprNode& expr);
00493    friend LatticeExprNode atan2 (const LatticeExprNode& left,
00494                                  const LatticeExprNode& right);
00495    friend LatticeExprNode pow  (const LatticeExprNode& left,
00496                                 const LatticeExprNode& right);
00497    friend LatticeExprNode fmod (const LatticeExprNode& left,
00498                                 const LatticeExprNode& right);
00499    friend LatticeExprNode min  (const LatticeExprNode& left,
00500                                 const LatticeExprNode& right);
00501    friend LatticeExprNode max  (const LatticeExprNode& left,
00502                                 const LatticeExprNode& right);
00503    friend LatticeExprNode formComplex (const LatticeExprNode& left,
00504                                        const LatticeExprNode& right);
00505    friend LatticeExprNode abs  (const LatticeExprNode& expr);
00506    friend LatticeExprNode arg  (const LatticeExprNode& expr);
00507    friend LatticeExprNode real (const LatticeExprNode& expr);
00508    friend LatticeExprNode imag (const LatticeExprNode& expr);
00509    friend LatticeExprNode min      (const LatticeExprNode& expr);
00510    friend LatticeExprNode max      (const LatticeExprNode& expr);
00511    friend LatticeExprNode sum      (const LatticeExprNode& expr);
00512    friend LatticeExprNode median   (const LatticeExprNode& expr);
00513    friend LatticeExprNode mean     (const LatticeExprNode& expr);
00514    friend LatticeExprNode variance (const LatticeExprNode& expr);
00515    friend LatticeExprNode stddev   (const LatticeExprNode& expr);
00516    friend LatticeExprNode avdev    (const LatticeExprNode& expr);
00517    friend LatticeExprNode fractile (const LatticeExprNode& expr,
00518                                     const LatticeExprNode& fraction);
00519    friend LatticeExprNode fractileRange (const LatticeExprNode& expr,
00520                                          const LatticeExprNode& fraction1,
00521                                          const LatticeExprNode& fraction2);
00522    friend LatticeExprNode fractileRange (const LatticeExprNode& expr,
00523                                          const LatticeExprNode& fraction);
00524    friend LatticeExprNode nelements (const LatticeExprNode& expr);
00525    friend LatticeExprNode ndim (const LatticeExprNode& expr);
00526    friend LatticeExprNode length (const LatticeExprNode& expr,
00527                                   const LatticeExprNode& axis);
00528    friend LatticeExprNode indexin (const LatticeExprNode& axis,
00529                                    const LatticeExprNode& indexFlags);
00530    friend LatticeExprNode rebin (const LatticeExprNode& expr,
00531                                  const LatticeExprNode& bin);
00532    friend LatticeExprNode isNaN (const LatticeExprNode& expr);
00533    friend LatticeExprNode any   (const LatticeExprNode& expr);
00534    friend LatticeExprNode all   (const LatticeExprNode& expr);
00535    friend LatticeExprNode ntrue (const LatticeExprNode& expr);
00536    friend LatticeExprNode nfalse(const LatticeExprNode& expr);
00537    friend LatticeExprNode mask (const LatticeExprNode& expr);
00538    friend LatticeExprNode value (const LatticeExprNode& expr);
00539    friend LatticeExprNode amp (const LatticeExprNode& left,
00540                                const LatticeExprNode& right);
00541    friend LatticeExprNode pa (const LatticeExprNode& left,
00542                               const LatticeExprNode& right);
00543    friend LatticeExprNode spectralindex (const LatticeExprNode& left,
00544                                          const LatticeExprNode& right);
00545    friend LatticeExprNode iif (const LatticeExprNode& condition,
00546                                const LatticeExprNode& arg1,
00547                                const LatticeExprNode& arg2);
00548    friend LatticeExprNode replace (const LatticeExprNode& arg1,
00549                                    const LatticeExprNode& arg2);
00550    friend LatticeExprNode toFloat   (const LatticeExprNode& expr);
00551    friend LatticeExprNode toDouble  (const LatticeExprNode& expr);
00552    friend LatticeExprNode toComplex (const LatticeExprNode& expr);
00553    friend LatticeExprNode toDComplex(const LatticeExprNode& expr);
00554    friend LatticeExprNode toBool    (const LatticeExprNode& expr);
00555 // </group>
00556 
00557 public:
00558 
00559 // Default constructor
00560    LatticeExprNode();
00561 
00562 // Unary constant expression constructors.
00563 // <group>
00564    LatticeExprNode (Int64 constant);
00565    LatticeExprNode (Int constant);
00566    LatticeExprNode (uInt constant);
00567    LatticeExprNode (Long constant);
00568    LatticeExprNode (Float constant);
00569    LatticeExprNode (Double constant);
00570    LatticeExprNode (const Complex& constant);
00571    LatticeExprNode (const DComplex& constant);
00572    LatticeExprNode (Bool constant);
00573 // </group>
00574 
00575 // Constructor from an IPosition (containing indices or axes).
00576    LatticeExprNode (const IPosition&);
00577 
00578 // Lattice expression (gets Lattice pixels) constructors.
00579 // <group>
00580    LatticeExprNode (const Lattice<Float>& lattice);
00581    LatticeExprNode (const Lattice<Double>& lattice);
00582    LatticeExprNode (const Lattice<Complex>& lattice);
00583    LatticeExprNode (const Lattice<DComplex>& lattice);
00584    LatticeExprNode (const Lattice<Bool>& lattice);
00585    LatticeExprNode (const MaskedLattice<Float>& lattice);
00586    LatticeExprNode (const MaskedLattice<Double>& lattice);
00587    LatticeExprNode (const MaskedLattice<Complex>& lattice);
00588    LatticeExprNode (const MaskedLattice<DComplex>& lattice);
00589    LatticeExprNode (const MaskedLattice<Bool>& lattice);
00590 // </group>
00591 
00592 // Create a lattice expression from a region.
00593 // It results in a boolean expression node.
00594 // <group>
00595    LatticeExprNode (const LCRegion& region);
00596    LatticeExprNode (const Slicer& slicer);
00597    LatticeExprNode (const LattRegionHolder& region);
00598 // </group>
00599 
00600 // Masking operator using a condition.
00601 // The given boolean expression forms a mask/region for this expression node.
00602    LatticeExprNode operator[] (const LatticeExprNode& cond) const;
00603 
00604 // Copy constructor (reference semantics)
00605    LatticeExprNode (const LatticeExprNode& other);
00606 
00607 // Destructor, does nothing
00608    virtual ~LatticeExprNode();
00609 
00610 // Assignment (reference semantics)
00611    LatticeExprNode& operator= (const LatticeExprNode& other);
00612 
00613 // Get the IPosition.
00614 // It throws an exception if the node does not contain an IPosition.
00615    const IPosition& getIPosition() const;
00616 
00617 // Convert the expression to another data type.
00618 // <group>
00619    CountedPtr<LELInterface<Float> >    makeFloat() const;
00620    CountedPtr<LELInterface<Double> >   makeDouble() const;
00621    CountedPtr<LELInterface<Complex> >  makeComplex() const;
00622    CountedPtr<LELInterface<DComplex> > makeDComplex() const;
00623    CountedPtr<LELInterface<Bool> >     makeBool() const;
00624 // </group>
00625 
00626 // Evaluate the expression.
00627 // One can be sure that the result is not a reference to another array.
00628 // This function should be used by LatticeExpr and other users.
00629 // <group>
00630    void eval (LELArray<Float>& result, const Slicer& section) const;
00631    void eval (LELArray<Double>& result, const Slicer& section) const;
00632    void eval (LELArray<Complex>& result, const Slicer& section) const;
00633    void eval (LELArray<DComplex>& result, const Slicer& section) const;
00634    void eval (LELArray<Bool>& result, const Slicer& section) const;
00635 // </group>
00636 
00637 // Evaluate the expression.
00638 // The result can be a reference to some internal array (in particular
00639 // to an array in an ArrayLattice object used as a lattice).
00640 // This function is meant for internal use by the LEL classes and
00641 // should not be used externally.
00642 // <group>
00643    void evalRef (LELArrayRef<Float>& result, const Slicer& section) const
00644     { pExprFloat_p->evalRef (result, section); }
00645    void evalRef (LELArrayRef<Double>& result, const Slicer& section) const
00646     { pExprDouble_p->evalRef (result, section); }
00647    void evalRef (LELArrayRef<Complex>& result, const Slicer& section) const
00648     { pExprComplex_p->evalRef (result, section); }
00649    void evalRef (LELArrayRef<DComplex>& result, const Slicer& section) const
00650     { pExprDComplex_p->evalRef (result, section); }
00651    void evalRef (LELArrayRef<Bool>& result, const Slicer& section) const
00652     { pExprBool_p->evalRef (result, section); }
00653 // </group>
00654 
00655 // Evaluate the expression (in case it is a scalar).  The "eval"
00656 // and "get*" functions do the same thing, they just have
00657 // a slightly different interface.
00658 // <group>
00659    void eval (Float& result) const;
00660    void eval (Double& result) const;
00661    void eval (Complex& result) const;
00662    void eval (DComplex& result) const;
00663    void eval (Bool& result) const;
00664    Float getFloat() const;
00665    Double getDouble() const;
00666    Complex getComplex() const;
00667    DComplex getDComplex() const;
00668    Bool getBool() const;
00669 // </group>
00670 
00671 // Evaluate the expression (in case it is a constant array).
00672 // <group>
00673    Array<Float> getArrayFloat() const;
00674    Array<Double> getArrayDouble() const;
00675    Array<Complex> getArrayComplex() const;
00676    Array<DComplex> getArrayDComplex() const;
00677    Array<Bool> getArrayBool() const;
00678 // </group>
00679 
00680 // Get the data type of the expression.
00681    DataType dataType() const
00682       {return dtype_p;}
00683 
00684 // Is the expression node a region?
00685    Bool isRegion() const
00686       {return pAttr_p->isRegion();}
00687 
00688 // Is the result of "eval" a scalar?
00689    Bool isScalar() const
00690       {return pAttr_p->isScalar();}
00691 
00692 // Is the result of "eval" masked?
00693    Bool isMasked() const
00694       {return pAttr_p->isMasked();}
00695 
00696 // Holds the node an invalid scalar?
00697    Bool isInvalidScalar() const
00698     {
00699       if (!donePrepare_p) doPrepare();
00700       return isInvalid_p;
00701     }
00702 
00703 // Return the shape of the Lattice including all degenerate axes
00704 // (ie. axes with a length of one)
00705    const IPosition& shape() const
00706       {return pAttr_p->shape();}
00707 
00708 // Get the attribute object of the expression.
00709    const LELAttribute& getAttribute() const
00710       {return *pAttr_p;}
00711 
00712 // Replace a scalar subexpression by its result.
00713    Bool replaceScalarExpr();
00714   
00715 // Make the object from a Counted<LELInterface> pointer.
00716 // Ideally this function is private, but alas it is needed in LELFunction1D,
00717 // operator==, and more (too many to make them friend).
00718 // <group>
00719    LatticeExprNode(const CountedPtr<LELInterface<Float> >& expr);
00720    LatticeExprNode(const CountedPtr<LELInterface<Double> >& expr);
00721    LatticeExprNode(const CountedPtr<LELInterface<Complex> >& expr);
00722    LatticeExprNode(const CountedPtr<LELInterface<DComplex> >& expr);
00723    LatticeExprNode(const CountedPtr<LELInterface<Bool> >& expr);
00724 // </group>
00725 
00726 // Determine the resulting data type from the given data types.
00727 // An exception is thrown if they are incompatible.
00728    static DataType resultDataType (DataType left, DataType right);
00729 
00730 // Check the arguments of a function and return the resulting attribute object.
00731 // The matchAxes argument tells if the axes have to match exactly or
00732 // whether it is possible that one expression is a subset of another
00733 // (i.e. that axes may be missing).
00734 // <br>The expectArray argument tells if the result should be an array
00735 // which is the case if one of the arguments is an array.
00736    static LELAttribute checkArg (const Block<LatticeExprNode>& arg,
00737                                  const Block<Int>& argType,
00738                                  Bool expectArray,
00739                                  Bool matchAxes = True);
00740 
00741   // Handle locking of the LatticeExpr which is delegated to all of its parts.
00742   // <group>
00743   Bool lock (FileLocker::LockType, uInt nattempts);
00744   void unlock();
00745   Bool hasLock (FileLocker::LockType) const;
00746   void resync();
00747   // </group>
00748 
00749 
00750 private:
00751 // Make the object from a LELInterface* pointer.
00752 // <group>
00753    LatticeExprNode(LELInterface<Float>* expr);
00754    LatticeExprNode(LELInterface<Double>* expr);
00755    LatticeExprNode(LELInterface<Complex>* expr);
00756    LatticeExprNode(LELInterface<DComplex>* expr);
00757    LatticeExprNode(LELInterface<Bool>* expr);
00758 // </group>
00759 
00760 // Test if both operands represent a region.
00761 // An exception is thrown if only one of them is a region.
00762    static Bool areRegions (const LatticeExprNode& left,
00763                            const LatticeExprNode& right);
00764 
00765 // Create a new node for a numerical unary operation.
00766 // The result has the same data type as the input.
00767    static LatticeExprNode newNumUnary (LELUnaryEnums::Operation oper,
00768                                        const LatticeExprNode& expr);
00769 
00770 // Create a new node for a numerical function with 1 argument.
00771 // The result has the same data type as the input.
00772    static LatticeExprNode newNumFunc1D (LELFunctionEnums::Function func,
00773                                         const LatticeExprNode& expr);
00774 
00775 // Create a new node for a real numerical function with 1 argument.
00776 // The result has the same data type as the input.
00777    static LatticeExprNode newRealFunc1D (LELFunctionEnums::Function func,
00778                                          const LatticeExprNode& expr);
00779 
00780 // Create a new node for a complex numerical function with 1 argument.
00781 // The result has the same data type as the input.
00782    static LatticeExprNode newComplexFunc1D (LELFunctionEnums::Function func,
00783                                             const LatticeExprNode& expr);
00784 
00785 // Create a new node for a numerical function with 1 argument that 
00786 // returns a real number
00787    static LatticeExprNode newNumReal1D (LELFunctionEnums::Function func,
00788                                         const LatticeExprNode& expr);
00789 
00790 // Create a new node for a numerical function with 2 arguments.
00791 // The result has the same data type as the combined input type.
00792    static LatticeExprNode newNumFunc2D (LELFunctionEnums::Function func,
00793                                         const LatticeExprNode& left,
00794                                         const LatticeExprNode& right);
00795 
00796 // Create a new node for a numerical binary operator.
00797 // The result has the same data type as the combined input type.
00798    static LatticeExprNode newNumBinary (LELBinaryEnums::Operation oper,
00799                                         const LatticeExprNode& left,
00800                                         const LatticeExprNode& right);
00801 
00802 // Create a new node for a logical binary operator.
00803 // The result has the same data type as the combined input type.
00804    static LatticeExprNode newLogBinary (LELBinaryEnums::Operation oper,
00805                                         const LatticeExprNode& left,
00806                                         const LatticeExprNode& right);
00807 
00808 // Create a new node for a comparison binary operator.
00809 // The result has the same data type as the combined input type.
00810    static LatticeExprNode newBinaryCmp (LELBinaryEnums::Operation oper,
00811                                         const LatticeExprNode& left,
00812                                         const LatticeExprNode& right);
00813 
00814 // Make (if needed and if possible) the expression nodes such that
00815 // the dimensionalities are equal. This is only possible if both
00816 // nodes have a coordinate system.
00817 // It is done by creating an ExtendLattice object for the node
00818 // with the lower dimensionality.
00819    static Int makeEqualDim (LatticeExprNode& expr0,
00820                             LatticeExprNode& expr1);
00821 
00822 // Do the preparation for the evaluation.
00823    void doPrepare() const;
00824 
00825    
00826 // Member variables.  
00827 
00828    Bool                donePrepare_p;
00829    DataType            dtype_p;
00830    Bool                isInvalid_p;
00831    IPosition           iposition_p;
00832    const LELAttribute* pAttr_p;
00833    CountedPtr<LELInterface<Float> >    pExprFloat_p;
00834    CountedPtr<LELInterface<Double> >   pExprDouble_p;
00835    CountedPtr<LELInterface<Complex> >  pExprComplex_p;
00836    CountedPtr<LELInterface<DComplex> > pExprDComplex_p;
00837    CountedPtr<LELInterface<Bool> >     pExprBool_p;
00838 };
00839 
00840 
00841 
00842 inline LatticeExprNode operator% (const LatticeExprNode& left,
00843                                   const LatticeExprNode& right)
00844   { return fmod (left, right); }
00845 inline LatticeExprNode operator^ (const LatticeExprNode& left,
00846                                   const LatticeExprNode& right)
00847   { return pow (left, right); }
00848 
00849 inline LatticeExprNode convertType(const LatticeExprNode& expr, const Float*)
00850   { return toFloat (expr); }
00851 inline LatticeExprNode convertType(const LatticeExprNode& expr, const Double*)
00852   { return toDouble (expr); }
00853 inline LatticeExprNode convertType(const LatticeExprNode& expr, const Complex*)
00854   { return toComplex (expr); }
00855 inline LatticeExprNode convertType(const LatticeExprNode& expr, const DComplex*)
00856   { return toDComplex (expr); }
00857 inline LatticeExprNode convertType(const LatticeExprNode& expr, const Bool*)
00858   { return toBool (expr); }
00859 
00860 } //# NAMESPACE CASACORE - END
00861 
00862 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1