Commit a16cd0db5fca9db0f9d00b95d9a92d529fc90ea2

Authored by Jürgen Knödlseder
1 parent 9fb9976d

Remove event fetching and disposal from GCTAObservation as this is now handled a…

…t GCTAEventList level.
ChangeLog
@@ -3,10 +3,11 @@ @@ -3,10 +3,11 @@
3 * Version 1.1.0 released 3 * Version 1.1.0 released
4 ========================= 4 =========================
5 5
6 - Implement event fetching and disposal in GCTAEventList (#1648) 6 + Remove event fetching from GCTAObservation class (#1648)
  7 + Implement event fetching and disposal in GCTAEventList class (#1648)
7 Add GFilename::fullname() method 8 Add GFilename::fullname() method
8 Add GCTAEventList::remove() method 9 Add GCTAEventList::remove() method
9 - Handle also additional columns in GCTAEventList::append method 10 + Handle also additional columns in GCTAEventList::append() method
10 Correct GFitsTableCol::insert() method for empty columns 11 Correct GFitsTableCol::insert() method for empty columns
11 Correct GCTAEdisp2D::compute_ebounds_xxx() methods (#1662) 12 Correct GCTAEdisp2D::compute_ebounds_xxx() methods (#1662)
12 Use GFilename in GFits to store filename (#1649) 13 Use GFilename in GFits to store filename (#1649)
@@ -13,9 +13,12 @@ made since the last release of GammaLib. @@ -13,9 +13,12 @@ made since the last release of GammaLib.
13 13
14 2. Public interface modifications 14 2. Public interface modifications
15 --------------------------------- 15 ---------------------------------
16 -The following methods return now GFilename instead of std::string:  
17 -- GFits::filename() 16 +The following methods have been removed from the public interface:
  17 +- GCTAObservation::dispose_events()
18 18
  19 +The return value has been changed for the following methods:
  20 +- GFits::filename() returns now GFilename instead of std::string
  21 +- GCTAObservation::eventtype() returns now std::string instead of const std::string&
19 22
20 3. Configuration 23 3. Configuration
21 ----------------- 24 -----------------
@@ -112,7 +115,8 @@ None @@ -112,7 +115,8 @@ None
112 ----------------- 115 -----------------
113 Event fetching and disposal has been implemented in the GCTAEventList class by 116 Event fetching and disposal has been implemented in the GCTAEventList class by
114 additing the fetch() and dispose() methods. Now, events are only loaded upon 117 additing the fetch() and dispose() methods. Now, events are only loaded upon
115 -request and can be dispatched after user to save memory (#1648). 118 +request and can be dispatched after user to save memory. The event fetching and
  119 +disposal logic has been removed from GCTAObservation (#1648).
116 120
117 Add GCTAEventList::remove() method to remove events from an event list. 121 Add GCTAEventList::remove() method to remove events from an event list.
118 122
inst/cta/include/GCTAObservation.hpp
@@ -87,10 +87,6 @@ public: @@ -87,10 +87,6 @@ public:
87 virtual void write(GXmlElement& xml) const; 87 virtual void write(GXmlElement& xml) const;
88 virtual std::string print(const GChatter& chatter = NORMAL) const; 88 virtual std::string print(const GChatter& chatter = NORMAL) const;
89 89
90 - // Overwrite virtual base class methods  
91 - virtual const GEvents* events(void) const;  
92 - virtual void events(const GEvents& events);  
93 -  
94 // Other methods 90 // Other methods
95 bool has_response(void) const; 91 bool has_response(void) const;
96 bool has_events(void) const; 92 bool has_events(void) const;
@@ -128,8 +124,7 @@ public: @@ -128,8 +124,7 @@ public:
128 void deadc(const double& deadc); 124 void deadc(const double& deadc);
129 void eventfile(const std::string& filename); 125 void eventfile(const std::string& filename);
130 const std::string& eventfile(void) const; 126 const std::string& eventfile(void) const;
131 - const std::string& eventtype(void) const;  
132 - void dispose_events(void); 127 + std::string eventtype(void) const;
133 const double& lo_user_thres(void) const; 128 const double& lo_user_thres(void) const;
134 const double& hi_user_thres(void) const; 129 const double& hi_user_thres(void) const;
135 void n_tels(const int& tels); 130 void n_tels(const int& tels);
@@ -142,12 +137,10 @@ protected: @@ -142,12 +137,10 @@ protected:
142 void free_members(void); 137 void free_members(void);
143 void read_attributes(const GFitsHDU& hdu); 138 void read_attributes(const GFitsHDU& hdu);
144 void write_attributes(GFitsHDU& hdu) const; 139 void write_attributes(GFitsHDU& hdu) const;
145 - void set_event_type(void);  
146 140
147 // Protected members 141 // Protected members
148 std::string m_instrument; //!< Instrument name 142 std::string m_instrument; //!< Instrument name
149 std::string m_eventfile; //!< Event filename 143 std::string m_eventfile; //!< Event filename
150 - std::string m_eventtype; //!< Event type (for XML file)  
151 GCTAResponse* m_response; //!< Pointer to instrument response functions 144 GCTAResponse* m_response; //!< Pointer to instrument response functions
152 GCTAPointing m_pointing; //!< Pointing direction 145 GCTAPointing m_pointing; //!< Pointing direction
153 int m_obs_id; //!< Observation ID 146 int m_obs_id; //!< Observation ID
@@ -449,18 +442,6 @@ const std::string&amp; GCTAObservation::eventfile(void) const @@ -449,18 +442,6 @@ const std::string&amp; GCTAObservation::eventfile(void) const
449 442
450 443
451 /***********************************************************************//** 444 /***********************************************************************//**
452 - * @brief Return type of events  
453 - *  
454 - * @return Type of events.  
455 - ***************************************************************************/  
456 -inline  
457 -const std::string& GCTAObservation::eventtype(void) const  
458 -{  
459 - return m_eventtype;  
460 -}  
461 -  
462 -  
463 -/***********************************************************************//**  
464 * @brief Return user low energy threshold 445 * @brief Return user low energy threshold
465 * 446 *
466 * @return User low energy threshold. 447 * @return User low energy threshold.
inst/cta/pyext/GCTAObservation.i
@@ -59,10 +59,6 @@ public: @@ -59,10 +59,6 @@ public:
59 virtual void read(const GXmlElement& xml); 59 virtual void read(const GXmlElement& xml);
60 virtual void write(GXmlElement& xml) const; 60 virtual void write(GXmlElement& xml) const;
61 61
62 - // Overwrite virtual base class methods  
63 - virtual const GEvents* events(void) const;  
64 - virtual void events(const GEvents& events);  
65 -  
66 // Other methods 62 // Other methods
67 bool has_response(void) const; 63 bool has_response(void) const;
68 bool has_events(void) const; 64 bool has_events(void) const;
@@ -100,8 +96,7 @@ public: @@ -100,8 +96,7 @@ public:
100 void deadc(const double& deadc); 96 void deadc(const double& deadc);
101 void eventfile(const std::string& filename); 97 void eventfile(const std::string& filename);
102 const std::string& eventfile(void) const; 98 const std::string& eventfile(void) const;
103 - const std::string& eventtype(void) const;  
104 - void dispose_events(void); 99 + std::string eventtype(void) const;
105 const double& lo_user_thres(void) const; 100 const double& lo_user_thres(void) const;
106 const double& hi_user_thres(void) const; 101 const double& hi_user_thres(void) const;
107 void n_tels(const int& tels); 102 void n_tels(const int& tels);
inst/cta/src/GCTAObservation.cpp
@@ -35,7 +35,6 @@ @@ -35,7 +35,6 @@
35 #include "GGti.hpp" 35 #include "GGti.hpp"
36 #include "GTools.hpp" 36 #include "GTools.hpp"
37 #include "GIntegral.hpp" 37 #include "GIntegral.hpp"
38 -#include "GCTAException.hpp"  
39 #include "GCTASupport.hpp" 38 #include "GCTASupport.hpp"
40 #include "GCTAObservation.hpp" 39 #include "GCTAObservation.hpp"
41 #include "GCTAResponseIrf.hpp" 40 #include "GCTAResponseIrf.hpp"
@@ -64,7 +63,6 @@ const GObservationRegistry g_obs_veritas_registry(&amp;g_obs_veritas_seed); @@ -64,7 +63,6 @@ const GObservationRegistry g_obs_veritas_registry(&amp;g_obs_veritas_seed);
64 #define G_WRITE "GCTAObservation::write(GXmlElement&)" 63 #define G_WRITE "GCTAObservation::write(GXmlElement&)"
65 #define G_LOAD "GCTAObservation::load(std::string&, std::string&, "\ 64 #define G_LOAD "GCTAObservation::load(std::string&, std::string&, "\
66 "std::string&, std::string&)" 65 "std::string&, std::string&)"
67 -#define G_EVENTS "GCTAObservation::events()"  
68 66
69 /* __ Macros _____________________________________________________________ */ 67 /* __ Macros _____________________________________________________________ */
70 68
@@ -82,7 +80,7 @@ const GObservationRegistry g_obs_veritas_registry(&amp;g_obs_veritas_seed); @@ -82,7 +80,7 @@ const GObservationRegistry g_obs_veritas_registry(&amp;g_obs_veritas_seed);
82 /***********************************************************************//** 80 /***********************************************************************//**
83 * @brief Void constructor 81 * @brief Void constructor
84 * 82 *
85 - * Creates an empty CTA observation. 83 + * Constructs an empty CTA observation.
86 ***************************************************************************/ 84 ***************************************************************************/
87 GCTAObservation::GCTAObservation(void) : GObservation() 85 GCTAObservation::GCTAObservation(void) : GObservation()
88 { 86 {
@@ -99,7 +97,7 @@ GCTAObservation::GCTAObservation(void) : GObservation() @@ -99,7 +97,7 @@ GCTAObservation::GCTAObservation(void) : GObservation()
99 * 97 *
100 * @param[in] instrument Instrument name. 98 * @param[in] instrument Instrument name.
101 * 99 *
102 - * Creates an empty CTA observation for a given instrument. This enables 100 + * Constructs an empty CTA observation for a given instrument. This enables
103 * using the CTA specific interface for any other VHE instrument. Note that 101 * using the CTA specific interface for any other VHE instrument. Note that
104 * each other VHE instruments needs a specific registry at the beginning 102 * each other VHE instruments needs a specific registry at the beginning
105 * of the GCTAObservation.cpp file. So far the following instruments are 103 * of the GCTAObservation.cpp file. So far the following instruments are
@@ -126,8 +124,8 @@ GCTAObservation::GCTAObservation(const std::string&amp; instrument) : GObservation() @@ -126,8 +124,8 @@ GCTAObservation::GCTAObservation(const std::string&amp; instrument) : GObservation()
126 * @param[in] psfcube Psf cube file name. 124 * @param[in] psfcube Psf cube file name.
127 * @param[in] bkgcube Backgorund cube file name. 125 * @param[in] bkgcube Backgorund cube file name.
128 * 126 *
129 - * Creates a CTA observation from a counts cube, an exposure cube and a Psf  
130 - * cube. 127 + * Constructs a CTA observation from a counts cube, an exposure cube, a Psf
  128 + * cube and a background cube.
131 ***************************************************************************/ 129 ***************************************************************************/
132 GCTAObservation::GCTAObservation(const std::string& cntcube, 130 GCTAObservation::GCTAObservation(const std::string& cntcube,
133 const std::string& expcube, 131 const std::string& expcube,
@@ -150,7 +148,7 @@ GCTAObservation::GCTAObservation(const std::string&amp; cntcube, @@ -150,7 +148,7 @@ GCTAObservation::GCTAObservation(const std::string&amp; cntcube,
150 * 148 *
151 * @param[in] obs CTA observation. 149 * @param[in] obs CTA observation.
152 * 150 *
153 - * Creates a CTA observation by copying an existing CTA observation. 151 + * Constructs a CTA observation by copying an existing CTA observation.
154 ***************************************************************************/ 152 ***************************************************************************/
155 GCTAObservation::GCTAObservation(const GCTAObservation& obs) : GObservation(obs) 153 GCTAObservation::GCTAObservation(const GCTAObservation& obs) : GObservation(obs)
156 { 154 {
@@ -167,6 +165,8 @@ GCTAObservation::GCTAObservation(const GCTAObservation&amp; obs) : GObservation(obs) @@ -167,6 +165,8 @@ GCTAObservation::GCTAObservation(const GCTAObservation&amp; obs) : GObservation(obs)
167 165
168 /***********************************************************************//** 166 /***********************************************************************//**
169 * @brief Destructor 167 * @brief Destructor
  168 + *
  169 + * Destructs CTA observation.
170 ***************************************************************************/ 170 ***************************************************************************/
171 GCTAObservation::~GCTAObservation(void) 171 GCTAObservation::~GCTAObservation(void)
172 { 172 {
@@ -223,6 +223,8 @@ GCTAObservation&amp; GCTAObservation::operator=(const GCTAObservation&amp; obs) @@ -223,6 +223,8 @@ GCTAObservation&amp; GCTAObservation::operator=(const GCTAObservation&amp; obs)
223 223
224 /***********************************************************************//** 224 /***********************************************************************//**
225 * @brief Clear CTA observation 225 * @brief Clear CTA observation
  226 + *
  227 + * Clear CTA observation.
226 ***************************************************************************/ 228 ***************************************************************************/
227 void GCTAObservation::clear(void) 229 void GCTAObservation::clear(void)
228 { 230 {
@@ -243,6 +245,8 @@ void GCTAObservation::clear(void) @@ -243,6 +245,8 @@ void GCTAObservation::clear(void)
243 * @brief Clone CTA observation 245 * @brief Clone CTA observation
244 * 246 *
245 * @return Pointer to deep copy of CTA observation. 247 * @return Pointer to deep copy of CTA observation.
  248 + *
  249 + * Returns a pointer to a deep copy of a CTA observation.
246 ***************************************************************************/ 250 ***************************************************************************/
247 GCTAObservation* GCTAObservation::clone(void) const 251 GCTAObservation* GCTAObservation::clone(void) const
248 { 252 {
@@ -255,28 +259,30 @@ GCTAObservation* GCTAObservation::clone(void) const @@ -255,28 +259,30 @@ GCTAObservation* GCTAObservation::clone(void) const
255 * 259 *
256 * @param[in] rsp Response function. 260 * @param[in] rsp Response function.
257 * 261 *
258 - * @exception GException::invalid_value  
259 - * Specified response in not of type GCTAResponse. 262 + * @exception GException::invalid_argument
  263 + * Invalid response class specified.
260 * 264 *
261 - * Sets the response function for the observation. The argument has to be of  
262 - * type GCTAResponse, otherwise an exception is thrown. 265 + * Sets the response function for the observation.
263 ***************************************************************************/ 266 ***************************************************************************/
264 void GCTAObservation::response(const GResponse& rsp) 267 void GCTAObservation::response(const GResponse& rsp)
265 { 268 {
  269 + // Cast response dynamically
  270 + const GCTAResponse* ptr = dynamic_cast<const GCTAResponse*>(&rsp);
  271 +
  272 + // Throw exception if response is not of correct type
  273 + if (ptr == NULL) {
  274 + std::string cls = std::string(typeid(&rsp).name());
  275 + std::string msg = "Invalid response type \""+cls+"\" provided on "
  276 + "input. Please specify a \"GCTAResponse\" "
  277 + "object as argument.";
  278 + throw GException::invalid_argument(G_RESPONSE_SET, msg);
  279 + }
  280 +
266 // Free response 281 // Free response
267 if (m_response != NULL) delete m_response; 282 if (m_response != NULL) delete m_response;
268 - m_response = NULL;  
269 -  
270 - // Get pointer on CTA response  
271 - const GCTAResponse* cta = dynamic_cast<const GCTAResponse*>(&rsp);  
272 - if (cta == NULL) {  
273 - std::string msg = "Specified response function is not a CTA "  
274 - "response function.\n" + rsp.print();  
275 - throw GException::invalid_value(G_RESPONSE_SET, msg);  
276 - }  
277 283
278 // Clone response function 284 // Clone response function
279 - m_response = cta->clone(); 285 + m_response = ptr->clone();
280 286
281 // Return 287 // Return
282 return; 288 return;
@@ -291,15 +297,16 @@ void GCTAObservation::response(const GResponse&amp; rsp) @@ -291,15 +297,16 @@ void GCTAObservation::response(const GResponse&amp; rsp)
291 * @exception GException::invalid_value 297 * @exception GException::invalid_value
292 * No valid response found in CTA observation. 298 * No valid response found in CTA observation.
293 * 299 *
294 - * Returns a pointer to the CTA response function. The pointer returned is  
295 - * never NULL. 300 + * Returns a pointer to the CTA response function. An exception is thrown if
  301 + * the pointer is not valid, hence the user does not need to verify the
  302 + * validity of the pointer.
296 ***************************************************************************/ 303 ***************************************************************************/
297 const GCTAResponse* GCTAObservation::response(void) const 304 const GCTAResponse* GCTAObservation::response(void) const
298 { 305 {
299 // Throw an exception if the response pointer is not valid 306 // Throw an exception if the response pointer is not valid
300 if (m_response == NULL) { 307 if (m_response == NULL) {
301 - std::string msg = "No valid response function found in CTA"  
302 - " observation.\n"; 308 + std::string msg = "No valid response function found in CTA "
  309 + "observation.\n";
303 throw GException::invalid_value(G_RESPONSE_GET, msg); 310 throw GException::invalid_value(G_RESPONSE_GET, msg);
304 } 311 }
305 312
@@ -380,287 +387,84 @@ void GCTAObservation::response(const GCTACubeExposure&amp; expcube, @@ -380,287 +387,84 @@ void GCTAObservation::response(const GCTACubeExposure&amp; expcube,
380 /***********************************************************************//** 387 /***********************************************************************//**
381 * @brief Get Region of Interest 388 * @brief Get Region of Interest
382 * 389 *
  390 + * @return Region of Interest.
  391 + *
383 * @exception GException::invalid_value 392 * @exception GException::invalid_value
384 - * Events is not an event list or unable to open an event file. 393 + * Observation does not contain events.
  394 + * Observation does not contain an event list.
385 * 395 *
386 - * Extract the Region of Interest from the event list. If events are loaded  
387 - * into the observation, the RoI is simply copied over. If no events are  
388 - * present, the method attemps to read the RoI from the header keywords of  
389 - * the event file. This obviously only works if a valid event file name is  
390 - * available. 396 + * Extracts the Region of Interest from the event list. An exception is
  397 + * thrown if the observation does not contain an event list.
391 ***************************************************************************/ 398 ***************************************************************************/
392 GCTARoi GCTAObservation::roi(void) const 399 GCTARoi GCTAObservation::roi(void) const
393 { 400 {
394 - // Initialise ROI  
395 - GCTARoi roi;  
396 -  
397 - // If CTA has events then simply retrieve the ROI from the event list  
398 - if (m_events != NULL) {  
399 -  
400 - // Extract region of interest from CTA observation  
401 - const GCTAEventList* list = dynamic_cast<const GCTAEventList*>(m_events);  
402 - if (list == NULL) {  
403 - std::string msg = "The observation does not contain an event "  
404 - "list. An event list is needed to retrieve "  
405 - "the Region of Interest.";  
406 - throw GException::invalid_value(G_ROI, msg);  
407 - }  
408 - roi = list->roi();  
409 - 401 + // Throw an exception if no events exist
  402 + if (m_events == NULL) {
  403 + std::string msg = "Region of Interest is not defined since the "
  404 + "observation does not contain events.";
  405 + throw GException::invalid_value(G_ROI, msg);
410 } 406 }
411 407
412 - // ... otherwise try reading the ROI from the event file header  
413 - else {  
414 -  
415 - // Try opening event file  
416 - GFits fits;  
417 - try {  
418 - fits.open(m_eventfile);  
419 - }  
420 - catch (std::exception &e) {  
421 - std::string msg;  
422 - if (m_eventfile.length() == 0) {  
423 - msg = "The observation does not contain any information about "  
424 - "the event file, hence the Region of Interest cannot be "  
425 - "determined.";  
426 - }  
427 - else {  
428 - msg = "Could no open the event file \""+m_eventfile+"\". "  
429 - "Please check that the file name is valid.";  
430 - }  
431 - throw GException::invalid_value(G_ROI, msg);  
432 - }  
433 -  
434 - GFilename fname(m_eventfile);  
435 -  
436 - // Get event list HDU  
437 - const GFitsTable& hdu = *fits.table(fname.extname("EVENTS"));  
438 -  
439 - // Read ROI from data selection keywords  
440 - roi = gammalib::read_ds_roi(hdu);  
441 -  
442 - // Close FITS file  
443 - fits.close();  
444 - 408 + // Get pointer to event list. Throw an exception if no event list is found
  409 + const GCTAEventList* list = dynamic_cast<const GCTAEventList*>(m_events);
  410 + if (list == NULL) {
  411 + std::string msg = "Region of Interest is not defined since the "
  412 + "observation does not contain an event list.";
  413 + throw GException::invalid_value(G_ROI, msg);
445 } 414 }
446 415
447 // Return ROI 416 // Return ROI
448 - return roi; 417 + return (list->roi());
449 } 418 }
450 419
451 420
452 /***********************************************************************//** 421 /***********************************************************************//**
453 * @brief Get Good Time Intervals 422 * @brief Get Good Time Intervals
454 * 423 *
455 - * @return Good Time Interval 424 + * @return Good Time Intervals.
456 * 425 *
457 * @exception GException::invalid_value 426 * @exception GException::invalid_value
458 - * Unable to open the event file or to extract GTI information  
459 - * from file.  
460 - *  
461 - * Extract the Good Time Intervals from the events. If events are loaded into  
462 - * the observation, the GTIs are simply copied over. If no events are present  
463 - * the method attemps to read the GTIs first from a GTI file, and if no GTI  
464 - * file is given, by building a GTI from the event TSTART and TSTOP values.  
465 - * The latter obviously only works if a valid event file name is available. 427 + * Observation does not contain events.
  428 + *
  429 + * Extracts the Good Time Intervals from the events. An exception is thrown
  430 + * if the observation does not contain events.
466 ***************************************************************************/ 431 ***************************************************************************/
467 GGti GCTAObservation::gti(void) const 432 GGti GCTAObservation::gti(void) const
468 { 433 {
469 - // Initialise GTIs  
470 - GGti gti;  
471 -  
472 - // If CTA has events then simply retrieve the GTIs from the events  
473 - if (m_events != NULL) {  
474 -  
475 - // Copy over GTIs  
476 - gti = m_events->gti();  
477 -  
478 - }  
479 -  
480 - // ... otherwise try reading the GTIs from file  
481 - else {  
482 -  
483 - // Extract the GTIs on basis on the DSS keywords, and if these  
484 - // keywords are not present, we build the GTIs from the start and  
485 - // stop time that is provided in the event header  
486 - if (!m_eventfile.empty()) {  
487 -  
488 - // Initialise filename  
489 - GFilename fname(m_eventfile);  
490 -  
491 - // Open FITS file  
492 - GFits fits(fname.filename());  
493 -  
494 - // Get extension name  
495 - std::string extname = fname.extname("EVENTS");  
496 -  
497 - // If the FITS file contains the specified extension then  
498 - // first search for DSS keywords, and if they were not found,  
499 - // use TSTART and TSTOP to build the GTI  
500 - if (fits.contains(extname)) {  
501 -  
502 - // Get event list HDU  
503 - const GFitsTable& events = *fits.table(extname);  
504 -  
505 - // Read GTI extension name from data sub-space keyword  
506 - std::string gti_extname = gammalib::read_ds_gti_extname(events);  
507 -  
508 - // If no GTI extension name was found then  
509 - if (gti_extname.empty()) {  
510 - gti_extname = "GTI";  
511 - }  
512 -  
513 - // If GTI extension is present in FITS file then read Good  
514 - // Time Intervals from that extension  
515 - if (fits.contains(gti_extname)) {  
516 - const GFitsTable& hdu = *fits.table(gti_extname);  
517 - gti.read(hdu);  
518 - }  
519 -  
520 - // ... otherwise build GTI from TSTART and TSTOP  
521 - else {  
522 -  
523 - // Read start and stop time  
524 - double tstart = events.real("TSTART");  
525 - double tstop = events.real("TSTOP");  
526 -  
527 - // Create time reference from header information  
528 - GTimeReference timeref(events);  
529 -  
530 - // Set GTI time reference  
531 - gti.reference(timeref);  
532 -  
533 - // Set start and stop time  
534 - GTime start(tstart, gti.reference());  
535 - GTime stop(tstop, gti.reference());  
536 -  
537 - // Append start and stop time as single time interval to GTI  
538 - gti.append(start, stop);  
539 -  
540 - } // endelse: GTI built from TSTART and TSTOP  
541 -  
542 - // Close FITS file  
543 - fits.close();  
544 -  
545 - } // endif: FITS files contained event extension  
546 -  
547 - // ... otherwise throw an exception  
548 - else {  
549 - std::string msg = "No event extension \""+extname+"\" found "  
550 - "in file \""+fname.filename()+"\". Please "  
551 - "specify a file name with a valid event "  
552 - "extension name.";  
553 - throw GException::invalid_value(G_GTI, msg);  
554 - }  
555 -  
556 - } // endif: event file name was not empty  
557 -  
558 - // ... else throw an exception  
559 - else {  
560 - std::string msg = "The observation does not contain any "  
561 - "information about the event file or the GTI "  
562 - "file, hence the Good Time Intervals cannot "  
563 - "be determined.";  
564 - throw GException::invalid_value(G_GTI, msg);  
565 - } // endelse: filenames were empty  
566 -  
567 - } // endelse: GTI had to be loaded  
568 -  
569 - // Check for GTI validity  
570 - if (gti.size() == 0) {  
571 - std::string msg = "Could not find Good Time Interval information "  
572 - "in the event file \""+m_eventfile+"\". Please "  
573 - "check that Good Time Interval information is "  
574 - "properly set in the event file."; 434 + // Throw an exception if no events exist
  435 + if (m_events == NULL) {
  436 + std::string msg = "Good Time Intervals are not defined since the "
  437 + "observation does not contain events.";
575 throw GException::invalid_value(G_GTI, msg); 438 throw GException::invalid_value(G_GTI, msg);
576 } 439 }
577 440
578 - // Return GTIs  
579 - return gti; 441 + // Return GTI
  442 + return (m_events->gti());
580 } 443 }
581 444
582 445
583 /***********************************************************************//** 446 /***********************************************************************//**
584 * @brief Get energy boundaries 447 * @brief Get energy boundaries
585 * 448 *
  449 + * @return Energy boundaries.
  450 + *
586 * @exception GException::invalid_value 451 * @exception GException::invalid_value
587 - * Unable to open the event file or to extract energy boundaries  
588 - * from file.  
589 - *  
590 - * Extract the energy boundaries from the events. If events are loaded into  
591 - * the observation, the energy boundaries are simply copied over. If no  
592 - * events are present the method attemps to read the energy boundaries from  
593 - * the event file. This obviously only works if a valid event file name is  
594 - * available. 452 + * Observation does not contain events.
  453 + *
  454 + * Extract the energy boundaries from the events. An exception is thrown if
  455 + * the observation does not contain events.
595 ***************************************************************************/ 456 ***************************************************************************/
596 GEbounds GCTAObservation::ebounds(void) const 457 GEbounds GCTAObservation::ebounds(void) const
597 { 458 {
598 - // Initialise energy boundaries  
599 - GEbounds ebounds;  
600 -  
601 - // If CTA has events then simply retrieve the energy boundaries from the  
602 - // events  
603 - if (m_events != NULL) {  
604 -  
605 - // Copy over energy boundaries  
606 - ebounds = m_events->ebounds();  
607 -  
608 - }  
609 -  
610 - // ... otherwise try reading the energy boundaries from the event file  
611 - else {  
612 -  
613 - // Try opening event file  
614 - GFits fits;  
615 - try {  
616 - fits.open(m_eventfile);  
617 - }  
618 - catch (std::exception &e) {  
619 - std::string msg;  
620 - if (m_eventfile.length() == 0) {  
621 - msg = "The observation does not contain any information about "  
622 - "the event file, hence the energy boundaries cannot be "  
623 - "determined.";  
624 - }  
625 - else {  
626 - msg = "Could not open the event file \""+m_eventfile+"\". "  
627 - "Please check that the file name is valid.";  
628 - }  
629 - throw GException::invalid_value(G_EBOUNDS, msg);  
630 - }  
631 -  
632 - GFilename fname(m_eventfile);  
633 -  
634 - // If file contains an EBOUNDS extension then load the energy  
635 - // boundaries from that extension  
636 - if (fits.contains("EBOUNDS")) {  
637 - const GFitsTable& hdu = *fits.table("EBOUNDS");  
638 - ebounds.read(hdu);  
639 - }  
640 -  
641 - // ... otherwise, if file contains an EVENTS extension then load the  
642 - // energy boundaries from the data selection keywords  
643 - else if (fits.contains(fname.extname("EVENTS"))) {  
644 - const GFitsTable& hdu = *fits.table(fname.extname("EVENTS"));  
645 - ebounds = gammalib::read_ds_ebounds(hdu);  
646 - }  
647 -  
648 - // ... else throw an exception  
649 - else {  
650 - std::string msg = "Could no find energy boundary information in "  
651 - "the event file \""+m_eventfile+"\". Please "  
652 - "check that energy boundary information is "  
653 - "properly set in the event file.";  
654 - throw GException::invalid_value(G_EBOUNDS, msg);  
655 - }  
656 -  
657 - // Close FITS file  
658 - fits.close();  
659 - 459 + // Throw an exception if no events exist
  460 + if (m_events == NULL) {
  461 + std::string msg = "Energy boundaries are not defined since the "
  462 + "observation does not contain events.";
  463 + throw GException::invalid_value(G_EBOUNDS, msg);
660 } 464 }
661 465
662 // Return energy boundaries 466 // Return energy boundaries
663 - return ebounds; 467 + return (m_events->ebounds());
664 } 468 }
665 469
666 470
@@ -726,6 +530,7 @@ GEbounds GCTAObservation::ebounds(void) const @@ -726,6 +530,7 @@ GEbounds GCTAObservation::ebounds(void) const
726 * ... 530 * ...
727 * <parameter name="ExposureCube" file="..."/> 531 * <parameter name="ExposureCube" file="..."/>
728 * <parameter name="PsfCube" file="..."/> 532 * <parameter name="PsfCube" file="..."/>
  533 + * <parameter name="BkgCube" file="..."/>
729 * </observation> 534 * </observation>
730 * 535 *
731 * Optional user energy thresholds can be specified by adding the @a emin 536 * Optional user energy thresholds can be specified by adding the @a emin
@@ -775,19 +580,22 @@ void GCTAObservation::read(const GXmlElement&amp; xml) @@ -775,19 +580,22 @@ void GCTAObservation::read(const GXmlElement&amp; xml)
775 (par->attribute("name") == "CountsCube")) { 580 (par->attribute("name") == "CountsCube")) {
776 581
777 // Store event type 582 // Store event type
778 - m_eventtype = par->attribute("name"); 583 + //m_eventtype = par->attribute("name");
779 584
780 // Read eventlist file name 585 // Read eventlist file name
781 std::string filename = par->attribute("file"); 586 std::string filename = par->attribute("file");
782 587
  588 + // Load events
  589 + load(filename);
  590 +
783 // Initialise filename 591 // Initialise filename
784 - GFilename fname(filename); 592 + //GFilename fname(filename);
785 593
786 // Open FITS file 594 // Open FITS file
787 - GFits fits(fname.filename()); 595 + //GFits fits(fname.filename());
788 596
789 // Get extension name 597 // Get extension name
790 - std::string extname = fname.extname("EVENTS"); 598 + //std::string extname = fname.extname("EVENTS");
791 599
792 // Read observation attributes. Note that we do not load the 600 // Read observation attributes. Note that we do not load the
793 // events and GTI here as this will be done on-the-fly when 601 // events and GTI here as this will be done on-the-fly when
@@ -796,6 +604,7 @@ void GCTAObservation::read(const GXmlElement&amp; xml) @@ -796,6 +604,7 @@ void GCTAObservation::read(const GXmlElement&amp; xml)
796 // GCTAObservation to access th GTIs without accessing the 604 // GCTAObservation to access th GTIs without accessing the
797 // events. It would be better if the GCTAEventList class handles 605 // events. It would be better if the GCTAEventList class handles
798 // the loading of the events on request. 606 // the loading of the events on request.
  607 + /*
799 if (fits.contains(extname)) { 608 if (fits.contains(extname)) {
800 const GFitsHDU& hdu = *fits.at(extname); 609 const GFitsHDU& hdu = *fits.at(extname);
801 read_attributes(hdu); 610 read_attributes(hdu);
@@ -804,12 +613,13 @@ void GCTAObservation::read(const GXmlElement&amp; xml) @@ -804,12 +613,13 @@ void GCTAObservation::read(const GXmlElement&amp; xml)
804 const GFitsHDU& hdu = *fits.at(0); 613 const GFitsHDU& hdu = *fits.at(0);
805 read_attributes(hdu); 614 read_attributes(hdu);
806 } 615 }
  616 + */
807 617
808 // Close FITS file 618 // Close FITS file
809 - fits.close(); 619 + //fits.close();
810 620
811 // Store event filename 621 // Store event filename
812 - m_eventfile = filename; 622 + //m_eventfile = filename;
813 623
814 // Increment parameter counter 624 // Increment parameter counter
815 n_evfile++; 625 n_evfile++;
@@ -1024,6 +834,7 @@ void GCTAObservation::read(const GXmlElement&amp; xml) @@ -1024,6 +834,7 @@ void GCTAObservation::read(const GXmlElement&amp; xml)
1024 * ... 834 * ...
1025 * <parameter name="ExposureCube" file="..."/> 835 * <parameter name="ExposureCube" file="..."/>
1026 * <parameter name="PsfCube" file="..."/> 836 * <parameter name="PsfCube" file="..."/>
  837 + * <parameter name="BkgCube" file="..."/>
1027 * </observation> 838 * </observation>
1028 * 839 *
1029 * If user energy thresholds are defined (i.e. threshold values are >0) the 840 * If user energy thresholds are defined (i.e. threshold values are >0) the
@@ -1035,18 +846,17 @@ void GCTAObservation::read(const GXmlElement&amp; xml) @@ -1035,18 +846,17 @@ void GCTAObservation::read(const GXmlElement&amp; xml)
1035 ***************************************************************************/ 846 ***************************************************************************/
1036 void GCTAObservation::write(GXmlElement& xml) const 847 void GCTAObservation::write(GXmlElement& xml) const
1037 { 848 {
1038 - // Throw an exception if m_eventtype is neither "EventList" nor  
1039 - // "CountsCube"  
1040 - if ((m_eventtype != "EventList") &&  
1041 - (m_eventtype != "CountsCube")) { 849 + // Throw an exception if eventtype() is neither "EventList" nor
  850 + std::string evttype = eventtype();
  851 + if ((evttype != "EventList") && (evttype != "CountsCube")) {
1042 std::string msg; 852 std::string msg;
1043 - if (m_eventtype.length() == 0) { 853 + if (evttype.empty()) {
1044 msg = "The observation does not contain any events, hence " 854 msg = "The observation does not contain any events, hence "
1045 "it cannot be written into an XML file."; 855 "it cannot be written into an XML file.";
1046 } 856 }
1047 else { 857 else {
1048 msg = "The observation contains an unknown event type \""+ 858 msg = "The observation contains an unknown event type \""+
1049 - m_eventtype+"\". The event type needs to be either " 859 + evttype+"\". The event type needs to be either "
1050 "\"EventList\" or \"CountsCube\"."; 860 "\"EventList\" or \"CountsCube\".";
1051 } 861 }
1052 throw GException::invalid_value(G_WRITE, msg); 862 throw GException::invalid_value(G_WRITE, msg);
@@ -1065,7 +875,7 @@ void GCTAObservation::write(GXmlElement&amp; xml) const @@ -1065,7 +875,7 @@ void GCTAObservation::write(GXmlElement&amp; xml) const
1065 if (!m_eventfile.empty()) { 875 if (!m_eventfile.empty()) {
1066 876
1067 // Write event file name 877 // Write event file name
1068 - GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, m_eventtype); 878 + GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, evttype);
1069 par->attribute("file", m_eventfile); 879 par->attribute("file", m_eventfile);
1070 880
1071 } 881 }
@@ -1104,6 +914,15 @@ void GCTAObservation::write(GXmlElement&amp; xml) const @@ -1104,6 +914,15 @@ void GCTAObservation::write(GXmlElement&amp; xml) const
1104 * @brief Read data from FITS file 914 * @brief Read data from FITS file
1105 * 915 *
1106 * @param[in] fits FITS file. 916 * @param[in] fits FITS file.
  917 + *
  918 + * Reads event data from a FITS file and sets the observation attributes.
  919 + *
  920 + * The method automatically switches between an event list and a counts cube,
  921 + * depending of the information provided in the FITS file. If an extension
  922 + * name is specified, the method checks whether the extension exists and
  923 + * loads the extension as event list. Otherwise, it checks whether the file
  924 + * contains an "EVENTS" extension and loads the extension as event list.
  925 + * If none of the above are satistified, the method loads a counts cube.
1107 ***************************************************************************/ 926 ***************************************************************************/
1108 void GCTAObservation::read(const GFits& fits) 927 void GCTAObservation::read(const GFits& fits)
1109 { 928 {
@@ -1155,9 +974,6 @@ void GCTAObservation::read(const GFits&amp; fits) @@ -1155,9 +974,6 @@ void GCTAObservation::read(const GFits&amp; fits)
1155 974
1156 } 975 }
1157 976
1158 - // Set the event type  
1159 - set_event_type();  
1160 -  
1161 // Return 977 // Return
1162 return; 978 return;
1163 } 979 }
@@ -1352,97 +1168,46 @@ void GCTAObservation::save(const std::string&amp; filename, const bool&amp; clobber) con @@ -1352,97 +1168,46 @@ void GCTAObservation::save(const std::string&amp; filename, const bool&amp; clobber) con
1352 1168
1353 1169
1354 /***********************************************************************//** 1170 /***********************************************************************//**
1355 - * @brief Set event container 1171 + * @brief Return event type string
1356 * 1172 *
1357 - * @param[in] events Event container. 1173 + * @return Event type string.
1358 * 1174 *
1359 - * Set the event container for this observation by cloning the @p events. 1175 + * Returns "EventList" if the observation contains an event list,
  1176 + * "CountsCube" if it contains a counts cube, "Events" if it container an
  1177 + * unknown type of events (which should never occur), and an empty string if
  1178 + * no events have been allocated.
1360 ***************************************************************************/ 1179 ***************************************************************************/
1361 -void GCTAObservation::events(const GEvents& events) 1180 +std::string GCTAObservation::eventtype(void) const
1362 { 1181 {
1363 - // Remove an existing event container  
1364 - if (m_events != NULL) delete m_events;  
1365 -  
1366 - // Clone events  
1367 - m_events = events.clone();  
1368 -  
1369 - // Set event type  
1370 - set_event_type();  
1371 -  
1372 - // Return  
1373 - return;  
1374 -}  
1375 - 1182 + // Initialise empty event type string
  1183 + std::string eventtype = "";
1376 1184
1377 -/***********************************************************************//**  
1378 - * @brief Return pointer to event container  
1379 - *  
1380 - * @return Pointer to event container (always valid).  
1381 - *  
1382 - * @exception GException::invalid_value  
1383 - * Events could not be fetched from disk.  
1384 - *  
1385 - * Returns a pointer to the event container. If no events exist the method  
1386 - * tries to fetch events from the file specified by the m_eventfile member.  
1387 - * If this fails, an exception will be thrown.  
1388 - ***************************************************************************/  
1389 -const GEvents* GCTAObservation::events(void) const  
1390 -{  
1391 - // If event container is offline then bring it online now  
1392 - if (m_events == NULL) { 1185 + // Continue only if events are allocated
  1186 + if (m_events != NULL) {
1393 1187
1394 - // Try loading the events from FITS file. Catch any exception. Put  
1395 - // the code into a critical zone as it might be called from within  
1396 - // a parallelized thread.  
1397 - #pragma omp critical  
1398 - {  
1399 - try {  
1400 - const_cast<GCTAObservation*>(this)->load(m_eventfile);  
1401 - }  
1402 - catch (...) {  
1403 - ;  
1404 - } 1188 + // Case A: we have a list
  1189 + GCTAEventList* list = dynamic_cast<GCTAEventList*>(m_events);
  1190 + if (list != NULL) {
  1191 + eventtype = "EventList";
1405 } 1192 }
1406 1193
1407 - // Throw an exception if the event container is still not valid  
1408 - if (m_events == NULL) {  
1409 - std::string msg;  
1410 - if (m_eventfile.length() == 0) {  
1411 - msg = "The observation does not contain any information about "  
1412 - "the event file, hence the events cannot be fetched "  
1413 - "from disk for access."; 1194 + // Case B: we have a cube
  1195 + else {
  1196 + GCTAEventCube* cube = dynamic_cast<GCTAEventCube*>(m_events);
  1197 + if (cube != NULL) {
  1198 + eventtype = "CountsCube";
1414 } 1199 }
  1200 +
  1201 + // Case C: we don't know what we have
1415 else { 1202 else {
1416 - msg = "Could no load the event file \""+m_eventfile+"\" into "  
1417 - "the observation. Please check that the file name is "  
1418 - "valid and that the file contains events."; 1203 + eventtype = "Events";
1419 } 1204 }
1420 - throw GException::invalid_value(G_EVENTS, msg);  
1421 } 1205 }
1422 1206
1423 - }  
1424 -  
1425 - // Return pointer to event container  
1426 - return m_events;  
1427 -}  
1428 - 1207 + } // endif: events were allocated
1429 1208
1430 -/***********************************************************************//**  
1431 - * @brief Dispose events  
1432 - *  
1433 - * Drops the events from the observation. Be careful with using this method  
1434 - * as the events are not saved before being disposed.  
1435 - ***************************************************************************/  
1436 -void GCTAObservation::dispose_events(void)  
1437 -{  
1438 - // Delete any existing event container  
1439 - if (m_events != NULL) delete m_events;  
1440 -  
1441 - // Signal that we disposed the events  
1442 - m_events = NULL;  
1443 -  
1444 - // Return  
1445 - return; 1209 + // Return event type
  1210 + return eventtype;
1446 } 1211 }
1447 1212
1448 1213
@@ -1468,7 +1233,7 @@ std::string GCTAObservation::print(const GChatter&amp; chatter) const @@ -1468,7 +1233,7 @@ std::string GCTAObservation::print(const GChatter&amp; chatter) const
1468 result.append("\n"+gammalib::parformat("Identifier")+id()); 1233 result.append("\n"+gammalib::parformat("Identifier")+id());
1469 result.append("\n"+gammalib::parformat("Instrument")+instrument()); 1234 result.append("\n"+gammalib::parformat("Instrument")+instrument());
1470 result.append("\n"+gammalib::parformat("Event file")+eventfile()); 1235 result.append("\n"+gammalib::parformat("Event file")+eventfile());
1471 - result.append("\n"+gammalib::parformat("Event type")+m_eventtype); 1236 + result.append("\n"+gammalib::parformat("Event type")+eventtype());
1472 result.append("\n"+gammalib::parformat("Statistics")+statistics()); 1237 result.append("\n"+gammalib::parformat("Statistics")+statistics());
1473 result.append("\n"+gammalib::parformat("Ontime")); 1238 result.append("\n"+gammalib::parformat("Ontime"));
1474 result.append(gammalib::str(ontime())+" s"); 1239 result.append(gammalib::str(ontime())+" s");
@@ -1544,7 +1309,6 @@ void GCTAObservation::init_members(void) @@ -1544,7 +1309,6 @@ void GCTAObservation::init_members(void)
1544 m_instrument = "CTA"; 1309 m_instrument = "CTA";
1545 m_object.clear(); 1310 m_object.clear();
1546 m_eventfile.clear(); 1311 m_eventfile.clear();
1547 - m_eventtype.clear();  
1548 m_bgdfile.clear(); 1312 m_bgdfile.clear();
1549 m_response = NULL; 1313 m_response = NULL;
1550 m_pointing.clear(); 1314 m_pointing.clear();
@@ -1574,7 +1338,6 @@ void GCTAObservation::copy_members(const GCTAObservation&amp; obs) @@ -1574,7 +1338,6 @@ void GCTAObservation::copy_members(const GCTAObservation&amp; obs)
1574 m_instrument = obs.m_instrument; 1338 m_instrument = obs.m_instrument;
1575 m_object = obs.m_object; 1339 m_object = obs.m_object;
1576 m_eventfile = obs.m_eventfile; 1340 m_eventfile = obs.m_eventfile;
1577 - m_eventtype = obs.m_eventtype;  
1578 m_bgdfile = obs.m_bgdfile; 1341 m_bgdfile = obs.m_bgdfile;
1579 m_pointing = obs.m_pointing; 1342 m_pointing = obs.m_pointing;
1580 m_obs_id = obs.m_obs_id; 1343 m_obs_id = obs.m_obs_id;
@@ -1759,46 +1522,3 @@ void GCTAObservation::write_attributes(GFitsHDU&amp; hdu) const @@ -1759,46 +1522,3 @@ void GCTAObservation::write_attributes(GFitsHDU&amp; hdu) const
1759 // Return 1522 // Return
1760 return; 1523 return;
1761 } 1524 }
1762 -  
1763 -  
1764 -/***********************************************************************//**  
1765 - * @brief Set event type  
1766 - *  
1767 - * Depending on the type of events that are stored in the m_events member,  
1768 - * set the event type to  
1769 - *  
1770 - * "EventList" if m_events is of type GCTAEventList  
1771 - * "CountsCube" if m_events is of type GCTAEventCube  
1772 - * "Events" if m_events is not NULL but neither GCTAEventList nor GCTAEventCube  
1773 - * "" if m_events is NULL  
1774 - *  
1775 - ***************************************************************************/  
1776 -void GCTAObservation::set_event_type(void)  
1777 -{  
1778 - // Continue only if events are loaded  
1779 - if (m_events != NULL) {  
1780 -  
1781 - // Case A: we have a list  
1782 - GCTAEventList* list = dynamic_cast<GCTAEventList*>(m_events);  
1783 - if (list != NULL) {  
1784 - m_eventtype = "EventList";  
1785 - }  
1786 -  
1787 - // Case B: we have a cube  
1788 - else {  
1789 - GCTAEventCube* cube = dynamic_cast<GCTAEventCube*>(m_events);  
1790 - if (cube != NULL) {  
1791 - m_eventtype = "CountsCube";  
1792 - }  
1793 -  
1794 - // Case C: we don't know what we have  
1795 - else {  
1796 - m_eventtype = "Events";  
1797 - }  
1798 - }  
1799 -  
1800 - }  
1801 -  
1802 - // Return  
1803 - return;  
1804 -}