diff --git a/include/GException.hpp b/include/GException.hpp index 04e7202..72abe7e 100644 --- a/include/GException.hpp +++ b/include/GException.hpp @@ -135,140 +135,10 @@ public: const std::string& message = ""); }; - // --- OLD EXCEPTIONS --- - - - - - // Invalid type conversion - class bad_type : public GExceptionHandler { - public: - bad_type(std::string origin, - std::string message = ""); - }; - - // Environment variable not found - class env_not_found : public GExceptionHandler { - public: - env_not_found(std::string origin, - std::string envname, - std::string message = ""); - }; - - // Memory allocation exception class - class mem_alloc : public GExceptionHandler { - public: - mem_alloc(std::string origin, unsigned num); - }; - - // Not enough nodes - class not_enough_nodes : public GExceptionHandler { - public: - not_enough_nodes(std::string origin, int num); - }; - - // File not found - class file_not_found : public GExceptionHandler { - public: - file_not_found(std::string origin, - std::string filename, - std::string message = ""); - }; - - // File open error - class file_open_error : public GExceptionHandler { - public: - file_open_error(std::string origin, - std::string filename, - std::string message = ""); - }; - - // Directory not found - class directory_not_found : public GExceptionHandler { - public: - directory_not_found(std::string origin, - std::string dirname, - std::string message = ""); - }; - - // Directory not accessible - class directory_not_accessible : public GExceptionHandler { - public: - directory_not_accessible(std::string origin, - std::string dirname, - std::string message = ""); - }; - - // Empty object exception class - /* - class empty : public GExceptionHandler { - public: - empty(std::string origin); - }; - - // Vector - Vector mismatch - class vector_mismatch : public GExceptionHandler { - public: - vector_mismatch(std::string origin, int size1, int size2); - }; - - // Cross product only defined for 3-element vectors - class vector_bad_cross_dim : public GExceptionHandler { - public: - vector_bad_cross_dim(std::string origin, int elements); - }; - - // Vector - Matrix mismatch - class matrix_vector_mismatch : public GExceptionHandler { - public: - matrix_vector_mismatch(std::string origin, int num, int rows, int cols); - }; - - // Matrix dimensions mismatch - class matrix_mismatch : public GExceptionHandler { - public: - matrix_mismatch(std::string origin, int rows1, int cols1, int rows2, - int cols2); - }; - - // Matrix not square - class matrix_not_square : public GExceptionHandler { - public: - matrix_not_square(std::string origin, int rows, int cols); - }; - - // Matrix not positive definite - class matrix_not_pos_definite : public GExceptionHandler { - public: - matrix_not_pos_definite(std::string origin, int row, double sum); - }; - // Matrix not symmetric - class matrix_not_symmetric : public GExceptionHandler { - public: - matrix_not_symmetric(std::string origin, int cols, int rows); - }; - // Matrix not factorised - class matrix_not_factorised : public GExceptionHandler { - public: - matrix_not_factorised(std::string origin, std::string type); - }; - - // All matrix elements are zero - class matrix_zero : public GExceptionHandler { - public: - matrix_zero(std::string origin); - }; - - // Invalid ordering scheme - class invalid_order : public GExceptionHandler { - public: - invalid_order(std::string origin, int order, int min_order, - int max_order); - }; - */ + // --- OLD EXCEPTIONS --- // GSkyMap exceptions class skymap : public GExceptionHandler { @@ -439,96 +309,6 @@ public: std::string message = ""); }; - - // Model exceptions - class model_invalid : public GExceptionHandler { - public: - model_invalid(std::string origin, std::string type, - std::string message = ""); - }; - class model_invalid_spatial : public GExceptionHandler { - public: - model_invalid_spatial(std::string origin, std::string type, - std::string message = ""); - }; - class model_invalid_spectral : public GExceptionHandler { - public: - model_invalid_spectral(std::string origin, std::string type, - std::string message = ""); - }; - class model_invalid_temporal : public GExceptionHandler { - public: - model_invalid_temporal(std::string origin, std::string type, - std::string message = ""); - }; - class model_invalid_parnum : public GExceptionHandler { - public: - model_invalid_parnum(std::string origin, GXmlElement xml, - std::string message = ""); - }; - class model_invalid_nodenum : public GExceptionHandler { - public: - model_invalid_nodenum(std::string origin, GXmlElement xml, - std::string message = ""); - }; - class model_invalid_parnames : public GExceptionHandler { - public: - model_invalid_parnames(std::string origin, GXmlElement xml, - std::string message = ""); - }; - class model_invalid_parvalue : public GExceptionHandler { - public: - model_invalid_parvalue(std::string origin, GXmlElement xml, - std::string message = ""); - }; - class model_invalid_parlimit : public GExceptionHandler { - public: - model_invalid_parlimit(std::string origin, GXmlElement xml, - std::string message = ""); - }; - class model_invalid_parscale : public GExceptionHandler { - public: - model_invalid_parscale(std::string origin, double scale, - std::string message = ""); - model_invalid_parscale(std::string origin, GXmlElement xml, - std::string message = ""); - }; - class file_function_data : public GExceptionHandler { - public: - file_function_data(std::string origin, std::string filename, - int num, std::string message = ""); - }; - class file_function_columns : public GExceptionHandler { - public: - file_function_columns(std::string origin, std::string filename, - int num, std::string message = ""); - }; - class file_function_value : public GExceptionHandler { - public: - file_function_value(std::string origin, std::string filename, - double value, std::string message = ""); - }; - class par_not_found : public GExceptionHandler { - public: - par_not_found(std::string origin, std::string name, - std::string message = ""); - }; - class model_not_found : public GExceptionHandler { - public: - model_not_found(std::string origin, std::string name, - std::string message = ""); - }; - class no_point_source : public GExceptionHandler { - public: - no_point_source(std::string origin, std::string name, - std::string message = ""); - }; - class no_extended_source : public GExceptionHandler { - public: - no_extended_source(std::string origin, std::string name, - std::string message = ""); - }; - // CSV exceptions class csv_bad_columns : public GExceptionHandler { public: diff --git a/include/GTools.hpp b/include/GTools.hpp index 9ae4392..3db6a8c 100644 --- a/include/GTools.hpp +++ b/include/GTools.hpp @@ -133,6 +133,12 @@ namespace gammalib { const GXmlElement& xml, const std::string& name, const std::string& attribute); + void xml_check_parnum(const std::string& origin, + const GXmlElement& xml, + const int& number); + void xml_check_type(const std::string& origin, + GXmlElement& xml, + const std::string& type); void xml_check_par(const std::string& origin, const std::string& name, const int& number); diff --git a/inst/cta/src/GCTABackgroundPerfTable.cpp b/inst/cta/src/GCTABackgroundPerfTable.cpp index 6dfd137..9bf7ea5 100644 --- a/inst/cta/src/GCTABackgroundPerfTable.cpp +++ b/inst/cta/src/GCTABackgroundPerfTable.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCTABackgroundPerfTable.cpp - CTA performance table background class * * ----------------------------------------------------------------------- * - * copyright (C) 2014-2018 by Juergen Knoedlseder * + * copyright (C) 2014-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -258,7 +258,10 @@ void GCTABackgroundPerfTable::load(const GFilename& filename) // Open performance table readonly FILE* fptr = std::fopen(filename.url().c_str(), "r"); if (fptr == NULL) { - throw GException::file_open_error(G_LOAD, filename.url()); + std::string msg = "Unable to open file \""+filename.url()+"\" for " + "read access. Please provide the name of a readable " + "file."; + throw GException::file_error(G_LOAD, msg); } // Read lines diff --git a/inst/cta/src/GCTAModelRadialGauss.cpp b/inst/cta/src/GCTAModelRadialGauss.cpp index 851152b..3d8f860 100644 --- a/inst/cta/src/GCTAModelRadialGauss.cpp +++ b/inst/cta/src/GCTAModelRadialGauss.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCTAModelRadialGauss.cpp - Radial Gaussian CTA model class * * ----------------------------------------------------------------------- * - * copyright (C) 2011-2018 by Juergen Knoedlseder * + * copyright (C) 2011-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -405,60 +405,23 @@ double GCTAModelRadialGauss::omega(void) const * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parvalue - * Non-positive parameter value found. - * @exception GException::model_invalid_parlimit - * Missing or non-positive minimum parameter boundary. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. + * Read the Gaussian radial model information from an XML element in the + * following format * - * Read the Gaussian radial model information from an XML element. The XML - * element is required to have one parameter named "Sigma". + * + * + * ***************************************************************************/ void GCTAModelRadialGauss::read(const GXmlElement& xml) { // Verify that XML element has exactly 1 parameter - if (xml.elements() != 1 || xml.elements("parameter") != 1) { - throw GException::model_invalid_parnum(G_READ, xml, - "Radial Gaussian model requires exactly 1 parameter."); - } + gammalib::xml_check_parnum(G_READ, xml, 1); - // Extract model parameters - int npar[] = {0}; - for (int i = 0; i < 1; ++i) { - - // Get parameter element - const GXmlElement* par = xml.element("parameter", i); - - // Handle Sigma - if (par->attribute("name") == "Sigma") { - - // Read parameter - m_sigma.read(*par); - - // Check parameter - if (m_sigma.value() <= 0.0) { - throw GException::model_invalid_parvalue(G_READ, xml, - "\"Sigma\" parameter is required to be positive."); - } - if (!m_sigma.has_min() || m_sigma.min() <= 0.0) { - throw GException::model_invalid_parlimit(G_READ, xml, - "\"Sigma\" parameter requires positive minimum boundary."); - } - - // Increment parameter counter - npar[0]++; - } + // Get parameters + const GXmlElement* sigma = gammalib::xml_get_par(G_READ, xml, m_sigma.name()); - } // endfor: looped over all parameters - - // Verify that all parameters were found - if (npar[0] != 1) { - throw GException::model_invalid_parnames(G_READ, xml, - "Radial Gaussian model requires \"Sigma\" parameter."); - } + // Read parameters + m_sigma.read(*sigma); // Return return; @@ -470,60 +433,23 @@ void GCTAModelRadialGauss::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type 'GaussFunction' - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. + * Write the Gaussian radial model information into an XML element in the + * following format * - * Write the Gaussian radial model information into an XML element. The XML - * element will have one parameter leaf named "Sigma". + * + * + * ***************************************************************************/ void GCTAModelRadialGauss::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } + // Check model type + gammalib::xml_check_type(G_WRITE, xml, type()); - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Radial Gaussian model is not of type \""+type()+"\"."); - } - - // If XML element has 0 nodes then append 1 parameter node - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Sigma\"")); - } + // Get or create parameter + GXmlElement* sigma = gammalib::xml_need_par(G_WRITE, xml, m_sigma.name()); - // Verify that XML element has exactly 1 parameter - if (xml.elements() != 1 || xml.elements("parameter") != 1) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Radial Gaussian model requires exactly 1 parameter."); - } - - // Set or update model parameter attributes - int npar[] = {0}; - for (int i = 0; i < 1; ++i) { - - // Get parameter element - GXmlElement* par = xml.element("parameter", i); - - // Handle sigma - if (par->attribute("name") == "Sigma") { - m_sigma.write(*par); - npar[0]++; - } - - } // endfor: looped over all parameters - - // Check of all required parameters are present - if (npar[0] != 1) { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Radial Gaussian model requires \"Sigma\" parameter."); - } + // Write parameter + m_sigma.write(*sigma); // Return return; diff --git a/inst/cta/src/GCTAModelRadialPolynom.cpp b/inst/cta/src/GCTAModelRadialPolynom.cpp index 42e9f7a..7c64f4f 100644 --- a/inst/cta/src/GCTAModelRadialPolynom.cpp +++ b/inst/cta/src/GCTAModelRadialPolynom.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCTAModelRadialPolynom.cpp - Radial Polynom CTA model class * * ----------------------------------------------------------------------- * - * copyright (C) 2011-2018 by Juergen Knoedlseder * + * copyright (C) 2011-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -469,14 +469,18 @@ double GCTAModelRadialPolynom::omega(void) const * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. + * @exception GException::invalid_value + * Invalid XML format encountered. * - * Read the radial Polynom model information from an XML element. The XML - * element is required to have at least one parameter. Parameters are named - * "CoeffX", where "X" starts from "0". + * Read the radial Polynom model information from an XML element in the + * following format + * + * + * + * + * + * ... + * * * @todo Implement a test of the coefficient boundaries. ***************************************************************************/ @@ -490,9 +494,9 @@ void GCTAModelRadialPolynom::read(const GXmlElement& xml) // Throw an error if no parameters were found if (max_coeffs < 1) { - std::string message = "Radial polynomial model requires at least" - " one coefficient."; - throw GException::model_invalid_parnum(G_READ, xml, message); + std::string msg = "Radial polynomial model requires at least one " + "coefficient. Please verify the XML format."; + throw GException::invalid_value(G_READ, msg); } // Verify XML file consistency and determine number of coefficients @@ -506,8 +510,10 @@ void GCTAModelRadialPolynom::read(const GXmlElement& xml) // Verify that parameter is indeed a coefficient if (par->attribute("name").compare(0,5,"Coeff") != 0) { - throw GException::model_invalid_parnames(G_READ, xml, - par->attribute("name")); + std::string msg = "Invalid parameter \""+par->attribute("name")+ + "\" encountered. Parameter name needs to start " + "with \"Coeff\". Please verify the XML format."; + throw GException::invalid_value(G_READ, msg); } // Verify that parameter coefficient has index in valid range @@ -517,20 +523,24 @@ void GCTAModelRadialPolynom::read(const GXmlElement& xml) index = gammalib::toint(par->attribute("name").substr(5, nchars)); } else { - throw GException::model_invalid_parnames(G_READ, xml, - "Radial polynomial \"Coeff\" parameter has no index."); + std::string msg = "Radial polynomial \"Coeff\" parameter has no " + "index. Please verify the XML format."; + throw GException::invalid_value(G_READ, msg); } if (index < 0) { - throw GException::model_invalid_parnames(G_READ, xml, - "Radial polynomial \"Coeff\" parameter index < 0."); + std::string msg = "Radial polynomial \"Coeff\" parameter has " + "negative index "+gammalib::str(index)+". Please " + "verify the XML format."; + throw GException::invalid_value(G_READ, msg); } if (index >= max_coeffs) { - std::string message = "There are "+gammalib::str(max_coeffs)+" parameters," - " hence polynomial coefficients are expected" - " to run from 0 to "+gammalib::str(max_coeffs-1)+", yet" - " a coefficient with index "+gammalib::str(index)+" was" - " encountered."; - throw GException::model_invalid_parnames(G_READ, xml, message); + std::string msg = "There are "+gammalib::str(max_coeffs)+ + " parameters, hence polynomial coefficients are " + "expected to run from 0 to "+ + gammalib::str(max_coeffs-1)+", yet a coefficient " + "with index "+gammalib::str(index)+" was " + "encountered. Please verify the XML format."; + throw GException::invalid_value(G_READ, msg); } // Increment parameter counter @@ -545,22 +555,25 @@ void GCTAModelRadialPolynom::read(const GXmlElement& xml) // Verify that the number of coefficients is between 1 and max_coeffs if (ncoeffs < 0 || ncoeffs > max_coeffs) { - std::string message = "Radial polynomial model requires at between" - " 1 and "+gammalib::str(max_coeffs)+" parameters."; - throw GException::model_invalid_parnum(G_READ, xml, message); + std::string msg = "Radial polynomial model requires between 1 and "+ + gammalib::str(max_coeffs)+" parameters. Please " + "verify the XML format."; + throw GException::invalid_value(G_READ, msg); } // Verify that all parameters were found for (int i = 0; i < ncoeffs; ++i) { if (npar[i] == 0) { - std::string message = "Parameter \"Coeff"+gammalib::str(i)+"\" required," - " but not found in XML file."; - throw GException::model_invalid_parnames(G_READ, xml, message); + std::string msg = "Parameter \"Coeff"+gammalib::str(i)+ + "\" not found in XML file. Please verify the " + "XML format."; + throw GException::invalid_value(G_READ, msg); } else if (npar[i] > 1) { - std::string message = "Multiple parameters \"Coeff"+gammalib::str(i)+"\"" - " found in XML file."; - throw GException::model_invalid_parnames(G_READ, xml, message); + std::string msg = "Multiple parameters \"Coeff"+gammalib::str(i)+ + "\" found in XML file. Please verify the XML " + "format."; + throw GException::invalid_value(G_READ, msg); } } @@ -583,8 +596,9 @@ void GCTAModelRadialPolynom::read(const GXmlElement& xml) // Make sure that we really have one (just a double check, this should // never fail) if (par == NULL) { - std::string message = "Required parameter \""+name+"\" not found."; - throw GException::model_invalid_parnames(G_READ, xml, message); + std::string msg = "Required parameter \""+name+"\" not found. " + "Please verify the XML format."; + throw GException::invalid_value(G_READ, msg); } // Now read that parameter ... @@ -615,90 +629,38 @@ void GCTAModelRadialPolynom::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type 'Polynom' - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. + * Write the polynomial radial model information into an XML element in the + * following format * - * Write the polynomial radial model information into an XML element. The XML - * element will have 1-10 parameter leafs named "CoeffX", where X runs from - * 0 to 9. + * + * + * + * + * ... + * ***************************************************************************/ void GCTAModelRadialPolynom::write(GXmlElement& xml) const { // Determine number of coefficients int ncoeffs = m_coeffs.size(); - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Radial polynomial model is not of type \""+type()+"\"."); - } - - // If XML element has 0 nodes then append nodes for coefficients - if (xml.elements() == 0) { - for (int i = 0; i < ncoeffs; ++i) { - std::string name = "parameter name=\"Coeff"+gammalib::str(i)+"\""; - xml.append(GXmlElement(name)); - } - } + // Check model type + gammalib::xml_check_type(G_WRITE, xml, type()); - // Verify that XML element has one parameter per coefficient - if (xml.elements() != ncoeffs || xml.elements("parameter") != ncoeffs) { - std::string message = "Radial polynomial model requires exactly " + - gammalib::str(ncoeffs) + " parameters."; - throw GException::model_invalid_parnum(G_WRITE, xml, message); - } - - // Set or update model parameter attributes - std::vector npar; - npar.assign(ncoeffs, 0); + // Write model parameters for (int i = 0; i < ncoeffs; ++i) { // Set parameter name std::string name = "Coeff"+gammalib::str(i); - // Get corresponding parameter element - GXmlElement* par = NULL; - for (int k = 0; k < ncoeffs; ++k) { - GXmlElement* element = xml.element("parameter", k); - if (element->attribute("name") == name) { - par = element; - break; - } - } - - // Make sure that we really have one (just a double check, this should - // never fail) - if (par == NULL) { - std::string message = "Required parameter \""+name+"\" not found."; - throw GException::model_invalid_parnames(G_WRITE, xml, message); - } + // Get or create parameter + GXmlElement* coeff = gammalib::xml_need_par(G_WRITE, xml, name); // Write parameter - m_coeffs[i].write(*par); - - // Increment parameter counter - npar[i]++; + m_coeffs[i].write(*coeff); } // endfor: looped over all parameters - // Verify that all parameters were present - for (int i = 0; i < ncoeffs; ++i) { - if (npar[i] != 1) { - std::string message = "Parameter \"Coeff"+gammalib::str(i)+"\" required," - " but not found in XML file."; - throw GException::model_invalid_parnames(G_WRITE, xml, message); - } - } - // Return return; } diff --git a/inst/cta/src/GCTAModelRadialProfile.cpp b/inst/cta/src/GCTAModelRadialProfile.cpp index 8fa35dd..60b1f52 100644 --- a/inst/cta/src/GCTAModelRadialProfile.cpp +++ b/inst/cta/src/GCTAModelRadialProfile.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCTAModelRadialProfile.cpp - Radial Profile CTA model class * * ----------------------------------------------------------------------- * - * copyright (C) 2011-2018 by Juergen Knoedlseder * + * copyright (C) 2011-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -409,82 +409,29 @@ double GCTAModelRadialProfile::omega(void) const * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parvalue - * Non-positive parameter value found. - * @exception GException::model_invalid_parlimit - * Missing or non-positive minimum parameter boundary. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. + * Read the Profile radial model information from an XML element in the + * following format * - * Read the Profile radial model information from an XML element. The XML - * element is required to have 3 parameter named "Width", "Core", and "Tail". + * + * + * + * + * ***************************************************************************/ void GCTAModelRadialProfile::read(const GXmlElement& xml) { - // Verify that XML element has exactly 3 parameter - if (xml.elements() != 3 || xml.elements("parameter") != 3) { - throw GException::model_invalid_parnum(G_READ, xml, - "Radial Profile model requires exactly 3 parameters."); - } - - // Extract model parameters - int npar[] = {0, 0, 0}; - for (int i = 0; i < 3; ++i) { - - // Get parameter element - const GXmlElement* par = xml.element("parameter", i); - - // Handle Width - if (par->attribute("name") == "Width") { - m_width.read(*par); - if (m_width.value() <= 0.0) { - throw GException::model_invalid_parvalue(G_READ, xml, - "\"Width\" parameter is required to be positive."); - } - if (!m_width.has_min() || m_width.min() <= 0.0) { - throw GException::model_invalid_parlimit(G_READ, xml, - "\"Width\" parameter requires positive minimum boundary."); - } - npar[0]++; - } - - // Handle Core - if (par->attribute("name") == "Core") { - m_core.read(*par); - if (m_core.value() <= 0.0) { - throw GException::model_invalid_parvalue(G_READ, xml, - "\"Core\" parameter is required to be positive."); - } - if (!m_core.has_min() || m_core.min() <= 0.0) { - throw GException::model_invalid_parlimit(G_READ, xml, - "\"Core\" parameter requires positive minimum boundary."); - } - npar[1]++; - } - - // Handle Tail - if (par->attribute("name") == "Tail") { - m_tail.read(*par); - if (m_tail.value() <= 0.0) { - throw GException::model_invalid_parvalue(G_READ, xml, - "\"Tail\" parameter is required to be positive."); - } - if (!m_tail.has_min() || m_tail.min() <= 0.0) { - throw GException::model_invalid_parlimit(G_READ, xml, - "\"Tail\" parameter requires positive minimum boundary."); - } - npar[2]++; - } + // Verify that XML element has exactly 3 parameters + gammalib::xml_check_parnum(G_READ, xml, 3); - } // endfor: looped over all parameters + // Get parameters + const GXmlElement* width = gammalib::xml_get_par(G_READ, xml, m_width.name()); + const GXmlElement* core = gammalib::xml_get_par(G_READ, xml, m_core.name()); + const GXmlElement* tail = gammalib::xml_get_par(G_READ, xml, m_tail.name()); - // 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 \"Width\", \"Core\" and \"Tail\" parameters."); - } + // Read parameters + m_width.read(*width); + m_core.read(*core); + m_tail.read(*tail); // Return return; @@ -496,74 +443,29 @@ void GCTAModelRadialProfile::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type 'ProfileFunction' - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. + * Write the radial Profile model information into an XML element in the + * following format * - * Write the radial Profile model information into an XML element. The XML - * element will have 3 parameter leafs named "Width", "Core" and "Tail". + * + * + * + * + * ***************************************************************************/ void GCTAModelRadialProfile::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Radial Profile model is not of type \""+type()+"\"."); - } - - // If XML element has 0 nodes then append 3 parameter nodes - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Width\"")); - xml.append(GXmlElement("parameter name=\"Core\"")); - xml.append(GXmlElement("parameter name=\"Tail\"")); - } - - // Verify that XML element has exactly 3 parameters - if (xml.elements() != 3 || xml.elements("parameter") != 3) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Radial Profile model requires exactly 3 parameters."); - } + // Check model type + gammalib::xml_check_type(G_WRITE, xml, 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") == "Width") { - m_width.write(*par); - npar[0]++; - } + // Get or create parameters + GXmlElement* width = gammalib::xml_need_par(G_WRITE, xml, m_width.name()); + GXmlElement* core = gammalib::xml_need_par(G_WRITE, xml, m_core.name()); + GXmlElement* tail = gammalib::xml_need_par(G_WRITE, xml, m_tail.name()); - // Handle index - else if (par->attribute("name") == "Core") { - m_core.write(*par); - npar[1]++; - } - - // Handle pivot energy - else if (par->attribute("name") == "Tail") { - m_tail.write(*par); - npar[2]++; - } - - } // endfor: looped over all parameters - - // 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 \"Width\", \"Core\" and \"Tail\" parameters."); - } + // Write parameters + m_width.write(*width); + m_core.write(*core); + m_tail.write(*tail); // Return return; @@ -573,7 +475,7 @@ void GCTAModelRadialProfile::write(GXmlElement& xml) const /***********************************************************************//** * @brief Print point source information * - * @param[in] chatter Chattiness (defaults to NORMAL). + * @param[in] chatter Chattiness. * @return String containing point source information. ***************************************************************************/ std::string GCTAModelRadialProfile::print(const GChatter& chatter) const diff --git a/inst/cta/src/GCTAModelSpatialGradient.cpp b/inst/cta/src/GCTAModelSpatialGradient.cpp index 08f3cbe..988ef79 100644 --- a/inst/cta/src/GCTAModelSpatialGradient.cpp +++ b/inst/cta/src/GCTAModelSpatialGradient.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCTAModelSpatialGradient.cpp - Spatial gradient CTA model class * * ----------------------------------------------------------------------- * - * copyright (C) 2018 by Juergen Knoedlseder * + * copyright (C) 2018-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -353,24 +353,12 @@ void GCTAModelSpatialGradient::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::invalid_value - * Spatial model is not of valid type. - * * Write the gradient spatial model information into an XML element. ***************************************************************************/ void GCTAModelSpatialGradient::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - - // Verify model type - if (xml.attribute("type") != type()) { - std::string msg = "Spatial model \""+xml.attribute("type")+ - "\" is not of type \""+type()+"\"."; - throw GException::invalid_value(G_WRITE, msg); - } + // Check model type + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* detx = gammalib::xml_need_par(G_WRITE, xml, m_detx_gradient.name()); diff --git a/inst/cta/src/GCTAModelSpatialMultiplicative.cpp b/inst/cta/src/GCTAModelSpatialMultiplicative.cpp index 5b53927..2323e2b 100644 --- a/inst/cta/src/GCTAModelSpatialMultiplicative.cpp +++ b/inst/cta/src/GCTAModelSpatialMultiplicative.cpp @@ -361,24 +361,12 @@ void GCTAModelSpatialMultiplicative::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::invalid_value - * Existing XML element is not of the expected type. - * * Writes the spatial information into an XML element. ***************************************************************************/ void GCTAModelSpatialMultiplicative::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - - // Verify model type - if (xml.attribute("type") != type()) { - std::string msg = "Spatial model \""+xml.attribute("type")+"\" is " - "not of expected type \""+type()+"\"."; - throw GException::invalid_value(G_WRITE, msg); - } + // Check model type + gammalib::xml_check_type(G_WRITE, xml, type()); // Loop over model components for (int i = 0; i < m_spatial.size(); i++) { diff --git a/pyext/GFitsTableCol.i b/pyext/GFitsTableCol.i index c3d6543..766e12c 100644 --- a/pyext/GFitsTableCol.i +++ b/pyext/GFitsTableCol.i @@ -132,7 +132,7 @@ public: (*col)(GTuple1D2D[1], GTuple1D2D[2]) = value; } else { - throw GException::bad_type("GFitsTableCol::__setitem__", + throw GException::invalid_argument("GFitsTableCol::__setitem__", "Column type does not support string setting."); } } @@ -210,7 +210,7 @@ public: (*col)(GTuple1D2D[1], GTuple1D2D[2]) = (float)value; } else { - throw GException::bad_type("GFitsTableCol::__setitem__", + throw GException::invalid_argument("GFitsTableCol::__setitem__", "Column type does not support integer setting."); } } @@ -233,7 +233,7 @@ public: } else { - throw GException::bad_type("GFitsTableCol::__setitem__", + throw GException::invalid_argument("GFitsTableCol::__setitem__", "Column type does not support floating point setting."); } } diff --git a/src/model/GException_model.cpp b/src/model/GException_model.cpp deleted file mode 100644 index 62da23b..0000000 --- a/src/model/GException_model.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/*************************************************************************** - * GException_model.cpp - Model exception handlers * - * ----------------------------------------------------------------------- * - * copyright (C) 2010-2011 by Jurgen Knodlseder * - * ----------------------------------------------------------------------- * - * * - * 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 . * - * * - ***************************************************************************/ -/** - * @file GException_model.cpp - * @brief Implement exceptions for the model module - * @author J. Knodlseder - */ - -/* __ Includes ___________________________________________________________ */ -#ifdef HAVE_CONFIG_H -#include -#endif -#include "GException.hpp" -#include "GModelRegistry.hpp" -#include "GModelSpatialRegistry.hpp" -#include "GModelSpectralRegistry.hpp" -#include "GModelTemporalRegistry.hpp" -#include "GTools.hpp" - - -/***********************************************************************//** - * @brief Invalid model type - * - * @param[in] origin Method that throws the error. - * @param[in] type Model type that has been encountered. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid::model_invalid(std::string origin, - std::string type, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid model type \""+type+"\" encountered. " + message; - - // Add list of valid models - GModelRegistry registry; - if (registry.size() > 0) { - m_message += "The following models are registered: "; - for (int i = 0; i < registry.size(); ++i) { - if (i > 0) - m_message += ", "; - m_message += "\"" + registry.name(i) + "\""; - } - m_message += "."; - } - else - m_message += "No models are registered."; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid spatial model type - * - * @param[in] origin Method that throws the error. - * @param[in] type Spatial model type that has been encountered. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_spatial::model_invalid_spatial(std::string origin, - std::string type, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid spatial model type \""+type+"\" encountered. " + - message; - - // Add list of valid spatial models - GModelSpatialRegistry registry; - if (registry.size() > 0) { - m_message += "The following models are registered: "; - for (int i = 0; i < registry.size(); ++i) { - if (i > 0) - m_message += ", "; - m_message += "\"" + registry.name(i) + "\""; - } - m_message += "."; - } - else - m_message += "No models are registered."; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid spectral model type - * - * @param[in] origin Method that throws the error. - * @param[in] type Spectral model type that has been encountered. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_spectral::model_invalid_spectral(std::string origin, - std::string type, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid spectral model type \""+type+"\" encountered. " + - message; - - // Add list of valid spectral models - GModelSpectralRegistry registry; - if (registry.size() > 0) { - m_message += "The following models are registered: "; - for (int i = 0; i < registry.size(); ++i) { - if (i > 0) - m_message += ", "; - m_message += "\"" + registry.name(i) + "\""; - } - m_message += "."; - } - else - m_message += "No models are registered."; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid temporal model type - * - * @param[in] origin Method that throws the error. - * @param[in] type Temporal model type that has been encountered. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_temporal::model_invalid_temporal(std::string origin, - std::string type, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid temporal model type \""+type+"\" encountered. " + - message; - - // Add list of valid spectral models - GModelTemporalRegistry registry; - if (registry.size() > 0) { - m_message += "The following models are registered: "; - for (int i = 0; i < registry.size(); ++i) { - if (i > 0) - m_message += ", "; - m_message += "\"" + registry.name(i) + "\""; - } - m_message += "."; - } - else - m_message += "No models are registered."; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid number of model parameters in XML element - * - * @param[in] origin Method that throws the error. - * @param[in] xml XML element. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_parnum::model_invalid_parnum(std::string origin, - GXmlElement xml, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid number of model parameters found in XML element. " + - message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid model parameter names in XML element - * - * @param[in] origin Method that throws the error. - * @param[in] xml XML element. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_parnames::model_invalid_parnames(std::string origin, - GXmlElement xml, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid model parameter names found in XML element. " + - message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid model parameter value in XML element - * - * @param[in] origin Method that throws the error. - * @param[in] xml XML element. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_parvalue::model_invalid_parvalue(std::string origin, - GXmlElement xml, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid model parameter value found in XML element. " + - message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid model parameter limit in XML element - * - * @param[in] origin Method that throws the error. - * @param[in] xml XML element. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_parlimit::model_invalid_parlimit(std::string origin, - GXmlElement xml, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid model parameter limit found in XML element. " + - message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Model parameter has invalid scale - * - * @param[in] origin Method that throws the error. - * @param[in] scale Scale. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_parscale::model_invalid_parscale(std::string origin, - double scale, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Model parameter has invalid scale="+gammalib::str(scale)+". " + - message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Model parameter has invalid scale - * - * @param[in] origin Method that throws the error. - * @param[in] xml XML element. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_invalid_parscale::model_invalid_parscale(std::string origin, - GXmlElement xml, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Model parameter with invalid scale found in XML element. " + - message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Not enough nodes in file function - * - * @param[in] origin Method that throws the error. - * @param[in] filename File function filename. - * @param[in] num Number of nodes. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::file_function_data::file_function_data(std::string origin, - std::string filename, - int num, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "File function \""+filename+"\" contains "+gammalib::str(num)+ - " energy nodes while at least 2 are required to describe a" - " spectral shape."; - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Not enough columns in file function - * - * @param[in] origin Method that throws the error. - * @param[in] filename File function filename. - * @param[in] num Number of columns. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::file_function_columns::file_function_columns(std::string origin, - std::string filename, - int num, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "File function \""+filename+"\" contains "+gammalib::str(num)+ - " columns while at least 2 are required to define" - " energy and intensity."; - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid value in file function - * - * @param[in] origin Method that throws the error. - * @param[in] filename File function filename. - * @param[in] value Number of columns. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::file_function_value::file_function_value(std::string origin, - std::string filename, - double value, - std::string message) -{ - // Set origin and message - m_origin = origin; - m_message = "Invalid value \""+gammalib::str(value)+"\" encountered in" - " file function \""+filename+"\"."; - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Parameter not found - * - * @param[in] origin Method that throws the error. - * @param[in] name Parameter name. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::par_not_found::par_not_found(std::string origin, - std::string name, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Parameter \""+name+"\" not found in container."; - if (message.length() > 0) - m_message += " "+message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Model not found - * - * @param[in] origin Method that throws the error. - * @param[in] name Model name. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::model_not_found::model_not_found(std::string origin, - std::string name, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Model \""+name+"\" not found in container."; - if (message.length() > 0) - m_message += " "+message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief No point source model component found - * - * @param[in] origin Method that throws the error. - * @param[in] name Model name. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::no_point_source::no_point_source(std::string origin, - std::string name, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "No point source model component found in model \""+name+"\"."; - if (message.length() > 0) - m_message += " "+message; - - // Return - return; -} - - -/***********************************************************************//** - * @brief No extended source model component found - * - * @param[in] origin Method that throws the error. - * @param[in] name Model name. - * @param[in] message Optional error message. - ***************************************************************************/ -GException::no_extended_source::no_extended_source(std::string origin, - std::string name, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "No extended source model component found in model \""+name+"\"."; - if (message.length() > 0) - m_message += " "+message; - - // Return - return; -} diff --git a/src/model/GModel.cpp b/src/model/GModel.cpp index de2ae80..e9d1b9f 100644 --- a/src/model/GModel.cpp +++ b/src/model/GModel.cpp @@ -156,8 +156,8 @@ GModel& GModel::operator=(const GModel& model) * @param[in] name Parameter name. * @return Reference to model parameter. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. * * Returns a reference to the model parameter of the specified @p name. * Throws an exception if no parameter with @p name is found. @@ -174,7 +174,9 @@ GModelPar& GModel::operator[](const std::string& name) // Throw exception if parameter name was not found if (index >= size()) { - throw GException::par_not_found(G_ACCESS, name); + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return reference @@ -188,8 +190,8 @@ GModelPar& GModel::operator[](const std::string& name) * @param[in] name Parameter name. * @return Reference to model parameter. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. * * Returns a const reference to the model parameter of the specified * @p name. Throws an exception if no parameter with @p name is found. @@ -206,7 +208,9 @@ const GModelPar& GModel::operator[](const std::string& name) const // Throw exception if parameter name was not found if (index >= size()) { - throw GException::par_not_found(G_ACCESS, name); + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return reference @@ -879,7 +883,7 @@ void GModel::read_scales(const GXmlElement& xml) * * @param[in] xml XML source element. * - * @exception GException::model_invalid_parnum + * @exception GException::invalid_value * Invalid number of instrument tags found in XML element. * * If there are instrument scale factors then add a tag with the following @@ -915,10 +919,21 @@ void GModel::write_scales(GXmlElement& xml) const scale = xml.element("scaling", 0); } - // Verify that scaling tag has the required number of instruments - if (scale->elements() != num || scale->elements("instrument") != num) { - throw GException::model_invalid_parnum(G_WRITE_SCALES, *scale, - "Instrument scaling needs "+gammalib::str(num)+" instrument tags."); + // Verify that scaling tag has the required number of instruments + if (scale->elements() != num) { + std::string msg = "Number of "+gammalib::str(scale->elements())+ + " scale elements in XML file does not correspond " + "to expected number of "+gammalib::str(num)+ + " elements. Please verify the XML format."; + throw GException::invalid_value(G_WRITE_SCALES, msg); + } + int npars = scale->elements("instrument"); + if (npars != num) { + std::string msg = "Number of "+gammalib::str(npars)+" \"instrument\" " + "scale elements in XML file does not correspond to " + "expected number of "+gammalib::str(num)+ + " elements. Please verify the XML format."; + throw GException::invalid_value(G_WRITE_SCALES, msg); } // Write all instruments diff --git a/src/model/GModelSpatial.cpp b/src/model/GModelSpatial.cpp index c2bd0e7..1a87dfb 100644 --- a/src/model/GModelSpatial.cpp +++ b/src/model/GModelSpatial.cpp @@ -136,8 +136,8 @@ GModelSpatial& GModelSpatial::operator=(const GModelSpatial& model) * @param[in] name Parameter name. * @return Model parameter reference. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. * * Returns reference to the model parameter of specified @p name. ***************************************************************************/ @@ -153,7 +153,9 @@ GModelPar& GModelSpatial::operator[](const std::string& name) // Throw exception if parameter name was not found if (index >= size()) { - throw GException::par_not_found(G_ACCESS, name); + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return reference @@ -167,8 +169,8 @@ GModelPar& GModelSpatial::operator[](const std::string& name) * @param[in] name Parameter name. * @return Model parameter reference. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. * * Returns reference to the model parameter of specified @p name. ***************************************************************************/ @@ -184,7 +186,9 @@ const GModelPar& GModelSpatial::operator[](const std::string& name) const // Throw exception if parameter name was not found if (index >= size()) { - throw GException::par_not_found(G_ACCESS, name); + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return reference diff --git a/src/model/GModelSpatialComposite.cpp b/src/model/GModelSpatialComposite.cpp index 405e7a6..dcaa256 100644 --- a/src/model/GModelSpatialComposite.cpp +++ b/src/model/GModelSpatialComposite.cpp @@ -419,27 +419,12 @@ void GModelSpatialComposite::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of appropriate type - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Write the spatial information into an XML element. ***************************************************************************/ void GModelSpatialComposite::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Spatial model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Write all model components for (int i = 0; i < m_components.size(); ++i) { diff --git a/src/model/GModelSpatialDiffuseConst.cpp b/src/model/GModelSpatialDiffuseConst.cpp index b35553a..0990022 100644 --- a/src/model/GModelSpatialDiffuseConst.cpp +++ b/src/model/GModelSpatialDiffuseConst.cpp @@ -421,6 +421,9 @@ double GModelSpatialDiffuseConst::mc_norm(const GSkyDir& dir, ***************************************************************************/ void GModelSpatialDiffuseConst::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 1); + // Get value parameter const GXmlElement* par = gammalib::xml_get_par(G_READ, xml, m_value.name()); @@ -437,9 +440,6 @@ void GModelSpatialDiffuseConst::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type "ConstantValue" - * * Write the isotropic source model information into an XML element. The XML * element will have the following format: * @@ -450,16 +450,8 @@ void GModelSpatialDiffuseConst::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialDiffuseConst::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Spatial model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get or create Value parameter GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, m_value.name()); diff --git a/src/model/GModelSpatialDiffuseCube.cpp b/src/model/GModelSpatialDiffuseCube.cpp index 48d213f..dd6ae7f 100644 --- a/src/model/GModelSpatialDiffuseCube.cpp +++ b/src/model/GModelSpatialDiffuseCube.cpp @@ -559,6 +559,9 @@ bool GModelSpatialDiffuseCube::contains(const GSkyDir& dir, ***************************************************************************/ void GModelSpatialDiffuseCube::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 1); + // If "Normalization" parameter exists then read parameter from this // XML element if (gammalib::xml_has_par(xml, "Normalization")) { @@ -599,13 +602,6 @@ void GModelSpatialDiffuseCube::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type "MapCubeFunction" - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Write the map cube information into an XML element. The XML element will * have either the format * @@ -623,44 +619,14 @@ void GModelSpatialDiffuseCube::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialDiffuseCube::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Spatial model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); - // If XML element has 0 nodes then append parameter node. The name - // of the node is "Normalization" 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=\"Normalization\"")); - } + // Get or create parameter + GXmlElement* value = gammalib::xml_need_par(G_WRITE, xml, m_value.name()); - // Verify that XML element has exactly 1 parameter - if (xml.elements() != 1 || xml.elements("parameter") != 1) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Map cube spatial model requires exactly 1 parameter."); - } - - // Get pointers on model parameter - GXmlElement* par = xml.element("parameter", 0); - - // Set or update parameter - if (par->attribute("name") == "Normalization" || - par->attribute("name") == "Value") { - m_value.write(*par); - } - else { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Map cube spatial model requires either \"Value\" or" - " \"Normalization\" parameter."); - } + // Write parameter + m_value.write(*value); // Set filename xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename)); diff --git a/src/model/GModelSpatialDiffuseMap.cpp b/src/model/GModelSpatialDiffuseMap.cpp index a9b0040..e9d2bc1 100644 --- a/src/model/GModelSpatialDiffuseMap.cpp +++ b/src/model/GModelSpatialDiffuseMap.cpp @@ -520,6 +520,9 @@ bool GModelSpatialDiffuseMap::contains(const GSkyDir& dir, ***************************************************************************/ void GModelSpatialDiffuseMap::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 1); + // If "Normalization" parameter exists then read parameter from this // XML element if (gammalib::xml_has_par(xml, "Normalization")) { @@ -596,47 +599,17 @@ void GModelSpatialDiffuseMap::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialDiffuseMap::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Spatial model is not of type \""+type()+"\"."); - } - - // Set sky map file name - xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename)); + gammalib::xml_check_type(G_WRITE, xml, type()); - // If XML element has 0 nodes then append parameter node. The name - // of the node is "Prefactor" 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=\"Prefactor\"")); - } - - // Verify that XML element has exactly 1 parameter - if (xml.elements() != 1 || xml.elements("parameter") != 1) { - throw GException::model_invalid_parnum(G_WRITE, xml, - "Spatial map model requires exactly 1 parameter."); - } + // Get or create parameter + GXmlElement* value = gammalib::xml_need_par(G_WRITE, xml, m_value.name()); - // Get pointer on model parameter - GXmlElement* par = xml.element("parameter", 0); + // Write parameters + m_value.write(*value); - // Set or update parameter - if (par->attribute("name") == "Normalization" || - par->attribute("name") == "Prefactor") { - m_value.write(*par); - } - else { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Spatial map model requires either \"Prefactor\" or" - " \"Normalization\" parameter."); - } + // Set sky map file name + xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename)); // Set optional normalization attribute if (m_has_normalize || !m_normalize) { diff --git a/src/model/GModelSpatialElliptical.cpp b/src/model/GModelSpatialElliptical.cpp index 2178e57..5bb003f 100644 --- a/src/model/GModelSpatialElliptical.cpp +++ b/src/model/GModelSpatialElliptical.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialElliptical.cpp - Abstract elliptical spatial model class * * ----------------------------------------------------------------------- * - * copyright (C) 2013-2020 by Juergen Knoedlseder * + * copyright (C) 2013-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -191,11 +191,6 @@ double GModelSpatialElliptical::eval(const GPhoton& photon, * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Reads the elliptical source location and position angle information from * an XML element in the following format * @@ -270,13 +265,6 @@ void GModelSpatialElliptical::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of requested type. - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Writes the elliptical source location and position angle information into * an XML element in the following format * @@ -292,16 +280,8 @@ void GModelSpatialElliptical::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialElliptical::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Elliptical model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get or create parameters GXmlElement* ra = gammalib::xml_need_par(G_WRITE, xml, m_ra.name()); diff --git a/src/model/GModelSpatialEllipticalDisk.cpp b/src/model/GModelSpatialEllipticalDisk.cpp index 903a903..c98b8cd 100644 --- a/src/model/GModelSpatialEllipticalDisk.cpp +++ b/src/model/GModelSpatialEllipticalDisk.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialEllipticalDisk.cpp - Elliptical disk source model class * * ----------------------------------------------------------------------- * - * copyright (C) 2013-2020 by Michael Mayer * + * copyright (C) 2013-2021 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -459,14 +459,8 @@ double GModelSpatialEllipticalDisk::theta_max(void) const ***************************************************************************/ void GModelSpatialEllipticalDisk::read(const GXmlElement& xml) { - // Determine number of parameter nodes in XML element - int npars = xml.elements("parameter"); - - // Verify that XML element has exactly 5 parameters - if (xml.elements() != 5 || npars != 5) { - throw GException::model_invalid_parnum(G_READ, xml, - "Elliptical disk model requires exactly 5 parameters."); - } + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 5); // Read disk location GModelSpatialElliptical::read(xml); @@ -489,11 +483,6 @@ void GModelSpatialEllipticalDisk::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Write the elliptical disk model information into an XML element. The XML * element will have the format * @@ -508,6 +497,9 @@ void GModelSpatialEllipticalDisk::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialEllipticalDisk::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write disk location GModelSpatialElliptical::write(xml); diff --git a/src/model/GModelSpatialEllipticalGauss.cpp b/src/model/GModelSpatialEllipticalGauss.cpp index 97db34f..2a52109 100644 --- a/src/model/GModelSpatialEllipticalGauss.cpp +++ b/src/model/GModelSpatialEllipticalGauss.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialEllipticalGauss.cpp - Elliptical gauss source model class * * ----------------------------------------------------------------------- * - * copyright (C) 2015-2020 by Michael Mayer * + * copyright (C) 2015-2021 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -498,11 +498,6 @@ double GModelSpatialEllipticalGauss::theta_max(void) const * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Reads the elliptical gauss model information from an XML element. The XML * element shall have either the format * @@ -529,14 +524,8 @@ double GModelSpatialEllipticalGauss::theta_max(void) const ***************************************************************************/ void GModelSpatialEllipticalGauss::read(const GXmlElement& xml) { - // Determine number of parameter nodes in XML element - int npars = xml.elements("parameter"); - - // Verify that XML element has exactly 5 parameters - if (xml.elements() != 5 || npars != 5) { - throw GException::model_invalid_parnum(G_READ, xml, - "Elliptical gauss model requires exactly 5 parameters."); - } + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 5); // Read gauss location GModelSpatialElliptical::read(xml); @@ -559,11 +548,6 @@ void GModelSpatialEllipticalGauss::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Write the elliptical gauss model information into an XML element. The XML * element will have the format * @@ -578,6 +562,9 @@ void GModelSpatialEllipticalGauss::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialEllipticalGauss::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write disk location GModelSpatialElliptical::write(xml); diff --git a/src/model/GModelSpatialPointSource.cpp b/src/model/GModelSpatialPointSource.cpp index 88d313b..d3b2ac2 100644 --- a/src/model/GModelSpatialPointSource.cpp +++ b/src/model/GModelSpatialPointSource.cpp @@ -348,11 +348,6 @@ bool GModelSpatialPointSource::contains(const GSkyDir& dir, * * @param[in] xml XML element containing point source model information. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Read the point source information from an XML element with the following * format * @@ -371,6 +366,9 @@ bool GModelSpatialPointSource::contains(const GSkyDir& dir, ***************************************************************************/ void GModelSpatialPointSource::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 2); + // Read RA/DEC parameters if (gammalib::xml_has_par(xml, "RA") && gammalib::xml_has_par(xml, "DEC")) { @@ -417,13 +415,6 @@ void GModelSpatialPointSource::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type 'SkyDirFunction' - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Write the point source information into an XML element with the following * format * @@ -437,16 +428,8 @@ void GModelSpatialPointSource::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialPointSource::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Spatial model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get or create parameters GXmlElement* ra = gammalib::xml_need_par(G_WRITE, xml, m_ra.name()); diff --git a/src/model/GModelSpatialRadial.cpp b/src/model/GModelSpatialRadial.cpp index cc1867b..298fc5c 100644 --- a/src/model/GModelSpatialRadial.cpp +++ b/src/model/GModelSpatialRadial.cpp @@ -282,16 +282,8 @@ void GModelSpatialRadial::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadial::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), - "Radial model is not of type \""+type()+"\"."); - } + // Check model type + gammalib::xml_check_type(G_WRITE, xml, type()); // Get or create parameters GXmlElement* ra = gammalib::xml_need_par(G_WRITE, xml, m_ra.name()); diff --git a/src/model/GModelSpatialRadialDisk.cpp b/src/model/GModelSpatialRadialDisk.cpp index 304a769..dcac48c 100644 --- a/src/model/GModelSpatialRadialDisk.cpp +++ b/src/model/GModelSpatialRadialDisk.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialRadialDisk.cpp - Radial disk source model class * * ----------------------------------------------------------------------- * - * copyright (C) 2011-2020 by Christoph Deil * + * copyright (C) 2011-2021 by Christoph Deil * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -409,14 +409,8 @@ double GModelSpatialRadialDisk::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialDisk::read(const GXmlElement& xml) { - // Determine number of parameter nodes in XML element - int npars = xml.elements("parameter"); - // Verify that XML element has exactly 3 parameters - if (xml.elements() != 3 || npars != 3) { - throw GException::model_invalid_parnum(G_READ, xml, - "Disk model requires exactly 3 parameters."); - } + gammalib::xml_check_parnum(G_READ, xml, 3); // Read disk location GModelSpatialRadial::read(xml); @@ -454,6 +448,9 @@ void GModelSpatialRadialDisk::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadialDisk::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write disk location GModelSpatialRadial::write(xml); diff --git a/src/model/GModelSpatialRadialGauss.cpp b/src/model/GModelSpatialRadialGauss.cpp index 1f81ec3..97fdc84 100644 --- a/src/model/GModelSpatialRadialGauss.cpp +++ b/src/model/GModelSpatialRadialGauss.cpp @@ -450,11 +450,6 @@ double GModelSpatialRadialGauss::theta_max(void) const * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Reads the radial Gauss model information from an XML element. The XML * element shall have either the format * @@ -477,14 +472,8 @@ double GModelSpatialRadialGauss::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialGauss::read(const GXmlElement& xml) { - // Determine number of parameter nodes in XML element - int npars = xml.elements("parameter"); - - // Verify that XML element has exactly 3 parameters - if (xml.elements() != 3 || npars != 3) { - throw GException::model_invalid_parnum(G_READ, xml, - "Gaussian source model requires exactly 3 parameters."); - } + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 3); // Read Gaussian location GModelSpatialRadial::read(xml); @@ -505,13 +494,6 @@ void GModelSpatialRadialGauss::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type 'GaussFunction' - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Writes the radial disk model information into an XML element. The XML * element will have the format * @@ -541,7 +523,7 @@ void GModelSpatialRadialGauss::write(GXmlElement& xml) const /***********************************************************************//** * @brief Print Gaussian source information * - * @param[in] chatter Chattiness (defaults to NORMAL). + * @param[in] chatter Chattiness. * @return String containing model information. ***************************************************************************/ std::string GModelSpatialRadialGauss::print(const GChatter& chatter) const diff --git a/src/model/GModelSpatialRadialProfileDMBurkert.cpp b/src/model/GModelSpatialRadialProfileDMBurkert.cpp index 903ee0f..6f3ecb5 100644 --- a/src/model/GModelSpatialRadialProfileDMBurkert.cpp +++ b/src/model/GModelSpatialRadialProfileDMBurkert.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialRadialProfileDMBurkert.cpp - Burkert radial profile class * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2020 by Nathan Kelley-Hoskins * + * copyright (C) 2016-2021 by Nathan Kelley-Hoskins * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -288,6 +288,9 @@ double GModelSpatialRadialProfileDMBurkert::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialProfileDMBurkert::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 8); + // Read DMBurkert location GModelSpatialRadial::read(xml); @@ -335,6 +338,9 @@ void GModelSpatialRadialProfileDMBurkert::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadialProfileDMBurkert::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write DMBurkert location GModelSpatialRadial::write(xml); diff --git a/src/model/GModelSpatialRadialProfileDMEinasto.cpp b/src/model/GModelSpatialRadialProfileDMEinasto.cpp index 4dbc38a..5c6c777 100644 --- a/src/model/GModelSpatialRadialProfileDMEinasto.cpp +++ b/src/model/GModelSpatialRadialProfileDMEinasto.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialRadialProfileDMEinasto.cpp - Einasto radial profile class * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2020 by Nathan Kelley-Hoskins * + * copyright (C) 2016-2021 by Nathan Kelley-Hoskins * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -291,6 +291,9 @@ double GModelSpatialRadialProfileDMEinasto::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialProfileDMEinasto::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 9); + // Read DMEinasto location GModelSpatialRadial::read(xml); @@ -349,6 +352,9 @@ void GModelSpatialRadialProfileDMEinasto::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadialProfileDMEinasto::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write DMEinasto location GModelSpatialRadial::write(xml); diff --git a/src/model/GModelSpatialRadialProfileDMZhao.cpp b/src/model/GModelSpatialRadialProfileDMZhao.cpp index 235f25e..b897655 100644 --- a/src/model/GModelSpatialRadialProfileDMZhao.cpp +++ b/src/model/GModelSpatialRadialProfileDMZhao.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialRadialProfileDMZhao.cpp - Zhao radial profile class * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2020 by Nathan Kelley-Hoskins * + * copyright (C) 2016-2021 by Nathan Kelley-Hoskins * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -291,6 +291,9 @@ double GModelSpatialRadialProfileDMZhao::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialProfileDMZhao::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 11); + // Read halo sky coordinate GModelSpatialRadial::read(xml); @@ -359,6 +362,9 @@ void GModelSpatialRadialProfileDMZhao::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadialProfileDMZhao::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write DMZhao location GModelSpatialRadial::write(xml); diff --git a/src/model/GModelSpatialRadialProfileGauss.cpp b/src/model/GModelSpatialRadialProfileGauss.cpp index a774278..9b9aa13 100644 --- a/src/model/GModelSpatialRadialProfileGauss.cpp +++ b/src/model/GModelSpatialRadialProfileGauss.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialRadialProfileGauss.cpp - Gaussian radial profile class * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2020 by Juergen Knoedlseder * + * copyright (C) 2016-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -286,6 +286,9 @@ double GModelSpatialRadialProfileGauss::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialProfileGauss::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 3); + // Read Gaussian location GModelSpatialRadial::read(xml); @@ -314,6 +317,9 @@ void GModelSpatialRadialProfileGauss::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadialProfileGauss::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write Gaussian location GModelSpatialRadial::write(xml); diff --git a/src/model/GModelSpatialRadialRing.cpp b/src/model/GModelSpatialRadialRing.cpp index 548b6f5..46658d1 100644 --- a/src/model/GModelSpatialRadialRing.cpp +++ b/src/model/GModelSpatialRadialRing.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialRadialRing.cpp - Radial ring source model class * * ----------------------------------------------------------------------- * - * copyright (C) 2020 by Pierrick Martin * + * copyright (C) 2020-2021 by Pierrick Martin * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -386,11 +386,6 @@ double GModelSpatialRadialRing::theta_max(void) const * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Reads the radial ring model information from an XML element. The XML * element shall have either the format * @@ -415,14 +410,8 @@ double GModelSpatialRadialRing::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialRing::read(const GXmlElement& xml) { - // Determine number of parameter nodes in XML element - int npars = xml.elements("parameter"); - - // Verify that XML element has exactly 4 parameters - if (xml.elements() != 4 || npars != 4) { - throw GException::model_invalid_parnum(G_READ, xml, - "Ring model requires exactly 4 parameters."); - } + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); // Read ring center location GModelSpatialRadial::read(xml); @@ -445,11 +434,6 @@ void GModelSpatialRadialRing::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Writes the radial ring model information into an XML element. The XML * element will have the format * @@ -463,6 +447,9 @@ void GModelSpatialRadialRing::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadialRing::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write ring center location GModelSpatialRadial::write(xml); diff --git a/src/model/GModelSpatialRadialShell.cpp b/src/model/GModelSpatialRadialShell.cpp index 90a3988..a9d1137 100644 --- a/src/model/GModelSpatialRadialShell.cpp +++ b/src/model/GModelSpatialRadialShell.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpatialRadialShell.cpp - Radial shell source model class * * ----------------------------------------------------------------------- * - * copyright (C) 2011-2020 by Christoph Deil * + * copyright (C) 2011-2021 by Christoph Deil * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -435,11 +435,6 @@ double GModelSpatialRadialShell::theta_max(void) const * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Reads the radial shell model information from an XML element. The XML * element shall have either the format * @@ -465,14 +460,8 @@ double GModelSpatialRadialShell::theta_max(void) const ***************************************************************************/ void GModelSpatialRadialShell::read(const GXmlElement& xml) { - // Determine number of parameter nodes in XML element - int npars = xml.elements("parameter"); - - // Verify that XML element has exactly 4 parameters - if (xml.elements() != 4 || npars != 4) { - throw GException::model_invalid_parnum(G_READ, xml, - "Shell model requires exactly 4 parameters."); - } + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); // Read shell location GModelSpatialRadial::read(xml); @@ -495,13 +484,6 @@ void GModelSpatialRadialShell::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spatial - * Existing XML element is not of type 'GaussFunction' - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter names found in XML element. - * * Writes the radial shell model information into an XML element. The XML * element will have the format * @@ -515,6 +497,9 @@ void GModelSpatialRadialShell::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpatialRadialShell::write(GXmlElement& xml) const { + // Verify model type + gammalib::xml_check_type(G_WRITE, xml, type()); + // Write shell location GModelSpatialRadial::write(xml); diff --git a/src/model/GModelSpectral.cpp b/src/model/GModelSpectral.cpp index b1bced0..d6e218d 100644 --- a/src/model/GModelSpectral.cpp +++ b/src/model/GModelSpectral.cpp @@ -131,8 +131,8 @@ GModelSpectral& GModelSpectral::operator=(const GModelSpectral& model) * * @param[in] name Parameter name. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. ***************************************************************************/ GModelPar& GModelSpectral::operator[](const std::string& name) { @@ -146,7 +146,9 @@ GModelPar& GModelSpectral::operator[](const std::string& name) // Throw exception if parameter name was not found if (index >= size()) { - throw GException::par_not_found(G_ACCESS, name); + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return reference @@ -159,8 +161,8 @@ GModelPar& GModelSpectral::operator[](const std::string& name) * * @param[in] name Parameter name. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. ***************************************************************************/ const GModelPar& GModelSpectral::operator[](const std::string& name) const { @@ -174,7 +176,9 @@ const GModelPar& GModelSpectral::operator[](const std::string& name) const // Throw exception if parameter name was not found if (index >= size()) { - throw GException::par_not_found(G_ACCESS, name); + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return reference diff --git a/src/model/GModelSpectralBins.cpp b/src/model/GModelSpectralBins.cpp index 2aee916..473ea87 100644 --- a/src/model/GModelSpectralBins.cpp +++ b/src/model/GModelSpectralBins.cpp @@ -668,17 +668,8 @@ void GModelSpectralBins::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpectralBins::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - std::string msg = "Spectral model type \""+xml.attribute("type")+"\" " - "is not of type \""+type()+"\"."; - throw GException::invalid_value(G_WRITE, msg); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get index parameter GXmlElement* index = gammalib::xml_need_par(G_WRITE, xml, m_index.name()); diff --git a/src/model/GModelSpectralBrokenPlaw.cpp b/src/model/GModelSpectralBrokenPlaw.cpp index 1c991ca..39fb268 100644 --- a/src/model/GModelSpectralBrokenPlaw.cpp +++ b/src/model/GModelSpectralBrokenPlaw.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralBrokenPlaw.cpp - Broken power law spectrum class * * ----------------------------------------------------------------------- * - * copyright (C) 2013-2017 by Anneli Schulz * + * copyright (C) 2013-2021 by Anneli Schulz * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -616,6 +616,9 @@ GEnergy GModelSpectralBrokenPlaw::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralBrokenPlaw::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); + // Get remaining XML parameters const GXmlElement* prefactor = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* index1 = gammalib::xml_get_par(G_READ, xml, m_index1.name()); @@ -638,23 +641,12 @@ void GModelSpectralBrokenPlaw::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralBrokenPlaw::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelSpectralComposite.cpp b/src/model/GModelSpectralComposite.cpp index aa35c07..b317c62 100644 --- a/src/model/GModelSpectralComposite.cpp +++ b/src/model/GModelSpectralComposite.cpp @@ -423,23 +423,12 @@ void GModelSpectralComposite::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralComposite::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Loop over model components for (int i = 0; i < m_spectral.size(); i++) { diff --git a/src/model/GModelSpectralConst.cpp b/src/model/GModelSpectralConst.cpp index 06b7682..608516b 100644 --- a/src/model/GModelSpectralConst.cpp +++ b/src/model/GModelSpectralConst.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralConst.cpp - Spectral constant model class * * ----------------------------------------------------------------------- * - * copyright (C) 2009-2016 by Juergen Knoedlseder * + * copyright (C) 2009-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -424,6 +424,9 @@ GEnergy GModelSpectralConst::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralConst::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 1); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); @@ -440,23 +443,12 @@ void GModelSpectralConst::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of type "ConstantValue" - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralConst::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get normalisation parameter GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelSpectralExpInvPlaw.cpp b/src/model/GModelSpectralExpInvPlaw.cpp index 35914df..f5da27f 100644 --- a/src/model/GModelSpectralExpInvPlaw.cpp +++ b/src/model/GModelSpectralExpInvPlaw.cpp @@ -630,6 +630,9 @@ GEnergy GModelSpectralExpInvPlaw::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralExpInvPlaw::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name()); @@ -652,23 +655,12 @@ void GModelSpectralExpInvPlaw::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralExpInvPlaw::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelSpectralExpPlaw.cpp b/src/model/GModelSpectralExpPlaw.cpp index 027cdb3..d6d4a1b 100644 --- a/src/model/GModelSpectralExpPlaw.cpp +++ b/src/model/GModelSpectralExpPlaw.cpp @@ -600,6 +600,9 @@ GEnergy GModelSpectralExpPlaw::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralExpPlaw::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name()); @@ -622,23 +625,12 @@ void GModelSpectralExpPlaw::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralExpPlaw::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelSpectralExponential.cpp b/src/model/GModelSpectralExponential.cpp index d7cfed5..2434cc2 100644 --- a/src/model/GModelSpectralExponential.cpp +++ b/src/model/GModelSpectralExponential.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralExponential.cpp - Exponential spectral model class * * ----------------------------------------------------------------------- * - * copyright (C) 2018-2020 by Luigi Tibaldo * + * copyright (C) 2018-2021 by Luigi Tibaldo * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -463,9 +463,6 @@ void GModelSpectralExponential::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. The XML element * will have the following format: * @@ -484,16 +481,8 @@ void GModelSpectralExponential::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpectralExponential::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Create a spectrum node xml.append(GXmlElement("spectrum")); diff --git a/src/model/GModelSpectralFunc.cpp b/src/model/GModelSpectralFunc.cpp index 2b04c97..de738bd 100644 --- a/src/model/GModelSpectralFunc.cpp +++ b/src/model/GModelSpectralFunc.cpp @@ -584,11 +584,6 @@ GEnergy GModelSpectralFunc::mc(const GEnergy& emin, * * @param[in] xml XML element containing power law model information. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter name found in XML element. - * * Reads the spectral information from an XML element. The format of the XML * elements is * @@ -598,23 +593,14 @@ GEnergy GModelSpectralFunc::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralFunc::read(const GXmlElement& xml) { - // Verify that XML element has exactly 1 parameter - if (xml.elements() != 1 || xml.elements("parameter") != 1) { - throw GException::model_invalid_parnum(G_READ, xml, - "Spectral function requires exactly 1 parameter."); - } + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 1); - // Get parameter element - const GXmlElement* par = xml.element("parameter", 0); + // Get parameter + const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); - // Get value - if (par->attribute("name") == "Normalization") { - m_norm.read(*par); - } - else { - throw GException::model_invalid_parnames(G_READ, xml, - "Require \"Normalization\" parameter."); - } + // Read parameter + m_norm.read(*norm); // Load nodes from file load_nodes(gammalib::xml_file_expand(xml, xml.attribute("file"))); @@ -629,13 +615,6 @@ void GModelSpectralFunc::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of type "FileFunction" - * @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 * @@ -648,39 +627,14 @@ void GModelSpectralFunc::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpectralFunc::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", "FileFunction"); - } - // Verify model type - if (xml.attribute("type") != "FileFunction") { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \"FileFunction\"."); - } - - // If XML element has 0 nodes then append 1 parameter node - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"Normalization\"")); - } - - // 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 function requires exactly 1 parameter."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); - // Get parameter element - GXmlElement* par = xml.element("parameter", 0); + // Get or create parameter + GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); - // Set parameter - if (par->attribute("name") == "Normalization") { - m_norm.write(*par); - } - else { - throw GException::model_invalid_parnames(G_WRITE, xml, - "Require \"Normalization\" parameter."); - } + // Write parameter + m_norm.write(*norm); // Set file attribute xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename)); @@ -1209,12 +1163,8 @@ void GModelSpectralFunc::free_members(void) * * @param[in] filename File name. * - * @exception GException::file_function_data - * File contains less than 2 nodes - * @exception GException::file_function_columns - * File contains less than 2 columns - * @exception GException::file_function_value - * File contains invalid value + * @exception GException::invalid_value + * Invalid file function ASCII file. * * The file function is stored as a column separated value table (CSV) in an * ASCII file with (at least) 2 columns. The first column specifies the @@ -1245,14 +1195,22 @@ void GModelSpectralFunc::load_nodes(const GFilename& filename) // Check if there are at least 2 nodes if (csv.nrows() < 2) { - throw GException::file_function_data(G_LOAD_NODES, filename.url(), - csv.nrows()); + std::string msg = "File function ASCII file \""+filename.url()+ + "\" contains "+gammalib::str(csv.nrows())+ + " rows but at least 2 rows are required. Please " + "specify a file function ASCII file with at " + "least two rows."; + throw GException::invalid_value(G_LOAD_NODES, msg); } // Check if there are at least 2 columns if (csv.ncols() < 2) { - throw GException::file_function_columns(G_LOAD_NODES, filename.url(), - csv.ncols()); + std::string msg = "File function ASCII file \""+filename.url()+ + "\" contains "+gammalib::str(csv.ncols())+ + " columns but at least 2 columns are required. " + "Please specify a file function ASCII file with " + "at least two columns."; + throw GException::invalid_value(G_LOAD_NODES, msg); } // Setup nodes @@ -1262,25 +1220,39 @@ void GModelSpectralFunc::load_nodes(const GFilename& filename) // Get log10 of node energy and value. Make sure they are valid. double log10energy; double log10value; - if (csv.real(i,0) > 0) { + if (csv.real(i,0) > 0.0) { log10energy = std::log10(csv.real(i,0)); } else { - throw GException::file_function_value(G_LOAD_NODES, filename.url(), - csv.real(i,0), "Energy value must be positive."); + std::string msg = "Non-positive energy "+ + gammalib::str(csv.real(i,0))+" encountered " + "in row "+gammalib::str(i)+" of file " + "function ASCII file. Please specify only " + "positive energies in file function."; + throw GException::invalid_value(G_LOAD_NODES, msg); } - if (csv.real(i,1) > 0) { + if (csv.real(i,1) > 0.0) { log10value = std::log10(csv.real(i,1)); } else { - throw GException::file_function_value(G_LOAD_NODES, filename.url(), - csv.real(i,1), "Intensity value must be positive."); + std::string msg = "Non-positive intensity "+ + gammalib::str(csv.real(i,1))+" encountered " + "in row "+gammalib::str(i)+" of file " + "function ASCII file. Please specify only " + "positive intensities in file function."; + throw GException::invalid_value(G_LOAD_NODES, msg); } // Make sure that energies are increasing if (csv.real(i,0) <= last_energy) { - throw GException::file_function_value(G_LOAD_NODES, filename.url(), - csv.real(i,0), "Energy values must be monotonically increasing."); + std::string msg = "Energy "+gammalib::str(csv.real(i,0))+ + "in row "+gammalib::str(i)+" of file " + "function ASCII file is equal or smaller " + "than preceding energy "+ + gammalib::str(last_energy)+". Please specify " + "monotonically increasing energies in the " + "file function ASCII file."; + throw GException::invalid_value(G_LOAD_NODES, msg); } // Append log10 of node energy and value diff --git a/src/model/GModelSpectralGauss.cpp b/src/model/GModelSpectralGauss.cpp index 8307fe5..dc18ee3 100644 --- a/src/model/GModelSpectralGauss.cpp +++ b/src/model/GModelSpectralGauss.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralGauss.cpp - Spectral Gaussian model class * * ----------------------------------------------------------------------- * - * copyright (C) 2014-2019 by Christoph Deil & Ellis Owen * + * copyright (C) 2014-2021 by Christoph Deil & Ellis Owen * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -485,11 +485,6 @@ GEnergy GModelSpectralGauss::mc(const GEnergy& emin, * * @param[in] xml XML element containing Gaussian model information. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter name found in XML element. - * * Read the spectral Gaussian information from an XML element. * The format of the XML elements is: * @@ -502,6 +497,9 @@ GEnergy GModelSpectralGauss::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralGauss::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 3); + // Get parameters const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* mean = gammalib::xml_get_par(G_READ, xml, m_mean.name()); @@ -522,13 +520,6 @@ void GModelSpectralGauss::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of type "Gaussian" - * @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 * @@ -540,16 +531,8 @@ void GModelSpectralGauss::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpectralGauss::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelSpectralLogParabola.cpp b/src/model/GModelSpectralLogParabola.cpp index 23e5e9e..b67efa3 100644 --- a/src/model/GModelSpectralLogParabola.cpp +++ b/src/model/GModelSpectralLogParabola.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralLogParabola.cpp - Log parabola spectral model class * * ----------------------------------------------------------------------- * - * copyright (C) 2012-2016 by Michael Mayer * + * copyright (C) 2012-2021 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -578,6 +578,9 @@ GEnergy GModelSpectralLogParabola::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralLogParabola::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name()); @@ -612,23 +615,12 @@ void GModelSpectralLogParabola::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of type "LogParabola" - * * Write the LogParabola model information into an XML element. ***************************************************************************/ void GModelSpectralLogParabola::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Check if parameters are Fermi/LAT style and need to be negated GModelPar inx = m_index; diff --git a/src/model/GModelSpectralMultiplicative.cpp b/src/model/GModelSpectralMultiplicative.cpp index 5eff7f4..911ba19 100644 --- a/src/model/GModelSpectralMultiplicative.cpp +++ b/src/model/GModelSpectralMultiplicative.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralMultiplicative.cpp - Multiplicative spectral model class * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2020 by Michael Mayer * + * copyright (C) 2016-2021 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -469,23 +469,12 @@ void GModelSpectralMultiplicative::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralMultiplicative::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Loop over model components for (int i = 0; i < m_spectral.size(); i++) { @@ -630,6 +619,9 @@ const GModelSpectral* GModelSpectralMultiplicative::component(const int& index) * @param[in] name Name of spectral component. * @return Pointer to spectral model. * + * @exception GException::invalid_argument + * Model component not found. + * * Returns a component of the multiplicative spectral model by @p name. ***************************************************************************/ const GModelSpectral* GModelSpectralMultiplicative::component(const std::string& name) const @@ -645,7 +637,9 @@ const GModelSpectral* GModelSpectralMultiplicative::component(const std::string& // Check if component name was found if (index == -1) { - throw GException::model_not_found(G_COMPONENT_NAME, name); + std::string msg = "Model component \""+name+"\" not found. Please " + "specify a valid model component name."; + throw GException::invalid_argument(G_COMPONENT_NAME, msg); } // Return spectral component diff --git a/src/model/GModelSpectralNodes.cpp b/src/model/GModelSpectralNodes.cpp index a278f30..bf3c86f 100644 --- a/src/model/GModelSpectralNodes.cpp +++ b/src/model/GModelSpectralNodes.cpp @@ -598,10 +598,8 @@ GEnergy GModelSpectralNodes::mc(const GEnergy& emin, * * @param[in] xml XML element. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter name found in XML element. + * @exception GException::invalid_value + * Not enough nodes in node function. * @exception GException::invalid_value * Energy or intensity are not positive. * @@ -622,6 +620,7 @@ GEnergy GModelSpectralNodes::mc(const GEnergy& emin, * * @todo Check that nodes are ordered * @todo Check that energy boundaries are not overlapping + * @todo Check whether we require at least one or two nodes ***************************************************************************/ void GModelSpectralNodes::read(const GXmlElement& xml) { @@ -634,9 +633,10 @@ void GModelSpectralNodes::read(const GXmlElement& xml) // Throw an error if there not at least two nodes if (nodes < 1) { - std::string message = "Node function model requires at least two" - " nodes."; - throw GException::model_invalid_parnum(G_READ, xml, message); + std::string msg = "Node function model contains "+gammalib::str(nodes)+ + " but requires at least one node. Please specify at " + "least one node."; + throw GException::invalid_value(G_READ, msg); } // Loop over all nodes @@ -710,10 +710,8 @@ void GModelSpectralNodes::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spectral - * 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::invalid_value + * Invalid number of nodes found in XML element. * * Writes the spectral information into an XML element. The format of the XML * element is @@ -735,16 +733,8 @@ void GModelSpectralNodes::write(GXmlElement& xml) const // Determine number of nodes int nodes = m_energies.size(); - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // If XML element has 0 nodes then append nodes if (xml.elements() == 0) { @@ -754,10 +744,20 @@ void GModelSpectralNodes::write(GXmlElement& xml) const } // Verify that XML element has the required number of nodes - if (xml.elements() != nodes || xml.elements("node") != nodes) { - std::string message = "Spectral model requires exactly " + - gammalib::str(nodes) + " nodes."; - throw GException::model_invalid_parnum(G_WRITE, xml, message); + if (xml.elements() != nodes) { + std::string msg = "Number of "+gammalib::str(xml.elements())+ + " child elements in XML file does not correspond " + "to expected number of "+gammalib::str(nodes)+ + " elements. Please verify the XML format."; + throw GException::invalid_value(G_WRITE, msg); + } + int npars = xml.elements("node"); + if (npars != nodes) { + std::string msg = "Number of "+gammalib::str(npars)+" \"node\" " + "child elements in XML file does not correspond to " + "expected number of "+gammalib::str(nodes)+ + " elements. Please verify the XML format."; + throw GException::invalid_value(G_WRITE, msg); } // Loop over all nodes diff --git a/src/model/GModelSpectralPlaw.cpp b/src/model/GModelSpectralPlaw.cpp index a81ac97..095e728 100644 --- a/src/model/GModelSpectralPlaw.cpp +++ b/src/model/GModelSpectralPlaw.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralPlaw.cpp - Spectral power law model class * * ----------------------------------------------------------------------- * - * copyright (C) 2009-2020 by Juergen Knoedlseder * + * copyright (C) 2009-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -513,6 +513,9 @@ GEnergy GModelSpectralPlaw::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralPlaw::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 3); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name()); @@ -533,23 +536,12 @@ void GModelSpectralPlaw::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralPlaw::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelSpectralPlawEnergyFlux.cpp b/src/model/GModelSpectralPlawEnergyFlux.cpp index 89658dd..ab74c63 100644 --- a/src/model/GModelSpectralPlawEnergyFlux.cpp +++ b/src/model/GModelSpectralPlawEnergyFlux.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralPlawEnergyFlux.cpp - Spectral power law model class * * ----------------------------------------------------------------------- * - * copyright (C) 2016-2020 by Michael Mayer * + * copyright (C) 2016-2021 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -567,6 +567,9 @@ GEnergy GModelSpectralPlawEnergyFlux::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralPlawEnergyFlux::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); + // Get parameter pointers const GXmlElement* eflux = gammalib::xml_get_par(G_READ, xml, m_eflux.name()); const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name()); @@ -589,23 +592,12 @@ void GModelSpectralPlawEnergyFlux::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of type "PowerLaw" - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralPlawEnergyFlux::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* eflux = gammalib::xml_need_par(G_WRITE, xml, m_eflux.name()); diff --git a/src/model/GModelSpectralPlawPhotonFlux.cpp b/src/model/GModelSpectralPlawPhotonFlux.cpp index d032b8a..6b8f864 100644 --- a/src/model/GModelSpectralPlawPhotonFlux.cpp +++ b/src/model/GModelSpectralPlawPhotonFlux.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelSpectralPlawPhotonFlux.cpp - Spectral power law model class * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2016 by Juergen Knoedlseder * + * copyright (C) 2010-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -577,6 +577,9 @@ GEnergy GModelSpectralPlawPhotonFlux::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralPlawPhotonFlux::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 4); + // Get parameter pointers const GXmlElement* flux = gammalib::xml_get_par(G_READ, xml, m_flux.name()); const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name()); @@ -599,23 +602,12 @@ void GModelSpectralPlawPhotonFlux::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of type "PowerLaw" - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralPlawPhotonFlux::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* flux = gammalib::xml_need_par(G_WRITE, xml, m_flux.name()); diff --git a/src/model/GModelSpectralSmoothBrokenPlaw.cpp b/src/model/GModelSpectralSmoothBrokenPlaw.cpp index 715ea68..91d7593 100644 --- a/src/model/GModelSpectralSmoothBrokenPlaw.cpp +++ b/src/model/GModelSpectralSmoothBrokenPlaw.cpp @@ -2,7 +2,7 @@ * GModelSpectralSmoothBrokenPlaw.cpp * * Smoothly broken power law spectrum class * * ----------------------------------------------------------------------- * - * copyright (C) 2017-2018 by Joshua Cardenzana * + * copyright (C) 2017-2021 by Joshua Cardenzana * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -623,6 +623,9 @@ GEnergy GModelSpectralSmoothBrokenPlaw::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralSmoothBrokenPlaw::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 6); + // Get remaining XML parameters const GXmlElement* prefactor = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* index1 = gammalib::xml_get_par(G_READ, xml, m_index1.name()); @@ -649,24 +652,13 @@ void GModelSpectralSmoothBrokenPlaw::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralSmoothBrokenPlaw::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } - + gammalib::xml_check_type(G_WRITE, xml, type()); + // 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()); diff --git a/src/model/GModelSpectralSuperExpPlaw.cpp b/src/model/GModelSpectralSuperExpPlaw.cpp index 53292bc..c8c710d 100644 --- a/src/model/GModelSpectralSuperExpPlaw.cpp +++ b/src/model/GModelSpectralSuperExpPlaw.cpp @@ -625,6 +625,9 @@ GEnergy GModelSpectralSuperExpPlaw::mc(const GEnergy& emin, ***************************************************************************/ void GModelSpectralSuperExpPlaw::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 5); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* index1 = gammalib::xml_get_par(G_READ, xml, m_index1.name()); @@ -649,23 +652,12 @@ void GModelSpectralSuperExpPlaw::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of the expected type. - * * Writes the spectral information into an XML element. ***************************************************************************/ void GModelSpectralSuperExpPlaw::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelSpectralTable.cpp b/src/model/GModelSpectralTable.cpp index ae7f790..2f195f9 100644 --- a/src/model/GModelSpectralTable.cpp +++ b/src/model/GModelSpectralTable.cpp @@ -704,11 +704,6 @@ GEnergy GModelSpectralTable::mc(const GEnergy& emin, * * @param[in] xml XML element containing power law model information. * - * @exception GException::model_invalid_parnum - * Invalid number of model parameters found in XML element. - * @exception GException::model_invalid_parnames - * Invalid model parameter name found in XML element. - * * Reads the spectral information from an XML element. The format of the XML * elements is * @@ -749,13 +744,6 @@ void GModelSpectralTable::read(const GXmlElement& xml) * * @param[in] xml XML element into which model information is written. * - * @exception GException::model_invalid_spectral - * Existing XML element is not of type "FileFunction" - * @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 * @@ -771,16 +759,8 @@ void GModelSpectralTable::read(const GXmlElement& xml) ***************************************************************************/ void GModelSpectralTable::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Spectral model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get normalisation parameter GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelTemporal.cpp b/src/model/GModelTemporal.cpp index 4149fef..0538a3d 100644 --- a/src/model/GModelTemporal.cpp +++ b/src/model/GModelTemporal.cpp @@ -130,21 +130,25 @@ GModelTemporal& GModelTemporal::operator=(const GModelTemporal& model) * * @param[in] name Parameter name. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. ***************************************************************************/ GModelPar& GModelTemporal::operator[](const std::string& name) { // Get parameter index int index = 0; for (; index < size(); ++index) { - if (m_pars[index]->name() == name) + if (m_pars[index]->name() == name) { break; + } } // Throw exception if parameter name was not found - if (index >= size()) - throw GException::par_not_found(G_ACCESS, name); + if (index >= size()) { + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); + } // Return reference return *(m_pars[index]); @@ -156,21 +160,25 @@ GModelPar& GModelTemporal::operator[](const std::string& name) * * @param[in] name Parameter name. * - * @exception GException::par_not_found - * Parameter with specified name not found in container. + * @exception GException::invalid_argument + * Parameter with specified name not found. ***************************************************************************/ const GModelPar& GModelTemporal::operator[](const std::string& name) const { // Get parameter index int index = 0; for (; index < size(); ++index) { - if (m_pars[index]->name() == name) + if (m_pars[index]->name() == name) { break; + } } // Throw exception if parameter name was not found - if (index >= size()) - throw GException::par_not_found(G_ACCESS, name); + if (index >= size()) { + std::string msg = "Model parameter \""+name+"\" not found in model. " + "Please specify a valid model parameter name."; + throw GException::invalid_argument(G_ACCESS, msg); + } // Return reference return *(m_pars[index]); diff --git a/src/model/GModelTemporalConst.cpp b/src/model/GModelTemporalConst.cpp index 2974ef9..8ed8963 100644 --- a/src/model/GModelTemporalConst.cpp +++ b/src/model/GModelTemporalConst.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelTemporalConst.cpp - Temporal constant model class * * ----------------------------------------------------------------------- * - * copyright (C) 2009-2018 by Juergen Knoedlseder * + * copyright (C) 2009-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -315,9 +315,6 @@ GTimes GModelTemporalConst::mc(const double& rate, const GTime& tmin, * * @param[in] xml XML element. * - * @exception GExpection::invalid_value - * Invalid XML format encountered. - * * Writes the temporal information from an XML element having the format * * @@ -326,6 +323,9 @@ GTimes GModelTemporalConst::mc(const double& rate, const GTime& tmin, ***************************************************************************/ void GModelTemporalConst::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 1); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); @@ -342,9 +342,6 @@ void GModelTemporalConst::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GExpection::invalid_value - * Invalid XML format encountered. - * * Writes the temporal information into an XML element in the format * * @@ -353,16 +350,8 @@ void GModelTemporalConst::read(const GXmlElement& xml) ***************************************************************************/ void GModelTemporalConst::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), - "Temporal model is not of type \""+type()+"\"."); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelTemporalLightCurve.cpp b/src/model/GModelTemporalLightCurve.cpp index a98499f..898b2cc 100644 --- a/src/model/GModelTemporalLightCurve.cpp +++ b/src/model/GModelTemporalLightCurve.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GModelTemporalLightCurve.cpp - Temporal light curve model class * * ----------------------------------------------------------------------- * - * copyright (C) 2017-2020 by Juergen Knoedlseder * + * copyright (C) 2017-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -373,6 +373,9 @@ GTimes GModelTemporalLightCurve::mc(const double& rate, const GTime& tmin, ***************************************************************************/ void GModelTemporalLightCurve::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 1); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); @@ -392,9 +395,6 @@ void GModelTemporalLightCurve::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GExpection::invalid_value - * Invalid XML format encountered. - * * Writes the temporal information into an XML element in the format * * @@ -403,17 +403,8 @@ void GModelTemporalLightCurve::read(const GXmlElement& xml) ***************************************************************************/ void GModelTemporalLightCurve::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - std::string msg = "Temporal model of type "+xml.attribute("type")+ - " encountered while \""+type()+"\" was expected."; - throw GException::invalid_value(G_WRITE, msg); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModelTemporalPhaseCurve.cpp b/src/model/GModelTemporalPhaseCurve.cpp index 13b33aa..276402a 100644 --- a/src/model/GModelTemporalPhaseCurve.cpp +++ b/src/model/GModelTemporalPhaseCurve.cpp @@ -375,6 +375,9 @@ GTimes GModelTemporalPhaseCurve::mc(const double& rate, const GTime& tmin, ***************************************************************************/ void GModelTemporalPhaseCurve::read(const GXmlElement& xml) { + // Verify number of model parameters + gammalib::xml_check_parnum(G_READ, xml, 6); + // Get parameter pointers const GXmlElement* norm = gammalib::xml_get_par(G_READ, xml, m_norm.name()); const GXmlElement* mjd = gammalib::xml_get_par(G_READ, xml, m_mjd.name()); @@ -415,9 +418,6 @@ void GModelTemporalPhaseCurve::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GExpection::invalid_value - * Invalid XML format encountered. - * * Writes the temporal information into an XML element. The XML element will * have the format * @@ -432,17 +432,8 @@ void GModelTemporalPhaseCurve::read(const GXmlElement& xml) ***************************************************************************/ void GModelTemporalPhaseCurve::write(GXmlElement& xml) const { - // Set model type - if (xml.attribute("type") == "") { - xml.attribute("type", type()); - } - // Verify model type - if (xml.attribute("type") != type()) { - std::string msg = "Temporal model of type "+xml.attribute("type")+ - " encountered while \""+type()+"\" was expected."; - throw GException::invalid_value(G_WRITE, msg); - } + gammalib::xml_check_type(G_WRITE, xml, type()); // Get XML parameters GXmlElement* norm = gammalib::xml_need_par(G_WRITE, xml, m_norm.name()); diff --git a/src/model/GModels.cpp b/src/model/GModels.cpp index 1cb659b..1edd18f 100644 --- a/src/model/GModels.cpp +++ b/src/model/GModels.cpp @@ -170,7 +170,7 @@ GModels& GModels::operator=(const GModels& models) * * @param[in] name Model name. * - * @exception GException::model_not_found + * @exception GException::invalid_argument * Model with specified name not found in container. * * Returns a pointer to the model with the specified @p name. @@ -182,7 +182,9 @@ GModel* GModels::operator[](const std::string& name) // Throw exception if model name was not found if (index == -1) { - throw GException::model_not_found(G_ACCESS, name); + std::string msg = "Model \""+name+"\" not found in model container. " + "Please specify the name of an available model."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return pointer @@ -195,7 +197,7 @@ GModel* GModels::operator[](const std::string& name) * * @param[in] name Model name. * - * @exception GException::model_not_found + * @exception GException::invalid_argument * Model with specified name not found in container. * * Returns a const pointer to the model with the specified @p name. @@ -207,7 +209,9 @@ const GModel* GModels::operator[](const std::string& name) const // Throw exception if model name was not found if (index == -1) { - throw GException::model_not_found(G_ACCESS, name); + std::string msg = "Model \""+name+"\" not found in model container. " + "Please specify the name of an available model."; + throw GException::invalid_argument(G_ACCESS, msg); } // Return pointer @@ -356,7 +360,7 @@ GModel* GModels::set(const int& index, const GModel& model) * @param[in] model Model pointer. * @return Pointer to deep copy of model. * - * @exception GException::model_not_found + * @exception GException::invalid_argument * Model with specified name not found in container. * @exception GException::invalid_value * Name of model exists already in container. @@ -370,7 +374,9 @@ GModel* GModels::set(const std::string& name, const GModel& model) // Throw exception if parameter name was not found if (index == -1) { - throw GException::model_not_found(G_SET2, name); + std::string msg = "Model \""+name+"\" not found in model container. " + "Please specify the name of an available model."; + throw GException::invalid_argument(G_SET2, msg); } // Check if a model with specified name does not yet exist @@ -498,7 +504,7 @@ GModel* GModels::insert(const int& index, const GModel& model) * @param[in] model Model. * @return Pointer to deep copy of model. * - * @exception GException::model_not_found + * @exception GException::invalid_argument * Model with specified name not found in container. * @exception GException::invalid_value * Name of model exists already in container. @@ -513,7 +519,9 @@ GModel* GModels::insert(const std::string& name, const GModel& model) // Throw exception if parameter name was not found if (index == -1) { - throw GException::model_not_found(G_INSERT2, name); + std::string msg = "Model \""+name+"\" not found in model container. " + "Please specify the name of an available model."; + throw GException::invalid_argument(G_INSERT2, msg); } // Check if a model with specified name does not yet exist @@ -575,7 +583,7 @@ void GModels::remove(const int& index) * * @param[in] name Model name. * - * @exception GException::model_not_found + * @exception GException::invalid_argument * Model with specified name not found in container. * * Remove model of specified @p name from container. @@ -587,7 +595,9 @@ void GModels::remove(const std::string& name) // Throw exception if parameter name was not found if (index == -1) { - throw GException::model_not_found(G_REMOVE2, name); + std::string msg = "Model \""+name+"\" not found in model container. " + "Please specify the name of an available model."; + throw GException::invalid_argument(G_REMOVE2, msg); } // Delete model @@ -739,7 +749,7 @@ void GModels::save(const GFilename& filename) const * * @param[in] xml XML document. * - * @exception GException::model_invalid + * @exception GException::invalid_value * Invalid model type encountered. * * Read models from the first source library found in the XML document. The @@ -786,7 +796,17 @@ void GModels::read(const GXml& xml) // ... otherwise throw an exception else { - throw GException::model_invalid(G_READ, type); + std::string msg = "No model of type \""+type+"\" found in model " + "registry. Please specify one of the following " + "model types:"; + for (int i = 0; i < registry.size(); ++i) { + if (i != 0) { + msg += ","; + } + msg += " \""+registry.name(i)+"\""; + } + msg += "."; + throw GException::invalid_value(G_READ, msg); } // Append model diff --git a/src/model/Makefile.am b/src/model/Makefile.am index d2e841e..912a8cd 100644 --- a/src/model/Makefile.am +++ b/src/model/Makefile.am @@ -80,8 +80,7 @@ sources = GModelPar.cpp \ GModelTemporalRegistry.cpp \ GModelTemporalConst.cpp \ GModelTemporalLightCurve.cpp \ - GModelTemporalPhaseCurve.cpp \ - GException_model.cpp + GModelTemporalPhaseCurve.cpp # Build libtool library noinst_LTLIBRARIES = libmodel.la diff --git a/src/obs/GCaldb.cpp b/src/obs/GCaldb.cpp index fc0e4d8..30a2661 100644 --- a/src/obs/GCaldb.cpp +++ b/src/obs/GCaldb.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCaldb.cpp - Calibration database class * * ----------------------------------------------------------------------- * - * copyright (C) 2011-2016 by Juergen Knoedlseder * + * copyright (C) 2011-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -242,10 +242,8 @@ int GCaldb::size(void) const /***********************************************************************//** * @brief Return path to CALDB root directory * - * @exception GException::directory_not_found - * Calibration directory not found. - * @exception GException::directory_not_accessible - * No read permission granted to calibration directory. + * @exception GException::invalid_value + * CALDB environment variable not set * * The calibration directory path is given by one of the following * @@ -271,10 +269,10 @@ std::string GCaldb::rootdir(void) const // Throw an exception if non of the environment variables was set if (ptr1 == NULL) { - throw GException::env_not_found(G_GET_ROOTDIR, - "CALDB", - "Please set the CALDB environment" - " variable to a valid calibration database root directory."); + std::string msg = "CALDB environment value not found. Please set " + "the CALDB environment variable to a valid " + "calibration database root directory."; + throw GException::invalid_value(G_GET_ROOTDIR, msg); } // If CALDB was set then check whether the directory exists @@ -296,9 +294,9 @@ std::string GCaldb::rootdir(void) const * * @param[in] pathname Calibration database root directory. * - * @exception GException::directory_not_found + * @exception GException::invalid_argument * Calibration database root directory not found. - * @exception GException::directory_not_accessible + * @exception GException::invalid_value * No read permission granted for calibration database root * directory. * @@ -312,13 +310,19 @@ void GCaldb::rootdir(const std::string& pathname) // Verify that specified root directory exists if (!gammalib::dir_exists(rootdir)) { - throw GException::directory_not_found(G_SET_ROOTDIR, rootdir); + std::string msg = "Calibration database root directory \""+ + rootdir+"\" not found. Please specify a valid " + "root directory name."; + throw GException::invalid_argument(G_SET_ROOTDIR, msg); } // Verify that specified root directory allows read access if (access(rootdir.c_str(), R_OK) != 0) { - throw GException::directory_not_accessible(G_SET_ROOTDIR, rootdir, - "Requested read permission not granted."); + std::string msg = "Calibration database root directory \""+ + rootdir+"\" is not accessible for read access. " + "Please provide read access to the calibration " + "database root directory."; + throw GException::invalid_value(G_SET_ROOTDIR, msg); } // Set calibration database root directory @@ -335,9 +339,9 @@ void GCaldb::rootdir(const std::string& pathname) * @param[in] mission Mission name (case insensitive). * @param[in] instrument Instrument name (case insensitive; optional). * - * @exception GException::directory_not_found + * @exception GException::invalid_argument * Calibration directory not found. - * @exception GException::directory_not_accessible + * @exception GException::invalid_value * No read permission granted to calibration directory. * * The calibration directory path is given by one of the following @@ -354,14 +358,19 @@ std::string GCaldb::path(const std::string& mission, const std::string& instrume // Verify that mission name is valid and directory is accessible std::string path = rootdir() + "/data/" + gammalib::tolower(mission); if (!gammalib::dir_exists(path)) { - throw GException::directory_not_found(G_PATH, path, - "Requested mission \""+gammalib::toupper(mission)+"\" not found in" - " calibration database."); + std::string msg = "Requested mission \""+gammalib::toupper(mission)+ + "\" not found in calibration database. Please " + "specify an available mission or add mission to " + "calibration database."; + throw GException::invalid_argument(G_PATH, msg); } if (access(path.c_str(), R_OK) != 0) { - throw GException::directory_not_accessible(G_PATH, path, - "Requested read permission not granted for mission \""+ - gammalib::toupper(mission)+"\"."); + std::string msg = "Calibration database directory \""+path+"\" for " + " mission \""+gammalib::toupper(mission)+"\" is " + "not accessible for read access. Please provide " + "read access to the calibration database " + "directory."; + throw GException::invalid_value(G_PATH, msg); } // If an instrument has been specified, verify that instrument name is @@ -373,16 +382,24 @@ std::string GCaldb::path(const std::string& mission, const std::string& instrume // Verify path if (!gammalib::dir_exists(path)) { - throw GException::directory_not_found(G_PATH, path, - "Requested instrument \""+gammalib::toupper(instrument)+"\" on" - " mission \""+gammalib::toupper(mission)+"\" not found in" - " calibration database."); + std::string msg = "Requested instrument \""+ + gammalib::toupper(instrument)+ + "\" on mission \""+ + gammalib::toupper(mission)+"\" not found in " + "calibration database. Please specify an " + "available instrument or add instrument to " + "calibration database."; + throw GException::invalid_argument(G_PATH, msg); } if (access(path.c_str(), R_OK) != 0) { - throw GException::directory_not_accessible(G_PATH, path, - "Requested read permission not granted for instrument \""+ - gammalib::toupper(instrument)+"\" on mission \""+gammalib::toupper(mission)+ - "\"."); + std::string msg = "Calibration database directory \""+path+"\" for " + "instrument \""+gammalib::toupper(instrument)+ + "\" on mission \""+ + gammalib::toupper(mission)+"\" is not " + "accessible for read access. Please provide " + "read access to the calibration database " + "directory."; + throw GException::invalid_value(G_PATH, msg); } } // endif: instrument has been specified diff --git a/src/sky/GSkyRegions.cpp b/src/sky/GSkyRegions.cpp index 4d7bcee..f237a0a 100644 --- a/src/sky/GSkyRegions.cpp +++ b/src/sky/GSkyRegions.cpp @@ -506,8 +506,8 @@ bool GSkyRegions::overlaps(const GSkyRegions& regions) const * * @param[in] filename DS9 region filename. * - * @exception GException::file_open_error - * File could not be opened. + * @exception GException::file_error + * Unable to open file. * * Loads all regions from a DS9 region file. ***************************************************************************/ @@ -604,7 +604,9 @@ void GSkyRegions::load(const GFilename& filename) // File could not be opened else { - throw GException::file_open_error(G_LOAD, filename.url()); + std::string msg = "Unable to open file \""+filename.url()+"\". Please " + "specify a valid file name."; + throw GException::file_error(G_LOAD, msg); } // Return @@ -617,8 +619,8 @@ void GSkyRegions::load(const GFilename& filename) * * @param[in] filename DS9 region filename. * - * @exception GException::file_open_error - * File could not be opened. + * @exception GException::file_error + * Unable to open file. * * Saves all regions in the container into a DS9 region file. ***************************************************************************/ @@ -652,7 +654,9 @@ void GSkyRegions::save(const GFilename& filename) const // ... otherwise, if file could not be opened then throw an exception else { - throw GException::file_open_error(G_SAVE, filename.url()); + std::string msg = "Unable to open file \""+filename.url()+"\". Please " + "specify a valid file name."; + throw GException::file_error(G_SAVE, msg); } // Return diff --git a/src/support/GCsv.cpp b/src/support/GCsv.cpp index 723286c..7ad2a9a 100644 --- a/src/support/GCsv.cpp +++ b/src/support/GCsv.cpp @@ -412,7 +412,7 @@ void GCsv::integer(const int& row, const int& col, const int& value) * @param[in] filename Filename. * @param[in] sep Column separator (default is whitespace). * - * @exception GException::file_not_found + * @exception GException::file_error * CSV table file not found. * @exception GException::csv_bad_columns * Inconsistent columns encountered in CSV table file. @@ -435,7 +435,9 @@ void GCsv::load(const GFilename& filename, const std::string& sep) // Open CSV table (read-only) FILE* fptr = std::fopen(fname.c_str(), "r"); if (fptr == NULL) { - throw GException::file_not_found(G_LOAD, fname); + std::string msg = "Unable to open file \""+fname+"\" for read access. " + "Please specify a readable file."; + throw GException::file_error(G_LOAD, msg); } // Read lines @@ -475,8 +477,12 @@ void GCsv::load(const GFilename& filename, const std::string& sep) else { // Check table consistency if (m_cols != elements.size()) { - throw GException::csv_bad_columns(G_LOAD, fname, - iline, m_cols, elements.size()); + std::string msg = "Number of "+gammalib::str(elements.size())+ + " columns in row "+gammalib::str(iline)+ + " is not consistent with number of "+ + gammalib::str(m_cols)+" in first row. Please " + "specify a correctly formatted CSV file."; + throw GException::invalid_value(G_LOAD, msg); } // Append elements diff --git a/src/support/GException.cpp b/src/support/GException.cpp index 567659f..f0e8362 100644 --- a/src/support/GException.cpp +++ b/src/support/GException.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GException.cpp - exception handlers * * ----------------------------------------------------------------------- * - * copyright (C) 2006-2017 by Juergen Knoedlseder * + * copyright (C) 2006-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -90,6 +90,35 @@ GException::invalid_argument::invalid_argument(const std::string& origin, /***********************************************************************//** + * @brief Invalid argument + * + * @param[in] origin Name of method that has thrown the exception. + * @param[in] argument Argument name. + * @param[in] message Optional message. + * + * This exception signals that a specified argument was not valid. + ***************************************************************************/ +GException::invalid_argument::invalid_argument(const std::string& origin, + const std::string& argument, + const std::string& message) +{ + // Set origin + m_origin = origin; + + // Set message string + m_message = "Invalid argument \""+argument+"\" value."; + + // Add optional error message + if (message.length() > 0) { + m_message += (" " + message); + } + + // Return + return; +} + + +/***********************************************************************//** * @brief Invalid return value * * @param[in] origin Name of method that has thrown the exception. @@ -199,7 +228,7 @@ GException::fits_error::fits_error(const std::string& origin, // Add optional error message if (message.length() > 0) { - m_message += " " + message; + m_message += (" " + message); } // Return @@ -261,245 +290,3 @@ GException::feature_not_implemented::feature_not_implemented(const std::string& // Return return; } - - -/***********************************************************************//** - * @brief Invalid argument - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] argument Argument name. - * @param[in] message Optional message. - * - * This exception signals that a specified argument was not valid. - ***************************************************************************/ -GException::invalid_argument::invalid_argument(const std::string& origin, - const std::string& argument, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Invalid argument \""+argument+"\" value."; - - // Add optional error message - if (message.length() > 0) { - m_message += " " + message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Invalid type conversion - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional message. - ***************************************************************************/ -GException::bad_type::bad_type(std::string origin, std::string message) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Invalid type conversion."; - if (message.length() > 0) { - m_message += " " + message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Environment variable not found - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] envname Name of environment variable. - * @param[in] message Optional message. - * - * This exception signals that are required environment variable was not - * found. - ***************************************************************************/ -GException::env_not_found::env_not_found(std::string origin, - std::string envname, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Environment variable \""+envname+"\" not found."; - if (message.length() > 0) { - m_message += " " + message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Memory allocation exception. - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] num Requested amount of memory. - ***************************************************************************/ -GException::mem_alloc::mem_alloc(std::string origin, unsigned num) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Memory allocation error (" + gammalib::str((int)num) + " elements)"; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Not enough nodes in node array - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] num Number of nodes in node array. - ***************************************************************************/ -GException::not_enough_nodes::not_enough_nodes(std::string origin, int num) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Not enough nodes in node array (" + gammalib::str(num) + " nodes)."; - - // Return - return; -} - - -/***********************************************************************//** - * @brief File not found - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] filename Filename. - * @param[in] message Optional message. - ***************************************************************************/ -GException::file_not_found::file_not_found(std::string origin, - std::string filename, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "File \"" + filename +"\" not found."; - if (message.length() > 0) { - m_message += " " + message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief File open error - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] filename Filename. - * @param[in] message Optional message. - ***************************************************************************/ -GException::file_open_error::file_open_error(std::string origin, - std::string filename, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Unable to open file \"" + filename +"\""; - if (message.length() > 0) { - m_message += " " + message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Directory not found - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] dirname Directory name. - * @param[in] message Optional message. - ***************************************************************************/ -GException::directory_not_found::directory_not_found(std::string origin, - std::string dirname, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Directory \"" + dirname +"\" not found."; - if (message.length() > 0) { - m_message += " " + message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Directory not accessible - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] dirname Directory name. - * @param[in] message Optional message. - ***************************************************************************/ -GException::directory_not_accessible::directory_not_accessible(std::string origin, - std::string dirname, - std::string message) -{ - // Set origin - m_origin = origin; - - // Set message string - m_message = "Directory \"" + dirname +"\" not accessible."; - if (message.length() > 0) { - m_message += " " + message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Bad CSV columns encountered - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] filename Filename. - * @param[in] row CSV file row. - * @param[in] cols Expected number of columns. - * @param[in] elements Found number of columns. - * @param[in] message Optional message. - ***************************************************************************/ -GException::csv_bad_columns::csv_bad_columns(std::string origin, - std::string filename, - int row, - int cols, - int elements, - std::string message) -{ - m_origin = origin; - m_message = "Inconsistent number of columns found in row "+gammalib::str(row)+ - " of file \""+filename+"\" ("+gammalib::str(cols)+" expected, "+ - gammalib::str(elements)+" encountered). "+message; - return; -} diff --git a/src/support/GNodeArray.cpp b/src/support/GNodeArray.cpp index 5892fd0..6eb0a09 100644 --- a/src/support/GNodeArray.cpp +++ b/src/support/GNodeArray.cpp @@ -525,7 +525,7 @@ void GNodeArray::nodes(const std::vector& vector) * @param[in] value Value \f$x\f$ at which interpolation should be done. * @param[in] vector Vector \f$y_i\f$ that should be interpolated. * - * @exception GException::not_enough_nodes + * @exception GException::invalid_value * Not enough nodes for interpolation in node array. * @exception GException::invalid_argument * Size of node vector does not match the size of vector argument. @@ -538,7 +538,11 @@ double GNodeArray::interpolate(const double& value, { // Throw exception if there are not enough nodes if (m_node.size() < 2) { - throw GException::not_enough_nodes(G_INTERPOLATE, m_node.size()); + std::string msg = "There are "+gammalib::str(m_node.size())+" nodes " + "in node array, yet at least 2 nodes are required " + "for interpolation. Please specify more nodes " + "before calling the method."; + throw GException::invalid_value(G_INTERPOLATE, msg); } // Throw exception if vectors have not the same size diff --git a/src/support/GTools.cpp b/src/support/GTools.cpp index 9478d22..652bf41 100644 --- a/src/support/GTools.cpp +++ b/src/support/GTools.cpp @@ -1695,6 +1695,82 @@ std::string gammalib::xml_get_attr(const std::string& origin, /***********************************************************************//** + * @brief Checks number of parameters + * + * @param[in] origin Method performing the check. + * @param[in] xml XML element. + * @param[in] number Expected number of parameters. + * + * @exception GException::invalid_value + * Invalid XML format encountered. + * + * Checks the number of parameter in an XML element. + ***************************************************************************/ +void gammalib::xml_check_parnum(const std::string& origin, + const GXmlElement& xml, + const int& number) +{ + // Throw exception if number of elements does not correspond to the + // expected number + if (xml.elements() != number) { + std::string msg = "Number of "+gammalib::str(xml.elements())+ + " child elements in XML file does not correspond " + "to expected number of "+gammalib::str(number)+ + " elements. Please verify the XML format."; + throw GException::invalid_value(origin, msg); + } + + // Throw exception if number of "parameter" elements does not correspond + // to the xpected number + int npars = xml.elements("parameter"); + if (npars != number) { + std::string msg = "Number of "+gammalib::str(npars)+" \"parameter\" " + "child elements in XML file does not correspond to " + "expected number of "+gammalib::str(number)+ + " elements. Please verify the XML format."; + throw GException::invalid_value(origin, msg); + } + + // Return + return; +} + + +/***********************************************************************//** + * @brief Checks the model type + * + * @param[in] origin Method performing the check. + * @param[in,out] xml XML element. + * @param[in] type Expected model typeN. + * + * @exception GException::invalid_value + * Invalid XML format encountered. + * + * Checks the number of parameter in an XML element. + ***************************************************************************/ +void gammalib::xml_check_type(const std::string& origin, + GXmlElement& xml, + const std::string& type) +{ + // If XML element has no model type then set model type + if (xml.attribute("type") == "") { + xml.attribute("type", type); + } + + // Throw an exception if the model type is not the expected one + if (xml.attribute("type") != type) { + std::string msg = "Model type \""+xml.attribute("type")+"\" is not " + "the expected type \""+type+"\". Please verify " + "the XML format."; + throw GException::invalid_value(origin, msg); + } + + // Return + return; +} + + +/***********************************************************************//** * @brief Checks whether a parameter has occured once * * @param[in] origin Method performing the check. diff --git a/src/support/GUrlFile.cpp b/src/support/GUrlFile.cpp index fbc6fca..c8d6969 100644 --- a/src/support/GUrlFile.cpp +++ b/src/support/GUrlFile.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GUrlFile.cpp - File URL class * * ----------------------------------------------------------------------- * - * copyright (C) 2013-2015 by Juergen Knoedlseder * + * copyright (C) 2013-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -195,7 +195,7 @@ GUrlFile* GUrlFile::clone(void) const * @param[in] url File name. * @param[in] mode File mode. * - * @exception GException::file_open_error + * @exception GException::file_error * Unable to open file. * * Opens a file @p url in the specified @p mode. Any environment variable @@ -214,7 +214,9 @@ void GUrlFile::open(const std::string& url, const std::string& mode) // Try opening file. Throw an exception if opening failed. m_fptr = std::fopen(filename.c_str(), mode.c_str()); if (m_fptr == NULL) { - throw GException::file_open_error(G_OPEN, filename); + std::string msg = "Unable to open file \""+filename+"\" in mode \""+ + mode+"\". Please specify an accessible file."; + throw GException::file_error(G_OPEN, msg); } // Store URL and mode diff --git a/src/xml/GXml.cpp b/src/xml/GXml.cpp index 48569db..865c131 100644 --- a/src/xml/GXml.cpp +++ b/src/xml/GXml.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GXml.cpp - XML class * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2018 by Juergen Knoedlseder * + * copyright (C) 2010-2021 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -524,6 +524,9 @@ const GXmlElement* GXml::element(const std::string& name, const int& index) cons * * @param[in] filename File name. * + * @exception GException::file_error + * Unable to open file. + * * Loads a XML document from a file by reading from the file's Unified * Resource Locator (URL). The read() method is invoked for this purpose. * @@ -538,7 +541,9 @@ void GXml::load(const GFilename& filename) { // Throw an exception if file does not exist if (!filename.exists()) { - throw GException::file_open_error(G_LOAD, filename); + std::string msg = "Unable to open file \""+filename.url()+"\". Please " + "specify a valid file name."; + throw GException::file_error(G_LOAD, msg); } // Open XML URL as file for reading