LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
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>
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>
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>
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;
192 };
193 
194 template <typename T, int inA, int inC>
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;
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
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
double x
table::Key< int > type
Definition: Detector.cc:163
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
A range of pixels within one row of an Image.
Definition: Span.h:47
int getMinX() const noexcept
Minimum x-value.
Definition: Span.h:84
int getY() const noexcept
Return the y-value.
Definition: Span.h:81
ConstantGetter & operator=(ConstantGetter const &)=default
ConstantGetter(ConstantGetter &&)=default
ConstantGetter(ConstantGetter const &)=default
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
ConstantGetter & operator=(ConstantGetter &&)=default
FlatNdGetter & operator=(FlatNdGetter const &)=default
FlatNdGetter(FlatNdGetter &&)=default
typename ndarray::Array< T, inA, inC >::Reference Reference
FlatNdGetter(FlatNdGetter const &)=default
FlatNdGetter & operator=(FlatNdGetter &&)=default
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
FlatNdGetter(ndarray::Array< T, inA, inC > const &array)
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
ImageNdGetter(ImageNdGetter const &)=default
ImageNdGetter & operator=(ImageNdGetter &&)=default
ImageNdGetter(ndarray::Array< T, N, C > const &array, lsst::geom::Point2I const &xy0)
typename ndarray::Array< T, N, C >::Reference::Reference Reference
ImageNdGetter(ImageNdGetter &&)=default
ImageNdGetter & operator=(ImageNdGetter const &)=default
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
std::iterator_traits< T >::reference get() const
IterGetter & operator=(IterGetter &&)=default
IterGetter(IterGetter &&)=default
IterGetter(IterGetter const &)=default
IterGetter & operator=(IterGetter const &)=default
typename std::iterator_traits< T >::value_type type
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:51
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
An integer coordinate rectangle.
Definition: Box.h:55
bool contains(Point2I const &point) const noexcept
Return true if the box contains the point.
Definition: Box.cc:114
Reports attempts to access elements outside a valid range of indices.
Definition: Runtime.h:89
void variadicSpanSetter(Span const spn, T &x)
FlatNdGetter< T, inA, inC > makeGetter(FlatNdGetter< T, inA, inC > &getter)
void variadicBoundChecker(lsst::geom::Box2I const box, int area, T const &x)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
class[[deprecated("Removed with no replacement (but see lsst::afw::image::TransmissionCurve). Will be " "removed after v22.")]] FilterProperty final
Describe the properties of a Filter (e.g.
Definition: Filter.h:53
FastFinder::Iterator Iterator
Definition: FastFinder.cc:178
A base class for image defects.
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.
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.
STL namespace.