Commit 209428cfb6d8e8333bb30b8993c664810e511130
1 parent
d0096357
Add ctlike results to XML file (#3431)
Showing
5 changed files
with
149 additions
and
63 deletions
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 |
NEWS
| @@ -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 */ |