Commit 573432d67780b9c8e56bdafb1b55ab9f07fe6a7f
1 parent
10e1f7cc
Add "refit_if_failed" parameter and set it by default to yes.
The "refit_if_failed" parameter instructs ctlike to perform a refit in case of a fit failure. Fit failures are either a stalled fit, an exhaustion of the number of iterations, or a significant difference between the number of observed and predicted events.
Showing
6 changed files
with
67 additions
and
12 deletions
src/ctlike/ctlike.cpp
| @@ -423,7 +423,10 @@ void ctlike::init_members(void) | @@ -423,7 +423,10 @@ void ctlike::init_members(void) | ||
| 423 | // Initialise members | 423 | // Initialise members |
| 424 | m_outmodel.clear(); | 424 | m_outmodel.clear(); |
| 425 | m_outcovmat.clear(); | 425 | m_outcovmat.clear(); |
| 426 | + m_max_iter = 50; | ||
| 427 | + m_like_accuracy = 0.005; | ||
| 426 | m_refit = false; | 428 | m_refit = false; |
| 429 | + m_refit_if_failed = true; | ||
| 427 | m_apply_edisp = false; | 430 | m_apply_edisp = false; |
| 428 | m_fix_spat_for_ts = false; | 431 | m_fix_spat_for_ts = false; |
| 429 | m_chatter = static_cast<GChatter>(2); | 432 | m_chatter = static_cast<GChatter>(2); |
| @@ -447,9 +450,12 @@ void ctlike::init_members(void) | @@ -447,9 +450,12 @@ void ctlike::init_members(void) | ||
| 447 | void ctlike::copy_members(const ctlike& app) | 450 | void ctlike::copy_members(const ctlike& app) |
| 448 | { | 451 | { |
| 449 | // Copy attributes | 452 | // Copy attributes |
| 450 | - m_refit = app.m_refit; | ||
| 451 | m_outmodel = app.m_outmodel; | 453 | m_outmodel = app.m_outmodel; |
| 452 | m_outcovmat = app.m_outcovmat; | 454 | m_outcovmat = app.m_outcovmat; |
| 455 | + m_max_iter = app.m_max_iter; | ||
| 456 | + m_like_accuracy = app.m_like_accuracy; | ||
| 457 | + m_refit = app.m_refit; | ||
| 458 | + m_refit_if_failed = app.m_refit_if_failed; | ||
| 453 | m_apply_edisp = app.m_apply_edisp; | 459 | m_apply_edisp = app.m_apply_edisp; |
| 454 | m_fix_spat_for_ts = app.m_fix_spat_for_ts; | 460 | m_fix_spat_for_ts = app.m_fix_spat_for_ts; |
| 455 | m_chatter = app.m_chatter; | 461 | m_chatter = app.m_chatter; |
| @@ -498,11 +504,14 @@ void ctlike::get_parameters(void) | @@ -498,11 +504,14 @@ void ctlike::get_parameters(void) | ||
| 498 | } // endif: no models were associated with observations | 504 | } // endif: no models were associated with observations |
| 499 | 505 | ||
| 500 | // Set optimizer characteristics from user parameters | 506 | // Set optimizer characteristics from user parameters |
| 501 | - m_opt.eps((*this)["like_accuracy"].real()); | ||
| 502 | - m_opt.max_iter((*this)["max_iter"].integer()); | 507 | + m_max_iter = (*this)["max_iter"].integer(); |
| 508 | + m_like_accuracy = (*this)["like_accuracy"].real(); | ||
| 509 | + m_opt.eps(m_like_accuracy); | ||
| 510 | + m_opt.max_iter(m_max_iter); | ||
| 503 | 511 | ||
| 504 | // Get other parameters | 512 | // Get other parameters |
| 505 | m_refit = (*this)["refit"].boolean(); | 513 | m_refit = (*this)["refit"].boolean(); |
| 514 | + m_refit_if_failed = (*this)["refit_if_failed"].boolean(); | ||
| 506 | m_apply_edisp = (*this)["edisp"].boolean(); | 515 | m_apply_edisp = (*this)["edisp"].boolean(); |
| 507 | m_fix_spat_for_ts = (*this)["fix_spat_for_ts"].boolean(); | 516 | m_fix_spat_for_ts = (*this)["fix_spat_for_ts"].boolean(); |
| 508 | m_chatter = static_cast<GChatter>((*this)["chatter"].integer()); | 517 | m_chatter = static_cast<GChatter>((*this)["chatter"].integer()); |
| @@ -570,7 +579,7 @@ void ctlike::optimize_lm(void) | @@ -570,7 +579,7 @@ void ctlike::optimize_lm(void) | ||
| 570 | m_obs.optimize(m_opt); | 579 | m_obs.optimize(m_opt); |
| 571 | 580 | ||
| 572 | // Optionally refit | 581 | // Optionally refit |
| 573 | - if (m_refit) { | 582 | + if (refit(&m_opt)) { |
| 574 | 583 | ||
| 575 | // Dump new header | 584 | // Dump new header |
| 576 | log.indent(0); | 585 | log.indent(0); |
| @@ -621,7 +630,7 @@ double ctlike::reoptimize_lm(void) | @@ -621,7 +630,7 @@ double ctlike::reoptimize_lm(void) | ||
| 621 | m_obs.optimize(*opt); | 630 | m_obs.optimize(*opt); |
| 622 | 631 | ||
| 623 | // Optionally refit | 632 | // Optionally refit |
| 624 | - if (m_refit) { | 633 | + if (refit(opt)) { |
| 625 | m_obs.optimize(*opt); | 634 | m_obs.optimize(*opt); |
| 626 | } | 635 | } |
| 627 | 636 | ||
| @@ -710,3 +719,43 @@ GXml ctlike::xml_result(void) const | @@ -710,3 +719,43 @@ GXml ctlike::xml_result(void) const | ||
| 710 | // Return XML result | 719 | // Return XML result |
| 711 | return xml; | 720 | return xml; |
| 712 | } | 721 | } |
| 722 | + | ||
| 723 | + | ||
| 724 | +/***********************************************************************//** | ||
| 725 | + * @brief Refit needed? | ||
| 726 | + * | ||
| 727 | + * @param[in] opt Pointer to optimiser. | ||
| 728 | + * @return True if refit is needed, false otherwise. | ||
| 729 | + * | ||
| 730 | + * This method returns true if either the "refit" parameter is set to yes | ||
| 731 | + * or the "refit_if_failed" parameter is set to yes and the fit has failed. | ||
| 732 | + * The fit is considered as failed if it either has stalled or the number | ||
| 733 | + * of fit iterations is exhausted. | ||
| 734 | + ***************************************************************************/ | ||
| 735 | +bool ctlike::refit(const GOptimizer* opt) | ||
| 736 | +{ | ||
| 737 | + // Initialise refit flag | ||
| 738 | + bool refit = m_refit; | ||
| 739 | + | ||
| 740 | + // If flag is false and "refit_if_failed" is true then examine optimiser | ||
| 741 | + // result to determine whether the fit has failed | ||
| 742 | + if (!refit && m_refit_if_failed) { | ||
| 743 | + | ||
| 744 | + // Has the fit stalled? | ||
| 745 | + if (opt->status() == G_LM_STALLED) { | ||
| 746 | + refit = true; | ||
| 747 | + log_value(NORMAL, "Refit requested", "Fit has stalled"); | ||
| 748 | + } | ||
| 749 | + | ||
| 750 | + // ... otherwise were the number of fit iterations exhausted? | ||
| 751 | + else if (opt->iter() >= 1) { | ||
| 752 | + refit = true; | ||
| 753 | + log_value(NORMAL, "Refit requested", | ||
| 754 | + "Number of fit iterations exhausted"); | ||
| 755 | + } | ||
| 756 | + | ||
| 757 | + } | ||
| 758 | + | ||
| 759 | + // Return refit flag | ||
| 760 | + return refit; | ||
| 761 | +} |
src/ctlike/ctlike.hpp
| @@ -66,11 +66,15 @@ protected: | @@ -66,11 +66,15 @@ protected: | ||
| 66 | void optimize_lm(void); | 66 | void optimize_lm(void); |
| 67 | double reoptimize_lm(void); | 67 | double reoptimize_lm(void); |
| 68 | GXml xml_result(void) const; | 68 | GXml xml_result(void) const; |
| 69 | + bool refit(const GOptimizer* opt); | ||
| 69 | 70 | ||
| 70 | // User parameters | 71 | // User parameters |
| 71 | GFilename m_outmodel; //!< Source model output XML file name | 72 | GFilename m_outmodel; //!< Source model output XML file name |
| 72 | GFilename m_outcovmat; //!< Covariance matrix output file name | 73 | GFilename m_outcovmat; //!< Covariance matrix output file name |
| 73 | - bool m_refit; //!< Refitting | 74 | + int m_max_iter; //!< Maximum number of iterations |
| 75 | + double m_like_accuracy; //!< Log-likelihood accuracy | ||
| 76 | + bool m_refit; //!< Refitting? | ||
| 77 | + bool m_refit_if_failed; //!< Refitting in case of failure? | ||
| 74 | bool m_apply_edisp; //!< Apply energy dispersion? | 78 | bool m_apply_edisp; //!< Apply energy dispersion? |
| 75 | bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation? | 79 | bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation? |
| 76 | GChatter m_chatter; //!< Chattiness | 80 | GChatter m_chatter; //!< Chattiness |
src/ctlike/ctlike.par
| @@ -33,6 +33,7 @@ outcovmat, f, h, NONE,,, "Output covariance matrix FITS file" | @@ -33,6 +33,7 @@ outcovmat, f, h, NONE,,, "Output covariance matrix FITS file" | ||
| 33 | #======================== | 33 | #======================== |
| 34 | statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic" | 34 | statistic, s, h, DEFAULT,DEFAULT|CSTAT|WSTAT|CHI2,, "Optimization statistic" |
| 35 | refit, b, h, no,,, "Do refitting?" | 35 | refit, b, h, no,,, "Do refitting?" |
| 36 | +refit_if_failed, b, h, yes,,, "Refit if fit stalled or fit iterations were exhausted?" | ||
| 36 | like_accuracy, r, h, 0.005,1.0e-30,1.0, "Absolute accuracy of maximum likelihood value" | 37 | like_accuracy, r, h, 0.005,1.0e-30,1.0, "Absolute accuracy of maximum likelihood value" |
| 37 | max_iter, i, h, 50,1,1000, "Maximum number of fit iterations" | 38 | max_iter, i, h, 50,1,1000, "Maximum number of fit iterations" |
| 38 | fix_spat_for_ts, b, h, no,,, "Fix spatial parameters for TS computation?" | 39 | fix_spat_for_ts, b, h, no,,, "Fix spatial parameters for TS computation?" |
src/ctulimit/ctulimit.cpp
| @@ -709,11 +709,6 @@ void ctulimit::ulimit_bisection(const double& parmin, const double& parmax) | @@ -709,11 +709,6 @@ void ctulimit::ulimit_bisection(const double& parmin, const double& parmax) | ||
| 709 | if (std::abs(eval_mid) < m_tol) { | 709 | if (std::abs(eval_mid) < m_tol) { |
| 710 | break; | 710 | break; |
| 711 | } | 711 | } |
| 712 | - /* | ||
| 713 | - if (std::abs(wrk_max-wrk_min) < m_tol) { | ||
| 714 | - break; | ||
| 715 | - } | ||
| 716 | - */ | ||
| 717 | 712 | ||
| 718 | // Change boundaries for further iteration | 713 | // Change boundaries for further iteration |
| 719 | if (eval_mid > 0.0) { | 714 | if (eval_mid > 0.0) { |
test/test_csworkflow.py
| @@ -142,7 +142,8 @@ class Test(test): | @@ -142,7 +142,8 @@ class Test(test): | ||
| 142 | prefactor = 3.63152145731529e-16 | 142 | prefactor = 3.63152145731529e-16 |
| 143 | index = 2.39100016863397 | 143 | index = 2.39100016863397 |
| 144 | pre_background = 1.30910556742873 | 144 | pre_background = 1.30910556742873 |
| 145 | - index_background = 0.252909973473968 | 145 | + #index_background = 0.252909973473968 |
| 146 | + index_background = 0.252938308459647 | ||
| 146 | 147 | ||
| 147 | # Check fit result values | 148 | # Check fit result values |
| 148 | self.test_value(models['Crab'][2].value(), | 149 | self.test_value(models['Crab'][2].value(), |
test/test_ctulimit.py
| @@ -209,6 +209,11 @@ class Test(test): | @@ -209,6 +209,11 @@ class Test(test): | ||
| 209 | ulimit.logFileOpen() # Needed to get a new log file | 209 | ulimit.logFileOpen() # Needed to get a new log file |
| 210 | ulimit.execute() | 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 | + | ||
| 212 | # Check results | 217 | # Check results |
| 213 | self.test_value(ulimit.diff_ulimit(), ref_diff, 1.0e-21, | 218 | self.test_value(ulimit.diff_ulimit(), ref_diff, 1.0e-21, |
| 214 | 'Check differential upper limit') | 219 | 'Check differential upper limit') |