From bf772c7391058b6fb6b9055cfe5f40e65fb9e4e4 Mon Sep 17 00:00:00 2001 From: knodlseder <> Date: Mon, 3 Mar 2008 22:50:42 +0000 Subject: [PATCH] start implementing table writing --- include/GFitsAsciiTable.hpp | 33 ++++++++++++--------------------- include/GFitsBinTable.hpp | 24 ++---------------------- include/GFitsCfitsio.hpp | 16 ++++++++++++++++ include/GFitsData.hpp | 5 ++++- include/GFitsHDU.hpp | 2 ++ include/GFitsHeaderCard.hpp | 1 + include/GFitsImage.hpp | 2 -- include/GFitsTable.hpp | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/GFitsTableCol.hpp | 19 ++++++++++--------- include/Makefile.am | 1 + include/Makefile.in | 1 + src/Makefile.am | 1 + src/Makefile.in | 22 +++++++++++++++++----- src/fits/GFitsAsciiTable.cpp | 177 +++++++++++++++++++++++++++++---------------------------------------------------------------------------------------------------------------------------------------------------- src/fits/GFitsBinTable.cpp | 294 +++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/fits/GFitsData.cpp | 14 ++++++++++++++ src/fits/GFitsHDU.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- src/fits/GFitsHeaderCard.cpp | 10 +++++++--- src/fits/GFitsImage.cpp | 15 --------------- src/fits/GFitsTable.cpp | 661 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/fits/GFitsTableCol.cpp | 4 ++++ test/test_GFits.cpp | 40 +++++++++++++++++++++++++++++++++++++++- 22 files changed, 1044 insertions(+), 537 deletions(-) create mode 100644 include/GFitsTable.hpp create mode 100644 src/fits/GFitsTable.cpp diff --git a/include/GFitsAsciiTable.hpp b/include/GFitsAsciiTable.hpp index 8b6f124..9b64a7f 100644 --- a/include/GFitsAsciiTable.hpp +++ b/include/GFitsAsciiTable.hpp @@ -10,6 +10,11 @@ * (at your option) any later version. * * * ***************************************************************************/ +/** + * @file GFitsAsciiTable.hpp + * @brief GFitsAsciiTable class definition. + * @author J. Knodlseder + */ #ifndef GFITSASCIITABLE_HPP #define GFITSASCIITABLE_HPP @@ -17,22 +22,22 @@ /* __ Includes ___________________________________________________________ */ #include "GFitsCfitsio.hpp" #include "GFitsData.hpp" -#include "GFitsTableCol.hpp" +#include "GFitsTable.hpp" /* __ Namespaces _________________________________________________________ */ -/*************************************************************************** - * GFitsAsciiTable class definition * +/***********************************************************************//** + * @class GFitsAsciiTable + * + * @brief Interface for FITS binary table ***************************************************************************/ -class GFitsAsciiTable : public GFitsData { - - // I/O friends - friend ostream& operator<< (ostream& os, const GFitsAsciiTable& table); +class GFitsAsciiTable : public GFitsTable { public: // Constructors and destructors GFitsAsciiTable(); + GFitsAsciiTable(int nrows, int ncols); GFitsAsciiTable(const GFitsAsciiTable& table); virtual ~GFitsAsciiTable(); @@ -40,34 +45,20 @@ public: GFitsAsciiTable& operator= (const GFitsAsciiTable& table); // Methods - void open(__fitsfile* fptr); - void save(void); - void close(void); GFitsAsciiTable* clone(void) const; - GFitsTableCol* column(const std::string& colname); - GFitsTableCol* column(const int& colnum); private: // Private methods void init_members(void); void copy_members(const GFitsAsciiTable& table); void free_members(void); - void connect(__fitsfile* fptr); // Private data area - int m_rows; - int m_cols; - GFitsTableCol** m_columns; }; /*************************************************************************** * Inline methods * ***************************************************************************/ -inline -GFitsAsciiTable* GFitsAsciiTable::clone(void) const -{ - return new GFitsAsciiTable(*this); -} #endif /* GFITSASCIITABLE_HPP */ diff --git a/include/GFitsBinTable.hpp b/include/GFitsBinTable.hpp index acd3bae..a8c292e 100644 --- a/include/GFitsBinTable.hpp +++ b/include/GFitsBinTable.hpp @@ -22,23 +22,17 @@ /* __ Includes ___________________________________________________________ */ #include "GFitsCfitsio.hpp" #include "GFitsData.hpp" -#include "GFitsTableCol.hpp" +#include "GFitsTable.hpp" /* __ Namespaces _________________________________________________________ */ -/* __ Structures _________________________________________________________ */ - - /***********************************************************************//** * @class GFitsBinTable * * @brief Interface for FITS binary table ***************************************************************************/ -class GFitsBinTable : public GFitsData { - - // I/O friends - friend ostream& operator<< (ostream& os, const GFitsBinTable& table); +class GFitsBinTable : public GFitsTable { public: // Constructors and destructors @@ -51,34 +45,20 @@ public: GFitsBinTable& operator= (const GFitsBinTable& table); // Methods - void open(__fitsfile* fptr); - void save(void); - void close(void); GFitsBinTable* clone(void) const; - GFitsTableCol* column(const std::string& colname); - GFitsTableCol* column(const int& colnum); private: // Private methods void init_members(void); void copy_members(const GFitsBinTable& table); void free_members(void); - void connect(__fitsfile* fptr); // Private data area - int m_rows; //!< Number of rows in table - int m_cols; //!< Number of columns in table - GFitsTableCol** m_columns; //!< Array of column pointers }; /*************************************************************************** * Inline methods * ***************************************************************************/ -inline -GFitsBinTable* GFitsBinTable::clone(void) const -{ - return new GFitsBinTable(*this); -} #endif /* GFITSBINTABLE_HPP */ diff --git a/include/GFitsCfitsio.hpp b/include/GFitsCfitsio.hpp index 5ecbc94..0fc45c7 100644 --- a/include/GFitsCfitsio.hpp +++ b/include/GFitsCfitsio.hpp @@ -31,6 +31,7 @@ /* __ Macros _____________________________________________________________ */ #define __ffclos(A, B) ffclos(A, B) #define __ffcrim(A, B, C, D, E) ffcrim(A, B, C, D, E) +#define __ffcrtb(A, B, C, D, E, F, G, H, I) ffcrtb(A, B, C, D, E, F, G, H, I) #define __ffdelt(A, B) ffdelt(A, B) #define __ffgcv(A, B, C, D, E, F, G, H, I, J) ffgcv(A, B, C, D, E, F, G, H, I, J) #define __ffgcvs(A, B, C, D, E, F, G, H, I) ffgcvs(A, B, C, D, E, F, G, H, I) @@ -49,14 +50,21 @@ #define __ffinit(A, B, C) ffinit(A, B, C) #define __ffopen(A, B, C, D) ffopen(A, B, C, D) #define __ffmahd(A, B, C, D) ffmahd(A, B, C, D) +#define __ffpcom(A, B, C) ffpcom(A, B, C) +#define __ffphis(A, B, C) ffphis(A, B, C) #define __ffpss(A, B, C, D, E, F) ffpss(A, B, C, D, E, F) #define __ffthdu(A, B, C) ffthdu(A, B, C) #define __ffuky(A, B, C, D, E, F) ffuky(A, B, C, D, E, F) +#define __ffukyd(A, B, C, D, E, F) ffukyd(A, B, C, D, E, F) +#define __ffukyj(A, B, C, D, E) ffukyj(A, B, C, D, E) +#define __ffukyl(A, B, C, D, E) ffukyl(A, B, C, D, E) +#define __ffukys(A, B, C, D, E) ffukys(A, B, C, D, E) #define __TBIT TBIT #define __TBYTE TBYTE #define __TLOGICAL TLOGICAL #define __TSTRING TSTRING #define __TSHORT TSHORT +#define __TINT TINT #define __TLONG TLONG #define __TLONGLONG TLONGLONG #define __TFLOAT TFLOAT @@ -73,6 +81,7 @@ typedef fitsfile __fitsfile; /* __ Macros _____________________________________________________________ */ #define __ffclos(A, B) __dummy() #define __ffcrim(A, B, C, D, E) __dummy() +#define __ffcrtb(A, B, C, D, E, F, G, H, I) __dummy() #define __ffdelt(A, B) __dummy() #define __ffgcv(A, B, C, D, E, F, G, H, I, J) __dummy() #define __ffgcvs(A, B, C, D, E, F, G, H, I) __dummy() @@ -91,14 +100,21 @@ typedef fitsfile __fitsfile; #define __ffinit(A, B, C) __dummy() #define __ffmahd(A, B, C, D) __dummy() #define __ffopen(A, B, C, D) __dummy() +#define __ffpcom(A, B, C) __dummy() +#define __ffphis(A, B, C) __dummy() #define __ffpss(A, B, C, D, E, F) __dummy() #define __ffthdu(A, B, C) __dummy() #define __ffuky(A, B, C, D, E, F) __dummy() +#define __ffukyd(A, B, C, D, E, F) __dummy() +#define __ffukyj(A, B, C, D, E) __dummy() +#define __ffukyl(A, B, C, D, E) __dummy() +#define __ffukys(A, B, C, D, E) __dummy() #define __TBIT 1 #define __TBYTE 11 #define __TLOGICAL 14 #define __TSTRING 16 #define __TSHORT 21 +#define __TINT 31 #define __TLONG 41 #define __TLONGLONG 81 #define __TFLOAT 42 diff --git a/include/GFitsData.hpp b/include/GFitsData.hpp index 1a20bc2..0114e1f 100644 --- a/include/GFitsData.hpp +++ b/include/GFitsData.hpp @@ -45,7 +45,10 @@ public: protected: // Protected methods - virtual void connect(__fitsfile* fptr) = 0; + virtual void connect(__fitsfile* fptr); + + // Protected data area + __fitsfile m_fitsfile; //!< FITS file }; #endif /* GFITSDATA_HPP */ diff --git a/include/GFitsHDU.hpp b/include/GFitsHDU.hpp index 7b7ee49..79f86c0 100644 --- a/include/GFitsHDU.hpp +++ b/include/GFitsHDU.hpp @@ -51,6 +51,8 @@ public: // Constructors and destructors GFitsHDU(); GFitsHDU(const GFitsImage& image); + GFitsHDU(const GFitsAsciiTable& table); + GFitsHDU(const GFitsBinTable& table); GFitsHDU(const GFitsHDU& hdu); ~GFitsHDU(); diff --git a/include/GFitsHeaderCard.hpp b/include/GFitsHeaderCard.hpp index 3c6d767..19211ca 100644 --- a/include/GFitsHeaderCard.hpp +++ b/include/GFitsHeaderCard.hpp @@ -92,6 +92,7 @@ private: int m_value_decimals; //!< Decimals of value (for float) std::string m_unit; //!< Unit of the card value std::string m_comment; //!< Card comment + int m_comment_write; //!< Signals that comment should be written }; diff --git a/include/GFitsImage.hpp b/include/GFitsImage.hpp index b0cf4d0..11a9156 100644 --- a/include/GFitsImage.hpp +++ b/include/GFitsImage.hpp @@ -65,13 +65,11 @@ protected: void init_members(void); void copy_members(const GFitsImage& image); void free_members(void); - void connect(__fitsfile* fptr); void open_image(__fitsfile* fptr); void load_image(int datatype, const void* pixels, const void* nulval, int* anynul); void save_image(int datatype, const void* pixels); // Private data area - __fitsfile m_fitsfile; //!< FITS file int m_bitpix; //!< Number of Bits/pixel int m_naxis; //!< Image dimension long* m_naxes; //!< Number of pixels in each dimension diff --git a/include/GFitsTable.hpp b/include/GFitsTable.hpp new file mode 100644 index 0000000..2625242 --- /dev/null +++ b/include/GFitsTable.hpp @@ -0,0 +1,85 @@ +/*************************************************************************** + * GFitsTable.hpp - FITS table abstract base class * + * ----------------------------------------------------------------------- * + * copyright : (C) 2008 by Jurgen Knodlseder * + * ----------------------------------------------------------------------- * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +/** + * @file GFitsTable.hpp + * @brief GFitsTable class definition. + * @author J. Knodlseder + */ + +#ifndef GFITSTABLE_HPP +#define GFITSTABLE_HPP + +/* __ Includes ___________________________________________________________ */ +#include "GFitsCfitsio.hpp" +#include "GFitsData.hpp" +#include "GFitsTableCol.hpp" + +/* __ Namespaces _________________________________________________________ */ + + +/* __ Structures _________________________________________________________ */ + + +/***********************************************************************//** + * @class GFitsTable + * + * @brief Abstract interface for FITS table + ***************************************************************************/ +class GFitsTable : public GFitsData { + + // I/O friends + friend ostream& operator<< (ostream& os, const GFitsTable& table); + +public: + // Constructors and destructors + GFitsTable(); + GFitsTable(int nrows, int ncols); + GFitsTable(const GFitsTable& table); + virtual ~GFitsTable(); + + // Operators + GFitsTable& operator= (const GFitsTable& table); + + // Methods + void open(__fitsfile* fptr); + void save(void); + void close(void); + GFitsTable* clone(void) const = 0; + GFitsTableCol* column(const std::string& colname); + GFitsTableCol* column(const int& colnum); + int rows(void) const; + int cols(void) const; + +protected: + // Protected methods + void init_members(void); + void copy_members(const GFitsTable& table); + void free_members(void); + void connect(__fitsfile* fptr); + char* get_ttype(const int& colnum) const; + char* get_tform(const int& colnum) const; + char* get_tunit(const int& colnum) const; + + // Protected data area + int m_type; //!< Table type (1=ASCII, 2=Binary) + int m_rows; //!< Number of rows in table + int m_cols; //!< Number of columns in table + GFitsTableCol** m_columns; //!< Array of column pointers +}; + + +/*************************************************************************** + * Inline methods * + ***************************************************************************/ + +#endif /* GFITSTABLE_HPP */ diff --git a/include/GFitsTableCol.hpp b/include/GFitsTableCol.hpp index 4d33940..4980e05 100644 --- a/include/GFitsTableCol.hpp +++ b/include/GFitsTableCol.hpp @@ -26,8 +26,7 @@ class GFitsTableCol { // Friend classes - friend class GFitsAsciiTable; - friend class GFitsBinTable; + friend class GFitsTable; // I/O friends friend ostream& operator<< (ostream& os, const GFitsTableCol& column); @@ -69,13 +68,15 @@ public: protected: // Protected data area - std::string m_name; - int m_colnum; - int m_type; - int m_repeat; - int m_width; - int m_length; - __fitsfile m_fitsfile; + std::string m_name; //!< Column name + std::string m_format; //!< Column format + std::string m_unit; //!< Column unit + int m_colnum; //!< Column number + int m_type; //!< Column type + int m_repeat; //!< Repeat value of column + int m_width; //!< Width of column + int m_length; //!< Length of column + __fitsfile m_fitsfile; //!< FITS file associated with column private: // Private methods diff --git a/include/Makefile.am b/include/Makefile.am index 932b352..ecdc793 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -11,6 +11,7 @@ pkginclude_HEADERS = GammaLib.hpp \ GFitsData.hpp \ GFitsImage.hpp \ GFitsDblImage.hpp \ + GFitsTable.hpp \ GFitsAsciiTable.hpp \ GFitsBinTable.hpp \ GFitsTableCol.hpp \ diff --git a/include/Makefile.in b/include/Makefile.in index 4658283..d0802d4 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -117,6 +117,7 @@ pkginclude_HEADERS = GammaLib.hpp \ GFitsData.hpp \ GFitsImage.hpp \ GFitsDblImage.hpp \ + GFitsTable.hpp \ GFitsAsciiTable.hpp \ GFitsBinTable.hpp \ GFitsTableCol.hpp \ diff --git a/src/Makefile.am b/src/Makefile.am index 1bad652..791c2fb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,7 @@ files = GException.cpp \ fits/GFitsData.cpp \ fits/GFitsImage.cpp \ fits/GFitsDblImage.cpp \ + fits/GFitsTable.cpp \ fits/GFitsAsciiTable.cpp \ fits/GFitsBinTable.cpp \ fits/GFitsTableCol.cpp \ diff --git a/src/Makefile.in b/src/Makefile.in index f7e2267..136fb0b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -125,6 +125,7 @@ files = GException.cpp \ fits/GFitsData.cpp \ fits/GFitsImage.cpp \ fits/GFitsDblImage.cpp \ + fits/GFitsTable.cpp \ fits/GFitsAsciiTable.cpp \ fits/GFitsBinTable.cpp \ fits/GFitsTableCol.cpp \ @@ -159,11 +160,12 @@ libgamma_la_LIBADD = am__objects_1 = GException.lo GTools.lo GSkyDir.lo GData.lo GResponse.lo \ GLATResponse.lo GObservation.lo GFitsHeaderCard.lo \ GFitsHeader.lo GFitsData.lo GFitsImage.lo GFitsDblImage.lo \ - GFitsAsciiTable.lo GFitsBinTable.lo GFitsTableCol.lo \ - GFitsTableStrCol.lo GFitsTableShtCol.lo GFitsTableLngCol.lo \ - GFitsTableFltCol.lo GFitsTableDblCol.lo GFitsHDU.lo GFits.lo \ - GFitPar.lo GVector.lo GMatrixBase.lo GMatrix.lo GSymMatrix.lo \ - GSparseMatrix.lo GSparseSymbolic.lo GSparseNumeric.lo + GFitsTable.lo GFitsAsciiTable.lo GFitsBinTable.lo \ + GFitsTableCol.lo GFitsTableStrCol.lo GFitsTableShtCol.lo \ + GFitsTableLngCol.lo GFitsTableFltCol.lo GFitsTableDblCol.lo \ + GFitsHDU.lo GFits.lo GFitPar.lo GVector.lo GMatrixBase.lo \ + GMatrix.lo GSymMatrix.lo GSparseMatrix.lo GSparseSymbolic.lo \ + GSparseNumeric.lo am_libgamma_la_OBJECTS = $(am__objects_1) libgamma_la_OBJECTS = $(am_libgamma_la_OBJECTS) @@ -233,6 +235,7 @@ GFitsHeader.lo: fits/GFitsHeader.cpp GFitsData.lo: fits/GFitsData.cpp GFitsImage.lo: fits/GFitsImage.cpp GFitsDblImage.lo: fits/GFitsDblImage.cpp +GFitsTable.lo: fits/GFitsTable.cpp GFitsAsciiTable.lo: fits/GFitsAsciiTable.cpp GFitsBinTable.lo: fits/GFitsBinTable.cpp GFitsTableCol.lo: fits/GFitsTableCol.cpp @@ -350,6 +353,15 @@ GFitsDblImage.obj: fits/GFitsDblImage.cpp GFitsDblImage.lo: fits/GFitsDblImage.cpp $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GFitsDblImage.lo `test -f 'fits/GFitsDblImage.cpp' || echo '$(srcdir)/'`fits/GFitsDblImage.cpp +GFitsTable.o: fits/GFitsTable.cpp + $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GFitsTable.o `test -f 'fits/GFitsTable.cpp' || echo '$(srcdir)/'`fits/GFitsTable.cpp + +GFitsTable.obj: fits/GFitsTable.cpp + $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GFitsTable.obj `cygpath -w fits/GFitsTable.cpp` + +GFitsTable.lo: fits/GFitsTable.cpp + $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GFitsTable.lo `test -f 'fits/GFitsTable.cpp' || echo '$(srcdir)/'`fits/GFitsTable.cpp + GFitsAsciiTable.o: fits/GFitsAsciiTable.cpp $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GFitsAsciiTable.o `test -f 'fits/GFitsAsciiTable.cpp' || echo '$(srcdir)/'`fits/GFitsAsciiTable.cpp diff --git a/src/fits/GFitsAsciiTable.cpp b/src/fits/GFitsAsciiTable.cpp index 40d4e7a..bf5375a 100644 --- a/src/fits/GFitsAsciiTable.cpp +++ b/src/fits/GFitsAsciiTable.cpp @@ -16,11 +16,11 @@ #include #include "GException.hpp" #include "GFitsAsciiTable.hpp" -#include "GFitsTableStrCol.hpp" -#include "GFitsTableShtCol.hpp" -#include "GFitsTableLngCol.hpp" -#include "GFitsTableFltCol.hpp" -#include "GFitsTableDblCol.hpp" +//#include "GFitsTableStrCol.hpp" +//#include "GFitsTableShtCol.hpp" +//#include "GFitsTableLngCol.hpp" +//#include "GFitsTableFltCol.hpp" +//#include "GFitsTableDblCol.hpp" /* __ Namespaces _________________________________________________________ */ @@ -43,7 +43,23 @@ /***********************************************************************//** * @brief Constructor ***************************************************************************/ -GFitsAsciiTable::GFitsAsciiTable() : GFitsData() +GFitsAsciiTable::GFitsAsciiTable() : GFitsTable() +{ + // Initialise class members for clean destruction + init_members(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Constructor + * + * @param[in] nrows Number of rows in table + * @param[in] ncols Number of columns in table + ***************************************************************************/ +GFitsAsciiTable::GFitsAsciiTable(int nrows, int ncols) : GFitsTable(nrows, ncols) { // Initialise class members for clean destruction init_members(); @@ -58,7 +74,7 @@ GFitsAsciiTable::GFitsAsciiTable() : GFitsData() * * @param table Table to be used to initialise instance ***************************************************************************/ -GFitsAsciiTable::GFitsAsciiTable(const GFitsAsciiTable& table) : GFitsData(table) +GFitsAsciiTable::GFitsAsciiTable(const GFitsAsciiTable& table) : GFitsTable(table) { // Initialise class members for clean destruction init_members(); @@ -101,7 +117,7 @@ GFitsAsciiTable& GFitsAsciiTable::operator= (const GFitsAsciiTable& table) if (this != &table) { // Copy base class members - this->GFitsData::operator=(table); + this->GFitsTable::operator=(table); // Free members free_members(); @@ -126,88 +142,11 @@ GFitsAsciiTable& GFitsAsciiTable::operator= (const GFitsAsciiTable& table) ==========================================================================*/ /***********************************************************************//** - * @brief Open Table - * - * NOT YET IMPLEMENTED + * @brief Clone ASCII table ***************************************************************************/ -void GFitsAsciiTable::open(__fitsfile* fptr) +GFitsAsciiTable* GFitsAsciiTable::clone(void) const { - // Return - return; -} - - -/***********************************************************************//** - * @brief Save ASCII table - * - * NOT YET IMPLEMENTED - ***************************************************************************/ -void GFitsAsciiTable::save(void) -{ - cout << "GFitsAsciiTable::save entry" << endl; - // Return - return; -} - - -/***********************************************************************//** - * @brief Close Table - ***************************************************************************/ -void GFitsAsciiTable::close(void) -{ - // Free members - free_members(); - - // Initialise members - init_members(); - - // Return - return; -} - - -/***********************************************************************//** - * @brief Return pointer to column with specified name - * - * @param colname Name of ASCII table column - ***************************************************************************/ -GFitsTableCol* GFitsAsciiTable::column(const std::string& colname) -{ - // Initialise pointer - GFitsTableCol* ptr = NULL; - - // If there are columns then search for the specified name - if (m_columns != NULL) { - for (int i = 0; i < m_cols; ++i) { - if (m_columns[i]->name() == colname) { - ptr = m_columns[i]; - break; - } - } - } - - // Return column pointer - return ptr; -} - - -/***********************************************************************//** - * @brief Return pointer to column with number - * - * @param colnum Number of ASCII column (starting from 0) - ***************************************************************************/ -GFitsTableCol* GFitsAsciiTable::column(const int& colnum) -{ - // Initialise pointer - GFitsTableCol* ptr = NULL; - - // If there are columns then search for the specified name - if (m_columns != NULL) { - ptr = m_columns[colnum]; - } - - // Return column pointer - return ptr; + return new GFitsAsciiTable(*this); } @@ -223,9 +162,7 @@ GFitsTableCol* GFitsAsciiTable::column(const int& colnum) void GFitsAsciiTable::init_members(void) { // Initialise members - m_rows = 0; - m_cols = 0; - m_columns = NULL; + m_type = 1; // Return return; @@ -239,18 +176,7 @@ void GFitsAsciiTable::init_members(void) ***************************************************************************/ void GFitsAsciiTable::copy_members(const GFitsAsciiTable& table) { - // Copy attributes - m_rows = table.m_rows; - m_cols = table.m_cols; - - // Copy column definition - if (table.m_columns != NULL && m_cols > 0) { - m_columns = new GFitsTableCol*[m_cols]; - for (int i = 0; i < m_cols; ++i) { - if (table.m_columns[i] != NULL) - m_columns[i] = table.m_columns[i]->clone(); - } - } + // Copy members // Return return; @@ -263,34 +189,8 @@ void GFitsAsciiTable::copy_members(const GFitsAsciiTable& table) void GFitsAsciiTable::free_members(void) { // Free memory - for (int i = 0; i < m_cols; ++i) { - if (m_columns[i] != NULL) delete m_columns[i]; - } - if (m_columns != NULL) delete [] m_columns; // Mark memory as freed - m_columns = NULL; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Connect ASCII table to FITS file - * - * @param fptr FITS file pointer to which the binary table should be connected - * - * The connection of the ASCII table is done by connecting all columns. - ***************************************************************************/ -void GFitsAsciiTable::connect(__fitsfile* fptr) -{ - // First connect ASCII table - - // Then connect all columns - for (int i = 0; i < m_cols; ++i) { - if (m_columns[i] != NULL) m_columns[i]->connect(fptr); - } // Return return; @@ -303,25 +203,6 @@ void GFitsAsciiTable::connect(__fitsfile* fptr) = = ==========================================================================*/ -/***********************************************************************//** - * @brief Output operator - * - * @param os Stream into which the output is done - * @param table Table to be dumped - ***************************************************************************/ -ostream& operator<< (ostream& os, const GFitsAsciiTable& table) -{ - // Put header in stream - os << "=== GFitsAsciiTable ===" << endl; - os << " Number of rows ............: " << table.m_rows << endl; - os << " Number of columns .........: " << table.m_cols << endl; - for (int i = 0; i < table.m_cols; ++i) - os << " " << *(table.m_columns[i]); - - // Return output stream - return os; -} - /*========================================================================== = = diff --git a/src/fits/GFitsBinTable.cpp b/src/fits/GFitsBinTable.cpp index 72c1166..bf87cdd 100644 --- a/src/fits/GFitsBinTable.cpp +++ b/src/fits/GFitsBinTable.cpp @@ -15,20 +15,17 @@ /* __ Includes ___________________________________________________________ */ #include #include "GException.hpp" -#include "GTools.hpp" +//#include "GTools.hpp" #include "GFitsBinTable.hpp" -#include "GFitsTableStrCol.hpp" -#include "GFitsTableShtCol.hpp" -#include "GFitsTableLngCol.hpp" -#include "GFitsTableFltCol.hpp" -#include "GFitsTableDblCol.hpp" +//#include "GFitsTableStrCol.hpp" +//#include "GFitsTableShtCol.hpp" +//#include "GFitsTableLngCol.hpp" +//#include "GFitsTableFltCol.hpp" +//#include "GFitsTableDblCol.hpp" /* __ Namespaces _________________________________________________________ */ /* __ Method name definitions ____________________________________________ */ -#define G_OPEN "GFitsBinTable::open(fitsfile*)" -#define G_COLUMN1 "GFitsBinTable::column(const std::string&)" -#define G_COLUMN2 "GFitsBinTable::column(const int&)" /* __ Macros _____________________________________________________________ */ @@ -46,7 +43,7 @@ /***********************************************************************//** * @brief Constructor ***************************************************************************/ -GFitsBinTable::GFitsBinTable() : GFitsData() +GFitsBinTable::GFitsBinTable() : GFitsTable() { // Initialise class members for clean destruction init_members(); @@ -62,27 +59,11 @@ GFitsBinTable::GFitsBinTable() : GFitsData() * @param[in] nrows Number of rows in table * @param[in] ncols Number of columns in table ***************************************************************************/ -GFitsBinTable::GFitsBinTable(int nrows, int ncols) : GFitsData() +GFitsBinTable::GFitsBinTable(int nrows, int ncols) : GFitsTable(nrows, ncols) { // Initialise class members for clean destruction init_members(); - // Store table dimension - m_rows = nrows; - m_cols = ncols; - - // If there are columns then allocate memory for column pointers - if (m_cols > 0) { - - // Allocate pointer memory - m_columns = new GFitsTableCol*[m_cols]; - - // Initialise pointers - for (int i = 0; i < m_cols; ++i) - m_columns[i] = NULL; - - } // endfor: looped over all columns - // Return return; } @@ -94,7 +75,7 @@ GFitsBinTable::GFitsBinTable(int nrows, int ncols) : GFitsData() * @param[in] table Table which will be used to construct GFitsBinTable * instance ***************************************************************************/ -GFitsBinTable::GFitsBinTable(const GFitsBinTable& table) : GFitsData(table) +GFitsBinTable::GFitsBinTable(const GFitsBinTable& table) : GFitsTable(table) { // Initialise class members for clean destruction init_members(); @@ -137,7 +118,7 @@ GFitsBinTable& GFitsBinTable::operator= (const GFitsBinTable& table) if (this != &table) { // Copy base class members - this->GFitsData::operator=(table); + this->GFitsTable::operator=(table); // Free members free_members(); @@ -162,197 +143,11 @@ GFitsBinTable& GFitsBinTable::operator= (const GFitsBinTable& table) ==========================================================================*/ /***********************************************************************//** - * @brief Open Table - * - * @param[in] fptr FITS file pointer - * - * Builds a description of the binary table in memory. Columns are not loaded - * but column descriptors are allocated. The column data will only be loaded - * once it needs to be accessed. - ***************************************************************************/ -void GFitsBinTable::open(__fitsfile* fptr) -{ - // Move to HDU - int status = 0; - status = __ffmahd(fptr, (fptr->HDUposition)+1, NULL, &status); - if (status != 0) - throw GException::fits_error(G_OPEN, status); - - // Determine number of rows in table - long nrows = 0; - status = __ffgnrw(fptr, &nrows, &status); - if (status != 0) - throw GException::fits_error(G_OPEN, status); - else - m_rows = (int)nrows; - - // Determine number of columns in table - status = __ffgncl(fptr, &m_cols, &status); - if (status != 0) - throw GException::fits_error(G_OPEN, status); - - // Allocate memory for column pointers - if (m_columns != NULL) delete [] m_columns; - m_columns = new GFitsTableCol*[m_cols]; - - // Get table column information - int typecode = 0; - long repeat = 0; - long width = 0; - for (int i = 0; i < m_cols; ++i) { - - // Get column name - char keyname[10]; - char value[80]; - sprintf(keyname, "TTYPE%d", i+1); - status = __ffgkey(fptr, keyname, value, NULL, &status); - if (status != 0) - throw GException::fits_error(G_OPEN, status); - value[strlen(value)-1] = '\0'; - - // Get column definition - status = __ffgtcl(fptr, i+1, &typecode, &repeat, &width, &status); - if (status != 0) - throw GException::fits_error(G_OPEN, status); - - // Allocate column - switch (typecode) { - case __TSTRING: - m_columns[i] = new GFitsTableStrCol(); - break; - case __TSHORT: - m_columns[i] = new GFitsTableShtCol(); - break; - case __TLONG: - m_columns[i] = new GFitsTableLngCol(); - break; - case __TFLOAT: - m_columns[i] = new GFitsTableFltCol(); - break; - case __TDOUBLE: - m_columns[i] = new GFitsTableDblCol(); - break; - default: - throw GException::fits_unknown_coltype(G_OPEN, typecode); - break; - } - - // Store column definition - m_columns[i]->set_name(strip_whitespace(&(value[1]))); - m_columns[i]->set_colnum(i+1); - m_columns[i]->set_type(typecode); - m_columns[i]->set_repeat(repeat); - m_columns[i]->set_width(width); - m_columns[i]->set_length(m_rows); - m_columns[i]->set_fitsfile(fptr); - - } // endfor: looped over all columns - - // Return - return; -} - - -/***********************************************************************//** - * @brief Save binary table - * - * NOT YET IMPLEMENTED - ***************************************************************************/ -void GFitsBinTable::save(void) -{ - cout << "GFitsBinTable::save entry" << endl; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Close binary table - ***************************************************************************/ -void GFitsBinTable::close(void) -{ - // Free members - free_members(); - - // Initialise members - init_members(); - - // Return - return; -} - - -/***********************************************************************//** - * @brief Return pointer to column with specified name - * - * @param[in] colname Name of column which should be accessed - * - * @exception GException::fits_no_data - * There are no column data in the table or there is not data - * for this column - * @exception GException::fits_column_not_found - * Requested column has not been found in table. - ***************************************************************************/ -GFitsTableCol* GFitsBinTable::column(const std::string& colname) -{ - // If there is no data then throw an exception - if (m_columns == NULL) - throw GException::fits_no_data(G_COLUMN1, "No column data in table"); - - // Initialise pointer - GFitsTableCol* ptr = NULL; - - // If there are columns then search for the specified name - if (m_columns != NULL) { - for (int i = 0; i < m_cols; ++i) { - if (m_columns[i]->name() == colname) { - ptr = m_columns[i]; - if (ptr == NULL) - throw GException::fits_no_data(G_COLUMN1, - "No data for this column"); - break; - } - } - } - - // If column has not been found throw an exception - if (ptr == NULL) - throw GException::fits_column_not_found(G_COLUMN1, colname); - - // Return column pointer - return ptr; -} - - -/***********************************************************************//** - * @brief Return pointer to column with number - * - * @param[in] colnum Number of requested column (starting from 0) - * - * @exception GException::fits_no_data - * There are no column data in the table or there is not data - * for this column - * @exception GException::out_of_range - * Requested column has not been found in table. + * @brief Clone binary table ***************************************************************************/ -GFitsTableCol* GFitsBinTable::column(const int& colnum) +GFitsBinTable* GFitsBinTable::clone(void) const { - // If there is no data then throw an exception - if (m_columns == NULL) - throw GException::fits_no_data(G_COLUMN2, "No column data in table"); - - // If column number is out of range then throw an exception - if (colnum < 0 || colnum >= m_cols) - throw GException::out_of_range(G_COLUMN2, colnum, 0, m_cols-1); - - // Get column pointer - GFitsTableCol* ptr = ptr = m_columns[colnum]; - if (ptr == NULL) - throw GException::fits_no_data(G_COLUMN2, "No data for this column"); - - // Return column pointer - return ptr; + return new GFitsBinTable(*this); } @@ -368,9 +163,7 @@ GFitsTableCol* GFitsBinTable::column(const int& colnum) void GFitsBinTable::init_members(void) { // Initialise members - m_rows = 0; - m_cols = 0; - m_columns = NULL; + m_type = 2; // Return return; @@ -384,18 +177,7 @@ void GFitsBinTable::init_members(void) ***************************************************************************/ void GFitsBinTable::copy_members(const GFitsBinTable& table) { - // Copy attributes - m_rows = table.m_rows; - m_cols = table.m_cols; - - // Copy column definition - if (table.m_columns != NULL && m_cols > 0) { - m_columns = new GFitsTableCol*[m_cols]; - for (int i = 0; i < m_cols; ++i) { - if (table.m_columns[i] != NULL) - m_columns[i] = table.m_columns[i]->clone(); - } - } + // Copy members // Return return; @@ -408,35 +190,8 @@ void GFitsBinTable::copy_members(const GFitsBinTable& table) void GFitsBinTable::free_members(void) { // Free memory - for (int i = 0; i < m_cols; ++i) { - if (m_columns[i] != NULL) delete m_columns[i]; - } - if (m_columns != NULL) delete [] m_columns; // Mark memory as freed - m_columns = NULL; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Connect binary table to FITS file - * - * @param[in] fptr FITS file pointer to which the binary table should be - * connected - * - * The connection of the binary table is done by connecting all columns. - ***************************************************************************/ -void GFitsBinTable::connect(__fitsfile* fptr) -{ - // First connect binary table - - // Then connect all columns - for (int i = 0; i < m_cols; ++i) { - if (m_columns[i] != NULL) m_columns[i]->connect(fptr); - } // Return return; @@ -449,25 +204,6 @@ void GFitsBinTable::connect(__fitsfile* fptr) = = ==========================================================================*/ -/***********************************************************************//** - * @brief Output operator - * - * @param[in] os Output stream - * @param[in] table Table to put in output stream - ***************************************************************************/ -ostream& operator<< (ostream& os, const GFitsBinTable& table) -{ - // Put header in stream - os << "=== GFitsBinTable ===" << endl; - os << " Number of rows ............: " << table.m_rows << endl; - os << " Number of columns .........: " << table.m_cols << endl; - for (int i = 0; i < table.m_cols; ++i) - os << " " << *(table.m_columns[i]); - - // Return output stream - return os; -} - /*========================================================================== = = diff --git a/src/fits/GFitsData.cpp b/src/fits/GFitsData.cpp index 053f3ee..8d29106 100644 --- a/src/fits/GFitsData.cpp +++ b/src/fits/GFitsData.cpp @@ -103,6 +103,20 @@ GFitsData& GFitsData::operator= (const GFitsData& data) = = ==========================================================================*/ +/***********************************************************************//** + * @brief Connect data to FITS file + * + * @param[in] fptr FITS file pointer to which the data should be connected + ***************************************************************************/ +void GFitsData::connect(__fitsfile* fptr) +{ + // Connect data + m_fitsfile = *fptr; + + // Return + return; +} + /*========================================================================== = = diff --git a/src/fits/GFitsHDU.cpp b/src/fits/GFitsHDU.cpp index e4f47e3..d10e4ae 100644 --- a/src/fits/GFitsHDU.cpp +++ b/src/fits/GFitsHDU.cpp @@ -27,6 +27,11 @@ #define G_COLUMN "GFitsHDU::column(const std::string&)" #define G_NEW_IMAGE "GFitsHDU::new_image()" +/* __ Definitions ________________________________________________________ */ +#define HT_IMAGE 0 +#define HT_ASCII_TABLE 1 +#define HT_BIN_TABLE 2 + /* __ Macros _____________________________________________________________ */ /* __ Coding definitions _________________________________________________ */ @@ -67,8 +72,9 @@ GFitsHDU::GFitsHDU(const GFitsImage& image) // Initialise class members for clean destruction init_members(); - // Copy image into HDU data + // Copy image into HDU data and set data type m_data = image.clone(); + m_type = HT_IMAGE; // Allocate new header m_header = new GFitsHeader(); @@ -99,9 +105,91 @@ GFitsHDU::GFitsHDU(const GFitsImage& image) /***********************************************************************//** + * @brief ASCII Table HDU Constructor + * + * @param[in] table Table from which the HDU should be constructed + ***************************************************************************/ +GFitsHDU::GFitsHDU(const GFitsAsciiTable& table) +{ + // Initialise class members for clean destruction + init_members(); + + // Copy table into HDU data and set data type + m_data = table.clone(); + m_type = HT_ASCII_TABLE; + + // Allocate new header + m_header = new GFitsHeader(); + + // Set image header keywords + /* + m_header->update(GFitsHeaderCard("XTENSION", "'BINTABLE'", + "binary table extension")); + m_header->update(GFitsHeaderCard("BITPIX", 8, + "8-bit bytes")); + m_header->update(GFitsHeaderCard("NAXIS", 2, + "2-dimensional binary table")); + m_header->update(GFitsHeaderCard("NAXIS1", 0, + "width of table in bytes")); + m_header->update(GFitsHeaderCard("NAXIS2", table.rows(), + "number of rows in table")); + m_header->update(GFitsHeaderCard("PCOUNT", 0, + "size of special data area")); + m_header->update(GFitsHeaderCard("GCOUNT", 1, + "one data group (required keyword)")); + m_header->update(GFitsHeaderCard("TFIELDS", 1, + "number of fields in each row")); +*/ + // Return + return; +} + + +/***********************************************************************//** + * @brief Binary Table HDU Constructor + * + * @param[in] table Table from which the HDU should be constructed + ***************************************************************************/ +GFitsHDU::GFitsHDU(const GFitsBinTable& table) +{ + // Initialise class members for clean destruction + init_members(); + + // Copy table into HDU data and set data type + m_data = table.clone(); + m_type = HT_BIN_TABLE; + + // Allocate new header + m_header = new GFitsHeader(); + + // Set image header keywords + /* + m_header->update(GFitsHeaderCard("XTENSION", "'BINTABLE'", + "binary table extension")); + m_header->update(GFitsHeaderCard("BITPIX", 8, + "8-bit bytes")); + m_header->update(GFitsHeaderCard("NAXIS", 2, + "2-dimensional binary table")); + m_header->update(GFitsHeaderCard("NAXIS1", 0, + "width of table in bytes")); + m_header->update(GFitsHeaderCard("NAXIS2", table.rows(), + "number of rows in table")); + m_header->update(GFitsHeaderCard("PCOUNT", 0, + "size of special data area")); + m_header->update(GFitsHeaderCard("GCOUNT", 1, + "one data group (required keyword)")); + m_header->update(GFitsHeaderCard("TFIELDS", 1, + "number of fields in each row")); +*/ + // Return + return; +} + + +/***********************************************************************//** * @brief Copy constructor * - * @param hdu HDU from which the instance should be constructed + * @param[in] hdu HDU from which the instance should be constructed ***************************************************************************/ GFitsHDU::GFitsHDU(const GFitsHDU& hdu) { @@ -138,7 +226,7 @@ GFitsHDU::~GFitsHDU() /***********************************************************************//** * @brief Assignment operator * - * @param hdu HDU which should be assigned + * @param[in] hdu HDU which should be assigned ***************************************************************************/ GFitsHDU& GFitsHDU::operator= (const GFitsHDU& hdu) { @@ -170,8 +258,8 @@ GFitsHDU& GFitsHDU::operator= (const GFitsHDU& hdu) /***********************************************************************//** * @brief Open HDU * - * @param fptr FITS file pointer - * @param hdunum Number of HDU (starting from 1) + * @param[in] fptr FITS file pointer + * @param[in] hdunum Number of HDU (starting from 1) * * Opens an (existing) HDU in the FITS file. This method does NOT create any * HDU if it does not exist. Opening consists of fetching all header cards @@ -204,13 +292,13 @@ void GFitsHDU::open(__fitsfile* fptr, int hdunum) // Open HDU data area if (m_data != NULL) delete m_data; switch (m_type) { - case 0: // Image HDU + case HT_IMAGE: // Image HDU m_data = new_image(); break; - case 1: // ASCII Table HDU + case HT_ASCII_TABLE: // ASCII Table HDU m_data = new GFitsAsciiTable(); break; - case 2: // Binary Table HDU + case HT_BIN_TABLE: // Binary Table HDU m_data = new GFitsBinTable(); break; default: @@ -251,30 +339,31 @@ void GFitsHDU::save(void) { //cout << "GFitsHDU::save " << m_fitsfile.Fptr << " " << m_hdunum << endl; // Move to HDU - int status = 0; - status = __ffmahd(&m_fitsfile, m_hdunum, NULL, &status); +// int status = 0; +// status = __ffmahd(&m_fitsfile, m_hdunum, NULL, &status); // If HDU does not yet exist in file then create it now. This works even // in the case that the actual HDU has no associated header and/or data // (these will be created automatically). However, to make this work we have // to set the fitsfile HDU position to the position we want to go. In that // was the save members will know that they have to create the HDU ... +/* if (status == 107) { m_fitsfile.HDUposition = m_hdunum-1; - status = 0; + status = 0; if (m_data != NULL) { switch (m_type) { - case 0: // Image HDU + case HT_IMAGE: // Image HDU m_data->connect(&m_fitsfile); - m_data->save(); + //m_data->save(); break; - case 1: // ASCII Table HDU + case HT_ASCII_TABLE: // ASCII Table HDU m_data->connect(&m_fitsfile); - m_data->save(); + //m_data->save(); break; - case 2: // Binary Table HDU + case HT_BIN_TABLE: // Binary Table HDU m_data->connect(&m_fitsfile); - m_data->save(); + //m_data->save(); break; default: throw GException::fits_unknown_HDU_type(G_SAVE, m_type); @@ -282,9 +371,11 @@ void GFitsHDU::save(void) } } } +*/ - // If they exist then save data and header + // Save data and header if they exist if (m_data != NULL) { + m_data->connect(&m_fitsfile); m_data->save(); if (m_header != NULL) m_header->save(&m_fitsfile); @@ -297,7 +388,8 @@ void GFitsHDU::save(void) // Special case: The first HDU does not exist. A FITS file needs at least // one primary HDU. Thus an empty image is created. if (m_fitsfile.HDUposition == 0) { - status = __ffcrim(&m_fitsfile, 8, 0, NULL, &status); + int status = 0; + status = __ffcrim(&m_fitsfile, 8, 0, NULL, &status); if (status != 0) throw GException::fits_error(G_SAVE, status); if (m_header != NULL) @@ -314,7 +406,7 @@ void GFitsHDU::save(void) /***********************************************************************//** * @brief Set HDU extension name (EXTNAME keyword) * - * @param extname Name of HDU + * @param[in] extname Name of HDU * * This methos sets the extension name of the HDU. The extension name will * be saved in the 'EXTNAME' header keyword. The header attached to the @@ -340,7 +432,7 @@ void GFitsHDU::extname(const std::string& extname) /***********************************************************************//** * @brief Return pointer to column of table * - * @param colname Name of FITS table column to be returned + * @param[in] colname Name of FITS table column to be returned * * If this method is called for an image a 'fits_HDU_not_a_table' exception * will be thrown. @@ -352,13 +444,13 @@ GFitsTableCol* GFitsHDU::column(const std::string& colname) const // Get pointer to table column switch (m_type) { - case 0: // Image HDU + case HT_IMAGE: // Image HDU throw GException::fits_HDU_not_a_table(G_COLUMN, m_type); break; - case 1: // ASCII Table HDU + case HT_ASCII_TABLE: // ASCII Table HDU ptr = ((GFitsAsciiTable*)this->data())->column(colname); break; - case 2: // Binary Table HDU + case HT_BIN_TABLE: // Binary Table HDU ptr = ((GFitsBinTable*)this->data())->column(colname); break; default: @@ -427,7 +519,7 @@ void GFitsHDU::init_members(void) /***********************************************************************//** * @brief Copy class members * - * @param hdu HDU to be copied + * @param[in] hdu HDU to be copied * * Assumes that all memory has been freed correctly before calling. ***************************************************************************/ @@ -467,7 +559,7 @@ void GFitsHDU::free_members(void) /***********************************************************************//** * @brief Connect HDU to FITS file * - * @param fptr FITS file pointer to which the HDU should be connected + * @param[in] fptr FITS file pointer to which the HDU should be connected * * Connects the HDU and the associated data area to the specified FITS file. * Note that the header area does not require a FITS pointer, hence no @@ -553,8 +645,8 @@ GFitsImage* GFitsHDU::new_image(void) /***********************************************************************//** * @brief Output operator * - * @param os Output stream into which the HDU will be dumped - * @param hdu HDU to be dumped + * @param[in] os Output stream into which the HDU will be dumped + * @param[in] hdu HDU to be dumped ***************************************************************************/ ostream& operator<< (ostream& os, const GFitsHDU& hdu) { @@ -585,13 +677,13 @@ ostream& operator<< (ostream& os, const GFitsHDU& hdu) // Put FITS data in stream if (hdu.m_data != NULL) { switch (hdu.m_type) { - case 0: // Image HDU + case HT_IMAGE: // Image HDU os << *(GFitsImage*)hdu.m_data; break; - case 1: // ASCII Table HDU + case HT_ASCII_TABLE: // ASCII Table HDU os << *(GFitsAsciiTable*)hdu.m_data; break; - case 2: // Binary Table HDU + case HT_BIN_TABLE: // Binary Table HDU os << *(GFitsBinTable*)hdu.m_data; break; default: diff --git a/src/fits/GFitsHeaderCard.cpp b/src/fits/GFitsHeaderCard.cpp index 7e31cd0..996574b 100644 --- a/src/fits/GFitsHeaderCard.cpp +++ b/src/fits/GFitsHeaderCard.cpp @@ -243,7 +243,7 @@ void GFitsHeaderCard::value(const std::string& value) if (m_value[m_value.length()-1] != '\x27') m_value += "'"; } - + // Return return; } @@ -598,10 +598,12 @@ void GFitsHeaderCard::write(__fitsfile* fptr) (char*)m_comment.c_str(), &status); break; case CT_COMMENT: - status = __ffpcom(fptr, (char*)m_comment.c_str(), &status); + if (m_comment_write) + status = __ffpcom(fptr, (char*)m_comment.c_str(), &status); break; case CT_HISTORY: - status = __ffphis(fptr, (char*)m_comment.c_str(), &status); + if (m_comment_write) + status = __ffphis(fptr, (char*)m_comment.c_str(), &status); break; default: break; @@ -632,6 +634,7 @@ void GFitsHeaderCard::init_members(void) m_value_decimals = 10; m_unit.clear(); m_comment.clear(); + m_comment_write = 0; // Return return; @@ -652,6 +655,7 @@ void GFitsHeaderCard::copy_members(const GFitsHeaderCard& card) m_value_decimals = card.m_value_decimals; m_unit = card.m_unit; m_comment = card.m_comment; + m_comment_write = card.m_comment_write; // Return return; diff --git a/src/fits/GFitsImage.cpp b/src/fits/GFitsImage.cpp index c7e6d35..ff05b73 100644 --- a/src/fits/GFitsImage.cpp +++ b/src/fits/GFitsImage.cpp @@ -273,21 +273,6 @@ void GFitsImage::free_members(void) /***********************************************************************//** - * @brief Connect image to FITS file - * - * @param[in] fptr FITS file pointer to which the image should be connected - ***************************************************************************/ -void GFitsImage::connect(__fitsfile* fptr) -{ - // Connect Image - m_fitsfile = *fptr; - - // Return - return; -} - - -/***********************************************************************//** * @brief Open Image * * @param[in] fptr FITS file pointer diff --git a/src/fits/GFitsTable.cpp b/src/fits/GFitsTable.cpp new file mode 100644 index 0000000..f0b1c4c --- /dev/null +++ b/src/fits/GFitsTable.cpp @@ -0,0 +1,661 @@ +/*************************************************************************** + * GFitsTable.cpp - FITS table base class * + * ----------------------------------------------------------------------- * + * copyright : (C) 2008 by Jurgen Knodlseder * + * ----------------------------------------------------------------------- * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * ----------------------------------------------------------------------- * + ***************************************************************************/ + +/* __ Includes ___________________________________________________________ */ +#include +#include "GException.hpp" +#include "GTools.hpp" +#include "GFitsTable.hpp" +#include "GFitsTableStrCol.hpp" +#include "GFitsTableShtCol.hpp" +#include "GFitsTableLngCol.hpp" +#include "GFitsTableFltCol.hpp" +#include "GFitsTableDblCol.hpp" + +/* __ Namespaces _________________________________________________________ */ + +/* __ Method name definitions ____________________________________________ */ +#define G_OPEN "GFitsTable::open(fitsfile*)" +#define G_SAVE "GFitsTable::save()" +#define G_COLUMN1 "GFitsTable::column(const std::string&)" +#define G_COLUMN2 "GFitsTable::column(const int&)" + +/* __ Macros _____________________________________________________________ */ + +/* __ Coding definitions _________________________________________________ */ + +/* __ Debug definitions __________________________________________________ */ + + +/*========================================================================== + = = + = GFitsTable constructors/destructors = + = = + ==========================================================================*/ + +/***********************************************************************//** + * @brief Constructor + ***************************************************************************/ +GFitsTable::GFitsTable() : GFitsData() +{ + // Initialise class members for clean destruction + init_members(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Constructor + * + * @param[in] nrows Number of rows in table + * @param[in] ncols Number of columns in table + ***************************************************************************/ +GFitsTable::GFitsTable(int nrows, int ncols) : GFitsData() +{ + // Initialise class members for clean destruction + init_members(); + + // Store table dimension + m_rows = nrows; + m_cols = ncols; + + // If there are columns then allocate memory for column pointers + if (m_cols > 0) { + + // Allocate pointer memory + m_columns = new GFitsTableCol*[m_cols]; + + // Initialise pointers + for (int i = 0; i < m_cols; ++i) + m_columns[i] = NULL; + + } // endfor: looped over all columns + + // Return + return; +} + + +/***********************************************************************//** + * @brief Copy constructor + * + * @param[in] table Table which will be used to construct GFitsTable instance + ***************************************************************************/ +GFitsTable::GFitsTable(const GFitsTable& table) : GFitsData(table) +{ + // Initialise class members for clean destruction + init_members(); + + // Copy members + copy_members(table); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Destructor + ***************************************************************************/ +GFitsTable::~GFitsTable() +{ + // Free members + free_members(); + + // Return + return; +} + + +/*========================================================================== + = = + = GFitsTable operators = + = = + ==========================================================================*/ + +/***********************************************************************//** + * @brief Assignment operator + * + * @param[in] table Table which will be assigned + ***************************************************************************/ +GFitsTable& GFitsTable::operator= (const GFitsTable& table) +{ + // Execute only if object is not identical + if (this != &table) { + + // Copy base class members + this->GFitsData::operator=(table); + + // Free members + free_members(); + + // Initialise private members for clean destruction + init_members(); + + // Copy members + copy_members(table); + + } // endif: object was not identical + + // Return this object + return *this; +} + + +/*========================================================================== + = = + = GFitsTable public methods = + = = + ==========================================================================*/ + +/***********************************************************************//** + * @brief Open Table + * + * @param[in] fptr FITS file pointer + * + * Builds a description of the binary table in memory. Columns are not loaded + * but column descriptors are allocated. The column data will only be loaded + * once it needs to be accessed. + ***************************************************************************/ +void GFitsTable::open(__fitsfile* fptr) +{ + // Move to HDU + int status = 0; + status = __ffmahd(fptr, (fptr->HDUposition)+1, NULL, &status); + if (status != 0) + throw GException::fits_error(G_OPEN, status); + + // Save FITS file pointer + m_fitsfile = *fptr; + + // Determine number of rows in table + long nrows = 0; + status = __ffgnrw(&m_fitsfile, &nrows, &status); + if (status != 0) + throw GException::fits_error(G_OPEN, status); + else + m_rows = (int)nrows; + + // Determine number of columns in table + status = __ffgncl(&m_fitsfile, &m_cols, &status); + if (status != 0) + throw GException::fits_error(G_OPEN, status); + + // Allocate memory for column pointers + if (m_columns != NULL) delete [] m_columns; + m_columns = new GFitsTableCol*[m_cols]; + + // Get table column information + int typecode = 0; + long repeat = 0; + long width = 0; + for (int i = 0; i < m_cols; ++i) { + + // Get column name + char keyname[10]; + char value[80]; + sprintf(keyname, "TTYPE%d", i+1); + status = __ffgkey(&m_fitsfile, keyname, value, NULL, &status); + if (status != 0) + throw GException::fits_error(G_OPEN, status); + value[strlen(value)-1] = '\0'; + + // Get column definition + status = __ffgtcl(&m_fitsfile, i+1, &typecode, &repeat, &width, &status); + if (status != 0) + throw GException::fits_error(G_OPEN, status); + + // Allocate column + switch (typecode) { + case __TSTRING: + m_columns[i] = new GFitsTableStrCol(); + break; + case __TSHORT: + m_columns[i] = new GFitsTableShtCol(); + break; + case __TLONG: + m_columns[i] = new GFitsTableLngCol(); + break; + case __TFLOAT: + m_columns[i] = new GFitsTableFltCol(); + break; + case __TDOUBLE: + m_columns[i] = new GFitsTableDblCol(); + break; + default: + throw GException::fits_unknown_coltype(G_OPEN, typecode); + break; + } + + // Store column definition + m_columns[i]->set_name(strip_whitespace(&(value[1]))); + m_columns[i]->set_colnum(i+1); + m_columns[i]->set_type(typecode); + m_columns[i]->set_repeat(repeat); + m_columns[i]->set_width(width); + m_columns[i]->set_length(m_rows); + m_columns[i]->set_fitsfile(fptr); + + } // endfor: looped over all columns + + // Return + return; +} + + +/***********************************************************************//** + * @brief Save FITS table + ***************************************************************************/ +void GFitsTable::save(void) +{ +//cout << "GFitsTable::save entry" << endl; + // Move to HDU + int status = 0; + status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status); + + // If HDU does not yet exist in file then create it now + if (status == 107) { + + // Reset status + status = 0; + + // Initialise number of fields + int tfields = 0; + + // Setup cfitsio column definition arrays + char** ttype = NULL; + char** tform = NULL; + char** tunit = NULL; + if (m_cols > 0) { + ttype = new char*[m_cols]; + tform = new char*[m_cols]; + tunit = new char*[m_cols]; + for (int i = 0; i < m_cols; ++i) { + ttype[i] = NULL; + tform[i] = NULL; + tunit[i] = NULL; + } + for (int i = 0; i < m_cols; ++i) { + ttype[tfields] = get_ttype(i); + tform[tfields] = get_tform(i); + tunit[tfields] = get_tunit(i); + if (ttype[tfields] != NULL && tform[tfields] != NULL && + tunit[tfields] != NULL) + tfields++; + } + } + + // Create FITS table + status = __ffcrtb(&m_fitsfile, m_type, m_rows, tfields, ttype, tform, + tunit, NULL, &status); + if (status != 0) + throw GException::fits_error(G_SAVE, status); + + // De-allocate column definition arrays + if (m_cols > 0) { + for (int i = 0; i < m_cols; ++i) { + if (ttype[i] != NULL) delete [] ttype[i]; + if (tform[i] != NULL) delete [] tform[i]; + if (tunit[i] != NULL) delete [] tunit[i]; + } + if (ttype != NULL) delete [] ttype; + if (ttype != NULL) delete [] tform; + if (ttype != NULL) delete [] tunit; + } + + } + else if (status != 0) + throw GException::fits_error(G_SAVE, status); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Close table + ***************************************************************************/ +void GFitsTable::close(void) +{ + // Free members + free_members(); + + // Initialise members + init_members(); + + // Return + return; +} + + +/***********************************************************************//** + * @brief Return pointer to column with specified name + * + * @param[in] colname Name of column which should be accessed + * + * @exception GException::fits_no_data + * There are no column data in the table or there is not data + * for this column + * @exception GException::fits_column_not_found + * Requested column has not been found in table. + ***************************************************************************/ +GFitsTableCol* GFitsTable::column(const std::string& colname) +{ + // If there is no data then throw an exception + if (m_columns == NULL) + throw GException::fits_no_data(G_COLUMN1, "No column data in table"); + + // Initialise pointer + GFitsTableCol* ptr = NULL; + + // If there are columns then search for the specified name + if (m_columns != NULL) { + for (int i = 0; i < m_cols; ++i) { + if (m_columns[i]->name() == colname) { + ptr = m_columns[i]; + if (ptr == NULL) + throw GException::fits_no_data(G_COLUMN1, + "No data for this column"); + break; + } + } + } + + // If column has not been found throw an exception + if (ptr == NULL) + throw GException::fits_column_not_found(G_COLUMN1, colname); + + // Return column pointer + return ptr; +} + + +/***********************************************************************//** + * @brief Return pointer to column with number + * + * @param[in] colnum Number of requested column (starting from 0) + * + * @exception GException::fits_no_data + * There are no column data in the table or there is not data + * for this column + * @exception GException::out_of_range + * Requested column has not been found in table. + ***************************************************************************/ +GFitsTableCol* GFitsTable::column(const int& colnum) +{ + // If there is no data then throw an exception + if (m_columns == NULL) + throw GException::fits_no_data(G_COLUMN2, "No column data in table"); + + // If column number is out of range then throw an exception + if (colnum < 0 || colnum >= m_cols) + throw GException::out_of_range(G_COLUMN2, colnum, 0, m_cols-1); + + // Get column pointer + GFitsTableCol* ptr = ptr = m_columns[colnum]; + if (ptr == NULL) + throw GException::fits_no_data(G_COLUMN2, "No data for this column"); + + // Return column pointer + return ptr; +} + + +/***********************************************************************//** + * @brief Return number of rows in table + ***************************************************************************/ +int GFitsTable::rows(void) const +{ + // Return number of rows + return m_rows; +} + + +/***********************************************************************//** + * @brief Return number of columns in table + ***************************************************************************/ +int GFitsTable::cols(void) const +{ + // Return number of columns + return m_cols; +} + + +/*========================================================================== + = = + = GFitsTable private methods = + = = + ==========================================================================*/ + +/***********************************************************************//** + * @brief Initialise class members + ***************************************************************************/ +void GFitsTable::init_members(void) +{ + // Initialise members + m_type = -1; + m_rows = 0; + m_cols = 0; + m_columns = NULL; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Copy class members + * + * @param[in] table Table to copy + ***************************************************************************/ +void GFitsTable::copy_members(const GFitsTable& table) +{ + // Copy attributes + m_type = table.m_type; + m_rows = table.m_rows; + m_cols = table.m_cols; + + // Copy column definition + if (table.m_columns != NULL && m_cols > 0) { + m_columns = new GFitsTableCol*[m_cols]; + for (int i = 0; i < m_cols; ++i) { + if (table.m_columns[i] != NULL) + m_columns[i] = table.m_columns[i]->clone(); + else + m_columns[i] = NULL; + } + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Delete class members + ***************************************************************************/ +void GFitsTable::free_members(void) +{ + // Free memory + for (int i = 0; i < m_cols; ++i) { + if (m_columns[i] != NULL) delete m_columns[i]; + } + if (m_columns != NULL) delete [] m_columns; + + // Mark memory as freed + m_columns = NULL; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Connect table to FITS file + * + * @param[in] fptr FITS file pointer to which the table should be connected + * + * The connection of the table is done by connecting all columns. + ***************************************************************************/ +void GFitsTable::connect(__fitsfile* fptr) +{ + // First connect binary table + m_fitsfile = *fptr; + + // Then connect all columns + if (m_columns != NULL) { + for (int i = 0; i < m_cols; ++i) { + if (m_columns[i] != NULL) m_columns[i]->connect(fptr); + } + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Returns pointer to column type + * + * @param[in] colnum Column number for which type is to be returned + * + * This methods allocates memory for the character string that holds the + * column type. The client has to de-allocate this memory after usage. + * In case that the column does not exist a NULL pointer is returned. + ***************************************************************************/ +char* GFitsTable::get_ttype(const int& colnum) const +{ + // Initialise result with NULL pointer + char* ptr = NULL; + + // Get type only if column exists + if (m_columns != NULL && colnum >=0 && colnum < m_cols && + m_columns[colnum] != NULL) { + int size = m_columns[colnum]->m_name.length() + 1; + ptr = new char[size]; + strncpy(ptr, m_columns[colnum]->m_name.c_str(), size-1); + } + + // Return result + return ptr; +} + + +/***********************************************************************//** + * @brief Returns pointer to column format + * + * @param[in] colnum Column number for which format is to be returned + * + * This methods allocates memory for the character string that holds the + * column format. The client has to de-allocate this memory after usage. + * In case that the column does not exist a NULL pointer is returned. + ***************************************************************************/ +char* GFitsTable::get_tform(const int& colnum) const +{ + // Initialise result with NULL pointer + char* ptr = NULL; + + // Get type only if column exists + if (m_columns != NULL && colnum >=0 && colnum < m_cols && + m_columns[colnum] != NULL) { + int size = m_columns[colnum]->m_format.length() + 1; + ptr = new char[size]; + strncpy(ptr, m_columns[colnum]->m_format.c_str(), size-1); + } + + // Return result + return ptr; +} + + +/***********************************************************************//** + * @brief Returns pointer to column unit + * + * @param[in] colnum Column number for which unit is to be returned + * + * This methods allocates memory for the character string that holds the + * column unit. The client has to de-allocate this memory after usage. + * In case that the column does not exist a NULL pointer is returned. + ***************************************************************************/ +char* GFitsTable::get_tunit(const int& colnum) const +{ + // Initialise result with NULL pointer + char* ptr = NULL; + + // Get type only if column exists + if (m_columns != NULL && colnum >=0 && colnum < m_cols && + m_columns[colnum] != NULL) { + int size = m_columns[colnum]->m_unit.length() + 1; + ptr = new char[size]; + strncpy(ptr, m_columns[colnum]->m_unit.c_str(), size-1); + } + + // Return result + return ptr; +} + + +/*========================================================================== + = = + = GFitsTable friends = + = = + ==========================================================================*/ + +/***********************************************************************//** + * @brief Output operator + * + * @param[in] os Output stream + * @param[in] table Table to put in output stream + ***************************************************************************/ +ostream& operator<< (ostream& os, const GFitsTable& table) +{ + // Put header in stream + os << "=== GFitsTable ===" << endl; + os << " Table type ................: "; + switch (table.m_type) { + case 1: + os << "ASCII table" << endl; + break; + case 2: + os << "Binary table" << endl; + break; + default: + os << "Unknown" << endl; + break; + } + os << " Number of rows ............: " << table.m_rows << endl; + os << " Number of columns .........: " << table.m_cols << endl; + if (table.m_columns != NULL) { + for (int i = 0; i < table.m_cols; ++i) { + if (table.m_columns[i] != NULL) + os << " " << *(table.m_columns[i]); + else + os << " column " << i << " undefined" << endl; + } + } + else + os << " table columns undefined" << endl; + + // Return output stream + return os; +} + + +/*========================================================================== + = = + = Other functions used by GFitsTable = + = = + ==========================================================================*/ diff --git a/src/fits/GFitsTableCol.cpp b/src/fits/GFitsTableCol.cpp index 58804b7..9dbab5f 100644 --- a/src/fits/GFitsTableCol.cpp +++ b/src/fits/GFitsTableCol.cpp @@ -131,6 +131,8 @@ void GFitsTableCol::init_members(void) { // Initialise members m_name.clear(); + m_format.clear(); + m_unit.clear(); m_colnum = 0; m_type = 0; m_repeat = 0; @@ -152,6 +154,8 @@ void GFitsTableCol::copy_members(const GFitsTableCol& column) { // Copy attributes m_name = column.m_name; + m_format = column.m_format; + m_unit = column.m_unit; m_colnum = column.m_colnum; m_type = column.m_type; m_repeat = column.m_repeat; diff --git a/test/test_GFits.cpp b/test/test_GFits.cpp index 7f5f848..1a3e192 100644 --- a/test/test_GFits.cpp +++ b/test/test_GFits.cpp @@ -335,7 +335,7 @@ void test_create(void) } GFitsHDU hdu(image); fits.append(&hdu); - cout << fits; + //cout << fits; fits.save(); } catch (exception &e) { @@ -370,6 +370,44 @@ void test_create(void) throw; } cout << "."; + + // Attach binary table + try { + GFits fits; + fits.open("test.fits"); + int nrows = 10; + int ncols = 5; + GFitsBinTable table(nrows,ncols); + GFitsHDU hdu(table); + fits.append(&hdu); + cout << fits; + fits.save(); + } + catch (exception &e) { + cout << endl << "TEST ERROR: Unable to attach binary table." << endl; + cout << e.what() << endl; + throw; + } + cout << "."; + + // Attach ASCII table + try { + GFits fits; + fits.open("test.fits"); + int nrows = 10; + int ncols = 5; + GFitsAsciiTable table(nrows,ncols); + GFitsHDU hdu(table); + fits.append(&hdu); + cout << fits; + fits.save(); + } + catch (exception &e) { + cout << endl << "TEST ERROR: Unable to attach ASCII table." << endl; + cout << e.what() << endl; + throw; + } + cout << "."; cout << ". ok." << endl; -- libgit2 0.21.4