GammaLib 2.1.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-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 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; ++i) {
1194 for (int i = 0; i < nids+1; ++i) {
1195
1196 // Set keyword names
1197 char keyword_id[10];
1198 char keyword_name[10];
1199 //sprintf(keyword_id, "MID%5.5d", i+1);
1200 //sprintf(keyword_name, "MMN%5.5d", i+1);
1201 sprintf(keyword_id, "MID%5.5d", i);
1202 sprintf(keyword_name, "MMN%5.5d", i);
1203
1204 // Fall through if keywords do not exist
1205 if (!table.has_card(std::string(keyword_id)) ||
1206 !table.has_card(std::string(keyword_name))) {
1207 continue;
1208 }
1209
1210 // Get header keywords
1211 int id = table.integer(std::string(keyword_id));
1212 std::string name = table.string(std::string(keyword_name));
1213
1214 // Put identifier and name in list
1215 m_mc_ids.push_back(id);
1216 m_mc_id_names.push_back(name);
1217
1218 } // endfor: looped over Monte Carlo identifiers
1219
1220 } // endif: there were identifiers
1221
1222 } // endif: there were Monte Carlo identifiers
1223
1224 // Return
1225 return;
1226}
1227
1228
1229/***********************************************************************//**
1230 * @brief Write CTA events into FITS table
1231 *
1232 * @param[in] hdu FITS binary table.
1233 *
1234 * Write the CTA event list into a FITS binary table.
1235 *
1236 * The following mandatory columns will be written into the FITS table:
1237 *
1238 * - EVENT_ID
1239 * - TIME
1240 * - RA
1241 * - DEC
1242 * - ENERGY
1243 *
1244 * If available, also the
1245 *
1246 * - DETX
1247 * - DETY
1248 * - PHASE
1249 *
1250 * columns are written. Any other columns that were read by the read_events()
1251 * method will be also written into the table.
1252 ***************************************************************************/
1254{
1255 // Make sure that the events are online
1256 fetch();
1257
1258 // Set extension name
1260
1261 // If there are events then write them now
1262 if (size() > 0) {
1263
1264 // Allocate mandatory columns
1265 GFitsTableULongCol col_eid("EVENT_ID", size());
1266 GFitsTableDoubleCol col_time("TIME", size());
1267 GFitsTableFloatCol col_ra("RA", size());
1268 GFitsTableFloatCol col_dec("DEC", size());
1269 GFitsTableFloatCol col_energy("ENERGY", size());
1270
1271 // Set units of columns
1272 // (see http://fits.gsfc.nasa.gov/standard30/fits_standard30aa.pdf)
1273 col_time.unit("s");
1274 col_ra.unit("deg");
1275 col_dec.unit("deg");
1276 col_energy.unit("TeV");
1277
1278 // Fill mandatory columns
1279 for (int i = 0; i < size(); ++i) {
1280 col_eid(i) = m_events[i].m_event_id;
1281 col_time(i) = m_events[i].time().convert(m_gti.reference());
1282 col_ra(i) = m_events[i].dir().dir().ra_deg();
1283 col_dec(i) = m_events[i].dir().dir().dec_deg();
1284 col_energy(i) = m_events[i].energy().TeV();
1285 }
1286
1287 // Append mandatory columns to table
1288 hdu.append(col_eid);
1289 hdu.append(col_time);
1290 hdu.append(col_ra);
1291 hdu.append(col_dec);
1292 hdu.append(col_energy);
1293
1294 // If available, add detector coordinates in degrees
1295 if (m_has_detxy) {
1296
1297 // Allocate columns
1298 GFitsTableFloatCol col_detx("DETX", size());
1299 GFitsTableFloatCol col_dety("DETY", size());
1300
1301 // Set units of columns
1302 // (see http://fits.gsfc.nasa.gov/standard30/fits_standard30aa.pdf)
1303 col_detx.unit("deg");
1304 col_dety.unit("deg");
1305
1306 // Fill columns
1307 for (int i = 0; i < size(); ++i) {
1308 col_detx(i) = m_events[i].dir().detx() * gammalib::rad2deg;
1309 col_dety(i) = m_events[i].dir().dety() * gammalib::rad2deg;
1310 }
1311
1312 // Append columns to table
1313 hdu.append(col_detx);
1314 hdu.append(col_dety);
1315
1316 }
1317
1318 // If available, add event phase
1319 if (m_has_phase) {
1320
1321 // Allocate columns
1322 GFitsTableFloatCol col_phase("PHASE", size());
1323
1324 // Fill columns
1325 for (int i = 0; i < size(); ++i) {
1326 col_phase(i) = m_events[i].m_phase;
1327 }
1328
1329 // Append column to table
1330 hdu.append(col_phase);
1331
1332 }
1333
1334 // If available, add Monte Carlo identifier
1335 if (m_has_mc_id) {
1336
1337 // Allocate columns
1338 GFitsTableLongCol col_mc_id("MC_ID", size());
1339
1340 // Fill columns
1341 for (int i = 0; i < size(); ++i) {
1342 col_mc_id(i) = m_events[i].m_mc_id;
1343 }
1344
1345 // Append column to table
1346 hdu.append(col_mc_id);
1347
1348 }
1349
1350 // Append other columns to table
1351 for (int i = 0; i < m_columns.size(); ++i) {
1352 hdu.append(*m_columns[i]);
1353 }
1354
1355 } // endif: there were events to write
1356
1357 // Return
1358 return;
1359}
1360
1361
1362/***********************************************************************//**
1363 * @brief Write data sub-space keywords into FITS HDU
1364 *
1365 * @param[in] hdu FITS HDU.
1366 * @param[in] gtiname Good Time Interval FITS extension.
1367 *
1368 * @exception GException::vector_mismatch
1369 * Lower and upper phase boundaries have different size.
1370 *
1371 * Writes the data sub-space keywords for an event list into the FITS HDU.
1372 * The following keywords will be written:
1373 *
1374 * DSTYP1 = "TIME" / Data sub-space type
1375 * DSUNI1 = "s" / Data sub-space unit
1376 * DSVAL1 = "TABLE" / Data sub-space value
1377 * DSREF1 = ":[extname]" / Data sub-space reference
1378 * DSTYP2 = "ENERGY" / Data sub-space type
1379 * DSUNI2 = "TeV" / Data sub-space unit
1380 * DSVAL2 = "[emin]:[emax]" / Data sub-space value
1381 * DSTYP3 = "POS(RA,DEC)" / Data sub-space type
1382 * DSUNI3 = "deg" / Data sub-space unit
1383 * DSVAL3 = "CIRCLE([ra],[dec],[rad])" / Data sub-space value
1384 * NDSKEYS = 3 / Number of data sub-space keys
1385 *
1386 * where
1387 *
1388 * [extname] is the GTI extension name @p gtiname
1389 * [emin] is the minimum event energy in TeV
1390 * [emax] is the maximum event energy in TeV
1391 * [ra] is the Right Ascension of the Region of Interest centre in degrees
1392 * [dec] is the Declination of the Region of Interest centre in degrees
1393 * [rad] is the radius of the Region of Interest in degrees
1394 ***************************************************************************/
1395void GCTAEventList::write_ds_keys(GFitsHDU& hdu, const std::string& gtiname) const
1396{
1397 // Set RoI parameters
1398 bool has_roi = (roi().centre().has_dir() && roi().is_valid());
1399 double ra = 0.0;
1400 double dec = 0.0;
1401 double rad = 0.0;
1402 if (has_roi) {
1403 ra = roi().centre().dir().ra_deg();
1404 dec = roi().centre().dir().dec_deg();
1405 rad = roi().radius();
1406 }
1407
1408 // Set energy range parameters
1409 double e_min = emin().TeV();
1410 double e_max = emax().TeV();
1411
1412 // Set energy selection string
1413 std::string dsval2 = gammalib::str(e_min) + ":" +
1414 gammalib::str(e_max);
1415
1416 // Set Good Time Intervals extension name
1417 std::string dsref1 = ":"+gtiname;
1418
1419 // Add time selection keywords
1420 hdu.card("DSTYP1", "TIME", "Data sub-space type");
1421 hdu.card("DSUNI1", "s", "Data sub-space unit");
1422 hdu.card("DSVAL1", "TABLE", "Data sub-space value");
1423 hdu.card("DSREF1", dsref1, "Data sub-space reference");
1424
1425 // Add energy range selection
1426 hdu.card("DSTYP2", "ENERGY", "Data sub-space type");
1427 hdu.card("DSUNI2", "TeV", "Data sub-space unit");
1428 hdu.card("DSVAL2", dsval2, "Data sub-space value");
1429
1430 // Initialise number of NDSKEYS
1431 int ndskeys = 2;
1432
1433 // Add acceptance cone only if RoI information is valid
1434 if (has_roi) {
1435
1436 // Set cone selection string
1437 std::string dsval3 = "CIRCLE(" +
1438 gammalib::str(ra) + "," +
1439 gammalib::str(dec) + "," +
1440 gammalib::str(rad) + ")";
1441
1442 // Write DS keywords
1443 hdu.card("DSTYP3", "POS(RA,DEC)", "Data sub-space type");
1444 hdu.card("DSUNI3", "deg", "Data sub-space unit");
1445 hdu.card("DSVAL3", dsval3, "Data sub-space value");
1446 ndskeys++;
1447
1448 } // endif: RoI was valid
1449
1450 // Check if there are phase interval cuts
1451 if (m_phases.size() > 0) {
1452
1453 // Set phase interval string
1454 std::string dsval4 = "";
1455 for (int i = 0; i < m_phases.size(); ++i) {
1456 if (i != 0) {
1457 dsval4 += ",";
1458 }
1459 dsval4 += gammalib::str(m_phases.pmin(i)) + ":" +
1461 }
1462
1463 // Write DS keywords
1464 ndskeys++;
1465 hdu.card("DSTYP"+gammalib::str(ndskeys), "PHASE",
1466 "Data sub-space type");
1467 hdu.card("DSUNI"+gammalib::str(ndskeys), "DIMENSIONLESS",
1468 "Data sub-space unit");
1469 hdu.card("DSVAL"+gammalib::str(ndskeys), dsval4,
1470 "Data sub-space value");
1471
1472 } // endif: there were phase interval cuts
1473
1474 // Set number of data selection keys
1475 hdu.card("NDSKEYS", ndskeys, "Number of data sub-space keys");
1476
1477 // Return
1478 return;
1479}
1480
1481
1482/***********************************************************************//**
1483 * @brief Write Monte Carlo identifier keywords into FITS HDU
1484 *
1485 * @param[in] hdu FITS HDU.
1486 *
1487 * Writes the Monte Carlo identifier keywords for an event list into the FITS
1488 * HDU. The following keywords will be written:
1489 *
1490 * NMCIDS Number of Monte Carlo identifiers
1491 * MID00001 First Monte Carlo identifier
1492 * MMN00001 Model name for first Monte Carlo identifier
1493 * MID00002 Second Monte Carlo identifier
1494 * MMN00002 Model name for second Monte Carlo identifier
1495 * ...
1496 ***************************************************************************/
1498{
1499 // Set number of Monte Carlo identifiers
1500 int nids = m_mc_ids.size();
1501
1502 // Continue only if there are Monte Carlo identifiers
1503 if (nids > 0) {
1504
1505 // Set number of Monte Carlo identifiers
1506 hdu.card("NMCIDS", nids, "Number of Monte Carlo identifiers");
1507
1508 // Loop over Monte Carlo identifiers
1509 for (int i = 0; i < nids; ++i) {
1510
1511 // Set keyword names
1512 char keyword_id[10];
1513 char keyword_name[10];
1514 sprintf(keyword_id, "MID%5.5d", i+1);
1515 sprintf(keyword_name, "MMN%5.5d", i+1);
1516
1517 // Set comments
1518 std::string comment_id = "Monte Carlo identifier for model " +
1519 gammalib::str(i+1);
1520 std::string comment_name = "Name of model " + gammalib::str(i+1);
1521
1522 // Write header keywords
1523 hdu.card(std::string(keyword_id), m_mc_ids[i], comment_id);
1524 hdu.card(std::string(keyword_name), m_mc_id_names[i], comment_name);
1525
1526 } // endfor: looped over Monte Carlo identifiers
1527
1528 } // endif: there were Monte Carlo identifiers
1529
1530 // Return
1531 return;
1532}
#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.
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:245
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:1162
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