From 966fb927bbd6fc3434c42cb2aa1dce93302aa448 Mon Sep 17 00:00:00 2001 From: knodlseder <> Date: Mon, 3 Mar 2008 16:42:19 +0000 Subject: [PATCH] improve doxygen documentation --- include/GException.hpp | 16 ++++++++++++++-- include/GFits.hpp | 10 +++++----- include/GFitsDblImage.hpp | 1 + include/GFitsHDU.hpp | 15 ++++++++------- include/GFitsHeader.hpp | 38 ++++++++++++++++++-------------------- include/GFitsHeaderCard.hpp | 61 ++++++++++++++++++++++++++++++++++++------------------------- include/GFitsImage.hpp | 17 +++++++++-------- include/GLATResponse.hpp | 17 ++++++----------- include/GResponse.hpp | 2 +- src/GException.cpp | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------- src/fits/GFits.cpp | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------- src/fits/GFitsDblImage.cpp | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------ src/fits/GFitsHDU.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- src/fits/GFitsHeader.cpp | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------- src/fits/GFitsHeaderCard.cpp | 447 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------- src/fits/GFitsImage.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++------------------ src/rsp/GLATResponse.cpp | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------- test/test_GFits.cpp | 70 ++++++++++++++++++++++++++++++++++++---------------------------------- test/test_GResponse.cpp | 26 +++++++------------------- 19 files changed, 1281 insertions(+), 541 deletions(-) diff --git a/include/GException.hpp b/include/GException.hpp index 59e2600..a08783a 100644 --- a/include/GException.hpp +++ b/include/GException.hpp @@ -135,6 +135,12 @@ public: fits_open_error(string origin, string filename, int status); }; + // FITS file exists already + class fits_file_exist : public GExceptionHandler { + public: + fits_file_exist(string origin, string filename, int status); + }; + // FITS file has already been opened class fits_already_opened : public GExceptionHandler { public: @@ -190,9 +196,15 @@ public: }; // FITS bad image operator - class fits_bad_image_operator : public GExceptionHandler { + class fits_wrong_image_operator : public GExceptionHandler { + public: + fits_wrong_image_operator(string origin, int naxis, int nargs); + }; + + // Response invalid response type + class rsp_invalid_type : public GExceptionHandler { public: - fits_bad_image_operator(string origin, int naxis, int nargs); + rsp_invalid_type(string origin, string type); }; }; diff --git a/include/GFits.hpp b/include/GFits.hpp index f48e45b..257c811 100644 --- a/include/GFits.hpp +++ b/include/GFits.hpp @@ -30,7 +30,7 @@ /***********************************************************************//** * @class GFits * - * @brief Implements a FITS file interface + * @brief Implements FITS file interface * * GFits is the basic FITS file interface. All FITS file handlings operate * via members of GFits. A FITS file is composed of Header Data Units (HDU) @@ -66,10 +66,10 @@ private: void free_members(void); // Private data area - std::string m_filename; // FITS file name - __fitsfile* m_fitsfile; // FITS file pointer - int m_num_hdu; // Number of HDUs in file - GFitsHDU* m_hdu; // Pointers to HDUs + std::string m_filename; //!< FITS file name + __fitsfile* m_fitsfile; //!< FITS file pointer + int m_num_hdu; //!< Number of HDUs in file + GFitsHDU* m_hdu; //!< Pointers to HDUs }; diff --git a/include/GFitsDblImage.hpp b/include/GFitsDblImage.hpp index dafb3d1..7685a86 100644 --- a/include/GFitsDblImage.hpp +++ b/include/GFitsDblImage.hpp @@ -39,6 +39,7 @@ public: // Constructors and destructors GFitsDblImage(); GFitsDblImage(int naxis, const int* naxes); + GFitsDblImage(int naxis, const int* naxes, const double* pixels); GFitsDblImage(const GFitsDblImage& image); ~GFitsDblImage(); diff --git a/include/GFitsHDU.hpp b/include/GFitsHDU.hpp index 37bfcbd..7b7ee49 100644 --- a/include/GFitsHDU.hpp +++ b/include/GFitsHDU.hpp @@ -32,7 +32,7 @@ /***********************************************************************//** * @class GFitsHDU * - * @brief Implements the FITS Header Data Unit (HDU) + * @brief Implements the FITS Header Data Unit (HDU) interface * * The HDU is the basic unit of a FITS file. Each HDU consists of a header * and a data area. The header is composed of cards and is implemented by @@ -61,6 +61,7 @@ public: void open(__fitsfile* fptr, int hdunum); void save(void); std::string extname(void) const; + void extname(const std::string& extname); int extno(void) const; int exttype(void) const; GFitsHeader* header(void) const; @@ -77,12 +78,12 @@ private: GFitsImage* new_image(void); // Private data area - __fitsfile m_fitsfile; // FITS file pointer - int m_hdunum; // HDU number (starting from 1) - std::string m_name; // HDU name - int m_type; // HDU type - GFitsHeader* m_header; // HDU header - GFitsData* m_data; // HDU data + __fitsfile m_fitsfile; //!< FITS file pointer + int m_hdunum; //!< HDU number (starting from 1) + std::string m_name; //!< HDU name (extname) + int m_type; //!< HDU type + GFitsHeader* m_header; //!< HDU header + GFitsData* m_data; //!< HDU data }; diff --git a/include/GFitsHeader.hpp b/include/GFitsHeader.hpp index 5d7ccee..237a0bb 100644 --- a/include/GFitsHeader.hpp +++ b/include/GFitsHeader.hpp @@ -10,6 +10,11 @@ * (at your option) any later version. * * * ***************************************************************************/ +/** + * @file GFitsHeader.hpp + * @brief GFitsHeader class definition. + * @author J. Knodlseder + */ #ifndef GFITSHEADER_HPP #define GFITSHEADER_HPP @@ -21,8 +26,16 @@ /* __ Namespaces _________________________________________________________ */ -/*************************************************************************** - * GFitsHeader class definition * +/***********************************************************************//** + * @class GFitsHeader + * + * @brief Interface for FITS header class + * + * The FITS header class contains all cards that are found in the header of + * a HDU. All cards will be hold in memory, so no link to a FITS file is + * required. Cards may be read from one file (using the 'open' method) and + * saved into another file (using the 'save' method). Cards are added or + * changed using the 'update' method. ***************************************************************************/ class GFitsHeader { @@ -40,7 +53,7 @@ public: // Methods void open(__fitsfile* fptr); - void save(void); + void save(__fitsfile* fptr); void close(void); void update(const GFitsHeaderCard& card); GFitsHeaderCard* card(const std::string& keyname); @@ -52,13 +65,13 @@ public: int integer(const std::string& keyname); int integer(const int& cardno); GFitsHeader* clone(void) const; - + private: // Private methods void init_members(void); void copy_members(const GFitsHeader& header); void free_members(void); - GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname); + GFitsHeaderCard* GFitsHeader::card_ptr(const std::string& keyname); // Private data area int m_num_cards; @@ -69,20 +82,5 @@ private: /*************************************************************************** * Inline methods * ***************************************************************************/ -inline -GFitsHeaderCard* GFitsHeader::card(const std::string& keyname) -{ - return GFitsHeader::card_ptr(keyname); -} -inline -GFitsHeaderCard* GFitsHeader::card(const int& cardno) -{ - return (cardno >= 0 && cardno < m_num_cards) ? &(m_card[cardno]) : NULL; -} -inline -GFitsHeader* GFitsHeader::clone(void) const -{ - return new GFitsHeader(*this); -} #endif /* GFITSHEADER_HPP */ diff --git a/include/GFitsHeaderCard.hpp b/include/GFitsHeaderCard.hpp index 1ad4e8b..ceb98b2 100644 --- a/include/GFitsHeaderCard.hpp +++ b/include/GFitsHeaderCard.hpp @@ -10,6 +10,11 @@ * (at your option) any later version. * * * ***************************************************************************/ +/** + * @file GFitsHeaderCard.hpp + * @brief GFitsHeaderCard class definition. + * @author J. Knodlseder + */ #ifndef GFITSHEADERCARD_HPP #define GFITSHEADERCARD_HPP @@ -20,8 +25,14 @@ /* __ Namespaces _________________________________________________________ */ -/*************************************************************************** - * GFitsHeaderCard class definition * +/***********************************************************************//** + * @class GFitsHeaderCard + * + * @brief Implements FITS header card interface + * + * This class implements FITS header card. Each card consists of a + * keyname (string), a value (string, floating pointer, integer or logical) + * and a comment (string). COMMENT or HISTORY cards do not have any value. ***************************************************************************/ class GFitsHeaderCard { @@ -31,7 +42,11 @@ class GFitsHeaderCard { public: // Constructors & Destructors GFitsHeaderCard(); - GFitsHeaderCard(const std::string& keyname, const std::string& value, + GFitsHeaderCard(const std::string& keyname, const std::string& value, + const std::string& comment); + GFitsHeaderCard(const std::string& keyname, const double& value, + const std::string& comment); + GFitsHeaderCard(const std::string& keyname, const int& value, const std::string& comment); GFitsHeaderCard(const GFitsHeaderCard& card); ~GFitsHeaderCard(); @@ -39,7 +54,15 @@ public: // Operators GFitsHeaderCard& operator= (const GFitsHeaderCard& card); - // Methods + // Methods to set card properties + void keyname(const std::string& keyname); + void value(const std::string& value); + void value(const double& value); + void value(const int& value); + void unit(const std::string& unit); + void comment(const std::string& comment); + + // Methods to get card properties std::string keyname(void) const; std::string value(void) const; int value_type(void) const; @@ -48,12 +71,10 @@ public: std::string string(void); double real(void); int integer(void); - void set_keyname(const std::string& keyname); - void set_value(const std::string& value); - void set_unit(const std::string& unit); - void set_comment(const std::string& comment); + + // Other methods void read(__fitsfile* fptr, int keynum); - void read(__fitsfile* fptr, std::string keyname); + void read(__fitsfile* fptr, const std::string& keyname); void write(__fitsfile* fptr); private: @@ -61,29 +82,19 @@ private: void init_members(void); void copy_members(const GFitsHeaderCard& card); void free_members(void); - int get_value_type(void); + int get_value_type(const std::string& value); // Private data area - std::string m_keyname; - std::string m_value; - int m_value_type; - std::string m_unit; - std::string m_comment; + std::string m_keyname; //!< Name of the card + std::string m_value; //!< Value of the card as read from file + int m_value_type; //!< Type of the card value + std::string m_unit; //!< Unit of the card value + std::string m_comment; //!< Card comment }; /*************************************************************************** * Inline methods * ***************************************************************************/ -inline std::string GFitsHeaderCard::keyname(void) const { return m_keyname; } -inline std::string GFitsHeaderCard::value(void) const { return m_value; } -inline int GFitsHeaderCard::value_type(void) const { return m_value_type; } -inline std::string GFitsHeaderCard::unit(void) const { return m_unit; } -inline std::string GFitsHeaderCard::comment(void) const { return m_comment; } -inline void GFitsHeaderCard::set_keyname(const std::string& keyname) { m_keyname = keyname; } -inline void GFitsHeaderCard::set_value(const std::string& value) { m_value = value; } -inline void GFitsHeaderCard::set_unit(const std::string& unit) { m_unit = unit; } -inline void GFitsHeaderCard::set_comment(const std::string& comment) { m_comment = comment; } - #endif /* GFITSHEADERCARD_HPP */ diff --git a/include/GFitsImage.hpp b/include/GFitsImage.hpp index 20a557b..b0cf4d0 100644 --- a/include/GFitsImage.hpp +++ b/include/GFitsImage.hpp @@ -53,11 +53,13 @@ public: virtual void save(void) = 0; virtual void close(void) = 0; virtual GFitsImage* clone(void) const = 0; - + // Methods + int bitpix(void) const; int naxis(void) const; int naxes(int axis) const; - + int num_pixels(void) const; + protected: // Private methods void init_members(void); @@ -69,17 +71,16 @@ protected: void save_image(int datatype, const void* pixels); // Private data area - __fitsfile m_fitsfile; // FITS file - int m_bitpix; // Number of Bits/pixel - int m_naxis; // Image dimension - long* m_naxes; // Number of pixels in each dimension - int m_num_pixels; // Number of image pixels + __fitsfile m_fitsfile; //!< FITS file + int m_bitpix; //!< Number of Bits/pixel + int m_naxis; //!< Image dimension + long* m_naxes; //!< Number of pixels in each dimension + int m_num_pixels; //!< Number of image pixels }; /*************************************************************************** * Inline methods * ***************************************************************************/ -inline int GFitsImage::naxis(void) const { return m_naxis; } #endif /* GFITSIMAGE_HPP */ diff --git a/include/GLATResponse.hpp b/include/GLATResponse.hpp index dd4ef56..a3bf22b 100644 --- a/include/GLATResponse.hpp +++ b/include/GLATResponse.hpp @@ -28,16 +28,11 @@ /* __ Namespaces _________________________________________________________ */ -/*************************************************************************** - * GLATResponse class definition * - ***************************************************************************/ -/** +/***********************************************************************//** * @class GLATResponse * * @brief Interface for the GLAST LAT instrument response function classes. - * - * @author J. Knodlseder - */ + ***************************************************************************/ class GLATResponse : public GResponse { public: @@ -67,9 +62,9 @@ public: const GSkyDir& instPntDir, const double& instPosAng, const double& time); - void set_caldb(std::string caldb); - void load(std::string rspname, std::string rsptype); - void save(std::string rspname) const; + void set_caldb(const std::string& caldb); + void load(const std::string& rspname, const std::string& rsptype); + void save(const std::string& rspname) const; GLATResponse* clone(void) const; private: @@ -82,7 +77,7 @@ private: double psf_scale(const double& energy); double psf_base_value(const double& u, const double& gamma); GVector psf_base_vector(const GVector& u, const double& gamma); - + // Private PSF data int m_psf_angle_num; double m_psf_angle_min; diff --git a/include/GResponse.hpp b/include/GResponse.hpp index 5416978..a4f11a7 100644 --- a/include/GResponse.hpp +++ b/include/GResponse.hpp @@ -108,7 +108,7 @@ public: /// Pure virtual method to define the calibration database /// @param caldb Calibration database to be used - virtual void set_caldb(std::string caldb) = 0; + virtual void set_caldb(const std::string& caldb) = 0; /// Pure virtual method to load the instrument response from the calibration /// database diff --git a/src/GException.cpp b/src/GException.cpp index 1ffa773..fe4cf9a 100644 --- a/src/GException.cpp +++ b/src/GException.cpp @@ -213,8 +213,11 @@ GException::invalid_order::invalid_order(string origin, int order, int min_order } -/*************************************************************************** - * FITS error * +/***********************************************************************//** + * @brief General FITS error + * + * @param[in] origin Method that throws the error. + * @param[in] status cfitsio status. ***************************************************************************/ GException::fits_error::fits_error(string origin, int status) { @@ -222,125 +225,211 @@ GException::fits_error::fits_error(string origin, int status) ostringstream s_error; char err_text[31]; __ffgerr(status, err_text); - s_error << err_text << " (status: " << status << ")"; + s_error << err_text << " (status=" << status << ")"; m_message = s_error.str(); } -/*************************************************************************** - * FITS file opening error * +/***********************************************************************//** + * @brief FITS error: unable to open FITS file + * + * @param[in] origin Method that throws the error. + * @param[in] filename Name of the file for which opening was attempted. + * @param[in] status cfitsio status. ***************************************************************************/ -GException::fits_open_error::fits_open_error(string origin, string filename, int status) +GException::fits_open_error::fits_open_error(string origin, + string filename, + int status) { m_origin = origin; - m_message = "Unable to open FITS file '" + filename + "'" - + " (status: " + str(status) + ")"; + m_message = "Unable to open FITS file '" + filename + "'"; + if (status != 0) + m_message += " (status=" + str(status) + ")"; } -/*************************************************************************** - * FITS file already opened * +/***********************************************************************//** + * @brief FITS error: attempted to overwrite FITS file + * + * @param[in] origin Method that throws the error. + * @param[in] filename Name of the file for which overwrite attempt was made. + * @param[in] status cfitsio status. ***************************************************************************/ -GException::fits_already_opened::fits_already_opened(string origin, string filename) +GException::fits_file_exist::fits_file_exist(string origin, + string filename, + int status) { m_origin = origin; - m_message = "GFits object has already the FITS file '" + filename + "' opened"; + m_message = "Attempted to overwrite FITS file '" + filename + "'"; + if (status != 0) + m_message += " (status=" + str(status) + ")"; } -/*************************************************************************** - * FITS keyword not found error * +/***********************************************************************//** + * @brief FITS error: file already open + * + * @param[in] origin Method that throws the error. + * @param[in] filename Name of file that is already open. ***************************************************************************/ -GException::fits_key_not_found::fits_key_not_found(string origin, string keyname, int status) +GException::fits_already_opened::fits_already_opened(string origin, + string filename) +{ + m_origin = origin; + m_message = "FITS file '" + filename + "' is already open"; +} + + +/***********************************************************************//** + * @brief FITS error: Keyword not in header + * + * @param[in] origin Method that throws the error. + * @param[in] keyname Name of keyword that was not found. + * @param[in] status cfitsio status. + ***************************************************************************/ +GException::fits_key_not_found::fits_key_not_found(string origin, + string keyname, + int status) { m_origin = origin; m_message = "Keyword '" + keyname + "' not found in header"; + if (status != 0) + m_message += " (status=" + str(status) + ")"; } -/*************************************************************************** - * FITS column not found error * +/***********************************************************************//** + * @brief FITS error: Table column not found + * + * @param[in] origin Method that throws the error. + * @param[in] colname Name of the table column that was not found. + * @param[in] status cfitsio status. ***************************************************************************/ -GException::fits_column_not_found::fits_column_not_found(string origin, string colname, int status) +GException::fits_column_not_found::fits_column_not_found(string origin, + string colname, + int status) { m_origin = origin; m_message = "Column '" + colname + "' not found in table"; + if (status != 0) + m_message += " (status=" + str(status) + ")"; } -/*************************************************************************** - * FITS HDU not found error * +/***********************************************************************//** + * @brief FITS error: HDU not found in FITS file + * + * @param[in] origin Method that throws the error. + * @param[in] extname Name of the extension that was not found. + * @param[in] status cfitsio status. ***************************************************************************/ -GException::fits_hdu_not_found::fits_hdu_not_found(string origin, string extname, int status) +GException::fits_hdu_not_found::fits_hdu_not_found(string origin, + string extname, + int status) { m_origin = origin; m_message = "HDU '" + extname + "' not found in FITS file"; + if (status != 0) + m_message += " (status=" + str(status) + ")"; } -/*************************************************************************** - * Unknown HDU type found * +/***********************************************************************//** + * @brief FITS error: HDU of unknown type found + * + * @param[in] origin Method that throws the error. + * @param[in] type Specified HDU type. ***************************************************************************/ -GException::fits_unknown_HDU_type::fits_unknown_HDU_type(string origin, int type) +GException::fits_unknown_HDU_type::fits_unknown_HDU_type(string origin, + int type) { m_origin = origin; - m_message = "HDU type " + str(type) + " is not known"; + m_message = "HDU type '" + str(type) + "' is not known"; } -/*************************************************************************** - * HDU is not a table * +/***********************************************************************//** + * @brief FITS error: HDU is not a table + * + * @param[in] origin Method that throws the error. + * @param[in] type Specified HDU type. ***************************************************************************/ -GException::fits_HDU_not_a_table::fits_HDU_not_a_table(string origin, int type) +GException::fits_HDU_not_a_table::fits_HDU_not_a_table(string origin, + int type) { m_origin = origin; - m_message = "HDU is not a table (type " + str(type) + ")"; + m_message = "HDU is not of type 'table' (type=" + str(type) + ")"; } -/*************************************************************************** - * HDU is not a table * +/***********************************************************************//** + * @brief FITS error: Invalid type + * + * @param[in] origin Method that throws the error. + * @param[in] message Error message. ***************************************************************************/ -GException::fits_invalid_type::fits_invalid_type(string origin, string message) +GException::fits_invalid_type::fits_invalid_type(string origin, + string message) { m_origin = origin; m_message = message; } -/*************************************************************************** - * Column type is unknown * +/***********************************************************************//** + * @brief FITS error: Column type is unknown + * + * @param[in] origin Method that throws the error. + * @param[in] type Specified column type. ***************************************************************************/ -GException::fits_unknown_coltype::fits_unknown_coltype(string origin, int type) +GException::fits_unknown_coltype::fits_unknown_coltype(string origin, + int type) { m_origin = origin; - m_message = "Column type " + str(type) + " is unknown"; + m_message = "Column type '" + str(type) + "' is unknown"; } /***********************************************************************//** * @brief FITS error: invalid number of bits per pixel * - * @param origin Method that throws the error - * @param bitpix Bitpix value that was not 8,16,32,64,-32, or -64 + * @param[in] origin Method that throws the error. + * @param[in] bitpix Bitpix value that was not 8,16,32,64,-32, or -64. + ***************************************************************************/ +GException::fits_bad_bitpix::fits_bad_bitpix(string origin, + int bitpix) +{ + m_origin = origin; + m_message = "Invalid number of bits per pixel (bitpix="+str(bitpix)+")"; +} + + +/***********************************************************************//** + * @brief FITS error: wrong image operator has been used + * + * @param[in] origin Method that throws the error. + * @param[in] naxis Dimension of image. + * @param[in] nargs Number of arguments of the image operator. ***************************************************************************/ -GException::fits_bad_bitpix::fits_bad_bitpix(string origin, int bitpix) +GException::fits_wrong_image_operator::fits_wrong_image_operator(string origin, + int naxis, + int nargs) { m_origin = origin; - m_message = "Invalid number of bits per pixel (bitpix=" + str(bitpix) + ")"; + m_message = "Wrong image pixel access operator has been used (dimension=" + + str(naxis) + " <=> arguments=" + str(nargs) + ")"; } /***********************************************************************//** - * @brief FITS error: bad image operator has been used + * @brief Response error: invalid response type specified * - * @param origin Method that throws the error - * @param naxis Dimension of image - * @param nargs Number of arguments of the image operator + * @param[in] origin Method that throws the error. + * @param[in] type Specified response type. ***************************************************************************/ -GException::fits_bad_image_operator::fits_bad_image_operator(string origin, int naxis, int nargs) +GException::rsp_invalid_type::rsp_invalid_type(string origin, + string type) { m_origin = origin; - m_message = "Bad image pixel access operator used (image dimension=" + - str(naxis) + "; operator arguments=" + str(nargs) + ")"; + m_message = "Invalid response type '"+type+"' specified"; } diff --git a/src/fits/GFits.cpp b/src/fits/GFits.cpp index aba1540..1623563 100644 --- a/src/fits/GFits.cpp +++ b/src/fits/GFits.cpp @@ -23,6 +23,8 @@ /* __ Method name definitions ____________________________________________ */ #define G_OPEN "GFits::open(std::string)" #define G_SAVETO "GFits::saveto(const std::string, int)" +#define G_HDU1 "GFits::hdu(const std::string&)" +#define G_HDU2 "GFits::hdu(int extno)" #define G_FREE_MEM "GFits::free_members()" /* __ Macros _____________________________________________________________ */ @@ -55,7 +57,7 @@ GFits::GFits() /***********************************************************************//** * @brief Copy constructor * - * @param fits FITS file from which the instance should be built + * @param[in] fits FITS file from which the instance should be built. ***************************************************************************/ GFits::GFits(const GFits& fits) { @@ -92,7 +94,7 @@ GFits::~GFits() /***********************************************************************//** * @brief Assignment operator * - * @param fits FITS file that should be assigned + * @param fits[in] FITS file that should be assigned to GFits instance. ***************************************************************************/ GFits& GFits::operator= (const GFits& fits) { @@ -122,11 +124,26 @@ GFits& GFits::operator= (const GFits& fits) ==========================================================================*/ /***********************************************************************//** - * @brief Open FITS file + * @brief Opens or creates FITS file * - * @param filename Name of FITS file to be opened + * @param[in] filename Name of FITS file to be opened * - * Opens all HDUs in the specified FITS file. + * @exception GException::fits_already_opened + * Class instance contains already an opened FITS file. + * Close file before opening a new one using GFits::close(). + * @exception GException::fits_open_error + * Unable to open the specified file. + * @exception GException::fits_error + * Unable to determine number of HDUs in the FITS file. + * + * This method opens all HDUs that are found in the specified FITS file. + * If the file does not exist then a new FITS file is created. + * For each HDU, a GFitsHDU object is associated to the GFits object. + * The HDUs can then be accessed using the + * GFits::hdu(const std::string&) + * or + * GFits::hdu(int extno) + * methods. ***************************************************************************/ void GFits::open(const std::string& filename) { @@ -137,7 +154,7 @@ void GFits::open(const std::string& filename) // Open FITS file int status = 0; status = __ffopen(&m_fitsfile, filename.c_str(), 1, &status); - + // If FITS file does not exist then create it now if (status == 104) { status = 0; @@ -172,9 +189,12 @@ void GFits::open(const std::string& filename) /***********************************************************************//** * @brief Append HDU to FITS file * - * @param hdu Pointer to FITS HDU that should be appended + * @param[in] hdu Pointer to FITS HDU that should be appended * - * NOT YET FULLY IMPLEMENTED + * Append HDU to the next free position in a FITS file. In case that no HDU + * exists so far in the FITS file and if the HDU to append is NOT an image, + * an empty primary image will be inserted as first HDU in the FITS file. + * This guarantees the compatibility with the FITS standard. ***************************************************************************/ void GFits::append(const GFitsHDU* hdu) { @@ -182,11 +202,11 @@ void GFits::append(const GFitsHDU* hdu) // the HDU to append is not an image then we have to add a primary // image first. In this case we add 2 new HDUs. int n_add = (m_num_hdu == 0 && hdu->m_type != 0) ? 2 : 1; - + // Create memory to hold HDUs GFitsHDU* tmp = new GFitsHDU[m_num_hdu+n_add]; if (tmp != NULL) { - + // Copy over existing HDUs and remove old ones if (m_hdu != NULL) { for (int i = 0; i < m_num_hdu; ++i) @@ -196,12 +216,12 @@ void GFits::append(const GFitsHDU* hdu) // Connect the new memory to the card pointer m_hdu = tmp; - + // Add primary image if required if (n_add == 2) { // Append empty primary image - //m_hdu[m_num_hdu] = TBD + m_hdu[m_num_hdu].primary(); // Set FITS file pointer for new HDU __fitsfile fptr = *m_fitsfile; @@ -214,15 +234,15 @@ void GFits::append(const GFitsHDU* hdu) // Append new HDU to list m_hdu[m_num_hdu] = *hdu; - + // Set FITS file pointer for new HDU __fitsfile fptr = *m_fitsfile; fptr.HDUposition = m_num_hdu; m_hdu[m_num_hdu].connect(&fptr); - + // Increment number of HDUs m_num_hdu++; - + } // Return @@ -233,7 +253,8 @@ void GFits::append(const GFitsHDU* hdu) /***********************************************************************//** * @brief Saves FITS file * - * Saves all HDUs to the FITS file. + * Saves all HDUs to the FITS file by looping over the GFitsHDU::save() + * method. ***************************************************************************/ void GFits::save(void) { @@ -249,10 +270,15 @@ void GFits::save(void) /***********************************************************************//** * @brief Saves to specified FITS file * - * @param filename Name of file into which should be saved - * @param clobber Specifies whether any existing file should be overwritten + * @param[in] filename Name of file into which should be saved. + * @param[in] clobber Specifies whether any existing file should be + * overwritten. * - * FUNCTION IS NOT FULLY IMPLEMENTED + * @exception GException::fits_file_exist + * File specified by 'filename' exists already. + * To overwrite an existing file set 'clobber=1'. + * @exception GException::fits_error + * Unable to delete exiting FITS file. ***************************************************************************/ void GFits::saveto(const std::string& filename, int clobber) { @@ -262,26 +288,36 @@ void GFits::saveto(const std::string& filename, int clobber) GFits new_fits = *this; // Check if specified FITS file exists. If yes, saving will only be - // allowed if clobber is true ... + // allowed if clobber is true. If this is the case the specified file + // will be deleted. int status = 0; status = __ffopen(&(new_fits.m_fitsfile), filename.c_str(), 1, &status); if (status == 0) { - if (!clobber) { - throw GException::fits_open_error(G_SAVETO, filename, status); - //throw file_exists ... - } - //delete existing file - //... - } - // ... otherwise create a new FITS file now - else { - // ... + // If overwriting was not allowed the throw an exception + if (!clobber) + throw GException::fits_file_exist(G_SAVETO, filename, status); + + // Delete existing file + __fitsfile* tmp; + status = __ffopen(&tmp, filename.c_str(), 1, &status); + status = __ffdelt(tmp, &status); + if (status == 0) + throw GException::fits_error(G_SAVETO, status); + } + else + status = 0; - // Save all HDUs + // Create a new FITS file now + new_fits.open(filename); + + // Copy all HDUs for (int i = 0; i < m_num_hdu; ++i) - new_fits.m_hdu[i].save(); + new_fits.m_hdu[i] = m_hdu[i]; + + // Save new FITS file + new_fits.save(); // Return return; @@ -310,10 +346,12 @@ void GFits::close(void) /***********************************************************************//** * @brief Get pointer to HDU * - * @param extname Name of HDU extension which should be returned + * @param[in] extname Name of HDU extension which should be returned + * + * @exception GException::fits_hdu_not_found + * HDU with specified extension name has not been found in FITS + * file. ***************************************************************************/ -#define G_HDU1 "GFits::hdu(const std::string&)" -#define G_HDU2 "GFits::hdu(int extno)" GFitsHDU* GFits::hdu(const std::string& extname) { // Initialise result to NULL pointer @@ -326,7 +364,7 @@ GFitsHDU* GFits::hdu(const std::string& extname) break; } } - + // Throw an error if HDU has not been found if (ptr == NULL) throw GException::fits_hdu_not_found(G_HDU1, extname); @@ -339,7 +377,11 @@ GFitsHDU* GFits::hdu(const std::string& extname) /***********************************************************************//** * @brief Get pointer to HDU * - * @param extno Extension number (starting from 1) + * @param extno[in] Extension number (starting from 1) + * + * @exception GException::fits_hdu_not_found + * HDU with specified extension number has not been found in FITS + * file. ***************************************************************************/ GFitsHDU* GFits::hdu(int extno) { @@ -426,13 +468,13 @@ void GFits::free_members(void) { // If FITS file has been opened then close it now if (m_fitsfile != NULL) { - + // If there are no HDUs then delete the file (don't worry about error) if (m_num_hdu == 0) { int status = 0; __ffdelt(m_fitsfile, &status); } - + // ... otherwise close the file else { int status = 0; diff --git a/src/fits/GFitsDblImage.cpp b/src/fits/GFitsDblImage.cpp index 9d8691d..0df5af4 100644 --- a/src/fits/GFitsDblImage.cpp +++ b/src/fits/GFitsDblImage.cpp @@ -57,7 +57,7 @@ GFitsDblImage::GFitsDblImage() : GFitsImage() /***********************************************************************//** * @brief Constructor * - * @param naxis Image dimensions (0,1,2,3,4) + * @param naxis Image dimension (0,1,2,3,4) * @param naxes Number of pixels in each dimension * * Construct instance of GFitsDblImage by specifying the image dimension and @@ -68,10 +68,46 @@ GFitsDblImage::GFitsDblImage(int naxis, const int* naxes) : GFitsImage(naxis, na { // Initialise class members for clean destruction init_members(); - + // Set bitpix m_bitpix = -64; - + + // Return + return; +} + + +/***********************************************************************//** + * @brief Constructor + * + * @param naxis Image dimension (0,1,2,3,4) + * @param naxes Number of pixels in each dimension + * @param pixels Pointer to image pixel array + * + * Construct instance of GFitsDblImage by specifying the image dimension, the + * number of pixels in each dimension and an image pixel array. If the + * 'pixels' pointer is valid (i.e. not NULL) the pixel data is indeed copied + * by this constructor. In case of memory shortage a combination of + * GFitsDblImage::GFitsDblImage(int naxis, const int* naxes) + * and + * GFitsDblImage::link(double* pixels) + * may be prefered to avoid duplication of the pixel data. + ***************************************************************************/ +GFitsDblImage::GFitsDblImage(int naxis, const int* naxes, const double* pixels) + : GFitsImage(naxis, naxes) +{ + // Initialise class members for clean destruction + init_members(); + + // Copy pixels into object + if (m_num_pixels > 0 && pixels != NULL) { + m_pixels = new double[m_num_pixels]; + memcpy(m_pixels, pixels, m_num_pixels*sizeof(double)); + } + + // Set bitpix + m_bitpix = -64; + // Return return; } @@ -146,7 +182,10 @@ GFitsDblImage& GFitsDblImage::operator= (const GFitsDblImage& image) /***********************************************************************//** * @brief 1D image pixel access operator * - * @param ix Pixel index + * @param[in] ix Pixel index + * + * @exception GException::fits_wrong_image_operator + * Image is not a 1D image * * Provides access to a pixel of a 1D image. No range checking is performed. * Use the at(ix) method if range checking is required. @@ -155,11 +194,11 @@ double& GFitsDblImage::operator() (const int& ix) { // Operator is only valid for 1D images if (m_naxis != 1) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 1); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 1); // If image pixels are not available then allocate them now if (m_pixels == NULL) fetch_pixels(); - + // Return image pixel return m_pixels[ix]; } @@ -168,7 +207,10 @@ double& GFitsDblImage::operator() (const int& ix) /***********************************************************************//** * @brief 1D image pixel access operator (const variant) * - * @param ix Pixel index + * @param[in] ix Pixel index + * + * @exception GException::fits_wrong_image_operator + * Image is not a 1D image * * Provides access to a pixel of a 1D image. No range checking is performed. * Use the at(ix) method if range checking is required. @@ -177,11 +219,11 @@ const double& GFitsDblImage::operator() (const int& ix) const { // Operator is only valid for 1D images if (m_naxis != 1) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 1); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 1); // If image pixels are not available then allocate them now if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); - + // Return image pixel return m_pixels[ix]; } @@ -190,8 +232,11 @@ const double& GFitsDblImage::operator() (const int& ix) const /***********************************************************************//** * @brief 2D image pixel access operator * - * @param ix Pixel index in first dimension - * @param iy Pixel index in second dimension + * @param[in] ix Pixel index in first dimension + * @param[in] iy Pixel index in second dimension + * + * @exception GException::fits_wrong_image_operator + * Image is not a 2D image * * Provides access to a pixel of a 2D image. No range checking is performed. * Use the at(ix,iy) method if range checking is required. @@ -200,14 +245,14 @@ double& GFitsDblImage::operator() (const int& ix, const int& iy) { // Operator is only valid for 2D images if (m_naxis != 2) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 2); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 2); // If image pixels are not available then allocate them now if (m_pixels == NULL) fetch_pixels(); - + // Calculate pixel offset int offset = ix + iy * m_naxes[0]; - + // Return image pixel return m_pixels[offset]; } @@ -216,8 +261,11 @@ double& GFitsDblImage::operator() (const int& ix, const int& iy) /***********************************************************************//** * @brief 2D image pixel access operator (const variant) * - * @param ix Pixel index in first dimension - * @param iy Pixel index in second dimension + * @param[in] ix Pixel index in first dimension + * @param[in] iy Pixel index in second dimension + * + * @exception GException::fits_wrong_image_operator + * Image is not a 2D image * * Provides access to a pixel of a 2D image. No range checking is performed. * Use the at(ix,iy) method if range checking is required. @@ -226,14 +274,14 @@ const double& GFitsDblImage::operator() (const int& ix, const int& iy) const { // Operator is only valid for 2D images if (m_naxis != 2) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 2); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 2); // If image pixels are not available then allocate them now if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); - + // Calculate pixel offset int offset = ix + iy * m_naxes[0]; - + // Return image pixel return m_pixels[offset]; } @@ -242,9 +290,12 @@ const double& GFitsDblImage::operator() (const int& ix, const int& iy) const /***********************************************************************//** * @brief 3D image pixel access operator * - * @param ix Pixel index in first dimension - * @param iy Pixel index in second dimension - * @param iz Pixel index in third dimension + * @param[in] ix Pixel index in first dimension + * @param[in] iy Pixel index in second dimension + * @param[in] iz Pixel index in third dimension + * + * @exception GException::fits_wrong_image_operator + * Image is not a 3D image * * Provides access to a pixel of a 3D image. No range checking is performed. * Use the at(ix,iy,iz) method if range checking is required. @@ -253,14 +304,14 @@ double& GFitsDblImage::operator() (const int& ix, const int& iy, const int& iz) { // Operator is only valid for 3D images if (m_naxis != 3) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 3); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 3); // If image pixels are not available then allocate them now if (m_pixels == NULL) fetch_pixels(); - + // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]); - + // Return image pixel return m_pixels[offset]; } @@ -269,9 +320,12 @@ double& GFitsDblImage::operator() (const int& ix, const int& iy, const int& iz) /***********************************************************************//** * @brief 3D image pixel access operator (const variant) * - * @param ix Pixel index in first dimension - * @param iy Pixel index in second dimension - * @param iz Pixel index in third dimension + * @param[in] ix Pixel index in first dimension + * @param[in] iy Pixel index in second dimension + * @param[in] iz Pixel index in third dimension + * + * @exception GException::fits_wrong_image_operator + * Image is not a 3D image * * Provides access to a pixel of a 3D image. No range checking is performed. * Use the at(ix,iy,iz) method if range checking is required. @@ -280,14 +334,14 @@ const double& GFitsDblImage::operator() (const int& ix, const int& iy, const int { // Operator is only valid for 3D images if (m_naxis != 3) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 3); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 3); // If image pixels are not available then allocate them now if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); - + // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + iz * m_naxes[1]); - + // Return image pixel return m_pixels[offset]; } @@ -296,10 +350,13 @@ const double& GFitsDblImage::operator() (const int& ix, const int& iy, const int /***********************************************************************//** * @brief 4D image pixel access operator * - * @param ix Pixel index in first dimension - * @param iy Pixel index in second dimension - * @param iz Pixel index in third dimension - * @param it Pixel index in forth dimension + * @param[in] ix Pixel index in first dimension + * @param[in] iy Pixel index in second dimension + * @param[in] iz Pixel index in third dimension + * @param[in] it Pixel index in forth dimension + * + * @exception GException::fits_wrong_image_operator + * Image is not a 4D image * * Provides access to a pixel of a 4D image. No range checking is performed. * Use the at(ix,iy,iz,it) method if range checking is required. @@ -308,14 +365,14 @@ double& GFitsDblImage::operator() (const int& ix, const int& iy, const int& iz, { // Operator is only valid for 4D images if (m_naxis != 4) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 4); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 4); // If image pixels are not available then allocate them now if (m_pixels == NULL) fetch_pixels(); - + // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2])); - + // Return image pixel return m_pixels[offset]; } @@ -324,10 +381,13 @@ double& GFitsDblImage::operator() (const int& ix, const int& iy, const int& iz, /***********************************************************************//** * @brief 4D image pixel access operator (const variant) * - * @param ix Pixel index in first dimension - * @param iy Pixel index in second dimension - * @param iz Pixel index in third dimension - * @param it Pixel index in forth dimension + * @param[in] ix Pixel index in first dimension + * @param[in] iy Pixel index in second dimension + * @param[in] iz Pixel index in third dimension + * @param[in] it Pixel index in forth dimension + * + * @exception GException::fits_wrong_image_operator + * Image is not a 4D image * * Provides access to a pixel of a 4D image. No range checking is performed. * Use the at(ix,iy,iz,it) method if range checking is required. @@ -336,14 +396,14 @@ const double& GFitsDblImage::operator() (const int& ix, const int& iy, const int { // Operator is only valid for 4D images if (m_naxis != 4) - throw GException::fits_bad_image_operator(G_OPERATOR2, m_naxis, 4); + throw GException::fits_wrong_image_operator(G_OPERATOR2, m_naxis, 4); // If image pixels are not available then allocate them now if (m_pixels == NULL) ((GFitsDblImage*)this)->fetch_pixels(); - + // Calculate pixel offset int offset = ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2])); - + // Return image pixel return m_pixels[offset]; } @@ -367,13 +427,13 @@ void GFitsDblImage::open(__fitsfile* fptr) { // Initialise base class members GFitsImage::init_members(); - + // Initialise class members init_members(); - + // Open image open_image(fptr); - + // Return return; } @@ -398,10 +458,10 @@ void GFitsDblImage::link(double* pixels) if (!m_linked) { if (m_pixels != NULL) delete [] m_pixels; } - + // Link pixel array to image m_pixels = pixels; - + // Flag that pixels have been linked m_linked = 1; @@ -419,7 +479,7 @@ void GFitsDblImage::save(void) { // Save a double precision image save_image(__TDOUBLE, m_pixels); - + // Return return; } @@ -442,10 +502,10 @@ void GFitsDblImage::close(void) // Free base class members GFitsImage::free_members(); - + // Initialise base class members GFitsImage::init_members(); - + // Return return; } @@ -457,7 +517,7 @@ void GFitsDblImage::close(void) * Cloning provides a copy of the FITS file. Cloning is used to allocate * derived classes into a base class pointer. ***************************************************************************/ -GFitsDblImage* GFitsDblImage::clone(void) const +GFitsDblImage* GFitsDblImage::clone(void) const { // Clone this image return new GFitsDblImage(*this); @@ -534,12 +594,12 @@ void GFitsDblImage::copy_members(const GFitsDblImage& image) // Copy attributes m_linked = image.m_linked; m_anynul = image.m_anynul; - + // Copy pixels if (m_linked) m_pixels = image.m_pixels; else { - if (m_num_pixels > 0) { + if (m_num_pixels > 0 && image.m_pixels != NULL) { m_pixels = new double[m_num_pixels]; memcpy(m_pixels, image.m_pixels, m_num_pixels*sizeof(double)); } @@ -566,10 +626,10 @@ void GFitsDblImage::free_members(void) if (!m_linked) { if (m_pixels != NULL) delete [] m_pixels; } - + // Free NULL value if (m_nulval != NULL) delete m_nulval; - + // Mark memory as free m_linked = 0; m_pixels = NULL; @@ -602,14 +662,14 @@ void GFitsDblImage::fetch_pixels(void) if (!m_linked) { if (m_pixels != NULL) delete [] m_pixels; } - + // Allocate fresh image pixels m_pixels = new double[m_num_pixels]; // Case 1: A FITS is attached. Load pixels now. if (m_fitsfile.Fptr != NULL) load_image(__TDOUBLE, m_pixels, m_nulval, &m_anynul); - + // Case 2: No FITS file is attached. Allocate pixels and set them all to 0.0 else { for (int i = 0; i < m_num_pixels; ++i) diff --git a/src/fits/GFitsHDU.cpp b/src/fits/GFitsHDU.cpp index d4cde43..027b18b 100644 --- a/src/fits/GFitsHDU.cpp +++ b/src/fits/GFitsHDU.cpp @@ -57,7 +57,10 @@ GFitsHDU::GFitsHDU() /***********************************************************************//** * @brief Image HDU Constructor * - * @param image Image from which the HDU should be constructed + * @param[in] image Image from which the HDU should be constructed + * + * Note that the HDU constructor copies the image, hence any change in the + * original object after copying will not be reflected in the copied object. * * IMPLEMENTATION NOT YET FINISHED (NEEDS KEYWORD SETTING) ***************************************************************************/ @@ -65,15 +68,32 @@ GFitsHDU::GFitsHDU(const GFitsImage& image) { // Initialise class members for clean destruction init_members(); - + // Copy image into HDU data m_data = image.clone(); - + // Allocate new header m_header = new GFitsHeader(); - - // Extract keywords from image - // TBW + + // Set image header keywords + m_header->update(GFitsHeaderCard("XTENSION", "'IMAGE '", + "IMAGE extension")); + m_header->update(GFitsHeaderCard("BITPIX", image.bitpix(), + "number of bits per data pixel")); + m_header->update(GFitsHeaderCard("NAXIS", image.naxis(), + "number of data axes")); + for (int i = 0; i < image.naxis(); ++i) { + ostringstream s_key; + ostringstream s_comment; + s_key << "NAXIS" << (i+1); + s_comment << "length of data axis " << (i+1); + m_header->update(GFitsHeaderCard(s_key.str(), image.naxes(i), + s_comment.str())); + } + m_header->update(GFitsHeaderCard("PCOUNT", 0, + "required keyword; must = 0")); + m_header->update(GFitsHeaderCard("GCOUNT", 1, + "required keyword; must = 1")); // Return return; @@ -202,7 +222,12 @@ void GFitsHDU::open(__fitsfile* fptr, int hdunum) m_data->open(&m_fitsfile); // Get HDU name from header - m_name = strip_whitespace(m_header->string("EXTNAME")); + try { + m_name = strip_whitespace(m_header->string("EXTNAME")); + } + catch (GException::fits_key_not_found) { + m_name.clear(); + } if (m_name.length() == 0) { if (hdunum == 1) m_name = "Primary"; @@ -230,7 +255,7 @@ void GFitsHDU::save(void) // Move to HDU int status = 0; status = __ffmahd(&m_fitsfile, m_hdunum, NULL, &status); - + // If HDU does not yet exist in file then create it now. This works even // in the case that the actual HDU has no associated header and/or data // (these will be created automatically). However, to make this work we have @@ -259,18 +284,18 @@ void GFitsHDU::save(void) } } } - + // If they exist then save data and header if (m_data != NULL) { m_data->save(); if (m_header != NULL) - m_header->save(); + m_header->save(&m_fitsfile); } - + // ... otherwise make sure that the FITS file has at least a primary // image. else { - + // Special case: The first HDU does not exist. A FITS file needs at least // one primary HDU. Thus an empty image is created. if (m_fitsfile.HDUposition == 0) { @@ -278,9 +303,9 @@ void GFitsHDU::save(void) if (status != 0) throw GException::fits_error(G_SAVE, status); if (m_header != NULL) - m_header->save(); + m_header->save(&m_fitsfile); } - + } // endelse: no data were available // Return @@ -289,6 +314,32 @@ void GFitsHDU::save(void) /***********************************************************************//** + * @brief Set HDU extension name (EXTNAME keyword) + * + * @param extname Name of HDU + * + * This methos sets the extension name of the HDU. The extension name will + * be saved in the 'EXTNAME' header keyword. The header attached to the + * HDU will be automatically updated by this method. + ***************************************************************************/ +void GFitsHDU::extname(const std::string& extname) +{ + // Set extension name + m_name = extname; + + // If no header exists then create one now + if (m_header == NULL) m_header = new GFitsHeader(); + + // Update header + m_header->update(GFitsHeaderCard("EXTNAME", extname, + "name of this extension")); + + // Return + return; +} + + +/***********************************************************************//** * @brief Return pointer to column of table * * @param colname Name of FITS table column to be returned @@ -329,20 +380,20 @@ void GFitsHDU::primary(void) { // Free any allocated header and data free_members(); - + // Create primary image in memory int status = 0; __fitsfile* fptr; status = __ffinit(&fptr, "mem://", &status); status = __ffcrim(fptr, 8, 0, NULL, &status); - + // Open HDU this->open(fptr,1); - + // Detach FITS file pointer this->m_fitsfile.HDUposition = 0; this->m_fitsfile.Fptr = NULL; - + // Return return; } @@ -429,10 +480,10 @@ void GFitsHDU::connect(__fitsfile* fptr) // First connect HDU m_fitsfile = *fptr; m_hdunum = m_fitsfile.HDUposition + 1; - + // Then connect data if (m_data != NULL) m_data->connect(fptr); - + // Return return; } @@ -457,7 +508,7 @@ GFitsImage* GFitsHDU::new_image(void) { // Initialise return value GFitsImage* image = NULL; - + // Get number of bits per pixel int status = 0; int bitpix = -64; @@ -528,11 +579,11 @@ ostream& operator<< (ostream& os, const GFitsHDU& hdu) os << "Unknown" << endl; break; } - + // Put FITS header in stream if (hdu.m_header != NULL) os << *hdu.m_header; - + // Put FITS data in stream if (hdu.m_data != NULL) { switch (hdu.m_type) { diff --git a/src/fits/GFitsHeader.cpp b/src/fits/GFitsHeader.cpp index 8e7898e..44f928d 100644 --- a/src/fits/GFitsHeader.cpp +++ b/src/fits/GFitsHeader.cpp @@ -20,7 +20,10 @@ /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ -#define G_OPEN "GFitsHeader::open(int)" +#define G_OPEN "GFitsHeader::open(fitsfile*)" +#define G_SAVE "GFitsHeader::save(fitsfile*)" +#define G_CARD "GFitsHeader::card(const int&)" +#define G_CARD_PTR "GFitsHeader::card_ptr(const std::string&)" /* __ Macros _____________________________________________________________ */ @@ -36,9 +39,8 @@ = = ==========================================================================*/ -/*************************************************************************** - * Constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Constructor ***************************************************************************/ GFitsHeader::GFitsHeader() { @@ -50,9 +52,10 @@ GFitsHeader::GFitsHeader() } -/*************************************************************************** - * Copy constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Copy constructor + * + * @param header Header from which GFitsHeader instance should be built ***************************************************************************/ GFitsHeader::GFitsHeader(const GFitsHeader& header) { @@ -67,9 +70,8 @@ GFitsHeader::GFitsHeader(const GFitsHeader& header) } -/*************************************************************************** - * Destructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Destructor ***************************************************************************/ GFitsHeader::~GFitsHeader() { @@ -87,9 +89,10 @@ GFitsHeader::~GFitsHeader() = = ==========================================================================*/ -/*************************************************************************** - * Assignment operator * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Assignment operator + * + * @param header Header which should be assigned to GFitsHeader instance ***************************************************************************/ GFitsHeader& GFitsHeader::operator= (const GFitsHeader& header) { @@ -121,7 +124,7 @@ GFitsHeader& GFitsHeader::operator= (const GFitsHeader& header) /***********************************************************************//** * @brief Open Header * - * @param fptr FITS file pointer + * @param fptr Pointer to FITS file from which the header will be loaded * * Loads all header cards into memory. Any header cards that existed before * will be dropped. @@ -157,10 +160,38 @@ void GFitsHeader::open(__fitsfile* fptr) /***********************************************************************//** * @brief Save Header to FITS file * - * NOT YET IMPLEMENTED + * @param fptr Pointer to FITS file into which the header cards will be saved + * + * Saves all header cards into HDU. This method does not write the following + * mandatory keywords to the HDU (those will be writted by methods handling + * the data of the HDU): + * 'SIMPLE' + * 'BITPIX' + * 'NAXIS', 'NAXIS1', 'NAXIS2', etc. + * 'EXTEND' + * 'PCOUNT' + * 'GCOUNT' ***************************************************************************/ -void GFitsHeader::save(void) +void GFitsHeader::save(__fitsfile* fptr) { + // Move to HDU + int status = 0; + status = __ffmahd(fptr, (fptr->HDUposition)+1, NULL, &status); + if (status != 0) + throw GException::fits_error(G_SAVE, status); + + // Save all cards + for (int i = 0; i < m_num_cards; ++i) { + if (m_card[i].keyname() != "SIMPLE" && + m_card[i].keyname() != "XTENSION" && + m_card[i].keyname() != "BITPIX" && + m_card[i].keyname() != "EXTEND" && + m_card[i].keyname() != "PCOUNT" && + m_card[i].keyname() != "GCOUNT" && + m_card[i].keyname().find("NAXIS") == std::string::npos) { + m_card[i].write(fptr); + } + } // Return return; @@ -191,49 +222,95 @@ void GFitsHeader::close(void) * @brief Update card in header or append card to header * * @param card FITS header card that should be updated - * - * This method updates one header card. Updating means replacing any - * existing card with the specified one or appending a new card to the - * list of existing cards. + * + * This method updates one header card. Updating means replacing any + * existing card with the specified one or appending a new card to the + * list of existing cards. ***************************************************************************/ void GFitsHeader::update(const GFitsHeaderCard& card) { - // If card exists then update existing values - GFitsHeaderCard* ptr = this->card(card.keyname()); - if (ptr != NULL) - *ptr = card; - - // ... otherwise append a new card - else { - - // Create memory to hold cards - GFitsHeaderCard* tmp = new GFitsHeaderCard[m_num_cards+1]; - if (tmp != NULL) { - - // Copy over existing cards and remove old ones - if (m_card != NULL) { - for (int i = 0; i < m_num_cards; ++i) - tmp[i] = m_card[i]; - delete [] m_card; - } - - // Connect the new memory to the card pointer - m_card = tmp; - - // Append new card to list - m_card[m_num_cards] = card; - - } // endif: new memory was valid - } // endif: card appending was required + // If card keyname is not COMMENT or HISTORY, then check first if + // card exists. If yes then update existing card + if (card.keyname() != "COMMENT" && card.keyname() != "HISTORY") { + try { + GFitsHeaderCard* ptr = this->card(card.keyname()); + *ptr = card; + return; + } + catch (GException::fits_key_not_found) { + ; + } + } + + // Create memory to hold cards + GFitsHeaderCard* tmp = new GFitsHeaderCard[m_num_cards+1]; + if (tmp != NULL) { + + // Copy over existing cards and remove old ones + if (m_card != NULL) { + for (int i = 0; i < m_num_cards; ++i) + tmp[i] = m_card[i]; + delete [] m_card; + } + + // Connect the new memory to the card pointer + m_card = tmp; + + // Append new card to list + m_card[m_num_cards] = card; + + // Increment number of cards + m_num_cards++; + + } // endif: new memory was valid // Return return; } -/*************************************************************************** - * Get specified header card value as string * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Return pointer of header card + * + * @param[in] keyname Name of header card + * + * Returns a pointer on the header card. + * If card was not found a 'fits_key_not_found' error will be thrown. + ***************************************************************************/ +GFitsHeaderCard* GFitsHeader::card(const std::string& keyname) +{ + return GFitsHeader::card_ptr(keyname); +} + + +/***********************************************************************//** + * @brief Return pointer of header card + * + * @param[in] keyname Name of header card + * + * Returns a pointer on the header card. + * If card was not found a 'out_of_range' error will be thrown. + ***************************************************************************/ +GFitsHeaderCard* GFitsHeader::card(const int& cardno) +{ + // If card number is out of range then throw an exception + if (cardno < 0 || cardno >= m_num_cards) + throw GException::out_of_range(G_CARD, cardno, 0, m_num_cards-1); + + // Get card pointer + GFitsHeaderCard* ptr = &(m_card[cardno]); + + // Return pointer + return ptr; +} + + +/***********************************************************************//** + * @brief Get specified header card value as string + * + * @param[in] keyname Name of header card + * + * If the header card is not found an empty string is returned. ***************************************************************************/ std::string GFitsHeader::string(const std::string& keyname) { @@ -248,9 +325,12 @@ std::string GFitsHeader::string(const std::string& keyname) } -/*************************************************************************** - * Get specified header card value as string * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get specified header card value as string + * + * @param[in] cardno Header card number (starting from 0) + * + * If the header card number does not exist an empty string is returned. ***************************************************************************/ std::string GFitsHeader::string(const int& cardno) { @@ -265,9 +345,12 @@ std::string GFitsHeader::string(const int& cardno) } -/*************************************************************************** - * Get specified header card value as double * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get specified header card value as double precision value + * + * @param[in] keyname Name of header card + * + * If the header card is not found 0 is returned. ***************************************************************************/ double GFitsHeader::real(const std::string& keyname) { @@ -282,9 +365,12 @@ double GFitsHeader::real(const std::string& keyname) } -/*************************************************************************** - * Get specified header card value as double * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get specified header card value as double precision value + * + * @param[in] cardno Header card number (starting from 0) + * + * If the header card number does not exist 0 is returned. ***************************************************************************/ double GFitsHeader::real(const int& cardno) { @@ -299,9 +385,12 @@ double GFitsHeader::real(const int& cardno) } -/*************************************************************************** - * Get specified header card value as int * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get specified header card value as integer value + * + * @param keyname Name of header card + * + * If the header card is not found 0 is returned. ***************************************************************************/ int GFitsHeader::integer(const std::string& keyname) { @@ -316,9 +405,12 @@ int GFitsHeader::integer(const std::string& keyname) } -/*************************************************************************** - * Get specified header card value as int * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get specified header card value as integer value + * + * @param[in] cardno Header card number (starting from 0) + * + * If the header card number does not exist 0 is returned. ***************************************************************************/ int GFitsHeader::integer(const int& cardno) { @@ -333,15 +425,23 @@ int GFitsHeader::integer(const int& cardno) } +/***********************************************************************//** + * @brief Clone header object + ***************************************************************************/ +GFitsHeader* GFitsHeader::clone(void) const +{ + return new GFitsHeader(*this); +} + + /*========================================================================== = = = GFitsHeader private methods = = = ==========================================================================*/ -/*************************************************************************** - * Initialise class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Initialise class members ***************************************************************************/ void GFitsHeader::init_members(void) { @@ -354,18 +454,19 @@ void GFitsHeader::init_members(void) } -/*************************************************************************** - * Copy class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Copy class members + * + * @param[in] header Header which should be copied ***************************************************************************/ void GFitsHeader::copy_members(const GFitsHeader& header) { // Copy attributes + m_num_cards = header.m_num_cards; // Copy cards - if (header.m_card != NULL && header.m_num_cards > 0) { - m_num_cards = header.m_num_cards; - m_card = new GFitsHeaderCard[m_num_cards]; + if (header.m_card != NULL && m_num_cards > 0) { + m_card = new GFitsHeaderCard[m_num_cards]; for (int i = 0; i < m_num_cards; ++i) m_card[i] = header.m_card[i]; } @@ -375,9 +476,8 @@ void GFitsHeader::copy_members(const GFitsHeader& header) } -/*************************************************************************** - * Delete class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Delete class members ***************************************************************************/ void GFitsHeader::free_members(void) { @@ -392,11 +492,15 @@ void GFitsHeader::free_members(void) } -/*************************************************************************** - * Get card pointer * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get pointer on header card + * + * @param[in] keyname Name of the header card + * + * Returns a pointer on the header card. + * If card was not found a 'fits_key_not_found' error will be thrown. ***************************************************************************/ -GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname) +GFitsHeaderCard* GFitsHeader::card_ptr(const std::string& keyname) { // Set card pointer to NULL (default) @@ -410,6 +514,10 @@ GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname) } } + // If no card was found then throw an error + if (ptr == NULL) + throw GException::fits_key_not_found(G_CARD_PTR, keyname); + // Return pointer return ptr; } @@ -421,15 +529,16 @@ GFitsHeaderCard* GFitsHeader::card_ptr(const std::string keyname) = = ==========================================================================*/ -/*************************************************************************** - * Output operator * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Output operator + * + * @param[in] os Output stream + * @param[in] header Header to put in output stream ***************************************************************************/ ostream& operator<< (ostream& os, const GFitsHeader& header) { // Put header in stream - os << "=== GFitsHeader ===" << endl; - os << " Number of cards ...........: " << header.m_num_cards << endl; + os << "=== GFitsHeader (" << header.m_num_cards << " cards) ===" << endl; for (int i = 0; i < header.m_num_cards; ++i) os << " " << header.m_card[i]; diff --git a/src/fits/GFitsHeaderCard.cpp b/src/fits/GFitsHeaderCard.cpp index 1a90b07..fcc123d 100644 --- a/src/fits/GFitsHeaderCard.cpp +++ b/src/fits/GFitsHeaderCard.cpp @@ -48,9 +48,8 @@ = = ==========================================================================*/ -/*************************************************************************** - * Constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Constructor ***************************************************************************/ GFitsHeaderCard::GFitsHeaderCard() { @@ -60,26 +59,91 @@ GFitsHeaderCard::GFitsHeaderCard() // Return return; } -GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname, - const std::string& value, + + +/***********************************************************************//** + * @brief Constructor for string cards + * + * @param[in] keyname Name of the header card + * @param[in] value String value of the header card + * @param[in] comment Comment of the header card + * + * This constructor builds a header card from the keyname, value and comment. + ***************************************************************************/ +GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname, + const std::string& value, const std::string& comment) { // Initialise class members for clean destruction init_members(); - + // Set members - this->set_keyname(keyname); - this->set_value(value); - this->set_comment(comment); + this->keyname(keyname); + this->value(value); + this->comment(comment); // Return return; } -/*************************************************************************** - * Copy constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Constructor for floating point cards + * + * @param[in] keyname Name of the header card + * @param[in] value Floating point value of the header card + * @param[in] comment Comment of the header card + * + * This constructor builds a header card from the keyname, value and comment. + ***************************************************************************/ +GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname, + const double& value, + const std::string& comment) +{ + // Initialise class members for clean destruction + init_members(); + + // Set members + this->keyname(keyname); + this->value(value); + this->comment(comment); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Constructor for integer cards + * + * @param[in] keyname Name of the header card + * @param[in] value Integer value of the header card + * @param[in] comment Comment of the header card + * + * This constructor builds a header card from the keyname, value and comment. + ***************************************************************************/ +GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname, + const int& value, + const std::string& comment) +{ + // Initialise class members for clean destruction + init_members(); + + // Set members + this->keyname(keyname); + this->value(value); + this->comment(comment); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Copy constructor + * + * @param card[in] Header card that will be used to construct GFitsHeaderCard + * instance ***************************************************************************/ GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard& card) { @@ -94,9 +158,8 @@ GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard& card) } -/*************************************************************************** - * Destructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Destructor ***************************************************************************/ GFitsHeaderCard::~GFitsHeaderCard() { @@ -113,24 +176,26 @@ GFitsHeaderCard::~GFitsHeaderCard() = = ==========================================================================*/ -/*************************************************************************** - * Assignment operator * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Assignment operator + * + * @param card[in] Header card that will be assigned to GFitsHeaderCard + * instance ***************************************************************************/ GFitsHeaderCard& GFitsHeaderCard::operator= (const GFitsHeaderCard& card) { // Execute only if object is not identical if (this != &card) { - + // Free members free_members(); - + // Initialise private members for clean destruction init_members(); // Copy members copy_members(card); - + } // endif: object was not identical // Return this object @@ -144,9 +209,174 @@ GFitsHeaderCard& GFitsHeaderCard::operator= (const GFitsHeaderCard& card) = = ==========================================================================*/ -/*************************************************************************** - * Return value as string * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Set name of header card + * + * @param[in] keyname Name of header card + ***************************************************************************/ +void GFitsHeaderCard::keyname(const std::string& keyname) +{ + // Set name of card + m_keyname = keyname; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Set string value of header card + * + * @param[in] value String value of header card + ***************************************************************************/ +void GFitsHeaderCard::value(const std::string& value) +{ + // Set value and value type + m_value = value; + m_value_type = get_value_type(value); + + // Attach hyphens if required + if (m_value_type == CT_STRING) { + if (m_value[0] != '\x27') + m_value = "'" + m_value; + if (m_value[m_value.length()-1] != '\x27') + m_value += "'"; + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Set floating point value of header card + * + * @param[in] value Floating point value of header card + ***************************************************************************/ +void GFitsHeaderCard::value(const double& value) +{ + // Convert value to string + ostringstream s_value; + s_value << scientific << value; + + // Assign value + m_value = s_value.str(); + + // Set value type + m_value_type = get_value_type(m_value); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Set integer value of header card + * + * @param[in] value Integer value of header card + ***************************************************************************/ +void GFitsHeaderCard::value(const int& value) +{ + // Convert value to string + ostringstream s_value; + s_value << value; + + // Assign value + m_value = s_value.str(); + + // Set value type + m_value_type = get_value_type(m_value); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Set unit of header card value + * + * @param[in] value Unit of header card + ***************************************************************************/ +void GFitsHeaderCard::unit(const std::string& unit) +{ + // Set unit + m_unit = unit; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Set comment of header card + * + * @param[in] value Header card comment + ***************************************************************************/ +void GFitsHeaderCard::comment(const std::string& comment) +{ + // Set comment + m_comment = comment; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Return header card keyname + ***************************************************************************/ +std::string GFitsHeaderCard::keyname(void) const +{ + // Return + return m_keyname; +} + + +/***********************************************************************//** + * @brief Return header card value + ***************************************************************************/ +std::string GFitsHeaderCard::value(void) const +{ + // Return + return m_value; +} + + +/***********************************************************************//** + * @brief Return header card value type + ***************************************************************************/ +int GFitsHeaderCard::value_type(void) const +{ + // Return + return m_value_type; +} + + +/***********************************************************************//** + * @brief Return header card value unit + ***************************************************************************/ +std::string GFitsHeaderCard::unit(void) const +{ + // Return + return m_unit; +} + + +/***********************************************************************//** + * @brief Return header card comment + ***************************************************************************/ +std::string GFitsHeaderCard::comment(void) const +{ + // Return + return m_comment; +} + + +/***********************************************************************//** + * @brief Return header card value as string + * + * Convert header card value into a string. + * Any hyphens that may occur in the FITS card will be automatically stripped. ***************************************************************************/ std::string GFitsHeaderCard::string(void) { @@ -174,9 +404,12 @@ std::string GFitsHeaderCard::string(void) } -/*************************************************************************** - * Return value as double * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Return header card value as double precision + * + * Convert header card value into a double precision value. In case that the + * card did not contain a numerical value, 0 will be returned by the + * method. ***************************************************************************/ double GFitsHeaderCard::real(void) { @@ -206,9 +439,12 @@ double GFitsHeaderCard::real(void) } -/*************************************************************************** - * Return value as int * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Return header card value as integer +* + * Convert header card value into a integer value. In case that the + * card did not contain a numerical value, 0 will be returned by the + * method. ***************************************************************************/ int GFitsHeaderCard::integer(void) { @@ -238,9 +474,11 @@ int GFitsHeaderCard::integer(void) } -/*************************************************************************** - * Read header card * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Read header card from FITS file + * + * @param[in] fptr Pointer to FITS file from which the card is read + * @param[in] keynum Number of the header card ***************************************************************************/ void GFitsHeaderCard::read(__fitsfile* fptr, int keynum) { @@ -264,18 +502,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, int keynum) m_comment.assign(comment); // Determine card type - m_value_type = get_value_type(); + m_value_type = get_value_type(m_value); // Return return; } -/*************************************************************************** - * Read header card * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Read header card from FITS file + * + * @param[in] fptr Pointer to FITS file from which the card is read + * @param[in] keyname Name of the header card ***************************************************************************/ -void GFitsHeaderCard::read(__fitsfile* fptr, std::string keyname) +void GFitsHeaderCard::read(__fitsfile* fptr, const std::string& keyname) { // Move to HDU int status = 0; @@ -300,16 +540,20 @@ void GFitsHeaderCard::read(__fitsfile* fptr, std::string keyname) m_comment.assign(comment); // Determine card type - m_value_type = get_value_type(); + m_value_type = get_value_type(m_value); // Return return; } -/*************************************************************************** - * Write header card * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Write header card + * + * @param fptr[in] Pointer to FITS file into which the header card should be + * written + * + * Writes any kind of header card to a FITS file. ***************************************************************************/ void GFitsHeaderCard::write(__fitsfile* fptr) { @@ -336,9 +580,8 @@ void GFitsHeaderCard::write(__fitsfile* fptr) = = ==========================================================================*/ -/*************************************************************************** - * Initialise class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Initialise class members ***************************************************************************/ void GFitsHeaderCard::init_members(void) { @@ -354,9 +597,10 @@ void GFitsHeaderCard::init_members(void) } -/*************************************************************************** - * Copy class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Copy class members + * + * @param[in] card Header card to be copied ***************************************************************************/ void GFitsHeaderCard::copy_members(const GFitsHeaderCard& card) { @@ -372,9 +616,8 @@ void GFitsHeaderCard::copy_members(const GFitsHeaderCard& card) } -/*************************************************************************** - * Delete class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Delete class members ***************************************************************************/ void GFitsHeaderCard::free_members(void) { @@ -383,11 +626,25 @@ void GFitsHeaderCard::free_members(void) } -/*************************************************************************** - * Determine card value type * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Determine card value type + * + * @param[in] value Value string for which the type should be determined + * + * Method that determines the type of the card value. The following types are + * defined: + * CT_UNKNOWN=0 (inknown type) + * CT_INVALID=1 (invalid type) + * CT_STRING=2 (string) + * CT_INT=3 (integer) + * CT_FLOAT=4 (floating point) + * CT_BOOL=5 (boolean) + * CT_COMMENT=6 (comment) + * CT_HISTORY=7 (history) + * The type is determined by analyzing the card value. It is stored in the + * private variable 'm_value_type'. ***************************************************************************/ -int GFitsHeaderCard::get_value_type(void) +int GFitsHeaderCard::get_value_type(const std::string& value) { // Get index of last string element int last = m_value.length() - 1; @@ -417,7 +674,8 @@ int GFitsHeaderCard::get_value_type(void) int found_int = 0; int found_float = 0; for (int i = 0; i <= last; ++i) { - if ((m_value[i] >= '0' && m_value[i] <= '9') || m_value[i] == '+' || m_value[i] == '-') + if ((m_value[i] >= '0' && m_value[i] <= '9') || m_value[i] == '+' || + m_value[i] == '-') found_int = 1; else if (m_value[i] == '.' || m_value[i] == 'e' || m_value[i] == 'E') found_float = 1; @@ -445,18 +703,77 @@ int GFitsHeaderCard::get_value_type(void) = = ==========================================================================*/ -/*************************************************************************** - * Output operator * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Output operator + * + * @param[in] os Output stream + * @param[in] card Card that should be put in output stream ***************************************************************************/ ostream& operator<< (ostream& os, const GFitsHeaderCard& card) { - // Put header card in stream - os << card.m_keyname << " = "; - os << card.m_value << " "; - os << card.m_unit << " "; - os << card.m_comment << " "; - os << card.m_value_type << endl; + // Set buffer + char buffer[100]; + + // Setup left justified keyname + std::string keyname = card.m_keyname; + while (keyname.length() < 8) + keyname.append(" "); + + // Setup buffer + if (card.m_value_type != CT_COMMENT && card.m_value_type != CT_HISTORY) { + if (card.m_unit.length() > 0) { + sprintf(buffer, "%8s =%21s / [%s] %s", + keyname.c_str(), + card.m_value.c_str(), + card.m_unit.c_str(), + card.m_comment.c_str()); + } + else { + sprintf(buffer, "%8s =%21s / %s", + keyname.c_str(), + card.m_value.c_str(), + card.m_comment.c_str()); + } + } + else { + sprintf(buffer, "%8s %s", + keyname.c_str(), + card.m_comment.c_str()); + } + + // Put buffer in stream + os << buffer; + + // Attach card type + switch (card.m_value_type) { + case CT_UNKNOWN: + os << " " << endl; + break; + case CT_INVALID: + os << " " << endl; + break; + case CT_STRING: + os << " " << endl; + break; + case CT_INT: + os << " " << endl; + break; + case CT_FLOAT: + os << " " << endl; + break; + case CT_BOOL: + os << " " << endl; + break; + case CT_COMMENT: + os << " " << endl; + break; + case CT_HISTORY: + os << " " << endl; + break; + default: + os << endl; + break; + } // Return output stream return os; diff --git a/src/fits/GFitsImage.cpp b/src/fits/GFitsImage.cpp index 33e566b..c7e6d35 100644 --- a/src/fits/GFitsImage.cpp +++ b/src/fits/GFitsImage.cpp @@ -125,7 +125,7 @@ GFitsImage::~GFitsImage() /***********************************************************************//** * @brief Assignment operator * - * @param image FITS image to be assigned + * @param[in] image FITS image to be assigned ***************************************************************************/ GFitsImage& GFitsImage::operator= (const GFitsImage& image) { @@ -158,9 +158,30 @@ GFitsImage& GFitsImage::operator= (const GFitsImage& image) ==========================================================================*/ /***********************************************************************//** + * @brief Return number of Bits per pixel (negative=floating point) + ***************************************************************************/ +int GFitsImage::bitpix(void) const +{ + // Return number of Bits per pixel + return m_bitpix; +} + + +/***********************************************************************//** + * @brief Return image dimension + ***************************************************************************/ +int GFitsImage::naxis(void) const +{ + // Return dimension + return m_naxis; +} + + +/***********************************************************************//** * @brief Return axis dimension * - * @param axis Axis for which the dimension should be returned (starting from 0) + * @param[in] axis Axis for which the dimension should be returned + * (starting from 0) ***************************************************************************/ int GFitsImage::naxes(int axis) const { @@ -176,6 +197,16 @@ int GFitsImage::naxes(int axis) const } +/***********************************************************************//** + * @brief Return number of pixels + ***************************************************************************/ +int GFitsImage::num_pixels(void) const +{ + // Return number of pixels + return m_num_pixels; +} + + /*========================================================================== = = = GFitsImage private methods = @@ -203,7 +234,7 @@ void GFitsImage::init_members(void) /***********************************************************************//** * @brief Copy class members * - * @param image FITS image to copy + * @param[in] image FITS image to copy ***************************************************************************/ void GFitsImage::copy_members(const GFitsImage& image) { @@ -232,7 +263,7 @@ void GFitsImage::free_members(void) { // Free memory if (m_naxes != NULL) delete [] m_naxes; - + // Mark memory as free m_naxes = NULL; @@ -244,13 +275,13 @@ void GFitsImage::free_members(void) /***********************************************************************//** * @brief Connect image to FITS file * - * @param fptr FITS file pointer to which the image should be connected + * @param[in] fptr FITS file pointer to which the image should be connected ***************************************************************************/ void GFitsImage::connect(__fitsfile* fptr) { // Connect Image m_fitsfile = *fptr; - + // Return return; } @@ -259,7 +290,7 @@ void GFitsImage::connect(__fitsfile* fptr) /***********************************************************************//** * @brief Open Image * - * @param fptr FITS file pointer + * @param[in] fptr FITS file pointer * * Open FITS image in FITS file. Opening means connecting the FITS file * pointer to the image and reading the image and axes dimensions. @@ -274,7 +305,7 @@ void GFitsImage::open_image(__fitsfile* fptr) // Save FITS file pointer m_fitsfile = *fptr; - + // Get the image dimensions status = __ffgidm(&m_fitsfile, &m_naxis, &status); if (status != 0) @@ -285,7 +316,7 @@ void GFitsImage::open_image(__fitsfile* fptr) // Get the axes dimensions if (m_naxis > 0) { - + // Allocate memory for axes dimensions if (m_naxes != NULL) delete [] m_naxes; m_naxes = new long[m_naxis]; @@ -294,14 +325,14 @@ void GFitsImage::open_image(__fitsfile* fptr) status = __ffgisz(&m_fitsfile, m_naxis, m_naxes, &status); if (status != 0) throw GException::fits_error(G_OPEN_IMAGE, status); - + // Calculate number of image pixels m_num_pixels = 1; for (int i = 0; i < m_naxis; ++i) m_num_pixels *= m_naxes[i]; } // endif: there is an image - + // Return return; } @@ -310,8 +341,8 @@ void GFitsImage::open_image(__fitsfile* fptr) /***********************************************************************//** * @brief Load FITS image * - * @param datatype Datatype of pixels to be saved - * @param pixels Pixel array to be saved + * @param[in] datatype Datatype of pixels to be saved + * @param[in] pixels Pixel array to be saved * * Save image pixels into FITS file. In case that the HDU does not exist it * is created. @@ -352,18 +383,19 @@ void GFitsImage::load_image(int datatype, const void* pixels, const void* nulval /***********************************************************************//** * @brief Save FITS image * - * @param datatype Datatype of pixels to be saved - * @param pixels Pixel array to be saved + * @param[in] datatype Datatype of pixels to be saved + * @param[in] pixels Pixel array to be saved * * Save image pixels into FITS file. In case that the HDU does not exist it - * is created. + * is created. In case that the pixel array is empty no data are saved; all + * image pixels will be empty in this case. ***************************************************************************/ void GFitsImage::save_image(int datatype, const void* pixels) { // Move to HDU int status = 0; status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status); - + // If HDU does not yet exist in file then create it now if (status == 107) { status = 0; @@ -388,7 +420,7 @@ void GFitsImage::save_image(int datatype, const void* pixels) } // Save the image pixels (if there are some ...) - if (m_naxis > 0) { + if (m_naxis > 0 && pixels != NULL) { long* fpixel = new long[m_naxis]; long* lpixel = new long[m_naxis]; for (int i = 0; i < m_naxis; ++i) { diff --git a/src/rsp/GLATResponse.cpp b/src/rsp/GLATResponse.cpp index ce7a9af..5669307 100644 --- a/src/rsp/GLATResponse.cpp +++ b/src/rsp/GLATResponse.cpp @@ -18,11 +18,14 @@ #include "GVector.hpp" #include "GLATResponse.hpp" #include "GFits.hpp" +#include "GFitsHDU.hpp" +#include "GFitsDblImage.hpp" #include "GFitsTableFltCol.hpp" /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ +#define G_LOAD "load(const std::string&, const std::string&)" #define G_INIT_AEFF "GLATResponse::init_aeff()" #define G_INIT_PSF "GLATResponse::init_psf()" #define G_INIT_EDISP "GLATResponse::init_edisp()" @@ -56,9 +59,8 @@ const double ln10 = 2.3025850929940459010936138; = = ==========================================================================*/ -/*************************************************************************** - * Constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Constructor ***************************************************************************/ GLATResponse::GLATResponse() : GResponse() { @@ -70,9 +72,10 @@ GLATResponse::GLATResponse() : GResponse() } -/*************************************************************************** - * Copy constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Copy constructor + * + * @param rsp Response to be copied ***************************************************************************/ GLATResponse::GLATResponse(const GLATResponse& rsp) : GResponse(rsp) { @@ -87,9 +90,8 @@ GLATResponse::GLATResponse(const GLATResponse& rsp) : GResponse(rsp) } -/*************************************************************************** - * Destructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Destructor ***************************************************************************/ GLATResponse::~GLATResponse() { @@ -107,9 +109,10 @@ GLATResponse::~GLATResponse() = = ==========================================================================*/ -/*************************************************************************** - * Assignment operator * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Assignment operator + * + * @param rsp Response to be assigned ***************************************************************************/ GLATResponse& GLATResponse::operator= (const GLATResponse& rsp) { @@ -141,9 +144,8 @@ GLATResponse& GLATResponse::operator= (const GLATResponse& rsp) = = ==========================================================================*/ -/*************************************************************************** - * Return value of instrument response function * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Return value of instrument response function. ***************************************************************************/ double GLATResponse::irf(const GSkyDir& obsDir, const double& obsEng, const GSkyDir& srcDir, const double& srcEng, @@ -155,9 +157,8 @@ double GLATResponse::irf(const GSkyDir& obsDir, const double& obsEng, } -/*************************************************************************** - * Return effective area * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Return effective area ***************************************************************************/ double GLATResponse::aeff(const GSkyDir& obsDir, const double& obsEng, const GSkyDir& srcDir, const double& srcEng, @@ -169,9 +170,8 @@ double GLATResponse::aeff(const GSkyDir& obsDir, const double& obsEng, } -/*************************************************************************** - * Return value of point spread function * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Return value of point spread function ***************************************************************************/ double GLATResponse::psf(const GSkyDir& obsDir, const double& obsEng, const GSkyDir& srcDir, const double& srcEng, @@ -183,9 +183,8 @@ double GLATResponse::psf(const GSkyDir& obsDir, const double& obsEng, } -/*************************************************************************** - * Return value of energy dispersion * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Return value of energy dispersion ***************************************************************************/ double GLATResponse::edisp(const GSkyDir& obsDir, const double& obsEng, const GSkyDir& srcDir, const double& srcEng, @@ -197,14 +196,14 @@ double GLATResponse::edisp(const GSkyDir& obsDir, const double& obsEng, } -/*************************************************************************** - * Set calibration database * - * ----------------------------------------------------------------------- * - ***************************************************************************/ -/** +/***********************************************************************//** * @brief Set the path to the calibration database. - */ -void GLATResponse::set_caldb(std::string caldb) + * + * @param caldb Absolute path to calibration database + * + * NOTE: So far no check is done on whether the path exists! + ***************************************************************************/ +void GLATResponse::set_caldb(const std::string& caldb) { // Simply copy path // NOTE: Some check should be done on whether the path exists !!! @@ -215,25 +214,29 @@ void GLATResponse::set_caldb(std::string caldb) } -/*************************************************************************** - * Load response * - * ----------------------------------------------------------------------- * - ***************************************************************************/ -/** +/***********************************************************************//** * @brief Load a specified LAT response function. - */ -void GLATResponse::load(std::string rspname, std::string rsptype) + * + * @param rspname Name of response + * @param rsptype Type of response ('front' or 'back') + * + * Loads the specified GLAST LAT response from the calibration database and + * performs some pre-calculations for faster response determination. + ***************************************************************************/ +void GLATResponse::load(const std::string& rspname, const std::string& rsptype) { // Store response name m_rspname = rspname; - - // Convert response type + + // Convert response type string to section if (rsptype == "front") m_section = 0; else if (rsptype == "back") m_section = 1; else - throw; + throw GException::rsp_invalid_type(G_LOAD, rsptype); + + // Store response type m_rsptype = rsptype; // Initialise effective area @@ -244,18 +247,46 @@ void GLATResponse::load(std::string rspname, std::string rsptype) // Initialise energy dispersion edisp_init(); + + // Return + return; } -/*************************************************************************** - * Save response * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Save response + * + * @param rspname Filename into which the response will be saved ***************************************************************************/ -/** - * @brief Save me my friend ... - */ -void GLATResponse::save(std::string rspname) const +void GLATResponse::save(const std::string& rspname) const { + // Open FITS file + GFits fits; + fits.open(rspname); + + // Build PSF HDUs + int naxes_psf2[] = {m_psf_energy_num, m_psf_ctheta_num}; + int naxes_psf3[] = {m_psf_angle_num, m_psf_energy_num, m_psf_ctheta_num}; + GFitsDblImage image_psf_psf(3, naxes_psf3, m_psf); + GFitsDblImage image_psf_norm(2, naxes_psf2, m_norm); + GFitsDblImage image_psf_sigma(2, naxes_psf2, m_sigma); + GFitsHDU hdu_psf_psf(image_psf_psf); + GFitsHDU hdu_psf_norm(image_psf_norm); + GFitsHDU hdu_psf_sigma(image_psf_sigma); + hdu_psf_psf.extname("PSF"); + hdu_psf_norm.extname("NORM"); + hdu_psf_sigma.extname("SIGMA"); + + // Append HDUs to FITS file + fits.append(&hdu_psf_psf); + fits.append(&hdu_psf_norm); + fits.append(&hdu_psf_sigma); + + // Save FITS file + fits.save(); + + // Return + return; } @@ -328,14 +359,14 @@ void GLATResponse::psf_init(void) GVector v_sigma = get_fits_vector(hdu, "SIGMA"); GVector v_gcore = get_fits_vector(hdu, "GCORE"); GVector v_gtail = get_fits_vector(hdu, "GTAIL"); - + // Set binning in angle, energy and cos theta m_psf_angle_num = 2000; m_psf_angle_min = 0.01; m_psf_angle_bin = 0.01; m_psf_energy_num = v_energy_lo.size(); m_psf_ctheta_num = v_ctheta_lo.size(); - + // Free old PSF memory if (m_psf != NULL) delete [] m_psf; if (m_norm != NULL) delete [] m_norm; @@ -347,7 +378,7 @@ void GLATResponse::psf_init(void) m_psf = new double[psf_size]; m_norm = new double[bin_size]; m_sigma = new double[bin_size]; - + // Setup PSF vector axis GVector xaxis(m_psf_angle_num); GVector u(m_psf_angle_num); @@ -356,46 +387,46 @@ void GLATResponse::psf_init(void) xaxis(i) = x; u(i) = 0.5*x*x; } - + // Get maximum angle m_psf_angle_max = xaxis(m_psf_angle_num-1); - + // Loop over all energy bins for (int ie = 0; ie < m_psf_energy_num; ++ie) { - + // Get mean energy of bin // NOTE: This should be replaced by a logarithmic mean double energy = 0.5 * (v_energy_lo(ie) + v_energy_hi(ie)); - + // Get scale at specified energy double scale = psf_scale(energy); - + // Loop over all cos theta bins for (int ic = 0; ic < m_psf_ctheta_num; ++ic) { - + // Extract PSF parameters int inx = ic * m_psf_energy_num + ie; double ncore = v_ncore(inx); double sigma = v_sigma(inx); double gcore = v_gcore(inx); double gtail = v_gtail(inx); - + // Evaluate ntail double denom = psf_base_value(10.0, gtail); double ntail = (denom != 0.0) ? ncore * psf_base_value(10.0, gcore) / denom : 0.0; - + // Calculate PSF dependence GVector psf = ncore * psf_base_vector(u, gcore) + ntail * psf_base_vector(u, gtail); - + // Normalize PSF vector to identical amplitudes at smallest angular // distance. This allows for accurate interpolation afterwards double norm = 1.0 / psf(0); psf *= norm; - + // Evaluate angular separation double stretch = sigma * scale; GVector delta = xaxis * stretch; - + // Calculate PSF normalization factor double sum = 0.0; for (int i = 0; i < m_psf_angle_num; ++i) { @@ -405,16 +436,16 @@ void GLATResponse::psf_init(void) } sum *= twopi; norm = scale / sum; - + // Store PSF information m_norm[inx] = norm; m_sigma[inx] = sigma; - + // Store PSF vector int ipsf = inx * m_psf_angle_num; for (int i = 0; i < m_psf_angle_num; ++i, ++ipsf) m_psf[ipsf] = psf(i); - + } // endfor: looped over cos theta } // endfor: looped over energies @@ -436,22 +467,22 @@ double GLATResponse::psf_get(const double& delta, const double& logE, const doub // Interpolate sigma and norm tables double sigma = 1.0; // Perform bi-linear interpolation in logE and ctheta double norm = 1.0; // Perform bi-linear interpolation in logE and ctheta - + // Evaluate scale double energy = pow(10.0,logE); // DUMMY: t=(0.01*(10.0^logE))^-0.8 double scale = psf_scale(energy); - + // Get stretch factor double stretch = sigma * scale; - + // Get PSF value from table double r = delta * deg2rad / stretch; // in radians - int inx = (r - m_psf_angle_min) / m_psf_angle_bin; // Perform linear interpolation + int inx = (int)((r - m_psf_angle_min) / m_psf_angle_bin); // Perform linear interpolation double psf = 1.0; - + // Normalize PSF psf *= norm; - + // Return PSF value return psf; } diff --git a/test/test_GFits.cpp b/test/test_GFits.cpp index b38bfed..7f5f848 100644 --- a/test/test_GFits.cpp +++ b/test/test_GFits.cpp @@ -38,18 +38,18 @@ int dequal(double val, double ref) ***************************************************************************/ void test_open(void) { - std::cout << "Test GFits: Open FITS file: "; + cout << "Test GFits: Open FITS file: "; try { GFits fits; fits.open("test_GFits.fits"); cout << endl << fits; } catch (exception &e) { - std::cout << std::endl << "TEST ERROR: Unable to open FITS file." << std::endl; - std::cout << e.what() << std::endl; + cout << endl << "TEST ERROR: Unable to open FITS file." << endl; + cout << e.what() << endl; throw; } - std::cout << ". ok." << std::endl; + cout << ". ok." << endl; } @@ -64,15 +64,15 @@ void test_columns(void) fits.open("test_GFits.fits"); } catch (exception &e) { - std::cout << std::endl << "TEST ERROR: Unable to open test file." << std::endl; - std::cout << e.what() << std::endl; + cout << endl << "TEST ERROR: Unable to open test file." << endl; + cout << e.what() << endl; throw; } // // Test single string column // - std::cout << "Test GFits: String column handling: "; + cout << "Test GFits: String column handling: "; try { GFitsTableStrCol str = *((GFitsTableStrCol*)fits.hdu("BinTable")->column("TSTRING")); if (str.string(0) != "1" || str.string(1) != "2" || str.string(2) != "") { @@ -93,16 +93,16 @@ void test_columns(void) std::cout << "."; } catch (exception &e) { - std::cout << std::endl << "TEST ERROR: Unable to handle single TSTRING column." << std::endl; - std::cout << e.what() << std::endl; + cout << endl << "TEST ERROR: Unable to handle single TSTRING column." << endl; + cout << e.what() << endl; throw; } - std::cout << ". ok." << std::endl; + cout << ". ok." << endl; // // Test single short column // - std::cout << "Test GFits: Short column handling: "; + cout << "Test GFits: Short column handling: "; try { GFitsTableShtCol sht = *((GFitsTableShtCol*)fits.hdu("BinTable")->column("TSHORT")); if (sht.integer(0) != 1 || sht.real(0) != 1.0 || sht.string(0) != "1" || @@ -115,16 +115,16 @@ void test_columns(void) std::cout << "."; } catch (exception &e) { - std::cout << std::endl << "TEST ERROR: Unable to handle single TSHORT column." << std::endl; - std::cout << e.what() << std::endl; + cout << endl << "TEST ERROR: Unable to handle single TSHORT column." << endl; + cout << e.what() << endl; throw; } - std::cout << ". ok." << std::endl; + cout << ". ok." << endl; // // Test single long column // - std::cout << "Test GFits: Long column handling: "; + cout << "Test GFits: Long column handling: "; try { GFitsTableLngCol lng = *((GFitsTableLngCol*)fits.hdu("BinTable")->column("TLONG")); if (lng.integer(0) != 10 || lng.real(0) != 10.0 || lng.string(0) != "10" || @@ -134,14 +134,14 @@ void test_columns(void) throw; } else - std::cout << "."; + cout << "."; } catch (exception &e) { - std::cout << std::endl << "TEST ERROR: Unable to handle single TLONG column." << std::endl; - std::cout << e.what() << std::endl; + cout << endl << "TEST ERROR: Unable to handle single TLONG column." << endl; + cout << e.what() << endl; throw; } - std::cout << ". ok." << std::endl; + cout << ". ok." << endl; // // Test single floating point column @@ -215,11 +215,11 @@ void test_columns(void) } } catch (exception &e) { - std::cout << std::endl << "TEST ERROR: Unable to handle single TFLOAT column." << std::endl; - std::cout << e.what() << std::endl; + cout << endl << "TEST ERROR: Unable to handle single TFLOAT column." << endl; + cout << e.what() << endl; throw; } - std::cout << ". ok." << std::endl; + cout << ". ok." << endl; // // Test single double column @@ -280,11 +280,11 @@ void test_columns(void) std::cout << "."; } catch (exception &e) { - std::cout << std::endl << "TEST ERROR: Unable to handle single TDOUBLE column." << std::endl; - std::cout << e.what() << std::endl; + cout << endl << "TEST ERROR: Unable to handle single TDOUBLE column." << endl; + cout << e.what() << endl; throw; } - std::cout << ". ok." << std::endl; + cout << ". ok." << endl; } @@ -296,10 +296,10 @@ void test_create(void) { // Dump header cout << "Test GFits: Create FITS file: "; - + // Remove FITS file system("rm -rf test.fits"); - + // Create FITS file with empty double precision image try { GFits fits; @@ -307,6 +307,7 @@ void test_create(void) GFitsDblImage image; GFitsHDU hdu(image); fits.append(&hdu); + //cout << fits; fits.save(); } catch (exception &e) { @@ -315,7 +316,7 @@ void test_create(void) throw; } cout << "."; - + // Attach double precision image double sum = 0.0; try { @@ -334,6 +335,7 @@ void test_create(void) } GFitsHDU hdu(image); fits.append(&hdu); + cout << fits; fits.save(); } catch (exception &e) { @@ -342,7 +344,7 @@ void test_create(void) throw; } cout << "."; - + // Re-open double precision image try { GFits fits; @@ -408,12 +410,12 @@ void test_image_double(void) throw; } cout << "."; - + // Bad 2D operator try { double result = image(0,1); } - catch (GException::fits_bad_image_operator &e) { + catch (GException::fits_wrong_image_operator &e) { cout << "."; } catch (exception &e) { @@ -426,7 +428,7 @@ void test_image_double(void) try { double result = image(0,1,2); } - catch (GException::fits_bad_image_operator &e) { + catch (GException::fits_wrong_image_operator &e) { cout << "."; } catch (exception &e) { @@ -439,7 +441,7 @@ void test_image_double(void) try { double result = image(0,1,2,3); } - catch (GException::fits_bad_image_operator &e) { + catch (GException::fits_wrong_image_operator &e) { cout << "."; } catch (exception &e) { @@ -447,7 +449,7 @@ void test_image_double(void) cout << e.what() << endl; throw; } - + } catch (exception &e) { cout << endl << "TEST ERROR: Unable to test GFitsDblImage classes." << endl; diff --git a/test/test_GResponse.cpp b/test/test_GResponse.cpp index 04822e8..e7ca4f2 100644 --- a/test/test_GResponse.cpp +++ b/test/test_GResponse.cpp @@ -12,8 +12,9 @@ ***************************************************************************/ /* __ Includes ___________________________________________________________ */ +#include +#include #include "test_GResponse.hpp" -#include // cout, cerr /* __ Namespaces _________________________________________________________ */ @@ -25,31 +26,18 @@ ***************************************************************************/ void test_lat_response(void) { + // Remove FITS file + system("rm -rf test_rsp.fits"); + cout << "Test GLATResponse: Open PSF FITS file: "; try { // Get HANDOFF Response GLATResponse rsp; rsp.set_caldb("irf/lat"); rsp.load("Pass5_v0", "front"); -/* - // Open FITS file - GFits fits; - fits.open("irf/lat/aeff_.fits"); - - // Get pointer towards effective area HDU - GFitsHDU* aeff = fits.hdu("EFFECTIVE AREA"); - if (aeff == NULL) { - cout << endl << "TEST ERROR: Unable to find HDU ." << endl; - throw; - } - // Get columns - GFitsTableFltCol energ_lo = *((GFitsTableFltCol*)aeff->column("ENERG_LO")); - GFitsTableFltCol energ_hi = *((GFitsTableFltCol*)aeff->column("ENERG_HI")); - GFitsTableFltCol ctheta_lo = *((GFitsTableFltCol*)aeff->column("CTHETA_LO")); - GFitsTableFltCol ctheta_hi = *((GFitsTableFltCol*)aeff->column("CTHETA_HI")); - GFitsTableFltCol effarea = *((GFitsTableFltCol*)aeff->column("EFFAREA")); -*/ + // Save response + rsp.save("test_rsp.fits"); } catch (exception &e) { cout << endl << "TEST ERROR: Unable to open FITS file." << endl; -- libgit2 0.21.4