LSST Applications g04c3c9f7ca+2075667efa,g1e125bf412+5f448d5fcf,g2079a07aa2+3e9fd84d81,g2305ad1205+b635cf1488,g2bbee38e9b+6c6beb4891,g337abbeb29+6c6beb4891,g33d1c0ed96+6c6beb4891,g3a166c0a6a+6c6beb4891,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+42f171e1e6,g5c3423f6d4+d536b04327,g607f77f49a+d536b04327,g6f43f06aed+ca1339dc19,g858d7b2824+d536b04327,g8ee334c5b4+d7f9608c2f,g9963eaa53e+b3dc1655d3,g998f4353bf+d536b04327,g99cad8db69+8ef2408349,g9ddcbc5298+9a081db1e4,ga1e77700b3+2cbb763275,gadfd92a7e4+aec2f3b930,gae0086650b+585e252eca,gb0e22166c9+0e73c8378f,gb3b7280ab2+cb5fdb229e,gbb8dafda3b+a327199e22,gc120e1dc64+88074880ea,gc28159a63d+6c6beb4891,gcdd4ae20e8+bd241b2308,gcde1bda545+903e937d91,gcf0d15dbbd+bd241b2308,gdaeeff99f8+f9a426f77a,gddc38dedce+585e252eca,ge79ae78c31+6c6beb4891,gfbcc870c63+b310236976,w.2024.23
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 <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) { \
113 auto except = LSST_FITS_EXCEPT(lsst::afw::fits::FitsError, fitsObj, __VA_ARGS__); \
114 (fitsObj).status = 0; \
115 throw except; \
116 }
117
119template <typename T>
120int getBitPix();
121
126public:
133 MemFileManager() : _ptr(nullptr), _len(0), _managed(true) {}
134
141 explicit MemFileManager(std::size_t len) : _ptr(nullptr), _len(0), _managed(true) { reset(len); }
142
150 MemFileManager(void* ptr, std::size_t len) : _ptr(ptr), _len(len), _managed(false) {}
151
157 void reset();
158
167 void reset(std::size_t len);
168
177 void reset(void* ptr, std::size_t len) {
178 reset();
179 _ptr = ptr;
180 _len = len;
181 _managed = false;
182 }
183
185
186 // No copying
189
190 // No moving
193
195 void* getData() const { return _ptr; }
196
198 std::size_t getLength() const { return _len; }
199
200private:
201 friend class Fits;
202
203 void* _ptr;
204 std::size_t _len;
205 bool _managed;
206};
207
211template <typename T, int N, int C>
212ndarray::Array<T const, N, N> const makeContiguousArray(ndarray::Array<T, N, C> const& array) {
213 ndarray::Array<T const, N, N> contiguous = ndarray::dynamic_dimension_cast<N>(array);
214 if (contiguous.empty()) contiguous = ndarray::copy(array);
215 return contiguous;
216}
217
226
228 template <typename T>
230
232 template <typename T>
234
236 explicit ImageWriteOptions(ImageCompressionOptions const& compression_ =
238 ImageScalingOptions const& scaling_ = ImageScalingOptions())
239 : compression(compression_), scaling(scaling_) {}
240
242 explicit ImageWriteOptions(ImageScalingOptions const& scaling_)
243 : compression(ImageCompressionOptions::NONE), scaling(scaling_) {}
244
270
283};
284
290enum class HduType : int { IMAGE = 0, ASCII_TABLE = 1, BIN_TABLE = 2, ANY = -1 };
291
308class Fits {
309 void createImageImpl(int bitpix, int nAxis, long const* nAxes);
310 template <typename T>
311 void writeImageImpl(T const* data, int nElements);
312 template <typename T>
313 void readImageImpl(int nAxis, T* data, long* begin, long* end, long* increment);
314 void getImageShapeImpl(int maxDim, long* nAxes);
315
316public:
318 AUTO_CLOSE = 0x01, // Close files when the Fits object goes out of scope if fptr != NULL
319 AUTO_CHECK = 0x02 // Call LSST_FITS_CHECK_STATUS after every cfitsio call
320 };
321
323 std::string getFileName() const;
324
326 int getHdu();
327
337 void setHdu(int hdu, bool relative = false);
338
347 void setHdu(std::string const& name, HduType hdutype = HduType::ANY, int hduver = 0);
348
350 int countHdus();
351
353
354 template <typename T>
355 void updateKey(std::string const& key, T const& value, std::string const& comment);
356 void updateKey(std::string const& key, char const* value, std::string const& comment) {
357 updateKey(key, std::string(value), comment);
358 }
359 template <typename T>
360 void updateKey(std::string const& key, T const& value);
361 void updateKey(std::string const& key, char const* value) { updateKey(key, std::string(value)); }
363
365
372 template <typename T>
373 void writeKey(std::string const& key, T const& value, std::string const& comment);
374 void writeKey(std::string const& key, char const* value, std::string const& comment) {
375 writeKey(key, std::string(value), comment);
376 }
377 template <typename T>
378 void writeKey(std::string const& key, T const& value);
379 void writeKey(std::string const& key, char const* value) { writeKey(key, std::string(value)); }
381
383
384 template <typename T>
385 void updateColumnKey(std::string const& prefix, int n, T const& value, std::string const& comment);
386 void updateColumnKey(std::string const& prefix, int n, char const* value, std::string const& comment) {
387 updateColumnKey(prefix, n, std::string(value), comment);
388 }
389 template <typename T>
390 void updateColumnKey(std::string const& prefix, int n, T const& value);
391 void updateColumnKey(std::string const& prefix, int n, char const* value) {
393 }
395
397
398 template <typename T>
399 void writeColumnKey(std::string const& prefix, int n, T const& value, std::string const& comment);
400 void writeColumnKey(std::string const& prefix, int n, char const* value, std::string const& comment) {
401 writeColumnKey(prefix, n, std::string(value), comment);
402 }
403 template <typename T>
404 void writeColumnKey(std::string const& prefix, int n, T const& value);
405 void writeColumnKey(std::string const& prefix, int n, char const* value) {
407 }
409
419 void writeMetadata(daf::base::PropertySet const& metadata);
420
430 void readMetadata(daf::base::PropertySet& metadata, bool strip = false);
431
433 template <typename T>
434 void readKey(std::string const& key, T& value);
435
444 void forEachKey(HeaderIterationFunctor& functor);
445
452 void createEmpty();
453
464 template <typename PixelT, int N>
465 void createImage(ndarray::Vector<ndarray::Size, N> const& shape) {
466 ndarray::Vector<long, N> nAxes(shape.reverse());
467 createImageImpl(detail::Bitpix<PixelT>::value, N, nAxes.elems);
468 }
469
470 template <int N>
471 void createImage(int bitpix, ndarray::Vector<ndarray::Size, N> const& shape) {
472 ndarray::Vector<long, N> nAxes(shape.reverse());
473 createImageImpl(bitpix, N, nAxes.elems);
474 }
475
482 template <typename PixelT>
483 void createImage(long x, long y) {
484 long naxes[2] = {x, y};
485 createImageImpl(detail::Bitpix<PixelT>::value, 2, naxes);
486 }
487
497 template <typename T, int N, int C>
498 void writeImage(ndarray::Array<T const, N, C> const& array) {
499 writeImageImpl(makeContiguousArray(array).getData(), array.getNumElements());
500 }
501
503
515 template <typename T>
516 void writeImage(
518 daf::base::PropertySet const * header = nullptr,
519 image::Mask<image::MaskPixel> const * mask = nullptr);
521
523 int getImageDim();
524
533 template <int N>
534 ndarray::Vector<ndarray::Size, N> getImageShape() {
535 ndarray::Vector<long, N> nAxes(1);
536 getImageShapeImpl(N, nAxes.elems);
537 ndarray::Vector<ndarray::Size, N> shape;
538 for (int i = 0; i < N; ++i) shape[i] = nAxes[N - i - 1];
539 return shape;
540 }
541
548 template <typename T>
549 bool checkImageType();
550
555
562 template <typename T, int N>
563 void readImage(ndarray::Array<T, N, N> const& array, ndarray::Vector<int, N> const& offset) {
564 ndarray::Vector<long, N> begin(offset.reverse());
565 ndarray::Vector<long, N> end(begin);
566 end += array.getShape().reverse();
567 ndarray::Vector<long, N> increment(1);
568 begin += increment; // first FITS pixel is 1, not 0
569 readImageImpl(N, array.getData(), begin.elems, end.elems, increment.elems);
570 }
571
573 void createTable();
574
581 template <typename T>
582 int addColumn(std::string const& ttype, int size, std::string const& comment);
583
590 template <typename T>
591 int addColumn(std::string const& ttype, int size);
592
595
598
600 template <typename T>
601 void writeTableArray(std::size_t row, int col, int nElements, T const* value);
602
604 template <typename T>
605 void writeTableScalar(std::size_t row, int col, T value) {
606 writeTableArray(row, col, 1, &value);
607 }
609 void writeTableScalar(std::size_t row, int col, std::string const& value);
610
612 template <typename T>
613 void readTableArray(std::size_t row, int col, int nElements, T* value);
614
616 template <typename T>
617 void readTableScalar(std::size_t row, int col, T& value) {
618 readTableArray(row, col, 1, &value);
619 }
620
622 void readTableScalar(std::size_t row, int col, std::string& value, bool isVariableLength);
623
625 long getTableArraySize(int col);
626
629
631 Fits() : fptr(nullptr), status(0), behavior(0) {}
632
634 Fits(std::string const& filename, std::string const& mode, int behavior);
635
637 Fits(MemFileManager& manager, std::string const& mode, int behavior);
638
640 void closeFile();
641
646
649
658
660 if ((fptr) && (behavior & AUTO_CLOSE)) closeFile();
661 }
662
663 // No copying
664 Fits(const Fits&) = delete;
665 Fits& operator=(const Fits&) = delete;
666
667 // No moving
668 Fits(Fits&&) = delete;
669 Fits& operator=(Fits&&) = delete;
670
671 void* fptr; // the actual cfitsio fitsfile pointer; void to avoid including fitsio.h here.
672 int status; // the cfitsio status indicator that gets passed to every cfitsio call.
673 int behavior; // bitwise OR of BehaviorFlags
674};
675
677
695 daf::base::PropertyList const & first,
696 daf::base::PropertyList const & second);
698
710 bool strip = false);
711
725 HduType type = HduType::ANY, int hduver = 0,
726 bool strip = false);
727
739 bool strip = false);
740
754 std::string const& hduname, HduType type = HduType::ANY,
755 int hduver = 0, bool strip = false);
756
767
768void setAllowImageCompression(bool allow);
770
771
772
783public:
784
785 HduMoveGuard() = delete;
786
787 HduMoveGuard(HduMoveGuard const &) = delete;
789
792
804 HduMoveGuard(Fits & fits, int hdu, bool relative=false);
805
807
809 void disable() { _enabled = false; }
810
811private:
812 Fits & _fits;
813 int _oldHdu;
814 bool _enabled;
815};
816
817
818} // namespace fits
819} // namespace afw
820} // namespace lsst
821
822#endif // !LSST_AFW_fits_h_INCLUDED
char * data
Definition BaseRecord.cc:61
int end
#define LSST_EXCEPTION_TYPE(t, b, c)
Macro used to define new types of exceptions without additional data.
Definition Exception.h:69
afw::table::Key< afw::table::Array< MaskPixelT > > mask
uint64_t * ptr
Definition RangeSet.cc:95
std::string prefix
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:308
void writeKey(std::string const &key, char const *value)
Definition fits.h:379
void updateKey(std::string const &key, char const *value)
Definition fits.h:361
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:563
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:686
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:718
void closeFile()
Close a FITS file.
Definition fits.cc:1643
void writeImage(ndarray::Array< T const, N, C > const &array)
Write an ndarray::Array to a FITS image HDU.
Definition fits.h:498
void writeKey(std::string const &key, char const *value, std::string const &comment)
Definition fits.h:374
int getImageDim()
Return the number of dimensions in the current HDU.
Definition fits.cc:1442
void writeColumnKey(std::string const &prefix, int n, char const *value)
Definition fits.h:405
void createImage(int bitpix, ndarray::Vector< ndarray::Size, N > const &shape)
Definition fits.h:471
std::size_t countRows()
Return the number of row in a table.
Definition fits.cc:1178
ImageCompressionOptions getImageCompression()
Return the current image compression settings.
Definition fits.cc:1515
void createEmpty()
Create an empty image HDU with NAXIS=0 at the end of the file.
Definition fits.cc:1259
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:483
void readTableArray(std::size_t row, int col, int nElements, T *value)
Read an array value from a binary table.
Definition fits.cc:1211
Fits & operator=(const Fits &)=delete
void writeColumnKey(std::string const &prefix, int n, char const *value, std::string const &comment)
Definition fits.h:400
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:710
void setHdu(int hdu, bool relative=false)
Set the current HDU.
Definition fits.cc:524
void createTable()
Create a new binary table extension.
Definition fits.cc:1136
Fits()
Default constructor; set all data members to 0.
Definition fits.h:631
void readTableScalar(std::size_t row, int col, T &value)
Read an array scalar from a binary table.
Definition fits.h:617
void updateKey(std::string const &key, char const *value, std::string const &comment)
Definition fits.h:356
bool checkCompressedImagePhu()
Go to the first image header in the FITS file.
Definition fits.cc:1767
int countHdus()
Return the number of HDUs in the file.
Definition fits.cc:553
void writeTableScalar(std::size_t row, int col, T value)
Write a scalar value to a binary table.
Definition fits.h:605
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:465
void forEachKey(HeaderIterationFunctor &functor)
Call a polymorphic functor for every key in the header.
Definition fits.cc:800
std::string getFileName() const
Return the file name associated with the FITS object or "<unknown>" if there is none.
Definition fits.cc:509
int addColumn(std::string const &ttype, int size, std::string const &comment)
Add a column to a table.
Definition fits.cc:1159
void updateColumnKey(std::string const &prefix, int n, char const *value)
Definition fits.h:391
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:678
void setImageCompression(ImageCompressionOptions const &options)
Set compression options for writing FITS images.
Definition fits.cc:1538
void readMetadata(daf::base::PropertySet &metadata, bool strip=false)
Read a FITS header into a PropertySet or PropertyList.
Definition fits.cc:1106
void writeTableArray(std::size_t row, int col, int nElements, T const *value)
Write an array value to a binary table.
Definition fits.cc:1188
void readKey(std::string const &key, T &value)
Read a FITS header key into the given reference.
Definition fits.cc:793
std::string getImageDType()
Return the numpy dtype equivalent of the image pixel type (e.g.
Definition fits.cc:1486
ndarray::Vector< ndarray::Size, N > getImageShape()
Return the shape of the current (image) HDU.
Definition fits.h:534
int getHdu()
Return the current HDU (0-indexed; 0 is the Primary HDU).
Definition fits.cc:518
void updateColumnKey(std::string const &prefix, int n, char const *value, std::string const &comment)
Definition fits.h:386
Fits & operator=(Fits &&)=delete
void writeMetadata(daf::base::PropertySet const &metadata)
Read a FITS header into a PropertySet or PropertyList.
Definition fits.cc:1114
Fits(Fits &&)=delete
long getTableArraySize(int col)
Return the size of an array column.
Definition fits.cc:1236
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:1168
bool checkImageType()
Return true if the current HDU is compatible with the given pixel type.
Definition fits.cc:1455
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:782
HduMoveGuard(HduMoveGuard &&)=delete
HduMoveGuard(HduMoveGuard const &)=delete
void disable()
Disable the guard, leaving the HDU at its current state at destruction.
Definition fits.h:809
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:125
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:150
MemFileManager()
Construct a MemFileManager with no initial memory buffer.
Definition fits.h:133
void reset(void *ptr, std::size_t len)
Set the internal memory buffer to an manually-managed external block.
Definition fits.h:177
MemFileManager(std::size_t len)
Construct a MemFileManager with (len) bytes of initial memory.
Definition fits.h:141
void * getData() const
Return the buffer.
Definition fits.h:195
MemFileManager & operator=(const MemFileManager &)=delete
void reset()
Return the manager to the same state it would be if default-constructed.
Definition fits.cc:486
MemFileManager(const MemFileManager &)=delete
std::size_t getLength() const
Return the buffer length.
Definition fits.h:198
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.
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:930
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:1648
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:1689
int getBitPix()
Return the cfitsio integer BITPIX code for the given data type.
Definition fits.cc:501
void setAllowImageCompression(bool allow)
Definition fits.cc:1566
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:431
bool getAllowImageCompression()
Definition fits.cc:1568
HduType
an enum representing the various types of FITS HDU that are available in cfitsio library
Definition fits.h:290
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:468
ndarray::Array< T const, N, N > const makeContiguousArray(ndarray::Array< T, N, C > const &array)
Construct a contiguous ndarray.
Definition fits.h:212
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:223
ImageCompressionOptions compression
Options controlling compression.
Definition fits.h:224
ImageScalingOptions scaling
Options controlling scaling.
Definition fits.h:225
ImageWriteOptions(ImageScalingOptions const &scaling_)
Construct with specific scaling options.
Definition fits.h:242
static std::shared_ptr< daf::base::PropertySet > validate(daf::base::PropertySet const &config)
Validate a PropertySet.
Definition fits.cc:1822
ImageWriteOptions(image::Image< T > const &image)
Construct with default options for images.
Definition fits.h:229
ImageWriteOptions(ImageCompressionOptions const &compression_=ImageCompressionOptions(ImageCompressionOptions::NONE), ImageScalingOptions const &scaling_=ImageScalingOptions())
Construct with specific compression and scaling options.
Definition fits.h:236
ImageWriteOptions(image::Mask< T > const &mask)
Construct with default options for masks.
Definition fits.h:233
FITS BITPIX header value by C++ type.