Commit 81c788f125a2129b8961c64bc7b100720ee11de6
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
Showing
5 changed files
with
52 additions
and
10 deletions
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& 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,,, "Output covariance matrix FITS file" |
| 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') | ... | ... |