Commit 966fb927bbd6fc3434c42cb2aa1dce93302aa448

Authored by knodlseder
1 parent 83ed050d

improve doxygen documentation

include/GException.hpp
... ... @@ -135,6 +135,12 @@ public:
135 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 144 // FITS file has already been opened
139 145 class fits_already_opened : public GExceptionHandler {
140 146 public:
... ... @@ -190,9 +196,15 @@ public:
190 196 };
191 197  
192 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 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 30 /***********************************************************************//**
31 31 * @class GFits
32 32 *
33   - * @brief Implements a FITS file interface
  33 + * @brief Implements FITS file interface
34 34 *
35 35 * GFits is the basic FITS file interface. All FITS file handlings operate
36 36 * via members of GFits. A FITS file is composed of Header Data Units (HDU)
... ... @@ -66,10 +66,10 @@ private:
66 66 void free_members(void);
67 67  
68 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 39 // Constructors and destructors
40 40 GFitsDblImage();
41 41 GFitsDblImage(int naxis, const int* naxes);
  42 + GFitsDblImage(int naxis, const int* naxes, const double* pixels);
42 43 GFitsDblImage(const GFitsDblImage& image);
43 44 ~GFitsDblImage();
44 45  
... ...
include/GFitsHDU.hpp
... ... @@ -32,7 +32,7 @@
32 32 /***********************************************************************//**
33 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 37 * The HDU is the basic unit of a FITS file. Each HDU consists of a header
38 38 * and a data area. The header is composed of cards and is implemented by
... ... @@ -61,6 +61,7 @@ public:
61 61 void open(__fitsfile* fptr, int hdunum);
62 62 void save(void);
63 63 std::string extname(void) const;
  64 + void extname(const std::string& extname);
64 65 int extno(void) const;
65 66 int exttype(void) const;
66 67 GFitsHeader* header(void) const;
... ... @@ -77,12 +78,12 @@ private:
77 78 GFitsImage* new_image(void);
78 79  
79 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 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 19 #ifndef GFITSHEADER_HPP
15 20 #define GFITSHEADER_HPP
... ... @@ -21,8 +26,16 @@
21 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 40 class GFitsHeader {
28 41  
... ... @@ -40,7 +53,7 @@ public:
40 53  
41 54 // Methods
42 55 void open(__fitsfile* fptr);
43   - void save(void);
  56 + void save(__fitsfile* fptr);
44 57 void close(void);
45 58 void update(const GFitsHeaderCard& card);
46 59 GFitsHeaderCard* card(const std::string& keyname);
... ... @@ -52,13 +65,13 @@ public:
52 65 int integer(const std::string& keyname);
53 66 int integer(const int& cardno);
54 67 GFitsHeader* clone(void) const;
55   -
  68 +
56 69 private:
57 70 // Private methods
58 71 void init_members(void);
59 72 void copy_members(const GFitsHeader& header);
60 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 76 // Private data area
64 77 int m_num_cards;
... ... @@ -69,20 +82,5 @@ private:
69 82 /***************************************************************************
70 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 86 #endif /* GFITSHEADER_HPP */
... ...
include/GFitsHeaderCard.hpp
... ... @@ -10,6 +10,11 @@
10 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 19 #ifndef GFITSHEADERCARD_HPP
15 20 #define GFITSHEADERCARD_HPP
... ... @@ -20,8 +25,14 @@
20 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 37 class GFitsHeaderCard {
27 38  
... ... @@ -31,7 +42,11 @@ class GFitsHeaderCard {
31 42 public:
32 43 // Constructors & Destructors
33 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 50 const std::string& comment);
36 51 GFitsHeaderCard(const GFitsHeaderCard& card);
37 52 ~GFitsHeaderCard();
... ... @@ -39,7 +54,15 @@ public:
39 54 // Operators
40 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 66 std::string keyname(void) const;
44 67 std::string value(void) const;
45 68 int value_type(void) const;
... ... @@ -48,12 +71,10 @@ public:
48 71 std::string string(void);
49 72 double real(void);
50 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 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 78 void write(__fitsfile* fptr);
58 79  
59 80 private:
... ... @@ -61,29 +82,19 @@ private:
61 82 void init_members(void);
62 83 void copy_members(const GFitsHeaderCard& card);
63 84 void free_members(void);
64   - int get_value_type(void);
  85 + int get_value_type(const std::string& value);
65 86  
66 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 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 100 #endif /* GFITSHEADERCARD_HPP */
... ...
include/GFitsImage.hpp
... ... @@ -53,11 +53,13 @@ public:
53 53 virtual void save(void) = 0;
54 54 virtual void close(void) = 0;
55 55 virtual GFitsImage* clone(void) const = 0;
56   -
  56 +
57 57 // Methods
  58 + int bitpix(void) const;
58 59 int naxis(void) const;
59 60 int naxes(int axis) const;
60   -
  61 + int num_pixels(void) const;
  62 +
61 63 protected:
62 64 // Private methods
63 65 void init_members(void);
... ... @@ -69,17 +71,16 @@ protected:
69 71 void save_image(int datatype, const void* pixels);
70 72  
71 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 83 * Inline methods *
82 84 ***************************************************************************/
83   -inline int GFitsImage::naxis(void) const { return m_naxis; }
84 85  
85 86 #endif /* GFITSIMAGE_HPP */
... ...
include/GLATResponse.hpp
... ... @@ -28,16 +28,11 @@
28 28 /* __ Namespaces _________________________________________________________ */
29 29  
30 30  
31   -/***************************************************************************
32   - * GLATResponse class definition *
33   - ***************************************************************************/
34   -/**
  31 +/***********************************************************************//**
35 32 * @class GLATResponse
36 33 *
37 34 * @brief Interface for the GLAST LAT instrument response function classes.
38   - *
39   - * @author J. Knodlseder
40   - */
  35 + ***************************************************************************/
41 36 class GLATResponse : public GResponse {
42 37  
43 38 public:
... ... @@ -67,9 +62,9 @@ public:
67 62 const GSkyDir& instPntDir, const double& instPosAng,
68 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 68 GLATResponse* clone(void) const;
74 69  
75 70 private:
... ... @@ -82,7 +77,7 @@ private:
82 77 double psf_scale(const double& energy);
83 78 double psf_base_value(const double& u, const double& gamma);
84 79 GVector psf_base_vector(const GVector& u, const double& gamma);
85   -
  80 +
86 81 // Private PSF data
87 82 int m_psf_angle_num;
88 83 double m_psf_angle_min;
... ...
include/GResponse.hpp
... ... @@ -108,7 +108,7 @@ public:
108 108  
109 109 /// Pure virtual method to define the calibration database
110 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 113 /// Pure virtual method to load the instrument response from the calibration
114 114 /// database
... ...
src/GException.cpp
... ... @@ -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 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 225 ostringstream s_error;
223 226 char err_text[31];
224 227 __ffgerr(status, err_text);
225   - s_error << err_text << " (status: " << status << ")";
  228 + s_error << err_text << " (status=" << status << ")";
226 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 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 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 294 m_origin = origin;
257 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 312 m_origin = origin;
267 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 330 m_origin = origin;
277 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 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 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 374 m_origin = origin;
307 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 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 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 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 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 23 /* __ Method name definitions ____________________________________________ */
24 24 #define G_OPEN "GFits::open(std::string)"
25 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 28 #define G_FREE_MEM "GFits::free_members()"
27 29  
28 30 /* __ Macros _____________________________________________________________ */
... ... @@ -55,7 +57,7 @@ GFits::GFits()
55 57 /***********************************************************************//**
56 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 62 GFits::GFits(const GFits& fits)
61 63 {
... ... @@ -92,7 +94,7 @@ GFits::~GFits()
92 94 /***********************************************************************//**
93 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 99 GFits& GFits::operator= (const GFits& fits)
98 100 {
... ... @@ -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 148 void GFits::open(const std::string& filename)
132 149 {
... ... @@ -137,7 +154,7 @@ void GFits::open(const std::string&amp; filename)
137 154 // Open FITS file
138 155 int status = 0;
139 156 status = __ffopen(&m_fitsfile, filename.c_str(), 1, &status);
140   -
  157 +
141 158 // If FITS file does not exist then create it now
142 159 if (status == 104) {
143 160 status = 0;
... ... @@ -172,9 +189,12 @@ void GFits::open(const std::string&amp; filename)
172 189 /***********************************************************************//**
173 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 199 void GFits::append(const GFitsHDU* hdu)
180 200 {
... ... @@ -182,11 +202,11 @@ void GFits::append(const GFitsHDU* hdu)
182 202 // the HDU to append is not an image then we have to add a primary
183 203 // image first. In this case we add 2 new HDUs.
184 204 int n_add = (m_num_hdu == 0 && hdu->m_type != 0) ? 2 : 1;
185   -
  205 +
186 206 // Create memory to hold HDUs
187 207 GFitsHDU* tmp = new GFitsHDU[m_num_hdu+n_add];
188 208 if (tmp != NULL) {
189   -
  209 +
190 210 // Copy over existing HDUs and remove old ones
191 211 if (m_hdu != NULL) {
192 212 for (int i = 0; i < m_num_hdu; ++i)
... ... @@ -196,12 +216,12 @@ void GFits::append(const GFitsHDU* hdu)
196 216  
197 217 // Connect the new memory to the card pointer
198 218 m_hdu = tmp;
199   -
  219 +
200 220 // Add primary image if required
201 221 if (n_add == 2) {
202 222  
203 223 // Append empty primary image
204   - //m_hdu[m_num_hdu] = TBD
  224 + m_hdu[m_num_hdu].primary();
205 225  
206 226 // Set FITS file pointer for new HDU
207 227 __fitsfile fptr = *m_fitsfile;
... ... @@ -214,15 +234,15 @@ void GFits::append(const GFitsHDU* hdu)
214 234  
215 235 // Append new HDU to list
216 236 m_hdu[m_num_hdu] = *hdu;
217   -
  237 +
218 238 // Set FITS file pointer for new HDU
219 239 __fitsfile fptr = *m_fitsfile;
220 240 fptr.HDUposition = m_num_hdu;
221 241 m_hdu[m_num_hdu].connect(&fptr);
222   -
  242 +
223 243 // Increment number of HDUs
224 244 m_num_hdu++;
225   -
  245 +
226 246 }
227 247  
228 248 // Return
... ... @@ -233,7 +253,8 @@ void GFits::append(const GFitsHDU* hdu)
233 253 /***********************************************************************//**
234 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 259 void GFits::save(void)
239 260 {
... ... @@ -249,10 +270,15 @@ void GFits::save(void)
249 270 /***********************************************************************//**
250 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 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 288 GFits new_fits = *this;
263 289  
264 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 293 int status = 0;
267 294 status = __ffopen(&(new_fits.m_fitsfile), filename.c_str(), 1, &status);
268 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 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 322 // Return
287 323 return;
... ... @@ -310,10 +346,12 @@ void GFits::close(void)
310 346 /***********************************************************************//**
311 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 355 GFitsHDU* GFits::hdu(const std::string& extname)
318 356 {
319 357 // Initialise result to NULL pointer
... ... @@ -326,7 +364,7 @@ GFitsHDU* GFits::hdu(const std::string&amp; extname)
326 364 break;
327 365 }
328 366 }
329   -
  367 +
330 368 // Throw an error if HDU has not been found
331 369 if (ptr == NULL)
332 370 throw GException::fits_hdu_not_found(G_HDU1, extname);
... ... @@ -339,7 +377,11 @@ GFitsHDU* GFits::hdu(const std::string&amp; extname)
339 377 /***********************************************************************//**
340 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 386 GFitsHDU* GFits::hdu(int extno)
345 387 {
... ... @@ -426,13 +468,13 @@ void GFits::free_members(void)
426 468 {
427 469 // If FITS file has been opened then close it now
428 470 if (m_fitsfile != NULL) {
429   -
  471 +
430 472 // If there are no HDUs then delete the file (don't worry about error)
431 473 if (m_num_hdu == 0) {
432 474 int status = 0;
433 475 __ffdelt(m_fitsfile, &status);
434 476 }
435   -
  477 +
436 478 // ... otherwise close the file
437 479 else {
438 480 int status = 0;
... ...
src/fits/GFitsDblImage.cpp
... ... @@ -57,7 +57,7 @@ GFitsDblImage::GFitsDblImage() : GFitsImage()
57 57 /***********************************************************************//**
58 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 61 * @param naxes Number of pixels in each dimension
62 62 *
63 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 68 {
69 69 // Initialise class members for clean destruction
70 70 init_members();
71   -
  71 +
72 72 // Set bitpix
73 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 111 // Return
76 112 return;
77 113 }
... ... @@ -146,7 +182,10 @@ GFitsDblImage&amp; GFitsDblImage::operator= (const GFitsDblImage&amp; image)
146 182 /***********************************************************************//**
147 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 190 * Provides access to a pixel of a 1D image. No range checking is performed.
152 191 * Use the at(ix) method if range checking is required.
... ... @@ -155,11 +194,11 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix)
155 194 {
156 195 // Operator is only valid for 1D images
157 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 199 // If image pixels are not available then allocate them now
161 200 if (m_pixels == NULL) fetch_pixels();
162   -
  201 +
163 202 // Return image pixel
164 203 return m_pixels[ix];
165 204 }
... ... @@ -168,7 +207,10 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix)
168 207 /***********************************************************************//**
169 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 215 * Provides access to a pixel of a 1D image. No range checking is performed.
174 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 219 {
178 220 // Operator is only valid for 1D images
179 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 224 // If image pixels are not available then allocate them now
183 225 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
184   -
  226 +
185 227 // Return image pixel
186 228 return m_pixels[ix];
187 229 }
... ... @@ -190,8 +232,11 @@ const double&amp; GFitsDblImage::operator() (const int&amp; ix) const
190 232 /***********************************************************************//**
191 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 241 * Provides access to a pixel of a 2D image. No range checking is performed.
197 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 245 {
201 246 // Operator is only valid for 2D images
202 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 250 // If image pixels are not available then allocate them now
206 251 if (m_pixels == NULL) fetch_pixels();
207   -
  252 +
208 253 // Calculate pixel offset
209 254 int offset = ix + iy * m_naxes[0];
210   -
  255 +
211 256 // Return image pixel
212 257 return m_pixels[offset];
213 258 }
... ... @@ -216,8 +261,11 @@ double&amp; GFitsDblImage::operator() (const int&amp; ix, const int&amp; iy)
216 261 /***********************************************************************//**
217 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 270 * Provides access to a pixel of a 2D image. No range checking is performed.
223 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 274 {
227 275 // Operator is only valid for 2D images
228 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 279 // If image pixels are not available then allocate them now
232 280 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
233   -
  281 +
234 282 // Calculate pixel offset
235 283 int offset = ix + iy * m_naxes[0];
236   -
  284 +
237 285 // Return image pixel
238 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 290 /***********************************************************************//**
243 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 300 * Provides access to a pixel of a 3D image. No range checking is performed.
250 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 304 {
254 305 // Operator is only valid for 3D images
255 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 309 // If image pixels are not available then allocate them now
259 310 if (m_pixels == NULL) fetch_pixels();
260   -
  311 +
261 312 // Calculate pixel offset
262 313 int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]);
263   -
  314 +
264 315 // Return image pixel
265 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 320 /***********************************************************************//**
270 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 330 * Provides access to a pixel of a 3D image. No range checking is performed.
277 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 334 {
281 335 // Operator is only valid for 3D images
282 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 339 // If image pixels are not available then allocate them now
286 340 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
287   -
  341 +
288 342 // Calculate pixel offset
289 343 int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]);
290   -
  344 +
291 345 // Return image pixel
292 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 350 /***********************************************************************//**
297 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 361 * Provides access to a pixel of a 4D image. No range checking is performed.
305 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 365 {
309 366 // Operator is only valid for 4D images
310 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 370 // If image pixels are not available then allocate them now
314 371 if (m_pixels == NULL) fetch_pixels();
315   -
  372 +
316 373 // Calculate pixel offset
317 374 int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2]));
318   -
  375 +
319 376 // Return image pixel
320 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 381 /***********************************************************************//**
325 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 392 * Provides access to a pixel of a 4D image. No range checking is performed.
333 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 396 {
337 397 // Operator is only valid for 4D images
338 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 401 // If image pixels are not available then allocate them now
342 402 if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels();
343   -
  403 +
344 404 // Calculate pixel offset
345 405 int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2]));
346   -
  406 +
347 407 // Return image pixel
348 408 return m_pixels[offset];
349 409 }
... ... @@ -367,13 +427,13 @@ void GFitsDblImage::open(__fitsfile* fptr)
367 427 {
368 428 // Initialise base class members
369 429 GFitsImage::init_members();
370   -
  430 +
371 431 // Initialise class members
372 432 init_members();
373   -
  433 +
374 434 // Open image
375 435 open_image(fptr);
376   -
  436 +
377 437 // Return
378 438 return;
379 439 }
... ... @@ -398,10 +458,10 @@ void GFitsDblImage::link(double* pixels)
398 458 if (!m_linked) {
399 459 if (m_pixels != NULL) delete [] m_pixels;
400 460 }
401   -
  461 +
402 462 // Link pixel array to image
403 463 m_pixels = pixels;
404   -
  464 +
405 465 // Flag that pixels have been linked
406 466 m_linked = 1;
407 467  
... ... @@ -419,7 +479,7 @@ void GFitsDblImage::save(void)
419 479 {
420 480 // Save a double precision image
421 481 save_image(__TDOUBLE, m_pixels);
422   -
  482 +
423 483 // Return
424 484 return;
425 485 }
... ... @@ -442,10 +502,10 @@ void GFitsDblImage::close(void)
442 502  
443 503 // Free base class members
444 504 GFitsImage::free_members();
445   -
  505 +
446 506 // Initialise base class members
447 507 GFitsImage::init_members();
448   -
  508 +
449 509 // Return
450 510 return;
451 511 }
... ... @@ -457,7 +517,7 @@ void GFitsDblImage::close(void)
457 517 * Cloning provides a copy of the FITS file. Cloning is used to allocate
458 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 522 // Clone this image
463 523 return new GFitsDblImage(*this);
... ... @@ -534,12 +594,12 @@ void GFitsDblImage::copy_members(const GFitsDblImage&amp; image)
534 594 // Copy attributes
535 595 m_linked = image.m_linked;
536 596 m_anynul = image.m_anynul;
537   -
  597 +
538 598 // Copy pixels
539 599 if (m_linked)
540 600 m_pixels = image.m_pixels;
541 601 else {
542   - if (m_num_pixels > 0) {
  602 + if (m_num_pixels > 0 && image.m_pixels != NULL) {
543 603 m_pixels = new double[m_num_pixels];
544 604 memcpy(m_pixels, image.m_pixels, m_num_pixels*sizeof(double));
545 605 }
... ... @@ -566,10 +626,10 @@ void GFitsDblImage::free_members(void)
566 626 if (!m_linked) {
567 627 if (m_pixels != NULL) delete [] m_pixels;
568 628 }
569   -
  629 +
570 630 // Free NULL value
571 631 if (m_nulval != NULL) delete m_nulval;
572   -
  632 +
573 633 // Mark memory as free
574 634 m_linked = 0;
575 635 m_pixels = NULL;
... ... @@ -602,14 +662,14 @@ void GFitsDblImage::fetch_pixels(void)
602 662 if (!m_linked) {
603 663 if (m_pixels != NULL) delete [] m_pixels;
604 664 }
605   -
  665 +
606 666 // Allocate fresh image pixels
607 667 m_pixels = new double[m_num_pixels];
608 668  
609 669 // Case 1: A FITS is attached. Load pixels now.
610 670 if (m_fitsfile.Fptr != NULL)
611 671 load_image(__TDOUBLE, m_pixels, m_nulval, &m_anynul);
612   -
  672 +
613 673 // Case 2: No FITS file is attached. Allocate pixels and set them all to 0.0
614 674 else {
615 675 for (int i = 0; i < m_num_pixels; ++i)
... ...
src/fits/GFitsHDU.cpp
... ... @@ -57,7 +57,10 @@ GFitsHDU::GFitsHDU()
57 57 /***********************************************************************//**
58 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 65 * IMPLEMENTATION NOT YET FINISHED (NEEDS KEYWORD SETTING)
63 66 ***************************************************************************/
... ... @@ -65,15 +68,32 @@ GFitsHDU::GFitsHDU(const GFitsImage&amp; image)
65 68 {
66 69 // Initialise class members for clean destruction
67 70 init_members();
68   -
  71 +
69 72 // Copy image into HDU data
70 73 m_data = image.clone();
71   -
  74 +
72 75 // Allocate new header
73 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 98 // Return
79 99 return;
... ... @@ -202,7 +222,12 @@ void GFitsHDU::open(__fitsfile* fptr, int hdunum)
202 222 m_data->open(&m_fitsfile);
203 223  
204 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 231 if (m_name.length() == 0) {
207 232 if (hdunum == 1)
208 233 m_name = "Primary";
... ... @@ -230,7 +255,7 @@ void GFitsHDU::save(void)
230 255 // Move to HDU
231 256 int status = 0;
232 257 status = __ffmahd(&m_fitsfile, m_hdunum, NULL, &status);
233   -
  258 +
234 259 // If HDU does not yet exist in file then create it now. This works even
235 260 // in the case that the actual HDU has no associated header and/or data
236 261 // (these will be created automatically). However, to make this work we have
... ... @@ -259,18 +284,18 @@ void GFitsHDU::save(void)
259 284 }
260 285 }
261 286 }
262   -
  287 +
263 288 // If they exist then save data and header
264 289 if (m_data != NULL) {
265 290 m_data->save();
266 291 if (m_header != NULL)
267   - m_header->save();
  292 + m_header->save(&m_fitsfile);
268 293 }
269   -
  294 +
270 295 // ... otherwise make sure that the FITS file has at least a primary
271 296 // image.
272 297 else {
273   -
  298 +
274 299 // Special case: The first HDU does not exist. A FITS file needs at least
275 300 // one primary HDU. Thus an empty image is created.
276 301 if (m_fitsfile.HDUposition == 0) {
... ... @@ -278,9 +303,9 @@ void GFitsHDU::save(void)
278 303 if (status != 0)
279 304 throw GException::fits_error(G_SAVE, status);
280 305 if (m_header != NULL)
281   - m_header->save();
  306 + m_header->save(&m_fitsfile);
282 307 }
283   -
  308 +
284 309 } // endelse: no data were available
285 310  
286 311 // Return
... ... @@ -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 343 * @brief Return pointer to column of table
293 344 *
294 345 * @param colname Name of FITS table column to be returned
... ... @@ -329,20 +380,20 @@ void GFitsHDU::primary(void)
329 380 {
330 381 // Free any allocated header and data
331 382 free_members();
332   -
  383 +
333 384 // Create primary image in memory
334 385 int status = 0;
335 386 __fitsfile* fptr;
336 387 status = __ffinit(&fptr, "mem://", &status);
337 388 status = __ffcrim(fptr, 8, 0, NULL, &status);
338   -
  389 +
339 390 // Open HDU
340 391 this->open(fptr,1);
341   -
  392 +
342 393 // Detach FITS file pointer
343 394 this->m_fitsfile.HDUposition = 0;
344 395 this->m_fitsfile.Fptr = NULL;
345   -
  396 +
346 397 // Return
347 398 return;
348 399 }
... ... @@ -429,10 +480,10 @@ void GFitsHDU::connect(__fitsfile* fptr)
429 480 // First connect HDU
430 481 m_fitsfile = *fptr;
431 482 m_hdunum = m_fitsfile.HDUposition + 1;
432   -
  483 +
433 484 // Then connect data
434 485 if (m_data != NULL) m_data->connect(fptr);
435   -
  486 +
436 487 // Return
437 488 return;
438 489 }
... ... @@ -457,7 +508,7 @@ GFitsImage* GFitsHDU::new_image(void)
457 508 {
458 509 // Initialise return value
459 510 GFitsImage* image = NULL;
460   -
  511 +
461 512 // Get number of bits per pixel
462 513 int status = 0;
463 514 int bitpix = -64;
... ... @@ -528,11 +579,11 @@ ostream&amp; operator&lt;&lt; (ostream&amp; os, const GFitsHDU&amp; hdu)
528 579 os << "Unknown" << endl;
529 580 break;
530 581 }
531   -
  582 +
