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
_readers.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 "ndarray/pybind11.h"
29
45
46namespace py = pybind11;
47using namespace pybind11::literals;
48
49namespace lsst {
50namespace afw {
51namespace image {
52namespace {
53
54// ImageBaseFitsReader is an implementation detail and is not exposed directly
55// to Python, as we have better ways to share wrapper code between classes
56// at the pybind11 level (e.g. declareCommon below).
57using PyImageFitsReader = py::class_<ImageFitsReader, std::shared_ptr<ImageFitsReader>>;
58using PyMaskFitsReader = py::class_<MaskFitsReader, std::shared_ptr<MaskFitsReader>>;
59using PyMaskedImageFitsReader = py::class_<MaskedImageFitsReader, std::shared_ptr<MaskedImageFitsReader>>;
60using PyExposureFitsReader = py::class_<ExposureFitsReader, std::shared_ptr<ExposureFitsReader>>;
61
62// Declare attributes common to all FitsReaders. Excludes constructors
63// because ExposureFitsReader's don't take an HDU argument.
64template <typename Class, typename... Args>
65void declareCommonMethods(py::class_<Class, Args...> &cls) {
66 cls.def("readBBox", &Class::readBBox, "origin"_a = PARENT);
67 cls.def("readXY0", &Class::readXY0, "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT);
68 cls.def("getFileName", &Class::getFileName);
69 cls.def_property_readonly("fileName", &Class::getFileName);
70}
71
72// Declare attributes common to ImageFitsReader and MaskFitsReader
73template <typename Class, typename... Args>
74void declareSinglePlaneMethods(py::class_<Class, Args...> &cls) {
75 cls.def(py::init<std::string const &, int>(), "fileName"_a, "hdu"_a = fits::DEFAULT_HDU);
76 cls.def(py::init<fits::MemFileManager &, int>(), "manager"_a, "hdu"_a = fits::DEFAULT_HDU);
77 cls.def("readMetadata", &Class::readMetadata);
78 cls.def("readDType", [](Class &self) { return py::dtype(self.readDType()); });
79 cls.def("getHdu", &Class::getHdu);
80 cls.def_property_readonly("hdu", &Class::getHdu);
81 cls.def(
82 "readArray",
83 [](Class &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool allowUnsafe,
84 py::object dtype) {
85 if (dtype.is(py::none())) {
86 dtype = py::dtype(self.readDType());
87 }
88 return cpputils::python::TemplateInvoker().apply(
89 [&](auto t) {
90 return self.template readArray<decltype(t)>(bbox, origin, allowUnsafe);
91 },
92 py::dtype(dtype),
93 cpputils::python::TemplateInvoker::Tag<std::uint16_t, int, float, double,
94 std::uint64_t>());
95 },
96 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "allowUnsafe"_a = false,
97 "dtype"_a = py::none());
98}
99
100// Declare attributes shared by MaskedImageFitsReader and MaskedImageFitsReader.
101template <typename Class, typename... Args>
102void declareMultiPlaneMethods(py::class_<Class, Args...> &cls) {
103 cls.def("readImageDType", [](Class &self) { return py::dtype(self.readImageDType()); });
104 cls.def("readMaskDType", [](Class &self) { return py::dtype(self.readMaskDType()); });
105 cls.def("readVarianceDType", [](Class &self) { return py::dtype(self.readVarianceDType()); });
106 cls.def(
107 "readImage",
108 [](Class &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool allowUnsafe,
109 py::object dtype) {
110 if (dtype.is(py::none())) {
111 dtype = py::dtype(self.readImageDType());
112 }
113 return cpputils::python::TemplateInvoker().apply(
114 [&](auto t) {
115 return self.template readImage<decltype(t)>(bbox, origin, allowUnsafe);
116 },
117 py::dtype(dtype),
118 cpputils::python::TemplateInvoker::Tag<std::uint16_t, int, float, double,
119 std::uint64_t>());
120 },
121 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "allowUnsafe"_a = false,
122 "dtype"_a = py::none());
123 cls.def(
124 "readImageArray",
125 [](Class &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool allowUnsafe,
126 py::object dtype) {
127 if (dtype.is(py::none())) {
128 dtype = py::dtype(self.readImageDType());
129 }
130 return cpputils::python::TemplateInvoker().apply(
131 [&](auto t) {
132 return self.template readImageArray<decltype(t)>(bbox, origin, allowUnsafe);
133 },
134 py::dtype(dtype),
135 cpputils::python::TemplateInvoker::Tag<std::uint16_t, int, float, double,
136 std::uint64_t>());
137 },
138 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "allowUnsafe"_a = false,
139 "dtype"_a = py::none());
140 cls.def(
141 "readMask",
142 [](Class &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool conformMasks,
143 bool allowUnsafe, py::object dtype) {
144 if (dtype.is(py::none())) {
145 dtype = py::dtype(self.readMaskDType());
146 }
147 return cpputils::python::TemplateInvoker().apply(
148 [&](auto t) {
149 return self.template readMask<decltype(t)>(bbox, origin, conformMasks,
150 allowUnsafe);
151 },
152 py::dtype(dtype), cpputils::python::TemplateInvoker::Tag<MaskPixel>());
153 },
154 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "conformMasks"_a = false,
155 "allowUnsafe"_a = false, "dtype"_a = py::none());
156 cls.def(
157 "readMaskArray",
158 [](Class &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool allowUnsafe,
159 py::object dtype) {
160 if (dtype.is(py::none())) {
161 dtype = py::dtype(self.readMaskDType());
162 }
163 return cpputils::python::TemplateInvoker().apply(
164 [&](auto t) {
165 return self.template readMaskArray<decltype(t)>(bbox, origin, allowUnsafe);
166 },
167 py::dtype(dtype), cpputils::python::TemplateInvoker::Tag<MaskPixel>());
168 },
169 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "allowUnsafe"_a = false,
170 "dtype"_a = py::none());
171 cls.def(
172 "readVariance",
173 [](Class &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool allowUnsafe,
174 py::object dtype) {
175 if (dtype.is(py::none())) {
176 dtype = py::dtype(self.readVarianceDType());
177 }
178 return cpputils::python::TemplateInvoker().apply(
179 [&](auto t) {
180 return self.template readVariance<decltype(t)>(bbox, origin, allowUnsafe);
181 },
182 py::dtype(dtype), cpputils::python::TemplateInvoker::Tag<VariancePixel>());
183 },
184 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "allowUnsafe"_a = false,
185 "dtype"_a = py::none());
186 cls.def(
187 "readVarianceArray",
188 [](Class &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool allowUnsafe,
189 py::object dtype) {
190 if (dtype.is(py::none())) {
191 dtype = py::dtype(self.readVarianceDType());
192 }
193 return cpputils::python::TemplateInvoker().apply(
194 [&](auto t) {
195 return self.template readVarianceArray<decltype(t)>(bbox, origin, allowUnsafe);
196 },
197 py::dtype(dtype), cpputils::python::TemplateInvoker::Tag<VariancePixel>());
198 },
199 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "allowUnsafe"_a = false,
200 "dtype"_a = py::none());
201}
202
203void declareImageFitsReader(lsst::cpputils::python::WrapperCollection &wrappers) {
204 wrappers.wrapType(PyImageFitsReader(wrappers.module, "ImageFitsReader"), [](auto &mod, auto &cls) {
205 declareCommonMethods(cls);
206 declareSinglePlaneMethods(cls);
207 cls.def(
208 "read",
209 [](ImageFitsReader &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool allowUnsafe,
210 py::object dtype) {
211 if (dtype.is(py::none())) {
212 dtype = py::dtype(self.readDType());
213 }
214 return cpputils::python::TemplateInvoker().apply(
215 [&](auto t) { return self.read<decltype(t)>(bbox, origin, allowUnsafe); },
216 py::dtype(dtype),
217 cpputils::python::TemplateInvoker::Tag<std::uint16_t, int, float, double,
218 std::uint64_t>());
219 },
220 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "allowUnsafe"_a = false,
221 "dtype"_a = py::none());
222 });
223}
224
225void declareMaskFitsReader(lsst::cpputils::python::WrapperCollection &wrappers) {
226 wrappers.wrapType(PyMaskFitsReader(wrappers.module, "MaskFitsReader"), [](auto &mod, auto &cls) {
227 declareCommonMethods(cls);
228 declareSinglePlaneMethods(cls);
229 cls.def(
230 "read",
231 [](MaskFitsReader &self, lsst::geom::Box2I const &bbox, ImageOrigin origin, bool conformMasks,
232 bool allowUnsafe, py::object dtype) {
233 if (dtype.is(py::none())) {
234 dtype = py::dtype(self.readDType());
235 }
236 return cpputils::python::TemplateInvoker().apply(
237 [&](auto t) {
238 return self.read<decltype(t)>(bbox, origin, conformMasks, allowUnsafe);
239 },
240 py::dtype(dtype), cpputils::python::TemplateInvoker::Tag<MaskPixel>());
241 },
242 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "conformMasks"_a = false,
243 "allowUnsafe"_a = false, "dtype"_a = py::none());
244 });
245 // all other methods provided by base class wrappers
246}
247
248void declareMaskedImageFitsReader(lsst::cpputils::python::WrapperCollection &wrappers) {
249 wrappers.wrapType(PyMaskedImageFitsReader(wrappers.module, "MaskedImageFitsReader"), [](auto &mod,
250 auto &cls) {
251 cls.def(py::init<std::string const &, int>(), "fileName"_a, "hdu"_a = fits::DEFAULT_HDU);
252 cls.def(py::init<fits::MemFileManager &, int>(), "manager"_a, "hdu"_a = fits::DEFAULT_HDU);
253 declareCommonMethods(cls);
254 declareMultiPlaneMethods(cls);
255 cls.def("readPrimaryMetadata", &MaskedImageFitsReader::readPrimaryMetadata);
256 cls.def("readImageMetadata", &MaskedImageFitsReader::readImageMetadata);
257 cls.def("readMaskMetadata", &MaskedImageFitsReader::readMaskMetadata);
258 cls.def("readVarianceMetadata", &MaskedImageFitsReader::readVarianceMetadata);
259 cls.def(
260 "read",
261 [](MaskedImageFitsReader &self, lsst::geom::Box2I const &bbox, ImageOrigin origin,
262 bool conformMasks, bool needAllHdus, bool allowUnsafe, py::object dtype) {
263 if (dtype.is(py::none())) {
264 dtype = py::dtype(self.readImageDType());
265 }
266 return cpputils::python::TemplateInvoker().apply(
267 [&](auto t) {
268 return self.read<decltype(t)>(bbox, origin, conformMasks, allowUnsafe);
269 },
270 py::dtype(dtype),
271 cpputils::python::TemplateInvoker::Tag<std::uint16_t, int, float, double,
272 std::uint64_t>());
273 },
274 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "conformMasks"_a = false,
275 "needAllHdus"_a = false, "allowUnsafe"_a = false, "dtype"_a = py::none());
276 });
277}
278
279void declareExposureFitsReader(lsst::cpputils::python::WrapperCollection &wrappers) {
280 wrappers.wrapType(PyExposureFitsReader(wrappers.module, "ExposureFitsReader"), [](auto &mod, auto &cls) {
281 cls.def(py::init<std::string const &>(), "fileName"_a);
282 cls.def(py::init<fits::MemFileManager &>(), "manager"_a);
283 declareCommonMethods(cls);
284 declareMultiPlaneMethods(cls);
285 cls.def("readSerializationVersion", &ExposureFitsReader::readSerializationVersion);
286 cls.def("readExposureId", &ExposureFitsReader::readExposureId);
287 cls.def("readMetadata", &ExposureFitsReader::readMetadata);
288 cls.def("readWcs", &ExposureFitsReader::readWcs);
289 cls.def("readFilter", &ExposureFitsReader::readFilter);
290 cls.def("readPhotoCalib", &ExposureFitsReader::readPhotoCalib);
291 cls.def("readPsf", &ExposureFitsReader::readPsf);
292 cls.def("readValidPolygon", &ExposureFitsReader::readValidPolygon);
293 cls.def("readApCorrMap", &ExposureFitsReader::readApCorrMap);
294 cls.def("readCoaddInputs", &ExposureFitsReader::readCoaddInputs);
295 cls.def("readVisitInfo", &ExposureFitsReader::readVisitInfo);
296 cls.def("readTransmissionCurve", &ExposureFitsReader::readTransmissionCurve);
297 cls.def("readComponent", &ExposureFitsReader::readComponent);
298 cls.def("readDetector", &ExposureFitsReader::readDetector);
299 cls.def("readExposureInfo", &ExposureFitsReader::readExposureInfo);
300 cls.def(
301 "readMaskedImage",
302 [](ExposureFitsReader &self, lsst::geom::Box2I const &bbox, ImageOrigin origin,
303 bool conformMasks, bool allowUnsafe, py::object dtype) {
304 if (dtype.is(py::none())) {
305 dtype = py::dtype(self.readImageDType());
306 }
307 return cpputils::python::TemplateInvoker().apply(
308 [&](auto t) {
309 return self.readMaskedImage<decltype(t)>(bbox, origin, conformMasks,
310 allowUnsafe);
311 },
312 py::dtype(dtype),
313 cpputils::python::TemplateInvoker::Tag<std::uint16_t, int, float, double,
314 std::uint64_t>());
315 },
316 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "conformMasks"_a = false,
317 "allowUnsafe"_a = false, "dtype"_a = py::none());
318 cls.def(
319 "read",
320 [](ExposureFitsReader &self, lsst::geom::Box2I const &bbox, ImageOrigin origin,
321 bool conformMasks, bool allowUnsafe, py::object dtype) {
322 if (dtype.is(py::none())) {
323 dtype = py::dtype(self.readImageDType());
324 }
325 return cpputils::python::TemplateInvoker().apply(
326 [&](auto t) {
327 return self.read<decltype(t)>(bbox, origin, conformMasks, allowUnsafe);
328 },
329 py::dtype(dtype),
330 cpputils::python::TemplateInvoker::Tag<std::uint16_t, int, float, double,
331 std::uint64_t>());
332 },
333 "bbox"_a = lsst::geom::Box2I(), "origin"_a = PARENT, "conformMasks"_a = false,
334 "allowUnsafe"_a = false, "dtype"_a = py::none());
335 });
336}
337} // namespace
339 // wrappers.addInheritanceDependency("lsst.daf.base");
340 wrappers.addSignatureDependency("lsst.geom");
341 wrappers.addSignatureDependency("lsst.afw.image._image");
342 wrappers.addSignatureDependency("lsst.afw.image._maskedImage");
343 wrappers.addSignatureDependency("lsst.afw.image._exposure");
344 declareImageFitsReader(wrappers);
345 declareMaskFitsReader(wrappers);
346 declareMaskedImageFitsReader(wrappers);
347 declareExposureFitsReader(wrappers);
348}
349} // namespace image
350} // namespace afw
351} // namespace lsst
AmpInfoBoxKey bbox
Definition Amplifier.cc:117
Implementation of the Photometric Calibration class.
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
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
An integer coordinate rectangle.
Definition Box.h:55
const int DEFAULT_HDU
Specify that the default HDU should be read.
void wrapReaders(lsst::cpputils::python::WrapperCollection &)
Definition _readers.cc:338