GammaLib 2.1.0.dev
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-2024 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. All cube bins with a
543 * negative content will be excluded from the sum.
544 ***************************************************************************/
545double GCTAEventCube::number(void) const
546{
547 // Initialise result
548 double number = 0.0;
549
550 // Get pointer on skymap pixels
551 const double* pixels = m_map.pixels();
552
553 // Sum event cube
554 if (size() > 0 && pixels != NULL) {
555 for (int i = 0; i < size(); ++i) {
556 if (pixels[i] > 0.0) {
557 number += pixels[i];
558 }
559 }
560 }
561
562 // Return
563 return number;
564}
565
566
567/***********************************************************************//**
568 * @brief Set event cube counts from sky map
569 *
570 * @param[in] counts Event cube counts sky map.
571 *
572 * Sets event cube counts from sky map. The methods also sets all weights to
573 * unity.
574 ***************************************************************************/
576{
577 // Store sky map
578 m_map = counts;
579
580 // Compute sky directions
582
583 // If event cube has pointing then set DETX and DETY coordinates of
584 // instrument direction
585 if (m_has_pnt) {
587 }
588
589 // Set all weights to unity
591 m_weights = 1.0;
592
593 // Return
594 return;
595}
596
597
598/***********************************************************************//**
599 * @brief Return energy of cube layer
600 *
601 * @param[in] index Event cube layer index [0,...,ebins()-1]
602 * @return Energy of event cube layer
603 *
604 * @exception GException::out_of_range
605 * Layer index is out of range.
606 *
607 * Returns the energy of the event cube layer specified by @p index.
608 ***************************************************************************/
609const GEnergy& GCTAEventCube::energy(const int& index) const
610{
611 // Optionally check if the index is valid
612 #if defined(G_RANGE_CHECK)
613 if (index < 0 || index >= ebins()) {
615 "CTA event cube energy axis", index, ebins());
616 }
617 #endif
618
619 // Return energy
620 return (m_energies[index]);
621}
622
623
624/***********************************************************************//**
625 * @brief Print event cube information
626 *
627 * @param[in] chatter Chattiness.
628 * @return String containing event cube information.
629 ***************************************************************************/
630std::string GCTAEventCube::print(const GChatter& chatter) const
631{
632 // Initialise result string
633 std::string result;
634
635 // Continue only if chatter is not silent
636 if (chatter != SILENT) {
637
638 // Append header
639 result.append("=== GCTAEventCube ===");
640 result.append("\n"+gammalib::parformat("Number of events") +
642 result.append("\n"+gammalib::parformat("Number of elements") +
644 result.append("\n"+gammalib::parformat("Number of pixels") +
646 result.append("\n"+gammalib::parformat("Number of energy bins") +
648
649 // Append GTI interval
650 result.append("\n"+gammalib::parformat("Time interval"));
651 if (gti().size() > 0) {
652 result.append(gammalib::str(tstart().mjd()));
653 result.append(" - ");
654 result.append(gammalib::str(tstop().mjd())+" days");
655 }
656 else {
657 result.append("not defined");
658 }
659
660 // Append pointing
661 result.append("\n"+gammalib::parformat("Pointing"));
662 if (m_has_pnt) {
663 result.append(m_pnt.dir().print());
664 }
665 else {
666 result.append("not defined");
667 }
668
669 // Append energy intervals
670 if (gammalib::reduce(chatter) > SILENT) {
671 if (ebounds().size() > 0) {
672 result.append("\n"+ebounds().print(gammalib::reduce(chatter)));
673 }
674 else {
675 result.append("\n"+gammalib::parformat("Energy intervals") +
676 "not defined");
677 }
678 }
679 else {
680 result.append("\n"+gammalib::parformat("Energy interval"));
681 if (ebounds().size() > 0) {
682 result.append(gammalib::str(emin().TeV()));
683 result.append(" - ");
684 result.append(gammalib::str(emax().TeV())+" TeV");
685 }
686 else {
687 result.append("not defined");
688 }
689 }
690
691 // Append skymap definition
692 if (gammalib::reduce(chatter) > SILENT) {
693 result.append("\n"+m_map.print(gammalib::reduce(chatter)));
694 }
695
696 } // endif: chatter was not silent
697
698 // Return result
699 return result;
700}
701
702
703/*==========================================================================
704 = =
705 = Private methods =
706 = =
707 ==========================================================================*/
708
709/***********************************************************************//**
710 * @brief Initialise class members
711 ***************************************************************************/
713{
714 // Initialise members
715 m_map.clear();
717 m_bin.clear();
718 m_time.clear();
719 m_pnt.clear();
720 m_has_pnt = false;
721 m_dirs.clear();
722 m_solidangle.clear();
723 m_energies.clear();
724 m_ewidth.clear();
725 m_ontime = 0.0;
726
727 // Prepare event bin
728 init_bin();
729
730 // Set CTA time reference for GTIs
731 m_gti.reference(GTimeReference(G_CTA_MJDREF, "s", "TT", "LOCAL"));
732
733 // Return
734 return;
735}
736
737
738/***********************************************************************//**
739 * @brief Copy class members
740 *
741 * @param[in] cube Event cube.
742 *
743 * This method copies the class members from another event cube in the actual
744 * object. It also prepares the event bin member that will be returned in
745 * case of an operator access to the class.
746 ***************************************************************************/
748{
749 // Copy members. Note that the event bin is not copied as it will
750 // be initialised later. The event bin serves just as a container of
751 // pointers, hence we do not want to copy over the pointers from the
752 // original class.
753 m_map = cube.m_map;
754 m_weights = cube.m_weights;
755 m_time = cube.m_time;
756 m_pnt = cube.m_pnt;
757 m_has_pnt = cube.m_has_pnt;
758 m_dirs = cube.m_dirs;
760 m_energies = cube.m_energies;
761 m_ewidth = cube.m_ewidth;
762 m_ontime = cube.m_ontime;
763
764 // Copy GTIs
765 m_gti = cube.m_gti;
766
767 // Prepare event bin
768 init_bin();
769
770 // Return
771 return;
772}
773
774
775/***********************************************************************//**
776 * @brief Delete class members
777 ***************************************************************************/
779{
780 // Return
781 return;
782}
783
784
785/***********************************************************************//**
786 * @brief Read CTA counts map from HDU.
787 *
788 * @param[in] hdu Image HDU.
789 *
790 * This method reads a CTA counts map from a FITS HDU. The counts map is
791 * stored in a GSkyMap object.
792 ***************************************************************************/
794{
795 // Load counts map as sky map
796 m_map.read(hdu);
797
798 // Set sky directions
800
801 // If header contains pointing direction then also set DETX and DETY
802 // coordinates
803 if (hdu.has_card("RA_PNT") && hdu.has_card("DEC_PNT")) {
804
805 // Read pointing direction
806 double ra_pnt = hdu.real("RA_PNT");
807 double dec_pnt = hdu.real("DEC_PNT");
808 GSkyDir pnt;
809 pnt.radec_deg(ra_pnt, dec_pnt);
810 m_pnt.dir(pnt);
811 m_has_pnt = true;
812
813 // Set DETX and DETY coordinates of instrument direction
815
816 } // endif: header contained pointing direction
817
818 // Return
819 return;
820}
821
822
823/***********************************************************************//**
824 * @brief Read energy boundaries from HDU.
825 *
826 * @param[in] hdu Energy boundaries table.
827 *
828 * Read the energy boundaries from the HDU.
829 ***************************************************************************/
831{
832 // Read energy boundaries
833 m_ebounds.read(hdu);
834
835 // Set log mean energies and energy widths
836 set_energies();
837
838 // Return
839 return;
840}
841
842
843/***********************************************************************//**
844 * @brief Read GTIs from HDU.
845 *
846 * @param[in] hdu GTI table.
847 *
848 * Reads the Good Time Intervals from the HDU.
849 ***************************************************************************/
851{
852 // Read Good Time Intervals
853 m_gti.read(hdu);
854
855 // Set times
856 set_times();
857
858 // Return
859 return;
860}
861
862
863/***********************************************************************//**
864 * @brief Set sky directions and solid angles of events cube.
865 *
866 * @exception GException::invalid_value
867 * No sky pixels found in event cube.
868 *
869 * This method computes the sky directions and solid angles for all event
870 * cube pixels. Sky directions are stored in an array of GCTAInstDir objects
871 * while solid angles are stored in units of sr in an array of double
872 * precision variables.
873 *
874 * A kluge has been introduced that handles invalid pixels. Invalid pixels
875 * may occur if a Hammer-Aitoff projection is used. In this case, pixels may
876 * lie outside the valid sky region. As invalid pixels lead to exceptions
877 * in the WCS classes, we simply need to catch the exceptions here. Invalid
878 * pixels are signaled by setting the solid angle of the pixel to 0.
879 ***************************************************************************/
881{
882 // Throw an error if we have no sky pixels
883 if (npix() < 1) {
884 std::string msg = "CTA event cube contains no sky pixels. Please "
885 "provide a valid CTA event cube.";
887 }
888
889 // Clear old pixel directions and solid angle
890 m_dirs.clear();
891 m_solidangle.clear();
892
893 // Reserve space for pixel directions and solid angles
894 m_dirs.reserve(npix());
895 m_solidangle.reserve(npix());
896
897 // Set pixel directions and solid angles
898 for (int iy = 0; iy < ny(); ++iy) {
899 for (int ix = 0; ix < nx(); ++ix) {
900 try {
901 GSkyPixel pixel = GSkyPixel(double(ix), double(iy));
902 m_dirs.push_back(GCTAInstDir(m_map.pix2dir(pixel)));
903 m_solidangle.push_back(m_map.solidangle(pixel));
904 }
906 m_dirs.push_back(GCTAInstDir());
907 m_solidangle.push_back(0.0);
908 }
909 }
910 }
911
912 // Return
913 return;
914}
915
916
917/***********************************************************************//**
918 * @brief Set DETX and DETY coordinates
919 *
920 * @param[in] pnt CTA pointing.
921 *
922 * Computes DETX and DETY coordinates for a given pointing direction.
923 ***************************************************************************/
925{
926 // Get number of instrument directions
927 int size = m_dirs.size();
928
929 // Loop over all intstrument directions
930 for (int i = 0; i < size; ++i) {
931
932 // Get sky direction
933 GSkyDir skydir = m_dirs[i].dir();
934
935 // Set instrument direction from sky direction
936 m_dirs[i] = pnt.instdir(skydir);
937
938 } // endfor: looped over all instrument directions
939
940 // Return
941 return;
942}
943
944
945/***********************************************************************//**
946 * @brief Set log mean energies and energy widths of event cube.
947 *
948 * @exception GException::invalid_value
949 * No energy boundaries found in event cube.
950 *
951 * This method computes the log mean energies and the energy widths of the
952 * event cube. The log mean energies and energy widths are stored unit
953 * independent in arrays of GEnergy objects.
954 ***************************************************************************/
956{
957 // Determine number of energy bins
958 int ebins = ebounds().size();
959
960 // Throw an error if we have no energy bins
961 if (ebins < 1) {
962 std::string msg = "CTA event cube contains no energy boundaries. "
963 "Please provide a valid CTA event cube.";
965 }
966
967 // Clear old bin energies and energy widths
968 m_energies.clear();
969 m_ewidth.clear();
970
971 // Reserve space for bin energies and energy widths
972 m_energies.reserve(ebins);
973 m_ewidth.reserve(ebins);
974
975 // Setup bin energies and energy widths
976 for (int i = 0; i < ebins; ++i) {
977 m_energies.push_back(ebounds().elogmean(i));
978 m_ewidth.push_back(ebounds().emax(i) - ebounds().emin(i));
979 }
980
981 // Return
982 return;
983}
984
985
986/***********************************************************************//**
987 * @brief Set mean event time and ontime of event cube
988 *
989 * @exception GException::invalid_value
990 * No Good Time Intervals found.
991 *
992 * Computes the mean time of the event cube by taking the mean between start
993 * and stop time. Computes also the ontime by summing up of all good time
994 * intervals.
995 *
996 * @todo Could add a more sophisticated mean event time computation that
997 * weights by the length of the GTIs, yet so far we do not really use
998 * the mean event time, hence there is no rush to implement this.
999 ***************************************************************************/
1001{
1002 // Throw an error if GTI is empty
1003 if (m_gti.size() < 1) {
1004 std::string msg = "No Good Time Intervals have been found in event "
1005 "cube. Every CTA event cube needs a definition "
1006 "of the Good Time Intervals.";
1008 }
1009
1010 // Compute mean time
1011 m_time = m_gti.tstart() + 0.5 * (m_gti.tstop() - m_gti.tstart());
1012
1013 // Set ontime
1014 m_ontime = m_gti.ontime();
1015
1016 // Return
1017 return;
1018}
1019
1020
1021/***********************************************************************//**
1022 * @brief Initialise event bin
1023 *
1024 * This method initialises the event bin. The event bin is cleared and all
1025 * fixed pointers are set.
1026 ***************************************************************************/
1028{
1029 // Free any existing memory
1031
1032 // Set fixed pointers (those will not be set in set_bin)
1033 m_bin.m_time = &m_time;
1035
1036 // Return
1037 return;
1038}
1039
1040
1041/***********************************************************************//**
1042 * @brief Set event bin
1043 *
1044 * @param[in] index Event index [0,...,size()-1].
1045 *
1046 * @exception GException::out_of_range
1047 * Event index is outside valid range.
1048 * @exception GException::invalid_value
1049 * Energy vectors have not been set up.
1050 * Sky directions and solid angles vectors have not been set up.
1051 *
1052 * This method provides the event attributes to the event bin. The event bin
1053 * is in fact physically stored in the event cube, and only a single event
1054 * bin is indeed allocated. This method sets up the pointers in the event
1055 * bin so that a client can easily access the information of individual bins
1056 * as if they were stored in an array.
1057 ***************************************************************************/
1058void GCTAEventCube::set_bin(const int& index)
1059{
1060 // Optionally check if the index is valid
1061 #if defined(G_RANGE_CHECK)
1062 if (index < 0 || index >= size()) {
1063 throw GException::out_of_range(G_SET_BIN, "Event index", index, size());
1064 }
1065 #endif
1066
1067 // Check for the existence of energies and energy widths
1068 if (m_energies.size() != ebins() || m_ewidth.size() != ebins()) {
1069 std::string msg = "Number of energy bins ("+gammalib::str(ebins())+
1070 ") is incompatible with size of energies ("+
1071 gammalib::str(m_energies.size())+") an/or size of "
1072 "energy widths ("+gammalib::str(m_ewidth.size())+
1073 "). Please provide an correctly initialised event "
1074 "cube.";
1076 }
1077
1078 // Check for the existence of sky directions and solid angles
1079 if (m_dirs.size() != npix() || m_solidangle.size() != npix()) {
1080 std::string msg = "Number of sky pixels ("+gammalib::str(npix())+
1081 ") is incompatible with size of sky directions ("+
1082 gammalib::str(m_dirs.size())+") and/or size of "
1083 "solid angles ("+gammalib::str(m_solidangle.size())+
1084 "). Please provide an correctly initialised event "
1085 "cube.";
1087 }
1088
1089 // Set pixel and energy bin indices.
1090 m_bin.m_ipix = index % npix();
1091 m_bin.m_ieng = index / npix();
1092
1093 // Set pointers
1094 m_bin.m_counts = const_cast<double*>(&(m_map.pixels()[index]));
1096 //m_bin.m_time = &m_time;
1100 //m_bin.m_ontime = &m_ontime;
1101 m_bin.m_weight = const_cast<double*>(&(m_weights.pixels()[index]));
1102
1103 // Return
1104 return;
1105}
#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.
virtual double number(void) const
Return number of events in cube.
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.
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:63
void reference(const GTimeReference &ref)
Set time reference for Good Time Intervals.
Definition GGti.hpp:260
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:815
const GTime & tstop(void) const
Returns latest stop time in Good Time Intervals.
Definition GGti.hpp:210
void read(const GFitsTable &table)
Read Good Time Intervals and time reference from FITS table.
Definition GGti.cpp:772
int size(void) const
Return number of Good Time Intervals.
Definition GGti.hpp:157
const double & ontime(void) const
Returns ontime.
Definition GGti.hpp:243
const GTime & tstart(void) const
Returns earliest start time in Good Time Intervals.
Definition GGti.hpp:197
Sky direction class.
Definition GSkyDir.hpp:62
void radec_deg(const double &ra, const double &dec)
Set equatorial sky direction (degrees)
Definition GSkyDir.cpp:245
std::string print(const GChatter &chatter=NORMAL) const
Print sky direction information.
Definition GSkyDir.cpp:1376
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:427
void clear(void)
Clear instance.
Definition GSkyMap.cpp:1100
const int & nx(void) const
Returns number of pixels in x coordinate.
Definition GSkyMap.hpp:399
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:383
const int & ny(void) const
Returns number of pixels in y coordinate.
Definition GSkyMap.hpp:415
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:513
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:1162
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:508
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:45