532 583 // Put FITS header in stream
533 584 if (hdu.m_header != NULL)
534 585 os << *hdu.m_header;
535   -
  586 +
536 587 // Put FITS data in stream
537 588 if (hdu.m_data != NULL) {
538 589 switch (hdu.m_type) {
... ...
src/fits/GFitsHeader.cpp
... ... @@ -20,7 +20,10 @@
20 20 /* __ Namespaces _________________________________________________________ */
21 21  
22 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 28 /* __ Macros _____________________________________________________________ */
26 29  
... ... @@ -36,9 +39,8 @@
36 39 = =
37 40 ==========================================================================*/
38 41  
39   -/***************************************************************************
40   - * Constructor *
41   - * ----------------------------------------------------------------------- *
  42 +/***********************************************************************//**
  43 + * @brief Constructor
42 44 ***************************************************************************/
43 45 GFitsHeader::GFitsHeader()
44 46 {
... ... @@ -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 60 GFitsHeader::GFitsHeader(const GFitsHeader& header)
58 61 {
... ... @@ -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 76 GFitsHeader::~GFitsHeader()
75 77 {
... ... @@ -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 97 GFitsHeader& GFitsHeader::operator= (const GFitsHeader& header)
95 98 {
... ... @@ -121,7 +124,7 @@ GFitsHeader&amp; GFitsHeader::operator= (const GFitsHeader&amp; header)
121 124 /***********************************************************************//**
122 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 129 * Loads all header cards into memory. Any header cards that existed before
127 130 * will be dropped.
... ... @@ -157,10 +160,38 @@ void GFitsHeader::open(__fitsfile* fptr)
157 160 /***********************************************************************//**
158 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 196 // Return
166 197 return;
... ... @@ -191,49 +222,95 @@ void GFitsHeader::close(void)
191 222 * @brief Update card in header or append card to header
192 223 *
193 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 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 267 // Return
230 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 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 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 335 std::string GFitsHeader::string(const int& cardno)
256 336 {
... ... @@ -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 355 double GFitsHeader::real(const std::string& keyname)
273 356 {
... ... @@ -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 375 double GFitsHeader::real(const int& cardno)
290 376 {
... ... @@ -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 395 int GFitsHeader::integer(const std::string& keyname)
307 396 {
... ... @@ -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 415 int GFitsHeader::integer(const int& cardno)
324 416 {
... ... @@ -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 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 446 void GFitsHeader::init_members(void)
347 447 {
... ... @@ -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 462 void GFitsHeader::copy_members(const GFitsHeader& header)
362 463 {
363 464 // Copy attributes
  465 + m_num_cards = header.m_num_cards;
364 466  
365 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 470 for (int i = 0; i < m_num_cards; ++i)
370 471 m_card[i] = header.m_card[i];
371 472 }
... ... @@ -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 482 void GFitsHeader::free_members(void)
383 483 {
... ... @@ -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 506 // Set card pointer to NULL (default)
... ... @@ -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 521 // Return pointer
414 522 return ptr;
415 523 }
... ... @@ -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 538 ostream& operator<< (ostream& os, const GFitsHeader& header)
429 539 {
430 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 542 for (int i = 0; i < header.m_num_cards; ++i)
434 543 os << " " << header.m_card[i];
435 544  
... ...
src/fits/GFitsHeaderCard.cpp
... ... @@ -48,9 +48,8 @@
48 48 = =
49 49 ==========================================================================*/
50 50  
51   -/***************************************************************************
52   - * Constructor *
53   - * ----------------------------------------------------------------------- *
  51 +/***********************************************************************//**
  52 + * @brief Constructor
54 53 ***************************************************************************/
55 54 GFitsHeaderCard::GFitsHeaderCard()
56 55 {
... ... @@ -60,26 +59,91 @@ GFitsHeaderCard::GFitsHeaderCard()
60 59 // Return
61 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 75 const std::string& comment)
66 76 {
67 77 // Initialise class members for clean destruction
68 78 init_members();
69   -
  79 +
70 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 85 // Return
76 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 148 GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard& card)
85 149 {
... ... @@ -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 164 GFitsHeaderCard::~GFitsHeaderCard()
102 165 {
... ... @@ -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 185 GFitsHeaderCard& GFitsHeaderCard::operator= (const GFitsHeaderCard& card)
121 186 {
122 187 // Execute only if object is not identical
123 188 if (this != &card) {
124   -
  189 +
125 190 // Free members
126 191 free_members();
127   -
  192 +
128 193 // Initialise private members for clean destruction
129 194 init_members();
130 195  
131 196 // Copy members
132 197 copy_members(card);
133   -
  198 +
134 199 } // endif: object was not identical
135 200  
136 201 // Return this object
... ... @@ -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 381 std::string GFitsHeaderCard::string(void)
152 382 {
... ... @@ -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 414 double GFitsHeaderCard::real(void)
182 415 {
... ... @@ -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 449 int GFitsHeaderCard::integer(void)
214 450 {
... ... @@ -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 483 void GFitsHeaderCard::read(__fitsfile* fptr, int keynum)
246 484 {
... ... @@ -264,18 +502,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, int keynum)
264 502 m_comment.assign(comment);
265 503  
266 504 // Determine card type
267   - m_value_type = get_value_type();
  505 + m_value_type = get_value_type(m_value);
268 506  
269 507 // Return
270 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 520 // Move to HDU
281 521 int status = 0;
... ... @@ -300,16 +540,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, std::string keyname)
300 540 m_comment.assign(comment);
301 541  
302 542 // Determine card type
303   - m_value_type = get_value_type();
  543 + m_value_type = get_value_type(m_value);
304 544  
305 545 // Return
306 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 558 void GFitsHeaderCard::write(__fitsfile* fptr)
315 559 {
... ... @@ -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 586 void GFitsHeaderCard::init_members(void)
344 587 {
... ... @@ -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 605 void GFitsHeaderCard::copy_members(const GFitsHeaderCard& card)
362 606 {
... ... @@ -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 622 void GFitsHeaderCard::free_members(void)
380 623 {
... ... @@ -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 649 // Get index of last string element
393 650 int last = m_value.length() - 1;
... ... @@ -417,7 +674,8 @@ int GFitsHeaderCard::get_value_type(void)
417 674 int found_int = 0;
418 675 int found_float = 0;
419 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 679 found_int = 1;
422 680 else if (m_value[i] == '.' || m_value[i] == 'e' || m_value[i] == 'E')
423 681 found_float = 1;
... ... @@ -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 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 778 // Return output stream
462 779 return os;
... ...
src/fits/GFitsImage.cpp
... ... @@ -125,7 +125,7 @@ GFitsImage::~GFitsImage()
125 125 /***********************************************************************//**
126 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 130 GFitsImage& GFitsImage::operator= (const GFitsImage& image)
131 131 {
... ... @@ -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 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 186 int GFitsImage::naxes(int axis) const
166 187 {
... ... @@ -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 212 = GFitsImage private methods =
... ... @@ -203,7 +234,7 @@ void GFitsImage::init_members(void)
203 234 /***********************************************************************//**
204 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 239 void GFitsImage::copy_members(const GFitsImage& image)
209 240 {
... ... @@ -232,7 +263,7 @@ void GFitsImage::free_members(void)
232 263 {
233 264 // Free memory
234 265 if (m_naxes != NULL) delete [] m_naxes;
235   -
  266 +
236 267 // Mark memory as free
237 268 m_naxes = NULL;
238 269  
... ... @@ -244,13 +275,13 @@ void GFitsImage::free_members(void)
244 275 /***********************************************************************//**
245 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 280 void GFitsImage::connect(__fitsfile* fptr)
250 281 {
251 282 // Connect Image
252 283 m_fitsfile = *fptr;
253   -
  284 +
254 285 // Return
255 286 return;
256 287 }
... ... @@ -259,7 +290,7 @@ void GFitsImage::connect(__fitsfile* fptr)
259 290 /***********************************************************************//**
260 291 * @brief Open Image
261 292 *
262   - * @param fptr FITS file pointer
  293 + * @param[in] fptr FITS file pointer
263 294 *
264 295 * Open FITS image in FITS file. Opening means connecting the FITS file
265 296 * pointer to the image and reading the image and axes dimensions.
... ... @@ -274,7 +305,7 @@ void GFitsImage::open_image(__fitsfile* fptr)
274 305  
275 306 // Save FITS file pointer
276 307 m_fitsfile = *fptr;
277   -
  308 +
278 309 // Get the image dimensions
279 310 status = __ffgidm(&m_fitsfile, &m_naxis, &status);
280 311 if (status != 0)
... ... @@ -285,7 +316,7 @@ void GFitsImage::open_image(__fitsfile* fptr)
285 316  
286 317 // Get the axes dimensions
287 318 if (m_naxis > 0) {
288   -
  319 +
289 320 // Allocate memory for axes dimensions
290 321 if (m_naxes != NULL) delete [] m_naxes;
291 322 m_naxes = new long[m_naxis];
... ... @@ -294,14 +325,14 @@ void GFitsImage::open_image(__fitsfile* fptr)
294 325 status = __ffgisz(&m_fitsfile, m_naxis, m_naxes, &status);
295 326 if (status != 0)
296 327 throw GException::fits_error(G_OPEN_IMAGE, status);
297   -
  328 +
298 329 // Calculate number of image pixels
299 330 m_num_pixels = 1;
300 331 for (int i = 0; i < m_naxis; ++i)
301 332 m_num_pixels *= m_naxes[i];
302 333  
303 334 } // endif: there is an image
304   -
  335 +
305 336 // Return
306 337 return;
307 338 }
... ... @@ -310,8 +341,8 @@ void GFitsImage::open_image(__fitsfile* fptr)
310 341 /***********************************************************************//**
311 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 347 * Save image pixels into FITS file. In case that the HDU does not exist it
317 348 * is created.
... ... @@ -352,18 +383,19 @@ void GFitsImage::load_image(int datatype, const void* pixels, const void* nulval
352 383 /***********************************************************************//**
353 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 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 393 void GFitsImage::save_image(int datatype, const void* pixels)
362 394 {
363 395 // Move to HDU
364 396 int status = 0;
365 397 status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status);
366   -
  398 +
367 399 // If HDU does not yet exist in file then create it now
368 400 if (status == 107) {
369 401 status = 0;
... ... @@ -388,7 +420,7 @@ void GFitsImage::save_image(int datatype, const void* pixels)
388 420 }
389 421  
390 422 // Save the image pixels (if there are some ...)
391   - if (m_naxis > 0) {
  423 + if (m_naxis > 0 && pixels != NULL) {
392 424 long* fpixel = new long[m_naxis];
393 425 long* lpixel = new long[m_naxis];
394 426 for (int i = 0; i < m_naxis; ++i) {
... ...
src/rsp/GLATResponse.cpp
... ... @@ -18,11 +18,14 @@
18 18 #include "GVector.hpp"
19 19 #include "GLATResponse.hpp"
20 20 #include "GFits.hpp"
  21 +#include "GFitsHDU.hpp"
  22 +#include "GFitsDblImage.hpp"
21 23 #include "GFitsTableFltCol.hpp"
22 24  
23 25 /* __ Namespaces _________________________________________________________ */
24 26  
25 27 /* __ Method name definitions ____________________________________________ */
  28 +#define G_LOAD "load(const std::string&, const std::string&)"
26 29 #define G_INIT_AEFF "GLATResponse::init_aeff()"
27 30 #define G_INIT_PSF "GLATResponse::init_psf()"
28 31 #define G_INIT_EDISP "GLATResponse::init_edisp()"
... ... @@ -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 65 GLATResponse::GLATResponse() : GResponse()
64 66 {
... ... @@ -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 80 GLATResponse::GLATResponse(const GLATResponse& rsp) : GResponse(rsp)
78 81 {
... ... @@ -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 96 GLATResponse::~GLATResponse()
95 97 {
... ... @@ -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 117 GLATResponse& GLATResponse::operator= (const GLATResponse& rsp)
115 118 {
... ... @@ -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 150 double GLATResponse::irf(const GSkyDir& obsDir, const double& obsEng,
149 151 const GSkyDir& srcDir, const double& srcEng,
... ... @@ -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 163 double GLATResponse::aeff(const GSkyDir& obsDir, const double& obsEng,
163 164 const GSkyDir& srcDir, const double& srcEng,
... ... @@ -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 176 double GLATResponse::psf(const GSkyDir& obsDir, const double& obsEng,
177 177 const GSkyDir& srcDir, const double& srcEng,
... ... @@ -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 189 double GLATResponse::edisp(const GSkyDir& obsDir, const double& obsEng,
191 190 const GSkyDir& srcDir, const double& srcEng,
... ... @@ -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 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 208 // Simply copy path
210 209 // NOTE: Some check should be done on whether the path exists !!!
... ... @@ -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 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 228 // Store response name
228 229 m_rspname = rspname;
229   -
230   - // Convert response type
  230 +
  231 + // Convert response type string to section
231 232 if (rsptype == "front")
232 233 m_section = 0;
233 234 else if (rsptype == "back")
234 235 m_section = 1;
235 236 else
236   - throw;
  237 + throw GException::rsp_invalid_type(G_LOAD, rsptype);
  238 +
  239 + // Store response type
237 240 m_rsptype = rsptype;
238 241  
239 242 // Initialise effective area
... ... @@ -244,18 +247,46 @@ void GLATResponse::load(std::string rspname, std::string rsptype)
244 247  
245 248 // Initialise energy dispersion
246 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 359 GVector v_sigma = get_fits_vector(hdu, "SIGMA");
329 360 GVector v_gcore = get_fits_vector(hdu, "GCORE");
330 361 GVector v_gtail = get_fits_vector(hdu, "GTAIL");
331   -
  362 +
332 363 // Set binning in angle, energy and cos theta
333 364 m_psf_angle_num = 2000;
334 365 m_psf_angle_min = 0.01;
335 366 m_psf_angle_bin = 0.01;
336 367 m_psf_energy_num = v_energy_lo.size();
337 368 m_psf_ctheta_num = v_ctheta_lo.size();
338   -
  369 +
339 370 // Free old PSF memory
340 371 if (m_psf != NULL) delete [] m_psf;
341 372 if (m_norm != NULL) delete [] m_norm;
... ... @@ -347,7 +378,7 @@ void GLATResponse::psf_init(void)
347 378 m_psf = new double[psf_size];
348 379 m_norm = new double[bin_size];
349 380 m_sigma = new double[bin_size];
350   -
  381 +
351 382 // Setup PSF vector axis
352 383 GVector xaxis(m_psf_angle_num);
353 384 GVector u(m_psf_angle_num);
... ... @@ -356,46 +387,46 @@ void GLATResponse::psf_init(void)
356 387 xaxis(i) = x;
357 388 u(i) = 0.5*x*x;
358 389 }
359   -
  390 +
360 391 // Get maximum angle
361 392 m_psf_angle_max = xaxis(m_psf_angle_num-1);
362   -
  393 +
363 394 // Loop over all energy bins
364 395 for (int ie = 0; ie < m_psf_energy_num; ++ie) {
365   -
  396 +
366 397 // Get mean energy of bin
367 398 // NOTE: This should be replaced by a logarithmic mean
368 399 double energy = 0.5 * (v_energy_lo(ie) + v_energy_hi(ie));
369   -
  400 +
370 401 // Get scale at specified energy
371 402 double scale = psf_scale(energy);
372   -
  403 +
373 404 // Loop over all cos theta bins
374 405 for (int ic = 0; ic < m_psf_ctheta_num; ++ic) {
375   -
  406 +
376 407 // Extract PSF parameters
377 408 int inx = ic * m_psf_energy_num + ie;
378 409 double ncore = v_ncore(inx);
379 410 double sigma = v_sigma(inx);
380 411 double gcore = v_gcore(inx);
381 412 double gtail = v_gtail(inx);
382   -
  413 +
383 414 // Evaluate ntail
384 415 double denom = psf_base_value(10.0, gtail);
385 416 double ntail = (denom != 0.0) ? ncore * psf_base_value(10.0, gcore) / denom : 0.0;
386   -
  417 +
387 418 // Calculate PSF dependence
388 419 GVector psf = ncore * psf_base_vector(u, gcore) + ntail * psf_base_vector(u, gtail);
389   -
  420 +
390 421 // Normalize PSF vector to identical amplitudes at smallest angular
391 422 // distance. This allows for accurate interpolation afterwards
392 423 double norm = 1.0 / psf(0);
393 424 psf *= norm;
394   -
  425 +
395 426 // Evaluate angular separation
396 427 double stretch = sigma * scale;
397 428 GVector delta = xaxis * stretch;
398   -
  429 +
399 430 // Calculate PSF normalization factor
400 431 double sum = 0.0;
401 432 for (int i = 0; i < m_psf_angle_num; ++i) {
... ... @@ -405,16 +436,16 @@ void GLATResponse::psf_init(void)
405 436 }
406 437 sum *= twopi;
407 438 norm = scale / sum;
408   -
  439 +
409 440 // Store PSF information
410 441 m_norm[inx] = norm;
411 442 m_sigma[inx] = sigma;
412   -
  443 +
413 444 // Store PSF vector
414 445 int ipsf = inx * m_psf_angle_num;
415 446 for (int i = 0; i < m_psf_angle_num; ++i, ++ipsf)
416 447 m_psf[ipsf] = psf(i);
417   -
  448 +
418 449 } // endfor: looped over cos theta
419 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 467 // Interpolate sigma and norm tables
437 468 double sigma = 1.0; // Perform bi-linear interpolation in logE and ctheta
438 469 double norm = 1.0; // Perform bi-linear interpolation in logE and ctheta
439   -
  470 +
440 471 // Evaluate scale
441 472 double energy = pow(10.0,logE); // DUMMY: t=(0.01*(10.0^logE))^-0.8
442 473 double scale = psf_scale(energy);
443   -
  474 +
444 475 // Get stretch factor
445 476 double stretch = sigma * scale;
446   -
  477 +
447 478 // Get PSF value from table
448 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 481 double psf = 1.0;
451   -
  482 +
452 483 // Normalize PSF
453 484 psf *= norm;
454   -
  485 +
455 486 // Return PSF value
456 487 return psf;
457 488 }
... ...
test/test_GFits.cpp
... ... @@ -38,18 +38,18 @@ int dequal(double val, double ref)
38 38 ***************************************************************************/
39 39 void test_open(void)
40 40 {
41   - std::cout << "Test GFits: Open FITS file: ";
  41 + cout << "Test GFits: Open FITS file: ";
42 42 try {
43 43 GFits fits;
44 44 fits.open("test_GFits.fits");
45 45 cout << endl << fits;
46 46 }
47 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 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 64 fits.open("test_GFits.fits");
65 65 }
66 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 69 throw;
70 70 }
71 71  
72 72 //
73 73 // Test single string column
74 74 //
75   - std::cout << "Test GFits: String column handling: ";
  75 + cout << "Test GFits: String column handling: ";
76 76 try {
77 77 GFitsTableStrCol str = *((GFitsTableStrCol*)fits.hdu("BinTable")->column("TSTRING"));
78 78 if (str.string(0) != "1" || str.string(1) != "2" || str.string(2) != "") {
... ... @@ -93,16 +93,16 @@ void test_columns(void)
93 93 std::cout << ".";
94 94 }
95 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 98 throw;
99 99 }
100   - std::cout << ". ok." << std::endl;
  100 + cout << ". ok." << endl;
101 101  
102 102 //
103 103 // Test single short column
104 104 //
105   - std::cout << "Test GFits: Short column handling: ";
  105 + cout << "Test GFits: Short column handling: ";
106 106 try {
107 107 GFitsTableShtCol sht = *((GFitsTableShtCol*)fits.hdu("BinTable")->column("TSHORT"));
108 108 if (sht.integer(0) != 1 || sht.real(0) != 1.0 || sht.string(0) != "1" ||
... ... @@ -115,16 +115,16 @@ void test_columns(void)
115 115 std::cout << ".";
116 116 }
117 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 120 throw;
121 121 }
122   - std::cout << ". ok." << std::endl;
  122 + cout << ". ok." << endl;
123 123  
124 124 //
125 125 // Test single long column
126 126 //
127   - std::cout << "Test GFits: Long column handling: ";
  127 + cout << "Test GFits: Long column handling: ";
128 128 try {
129 129 GFitsTableLngCol lng = *((GFitsTableLngCol*)fits.hdu("BinTable")->column("TLONG"));
130 130 if (lng.integer(0) != 10 || lng.real(0) != 10.0 || lng.string(0) != "10" ||
... ... @@ -134,14 +134,14 @@ void test_columns(void)
134 134 throw;
135 135 }
136 136 else
137   - std::cout << ".";
  137 + cout << ".";
138 138 }
139 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 142 throw;
143 143 }
144   - std::cout << ". ok." << std::endl;
  144 + cout << ". ok." << endl;
145 145  
146 146 //
147 147 // Test single floating point column
... ... @@ -215,11 +215,11 @@ void test_columns(void)
215 215 }
216 216 }
217 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 220 throw;
221 221 }
222   - std::cout << ". ok." << std::endl;
  222 + cout << ". ok." << endl;
223 223  
224 224 //
225 225 // Test single double column
... ... @@ -280,11 +280,11 @@ void test_columns(void)
280 280 std::cout << ".";
281 281 }
282 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 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 296 {
297 297 // Dump header
298 298 cout << "Test GFits: Create FITS file: ";
299   -
  299 +
300 300 // Remove FITS file
301 301 system("rm -rf test.fits");
302   -
  302 +
303 303 // Create FITS file with empty double precision image
304 304 try {
305 305 GFits fits;
... ... @@ -307,6 +307,7 @@ void test_create(void)
307 307 GFitsDblImage image;
308 308 GFitsHDU hdu(image);
309 309 fits.append(&hdu);
  310 + //cout << fits;
310 311 fits.save();
311 312 }
312 313 catch (exception &e) {
... ... @@ -315,7 +316,7 @@ void test_create(void)
315 316 throw;
316 317 }
317 318 cout << ".";
318   -
  319 +
319 320 // Attach double precision image
320 321 double sum = 0.0;
321 322 try {
... ... @@ -334,6 +335,7 @@ void test_create(void)
334 335 }
335 336 GFitsHDU hdu(image);
336 337 fits.append(&hdu);
  338 + cout << fits;
337 339 fits.save();
338 340 }
339 341 catch (exception &e) {
... ... @@ -342,7 +344,7 @@ void test_create(void)
342 344 throw;
343 345 }
344 346 cout << ".";
345   -
  347 +
346 348 // Re-open double precision image
347 349 try {
348 350 GFits fits;
... ... @@ -408,12 +410,12 @@ void test_image_double(void)
408 410 throw;
409 411 }
410 412 cout << ".";
411   -
  413 +
412 414 // Bad 2D operator
413 415 try {
414 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 419 cout << ".";
418 420 }
419 421 catch (exception &e) {
... ... @@ -426,7 +428,7 @@ void test_image_double(void)
426 428 try {
427 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 432 cout << ".";
431 433 }
432 434 catch (exception &e) {
... ... @@ -439,7 +441,7 @@ void test_image_double(void)
439 441 try {
440 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 445 cout << ".";
444 446 }
445 447 catch (exception &e) {
... ... @@ -447,7 +449,7 @@ void test_image_double(void)
447 449 cout << e.what() << endl;
448 450 throw;
449 451 }
450   -
  452 +
451 453 }
452 454 catch (exception &e) {
453 455 cout << endl << "TEST ERROR: Unable to test GFitsDblImage classes." << endl;
... ...
test/test_GResponse.cpp
... ... @@ -12,8 +12,9 @@
12 12 ***************************************************************************/
13 13  
14 14 /* __ Includes ___________________________________________________________ */
  15 +#include <stdlib.h>
  16 +#include <iostream>
15 17 #include "test_GResponse.hpp"
16   -#include <iostream> // cout, cerr
17 18  
18 19 /* __ Namespaces _________________________________________________________ */
19 20  
... ... @@ -25,31 +26,18 @@
25 26 ***************************************************************************/
26 27 void test_lat_response(void)
27 28 {
  29 + // Remove FITS file
  30 + system("rm -rf test_rsp.fits");
  31 +
28 32 cout << "Test GLATResponse: Open PSF FITS file: ";
29 33 try {
30 34 // Get HANDOFF Response
31 35 GLATResponse rsp;
32 36 rsp.set_caldb("irf/lat");
33 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 42 catch (exception &e) {
55 43 cout << endl << "TEST ERROR: Unable to open FITS file." << endl;
... ...