Commit a0df9c339c7d1c6e8daa2c0ad92f79906efdcd2e

Authored by Jürgen Knödlseder
1 parent f0b7fc86

Review GFitsHeader class.

The GFitsHeader class now derives from GContainer and implements all generic container class methods (at(), size(), isempty(), append(), insert(), remove(), reserve(), extend()). The hascard() methods have been renamed to contains() for compliance with other container classes. The card() methods have been renamed to at(), also for compliance. The card access operators and methods now return the cards by reference. Card access operators[] have been implemented to access header cards without range checking.

The cards are now stored using a std::vector structure.
... ... @@ -43,6 +43,16 @@ GFits
43 43 returned as const references. HDU access operators[] have been
44 44 implemented to access FITS extensions without range checking.
45 45  
  46 +GFitsHeader
  47 + The GFitsHeader class now derives from GContainer and implements all
  48 + generic container class methods (at(), size(), isempty(), append(),
  49 + insert(), remove(), reserve(), extend()). The hascard() methods have
  50 + been renamed to contains() for compliance with other container classes.
  51 + The card() methods have been renamed to at(), also for compliance.
  52 + The card access operators and methods now return the cards by
  53 + reference. Card access operators[] have been implemented to access
  54 + header cards without range checking.
  55 +
46 56 GFitsTable
47 57 The column table operator[] now returns a pointer instead of a
48 58 reference. Set set() method has been added for column setting.
... ... @@ -218,6 +228,7 @@ from GContainer:
218 228 - GEnergies
219 229 - GGti
220 230 - GFits
  231 +- GFitsHeader
221 232 - GObservations
222 233 - GOptimizerPars (and hence GModels)
223 234 - GPars
... ...
include/GFitsHDU.hpp
1 1 /***************************************************************************
2   - * GFitsHDU.hpp - FITS HDU handling class *
  2 + * GFitsHDU.hpp - Abstract FITS extension base class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2008-2013 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -20,7 +20,7 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file GFitsHDU.hpp
23   - * @brief GFitsHDU class definition.
  23 + * @brief Abstract FITS extension base class definition.
24 24 * @author Juergen Knoedlseder
25 25 */
26 26  
... ... @@ -37,13 +37,13 @@
37 37 /***********************************************************************//**
38 38 * @class GFitsHDU
39 39 *
40   - * @brief Implements the FITS Header Data Unit (HDU) interface
  40 + * @brief Abstract FITS extension base class
41 41 *
42   - * The HDU is the basic unit of a FITS file. Each HDU consists of a header
43   - * and a data area. The header is composed of cards and is implemented by
44   - * the GFitsHeader class. The data are is either an image or a table and
45   - * is implemented by the abstract GFitsData base class.
46   - * The class holds a copy of the original FITS
  42 + * This class defines the abstract interface for a FITS extension, also known
  43 + * as Header Data Unit (HDU). Each HDU consists of a header and a data area.
  44 + * The header is composed of cards and is implemented by the GFitsHeader
  45 + * class. The data are is either an image or a table which are implemented
  46 + * as derived classes from GFitsHDU.
47 47 *
48 48 * @todo Implement GFitsHDU* select(const std::string& expr) that applies
49 49 * to a table HDU for row selection.
... ... @@ -60,7 +60,7 @@ public:
60 60 virtual ~GFitsHDU(void);
61 61  
62 62 // Operators
63   - GFitsHDU& operator= (const GFitsHDU& hdu);
  63 + GFitsHDU& operator=(const GFitsHDU& hdu);
64 64  
65 65 // Public enumerators
66 66 enum HDUType {
... ... @@ -76,16 +76,17 @@ public:
76 76 virtual std::string print(const GChatter& chatter = NORMAL) const = 0;
77 77  
78 78 // Implemented methods
79   - int size(void) const { return m_header.size(); }
80   - std::string extname(void) const { return m_name; }
81   - void extname(const std::string& extname);
82   - int extno(void) const { return m_hdunum; }
83   - void extno(int num) { m_hdunum=num; }
84   - GFitsHeader* header(void) { return &m_header; }
85   - bool hascard(const std::string& keyname) const;
86   - bool hascard(const int& cardno) const;
87   - GFitsHeaderCard* card(const std::string& keyname);
88   - GFitsHeaderCard* card(const int& cardno);
  79 + int size(void) const;
  80 + const std::string& extname(void) const;
  81 + void extname(const std::string& extname);
  82 + const int& extno(void) const;
  83 + void extno(const int& extno);
  84 + const GFitsHeader& header(void) const;
  85 +
  86 + bool hascard(const std::string& keyname) const;
  87 + bool hascard(const int& cardno) const;
  88 + GFitsHeaderCard* card(const std::string& keyname);
  89 + GFitsHeaderCard* card(const int& cardno);
89 90 std::string string(const std::string& keyname) const;
90 91 double real(const std::string& keyname) const;
91 92 int integer(const std::string& keyname) const;
... ... @@ -122,4 +123,75 @@ protected:
122 123 GFitsHeader m_header; //!< HDU header
123 124 };
124 125  
  126 +
  127 +/***********************************************************************//**
  128 + * @brief Return number of cards in HDU header
  129 + *
  130 + * @return Number of cards in HDU header.
  131 + *
  132 + * Returns the number of cards in the header of the FITS extension.
  133 + ***************************************************************************/
  134 +inline
  135 +int GFitsHDU::size(void) const
  136 +{
  137 + return (m_header.size());
  138 +}
  139 +
  140 +
  141 +/***********************************************************************//**
  142 + * @brief Return extension name
  143 + *
  144 + * @return Extension name.
  145 + *
  146 + * Returns the name of the FITS extension.
  147 + ***************************************************************************/
  148 +inline
  149 +const std::string& GFitsHDU::extname(void) const
  150 +{
  151 + return (m_name);
  152 +}
  153 +
  154 +
  155 +/***********************************************************************//**
  156 + * @brief Return extension number
  157 + *
  158 + * @return Extension number (starting from 0 for the primary image).
  159 + *
  160 + * Returns the number of the FITS extension.
  161 + ***************************************************************************/
  162 +inline
  163 +const int& GFitsHDU::extno(void) const
  164 +{
  165 + return (m_hdunum);
  166 +}
  167 +
  168 +
  169 +/***********************************************************************//**
  170 + * @brief Set extension number
  171 + *
  172 + * @param[in] extno Extension number (starting from 0 for the primary image).
  173 + *
  174 + * Set the number of the FITS extension.
  175 + ***************************************************************************/
  176 +inline
  177 +void GFitsHDU::extno(const int& extno)
  178 +{
  179 + m_hdunum = extno;
  180 + return;
  181 +}
  182 +
  183 +
  184 +/***********************************************************************//**
  185 + * @brief Return extension header
  186 + *
  187 + * @return Extension header.
  188 + *
  189 + * Returns the extension header.
  190 + ***************************************************************************/
  191 +inline
  192 +const GFitsHeader& GFitsHDU::header(void) const
  193 +{
  194 + return (m_header);
  195 +}
  196 +
125 197 #endif /* GFITSHDU_HPP */
... ...
include/GFitsHeader.hpp
1 1 /***************************************************************************
2   - * GFitsHeader.hpp - FITS header handling class *
  2 + * GFitsHeader.hpp - FITS header cards container class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2008-2013 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -20,7 +20,7 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file GFitsHeader.hpp
23   - * @brief FITS header class definition
  23 + * @brief FITS header cards container class definition
24 24 * @author Juergen Knoedlseder
25 25 */
26 26  
... ... @@ -28,7 +28,9 @@
28 28 #define GFITSHEADER_HPP
29 29  
30 30 /* __ Includes ___________________________________________________________ */
31   -#include "GBase.hpp"
  31 +#include <string>
  32 +#include <vector>
  33 +#include "GContainer.hpp"
32 34 #include "GFitsHeaderCard.hpp"
33 35  
34 36  
... ... @@ -37,13 +39,13 @@
37 39 *
38 40 * @brief Interface for FITS header class
39 41 *
40   - * The FITS header class contains all cards that are found in the header of
41   - * a HDU. All cards will be hold in memory, so no link to a FITS file is
42   - * required. Cards may be read from one file (using the 'open' method) and
43   - * saved into another file (using the 'save' method). Cards are added or
44   - * changed using the 'update' method.
  42 + * The FITS header class is a container class for header cards.
  43 + *
  44 + * All cards of a FITS file extension will be held in memory, so no link to
  45 + * a FITS file is required. Cards are read from a file using the load()
  46 + * method, and cards are saved into a file using the save() method.
