casa
$Rev:20696$
|
00001 //# ImageExprParse.h: Classes to hold results from image expression parser 00002 //# Copyright (C) 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: ImageExprParse.h 20615 2009-06-09 02:16:01Z Malte.Marquarding $ 00027 00028 #ifndef IMAGES_IMAGEEXPRPARSE_H 00029 #define IMAGES_IMAGEEXPRPARSE_H 00030 00031 00032 //# Includes 00033 #include <lattices/Lattices/LatticeExpr.h> 00034 #include <casa/BasicSL/Complex.h> 00035 #include <casa/BasicSL/String.h> 00036 #include <casa/Utilities/DataType.h> 00037 #include <casa/stdvector.h> 00038 #include <casa/Utilities/CountedPtr.h> 00039 #include <casa/HDF5/HDF5File.h> 00040 00041 namespace casa { //# NAMESPACE CASA - BEGIN 00042 00043 //# Forward Declarations 00044 template<class T> class Block; 00045 template<class T> class PtrBlock; 00046 class ImageRegion; 00047 class Table; 00048 class Slice; 00049 00050 00051 // <summary> 00052 // Class to hold values from image expression parser 00053 // </summary> 00054 00055 // <use visibility=export> 00056 00057 // <reviewed reviewer="" date="" tests=""> 00058 // </reviewed> 00059 00060 // <prerequisite> 00061 //# Classes you should understand before using this one. 00062 // <li> <linkto class=LatticeExpr>LatticeExpr</linkto> 00063 // </prerequisite> 00064 00065 // <etymology> 00066 // ImageExprParse is the class used to parse an image expression command. 00067 // </etymology> 00068 00069 // <synopsis> 00070 // ImageExprParse is used by the parser of image expression statements. 00071 // The parser is written in Bison and Flex in files ImageExprGram.y and .l. 00072 // The statements in there use the routines in this file to act 00073 // upon a reduced rule. 00074 // <p> 00075 // The main function (and the only function to be used by a user) is the 00076 // static function ImageExprParse::command which parses an expression command. 00077 // It returns a <linkto class=LatticeExprNode>LatticeExprNode</linkto> 00078 // object containing the expression represented as a tree. 00079 // The object can be used as a <src>Lattice(Expr)<T></src> in other operations. 00080 // <p> 00081 // The syntax of the command is similar to that of expressions in C++. 00082 // E.g. 00083 // <srcblock> 00084 // min(img1, img2) + sin(img3) 00085 // </srcblock> 00086 // The following items can be used in an expression: 00087 // <ul> 00088 // <li> Binary operators +, -, *, /, % (modulo), and ^ (power). 00089 // <li> Unary operators + and -. 00090 // <li> Comparison operators ==, >, >=, <, <=, and !=. 00091 // <li> Logical operators &&, ||, and !. 00092 // <li> Constant single and double precision values. 00093 // <br>No exponent or exponent "e" results in single precision (Float), 00094 // while "d" results in double precision (Double). 00095 // <li> The imaginary part of a complex value can be given by the suffix "i". 00096 // A full complex number can be given by addition. E.g. "3+4i". 00097 // The complex is single (Complex) or double (DComplex) precision 00098 // depending on the constituting parts. 00099 // <li> The special constants pi and e can be given as a double precision 00100 // value by means of the functions pi() and e(). 00101 // <li> Boolean constants T and F can be given. 00102 // <li> A lot of functions are available. 00103 // They are the same as the ones supported by class 00104 // <linkto class=LatticeExprNode>LatticeExprNode</linkto>. 00105 // <li> Explicit conversion functions float, double, complex and dcomplex 00106 // are available. Conversions are automatically done where needed, 00107 // but for performance reasons it may sometimes be better to do 00108 // explicit conversions. See also below in the first example. 00109 // <li> An image can to be given using its file name. The file name 00110 // can contain environment variables and user home directories 00111 // using the standard UNIX syntax $ENVVAR and ~username. 00112 // There are 3 ways to specify a file name: 00113 // <ol> 00114 // <li> When the name contains no other special characters than 00115 // $, ~, and . it can be given as such. 00116 // <li> Backslashes can be used to escape individual special characters. 00117 // <li> The full name can be enclosed in quotes (single or double) 00118 // to escape the entire name. Adjacent quoted parts 00119 // are combined to one name, which can be used to use quotes 00120 // in the file name. 00121 // </ol> 00122 // Note that escaping has to be used too for the file name 00123 // T or F (otherwise it is the boolean constant). 00124 // E.g. 00125 // <srcblock> 00126 // image.data 00127 // "~noordam/data/image.data" 00128 // "~/image.data" 00129 // "$HOME/image.data" 00130 // $HOME\/image.data 00131 // "ab'c"'d"e' results in ab'cd"e 00132 // </srcblock> 00133 // Only input images with data type Float and Complex are supported, 00134 // because those data types are the only ones used so far. 00135 // Support of Bool, Double, and DComplex is very simple to build in. 00136 // The resulting lattice can be of type Bool, Float, Double, 00137 // Complex, and DComplex. 00138 // <li> An image can also be given by means of the <src>$n</src> notation, 00139 // where <src>n</src> is the sequence number in the 00140 // <src>tempLattices</src> argument given to the <src>command</src> 00141 // function. Note that the sequence numbers start counting at 1 00142 // (to be compliant with glish indexing). 00143 // <br>It can, for instance, be used to use non-persistent lattices 00144 // in an expression. 00145 // </ul> 00146 // When the expression is parsed, it is checked if the images and lattices 00147 // involved have conforming shapes and coordinates. Note, however, that 00148 // some functions (e.g. mean) reduce an image to a scalar. Such an image 00149 // can have a different shape and coordinates. 00150 // <p> 00151 // The data types of the images and constants involved can be different. 00152 // The data type of a subexpression is the common data type (e.g. 00153 // Float and Double result in Double; Complex and Double result in DComplex). 00154 // Automatic implicit conversions are done where needed. However, for 00155 // performance reasons it may sometimes be better to convert explicitly. 00156 // See below in the first example. 00157 // <p> 00158 // The expression evaluator (which is not part of the parser) evaluates 00159 // the expression in chunks to avoid having to keep large temporary 00160 // results. A scalar subexpression is evaluated only once to avoid 00161 // unnecessary (possibly expensive) calculations. 00162 // <p> 00163 // Some examples: 00164 // <dl> 00165 // <dt> <src> img1 + min(float(pi()), mean(img2)) </src> 00166 // <dd> Suppose img1 and img2 are images with single precision data. 00167 // They do not need to have conforming shapes and coordinates, 00168 // because only the mean of img2 is used. 00169 // <br>Note that pi is explicitly converted to single precision, 00170 // because pi() results in a Double. If that was not done, 00171 // the expression result would be a Double with the effect that 00172 // all data of img1 had to be converted to Double. 00173 // <dt> <src> min(img1, (min(img1)+max(img1))/2) </src> 00174 // <dd> This example shows that there are 2 min functions. One with a 00175 // single argument returning the minimum value of that image. 00176 // The other with 2 arguments returning a lattice containing 00177 // img1 data clipped at the value of the 2nd argument. 00178 // </dl> 00179 // </synopsis> 00180 00181 // <example> 00182 // <srcblock> 00183 // LatticeExpr<Double> expr ("a + sin(b)"); 00184 // ArrayLattice<Double> arr(expr.shape()); 00185 // arr.copyData (expr); 00186 // </srcblock> 00187 // Line 1 creates a LatticeExpr object for the given expression. Note that 00188 // <src>a</src> and <src>b</src> are names of lattice files (e.g. PagedImage). 00189 // <br> Line 2 creates an ArrayLattice with the same shape as the expression 00190 // (which is the shape of lattice a (and b)). 00191 // <br> Line 3 copies the result of the expression to the ArrayLattice. 00192 // </example> 00193 00194 // <motivation> 00195 // It is necessary to be able to give an image expression command in ASCII. 00196 // This can be used in glish to operate on lattices/images. 00197 // </motivation> 00198 00199 //# <todo asof="$DATE:$"> 00200 //# A List of bugs, limitations, extensions or planned refinements. 00201 //# </todo> 00202 00203 00204 class ImageExprParse 00205 { 00206 public: 00207 00208 // Parse the given command. 00209 // It will open all lattices needed. 00210 // It returns the resulting image expression. 00211 // <br>The <src>tempLattices/tempRegions</src> arguments make it possible 00212 // to use temporary lattices/images and regions in the expression by means 00213 // of the <src>$n</src> notation. 00214 // <br> If a directory name is given, it is used instead of the working 00215 // directory for relative file names. 00216 // <group> 00217 static LatticeExprNode command (const String& str, 00218 const String& dirName = String()); 00219 static LatticeExprNode command (const String& str, 00220 const Block<LatticeExprNode>& tempLattices, 00221 const PtrBlock<const ImageRegion*>& tempRegions, 00222 const String& dirName = String()); 00223 // </group> 00224 00225 // Construct a literal object for the given type. 00226 // <group> 00227 ImageExprParse (Bool value); 00228 ImageExprParse (Int value); 00229 ImageExprParse (Float value); 00230 ImageExprParse (Double value); 00231 ImageExprParse (const Complex& value); 00232 ImageExprParse (const DComplex& value); 00233 ImageExprParse (const Char* value); 00234 ImageExprParse (const String& value); 00235 // </group> 00236 00237 // Make a LatticeExprNode for a function. 00238 // <group> 00239 LatticeExprNode makeFuncNode () const; 00240 LatticeExprNode makeFuncNode (const LatticeExprNode& arg1) const; 00241 LatticeExprNode makeFuncNode (const LatticeExprNode& arg1, 00242 const LatticeExprNode& arg2) const; 00243 LatticeExprNode makeFuncNode (const LatticeExprNode& arg1, 00244 const LatticeExprNode& arg2, 00245 const LatticeExprNode& arg3) const; 00246 // </group> 00247 00248 // Make a LatticeExprNode object for the lattice or region name. 00249 LatticeExprNode makeLRNode() const; 00250 00251 // Make a LatticeExprNode object for the name of constant, lattice, 00252 // or region. 00253 LatticeExprNode makeLitLRNode() const; 00254 00255 // Make a LatticeExprNode object for the temporary region number. 00256 LatticeExprNode makeRegionNode() const; 00257 00258 // Make a LatticeExprNode object for the literal value. 00259 LatticeExprNode makeLiteralNode() const; 00260 00261 // Make a Slice object from 1-3 literals. 00262 // <group> 00263 static Slice* makeSlice (const ImageExprParse& start); 00264 static Slice* makeSlice (const ImageExprParse& start, 00265 const ImageExprParse& end); 00266 static Slice* makeSlice (const ImageExprParse& start, 00267 const ImageExprParse& end, 00268 const ImageExprParse& incr); 00269 // </group> 00270 00271 // Make a node for the INDEXIN function. 00272 static LatticeExprNode makeIndexinNode (const LatticeExprNode& axis, 00273 const vector<Slice>& slices); 00274 00275 // Make an array from a value list. 00276 static LatticeExprNode makeValueList 00277 (const Block<LatticeExprNode>& values); 00278 00279 // Make an IPosition containing the binning values. 00280 static IPosition makeBinning (const LatticeExprNode& values); 00281 00282 // Set the static node object (used by the .y file). 00283 static void setNode (const LatticeExprNode& node) 00284 { theirNode = node; } 00285 00286 // Keep track of the nodes allocated while parsing the expression. 00287 // <group> 00288 static void addNode (LatticeExprNode* node); 00289 static void addNode (ImageExprParse* node); 00290 static void deleteNodes(); 00291 // </group> 00292 00293 // A function to test addDir. It first sets the directory. 00294 static String setAddDir (const String& dirName, const String& fileName); 00295 00296 private: 00297 // If a directory was given, prepend it to the file name if relative. 00298 static String addDir (const String& fileName); 00299 00300 // Try if the name represent a lattice or image. 00301 // Return False if not. 00302 Bool tryLatticeNode (LatticeExprNode& node, const String& name) const; 00303 00304 // Make the node from the image name and a mask name. 00305 // The mask name can be NOMASK (case insensitive) meaning that no mask 00306 // is applied to the image. 00307 LatticeExprNode makeImageNode (const String& name, 00308 const String& mask) const; 00309 00310 // Callback function for RegionHandlerTable to get the table to be used. 00311 static Table& getRegionTable (void*, Bool); 00312 00313 // Callback function for RegionHandlerHDF5 to get the file to be used. 00314 static const CountedPtr<HDF5File>& getRegionHDF5 (void*); 00315 00316 //# A 'global' node object to hold the resulting expression. 00317 static LatticeExprNode theirNode; 00318 00319 DataType itsType; 00320 Bool itsBval; //# boolean literal 00321 Int itsIval; //# integer literal 00322 Float itsFval; //# Float literal 00323 Double itsDval; //# Double literal 00324 Complex itsCval; //# Complex literal 00325 DComplex itsDCval; //# DComplex literal 00326 String itsSval; //# lattice name; function name 00327 }; 00328 00329 00330 } //# NAMESPACE CASA - END 00331 00332 #endif