casacore
Loading...
Searching...
No Matches
Cube.h
Go to the documentation of this file.
1// # Cube.h: A 3-D Specialization of the Array Class
2// # Copyright (C) 1993,1994,1995,1996,1999,2000,2001,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 CASA_CUBE_2_H
27#define CASA_CUBE_2_H
28
29#include "Array.h"
30
31namespace casacore { // #Begin casa namespace
32
33// <summary> A 3-D Specialization of the Array class </summary>
34// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
35// </reviewed>
36//
37// Cube objects are three-dimensional specializations (e.g., more convenient
38// and efficient indexing) of the general Array class. You might also want
39// to look at the Array documentation to see inherited functionality.
40//
41// Generally the member functions of Array are also available in
42// Cube versions which take a pair of integers where the array
43// needs an IPosition. Since the Cube
44// is three-dimensional, the IPositions are overkill, although you may
45// use those versions if you want to.
46// <srcblock>
47// Cube<int> ci(100,100,100); // Shape is 100x100
48// ci.resize(50,50,50); // Shape now 50x50
49// </srcblock>
50//
51// Slices may be taken with the Slice class. To take a slice, one "indexes"
52// with one Slice(start, length, inc) for each axis, where end and inc
53// are optional. Additionally, there is an xyPlane()
54// member function which return a Matrix which corresponds to some plane:
55// <srcblock>
56// Cube<float> cube(10,20,30);
57// for(size_t i=0; i < 30; i++) {
58// cube.xyPlane(i) = i; // Set every 10x20 plane to its "height"
59// }
60// </srcblock>
61//
62// Element-by-element arithmetic and logical operations are available (in
63// aips/ArrayMath.h and aips/ArrayLogical.h).
64//
65// As with the Arrays, if the preprocessor symbol AIPS_DEBUG is
66// defined at compile time invariants will be checked on entry to most
67// member functions. Additionally, if AIPS_ARRAY_INDEX_CHECK is defined
68// index operations will be bounds-checked. Neither of these should
69// be defined for production code.
70
71template <typename T>
72class Cube : public Array<T> {
73 public:
74 // A Cube of length zero in each dimension; zero origin.
76
77 // A l1xl2xl3 sized cube.
78 // Fill it with the initial value.
79 Cube(size_t l1, size_t l2, size_t l3, const T &initialValue = T());
80
81 // An uninitialized l1xl2xl3 sized cube.
82 Cube(size_t l1, size_t l2, size_t l3, typename Array<T>::uninitializedType);
83
84 // A Cube where the shape ("len") is defined with IPositions.
85 // Fill it with the initial value.
86 Cube(const IPosition &length, const T &initialValue = T());
87
88 // An uninitialized Cube where the shape ("len") is defined with IPositions.
90
91 // The copy constructor uses reference semantics.
92 Cube(const Cube<T> &);
94
95 // Construct a cube by reference from "other". "other must have
96 // ndim() of 3 or less. The warning which applies to the copy constructor
97 // is also valid here.
98 Cube(const Array<T> &);
100
101 // Create an Cube of a given shape from a pointer.
103 // Create an Cube of a given shape from a pointer. Because the pointer
104 // is const, a copy is always made.
105 Cube(const IPosition &shape, const T *storage);
106
107 // Resize to the given shape.
108 // Resize without argument is equal to resize(0,0,0).
109 // <group>
110 using Array<T>::resize;
111 void resize(size_t nx, size_t ny, size_t nz, bool copyValues = false);
112 // </group>
113
114 // Copy the values from other to this cube. If this cube has zero
115 // elements then it will resize to be the same shape as other; otherwise
116 // other must conform to this.
117 // Note that the assign function can be used to assign a
118 // non-conforming cube.
119 // <group>
120 Cube<T> &operator=(const Cube<T> &source) {
121 Array<T>::operator=(source);
122 return *this;
123 }
125 Array<T>::operator=(std::move(source));
126 return *this;
127 }
128
129 Cube<T> &operator=(const Array<T> &source) {
130 // TODO is it highly confusing that operator= is specialized for Cube, e.g.
131 // this is allowed:
132 // Cube<int> cube(5,1,1);
133 // Vector<int> v(5,0);
134 // cube = v;
135 // But this is not:
136 // Array arr(IPosition{5,1,1});
137 // Vector<int> v(5,0);
138 // arr = v;
139 // If it should be allowed to assign from dim(5,1,1) to dim(5), this should
140 // be supported already by the Array class so that the semantics are the
141 // same!
142
143 if (source.ndim() == 3) {
144 Array<T>::operator=(source);
145 } else {
146 // This might work if a.ndim == 1 or 2
147 (*this) = Cube<T>(source);
148 }
149 return *this;
150 }
151
153 if (source.ndim() == 3) {
154 Array<T>::operator=(std::move(source));
155 } else {
156 (*this) = Cube<T>(std::move(source));
157 }
158 return *this;
159 }
160
161 // </group>
162
163 // Copy val into every element of this cube; i.e. behaves as if
164 // val were a constant conformant cube.
165 Array<T> &operator=(const T &val) { return Array<T>::operator=(val); }
166
167 // Copy to this those values in marray whose corresponding elements
168 // in marray's mask are true.
169
170 // TODO
171 // Cube<T> &operator= (const MaskedArray<T> &marray)
172 // { Array<T> (*this) = marray; return *this; }
173
174 // Single-pixel addressing. If AIPS_ARRAY_INDEX_CHECK is defined,
175 // bounds checking is performed.
176 // <group>
177 T &operator()(const IPosition &i) { return Array<T>::operator()(i); }
178 const T &operator()(const IPosition &i) const { return Array<T>::operator()(i); }
179
180 T &operator()(size_t i1, size_t i2, size_t i3) { return this->begin_p[index(i1, i2, i3)]; }
181
182 const T &operator()(size_t i1, size_t i2, size_t i3) const {
183 return this->begin_p[index(i1, i2, i3)];
184 }
185 // </group>
186
187 // Take a slice of this cube. Slices are always indexed starting
188 // at zero. This uses reference semantics, i.e. changing a value
189 // in the slice changes the original.
190 // <srcblock>
191 // Cube<double> vd(100,100,100);
192 // //...
193 // vd(Slice(0,10),Slice(10,10,Slice(0,10))) = -1.0; // sub-cube set to -1.0
194 // </srcblock>
195 // <group>
196 Cube<T> operator()(const Slice &sliceX, const Slice &sliceY, const Slice &sliceZ);
197 const Cube<T> operator()(const Slice &sliceX, const Slice &sliceY, const Slice &sliceZ) const;
198 // </group>
199
200 // Slice using IPositions. Required to be defined, otherwise the base
201 // class versions are hidden.
202 // <group>
203 Array<T> operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr) {
204 return Array<T>::operator()(blc, trc, incr);
205 }
206 const Array<T> operator()(const IPosition &blc, const IPosition &trc,
207 const IPosition &incr) const {
208 return Array<T>::operator()(blc, trc, incr);
209 }
210 Array<T> operator()(const IPosition &blc, const IPosition &trc) {
211 return Array<T>::operator()(blc, trc);
212 }
213 const Array<T> operator()(const IPosition &blc, const IPosition &trc) const {
214 return Array<T>::operator()(blc, trc);
215 }
216 Array<T> operator()(const Slicer &slicer) { return Array<T>::operator()(slicer); }
217 const Array<T> operator()(const Slicer &slicer) const { return Array<T>::operator()(slicer); }
218 // </group>
219
220 // The array is masked by the input LogicalArray.
221 // This mask must conform to the array.
222 // <group>
223
224 // Return a MaskedArray.
227 }
228
229 // Return a MaskedArray.
231
232 // </group>
233
234 // The array is masked by the input MaskedLogicalArray.
235 // The mask is effectively the AND of the internal LogicalArray
236 // and the internal mask of the MaskedLogicalArray.
237 // The MaskedLogicalArray must conform to the array.
238 // <group>
239
240 // Return a MaskedArray.
244
245 // Return a MaskedArray.
247
248 // </group>
249
250 // Extract a plane as a matrix referencing the original data.
251 // Of course you could also use a Matrix
252 // iterator on the cube.
253 // <group>
254 Matrix<T> xyPlane(size_t zplane);
255 const Matrix<T> xyPlane(size_t zplane) const;
256 Matrix<T> xzPlane(size_t yplane);
257 const Matrix<T> xzPlane(size_t yplane) const;
258 Matrix<T> yzPlane(size_t xplane);
259 const Matrix<T> yzPlane(size_t xplane) const;
260 // </group>
261
262 // The length of each axis of the cube.
263 const IPosition &shape() const { return this->length_p; }
264 void shape(int &s1, int &s2, int &s3) const {
265 s1 = this->length_p(0);
266 s2 = this->length_p(1);
267 s3 = this->length_p(2);
268 }
269
270 // The number of rows in the Cube, i.e. the length of the first axis.
271 size_t nrow() const { return this->length_p(0); }
272
273 // The number of columns in the Cube, i.e. the length of the 2nd axis.
274 size_t ncolumn() const { return this->length_p(1); }
275
276 // The number of planes in the Cube, i.e. the length of the 3rd axis.
277 size_t nplane() const { return this->length_p(2); }
278
279 // Checks that the cube is consistent (invariants check out).
280 virtual bool ok() const override;
281
282 protected:
283 virtual void preTakeStorage(const IPosition &shape) override;
284 // Remove the degenerate axes from other and store result in this cube.
285 // An exception is thrown if removing degenerate axes does not result
286 // in a cube.
287 virtual void doNonDegenerate(const Array<T> &other, const IPosition &ignoreAxes) override;
288
289 size_t fixedDimensionality() const override { return 3; }
290
291 private:
292 // Cached constants to improve indexing.
293 // size_t xinc_p, yinc_p, zinc_p;
294 // Helper fn to calculate the indexing constants.
295 // void makeIndexingConstants();
296 size_t xinc() const { return this->inc_p(0); }
297 size_t yinc() const { return this->inc_p(1) * this->originalLength_p(0); }
298 size_t zinc() const {
299 return this->inc_p(2) * this->originalLength_p(0) * this->originalLength_p(1);
300 }
301 size_t index(size_t i1, size_t i2, size_t i3) const {
302 return xinc() * i1 +
303 this->originalLength_p(0) *
304 (this->inc_p(1) * i2 + this->inc_p(2) * this->originalLength_p(1) * i3);
305 }
306 size_t index_continuous(size_t i1, size_t i2, size_t i3) const {
307 return i1 + this->originalLength_p(0) *
308 (this->inc_p(1) * i2 + this->inc_p(2) * this->originalLength_p(1) * i3);
309 }
310};
311
312} // namespace casacore
313
314#include "Cube.tcc"
315
316#endif
size_t ndim() const
The dimensionality of this array.
Definition ArrayBase.h:94
IPosition originalLength_p
Definition ArrayBase.h:256
IPosition length_p
Used to hold the shape, increment into the underlying storage and originalLength of the array.
Definition ArrayBase.h:256
Array< T > & operator=(const Array< T > &other)
TODO we should change the semantics.
Definition Array.h:292
LogicalArrayElem * begin_p
Definition Array.h:920
T & operator()(const IPosition &)
Access a single element of the array.
Array()
Result has dimensionality of zero, and nelements is zero.
Cube(size_t l1, size_t l2, size_t l3, const T &initialValue=T())
A l1xl2xl3 sized cube.
const Matrix< T > xyPlane(size_t zplane) const
Cube(const IPosition &length, const T &initialValue=T())
A Cube where the shape ("len") is defined with IPositions.
void resize(size_t nx, size_t ny, size_t nz, bool copyValues=false)
T & operator()(size_t i1, size_t i2, size_t i3)
Definition Cube.h:180
MaskedArray< T > operator()(const LogicalArray &mask)
Return a MaskedArray.
Definition Cube.h:230
const Array< T > operator()(const IPosition &blc, const IPosition &trc) const
Definition Cube.h:213
size_t yinc() const
Definition Cube.h:297
Matrix< T > xyPlane(size_t zplane)
Extract a plane as a matrix referencing the original data.
virtual void doNonDegenerate(const Array< T > &other, const IPosition &ignoreAxes) override
Remove the degenerate axes from other and store result in this cube.
Array< T > operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr)
Slice using IPositions.
Definition Cube.h:203
const MaskedArray< T > operator()(const LogicalArray &mask) const
The array is masked by the input LogicalArray.
Definition Cube.h:225
Cube< T > & operator=(const Cube< T > &source)
Copy the values from other to this cube.
Definition Cube.h:120
Cube(const Array< T > &)
Construct a cube by reference from "other".
const Array< T > operator()(const Slicer &slicer) const
Definition Cube.h:217
size_t fixedDimensionality() const override
Subclasses can return their dimensionality.
Definition Cube.h:289
const MaskedArray< T > operator()(const MaskedLogicalArray &mask) const
The array is masked by the input MaskedLogicalArray.
Definition Cube.h:241
Cube< T > operator()(const Slice &sliceX, const Slice &sliceY, const Slice &sliceZ)
Take a slice of this cube.
MaskedArray< T > operator()(const MaskedLogicalArray &mask)
Return a MaskedArray.
Definition Cube.h:246
Cube(const IPosition &shape, T *storage, StorageInitPolicy policy=COPY)
Create an Cube of a given shape from a pointer.
Cube(size_t l1, size_t l2, size_t l3, typename Array< T >::uninitializedType)
An uninitialized l1xl2xl3 sized cube.
Cube(const IPosition &length, typename Array< T >::uninitializedType)
An uninitialized Cube where the shape ("len") is defined with IPositions.
size_t nplane() const
The number of planes in the Cube, i.e.
Definition Cube.h:277
Cube(Array< T > &&)
const T & operator()(const IPosition &i) const
Definition Cube.h:178
Matrix< T > xzPlane(size_t yplane)
size_t ncolumn() const
The number of columns in the Cube, i.e.
Definition Cube.h:274
const Matrix< T > yzPlane(size_t xplane) const
size_t xinc() const
Cached constants to improve indexing.
Definition Cube.h:296
void shape(int &s1, int &s2, int &s3) const
Definition Cube.h:264
Cube(const IPosition &shape, const T *storage)
Create an Cube of a given shape from a pointer.
Cube< T > & operator=(Array< T > &&source)
Definition Cube.h:152
size_t index(size_t i1, size_t i2, size_t i3) const
Definition Cube.h:301
Cube(const Cube< T > &)
The copy constructor uses reference semantics.
Array< T > & operator=(const T &val)
Copy val into every element of this cube; i.e.
Definition Cube.h:165
Array< T > operator()(const Slicer &slicer)
Definition Cube.h:216
virtual bool ok() const override
Checks that the cube is consistent (invariants check out).
const Cube< T > operator()(const Slice &sliceX, const Slice &sliceY, const Slice &sliceZ) const
const Matrix< T > xzPlane(size_t yplane) const
Array< T > operator()(const IPosition &blc, const IPosition &trc)
Definition Cube.h:210
const T & operator()(size_t i1, size_t i2, size_t i3) const
Definition Cube.h:182
size_t nrow() const
The number of rows in the Cube, i.e.
Definition Cube.h:271
const IPosition & shape() const
Definition Cube.h:263
Cube< T > & operator=(const Array< T > &source)
Definition Cube.h:129
T & operator()(const IPosition &i)
Copy to this those values in marray whose corresponding elements in marray's mask are true.
Definition Cube.h:177
size_t index_continuous(size_t i1, size_t i2, size_t i3) const
Definition Cube.h:306
Cube< T > & operator=(Cube< T > &&source)
Definition Cube.h:124
virtual void preTakeStorage(const IPosition &shape) override
pre/post processing hook of takeStorage() for subclasses.
Cube()
A Cube of length zero in each dimension; zero origin.
Cube(Cube< T > &&)
Matrix< T > yzPlane(size_t xplane)
const Array< T > operator()(const IPosition &blc, const IPosition &trc, const IPosition &incr) const
Definition Cube.h:206
size_t zinc() const
Definition Cube.h:298
StorageInitPolicy
Definition ArrayBase.h:48
@ COPY
COPY is used when an internal copy of the storage is to be made.
Definition ArrayBase.h:51
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
T * storage()
If you really, really, need a "raw" pointer to the beginning of the storage area this will give it to...
Definition Block.h:559
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
Array< LogicalArrayElem > LogicalArray
Definition ArrayFwd.h:17
LatticeExprNode length(const LatticeExprNode &expr, const LatticeExprNode &axis)
2-argument function to get the length of an axis.
MaskedArray< LogicalArrayElem > MaskedLogicalArray
Definition ArrayFwd.h:20
This is a tag for the constructor that may be used to construct an uninitialized Array.
Definition Array.h:180