mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fitsHeaderCard.cpp
Go to the documentation of this file.
1 /** \file fitsHeaderCard.cpp
2  * \brief Definitiions for a class to work with a FITS header card
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 
34 fitsHeaderCard::fitsHeaderCard( const std::string & k,
35  const std::string & v,
36  const std::string & c
37  )
38 {
39  m_keyword = k;
40  m_valueStr.str(v);
41  m_valueGood = false;
42  m_valueStrGood = true;
43  m_type = fitsType<std::string>();
44  m_comment = c;
45 }
46 
47 fitsHeaderCard::fitsHeaderCard( const std::string & k,
48  const std::string & v,
49  const int & type,
50  const std::string & c
51  )
52 {
53  m_keyword = k;
54  m_valueStr.str(v);
55  m_valueGood = false;
56  m_valueStrGood = true;
57  m_type = type;
58  m_comment = c;
59 }
60 
61 fitsHeaderCard::fitsHeaderCard( const std::string & k,
62  fitsCommentType v,
63  const std::string & c
64  )
65 {
66  m_keyword = k;
67  m_valueGood = false;
68  m_valueStrGood = false;
69  m_type = fitsType<fitsCommentType>();
70  m_comment = c;
71 }
72 
73 fitsHeaderCard::fitsHeaderCard( const std::string & k,
74  fitsHistoryType v,
75  const std::string & c
76  )
77 {
78  m_keyword = k;
79  m_valueGood = false;
80  m_valueStrGood = false;
81  m_type = fitsType<fitsHistoryType>();
82  m_comment = c;
83 }
84 
85 fitsHeaderCard::fitsHeaderCard(const std::string & k)
86 {
87  m_keyword = k;
88 }
89 
90 fitsHeaderCard::fitsHeaderCard( const std::string & k,
91  const int type
92  )
93 {
94  m_keyword = k;
95  m_type = type;
96 }
97 
98 
100 {
101  m_keyword = card.m_keyword;
102  m_type = card.m_type;
103  memcpy( &m_value, &card.m_value, sizeof(values));
104  m_valueStr.str(card.m_valueStr.str());
105  m_valueGood = card.m_valueGood;
107  m_comment = card.m_comment;
108 }
109 
111 {
112  m_keyword = card.m_keyword;
113  m_type = card.m_type;
114  memcpy( &m_value, &card.m_value, sizeof(values));
115  m_valueStr.str(card.m_valueStr.str());
116  m_valueGood = card.m_valueGood;
118  m_comment = card.m_comment;
119 
120  return *this;
121 }
122 
124 {
125  if(!m_valueGood)
126  {
127  mxThrowException(err::paramnotset, "fitsHeaderCard::convertToString()", "no value to convert for " + m_keyword);
128  return;
129  }
130 
131  if(m_type == fitsType<char *>()|| m_type == fitsType<std::string>())
132  {
133  m_valueStrGood = true; //It should be hard to get here, but just in case.
134  return;
135  }
136 
137  m_valueStr.str("");
138  m_valueStr.precision(10);
139 
140  switch(m_type)
141  {
142  case fitsType<char>():
143  m_valueStr << static_cast<int>(m_value.Char);
144  break;
145  case fitsType<unsigned char>():
146  m_valueStr << static_cast<int>(m_value.UChar);
147  break;
148  case fitsType<short>():
149  m_valueStr << m_value.Short;
150  break;
151  case fitsType<unsigned short>():
152  m_valueStr << m_value.UShort;
153  break;
154  case fitsType<int>():
155  m_valueStr << m_value.Int;
156  break;
157  case fitsType<unsigned int>():
158  m_valueStr << m_value.UInt;
159  break;
160  case fitsType<long>():
161  m_valueStr << m_value.Long;
162  break;
163  case fitsType<unsigned long>():
164  m_valueStr << m_value.ULong;
165  break;
166  case fitsType<long long>():
167  m_valueStr << m_value.LongLong;
168  break;
169  case fitsType<unsigned long long>():
170  m_valueStr << m_value.ULongLong;
171  break;
172  case fitsType<float>():
173  m_valueStr << m_value.Float;
174  break;
175  case fitsType<std::complex<float>>():
176  m_valueStr << m_value.complexFloat;
177  break;
178  case fitsType<double>():
179  m_valueStr << m_value.Double;
180  break;
181  case fitsType<std::complex<double>>():
182  m_valueStr << m_value.complexDouble;
183  break;
184  case fitsType<fitsCommentType>():
185  return;
186  case fitsType<fitsHistoryType>():
187  return;
188  default:
189  mxThrowException(err::invalidarg, "fitsHeaderCard::convertToString()", "Unknown FITS type");
190 
191  }
192 
193  m_valueStrGood = true;
194  return;
195 }
196 
197 template<>
198 void fitsHeaderCard::convertFromString<char>()
199 {
200  m_type = fitsType<char>();
201  m_value.Char = std::stoi(m_valueStr.str());
202  m_valueGood = true;
203 }
204 
205 template<>
206 void fitsHeaderCard::convertFromString<unsigned char>()
207 {
208  m_type = fitsType<unsigned char>();
209  m_value.UChar = std::stoi(m_valueStr.str());
210  m_valueGood = true;
211 }
212 
213 template<>
214 void fitsHeaderCard::convertFromString<short>()
215 {
216  m_type = fitsType<short>();
217  m_value.Short = std::stoi(m_valueStr.str());
218  m_valueGood = true;
219 }
220 
221 template<>
222 void fitsHeaderCard::convertFromString<unsigned short>()
223 {
224  m_type = fitsType<unsigned short>();
225  m_value.UShort = std::stoi(m_valueStr.str());
226  m_valueGood = true;
227 }
228 
229 template<>
230 void fitsHeaderCard::convertFromString<int>()
231 {
232  m_type = fitsType<int>();
233  m_value.Int = std::stoi(m_valueStr.str());
234  m_valueGood = true;
235 }
236 
237 template<>
238 void fitsHeaderCard::convertFromString<unsigned int>()
239 {
240  m_type = fitsType<unsigned int>();
241  m_value.UInt = std::stol(m_valueStr.str());
242  m_valueGood = true;
243 }
244 
245 
246 template<>
247 void fitsHeaderCard::convertFromString<long>()
248 {
249  m_type = fitsType<long>();
250  m_value.Long = std::stol(m_valueStr.str());
251  m_valueGood = true;
252 }
253 
254 template<>
255 void fitsHeaderCard::convertFromString<unsigned long>()
256 {
257  m_type = fitsType<unsigned long>();
258  m_value.ULong = std::stoul(m_valueStr.str());
259  m_valueGood = true;
260 }
261 
262 template<>
263 void fitsHeaderCard::convertFromString<long long>()
264 {
265  m_type = fitsType<long long>();
266  m_value.LongLong = std::stoll(m_valueStr.str());
267  m_valueGood = true;
268 }
269 
270 template<>
271 void fitsHeaderCard::convertFromString<unsigned long long>()
272 {
273  m_type = fitsType<unsigned long long>();
274  m_value.ULongLong = std::stoull(m_valueStr.str());
275  m_valueGood = true;
276 }
277 
278 template<>
279 void fitsHeaderCard::convertFromString<float>()
280 {
281  m_type = fitsType<float>();
282  m_value.Float = std::stof(m_valueStr.str());
283  m_valueGood = true;
284 }
285 
286 template<>
287 void fitsHeaderCard::convertFromString<std::complex<float>>()
288 {
289  mxThrowException(err::notimpl, "fitsHeaderCard::convertFromString<std::complex<float>>", "no conversion from string to std::complex<float>");
290  m_type = fitsType<std::complex<float>>();
291  m_value.complexFloat = std::stof(m_valueStr.str());
292  m_valueGood = true;
293 }
294 
295 template<>
296 void fitsHeaderCard::convertFromString<double>()
297 {
298  m_type = fitsType<double>();
299  m_value.Double = std::stof(m_valueStr.str());
300  m_valueGood = true;
301 }
302 
303 template<>
304 void fitsHeaderCard::convertFromString<std::complex<double>>()
305 {
306  mxThrowException(err::notimpl, "fitsHeaderCard::convertFromString<std::complex<double>>", "no conversion from string to std::complex<double>");
307  m_type = fitsType<std::complex<double>>();
308  m_value.complexDouble = std::stof(m_valueStr.str());
309  m_valueGood = true;
310 }
311 
312 template<typename typeT>
314 {
315  switch(m_type)
316  {
317  case fitsType<unsigned char>():
318  {
319  return m_value.UChar;
320  }
321  case fitsType<char>():
322  {
323  return m_value.Char;
324  }
325  case fitsType<short>():
326  {
327  return m_value.Short;
328  }
329  case fitsType<unsigned short>():
330  {
331  return m_value.UShort;
332  }
333  case fitsType<int>():
334  {
335  return m_value.Int;
336  }
337  case fitsType<unsigned int>():
338  {
339  return m_value.UInt;
340  }
341  case fitsType<long>():
342  {
343  return m_value.Long;
344  }
345  case fitsType<unsigned long>():
346  {
347  return m_value.ULong;
348  }
349  case fitsType<long long>():
350  {
351  return m_value.LongLong;
352  }
353  case fitsType<unsigned long long>():
354  {
355  return m_value.ULongLong;
356  }
357  case fitsType<float>():
358  {
359  return m_value.Float;
360  }
361  case fitsType<std::complex<float>>():
362  {
363  mxThrowException(err::notimpl, "fitsHeaderCard::convertedValue<typeT>", std::string("conversions no supported for complex types in ") + m_keyword);
364  }
365  case fitsType<double>():
366  {
367  return m_value.Double;
368  }
369  case fitsType<std::complex<double>>():
370  {
371  mxThrowException(err::notimpl, "fitsHeaderCard::convertedValue<typeT>", std::string("conversions no supported for complex types in ") + m_keyword);
372  }
373  case fitsType<fitsCommentType>():
374  {
375  mxThrowException(err::invalidarg, "fitsHeaderCard::convertedValue<typeT>", "cannot convert comment to numeric type");
376  }
377  case fitsType<fitsHistoryType>():
378  {
379  mxThrowException(err::invalidarg, "fitsHeaderCard::convertedValue<typeT>", "cannot convert history to numeric type");
380  }
381  case TSTRING:
382  {
383  mxThrowException(err::invalidarg, "fitsHeaderCard::convertedValue<typeT>", std::string("cannot convert string to numeric type in ") + m_keyword);
384  }
385  default:
386  {
387  mxThrowException(err::invalidarg, "fitsHeaderCard::convertedValue<typeT>", std::string("invalid FITS type for conversion in ") + m_keyword);
388  }
389  }
390 }
391 
393 {
394  if(!m_valueGood)
395  {
396  m_type = newtype;
397  return;
398  }
399 
400  switch(newtype)
401  {
402  case fitsType<unsigned char>():
403  {
404  m_value.UChar = convertedValue<unsigned char>();
405  break;
406  }
407  case fitsType<char>():
408  {
409  m_value.Char = convertedValue<char>();
410  break;
411  }
412  case fitsType<short>():
413  {
414  m_value.Short = convertedValue<short>();
415  break;
416  }
417  case fitsType<unsigned short>():
418  {
419  m_value.UShort = convertedValue<unsigned short>();
420  break;
421  }
422  case fitsType<int>():
423  {
424  m_value.Int = convertedValue<int>();
425  break;
426  }
427  case fitsType<unsigned int>():
428  {
429  m_value.UInt = convertedValue<unsigned int>();
430  break;
431  }
432  case fitsType<long>():
433  {
434  m_value.Long = convertedValue<long>();
435  break;
436  }
437  case fitsType<unsigned long>():
438  {
439  m_value.ULong = convertedValue<unsigned long>();
440  break;
441  }
442  case fitsType<long long>():
443  {
444  m_value.LongLong = convertedValue<long long>();
445  break;
446  }
447  case fitsType<unsigned long long>():
448  {
449  m_value.ULongLong = convertedValue<unsigned long long>();
450  break;
451  }
452  case fitsType<float>():
453  {
454  m_value.Float = convertedValue<float>();
455  break;
456  }
457  case fitsType<std::complex<float>>():
458  {
459  mxThrowException(err::notimpl, "fitsHeaderCard::convertValue", std::string("conversions not supported for complex types in ") + m_keyword);
460  }
461  case fitsType<double>():
462  {
463  m_value.Double = convertedValue<double>();
464  break;
465  }
466  case fitsType<std::complex<double>>():
467  {
468  mxThrowException(err::notimpl, "fitsHeaderCard::convertValue", std::string("conversions not supported for complex types in ") + m_keyword);
469  }
470  case fitsType<fitsCommentType>():
471  {
472  mxThrowException(err::invalidarg, "fitsHeaderCard::convertValue", "cannot convert comment to numeric type");
473  }
474  case fitsType<fitsHistoryType>():
475  {
476  mxThrowException(err::invalidarg, "fitsHeaderCard::convertValue", "cannot convert history to numeric type");
477  }
478  case TSTRING:
479  {
480  convertToString();
481  m_type = newtype;
482  m_valueGood = false;
483  return;
484  }
485  default:
486  {
487  mxThrowException(err::invalidarg, "fitsHeaderCard::convertValue", std::string("invalid FITS type for conversion in ") + m_keyword);
488  }
489  }
490 
491  m_type = newtype;
492  m_valueGood = true;
493 }
494 
495 const std::string & fitsHeaderCard::keyword()
496 {
497  return m_keyword;
498 }
499 
500 void fitsHeaderCard::keyword(const std::string & kw)
501 {
502  m_keyword = kw;
503 }
504 
505 template<>
506 std::string fitsHeaderCard::value<std::string>()
507 {
508  if(m_valueStrGood == false)
509  {
510  convertToString();
511  }
512 
513  //Strip ' from beginning and end if present
514  std::string str = m_valueStr.str();
515 
516  if(str[0] == '\'')
517  {
518  str.erase(0,1);
519  }
520 
521  if(str[str.size()-1] == '\'')
522  {
523  str.erase(str.size()-1,1);
524  }
525 
526  return str;
527 }
528 
529 template<>
530 char fitsHeaderCard::value<char>()
531 {
532  if(m_valueGood == false)
533  {
534  convertFromString<char>();
535  }
536 
537  if(m_type != fitsType<char>())
538  {
539  return convertedValue<char>();
540  }
541 
542  return m_value.Char;
543 }
544 
545 template<>
546 unsigned char fitsHeaderCard::value<unsigned char>()
547 {
548  if(m_valueGood == false)
549  {
550  convertFromString<unsigned char>();
551  }
552 
553  if(m_type != fitsType<unsigned char>())
554  {
555  return convertedValue<unsigned char>();
556  }
557 
558  return m_value.UChar;
559 }
560 
561 template<>
562 short fitsHeaderCard::value<short>()
563 {
564  if(m_valueGood == false)
565  {
566  convertFromString<short>();
567  }
568 
569  if(m_type != fitsType<short>())
570  {
571  return convertedValue<short>();
572  }
573 
574  return m_value.Short;
575 }
576 
577 template<>
578 unsigned short fitsHeaderCard::value<unsigned short>()
579 {
580  if(m_valueGood == false)
581  {
582  convertFromString<unsigned short>();
583  }
584 
585  if(m_type != fitsType<unsigned short>())
586  {
587  return convertedValue<unsigned short>();
588  }
589 
590  return m_value.UShort;
591 }
592 
593 template<>
594 int fitsHeaderCard::value<int>()
595 {
596  if(m_valueGood == false)
597  {
598  convertFromString<int>();
599  }
600 
601  if(m_type != fitsType<int>())
602  {
603  return convertedValue<int>();
604  }
605 
606  return m_value.Int;
607 }
608 
609 template<>
610 unsigned int fitsHeaderCard::value<unsigned int>()
611 {
612  if(m_valueGood == false)
613  {
614  convertFromString<unsigned int>();
615  }
616 
617  if(m_type != fitsType<unsigned int>())
618  {
619  return convertedValue<unsigned int>();
620  }
621 
622  return m_value.UInt;
623 }
624 
625 template<>
626 long fitsHeaderCard::value<long>()
627 {
628  if(m_valueGood == false)
629  {
630  convertFromString<long>();
631  }
632 
633  if(m_type != fitsType<long>())
634  {
635  return convertedValue<long>();
636  }
637 
638  return m_value.Long;
639 }
640 
641 template<>
642 unsigned long fitsHeaderCard::value<unsigned long>()
643 {
644  if(m_valueGood == false)
645  {
646  convertFromString<unsigned long>();
647  }
648 
649  if(m_type != fitsType<unsigned long>())
650  {
651  return convertedValue<unsigned long>();
652  }
653 
654  return m_value.ULong;
655 }
656 
657 template<>
658 long long fitsHeaderCard::value<long long>()
659 {
660  if(m_valueGood == false)
661  {
662  convertFromString<long long>();
663  }
664 
665  if(m_type != fitsType<long long>())
666  {
667  return convertedValue<long long>();
668  }
669 
670  return m_value.LongLong;
671 }
672 
673 template<>
674 unsigned long long fitsHeaderCard::value<unsigned long long>()
675 {
676  if(m_valueGood == false)
677  {
678  convertFromString<unsigned long long>();
679  }
680 
681  if(m_type != fitsType<unsigned long long>())
682  {
683  return convertedValue<unsigned long long>();
684  }
685 
686  return m_value.ULongLong;
687 }
688 
689 template<>
690 float fitsHeaderCard::value<float>()
691 {
692  if(m_valueGood == false)
693  {
694  convertFromString<float>();
695  }
696 
697  if(m_type != fitsType<float>())
698  {
699  return convertedValue<float>();
700  }
701 
702  return m_value.Float;
703 }
704 
705 template<>
706 std::complex<float> fitsHeaderCard::value<std::complex<float>>()
707 {
708  if(m_valueGood == false)
709  {
710  convertFromString<std::complex<float>>();
711  }
712 
713  if(m_type != fitsType<std::complex<float>>())
714  {
715  return convertedValue<std::complex<float>>();
716  }
717 
718  return m_value.complexFloat;
719 }
720 
721 template<>
722 double fitsHeaderCard::value<double>()
723 {
724  if(m_valueGood == false)
725  {
726  convertFromString<double>();
727  }
728 
729  if(m_type != fitsType<double>())
730  {
731  return convertedValue<double>();
732  }
733 
734  return m_value.Double;
735 }
736 
737 template<>
738 std::complex<double> fitsHeaderCard::value<std::complex<double>>()
739 {
740  if(m_valueGood == false)
741  {
742  convertFromString<std::complex<double>>();
743  }
744 
745  if(m_type != fitsType<std::complex<double>>())
746  {
747  return convertedValue<std::complex<double>>();
748  }
749 
750  return m_value.complexDouble;
751 }
752 
754 {
755  return value<std::string>();
756 }
757 
759 {
760  return value<char>();
761 }
762 
763 unsigned char fitsHeaderCard::UChar()
764 {
765  return value<unsigned char>();
766 }
767 
769 {
770  return value<short>();
771 }
772 
773 unsigned short fitsHeaderCard::UShort()
774 {
775  return value<unsigned short>();
776 }
777 
779 {
780  return value<int>();
781 }
782 
783 unsigned int fitsHeaderCard::UInt()
784 {
785  return value<unsigned int>();
786 }
787 
789 {
790  return value<long>();
791 }
792 
793 unsigned long fitsHeaderCard::ULong()
794 {
795  return value<unsigned long>();
796 }
797 
799 {
800  return value<long long>();
801 }
802 
803 unsigned long long fitsHeaderCard::ULongLong()
804 {
805  return value<unsigned long long>();
806 }
807 
809 {
810  return value<float>();
811 }
812 
813 std::complex<float> fitsHeaderCard::complexFloat()
814 {
815  return value<std::complex<float>>();
816 }
817 
819 {
820  return value<double>();
821 }
822 
823 std::complex<double> fitsHeaderCard::complexDouble()
824 {
825  return value<std::complex<double>>();
826 }
827 
828 void fitsHeaderCard::value(const char * v)
829 {
830  //Strip ' from beginning and end if present
831  std::string str = v;
832 
833  if(str[0] == '\'')
834  {
835  str.erase(0,1);
836  }
837 
838  if(str[str.size()-1] == '\'')
839  {
840  str.erase(str.size()-1,1);
841  }
842 
843  m_valueStr.str(str);
844 
845  m_valueGood = false;
846  m_valueStrGood = true;
847  m_type = fitsType<char *>();
848 }
849 
850 void fitsHeaderCard::value(const std::string & v)
851 {
852  //Strip ' from beginning and end if present
853  std::string str = v;
854 
855  if(str[0] == '\'')
856  {
857  str.erase(0,1);
858  }
859 
860  if(str[str.size()-1] == '\'')
861  {
862  str.erase(str.size()-1,1);
863  }
864 
865  m_valueStr.str(v);
866  m_valueGood = false;
867  m_valueStrGood = true;
868  m_type = fitsType<std::string>();
869 }
870 
871 void fitsHeaderCard::value(const char & v)
872 {
873  m_value.Char = v;
874  m_valueGood = true;
875  m_valueStrGood = false;
876  m_type = fitsType<char>();
877 }
878 
879 void fitsHeaderCard::value(const unsigned char & v)
880 {
881  m_value.UChar = v;
882  m_valueGood = true;
883  m_valueStrGood = false;
884  m_type = fitsType<unsigned char>();
885 }
886 
887 void fitsHeaderCard::value(const short int & v)
888 {
889  m_value.Short = v;
890  m_valueGood = true;
891  m_valueStrGood = false;
892  m_type = fitsType<short>();
893 }
894 
895 void fitsHeaderCard::value(const unsigned short & v)
896 {
897  m_value.UShort = v;
898  m_valueGood = true;
899  m_valueStrGood = false;
900  m_type = fitsType<unsigned short>();
901 }
902 
903 void fitsHeaderCard::value(const int & v)
904 {
905  m_value.Int = v;
906  m_valueGood = true;
907  m_valueStrGood = false;
908  m_type = fitsType<int>();
909 }
910 
911 void fitsHeaderCard::value(const unsigned int & v)
912 {
913  m_value.UInt = v;
914  m_valueGood = true;
915  m_valueStrGood = false;
916  m_type = fitsType<unsigned int>();
917 }
918 
919 void fitsHeaderCard::value(const long & v)
920 {
921  m_value.Long = v;
922  m_valueGood = true;
923  m_valueStrGood = false;
924  m_type = fitsType<long>();
925 }
926 
927 void fitsHeaderCard::value(const unsigned long int & v)
928 {
929  m_value.ULong = v;
930  m_valueGood = true;
931  m_valueStrGood = false;
932  m_type = fitsType<unsigned long>();
933 }
934 
935 void fitsHeaderCard::value(const long long & v)
936 {
937  m_value.LongLong = v;
938  m_valueGood = true;
939  m_valueStrGood = false;
940  m_type = fitsType<long long>();
941 }
942 
943 void fitsHeaderCard::value(const unsigned long long int & v)
944 {
945  m_value.ULongLong = v;
946  m_valueGood = true;
947  m_valueStrGood = false;
948  m_type = fitsType<unsigned long long>();
949 }
950 
951 void fitsHeaderCard::value(const float & v)
952 {
953  m_value.Float = v;
954  m_valueGood = true;
955  m_valueStrGood = false;
956  m_type = fitsType<float>();
957 }
958 
959 
960 void fitsHeaderCard::value(const std::complex<float> & v)
961 {
962  m_value.complexFloat = v;
963  m_valueGood = true;
964  m_valueStrGood = false;
965  m_type = fitsType<std::complex<float>>();
966 }
967 
968 void fitsHeaderCard::value(const double & v)
969 {
970  m_value.Double= v;
971  m_valueGood = true;
972  m_valueStrGood = false;
973  m_type = fitsType<double>();
974 }
975 
976 void fitsHeaderCard::value(const std::complex<double> & v)
977 {
978  m_value.complexDouble = v;
979  m_valueGood = true;
980  m_valueStrGood = false;
981  m_type = fitsType<std::complex<double>>();
982 }
983 
985 {
986  return m_type;
987 }
988 
989 void fitsHeaderCard::type( const int & t)
990 {
991  if(t == m_type) return;
992 
993  if(m_valueGood)
994  {
995  convertValue(t);
996  }
997  else m_type = t;
998 
999  //Need to reconvert, always favor the actual value.
1001  {
1002  m_valueStrGood = false;
1003  }
1004 }
1005 
1006 std::string fitsHeaderCard::valueStr()
1007 {
1008  if(!m_valueStrGood)
1009  {
1010  convertToString();
1011  }
1012 
1013  std::string s = m_valueStr.str();
1014  return s;
1015 }
1016 
1017 bool fitsHeaderCard::valueGood()
1018 {
1019  return m_valueGood;
1020 }
1021 
1022 bool fitsHeaderCard::valueStrGood()
1023 {
1024  return m_valueStrGood;
1025 }
1026 
1027 const std::string & fitsHeaderCard::comment()
1028 {
1029  return m_comment;
1030 }
1031 
1032 void fitsHeaderCard::comment( const std::string & c)
1033 {
1034  m_comment = c;
1035 }
1036 
1037 int fitsHeaderCard::write(fitsfile *fptr)
1038 {
1039  if(m_type == fitsType<char *>() || m_type == fitsType<std::string>())
1040  {
1041  return fits_write_key<char *>(fptr, (char *) m_keyword.c_str(), (void *)m_valueStr.str().c_str(), (char *) m_comment.c_str());
1042  }
1043 
1044  //If the string is good, meaning already converted.
1045  if(m_valueStrGood == true)
1046  {
1047  //This populates the card directly.
1048  return fits_write_key<fitsUnknownType>(fptr, (char *) m_keyword.c_str(), (void *)m_valueStr.str().c_str(), (char *) m_comment.c_str());
1049  }
1050 
1051  //Ok, now we write the type directly using fitsio routines because it hasn't been converted.
1052  switch(m_type)
1053  {
1054  case fitsType<unsigned char>():
1055  {
1056  return fits_write_key<unsigned char>(fptr, (char *) m_keyword.c_str(), &m_value.UChar, (char *) m_comment.c_str());
1057  }
1058  case fitsType<char>():
1059  {
1060  return fits_write_key<char>(fptr, (char *) m_keyword.c_str(), &m_value.Char, (char *) m_comment.c_str());
1061  }
1062  case fitsType<short>():
1063  {
1064  return fits_write_key<short>(fptr, (char *) m_keyword.c_str(), &m_value.Short, (char *) m_comment.c_str());
1065  }
1066  case fitsType<unsigned short>():
1067  {
1068  return fits_write_key<unsigned short>(fptr, (char *) m_keyword.c_str(), &m_value.UShort, (char *) m_comment.c_str());
1069  }
1070  case fitsType<int>():
1071  {
1072  return fits_write_key<int>(fptr, (char *) m_keyword.c_str(), &m_value.Int, (char *) m_comment.c_str());
1073  }
1074  case fitsType<unsigned int>():
1075  {
1076  return fits_write_key<unsigned int>(fptr, (char *) m_keyword.c_str(), &m_value.UInt, (char *) m_comment.c_str());
1077  }
1078  case fitsType<long>():
1079  {
1080  return fits_write_key<long>(fptr, (char *) m_keyword.c_str(), &m_value.Long, (char *) m_comment.c_str());
1081  }
1082  case fitsType<unsigned long>():
1083  {
1084  return fits_write_key<unsigned long>(fptr, (char *) m_keyword.c_str(), &m_value.ULong, (char *) m_comment.c_str());
1085  }
1086  case fitsType<long long>():
1087  {
1088  return fits_write_key<long long>(fptr, (char *) m_keyword.c_str(), &m_value.LongLong, (char *) m_comment.c_str());
1089  }
1090  case fitsType<unsigned long long>():
1091  {
1092  return fits_write_key<unsigned long long>(fptr, (char *) m_keyword.c_str(), &m_value.ULongLong, (char *) m_comment.c_str());
1093  }
1094  case fitsType<float>():
1095  {
1096  return fits_write_key<float>(fptr, (char *) m_keyword.c_str(), &m_value.Float, (char *) m_comment.c_str());
1097  }
1098  case fitsType<double>():
1099  {
1100  return fits_write_key<double>(fptr, (char *) m_keyword.c_str(), &m_value.Double, (char *) m_comment.c_str());
1101  }
1102  case fitsType<fitsCommentType>():
1103  {
1104  return fits_write_comment(fptr, (char *) m_comment.c_str());
1105  }
1106  case fitsType<fitsHistoryType>():
1107  {
1108  return fits_write_history(fptr, (char *) m_comment.c_str());
1109  }
1110  default:
1111  {
1112  mxThrowException(err::invalidarg, "fitsHeaderCard::write", std::string("invalid FITS type for ") + m_keyword);
1113  }
1114  }
1115 }
1116 
1117 } //namespace fits
1118 } //namespace mx
1119 
1120 
mxException for invalid arguments
mxException for not implemented features
mxException for parameters which aren't set
Class to manage the three components of a FITS header card.
std::complex< float > complexFloat()
Get the value as a std::complex<float>
fitsHeaderCard & operator=(const fitsHeaderCard &card)
Assignment.
const std::string & keyword()
Get the keyword.
int m_type
The FITS type of the value, and indicates which member of m_values to access.
std::stringstream m_valueStr
The value in string form.
int type()
Get the type.
char Char()
Get the value as a char.
std::string m_keyword
The keyword.
bool m_valueGood
Flag indicating if the value is valid.
const std::string & comment()
Get the comment.
typeT value()
Get the value.
double Double()
Get the value as a double.
long Long()
Get the value as a long.
int Int()
Get the value as a int.
unsigned char UChar()
Get the value as an unsigned char.
typeT convertedValue()
Get the value from its type converted to a different type.
unsigned short UShort()
Get the value as an unsigned short.
unsigned long ULong()
Get the value as an unsigned long.
unsigned int UInt()
Get the value as an unsigned int.
std::complex< double > complexDouble()
Get the value as a std::complex<double>
short Short()
Get the value as a short.
std::string m_comment
The comment.
bool m_valueStrGood
Flag indicating if the value string is valid.
long long LongLong()
Get the value as a long long.
void convertValue(int newtype)
Convert the value from its type to a different type.
unsigned long long ULongLong()
Get the value as an unsigned long long.
void convertToString()
Convert from the type to a string.
std::string String()
Get the value as a string.
int write(fitsfile *fptr)
Writes this card to a FITS file, using mx::improc::fits_write_key<typename typeT>(fitsfile * fptr,...
float Float()
Get the value as a float.
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
constexpr int fitsType()
Return the cfitsio constant for a given data type.
Definition: fitsUtils.hpp:107
std::string convertToString(const typeT &value, int precision=0)
Convert a numerical value to a string.
Definition: stringUtils.hpp:82
The mxlib c++ namespace.
Definition: mxError.hpp:107
The native type is held in a union.
unsigned int UInt
the unsigned int value
unsigned long long ULongLong
the unsigned long long value
std::complex< double > complexDouble
the std::complex<double> value
std::complex< float > complexFloat
the std::complex<float> value
unsigned short UShort
the unsigned short value
unsigned long ULong
the unsigned long value
double Double
the double value
unsigned char UChar
the unsigned char value
long long LongLong
the long long value