mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fitsHeader.cpp
Go to the documentation of this file.
1 /** \file fitsHeader.cpp
2  * \brief Implementation of 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 
28 
29 namespace mx
30 {
31 namespace fits
32 {
33 
35 {
36 }
37 
39 {
40  operator=(head);
41 
42 }
43 
45 {
46  clear();
47 }
48 
50 {
51  cards = head.cards;
52 
53  headerIterator it = cards.begin();
54 
55  cardMap.clear();
56  while(it != cards.end())
57  {
58  cardMap.insert(std::pair<std::string, headerIterator>(it->keyword(), it));
59  ++it;
60  }
61 
62  return *this;
63 }
64 
65 
67 {
68  return cards.begin();
69 }
70 
72 {
73  return cards.end();
74 }
75 
77 {
78  return cardMap.find(keyword)->second;
79 }
80 
82 {
83  return cards.empty();
84 }
85 
87 {
88  return cards.size();
89 }
90 
92 {
93  cards.clear();
94  cardMap.clear();
95 }
96 
97 size_t fitsHeader::count( const std::string & keyword)
98 {
99  return cardMap.count(keyword);
100 }
101 
102 void fitsHeader::erase(const std::string & keyword)
103 {
104  if(keyword == "COMMENT" || keyword == "HISTORY")
105  {
106  return;
107  }
108  headerIterator it;
109  it = (cardMap.find(keyword))->second; //trying to fool codacy
110  cardMap.erase(keyword);
111  cards.erase(it);
112 }
113 
115 {
116  mapIterator mit = cardMap.find(it->keyword());
117 
118  if(it->keyword() == "COMMENT" || it->keyword() == "HISTORY")
119  {
120  while(mit->second->keyword() == it->keyword() && it->comment() != mit->second->comment()) ++mit;
121  }
122  cardMap.erase(mit);
123  cards.erase(it);
124 }
125 
127 {
128 
129  headerIterator it = begin(), nit;
130 
131  int n =0;
132  while(it != end())
133  {
134  nit = it;
135  ++nit;
136  if(it->keyword() == "SIMPLE" || it->keyword() == "BITPIX" || it->keyword() == "NAXIS"
137  || it->keyword() == "NAXIS1" || it->keyword() == "NAXIS2" || it->keyword() == "NAXIS3" || it->keyword() == "EXTEND"
138  || it->keyword() == "BZERO" || it->keyword() == "BSCALE" || it->keyword() == "LONGSTRN")
139  {
140  erase(it);
141  }
142 
143  if(it->keyword() == "COMMENT")
144  {
145  if(it->comment().find("FITS (Flexible Image") != std::string::npos) erase(it);
146  else if(it->comment().find("and Astrophysics'") != std::string::npos) erase(it);
147  }
148 
149  if(nit == end()) break;
150  it = nit;
151  ++n;
152  }
153 
154 }
155 
157 {
158  //First check if duplicate key
159  if(cardMap.count(card.keyword()) > 0)
160  {
161  if(card.type() != fitsType<fitsCommentType>() && card.type() != fitsType<fitsHistoryType>())
162  {
163  std::cerr << "attempt to duplicate keyword: " << card.keyword() << "\n";
164  return;
165  }
166  }
167 
168  //Now insert in list
169  cards.push_back(card);
170 
171  //Then add to the Map.
172  headerIterator insertedIt = cards.end();
173  --insertedIt;
174  cardMap.insert( std::pair<std::string, headerIterator>(card.keyword(), insertedIt) );
175 
176 }
177 
179 {
180  headerIterator it;
181 
182  for(it = head.begin(); it != head.end(); ++it)
183  {
184  append(*it);
185  }
186 }
187 
188 void fitsHeader::append(const std::string &k)
189 {
191 }
192 
194  fitsHeaderCard card
195  )
196 {
197  //First check if duplicate key
198  if(cardMap.count(card.keyword()) > 0)
199  {
200  if(card.type() != fitsType<fitsCommentType>() && card.type() != fitsType<fitsHistoryType>())
201  {
202  std::cerr << "attempt to duplicate keyword: " << card.keyword() << "\n";
203  return;
204  }
205  }
206 
207  //Now insert in list
208  headerIterator insertedIt = cards.insert(it, card);
209 
210  //Then add to the Map.
211  cardMap.insert(std::pair<std::string, headerIterator>(card.keyword(), insertedIt));
212 
213 }
214 
216  fitsHeaderCard card
217  )
218 {
219  //First check if duplicate key
220  if(cardMap.count(card.keyword()) > 0)
221  {
222  if(card.type() != fitsType<fitsCommentType>() && card.type() != fitsType<fitsHistoryType>())
223  {
224  std::cerr << "attempt to duplicate keyword:" << card.keyword() << "\n";
225  return;
226  }
227  }
228 
229  //Now insert in list
230  headerIterator insertedIt = cards.insert(++it, card);
231 
232  //Then add to the Map.
233  cardMap.insert(std::pair<std::string, headerIterator>(card.keyword(), insertedIt));
234 
235 
236 }
237 
238 fitsHeaderCard & fitsHeader::operator[](const std::string & keyword)
239 {
240  headerIterator it;
241 
242  //If not found, append it.
243  if(cardMap.find(keyword) == cardMap.end())
244  {
245  append(keyword);
246  }
247 
248  it = cardMap.find(keyword)->second;
249 
250  return *it;
251 
252 }
253 
254 const fitsHeaderCard & fitsHeader::operator[](const std::string & keyword) const
255 {
256  if(cardMap.find(keyword) == cardMap.end())
257  {
258  std::cerr << "Fits header card with keyword: " << keyword << " not found.\n";
259  }
260 
261 
262  headerIterator it = cardMap.find(keyword)->second;
263 
264  return *it;
265 }
266 
268  const std::string & repoName,
269  const char * sha1,
270  int modified
271  )
272 {
273  std::string hist = "Git status for " + repoName + ":";
274  head.append("", fitsHistoryType(), hist);
275 
276  hist = " sha1=";
277  hist += sha1;
278  if(modified) hist += ", modified";
279 
280  head.append("", fitsHistoryType(), hist);
281 }
282 
283 } //namespace fits
284 } //namespace mx
Class to manage the three components of a FITS header card.
const std::string & keyword()
Get the keyword.
int type()
Get the type.
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
Declares and defines a class to work with a FITS header.
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
The mxlib c++ namespace.
Definition: mxError.hpp:107