GammaLib 2.0.0
Loading...
Searching...
No Matches
GFitsImage.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GFitsImage.cpp - Abstract FITS image base 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 GFitsImage.cpp
23 * @brief Abstract FITS image base class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GException.hpp"
32#include "GFitsCfitsio.hpp"
33#include "GFits.hpp"
34#include "GFitsImage.hpp"
35#include "GTools.hpp"
36
37/* __ Method name definitions ____________________________________________ */
38#define G_NAXES "GFitsImage::naxes(int)"
39#define G_OPEN_IMAGE "GFitsImage::open(void*)"
40#define G_LOAD_IMAGE "GFitsImage::load_image(int,void*,void*,int*)"
41#define G_SAVE_IMAGE "GFitsImage::save_image(int,void*)"
42#define G_OFFSET_1D "GFitsImage::offset(int&)"
43#define G_OFFSET_2D "GFitsImage::offset(int&,int&)"
44#define G_OFFSET_3D "GFitsImage::offset(int&,int&,int&)"
45#define G_OFFSET_4D "GFitsImage::offset(int&,int&,int&,int&)"
46
47/* __ Macros _____________________________________________________________ */
48
49/* __ Coding definitions _________________________________________________ */
50
51/* __ Debug definitions __________________________________________________ */
52
53
54/*==========================================================================
55 = =
56 = Constructors/destructors =
57 = =
58 ==========================================================================*/
59
60/***********************************************************************//**
61 * @brief Void constructor
62 *
63 * Construct instance of an empty image. No header cards are present in an
64 * empty image.
65 ***************************************************************************/
67{
68 // Initialise class members for clean destruction
70
71 // Return
72 return;
73}
74
75
76/***********************************************************************//**
77 * @brief 1D image constructor
78 *
79 * @param[in] bitpix Number of Bits per pixel (negative is floating point).
80 * @param[in] nx Number of pixels.
81 *
82 * Construct 1D instance of GFitsImage by specifying the number of pixels.
83 * This method also adds the relevant header cards.
84 ***************************************************************************/
85GFitsImage::GFitsImage(const int& bitpix, const int& nx) : GFitsHDU()
86{
87 // Initialise class members for clean destruction
89
90 // Store number of Bits per pixel
92
93 // Set number of axes
94 m_naxis = 1;
95
96 // Set image dimensions
97 m_naxes = new long[m_naxis];
98 m_naxes[0] = nx;
99 m_num_pixels = nx;
100
101 // Initialise header
103
104 // Return
105 return;
106}
107
108
109/***********************************************************************//**
110 * @brief 2D image constructor
111 *
112 * @param[in] bitpix Number of Bits per pixel (negative is floating point).
113 * @param[in] nx Number of pixels in first dimension.
114 * @param[in] ny Number of pixels in second dimension.
115 *
116 * Construct 2D instance of GFitsImage by specifying the number of pixels
117 * in each dimension. This method also adds the relevant header cards.
118 ***************************************************************************/
119GFitsImage::GFitsImage(const int& bitpix, const int& nx, const int& ny) :
120 GFitsHDU()
121{
122 // Initialise class members for clean destruction
123 init_members();
124
125 // Store number of Bits per pixel
127
128 // Set number of axes
129 m_naxis = 2;
130
131 // Set image dimensions
132 m_naxes = new long[m_naxis];
133 m_naxes[0] = nx;
134 m_naxes[1] = ny;
135 m_num_pixels = nx * ny;
136
137 // Initialise header
139
140 // Return
141 return;
142}
143
144
145/***********************************************************************//**
146 * @brief 3D image constructor
147 *
148 * @param[in] bitpix Number of Bits per pixel (negative is floating point).
149 * @param[in] nx Number of pixels in first dimension.
150 * @param[in] ny Number of pixels in second dimension.
151 * @param[in] nz Number of pixels in third dimension.
152 *
153 * Construct 3D instance of GFitsImage by specifying the number of pixels
154 * in each dimension. This method also adds the relevant header cards.
155 ***************************************************************************/
156GFitsImage::GFitsImage(const int& bitpix, const int& nx, const int& ny,
157 const int& nz) : GFitsHDU()
158{
159 // Initialise class members for clean destruction
160 init_members();
161
162 // Store number of Bits per pixel
164
165 // Set number of axes
166 m_naxis = 3;
167
168 // Set image dimensions
169 m_naxes = new long[m_naxis];
170 m_naxes[0] = nx;
171 m_naxes[1] = ny;
172 m_naxes[2] = nz;
173 m_num_pixels = nx * ny * nz;
174
175 // Initialise header
177
178 // Return
179 return;
180}
181
182
183/***********************************************************************//**
184 * @brief 4D image constructor
185 *
186 * @param[in] bitpix Number of Bits per pixel (negative is floating point).
187 * @param[in] nx Number of pixels in first dimension.
188 * @param[in] ny Number of pixels in second dimension.
189 * @param[in] nz Number of pixels in third dimension.
190 * @param[in] nt Number of pixels in forth dimension.
191 *
192 * Construct 4D instance of GFitsImage by specifying the number of pixels
193 * in each dimension. This method also adds the relevant header cards.
194 ***************************************************************************/
195GFitsImage::GFitsImage(const int& bitpix, const int& nx, const int& ny,
196 const int& nz, const int& nt) : GFitsHDU()
197{
198 // Initialise class members for clean destruction
199 init_members();
200
201 // Store number of Bits per pixel
203
204 // Set number of axes
205 m_naxis = 4;
206
207 // Set image dimensions
208 m_naxes = new long[m_naxis];
209 m_naxes[0] = nx;
210 m_naxes[1] = ny;
211 m_naxes[2] = nz;
212 m_naxes[3] = nt;
213 m_num_pixels = nx * ny * nz * nt;
214
215 // Initialise header
217
218 // Return
219 return;
220}
221
222
223/***********************************************************************//**
224 * @brief Constructor
225 *
226 * @param[in] bitpix Number of Bits per pixel (negative is floating point).
227 * @param[in] naxes Vector of number of pixels in each dimension.
228 *
229 * Construct instance of GFitsImage by specifying the image dimension and
230 * the number of pixels in each dimension. This method also adds the relevant
231 * header cards.
232 ***************************************************************************/
233GFitsImage::GFitsImage(const int& bitpix, const std::vector<int>& naxes) : GFitsHDU()
234{
235 // Initialise class members for clean destruction
236 init_members();
237
238 // Store number of Bits per pixel
240
241 // Store number of axes
242 m_naxis = naxes.size();
243
244 // Copy number of pixels in each dimension and calculate the total
245 // number of pixels
246 if (m_naxis > 0) {
247 m_naxes = new long[m_naxis];
248 m_num_pixels = 1;
249 for (int i = 0; i < m_naxis; ++i) {
250 m_naxes[i] = naxes[i];
251 m_num_pixels *= naxes[i];
252 }
253 }
254
255 // Initialise header
257
258 // Return
259 return;
260}
261
262
263/***********************************************************************//**
264 * @brief Copy constructor
265 *
266 * @param[in] image FITS image.
267 ***************************************************************************/
269{
270 // Initialise class members for clean destruction
271 init_members();
272
273 // Copy members
274 copy_members(image);
275
276 // Return
277 return;
278}
279
280
281/***********************************************************************//**
282 * @brief Destructor
283 ***************************************************************************/
285{
286 // Free members
287 free_members();
288
289 // Return
290 return;
291}
292
293
294/*==========================================================================
295 = =
296 = Operators =
297 = =
298 ==========================================================================*/
299
300/***********************************************************************//**
301 * @brief Assignment operator
302 *
303 * @param[in] image FITS image.
304 * @return FITS image.
305 ***************************************************************************/
307{
308 // Execute only if object is not identical
309 if (this != &image) {
310
311 // Copy base class members
312 this->GFitsHDU::operator=(image);
313
314 // Free members
315 free_members();
316
317 // Initialise private members for clean destruction
318 init_members();
319
320 // Copy members
321 copy_members(image);
322
323 } // endif: object was not identical
324
325 // Return this object
326 return *this;
327}
328
329
330/*==========================================================================
331 = =
332 = Public methods =
333 = =
334 ==========================================================================*/
335
336/***********************************************************************//**
337 * @brief Return dimension of an image axis
338 *
339 * @param[in] axis Image axis [0,...,naxis()-1].
340 *
341 * @exception GException::out_of_range
342 * Image axis not valid.
343 ***************************************************************************/
344int GFitsImage::naxes(const int& axis) const
345{
346 // Check if axis is within the range
347 #if defined(G_RANGE_CHECK)
348 if (axis < 0 || axis >= naxis()) {
349 throw GException::out_of_range(G_NAXES, "Image axis", axis, naxis());
350 }
351 #endif
352
353 // Get axis dimension
354 int dim = m_naxes[axis];
355
356 // Return axis dimension
357 return dim;
358}
359
360
361/***********************************************************************//**
362 * @brief Set nul value
363 *
364 * @param[in] value Nul value.
365 *
366 * @todo To correctly reflect the nul value in the data, the image should
367 * be reloaded. However, the image may have been changed, so in principle
368 * saving is needed. However, we may not want to store the image, hence saving
369 * is also not desired. We thus have to develop a method to update the
370 * image information for a new nul value in place ...
371 ***************************************************************************/
372void GFitsImage::nulval(const void* value)
373{
374 // Allocate nul value
375 alloc_nulval(value);
376
377 // Update image
378 //TODO
379
380 // Return
381 return;
382}
383
384
385/***********************************************************************//**
386 * @brief Print column information
387 *
388 * @param[in] chatter Chattiness.
389 * @return String containing column information.
390 *
391 * @todo Format and cfitsio information is mainly for debugging. This could
392 * be vanish in a more stable version of the code, or it could be compiled
393 * in conditionally using a debug option.
394 ***************************************************************************/
395std::string GFitsImage::print(const GChatter& chatter) const
396{
397 // Initialise result string
398 std::string result;
399
400 // Continue only if chatter is not silent
401 if (chatter != SILENT) {
402
403 // Append header
404 result.append("=== GFitsImage ===");
405
406 // Append HDU information
407 result.append("\n"+print_hdu(chatter));
408
409 // Append image dimensions
410 result.append("\n"+gammalib::parformat("Image type"));
411 result.append(typecode(type()));
412 result.append("\n"+gammalib::parformat("Number of dimensions"));
413 result.append(gammalib::str(naxis()));
414 result.append("\n"+gammalib::parformat("Number of image pixels"));
415 result.append(gammalib::str(npix()));
416 for (int i = 0; i < naxis(); ++i) {
417 result.append("\n"+gammalib::parformat("Number of bins in "+gammalib::str(i)));
418 result.append(gammalib::str(naxes(i)));
419 }
420
421 // NORMAL: Append header information
422 if (chatter >= NORMAL) {
423 result.append(+"\n"+m_header.print(gammalib::reduce(chatter)));
424 }
425
426 } // endif: chatter was not silent
427
428 // Return result
429 return result;
430}
431
432
433/*==========================================================================
434 = =
435 = Protected methods =
436 = =
437 ==========================================================================*/
438
439/***********************************************************************//**
440 * @brief Initialise class members
441 ***************************************************************************/
443{
444 // Initialise members
445 m_bitpix = 8;
446 m_naxis = 0;
447 m_naxes = NULL;
448 m_num_pixels = 0;
449 m_anynul = 0;
450
451 // Return
452 return;
453}
454
455
456/***********************************************************************//**
457 * @brief Copy class members
458 *
459 * @param[in] image FITS image to copy
460 ***************************************************************************/
462{
463 // Copy attributes
464 m_bitpix = image.m_bitpix;
465 m_naxis = image.m_naxis;
467 m_anynul = image.m_anynul;
468
469 // Copy axes
470 m_naxes = NULL;
471 if (image.m_naxes != NULL && m_naxis > 0) {
472 m_naxes = new long[m_naxis];
473 for (int i = 0; i < m_naxis; ++i) {
474 m_naxes[i] = image.m_naxes[i];
475 }
476 }
477
478 // Return
479 return;
480}
481
482
483/***********************************************************************//**
484 * @brief Delete class members
485 ***************************************************************************/
487{
488 // Free memory
489 if (m_naxes != NULL) delete [] m_naxes;
490
491 // Mark memory as free
492 m_naxes = NULL;
493
494 // Return
495 return;
496}
497
498
499/***********************************************************************//**
500 * @brief Open FITS image
501 *
502 * @param[in] vptr FITS file pointer
503 *
504 * Open FITS image in FITS file. Opening means connecting the FITS file
505 * pointer to the image and reading the image and axes dimensions.
506 ***************************************************************************/
507void GFitsImage::data_open(void* vptr)
508{
509 // Open image
510 open_image(vptr);
511
512 // Return
513 return;
514}
515
516
517/***********************************************************************//**
518 * @brief Save FITS image
519 *
520 * Saves the image into the FITS file.
521 ***************************************************************************/
523{
524 // Save image
525 save_image(type(), pixels());
526
527 // Return
528 return;
529}
530
531
532/***********************************************************************//**
533 * @brief Close FITS image
534 *
535 * Closing a FITS image resets the object into its initial state. Closing
536 * does NOT save the image into the FITS file. Use the save method for this
537 * purpose.
538 *
539 * @todo Not sure that this is efficient at this level since the pixel array
540 * will not be deallocated!!!
541 ***************************************************************************/
543{
544 // Free members
545 free_members();
546
547 // Initialise members
548 init_members();
549
550 // Return
551 return;
552}
553
554
555/***********************************************************************//**
556 * @brief Connect FITS image
557 *
558 * @param[in] vptr FITS file pointer
559 *
560 * Connects a FITS file pointer to an image. This method actually does
561 * nothing since any GFitsImage can directly access the FITS file pointer
562 * that is stored in the GFitsHDU base class.
563 ***************************************************************************/
565{
566 // Return
567 return;
568}
569
570
571/***********************************************************************//**
572 * @brief Initialise image header
573 *
574 * Initialises the image header by setting the default header cards. This
575 * method requires the members m_bitpix, m_naxis, and m_naxes to be set
576 * previously.
577 ***************************************************************************/
579{
580 // Set image header keywords
581 m_header.append(GFitsHeaderCard("XTENSION", "IMAGE ",
582 "IMAGE extension"));
584 "number of bits per data pixel"));
586 "number of data axes"));
587 for (int i = 0; i < naxis(); ++i) {
588 std::ostringstream s_key;
589 std::ostringstream s_comment;
590 s_key << "NAXIS" << (i+1);
591 s_comment << "length of data axis " << (i+1);
592 m_header.append(GFitsHeaderCard(s_key.str(), naxes(i),
593 s_comment.str()));
594 }
595 m_header.append(GFitsHeaderCard("PCOUNT", 0,
596 "required keyword; must = 0"));
597 m_header.append(GFitsHeaderCard("GCOUNT", 1,
598 "required keyword; must = 1"));
599
600 // Return
601 return;
602}
603
604
605/***********************************************************************//**
606 * @brief Open Image
607 *
608 * @param[in] vptr FITS file void pointer.
609 *
610 * @exception GException::fits_error
611 * FITS error.
612 *
613 * Open FITS image in FITS file. Opening means connecting the FITS file
614 * pointer to the image and reading the image and axes dimensions.
615 ***************************************************************************/
617{
618 // Move to HDU
620
621 // Save the FITS file pointer and the HDU number
622 FPTR_COPY(m_fitsfile, vptr);
623 m_hdunum = FPTR(vptr)->HDUposition;
624
625 // Get the image dimensions
626 int status = 0;
627 status = __ffgidm(FPTR(m_fitsfile), &m_naxis, &status);
628 if (status != 0) {
630 }
631
632 // Reset number of image pixels
633 m_num_pixels = 0;
634
635 // Get the axes dimensions
636 if (m_naxis > 0) {
637
638 // Allocate memory for axes dimensions
639 if (m_naxes != NULL) delete [] m_naxes;
640 m_naxes = new long[m_naxis];
641
642 // Get the axes dimensions
643 status = __ffgisz(FPTR(m_fitsfile), m_naxis, m_naxes, &status);
644 if (status != 0) {
646 }
647
648 // Calculate number of image pixels
649 m_num_pixels = 1;
650 for (int i = 0; i < m_naxis; ++i) {
651 m_num_pixels *= m_naxes[i];
652 }
653
654 } // endif: there is an image
655
656 // Return
657 return;
658}
659
660
661/***********************************************************************//**
662 * @brief Load FITS image
663 *
664 * @param[in] datatype Datatype of pixels to be saved.
665 * @param[in] pixels Pixel array to be saved.
666 * @param[in] nulval Pointer to pixel nul value.
667 * @param[out] anynul Number of nul values encountered during loading.
668 *
669 * @exception GException::fits_error
670 * FITS error.
671 *
672 * Load image pixels from FITS file.
673 ***************************************************************************/
674void GFitsImage::load_image(int datatype, const void* pixels,
675 const void* nulval, int* anynul)
676{
677 // Move to HDU
678 move_to_hdu();
679
680 // Load the image pixels (if there are some ...)
681 if (m_naxis > 0) {
682 long* fpixel = new long[m_naxis];
683 long* lpixel = new long[m_naxis];
684 long* inc = new long[m_naxis];
685 for (int i = 0; i < m_naxis; ++i) {
686 fpixel[i] = 1;
687 lpixel[i] = m_naxes[i];
688 inc[i] = 1;
689 }
690 int status = 0;
691 status = __ffgsv(FPTR(m_fitsfile), datatype, fpixel, lpixel, inc,
692 (void*)nulval, (void*)pixels, anynul, &status);
693 delete [] fpixel;
694 delete [] lpixel;
695 delete [] inc;
696 if (status != 0) {
698 }
699 }
700
701 // Return
702 return;
703}
704
705
706/***********************************************************************//**
707 * @brief Save FITS image
708 *
709 * @param[in] datatype Datatype of pixels to be saved
710 * @param[in] pixels Pixel array to be saved
711 *
712 * @exception GException::runtime_error
713 * No FITS file has been opened.
714 * @exception GException::fits_error
715 * FITS error.
716 *
717 * Save image pixels into FITS file. In case that the HDU does not exist it
718 * is created. In case that the pixel array is empty no data are saved; all
719 * image pixels will be empty in this case.
720 ***************************************************************************/
721void GFitsImage::save_image(int datatype, const void* pixels)
722{
723 // Throw an exception if FITS file is not open
724 if (FPTR(m_fitsfile)->Fptr == NULL) {
725 std::string msg = "FITS file not open. Please open the FITS file "
726 "before saving the image.";
728 }
729
730 // Move to HDU. We use here an explicit cfitsio moveto function since we
731 // want to recover the error code ...
732 int status = 0;
733 int type = 0;
734 status = __ffmahd(FPTR(m_fitsfile), m_hdunum+1, &type, &status);
735
736 // If move was successful but HDU type in file differs from HDU type
737 // of object then replace the HDU in the file
738 if (status == 0 && type != exttype()) {
739 status = __ffdhdu(FPTR(m_fitsfile), NULL, &status);
740 if (status != 0) {
742 }
743 status = __ffiimg(FPTR(m_fitsfile), m_bitpix, m_naxis, m_naxes, &status);
744 //status = __ffiimgll(FPTR(m_fitsfile), m_bitpix, m_naxis, m_naxes, &status);
745 if (status != 0) {
747 }
748 }
749
750 // If HDU does not yet exist in file then create it now
751 if (status == 107) {
752 status = 0;
753 status = __ffcrim(FPTR(m_fitsfile), m_bitpix, m_naxis, m_naxes, &status);
754 if (status != 0) {
756 }
757 }
758 else if (status != 0) {
760 }
761
762 // If HDU seems to be empty then create it now. This is only needed for the
763 // primary HDU, since __ffmahd gives no error if the primary HDU is empty.
764 // By checking the number of keywords in the HDU we detect an empty HDU ...
765 int num = 0;
766 status = __ffghsp(FPTR(m_fitsfile), &num, NULL, &status);
767 if (status != 0) {
769 }
770 if (num == 0) {
771 status = __ffcrim(FPTR(m_fitsfile), m_bitpix, m_naxis, m_naxes, &status);
772 if (status != 0) {
774 }
775 }
776
777 // Make sure that the image on disk has the right size by resizing it
778 status = __ffrsim(FPTR(m_fitsfile), m_bitpix, m_naxis, m_naxes, &status);
779 if (status != 0) {
781 }
782
783 // Save the image pixels (if there are some ...)
784 if (m_naxis > 0 && pixels != NULL) {
785 long* fpixel = new long[m_naxis];
786 long* lpixel = new long[m_naxis];
787 for (int i = 0; i < m_naxis; ++i) {
788 fpixel[i] = 1;
789 lpixel[i] = m_naxes[i];
790 }
791 status = __ffpss(FPTR(m_fitsfile), datatype, fpixel, lpixel,
792 (void*)pixels, &status);
793 delete [] fpixel;
794 delete [] lpixel;
795 if (status != 0) {
797 }
798 }
799
800 // Return
801 return;
802}
803
804
805/***********************************************************************//**
806 * @brief Fetch image pixels
807 *
808 * Fetch the image pixels. This function is in general called if pixel
809 * values should be read or written yet no pixel array is allocated. In case
810 * that pixels existed already before they will be deleted before fetching
811 * new ones.
812 * There are two possibilities to fetch the pixels:
813 * (1) In case that a FITS file is attached to the image, the pixel array
814 * will be loaded from the FITS file using the load_image() method.
815 * (2) In case that no FITS file is attached, a new pixel array will be
816 * allocated that is initalised to zero.
817 ***************************************************************************/
819{
820 // Fetch only if there are pixels in image
821 if (m_num_pixels > 0) {
822
823 // Allocate and initialise fresh memory
824 alloc_data();
825 init_data();
826
827 // If a FITS file is attached then load pixels from FITS file.
828 if (FPTR(m_fitsfile)->Fptr != NULL) {
830 }
831
832 } // endif: there were pixels available
833
834 // Return
835 return;
836}
837
838
839/***********************************************************************//**
840 * @brief Return pixel offset
841 *
842 * @param[in] ix Pixel index [0,...,m_num_pixels-1].
843 *
844 * @exception GException::out_of_range
845 * Pixel index is outside valid range.
846 ***************************************************************************/
847int GFitsImage::offset(const int& ix) const
848{
849 // Check if axis is within the range
850 #if defined(G_RANGE_CHECK)
851 if (ix < 0 || ix >= m_num_pixels) {
852 throw GException::out_of_range(G_OFFSET_1D, "Pixel index", ix, m_num_pixels);
853 }
854 #endif
855
856 // Return index
857 return ix;
858}
859
860
861/***********************************************************************//**
862 * @brief Return 2D pixel offset
863 *
864 * @param[in] ix Pixel index in first dimension (starting from 0).
865 * @param[in] iy Pixel index in second dimension (starting from 0).
866 *
867 * @exception GException::invalid_argument
868 * Pixel array has less than 2 dimensions.
869 * @exception GException::out_of_range
870 * Image axis not valid.
871 *
872 * Computes of offset in the pixel array of a 2D coordinate. This method is
873 * only applicable to pixels arrays that have at least 2 dimenions.
874 ***************************************************************************/
875int GFitsImage::offset(const int& ix, const int& iy) const
876{
877 // Operator is only valid for 2D images
878 if (m_naxis < 2) {
879 std::string msg = "2D pixel access operator used for image with "+
880 gammalib::str(m_naxis)+" dimensions. Please use "
881 "the correct pixel access operator.";
883 }
884
885 // Check if axis is within the range
886 #if defined(G_RANGE_CHECK)
887 if (ix < 0 || ix >= m_naxes[0]) {
889 "Pixel index for first dimension",
890 ix, m_naxes[0]);
891 }
892 if (iy < 0 || iy >= m_naxes[1]) {
894 "Pixel index for second dimension",
895 iy, m_naxes[1]);
896 }
897 #endif
898
899 // Return offset
900 return (ix + iy * m_naxes[0]);
901}
902
903
904/***********************************************************************//**
905 * @brief Return 3D pixel offset
906 *
907 * @param[in] ix Pixel index in first dimension (starting from 0).
908 * @param[in] iy Pixel index in second dimension (starting from 0).
909 * @param[in] iz Pixel index in third dimension (starting from 0).
910 *
911 * @exception GException::invalid_argument
912 * Pixel array has less than 3 dimensions.
913 * @exception GException::out_of_range
914 * Image axis not valid.
915 *
916 * Computes of offset in the pixel array of a 3D coordinate. This method is
917 * only applicable to pixels arrays that have at least 3 dimenions.
918 ***************************************************************************/
919int GFitsImage::offset(const int& ix, const int& iy, const int& iz) const
920{
921 // Operator is only valid for 3D images
922 if (m_naxis < 3) {
923 std::string msg = "3D pixel access operator used for image with "+
924 gammalib::str(m_naxis)+" dimensions. Please use "
925 "the correct pixel access operator.";
927 }
928
929 // Check if axis is within the range
930 #if defined(G_RANGE_CHECK)
931 if (ix < 0 || ix >= m_naxes[0]) {
933 "Pixel index for first dimension",
934 ix, m_naxes[0]);
935 }
936 if (iy < 0 || iy >= m_naxes[1]) {
938 "Pixel index for second dimension",
939 iy, m_naxes[1]);
940 }
941 if (iz < 0 || iz >= m_naxes[2]) {
943 "Pixel index for third dimension",
944 iz, m_naxes[2]);
945 }
946 #endif
947
948 // Return offset
949 return (ix + m_naxes[0] * (iy + iz * m_naxes[1]));
950}
951
952
953/***********************************************************************//**
954 * @brief Return 4D pixel offset
955 *
956 * @param[in] ix Pixel index in first dimension (starting from 0).
957 * @param[in] iy Pixel index in second dimension (starting from 0).
958 * @param[in] iz Pixel index in third dimension (starting from 0).
959 * @param[in] it Pixel index in forth dimension (starting from 0).
960 *
961 * @exception GException::invalid_argument
962 * Pixel array has less than 4 dimensions.
963 * @exception GException::out_of_range
964 * Image axis not valid.
965 *
966 * Computes of offset in the pixel array of a 4D coordinate. This method is
967 * only applicable to pixels arrays that have at least 4 dimenions.
968 ***************************************************************************/
969int GFitsImage::offset(const int& ix, const int& iy, const int& iz,
970 const int& it) const
971{
972 // Operator is only valid for 4D images
973 if (m_naxis < 4) {
974 std::string msg = "4D pixel access operator used for image with "+
975 gammalib::str(m_naxis)+" dimensions. Please use "
976 "the correct pixel access operator.";
978 }
979
980 // Check if axis is within the range
981 #if defined(G_RANGE_CHECK)
982 if (ix < 0 || ix >= m_naxes[0]) {
984 "Pixel index for first dimension",
985 ix, m_naxes[0]);
986 }
987 if (iy < 0 || iy >= m_naxes[1]) {
989 "Pixel index for second dimension",
990 iy, m_naxes[1]);
991 }
992 if (iz < 0 || iz >= m_naxes[2]) {
994 "Pixel index for third dimension",
995 iz, m_naxes[2]);
996 }
997 if (it < 0 || it >= m_naxes[3]) {
999 "Pixel index for third dimension",
1000 it, m_naxes[3]);
1001 }
1002 #endif
1003
1004 // Return offset
1005 return (ix + m_naxes[0] * (iy + m_naxes[1] * (iz + it * m_naxes[2])));
1006}
Exception handler interface definition.
CFITSIO interface header.
#define __ffpss(A, B, C, D, E, F)
#define FPTR(A)
#define __ffrsim(A, B, C, D, E)
#define __ffiimg(A, B, C, D, E)
#define __ffgisz(A, B, C, D)
#define __ffghsp(A, B, C, D)
#define __ffmahd(A, B, C, D)
#define FPTR_COPY(A, B)
#define __ffgidm(A, B, C)
#define __ffdhdu(A, B, C)
#define __ffcrim(A, B, C, D, E)
#define __ffgsv(A, B, C, D, E, F, G, H, I)
#define G_LOAD_IMAGE
#define G_OFFSET_3D
#define G_SAVE_IMAGE
#define G_OFFSET_4D
#define G_NAXES
#define G_OFFSET_1D
#define G_OFFSET_2D
#define G_OPEN_IMAGE
Abstract FITS image base class definition.
FITS file class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ NORMAL
Definition GTypemaps.hpp:36
@ SILENT
Definition GTypemaps.hpp:34
Abstract FITS extension base class.
Definition GFitsHDU.hpp:51
GFitsHeader m_header
HDU header.
Definition GFitsHDU.hpp:136
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
int m_hdunum
HDU number (starting from 0)
Definition GFitsHDU.hpp:134
void move_to_hdu(void)
Move FITS file pointer to HDU.
Definition GFitsHDU.cpp:222
std::string typecode(int type) const
Return typecode as string.
Definition GFitsHDU.cpp:398
std::string print_hdu(const GChatter &chatter=NORMAL) const
Print basic HDU information.
Definition GFitsHDU.cpp:373
Implements FITS header card interface.
GFitsHeaderCard & append(const GFitsHeaderCard &card)
Append or update header card.
std::string print(const GChatter &chatter=NORMAL) const
Print FITS header information.
Abstract FITS image base class.
void open_image(void *vptr)
Open Image.
virtual void init_data(void)=0
virtual void * ptr_nulval(void)=0
int m_naxis
Image dimension.
int naxes(const int &axis) const
Return dimension of an image axis.
const int & bitpix(void) const
Return number of Bits per pixel (negative=floating point)
int offset(const int &ix) const
Return pixel offset.
void free_members(void)
Delete class members.
const int & npix(void) const
Return size of pixel array.
void load_image(int datatype, const void *pixels, const void *nulval, int *anynul)
Load FITS image.
void fetch_data(void)
Fetch image pixels.
long * m_naxes
Number of pixels in each dimension.
const int & naxis(void) const
Return dimension of image.
HDUType exttype(void) const
Return extension type.
virtual void alloc_nulval(const void *value)=0
void data_save(void)
Save FITS image.
void save_image(int datatype, const void *pixels)
Save FITS image.
int m_bitpix
Number of Bits/pixel.
void copy_members(const GFitsImage &image)
Copy class members.
int m_num_pixels
Number of image pixels.
void init_image_header(void)
Initialise image header.
std::string print(const GChatter &chatter=NORMAL) const
Print column information.
void data_open(void *vptr)
Open FITS image.
GFitsImage & operator=(const GFitsImage &image)
Assignment operator.
const int & anynul(void) const
Return number of nul values encountered during loading.
virtual void * ptr_data(void)=0
void data_connect(void *vptr)
Connect FITS image.
GFitsImage(void)
Void constructor.
virtual void alloc_data(void)=0
const void * nulval(void) const
Return nul value.
virtual void * pixels(void)=0
int m_anynul
Number of NULLs encountered.
virtual int type(void) const =0
void data_close(void)
Close FITS image.
virtual ~GFitsImage(void)
Destructor.
void init_members(void)
Initialise class members.
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
int fits_move_to_hdu(const std::string &caller, void *vptr, const int &hdunum=0)
Move to FITS extension.
Definition GFits.cpp:1774
GChatter reduce(const GChatter &chatter)
Reduce chattiness by one level.
Definition GTypemaps.hpp:65