diff --git a/ChangeLog b/ChangeLog index cf3ec76..6a33201 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,9 @@ -2016-07-18 Juergen Knoedlseder +2016-07-19 Juergen Knoedlseder * Version 1.1.0 released ========================= + Write same XML element names than those that were read (#1820) Rename spatial model components (#1818) Fix consistency problem in GCTABackground3D (#1815) Models accessing file now support relative file names (#1808) diff --git a/NEWS b/NEWS index ee2bf23..200d9bb 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ New Features and Important Changes in GammaLib 1.1.0 Author(s) : Juergen Knoedlseder -18 July 2016 +19 July 2016 1. Introduction @@ -233,6 +233,9 @@ By default the old model names are still supported. Support of the old model names can be turned off by specifying the --disable-legacy-model-names option to the ./configure script (#1818). +The model classes now write the same XML element names than those that were read +in. In that way a maximum legacy for the Fermi/LAT data format is assured (#1820). + 9. Numerics module ------------------ diff --git a/README.md b/README.md index 850ea7a..92841d5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ GammaLib information ==================== -* Version: 1.1.0.dev1 (18 July 2016) +* Version: 1.1.0.dev1 (19 July 2016) * Author: Juergen Knoedlseder (jurgen.knodlseder@irap.omp.eu) [![Build Status](https://cta-jenkins.irap.omp.eu/buildStatus/icon?job=gammalib-integrate-os)](https://cta-jenkins.irap.omp.eu/job/gammalib-integrate-os/) diff --git a/dev/testreport.py b/dev/testreport.py new file mode 100755 index 0000000..5fbd775 --- /dev/null +++ b/dev/testreport.py @@ -0,0 +1,224 @@ +#! /usr/bin/env python +# ========================================================================== +# Display test reports +# +# Copyright (C) 2016 Juergen Knoedlseder +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# ========================================================================== +import glob +import gammalib + + +# ====================== # +# Report test case error # +# ====================== # +def report_one_error(name, xml): + """ + Report test case error + + Parameters + ---------- + name : str + Test case name + xml : gammalib.GXmlElement + Error XML element + """ + # Extract information + message = xml.attribute('message') + type = xml.attribute('type') + + # Print error information + print(' Error in %s: %s (%s)' % (name, message, type)) + + # Return + return + + +# ======================== # +# Report test case failure # +# ======================== # +def report_one_failure(name, xml): + """ + Report test case failure + + Parameters + ---------- + name : str + Test case name + xml : gammalib.GXmlElement + Failure XML element + """ + # Extract information + message = xml.attribute('message') + type = xml.attribute('type') + + # Print failure information + print(' Failure in %s: %s (%s)' % (name, message, type)) + + # Return + return + + +# ======================= # +# Report test case result # +# ======================= # +def report_one_test_case(xml): + """ + Report test case result + + Parameters + ---------- + xml : gammalib.GXmlElement + Test case XML element + """ + # Extract test case information + name = xml.attribute('name') + errors = int(xml.elements('error')) + failures = int(xml.elements('failure')) + + # If there are errors then display them + if errors > 0: + num = int(xml.elements('error')) + for i in range(num): + error = xml.element('error[%d]' % i) + report_one_error(name, error) + + # If there are failures then display them + if failures > 0: + num = int(xml.elements('failure')) + for i in range(num): + failure = xml.element('failure[%d]' % i) + report_one_failure(name, failure) + + # Return + return + + +# ========================= # +# Report test suite results # +# ========================= # +def report_one_test_suite(xml): + """ + Report test suite result + + Parameters + ---------- + xml : gammalib.GXmlElement + Test suite XML element + """ + # Extract test suite information + name = xml.attribute('name') + errors = int(xml.attribute('errors')) + failures = int(xml.attribute('failures')) + + # If there are errors or failures then print them + if errors > 0 or failures > 0: + + # Print header + if errors == 0: + print('%d failures occured in module "%s":' % + (failures, name)) + elif failures == 0: + print('%d errors occured in module "%s":' % + (errors, name)) + else: + print('%d errors and %d failures occured in module "%s":' % + (errors, failures, name)) + + # Determine number of test cases + num = int(xml.elements('testcase')) + + # Loop over all test cases + for i in range(num): + + # Get test case + case = xml.element('testcase[%d]' % i) + + # Report test case result + report_one_test_case(case) + + # Return + return + + +# ====================== # +# Report one test result # +# ====================== # +def report_one_test_result(file): + """ + Report one test result + + Parameters + ---------- + file : str + Test result file + """ + # Open XML file + xml = gammalib.GXml(file) + + # Determine number of testsuites + num = int(xml.element('testsuites').elements('testsuite')) + + # Loop over all test suites + for i in range(num): + + # Get test suite + suite = xml.element('testsuites > testsuite[%d]' % i) + + # Report test suite result + report_one_test_suite(suite) + + # Return + return + + +# =================== # +# Report test results # +# =================== # +def report_test_results(path, pattern="*.xml"): + """ + Report test results + + Parameters + ---------- + path : str + Directory containing test results + pattern : str, optional + Test report pattern + """ + # Get list of test reports + reports = glob.glob(path+'/'+pattern) + + # Loop over all reports + for report in reports: + report_one_test_result(report) + + # Return + return + + +# ======================== # +# Main routine entry point # +# ======================== # +if __name__ == '__main__': + + # Print header + print('') + print('GammaLib test reports') + print('=====================') + + # Report test results + report_test_results('test/reports') diff --git a/inst/com/test/data/crab.xml b/inst/com/test/data/crab.xml index 9152bdf..e3518d7 100644 --- a/inst/com/test/data/crab.xml +++ b/inst/com/test/data/crab.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab.xml b/inst/cta/test/data/crab.xml index 8b136bf..b65f128 100644 --- a/inst/cta/test/data/crab.xml +++ b/inst/cta/test/data/crab.xml @@ -1,10 +1,10 @@ - + - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_disk.xml b/inst/cta/test/data/crab_disk.xml index bf2d270..9ca1d2b 100644 --- a/inst/cta/test/data/crab_disk.xml +++ b/inst/cta/test/data/crab_disk.xml @@ -2,9 +2,9 @@ - - - + + + @@ -14,9 +14,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_edisk.xml b/inst/cta/test/data/crab_edisk.xml index 6b796d8..45cc715 100644 --- a/inst/cta/test/data/crab_edisk.xml +++ b/inst/cta/test/data/crab_edisk.xml @@ -2,9 +2,9 @@ - - - + + + @@ -16,9 +16,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_eplaw.xml b/inst/cta/test/data/crab_eplaw.xml index 8576983..61c7f0f 100644 --- a/inst/cta/test/data/crab_eplaw.xml +++ b/inst/cta/test/data/crab_eplaw.xml @@ -2,10 +2,10 @@ - - - - + + + + @@ -14,9 +14,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_file_function.xml b/inst/cta/test/data/crab_file_function.xml index 3eaba1a..97fd25d 100644 --- a/inst/cta/test/data/crab_file_function.xml +++ b/inst/cta/test/data/crab_file_function.xml @@ -11,9 +11,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_file_function_mod.xml b/inst/cta/test/data/crab_file_function_mod.xml index 0dba311..4ed5fa0 100644 --- a/inst/cta/test/data/crab_file_function_mod.xml +++ b/inst/cta/test/data/crab_file_function_mod.xml @@ -11,9 +11,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_gauss.xml b/inst/cta/test/data/crab_gauss.xml index 446327e..25ca0cd 100644 --- a/inst/cta/test/data/crab_gauss.xml +++ b/inst/cta/test/data/crab_gauss.xml @@ -2,9 +2,9 @@ - - - + + + @@ -14,9 +14,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_irf.xml b/inst/cta/test/data/crab_irf.xml index 238cbaa..6d5e049 100644 --- a/inst/cta/test/data/crab_irf.xml +++ b/inst/cta/test/data/crab_irf.xml @@ -2,9 +2,9 @@ - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_poly.xml b/inst/cta/test/data/crab_poly.xml index 6d1b1f8..faee3c5 100644 --- a/inst/cta/test/data/crab_poly.xml +++ b/inst/cta/test/data/crab_poly.xml @@ -2,9 +2,9 @@ - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_profile.xml b/inst/cta/test/data/crab_profile.xml index 1ffa630..2506b47 100644 --- a/inst/cta/test/data/crab_profile.xml +++ b/inst/cta/test/data/crab_profile.xml @@ -2,9 +2,9 @@ - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_ptsrc.xml b/inst/cta/test/data/crab_ptsrc.xml index 066242c..e34d283 100644 --- a/inst/cta/test/data/crab_ptsrc.xml +++ b/inst/cta/test/data/crab_ptsrc.xml @@ -2,9 +2,9 @@ - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/cta/test/data/crab_shell.xml b/inst/cta/test/data/crab_shell.xml index 83716d0..66525bb 100644 --- a/inst/cta/test/data/crab_shell.xml +++ b/inst/cta/test/data/crab_shell.xml @@ -2,9 +2,9 @@ - - - + + + @@ -15,9 +15,9 @@ - - - + + + diff --git a/inst/cta/test/data/cta_model_aeff_bgd.xml b/inst/cta/test/data/cta_model_aeff_bgd.xml index e151501..b12a0e2 100644 --- a/inst/cta/test/data/cta_model_aeff_bgd.xml +++ b/inst/cta/test/data/cta_model_aeff_bgd.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/inst/cta/test/data/cta_model_cube_bgd.xml b/inst/cta/test/data/cta_model_cube_bgd.xml index 513c7e5..0cf9544 100644 --- a/inst/cta/test/data/cta_model_cube_bgd.xml +++ b/inst/cta/test/data/cta_model_cube_bgd.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/inst/cta/test/data/cta_model_irf_bgd.xml b/inst/cta/test/data/cta_model_irf_bgd.xml index 6068fb6..f368c8c 100644 --- a/inst/cta/test/data/cta_model_irf_bgd.xml +++ b/inst/cta/test/data/cta_model_irf_bgd.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/inst/cta/test/data/onoff_model.xml b/inst/cta/test/data/onoff_model.xml index 38d32f9..2fc0a74 100644 --- a/inst/cta/test/data/onoff_model.xml +++ b/inst/cta/test/data/onoff_model.xml @@ -2,9 +2,9 @@ - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/cta/test/data/radio.xml b/inst/cta/test/data/radio.xml index 295412f..a4a6249 100644 --- a/inst/cta/test/data/radio.xml +++ b/inst/cta/test/data/radio.xml @@ -2,9 +2,9 @@ - - - + + + @@ -12,9 +12,9 @@ - - - + + + diff --git a/inst/cta/test/data/rsp_models.xml b/inst/cta/test/data/rsp_models.xml index af3db6c..c4148f8 100644 --- a/inst/cta/test/data/rsp_models.xml +++ b/inst/cta/test/data/rsp_models.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/inst/cta/test/data/stacked_model.xml b/inst/cta/test/data/stacked_model.xml index 2889676..626719b 100644 --- a/inst/cta/test/data/stacked_model.xml +++ b/inst/cta/test/data/stacked_model.xml @@ -2,9 +2,9 @@ - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/mwl/test/data/crab.xml b/inst/mwl/test/data/crab.xml index c0b57a7..3dbfe32 100644 --- a/inst/mwl/test/data/crab.xml +++ b/inst/mwl/test/data/crab.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/inst/mwl/test/data/crab_mwl.xml b/inst/mwl/test/data/crab_mwl.xml index 268750d..2df6215 100644 --- a/inst/mwl/test/data/crab_mwl.xml +++ b/inst/mwl/test/data/crab_mwl.xml @@ -2,9 +2,9 @@ - - - + + + @@ -13,9 +13,9 @@ - - - + + + diff --git a/inst/mwl/test/data/crab_mwl2.xml b/inst/mwl/test/data/crab_mwl2.xml index 95c3b71..7f38e2b 100644 --- a/inst/mwl/test/data/crab_mwl2.xml +++ b/inst/mwl/test/data/crab_mwl2.xml @@ -2,10 +2,10 @@ - - - - + + + + @@ -14,9 +14,9 @@ - - - + + + diff --git a/src/model/GModelPar.cpp b/src/model/GModelPar.cpp index 155d943..63674ba 100644 --- a/src/model/GModelPar.cpp +++ b/src/model/GModelPar.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelPar.cpp - Model parameter class * * ----------------------------------------------------------------------- * - * copyright (C) 2009-2013 by Juergen Knoedlseder * + * copyright (C) 2009-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -217,17 +217,28 @@ GModelPar* GModelPar::clone(void) const * * Each of the attributes are optional, with the following scheme for * assigning default values in case that the attribute was not found: - * - @p value sets @p m_factor_value (defaults to 0.0) - * - @p error sets @p m_factor_error (defaults to 0.0) - * - @p scale sets @p m_scale (defaults to 1.0) - * - @p min sets @p m_factor_min (will remove_min() if not found) - * - @p max sets @p m_factor_max (will remove_max() if not found) - * - @p free sets @p m_free (papameter will be fixed if not found) + * + * @p name sets @p m_name (defaults to "Unknown") + * @p value sets @p m_factor_value (defaults to 0.0) + * @p error sets @p m_factor_error (defaults to 0.0) + * @p scale sets @p m_scale (defaults to 1.0) + * @p min sets @p m_factor_min (will remove_min() if not found) + * @p max sets @p m_factor_max (will remove_max() if not found) + * @p free sets @p m_free (papameter will be fixed if not found) ***************************************************************************/ void GModelPar::read(const GXmlElement& xml) { + // Get name + std::string arg = xml.attribute("name"); + if (arg != "") { + m_name = arg; + } + else { + m_name = "Unknown"; + } + // Get value - std::string arg = xml.attribute("value"); + arg = xml.attribute("value"); if (arg != "") { m_factor_value = gammalib::todouble(arg); } @@ -330,15 +341,20 @@ void GModelPar::read(const GXmlElement& xml) * * * The following attributes will be set: - * - @p value - * - @p error (only in case that the parameter is free) - * - @p scale - * - @p min (only in case that a minimum exists) - * - @p max (only in case that a maximum exists) - * - @p free + * + * @p name + * @p value + * @p error (only in case that the parameter is free) + * @p scale + * @p min (only in case that a minimum exists) + * @p max (only in case that a maximum exists) + * @p free ***************************************************************************/ void GModelPar::write(GXmlElement& xml) const { + // Set name + xml.attribute("name", m_name); + // Set value xml.attribute("value", gammalib::str(m_factor_value)); diff --git a/src/model/GModelSpectralConst.cpp b/src/model/GModelSpectralConst.cpp index bc90e8e..9074300 100644 --- a/src/model/GModelSpectralConst.cpp +++ b/src/model/GModelSpectralConst.cpp @@ -466,57 +466,31 @@ void GModelSpectralConst::read(const GXmlElement& xml) * * @exception GException::model_invalid_spectral * Existing XML element is not of type "ConstantValue" - * @exception GException::model_invalid_parnum - * Invalid number of model parameters or nodes found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. * * Writes the spectral information into an XML element with the format * * - * + * * ***************************************************************************/ void GModelSpectralConst::write(GXmlElement& xml) const { // Set model type if (xml.attribute("type") == "") { - xml.attribute("type", "ConstantValue"); + xml.attribute("type", type()); } // Verify model type - if (xml.attribute("type") != "ConstantValue") { + if (xml.attribute("type") != type()) { throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \"ConstantValue\"."); - } - - // If XML element has 0 nodes then append parameter node. The name - // of the node is "Value" as this is the Fermi-LAT standard. - // We thus assure that the XML files will be compatible with - // Fermi-LAT. - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Value\"")); + "Spectral model is not of type \""+type()+"\"."); } - // Verify that XML element has exactly 1 parameter - if (xml.elements() != 1 || xml.elements("parameter") != 1) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Spectral constant requires exactly 1 parameter."); - } + // Get normalisation parameter + GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); - // Get parameter element - GXmlElement* par = xml.element("parameter", 0); - - // Set parameyter - if (par->attribute("name") == "Normalization" || - par->attribute("name") == "Value") { - m_norm.write(*par); - } - else { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Spectral constant requires either" - " \"Normalization\" or \"Value\" parameter."); - } + // Write normalisation parameter + m_norm.write(*par); // Return return; diff --git a/src/model/GModelSpectralExpPlaw.cpp b/src/model/GModelSpectralExpPlaw.cpp index 4e64e40..51620f8 100644 --- a/src/model/GModelSpectralExpPlaw.cpp +++ b/src/model/GModelSpectralExpPlaw.cpp @@ -575,10 +575,10 @@ GEnergy GModelSpectralExpPlaw::mc(const GEnergy& emin, * elements is * * - * - * - * - * + * + * + * + * * ***************************************************************************/ void GModelSpectralExpPlaw::read(const GXmlElement& xml) @@ -615,7 +615,8 @@ void GModelSpectralExpPlaw::read(const GXmlElement& xml) } // Handle pivot energy - else if (par->attribute("name") == "Scale") { + else if ((par->attribute("name") == "Scale") || + (par->attribute("name") == "PivotEnergy")) { m_pivot.read(*par); npar[3]++; } @@ -626,7 +627,7 @@ void GModelSpectralExpPlaw::read(const GXmlElement& xml) if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1) { throw GException::model_invalid_parnames(G_READ, xml, "Require \"Prefactor\", \"Index\", \"Cutoff\" and \"Scale\"" - " parameters."); + " or \"PivotEnergy\" parameters."); } // Return @@ -650,78 +651,36 @@ void GModelSpectralExpPlaw::read(const GXmlElement& xml) * element is * * - * - * - * - * + * + * + * + * * ***************************************************************************/ void GModelSpectralExpPlaw::write(GXmlElement& xml) const { // Set model type if (xml.attribute("type") == "") { - xml.attribute("type", "ExpCutoff"); + xml.attribute("type", type()); } // Verify model type - if (xml.attribute("type") != "ExpCutoff") { + if (xml.attribute("type") != type()) { throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \"ExpCutoff\"."); + "Spectral model is not of type \""+type()+"\"."); } - // If XML element has 0 nodes then append 4 parameter nodes - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Prefactor\"")); - xml.append(GXmlElement("parameter name=\"Index\"")); - xml.append(GXmlElement("parameter name=\"Cutoff\"")); - xml.append(GXmlElement("parameter name=\"Scale\"")); - } - - // Verify that XML element has exactly 4 parameters - if (xml.elements() != 4 || xml.elements("parameter") != 4) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Power law model requires exactly 4 parameters."); - } - - // Set or update model parameter attributes - int npar[] = {0, 0, 0, 0}; - for (int i = 0; i < 4; ++i) { - - // Get parameter element - GXmlElement* par = xml.element("parameter", i); - - // Handle prefactor - if (par->attribute("name") == "Prefactor") { - npar[0]++; - m_norm.write(*par); - } - - // Handle index - else if (par->attribute("name") == "Index") { - npar[1]++; - m_index.write(*par); - } - - // Handle index - else if (par->attribute("name") == "Cutoff") { - npar[2]++; - m_ecut.write(*par); - } - - // Handle pivot energy - else if (par->attribute("name") == "Scale") { - m_pivot.write(*par); - npar[3]++; - } - - } // endfor: looped over all parameters - - // Check of all required parameters are present - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1) { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Require \"Prefactor\", \"Index\", \"Cutoff\" and \"Scale\"" - " parameters."); - } + // Get XML parameters + GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); + GXmlElement* index = gammalib::xml_need_par(G_WRITE, xml, m_index.name()); + GXmlElement* ecut = gammalib::xml_need_par(G_WRITE, xml, m_ecut.name()); + GXmlElement* pivot = gammalib::xml_need_par(G_WRITE, xml, m_pivot.name()); + + // Write parameters + m_norm.write(*norm); + m_index.write(*index); + m_ecut.write(*ecut); + m_pivot.write(*pivot); // Return return; diff --git a/src/model/GModelSpectralLogParabola.cpp b/src/model/GModelSpectralLogParabola.cpp index a4df0d4..834e230 100644 --- a/src/model/GModelSpectralLogParabola.cpp +++ b/src/model/GModelSpectralLogParabola.cpp @@ -650,8 +650,9 @@ void GModelSpectralLogParabola::read(const GXmlElement& xml) } // Handle pivot energy - else if (par->attribute("name") == "Scale" || - par->attribute("name") == "Eb") { + else if ((par->attribute("name") == "Scale") || + (par->attribute("name") == "Eb") || + (par->attribute("name") == "PivotEnergy")) { m_pivot.read(*par); npar[3]++; } @@ -663,7 +664,7 @@ void GModelSpectralLogParabola::read(const GXmlElement& xml) throw GException::model_invalid_parnames(G_READ, xml, "LogParabola requires \"Prefactor\" or \"norm\"," " \"Index\" or \"alpha\", \"Curvature\" or \"beta\"" - " and \"Scale\" or \"Eb\" parameters."); + " and \"Scale\", \"Eb\" or \"PivotEnergy\" parameters."); } // Return @@ -687,10 +688,10 @@ void GModelSpectralLogParabola::read(const GXmlElement& xml) * of the XML elements is * * - * - * - * - * + * + * + * + * * ***************************************************************************/ void GModelSpectralLogParabola::write(GXmlElement& xml) const @@ -706,59 +707,17 @@ void GModelSpectralLogParabola::write(GXmlElement& xml) const "Spectral model is not of type \""+type()+"\"."); } - // If XML element has 0 nodes then append 4 parameter nodes - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Prefactor\"")); - xml.append(GXmlElement("parameter name=\"Index\"")); - xml.append(GXmlElement("parameter name=\"Curvature\"")); - xml.append(GXmlElement("parameter name=\"Scale\"")); - } - - // Verify that XML element has exactly 4 parameters - if (xml.elements() != 4 || xml.elements("parameter") != 4) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "LogParabola law model requires exactly 4 parameters."); - } - - // Set or update model parameter attributes - int npar[] = {0, 0, 0,0}; - for (int i = 0; i < 4; ++i) { - - // Get parameter element - GXmlElement* par = xml.element("parameter", i); - - // Handle prefactor - if (par->attribute("name") == "Prefactor"){ - npar[0]++; - m_norm.write(*par); - } - - // Handle index - else if (par->attribute("name") == "Index") { - npar[1]++; - m_index.write(*par); - } - - // Handle index - else if (par->attribute("name") == "Curvature"){ - npar[2]++; - m_curvature.write(*par); - } - - // Handle pivot energy - else if (par->attribute("name") == "Scale") { - m_pivot.write(*par); - npar[3]++; - } - - } // endfor: looped over all parameters - - // Check of all required parameters are present - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1) { - throw GException::model_invalid_parnames(G_WRITE, xml, - "LogParabola requires \"Prefactor\", \"Index\", \"Curvature\"" - " and \"Scale\" parameters."); - } + // Get XML parameters + GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); + GXmlElement* index = gammalib::xml_need_par(G_WRITE, xml, m_index.name()); + GXmlElement* curvature = gammalib::xml_need_par(G_WRITE, xml, m_curvature.name()); + GXmlElement* pivot = gammalib::xml_need_par(G_WRITE, xml, m_pivot.name()); + + // Write parameters + m_norm.write(*norm); + m_index.write(*index); + m_curvature.write(*curvature); + m_pivot.write(*pivot); // Return return; diff --git a/src/model/GModelSpectralNodes.cpp b/src/model/GModelSpectralNodes.cpp index d49d9de..ac216a4 100644 --- a/src/model/GModelSpectralNodes.cpp +++ b/src/model/GModelSpectralNodes.cpp @@ -614,13 +614,13 @@ GEnergy GModelSpectralNodes::mc(const GEnergy& emin, * * * - * - * + * + * * * ... * - * - * + * + * * * * @@ -727,21 +727,19 @@ void GModelSpectralNodes::read(const GXmlElement& xml) * Existing XML element is not of required type * @exception GException::model_invalid_parnum * Invalid number of model parameters or nodes found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. * * Writes the spectral information into an XML element. The format of the XML * element is * * * - * - * + * + * * * ... * - * - * + * + * * * ***************************************************************************/ @@ -781,45 +779,23 @@ void GModelSpectralNodes::write(GXmlElement& xml) const // Get node GXmlElement* node = xml.element("node", i); - // If XML element has 0 leafes then append energy and intensity - // element - if (node->elements() == 0) { - node->append(GXmlElement("parameter name=\"Energy\"")); - node->append(GXmlElement("parameter name=\"Intensity\"")); - } - - // Verify that node XML element has exactly 2 parameters - if (node->elements() != 2 || node->elements("parameter") != 2) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Node requires exactly 2 parameters."); - } + // Get copy of parameters so that we can change their names + GModelPar energy = m_energies[i]; + GModelPar intensity = m_values[i]; - // Set or update model parameter attributes - int npar[] = {0, 0}; - for (int k = 0; k < 2; ++k) { + // Set names since we appended for internal usage the indices to the + // parameter names, and we want to get rid of them for writing the + // model into the XML element + energy.name("Energy"); + intensity.name("Intensity"); - // Get parameter element - GXmlElement* par = node->element("parameter", k); + // Get XML parameters + GXmlElement* eng = gammalib::xml_need_par(G_WRITE, *node, energy.name()); + GXmlElement* val = gammalib::xml_need_par(G_WRITE, *node, intensity.name()); - // Handle prefactor - if (par->attribute("name") == "Energy") { - npar[0]++; - m_energies[i].write(*par); - } - - // Handle index - else if (par->attribute("name") == "Intensity") { - npar[1]++; - m_values[i].write(*par); - } - - } // endfor: looped over parameters - - // Check of all required parameters are present - if (npar[0] != 1 || npar[1] != 1) { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Require \"Energy\" and \"Intensity\" parameters."); - } + // Write parameters + energy.write(*eng); + intensity.write(*val); } // endfor: looped over nodes diff --git a/src/model/GModelSpectralPlaw.cpp b/src/model/GModelSpectralPlaw.cpp index 35cd67d..c535923 100644 --- a/src/model/GModelSpectralPlaw.cpp +++ b/src/model/GModelSpectralPlaw.cpp @@ -524,9 +524,9 @@ GEnergy GModelSpectralPlaw::mc(const GEnergy& emin, * elements is * * - * - * - * + * + * + * * * * @todo Add parameter validity check @@ -559,7 +559,8 @@ void GModelSpectralPlaw::read(const GXmlElement& xml) } // Handle pivot energy - else if (par->attribute("name") == "Scale") { + else if ((par->attribute("name") == "Scale") || + (par->attribute("name") == "PivotEnergy")) { m_pivot.read(*par); npar[2]++; } @@ -569,7 +570,8 @@ void GModelSpectralPlaw::read(const GXmlElement& xml) // Verify that all parameters were found if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1) { throw GException::model_invalid_parnames(G_READ, xml, - "Require \"Prefactor\", \"Index\" and \"Scale\" parameters."); + "Require \"Prefactor\", \"Index\" and \"Scale\" or " + "\"PivotEnergy\" parameters."); } // Return @@ -584,78 +586,38 @@ void GModelSpectralPlaw::read(const GXmlElement& xml) * * @exception GException::model_invalid_spectral * Existing XML element is not of type "PowerLaw" - * @exception GException::model_invalid_parnum - * Invalid number of model parameters or nodes found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. * * Writes the spectral information into an XML element. The format of the XML * element is * * - * - * - * + * + * + * * ***************************************************************************/ void GModelSpectralPlaw::write(GXmlElement& xml) const { // Set model type if (xml.attribute("type") == "") { - xml.attribute("type", "PowerLaw"); + xml.attribute("type", type()); } // Verify model type - if (xml.attribute("type") != "PowerLaw") { + if (xml.attribute("type") != type()) { throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \"PowerLaw\"."); - } - - // If XML element has 0 nodes then append 3 parameter nodes - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Prefactor\"")); - xml.append(GXmlElement("parameter name=\"Index\"")); - xml.append(GXmlElement("parameter name=\"Scale\"")); - } - - // Verify that XML element has exactly 3 parameters - if (xml.elements() != 3 || xml.elements("parameter") != 3) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Power law model requires exactly 3 parameters."); + "Spectral model is not of type \""+type()+"\"."); } - // Set or update model parameter attributes - int npar[] = {0, 0, 0}; - for (int i = 0; i < 3; ++i) { - - // Get parameter element - GXmlElement* par = xml.element("parameter", i); - - // Handle prefactor - if (par->attribute("name") == "Prefactor") { - npar[0]++; - m_norm.write(*par); - } - - // Handle index - else if (par->attribute("name") == "Index") { - npar[1]++; - m_index.write(*par); - } - - // Handle pivot energy - else if (par->attribute("name") == "Scale") { - m_pivot.write(*par); - npar[2]++; - } - - } // endfor: looped over all parameters + // Get XML parameters + GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); + GXmlElement* index = gammalib::xml_need_par(G_WRITE, xml, m_index.name()); + GXmlElement* pivot = gammalib::xml_need_par(G_WRITE, xml, m_pivot.name()); - // Check of all required parameters are present - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1) { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Require \"Prefactor\", \"Index\" and \"Scale\" parameters."); - } + // Write parameters + m_norm.write(*norm); + m_index.write(*index); + m_pivot.write(*pivot); // Return return; diff --git a/src/model/GModelSpectralSuperExpPlaw.cpp b/src/model/GModelSpectralSuperExpPlaw.cpp index 8ffb037..7361ed8 100644 --- a/src/model/GModelSpectralSuperExpPlaw.cpp +++ b/src/model/GModelSpectralSuperExpPlaw.cpp @@ -599,11 +599,11 @@ GEnergy GModelSpectralSuperExpPlaw::mc(const GEnergy& emin, * elements is * * - * - * - * - * - * + * + * + * + * + * * ***************************************************************************/ void GModelSpectralSuperExpPlaw::read(const GXmlElement& xml) @@ -640,7 +640,8 @@ void GModelSpectralSuperExpPlaw::read(const GXmlElement& xml) } // Handle pivot energy - else if (par->attribute("name") == "Scale") { + else if ((par->attribute("name") == "Scale") || + (par->attribute("name") == "PivotEnergy")) { m_pivot.read(*par); npar[3]++; } @@ -656,8 +657,8 @@ void GModelSpectralSuperExpPlaw::read(const GXmlElement& xml) // Verify that all parameters were found if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1 || npar[4] != 1) { throw GException::model_invalid_parnames(G_READ, xml, - "Require \"Prefactor\", \"Index1\", \"Cutoff\", \"Scale\" and \"Index2\"" - " parameters."); + "Require \"Prefactor\", \"Index1\", \"Cutoff\", \"Scale\" or " + "\"PivotEnergy\" and \"Index2\" parameters."); } // Return @@ -672,95 +673,44 @@ void GModelSpectralSuperExpPlaw::read(const GXmlElement& xml) * * @exception GException::model_invalid_spectral * Existing XML element is not of type "ExpCutoff" - * @exception GException::model_invalid_parnum - * Invalid number of model parameters or nodes found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. * * Writes the spectral information into an XML element. The format of the XML * element is * * - * - * - * - * - * + * + * + * + * + * * ***************************************************************************/ void GModelSpectralSuperExpPlaw::write(GXmlElement& xml) const { // Set model type if (xml.attribute("type") == "") { - xml.attribute("type", "PLSuperExpCutoff"); + xml.attribute("type", type()); } // Verify model type - if (xml.attribute("type") != "PLSuperExpCutoff") { + if (xml.attribute("type") != type()) { throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \"PLSuperExpCutoff\"."); + "Spectral model is not of type \""+type()+"\"."); } - // If XML element has 0 nodes then append 5 parameter nodes - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Prefactor\"")); - xml.append(GXmlElement("parameter name=\"Index1\"")); - xml.append(GXmlElement("parameter name=\"Cutoff\"")); - xml.append(GXmlElement("parameter name=\"Scale\"")); - xml.append(GXmlElement("parameter name=\"Index2\"")); - } - - // Verify that XML element has exactly 5 parameters - if (xml.elements() != 5 || xml.elements("parameter") != 5) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Super Exponetial Power law model requires exactly 5 parameters."); - } - - // Set or update model parameter attributes - int npar[] = {0, 0, 0, 0, 0}; - for (int i = 0; i < 5; ++i) { - - // Get parameter element - GXmlElement* par = xml.element("parameter", i); - - // Handle prefactor - if (par->attribute("name") == "Prefactor") { - npar[0]++; - m_norm.write(*par); - } - - // Handle index1 - else if (par->attribute("name") == "Index1") { - npar[1]++; - m_index1.write(*par); - } - - // Handle index - else if (par->attribute("name") == "Cutoff") { - npar[2]++; - m_ecut.write(*par); - } - - // Handle pivot energy - else if (par->attribute("name") == "Scale") { - m_pivot.write(*par); - npar[3]++; - } - - // Handle index2 - else if (par->attribute("name") == "Index2") { - npar[4]++; - m_index2.write(*par); - } - - } // endfor: looped over all parameters - - // Check of all required parameters are present - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1 || npar[4] != 1) { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Require \"Prefactor\", \"Index1\", \"Cutoff\", \"Scale\" and \"Index2\"" - " parameters."); - } + // Get XML parameters + GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); + GXmlElement* index1 = gammalib::xml_need_par(G_WRITE, xml, m_index1.name()); + GXmlElement* ecut = gammalib::xml_need_par(G_WRITE, xml, m_ecut.name()); + GXmlElement* index2 = gammalib::xml_need_par(G_WRITE, xml, m_index2.name()); + GXmlElement* pivot = gammalib::xml_need_par(G_WRITE, xml, m_pivot.name()); + + // Write parameters + m_norm.write(*norm); + m_index1.write(*index1); + m_ecut.write(*ecut); + m_index2.write(*index2); + m_pivot.write(*pivot); // Return return; diff --git a/test/data/crab.xml b/test/data/crab.xml index 30d79d6..d446737 100644 --- a/test/data/crab.xml +++ b/test/data/crab.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_diffuse_const.xml b/test/data/model_diffuse_const.xml index e610701..c4bd3f4 100644 --- a/test/data/model_diffuse_const.xml +++ b/test/data/model_diffuse_const.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_diffuse_map.xml b/test/data/model_diffuse_map.xml index af3db6c..c4148f8 100644 --- a/test/data/model_diffuse_map.xml +++ b/test/data/model_diffuse_map.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_elliptical_disk.xml b/test/data/model_elliptical_disk.xml index 7fc6b92..b42ff04 100644 --- a/test/data/model_elliptical_disk.xml +++ b/test/data/model_elliptical_disk.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_elliptical_gauss.xml b/test/data/model_elliptical_gauss.xml index 54ecb44..cd48ba6 100644 --- a/test/data/model_elliptical_gauss.xml +++ b/test/data/model_elliptical_gauss.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_point_eplaw.xml b/test/data/model_point_eplaw.xml index a087ed1..5642071 100644 --- a/test/data/model_point_eplaw.xml +++ b/test/data/model_point_eplaw.xml @@ -2,10 +2,10 @@ - - - - + + + + diff --git a/test/data/model_point_logparabola.xml b/test/data/model_point_logparabola.xml index 3ffb995..0a01e16 100644 --- a/test/data/model_point_logparabola.xml +++ b/test/data/model_point_logparabola.xml @@ -2,10 +2,10 @@ - - - - + + + + diff --git a/test/data/model_point_plaw.xml b/test/data/model_point_plaw.xml index 64e227d..df72ed5 100644 --- a/test/data/model_point_plaw.xml +++ b/test/data/model_point_plaw.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_point_supeplaw.xml b/test/data/model_point_supeplaw.xml index 4fc6d3e..d7a1fbd 100644 --- a/test/data/model_point_supeplaw.xml +++ b/test/data/model_point_supeplaw.xml @@ -2,11 +2,11 @@ - - - - - + + + + + diff --git a/test/data/model_radial_disk.xml b/test/data/model_radial_disk.xml index 7b622bb..1ac033a 100644 --- a/test/data/model_radial_disk.xml +++ b/test/data/model_radial_disk.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_radial_gauss.xml b/test/data/model_radial_gauss.xml index 1c6d39d..9dbac30 100644 --- a/test/data/model_radial_gauss.xml +++ b/test/data/model_radial_gauss.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/model_radial_shell.xml b/test/data/model_radial_shell.xml index 00b7a6c..9599057 100644 --- a/test/data/model_radial_shell.xml +++ b/test/data/model_radial_shell.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/test/data/test.xml b/test/data/test.xml index 627d842..5359b20 100644 --- a/test/data/test.xml +++ b/test/data/test.xml @@ -6,7 +6,7 @@ - + diff --git a/test/test_GModel.cpp b/test/test_GModel.cpp index 22d7354..c9bb2d9 100644 --- a/test/test_GModel.cpp +++ b/test/test_GModel.cpp @@ -1392,7 +1392,7 @@ void TestGModel::test_const(void) test_value(model.value(), 3.9e-16); // Test operator access - const char* strarray[] = {"Value"}; + const char* strarray[] = {"Normalization"}; for (int i = 0; i < 1; ++i) { std::string keyname(strarray[i]); model[keyname].remove_range(); // To allow setting of any value diff --git a/test/test_GXml.cpp b/test/test_GXml.cpp index 5cad29e..b99fdde 100644 --- a/test/test_GXml.cpp +++ b/test/test_GXml.cpp @@ -274,55 +274,39 @@ void TestGXml::test_GXml_access(void) // Test root document access GXml xml; xml.load(m_xml_file); - test_assert(xml.size() == 3, - "Test if xml.children()==3", - "Unexpected number of children in document "+ - gammalib::str(xml.size())); + test_value(xml.size(), 3, "Check number of child elements"); // Test node access for (int i = 0; i < xml.size(); ++i) { GXmlNode* ptr = xml[i]; - test_assert(ptr != 0, "Test node access"); + test_assert(ptr != 0, "Check XML node access"); } - test_assert(xml.elements() == 1, - "Test if xml.elements()==1", - "Unexpected number of child elements in document "+ - gammalib::str(xml.elements())); + test_value(xml.elements(), 1, "Check number of child elements"); // Test node access for (int i = 0; i < xml.elements(); ++i) { GXmlNode* ptr = xml.element(i); - test_assert(ptr != 0, "Test xml element access"); + test_assert(ptr != 0, "Check XML element access"); } - test_assert(xml.elements("source_library") == 1, - "Test if the source_library = 1", - "Unexpected number of child elements in document "+ - gammalib::str(xml.elements("source_library"))); + test_value(xml.elements("source_library"), 1, "Check number of child elements"); // Test element access for (int i = 0; i < xml.elements("source_library"); ++i) { GXmlElement* ptr = xml.element("source_library", i); - test_assert(ptr->name() == "source_library", - "Test name", - "Unexpected element name "+ptr->name()); + test_value(ptr->name(), "source_library", "Check element name"); } // Test hierarchy access GXmlElement* ptr = NULL; ptr = xml.element("source_library"); - test_assert(ptr->name() == "source_library", "Test hierarchy access", - "Unexpected element name "+ptr->name()); + test_value(ptr->name(), "source_library", "Check hierarchy level 1"); ptr = xml.element("source_library > source"); - test_assert(ptr->name() == "source", "Test hierarchy access", - "Unexpected element name "+ptr->name()); + test_value(ptr->name(), "source", "Check hierarchy level 2"); ptr = xml.element("source_library > source > spectrum"); - test_assert(ptr->name() == "spectrum", "Test hierarchy access", - "Unexpected element name "+ptr->name()); + test_value(ptr->name(), "spectrum", "Check hierarchy level 3"); ptr = xml.element("source_library > source > spectrum > parameter[2]"); - test_assert(ptr->name() == "parameter", "Test hierarchy access", - "Unexpected element name "+ptr->name()); - test_assert(ptr->attribute("name") == "Scale", "Test hierarchy access", - "Unexpected element attribute "+ptr->attribute("name")); + test_value(ptr->name(), "parameter", "Check hierarchy level 4"); + test_value(ptr->attribute("name"), "PivotEnergy", "Check for attribute"); // Return return;