casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ImageExprParse.h
Go to the documentation of this file.
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