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