GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GFitsHDU.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GFitsHDU.cpp - FITS HDU handling class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2008-2014 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GFitsHDU.cpp
23  * @brief GFitsHDU class implementation.
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <iostream>
32 #include <cstdlib>
33 #include "GException.hpp"
34 #include "GTools.hpp"
35 #include "GFitsCfitsio.hpp"
36 #include "GFits.hpp"
37 #include "GFitsHDU.hpp"
38 #include "GFitsHeaderCard.hpp"
39 #include "GTools.hpp"
40 
41 /* __ Method name definitions ____________________________________________ */
42 #define G_OPEN "GFitsHDU::open(int)"
43 #define G_SAVE "GFitsHDU::save()"
44 #define G_HEADER "GFitsHDU::header()"
45 #define G_DATA "GFitsHDU::data()"
46 #define G_COLUMN "GFitsHDU::column(std::string&)"
47 #define G_CONNECT "GFitsHDU::connect(void*)"
48 #define G_MOVE_TO_HDU "GFitsHDU::move_to_hdu()"
49 #define G_GET_HDU_TYPE "GFitsHDU::get_hdu_type()"
50 #define G_NEW_IMAGE "GFitsHDU::new_image()"
51 
52 /* __ Definitions ________________________________________________________ */
53 #define DEBUG 0
54 
55 /* __ Macros _____________________________________________________________ */
56 
57 /* __ Coding definitions _________________________________________________ */
58 
59 /* __ Debug definitions __________________________________________________ */
60 
61 
62 
63 /*==========================================================================
64  = =
65  = Constructors/destructors =
66  = =
67  ==========================================================================*/
68 
69 /***********************************************************************//**
70  * @brief Void constructor
71  ***************************************************************************/
73 {
74  // Initialise class members for clean destruction
75  init_members();
76 
77  // Return
78  return;
79 }
80 
81 
82 /***********************************************************************//**
83  * @brief Copy constructor
84  *
85  * @param[in] hdu HDU from which the instance should be constructed.
86  ***************************************************************************/
88 {
89  // Initialise class members for clean destruction
90  init_members();
91 
92  // Copy members
93  copy_members(hdu);
94 
95  // Return
96  return;
97 }
98 
99 
100 /***********************************************************************//**
101  * @brief Destructor
102  ***************************************************************************/
104 {
105  // Free members
106  free_members();
107 
108  // Return
109  return;
110 }
111 
112 
113 /*==========================================================================
114  = =
115  = Operators =
116  = =
117  ==========================================================================*/
118 
119 /***********************************************************************//**
120  * @brief Assignment operator
121  *
122  * @param[in] hdu HDU which should be assigned.
123  ***************************************************************************/
125 {
126  // Execute only if object is not identical
127  if (this != &hdu) {
128 
129  // Free members
130  free_members();
131 
132  // Initialise private members for clean destruction
133  init_members();
134 
135  // Copy members
136  copy_members(hdu);
137 
138  } // endif: object was not identical
139 
140  // Return this object
141  return *this;
142 }
143 
144 
145 /*==========================================================================
146  = =
147  = Public methods =
148  = =
149  ==========================================================================*/
150 
151 /***********************************************************************//**
152  * @brief Set HDU extension name (EXTNAME keyword)
153  *
154  * @param[in] extname Name of HDU.
155  *
156  * This method sets the extension name of the HDU. The extension name will
157  * be saved in the 'EXTNAME' header keyword. The header attached to the
158  * HDU will be automatically updated by this method.
159  ***************************************************************************/
160 void GFitsHDU::extname(const std::string& extname)
161 {
162  // Set extension name
163  m_name = extname;
164 
165  // If no header exists then create one now
166  //if (m_header == NULL) m_header = new GFitsHeader();
167 
168  // Update header
169  m_header.append(GFitsHeaderCard("EXTNAME", extname,
170  "name of this extension"));
171 
172  // Return
173  return;
174 }
175 
176 
177 /*==========================================================================
178  = =
179  = Protected methods =
180  = =
181  ==========================================================================*/
182 
183 /***********************************************************************//**
184  * @brief Connect HDU to FITS file
185  *
186  * @param[in] vptr FITS file pointer.
187  *
188  * Connects the HDU to the file specified by the FITS file pointer. Sets
189  * also the HDU number (or extension number, starting from 0). This method
190  * does nothing if the file pointer in not valid.
191  ***************************************************************************/
192 void GFitsHDU::connect(void* vptr)
193 {
194  // Continue only if file pointer is valid
195  if (vptr != NULL) {
196 
197  // Connect HDU by copying the file pointer
198  FPTR_COPY(m_fitsfile, vptr);
199 
200  // Extract HDU number from file pointer
201  m_hdunum = FPTR(m_fitsfile)->HDUposition;
202 
203  // Connect data
204  data_connect(vptr);
205 
206  } // endif: file pointer was valid
207 
208  // Return
209  return;
210 }
211 
212 
213 /***********************************************************************//**
214  * @brief Move FITS file pointer to HDU
215  *
216  * @exception GException::fits_file_not_open
217  * No FITS file has been opened.
218  *
219  * Moves FITS file pointer to the actual HDU. This operation should preceed
220  * any FITS file manipulation.
221  ***************************************************************************/
223 {
224  // Throw an exception if FITS file is not open
225  if (FPTR(m_fitsfile)->Fptr == NULL) {
227  "Open file before moving file pointer to HDU.");
228  }
229 
230  // Move to HDU
232 
233  // Return
234  return;
235 }
236 
237 
238 /***********************************************************************//**
239  * @brief Get HDU type from FITS file
240  *
241  * @exception GException::fits_file_not_open
242  * No FITS file has been opened.
243  * @exception GException::fits_hdu_not_found
244  * Requested HDU not found.
245  ***************************************************************************/
247 {
248  // Initialise HDU type
249  int type = 0;
250 
251  // Throw an exception if FITS file is not open
252  if (FPTR(m_fitsfile)->Fptr == NULL) {
254  "Open file before requesting HDU type.");
255  }
256 
257  // Get HDU type
258  int status = 0;
259  status = __ffghdt(FPTR(m_fitsfile), &type, &status);
260  if (status != 0) {
261  throw GException::fits_error(G_GET_HDU_TYPE, status);
262  }
263 
264  // Return HDU type
265  return (HDUType)type;
266 }
267 
268 
269 /***********************************************************************//**
270  * @brief Open HDU
271  *
272  * @param[in] vptr FITS file pointer.
273  * @param[in] hdunum Number of HDU (starting from 0).
274  *
275  * @exception GException::fits_file_not_open
276  * FITS file pointer does not point to an open FITS file
277  * @exception GException::fits_error
278  * Unable to open FITS HDU.
279  *
280  * Opens an (existing) HDU in the FITS file. This method does NOT create any
281  * HDU if it does not exist. Opening consists of fetching all header cards
282  * (by opening an associated GFitsHeader instance) and of opening the data
283  * area (which can be of type Image or Table)
284  ***************************************************************************/
285 void GFitsHDU::open(void* vptr, int hdunum)
286 {
287  // Verify that FITS file pointer is valid
288  if (vptr == NULL) {
290  "FITS file pointer does not point to an open FITS file.");
291  }
292 
293  // Move to HDU
294  gammalib::fits_move_to_hdu(G_OPEN, vptr, hdunum+1);
295 
296  // Save the FITS file pointer and the HDU number
297  FPTR_COPY(m_fitsfile, vptr);
298  m_hdunum = hdunum;
299 
300  // Load HDU header
302 
303  // Open HDU data area
305 
306  // Get HDU name from header. If no name was found and this is the primary
307  // HDU then set the name to "Primary", otherwise to "NoName".
308  if (m_header.contains("EXTNAME")) {
310  }
311  else {
312  m_name.clear();
313  }
314  if (m_name.length() == 0) {
315  if (hdunum == 0) {
316  m_name = "Primary";
317  }
318  else {
319  m_name = "NoName";
320  }
321  }
322 
323  // Return
324  return;
325 }
326 
327 
328 /***********************************************************************//**
329  * @brief Saves HDU
330  *
331  * Save the HDU to the FITS file. In case that the HDU does not exist in the
332  * file it will be created (by the save_data() method). In the special case
333  * that no first HDU exists, an empty primary image is created.
334  *
335  * @todo Put the m_header.save(FPTR(m_fitsfile)) call in the data_save()
336  * methods
337  ***************************************************************************/
338 void GFitsHDU::save(void)
339 {
340  // Debug header
341  #if DEBUG
342  std::cout << "GFitsHDU::save() -->" << std::endl;
343  #endif
344 
345  // Save data. This method allows saving past the file and will
346  // physically append a new HDU to a FITS file. It has to be called
347  // before the saving of the header cards, since header card
348  // saving requires the HDU to exist in the FITS file.
349  data_save();
350 
351  // Save header cards (assumes implicitely that the HDU exists in
352  // FITS file)
354 
355  // Debug trailer
356  #if DEBUG
357  std::cout << "<-- GFitsHDU::save" << std::endl;
358  #endif
359 
360  // Return
361  return;
362 }
363 
364 
365 /***********************************************************************//**
366  * @brief Print basic HDU information
367  *
368  * @param[in] chatter Chattiness (defaults to NORMAL).
369  * @return String containing basic HDU information.
370  ***************************************************************************/
371 std::string GFitsHDU::print_hdu(const GChatter& chatter) const
372 {
373  // Initialise result string
374  std::string result;
375 
376  // Continue only if chatter is not silent
377  if (chatter != SILENT) {
378 
379  // Append HDU information
380  result.append(gammalib::parformat("HDU number"));
381  result.append(gammalib::str(m_hdunum)+"\n");
382  result.append(gammalib::parformat("HDU name")+m_name);
383 
384  } // endif: chatter was not silent
385 
386  // Return result
387  return result;
388 }
389 
390 
391 /***********************************************************************//**
392  * @brief Return typecode as string
393  *
394  * @param[in] type Type code.
395  ***************************************************************************/
396 std::string GFitsHDU::typecode(int type) const
397 {
398  // Allocate string
399  std::string result;
400 
401  // Set typecode
402  switch (type) {
403  case __TBIT:
404  result = "bit";
405  break;
406  case __TBYTE:
407  result = "unsigned byte";
408  break;
409  case __TSBYTE:
410  result = "signed byte";
411  break;
412  case __TLOGICAL:
413  result = "boolean";
414  break;
415  case __TSTRING:
416  result = "string";
417  break;
418  case __TUSHORT:
419  result = "unsigned short integer";
420  break;
421  case __TSHORT:
422  result = "short integer";
423  break;
424  case __TULONG:
425  result = "unsigned long integer";
426  break;
427  case __TLONG:
428  result = "long integer";
429  break;
430  case __TFLOAT:
431  result = "single precision floating point";
432  break;
433  case __TLONGLONG:
434  result = "long long integer";
435  break;
436  case __TDOUBLE:
437  result = "double precision floating point";
438  break;
439  default:
440  result = "unsupported format";
441  break;
442  }
443 
444  // Return result
445  return result;
446 }
447 
448 
449 /*==========================================================================
450  = =
451  = Private methods =
452  = =
453  ==========================================================================*/
454 
455 /***********************************************************************//**
456  * @brief Initialise class members
457  *
458  * Sets all class members to well defined values.
459  ***************************************************************************/
461 {
462  // Allocate FITS file pointer. As the pointer is of type void the C-style
463  // memory allocation function malloc is used as this function does not
464  // deal with types but always returns a void pointer
465  m_fitsfile = malloc(sizeof(__fitsfile));
466 
467  // Initialise FITS file pointer
468  FPTR(m_fitsfile)->HDUposition = 0;
469  FPTR(m_fitsfile)->Fptr = NULL;
470 
471  // Initialise members
472  m_hdunum = 0;
473  m_name.clear();
474 
475  // Return
476  return;
477 }
478 
479 
480 /***********************************************************************//**
481  * @brief Copy class members
482  *
483  * @param[in] hdu HDU to be copied.
484  *
485  * Assumes that all memory has been freed correctly before calling.
486  ***************************************************************************/
488 {
489  // Copy members
491  m_hdunum = hdu.m_hdunum;
492  m_name = hdu.m_name;
493  m_header = hdu.m_header;
494 
495  // Return
496  return;
497 }
498 
499 
500 /***********************************************************************//**
501  * @brief Delete class members
502  ***************************************************************************/
504 {
505  // Free memory. Note that the malloc function was used for allocation,
506  // hence the free function needs to be called for freeing.
507  if (m_fitsfile != NULL) free(m_fitsfile);
508 
509  // Signal free pointers
510  m_fitsfile = NULL;
511 
512  // Return
513  return;
514 }
#define G_MOVE_TO_HDU
Definition: GFitsHDU.cpp:48
#define G_OPEN
Definition: GFitsHDU.cpp:42
#define __TUSHORT
#define __TULONG
#define __TLOGICAL
#define FPTR(A)
std::string print_hdu(const GChatter &chatter=NORMAL) const
Print basic HDU information.
Definition: GFitsHDU.cpp:371
void open(void *vptr, int hdunum)
Open HDU.
Definition: GFitsHDU.cpp:285
Abstract FITS extension base class.
Definition: GFitsHDU.hpp:51
void connect(void *fptr)
Connect HDU to FITS file.
Definition: GFitsHDU.cpp:192
void save(void *vptr) const
Save header to FITS file.
void move_to_hdu(void)
Move FITS file pointer to HDU.
Definition: GFitsHDU.cpp:222
void * m_fitsfile
FITS file pointer pointing on actual HDU.
Definition: GFitsHDU.hpp:133
#define __TDOUBLE
Gammalib tools definition.
std::string m_name
HDU name (extname)
Definition: GFitsHDU.hpp:135
FITS file class interface definition.
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
Definition: GTools.cpp:73
FITS header card class definition.
std::string string(const int &cardno) const
Return header card value as string value.
GFitsHDU & operator=(const GFitsHDU &hdu)
Assignment operator.
Definition: GFitsHDU.cpp:124
#define __TBYTE
virtual void data_open(void *vptr)=0
Abstract FITS extension base class definition.
Implements FITS header card interface.
void save(void)
Saves HDU.
Definition: GFitsHDU.cpp:338
#define __TBIT
GFitsHeaderCard & append(const GFitsHeaderCard &card)
Append or update header card.
#define __ffghdt(A, B, C)
#define __TSHORT
CFITSIO interface header.
void load(void *vptr)
Load header from FITS file.
virtual void data_connect(void *vptr)=0
HDUType get_hdu_type(void) const
Get HDU type from FITS file.
Definition: GFitsHDU.cpp:246
GChatter
Definition: GTypemaps.hpp:33
#define __TLONG
GFitsHeader m_header
HDU header.
Definition: GFitsHDU.hpp:136
virtual void data_save(void)=0
const std::string & extname(void) const
Return extension name.
Definition: GFitsHDU.hpp:162
#define __TFLOAT
#define FPTR_COPY(A, B)
void init_members(void)
Initialise class members.
Definition: GFitsHDU.cpp:460
#define G_GET_HDU_TYPE
Definition: GFitsHDU.cpp:49
std::string typecode(int type) const
Return typecode as string.
Definition: GFitsHDU.cpp:396
#define __TLONGLONG
GFitsHDU(void)
Void constructor.
Definition: GFitsHDU.cpp:72
bool contains(const int &cardno) const
Check if card is present in header.
Exception handler interface definition.
#define __TSBYTE
void copy_members(const GFitsHDU &hdu)
Copy class members.
Definition: GFitsHDU.cpp:487
int fits_move_to_hdu(const std::string &caller, void *vptr, const int &hdunum=0)
Move to FITS extension.
Definition: GFits.cpp:1745
void free_members(void)
Delete class members.
Definition: GFitsHDU.cpp:503
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1022
virtual ~GFitsHDU(void)
Destructor.
Definition: GFitsHDU.cpp:103
#define __TSTRING
int m_hdunum
HDU number (starting from 0)
Definition: GFitsHDU.hpp:134
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:413