23 #include "pybind11/pybind11.h"
24 #include "pybind11/stl.h"
26 #include "ndarray/pybind11.h"
35 using namespace pybind11::literals;
43 template <
typename PixelT>
46 template <
typename PixelT>
49 template <
typename PixelT>
52 template <
typename MaskPixelT>
63 template <
typename FromPixelT,
typename ToPixelT>
64 static void declareCastConstructor(PyImage<ToPixelT> &cls) {
65 cls.def(
py::init<Image<FromPixelT>
const &,
bool const>(),
"src"_a,
"deep"_a);
68 template <
typename PixelT>
70 using Array =
typename ImageBase<PixelT>::Array;
71 wrappers.
wrapType(PyImageBase<PixelT>(wrappers.
module, (
"ImageBase" + suffix).c_str()), [](
auto &mod,
73 cls.def(py::init<lsst::geom::Extent2I const &>(),
"dimensions"_a = lsst::geom::Extent2I());
74 cls.def(py::init<ImageBase<PixelT> const &, bool>(),
"src"_a,
"deep"_a = false);
75 cls.def(py::init<ImageBase<PixelT> const &, lsst::geom::Box2I const &, ImageOrigin, bool>(),
"src"_a,
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,
78 "xy0"_a = lsst::geom::Point2I());
80 cls.def(
"assign", &ImageBase<PixelT>::assign,
"rhs"_a,
"bbox"_a = lsst::geom::Box2I(),
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);
89 cls.def(
"positionToIndex", &ImageBase<PixelT>::positionToIndex,
"position"_a,
"xOrY"_a);
90 cls.def(
"indexToPosition", &ImageBase<PixelT>::indexToPosition,
"index"_a,
"xOrY"_a);
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) {
97 if (array.shallow() != self.getArray().shallow()) {
98 self.getArray().deep() = array;
104 cls.def(
"setXY0", (
void (ImageBase<PixelT>::*)(
int const,
int const)) & ImageBase<PixelT>::setXY0,
106 cls.def(
"getBBox", &ImageBase<PixelT>::getBBox,
"origin"_a =
PARENT);
108 cls.def(
"set", [](ImageBase<PixelT> &img,
PixelT val) { img =
val; });
113 img.get(index, origin) =
val;
115 "index"_a,
"value"_a,
"origin"_a);
120 return img.get(index, origin);
122 "index"_a,
"origin"_a);
126 template <
typename MaskPixelT>
128 wrappers.
wrapType(PyMask<MaskPixelT>(wrappers.
module, (
"Mask" + suffix).c_str()), [](
auto &mod,
131 cls.def(py::init<unsigned int, unsigned int, typename Mask<MaskPixelT>::MaskPlaneDict const &>(),
132 "width"_a,
"height"_a,
"planeDefs"_a = typename Mask<MaskPixelT>::MaskPlaneDict());
133 cls.def(py::init<unsigned int, unsigned int, MaskPixelT,
134 typename Mask<MaskPixelT>::MaskPlaneDict const &>(),
135 "width"_a,
"height"_a,
"initialValue"_a,
136 "planeDefs"_a = typename Mask<MaskPixelT>::MaskPlaneDict());
137 cls.def(py::init<lsst::geom::Extent2I const &, typename Mask<MaskPixelT>::MaskPlaneDict const &>(),
138 "dimensions"_a = lsst::geom::Extent2I(),
139 "planeDefs"_a = typename Mask<MaskPixelT>::MaskPlaneDict());
140 cls.def(py::init<lsst::geom::Extent2I const &, MaskPixelT,
141 typename Mask<MaskPixelT>::MaskPlaneDict const &>(),
142 "dimensions"_a = lsst::geom::Extent2I(),
"initialValue"_a,
143 "planeDefs"_a = typename Mask<MaskPixelT>::MaskPlaneDict());
144 cls.def(py::init<lsst::geom::Box2I const &, typename Mask<MaskPixelT>::MaskPlaneDict const &>(),
145 "bbox"_a,
"planeDefs"_a = typename Mask<MaskPixelT>::MaskPlaneDict());
146 cls.def(py::init<lsst::geom::Box2I const &, MaskPixelT,
147 typename Mask<MaskPixelT>::MaskPlaneDict const &>(),
148 "bbox"_a,
"initialValue"_a,
"planeDefs"_a = typename Mask<MaskPixelT>::MaskPlaneDict());
149 cls.def(py::init<const Mask<MaskPixelT> &, const bool>(),
"src"_a,
"deep"_a = false);
150 cls.def(py::init<const Mask<MaskPixelT> &, const lsst::geom::Box2I &, ImageOrigin const,
152 "src"_a,
"bbox"_a,
"origin"_a = PARENT,
"deep"_a = false);
153 cls.def(py::init<ndarray::Array<MaskPixelT, 2, 1> const &, bool, lsst::geom::Point2I const &>(),
154 "array"_a,
"deep"_a = false,
"xy0"_a = lsst::geom::Point2I());
155 cls.def(py::init<std::string const &, int, std::shared_ptr<lsst::daf::base::PropertySet>,
156 lsst::geom::Box2I const &, ImageOrigin, bool, bool>(),
157 "fileName"_a,
"hdu"_a = fits::DEFAULT_HDU,
"metadata"_a = nullptr,
158 "bbox"_a = lsst::geom::Box2I(),
"origin"_a = PARENT,
"conformMasks"_a = false,
159 "allowUnsafe"_a = false);
160 cls.def(py::init<fits::MemFileManager &, int, std::shared_ptr<lsst::daf::base::PropertySet>,
161 lsst::geom::Box2I const &, ImageOrigin, bool, bool>(),
162 "manager"_a,
"hdu"_a = fits::DEFAULT_HDU,
"metadata"_a = nullptr,
163 "bbox"_a = lsst::geom::Box2I(),
"origin"_a = PARENT,
"conformMasks"_a = false,
164 "allowUnsafe"_a = false);
165 cls.def(py::init<fits::Fits &, std::shared_ptr<lsst::daf::base::PropertySet>,
166 lsst::geom::Box2I const &, ImageOrigin, bool, bool>(),
167 "fitsFile"_a,
"metadata"_a = nullptr,
"bbox"_a = lsst::geom::Box2I(),
"origin"_a = PARENT,
168 "conformMasks"_a = false,
"allowUnsafe"_a = false);
171 cls.def(
"__ior__", [](Mask<MaskPixelT> &self, Mask<MaskPixelT> &other) { return self |= other; });
172 cls.def(
"__ior__", [](Mask<MaskPixelT> &
self, MaskPixelT
const other) {
return self |=
other; });
173 cls.def(
"__ior__", [](Mask<MaskPixelT> &
self,
int other) {
return self |=
other; });
174 cls.def(
"__iand__", [](Mask<MaskPixelT> &
self, Mask<MaskPixelT> &
other) {
return self &=
other; });
175 cls.def(
"__iand__", [](Mask<MaskPixelT> &
self, MaskPixelT
const other) {
return self &=
other; });
176 cls.def(
"__iand__", [](Mask<MaskPixelT> &
self,
int other) {
return self &=
other; });
177 cls.def(
"__ixor__", [](Mask<MaskPixelT> &
self, Mask<MaskPixelT> &
other) {
return self ^=
other; });
178 cls.def(
"__ixor__", [](Mask<MaskPixelT> &
self, MaskPixelT
const other) {
return self ^=
other; });
179 cls.def(
"__ixor__", [](Mask<MaskPixelT> &
self,
int other) {
return self ^=
other; });
190 (
void (Mask<MaskPixelT>::*)(fits::MemFileManager &,
201 (
void (Mask<MaskPixelT>::*)(
std::string const &, fits::ImageWriteOptions
const &,
205 "filename"_a,
"options"_a,
"mode"_a =
"w",
208 (
void (Mask<MaskPixelT>::*)(fits::MemFileManager &, fits::ImageWriteOptions
const &,
212 "manager"_a,
"options"_a,
"mode"_a =
"w",
215 (
void (Mask<MaskPixelT>::*)(fits::Fits &, fits::ImageWriteOptions
const &,
219 cls.def_static(
"readFits", (Mask<MaskPixelT>(*)(
std::string const &,
int))Mask<MaskPixelT>::readFits,
221 cls.def_static(
"readFits",
222 (Mask<MaskPixelT>(*)(fits::MemFileManager &,
int))Mask<MaskPixelT>::readFits,
224 cls.def_static(
"interpret", Mask<MaskPixelT>::interpret);
225 cls.def(
"subset", &Mask<MaskPixelT>::subset,
"bbox"_a,
"origin"_a =
PARENT);
226 cls.def(
"getAsString", &Mask<MaskPixelT>::getAsString);
227 cls.def(
"clearAllMaskPlanes", &Mask<MaskPixelT>::clearAllMaskPlanes);
228 cls.def(
"clearMaskPlane", &Mask<MaskPixelT>::clearMaskPlane);
229 cls.def(
"setMaskPlaneValues", &Mask<MaskPixelT>::setMaskPlaneValues);
230 cls.def_static(
"parseMaskPlaneMetadata", Mask<MaskPixelT>::parseMaskPlaneMetadata);
231 cls.def_static(
"clearMaskPlaneDict", Mask<MaskPixelT>::clearMaskPlaneDict);
232 cls.def_static(
"removeMaskPlane", Mask<MaskPixelT>::removeMaskPlane);
233 cls.def(
"removeAndClearMaskPlane", &Mask<MaskPixelT>::removeAndClearMaskPlane,
"name"_a,
234 "removeFromDefault"_a =
false);
235 cls.def_static(
"getMaskPlane", Mask<MaskPixelT>::getMaskPlane);
236 cls.def_static(
"getPlaneBitMask",
237 (MaskPixelT(*)(
const std::string &))Mask<MaskPixelT>::getPlaneBitMask);
238 cls.def_static(
"getPlaneBitMask",
240 cls.def_static(
"getNumPlanesMax", Mask<MaskPixelT>::getNumPlanesMax);
241 cls.def_static(
"getNumPlanesUsed", Mask<MaskPixelT>::getNumPlanesUsed);
242 cls.def(
"getMaskPlaneDict", &Mask<MaskPixelT>::getMaskPlaneDict);
243 cls.def(
"printMaskPlanes", &Mask<MaskPixelT>::printMaskPlanes);
244 cls.def_static(
"addMaskPlanesToMetadata", Mask<MaskPixelT>::addMaskPlanesToMetadata);
245 cls.def(
"conformMaskPlanes", &Mask<MaskPixelT>::conformMaskPlanes);
246 cls.def_static(
"addMaskPlane", (
int (*)(
const std::string &))Mask<MaskPixelT>::addMaskPlane);
250 template <
typename PixelT>
253 return wrappers.
wrapType(PyImage<PixelT>(wrappers.
module, (
"Image" + suffix).c_str()), [](
auto &mod,
256 cls.def(py::init<unsigned int, unsigned int, PixelT>(),
"width"_a,
"height"_a,
"intialValue"_a = 0);
257 cls.def(py::init<lsst::geom::Extent2I const &, PixelT>(),
"dimensions"_a = lsst::geom::Extent2I(),
258 "initialValue"_a = 0);
259 cls.def(py::init<lsst::geom::Box2I const &, PixelT>(),
"bbox"_a,
"initialValue"_a = 0);
260 cls.def(py::init<Image<PixelT> const &, lsst::geom::Box2I const &, ImageOrigin const, const bool>(),
261 "rhs"_a,
"bbox"_a,
"origin"_a = PARENT,
"deep"_a = false);
262 cls.def(py::init<ndarray::Array<PixelT, 2, 1> const &, bool, lsst::geom::Point2I const &>(),
263 "array"_a,
"deep"_a = false,
"xy0"_a = lsst::geom::Point2I());
264 cls.def(py::init<std::string const &, int, std::shared_ptr<daf::base::PropertySet>,
265 lsst::geom::Box2I const &, ImageOrigin, bool>(),
266 "fileName"_a,
"hdu"_a = fits::DEFAULT_HDU,
"metadata"_a = nullptr,
267 "bbox"_a = lsst::geom::Box2I(),
"origin"_a = PARENT,
"allowUnsafe"_a = false);
268 cls.def(py::init<fits::MemFileManager &, int, std::shared_ptr<daf::base::PropertySet>,
269 lsst::geom::Box2I const &, ImageOrigin, bool>(),
270 "manager"_a,
"hdu"_a = fits::DEFAULT_HDU,
"metadata"_a = nullptr,
271 "bbox"_a = lsst::geom::Box2I(),
"origin"_a = PARENT,
"allowUnsafe"_a = false);
272 cls.def(py::init<fits::Fits &, std::shared_ptr<daf::base::PropertySet>, lsst::geom::Box2I const &,
273 ImageOrigin, bool>(),
274 "fitsFile"_a,
"metadata"_a = nullptr,
"bbox"_a = lsst::geom::Box2I(),
"origin"_a = PARENT,
275 "allowUnsafe"_a = false);
278 cls.def(
"__iadd__", [](Image<PixelT> &self, PixelT const &other) { return self += other; });
279 cls.def(
"__iadd__", [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self +=
other; });
281 return self +=
other;
283 cls.def(
"__isub__", [](Image<PixelT> &
self,
PixelT const &
other) {
return self -=
other; });
284 cls.def(
"__isub__", [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self -=
other; });
286 return self -=
other;
288 cls.def(
"__imul__", [](Image<PixelT> &
self,
PixelT const &
other) {
return self *=
other; });
289 cls.def(
"__imul__", [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self *=
other; });
290 cls.def(
"__itruediv__", [](Image<PixelT> &
self,
PixelT const &
other) {
return self /=
other; });
291 cls.def(
"__itruediv__",
292 [](Image<PixelT> &
self, Image<PixelT>
const &
other) {
return self /=
other; });
296 cls.def(
"scaledMinus", &Image<PixelT>::scaledMinus);
297 cls.def(
"scaledMultiplies", &Image<PixelT>::scaledMultiplies);
298 cls.def(
"scaledDivides", &Image<PixelT>::scaledDivides);
300 cls.def(
"subset", &Image<PixelT>::subset,
"bbox"_a,
"origin"_a =
PARENT);
308 (
void (Image<PixelT>::*)(fits::MemFileManager &,
318 (
void (Image<PixelT>::*)(
std::string const &, fits::ImageWriteOptions
const &,
322 "filename"_a,
"options"_a,
"mode"_a =
"w",
326 (
void (Image<PixelT>::*)(fits::MemFileManager &, fits::ImageWriteOptions
const &,
330 "manager"_a,
"options"_a,
"mode"_a =
"w",
334 (
void (Image<PixelT>::*)(fits::Fits &, fits::ImageWriteOptions
const &,
341 cls.def_static(
"readFits", (Image<PixelT>(*)(
std::string const &,
int))Image<PixelT>::readFits,
343 cls.def_static(
"readFits", (Image<PixelT>(*)(fits::MemFileManager &,
int))Image<PixelT>::readFits,
345 cls.def(
"sqrt", &Image<PixelT>::sqrt);
349 template <
typename PixelT>
353 PyDecoratedImage<PixelT>(wrappers.
module, (
"DecoratedImage" + suffix).c_str()),
354 [](
auto &mod,
auto &cls) {
355 cls.def(py::init<const lsst::geom::Extent2I &>(),
"dimensions"_a = lsst::geom::Extent2I());
356 cls.def(py::init<const lsst::geom::Box2I &>(),
"bbox"_a);
357 cls.def(py::init<std::shared_ptr<Image<PixelT>>>(),
"rhs"_a);
358 cls.def(py::init<DecoratedImage<PixelT> const &, const bool>(),
"rhs"_a,
"deep"_a = false);
359 cls.def(py::init<std::string const &, const int, lsst::geom::Box2I const &, ImageOrigin const,
361 "fileName"_a,
"hdu"_a = fits::DEFAULT_HDU,
"bbox"_a = lsst::geom::Box2I(),
362 "origin"_a = PARENT,
"allowUnsafe"_a = false);
364 cls.def(
"getMetadata", &DecoratedImage<PixelT>::getMetadata);
365 cls.def(
"setMetadata", &DecoratedImage<PixelT>::setMetadata);
366 cls.def(
"getWidth", &DecoratedImage<PixelT>::getWidth);
367 cls.def(
"getHeight", &DecoratedImage<PixelT>::getHeight);
368 cls.def(
"getX0", &DecoratedImage<PixelT>::getX0);
369 cls.def(
"getY0", &DecoratedImage<PixelT>::getY0);
370 cls.def(
"getDimensions", &DecoratedImage<PixelT>::getDimensions);
371 cls.def(
"swap", &DecoratedImage<PixelT>::swap);
373 py::overload_cast<std::string const &, std::shared_ptr<daf::base::PropertySet const>,
374 std::string const &>(&DecoratedImage<PixelT>::writeFits,
376 "filename"_a,
"metadata"_a = std::shared_ptr<daf::base::PropertyList>(),
379 py::overload_cast<std::string const &, fits::ImageWriteOptions const &,
380 std::shared_ptr<daf::base::PropertySet const>, std::string const &>(
381 &DecoratedImage<PixelT>::writeFits, py::const_),
382 "filename"_a,
"options"_a,
"metadata"_a = std::shared_ptr<daf::base::PropertyList>(),
384 cls.def(
"getImage", py::overload_cast<>(&DecoratedImage<PixelT>::getImage));
385 cls.def_property_readonly(
"image", py::overload_cast<>(&DecoratedImage<PixelT>::getImage));
386 cls.def(
"getGain", &DecoratedImage<PixelT>::getGain);
387 cls.def(
"setGain", &DecoratedImage<PixelT>::setGain);
392 template <
typename PixelT>
393 static void addImageSliceOperators(
394 py::class_<Image<PixelT>,
std::shared_ptr<Image<PixelT>>, ImageBase<PixelT>> &cls) {
397 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self +
other; },
401 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self -
other; },
405 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self *
other; },
409 [](Image<PixelT>
const &
self, ImageSlice<PixelT>
const &
other) {
return self /
other; },
411 cls.def(
"__iadd__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
415 cls.def(
"__isub__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
419 cls.def(
"__imul__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
423 cls.def(
"__itruediv__", [](Image<PixelT> &
self, ImageSlice<PixelT>
const &
other) {
429 template <
typename PixelT,
typename PyClass>
430 static void addGeneralizedCopyConstructors(
PyClass &cls) {
431 cls.def(
py::init<Image<int>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
432 cls.def(
py::init<Image<float>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
433 cls.def(
py::init<Image<double>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
434 cls.def(
py::init<Image<std::uint16_t>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
435 cls.def(
py::init<Image<std::uint64_t>
const &,
const bool>(),
"rhs"_a,
"deep"_a =
false);
437 cls.def(
"convertI", [](Image<PixelT>
const &
self) {
return Image<int>(
self,
true); });
438 cls.def(
"convertF", [](Image<PixelT>
const &
self) {
return Image<float>(
self,
true); });
439 cls.def(
"convertD", [](Image<PixelT>
const &
self) {
return Image<double>(
self,
true); });
440 cls.def(
"convertU", [](Image<PixelT>
const &
self) {
return Image<std::uint16_t>(
self,
true); });
441 cls.def(
"convertL", [](Image<PixelT>
const &
self) {
return Image<std::uint64_t>(
self,
true); });
443 cls.def(
"convertFloat", [](Image<PixelT>
const &
self) {
return Image<float>(
self,
true); });
444 cls.def(
"convertDouble", [](Image<PixelT>
const &
self) {
return Image<double>(
self,
true); });
451 wrappers.
wrapType(py::enum_<ImageOrigin>(wrappers.
module,
"ImageOrigin"), [](
auto &mod,
auto &enm) {
452 enm.value(
"PARENT", ImageOrigin::PARENT);
453 enm.value(
"LOCAL", ImageOrigin::LOCAL);
457 declareImageBase<int>(wrappers,
"I");
458 declareImageBase<float>(wrappers,
"F");
459 declareImageBase<double>(wrappers,
"D");
460 declareImageBase<std::uint16_t>(wrappers,
"U");
461 declareImageBase<std::uint64_t>(wrappers,
"L");
464 declareMask<MaskPixel>(wrappers,
"X");
466 auto clsImageI = declareImage<int>(wrappers,
"I");
467 auto clsImageF = declareImage<float>(wrappers,
"F");
468 auto clsImageD = declareImage<double>(wrappers,
"D");
469 auto clsImageU = declareImage<std::uint16_t>(wrappers,
"U");
470 auto clsImageL = declareImage<std::uint64_t>(wrappers,
"L");
473 addGeneralizedCopyConstructors<int>(clsImageI);
474 addGeneralizedCopyConstructors<float>(clsImageF);
475 addGeneralizedCopyConstructors<double>(clsImageD);
476 addGeneralizedCopyConstructors<std::uint16_t>(clsImageU);
477 addGeneralizedCopyConstructors<std::uint64_t>(clsImageL);
480 addImageSliceOperators<float>(clsImageF);
481 addImageSliceOperators<double>(clsImageD);
483 declareDecoratedImage<int>(wrappers,
"I");
484 declareDecoratedImage<float>(wrappers,
"F");
485 declareDecoratedImage<double>(wrappers,
"D");
486 declareDecoratedImage<std::uint16_t>(wrappers,
"U");
487 declareDecoratedImage<std::uint64_t>(wrappers,
"L");
491 declareCastConstructor<int, float>(clsImageF);
492 declareCastConstructor<int, double>(clsImageD);
494 declareCastConstructor<float, double>(clsImageD);
496 declareCastConstructor<double, float>(clsImageF);
498 declareCastConstructor<std::uint16_t, float>(clsImageF);
499 declareCastConstructor<std::uint16_t, double>(clsImageD);
501 declareCastConstructor<std::uint64_t, float>(clsImageF);
502 declareCastConstructor<std::uint64_t, double>(clsImageD);
ItemVariant const * other
Represent a 2-dimensional array of bitmask pixels.
A Function taking two arguments.
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.
void finish()
Invoke all deferred wrapper-declaring callables.
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 addInheritanceDependency(std::string const &name)
Indicate an external module that provides a base class for a subsequent addType call.
void wrap(WrapperCallback function)
Add a set of wrappers without defining a class.
PYBIND11_MODULE(imageUtils, mod)
void swap(CameraSys &a, CameraSys &b)
const int DEFAULT_HDU
Specify that the default HDU should be read.
void checkBounds(geom::Point2I const &index, geom::Box2I const &bbox)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
lsst::geom::Box2I bboxFromMetadata(daf::base::PropertySet &metadata)
Determine the image bounding box from its metadata (FITS header)
void scaledPlus(OutImageT &outImage, double c1, InImageT const &inImage1, double c2, InImageT const &inImage2)
Compute the scaled sum of two images.
py::class_< PixelAreaBoundedField, std::shared_ptr< PixelAreaBoundedField >, BoundedField > PyClass
def writeFits(filename, stamp_ims, metadata, write_mask, write_variance)
A base class for image defects.