From 56d87b7ad30800c7d8df486c910dfb0592139f33 Mon Sep 17 00:00:00 2001 From: knodlseder <> Date: Thu, 6 Mar 2008 15:53:37 +0000 Subject: [PATCH] enhance column table handling and testing suite --- include/GFitsData.hpp | 2 +- include/GFitsImage.hpp | 3 ++- include/GFitsTableCol.hpp | 45 +++++++++++++++++++++++++++------------------ include/GFitsTableDblCol.hpp | 8 +++++--- include/GFitsTableFltCol.hpp | 8 +++++--- include/GFitsTableLngCol.hpp | 11 ++++++++--- include/GFitsTableShtCol.hpp | 49 +++++++++++++++++++++++++------------------------ include/GFitsTableStrCol.hpp | 55 ++++++++++++++++++++++++++++++------------------------- src/fits/GFitsTable.cpp | 12 ++++++++---- src/fits/GFitsTableCol.cpp | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/fits/GFitsTableDblCol.cpp | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------- src/fits/GFitsTableFltCol.cpp | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------ src/fits/GFitsTableLngCol.cpp | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------------------------- src/fits/GFitsTableShtCol.cpp | 371 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------- src/fits/GFitsTableStrCol.cpp | 548 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- test/test_GFits.cpp | 630 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- 16 files changed, 1671 insertions(+), 760 deletions(-) diff --git a/include/GFitsData.hpp b/include/GFitsData.hpp index 0114e1f..ca7877f 100644 --- a/include/GFitsData.hpp +++ b/include/GFitsData.hpp @@ -46,7 +46,7 @@ public: protected: // Protected methods virtual void connect(__fitsfile* fptr); - + // Protected data area __fitsfile m_fitsfile; //!< FITS file }; diff --git a/include/GFitsImage.hpp b/include/GFitsImage.hpp index 11a9156..0bcc330 100644 --- a/include/GFitsImage.hpp +++ b/include/GFitsImage.hpp @@ -66,7 +66,8 @@ protected: void copy_members(const GFitsImage& image); void free_members(void); void open_image(__fitsfile* fptr); - void load_image(int datatype, const void* pixels, const void* nulval, int* anynul); + void load_image(int datatype, const void* pixels, const void* nulval, + int* anynul); void save_image(int datatype, const void* pixels); // Private data area diff --git a/include/GFitsTableCol.hpp b/include/GFitsTableCol.hpp index 9802575..5038b23 100644 --- a/include/GFitsTableCol.hpp +++ b/include/GFitsTableCol.hpp @@ -37,9 +37,6 @@ class GFitsTableCol { // Friend classes friend class GFitsTable; - // I/O friends -// friend ostream& operator<< (ostream& os, const GFitsTableCol& column); - public: // Constructors and destructors GFitsTableCol(); @@ -70,24 +67,36 @@ public: protected: // Protected data area - std::string m_name; //!< Column name - std::string m_unit; //!< Column unit - int m_colnum; //!< @brief Column number (starting from 1). - //!< This parameter is used to signal if a - //!< table column corresponds to a FITS file - //!< column. If it is set to 0 there is no - //!< correspondance. - int m_type; //!< Column type - int m_repeat; //!< Repeat value of column - int m_width; //!< Width of single column element - int m_number; //!< Number of elements in column - //!< m_number = m_repeat / m_width - int m_length; //!< Length of column - __fitsfile m_fitsfile; //!< FITS file associated with column + std::string m_name; //!< Column name + std::string m_unit; //!< Column unit + int m_colnum; //!< @brief Column number (starting from 1). + //!< This parameter is used to signal if a + //!< table column corresponds to a FITS file + //!< column. If it is set to 0 there is no + //!< correspondance. + int m_type; //!< Column type + int m_repeat; //!< Repeat value of column + int m_width; //!< Width of single column element + int m_number; //!< @brief Number of elements in column. + //!< m_number = m_repeat / m_width + int m_length; //!< Length of column + int m_size; //!< Size of allocated data area (0 if not loaded) + int m_anynul; //!< Number of NULLs encountered + __fitsfile m_fitsfile; //!< FITS file associated with column - // Protected methods + // Protected virtual methods virtual std::string ascii_format(void) const = 0; virtual std::string binary_format(void) const = 0; + virtual void alloc_data(void) = 0; + virtual void init_data(void) = 0; + virtual void fetch_data(void) = 0; + virtual void* ptr_data(void) = 0; + virtual void* ptr_nulval(void) = 0; + + // Protected methods + void load_column(void); + void save_column(void); + void dump_column(ostream& os, void* data) const; private: // Private methods diff --git a/include/GFitsTableDblCol.hpp b/include/GFitsTableDblCol.hpp index f1f6e1d..6815105 100644 --- a/include/GFitsTableDblCol.hpp +++ b/include/GFitsTableDblCol.hpp @@ -68,15 +68,17 @@ private: void init_members(void); void copy_members(const GFitsTableDblCol& column); void free_members(void); - void fetch_data(void); std::string ascii_format(void) const; std::string binary_format(void) const; + void alloc_data(void); + void init_data(void); + void fetch_data(void); + void* ptr_data(void) { return m_data; } + void* ptr_nulval(void) { return m_nulval; } // Private data area - int m_size; //!< Size of allocated data area (0 if not loaded) double* m_data; //!< Data area double* m_nulval; //!< NULL value - int m_anynul; //!< Number of NULLs encountered }; #endif /* GFITSTABLEDBLCOL_HPP */ diff --git a/include/GFitsTableFltCol.hpp b/include/GFitsTableFltCol.hpp index 4f52367..0771087 100644 --- a/include/GFitsTableFltCol.hpp +++ b/include/GFitsTableFltCol.hpp @@ -68,15 +68,17 @@ private: void init_members(void); void copy_members(const GFitsTableFltCol& column); void free_members(void); - void fetch_data(void); std::string ascii_format(void) const; std::string binary_format(void) const; + void alloc_data(void); + void init_data(void); + void fetch_data(void); + void* ptr_data(void) { return m_data; } + void* ptr_nulval(void) { return m_nulval; } // Private data area - int m_size; //!< Size of allocated data area (0 if not loaded) float* m_data; //!< Data area float* m_nulval; //!< NULL value - int m_anynul; //!< Number of NULLs encountered }; #endif /* GFITSTABLEFLTCOL_HPP */ diff --git a/include/GFitsTableLngCol.hpp b/include/GFitsTableLngCol.hpp index 0a243d8..2866658 100644 --- a/include/GFitsTableLngCol.hpp +++ b/include/GFitsTableLngCol.hpp @@ -38,6 +38,9 @@ ***************************************************************************/ class GFitsTableLngCol : public GFitsTableCol { + // I/O friends + friend ostream& operator<< (ostream& os, const GFitsTableLngCol& column); + public: // Constructors and destructors GFitsTableLngCol(); @@ -65,15 +68,17 @@ private: void init_members(void); void copy_members(const GFitsTableLngCol& column); void free_members(void); - void fetch_data(void); std::string ascii_format(void) const; std::string binary_format(void) const; + void alloc_data(void); + void init_data(void); + void fetch_data(void); + void* ptr_data(void) { return m_data; } + void* ptr_nulval(void) { return m_nulval; } // Private data area - int m_size; //!< Size of data area long* m_data; //!< Data area long* m_nulval; //!< NULL value - int m_anynul; //!< Number of NULLs encountered }; #endif /* GFITSTABLELNGCOL_HPP */ diff --git a/include/GFitsTableShtCol.hpp b/include/GFitsTableShtCol.hpp index f302b28..44b82fa 100644 --- a/include/GFitsTableShtCol.hpp +++ b/include/GFitsTableShtCol.hpp @@ -10,6 +10,11 @@ * (at your option) any later version. * * * ***************************************************************************/ +/** + * @file GFitsTableShtCol.hpp + * @brief GFitsTableShtCol class definition. + * @author J. Knodlseder + */ #ifndef GFITSTABLESHTCOL_HPP #define GFITSTABLESHTCOL_HPP @@ -24,21 +29,30 @@ /* __ Structures _________________________________________________________ */ -/*************************************************************************** - * GFitsTableShtCol class definition * +/***********************************************************************//** + * @class GFitsTableShtCol + * + * @brief Interface for FITS table short integer column + * + * This class implements a FITS table short integer column. ***************************************************************************/ class GFitsTableShtCol : public GFitsTableCol { + // I/O friends + friend ostream& operator<< (ostream& os, const GFitsTableShtCol& column); + public: // Constructors and destructors GFitsTableShtCol(); GFitsTableShtCol(const std::string& name, const int& length, - const int& size = 1); + const int& size = 1); GFitsTableShtCol(const GFitsTableShtCol& column); virtual ~GFitsTableShtCol(); // Operators GFitsTableShtCol& operator= (const GFitsTableShtCol& column); + short& operator() (const int& row, const int& inx = 0); + const short& operator() (const int& row, const int& inx = 0) const; // Methods void save(void); @@ -46,11 +60,7 @@ public: double real(const int& row, const int& col = 0); int integer(const int& row, const int& col = 0); GFitsTableShtCol* clone(void) const; - double* ptr_double(void); - float* ptr_float(void); - short* ptr_short(void); - long* ptr_long(void); - int* ptr_int(void); + short* data(void); void set_nullval(const short* value); private: @@ -58,26 +68,17 @@ private: void init_members(void); void copy_members(const GFitsTableShtCol& column); void free_members(void); - void load(void); std::string ascii_format(void) const; std::string binary_format(void) const; + void alloc_data(void); + void init_data(void); + void fetch_data(void); + void* ptr_data(void) { return m_data; } + void* ptr_nulval(void) { return m_nulval; } // Private data area - int m_size; // Size of data area - short* m_data; // Data area - short* m_nulval; // NULL value - int m_anynul; // Number of NULLs encountered + short* m_data; //!< Data area + short* m_nulval; //!< NULL value }; - -/*************************************************************************** - * Inline methods * - ***************************************************************************/ -inline short* GFitsTableShtCol::ptr_short(void) { return m_data; } -inline -GFitsTableShtCol* GFitsTableShtCol::clone(void) const -{ - return new GFitsTableShtCol(*this); -} - #endif /* GFITSTABLESHTCOL_HPP */ diff --git a/include/GFitsTableStrCol.hpp b/include/GFitsTableStrCol.hpp index ed7f655..e81a955 100644 --- a/include/GFitsTableStrCol.hpp +++ b/include/GFitsTableStrCol.hpp @@ -10,6 +10,11 @@ * (at your option) any later version. * * * ***************************************************************************/ +/** + * @file GFitsTableStrCol.hpp + * @brief GFitsTableStrCol class definition. + * @author J. Knodlseder + */ #ifndef GFITSTABLESTRCOL_HPP #define GFITSTABLESTRCOL_HPP @@ -24,21 +29,30 @@ /* __ Structures _________________________________________________________ */ -/*************************************************************************** - * GFitsTableStrCol class definition * +/***********************************************************************//** + * @class GFitsTableStrCol + * + * @brief Interface for FITS table string column + * + * This class implements a FITS table string column. ***************************************************************************/ class GFitsTableStrCol : public GFitsTableCol { + // I/O friends + friend ostream& operator<< (ostream& os, const GFitsTableStrCol& column); + public: // Constructors and destructors GFitsTableStrCol(); GFitsTableStrCol(const std::string& name, const int& length, - const int& size = 1); + const int& width, const int& size = 1); GFitsTableStrCol(const GFitsTableStrCol& column); ~GFitsTableStrCol(); // Operators - GFitsTableStrCol& operator= (const GFitsTableStrCol& column); + GFitsTableStrCol& operator= (const GFitsTableStrCol& column); + std::string& operator() (const int& row, const int& inx = 0); + const std::string& operator() (const int& row, const int& inx = 0) const; // Methods void save(void); @@ -46,37 +60,28 @@ public: double real(const int& row, const int& col = 0); int integer(const int& row, const int& col = 0); GFitsTableStrCol* clone(void) const; - float* ptr_float(void); - double* ptr_double(void); - short* ptr_short(void); - long* ptr_long(void); - int* ptr_int(void); - void set_nullstr(const std::string string); + std::string* data(void); + void set_nullval(const std::string string); private: // Private methods void init_members(void); void copy_members(const GFitsTableStrCol& column); void free_members(void); - void load(void); std::string ascii_format(void) const; std::string binary_format(void) const; + void alloc_data(void); + void init_data(void); + void fetch_data(void); + void* ptr_data(void) { return m_buffer; } + void* ptr_nulval(void) { return m_nulval; } + void alloc_buffer(void); + void free_buffer(void); // Private data area - int m_size; // Total number of strings - char** m_data; // Data area - char* m_nulstr; // NULL string - int m_anynul; // Number of NULLs encountered + std::string* m_data; //!< Data area + char** m_buffer; //!< Data area for CFITSIO transfer + char* m_nulval; //!< NULL string }; - -/*************************************************************************** - * Inline methods * - ***************************************************************************/ -inline -GFitsTableStrCol* GFitsTableStrCol::clone(void) const -{ - return new GFitsTableStrCol(*this); -} - #endif /* GFITSTABLESTRCOL_HPP */ diff --git a/src/fits/GFitsTable.cpp b/src/fits/GFitsTable.cpp index 2756f5a..81b98e9 100644 --- a/src/fits/GFitsTable.cpp +++ b/src/fits/GFitsTable.cpp @@ -917,16 +917,20 @@ ostream& operator<< (ostream& os, const GFitsTable& table) if (table.m_columns[i] != NULL) { switch (table.m_columns[i]->type()) { case __TSTRING: - os << " column " << i << " no << operator" << endl; + os << " " << *((GFitsTableStrCol*)table.m_columns[i]) + << endl; break; case __TSHORT: - os << " column " << i << " no << operator" << endl; + os << " " << *((GFitsTableShtCol*)table.m_columns[i]) + << endl; break; case __TLONG: - os << " column " << i << " no << operator" << endl; + os << " " << *((GFitsTableLngCol*)table.m_columns[i]) + << endl; break; case __TFLOAT: - os << " column " << i << " no << operator" << endl; + os << " " << *((GFitsTableFltCol*)table.m_columns[i]) + << endl; break; case __TDOUBLE: os << " " << *((GFitsTableDblCol*)table.m_columns[i]) diff --git a/src/fits/GFitsTableCol.cpp b/src/fits/GFitsTableCol.cpp index 11067c0..708a381 100644 --- a/src/fits/GFitsTableCol.cpp +++ b/src/fits/GFitsTableCol.cpp @@ -20,6 +20,8 @@ /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ +#define G_LOAD_COLUMN "GFitsTableCol::load_column(void*, void*)" +#define G_SAVE_COLUMN "GFitsTableCol::save_column(void*, void*)" /* __ Macros _____________________________________________________________ */ @@ -268,6 +270,8 @@ void GFitsTableCol::init_members(void) m_width = 0; m_number = 0; m_length = 0; + m_size = 0; + m_anynul = 0; m_fitsfile.HDUposition = 0; m_fitsfile.Fptr = NULL; @@ -292,6 +296,8 @@ void GFitsTableCol::copy_members(const GFitsTableCol& column) m_width = column.m_width; m_number = column.m_number; m_length = column.m_length; + m_size = column.m_size; + m_anynul = column.m_anynul; m_fitsfile = column.m_fitsfile; // Return @@ -329,6 +335,159 @@ void GFitsTableCol::connect(__fitsfile* fptr) } +/***********************************************************************//** + * @brief Load table column from FITS file + * + * @exception GException::fits_hdu_not_found + * Specified HDU not found in FITS file. + * @exception GException::fits_error + * An error occured while loading column data from FITS file. + * + * If a FITS file is attached to the column the data are loaded into memory + * from the FITS file. If no FITS file is attached, memory is allocated + * to hold the column data and all cells are set to 0. + * + * The method make use of the virtual methods + * GFitsTableCol::alloc_data, + * GFitsTableCol::init_data, + * GFitsTableCol::ptr_data, and + * GFitsTableCol::ptr_nulval. + * These methods are implemented by the derived column classes which + * implement a specific storage class (i.e. float, double, short, ...). + ***************************************************************************/ +void GFitsTableCol::load_column(void) +{ + // Calculate size of memory + m_size = m_number * m_length; + + // Load only if the column has a positive size + if (m_size > 0) { + + // Allocate fresh memory + alloc_data(); + + // If a FITS file is attached then load column data from the FITS + // file + if (m_fitsfile.Fptr != NULL) { + + // Move to the HDU + int status = 0; + status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, + NULL, &status); + if (status != 0) + throw GException::fits_hdu_not_found(G_LOAD_COLUMN, + (m_fitsfile.HDUposition)+1, + status); + + // Load data + status = __ffgcv(&m_fitsfile, m_type, m_colnum, 1, 1, m_size, + ptr_nulval(), ptr_data(), &m_anynul, &status); + if (status != 0) + throw GException::fits_error(G_LOAD_COLUMN, status); + } + + // ... otherwise initialise all column values + else + init_data(); + + } // endif: column has a positive size + + // Return + return; +} + + +/***********************************************************************//** + * @brief Save table column into FITS file + * + * @exception GException::fits_hdu_not_found + * Specified HDU not found in FITS file. + * @exception GException::fits_error + * Error occured during writing of the column data. + * + * The table column is only saved if it is linked to a FITS file and if the + * data are indeed present in the class instance. This avoids saving of data + * that have not been modified. + * + * The method make use of the virtual methods + * GFitsTableCol::ptr_data and + * GFitsTableCol::ptr_nulval. + * These methods are implemented by the derived column classes which + * implement a specific storage class (i.e. float, double, short, ...). + ***************************************************************************/ +void GFitsTableCol::save_column(void) +{ + // Continue only if a FITS file is connected and data have been loaded + if (m_fitsfile.Fptr != NULL && m_colnum > 0 && ptr_data() != NULL) { + + // Move to the HDU + int status = 0; + status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, + &status); + if (status != 0) + throw GException::fits_hdu_not_found(G_SAVE_COLUMN, + (m_fitsfile.HDUposition)+1, + status); + // Save the column data + status = __ffpcn(&m_fitsfile, m_type, m_colnum, 1, 1, + (long)m_size, ptr_data(), ptr_nulval(), &status); + if (status != 0) + throw GException::fits_error(G_SAVE_COLUMN, status); + + } // endif: FITS file was connected + + // Return + return; +} + + +/***********************************************************************//** + * @brief Put column information in output stream + * + * @param[in] os Output stream + * @param[in] column Column to put in output stream + ***************************************************************************/ +void GFitsTableCol::dump_column(ostream& os, void* data) const +{ + // Put column name in stream + os << "'" << m_name << "'"; + + // Put FITS column number in stream + if (m_colnum > 0) + os << " [fits_colnum=" << m_colnum << "]"; + else + os << " [not linked to FITS file]"; + + // Put column type in stream + os << " " << ascii_format(); + os << " " << binary_format(); + + // Put data loading in stream + if (data == NULL) + os << " (not loaded)"; + else + os << " (loaded in memory)"; + + // Set data area size + os << " size=" << m_size; + + // Set vector length + os << " repeat=" << m_repeat; + + // Set width + os << " width=" << m_width; + + // Set number + os << " number=" << m_number; + + // Set length + os << " length=" << m_length; + + // Return + return; +} + + /*========================================================================== = = = GFitsTableCol friends = diff --git a/src/fits/GFitsTableDblCol.cpp b/src/fits/GFitsTableDblCol.cpp index 92589a6..69e256f 100644 --- a/src/fits/GFitsTableDblCol.cpp +++ b/src/fits/GFitsTableDblCol.cpp @@ -21,11 +21,9 @@ /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ -#define G_SAVE "GFitsTableDblCol::save(void)" -#define G_STRING "GFitsTableDblCol::string(const int&, const int&)" -#define G_REAL "GFitsTableDblCol::real(const int&, const int&)" -#define G_INTEGER "GFitsTableDblCol::integer(const int&, const int&)" -#define G_FETCH_DATA "GFitsTableDblCol::fetch_data()" +#define G_STRING "GFitsTableDblCol::string(const int&, const int&)" +#define G_REAL "GFitsTableDblCol::real(const int&, const int&)" +#define G_INTEGER "GFitsTableDblCol::integer(const int&, const int&)" /* __ Macros _____________________________________________________________ */ @@ -161,7 +159,7 @@ double& GFitsTableDblCol::operator() (const int& row, const int& inx) // Calculate pixel offset int offset = row * m_number + inx; - // Return image pixel + // Return data bin return m_data[offset]; } @@ -180,7 +178,7 @@ double& GFitsTableDblCol::operator() (const int& row, const int& inx) * if range checking is required. ***************************************************************************/ const double& GFitsTableDblCol::operator() (const int& row, const int& inx) - const + const { // If data are not available then load them now if (m_data == NULL) ((GFitsTableDblCol*)this)->fetch_data(); @@ -188,7 +186,7 @@ const double& GFitsTableDblCol::operator() (const int& row, const int& inx) // Calculate pixel offset int offset = row * m_number + inx; - // Return image pixel + // Return data bin return m_data[offset]; } @@ -202,35 +200,16 @@ const double& GFitsTableDblCol::operator() (const int& row, const int& inx) /***********************************************************************//** * @brief Save table column into FITS file * - * @exception GException::fits_hdu_not_found - * Specified HDU not found in FITS file. - * @exception GException::fits_error - * Error occured during writing of the column data. - * * The table column is only saved if it is linked to a FITS file and if the * data are indeed present in the class instance. This avoids saving of data * that have not been modified. + * + * Refer to GFitsTableCol::save_column() for more information. ***************************************************************************/ void GFitsTableDblCol::save(void) { - // Continue only if a FITS file is connected and data have been loaded - if (m_fitsfile.Fptr != NULL && m_colnum > 0 && m_data != NULL) { - - // Move to the HDU - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - if (status != 0) - throw GException::fits_hdu_not_found(G_SAVE, - (m_fitsfile.HDUposition)+1, - status); - // Save the column data - status = __ffpcn(&m_fitsfile, __TDOUBLE, m_colnum, 1, 1, - (long)m_size, m_data, m_nulval, &status); - if (status != 0) - throw GException::fits_error(G_SAVE, status); - - } // endif: FITS file was connected + // Save column + save_column(); // Return return; @@ -406,8 +385,6 @@ void GFitsTableDblCol::init_members(void) { // Initialise members m_type = __TDOUBLE; - m_size = 0; - m_anynul = 0; m_data = NULL; m_nulval = NULL; @@ -424,8 +401,6 @@ void GFitsTableDblCol::init_members(void) void GFitsTableDblCol::copy_members(const GFitsTableDblCol& column) { // Copy attributes - m_size = column.m_size; - m_anynul = column.m_anynul; // Copy column data if (column.m_data != NULL && m_size > 0) { @@ -465,53 +440,6 @@ void GFitsTableDblCol::free_members(void) /***********************************************************************//** - * @brief Fetch column data - * - * @exception GException::fits_error - * An error occured while loading column data from FITS file. - * - * If a FITS file is attached to the column the data are loaded into memory - * from the FITS file. If no FITS file is attached, memory is allocated - * to hold the column data and all cells are set to 0. - ***************************************************************************/ -void GFitsTableDblCol::fetch_data(void) -{ - // Calculate size of memory - m_size = m_number * m_length; - - // Load only if the column has a positive size - if (m_size > 0) { - - // Allocate fresh memory - if (m_data != NULL) delete [] m_data; - m_data = new double[m_size]; - - // If a FITS file is attached then load column data from the FITS - // file - if (m_fitsfile.Fptr != NULL) { - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - status = __ffgcv(&m_fitsfile, __TDOUBLE, m_colnum, 1, 1, m_size, - m_nulval, m_data, &m_anynul, &status); - if (status != 0) - throw GException::fits_error(G_FETCH_DATA, status); - } - - // ... otherwise initialise all column values to 0 - else { - for (int i = 0; i < m_size; ++i) - m_data[i] = 0.0; - } - - } // endif: column has a positive size - - // Return - return; -} - - -/***********************************************************************//** * @brief Returns format string of ASCII table ***************************************************************************/ std::string GFitsTableDblCol::ascii_format(void) const @@ -549,6 +477,61 @@ std::string GFitsTableDblCol::binary_format(void) const } +/***********************************************************************//** + * @brief Allocates column data + ***************************************************************************/ +void GFitsTableDblCol::alloc_data(void) +{ + // Free any existing memory + if (m_data != NULL) delete [] m_data; + + // Mark pointer as free + m_data = NULL; + + // Allocate new data + if (m_size > 0) + m_data = new double[m_size]; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Initialise column data + ***************************************************************************/ +void GFitsTableDblCol::init_data(void) +{ + // Initialise data if they exist + if (m_data != NULL) { + for (int i = 0; i < m_size; ++i) + m_data[i] = 0.0; + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Fetch column data + * + * If a FITS file is attached to the column the data are loaded into memory + * from the FITS file. If no FITS file is attached, memory is allocated + * to hold the column data and all cells are set to 0. + * + * Refer to GFitsTableCol::load_column for more information. + ***************************************************************************/ +void GFitsTableDblCol::fetch_data(void) +{ + // Save column + load_column(); + + // Return + return; +} + + /*========================================================================== = = = GFitsTableDblCol friends = @@ -563,39 +546,8 @@ std::string GFitsTableDblCol::binary_format(void) const ***************************************************************************/ ostream& operator<< (ostream& os, const GFitsTableDblCol& column) { - // Put column name in stream - os << "'" << column.m_name << "'"; - - // Put FITS column number in stream - if (column.m_colnum > 0) - os << " [fits_colnum=" << column.m_colnum << "]"; - else - os << " [not linked to FITS file]"; - - // Put column type in stream - os << " " << column.ascii_format(); - os << " " << column.binary_format(); - - // Put data loading in stream - if (column.m_data == NULL) - os << " (not loaded)"; - else - os << " (loaded in memory)"; - - // Set data area size - os << " size=" << column.m_size; - - // Set vector length - os << " repeat=" << column.m_repeat; - - // Set width - os << " width=" << column.m_width; - - // Set number - os << " number=" << column.m_number; - - // Set length - os << " length=" << column.m_length; + // Dump column in output stream + column.dump_column(os, column.m_data); // Return output stream return os; diff --git a/src/fits/GFitsTableFltCol.cpp b/src/fits/GFitsTableFltCol.cpp index ee2860e..ef10309 100644 --- a/src/fits/GFitsTableFltCol.cpp +++ b/src/fits/GFitsTableFltCol.cpp @@ -21,11 +21,9 @@ /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ -#define G_SAVE "GFitsTableFltCol::save()" -#define G_STRING "GFitsTableFltCol::string(const int&, const int&)" -#define G_REAL "GFitsTableFltCol::real(const int&, const int&)" -#define G_INTEGER "GFitsTableFltCol::integer(const int&, const int&)" -#define G_FETCH_DATA "GFitsTableFltCol::fetch_data()" +#define G_STRING "GFitsTableFltCol::string(const int&, const int&)" +#define G_REAL "GFitsTableFltCol::real(const int&, const int&)" +#define G_INTEGER "GFitsTableFltCol::integer(const int&, const int&)" /* __ Macros _____________________________________________________________ */ @@ -202,35 +200,16 @@ const float& GFitsTableFltCol::operator() (const int& row, const int& inx) /***********************************************************************//** * @brief Save table column into FITS file * - * @exception GException::fits_hdu_not_found - * Specified HDU not found in FITS file. - * @exception GException::fits_error - * Error occured during writing of the column data. - * * The table column is only saved if it is linked to a FITS file and if the * data are indeed present in the class instance. This avoids saving of data * that have not been modified. + * + * Refer to GFitsTableCol::save_column() for more information. ***************************************************************************/ void GFitsTableFltCol::save(void) { - // Continue only if a FITS file is connected and data have been loaded - if (m_fitsfile.Fptr != NULL && m_colnum > 0 && m_data != NULL) { - - // Move to the HDU - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - if (status != 0) - throw GException::fits_hdu_not_found(G_SAVE, - (m_fitsfile.HDUposition)+1, - status); - // Save the column data - status = __ffpcn(&m_fitsfile, __TFLOAT, m_colnum, 1, 1, - (long)m_size, m_data, m_nulval, &status); - if (status != 0) - throw GException::fits_error(G_SAVE, status); - - } // endif: FITS file was connected + // Save column + save_column(); // Return return; @@ -410,8 +389,6 @@ void GFitsTableFltCol::init_members(void) { // Initialise members m_type = __TFLOAT; - m_size = 0; - m_anynul = 0; m_data = NULL; m_nulval = NULL; @@ -428,8 +405,6 @@ void GFitsTableFltCol::init_members(void) void GFitsTableFltCol::copy_members(const GFitsTableFltCol& column) { // Copy attributes - m_size = column.m_size; - m_anynul = column.m_anynul; // Copy column data if (column.m_data != NULL && m_size > 0) { @@ -469,55 +444,6 @@ void GFitsTableFltCol::free_members(void) /***********************************************************************//** - * @brief Fetch column data - * - * @exception GException::fits_error - * An error occured while loading column data from FITS file. - * - * If a FITS file is attached to the column the data are loaded into memory - * from the FITS file. If no FITS file is attached, memory is allocated - * to hold the column data and all cells are set to 0. - ***************************************************************************/ -void GFitsTableFltCol::fetch_data(void) -{ - // Calculate size of memory - m_size = m_number * m_length; - - // Load only if the column has a positive size - if (m_size > 0) { - - // Allocate fresh memory - if (m_data != NULL) delete [] m_data; - m_data = new float[m_size]; - - // If a FITS file is attached then load column data from the FITS - // file - if (m_fitsfile.Fptr != NULL) { - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - status = __ffgcv(&m_fitsfile, __TFLOAT, m_colnum, 1, 1, m_size, - m_nulval, m_data, &m_anynul, &status); - if (status != 0) - throw GException::fits_error(G_FETCH_DATA, status); - } - - // ... otherwise initialise all column values to 0 - else { - for (int i = 0; i < m_size; ++i) - m_data[i] = 0.0; - } - - } // endif: column has a positive size - - // Return - return; -} - - - - -/***********************************************************************//** * @brief Returns format string of ASCII table ***************************************************************************/ std::string GFitsTableFltCol::ascii_format(void) const @@ -555,6 +481,61 @@ std::string GFitsTableFltCol::binary_format(void) const } +/***********************************************************************//** + * @brief Allocates column data + ***************************************************************************/ +void GFitsTableFltCol::alloc_data(void) +{ + // Free any existing memory + if (m_data != NULL) delete [] m_data; + + // Mark pointer as free + m_data = NULL; + + // Allocate new data + if (m_size > 0) + m_data = new float[m_size]; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Initialise column data + ***************************************************************************/ +void GFitsTableFltCol::init_data(void) +{ + // Initialise data if they exist + if (m_data != NULL) { + for (int i = 0; i < m_size; ++i) + m_data[i] = 0.0; + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Fetch column data + * + * If a FITS file is attached to the column the data are loaded into memory + * from the FITS file. If no FITS file is attached, memory is allocated + * to hold the column data and all cells are set to 0. + * + * Refer to GFitsTableCol::load_column for more information. + ***************************************************************************/ +void GFitsTableFltCol::fetch_data(void) +{ + // Save column + load_column(); + + // Return + return; +} + + /*========================================================================== = = = GFitsTableFltCol friends = @@ -569,39 +550,8 @@ std::string GFitsTableFltCol::binary_format(void) const ***************************************************************************/ ostream& operator<< (ostream& os, const GFitsTableFltCol& column) { - // Put column name in stream - os << "'" << column.m_name << "'"; - - // Put FITS column number in stream - if (column.m_colnum > 0) - os << " [fits_colnum=" << column.m_colnum << "]"; - else - os << " [not linked to FITS file]"; - - // Put column type in stream - os << " " << column.ascii_format(); - os << " " << column.binary_format(); - - // Put data loading in stream - if (column.m_data == NULL) - os << " (not loaded)"; - else - os << " (loaded in memory)"; - - // Set data area size - os << " size=" << column.m_size; - - // Set vector length - os << " repeat=" << column.m_repeat; - - // Set width - os << " width=" << column.m_width; - - // Set number - os << " number=" << column.m_number; - - // Set length - os << " length=" << column.m_length; + // Dump column in output stream + column.dump_column(os, column.m_data); // Return output stream return os; diff --git a/src/fits/GFitsTableLngCol.cpp b/src/fits/GFitsTableLngCol.cpp index 7c6e091..7262a5b 100644 --- a/src/fits/GFitsTableLngCol.cpp +++ b/src/fits/GFitsTableLngCol.cpp @@ -21,11 +21,9 @@ /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ -#define G_SAVE "GFitsTableLngCol::save()" -#define G_STRING "GFitsTableLngCol::string(const int&, const int&)" -#define G_REAL "GFitsTableLngCol::real(const int&, const int&)" -#define G_INTEGER "GFitsTableLngCol::integer(const int&, const int&)" -#define G_FETCH_DATA "GFitsTableLngCol::fetch_data()" +#define G_STRING "GFitsTableLngCol::string(const int&, const int&)" +#define G_REAL "GFitsTableLngCol::real(const int&, const int&)" +#define G_INTEGER "GFitsTableLngCol::integer(const int&, const int&)" /* __ Macros _____________________________________________________________ */ @@ -78,8 +76,8 @@ GFitsTableLngCol::GFitsTableLngCol(const std::string& name, * * @param[in] column Column from which class instance should be built. ***************************************************************************/ -GFitsTableLngCol::GFitsTableLngCol(const GFitsTableLngCol& column) : - GFitsTableCol(column) +GFitsTableLngCol::GFitsTableLngCol(const GFitsTableLngCol& column) + : GFitsTableCol(column) { // Initialise class members for clean destruction init_members(); @@ -159,7 +157,7 @@ long& GFitsTableLngCol::operator() (const int& row, const int& inx) if (m_data == NULL) fetch_data(); // Calculate pixel offset - int offset = row * m_repeat + inx; + int offset = row * m_number + inx; // Return image pixel return m_data[offset]; @@ -180,13 +178,13 @@ long& GFitsTableLngCol::operator() (const int& row, const int& inx) * if range checking is required. ***************************************************************************/ const long& GFitsTableLngCol::operator() (const int& row, const int& inx) - const + const { // If data are not available then load them now if (m_data == NULL) ((GFitsTableLngCol*)this)->fetch_data(); // Calculate pixel offset - int offset = row * m_repeat + inx; + int offset = row * m_number + inx; // Return image pixel return m_data[offset]; @@ -202,27 +200,16 @@ const long& GFitsTableLngCol::operator() (const int& row, const int& inx) /***********************************************************************//** * @brief Save table column into FITS file * - * @exception GException::fits_hdu_not_found - * Specified HDU not found in FITS file. + * The table column is only saved if it is linked to a FITS file and if the + * data are indeed present in the class instance. This avoids saving of data + * that have not been modified. + * + * Refer to GFitsTableCol::save_column() for more information. ***************************************************************************/ void GFitsTableLngCol::save(void) { - // Continue only if a FITS file is connected - if (m_fitsfile.Fptr != NULL) { - - // Move to the HDU - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - if (status != 0) - throw GException::fits_hdu_not_found(G_SAVE, - (m_fitsfile.HDUposition)+1, - status); - - // Save the column data - // TBD - - } // endif: FITS file was connected + // Save column + save_column(); // Return return; @@ -254,7 +241,7 @@ std::string GFitsTableLngCol::string(const int& row, const int& inx) throw GException::out_of_range(G_STRING, inx, 0, m_number-1); // Get index - int offset = row * m_repeat + inx; + int offset = row * m_number + inx; // Convert long into string ostringstream s_value; @@ -290,7 +277,7 @@ double GFitsTableLngCol::real(const int& row, const int& inx) throw GException::out_of_range(G_REAL, inx, 0, m_number-1); // Get index - int offset = row * m_repeat + inx; + int offset = row * m_number + inx; // Convert long into double double value = (double)m_data[offset]; @@ -325,7 +312,7 @@ int GFitsTableLngCol::integer(const int& row, const int& inx) throw GException::out_of_range(G_INTEGER, inx, 0, m_number-1); // Get index - int offset = row * m_repeat + inx; + int offset = row * m_number + inx; // Convert long into int int value = (int)m_data[offset]; @@ -402,8 +389,6 @@ void GFitsTableLngCol::init_members(void) { // Initialise members m_type = __TLONG; - m_size = 0; - m_anynul = 0; m_data = NULL; m_nulval = NULL; @@ -420,8 +405,6 @@ void GFitsTableLngCol::init_members(void) void GFitsTableLngCol::copy_members(const GFitsTableLngCol& column) { // Copy attributes - m_size = column.m_size; - m_anynul = column.m_anynul; // Copy column data if (column.m_data != NULL && m_size > 0) { @@ -461,53 +444,6 @@ void GFitsTableLngCol::free_members(void) /***********************************************************************//** - * @brief Fetch column data - * - * @exception GException::fits_error - * An error occured while loading column data from FITS file. - * - * If a FITS file is attached to the column the data are loaded into memory - * from the FITS file. If no FITS file is attached, memory is allocated - * to hold the column data and all cells are set to 0. - ***************************************************************************/ -void GFitsTableLngCol::fetch_data(void) -{ - // Calculate size of memory - m_size = m_number * m_length; - - // Load only if the column has a positive size - if (m_size > 0) { - - // Allocate fresh memory - if (m_data != NULL) delete [] m_data; - m_data = new long[m_size]; - - // If a FITS file is attached then load column data from the FITS - // file - if (m_fitsfile.Fptr != NULL) { - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - status = __ffgcv(&m_fitsfile, __TLONG, m_colnum, 1, 1, m_size, - m_nulval, m_data, &m_anynul, &status); - if (status != 0) - throw GException::fits_error(G_FETCH_DATA, status); - } - - // ... otherwise initialise all column values to 0 - else { - for (int i = 0; i < m_size; ++i) - m_data[i] = 0; - } - - } // endif: column has a positive size - - // Return - return; -} - - -/***********************************************************************//** * @brief Returns format string of ASCII table ***************************************************************************/ std::string GFitsTableLngCol::ascii_format(void) const @@ -545,12 +481,82 @@ std::string GFitsTableLngCol::binary_format(void) const } +/***********************************************************************//** + * @brief Allocates column data + ***************************************************************************/ +void GFitsTableLngCol::alloc_data(void) +{ + // Free any existing memory + if (m_data != NULL) delete [] m_data; + + // Mark pointer as free + m_data = NULL; + + // Allocate new data + if (m_size > 0) + m_data = new long[m_size]; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Initialise column data + ***************************************************************************/ +void GFitsTableLngCol::init_data(void) +{ + // Initialise data if they exist + if (m_data != NULL) { + for (int i = 0; i < m_size; ++i) + m_data[i] = 0; + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Fetch column data + * + * If a FITS file is attached to the column the data are loaded into memory + * from the FITS file. If no FITS file is attached, memory is allocated + * to hold the column data and all cells are set to 0. + * + * Refer to GFitsTableCol::load_column for more information. + ***************************************************************************/ +void GFitsTableLngCol::fetch_data(void) +{ + // Save column + load_column(); + + // Return + return; +} + + /*========================================================================== = = = GFitsTableLngCol friends = = = ==========================================================================*/ +/***********************************************************************//** + * @brief Output operator + * + * @param[in] os Output stream + * @param[in] column Column to put in output stream + ***************************************************************************/ +ostream& operator<< (ostream& os, const GFitsTableLngCol& column) +{ + // Dump column in output stream + column.dump_column(os, column.m_data); + + // Return output stream + return os; +} + /*========================================================================== = = diff --git a/src/fits/GFitsTableShtCol.cpp b/src/fits/GFitsTableShtCol.cpp index 9f10168..b2dcb51 100644 --- a/src/fits/GFitsTableShtCol.cpp +++ b/src/fits/GFitsTableShtCol.cpp @@ -21,16 +21,9 @@ /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ -#define G_SAVE "GFitsTableShtCol::save()" -#define G_STRING "GFitsTableShtCol::string(const int&, const int&)" -#define G_REAL "GFitsTableShtCol::real(const int&, const int&)" -#define G_INTEGER "GFitsTableShtCol::integer(const int&, const int&)" -#define G_PTR_FLOAT "GFitsTableShtCol::ptr_float()" -#define G_PTR_DOUBLE "GFitsTableShtCol::ptr_double()" -#define G_PTR_SHORT "GFitsTableShtCol::ptr_short()" -#define G_PTR_LONG "GFitsTableShtCol::ptr_long()" -#define G_PTR_INT "GFitsTableShtCol::ptr_int()" -#define G_LOAD "GFitsTableShtCol::load()" +#define G_STRING "GFitsTableShtCol::string(const int&, const int&)" +#define G_REAL "GFitsTableShtCol::real(const int&, const int&)" +#define G_INTEGER "GFitsTableShtCol::integer(const int&, const int&)" /* __ Macros _____________________________________________________________ */ @@ -45,9 +38,8 @@ = = ==========================================================================*/ -/*************************************************************************** - * Constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Constructor ***************************************************************************/ GFitsTableShtCol::GFitsTableShtCol() : GFitsTableCol() { @@ -79,9 +71,10 @@ GFitsTableShtCol::GFitsTableShtCol(const std::string& name, } -/*************************************************************************** - * Copy constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Copy constructor + * + * @param[in] column Column from which class instance should be built. ***************************************************************************/ GFitsTableShtCol::GFitsTableShtCol(const GFitsTableShtCol& column) : GFitsTableCol(column) { @@ -96,9 +89,8 @@ GFitsTableShtCol::GFitsTableShtCol(const GFitsTableShtCol& column) : GFitsTableC } -/*************************************************************************** - * Destructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Destructor ***************************************************************************/ GFitsTableShtCol::~GFitsTableShtCol() { @@ -116,9 +108,10 @@ GFitsTableShtCol::~GFitsTableShtCol() = = ==========================================================================*/ -/*************************************************************************** - * Assignment operator * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Assignment operator + * + * @param[in] column Column which should be assigned ***************************************************************************/ GFitsTableShtCol& GFitsTableShtCol::operator= (const GFitsTableShtCol& column) { @@ -144,6 +137,59 @@ GFitsTableShtCol& GFitsTableShtCol::operator= (const GFitsTableShtCol& column) } +/***********************************************************************//** + * @brief Column data access operator + * + * @param[in] row Row of column to access. + * @param[in] inx Vector index in column row to access + * + * Provides access to data in a column. No range checking is performed. + * Use one of + * GFitsTableShtCol::string(ix,iy), + * GFitsTableShtCol::real(ix;iy) or + * GFitsTableShtCol::integer(ix;iy) + * if range checking is required. + ***************************************************************************/ +short& GFitsTableShtCol::operator() (const int& row, const int& inx) +{ + // If data are not available then load them now + if (m_data == NULL) fetch_data(); + + // Calculate pixel offset + int offset = row * m_number + inx; + + // Return data bin + return m_data[offset]; +} + + +/***********************************************************************//** + * @brief Column data access operator (const variant) + * + * @param[in] row Row of column to access. + * @param[in] inx Vector index in column row to access + * + * Provides access to data in a column. No range checking is performed. + * Use one of + * GFitsTableDblCol::string(ix,iy), + * GFitsTableShtCol::real(ix;iy) or + * GFitsTableShtCol::integer(ix;iy) + * if range checking is required. + ***************************************************************************/ +const short& GFitsTableShtCol::operator() (const int& row, const int& inx) + const +{ + // If data are not available then load them now + if (m_data == NULL) ((GFitsTableShtCol*)this)->fetch_data(); + + // Calculate pixel offset + int offset = row * m_number + inx; + + // Return data bin + return m_data[offset]; +} + + /*========================================================================== = = = GFitsTableShtCol public methods = @@ -153,149 +199,153 @@ GFitsTableShtCol& GFitsTableShtCol::operator= (const GFitsTableShtCol& column) /***********************************************************************//** * @brief Save table column into FITS file * - * @exception GException::fits_hdu_not_found - * Specified HDU not found in FITS file. + * The table column is only saved if it is linked to a FITS file and if the + * data are indeed present in the class instance. This avoids saving of data + * that have not been modified. + * + * Refer to GFitsTableCol::save_column() for more information. ***************************************************************************/ void GFitsTableShtCol::save(void) { - // Continue only if a FITS file is connected - if (m_fitsfile.Fptr != NULL) { - - // Move to the HDU - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - if (status != 0) - throw GException::fits_hdu_not_found(G_SAVE, - (m_fitsfile.HDUposition)+1, - status); - - // Save the column data - // TBD - - } // endif: FITS file was connected + // Save column + save_column(); // Return return; } -/*************************************************************************** - * Get string value * - * ----------------------------------------------------------------------- * + +/***********************************************************************//** + * @brief Get string value + * + * @param[in] row Table row. + * @param[in] inx Table column vector index. + * + * @exception GException::out_of_range + * Table row or vector index are out of valid range. + * + * Returns value of specified row and vector index as string. ***************************************************************************/ -std::string GFitsTableShtCol::string(const int& row, const int& col) +std::string GFitsTableShtCol::string(const int& row, const int& inx) { - // Make sure that data are loaded - if (m_data == NULL) - load(); + // If data are not available then load them now + if (m_data == NULL) fetch_data(); // Check row value if (row < 0 || row >= m_length) throw GException::out_of_range(G_STRING, row, 0, m_length-1); - // Check col value - if (col < 0 || col >= m_number) - throw GException::out_of_range(G_STRING, col, 0, m_number-1); + // Check inx value + if (inx < 0 || inx >= m_number) + throw GException::out_of_range(G_STRING, inx, 0, m_number-1); // Get index - int inx = row * m_repeat + col; + int offset = row * m_number + inx; - // Convert short into string + // Convert double into string ostringstream s_value; - s_value << m_data[inx]; + s_value << m_data[offset]; // Return value return s_value.str(); } -/*************************************************************************** - * Get real value * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get double precision value + * + * @param[in] row Table row. + * @param[in] inx Table column vector index. + * + * @exception GException::out_of_range + * Table row or vector index are out of valid range. + * + * Returns value of specified row and vector index as double precision. ***************************************************************************/ -double GFitsTableShtCol::real(const int& row, const int& col) +double GFitsTableShtCol::real(const int& row, const int& inx) { - // Make sure that data are loaded - if (m_data == NULL) - load(); + // If data are not available then load them now + if (m_data == NULL) fetch_data(); // Check row value if (row < 0 || row >= m_length) throw GException::out_of_range(G_REAL, row, 0, m_length-1); - // Check col value - if (col < 0 || col >= m_number) - throw GException::out_of_range(G_REAL, col, 0, m_number-1); + // Check inx value + if (inx < 0 || inx >= m_number) + throw GException::out_of_range(G_REAL, inx, 0, m_number-1); // Get index - int inx = row * m_repeat + col; + int offset = row * m_number + inx; // Convert short into double - double value = (double)m_data[inx]; + double value = (double)m_data[offset]; // Return value return value; } -/*************************************************************************** - * Get int value * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get integer value + * + * @param[in] row Table row. + * @param[in] inx Table column vector index. + * + * @exception GException::out_of_range + * Table row or vector index are out of valid range. + * + * Returns value of specified row and vector index as integer. ***************************************************************************/ -int GFitsTableShtCol::integer(const int& row, const int& col) +int GFitsTableShtCol::integer(const int& row, const int& inx) { - // Make sure that data are loaded - if (m_data == NULL) - load(); + // If data are not available then load them now + if (m_data == NULL) fetch_data(); // Check row value if (row < 0 || row >= m_length) throw GException::out_of_range(G_INTEGER, row, 0, m_length-1); // Check col value - if (col < 0 || col >= m_number) - throw GException::out_of_range(G_INTEGER, col, 0, m_number-1); + if (inx < 0 || inx >= m_number) + throw GException::out_of_range(G_INTEGER, inx, 0, m_number-1); // Get index - int inx = row * m_repeat + col; + int offset = row * m_number + inx; // Convert short into int - int value = (int)m_data[inx]; + int value = (int)m_data[offset]; // Return value return value; } -/*************************************************************************** - * Access to invalid data pointers * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Clone column ***************************************************************************/ -float* GFitsTableShtCol::ptr_float(void) +GFitsTableShtCol* GFitsTableShtCol::clone(void) const { - throw GException::fits_invalid_type(G_PTR_FLOAT, - "No pointer allowed to array"); + return new GFitsTableShtCol(*this); } -double* GFitsTableShtCol::ptr_double(void) -{ - throw GException::fits_invalid_type(G_PTR_DOUBLE, - "No pointer allowed to array"); -} -long* GFitsTableShtCol::ptr_long(void) -{ - throw GException::fits_invalid_type(G_PTR_LONG, - "No pointer allowed to array"); -} -int* GFitsTableShtCol::ptr_int(void) + + +/***********************************************************************//** + * @brief Return pointer to short integer column + ***************************************************************************/ +short* GFitsTableShtCol::data(void) { - throw GException::fits_invalid_type(G_PTR_INT, - "No pointer allowed to array"); + return m_data; } -/*************************************************************************** - * Set NULL string * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Set NULL value + * + * @param[in] value Pointer on NULL value + * + * Allows the specification of the FITS table NULL value. If value=NULL the + * data will not be screened for NULL values. ***************************************************************************/ void GFitsTableShtCol::set_nullval(const short* value) { @@ -312,13 +362,13 @@ void GFitsTableShtCol::set_nullval(const short* value) *m_nulval = *value; } - // Re-load column - // NOTE: THIS WILL LEAD TO A LOSS OF MODIFICATIONS; ISSUE SAVE BEFORE !!! + // Re-load column +/* if (m_data != NULL) { - //save(); + save(); load(); } - +*/ // Return return; } @@ -330,16 +380,13 @@ void GFitsTableShtCol::set_nullval(const short* value) = = ==========================================================================*/ -/*************************************************************************** - * Initialise class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Initialise class members ***************************************************************************/ void GFitsTableShtCol::init_members(void) { // Initialise members m_type = __TSHORT; - m_size = 0; - m_anynul = 0; m_data = NULL; m_nulval = NULL; @@ -348,15 +395,14 @@ void GFitsTableShtCol::init_members(void) } -/*************************************************************************** - * Copy class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Copy class members + * + * @param[in] column Column for which members should be copied. ***************************************************************************/ void GFitsTableShtCol::copy_members(const GFitsTableShtCol& column) { // Copy attributes - m_size = column.m_size; - m_anynul = column.m_anynul; // Copy column data if (column.m_data != NULL && m_size > 0) { @@ -377,9 +423,8 @@ void GFitsTableShtCol::copy_members(const GFitsTableShtCol& column) } -/*************************************************************************** - * Delete class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Delete class members ***************************************************************************/ void GFitsTableShtCol::free_members(void) { @@ -396,32 +441,6 @@ void GFitsTableShtCol::free_members(void) } -/*************************************************************************** - * Load column data * - * ----------------------------------------------------------------------- * - ***************************************************************************/ -void GFitsTableShtCol::load(void) -{ - // Calculate size of memory - m_size = m_number * m_length; - - // Allocate memory - if (m_data != NULL) delete [] m_data; - m_data = new short[m_size]; - - // Load column data - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status); - status = __ffgcv(&m_fitsfile, __TSHORT, m_colnum, 1, 1, m_size, - m_nulval, m_data, &m_anynul, &status); - if (status != 0) - throw GException::fits_error(G_LOAD, status); - - // Return - return; -} - - /***********************************************************************//** * @brief Returns format string of ASCII table ***************************************************************************/ @@ -460,12 +479,82 @@ std::string GFitsTableShtCol::binary_format(void) const } +/***********************************************************************//** + * @brief Allocates column data + ***************************************************************************/ +void GFitsTableShtCol::alloc_data(void) +{ + // Free any existing memory + if (m_data != NULL) delete [] m_data; + + // Mark pointer as free + m_data = NULL; + + // Allocate new data + if (m_size > 0) + m_data = new short[m_size]; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Initialise column data + ***************************************************************************/ +void GFitsTableShtCol::init_data(void) +{ + // Initialise data if they exist + if (m_data != NULL) { + for (int i = 0; i < m_size; ++i) + m_data[i] = 0; + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Fetch column data + * + * If a FITS file is attached to the column the data are loaded into memory + * from the FITS file. If no FITS file is attached, memory is allocated + * to hold the column data and all cells are set to 0. + * + * Refer to GFitsTableCol::load_column for more information. + ***************************************************************************/ +void GFitsTableShtCol::fetch_data(void) +{ + // Save column + load_column(); + + // Return + return; +} + + /*========================================================================== = = = GFitsTableShtCol friends = = = ==========================================================================*/ +/***********************************************************************//** + * @brief Output operator + * + * @param[in] os Output stream + * @param[in] column Column to put in output stream + ***************************************************************************/ +ostream& operator<< (ostream& os, const GFitsTableShtCol& column) +{ + // Dump column in output stream + column.dump_column(os, column.m_data); + + // Return output stream + return os; +} + /*========================================================================== = = diff --git a/src/fits/GFitsTableStrCol.cpp b/src/fits/GFitsTableStrCol.cpp index 3d3787c..c5e8fca 100644 --- a/src/fits/GFitsTableStrCol.cpp +++ b/src/fits/GFitsTableStrCol.cpp @@ -21,17 +21,9 @@ /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ -#define G_SAVE "GFitsTableStrCol::save()" -#define G_STRING "GFitsTableStrCol::string(const int&, const int&)" -#define G_REAL "GFitsTableStrCol::real(const int&, const int&)" -#define G_INTEGER "GFitsTableStrCol::integer(const int&, const int&)" -#define G_PTR_STRING "GFitsTableStrCol::ptr_string()" -#define G_PTR_FLOAT "GFitsTableStrCol::ptr_float()" -#define G_PTR_DOUBLE "GFitsTableStrCol::ptr_double()" -#define G_PTR_SHORT "GFitsTableStrCol::ptr_short()" -#define G_PTR_LONG "GFitsTableStrCol::ptr_long()" -#define G_PTR_INT "GFitsTableStrCol::ptr_int()" -#define G_LOAD "GFitsTableStrCol::load()" +#define G_STRING "GFitsTableStrCol::string(const int&, const int&)" +#define G_REAL "GFitsTableStrCol::real(const int&, const int&)" +#define G_INTEGER "GFitsTableStrCol::integer(const int&, const int&)" /* __ Macros _____________________________________________________________ */ @@ -46,9 +38,8 @@ = = ==========================================================================*/ -/*************************************************************************** - * Constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Constructor ***************************************************************************/ GFitsTableStrCol::GFitsTableStrCol() : GFitsTableCol() { @@ -60,11 +51,35 @@ GFitsTableStrCol::GFitsTableStrCol() : GFitsTableCol() } -/*************************************************************************** - * Copy constructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Constructor + * + * @param[in] name Name of column. + * @param[in] length Length of column. + * @param[in] width Length of individual string. + * @param[in] size Number of strings in each column. ***************************************************************************/ -GFitsTableStrCol::GFitsTableStrCol(const GFitsTableStrCol& column) : GFitsTableCol(column) +GFitsTableStrCol::GFitsTableStrCol(const std::string& name, + const int& length, + const int& width, + const int& size) + : GFitsTableCol(name, length, size, width) +{ + // Initialise class members for clean destruction + init_members(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Copy constructor + * + * @param[in] column Column from which class instance should be built. + ***************************************************************************/ +GFitsTableStrCol::GFitsTableStrCol(const GFitsTableStrCol& column) + : GFitsTableCol(column) { // Initialise class members for clean destruction init_members(); @@ -77,9 +92,8 @@ GFitsTableStrCol::GFitsTableStrCol(const GFitsTableStrCol& column) : GFitsTableC } -/*************************************************************************** - * Destructor * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Destructor ***************************************************************************/ GFitsTableStrCol::~GFitsTableStrCol() { @@ -97,9 +111,10 @@ GFitsTableStrCol::~GFitsTableStrCol() = = ==========================================================================*/ -/*************************************************************************** - * Assignment operator * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Assignment operator + * + * @param[in] column Column which should be assigned ***************************************************************************/ GFitsTableStrCol& GFitsTableStrCol::operator= (const GFitsTableStrCol& column) { @@ -125,6 +140,59 @@ GFitsTableStrCol& GFitsTableStrCol::operator= (const GFitsTableStrCol& column) } +/***********************************************************************//** + * @brief Column data access operator + * + * @param[in] row Row of column to access. + * @param[in] inx Vector index in column row to access + * + * Provides access to data in a column. No range checking is performed. + * Use one of + * GFitsTableStrCol::string(ix,iy), + * GFitsTableStrCol::real(ix;iy) or + * GFitsTableStrCol::integer(ix;iy) + * if range checking is required. + ***************************************************************************/ +std::string& GFitsTableStrCol::operator() (const int& row, const int& inx) +{ + // If data are not available then load them now + if (m_data == NULL) fetch_data(); + + // Calculate pixel offset + int offset = row * m_number + inx; + + // Return data bin + return m_data[offset]; +} + + +/***********************************************************************//** + * @brief Column data access operator (const variant) + * + * @param[in] row Row of column to access. + * @param[in] inx Vector index in column row to access + * + * Provides access to data in a column. No range checking is performed. + * Use one of + * GFitsTableStrCol::string(ix,iy), + * GFitsTableStrCol::real(ix;iy) or + * GFitsTableStrCol::integer(ix;iy) + * if range checking is required. + ***************************************************************************/ +const std::string& GFitsTableStrCol::operator() (const int& row, const int& inx) + const +{ + // If data are not available then load them now + if (m_data == NULL) ((GFitsTableStrCol*)this)->fetch_data(); + + // Calculate pixel offset + int offset = row * m_number + inx; + + // Return data bin + return m_data[offset]; +} + + /*========================================================================== = = = GFitsTableStrCol public methods = @@ -134,171 +202,186 @@ GFitsTableStrCol& GFitsTableStrCol::operator= (const GFitsTableStrCol& column) /***********************************************************************//** * @brief Save table column into FITS file * - * @exception GException::fits_hdu_not_found - * Specified HDU not found in FITS file. + * The table column is only saved if it is linked to a FITS file and if the + * data are indeed present in the class instance. This avoids saving of data + * that have not been modified. + * + * Refer to GFitsTableCol::save_column() for more information. ***************************************************************************/ void GFitsTableStrCol::save(void) { - // Continue only if a FITS file is connected - if (m_fitsfile.Fptr != NULL) { + // Free buffer + free_buffer(); - // Move to the HDU - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - if (status != 0) - throw GException::fits_hdu_not_found(G_SAVE, - (m_fitsfile.HDUposition)+1, - status); + // Allocate buffer + alloc_buffer(); - // Save the column data - // TBD + // Transfer string into buffer + for (int i = 0; i < m_size; ++i) + strncpy(m_buffer[i], m_data[i].c_str(), m_width); - } // endif: FITS file was connected + // Save column + save_column(); + + // Free buffer + free_buffer(); // Return return; } -/*************************************************************************** - * Get string value * - * ----------------------------------------------------------------------- * + +/***********************************************************************//** + * @brief Get string value + * + * @param[in] row Table row. + * @param[in] inx Table column vector index. + * + * @exception GException::out_of_range + * Table row or vector index are out of valid range. + * + * Returns value of specified row and vector index as string. ***************************************************************************/ -std::string GFitsTableStrCol::string(const int& row, const int& col) +std::string GFitsTableStrCol::string(const int& row, const int& inx) { - // Make sure that data are loaded - if (m_data == NULL) - load(); + // If data are not available then load them now + if (m_data == NULL) fetch_data(); // Check row value if (row < 0 || row >= m_length) throw GException::out_of_range(G_STRING, row, 0, m_length-1); - // Check col value - if (col < 0 || col >= m_number) - throw GException::out_of_range(G_STRING, col, 0, m_number-1); + // Check inx value + if (inx < 0 || inx >= m_number) + throw GException::out_of_range(G_STRING, inx, 0, m_number-1); - // Get string index - int inx = row * m_repeat + col; - - // Assign C string to C++ std::string - std::string value; - value.assign(m_data[inx]); + // Get index + int offset = row * m_number + inx; // Return value - return value; + return m_data[offset]; } -/*************************************************************************** - * Get real value * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get double precision value + * + * @param[in] row Table row. + * @param[in] inx Table column vector index. + * + * @exception GException::out_of_range + * Table row or vector index are out of valid range. + * + * Returns value of specified row and vector index as double precision. ***************************************************************************/ -double GFitsTableStrCol::real(const int& row, const int& col) +double GFitsTableStrCol::real(const int& row, const int& inx) { - // Make sure that data are loaded - if (m_data == NULL) - load(); + // If data are not available then load them now + if (m_data == NULL) fetch_data(); // Check row value if (row < 0 || row >= m_length) - throw GException::out_of_range(G_STRING, row, 0, m_length-1); + throw GException::out_of_range(G_REAL, row, 0, m_length-1); - // Check col value - if (col < 0 || col >= m_number) - throw GException::out_of_range(G_STRING, col, 0, m_number-1); + // Check inx value + if (inx < 0 || inx >= m_number) + throw GException::out_of_range(G_REAL, inx, 0, m_number-1); - // Get string index - int inx = row * m_repeat + col; + // Get index + int offset = row * m_number + inx; // Assign C string to double - double value = atof(m_data[inx]); + double value = atof(m_data[offset].c_str()); // Return value return value; } -/*************************************************************************** - * Get int value * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Get integer value + * + * @param[in] row Table row. + * @param[in] inx Table column vector index. + * + * @exception GException::out_of_range + * Table row or vector index are out of valid range. + * + * Returns value of specified row and vector index as integer. ***************************************************************************/ -int GFitsTableStrCol::integer(const int& row, const int& col) +int GFitsTableStrCol::integer(const int& row, const int& inx) { - // Make sure that data are loaded - if (m_data == NULL) - load(); + // If data are not available then load them now + if (m_data == NULL) fetch_data(); // Check row value if (row < 0 || row >= m_length) - throw GException::out_of_range(G_STRING, row, 0, m_length-1); + throw GException::out_of_range(G_INTEGER, row, 0, m_length-1); // Check col value - if (col < 0 || col >= m_number) - throw GException::out_of_range(G_STRING, col, 0, m_number-1); + if (inx < 0 || inx >= m_number) + throw GException::out_of_range(G_INTEGER, inx, 0, m_number-1); - // Get string index - int inx = row * m_repeat + col; + // Get index + int offset = row * m_number + inx; // Assign C string to int - int value = atoi(m_data[inx]); + int value = atoi(m_data[offset].c_str()); // Return value return value; } -/*************************************************************************** - * Access to invalid data pointers * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Clone column ***************************************************************************/ -float* GFitsTableStrCol::ptr_float(void) +GFitsTableStrCol* GFitsTableStrCol::clone(void) const { - throw GException::fits_invalid_type(G_PTR_FLOAT, "No pointer allowed to array"); + return new GFitsTableStrCol(*this); } -double* GFitsTableStrCol::ptr_double(void) -{ - throw GException::fits_invalid_type(G_PTR_FLOAT, "No pointer allowed to array"); -} -short* GFitsTableStrCol::ptr_short(void) -{ - throw GException::fits_invalid_type(G_PTR_SHORT, "No pointer allowed to array"); -} -long* GFitsTableStrCol::ptr_long(void) -{ - throw GException::fits_invalid_type(G_PTR_LONG, "No pointer allowed to array"); -} -int* GFitsTableStrCol::ptr_int(void) + + +/***********************************************************************//** + * @brief Return pointer to std::string column + ***************************************************************************/ +std::string* GFitsTableStrCol::data(void) { - throw GException::fits_invalid_type(G_PTR_INT, "No pointer allowed to array"); + return m_data; } -/*************************************************************************** - * Set NULL string * - * ----------------------------------------------------------------------- * + +/***********************************************************************//** + * @brief Set NULL string + * + * @param[in] value Pointer on NULL string + * + * Allows the specification of the FITS table NULL string. If the string + * is empty the data will not be screened for NULL values. ***************************************************************************/ -void GFitsTableStrCol::set_nullstr(const std::string string) +void GFitsTableStrCol::set_nullval(const std::string string) { // If NULL string is empty then reset the NULL string if (string.empty()) { - if (m_nulstr != NULL) delete [] m_nulstr; - m_nulstr = NULL; + if (m_nulval != NULL) delete [] m_nulval; + m_nulval = NULL; } // ... otherwise copy string into NULL string else { - if (m_nulstr != NULL) delete [] m_nulstr; - m_nulstr = new char[m_width+1]; - strncpy(m_nulstr, string.c_str(), m_width); + if (m_nulval != NULL) delete [] m_nulval; + m_nulval = new char[m_width+1]; + strncpy(m_nulval, string.c_str(), m_width); } - // Re-load column - // NOTE: THIS WILL LEAD TO A LOSS OF MODIFICATIONS; ISSUE SAVE BEFORE !!! + // Re-load column +/* if (m_data != NULL) { - //save(); + save(); load(); } +*/ // Return return; @@ -311,53 +394,40 @@ void GFitsTableStrCol::set_nullstr(const std::string string) = = ==========================================================================*/ -/*************************************************************************** - * Initialise class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Initialise class members ***************************************************************************/ void GFitsTableStrCol::init_members(void) { // Initialise members m_type = __TSTRING; - m_size = 0; - m_data = NULL; - m_nulstr = NULL; - m_anynul = 0; + m_data = NULL; + m_buffer = NULL; + m_nulval = NULL; // Return return; } -/*************************************************************************** - * Copy class members * - * ----------------------------------------------------------------------- * - * Note: it is assumed that no memory has been allocated so far for the * - * actual instance. * +/***********************************************************************//** + * @brief Copy class members + * + * @param[in] column Column for which members should be copied. ***************************************************************************/ void GFitsTableStrCol::copy_members(const GFitsTableStrCol& column) { - // Copy string size - m_size = column.m_size; - m_anynul = column.m_anynul; - // Copy column data if (column.m_data != NULL && m_size > 0) { - m_data = new char*[m_size]; - for (int i = 0; i < m_size; ++i) { - if (column.m_data[i] != NULL) { - m_data[i] = new char[m_width+1]; - memcpy(m_data[i], column.m_data[i], m_width); - } - else - m_data[i] = NULL; - } + m_data = new std::string[m_size]; + for (int i = 0; i < m_size; ++i) + m_data[i] = column.m_data[i]; } - // Copy nulstr data - if (column.m_nulstr != NULL) { - m_nulstr = new char[m_width+1]; - strncpy(m_nulstr, column.m_nulstr, m_width); + // Copy nulval data + if (column.m_nulval != NULL) { + m_nulval = new char[m_width+1]; + strncpy(m_nulval, column.m_nulval, m_width); } // Return @@ -365,65 +435,21 @@ void GFitsTableStrCol::copy_members(const GFitsTableStrCol& column) } -/*************************************************************************** - * Delete class members * - * ----------------------------------------------------------------------- * +/***********************************************************************//** + * @brief Delete class members ***************************************************************************/ void GFitsTableStrCol::free_members(void) { // Free memory - if (m_data != NULL) { - for (int i = 0; i < m_size; ++i) { - if (m_data[i] != NULL) delete [] m_data[i]; - } - delete [] m_data; - } + if (m_data != NULL) delete [] m_data; + if (m_nulval != NULL) delete m_nulval; // Mark memory as freed - m_data = NULL; - - // Return - return; -} - - -/*************************************************************************** - * Load column data * - * ----------------------------------------------------------------------- * - * The string column is read in a list of character buffers. The length of * - * each character buffer is 'm_width+1' to hold the final '\0'. The number * - * of strings is given by the number of rows of the table times the number * - * of substrings. * - ***************************************************************************/ -void GFitsTableStrCol::load(void) -{ - // Calculate total number of strings - m_size = m_number * m_length; - - // Free memory - free_members(); - - // Reset number of NULLs - m_anynul = 0; - - // Load data only if some are available - if (m_size > 0) { - - // Allocate memory - m_data = new char*[m_size]; - for (int i = 0; i < m_size; ++i) - m_data[i] = new char[m_width+1]; + m_data = NULL; + m_nulval = NULL; - // Load column data - int status = 0; - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, - &status); - status = __ffgcvs(&m_fitsfile, m_colnum, 1, 1, m_size, m_nulstr, m_data, - &m_anynul, &status); - if (status != 0) - throw GException::fits_error(G_LOAD, status); - - } // endif: data were available + // Free buffer + free_buffer(); // Return return; @@ -472,12 +498,144 @@ std::string GFitsTableStrCol::binary_format(void) const } +/***********************************************************************//** + * @brief Allocates column data + ***************************************************************************/ +void GFitsTableStrCol::alloc_data(void) +{ + // Free memory + if (m_data != NULL) delete [] m_data; + + // Mark pointer as free + m_data = NULL; + + // Allocate new data + if (m_size > 0) + m_data = new std::string[m_size]; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Initialise column data + ***************************************************************************/ +void GFitsTableStrCol::init_data(void) +{ + // Initialise data if they exist + if (m_data != NULL) { + for (int i = 0; i < m_size; ++i) + m_data[i].clear(); + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Fetch column data + * + * If a FITS file is attached to the column the data are loaded into memory + * from the FITS file. If no FITS file is attached, memory is allocated + * to hold the column data and all cells are set to 0. + * + * Refer to GFitsTableCol::load_column for more information. + ***************************************************************************/ +void GFitsTableStrCol::fetch_data(void) +{ + // Calculate size of memory + m_size = m_number * m_length; + + // Free old buffer memory + free_buffer(); + + // Allocate buffer memory + alloc_buffer(); + + // Save column + load_column(); + + // Extract string from buffer + for (int i = 0; i < m_size; ++i) { + if (m_buffer[i] != NULL) + m_data[i].assign(m_buffer[i]); + } + + // Free buffer memory + free_buffer(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Allocate buffer memory + ***************************************************************************/ +void GFitsTableStrCol::alloc_buffer(void) +{ + // Allocate buffer memory + if (m_size > 0) { + m_buffer = new char*[m_size]; + for (int i = 0; i < m_size; ++i) + m_buffer[i] = new char[m_width+1]; + } + + // Initialise buffer + if (m_buffer != NULL) { + for (int i = 0; i < m_size; ++i) { + for (int j = 0; j <= m_width; ++j) + (m_buffer[i])[j] = '\0'; + } + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Free buffer memory + ***************************************************************************/ +void GFitsTableStrCol::free_buffer(void) +{ + // If there was a buffer allocated then free it + if (m_buffer != NULL) { + for (int i = 0; i < m_size; ++i) { + if (m_buffer[i] != NULL) delete [] m_buffer[i]; + } + delete [] m_buffer; + m_buffer = NULL; + } + + // Return + return; +} + + /*========================================================================== = = = GFitsTableStrCol friends = = = ==========================================================================*/ +/***********************************************************************//** + * @brief Output operator + * + * @param[in] os Output stream + * @param[in] column Column to put in output stream + ***************************************************************************/ +ostream& operator<< (ostream& os, const GFitsTableStrCol& column) +{ + // Dump column in output stream + column.dump_column(os, column.m_data); + + // Return output stream + return os; +} + /*========================================================================== = = diff --git a/test/test_GFits.cpp b/test/test_GFits.cpp index 0049f21..2febaeb 100644 --- a/test/test_GFits.cpp +++ b/test/test_GFits.cpp @@ -82,8 +82,8 @@ void test_columns(void) } else std::cout << "."; - std::string nullstr = "empty"; - str.set_nullstr(nullstr); + std::string nullval = "empty"; + str.set_nullval(nullval); if (str.string(2) != "empty") { cout << endl << "TEST ERROR: Bad single TSTRING NULL value read (" << str.string(2) << ")." << endl; @@ -508,13 +508,31 @@ void test_bin_table(void) system("rm -rf test_bintables.fits"); // Allocate reference sums - double sum_dbl = 0.0; - int sum_dbl_int = 0; + double sum_dbl = 0.0; + double sum_dbl10 = 0.0; + int sum_dbl_int = 0; + int sum_dbl10_int = 0; std::string sum_dbl_str; - float sum_flt = 0.0; - int sum_flt_int = 0; + std::string sum_dbl10_str; + float sum_flt = 0.0; + float sum_flt10 = 0.0; + int sum_flt_int = 0; + int sum_flt10_int = 0; std::string sum_flt_str; - + std::string sum_flt10_str; + short sum_sht = 0; + short sum_sht10 = 0; + short sum_sht_int = 0; + short sum_sht10_int = 0; + std::string sum_sht_str; + std::string sum_sht10_str; + long sum_lng = 0; + long sum_lng10 = 0; + long sum_lng_int = 0; + long sum_lng10_int = 0; + std::string sum_lng_str; + std::string sum_lng10_str; + // Build tables try { // Open FITS file @@ -523,17 +541,20 @@ void test_bin_table(void) // Set number of rows int nrows = 10; + int nvec = 10; // Initial control sums float tot_flt = 0.0; double tot_dbl = 0.0; int tot_int = 0; + long tot_lng = 0; + short tot_sht = 0; std::string tot_str; // // ===== D O U B L E ===== // - + // Set double precision table GFitsTableDblCol col_dbl = GFitsTableDblCol("DOUBLE", nrows); for (int i = 0; i < nrows; ++i) { @@ -546,14 +567,15 @@ void test_bin_table(void) sum_dbl_str += ":"+s_value.str(); } cout << "."; - + // Check double precision table (operator access) tot_dbl = 0.0; for (int i = 0; i < nrows; ++i) tot_dbl += col_dbl(i); if (!dequal(tot_dbl, sum_dbl)) { - cout << endl << "TEST ERROR: GFitsTableDblCol::operator()" - << endl; + cout << endl << "TEST ERROR: GFitsTableDblCol::operator()"; + cout << endl << " Reference sum: " << sum_dbl; + cout << endl << " Derived sum: " << tot_dbl << endl; throw; } cout << "."; @@ -563,19 +585,21 @@ void test_bin_table(void) for (int i = 0; i < nrows; ++i) tot_dbl += col_dbl.real(i); if (!dequal(tot_dbl, sum_dbl)) { - cout << endl << "TEST ERROR: GFitsTableDblCol::real()" - << endl; + cout << endl << "TEST ERROR: GFitsTableDblCol::real()"; + cout << endl << " Reference sum: " << sum_dbl; + cout << endl << " Derived sum: " << tot_dbl << endl; throw; } cout << "."; // Check double precision table (int access) - tot_int = 0.0; + tot_int = 0; for (int i = 0; i < nrows; ++i) tot_int += col_dbl.integer(i); if (tot_int != sum_dbl_int) { - cout << endl << "TEST ERROR: GFitsTableDblCol::integer()" - << endl; + cout << endl << "TEST ERROR: GFitsTableDblCol::integer()"; + cout << endl << " Reference sum: " << sum_dbl_int; + cout << endl << " Derived sum: " << tot_int << endl; throw; } cout << "."; @@ -585,8 +609,84 @@ void test_bin_table(void) for (int i = 0; i < nrows; ++i) tot_str += ":"+col_dbl.string(i); if (tot_str != sum_dbl_str) { - cout << endl << "TEST ERROR: GFitsTableDblCol::string()" - << endl; + cout << endl << "TEST ERROR: GFitsTableDblCol::string()"; + cout << endl << " Reference sum: " << sum_dbl_str; + cout << endl << " Derived sum: " << tot_str << endl; + throw; + } + cout << "."; + + // + // ===== D O U B L E 1 0 ===== + // + + // Set double precision table + GFitsTableDblCol col_dbl10 = GFitsTableDblCol("DOUBLE10", nrows, nvec); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) { + double val_dbl = cos(double(i))*cos(0.33*double(j)); + col_dbl10(i,j) = val_dbl; + sum_dbl10 += val_dbl; + sum_dbl10_int += int(val_dbl); + ostringstream s_value; + s_value << scientific << val_dbl; + sum_dbl10_str += ":"+s_value.str(); + } + } + cout << "."; + + // Check double precision table (operator access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_dbl += col_dbl10(i,j); + } + if (!dequal(tot_dbl, sum_dbl10)) { + cout << endl << "TEST ERROR: GFitsTableDblCol::operator() - 10"; + cout << endl << " Reference sum: " << sum_dbl10; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check double precision table (real access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_dbl += col_dbl10.real(i,j); + } + if (!dequal(tot_dbl, sum_dbl10)) { + cout << endl << "TEST ERROR: GFitsTableDblCol::real() - 10"; + cout << endl << " Reference sum: " << sum_dbl10; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check double precision table (int access) + tot_int = 0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_int += col_dbl10.integer(i,j); + } + if (tot_int != sum_dbl10_int) { + cout << endl << "TEST ERROR: GFitsTableDblCol::integer() - 10"; + cout << endl << " Reference sum: " << sum_dbl10_int; + cout << endl << " Derived sum: " << tot_int << endl; + throw; + } + cout << "."; + + // Check double precision table (string access) + tot_str.clear(); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_str += ":"+col_dbl10.string(i,j); + } + if (tot_str != sum_dbl10_str) { + cout << endl << "TEST ERROR: GFitsTableDblCol::string() - 10"; + cout << endl << " Reference sum: " << sum_dbl10_str; + cout << endl << " Derived sum: " << tot_str << endl; throw; } cout << "."; @@ -613,8 +713,9 @@ void test_bin_table(void) for (int i = 0; i < nrows; ++i) tot_flt += col_flt(i); if (!fequal(tot_flt, sum_flt)) { - cout << endl << "TEST ERROR: GFitsTableFltCol::operator()" - << endl; + cout << endl << "TEST ERROR: GFitsTableFltCol::operator()"; + cout << endl << " Reference sum: " << sum_flt; + cout << endl << " Derived sum: " << tot_flt << endl; throw; } cout << "."; @@ -624,19 +725,21 @@ void test_bin_table(void) for (int i = 0; i < nrows; ++i) tot_flt += col_flt.real(i); if (!fequal(tot_flt, sum_flt)) { - cout << endl << "TEST ERROR: GFitsTableFltCol::real()" - << endl; + cout << endl << "TEST ERROR: GFitsTableFltCol::real()"; + cout << endl << " Reference sum: " << sum_flt; + cout << endl << " Derived sum: " << tot_flt << endl; throw; } cout << "."; // Check single precision table (int access) - tot_int = 0.0; + tot_int = 0; for (int i = 0; i < nrows; ++i) tot_int += col_flt.integer(i); if (tot_int != sum_flt_int) { - cout << endl << "TEST ERROR: GFitsTableFltCol::integer()" - << endl; + cout << endl << "TEST ERROR: GFitsTableFltCol::integer()"; + cout << endl << " Reference sum: " << sum_flt_int; + cout << endl << " Derived sum: " << tot_int << endl; throw; } cout << "."; @@ -646,27 +749,493 @@ void test_bin_table(void) for (int i = 0; i < nrows; ++i) tot_str += ":"+col_flt.string(i); if (tot_str != sum_flt_str) { - cout << endl << "TEST ERROR: GFitsTableFltCol::string()" - << endl; + cout << endl << "TEST ERROR: GFitsTableFltCol::string()"; + cout << endl << " Reference sum: " << sum_flt_str; + cout << endl << " Derived sum: " << tot_str << endl; throw; } cout << "."; // + // ===== F L O A T 1 0 ===== + // + + // Set single precision table + GFitsTableFltCol col_flt10 = GFitsTableFltCol("FLOAT10", nrows, nvec); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) { + float val_flt = cos(0.1*float(i))*cos(0.33*float(j)); + col_flt10(i,j) = val_flt; + sum_flt10 += val_flt; + sum_flt10_int += int(val_flt); + ostringstream s_value; + s_value << scientific << val_flt; + sum_flt10_str += ":"+s_value.str(); + } + } + cout << "."; + + // Check single precision table (operator access) + tot_flt = 0.0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_flt += col_flt10(i,j); + } + if (!fequal(tot_flt, sum_flt10)) { + cout << endl << "TEST ERROR: GFitsTableFltCol::operator() - 10"; + cout << endl << " Reference sum: " << sum_flt10; + cout << endl << " Derived sum: " << tot_flt << endl; + throw; + } + cout << "."; + + // Check single precision table (real access) + tot_flt = 0.0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_flt += col_flt10.real(i,j); + } + if (!fequal(tot_flt, sum_flt10)) { + cout << endl << "TEST ERROR: GFitsTableFltCol::real() - 10"; + cout << endl << " Reference sum: " << sum_flt10; + cout << endl << " Derived sum: " << tot_flt << endl; + throw; + } + cout << "."; + + // Check double precision table (int access) + tot_int = 0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_int += col_flt10.integer(i,j); + } + if (tot_int != sum_flt10_int) { + cout << endl << "TEST ERROR: GFitsTableFltCol::integer() - 10"; + cout << endl << " Reference sum: " << sum_flt10_int; + cout << endl << " Derived sum: " << tot_int << endl; + throw; + } + cout << "."; + + // Check single precision table (string access) + tot_str.clear(); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_str += ":"+col_flt10.string(i,j); + } + if (tot_str != sum_flt10_str) { + cout << endl << "TEST ERROR: GFitsTableFltCol::string() - 10"; + cout << endl << " Reference sum: " << sum_flt10_str; + cout << endl << " Derived sum: " << tot_str << endl; + throw; + } + cout << "."; + + // + // ===== S H O R T ===== + // + + // Set short table + GFitsTableShtCol col_sht = GFitsTableShtCol("SHORT", nrows); + for (int i = 0; i < nrows; ++i) { + short val_sht = short(1000.0 * cos(0.1*float(i))); + col_sht(i) = val_sht; + sum_sht += val_sht; + sum_sht_int += int(val_sht); + ostringstream s_value; + s_value << val_sht; + sum_sht_str += ":"+s_value.str(); + } + cout << "."; + + // Check short table (operator access) + tot_sht = 0; + for (int i = 0; i < nrows; ++i) + tot_sht += col_sht(i); + if (tot_sht != sum_sht) { + cout << endl << "TEST ERROR: GFitsTableShtCol::operator()"; + cout << endl << " Reference sum: " << sum_sht; + cout << endl << " Derived sum: " << tot_sht << endl; + throw; + } + cout << "."; + + // Check short table (real access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) + tot_dbl += col_sht.real(i); + if (!dequal(tot_dbl, double(sum_sht))) { + cout << endl << "TEST ERROR: GFitsTableShtCol::real()"; + cout << endl << " Reference sum: " << sum_sht; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check short table (int access) + tot_int = 0; + for (int i = 0; i < nrows; ++i) + tot_int += col_sht.integer(i); + if (tot_int != sum_sht_int) { + cout << endl << "TEST ERROR: GFitsTableShtCol::integer()"; + cout << endl << " Reference sum: " << sum_sht_int; + cout << endl << " Derived sum: " << tot_int << endl; + throw; + } + cout << "."; + + // Check single precision table (string access) + tot_str.clear(); + for (int i = 0; i < nrows; ++i) + tot_str += ":"+col_sht.string(i); + if (tot_str != sum_sht_str) { + cout << endl << "TEST ERROR: GFitsTableShtCol::string()"; + cout << endl << " Reference sum: " << sum_sht_str; + cout << endl << " Derived sum: " << tot_str << endl; + throw; + } + cout << "."; + + // + // ===== S H O R T 1 0 ===== + // + + // Set short table + GFitsTableShtCol col_sht10 = GFitsTableShtCol("SHORT10", nrows, nvec); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) { + short val_sht = short(100.0*cos(0.1*float(i))* + cos(0.33*float(j))); + col_sht10(i,j) = val_sht; + sum_sht10 += val_sht; + sum_sht10_int += int(val_sht); + ostringstream s_value; + s_value << val_sht; + sum_sht10_str += ":"+s_value.str(); + } + } + cout << "."; + + // Check short table (operator access) + tot_sht = 0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_sht += col_sht10(i,j); + } + if (tot_sht != sum_sht10) { + cout << endl << "TEST ERROR: GFitsTableShtCol::operator() - 10"; + cout << endl << " Reference sum: " << sum_sht10; + cout << endl << " Derived sum: " << tot_sht << endl; + throw; + } + cout << "."; + + // Check short table (real access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_dbl += col_sht10.real(i,j); + } + if (!dequal(tot_dbl, sum_sht10)) { + cout << endl << "TEST ERROR: GFitsTableShtCol::real() - 10"; + cout << endl << " Reference sum: " << sum_sht10; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check short table (int access) + tot_int = 0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_int += col_sht10.integer(i,j); + } + if (tot_int != sum_sht10_int) { + cout << endl << "TEST ERROR: GFitsTableShtCol::integer() - 10"; + cout << endl << " Reference sum: " << sum_sht10_int; + cout << endl << " Derived sum: " << tot_int << endl; + throw; + } + cout << "."; + + // Check single precision table (string access) + tot_str.clear(); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_str += ":"+col_sht10.string(i,j); + } + if (tot_str != sum_sht10_str) { + cout << endl << "TEST ERROR: GFitsTableShtCol::string() - 10"; + cout << endl << " Reference sum: " << sum_sht10_str; + cout << endl << " Derived sum: " << tot_str << endl; + throw; + } + cout << "."; + + // + // ===== L O N G ===== + // + + // Set long table + GFitsTableLngCol col_lng = GFitsTableLngCol("LONG", nrows); + for (int i = 0; i < nrows; ++i) { + long val_lng = long(100000.0 * cos(0.1*float(i))); + col_lng(i) = val_lng; + sum_lng += val_lng; + sum_lng_int += int(val_lng); + ostringstream s_value; + s_value << val_lng; + sum_lng_str += ":"+s_value.str(); + } + cout << "."; + + // Check long table (operator access) + tot_lng = 0; + for (int i = 0; i < nrows; ++i) + tot_lng += col_lng(i); + if (tot_lng != sum_lng) { + cout << endl << "TEST ERROR: GFitsTableLngCol::operator()"; + cout << endl << " Reference sum: " << sum_lng; + cout << endl << " Derived sum: " << tot_lng << endl; + throw; + } + cout << "."; + + // Check long table (real access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) + tot_dbl += col_lng.real(i); + if (!dequal(tot_dbl, double(sum_lng))) { + cout << endl << "TEST ERROR: GFitsTableLngCol::real()"; + cout << endl << " Reference sum: " << sum_lng; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check long table (int access) + tot_int = 0; + for (int i = 0; i < nrows; ++i) + tot_int += col_lng.integer(i); + if (tot_int != sum_lng_int) { + cout << endl << "TEST ERROR: GFitsTableLngCol::integer()"; + cout << endl << " Reference sum: " << sum_lng_int; + cout << endl << " Derived sum: " << tot_int << endl; + throw; + } + cout << "."; + + // Check long table (string access) + tot_str.clear(); + for (int i = 0; i < nrows; ++i) + tot_str += ":"+col_lng.string(i); + if (tot_str != sum_lng_str) { + cout << endl << "TEST ERROR: GFitsTableLngCol::string()"; + cout << endl << " Reference sum: " << sum_lng_str; + cout << endl << " Derived sum: " << tot_str << endl; + throw; + } + cout << "."; + + // + // ===== L O N G 1 0 ===== + // + + // Set long table + GFitsTableLngCol col_lng10 = GFitsTableLngCol("LONG10", nrows, nvec); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) { + long val_lng = long(1000.0*cos(0.1*float(i))* + cos(0.33*float(j))); + col_lng10(i,j) = val_lng; + sum_lng10 += val_lng; + sum_lng10_int += int(val_lng); + ostringstream s_value; + s_value << val_lng; + sum_lng10_str += ":"+s_value.str(); + } + } + cout << "."; + + // Check long table (operator access) + tot_lng = 0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_lng += col_lng10(i,j); + } + if (tot_lng != sum_lng10) { + cout << endl << "TEST ERROR: GFitsTableLngCol::operator() - 10"; + cout << endl << " Reference sum: " << sum_lng10; + cout << endl << " Derived sum: " << tot_lng << endl; + throw; + } + cout << "."; + + // Check long table (real access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_dbl += col_lng10.real(i,j); + } + if (!dequal(tot_dbl, sum_lng10)) { + cout << endl << "TEST ERROR: GFitsTableLngCol::real() - 10"; + cout << endl << " Reference sum: " << sum_lng10; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check long table (int access) + tot_int = 0; + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_int += col_lng10.integer(i,j); + } + if (tot_int != sum_lng10_int) { + cout << endl << "TEST ERROR: GFitsTableLngCol::integer() - 10"; + cout << endl << " Reference sum: " << sum_lng10_int; + cout << endl << " Derived sum: " << tot_int << endl; + throw; + } + cout << "."; + + // Check single precision table (string access) + tot_str.clear(); + for (int i = 0; i < nrows; ++i) { + for (int j = 0; j < nvec; ++j) + tot_str += ":"+col_lng10.string(i,j); + } + if (tot_str != sum_lng10_str) { + cout << endl << "TEST ERROR: GFitsTableLngCol::string() - 10"; + cout << endl << " Reference sum: " << sum_lng10_str; + cout << endl << " Derived sum: " << tot_str << endl; + throw; + } + cout << "."; + + // + // ===== S T R I N G ===== + // + + // Set string table + GFitsTableStrCol col_str = GFitsTableStrCol("STRING", nrows, 20); + for (int i = 0; i < nrows; ++i) { + double val_dbl = cos(0.1*double(i)); + ostringstream s_value; + s_value << scientific << val_dbl; + col_str(i) = s_value.str(); + } + cout << "."; + + // // ===== W R I T E T A B L E ===== // - + // Build binary table GFitsBinTable table = GFitsBinTable(nrows); table.append_column(col_dbl); table.append_column(col_flt); - + table.append_column(col_sht); + table.append_column(col_lng); + table.append_column(col_str); + table.insert_column(1, col_dbl10); + table.insert_column(1, col_flt10); + table.insert_column(0, col_sht10); + table.insert_column(99, col_lng10); + // Create HDU and append to FILE file GFitsHDU hdu(table); fits.append_hdu(hdu); // Save FITS file fits.save(); + //cout << fits; + cout << "."; + } + catch (exception &e) { + cout << endl << "TEST ERROR: Unable to build tables." << endl; + cout << e.what() << endl; + throw; + } + cout << "."; + + + //================================================================ + //================================================================ + //================================================================ + // Read tables + //================================================================ + //================================================================ + //================================================================ + try { + // Open FITS file + GFits fits; + fits.open("test_bintables.fits"); + + // Set number of rows + int nrows = 10; + int nvec = 10; + + // Initial control sums + float tot_flt = 0.0; + double tot_dbl = 0.0; + int tot_int = 0; + std::string tot_str; + + // + // ===== D O U B L E ===== + // + + // Get column + GFitsTableDblCol* col_dbl = + (GFitsTableDblCol*)fits.hdu(2)->column("DOUBLE"); + + // Check double precision table (operator access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) + tot_dbl += (*col_dbl)(i); + if (!dequal(tot_dbl, sum_dbl)) { + cout << endl << "TEST ERROR: GFitsTableDblCol::operator()"; + cout << endl << " Reference sum: " << sum_dbl; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check double precision table (real access) + tot_dbl = 0.0; + for (int i = 0; i < nrows; ++i) + tot_dbl += (*col_dbl).real(i); + if (!dequal(tot_dbl, sum_dbl)) { + cout << endl << "TEST ERROR: GFitsTableDblCol::real()"; + cout << endl << " Reference sum: " << sum_dbl; + cout << endl << " Derived sum: " << tot_dbl << endl; + throw; + } + cout << "."; + + // Check double precision table (int access) + tot_int = 0; + for (int i = 0; i < nrows; ++i) + tot_int += (*col_dbl).integer(i); + if (tot_int != sum_dbl_int) { + cout << endl << "TEST ERROR: GFitsTableDblCol::integer()"; + cout << endl << " Reference sum: " << sum_dbl_int; + cout << endl << " Derived sum: " << tot_int << endl; + throw; + } + cout << "."; + + // Check double precision table (string access) + tot_str.clear(); + for (int i = 0; i < nrows; ++i) + tot_str += ":"+ (*col_dbl).string(i); + if (tot_str != sum_dbl_str) { + cout << endl << "TEST ERROR: GFitsTableDblCol::string()"; + cout << endl << " Reference sum: " << sum_dbl_str; + cout << endl << " Derived sum: " << tot_str << endl; + throw; + } cout << "."; } catch (exception &e) { @@ -675,8 +1244,7 @@ void test_bin_table(void) throw; } cout << ". ok." << endl; - - + } /*************************************************************************** -- libgit2 0.21.4