Commit 966fb927bbd6fc3434c42cb2aa1dce93302aa448

Authored by knodlseder
1 parent 83ed050d

improve doxygen documentation

include/GException.hpp
@@ -135,6 +135,12 @@ public: @@ -135,6 +135,12 @@ public:
135 fits_open_error(string origin, string filename, int status); 135 fits_open_error(string origin, string filename, int status);
136 }; 136 };
137 137
  138 + // FITS file exists already
  139 + class fits_file_exist : public GExceptionHandler {
  140 + public:
  141 + fits_file_exist(string origin, string filename, int status);
  142 + };
  143 +
138 // FITS file has already been opened 144 // FITS file has already been opened
139 class fits_already_opened : public GExceptionHandler { 145 class fits_already_opened : public GExceptionHandler {
140 public: 146 public:
@@ -190,9 +196,15 @@ public: @@ -190,9 +196,15 @@ public:
190 }; 196 };
191 197
192 // FITS bad image operator 198 // FITS bad image operator
193 - class fits_bad_image_operator : public GExceptionHandler { 199 + class fits_wrong_image_operator : public GExceptionHandler {
  200 + public:
  201 + fits_wrong_image_operator(string origin, int naxis, int nargs);
  202 + };
  203 +
  204 + // Response invalid response type
  205 + class rsp_invalid_type : public GExceptionHandler {
194 public: 206 public:
195 - fits_bad_image_operator(string origin, int naxis, int nargs); 207 + rsp_invalid_type(string origin, string type);
196 }; 208 };
197 209
198 }; 210 };
include/GFits.hpp
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 /***********************************************************************//** 30 /***********************************************************************//**
31 * @class GFits 31 * @class GFits
32 * 32 *
33 - * @brief Implements a FITS file interface 33 + * @brief Implements FITS file interface
34 * 34 *
35 * GFits is the basic FITS file interface. All FITS file handlings operate 35 * GFits is the basic FITS file interface. All FITS file handlings operate
36 * via members of GFits. A FITS file is composed of Header Data Units (HDU) 36 * via members of GFits. A FITS file is composed of Header Data Units (HDU)
@@ -66,10 +66,10 @@ private: @@ -66,10 +66,10 @@ private:
66 void free_members(void); 66 void free_members(void);
67 67
68 // Private data area 68 // Private data area
69 - std::string m_filename; // FITS file name  
70 - __fitsfile* m_fitsfile; // FITS file pointer  
71 - int m_num_hdu; // Number of HDUs in file  
72 - GFitsHDU* m_hdu; // Pointers to HDUs 69 + std::string m_filename; //!< FITS file name
  70 + __fitsfile* m_fitsfile; //!< FITS file pointer
  71 + int m_num_hdu; //!< Number of HDUs in file
  72 + GFitsHDU* m_hdu; //!< Pointers to HDUs
73 }; 73 };
74 74
75 75
include/GFitsDblImage.hpp
@@ -39,6 +39,7 @@ public: @@ -39,6 +39,7 @@ public:
39 // Constructors and destructors 39 // Constructors and destructors
40 GFitsDblImage(); 40 GFitsDblImage();
41 GFitsDblImage(int naxis, const int* naxes); 41 GFitsDblImage(int naxis, const int* naxes);
  42 + GFitsDblImage(int naxis, const int* naxes, const double* pixels);
42 GFitsDblImage(const GFitsDblImage& image); 43 GFitsDblImage(const GFitsDblImage& image);
43 ~GFitsDblImage(); 44 ~GFitsDblImage();
44 45
include/GFitsHDU.hpp
@@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
32 /***********************************************************************//** 32 /***********************************************************************//**
33 * @class GFitsHDU 33 * @class GFitsHDU
34 * 34 *
35 - * @brief Implements the FITS Header Data Unit (HDU) 35 + * @brief Implements the FITS Header Data Unit (HDU) interface
36 * 36 *
37 * The HDU is the basic unit of a FITS file. Each HDU consists of a header 37 * The HDU is the basic unit of a FITS file. Each HDU consists of a header
38 * and a data area. The header is composed of cards and is implemented by 38 * and a data area. The header is composed of cards and is implemented by
@@ -61,6 +61,7 @@ public: @@ -61,6 +61,7 @@ public:
61 void open(__fitsfile* fptr, int hdunum); 61 void open(__fitsfile* fptr, int hdunum);
62 void save(void); 62 void save(void);
63 std::string extname(void) const; 63 std::string extname(void) const;
  64 + void extname(const std::string& extname);
64 int extno(void) const; 65 int extno(void) const;
65 int exttype(void) const; 66 int exttype(void) const;
66 GFitsHeader* header(void) const; 67 GFitsHeader* header(void) const;
@@ -77,12 +78,12 @@ private: @@ -77,12 +78,12 @@ private:
77 GFitsImage* new_image(void); 78 GFitsImage* new_image(void);
78 79
79 // Private data area 80 // Private data area
80 - __fitsfile m_fitsfile; // FITS file pointer  
81 - int m_hdunum; // HDU number (starting from 1)  
82 - std::string m_name; // HDU name  
83 - int m_type; // HDU type  
84 - GFitsHeader* m_header; // HDU header  
85 - GFitsData* m_data; // HDU data 81 + __fitsfile m_fitsfile; //!< FITS file pointer
  82 + int m_hdunum; //!< HDU number (starting from 1)
  83 + std::string m_name; //!< HDU name (extname)
  84 + int m_type; //!< HDU type
  85 + GFitsHeader* m_header; //!< HDU header
  86 + GFitsData* m_data; //!< HDU data
86 }; 87 };
87 88
88 89
include/GFitsHeader.hpp
@@ -10,6 +10,11 @@ @@ -10,6 +10,11 @@
10 * (at your option) any later version. * 10 * (at your option) any later version. *
11 * * 11 * *
12 ***************************************************************************/ 12 ***************************************************************************/
  13 +/**
  14 + * @file GFitsHeader.hpp
  15 + * @brief GFitsHeader class definition.
  16 + * @author J. Knodlseder
  17 + */
