GammaLib 2.0.0
Loading...
Searching...
No Matches
GCTAEventCube.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCTAEventCube.cpp - CTA event bin container class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-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 GCTAEventCube.cpp
23 * @brief CTA event bin container 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 "GTools.hpp"
33#include "GFits.hpp"
34#include "GCTAEventCube.hpp"
35#include "GCTATypemaps.hpp"
36
37/* __ Method name definitions ____________________________________________ */
38#define G_NAXIS "GCTAEventCube::naxis(int)"
39#define G_ENERGY "GCTAEventCube::energy(int&)"
40#define G_SET_DIRECTIONS "GCTAEventCube::set_directions()"
41#define G_SET_ENERGIES "GCTAEventCube::set_energies()"
42#define G_SET_TIMES "GCTAEventCube::set_times()"
43#define G_SET_BIN "GCTAEventCube::set_bin(int&)"
44
45/* __ Macros _____________________________________________________________ */
46
47/* __ Coding definitions _________________________________________________ */
48
49/* __ Debug definitions __________________________________________________ */
50
51
52
53/*==========================================================================
54 = =
55 = Constructors/destructors =
56 = =
57 ==========================================================================*/
58
59/***********************************************************************//**
60 * @brief Void constructor
61 ***************************************************************************/
63{
64 // Initialise members
66
67 // Return
68 return;
69}
70
71
72/***********************************************************************//**
73 * @brief File name constructor
74 *
75 * @param[in] filename Counts cube filename.
76 *
77 * Constructs instance of events cube from a counts cube file.
78 ***************************************************************************/
80{
81 // Initialise members
83
84 // Load counts cube
85 load(filename);
86
87 // Return
88 return;
89}
90
91
92/***********************************************************************//**
93 * @brief Constructor
94 *
95 * @param[in] map Sky map.
96 * @param[in] ebds Energy boundaries.
97 * @param[in] gti Good Time intervals.
98 *
99 * Constructs instance of events cube from a sky map, energy boundaries and
100 * Good Time Intervals. All event cube weights are set to unity.
101 ***************************************************************************/
103 const GEbounds& ebds,
104 const GGti& gti) : GEventCube()
105{
106 // Initialise members
107 init_members();
108
109 // Set sky map, energy boundaries and GTI
110 m_map = map;
111 this->ebounds(ebds);
112 this->gti(gti);
113
114 // Set sky directions
116
117 // Set energies
118 set_energies();
119
120 // Set times
121 set_times();
122
123 // Set all weights to unity
125 m_weights = 1.0;
126
127 // Return
128 return;
129}
130
131
132/***********************************************************************//**
133 * @brief Constructor
134 *
135 * @param[in] map Sky map.
136 * @param[in] weights Event cube weights.
137 * @param[in] ebds Energy boundaries.
138 * @param[in] gti Good Time intervals.
139 *
140 * Constructs instance of events cube from a sky map, a map of weights,
141 * energy boundaries and Good Time Intervals.
142 ***************************************************************************/
144 const GSkyMap& weights,
145 const GEbounds& ebds,
146 const GGti& gti) : GEventCube()
147{
148 // Initialise members
149 init_members();
150
151 // Set sky map, energy boundaries and GTI
152 m_map = map;
153 this->ebounds(ebds);
154 this->gti(gti);
155
156 // Set weight map
158
159 // Set sky directions
161
162 // Set energies
163 set_energies();
164
165 // Set times
166 set_times();
167
168 // Return
169 return;
170}
171
172
173/***********************************************************************//**
174 * @brief Copy constructor
175 *
176 * @param[in] cube Event cube.
177 ***************************************************************************/
179{
180 // Initialise members
181 init_members();
182
183 // Copy members
184 copy_members(cube);
185
186 // Return
187 return;
188}
189
190
191/***********************************************************************//**
192 * @brief Destructor
193 ***************************************************************************/
195{
196 // Free members
197 free_members();
198
199 // Return
200 return;
201}
202
203
204/*==========================================================================
205 = =
206 = Operators =
207 = =
208 ==========================================================================*/
209
210/***********************************************************************//**
211 * @brief Assignment operator
212 *
213 * @param[in] cube Event cube.
214 * @return Event cube
215 ***************************************************************************/
217{
218 // Execute only if object is not identical
219 if (this != &cube) {
220
221 // Copy base class members
222 this->GEventCube::operator=(cube);
223
224 // Free members
225 free_members();
226
227 // Initialise members
228 init_members();
229
230 // Copy members
231 copy_members(cube);
232
233 } // endif: object was not identical
234
235 // Return this object
236 return *this;
237}
238
239
240/***********************************************************************//**
241 * @brief Event bin access operator
242 *
243 * @param[in] index Event index [0,...,size()-1].
244 *
245 * Returns pointer to an event bin.
246 ***************************************************************************/
248{
249 // Set event bin
250 set_bin(index);
251
252 // Return pointer
253 return (&m_bin);
254}
255
256
257/***********************************************************************//**
258 * @brief Event bin access operator (const version)
259 *
260 * @param[in] index Event index [0,...,size()-1].
261 *
262 * Returns pointer to an event bin.
263 ***************************************************************************/
264const GCTAEventBin* GCTAEventCube::operator[](const int& index) const
265{
266 // Set event bin (circumvent const correctness)
267 (const_cast<GCTAEventCube*>(this))->set_bin(index);
268
269 // Return pointer
270 return (&m_bin);
271}
272
273
274/*==========================================================================
275 = =
276 = Public methods =
277 = =
278 ==========================================================================*/
279
280/***********************************************************************//**
281 * @brief Clear CTA event cube
282 ***************************************************************************/
284{
285 // Free class members (base and derived classes, derived class first)
286 free_members();
288 this->GEvents::free_members();
289
290 // Initialise members
291 this->GEvents::init_members();
293 init_members();
294
295 // Return
296 return;
297}
298
299
300/***********************************************************************//**
301 * @brief Clone CTA event cube
302 *
303 * @return Pointer to deep copy of CTA event cube.
304 ***************************************************************************/
306{
307 return new GCTAEventCube(*this);
308}
309
310
311/***********************************************************************//**
312 * @brief Return number of bins in event cube
313 ***************************************************************************/
314int GCTAEventCube::size(void) const
315{
316 // Compute number of bins
317 int nbins = m_map.npix() * m_map.nmaps();
318
319 // Return number of bins
320 return nbins;
321}
322
323
324/***********************************************************************//**
325 * @brief Return number of bins in axis
326 *
327 * @param[in] axis Axis [0,...,dim()-1]
328 * @return Number of bins in specified axis
329 *
330 * @exception GException::out_of_range
331 * Axis is out of range.
332 *
333 * Returns the number of bins along a given event cube @p axis.
334 ***************************************************************************/
335int GCTAEventCube::naxis(const int& axis) const
336{
337 // Optionally check if the axis is valid
338 #if defined(G_RANGE_CHECK)
339 if (axis < 0 || axis >= dim()) {
340 throw GException::out_of_range(G_NAXIS, "CTA event cube axis", axis, dim());
341 }
342 #endif
343
344 // Set result
345 int naxis = 0;
346 switch (axis) {
347 case 0:
348 naxis = m_map.nx();
349 break;
350 case 1:
351 naxis = m_map.ny();
352 break;
353 case 2:
354 naxis = m_map.nmaps();
355 break;
356 }
357
358 // Return result
359 return naxis;
360}
361
362
363/***********************************************************************//**
364 * @brief Load CTA event cube from FITS file
365 *
366 * @param[in] filename FITS filename.
367 *
368 * Loads the event cube from a FITS file. See the read() method for more
369 * information about the structure of the FITS file.
370 *
371 * The method clears the object before loading, thus any events residing in
372 * the object before loading will be lost.
373 ***************************************************************************/
374void GCTAEventCube::load(const GFilename& filename)
375{
376 // Clear object
377 clear();
378
379 // Open counts map FITS file
380 GFits fits(filename);
381
382 // Load counts map
383 read(fits);
384
385 // Close FITS file
386 fits.close();
387
388 // Return
389 return;
390}
391
392
393/***********************************************************************//**
394 * @brief Save CTA event cube into FITS file
395 *
396 * @param[in] filename FITS filename.
397 * @param[in] clobber Overwrite existing FITS file.
398 *
399 * Save the CTA event cube into FITS file. See the write() method for more
400 * information about the structure of the FITS file.
401 ***************************************************************************/
402void GCTAEventCube::save(const GFilename& filename,
403 const bool& clobber) const
404{
405 // Create empty FITS file
406 GFits fits;
407
408 // Write event cube
409 write(fits);
410
411 // Save FITS file
412 fits.saveto(filename, clobber);
413
414 // Return
415 return;
416}
417
418
419/***********************************************************************//**
420 * @brief Read CTA event cube from FITS file
421 *
422 * @param[in] fits FITS file.
423 *
424 * Read an event cube from a FITS file. The following HDUs will be read
425 *
426 * COUNTS - Counts cube (or primary extension if COUNTS does not exist)
427 * WEIGHTS - Weights for each counts cube bin (optional)
428 * EBOUNDS - Energy boundaries
429 * GTI - Good Time Intervals
430 *
431 * The method clears the event cube before reading, thus any events residing
432 * in the event cube will be lost.
433 ***************************************************************************/
434void GCTAEventCube::read(const GFits& fits)
435{
436 // Clear object
437 clear();
438
439 // Set counts cube HDU
440 std::string counts_hdu("Primary");
442 counts_hdu = gammalib::extname_cta_counts;
443 }
444
445 // Get HDUs
446 const GFitsImage& hdu_cntmap = *fits.image(counts_hdu);
447 const GFitsTable& hdu_ebounds = *fits.table(gammalib::extname_ebounds);
448 const GFitsTable& hdu_gti = *fits.table(gammalib::extname_gti);
449
450 // Load counts map
451 read_cntmap(hdu_cntmap);
452
453 // Load energy boundaries
454 read_ebds(hdu_ebounds);
455
456 // Load GTIs
457 read_gti(hdu_gti);
458
459 // If a WEIGHTS HDU exist then load it from the FITS file ...
461
462 // Get WEIGHTS HDU
463 const GFitsImage& hdu_weights = *fits.image(gammalib::extname_cta_weights);
464
465 // Read HDU
466 m_weights.read(hdu_weights);
467
468 }
469
470 // ... otherwise set the weight map to unity
471 else {
473 m_weights = 1.0;
474 }
475
476 // Return
477 return;
478}
479
480
481/***********************************************************************//**
482 * @brief Write CTA event cube into FITS file.
483 *
484 * @param[in] fits FITS file.
485 *
486 * Writes CTA event cube into a FITS file. The following HDUs will be written
487 *
488 * COUNTS - Counts cube
489 * WEIGHTS - Weights for each counts cube bin
490 * EBOUNDS - Energy boundaries
491 * GTI - Good Time Intervals
492 *
493 * The counts cube will be written as a double precision sky map. The
494 * weighing cube contains the weight for each counts cube, computed as the
495 * fraction of the event bin that has been selected in filling the counts
496 * cube. This allows to account for proper stacking of observations with
497 * different energy thresholds, or different regions of interest. The energy
498 * boundaries for all counts cube layers are also written, as well as the
499 * Good Time Intervals that have been used in generating the counts cube.
500 ***************************************************************************/
502{
503 // Remove HDUs if they exist already
506 }
509 }
512 }
515 }
516 if (fits.contains("Primary")) {
517 fits.remove("Primary");
518 }
519
520 // Write counts cube
522
523 // Write cube weighting
525
526 // Write energy boundaries
527 ebounds().write(fits);
528
529 // Write Good Time intervals
530 gti().write(fits);
531
532 // Return
533 return;
534}
535
536
537/***********************************************************************//**
538 * @brief Return number of events in cube
539 *
540 * @return Number of events in cube, rounded to nearest integer value.
541 *
542 * Returns the total number of events in the cube, rounded to the nearest
543 * integer value. All cube bins with a negative content will be excluded
544 * from the sum.
545 ***************************************************************************/
547{
548 // Initialise result
549 double number = 0.0;
550
551 // Get pointer on skymap pixels
552 const double* pixels = m_map.pixels();
553
554 // Sum event cube
555 if (size() > 0 && pixels != NULL) {
556 for (int i = 0; i < size(); ++i) {
557 if (pixels[i] > 0.0) {
558 number += pixels[i];
559 }
560 }
561 }
562
563 // Return
564 return int(number+0.5);
565}
566
567
568/***********************************************************************//**
569 * @brief Set event cube counts from sky map
570 *
571 * @param[in] counts Event cube counts sky map.
572 *
573 * Sets event cube counts from sky map. The methods also sets all weights to
574 * unity.
575 ***************************************************************************/
577{
578 // Store sky map
579 m_map = counts;
580
581 // Compute sky directions
583
584 // If event cube has pointing then set DETX and DETY coordinates of
585 // instrument direction
586 if (m_has_pnt) {
588 }
589
590 // Set all weights to unity
592 m_weights = 1.0;
593
594 // Return
595 return;
596}
597
598
599/***********************************************************************//**
600 * @brief Return energy of cube layer
601 *
602 * @param[in] index Event cube layer index [0,...,ebins()-1]
603 * @return Energy of event cube layer
604 *
605 * @exception GException::out_of_range
606 * Layer index is out of range.
607 *
608 * Returns the energy of the event cube layer specified by @p index.
609 ***************************************************************************/
610const GEnergy& GCTAEventCube::energy(const int& index) const
611{
612 // Optionally check if the index is valid
613 #if defined(G_RANGE_CHECK)
614 if (index < 0 || index >= ebins()) {
616 "CTA event cube energy axis", index, ebins());
617 }
618 #endif
619
620 // Return energy
621 return (m_energies[index]);
622}
623
624
625/***********************************************************************//**
626 * @brief Print event cube information
627 *
628 * @param[in] chatter Chattiness.
629 * @return String containing event cube information.
630 ***************************************************************************/
631std::string GCTAEventCube::print(const GChatter& chatter) const
632{
633 // Initialise result string
634 std::string result;
635
636 // Continue only if chatter is not silent
637 if (chatter != SILENT) {
638
639 // Append header
640 result.append("=== GCTAEventCube ===");
641 result.append("\n"+gammalib::parformat("Number of events") +
643 result.append("\n"+gammalib::parformat("Number of elements") +
645 result.append("\n"+gammalib::parformat("Number of pixels") +
647 result.append("\n"+gammalib::parformat("Number of energy bins") +
649
650 // Append GTI interval
651 result.append("\n"+gammalib::parformat("Time interval"));
652 if (gti().size() > 0) {
653 result.append(gammalib::str(tstart().mjd()));
654 result.append(" - ");
655 result.append(gammalib::str(tstop().mjd())+" days");
656 }
657 else {
658 result.append("not defined");
659 }
660
661 // Append pointing
662 result.append("\n"+gammalib::parformat("Pointing"));
663 if (m_has_pnt) {
664 result.append(m_pnt.dir().print());
665 }
666 else {
667 result.append("not defined");
668 }
669
670 // Append energy intervals
671 if (gammalib::reduce(chatter) > SILENT) {
672 if (ebounds().size() > 0) {
673 result.append("\n"+ebounds().print(gammalib::reduce(chatter)));
674 }
675 else {
676 result.append("\n"+gammalib::parformat("Energy intervals") +
677 "not defined");
678 }
679 }
680 else {
681 result.append("\n"+gammalib::parformat("Energy interval"));
682 if (ebounds().size() > 0) {
683 result.append(gammalib::str(emin().TeV()));
684 result.append(" - ");
685 result.append(gammalib::str(emax().TeV())+" TeV");
686 }
687 else {
688 result.append("not defined");
689 }
690 }
691
692 // Append skymap definition
693 if (gammalib::reduce(chatter) > SILENT) {
694 result.append("\n"+m_map.print(gammalib::reduce(chatter)));
695 }
696
697 } // endif: chatter was not silent
698
699 // Return result
700 return result;
701}
702
703
704/*==========================================================================
705 = =
706 = Private methods =
707 = =
708 ==========================================================================*/
709
710/***********************************************************************//**
711 * @brief Initialise class members
712 ***************************************************************************/
714{
715 // Initialise members
716 m_map.clear();
718 m_bin.clear();
719 m_time.clear();
720 m_pnt.clear();
721 m_has_pnt = false;
722 m_dirs.clear();
723 m_solidangle.clear();
724 m_energies.clear();
725 m_ewidth.clear();
726 m_ontime = 0.0;
727
728 // Prepare event bin
729 init_bin();
730
731 // Set CTA time reference for GTIs
732 m_gti.reference(GTimeReference(G_CTA_MJDREF, "s", "TT", "LOCAL"));
733
734 // Return
735 return;
736}
737
738
739/***********************************************************************//**
740 * @brief Copy class members
741 *
742 * @param[in] cube Event cube.
743 *
744 * This method copies the class members from another event cube in the actual
745 * object. It also prepares the event bin member that will be returned in
746 * case of an operator access to the class.
747 ***************************************************************************/
749{
750 // Copy members. Note that the event bin is not copied as it will
751 // be initialised later. The event bin serves just as a container of
752 // pointers, hence we do not want to copy over the pointers from the
753 // original class.
754 m_map = cube.m_map;
755 m_weights = cube.m_weights;
756 m_time = cube.m_time;
757 m_pnt = cube.m_pnt;
758 m_has_pnt = cube.m_has_pnt;
759 m_dirs = cube.m_dirs;
761 m_energies = cube.m_energies;
762 m_ewidth = cube.m_ewidth;
763 m_ontime = cube.m_ontime;
764
765 // Copy GTIs
766 m_gti = cube.m_gti;
767
768 // Prepare event bin
769 init_bin();
770
771 // Return
772 return;
773}
774
775
776/***********************************************************************//**
777 * @brief Delete class members
778 ***************************************************************************/
780{
781 // Return
782 return;
783}
784
785
786/***********************************************************************//**
787 * @brief Read CTA counts map from HDU.
788 *
789 * @param[in] hdu Image HDU.
790 *
791 * This method reads a CTA counts map from a FITS HDU. The counts map is
792 * stored in a GSkyMap object.
793 ***************************************************************************/
795{
796 // Load counts map as sky map
797 m_map.read(hdu);
798
799 // Set sky directions
801
802 // If header contains pointing direction then also set DETX and DETY
803 // coordinates
804 if (hdu.has_card("RA_PNT") && hdu.has_card("DEC_PNT")) {
805
806 // Read pointing direction
807 double ra_pnt = hdu.real("RA_PNT");
808 double dec_pnt = hdu.real("DEC_PNT");
809 GSkyDir pnt;
810 pnt.radec_deg(ra_pnt, dec_pnt);
811 m_pnt.dir(pnt);
812 m_has_pnt = true;
813
814 // Set DETX and DETY coordinates of instrument direction
816
817 } // endif: header contained pointing direction
818
819 // Return
820 return;
821}
822
823
824/***********************************************************************//**
825 * @brief Read energy boundaries from HDU.
826 *
827 * @param[in] hdu Energy boundaries table.
828 *
829 * Read the energy boundaries from the HDU.
830 ***************************************************************************/
832{
833 // Read energy boundaries
834 m_ebounds.read(hdu);
835
836 // Set log mean energies and energy widths
837 set_energies();
838
839 // Return
840 return;
841}
842
843
844/***********************************************************************//**
845 * @brief Read GTIs from HDU.
846 *
847 * @param[in] hdu GTI table.
848 *
849 * Reads the Good Time Intervals from the HDU.
850 ***************************************************************************/
852{
853 // Read Good Time Intervals
854 m_gti.read(hdu);
855
856 // Set times
857 set_times();
858
859 // Return
860 return;
861}
862
863
864/***********************************************************************//**
865 * @brief Set sky directions and solid angles of events cube.
866 *
867 * @exception GException::invalid_value
868 * No sky pixels found in event cube.
869 *
870 * This method computes the sky directions and solid angles for all event
871 * cube pixels. Sky directions are stored in an array of GCTAInstDir objects
872 * while solid angles are stored in units of sr in an array of double
873 * precision variables.
874 *
875 * A kluge has been introduced that handles invalid pixels. Invalid pixels
876 * may occur if a Hammer-Aitoff projection is used. In this case, pixels may
877 * lie outside the valid sky region. As invalid pixels lead to exceptions
878 * in the WCS classes, we simply need to catch the exceptions here. Invalid
879 * pixels are signaled by setting the solid angle of the pixel to 0.
880 ***************************************************************************/
882{
883 // Throw an error if we have no sky pixels
884 if (npix() < 1) {
885 std::string msg = "CTA event cube contains no sky pixels. Please "
886 "provide a valid CTA event cube.";
888 }
889
890 // Clear old pixel directions and solid angle
891 m_dirs.clear();
892 m_solidangle.clear();
893
894 // Reserve space for pixel directions and solid angles
895 m_dirs.reserve(npix());
896 m_solidangle.reserve(npix());
897
898 // Set pixel directions and solid angles
899 for (int iy = 0; iy < ny(); ++iy) {
900 for (int ix = 0; ix < nx(); ++ix) {
901 try {
902 GSkyPixel pixel = GSkyPixel(double(ix), double(iy));
903 m_dirs.push_back(GCTAInstDir(m_map.pix2dir(pixel)));
904 m_solidangle.push_back(m_map.solidangle(pixel));
905 }
907 m_dirs.push_back(GCTAInstDir());
908 m_solidangle.push_back(0.0);
909 }
910 }
911 }
912
913 // Return
914 return;
915}
916
917
918/***********************************************************************//**
919 * @brief Set DETX and DETY coordinates
920 *
921 * @param[in] pnt CTA pointing.
922 *
923 * Computes DETX and DETY coordinates for a given pointing direction.
924 ***************************************************************************/
926{
927 // Get number of instrument directions
928 int size = m_dirs.size();
929
930 // Loop over all intstrument directions
931 for (int i = 0; i < size; ++i) {
932
933 // Get sky direction
934 GSkyDir skydir = m_dirs[i].dir();
935
936 // Set instrument direction from sky direction
937 m_dirs[i] = pnt.instdir(skydir);
938
939 } // endfor: looped over all instrument directions
940
941 // Return
942 return;
943}
944
945
946/***********************************************************************//**
947 * @brief Set log mean energies and energy widths of event cube.
948 *
949 * @exception GException::invalid_value
950 * No energy boundaries found in event cube.
951 *
952 * This method computes the log mean energies and the energy widths of the
953 * event cube. The log mean energies and energy widths are stored unit
954 * independent in arrays of GEnergy objects.
955 ***************************************************************************/
957{
958 // Determine number of energy bins
959 int ebins = ebounds().size();
960
961 // Throw an error if we have no energy bins
962 if (ebins < 1) {
963 std::string msg = "CTA event cube contains no energy boundaries. "
964 "Please provide a valid CTA event cube.";
966 }
967
968 // Clear old bin energies and energy widths
969 m_energies.clear();
970 m_ewidth.clear();
971
972 // Reserve space for bin energies and energy widths
973 m_energies.reserve(ebins);
974 m_ewidth.reserve(ebins);
975
976 // Setup bin energies and energy widths
977 for (int i = 0; i < ebins; ++i) {
978 m_energies.push_back(ebounds().elogmean(i));
979 m_ewidth.push_back(ebounds().emax(i) - ebounds().emin(i));
980 }
981
982 // Return
983 return;
984}
985
986
987/***********************************************************************//**
988 * @brief Set mean event time and ontime of event cube
989 *
990 * @exception GException::invalid_value
991 * No Good Time Intervals found.
992 *
993 * Computes the mean time of the event cube by taking the mean between start
994 * and stop time. Computes also the ontime by summing up of all good time
995 * intervals.
996 *
997 * @todo Could add a more sophisticated mean event time computation that
998 * weights by the length of the GTIs, yet so far we do not really use
999 * the mean event time, hence there is no rush to implement this.
1000 ***************************************************************************/
1002{
1003 // Throw an error if GTI is empty
1004 if (m_gti.size() < 1) {
1005 std::string msg = "No Good Time Intervals have been found in event "
1006 "cube. Every CTA event cube needs a definition "
1007 "of the Good Time Intervals.";
1009 }
1010
1011 // Compute mean time
1012 m_time = m_gti.tstart() + 0.5 * (m_gti.tstop() - m_gti.tstart());
1013
1014 // Set ontime
1015 m_ontime = m_gti.ontime();
1016
1017 // Return
1018 return;
1019}
1020
1021
1022/***********************************************************************//**
1023 * @brief Initialise event bin
1024 *
1025 * This method initialises the event bin. The event bin is cleared and all
1026 * fixed pointers are set.
1027 ***************************************************************************/
1029{
1030 // Free any existing memory
1032
1033 // Set fixed pointers (those will not be set in set_bin)
1034 m_bin.m_time = &m_time;
1036
1037 // Return
1038 return;
1039}
1040
1041
1042/***********************************************************************//**
1043 * @brief Set event bin
1044 *
1045 * @param[in] index Event index [0,...,size()-1].
1046 *
1047 * @exception GException::out_of_range
1048 * Event index is outside valid range.
1049 * @exception GException::invalid_value
1050 * Energy vectors have not been set up.
1051 * Sky directions and solid angles vectors have not been set up.
1052 *
1053 * This method provides the event attributes to the event bin. The event bin
1054 * is in fact physically stored in the event cube, and only a single event
1055 * bin is indeed allocated. This method sets up the pointers in the event
1056 * bin so that a client can easily access the information of individual bins
1057 * as if they were stored in an array.
1058 ***************************************************************************/
1059void GCTAEventCube::set_bin(const int& index)
1060{
1061 // Optionally check if the index is valid
1062 #if defined(G_RANGE_CHECK)
1063 if (index < 0 || index >= size()) {
1064 throw GException::out_of_range(G_SET_BIN, "Event index", index, size());
1065 }
1066 #endif
1067
1068 // Check for the existence of energies and energy widths
1069 if (m_energies.size() != ebins() || m_ewidth.size() != ebins()) {
1070 std::string msg = "Number of energy bins ("+gammalib::str(ebins())+
1071 ") is incompatible with size of energies ("+
1072 gammalib::str(m_energies.size())+") an/or size of "
1073 "energy widths ("+gammalib::str(m_ewidth.size())+
1074 "). Please provide an correctly initialised event "
1075 "cube.";
1077 }
1078
1079 // Check for the existence of sky directions and solid angles
1080 if (m_dirs.size() != npix() || m_solidangle.size() != npix()) {
1081 std::string msg = "Number of sky pixels ("+gammalib::str(npix())+
1082 ") is incompatible with size of sky directions ("+
1083 gammalib::str(m_dirs.size())+") and/or size of "
1084 "solid angles ("+gammalib::str(m_solidangle.size())+
1085 "). Please provide an correctly initialised event "
1086 "cube.";
1088 }
1089
1090 // Set pixel and energy bin indices.
1091 m_bin.m_ipix = index % npix();
1092 m_bin.m_ieng = index / npix();
1093
1094 // Set pointers
1095 m_bin.m_counts = const_cast<double*>(&(m_map.pixels()[index]));
1097 //m_bin.m_time = &m_time;
1101 //m_bin.m_ontime = &m_ontime;
1102 m_bin.m_weight = const_cast<double*>(&(m_weights.pixels()[index]));
1103
1104 // Return
1105 return;
1106}
#define G_SET_TIMES
#define G_SET_ENERGIES
#define G_SET_BIN
#define G_NAXIS
#define G_ENERGY
#define G_SET_DIRECTIONS
CTA event bin container class interface definition.
Definition of GammaLib CTA typemaps.
#define G_CTA_MJDREF
Reference of CTA time frame.
Exception handler interface definition.
FITS file class interface definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
GCTAEventBin class interface definition.
int m_ieng
Index of energy layer.
double * m_weight
Pointer to weight of bin.
double * m_solidangle
Pointer to solid angle of pixel (sr)
GEnergy * m_energy
Pointer to bin energy.
double * m_counts
Pointer to number of counts.
GEnergy * m_ewidth
Pointer to energy width of bin.
GTime * m_time
Pointer to bin time.
void free_members(void)
Delete class members.
int m_ipix
Index in spatial map.
GCTAInstDir * m_dir
Pointer to bin direction.
double * m_ontime
Pointer to ontime of bin (seconds)
virtual void clear(void)
Clear eventbin.
CTA event bin container class.
void init_bin(void)
Initialise event bin.
virtual void load(const GFilename &filename)
Load CTA event cube from FITS file.
const GEnergy & energy(const int &index) const
Return energy of cube layer.
const GSkyMap & counts(void) const
Return event cube counts as sky map.
GSkyMap m_weights
Cube weights stored as sky map.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print event cube information.
virtual void clear(void)
Clear CTA event cube.
void read_cntmap(const GFitsImage &hdu)
Read CTA counts map from HDU.
void copy_members(const GCTAEventCube &cube)
Copy class members.
GCTAEventBin m_bin
Actual event bin.
virtual int dim(void) const
Return dimension of event cube.
virtual int size(void) const
Return number of bins in event cube.
void read_ebds(const GFitsTable &hdu)
Read energy boundaries from HDU.
int npix(void) const
Return number of pixels in one energy bins of the event cube.
int nx(void) const
Return number of bins in X direction.
void set_detxy(const GCTAPointing &pnt)
Set DETX and DETY coordinates.
double m_ontime
Event cube ontime (sec)
void init_members(void)
Initialise class members.
GCTAEventCube(void)
Void constructor.
virtual int naxis(const int &axis) const
Return number of bins in axis.
virtual GCTAEventCube * clone(void) const
Clone CTA event cube.
std::vector< double > m_solidangle
Array of solid angles (sr)
std::vector< GCTAInstDir > m_dirs
Array of event directions.
GTime m_time
Event cube mean time.
std::vector< GEnergy > m_ewidth
Array of energy bin widths.
virtual void set_energies(void)
Set log mean energies and energy widths of event cube.
virtual GCTAEventCube & operator=(const GCTAEventCube &cube)
Assignment operator.
virtual GCTAEventBin * operator[](const int &index)
Event bin access operator.
virtual void read(const GFits &file)
Read CTA event cube from FITS file.
virtual void save(const GFilename &filename, const bool &clobber=false) const
Save CTA event cube into FITS file.
void free_members(void)
Delete class members.
bool m_has_pnt
Event cube has pointing.
const GSkyMap & weights(void) const
Return event cube weights as sky map.
virtual void write(GFits &file) const
Write CTA event cube into FITS file.
virtual ~GCTAEventCube(void)
Destructor.
virtual void set_times(void)
Set mean event time and ontime of event cube.
GSkyMap m_map
Counts cube stored as sky map.
void set_bin(const int &index)
Set event bin.
GCTAPointing m_pnt
Event cube pointing.
void read_gti(const GFitsTable &hdu)
Read GTIs from HDU.
std::vector< GEnergy > m_energies
Array of log mean energies.
void set_directions(void)
Set sky directions and solid angles of events cube.
int ebins(void) const
Return number of energy bins in the event cube.
virtual int number(void) const
Return number of events in cube.
int ny(void) const
Return number of bins in Y direction.
CTA instrument direction class.
CTA pointing class.
GCTAInstDir instdir(const GSkyDir &skydir) const
Get instrument direction from sky direction.
const GSkyDir & dir(void) const
Return pointing sky direction.
void clear(void)
Clear CTA pointing.
Energy boundaries container class.
Definition GEbounds.hpp:60
void read(const GFitsTable &table)
Read energy boundaries from FITS table.
Definition GEbounds.cpp:761
int size(void) const
Return number of energy boundaries.
Definition GEbounds.hpp:163
void write(GFits &file, const std::string &extname=gammalib::extname_ebounds, const std::string &unit="keV") const
Write energy boundaries into FITS object.
Definition GEbounds.cpp:816
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
Abstract event bin container class.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
virtual GEventCube & operator=(const GEventCube &cube)
Assignment operator.
void free_members(void)
Delete class members.
Definition GEvents.cpp:206
GGti m_gti
Good time intervals covered by events.
Definition GEvents.hpp:112
const GTime & tstart(void) const
Return start time.
Definition GEvents.hpp:146
GEbounds m_ebounds
Energy boundaries covered by events.
Definition GEvents.hpp:111
const GGti & gti(void) const
Return Good Time Intervals.
Definition GEvents.hpp:134
void init_members(void)
Initialise class members.
Definition GEvents.cpp:176
const GTime & tstop(void) const
Return stop time.
Definition GEvents.hpp:158
const GEbounds & ebounds(void) const
Return energy boundaries.
Definition GEvents.hpp:122
const GEnergy & emax(void) const
Return maximum energy.
Definition GEvents.hpp:182
const GEnergy & emin(void) const
Return minimum energy.
Definition GEvents.hpp:170
Filename class.
Definition GFilename.hpp:62
bool has_card(const int &cardno) const
Check existence of header card.
Definition GFitsHDU.hpp:233
double real(const std::string &keyname) const
Return card value as double precision.
Definition GFitsHDU.hpp:423
Abstract FITS image base class.
Abstract interface for FITS table.
FITS file class.
Definition GFits.hpp:63
void saveto(const GFilename &filename, const bool &clobber=false)
Saves to specified FITS file.
Definition GFits.cpp:1293
bool contains(const int &extno) const
Check if HDU exists in FITS file.
Definition GFits.hpp:282
GFitsImage * image(const int &extno)
Get pointer to image HDU.
Definition GFits.cpp:368
void close(void)
Close FITS file.
Definition GFits.cpp:1342
void remove(const int &extno)
Remove HDU from FITS file.
Definition GFits.cpp:862
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition GFits.cpp:482
Good Time Interval class.
Definition GGti.hpp:62
void reference(const GTimeReference &ref)
Set time reference for Good Time Intervals.
Definition GGti.hpp:257
void write(GFits &fits, const std::string &extname=gammalib::extname_gti) const
Write Good Time Intervals and time reference into FITS object.
Definition GGti.cpp:796
const GTime & tstop(void) const
Returns latest stop time in Good Time Intervals.
Definition GGti.hpp:207
void read(const GFitsTable &table)
Read Good Time Intervals and time reference from FITS table.
Definition GGti.cpp:753
int size(void) const
Return number of Good Time Intervals.
Definition GGti.hpp:154
const double & ontime(void) const
Returns ontime.
Definition GGti.hpp:240
const GTime & tstart(void) const
Returns earliest start time in Good Time Intervals.
Definition GGti.hpp:194
Sky direction class.
Definition GSkyDir.hpp:62
void radec_deg(const double &ra, const double &dec)
Set equatorial sky direction (degrees)
Definition GSkyDir.cpp:224
std::string print(const GChatter &chatter=NORMAL) const
Print sky direction information.
Definition GSkyDir.cpp:1227
Sky map class.
Definition GSkyMap.hpp:89
double solidangle(const int &index) const
Returns solid angle of pixel.
Definition GSkyMap.cpp:1858
const int & nmaps(void) const
Returns number of maps.
Definition GSkyMap.hpp:389
void clear(void)
Clear instance.
Definition GSkyMap.cpp:1100
const int & nx(void) const
Returns number of pixels in x coordinate.
Definition GSkyMap.hpp:361
void read(const GFitsHDU &hdu)
Read skymap from FITS HDU.
Definition GSkyMap.cpp:2664
const int & npix(void) const
Returns number of pixels.
Definition GSkyMap.hpp:345
const int & ny(void) const
Returns number of pixels in y coordinate.
Definition GSkyMap.hpp:377
GFitsHDU * write(GFits &file, const std::string &extname="") const
Write sky map into FITS file.
Definition GSkyMap.cpp:2697
GSkyDir pix2dir(const GSkyPixel &pixel) const
Returns sky direction of pixel.
Definition GSkyMap.cpp:1360
const double * pixels(void) const
Returns pointer to pixel data.
Definition GSkyMap.hpp:475
std::string print(const GChatter &chatter=NORMAL) const
Print sky map.
Definition GSkyMap.cpp:2787
Sky map pixel class.
Definition GSkyPixel.hpp:74
Implements a time reference.
void clear(void)
Clear time.
Definition GTime.cpp:252
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
const std::string extname_ebounds
Definition GEbounds.hpp:44
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
const std::string extname_cta_counts
GChatter reduce(const GChatter &chatter)
Reduce chattiness by one level.
Definition GTypemaps.hpp:65
const std::string extname_cta_weights
const std::string extname_gti
Definition GGti.hpp:44