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