diff --git a/ChangeLog b/ChangeLog index 5f15df2..ac3d121 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ * Version 1.2.0 released ========================= - Improve exception message in GModelSpatialDiffuseCube::mc (#1915) + Monte Carlo for empty maps or map cubes no longer throws an exception (#1915) Add GModelTemporalFunc call (#1914) Add GSkyMap FITS HDU constructor Add leap second for 1-1-2017 (#1887) diff --git a/NEWS b/NEWS index 304e661..ee60e86 100644 --- a/NEWS +++ b/NEWS @@ -175,8 +175,10 @@ function for the simulation of transient sources. A unit test has been added and the mc() and eval() methods have been validated using a dedicated test script (#1914). -Improve the exception message for empty map cubes in GModelSpatialDiffuseCube::mc -(#1915). +The GModelSpatialDiffuseMap::mc and GModelSpatialDiffuseCube::mc methods +now throw an GException::invalid_return_value exception that is catched +in the GModelSky::mc method and leads to the skipping of the concerned +photon. This allows handling of empty diffuse maps or map cubes (#1915). 9. Numerics module diff --git a/include/GException.hpp b/include/GException.hpp index 7e3372c..df3bbe7 100644 --- a/include/GException.hpp +++ b/include/GException.hpp @@ -1,7 +1,7 @@ /*************************************************************************** * GException.hpp - Exception handler * * ----------------------------------------------------------------------- * - * copyright (C) 2006-2015 by Juergen Knoedlseder * + * copyright (C) 2006-2017 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -82,6 +82,13 @@ public: const std::string& message); }; + // Invalid return value + class invalid_return_value : public GExceptionHandler { + public: + invalid_return_value(const std::string& origin, + const std::string& message); + }; + // Out of range class out_of_range : public GExceptionHandler { public: diff --git a/src/model/GModelSky.cpp b/src/model/GModelSky.cpp index 82a9c28..064c920 100644 --- a/src/model/GModelSky.cpp +++ b/src/model/GModelSky.cpp @@ -942,8 +942,15 @@ GPhotons GModelSky::mc(const double& area, std::cout << " Energy=" << photon.energy() << std::endl; #endif - // Set incident photon direction - photon.dir(m_spatial->mc(photon.energy(), photon.time(), ran)); + // Set incident photon direction. If an invalid_return_value + // exception occurs the sky direction returned by the spatial + // Monte Carlo method is invalid and the photon is skipped. + try { + photon.dir(m_spatial->mc(photon.energy(), photon.time(), ran)); + } + catch (GException::invalid_return_value) { + continue; + } // Debug option: dump direction #if defined(G_DUMP_MC_DETAIL) diff --git a/src/model/GModelSpatialDiffuseCube.cpp b/src/model/GModelSpatialDiffuseCube.cpp index f7cd1b6..ae6dd5c 100644 --- a/src/model/GModelSpatialDiffuseCube.cpp +++ b/src/model/GModelSpatialDiffuseCube.cpp @@ -363,11 +363,15 @@ double GModelSpatialDiffuseCube::eval(const GPhoton& photon, * @exception GException::invalid_value * No map cube defined. * No energy boundaries defined. - * Simulation cone not defined or does not overlap with map cube. + * @exception GException::invalid_return_value + * Simulation cone not defined, does not overlap with map cube or + * map cube is empty for the specified energy. * * Returns a random sky direction according to the intensity distribution of * the model sky map and the specified energy. The method uses a rejection - * method to determine the sky direction. + * method to determine the sky direction. If no sky direction could be + * determined, the method throws an GException::invalid_return_value + * exception. ***************************************************************************/ GSkyDir GModelSpatialDiffuseCube::mc(const GEnergy& energy, const GTime& time, @@ -430,7 +434,7 @@ GSkyDir GModelSpatialDiffuseCube::mc(const GEnergy& energy, "restrict the simulated energies to values where the map " "cube is non-zero within the simulation cone."; } - throw GException::invalid_value(G_MC, msg); + throw GException::invalid_return_value(G_MC, msg); } // Allocate sky direction diff --git a/src/model/GModelSpatialDiffuseMap.cpp b/src/model/GModelSpatialDiffuseMap.cpp index ed8694f..eac8923 100644 --- a/src/model/GModelSpatialDiffuseMap.cpp +++ b/src/model/GModelSpatialDiffuseMap.cpp @@ -350,12 +350,15 @@ double GModelSpatialDiffuseMap::eval(const GPhoton& photon, * @return Sky direction. * * @exception GException::invalid_value - * Simulation cone not defined or does not overlap with sky map. * No sky map defined. + * @exception GException::invalid_return_value + * Simulation cone not defined, does not overlap with map or map + * is empty. * * Returns a random sky direction according to the intensity distribution of * the model sky map. The method uses a rejection method to determine the sky - * direction. + * direction. If no sky direction could be determined, the method throws an + * GException::invalid_return_value exception. ***************************************************************************/ GSkyDir GModelSpatialDiffuseMap::mc(const GEnergy& energy, const GTime& time, @@ -368,7 +371,7 @@ GSkyDir GModelSpatialDiffuseMap::mc(const GEnergy& energy, std::string msg = "Simulation cone has not been defined or does not " "overlap with the sky map. Please specify a valid " "simulation cone."; - throw GException::invalid_value(G_MC, msg); + throw GException::invalid_return_value(G_MC, msg); } // Determine number of skymap pixels diff --git a/src/support/GException.cpp b/src/support/GException.cpp index 198830e..5cc2df9 100644 --- a/src/support/GException.cpp +++ b/src/support/GException.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * GException.cpp - exception handlers * * ----------------------------------------------------------------------- * - * copyright (C) 2006-2015 by Juergen Knoedlseder * + * copyright (C) 2006-2017 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -89,6 +89,29 @@ GException::invalid_argument::invalid_argument(const std::string& origin, /***********************************************************************//** + * @brief Invalid return value + * + * @param[in] origin Name of method that has thrown the exception. + * @param[in] message Error message. + ***************************************************************************/ +GException::invalid_return_value::invalid_return_value(const std::string& origin, + const std::string& message) +{ + // Set origin + m_origin = origin; + + // Set message string + m_message = "Invalid return value."; + if (message.length() > 0) { + m_message += (" " + message); + } + + // Return + return; +} + + +/***********************************************************************//** * @brief Index is out of range [0,elements-1] * * @param[in] origin Method throwing the exception.