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
_maskedImage.cc
Go to the documentation of this file.
1/*
2 * This file is part of afw.
3 *
4 * Developed for the LSST Data Management System.
5 * This product includes software developed by the LSST Project
6 * (https://www.lsst.org).
7 * See the COPYRIGHT file at the top-level directory of this distribution
8 * for details of code ownership.
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#include "pybind11/pybind11.h"
25#include "pybind11/stl.h"
27
28#include "lsst/afw/fits.h"
30
31namespace py = pybind11;
32using namespace pybind11::literals;
33
34namespace lsst {
35namespace afw {
36namespace image {
37
38namespace {
39
40template <typename ImagePixelT> // only the image type varies; mask and variance are fixed
41using PyMaskedImage = py::class_<MaskedImage<ImagePixelT>, std::shared_ptr<MaskedImage<ImagePixelT>>>;
42
51template <typename FromPixelT, typename ToPixelT>
52void declareCastConstructor(PyMaskedImage<ToPixelT> &cls) {
53 cls.def(py::init<MaskedImage<FromPixelT> const &, bool const>(), "src"_a, "deep"_a);
54}
55
56template <typename ImagePixelT>
57PyMaskedImage<ImagePixelT> declareMaskedImage(lsst::cpputils::python::WrapperCollection &wrappers,
58 const std::string &suffix) {
59 using MI = MaskedImage<ImagePixelT>;
60
61 return wrappers.wrapType(
62 PyMaskedImage<ImagePixelT>(wrappers.module, ("MaskedImage" + suffix).c_str()),
63 [](auto &mod, auto &cls) {
64 mod.def("makeMaskedImage", &makeMaskedImage<ImagePixelT, MaskPixel, VariancePixel>, "image"_a,
65 "mask"_a = nullptr, "variance"_a = nullptr);
66
67 /* Member types and enums */
68
69 /* Constructors */
70 cls.def(py::init<unsigned int, unsigned int, typename MI::MaskPlaneDict const &>(), "width"_a,
71 "height"_a, "planeDict"_a = typename MI::MaskPlaneDict());
72 cls.def(py::init<lsst::geom::Extent2I, typename MI::MaskPlaneDict const &>(), "dimensions"_a,
73 "planeDict"_a = typename MI::MaskPlaneDict());
74 cls.def(py::init<typename MI::ImagePtr, typename MI::MaskPtr, typename MI::VariancePtr>(),
75 "image"_a, "mask"_a = nullptr, "variance"_a = nullptr);
76 cls.def(py::init<lsst::geom::Box2I const &, typename MI::MaskPlaneDict const &>(), "bbox"_a,
77 "planeDict"_a = typename MI::MaskPlaneDict());
78 cls.def(py::init<std::string const &, std::shared_ptr<daf::base::PropertySet>,
79 lsst::geom::Box2I const &, ImageOrigin, bool, bool,
80 std::shared_ptr<daf::base::PropertySet>,
81 std::shared_ptr<daf::base::PropertySet>,
82 std::shared_ptr<daf::base::PropertySet>, bool>(),
83 "fileName"_a, "metadata"_a = nullptr, "bbox"_a = lsst::geom::Box2I(),
84 "origin"_a = PARENT, "conformMasks"_a = false, "needAllHdus"_a = false,
85 "imageMetadata"_a = nullptr, "maskMetadata"_a = nullptr,
86 "varianceMetadata"_a = nullptr, "allowUnsafe"_a = false);
87 cls.def(py::init<fits::MemFileManager &, std::shared_ptr<daf::base::PropertySet>,
88 lsst::geom::Box2I const &, ImageOrigin, bool, bool,
89 std::shared_ptr<daf::base::PropertySet>,
90 std::shared_ptr<daf::base::PropertySet>,
91 std::shared_ptr<daf::base::PropertySet>, bool>(),
92 "manager"_a, "metadata"_a = nullptr, "bbox"_a = lsst::geom::Box2I(),
93 "origin"_a = PARENT, "conformMasks"_a = false, "needAllHdus"_a = false,
94 "imageMetadata"_a = nullptr, "maskMetadata"_a = nullptr,
95 "varianceMetadata"_a = nullptr, "allowUnsafe"_a = false);
96 cls.def(py::init<MI const &, bool>(), "rhs"_a, "deep"_a = false);
97 cls.def(py::init<MI const &, lsst::geom::Box2I const &, ImageOrigin, bool>(), "rhs"_a,
98 "bbox"_a, "origin"_a = PARENT, "deep"_a = false);
99
100 /* Operators */
101 cls.def("swap", &MI::swap);
102 cls.def("assign", &MI::assign, "rhs"_a, "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT,
103 py::is_operator() // py::is_operator is a workaround for code in slicing.py
104 // that expects NotImplemented to be returned on failure.
105 );
106
107 cls.def("subset", &MI::subset, "bbox"_a, "origin"_a = PARENT);
108
109 cls.def("__iadd__", (MI & (MI::*)(ImagePixelT const)) & MI::operator+=);
110 cls.def("__iadd__", (MI & (MI::*)(MI const &)) & MI::operator+=);
111 cls.def("__iadd__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator+=);
112 cls.def("__iadd__", (MI & (MI::*)(math::Function2<double> const &)) & MI::operator+=);
113 cls.def("scaledPlus", &MI::scaledPlus);
114 cls.def("__isub__", (MI & (MI::*)(ImagePixelT const)) & MI::operator-=);
115 cls.def("__isub__", (MI & (MI::*)(MI const &)) & MI::operator-=);
116 cls.def("__isub__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator-=);
117 cls.def("__isub__", (MI & (MI::*)(math::Function2<double> const &)) & MI::operator-=);
118 cls.def("scaledMinus", &MI::scaledMinus);
119 cls.def("__imul__", (MI & (MI::*)(ImagePixelT const)) & MI::operator*=);
120 cls.def("__imul__", (MI & (MI::*)(MI const &)) & MI::operator*=);
121 cls.def("__imul__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator*=);
122 cls.def("scaledMultiplies", &MI::scaledMultiplies);
123 cls.def("__itruediv__", (MI & (MI::*)(ImagePixelT const)) & MI::operator/=);
124 cls.def("__itruediv__", (MI & (MI::*)(MI const &)) & MI::operator/=);
125 cls.def("__itruediv__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator/=);
126 cls.def("scaledDivides", &MI::scaledDivides);
127
128 /* Members */
129 cls.def("writeFits",
130 (void (MI::*)(std::string const &, std::shared_ptr<daf::base::PropertySet const>,
131 std::shared_ptr<daf::base::PropertySet const>,
132 std::shared_ptr<daf::base::PropertySet const>,
133 std::shared_ptr<daf::base::PropertySet const>) const) &
134 MI::writeFits,
135 "fileName"_a, "metadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
136 "imageMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
137 "maskMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
138 "varianceMetadata"_a = std::shared_ptr<daf::base::PropertySet const>());
139 cls.def("writeFits",
140 (void (MI::*)(fits::MemFileManager &, std::shared_ptr<daf::base::PropertySet const>,
141 std::shared_ptr<daf::base::PropertySet const>,
142 std::shared_ptr<daf::base::PropertySet const>,
143 std::shared_ptr<daf::base::PropertySet const>) const) &
144 MI::writeFits,
145 "manager"_a, "metadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
146 "imageMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
147 "maskMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
148 "varianceMetadata"_a = std::shared_ptr<daf::base::PropertySet const>());
149 cls.def("writeFits",
150 (void (MI::*)(fits::Fits &, std::shared_ptr<daf::base::PropertySet const>,
151 std::shared_ptr<daf::base::PropertySet const>,
152 std::shared_ptr<daf::base::PropertySet const>,
153 std::shared_ptr<daf::base::PropertySet const>) const) &
154 MI::writeFits,
155 "fitsfile"_a, "metadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
156 "imageMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
157 "maskMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
158 "varianceMetadata"_a = std::shared_ptr<daf::base::PropertySet const>());
159
160 cls.def(
161 "writeFits",
162 [](MI &self, std::string const &filename, fits::ImageWriteOptions const &imageOptions,
163 fits::ImageWriteOptions const &maskOptions,
164 fits::ImageWriteOptions const &varianceOptions,
165 std::shared_ptr<daf::base::PropertySet const> header) {
166 self.writeFits(filename, imageOptions, maskOptions, varianceOptions, header);
167 },
168 "filename"_a, "imageOptions"_a, "maskOptions"_a, "varianceOptions"_a,
170 cls.def(
171 "writeFits",
172 [](MI &self, fits::MemFileManager &manager,
173 fits::ImageWriteOptions const &imageOptions,
174 fits::ImageWriteOptions const &maskOptions,
175 fits::ImageWriteOptions const &varianceOptions,
177 self.writeFits(manager, imageOptions, maskOptions, varianceOptions, header);
178 },
179 "manager"_a, "imageOptions"_a, "maskOptions"_a, "varianceOptions"_a,
181 cls.def(
182 "writeFits",
183 [](MI &self, fits::Fits &fits, fits::ImageWriteOptions const &imageOptions,
184 fits::ImageWriteOptions const &maskOptions,
185 fits::ImageWriteOptions const &varianceOptions,
187 self.writeFits(fits, imageOptions, maskOptions, varianceOptions, header);
188 },
189 "fits"_a, "imageOptions"_a, "maskOptions"_a, "varianceOptions"_a,
191
192 cls.def_static("readFits", (MI(*)(std::string const &))MI::readFits, "filename"_a);
193 cls.def_static("readFits", (MI(*)(fits::MemFileManager &))MI::readFits, "manager"_a);
194 cls.def("getImage", &MI::getImage);
195 cls.def("setImage", &MI::setImage);
196 cls.def_property("image", &MI::getImage, &MI::setImage);
197 cls.def("getMask", &MI::getMask);
198 cls.def("setMask", &MI::setMask);
199 cls.def_property("mask", &MI::getMask, &MI::setMask);
200 cls.def("getVariance", &MI::getVariance);
201 cls.def("setVariance", &MI::setVariance);
202 cls.def_property("variance", &MI::getVariance, &MI::setVariance);
203 cls.def("getWidth", &MI::getWidth);
204 cls.def("getHeight", &MI::getHeight);
205 cls.def("getDimensions", &MI::getDimensions);
206 cls.def("getBBox", &MI::getBBox, "origin"_a = PARENT);
207 cls.def("getX0", &MI::getX0);
208 cls.def("getY0", &MI::getY0);
209 cls.def("getXY0", &MI::getXY0);
210 cls.def("setXY0", (void (MI::*)(int const, int const)) & MI::setXY0, "x0"_a, "y0"_a);
211 cls.def("setXY0", (void (MI::*)(lsst::geom::Point2I const)) & MI::setXY0, "origin"_a);
212 cls.def("indexToPosition", &MI::indexToPosition);
213 cls.def("positionToIndex", &MI::positionToIndex);
214 });
215}
216
217template <typename ImagePixelT> // addtional template types do not seem to be needed
218void declareMakeMaskedImage(lsst::cpputils::python::WrapperCollection &wrappers) {
219 wrappers.wrap([](auto &mod) {
220 mod.def("makeMaskedImage", makeMaskedImage<ImagePixelT, MaskPixel, VariancePixel>, "image"_a,
221 "mask"_a = nullptr, "variance"_a = nullptr);
222 });
223}
224
225template <typename ImagePixelT1, typename ImagePixelT2>
226void declareImagesOverlap(lsst::cpputils::python::WrapperCollection &wrappers) {
227 // wrap both the Image and MaskedImage versions of imagesOverlap here, as wrapping
228 // the Image version in the Image wrapper results in it being invisible in lsst.afw.image
229 wrappers.wrap([](auto &mod) {
230 mod.def("imagesOverlap",
231 py::overload_cast<ImageBase<ImagePixelT1> const &, ImageBase<ImagePixelT2> const &>(
232 &imagesOverlap<ImagePixelT1, ImagePixelT2>),
233 "image1"_a, "image2"_a);
234
235 mod.def("imagesOverlap",
236 py::overload_cast<MaskedImage<ImagePixelT1> const &, MaskedImage<ImagePixelT2> const &>(
237 &imagesOverlap<ImagePixelT1, ImagePixelT2>),
238 "image1"_a, "image2"_a);
239 });
240}
241
242} // namespace
243
244PYBIND11_MODULE(_maskedImage, mod) {
245 lsst::cpputils::python::WrapperCollection wrappers(mod, "lsst.afw.image._maskedImage");
246 wrappers.addSignatureDependency("lsst.afw.image._image");
247 wrappers.addInheritanceDependency("lsst.daf.base");
248
249 auto clsMaskedImageF = declareMaskedImage<float>(wrappers, "F");
250 auto clsMaskedImageD = declareMaskedImage<double>(wrappers, "D");
251 auto clsMaskedImageI = declareMaskedImage<int>(wrappers, "I");
252 auto clsMaskedImageU = declareMaskedImage<std::uint16_t>(wrappers, "U");
253 auto clsMaskedImageL = declareMaskedImage<std::uint64_t>(wrappers, "L");
254
255 // Declare constructors for casting all exposure types to to float and double
256 // (the only two types of casts that Python supports)
257 declareCastConstructor<int, float>(clsMaskedImageF);
258 declareCastConstructor<int, double>(clsMaskedImageD);
259 declareCastConstructor<float, double>(clsMaskedImageD);
260 declareCastConstructor<double, float>(clsMaskedImageF);
261 declareCastConstructor<std::uint16_t, float>(clsMaskedImageF);
262 declareCastConstructor<std::uint16_t, double>(clsMaskedImageD);
263 declareCastConstructor<std::uint64_t, float>(clsMaskedImageF);
264 declareCastConstructor<std::uint64_t, double>(clsMaskedImageD);
265
266 /* Module level */
267 declareMakeMaskedImage<int>(wrappers);
268 declareMakeMaskedImage<float>(wrappers);
269 declareMakeMaskedImage<double>(wrappers);
270 declareMakeMaskedImage<std::uint16_t>(wrappers);
271 declareMakeMaskedImage<std::uint64_t>(wrappers);
272
273 declareImagesOverlap<int, int>(wrappers);
274 declareImagesOverlap<int, float>(wrappers);
275 declareImagesOverlap<int, double>(wrappers);
276 declareImagesOverlap<int, std::uint16_t>(wrappers);
277 declareImagesOverlap<int, std::uint64_t>(wrappers);
278
279 declareImagesOverlap<float, int>(wrappers);
280 declareImagesOverlap<float, float>(wrappers);
281 declareImagesOverlap<float, double>(wrappers);
282 declareImagesOverlap<float, std::uint16_t>(wrappers);
283 declareImagesOverlap<float, std::uint64_t>(wrappers);
284
285 declareImagesOverlap<double, int>(wrappers);
286 declareImagesOverlap<double, float>(wrappers);
287 declareImagesOverlap<double, double>(wrappers);
288 declareImagesOverlap<double, std::uint16_t>(wrappers);
289 declareImagesOverlap<double, std::uint64_t>(wrappers);
290
291 declareImagesOverlap<std::uint16_t, int>(wrappers);
292 declareImagesOverlap<std::uint16_t, float>(wrappers);
293 declareImagesOverlap<std::uint16_t, double>(wrappers);
294 declareImagesOverlap<std::uint16_t, std::uint16_t>(wrappers);
295 declareImagesOverlap<std::uint16_t, std::uint64_t>(wrappers);
296
297 declareImagesOverlap<std::uint64_t, int>(wrappers);
298 declareImagesOverlap<std::uint64_t, float>(wrappers);
299 declareImagesOverlap<std::uint64_t, double>(wrappers);
300 declareImagesOverlap<std::uint64_t, std::uint16_t>(wrappers);
301 declareImagesOverlap<std::uint64_t, std::uint64_t>(wrappers);
302 wrappers.finish();
303}
304} // namespace image
305} // namespace afw
306} // namespace lsst
A helper class for subdividing pybind11 module across multiple translation units (i....
Definition python.h:242
void addSignatureDependency(std::string const &name)
Indicate an external module that provides a type used in function/method signatures.
Definition python.h:357
void wrap(WrapperCallback function)
Add a set of wrappers without defining a class.
Definition python.h:369
void addInheritanceDependency(std::string const &name)
Indicate an external module that provides a base class for a subsequent addType call.
Definition python.h:343
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...
Definition python.h:391
void finish()
Invoke all deferred wrapper-declaring callables.
Definition python.h:435
PYBIND11_MODULE(_gauss2d, m)
Definition pybind11.cc:31
Point< int, 2 > Point2I
Definition Point.h:321