LSSTApplications  19.0.0-14-gb0260a2+72efe9b372,20.0.0+7927753e06,20.0.0+8829bf0056,20.0.0+995114c5d2,20.0.0+b6f4b2abd1,20.0.0+bddc4f4cbe,20.0.0-1-g253301a+8829bf0056,20.0.0-1-g2b7511a+0d71a2d77f,20.0.0-1-g5b95a8c+7461dd0434,20.0.0-12-g321c96ea+23efe4bbff,20.0.0-16-gfab17e72e+fdf35455f6,20.0.0-2-g0070d88+ba3ffc8f0b,20.0.0-2-g4dae9ad+ee58a624b3,20.0.0-2-g61b8584+5d3db074ba,20.0.0-2-gb780d76+d529cf1a41,20.0.0-2-ged6426c+226a441f5f,20.0.0-2-gf072044+8829bf0056,20.0.0-2-gf1f7952+ee58a624b3,20.0.0-20-geae50cf+e37fec0aee,20.0.0-25-g3dcad98+544a109665,20.0.0-25-g5eafb0f+ee58a624b3,20.0.0-27-g64178ef+f1f297b00a,20.0.0-3-g4cc78c6+e0676b0dc8,20.0.0-3-g8f21e14+4fd2c12c9a,20.0.0-3-gbd60e8c+187b78b4b8,20.0.0-3-gbecbe05+48431fa087,20.0.0-38-ge4adf513+a12e1f8e37,20.0.0-4-g97dc21a+544a109665,20.0.0-4-gb4befbc+087873070b,20.0.0-4-gf910f65+5d3db074ba,20.0.0-5-gdfe0fee+199202a608,20.0.0-5-gfbfe500+d529cf1a41,20.0.0-6-g64f541c+d529cf1a41,20.0.0-6-g9a5b7a1+a1cd37312e,20.0.0-68-ga3f3dda+5fca18c6a4,20.0.0-9-g4aef684+e18322736b,w.2020.45
LSSTDataManagementBasePackage
maskedImage.cc
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2008-2017 AURA/LSST.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <https://www.lsstcorp.org/LegalNotices/>.
21  */
22 
23 #include "pybind11/pybind11.h"
24 #include "pybind11/stl.h"
25 
26 #include "lsst/afw/fits.h"
28 
29 namespace py = pybind11;
30 using namespace pybind11::literals;
31 
32 namespace lsst {
33 namespace afw {
34 namespace image {
35 
36 namespace {
37 
38 template <typename ImagePixelT> // only the image type varies; mask and variance are fixed
39 using PyMaskedImage = py::class_<MaskedImage<ImagePixelT>, std::shared_ptr<MaskedImage<ImagePixelT>>>;
40 
49 template <typename FromPixelT, typename ToPixelT>
50 void declareCastConstructor(PyMaskedImage<ToPixelT> &cls) {
51  cls.def(py::init<MaskedImage<FromPixelT> const &, bool const>(), "src"_a, "deep"_a);
52 }
53 
54 template <typename ImagePixelT>
55 PyMaskedImage<ImagePixelT> declareMaskedImage(py::module &mod, const std::string &suffix) {
56  using MI = MaskedImage<ImagePixelT>;
57 
58  py::module::import("lsst.daf.base");
59 
60  PyMaskedImage<ImagePixelT> cls(mod, ("MaskedImage" + suffix).c_str());
61 
62  mod.def("makeMaskedImage", &makeMaskedImage<ImagePixelT, MaskPixel, VariancePixel>, "image"_a,
63  "mask"_a = nullptr, "variance"_a = nullptr);
64 
65  /* Member types and enums */
66 
67  /* Constructors */
68  cls.def(py::init<unsigned int, unsigned int, typename MI::MaskPlaneDict const &>(), "width"_a, "height"_a,
69  "planeDict"_a = typename MI::MaskPlaneDict());
70  cls.def(py::init<lsst::geom::Extent2I, typename MI::MaskPlaneDict const &>(), "dimensions"_a,
71  "planeDict"_a = typename MI::MaskPlaneDict());
72  cls.def(py::init<typename MI::ImagePtr, typename MI::MaskPtr, typename MI::VariancePtr>(), "image"_a,
73  "mask"_a = nullptr, "variance"_a = nullptr);
74  cls.def(py::init<lsst::geom::Box2I const &, typename MI::MaskPlaneDict const &>(), "bbox"_a,
75  "planeDict"_a = typename MI::MaskPlaneDict());
79  bool>(),
80  "fileName"_a, "metadata"_a = nullptr, "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT,
81  "conformMasks"_a = false, "needAllHdus"_a = false, "imageMetadata"_a = nullptr,
82  "maskMetadata"_a = nullptr, "varianceMetadata"_a = nullptr, "allowUnsafe"_a = false);
83  cls.def(py::init<fits::MemFileManager &, std::shared_ptr<daf::base::PropertySet>,
84  lsst::geom::Box2I const &, ImageOrigin, bool, bool,
87  "manager"_a, "metadata"_a = nullptr, "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT,
88  "conformMasks"_a = false, "needAllHdus"_a = false, "imageMetadata"_a = nullptr,
89  "maskMetadata"_a = nullptr, "varianceMetadata"_a = nullptr, "allowUnsafe"_a = false);
90  cls.def(py::init<MI const &, bool>(), "rhs"_a, "deep"_a = false);
91  cls.def(py::init<MI const &, lsst::geom::Box2I const &, ImageOrigin, bool>(), "rhs"_a, "bbox"_a,
92  "origin"_a = PARENT, "deep"_a = false);
93 
94  /* Operators */
95  cls.def("swap", &MI::swap);
96  cls.def("assign", &MI::assign, "rhs"_a, "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT,
97  py::is_operator() // py::is_operator is a workaround for code in slicing.py
98  // that expects NotImplemented to be returned on failure.
99  );
100 
101  cls.def("subset", &MI::subset, "bbox"_a, "origin"_a = PARENT);
102 
103  cls.def("__iadd__", (MI & (MI::*)(ImagePixelT const)) & MI::operator+=);
104  cls.def("__iadd__", (MI & (MI::*)(MI const &)) & MI::operator+=);
105  cls.def("__iadd__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator+=);
106  cls.def("__iadd__", (MI & (MI::*)(math::Function2<double> const &)) & MI::operator+=);
107  cls.def("scaledPlus", &MI::scaledPlus);
108  cls.def("__isub__", (MI & (MI::*)(ImagePixelT const)) & MI::operator-=);
109  cls.def("__isub__", (MI & (MI::*)(MI const &)) & MI::operator-=);
110  cls.def("__isub__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator-=);
111  cls.def("__isub__", (MI & (MI::*)(math::Function2<double> const &)) & MI::operator-=);
112  cls.def("scaledMinus", &MI::scaledMinus);
113  cls.def("__imul__", (MI & (MI::*)(ImagePixelT const)) & MI::operator*=);
114  cls.def("__imul__", (MI & (MI::*)(MI const &)) & MI::operator*=);
115  cls.def("__imul__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator*=);
116  cls.def("scaledMultiplies", &MI::scaledMultiplies);
117  cls.def("__itruediv__", (MI & (MI::*)(ImagePixelT const)) & MI::operator/=);
118  cls.def("__itruediv__", (MI & (MI::*)(MI const &)) & MI::operator/=);
119  cls.def("__itruediv__", (MI & (MI::*)(Image<ImagePixelT> const &)) & MI::operator/=);
120  cls.def("scaledDivides", &MI::scaledDivides);
121 
122  /* Members */
123  cls.def("writeFits",
128  MI::writeFits,
129  "fileName"_a, "metadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
130  "imageMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
132  "varianceMetadata"_a = std::shared_ptr<daf::base::PropertySet const>());
133  cls.def("writeFits",
134  (void (MI::*)(fits::MemFileManager &, std::shared_ptr<daf::base::PropertySet const>,
138  MI::writeFits,
139  "manager"_a, "metadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
140  "imageMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
142  "varianceMetadata"_a = std::shared_ptr<daf::base::PropertySet const>());
143  cls.def("writeFits",
144  (void (MI::*)(fits::Fits &, std::shared_ptr<daf::base::PropertySet const>,
148  MI::writeFits,
149  "fitsfile"_a, "metadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
150  "imageMetadata"_a = std::shared_ptr<daf::base::PropertySet const>(),
152  "varianceMetadata"_a = std::shared_ptr<daf::base::PropertySet const>());
153 
154  cls.def("writeFits",
155  [](MI &self, std::string const &filename, fits::ImageWriteOptions const &imageOptions,
156  fits::ImageWriteOptions const &maskOptions, fits::ImageWriteOptions const &varianceOptions,
158  self.writeFits(filename, imageOptions, maskOptions, varianceOptions, header);
159  },
160  "filename"_a, "imageOptions"_a, "maskOptions"_a, "varianceOptions"_a,
162  cls.def("writeFits",
163  [](MI &self, fits::MemFileManager &manager, fits::ImageWriteOptions const &imageOptions,
164  fits::ImageWriteOptions const &maskOptions, fits::ImageWriteOptions const &varianceOptions,
166  self.writeFits(manager, imageOptions, maskOptions, varianceOptions, header);
167  },
168  "manager"_a, "imageOptions"_a, "maskOptions"_a, "varianceOptions"_a,
170  cls.def("writeFits",
171  [](MI &self, fits::Fits &fits, fits::ImageWriteOptions const &imageOptions,
172  fits::ImageWriteOptions const &maskOptions, fits::ImageWriteOptions const &varianceOptions,
174  self.writeFits(fits, imageOptions, maskOptions, varianceOptions, header);
175  },
176  "fits"_a, "imageOptions"_a, "maskOptions"_a, "varianceOptions"_a,
178 
179  cls.def_static("readFits", (MI(*)(std::string const &))MI::readFits, "filename"_a);
180  cls.def_static("readFits", (MI(*)(fits::MemFileManager &))MI::readFits, "manager"_a);
181  cls.def("getImage", &MI::getImage);
182  cls.def("setImage", &MI::setImage);
183  cls.def_property("image", &MI::getImage, &MI::setImage);
184  cls.def("getMask", &MI::getMask);
185  cls.def("setMask", &MI::setMask);
186  cls.def_property("mask", &MI::getMask, &MI::setMask);
187  cls.def("getVariance", &MI::getVariance);
188  cls.def("setVariance", &MI::setVariance);
189  cls.def_property("variance", &MI::getVariance, &MI::setVariance);
190  cls.def("getWidth", &MI::getWidth);
191  cls.def("getHeight", &MI::getHeight);
192  cls.def("getDimensions", &MI::getDimensions);
193  cls.def("getBBox", &MI::getBBox, "origin"_a = PARENT);
194  cls.def("getX0", &MI::getX0);
195  cls.def("getY0", &MI::getY0);
196  cls.def("getXY0", &MI::getXY0);
197  cls.def("setXY0", (void (MI::*)(int const, int const)) & MI::setXY0, "x0"_a, "y0"_a);
198  cls.def("setXY0", (void (MI::*)(lsst::geom::Point2I const)) & MI::setXY0, "origin"_a);
199  cls.def("indexToPosition", &MI::indexToPosition);
200  cls.def("positionToIndex", &MI::positionToIndex);
201 
202  return cls;
203 }
204 
205 template <typename ImagePixelT> // addtional template types do not seem to be needed
206 void declareMakeMaskedImage(py::module &mod) {
207  mod.def("makeMaskedImage", makeMaskedImage<ImagePixelT, MaskPixel, VariancePixel>, "image"_a,
208  "mask"_a = nullptr, "variance"_a = nullptr);
209 }
210 
211 template <typename ImagePixelT1, typename ImagePixelT2>
212 void declareImagesOverlap(py::module &mod) {
213  // wrap both the Image and MaskedImage versions of imagesOverlap here, as wrapping
214  // the Image version in the Image wrapper results in it being invisible in lsst.afw.image
215  mod.def("imagesOverlap",
216  py::overload_cast<ImageBase<ImagePixelT1> const &, ImageBase<ImagePixelT2> const &>(
217  &imagesOverlap<ImagePixelT1, ImagePixelT2>),
218  "image1"_a, "image2"_a);
219 
220  mod.def("imagesOverlap",
221  py::overload_cast<MaskedImage<ImagePixelT1> const &, MaskedImage<ImagePixelT2> const &>(
222  &imagesOverlap<ImagePixelT1, ImagePixelT2>),
223  "image1"_a, "image2"_a);
224 }
225 
226 } // namespace
227 
228 PYBIND11_MODULE(maskedImage, mod) {
229  py::module::import("lsst.afw.image.image");
230 
231  auto clsMaskedImageF = declareMaskedImage<float>(mod, "F");
232  auto clsMaskedImageD = declareMaskedImage<double>(mod, "D");
233  auto clsMaskedImageI = declareMaskedImage<int>(mod, "I");
234  auto clsMaskedImageU = declareMaskedImage<std::uint16_t>(mod, "U");
235  auto clsMaskedImageL = declareMaskedImage<std::uint64_t>(mod, "L");
236 
237  // Declare constructors for casting all exposure types to to float and double
238  // (the only two types of casts that Python supports)
239  declareCastConstructor<int, float>(clsMaskedImageF);
240  declareCastConstructor<int, double>(clsMaskedImageD);
241  declareCastConstructor<float, double>(clsMaskedImageD);
242  declareCastConstructor<double, float>(clsMaskedImageF);
243  declareCastConstructor<std::uint16_t, float>(clsMaskedImageF);
244  declareCastConstructor<std::uint16_t, double>(clsMaskedImageD);
245  declareCastConstructor<std::uint64_t, float>(clsMaskedImageF);
246  declareCastConstructor<std::uint64_t, double>(clsMaskedImageD);
247 
248  /* Module level */
249  declareMakeMaskedImage<int>(mod);
250  declareMakeMaskedImage<float>(mod);
251  declareMakeMaskedImage<double>(mod);
252  declareMakeMaskedImage<std::uint16_t>(mod);
253  declareMakeMaskedImage<std::uint64_t>(mod);
254 
255  declareImagesOverlap<int, int>(mod);
256  declareImagesOverlap<int, float>(mod);
257  declareImagesOverlap<int, double>(mod);
258  declareImagesOverlap<int, std::uint16_t>(mod);
259  declareImagesOverlap<int, std::uint64_t>(mod);
260 
261  declareImagesOverlap<float, int>(mod);
262  declareImagesOverlap<float, float>(mod);
263  declareImagesOverlap<float, double>(mod);
264  declareImagesOverlap<float, std::uint16_t>(mod);
265  declareImagesOverlap<float, std::uint64_t>(mod);
266 
267  declareImagesOverlap<double, int>(mod);
268  declareImagesOverlap<double, float>(mod);
269  declareImagesOverlap<double, double>(mod);
270  declareImagesOverlap<double, std::uint16_t>(mod);
271  declareImagesOverlap<double, std::uint64_t>(mod);
272 
273  declareImagesOverlap<std::uint16_t, int>(mod);
274  declareImagesOverlap<std::uint16_t, float>(mod);
275  declareImagesOverlap<std::uint16_t, double>(mod);
276  declareImagesOverlap<std::uint16_t, std::uint16_t>(mod);
277  declareImagesOverlap<std::uint16_t, std::uint64_t>(mod);
278 
279  declareImagesOverlap<std::uint64_t, int>(mod);
280  declareImagesOverlap<std::uint64_t, float>(mod);
281  declareImagesOverlap<std::uint64_t, double>(mod);
282  declareImagesOverlap<std::uint64_t, std::uint16_t>(mod);
283  declareImagesOverlap<std::uint64_t, std::uint64_t>(mod);
284 }
285 } // namespace image
286 } // namespace afw
287 } // namespace lsst
lsst::afw::image
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Definition: imageAlgorithm.dox:1
std::string
STL class.
std::shared_ptr
STL class.
lsst::afw::image::detail::MaskPlaneDict
std::map< std::string, int > MaskPlaneDict
Definition: Mask.h:58
lsst::afw::image::positionToIndex
int positionToIndex(double pos)
Convert image position to nearest integer index.
Definition: ImageUtils.h:69
lsst::afw::math::scaledPlus
void scaledPlus(OutImageT &outImage, double c1, InImageT const &inImage1, double c2, InImageT const &inImage2)
Compute the scaled sum of two images.
Definition: ConvolveImage.cc:162
MaskedImage.h
fits.h
lsst::afw
Definition: imageAlgorithm.dox:1
lsst::afw::image::indexToPosition
double indexToPosition(double ind)
Convert image index to image position.
Definition: ImageUtils.h:55
lsst::afw::geom.transform.transformContinued.cls
cls
Definition: transformContinued.py:33
fits
Fits * fits
Definition: FitsWriter.cc:90
lsst::afw::image::PYBIND11_MODULE
PYBIND11_MODULE(maskedImage, mod)
Definition: maskedImage.cc:228
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
lsst::geom::Point< int, 2 >
lsst::afw::cameraGeom::swap
void swap(CameraSys &a, CameraSys &b)
Definition: CameraSys.h:157
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::afw::image::PARENT
@ PARENT
Definition: ImageBase.h:94
pybind11
Definition: _GenericMap.cc:40
lsst::afw::image::ImageOrigin
ImageOrigin
Definition: ImageBase.h:94
lsst::utils.tests.init
def init()
Definition: tests.py:59
lsst::meas::modelfit.psf.psfContinued.module
module
Definition: psfContinued.py:42