mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fitsHeader.hpp
Go to the documentation of this file.
1 /** \file fitsHeader.hpp
2  * \brief Declares and defines a class to work with a FITS header
3  * \ingroup fits_processing_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015-2022 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef ioutils_fits__fitsHeader_hpp
28 #define ioutils_fits__fitsHeader_hpp
29 
30 
31 #include <list>
32 #include <unordered_map>
33 #include <iostream>
34 #include <vector>
35 
36 #include "fitsHeaderCard.hpp"
37 
38 namespace mx
39 {
40 namespace fits
41 {
42 
43 
44 /// Class to manage a complete fits header
45 /** Manages tasks such as insertion (avoiding duplicates), and keyword lookup.
46  * The \ref fitsHeaderCard "cards" are stored in a std::list to preserve order, but
47  * a std::unordered_multimap is used to provide fast keyword lookup.
48  *
49  * \ingroup fits_processing
50  */
52 {
53 
54 public:
55 
56  /// The iterator type for the cards list
57  typedef std::list<fitsHeaderCard>::iterator headerIterator ;
58 
59  /// The iterator type for the card map
60  typedef std::unordered_multimap<std::string, headerIterator>::iterator mapIterator;
61 
62 protected:
63 
64  /// The storage for the FITS header cards
65  /** We use a list, rather than forward_list, so that append (insert at end) is constant time.
66  *
67  */
68  std::list<fitsHeaderCard> cards;
69 
70  /// This multimap allows for fast lookup by keyword.
71  /** Use unordered_multimap to handle HISTORY and COMMENT properly, and be as efficient as possible.
72  */
73  std::unordered_multimap<std::string, headerIterator> cardMap;
74 
75 public:
76 
77  ///Default c'tor
78  fitsHeader();
79 
80  ///Copy constructor
81  /** Must be explicitly defined to handle creation of new iterators in the cardMap
82  */
83  fitsHeader(const fitsHeader & head /**< The fitsHeader to copy */);
84 
85  ///Destructor
86  ~fitsHeader();
87 
88  /// Assignment
89  /** Must be explicitly defined to handle creation of new iterators in the cardMap
90  */
91  fitsHeader & operator=(const fitsHeader & head /**< The fitsHeader to copy */);
92 
93  /// Get iterator to the beginning of the cards list
95 
96  /// Get iterator to the end of the cards list
98 
99  /// Get iterator pointing to a specific element
100  headerIterator iterator(const std::string & keyword /**< The keyword to look up*/);
101 
102  /// Test whether the header is empty.
103  bool empty();
104 
105  /// Get number of cards currently stored in the header.
106  size_t size();
107 
108  /// Clear all cards from the header
109  void clear();
110 
111  /// Get number of cards with a given keyword
112  /** Reeturns the result of the count() method of the header map.
113  *
114  * \retval the number of cards with keyword.
115  */
116  size_t count( const std::string & keyword /**< [in] the keyword to loop up*/);
117 
118  /// Erase card by keyword
119  /** This can not be used to erase COMMENT or HISTORY cards.
120  *
121  * \param keyword the keyword of the card to delete
122  *
123  */
124  void erase(const std::string & keyword);
125 
126  /// Erase card by iterator
127  /** This handles COMMENT and HISTORY cards, deleting only the one pointed to by it
128  *
129  * \param it is a headerIterator pointing to the card to delete.
130  *
131  */
132  void erase(headerIterator it);
133 
134  /// Erase the standard entries at the top of the header
135  /** Erases each entry down to BSCALE. This is useful for appending
136  * a header to a newly created file.
137  */
138  void eraseStandardTop();
139 
140  /// Append a fitsHeaderCard to the end of the header
141  /**
142  * \param card is a fitsHeaderCard already populated
143  */
144  void append(fitsHeaderCard card);
145 
146  /// Append a card to the end of the header, from the three components of a card.
147  /**
148  * \tparam typeT is the data type of the value
149  *
150  * \param k is the keyword string
151  * \param v is the value of typeT
152  * \param c is the comment string
153  */
154  template<typename typeT>
155  void append(const std::string &k, const typeT &v, const std::string &c);
156 
157  /// Append a card to the end of the header, from the components of a card with no comment.
158  /**
159  * \tparam typeT is the data type of the value
160  *
161  * \param k is the keyword string
162  * \param v is the value of typeT
163  */
164  template<typename typeT>
165  void append(const std::string &k, const typeT &v);
166 
167  /// Append a card to the end of the header, with just a keyword.
168  /** Appens a headerCard with unknownType
169  *
170  * \param k is the keyword string
171  */
172  void append(const std::string &k);
173 
174  /// Append a fitsHeader to the end of the header
175  /**
176  * \param head is a populated fitsHeader
177  */
178  void append(fitsHeader & head);
179 
180  /// Insert a card before another card.
181  /**
182  * \param it points to the element before which to insert
183  * \param card contains the card to insert
184  */
186 
187  /// Insert a card before another card, specifying the card by its components.
188  /**
189  * \tparam typeT is the type of the value, which is converted to string for insertion
190  *
191  * \param it points to the element before which to insert
192  * \param k is the keyword
193  * \param v is the value
194  * \param c is the comment
195  *
196  */
197  template<typename typeT>
198  void insert_before(headerIterator it, const std::string &k, typeT v, const std::string &c);
199 
200  /// Insert a card before another card, specifying the card by its components.
201  /**
202  * \tparam typeT is the type of the value, which is converted to string for insertion
203  *
204  * \param it points to the element before which to insert
205  * \param k is the keyword
206  * \param v is the value
207  *
208  */
209  template<typename typeT>
210  void insert_before(headerIterator it, const std::string &k, typeT v);
211 
212  /// Insert a card after another card.
213  /**
214  * \param it points to the element after which to insert
215  * \param card contains the card to insert
216  */
218 
219  /// Insert a card after another card, specifying the card by its components.
220  /**
221  * \tparam typeT is the type of the value, which is converted to string for insertion
222  *
223  * \param it points to the element after which to insert
224  * \param k is the keyword
225  * \param v is the value
226  * \param c is the comment
227  *
228 
229  */
230  template<typename typeT>
231  void insert_after(headerIterator it, const std::string &k, typeT v, const std::string &c);
232 
233  /// Insert a card after another card, specifying the card by its components.
234  /**
235  * \tparam typeT is the type of the value, which is converted to string for insertion
236  *
237  * \param it points to the element after which to insert
238  * \param k is the keyword
239  * \param v is the value
240  *
241  */
242  template<typename typeT>
243  void insert_after(headerIterator it, const std::string &k, typeT v);
244 
245  /// Card access by keyword operator
246  /** Looks up the card by its keyword, and returns a reference to it.
247  *
248  * \param keyword is the header keyword to look up
249  *
250  * \retval fitsHeaderCard& reference to the \ref fitsHeaderCard
251  */
252  fitsHeaderCard & operator[](const std::string & keyword);
253 
254  /// Card access by keyword operator (const version)
255  /** Looks up the card by its keyword, and returns a reference to it.
256  *
257  * \param keyword is the header keyword to look up
258  *
259  * \retval fitsHeaderCard& const reference to the \ref fitsHeaderCard
260  */
261  const fitsHeaderCard & operator[](const std::string & keyword) const;
262 
263 
264 
265 }; // fitsHeader
266 
267 
268 
269 template<typename typeT>
270 void fitsHeader::append( const std::string &k,
271  const typeT &v,
272  const std::string &c
273  )
274 {
275  append(fitsHeaderCard(k,v,c));
276 }
277 
278 
279 template<typename typeT>
280 void fitsHeader::append( const std::string &k,
281  const typeT &v
282  )
283 {
284  append(fitsHeaderCard(k,v));
285 }
286 
287 template<typename typeT>
289  const std::string &k,
290  typeT v,
291  const std::string &c
292  )
293 {
295 }
296 
297 
298 template<typename typeT>
300  const std::string &k,
301  typeT v
302  )
303 {
305 }
306 
307 template<typename typeT>
309  const std::string &k,
310  typeT v,
311  const std::string &c
312  )
313 {
314  insert_after(it, fitsHeaderCard(k,v,c));
315 }
316 
317 
318 template<typename typeT>
320  const std::string &k,
321  typeT v
322  )
323 {
324  insert_after(it, fitsHeaderCard(k,v));
325 }
326 
327 
328 /** \addtogroup fits_utils
329  * @{
330  */
331 
332 ///Convert the values in a std::vector of \ref fitsHeader "fits headers" into a std::vector of values.
333 /** Resizes the vector of the appropriate type.
334  *
335  * \tparam dataT is the type of the header value
336  *
337  * \param[out] v will contain the converted values
338  * \param[in] heads contains the headers
339  * \param[in] keyw contains the keyword designating which value to convert
340  *
341  */
342 template<typename dataT>
343 void headersToValues( std::vector<dataT> & v,
344  std::vector<fitsHeader> & heads,
345  const std::string &keyw
346  )
347 {
348  v.resize(heads.size());
349 
350  for(size_t i=0;i<heads.size(); ++i)
351  {
352  v[i] = heads[i][keyw].value<dataT>();//convertFromString<dataT>(heads[i][keyw].value);
353  }
354 
355 }
356 
357 ///Convert the values in a std::vector of \ref fitsHeader "fits headers" into a std::vector of values.
358 /** Creates a vector of the appropriate type and size.
359  *
360  * \tparam dataT is the type of the header value
361  *
362  * \param[in] heads contains the headers
363  * \param[in] keyw contains the keyword designating which value to convert
364  *
365  * \retval std::vector<dataT> containing the converted values
366  */
367 template<typename dataT>
368 std::vector<dataT> headersToValues( std::vector<fitsHeader> & heads,
369  const std::string &keyw
370  )
371 {
372  std::vector<dataT> v(heads.size());
373 
374  headersToValues(v,heads, keyw);
375 
376  return v;
377 }
378 
379 
380 ///Write the status of a Git repository to HISTORY in a FITS header.
381 /**
382  * \param [in,out] head the HISTORY cards will be appended to this header
383  * \param [in] repoName the name of the repository
384  * \param [in] sha1 is the SHA-1 hash string of the repository
385  * \param [in] modified whether or not the repository has been modified after the
386  * commit referred to by sha1
387  */
388 void fitsHeaderGitStatus( fitsHeader & head,
389  const std::string & repoName,
390  const char * sha1,
391  int modified
392  );
393 
394 ///@}
395 
396 
397 } //namespace fits
398 } //namespace mx
399 
400 
401 
402 #endif //ioutils_fits__fitsHeader_hpp
Class to manage the three components of a FITS header card.
Class to manage a complete fits header.
Definition: fitsHeader.hpp:52
size_t count(const std::string &keyword)
Get number of cards with a given keyword.
Definition: fitsHeader.cpp:97
~fitsHeader()
Destructor.
Definition: fitsHeader.cpp:44
std::list< fitsHeaderCard >::iterator headerIterator
The iterator type for the cards list.
Definition: fitsHeader.hpp:57
fitsHeader()
Default c'tor.
Definition: fitsHeader.cpp:34
fitsHeaderCard & operator[](const std::string &keyword)
Card access by keyword operator.
Definition: fitsHeader.cpp:238
headerIterator begin()
Get iterator to the beginning of the cards list.
Definition: fitsHeader.cpp:66
void clear()
Clear all cards from the header.
Definition: fitsHeader.cpp:91
std::unordered_multimap< std::string, headerIterator >::iterator mapIterator
The iterator type for the card map.
Definition: fitsHeader.hpp:60
std::list< fitsHeaderCard > cards
The storage for the FITS header cards.
Definition: fitsHeader.hpp:68
void eraseStandardTop()
Erase the standard entries at the top of the header.
Definition: fitsHeader.cpp:126
headerIterator iterator(const std::string &keyword)
Get iterator pointing to a specific element.
Definition: fitsHeader.cpp:76
void erase(const std::string &keyword)
Erase card by keyword.
Definition: fitsHeader.cpp:102
void insert_before(headerIterator it, fitsHeaderCard card)
Insert a card before another card.
Definition: fitsHeader.cpp:193
size_t size()
Get number of cards currently stored in the header.
Definition: fitsHeader.cpp:86
std::unordered_multimap< std::string, headerIterator > cardMap
This multimap allows for fast lookup by keyword.
Definition: fitsHeader.hpp:73
fitsHeader & operator=(const fitsHeader &head)
Assignment.
Definition: fitsHeader.cpp:49
bool empty()
Test whether the header is empty.
Definition: fitsHeader.cpp:81
void append(fitsHeaderCard card)
Append a fitsHeaderCard to the end of the header.
Definition: fitsHeader.cpp:156
void insert_after(headerIterator it, fitsHeaderCard card)
Insert a card after another card.
Definition: fitsHeader.cpp:215
headerIterator end()
Get iterator to the end of the cards list.
Definition: fitsHeader.cpp:71
A class to work with a FITS header card.
constexpr units::realT c()
The speed of light.
Definition: constants.hpp:60
constexpr units::realT k()
Boltzmann Constant.
Definition: constants.hpp:71
void fitsHeaderGitStatus(fitsHeader &head, const std::string &repoName, const char *sha1, int modified)
Write the status of a Git repository to HISTORY in a FITS header.
Definition: fitsHeader.cpp:267
std::vector< dataT > headersToValues(std::vector< fitsHeader > &heads, const std::string &keyw)
Convert the values in a std::vector of fits headers into a std::vector of values.
Definition: fitsHeader.hpp:368
The mxlib c++ namespace.
Definition: mxError.hpp:107