casacore
Loading...
Searching...
No Matches
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: casa-feedback@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#ifndef LATTICES_LELINTERFACE_H
27#define LATTICES_LELINTERFACE_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/lattices/LEL/LELAttribute.h>
32#include <casacore/casa/Arrays/IPosition.h>
33#include <casacore/casa/Utilities/DataType.h>
34#include <casacore/casa/IO/FileLocker.h>
35#include <memory>
36
37namespace casacore { // # NAMESPACE CASACORE - BEGIN
38
39// # Forward Declarations
40template <class T>
41class LELScalar;
42template <class T>
43class LELArray;
44template <class T>
45class LELArrayRef;
46class Slicer;
47
48// <summary> This base class provides the interface for Lattice expressions </summary>
49
50// <use visibility=local>
51
52// <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
53// </reviewed>
54
55// <prerequisite>
56// <li> <linkto class="Lattice"> Lattice</linkto>
57// <li> <linkto class="LatticeExpr"> LatticeExpr</linkto>
58// <li> <linkto class="LatticeExprNode"> LatticeExprNode</linkto>
59// </prerequisite>
60
61// <etymology>
62// The name means "Lattice Expression Language Interface".
63// This class provides the declaration for the interface for classes
64// that are to provide Lattice expression computational functionality
65// </etymology>
66
67// <synopsis>
68// This class is part of the Letter/envelope scheme which enables
69// the C++ programmer to write mathematical expressions involving
70// Lattices. The envelope class LatticeExpr invokes the bridge
71// class LatticeExprNode. LatticeExprNode activates the letter
72// classes which provide the real functionality.
73//
74// A description of the implementation details of these classes can
75// be found in
76// <a href="../notes/216.html">Note 216</a>
77//
78// This class, LELInterface, is the abstract base class for all of
79// the letter classes. Its purpose is to declare the interface inherited
80// by all of its derived classes which are used polymorphically. The derived
81// classes offer the functionality to create and evaluate the expression
82// tree that results from the compiler parsing the expression.
83// For example, these derived classes are activated by LatticeExprNode to
84// handle operations like reading pixels from a Lattice, applying binary
85// operations to Lattices, applying mathematical functions to Lattices
86// and so on.
87//
88// The heart of the interface is in the functions <src>eval</src> and
89// <src>getScalar</src>. These recursively evaluate the result of the
90// current expression when the result is either an array or a scalar,
91// respectively. The need for recursion can be understood with a simple
92// example.
93//
94// Consider an expression summing two Lattices such as "2*(b+c)".
95// The expression tree consists of nodes (leaves) that 1) get Lattice
96// pixels from the Lattice (expressions "b" and "c"), 2) add the pixel
97// values of the Lattices together (operator "+"), and 3) multiply a Lattice
98// by a scalar (operator "*"). At the top of the tree,
99// we have a scalar (2.0) and a Lattice (the
100// result of "b+c"). The top-of-the-tree expression has to multiply
101// them together. That's what the <src>eval</src> function for the "*"
102// operation needs to do. The key is that each of the "2.0" and
103// "b+c" are really Lattice expressions themselves and they can be evaluated.
104// So before the "*" <src>eval</src> function can
105// multiply its two expressions together, it must individually evaluate them.
106// Thus, it first calls the <src>getScalar</src> function of
107// the object housing the expression "2.0". This will in fact return
108// the scalar value "2.0". Then it calls
109// <src>eval</src> on the expression object housing "b+c". This
110// object in turn first calls <src>eval</src> on the left ("b") and
111// right ("c") expressions which results in the pixels for the Lattices
112// being returned. It then adds them together, returning the result
113// to the top of the tree where they are multiplied by 2. You can see
114// that since all these different expression objects call the
115// <src>eval</src> or <src>getScalar</src> function that they all inherit
116// from LELInterface. Indeed for our example above, the actual classes
117// involved are are LELLattice (get pixels from Lattice) and LELBinary
118// ("+" and "*" operators) which inherit from LELInterface. When these
119// objects are constructed, they work out whether the result of their
120// evaluation is a scalar or not. This is how the classes higher up
121// the tree know whether to call <src>eval</src> or <src>getScalar</src>.
122//
123// The results of the computations are either returned in the buffer in
124// the <src>eval</src> function or by value by <src>getScalar</src>
125//
126// The classes evaluate the expression for each specified Lattice
127// chunk (usually tile by tile). The <src>section</src> argument
128// in the <src>eval</src> function specifies the section of the
129// Lattice being evaluated. The absence of the <src>section</src>
130// argument in the <src>getScalar</src> function emphasises the
131// scalar nature; a scalar expression does not have a shape. For most
132// of the letter classes, the <src>section</src> argument is irrelevant;
133// the only one it really matters for is LELLattice which fetches the
134// pixels from the Lattice. The rest only care about the shape of the
135// buffer in the <src>eval</src> call.
136//
137// </synopsis>
138//
139// <motivation>
140// The many letter classes that actually do the computational work
141// are used polymorphically. Therefore, they must have a base
142// class declaring the interface.
143// </motivation>
144
145// <todo asof="1998/02/20">
146// </todo>
147
148template <class T>
150 public:
151 // Virtual destructor
152 virtual ~LELInterface();
153
154 // Evaluate the expression and fill the result array
155 virtual void eval(LELArray<T>& result, const Slicer& section) const = 0;
156 virtual void evalRef(LELArrayRef<T>& result, const Slicer& section) const;
157
158 // Get the result of a scalar subexpression.
159 virtual LELScalar<T> getScalar() const = 0;
160
161 // Get the result of an array subexpression.
162 // It does eval for the entire array.
163 // An exception is thrown if the shape of the subexpression is unknown.
165
166 // Do further preparations (e.g. optimization) on the expression.
167 // It returns True if the expression is an invalid scalar
168 // (i.e. with a False mask).
169 // That can happen if the expression has a component with an invalid
170 // scalar value (e.g. min(lattice) where lattice contains no valid elements).
171 virtual Bool prepareScalarExpr() = 0;
172
173 // Is the result of evaluating this expression a scalar ?
174 Bool isScalar() const { return attr_p.isScalar(); }
175
176 // Get the shape of the expression result.
177 const IPosition& shape() const { return attr_p.shape(); }
178
179 // Get expression attribute
180 const LELAttribute& getAttribute() const { return attr_p; }
181
182 // Get class name
183 virtual String className() const = 0;
184
185 // If the given expression is a valid scalar, replace it by its result.
186 // It returns False if the expression is no scalar or if the expression
187 // is an invalid scalar (i.e. with a False mask).
188 static Bool replaceScalarExpr(std::shared_ptr<LELInterface<T>>& expr);
189
190 // Handle locking/syncing of the parts of a lattice expression.
191 // <br>By default the functions do not do anything at all.
192 // lock() and hasLock return True.
193 // <group>
194 virtual Bool lock(FileLocker::LockType, uInt nattempts);
195 virtual void unlock();
197 virtual void resync();
198 // </group>
199
200 protected:
201 // Set the expression attributes of this object.
202 void setAttr(const LELAttribute& attrib);
203
204 private:
206};
207
208} // namespace casacore
209
210// # There is a problem in including LELInterface.tcc, because it needs
211// # LELUnary.h which in its turn includes LELInterface.h again.
212// # So in a source file including LELUnary.h, LELInterface::replaceScalarExpr
213// # fails to compile, because the LELUnary declarations are not seen yet.
214// # Therefore LELUnary.h is included here, while LELUnary.h includes
215// # LELInterface.tcc.
216#ifndef CASACORE_NO_AUTO_TEMPLATES
217#include <casacore/lattices/LEL/LELUnary.h>
218#endif // # CASACORE_NO_AUTO_TEMPLATES
219#endif
LockType
Define the possible lock types.
Definition FileLocker.h:89
This LEL class holds a possible referenced array with a mask.
Definition LELArray.h:119
const LELAttribute & getAttribute() const
Get expression attribute.
virtual Bool hasLock(FileLocker::LockType) const
const IPosition & shape() const
Get the shape of the expression result.
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.
void setAttr(const LELAttribute &attrib)
Set the expression attributes of this object.
virtual void unlock()
static Bool replaceScalarExpr(std::shared_ptr< LELInterface< T > > &expr)
If the given expression is a valid scalar, replace it by its result.
Bool isScalar() const
Is the result of evaluating this expression a scalar ?
virtual LELScalar< T > getScalar() const =0
Get the result of a scalar subexpression.
virtual Bool prepareScalarExpr()=0
Do further preparations (e.g.
LELArray< T > getArray() const
Get the result of an array subexpression.
String: the storage and methods of handling collections of characters.
Definition String.h:355
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
unsigned int uInt
Definition aipstype.h:49
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40