Commit 81c788f125a2129b8961c64bc7b100720ee11de6

Authored by Jürgen Knödlseder
1 parent 573432d6

Correctly compute total number of fit iterations for XML file, fix a bug in the …

…new refitting logic, and revert back to original reference values for the unit tests
src/ctlike/ctlike.cpp
... ... @@ -430,6 +430,7 @@ void ctlike::init_members(void)
430 430 m_apply_edisp = false;
431 431 m_fix_spat_for_ts = false;
432 432 m_chatter = static_cast<GChatter>(2);
  433 + m_iter = 0;
433 434 m_logL = 0.0;
434 435 m_nobs = 0.0;
435 436 m_npred = 0.0;
... ... @@ -459,6 +460,7 @@ void ctlike::copy_members(const ctlike&amp; app)
459 460 m_apply_edisp = app.m_apply_edisp;
460 461 m_fix_spat_for_ts = app.m_fix_spat_for_ts;
461 462 m_chatter = app.m_chatter;
  463 + m_iter = app.m_iter;
462 464 m_logL = app.m_logL;
463 465 m_nobs = app.m_nobs;
464 466 m_npred = app.m_npred;
... ... @@ -557,6 +559,9 @@ void ctlike::optimize_lm(void)
557 559 log_header1(TERSE, "Maximum likelihood optimisation");
558 560 log.indent(1);
559 561  
  562 + // Initialise number of iterations
  563 + m_iter = 0;
  564 +
560 565 // Compute number of fitted parameters
561 566 int nfit = 0;
562 567 for (int i = 0; i < m_obs.models().size(); ++i) {
... ... @@ -578,6 +583,9 @@ void ctlike::optimize_lm(void)
578 583 // Perform LM optimization
579 584 m_obs.optimize(m_opt);
580 585  
  586 + // Add number of iterations
  587 + m_iter += m_opt.iter();
  588 +
581 589 // Optionally refit
582 590 if (refit(&m_opt)) {
583 591  
... ... @@ -589,6 +597,9 @@ void ctlike::optimize_lm(void)
589 597 // Optimise again
590 598 m_obs.optimize(m_opt);
591 599  
  600 + // Add number of iterations
  601 + m_iter += m_opt.iter();
  602 +
592 603 }
593 604  
594 605 // Optionally show curvature matrix
... ... @@ -701,7 +712,7 @@ GXml ctlike::xml_result(void) const
701 712 result->append(GXmlElement("status", status));
702 713 result->append(GXmlElement("log-likelihood", m_logL));
703 714 result->append(GXmlElement("precision", m_opt.eps()));
704   - result->append(GXmlElement("iterations", m_opt.iter()));
  715 + result->append(GXmlElement("iterations", m_iter));
705 716 result->append(GXmlElement("lambda", m_opt.lambda()));
706 717 result->append(GXmlElement("total_parameters", m_opt.npars()));
707 718 result->append(GXmlElement("fitted_parameters", m_opt.nfree()));
... ... @@ -748,12 +759,48 @@ bool ctlike::refit(const GOptimizer* opt)
748 759 }
749 760  
750 761 // ... otherwise were the number of fit iterations exhausted?
751   - else if (opt->iter() >= 1) {
  762 + else if (opt->iter() >= m_max_iter) {
752 763 refit = true;
753 764 log_value(NORMAL, "Refit requested",
754 765 "Number of fit iterations exhausted");
755 766 }
756 767  
  768 + // ... otherwise check if there is a significant difference between
  769 + // the number of observed and predicted events
  770 + else {
  771 + double npred = m_obs.npred();
  772 + double difference = m_nobs - npred;
  773 + if (m_nobs > 0.0) {
  774 + double fraction = difference / m_nobs;
  775 + if (std::abs(fraction) > 1.0e-4) {
  776 + refit = true;
  777 + log_value(NORMAL, "Refit requested",
  778 + "Difference "+
  779 + gammalib::str(difference)+
  780 + " between number of observed events "+
  781 + gammalib::str(m_nobs)+
  782 + " and predicted events "+
  783 + gammalib::str(npred)+
  784 + " is larger than +/- 1.0e-4 times the number of"+
  785 + " observed events ("+
  786 + gammalib::str(fraction)+").");
  787 + }
  788 + }
  789 + else {
  790 + if (std::abs(difference) > 10.0) {
  791 + refit = true;
  792 + log_value(NORMAL, "Refit requested",
  793 + "Difference "+
  794 + gammalib::str(difference)+
  795 + " between number of observed events "+
  796 + gammalib::str(m_nobs)+
  797 + " and predicted events "+
  798 + gammalib::str(npred)+
  799 + " is larger than +/- 10.");
  800 + }
  801 + }
  802 + } // endelse: check number of events
  803 +
757 804 }
758 805  
759 806 // Return refit flag
... ...
src/ctlike/ctlike.hpp
... ... @@ -80,6 +80,7 @@ protected:
80 80 GChatter m_chatter; //!< Chattiness
81 81  
82 82 // Members
  83 + int m_iter; //!< Number of iterations
83 84 double m_logL; //!< Maximum log likelihood
84 85 double m_nobs; //!< Number of observed events
85 86 double m_npred; //!< Number of predicted events
... ...
src/ctlike/ctlike.par
... ... @@ -33,7 +33,7 @@ outcovmat, f, h, NONE,,, &quot;Output covariance matrix FITS file&quot;
33 33 #========================
34 34 statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic"
35 35 refit, b, h, no,,, "Do refitting?"
36   -refit_if_failed, b, h, yes,,, "Refit if fit stalled or fit iterations were exhausted?"
  36 +refit_if_failed, b, h, yes,,, "Refit if fit failed?"
37 37 like_accuracy, r, h, 0.005,1.0e-30,1.0, "Absolute accuracy of maximum likelihood value"
38 38 max_iter, i, h, 50,1,1000, "Maximum number of fit iterations"
39 39 fix_spat_for_ts, b, h, no,,, "Fix spatial parameters for TS computation?"
... ...
test/test_csworkflow.py
... ... @@ -142,8 +142,7 @@ class Test(test):
142 142 prefactor = 3.63152145731529e-16
143 143 index = 2.39100016863397
144 144 pre_background = 1.30910556742873
145   - #index_background = 0.252909973473968
146   - index_background = 0.252938308459647
  145 + index_background = 0.252909973473968
147 146  
148 147 # Check fit result values
149 148 self.test_value(models['Crab'][2].value(),
... ...
test/test_ctulimit.py
... ... @@ -209,11 +209,6 @@ class Test(test):
209 209 ulimit.logFileOpen() # Needed to get a new log file
210 210 ulimit.execute()
211 211  
212   - # Set new reference values since the ctlike results changed
213   - # a bit due to changes in ctlike
214   - ref_flux = 1.6694433147174e-11
215   - ref_eflux = 6.458852107887e-11
216   -
217 212 # Check results
218 213 self.test_value(ulimit.diff_ulimit(), ref_diff, 1.0e-21,
219 214 'Check differential upper limit')
... ...