casacore
LELInterface.h
Go to the documentation of this file.
1 //# LELInterface.h: Abstract base class for lattice expressions
2 //# Copyright (C) 1997,1998,1999,2000,2003
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef LATTICES_LELINTERFACE_H
29 #define LATTICES_LELINTERFACE_H
30 
31 
32 //# Includes
33 #include <casacore/casa/aips.h>
34 #include <casacore/lattices/LEL/LELAttribute.h>
35 #include <casacore/casa/Arrays/IPosition.h>
36 #include <casacore/casa/Utilities/CountedPtr.h>
37 #include <casacore/casa/Utilities/DataType.h>
38 #include <casacore/casa/IO/FileLocker.h>
39 
40 namespace casacore { //# NAMESPACE CASACORE - BEGIN
41 
42 //# Forward Declarations
43 template <class T> class LELScalar;
44 template <class T> class LELArray;
45 template <class T> class LELArrayRef;
46 class Slicer;
47 
48 
49 // <summary> This base class provides the interface for Lattice expressions </summary>
50 
51 // <use visibility=local>
52 
53 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
54 // </reviewed>
55 
56 // <prerequisite>
57 // <li> <linkto class="Lattice"> Lattice</linkto>
58 // <li> <linkto class="LatticeExpr"> LatticeExpr</linkto>
59 // <li> <linkto class="LatticeExprNode"> LatticeExprNode</linkto>
60 // </prerequisite>
61 
62 // <etymology>
63 // The name means "Lattice Expression Language Interface".
64 // This class provides the declaration for the interface for classes
65 // that are to provide Lattice expression computational functionality
66 // </etymology>
67 
68 // <synopsis>
69 // This class is part of the Letter/envelope scheme which enables
70 // the C++ programmer to write mathematical expressions involving
71 // Lattices. The envelope class LatticeExpr invokes the bridge
72 // class LatticeExprNode. LatticeExprNode activates the letter
73 // classes which provide the real functionality.
74 //
75 // A description of the implementation details of these classes can
76 // be found in
77 // <a href="../notes/216.html">Note 216</a>
78 //
79 // This class, LELInterface, is the abstract base class for all of
80 // the letter classes. Its purpose is to declare the interface inherited
81 // by all of its derived classes which are used polymorphically. The derived
82 // classes offer the functionality to create and evaluate the expression
83 // tree that results from the compiler parsing the expression.
84 // For example, these derived classes are activated by LatticeExprNode to
85 // handle operations like reading pixels from a Lattice, applying binary
86 // operations to Lattices, applying mathematical functions to Lattices
87 // and so on.
88 //
89 // The heart of the interface is in the functions <src>eval</src> and
90 // <src>getScalar</src>. These recursively evaluate the result of the
91 // current expression when the result is either an array or a scalar,
92 // respectively. The need for recursion can be understood with a simple
93 // example.
94 //
95 // Consider an expression summing two Lattices such as "2*(b+c)".
96 // The expression tree consists of nodes (leaves) that 1) get Lattice
97 // pixels from the Lattice (expressions "b" and "c"), 2) add the pixel
98 // values of the Lattices together (operator "+"), and 3) multiply a Lattice
99 // by a scalar (operator "*"). At the top of the tree,
100 // we have a scalar (2.0) and a Lattice (the
101 // result of "b+c"). The top-of-the-tree expression has to multiply
102 // them together. That's what the <src>eval</src> function for the "*"
103 // operation needs to do. The key is that each of the "2.0" and
104 // "b+c" are really Lattice expressions themselves and they can be evaluated.
105 // So before the "*" <src>eval</src> function can
106 // multiply its two expressions together, it must individually evaluate them.
107 // Thus, it first calls the <src>getScalar</src> function of
108 // the object housing the expression "2.0". This will in fact return
109 // the scalar value "2.0". Then it calls
110 // <src>eval</src> on the expression object housing "b+c". This
111 // object in turn first calls <src>eval</src> on the left ("b") and
112 // right ("c") expressions which results in the pixels for the Lattices
113 // being returned. It then adds them together, returning the result
114 // to the top of the tree where they are multiplied by 2. You can see
115 // that since all these different expression objects call the
116 // <src>eval</src> or <src>getScalar</src> function that they all inherit
117 // from LELInterface. Indeed for our example above, the actual classes
118 // involved are are LELLattice (get pixels from Lattice) and LELBinary
119 // ("+" and "*" operators) which inherit from LELInterface. When these
120 // objects are constructed, they work out whether the result of their
121 // evaluation is a scalar or not. This is how the classes higher up
122 // the tree know whether to call <src>eval</src> or <src>getScalar</src>.
123 //
124 // The results of the computations are either returned in the buffer in
125 // the <src>eval</src> function or by value by <src>getScalar</src>
126 //
127 // The classes evaluate the expression for each specified Lattice
128 // chunk (usually tile by tile). The <src>section</src> argument
129 // in the <src>eval</src> function specifies the section of the
130 // Lattice being evaluated. The absence of the <src>section</src>
131 // argument in the <src>getScalar</src> function emphasises the
132 // scalar nature; a scalar expression does not have a shape. For most
133 // of the letter classes, the <src>section</src> argument is irrelevant;
134 // the only one it really matters for is LELLattice which fetches the
135 // pixels from the Lattice. The rest only care about the shape of the
136 // buffer in the <src>eval</src> call.
137 //
138 // </synopsis>
139 //
140 // <motivation>
141 // The many letter classes that actually do the computational work
142 // are used polymorphically. Therefore, they must have a base
143 // class declaring the interface.
144 // </motivation>
145 
146 // <todo asof="1998/02/20">
147 // </todo>
148 
149 
150 template <class T> class LELInterface
151 {
152 public:
153 
154 // Virtual destructor
155  virtual ~LELInterface();
156 
157 // Evaluate the expression and fill the result array
158  virtual void eval (LELArray<T>& result,
159  const Slicer& section) const = 0;
160  virtual void evalRef (LELArrayRef<T>& result,
161  const Slicer& section) const;
162 
163 // Get the result of a scalar subexpression.
164  virtual LELScalar<T> getScalar() const = 0;
165 
166 // Get the result of an array subexpression.
167 // It does eval for the entire array.
168 // An exception is thrown if the shape of the subexpression is unknown.
170 
171 // Do further preparations (e.g. optimization) on the expression.
172 // It returns True if the expression is an invalid scalar
173 // (i.e. with a False mask).
174 // That can happen if the expression has a component with an invalid
175 // scalar value (e.g. min(lattice) where lattice contains no valid elements).
176  virtual Bool prepareScalarExpr() = 0;
177 
178 // Is the result of evaluating this expression a scalar ?
179  Bool isScalar() const {return attr_p.isScalar();}
180 
181 // Get the shape of the expression result.
182  const IPosition& shape() const {return attr_p.shape();}
183 
184 // Get expression attribute
185  const LELAttribute& getAttribute() const {return attr_p;}
186 
187 // Get class name
188  virtual String className() const = 0;
189 
190 // If the given expression is a valid scalar, replace it by its result.
191 // It returns False if the expression is no scalar or if the expression
192 // is an invalid scalar (i.e. with a False mask).
194 
195  // Handle locking/syncing of the parts of a lattice expression.
196  // <br>By default the functions do not do anything at all.
197  // lock() and hasLock return True.
198  // <group>
199  virtual Bool lock (FileLocker::LockType, uInt nattempts);
200  virtual void unlock();
202  virtual void resync();
203  // </group>
204 
205 protected:
206 // Set the expression attributes of this object.
207  void setAttr(const LELAttribute& attrib);
208 
209 private:
211 };
212 
213 
214 
215 } //# NAMESPACE CASACORE - END
216 
217 //# There is a problem in including LELInterface.tcc, because it needs
218 //# LELUnary.h which in its turn includes LELInterface.h again.
219 //# So in a source file including LELUnary.h, LELInterface::replaceScalarExpr
220 //# fails to compile, because the LELUnary declarations are not seen yet.
221 //# Therefore LELUnary.h is included here, while LELUnary.h includes
222 //# LELInterface.tcc.
223 #ifndef CASACORE_NO_AUTO_TEMPLATES
224 #include <casacore/lattices/LEL/LELUnary.h>
225 #endif //# CASACORE_NO_AUTO_TEMPLATES
226 #endif
Referenced counted pointer for constant data.
Definition: CountedPtr.h:81
LockType
Define the possible lock types.
Definition: FileLocker.h:95
This LEL class holds a possible referenced array with a mask.
Definition: LELArray.h:133
Bool isScalar() const
Is expression a scalar?
Definition: LELAttribute.h:117
const IPosition & shape() const
What is the shape of the expression?
Definition: LELAttribute.h:129
virtual Bool hasLock(FileLocker::LockType) const
const LELAttribute & getAttribute() const
Get expression attribute.
Definition: LELInterface.h:185
virtual LELScalar< T > getScalar() const =0
Get the result of a scalar subexpression.
virtual ~LELInterface()
Virtual destructor.
virtual void resync()
virtual void eval(LELArray< T > &result, const Slicer &section) const =0
Evaluate the expression and fill the result array.
virtual void evalRef(LELArrayRef< T > &result, const Slicer &section) const
virtual String className() const =0
Get class name.
virtual Bool lock(FileLocker::LockType, uInt nattempts)
Handle locking/syncing of the parts of a lattice expression.
const IPosition & shape() const
Get the shape of the expression result.
Definition: LELInterface.h:182
void setAttr(const LELAttribute &attrib)
Set the expression attributes of this object.
virtual void unlock()
LELArray< T > getArray() const
Get the result of an array subexpression.
Bool isScalar() const
Is the result of evaluating this expression a scalar ?
Definition: LELInterface.h:179
virtual Bool prepareScalarExpr()=0
Do further preparations (e.g.
static Bool replaceScalarExpr(CountedPtr< LELInterface< T > > &expr)
If the given expression is a valid scalar, replace it by its result.
String: the storage and methods of handling collections of characters.
Definition: String.h:225
this file contains all the compiler specific defines
Definition: mainpage.dox:28
unsigned int uInt
Definition: aipstype.h:51
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42