GammaLib 2.0.0
Loading...
Searching...
No Matches
GFitsHeaderCard.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GFitsHeaderCard.cpp - FITS header card class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2008-2018 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GFitsHeaderCard.cpp
23 * @brief FITS header card class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <cfloat>
32#include <climits>
33#include "GException.hpp"
34#include "GTools.hpp"
35#include "GFitsCfitsio.hpp"
36#include "GFits.hpp"
37#include "GFitsHeaderCard.hpp"
38
39/* __ Method name definitions ____________________________________________ */
40#define G_COPY_DTYPE "GFitsHeaderCard::copy_dtype(GFitsHeaderCard&)"
41#define G_FREE_DTYPE "GFitsHeaderCard::free_dtype()"
42#define G_SET_DTYPE "GFitsHeaderCard::set_dtype(std::string&)"
43#define G_READ_NUM "GFitsHeaderCard::read(void*, int&)"
44#define G_READ_STR "GFitsHeaderCard::read(void*, std::string&)"
45#define G_WRITE "GFitsHeaderCard::write(void*)"
46
47/* __ Definitions ________________________________________________________ */
48
49/* __ Macros _____________________________________________________________ */
50
51/* __ Coding definitions _________________________________________________ */
52
53/* __ Enumerations _______________________________________________________ */
54
55/* __ Debug definitions __________________________________________________ */
56
57
58/*==========================================================================
59 = =
60 = Constructors/destructors =
61 = =
62 ==========================================================================*/
63
64/***********************************************************************//**
65 * @brief Void constructor
66 ***************************************************************************/
68{
69 // Initialise class members
71
72 // Return
73 return;
74}
75
76
77/***********************************************************************//**
78 * @brief Card constructor
79 *
80 * @param[in] keyname Card name.
81 * @param[in] value Card value.
82 * @param[in] unit Card unit.
83 * @param[in] comment Card comment.
84 *
85 * Constructs a header card from @p keyname, @p value, @p unit and
86 * @p comment string. The card type is determined from the card value format.
87 ***************************************************************************/
88GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
89 const std::string& value,
90 const std::string& unit,
91 const std::string& comment)
92{
93 // Initialise class members
95
96 // Set members
98
99 // Return
100 return;
101}
102
103
104
105
106/***********************************************************************//**
107 * @brief Constructor for string cards
108 *
109 * @param[in] keyname Card name.
110 * @param[in] value Card string value.
111 * @param[in] comment Card comment.
112 *
113 * This constructor builds a header card from the keyname, value and comment.
114 ***************************************************************************/
115GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
116 const std::string& value,
117 const std::string& comment)
118{
119 // Initialise class members
120 init_members();
121
122 // Set members
123 this->keyname(keyname);
124 this->value("'"+value+"'");
125 this->comment(comment);
126
127 // Return
128 return;
129}
130
131
132/***********************************************************************//**
133 * @brief Constructor for floating point cards
134 *
135 * @param[in] keyname Card name.
136 * @param[in] value Card floating point value.
137 * @param[in] comment Card comment.
138 *
139 * This constructor builds a header card from the keyname, value and comment.
140 ***************************************************************************/
141GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
142 const double& value,
143 const std::string& comment)
144{
145 // Initialise class members
146 init_members();
147
148 // Set members
149 this->keyname(keyname);
150 this->value(value);
151 this->comment(comment);
152
153 // Return
154 return;
155}
156
157
158/***********************************************************************//**
159 * @brief Constructor for boolean cards
160 *
161 * @param[in] keyname Card name.
162 * @param[in] value Card integer value.
163 * @param[in] comment Card comment.
164 *
165 * This constructor builds a header card from the keyname, value and comment.
166 ***************************************************************************/
167GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
168 const int& value,
169 const std::string& comment)
170{
171 // Initialise class members
172 init_members();
173
174 // Set members
175 this->keyname(keyname);
176 this->value(value);
177 this->comment(comment);
178
179 // Return
180 return;
181}
182
183
184/***********************************************************************//**
185 * @brief Constructor for integer cards
186 *
187 * @param[in] keyname Card name.
188 * @param[in] value Card boolean value.
189 * @param[in] comment Card comment.
190 *
191 * This constructor builds a header card from the keyname, value and comment.
192 ***************************************************************************/
193GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
194 const bool& value,
195 const std::string& comment)
196{
197 // Initialise class members
198 init_members();
199
200 // Set members
201 this->keyname(keyname);
202 this->value(value);
203 this->comment(comment);
204
205 // Return
206 return;
207}
208
209
210/***********************************************************************//**
211 * @brief Constructor for character string cards
212 *
213 * @param[in] keyname Card name.
214 * @param[in] value Card character string value.
215 * @param[in] comment Card comment.
216 *
217 * This constructor builds a header card from the keyname, value and comment.
218 ***************************************************************************/
219GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
220 const char* value,
221 const std::string& comment)
222{
223 // Initialise class members
224 init_members();
225
226 // Set members
227 this->keyname(keyname);
228 this->value(std::string(value));
229 this->comment(comment);
230
231 // Return
232 return;
233}
234
235
236/***********************************************************************//**
237 * @brief Copy constructor
238 *
239 * @param[in] card Header card.
240 ***************************************************************************/
242{
243 // Initialise class members for clean destruction
244 init_members();
245
246 // Copy members
247 copy_members(card);
248
249 // Return
250 return;
251}
252
253
254/***********************************************************************//**
255 * @brief Destructor
256 ***************************************************************************/
258{
259 // Free members
260 free_members();
261
262 // Return
263 return;
264}
265
266/*==========================================================================
267 = =
268 = Operators =
269 = =
270 ==========================================================================*/
271
272/***********************************************************************//**
273 * @brief Assignment operator
274 *
275 * @param[in] card Header card.
276 * @return Header card.
277 ***************************************************************************/
279{
280 // Execute only if object is not identical
281 if (this != &card) {
282
283 // Free members
284 free_members();
285
286 // Initialise private members for clean destruction
287 init_members();
288
289 // Copy members
290 copy_members(card);
291
292 } // endif: object was not identical
293
294 // Return this object
295 return *this;
296}
297
298
299/*==========================================================================
300 = =
301 = Public methods =
302 = =
303 ==========================================================================*/
304
305/***********************************************************************//**
306 * @brief Clear header card
307 ***************************************************************************/
309{
310 // Free members
311 free_members();
312
313 // Initialise members
314 init_members();
315
316 // Return
317 return;
318}
319
320
321/***********************************************************************//**
322 * @brief Clone header card
323 *
324 * @return Pointer to deep copy of header card.
325 ***************************************************************************/
327{
328 return new GFitsHeaderCard(*this);
329}
330
331
332/***********************************************************************//**
333 * @brief Set name of header card
334 *
335 * @param[in] keyname Card name.
336 ***************************************************************************/
337void GFitsHeaderCard::keyname(const std::string& keyname)
338{
339 // Set name of card
341
342 // Return
343 return;
344}
345
346
347/***********************************************************************//**
348 * @brief Set string value of header card
349 *
350 * @param[in] value Card string value.
351 *
352 * This method sets the value of a string header card. The internal string
353 * representation contains hyphens, yet for keyword writing the hyphens are
354 * stripped.
355 ***************************************************************************/
356void GFitsHeaderCard::value(const std::string& value)
357{
358 // Free data type
359 free_dtype();
360
361 // Set value
362 m_value = value;
363
364 // Attach hyphens to internal string representation if required
365 if (m_value[0] != '\x27') {
366 m_value = "'" + m_value;
367 }
368 if (m_value[m_value.length()-1] != '\x27') {
369 m_value = m_value + "'";
370 }
371
372 // Strip hyphens and whitespace from datatype value that is used for
373 // keyword writing
374 std::string value_dtype =
375 gammalib::strip_whitespace(m_value.substr(1, m_value.length() - 2));
376
377 // Set data type
379 m_value_dtype = new std::string(value_dtype);
380
381 // Return
382 return;
383}
384
385
386/***********************************************************************//**
387 * @brief Set boolean value of header card
388 *
389 * @param[in] value Card boolean value.
390 ***************************************************************************/
391void GFitsHeaderCard::value(const bool& value)
392{
393 // Free data type
394 free_dtype();
395
396 // Set value and data type
397 m_value = (value) ? "T" : "F";
399 m_value_dtype = new bool(value);
400
401 // Return
402 return;
403}
404
405
406/***********************************************************************//**
407 * @brief Set single precision value of header card
408 *
409 * @param[in] value Card single precision value.
410 ***************************************************************************/
411void GFitsHeaderCard::value(const float& value)
412{
413 // Free data type
414 free_dtype();
415
416 // Set value and data type
419 m_value_dtype = new float(value);
420
421 // Return
422 return;
423}
424
425
426/***********************************************************************//**
427 * @brief Set double precision value of header card
428 *
429 * @param[in] value Card double precision value.
430 ***************************************************************************/
431void GFitsHeaderCard::value(const double& value)
432{
433 // Free data type
434 free_dtype();
435
436 // Set value and data type
439 m_value_dtype = new double(value);
440
441 // Return
442 return;
443}
444
445
446/***********************************************************************//**
447 * @brief Set unsigned short integer value of header card
448 *
449 * @param[in] value Card unsigned short integer value.
450 ***************************************************************************/
451void GFitsHeaderCard::value(const unsigned short& value)
452{
453 // Free data type
454 free_dtype();
455
456 // Set value and data type
459 m_value_dtype = new unsigned short(value);
460
461 // Return
462 return;
463}
464
465
466/***********************************************************************//**
467 * @brief Set short integer value of header card
468 *
469 * @param[in] value Card short integer value.
470 ***************************************************************************/
471void GFitsHeaderCard::value(const short& value)
472{
473 // Free data type
474 free_dtype();
475
476 // Set value and data type
479 m_value_dtype = new short(value);
480
481 // Return
482 return;
483}
484
485
486/***********************************************************************//**
487 * @brief Set unsigned integer value of header card
488 *
489 * @param[in] value Card unsigned integer value.
490 ***************************************************************************/
491void GFitsHeaderCard::value(const unsigned int& value)
492{
493 // Free data type
494 free_dtype();
495
496 // Set value and data type
499 m_value_dtype = new unsigned int(value);
500
501 // Return
502 return;
503}
504
505
506/***********************************************************************//**
507 * @brief Set integer value of header card
508 *
509 * @param[in] value Card integer value.
510 ***************************************************************************/
511void GFitsHeaderCard::value(const int& value)
512{
513 // Free data type
514 free_dtype();
515
516 // Set value and data type
518 m_dtype = __TINT;
519 m_value_dtype = new int(value);
520
521 // Return
522 return;
523}
524
525
526/***********************************************************************//**
527 * @brief Set long integer value of header card
528 *
529 * @param[in] value Card long integer value.
530 ***************************************************************************/
531void GFitsHeaderCard::value(const long& value)
532{
533 // Free data type
534 free_dtype();
535
536 // Set value and data type
539 m_value_dtype = new long(value);
540
541 // Return
542 return;
543}
544
545
546/***********************************************************************//**
547 * @brief Set unsigned integer long value of header card
548 *
549 * @param[in] value Card unsigned long integer value.
550 ***************************************************************************/
551void GFitsHeaderCard::value(const unsigned long& value)
552{
553 // Free data type
554 free_dtype();
555
556 // Set value and data type
559 m_value_dtype = new unsigned long(value);
560
561 // Return
562 return;
563}
564
565
566/***********************************************************************//**
567 * @brief Set long long integer value of header card
568 *
569 * @param[in] value Card long long integer value.
570 ***************************************************************************/
571void GFitsHeaderCard::value(const long long& value)
572{
573 // Free data type
574 free_dtype();
575
576 // Set value and data type
579 m_value_dtype = new long long(value);
580
581 // Return
582 return;
583}
584
585
586/***********************************************************************//**
587 * @brief Return header card value as string
588 *
589 * @return Header card value as string
590 *
591 * Returns header card value as string. Any hyphens that may occur in the
592 * FITS card will be stripped.
593 ***************************************************************************/
594std::string GFitsHeaderCard::string(void) const
595{
596 // Initialize return value to actual value string
597 std::string result = m_value;
598
599 // Type dependent conversion
600 if (m_value_dtype != NULL) {
601 switch (m_dtype) {
602 case __TSTRING:
603 {
604 int n = m_value.length();
605 if (n > 2) {
606 result = gammalib::strip_whitespace(m_value.substr(1, n-2));
607 }
608 else {
609 result = "";
610 }
611 }
612 break;
613 default:
614 break;
615 }
616 }
617
618 // Return string
619 return result;
620
621}
622
623
624/***********************************************************************//**
625 * @brief Return header card value as double precision
626 *
627 * Convert header card value into a double precision value. In case that the
628 * card did not contain a numerical value, 0 will be returned by the
629 * method.
630 ***************************************************************************/
631double GFitsHeaderCard::real(void) const
632{
633 // Initialize return value to 0.0
634 double result = 0.0;
635
636 // Type dependent conversion
637 if (m_value_dtype != NULL) {
638 switch (m_dtype) {
639 case __TSTRING:
640 if (m_value.length() > 2) {
641 result = gammalib::todouble(m_value.substr(1, m_value.length() - 2));
642 }
643 break;
644 case __TLOGICAL:
645 result = (m_value == "T") ? 1.0 : 0.0;
646 break;
647 default:
648 result = gammalib::todouble(m_value);
649 break;
650 }
651 }
652
653 // Return string
654 return result;
655
656}
657
658
659/***********************************************************************//**
660 * @brief Return header card value as integer
661*
662 * Convert header card value into a integer value. In case that the
663 * card did not contain a numerical value, 0 will be returned by the
664 * method.
665 ***************************************************************************/
667{
668 // Initialize return value to 0
669 int result = 0;
670
671 // Type dependent conversion
672 if (m_value_dtype != NULL) {
673 switch (m_dtype) {
674 case __TSTRING:
675 if (m_value.length() > 2) {
676 result = gammalib::toint(m_value.substr(1, m_value.length() - 2));
677 }
678 break;
679 case __TLOGICAL:
680 result = (m_value == "T") ? 1 : 0;
681 break;
682 default:
683 result = gammalib::toint(m_value);
684 break;
685 }
686 }
687
688 // Return string
689 return result;
690
691}
692
693
694/***********************************************************************//**
695 * @brief Print header card information
696 *
697 * @param[in] chatter Chattiness (defaults to NORMAL).
698 * @return String containing header card information.
699 ***************************************************************************/
700std::string GFitsHeaderCard::print(const GChatter& chatter) const
701{
702 // Initialise result string
703 std::string result;
704
705 // Continue only if chatter is not silent
706 if (chatter != SILENT) {
707
708 // Append keyname
709 result.append(gammalib::left(m_keyname,8));
710
711 // Format values
712 if (m_keyname != "COMMENT" && m_keyname != "HISTORY" && m_keyname != "") {
713 if (m_unit.length() > 0) {
714 result.append(" ="+gammalib::right(m_value,21)+" / ["+m_unit+"] "+m_comment);
715 }
716 else {
717 result.append(" ="+gammalib::right(m_value,21)+" / "+m_comment);
718 }
719 }
720 else {
721 result.append(" "+m_comment);
722 }
723
724 // Attach card type
725 if (m_value_dtype != NULL) {
726 switch (m_dtype) {
727 case __TNULL:
728 result.append(" <null>");
729 break;
730 case __TBIT:
731 result.append(" <bit>");
732 break;
733 case __TBYTE:
734 result.append(" <byte>");
735 break;
736 case __TSBYTE:
737 result.append(" <signed byte>");
738 break;
739 case __TLOGICAL:
740 result.append(" <bool>");
741 break;
742 case __TSTRING:
743 result.append(" <string>");
744 break;
745 case __TUSHORT:
746 result.append(" <unsigned short>");
747 break;
748 case __TSHORT:
749 result.append(" <short>");
750 break;
751 case __TUINT:
752 result.append(" <unsigned int>");
753 break;
754 case __TINT:
755 result.append(" <int>");
756 break;
757 case __TULONG:
758 result.append(" <unsigned long>");
759 break;
760 case __TLONG:
761 result.append(" <long>");
762 break;
763 case __TLONGLONG:
764 result.append(" <long long>");
765 break;
766 case __TFLOAT:
767 result.append(" <float>");
768 break;
769 case __TDOUBLE:
770 result.append(" <double>");
771 break;
772 case __TCOMPLEX:
773 result.append(" <complex>");
774 break;
775 case __TDBLCOMPLEX:
776 result.append(" <double complex>");
777 break;
778 default:
779 result.append(" <unsupported value "+gammalib::str(m_dtype)+">");
780 break;
781 }
782 }
783 /*
784 else {
785 switch (m_dtype) {
786 case __TNULL:
787 result.append(" <null>");
788 break;
789 default:
790 result.append(" <non native>");
791 break;
792 }
793 }
794 */
795
796 } // endif: chatter was not silent
797
798 // Return result
799 return result;
800}
801
802
803/*==========================================================================
804 = =
805 = Private methods =
806 = =
807 ==========================================================================*/
808
809/***********************************************************************//**
810 * @brief Initialise class members
811 ***************************************************************************/
813{
814 // Initialise members
815 m_keyname.clear();
816 m_value.clear();
817 m_unit.clear();
818 m_comment.clear();
819 m_value_dtype = NULL;
821 m_value_decimals = 10;
822 m_comment_write = true; // Was false before, not sure why ...
823
824 // Return
825 return;
826}
827
828
829/***********************************************************************//**
830 * @brief Copy class members
831 *
832 * @param[in] card Header card to be copied
833 ***************************************************************************/
835{
836 // Copy members
837 m_keyname = card.m_keyname;
838 m_value = card.m_value;
840 m_unit = card.m_unit;
841 m_comment = card.m_comment;
843
844 // Copy native data types
845 copy_dtype(card);
846
847 // Return
848 return;
849}
850
851
852/***********************************************************************//**
853 * @brief Delete class members
854 ***************************************************************************/
856{
857 // Free members
858 free_dtype();
859
860 // Return
861 return;
862}
863
864
865/***********************************************************************//**
866 * @brief Set card members
867 *
868 * @param[in] keyname Card name.
869 * @param[in] value Card value.
870 * @param[in] unit Card unit.
871 * @param[in] comment Card comment.
872 *
873 * Sets the card members from @p keyname, @p value, @p unit, and @p comment
874 * strings. The card type is determined from the format of the card value.
875 ***************************************************************************/
876void GFitsHeaderCard::set_members(const std::string& keyname,
877 const std::string& value,
878 const std::string& unit,
879 const std::string& comment) {
880
881 // Store attributes
883 m_value = value;
885
886 // Determine card type
888
889 // Return
890 return;
891}
892
893
894/***********************************************************************//**
895 * @brief Copy dtype
896 *
897 * @param[in] card Header card.
898 *
899 * Copies the data type of a header card.
900 ***************************************************************************/
902{
903 // Copy data type
904 if (card.m_value_dtype != NULL) {
905 m_dtype = card.m_dtype;
906 switch (m_dtype) {
907 case __TLOGICAL:
908 m_value_dtype = new bool(*((bool*)card.m_value_dtype));
909 break;
910 case __TSTRING:
911 m_value_dtype = new std::string(*((std::string*)card.m_value_dtype));
912 break;
913 case __TUSHORT:
914 m_value_dtype = new unsigned short(*((unsigned short*)card.m_value_dtype));
915 break;
916 case __TSHORT:
917 m_value_dtype = new short(*((short*)card.m_value_dtype));
918 break;
919 case __TUINT:
920 m_value_dtype = new unsigned int(*((unsigned int*)card.m_value_dtype));
921 break;
922 case __TINT:
923 m_value_dtype = new int(*((int*)card.m_value_dtype));
924 break;
925 case __TULONG:
926 m_value_dtype = new unsigned long(*((unsigned long*)card.m_value_dtype));
927 break;
928 case __TLONG:
929 m_value_dtype = new long(*((long*)card.m_value_dtype));
930 break;
931 case __TLONGLONG:
932 m_value_dtype = new long long(*((long long*)card.m_value_dtype));
933 break;
934 case __TFLOAT:
935 m_value_dtype = new float(*((float*)card.m_value_dtype));
936 break;
937 case __TDOUBLE:
938 m_value_dtype = new double(*((double*)card.m_value_dtype));
939 break;
940 default:
941 std::string msg = "Invalid data type code "+
942 gammalib::str(m_dtype)+" encountered.";
944 break;
945 }
946 }
947
948 // Return
949 return;
950}
951
952
953/***********************************************************************//**
954 * @brief Free dtype
955 ***************************************************************************/
957{
958 // Free data type
959 if (m_value_dtype != NULL) {
960 switch (m_dtype) {
961 case __TLOGICAL:
962 delete (bool*)m_value_dtype;
963 break;
964 case __TSTRING:
965 delete (std::string*)m_value_dtype;
966 break;
967 case __TUSHORT:
968 delete (unsigned short*)m_value_dtype;
969 break;
970 case __TSHORT:
971 delete (short*)m_value_dtype;
972 break;
973 case __TUINT:
974 delete (unsigned int*)m_value_dtype;
975 break;
976 case __TINT:
977 delete (int*)m_value_dtype;
978 break;
979 case __TULONG:
980 delete (unsigned long*)m_value_dtype;
981 break;
982 case __TLONG:
983 delete (long*)m_value_dtype;
984 break;
985 case __TLONGLONG:
986 delete (long long*)m_value_dtype;
987 break;
988 case __TFLOAT:
989 delete (float*)m_value_dtype;
990 break;
991 case __TDOUBLE:
992 delete (double*)m_value_dtype;
993 break;
994 default:
995 std::string msg = "Invalid data type code "+
996 gammalib::str(m_dtype)+" encountered.";
998 break;
999 }
1000 }
1001
1002 // Return
1003 return;
1004}
1005
1006
1007/***********************************************************************//**
1008 * @brief Set native data type from card string
1009 *
1010 * @param[in] value Card string.
1011 *
1012 * The native data type is determined from the card string. This method sets
1013 * the members m_dtype and m_value_type. The card type is determined by
1014 * analyzing the card value.
1015 *
1016 * @todo Implement syntax checking for integer or float values.
1017 ***************************************************************************/
1018void GFitsHeaderCard::set_dtype(const std::string& value)
1019{
1020 // Free data type
1021 free_dtype();
1022
1023 // Main loop to allow fall through
1024 do {
1025
1026 // Get index of last string element
1027 int last = m_value.length() - 1;
1028
1029 // If value is empty and there is a COMMENT, HISTORY or BLANKFIELD
1030 // (empty) keyword then we have a commentary card. We can just
1031 // skip this card here. Otherwise we have an undefined value, also
1032 // called NULL value.
1033 if (last < 0) {
1034 if (m_keyname == "COMMENT" ||
1035 m_keyname == "HISTORY" ||
1036 m_keyname == "") {
1037 continue;
1038 }
1039 else {
1040 m_dtype = __TNULL;
1041 continue;
1042 }
1043 }
1044
1045 // If value is enclosed in parentheses then we have a string
1046 if (m_value[0] == '\x27' && m_value[last] == '\x27') {
1047 this->value(value);
1048 continue;
1049 }
1050
1051 // If value has only one digit and is either 'F' or 'T' we have a
1052 // Boolean
1053 if (last == 0 && (m_value[0] == 'F' || m_value[0] == 'T')) {
1054 this->value((m_value[0] == 'T'));
1055 continue;
1056 }
1057
1058 // Conversion
1059 double value_dbl = gammalib::todouble(m_value);
1060 long long value_ll = gammalib::tolonglong(m_value);
1061 unsigned long long value_ull = gammalib::toulonglong(m_value);
1062
1063 // Check if we have an integer
1064 if ((value_dbl >= 0 && value_dbl == value_ull) ||
1065 (value_dbl < 0 && value_dbl == value_ll)) {
1066
1067 // Consider positive integers as unsigned
1068 if (value_dbl >= 0) {
1069 if (value_ull > ULONG_MAX) {
1071 m_value_dtype = new long long(value_ll);
1072 }
1073 else if (value_ull > USHRT_MAX) {
1074 m_dtype = __TULONG;
1075 m_value_dtype = new unsigned long(value_ull);
1076 }
1077 else {
1079 m_value_dtype = new unsigned short(value_ull);
1080 }
1081 }
1082
1083 // ... otherwise consider signed
1084 else {
1085 if (value_ll > LONG_MAX || value_ll < LONG_MIN) {
1087 m_value_dtype = new long long(value_ll);
1088 }
1089 else if (value_ll > SHRT_MAX || value_ll < SHRT_MIN) {
1090 m_dtype = __TLONG;
1091 m_value_dtype = new long(value_ll);
1092 }
1093 else {
1094 m_dtype = __TSHORT;
1095 m_value_dtype = new short(value_ll);
1096 }
1097 }
1098 } // endif: handled integers
1099
1100 // ... otherwise handle floats
1101 else {
1102 if (value_dbl > FLT_MAX || value_dbl < FLT_MIN) {
1104 m_value_dtype = new double(value_dbl);
1105 }
1106 else {
1107 m_dtype = __TFLOAT;
1108 m_value_dtype = new float(value_dbl);
1109 }
1110 }
1111
1112 } while(0);
1113
1114 // Return
1115 return;
1116}
1117
1118
1119/***********************************************************************//**
1120 * @brief Read header card from FITS file
1121 *
1122 * @param[in] vptr FITS file void pointer.
1123 * @param[in] keynum Number of the header card.
1124 ***************************************************************************/
1125void GFitsHeaderCard::read(void* vptr, const int& keynum)
1126{
1127 // Initialise status
1128 int status = 0;
1129
1130 // Move to HDU
1132
1133 // Read keyword
1134 char keyname[80];
1135 char value[80];
1136 char comment[80];
1137 status = __ffgkyn(FPTR(vptr), keynum, keyname, value, comment, &status);
1138 if (status != 0) {
1139 throw GException::fits_error(G_READ_NUM, status);
1140 }
1141
1142 // Store result
1143 m_keyname.assign(keyname);
1144 m_value.assign(value);
1145 m_comment.assign(comment);
1146
1147 // Determine card type
1149
1150 // Return
1151 return;
1152}
1153
1154
1155/***********************************************************************//**
1156 * @brief Read header card from FITS file
1157 *
1158 * @param[in] vptr FITS file void pointer.
1159 * @param[in] keyname Name of the header card.
1160 *
1161 * @exception GException::invalid_value
1162 * Specified @p keyname not found in FITS header.
1163 * @exception GException::fits_error
1164 * cfitsio error occured.
1165 ***************************************************************************/
1166void GFitsHeaderCard::read(void* vptr, const std::string& keyname)
1167{
1168 // Initialise FITS status
1169 int status = 0;
1170
1171 // Move to HDU
1173
1174 // Read keyword
1175 char value[80];
1176 char comment[80];
1177 status = __ffgkey(FPTR(vptr), (char*)keyname.c_str(), value, comment,
1178 &status);
1179
1180 // Catch error
1181 if (status == 202) { // Keyword not found
1182 std::string msg = "Header card with keyword \""+keyname+"\" not"
1183 " found in FITS header (status=202).";
1185 }
1186 else if (status != 0) { // Any other error
1187 std::string msg = "Unable to read keyword \""+keyname+"\" from"
1188 " FITS extension "+
1189 gammalib::str((FPTR(vptr)->HDUposition))+
1190 " header.";
1191 throw GException::fits_error(G_READ_STR, status, msg);
1192 }
1193
1194 // Store result
1196 m_value.assign(value);
1197 m_comment.assign(comment);
1198
1199 // Determine card type
1201
1202 // Return
1203 return;
1204}
1205
1206
1207/***********************************************************************//**
1208 * @brief Write header card
1209 *
1210 * @param[in] vptr FITS file void pointer.
1211 *
1212 * Writes any kind of header card to a FITS file.
1213 ***************************************************************************/
1214void GFitsHeaderCard::write(void* vptr) const
1215{
1216 // Initialise status
1217 int status = 0;
1218
1219 // Move to HDU
1221
1222 // If card is comment then write comment
1223 if (m_keyname == "COMMENT") {
1224 if (m_comment_write) {
1225 status = __ffpcom(FPTR(vptr), (char*)m_comment.c_str(), &status);
1226 }
1227 }
1228
1229 // If card is history then write history
1230 else if (m_keyname == "HISTORY") {
1231 if (m_comment_write) {
1232 status = __ffphis(FPTR(vptr), (char*)m_comment.c_str(), &status);
1233 }
1234 }
1235
1236 // If card is BLANKFIELD (empty keyword) then write empty line
1237 else if (m_keyname == "") {
1238 if (m_comment_write) {
1239 status = __ffprec(FPTR(vptr), "", &status);
1240 }
1241 }
1242
1243 // If card holds a native data type then write it
1244 else if (m_value_dtype != NULL) {
1245 switch (m_dtype) {
1246 case __TLOGICAL:
1247 {
1248 int value = (*((bool*)m_value_dtype)) ? 1 : 0;
1249 status = __ffukyl(FPTR(vptr), (char*)m_keyname.c_str(), value,
1250 (char*)m_comment.c_str(), &status);
1251 }
1252 break;
1253 case __TSTRING:
1254 status = __ffukys(FPTR(vptr), (char*)m_keyname.c_str(),
1255 (char*)((std::string*)m_value_dtype)->c_str(),
1256 (char*)m_comment.c_str(), &status);
1257 break;
1258 case __TFLOAT:
1259 status = __ffukye(FPTR(vptr), (char*)m_keyname.c_str(),
1260 *((float*)m_value_dtype), decimals(),
1261 (char*)m_comment.c_str(), &status);
1262 break;
1263 case __TDOUBLE:
1264 status = __ffukyd(FPTR(vptr), (char*)m_keyname.c_str(),
1265 *((double*)m_value_dtype), decimals(),
1266 (char*)m_comment.c_str(), &status);
1267 break;
1268 default:
1269 status = __ffuky(FPTR(vptr), m_dtype, (char*)m_keyname.c_str(),
1270 m_value_dtype, (char*)m_comment.c_str(), &status);
1271 break;
1272 }
1273 } // endif: had native data type
1274
1275 // ... otherwise if card holds a NULL value then write it
1276 else if (m_dtype == __TNULL) {
1277 status = __ffukyu(FPTR(vptr), (char*)m_keyname.c_str(),
1278 (char*)m_comment.c_str(), &status);
1279 }
1280
1281 // ... capture all other stuff
1282 else {
1283 std::string msg = "The code should never arrive at this point!\n"
1284 "The keyname \""+m_keyname+"\" is neither"
1285 " \"COMMENT\" nor \"HISTRORY\" but it has a"
1286 " NULL data type value and a data type of"
1287 " "+gammalib::str(m_dtype)+".\n"
1288 "Maybe an invalid FITS header card has been"
1289 " encountered in reading a file?";
1291 }
1292
1293 // Throw exception in case of a FITS error
1294 if (status != 0) {
1295 throw GException::fits_error(G_WRITE, status);
1296 }
1297
1298 // Return
1299 return;
1300}
#define G_WRITE
Exception handler interface definition.
CFITSIO interface header.
#define __TLONG
#define __TLOGICAL
#define __ffukyu(A, B, C, D)
#define __TLONGLONG
#define __ffgkyn(A, B, C, D, E, F)
#define __ffuky(A, B, C, D, E, F)
#define __TSHORT
#define FPTR(A)
#define __TNULL
#define __ffpcom(A, B, C)
#define __ffukye(A, B, C, D, E, F)
#define __ffukyd(A, B, C, D, E, F)
#define __TDBLCOMPLEX
#define __ffphis(A, B, C)
#define __TBYTE
#define __ffprec(A, B, C)
#define __TULONG
#define __TSTRING
#define __TFLOAT
#define __ffukys(A, B, C, D, E)
#define __TDOUBLE
#define __TINT
#define __TUSHORT
#define __TSBYTE
#define __ffukyl(A, B, C, D, E)
#define __ffgkey(A, B, C, D, E)
#define __TCOMPLEX
#define __TUINT
#define __TBIT
#define G_READ_STR
#define G_FREE_DTYPE
#define G_READ_NUM
#define G_COPY_DTYPE
FITS header card class definition.
FITS file class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Implements FITS header card interface.
int m_dtype
Native data type.
std::string string(void) const
Return header card value as string.
void clear(void)
Clear header card.
void free_dtype(void)
Free dtype.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
void copy_dtype(const GFitsHeaderCard &card)
Copy dtype.
const std::string & comment(void) const
Return header card comment.
void set_dtype(const std::string &value)
Set native data type from card string.
const std::string & value(void) const
Return header card value.
std::string m_unit
Unit of the card value.
GFitsHeaderCard * clone(void) const
Clone header card.
const std::string & unit(void) const
Return header card value unit.
std::string m_comment
Card comment.
void copy_members(const GFitsHeaderCard &card)
Copy class members.
const std::string & keyname(void) const
Return header card keyname.
std::string m_keyname
Name of the card.
virtual ~GFitsHeaderCard(void)
Destructor.
double real(void) const
Return header card value as double precision.
std::string print(const GChatter &chatter=NORMAL) const
Print header card information.
GFitsHeaderCard(void)
Void constructor.
void write(void *fptr) const
Write header card.
int m_value_decimals
Decimals of value (for float)
void read(void *vptr, const int &keynum)
Read header card from FITS file.
const int & decimals(void) const
Return header card decimals.
GFitsHeaderCard & operator=(const GFitsHeaderCard &card)
Assignment operator.
std::string m_value
Value of the card as read from file.
bool m_comment_write
Signals that comment should be written.
void set_members(const std::string &keyname, const std::string &value, const std::string &unit, const std::string &comment)
Set card members.
int integer(void) const
Return header card value as integer.
void * m_value_dtype
Value in native data type.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
double todouble(const std::string &arg)
Convert string into double precision value.
Definition GTools.cpp:926
std::string left(const std::string &s, const int &n, const char &c=' ')
Left justify string to achieve a length of n characters.
Definition GTools.cpp:1070
std::string right(const std::string &s, const int &n, const char &c=' ')
Right justify string to achieve a length of n characters.
Definition GTools.cpp:1094
unsigned long long toulonglong(const std::string &arg)
Convert string into unsigned long long value.
Definition GTools.cpp:896
int toint(const std::string &arg)
Convert string into integer value.
Definition GTools.cpp:821
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
Definition GTools.cpp:80
int fits_move_to_hdu(const std::string &caller, void *vptr, const int &hdunum=0)
Move to FITS extension.
Definition GFits.cpp:1774
void warning(const std::string &origin, const std::string &message)
Emits warning.
Definition GTools.cpp:1386
long long tolonglong(const std::string &arg)
Convert string into long long value.
Definition GTools.cpp:881