Commit 209428cfb6d8e8333bb30b8993c664810e511130

Authored by Jürgen Knödlseder
1 parent d0096357

Add ctlike results to XML file (#3431)

ChangeLog
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 * Version 2.0.0 released 3 * Version 2.0.0 released
4 ======================== 4 ========================
5 5
  6 + Add ctlike results to XML file (#3431)
6 Fix implementation of fix_spat_for_ts parameter in ctlike (#3426) 7 Fix implementation of fix_spat_for_ts parameter in ctlike (#3426)
7 8
8 9
@@ -76,6 +76,9 @@ None @@ -76,6 +76,9 @@ None
76 76
77 ctlike - Maximum likelihood fitting 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 A bug was fixed in the implementation of the fix_spat_for_ts parameter that 82 A bug was fixed in the implementation of the fix_spat_for_ts parameter that
80 only fixed the spatial parameters for the first of the sky models but left 83 only fixed the spatial parameters for the first of the sky models but left
81 the spatial parameters free for all additional sky models. Now the parameters 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,6 +24,9 @@ Bug fixes
24 Improvements 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 New features 31 New features
29 ------------ 32 ------------
src/ctlike/ctlike.cpp
1 /*************************************************************************** 1 /***************************************************************************
2 * ctlike - Maximum likelihood fitting tool * 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 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -236,10 +236,10 @@ void ctlike::run(void) @@ -236,10 +236,10 @@ void ctlike::run(void)
236 // Store copy of curvature matrix 236 // Store copy of curvature matrix
237 GMatrixSparse curvature = 237 GMatrixSparse curvature =
238 *(const_cast<GObservations::likelihood&>(m_obs.function()).curvature()); 238 *(const_cast<GObservations::likelihood&>(m_obs.function()).curvature());
239 - 239 +
240 // Store Npred 240 // Store Npred
241 - double npred = m_obs.npred();  
242 - 241 + m_npred = m_obs.npred();
  242 +
243 // Store models for which TS should be computed 243 // Store models for which TS should be computed
244 std::vector<std::string> ts_srcs; 244 std::vector<std::string> ts_srcs;
245 GModels models_orig = m_obs.models(); 245 GModels models_orig = m_obs.models();
@@ -308,11 +308,11 @@ void ctlike::run(void) @@ -308,11 +308,11 @@ void ctlike::run(void)
308 } // endif: requested TS computation 308 } // endif: requested TS computation
309 309
310 // Compute number of observed events in all observations 310 // Compute number of observed events in all observations
311 - double num_events = 0.0; 311 + m_nobs = 0.0;
312 for (int i = 0; i < m_obs.size(); ++i) { 312 for (int i = 0; i < m_obs.size(); ++i) {
313 double data = m_obs[i]->nobserved(); 313 double data = m_obs[i]->nobserved();
314 if (data >= 0.0) { 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,9 +320,9 @@ void ctlike::run(void)
320 log_header1(NORMAL, "Maximum likelihood optimisation results"); 320 log_header1(NORMAL, "Maximum likelihood optimisation results");
321 log_string(NORMAL, m_opt.print(m_chatter)); 321 log_string(NORMAL, m_opt.print(m_chatter));
322 log_value(NORMAL, "Maximum log likelihood", gammalib::str(m_logL,3)); 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 log_string(NORMAL, m_obs.models().print(m_chatter)); 326 log_string(NORMAL, m_obs.models().print(m_chatter));
327 327
328 // Restore energy dispersion flags of all CTA observations 328 // Restore energy dispersion flags of all CTA observations
@@ -356,6 +356,9 @@ void ctlike::save(void) @@ -356,6 +356,9 @@ void ctlike::save(void)
356 // Save model only if filename is valid 356 // Save model only if filename is valid
357 if ((*this)["outmodel"].is_valid()) { 357 if ((*this)["outmodel"].is_valid()) {
358 358
  359 + // Generate XML instance
  360 + GXml xml = xml_result();
  361 +
359 // Get output filename 362 // Get output filename
360 m_outmodel = (*this)["outmodel"].filename(); 363 m_outmodel = (*this)["outmodel"].filename();
361 364
@@ -363,9 +366,9 @@ void ctlike::save(void) @@ -363,9 +366,9 @@ void ctlike::save(void)
363 log_value(NORMAL, "Model definition file", m_outmodel.url()); 366 log_value(NORMAL, "Model definition file", m_outmodel.url());
364 367
365 // Write results out as XML model 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 // ... otherwise signal that file was not saved 373 // ... otherwise signal that file was not saved
371 else { 374 else {
@@ -396,6 +399,69 @@ void ctlike::save(void) @@ -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 * @brief Get application parameters 466 * @brief Get application parameters
401 * 467 *
@@ -562,60 +628,70 @@ double ctlike::reoptimize_lm(void) @@ -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 * ctlike - Maximum likelihood fitting tool * 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 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -65,17 +65,20 @@ protected: @@ -65,17 +65,20 @@ protected:
65 void get_parameters(void); 65 void get_parameters(void);
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 69
69 // User parameters 70 // User parameters
70 - bool m_refit; //!< Refitting  
71 GFilename m_outmodel; //!< Source model output XML file name 71 GFilename m_outmodel; //!< Source model output XML file name
72 GFilename m_outcovmat; //!< Covariance matrix output file name 72 GFilename m_outcovmat; //!< Covariance matrix output file name
  73 + bool m_refit; //!< Refitting
73 bool m_apply_edisp; //!< Apply energy dispersion? 74 bool m_apply_edisp; //!< Apply energy dispersion?
74 bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation? 75 bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation?
75 GChatter m_chatter; //!< Chattiness 76 GChatter m_chatter; //!< Chattiness
76 77
77 // Members 78 // Members
78 double m_logL; //!< Maximum log likelihood 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 #endif /* CTLIKE_HPP */ 84 #endif /* CTLIKE_HPP */