Commit 1e57632c95e62281c732dfc057d6957ccbb1baa5

Authored by Jürgen Knödlseder
2 parents 6755e796 d223acf4

Merge branch 'upper-limit' into integration

Showing 1 changed file with 31 additions and 3 deletions
src/ctulimit/ctulimit.cpp
1 1 /***************************************************************************
2 2 * ctulimit - Upper limit calculation tool *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2015-2020 by Michael Mayer *
  4 + * copyright (C) 2015-2021 by Michael Mayer *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -268,7 +268,8 @@ void ctulimit::run(void)
268 268  
269 269 } // endif: likelihood was zero
270 270  
271   - // Get parameter brackets
  271 + // Get parameter brackets. Note that this method recomputes m_best_logL
  272 + // to make sure that the value is coherent for the upper limit search.
272 273 double parmin;
273 274 double parmax;
274 275 get_parameter_brackets(parmin, parmax);
... ... @@ -280,6 +281,7 @@ void ctulimit::run(void)
280 281 log_value(NORMAL, "Model name", m_skymodel->name());
281 282 log_value(NORMAL, "Parameter name", m_model_par->name());
282 283 log_value(NORMAL, "Confidence level", gammalib::str(m_confidence*100.0)+"%");
  284 + log_value(NORMAL, "Best log-likelihood value", m_best_logL);
283 285 log_value(NORMAL, "Log-likelihood difference", m_dlogL);
284 286 log_value(NORMAL, "Initial parameter range",
285 287 "["+gammalib::str(parmin)+", "+gammalib::str(parmax)+"]");
... ... @@ -604,6 +606,13 @@ void ctulimit::get_parameter_brackets(double& parmin, double& parmax)
604 606 double value = m_model_par->factor_value();
605 607 double error = m_model_par->factor_error();
606 608  
  609 + // Re-compute best log-likelihood for value fixed at optimum
  610 + m_best_logL = evaluate(*m_model_par, value);
  611 +
  612 + // Write best log-likelihood
  613 + log_value(NORMAL, "Best log-likelihood",
  614 + "logL("+gammalib::str(value)+")="+gammalib::str(m_best_logL));
  615 +
607 616 // If parameter error is zero then take parameter value as error
608 617 if (error == 0.0) {
609 618 error = value;
... ... @@ -671,7 +680,12 @@ void ctulimit::get_parameter_brackets(double& parmin, double& parmax)
671 680 * Exceeded maximum number of iterations in the upper limit
672 681 * search.
673 682 *
674   - * Calculates the upper limit using a bisection method.
  683 + * Calculates the upper limit using a bisection method. The bisection is
  684 + * stopped if the log-likelihood value is within the tolerance of the target
  685 + * value. The bisection is also stopped putting a warning in the log file if
  686 + * the parameter interval becomes smaller than a tolerance of 1.0e-6. The
  687 + * method stops with an exception if the maximum number of iterations is
  688 + * exhausted.
675 689 ***************************************************************************/
676 690 void ctulimit::ulimit_bisection(const double& parmin, const double& parmax)
677 691 {
... ... @@ -710,6 +724,20 @@ void ctulimit::ulimit_bisection(const double& parmin, const double& parmax)
710 724 break;
711 725 }
712 726  
  727 + // Check for vanishing parameter range
  728 + if (std::abs(wrk_min-wrk_max) < 1.0e-6) {
  729 + std::string msg = "*** WARNING: Parameter range "
  730 + "["+gammalib::str(wrk_min)+", "+
  731 + gammalib::str(wrk_max)+"] has reduced to a "
  732 + "narrow interval without reaching convergence!\n"
  733 + " The best log-likelihood value is "
  734 + "probably not an absolute but only a local "
  735 + "minimum.\n"
  736 + " Stop iterations.";
  737 + log_string(TERSE, msg);
  738 + break;
  739 + }
  740 +
713 741 // Change boundaries for further iteration
714 742 if (eval_mid > 0.0) {
715 743 wrk_max = mid; // logL too large, new range = [wrk_min, mid]
... ...