LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
fits.h
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2#ifndef LSST_AFW_fits_h_INCLUDED
3#define LSST_AFW_fits_h_INCLUDED
4
5/*
6 * Utilities for working with FITS files. These are mostly thin wrappers around
7 * cfitsio calls, and their main purpose is to transform functions signatures from
8 * void pointers and cfitsio's preprocessor type enums to a more type-safe and
9 * convenient interface using overloads and templates.
10 *
11 * This was written as part of implementing the afw/table library. Someday
12 * the afw/image FITS I/O should be modified to use some of these with the goal
13 * of eliminating a lot of code between the two.
14 */
15
16#include <climits>
17#include <string>
18#include <set>
19
20#include <boost/format.hpp>
21
22#include "lsst/base.h"
23#include "lsst/pex/exceptions.h"
24#include "lsst/daf/base.h"
25#include "ndarray.h"
28
29namespace lsst {
30namespace afw {
31namespace fits {
32
37
38
42
50public:
51 virtual void operator()(std::string const& key, std::string const& value, std::string const& comment) = 0;
52
54};
55
64std::string makeErrorMessage(std::string const& fileName = "", int status = 0, std::string const& msg = "");
65inline std::string makeErrorMessage(std::string const& fileName, int status, boost::format const& msg) {
66 return makeErrorMessage(fileName, status, msg.str());
67}
68
78std::string makeErrorMessage(void* fptr, int status = 0, std::string const& msg = "");
79inline std::string makeErrorMessage(void* fptr, int status, boost::format const& msg) {
80 return makeErrorMessage(fptr, status, msg.str());
81}
82
99 std::set<std::string> const& excludeNames = {});
100
105#define LSST_FITS_EXCEPT(type, fitsObj, ...) \
106 type(LSST_EXCEPT_HERE, lsst::afw::fits::makeErrorMessage((fitsObj).fptr, (fitsObj).status, __VA_ARGS__))
107
111#define LSST_FITS_CHECK_STATUS(fitsObj, ...) \
112 if ((fitsObj).status != 0) throw LSST_FITS_EXCEPT(lsst::afw::fits::FitsError, fitsObj, __VA_ARGS__)
113
115template <typename T>
116int getBitPix();
117
122public:
129 MemFileManager() : _ptr(nullptr), _len(0), _managed(true) {}
130
137 explicit MemFileManager(std::size_t len) : _ptr(nullptr), _len(0), _managed(true) { reset(len); }
138
146 MemFileManager(void* ptr, std::size_t len) : _ptr(ptr), _len(len), _managed(false) {}
147
153 void reset();
154
163 void reset(std::size_t len);
164
173 void reset(void* ptr, std::size_t len) {
174 reset();
175 _ptr = ptr;
176 _len = len;
177 _managed = false;
178 }
179
181
182 // No copying
185
186 // No moving
189
191 void* getData() const { return _ptr; }
192
194 std::size_t getLength() const { return _len; }
195
196private:
197 friend class Fits;
198
199 void* _ptr;
200 std::size_t _len;
201 bool _managed;
202};
203
207template <typename T, int N, int C>
208ndarray::Array<T const, N, N> const makeContiguousArray(ndarray::Array<T, N, C> const& array) {
209 ndarray::Array<T const, N, N> contiguous = ndarray::dynamic_dimension_cast<N>(array);
210 if (contiguous.empty()) contiguous = ndarray::copy(array);
211 return contiguous;
212}
213
222
224 template <typename T>
226
228 template <typename T>
230
232 explicit ImageWriteOptions(ImageCompressionOptions const& compression_ =
234 ImageScalingOptions const& scaling_ = ImageScalingOptions())
235 : compression(compression_), scaling(scaling_) {}
236
238 explicit ImageWriteOptions(ImageScalingOptions const& scaling_)
239 : compression(ImageCompressionOptions::NONE), scaling(scaling_) {}
240
266
279};
280
297class Fits {
298 void createImageImpl(int bitpix, int nAxis, long const* nAxes);
299 template <typename T>
300 void writeImageImpl(T const* data, int nElements);
301 template <typename T>
302 void readImageImpl(int nAxis, T* data, long* begin, long* end, long* increment);
303 void getImageShapeImpl(int maxDim, long* nAxes);
304
305public:
307 AUTO_CLOSE = 0x01, // Close files when the Fits object goes out of scope if fptr != NULL
308 AUTO_CHECK = 0x02 // Call LSST_FITS_CHECK_STATUS after every cfitsio call
309 };
310
312 std::string getFileName() const;
313
315 int getHdu();
316
326 void setHdu(int hdu, bool relative = false);
327
329 int countHdus();
330
332
333 template <typename T>
334 void updateKey(std::string const& key, T const& value, std::string const& comment);
335 void updateKey(std::string const& key, char const* value, std::string const& comment) {
336 updateKey(key, std::string(value), comment);
337 }
338 template <typename T>
339 void updateKey(std::string const& key, T const& value);
340 void updateKey(std::string const& key, char const* value) { updateKey(key, std::string(value)); }
342
344
351 template <typename T>
352 void writeKey(std::string const& key, T const& value, std::string const& comment);
353 void writeKey(std::string const& key, char const* value, std::string const& comment) {
354 writeKey(key, std::string(value), comment);
355 }
356 template <typename T>
357 void writeKey(std::string const& key, T const& value);
358 void writeKey(std::string const& key, char const* value) { writeKey(key, std::string(value)); }
360
362
363 template <typename T>
364 void updateColumnKey(std::string const& prefix, int n, T const& value, std::string const& comment);
365 void updateColumnKey(std::string const& prefix, int n, char const* value, std::string const& comment) {
366 updateColumnKey(prefix, n, std::string(value), comment);
367 }
368 template <typename T>
369 void updateColumnKey(std::string const& prefix, int n, T const& value);
370 void updateColumnKey(std::string const& prefix, int n, char const* value) {
372 }
374
376
377 template <typename T>
378 void writeColumnKey(std::string const& prefix, int n, T const& value, std::string const& comment);
379 void writeColumnKey(std::string const& prefix, int n, char const* value, std::string const& comment) {
380 writeColumnKey(prefix, n, std::string(value), comment);
381 }
382 template <typename T>
383 void writeColumnKey(std::string const& prefix, int n, T const& value);
384 void writeColumnKey(std::string const& prefix, int n, char const* value) {
386 }
388
398 void writeMetadata(daf::base::PropertySet const& metadata);
399
409 void readMetadata(daf::base::PropertySet& metadata, bool strip = false);
410
412 template <typename T>
413 void readKey(std::string const& key, T& value);
414
423 void forEachKey(HeaderIterationFunctor& functor);
424
431 void createEmpty();
432
443 template <typename PixelT, int N>
444 void createImage(ndarray::Vector<ndarray::Size, N> const& shape) {
445 ndarray::Vector<long, N> nAxes(shape.reverse());
446 createImageImpl(detail::Bitpix<PixelT>::value, N, nAxes.elems);
447 }
448
449 template <int N>
450 void createImage(int bitpix, ndarray::Vector<ndarray::Size, N> const& shape) {
451 ndarray::Vector<long, N> nAxes(shape.reverse());
452 createImageImpl(bitpix, N, nAxes.elems);
453 }
454
461 template <typename PixelT>
462 void createImage(long x, long y) {
463 long naxes[2] = {x, y};
464 createImageImpl(detail::Bitpix<PixelT>::value, 2, naxes);
465 }
466
476 template <typename T, int N, int C>
477 void writeImage(ndarray::Array<T const, N, C> const& array) {
478 writeImageImpl(makeContiguousArray(array).getData(), array.getNumElements());
479 }
480
482
494 template <typename T>
495 void writeImage(
496 image::ImageBase<T> const& image, ImageWriteOptions const& options,
497 daf::base::PropertySet const * header = nullptr,
498 image::Mask<image::MaskPixel> const * mask = nullptr);
499 template <typename T>
500 [[deprecated("Replaced by a non-shared_ptr overload. Will be removed after v25.")]]
501 void writeImage(
502 image::ImageBase<T> const& image, ImageWriteOptions const& options,
506
508 int getImageDim();
509
518 template <int N>
519 ndarray::Vector<ndarray::Size, N> getImageShape() {
520 ndarray::Vector<long, N> nAxes(1);
521 getImageShapeImpl(N, nAxes.elems);
522 ndarray::Vector<ndarray::Size, N> shape;
523 for (int i = 0; i < N; ++i) shape[i] = nAxes[N - i - 1];
524 return shape;
525 }
526
533 template <typename T>
534 bool checkImageType();
535
540
547 template <typename T, int N>
548 void readImage(ndarray::Array<T, N, N> const& array, ndarray::Vector<int, N> const& offset) {
549 ndarray::Vector<long, N> begin(offset.reverse());
550 ndarray::Vector<long, N> end(begin);
551 end += array.getShape().reverse();
552 ndarray::Vector<long, N> increment(1);
553 begin += increment; // first FITS pixel is 1, not 0
554 readImageImpl(N, array.getData(), begin.elems, end.elems, increment.elems);
555 }
556
558 void createTable();
559
566 template <typename T>
567 int addColumn(std::string const& ttype, int size, std::string const& comment);
568
575 template <typename T>
576 int addColumn(std::string const& ttype, int size);
577
580
583
585 template <typename T>
586 void writeTableArray(std::size_t row, int col, int nElements, T const* value);
587
589 template <typename T>
591 writeTableArray(row, col, 1, &value);
592 }
594 void writeTableScalar(std::size_t row, int col, std::string const& value);
595
597 template <typename T>
598 void readTableArray(std::size_t row, int col, int nElements, T* value);
599
601 template <typename T>
602 void readTableScalar(std::size_t row, int col, T& value) {
603 readTableArray(row, col, 1, &value);
604 }
605
607 void readTableScalar(std::size_t row, int col, std::string& value, bool isVariableLength);
608
610 long getTableArraySize(int col);
611
614
616 Fits() : fptr(nullptr), status(0), behavior(0) {}
617
619 Fits(std::string const& filename, std::string const& mode, int behavior);
620
622 Fits(MemFileManager& manager, std::string const& mode, int behavior);
623
625 void closeFile();
626
630 void setImageCompression(ImageCompressionOptions const& options);
631
634
643
645 if ((fptr) && (behavior & AUTO_CLOSE)) closeFile();
646 }
647
648 // No copying
649 Fits(const Fits&) = delete;
650 Fits& operator=(const Fits&) = delete;
651
652 // No moving
653 Fits(Fits&&) = delete;
654 Fits& operator=(Fits&&) = delete;
655
656 void* fptr; // the actual cfitsio fitsfile pointer; void to avoid including fitsio.h here.
657 int status; // the cfitsio status indicator that gets passed to every cfitsio call.
658 int behavior; // bitwise OR of BehaviorFlags
659};
660
662
682[[deprecated("Replaced by a non-shared_ptr overload. Will be removed after v25.")]]
687
699 bool strip = false);
711 bool strip = false);
722
723void setAllowImageCompression(bool allow);
725
726
727
738public:
739
740 HduMoveGuard() = delete;
741
742 HduMoveGuard(HduMoveGuard const &) = delete;
744
747
759 HduMoveGuard(Fits & fits, int hdu, bool relative=false);
760
762
764 void disable() { _enabled = false; }
765
766private:
767 Fits & _fits;
768 int _oldHdu;
769 bool _enabled;
770};
771
772
773} // namespace fits
774} // namespace afw
775} // namespace lsst
776
777#endif // !LSST_AFW_fits_h_INCLUDED
char * data
Definition: BaseRecord.cc:61
int end
double x
#define LSST_EXCEPTION_TYPE(t, b, c)
Macro used to define new types of exceptions without additional data.
Definition: Exception.h:69
Fits * fits
Definition: FitsWriter.cc:90
afw::table::Key< afw::table::Array< MaskPixelT > > mask
uint64_t * ptr
Definition: RangeSet.cc:88
std::string prefix
Definition: SchemaMapper.cc:72
int y
Definition: SpanSet.cc:48
Basic LSST definitions.
An exception thrown when problems are found when reading or writing FITS files.
Definition: fits.h:36
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition: fits.h:297
void writeKey(std::string const &key, char const *value)
Definition: fits.h:358
void updateKey(std::string const &key, char const *value)
Definition: fits.h:340
void readImage(ndarray::Array< T, N, N > const &array, ndarray::Vector< int, N > const &offset)
Read an array from a FITS image.
Definition: fits.h:548
void writeKey(std::string const &key, T const &value, std::string const &comment)
Add a FITS header key to the bottom of the header.
Definition: fits.cc:667
void writeColumnKey(std::string const &prefix, int n, T const &value, std::string const &comment)
Write a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.
Definition: fits.cc:699
void closeFile()
Close a FITS file.
Definition: fits.cc:1630
void writeImage(ndarray::Array< T const, N, C > const &array)
Write an ndarray::Array to a FITS image HDU.
Definition: fits.h:477
void writeKey(std::string const &key, char const *value, std::string const &comment)
Definition: fits.h:353
int getImageDim()
Return the number of dimensions in the current HDU.
Definition: fits.cc:1429
void writeColumnKey(std::string const &prefix, int n, char const *value)
Definition: fits.h:384
void createImage(int bitpix, ndarray::Vector< ndarray::Size, N > const &shape)
Definition: fits.h:450
std::size_t countRows()
Return the number of row in a table.
Definition: fits.cc:1159
ImageCompressionOptions getImageCompression()
Return the current image compression settings.
Definition: fits.cc:1502
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
Definition: fits.cc:1240
void createImage(long x, long y)
Create a 2-d image with pixel type provided by the given explicit PixelT template parameter.
Definition: fits.h:462
void readTableArray(std::size_t row, int col, int nElements, T *value)
Read an array value from a binary table.
Definition: fits.cc:1192
Fits & operator=(const Fits &)=delete
void writeColumnKey(std::string const &prefix, int n, char const *value, std::string const &comment)
Definition: fits.h:379
void updateColumnKey(std::string const &prefix, int n, T const &value, std::string const &comment)
Update a key of the form XXXXXnnn, where XXXXX is the prefix and nnn is a column number.
Definition: fits.cc:691
void setHdu(int hdu, bool relative=false)
Set the current HDU.
Definition: fits.cc:513
void createTable()
Create a new binary table extension.
Definition: fits.cc:1117
Fits()
Default constructor; set all data members to 0.
Definition: fits.h:616
void readTableScalar(std::size_t row, int col, T &value)
Read an array scalar from a binary table.
Definition: fits.h:602
void updateKey(std::string const &key, char const *value, std::string const &comment)
Definition: fits.h:335
bool checkCompressedImagePhu()
Go to the first image header in the FITS file.
Definition: fits.cc:1745
int countHdus()
Return the number of HDUs in the file.
Definition: fits.cc:534
void writeTableScalar(std::size_t row, int col, T value)
Write a scalar value to a binary table.
Definition: fits.h:590
void createImage(ndarray::Vector< ndarray::Size, N > const &shape)
Create an image with pixel type provided by the given explicit PixelT template parameter and shape de...
Definition: fits.h:444
void forEachKey(HeaderIterationFunctor &functor)
Call a polymorphic functor for every key in the header.
Definition: fits.cc:781
std::string getFileName() const
Return the file name associated with the FITS object or "<unknown>" if there is none.
Definition: fits.cc:498
int addColumn(std::string const &ttype, int size, std::string const &comment)
Add a column to a table.
Definition: fits.cc:1140
void updateColumnKey(std::string const &prefix, int n, char const *value)
Definition: fits.h:370
Fits(const Fits &)=delete
void updateKey(std::string const &key, T const &value, std::string const &comment)
Set a FITS header key, editing if it already exists and appending it if not.
Definition: fits.cc:659
void setImageCompression(ImageCompressionOptions const &options)
Set compression options for writing FITS images.
Definition: fits.cc:1525
void readMetadata(daf::base::PropertySet &metadata, bool strip=false)
Read a FITS header into a PropertySet or PropertyList.
Definition: fits.cc:1087
void writeTableArray(std::size_t row, int col, int nElements, T const *value)
Write an array value to a binary table.
Definition: fits.cc:1169
void readKey(std::string const &key, T &value)
Read a FITS header key into the given reference.
Definition: fits.cc:774
std::string getImageDType()
Return the numpy dtype equivalent of the image pixel type (e.g.
Definition: fits.cc:1473
ndarray::Vector< ndarray::Size, N > getImageShape()
Return the shape of the current (image) HDU.
Definition: fits.h:519
int getHdu()
Return the current HDU (0-indexed; 0 is the Primary HDU).
Definition: fits.cc:507
void updateColumnKey(std::string const &prefix, int n, char const *value, std::string const &comment)
Definition: fits.h:365
Fits & operator=(Fits &&)=delete
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
Definition: fits.cc:1095
Fits(Fits &&)=delete
long getTableArraySize(int col)
Return the size of an array column.
Definition: fits.cc:1217
std::size_t addRows(std::size_t nRows)
Append rows to a table, and return the index of the first new row.
Definition: fits.cc:1149
bool checkImageType()
Return true if the current HDU is compatible with the given pixel type.
Definition: fits.cc:1442
An exception thrown when a FITS file has the wrong type.
Definition: fits.h:41
RAII scoped guard for moving the HDU in a Fits object.
Definition: fits.h:737
HduMoveGuard(HduMoveGuard &&)=delete
HduMoveGuard(HduMoveGuard const &)=delete
void disable()
Disable the guard, leaving the HDU at its current state at destruction.
Definition: fits.h:764
HduMoveGuard & operator=(HduMoveGuard const &)=delete
HduMoveGuard & operator=(HduMoveGuard &&)=delete
Base class for polymorphic functors used to iterator over FITS key headers.
Definition: fits.h:49
virtual void operator()(std::string const &key, std::string const &value, std::string const &comment)=0
Options for scaling image pixels.
Lifetime-management for memory that goes into FITS memory files.
Definition: fits.h:121
MemFileManager(MemFileManager &&)=delete
MemFileManager & operator=(MemFileManager &&)=delete
MemFileManager(void *ptr, std::size_t len)
Construct a MemFileManager that references and does not manage external memory.
Definition: fits.h:146
MemFileManager()
Construct a MemFileManager with no initial memory buffer.
Definition: fits.h:129
void reset(void *ptr, std::size_t len)
Set the internal memory buffer to an manually-managed external block.
Definition: fits.h:173
MemFileManager(std::size_t len)
Construct a MemFileManager with (len) bytes of initial memory.
Definition: fits.h:137
void * getData() const
Return the buffer.
Definition: fits.h:191
MemFileManager & operator=(const MemFileManager &)=delete
void reset()
Return the manager to the same state it would be if default-constructed.
Definition: fits.cc:475
MemFileManager(const MemFileManager &)=delete
std::size_t getLength() const
Return the buffer length.
Definition: fits.h:194
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:77
Class for storing ordered metadata with comments.
Definition: PropertyList.h:68
Class for storing generic metadata.
Definition: PropertySet.h:66
Reports errors in external input/output operations.
Definition: Runtime.h:160
bool strip
Definition: fits.cc:911
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.
Definition: fits.cc:1635
const int DEFAULT_HDU
Specify that the default HDU should be read.
Definition: fitsDefaults.h:18
int getBitPix()
Return the cfitsio integer BITPIX code for the given data type.
Definition: fits.cc:490
std::shared_ptr< daf::base::PropertyList > readMetadata(std::string const &fileName, int hdu=DEFAULT_HDU, bool strip=false)
Read FITS header.
Definition: fits.cc:1676
void setAllowImageCompression(bool allow)
Definition: fits.cc:1553
std::string makeErrorMessage(std::string const &fileName="", int status=0, std::string const &msg="")
Return an error message reflecting FITS I/O errors.
Definition: fits.cc:426
bool getAllowImageCompression()
Definition: fits.cc:1555
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.
Definition: fits.cc:457
ndarray::Array< T const, N, N > const makeContiguousArray(ndarray::Array< T, N, C > const &array)
Construct a contiguous ndarray.
Definition: fits.h:208
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A base class for image defects.
int row
Definition: CR.cc:145
int col
Definition: CR.cc:144
Options for tile compression of image pixels.
Options for writing an image to FITS.
Definition: fits.h:219
ImageCompressionOptions compression
Options controlling compression.
Definition: fits.h:220
ImageScalingOptions scaling
Options controlling scaling.
Definition: fits.h:221
ImageWriteOptions(ImageScalingOptions const &scaling_)
Construct with specific scaling options.
Definition: fits.h:238
static std::shared_ptr< daf::base::PropertySet > validate(daf::base::PropertySet const &config)
Validate a PropertySet.
Definition: fits.cc:1800
ImageWriteOptions(image::Image< T > const &image)
Construct with default options for images.
Definition: fits.h:225
ImageWriteOptions(ImageCompressionOptions const &compression_=ImageCompressionOptions(ImageCompressionOptions::NONE), ImageScalingOptions const &scaling_=ImageScalingOptions())
Construct with specific compression and scaling options.
Definition: fits.h:232
ImageWriteOptions(image::Mask< T > const &mask)
Construct with default options for masks.
Definition: fits.h:229
FITS BITPIX header value by C++ type.