23 #include "pybind11/pybind11.h"
24 #include "pybind11/stl.h"
25 #include "ndarray/pybind11.h"
34 using namespace pybind11::literals;
42 template <
typename PixelT>
45 template <
typename PixelT>
48 template <
typename PixelT>
51 template <
typename MaskPixelT>
62 template <
typename FromPixelT,
typename ToPixelT>
63 static void declareCastConstructor(PyImage<ToPixelT> &
cls) {
64 cls.def(
py::init<Image<FromPixelT>
const &,
bool const>(),
"src"_a,
"deep"_a);
67 template <
typename PixelT>
69 PyImageBase<PixelT>
cls(mod, (
"ImageBase" + suffix).c_str());
71 using Array =
typename ImageBase<PixelT>::Array;
74 cls.def(
py::init<ImageBase<PixelT>
const &,
bool>(),
"src"_a,
"deep"_a =
false);
76 "bbox"_a,
"origin"_a =
PARENT,
"deep"_a =
false);
77 cls.def(py::init<Array const &, bool, lsst::geom::Point2I const &>(),
"array"_a,
"deep"_a =
false,
84 cls.def(
"getWidth", &ImageBase<PixelT>::getWidth);
85 cls.def(
"getHeight", &ImageBase<PixelT>::getHeight);
86 cls.def(
"getX0", &ImageBase<PixelT>::getX0);
87 cls.def(
"getY0", &ImageBase<PixelT>::getY0);
88 cls.def(
"getXY0", &ImageBase<PixelT>::getXY0);
91 cls.def(
"getDimensions", &ImageBase<PixelT>::getDimensions);
92 cls.def(
"getArray", (Array(ImageBase<PixelT>::*)()) & ImageBase<PixelT>::getArray);
93 cls.def_property(
"array", (Array(ImageBase<PixelT>::*)()) & ImageBase<PixelT>::getArray,
94 [](ImageBase<PixelT> &
self, ndarray::Array<PixelT const, 2, 0>
const &array) {
96 if (array.shallow() !=
self.getArray().shallow()) {
97 self.getArray().deep() = array;
102 cls.def(
"setXY0", (
void (ImageBase<PixelT>::*)(
int const,
int const)) & ImageBase<PixelT>::setXY0,
"x0"_a,
104 cls.def(
"getBBox", &ImageBase<PixelT>::getBBox,
"origin"_a =
PARENT);
110 img.get(index, origin) =
val;
112 "index"_a,
"value"_a,
"origin"_a);
116 return img.get(index, origin);
118 "index"_a,
"origin"_a);
121 template <
typename MaskPixelT>
123 PyMask<MaskPixelT>
cls(mod, (
"Mask" + suffix).c_str());
128 cls.def(
py::init<
unsigned int,
unsigned int, MaskPixelT,
130 "width"_a,
"height"_a,
"initialValue"_a,
144 cls.def(
py::init<
const Mask<MaskPixelT> &,
const bool>(),
"src"_a,
"deep"_a =
false);
146 "src"_a,
"bbox"_a,
"origin"_a =
PARENT,
"deep"_a =
false);
152 "origin"_a =
PARENT,
"conformMasks"_a =
false,
"allowUnsafe"_a =
false);
156 "origin"_a =
PARENT,
"conformMasks"_a =
false,
"allowUnsafe"_a =
false);
160 "conformMasks"_a =
false,
"allowUnsafe"_a =
false);
163 cls.def(
"__ior__", [](Mask<MaskPixelT> &
self, Mask<MaskPixelT> &
other) {
return self |=
other; });
164 cls.def(
"__ior__", [](Mask<MaskPixelT> &
self, MaskPixelT
const other) {
return self |=
other; });
165 cls.def(
"__ior__", [](Mask<MaskPixelT> &
self,
int other) {
return self |=
other; });
166 cls.def(
"__iand__", [](Mask<MaskPixelT> &
self, Mask<MaskPixelT> &
other) {
return self &=
other; });
167 cls.def(
"__iand__", [](Mask<MaskPixelT> &
self, MaskPixelT
const other) {
return self &=
other; });
168 cls.def(
"__iand__", [](Mask<MaskPixelT> &
self,
int other) {
return self &=
other; });
169 cls.def(
"__ixor__", [](Mask<MaskPixelT> &
self, Mask<MaskPixelT> &
other) {
return self ^=
other; });
170 cls.def(
"__ixor__", [](Mask<MaskPixelT> &
self, MaskPixelT
const other) {
return self ^=
other; });
171 cls.def(
"__ixor__", [](Mask<MaskPixelT> &
self,
int other) {
return self ^=
other; });
182 (
void (Mask<MaskPixelT>::*)(fits::MemFileManager &,
193 (
void (Mask<MaskPixelT>::*)(
std::string const &, fits::ImageWriteOptions
const &,
197 "filename"_a,
"options"_a,
"mode"_a =
"w",
200 (
void (Mask<MaskPixelT>::*)(fits::MemFileManager &, fits::ImageWriteOptions
const &,
204 "manager"_a,
"options"_a,
"mode"_a =
"w",
207 (
void (Mask<MaskPixelT>::*)(fits::Fits &, fits::ImageWriteOptions
const &,
211 cls.def_static(
"readFits", (Mask<MaskPixelT>(*)(
std::string const &,
int))Mask<MaskPixelT>::readFits,
213 cls.def_static(
"readFits", (Mask<MaskPixelT>(*)(fits::MemFileManager &,
int))Mask<MaskPixelT>::readFits,
215 cls.def_static(
"interpret", Mask<MaskPixelT>::interpret);
216 cls.def(
"subset", &Mask<MaskPixelT>::subset,
"bbox"_a,
"origin"_a =
PARENT);
217 cls.def(
"getAsString", &Mask<MaskPixelT>::getAsString);
218 cls.def(
"clearAllMaskPlanes", &Mask<MaskPixelT>::clearAllMaskPlanes);
219 cls.def(
"clearMaskPlane", &Mask<MaskPixelT>::clearMaskPlane);
220 cls.def(
"setMaskPlaneValues", &Mask<MaskPixelT>::setMaskPlaneValues);
221 cls.def_static(
"parseMaskPlaneMetadata", Mask<MaskPixelT>::parseMaskPlaneMetadata);
222 cls.def_static(
"clearMaskPlaneDict", Mask<MaskPixelT>::clearMaskPlaneDict);
223 cls.def_static(
"removeMaskPlane", Mask<MaskPixelT>::removeMaskPlane);
224 cls.def(
"removeAndClearMaskPlane", &Mask<MaskPixelT>::removeAndClearMaskPlane,
"name"_a,
225 "removeFromDefault"_a =
false);
226 cls.def_static(
"getMaskPlane", Mask<MaskPixelT>::getMaskPlane);
227 cls.def_static(
"getPlaneBitMask", (MaskPixelT(*)(
const std::string &))Mask<MaskPixelT>::getPlaneBitMask);
228 cls.def_static(
"getPlaneBitMask",
230 cls.def_static(
"getNumPlanesMax", Mask<MaskPixelT>::getNumPlanesMax);
231 cls.def_static(
"getNumPlanesUsed", Mask<MaskPixelT>::getNumPlanesUsed);
232 cls.def(
"getMaskPlaneDict", &Mask<MaskPixelT>::getMaskPlaneDict);
233 cls.def(
"printMaskPlanes", &Mask<MaskPixelT>::printMaskPlanes);
234 cls.def_static(
"addMaskPlanesToMetadata", Mask<MaskPixelT>::addMaskPlanesToMetadata);
235 cls.def(
"conformMaskPlanes", &Mask<MaskPixelT>::conformMaskPlanes);
236 cls.def_static(
"addMaskPlane", (
int (*)(
const std::string &))Mask<MaskPixelT>::addMaskPlane);
239 template <
typename PixelT>
241 PyImage<PixelT>
cls(mod, (
"Image" + suffix).c_str());
244 cls.def(py::init<unsigned int, unsigned int, PixelT>(),
"width"_a,
"height"_a,
"intialValue"_a = 0);
246 "initialValue"_a = 0);
247 cls.def(py::init<lsst::geom::Box2I const &, PixelT>(),
"bbox"_a,
"initialValue"_a = 0);
249 "rhs"_a,
"bbox"_a,
"origin"_a =
PARENT,
"deep"_a =
false);
255 "origin"_a =
PARENT,
"allowUnsafe"_a =
false);
259 "origin"_a =
PARENT,
"allowUnsafe"_a =
false);
263 "allowUnsafe"_a =
false);
266 cls.def(
"__iadd__", [](Image<PixelT> &
self,
PixelT const &
other) {
return self +=
other; });
267 cls.def(
"__iadd__", [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self +=
other; });
269 return self +=
other;
271 cls.def(
"__isub__", [](Image<PixelT> &
self,
PixelT const &
other) {
return self -=
other; });
272 cls.def(
"__isub__", [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self -=
other; });
274 return self -=
other;
276 cls.def(
"__imul__", [](Image<PixelT> &
self,
PixelT const &
other) {
return self *=
other; });
277 cls.def(
"__imul__", [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self *=
other; });
278 cls.def(
"__itruediv__", [](Image<PixelT> &
self,
PixelT const &
other) {
return self /=
other; });
279 cls.def(
"__itruediv__", [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self /=
other; });
283 cls.def(
"scaledMinus", &Image<PixelT>::scaledMinus);
284 cls.def(
"scaledMultiplies", &Image<PixelT>::scaledMultiplies);
285 cls.def(
"scaledDivides", &Image<PixelT>::scaledDivides);
287 cls.def(
"subset", &Image<PixelT>::subset,
"bbox"_a,
"origin"_a =
PARENT);
304 (
void (Image<PixelT>::*)(
std::string const &, fits::ImageWriteOptions
const &,
308 "filename"_a,
"options"_a,
"mode"_a =
"w",
312 (
void (Image<PixelT>::*)(fits::MemFileManager &, fits::ImageWriteOptions
const &,
319 (
void (Image<PixelT>::*)(fits::Fits &, fits::ImageWriteOptions
const &,
326 cls.def_static(
"readFits", (Image<PixelT>(*)(
std::string const &,
int))Image<PixelT>::readFits,
328 cls.def_static(
"readFits", (Image<PixelT>(*)(fits::MemFileManager &,
int))Image<PixelT>::readFits,
330 cls.def(
"sqrt", &Image<PixelT>::sqrt);
335 template <
typename PixelT>
337 PyDecoratedImage<PixelT>
cls(mod, (
"DecoratedImage" + suffix).c_str());
340 cls.def(py::init<const lsst::geom::Box2I &>(),
"bbox"_a);
342 cls.def(
py::init<DecoratedImage<PixelT>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
343 cls.def(py::init<std::string const &, const int, lsst::geom::Box2I const &, ImageOrigin const, bool>(),
345 "allowUnsafe"_a =
false);
347 cls.def(
"getMetadata", &DecoratedImage<PixelT>::getMetadata);
348 cls.def(
"setMetadata", &DecoratedImage<PixelT>::setMetadata);
349 cls.def(
"getWidth", &DecoratedImage<PixelT>::getWidth);
350 cls.def(
"getHeight", &DecoratedImage<PixelT>::getHeight);
351 cls.def(
"getX0", &DecoratedImage<PixelT>::getX0);
352 cls.def(
"getY0", &DecoratedImage<PixelT>::getY0);
353 cls.def(
"getDimensions", &DecoratedImage<PixelT>::getDimensions);
360 py::overload_cast<
std::string const &, fits::ImageWriteOptions
const &,
365 cls.def(
"getImage", py::overload_cast<>(&DecoratedImage<PixelT>::getImage));
366 cls.def_property_readonly(
"image", py::overload_cast<>(&DecoratedImage<PixelT>::getImage));
367 cls.def(
"getGain", &DecoratedImage<PixelT>::getGain);
368 cls.def(
"setGain", &DecoratedImage<PixelT>::setGain);
372 template <
typename PixelT>
373 static void addImageSliceOperators(
376 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self +
other; },
379 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self -
other; },
382 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self *
other; },
384 cls.def(
"__truediv__",
385 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self /
other; },
387 cls.def(
"__iadd__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
391 cls.def(
"__isub__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
395 cls.def(
"__imul__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
399 cls.def(
"__itruediv__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
405 template <
typename PixelT,
typename PyClass>
406 static void addGeneralizedCopyConstructors(
PyClass &
cls) {
407 cls.def(
py::init<Image<int>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
408 cls.def(
py::init<Image<float>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
409 cls.def(
py::init<Image<double>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
410 cls.def(
py::init<Image<std::uint16_t>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
411 cls.def(
py::init<Image<std::uint64_t>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
413 cls.def(
"convertI", [](Image<PixelT>
const &
self) {
return Image<int>(
self,
true); });
414 cls.def(
"convertF", [](Image<PixelT>
const &
self) {
return Image<float>(
self,
true); });
415 cls.def(
"convertD", [](Image<PixelT>
const &
self) {
return Image<double>(
self,
true); });
416 cls.def(
"convertU", [](Image<PixelT>
const &
self) {
return Image<std::uint16_t>(
self,
true); });
417 cls.def(
"convertL", [](Image<PixelT>
const &
self) {
return Image<std::uint64_t>(
self,
true); });
419 cls.def(
"convertFloat", [](Image<PixelT>
const &
self) {
return Image<float>(
self,
true); });
420 cls.def(
"convertDouble", [](Image<PixelT>
const &
self) {
return Image<double>(
self,
true); });
424 py::module::import(
"lsst.daf.base");
426 py::enum_<ImageOrigin>(mod,
"ImageOrigin")
431 declareImageBase<int>(mod,
"I");
432 declareImageBase<float>(mod,
"F");
433 declareImageBase<double>(mod,
"D");
434 declareImageBase<std::uint16_t>(mod,
"U");
435 declareImageBase<std::uint64_t>(mod,
"L");
438 declareMask<MaskPixel>(mod,
"X");
440 auto clsImageI = declareImage<int>(mod,
"I");
441 auto clsImageF = declareImage<float>(mod,
"F");
442 auto clsImageD = declareImage<double>(mod,
"D");
443 auto clsImageU = declareImage<std::uint16_t>(mod,
"U");
444 auto clsImageL = declareImage<std::uint64_t>(mod,
"L");
447 addGeneralizedCopyConstructors<int>(clsImageI);
448 addGeneralizedCopyConstructors<float>(clsImageF);
449 addGeneralizedCopyConstructors<double>(clsImageD);
450 addGeneralizedCopyConstructors<std::uint16_t>(clsImageU);
451 addGeneralizedCopyConstructors<std::uint64_t>(clsImageL);
454 addImageSliceOperators<float>(clsImageF);
455 addImageSliceOperators<double>(clsImageD);
457 declareDecoratedImage<int>(mod,
"I");
458 declareDecoratedImage<float>(mod,
"F");
459 declareDecoratedImage<double>(mod,
"D");
460 declareDecoratedImage<std::uint16_t>(mod,
"U");
461 declareDecoratedImage<std::uint64_t>(mod,
"L");
465 declareCastConstructor<int, float>(clsImageF);
466 declareCastConstructor<int, double>(clsImageD);
468 declareCastConstructor<float, double>(clsImageD);
470 declareCastConstructor<double, float>(clsImageF);
472 declareCastConstructor<std::uint16_t, float>(clsImageF);
473 declareCastConstructor<std::uint16_t, double>(clsImageD);
475 declareCastConstructor<std::uint64_t, float>(clsImageF);
476 declareCastConstructor<std::uint64_t, double>(clsImageD);