34#include "GOptimizer.hpp"
37#define G_GET_MODEL_PARAMETER "ctulimit::get_model_parameter()"
38#define G_GET_PARAMETER_BRACKETS "ctulimit::get_parameter_brackets(double&, "\
40#define G_UL_BISECTION "ctulimit::ul_bisection(double&, double&)"
201 this->GApplication::clear();
235 GModels models_orig =
m_obs.models();
238 log_header1(TERSE,
"Compute best-fit likelihood");
249 GOptimizerLM best_opt =
m_opt;
253 log_value(NORMAL,
"Maximum log likelihood",gammalib::str(
m_best_logL,3));
262 log_header1(TERSE,
"Compute upper limit");
265 log_value(NORMAL,
"Model name",
m_skymodel->name());
266 log_value(NORMAL,
"Parameter name",
m_model_par->name());
268 log_value(NORMAL,
"Confidence level", gammalib::str(
m_confidence*100.0)+
"%");
269 log_value(NORMAL,
"Maximum log likelihood",gammalib::str(
m_best_logL,3));
270 log_value(NORMAL,
"Log-likelihood difference",
m_dlogL);
271 log_value(NORMAL,
"Initial factor value range",
272 "["+gammalib::str(parmin)+
", "+gammalib::str(parmax)+
"]");
278 log_value(NORMAL,
"Upper limit factor value",
m_model_par->factor_value());
279 log_value(NORMAL,
"Upper limit param. value",
m_model_par->value());
285 log_header1(TERSE,
"Upper limit results");
288 log_value(TERSE,
"Differential flux limit",
290 gammalib::str(
m_eref)+
" TeV");
291 log_value(TERSE,
"Integral flux limit",
293 gammalib::str(
m_emin)+
"-"+
294 gammalib::str(
m_emax)+
"] TeV");
295 log_value(TERSE,
"Energy flux limit",
297 gammalib::str(
m_emin)+
"-"+
298 gammalib::str(
m_emax)+
"] TeV");
301 m_obs.models(models_orig);
447 double sigma = gammalib::erfinv(
m_confidence) * gammalib::sqrt_two;
455 m_eref = (*this)[
"eref"].real();
456 m_emin = (*this)[
"emin"].real();
457 m_emax = (*this)[
"emax"].real();
460 m_opt.eps((*
this)[
"like_accuracy"].real());
461 m_opt.max_iter((*
this)[
"max_iter"].integer());
464 m_tol = (*this)[
"tol"].real();
468 m_chatter =
static_cast<GChatter
>((*this)[
"chatter"].integer());
492 const char* pars[] = {
"Normalization",
"Value",
"Prefactor",
493 "Integral",
"PhotonFlux",
"EnergyFlux",
504 std::string msg =
"Source \""+
m_srcname+
"\" not found in model "
505 "container. Please add a source with that name "
506 "or check for possible typos.";
513 GModels&
models =
const_cast<GModels&
>(
m_obs.models());
516 std::string msg =
"Source \""+
m_srcname+
"\" is not a sky model. Please "
517 "specify the name of a sky model for upper limit "
532 std::string msg =
"Spatial or spectral model of source \""+
534 "\". Please specify a valid parameter name "
535 "or leave the parameter name blank for "
536 "autodetermination of an intensity- or "
537 "flux-like parameter.";
547 if (
m_skymodel->spectral()->type() ==
"NodeFunction") {
548 std::string msg =
"Spectral model of source \""+
m_srcname+
"\" is "
549 "a \"NodeFunction\" but no parameter name was "
550 "specified. Please use the \"parname\" parameter "
551 "to specify the parameter that should be used "
552 "for the upper limit computation.";
558 for (
const char** par = pars; *par != NULL; ++par) {
569 std::string msg =
"Require one of the following spectral "
570 "parameters for upper limit computation: ";
571 for (
const char** par = pars; *par != NULL; ++par) {
575 msg.append(
"\""+std::string(*par)+
"\"");
577 msg.append(
". The specified source \""+
m_srcname+
"\" does not "
578 "have such a parameter.");
601 log_header1(TERSE,
"Find parameter brackets");
630 std::string msg =
"The maximum number of "+gammalib::str(
m_max_iter)+
631 " has been reached. You may consider to increase"
632 " the \"max_iter\" parameter and re-run ctulimit.";
647 log_value(NORMAL,
"Parameter range",
648 "["+gammalib::str(parmin)+
", "+gammalib::str(parmax)+
"] "
649 "logL("+gammalib::str(parmax)+
")="+gammalib::str(logL));
653 if (eval_mid < 0.0) {
690 double wrk_min = parmin;
691 double wrk_max = parmax;
695 bool restart =
false;
702 std::string msg =
"The maximum number of "+gammalib::str(
m_max_iter)+
703 " has been reached. You may consider to increase"
704 " the \"max_iter\" parameter and re-run ctulimit.";
715 double mid = (wrk_min + wrk_max) / 2.0;
722 log_value(NORMAL,
"Iteration "+gammalib::str(iter),
723 "["+gammalib::str(wrk_min)+
", "+gammalib::str(wrk_max)+
"] "
724 "logL("+gammalib::str(mid)+
")="+gammalib::str(logL)+
" "
725 "dlogL="+gammalib::str(eval_mid));
728 if (std::abs(eval_mid) <
m_tol) {
737 if (std::abs(eps) < 1.0e-6) {
739 " *** WARNING: Parameter range mid-point "+gammalib::str(mid)+
" is "
740 "close to best factor\n"
742 "log-likelihood value "+gammalib::str(logL)+
"\n"
743 " at the mid-point differs significantly from the "
744 "log-likelihood value\n"
745 " "+gammalib::str(
m_best_logL)+
" for the best factor "
747 log_string(TERSE, msg);
752 eps = (mid != 0.0) ? (wrk_min - wrk_max)/mid : wrk_min - wrk_max;
753 if (std::abs(eps) < 1.0e-6) {
755 " *** WARNING: Parameter range ["+gammalib::str(wrk_min)+
", "+
756 gammalib::str(wrk_max)+
"] has reduced\n"
757 " to a narrow interval without reaching convergence! "
759 " log-likelihood value is probably not an absolute "
762 log_string(TERSE, msg);
767 if (!restart && status != 0) {
778 " Adopt "+gammalib::str(logL)+
" as best log-likelihood and restart "
780 log_string(TERSE, msg);
788 if (eval_mid > 0.0) {
820 GEnergy eref = GEnergy(
m_eref,
"TeV");
823 GEnergy emin = GEnergy(
m_emin,
"TeV");
824 GEnergy emax = GEnergy(
m_emax,
"TeV");
828 GModelSpectral* spectral =
m_skymodel->spectral();
829 GModelSpectralNodes* nodes = NULL;
834 GModelSpatialDiffuseCube* cube =
835 dynamic_cast<GModelSpatialDiffuseCube*
>(
m_skymodel->spatial());
840 cube->mc_cone(GSkyRegionCircle(0.0, 0.0, 180.0));
843 nodes =
new GModelSpectralNodes(cube->spectrum());
844 for (
int i = 0; i < nodes->nodes(); ++i) {
845 GEnergy energy = nodes->energy(i);
846 double intensity = nodes->intensity(i);
847 double value = spectral->eval(energy);
848 nodes->intensity(i, value*intensity);
854 if (nodes->nodes() > 0) {
864 if (spectral != NULL) {
Base class for likelihood tools.
GOptimizerLM m_opt
Optimizer.
ctlikelihood & operator=(const ctlikelihood &app)
Assignment operator.
double evaluate(GModelPar &par, const double &value)
Evaluates the log-likelihood function.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
GObservations m_obs
Observation container.
const GModels & models(void) const
Return model container.
void init_members(void)
Initialise class members.
void set_obs_statistic(const std::string &statistic)
Set fit statistic for CTA observations.
Upper limit calculation tool.
ctulimit & operator=(const ctulimit &app)
Assignment operator.
double m_sigma_min
Starting value minimum (multiple fit errors above fit values)
bool m_apply_edisp
Apply energy dispersion?
void save(void)
Save upper limits.
double m_flux_ulimit
Flux upper limit value.
double m_best_value
Best parameter value factor.
void get_parameters(void)
Get application parameters.
virtual ~ctulimit(void)
Destructor.
GModelPar * m_model_par
Pointer to model parameter.
double m_eflux_ulimit
Energy flux upper limits.
void process(void)
Compute upper limit.
void ulimit_bisection(const double &parmin, const double &parmax)
Calculate upper limit using a bisection method.
double m_eref
Reference energy for flux limits (TeV)
void free_members(void)
Delete class members.
ctulimit(void)
Void constructor.
void get_model_parameter(void)
Get model parameter.
double m_confidence
Confidence level.
std::string m_srcname
Name of source for upper limit computation.
void compute_ulimit(void)
Compute upper limit intensity and fluxes.
double m_diff_ulimit
Differential upper limit value.
GModelSky * m_skymodel
Pointer to sky model.
void copy_members(const ctulimit &app)
Copy class members.
int m_max_iter
Maximum number of iterations.
double m_emax
Maximum energy for flux limits (TeV)
void clear(void)
Clear ctulimit tool.
std::string m_parname
Name of parameter for upper limit computation.
double m_dlogL
Likelihood difference for upper limit computation.
double m_best_logL
Best fit log likelihood of given model.
double m_best_error
Best parameter value error.
double m_sigma_max
Starting value maximum (multiple fit errors above fit values)
double m_tol
Tolerance for limit determination.
double m_emin
Minimum energy for flux limits (TeV)
bool m_is_spatial
Signal that model parameter is spatial parameter.
void init_members(void)
Initialise class members.
void get_parameter_brackets(double &parmin, double &parmax)
Determine parameter brackets.
GChatter m_chatter
Chattiness.
#define G_GET_PARAMETER_BRACKETS
#define G_GET_MODEL_PARAMETER
Upper limit calculation tool interface implementation.