GammaLib 2.2.0.dev
Loading...
Searching...
No Matches
GCTAEventList.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCTAEventList.cpp - CTA event list class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-2026 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 GCTAEventList.cpp
23 * @brief CTA event list class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <typeinfo>
32#include <cstdio> // sprintf
33#include "GTools.hpp"
34#include "GMath.hpp"
35#include "GFilename.hpp"
36#include "GFits.hpp"
37#include "GFitsTable.hpp"
38#include "GFitsBinTable.hpp"
39#include "GFitsTableCol.hpp"
42#include "GFitsTableLongCol.hpp"
44#include "GTime.hpp"
45#include "GTimeReference.hpp"
46#include "GCTAEventList.hpp"
47#include "GCTATypemaps.hpp"
48#include "GCTASupport.hpp"
49
50/* __ Method name definitions ____________________________________________ */
51#define G_OPERATOR "GCTAEventList::operator[](int&)"
52#define G_ROI "GCTAEventList::roi(GRoi&)"
53#define G_APPEND_COLUMN "GCTAEventList::append_column(GFitsTableCol&)"
54#define G_SET_MC_ID_NAMES "GCTAEventList::set_mc_id_names(std::vector<int>&,"\
55 " std::vector<std::string>&)"
56#define G_FETCH "GCTAEventList::fetch()"
57#define G_WRITE_DS_KEYS "GCTAEventList::write_ds_keys(GFitsHDU&, "\
58 "const std::string&) const"
59
60/* __ Macros _____________________________________________________________ */
61
62/* __ Coding definitions _________________________________________________ */
63
64/* __ Debug definitions __________________________________________________ */
65
66
67/*==========================================================================
68 = =
69 = Constructors/destructors =
70 = =
71 ==========================================================================*/
72
73/***********************************************************************//**
74 * @brief Void constructor
75 *
76 * Constructs empty event list.
77 ***************************************************************************/
79{
80 // Initialise members
82
83 // Return
84 return;
85}
86
87
88/***********************************************************************//**
89 * @brief File name constructor
90 *
91 * @param[in] filename Counts cube filename.
92 *
93 * Constructs event list by loading the events from a FITS file.
94 ***************************************************************************/
96{
97 // Initialise members
99
100 // Load event list
101 load(filename);
102
103 // Return
104 return;
105}
106
107
108/***********************************************************************//**
109 * @brief Copy constructor
110 *
111 * @param[in] list Event list.
112 *
113 * Constructs event list by coping from another event list.
114 ***************************************************************************/
116{
117 // Initialise members
118 init_members();
119
120 // Copy members
121 copy_members(list);
122
123 // Return
124 return;
125}
126
127
128/***********************************************************************//**
129 * @brief Destructor
130 *
131 * Destructs event list.
132 ***************************************************************************/
134{
135 // Free members
136 free_members();
137
138 // Return
139 return;
140}
141
142
143/*==========================================================================
144 = =
145 = Operators =
146 = =
147 ==========================================================================*/
148
149/***********************************************************************//**
150 * @brief Assignment operator
151 *
152 * @param[in] list Event list.
153 * @return Event list.
154 *
155 * Assigns events from another event list.
156 ***************************************************************************/
158{
159 // Execute only if object is not identical
160 if (this != &list) {
161
162 // Copy base class members
163 this->GEventList::operator=(list);
164
165 // Free members
166 free_members();
167
168 // Initialise members
169 init_members();
170
171 // Copy members
172 copy_members(list);
173
174 } // endif: object was not identical
175
176 // Return this object
177 return *this;
178}
179
180
181/***********************************************************************//**
182 * @brief Event atom access operator
183 *
184 * @param[in] index Event index [0,...,size()-1].
185 * @return Pointer to event atom.
186 *
187 * @exception GException::out_of_range
188 * Event index outside valid range.
189 *
190 * Returns pointer to an event atom.
191 ***************************************************************************/
193{
194 // Make sure that the events are online
195 fetch();
196
197 // Optionally check if the index is valid
198 #if defined(G_RANGE_CHECK)
199 if (index < 0 || index >= size()) {
200 throw GException::out_of_range(G_OPERATOR, "Event index",
201 index, size());
202 }
203 #endif
204
205 // Return pointer
206 return (&(m_events[index]));
207}
208
209
210/***********************************************************************//**
211 * @brief Event atom access operator
212 *
213 * @param[in] index Event index [0,...,size()-1].
214 * @return Pointer to event atom.
215 *
216 * @exception GException::out_of_range
217 * Event index outside valid range.
218 *
219 * Returns pointer to an event atom.
220 ***************************************************************************/
221const GCTAEventAtom* GCTAEventList::operator[](const int& index) const
222{
223 // Make sure that the events are online
224 fetch();
225
226 // Optionally check if the index is valid
227 #if defined(G_RANGE_CHECK)
228 if (index < 0 || index >= size()) {
229 throw GException::out_of_range(G_OPERATOR, "Event index",
230 index, size());
231 }
232 #endif
233
234 // Return pointer
235 return (&(m_events[index]));
236}
237
238
239/*==========================================================================
240 = =
241 = Public methods =
242 = =
243 ==========================================================================*/
244
245/***********************************************************************//**
246 * @brief Clear event list
247 *
248 * Clear event list.
249 ***************************************************************************/
251{
252 // Free class members (base and derived classes, derived class first)
253 free_members();
255 this->GEvents::free_members();
256
257 // Initialise members
258 this->GEvents::init_members();
260 init_members();
261
262 // Return
263 return;
264}
265
266
267/***********************************************************************//**
268 * @brief Clone event list
269 *
270 * @return Pointer to deep copy of event list.
271 *
272 * Returns a pointer to a deep copy of the event list.
273 ***************************************************************************/
275{
276 // Clone event list
277 return new GCTAEventList(*this);
278}
279
280
281/***********************************************************************//**
282 * @brief Load events from FITS file.
283 *
284 * @param[in] filename FITS file name.
285 *
286 * Loads the event list from a FITS file. See the read() method for details.
287 ***************************************************************************/
288void GCTAEventList::load(const GFilename& filename)
289{
290 // Open FITS file
291 GFits fits(filename);
292
293 // Read event list
294 read(fits);
295
296 // Close FITS file
297 fits.close();
298
299 // Return
300 return;
301}
302
303
304/***********************************************************************//**
305 * @brief Save events into FITS file.
306 *
307 * @param[in] filename FITS file name.
308 * @param[in] clobber Overwrite existing FITS file (default: false).
309 *
310 * Saves the event list into a FITS file. See the write() method for details.
311 ***************************************************************************/
312void GCTAEventList::save(const GFilename& filename,
313 const bool& clobber) const
314{
315 // Open or create FITS file (without extension name since the requested
316 // extension may not yet exist in the file)
317 GFits fits(filename.url(), true);
318
319 // Write event list
320 write(fits);
321
322 // Save FITS file
323 fits.save(clobber);
324
325 // Return
326 return;
327}
328
329
330/***********************************************************************//**
331 * @brief Read events from FITS file.
332 *
333 * @param[in] fits FITS file.
334 *
335 * Reads the event list from a FITS file.
336 *
337 * The events will be read by default from the extension `EVENTS` unless
338 * an extension name is explicitly specified in the FITS file name. The
339 * FITS header of the extension will be scanned for data sub-space keywords
340 * to extract the energy boundaries, the region of interest, as well as the
341 * extension name for the Good Time Intervals. If no extension name for
342 * Good Time Intervals is found it is expected that the Good Time Intervals
343 * reside in the `GTI` extension.
344 *
345 * If a Good Time Intervals is found in the same FITS file, the Good Time
346 * Intervals will be loaded. Otherwise, a single Good Time Interval will
347 * be assumed based on the `TSTART` and `TSTOP` keywords found in the header
348 * of the event list.
349 *
350 * The method clears the event list before reading, thus any events that
351 * existed before in the event list will be lost. Note that the method will
352 * actually not read the events but only the event metadata. The events are
353 * only read from the FITS file when they are actually need. This reduces
354 * the memory requirements. Events can be manually loaded into memory using
355 * the fetch() method. Events can be unloaded using the dispose() method, but
356 * the user has to take care of saving the events to disk in case he wants
357 * to keep them for further use.
358 ***************************************************************************/
359void GCTAEventList::read(const GFits& fits)
360{
361 // Clear object
362 clear();
363
364 // Store the FITS file name
365 m_filename = fits.filename();
366
367 // Initialise events extension name
368 std::string extname = fits.filename().extname(gammalib::extname_cta_events);
369
370 // Get event list HDU
371 const GFitsTable& events = *fits.table(extname);
372
373 // Determine number of events from event list HDU
374 m_num_events = events.nrows();
375
376 // Signal presence of "DETX" and "DETY" columns
377 if (events.contains("DETX") && events.contains("DETY")) {
378 m_has_detxy = true;
379 }
380 else {
381 m_has_detxy = false;
382 }
383
384 // Signal presence of "PHASE" column
385 if (events.contains("PHASE")) {
386 m_has_phase = true;
387 }
388 else {
389 m_has_phase = false;
390 }
391
392 // Signal presence of "MC_ID" column
393 if (events.contains("MC_ID")) {
394 m_has_mc_id = true;
395 }
396 else {
397 m_has_mc_id = false;
398 }
399
400 // Read pointing direction
401 double ra_pnt = events.real("RA_PNT");
402 double dec_pnt = events.real("DEC_PNT");
403 GSkyDir dir_pnt;
404 dir_pnt.radec_deg(ra_pnt, dec_pnt);
405 m_pnt.dir(dir_pnt);
406
407 // Read GTI extension name from data sub-space keyword
408 std::string gti_extname = gammalib::read_ds_gti_extname(events);
409
410 // If no GTI extension name was found then
411 if (gti_extname.empty()) {
412 gti_extname = gammalib::extname_gti;
413 }
414
415 // If GTI extension is present in FITS file then read Good Time Intervals
416 // from that extension
417 if (fits.contains(gti_extname)) {
418 const GFitsTable& gti = *fits.table(gti_extname);
419 m_gti_extname = gti_extname;
420 m_gti.read(gti);
421 }
422
423 // ... otherwise build GTI from TSTART and TSTOP
424 else {
425
426 // Read start and stop time
427 double tstart = events.real("TSTART");
428 double tstop = events.real("TSTOP");
429
430 // Create time reference from header information
431 GTimeReference timeref(events);
432
433 // Set GTI time reference
434 m_gti.reference(timeref);
435
436 // Set start and stop time
437 GTime start(tstart, m_gti.reference());
438 GTime stop(tstop, m_gti.reference());
439
440 // Append start and stop time as single time interval to GTI
441 m_gti.append(start, stop);
442
443
444 } // endelse: GTI built from TSTART and TSTOP
445
446 // Read region of interest from data sub-space keyword
448
449 // Read energy boundaries from data sub-space keyword
451
452 // Read phase intervals from data sub-space keyword
454
455 // If the file name contains an expression or the filename is empty then
456 // load the events now. We do this at the end to make sure that the GTI
457 // has been set before.
459 read_events(events);
460 }
461
462 // Read Monte Carlo identifier keywords
463 read_mc_ids(events);
464
465 // Return
466 return;
467}
468
469
470/***********************************************************************//**
471 * @brief Write CTA events and Good Time Intervals into FITS file
472 *
473 * @param[in] fits FITS file.
474 *
475 * Writes the CTA event list and the Good Time intervals into a FITS file.
476 *
477 * The events will be written by default into the extension `EVENTS` unless
478 * an extension name is explicitly specified in the FITS file name. The
479 * method also writes the data sub-space keywords in the FITS header of the
480 * events table.
481 *
482 * In addition, the method will also append a table containing the Good Time
483 * Intervals of the events to the FITS file. The extension name for the Good
484 * Time Intervals is either taken from the m_gti_extname member, or if empty,
485 * is set to `GTI`.
486 ***************************************************************************/
488{
489 // Set event extension name
490 std::string evtname = fits.filename().extname(gammalib::extname_cta_events);
491
492 // Set GTI extension name
493 std::string gtiname = (m_gti_extname.empty())
495
496 // Write events and GTIs
497 write(fits, evtname, gtiname);
498
499 // Return
500 return;
501}
502
503
504/***********************************************************************//**
505 * @brief Write CTA events and Good Time Intervals into FITS file
506 *
507 * @param[in] fits FITS file.
508 * @param[in] evtname Event FITS extension name.
509 * @param[in] gtiname Good Time Intervals FITS extension name.
510 *
511 * Writes the CTA event list and the Good Time intervals into a FITS file.
512 *
513 * The events will be written into the extension @p evtname while the Good
514 * Time Intervals will be written into the extension @p gtiname.
515 ***************************************************************************/
516void GCTAEventList::write(GFits& fits, const std::string& evtname,
517 const std::string& gtiname) const
518{
519 // Allocate empty FITS binary table
520 GFitsBinTable table;
521
522 // Write events into binary table
523 write_events(table);
524
525 // Set FITS extension name
526 table.extname(evtname);
527
528 // Write pointing direction
529 double ra_pnt = m_pnt.dir().ra_deg();
530 double dec_pnt = m_pnt.dir().dec_deg();
531 table.card("RA_PNT", ra_pnt, "[deg] Pointing Right Ascension");
532 table.card("DEC_PNT", dec_pnt, "[deg] Pointing Declination");
533
534 // Write data selection keywords
535 write_ds_keys(table, gtiname);
536
537 // Write Monte Carlo identifier keywords
538 write_mc_ids(table);
539
540 // Append event table to FITS file
541 fits.append(table);
542
543 // Write GTI extension
544 gti().write(fits, gtiname);
545
546 // Store FITS file name
547 m_filename = fits.filename();
548
549 // Return
550 return;
551}
552
553
554/***********************************************************************//**
555 * @brief Set ROI
556 *
557 * @param[in] roi ROI.
558 *
559 * @exception GException::invalid_argument
560 * Invalid region of interest class specified.
561 *
562 * Sets the region of interest of the event list.
563 ***************************************************************************/
564void GCTAEventList::roi(const GRoi& roi)
565{
566 // Cast ROI dynamically
567 const GCTARoi* ptr = dynamic_cast<const GCTARoi*>(&roi);
568
569 // Throw exception if ROI is not of correct type
570 if (ptr == NULL) {
571 std::string cls = std::string(typeid(&roi).name());
572 std::string msg = "Invalid region of interest type \""+cls+"\" "
573 "provided on input. Please specify a \"GCTARoi\" "
574 "object as argument.";
576 }
577
578 // Set ROI
579 m_roi = *ptr;
580
581 // Return
582 return;
583}
584
585
586/***********************************************************************//**
587 * @brief Append event to event list
588 *
589 * @param[in] event Event.
590 *
591 * Appends an event to the end of the event list.
592 ***************************************************************************/
594{
595 // Make sure that the events are online
596 fetch();
597
598 // Append event
599 m_events.push_back(event);
600
601 // Append an element to all additional columns
602 for (int i = 0; i < m_columns.size(); ++i) {
603 m_columns[i]->insert(m_columns[i]->nrows(),1);
604 }
605
606 // Set number of events
607 m_num_events = m_events.size();
608
609 // Set event index
610 int index = m_num_events - 1;
611 m_events[index].m_index = index;
612
613 // Return
614 return;
615}
616
617
618
619/***********************************************************************//**
620 * @brief Append FITS table column to event list
621 *
622 * @param[in] column FITS table column to be appended.
623 *
624 * @exception GException::invalid_argument
625 * FITS column has incompatible number of rows.
626 *
627 * Appends a FITS table column to the event list. The length of the FITS
628 * column must be identical to the number of events in the event list.
629 ***************************************************************************/
631{
632 // Throw an exception if the column has an incompatible number of rows
633 if (size() != column.nrows()) {
634 std::string msg = "Incompatible column length. Attempt to append a "
635 "column of length "+gammalib::str(column.nrows())+
636 " to an event list with "+gammalib::str(size())+
637 " events. Please specify a column of length "+
638 gammalib::str(size())+".";
640 }
641
642 // Make sure that the events are online
643 fetch();
644
645 // Clone the FITS column. De-allocation is done when the object is free'd
646 GFitsTableCol* ptr = column.clone();
647
648 // Append the column
649 m_columns.push_back(ptr);
650
651 // Return
652 return;
653}
654
655
656/***********************************************************************//**
657 * @brief Remove events from event list
658 *
659 * @param[in] index Index from which on events should be removed.
660 * @param[in] number Number of event to remove (default: 1).
661 *
662 * Removes events from the event list. This method does nothing if @p index
663 * points beyond the event list. The method does also gently accept
664 * @p number arguments where @p index + @p number reach beyond the event
665 * list. In that case, all events from event @p index on will be removed.
666 ***************************************************************************/
667void GCTAEventList::remove(const int& index, const int& number)
668{
669 // Make sure that the events are online
670 fetch();
671
672 // Continue only if index is valid
673 if (index < size()) {
674
675 // Determine number of elements to remove
676 int n_remove = (index + number > size()) ? size() - index : number;
677
678 // Remove events
679 m_events.erase(m_events.begin() + index,
680 m_events.begin() + index + n_remove);
681
682 // Remove elements from additional columns
683 for (int i = 0; i < m_columns.size(); ++i) {
684 m_columns[i]->remove(index, n_remove);
685 }
686
687 // Set number of events
688 m_num_events = m_events.size();
689
690 } // endif: index was valid
691
692 // Return
693 return;
694}
695
696
697/***********************************************************************//**
698 * @brief Fetch events
699 *
700 * @exception GException::file_error
701 * File not found.
702 * Unable to load events.
703 * @exception GException::invalid_value
704 * No file name has been specified.
705 * Fetched number of events mismatches the expectation.
706 *
707 * Fetches the events by reading them from a FITS file. This method does
708 * nothing if the events are already loaded, if there is nothing to fetch,
709 * or if the m_filename member is empty.
710 *
711 * The method is thread save. The method furthermore checks whether the
712 * loaded number of events corresponds to the expectation. If also checks
713 * whether the file from which events should be loaded actually exists.
714 ***************************************************************************/
715void GCTAEventList::fetch(void) const
716{
717 // Continue only if events are not loaded but there are events to fetch
718 if (m_events.empty() && size() > 0) {
719
720 // Continue only if the file name is not empty
721 if (!m_filename.is_empty()) {
722
723 // Initialise exception flag
724 bool has_exception = false;
725
726 // Load events. Catch any exception. Put the code into a critical
727 // zone as it might be called from within a parallelized thread.
728 #pragma omp critical(GCTAEventList_fetch)
729 {
730 try {
731 // Open FITS file
732 GFits fits(m_filename);
733
734 // Initialise events extension name
735 std::string extname =
737
738 // Get event list HDU
739 const GFitsTable& events = *fits.table(extname);
740
741 // Load event data
742 read_events(events);
743
744 // Close FITS file
745 fits.close();
746
747 }
748 catch (...) {
749 has_exception = true;
750 }
751 }
752
753 // Throw an exception if an exception has occured
754 if (has_exception) {
755 std::string msg = "Unable to load events from file \""+
756 m_filename+"\".";
758 }
759
760 // Throw an exception if the number of events does not correspond
761 // to the expectation
762 if (m_events.size() != size()) {
763 std::string msg = "Loaded "+gammalib::str(m_events.size())+
764 " events from FITS file while "+
765 gammalib::str(size())+" events were "
766 "expected. This should never happen!";
768 }
769
770 } // endif: filename was not empty
771
772 // Throw an exception if the FITS file name is not known
773 else {
774 std::string msg = "Unable to fetch "+gammalib::str(size())+
775 " events since the name of the FITS file from "
776 "which to fetch the events is not known.";
778 }
779
780 } // endif: there were no events
781
782 // Return
783 return;
784}
785
786
787/***********************************************************************//**
788 * @brief Dispose events
789 *
790 * Disposes the events to save memory. The method free's all memory
791 * associated to the events. The method should be used with care as it does
792 * not check whether the events can actually be recovered using the fetch()
793 * method. Eventually, the events should be saved before so that fetch()
794 * can recover them.
795 ***************************************************************************/
797{
798 // Free additional columns
799 for (int i = 0; i < m_columns.size(); ++i) {
800 delete m_columns[i];
801 m_columns[i] = NULL;
802 }
803
804 // Clear events and additional columns
805 m_events.clear();
806 m_columns.clear();
807
808 // Now actually remove the memory reserved for these objects. See
809 // https://prateekvjoshi.com/2013/10/20/c-vector-memory-release/
810 // for an explanation of this code.
811 std::vector<GCTAEventAtom>(m_events).swap(m_events);
812 std::vector<GFitsTableCol*>(m_columns).swap(m_columns);
813
814 // Return
815 return;
816}
817
818
819/***********************************************************************//**
820 * @brief Set Monte Carlo identifiers and model names
821 *
822 * @param[in] ids Monte Carlo identifiers.
823 * @param[in] names Model name for each Monte Carlo identifier.
824 *
825 * Sets the Monte Carlo identifiers and their corresponding model names.
826 * The information will then be written into the header file.
827 ***************************************************************************/
828void GCTAEventList::set_mc_id_names(const std::vector<int>& ids,
829 const std::vector<std::string>& names)
830{
831 // Throw an exception if the vectors have an incompatible size
832 if (ids.size() != names.size()) {
833 std::string msg = "The number of Monte Carlo identifiers ("+
834 gammalib::str(ids.size())+") does not correspond to "
835 "the number of model names ("+
836 gammalib::str(names.size())+"). Please provide the "
837 "same number of model names and Monte Carlo "
838 "identifiers.";
840 }
841
842 // Set vectors
843 m_mc_ids = ids;
844 m_mc_id_names = names;
845
846 // Return
847 return;
848}
849
850
851
852/***********************************************************************//**
853 * @brief Print event list information
854 *
855 * @param[in] chatter Chattiness.
856 * @return String containing event list information.
857 ***************************************************************************/
858std::string GCTAEventList::print(const GChatter& chatter) const
859{
860 // Initialise result string
861 std::string result;
862
863 // Continue only if chatter is not silent
864 if (chatter != SILENT) {
865
866 // Append header
867 result.append("=== GCTAEventList ===");
868
869 // Append number of events and disposal information
870 result.append("\n"+gammalib::parformat("Number of events") +
872 if (m_events.empty()) {
873 if (!m_filename.is_empty()) {
874 result.append(" (disposed in \""+m_filename+"\")");
875 }
876 else {
877 result.append(" (disposed without possibility to recover)");
878 }
879 }
880 else {
881 result.append(" (loaded)");
882 }
883
884 // Append GTI interval
885 result.append("\n"+gammalib::parformat("Time interval"));
886 if (gti().size() > 0) {
887 result.append(gammalib::str(tstart().mjd()));
888 result.append(" - ");
889 result.append(gammalib::str(tstop().mjd())+" days");
890 }
891 else {
892 result.append("not defined");
893 }
894
895 // Append energy intervals
896 if (gammalib::reduce(chatter) > SILENT) {
897 if (ebounds().size() > 0) {
898 result.append("\n"+ebounds().print(gammalib::reduce(chatter)));
899 }
900 else {
901 result.append("\n"+gammalib::parformat("Energy intervals") +
902 "not defined");
903 }
904 }
905 else {
906 result.append("\n"+gammalib::parformat("Energy interval"));
907 if (ebounds().size() > 0) {
908 result.append(gammalib::str(emin().TeV()));
909 result.append(" - ");
910 result.append(gammalib::str(emax().TeV())+" TeV");
911 }
912 else {
913 result.append("not defined");
914 }
915 }
916
917 // Append ROI
918 if (gammalib::reduce(chatter) > SILENT) {
919 if (roi().radius() > 0) {
920 result.append("\n"+roi().print(gammalib::reduce(chatter)));
921 }
922 else {
923 result.append("\n"+gammalib::parformat("Region of interest") +
924 "not defined");
925 }
926 }
927 else {
928 result.append("\n"+gammalib::parformat("Region of interest"));
929 if (roi().radius() > 0) {
930 result.append(roi().centre().print());
931 result.append(" Radius=");
932 result.append(gammalib::str(roi().radius())+" deg");
933 }
934 else {
935 result.append("not defined");
936 }
937 }
938
939 } // endif: chatter was not silent
940
941 // Return result
942 return result;
943}
944
945
946/*==========================================================================
947 = =
948 = Private methods =
949 = =
950 ==========================================================================*/
951
952/***********************************************************************//**
953 * @brief Initialise class members
954 ***************************************************************************/
956{
957 // Initialise members
958 m_roi.clear();
959 m_pnt.clear();
960 m_phases.clear();
961 m_events.clear();
962 m_columns.clear();
964 m_num_events = 0;
965 m_gti_extname = gammalib::extname_gti; //!< Default GTI extension name
966 m_has_phase = false;
967 m_has_detxy = true;
968 m_has_mc_id = false;
969 m_mc_ids.clear();
970 m_mc_id_names.clear();
971
972 // Set CTA time reference for GTIs
973 m_gti.reference(GTimeReference(G_CTA_MJDREF, "s", "TT", "LOCAL"));
974
975 // Return
976 return;
977}
978
979
980/***********************************************************************//**
981 * @brief Copy class members
982 *
983 * @param[in] list Event list.
984 ***************************************************************************/
986{
987 // Copy members
988 m_roi = list.m_roi;
989 m_pnt = list.m_pnt;
990 m_phases = list.m_phases;
991 m_events = list.m_events;
992 m_filename = list.m_filename;
998 m_mc_ids = list.m_mc_ids;
1000
1001 // Copy GTIs
1002 m_gti = list.m_gti;
1003
1004 // Copy column pointers
1005 m_columns.clear();
1006 for (int i = 0; i < list.m_columns.size(); ++i) {
1007 m_columns.push_back((list.m_columns[i]->clone()));
1008 }
1009
1010 // Return
1011 return;
1012}
1013
1014
1015/***********************************************************************//**
1016 * @brief Delete class members
1017 ***************************************************************************/
1019{
1020 // Free columns
1021 for (int i = 0; i < m_columns.size(); ++i) {
1022 delete m_columns[i];
1023 m_columns[i] = NULL;
1024 }
1025
1026 // Return
1027 return;
1028}
1029
1030
1031/***********************************************************************//**
1032 * @brief Read CTA events from FITS table
1033 *
1034 * @param[in] table FITS table.
1035 *
1036 * This method reads the CTA event list from a FITS table into memory.
1037 * The following columns are mandatory in the FITS table:
1038 *
1039 * - EVENT_ID
1040 * - TIME
1041 * - RA
1042 * - DEC
1043 * - ENERGY
1044 *
1045 * Optionally, the
1046 *
1047 * - DETX
1048 * - DETY
1049 * - PHASE
1050 *
1051 * columns are read. Any other columns present in the FITS table will also be
1052 * read, and written into the FITS table when the write_events() method is
1053 * called.
1054 ***************************************************************************/
1056{
1057 // Dispose any existing events
1058 dispose();
1059
1060 // Extract number of events in FITS file
1061 int num = table.nrows();
1062
1063 // If there are events then load them
1064 if (num > 0) {
1065
1066 // Reserve data
1067 m_events.reserve(num);
1068
1069 // Get column pointers
1070 const GFitsTableCol* ptr_eid = table["EVENT_ID"];
1071 const GFitsTableCol* ptr_time = table["TIME"];
1072 const GFitsTableCol* ptr_ra = table["RA"];
1073 const GFitsTableCol* ptr_dec = table["DEC"];
1074 const GFitsTableCol* ptr_energy = table["ENERGY"];
1075
1076 // Optionally get pointers to DETX and DETY columns
1077 const GFitsTableCol* ptr_detx = (m_has_detxy) ? table["DETX"] : NULL;
1078 const GFitsTableCol* ptr_dety = (m_has_detxy) ? table["DETY"] : NULL;
1079
1080 // Optionally get pointer to PHASE column
1081 const GFitsTableCol* ptr_phase = (m_has_phase) ? table["PHASE"] : NULL;
1082
1083 // Optionally get pointer to MC_ID column
1084 const GFitsTableCol* ptr_mc_id = (m_has_mc_id) ? table["MC_ID"] : NULL;
1085
1086 // Copy data from columns into GCTAEventAtom objects
1087 for (int i = 0; i < num; ++i) {
1088
1089 // Allocate event
1090 GCTAEventAtom event;
1091
1092 // Set sky direction
1093 GSkyDir dir;
1094 dir.radec_deg(ptr_ra->real(i), ptr_dec->real(i));
1095
1096 // Set mandatory information
1097 event.m_time.set(ptr_time->real(i), m_gti.reference());
1098 event.m_dir.dir(dir);
1099 event.m_energy.TeV(ptr_energy->real(i));
1100 event.m_event_id = ptr_eid->integer(i);
1101 event.m_index = i;
1102
1103 // If available, set detector coordinates in radians
1104 if (m_has_detxy) {
1105 event.m_dir.detx(ptr_detx->real(i)*gammalib::deg2rad);
1106 event.m_dir.dety(ptr_dety->real(i)*gammalib::deg2rad);
1107 }
1108 else {
1109 GCTAInstDir instdir = m_pnt.instdir(event.m_dir.dir());
1110 event.m_dir.detx(instdir.detx());
1111 event.m_dir.dety(instdir.dety());
1112 }
1113
1114 // If available, set pulse phase
1115 if (m_has_phase) {
1116 event.m_phase = ptr_phase->real(i);
1117 }
1118
1119 // If available, set Monte Carlo identifier
1120 if (m_has_mc_id) {
1121 event.m_mc_id = ptr_mc_id->integer(i);
1122 }
1123
1124 // Append event
1125 m_events.push_back(event);
1126
1127 } // endfor: looped over all events
1128
1129 // Loop over table and find optional columns
1130 for (int i = 0; i < table.ncols(); ++i) {
1131
1132 // Get column pointer
1133 const GFitsTableCol* col = table[i];
1134
1135 // Get column name
1136 const std::string name = col->name();
1137
1138 // If column was mandatory or optional then skip it ...
1139 if (name == "EVENT_ID" ||
1140 name == "TIME" ||
1141 name == "RA" ||
1142 name == "DEC" ||
1143 name == "ENERGY" ||
1144 name == "DETX" ||
1145 name == "DETY" ||
1146 name == "PHASE" ||
1147 name == "MC_ID") {
1148 continue;
1149 }
1150
1151 // ... otherwise keep a copy
1152 else {
1153 m_columns.push_back(col->clone());
1154 }
1155
1156 } // endfor: loop over optional columns
1157
1158 } // endif: there were events
1159
1160 // Return
1161 return;
1162}
1163
1164
1165/***********************************************************************//**
1166 * @brief Read Monte Carlo identifier keywords from FITS HDU
1167 *
1168 * @param[in] table FITS table HDU.
1169 *
1170 * Reads the Monte Carlo identifier keywords for an event list from the FITS
1171 * table HDU.
1172 ***************************************************************************/
1174{
1175 // Clear Monte Carlo identifiers and names
1176 m_mc_ids.clear();
1177 m_mc_id_names.clear();
1178
1179 // Continue only if the header contains a "NMCIDS" keyword
1180 if (table.has_card("NMCIDS")) {
1181
1182 // Get number of Monte Carlo identifiers
1183 int nids = table.integer("NMCIDS");
1184
1185 // Continue only if there are identifiers
1186 if (nids > 0) {
1187
1188 // Reserve space for elements
1189 m_mc_ids.reserve(nids);
1190 m_mc_id_names.reserve(nids);
1191
1192 // Loop over Monte Carlo identifiers
1193 for (int i = 0; i < nids+1; ++i) {
1194
1195 // Set keyword names
1196 char keyword_id[10];
1197 char keyword_name[10];
1198 gammalib_snprintf(keyword_id, 10, "MID%5.5d", i);
1199 gammalib_snprintf(keyword_name, 10, "MMN%5.5d", i);
1200
1201 // Fall through if keywords do not exist
1202 if (!table.has_card(std::string(keyword_id)) ||
1203 !table.has_card(std::string(keyword_name))) {
1204 continue;
1205 }
1206
1207 // Get header keywords
1208 int id = table.integer(std::string(keyword_id));
1209 std::string name = table.string(std::string(keyword_name));
1210
1211 // Put identifier and name in list
1212 m_mc_ids.push_back(id);
1213 m_mc_id_names.push_back(name);
1214
1215 } // endfor: looped over Monte Carlo identifiers
1216
1217 } // endif: there were identifiers
1218
1219 } // endif: there were Monte Carlo identifiers
1220
1221 // Return
1222 return;
1223}
1224
1225
1226/***********************************************************************//**
1227 * @brief Write CTA events into FITS table
1228 *
1229 * @param[in] hdu FITS binary table.
1230 *
1231 * Write the CTA event list into a FITS binary table.
1232 *
1233 * The following mandatory columns will be written into the FITS table:
1234 *
1235 * - EVENT_ID
1236 * - TIME
1237 * - RA
1238 * - DEC
1239 * - ENERGY
1240 *
1241 * If available, also the
1242 *
1243 * - DETX
1244 * - DETY
1245 * - PHASE
1246 *
1247 * columns are written. Any other columns that were read by the read_events()
1248 * method will be also written into the table.
1249 ***************************************************************************/
1251{
1252 // Make sure that the events are online
1253 fetch();
1254
1255 // Set extension name
1257
1258 // If there are events then write them now
1259 if (size() > 0) {
1260
1261 // Allocate mandatory columns
1262 GFitsTableULongCol col_eid("EVENT_ID", size());
1263 GFitsTableDoubleCol col_time("TIME", size());
1264 GFitsTableFloatCol col_ra("RA", size());
1265 GFitsTableFloatCol col_dec("DEC", size());
1266 GFitsTableFloatCol col_energy("ENERGY", size());
1267
1268 // Set units of columns
1269 // (see http://fits.gsfc.nasa.gov/standard30/fits_standard30aa.pdf)
1270 col_time.unit("s");
1271 col_ra.unit("deg");
1272 col_dec.unit("deg");
1273 col_energy.unit("TeV");
1274
1275 // Fill mandatory columns
1276 for (int i = 0; i < size(); ++i) {
1277 col_eid(i) = m_events[i].m_event_id;
1278 col_time(i) = m_events[i].time().convert(m_gti.reference());
1279 col_ra(i) = m_events[i].dir().dir().ra_deg();
1280 col_dec(i) = m_events[i].dir().dir().dec_deg();
1281 col_energy(i) = m_events[i].energy().TeV();
1282 }
1283
1284 // Append mandatory columns to table
1285 hdu.append(col_eid);
1286 hdu.append(col_time);
1287 hdu.append(col_ra);
1288 hdu.append(col_dec);
1289 hdu.append(col_energy);
1290
1291 // If available, add detector coordinates in degrees
1292 if (m_has_detxy) {
1293
1294 // Allocate columns
1295 GFitsTableFloatCol col_detx("DETX", size());
1296 GFitsTableFloatCol col_dety("DETY", size());
1297
1298 // Set units of columns
1299 // (see http://fits.gsfc.nasa.gov/standard30/fits_standard30aa.pdf)
1300 col_detx.unit("deg");
1301 col_dety.unit("deg");
1302
1303 // Fill columns
1304 for (int i = 0; i < size(); ++i) {
1305 col_detx(i) = m_events[i].dir().detx() * gammalib::rad2deg;
1306 col_dety(i) = m_events[i].dir().dety() * gammalib::rad2deg;
1307 }
1308
1309 // Append columns to table
1310 hdu.append(col_detx);
1311 hdu.append(col_dety);
1312
1313 }
1314
1315 // If available, add event phase
1316 if (m_has_phase) {
1317
1318 // Allocate columns
1319 GFitsTableFloatCol col_phase("PHASE", size());
1320
1321 // Fill columns
1322 for (int i = 0; i < size(); ++i) {
1323 col_phase(i) = m_events[i].m_phase;
1324 }
1325
1326 // Append column to table
1327 hdu.append(col_phase);
1328
1329 }
1330
1331 // If available, add Monte Carlo identifier
1332 if (m_has_mc_id) {
1333
1334 // Allocate columns
1335 GFitsTableLongCol col_mc_id("MC_ID", size());
1336
1337 // Fill columns
1338 for (int i = 0; i < size(); ++i) {
1339 col_mc_id(i) = m_events[i].m_mc_id;
1340 }
1341
1342 // Append column to table
1343 hdu.append(col_mc_id);
1344
1345 }
1346
1347 // Append other columns to table
1348 for (int i = 0; i < m_columns.size(); ++i) {
1349 hdu.append(*m_columns[i]);
1350 }
1351
1352 } // endif: there were events to write
1353
1354 // Return
1355 return;
1356}
1357
1358
1359/***********************************************************************//**
1360 * @brief Write data sub-space keywords into FITS HDU
1361 *
1362 * @param[in] hdu FITS HDU.
1363 * @param[in] gtiname Good Time Interval FITS extension.
1364 *
1365 * @exception GException::vector_mismatch
1366 * Lower and upper phase boundaries have different size.
1367 *
1368 * Writes the data sub-space keywords for an event list into the FITS HDU.
1369 * The following keywords will be written:
1370 *
1371 * DSTYP1 = "TIME" / Data sub-space type
1372 * DSUNI1 = "s" / Data sub-space unit
1373 * DSVAL1 = "TABLE" / Data sub-space value
1374 * DSREF1 = ":[extname]" / Data sub-space reference
1375 * DSTYP2 = "ENERGY" / Data sub-space type
1376 * DSUNI2 = "TeV" / Data sub-space unit
1377 * DSVAL2 = "[emin]:[emax]" / Data sub-space value
1378 * DSTYP3 = "POS(RA,DEC)" / Data sub-space type
1379 * DSUNI3 = "deg" / Data sub-space unit
1380 * DSVAL3 = "CIRCLE([ra],[dec],[rad])" / Data sub-space value
1381 * NDSKEYS = 3 / Number of data sub-space keys
1382 *
1383 * where
1384 *
1385 * [extname] is the GTI extension name @p gtiname
1386 * [emin] is the minimum event energy in TeV
1387 * [emax] is the maximum event energy in TeV
1388 * [ra] is the Right Ascension of the Region of Interest centre in degrees
1389 * [dec] is the Declination of the Region of Interest centre in degrees
1390 * [rad] is the radius of the Region of Interest in degrees
1391 ***************************************************************************/
1392void GCTAEventList::write_ds_keys(GFitsHDU& hdu, const std::string& gtiname) const
1393{
1394 // Set RoI parameters
1395 bool has_roi = (roi().centre().has_dir() && roi().is_valid());
1396 double ra = 0.0;
1397 double dec = 0.0;
1398 double rad = 0.0;
1399 if (has_roi) {
1400 ra = roi().centre().dir().ra_deg();
1401 dec = roi().centre().dir().dec_deg();
1402 rad = roi().radius();
1403 }
1404
1405 // Set energy range parameters
1406 double e_min = emin().TeV();
1407 double e_max = emax().TeV();
1408
1409 // Set energy selection string
1410 std::string dsval2 = gammalib::str(e_min) + ":" +
1411 gammalib::str(e_max);
1412
1413 // Set Good Time Intervals extension name
1414 std::string dsref1 = ":"+gtiname;
1415
1416 // Add time selection keywords
1417 hdu.card("DSTYP1", "TIME", "Data sub-space type");
1418 hdu.card("DSUNI1", "s", "Data sub-space unit");
1419 hdu.card("DSVAL1", "TABLE", "Data sub-space value");
1420 hdu.card("DSREF1", dsref1, "Data sub-space reference");
1421
1422 // Add energy range selection
1423 hdu.card("DSTYP2", "ENERGY", "Data sub-space type");
1424 hdu.card("DSUNI2", "TeV", "Data sub-space unit");
1425 hdu.card("DSVAL2", dsval2, "Data sub-space value");
1426
1427 // Initialise number of NDSKEYS
1428 int ndskeys = 2;
1429
1430 // Add acceptance cone only if RoI information is valid
1431 if (has_roi) {
1432
1433 // Set cone selection string
1434 std::string dsval3 = "CIRCLE(" +
1435 gammalib::str(ra) + "," +
1436 gammalib::str(dec) + "," +
1437 gammalib::str(rad) + ")";
1438
1439 // Write DS keywords
1440 hdu.card("DSTYP3", "POS(RA,DEC)", "Data sub-space type");
1441 hdu.card("DSUNI3", "deg", "Data sub-space unit");
1442 hdu.card("DSVAL3", dsval3, "Data sub-space value");
1443 ndskeys++;
1444
1445 } // endif: RoI was valid
1446
1447 // Check if there are phase interval cuts
1448 if (m_phases.size() > 0) {
1449
1450 // Set phase interval string
1451 std::string dsval4 = "";
1452 for (int i = 0; i < m_phases.size(); ++i) {
1453 if (i != 0) {
1454 dsval4 += ",";
1455 }
1456 dsval4 += gammalib::str(m_phases.pmin(i)) + ":" +
1458 }
1459
1460 // Write DS keywords
1461 ndskeys++;
1462 hdu.card("DSTYP"+gammalib::str(ndskeys), "PHASE",
1463 "Data sub-space type");
1464 hdu.card("DSUNI"+gammalib::str(ndskeys), "DIMENSIONLESS",
1465 "Data sub-space unit");
1466 hdu.card("DSVAL"+gammalib::str(ndskeys), dsval4,
1467 "Data sub-space value");
1468
1469 } // endif: there were phase interval cuts
1470
1471 // Set number of data selection keys
1472 hdu.card("NDSKEYS", ndskeys, "Number of data sub-space keys");
1473
1474 // Return
1475 return;
1476}
1477
1478
1479/***********************************************************************//**
1480 * @brief Write Monte Carlo identifier keywords into FITS HDU
1481 *
1482 * @param[in] hdu FITS HDU.
1483 *
1484 * Writes the Monte Carlo identifier keywords for an event list into the FITS
1485 * HDU. The following keywords will be written:
1486 *
1487 * NMCIDS Number of Monte Carlo identifiers
1488 * MID00001 First Monte Carlo identifier
1489 * MMN00001 Model name for first Monte Carlo identifier
1490 * MID00002 Second Monte Carlo identifier
1491 * MMN00002 Model name for second Monte Carlo identifier
1492 * ...
1493 ***************************************************************************/
1495{
1496 // Set number of Monte Carlo identifiers
1497 int nids = m_mc_ids.size();
1498
1499 // Continue only if there are Monte Carlo identifiers
1500 if (nids > 0) {
1501
1502 // Set number of Monte Carlo identifiers
1503 hdu.card("NMCIDS", nids, "Number of Monte Carlo identifiers");
1504
1505 // Loop over Monte Carlo identifiers
1506 for (int i = 0; i < nids; ++i) {
1507
1508 // Set keyword names
1509 char keyword_id[10];
1510 char keyword_name[10];
1511 gammalib_snprintf(keyword_id, 10, "MID%5.5d", i+1);
1512 gammalib_snprintf(keyword_name, 10, "MMN%5.5d", i+1);
1513
1514 // Set comments
1515 std::string comment_id = "Monte Carlo identifier for model " +
1516 gammalib::str(i+1);
1517 std::string comment_name = "Name of model " + gammalib::str(i+1);
1518
1519 // Write header keywords
1520 hdu.card(std::string(keyword_id), m_mc_ids[i], comment_id);
1521 hdu.card(std::string(keyword_name), m_mc_id_names[i], comment_name);
1522
1523 } // endfor: looped over Monte Carlo identifiers
1524
1525 } // endif: there were Monte Carlo identifiers
1526
1527 // Return
1528 return;
1529}
#define G_ROI
#define G_FETCH
#define G_SET_MC_ID_NAMES
#define G_APPEND_COLUMN
CTA event list class interface definition.
Definition of support function used by CTA classes.
Definition of GammaLib CTA typemaps.
#define G_CTA_MJDREF
Reference of CTA time frame.
Filename class interface definition.
FITS binary table class definition.
FITS table column abstract base class definition.
FITS table double column class interface definition.
FITS table float column class interface definition.
FITS table long integer column class interface definition.
FITS table unsigned long integer column class interface definition.
FITS table abstract base class interface definition.
FITS file class interface definition.
Mathematical function definitions.
Time reference class interface definition.
Time class interface definition.
Gammalib tools definition.
#define gammalib_snprintf(O, S, F, A)
Definition GTools.hpp:45
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
#define G_OPERATOR
CTA event atom class.
GCTAInstDir m_dir
Event direction.
CTA event list class.
virtual void clear(void)
Clear event list.
virtual ~GCTAEventList(void)
Destructor.
void append_column(const GFitsTableCol &column)
Append FITS table column to event list.
GCTAPointing m_pnt
Pointing direction for DETX/Y conversion.
void write_ds_keys(GFitsHDU &hdu, const std::string &gtiname=gammalib::extname_gti) const
Write data sub-space keywords into FITS HDU.
virtual GCTAEventAtom * operator[](const int &index)
Event atom access operator.
void copy_members(const GCTAEventList &list)
Copy class members.
void dispose(void) const
Dispose events.
virtual void read(const GFits &fits)
Read events from FITS file.
virtual const GCTARoi & roi(void) const
Return Region of Interest.
virtual GCTAEventList * clone(void) const
Clone event list.
void init_members(void)
Initialise class members.
const std::string & gtiname(void) const
Return Good Time Interval extension name.
virtual double number(void) const
Return number of events in list.
std::vector< std::string > m_mc_id_names
List of model names.
GFilename m_filename
Event list file name.
int m_num_events
Number of events.
bool m_has_phase
Signal presence of phase.
bool m_has_mc_id
Signal presence of MC identifier.
virtual int size(void) const
Return number of events in list.
GCTARoi m_roi
Region of interest.
void fetch(void) const
Fetch events.
GPhases m_phases
Phase intervals.
GCTAEventList(void)
Void constructor.
void read_events(const GFitsTable &table) const
Read CTA events from FITS table.
virtual GCTAEventList & operator=(const GCTAEventList &list)
Assignment operator.
bool m_has_detxy
Signal presence of detector coordinates.
virtual void write(GFits &fits) const
Write CTA events and Good Time Intervals into FITS file.
void read_mc_ids(const GFitsTable &table)
Read Monte Carlo identifier keywords from FITS HDU.
void remove(const int &index, const int &number=1)
Remove events from event list.
void write_mc_ids(GFitsHDU &hdu) const
Write Monte Carlo identifier keywords into FITS HDU.
void write_events(GFitsBinTable &table) const
Write CTA events into FITS table.
void set_mc_id_names(const std::vector< int > &ids, const std::vector< std::string > &names)
Set Monte Carlo identifiers and model names.
std::vector< GFitsTableCol * > m_columns
Pointers to optional columns.
void free_members(void)
Delete class members.
std::string m_gti_extname
GTI extension name.
virtual void load(const GFilename &filename)
Load events from FITS file.
virtual void save(const GFilename &filename, const bool &clobber=false) const
Save events into FITS file.
std::string print(const GChatter &chatter=NORMAL) const
Print event list information.
std::vector< GCTAEventAtom > m_events
Events.
void append(const GCTAEventAtom &event)
Append event to event list.
std::vector< int > m_mc_ids
List of Monte Carlo IDs.
CTA instrument direction class.
void dir(const GSkyDir &dir)
Set sky direction.
void dety(const double &y)
Set DETY coordinate (in radians)
void detx(const double &x)
Set DETX coordinate (in radians)
const bool & has_dir(void) const
Signal if instrument direction has valid sky direction.
GSkyDir m_dir
Observed incident direction of event.
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.
Interface for the CTA region of interest class.
Definition GCTARoi.hpp:49
const double & radius(void) const
Returns radius of region of interest in degrees.
Definition GCTARoi.hpp:125
bool is_valid(void) const
Checks if RoI is valid.
Definition GCTARoi.hpp:152
virtual void clear(void)
Clear instance.
Definition GCTARoi.cpp:184
const GCTAInstDir & centre(void) const
Returns region of interest centre.
Definition GCTARoi.hpp:111
double TeV(void) const
Return energy in TeV.
Definition GEnergy.cpp:369
Abstract event atom container class.
virtual GEventList & operator=(const GEventList &list)
Assignment operator.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
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_expression(void) const
Signal if filename has an expression.
std::string url(void) const
Return Uniform Resource Locator (URL)
std::string extname(const std::string &defaultname="") const
Return extension name.
bool is_empty(void) const
Signal if filename is empty.
void clear(void)
Clear file name.
FITS binary table class.
Abstract FITS extension base class.
Definition GFitsHDU.hpp:51
bool has_card(const int &cardno) const
Check existence of header card.
Definition GFitsHDU.hpp:233
const std::string & extname(void) const
Return extension name.
Definition GFitsHDU.hpp:162
double real(const std::string &keyname) const
Return card value as double precision.
Definition GFitsHDU.hpp:423
std::string string(const std::string &keyname) const
Return card value as string.
Definition GFitsHDU.hpp:410
GFitsHeaderCard & card(const int &cardno)
Return header card.
Definition GFitsHDU.hpp:259
int integer(const std::string &keyname) const
Return card value as integer.
Definition GFitsHDU.hpp:436
Abstract interface for FITS table column.
virtual int integer(const int &row, const int &inx=0) const =0
void name(const std::string &name)
Set column name.
virtual double real(const int &row, const int &inx=0) const =0
void unit(const std::string &unit)
Set column unit.
void nrows(const int &nrows)
Set number of rows in column.
virtual GFitsTableCol * clone(void) const =0
Clones object.
FITS table double column.
FITS table float column.
FITS table long integer column.
FITS table unsigned long integer column.
Abstract interface for FITS table.
bool contains(const std::string &colname) const
Checks the presence of a column in table.
GFitsTableCol * append(const GFitsTableCol &column)
Append column to the table.
const int & nrows(void) const
Return number of rows in table.
const int & ncols(void) const
Return number of columns in table.
FITS file class.
Definition GFits.hpp:63
bool contains(const int &extno) const
Check if HDU exists in FITS file.
Definition GFits.hpp:282
GFitsHDU * append(const GFitsHDU &hdu)
Append HDU to FITS file.
Definition GFits.cpp:678
void close(void)
Close FITS file.
Definition GFits.cpp:1342
void save(const bool &clobber=false)
Saves FITS file.
Definition GFits.cpp:1178
const GFilename & filename(void) const
Return FITS filename.
Definition GFits.hpp:313
GFitsTable * table(const int &extno)
Get pointer to table HDU.
Definition GFits.cpp:482
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
void read(const GFitsTable &table)
Read Good Time Intervals and time reference from FITS table.
Definition GGti.cpp:772
void append(const GTime &tstart, const GTime &tstop)
Append Good Time Interval.
Definition GGti.cpp:270
int size(void) const
Return number of phase intervals.
Definition GPhases.hpp:102
double pmax(const int &index) const
Returns upper boundary for a given phase interval.
Definition GPhases.cpp:345
void clear(void)
Clear phase intervals.
Definition GPhases.cpp:166
double pmin(const int &index) const
Returns lower boundary for a given phase interval.
Definition GPhases.cpp:321
Interface for the region of interest classes.
Definition GRoi.hpp:48
Sky direction class.
Definition GSkyDir.hpp:62
double dec_deg(void) const
Returns Declination in degrees.
Definition GSkyDir.hpp:258
double ra_deg(void) const
Returns Right Ascension in degrees.
Definition GSkyDir.hpp:231
void radec_deg(const double &ra, const double &dec)
Set equatorial sky direction (degrees)
Definition GSkyDir.cpp:246
Implements a time reference.
Time class.
Definition GTime.hpp:55
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1136
std::string read_ds_gti_extname(const GFitsHDU &hdu)
Return Good Time Intervals extension name from data sub-space keywords.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508
GCTARoi read_ds_roi(const GFitsHDU &hdu)
Extract ROI from data sub-space keywords.
const double deg2rad
Definition GMath.hpp:43
GChatter reduce(const GChatter &chatter)
Reduce chattiness by one level.
Definition GTypemaps.hpp:65
GEbounds read_ds_ebounds(const GFitsHDU &hdu)
Read energy boundary data sub-space keywords.
const std::string extname_gti
Definition GGti.hpp:45
const std::string extname_cta_events
GPhases read_ds_phase(const GFitsHDU &hdu)
Read phase boundary data sub-space keywords.
const double rad2deg
Definition GMath.hpp:44