LSSTApplications  20.0.0
LSSTDataManagementBasePackage
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 
15 #include "lsst/afw/image/Image.h"
16 #include "lsst/afw/image/Mask.h"
17 
18 namespace lsst {
19 namespace afw {
20 namespace fits {
21 
22 // Forward declarations
23 class Fits;
24 
25 namespace detail {
26 
28 template <typename T>
29 struct Bitpix;
30 
31 template <>
32 struct Bitpix<std::uint8_t> {
33  static int const value = 8;
34 };
35 template <>
36 struct Bitpix<std::int16_t> {
37  static int const value = 16;
38 };
39 template <>
40 struct Bitpix<std::int32_t> {
41  static int const value = 32;
42 };
43 template <>
44 struct Bitpix<std::int64_t> {
45  static int const value = 64;
46 };
47 template <>
48 struct Bitpix<std::uint16_t> {
49  static int const value = 16;
50 };
51 template <>
52 struct Bitpix<std::uint32_t> {
53  static int const value = 32;
54 };
55 template <>
56 struct Bitpix<std::uint64_t> {
57  static int const value = 64;
58 };
59 template <>
60 struct Bitpix<float> {
61  static int const value = -32;
62 };
63 template <>
64 struct Bitpix<double> {
65  static int const value = -64;
66 };
67 
76 public:
77  virtual ~PixelArrayBase() {}
78 
80  virtual void const* getData() const = 0;
81 
83  std::size_t getNumElements() const { return _num; }
84 
85 protected:
86  PixelArrayBase(std::size_t num) : _num(num) {}
87 
88 private:
89  std::size_t _num; // Number of pixel values
90 };
91 
93 template <typename T>
94 class PixelArray : public PixelArrayBase {
95 public:
96  PixelArray() = delete;
97  PixelArray(PixelArray const&) = delete;
98 
102  PixelArray(ndarray::Array<T, 1, 1> const& array)
103  : PixelArrayBase(array.getNumElements()),
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 
123 private:
124  void const* _pixels; // The data
125  ndarray::Manager::Ptr _manager; // Memory manager; holds onto the data while we use it
126 };
127 
133 template <typename T>
134 std::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 
193  };
194  typedef ndarray::Array<long, 1, 1> Tiles;
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 
262 struct ImageScale {
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 
356 public:
364  };
366  int bitpix;
367  bool fuzz;
368  int seed;
371  float quantizePad;
372  double bscale;
373  double bzero;
374 
379  : ImageScalingOptions(NONE, 0, {}, 1, 4.0, 5.0, false, std::numeric_limits<double>::quiet_NaN(),
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  template <typename T>
413  std::shared_ptr<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 
423 private:
425  template <typename T>
426  std::pair<ndarray::Array<T const, 2, 2>, ndarray::Array<bool, 2, 2>> _toArray(
427  image::ImageBase<T> const& image,
428  std::shared_ptr<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
lsst::afw::image
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
Definition: imageAlgorithm.dox:1
lsst::afw::fits::ImageCompressionOptions::Tiles
ndarray::Array< long, 1, 1 > Tiles
Definition: fitsCompression.h:194
std::string
STL class.
std::shared_ptr
STL class.
lsst::afw::fits::ImageScalingOptions::algorithm
ScalingAlgorithm algorithm
Scaling algorithm to use.
Definition: fitsCompression.h:365
lsst::afw::fits::ImageScale::ImageScale
ImageScale(int bitpix_, double bscale_, double bzero_)
Constructor.
Definition: fitsCompression.h:276
lsst::afw::fits::ImageScale::bitpix
int bitpix
Bits per pixel; negative means floating-point: 8,16,32,64,-32,-64.
Definition: fitsCompression.h:263
lsst::afw::image::Mask
Represent a 2-dimensional array of bitmask pixels.
Definition: Mask.h:77
lsst::afw::fits::detail::PixelArrayBase
Abstract base class for an array of pixel values.
Definition: fitsCompression.h:75
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(CompressionAlgorithm algorithm_, Tiles tiles_, float quantizeLevel_=0.0)
Custom compression.
Definition: fitsCompression.h:201
lsst::afw::fits::compressionAlgorithmToCfitsio
int compressionAlgorithmToCfitsio(ImageCompressionOptions::CompressionAlgorithm algorithm)
Convert ImageCompressionOptions::CompressionAlgorithm to cfitsio.
Definition: fitsCompression.cc:72
lsst::afw::fits::detail::PixelArray::PixelArray
PixelArray()=delete
lsst::afw::fits::ImageCompressionOptions::CompressionAlgorithm
CompressionAlgorithm
Compression algorithms.
Definition: fitsCompression.h:187
lsst::afw::fits::ImageScalingOptions::bitpix
int bitpix
Bits per pixel (0, 8,16,32,64,-32,-64)
Definition: fitsCompression.h:366
lsst::afw::fits::ImageScale::blank
long blank
Value for integer images indicating non-finite values.
Definition: fitsCompression.h:266
lsst::afw::fits::detail::PixelArrayBase::~PixelArrayBase
virtual ~PixelArrayBase()
Definition: fitsCompression.h:77
std::pair
lsst::afw::fits::detail::makePixelArray
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.
Definition: fitsCompression.h:134
lsst::afw::fits::detail::PixelArray::~PixelArray
~PixelArray() override
Definition: fitsCompression.h:119
std::numeric_limits::quiet_NaN
T quiet_NaN(T... args)
arrays
ArrayKeyVector arrays
Definition: TransmissionCurve.cc:348
std::vector
STL class.
lsst::afw::fits::ImageCompressionOptions::quantizeLevel
float quantizeLevel
quantization level: 0.0 = none requires use of GZIP or GZIP_SHUFFLE
Definition: fitsCompression.h:198
lsst::afw::fits::ImageCompressionOptions::algorithm
CompressionAlgorithm algorithm
Compresion algorithm to use.
Definition: fitsCompression.h:196
lsst::afw::fits::ImageScale
Scale to apply to image.
Definition: fitsCompression.h:262
lsst::afw
Definition: imageAlgorithm.dox:1
lsst::afw::fits::ImageCompressionOptions::PLIO
@ PLIO
PLIO compression.
Definition: fitsCompression.h:192
lsst::afw::fits::detail::PixelArrayBase::getNumElements
std::size_t getNumElements() const
Return the number of pixels.
Definition: fitsCompression.h:83
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(image::Image< std::int64_t > const &image)
Definition: fitsCompression.h:231
lsst::afw::fits::ImageScalingOptions::quantizeLevel
float quantizeLevel
Divisor of the standard deviation for STDEV_* scaling.
Definition: fitsCompression.h:370
lsst::afw::fits::ImageScalingOptions::determine
ImageScale determine(ndarray::Array< T const, N, N > const &image, ndarray::Array< bool, N, N > const &mask) const
lsst::afw::geom.transform.transformContinued.name
string name
Definition: transformContinued.py:32
mask
afw::table::Key< afw::table::Array< MaskPixelT > > mask
Definition: HeavyFootprint.cc:217
lsst::afw::fits::ImageScalingOptions::seed
int seed
Seed for random number generator when fuzzing.
Definition: fitsCompression.h:368
Image.h
lsst::afw::fits::ImageCompressionOptions
Options for tile compression of image pixels.
Definition: fitsCompression.h:180
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(CompressionAlgorithm algorithm_, std::vector< long > tiles_, float quantizeLevel_=0.0)
Definition: fitsCompression.h:205
lsst::afw::fits::ImageScalingOptions::MANUAL
@ MANUAL
Scale set manually.
Definition: fitsCompression.h:363
lsst::afw::fits::ImageScalingOptions::STDEV_NEGATIVE
@ STDEV_NEGATIVE
Scale based on the standard deviation, dynamic range negative.
Definition: fitsCompression.h:361
lsst::afw::fits::detail::PixelArray::PixelArray
PixelArray(ndarray::Array< U, 1, 1 > const &array)
Construct from an ndarray::Array of different type.
Definition: fitsCompression.h:111
fits
Fits * fits
Definition: FitsWriter.cc:90
ndarray
Definition: SpanSetFunctorGetters.h:303
lsst::afw::fits::ImageScalingOptions::STDEV_POSITIVE
@ STDEV_POSITIVE
Scale based on the standard deviation. dynamic range positive.
Definition: fitsCompression.h:360
lsst::afw::fits::detail::PixelArray::getData
void const * getData() const override
Return a void* array of the pixels.
Definition: fitsCompression.h:121
lsst::afw::fits::detail::PixelArray::PixelArray
PixelArray(ndarray::Array< T, 1, 1 > const &array)
Construct from an ndarray::Array of the same type.
Definition: fitsCompression.h:102
lsst::afw::fits::ImageScalingOptions
Options for scaling image pixels.
Definition: fitsCompression.h:355
lsst::afw::fits::ImageScalingOptions::RANGE
@ RANGE
Scale to preserve dynamic range.
Definition: fitsCompression.h:359
lsst::afw::fits::ImageScalingOptions::NONE
@ NONE
No scaling.
Definition: fitsCompression.h:358
std::copy
T copy(T... args)
lsst::afw::fits::compressionAlgorithmFromString
ImageCompressionOptions::CompressionAlgorithm compressionAlgorithmFromString(std::string const &name)
Interpret compression algorithm expressed in string.
Definition: fitsCompression.cc:20
lsst::afw::fits::detail::PixelArray
Typed array of pixel values.
Definition: fitsCompression.h:94
lsst::afw::fits::detail::PixelArrayBase::getData
virtual void const * getData() const =0
Return a void* array of the pixels.
lsst::afw::fits::ImageScalingOptions::determine
ImageScale determine(image::ImageBase< T > const &image, std::shared_ptr< image::Mask< image::MaskPixel > const > mask=nullptr) const
Determine the scaling for a particular image.
Definition: fitsCompression.h:412
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
LSST_EXCEPT
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
std::ostringstream
STL class.
lsst::afw::fits::ImageScale::bzero
double bzero
Zero-point to apply when reading from FITS.
Definition: fitsCompression.h:265
lsst::afw::fits::detail::PixelArrayBase::PixelArrayBase
PixelArrayBase(std::size_t num)
Definition: fitsCompression.h:86
os
std::ostream * os
Definition: Schema.cc:746
lsst::afw::fits::ImageCompressionOptions::GZIP
@ GZIP
Standard GZIP compression.
Definition: fitsCompression.h:189
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(image::Mask< T > const &mask)
Definition: fitsCompression.h:227
Mask.h
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(image::Image< std::uint64_t > const &image)
Definition: fitsCompression.h:234
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(image::Mask< std::int64_t > const &mask)
Definition: fitsCompression.h:233
lsst::afw::fits::ImageScale::bscale
double bscale
Scale to apply when reading from FITS.
Definition: fitsCompression.h:264
lsst::pex::exceptions::InvalidParameterError
Reports invalid arguments.
Definition: Runtime.h:66
lsst::afw::fits::scalingAlgorithmToString
std::string scalingAlgorithmToString(ImageScalingOptions::ScalingAlgorithm algorithm)
Provide string version of compression algorithm.
Definition: fitsCompression.cc:109
std::vector::cbegin
T cbegin(T... args)
lsst::afw::fits::ImageScalingOptions::bscale
double bscale
Manually specified BSCALE (for MANUAL scaling)
Definition: fitsCompression.h:372
lsst::afw::fits::ImageScalingOptions::ImageScalingOptions
ImageScalingOptions(int bitpix_, double bscale_=1.0, double bzero_=0.0)
Manual scaling Ctor.
Definition: fitsCompression.h:403
std
STL namespace.
lsst::afw::fits::detail::PixelArray::PixelArray
PixelArray(PixelArray const &)=delete
lsst::afw::fits::ImageScalingOptions::ImageScalingOptions
ImageScalingOptions()
Default Ctor.
Definition: fitsCompression.h:378
lsst::afw::fits::compressionAlgorithmToString
std::string compressionAlgorithmToString(ImageCompressionOptions::CompressionAlgorithm algorithm)
Provide string version of compression algorithm.
Definition: fitsCompression.cc:31
lsst::afw::fits::ImageScalingOptions::fuzz
bool fuzz
Fuzz the values when quantising floating-point values?
Definition: fitsCompression.h:367
std::remove_const
lsst::afw::fits::ImageScalingOptions::bzero
double bzero
Manually specified BZERO (for MANUAL scaling)
Definition: fitsCompression.h:373
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(image::Mask< std::uint64_t > const &mask)
Definition: fitsCompression.h:236
std::size_t
lsst::afw::fits::ImageScalingOptions::STDEV_BOTH
@ STDEV_BOTH
Scale based on the standard deviation, dynamic range positive+negative.
Definition: fitsCompression.h:362
std::make_pair
T make_pair(T... args)
lsst::afw::fits::ImageCompressionOptions::ImageCompressionOptions
ImageCompressionOptions(image::Image< T > const &image)
Default compression for a particular style of image.
Definition: fitsCompression.h:224
std::vector::cend
T cend(T... args)
lsst::afw::fits::ImageScalingOptions::quantizePad
float quantizePad
Number of stdev to allow on the low/high side (for STDEV_POSITIVE/NEGATIVE)
Definition: fitsCompression.h:371
lsst::afw::fits::detail::Bitpix
FITS BITPIX header value by C++ type.
Definition: fitsCompression.h:29
lsst::afw::fits::ImageCompressionOptions::NONE
@ NONE
No compression.
Definition: fitsCompression.h:188
lsst::afw::fits::compressionAlgorithmFromCfitsio
ImageCompressionOptions::CompressionAlgorithm compressionAlgorithmFromCfitsio(int cfitsio)
Convert compression algorithm from cfitsio to ImageCompressionOptions::CompressionAlgorithm.
Definition: fitsCompression.cc:50
lsst::afw::image::Image
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:58
lsst::geom::floor
Extent< int, N > floor(Extent< double, N > const &input) noexcept
Return the component-wise floor (round towards more negative).
Definition: Extent.cc:109
lsst::afw::fits::ImageCompressionOptions::tiles
Tiles tiles
Tile size; a dimension with 0 means infinite (e.g., to specify one row: 0,1)
Definition: fitsCompression.h:197
lsst::afw::fits::ImageScale::toFits
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.
Definition: fitsCompression.cc:409
lsst::afw::fits::ImageScalingOptions::maskPlanes
std::vector< std::string > maskPlanes
Mask planes to ignore when doing statistics.
Definition: fitsCompression.h:369
lsst::afw::image::ImageBase
The base class for all image classed (Image, Mask, MaskedImage, ...)
Definition: ImageBase.h:102
lsst::afw::fits::ImageScalingOptions::ScalingAlgorithm
ScalingAlgorithm
Definition: fitsCompression.h:357
lsst::afw::fits::scalingAlgorithmFromString
ImageScalingOptions::ScalingAlgorithm scalingAlgorithmFromString(std::string const &name)
Interpret scaling algorithm expressed in string.
Definition: fitsCompression.cc:99
exceptions.h
lsst::afw::fits::ImageCompressionOptions::GZIP_SHUFFLE
@ GZIP_SHUFFLE
GZIP compression with shuffle (most-significant byte first)
Definition: fitsCompression.h:190
base.h
lsst::afw::fits::ImageScale::fromFits
ndarray::Array< T, 2, 2 > fromFits(ndarray::Array< T, 2, 2 > const &image) const
Convert to an array.
Definition: fitsCompression.cc:486
lsst::afw::fits::ImageCompressionOptions::RICE
@ RICE
RICE compression.
Definition: fitsCompression.h:191