LSST Applications g180d380827+78227d2bc4,g2079a07aa2+86d27d4dc4,g2305ad1205+bdd7851fe3,g2bbee38e9b+c6a8a0fb72,g337abbeb29+c6a8a0fb72,g33d1c0ed96+c6a8a0fb72,g3a166c0a6a+c6a8a0fb72,g3d1719c13e+260d7c3927,g3ddfee87b4+723a6db5f3,g487adcacf7+29e55ea757,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+9443c4b912,g62aa8f1a4b+7e2ea9cd42,g858d7b2824+260d7c3927,g864b0138d7+8498d97249,g95921f966b+dffe86973d,g991b906543+260d7c3927,g99cad8db69+4809d78dd9,g9c22b2923f+e2510deafe,g9ddcbc5298+9a081db1e4,ga1e77700b3+03d07e1c1f,gb0e22166c9+60f28cb32d,gb23b769143+260d7c3927,gba4ed39666+c2a2e4ac27,gbb8dafda3b+e22341fd87,gbd998247f1+585e252eca,gc120e1dc64+713f94b854,gc28159a63d+c6a8a0fb72,gc3e9b769f7+385ea95214,gcf0d15dbbd+723a6db5f3,gdaeeff99f8+f9a426f77a,ge6526c86ff+fde82a80b9,ge79ae78c31+c6a8a0fb72,gee10cc3b42+585e252eca,w.2024.18
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"
26#include "lsst/utils/python.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 utils::python::TemplateInvoker().apply(
89 [&](auto t) {
90 return self.template readArray<decltype(t)>(bbox, origin, allowUnsafe);
91 },
92 py::dtype(dtype),
93 utils::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 utils::python::TemplateInvoker().apply(
114 [&](auto t) {
115 return self.template readImage<decltype(t)>(bbox, origin, allowUnsafe);
116 },
117 py::dtype(dtype),
118 utils::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 utils::python::TemplateInvoker().apply(
131 [&](auto t) {
132 return self.template readImageArray<decltype(t)>(bbox, origin, allowUnsafe);
133 },
134 py::dtype(dtype),
135 utils::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 utils::python::TemplateInvoker().apply(
148 [&](auto t) {
149 return self.template readMask<decltype(t)>(bbox, origin, conformMasks,
150 allowUnsafe);
151 },
152 py::dtype(dtype), utils::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 utils::python::TemplateInvoker().apply(
164 [&](auto t) {
165 return self.template readMaskArray<decltype(t)>(bbox, origin, allowUnsafe);
166 },
167 py::dtype(dtype), utils::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 utils::python::TemplateInvoker().apply(
179 [&](auto t) {
180 return self.template readVariance<decltype(t)>(bbox, origin, allowUnsafe);
181 },
182 py::dtype(dtype), utils::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 utils::python::TemplateInvoker().apply(
194 [&](auto t) {
195 return self.template readVarianceArray<decltype(t)>(bbox, origin, allowUnsafe);
196 },
197 py::dtype(dtype), utils::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::utils::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 utils::python::TemplateInvoker().apply(
215 [&](auto t) { return self.read<decltype(t)>(bbox, origin, allowUnsafe); },
216 py::dtype(dtype),
217 utils::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::utils::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 utils::python::TemplateInvoker().apply(
237 [&](auto t) {
238 return self.read<decltype(t)>(bbox, origin, conformMasks, allowUnsafe);
239 },
240 py::dtype(dtype), utils::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::utils::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 utils::python::TemplateInvoker().apply(
267 [&](auto t) {
268 return self.read<decltype(t)>(bbox, origin, conformMasks, allowUnsafe);
269 },
270 py::dtype(dtype),
271 utils::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::utils::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 utils::python::TemplateInvoker().apply(
308 [&](auto t) {
309 return self.readMaskedImage<decltype(t)>(bbox, origin, conformMasks,
310 allowUnsafe);
311 },
312 py::dtype(dtype),
313 utils::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 utils::python::TemplateInvoker().apply(
326 [&](auto t) {
327 return self.read<decltype(t)>(bbox, origin, conformMasks, allowUnsafe);
328 },
329 py::dtype(dtype),
330 utils::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
338void wrapReaders(lsst::utils::python::WrapperCollection &wrappers) {
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.
An integer coordinate rectangle.
Definition Box.h:55
const int DEFAULT_HDU
Specify that the default HDU should be read.
void wrapReaders(lsst::utils::python::WrapperCollection &)
Definition _readers.cc:338