24#include <pybind11/pybind11.h>
25#include <pybind11/stl.h>
29#include "ndarray/pybind11.h"
41using namespace pybind11::literals;
46void declareImageCompression(lsst::utils::python::WrapperCollection &wrappers) {
47 auto options = wrappers.wrapType(
48 py::class_<ImageCompressionOptions>(wrappers.module,
"ImageCompressionOptions"),
49 [](
auto &mod,
auto &cls) {
50 cls.def(py::init<ImageCompressionOptions::CompressionAlgorithm,
51 ImageCompressionOptions::Tiles, float>(),
52 "algorithm"_a,
"tiles"_a,
"quantizeLevel"_a = 0.0);
53 cls.def(py::init<ImageCompressionOptions::CompressionAlgorithm, int, float>(),
"algorithm"_a,
54 "rows"_a = 1,
"quantizeLevel"_a = 0.0);
56 cls.def(py::init<lsst::afw::image::Image<unsigned char> const &>());
57 cls.def(py::init<lsst::afw::image::Image<unsigned short> const &>());
58 cls.def(py::init<lsst::afw::image::Image<short> const &>());
59 cls.def(py::init<lsst::afw::image::Image<int> const &>());
60 cls.def(py::init<lsst::afw::image::Image<unsigned int> const &>());
61 cls.def(py::init<lsst::afw::image::Image<float> const &>());
62 cls.def(py::init<lsst::afw::image::Image<double> const &>());
63 cls.def(py::init<lsst::afw::image::Image<std::uint64_t> const &>());
65 cls.def(py::init<lsst::afw::image::Mask<unsigned char> const &>());
66 cls.def(py::init<lsst::afw::image::Mask<unsigned short> const &>());
67 cls.def(py::init<lsst::afw::image::Mask<short> const &>());
68 cls.def(py::init<lsst::afw::image::Mask<std::int32_t> const &>());
70 cls.def_readonly(
"algorithm", &ImageCompressionOptions::algorithm);
71 cls.def_readonly(
"tiles", &ImageCompressionOptions::tiles);
72 cls.def_readonly(
"quantizeLevel", &ImageCompressionOptions::quantizeLevel);
75 py::enum_<ImageCompressionOptions::CompressionAlgorithm>(options,
"CompressionAlgorithm"),
76 [](
auto &mod,
auto &enm) {
87void declareImageScalingOptionsTemplates(py::class_<ImageScalingOptions> &cls) {
93 ImageScalingOptions
const & self,
97 return self.determine(
image, mask);
104void declareImageScalingOptions(lsst::utils::python::WrapperCollection &wrappers) {
105 auto options = wrappers.wrapType(
106 py::class_<ImageScalingOptions>(wrappers.module,
"ImageScalingOptions"),
107 [](
auto &mod,
auto &cls) {
108 cls.def(py::init<>());
109 cls.def(py::init<ImageScalingOptions::ScalingAlgorithm, int, std::vector<std::string> const &,
110 unsigned long, float, float, bool, double, double>(),
111 "algorithm"_a,
"bitpix"_a,
"maskPlanes"_a = std::vector<std::string>(),
"seed"_a = 1,
112 "quantizeLevel"_a = 4.0,
"quantizePad"_a = 5.0,
"fuzz"_a = true,
"bscale"_a = 1.0,
115 cls.def_readonly(
"algorithm", &ImageScalingOptions::algorithm);
116 cls.def_readonly(
"bitpix", &ImageScalingOptions::bitpix);
117 cls.def_readonly(
"maskPlanes", &ImageScalingOptions::maskPlanes);
118 cls.def_readonly(
"seed", &ImageScalingOptions::seed);
119 cls.def_readonly(
"quantizeLevel", &ImageScalingOptions::quantizeLevel);
120 cls.def_readonly(
"quantizePad", &ImageScalingOptions::quantizePad);
121 cls.def_readonly(
"fuzz", &ImageScalingOptions::fuzz);
122 cls.def_readonly(
"bscale", &ImageScalingOptions::bscale);
123 cls.def_readonly(
"bzero", &ImageScalingOptions::bzero);
125 declareImageScalingOptionsTemplates<float>(cls);
126 declareImageScalingOptionsTemplates<double>(cls);
128 wrappers.wrapType(py::enum_<ImageScalingOptions::ScalingAlgorithm>(options,
"ScalingAlgorithm"),
129 [](
auto &mod,
auto &enm) {
141void declareImageScaleTemplates(py::class_<ImageScale> &cls,
std::string const &suffix) {
142 cls.def(
"toFits", &ImageScale::toFits<T>,
"image"_a,
"forceNonfiniteRemoval"_a =
false,
"fuzz"_a =
true,
143 "tiles"_a = ndarray::Array<long, 1, 1>(),
"seed"_a = 1);
144 cls.def(
"fromFits", &ImageScale::fromFits<T>);
147void declareImageScale(lsst::utils::python::WrapperCollection &wrappers) {
148 wrappers.wrapType(py::class_<ImageScale>(wrappers.module,
"ImageScale"), [](
auto &mod,
auto &cls) {
149 cls.def(py::init<int, double, double>(),
"bitpix"_a,
"bscale"_a,
"bzero"_a);
150 cls.def_readonly(
"bitpix", &ImageScale::bitpix);
151 cls.def_readonly(
"bscale", &ImageScale::bscale);
152 cls.def_readonly(
"bzero", &ImageScale::bzero);
153 cls.def_readonly(
"blank", &ImageScale::blank);
155 declareImageScaleTemplates<float>(cls,
"F");
156 declareImageScaleTemplates<double>(cls,
"D");
160void declareImageWriteOptions(lsst::utils::python::WrapperCollection &wrappers) {
161 wrappers.wrapType(py::class_<ImageWriteOptions>(wrappers.module,
"ImageWriteOptions"),
162 [](
auto &mod,
auto &cls) {
163 cls.def(py::init<lsst::afw::image::Image<std::uint16_t>>());
164 cls.def(py::init<lsst::afw::image::Image<std::int32_t>>());
165 cls.def(py::init<lsst::afw::image::Image<std::uint64_t>>());
166 cls.def(py::init<lsst::afw::image::Image<float>>());
167 cls.def(py::init<lsst::afw::image::Image<double>>());
169 cls.def(py::init<lsst::afw::image::Mask<lsst::afw::image::MaskPixel>>());
171 cls.def(py::init<ImageCompressionOptions const &, ImageScalingOptions const &>(),
172 "compression"_a,
"scaling"_a = ImageScalingOptions());
173 cls.def(py::init<ImageScalingOptions const &>());
175 cls.def(py::init<lsst::daf::base::PropertySet const &>());
177 cls.def_readonly(
"compression", &ImageWriteOptions::compression);
178 cls.def_readonly(
"scaling", &ImageWriteOptions::scaling);
180 cls.def_static(
"validate", &ImageWriteOptions::validate);
188void declareFits(lsst::utils::python::WrapperCollection &wrappers) {
189 wrappers.wrapType(py::class_<Fits>(wrappers.module,
"Fits"), [](
auto &mod,
auto &cls) {
190 cls.def(py::init<std::string const &, std::string const &, int>(),
"filename"_a,
"mode"_a,
191 "behavior"_a = Fits::AUTO_CLOSE | Fits::AUTO_CHECK);
192 cls.def(py::init<MemFileManager &, std::string const &, int>(),
"manager"_a,
"mode"_a,
193 "behavior"_a = Fits::AUTO_CLOSE | Fits::AUTO_CHECK);
195 cls.def(
"closeFile", &Fits::closeFile);
196 cls.def(
"getFileName", &Fits::getFileName);
197 cls.def(
"getHdu", &Fits::getHdu);
198 cls.def(
"setHdu", py::overload_cast<int, bool>(&Fits::setHdu),
"hdu"_a,
"relative"_a = false);
200 "setHdu", [](Fits &self, std::string const &name) { self.setHdu(name); },
"name"_a);
209 cls.def(
"readImageI", [](Fits &self) {
210 ndarray::Vector<int, 2>
const offset;
211 ndarray::Vector<ndarray::Size, 2> shape = self.getImageShape<2>();
212 ndarray::Array<int, 2, 2>
result = ndarray::allocate(shape[0], shape[1]);
213 self.readImage(
result, offset);
217 cls.def(
"gotoFirstHdu", [](Fits &self) { self.setHdu(
DEFAULT_HDU); });
227void declareFitsModule(lsst::utils::python::WrapperCollection &wrappers) {
228 wrappers.wrap([](
auto &mod) {
229 py::class_<MemFileManager> clsMemFileManager(mod,
"MemFileManager");
231 clsMemFileManager.def(py::init<>());
232 clsMemFileManager.def(py::init<size_t>());
238 clsMemFileManager.def(
"getData", [](MemFileManager &
m) {
239 return py::bytes(
static_cast<char *
>(
m.getData()),
m.getLength());
241 clsMemFileManager.def(
"setData", [](MemFileManager &
m, py::bytes
const &d,
size_t size) {
242 memcpy(
m.getData(), PyBytes_AsString(d.ptr()), size);
244 clsMemFileManager.def(
253 py::overload_cast<daf::base::PropertyList const&, daf::base::PropertyList const &>(
256 "first"_a,
"second"_a
265 "fileName"_a,
"hdu"_a =
DEFAULT_HDU,
"strip"_a =
false);
272 "fileName"_a,
"hduName"_a,
"strip"_a =
false);
274 mod.def(
"setAllowImageCompression", &setAllowImageCompression,
"allow"_a);
278 mod.def(
"compressionAlgorithmToString", &compressionAlgorithmToString);
280 mod.def(
"scalingAlgorithmToString", &scalingAlgorithmToString);
284PYBIND11_MODULE(_fits, mod) {
285 lsst::utils::python::WrapperCollection wrappers(mod,
"lsst.afw.fits");
286 wrappers.addSignatureDependency(
"lsst.pex.exceptions");
287 wrappers.addSignatureDependency(
"lsst.daf.base");
291 cls.def(py::init<std::string const &>());
292 declareImageCompression(wrappers);
293 declareImageScalingOptions(wrappers);
294 declareImageScale(wrappers);
295 declareImageWriteOptions(wrappers);
296 declareFits(wrappers);
297 declareFitsModule(wrappers);
An exception thrown when problems are found when reading or writing FITS files.
ImageCompressionOptions getImageCompression()
Return the current image compression settings.
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
bool checkCompressedImagePhu()
Go to the first image header in the FITS file.
int countHdus()
Return the number of HDUs in the file.
void setImageCompression(ImageCompressionOptions const &options)
Set compression options for writing FITS images.
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
@ MANUAL
Scale set manually.
@ STDEV_NEGATIVE
Scale based on the standard deviation, dynamic range negative.
@ STDEV_POSITIVE
Scale based on the standard deviation. dynamic range positive.
@ STDEV_BOTH
Scale based on the standard deviation, dynamic range positive+negative.
@ RANGE
Scale to preserve dynamic range.
std::size_t getLength() const
Return the buffer length.
The base class for all image classed (Image, Mask, MaskedImage, ...)
Represent a 2-dimensional array of bitmask pixels.
Reports errors in external input/output operations.
std::shared_ptr< daf::base::PropertyList > combineMetadata(daf::base::PropertyList const &first, daf::base::PropertyList const &second)
Combine two sets of metadata in a FITS-appropriate fashion.
const int DEFAULT_HDU
Specify that the default HDU should be read.
std::shared_ptr< daf::base::PropertyList > readMetadata(std::string const &fileName, int hdu=DEFAULT_HDU, bool strip=false)
Read FITS header.
ImageScalingOptions::ScalingAlgorithm scalingAlgorithmFromString(std::string const &name)
Interpret scaling algorithm expressed in string.
bool getAllowImageCompression()
std::string makeLimitedFitsHeader(lsst::daf::base::PropertySet const &metadata, std::set< std::string > const &excludeNames={})
Format a PropertySet into an FITS header string in a simplistic fashion.
ImageCompressionOptions::CompressionAlgorithm compressionAlgorithmFromString(std::string const &name)
Interpret compression algorithm expressed in string.
@ GZIP_SHUFFLE
GZIP compression with shuffle (most-significant byte first)
@ GZIP
Standard GZIP compression.