Commit 0aed83aabcc9619711008a5d2028853c8e26a3b1

Authored by Jürgen Knödlseder
1 parent 8c02499b

Correctly compute model for stacked analysis (fixes #1609).

Although the get_obs() method was put back, ctmodel used the dummy cube (which consisted of a single pixel) instead of a cube defined from the input parameters. This was due to an internal change of the logic, that now has been corrected for.
src/ctmodel/ctmodel.cpp
@@ -284,7 +284,7 @@ void ctmodel::run(void) @@ -284,7 +284,7 @@ void ctmodel::run(void)
284 284
285 // Fill cube and leave loop if we are binned mode (meaning we 285 // Fill cube and leave loop if we are binned mode (meaning we
286 // only have one binned observation) 286 // only have one binned observation)
287 - if (m_binned && m_obs.size() == 1) { 287 + if (m_binned) {
288 fill_cube(obs); 288 fill_cube(obs);
289 break; 289 break;
290 } 290 }
@@ -464,13 +464,16 @@ void ctmodel::get_parameters(void) @@ -464,13 +464,16 @@ void ctmodel::get_parameters(void)
464 m_append_cube = false; 464 m_append_cube = false;
465 465
466 // If there are no observations in container then load them via user 466 // If there are no observations in container then load them via user
467 - // parameters 467 + // parameters.
468 if (m_obs.size() == 0) { 468 if (m_obs.size() == 0) {
469 get_obs(); 469 get_obs();
470 } 470 }
471 471
472 - // Check if we got excactly one binned CTA observation  
473 - if (m_obs.size() == 1) { 472 + // If we have now excactly one CTA observation (but no cube has yet been
  473 + // appended to the observation) then check whether this observation
  474 + // is a binned observation, and if yes, extract the counts cube for
  475 + // model generation
  476 + if ((m_obs.size() == 1) && (m_append_cube == false)) {
474 477
475 // Get CTA observation 478 // Get CTA observation
476 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); 479 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]);
@@ -498,7 +501,6 @@ void ctmodel::get_parameters(void) @@ -498,7 +501,6 @@ void ctmodel::get_parameters(void)
498 501
499 } // endif: had exactly one observation 502 } // endif: had exactly one observation
500 503
501 -  
502 // Read model definition file if required 504 // Read model definition file if required
503 if (m_obs.models().size() == 0) { 505 if (m_obs.models().size() == 0) {
504 506
@@ -513,7 +515,9 @@ void ctmodel::get_parameters(void) @@ -513,7 +515,9 @@ void ctmodel::get_parameters(void)
513 // Get energy dispersion flag parameters 515 // Get energy dispersion flag parameters
514 m_apply_edisp = (*this)["edisp"].boolean(); 516 m_apply_edisp = (*this)["edisp"].boolean();
515 517
516 - // Optionally get input counts cube for model cube definition 518 + // If we do not have yet a counts cube for model computation then check
  519 + // whether we should read it from the "incube" parameter or whether we
  520 + // should create it from scratch using the task parameters
517 if (!m_has_cube) { 521 if (!m_has_cube) {
518 522
519 // Read cube definition file 523 // Read cube definition file
@@ -544,18 +548,21 @@ void ctmodel::get_parameters(void) @@ -544,18 +548,21 @@ void ctmodel::get_parameters(void)
544 548
545 // Signal that cube has been set 549 // Signal that cube has been set
546 m_has_cube = true; 550 m_has_cube = true;
547 - } 551 +
  552 + } // endif: we had no cube yet
548 553
549 // Read optionally output cube filenames 554 // Read optionally output cube filenames
550 if (read_ahead()) { 555 if (read_ahead()) {
551 - m_outcube = (*this)["outcube"].filename(); 556 + m_outcube = (*this)["outcube"].filename();
552 } 557 }
553 558
554 // If cube should be appended to first observation then do that now. 559 // If cube should be appended to first observation then do that now.
555 // This is a kluge that makes sure that the cube is passed as part 560 // This is a kluge that makes sure that the cube is passed as part
556 // of the observation in case that a cube response is used. The kluge 561 // of the observation in case that a cube response is used. The kluge
557 // is needed because the GCTACubeSourceDiffuse::set method needs to 562 // is needed because the GCTACubeSourceDiffuse::set method needs to
558 - // get the full event cube from the observation. 563 + // get the full event cube from the observation. It is also at this
  564 + // step that the GTI, which may just be a dummy GTI when create_cube()
  565 + // has been used, will be set.
559 if (m_append_cube) { 566 if (m_append_cube) {
560 567
561 //TODO: Check that energy boundaries are compatible 568 //TODO: Check that energy boundaries are compatible
@@ -588,6 +595,11 @@ void ctmodel::get_parameters(void) @@ -588,6 +595,11 @@ void ctmodel::get_parameters(void)
588 * If no file names are specified for the "expcube", "psfcube" or "bkgcube" 595 * If no file names are specified for the "expcube", "psfcube" or "bkgcube"
589 * parameters, the method reads the necessary parameters to build a CTA 596 * parameters, the method reads the necessary parameters to build a CTA
590 * observation from scratch. 597 * observation from scratch.
  598 + *
  599 + * The method sets m_append_cube = true and m_binned = true in case that
  600 + * a stacked observation is requested (as detected by the presence of the
  601 + * "expcube", "psfcube", and "bkgcube" parameters). In that case, it appended
  602 + * a dummy event cube to the observation.
591 ***************************************************************************/ 603 ***************************************************************************/
592 void ctmodel::get_obs(void) 604 void ctmodel::get_obs(void)
593 { 605 {
@@ -620,7 +632,6 @@ void ctmodel::get_obs(void) @@ -620,7 +632,6 @@ void ctmodel::get_obs(void)
620 632
621 // Create dummy sky map cube 633 // Create dummy sky map cube
622 GSkyMap map("CAR","GAL",0.0,0.0,1.0,1.0,1,1,ebounds.size()); 634 GSkyMap map("CAR","GAL",0.0,0.0,1.0,1.0,1,1,ebounds.size());
623 - m_append_cube = true;  
624 635
625 // Create event cube 636 // Create event cube
626 GCTAEventCube cube(map, ebounds, exposure.gti()); 637 GCTAEventCube cube(map, ebounds, exposure.gti());
@@ -633,6 +644,12 @@ void ctmodel::get_obs(void) @@ -633,6 +644,12 @@ void ctmodel::get_obs(void)
633 // Append observation to container 644 // Append observation to container
634 m_obs.append(cta); 645 m_obs.append(cta);
635 646
  647 + // Signal that we are in binned mode
  648 + m_binned = true;
  649 +
  650 + // Signal that we appended a cube
  651 + m_append_cube = true;
  652 +
636 } // endif: cube response information was available 653 } // endif: cube response information was available
637 654
638 // ... otherwise build an observation from IRF response information 655 // ... otherwise build an observation from IRF response information
@@ -646,7 +663,7 @@ void ctmodel::get_obs(void) @@ -646,7 +663,7 @@ void ctmodel::get_obs(void)
646 663
647 // Append observation to container 664 // Append observation to container
648 m_obs.append(cta); 665 m_obs.append(cta);
649 - 666 +
650 } 667 }
651 668
652 } // endif: filename was "NONE" or "" 669 } // endif: filename was "NONE" or ""
src/support/ctool.cpp
@@ -652,7 +652,7 @@ GCTAObservation ctool::create_cta_obs(void) @@ -652,7 +652,7 @@ GCTAObservation ctool::create_cta_obs(void)
652 list.gti(gti); 652 list.gti(gti);
653 list.ebounds(ebounds); 653 list.ebounds(ebounds);
654 654
655 - // Attach event list to CTA observation 655 + // Attach empty event list to CTA observation
656 obs.events(list); 656 obs.events(list);
657 657
658 // Set observation ontime, livetime and deadtime correction factor 658 // Set observation ontime, livetime and deadtime correction factor