24 #include "pybind11/pybind11.h"
26 #include "pybind11/stl.h"
33 #include "ndarray/pybind11.h"
40 using namespace pybind11::literals;
48 using PySpanSet = py::class_<SpanSet, std::shared_ptr<SpanSet>>;
50 template <
typename Pixel,
typename PyClass>
51 void declareFlattenMethod(
PyClass &cls) {
53 (ndarray::Array<Pixel, 1, 1>(SpanSet::*)(ndarray::Array<Pixel, 2, 0>
const &,
55 SpanSet::flatten<Pixel, 2, 0>,
58 (ndarray::Array<Pixel, 2, 2>(SpanSet::*)(ndarray::Array<Pixel, 3, 0>
const &,
60 SpanSet::flatten<Pixel, 3, 0>,
63 (
void (SpanSet::*)(ndarray::Array<Pixel, 1, 0>
const &, ndarray::Array<Pixel, 2, 0>
const &,
65 SpanSet::flatten<Pixel, Pixel, 2, 0, 0>,
68 (
void (SpanSet::*)(ndarray::Array<Pixel, 2, 0>
const &, ndarray::Array<Pixel, 3, 0>
const &,
70 SpanSet::flatten<Pixel, Pixel, 3, 0, 0>,
74 template <
typename Pixel,
typename PyClass>
75 void declareUnflattenMethod(
PyClass &cls) {
77 (ndarray::Array<Pixel, 2, 2>(SpanSet::*)(ndarray::Array<Pixel, 1, 0>
const &input)
const) &
78 SpanSet::unflatten<Pixel, 1, 0>);
80 (ndarray::Array<Pixel, 3, 3>(SpanSet::*)(ndarray::Array<Pixel, 2, 0>
const &input)
const) &
81 SpanSet::unflatten<Pixel, 2, 0>);
83 (
void (SpanSet::*)(ndarray::Array<Pixel, 2, 0>
const &, ndarray::Array<Pixel, 1, 0>
const &,
85 SpanSet::unflatten<Pixel, Pixel, 1, 0, 0>,
88 (
void (SpanSet::*)(ndarray::Array<Pixel, 3, 0>
const &, ndarray::Array<Pixel, 2, 0>
const &,
90 SpanSet::unflatten<Pixel, Pixel, 2, 0, 0>,
94 template <
typename Pixel,
typename PyClass>
95 void declareSetMaskMethod(
PyClass &cls) {
99 template <
typename Pixel,
typename PyClass>
100 void declareClearMaskMethod(
PyClass &cls) {
104 template <
typename Pixel,
typename PyClass>
105 void declareIntersectMethod(
PyClass &cls) {
109 "other"_a,
"bitmask"_a);
114 auto tempSpanSet = SpanSet::fromMask(
mask);
115 return self.intersect(*tempSpanSet);
120 template <
typename Pixel,
typename PyClass>
121 void declareIntersectNotMethod(
PyClass &cls) {
122 cls.def(
"intersectNot",
124 SpanSet::intersectNot,
125 "other"_a,
"bitmask"_a);
130 auto tempSpanSet = SpanSet::fromMask(
mask);
131 return self.intersectNot(*tempSpanSet);
136 template <
typename Pixel,
typename PyClass>
137 void declareUnionMethod(
PyClass &cls) {
140 "other"_a,
"bitmask"_a);
145 auto tempSpanSet = SpanSet::fromMask(
mask);
146 return self.union_(*tempSpanSet);
151 template <
typename ImageT,
typename PyClass>
152 void declareCopyImage(
PyClass &cls) {
153 cls.def(
"copyImage", &SpanSet::copyImage<ImageT>);
156 template <
typename ImageT,
typename PyClass>
157 void declareCopyMaskedImage(
PyClass &cls) {
160 cls.def(
"copyMaskedImage", &SpanSet::copyMaskedImage<ImageT, MaskPixel, VariancePixel>);
163 template <
typename ImageT,
typename PyClass>
164 void declareSetImage(
PyClass &cls) {
171 template <
typename MaskPixel,
typename PyClass>
172 void declarefromMask(
PyClass &cls) {
175 return SpanSet::fromMask(
mask, bitmask);
179 template <
typename Pixel,
typename PyClass>
180 void declareMaskMethods(
PyClass &cls) {
181 declareSetMaskMethod<Pixel>(cls);
182 declareClearMaskMethod<Pixel>(cls);
183 declareIntersectMethod<Pixel>(cls);
184 declareIntersectNotMethod<Pixel>(cls);
185 declareUnionMethod<Pixel>(cls);
188 template <
typename Pixel,
typename PyClass>
189 void declareImageTypes(
PyClass &cls) {
190 declareFlattenMethod<Pixel>(cls);
191 declareUnflattenMethod<Pixel>(cls);
192 declareCopyImage<Pixel>(cls);
193 declareCopyMaskedImage<Pixel>(cls);
194 declareSetImage<Pixel>(cls);
198 wrappers.
wrapType(py::enum_<Stencil>(wrappers.
module,
"Stencil"), [](
auto &mod,
auto &enm) {
199 enm.value(
"CIRCLE", Stencil::CIRCLE);
200 enm.value(
"BOX", Stencil::BOX);
201 enm.value(
"MANHATTAN", Stencil::MANHATTAN);
208 wrappers.
wrapType(PySpanSet(wrappers.
module,
"SpanSet"), [](
auto &mod,
auto &cls) {
210 cls.def(py::init<>());
211 cls.def(py::init<lsst::geom::Box2I>(),
"box"_a);
212 cls.def(py::init<std::vector<Span>, bool>(),
"spans"_a,
"normalize"_a = true);
214 table::io::python::addPersistableMethods<SpanSet>(cls);
217 cls.def(
"getArea", &SpanSet::getArea);
218 cls.def(
"getBBox", &SpanSet::getBBox);
219 cls.def(
"isContiguous", &SpanSet::isContiguous);
220 cls.def(
"shiftedBy", (std::shared_ptr<SpanSet>(SpanSet::*)(int, int) const) & SpanSet::shiftedBy);
221 cls.def(
"shiftedBy", (std::shared_ptr<SpanSet>(SpanSet::*)(lsst::geom::Extent2I const &) const) &
223 cls.def(
"clippedTo", &SpanSet::clippedTo);
224 cls.def(
"transformedBy",
225 (std::shared_ptr<SpanSet>(SpanSet::*)(lsst::geom::LinearTransform const &) const) &
226 SpanSet::transformedBy);
227 cls.def(
"transformedBy",
228 (std::shared_ptr<SpanSet>(SpanSet::*)(lsst::geom::AffineTransform const &) const) &
229 SpanSet::transformedBy);
230 cls.def(
"transformedBy",
231 (std::shared_ptr<SpanSet>(SpanSet::*)(TransformPoint2ToPoint2 const &) const) &
232 SpanSet::transformedBy);
233 cls.def(
"overlaps", &SpanSet::overlaps);
234 cls.def(
"contains", (bool (SpanSet::*)(SpanSet const &) const) & SpanSet::contains);
235 cls.def(
"contains", (bool (SpanSet::*)(lsst::geom::Point2I const &) const) & SpanSet::contains);
236 cls.def(
"computeCentroid", &SpanSet::computeCentroid);
237 cls.def(
"computeShape", &SpanSet::computeShape);
238 cls.def(
"dilated", (std::shared_ptr<SpanSet>(SpanSet::*)(int, Stencil) const) & SpanSet::dilated,
239 "radius"_a,
"stencil"_a = Stencil::CIRCLE);
240 cls.def(
"dilated", (std::shared_ptr<SpanSet>(SpanSet::*)(SpanSet const &) const) & SpanSet::dilated);
241 cls.def(
"eroded", (std::shared_ptr<SpanSet>(SpanSet::*)(int, Stencil) const) & SpanSet::eroded,
242 "radius"_a,
"stencil"_a = Stencil::CIRCLE);
243 cls.def(
"eroded", (std::shared_ptr<SpanSet>(SpanSet::*)(SpanSet const &) const) & SpanSet::eroded);
245 (std::shared_ptr<SpanSet>(SpanSet::*)(SpanSet const &) const) & SpanSet::intersect);
246 cls.def(
"intersectNot",
247 (std::shared_ptr<SpanSet>(SpanSet::*)(SpanSet const &) const) & SpanSet::intersectNot);
248 cls.def(
"union", (std::shared_ptr<SpanSet>(SpanSet::*)(SpanSet const &) const) & SpanSet::union_);
249 cls.def_static(
"fromShape",
250 (std::shared_ptr<SpanSet>(*)(int, Stencil, lsst::geom::Point2I)) & SpanSet::fromShape,
251 "radius"_a,
"stencil"_a = Stencil::CIRCLE,
"offset"_a = lsst::geom::Point2I());
254 [](int r, Stencil s, std::pair<int, int> point) {
255 return SpanSet::fromShape(r, s, lsst::geom::Point2I(point.first, point.second));
258 cls.def_static(
"fromShape",
260 cls.def(
"split", &SpanSet::split);
261 cls.def(
"findEdgePixels", &SpanSet::findEdgePixels);
267 for (
auto const &span :
self) {
268 auto y = span.getY();
269 for (
int x = span.getX0();
x <= span.getX1(); ++
x) {
279 "__eq__", [](SpanSet
const &
self, SpanSet
const &
other) ->
bool {
return self ==
other; },
282 "__ne__", [](SpanSet
const &
self, SpanSet
const &
other) ->
bool {
return self !=
other; },
285 "__iter__", [](SpanSet &
self) {
return py::make_iterator(
self.
begin(),
self.
end()); },
286 py::keep_alive<0, 1>());
287 cls.def(
"__len__", [](SpanSet
const &
self) -> decltype(
self.size()) {
return self.size(); });
288 cls.def(
"__contains__",
289 [](SpanSet &
self, SpanSet
const &
other) ->
bool {
return self.contains(
other); });
290 cls.def(
"__contains__",
292 cls.def(
"__repr__", [](SpanSet
const &
self) ->
std::string {
295 self.setMask(tempMask,
static_cast<MaskPixel>(1));
296 auto array = tempMask.getArray();
297 auto dims = array.getShape();
302 if (j != dims[1] - 1) {
310 cls.def(
"__str__", [](SpanSet
const &
self) ->
std::string {
312 for (
auto const &span :
self) {
313 os << span.getY() <<
": " << span.getMinX() <<
".." << span.getMaxX() <<
std::endl;
319 declareMaskMethods<MaskPixel>(cls);
321 declareImageTypes<std::uint16_t>(cls);
322 declareImageTypes<std::uint64_t>(cls);
323 declareImageTypes<int>(cls);
324 declareImageTypes<float>(cls);
325 declareImageTypes<double>(cls);
328 declareFlattenMethod<long>(cls);
329 declareUnflattenMethod<long>(cls);
331 declarefromMask<MaskPixel>(cls);
338 declareStencil(wrappers);
339 declareSpanSet(wrappers);
ItemVariant const * other
A class to represent a 2-dimensional array of pixels.
Represent a 2-dimensional array of bitmask pixels.
An integer coordinate rectangle.
A helper class for subdividing pybind11 module across multiple translation units (i....
pybind11::module module
The module object passed to the PYBIND11_MODULE block that contains this WrapperCollection.
PyType wrapType(PyType cls, ClassWrapperCallback function, bool setModuleName=true)
Add a type (class or enum) wrapper, deferring method and other attribute definitions until finish() i...
void addSignatureDependency(std::string const &name)
Indicate an external module that provides a type used in function/method signatures.
void wrapSpanSet(lsst::utils::python::WrapperCollection &)
std::int32_t MaskPixel
default type for Masks and MaskedImage Masks
float VariancePixel
default type for MaskedImage variance images
py::class_< PixelAreaBoundedField, std::shared_ptr< PixelAreaBoundedField >, BoundedField > PyClass
float Pixel
Typedefs to be used for pixel values.
A base class for image defects.