Commit f8091f657a4fd25d62be9f2232ec409ff08d9151

Authored by Jürgen Knödlseder
2 parents ac71a9ff 0658d867

Merge branch '1439-change-usage-of-binned-observations-in-GCTACube-classes' into integration

inst/cta/include/GCTACubeBackground.hpp
@@ -65,7 +65,7 @@ public: @@ -65,7 +65,7 @@ public:
65 void clear(void); 65 void clear(void);
66 GCTACubeBackground* clone(void) const; 66 GCTACubeBackground* clone(void) const;
67 std::string classname(void) const; 67 std::string classname(void) const;
68 - void fill(const GObservations& obs); 68 + void fill(const GObservations& obs, GLog* log = NULL);
69 double integral(const double& logE) const; 69 double integral(const double& logE) const;
70 void read(const GFits& fits); 70 void read(const GFits& fits);
71 void write(GFits& file) const; 71 void write(GFits& file) const;
inst/cta/include/GCTACubeExposure.hpp
@@ -74,7 +74,7 @@ public: @@ -74,7 +74,7 @@ public:
74 GCTACubeExposure* clone(void) const; 74 GCTACubeExposure* clone(void) const;
75 std::string classname(void) const; 75 std::string classname(void) const;
76 void set(const GCTAObservation& obs); 76 void set(const GCTAObservation& obs);
77 - void fill(const GObservations& obs); 77 + void fill(const GObservations& obs, GLog* log = NULL);
78 const GSkymap& cube(void) const; 78 const GSkymap& cube(void) const;
79 const GEbounds& ebounds(void) const; 79 const GEbounds& ebounds(void) const;
80 const GGti& gti(void) const; 80 const GGti& gti(void) const;
inst/cta/include/GCTACubePsf.hpp
@@ -82,7 +82,7 @@ public: @@ -82,7 +82,7 @@ public:
82 GCTACubePsf* clone(void) const; 82 GCTACubePsf* clone(void) const;
83 std::string classname(void) const; 83 std::string classname(void) const;
84 void set(const GCTAObservation& obs); 84 void set(const GCTAObservation& obs);
85 - void fill(const GObservations& obs); 85 + void fill(const GObservations& obs, GLog* log = NULL);
86 const GSkymap& map(void) const; 86 const GSkymap& map(void) const;
87 const GEbounds& ebounds(void) const; 87 const GEbounds& ebounds(void) const;
88 const GNodeArray& deltas(void) const; 88 const GNodeArray& deltas(void) const;
inst/cta/include/GCTAObservation.hpp
@@ -124,6 +124,7 @@ public: @@ -124,6 +124,7 @@ public:
124 void deadc(const double& deadc); 124 void deadc(const double& deadc);
125 void eventfile(const std::string& filename); 125 void eventfile(const std::string& filename);
126 const std::string& eventfile(void) const; 126 const std::string& eventfile(void) const;
  127 + const std::string& eventtype(void) const;
