Loading [MathJax]/extensions/tex2jax.js
LSST Applications g04a91732dc+a777afbe81,g07dc498a13+7e3c5f68a2,g12483e3c20+0145ec33cd,g1409bbee79+7e3c5f68a2,g1a7e361dbc+7e3c5f68a2,g1fd858c14a+9f35e23ec3,g35bb328faa+fcb1d3bbc8,g3ad4f90e5c+0145ec33cd,g3bd4b5ce2c+cbf1bea503,g4e0f332c67+5d362be553,g53246c7159+fcb1d3bbc8,g5477a8d5ce+db04660fe6,g60b5630c4e+0145ec33cd,g623d845a50+0145ec33cd,g6f0c2978f1+3526b51a37,g75b6c65c88+d54b601591,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g7b71ed6315+fcb1d3bbc8,g8852436030+4639f750a5,g89139ef638+7e3c5f68a2,g9125e01d80+fcb1d3bbc8,g919ac25b3e+6220c5324a,g95236ca021+f7a31438ed,g989de1cb63+7e3c5f68a2,g9f33ca652e+2d6fa11d35,gaaedd4e678+7e3c5f68a2,gabe3b4be73+1e0a283bba,gb1101e3267+4a428ef779,gb4a253aaf5+0122250889,gb58c049af0+f03b321e39,gc99c83e5f0+76d20ab76d,gcf25f946ba+4639f750a5,gd6cbbdb0b4+c8606af20c,gde0f65d7ad+3d8a3b7e46,ge278dab8ac+932305ba37,gf795337580+03b96afe58,gfba249425e+fcb1d3bbc8,w.2025.08
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
fitsCompression.h
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2#ifndef LSST_AFW_fitsCompression_h_INCLUDED
3#define LSST_AFW_fitsCompression_h_INCLUDED
4
5#include <string>
6#include <limits>
7
8#include "boost/cstdfloat.hpp"
9
10#include "lsst/pex/exceptions.h"
11#include "lsst/daf/base.h"
12#include "ndarray.h"
13#include "ndarray/eigen.h"
14
16#include "lsst/afw/image/Mask.h"
17
18namespace lsst {
19namespace afw {
20namespace fits {
21
22// Forward declarations
23class Fits;
24
25namespace detail {
26
28template <typename T>
29struct Bitpix;
30
31template <>
32struct Bitpix<std::uint8_t> {
33 static int const value = 8;
34};
35template <>
36struct Bitpix<std::int16_t> {
37 static int const value = 16;
38};
39template <>
40struct Bitpix<std::int32_t> {
41 static int const value = 32;
42};
43template <>
44struct Bitpix<std::int64_t> {
45 static int const value = 64;
46};
47template <>
48struct Bitpix<std::uint16_t> {
49 static int const value = 16;
50};
51template <>
52struct Bitpix<std::uint32_t> {
53 static int const value = 32;
54};
55template <>
56struct Bitpix<std::uint64_t> {
57 static int const value = 64;
58};
59template <>
60struct Bitpix<float> {
61 static int const value = -32;
62};
63template <>
64struct Bitpix<double> {
65 static int const value = -64;
66};
67
76public:
77 virtual ~PixelArrayBase() {}
78
80 virtual void const* getData() const = 0;
81
83 std::size_t getNumElements() const { return _num; }
84
85protected:
86 PixelArrayBase(std::size_t num) : _num(num) {}
87
88private:
89 std::size_t _num; // Number of pixel values
90};
91
93template <typename T>
94class PixelArray : public PixelArrayBase {
95public:
96 PixelArray() = delete;
97 PixelArray(PixelArray const&) = delete;
98
102 PixelArray(ndarray::Array<T, 1, 1> const& array)
104 _pixels(array.getData()),
105 _manager(array.getManager()) {}
106
110 template <typename U>
111 PixelArray(ndarray::Array<U, 1, 1> const& array) : PixelArrayBase(array.getNumElements()) {
112 auto mem = ndarray::SimpleManager<U>::allocate(getNumElements());
113 _manager = mem.first;
114 _pixels = mem.second;
115 std::copy(array.begin(), array.end(),
116 const_cast<typename std::remove_const<T>::type*>(reinterpret_cast<T const*>(_pixels)));
117 }
118
119 ~PixelArray() override {}
120
121 void const* getData() const override { return _pixels; }
122
123private:
124 void const* _pixels; // The data
125 ndarray::Manager::Ptr _manager; // Memory manager; holds onto the data while we use it
126};
127
133template <typename T>
134std::shared_ptr<PixelArrayBase> makePixelArray(int bitpix, ndarray::Array<T, 1, 1> const& array) {
135 switch (bitpix) {
136 case 0:
137 return std::make_shared<PixelArray<T>>(array);
138 case 8:
140 case 16:
142 case 32:
144 case 64:
146 case -32:
148 case -64:
150 default:
152 os << "Unrecognized bitpix: " << bitpix;
154 }
155}
156
157} // namespace detail
158
194 using Tiles = ndarray::Array<long, 1, 1>;
195
199
202 float quantizeLevel_ = 0.0)
203 : algorithm(algorithm_), tiles(ndarray::copy(tiles_)), quantizeLevel(quantizeLevel_) {}
204
206 float quantizeLevel_ = 0.0)
207 : algorithm(algorithm_), tiles(ndarray::allocate(tiles_.size())), quantizeLevel(quantizeLevel_) {
208 std::copy(tiles_.cbegin(), tiles_.cend(), tiles.begin());
209 }
210
216 explicit ImageCompressionOptions(CompressionAlgorithm algorithm_, int rows = 1,
217 float quantizeLevel_ = 0.0);
218
223 template <typename T>
225 : ImageCompressionOptions(image.getBBox().getArea() > 0 ? NONE : NONE) {}
226 template <typename T>
228 : ImageCompressionOptions(mask.getBBox().getArea() > 0 ? NONE : NONE) {}
229
230 // Disable compression for int64: cfitsio won't compress them
238};
239
242
245
248
251
263 int bitpix;
264 double bscale;
265 double bzero;
266 long blank;
267
276 ImageScale(int bitpix_, double bscale_, double bzero_)
277 : bitpix(bitpix_),
278 bscale(bscale_),
279 bzero(std::floor(bzero_ / bscale_ + 0.5) * bscale_),
280 blank(bitpix > 0 ? (bitpix == 8 ? 255 : (1L << (bitpix - 1)) - 1) : 0) {}
281
292 template <typename T>
294 ndarray::Array<T const, 2, 2> const& image, bool forceNonfiniteRemoval, bool fuzz = true,
295 ndarray::Array<long, 1> const& tiles = ndarray::Array<long, 1, 1>(), int seed = 1) const;
296
302 template <typename T>
303 ndarray::Array<T, 2, 2> fromFits(ndarray::Array<T, 2, 2> const& image) const;
304};
305
356public:
366 int bitpix;
367 bool fuzz;
368 int seed;
372 double bscale;
373 double bzero;
374
381
393 ImageScalingOptions(ScalingAlgorithm algorithm_, int bitpix_,
394 std::vector<std::string> const& maskPlanes_ = {}, int seed_ = 1,
395 float quantizeLevel_ = 4.0, float quantizePad_ = 5.0, bool fuzz_ = true,
396 double bscale_ = 1.0, double bzero_ = 0.0);
397
403 ImageScalingOptions(int bitpix_, double bscale_ = 1.0, double bzero_ = 0.0)
404 : ImageScalingOptions(MANUAL, bitpix_, {}, 1, 4.0, 5.0, false, bscale_, bzero_) {}
405
407
411 template <typename T>
413 image::Mask<image::MaskPixel> const * mask = nullptr) const {
414 auto const arrays = _toArray(image, mask);
415 return determine(arrays.first, arrays.second);
416 }
417
418 template <typename T, int N>
419 ImageScale determine(ndarray::Array<T const, N, N> const& image,
420 ndarray::Array<bool, N, N> const& mask) const;
422
423private:
425 template <typename T>
426 std::pair<ndarray::Array<T const, 2, 2>, ndarray::Array<bool, 2, 2>> _toArray(
428 image::Mask<image::MaskPixel> const * mask = nullptr) const {
429 if (mask && image.getDimensions() != mask->getDimensions()) {
431 os << "Size mismatch between image and mask: ";
432 os << image.getWidth() << "x" << image.getHeight();
433 os << " vs ";
434 os << mask->getWidth() << "x" << mask->getHeight();
436 }
437 ndarray::Array<T const, 2, 2> imageArray = ndarray::dynamic_dimension_cast<2>(image.getArray());
438 if (imageArray.empty()) imageArray = ndarray::copy(image.getArray());
439 ndarray::Array<bool, 2, 2> maskArray = ndarray::allocate(imageArray.getShape());
440 if (mask) {
441 maskArray.deep() = (mask->getArray() & mask->getPlaneBitMask(maskPlanes));
442 } else {
443 maskArray.deep() = false;
444 }
445 return std::make_pair(imageArray, maskArray);
446 }
447
454 template <typename T, int N>
455 ImageScale determineFromRange(ndarray::Array<T const, N, N> const& image,
456 ndarray::Array<bool, N, N> const& mask, bool isUnsigned = false,
457 bool cfitsioPadding = true) const;
458
465 template <typename T, int N>
466 ImageScale determineFromStdev(ndarray::Array<T const, N, N> const& image,
467 ndarray::Array<bool, N, N> const& mask, bool isUnsigned = false,
468 bool cfitsioPadding = true) const;
469};
470
473
476
477} // namespace fits
478} // namespace afw
479} // namespace lsst
480
481#endif // ifndef LSST_AFW_fitsCompression_h_INCLUDED
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
T cbegin(T... args)
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition fits.h:308
ScalingAlgorithm algorithm
Scaling algorithm to use.
float quantizeLevel
Divisor of the standard deviation for STDEV_* scaling.
@ 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.
ImageScalingOptions(int bitpix_, double bscale_=1.0, double bzero_=0.0)
Manual scaling Ctor.
bool fuzz
Fuzz the values when quantising floating-point values?
ImageScale determine(image::ImageBase< T > const &image, image::Mask< image::MaskPixel > const *mask=nullptr) const
Determine the scaling for a particular image.
float quantizePad
Number of stdev to allow on the low/high side (for STDEV_POSITIVE/NEGATIVE)
int bitpix
Bits per pixel (0, 8,16,32,64,-32,-64)
double bscale
Manually specified BSCALE (for MANUAL scaling)
ImageScale determine(ndarray::Array< T const, N, N > const &image, ndarray::Array< bool, N, N > const &mask) const
std::vector< std::string > maskPlanes
Mask planes to ignore when doing statistics.
int seed
Seed for random number generator when fuzzing.
double bzero
Manually specified BZERO (for MANUAL scaling)
std::size_t getNumElements() const
Return the number of pixels.
virtual void const * getData() const =0
Return a void* array of the pixels.
void const * getData() const override
Return a void* array of the pixels.
PixelArray(PixelArray const &)=delete
PixelArray(ndarray::Array< U, 1, 1 > const &array)
Construct from an ndarray::Array of different type.
PixelArray(ndarray::Array< T, 1, 1 > const &array)
Construct from an ndarray::Array of the same type.
The base class for all image classed (Image, Mask, MaskedImage, ...)
Definition ImageBase.h:102
A class to represent a 2-dimensional array of pixels.
Definition Image.h:51
Represent a 2-dimensional array of bitmask pixels.
Definition Mask.h:82
Reports invalid arguments.
Definition Runtime.h:66
T copy(T... args)
T cend(T... args)
T make_pair(T... args)
T make_shared(T... args)
std::shared_ptr< PixelArrayBase > makePixelArray(int bitpix, ndarray::Array< T, 1, 1 > const &array)
Create a PixelArray suitable for an image with the nominated BITPIX.
std::string compressionAlgorithmToString(ImageCompressionOptions::CompressionAlgorithm algorithm)
Provide string version of compression algorithm.
ImageScalingOptions::ScalingAlgorithm scalingAlgorithmFromString(std::string const &name)
Interpret scaling algorithm expressed in string.
int compressionAlgorithmToCfitsio(ImageCompressionOptions::CompressionAlgorithm algorithm)
Convert ImageCompressionOptions::CompressionAlgorithm to cfitsio.
std::string scalingAlgorithmToString(ImageScalingOptions::ScalingAlgorithm algorithm)
Provide string version of compression algorithm.
ImageCompressionOptions::CompressionAlgorithm compressionAlgorithmFromCfitsio(int cfitsio)
Convert compression algorithm from cfitsio to ImageCompressionOptions::CompressionAlgorithm.
ImageCompressionOptions::CompressionAlgorithm compressionAlgorithmFromString(std::string const &name)
Interpret compression algorithm expressed in string.
STL namespace.
T quiet_NaN(T... args)
T str(T... args)
ImageCompressionOptions(CompressionAlgorithm algorithm_, Tiles tiles_, float quantizeLevel_=0.0)
Custom compression.
float quantizeLevel
quantization level: 0.0 = none requires use of GZIP or GZIP_SHUFFLE
CompressionAlgorithm algorithm
Compresion algorithm to use.
ImageCompressionOptions(image::Mask< T > const &mask)
Tiles tiles
Tile size; a dimension with 0 means infinite (e.g., to specify one row: 0,1)
ImageCompressionOptions(image::Image< std::int64_t > const &image)
ImageCompressionOptions(image::Mask< std::uint64_t > const &mask)
ImageCompressionOptions(image::Image< std::uint64_t > const &image)
@ GZIP_SHUFFLE
GZIP compression with shuffle (most-significant byte first)
ImageCompressionOptions(image::Image< T > const &image)
Default compression for a particular style of image.
ImageCompressionOptions(image::Mask< std::int64_t > const &mask)
ImageCompressionOptions(CompressionAlgorithm algorithm_, std::vector< long > tiles_, float quantizeLevel_=0.0)
Scale to apply to image.
double bscale
Scale to apply when reading from FITS.
long blank
Value for integer images indicating non-finite values.
ImageScale(int bitpix_, double bscale_, double bzero_)
Constructor.
int bitpix
Bits per pixel; negative means floating-point: 8,16,32,64,-32,-64.
double bzero
Zero-point to apply when reading from FITS.
ndarray::Array< T, 2, 2 > fromFits(ndarray::Array< T, 2, 2 > const &image) const
Convert to an array.
std::shared_ptr< detail::PixelArrayBase > toFits(ndarray::Array< T const, 2, 2 > const &image, bool forceNonfiniteRemoval, bool fuzz=true, ndarray::Array< long, 1 > const &tiles=ndarray::Array< long, 1, 1 >(), int seed=1) const
Convert to an array of pixel values to write to FITS.
FITS BITPIX header value by C++ type.