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