127 void dispose_events(void); 128 void dispose_events(void);
128 const double& lo_user_thres(void) const; 129 const double& lo_user_thres(void) const;
129 const double& hi_user_thres(void) const; 130 const double& hi_user_thres(void) const;
@@ -413,6 +414,18 @@ const std::string& GCTAObservation::eventfile(void) const @@ -413,6 +414,18 @@ const std::string& GCTAObservation::eventfile(void) const
413 414
414 415
415 /***********************************************************************//** 416 /***********************************************************************//**
  417 + * @brief Return type of events
  418 + *
  419 + * @return Type of events.
  420 + ***************************************************************************/
  421 +inline
  422 +const std::string& GCTAObservation::eventtype(void) const
  423 +{
  424 + return m_eventtype;
  425 +}
  426 +
  427 +
  428 +/***********************************************************************//**
416 * @brief Return user low energy threshold 429 * @brief Return user low energy threshold
417 * 430 *
418 * @return User low energy threshold. 431 * @return User low energy threshold.
inst/cta/pyext/GCTACubeBackground.i
@@ -52,7 +52,7 @@ public: @@ -52,7 +52,7 @@ public:
52 void clear(void); 52 void clear(void);
53 GCTACubeBackground* clone(void) const; 53 GCTACubeBackground* clone(void) const;
54 std::string classname(void) const; 54 std::string classname(void) const;
55 - void fill(const GObservations& obs); 55 + void fill(const GObservations& obs, GLog* log = NULL);
56 double integral(const double& logE) const; 56 double integral(const double& logE) const;
57 void read(const GFits& fits); 57 void read(const GFits& fits);
58 void write(GFits& file) const; 58 void write(GFits& file) const;
inst/cta/pyext/GCTACubeExposure.i
@@ -65,7 +65,7 @@ public: @@ -65,7 +65,7 @@ public:
65 GCTACubeExposure* clone(void) const; 65 GCTACubeExposure* clone(void) const;
66 std::string classname(void) const; 66 std::string classname(void) const;
67 void set(const GCTAObservation& obs); 67 void set(const GCTAObservation& obs);
68 - void fill(const GObservations& obs); 68 + void fill(const GObservations& obs, GLog* log = NULL);
69 const GSkymap& cube(void) const; 69 const GSkymap& cube(void) const;
70 const GEbounds& ebounds(void) const; 70 const GEbounds& ebounds(void) const;
71 const GGti& gti(void) const; 71 const GGti& gti(void) const;
inst/cta/pyext/GCTACubePsf.i
@@ -74,7 +74,7 @@ public: @@ -74,7 +74,7 @@ public:
74 GCTACubePsf* clone(void) const; 74 GCTACubePsf* clone(void) const;
75 std::string classname(void) const; 75 std::string classname(void) const;
76 void set(const GCTAObservation& obs); 76 void set(const GCTAObservation& obs);
77 - void fill(const GObservations& obs); 77 + void fill(const GObservations& obs, GLog* log = NULL);
78 const GSkymap& map(void) const; 78 const GSkymap& map(void) const;
79 const GEbounds& ebounds(void) const; 79 const GEbounds& ebounds(void) const;
80 const GNodeArray& deltas(void) const; 80 const GNodeArray& deltas(void) const;
inst/cta/pyext/GCTAObservation.i
@@ -96,6 +96,7 @@ public: @@ -96,6 +96,7 @@ public:
96 void deadc(const double& deadc); 96 void deadc(const double& deadc);
97 void eventfile(const std::string& filename); 97 void eventfile(const std::string& filename);
98 const std::string& eventfile(void) const; 98 const std::string& eventfile(void) const;
  99 + const std::string& eventtype(void) const;
99 void dispose_events(void); 100 void dispose_events(void);
100 const double& lo_user_thres(void) const; 101 const double& lo_user_thres(void) const;
101 const double& hi_user_thres(void) const; 102 const double& hi_user_thres(void) const;
inst/cta/src/GCTACubeBackground.cpp
@@ -40,6 +40,7 @@ @@ -40,6 +40,7 @@
40 #include "GCTARoi.hpp" 40 #include "GCTARoi.hpp"
41 #include "GCTAInstDir.hpp" 41 #include "GCTAInstDir.hpp"
42 #include "GCTACubeBackground.hpp" 42 #include "GCTACubeBackground.hpp"
  43 +#include "GLog.hpp"
43 44
44 /* __ Method name definitions ____________________________________________ */ 45 /* __ Method name definitions ____________________________________________ */
45 #define G_READ "GCTACubeBackground::read(GFits&)" 46 #define G_READ "GCTACubeBackground::read(GFits&)"
@@ -263,6 +264,7 @@ GCTACubeBackground* GCTACubeBackground::clone(void) const @@ -263,6 +264,7 @@ GCTACubeBackground* GCTACubeBackground::clone(void) const
263 * @brief Fill background cube from observation container 264 * @brief Fill background cube from observation container
264 * 265 *
265 * @param[in] obs Observation container. 266 * @param[in] obs Observation container.
  267 + * @param[in] log Pointer to logger (optional).
