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