45 47 ***************************************************************************/
46   -class GFitsHeader : public GBase {
  48 +class GFitsHeader : public GContainer {
47 49  
48 50 public:
49 51 // Constructors and destructors
... ... @@ -52,38 +54,174 @@ public:
52 54 virtual ~GFitsHeader(void);
53 55  
54 56 // Operators
55   - GFitsHeader& operator= (const GFitsHeader& header);
  57 + GFitsHeader& operator=(const GFitsHeader& header);
  58 + GFitsHeaderCard& operator[](const int& cardno);
  59 + const GFitsHeaderCard& operator[](const int& cardno) const;
  60 + GFitsHeaderCard& operator[](const std::string& keyname);
  61 + const GFitsHeaderCard& operator[](const std::string& keyname) const;
56 62  
57 63 // Methods
58   - void clear(void);
59   - GFitsHeader* clone(void) const;
60   - int size(void) const;
61   - void open(void* vptr);
62   - void save(void* vptr);
63   - void close(void);
64   - bool hascard(const std::string& keyname) const;
65   - bool hascard(const int& cardno) const;
66   - void update(const GFitsHeaderCard& card);
67   - GFitsHeaderCard* card(const std::string& keyname);
68   - GFitsHeaderCard* card(const int& cardno);
69   - std::string string(const std::string& keyname);
70   - std::string string(const int& cardno);
71   - double real(const std::string& keyname);
72   - double real(const int& cardno);
73   - int integer(const std::string& keyname);
74   - int integer(const int& cardno);
75   - std::string print(const GChatter& chatter = NORMAL) const;
  64 + void clear(void);
  65 + GFitsHeader* clone(void) const;
  66 + GFitsHeaderCard& at(const int& cardno);
  67 + const GFitsHeaderCard& at(const int& cardno) const;
  68 + GFitsHeaderCard& at(const std::string& keyname);
  69 + const GFitsHeaderCard& at(const std::string& keyname) const;
  70 + std::string string(const int& cardno) const;
  71 + std::string string(const std::string& keyname) const;
  72 + double real(const int& cardno) const;
  73 + double real(const std::string& keyname) const;
  74 + int integer(const int& cardno) const;
  75 + int integer(const std::string& keyname) const;
  76 + int size(void) const;
  77 + bool isempty(void) const;
  78 + GFitsHeaderCard& append(const GFitsHeaderCard& card);
  79 + GFitsHeaderCard& insert(const int& cardno, const GFitsHeaderCard& card);
  80 + GFitsHeaderCard& insert(const std::string& keyname, const GFitsHeaderCard& card);
  81 + void remove(const int& cardno);
  82 + void remove(const std::string& keyname);
  83 + void reserve(const int& num);
  84 + void extend(const GFitsHeader& header);
  85 + bool contains(const int& cardno) const;
  86 + bool contains(const std::string& keyname) const;
  87 + void load(void* vptr);
  88 + void save(void* vptr) const;
  89 + std::string print(const GChatter& chatter = NORMAL) const;
76 90  
77 91 private:
78 92 // Private methods
79   - void init_members(void);
80   - void copy_members(const GFitsHeader& header);
81   - void free_members(void);
82   - GFitsHeaderCard* card_ptr(const std::string& keyname) const;
  93 + void init_members(void);
  94 + void copy_members(const GFitsHeader& header);
  95 + void free_members(void);
  96 + int get_index(const std::string& keyname) const;
83 97  
84 98 // Private data area
85   - int m_num_cards;
86   - GFitsHeaderCard* m_card;
  99 + std::vector<GFitsHeaderCard> m_cards; //!< Header cards
87 100 };
88 101  
  102 +
  103 +/***********************************************************************//**
  104 + * @brief Return header card
  105 + *
  106 + * @param[in] cardno Number of card in header [0,...,size()-1]
  107 + * @return Header card.
  108 + ***************************************************************************/
  109 +inline
  110 +GFitsHeaderCard& GFitsHeader::operator[](const int& cardno)
  111 +{
  112 + return (m_cards[cardno]);
  113 +}
  114 +
  115 +
  116 +/***********************************************************************//**
  117 + * @brief Return pointer to model (const version)
  118 + *
  119 + * @param[in] cardno Number of card in header [0,...,size()-1]
  120 + * @return Header card.
  121 + ***************************************************************************/
  122 +inline
  123 +const GFitsHeaderCard& GFitsHeader::operator[](const int& cardno) const
  124 +{
  125 + return (m_cards[cardno]);
  126 +}
  127 +
  128 +
  129 +/***********************************************************************//**
  130 + * @brief Return header card
  131 + *
  132 + * @param[in] keyname Name of header card
  133 + * @return Header card.
  134 + ***************************************************************************/
  135 +inline
  136 +GFitsHeaderCard& GFitsHeader::operator[](const std::string& keyname)
  137 +{
  138 + return (at(keyname));
  139 +}
  140 +
  141 +
  142 +/***********************************************************************//**
  143 + * @brief Return header card (const version)
  144 + *
  145 + * @param[in] keyname Name of header card
  146 + * @return Header card.
  147 + ***************************************************************************/
  148 +inline
  149 +const GFitsHeaderCard& GFitsHeader::operator[](const std::string& keyname) const
  150 +{
  151 + return (at(keyname));
  152 +}
  153 +
  154 +
  155 +/***********************************************************************//**
  156 + * @brief Return number of cards in header
  157 + *
  158 + * @return Number of cards in header.
  159 + *
  160 + * Returns the number of cards in the extension header.
  161 + ***************************************************************************/
  162 +inline
  163 +int GFitsHeader::size(void) const
  164 +{
  165 + return (m_cards.size());
  166 +}
  167 +
  168 +
  169 +/***********************************************************************//**
  170 + * @brief Signals if there are no cards in the FITS header
  171 + *
  172 + * @return True if there are no cards in the FITS header, false otherwise
  173 + *
  174 + * Signals if there are no cards in the FITS header.
  175 + ***************************************************************************/
  176 +inline
  177 +bool GFitsHeader::isempty(void) const
  178 +{
  179 + return (m_cards.empty());
  180 +}
  181 +
  182 +
  183 +/***********************************************************************//**
  184 + * @brief Reserves space for cards in FITS header
  185 + *
  186 + * @param[in] num Number of cards
  187 + *
  188 + * Reserves space for @p num cards in the FITS header.
  189 + ***************************************************************************/
  190 +inline
  191 +void GFitsHeader::reserve(const int& num)
  192 +{
  193 + m_cards.reserve(num);
  194 + return;
  195 +}
  196 +
  197 +
  198 +/***********************************************************************//**
  199 + * @brief Check if card is present in header
  200 + *
  201 + * @param[in] cardno Number of card in header.
  202 + * @return True of card exists, false otherwise.
  203 + *
  204 + * Signals whether a card with specified card number exists in header.
  205 + ***************************************************************************/
  206 +inline
  207 +bool GFitsHeader::contains(const int& cardno) const
  208 +{
  209 + return (cardno >= 0 && cardno < size());
  210 +}
  211 +
  212 +
  213 +/***********************************************************************//**
  214 + * @brief Check if card is present in header
  215 + *
  216 + * @param[in] keyname Name of header card.
  217 + * @return True of card exists, false otherwise.
  218 + *
  219 + * Signals whether a card with specified @p keyname exists in header.
  220 + ***************************************************************************/
  221 +inline
  222 +bool GFitsHeader::contains(const std::string& keyname) const
  223 +{
  224 + return (get_index(keyname) != -1);
  225 +}
  226 +
89 227 #endif /* GFITSHEADER_HPP */
... ...
include/GFitsHeaderCard.hpp
... ... @@ -85,9 +85,9 @@ public:
85 85 std::string unit(void) const;
86 86 void comment(const std::string& comment);
87 87 std::string comment(void) const;
88   - std::string string(void);
89   - double real(void);
90   - int integer(void);
  88 + std::string string(void) const;
  89 + double real(void) const;
  90 + int integer(void) const;
91 91 std::string print(const GChatter& chatter = NORMAL) const;
92 92  
93 93 private:
... ... @@ -100,7 +100,7 @@ private:
100 100 void set_dtype(const std::string& value);
101 101 void read(void* vptr, const int& keynum);
102 102 void read(void* fptr, const std::string& keyname);
103   - void write(void* fptr);
  103 + void write(void* fptr) const;
104 104  
105 105 // Private data area
106 106 std::string m_keyname; //!< Name of the card
... ...
inst/lat/src/GLATEventList.cpp
... ... @@ -616,38 +616,38 @@ void GLATEventList::read_ds_keys(const GFitsHDU&amp; hdu)
616 616 for (int i = 0; i < ds_num; ++i) {
617 617  
618 618 // Get DSTYPnn
619   - try {
620   - std::sprintf(keyword, "DSTYP%d", i+1);
  619 + std::sprintf(keyword, "DSTYP%d", i+1);
  620 + if (ptr->hascard(keyword)) {
621 621 m_ds_type.push_back(ptr->card(std::string(keyword))->string());
622 622 }
623   - catch (GException::fits_key_not_found &e) {
  623 + else {
624 624 m_ds_type.push_back("");
625 625 }
626 626  
627 627 // Get DSUNInn
628   - try {
629   - std::sprintf(keyword, "DSUNI%d", i+1);
  628 + std::sprintf(keyword, "DSUNI%d", i+1);
  629 + if (ptr->hascard(keyword)) {
630 630 m_ds_unit.push_back(ptr->card(std::string(keyword))->string());
631 631 }
632   - catch (GException::fits_key_not_found &e) {
  632 + else {
633 633 m_ds_unit.push_back("");
634 634 }
635 635  
636 636 // Get DSVALnn
637   - try {
638   - std::sprintf(keyword, "DSVAL%d", i+1);
  637 + std::sprintf(keyword, "DSVAL%d", i+1);
  638 + if (ptr->hascard(keyword)) {
639 639 m_ds_value.push_back(ptr->card(std::string(keyword))->string());
640 640 }
641   - catch (GException::fits_key_not_found &e) {
  641 + else {
642 642 m_ds_value.push_back("");
643 643 }
644 644  
645 645 // Get DSREFnn
646   - try {
647   - std::sprintf(keyword, "DSREF%d", i+1);
  646 + std::sprintf(keyword, "DSREF%d", i+1);
  647 + if (ptr->hascard(keyword)) {
648 648 m_ds_reference.push_back(ptr->card(std::string(keyword))->string());
649 649 }
650   - catch (GException::fits_key_not_found &e) {
  650 + else {
651 651 m_ds_reference.push_back("");
652 652 }
653 653  
... ...
inst/lat/src/GLATPsf.cpp
... ... @@ -294,7 +294,7 @@ void GLATPsf::save(const std::string&amp; filename, bool clobber)
294 294 * and allocates the proper PSF version class. It reads the PSF information
295 295 * from the FITS file.
296 296 *
297   - * @todo Implement PSF versions 2 and 3.
  297 + * @todo Implement PSF version 2.
298 298 ***************************************************************************/
299 299 void GLATPsf::read(const GFits& fits)
300 300 {
... ... @@ -314,13 +314,7 @@ void GLATPsf::read(const GFits&amp; fits)
314 314 }
315 315  
316 316 // Determine PSF version (default version is version 1)
317   - int version = 1;
318   - try {
319   - version = hdu_rpsf->integer("PSFVER");
320   - }
321   - catch (GException::fits_key_not_found &e) {
322   - version = 1;
323   - }
  317 + int version = (hdu_rpsf->hascard("PSFVER")) ? hdu_rpsf->integer("PSFVER") : 1;
324 318  
325 319 // Determine PSF type
326 320 bool front = true;
... ...
inst/mwl/src/GMWLSpectrum.cpp
... ... @@ -676,18 +676,18 @@ void GMWLSpectrum::read_fits(const GFitsTable* table)
676 676 }
677 677  
678 678 // Get telescope name
679   - try {
  679 + if (table->hascard("TELESCOP")) {
680 680 m_telescope = table->string("TELESCOP");
681 681 }
682   - catch (GException::fits_key_not_found &e) {
  682 + else {
683 683 m_telescope = "unknown";
684 684 }
685 685  
686 686 // Get instrument name
687   - try {
  687 + if (table->hascard("INSTRUME")) {
688 688 m_instrument = table->string("INSTRUME");
689 689 }
690   - catch (GException::fits_key_not_found &e) {
  690 + else {
691 691 m_instrument = "unknown";
692 692 }
693 693  
... ...
pyext/GFitsHDU.i
... ... @@ -61,12 +61,13 @@ public:
61 61 virtual HDUType exttype(void) const = 0;
62 62  
63 63 // Implemented methods
64   - int size(void) const;
65   - std::string extname(void) const;
66   - void extname(const std::string& extname);
67   - int extno(void) const;
68   - void extno(int num);
69   - GFitsHeader* header(void);
  64 + int size(void) const;
  65 + const std::string& extname(void) const;
  66 + void extname(const std::string& extname);
  67 + const int& extno(void) const;
  68 + void extno(const int& extno);
  69 + const GFitsHeader& header(void) const;
  70 +
70 71 bool hascard(const std::string& keyname) const;
71 72 bool hascard(const int& cardno) const;
72 73 GFitsHeaderCard* card(const std::string& keyname);
... ...
pyext/GFitsHeader.i
1 1 /***************************************************************************
2   - * GFitsHeader.i - FITS header class *
  2 + * GFitsHeader.hpp - FITS header cards container class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2008-2013 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -20,7 +20,7 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file GFitsHeader.i
23   - * @brief FITS header class interface definition
  23 + * @brief FITS header cards container class definition
24 24 * @author Juergen Knoedlseder
25 25 */
26 26 %{
... ... @@ -29,19 +29,13 @@
29 29 #include "GTools.hpp"
30 30 %}
31 31  
32   -%include stl.i
  32 +//%include stl.i
33 33  
34 34  
35 35 /***********************************************************************//**
36 36 * @class GFitsHeader
37 37 *
38   - * @brief Implements FITS header class SWIG interface
39   - *
40   - * The FITS header class contains all cards that are found in the header of
41   - * a HDU. All cards will be hold in memory, so no link to a FITS file is
42   - * required. Cards may be read from one file (using the 'open' method) and
43   - * saved into another file (using the 'save' method). Cards are added or
44   - * changed using the 'update' method.
  38 + * @brief Interface for FITS header class
45 39 ***************************************************************************/
46 40 class GFitsHeader : public GBase {
47 41 public:
... ... @@ -53,28 +47,62 @@ public:
53 47 // Methods
54 48 void clear(void);
55 49 GFitsHeader* clone(void) const;
  50 + GFitsHeaderCard& at(const int& cardno);
  51 + GFitsHeaderCard& at(const std::string& keyname);
  52 + std::string string(const int& cardno) const;
  53 + std::string string(const std::string& keyname) const;
  54 + double real(const int& cardno) const;
  55 + double real(const std::string& keyname) const;
  56 + int integer(const int& cardno) const;
  57 + int integer(const std::string& keyname) const;
56 58 int size(void) const;
57   - void open(void* vptr);
58   - void save(void* vptr);
59   - void close(void);
60   - bool hascard(const std::string& keyname) const;
61   - bool hascard(const int& cardno) const;
62   - void update(const GFitsHeaderCard& card);
63   - GFitsHeaderCard* card(const std::string& keyname);
64   - GFitsHeaderCard* card(const int& cardno);
65   - std::string string(const std::string& keyname);
66   - std::string string(const int& cardno);
67   - double real(const std::string& keyname);
68   - double real(const int& cardno);
69   - int integer(const std::string& keyname);
70   - int integer(const int& cardno);
  59 + bool isempty(void) const;
  60 + GFitsHeaderCard& append(const GFitsHeaderCard& card);
  61 + GFitsHeaderCard& insert(const int& cardno, const GFitsHeaderCard& card);
  62 + GFitsHeaderCard& insert(const std::string& keyname, const GFitsHeaderCard& card);
  63 + void remove(const int& cardno);
  64 + void remove(const std::string& keyname);
  65 + void reserve(const int& num);
  66 + void extend(const GFitsHeader& header);
  67 + bool contains(const int& cardno) const;
  68 + bool contains(const std::string& keyname) const;
  69 + void load(void* vptr);
  70 + void save(void* vptr) const;
71 71 };
72 72  
73 73  
74 74 /***********************************************************************//**
75   - * @brief GFitsHeader class SWIG extension
  75 + * @brief GFitsHeader class extension
76 76 ***************************************************************************/
77 77 %extend GFitsHeader {
  78 + GFitsHeaderCard& __getitem__(const int& cardno) {
  79 + if (cardno >= 0 && cardno < self->size()) {
  80 + return (*self)[cardno];
  81 + }
  82 + else {
  83 + throw GException::out_of_range("__getitem__(int)",
  84 + "Header card number",
  85 + cardno, self->size());
  86 + }
  87 + }
  88 + GFitsHeaderCard& __getitem__(const std::string& keyname) {
  89 + return (*self)[keyname];
  90 + }
  91 + void __setitem__(const int& cardno, const GFitsHeaderCard& card) {
  92 + if (cardno >= 0 && cardno < self->size()) {
  93 + (*self)[cardno] = card;
  94 + return;
  95 + }
  96 + else {
  97 + throw GException::out_of_range("__setitem__(int)",
  98 + "Header card number",
  99 + cardno, self->size());
  100 + }
  101 + }
  102 + void __setitem__(const std::string& keyname, const GFitsHeaderCard& card) {
  103 + (*self)[keyname] = card;
  104 + return;
  105 + }
78 106 GFitsHeader copy() {
79 107 return (*self);
80 108 }
... ...
src/fits/GFitsHDU.cpp
... ... @@ -164,7 +164,7 @@ void GFitsHDU::extname(const std::string&amp; extname)
164 164 //if (m_header == NULL) m_header = new GFitsHeader();
165 165  
166 166 // Update header
167   - m_header.update(GFitsHeaderCard("EXTNAME", extname,
  167 + m_header.append(GFitsHeaderCard("EXTNAME", extname,
168 168 "name of this extension"));
169 169  
170 170 // Return
... ... @@ -180,7 +180,7 @@ void GFitsHDU::extname(const std::string&amp; extname)
180 180 GFitsHeaderCard* GFitsHDU::card(const std::string& keyname)
181 181 {
182 182 // Return pointer
183   - return m_header.card(keyname);
  183 + return &(m_header.at(keyname));
184 184 }
185 185  
186 186  
... ... @@ -192,7 +192,7 @@ GFitsHeaderCard* GFitsHDU::card(const std::string&amp; keyname)
192 192 GFitsHeaderCard* GFitsHDU::card(const int& cardno)
193 193 {
194 194 // Return pointer
195   - return m_header.card(cardno);
  195 + return &(m_header.at(cardno));
196 196 }
197 197  
198 198  
... ... @@ -203,11 +203,8 @@ GFitsHeaderCard* GFitsHDU::card(const int&amp; cardno)
203 203 ***************************************************************************/
204 204 std::string GFitsHDU::string(const std::string& keyname) const
205 205 {
206   - // Get pointer on card
207   - GFitsHeaderCard* card = const_cast<GFitsHDU*>(this)->card(keyname);
208   -
209 206 // Return card value
210   - return (card->string());
  207 + return (m_header.at(keyname).string());
211 208 }
212 209  
213 210  
... ... @@ -218,11 +215,8 @@ std::string GFitsHDU::string(const std::string&amp; keyname) const
218 215 ***************************************************************************/
219 216 double GFitsHDU::real(const std::string& keyname) const
220 217 {
221   - // Get pointer on card
222   - GFitsHeaderCard* card = const_cast<GFitsHDU*>(this)->card(keyname);
223   -
224 218 // Return card value
225   - return (card->real());
  219 + return (m_header.at(keyname).real());
226 220 }
227 221  
228 222  
... ... @@ -233,11 +227,8 @@ double GFitsHDU::real(const std::string&amp; keyname) const
233 227 ***************************************************************************/
234 228 int GFitsHDU::integer(const std::string& keyname) const
235 229 {
236   - // Get pointer on card
237   - GFitsHeaderCard* card = const_cast<GFitsHDU*>(this)->card(keyname);
238   -
239 230 // Return card value
240   - return (card->integer());
  231 + return (m_header.at(keyname).integer());
241 232 }
242 233  
243 234  
... ... @@ -252,7 +243,7 @@ void GFitsHDU::card(const std::string&amp; keyname, const std::string&amp; value,
252 243 const std::string& comment)
253 244 {
254 245 // Update card
255   - m_header.update(GFitsHeaderCard(keyname, value, comment));
  246 + m_header.append(GFitsHeaderCard(keyname, value, comment));
256 247  
257 248 // Return
258 249 return;
... ... @@ -270,7 +261,7 @@ void GFitsHDU::card(const std::string&amp; keyname, const double&amp; value,
270 261 const std::string& comment)
271 262 {
272 263 // Update card
273   - m_header.update(GFitsHeaderCard(keyname, value, comment));
  264 + m_header.append(GFitsHeaderCard(keyname, value, comment));
274 265  
275 266 // Return
276 267 return;
... ... @@ -288,7 +279,7 @@ void GFitsHDU::card(const std::string&amp; keyname, const int&amp; value,
288 279 const std::string& comment)
289 280 {
290 281 // Update card
291   - m_header.update(GFitsHeaderCard(keyname, value, comment));
  282 + m_header.append(GFitsHeaderCard(keyname, value, comment));
292 283  
293 284 // Return
294 285 return;
... ... @@ -303,7 +294,7 @@ void GFitsHDU::card(const std::string&amp; keyname, const int&amp; value,
303 294 bool GFitsHDU::hascard(const std::string& keyname) const
304 295 {
305 296 // Return presence
306   - return (m_header.hascard(keyname));
  297 + return (m_header.contains(keyname));
307 298 }
308 299  
309 300  
... ... @@ -315,7 +306,7 @@ bool GFitsHDU::hascard(const std::string&amp; keyname) const
315 306 bool GFitsHDU::hascard(const int& cardno) const
316 307 {
317 308 // Return presence
318   - return m_header.hascard(cardno);
  309 + return m_header.contains(cardno);
319 310 }
320 311  
321 312  
... ... @@ -453,25 +444,27 @@ void GFitsHDU::open(void* vptr, int hdunum)
453 444 FPTR_COPY(m_fitsfile, vptr);
454 445 m_hdunum = hdunum;
455 446  
456   - // Open HDU header
457   - m_header.open(FPTR(m_fitsfile));
  447 + // Load HDU header
  448 + m_header.load(FPTR(m_fitsfile));
458 449  
459 450 // Open HDU data area
460 451 data_open(FPTR(m_fitsfile));
461 452  
462 453 // Get HDU name from header. If no name was found and this is the primary
463   - // HDU then set the name to "PRIMARY", otherwise to "NoName".
464   - try {
  454 + // HDU then set the name to "Primary", otherwise to "NoName".
  455 + if (m_header.contains("EXTNAME")) {
465 456 m_name = gammalib::strip_whitespace(m_header.string("EXTNAME"));
466 457 }
467   - catch (GException::fits_key_not_found &e) {
  458 + else {
468 459 m_name.clear();
469 460 }
470 461 if (m_name.length() == 0) {
471   - if (hdunum == 0)
  462 + if (hdunum == 0) {
472 463 m_name = "Primary";
473   - else
  464 + }
  465 + else {
474 466 m_name = "NoName";
  467 + }
475 468 }
476 469  
477 470 // Return
... ...
src/fits/GFitsHeader.cpp
1 1 /***************************************************************************
2   - * GFitsHeader.cpp - FITS header handling class *
  2 + * GFitsHeader.hpp - FITS header cards container class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2008-2013 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -20,7 +20,7 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file GFitsHeader.cpp
23   - * @brief FITS header class implementation
  23 + * @brief FITS header cards container class implementation
24 24 * @author Juergen Knoedlseder
25 25 */
26 26  
... ... @@ -34,8 +34,18 @@
34 34 #include "GTools.hpp"
35 35  
36 36 /* __ Method name definitions ____________________________________________ */
37   -#define G_CARD1 "GFitsHeader::card(std::string&)"
38   -#define G_CARD2 "GFitsHeader::card(int&)"
  37 +#define G_AT1 "GFitsHeaderCard& GFitsHeader::at(int&)"
  38 +#define G_AT2 "GFitsHeaderCard& GFitsHeader::at(std::string&)"
  39 +#define G_STRING1 "GFitsHeader::string(int&)"
  40 +#define G_STRING2 "GFitsHeader::string(std::string&)"
  41 +#define G_REAL1 "GFitsHeader::real(int&)"
  42 +#define G_REAL2 "GFitsHeader::real(std::string&)"
  43 +#define G_INTEGER1 "GFitsHeader::integer(int&)"
  44 +#define G_INTEGER2 "GFitsHeader::integer(std::string&)"
  45 +#define G_INSERT1 "GFitsHeader::insert(int&, GFitsHeaderCard&)"
  46 +#define G_INSERT2 "GFitsHeader::insert(std::string&, GFitsHeaderCard&)"
  47 +#define G_REMOVE1 "GFitsHeader::remove(int&)"
  48 +#define G_REMOVE2 "GFitsHeader::remove(std::string&)"
39 49 #define G_OPEN "GFitsHeader::open(void*)"
40 50 #define G_SAVE "GFitsHeader::save(void*)"
41 51  
... ... @@ -69,7 +79,7 @@ GFitsHeader::GFitsHeader(void)
69 79 /***********************************************************************//**
70 80 * @brief Copy constructor
71 81 *
72   - * @param header Header from which GFitsHeader instance should be built
  82 + * @param header FITS header.
73 83 ***************************************************************************/
74 84 GFitsHeader::GFitsHeader(const GFitsHeader& header)
75 85 {
... ... @@ -106,9 +116,10 @@ GFitsHeader::~GFitsHeader(void)
106 116 /***********************************************************************//**
107 117 * @brief Assignment operator
108 118 *
109   - * @param header Header which should be assigned to GFitsHeader instance
  119 + * @param header FITS header.
  120 + * @return FITS header.
110 121 ***************************************************************************/
111   -GFitsHeader& GFitsHeader::operator= (const GFitsHeader& header)
  122 +GFitsHeader& GFitsHeader::operator=(const GFitsHeader& header)
112 123 {
113 124 // Execute only if object is not identical
114 125 if (this != &header) {
... ... @@ -136,9 +147,7 @@ GFitsHeader&amp; GFitsHeader::operator= (const GFitsHeader&amp; header)
136 147 ==========================================================================*/
137 148  
138 149 /***********************************************************************//**
139   - * @brief Clear object
140   - *
141   - * Sets the FITS header in an initial proper state.
  150 + * @brief Clear header
142 151 ***************************************************************************/
143 152 void GFitsHeader::clear(void)
144 153 {
... ... @@ -154,7 +163,9 @@ void GFitsHeader::clear(void)
154 163  
155 164  
156 165 /***********************************************************************//**
157   - * @brief Clone header object
  166 + * @brief Clone header
  167 + *
  168 + * @return Pointer to deep copy of header.
158 169 ***************************************************************************/
159 170 GFitsHeader* GFitsHeader::clone(void) const
160 171 {
... ... @@ -163,370 +174,524 @@ GFitsHeader* GFitsHeader::clone(void) const
163 174  
164 175  
165 176 /***********************************************************************//**
166   - * @brief Returns number of header cards
  177 + * @brief Return header card
  178 + *
  179 + * @param[in] cardno Number of card in header [0,...,size()-1]
  180 + * @return Header card.
  181 + *
  182 + * @exception GException::out_of_range
  183 + * Card number out of range.
167 184 ***************************************************************************/
168   -int GFitsHeader::size(void) const
  185 +GFitsHeaderCard& GFitsHeader::at(const int& cardno)
169 186 {
170   - // Return number of header cards
171   - return m_num_cards;
  187 + // Compile option: raise an exception if cardno is out of range
  188 + #if defined(G_RANGE_CHECK)
  189 + if (!contains(cardno)) {
  190 + throw GException::out_of_range(G_AT1, "Header card number", cardno, size());
  191 + }
  192 + #endif
  193 +
  194 + // Return card
  195 + return (m_cards[cardno]);
172 196 }
173 197  
174 198  
175 199 /***********************************************************************//**
176   - * @brief Open Header
177   - *
178   - * @param[in] vptr FITS file void pointer.
  200 + * @brief Return header card (const version)
179 201 *
180   - * @exception GException::fits_error
181   - * FITS error occured.
  202 + * @param[in] cardno Number of card in header [0,...,size()-1]
  203 + * @return Header card.
182 204 *
183   - * Loads all header cards into memory. Any header cards that existed before
184   - * will be dropped.
  205 + * @exception GException::out_of_range
  206 + * Card number out of range.
185 207 ***************************************************************************/
186   -void GFitsHeader::open(void* vptr)
  208 +const GFitsHeaderCard& GFitsHeader::at(const int& cardno) const
187 209 {
188   - // Move to HDU
189   - int status = 0;
190   - status = __ffmahd(FPTR(vptr), (FPTR(vptr)->HDUposition)+1, NULL, &status);
191   - if (status != 0)
192   - throw GException::fits_error(G_OPEN, status);
  210 + // Compile option: raise an exception if cardno is out of range
  211 + #if defined(G_RANGE_CHECK)
  212 + if (!contains(cardno)) {
  213 + throw GException::out_of_range(G_AT1, "Header card number", cardno, size());
  214 + }
  215 + #endif
193 216  
194   - // Determine number of cards in header
195   - status = __ffghsp(FPTR(vptr), &m_num_cards, NULL, &status);
196   - if (status != 0)
197   - throw GException::fits_error(G_OPEN, status);
  217 + // Return card
  218 + return (m_cards[cardno]);
  219 +}
198 220  
199   - // Drop any old cards
200   - if (m_card != NULL) delete [] m_card;
201 221  
202   - // Allocate memory for new cards
203   - m_card = new GFitsHeaderCard[m_num_cards];
  222 +/***********************************************************************//**
  223 + * @brief Return header card
  224 + *
  225 + * @param[in] keyname Name of header card
  226 + * @return Header card.
  227 + *
  228 + * @exception GException::invalid_argument
  229 + * Key name not found.
  230 + ***************************************************************************/
  231 +GFitsHeaderCard& GFitsHeader::at(const std::string& keyname)
  232 +{
  233 + // Get card number
  234 + int cardno = get_index(keyname);
204 235  
205   - // Read all cards
206   - for (int i = 0; i < m_num_cards; ++i)
207   - m_card[i].read(FPTR(vptr), i+1);
  236 + // Throw an exception if keyname is not found
  237 + if (cardno == -1) {
  238 + std::string msg = "Keyword \""+keyname+"\" not found in FITS header.";
  239 + throw GException::invalid_argument(G_AT2, msg);
  240 + }
208 241  
209   - // Return
210   - return;
  242 + // Return card
  243 + return (m_cards[cardno]);
211 244 }
212 245  
213 246  
214 247 /***********************************************************************//**
215   - * @brief Save Header to FITS file
216   - *
217   - * @param[in] vptr FITS file void pointer.
  248 + * @brief Return header card (const version)
218 249 *
219   - * @exception GException::fits_error
220   - * FITS error occured.
  250 + * @param[in] keyname Name of header card
  251 + * @return Header card.
221 252 *
222   - * Saves all header cards into HDU. This method does not write the following
223   - * mandatory keywords to the HDU (those will be written by methods handling
224   - * the data of the HDU):
225   - * 'SIMPLE'
226   - * 'BITPIX'
227   - * 'NAXIS', 'NAXIS1', 'NAXIS2', etc.
228   - * 'EXTEND'
229   - * 'PCOUNT'
230   - * 'GCOUNT'
  253 + * @exception GException::invalid_argument
  254 + * Key name not found.
231 255 ***************************************************************************/
232   -void GFitsHeader::save(void* vptr)
  256 +const GFitsHeaderCard& GFitsHeader::at(const std::string& keyname) const
233 257 {
234   - // Move to HDU
235   - int status = 0;
236   - status = __ffmahd(FPTR(vptr), (FPTR(vptr)->HDUposition)+1, NULL, &status);
237   - if (status != 0)
238   - throw GException::fits_error(G_SAVE, status);
  258 + // Get card number
  259 + int cardno = get_index(keyname);
239 260  
240   - // Save all cards
241   - for (int i = 0; i < m_num_cards; ++i) {
242   - if (m_card[i].keyname() != "SIMPLE" &&
243   - m_card[i].keyname() != "XTENSION" &&
244   - m_card[i].keyname() != "BITPIX" &&
245   - m_card[i].keyname() != "EXTEND" &&
246   - m_card[i].keyname() != "PCOUNT" &&
247   - m_card[i].keyname() != "GCOUNT" &&
248   - m_card[i].keyname().find("NAXIS") == std::string::npos) {
249   - m_card[i].write(FPTR(vptr));
250   - }
  261 + // Throw an exception if keyname is not found
  262 + if (cardno == -1) {
  263 + std::string msg = "Keyword \""+keyname+"\" not found in FITS header.";
  264 + throw GException::invalid_argument(G_AT2, msg);
251 265 }
252 266  
253   - // Return
254   - return;
  267 + // Return card
  268 + return (m_cards[cardno]);
255 269 }
256 270  
257 271  
258 272 /***********************************************************************//**
259   - * @brief Close Header
  273 + * @brief Return header card value as string value
  274 + *
  275 + * @param[in] cardno Header card number [0,...,size()-1].
  276 + * @return Header card string value.
260 277 *
261   - * Drops all header cards. Note that closing does not save the cards to the
262   - * FITS file. Use the save method in case that cards should be save to the
263   - * FITS file.
  278 + * @exception GException::out_of_range
  279 + * Card number out of range.
264 280 ***************************************************************************/
265   -void GFitsHeader::close(void)
  281 +std::string GFitsHeader::string(const int& cardno) const
266 282 {
267   - // Free members
268   - free_members();
269   -
270   - // Initialise members
271   - init_members();
  283 + // Compile option: raise an exception if cardno is out of range
  284 + #if defined(G_RANGE_CHECK)
  285 + if (!contains(cardno)) {
  286 + throw GException::out_of_range(G_STRING1, "Header card number", cardno, size());
  287 + }
  288 + #endif
272 289  
273   - // Return
274   - return;
  290 + // Return card value
  291 + return (m_cards[cardno].string());
275 292 }
276 293  
277 294  
278 295 /***********************************************************************//**
279   - * @brief Check if card is present in header
  296 + * @brief Return header card value as string value
280 297 *
281   - * @param[in] keyname Name of header card.
  298 + * @param[in] keyname Header card key name.
  299 + * @return Header card string value.
282 300 *
283   - * Returns true if header card is present, false otherwise.
  301 + * @exception GException::invalid_argument
  302 + * Key name not found.
284 303 ***************************************************************************/
285   -bool GFitsHeader::hascard(const std::string& keyname) const
  304 +std::string GFitsHeader::string(const std::string& keyname) const
286 305 {
287   - // Check for presence
288   - bool present = (card_ptr(keyname) != NULL);
  306 + // Get card number
  307 + int cardno = get_index(keyname);
  308 +
  309 + // Throw an exception if keyname is not found
  310 + if (cardno == -1) {
  311 + std::string msg = "Keyword \""+keyname+"\" not found in FITS header.";
  312 + throw GException::invalid_argument(G_STRING2, msg);
  313 + }
289 314  
290   - // Return presence
291   - return present;
  315 + // Return card value
  316 + return (m_cards[cardno].string());
292 317 }
293 318  
294 319  
295 320 /***********************************************************************//**
296   - * @brief Check if card is present in header
  321 + * @brief Return header card value as double precision value
297 322 *
298   - * @param[in] cardno Number of card in header
  323 + * @param[in] cardno Header card number [0,...,size()-1].
  324 + * @return Header card double precision value.
299 325 *
300   - * Returns true if header card is present, false otherwise.
  326 + * @exception GException::out_of_range
  327 + * Card number out of range.
301 328 ***************************************************************************/
302   -bool GFitsHeader::hascard(const int& cardno) const
  329 +double GFitsHeader::real(const int& cardno) const
303 330 {
304   - // Check for presence
305   - bool present = (cardno >= 0 && cardno < m_num_cards);
  331 + // Compile option: raise an exception if cardno is out of range
  332 + #if defined(G_RANGE_CHECK)
  333 + if (!contains(cardno)) {
  334 + throw GException::out_of_range(G_REAL1, "Header card number", cardno, size());
  335 + }
  336 + #endif
306 337  
307   - // Return presence
308   - return present;
  338 + // Return card value
  339 + return (m_cards[cardno].real());
309 340 }
310 341  
311 342  
312 343 /***********************************************************************//**
313   - * @brief Update card in header or append card to header
  344 + * @brief Return header card value as double precision value
314 345 *
315   - * @param card FITS header card that should be updated
  346 + * @param[in] keyname Header card key name.
  347 + * @return Header card double precision value.
316 348 *
317   - * This method updates one header card. Updating means replacing any
318   - * existing card with the specified one or appending a new card to the
319   - * list of existing cards.
  349 + * @exception GException::invalid_argument
  350 + * Key name not found.
320 351 ***************************************************************************/
321   -void GFitsHeader::update(const GFitsHeaderCard& card)
  352 +double GFitsHeader::real(const std::string& keyname) const
322 353 {
323   - // If card keyname is not COMMENT or HISTORY, then check first if
324   - // card exists. If yes then update existing card
325   - if (card.keyname() != "COMMENT" && card.keyname() != "HISTORY") {
326   - try {
327   - GFitsHeaderCard* ptr = this->card(card.keyname());
328   - *ptr = card;
329   - return;
330   - }
331   - catch (GException::fits_key_not_found &e) {
332   - ;
333   - }
  354 + // Get card number
  355 + int cardno = get_index(keyname);
  356 +
  357 + // Throw an exception if keyname is not found
  358 + if (cardno == -1) {
  359 + std::string msg = "Keyword \""+keyname+"\" not found in FITS header.";
  360 + throw GException::invalid_argument(G_REAL2, msg);
334 361 }
335 362  
336   - // Create memory to hold cards
337   - GFitsHeaderCard* tmp = new GFitsHeaderCard[m_num_cards+1];
338   - if (tmp != NULL) {
  363 + // Return card value
  364 + return (m_cards[cardno].real());
  365 +}
339 366  
340   - // Copy over existing cards and remove old ones
341   - if (m_card != NULL) {
342   - for (int i = 0; i < m_num_cards; ++i)
343   - tmp[i] = m_card[i];
344   - delete [] m_card;
345   - }
346 367  
347   - // Connect the new memory to the card pointer
348   - m_card = tmp;
  368 +/***********************************************************************//**
  369 + * @brief Return header card value as integer value
  370 + *
  371 + * @param[in] cardno Header card number [0,...,size()-1].
  372 + * @return Header card integer value.
  373 + *
  374 + * @exception GException::out_of_range
  375 + * Card number out of range.
  376 + ***************************************************************************/
  377 +int GFitsHeader::integer(const int& cardno) const
  378 +{
  379 + // Compile option: raise an exception if cardno is out of range
  380 + #if defined(G_RANGE_CHECK)
  381 + if (!contains(cardno)) {
  382 + throw GException::out_of_range(G_INTEGER1, "Header card number", cardno, size());
  383 + }
  384 + #endif
  385 +
  386 + // Return card value
  387 + return (m_cards[cardno].integer());
  388 +}
349 389  
350   - // Append new card to list
351   - m_card[m_num_cards] = card;
352 390  
353   - // Increment number of cards
354   - m_num_cards++;
  391 +/***********************************************************************//**
  392 + * @brief Return header card value as integer value
  393 + *
  394 + * @param[in] keyname Header card key name.
  395 + * @return Header card integer value.
  396 + *
  397 + * @exception GException::invalid_argument
  398 + * Key name not found.
  399 + ***************************************************************************/
  400 +int GFitsHeader::integer(const std::string& keyname) const
  401 +{
  402 + // Get card number
  403 + int cardno = get_index(keyname);
355 404  
356   - } // endif: new memory was valid
  405 + // Throw an exception if keyname is not found
  406 + if (cardno == -1) {
  407 + std::string msg = "Keyword \""+keyname+"\" not found in FITS header.";
  408 + throw GException::invalid_argument(G_INTEGER2, msg);
  409 + }
357 410  
358   - // Return
359   - return;
  411 + // Return card value
  412 + return (m_cards[cardno].integer());
360 413 }
361 414  
362 415  
363 416 /***********************************************************************//**
364   - * @brief Return pointer of header card
  417 + * @brief Append or update header card
365 418 *
366   - * @param[in] keyname Name of header card
  419 + * @param[in] card Header card.
  420 + * @return Reference to appended header card.
367 421 *
368   - * @exception GException::fits_key_not_found
369   - * Requested card was not found in header.
370   - *
371   - * Returns a pointer on the header card.
  422 + * If the keyname of the header @p card does not yet exist in the header
  423 + * (or if the keyname is COMMENT or HISTORY) then append the header card
  424 + * to the header. If the keyname exists already, the header card is updated.
372 425 ***************************************************************************/
373   -GFitsHeaderCard* GFitsHeader::card(const std::string& keyname)
  426 +GFitsHeaderCard& GFitsHeader::append(const GFitsHeaderCard& card)
374 427 {
375   - // Get header card pointer
376   - GFitsHeaderCard* ptr = card_ptr(keyname);
  428 + // If card keyname is not COMMENT or HISTORY, then check first if
  429 + // card exists. If yes then update existing card
  430 + int cardno = -1;
  431 + if (card.keyname() != "COMMENT" && card.keyname() != "HISTORY") {
  432 + cardno = get_index(card.keyname());
  433 + if (cardno != -1) {
  434 + m_cards[cardno] = card;
  435 + }
  436 + }
377 437  
378   - // If no card was found then throw an error
379   - if (ptr == NULL) {
380   - throw GException::fits_key_not_found(G_CARD1, keyname);
  438 + // If card has not yet been updated then append card to header
  439 + if (cardno == -1) {
  440 + m_cards.push_back(card);
  441 + cardno = size()-1;
381 442 }
382   -
383   - // Return card pointer
384   - return ptr;
  443 +
  444 + // Return reference
  445 + return (m_cards[cardno]);
385 446 }
386 447  
387 448  
388 449 /***********************************************************************//**
389   - * @brief Return pointer of header card
  450 + * @brief Insert card into header
390 451 *
391   - * @param[in] cardno Number of card in header
  452 + * @param[in] cardno Header card number [0,...,size()-1].
  453 + * @param[in] card Header card.
  454 + * @return Reference to inserted header card.
392 455 *
393 456 * @exception GException::out_of_range
394   - * Requested card was not found in header.
  457 + * Card number out of range.
395 458 *
396   - * Returns a pointer on the header card.
  459 + * Inserts a @p card into the header before the card with the specified card
  460 + * number @p cardno.
397 461 ***************************************************************************/
398   -GFitsHeaderCard* GFitsHeader::card(const int& cardno)
  462 +GFitsHeaderCard& GFitsHeader::insert(const int& cardno,
  463 + const GFitsHeaderCard& card)
399 464 {
400   - // If card number is out of range then throw an exception
401   - if (cardno < 0 || cardno >= m_num_cards) {
402   - throw GException::out_of_range(G_CARD2, cardno, 0, m_num_cards-1);
  465 + // Compile option: raise exception if index is out of range
  466 + #if defined(G_RANGE_CHECK)
  467 + if (isempty()) {
  468 + if (cardno > 0) {
  469 + throw GException::out_of_range(G_INSERT1, "Header card number",
  470 + cardno, size());
  471 + }
403 472 }
  473 + else {
  474 + if (cardno < 0 || cardno >= size()) {
  475 + throw GException::out_of_range(G_INSERT1, "Header card number",
  476 + cardno, size());
  477 + }
  478 + }
  479 + #endif
404 480  
405   - // Get card pointer
406   - GFitsHeaderCard* ptr = &(m_card[cardno]);
407   -
408   - // Return pointer
409   - return ptr;
  481 + // Inserts card
  482 + m_cards.insert(m_cards.begin()+cardno, card);
  483 +
  484 + // Return reference
  485 + return m_cards[cardno];
410 486 }
411 487  
412 488  
413 489 /***********************************************************************//**
414   - * @brief Get specified header card value as string
  490 + * @brief Insert card into header
  491 + *
  492 + * @param[in] keyname Header card key name.
  493 + * @param[in] card Header card.
  494 + * @return Reference to inserted header card.
415 495 *
416   - * @param[in] keyname Name of header card.
  496 + * @exception GException::invalid_argument
  497 + * Key name not found.
417 498 *
418   - * If the header card is not found an empty string is returned.
  499 + * Inserts a @p card into the header before the card with the specified
  500 + * @p keyname.
419 501 ***************************************************************************/
420   -std::string GFitsHeader::string(const std::string& keyname)
  502 +GFitsHeaderCard& GFitsHeader::insert(const std::string& keyname,
  503 + const GFitsHeaderCard& card)
421 504 {
422   - // Get card pointer
423   - GFitsHeaderCard* ptr = GFitsHeader::card(keyname);
  505 + // Get card number
  506 + int cardno = get_index(keyname);
424 507  
425   - // Get string value
426   - std::string value = (ptr != NULL) ? ptr->string() : "";
  508 + // Throw an exception if keyname is not found
  509 + if (cardno == -1) {
  510 + std::string msg = "Keyword \""+keyname+"\" not found in FITS header.";
  511 + throw GException::invalid_argument(G_INSERT2, msg);
  512 + }
427 513  
428   - // Return string
429   - return value;
  514 + // Inserts card
  515 + m_cards.insert(m_cards.begin()+cardno, card);
  516 +
  517 + // Return reference
  518 + return m_cards[cardno];
430 519 }
431 520  
432 521  
433 522 /***********************************************************************//**
434   - * @brief Get specified header card value as string
  523 + * @brief Remove card from header
435 524 *
436   - * @param[in] cardno Header card number (starting from 0).
  525 + * @param[in] cardno Header card number [0,...,size()-1].
437 526 *
438   - * If the header card number does not exist an empty string is returned.
  527 + * @exception GException::out_of_range
  528 + * Card number out of range.
  529 + *
  530 + * Remove header card of specified card number from container.
439 531 ***************************************************************************/
440   -std::string GFitsHeader::string(const int& cardno)
  532 +void GFitsHeader::remove(const int& cardno)
441 533 {
442   - // Get card pointer
443   - GFitsHeaderCard* ptr = GFitsHeader::card(cardno);
444   -
445   - // Get string value
446   - std::string value = (ptr != NULL) ? ptr->string() : "";
  534 + // Compile option: raise an exception if cardno is out of range
  535 + #if defined(G_RANGE_CHECK)
  536 + if (!contains(cardno)) {
  537 + throw GException::out_of_range(G_REMOVE1, "Header card number", cardno, size());
  538 + }
  539 + #endif
447 540  
448   - // Return string
449   - return value;
  541 + // Erase card from header
  542 + m_cards.erase(m_cards.begin() + cardno);
  543 +
  544 + // Return
  545 + return;
450 546 }
451 547  
452 548  
453 549 /***********************************************************************//**
454   - * @brief Get specified header card value as double precision value
  550 + * @brief Remove card from header
  551 + *
  552 + * @param[in] keyname Header card key name.
455 553 *
456   - * @param[in] keyname Name of header card.
  554 + * @exception GException::invalid_argument
  555 + * Key name not found.
457 556 *
458   - * If the header card is not found 0 is returned.
  557 + * Remove card with specified @p keyname from header.
459 558 ***************************************************************************/
460   -double GFitsHeader::real(const std::string& keyname)
  559 +void GFitsHeader::remove(const std::string& keyname)
461 560 {
462   - // Get card pointer
463   - GFitsHeaderCard* ptr = GFitsHeader::card(keyname);
  561 + // Get card number
  562 + int cardno = get_index(keyname);
464 563  
465   - // Get string value
466   - double value = (ptr != NULL) ? ptr->real() : 0.0;
  564 + // Throw an exception if keyname is not found
  565 + if (cardno == -1) {
  566 + std::string msg = "Keyword \""+keyname+"\" not found in FITS header.";
  567 + throw GException::invalid_argument(G_REMOVE2, msg);
  568 + }
467 569  
468   - // Return double
469   - return value;
  570 + // Erase card from header
  571 + m_cards.erase(m_cards.begin() + cardno);
  572 +
  573 + // Return
  574 + return;
470 575 }
471 576  
472 577  
473 578 /***********************************************************************//**
474   - * @brief Get specified header card value as double precision value
  579 + * @brief Append header
475 580 *
476   - * @param[in] cardno Header card number (starting from 0).
  581 + * @param[in] header FITS header.
477 582 *
478   - * If the header card number does not exist 0 is returned.
  583 + * Append all cards from a FITS header to the actual header.
479 584 ***************************************************************************/
480   -double GFitsHeader::real(const int& cardno)
  585 +void GFitsHeader::extend(const GFitsHeader& header)
481 586 {
482   - // Get card pointer
483   - GFitsHeaderCard* ptr = GFitsHeader::card(cardno);
  587 + // Do nothing if header is empty
  588 + if (!header.isempty()) {
  589 +
  590 + // Get size. Note that we extract the size first to avoid an
  591 + // endless loop that arises when a container is appended to
  592 + // itself.
  593 + int num = header.size();
  594 +
  595 + // Reserve enough space
  596 + reserve(size() + num);
484 597  
485   - // Get string value
486   - double value = (ptr != NULL) ? ptr->real() : 0.0;
  598 + // Loop over all card and append them to the header
  599 + for (int i = 0; i < num; ++i) {
  600 + m_cards.push_back(header[i]);
  601 + }
487 602  
488   - // Return double
489   - return value;
  603 + } // endif: header was not empty
  604 +
  605 + // Return
  606 + return;
490 607 }
491 608  
492 609  
493 610 /***********************************************************************//**
494   - * @brief Get specified header card value as integer value
  611 + * @brief Load header from FITS file
  612 + *
  613 + * @param[in] vptr FITS file void pointer.
495 614 *
496   - * @param keyname Name of header card.
  615 + * @exception GException::fits_error
  616 + * FITS error occured.
497 617 *
498   - * If the header card is not found 0 is returned.
  618 + * Loads all header cards into memory. Any header cards that existed before
  619 + * will be dropped.
499 620 ***************************************************************************/
500   -int GFitsHeader::integer(const std::string& keyname)
  621 +void GFitsHeader::load(void* vptr)
501 622 {
502   - // Get card pointer
503   - GFitsHeaderCard* ptr = GFitsHeader::card(keyname);
  623 + // Move to HDU
  624 + int status = 0;
  625 + status = __ffmahd(FPTR(vptr), (FPTR(vptr)->HDUposition)+1, NULL, &status);
  626 + if (status != 0) {
  627 + throw GException::fits_error(G_OPEN, status);
  628 + }
  629 +
  630 + // Determine number of cards in header
  631 + int num_cards = 0;
  632 + status = __ffghsp(FPTR(vptr), &num_cards, NULL, &status);
  633 + if (status != 0) {
  634 + throw GException::fits_error(G_OPEN, status);
  635 + }
504 636  
505   - // Get string value
506   - int value = (ptr != NULL) ? ptr->integer() : 0;
  637 + // Drop any old cards and reserve space for new cards
  638 + m_cards.clear();
  639 + reserve(num_cards);
507 640  
508   - // Return double
509   - return value;
  641 + // Read all cards
  642 + for (int i = 0; i < num_cards; ++i) {
  643 + GFitsHeaderCard card;
  644 + card.read(FPTR(vptr), i+1);
  645 + m_cards.push_back(card);
  646 + }
  647 +
  648 + // Return
  649 + return;
510 650 }
511 651  
512 652  
513 653 /***********************************************************************//**
514   - * @brief Get specified header card value as integer value
  654 + * @brief Save header to FITS file
515 655 *
516   - * @param[in] cardno Header card number (starting from 0).
  656 + * @param[in] vptr FITS file void pointer.
517 657 *
518   - * If the header card number does not exist 0 is returned.
  658 + * @exception GException::fits_error
  659 + * FITS error occured.
  660 + *
  661 + * Saves all header cards into HDU. This method does not write the following
  662 + * mandatory keywords to the HDU (those will be written by methods handling
  663 + * the data of the HDU):
  664 + * 'SIMPLE'
  665 + * 'BITPIX'
  666 + * 'NAXIS', 'NAXIS1', 'NAXIS2', etc.
  667 + * 'EXTEND'
  668 + * 'PCOUNT'
  669 + * 'GCOUNT'
519 670 ***************************************************************************/
520   -int GFitsHeader::integer(const int& cardno)
  671 +void GFitsHeader::save(void* vptr) const
521 672 {
522   - // Get card pointer
523   - GFitsHeaderCard* ptr = GFitsHeader::card(cardno);
  673 + // Move to HDU
  674 + int status = 0;
  675 + status = __ffmahd(FPTR(vptr), (FPTR(vptr)->HDUposition)+1, NULL, &status);
  676 + if (status != 0) {
  677 + throw GException::fits_error(G_SAVE, status);
  678 + }
524 679  
525   - // Get string value
526   - int value = (ptr != NULL) ? ptr->integer() : 0;
  680 + // Save all cards
  681 + for (int i = 0; i < size(); ++i) {
  682 + if (m_cards[i].keyname() != "SIMPLE" &&
  683 + m_cards[i].keyname() != "XTENSION" &&
  684 + m_cards[i].keyname() != "BITPIX" &&
  685 + m_cards[i].keyname() != "EXTEND" &&
  686 + m_cards[i].keyname() != "PCOUNT" &&
  687 + m_cards[i].keyname() != "GCOUNT" &&
  688 + m_cards[i].keyname().find("NAXIS") == std::string::npos) {
  689 + m_cards[i].write(FPTR(vptr));
  690 + }
  691 + }
527 692  
528   - // Return double
529   - return value;
  693 + // Return
  694 + return;
530 695 }
531 696  
532 697  
... ... @@ -545,13 +710,12 @@ std::string GFitsHeader::print(const GChatter&amp; chatter) const
545 710 if (chatter != SILENT) {
546 711  
547 712 // Append header
548   - result.append("=== GFitsHeader ("+gammalib::str(m_num_cards)+" cards) ===");
  713 + result.append("=== GFitsHeader ("+gammalib::str(size())+" cards) ===");
549 714  
550 715 // NORMAL: Append cards
551 716 if (chatter >= NORMAL) {
552   - for (int i = 0; i < m_num_cards; ++i) {
553   - result.append("\n");
554   - result.append(m_card[i].print());
  717 + for (int i = 0; i < size(); ++i) {
  718 + result.append("\n"+m_cards[i].print());
555 719 }
556 720 }
557 721  
... ... @@ -574,8 +738,7 @@ std::string GFitsHeader::print(const GChatter&amp; chatter) const
574 738 void GFitsHeader::init_members(void)
575 739 {
576 740 // Initialise members
577   - m_num_cards = 0;
578   - m_card = NULL;
  741 + m_cards.clear();
579 742  
580 743 // Return
581 744 return;
... ... @@ -585,19 +748,12 @@ void GFitsHeader::init_members(void)
585 748 /***********************************************************************//**
586 749 * @brief Copy class members
587 750 *
588   - * @param[in] header Header which should be copied
  751 + * @param[in] header FITS header.
589 752 ***************************************************************************/
590 753 void GFitsHeader::copy_members(const GFitsHeader& header)
591 754 {
592   - // Copy attributes
593   - m_num_cards = header.m_num_cards;
594   -
595   - // Copy cards
596   - if (header.m_card != NULL && m_num_cards > 0) {
597   - m_card = new GFitsHeaderCard[m_num_cards];
598   - for (int i = 0; i < m_num_cards; ++i)
599   - m_card[i] = header.m_card[i];
600   - }
  755 + // Copy members
  756 + m_cards = header.m_cards;
601 757  
602 758 // Return
603 759 return;
... ... @@ -609,39 +765,33 @@ void GFitsHeader::copy_members(const GFitsHeader&amp; header)
609 765 ***************************************************************************/
610 766 void GFitsHeader::free_members(void)
611 767 {
612   - // Free memory
613   - if (m_card != NULL) delete [] m_card;
614   -
615   - // Properly mark as free
616   - m_card = NULL;
617   -
618 768 // Return
619 769 return;
620 770 }
621 771  
622 772  
623 773 /***********************************************************************//**
624   - * @brief Get pointer on header card
  774 + * @brief Get index of header card
625 775 *
626   - * @param[in] keyname Name of the header card
  776 + * @param[in] keyname Header card key name.
  777 + * @return Index of header card (-1 if @p keyname is not found)
627 778 *
628   - * Returns pointer on header card. If the header card was not found then
629   - * return a NULL pointer.
  779 + * Returns index of header card based on the @p keyname. If no header card
  780 + * is found, -1 is returned.
630 781 ***************************************************************************/
631   -GFitsHeaderCard* GFitsHeader::card_ptr(const std::string& keyname) const
  782 +int GFitsHeader::get_index(const std::string& keyname) const
632 783 {
633   -
634   - // Set card pointer to NULL (default)
635   - GFitsHeaderCard* ptr = NULL;
  784 + // Initialise index
  785 + int index = -1;
636 786  
637 787 // Search keyname in list
638   - for (int i = 0; i < m_num_cards; ++i) {
639   - if (m_card[i].keyname() == keyname) {
640   - ptr = &(m_card[i]);
  788 + for (int i = 0; i < size(); ++i) {
  789 + if (m_cards[i].keyname() == keyname) {
  790 + index = i;
641 791 break;
642 792 }
643 793 }
644 794  
645   - // Return pointer
646   - return ptr;
  795 + // Return index
  796 + return index;
647 797 }
... ...
src/fits/GFitsHeaderCard.cpp
... ... @@ -506,7 +506,7 @@ void GFitsHeaderCard::value(const long long&amp; value)
506 506 * Convert header card value into a string.
507 507 * Any hyphens that may occur in the FITS card will be automatically stripped.
508 508 ***************************************************************************/
509   -std::string GFitsHeaderCard::string(void)
  509 +std::string GFitsHeaderCard::string(void) const
510 510 {
511 511 // Initialize return value to actual value string
512 512 std::string result = m_value;
... ... @@ -537,7 +537,7 @@ std::string GFitsHeaderCard::string(void)
537 537 * card did not contain a numerical value, 0 will be returned by the
538 538 * method.
539 539 ***************************************************************************/
540   -double GFitsHeaderCard::real(void)
  540 +double GFitsHeaderCard::real(void) const
541 541 {
542 542 // Initialize return value to 0.0
543 543 double result = 0.0;
... ... @@ -572,7 +572,7 @@ double GFitsHeaderCard::real(void)
572 572 * card did not contain a numerical value, 0 will be returned by the
573 573 * method.
574 574 ***************************************************************************/
575   -int GFitsHeaderCard::integer(void)
  575 +int GFitsHeaderCard::integer(void) const
576 576 {
577 577 // Initialize return value to 0
578 578 int result = 0;
... ... @@ -1068,7 +1068,7 @@ void GFitsHeaderCard::read(void* vptr, const std::string&amp; keyname)
1068 1068 *
1069 1069 * Writes any kind of header card to a FITS file.
1070 1070 ***************************************************************************/
1071   -void GFitsHeaderCard::write(void* vptr)
  1071 +void GFitsHeaderCard::write(void* vptr) const
1072 1072 {
1073 1073 // Move to HDU
1074 1074 int status = 0;
... ...
src/fits/GFitsImage.cpp
... ... @@ -560,23 +560,23 @@ void GFitsImage::data_connect(void* vptr)
560 560 void GFitsImage::init_image_header(void)
561 561 {
562 562 // Set image header keywords
563   - m_header.update(GFitsHeaderCard("XTENSION", "IMAGE ",
  563 + m_header.append(GFitsHeaderCard("XTENSION", "IMAGE ",
564 564 "IMAGE extension"));
565   - m_header.update(GFitsHeaderCard("BITPIX", bitpix(),
  565 + m_header.append(GFitsHeaderCard("BITPIX", bitpix(),
566 566 "number of bits per data pixel"));
567   - m_header.update(GFitsHeaderCard("NAXIS", naxis(),
  567 + m_header.append(GFitsHeaderCard("NAXIS", naxis(),
568 568 "number of data axes"));
569 569 for (int i = 0; i < naxis(); ++i) {
570 570 std::ostringstream s_key;
571 571 std::ostringstream s_comment;
572 572 s_key << "NAXIS" << (i+1);
573 573 s_comment << "length of data axis " << (i+1);
574   - m_header.update(GFitsHeaderCard(s_key.str(), naxes(i),
  574 + m_header.append(GFitsHeaderCard(s_key.str(), naxes(i),
575 575 s_comment.str()));
576 576 }
577   - m_header.update(GFitsHeaderCard("PCOUNT", 0,
  577 + m_header.append(GFitsHeaderCard("PCOUNT", 0,
578 578 "required keyword; must = 0"));
579   - m_header.update(GFitsHeaderCard("GCOUNT", 1,
  579 + m_header.append(GFitsHeaderCard("GCOUNT", 1,
580 580 "required keyword; must = 1"));
581 581  
582 582 // Return
... ...
src/sky/GHealpix.cpp
... ... @@ -280,10 +280,10 @@ void GHealpix::read(const GFitsHDU* hdu)
280 280 // versions of LAT exposure cubes). If not found then search for standard
281 281 // COORDSYS keyword.
282 282 std::string coords;
283   - try {
  283 + if (hdu->hascard("HIER_CRD")) {
284 284 coords = hdu->string("HIER_CRD");
285 285 }
286   - catch (GException::fits_key_not_found &e) {
  286 + else if (hdu->hascard("COORDSYS")) {
287 287 coords = hdu->string("COORDSYS");
288 288 }
289 289  
... ...