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