GammaLib  2.1.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-2021 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::runtime_error
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) {
226  std::string msg = "FITS file not opened. Please open the FITS file "
227  "before moving the file pointer to an HDU.";
229  }
230 
231  // Move to HDU
233 
234  // Return
235  return;
236 }
237 
238 
239 /***********************************************************************//**
240  * @brief Get HDU type from FITS file
241  *
242  * @exception GException::runtime_error
243  * No FITS file has been opened.
244  ***************************************************************************/
246 {
247  // Initialise HDU type
248  int type = 0;
249 
250  // Throw an exception if FITS file is not open
251  if (FPTR(m_fitsfile)->Fptr == NULL) {
252  std::string msg = "FITS file not opened. Please open the FITS file "
253  "before requesting an 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::invalid_argument
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) {
289  std::string msg = "FITS file pointer does not point to an open FITS "
290  "file. Please open the FITS file before opening an "
291  "HDU.";
293  }
294 
295  // Move to HDU
296  gammalib::fits_move_to_hdu(G_OPEN, vptr, hdunum+1);
297 
298  // Save the FITS file pointer and the HDU number
299  FPTR_COPY(m_fitsfile, vptr);
300  m_hdunum = hdunum;
301 
302  // Load HDU header
304 
305  // Open HDU data area
307 
308  // Get HDU name from header. If no name was found and this is the primary
309  // HDU then set the name to "Primary", otherwise to "NoName".
310  if (m_header.contains("EXTNAME")) {
312  }
313  else {
314  m_name.clear();
315  }
316  if (m_name.length() == 0) {
317  if (hdunum == 0) {
318  m_name = "Primary";
319  }
320  else {
321  m_name = "NoName";
322  }
323  }
324 
325  // Return
326  return;
327 }
328 
329 
330 /***********************************************************************//**
331  * @brief Saves HDU
332  *
333  * Save the HDU to the FITS file. In case that the HDU does not exist in the
334  * file it will be created (by the save_data() method). In the special case
335  * that no first HDU exists, an empty primary image is created.
336  *
337  * @todo Put the m_header.save(FPTR(m_fitsfile)) call in the data_save()
338  * methods
339  ***************************************************************************/
340 void GFitsHDU::save(void)
341 {
342  // Debug header
343  #if DEBUG
344  std::cout << "GFitsHDU::save() -->" << std::endl;
345  #endif
346 
347  // Save data. This method allows saving past the file and will
348  // physically append a new HDU to a FITS file. It has to be called
349  // before the saving of the header cards, since header card
350  // saving requires the HDU to exist in the FITS file.
351  data_save();
352 
353  // Save header cards (assumes implicitely that the HDU exists in
354  // FITS file)
356 
357  // Debug trailer
358  #if DEBUG
359  std::cout << "<-- GFitsHDU::save" << std::endl;
360  #endif
361 
362  // Return
363  return;
364 }
365 
366 
367 /***********************************************************************//**
368  * @brief Print basic HDU information
369  *
370  * @param[in] chatter Chattiness (defaults to NORMAL).
371  * @return String containing basic HDU information.
372  ***************************************************************************/
373 std::string GFitsHDU::print_hdu(const GChatter& chatter) const
374 {
375  // Initialise result string
376  std::string result;
377 
378  // Continue only if chatter is not silent
379  if (chatter != SILENT) {
380 
381  // Append HDU information
382  result.append(gammalib::parformat("HDU number"));
383  result.append(gammalib::str(m_hdunum)+"\n");
384  result.append(gammalib::parformat("HDU name")+m_name);
385 
386  } // endif: chatter was not silent
387 
388  // Return result
389  return result;
390 }
391 
392 
393 /***********************************************************************//**
394  * @brief Return typecode as string
395  *
396  * @param[in] type Type code.
397  ***************************************************************************/
398 std::string GFitsHDU::typecode(int type) const
399 {
400  // Allocate string
401  std::string result;
402 
403  // Set typecode
404  switch (type) {
405  case __TBIT:
406  result = "bit";
407  break;
408  case __TBYTE:
409  result = "unsigned byte";
410  break;
411  case __TSBYTE:
412  result = "signed byte";
413  break;
414  case __TLOGICAL:
415  result = "boolean";
416  break;
417  case __TSTRING:
418  result = "string";
419  break;
420  case __TUSHORT:
421  result = "unsigned short integer";
422  break;
423  case __TSHORT:
424  result = "short integer";
425  break;
426  case __TULONG:
427  result = "unsigned long integer";
428  break;
429  case __TLONG:
430  result = "long integer";
431  break;
432  case __TFLOAT:
433  result = "single precision floating point";
434  break;
435  case __TLONGLONG:
436  result = "long long integer";
437  break;
438  case __TDOUBLE:
439  result = "double precision floating point";
440  break;
441  default:
442  result = "unsupported format";
443  break;
444  }
445 
446  // Return result
447  return result;
448 }
449 
450 
451 /*==========================================================================
452  = =
453  = Private methods =
454  = =
455  ==========================================================================*/
456 
457 /***********************************************************************//**
458  * @brief Initialise class members
459  *
460  * Sets all class members to well defined values.
461  ***************************************************************************/
463 {
464  // Allocate FITS file pointer. As the pointer is of type void the C-style
465  // memory allocation function malloc is used as this function does not
466  // deal with types but always returns a void pointer
467  m_fitsfile = malloc(sizeof(__fitsfile));
468 
469  // Initialise FITS file pointer
470  FPTR(m_fitsfile)->HDUposition = 0;
471  FPTR(m_fitsfile)->Fptr = NULL;
472 
473  // Initialise members
474  m_hdunum = 0;
475  m_name.clear();
476 
477  // Return
478  return;
479 }
480 
481 
482 /***********************************************************************//**
483  * @brief Copy class members
484  *
485  * @param[in] hdu HDU to be copied.
486  *
487  * Assumes that all memory has been freed correctly before calling.
488  ***************************************************************************/
490 {
491  // Copy members
493  m_hdunum = hdu.m_hdunum;
494  m_name = hdu.m_name;
495  m_header = hdu.m_header;
496 
497  // Return
498  return;
499 }
500 
501 
502 /***********************************************************************//**
503  * @brief Delete class members
504  ***************************************************************************/
506 {
507  // Free memory. Note that the malloc function was used for allocation,
508  // hence the free function needs to be called for freeing.
509  if (m_fitsfile != NULL) free(m_fitsfile);
510 
511  // Signal free pointers
512  m_fitsfile = NULL;
513 
514  // Return
515  return;
516 }
#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:373
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:80
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:340
#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:245
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:462
#define G_GET_HDU_TYPE
Definition: GFitsHDU.cpp:49
std::string typecode(int type) const
Return typecode as string.
Definition: GFitsHDU.cpp:398
#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:489
int fits_move_to_hdu(const std::string &caller, void *vptr, const int &hdunum=0)
Move to FITS extension.
Definition: GFits.cpp:1774
void free_members(void)
Delete class members.
Definition: GFitsHDU.cpp:505
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
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:489