LSST Applications g042eb84c57+730a74494b,g04e9c324dd+8c5ae1fdc5,g134cb467dc+1f1e3e7524,g199a45376c+0ba108daf9,g1fd858c14a+fa7d31856b,g210f2d0738+f66ac109ec,g262e1987ae+83a3acc0e5,g29ae962dfc+d856a2cb1f,g2cef7863aa+aef1011c0b,g35bb328faa+8c5ae1fdc5,g3fd5ace14f+a1e0c9f713,g47891489e3+0d594cb711,g4d44eb3520+c57ec8f3ed,g4d7b6aa1c5+f66ac109ec,g53246c7159+8c5ae1fdc5,g56a1a4eaf3+fd7ad03fde,g64539dfbff+f66ac109ec,g67b6fd64d1+0d594cb711,g67fd3c3899+f66ac109ec,g6985122a63+0d594cb711,g74acd417e5+3098891321,g786e29fd12+668abc6043,g81db2e9a8d+98e2ab9f28,g87389fa792+8856018cbb,g89139ef638+0d594cb711,g8d7436a09f+80fda9ce03,g8ea07a8fe4+760ca7c3fc,g90f42f885a+033b1d468d,g97be763408+a8a29bda4b,g99822b682c+e3ec3c61f9,g9d5c6a246b+0d5dac0c3d,ga41d0fce20+9243b26dd2,gbf99507273+8c5ae1fdc5,gd7ef33dd92+0d594cb711,gdab6d2f7ff+3098891321,ge410e46f29+0d594cb711,geaed405ab2+c4bbc419c6,gf9a733ac38+8c5ae1fdc5,w.2025.38
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:
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.