Commit a235d9c77dcab8d0f86078045ff134e7ae2b3fd1

Authored by knodlseder
1 parent e729b089

enhance FITS table and table column interfaces

include/GException.hpp
@@ -195,6 +195,12 @@ public: @@ -195,6 +195,12 @@ public:
195 fits_unknown_coltype(string origin, int type); 195 fits_unknown_coltype(string origin, int type);
196 }; 196 };
197 197
  198 + // FITS bad column length
  199 + class fits_bad_col_length : public GExceptionHandler {
  200 + public:
  201 + fits_bad_col_length(string origin, int length, int rows);
  202 + };
  203 +
198 // FITS bad bitpix value 204 // FITS bad bitpix value
199 class fits_bad_bitpix : public GExceptionHandler { 205 class fits_bad_bitpix : public GExceptionHandler {
200 public: 206 public:
include/GFitsAsciiTable.hpp
@@ -37,7 +37,7 @@ class GFitsAsciiTable : public GFitsTable { @@ -37,7 +37,7 @@ class GFitsAsciiTable : public GFitsTable {
37 public: 37 public:
38 // Constructors and destructors 38 // Constructors and destructors
39 GFitsAsciiTable(); 39 GFitsAsciiTable();
40 - GFitsAsciiTable(int nrows, int ncols); 40 + GFitsAsciiTable(int nrows);
41 GFitsAsciiTable(const GFitsAsciiTable& table); 41 GFitsAsciiTable(const GFitsAsciiTable& table);
42 virtual ~GFitsAsciiTable(); 42 virtual ~GFitsAsciiTable();
43 43
include/GFitsBinTable.hpp
@@ -37,7 +37,7 @@ class GFitsBinTable : public GFitsTable { @@ -37,7 +37,7 @@ class GFitsBinTable : public GFitsTable {
37 public: 37 public:
38 // Constructors and destructors 38 // Constructors and destructors
39 GFitsBinTable(); 39 GFitsBinTable();
40 - GFitsBinTable(int nrows, int ncols); 40 + GFitsBinTable(int nrows);
41 GFitsBinTable(const GFitsBinTable& table); 41 GFitsBinTable(const GFitsBinTable& table);
42 virtual ~GFitsBinTable(); 42 virtual ~GFitsBinTable();
43 43
include/GFitsCfitsio.hpp
@@ -66,8 +66,8 @@ @@ -66,8 +66,8 @@
66 #define __TSHORT TSHORT 66 #define __TSHORT TSHORT
67 #define __TINT TINT 67 #define __TINT TINT
68 #define __TLONG TLONG 68 #define __TLONG TLONG
69 -#define __TLONGLONG TLONGLONG  
70 #define __TFLOAT TFLOAT 69 #define __TFLOAT TFLOAT
  70 +#define __TLONGLONG TLONGLONG
71 #define __TDOUBLE TDOUBLE 71 #define __TDOUBLE TDOUBLE
72 72
73 /* __ Type definition ____________________________________________________ */ 73 /* __ Type definition ____________________________________________________ */
@@ -116,8 +116,8 @@ typedef fitsfile __fitsfile; @@ -116,8 +116,8 @@ typedef fitsfile __fitsfile;
116 #define __TSHORT 21 116 #define __TSHORT 21
117 #define __TINT 31 117 #define __TINT 31
118 #define __TLONG 41 118 #define __TLONG 41
119 -#define __TLONGLONG 81  
120 #define __TFLOAT 42 119 #define __TFLOAT 42
  120 +#define __TLONGLONG 81
121 #define __TDOUBLE 82 121 #define __TDOUBLE 82
122 #define __TCOMPLEX 83 122 #define __TCOMPLEX 83
123 #define __TDBLCOMPLEX 163 123 #define __TDBLCOMPLEX 163
include/GFitsTable.hpp
@@ -34,6 +34,9 @@ @@ -34,6 +34,9 @@
34 * @class GFitsTable 34 * @class GFitsTable
35 * 35 *
36 * @brief Abstract interface for FITS table 36 * @brief Abstract interface for FITS table
  37 + *
  38 + * This class implements a FITS table. A FITS table is a collection of
  39 + * columns with an identical number of rows.
37 ***************************************************************************/ 40 ***************************************************************************/
38 class GFitsTable : public GFitsData { 41 class GFitsTable : public GFitsData {
39 42
@@ -43,7 +46,7 @@ class GFitsTable : public GFitsData { @@ -43,7 +46,7 @@ class GFitsTable : public GFitsData {
43 public: 46 public:
44 // Constructors and destructors 47 // Constructors and destructors
45 GFitsTable(); 48 GFitsTable();
46 - GFitsTable(int nrows, int ncols); 49 + GFitsTable(int nrows);
47 GFitsTable(const GFitsTable& table); 50 GFitsTable(const GFitsTable& table);
48 virtual ~GFitsTable(); 51 virtual ~GFitsTable();
49 52
@@ -55,10 +58,14 @@ public: @@ -55,10 +58,14 @@ public:
55 void save(void); 58 void save(void);
56 void close(void); 59 void close(void);
57 GFitsTable* clone(void) const = 0; 60 GFitsTable* clone(void) const = 0;
  61 + void append_column(GFitsTableCol* column);
  62 + void insert_column(int colnum, GFitsTableCol* column);
  63 + void append_rows(const int& nrows);
  64 + void insert_rows(const int& rownum, const int& nrows);
58 GFitsTableCol* column(const std::string& colname); 65 GFitsTableCol* column(const std::string& colname);
59 GFitsTableCol* column(const int& colnum); 66 GFitsTableCol* column(const int& colnum);
60 - int rows(void) const;  
61 - int cols(void) const; 67 + int nrows(void) const;
  68 + int ncols(void) const;
62 69
63 protected: 70 protected:
64 // Protected methods 71 // Protected methods
include/GFitsTableCol.hpp
@@ -10,6 +10,11 @@ @@ -10,6 +10,11 @@
10 * (at your option) any later version. * 10 * (at your option) any later version. *
11 * * 11 * *
12 ***************************************************************************/ 12 ***************************************************************************/
  13 +/**
  14 + * @file GFitsTableCol.hpp
  15 + * @brief GFitsTableCol class definition.
  16 + * @author J. Knodlseder
  17 + */
13 18
14 #ifndef GFITSTABLECOL_HPP 19 #ifndef GFITSTABLECOL_HPP
15 #define GFITSTABLECOL_HPP 20 #define GFITSTABLECOL_HPP
@@ -20,14 +25,18 @@ @@ -20,14 +25,18 @@
20 /* __ Namespaces _________________________________________________________ */ 25 /* __ Namespaces _________________________________________________________ */
21 26
22 27
23 -/***************************************************************************  
24 - * GFitsTableCol class definition * 28 +/***********************************************************************//**
  29 + * @class GFitsTableCol
  30 + *
  31 + * @brief Abstract interface for FITS table column
  32 + *
  33 + * This class implements a FITS table column.
25 ***************************************************************************/ 34 ***************************************************************************/
26 class GFitsTableCol { 35 class GFitsTableCol {
27 36
28 // Friend classes 37 // Friend classes
29 friend class GFitsTable; 38 friend class GFitsTable;
30 - 39 +
31 // I/O friends 40 // I/O friends
32 friend ostream& operator<< (ostream& os, const GFitsTableCol& column); 41 friend ostream& operator<< (ostream& os, const GFitsTableCol& column);
33 42
@@ -52,13 +61,12 @@ public: @@ -52,13 +61,12 @@ public:
52 virtual int* ptr_int(void) = 0; 61 virtual int* ptr_int(void) = 0;
53 62
54 // Base class Methods 63 // Base class Methods
55 - void set_name(const std::string name);  
56 - void set_colnum(const int colnum);  
57 - void set_type(const int type);  
58 - void set_repeat(const int repeat);  
59 - void set_width(const int width);  
60 - void set_length(const int length);  
61 - void set_fitsfile(const __fitsfile* fptr); 64 + void name(const std::string& name);
  65 + //void colnum(const int& colnum); //!< DO WE REALLY NEED THIS???
  66 + //void type(const int& type); //!< DO WE REALLY NEED THIS???
  67 + //void repeat(const int repeat); //!< DO WE REALLY NEED THIS???
  68 + //void width(const int width); //!< DO WE REALLY NEED THIS???
  69 + //void length(const int& length); //!< DO WE REALLY NEED THIS???
62 std::string name(void); 70 std::string name(void);
63 int colnum(void); 71 int colnum(void);
64 int type(void); 72 int type(void);
@@ -71,7 +79,7 @@ protected: @@ -71,7 +79,7 @@ protected:
71 std::string m_name; //!< Column name 79 std::string m_name; //!< Column name
72 std::string m_format; //!< Column format 80 std::string m_format; //!< Column format
73 std::string m_unit; //!< Column unit 81 std::string m_unit; //!< Column unit
74 - int m_colnum; //!< Column number 82 + int m_colnum; //!< Column number (starting from 1)
75 int m_type; //!< Column type 83 int m_type; //!< Column type
76 int m_repeat; //!< Repeat value of column 84 int m_repeat; //!< Repeat value of column
77 int m_width; //!< Width of column 85 int m_width; //!< Width of column
@@ -90,18 +98,5 @@ private: @@ -90,18 +98,5 @@ private:
90 /*************************************************************************** 98 /***************************************************************************
91 * Inline methods * 99 * Inline methods *
92 ***************************************************************************/ 100 ***************************************************************************/
93 -inline void GFitsTableCol::set_name(const std::string name) { m_name = name; }  
94 -inline void GFitsTableCol::set_colnum(const int colnum) { m_colnum = colnum; }  
95 -inline void GFitsTableCol::set_type(const int type) { m_type = type; }  
96 -inline void GFitsTableCol::set_repeat(const int repeat) { m_repeat = repeat; }  
97 -inline void GFitsTableCol::set_width(const int width) { m_width = width; }  
98 -inline void GFitsTableCol::set_length(const int length) { m_length = length; }  
99 -inline void GFitsTableCol::set_fitsfile(const __fitsfile* fptr) { m_fitsfile = *fptr; }  
100 -inline std::string GFitsTableCol::name(void) { return m_name; }  
101 -inline int GFitsTableCol::colnum(void) { return m_colnum; }  
102 -inline int GFitsTableCol::type(void) { return m_type; }  
103 -inline int GFitsTableCol::repeat(void) { return m_repeat; }  
104 -inline int GFitsTableCol::width(void) { return m_width; }  
105 -inline int GFitsTableCol::length(void) { return m_length; }  
106 101
107 #endif /* GFITSTABLECOL_HPP */ 102 #endif /* GFITSTABLECOL_HPP */
src/GException.cpp
@@ -409,6 +409,24 @@ GException::fits_unknown_coltype::fits_unknown_coltype(string origin, @@ -409,6 +409,24 @@ GException::fits_unknown_coltype::fits_unknown_coltype(string origin,
409 409
410 410
411 /***********************************************************************//** 411 /***********************************************************************//**
  412 + * @brief FITS error: Bad column length
  413 + *
  414 + * @param[in] origin Method that throws the error.
  415 + * @param[in] length Length of the column.
  416 + * @param[in] rows Number of rows in table.
  417 + ***************************************************************************/
  418 +GException::fits_bad_col_length::fits_bad_col_length(string origin,
  419 + int length,
  420 + int rows)
  421 +{
  422 + m_origin = origin;
  423 + m_message = "Column length '" + str(length) + "' is not compatible"
  424 + " with the number of rows '" + str(rows) + "' in the"
  425 + " table";
  426 +}
  427 +
  428 +
  429 +/***********************************************************************//**
412 * @brief FITS error: invalid number of bits per pixel 430 * @brief FITS error: invalid number of bits per pixel
413 * 431 *
414 * @param[in] origin Method that throws the error. 432 * @param[in] origin Method that throws the error.
src/fits/GFitsAsciiTable.cpp
@@ -59,7 +59,7 @@ GFitsAsciiTable::GFitsAsciiTable() : GFitsTable() @@ -59,7 +59,7 @@ GFitsAsciiTable::GFitsAsciiTable() : GFitsTable()
59 * @param[in] nrows Number of rows in table 59 * @param[in] nrows Number of rows in table
60 * @param[in] ncols Number of columns in table 60 * @param[in] ncols Number of columns in table
61 ***************************************************************************/ 61 ***************************************************************************/
62 -GFitsAsciiTable::GFitsAsciiTable(int nrows, int ncols) : GFitsTable(nrows, ncols) 62 +GFitsAsciiTable::GFitsAsciiTable(int nrows) : GFitsTable(nrows)
63 { 63 {
64 // Initialise class members for clean destruction 64 // Initialise class members for clean destruction
65 init_members(); 65 init_members();
src/fits/GFitsBinTable.cpp
@@ -59,7 +59,7 @@ GFitsBinTable::GFitsBinTable() : GFitsTable() @@ -59,7 +59,7 @@ GFitsBinTable::GFitsBinTable() : GFitsTable()
59 * @param[in] nrows Number of rows in table 59 * @param[in] nrows Number of rows in table
60 * @param[in] ncols Number of columns in table 60 * @param[in] ncols Number of columns in table
61 ***************************************************************************/ 61 ***************************************************************************/
62 -GFitsBinTable::GFitsBinTable(int nrows, int ncols) : GFitsTable(nrows, ncols) 62 +GFitsBinTable::GFitsBinTable(int nrows) : GFitsTable(nrows)
63 { 63 {
64 // Initialise class members for clean destruction 64 // Initialise class members for clean destruction
65 init_members(); 65 init_members();
src/fits/GFitsHDU.cpp
@@ -385,8 +385,8 @@ void GFitsHDU::save(void) @@ -385,8 +385,8 @@ void GFitsHDU::save(void)
385 // image. 385 // image.
386 else { 386 else {
387 387
388 - // Special case: The first HDU does not exist. A FITS file needs at least  
389 - // one primary HDU. Thus an empty image is created. 388 + // Special case: The first HDU does not exist. A FITS file needs at
  389 + // least one primary HDU. Thus an empty image is created.
390 if (m_fitsfile.HDUposition == 0) { 390 if (m_fitsfile.HDUposition == 0) {
391 int status = 0; 391 int status = 0;
392 status = __ffcrim(&m_fitsfile, 8, 0, NULL, &status); 392 status = __ffcrim(&m_fitsfile, 8, 0, NULL, &status);
src/fits/GFitsTable.cpp
@@ -26,10 +26,12 @@ @@ -26,10 +26,12 @@
26 /* __ Namespaces _________________________________________________________ */ 26 /* __ Namespaces _________________________________________________________ */
27 27
28 /* __ Method name definitions ____________________________________________ */ 28 /* __ Method name definitions ____________________________________________ */
29 -#define G_OPEN "GFitsTable::open(fitsfile*)"  
30 -#define G_SAVE "GFitsTable::save()"  
31 -#define G_COLUMN1 "GFitsTable::column(const std::string&)"  
32 -#define G_COLUMN2 "GFitsTable::column(const int&)" 29 +#define G_OPEN "GFitsTable::open(fitsfile*)"
  30 +#define G_SAVE "GFitsTable::save()"
  31 +#define G_APPEND_COLUMN "GFitsTable::append_column(GFitsTableCol*)"
  32 +#define G_INSERT_COLUMN "GFitsTable::insert_column(int, GFitsTableCol*)"
  33 +#define G_COLUMN1 "GFitsTable::column(const std::string&)"
  34 +#define G_COLUMN2 "GFitsTable::column(const int&)"
33 35
34 /* __ Macros _____________________________________________________________ */ 36 /* __ Macros _____________________________________________________________ */
35 37
@@ -46,6 +48,13 @@ @@ -46,6 +48,13 @@
46 48
47 /***********************************************************************//** 49 /***********************************************************************//**
48 * @brief Constructor 50 * @brief Constructor
  51 + *
  52 + * Construct an instance of GFitsTable with zero rows.
  53 + * Use the methods
  54 + * GFitsTable::append_column and GFitsTable::insert_column
  55 + * to add columns and
  56 + * GFitsTable::append_rows and GFitsTable::insert_rows
  57 + * to add rows to this table.
49 ***************************************************************************/ 58 ***************************************************************************/
50 GFitsTable::GFitsTable() : GFitsData() 59 GFitsTable::GFitsTable() : GFitsData()
51 { 60 {
@@ -61,28 +70,19 @@ GFitsTable::GFitsTable() : GFitsData() @@ -61,28 +70,19 @@ GFitsTable::GFitsTable() : GFitsData()
61 * @brief Constructor 70 * @brief Constructor
62 * 71 *
63 * @param[in] nrows Number of rows in table 72 * @param[in] nrows Number of rows in table
64 - * @param[in] ncols Number of columns in table 73 + *
  74 + * Construct an instance of GFitsTable with a given number of rows.
  75 + * Use the methods
  76 + * GFitsTable::append_column and GFitsTable::insert_column
  77 + * to add columns to this table.
65 ***************************************************************************/ 78 ***************************************************************************/
66 -GFitsTable::GFitsTable(int nrows, int ncols) : GFitsData() 79 +GFitsTable::GFitsTable(int nrows) : GFitsData()
67 { 80 {
68 // Initialise class members for clean destruction 81 // Initialise class members for clean destruction
69 init_members(); 82 init_members();
70 83
71 - // Store table dimension 84 + // Store numnber of rows
72 m_rows = nrows; 85 m_rows = nrows;
73 - m_cols = ncols;  
74 -  
75 - // If there are columns then allocate memory for column pointers  
76 - if (m_cols > 0) {  
77 -  
78 - // Allocate pointer memory  
79 - m_columns = new GFitsTableCol*[m_cols];  
80 -  
81 - // Initialise pointers  
82 - for (int i = 0; i < m_cols; ++i)  
83 - m_columns[i] = NULL;  
84 -  
85 - } // endfor: looped over all columns  
86 86
87 // Return 87 // Return
88 return; 88 return;
@@ -166,9 +166,9 @@ GFitsTable&amp; GFitsTable::operator= (const GFitsTable&amp; table) @@ -166,9 +166,9 @@ GFitsTable&amp; GFitsTable::operator= (const GFitsTable&amp; table)
166 * 166 *
167 * @param[in] fptr FITS file pointer 167 * @param[in] fptr FITS file pointer
168 * 168 *
169 - * Builds a description of the binary table in memory. Columns are not loaded  
170 - * but column descriptors are allocated. The column data will only be loaded  
171 - * once it needs to be accessed. 169 + * Builds a description of the table in memory.
  170 + * Columns are not loaded but column descriptors are allocated.
  171 + * The column data will only be loaded once it needs to be accessed.
172 ***************************************************************************/ 172 ***************************************************************************/
173 void GFitsTable::open(__fitsfile* fptr) 173 void GFitsTable::open(__fitsfile* fptr)
174 { 174 {
@@ -214,7 +214,8 @@ void GFitsTable::open(__fitsfile* fptr) @@ -214,7 +214,8 @@ void GFitsTable::open(__fitsfile* fptr)
214 value[strlen(value)-1] = '\0'; 214 value[strlen(value)-1] = '\0';
215 215
216 // Get column definition 216 // Get column definition
217 - status = __ffgtcl(&m_fitsfile, i+1, &typecode, &repeat, &width, &status); 217 + status = __ffgtcl(&m_fitsfile, i+1, &typecode, &repeat, &width,
  218 + &status);
218 if (status != 0) 219 if (status != 0)
219 throw GException::fits_error(G_OPEN, status); 220 throw GException::fits_error(G_OPEN, status);
220 221
@@ -241,13 +242,13 @@ void GFitsTable::open(__fitsfile* fptr) @@ -241,13 +242,13 @@ void GFitsTable::open(__fitsfile* fptr)
241 } 242 }
242 243
243 // Store column definition 244 // Store column definition
244 - m_columns[i]->set_name(strip_whitespace(&(value[1])));  
245 - m_columns[i]->set_colnum(i+1);  
246 - m_columns[i]->set_type(typecode);  
247 - m_columns[i]->set_repeat(repeat);  
248 - m_columns[i]->set_width(width);  
249 - m_columns[i]->set_length(m_rows);  
250 - m_columns[i]->set_fitsfile(fptr); 245 + m_columns[i]->name(strip_whitespace(&(value[1])));
  246 + m_columns[i]->m_colnum = i+1;
  247 + m_columns[i]->m_type = typecode;
  248 + m_columns[i]->m_repeat = repeat;
  249 + m_columns[i]->m_width = width;
  250 + m_columns[i]->m_length = m_rows;
  251 + m_columns[i]->connect(fptr);
251 252
252 } // endfor: looped over all columns 253 } // endfor: looped over all columns
253 254
@@ -264,14 +265,15 @@ void GFitsTable::save(void) @@ -264,14 +265,15 @@ void GFitsTable::save(void)
264 //cout << "GFitsTable::save entry" << endl; 265 //cout << "GFitsTable::save entry" << endl;
265 // Move to HDU 266 // Move to HDU
266 int status = 0; 267 int status = 0;
267 - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status); 268 + status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL,
  269 + &status);
268 270
269 // If HDU does not yet exist in file then create it now 271 // If HDU does not yet exist in file then create it now
270 if (status == 107) { 272 if (status == 107) {
271 - 273 +
272 // Reset status 274 // Reset status
273 status = 0; 275 status = 0;
274 - 276 +
275 // Initialise number of fields 277 // Initialise number of fields
276 int tfields = 0; 278 int tfields = 0;
277 279
@@ -297,13 +299,13 @@ void GFitsTable::save(void) @@ -297,13 +299,13 @@ void GFitsTable::save(void)
297 tfields++; 299 tfields++;
298 } 300 }
299 } 301 }
300 - 302 +
301 // Create FITS table 303 // Create FITS table
302 status = __ffcrtb(&m_fitsfile, m_type, m_rows, tfields, ttype, tform, 304 status = __ffcrtb(&m_fitsfile, m_type, m_rows, tfields, ttype, tform,
303 tunit, NULL, &status); 305 tunit, NULL, &status);
304 if (status != 0) 306 if (status != 0)
305 throw GException::fits_error(G_SAVE, status); 307 throw GException::fits_error(G_SAVE, status);
306 - 308 +
307 // De-allocate column definition arrays 309 // De-allocate column definition arrays
308 if (m_cols > 0) { 310 if (m_cols > 0) {
309 for (int i = 0; i < m_cols; ++i) { 311 for (int i = 0; i < m_cols; ++i) {
@@ -342,6 +344,128 @@ void GFitsTable::close(void) @@ -342,6 +344,128 @@ void GFitsTable::close(void)
342 344
343 345
344 /***********************************************************************//** 346 /***********************************************************************//**
  347 + * @brief Append column to the table
  348 + *
  349 + * @param[in] column Pointer to column which should be appended
  350 + *
  351 + * @exception GException::fits_no_data
  352 + * A NULL column pointer was passed to the method.
  353 + * This method requires a valid column pointer.
  354 + *
  355 + * A column will be appended at the end of the table. See
  356 + * GFitsTable::insert_column
  357 + * for more details on the method.
  358 + ***************************************************************************/
  359 +void GFitsTable::append_column(GFitsTableCol* column)
  360 +{
  361 + // Throw exception if column pointer is empty
  362 + if (column == NULL)
  363 + throw GException::fits_no_data(G_APPEND_COLUMN,
  364 + "Column pointer was NULL");
  365 +
  366 + // Inserting at the end correspond to appending
  367 + insert_column(m_cols, column);
  368 +
  369 + // Return
  370 + return;
  371 +}
  372 +
  373 +/***********************************************************************//**
  374 + * @brief Insert column into the table
  375 + *
  376 + * @param[in] colnum Column number to be inserted
  377 + * @param[in] column Pointer to column which should be inserted
  378 + *
  379 + * @exception GException::fits_no_data
  380 + * A NULL column pointer was passed to the method.
  381 + * This method requires a valid column pointer.
  382 + * @exception GException::fits_bad_col_length
  383 + * The length of the column is incompatible with the number of
  384 + * rows in the table.
  385 + *
  386 + * A column will be inserted at position 'colnum' of the table. If the
  387 + * position is beyond the end of the table the column will be appended.
  388 + * Any 'colnum' value smaller than 0 will be set automatically to 0.
  389 + *
  390 + * If the table is empty and has 0 rows, the number of rows will be set to
  391 + * the length of the column.
  392 + *
  393 + * The length of the column to be inserted has to be identical to the number
  394 + * of rows in the table.
  395 + ***************************************************************************/
  396 +void GFitsTable::insert_column(int colnum, GFitsTableCol* column)
  397 +{
  398 + // Throw exception if column pointer is empty
  399 + if (column == NULL)
  400 + throw GException::fits_no_data(G_INSERT_COLUMN,
  401 + "Column pointer was NULL");
  402 +
  403 + // Make sure that 'colnum' is valid. Since we add one column the total
  404 + // number of columns at return will be m_cols+1, hence the column
  405 + // index is comprised between [0,m_cols]
  406 + if (colnum < 0) colnum = 0;
  407 + if (colnum > m_cols) colnum = m_cols;
  408 +
  409 + // If the table is empty and has 0 rows then set the number of rows in
  410 + // the table to the length of the column
  411 + if (m_columns == NULL && m_rows == 0)
  412 + m_rows = column->length();
  413 +
  414 + // Throw exception if the column length is incompatible with number of
  415 + // rows in the table
  416 + if (m_rows != column->length())
  417 + throw GException::fits_bad_col_length(G_INSERT_COLUMN,
  418 + column->length(), m_rows);
  419 +
  420 + // If there are no rows in the table then set the number of rows to
  421 + // the length of the column
  422 + if (m_rows == 0 && column->length() > 0)
  423 + m_rows = column->length();
  424 +
  425 + // If no column data exist then allocate them now
  426 + if (m_columns == NULL) {
  427 + m_columns = new GFitsTableCol*[1];
  428 + m_cols = 1;
  429 + m_columns[0] = NULL;
  430 + colnum = 0; // We insert at the first place
  431 + }
  432 +
  433 + // ... otherwise make space to insert column
  434 + else {
  435 +
  436 + // Allocate fresh memory
  437 + GFitsTableCol** tmp = new GFitsTableCol*[m_cols+1];
  438 +
  439 + // Copy over old column pointers. Leave some space at the position
  440 + // where we want to insert the column
  441 + int src;
  442 + int dst;
  443 + for (src = 0, dst = 0; dst < m_cols+1; ++dst) {
  444 + if (dst == colnum)
  445 + tmp[dst] = NULL;
  446 + else {
  447 + tmp[dst] = m_columns[src];
  448 + src++;
  449 + }
  450 + }
  451 +
  452 + // Free old column pointer array
  453 + delete [] m_columns;
  454 +
  455 + // Connect new memory
  456 + m_columns = tmp;
  457 +
  458 + } // endelse: we made space to insert a column
  459 +
  460 + // Insert column pointer
  461 + m_columns[colnum] = column;
  462 +
  463 + // Return
  464 + return;
  465 +}
  466 +
  467 +
  468 +/***********************************************************************//**
345 * @brief Return pointer to column with specified name 469 * @brief Return pointer to column with specified name
346 * 470 *
347 * @param[in] colname Name of column which should be accessed 471 * @param[in] colname Name of column which should be accessed
@@ -417,7 +541,7 @@ GFitsTableCol* GFitsTable::column(const int&amp; colnum) @@ -417,7 +541,7 @@ GFitsTableCol* GFitsTable::column(const int&amp; colnum)
417 /***********************************************************************//** 541 /***********************************************************************//**
418 * @brief Return number of rows in table 542 * @brief Return number of rows in table
419 ***************************************************************************/ 543 ***************************************************************************/
420 -int GFitsTable::rows(void) const 544 +int GFitsTable::nrows(void) const
421 { 545 {
422 // Return number of rows 546 // Return number of rows
423 return m_rows; 547 return m_rows;
@@ -427,7 +551,7 @@ int GFitsTable::rows(void) const @@ -427,7 +551,7 @@ int GFitsTable::rows(void) const
427 /***********************************************************************//** 551 /***********************************************************************//**
428 * @brief Return number of columns in table 552 * @brief Return number of columns in table
429 ***************************************************************************/ 553 ***************************************************************************/
430 -int GFitsTable::cols(void) const 554 +int GFitsTable::ncols(void) const
431 { 555 {
432 // Return number of columns 556 // Return number of columns
433 return m_cols; 557 return m_cols;
src/fits/GFitsTableCol.cpp
@@ -34,9 +34,8 @@ @@ -34,9 +34,8 @@
34 = = 34 = =
35 ==========================================================================*/ 35 ==========================================================================*/
36 36
37 -/***************************************************************************  
38 - * Constructor *  
39 - * ----------------------------------------------------------------------- * 37 +/***********************************************************************//**
  38 + * @brief Constructor
40 ***************************************************************************/ 39 ***************************************************************************/
41 GFitsTableCol::GFitsTableCol() 40 GFitsTableCol::GFitsTableCol()
42 { 41 {
@@ -48,9 +47,10 @@ GFitsTableCol::GFitsTableCol() @@ -48,9 +47,10 @@ GFitsTableCol::GFitsTableCol()
48 } 47 }
49 48
50 49
51 -/***************************************************************************  
52 - * Copy constructor *  
53 - * ----------------------------------------------------------------------- * 50 +/***********************************************************************//**
  51 + * @brief Copy constructor
  52 + *
  53 + * @param[in] column Column from which the class instance should be built
54 ***************************************************************************/ 54 ***************************************************************************/
55 GFitsTableCol::GFitsTableCol(const GFitsTableCol& column) 55 GFitsTableCol::GFitsTableCol(const GFitsTableCol& column)
56 { 56 {
@@ -65,9 +65,8 @@ GFitsTableCol::GFitsTableCol(const GFitsTableCol&amp; column) @@ -65,9 +65,8 @@ GFitsTableCol::GFitsTableCol(const GFitsTableCol&amp; column)
65 } 65 }
66 66
67 67
68 -/***************************************************************************  
69 - * Destructor *  
70 - * ----------------------------------------------------------------------- * 68 +/***********************************************************************//**
  69 + * @brief Destructor
71 ***************************************************************************/ 70 ***************************************************************************/
72 GFitsTableCol::~GFitsTableCol() 71 GFitsTableCol::~GFitsTableCol()
73 { 72 {
@@ -85,24 +84,25 @@ GFitsTableCol::~GFitsTableCol() @@ -85,24 +84,25 @@ GFitsTableCol::~GFitsTableCol()
85 = = 84 = =
86 ==========================================================================*/ 85 ==========================================================================*/
87 86
88 -/***************************************************************************  
89 - * Assignment operator *  
90 - * ----------------------------------------------------------------------- * 87 +/***********************************************************************//**
  88 + * @brief Assignment operator
  89 + *
  90 + * @param[in] column Column which will be assigned
91 ***************************************************************************/ 91 ***************************************************************************/
92 GFitsTableCol& GFitsTableCol::operator= (const GFitsTableCol& column) 92 GFitsTableCol& GFitsTableCol::operator= (const GFitsTableCol& column)
93 { 93 {
94 // Execute only if object is not identical 94 // Execute only if object is not identical
95 if (this != &column) { 95 if (this != &column) {
96 - 96 +
97 // Free members 97 // Free members
98 free_members(); 98 free_members();
99 - 99 +
100 // Initialise private members for clean destruction 100 // Initialise private members for clean destruction
101 init_members(); 101 init_members();
102 102
103 // Copy members 103 // Copy members
104 copy_members(column); 104 copy_members(column);
105 - 105 +
106 } // endif: object was not identical 106 } // endif: object was not identical
107 107
108 // Return this object 108 // Return this object
@@ -116,6 +116,142 @@ GFitsTableCol&amp; GFitsTableCol::operator= (const GFitsTableCol&amp; column) @@ -116,6 +116,142 @@ GFitsTableCol&amp; GFitsTableCol::operator= (const GFitsTableCol&amp; column)
116 = = 116 = =
117 ==========================================================================*/ 117 ==========================================================================*/
118 118
  119 +/***********************************************************************//**
  120 + * @brief Set column name
  121 + *
  122 + * @param[in] name Name of the column.
  123 + ***************************************************************************/
  124 +void GFitsTableCol::name(const std::string& name)
  125 +{
  126 + // Set name
  127 + m_name = name;
  128 +
  129 + // Return
  130 + return;
  131 +}
  132 +
  133 +
  134 +/***********************************************************************//**
  135 + * @brief Set column number
  136 + *
  137 + * @param[in] colnum Number of column.
  138 + ***************************************************************************/
  139 +/*
  140 +void GFitsTableCol::colnum(const int& colnum)
  141 +{
  142 + // Set column number
  143 + m_colnum = colnum;
  144 +
  145 + // Return
  146 + return;
  147 +}
  148 +*/
  149 +
  150 +/***********************************************************************//**
  151 + * @brief Set column type
  152 + *
  153 + * @param[in] type Type of column.
  154 + ***************************************************************************/
  155 +/*
  156 +void GFitsTableCol::type(const int& type)
  157 +{
  158 + // Set column type
  159 + m_type = type;
  160 +
  161 + // Return
  162 + return;
  163 +}
  164 +*/
  165 +
  166 +/***********************************************************************//**
  167 + * @brief Set column length
  168 + *
  169 + * @param[in] length Length of column.
  170 + ***************************************************************************/
  171 +/*
  172 +void GFitsTableCol::length(const int& length)
  173 +{
  174 + // Set column length
  175 + m_length = length;
  176 +
  177 + // Return
  178 + return;
  179 +}
  180 +*/
  181 +
  182 +/***********************************************************************//**
  183 + * @brief Get column name
  184 + ***************************************************************************/
  185 +std::string GFitsTableCol::name(void)
  186 +{
  187 + // Return Name
  188 + return m_name;
  189 +}
  190 +
  191 +
  192 +/***********************************************************************//**
  193 + * @brief Get number of column in FITS file (starting from 1)
  194 + ***************************************************************************/
  195 +int GFitsTableCol::colnum(void)
  196 +{
  197 + // Return column number
  198 + return m_colnum;
  199 +}
  200 +
  201 +
  202 +/***********************************************************************//**
  203 + * @brief Get CFITSIO column type
  204 + *
  205 + * Returns one of the following:
  206 + * 1 (TBIT)
  207 + * 11 (TBYTE)
  208 + * 14 (TLOGICAL)
  209 + * 16 (TSTRING)
  210 + * 21 (TSHORT)
  211 + * 31 (TINT)
  212 + * 41 (TLONG)
  213 + * 42 (TFLOAT)
  214 + * 81 (TLONGLONG)
  215 + * 82 (TDOUBLE)
  216 + * 83 (TCOMPLEX)
  217 + * 163 (TDBLCOMPLEX)
  218 + ***************************************************************************/
  219 +int GFitsTableCol::type(void)
  220 +{
  221 + // Return column type
  222 + return m_type;
  223 +}
  224 +
  225 +
  226 +/***********************************************************************//**
  227 + * @brief Get column repeat value
  228 + ***************************************************************************/
  229 +int GFitsTableCol::repeat(void)
  230 +{
  231 + // Return column repeat value
  232 + return m_repeat;
  233 +}
  234 +
  235 +
  236 +/***********************************************************************//**
  237 + * @brief Get column width
  238 + ***************************************************************************/
  239 +int GFitsTableCol::width(void)
  240 +{
  241 + // Return column width
  242 + return m_width;
  243 +}
  244 +
  245 +
  246 +/***********************************************************************//**
  247 + * @brief Get column length
  248 + ***************************************************************************/
  249 +int GFitsTableCol::length(void)
  250 +{
  251 + // Return column length
  252 + return m_length;
  253 +}
  254 +
119 255
120 /*========================================================================== 256 /*==========================================================================
121 = = 257 = =
@@ -123,9 +259,8 @@ GFitsTableCol&amp; GFitsTableCol::operator= (const GFitsTableCol&amp; column) @@ -123,9 +259,8 @@ GFitsTableCol&amp; GFitsTableCol::operator= (const GFitsTableCol&amp; column)
123 = = 259 = =
124 ==========================================================================*/ 260 ==========================================================================*/
125 261
126 -/***************************************************************************  
127 - * Initialise class members *  
128 - * ----------------------------------------------------------------------- * 262 +/***********************************************************************//**
  263 + * @brief Initialise class members
129 ***************************************************************************/ 264 ***************************************************************************/
130 void GFitsTableCol::init_members(void) 265 void GFitsTableCol::init_members(void)
131 { 266 {
@@ -146,9 +281,10 @@ void GFitsTableCol::init_members(void) @@ -146,9 +281,10 @@ void GFitsTableCol::init_members(void)
146 } 281 }
147 282
148 283
149 -/***************************************************************************  
150 - * Copy class members *  
151 - * ----------------------------------------------------------------------- * 284 +/***********************************************************************//**
  285 + * @brief Copy class members
  286 + *
  287 + * @param[in] column Column to be copied
152 ***************************************************************************/ 288 ***************************************************************************/
153 void GFitsTableCol::copy_members(const GFitsTableCol& column) 289 void GFitsTableCol::copy_members(const GFitsTableCol& column)
154 { 290 {
@@ -162,22 +298,21 @@ void GFitsTableCol::copy_members(const GFitsTableCol&amp; column) @@ -162,22 +298,21 @@ void GFitsTableCol::copy_members(const GFitsTableCol&amp; column)
162 m_width = column.m_width; 298 m_width = column.m_width;
163 m_length = column.m_length; 299 m_length = column.m_length;
164 m_fitsfile = column.m_fitsfile; 300 m_fitsfile = column.m_fitsfile;
165 - 301 +
166 // Return 302 // Return
167 return; 303 return;
168 } 304 }
169 305
170 306
171 -/***************************************************************************  
172 - * Delete class members *  
173 - * ----------------------------------------------------------------------- * 307 +/***********************************************************************//**
  308 + * @brief Delete class members
174 ***************************************************************************/ 309 ***************************************************************************/
175 void GFitsTableCol::free_members(void) 310 void GFitsTableCol::free_members(void)
176 { 311 {
177 // Free memory 312 // Free memory
178 - 313 +
179 // Mark memory as freed 314 // Mark memory as freed
180 - 315 +
181 // Return 316 // Return
182 return; 317 return;
183 } 318 }
@@ -186,13 +321,14 @@ void GFitsTableCol::free_members(void) @@ -186,13 +321,14 @@ void GFitsTableCol::free_members(void)
186 /***********************************************************************//** 321 /***********************************************************************//**
187 * @brief Connect table column to FITS file 322 * @brief Connect table column to FITS file
188 * 323 *
189 - * @param fptr FITS file pointer to which the table column should be connected 324 + * @param[in] fptr FITS file pointer to which the table column should be
  325 + * connected
190 ***************************************************************************/ 326 ***************************************************************************/
191 void GFitsTableCol::connect(__fitsfile* fptr) 327 void GFitsTableCol::connect(__fitsfile* fptr)
192 { 328 {
193 // Connect Image 329 // Connect Image
194 m_fitsfile = *fptr; 330 m_fitsfile = *fptr;
195 - 331 +
196 // Return 332 // Return
197 return; 333 return;
198 } 334 }
@@ -204,9 +340,11 @@ void GFitsTableCol::connect(__fitsfile* fptr) @@ -204,9 +340,11 @@ void GFitsTableCol::connect(__fitsfile* fptr)
204 = = 340 = =
205 ==========================================================================*/ 341 ==========================================================================*/
206 342
207 -/***************************************************************************  
208 - * Output operator *  
209 - * ----------------------------------------------------------------------- * 343 +/***********************************************************************//**
  344 + * @brief Output operator
  345 + *
  346 + * @param[in] os Output stream
  347 + * @param[in] column Column to put in output stream
210 ***************************************************************************/ 348 ***************************************************************************/
211 ostream& operator<< (ostream& os, const GFitsTableCol& column) 349 ostream& operator<< (ostream& os, const GFitsTableCol& column)
212 { 350 {
src/rsp/GLATResponse.cpp
@@ -264,22 +264,27 @@ void GLATResponse::save(const std::string&amp; rspname) const @@ -264,22 +264,27 @@ void GLATResponse::save(const std::string&amp; rspname) const
264 GFits fits; 264 GFits fits;
265 fits.open(rspname); 265 fits.open(rspname);
266 266
267 - // Build PSF HDUs  
268 - GFitsBinTable table_psf_bounds(1,4); 267 + // Build PSF tables and images
  268 + GFitsBinTable table_psf_bounds(1);
269 int naxes_psf2[] = {m_psf_energy_num, m_psf_ctheta_num}; 269 int naxes_psf2[] = {m_psf_energy_num, m_psf_ctheta_num};
270 - int naxes_psf3[] = {m_psf_angle_num, m_psf_energy_num, m_psf_ctheta_num}; 270 + int naxes_psf3[] = {m_psf_angle_num, m_psf_energy_num,
  271 + m_psf_ctheta_num};
271 GFitsDblImage image_psf_psf(3, naxes_psf3, m_psf); 272 GFitsDblImage image_psf_psf(3, naxes_psf3, m_psf);
272 GFitsDblImage image_psf_norm(2, naxes_psf2, m_norm); 273 GFitsDblImage image_psf_norm(2, naxes_psf2, m_norm);
273 GFitsDblImage image_psf_sigma(2, naxes_psf2, m_sigma); 274 GFitsDblImage image_psf_sigma(2, naxes_psf2, m_sigma);
274 - //TBD GFitsHDU hdu_psf_bounds(table_psf_bounds);  
275 - GFitsHDU hdu_psf_psf(image_psf_psf);  
276 - GFitsHDU hdu_psf_norm(image_psf_norm);  
277 - GFitsHDU hdu_psf_sigma(image_psf_sigma); 275 +
  276 + // Construct PSF HDUs
  277 + GFitsHDU hdu_psf_bounds(table_psf_bounds);
  278 + GFitsHDU hdu_psf_psf(image_psf_psf);
  279 + GFitsHDU hdu_psf_norm(image_psf_norm);
  280 + GFitsHDU hdu_psf_sigma(image_psf_sigma);
  281 + hdu_psf_bounds.extname("PBOUNDS");
278 hdu_psf_psf.extname("PSF"); 282 hdu_psf_psf.extname("PSF");
279 hdu_psf_norm.extname("NORM"); 283 hdu_psf_norm.extname("NORM");
280 hdu_psf_sigma.extname("SIGMA"); 284 hdu_psf_sigma.extname("SIGMA");
281 285
282 // Append HDUs to FITS file 286 // Append HDUs to FITS file
  287 + fits.append(&hdu_psf_bounds);
283 fits.append(&hdu_psf_psf); 288 fits.append(&hdu_psf_psf);
284 fits.append(&hdu_psf_norm); 289 fits.append(&hdu_psf_norm);
285 fits.append(&hdu_psf_sigma); 290 fits.append(&hdu_psf_sigma);
test/test_GFits.cpp
@@ -377,7 +377,7 @@ void test_create(void) @@ -377,7 +377,7 @@ void test_create(void)
377 fits.open("test.fits"); 377 fits.open("test.fits");
378 int nrows = 10; 378 int nrows = 10;
379 int ncols = 5; 379 int ncols = 5;
380 - GFitsBinTable table(nrows,ncols); 380 + GFitsBinTable table(nrows);
381 GFitsHDU hdu(table); 381 GFitsHDU hdu(table);
382 fits.append(&hdu); 382 fits.append(&hdu);
383 cout << fits; 383 cout << fits;
@@ -390,25 +390,6 @@ void test_create(void) @@ -390,25 +390,6 @@ void test_create(void)
390 } 390 }
391 cout << "."; 391 cout << ".";
392 392
393 - // Attach ASCII table  
394 - try {  
395 - GFits fits;  
396 - fits.open("test.fits");  
397 - int nrows = 10;  
398 - int ncols = 5;  
399 - GFitsAsciiTable table(nrows,ncols);  
400 - GFitsHDU hdu(table);  
401 - fits.append(&hdu);  
402 - cout << fits;  
403 - fits.save();  
404 - }  
405 - catch (exception &e) {  
406 - cout << endl << "TEST ERROR: Unable to attach ASCII table." << endl;  
407 - cout << e.what() << endl;  
408 - throw;  
409 - }  
410 - cout << ".";  
411 -  
412 393
413 cout << ". ok." << endl; 394 cout << ". ok." << endl;
414 } 395 }
@@ -421,7 +402,7 @@ void test_image_double(void) @@ -421,7 +402,7 @@ void test_image_double(void)
421 { 402 {
422 // Dump header 403 // Dump header
423 cout << "Test GFitsDblImage: "; 404 cout << "Test GFitsDblImage: ";
424 - 405 +
425 // Test 1D Image 406 // Test 1D Image
426 try { 407 try {
427 int naxis = 1; 408 int naxis = 1;
@@ -429,7 +410,7 @@ void test_image_double(void) @@ -429,7 +410,7 @@ void test_image_double(void)
429 int naxes[] = {nx}; 410 int naxes[] = {nx};
430 GFitsDblImage image(naxis, naxes); 411 GFitsDblImage image(naxis, naxes);
431 cout << "."; 412 cout << ".";
432 - 413 +
433 // Fill and read image 414 // Fill and read image
434 try { 415 try {
435 for (int ix = 0; ix < nx; ++ix) 416 for (int ix = 0; ix < nx; ++ix)