diff --git a/include/GTools.hpp b/include/GTools.hpp index 324784f..d8d73d1 100644 --- a/include/GTools.hpp +++ b/include/GTools.hpp @@ -1,7 +1,7 @@ /*************************************************************************** * GTools.hpp - GammaLib tools * * ----------------------------------------------------------------------- * - * copyright (C) 2008-2015 by Juergen Knoedlseder * + * copyright (C) 2008-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -115,6 +115,10 @@ namespace gammalib { const GXmlElement* xml_get_par(const std::string& origin, const GXmlElement& xml, const std::string& name); + std::string xml_get_attr(const std::string& origin, + const GXmlElement& xml, + const std::string& name, + const std::string& attribute); void xml_check_par(const std::string& origin, const std::string& name, const int& number); diff --git a/inst/com/Makefile.am b/inst/com/Makefile.am index e1cecd1..80c10aa 100644 --- a/inst/com/Makefile.am +++ b/inst/com/Makefile.am @@ -13,7 +13,6 @@ INCLUDES = -I$(top_srcdir)/include \ # Define sources for this directory sources = src/GCOMSupport.cpp \ - src/GCOMException.cpp \ src/GCOMEventCube.cpp \ src/GCOMEventBin.cpp \ src/GCOMInstDir.cpp \ @@ -22,8 +21,7 @@ sources = src/GCOMSupport.cpp \ src/GCOMModelDRBFitting.cpp # Define headers to be installed -pkginclude_HEADERS = include/GCOMException.hpp \ - include/GCOMEventCube.hpp \ +pkginclude_HEADERS = include/GCOMEventCube.hpp \ include/GCOMEventBin.hpp \ include/GCOMInstDir.hpp \ include/GCOMResponse.hpp \ diff --git a/inst/com/include/GCOMException.hpp b/inst/com/include/GCOMException.hpp deleted file mode 100644 index 4ae9d0c..0000000 --- a/inst/com/include/GCOMException.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * GCOMException.hpp - COMPTEL exception handler * - * ----------------------------------------------------------------------- * - * copyright (C) 2012 by Juergen Knoedlseder * - * ----------------------------------------------------------------------- * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - ***************************************************************************/ -/** - * @file GCOMException.hpp - * @brief COMPTEL exception handler interface definition - * @author Juergen Knoedlseder - */ - -#ifndef GCOMEXCEPTION_HPP -#define GCOMEXCEPTION_HPP - -/* __ Includes ___________________________________________________________ */ -#include // string -#include // ostringstream -#include // exception - - -/***********************************************************************//** - * @class GCOMExceptionHandler - * - * @brief Interface for COMPTEL exception handler - ***************************************************************************/ -class GCOMExceptionHandler : public std::exception { -public: - GCOMExceptionHandler(void) { } - virtual ~GCOMExceptionHandler(void) throw() { } - virtual const char* what() const throw(); -protected: - std::string m_origin; - std::string m_message; -}; - - -/***********************************************************************//** - * @class GCOMException - * - * @brief Interface for COMPTEL exceptions - * - * This object is thrown in case of a COMPTEL exception. - ***************************************************************************/ -class GCOMException : public GCOMExceptionHandler { -public: - // General exceptions - class file_open_error : public GCOMExceptionHandler { - public: - file_open_error(const std::string& origin, - const std::string& filename, - const std::string& message = ""); - }; - - // Event cube exceptions - class no_sky : public GCOMExceptionHandler { - public: - no_sky(const std::string& origin, - const std::string& message = ""); - }; - class no_ebds : public GCOMExceptionHandler { - public: - no_ebds(const std::string& origin, - const std::string& message = ""); - }; - class no_gti : public GCOMExceptionHandler { - public: - no_gti(const std::string& origin, - const std::string& message = ""); - }; - class no_dirs : public GCOMExceptionHandler { - public: - no_dirs(const std::string& origin, - const std::string& message = ""); - }; - - // Observation exceptions - class incompatible_dataspace : public GCOMExceptionHandler { - public: - incompatible_dataspace(const std::string& origin, - const std::string& message = ""); - }; - - // Response exceptions - class bad_observation_type : public GCOMExceptionHandler { - public: - bad_observation_type(const std::string& origin, - const std::string& message = ""); - }; - class bad_event_type : public GCOMExceptionHandler { - public: - bad_event_type(const std::string& origin, - const std::string& message = ""); - }; - class bad_instdir_type : public GCOMExceptionHandler { - public: - bad_instdir_type(const std::string& origin, - const std::string& message = ""); - }; -}; - -#endif /* GCOMEXCEPTION_HPP */ diff --git a/inst/com/include/GCOMObservation.hpp b/inst/com/include/GCOMObservation.hpp index 5433c2f..f60b100 100644 --- a/inst/com/include/GCOMObservation.hpp +++ b/inst/com/include/GCOMObservation.hpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCOMObservation.hpp - COMPTEL observation class * * ----------------------------------------------------------------------- * - * copyright (C) 2012-2015 by Juergen Knoedlseder * + * copyright (C) 2012-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -41,9 +41,11 @@ * * @brief Interface class for COMPTEL observations * - * This class implements a multi-wavelength observation. A multi-wavelength - * observation contains spectral points obtained with an unspecified - * instrument. The spectral points are given in physical units. + * This class implements a COMPTEL observation. Each COMPTEL observation is + * defined for a given energy range, and is composed of a DRE, DRB, DRG and + * DRX file. The DRE file contains the event data, the DRB file contains a + * background model, the DRG file contains geometry factors, and the DRX file + * contains the exposure. ***************************************************************************/ class GCOMObservation : public GObservation { @@ -58,7 +60,7 @@ public: virtual ~GCOMObservation(void); // Operators - virtual GCOMObservation& operator= (const GCOMObservation& obs); + virtual GCOMObservation& operator=(const GCOMObservation& obs); // Implement pure virtual methods virtual void clear(void); @@ -66,10 +68,10 @@ public: virtual std::string classname(void) const; virtual void response(const GResponse& rsp); virtual const GCOMResponse* response(void) const; - virtual std::string instrument(void) const { return m_instrument; } - virtual double ontime(void) const { return m_ontime; } - virtual double livetime(void) const { return m_livetime; } - virtual double deadc(const GTime& time) const { return m_deadc; } + virtual std::string instrument(void) const; + virtual double ontime(void) const; + virtual double livetime(void) const; + virtual double deadc(const GTime& time) const; virtual void read(const GXmlElement& xml); virtual void write(GXmlElement& xml) const; virtual std::string print(const GChatter& chatter = NORMAL) const; @@ -80,16 +82,16 @@ public: const std::string& drgname, const std::string& drxname); void response(const std::string& rspname, const GCaldb& caldb); - void obs_id(const double& id) { m_obs_id=id; } - void ontime(const double& ontime) { m_ontime=ontime; } - void livetime(const double& livetime) { m_livetime=livetime; } - void deadc(const double& deadc) { m_deadc=deadc; } - void ewidth(const double& ewidth) { m_ewidth=ewidth; } - const double& obs_id(void) const { return m_obs_id; } - const double& ewidth(void) const { return m_ewidth; } - const GSkyMap& drb(void) const { return m_drb; } - const GSkyMap& drg(void) const { return m_drg; } - const GSkyMap& drx(void) const { return m_drx; } + void obs_id(const double& id); + void ontime(const double& ontime); + void livetime(const double& livetime); + void deadc(const double& deadc); + void ewidth(const double& ewidth); + const double& obs_id(void) const; + const double& ewidth(void) const; + const GSkyMap& drb(void) const; + const GSkyMap& drg(void) const; + const GSkyMap& drx(void) const; protected: // Protected methods @@ -147,4 +149,188 @@ const GCOMResponse* GCOMObservation::response(void) const return &m_response; } + +/***********************************************************************//** + * @brief Return instrument + * + * @return Instrument name. + ***************************************************************************/ +inline +std::string GCOMObservation::instrument(void) const +{ + // Return instrument + return (m_instrument); +} + + +/***********************************************************************//** + * @brief Return ontime + * + * @return Ontime (seconds). + ***************************************************************************/ +inline +double GCOMObservation::ontime(void) const +{ + // Return ontime + return (m_ontime); +} + + +/***********************************************************************//** + * @brief Return livetime + * + * @return Livetime (seconds). + ***************************************************************************/ +inline +double GCOMObservation::livetime(void) const +{ + // Return livetime + return (m_livetime); +} + + +/***********************************************************************//** + * @brief Return deadtime correction factor + * + * @param[in] time Time. + * + * @return Deadtime correction factor. + ***************************************************************************/ +inline +double GCOMObservation::deadc(const GTime& time) const +{ + // Return livetime + return (m_deadc); +} + + +/***********************************************************************//** + * @brief Set observation ID + * + * @param[in] id Observation ID. + ***************************************************************************/ +inline +void GCOMObservation::obs_id(const double& id) +{ + m_obs_id = id; + return; +} + + +/***********************************************************************//** + * @brief Set ontime + * + * @param[in] ontime Ontime. + ***************************************************************************/ +inline +void GCOMObservation::ontime(const double& ontime) +{ + m_ontime = ontime; + return; +} + + +/***********************************************************************//** + * @brief Set livetime + * + * @param[in] livetime Livetime. + ***************************************************************************/ +inline +void GCOMObservation::livetime(const double& livetime) +{ + m_livetime = livetime; + return; +} + + +/***********************************************************************//** + * @brief Set deadtime correction factor + * + * @param[in] deadc Deadtime correction factor. + ***************************************************************************/ +inline +void GCOMObservation::deadc(const double& deadc) +{ + m_deadc = deadc; + return; +} + + +/***********************************************************************//** + * @brief Set energy width + * + * @param[in] ewidth Energy width (MeV). + ***************************************************************************/ +inline +void GCOMObservation::ewidth(const double& ewidth) +{ + m_ewidth = ewidth; + return; +} + + +/***********************************************************************//** + * @brief Return observation ID + * + * @return Observation ID. + ***************************************************************************/ +inline +const double& GCOMObservation::obs_id(void) const +{ + // Return observation ID + return (m_obs_id); +} + + +/***********************************************************************//** + * @brief Return energy width + * + * @return Energy width (MeV). + ***************************************************************************/ +inline +const double& GCOMObservation::ewidth(void) const +{ + // Return energy width + return (m_ewidth); +} + + +/***********************************************************************//** + * @brief Return background model + * + * @return Background model. + ***************************************************************************/ +inline +const GSkyMap& GCOMObservation::drb(void) const +{ + // Return background model + return (m_drb); +} + + +/***********************************************************************//** + * @brief Return geometry factors + * + * @return Geometry factors. + ***************************************************************************/ +inline +const GSkyMap& GCOMObservation::drg(void) const +{ + // Return geometry factors + return (m_drg); +} + + +/***********************************************************************//** + * @brief Return exposure + * + * @return Exposure. + ***************************************************************************/ +inline +const GSkyMap& GCOMObservation::drx(void) const +{ + // Return exposure + return (m_drx); +} + #endif /* GCOMOBSERVATION_HPP */ diff --git a/inst/com/src/GCOMEventCube.cpp b/inst/com/src/GCOMEventCube.cpp index b94a8b9..414cd95 100644 --- a/inst/com/src/GCOMEventCube.cpp +++ b/inst/com/src/GCOMEventCube.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCOMEventCube.cpp - COMPTEL event bin container class * * ----------------------------------------------------------------------- * - * copyright (C) 2012-2015 by Juergen Knoedlseder * + * copyright (C) 2012-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -28,9 +28,9 @@ #ifdef HAVE_CONFIG_H #include #endif +#include "GException.hpp" #include "GTools.hpp" #include "GFits.hpp" -#include "GCOMException.hpp" #include "GCOMSupport.hpp" #include "GCOMEventCube.hpp" @@ -102,9 +102,11 @@ GCOMEventCube::GCOMEventCube(const std::string& filename) : GEventCube() * Construct an event cube from sky map, energy boundaries, Good Time * Intervals and the scatter angle minimum value and step size. ***************************************************************************/ -GCOMEventCube::GCOMEventCube(const GSkyMap& map, const GEbounds& ebds, - const GGti& gti, const double& phimin, - const double& dphi) : GEventCube() +GCOMEventCube::GCOMEventCube(const GSkyMap& map, + const GEbounds& ebds, + const GGti& gti, + const double& phimin, + const double& dphi) : GEventCube() { // Initialise members init_members(); @@ -174,7 +176,7 @@ GCOMEventCube::~GCOMEventCube(void) * @param[in] cube Event cube. * @return Event cube. ***************************************************************************/ -GCOMEventCube& GCOMEventCube::operator= (const GCOMEventCube& cube) +GCOMEventCube& GCOMEventCube::operator=(const GCOMEventCube& cube) { // Execute only if object is not identical if (this != &cube) { @@ -680,7 +682,7 @@ void GCOMEventCube::free_members(void) /***********************************************************************//** * @brief Set sky directions and solid angles of events cube * - * @exception GCOMException::no_sky + * @exception GException::invalid_value * No sky pixels have been defined. * * This method computes the sky directions and solid angles for all (Chi,Psi) @@ -692,8 +694,10 @@ void GCOMEventCube::set_scatter_directions(void) { // Throw an error if we have no sky pixels if (npix() < 1) { - throw GCOMException::no_sky(G_SET_SCATTER_DIRECTIONS, - "Every COMPTEL event cube needs a definition of sky pixels."); + std::string msg = "No sky pixels have been found in event cube. " + "Every COMPTEL event cube needs a definition of " + "sky pixels."; + throw GException::invalid_value(G_SET_SCATTER_DIRECTIONS, msg); } // Clear vectors @@ -752,15 +756,17 @@ void GCOMEventCube::set_scatter_angles(const double& phimin, const double& dphi) /***********************************************************************//** * @brief Set log mean energy and energy width of event cube * - * @exception GCOMException::no_ebds - * No energy intervals found. + * @exception GException::invalid_value + * No energy boundaries found. ***************************************************************************/ void GCOMEventCube::set_energies(void) { // Throw an error if GTI is empty if (m_ebounds.size() < 1) { - throw GCOMException::no_ebds(G_SET_ENERGIES, "Every COMPTEL event" - " cube needs a definition of the energy boundaries."); + std::string msg = "No energy boundaries have been found in event " + "cube. Every COMPTEL event cube needs a definition " + "of the energy boundaries."; + throw GException::invalid_value(G_SET_ENERGIES, msg); } // Compute the logarithmic mean energy @@ -777,7 +783,7 @@ void GCOMEventCube::set_energies(void) /***********************************************************************//** * @brief Set mean event time and ontime of event cube * - * @exception GCOMException::no_gti + * @exception GException::invalid_value * No Good Time Intervals found. * * Computes the mean time of the event cube by taking the mean between start @@ -788,9 +794,10 @@ void GCOMEventCube::set_times(void) { // Throw an error if GTI is empty if (m_gti.size() < 1) { - throw GCOMException::no_gti(G_SET_TIMES, "Every COMPTEL event cube" - " needs associated GTIs to allow the computation of the" - " ontime."); + std::string msg = "No Good Time Intervals have been found in event " + "cube. Every COMPTEL event cube needs a definition " + "of the Good Time Intervals."; + throw GException::invalid_value(G_SET_TIMES, msg); } // Compute mean time @@ -836,7 +843,7 @@ void GCOMEventCube::init_bin(void) * * @exception GException::out_of_range * Event index is outside valid range. - * @exception GCOMException::no_dirs + * @exception GException::invalid_value * Sky directions and solid angles vectors have not been set up. * * This method provides the event attributes to the event bin. The event bin @@ -856,7 +863,10 @@ void GCOMEventCube::set_bin(const int& index) // Check for the existence of sky directions and solid angles if (m_dirs.size() != npix() || m_solidangle.size() != npix()) { - throw GCOMException::no_dirs(G_SET_BIN); + std::string msg = "Sky direction vector has not been setup for " + "event cube. Every COMPTEL event cube needs an " + "internal vector of sky directions."; + throw GException::invalid_value(G_SET_BIN, msg); } // Get pixel and energy bin indices. @@ -871,7 +881,7 @@ void GCOMEventCube::set_bin(const int& index) m_dir.phibar(m_phi[iphi]); // Set pointers - m_bin.m_counts = const_cast(&(m_map.pixels()[index])); + m_bin.m_counts = const_cast(&(m_map.pixels()[index])); m_bin.m_solidangle = &(m_solidangle[ipix]); // Return diff --git a/inst/com/src/GCOMException.cpp b/inst/com/src/GCOMException.cpp deleted file mode 100644 index ebe189a..0000000 --- a/inst/com/src/GCOMException.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/*************************************************************************** - * GCOMException.cpp - COMPTEL exception handler * - * ----------------------------------------------------------------------- * - * copyright (C) 2012-2013 by Juergen Knoedlseder * - * ----------------------------------------------------------------------- * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - ***************************************************************************/ -/** - * @file GCOMException.cpp - * @brief COMPTEL exception handler interface implementation - * @author Juergen Knoedlseder - */ - -/* __ Includes ___________________________________________________________ */ -#include "GCOMException.hpp" -#include "GTools.hpp" - - -/***********************************************************************//** - * @brief Exception message - ***************************************************************************/ -const char* GCOMExceptionHandler::what() const throw() -{ - // Set error message - std::string message = "*** ERROR in " + m_origin + ": " + m_message; - - // Return message as C character array - return gammalib::tochar(message); -} - - -/***********************************************************************//** - * @brief Error while opening file - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] filename Name of file that could not be opened. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::file_open_error::file_open_error(const std::string& origin, - const std::string& filename, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Unable to open file \""+filename+"\"."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief No sky pixels found - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::no_sky::no_sky(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "No sky pixels have been found."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief No energy boundaries found - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::no_ebds::no_ebds(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "No energy boundaries have been found."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief No Good Time Intervals found - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::no_gti::no_gti(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "No Good Time Intervals (GTIs) have been found."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief No sky directions found - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::no_dirs::no_dirs(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Sky direction vector has not been setup." - " Cannot access event information."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Incompatible COMPTEL dataspace - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::incompatible_dataspace::incompatible_dataspace(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Dataspace incompatibility."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Observation is not a COMPTEL observation - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::bad_observation_type::bad_observation_type(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Observation is not of type GCOMObservation."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - -/***********************************************************************//** - * @brief Event is not a COMPTEL event - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::bad_event_type::bad_event_type(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Event is not of type GCOMEventAtom or GCOMEventBin."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} - - - - -/***********************************************************************//** - * @brief Instrument direction is not a COMPTEL instrument direction - * - * @param[in] origin Name of method that has thrown the exception. - * @param[in] message Optional error message. - ***************************************************************************/ -GCOMException::bad_instdir_type::bad_instdir_type(const std::string& origin, - const std::string& message) -{ - // Set origin - m_origin = origin; - - // Set message - m_message = "Instrument direction is not of type GCOMInstDir."; - - // Append optional message - if (message.length() > 0) { - m_message += " "+message; - } - - // Return - return; -} diff --git a/inst/com/src/GCOMModelDRBFitting.cpp b/inst/com/src/GCOMModelDRBFitting.cpp index 35cf383..56761c9 100644 --- a/inst/com/src/GCOMModelDRBFitting.cpp +++ b/inst/com/src/GCOMModelDRBFitting.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCOMModelDRBFitting.cpp - COMPTEL DRB model fitting class * * ----------------------------------------------------------------------- * - * copyright (C) 2012-2013 by Juergen Knoedlseder * + * copyright (C) 2012-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -28,11 +28,11 @@ #ifdef HAVE_CONFIG_H #include #endif +#include #include "GException.hpp" #include "GTools.hpp" #include "GModelRegistry.hpp" #include "GCOMModelDRBFitting.hpp" -#include "GCOMException.hpp" #include "GCOMObservation.hpp" #include "GCOMEventBin.hpp" @@ -231,9 +231,8 @@ GCOMModelDRBFitting* GCOMModelDRBFitting::clone(void) const * @param[in] obs Observation. * @return Background model value. * - * @exception GCOMException::bad_observation_type + * @exception GException::invalid_argument * Observation is not a COMPTEL observation. - * @exception GCOMException::bad_event_type * Event is not a COMPTEL event bin. * * Evaluates the COMPTEL DRB fitting model. @@ -244,13 +243,20 @@ double GCOMModelDRBFitting::eval(const GEvent& event, // Extract COMPTEL observation const GCOMObservation* observation = dynamic_cast(&obs); if (observation == NULL) { - throw GCOMException::bad_observation_type(G_EVAL); + std::string cls = std::string(typeid(&obs).name()); + std::string msg = "Observation of type \""+cls+"\" is not a COMPTEL " + "observations. Please specify a COMPTEL observation " + "as argument."; + throw GException::invalid_argument(G_EVAL, msg); } // Extract COMPTEL event bin const GCOMEventBin* bin = dynamic_cast(&event); if (bin == NULL) { - throw GCOMException::bad_event_type(G_EVAL); + std::string cls = std::string(typeid(&event).name()); + std::string msg = "Event of type \""+cls+"\" is not a COMPTEL event. " + "Please specify a COMPTEL event as argument."; + throw GException::invalid_argument(G_EVAL, msg); } // Initialise value @@ -337,13 +343,20 @@ double GCOMModelDRBFitting::eval_gradients(const GEvent& event, // Extract COMPTEL observation const GCOMObservation* observation = dynamic_cast(&obs); if (observation == NULL) { - throw GCOMException::bad_observation_type(G_EVAL_GRADIENTS); + std::string cls = std::string(typeid(&obs).name()); + std::string msg = "Observation of type \""+cls+"\" is not a COMPTEL " + "observations. Please specify a COMPTEL observation " + "as argument."; + throw GException::invalid_argument(G_EVAL_GRADIENTS, msg); } // Extract COMPTEL event bin const GCOMEventBin* bin = dynamic_cast(&event); if (bin == NULL) { - throw GCOMException::bad_event_type(G_EVAL_GRADIENTS); + std::string cls = std::string(typeid(&event).name()); + std::string msg = "Event of type \""+cls+"\" is not a COMPTEL event. " + "Please specify a COMPTEL event as argument."; + throw GException::invalid_argument(G_EVAL_GRADIENTS, msg); } // Initialise value and gradients @@ -491,10 +504,8 @@ GCOMEventCube* GCOMModelDRBFitting::mc(const GObservation& obs, * * @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 + * Model definition requires at least one node. * * Read the COMPTEL DRB fitting model from an XML element. * @@ -524,9 +535,9 @@ void GCOMModelDRBFitting::read(const GXmlElement& xml) // Throw an error if there are no nodes if (nodes < 1) { - std::string message = "DRB fitting model requires at least one" - " Phibar node."; - throw GException::model_invalid_parnum(G_READ, xml, message); + std::string msg = "DRB fitting model requires at least one Phibar " + "node. Please correct XML format."; + throw GException::invalid_value(G_READ, msg); } // Loop over all nodes @@ -539,38 +550,13 @@ void GCOMModelDRBFitting::read(const GXmlElement& xml) // Get node const GXmlElement* node = xml.element("node", i); - // Verify that node XML element has exactly 2 parameters - if (node->elements() != 2 || node->elements("parameter") != 2) { - throw GException::model_invalid_parnum(G_READ, xml, - "Node requires exactly 2 parameters."); - } - - // Extract node parameters - int npar[] = {0, 0}; - for (int k = 0; k < 2; ++k) { - - // Get parameter element - const GXmlElement* par = node->element("parameter", k); - - // Handle energy - if (par->attribute("name") == "Phibar") { - phibar.read(*par); - npar[0]++; - } - - // Handle intensity - else if (par->attribute("name") == "Normalization") { - normalization.read(*par); - npar[1]++; - } - - } // endfor: looped over parameters + // Read Phibar parameter + const GXmlElement* par = gammalib::xml_get_par(G_READ, *node, "Phibar"); + phibar.read(*par); - // Verify that all parameters were found - if (npar[0] != 1 || npar[1] != 1) { - throw GException::model_invalid_parnames(G_READ, xml, - "Require \"Phibar\" and \"Normalization\" parameters."); - } + // Read Normalization parameter + par = gammalib::xml_get_par(G_READ, *node, "Normalization"); + normalization.read(*par); // Set parameter names std::string phibar_name = "Phibar layer "+gammalib::str(i); @@ -675,8 +661,10 @@ void GCOMModelDRBFitting::write(GXmlElement& xml) const // Verify model type if (src->attribute("type") != type()) { - throw GException::model_invalid_spectral(G_WRITE, src->attribute("type"), - "DRB fitting model is not of type \""+type()+"\"."); + std::string msg = "Invalid model type \""+src->attribute("type")+"\" " + "found in XML file. Model type \""+type()+"\" " + "expected."; + throw GException::invalid_value(G_WRITE, msg); } // Determine number of nodes @@ -691,9 +679,11 @@ void GCOMModelDRBFitting::write(GXmlElement& xml) const // Verify that XML element has the required number of nodes if (src->elements() != nodes || src->elements("node") != nodes) { - std::string message = "DRB fitting model requires exactly " + - gammalib::str(nodes) + " nodes."; - throw GException::model_invalid_parnum(G_WRITE, *src, message); + std::string msg = "Invalid number of nodes "+ + gammalib::str(src->elements("node"))+ + " found in XML file, but model requires exactly "+ + gammalib::str(nodes)+" nodes."; + throw GException::invalid_value(G_WRITE, msg); } // Loop over all nodes @@ -702,45 +692,13 @@ void GCOMModelDRBFitting::write(GXmlElement& xml) const // Get node GXmlElement* node = src->element("node", i); - // If XML element has 0 leafs then append energy and intensity - // element - if (node->elements() == 0) { - node->append(GXmlElement("parameter name=\"Phibar\"")); - node->append(GXmlElement("parameter name=\"Normalization\"")); - } - - // Verify that node XML element has exactly 2 parameters - if (node->elements() != 2 || node->elements("parameter") != 2) { - throw GException::model_invalid_parnum(G_WRITE, *src, - "Node requires exactly 2 parameters."); - } - - // Set or update model parameter attributes - int npar[] = {0, 0}; - for (int k = 0; k < 2; ++k) { - - // Get parameter element - GXmlElement* par = node->element("parameter", k); + // Write Phibar parameter + GXmlElement* par = gammalib::xml_need_par(G_WRITE, *node, "Phibar"); + m_phibars[i].write(*par); - // Handle prefactor - if (par->attribute("name") == "Phibar") { - npar[0]++; - m_phibars[i].write(*par); - } - - // Handle index - else if (par->attribute("name") == "Normalization") { - npar[1]++; - m_values[i].write(*par); - } - - } // endfor: looped over parameters - - // Check of all required parameters are present - if (npar[0] != 1 || npar[1] != 1) { - throw GException::model_invalid_parnames(G_WRITE, *src, - "Require \"Phibar\" and \"Normalization\" parameters."); - } + // Write Normalization parameter + par = gammalib::xml_need_par(G_WRITE, *node, "Normalization"); + m_values[i].write(*par); } // endfor: looped over nodes diff --git a/inst/com/src/GCOMObservation.cpp b/inst/com/src/GCOMObservation.cpp index 222f161..a74ef70 100644 --- a/inst/com/src/GCOMObservation.cpp +++ b/inst/com/src/GCOMObservation.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCOMObservation.cpp - COMPTEL Observation class * * ----------------------------------------------------------------------- * - * copyright (C) 2012-2015 by Juergen Knoedlseder * + * copyright (C) 2012-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -33,7 +33,6 @@ #include "GException.hpp" #include "GFits.hpp" #include "GTools.hpp" -#include "GCOMException.hpp" #include "GCOMObservation.hpp" #include "GCOMEventCube.hpp" #include "GCOMSupport.hpp" @@ -65,7 +64,7 @@ const GObservationRegistry g_obs_com_registry(&g_obs_com_seed); /***********************************************************************//** * @brief Void constructor * - * Creates empty class instance. + * Creates an empty COMPTEL observation. ***************************************************************************/ GCOMObservation::GCOMObservation(void) : GObservation() { @@ -115,7 +114,7 @@ GCOMObservation::GCOMObservation(const std::string& drename, * * @param[in] obs COMPTEL observation. * - * Creates class instance by copying an existing COMPTEL observation. + * Creates COMPTEL observation by copying an existing COMPTEL observation. ***************************************************************************/ GCOMObservation::GCOMObservation(const GCOMObservation& obs) : GObservation(obs) { @@ -188,7 +187,7 @@ GCOMObservation& GCOMObservation::operator=(const GCOMObservation& obs) ==========================================================================*/ /***********************************************************************//** - * @brief Clear instance + * @brief Clear COMPTEL observation ***************************************************************************/ void GCOMObservation::clear(void) { @@ -206,7 +205,7 @@ void GCOMObservation::clear(void) /***********************************************************************//** - * @brief Clone instance + * @brief Clone COMPTEL observation * * @return Pointer to deep copy of COMPTEL observation. ***************************************************************************/ @@ -221,19 +220,21 @@ GCOMObservation* GCOMObservation::clone(void) const * * @param[in] rsp Response function. * - * @exception GException::rsp_invalid_type - * Specified response is not of type GCOMResponse. + * @exception GException::invalid_argument + * Specified response is not a COMPTEL response. * - * Sets the response function for the observation. The argument has to be of - * type GCOMResponse, otherwise an exception is thrown. + * Sets the response function for the observation. ***************************************************************************/ void GCOMObservation::response(const GResponse& rsp) { // Get pointer on COM response const GCOMResponse* comrsp = dynamic_cast(&rsp); if (comrsp == NULL) { - throw GException::rsp_invalid_type(G_RESPONSE, - typeid(&rsp).name(), "Expected type \"GCOMResponse\"."); + std::string cls = std::string(typeid(&rsp).name()); + std::string msg = "Response of type \""+cls+"\" is " + "not a COMPTEL response. Please specify a COMPTEL " + "response as argument."; + throw GException::invalid_argument(G_RESPONSE, msg); } // Clone response function @@ -250,8 +251,8 @@ void GCOMObservation::response(const GResponse& rsp) * @param[in] rspname Name of COMPTEL response. * @param[in] caldb Calibration database. * - * Sets the response function by loading the response information from an - * IAQ file. + * Sets the response function by loading the response information from the + * calibration database. ***************************************************************************/ void GCOMObservation::response(const std::string& rspname, const GCaldb& caldb) { @@ -274,11 +275,6 @@ void GCOMObservation::response(const std::string& rspname, const GCaldb& caldb) * * @param[in] xml XML element. * - * @exception GException::xml_invalid_parnum - * Invalid number of parameters found in XML element. - * @exception GException::xml_invalid_parnames - * Invalid parameter names found in XML element. - * * Reads information for a COMPTEL observation from an XML element. * The expected format of the XML element is * @@ -287,7 +283,7 @@ void GCOMObservation::response(const std::string& rspname, const GCaldb& caldb) * * * - * + * * * * for a binned observation. @@ -297,70 +293,15 @@ void GCOMObservation::read(const GXmlElement& xml) // Clear observation clear(); - // Initialise FITS file names - std::string drename; - std::string drbname; - std::string drgname; - std::string drxname; - std::string iaqname; - // Extract instrument name m_instrument = xml.attribute("instrument"); - // 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::xml_invalid_parnum(G_READ, xml, - "COMPTEL observation requires exactly 5 parameters."); - } - - // Extract parameters - int npar[] = {0, 0, 0, 0, 0}; - for (int i = 0; i < npars; ++i) { - - // Get parameter element - const GXmlElement* par = xml.element("parameter", i); - - // Handle EventList - if (par->attribute("name") == "DRE") { - drename = par->attribute("file"); - npar[0]++; - } - - // Handle DRB - else if (par->attribute("name") == "DRB") { - drbname = par->attribute("file"); - npar[1]++; - } - - // Handle DRG - else if (par->attribute("name") == "DRG") { - drgname = par->attribute("file"); - npar[2]++; - } - - // Handle DRX - else if (par->attribute("name") == "DRX") { - drxname = par->attribute("file"); - npar[3]++; - } - - // Handle IAQ - else if (par->attribute("name") == "IAQ") { - iaqname = par->attribute("file"); - npar[4]++; - } - - } // endfor: looped over all parameters - - // Verify that all parameters were found - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1 || npar[4] != 1) { - throw GException::xml_invalid_parnames(G_READ, xml, - "Require \"DRE\", \"DRB\", \"DRG\", \"DRX\" and \"IAQ\"" - " parameters."); - } + // Get parameters + std::string drename = gammalib::xml_get_attr(G_READ, xml, "DRE", "file"); + std::string drbname = gammalib::xml_get_attr(G_READ, xml, "DRB", "file"); + std::string drgname = gammalib::xml_get_attr(G_READ, xml, "DRG", "file"); + std::string drxname = gammalib::xml_get_attr(G_READ, xml, "DRX", "file"); + std::string iaqname = gammalib::xml_get_attr(G_READ, xml, "IAQ", "value"); // Load observation load(drename, drbname, drgname, drxname); @@ -378,11 +319,6 @@ void GCOMObservation::read(const GXmlElement& xml) * * @param[in] xml XML element. * - * @exception GException::xml_invalid_parnum - * Invalid number of parameters found in XML element. - * @exception GException::xml_invalid_parnames - * Invalid parameter names found in XML element. - * * Writes information for a COMPTEL observation into an XML element. The * expected format of the XML element is * @@ -391,75 +327,35 @@ void GCOMObservation::read(const GXmlElement& xml) * * * - * + * * * * for a binned observation. ***************************************************************************/ void GCOMObservation::write(GXmlElement& xml) const { - // If XML element has 0 nodes then append 5 parameter nodes - if (xml.elements() == 0) { - xml.append(GXmlElement("parameter name=\"DRE\"")); - xml.append(GXmlElement("parameter name=\"DRB\"")); - xml.append(GXmlElement("parameter name=\"DRG\"")); - xml.append(GXmlElement("parameter name=\"DRX\"")); - xml.append(GXmlElement("parameter name=\"IAQ\"")); - } - - // Verify that XML element has exactly 5 parameters - if (xml.elements() != 5 || xml.elements("parameter") != 5) { - throw GException::xml_invalid_parnum(G_WRITE, xml, - "COMPTEL observation requires exactly 5 parameters."); - } - - // Set or update parameter attributes - int npar[] = {0, 0, 0, 0, 0}; - for (int i = 0; i < 5; ++i) { - - // Get parameter element - GXmlElement* par = xml.element("parameter", i); + // Allocate XML element pointer + GXmlElement* par; - // Handle DRE - if (par->attribute("name") == "DRE") { - par->attribute("file", m_drename); - npar[0]++; - } - - // Handle DRB - else if (par->attribute("name") == "DRB") { - par->attribute("file", m_drbname); - npar[1]++; - } - - // Handle DRG - else if (par->attribute("name") == "DRG") { - par->attribute("file", m_drgname); - npar[2]++; - } + // Set DRE parameter + par = gammalib::xml_need_par(G_WRITE, xml, "DRE"); + par->attribute("file", m_drename); - // Handle DRX - else if (par->attribute("name") == "DRX") { - par->attribute("file", m_drxname); - npar[3]++; - } + // Set DRB parameter + par = gammalib::xml_need_par(G_WRITE, xml, "DRB"); + par->attribute("file", m_drbname); - // Handle IAQ - else if (par->attribute("name") == "IAQ") { - std::string iaqname = ""; - iaqname = m_response.rspname(); - par->attribute("file", iaqname); - npar[4]++; - } + // Set DRG parameter + par = gammalib::xml_need_par(G_WRITE, xml, "DRG"); + par->attribute("file", m_drgname); - } // endfor: looped over all parameters + // Set DRX parameter + par = gammalib::xml_need_par(G_WRITE, xml, "DRX"); + par->attribute("file", m_drxname); - // Verify that all required parameters are present - if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1 || npar[4] != 1) { - throw GException::xml_invalid_parnames(G_WRITE, xml, - "Require \"DRE\", \"DRB\", \"DRG\", \"DRX\" and \"IAQ\"" - " parameters."); - } + // Set IAQ parameter + par = gammalib::xml_need_par(G_WRITE, xml, "DRX"); + par->attribute("value", m_response.rspname()); // Return return; @@ -579,11 +475,11 @@ void GCOMObservation::init_members(void) m_drx.clear(); m_pointing.clear(); m_response.clear(); - m_obs_id = 0; - m_ontime = 0.0; - m_livetime = 0.0; - m_deadc = 0.0; - m_ewidth = 0.0; + m_obs_id = 0; + m_ontime = 0.0; + m_livetime = 0.0; + m_deadc = 0.0; + m_ewidth = 0.0; // Return return; @@ -670,7 +566,7 @@ void GCOMObservation::load_dre(const std::string& drename) * * @param[in] drbname DRB filename. * - * @exception GCOMException::incompatible_dataspace + * @exception GException::invalid_value * DRB data space incompatible with DRE data space. * * Load the background model from the primary image of the specified FITS @@ -695,8 +591,9 @@ void GCOMObservation::load_drb(const std::string& drbname) // Check map dimensions if (!check_map(m_drb)) { - throw GCOMException::incompatible_dataspace(G_LOAD_DRB, - "DRB data cube incompatible with DRE data cube."); + std::string msg = "DRB data cube \""+drbname+"\" incompatible with " + "DRE data cube \""+m_drename+"\"."; + throw GException::invalid_value(G_LOAD_DRB, msg); } // Store DRB filename @@ -712,7 +609,7 @@ void GCOMObservation::load_drb(const std::string& drbname) * * @param[in] drgname DRG filename. * - * @exception GCOMException::incompatible_dataspace + * @exception GException::invalid_value * DRG data space incompatible with DRE data space. * * Load the geometry factors from the primary image of the specified FITS @@ -737,8 +634,9 @@ void GCOMObservation::load_drg(const std::string& drgname) // Check map dimensions if (!check_map(m_drg)) { - throw GCOMException::incompatible_dataspace(G_LOAD_DRG, - "DRG data cube incompatible with DRE data cube."); + std::string msg = "DRG data cube \""+drgname+"\" incompatible with " + "DRE data cube \""+m_drename+"\"."; + throw GException::invalid_value(G_LOAD_DRB, msg); } // Store DRG filename diff --git a/inst/com/src/GCOMResponse.cpp b/inst/com/src/GCOMResponse.cpp index db0fa48..1e9d74c 100644 --- a/inst/com/src/GCOMResponse.cpp +++ b/inst/com/src/GCOMResponse.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GCOMResponse.cpp - COMPTEL Response class * * ----------------------------------------------------------------------- * - * copyright (C) 2012-2015 by Juergen Knoedlseder * + * copyright (C) 2012-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -29,6 +29,7 @@ #include #endif #include +#include #include "GTools.hpp" #include "GMath.hpp" #include "GFits.hpp" @@ -46,7 +47,6 @@ #include "GCOMObservation.hpp" #include "GCOMEventBin.hpp" #include "GCOMInstDir.hpp" -#include "GCOMException.hpp" /* __ Method name definitions ____________________________________________ */ #define G_IRF "GCOMResponse::irf(GEvent&, GSource&, GObservation&)" @@ -230,10 +230,9 @@ GCOMResponse* GCOMResponse::clone(void) const * @param[in] obs Observation. * @return Instrument response function (cm2 sr-1) * - * @exception GCOMException::bad_observation_type + * @exception GException::invalid_argument * Observation is not a COMPTEL observation. - * @exception GCOMException::bad_instdir_type - * Instrument direction is not a COMPTEL instrument direction. + * Event is not a COMPTEL event bin. * * Returns the instrument response function for a given observed photon * direction as function of the assumed true photon direction. The result @@ -258,13 +257,20 @@ double GCOMResponse::irf(const GEvent& event, // Extract COMPTEL observation const GCOMObservation* observation = dynamic_cast(&obs); if (observation == NULL) { - throw GCOMException::bad_observation_type(G_IRF); + std::string cls = std::string(typeid(&obs).name()); + std::string msg = "Observation of type \""+cls+"\" is not a COMPTEL " + "observations. Please specify a COMPTEL observation " + "as argument."; + throw GException::invalid_argument(G_IRF, msg); } // Extract COMPTEL event bin const GCOMEventBin* bin = dynamic_cast(&event); if (bin == NULL) { - throw GCOMException::bad_event_type(G_IRF); + std::string cls = std::string(typeid(&event).name()); + std::string msg = "Event of type \""+cls+"\" is not a COMPTEL event. " + "Please specify a COMPTEL event as argument."; + throw GException::invalid_argument(G_IRF, msg); } // Extract event parameters diff --git a/inst/com/test/data/obs.xml b/inst/com/test/data/obs.xml index 72877f2..15279db 100644 --- a/inst/com/test/data/obs.xml +++ b/inst/com/test/data/obs.xml @@ -1,9 +1,10 @@ + - + \ No newline at end of file diff --git a/pyext/GTools.i b/pyext/GTools.i index 4408977..216b63a 100644 --- a/pyext/GTools.i +++ b/pyext/GTools.i @@ -1,7 +1,7 @@ /*************************************************************************** * GTools.i - GammaLib tools * * ----------------------------------------------------------------------- * - * copyright (C) 2008-2015 by Juergen Knoedlseder * + * copyright (C) 2008-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -82,6 +82,10 @@ namespace gammalib { const GXmlElement* xml_get_par(const std::string& origin, const GXmlElement& xml, const std::string& name); + std::string xml_get_attr(const std::string& origin, + const GXmlElement& xml, + const std::string& name, + const std::string& attribute); void xml_check_par(const std::string& origin, const std::string& name, const int& number); diff --git a/src/support/GTools.cpp b/src/support/GTools.cpp index 40979c6..42544c5 100644 --- a/src/support/GTools.cpp +++ b/src/support/GTools.cpp @@ -1392,10 +1392,10 @@ bool gammalib::xml_has_par(const GXmlElement& xml, const std::string& name) * * Returns pointer to parameter with given @p name in XML element. If the * @p name is not found, a parameter with the given @p name is added. In - * that respect the method differs from xml_getpar which does not add a + * that respect the function differs from xml_get_par which does not add a * parameter element. * - * The method checks for multiple occurences of a parameter and throws an + * The function checks for multiple occurences of a parameter and throws an * exception in case that more than one parameter with a given name is found. ***************************************************************************/ GXmlElement* gammalib::xml_need_par(const std::string& origin, @@ -1442,10 +1442,10 @@ GXmlElement* gammalib::xml_need_par(const std::string& origin, * @exception GException::invalid_value * Invalid XML format encountered. * - * Returns pointer to parameter with given @p name in XML element. The method - * checks whether the parameter has been found and throws an exception if - * no parameter or multiple occurences of a parameter with given @p name - * are found. + * Returns pointer to parameter with given @p name in XML element. The + * function checks whether the parameter has been found and throws an + * exception if no parameter or multiple occurences of a parameter with given + * @p name are found. ***************************************************************************/ const GXmlElement* gammalib::xml_get_par(const std::string& origin, const GXmlElement& xml, @@ -1476,6 +1476,51 @@ const GXmlElement* gammalib::xml_get_par(const std::string& origin, /***********************************************************************//** + * @brief Return attribute value for a given parameter in XML element + * + * @param[in] origin Method requesting parameter. + * @param[in] xml XML element. + * @param[in] name Parameter name. + * @param[in] attribute Attribute name. + * @return Value of attribute. + * + * @exception GException::invalid_value + * Attribute not found. + * + * Returns the value of @p attribute of parameter @p name in XML element. + * The function checks whether the parameter has been found and throws an + * exception if no parameter or multiple occurences of a parameter with given + * @p name are found. The function furthermore checks whether the attribute + * exists. + ***************************************************************************/ +std::string gammalib::xml_get_attr(const std::string& origin, + const GXmlElement& xml, + const std::string& name, + const std::string& attribute) +{ + // Initialise attribute value + std::string value = ""; + + // Get parameter + const GXmlElement* par = gammalib::xml_get_par(origin, xml, name); + + // Throw an exception if a parameter has not the requested attribute + if (!par->has_attribute(attribute)) { + std::string msg = "Attribute \""+attribute+"\" not found in XML " + "parameter \""+name+"\". Please verify the XML " + "format."; + throw GException::invalid_value(origin, msg); + } + + // Extract attribute + value = par->attribute(attribute); + + // Return attribute value + return value; +} + + +/***********************************************************************//** * @brief Checks whether a parameter has occured once * * @param[in] origin Method performing the check.