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
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:
139 return std::make_shared<PixelArray<std::uint8_t>>(array);
140 case 16:
141 return std::make_shared<PixelArray<std::int16_t>>(array);
142 case 32:
143 return std::make_shared<PixelArray<std::int32_t>>(array);
144 case 64:
145 return std::make_shared<PixelArray<std::int64_t>>(array);
146 case -32:
147 return std::make_shared<PixelArray<boost::float32_t>>(array);
148 case -64:
149 return std::make_shared<PixelArray<boost::float64_t>>(array);
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
afw::table::Key< afw::table::Array< MaskPixelT > > mask
std::ostream * os
Definition Schema.cc:557
ArrayKeyVector arrays
T cbegin(T... args)
Options for scaling image pixels.
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)
Abstract base class for an array of pixel values.
std::size_t getNumElements() const
Return the number of pixels.
virtual void const * getData() const =0
Return a void* array of the pixels.
Typed array of pixel values.
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:81
Reports invalid arguments.
Definition Runtime.h:66
T copy(T... args)
T cend(T... args)
T make_pair(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)
Options for tile compression of image pixels.
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.