LSST Applications g00d0e8bbd7+edbf708997,g03191d30f7+9ce8016dbd,g1955dfad08+0bd186d245,g199a45376c+5137f08352,g1fd858c14a+a888a50aa2,g262e1987ae+45f9aba685,g29ae962dfc+1c7d47a24f,g2cef7863aa+73c82f25e4,g35bb328faa+edbf708997,g3fd5ace14f+eed17d2c67,g47891489e3+6dc8069a4c,g53246c7159+edbf708997,g64539dfbff+c4107e45b5,g67b6fd64d1+6dc8069a4c,g74acd417e5+f452e9c21a,g786e29fd12+af89c03590,g7ae74a0b1c+a25e60b391,g7aefaa3e3d+2025e9ce17,g7cc15d900a+2d158402f9,g87389fa792+a4172ec7da,g89139ef638+6dc8069a4c,g8d4809ba88+c4107e45b5,g8d7436a09f+e96c132b44,g8ea07a8fe4+db21c37724,g98df359435+aae6d409c1,ga2180abaac+edbf708997,gac66b60396+966efe6077,gb632fb1845+88945a90f8,gbaa8f7a6c5+38b34f4976,gbf99507273+edbf708997,gca7fc764a6+6dc8069a4c,gd7ef33dd92+6dc8069a4c,gda68eeecaf+7d1e613a8d,gdab6d2f7ff+f452e9c21a,gdbb4c4dda9+c4107e45b5,ge410e46f29+6dc8069a4c,ge41e95a9f2+c4107e45b5,geaed405ab2+e194be0d2b,w.2025.47
LSST Data Management Base Package
Loading...
Searching...
No Matches
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 <optional>
18#include <string>
19#include <set>
20
21#include <boost/format.hpp>
22
23#include "lsst/base.h"
24#include "lsst/pex/exceptions.h"
25#include "lsst/daf/base.h"
26#include "ndarray.h"
29
30namespace lsst {
31namespace afw {
32namespace fits {
33
38
39
43
51public:
52 virtual void operator()(std::string const& key, std::string const& value, std::string const& comment) = 0;
53
55};
56
65std::string makeErrorMessage(std::string const& fileName = "", int status = 0, std::string const& msg = "");
66inline std::string makeErrorMessage(std::string const& fileName, int status, boost::format const& msg) {
67 return makeErrorMessage(fileName, status, msg.str());
68}
69
79std::string makeErrorMessage(void* fptr, int status = 0, std::string const& msg = "");
80inline std::string makeErrorMessage(void* fptr, int status, boost::format const& msg) {
81 return makeErrorMessage(fptr, status, msg.str());
82}
83
100 std::set<std::string> const& excludeNames = {});
101
106#define LSST_FITS_EXCEPT(type, fitsObj, ...) \
107 type(LSST_EXCEPT_HERE, lsst::afw::fits::makeErrorMessage((fitsObj).fptr, (fitsObj).status, __VA_ARGS__))
108
112#define LSST_FITS_CHECK_STATUS(fitsObj, ...) \
113 if ((fitsObj).status != 0) { \
114 auto except = LSST_FITS_EXCEPT(lsst::afw::fits::FitsError, fitsObj, __VA_ARGS__); \
115 (fitsObj).status = 0; \
116 throw except; \
117 }
118
120template <typename T>
121int getBitPix();
122
127public:
134 MemFileManager() : _ptr(nullptr), _len(0), _managed(true) {}
135
142 explicit MemFileManager(std::size_t len) : _ptr(nullptr), _len(0), _managed(true) { reset(len); }
143
151 MemFileManager(void* ptr, std::size_t len) : _ptr(ptr), _len(len), _managed(false) {}
152
158 void reset();
159
168 void reset(std::size_t len);
169
178 void reset(void* ptr, std::size_t len) {
179 reset();
180 _ptr = ptr;
181 _len = len;
182 _managed = false;
183 }
184
186
187 // No copying
190
191 // No moving
194
196 void* getData() const { return _ptr; }
197
199 std::size_t getLength() const { return _len; }
200
201private:
202 friend class Fits;
203
204 void* _ptr;
205 std::size_t _len;
206 bool _managed;
207};
208
212template <typename T, int N, int C>
213ndarray::Array<T const, N, N> const makeContiguousArray(ndarray::Array<T, N, C> const& array) {
214 ndarray::Array<T const, N, N> contiguous = ndarray::dynamic_dimension_cast<N>(array);
215 if (contiguous.empty()) contiguous = ndarray::copy(array);
216 return contiguous;
217}
218
224enum class HduType : int { IMAGE = 0, ASCII_TABLE = 1, BIN_TABLE = 2, ANY = -1 };
225
242class Fits {
243 void createImageImpl(int bitpix, int nAxis, long const* nAxes);
244 template <typename T>
245 void writeImageImpl(T const* data, int nElements, std::optional<T> explicit_null = std::nullopt);
246 template <typename T>
247 void readImageImpl(int nAxis, T* data, long* begin, long* end, long* increment);
248 void getImageShapeImpl(int maxDim, long* nAxes);
249
250public:
252 AUTO_CLOSE = 0x01, // Close files when the Fits object goes out of scope if fptr != NULL
253 AUTO_CHECK = 0x02 // Call LSST_FITS_CHECK_STATUS after every cfitsio call
254 };
255
257 std::string getFileName() const;
258
260 int getHdu();
261
271 void setHdu(int hdu, bool relative = false);
272
281 void setHdu(std::string const& name, HduType hdutype = HduType::ANY, int hduver = 0);
282
284 int countHdus();
285
287
288 template <typename T>
289 void updateKey(std::string const& key, T const& value, std::string const& comment);
290 void updateKey(std::string const& key, char const* value, std::string const& comment) {
291 updateKey(key, std::string(value), comment);
292 }
293 template <typename T>
294 void updateKey(std::string const& key, T const& value);
295 void updateKey(std::string const& key, char const* value) { updateKey(key, std::string(value)); }
297
299
306 template <typename T>
307 void writeKey(std::string const& key, T const& value, std::string const& comment);
308 void writeKey(std::string const& key, char const* value, std::string const& comment) {
309 writeKey(key, std::string(value), comment);
310 }
311 template <typename T>
312 void writeKey(std::string const& key, T const& value);
313 void writeKey(std::string const& key, char const* value) { writeKey(key, std::string(value)); }
315
317
318 template <typename T>
319 void updateColumnKey(std::string const& prefix, int n, T const& value, std::string const& comment);
320 void updateColumnKey(std::string const& prefix, int n, char const* value, std::string const& comment) {
321 updateColumnKey(prefix, n, std::string(value), comment);
322 }
323 template <typename T>
324 void updateColumnKey(std::string const& prefix, int n, T const& value);
325 void updateColumnKey(std::string const& prefix, int n, char const* value) {
326 updateColumnKey(prefix, n, std::string(value));
327 }
328
329
331
332 template <typename T>
333 void writeColumnKey(std::string const& prefix, int n, T const& value, std::string const& comment);
334 void writeColumnKey(std::string const& prefix, int n, char const* value, std::string const& comment) {
335 writeColumnKey(prefix, n, std::string(value), comment);
336 }
337 template <typename T>
338 void writeColumnKey(std::string const& prefix, int n, T const& value);
339 void writeColumnKey(std::string const& prefix, int n, char const* value) {
340 writeColumnKey(prefix, n, std::string(value));
341 }
342
343
353 void writeMetadata(daf::base::PropertySet const& metadata);
354
364 void readMetadata(daf::base::PropertySet& metadata, bool strip = false);
365
367 template <typename T>
368 void readKey(std::string const& key, T& value);
369
378 void forEachKey(HeaderIterationFunctor& functor);
379
386 void createEmpty();
387
389
399 template <typename PixelT, int N>
400 void createImage(ndarray::Vector<ndarray::Size, N> const& shape) {
401 ndarray::Vector<long, N> nAxes(shape.reverse());
402 createImageImpl(getBitPix<PixelT>(), N, nAxes.elems);
403 }
404
405 template <int N>
406 void createImage(int bitpix, ndarray::Vector<ndarray::Size, N> const& shape) {
407 ndarray::Vector<long, N> nAxes(shape.reverse());
408 createImageImpl(bitpix, N, nAxes.elems);
409 }
410
411
418 template <typename PixelT>
419 void createImage(long x, long y) {
420 long naxes[2] = {x, y};
421 createImageImpl(getBitPix<PixelT>(), 2, naxes);
422 }
423
433 template <typename T, int N, int C>
434 void writeImage(ndarray::Array<T const, N, C> const& array) {
435 writeImageImpl(makeContiguousArray(array).getData(), array.getNumElements());
436 }
437
439
451 template <typename T>
452 void writeImage(
453 image::ImageBase<T> const& image, CompressionOptions const * compression = nullptr,
454 daf::base::PropertySet const * header = nullptr,
455 image::Mask<image::MaskPixel> const * mask = nullptr);
457
459 int getImageDim();
460
469 template <int N>
470 ndarray::Vector<ndarray::Size, N> getImageShape() {
471 ndarray::Vector<long, N> nAxes(1);
472 getImageShapeImpl(N, nAxes.elems);
473 ndarray::Vector<ndarray::Size, N> shape;
474 for (int i = 0; i < N; ++i) shape[i] = nAxes[N - i - 1];
475 return shape;
476 }
477
484 template <typename T>
485 bool checkImageType();
486
491
498 template <typename T, int N>
499 void readImage(ndarray::Array<T, N, N> const& array, ndarray::Vector<int, N> const& offset) {
500 ndarray::Vector<long, N> begin(offset.reverse());
501 ndarray::Vector<long, N> end(begin);
502 end += array.getShape().reverse();
503 ndarray::Vector<long, N> increment(1);
504 begin += increment; // first FITS pixel is 1, not 0
505 readImageImpl(N, array.getData(), begin.elems, end.elems, increment.elems);
506 }
507
509 void createTable();
510
517 template <typename T>
518 int addColumn(std::string const& ttype, int size, std::string const& comment);
519
526 template <typename T>
527 int addColumn(std::string const& ttype, int size);
528
531
534
536 template <typename T>
537 void writeTableArray(std::size_t row, int col, int nElements, T const* value);
538
540 template <typename T>
541 void writeTableScalar(std::size_t row, int col, T value) {
542 writeTableArray(row, col, 1, &value);
543 }
544
545 void writeTableScalar(std::size_t row, int col, std::string const& value);
546
548 template <typename T>
549 void readTableArray(std::size_t row, int col, int nElements, T* value);
550
552 template <typename T>
553 void readTableScalar(std::size_t row, int col, T& value) {
554 readTableArray(row, col, 1, &value);
555 }
556
558 void readTableScalar(std::size_t row, int col, std::string& value, bool isVariableLength);
559
561 long getTableArraySize(int col);
562
564 long getTableArraySize(std::size_t row, int col);
565
567 Fits() : fptr(nullptr), status(0), behavior(0) {}
568
570 Fits(std::string const& filename, std::string const& mode, int behavior);
571
573 Fits(MemFileManager& manager, std::string const& mode, int behavior);
574
576 void closeFile();
577
586
588 if ((fptr) && (behavior & AUTO_CLOSE)) closeFile();
589 }
590
591 // No copying
592 Fits(const Fits&) = delete;
593 Fits& operator=(const Fits&) = delete;
594
595 // No moving
596 Fits(Fits&&) = delete;
597 Fits& operator=(Fits&&) = delete;
598
599 void* fptr; // the actual cfitsio fitsfile pointer; void to avoid including fitsio.h here.
600 int status; // the cfitsio status indicator that gets passed to every cfitsio call.
601 int behavior; // bitwise OR of BehaviorFlags
602};
603
605
623 daf::base::PropertyList const & first,
624 daf::base::PropertyList const & second);
626
638 bool strip = false);
639
653 HduType type = HduType::ANY, int hduver = 0,
654 bool strip = false);
655
667 bool strip = false);
668
682 std::string const& hduname, HduType type = HduType::ANY,
683 int hduver = 0, bool strip = false);
684
695
696
707public:
708
709 HduMoveGuard() = delete;
710
711 HduMoveGuard(HduMoveGuard const &) = delete;
713
716
728 HduMoveGuard(Fits & fits, int hdu, bool relative=false);
729
731
733 void disable() { _enabled = false; }
734
735private:
736 Fits & _fits;
737 int _oldHdu;
738 bool _enabled;
739};
740
741
742} // namespace fits
743} // namespace afw
744} // namespace lsst
745
746#endif // !LSST_AFW_fits_h_INCLUDED
#define LSST_EXCEPTION_TYPE(t, b, c)
Macro used to define new types of exceptions without additional data.
Definition Exception.h:69
Basic LSST definitions.
An exception thrown when problems are found when reading or writing FITS files.
Definition fits.h:37
A simple struct that combines the two arguments that must be passed to most cfitsio routines and cont...
Definition fits.h:242
void writeKey(std::string const &key, char const *value)
Definition fits.h:313
void updateKey(std::string const &key, char const *value)
Definition fits.h:295
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:499
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:651
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:683
void closeFile()
Close a FITS file.
Definition fits.cc:1778
void writeImage(ndarray::Array< T const, N, C > const &array)
Write an ndarray::Array to a FITS image HDU.
Definition fits.h:434
void writeKey(std::string const &key, char const *value, std::string const &comment)
Definition fits.h:308
int getImageDim()
Return the number of dimensions in the current HDU.
Definition fits.cc:1639
void writeColumnKey(std::string const &prefix, int n, char const *value)
Definition fits.h:339
void createImage(int bitpix, 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:406
std::size_t countRows()
Return the number of row in a table.
Definition fits.cc:1150
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
Definition fits.cc:1534
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:419
void readTableArray(std::size_t row, int col, int nElements, T *value)
Read an array value from a binary table.
Definition fits.cc:1183
Fits & operator=(const Fits &)=delete
void writeColumnKey(std::string const &prefix, int n, char const *value, std::string const &comment)
Definition fits.h:334
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:675
void setHdu(int hdu, bool relative=false)
Set the current HDU.
Definition fits.cc:489
void createTable()
Create a new binary table extension.
Definition fits.cc:1108
Fits()
Default constructor; set all data members to 0.
Definition fits.h:567
void readTableScalar(std::size_t row, int col, T &value)
Read an array scalar from a binary table.
Definition fits.h:553
void updateKey(std::string const &key, char const *value, std::string const &comment)
Definition fits.h:290
bool checkCompressedImagePhu()
Go to the first image header in the FITS file.
Definition fits.cc:1902
int countHdus()
Return the number of HDUs in the file.
Definition fits.cc:518
void writeTableScalar(std::size_t row, int col, T value)
Write a scalar value to a binary table.
Definition fits.h:541
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:400
void forEachKey(HeaderIterationFunctor &functor)
Call a polymorphic functor for every key in the header.
Definition fits.cc:765
std::string getFileName() const
Return the file name associated with the FITS object or "<unknown>" if there is none.
Definition fits.cc:474
int addColumn(std::string const &ttype, int size, std::string const &comment)
Add a column to a table.
Definition fits.cc:1131
void updateColumnKey(std::string const &prefix, int n, char const *value)
Definition fits.h:325
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:643
void readMetadata(daf::base::PropertySet &metadata, bool strip=false)
Read a FITS header into a PropertySet or PropertyList.
Definition fits.cc:1078
void writeTableArray(std::size_t row, int col, int nElements, T const *value)
Write an array value to a binary table.
Definition fits.cc:1160
void readKey(std::string const &key, T &value)
Read a FITS header key into the given reference.
Definition fits.cc:758
std::string getImageDType()
Return the numpy dtype equivalent of the image pixel type (e.g.
Definition fits.cc:1684
ndarray::Vector< ndarray::Size, N > getImageShape()
Return the shape of the current (image) HDU.
Definition fits.h:470
int getHdu()
Return the current HDU (0-indexed; 0 is the Primary HDU).
Definition fits.cc:483
void updateColumnKey(std::string const &prefix, int n, char const *value, std::string const &comment)
Definition fits.h:320
Fits & operator=(Fits &&)=delete
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
Definition fits.cc:1086
Fits(Fits &&)=delete
long getTableArraySize(int col)
Return the size of an array column.
Definition fits.cc:1208
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:1140
bool checkImageType()
Return true if the current HDU is compatible with the given pixel type.
Definition fits.cc:1652
An exception thrown when a FITS file has the wrong type.
Definition fits.h:42
HduMoveGuard(HduMoveGuard &&)=delete
HduMoveGuard(HduMoveGuard const &)=delete
void disable()
Disable the guard, leaving the HDU at its current state at destruction.
Definition fits.h:733
HduMoveGuard & operator=(HduMoveGuard const &)=delete
HduMoveGuard & operator=(HduMoveGuard &&)=delete
Base class for polymorphic functors used to iterator over FITS key headers.
Definition fits.h:50
virtual void operator()(std::string const &key, std::string const &value, std::string const &comment)=0
Lifetime-management for memory that goes into FITS memory files.
Definition fits.h:126
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:151
MemFileManager()
Construct a MemFileManager with no initial memory buffer.
Definition fits.h:134
void reset(void *ptr, std::size_t len)
Set the internal memory buffer to an manually-managed external block.
Definition fits.h:178
MemFileManager(std::size_t len)
Construct a MemFileManager with (len) bytes of initial memory.
Definition fits.h:142
void * getData() const
Return the buffer.
Definition fits.h:196
MemFileManager & operator=(const MemFileManager &)=delete
void reset()
Return the manager to the same state it would be if default-constructed.
Definition fits.cc:451
MemFileManager(const MemFileManager &)=delete
std::size_t getLength() const
Return the buffer length.
Definition fits.h:199
The base class for all image classed (Image, Mask, MaskedImage, ...)
Definition ImageBase.h:102
Represent a 2-dimensional array of bitmask pixels.
Definition Mask.h:82
Class for storing ordered metadata with comments.
Class for storing generic metadata.
Definition PropertySet.h:67
Reports errors in external input/output operations.
Definition Runtime.h:160
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:1783
const int DEFAULT_HDU
Specify that the default HDU should be read.
std::shared_ptr< daf::base::PropertyList > readMetadata(std::string const &fileName, int hdu=DEFAULT_HDU, bool strip=false)
Read FITS header.
Definition fits.cc:1824
int getBitPix()
Return the cfitsio integer BITPIX code for the given data type.
Definition fits.cc:466
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:396
HduType
an enum representing the various types of FITS HDU that are available in cfitsio library
Definition fits.h:224
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:433
ndarray::Array< T const, N, N > const makeContiguousArray(ndarray::Array< T, N, C > const &array)
Construct a contiguous ndarray.
Definition fits.h:213
Options controlling image compression with FITS.