Commit d111479afe442f0b9439b4445ae0fcdd46676f6d
1 parent
3fb167e4
improve single precision column implementation and testing suite
Showing
5 changed files
with
396 additions
and
78 deletions
include/GFitsTableDblCol.hpp
| ... | ... | @@ -73,10 +73,10 @@ private: |
| 73 | 73 | std::string binary_format(void) const; |
| 74 | 74 | |
| 75 | 75 | // Private data area |
| 76 | - int m_size; //!< Size of allocated data area (0 if offline) | |
| 77 | - double* m_data; //!< Data area | |
| 78 | - double* m_nulval; //!< NULL value | |
| 79 | - int m_anynul; //!< Number of NULLs encountered | |
| 76 | + int m_size; //!< Size of allocated data area (0 if not loaded) | |
| 77 | + double* m_data; //!< Data area | |
| 78 | + double* m_nulval; //!< NULL value | |
| 79 | + int m_anynul; //!< Number of NULLs encountered | |
| 80 | 80 | }; |
| 81 | 81 | |
| 82 | 82 | #endif /* GFITSTABLEDBLCOL_HPP */ | ... | ... |
include/GFitsTableFltCol.hpp
| ... | ... | @@ -38,6 +38,9 @@ |
| 38 | 38 | ***************************************************************************/ |
| 39 | 39 | class GFitsTableFltCol : public GFitsTableCol { |
| 40 | 40 | |
| 41 | + // I/O friends | |
| 42 | + friend ostream& operator<< (ostream& os, const GFitsTableFltCol& column); | |
| 43 | + | |
| 41 | 44 | public: |
| 42 | 45 | // Constructors and destructors |
| 43 | 46 | GFitsTableFltCol(); |
| ... | ... | @@ -48,6 +51,8 @@ public: |
| 48 | 51 | |
| 49 | 52 | // Operators |
| 50 | 53 | GFitsTableFltCol& operator= (const GFitsTableFltCol& column); |
| 54 | + float& operator() (const int& row, const int& inx = 0); | |
| 55 | + const float& operator() (const int& row, const int& inx = 0) const; | |
| 51 | 56 | |
| 52 | 57 | // Methods |
| 53 | 58 | void save(void); |
| ... | ... | @@ -63,20 +68,15 @@ private: |
| 63 | 68 | void init_members(void); |
| 64 | 69 | void copy_members(const GFitsTableFltCol& column); |
| 65 | 70 | void free_members(void); |
| 66 | - void load(void); | |
| 71 | + void fetch_data(void); | |
| 67 | 72 | std::string ascii_format(void) const; |
| 68 | 73 | std::string binary_format(void) const; |
| 69 | 74 | |
| 70 | 75 | // Private data area |
| 71 | - int m_size; //!< Size of data area | |
| 72 | - float* m_data; //!< Data area | |
| 73 | - float* m_nulval; //!< NULL value | |
| 74 | - int m_anynul; //!< Number of NULLs encountered | |
| 76 | + int m_size; //!< Size of allocated data area (0 if not loaded) | |
| 77 | + float* m_data; //!< Data area | |
| 78 | + float* m_nulval; //!< NULL value | |
| 79 | + int m_anynul; //!< Number of NULLs encountered | |
| 75 | 80 | }; |
| 76 | 81 | |
| 77 | - | |
| 78 | -/*************************************************************************** | |
| 79 | - * Inline methods * | |
| 80 | - ***************************************************************************/ | |
| 81 | - | |
| 82 | 82 | #endif /* GFITSTABLEFLTCOL_HPP */ | ... | ... |
src/fits/GFitsTableDblCol.cpp
| ... | ... | @@ -78,8 +78,8 @@ GFitsTableDblCol::GFitsTableDblCol(const std::string& name, |
| 78 | 78 | * |
| 79 | 79 | * @param[in] column Column from which class instance should be built. |
| 80 | 80 | ***************************************************************************/ |
| 81 | -GFitsTableDblCol::GFitsTableDblCol(const GFitsTableDblCol& column) : | |
| 82 | - GFitsTableCol(column) | |
| 81 | +GFitsTableDblCol::GFitsTableDblCol(const GFitsTableDblCol& column) | |
| 82 | + : GFitsTableCol(column) | |
| 83 | 83 | { |
| 84 | 84 | // Initialise class members for clean destruction |
| 85 | 85 | init_members(); |
| ... | ... | @@ -159,7 +159,7 @@ double& GFitsTableDblCol::operator() (const int& row, const int& inx) |
| 159 | 159 | if (m_data == NULL) fetch_data(); |
| 160 | 160 | |
| 161 | 161 | // Calculate pixel offset |
| 162 | - int offset = row * m_repeat + inx; | |
| 162 | + int offset = row * m_number + inx; | |
| 163 | 163 | |
| 164 | 164 | // Return image pixel |
| 165 | 165 | return m_data[offset]; |
| ... | ... | @@ -180,13 +180,13 @@ double& GFitsTableDblCol::operator() (const int& row, const int& inx) |
| 180 | 180 | * if range checking is required. |
| 181 | 181 | ***************************************************************************/ |
| 182 | 182 | const double& GFitsTableDblCol::operator() (const int& row, const int& inx) |
| 183 | - const | |
| 183 | + const | |
| 184 | 184 | { |
| 185 | 185 | // If data are not available then load them now |
| 186 | 186 | if (m_data == NULL) ((GFitsTableDblCol*)this)->fetch_data(); |
| 187 | 187 | |
| 188 | 188 | // Calculate pixel offset |
| 189 | - int offset = row * m_repeat + inx; | |
| 189 | + int offset = row * m_number + inx; | |
| 190 | 190 | |
| 191 | 191 | // Return image pixel |
| 192 | 192 | return m_data[offset]; |
| ... | ... | @@ -262,7 +262,7 @@ std::string GFitsTableDblCol::string(const int& row, const int& inx) |
| 262 | 262 | throw GException::out_of_range(G_STRING, inx, 0, m_number-1); |
| 263 | 263 | |
| 264 | 264 | // Get index |
| 265 | - int offset = row * m_repeat + inx; | |
| 265 | + int offset = row * m_number + inx; | |
| 266 | 266 | |
| 267 | 267 | // Convert double into string |
| 268 | 268 | ostringstream s_value; |
| ... | ... | @@ -298,7 +298,7 @@ double GFitsTableDblCol::real(const int& row, const int& inx) |
| 298 | 298 | throw GException::out_of_range(G_REAL, inx, 0, m_number-1); |
| 299 | 299 | |
| 300 | 300 | // Get index |
| 301 | - int offset = row * m_repeat + inx; | |
| 301 | + int offset = row * m_number + inx; | |
| 302 | 302 | |
| 303 | 303 | // Return value |
| 304 | 304 | return m_data[offset]; |
| ... | ... | @@ -330,7 +330,7 @@ int GFitsTableDblCol::integer(const int& row, const int& inx) |
| 330 | 330 | throw GException::out_of_range(G_INTEGER, inx, 0, m_number-1); |
| 331 | 331 | |
| 332 | 332 | // Get index |
| 333 | - int offset = row * m_repeat + inx; | |
| 333 | + int offset = row * m_number + inx; | |
| 334 | 334 | |
| 335 | 335 | // Convert double into int |
| 336 | 336 | int value = (int)m_data[offset]; | ... | ... |
src/fits/GFitsTableFltCol.cpp
| ... | ... | @@ -25,12 +25,7 @@ |
| 25 | 25 | #define G_STRING "GFitsTableFltCol::string(const int&, const int&)" |
| 26 | 26 | #define G_REAL "GFitsTableFltCol::real(const int&, const int&)" |
| 27 | 27 | #define G_INTEGER "GFitsTableFltCol::integer(const int&, const int&)" |
| 28 | -#define G_PTR_FLOAT "GFitsTableFltCol::ptr_float()" | |
| 29 | -#define G_PTR_DOUBLE "GFitsTableFltCol::ptr_double()" | |
| 30 | -#define G_PTR_SHORT "GFitsTableFltCol::ptr_short()" | |
| 31 | -#define G_PTR_LONG "GFitsTableFltCol::ptr_long()" | |
| 32 | -#define G_PTR_INT "GFitsTableFltCol::ptr_int()" | |
| 33 | -#define G_LOAD "GFitsTableFltCol::load()" | |
| 28 | +#define G_FETCH_DATA "GFitsTableFltCol::fetch_data()" | |
| 34 | 29 | |
| 35 | 30 | /* __ Macros _____________________________________________________________ */ |
| 36 | 31 | |
| ... | ... | @@ -83,8 +78,8 @@ GFitsTableFltCol::GFitsTableFltCol(const std::string& name, |
| 83 | 78 | * |
| 84 | 79 | * @param[in] column Column from which class instance should be built. |
| 85 | 80 | ***************************************************************************/ |
| 86 | -GFitsTableFltCol::GFitsTableFltCol(const GFitsTableFltCol& column) : | |
| 87 | - GFitsTableCol(column) | |
| 81 | +GFitsTableFltCol::GFitsTableFltCol(const GFitsTableFltCol& column) | |
| 82 | + : GFitsTableCol(column) | |
| 88 | 83 | { |
| 89 | 84 | // Initialise class members for clean destruction |
| 90 | 85 | init_members(); |
| ... | ... | @@ -145,6 +140,59 @@ GFitsTableFltCol& GFitsTableFltCol::operator= (const GFitsTableFltCol& column) |
| 145 | 140 | } |
| 146 | 141 | |
| 147 | 142 | |
| 143 | +/***********************************************************************//** | |
| 144 | + * @brief Column data access operator | |
| 145 | + * | |
| 146 | + * @param[in] row Row of column to access. | |
| 147 | + * @param[in] inx Vector index in column row to access | |
| 148 | + * | |
| 149 | + * Provides access to data in a column. No range checking is performed. | |
| 150 | + * Use one of | |
| 151 | + * GFitsTableFltCol::string(ix,iy), | |
| 152 | + * GFitsTableFltCol::real(ix;iy) or | |
| 153 | + * GFitsTableFltCol::integer(ix;iy) | |
| 154 | + * if range checking is required. | |
| 155 | + ***************************************************************************/ | |
| 156 | +float& GFitsTableFltCol::operator() (const int& row, const int& inx) | |
| 157 | +{ | |
| 158 | + // If data are not available then load them now | |
| 159 | + if (m_data == NULL) fetch_data(); | |
| 160 | + | |
| 161 | + // Calculate pixel offset | |
| 162 | + int offset = row * m_number + inx; | |
| 163 | + | |
| 164 | + // Return image pixel | |
| 165 | + return m_data[offset]; | |
| 166 | +} | |
| 167 | + | |
| 168 | + | |
| 169 | +/***********************************************************************//** | |
| 170 | + * @brief Column data access operator (const variant) | |
| 171 | + * | |
| 172 | + * @param[in] row Row of column to access. | |
| 173 | + * @param[in] inx Vector index in column row to access | |
| 174 | + * | |
| 175 | + * Provides access to data in a column. No range checking is performed. | |
| 176 | + * Use one of | |
| 177 | + * GFitsTableFltCol::string(ix,iy), | |
| 178 | + * GFitsTableFltCol::real(ix;iy) or | |
| 179 | + * GFitsTableFltCol::integer(ix;iy) | |
| 180 | + * if range checking is required. | |
| 181 | + ***************************************************************************/ | |
| 182 | +const float& GFitsTableFltCol::operator() (const int& row, const int& inx) | |
| 183 | + const | |
| 184 | +{ | |
| 185 | + // If data are not available then load them now | |
| 186 | + if (m_data == NULL) ((GFitsTableFltCol*)this)->fetch_data(); | |
| 187 | + | |
| 188 | + // Calculate pixel offset | |
| 189 | + int offset = row * m_number + inx; | |
| 190 | + | |
| 191 | + // Return image pixel | |
| 192 | + return m_data[offset]; | |
| 193 | +} | |
| 194 | + | |
| 195 | + | |
| 148 | 196 | /*========================================================================== |
| 149 | 197 | = = |
| 150 | 198 | = GFitsTableFltCol public methods = |
| ... | ... | @@ -156,11 +204,17 @@ GFitsTableFltCol& GFitsTableFltCol::operator= (const GFitsTableFltCol& column) |
| 156 | 204 | * |
| 157 | 205 | * @exception GException::fits_hdu_not_found |
| 158 | 206 | * Specified HDU not found in FITS file. |
| 207 | + * @exception GException::fits_error | |
| 208 | + * Error occured during writing of the column data. | |
| 209 | + * | |
| 210 | + * The table column is only saved if it is linked to a FITS file and if the | |
| 211 | + * data are indeed present in the class instance. This avoids saving of data | |
| 212 | + * that have not been modified. | |
| 159 | 213 | ***************************************************************************/ |
| 160 | 214 | void GFitsTableFltCol::save(void) |
| 161 | 215 | { |
| 162 | - // Continue only if a FITS file is connected | |
| 163 | - if (m_fitsfile.Fptr != NULL) { | |
| 216 | + // Continue only if a FITS file is connected and data have been loaded | |
| 217 | + if (m_fitsfile.Fptr != NULL && m_colnum > 0 && m_data != NULL) { | |
| 164 | 218 | |
| 165 | 219 | // Move to the HDU |
| 166 | 220 | int status = 0; |
| ... | ... | @@ -170,9 +224,11 @@ void GFitsTableFltCol::save(void) |
| 170 | 224 | throw GException::fits_hdu_not_found(G_SAVE, |
| 171 | 225 | (m_fitsfile.HDUposition)+1, |
| 172 | 226 | status); |
| 173 | - | |
| 174 | 227 | // Save the column data |
| 175 | - // TBD | |
| 228 | + status = __ffpcn(&m_fitsfile, __TFLOAT, m_colnum, 1, 1, | |
| 229 | + (long)m_size, m_data, m_nulval, &status); | |
| 230 | + if (status != 0) | |
| 231 | + throw GException::fits_error(G_SAVE, status); | |
| 176 | 232 | |
| 177 | 233 | } // endif: FITS file was connected |
| 178 | 234 | |
| ... | ... | @@ -185,30 +241,32 @@ void GFitsTableFltCol::save(void) |
| 185 | 241 | * @brief Get string value |
| 186 | 242 | * |
| 187 | 243 | * @param[in] row Table row. |
| 188 | - * @param[in] col Table column vector index. | |
| 244 | + * @param[in] inx Table column vector index. | |
| 245 | + * | |
| 246 | + * @exception GException::out_of_range | |
| 247 | + * Table row or vector index are out of valid range. | |
| 189 | 248 | * |
| 190 | 249 | * Returns value of specified row and vector index as string. |
| 191 | 250 | ***************************************************************************/ |
| 192 | -std::string GFitsTableFltCol::string(const int& row, const int& col) | |
| 251 | +std::string GFitsTableFltCol::string(const int& row, const int& inx) | |
| 193 | 252 | { |
| 194 | - // Make sure that data are loaded | |
| 195 | - if (m_data == NULL) | |
| 196 | - load(); | |
| 253 | + // If data are not available then load them now | |
| 254 | + if (m_data == NULL) fetch_data(); | |
| 197 | 255 | |
| 198 | 256 | // Check row value |
| 199 | 257 | if (row < 0 || row >= m_length) |
| 200 | 258 | throw GException::out_of_range(G_STRING, row, 0, m_length-1); |
| 201 | 259 | |
| 202 | - // Check col value | |
| 203 | - if (col < 0 || col >= m_number) | |
| 204 | - throw GException::out_of_range(G_STRING, col, 0, m_number-1); | |
| 260 | + // Check inx value | |
| 261 | + if (inx < 0 || inx >= m_number) | |
| 262 | + throw GException::out_of_range(G_STRING, inx, 0, m_number-1); | |
| 205 | 263 | |
| 206 | 264 | // Get index |
| 207 | - int inx = row * m_repeat + col; | |
| 265 | + int offset = row * m_number + inx; | |
| 208 | 266 | |
| 209 | 267 | // Convert double into string |
| 210 | 268 | ostringstream s_value; |
| 211 | - s_value << scientific << m_data[inx]; | |
| 269 | + s_value << scientific << m_data[offset]; | |
| 212 | 270 | |
| 213 | 271 | // Return value |
| 214 | 272 | return s_value.str(); |
| ... | ... | @@ -219,29 +277,31 @@ std::string GFitsTableFltCol::string(const int& row, const int& col) |
| 219 | 277 | * @brief Get double precision value |
| 220 | 278 | * |
| 221 | 279 | * @param[in] row Table row. |
| 222 | - * @param[in] col Table column vector index. | |
| 280 | + * @param[in] inx Table column vector index. | |
| 281 | + * | |
| 282 | + * @exception GException::out_of_range | |
| 283 | + * Table row or vector index are out of valid range. | |
| 223 | 284 | * |
| 224 | 285 | * Returns value of specified row and vector index as double precision. |
| 225 | 286 | ***************************************************************************/ |
| 226 | -double GFitsTableFltCol::real(const int& row, const int& col) | |
| 287 | +double GFitsTableFltCol::real(const int& row, const int& inx) | |
| 227 | 288 | { |
| 228 | - // Make sure that data are loaded | |
| 229 | - if (m_data == NULL) | |
| 230 | - load(); | |
| 289 | + // If data are not available then load them now | |
| 290 | + if (m_data == NULL) fetch_data(); | |
| 231 | 291 | |
| 232 | 292 | // Check row value |
| 233 | 293 | if (row < 0 || row >= m_length) |
| 234 | 294 | throw GException::out_of_range(G_REAL, row, 0, m_length-1); |
| 235 | 295 | |
| 236 | - // Check col value | |
| 237 | - if (col < 0 || col >= m_number) | |
| 238 | - throw GException::out_of_range(G_REAL, col, 0, m_number-1); | |
| 296 | + // Check inx value | |
| 297 | + if (inx < 0 || inx >= m_number) | |
| 298 | + throw GException::out_of_range(G_REAL, inx, 0, m_number-1); | |
| 239 | 299 | |
| 240 | 300 | // Get index |
| 241 | - int inx = row * m_repeat + col; | |
| 301 | + int offset = row * m_number + inx; | |
| 242 | 302 | |
| 243 | 303 | // Convert float into double |
| 244 | - double value = (double)m_data[inx]; | |
| 304 | + double value = (double)m_data[offset]; | |
| 245 | 305 | |
| 246 | 306 | // Return value |
| 247 | 307 | return value; |
| ... | ... | @@ -252,29 +312,31 @@ double GFitsTableFltCol::real(const int& row, const int& col) |
| 252 | 312 | * @brief Get integer value |
| 253 | 313 | * |
| 254 | 314 | * @param[in] row Table row. |
| 255 | - * @param[in] col Table column vector index. | |
| 315 | + * @param[in] inx Table column vector index. | |
| 316 | + * | |
| 317 | + * @exception GException::out_of_range | |
| 318 | + * Table row or vector index are out of valid range. | |
| 256 | 319 | * |
| 257 | 320 | * Returns value of specified row and vector index as integer. |
| 258 | 321 | ***************************************************************************/ |
| 259 | -int GFitsTableFltCol::integer(const int& row, const int& col) | |
| 322 | +int GFitsTableFltCol::integer(const int& row, const int& inx) | |
| 260 | 323 | { |
| 261 | - // Make sure that data are loaded | |
| 262 | - if (m_data == NULL) | |
| 263 | - load(); | |
| 324 | + // If data are not available then load them now | |
| 325 | + if (m_data == NULL) fetch_data(); | |
| 264 | 326 | |
| 265 | 327 | // Check row value |
| 266 | 328 | if (row < 0 || row >= m_length) |
| 267 | 329 | throw GException::out_of_range(G_INTEGER, row, 0, m_length-1); |
| 268 | 330 | |
| 269 | - // Check col value | |
| 270 | - if (col < 0 || col >= m_number) | |
| 271 | - throw GException::out_of_range(G_INTEGER, col, 0, m_number-1); | |
| 331 | + // Check inx value | |
| 332 | + if (inx < 0 || inx >= m_number) | |
| 333 | + throw GException::out_of_range(G_INTEGER, inx, 0, m_number-1); | |
| 272 | 334 | |
| 273 | 335 | // Get index |
| 274 | - int inx = row * m_repeat + col; | |
| 336 | + int offset = row * m_number + inx; | |
| 275 | 337 | |
| 276 | 338 | // Convert float into int |
| 277 | - int value = (int)m_data[inx]; | |
| 339 | + int value = (int)m_data[offset]; | |
| 278 | 340 | |
| 279 | 341 | // Return value |
| 280 | 342 | return value; |
| ... | ... | @@ -407,30 +469,54 @@ void GFitsTableFltCol::free_members(void) |
| 407 | 469 | |
| 408 | 470 | |
| 409 | 471 | /***********************************************************************//** |
| 410 | - * @brief Load column data | |
| 472 | + * @brief Fetch column data | |
| 473 | + * | |
| 474 | + * @exception GException::fits_error | |
| 475 | + * An error occured while loading column data from FITS file. | |
| 476 | + * | |
| 477 | + * If a FITS file is attached to the column the data are loaded into memory | |
| 478 | + * from the FITS file. If no FITS file is attached, memory is allocated | |
| 479 | + * to hold the column data and all cells are set to 0. | |
| 411 | 480 | ***************************************************************************/ |
| 412 | -void GFitsTableFltCol::load(void) | |
| 481 | +void GFitsTableFltCol::fetch_data(void) | |
| 413 | 482 | { |
| 414 | 483 | // Calculate size of memory |
| 415 | 484 | m_size = m_number * m_length; |
| 416 | 485 | |
| 417 | - // Allocate memory | |
| 418 | - if (m_data != NULL) delete [] m_data; | |
| 419 | - m_data = new float[m_size]; | |
| 486 | + // Load only if the column has a positive size | |
| 487 | + if (m_size > 0) { | |
| 488 | + | |
| 489 | + // Allocate fresh memory | |
| 490 | + if (m_data != NULL) delete [] m_data; | |
| 491 | + m_data = new float[m_size]; | |
| 492 | + | |
| 493 | + // If a FITS file is attached then load column data from the FITS | |
| 494 | + // file | |
| 495 | + if (m_fitsfile.Fptr != NULL) { | |
| 496 | + int status = 0; | |
| 497 | + status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, | |
| 498 | + &status); | |
| 499 | + status = __ffgcv(&m_fitsfile, __TFLOAT, m_colnum, 1, 1, m_size, | |
| 500 | + m_nulval, m_data, &m_anynul, &status); | |
| 501 | + if (status != 0) | |
| 502 | + throw GException::fits_error(G_FETCH_DATA, status); | |
| 503 | + } | |
| 504 | + | |
| 505 | + // ... otherwise initialise all column values to 0 | |
| 506 | + else { | |
| 507 | + for (int i = 0; i < m_size; ++i) | |
| 508 | + m_data[i] = 0.0; | |
| 509 | + } | |
| 420 | 510 | |
| 421 | - // Load column data | |
| 422 | - int status = 0; | |
| 423 | - status = __ffmahd(&m_fitsfile, (m_fitsfile.HDUposition)+1, NULL, &status); | |
| 424 | - status = __ffgcv(&m_fitsfile, __TFLOAT, m_colnum, 1, 1, m_size, | |
| 425 | - m_nulval, m_data, &m_anynul, &status); | |
| 426 | - if (status != 0) | |
| 427 | - throw GException::fits_error(G_LOAD, status); | |
| 511 | + } // endif: column has a positive size | |
| 428 | 512 | |
| 429 | 513 | // Return |
| 430 | 514 | return; |
| 431 | 515 | } |
| 432 | 516 | |
| 433 | 517 | |
| 518 | + | |
| 519 | + | |
| 434 | 520 | /***********************************************************************//** |
| 435 | 521 | * @brief Returns format string of ASCII table |
| 436 | 522 | ***************************************************************************/ |
| ... | ... | @@ -475,6 +561,52 @@ std::string GFitsTableFltCol::binary_format(void) const |
| 475 | 561 | = = |
| 476 | 562 | ==========================================================================*/ |
| 477 | 563 | |
| 564 | +/***********************************************************************//** | |
| 565 | + * @brief Output operator | |
| 566 | + * | |
| 567 | + * @param[in] os Output stream | |
| 568 | + * @param[in] column Column to put in output stream | |
| 569 | + ***************************************************************************/ | |
| 570 | +ostream& operator<< (ostream& os, const GFitsTableFltCol& column) | |
| 571 | +{ | |
| 572 | + // Put column name in stream | |
| 573 | + os << "'" << column.m_name << "'"; | |
| 574 | + | |
| 575 | + // Put FITS column number in stream | |
| 576 | + if (column.m_colnum > 0) | |
| 577 | + os << " [fits_colnum=" << column.m_colnum << "]"; | |
| 578 | + else | |
| 579 | + os << " [not linked to FITS file]"; | |
| 580 | + | |
| 581 | + // Put column type in stream | |
| 582 | + os << " " << column.ascii_format(); | |
| 583 | + os << " " << column.binary_format(); | |
| 584 | + | |
| 585 | + // Put data loading in stream | |
| 586 | + if (column.m_data == NULL) | |
| 587 | + os << " (not loaded)"; | |
| 588 | + else | |
| 589 | + os << " (loaded in memory)"; | |
| 590 | + | |
| 591 | + // Set data area size | |
| 592 | + os << " size=" << column.m_size; | |
| 593 | + | |
| 594 | + // Set vector length | |
| 595 | + os << " repeat=" << column.m_repeat; | |
| 596 | + | |
| 597 | + // Set width | |
| 598 | + os << " width=" << column.m_width; | |
| 599 | + | |
| 600 | + // Set number | |
| 601 | + os << " number=" << column.m_number; | |
| 602 | + | |
| 603 | + // Set length | |
| 604 | + os << " length=" << column.m_length; | |
| 605 | + | |
| 606 | + // Return output stream | |
| 607 | + return os; | |
| 608 | +} | |
| 609 | + | |
| 478 | 610 | |
| 479 | 611 | /*========================================================================== |
| 480 | 612 | = = | ... | ... |
test/test_GFits.cpp
| ... | ... | @@ -382,7 +382,9 @@ void test_create(void) |
| 382 | 382 | GFitsBinTable table = GFitsBinTable(nrows); |
| 383 | 383 | GFitsTableDblCol first = GFitsTableDblCol("First", nrows); |
| 384 | 384 | GFitsTableDblCol second = GFitsTableDblCol("Second", nrows); |
| 385 | - first(9) = 99.0; | |
| 385 | + first(0) = 1.0; | |
| 386 | + first(1) = 2.0; | |
| 387 | + first(2) = 3.0; | |
| 386 | 388 | second(0) = -99.0; |
| 387 | 389 | cout << endl << first << endl; |
| 388 | 390 | cout << second << endl; |
| ... | ... | @@ -495,6 +497,189 @@ void test_image_double(void) |
| 495 | 497 | |
| 496 | 498 | |
| 497 | 499 | /*************************************************************************** |
| 500 | + * Test: FITS binary table test * | |
| 501 | + ***************************************************************************/ | |
| 502 | +void test_bin_table(void) | |
| 503 | +{ | |
| 504 | + // Dump header | |
| 505 | + cout << "Test GFitsBinTable: "; | |
| 506 | + | |
| 507 | + // Remove FITS file | |
| 508 | + system("rm -rf test_bintables.fits"); | |
| 509 | + | |
| 510 | + // Allocate reference sums | |
| 511 | + double sum_dbl = 0.0; | |
| 512 | + int sum_dbl_int = 0; | |
| 513 | + std::string sum_dbl_str; | |
| 514 | + float sum_flt = 0.0; | |
| 515 | + int sum_flt_int = 0; | |
| 516 | + std::string sum_flt_str; | |
| 517 | + | |
| 518 | + // Build tables | |
| 519 | + try { | |
| 520 | + // Open FITS file | |
| 521 | + GFits fits; | |
| 522 | + fits.open("test_bintables.fits"); | |
| 523 | + | |
| 524 | + // Set number of rows | |
| 525 | + int nrows = 10; | |
| 526 | + | |
| 527 | + // Initial control sums | |
| 528 | + float tot_flt = 0.0; | |
| 529 | + double tot_dbl = 0.0; | |
| 530 | + int tot_int = 0; | |
| 531 | + std::string tot_str; | |
| 532 | + | |
| 533 | + // | |
| 534 | + // ===== D O U B L E ===== | |
| 535 | + // | |
| 536 | + | |
| 537 | + // Set double precision table | |
| 538 | + GFitsTableDblCol col_dbl = GFitsTableDblCol("DOUBLE", nrows); | |
| 539 | + for (int i = 0; i < nrows; ++i) { | |
| 540 | + double val_dbl = cos(double(i)); | |
| 541 | + col_dbl(i) = val_dbl; | |
| 542 | + sum_dbl += val_dbl; | |
| 543 | + sum_dbl_int += int(val_dbl); | |
| 544 | + ostringstream s_value; | |
| 545 | + s_value << scientific << val_dbl; | |
| 546 | + sum_dbl_str += ":"+s_value.str(); | |
| 547 | + } | |
| 548 | + cout << "."; | |
| 549 | + | |
| 550 | + // Check double precision table (operator access) | |
| 551 | + tot_dbl = 0.0; | |
| 552 | + for (int i = 0; i < nrows; ++i) | |
| 553 | + tot_dbl += col_dbl(i); | |
| 554 | + if (!dequal(tot_dbl, sum_dbl)) { | |
| 555 | + cout << endl << "TEST ERROR: GFitsTableDblCol::operator()" | |
| 556 | + << endl; | |
| 557 | + throw; | |
| 558 | + } | |
| 559 | + cout << "."; | |
| 560 | + | |
| 561 | + // Check double precision table (real access) | |
| 562 | + tot_dbl = 0.0; | |
| 563 | + for (int i = 0; i < nrows; ++i) | |
| 564 | + tot_dbl += col_dbl.real(i); | |
| 565 | + if (!dequal(tot_dbl, sum_dbl)) { | |
| 566 | + cout << endl << "TEST ERROR: GFitsTableDblCol::real()" | |
| 567 | + << endl; | |
| 568 | + throw; | |
| 569 | + } | |
| 570 | + cout << "."; | |
| 571 | + | |
| 572 | + // Check double precision table (int access) | |
| 573 | + tot_int = 0.0; | |
| 574 | + for (int i = 0; i < nrows; ++i) | |
| 575 | + tot_int += col_dbl.integer(i); | |
| 576 | + if (tot_int != sum_dbl_int) { | |
| 577 | + cout << endl << "TEST ERROR: GFitsTableDblCol::integer()" | |
| 578 | + << endl; | |
| 579 | + throw; | |
| 580 | + } | |
| 581 | + cout << "."; | |
| 582 | + | |
| 583 | + // Check double precision table (string access) | |
| 584 | + tot_str.clear(); | |
| 585 | + for (int i = 0; i < nrows; ++i) | |
| 586 | + tot_str += ":"+col_dbl.string(i); | |
| 587 | + if (tot_str != sum_dbl_str) { | |
| 588 | + cout << endl << "TEST ERROR: GFitsTableDblCol::string()" | |
| 589 | + << endl; | |
| 590 | + throw; | |
| 591 | + } | |
| 592 | + cout << "."; | |
| 593 | + | |
| 594 | + // | |
| 595 | + // ===== F L O A T ===== | |
| 596 | + // | |
| 597 | + | |
| 598 | + // Set single precision table | |
| 599 | + GFitsTableFltCol col_flt = GFitsTableFltCol("FLOAT", nrows); | |
| 600 | + for (int i = 0; i < nrows; ++i) { | |
| 601 | + float val_flt = cos(0.1*float(i)); | |
| 602 | + col_flt(i) = val_flt; | |
| 603 | + sum_flt += val_flt; | |
| 604 | + sum_flt_int += int(val_flt); | |
| 605 | + ostringstream s_value; | |
| 606 | + s_value << scientific << val_flt; | |
| 607 | + sum_flt_str += ":"+s_value.str(); | |
| 608 | + } | |
| 609 | + cout << "."; | |
| 610 | + | |
| 611 | + // Check single precision table (operator access) | |
| 612 | + tot_flt = 0.0; | |
| 613 | + for (int i = 0; i < nrows; ++i) | |
| 614 | + tot_flt += col_flt(i); | |
| 615 | + if (!fequal(tot_flt, sum_flt)) { | |
| 616 | + cout << endl << "TEST ERROR: GFitsTableFltCol::operator()" | |
| 617 | + << endl; | |
| 618 | + throw; | |
| 619 | + } | |
| 620 | + cout << "."; | |
| 621 | + | |
| 622 | + // Check single precision table (real access) | |
| 623 | + tot_flt = 0.0; | |
| 624 | + for (int i = 0; i < nrows; ++i) | |
| 625 | + tot_flt += col_flt.real(i); | |
| 626 | + if (!fequal(tot_flt, sum_flt)) { | |
| 627 | + cout << endl << "TEST ERROR: GFitsTableFltCol::real()" | |
| 628 | + << endl; | |
| 629 | + throw; | |
| 630 | + } | |
| 631 | + cout << "."; | |
| 632 | + | |
| 633 | + // Check single precision table (int access) | |
| 634 | + tot_int = 0.0; | |
| 635 | + for (int i = 0; i < nrows; ++i) | |
| 636 | + tot_int += col_flt.integer(i); | |
| 637 | + if (tot_int != sum_flt_int) { | |
| 638 | + cout << endl << "TEST ERROR: GFitsTableFltCol::integer()" | |
| 639 | + << endl; | |
| 640 | + throw; | |
| 641 | + } | |
| 642 | + cout << "."; | |
| 643 | + | |
| 644 | + // Check single precision table (string access) | |
| 645 | + tot_str.clear(); | |
| 646 | + for (int i = 0; i < nrows; ++i) | |
| 647 | + tot_str += ":"+col_flt.string(i); | |
| 648 | + if (tot_str != sum_flt_str) { | |
| 649 | + cout << endl << "TEST ERROR: GFitsTableFltCol::string()" | |
| 650 | + << endl; | |
| 651 | + throw; | |
| 652 | + } | |
| 653 | + cout << "."; | |
| 654 | + | |
| 655 | + // | |
| 656 | + // ===== W R I T E T A B L E ===== | |
| 657 | + // | |
| 658 | + | |
| 659 | + // Build binary table | |
| 660 | + GFitsBinTable table = GFitsBinTable(nrows); | |
| 661 | + table.append_column(col_dbl); | |
| 662 | + table.append_column(col_flt); | |
| 663 | + | |
| 664 | + // Create HDU and append to FILE file | |
| 665 | + GFitsHDU hdu(table); | |
| 666 | + fits.append_hdu(hdu); | |
| 667 | + | |
| 668 | + // Save FITS file | |
| 669 | + fits.save(); | |
| 670 | + cout << "."; | |
| 671 | + } | |
| 672 | + catch (exception &e) { | |
| 673 | + cout << endl << "TEST ERROR: Unable to build tables." << endl; | |
| 674 | + cout << e.what() << endl; | |
| 675 | + throw; | |
| 676 | + } | |
| 677 | + cout << ". ok." << endl; | |
| 678 | + | |
| 679 | + | |
| 680 | +} | |
| 681 | + | |
| 682 | +/*************************************************************************** | |
| 498 | 683 | * Main test function * |
| 499 | 684 | ***************************************************************************/ |
| 500 | 685 | int main(void) |
| ... | ... | @@ -506,8 +691,9 @@ int main(void) |
| 506 | 691 | std::cout << "***********************" << std::endl; |
| 507 | 692 | |
| 508 | 693 | // Execute the tests |
| 509 | - test_image_double(); | |
| 510 | 694 | test_create(); |
| 695 | + test_image_double(); | |
| 696 | + test_bin_table(); | |
| 511 | 697 | //test_open(); |
| 512 | 698 | //test_columns(); |
| 513 | 699 | ... | ... |