GammaLib 2.0.0
Loading...
Searching...
No Matches
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
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
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 ***************************************************************************/
160void 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
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 ***************************************************************************/
192void 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) {
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 ***************************************************************************/
285void 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 ***************************************************************************/
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 ***************************************************************************/
373std::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 ***************************************************************************/
398std::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}
Exception handler interface definition.
CFITSIO interface header.
#define __TLONG
#define __TLOGICAL
#define __TLONGLONG
#define __TSHORT
#define FPTR(A)
#define __TBYTE
#define __TULONG
#define FPTR_COPY(A, B)
#define __TSTRING
#define __ffghdt(A, B, C)
#define __TFLOAT
#define __TDOUBLE
#define __TUSHORT
#define __TSBYTE
#define __TBIT
#define G_GET_HDU_TYPE
Definition GFitsHDU.cpp:49
#define G_MOVE_TO_HDU
Definition GFitsHDU.cpp:48
Abstract FITS extension base class definition.
FITS header card class definition.
#define G_OPEN
Definition GFits.cpp:63
FITS file class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Abstract FITS extension base class.
Definition GFitsHDU.hpp:51
std::string m_name
HDU name (extname)
Definition GFitsHDU.hpp:135
virtual ~GFitsHDU(void)
Destructor.
Definition GFitsHDU.cpp:103
void free_members(void)
Delete class members.
Definition GFitsHDU.cpp:505
GFitsHeader m_header
HDU header.
Definition GFitsHDU.hpp:136
const std::string & extname(void) const
Return extension name.
Definition GFitsHDU.hpp:162
GFitsHDU & operator=(const GFitsHDU &hdu)
Assignment operator.
Definition GFitsHDU.cpp:124
void * m_fitsfile
FITS file pointer pointing on actual HDU.
Definition GFitsHDU.hpp:133
HDUType get_hdu_type(void) const
Get HDU type from FITS file.
Definition GFitsHDU.cpp:245
int m_hdunum
HDU number (starting from 0)
Definition GFitsHDU.hpp:134
void open(void *vptr, int hdunum)
Open HDU.
Definition GFitsHDU.cpp:285
void init_members(void)
Initialise class members.
Definition GFitsHDU.cpp:462
void connect(void *fptr)
Connect HDU to FITS file.
Definition GFitsHDU.cpp:192
void save(void)
Saves HDU.
Definition GFitsHDU.cpp:340
GFitsHDU(void)
Void constructor.
Definition GFitsHDU.cpp:72
void move_to_hdu(void)
Move FITS file pointer to HDU.
Definition GFitsHDU.cpp:222
virtual void data_save(void)=0
std::string typecode(int type) const
Return typecode as string.
Definition GFitsHDU.cpp:398
virtual void data_open(void *vptr)=0
virtual void data_connect(void *vptr)=0
void copy_members(const GFitsHDU &hdu)
Copy class members.
Definition GFitsHDU.cpp:489
std::string print_hdu(const GChatter &chatter=NORMAL) const
Print basic HDU information.
Definition GFitsHDU.cpp:373
Implements FITS header card interface.
bool contains(const int &cardno) const
Check if card is present in header.
std::string string(const int &cardno) const
Return header card value as string value.
void save(void *vptr) const
Save header to FITS file.
GFitsHeaderCard & append(const GFitsHeaderCard &card)
Append or update header card.
void load(void *vptr)
Load header from FITS file.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
Definition GTools.cpp:80
int fits_move_to_hdu(const std::string &caller, void *vptr, const int &hdunum=0)
Move to FITS extension.
Definition GFits.cpp:1774