266 * 268 *
267 * @exception GException::invalid_value 269 * @exception GException::invalid_value
268 * No event list found in CTA observations. 270 * No event list found in CTA observations.
@@ -271,7 +273,7 @@ GCTACubeBackground* GCTACubeBackground::clone(void) const @@ -271,7 +273,7 @@ GCTACubeBackground* GCTACubeBackground::clone(void) const
271 * for all CTA observations in an observation container. The cube pixel 273 * for all CTA observations in an observation container. The cube pixel
272 * values are computed as the sum over the background rates. 274 * values are computed as the sum over the background rates.
273 ***************************************************************************/ 275 ***************************************************************************/
274 -void GCTACubeBackground::fill(const GObservations& obs) 276 +void GCTACubeBackground::fill(const GObservations& obs, GLog* log)
275 { 277 {
276 // Clear background cube 278 // Clear background cube
277 m_cube = 0.0; 279 m_cube = 0.0;
@@ -288,49 +290,63 @@ void GCTACubeBackground::fill(const GObservations& obs) @@ -288,49 +290,63 @@ void GCTACubeBackground::fill(const GObservations& obs)
288 // Get observation and continue only if it is a CTA observation 290 // Get observation and continue only if it is a CTA observation
289 const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(obs[i]); 291 const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(obs[i]);
290 292
291 - if (cta != NULL) { 293 + // Skip observation if it's not CTA
  294 + if (cta == NULL) {
  295 + if (log != NULL) {
  296 + *log << "Warning: Skipping "+obs[i]->instrument()+" observation ";
  297 + *log << "\"" << obs[i]->name() << "\"" <<std::endl;
  298 + }
  299 + continue;
  300 + }
292 301
293 - // Extract region of interest from CTA observation  
294 - GCTARoi roi = cta->roi(); 302 + // Skip observation if we don't have an unbinned observation
  303 + if (cta->eventtype() != "EventList") {
  304 + if (log != NULL) {
  305 + *log << "Warning: Skipping binned observation ";
  306 + *log << "\"" << cta->name() << "\"" <<std::endl;
  307 + }
  308 + continue;
  309 + }
295 310
296 - // Set GTI of actual observations as the GTI of the event cube  
297 - eventcube.gti(cta->gti()); 311 + // Extract region of interest from CTA observation
  312 + GCTARoi roi = cta->roi();
298 313
299 - // Get observation livetime  
300 - double livetime = cta->livetime(); 314 + // Set GTI of actual observations as the GTI of the event cube
  315 + eventcube.gti(cta->gti());
301 316
302 - // Loop over all bins in background cube  
303 - for (int i = 0; i < eventcube.size(); ++i) { 317 + // Get observation livetime
  318 + double livetime = cta->livetime();
304 319
305 - // Get event bin  
306 - GCTAEventBin* bin = eventcube[i]; 320 + // Loop over all bins in background cube
  321 + for (int i = 0; i < eventcube.size(); ++i) {
307 322
308 - // Continue only if binned in contained in ROI  
309 - if (roi.contains(*bin)) { 323 + // Get event bin
  324 + GCTAEventBin* bin = eventcube[i];
310 325
311 - // Compute model value for event bin. The model value is  
312 - // given in counts/MeV/s/sr.  
313 - double model = obs.models().eval(*bin, *cta); 326 + // Continue only if binned in contained in ROI
  327 + if (roi.contains(*bin)) {
314 328
315 - // Multiply by livetime to get the correct weighting for  
316 - // each observation. We divide by the total livetime later  
317 - // to get the background model in units of counts/MeV/s/sr.  
318 - model *= livetime; 329 + // Compute model value for event bin. The model value is
  330 + // given in counts/MeV/s/sr.
  331 + double model = obs.models().eval(*bin, *cta);
319 332
320 - // Add existing number of counts  
321 - model += bin->counts(); 333 + // Multiply by livetime to get the correct weighting for
  334 + // each observation. We divide by the total livetime later
  335 + // to get the background model in units of counts/MeV/s/sr.
  336 + model *= livetime;
322 337
323 - // Store cumulated value (units: counts/MeV/sr)  
324 - bin->counts(model); 338 + // Add existing number of counts
  339 + model += bin->counts();
325 340
326 - } // endif: bin was contained in RoI 341 + // Store cumulated value (units: counts/MeV/sr)
  342 + bin->counts(model);
327 343
328 - } // endfor: looped over all bins 344 + } // endif: bin was contained in RoI
329 345
330 - // Accumulate livetime  
331 - total_livetime += livetime; 346 + } // endfor: looped over all bins
332 347
333 - } // endif: cta observation was vaild 348 + // Accumulate livetime
  349 + total_livetime += livetime;
334 350
335 } // endfor: looped over all observations 351 } // endfor: looped over all observations
336 352
inst/cta/src/GCTACubeExposure.cpp
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 #include "GCTAEventList.hpp" 34 #include "GCTAEventList.hpp"
35 #include "GMath.hpp" 35 #include "GMath.hpp"
36 #include "GTools.hpp" 36 #include "GTools.hpp"
  37 +#include "GLog.hpp"
37 38
38 /* __ Method name definitions ____________________________________________ */ 39 /* __ Method name definitions ____________________________________________ */
39 40
@@ -298,55 +299,61 @@ GCTACubeExposure* GCTACubeExposure::clone(void) const @@ -298,55 +299,61 @@ GCTACubeExposure* GCTACubeExposure::clone(void) const
298 ***************************************************************************/ 299 ***************************************************************************/
299 void GCTACubeExposure::set(const GCTAObservation& obs) 300 void GCTACubeExposure::set(const GCTAObservation& obs)
300 { 301 {
301 - // Clear GTIs, reset livetime and exposure cube pixels  
302 - m_gti.clear();  
303 - m_livetime = 0.0;  
304 - m_cube = 0.0;  
305 302
306 - // Extract region of interest from CTA observation  
307 - GCTARoi roi = obs.roi(); 303 + // Only continue if we have an unbinned observation
  304 + if (obs.eventtype() == "EventList") {
308 305
309 - // Get references on CTA response and pointing direction  
310 - const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(obs.response());  
311 - const GSkyDir& pnt = obs.pointing().dir(); 306 + // Clear GTIs, reset livetime and exposure cube pixels
  307 + m_gti.clear();
  308 + m_livetime = 0.0;
  309 + m_cube = 0.0;
312 310
313 - // Continue only if response is valid  
314 - if (rsp != NULL) { 311 + // Extract region of interest from CTA observation
  312 + GCTARoi roi = obs.roi();
315 313
316 - // Loop over all pixels in sky map  
317 - for (int pixel = 0; pixel < m_cube.npix(); ++pixel) { 314 + // Get references on CTA response and pointing direction
  315 + const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(obs.response());
  316 + const GSkyDir& pnt = obs.pointing().dir();
318 317
319 - // Get pixel sky direction  
320 - GSkyDir dir = m_cube.inx2dir(pixel);  
321 -  
322 - // Continue only if pixel is within RoI  
323 - if (roi.centre().dir().dist_deg(dir) <= roi.radius()) { 318 + // Continue only if response is valid
  319 + if (rsp != NULL) {
324 320
325 - // Compute theta angle with respect to pointing direction  
326 - // in radians  
327 - double theta = pnt.dist(dir);  
328 -  
329 - // Loop over all exposure cube energy bins  
330 - for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){ 321 + // Loop over all pixels in sky map
  322 + for (int pixel = 0; pixel < m_cube.npix(); ++pixel) {
331 323
332 - // Get logE/TeV  
333 - double logE = m_ebounds.elogmean(iebin).log10TeV(); 324 + // Get pixel sky direction
  325 + GSkyDir dir = m_cube.inx2dir(pixel);
334 326
335 - // Set exposure cube (effective area * lifetime)  
336 - m_cube(pixel, iebin) = rsp->aeff(theta, 0.0, 0.0, 0.0, logE) *  
337 - obs.livetime(); 327 + // Continue only if pixel is within RoI
  328 + if (roi.centre().dir().dist_deg(dir) <= roi.radius()) {
338 329
339 - } // endfor: looped over energy bins 330 + // Compute theta angle with respect to pointing direction
  331 + // in radians
  332 + double theta = pnt.dist(dir);
340 333
341 - } // endif: pixel was within RoI 334 + // Loop over all exposure cube energy bins
  335 + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){
342 336
343 - } // endfor: looped over all pixels 337 + // Get logE/TeV
  338 + double logE = m_ebounds.elogmean(iebin).log10TeV();
344 339
345 - // Append GTIs and increment livetime  
346 - m_gti.extend(obs.gti());  
347 - m_livetime += obs.livetime(); 340 + // Set exposure cube (effective area * lifetime)
  341 + m_cube(pixel, iebin) = rsp->aeff(theta, 0.0, 0.0, 0.0, logE) *
  342 + obs.livetime();
  343 +
  344 + } // endfor: looped over energy bins
  345 +
  346 + } // endif: pixel was within RoI
  347 +
  348 + } // endfor: looped over all pixels
348 349
349 - } // endif: response was valid 350 + // Append GTIs and increment livetime
  351 + m_gti.extend(obs.gti());
  352 + m_livetime += obs.livetime();
  353 +
  354 + } // endif: response was valid
  355 +
  356 + } // endif: observation was unbinned
350 357
351 // Return 358 // Return
352 return; 359 return;
@@ -357,6 +364,7 @@ void GCTACubeExposure::set(const GCTAObservation&amp; obs) @@ -357,6 +364,7 @@ void GCTACubeExposure::set(const GCTAObservation&amp; obs)
357 * @brief Fill exposure cube from observation container 364 * @brief Fill exposure cube from observation container
358 * 365 *
359 * @param[in] obs Observation container. 366 * @param[in] obs Observation container.
  367 + * @param[in] log Pointer to logger (optional).
360 * 368 *
361 * @exception GException::invalid_value 369 * @exception GException::invalid_value
362 * No event list found in CTA observations. 370 * No event list found in CTA observations.
@@ -365,7 +373,7 @@ void GCTACubeExposure::set(const GCTAObservation&amp; obs) @@ -365,7 +373,7 @@ void GCTACubeExposure::set(const GCTAObservation&amp; obs)
365 * an observation container. The cube pixel values are computed as the sum 373 * an observation container. The cube pixel values are computed as the sum
366 * over the products of the effective area and the livetime. 374 * over the products of the effective area and the livetime.
367 ***************************************************************************/ 375 ***************************************************************************/
368 -void GCTACubeExposure::fill(const GObservations& obs) 376 +void GCTACubeExposure::fill(const GObservations& obs, GLog* log)
369 { 377 {
370 // Clear GTIs, reset livetime and exposure cube pixels 378 // Clear GTIs, reset livetime and exposure cube pixels
371 m_gti.clear(); 379 m_gti.clear();
@@ -377,55 +385,74 @@ void GCTACubeExposure::fill(const GObservations&amp; obs) @@ -377,55 +385,74 @@ void GCTACubeExposure::fill(const GObservations&amp; obs)
377 385
378 // Get observation and continue only if it is a CTA observation 386 // Get observation and continue only if it is a CTA observation
379 const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(obs[i]); 387 const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(obs[i]);
380 - if (cta != NULL) {  
381 388
382 - // Extract region of interest from CTA observation  
383 - GCTARoi roi = cta->roi(); 389 + // Skip observation if it's not CTA
  390 + if (cta == NULL) {
  391 + if (log != NULL) {
  392 + *log << "Warning: Skipping "+obs[i]->instrument()+" observation ";
  393 + *log << "\"" << obs[i]->name() << "\"" <<std::endl;
  394 + }
  395 + continue;
  396 + }
  397 +
  398 + // Skip observation if we don't have an unbinned observation
  399 + if (cta->eventtype() != "EventList") {
  400 + if (log != NULL) {
  401 + *log << "Warning: Skipping binned observation ";
  402 + *log << "\"" << cta->name() << "\"" <<std::endl;
  403 + }
  404 + continue;
  405 + }
  406 +
  407 + // Extract region of interest from CTA observation
  408 + GCTARoi roi = cta->roi();
384 409
385 - // Get references on CTA response and pointing direction  
386 - const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response());  
387 - const GSkyDir& pnt = cta->pointing().dir(); 410 + // Get references on CTA response and pointing direction
  411 + const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response());
  412 + const GSkyDir& pnt = cta->pointing().dir();
388 413
389 - // Continue only if response is valid  
390 - if (rsp != NULL) { 414 + // Skip observation if we don't have an unbinned observation
  415 + if (rsp == NULL) {
  416 + if (log != NULL) {
  417 + *log << "Warning: Observation \"" << cta->name();
  418 + *log << "\" contains no IRF response." <<std::endl;
  419 + }
  420 + continue;
  421 + }
391 422
392 - // Loop over all pixels in sky map  
393 - for (int pixel = 0; pixel < m_cube.npix(); ++pixel) { 423 + // Loop over all pixels in sky map
  424 + for (int pixel = 0; pixel < m_cube.npix(); ++pixel) {
394 425
395 - // Get pixel sky direction  
396 - GSkyDir dir = m_cube.inx2dir(pixel); 426 + // Get pixel sky direction
  427 + GSkyDir dir = m_cube.inx2dir(pixel);
397 428
398 - // Continue only if pixel is within RoI  
399 - if (roi.centre().dir().dist_deg(dir) <= roi.radius()) { 429 + // Continue only if pixel is within RoI
  430 + if (roi.centre().dir().dist_deg(dir) <= roi.radius()) {
400 431
401 - // Compute theta angle with respect to pointing  
402 - // direction in radians  
403 - double theta = pnt.dist(dir);  
404 -  
405 - // Loop over all exposure cube energy bins  
406 - for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){ 432 + // Compute theta angle with respect to pointing
  433 + // direction in radians
  434 + double theta = pnt.dist(dir);
  435 +
  436 + // Loop over all exposure cube energy bins
  437 + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){
407 438
408 - // Get logE/TeV  
409 - double logE = m_ebounds.elogmean(iebin).log10TeV(); 439 + // Get logE/TeV
  440 + double logE = m_ebounds.elogmean(iebin).log10TeV();
410 441
411 - // Add to exposure cube (effective area * livetime)  
412 - m_cube(pixel, iebin) += rsp->aeff(theta, 0.0, 0.0, 0.0, logE) *  
413 - cta->livetime(); 442 + // Add to exposure cube (effective area * livetime)
  443 + m_cube(pixel, iebin) += rsp->aeff(theta, 0.0, 0.0, 0.0, logE) *
  444 + cta->livetime();
414 445
415 - } // endfor: looped over energy bins 446 + } // endfor: looped over energy bins
416 447
417 - } // endif: pixel within RoI 448 + } // endif: pixel within RoI
418 449
419 - } // endfor: looped over all pixels 450 + } // endfor: looped over all pixels
420 451
421 - // Append GTIs and increment livetime  
422 - m_gti.extend(cta->gti());  
423 - m_livetime += cta->livetime(); 452 + // Append GTIs and increment livetime
  453 + m_gti.extend(cta->gti());
  454 + m_livetime += cta->livetime();
424 455
425 - } // endif: response was valid  
426 -  
427 - } // endif: observation was a CTA observation  
428 -  
429 } // endfor: looped over observations 456 } // endfor: looped over observations
430 457
431 // Return 458 // Return
inst/cta/src/GCTACubePsf.cpp
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 #include "GCTAEventList.hpp" 34 #include "GCTAEventList.hpp"
35 #include "GMath.hpp" 35 #include "GMath.hpp"
36 #include "GTools.hpp" 36 #include "GTools.hpp"
  37 +#include "GLog.hpp"
37 38
38 /* __ Method name definitions ____________________________________________ */ 39 /* __ Method name definitions ____________________________________________ */
39 #define G_SET "GCTACubePsf::set(GCTAObservation&)" 40 #define G_SET "GCTACubePsf::set(GCTAObservation&)"
@@ -357,64 +358,69 @@ void GCTACubePsf::set(const GCTAObservation&amp; obs) @@ -357,64 +358,69 @@ void GCTACubePsf::set(const GCTAObservation&amp; obs)
357 // Clear PSF cube 358 // Clear PSF cube
358 clear_cube(); 359 clear_cube();
359 360
360 - // Extract region of interest from CTA observation  
361 - const GCTAEventList* list = dynamic_cast<const GCTAEventList*>(obs.events());  
362 - if (list == NULL) {  
363 - std::string msg = "CTA Observation does not contain an event "  
364 - "list. Event list information is needed to "  
365 - "retrieve the Region of Interest for each "  
366 - "CTA observation.";  
367 - throw GException::invalid_value(G_SET, msg);  
368 - }  
369 - const GCTARoi& roi = list->roi(); 361 + // Only continue if we have an unbinned observation
  362 + if (obs.eventtype() == "EventList") {
  363 +
  364 + // Extract region of interest from CTA observation
  365 + const GCTAEventList* list = dynamic_cast<const GCTAEventList*>(obs.events());
  366 + if (list == NULL) {
  367 + std::string msg = "CTA Observation does not contain an event "
  368 + "list. Event list information is needed to "
  369 + "retrieve the Region of Interest for each "
  370 + "CTA observation.";
  371 + throw GException::invalid_value(G_SET, msg);
  372 + }
  373 + const GCTARoi& roi = list->roi();
370 374
371 - // Get references on CTA response and pointing direction  
372 - const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(obs.response());  
373 - const GSkyDir& pnt = obs.pointing().dir(); 375 + // Get references on CTA response and pointing direction
  376 + const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(obs.response());
  377 + const GSkyDir& pnt = obs.pointing().dir();
374 378
375 - // Continue only if response is valid  
376 - if (rsp != NULL) { 379 + // Continue only if response is valid
  380 + if (rsp != NULL) {
377 381
378 - // Loop over all pixels in sky map  
379 - for (int pixel = 0; pixel < m_cube.npix(); ++pixel) { 382 + // Loop over all pixels in sky map
  383 + for (int pixel = 0; pixel < m_cube.npix(); ++pixel) {
  384 +
  385 + // Get pixel sky direction
  386 + GSkyDir dir = m_cube.inx2dir(pixel);
  387 +
  388 + // Continue only if pixel is within RoI
  389 + if (roi.centre().dir().dist_deg(dir) <= roi.radius()) {
380 390
381 - // Get pixel sky direction  
382 - GSkyDir dir = m_cube.inx2dir(pixel);  
383 -  
384 - // Continue only if pixel is within RoI  
385 - if (roi.centre().dir().dist_deg(dir) <= roi.radius()) { 391 + // Compute theta angle with respect to pointing direction
  392 + // in radians
  393 + double theta = pnt.dist(dir);
386 394
387 - // Compute theta angle with respect to pointing direction  
388 - // in radians  
389 - double theta = pnt.dist(dir);  
390 -  
391 - // Loop over all exposure cube energy bins  
392 - for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){ 395 + // Loop over all exposure cube energy bins
  396 + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){
393 397
394 - // Get logE/TeV  
395 - double logE = m_ebounds.elogmean(iebin).log10TeV(); 398 + // Get logE/TeV
  399 + double logE = m_ebounds.elogmean(iebin).log10TeV();
396 400
397 - // Loop over delta values  
398 - for (int idelta = 0; idelta < m_deltas.size(); ++idelta) { 401 + // Loop over delta values
  402 + for (int idelta = 0; idelta < m_deltas.size(); ++idelta) {
399 403
400 - // Compute delta in radians  
401 - double delta = m_deltas[idelta] * gammalib::deg2rad; 404 + // Compute delta in radians
  405 + double delta = m_deltas[idelta] * gammalib::deg2rad;
402 406
403 - // Set map index  
404 - int imap = offset(idelta, iebin);  
405 -  
406 - // Set PSF cube  
407 - m_cube(pixel, imap) = rsp->psf(delta, theta, 0.0, 0.0, 0.0, logE); 407 + // Set map index
  408 + int imap = offset(idelta, iebin);
408 409
409 - } // endfor: looped over delta bins 410 + // Set PSF cube
  411 + m_cube(pixel, imap) = rsp->psf(delta, theta, 0.0, 0.0, 0.0, logE);
410 412
411 - } // endfor: looped over energy bins 413 + } // endfor: looped over delta bins
412 414
413 - } // endif: pixel was within RoI 415 + } // endfor: looped over energy bins
414 416
415 - } // endfor: looped over all pixels 417 + } // endif: pixel was within RoI
416 418
417 - } // endif: response was valid 419 + } // endfor: looped over all pixels
  420 +
  421 + } // endif: response was valid
  422 +
  423 + } // endif: observation was unbinned
418 424
419 // Compile option: guarantee smooth Psf 425 // Compile option: guarantee smooth Psf
420 #if defined(G_SMOOTH_PSF) 426 #if defined(G_SMOOTH_PSF)
@@ -431,7 +437,7 @@ void GCTACubePsf::set(const GCTAObservation&amp; obs) @@ -431,7 +437,7 @@ void GCTACubePsf::set(const GCTAObservation&amp; obs)
431 * 437 *
432 * @param[in] obs Observation container. 438 * @param[in] obs Observation container.
433 ***************************************************************************/ 439 ***************************************************************************/
434 -void GCTACubePsf::fill(const GObservations& obs) 440 +void GCTACubePsf::fill(const GObservations& obs, GLog* log)
435 { 441 {
436 // Clear PSF cube 442 // Clear PSF cube
437 clear_cube(); 443 clear_cube();
@@ -444,68 +450,87 @@ void GCTACubePsf::fill(const GObservations&amp; obs) @@ -444,68 +450,87 @@ void GCTACubePsf::fill(const GObservations&amp; obs)
444 450
445 // Get observation and continue only if it is a CTA observation 451 // Get observation and continue only if it is a CTA observation
446 const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(obs[i]); 452 const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(obs[i]);
447 - if (cta != NULL) {  
448 453
449 - // Extract region of interest from CTA observation  
450 - GCTARoi roi = cta->roi(); 454 + // Skip observation if it's not CTA
  455 + if (cta == NULL) {
  456 + if (log != NULL) {
  457 + *log << "Warning: Skipping "+obs[i]->instrument()+" observation ";
  458 + *log << "\"" << obs[i]->name() << "\"" <<std::endl;
  459 + }
  460 + continue;
  461 + }
451 462
452 - // Get references on CTA response and pointing direction  
453 - const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response());  
454 - const GSkyDir& pnt = cta->pointing().dir(); 463 + // Skip observation if we don't have an unbinned observation
  464 + if (cta->eventtype() != "EventList") {
  465 + if (log != NULL) {
  466 + *log << "Warning: Skipping binned observation ";
  467 + *log << "\"" << cta->name() << "\"" <<std::endl;
  468 + }
  469 + continue;
  470 + }
455 471
456 - // Continue only if response is valid  
457 - if (rsp != NULL) { 472 + // Extract region of interest from CTA observation
  473 + GCTARoi roi = cta->roi();
458 474
459 - // Loop over all pixels in sky map  
460 - for (int pixel = 0; pixel < m_cube.npix(); ++pixel) { 475 + // Get references on CTA response and pointing direction
  476 + const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response());
  477 + const GSkyDir& pnt = cta->pointing().dir();
461 478
462 - // Get pixel sky direction  
463 - GSkyDir dir = m_cube.inx2dir(pixel);  
464 -  
465 - // Continue only if pixel is within RoI  
466 - if (roi.centre().dir().dist_deg(dir) <= roi.radius()) { 479 + // Skip observation if we don't have an unbinned observation
  480 + if (rsp == NULL) {
  481 + if (log != NULL) {
  482 + *log << "Warning: Observation \"" << cta->name();
  483 + *log << "\" contains no IRF response." <<std::endl;
  484 + }
  485 + continue;
  486 + }
467 487
468 - // Compute theta angle with respect to pointing  
469 - // direction in radians  
470 - double theta = pnt.dist(dir);  
471 -  
472 - // Loop over all energy bins  
473 - for (int iebin = 0; iebin < m_ebounds.size(); ++iebin) { 488 + // Loop over all pixels in sky map
  489 + for (int pixel = 0; pixel < m_cube.npix(); ++pixel) {
474 490
475 - // Get logE/TeV  
476 - double logE = m_ebounds.elogmean(iebin).log10TeV(); 491 + // Get pixel sky direction
  492 + GSkyDir dir = m_cube.inx2dir(pixel);
  493 +
  494 + // Continue only if pixel is within RoI
  495 + if (roi.centre().dir().dist_deg(dir) <= roi.radius()) {
477 496
478 - // Compute exposure weight  
479 - double weight = rsp->aeff(theta, 0.0, 0.0, 0.0, logE) *  
480 - cta->livetime(); 497 + // Compute theta angle with respect to pointing
  498 + // direction in radians
  499 + double theta = pnt.dist(dir);
481 500
482 - // Accumulate weights  
483 - exposure(pixel, iebin) += weight; 501 + // Loop over all energy bins
  502 + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin) {
484 503
485 - // Loop over delta values  
486 - for (int idelta = 0; idelta < m_deltas.size(); ++idelta) { 504 + // Get logE/TeV
  505 + double logE = m_ebounds.elogmean(iebin).log10TeV();
487 506
488 - // Compute delta in radians  
489 - double delta = m_deltas[idelta] * gammalib::deg2rad; 507 + // Compute exposure weight
  508 + double weight = rsp->aeff(theta, 0.0, 0.0, 0.0, logE) *
  509 + cta->livetime();
490 510
491 - // Set map index  
492 - int imap = offset(idelta, iebin); 511 + // Accumulate weights
  512 + exposure(pixel, iebin) += weight;
493 513
494 - // Add on PSF cube  
495 - m_cube(pixel, imap) +=  
496 - rsp->psf(delta, theta, 0.0, 0.0, 0.0, logE) * weight; 514 + // Loop over delta values
  515 + for (int idelta = 0; idelta < m_deltas.size(); ++idelta) {
497 516
498 - } // endfor: looped over delta bins 517 + // Compute delta in radians
  518 + double delta = m_deltas[idelta] * gammalib::deg2rad;
499 519
500 - } // endfor: looped over energy bins 520 + // Set map index
  521 + int imap = offset(idelta, iebin);
  522 +
  523 + // Add on PSF cube
  524 + m_cube(pixel, imap) +=
  525 + rsp->psf(delta, theta, 0.0, 0.0, 0.0, logE) * weight;
501 526
502 - } // endif: pixel was within RoI 527 + } // endfor: looped over delta bins
503 528
504 - } // endfor: looped over all pixels 529 + } // endfor: looped over energy bins
505 530
506 - } // endif: response was valid 531 + } // endif: pixel was within RoI
507 532
508 - } // endif: observation was a CTA observation 533 + } // endfor: looped over all pixels
509 534
510 } // endfor: looped over observations 535 } // endfor: looped over observations
511 536