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 "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
81  init_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
98  init_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  ***************************************************************************/
221 const 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();
254  this->GEventList::free_members();
255  this->GEvents::free_members();
256 
257  // Initialise members
258  this->GEvents::init_members();
259  this->GEventList::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  ***************************************************************************/
288 void 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  ***************************************************************************/
312 void 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  ***************************************************************************/
359 void 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
447  m_roi = gammalib::read_ds_roi(events);
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  ***************************************************************************/
487 void GCTAEventList::write(GFits& fits) const
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  ***************************************************************************/
516 void 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  ***************************************************************************/
564 void 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  ***************************************************************************/
667 void 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  ***************************************************************************/
715 void 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+"\".";
757  throw GException::file_error(G_FETCH, msg);
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  ***************************************************************************/
796 void GCTAEventList::dispose(void) const
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  ***************************************************************************/
828 void 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  ***************************************************************************/
858 std::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") +
871  gammalib::str(size()));
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();
963  m_filename.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;
993  m_num_events = list.m_num_events;
995  m_has_phase = list.m_has_phase;
996  m_has_detxy = list.m_has_detxy;
997  m_has_mc_id = list.m_has_mc_id;
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  ***************************************************************************/
1055 void GCTAEventList::read_events(const GFitsTable& table) const
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  ***************************************************************************/
1386 void 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 }
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.
Definition: GCTASupport.cpp:91
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.
CTA event list class interface definition.
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:1057
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
GCTAInstDir m_dir
Event direction.
double dec_deg(void) const
Returns Declination in degrees.
Definition: GSkyDir.hpp:254
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
Definition of GammaLib CTA typemaps.
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.
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:1008
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:227
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:224
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.
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:63
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_CTA_MJDREF
Reference of CTA time frame.
#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:1033
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:415
FITS table abstract base class interface definition.