diff --git a/NEWS b/NEWS index fefc685..186c8ec 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,7 @@ The following methods have been added: - GObservation::model_grad(GModel&, GModelPar&) - GModels::eval(GObservation&, GMatrixSparse*) - GModel::eval(GObservation&, GMatrixSparse*) +- GModel::associations() - GModelSky::eval(GObservation&, GMatrixSparse*) - GModelData::eval(GObservation&, GMatrixSparse*) - GModelSky::flux(GEnergy&, GEnergy&) @@ -102,8 +103,12 @@ Implemented GMatrixSparse::row() and GMatrixSparse::add_to_row() methods. 8. Model module --------------- Added GModelAssociation class to implement a model association and the -GModelAssociations container class to hold a list of model associations -(#3469). +GModelAssociations container class to hold a list of model associations. +The GModelAssociations class was added as a member of GModel, and +GModel::associations() getter and setter methods have been implemented to +access the associations. The associations are also automatically written in +the GModel::read_attributes() and GModel::write_attributes() methods, and +the association names are displayed by GModel::print_attributes() (#3469). Added GModels::eval() vector evaluation method to compute the model values for all events within a given observation (#3455). diff --git a/include/GModel.hpp b/include/GModel.hpp index 896b439..475a695 100644 --- a/include/GModel.hpp +++ b/include/GModel.hpp @@ -32,6 +32,7 @@ #include #include "GBase.hpp" #include "GModelPar.hpp" +#include "GModelAssociations.hpp" #include "GXmlElement.hpp" #include "GEnergy.hpp" #include "GTime.hpp" @@ -130,31 +131,33 @@ public: virtual std::string print(const GChatter& chatter = NORMAL) const = 0; // Implemented methods - int size(void) const; - int scales(void) const; - GModelPar& at(const int& index); - const GModelPar& at(const int& index) const; - bool has_par(const std::string& name) const; - bool has_scales(void) const; - const std::string& name(void) const; - void name(const std::string& name); - const double& ts(void) const; - void ts(const double& ts); - const bool& tscalc(void) const; - void tscalc(const bool& tscalc); - const bool& has_ts(void) const; - std::string instruments(void) const; - void instruments(const std::string& instruments); - GModelPar& scale(const int& index); - const GModelPar& scale(const int& index) const; - GModelPar scale(const std::string& instrument) const; - void scale(const GModelPar& par); - std::string ids(void) const; - void ids(const std::string& ids); - bool is_valid(const std::string& instruments, - const std::string& ids) const; - const bool& has_eval_indices(void) const; - const std::vector& eval_indices(void) const; + int size(void) const; + int scales(void) const; + GModelPar& at(const int& index); + const GModelPar& at(const int& index) const; + bool has_par(const std::string& name) const; + bool has_scales(void) const; + const std::string& name(void) const; + void name(const std::string& name); + const double& ts(void) const; + void ts(const double& ts); + const bool& tscalc(void) const; + void tscalc(const bool& tscalc); + const bool& has_ts(void) const; + std::string instruments(void) const; + void instruments(const std::string& instruments); + GModelPar& scale(const int& index); + const GModelPar& scale(const int& index) const; + GModelPar scale(const std::string& instrument) const; + void scale(const GModelPar& par); + std::string ids(void) const; + void ids(const std::string& ids); + bool is_valid(const std::string& instruments, + const std::string& ids) const; + const GModelAssociations& associations(void) const; + void associations(const GModelAssociations& associations); + const bool& has_eval_indices(void) const; + const std::vector& eval_indices(void) const; protected: // Protected methods @@ -173,6 +176,7 @@ protected: std::vector m_scales; //!< Model instrument scale factors std::vector m_ids; //!< Identifiers to which model applies std::vector m_pars; //!< Pointers to all model parameters + GModelAssociations m_associations; //!< Model associations bool m_has_ts; //!< Signals if TS is available bool m_has_tscalc; //!< Signals if tscalc attribute is available bool m_tscalc; //!< Signals if TS should be computed @@ -274,6 +278,7 @@ void GModel::name(const std::string& name) return; } + /***********************************************************************//** * @brief Return Test Statistic value * @@ -366,6 +371,35 @@ const bool& GModel::has_ts(void) const /***********************************************************************//** + * @brief Return model associations + * + * @return Model associations. + * + * Returns model associations. + ***************************************************************************/ +inline +const GModelAssociations& GModel::associations(void) const +{ + return m_associations; +} + + +/***********************************************************************//** + * @brief Set model associations + * + * @param[in] associations Model associations. + * + * Set the model associations. + ***************************************************************************/ +inline +void GModel::associations(const GModelAssociations& associations) +{ + m_associations = associations; + return; +} + + +/***********************************************************************//** * @brief Signals that parameter indices updated by eval() method were set * * @return True if parameter indices updated by eval() method were set. diff --git a/include/GModelAssociations.hpp b/include/GModelAssociations.hpp index b0e1deb..026bfa5 100644 --- a/include/GModelAssociations.hpp +++ b/include/GModelAssociations.hpp @@ -31,9 +31,9 @@ #include #include #include "GContainer.hpp" +#include "GModelAssociation.hpp" /* __ Forward declarations _______________________________________________ */ -class GModelAssociation; class GXmlElement; diff --git a/pyext/GModel.i b/pyext/GModel.i index 57c6efa..8780136 100644 --- a/pyext/GModel.i +++ b/pyext/GModel.i @@ -61,28 +61,30 @@ public: virtual void write(GXmlElement& xml) const = 0; // Implemented methods - int size(void) const; - int scales(void) const; - bool has_par(const std::string& name) const; - bool has_scales(void) const; - const std::string& name(void) const; - void name(const std::string& name); - const double& ts(void) const; - void ts(const double& ts); - const bool& tscalc(void) const; - void tscalc(const bool& tscalc); - const bool& has_ts(void) const; - std::string instruments(void) const; - void instruments(const std::string& instruments); - GModelPar& scale(const int& index); - GModelPar scale(const std::string& instrument) const; - void scale(const GModelPar& par); - std::string ids(void) const; - void ids(const std::string& ids); - bool is_valid(const std::string& instruments, - const std::string& ids) const; - const bool& has_eval_indices(void) const; - const std::vector& eval_indices(void) const; + int size(void) const; + int scales(void) const; + bool has_par(const std::string& name) const; + bool has_scales(void) const; + const std::string& name(void) const; + void name(const std::string& name); + const double& ts(void) const; + void ts(const double& ts); + const bool& tscalc(void) const; + void tscalc(const bool& tscalc); + const bool& has_ts(void) const; + std::string instruments(void) const; + void instruments(const std::string& instruments); + GModelPar& scale(const int& index); + GModelPar scale(const std::string& instrument) const; + void scale(const GModelPar& par); + std::string ids(void) const; + void ids(const std::string& ids); + bool is_valid(const std::string& instruments, + const std::string& ids) const; + const GModelAssociations& associations(void) const; + void associations(const GModelAssociations& associations); + const bool& has_eval_indices(void) const; + const std::vector& eval_indices(void) const; }; diff --git a/src/model/GModel.cpp b/src/model/GModel.cpp index fe18134..8e4ce5d 100644 --- a/src/model/GModel.cpp +++ b/src/model/GModel.cpp @@ -621,6 +621,7 @@ void GModel::init_members(void) m_scales.clear(); m_ids.clear(); m_pars.clear(); + m_associations.clear(); m_ts = 0.0; m_has_ts = false; m_has_tscalc = false; @@ -646,6 +647,7 @@ void GModel::copy_members(const GModel& model) m_scales = model.m_scales; m_ids = model.m_ids; m_pars = model.m_pars; + m_associations = model.m_associations; m_ts = model.m_ts; m_has_ts = model.m_has_ts; m_has_tscalc = model.m_has_tscalc; @@ -699,6 +701,9 @@ void GModel::read_attributes(const GXmlElement& xml) // Read instrument scales read_scales(xml); + // Read model associations + m_associations.read(xml); + // Return return; } @@ -743,6 +748,9 @@ void GModel::write_attributes(GXmlElement& xml) const // Write instrument scales write_scales(xml); + // Write model associations + m_associations.write(xml); + // Return return; } @@ -799,6 +807,17 @@ std::string GModel::print_attributes(void) const result.append("all"); } + // Append associations + if (!m_associations.is_empty()) { + result.append("\n"+gammalib::parformat("Associations")); + for (int i = 0; i < m_associations.size(); ++i) { + if (i > 0) { + result.append(", "); + } + result.append(m_associations[i].name()); + } + } + // Return result return result; } diff --git a/test/data/crab_associations.xml b/test/data/crab_associations.xml new file mode 100644 index 0000000..4f70368 --- /dev/null +++ b/test/data/crab_associations.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/test_GModel.cpp b/test/test_GModel.cpp index 309cd24..8eb36ab 100644 --- a/test/test_GModel.cpp +++ b/test/test_GModel.cpp @@ -55,6 +55,7 @@ void TestGModel::set(void) m_temp_lightcurve = datadir + "/model_temporal_lightcurve.fits"; m_temp_phasecurve = datadir + "/model_temporal_phasecurve.fits"; m_xml_file = datadir + "/crab.xml"; + m_assoc_file = datadir + "/crab_associations.xml"; // Set model definiton XML files m_xml_model_point_const = datadir + "/model_point_const.xml"; @@ -788,6 +789,7 @@ void TestGModel::test_sky_model(void) GXml xml2(m_xml_file); GXmlElement* element2 = xml2.element(0)->element(0); GModelSky sky6(*element2); + test_value(sky6.associations().size(), 0, "Check absence of associations"); // Test has_par methods test_assert(sky6.spatial()->has_par("RA"), @@ -814,6 +816,14 @@ void TestGModel::test_sky_model(void) test_value(flux, flux_spectrum, "Test flux() method"); test_value(eflux, eflux_spectrum, "Test eflux() method"); + // Test associations + GXml xml3(m_assoc_file); + GXmlElement* element3 = xml3.element(0)->element(0); + GModelSky sky8(*element3); + test_value(sky8.associations().size(), 2, "Check presence of two associations"); + test_assert(sky8.associations().contains("Crab nebula"), "Check presence of \"Crab nebula\" association"); + test_assert(sky8.associations().contains("Crab pulsar"), "Check presence of \"Crab pulsar\" association"); + // Exit test return; } diff --git a/test/test_GModel.hpp b/test/test_GModel.hpp index 0de35b9..b7a29c6 100644 --- a/test/test_GModel.hpp +++ b/test/test_GModel.hpp @@ -116,6 +116,7 @@ private: std::string m_temp_lightcurve; std::string m_temp_phasecurve; std::string m_xml_file; + std::string m_assoc_file; // Model definiton XML files std::string m_xml_model_point_const;