lsst.afw  21.0.0-6-ge3f375325+ce03d725a7
SpanSetFunctorGetters.h
Go to the documentation of this file.
1 
2 
3 // -*- lsst-c++ -*-
4 
5 /*
6  * LSST Data Management System
7  * Copyright 2008-2016 AURA/LSST.
8  *
9  * This product includes software developed by the
10  * LSST Project (http://www.lsst.org/).
11  *
12  * This program is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the LSST License Statement and
23  * the GNU General Public License along with this program. If not,
24  * see <https://www.lsstcorp.org/LegalNotices/>.
25  */
26 
27 #ifndef LSST_AFW_GEOM_SPANSETFUNCTORGETTERS_H
28 #define LSST_AFW_GEOM_SPANSETFUNCTORGETTERS_H
29 
30 #include <type_traits>
31 #include "lsst/afw/geom/Span.h"
32 #include "lsst/geom/Point.h"
33 #include "lsst/afw/image/Image.h"
34 #include "lsst/afw/image/Mask.h"
35 #include "lsst/pex/exceptions.h"
36 
37 namespace lsst {
38 namespace afw {
39 namespace geom {
40 namespace details {
41 
42 /* These variadic functions exist because of a current limitation in c++ where
43  * calls of the form foo(x)... are not possible unless it is used as a parameter
44  * for a second function. The following functions take in a variadic parameter
45  * pack, and make recursive calls until the corresponding class method has been
46  * called on all the variadic parameters
47  */
48 
49 template <typename T>
50 void variadicSpanSetter(Span const spn, T& x) {
51  x.setSpan(spn);
52 }
53 
54 template <typename T, typename... Args>
55 void variadicSpanSetter(Span const spn, T& first, Args&... x) {
57  variadicSpanSetter(spn, x...);
58 }
59 
60 template <typename T>
61 void variadicBoundChecker(lsst::geom::Box2I const box, int area, T const& x) {
62  x.checkExtents(box, area);
63 }
64 
65 template <typename T, typename... Args>
66 void variadicBoundChecker(lsst::geom::Box2I const box, int area, T const& first, Args&... x) {
67  variadicBoundChecker(box, area, first);
68  variadicBoundChecker(box, area, x...);
69 }
70 
71 template <typename T>
73  x.increment();
74 }
75 
76 template <typename T, typename... Args>
77 void variadicIncrementPosition(T& first, Args&... x) {
80 }
81 
82 /* Getter classes exist to provide a common API (duck-type) for accessing data from
83  * different data-types. This common API is used by the SpanSets applyFunctor method
84  * for passing the correct references into the supplied functor.
85  */
86 
87 template <typename T>
88 class IterGetter final {
89  /* Getter class to manage retrieving values from a generic iterator
90  !!! be careful !!! Because there is no way to easily check bounds
91  for a generic iterator, it is possible to pass an iterator too
92  short, in which case the apply functor will run off the end.
93 
94  Also note that because this is a generic iterator, the iterator
95  must always provide the next desired value when it is incremented.
96  For instance when iterating over a two dimensional object should
97  automatically wrap to the next line when the ++ operator reaches
98  the end of the line. In this way all generic inputs must be treated
99  as 1d arrays, of length at least the number of elements in the
100  SpanSet which originates the applyFunctor call
101  */
102 public:
104  explicit IterGetter(T iter) : _iter(iter) {}
105 
106  IterGetter(IterGetter const&) = default;
107  IterGetter(IterGetter&&) = default;
108  IterGetter& operator=(IterGetter const&) = default;
110  ~IterGetter() = default;
111 
112  // There is no good way to check the extents of a generic iterator, so make
113  // a no-op function to satisfy api
114  void checkExtents(lsst::geom::Box2I const& bbox, int area) const {}
115 
116  void setSpan(Span const& span) {}
117 
118  void increment() { ++_iter; }
119 
120  typename std::iterator_traits<T>::reference get() const { return *_iter; }
121 
122 private:
123  T _iter;
124 };
125 
126 template <typename T>
127 class ConstantGetter final {
128  // Getter class which takes in a constant value, and simply returns that value
129  // for each iteration
130 public:
131  explicit ConstantGetter(T constant) : _const(constant) {}
132 
133  ConstantGetter(ConstantGetter const&) = default;
137  ~ConstantGetter() = default;
138 
139  // Constants are simply repeated, so no need to check extents, make no-op
140  // function
141  void checkExtents(lsst::geom::Box2I const& bbox, int area) const {}
142 
143  void setSpan(Span const& span) {}
144 
145  // No need to increment, make a no-op function
146  void increment() {}
147 
148  T get() const { return _const; }
149 
150 private:
151  T _const;
152 };
153 
154 template <typename T, int N, int C>
155 class ImageNdGetter final {
156  // Getter class to manage iterating though an ndarray which is interpreted as a 2D image
157 public:
158  using Reference = typename ndarray::Array<T, N, C>::Reference::Reference;
159 
160  ImageNdGetter(ndarray::Array<T, N, C> const& array, lsst::geom::Point2I const& xy0)
161  : _array(array), _xy0(xy0) {}
162 
163  ImageNdGetter(ImageNdGetter const&) = default;
167  ~ImageNdGetter() = default;
168 
169  void checkExtents(lsst::geom::Box2I const& bbox, int area) const {
170  // If the bounding box lays outside the are of the image, throw an error
171  lsst::geom::Box2I arrayBBox(
172  _xy0, lsst::geom::Extent2I(_array.template getSize<1>(), _array.template getSize<0>()));
173  if (!arrayBBox.contains(bbox)) {
175  "SpanSet bounding box lands outside array");
176  }
177  }
178 
179  void setSpan(Span const& span) {
180  auto _iterY = _array.begin() + (span.getY() - _xy0.getY());
181  _iterX = (*_iterY).begin() + (span.getMinX() - _xy0.getX());
182  }
183 
184  void increment() { ++_iterX; }
185 
186  Reference get() { return *_iterX; }
187 
188 private:
189  ndarray::Array<T, N, C> _array;
190  lsst::geom::Point2I _xy0;
191  typename ndarray::Array<T, N, C>::Reference::Iterator _iterX;
192 };
193 
194 template <typename T, int inA, int inC>
195 class FlatNdGetter final {
196  // Getter class to manage iterating though an ndarray which is interpreted as a 1D image
197 public:
198  using Reference = typename ndarray::Array<T, inA, inC>::Reference;
199 
200  explicit FlatNdGetter(ndarray::Array<T, inA, inC> const& array) : _array(array), _iter(_array.begin()) {}
201 
202  FlatNdGetter(FlatNdGetter const&) = default;
204  FlatNdGetter& operator=(FlatNdGetter const&) = default;
206  ~FlatNdGetter() = default;
207 
208  void checkExtents(lsst::geom::Box2I const& bbox, int area) const {
209  // If the area of the array is greater than the size of the array, throw an error
210  // as the iteration dimensions will not match
211  auto shape = _array.getShape();
212  if (area > static_cast<int>(shape[0])) {
214  "SpanSet has dimensionality greater than array");
215  }
216  }
217 
218  void setSpan(Span const& span) {}
219 
220  void increment() { ++_iter; }
221 
222  Reference get() const { return *_iter; }
223 
224 private:
225  ndarray::Array<T, inA, inC> _array;
226  typename ndarray::Array<T, inA, inC>::Iterator _iter;
227 };
228 
229 /*
230  * The MakeGetter function serves as a dispatch agent for the applyFunctor method.
231  * The overloaded function accepts various types of objects and initialized the
232  * corresponding "Getter" classes. These classes exist to structure calls to the
233  * various data-types in such a way that they all share a common API. This allows
234  * the applyFunctor method to operate on each of these data-types as if they were all
235  * the same. (aka they all correspond to the same duck-type)
236  */
237 
238 template <typename T, int inA, int inC>
240  // This function simply passes through any FlatNdGetter passed to it
241  return getter;
242 }
243 
244 template <typename T, int inA, int inB>
246  // This function simply passes though any imageNdGetter passed to it
247  return getter;
248 }
249 
250 template <typename T>
252  // Function to create a ndarray getter from an afw image
253  return ImageNdGetter<T, 2, 1>(image.getArray(), image.getXY0());
254 }
255 
256 template <typename T>
258  // Function to create a ndarray getter from an afw image
259  return ImageNdGetter<T const, 2, 1>(image.getArray(), image.getXY0());
260 }
261 
262 template <typename T>
264  // Function to create a ndarray getter from an afw image
265  return ImageNdGetter<T, 2, 1>(image.getArray(), image.getXY0());
266 }
267 
268 template <typename T>
270  // Function to create a ndarray getter from an afw image
271  return ImageNdGetter<T const, 2, 1>(image.getArray(), image.getXY0());
272 }
273 
274 template <typename T>
276  // Function to create a getter for constant numeric types. Use template type checking to ensure the
277  // type is an integral type, or floating point type
278  return ConstantGetter<T>(num);
279 }
280 
281 // There is no type trait in the standard library to check for iterator types, so we declare one here
282 // Template specialization is used here. If type T can be mapped to an iterator trait, then it should
283 // be considered as an iterator. If c++11 supported concepts this would be a perfect place for it. this
284 // is essentially a duck-type type checking mechanism
285 template <typename T, typename = void>
287 
288 template <typename T>
289 struct is_iterator<T, typename std::enable_if<
290  !std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type>
291  : std::true_type {};
292 
293 template <typename T>
295  // Use defined type trait checker to create an iterator getter if the template is an iterator type
296  return IterGetter<T>(iter);
297 }
298 } // namespace details
299 } // namespace geom
300 } // namespace afw
301 } // namespace lsst
302 
303 namespace ndarray {
304 // These function are placed in the ndarray namespace to enable function argument namespace lookup
305 // This means the function can be used on an ndarray without the need to specify the namespace of
306 // the function itself
308 template <typename T, int inA, int inB>
309 
318 details::FlatNdGetter<T, inA, inB> ndFlat(ndarray::Array<T, inA, inB> const& array) {
319  // Function to mark a ndarray to be treated as a flat vector by the applyFunctor method
321 }
322 
332 template <typename T, int inA, int inB>
333 details::ImageNdGetter<T, inA, inB> ndImage(ndarray::Array<T, inA, inB> const& array,
335  // Function to mark a ndarray to be treated as a 2D image by the applyFunctor method
336  return details::ImageNdGetter<T, inA, inB>(array, xy0);
337 }
338 } // namespace ndarray
339 
340 #endif // LSST_AFW_GEOM_SPANSETFUNCTORGETTERS_H
ndarray::ndImage
details::ImageNdGetter< T, inA, inB > ndImage(ndarray::Array< T, inA, inB > const &array, lsst::geom::Point2I xy0=lsst::geom::Point2I())
Marks a ndarray to be interpreted as an image when applying a functor from a SpanSet.
Definition: SpanSetFunctorGetters.h:333
lsst::afw::geom::details::ImageNdGetter::ImageNdGetter
ImageNdGetter(ndarray::Array< T, N, C > const &array, lsst::geom::Point2I const &xy0)
Definition: SpanSetFunctorGetters.h:160
lsst::afw::geom::details::IterGetter::checkExtents
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
Definition: SpanSetFunctorGetters.h:114
lsst::afw::geom::details::IterGetter::~IterGetter
~IterGetter()=default
lsst::afw::image
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Definition: imageAlgorithm.dox:1
lsst::afw::geom::details::ImageNdGetter::operator=
ImageNdGetter & operator=(ImageNdGetter &&)=default
std::false_type
lsst::afw::geom::Span
A range of pixels within one row of an Image.
Definition: Span.h:47
lsst::afw::geom::details::FlatNdGetter::FlatNdGetter
FlatNdGetter(FlatNdGetter &&)=default
lsst::afw::geom::details::IterGetter::get
std::iterator_traits< T >::reference get() const
Definition: SpanSetFunctorGetters.h:120
lsst::afw::image::Mask
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
lsst::afw::geom::details::ConstantGetter::checkExtents
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
Definition: SpanSetFunctorGetters.h:141
lsst::afw::geom::details::ImageNdGetter::operator=
ImageNdGetter & operator=(ImageNdGetter const &)=default
lsst::afw::geom::details::ConstantGetter::increment
void increment()
Definition: SpanSetFunctorGetters.h:146
lsst::afw::geom::details::FlatNdGetter::Reference
typename ndarray::Array< T, inA, inC >::Reference Reference
Definition: SpanSetFunctorGetters.h:198
lsst::afw::geom::details::IterGetter::IterGetter
IterGetter(T iter)
Definition: SpanSetFunctorGetters.h:104
lsst::afw::geom::details::ConstantGetter::ConstantGetter
ConstantGetter(T constant)
Definition: SpanSetFunctorGetters.h:131
lsst::afw::table._match.first
first
Definition: _match.py:74
lsst::afw::geom::details::FlatNdGetter::operator=
FlatNdGetter & operator=(FlatNdGetter &&)=default
lsst::afw::geom::details::IterGetter::setSpan
void setSpan(Span const &span)
Definition: SpanSetFunctorGetters.h:116
lsst::afw::geom::details::ImageNdGetter
Definition: SpanSetFunctorGetters.h:155
lsst::afw::geom::details::FlatNdGetter::increment
void increment()
Definition: SpanSetFunctorGetters.h:220
lsst::afw::geom::details::FlatNdGetter::setSpan
void setSpan(Span const &span)
Definition: SpanSetFunctorGetters.h:218
lsst::afw::geom::details::ConstantGetter::ConstantGetter
ConstantGetter(ConstantGetter const &)=default
Image.h
lsst::afw::geom::details::ConstantGetter::~ConstantGetter
~ConstantGetter()=default
lsst::afw::geom::details::IterGetter::IterGetter
IterGetter(IterGetter &&)=default
lsst::afw::geom::details::FlatNdGetter::operator=
FlatNdGetter & operator=(FlatNdGetter const &)=default
std::is_arithmetic
ndarray
Definition: SpanSetFunctorGetters.h:303
lsst::afw::geom::details::FlatNdGetter
Definition: SpanSetFunctorGetters.h:195
lsst::afw::geom::details::FlatNdGetter::~FlatNdGetter
~FlatNdGetter()=default
std::enable_if
lsst::afw::geom::details::is_iterator
Definition: SpanSetFunctorGetters.h:286
lsst::afw::geom::Span::getY
int getY() const noexcept
Return the y-value.
Definition: Span.h:76
lsst::afw::geom::details::IterGetter::increment
void increment()
Definition: SpanSetFunctorGetters.h:118
lsst::afw::geom::details::ConstantGetter::setSpan
void setSpan(Span const &span)
Definition: SpanSetFunctorGetters.h:143
std::iterator_traits
x
double x
Definition: ChebyshevBoundedField.cc:277
ndarray::ndFlat
details::FlatNdGetter< T, inA, inB > ndFlat(ndarray::Array< T, inA, inB > const &array)
Marks a ndarray to be interpreted as a 1D vector when applying a functor from a SpanSet.
Definition: SpanSetFunctorGetters.h:318
lsst::afw::geom::details::IterGetter
Definition: SpanSetFunctorGetters.h:88
lsst::afw::geom::details::IterGetter::type
typename std::iterator_traits< T >::value_type type
Definition: SpanSetFunctorGetters.h:103
lsst::geom::Box2I::contains
bool contains(Point2I const &point) const noexcept
Span.h
lsst::afw::geom::details::ConstantGetter::get
T get() const
Definition: SpanSetFunctorGetters.h:148
Point.h
lsst::afw::geom::details::ConstantGetter::ConstantGetter
ConstantGetter(ConstantGetter &&)=default
lsst::afw::geom::details::FlatNdGetter::FlatNdGetter
FlatNdGetter(ndarray::Array< T, inA, inC > const &array)
Definition: SpanSetFunctorGetters.h:200
lsst::afw::geom::Span::getMinX
int getMinX() const noexcept
Minimum x-value.
Definition: Span.h:79
lsst::afw::geom::details::FlatNdGetter::FlatNdGetter
FlatNdGetter(FlatNdGetter const &)=default
lsst::afw::geom::details::makeGetter
FlatNdGetter< T, inA, inC > makeGetter(FlatNdGetter< T, inA, inC > &getter)
Definition: SpanSetFunctorGetters.h:239
lsst::afw::geom::details::FlatNdGetter::checkExtents
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
Definition: SpanSetFunctorGetters.h:208
lsst::afw::geom::details::ImageNdGetter::checkExtents
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
Definition: SpanSetFunctorGetters.h:169
lsst::afw::geom::details::ConstantGetter
Definition: SpanSetFunctorGetters.h:127
lsst
A base class for image defects.
LSST_EXCEPT
#define LSST_EXCEPT(type,...)
exceptions.h
lsst::afw::geom::details::ImageNdGetter::~ImageNdGetter
~ImageNdGetter()=default
lsst::afw::geom::details::ConstantGetter::operator=
ConstantGetter & operator=(ConstantGetter &&)=default
Mask.h
lsst::afw::geom::details::IterGetter::operator=
IterGetter & operator=(IterGetter &&)=default
std
STL namespace.
type
table::Key< int > type
Definition: Detector.cc:163
lsst::afw::geom::details::ImageNdGetter::get
Reference get()
Definition: SpanSetFunctorGetters.h:186
Point< int, 2 >
lsst::pex::exceptions::OutOfRangeError
lsst::afw::geom::details
Definition: SpanSet.h:48
lsst::afw::geom::details::FlatNdGetter::get
Reference get() const
Definition: SpanSetFunctorGetters.h:222
lsst::geom::Box2I
lsst::afw::geom::details::variadicIncrementPosition
void variadicIncrementPosition(T &x)
Definition: SpanSetFunctorGetters.h:72
lsst::afw::geom::details::variadicBoundChecker
void variadicBoundChecker(lsst::geom::Box2I const box, int area, T const &x)
Definition: SpanSetFunctorGetters.h:61
lsst::afw::geom::details::ImageNdGetter::increment
void increment()
Definition: SpanSetFunctorGetters.h:184
lsst::afw::geom::details::IterGetter::IterGetter
IterGetter(IterGetter const &)=default
lsst::afw::geom::details::ConstantGetter::operator=
ConstantGetter & operator=(ConstantGetter const &)=default
lsst::afw::image::Image
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:58
lsst::afw::geom::details::ImageNdGetter::Reference
typename ndarray::Array< T, N, C >::Reference::Reference Reference
Definition: SpanSetFunctorGetters.h:158
lsst::afw::geom::details::ImageNdGetter::ImageNdGetter
ImageNdGetter(ImageNdGetter const &)=default
lsst::afw::geom::details::ImageNdGetter::ImageNdGetter
ImageNdGetter(ImageNdGetter &&)=default
Extent< int, 2 >
iter
def iter(self)
lsst::afw::geom::details::IterGetter::operator=
IterGetter & operator=(IterGetter const &)=default
lsst::afw::geom::details::ImageNdGetter::setSpan
void setSpan(Span const &span)
Definition: SpanSetFunctorGetters.h:179
bbox
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
lsst::afw::geom::details::variadicSpanSetter
void variadicSpanSetter(Span const spn, T &x)
Definition: SpanSetFunctorGetters.h:50