ctools  2.1.0.dev
 All Classes Namespaces Files Functions Variables Macros Pages
ctobservation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * ctobservation - Base class for observation tools *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2016-2021 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 ctobservation.cpp
23  * @brief Observation tool base class implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <string>
32 #include "ctobservation.hpp"
33 
34 /* __ Method name definitions ____________________________________________ */
35 
36 /* __ Debug definitions __________________________________________________ */
37 
38 /* __ Coding definitions _________________________________________________ */
39 
40 
41 /*==========================================================================
42  = =
43  = Constructors/destructors =
44  = =
45  ==========================================================================*/
46 
47 /***********************************************************************//**
48  * @brief Name constructor
49  *
50  * @param[in] name Observation tool name.
51  * @param[in] version Observation tool version.
52  *
53  * Constructs a observation tool from the @p name and @p version. See the
54  * equivalent ctool constructor for details.
55  ***************************************************************************/
56 ctobservation::ctobservation(const std::string& name,
57  const std::string& version) : ctool(name, version)
58 {
59  // Initialise members
60  init_members();
61 
62  // Return
63  return;
64 }
65 
66 
67 /***********************************************************************//**
68  * @brief Application parameters constructor
69  *
70  * @param[in] name Observation tool name.
71  * @param[in] version Observation tool version.
72  * @param[in] pars Application parameters.
73  *
74  * Constructs a observation tool from the @p name, @p version and the
75  * application parameters @p pars. See the equivalent ctool constructor
76  * for details.
77  ***************************************************************************/
78 ctobservation::ctobservation(const std::string& name,
79  const std::string& version,
80  const GApplicationPars& pars) :
81  ctool(name, version, pars)
82 {
83  // Initialise members
84  init_members();
85 
86  // Return
87  return;
88 }
89 
90 
91 /***********************************************************************//**
92  * @brief Command line constructor
93  *
94  * @param[in] name Observation tool name.
95  * @param[in] version Observation tool version.
96  * @param[in] argc Number of arguments in command line.
97  * @param[in] argv Array of command line arguments.
98  *
99  * Constructs a observation tool from the @p name, @p version and command
100  * line arguments. See the equivalent ctool constructor for details.
101  ***************************************************************************/
102 ctobservation::ctobservation(const std::string& name,
103  const std::string& version,
104  int argc,
105  char *argv[]) : ctool(name, version, argc, argv)
106 {
107  // Initialise members
108  init_members();
109 
110  // Return
111  return;
112 }
113 
114 
115 /***********************************************************************//**
116  * @brief Observations constructor
117  *
118  * @param[in] name Observation tool name.
119  * @param[in] version Observation tool version.
120  * @param[in] obs Observation container.
121  *
122  * Constructs a observation tool from the @p name, @p version and an
123  * observation container.
124  ***************************************************************************/
125 ctobservation::ctobservation(const std::string& name,
126  const std::string& version,
127  const GObservations& obs) : ctool(name, version)
128 {
129  // Initialise members
130  init_members();
131 
132  // Set observations
133  m_obs = obs;
134 
135  // Return
136  return;
137 }
138 
139 
140 /***********************************************************************//**
141  * @brief Copy constructor
142  *
143  * @param[in] app Observation tool.
144  *
145  * Constructs an instance of a observation tool by copying information from
146  * another observation tool.
147  ***************************************************************************/
149 {
150  // Initialise members
151  init_members();
152 
153  // Copy members
154  copy_members(app);
155 
156  // Return
157  return;
158 }
159 
160 
161 /***********************************************************************//**
162  * @brief Destructor
163  *
164  * Destructs the observation tool.
165  ***************************************************************************/
167 {
168  // Free members
169  free_members();
170 
171  // Return
172  return;
173 }
174 
175 
176 /*==========================================================================
177  = =
178  = Operators =
179  = =
180  ==========================================================================*/
181 
182 /***********************************************************************//**
183  * @brief Assignment operator
184  *
185  * @param[in] app Observation tool.
186  * @return Observation tool.
187  *
188  * Assigns a observation tool.
189  ***************************************************************************/
191 {
192  // Execute only if object is not identical
193  if (this != &app) {
194 
195  // Copy base class members
196  this->ctool::operator=(app);
197 
198  // Free members
199  free_members();
200 
201  // Initialise members
202  init_members();
203 
204  // Copy members
205  copy_members(app);
206 
207  } // endif: object was not identical
208 
209  // Return this object
210  return *this;
211 }
212 
213 
214 /*==========================================================================
215  = =
216  = Public methods =
217  = =
218  ==========================================================================*/
219 
220 
221 /*==========================================================================
222  = =
223  = Protected methods exposed in Python =
224  = =
225  ==========================================================================*/
226 
227 /***********************************************************************//**
228  * @brief Return first unbinned CTA observation (const version)
229  *
230  * @return Const pointer to first unbinned CTA observation
231  *
232  * Returns a const pointer to the first unbinned CTA observation in the
233  * container. If no CTA observation exists a NULL pointer is returned.
234  *
235  * The method calls next_unbinned_observation(). See the method for details.
236  ***************************************************************************/
237 const GCTAObservation* ctobservation::first_unbinned_observation(void) const
238 {
239  // Initialise index
240  m_index_unbinned = 0;
241 
242  // Initialise OGIP members
243  m_ogip_telescope.clear();
244  m_ogip_tstart.clear();
245  m_ogip_tstop.clear();
246  m_ogip_telapse = 0.0;
247  m_ogip_exposure = 0.0;
248  m_ogip_ontime = 0.0;
249  m_ogip_livetime = 0.0;
250 
251  // Get next unbinned CTA observation
252  const GCTAObservation* obs = next_unbinned_observation();
253 
254  // Return first CTA observation
255  return obs;
256 }
257 
258 
259 /***********************************************************************//**
260  * @brief Return next unbinned CTA observation (const version)
261  *
262  * @return Const pointer to next unbinned CTA observation
263  *
264  * Returns a const pointer to the next unbinned CTA observation in the
265  * container. If no CTA observation exists any more a NULL pointer is
266  * returned.
267  *
268  * The method writes for each encountered observation a level 3 header into
269  * the logger. It will also signal when an observation was skipped because
270  * it either was not a CTA observation or not an unbinned observation.
271  *
272  * @todo Logger methods should be declared const to avoid the const casting.
273  ***************************************************************************/
274 const GCTAObservation* ctobservation::next_unbinned_observation(void) const
275 {
276  // Initialise pointer on CTA observation
277  const GCTAObservation* obs = NULL;
278 
279  // Loop over all remaining observation in the container
280  for (; m_index_unbinned < m_obs.size(); ++m_index_unbinned) {
281 
282  // Write header for the current observation
283  const_cast<ctobservation*>(this)->log_header3(TERSE,
285 
286  // Case the observation to a CTA observation. This will return a
287  // NULL pointer if the observation is not a CTA observation.
288  obs = dynamic_cast<const GCTAObservation*>(m_obs[m_index_unbinned]);
289 
290  // Skip observation if it's not CTA
291  if (obs == NULL) {
292  std::string msg = " Skipping "+
293  m_obs[m_index_unbinned]->instrument()+
294  " observation";
295  const_cast<ctobservation*>(this)->log_string(NORMAL, msg);
296  continue;
297  }
298 
299  // Skip observation if we have a binned observation
300  if (obs->eventtype() == "CountsCube") {
301  obs = NULL;
302  std::string msg = " Skipping binned "+
303  m_obs[m_index_unbinned]->instrument()+
304  " observation";
305  const_cast<ctobservation*>(this)->log_string(NORMAL, msg);
306  continue;
307  }
308 
309  // If we come to this point we have an unbinned CTA observation and
310  // we can forward the index to the next index and break the loop
311  m_index_unbinned++;
312  break;
313 
314  } // endfor: looped over all observation
315 
316  // Update OGIP members
317  if (obs != NULL) {
318  if (m_ogip_telapse == 0.0) {
319  m_ogip_telescope = obs->instrument();
320  m_ogip_tstart = obs->gti().tstart();
321  m_ogip_tstop = obs->gti().tstop();
322  m_ogip_telapse = obs->gti().telapse();
323  m_ogip_exposure = obs->ontime();
324  m_ogip_ontime = obs->ontime();
325  m_ogip_livetime = obs->livetime();
326  }
327  else {
328  if (obs->gti().tstart() < m_ogip_tstart) {
329  m_ogip_tstart = obs->gti().tstart();
330  }
331  if (obs->gti().tstop() > m_ogip_tstop) {
332  m_ogip_tstop = obs->gti().tstop();
333  }
334  m_ogip_telapse += obs->gti().telapse();
335  m_ogip_exposure += obs->ontime();
336  m_ogip_ontime += obs->ontime();
337  m_ogip_livetime += obs->livetime();
338  }
339  }
340 
341  // Return next CTA observation
342  return obs;
343 }
344 
345 
346 /***********************************************************************//**
347  * @brief Read OGIP keywords from FITS HDU
348  *
349  * @param[in,out] hdu Pointer to FITS HDU.
350  *
351  * Read OGIP keywords from FITS HDU.
352  ***************************************************************************/
353 void ctobservation::read_ogip_keywords(GFitsHDU* hdu) const
354 {
355  // Continue only if pointer is valid
356  if (hdu != NULL) {
357 
358  // Get observation information
359  m_ogip_telescope = (hdu->has_card("TELESCOP")) ? hdu->string("TELESCOP") : "";
360 
361  // Get observation time information
362  std::string date_obs = (hdu->has_card("DATE-OBS")) ? hdu->string("DATE-OBS") : "";
363  std::string time_obs = (hdu->has_card("TIME-OBS")) ? hdu->string("TIME-OBS") : "";
364  std::string date_end = (hdu->has_card("DATE-END")) ? hdu->string("DATE-END") : "";
365  std::string time_end = (hdu->has_card("TIME-END")) ? hdu->string("TIME-END") : "";
366  m_ogip_telapse = (hdu->has_card("TELAPSE")) ? hdu->real("TELAPSE") : 0.0;
367  m_ogip_ontime = (hdu->has_card("ONTIME")) ? hdu->real("ONTIME") : 0.0;
368  m_ogip_livetime = (hdu->has_card("LIVETIME")) ? hdu->real("LIVETIME") : 0.0;
369  m_ogip_exposure = (hdu->has_card("EXPOSURE")) ? hdu->real("EXPOSURE") : 0.0;
370 
371  // Get OGIP start and stop time
372  std::string tstart = date_obs + "T" + time_obs;
373  std::string tstop = date_end + "T" + time_end;
374  if (tstart != "T") {
375  m_ogip_tstart.utc(tstart);
376  }
377  if (tstop != "T") {
378  m_ogip_tstop.utc(tstop);
379  }
380 
381  } // endif: pointer was valid
382 
383  // Return
384  return;
385 }
386 
387 
388 /***********************************************************************//**
389  * @brief Write OGIP keywords in FITS HDU
390  *
391  * @param[in,out] hdu Pointer to FITS HDU.
392  *
393  * Writes OGIP keywords in FITS HDU.
394  ***************************************************************************/
395 void ctobservation::write_ogip_keywords(GFitsHDU* hdu) const
396 {
397  // Continue only if pointer is valid
398  if (hdu != NULL) {
399 
400  // Set creator
401  std::string creator = this->name() + " v" + this->version();
402 
403  // Compute times
404  std::string utc_obs = m_ogip_tstart.utc();
405  std::string utc_end = m_ogip_tstop.utc();
406  std::string date_obs = utc_obs.substr(0, 10);
407  std::string time_obs = utc_obs.substr(11, 8);
408  std::string date_end = utc_end.substr(0, 10);
409  std::string time_end = utc_end.substr(11, 8);
410 
411  // Compute deadtime correction
412  double deadc = (m_ogip_ontime > 0.0) ? m_ogip_livetime / m_ogip_ontime : 1.0;
413 
414  // Set observation information
415  hdu->card("CREATOR", creator, "Program which created the file");
416  hdu->card("TELESCOP", m_ogip_telescope, "Telescope");
417 
418  // Set observation time information
419  hdu->card("DATE-OBS", date_obs, "Observation start date");
420  hdu->card("TIME-OBS", time_obs, "Observation start time");
421  hdu->card("DATE-END", date_end, "Observation end date");
422  hdu->card("TIME-END", time_end, "Observation end time");
423  hdu->card("TELAPSE", m_ogip_telapse, "[s] Elapsed time");
424  hdu->card("ONTIME", m_ogip_ontime, "[s] Total good time including deadtime");
425  hdu->card("LIVETIME", m_ogip_livetime, "[s] Total livetime");
426  hdu->card("EXPOSURE", m_ogip_exposure, "[s] Exposure time");
427  hdu->card("DEADC", deadc, "Deadtime correction factor");
428 
429  } // endif: pointer was valid
430 
431  // Return
432  return;
433 }
434 
435 
436 /***********************************************************************//**
437  * @brief Set fit statistic for CTA observations
438  *
439  * @param[in] statistic Requested fit statistic.
440  *
441  * Sets the fit statistic for all CTA observations. The method handles
442  * regular CTA observations as well as On/Off observations.
443  *
444  * For regular CTA observations of type GCTAObservation the fit statistic is
445  * only set for binned or stacked observations. Possible values are
446  * @c POISSON, @c GAUSSIAN or @c CHI2 (case insensitive).
447  *
448  * For On/Off CTA observations of type GCTAOnOffObservation the fit statistic
449  * is always set. Possible values are @c POISSON, @c CSTAT or @c WSTAT (case
450  * insensitive).
451  *
452  * If @p statistic is any other string the fit statistic of the observations
453  * will not be modified.
454  ***************************************************************************/
455 void ctobservation::set_obs_statistic(const std::string& statistic)
456 {
457  // Convert statistic to upper case
458  std::string ustatistic = gammalib::toupper(statistic);
459 
460  // Flag which observation types are handled
461  bool handle_cta = ((ustatistic == "POISSON") ||
462  (ustatistic == "GAUSSIAN") ||
463  (ustatistic == "CHI2"));
464  bool handle_onoff = ((ustatistic == "POISSON") ||
465  (ustatistic == "CSTAT") ||
466  (ustatistic == "WSTAT"));
467 
468  // Loop over all observation in container
469  for (int i = 0; i < m_obs.size(); ++i) {
470 
471  // For regular CTA observations only set statistic for binned or
472  // stacked observations
473  if ((m_obs[i]->classname() == "GCTAObservation") && handle_cta) {
474  if (m_obs[i]->events()->classname() == "GCTAEventCube") {
475  m_obs[i]->statistic(statistic);
476  }
477  }
478 
479  // For On/Off CTA observations always set statistic
480  else if ((m_obs[i]->classname() == "GCTAOnOffObservation") &&
481  handle_onoff) {
482  m_obs[i]->statistic(statistic);
483  }
484 
485  } // endfor: looped over all observations
486 
487  // Return
488  return;
489 }
490 
491 
492 /***********************************************************************//**
493  * @brief Set observation boundaries for CTA observations
494  *
495  * Sets the observation boundaries for all CTA observations that contain
496  * event lists if they do not yet exist.
497  *
498  * If the event list does not contain any Good Time Intervals, they are
499  * derived from the time limits provided by the @a tmin and @a tmax user
500  * parameters if they exist and are valid. Furthermore, the reference time
501  * for the Good Time Intervals is inferred from the @p mjdref parameter
502  * if it exists. Otherwise, G_CTA_MJDREF is used as reference time.
503  *
504  * If the event list does not contain energy boundaries, they are derived
505  * from the energy limits provided by the @a emin and @a emax user
506  * parameters if they exist and are valid.
507  *
508  * If the event list does not contain a valid ROI, the ROI radius is
509  * determined by the @a rad user parameter if it exists and is valid. The
510  * center is either taken from the pointing direction, and if this is not
511  * valid, it is set from the @a ra and @a dec user parameters if they exist
512  * and are valid.
513  ***************************************************************************/
515 {
516  // Loop over all observations in the container
517  for (int i = 0; i < m_obs.size(); ++i) {
518 
519  // Get pointer to CTA observation
520  GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
521 
522  // Fall through if observation is not a CTA observation or if it
523  // does not contain events
524  if ((obs == NULL) || (!obs->has_events())) {
525  continue;
526  }
527 
528  // Get pointer on CTA event list
529  GCTAEventList* list = const_cast<GCTAEventList*>
530  (dynamic_cast<const GCTAEventList*>(obs->events()));
531 
532  // Fall through if CTA observation does not contain an event list
533  if (list == NULL) {
534  continue;
535  }
536 
537  // If there is no RoI then read the "rad" user parameters and use
538  // the pointing direction to set the RoI
539  if (!list->roi().is_valid()) {
540  if (has_par("rad") && (*this)["rad"].is_valid()) {
541  if (obs->pointing().is_valid() ||
542  (has_par("ra") && (*this)["ra"].is_valid() &&
543  has_par("dec") && (*this)["dec"].is_valid())) {
544 
545  // Get sky direction
546  GSkyDir dir;
547  if (obs->pointing().is_valid()) {
548  dir = obs->pointing().dir();
549  }
550  else {
551  dir.radec_deg((*this)["ra"].real(),
552  (*this)["dec"].real());
553  }
554 
555  // Get instrument direction
556  GCTAInstDir instdir(dir);
557 
558  // Get radius
559  double rad = (*this)["rad"].real();
560 
561  // Set ROI
562  GCTARoi roi(instdir, rad);
563 
564  // Set ROI of list
565  list->roi(roi);
566 
567  } // endif: sky direction was accessible
568  } // endif: ROI radius was accessible
569  } // endif: list had no ROI
570 
571  // If there are no energy boundaries then read the "emin" and "emax"
572  // user parameters and add them
573  if (list->ebounds().is_empty()) {
574  if (has_par("emin") && (*this)["emin"].is_valid() &&
575  has_par("emax") && (*this)["emax"].is_valid()) {
576  double emin((*this)["emin"].real());
577  double emax((*this)["emax"].real());
578  GEbounds ebounds(GEnergy(emin, "TeV"),
579  GEnergy(emax, "TeV"));
580  list->ebounds(ebounds);
581  }
582  }
583 
584  // If there are no Good Time Intervals then read the "tmin" and "tmax"
585  // user parameters and add them
586  if (list->gti().is_empty()) {
587  if (has_par("tmin") && (*this)["tmin"].is_valid() &&
588  has_par("tmax") && (*this)["tmax"].is_valid()) {
589 
590  // Set time reference
591  GTimeReference ref = (has_par("mjdref"))
592  ? GTimeReference((*this)["mjdref"].real(), "s", "TT", "LOCAL")
593  : GTimeReference(G_CTA_MJDREF, "s", "TT", "LOCAL");
594 
595  // Get time limits
596  GTime tmin = (*this)["tmin"].time(ref);
597  GTime tmax = (*this)["tmax"].time(ref);
598 
599  // Set GTI
600  GGti gti(tmin, tmax);
601 
602  // Set GTI of list
603  list->gti(gti);
604 
605  } // endif: "tmin" and "tmax" parameters existed and were valid
606  } // endif: GTI was not set
607 
608  } // endfor: looped over observations
609 
610  // Return
611  return;
612 }
613 
614 
615 /***********************************************************************//**
616  * @brief Save event list in FITS format.
617  *
618  * Save the event list as a FITS file. The file name of the FITS file is
619  * specified by the `outobs` parameter.
620  ***************************************************************************/
622 {
623  // Save only if there are observations
624  if (m_obs.size() > 0) {
625 
626  // Get output filename
627  std::string outobs = (*this)["outobs"].filename();
628 
629  // Loop over all unbinned CTA observations in the container
630  for (GCTAObservation* obs = first_unbinned_observation(); obs != NULL;
632 
633  // Get input file name and default extension names
634  std::string infile = obs->eventfile();
635  std::string evtname = gammalib::extname_cta_events;
636  std::string gtiname = gammalib::extname_gti;
637 
638  // Create file name object
639  GFilename fname(outobs);
640 
641  // Extract filename and event extension name
642  std::string outfile = fname.url();
643 
644  // Append event extension name. We handle here the possibility
645  // to write the events into a different extension.
646  if (fname.has_extname()) {
647  outfile += "["+fname.extname()+"]";
648  }
649  else {
650  outfile += "["+gammalib::extname_cta_events+"]";
651  }
652 
653  // Log filename
654  log_value(NORMAL, "Event list file", outfile);
655 
656  // Save event list
657  save_event_list(obs, infile, evtname, gtiname, outfile);
658 
659  // Exit the loop (if this method is called we should only
660  // have a single unbinned observation in the observation
661  // container
662  break;
663 
664  } // endfor: looped over all unbinned observations
665 
666  } // endif: there were observations
667 
668  // Return
669  return;
670 }
671 
672 
673 /***********************************************************************//**
674  * @brief Save event list(s) in XML format.
675  *
676  * Save the event list(s) into FITS files and write the file path information
677  * into a XML file. The filename of the XML file is specified by the `outobs`
678  * parameter, the filename(s) of the event lists are built by prepending a
679  * prefix to the input event list filenames. Any path present in the input
680  * filename will be stripped, i.e. the event list(s) will be written in the
681  * local working directory (unless a path is specified in the prefix).
682  ***************************************************************************/
684 {
685  // Get output filename and prefix
686  std::string outobs = (*this)["outobs"].filename();
687 
688  // Issue warning if output filename has no .xml suffix
689  log_string(TERSE, warn_xml_suffix(outobs));
690 
691  // Loop over all unbinned CTA observations in the container
692  for (GCTAObservation* obs = first_unbinned_observation(); obs != NULL;
694 
695  // Get input file name and default extension names
696  std::string infile = obs->eventfile();
697  std::string evtname = gammalib::extname_cta_events;
698  std::string gtiname = gammalib::extname_gti;
699 
700  // Extract event and GTI extension names from input FITS file
701  GFilename fname(infile);
702  if (fname.has_extname()) {
703  evtname = fname.extname();
704  }
705  gtiname = get_gtiname(fname.url(), evtname);
706 
707  // Set event output file name
708  std::string outfile = set_outfile_name(infile);
709 
710  // Append event extension name
711  outfile += "["+evtname+"]";
712 
713  // Log filename
714  log_value(NORMAL, "Event list file", outfile);
715 
716  // Store output file name in observation
717  obs->eventfile(outfile);
718 
719  // Save event list
720  save_event_list(obs, infile, evtname, gtiname, outfile);
721 
722  } // endfor: looped over observations
723 
724  // Write observation definition XML file name into logger
725  log_value(NORMAL, "Obs. definition file", outobs);
726 
727  // Save observations in XML file
728  m_obs.save(outobs);
729 
730  // Return
731  return;
732 }
733 
734 
735 /*==========================================================================
736  = =
737  = Protected methods =
738  = =
739  ==========================================================================*/
740 
741 /***********************************************************************//**
742  * @brief Initialise class members
743  ***************************************************************************/
745 {
746  // Initialise protected members
747  m_obs.clear();
748 
749  // Initialise private members
750  m_ogip_telescope.clear();
751  m_ogip_tstart.clear();
752  m_ogip_tstop.clear();
753  m_ogip_telapse = 0.0;
754  m_ogip_exposure = 0.0;
755  m_ogip_ontime = 0.0;
756  m_ogip_livetime = 0.0;
757  m_index_unbinned = 0;
758 
759  // Return
760  return;
761 }
762 
763 
764 /***********************************************************************//**
765  * @brief Copy class members
766  *
767  * @param[in] app Observation tool.
768  ***************************************************************************/
770 {
771  // Copy protected members
772  m_obs = app.m_obs;
773 
774  // Copy private members
783 
784  // Return
785  return;
786 }
787 
788 
789 /***********************************************************************//**
790  * @brief Delete class members
791  ***************************************************************************/
793 {
794  // Return
795  return;
796 }
std::string warn_xml_suffix(const GFilename &filename) const
Set warning string if file has no .xml suffix.
Definition: ctool.cpp:2427
const GObservations & obs(void) const
Return observation container.
Base class for ctools.
Definition: ctool.hpp:50
GCTAObservation * next_unbinned_observation(void)
Return next unbinned CTA observation.
GTime m_ogip_tstop
Stop time for OGIP keywords.
void copy_members(const ctobservation &app)
Copy class members.
double m_ogip_ontime
Ontime for OGIP keywords.
ctobservation(const std::string &name, const std::string &version)
Name constructor.
void set_obs_statistic(const std::string &statistic)
Set fit statistic for CTA observations.
double m_ogip_telapse
Elapsed time.
double m_ogip_exposure
Exposure time.
double m_ogip_livetime
Livetime for OGIP keywords.
int m_index_unbinned
Current index of unbinned observation.
Observation tool base class interface definition.
Base class for observation tools.
void read_ogip_keywords(GFitsHDU *hdu) const
Read OGIP keywords from FITS HDU.
void save_events_fits(void)
Save event list in FITS format.
virtual ~ctobservation(void)
Destructor.
GTime m_ogip_tstart
Start time for OGIP keywords.
void free_members(void)
Delete class members.
std::string m_ogip_telescope
Name of telescope.
std::string get_obs_header(const GObservation *obs) const
Return observation header string.
Definition: ctool.cpp:2090
void write_ogip_keywords(GFitsHDU *hdu) const
Write OGIP keywords in FITS HDU.
void save_event_list(const GCTAObservation *obs, const std::string &infile, const std::string &evtname, const std::string &gtiname, const std::string &outfile) const
Save event list into FITS file.
Definition: ctool.cpp:2266
void set_obs_bounds()
Set observation boundaries for CTA observations.
void init_members(void)
Initialise class members.
ctool & operator=(const ctool &app)
Assignment operator.
Definition: ctool.cpp:221
std::string get_gtiname(const std::string &filename, const std::string &evtname) const
Get Good Time Intervals extension name.
Definition: ctool.cpp:2352
GCTAObservation * first_unbinned_observation(void)
Return first unbinned CTA observation.
ctobservation & operator=(const ctobservation &app)
Assignment operator.
std::string set_outfile_name(const std::string &filename)
Set output file name.
Definition: ctool.cpp:1491
GObservations m_obs
Observation container.
void save_events_xml(void)
Save event list(s) in XML format.