13 18
14 #ifndef GFITSHEADER_HPP 19 #ifndef GFITSHEADER_HPP
15 #define GFITSHEADER_HPP 20 #define GFITSHEADER_HPP
@@ -21,8 +26,16 @@ @@ -21,8 +26,16 @@
21 /* __ Namespaces _________________________________________________________ */ 26 /* __ Namespaces _________________________________________________________ */
22 27
23 28
24 -/***************************************************************************  
25 - * GFitsHeader class definition * 29 +/***********************************************************************//**
  30 + * @class GFitsHeader
  31 + *
  32 + * @brief Interface for FITS header class
  33 + *
  34 + * The FITS header class contains all cards that are found in the header of
  35 + * a HDU. All cards will be hold in memory, so no link to a FITS file is
  36 + * required. Cards may be read from one file (using the 'open' method) and
  37 + * saved into another file (using the 'save' method). Cards are added or
  38 + * changed using the 'update' method.
26 ***************************************************************************/ 39 ***************************************************************************/
27 class GFitsHeader { 40 class GFitsHeader {
28 41
@@ -40,7 +53,7 @@ public: @@ -40,7 +53,7 @@ public:
40 53
41 // Methods 54 // Methods
42 void open(__fitsfile* fptr); 55 void open(__fitsfile* fptr);
43 - void save(void); 56 + void save(__fitsfile* fptr);
44 void close(void); 57 void close(void);
45 void update(const GFitsHeaderCard& card); 58 void update(const GFitsHeaderCard& card);
46 GFitsHeaderCard* card(const std::string& keyname); 59 GFitsHeaderCard* card(const std::string& keyname);
@@ -52,13 +65,13 @@ public: @@ -52,13 +65,13 @@ public:
52 int integer(const std::string& keyname); 65 int integer(const std::string& keyname);
53 int integer(const int& cardno); 66 int integer(const int& cardno);
54 GFitsHeader* clone(void) const; 67 GFitsHeader* clone(void) const;
55 - 68 +
56 private: 69 private:
57 // Private methods 70 // Private methods
58 void init_members(void); 71 void init_members(void);
59 void copy_members(const GFitsHeader& header); 72 void copy_members(const GFitsHeader& header);
60 void free_members(void); 73 void free_members(void);
61 - GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname); 74 + GFitsHeaderCard* GFitsHeader::card_ptr(const std::string& keyname);
62 75
63 // Private data area 76 // Private data area
64 int m_num_cards; 77 int m_num_cards;
@@ -69,20 +82,5 @@ private: @@ -69,20 +82,5 @@ private:
69 /*************************************************************************** 82 /***************************************************************************
70 * Inline methods * 83 * Inline methods *
71 ***************************************************************************/ 84 ***************************************************************************/
72 -inline  
73 -GFitsHeaderCard* GFitsHeader::card(const std::string& keyname)  
74 -{  
75 - return GFitsHeader::card_ptr(keyname);  
76 -}  
77 -inline  
78 -GFitsHeaderCard* GFitsHeader::card(const int& cardno)  
79 -{  
80 - return (cardno >= 0 && cardno < m_num_cards) ? &(m_card[cardno]) : NULL;  
81 -}  
82 -inline  
83 -GFitsHeader* GFitsHeader::clone(void) const  
84 -{  
85 - return new GFitsHeader(*this);  
86 -}  
87 85
88 #endif /* GFITSHEADER_HPP */ 86 #endif /* GFITSHEADER_HPP */
include/GFitsHeaderCard.hpp
@@ -10,6 +10,11 @@ @@ -10,6 +10,11 @@
10 * (at your option) any later version. * 10 * (at your option) any later version. *
11 * * 11 * *
12 ***************************************************************************/ 12 ***************************************************************************/
  13 +/**
  14 + * @file GFitsHeaderCard.hpp
  15 + * @brief GFitsHeaderCard class definition.
  16 + * @author J. Knodlseder
  17 + */
13 18
14 #ifndef GFITSHEADERCARD_HPP 19 #ifndef GFITSHEADERCARD_HPP
15 #define GFITSHEADERCARD_HPP 20 #define GFITSHEADERCARD_HPP
@@ -20,8 +25,14 @@ @@ -20,8 +25,14 @@
20 /* __ Namespaces _________________________________________________________ */ 25 /* __ Namespaces _________________________________________________________ */
21 26
22 27
23 -/***************************************************************************  
24 - * GFitsHeaderCard class definition * 28 +/***********************************************************************//**
  29 + * @class GFitsHeaderCard
  30 + *
  31 + * @brief Implements FITS header card interface
  32 + *
  33 + * This class implements FITS header card. Each card consists of a
  34 + * keyname (string), a value (string, floating pointer, integer or logical)
  35 + * and a comment (string). COMMENT or HISTORY cards do not have any value.
25 ***************************************************************************/ 36 ***************************************************************************/
26 class GFitsHeaderCard { 37 class GFitsHeaderCard {
27 38
@@ -31,7 +42,11 @@ class GFitsHeaderCard { @@ -31,7 +42,11 @@ class GFitsHeaderCard {
31 public: 42 public:
32 // Constructors & Destructors 43 // Constructors & Destructors
33 GFitsHeaderCard(); 44 GFitsHeaderCard();
34 - GFitsHeaderCard(const std::string& keyname, const std::string& value, 45 + GFitsHeaderCard(const std::string& keyname, const std::string& value,
  46 + const std::string& comment);
  47 + GFitsHeaderCard(const std::string& keyname, const double& value,
  48 + const std::string& comment);
  49 + GFitsHeaderCard(const std::string& keyname, const int& value,
35 const std::string& comment); 50 const std::string& comment);
36 GFitsHeaderCard(const GFitsHeaderCard& card); 51 GFitsHeaderCard(const GFitsHeaderCard& card);
37 ~GFitsHeaderCard(); 52 ~GFitsHeaderCard();
@@ -39,7 +54,15 @@ public: @@ -39,7 +54,15 @@ public:
39 // Operators 54 // Operators
40 GFitsHeaderCard& operator= (const GFitsHeaderCard& card); 55 GFitsHeaderCard& operator= (const GFitsHeaderCard& card);
41 56
42 - // Methods 57 + // Methods to set card properties
  58 + void keyname(const std::string& keyname);
  59 + void value(const std::string& value);
  60 + void value(const double& value);
  61 + void value(const int& value);
  62 + void unit(const std::string& unit);
  63 + void comment(const std::string& comment);
  64 +
  65 + // Methods to get card properties
43 std::string keyname(void) const; 66 std::string keyname(void) const;
44 std::string value(void) const; 67 std::string value(void) const;
45 int value_type(void) const; 68 int value_type(void) const;
@@ -48,12 +71,10 @@ public: @@ -48,12 +71,10 @@ public:
48 std::string string(void); 71 std::string string(void);
49 double real(void); 72 double real(void);
50 int integer(void); 73 int integer(void);
51 - void set_keyname(const std::string& keyname);  
52 - void set_value(const std::string& value);  
53 - void set_unit(const std::string& unit);  
54 - void set_comment(const std::string& comment); 74 +
  75 + // Other methods
55 void read(__fitsfile* fptr, int keynum); 76 void read(__fitsfile* fptr, int keynum);
56 - void read(__fitsfile* fptr, std::string keyname); 77 + void read(__fitsfile* fptr, const std::string& keyname);
57 void write(__fitsfile* fptr); 78 void write(__fitsfile* fptr);
58 79
59 private: 80 private:
@@ -61,29 +82,19 @@ private: @@ -61,29 +82,19 @@ private:
61 void init_members(void); 82 void init_members(void);
62 void copy_members(const GFitsHeaderCard& card); 83 void copy_members(const GFitsHeaderCard& card);
63 void free_members(void); 84 void free_members(void);
64 - int get_value_type(void); 85 + int get_value_type(const std::string& value);
65 86
66 // Private data area 87 // Private data area
67 - std::string m_keyname;  
68 - std::string m_value;  
69 - int m_value_type;  
70 - std::string m_unit;  
71 - std::string m_comment; 88 + std::string m_keyname; //!< Name of the card
  89 + std::string m_value; //!< Value of the card as read from file
  90 + int m_value_type; //!< Type of the card value
  91 + std::string m_unit; //!< Unit of the card value
  92 + std::string m_comment; //!< Card comment
72 }; 93 };
73 94
74 95
75 /*************************************************************************** 96 /***************************************************************************
76 * Inline methods * 97 * Inline methods *
77 ***************************************************************************/ 98 ***************************************************************************/
78 -inline std::string GFitsHeaderCard::keyname(void) const { return m_keyname; }  
79 -inline std::string GFitsHeaderCard::value(void) const { return m_value; }  
80 -inline int GFitsHeaderCard::value_type(void) const { return m_value_type; }  
81 -inline std::string GFitsHeaderCard::unit(void) const { return m_unit; }  
82 -inline std::string GFitsHeaderCard::comment(void) const { return m_comment; }  
83 -inline void GFitsHeaderCard::set_keyname(const std::string& keyname) { m_keyname = keyname; }  
84 -inline void GFitsHeaderCard::set_value(const std::string& value) { m_value = value; }  
85 -inline void GFitsHeaderCard::set_unit(const std::string& unit) { m_unit = unit; }  
86 -inline void GFitsHeaderCard::set_comment(const std::string& comment) { m_comment = comment; }  
87 -  
88 99
89 #endif /* GFITSHEADERCARD_HPP */ 100 #endif /* GFITSHEADERCARD_HPP */
include/GFitsImage.hpp
@@ -53,11 +53,13 @@ public: @@ -53,11 +53,13 @@ public:
53 virtual void save(void) = 0; 53 virtual void save(void) = 0;
54 virtual void close(void) = 0; 54 virtual void close(void) = 0;
55 virtual GFitsImage* clone(void) const = 0; 55 virtual GFitsImage* clone(void) const = 0;
56 - 56 +
57 // Methods 57 // Methods
  58 + int bitpix(void) const;
58 int naxis(void) const; 59 int naxis(void) const;
59 int naxes(int axis) const; 60 int naxes(int axis) const;
60 - 61 + int num_pixels(void) const;
  62 +
61 protected: 63 protected:
62 // Private methods 64 // Private methods
63 void init_members(void); 65 void init_members(void);
@@ -69,17 +71,16 @@ protected: @@ -69,17 +71,16 @@ protected:
69 void save_image(int datatype, const void* pixels); 71 void save_image(int datatype, const void* pixels);
70 72
71 // Private data area 73 // Private data area
72 - __fitsfile m_fitsfile; // FITS file  
73 - int m_bitpix; // Number of Bits/pixel  
74 - int m_naxis; // Image dimension  
75 - long* m_naxes; // Number of pixels in each dimension  
76 - int m_num_pixels; // Number of image pixels 74 + __fitsfile m_fitsfile; //!< FITS file
  75 + int m_bitpix; //!< Number of Bits/pixel
  76 + int m_naxis; //!< Image dimension
  77 + long* m_naxes; //!< Number of pixels in each dimension
  78 + int m_num_pixels; //!< Number of image pixels
77 }; 79 };
78 80
79 81
80 /*************************************************************************** 82 /***************************************************************************
81 * Inline methods * 83 * Inline methods *
82 ***************************************************************************/ 84 ***************************************************************************/
83 -inline int GFitsImage::naxis(void) const { return m_naxis; }  
84 85
85 #endif /* GFITSIMAGE_HPP */ 86 #endif /* GFITSIMAGE_HPP */
include/GLATResponse.hpp
@@ -28,16 +28,11 @@ @@ -28,16 +28,11 @@
28 /* __ Namespaces _________________________________________________________ */ 28 /* __ Namespaces _________________________________________________________ */
29 29
30 30
31 -/***************************************************************************  
32 - * GLATResponse class definition *  
33 - ***************************************************************************/  
34 -/** 31 +/***********************************************************************//**
35 * @class GLATResponse 32 * @class GLATResponse
36 * 33 *
37 * @brief Interface for the GLAST LAT instrument response function classes. 34 * @brief Interface for the GLAST LAT instrument response function classes.
38 - *  
39 - * @author J. Knodlseder  
40 - */ 35 + ***************************************************************************/
41 class GLATResponse : public GResponse { 36 class GLATResponse : public GResponse {
42 37
43 public: 38 public:
@@ -67,9 +62,9 @@ public: @@ -67,9 +62,9 @@ public:
67 const GSkyDir& instPntDir, const double& instPosAng, 62 const GSkyDir& instPntDir, const double& instPosAng,
68 const double& time); 63 const double& time);
69 64
70 - void set_caldb(std::string caldb);  
71 - void load(std::string rspname, std::string rsptype);  
72 - void save(std::string rspname) const; 65 + void set_caldb(const std::string& caldb);
  66 + void load(const std::string& rspname, const std::string& rsptype);
  67 + void save(const std::string& rspname) const;
73 GLATResponse* clone(void) const; 68 GLATResponse* clone(void) const;
74 69
75 private: 70 private:
@@ -82,7 +77,7 @@ private: @@ -82,7 +77,7 @@ private:
82 double psf_scale(const double& energy); 77 double psf_scale(const double& energy);
83 double psf_base_value(const double& u, const double& gamma); 78 double psf_base_value(const double& u, const double& gamma);
84 GVector psf_base_vector(const GVector& u, const double& gamma); 79 GVector psf_base_vector(const GVector& u, const double& gamma);
85 - 80 +
86 // Private PSF data 81 // Private PSF data
87 int m_psf_angle_num; 82 int m_psf_angle_num;
88 double m_psf_angle_min; 83 double m_psf_angle_min;
include/GResponse.hpp
@@ -108,7 +108,7 @@ public: @@ -108,7 +108,7 @@ public:
108 108
109 /// Pure virtual method to define the calibration database 109 /// Pure virtual method to define the calibration database
110 /// @param caldb Calibration database to be used 110 /// @param caldb Calibration database to be used
111 - virtual void set_caldb(std::string caldb) = 0; 111 + virtual void set_caldb(const std::string& caldb) = 0;
112 112
113 /// Pure virtual method to load the instrument response from the calibration 113 /// Pure virtual method to load the instrument response from the calibration
114 /// database 114 /// database
src/GException.cpp
@@ -213,8 +213,11 @@ GException::invalid_order::invalid_order(string origin, int order, int min_order @@ -213,8 +213,11 @@ GException::invalid_order::invalid_order(string origin, int order, int min_order
213 } 213 }
214 214
215 215
216 -/***************************************************************************  
217 - * FITS error * 216 +/***********************************************************************//**
  217 + * @brief General FITS error
  218 + *
  219 + * @param[in] origin Method that throws the error.
  220 + * @param[in] status cfitsio status.
218 ***************************************************************************/ 221 ***************************************************************************/
219 GException::fits_error::fits_error(string origin, int status) 222 GException::fits_error::fits_error(string origin, int status)
220 { 223 {
@@ -222,125 +225,211 @@ GException::fits_error::fits_error(string origin, int status) @@ -222,125 +225,211 @@ GException::fits_error::fits_error(string origin, int status)
222 ostringstream s_error; 225 ostringstream s_error;
223 char err_text[31]; 226 char err_text[31];
224 __ffgerr(status, err_text); 227 __ffgerr(status, err_text);
225 - s_error << err_text << " (status: " << status << ")"; 228 + s_error << err_text << " (status=" << status << ")";
226 m_message = s_error.str(); 229 m_message = s_error.str();
227 } 230 }
228 231
229 232
230 -/***************************************************************************  
231 - * FITS file opening error * 233 +/***********************************************************************//**
  234 + * @brief FITS error: unable to open FITS file
  235 + *
  236 + * @param[in] origin Method that throws the error.
  237 + * @param[in] filename Name of the file for which opening was attempted.
  238 + * @param[in] status cfitsio status.
232 ***************************************************************************/ 239 ***************************************************************************/
233 -GException::fits_open_error::fits_open_error(string origin, string filename, int status) 240 +GException::fits_open_error::fits_open_error(string origin,
  241 + string filename,
  242 + int status)
234 { 243 {
235 m_origin = origin; 244 m_origin = origin;
236 - m_message = "Unable to open FITS file '" + filename + "'"  
237 - + " (status: " + str(status) + ")"; 245 + m_message = "Unable to open FITS file '" + filename + "'";
  246 + if (status != 0)
  247 + m_message += " (status=" + str(status) + ")";
238 } 248 }
239 249
240 250
241 -/***************************************************************************  
242 - * FITS file already opened * 251 +/***********************************************************************//**
  252 + * @brief FITS error: attempted to overwrite FITS file
  253 + *
  254 + * @param[in] origin Method that throws the error.
  255 + * @param[in] filename Name of the file for which overwrite attempt was made.
  256 + * @param[in] status cfitsio status.
243 ***************************************************************************/ 257 ***************************************************************************/
244 -GException::fits_already_opened::fits_already_opened(string origin, string filename) 258 +GException::fits_file_exist::fits_file_exist(string origin,
  259 + string filename,
  260 + int status)
245 { 261 {
246 m_origin = origin; 262 m_origin = origin;
247 - m_message = "GFits object has already the FITS file '" + filename + "' opened"; 263 + m_message = "Attempted to overwrite FITS file '" + filename + "'";
  264 + if (status != 0)
  265 + m_message += " (status=" + str(status) + ")";
248 } 266 }
249 267
250 268
251 -/***************************************************************************  
252 - * FITS keyword not found error * 269 +/***********************************************************************//**
  270 + * @brief FITS error: file already open
  271 + *
  272 + * @param[in] origin Method that throws the error.
  273 + * @param[in] filename Name of file that is already open.
253 ***************************************************************************/ 274 ***************************************************************************/
254 -GException::fits_key_not_found::fits_key_not_found(string origin, string keyname, int status) 275 +GException::fits_already_opened::fits_already_opened(string origin,
  276 + string filename)
  277 +{
  278 + m_origin = origin;
  279 + m_message = "FITS file '" + filename + "' is already open";
  280 +}
  281 +
  282 +
  283 +/***********************************************************************//**
  284 + * @brief FITS error: Keyword not in header
  285 + *
  286 + * @param[in] origin Method that throws the error.
  287 + * @param[in] keyname Name of keyword that was not found.
  288 + * @param[in] status cfitsio status.
  289 + ***************************************************************************/
  290 +GException::fits_key_not_found::fits_key_not_found(string origin,
  291 + string keyname,
  292 + int status)
255 { 293 {
256 m_origin = origin; 294 m_origin = origin;
257 m_message = "Keyword '" + keyname + "' not found in header"; 295 m_message = "Keyword '" + keyname + "' not found in header";
  296 + if (status != 0)
  297 + m_message += " (status=" + str(status) + ")";
258 } 298 }
259 299
260 300
261 -/***************************************************************************  
262 - * FITS column not found error * 301 +/***********************************************************************//**
  302 + * @brief FITS error: Table column not found
  303 + *
  304 + * @param[in] origin Method that throws the error.
  305 + * @param[in] colname Name of the table column that was not found.
  306 + * @param[in] status cfitsio status.
263 ***************************************************************************/ 307 ***************************************************************************/
264 -GException::fits_column_not_found::fits_column_not_found(string origin, string colname, int status) 308 +GException::fits_column_not_found::fits_column_not_found(string origin,
  309 + string colname,
  310 + int status)
265 { 311 {
266 m_origin = origin; 312 m_origin = origin;
267 m_message = "Column '" + colname + "' not found in table"; 313 m_message = "Column '" + colname + "' not found in table";
  314 + if (status != 0)
  315 + m_message += " (status=" + str(status) + ")";
268 } 316 }
269 317
270 318
271 -/***************************************************************************  
272 - * FITS HDU not found error * 319 +/***********************************************************************//**
  320 + * @brief FITS error: HDU not found in FITS file
  321 + *
  322 + * @param[in] origin Method that throws the error.
  323 + * @param[in] extname Name of the extension that was not found.
  324 + * @param[in] status cfitsio status.
273 ***************************************************************************/ 325 ***************************************************************************/
274 -GException::fits_hdu_not_found::fits_hdu_not_found(string origin, string extname, int status) 326 +GException::fits_hdu_not_found::fits_hdu_not_found(string origin,
  327 + string extname,
  328 + int status)
275 { 329 {
276 m_origin = origin; 330 m_origin = origin;
277 m_message = "HDU '" + extname + "' not found in FITS file"; 331 m_message = "HDU '" + extname + "' not found in FITS file";
  332 + if (status != 0)
  333 + m_message += " (status=" + str(status) + ")";
278 } 334 }
279 335
280 336
281 -/***************************************************************************  
282 - * Unknown HDU type found * 337 +/***********************************************************************//**
  338 + * @brief FITS error: HDU of unknown type found
  339 + *
  340 + * @param[in] origin Method that throws the error.
  341 + * @param[in] type Specified HDU type.
283 ***************************************************************************/ 342 ***************************************************************************/
284 -GException::fits_unknown_HDU_type::fits_unknown_HDU_type(string origin, int type) 343 +GException::fits_unknown_HDU_type::fits_unknown_HDU_type(string origin,
  344 + int type)
285 { 345 {
286 m_origin = origin; 346 m_origin = origin;
287 - m_message = "HDU type " + str(type) + " is not known"; 347 + m_message = "HDU type '" + str(type) + "' is not known";
288 } 348 }
289 349
290 350
291 -/***************************************************************************  
292 - * HDU is not a table * 351 +/***********************************************************************//**
  352 + * @brief FITS error: HDU is not a table
  353 + *
  354 + * @param[in] origin Method that throws the error.
  355 + * @param[in] type Specified HDU type.
293 ***************************************************************************/ 356 ***************************************************************************/
294 -GException::fits_HDU_not_a_table::fits_HDU_not_a_table(string origin, int type) 357 +GException::fits_HDU_not_a_table::fits_HDU_not_a_table(string origin,
  358 + int type)
295 { 359 {
296 m_origin = origin; 360 m_origin = origin;
297 - m_message = "HDU is not a table (type " + str(type) + ")"; 361 + m_message = "HDU is not of type 'table' (type=" + str(type) + ")";
298 } 362 }
299 363
300 364
301 -/***************************************************************************  
302 - * HDU is not a table * 365 +/***********************************************************************//**
  366 + * @brief FITS error: Invalid type
  367 + *
  368 + * @param[in] origin Method that throws the error.
  369 + * @param[in] message Error message.
303 ***************************************************************************/ 370 ***************************************************************************/
304 -GException::fits_invalid_type::fits_invalid_type(string origin, string message) 371 +GException::fits_invalid_type::fits_invalid_type(string origin,
  372 + string message)
305 { 373 {
306 m_origin = origin; 374 m_origin = origin;
307 m_message = message; 375 m_message = message;
308 } 376 }
309 377
310 378
311 -/***************************************************************************  
312 - * Column type is unknown * 379 +/***********************************************************************//**
  380 + * @brief FITS error: Column type is unknown
  381 + *
  382 + * @param[in] origin Method that throws the error.
  383 + * @param[in] type Specified column type.
313 ***************************************************************************/ 384 ***************************************************************************/
314 -GException::fits_unknown_coltype::fits_unknown_coltype(string origin, int type) 385 +GException::fits_unknown_coltype::fits_unknown_coltype(string origin,
  386 + int type)
315 { 387 {
316 m_origin = origin; 388 m_origin = origin;
317 - m_message = "Column type " + str(type) + " is unknown"; 389 + m_message = "Column type '" + str(type) + "' is unknown";
318 } 390 }
319 391
320 392
321 /***********************************************************************//** 393 /***********************************************************************//**
322 * @brief FITS error: invalid number of bits per pixel 394 * @brief FITS error: invalid number of bits per pixel
323 * 395 *
324 - * @param origin Method that throws the error  
325 - * @param bitpix Bitpix value that was not 8,16,32,64,-32, or -64 396 + * @param[in] origin Method that throws the error.
  397 + * @param[in] bitpix Bitpix value that was not 8,16,32,64,-32, or -64.
  398 + ***************************************************************************/
  399 +GException::fits_bad_bitpix::fits_bad_bitpix(string origin,
  400 + int bitpix)
  401 +{
  402 + m_origin = origin;
  403 + m_message = "Invalid number of bits per pixel (bitpix="+str(bitpix)+")";
  404 +}
  405 +
  406 +
  407 +/***********************************************************************//**
  408 + * @brief FITS error: wrong image operator has been used
  409 + *
  410 + * @param[in] origin Method that throws the error.
  411 + * @param[in] naxis Dimension of image.
  412 + * @param[in] nargs Number of arguments of the image operator.
326 ***************************************************************************/ 413 ***************************************************************************/
327 -GException::fits_bad_bitpix::fits_bad_bitpix(string origin, int bitpix) 414 +GException::fits_wrong_image_operator::fits_wrong_image_operator(string origin,
  415 + int naxis,
  416 + int nargs)
328 { 417 {
329 m_origin = origin; 418 m_origin = origin;
330 - m_message = "Invalid number of bits per pixel (bitpix=" + str(bitpix) + ")"; 419 + m_message = "Wrong image pixel access operator has been used (dimension=" +
  420 + str(naxis) + " <=> arguments=" + str(nargs) + ")";
331 } 421 }
332 422
333 423
334 /***********************************************************************//** 424 /***********************************************************************//**
335 - * @brief FITS error: bad image operator has been used 425 + * @brief Response error: invalid response type specified
336 * 426 *
337 - * @param origin Method that throws the error  
338 - * @param naxis Dimension of image  
339 - * @param nargs Number of arguments of the image operator 427 + * @param[in] origin Method that throws the error.
  428 + * @param[in] type Specified response type.
340 ***************************************************************************/ 429 ***************************************************************************/
341 -GException::fits_bad_image_operator::fits_bad_image_operator(string origin, int naxis, int nargs) 430 +GException::rsp_invalid_type::rsp_invalid_type(string origin,
  431 + string type)
342 { 432 {
343 m_origin = origin; 433 m_origin = origin;
344 - m_message = "Bad image pixel access operator used (image dimension=" +  
345 - str(naxis) + "; operator arguments=" + str(nargs) + ")"; 434 + m_message = "Invalid response type '"+type+"' specified";
346 } 435 }
src/fits/GFits.cpp
@@ -23,6 +23,8 @@ @@ -23,6 +23,8 @@
23 /* __ Method name definitions ____________________________________________ */ 23 /* __ Method name definitions ____________________________________________ */
24 #define G_OPEN "GFits::open(std::string)" 24 #define G_OPEN "GFits::open(std::string)"
25 #define G_SAVETO "GFits::saveto(const std::string, int)" 25 #define G_SAVETO "GFits::saveto(const std::string, int)"
  26 +#define G_HDU1 "GFits::hdu(const std::string&)"
  27 +#define G_HDU2 "GFits::hdu(int extno)"
26 #define G_FREE_MEM "GFits::free_members()" 28 #define G_FREE_MEM "GFits::free_members()"
27 29
28 /* __ Macros _____________________________________________________________ */ 30 /* __ Macros _____________________________________________________________ */
@@ -55,7 +57,7 @@ GFits::GFits() @@ -55,7 +57,7 @@ GFits::GFits()
55 /***********************************************************************//** 57 /***********************************************************************//**
56 * @brief Copy constructor 58 * @brief Copy constructor
57 * 59 *
58 - * @param fits FITS file from which the instance should be built 60 + * @param[in] fits FITS file from which the instance should be built.
59 ***************************************************************************/ 61 ***************************************************************************/
60 GFits::GFits(const GFits& fits) 62 GFits::GFits(const GFits& fits)
61 { 63 {
@@ -92,7 +94,7 @@ GFits::~GFits() @@ -92,7 +94,7 @@ GFits::~GFits()
92 /***********************************************************************//** 94 /***********************************************************************//**
93 * @brief Assignment operator 95 * @brief Assignment operator
94 * 96 *
95 - * @param fits FITS file that should be assigned 97 + * @param fits[in] FITS file that should be assigned to GFits instance.
96 ***************************************************************************/ 98 ***************************************************************************/
97 GFits& GFits::operator= (const GFits& fits) 99 GFits& GFits::operator= (const GFits& fits)
98 { 100 {
@@ -122,11 +124,26 @@ GFits&amp; GFits::operator= (const GFits&amp; fits) @@ -122,11 +124,26 @@ GFits&amp; GFits::operator= (const GFits&amp; fits)
122 ==========================================================================*/ 124 ==========================================================================*/
123 125
124 /***********************************************************************//** 126 /***********************************************************************//**
125 - * @brief Open FITS file 127 + * @brief Opens or creates FITS file
126 * 128 *
127 - * @param filename Name of FITS file to be opened 129 + * @param[in] filename Name of FITS file to be opened
128 * 130 *
129 - * Opens all HDUs in the specified FITS file. 131 + * @exception GException::fits_already_opened
  132 + * Class instance contains already an opened FITS file.
  133 + * Close file before opening a new one using GFits::close().
  134 + * @exception GException::fits_open_error
  135 + * Unable to open the specified file.
  136 + * @exception GException::fits_error
  137 + * Unable to determine number of HDUs in the FITS file.
  138 + *
  139 + * This method opens all HDUs that are found in the specified FITS file.
  140 + * If the file does not exist then a new FITS file is created.
  141 + * For each HDU, a GFitsHDU object is associated to the GFits object.
  142 + * The HDUs can then be accessed using the
  143 + * GFits::hdu(const std::string&)
  144 + * or
  145 + * GFits::hdu(int extno)
  146 + * methods.
130 ***************************************************************************/ 147 ***************************************************************************/
131 void GFits::open(const std::string& filename) 148 void GFits::open(const std::string& filename)
132 { 149 {
@@ -137,7 +154,7 @@ void GFits::open(const std::string&amp; filename) @@ -137,7 +154,7 @@ void GFits::open(const std::string&amp; filename)
137 // Open FITS file 154 // Open FITS file
138 int status = 0; 155 int status = 0;
139 status = __ffopen(&m_fitsfile, filename.c_str(), 1, &status); 156 status = __ffopen(&m_fitsfile, filename.c_str(), 1, &status);
140 - 157 +
141 // If FITS file does not exist then create it now 158 // If FITS file does not exist then create it now
142 if (status == 104) { 159 if (status == 104) {
143 status = 0; 160 status = 0;
@@ -172,9 +189,12 @@ void GFits::open(const std::string&amp; filename) @@ -172,9 +189,12 @@ void GFits::open(const std::string&amp; filename)
172 /***********************************************************************//** 189 /***********************************************************************//**
173 * @brief Append HDU to FITS file 190 * @brief Append HDU to FITS file
174 * 191 *
175 - * @param hdu Pointer to FITS HDU that should be appended 192 + * @param[in] hdu Pointer to FITS HDU that should be appended
176 * 193 *
177 - * NOT YET FULLY IMPLEMENTED 194 + * Append HDU to the next free position in a FITS file. In case that no HDU
  195 + * exists so far in the FITS file and if the HDU to append is NOT an image,
  196 + * an empty primary image will be inserted as first HDU in the FITS file.
  197 + * This guarantees the compatibility with the FITS standard.
178 ***************************************************************************/ 198 ***************************************************************************/
179 void GFits::append(const GFitsHDU* hdu) 199 void GFits::append(const GFitsHDU* hdu)
180 { 200 {
@@ -182,11 +202,11 @@ void GFits::append(const GFitsHDU* hdu) @@ -182,11 +202,11 @@ void GFits::append(const GFitsHDU* hdu)
182 // the HDU to append is not an image then we have to add a primary 202 // the HDU to append is not an image then we have to add a primary
183 // image first. In this case we add 2 new HDUs. 203 // image first. In this case we add 2 new HDUs.
184 int n_add = (m_num_hdu == 0 && hdu->m_type != 0) ? 2 : 1; 204 int n_add = (m_num_hdu == 0 && hdu->m_type != 0) ? 2 : 1;
185 - 205 +
186 // Create memory to hold HDUs 206 // Create memory to hold HDUs
187 GFitsHDU* tmp = new GFitsHDU[m_num_hdu+n_add]; 207 GFitsHDU* tmp = new GFitsHDU[m_num_hdu+n_add];
188 if (tmp != NULL) { 208 if (tmp != NULL) {
189 - 209 +
190 // Copy over existing HDUs and remove old ones 210 // Copy over existing HDUs and remove old ones
191 if (m_hdu != NULL) { 211 if (m_hdu != NULL) {
192 for (int i = 0; i < m_num_hdu; ++i) 212 for (int i = 0; i < m_num_hdu; ++i)
@@ -196,12 +216,12 @@ void GFits::append(const GFitsHDU* hdu) @@ -196,12 +216,12 @@ void GFits::append(const GFitsHDU* hdu)
196 216
197 // Connect the new memory to the card pointer 217 // Connect the new memory to the card pointer
198 m_hdu = tmp; 218 m_hdu = tmp;
199 - 219 +
200 // Add primary image if required 220 // Add primary image if required
201 if (n_add == 2) { 221 if (n_add == 2) {
202 222
203 // Append empty primary image 223 // Append empty primary image
204 - //m_hdu[m_num_hdu] = TBD 224 + m_hdu[m_num_hdu].primary();
205 225
206 // Set FITS file pointer for new HDU 226 // Set FITS file pointer for new HDU
207 __fitsfile fptr = *m_fitsfile; 227 __fitsfile fptr = *m_fitsfile;
@@ -214,15 +234,15 @@ void GFits::append(const GFitsHDU* hdu) @@ -214,15 +234,15 @@ void GFits::append(const GFitsHDU* hdu)
214 234
215 // Append new HDU to list 235 // Append new HDU to list
216 m_hdu[m_num_hdu] = *hdu; 236 m_hdu[m_num_hdu] = *hdu;
217 - 237 +
218 // Set FITS file pointer for new HDU 238 // Set FITS file pointer for new HDU
219 __fitsfile fptr = *m_fitsfile; 239 __fitsfile fptr = *m_fitsfile;
220 fptr.HDUposition = m_num_hdu; 240 fptr.HDUposition = m_num_hdu;
221 m_hdu[m_num_hdu].connect(&fptr); 241 m_hdu[m_num_hdu].connect(&fptr);
222 - 242 +
223 // Increment number of HDUs 243 // Increment number of HDUs
224 m_num_hdu++; 244 m_num_hdu++;
225 - 245 +
226 } 246 }
227 247
228 // Return 248 // Return
@@ -233,7 +253,8 @@ void GFits::append(const GFitsHDU* hdu) @@ -233,7 +253,8 @@ void GFits::append(const GFitsHDU* hdu)
233 /***********************************************************************//** 253 /***********************************************************************//**
234 * @brief Saves FITS file 254 * @brief Saves FITS file
235 * 255 *
236 - * Saves all HDUs to the FITS file. 256 + * Saves all HDUs to the FITS file by looping over the GFitsHDU::save()
  257 + * method.
237 ***************************************************************************/ 258 ***************************************************************************/
238 void GFits::save(void) 259 void GFits::save(void)
239 { 260 {
@@ -249,10 +270,15 @@ void GFits::save(void) @@ -249,10 +270,15 @@ void GFits::save(void)
249 /***********************************************************************//** 270 /***********************************************************************//**
250 * @brief Saves to specified FITS file 271 * @brief Saves to specified FITS file
251 * 272 *
252 - * @param filename Name of file into which should be saved  
253 - * @param clobber Specifies whether any existing file should be overwritten 273 + * @param[in] filename Name of file into which should be saved.
  274 + * @param[in] clobber Specifies whether any existing file should be
  275 + * overwritten.
254 * 276 *
255 - * FUNCTION IS NOT FULLY IMPLEMENTED 277 + * @exception GException::fits_file_exist
  278 + * File specified by 'filename' exists already.
  279 + * To overwrite an existing file set 'clobber=1'.
  280 + * @exception GException::fits_error
  281 + * Unable to delete exiting FITS file.
256 ***************************************************************************/ 282 ***************************************************************************/
257 void GFits::saveto(const std::string& filename, int clobber) 283 void GFits::saveto(const std::string& filename, int clobber)
258 { 284 {
@@ -262,26 +288,36 @@ void GFits::saveto(const std::string&amp; filename, int clobber) @@ -262,26 +288,36 @@ void GFits::saveto(const std::string&amp; filename, int clobber)
262 GFits new_fits = *this; 288 GFits new_fits = *this;
263 289
264 // Check if specified FITS file exists. If yes, saving will only be 290 // Check if specified FITS file exists. If yes, saving will only be
265 - // allowed if clobber is true ... 291 + // allowed if clobber is true. If this is the case the specified file
  292 + // will be deleted.
266 int status = 0; 293 int status = 0;
267 status = __ffopen(&(new_fits.m_fitsfile), filename.c_str(), 1, &status); 294 status = __ffopen(&(new_fits.m_fitsfile), filename.c_str(), 1, &status);
268 if (status == 0) { 295 if (status == 0) {
269 - if (!clobber) {  
270 - throw GException::fits_open_error(G_SAVETO, filename, status);  
271 - //throw file_exists ...  
272 - }  
273 - //delete existing file  
274 - //...  
275 - }  
276 296
277 - // ... otherwise create a new FITS file now  
278 - else {  
279 - // ... 297 + // If overwriting was not allowed the throw an exception
  298 + if (!clobber)
  299 + throw GException::fits_file_exist(G_SAVETO, filename, status);
  300 +
  301 + // Delete existing file
  302 + __fitsfile* tmp;
  303 + status = __ffopen(&tmp, filename.c_str(), 1, &status);
  304 + status = __ffdelt(tmp, &status);
  305 + if (status == 0)
  306 + throw GException::fits_error(G_SAVETO, status);
  307 +
280 } 308 }
  309 + else
  310 + status = 0;
281 311
282 - // Save all HDUs 312 + // Create a new FITS file now
  313 + new_fits.open(filename);
  314 +
  315 + // Copy all HDUs
283 for (int i = 0; i < m_num_hdu; ++i) 316 for (int i = 0; i < m_num_hdu; ++i)
284 - new_fits.m_hdu[i].save(); 317 + new_fits.m_hdu[i] = m_hdu[i];
  318 +
  319 + // Save new FITS file
  320 + new_fits.save();
285 321
286 // Return 322 // Return
287 return; 323 return;
@@ -310,10 +346,12 @@ void GFits::close(void) @@ -310,10 +346,12 @@ void GFits::close(void)
310 /***********************************************************************//** 346 /***********************************************************************//**
311 * @brief Get pointer to HDU 347 * @brief Get pointer to HDU
312 * 348 *
313 - * @param extname Name of HDU extension which should be returned 349 + * @param[in] extname Name of HDU extension which should be returned
  350 + *
  351 + * @exception GException::fits_hdu_not_found
  352 + * HDU with specified extension name has not been found in FITS
  353 + * file.
314 ***************************************************************************/ 354 ***************************************************************************/
315 -#define G_HDU1 "GFits::hdu(const std::string&)"  
316 -#define G_HDU2 "GFits::hdu(int extno)"  
317 GFitsHDU* GFits::hdu(const std::string& extname) 355 GFitsHDU* GFits::hdu(const std::string& extname)
318 { 356 {
319 // Initialise result to NULL pointer 357 // Initialise result to NULL pointer
@@ -326,7 +364,7 @@ GFitsHDU* GFits::hdu(const std::string&amp; extname) @@ -326,7 +364,7 @@ GFitsHDU* GFits::hdu(const std::string&amp; extname)
326 break; 364 break;
327 } 365 }
328 } 366 }
329 - 367 +
330 // Throw an error if HDU has not been found 368 // Throw an error if HDU has not been found
331 if (ptr == NULL) 369 if (ptr == NULL)
332 throw GException::fits_hdu_not_found(G_HDU1, extname); 370 throw GException::fits_hdu_not_found(G_HDU1, extname);
@@ -339,7 +377,11 @@ GFitsHDU* GFits::hdu(const std::string&amp; extname) @@ -339,7 +377,11 @@ GFitsHDU* GFits::hdu(const std::string&amp; extname)
339 /***********************************************************************//** 377 /***********************************************************************//**
340 * @brief Get pointer to HDU 378 * @brief Get pointer to HDU
341 * 379 *
342 - * @param extno Extension number (starting from 1) 380 + * @param extno[in] Extension number (starting from 1)
  381 + *
  382 + * @exception GException::fits_hdu_not_found
  383 + * HDU with specified extension number has not been found in FITS
  384 + * file.
343 ***************************************************************************/ 385 ***************************************************************************/
344 GFitsHDU* GFits::hdu(int extno) 386 GFitsHDU* GFits::hdu(int extno)
345 { 387 {
@@ -426,13 +468,13 @@ void GFits::free_members(void) @@ -426,13 +468,13 @@ void GFits::free_members(void)
426 { 468 {
427 // If FITS file has been opened then close it now 469 // If FITS file has been opened then close it now
428 if (m_fitsfile != NULL) { 470 if (m_fitsfile != NULL) {
429 - 471 +
430 // If there are no HDUs then delete the file (don't worry about error) 472 // If there are no HDUs then delete the file (don't worry about error)
431 if (m_num_hdu == 0) { 473 if (m_num_hdu == 0) {
432 int status = 0; 474 int status = 0;
433 __ffdelt(m_fitsfile, &status); 475 __ffdelt(m_fitsfile, &status);
434 } 476 }
435 - 477 +
436 // ... otherwise close the file 478 // ... otherwise close the file
437 else { 479 else {
438 int status = 0; 480 int status = 0;
src/fits/GFitsDblImage.cpp
@@ -57,7 +57,7 @@ GFitsDblImage::GFitsDblImage() : GFitsImage() @@ -57,7 +57,7 @@ GFitsDblImage::GFitsDblImage() : GFitsImage()
57 /***********************************************************************//** 57 /***********************************************************************//**
58 * @brief Constructor 58 * @brief Constructor
59 * 59 *
60 - * @param naxis Image dimensions (0,1,2,3,4) 60 + * @param naxis Image dimension (0,1,2,3,4)
61 * @param naxes Number of pixels in each dimension 61 * @param naxes Number of pixels in each dimension
62 * 62 *
63 * Construct instance of GFitsDblImage by specifying the image dimension and 63 * Construct instance of GFitsDblImage by specifying the image dimension and
@@ -68,10 +68,46 @@ GFitsDblImage::GFitsDblImage(int naxis, const int* naxes) : GFitsImage(naxis, na @@ -68,10 +68,46 @@ GFitsDblImage::GFitsDblImage(int naxis, const int* naxes) : GFitsImage(naxis, na
68 { 68 {
69 // Initialise class members for clean destruction 69 // Initialise class members for clean destruction
70 init_members(); 70 init_members();
71 - 71 +
72 // Set bitpix 72 // Set bitpix
73 m_bitpix = -64; 73 m_bitpix = -64;
74 - 74 +
  75 + // Return
  76 + return;
  77 +}
  78 +
  79 +
  80 +/***********************************************************************//**
  81 + * @brief Constructor
  82 + *
  83 + * @param naxis Image dimension (0,1,2,3,4)
  84 + * @param naxes Number of pixels in each dimension
  85 + * @param pixels Pointer to image pixel array
  86 + *
  87 + * Construct instance of GFitsDblImage by specifying the image dimension, the
  88 + * number of pixels in each dimension and an image pixel array. If the
  89 + * 'pixels' pointer is valid (i.e. not NULL) the pixel data is indeed copied
  90 + * by this constructor. In case of memory shortage a combination of
  91 + * GFitsDblImage::GFitsDblImage(int naxis, const int* naxes)
  92 + * and
  93 + * GFitsDblImage::link(double* pixels)
  94 + * may be prefered to avoid duplication of the pixel data.
  95 + ***************************************************************************/
  96 +GFitsDblImage::GFitsDblImage(int naxis, const int* naxes, const double* pixels)
  97 + : GFitsImage(naxis, naxes)
  98 +{
  99 + // Initialise class members for clean destruction
  100 + init_members();
  101 +
  102 + // Copy pixels into object
  103 + if (m_num_pixels > 0 && pixels != NULL) {
  104 + m_pixels = new double[m_num_pixels];
  105 + memcpy(m_pixels, pixels, m_num_pixels*sizeof(double));
  106 + }
  107 +
  108 + // Set bitpix
  109 + m_bitpix = -64;
  110 +
75 // Return 111 // Return
76 return; 112 return;
77 } 113 }
@@ -146,7 +182,10 @@ GFitsDblImage&amp; GFitsDblImage::operator= (const GFitsDblImage&amp; image) @@ -146,7 +182,10 @@ GFitsDblImage&amp; GFitsDblImage::operator= (const GFitsDblImage&amp; image)
146 /***********************************************************************//** 182 /***********************************************************************//**
147 * @brief 1D image pixel access operator 183 * @brief 1D image pixel access operator
148 * 184 *
149 - * @param ix Pixel index 185 + * @param[in] ix Pixel index
  186 + *
  187 + * @exception GException::fits_wrong_image_operator
  188 + * Image is not a 1D image
150 * 189 *
151 * Provides access to a pixel of a 1D image. No range checking is performed. 190 * Provides access to a pixel of a 1D image. No range checking is performed.
152 * Use the at(ix) method if range checking is required. 191 * Use the at(ix) method if range checking is required.
@@ -155,11 +194,11 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix) @@ -155,11 +194,11 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix)
155 { 194 {
156 // Operator is only valid for 1D images 195 // Operator is only valid for 1D images
157 if (m_naxis != 1) 196 if (m_naxis != 1)
158 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 1); 197 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 1);
159 198
160 // If image pixels are not available then allocate them now 199 // If image pixels are not available then allocate them now
161 if (m_pixels == NULL) fetch_pixels(); 200 if (m_pixels == NULL) fetch_pixels();
162 - 201 +
163 // Return image pixel 202 // Return image pixel
164 return m_pixels[ix]; 203 return m_pixels[ix];
165 } 204 }
@@ -168,7 +207,10 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix) @@ -168,7 +207,10 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix)
168 /***********************************************************************//** 207 /***********************************************************************//**
169 * @brief 1D image pixel access operator (const variant) 208 * @brief 1D image pixel access operator (const variant)
170 * 209 *
171 - * @param ix Pixel index 210 + * @param[in] ix Pixel index
  211 + *
  212 + * @exception GException::fits_wrong_image_operator
  213 + * Image is not a 1D image
172 * 214 *
173 * Provides access to a pixel of a 1D image. No range checking is performed. 215 * Provides access to a pixel of a 1D image. No range checking is performed.
174 * Use the at(ix) method if range checking is required. 216 * Use the at(ix) method if range checking is required.
@@ -177,11 +219,11 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix) const @@ -177,11 +219,11 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix) const
177 { 219 {
178 // Operator is only valid for 1D images 220 // Operator is only valid for 1D images
179 if (m_naxis != 1) 221 if (m_naxis != 1)
180 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 1); 222 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 1);
181 223
182 // If image pixels are not available then allocate them now 224 // If image pixels are not available then allocate them now
183 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); 225 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
184 - 226 +
185 // Return image pixel 227 // Return image pixel
186 return m_pixels[ix]; 228 return m_pixels[ix];
187 } 229 }
@@ -190,8 +232,11 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix) const @@ -190,8 +232,11 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix) const
190 /***********************************************************************//** 232 /***********************************************************************//**
191 * @brief 2D image pixel access operator 233 * @brief 2D image pixel access operator
192 * 234 *
193 - * @param ix Pixel index in first dimension  
194 - * @param iy Pixel index in second dimension 235 + * @param[in] ix Pixel index in first dimension
  236 + * @param[in] iy Pixel index in second dimension
  237 + *
  238 + * @exception GException::fits_wrong_image_operator
  239 + * Image is not a 2D image
195 * 240 *
196 * Provides access to a pixel of a 2D image. No range checking is performed. 241 * Provides access to a pixel of a 2D image. No range checking is performed.
197 * Use the at(ix,iy) method if range checking is required. 242 * Use the at(ix,iy) method if range checking is required.
@@ -200,14 +245,14 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy) @@ -200,14 +245,14 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy)
200 { 245 {
201 // Operator is only valid for 2D images 246 // Operator is only valid for 2D images
202 if (m_naxis != 2) 247 if (m_naxis != 2)
203 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 2); 248 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 2);
204 249
205 // If image pixels are not available then allocate them now 250 // If image pixels are not available then allocate them now
206 if (m_pixels == NULL) fetch_pixels(); 251 if (m_pixels == NULL) fetch_pixels();
207 - 252 +
208 // Calculate pixel offset 253 // Calculate pixel offset
209 int offset = ix + iy * m_naxes[0]; 254 int offset = ix + iy * m_naxes[0];
210 - 255 +
211 // Return image pixel 256 // Return image pixel
212 return m_pixels[offset]; 257 return m_pixels[offset];
213 } 258 }
@@ -216,8 +261,11 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy) @@ -216,8 +261,11 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy)
216 /***********************************************************************//** 261 /***********************************************************************//**
217 * @brief 2D image pixel access operator (const variant) 262 * @brief 2D image pixel access operator (const variant)
218 * 263 *
219 - * @param ix Pixel index in first dimension  
220 - * @param iy Pixel index in second dimension 264 + * @param[in] ix Pixel index in first dimension
  265 + * @param[in] iy Pixel index in second dimension
  266 + *
  267 + * @exception GException::fits_wrong_image_operator
  268 + * Image is not a 2D image
221 * 269 *
222 * Provides access to a pixel of a 2D image. No range checking is performed. 270 * Provides access to a pixel of a 2D image. No range checking is performed.
223 * Use the at(ix,iy) method if range checking is required. 271 * Use the at(ix,iy) method if range checking is required.
@@ -226,14 +274,14 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy) const @@ -226,14 +274,14 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy) const
226 { 274 {
227 // Operator is only valid for 2D images 275 // Operator is only valid for 2D images
228 if (m_naxis != 2) 276 if (m_naxis != 2)
229 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 2); 277 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 2);
230 278
231 // If image pixels are not available then allocate them now 279 // If image pixels are not available then allocate them now
232 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); 280 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
233 - 281 +
234 // Calculate pixel offset 282 // Calculate pixel offset
235 int offset = ix + iy * m_naxes[0]; 283 int offset = ix + iy * m_naxes[0];
236 - 284 +
237 // Return image pixel 285 // Return image pixel
238 return m_pixels[offset]; 286 return m_pixels[offset];
239 } 287 }
@@ -242,9 +290,12 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy) const @@ -242,9 +290,12 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy) const
242 /***********************************************************************//** 290 /***********************************************************************//**
243 * @brief 3D image pixel access operator 291 * @brief 3D image pixel access operator
244 * 292 *
245 - * @param ix Pixel index in first dimension  
246 - * @param iy Pixel index in second dimension  
247 - * @param iz Pixel index in third dimension 293 + * @param[in] ix Pixel index in first dimension
  294 + * @param[in] iy Pixel index in second dimension
  295 + * @param[in] iz Pixel index in third dimension
  296 + *
  297 + * @exception GException::fits_wrong_image_operator
  298 + * Image is not a 3D image
248 * 299 *
249 * Provides access to a pixel of a 3D image. No range checking is performed. 300 * Provides access to a pixel of a 3D image. No range checking is performed.
250 * Use the at(ix,iy,iz) method if range checking is required. 301 * Use the at(ix,iy,iz) method if range checking is required.
@@ -253,14 +304,14 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz) @@ -253,14 +304,14 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz)
253 { 304 {
254 // Operator is only valid for 3D images 305 // Operator is only valid for 3D images
255 if (m_naxis != 3) 306 if (m_naxis != 3)
256 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 3); 307 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 3);
257 308
258 // If image pixels are not available then allocate them now 309 // If image pixels are not available then allocate them now
259 if (m_pixels == NULL) fetch_pixels(); 310 if (m_pixels == NULL) fetch_pixels();
260 - 311 +
261 // Calculate pixel offset 312 // Calculate pixel offset
262 int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]); 313 int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]);
263 - 314 +
264 // Return image pixel 315 // Return image pixel
265 return m_pixels[offset]; 316 return m_pixels[offset];
266 } 317 }
@@ -269,9 +320,12 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz) @@ -269,9 +320,12 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz)
269 /***********************************************************************//** 320 /***********************************************************************//**
270 * @brief 3D image pixel access operator (const variant) 321 * @brief 3D image pixel access operator (const variant)
271 * 322 *
272 - * @param ix Pixel index in first dimension  
273 - * @param iy Pixel index in second dimension  
274 - * @param iz Pixel index in third dimension 323 + * @param[in] ix Pixel index in first dimension
  324 + * @param[in] iy Pixel index in second dimension
  325 + * @param[in] iz Pixel index in third dimension
  326 + *
  327 + * @exception GException::fits_wrong_image_operator
  328 + * Image is not a 3D image
275 * 329 *
276 * Provides access to a pixel of a 3D image. No range checking is performed. 330 * Provides access to a pixel of a 3D image. No range checking is performed.
277 * Use the at(ix,iy,iz) method if range checking is required. 331 * Use the at(ix,iy,iz) method if range checking is required.
@@ -280,14 +334,14 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int @@ -280,14 +334,14 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int
280 { 334 {
281 // Operator is only valid for 3D images 335 // Operator is only valid for 3D images
282 if (m_naxis != 3) 336 if (m_naxis != 3)
283 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 3); 337 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 3);
284 338
285 // If image pixels are not available then allocate them now 339 // If image pixels are not available then allocate them now
286 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); 340 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
287 - 341 +
288 // Calculate pixel offset 342 // Calculate pixel offset
289 int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]); 343 int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]);
290 - 344 +
291 // Return image pixel 345 // Return image pixel
292 return m_pixels[offset]; 346 return m_pixels[offset];
293 } 347 }
@@ -296,10 +350,13 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int @@ -296,10 +350,13 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int
296 /***********************************************************************//** 350 /***********************************************************************//**
297 * @brief 4D image pixel access operator 351 * @brief 4D image pixel access operator
298 * 352 *
299 - * @param ix Pixel index in first dimension  
300 - * @param iy Pixel index in second dimension  
301 - * @param iz Pixel index in third dimension  
302 - * @param it Pixel index in forth dimension 353 + * @param[in] ix Pixel index in first dimension
  354 + * @param[in] iy Pixel index in second dimension
  355 + * @param[in] iz Pixel index in third dimension
  356 + * @param[in] it Pixel index in forth dimension
  357 + *
  358 + * @exception GException::fits_wrong_image_operator
  359 + * Image is not a 4D image
303 * 360 *
304 * Provides access to a pixel of a 4D image. No range checking is performed. 361 * Provides access to a pixel of a 4D image. No range checking is performed.
305 * Use the at(ix,iy,iz,it) method if range checking is required. 362 * Use the at(ix,iy,iz,it) method if range checking is required.
@@ -308,14 +365,14 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz, @@ -308,14 +365,14 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz,
308 { 365 {
309 // Operator is only valid for 4D images 366 // Operator is only valid for 4D images
310 if (m_naxis != 4) 367 if (m_naxis != 4)
311 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 4); 368 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 4);
312 369
313 // If image pixels are not available then allocate them now 370 // If image pixels are not available then allocate them now
314 if (m_pixels == NULL) fetch_pixels(); 371 if (m_pixels == NULL) fetch_pixels();
315 - 372 +
316 // Calculate pixel offset 373 // Calculate pixel offset
317 int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2])); 374 int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2]));
318 - 375 +
319 // Return image pixel 376 // Return image pixel
320 return m_pixels[offset]; 377 return m_pixels[offset];
321 } 378 }
@@ -324,10 +381,13 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz, @@ -324,10 +381,13 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int&amp; iz,
324 /***********************************************************************//** 381 /***********************************************************************//**
325 * @brief 4D image pixel access operator (const variant) 382 * @brief 4D image pixel access operator (const variant)
326 * 383 *
327 - * @param ix Pixel index in first dimension  
328 - * @param iy Pixel index in second dimension  
329 - * @param iz Pixel index in third dimension  
330 - * @param it Pixel index in forth dimension 384 + * @param[in] ix Pixel index in first dimension
  385 + * @param[in] iy Pixel index in second dimension
  386 + * @param[in] iz Pixel index in third dimension
  387 + * @param[in] it Pixel index in forth dimension
  388 + *
  389 + * @exception GException::fits_wrong_image_operator
  390 + * Image is not a 4D image
331 * 391 *
332 * Provides access to a pixel of a 4D image. No range checking is performed. 392 * Provides access to a pixel of a 4D image. No range checking is performed.
333 * Use the at(ix,iy,iz,it) method if range checking is required. 393 * Use the at(ix,iy,iz,it) method if range checking is required.
@@ -336,14 +396,14 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int @@ -336,14 +396,14 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy, const int
336 { 396 {
337 // Operator is only valid for 4D images 397 // Operator is only valid for 4D images
338 if (m_naxis != 4) 398 if (m_naxis != 4)
339 - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 4); 399 + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 4);
340 400
341 // If image pixels are not available then allocate them now 401 // If image pixels are not available then allocate them now
342 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); 402 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
343 - 403 +
344 // Calculate pixel offset 404 // Calculate pixel offset
345 int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2])); 405 int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2]));
346 - 406 +
347 // Return image pixel 407 // Return image pixel
348 return m_pixels[offset]; 408 return m_pixels[offset];
349 } 409 }
@@ -367,13 +427,13 @@ void GFitsDblImage::open(__fitsfile* fptr) @@ -367,13 +427,13 @@ void GFitsDblImage::open(__fitsfile* fptr)
367 { 427 {
368 // Initialise base class members 428 // Initialise base class members
369 GFitsImage::init_members(); 429 GFitsImage::init_members();
370 - 430 +
371 // Initialise class members 431 // Initialise class members
372 init_members(); 432 init_members();
373 - 433 +
374 // Open image 434 // Open image
375 open_image(fptr); 435 open_image(fptr);
376 - 436 +
377 // Return 437 // Return
378 return; 438 return;
379 } 439 }
@@ -398,10 +458,10 @@ void GFitsDblImage::link(double* pixels) @@ -398,10 +458,10 @@ void GFitsDblImage::link(double* pixels)
398 if (!m_linked) { 458 if (!m_linked) {
399 if (m_pixels != NULL) delete [] m_pixels; 459 if (m_pixels != NULL) delete [] m_pixels;
400 } 460 }
401 - 461 +
402 // Link pixel array to image 462 // Link pixel array to image
403 m_pixels = pixels; 463 m_pixels = pixels;
404 - 464 +
405 // Flag that pixels have been linked 465 // Flag that pixels have been linked
406 m_linked = 1; 466 m_linked = 1;
407 467
@@ -419,7 +479,7 @@ void GFitsDblImage::save(void) @@ -419,7 +479,7 @@ void GFitsDblImage::save(void)
419 { 479 {
420 // Save a double precision image 480 // Save a double precision image
421 save_image(__TDOUBLE, m_pixels); 481 save_image(__TDOUBLE, m_pixels);
422 - 482 +
423 // Return 483 // Return
424 return; 484 return;
425 } 485 }
@@ -442,10 +502,10 @@ void GFitsDblImage::close(void) @@ -442,10 +502,10 @@ void GFitsDblImage::close(void)
442 502
443 // Free base class members 503 // Free base class members
444 GFitsImage::free_members(); 504 GFitsImage::free_members();
445 - 505 +
446 // Initialise base class members 506 // Initialise base class members
447 GFitsImage::init_members(); 507 GFitsImage::init_members();
448 - 508 +
449 // Return 509 // Return
450 return; 510 return;
451 } 511 }
@@ -457,7 +517,7 @@ void GFitsDblImage::close(void) @@ -457,7 +517,7 @@ void GFitsDblImage::close(void)
457 * Cloning provides a copy of the FITS file. Cloning is used to allocate 517 * Cloning provides a copy of the FITS file. Cloning is used to allocate
458 * derived classes into a base class pointer. 518 * derived classes into a base class pointer.
459 ***************************************************************************/ 519 ***************************************************************************/
460 -GFitsDblImage* GFitsDblImage::clone(void) const 520 +GFitsDblImage* GFitsDblImage::clone(void) const
461 { 521 {
462 // Clone this image 522 // Clone this image
463 return new GFitsDblImage(*this); 523 return new GFitsDblImage(*this);
@@ -534,12 +594,12 @@ void GFitsDblImage::copy_members(const GFitsDblImage&amp; image) @@ -534,12 +594,12 @@ void GFitsDblImage::copy_members(const GFitsDblImage&amp; image)
534 // Copy attributes 594 // Copy attributes
535 m_linked = image.m_linked; 595 m_linked = image.m_linked;
536 m_anynul = image.m_anynul; 596 m_anynul = image.m_anynul;
537 - 597 +
538 // Copy pixels 598 // Copy pixels
539 if (m_linked) 599 if (m_linked)
540 m_pixels = image.m_pixels; 600 m_pixels = image.m_pixels;
541 else { 601 else {
542 - if (m_num_pixels > 0) { 602 + if (m_num_pixels > 0 && image.m_pixels != NULL) {
543 m_pixels = new double[m_num_pixels]; 603 m_pixels = new double[m_num_pixels];
544 memcpy(m_pixels, image.m_pixels, m_num_pixels*sizeof(double)); 604 memcpy(m_pixels, image.m_pixels, m_num_pixels*sizeof(double));
545 } 605 }
@@ -566,10 +626,10 @@ void GFitsDblImage::free_members(void) @@ -566,10 +626,10 @@ void GFitsDblImage::free_members(void)
566 if (!m_linked) { 626 if (!m_linked) {
567 if (m_pixels != NULL) delete [] m_pixels; 627 if (m_pixels != NULL) delete [] m_pixels;
568 } 628 }
569 - 629 +
570 // Free NULL value 630 // Free NULL value
571 if (m_nulval != NULL) delete m_nulval; 631 if (m_nulval != NULL) delete m_nulval;
572 - 632 +
573 // Mark memory as free 633 // Mark memory as free
574 m_linked = 0; 634 m_linked = 0;
575 m_pixels = NULL; 635 m_pixels = NULL;
@@ -602,14 +662,14 @@ void GFitsDblImage::fetch_pixels(void) @@ -602,14 +662,14 @@ void GFitsDblImage::fetch_pixels(void)
602 if (!m_linked) { 662 if (!m_linked) {
603 if (m_pixels != NULL) delete [] m_pixels; 663 if (m_pixels != NULL) delete [] m_pixels;
604 } 664 }
605 - 665 +
606 // Allocate fresh image pixels 666 // Allocate fresh image pixels
607 m_pixels = new double[m_num_pixels]; 667 m_pixels = new double[m_num_pixels];
608 668
609 // Case 1: A FITS is attached. Load pixels now. 669 // Case 1: A FITS is attached. Load pixels now.
610 if (m_fitsfile.Fptr != NULL) 670 if (m_fitsfile.Fptr != NULL)
611 load_image(__TDOUBLE, m_pixels, m_nulval, &m_anynul); 671 load_image(__TDOUBLE, m_pixels, m_nulval, &m_anynul);
612 - 672 +
613 // Case 2: No FITS file is attached. Allocate pixels and set them all to 0.0 673 // Case 2: No FITS file is attached. Allocate pixels and set them all to 0.0
614 else { 674 else {
615 for (int i = 0; i < m_num_pixels; ++i) 675 for (int i = 0; i < m_num_pixels; ++i)
src/fits/GFitsHDU.cpp
@@ -57,7 +57,10 @@ GFitsHDU::GFitsHDU() @@ -57,7 +57,10 @@ GFitsHDU::GFitsHDU()
57 /***********************************************************************//** 57 /***********************************************************************//**
58 * @brief Image HDU Constructor 58 * @brief Image HDU Constructor
59 * 59 *
60 - * @param image Image from which the HDU should be constructed 60 + * @param[in] image Image from which the HDU should be constructed
  61 + *
  62 + * Note that the HDU constructor copies the image, hence any change in the
  63 + * original object after copying will not be reflected in the copied object.
61 * 64 *
62 * IMPLEMENTATION NOT YET FINISHED (NEEDS KEYWORD SETTING) 65 * IMPLEMENTATION NOT YET FINISHED (NEEDS KEYWORD SETTING)
63 ***************************************************************************/ 66 ***************************************************************************/
@@ -65,15 +68,32 @@ GFitsHDU::GFitsHDU(const GFitsImage&amp; image) @@ -65,15 +68,32 @@ GFitsHDU::GFitsHDU(const GFitsImage&amp; image)
65 { 68 {
66 // Initialise class members for clean destruction 69 // Initialise class members for clean destruction
67 init_members(); 70 init_members();
68 - 71 +
69 // Copy image into HDU data 72 // Copy image into HDU data
70 m_data = image.clone(); 73 m_data = image.clone();
71 - 74 +
72 // Allocate new header 75 // Allocate new header
73 m_header = new GFitsHeader(); 76 m_header = new GFitsHeader();
74 -  
75 - // Extract keywords from image  
76 - // TBW 77 +
  78 + // Set image header keywords
  79 + m_header->update(GFitsHeaderCard("XTENSION", "'IMAGE '",
  80 + "IMAGE extension"));
  81 + m_header->update(GFitsHeaderCard("BITPIX", image.bitpix(),
  82 + "number of bits per data pixel"));
  83 + m_header->update(GFitsHeaderCard("NAXIS", image.naxis(),
  84 + "number of data axes"));
  85 + for (int i = 0; i < image.naxis(); ++i) {
  86 + ostringstream s_key;
  87 + ostringstream s_comment;
  88 + s_key << "NAXIS" << (i+1);
  89 + s_comment << "length of data axis " << (i+1);
  90 + m_header->update(GFitsHeaderCard(s_key.str(), image.naxes(i),
  91 + s_comment.str()));
  92 + }
  93 + m_header->update(GFitsHeaderCard("PCOUNT", 0,
  94 + "required keyword; must = 0"));
  95 + m_header->update(GFitsHeaderCard("GCOUNT", 1,
  96 + "required keyword; must = 1"));
77 97
78 // Return 98 // Return
79 return; 99 return;
@@ -202,7 +222,12 @@ void GFitsHDU::open(__fitsfile* fptr, int hdunum) @@ -202,7 +222,12 @@ void GFitsHDU::open(__fitsfile* fptr, int hdunum)
202 m_data->open(&m_fitsfile); 222 m_data->open(&m_fitsfile);
203 223
204 // Get HDU name from header 224 // Get HDU name from header
205 - m_name = strip_whitespace(m_header->string("EXTNAME")); 225 + try {
  226 + m_name = strip_whitespace(m_header->string("EXTNAME"));
  227 + }
  228 + catch (GException::fits_key_not_found) {
  229 + m_name.clear();
  230 + }
206 if (m_name.length() == 0) { 231 if (m_name.length() == 0) {
207 if (hdunum == 1) 232 if (hdunum == 1)
208 m_name = "Primary"; 233 m_name = "Primary";
@@ -230,7 +255,7 @@ void GFitsHDU::save(void) @@ -230,7 +255,7 @@ void GFitsHDU::save(void)
230 // Move to HDU 255 // Move to HDU
231 int status = 0; 256 int status = 0;
232 status = __ffmahd(&m_fitsfile, m_hdunum, NULL, &status); 257 status = __ffmahd(&m_fitsfile, m_hdunum, NULL, &status);
233 - 258 +
234 // If HDU does not yet exist in file then create it now. This works even 259 // If HDU does not yet exist in file then create it now. This works even
235 // in the case that the actual HDU has no associated header and/or data 260 // in the case that the actual HDU has no associated header and/or data
236 // (these will be created automatically). However, to make this work we have 261 // (these will be created automatically). However, to make this work we have
@@ -259,18 +284,18 @@ void GFitsHDU::save(void) @@ -259,18 +284,18 @@ void GFitsHDU::save(void)
259 } 284 }
260 } 285 }
261 } 286 }
262 - 287 +
263 // If they exist then save data and header 288 // If they exist then save data and header
264 if (m_data != NULL) { 289 if (m_data != NULL) {
265 m_data->save(); 290 m_data->save();
266 if (m_header != NULL) 291 if (m_header != NULL)
267 - m_header->save(); 292 + m_header->save(&m_fitsfile);
268 } 293 }
269 - 294 +
270 // ... otherwise make sure that the FITS file has at least a primary 295 // ... otherwise make sure that the FITS file has at least a primary
271 // image. 296 // image.
272 else { 297 else {
273 - 298 +
274 // Special case: The first HDU does not exist. A FITS file needs at least 299 // Special case: The first HDU does not exist. A FITS file needs at least
275 // one primary HDU. Thus an empty image is created. 300 // one primary HDU. Thus an empty image is created.
276 if (m_fitsfile.HDUposition == 0) { 301 if (m_fitsfile.HDUposition == 0) {
@@ -278,9 +303,9 @@ void GFitsHDU::save(void) @@ -278,9 +303,9 @@ void GFitsHDU::save(void)
278 if (status != 0) 303 if (status != 0)
279 throw GException::fits_error(G_SAVE, status); 304 throw GException::fits_error(G_SAVE, status);
280 if (m_header != NULL) 305 if (m_header != NULL)
281 - m_header->save(); 306 + m_header->save(&m_fitsfile);
282 } 307 }
283 - 308 +
284 } // endelse: no data were available 309 } // endelse: no data were available
285 310
286 // Return 311 // Return
@@ -289,6 +314,32 @@ void GFitsHDU::save(void) @@ -289,6 +314,32 @@ void GFitsHDU::save(void)
289 314
290 315
291 /***********************************************************************//** 316 /***********************************************************************//**
  317 + * @brief Set HDU extension name (EXTNAME keyword)
  318 + *
  319 + * @param extname Name of HDU
  320 + *
  321 + * This methos sets the extension name of the HDU. The extension name will
  322 + * be saved in the 'EXTNAME' header keyword. The header attached to the
  323 + * HDU will be automatically updated by this method.
  324 + ***************************************************************************/
  325 +void GFitsHDU::extname(const std::string& extname)
  326 +{
  327 + // Set extension name
  328 + m_name = extname;
  329 +
  330 + // If no header exists then create one now
  331 + if (m_header == NULL) m_header = new GFitsHeader();
  332 +
  333 + // Update header
  334 + m_header->update(GFitsHeaderCard("EXTNAME", extname,
  335 + "name of this extension"));
  336 +
  337 + // Return
  338 + return;
  339 +}
  340 +
  341 +
  342 +/***********************************************************************//**
292 * @brief Return pointer to column of table 343 * @brief Return pointer to column of table
293 * 344 *
294 * @param colname Name of FITS table column to be returned 345 * @param colname Name of FITS table column to be returned
@@ -329,20 +380,20 @@ void GFitsHDU::primary(void) @@ -329,20 +380,20 @@ void GFitsHDU::primary(void)
329 { 380 {
330 // Free any allocated header and data 381 // Free any allocated header and data
331 free_members(); 382 free_members();
332 - 383 +
333 // Create primary image in memory 384 // Create primary image in memory
334 int status = 0; 385 int status = 0;
335 __fitsfile* fptr; 386 __fitsfile* fptr;
336 status = __ffinit(&fptr, "mem://", &status); 387 status = __ffinit(&fptr, "mem://", &status);
337 status = __ffcrim(fptr, 8, 0, NULL, &status); 388 status = __ffcrim(fptr, 8, 0, NULL, &status);
338 - 389 +
339 // Open HDU 390 // Open HDU
340 this->open(fptr,1); 391 this->open(fptr,1);
341 - 392 +
342 // Detach FITS file pointer 393 // Detach FITS file pointer
343 this->m_fitsfile.HDUposition = 0; 394 this->m_fitsfile.HDUposition = 0;
344 this->m_fitsfile.Fptr = NULL; 395 this->m_fitsfile.Fptr = NULL;
345 - 396 +
346 // Return 397 // Return
347 return; 398 return;
348 } 399 }
@@ -429,10 +480,10 @@ void GFitsHDU::connect(__fitsfile* fptr) @@ -429,10 +480,10 @@ void GFitsHDU::connect(__fitsfile* fptr)
429 // First connect HDU 480 // First connect HDU
430 m_fitsfile = *fptr; 481 m_fitsfile = *fptr;
431 m_hdunum = m_fitsfile.HDUposition + 1; 482 m_hdunum = m_fitsfile.HDUposition + 1;
432 - 483 +
433 // Then connect data 484 // Then connect data
434 if (m_data != NULL) m_data->connect(fptr); 485 if (m_data != NULL) m_data->connect(fptr);
435 - 486 +
436 // Return 487 // Return
437 return; 488 return;
438 } 489 }
@@ -457,7 +508,7 @@ GFitsImage* GFitsHDU::new_image(void) @@ -457,7 +508,7 @@ GFitsImage* GFitsHDU::new_image(void)
457 { 508 {
458 // Initialise return value 509 // Initialise return value
459 GFitsImage* image = NULL; 510 GFitsImage* image = NULL;
460 - 511 +
461 // Get number of bits per pixel 512 // Get number of bits per pixel
462 int status = 0; 513 int status = 0;
463 int bitpix = -64; 514 int bitpix = -64;
@@ -528,11 +579,11 @@ ostream&amp; operator&lt;&lt; (ostream&amp; os, const GFitsHDU&amp; hdu) @@ -528,11 +579,11 @@ ostream&amp; operator&lt;&lt; (ostream&amp; os, const GFitsHDU&amp; hdu)
528 os << "Unknown" << endl; 579 os << "Unknown" << endl;
529 break; 580 break;
530 } 581 }
531 - 582 +
532 // Put FITS header in stream 583 // Put FITS header in stream
533 if (hdu.m_header != NULL) 584 if (hdu.m_header != NULL)
534 os << *hdu.m_header; 585 os << *hdu.m_header;
535 - 586 +
536 // Put FITS data in stream 587 // Put FITS data in stream
537 if (hdu.m_data != NULL) { 588 if (hdu.m_data != NULL) {
538 switch (hdu.m_type) { 589 switch (hdu.m_type) {
src/fits/GFitsHeader.cpp
@@ -20,7 +20,10 @@ @@ -20,7 +20,10 @@
20 /* __ Namespaces _________________________________________________________ */ 20 /* __ Namespaces _________________________________________________________ */
21 21
22 /* __ Method name definitions ____________________________________________ */ 22 /* __ Method name definitions ____________________________________________ */
23 -#define G_OPEN "GFitsHeader::open(int)" 23 +#define G_OPEN "GFitsHeader::open(fitsfile*)"
  24 +#define G_SAVE "GFitsHeader::save(fitsfile*)"
  25 +#define G_CARD "GFitsHeader::card(const int&)"
  26 +#define G_CARD_PTR "GFitsHeader::card_ptr(const std::string&)"
24 27
25 /* __ Macros _____________________________________________________________ */ 28 /* __ Macros _____________________________________________________________ */
26 29
@@ -36,9 +39,8 @@ @@ -36,9 +39,8 @@
36 = = 39 = =
37 ==========================================================================*/ 40 ==========================================================================*/
38 41
39 -/***************************************************************************  
40 - * Constructor *  
41 - * ----------------------------------------------------------------------- * 42 +/***********************************************************************//**
  43 + * @brief Constructor
42 ***************************************************************************/ 44 ***************************************************************************/
43 GFitsHeader::GFitsHeader() 45 GFitsHeader::GFitsHeader()
44 { 46 {
@@ -50,9 +52,10 @@ GFitsHeader::GFitsHeader() @@ -50,9 +52,10 @@ GFitsHeader::GFitsHeader()
50 } 52 }
51 53
52 54
53 -/***************************************************************************  
54 - * Copy constructor *  
55 - * ----------------------------------------------------------------------- * 55 +/***********************************************************************//**
  56 + * @brief Copy constructor
  57 + *
  58 + * @param header Header from which GFitsHeader instance should be built
56 ***************************************************************************/ 59 ***************************************************************************/
57 GFitsHeader::GFitsHeader(const GFitsHeader& header) 60 GFitsHeader::GFitsHeader(const GFitsHeader& header)
58 { 61 {
@@ -67,9 +70,8 @@ GFitsHeader::GFitsHeader(const GFitsHeader&amp; header) @@ -67,9 +70,8 @@ GFitsHeader::GFitsHeader(const GFitsHeader&amp; header)
67 } 70 }
68 71
69 72
70 -/***************************************************************************  
71 - * Destructor *  
72 - * ----------------------------------------------------------------------- * 73 +/***********************************************************************//**
  74 + * @brief Destructor
73 ***************************************************************************/ 75 ***************************************************************************/
74 GFitsHeader::~GFitsHeader() 76 GFitsHeader::~GFitsHeader()
75 { 77 {
@@ -87,9 +89,10 @@ GFitsHeader::~GFitsHeader() @@ -87,9 +89,10 @@ GFitsHeader::~GFitsHeader()
87 = = 89 = =
88 ==========================================================================*/ 90 ==========================================================================*/
89 91
90 -/***************************************************************************  
91 - * Assignment operator *  
92 - * ----------------------------------------------------------------------- * 92 +/***********************************************************************//**
  93 + * @brief Assignment operator
  94 + *
  95 + * @param header Header which should be assigned to GFitsHeader instance
93 ***************************************************************************/ 96 ***************************************************************************/
94 GFitsHeader& GFitsHeader::operator= (const GFitsHeader& header) 97 GFitsHeader& GFitsHeader::operator= (const GFitsHeader& header)
95 { 98 {
@@ -121,7 +124,7 @@ GFitsHeader&amp; GFitsHeader::operator= (const GFitsHeader&amp; header) @@ -121,7 +124,7 @@ GFitsHeader&amp; GFitsHeader::operator= (const GFitsHeader&amp; header)
121 /***********************************************************************//** 124 /***********************************************************************//**
122 * @brief Open Header 125 * @brief Open Header
123 * 126 *
124 - * @param fptr FITS file pointer 127 + * @param fptr Pointer to FITS file from which the header will be loaded
125 * 128 *
126 * Loads all header cards into memory. Any header cards that existed before 129 * Loads all header cards into memory. Any header cards that existed before
127 * will be dropped. 130 * will be dropped.
@@ -157,10 +160,38 @@ void GFitsHeader::open(__fitsfile* fptr) @@ -157,10 +160,38 @@ void GFitsHeader::open(__fitsfile* fptr)
157 /***********************************************************************//** 160 /***********************************************************************//**
158 * @brief Save Header to FITS file 161 * @brief Save Header to FITS file
159 * 162 *
160 - * NOT YET IMPLEMENTED 163 + * @param fptr Pointer to FITS file into which the header cards will be saved
  164 + *
  165 + * Saves all header cards into HDU. This method does not write the following
  166 + * mandatory keywords to the HDU (those will be writted by methods handling
  167 + * the data of the HDU):
  168 + * 'SIMPLE'
  169 + * 'BITPIX'
  170 + * 'NAXIS', 'NAXIS1', 'NAXIS2', etc.
  171 + * 'EXTEND'
  172 + * 'PCOUNT'
  173 + * 'GCOUNT'
161 ***************************************************************************/ 174 ***************************************************************************/
162 -void GFitsHeader::save(void) 175 +void GFitsHeader::save(__fitsfile* fptr)
163 { 176 {
  177 + // Move to HDU
  178 + int status = 0;
  179 + status = __ffmahd(fptr, (fptr->HDUposition)+1, NULL, &status);
  180 + if (status != 0)
  181 + throw GException::fits_error(G_SAVE, status);
  182 +
  183 + // Save all cards
  184 + for (int i = 0; i < m_num_cards; ++i) {
  185 + if (m_card[i].keyname() != "SIMPLE" &&
  186 + m_card[i].keyname() != "XTENSION" &&
  187 + m_card[i].keyname() != "BITPIX" &&
  188 + m_card[i].keyname() != "EXTEND" &&
  189 + m_card[i].keyname() != "PCOUNT" &&
  190 + m_card[i].keyname() != "GCOUNT" &&
  191 + m_card[i].keyname().find("NAXIS") == std::string::npos) {
  192 + m_card[i].write(fptr);
  193 + }
  194 + }
164 195
165 // Return 196 // Return
166 return; 197 return;
@@ -191,49 +222,95 @@ void GFitsHeader::close(void) @@ -191,49 +222,95 @@ void GFitsHeader::close(void)
191 * @brief Update card in header or append card to header 222 * @brief Update card in header or append card to header
192 * 223 *
193 * @param card FITS header card that should be updated 224 * @param card FITS header card that should be updated
194 - *  
195 - * This method updates one header card. Updating means replacing any  
196 - * existing card with the specified one or appending a new card to the  
197 - * list of existing cards. 225 + *
  226 + * This method updates one header card. Updating means replacing any
  227 + * existing card with the specified one or appending a new card to the
  228 + * list of existing cards.
198 ***************************************************************************/ 229 ***************************************************************************/
199 void GFitsHeader::update(const GFitsHeaderCard& card) 230 void GFitsHeader::update(const GFitsHeaderCard& card)
200 { 231 {
201 - // If card exists then update existing values  
202 - GFitsHeaderCard* ptr = this->card(card.keyname());  
203 - if (ptr != NULL)  
204 - *ptr = card;  
205 -  
206 - // ... otherwise append a new card  
207 - else {  
208 -  
209 - // Create memory to hold cards  
210 - GFitsHeaderCard* tmp = new GFitsHeaderCard[m_num_cards+1];  
211 - if (tmp != NULL) {  
212 -  
213 - // Copy over existing cards and remove old ones  
214 - if (m_card != NULL) {  
215 - for (int i = 0; i < m_num_cards; ++i)  
216 - tmp[i] = m_card[i];  
217 - delete [] m_card;  
218 - }  
219 -  
220 - // Connect the new memory to the card pointer  
221 - m_card = tmp;  
222 -  
223 - // Append new card to list  
224 - m_card[m_num_cards] = card;  
225 -  
226 - } // endif: new memory was valid  
227 - } // endif: card appending was required 232 + // If card keyname is not COMMENT or HISTORY, then check first if
  233 + // card exists. If yes then update existing card
  234 + if (card.keyname() != "COMMENT" && card.keyname() != "HISTORY") {
  235 + try {
  236 + GFitsHeaderCard* ptr = this->card(card.keyname());
  237 + *ptr = card;
  238 + return;
  239 + }
  240 + catch (GException::fits_key_not_found) {
  241 + ;
  242 + }
  243 + }
  244 +
  245 + // Create memory to hold cards
  246 + GFitsHeaderCard* tmp = new GFitsHeaderCard[m_num_cards+1];
  247 + if (tmp != NULL) {
  248 +
  249 + // Copy over existing cards and remove old ones
  250 + if (m_card != NULL) {
  251 + for (int i = 0; i < m_num_cards; ++i)
  252 + tmp[i] = m_card[i];
  253 + delete [] m_card;
  254 + }
  255 +
  256 + // Connect the new memory to the card pointer
  257 + m_card = tmp;
  258 +
  259 + // Append new card to list
  260 + m_card[m_num_cards] = card;
  261 +
  262 + // Increment number of cards
  263 + m_num_cards++;
  264 +
  265 + } // endif: new memory was valid
228 266
229 // Return 267 // Return
230 return; 268 return;
231 } 269 }
232 270
233 271
234 -/***************************************************************************  
235 - * Get specified header card value as string *  
236 - * ----------------------------------------------------------------------- * 272 +/***********************************************************************//**
  273 + * @brief Return pointer of header card
  274 + *
  275 + * @param[in] keyname Name of header card
  276 + *
  277 + * Returns a pointer on the header card.
  278 + * If card was not found a 'fits_key_not_found' error will be thrown.
  279 + ***************************************************************************/
  280 +GFitsHeaderCard* GFitsHeader::card(const std::string& keyname)
  281 +{
  282 + return GFitsHeader::card_ptr(keyname);
  283 +}
  284 +
  285 +
  286 +/***********************************************************************//**
  287 + * @brief Return pointer of header card
  288 + *
  289 + * @param[in] keyname Name of header card
  290 + *
  291 + * Returns a pointer on the header card.
  292 + * If card was not found a 'out_of_range' error will be thrown.
  293 + ***************************************************************************/
  294 +GFitsHeaderCard* GFitsHeader::card(const int& cardno)
  295 +{
  296 + // If card number is out of range then throw an exception
  297 + if (cardno < 0 || cardno >= m_num_cards)
  298 + throw GException::out_of_range(G_CARD, cardno, 0, m_num_cards-1);
  299 +
  300 + // Get card pointer
  301 + GFitsHeaderCard* ptr = &(m_card[cardno]);
  302 +
  303 + // Return pointer
  304 + return ptr;
  305 +}
  306 +
  307 +
  308 +/***********************************************************************//**
  309 + * @brief Get specified header card value as string
  310 + *
  311 + * @param[in] keyname Name of header card
  312 + *
  313 + * If the header card is not found an empty string is returned.
237 ***************************************************************************/ 314 ***************************************************************************/
238 std::string GFitsHeader::string(const std::string& keyname) 315 std::string GFitsHeader::string(const std::string& keyname)
239 { 316 {
@@ -248,9 +325,12 @@ std::string GFitsHeader::string(const std::string&amp; keyname) @@ -248,9 +325,12 @@ std::string GFitsHeader::string(const std::string&amp; keyname)
248 } 325 }
249 326
250 327
251 -/***************************************************************************  
252 - * Get specified header card value as string *  
253 - * ----------------------------------------------------------------------- * 328 +/***********************************************************************//**
  329 + * @brief Get specified header card value as string
  330 + *
  331 + * @param[in] cardno Header card number (starting from 0)
  332 + *
  333 + * If the header card number does not exist an empty string is returned.
254 ***************************************************************************/ 334 ***************************************************************************/
255 std::string GFitsHeader::string(const int& cardno) 335 std::string GFitsHeader::string(const int& cardno)
256 { 336 {
@@ -265,9 +345,12 @@ std::string GFitsHeader::string(const int&amp; cardno) @@ -265,9 +345,12 @@ std::string GFitsHeader::string(const int&amp; cardno)
265 } 345 }
266 346
267 347
268 -/***************************************************************************  
269 - * Get specified header card value as double *  
270 - * ----------------------------------------------------------------------- * 348 +/***********************************************************************//**
  349 + * @brief Get specified header card value as double precision value
  350 + *
  351 + * @param[in] keyname Name of header card
  352 + *
  353 + * If the header card is not found 0 is returned.
271 ***************************************************************************/ 354 ***************************************************************************/
272 double GFitsHeader::real(const std::string& keyname) 355 double GFitsHeader::real(const std::string& keyname)
273 { 356 {
@@ -282,9 +365,12 @@ double GFitsHeader::real(const std::string&amp; keyname) @@ -282,9 +365,12 @@ double GFitsHeader::real(const std::string&amp; keyname)
282 } 365 }
283 366
284 367
285 -/***************************************************************************  
286 - * Get specified header card value as double *  
287 - * ----------------------------------------------------------------------- * 368 +/***********************************************************************//**
  369 + * @brief Get specified header card value as double precision value
  370 + *
  371 + * @param[in] cardno Header card number (starting from 0)
  372 + *
  373 + * If the header card number does not exist 0 is returned.
288 ***************************************************************************/ 374 ***************************************************************************/
289 double GFitsHeader::real(const int& cardno) 375 double GFitsHeader::real(const int& cardno)
290 { 376 {
@@ -299,9 +385,12 @@ double GFitsHeader::real(const int&amp; cardno) @@ -299,9 +385,12 @@ double GFitsHeader::real(const int&amp; cardno)
299 } 385 }
300 386
301 387
302 -/***************************************************************************  
303 - * Get specified header card value as int *  
304 - * ----------------------------------------------------------------------- * 388 +/***********************************************************************//**
  389 + * @brief Get specified header card value as integer value
  390 + *
  391 + * @param keyname Name of header card
  392 + *
  393 + * If the header card is not found 0 is returned.
305 ***************************************************************************/ 394 ***************************************************************************/
306 int GFitsHeader::integer(const std::string& keyname) 395 int GFitsHeader::integer(const std::string& keyname)
307 { 396 {
@@ -316,9 +405,12 @@ int GFitsHeader::integer(const std::string&amp; keyname) @@ -316,9 +405,12 @@ int GFitsHeader::integer(const std::string&amp; keyname)
316 } 405 }
317 406
318 407
319 -/***************************************************************************  
320 - * Get specified header card value as int *  
321 - * ----------------------------------------------------------------------- * 408 +/***********************************************************************//**
  409 + * @brief Get specified header card value as integer value
  410 + *
  411 + * @param[in] cardno Header card number (starting from 0)
  412 + *
  413 + * If the header card number does not exist 0 is returned.
322 ***************************************************************************/ 414 ***************************************************************************/
323 int GFitsHeader::integer(const int& cardno) 415 int GFitsHeader::integer(const int& cardno)
324 { 416 {
@@ -333,15 +425,23 @@ int GFitsHeader::integer(const int&amp; cardno) @@ -333,15 +425,23 @@ int GFitsHeader::integer(const int&amp; cardno)
333 } 425 }
334 426
335 427
  428 +/***********************************************************************//**
  429 + * @brief Clone header object
  430 + ***************************************************************************/
  431 +GFitsHeader* GFitsHeader::clone(void) const
  432 +{
  433 + return new GFitsHeader(*this);
  434 +}
  435 +
  436 +
336 /*========================================================================== 437 /*==========================================================================
337 = = 438 = =
338 = GFitsHeader private methods = 439 = GFitsHeader private methods =
339 = = 440 = =
340 ==========================================================================*/ 441 ==========================================================================*/
341 442
342 -/***************************************************************************  
343 - * Initialise class members *  
344 - * ----------------------------------------------------------------------- * 443 +/***********************************************************************//**
  444 + * @brief Initialise class members
345 ***************************************************************************/ 445 ***************************************************************************/
346 void GFitsHeader::init_members(void) 446 void GFitsHeader::init_members(void)
347 { 447 {
@@ -354,18 +454,19 @@ void GFitsHeader::init_members(void) @@ -354,18 +454,19 @@ void GFitsHeader::init_members(void)
354 } 454 }
355 455
356 456
357 -/***************************************************************************  
358 - * Copy class members *  
359 - * ----------------------------------------------------------------------- * 457 +/***********************************************************************//**
  458 + * @brief Copy class members
  459 + *
  460 + * @param[in] header Header which should be copied
360 ***************************************************************************/ 461 ***************************************************************************/
361 void GFitsHeader::copy_members(const GFitsHeader& header) 462 void GFitsHeader::copy_members(const GFitsHeader& header)
362 { 463 {
363 // Copy attributes 464 // Copy attributes
  465 + m_num_cards = header.m_num_cards;
364 466
365 // Copy cards 467 // Copy cards
366 - if (header.m_card != NULL && header.m_num_cards > 0) {  
367 - m_num_cards = header.m_num_cards;  
368 - m_card = new GFitsHeaderCard[m_num_cards]; 468 + if (header.m_card != NULL && m_num_cards > 0) {
  469 + m_card = new GFitsHeaderCard[m_num_cards];
369 for (int i = 0; i < m_num_cards; ++i) 470 for (int i = 0; i < m_num_cards; ++i)
370 m_card[i] = header.m_card[i]; 471 m_card[i] = header.m_card[i];
371 } 472 }
@@ -375,9 +476,8 @@ void GFitsHeader::copy_members(const GFitsHeader&amp; header) @@ -375,9 +476,8 @@ void GFitsHeader::copy_members(const GFitsHeader&amp; header)
375 } 476 }
376 477
377 478
378 -/***************************************************************************  
379 - * Delete class members *  
380 - * ----------------------------------------------------------------------- * 479 +/***********************************************************************//**
  480 + * @brief Delete class members
381 ***************************************************************************/ 481 ***************************************************************************/
382 void GFitsHeader::free_members(void) 482 void GFitsHeader::free_members(void)
383 { 483 {
@@ -392,11 +492,15 @@ void GFitsHeader::free_members(void) @@ -392,11 +492,15 @@ void GFitsHeader::free_members(void)
392 } 492 }
393 493
394 494
395 -/***************************************************************************  
396 - * Get card pointer *  
397 - * ----------------------------------------------------------------------- * 495 +/***********************************************************************//**
  496 + * @brief Get pointer on header card
  497 + *
  498 + * @param[in] keyname Name of the header card
  499 + *
  500 + * Returns a pointer on the header card.
  501 + * If card was not found a 'fits_key_not_found' error will be thrown.
398 ***************************************************************************/ 502 ***************************************************************************/
399 -GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname) 503 +GFitsHeaderCard* GFitsHeader::card_ptr(const std::string& keyname)
400 { 504 {
401 505
402 // Set card pointer to NULL (default) 506 // Set card pointer to NULL (default)
@@ -410,6 +514,10 @@ GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname) @@ -410,6 +514,10 @@ GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname)
410 } 514 }
411 } 515 }
412 516
  517 + // If no card was found then throw an error
  518 + if (ptr == NULL)
  519 + throw GException::fits_key_not_found(G_CARD_PTR, keyname);
  520 +
413 // Return pointer 521 // Return pointer
414 return ptr; 522 return ptr;
415 } 523 }
@@ -421,15 +529,16 @@ GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname) @@ -421,15 +529,16 @@ GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname)
421 = = 529 = =
422 ==========================================================================*/ 530 ==========================================================================*/
423 531
424 -/***************************************************************************  
425 - * Output operator *  
426 - * ----------------------------------------------------------------------- * 532 +/***********************************************************************//**
  533 + * @brief Output operator
  534 + *
  535 + * @param[in] os Output stream
  536 + * @param[in] header Header to put in output stream
427 ***************************************************************************/ 537 ***************************************************************************/
428 ostream& operator<< (ostream& os, const GFitsHeader& header) 538 ostream& operator<< (ostream& os, const GFitsHeader& header)
429 { 539 {
430 // Put header in stream 540 // Put header in stream
431 - os << "=== GFitsHeader ===" << endl;  
432 - os << " Number of cards ...........: " << header.m_num_cards << endl; 541 + os << "=== GFitsHeader (" << header.m_num_cards << " cards) ===" << endl;
433 for (int i = 0; i < header.m_num_cards; ++i) 542 for (int i = 0; i < header.m_num_cards; ++i)
434 os << " " << header.m_card[i]; 543 os << " " << header.m_card[i];
435 544
src/fits/GFitsHeaderCard.cpp
@@ -48,9 +48,8 @@ @@ -48,9 +48,8 @@
48 = = 48 = =
49 ==========================================================================*/ 49 ==========================================================================*/
50 50
51 -/***************************************************************************  
52 - * Constructor *  
53 - * ----------------------------------------------------------------------- * 51 +/***********************************************************************//**
  52 + * @brief Constructor
54 ***************************************************************************/ 53 ***************************************************************************/
55 GFitsHeaderCard::GFitsHeaderCard() 54 GFitsHeaderCard::GFitsHeaderCard()
56 { 55 {
@@ -60,26 +59,91 @@ GFitsHeaderCard::GFitsHeaderCard() @@ -60,26 +59,91 @@ GFitsHeaderCard::GFitsHeaderCard()
60 // Return 59 // Return
61 return; 60 return;
62 } 61 }
63 -GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,  
64 - const std::string& value, 62 +
  63 +
  64 +/***********************************************************************//**
  65 + * @brief Constructor for string cards
  66 + *
  67 + * @param[in] keyname Name of the header card
  68 + * @param[in] value String value of the header card
  69 + * @param[in] comment Comment of the header card
  70 + *
  71 + * This constructor builds a header card from the keyname, value and comment.
  72 + ***************************************************************************/
  73 +GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
  74 + const std::string& value,
65 const std::string& comment) 75 const std::string& comment)
66 { 76 {
67 // Initialise class members for clean destruction 77 // Initialise class members for clean destruction
68 init_members(); 78 init_members();
69 - 79 +
70 // Set members 80 // Set members
71 - this->set_keyname(keyname);  
72 - this->set_value(value);  
73 - this->set_comment(comment); 81 + this->keyname(keyname);
  82 + this->value(value);
  83 + this->comment(comment);
74 84
75 // Return 85 // Return
76 return; 86 return;
77 } 87 }
78 88
79 89
80 -/***************************************************************************  
81 - * Copy constructor *  
82 - * ----------------------------------------------------------------------- * 90 +/***********************************************************************//**
  91 + * @brief Constructor for floating point cards
  92 + *
  93 + * @param[in] keyname Name of the header card
  94 + * @param[in] value Floating point value of the header card
  95 + * @param[in] comment Comment of the header card
  96 + *
  97 + * This constructor builds a header card from the keyname, value and comment.
  98 + ***************************************************************************/
  99 +GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
  100 + const double& value,
  101 + const std::string& comment)
  102 +{
  103 + // Initialise class members for clean destruction
  104 + init_members();
  105 +
  106 + // Set members
  107 + this->keyname(keyname);
  108 + this->value(value);
  109 + this->comment(comment);
  110 +
  111 + // Return
  112 + return;
  113 +}
  114 +
  115 +
  116 +/***********************************************************************//**
  117 + * @brief Constructor for integer cards
  118 + *
  119 + * @param[in] keyname Name of the header card
  120 + * @param[in] value Integer value of the header card
  121 + * @param[in] comment Comment of the header card
  122 + *
  123 + * This constructor builds a header card from the keyname, value and comment.
  124 + ***************************************************************************/
  125 +GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
  126 + const int& value,
  127 + const std::string& comment)
  128 +{
  129 + // Initialise class members for clean destruction
  130 + init_members();
  131 +
  132 + // Set members
  133 + this->keyname(keyname);
  134 + this->value(value);
  135 + this->comment(comment);
  136 +
  137 + // Return
  138 + return;
  139 +}
  140 +
  141 +
  142 +/***********************************************************************//**
  143 + * @brief Copy constructor
  144 + *
  145 + * @param card[in] Header card that will be used to construct GFitsHeaderCard
  146 + * instance
83 ***************************************************************************/ 147 ***************************************************************************/
84 GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard& card) 148 GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard& card)
85 { 149 {
@@ -94,9 +158,8 @@ GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard&amp; card) @@ -94,9 +158,8 @@ GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard&amp; card)
94 } 158 }
95 159
96 160
97 -/***************************************************************************  
98 - * Destructor *  
99 - * ----------------------------------------------------------------------- * 161 +/***********************************************************************//**
  162 + * @brief Destructor
100 ***************************************************************************/ 163 ***************************************************************************/
101 GFitsHeaderCard::~GFitsHeaderCard() 164 GFitsHeaderCard::~GFitsHeaderCard()
102 { 165 {
@@ -113,24 +176,26 @@ GFitsHeaderCard::~GFitsHeaderCard() @@ -113,24 +176,26 @@ GFitsHeaderCard::~GFitsHeaderCard()
113 = = 176 = =
114 ==========================================================================*/ 177 ==========================================================================*/
115 178
116 -/***************************************************************************  
117 - * Assignment operator *  
118 - * ----------------------------------------------------------------------- * 179 +/***********************************************************************//**
  180 + * @brief Assignment operator
  181 + *
  182 + * @param card[in] Header card that will be assigned to GFitsHeaderCard
  183 + * instance
119 ***************************************************************************/ 184 ***************************************************************************/
120 GFitsHeaderCard& GFitsHeaderCard::operator= (const GFitsHeaderCard& card) 185 GFitsHeaderCard& GFitsHeaderCard::operator= (const GFitsHeaderCard& card)
121 { 186 {
122 // Execute only if object is not identical 187 // Execute only if object is not identical
123 if (this != &card) { 188 if (this != &card) {
124 - 189 +
125 // Free members 190 // Free members
126 free_members(); 191 free_members();
127 - 192 +
128 // Initialise private members for clean destruction 193 // Initialise private members for clean destruction
129 init_members(); 194 init_members();
130 195
131 // Copy members 196 // Copy members
132 copy_members(card); 197 copy_members(card);
133 - 198 +
134 } // endif: object was not identical 199 } // endif: object was not identical
135 200
136 // Return this object 201 // Return this object
@@ -144,9 +209,174 @@ GFitsHeaderCard&amp; GFitsHeaderCard::operator= (const GFitsHeaderCard&amp; card) @@ -144,9 +209,174 @@ GFitsHeaderCard&amp; GFitsHeaderCard::operator= (const GFitsHeaderCard&amp; card)
144 = = 209 = =
145 ==========================================================================*/ 210 ==========================================================================*/
146 211
147 -/***************************************************************************  
148 - * Return value as string *  
149 - * ----------------------------------------------------------------------- * 212 +/***********************************************************************//**
  213 + * @brief Set name of header card
  214 + *
  215 + * @param[in] keyname Name of header card
  216 + ***************************************************************************/
  217 +void GFitsHeaderCard::keyname(const std::string& keyname)
  218 +{
  219 + // Set name of card
  220 + m_keyname = keyname;
  221 +
  222 + // Return
  223 + return;
  224 +}
  225 +
  226 +
  227 +/***********************************************************************//**
  228 + * @brief Set string value of header card
  229 + *
  230 + * @param[in] value String value of header card
  231 + ***************************************************************************/
  232 +void GFitsHeaderCard::value(const std::string& value)
  233 +{
  234 + // Set value and value type
  235 + m_value = value;
  236 + m_value_type = get_value_type(value);
  237 +
  238 + // Attach hyphens if required
  239 + if (m_value_type == CT_STRING) {
  240 + if (m_value[0] != '\x27')
  241 + m_value = "'" + m_value;
  242 + if (m_value[m_value.length()-1] != '\x27')
  243 + m_value += "'";
  244 + }
  245 +
  246 + // Return
  247 + return;
  248 +}
  249 +
  250 +
  251 +/***********************************************************************//**
  252 + * @brief Set floating point value of header card
  253 + *
  254 + * @param[in] value Floating point value of header card
  255 + ***************************************************************************/
  256 +void GFitsHeaderCard::value(const double& value)
  257 +{
  258 + // Convert value to string
  259 + ostringstream s_value;
  260 + s_value << scientific << value;
  261 +
  262 + // Assign value
  263 + m_value = s_value.str();
  264 +
  265 + // Set value type
  266 + m_value_type = get_value_type(m_value);
  267 +
  268 + // Return
  269 + return;
  270 +}
  271 +
  272 +
  273 +/***********************************************************************//**
  274 + * @brief Set integer value of header card
  275 + *
  276 + * @param[in] value Integer value of header card
  277 + ***************************************************************************/
  278 +void GFitsHeaderCard::value(const int& value)
  279 +{
  280 + // Convert value to string
  281 + ostringstream s_value;
  282 + s_value << value;
  283 +
  284 + // Assign value
  285 + m_value = s_value.str();
  286 +
  287 + // Set value type
  288 + m_value_type = get_value_type(m_value);
  289 +
  290 + // Return
  291 + return;
  292 +}
  293 +
  294 +
  295 +/***********************************************************************//**
  296 + * @brief Set unit of header card value
  297 + *
  298 + * @param[in] value Unit of header card
  299 + ***************************************************************************/
  300 +void GFitsHeaderCard::unit(const std::string& unit)
  301 +{
  302 + // Set unit
  303 + m_unit = unit;
  304 +
  305 + // Return
  306 + return;
  307 +}
  308 +
  309 +
  310 +/***********************************************************************//**
  311 + * @brief Set comment of header card
  312 + *
  313 + * @param[in] value Header card comment
  314 + ***************************************************************************/
  315 +void GFitsHeaderCard::comment(const std::string& comment)
  316 +{
  317 + // Set comment
  318 + m_comment = comment;
  319 +
  320 + // Return
  321 + return;
  322 +}
  323 +
  324 +
  325 +/***********************************************************************//**
  326 + * @brief Return header card keyname
  327 + ***************************************************************************/
  328 +std::string GFitsHeaderCard::keyname(void) const
  329 +{
  330 + // Return
  331 + return m_keyname;
  332 +}
  333 +
  334 +
  335 +/***********************************************************************//**
  336 + * @brief Return header card value
  337 + ***************************************************************************/
  338 +std::string GFitsHeaderCard::value(void) const
  339 +{
  340 + // Return
  341 + return m_value;
  342 +}
  343 +
  344 +
  345 +/***********************************************************************//**
  346 + * @brief Return header card value type
  347 + ***************************************************************************/
  348 +int GFitsHeaderCard::value_type(void) const
  349 +{
  350 + // Return
  351 + return m_value_type;
  352 +}
  353 +
  354 +
  355 +/***********************************************************************//**
  356 + * @brief Return header card value unit
  357 + ***************************************************************************/
  358 +std::string GFitsHeaderCard::unit(void) const
  359 +{
  360 + // Return
  361 + return m_unit;
  362 +}
  363 +
  364 +
  365 +/***********************************************************************//**
  366 + * @brief Return header card comment
  367 + ***************************************************************************/
  368 +std::string GFitsHeaderCard::comment(void) const
  369 +{
  370 + // Return
  371 + return m_comment;
  372 +}
  373 +
  374 +
  375 +/***********************************************************************//**
  376 + * @brief Return header card value as string
  377 + *
  378 + * Convert header card value into a string.
  379 + * Any hyphens that may occur in the FITS card will be automatically stripped.
150 ***************************************************************************/ 380 ***************************************************************************/
151 std::string GFitsHeaderCard::string(void) 381 std::string GFitsHeaderCard::string(void)
152 { 382 {
@@ -174,9 +404,12 @@ std::string GFitsHeaderCard::string(void) @@ -174,9 +404,12 @@ std::string GFitsHeaderCard::string(void)
174 } 404 }
175 405
176 406
177 -/***************************************************************************  
178 - * Return value as double *  
179 - * ----------------------------------------------------------------------- * 407 +/***********************************************************************//**
  408 + * @brief Return header card value as double precision
  409 + *
  410 + * Convert header card value into a double precision value. In case that the
  411 + * card did not contain a numerical value, 0 will be returned by the
  412 + * method.
180 ***************************************************************************/ 413 ***************************************************************************/
181 double GFitsHeaderCard::real(void) 414 double GFitsHeaderCard::real(void)
182 { 415 {
@@ -206,9 +439,12 @@ double GFitsHeaderCard::real(void) @@ -206,9 +439,12 @@ double GFitsHeaderCard::real(void)
206 } 439 }
207 440
208 441
209 -/***************************************************************************  
210 - * Return value as int *  
211 - * ----------------------------------------------------------------------- * 442 +/***********************************************************************//**
  443 + * @brief Return header card value as integer
  444 +*
  445 + * Convert header card value into a integer value. In case that the
  446 + * card did not contain a numerical value, 0 will be returned by the
  447 + * method.
212 ***************************************************************************/ 448 ***************************************************************************/
213 int GFitsHeaderCard::integer(void) 449 int GFitsHeaderCard::integer(void)
214 { 450 {
@@ -238,9 +474,11 @@ int GFitsHeaderCard::integer(void) @@ -238,9 +474,11 @@ int GFitsHeaderCard::integer(void)
238 } 474 }
239 475
240 476
241 -/***************************************************************************  
242 - * Read header card *  
243 - * ----------------------------------------------------------------------- * 477 +/***********************************************************************//**
  478 + * @brief Read header card from FITS file
  479 + *
  480 + * @param[in] fptr Pointer to FITS file from which the card is read
  481 + * @param[in] keynum Number of the header card
244 ***************************************************************************/ 482 ***************************************************************************/
245 void GFitsHeaderCard::read(__fitsfile* fptr, int keynum) 483 void GFitsHeaderCard::read(__fitsfile* fptr, int keynum)
246 { 484 {
@@ -264,18 +502,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, int keynum) @@ -264,18 +502,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, int keynum)
264 m_comment.assign(comment); 502 m_comment.assign(comment);
265 503
266 // Determine card type 504 // Determine card type
267 - m_value_type = get_value_type(); 505 + m_value_type = get_value_type(m_value);
268 506
269 // Return 507 // Return
270 return; 508 return;
271 } 509 }
272 510
273 511
274 -/***************************************************************************  
275 - * Read header card *  
276 - * ----------------------------------------------------------------------- * 512 +/***********************************************************************//**
  513 + * @brief Read header card from FITS file
  514 + *
  515 + * @param[in] fptr Pointer to FITS file from which the card is read
  516 + * @param[in] keyname Name of the header card
277 ***************************************************************************/ 517 ***************************************************************************/
278 -void GFitsHeaderCard::read(__fitsfile* fptr, std::string keyname) 518 +void GFitsHeaderCard::read(__fitsfile* fptr, const std::string& keyname)
279 { 519 {
280 // Move to HDU 520 // Move to HDU
281 int status = 0; 521 int status = 0;
@@ -300,16 +540,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, std::string keyname) @@ -300,16 +540,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, std::string keyname)
300 m_comment.assign(comment); 540 m_comment.assign(comment);
301 541
302 // Determine card type 542 // Determine card type
303 - m_value_type = get_value_type(); 543 + m_value_type = get_value_type(m_value);
304 544
305 // Return 545 // Return
306 return; 546 return;
307 } 547 }
308 548
309 549
310 -/***************************************************************************  
311 - * Write header card *  
312 - * ----------------------------------------------------------------------- * 550 +/***********************************************************************//**
  551 + * @brief Write header card
  552 + *
  553 + * @param fptr[in] Pointer to FITS file into which the header card should be
  554 + * written
  555 + *
  556 + * Writes any kind of header card to a FITS file.
313 ***************************************************************************/ 557 ***************************************************************************/
314 void GFitsHeaderCard::write(__fitsfile* fptr) 558 void GFitsHeaderCard::write(__fitsfile* fptr)
315 { 559 {
@@ -336,9 +580,8 @@ void GFitsHeaderCard::write(__fitsfile* fptr) @@ -336,9 +580,8 @@ void GFitsHeaderCard::write(__fitsfile* fptr)
336 = = 580 = =
337 ==========================================================================*/ 581 ==========================================================================*/
338 582
339 -/***************************************************************************  
340 - * Initialise class members *  
341 - * ----------------------------------------------------------------------- * 583 +/***********************************************************************//**
  584 + * @brief Initialise class members
342 ***************************************************************************/ 585 ***************************************************************************/
343 void GFitsHeaderCard::init_members(void) 586 void GFitsHeaderCard::init_members(void)
344 { 587 {
@@ -354,9 +597,10 @@ void GFitsHeaderCard::init_members(void) @@ -354,9 +597,10 @@ void GFitsHeaderCard::init_members(void)
354 } 597 }
355 598
356 599
357 -/***************************************************************************  
358 - * Copy class members *  
359 - * ----------------------------------------------------------------------- * 600 +/***********************************************************************//**
  601 + * @brief Copy class members
  602 + *
  603 + * @param[in] card Header card to be copied
360 ***************************************************************************/ 604 ***************************************************************************/
361 void GFitsHeaderCard::copy_members(const GFitsHeaderCard& card) 605 void GFitsHeaderCard::copy_members(const GFitsHeaderCard& card)
362 { 606 {
@@ -372,9 +616,8 @@ void GFitsHeaderCard::copy_members(const GFitsHeaderCard&amp; card) @@ -372,9 +616,8 @@ void GFitsHeaderCard::copy_members(const GFitsHeaderCard&amp; card)
372 } 616 }
373 617
374 618
375 -/***************************************************************************  
376 - * Delete class members *  
377 - * ----------------------------------------------------------------------- * 619 +/***********************************************************************//**
  620 + * @brief Delete class members
378 ***************************************************************************/ 621 ***************************************************************************/
379 void GFitsHeaderCard::free_members(void) 622 void GFitsHeaderCard::free_members(void)
380 { 623 {
@@ -383,11 +626,25 @@ void GFitsHeaderCard::free_members(void) @@ -383,11 +626,25 @@ void GFitsHeaderCard::free_members(void)
383 } 626 }
384 627
385 628
386 -/***************************************************************************  
387 - * Determine card value type *  
388 - * ----------------------------------------------------------------------- * 629 +/***********************************************************************//**
  630 + * @brief Determine card value type
  631 + *
  632 + * @param[in] value Value string for which the type should be determined
  633 + *
  634 + * Method that determines the type of the card value. The following types are
  635 + * defined:
  636 + * CT_UNKNOWN=0 (inknown type)
  637 + * CT_INVALID=1 (invalid type)
  638 + * CT_STRING=2 (string)
  639 + * CT_INT=3 (integer)
  640 + * CT_FLOAT=4 (floating point)
  641 + * CT_BOOL=5 (boolean)
  642 + * CT_COMMENT=6 (comment)
  643 + * CT_HISTORY=7 (history)
  644 + * The type is determined by analyzing the card value. It is stored in the
  645 + * private variable 'm_value_type'.
389 ***************************************************************************/ 646 ***************************************************************************/
390 -int GFitsHeaderCard::get_value_type(void) 647 +int GFitsHeaderCard::get_value_type(const std::string& value)
391 { 648 {
392 // Get index of last string element 649 // Get index of last string element
393 int last = m_value.length() - 1; 650 int last = m_value.length() - 1;
@@ -417,7 +674,8 @@ int GFitsHeaderCard::get_value_type(void) @@ -417,7 +674,8 @@ int GFitsHeaderCard::get_value_type(void)
417 int found_int = 0; 674 int found_int = 0;
418 int found_float = 0; 675 int found_float = 0;
419 for (int i = 0; i <= last; ++i) { 676 for (int i = 0; i <= last; ++i) {
420 - if ((m_value[i] >= '0' && m_value[i] <= '9') || m_value[i] == '+' || m_value[i] == '-') 677 + if ((m_value[i] >= '0' && m_value[i] <= '9') || m_value[i] == '+' ||
  678 + m_value[i] == '-')
421 found_int = 1; 679 found_int = 1;
422 else if (m_value[i] == '.' || m_value[i] == 'e' || m_value[i] == 'E') 680 else if (m_value[i] == '.' || m_value[i] == 'e' || m_value[i] == 'E')
423 found_float = 1; 681 found_float = 1;
@@ -445,18 +703,77 @@ int GFitsHeaderCard::get_value_type(void) @@ -445,18 +703,77 @@ int GFitsHeaderCard::get_value_type(void)
445 = = 703 = =
446 ==========================================================================*/ 704 ==========================================================================*/
447 705
448 -/***************************************************************************  
449 - * Output operator *  
450 - * ----------------------------------------------------------------------- * 706 +/***********************************************************************//**
  707 + * @brief Output operator
  708 + *
  709 + * @param[in] os Output stream
  710 + * @param[in] card Card that should be put in output stream
451 ***************************************************************************/ 711 ***************************************************************************/
452 ostream& operator<< (ostream& os, const GFitsHeaderCard& card) 712 ostream& operator<< (ostream& os, const GFitsHeaderCard& card)
453 { 713 {
454 - // Put header card in stream  
455 - os << card.m_keyname << " = ";  
456 - os << card.m_value << " ";  
457 - os << card.m_unit << " ";  
458 - os << card.m_comment << " ";  
459 - os << card.m_value_type << endl; 714 + // Set buffer
  715 + char buffer[100];
  716 +
  717 + // Setup left justified keyname
  718 + std::string keyname = card.m_keyname;
  719 + while (keyname.length() < 8)
  720 + keyname.append(" ");
  721 +
  722 + // Setup buffer
  723 + if (card.m_value_type != CT_COMMENT && card.m_value_type != CT_HISTORY) {
  724 + if (card.m_unit.length() > 0) {
  725 + sprintf(buffer, "%8s =%21s / [%s] %s",
  726 + keyname.c_str(),
  727 + card.m_value.c_str(),
  728 + card.m_unit.c_str(),
  729 + card.m_comment.c_str());
  730 + }
  731 + else {
  732 + sprintf(buffer, "%8s =%21s / %s",
  733 + keyname.c_str(),
  734 + card.m_value.c_str(),
  735 + card.m_comment.c_str());
  736 + }
  737 + }
  738 + else {
  739 + sprintf(buffer, "%8s %s",
  740 + keyname.c_str(),
  741 + card.m_comment.c_str());
  742 + }
  743 +
  744 + // Put buffer in stream
  745 + os << buffer;
  746 +
  747 + // Attach card type
  748 + switch (card.m_value_type) {
  749 + case CT_UNKNOWN:
  750 + os << " <type unknown>" << endl;
  751 + break;
  752 + case CT_INVALID:
  753 + os << " <invalid type>" << endl;
  754 + break;
  755 + case CT_STRING:
  756 + os << " <string>" << endl;
  757 + break;
  758 + case CT_INT:
  759 + os << " <int>" << endl;
  760 + break;
  761 + case CT_FLOAT:
  762 + os << " <float>" << endl;
  763 + break;
  764 + case CT_BOOL:
  765 + os << " <boolean>" << endl;
  766 + break;
  767 + case CT_COMMENT:
  768 + os << " <comment>" << endl;
  769 + break;
  770 + case CT_HISTORY:
  771 + os << " <history>" << endl;
  772 + break;
  773 + default:
  774 + os << endl;
  775 + break;
  776 + }
460 777
461 // Return output stream 778 // Return output stream
462 return os; 779 return os;
src/fits/GFitsImage.cpp
@@ -125,7 +125,7 @@ GFitsImage::~GFitsImage() @@ -125,7 +125,7 @@ GFitsImage::~GFitsImage()
125 /***********************************************************************//** 125 /***********************************************************************//**
126 * @brief Assignment operator 126 * @brief Assignment operator
127 * 127 *
128 - * @param image FITS image to be assigned 128 + * @param[in] image FITS image to be assigned
129 ***************************************************************************/ 129 ***************************************************************************/
130 GFitsImage& GFitsImage::operator= (const GFitsImage& image) 130 GFitsImage& GFitsImage::operator= (const GFitsImage& image)
131 { 131 {
@@ -158,9 +158,30 @@ GFitsImage&amp; GFitsImage::operator= (const GFitsImage&amp; image) @@ -158,9 +158,30 @@ GFitsImage&amp; GFitsImage::operator= (const GFitsImage&amp; image)
158 ==========================================================================*/ 158 ==========================================================================*/
159 159
160 /***********************************************************************//** 160 /***********************************************************************//**
  161 + * @brief Return number of Bits per pixel (negative=floating point)
  162 + ***************************************************************************/
  163 +int GFitsImage::bitpix(void) const
  164 +{
  165 + // Return number of Bits per pixel
  166 + return m_bitpix;
  167 +}
  168 +
  169 +
  170 +/***********************************************************************//**
  171 + * @brief Return image dimension
  172 + ***************************************************************************/
  173 +int GFitsImage::naxis(void) const
  174 +{
  175 + // Return dimension
  176 + return m_naxis;
  177 +}
  178 +
  179 +
  180 +/***********************************************************************//**
161 * @brief Return axis dimension 181 * @brief Return axis dimension
162 * 182 *
163 - * @param axis Axis for which the dimension should be returned (starting from 0) 183 + * @param[in] axis Axis for which the dimension should be returned
  184 + * (starting from 0)
164 ***************************************************************************/ 185 ***************************************************************************/
165 int GFitsImage::naxes(int axis) const 186 int GFitsImage::naxes(int axis) const
166 { 187 {
@@ -176,6 +197,16 @@ int GFitsImage::naxes(int axis) const @@ -176,6 +197,16 @@ int GFitsImage::naxes(int axis) const
176 } 197 }
177 198
178 199
  200 +/***********************************************************************//**
  201 + * @brief Return number of pixels
  202 + ***************************************************************************/
  203 +int GFitsImage::num_pixels(void) const
  204 +{
  205 + // Return number of pixels
  206 + return m_num_pixels;
  207 +}
  208 +
  209 +
179 /*========================================================================== 210 /*==========================================================================
180 = = 211 = =
181 = GFitsImage private methods = 212 = GFitsImage private methods =
@@ -203,7 +234,7 @@ void GFitsImage::init_members(void) @@ -203,7 +234,7 @@ void GFitsImage::init_members(void)
203 /***********************************************************************//** 234 /***********************************************************************//**
204 * @brief Copy class members 235 * @brief Copy class members
205 * 236 *
206 - * @param image FITS image to copy 237 + * @param[in] image FITS image to copy
207 ***************************************************************************/ 238 ***************************************************************************/
208 void GFitsImage::copy_members(const GFitsImage& image) 239 void GFitsImage::copy_members(const GFitsImage& image)
209 { 240 {
@@ -232,7 +263,7 @@ void GFitsImage::free_members(void) @@ -232,7 +263,7 @@ void GFitsImage::free_members(void)
232 { 263 {
233 // Free memory 264 // Free memory
234 if (m_naxes != NULL) delete [] m_naxes; 265 if (m_naxes != NULL) delete [] m_naxes;
235 - 266 +
236 // Mark memory as free 267 // Mark memory as free
237 m_naxes = NULL; 268 m_naxes = NULL;
238 269
@@ -244,13 +275,13 @@ void GFitsImage::free_members(void) @@ -244,13 +275,13 @@ void GFitsImage::free_members(void)
244 /***********************************************************************//** 275 /***********************************************************************//**
245 * @brief Connect image to FITS file 276 * @brief Connect image to FITS file
246 * 277 *
247 - * @param fptr FITS file pointer to which the image should be connected 278 + * @param[in] fptr FITS file pointer to which the image should be connected
248 ***************************************************************************/ 279 ***************************************************************************/
249 void GFitsImage::connect(__fitsfile* fptr) 280 void GFitsImage::connect(__fitsfile* fptr)
250 { 281 {
251 // Connect Image 282 // Connect Image
252 m_fitsfile = *fptr; 283 m_fitsfile = *fptr;
253 - 284 +
254 // Return 285 // Return
255 return; 286 return;
256 } 287 }
@@ -259,7 +290,7 @@ void GFitsImage::connect(__fitsfile* fptr) @@ -259,7 +290,7 @@ void GFitsImage::connect(__fitsfile* fptr)
259 /***********************************************************************//** 290 /***********************************************************************//**
260 * @brief Open Image 291 * @brief Open Image
261 * 292 *
262 - * @param fptr FITS file pointer 293 + * @param[in] fptr FITS file pointer
263 * 294 *
264 * Open FITS image in FITS file. Opening means connecting the FITS file 295 * Open FITS image in FITS file. Opening means connecting the FITS file
265 * pointer to the image and reading the image and axes dimensions. 296 * pointer to the image and reading the image and axes dimensions.
@@ -274,7 +305,7 @@ void GFitsImage::open_image(__fitsfile* fptr) @@ -274,7 +305,7 @@ void GFitsImage::open_image(__fitsfile* fptr)
274 305
275 // Save FITS file pointer 306 // Save FITS file pointer
276 m_fitsfile = *fptr; 307 m_fitsfile = *fptr;
277 - 308 +
278 // Get the image dimensions 309 // Get the image dimensions
279 status = __ffgidm(&m_fitsfile, &m_naxis, &status); 310 status = __ffgidm(&m_fitsfile, &m_naxis, &status);
280 if (status != 0) 311 if (status != 0)
@@ -285,7 +316,7 @@ void GFitsImage::open_image(__fitsfile* fptr) @@ -285,7 +316,7 @@ void GFitsImage::open_image(__fitsfile* fptr)
285 316
286 // Get the axes dimensions 317 // Get the axes dimensions
287 if (m_naxis > 0) { 318 if (m_naxis > 0) {
288 - 319 +
289 // Allocate memory for axes dimensions 320 // Allocate memory for axes dimensions
290 if (m_naxes != NULL) delete [] m_naxes; 321 if (m_naxes != NULL) delete [] m_naxes;
291 m_naxes = new long[m_naxis]; 322 m_naxes = new long[m_naxis];
@@ -294,14 +325,14 @@ void GFitsImage::open_image(__fitsfile* fptr) @@ -294,14 +325,14 @@ void GFitsImage::open_image(__fitsfile* fptr)
294 status = __ffgisz(&m_fitsfile, m_naxis, m_naxes, &status); 325 status = __ffgisz(&m_fitsfile, m_naxis, m_naxes, &status);
295 if (status != 0) 326 if (status != 0)
296 throw GException::fits_error(G_OPEN_IMAGE, status); 327 throw GException::fits_error(G_OPEN_IMAGE, status);
297 - 328 +
298 // Calculate number of image pixels 329 // Calculate number of image pixels
299 m_num_pixels = 1; 330 m_num_pixels = 1;
300 for (int i = 0; i < m_naxis; ++i) 331 for (int i = 0; i < m_naxis; ++i)
301 m_num_pixels *= m_naxes[i]; 332 m_num_pixels *= m_naxes[i];
302 333
303 } // endif: there is an image 334 } // endif: there is an image
304 - 335 +
305 // Return 336 // Return
306 return; 337 return;
307 } 338 }
@@ -310,8 +341,8 @@ void GFitsImage::open_image(__fitsfile* fptr) @@ -310,8 +341,8 @@ void GFitsImage::open_image(__fitsfile* fptr)
310 /***********************************************************************//** 341 /***********************************************************************//**
311 * @brief Load FITS image 342 * @brief Load FITS image
312 * 343 *
313 - * @param datatype Datatype of pixels to be saved  
314 - * @param pixels Pixel array to be saved 344 + * @param[in] datatype Datatype of pixels to be saved
  345 + * @param[in] pixels Pixel array to be saved
315 * 346 *
316 * Save image pixels into FITS file. In case that the HDU does not exist it 347 * Save image pixels into FITS file. In case that the HDU does not exist it
317 * is created. 348 * is created.
@@ -352,18 +383,19 @@ void GFitsImage::load_image(int datatype, const void* pixels, const void* nulval @@ -352,18 +383,19 @@ void GFitsImage::load_image(int datatype, const void* pixels, const void* nulval
352 /***********************************************************************//** 383 /***********************************************************************//**
353 * @brief Save FITS image 384 * @brief Save FITS image
354 * 385 *
355 - * @param datatype Datatype of pixels to be saved  
356 - * @param pixels Pixel array to be saved 386 + * @param[in] datatype Datatype of pixels to be saved
  387 + * @param[in] pixels Pixel array to be saved
357 * 388 *
358 * Save image pixels into FITS file. In case that the HDU does not exist it 389 * Save image pixels into FITS file. In case that the HDU does not exist it
359 - * is created. 390 + * is created. In case that the pixel array is empty no data are saved; all
  391 + * image pixels will be empty in this case.
360 ***************************************************************************/ 392 ***************************************************************************/
361 void GFitsImage::save_image(int datatype, const void* pixels) 393 void GFitsImage::save_image(int datatype, const void* pixels)
362 { 394 {
363 // Move to HDU 395 // Move to HDU
364 int status = 0; 396 int status = 0;
365 status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status); 397 status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status);
366 - 398 +
367 // If HDU does not yet exist in file then create it now 399 // If HDU does not yet exist in file then create it now
368 if (status == 107) { 400 if (status == 107) {
369 status = 0; 401 status = 0;
@@ -388,7 +420,7 @@ void GFitsImage::save_image(int datatype, const void* pixels) @@ -388,7 +420,7 @@ void GFitsImage::save_image(int datatype, const void* pixels)
388 } 420 }
389 421
390 // Save the image pixels (if there are some ...) 422 // Save the image pixels (if there are some ...)
391 - if (m_naxis > 0) { 423 + if (m_naxis > 0 && pixels != NULL) {
392 long* fpixel = new long[m_naxis]; 424 long* fpixel = new long[m_naxis];
393 long* lpixel = new long[m_naxis]; 425 long* lpixel = new long[m_naxis];
394 for (int i = 0; i < m_naxis; ++i) { 426 for (int i = 0; i < m_naxis; ++i) {
src/rsp/GLATResponse.cpp
@@ -18,11 +18,14 @@ @@ -18,11 +18,14 @@
18 #include "GVector.hpp" 18 #include "GVector.hpp"
19 #include "GLATResponse.hpp" 19 #include "GLATResponse.hpp"
20 #include "GFits.hpp" 20 #include "GFits.hpp"
  21 +#include "GFitsHDU.hpp"
  22 +#include "GFitsDblImage.hpp"
21 #include "GFitsTableFltCol.hpp" 23 #include "GFitsTableFltCol.hpp"
22 24
23 /* __ Namespaces _________________________________________________________ */ 25 /* __ Namespaces _________________________________________________________ */
24 26
25 /* __ Method name definitions ____________________________________________ */ 27 /* __ Method name definitions ____________________________________________ */
  28 +#define G_LOAD "load(const std::string&, const std::string&)"
26 #define G_INIT_AEFF "GLATResponse::init_aeff()" 29 #define G_INIT_AEFF "GLATResponse::init_aeff()"
27 #define G_INIT_PSF "GLATResponse::init_psf()" 30 #define G_INIT_PSF "GLATResponse::init_psf()"
28 #define G_INIT_EDISP "GLATResponse::init_edisp()" 31 #define G_INIT_EDISP "GLATResponse::init_edisp()"
@@ -56,9 +59,8 @@ const double ln10 = 2.3025850929940459010936138; @@ -56,9 +59,8 @@ const double ln10 = 2.3025850929940459010936138;
56 = = 59 = =
57 ==========================================================================*/ 60 ==========================================================================*/
58 61
59 -/***************************************************************************  
60 - * Constructor *  
61 - * ----------------------------------------------------------------------- * 62 +/***********************************************************************//**
  63 + * @brief Constructor
62 ***************************************************************************/ 64 ***************************************************************************/
63 GLATResponse::GLATResponse() : GResponse() 65 GLATResponse::GLATResponse() : GResponse()
64 { 66 {
@@ -70,9 +72,10 @@ GLATResponse::GLATResponse() : GResponse() @@ -70,9 +72,10 @@ GLATResponse::GLATResponse() : GResponse()
70 } 72 }
71 73
72 74
73 -/***************************************************************************  
74 - * Copy constructor *  
75 - * ----------------------------------------------------------------------- * 75 +/***********************************************************************//**
  76 + * @brief Copy constructor
  77 + *
  78 + * @param rsp Response to be copied
76 ***************************************************************************/ 79 ***************************************************************************/
77 GLATResponse::GLATResponse(const GLATResponse& rsp) : GResponse(rsp) 80 GLATResponse::GLATResponse(const GLATResponse& rsp) : GResponse(rsp)
78 { 81 {
@@ -87,9 +90,8 @@ GLATResponse::GLATResponse(const GLATResponse&amp; rsp) : GResponse(rsp) @@ -87,9 +90,8 @@ GLATResponse::GLATResponse(const GLATResponse&amp; rsp) : GResponse(rsp)
87 } 90 }
88 91
89 92
90 -/***************************************************************************  
91 - * Destructor *  
92 - * ----------------------------------------------------------------------- * 93 +/***********************************************************************//**
  94 + * @brief Destructor
93 ***************************************************************************/ 95 ***************************************************************************/
94 GLATResponse::~GLATResponse() 96 GLATResponse::~GLATResponse()
95 { 97 {
@@ -107,9 +109,10 @@ GLATResponse::~GLATResponse() @@ -107,9 +109,10 @@ GLATResponse::~GLATResponse()
107 = = 109 = =
108 ==========================================================================*/ 110 ==========================================================================*/
109 111
110 -/***************************************************************************  
111 - * Assignment operator *  
112 - * ----------------------------------------------------------------------- * 112 +/***********************************************************************//**
  113 + * @brief Assignment operator
  114 + *
  115 + * @param rsp Response to be assigned
113 ***************************************************************************/ 116 ***************************************************************************/
114 GLATResponse& GLATResponse::operator= (const GLATResponse& rsp) 117 GLATResponse& GLATResponse::operator= (const GLATResponse& rsp)
115 { 118 {
@@ -141,9 +144,8 @@ GLATResponse&amp; GLATResponse::operator= (const GLATResponse&amp; rsp) @@ -141,9 +144,8 @@ GLATResponse&amp; GLATResponse::operator= (const GLATResponse&amp; rsp)
141 = = 144 = =
142 ==========================================================================*/ 145 ==========================================================================*/
143 146
144 -/***************************************************************************  
145 - * Return value of instrument response function *  
146 - * ----------------------------------------------------------------------- * 147 +/***********************************************************************//**
  148 + * @brief Return value of instrument response function.
147 ***************************************************************************/ 149 ***************************************************************************/
148 double GLATResponse::irf(const GSkyDir& obsDir, const double& obsEng, 150 double GLATResponse::irf(const GSkyDir& obsDir, const double& obsEng,
149 const GSkyDir& srcDir, const double& srcEng, 151 const GSkyDir& srcDir, const double& srcEng,
@@ -155,9 +157,8 @@ double GLATResponse::irf(const GSkyDir&amp; obsDir, const double&amp; obsEng, @@ -155,9 +157,8 @@ double GLATResponse::irf(const GSkyDir&amp; obsDir, const double&amp; obsEng,
155 } 157 }
156 158
157 159
158 -/***************************************************************************  
159 - * Return effective area *  
160 - * ----------------------------------------------------------------------- * 160 +/***********************************************************************//**
  161 + * @brief Return effective area
161 ***************************************************************************/ 162 ***************************************************************************/
162 double GLATResponse::aeff(const GSkyDir& obsDir, const double& obsEng, 163 double GLATResponse::aeff(const GSkyDir& obsDir, const double& obsEng,
163 const GSkyDir& srcDir, const double& srcEng, 164 const GSkyDir& srcDir, const double& srcEng,
@@ -169,9 +170,8 @@ double GLATResponse::aeff(const GSkyDir&amp; obsDir, const double&amp; obsEng, @@ -169,9 +170,8 @@ double GLATResponse::aeff(const GSkyDir&amp; obsDir, const double&amp; obsEng,
169 } 170 }
170 171
171 172
172 -/***************************************************************************  
173 - * Return value of point spread function *  
174 - * ----------------------------------------------------------------------- * 173 +/***********************************************************************//**
  174 + * @brief Return value of point spread function
175 ***************************************************************************/ 175 ***************************************************************************/
176 double GLATResponse::psf(const GSkyDir& obsDir, const double& obsEng, 176 double GLATResponse::psf(const GSkyDir& obsDir, const double& obsEng,
177 const GSkyDir& srcDir, const double& srcEng, 177 const GSkyDir& srcDir, const double& srcEng,
@@ -183,9 +183,8 @@ double GLATResponse::psf(const GSkyDir&amp; obsDir, const double&amp; obsEng, @@ -183,9 +183,8 @@ double GLATResponse::psf(const GSkyDir&amp; obsDir, const double&amp; obsEng,
183 } 183 }
184 184
185 185
186 -/***************************************************************************  
187 - * Return value of energy dispersion *  
188 - * ----------------------------------------------------------------------- * 186 +/***********************************************************************//**
  187 + * @brief Return value of energy dispersion
189 ***************************************************************************/ 188 ***************************************************************************/
190 double GLATResponse::edisp(const GSkyDir& obsDir, const double& obsEng, 189 double GLATResponse::edisp(const GSkyDir& obsDir, const double& obsEng,
191 const GSkyDir& srcDir, const double& srcEng, 190 const GSkyDir& srcDir, const double& srcEng,
@@ -197,14 +196,14 @@ double GLATResponse::edisp(const GSkyDir&amp; obsDir, const double&amp; obsEng, @@ -197,14 +196,14 @@ double GLATResponse::edisp(const GSkyDir&amp; obsDir, const double&amp; obsEng,
197 } 196 }
198 197
199 198
200 -/***************************************************************************  
201 - * Set calibration database *  
202 - * ----------------------------------------------------------------------- *  
203 - ***************************************************************************/  
204 -/** 199 +/***********************************************************************//**
205 * @brief Set the path to the calibration database. 200 * @brief Set the path to the calibration database.
206 - */  
207 -void GLATResponse::set_caldb(std::string caldb) 201 + *
  202 + * @param caldb Absolute path to calibration database
  203 + *
  204 + * NOTE: So far no check is done on whether the path exists!
  205 + ***************************************************************************/
  206 +void GLATResponse::set_caldb(const std::string& caldb)
208 { 207 {
209 // Simply copy path 208 // Simply copy path
210 // NOTE: Some check should be done on whether the path exists !!! 209 // NOTE: Some check should be done on whether the path exists !!!
@@ -215,25 +214,29 @@ void GLATResponse::set_caldb(std::string caldb) @@ -215,25 +214,29 @@ void GLATResponse::set_caldb(std::string caldb)
215 } 214 }
216 215
217 216
218 -/***************************************************************************  
219 - * Load response *  
220 - * ----------------------------------------------------------------------- *  
221 - ***************************************************************************/  
222 -/** 217 +/***********************************************************************//**
223 * @brief Load a specified LAT response function. 218 * @brief Load a specified LAT response function.
224 - */  
225 -void GLATResponse::load(std::string rspname, std::string rsptype) 219 + *
  220 + * @param rspname Name of response
  221 + * @param rsptype Type of response ('front' or 'back')
  222 + *
  223 + * Loads the specified GLAST LAT response from the calibration database and
  224 + * performs some pre-calculations for faster response determination.
  225 + ***************************************************************************/
  226 +void GLATResponse::load(const std::string& rspname, const std::string& rsptype)
226 { 227 {
227 // Store response name 228 // Store response name
228 m_rspname = rspname; 229 m_rspname = rspname;
229 -  
230 - // Convert response type 230 +
  231 + // Convert response type string to section
231 if (rsptype == "front") 232 if (rsptype == "front")
232 m_section = 0; 233 m_section = 0;
233 else if (rsptype == "back") 234 else if (rsptype == "back")
234 m_section = 1; 235 m_section = 1;
235 else 236 else
236 - throw; 237 + throw GException::rsp_invalid_type(G_LOAD, rsptype);
  238 +
  239 + // Store response type
237 m_rsptype = rsptype; 240 m_rsptype = rsptype;
238 241
239 // Initialise effective area 242 // Initialise effective area
@@ -244,18 +247,46 @@ void GLATResponse::load(std::string rspname, std::string rsptype) @@ -244,18 +247,46 @@ void GLATResponse::load(std::string rspname, std::string rsptype)
244 247
245 // Initialise energy dispersion 248 // Initialise energy dispersion
246 edisp_init(); 249 edisp_init();
  250 +
  251 + // Return
  252 + return;
247 } 253 }
248 254
249 255
250 -/***************************************************************************  
251 - * Save response *  
252 - * ----------------------------------------------------------------------- * 256 +/***********************************************************************//**
  257 + * @brief Save response
  258 + *
  259 + * @param rspname Filename into which the response will be saved
253 ***************************************************************************/ 260 ***************************************************************************/
254 -/**  
255 - * @brief Save me my friend ...  
256 - */  
257 -void GLATResponse::save(std::string rspname) const 261 +void GLATResponse::save(const std::string& rspname) const
258 { 262 {
  263 + // Open FITS file
  264 + GFits fits;
  265 + fits.open(rspname);
  266 +
  267 + // Build PSF HDUs
  268 + int naxes_psf2[] = {m_psf_energy_num, m_psf_ctheta_num};
  269 + int naxes_psf3[] = {m_psf_angle_num, m_psf_energy_num, m_psf_ctheta_num};
  270 + GFitsDblImage image_psf_psf(3, naxes_psf3, m_psf);
  271 + GFitsDblImage image_psf_norm(2, naxes_psf2, m_norm);
  272 + GFitsDblImage image_psf_sigma(2, naxes_psf2, m_sigma);
  273 + GFitsHDU hdu_psf_psf(image_psf_psf);
  274 + GFitsHDU hdu_psf_norm(image_psf_norm);
  275 + GFitsHDU hdu_psf_sigma(image_psf_sigma);
  276 + hdu_psf_psf.extname("PSF");
  277 + hdu_psf_norm.extname("NORM");
  278 + hdu_psf_sigma.extname("SIGMA");
  279 +
  280 + // Append HDUs to FITS file
  281 + fits.append(&hdu_psf_psf);
  282 + fits.append(&hdu_psf_norm);
  283 + fits.append(&hdu_psf_sigma);
  284 +
  285 + // Save FITS file
  286 + fits.save();
  287 +
  288 + // Return
  289 + return;
259 } 290 }
260 291
261 292
@@ -328,14 +359,14 @@ void GLATResponse::psf_init(void) @@ -328,14 +359,14 @@ void GLATResponse::psf_init(void)
328 GVector v_sigma = get_fits_vector(hdu, "SIGMA"); 359 GVector v_sigma = get_fits_vector(hdu, "SIGMA");
329 GVector v_gcore = get_fits_vector(hdu, "GCORE"); 360 GVector v_gcore = get_fits_vector(hdu, "GCORE");
330 GVector v_gtail = get_fits_vector(hdu, "GTAIL"); 361 GVector v_gtail = get_fits_vector(hdu, "GTAIL");
331 - 362 +
332 // Set binning in angle, energy and cos theta 363 // Set binning in angle, energy and cos theta
333 m_psf_angle_num = 2000; 364 m_psf_angle_num = 2000;
334 m_psf_angle_min = 0.01; 365 m_psf_angle_min = 0.01;
335 m_psf_angle_bin = 0.01; 366 m_psf_angle_bin = 0.01;
336 m_psf_energy_num = v_energy_lo.size(); 367 m_psf_energy_num = v_energy_lo.size();
337 m_psf_ctheta_num = v_ctheta_lo.size(); 368 m_psf_ctheta_num = v_ctheta_lo.size();
338 - 369 +
339 // Free old PSF memory 370 // Free old PSF memory
340 if (m_psf != NULL) delete [] m_psf; 371 if (m_psf != NULL) delete [] m_psf;
341 if (m_norm != NULL) delete [] m_norm; 372 if (m_norm != NULL) delete [] m_norm;
@@ -347,7 +378,7 @@ void GLATResponse::psf_init(void) @@ -347,7 +378,7 @@ void GLATResponse::psf_init(void)
347 m_psf = new double[psf_size]; 378 m_psf = new double[psf_size];
348 m_norm = new double[bin_size]; 379 m_norm = new double[bin_size];
349 m_sigma = new double[bin_size]; 380 m_sigma = new double[bin_size];
350 - 381 +
351 // Setup PSF vector axis 382 // Setup PSF vector axis
352 GVector xaxis(m_psf_angle_num); 383 GVector xaxis(m_psf_angle_num);
353 GVector u(m_psf_angle_num); 384 GVector u(m_psf_angle_num);
@@ -356,46 +387,46 @@ void GLATResponse::psf_init(void) @@ -356,46 +387,46 @@ void GLATResponse::psf_init(void)
356 xaxis(i) = x; 387 xaxis(i) = x;
357 u(i) = 0.5*x*x; 388 u(i) = 0.5*x*x;
358 } 389 }
359 - 390 +
360 // Get maximum angle 391 // Get maximum angle
361 m_psf_angle_max = xaxis(m_psf_angle_num-1); 392 m_psf_angle_max = xaxis(m_psf_angle_num-1);
362 - 393 +
363 // Loop over all energy bins 394 // Loop over all energy bins
364 for (int ie = 0; ie < m_psf_energy_num; ++ie) { 395 for (int ie = 0; ie < m_psf_energy_num; ++ie) {
365 - 396 +
366 // Get mean energy of bin 397 // Get mean energy of bin
367 // NOTE: This should be replaced by a logarithmic mean 398 // NOTE: This should be replaced by a logarithmic mean
368 double energy = 0.5 * (v_energy_lo(ie) + v_energy_hi(ie)); 399 double energy = 0.5 * (v_energy_lo(ie) + v_energy_hi(ie));
369 - 400 +
370 // Get scale at specified energy 401 // Get scale at specified energy
371 double scale = psf_scale(energy); 402 double scale = psf_scale(energy);
372 - 403 +
373 // Loop over all cos theta bins 404 // Loop over all cos theta bins
374 for (int ic = 0; ic < m_psf_ctheta_num; ++ic) { 405 for (int ic = 0; ic < m_psf_ctheta_num; ++ic) {
375 - 406 +
376 // Extract PSF parameters 407 // Extract PSF parameters
377 int inx = ic * m_psf_energy_num + ie; 408 int inx = ic * m_psf_energy_num + ie;
378 double ncore = v_ncore(inx); 409 double ncore = v_ncore(inx);
379 double sigma = v_sigma(inx); 410 double sigma = v_sigma(inx);
380 double gcore = v_gcore(inx); 411 double gcore = v_gcore(inx);
381 double gtail = v_gtail(inx); 412 double gtail = v_gtail(inx);
382 - 413 +
383 // Evaluate ntail 414 // Evaluate ntail
384 double denom = psf_base_value(10.0, gtail); 415 double denom = psf_base_value(10.0, gtail);
385 double ntail = (denom != 0.0) ? ncore * psf_base_value(10.0, gcore) / denom : 0.0; 416 double ntail = (denom != 0.0) ? ncore * psf_base_value(10.0, gcore) / denom : 0.0;
386 - 417 +
387 // Calculate PSF dependence 418 // Calculate PSF dependence
388 GVector psf = ncore * psf_base_vector(u, gcore) + ntail * psf_base_vector(u, gtail); 419 GVector psf = ncore * psf_base_vector(u, gcore) + ntail * psf_base_vector(u, gtail);
389 - 420 +
390 // Normalize PSF vector to identical amplitudes at smallest angular 421 // Normalize PSF vector to identical amplitudes at smallest angular
391 // distance. This allows for accurate interpolation afterwards 422 // distance. This allows for accurate interpolation afterwards
392 double norm = 1.0 / psf(0); 423 double norm = 1.0 / psf(0);
393 psf *= norm; 424 psf *= norm;
394 - 425 +
395 // Evaluate angular separation 426 // Evaluate angular separation
396 double stretch = sigma * scale; 427 double stretch = sigma * scale;
397 GVector delta = xaxis * stretch; 428 GVector delta = xaxis * stretch;
398 - 429 +
399 // Calculate PSF normalization factor 430 // Calculate PSF normalization factor
400 double sum = 0.0; 431 double sum = 0.0;
401 for (int i = 0; i < m_psf_angle_num; ++i) { 432 for (int i = 0; i < m_psf_angle_num; ++i) {
@@ -405,16 +436,16 @@ void GLATResponse::psf_init(void) @@ -405,16 +436,16 @@ void GLATResponse::psf_init(void)
405 } 436 }
406 sum *= twopi; 437 sum *= twopi;
407 norm = scale / sum; 438 norm = scale / sum;
408 - 439 +
409 // Store PSF information 440 // Store PSF information
410 m_norm[inx] = norm; 441 m_norm[inx] = norm;
411 m_sigma[inx] = sigma; 442 m_sigma[inx] = sigma;
412 - 443 +
413 // Store PSF vector 444 // Store PSF vector
414 int ipsf = inx * m_psf_angle_num; 445 int ipsf = inx * m_psf_angle_num;
415 for (int i = 0; i < m_psf_angle_num; ++i, ++ipsf) 446 for (int i = 0; i < m_psf_angle_num; ++i, ++ipsf)
416 m_psf[ipsf] = psf(i); 447 m_psf[ipsf] = psf(i);
417 - 448 +
418 } // endfor: looped over cos theta 449 } // endfor: looped over cos theta
419 } // endfor: looped over energies 450 } // endfor: looped over energies
420 451
@@ -436,22 +467,22 @@ double GLATResponse::psf_get(const double&amp; delta, const double&amp; logE, const doub @@ -436,22 +467,22 @@ double GLATResponse::psf_get(const double&amp; delta, const double&amp; logE, const doub
436 // Interpolate sigma and norm tables 467 // Interpolate sigma and norm tables
437 double sigma = 1.0; // Perform bi-linear interpolation in logE and ctheta 468 double sigma = 1.0; // Perform bi-linear interpolation in logE and ctheta
438 double norm = 1.0; // Perform bi-linear interpolation in logE and ctheta 469 double norm = 1.0; // Perform bi-linear interpolation in logE and ctheta
439 - 470 +
440 // Evaluate scale 471 // Evaluate scale
441 double energy = pow(10.0,logE); // DUMMY: t=(0.01*(10.0^logE))^-0.8 472 double energy = pow(10.0,logE); // DUMMY: t=(0.01*(10.0^logE))^-0.8
442 double scale = psf_scale(energy); 473 double scale = psf_scale(energy);
443 - 474 +
444 // Get stretch factor 475 // Get stretch factor
445 double stretch = sigma * scale; 476 double stretch = sigma * scale;
446 - 477 +
447 // Get PSF value from table 478 // Get PSF value from table
448 double r = delta * deg2rad / stretch; // in radians 479 double r = delta * deg2rad / stretch; // in radians
449 - int inx = (r - m_psf_angle_min) / m_psf_angle_bin; // Perform linear interpolation 480 + int inx = (int)((r - m_psf_angle_min) / m_psf_angle_bin); // Perform linear interpolation
450 double psf = 1.0; 481 double psf = 1.0;
451 - 482 +
452 // Normalize PSF 483 // Normalize PSF
453 psf *= norm; 484 psf *= norm;
454 - 485 +
455 // Return PSF value 486 // Return PSF value
456 return psf; 487 return psf;
457 } 488 }
test/test_GFits.cpp
@@ -38,18 +38,18 @@ int dequal(double val, double ref) @@ -38,18 +38,18 @@ int dequal(double val, double ref)
38 ***************************************************************************/ 38 ***************************************************************************/
39 void test_open(void) 39 void test_open(void)
40 { 40 {
41 - std::cout << "Test GFits: Open FITS file: "; 41 + cout << "Test GFits: Open FITS file: ";
42 try { 42 try {
43 GFits fits; 43 GFits fits;
44 fits.open("test_GFits.fits"); 44 fits.open("test_GFits.fits");
45 cout << endl << fits; 45 cout << endl << fits;
46 } 46 }
47 catch (exception &e) { 47 catch (exception &e) {
48 - std::cout << std::endl << "TEST ERROR: Unable to open FITS file." << std::endl;  
49 - std::cout << e.what() << std::endl; 48 + cout << endl << "TEST ERROR: Unable to open FITS file." << endl;
  49 + cout << e.what() << endl;
50 throw; 50 throw;
51 } 51 }
52 - std::cout << ". ok." << std::endl; 52 + cout << ". ok." << endl;
53 } 53 }
54 54
55 55
@@ -64,15 +64,15 @@ void test_columns(void) @@ -64,15 +64,15 @@ void test_columns(void)
64 fits.open("test_GFits.fits"); 64 fits.open("test_GFits.fits");
65 } 65 }
66 catch (exception &e) { 66 catch (exception &e) {
67 - std::cout << std::endl << "TEST ERROR: Unable to open test file." << std::endl;  
68 - std::cout << e.what() << std::endl; 67 + cout << endl << "TEST ERROR: Unable to open test file." << endl;
  68 + cout << e.what() << endl;
69 throw; 69 throw;
70 } 70 }
71 71
72 // 72 //
73 // Test single string column 73 // Test single string column
74 // 74 //
75 - std::cout << "Test GFits: String column handling: "; 75 + cout << "Test GFits: String column handling: ";
76 try { 76 try {
77 GFitsTableStrCol str = *((GFitsTableStrCol*)fits.hdu("BinTable")->column("TSTRING")); 77 GFitsTableStrCol str = *((GFitsTableStrCol*)fits.hdu("BinTable")->column("TSTRING"));
78 if (str.string(0) != "1" || str.string(1) != "2" || str.string(2) != "") { 78 if (str.string(0) != "1" || str.string(1) != "2" || str.string(2) != "") {
@@ -93,16 +93,16 @@ void test_columns(void) @@ -93,16 +93,16 @@ void test_columns(void)
93 std::cout << "."; 93 std::cout << ".";
94 } 94 }
95 catch (exception &e) { 95 catch (exception &e) {
96 - std::cout << std::endl << "TEST ERROR: Unable to handle single TSTRING column." << std::endl;  
97 - std::cout << e.what() << std::endl; 96 + cout << endl << "TEST ERROR: Unable to handle single TSTRING column." << endl;
  97 + cout << e.what() << endl;
98 throw; 98 throw;
99 } 99 }
100 - std::cout << ". ok." << std::endl; 100 + cout << ". ok." << endl;
101 101
102 // 102 //
103 // Test single short column 103 // Test single short column
104 // 104 //
105 - std::cout << "Test GFits: Short column handling: "; 105 + cout << "Test GFits: Short column handling: ";
106 try { 106 try {
107 GFitsTableShtCol sht = *((GFitsTableShtCol*)fits.hdu("BinTable")->column("TSHORT")); 107 GFitsTableShtCol sht = *((GFitsTableShtCol*)fits.hdu("BinTable")->column("TSHORT"));
108 if (sht.integer(0) != 1 || sht.real(0) != 1.0 || sht.string(0) != "1" || 108 if (sht.integer(0) != 1 || sht.real(0) != 1.0 || sht.string(0) != "1" ||
@@ -115,16 +115,16 @@ void test_columns(void) @@ -115,16 +115,16 @@ void test_columns(void)
115 std::cout << "."; 115 std::cout << ".";
116 } 116 }
117 catch (exception &e) { 117 catch (exception &e) {
118 - std::cout << std::endl << "TEST ERROR: Unable to handle single TSHORT column." << std::endl;  
119 - std::cout << e.what() << std::endl; 118 + cout << endl << "TEST ERROR: Unable to handle single TSHORT column." << endl;
  119 + cout << e.what() << endl;
120 throw; 120 throw;
121 } 121 }
122 - std::cout << ". ok." << std::endl; 122 + cout << ". ok." << endl;
123 123
124 // 124 //
125 // Test single long column 125 // Test single long column
126 // 126 //
127 - std::cout << "Test GFits: Long column handling: "; 127 + cout << "Test GFits: Long column handling: ";
128 try { 128 try {
129 GFitsTableLngCol lng = *((GFitsTableLngCol*)fits.hdu("BinTable")->column("TLONG")); 129 GFitsTableLngCol lng = *((GFitsTableLngCol*)fits.hdu("BinTable")->column("TLONG"));
130 if (lng.integer(0) != 10 || lng.real(0) != 10.0 || lng.string(0) != "10" || 130 if (lng.integer(0) != 10 || lng.real(0) != 10.0 || lng.string(0) != "10" ||
@@ -134,14 +134,14 @@ void test_columns(void) @@ -134,14 +134,14 @@ void test_columns(void)
134 throw; 134 throw;
135 } 135 }
136 else 136 else
137 - std::cout << "."; 137 + cout << ".";
138 } 138 }
139 catch (exception &e) { 139 catch (exception &e) {
140 - std::cout << std::endl << "TEST ERROR: Unable to handle single TLONG column." << std::endl;  
141 - std::cout << e.what() << std::endl; 140 + cout << endl << "TEST ERROR: Unable to handle single TLONG column." << endl;
  141 + cout << e.what() << endl;
142 throw; 142 throw;
143 } 143 }
144 - std::cout << ". ok." << std::endl; 144 + cout << ". ok." << endl;
145 145
146 // 146 //
147 // Test single floating point column 147 // Test single floating point column
@@ -215,11 +215,11 @@ void test_columns(void) @@ -215,11 +215,11 @@ void test_columns(void)
215 } 215 }
216 } 216 }
217 catch (exception &e) { 217 catch (exception &e) {
218 - std::cout << std::endl << "TEST ERROR: Unable to handle single TFLOAT column." << std::endl;  
219 - std::cout << e.what() << std::endl; 218 + cout << endl << "TEST ERROR: Unable to handle single TFLOAT column." << endl;
  219 + cout << e.what() << endl;
220 throw; 220 throw;
221 } 221 }
222 - std::cout << ". ok." << std::endl; 222 + cout << ". ok." << endl;
223 223
224 // 224 //
225 // Test single double column 225 // Test single double column
@@ -280,11 +280,11 @@ void test_columns(void) @@ -280,11 +280,11 @@ void test_columns(void)
280 std::cout << "."; 280 std::cout << ".";
281 } 281 }
282 catch (exception &e) { 282 catch (exception &e) {
283 - std::cout << std::endl << "TEST ERROR: Unable to handle single TDOUBLE column." << std::endl;  
284 - std::cout << e.what() << std::endl; 283 + cout << endl << "TEST ERROR: Unable to handle single TDOUBLE column." << endl;
  284 + cout << e.what() << endl;
285 throw; 285 throw;
286 } 286 }
287 - std::cout << ". ok." << std::endl; 287 + cout << ". ok." << endl;
288 288
289 } 289 }
290 290
@@ -296,10 +296,10 @@ void test_create(void) @@ -296,10 +296,10 @@ void test_create(void)
296 { 296 {
297 // Dump header 297 // Dump header
298 cout << "Test GFits: Create FITS file: "; 298 cout << "Test GFits: Create FITS file: ";
299 - 299 +
300 // Remove FITS file 300 // Remove FITS file
301 system("rm -rf test.fits"); 301 system("rm -rf test.fits");
302 - 302 +
303 // Create FITS file with empty double precision image 303 // Create FITS file with empty double precision image
304 try { 304 try {
305 GFits fits; 305 GFits fits;
@@ -307,6 +307,7 @@ void test_create(void) @@ -307,6 +307,7 @@ void test_create(void)
307 GFitsDblImage image; 307 GFitsDblImage image;
308 GFitsHDU hdu(image); 308 GFitsHDU hdu(image);
309 fits.append(&hdu); 309 fits.append(&hdu);
  310 + //cout << fits;
310 fits.save(); 311 fits.save();
311 } 312 }
312 catch (exception &e) { 313 catch (exception &e) {
@@ -315,7 +316,7 @@ void test_create(void) @@ -315,7 +316,7 @@ void test_create(void)
315 throw; 316 throw;
316 } 317 }
317 cout << "."; 318 cout << ".";
318 - 319 +
319 // Attach double precision image 320 // Attach double precision image
320 double sum = 0.0; 321 double sum = 0.0;
321 try { 322 try {
@@ -334,6 +335,7 @@ void test_create(void) @@ -334,6 +335,7 @@ void test_create(void)
334 } 335 }
335 GFitsHDU hdu(image); 336 GFitsHDU hdu(image);
336 fits.append(&hdu); 337 fits.append(&hdu);
  338 + cout << fits;
337 fits.save(); 339 fits.save();
338 } 340 }
339 catch (exception &e) { 341 catch (exception &e) {
@@ -342,7 +344,7 @@ void test_create(void) @@ -342,7 +344,7 @@ void test_create(void)
342 throw; 344 throw;
343 } 345 }
344 cout << "."; 346 cout << ".";
345 - 347 +
346 // Re-open double precision image 348 // Re-open double precision image
347 try { 349 try {
348 GFits fits; 350 GFits fits;
@@ -408,12 +410,12 @@ void test_image_double(void) @@ -408,12 +410,12 @@ void test_image_double(void)
408 throw; 410 throw;
409 } 411 }
410 cout << "."; 412 cout << ".";
411 - 413 +
412 // Bad 2D operator 414 // Bad 2D operator
413 try { 415 try {
414 double result = image(0,1); 416 double result = image(0,1);
415 } 417 }
416 - catch (GException::fits_bad_image_operator &e) { 418 + catch (GException::fits_wrong_image_operator &e) {
417 cout << "."; 419 cout << ".";
418 } 420 }
419 catch (exception &e) { 421 catch (exception &e) {
@@ -426,7 +428,7 @@ void test_image_double(void) @@ -426,7 +428,7 @@ void test_image_double(void)
426 try { 428 try {
427 double result = image(0,1,2); 429 double result = image(0,1,2);
428 } 430 }
429 - catch (GException::fits_bad_image_operator &e) { 431 + catch (GException::fits_wrong_image_operator &e) {
430 cout << "."; 432 cout << ".";
431 } 433 }
432 catch (exception &e) { 434 catch (exception &e) {
@@ -439,7 +441,7 @@ void test_image_double(void) @@ -439,7 +441,7 @@ void test_image_double(void)
439 try { 441 try {
440 double result = image(0,1,2,3); 442 double result = image(0,1,2,3);
441 } 443 }
442 - catch (GException::fits_bad_image_operator &e) { 444 + catch (GException::fits_wrong_image_operator &e) {
443 cout << "."; 445 cout << ".";
444 } 446 }
445 catch (exception &e) { 447 catch (exception &e) {
@@ -447,7 +449,7 @@ void test_image_double(void) @@ -447,7 +449,7 @@ void test_image_double(void)
447 cout << e.what() << endl; 449 cout << e.what() << endl;
448 throw; 450 throw;
449 } 451 }
450 - 452 +
451 } 453 }
452 catch (exception &e) { 454 catch (exception &e) {
453 cout << endl << "TEST ERROR: Unable to test GFitsDblImage classes." << endl; 455 cout << endl << "TEST ERROR: Unable to test GFitsDblImage classes." << endl;
test/test_GResponse.cpp
@@ -12,8 +12,9 @@ @@ -12,8 +12,9 @@
12 ***************************************************************************/ 12 ***************************************************************************/
13 13
14 /* __ Includes ___________________________________________________________ */ 14 /* __ Includes ___________________________________________________________ */
  15 +#include <stdlib.h>
  16 +#include <iostream>
15 #include "test_GResponse.hpp" 17 #include "test_GResponse.hpp"
16 -#include <iostream> // cout, cerr  
17 18
18 /* __ Namespaces _________________________________________________________ */ 19 /* __ Namespaces _________________________________________________________ */
19 20
@@ -25,31 +26,18 @@ @@ -25,31 +26,18 @@
25 ***************************************************************************/ 26 ***************************************************************************/
26 void test_lat_response(void) 27 void test_lat_response(void)
27 { 28 {
  29 + // Remove FITS file
  30 + system("rm -rf test_rsp.fits");
  31 +
28 cout << "Test GLATResponse: Open PSF FITS file: "; 32 cout << "Test GLATResponse: Open PSF FITS file: ";
29 try { 33 try {
30 // Get HANDOFF Response 34 // Get HANDOFF Response
31 GLATResponse rsp; 35 GLATResponse rsp;
32 rsp.set_caldb("irf/lat"); 36 rsp.set_caldb("irf/lat");
33 rsp.load("Pass5_v0", "front"); 37 rsp.load("Pass5_v0", "front");
34 -/*  
35 - // Open FITS file  
36 - GFits fits;  
37 - fits.open("irf/lat/aeff_.fits");  
38 -  
39 - // Get pointer towards effective area HDU  
40 - GFitsHDU* aeff = fits.hdu("EFFECTIVE AREA");  
41 - if (aeff == NULL) {  
42 - cout << endl << "TEST ERROR: Unable to find HDU <EFFECTIVE AREA>." << endl;  
43 - throw;  
44 - }  
45 38
46 - // Get columns  
47 - GFitsTableFltCol energ_lo = *((GFitsTableFltCol*)aeff->column("ENERG_LO"));  
48 - GFitsTableFltCol energ_hi = *((GFitsTableFltCol*)aeff->column("ENERG_HI"));  
49 - GFitsTableFltCol ctheta_lo = *((GFitsTableFltCol*)aeff->column("CTHETA_LO"));  
50 - GFitsTableFltCol ctheta_hi = *((GFitsTableFltCol*)aeff->column("CTHETA_HI"));  
51 - GFitsTableFltCol effarea = *((GFitsTableFltCol*)aeff->column("EFFAREA"));  
52 -*/ 39 + // Save response
  40 + rsp.save("test_rsp.fits");
53 } 41 }
54 catch (exception &e) { 42 catch (exception &e) {
55 cout << endl << "TEST ERROR: Unable to open FITS file." << endl; 43 cout << endl << "TEST ERROR: Unable to open FITS file." << endl;