casacore
Loading...
Searching...
No Matches
MaskedLattice.h
Go to the documentation of this file.
1//# MaskedLattice.h: Abstract base class for array-like classes with masks
2//# Copyright (C) 1998,1999,2000
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_MASKEDLATTICE_H
27#define LATTICES_MASKEDLATTICE_H
28
29
30//# Includes
31#include <casacore/casa/aips.h>
32#include <casacore/lattices/Lattices/Lattice.h>
33
34namespace casacore { //# NAMESPACE CASACORE - BEGIN
35
36//# Forward Declarations
37class LatticeRegion;
38
39
40// <summary>
41// A templated, abstract base class for array-like objects with masks.
42// </summary>
43
44// <use visibility=export>
45
46// <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="dLattice.cc">
47// </reviewed>
48
49// <prerequisite>
50// <li> <linkto class="IPosition"> IPosition </linkto>
51// <li> Abstract Base class Inheritance - try "Advanced C++" by James
52// O. Coplien, Ch. 5.
53// </prerequisite>
54
55// <etymology>
56// Lattice: "A regular, periodic configuration of points, particles,
57// or objects, throughout an area of a space..." (American Heritage Directory)
58// This definition matches our own: an n-dimensional arrangement of items,
59// on regular orthogonal axes.
60// </etymology>
61
62// <synopsis>
63// This pure abstract base class defines the operations which may be performed
64// on any concrete class derived from it. It has only a few non-pure virtual
65// member functions.
66// The fundamental contribution of this class, therefore, is that it
67// defines the operations derived classes must provide:
68// <ul>
69// <li> how to extract a "slice" (or sub-array, or subsection) from
70// a Lattice.
71// <li> how to copy a slice in.
72// <li> how to get and put a single element
73// <li> how to apply a function to all elements
74// <li> various shape related functions.
75// </ul>
76// <note role=tip> Lattices are always zero origined. </note>
77// </synopsis>
78
79// <example>
80// Because Lattice is an abstract base class, an actual instance of this
81// class cannot be constructed. However the interface it defines can be used
82// inside a function. This is always recommended as it allows Functions
83// which have Lattices as arguments to work for any derived class.
84//
85// I will give a few examples here and then refer the reader to the
86// <linkto class="ArrayLattice">ArrayLattice</linkto> class (a memory resident
87// Lattice) and the <linkto class="PagedArray">PagedArray</linkto> class (a
88// disk based Lattice) which contain further examples with concrete
89// classes (rather than an abstract one). All the examples shown below are used
90// in the <src>dLattice.cc</src> demo program.
91//
92// <h4>Example 1:</h4>
93// This example calculates the mean of the Lattice. Because Lattices can be too
94// large to fit into physical memory it is not good enough to simply use
95// <src>getSlice</src> to read all the elements into an Array. Instead the
96// Lattice is accessed in chunks which can fit into memory (the size is
97// determined by the <src>maxPixels</src> and <src>niceCursorShape</src>
98// functions). The <src>LatticeIterator::cursor()</src> function then returns
99// each of these chunks as an Array and the standard Array based functions are
100// used to calculate the mean on each of these chunks. Functions like this one
101// are the recommended way to access Lattices as the
102// <linkto class="LatticeIterator">LatticeIterator</linkto> will correctly
103// setup any required caches.
104//
105// <srcblock>
106// Complex latMean(const Lattice<Complex>& lat) {
107// const uInt cursorSize = lat.advisedMaxPixels();
108// const IPosition cursorShape = lat.niceCursorShape(cursorSize);
109// const IPosition latticeShape = lat.shape();
110// Complex currentSum = 0.0f;
111// size_t nPixels = 0;
112// RO_LatticeIterator<Complex> iter(lat,
113// LatticeStepper(latticeShape, cursorShape));
114// for (iter.reset(); !iter.atEnd(); iter++){
115// currentSum += sum(iter.cursor());
116// nPixels += iter.cursor().nelements();
117// }
118// return currentSum/nPixels;
119// }
120// </srcblock>
121//
122// <h4>Example 2:</h4>
123// Sometimes it will be neccesary to access slices of a Lattice in a nearly
124// random way. Often this can be done using the subSection commands in the
125// <linkto class="LatticeStepper">LatticeStepper</linkto> class. But it is also
126// possible to use the getSlice and putSlice functions. The following example
127// does a two-dimensional Real to Complex Fourier transform. This example is
128// restricted to four-dimensional Arrays (unlike the previous example) and does
129// not set up any caches (caching is currently only used with PagedArrays). So
130// only use getSlice and putSlice when things cannot be done using
131// LatticeIterators.
132//
133// <srcblock>
134// void FFT2DReal2Complex(Lattice<Complex>& result,
135// const Lattice<Float>& input){
136// AlwaysAssert(input.ndim() == 4, AipsError);
137// const IPosition shape = input.shape();
138// const uInt nx = shape(0);
139// AlwaysAssert (nx > 1, AipsError);
140// const uInt ny = shape(1);
141// AlwaysAssert (ny > 1, AipsError);
142// const uInt npol = shape(2);
143// const uInt nchan = shape(3);
144// const IPosition resultShape = result.shape();
145// AlwaysAssert(resultShape.nelements() == 4, AipsError);
146// AlwaysAssert(resultShape(3) == nchan, AipsError);
147// AlwaysAssert(resultShape(2) == npol, AipsError);
148// AlwaysAssert(resultShape(1) == ny, AipsError);
149// AlwaysAssert(resultShape(0) == nx/2 + 1, AipsError);
150//
151// const IPosition inputSliceShape(4,nx,ny,1,1);
152// const IPosition resultSliceShape(4,nx/2+1,ny,1,1);
153// COWPtr<Array<Float>>
154// inputArrPtr(new Array<Float>(inputSliceShape.nonDegenerate()));
155// Array<Complex> resultArray(resultSliceShape.nonDegenerate());
156// FFTServer<Float, Complex> FFT2D(inputSliceShape.nonDegenerate());
157//
158// IPosition start(4,0);
159// Bool isARef;
160// for (uInt c = 0; c < nchan; c++){
161// for (uInt p = 0; p < npol; p++){
162// isARef = input.getSlice(inputArrPtr,
163// Slicer(start,inputSliceShape), True);
164// FFT2D.fft(resultArray, *inputArrPtr);
165// result.putSlice(resultArray, start);
166// start(2) += 1;
167// }
168// start(2) = 0;
169// start(3) += 1;
170// }
171// }
172// </srcblock>
173//
174// <h4>Example 3:</h4>
175// Occasionally you may want to access a few elements of a Lattice without
176// all the difficulty involved in setting up Iterators or calling getSlice
177// and putSlice. This is demonstrated in the example below and uses the
178// parenthesis operator, along with the LatticeValueRef companion
179// class. Using these functions to access many elements of a Lattice is not
180// recommended as this is the slowest access method.
181//
182// In this example an ideal point spread function will be inserted into an
183// empty Lattice. As with the previous examples all the action occurs
184// inside a function because Lattice is an interface (abstract) class.
185//
186// <srcblock>
187// void makePsf(Lattice<Float>& psf) {
188// const IPosition centrePos = psf.shape()/2;
189// psf.set(0.0f); // this sets all the elements to zero
190// // As it uses a LatticeIterator it is efficient
191// psf(centrePos) = 1; // This sets just the centre element to one
192// AlwaysAssert(near(psf(centrePos), 1.0f, 1E-6), AipsError);
193// AlwaysAssert(near(psf(centrePos*0), 0.0f, 1E-6), AipsError);
194// }
195// </srcblock>
196// </example>
197
198// <motivation>
199// Creating an abstract base class which provides a common interface between
200// memory and disk based arrays has a number of advantages.
201// <ul>
202// <li> It allows functions common to all arrays to be written independent
203// of the way the data is stored. This is illustrated in the three examples
204// above.
205// <li> It reduces the learning curve for new users who only have to become
206// familiar with one interface (ie. Lattice) rather than distinct interfaces
207// for different array types.
208// </ul>
209// </motivation>
210
211//# <todo asof="1996/07/01">
212//# <li>
213//# </todo>
214
215template <class T> class MaskedLattice : public Lattice<T>
216{
217 //# Make members of parent class known.
218public:
219 using Lattice<T>::ndim;
220 using Lattice<T>::shape;
221
222public:
223 // Default constructor.
226
227 // Copy constructor.
229
230 // a virtual destructor is needed so that it will use the actual destructor
231 // in the derived class
232 virtual ~MaskedLattice();
233
234 // Make a copy of the object (reference semantics).
235 // <group>
236 virtual MaskedLattice<T>* cloneML() const = 0;
237 virtual Lattice<T>* clone() const;
238 // </group>
239
240 // Has the object really a mask?
241 // The default implementation returns True if the MaskedLattice has
242 // a region with a mask.
243 virtual Bool isMasked() const;
244
245 // Does the lattice have a pixelmask?
246 // The default implementation returns False.
247 virtual Bool hasPixelMask() const;
248
249 // Get access to the pixelmask.
250 // An exception is thrown if the lattice does not have a pixelmask.
251 // <group>
252 virtual const Lattice<Bool>& pixelMask() const;
254 // </group>
255
256 // Get the region used.
257 // This is in principle the region pointed to by <src>getRegionPtr</src>.
258 // However, if that pointer is 0, it returns a LatticeRegion for the
259 // full image.
260 const LatticeRegion& region() const;
261
262 // Get the mask or a slice from the mask.
263 // This is the mask formed by combination of the possible pixelmask of the
264 // lattice and the possible mask of the region taken from the lattice.
265 // If there is no mask, it still works fine.
266 // In that case it sizes the buffer correctly and sets it to True.
267 // <group>
269 Bool removeDegenerateAxes=False) const;
270 Bool getMaskSlice (COWPtr<Array<Bool>>& buffer, const Slicer& section,
271 Bool removeDegenerateAxes=False) const;
272 Bool getMaskSlice (COWPtr<Array<Bool>>& buffer, const IPosition& start,
273 const IPosition& shape,
274 Bool removeDegenerateAxes=False) const;
275 Bool getMaskSlice (COWPtr<Array<Bool>>& buffer, const IPosition& start,
276 const IPosition& shape, const IPosition& stride,
277 Bool removeDegenerateAxes=False) const;
279 Bool removeDegenerateAxes=False);
280 Bool getMaskSlice (Array<Bool>& buffer, const Slicer& section,
281 Bool removeDegenerateAxes=False);
282 Bool getMaskSlice (Array<Bool>& buffer, const IPosition& start,
283 const IPosition& shape,
284 Bool removeDegenerateAxes=False);
285 Bool getMaskSlice (Array<Bool>& buffer, const IPosition& start,
286 const IPosition& shape, const IPosition& stride,
287 Bool removeDegenerateAxes=False);
288 Array<Bool> getMask (Bool removeDegenerateAxes=False) const;
290 Bool removeDegenerateAxes=False) const;
292 const IPosition& shape,
293 Bool removeDegenerateAxes=False) const;
295 const IPosition& shape, const IPosition& stride,
296 Bool removeDegenerateAxes=False) const;
297 // </group>
298
299 // The function (in the derived classes) doing the actual work.
300 // These functions are public, so they can be used internally in the
301 // various Lattice classes.
302 // <br>However, doGetMaskSlice does not call Slicer::inferShapeFromSource
303 // to fill in possible unspecified section values. Therefore one
304 // should normally use one of the getMask(Slice) functions. doGetMaskSlice
305 // should be used with care and only when performance is an issue.
306 // <br>The default implementation gets the mask from the region
307 // and fills the buffer with True values if there is no region.
308 virtual Bool doGetMaskSlice (Array<Bool>& buffer, const Slicer& section);
309
310protected:
311 // Assignment can only be used by derived classes.
313
314 // Get a pointer to the region used.
315 // It can return 0 meaning that the MaskedLattice is the full lattice.
316 virtual const LatticeRegion* getRegionPtr() const = 0;
317
318private:
320};
321
322
323
324} //# NAMESPACE CASACORE - END
325
326#ifndef CASACORE_NO_AUTO_TEMPLATES
327#include <casacore/lattices/Lattices/MaskedLattice.tcc>
328#endif //# CASACORE_NO_AUTO_TEMPLATES
329#endif
virtual IPosition shape() const =0
Return the shape of the Lattice including all degenerate axes (ie.
virtual uInt ndim() const
Return the number of axes in this Lattice.
Lattice()
Define default constructor to satisfy compiler.
Definition Lattice.h:405
Bool getMask(COWPtr< Array< Bool > > &buffer, Bool removeDegenerateAxes=False) const
Get the mask or a slice from the mask.
MaskedLattice< T > & operator=(const MaskedLattice< T > &)
Assignment can only be used by derived classes.
MaskedLattice()
Default constructor.
Array< Bool > getMaskSlice(const IPosition &start, const IPosition &shape, Bool removeDegenerateAxes=False) const
Array< Bool > getMaskSlice(const Slicer &section, Bool removeDegenerateAxes=False) const
Bool getMaskSlice(COWPtr< Array< Bool > > &buffer, const Slicer &section, Bool removeDegenerateAxes=False) const
virtual Bool doGetMaskSlice(Array< Bool > &buffer, const Slicer &section)
The function (in the derived classes) doing the actual work.
virtual Lattice< Bool > & pixelMask()
Array< Bool > getMask(Bool removeDegenerateAxes=False) const
Bool getMaskSlice(COWPtr< Array< Bool > > &buffer, const IPosition &start, const IPosition &shape, Bool removeDegenerateAxes=False) const
virtual const LatticeRegion * getRegionPtr() const =0
Get a pointer to the region used.
Bool getMaskSlice(Array< Bool > &buffer, const IPosition &start, const IPosition &shape, const IPosition &stride, Bool removeDegenerateAxes=False)
virtual MaskedLattice< T > * cloneML() const =0
Make a copy of the object (reference semantics).
virtual Lattice< T > * clone() const
Make a copy of the derived object (reference semantics).
Bool getMaskSlice(Array< Bool > &buffer, const IPosition &start, const IPosition &shape, Bool removeDegenerateAxes=False)
const LatticeRegion & region() const
Get the region used.
MaskedLattice(const MaskedLattice< T > &)
Copy constructor.
virtual Bool hasPixelMask() const
Does the lattice have a pixelmask? The default implementation returns False.
virtual ~MaskedLattice()
a virtual destructor is needed so that it will use the actual destructor in the derived class
Array< Bool > getMaskSlice(const IPosition &start, const IPosition &shape, const IPosition &stride, Bool removeDegenerateAxes=False) const
virtual Bool isMasked() const
Has the object really a mask? The default implementation returns True if the MaskedLattice has a regi...
virtual const Lattice< Bool > & pixelMask() const
Get access to the pixelmask.
Bool getMaskSlice(Array< Bool > &buffer, const Slicer &section, Bool removeDegenerateAxes=False)
LatticeRegion * itsDefRegPtr
Bool getMaskSlice(COWPtr< Array< Bool > > &buffer, const IPosition &start, const IPosition &shape, const IPosition &stride, Bool removeDegenerateAxes=False) const
Bool getMask(Array< Bool > &buffer, Bool removeDegenerateAxes=False)
this file contains all the compiler specific defines
Definition mainpage.dox:28
const Bool False
Definition aipstype.h:42
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40