LSST Applications g0f08755f38+82efc23009,g12f32b3c4e+e7bdf1200e,g1653933729+a8ce1bb630,g1a0ca8cf93+50eff2b06f,g28da252d5a+52db39f6a5,g2bbee38e9b+37c5a29d61,g2bc492864f+37c5a29d61,g2cdde0e794+c05ff076ad,g3156d2b45e+41e33cbcdc,g347aa1857d+37c5a29d61,g35bb328faa+a8ce1bb630,g3a166c0a6a+37c5a29d61,g3e281a1b8c+fb992f5633,g414038480c+7f03dfc1b0,g41af890bb2+11b950c980,g5fbc88fb19+17cd334064,g6b1c1869cb+12dd639c9a,g781aacb6e4+a8ce1bb630,g80478fca09+72e9651da0,g82479be7b0+04c31367b4,g858d7b2824+82efc23009,g9125e01d80+a8ce1bb630,g9726552aa6+8047e3811d,ga5288a1d22+e532dc0a0b,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+37c5a29d61,gcf0d15dbbd+2acd6d4d48,gd7358e8bfb+778a810b6e,gda3e153d99+82efc23009,gda6a2b7d83+2acd6d4d48,gdaeeff99f8+1711a396fd,ge2409df99d+6b12de1076,ge79ae78c31+37c5a29d61,gf0baf85859+d0a5978c5a,gf3967379c6+4954f8c433,gfb92a5be7c+82efc23009,gfec2e1e490+2aaed99252,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
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"
34#include "lsst/afw/image/Mask.h"
35#include "lsst/pex/exceptions.h"
36
37namespace lsst {
38namespace afw {
39namespace geom {
40namespace 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
49template <typename T>
50void variadicSpanSetter(Span const spn, T& x) {
51 x.setSpan(spn);
52}
53
54template <typename T, typename... Args>
55void variadicSpanSetter(Span const spn, T& first, Args&... x) {
56 variadicSpanSetter(spn, first);
57 variadicSpanSetter(spn, x...);
58}
59
60template <typename T>
61void variadicBoundChecker(lsst::geom::Box2I const box, int area, T const& x) {
62 x.checkExtents(box, area);
63}
64
65template <typename T, typename... Args>
66void 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
71template <typename T>
73 x.increment();
74}
75
76template <typename T, typename... Args>
77void 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
87template <typename T>
88class 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 */
102public:
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
122private:
123 T _iter;
124};
125
126template <typename T>
127class ConstantGetter final {
128 // Getter class which takes in a constant value, and simply returns that value
129 // for each iteration
130public:
131 explicit ConstantGetter(T constant) : _const(constant) {}
132
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
150private:
151 T _const;
152};
153
154template <typename T, int N, int C>
155class ImageNdGetter final {
156 // Getter class to manage iterating though an ndarray which is interpreted as a 2D image
157public:
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
188private:
189 ndarray::Array<T, N, C> _array;
191 typename ndarray::Array<T, N, C>::Reference::Iterator _iterX;
192};
193
194template <typename T, int inA, int inC>
195class FlatNdGetter final {
196 // Getter class to manage iterating though an ndarray which is interpreted as a 1D image
197public:
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;
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
224private:
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
238template <typename T, int inA, int inC>
240 // This function simply passes through any FlatNdGetter passed to it
241 return getter;
242}
243
244template <typename T, int inA, int inB>
246 // This function simply passes though any imageNdGetter passed to it
247 return getter;
248}
249
250template <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
256template <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
262template <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
268template <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
274template <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
285template <typename T, typename = void>
287
288template <typename T>
289struct 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
293template <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
303namespace 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
308template <typename T, int inA, int inB>
309
318details::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
332template <typename T, int inA, int inB>
333details::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
#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(ConstantGetter &&)=default
ConstantGetter(ConstantGetter const &)=default
ConstantGetter & operator=(ConstantGetter const &)=default
ConstantGetter & operator=(ConstantGetter &&)=default
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
FlatNdGetter(FlatNdGetter &&)=default
typename ndarray::Array< T, inA, inC >::Reference Reference
FlatNdGetter(FlatNdGetter const &)=default
FlatNdGetter & operator=(FlatNdGetter &&)=default
FlatNdGetter & operator=(FlatNdGetter const &)=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 & operator=(ImageNdGetter &&)=default
ImageNdGetter(ImageNdGetter const &)=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
IterGetter & operator=(IterGetter &&)=default
void checkExtents(lsst::geom::Box2I const &bbox, int area) const
IterGetter & operator=(IterGetter const &)=default
IterGetter(IterGetter &&)=default
std::iterator_traits< T >::reference get() const
IterGetter(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:81
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)
void variadicBoundChecker(lsst::geom::Box2I const box, int area, T const &x)
FlatNdGetter< T, inA, inC > makeGetter(FlatNdGetter< T, inA, inC > &getter)
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.
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.
STL namespace.