Commit 209428cfb6d8e8333bb30b8993c664810e511130

Authored by Jürgen Knödlseder
1 parent d0096357

Add ctlike results to XML file (#3431)

ChangeLog
... ... @@ -3,6 +3,7 @@
3 3 * Version 2.0.0 released
4 4 ========================
5 5  
  6 + Add ctlike results to XML file (#3431)
6 7 Fix implementation of fix_spat_for_ts parameter in ctlike (#3426)
7 8  
8 9  
... ...
... ... @@ -76,6 +76,9 @@ None
76 76  
77 77 ctlike - Maximum likelihood fitting
78 78 -----------------------------------
  79 +The model fitting results, such as log-likelihood value, number of iterations
  80 +etc. are now added to the output XML file (#3431).
  81 +
79 82 A bug was fixed in the implementation of the fix_spat_for_ts parameter that
80 83 only fixed the spatial parameters for the first of the sky models but left
81 84 the spatial parameters free for all additional sky models. Now the parameters
... ...
doc/source/admin/release_history/2.0.rst
... ... @@ -24,6 +24,9 @@ Bug fixes
24 24 Improvements
25 25 ------------
26 26  
  27 +* [`3431 <https://cta-redmine.irap.omp.eu/issues/3431>`_] -
  28 + Add :ref:`ctlike` results to XML file
  29 +
27 30  
28 31 New features
29 32 ------------
... ...
src/ctlike/ctlike.cpp
1 1 /***************************************************************************
2 2 * ctlike - Maximum likelihood fitting tool *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2019 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2020 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -236,10 +236,10 @@ void ctlike::run(void)
236 236 // Store copy of curvature matrix
237 237 GMatrixSparse curvature =
238 238 *(const_cast<GObservations::likelihood&>(m_obs.function()).curvature());
239   -
  239 +
240 240 // Store Npred
241   - double npred = m_obs.npred();
242   -
  241 + m_npred = m_obs.npred();
  242 +
243 243 // Store models for which TS should be computed
244 244 std::vector<std::string> ts_srcs;
245 245 GModels models_orig = m_obs.models();
... ... @@ -308,11 +308,11 @@ void ctlike::run(void)
308 308 } // endif: requested TS computation
309 309  
310 310 // Compute number of observed events in all observations
311   - double num_events = 0.0;
  311 + m_nobs = 0.0;
312 312 for (int i = 0; i < m_obs.size(); ++i) {
313 313 double data = m_obs[i]->nobserved();
314 314 if (data >= 0.0) {
315   - num_events += data;
  315 + m_nobs += data;
316 316 }
317 317 }
318 318  
... ... @@ -320,9 +320,9 @@ void ctlike::run(void)
320 320 log_header1(NORMAL, "Maximum likelihood optimisation results");
321 321 log_string(NORMAL, m_opt.print(m_chatter));
322 322 log_value(NORMAL, "Maximum log likelihood", gammalib::str(m_logL,3));
323   - log_value(NORMAL, "Observed events (Nobs)", gammalib::str(num_events,3));
324   - log_value(NORMAL, "Predicted events (Npred)", gammalib::str(npred,3)+
325   - " (Nobs - Npred = "+gammalib::str(num_events-npred)+")");
  323 + log_value(NORMAL, "Observed events (Nobs)", gammalib::str(m_nobs,3));
  324 + log_value(NORMAL, "Predicted events (Npred)", gammalib::str(m_npred,3)+
  325 + " (Nobs - Npred = "+gammalib::str(m_nobs-m_npred)+")");
326 326 log_string(NORMAL, m_obs.models().print(m_chatter));
327 327  
328 328 // Restore energy dispersion flags of all CTA observations
... ... @@ -356,6 +356,9 @@ void ctlike::save(void)
356 356 // Save model only if filename is valid
357 357 if ((*this)["outmodel"].is_valid()) {
358 358  
  359 + // Generate XML instance
  360 + GXml xml = xml_result();
  361 +
359 362 // Get output filename
360 363 m_outmodel = (*this)["outmodel"].filename();
361 364  
... ... @@ -363,9 +366,9 @@ void ctlike::save(void)
363 366 log_value(NORMAL, "Model definition file", m_outmodel.url());
364 367  
365 368 // Write results out as XML model
366   - m_obs.models().save(m_outmodel);
  369 + xml.save(m_outmodel);
367 370  
368   - }
  371 + } // endif: filename was valid
369 372  
370 373 // ... otherwise signal that file was not saved
371 374 else {
... ... @@ -396,6 +399,69 @@ void ctlike::save(void)
396 399 }
397 400  
398 401  
  402 +/*==========================================================================
  403 + = =
  404 + = Private methods =
  405 + = =
  406 + ==========================================================================*/
  407 +
  408 +/***********************************************************************//**
  409 + * @brief Initialise class members
  410 + ***************************************************************************/
  411 +void ctlike::init_members(void)
  412 +{
  413 + // Initialise members
  414 + m_outmodel.clear();
  415 + m_outcovmat.clear();
  416 + m_refit = false;
  417 + m_apply_edisp = false;
  418 + m_fix_spat_for_ts = false;
  419 + m_chatter = static_cast<GChatter>(2);
  420 + m_logL = 0.0;
  421 + m_nobs = 0.0;
  422 + m_npred = 0.0;
  423 +
  424 + // Set logger properties
  425 + log.date(true);
  426 +
  427 + // Return
  428 + return;
  429 +}
  430 +
  431 +
  432 +/***********************************************************************//**
  433 + * @brief Copy class members
  434 + *
  435 + * @param[in] app Application.
  436 + ***************************************************************************/
  437 +void ctlike::copy_members(const ctlike& app)
  438 +{
  439 + // Copy attributes
  440 + m_refit = app.m_refit;
  441 + m_outmodel = app.m_outmodel;
  442 + m_outcovmat = app.m_outcovmat;
  443 + m_apply_edisp = app.m_apply_edisp;
  444 + m_fix_spat_for_ts = app.m_fix_spat_for_ts;
  445 + m_chatter = app.m_chatter;
  446 + m_logL = app.m_logL;
  447 + m_nobs = app.m_nobs;
  448 + m_npred = app.m_npred;
  449 +
  450 + // Return
  451 + return;
  452 +}
  453 +
  454 +
  455 +/***********************************************************************//**
  456 + * @brief Delete class members
  457 + ***************************************************************************/
  458 +void ctlike::free_members(void)
  459 +{
  460 + // Return
  461 + return;
  462 +}
  463 +
  464 +
399 465 /***********************************************************************//**
400 466 * @brief Get application parameters
401 467 *
... ... @@ -562,60 +628,70 @@ double ctlike::reoptimize_lm(void)
562 628 }
563 629  
564 630  
565   -/*==========================================================================
566   - = =
567   - = Private methods =
568   - = =
569   - ==========================================================================*/
570   -
571   -/***********************************************************************//**
572   - * @brief Initialise class members
573   - ***************************************************************************/
574   -void ctlike::init_members(void)
575   -{
576   - // Initialise members
577   - m_outmodel.clear();
578   - m_outcovmat.clear();
579   - m_refit = false;
580   - m_logL = 0.0;
581   - m_apply_edisp = false;
582   - m_fix_spat_for_ts = false;
583   - m_chatter = static_cast<GChatter>(2);
584   -
585   - // Set logger properties
586   - log.date(true);
587   -
588   - // Return
589   - return;
590   -}
591   -
592   -
593 631 /***********************************************************************//**
594   - * @brief Copy class members
  632 + * @brief Generate XML result
595 633 *
596   - * @param[in] app Application.
  634 + * @return XML result
  635 + *
  636 + * Generates the XML result composed of the ctlike results and the model
  637 + * fitting results.
597 638 ***************************************************************************/
598   -void ctlike::copy_members(const ctlike& app)
  639 +GXml ctlike::xml_result(void) const
599 640 {
600   - // Copy attributes
601   - m_refit = app.m_refit;
602   - m_outmodel = app.m_outmodel;
603   - m_outcovmat = app.m_outcovmat;
604   - m_logL = app.m_logL;
605   - m_apply_edisp = app.m_apply_edisp;
606   - m_fix_spat_for_ts = app.m_fix_spat_for_ts;
607   - m_chatter = app.m_chatter;
608   -
609   - // Return
610   - return;
611   -}
  641 + // Initialise XML result
  642 + GXml xml;
  643 +
  644 + // Set fit status
  645 + std::string status;
  646 + switch (m_opt.status()) {
  647 + case G_LM_CONVERGED:
  648 + status.append("converged");
  649 + break;
  650 + case G_LM_STALLED:
  651 + status.append("stalled");
  652 + break;
  653 + case G_LM_SINGULAR:
  654 + status.append("singular curvature matrix encountered");
  655 + break;
  656 + case G_LM_NOT_POSTIVE_DEFINITE:
  657 + status.append("curvature matrix not positive definite");
  658 + break;
  659 + case G_LM_BAD_ERRORS:
  660 + status.append("errors are inaccurate");
  661 + break;
  662 + default:
  663 + status.append("unknown");
  664 + break;
  665 + }
612 666  
  667 + // Set flag strings
  668 + std::string refit = (m_refit) ? "yes" : "no";
  669 + std::string edisp = (m_apply_edisp) ? "yes" : "no";
  670 + std::string fix_spat_for_ts = (m_fix_spat_for_ts) ? "yes" : "no";
613 671  
614   -/***********************************************************************//**
615   - * @brief Delete class members
616   - ***************************************************************************/
617   -void ctlike::free_members(void)
618   -{
619   - // Return
620   - return;
  672 + // Write ctlike results into XML instance
  673 + if (xml.elements("ctlike_results") == 0) {
  674 + xml.append(GXmlElement("ctlike_results title=\"ctlike fit results\""));
  675 + }
  676 + GXmlElement* result = xml.element("ctlike_results", 0);
  677 + result->append(GXmlElement("status", status));
  678 + result->append(GXmlElement("log-likelihood", m_logL));
  679 + result->append(GXmlElement("precision", m_opt.eps()));
  680 + result->append(GXmlElement("iterations", m_opt.iter()));
  681 + result->append(GXmlElement("lambda", m_opt.lambda()));
  682 + result->append(GXmlElement("total_parameters", m_opt.npars()));
  683 + result->append(GXmlElement("fitted_parameters", m_opt.nfree()));
  684 + result->append(GXmlElement("observed-events", m_nobs));
  685 + result->append(GXmlElement("predicted-events", m_npred));
  686 + result->append(GXmlElement("refit", refit));
  687 + result->append(GXmlElement("edisp", edisp));
  688 + result->append(GXmlElement("fix-spatial-for-ts", fix_spat_for_ts));
  689 + result->append(GXmlElement("elapsed-time", this->telapse()));
  690 + result->append(GXmlElement("cpu-seconds", this->celapse()));
  691 +
  692 + // Write model results into XML instance
  693 + m_obs.models().write(xml);
  694 +
  695 + // Return XML result
  696 + return xml;
621 697 }
... ...
src/ctlike/ctlike.hpp
1 1 /***************************************************************************
2 2 * ctlike - Maximum likelihood fitting tool *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2018 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2020 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -65,17 +65,20 @@ protected:
65 65 void get_parameters(void);
66 66 void optimize_lm(void);
67 67 double reoptimize_lm(void);
  68 + GXml xml_result(void) const;
68 69  
69 70 // User parameters
70   - bool m_refit; //!< Refitting
71 71 GFilename m_outmodel; //!< Source model output XML file name
72 72 GFilename m_outcovmat; //!< Covariance matrix output file name
  73 + bool m_refit; //!< Refitting
73 74 bool m_apply_edisp; //!< Apply energy dispersion?
74 75 bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation?
75 76 GChatter m_chatter; //!< Chattiness
76 77  
77 78 // Members
78 79 double m_logL; //!< Maximum log likelihood
  80 + double m_nobs; //!< Number of observed events
  81 + double m_npred; //!< Number of predicted events
79 82 };
80 83  
81 84 #endif /* CTLIKE_HPP */
... ...