ifw-daq  3.0.0-pre2
IFW Data Acquisition modules
cfitsio.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * @ingroup daq_ocm_libfits
4  * @copyright 2022 ESO - European Southern Observatory
5  *
6  * @brief Contains functions and data structures related to cfitsio.
7  */
8 #ifndef DAQ_OCM_DAQ_FITS_CFITSIO_HPP_
9 #define DAQ_OCM_DAQ_FITS_CFITSIO_HPP_
10 #include <memory>
11 #include <optional>
12 #include <stdexcept>
13 
14 #include <cfitsio/fitsio.h>
15 
16 #include <daq/fits/keyword.hpp>
17 
18 namespace daq::fits {
19 enum class HduType : int {
20  Image = IMAGE_HDU,
21  Ascii = ASCII_TBL,
22  Binary = BINARY_TBL,
23 };
24 
25 
26 enum class OpenMode : uint8_t { ReadOnly, ReadWrite };
27 
28 /**
29  * Defines unique ownership type to cfitsio fitsfile.
30  *
31  * @ingroup daq_ocm_libfits
32  */
33 using UniqueFitsFile = std::unique_ptr<fitsfile, void (*)(fitsfile*) noexcept>;
34 
35 /**
36  * In-memory FITS file.
37  */
39 public:
40  /**
41  * Creates empty file.
42  */
43  MemoryFitsFile() noexcept;
44  /**
45  * Creates empty file.
46  */
47  explicit MemoryFitsFile(size_t initial_buffer_size);
48  explicit MemoryFitsFile(MemoryFitsFile&& other) noexcept = default;
49  MemoryFitsFile& operator=(MemoryFitsFile&& other) noexcept = default;
50 
51  /**
52  * Get fits pointer
53  *
54  * @return In-memory FITS file pointer.
55  */
56  fitsfile* GetFile() const noexcept {
57  return m_file.get();
58  }
59 
60  /**
61  * Move out ptr.
62  *
63  * @warning Object lifetime of this object must exeed the UniqueFits file as it
64  * references memory owned associated by this object.
65  *
66  * @return Owned FITS file.
67  */
69  return std::move(m_file);
70  }
71 
72 private:
73  /** In-memory buffer used by FITS */
74  struct FitsMemory {
75  FitsMemory(size_t initial_size);
76  ~FitsMemory() noexcept;
77  void* buffer;
78  size_t size;
79  };
80 
81  std::unique_ptr<FitsMemory> m_memory;
82  UniqueFitsFile m_file;
83 };
84 
85 /**
86  * Represents errors from cfitsio.
87  *
88  * @ingroup daq_ocm_libfits
89  */
90 class CfitsioError : public std::runtime_error {
91 public:
92  CfitsioError(int status, char const* message);
93  CfitsioError(int status, std::string const& message);
94 
95  /**
96  * @return cfitsio status code causing the exception.
97  */
98  int GetStatus() const noexcept;
99 
100 private:
101  int m_status;
102 };
103 
104 /**
105  * Select current HDU number.
106  * @param hdu_num HDU number starting with primary HDU == 1.
107  */
108 void SelectHduNum(fitsfile* ptr, int hdu_num);
109 
110 /**
111  * Default close function that is used by UniqueFitsFile as a deleter.
112  *
113  * @ingroup daq_ocm_libfits
114  */
115 void DefaultClose(fitsfile* ptr) noexcept;
116 
117 /**
118  * Creates empty FITS file using @c fits_create_file and returns a pointer with a deleter that will
119  * close the file.
120  *
121  * @ingroup daq_ocm_libfits
122  */
123 UniqueFitsFile CreateEmpty(char const* filename);
124 
125 /**
126  * Open file
127  *
128  * @param filename Path to file to open.
129  * @param mode File open mode.
130  * @throw CfitsioError on errors.
131  */
132 UniqueFitsFile Open(char const* filename, OpenMode mode);
133 
134 /**
135  * Initializes an empty FITS file with an empty primary HDU (no keywords)
136  *
137  * @pre ptr != nullptr
138  *
139  * @param ptr Valid FITS file.
140  * @throw CfitsioError on error.
141  */
142 void InitPrimaryHduEmpty(fitsfile* ptr);
143 
144 /**
145  * Initializes an empty FITS file with a primary HDU
146  *
147  * Mandatory keywords are set and primary HDU added if necessary.
148  *
149  * Mandatory keywords are initialized as:
150  * - SIMPLE = T
151  * - BITPIX = 8
152  * - NAXIS = 0
153  *
154  * @pre ptr != nullptr
155  *
156  * @param ptr Valid FITS file.
157  * @throw CfitsioError on error.
158  */
159 void InitPrimaryHduNoImage(fitsfile* ptr);
160 
161 /**
162  * Read keywords from HDU identifed by absolute position @a hdu_num.
163  *
164  * @param ptr FITS file to read from.
165  * @param hdu_num HDU number. HDU numbers are 1-indexed, so primary HDU is 1.
166  * @throw CfitsioError on error.
167  */
168 std::vector<LiteralKeyword> ReadKeywords(fitsfile* ptr, int hdu_num);
169 
170 /**
171  * Delete all keywords from HDU
172  *
173  * @param ptr FITS file to delete keywords from.
174  * @param hdu_num HDU number. HDU numbers are 1-indexed, so primary HDU is 1.
175  * @throw CfitsioError on error.
176  */
177 void DeleteAllKeywords(fitsfile* ptr, int hdu_num);
178 
179 /**
180  * Read keywords from HDU identifed by @a EXTNAME and @c EXTVER keywords.
181  *
182  * @param ptr FITS file to read from.
183  * @param name HDU extension name as identified by @c EXTNAME keyword.
184  * @param version HDU extension version as identified by @c EXTVER keyword. If version is not
185  * provided the @c EXTVER will be ignored when looking up extension.
186  * @throw CfitsioError on error.
187  */
188 std::vector<LiteralKeyword>
189 ReadKeywords(fitsfile* ptr, std::string_view name, std::optional<int> version = std::nullopt);
190 
191 /**
192  * Write keywords to HDU identified by number @a hdu_num.
193  *
194  * @param ptr FITS file to write to.
195  * @param hdu_num HDU number. HDU numbers are 1-indexed, so primary HDU is 1.
196  * @param keywords Keywords to write.
197  * @param [out] remaining_size optional parameter that is updated with remaining size in HDU before
198  * any allocations. If this number is negative it means the HDU required to be allocated with an
199  * associated performance penalty.
200  *
201  * @throw CfitsioError on error.
202  */
203 void WriteKeywords(fitsfile* ptr,
204  int hdu_num,
205  std::vector<LiteralKeyword> const& keywords,
206  std::optional<ssize_t>* remaining_size = nullptr);
207 
208 /**
209  * Write or update checksum keywords DATASUM and CHECKSUM to HDU specified by @a hdu_num.
210  *
211  * @param hdu_num HDU to calculate and update checksum keywords for if necessary.
212  * @throw CfitsioError on error.
213  */
214 void WriteChecksum(fitsfile* ptr, int hdu_num);
215 
216 } // namespace daq::fits
217 
218 #endif // #define DAQ_OCM_DAQ_FITS_CFITSIO_HPP_
Represents errors from cfitsio.
Definition: cfitsio.hpp:90
In-memory FITS file.
Definition: cfitsio.hpp:38
MemoryFitsFile(MemoryFitsFile &&other) noexcept=default
UniqueFitsFile GetOwnedFile() &&
Move out ptr.
Definition: cfitsio.hpp:68
MemoryFitsFile & operator=(MemoryFitsFile &&other) noexcept=default
MemoryFitsFile() noexcept
Creates empty file.
Definition: cfitsio.cpp:55
fitsfile * GetFile() const noexcept
Get fits pointer.
Definition: cfitsio.hpp:56
Contains data structure for FITS keywords.
string version
Definition: conf.py:90
void SelectHduNum(fitsfile *ptr, int hdu_num)
Select current HDU number.
Definition: cfitsio.cpp:89
UniqueFitsFile Open(char const *filename, OpenMode mode)
Open file.
Definition: cfitsio.cpp:168
std::unique_ptr< fitsfile, void(*)(fitsfile *) noexcept > UniqueFitsFile
Defines unique ownership type to cfitsio fitsfile.
Definition: cfitsio.hpp:33
void WriteKeywords(fitsfile *ptr, int hdu_num, std::vector< LiteralKeyword > const &keywords, std::optional< ssize_t > *remaining_size)
Write keywords to HDU identified by number hdu_num.
Definition: cfitsio.cpp:247
void WriteChecksum(fitsfile *ptr, int hdu_num)
Write or update checksum keywords DATASUM and CHECKSUM to HDU specified by hdu_num.
Definition: cfitsio.cpp:283
void DefaultClose(fitsfile *ptr) noexcept
Default close function that is used by UniqueFitsFile as a deleter.
Definition: cfitsio.cpp:100
void DeleteAllKeywords(fitsfile *ptr, int hdu_num)
Delete all keywords from HDU.
Definition: cfitsio.cpp:209
void InitPrimaryHduNoImage(fitsfile *ptr)
Initializes an empty FITS file with a primary HDU.
Definition: cfitsio.cpp:125
std::vector< LiteralKeyword > ReadKeywords(fitsfile *ptr, int hdu_num)
Read keywords from HDU identifed by absolute position hdu_num.
Definition: cfitsio.cpp:181
UniqueFitsFile CreateEmpty(char const *filename)
Creates empty FITS file using fits_create_file and returns a pointer with a deleter that will close t...
Definition: cfitsio.cpp:158
void InitPrimaryHduEmpty(fitsfile *ptr)
Initializes an empty FITS file with an empty primary HDU (no keywords)
Definition: cfitsio.cpp:112