Commit 045c40f4f63b336fedcad716201189da491db487
1 parent
f5b90eec
Add GModelSpatialRadialProfile base class and GModelSpatialRadialProfileGauss derived class (#1520)
The GModelSpatialRadialProfile class is the base class for an arbitrary radial model. The GModelSpatialRadialProfileGauss class basically illustrates its usage, and provides a comparison with the analytical Gaussian model, implemented by GModelSpatialRadialGauss.
Showing
12 changed files
with
1267 additions
and
3 deletions
ChangeLog
| 1 | -2016-02-28 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> | 1 | +2016-03-01 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> |
| 2 | 2 | ||
| 3 | * Version 1.1.0 released | 3 | * Version 1.1.0 released |
| 4 | ========================= | 4 | ========================= |
| 5 | 5 | ||
| 6 | + Add GModelSpatialRadialProfile and GModelSpatialRadialProfileGauss classes (#1520) | ||
| 6 | Make GFilename::is_fits thread safe (#1717). | 7 | Make GFilename::is_fits thread safe (#1717). |
| 7 | Revise GTime operators (#1714) | 8 | Revise GTime operators (#1714) |
| 8 | Add GSkyMap::publish() method to publish map on VO Hub (#1710) | 9 | Add GSkyMap::publish() method to publish map on VO Hub (#1710) |
NEWS
| @@ -2,7 +2,7 @@ New Features and Important Changes in GammaLib 1.1.0 | @@ -2,7 +2,7 @@ New Features and Important Changes in GammaLib 1.1.0 | ||
| 2 | 2 | ||
| 3 | Author(s) : Juergen Knoedlseder | 3 | Author(s) : Juergen Knoedlseder |
| 4 | 4 | ||
| 5 | -28 February 2016 | 5 | +1 March 2016 |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | 1. Introduction | 8 | 1. Introduction |
| @@ -142,6 +142,14 @@ GModelSpatialDiffuseMap class now recompute only the Monte Carlo acceptance | @@ -142,6 +142,14 @@ GModelSpatialDiffuseMap class now recompute only the Monte Carlo acceptance | ||
| 142 | cone in case that the cone centre or radius have changed since the last | 142 | cone in case that the cone centre or radius have changed since the last |
| 143 | computation. This speeds up the computations (#1673). | 143 | computation. This speeds up the computations (#1673). |
| 144 | 144 | ||
| 145 | +Add GModelSpatialRadialProfile class to handle arbitrary radial profiles. | ||
| 146 | +The method deals with pre-computation and normalization of the profiles, | ||
| 147 | +and implements the eval(), eval_grandients() and mc() method. The class | ||
| 148 | +GModelSpatialRadialProfileGauss has been added to show how to implement | ||
| 149 | +radial profile for the case of a Gaussian, and also to cross-check the | ||
| 150 | +results with the GModelSpatialRadialGauss class that should return basically | ||
| 151 | +the same results (#1520). | ||
| 152 | + | ||
| 145 | 153 | ||
| 146 | 9. Numerics module | 154 | 9. Numerics module |
| 147 | ------------------ | 155 | ------------------ |
include/GModelSpatialRadialProfile.hpp
0 → 100644
| 1 | +/*************************************************************************** | ||
| 2 | + * GModelSpatialRadialProfile.hpp - Radial profile source model class * | ||
| 3 | + * ----------------------------------------------------------------------- * | ||
| 4 | + * copyright (C) 2016 by Juergen Knoedlseder * | ||
| 5 | + * ----------------------------------------------------------------------- * | ||
| 6 | + * * | ||
| 7 | + * This program is free software: you can redistribute it and/or modify * | ||
| 8 | + * it under the terms of the GNU General Public License as published by * | ||
| 9 | + * the Free Software Foundation, either version 3 of the License, or * | ||
| 10 | + * (at your option) any later version. * | ||
| 11 | + * * | ||
| 12 | + * This program is distributed in the hope that it will be useful, * | ||
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
| 15 | + * GNU General Public License for more details. * | ||
| 16 | + * * | ||
| 17 | + * You should have received a copy of the GNU General Public License * | ||
| 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
| 19 | + * * | ||
| 20 | + ***************************************************************************/ | ||
| 21 | +/** | ||
| 22 | + * @file GModelSpatialRadialProfile.hpp | ||
| 23 | + * @brief Radial profile model class interface definition | ||
| 24 | + * @author Juergen Knoedlseder | ||
| 25 | + */ | ||
| 26 | + | ||
| 27 | +#ifndef GMODELSPATIALRADIALPROFILE_HPP | ||
| 28 | +#define GMODELSPATIALRADIALPROFILE_HPP | ||
| 29 | + | ||
| 30 | +/* __ Includes ___________________________________________________________ */ | ||
| 31 | +#include <string> | ||
| 32 | +#include "GModelSpatialRadial.hpp" | ||
| 33 | +#include "GNodeArray.hpp" | ||
| 34 | + | ||
| 35 | +/* __ Forward declaration ________________________________________________ */ | ||
| 36 | +class GXmlElement; | ||
| 37 | +class GSkyDir; | ||
| 38 | + | ||
| 39 | + | ||
| 40 | +/************************************************************************** | ||
| 41 | + * @class GModelSpatialRadialProfile | ||
| 42 | + * | ||
| 43 | + * @brief Radial profile source model class | ||
| 44 | + * | ||
| 45 | + * This class implements the spatial component of the factorised source | ||
| 46 | + * model for an arbitrary radial profile. | ||
| 47 | + ***************************************************************************/ | ||
| 48 | +class GModelSpatialRadialProfile : public GModelSpatialRadial { | ||
| 49 | + | ||
| 50 | +public: | ||
| 51 | + // Constructors and destructors | ||
| 52 | + GModelSpatialRadialProfile(void); | ||
| 53 | + explicit GModelSpatialRadialProfile(const GXmlElement& xml); | ||
| 54 | + GModelSpatialRadialProfile(const GModelSpatialRadialProfile& model); | ||
| 55 | + virtual ~GModelSpatialRadialProfile(void); | ||
| 56 | + | ||
| 57 | + // Operators | ||
| 58 | + virtual GModelSpatialRadialProfile& operator=(const GModelSpatialRadialProfile& model); | ||
| 59 | + | ||
| 60 | + // Pure virtual methods | ||
| 61 | + virtual void clear(void) = 0; | ||
| 62 | + virtual GModelSpatialRadialProfile* clone(void) const = 0; | ||
| 63 | + virtual std::string classname(void) const = 0; | ||
| 64 | + virtual std::string type(void) const = 0; | ||
| 65 | + virtual double theta_max(void) const = 0; | ||
| 66 | + virtual std::string print(const GChatter& chatter = NORMAL) const = 0; | ||
| 67 | + | ||
| 68 | + // Implemented pure virtual base class methods | ||
| 69 | + virtual double eval(const double& theta, | ||
| 70 | + const GEnergy& energy, | ||
| 71 | + const GTime& time) const; | ||
| 72 | + virtual double eval_gradients(const double& theta, | ||
| 73 | + const GEnergy& energy, | ||
| 74 | + const GTime& time) const; | ||
| 75 | + virtual GSkyDir mc(const GEnergy& energy, | ||
| 76 | + const GTime& time, | ||
| 77 | + GRan& ran) const; | ||
| 78 | + virtual bool contains(const GSkyDir& dir, | ||
| 79 | + const double& margin = 0.0) const; | ||
| 80 | + | ||
| 81 | + // Implement other methods | ||
| 82 | + int num_nodes(void) const; | ||
| 83 | + void num_nodes(const int& number); | ||
| 84 | + | ||
| 85 | +protected: | ||
| 86 | + // Protected methods | ||
| 87 | + void init_members(void); | ||
| 88 | + void copy_members(const GModelSpatialRadialProfile& model); | ||
| 89 | + void free_members(void); | ||
| 90 | + int cache_index(void) const; | ||
| 91 | + virtual double profile_value(const double& theta) const = 0; | ||
| 92 | + | ||
| 93 | + // Protected members | ||
| 94 | + int m_num_nodes; //!< Number of profile nodes | ||
| 95 | + | ||
| 96 | + // Pre-computed radial profile | ||
| 97 | + struct profile { | ||
| 98 | + std::vector<double> pars; //!< Profile parameters | ||
| 99 | + GNodeArray nodes; //!< Profile nodes | ||
| 100 | + std::vector<double> values; //!< Profile values | ||
| 101 | + std::vector<double> mc; //!< Profile for MC | ||
| 102 | + double mc_max; //!< Maximum of profile for MC | ||
| 103 | + }; | ||
| 104 | + | ||
| 105 | + // Pre-computation cache | ||
| 106 | + mutable std::vector<profile> m_profile; // Pre-computation cache | ||
| 107 | +}; | ||
| 108 | + | ||
| 109 | + | ||
| 110 | +/***********************************************************************//** | ||
| 111 | + * @brief Return number of nodes | ||
| 112 | + * | ||
| 113 | + * @return Number of nodes. | ||
| 114 | + * | ||
| 115 | + * Returns the number of nodes in the radial profile. | ||
| 116 | + ***************************************************************************/ | ||
| 117 | +inline | ||
| 118 | +int GModelSpatialRadialProfile::num_nodes(void) const | ||
| 119 | +{ | ||
| 120 | + return (m_num_nodes); | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | + | ||
| 124 | +/***********************************************************************//** | ||
| 125 | + * @brief Set number of nodes | ||
| 126 | + * | ||
| 127 | + * @param[in] number Number of nodes. | ||
| 128 | + * | ||
| 129 | + * Sets the number of nodes in the radial profile. | ||
| 130 | + ***************************************************************************/ | ||
| 131 | +inline | ||
| 132 | +void GModelSpatialRadialProfile::num_nodes(const int& number) | ||
| 133 | +{ | ||
| 134 | + m_num_nodes = number; | ||
| 135 | + return; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +#endif /* GMODELSPATIALRADIALPROFILE_HPP */ |
include/GModelSpatialRadialProfileGauss.hpp
0 → 100644
| 1 | +/*************************************************************************** | ||
| 2 | + * GModelSpatialRadialProfileGauss.hpp - Gaussian radial profile class * | ||
| 3 | + * ----------------------------------------------------------------------- * | ||
| 4 | + * copyright (C) 2016 by Juergen Knoedlseder * | ||
| 5 | + * ----------------------------------------------------------------------- * | ||
| 6 | + * * | ||
| 7 | + * This program is free software: you can redistribute it and/or modify * | ||
| 8 | + * it under the terms of the GNU General Public License as published by * | ||
| 9 | + * the Free Software Foundation, either version 3 of the License, or * | ||
| 10 | + * (at your option) any later version. * | ||
| 11 | + * * | ||
| 12 | + * This program is distributed in the hope that it will be useful, * | ||
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
| 15 | + * GNU General Public License for more details. * | ||
| 16 | + * * | ||
| 17 | + * You should have received a copy of the GNU General Public License * | ||
| 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
| 19 | + * * | ||
| 20 | + ***************************************************************************/ | ||
| 21 | +/** | ||
| 22 | + * @file GModelSpatialRadialProfileGauss.hpp | ||
| 23 | + * @brief Radial Gaussian profile model class interface definition | ||
| 24 | + * @author Juergen Knoedlseder | ||
| 25 | + */ | ||
| 26 | + | ||
| 27 | +#ifndef GMODELSPATIALRADIALPROFILEGAUSS_HPP | ||
| 28 | +#define GMODELSPATIALRADIALPROFILEGAUSS_HPP | ||
| 29 | + | ||
| 30 | +/* __ Includes ___________________________________________________________ */ | ||
| 31 | +#include <string> | ||
| 32 | +#include "GModelSpatialRadialProfile.hpp" | ||
| 33 | +#include "GModelPar.hpp" | ||
| 34 | + | ||
| 35 | +/* __ Forward declaration ________________________________________________ */ | ||
| 36 | +class GXmlElement; | ||
| 37 | + | ||
| 38 | + | ||
| 39 | +/************************************************************************** | ||
| 40 | + * @class GModelSpatialRadialProfileGauss | ||
| 41 | + * | ||
| 42 | + * @brief Radial Gaussian profile source model class | ||
| 43 | + * | ||
| 44 | + * This class implements the spatial component of the factorised source | ||
| 45 | + * model for a Gaussian radial profile. | ||
| 46 | + ***************************************************************************/ | ||
| 47 | +class GModelSpatialRadialProfileGauss : public GModelSpatialRadialProfile { | ||
| 48 | + | ||
| 49 | +public: | ||
| 50 | + // Constructors and destructors | ||
| 51 | + GModelSpatialRadialProfileGauss(void); | ||
| 52 | + explicit GModelSpatialRadialProfileGauss(const GXmlElement& xml); | ||
| 53 | + GModelSpatialRadialProfileGauss(const GModelSpatialRadialProfileGauss& model); | ||
| 54 | + virtual ~GModelSpatialRadialProfileGauss(void); | ||
| 55 | + | ||
| 56 | + // Operators | ||
| 57 | + virtual GModelSpatialRadialProfileGauss& operator=(const GModelSpatialRadialProfileGauss& model); | ||
| 58 | + | ||
| 59 | + // Implemented pure virtual base class methods | ||
| 60 | + virtual void clear(void); | ||
| 61 | + virtual GModelSpatialRadialProfileGauss* clone(void) const; | ||
| 62 | + virtual std::string classname(void) const; | ||
| 63 | + virtual std::string type(void) const; | ||
| 64 | + virtual double theta_max(void) const; | ||
| 65 | + virtual void read(const GXmlElement& xml); | ||
| 66 | + virtual void write(GXmlElement& xml) const; | ||
| 67 | + virtual std::string print(const GChatter& chatter = NORMAL) const; | ||
| 68 | + | ||
| 69 | +protected: | ||
| 70 | + // Protected methods | ||
| 71 | + void init_members(void); | ||
| 72 | + void copy_members(const GModelSpatialRadialProfileGauss& model); | ||
| 73 | + void free_members(void); | ||
| 74 | + virtual double profile_value(const double& theta) const; | ||
| 75 | + | ||
| 76 | + // Protected members | ||
| 77 | + GModelPar m_sigma; //!< Gaussian width (deg) | ||
| 78 | +}; | ||
| 79 | + | ||
| 80 | + | ||
| 81 | +/***********************************************************************//** | ||
| 82 | + * @brief Return class name | ||
| 83 | + * | ||
| 84 | + * @return String containing the class name ("GModelSpatialRadialProfileGauss"). | ||
| 85 | + ***************************************************************************/ | ||
| 86 | +inline | ||
| 87 | +std::string GModelSpatialRadialProfileGauss::classname(void) const | ||
| 88 | +{ | ||
| 89 | + return ("GModelSpatialRadialProfileGauss"); | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | + | ||
| 93 | +/***********************************************************************//** | ||
| 94 | + * @brief Return model type | ||
| 95 | + * | ||
| 96 | + * @return "GaussianProfile". | ||
| 97 | + * | ||
| 98 | + * Returns the type of the radial profile model. | ||
| 99 | + ***************************************************************************/ | ||
| 100 | +inline | ||
| 101 | +std::string GModelSpatialRadialProfileGauss::type(void) const | ||
| 102 | +{ | ||
| 103 | + return "GaussianProfile"; | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +#endif /* GMODELSPATIALRADIALPROFILEGAUSS_HPP */ |
include/GammaLib.hpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * GammaLib.hpp - Gamma-Ray Astronomy Library Header file * | 2 | * GammaLib.hpp - Gamma-Ray Astronomy Library Header file * |
| 3 | * ----------------------------------------------------------------------- * | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2006-2015 by Juergen Knoedlseder * | 4 | + * copyright (C) 2006-2016 by Juergen Knoedlseder * |
| 5 | * ----------------------------------------------------------------------- * | 5 | * ----------------------------------------------------------------------- * |
| 6 | * * | 6 | * * |
| 7 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -196,6 +196,8 @@ | @@ -196,6 +196,8 @@ | ||
| 196 | #include "GModelSpatialRadialDisk.hpp" | 196 | #include "GModelSpatialRadialDisk.hpp" |
| 197 | #include "GModelSpatialRadialGauss.hpp" | 197 | #include "GModelSpatialRadialGauss.hpp" |
| 198 | #include "GModelSpatialRadialShell.hpp" | 198 | #include "GModelSpatialRadialShell.hpp" |
| 199 | +#include "GModelSpatialRadialProfile.hpp" | ||
| 200 | +#include "GModelSpatialRadialProfileGauss.hpp" | ||
| 199 | #include "GModelSpatialElliptical.hpp" | 201 | #include "GModelSpatialElliptical.hpp" |
| 200 | #include "GModelSpatialEllipticalDisk.hpp" | 202 | #include "GModelSpatialEllipticalDisk.hpp" |
| 201 | #include "GModelSpatialEllipticalGauss.hpp" | 203 | #include "GModelSpatialEllipticalGauss.hpp" |
include/Makefile.am
| @@ -133,6 +133,8 @@ pkginclude_HEADERS = GammaLib.hpp \ | @@ -133,6 +133,8 @@ pkginclude_HEADERS = GammaLib.hpp \ | ||
| 133 | GModelSpatialRadialDisk.hpp \ | 133 | GModelSpatialRadialDisk.hpp \ |
| 134 | GModelSpatialRadialGauss.hpp \ | 134 | GModelSpatialRadialGauss.hpp \ |
| 135 | GModelSpatialRadialShell.hpp \ | 135 | GModelSpatialRadialShell.hpp \ |
| 136 | + GModelSpatialRadialProfile.hpp \ | ||
| 137 | + GModelSpatialRadialProfileGauss.hpp \ | ||
| 136 | GModelSpatialElliptical.hpp \ | 138 | GModelSpatialElliptical.hpp \ |
| 137 | GModelSpatialEllipticalDisk.hpp \ | 139 | GModelSpatialEllipticalDisk.hpp \ |
| 138 | GModelSpatialEllipticalGauss.hpp \ | 140 | GModelSpatialEllipticalGauss.hpp \ |
pyext/GModelSpatialRadialProfile.i
0 → 100644
| 1 | +/*************************************************************************** | ||
| 2 | + * GModelSpatialRadialProfile.i - Radial profile source model class * | ||
| 3 | + * ----------------------------------------------------------------------- * | ||
| 4 | + * copyright (C) 2016 by Juergen Knoedlseder * | ||
| 5 | + * ----------------------------------------------------------------------- * | ||
| 6 | + * * | ||
| 7 | + * This program is free software: you can redistribute it and/or modify * | ||
| 8 | + * it under the terms of the GNU General Public License as published by * | ||
| 9 | + * the Free Software Foundation, either version 3 of the License, or * | ||
| 10 | + * (at your option) any later version. * | ||
| 11 | + * * | ||
| 12 | + * This program is distributed in the hope that it will be useful, * | ||
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
| 15 | + * GNU General Public License for more details. * | ||
| 16 | + * * | ||
| 17 | + * You should have received a copy of the GNU General Public License * | ||
| 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
| 19 | + * * | ||
| 20 | + ***************************************************************************/ | ||
| 21 | +/** | ||
| 22 | + * @file GModelSpatialRadialProfile.i | ||
| 23 | + * @brief Radial profile model class interface definition | ||
| 24 | + * @author Juergen Knoedlseder | ||
| 25 | + */ | ||
| 26 | +%{ | ||
| 27 | +/* Put headers and other declarations here that are needed for compilation */ | ||
| 28 | +#include "GModelSpatialRadialProfile.hpp" | ||
| 29 | +%} | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +/************************************************************************** | ||
| 33 | + * @class GModelSpatialRadialProfile | ||
| 34 | + * | ||
| 35 | + * @brief Radial profile source model class | ||
| 36 | + * | ||
| 37 | + * This class implements the spatial component of the factorised source | ||
| 38 | + * model for an arbitrary radial profile. | ||
| 39 | + ***************************************************************************/ | ||
| 40 | +class GModelSpatialRadialProfile : public GModelSpatialRadial { | ||
| 41 | + | ||
| 42 | +public: | ||
| 43 | + // Constructors and destructors | ||
| 44 | + GModelSpatialRadialProfile(void); | ||
| 45 | + explicit GModelSpatialRadialProfile(const GXmlElement& xml); | ||
| 46 | + GModelSpatialRadialProfile(const GModelSpatialRadialProfile& model); | ||
| 47 | + virtual ~GModelSpatialRadialProfile(void); | ||
| 48 | + | ||
| 49 | + // Pure virtual methods | ||
| 50 | + virtual void clear(void) = 0; | ||
| 51 | + virtual GModelSpatialRadialProfile* clone(void) const = 0; | ||
| 52 | + virtual std::string classname(void) const = 0; | ||
| 53 | + virtual std::string type(void) const = 0; | ||
| 54 | + virtual double theta_max(void) const = 0; | ||
| 55 | + | ||
| 56 | + // Implemented pure virtual base class methods | ||
| 57 | + virtual double eval(const double& theta, | ||
| 58 | + const GEnergy& energy, | ||
| 59 | + const GTime& time) const; | ||
| 60 | + virtual double eval_gradients(const double& theta, | ||
| 61 | + const GEnergy& energy, | ||
| 62 | + const GTime& time) const; | ||
| 63 | + virtual GSkyDir mc(const GEnergy& energy, | ||
| 64 | + const GTime& time, | ||
| 65 | + GRan& ran) const; | ||
| 66 | + virtual bool contains(const GSkyDir& dir, | ||
| 67 | + const double& margin = 0.0) const; | ||
| 68 | + | ||
| 69 | + // Implement other methods | ||
| 70 | + int num_nodes(void) const; | ||
| 71 | + void num_nodes(const int& number); | ||
| 72 | +}; |
pyext/GModelSpatialRadialProfileGauss.i
0 → 100644
| 1 | +/*************************************************************************** | ||
| 2 | + * GModelSpatialRadialProfileGauss.i - Gaussian radial profile class * | ||
| 3 | + * ----------------------------------------------------------------------- * | ||
| 4 | + * copyright (C) 2016 by Juergen Knoedlseder * | ||
| 5 | + * ----------------------------------------------------------------------- * | ||
| 6 | + * * | ||
| 7 | + * This program is free software: you can redistribute it and/or modify * | ||
| 8 | + * it under the terms of the GNU General Public License as published by * | ||
| 9 | + * the Free Software Foundation, either version 3 of the License, or * | ||
| 10 | + * (at your option) any later version. * | ||
| 11 | + * * | ||
| 12 | + * This program is distributed in the hope that it will be useful, * | ||
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
| 15 | + * GNU General Public License for more details. * | ||
| 16 | + * * | ||
| 17 | + * You should have received a copy of the GNU General Public License * | ||
| 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
| 19 | + * * | ||
| 20 | + ***************************************************************************/ | ||
| 21 | +/** | ||
| 22 | + * @file GModelSpatialRadialProfileGauss.hpp | ||
| 23 | + * @brief Radial Gaussian profile model class interface definition | ||
| 24 | + * @author Juergen Knoedlseder | ||
| 25 | + */ | ||
| 26 | +%{ | ||
| 27 | +/* Put headers and other declarations here that are needed for compilation */ | ||
| 28 | +#include "GModelSpatialRadialProfileGauss.hpp" | ||
| 29 | +%} | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +/************************************************************************** | ||
| 33 | + * @class GModelSpatialRadialProfileGauss | ||
| 34 | + * | ||
| 35 | + * @brief Radial Gaussian profile source model class | ||
| 36 | + * | ||
| 37 | + * This class implements the spatial component of the factorised source | ||
| 38 | + * model for a Gaussian radial profile. | ||
| 39 | + ***************************************************************************/ | ||
| 40 | +class GModelSpatialRadialProfileGauss : public GModelSpatialRadialProfile { | ||
| 41 | + | ||
| 42 | +public: | ||
| 43 | + // Constructors and destructors | ||
| 44 | + GModelSpatialRadialProfileGauss(void); | ||
| 45 | + explicit GModelSpatialRadialProfileGauss(const GXmlElement& xml); | ||
| 46 | + GModelSpatialRadialProfileGauss(const GModelSpatialRadialProfileGauss& model); | ||
| 47 | + virtual ~GModelSpatialRadialProfileGauss(void); | ||
| 48 | + | ||
| 49 | + // Implemented pure virtual base class methods | ||
| 50 | + virtual void clear(void); | ||
| 51 | + virtual GModelSpatialRadialProfileGauss* clone(void) const; | ||
| 52 | + virtual std::string classname(void) const; | ||
| 53 | + virtual std::string type(void) const; | ||
| 54 | + virtual double theta_max(void) const; | ||
| 55 | + virtual void read(const GXmlElement& xml); | ||
| 56 | + virtual void write(GXmlElement& xml) const; | ||
| 57 | +}; | ||
| 58 | + | ||
| 59 | + | ||
| 60 | +/***********************************************************************//** | ||
| 61 | + * @brief GModelSpatialRadialGauss class extension | ||
| 62 | + * | ||
| 63 | + * The eval(GSkyDir&) and eval_gradients(GSkyDir&) need to be defined in the | ||
| 64 | + * extension to force swig to build also the interface for these methods that | ||
| 65 | + * are implemented in the base class only. It's not clear to me why these | ||
| 66 | + * methods are not inherited automatically. Maybe this could also be handled | ||
| 67 | + * by a %typemap(typecheck) construct. | ||
| 68 | + ***************************************************************************/ | ||
| 69 | +%extend GModelSpatialRadialProfileGauss { | ||
| 70 | + double eval(const GPhoton& photon) const { | ||
| 71 | + return self->GModelSpatialRadial::eval(photon); | ||
| 72 | + } | ||
| 73 | + double eval_gradients(const GPhoton& photon) const { | ||
| 74 | + return self->GModelSpatialRadial::eval_gradients(photon); | ||
| 75 | + } | ||
| 76 | +}; |
pyext/gammalib/model.i
| @@ -134,6 +134,8 @@ | @@ -134,6 +134,8 @@ | ||
| 134 | %include "GModelSpatialRadialDisk.i" | 134 | %include "GModelSpatialRadialDisk.i" |
| 135 | %include "GModelSpatialRadialGauss.i" | 135 | %include "GModelSpatialRadialGauss.i" |
| 136 | %include "GModelSpatialRadialShell.i" | 136 | %include "GModelSpatialRadialShell.i" |
| 137 | +%include "GModelSpatialRadialProfile.i" | ||
| 138 | +%include "GModelSpatialRadialProfileGauss.i" | ||
| 137 | %include "GModelSpatialElliptical.i" | 139 | %include "GModelSpatialElliptical.i" |
| 138 | %include "GModelSpatialEllipticalDisk.i" | 140 | %include "GModelSpatialEllipticalDisk.i" |
| 139 | %include "GModelSpatialEllipticalGauss.i" | 141 | %include "GModelSpatialEllipticalGauss.i" |
src/model/GModelSpatialRadialProfile.cpp
0 → 100644
| 1 | +/*************************************************************************** | ||
| 2 | + * GModelSpatialRadialProfile.cpp - Radial profile source model class * | ||
| 3 | + * ----------------------------------------------------------------------- * | ||
| 4 | + * copyright (C) 2016 by Juergen Knoedlseder * | ||
| 5 | + * ----------------------------------------------------------------------- * | ||
| 6 | + * * | ||
| 7 | + * This program is free software: you can redistribute it and/or modify * | ||
| 8 | + * it under the terms of the GNU General Public License as published by * | ||
| 9 | + * the Free Software Foundation, either version 3 of the License, or * | ||
| 10 | + * (at your option) any later version. * | ||
| 11 | + * * | ||
| 12 | + * This program is distributed in the hope that it will be useful, * | ||
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
| 15 | + * GNU General Public License for more details. * | ||
| 16 | + * * | ||
| 17 | + * You should have received a copy of the GNU General Public License * | ||
| 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
| 19 | + * * | ||
| 20 | + ***************************************************************************/ | ||
| 21 | +/** | ||
| 22 | + * @file GModelSpatialRadialProfile.cpp | ||
| 23 | + * @brief Radial profile model class implementation | ||
| 24 | + * @author Juergen Knoedlseder | ||
| 25 | + */ | ||
| 26 | + | ||
| 27 | +/* __ Includes ___________________________________________________________ */ | ||
| 28 | +#ifdef HAVE_CONFIG_H | ||
| 29 | +#include <config.h> | ||
| 30 | +#endif | ||
| 31 | +#include "GException.hpp" | ||
| 32 | +#include "GTools.hpp" | ||
| 33 | +#include "GMath.hpp" | ||
| 34 | +#include "GSkyDir.hpp" | ||
| 35 | +#include "GXmlElement.hpp" | ||
| 36 | +#include "GModelSpatialRadialProfile.hpp" | ||
| 37 | + | ||
| 38 | +/* __ Constants __________________________________________________________ */ | ||
| 39 | + | ||
| 40 | +/* __ Globals ____________________________________________________________ */ | ||
| 41 | + | ||
| 42 | +/* __ Method name definitions ____________________________________________ */ | ||
| 43 | + | ||
| 44 | +/* __ Macros _____________________________________________________________ */ | ||
| 45 | + | ||
| 46 | +/* __ Coding definitions _________________________________________________ */ | ||
| 47 | + | ||
| 48 | +/* __ Debug definitions __________________________________________________ */ | ||
| 49 | +//#define G_DEBUG_PRECOMPUTATION | ||
| 50 | + | ||
| 51 | + | ||
| 52 | +/*========================================================================== | ||
| 53 | + = = | ||
| 54 | + = Constructors/destructors = | ||
| 55 | + = = | ||
| 56 | + ==========================================================================*/ | ||
| 57 | + | ||
| 58 | +/***********************************************************************//** | ||
| 59 | + * @brief Void constructor | ||
| 60 | + * | ||
| 61 | + * Constructs empty radial profile | ||
| 62 | + ***************************************************************************/ | ||
| 63 | +GModelSpatialRadialProfile::GModelSpatialRadialProfile(void) : | ||
| 64 | + GModelSpatialRadial() | ||
| 65 | +{ | ||
| 66 | + // Initialise members | ||
| 67 | + init_members(); | ||
| 68 | + | ||
| 69 | + // Return | ||
| 70 | + return; | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | + | ||
| 74 | +/***********************************************************************//** | ||
| 75 | + * @brief XML constructor | ||
| 76 | + * | ||
| 77 | + * @param[in] xml XML element. | ||
| 78 | + * | ||
| 79 | + * Constructs radial profile model by extracting information from an XML | ||
| 80 | + * elements. | ||
| 81 | + ***************************************************************************/ | ||
| 82 | +GModelSpatialRadialProfile::GModelSpatialRadialProfile(const GXmlElement& xml) : | ||
| 83 | + GModelSpatialRadial() | ||
| 84 | +{ | ||
| 85 | + // Initialise members | ||
| 86 | + init_members(); | ||
| 87 | + | ||
| 88 | + // Read information from XML element | ||
| 89 | + read(xml); | ||
| 90 | + | ||
| 91 | + // Return | ||
| 92 | + return; | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | + | ||
| 96 | +/***********************************************************************//** | ||
| 97 | + * @brief Copy constructor | ||
| 98 | + * | ||
| 99 | + * @param[in] model Radial profile model. | ||
| 100 | + * | ||
| 101 | + * Copies radial profile model from another radial profile model. | ||
| 102 | + ***************************************************************************/ | ||
| 103 | +GModelSpatialRadialProfile::GModelSpatialRadialProfile(const GModelSpatialRadialProfile& model) : | ||
| 104 | + GModelSpatialRadial(model) | ||
| 105 | +{ | ||
| 106 | + // Initialise members | ||
| 107 | + init_members(); | ||
| 108 | + | ||
| 109 | + // Copy members | ||
| 110 | + copy_members(model); | ||
| 111 | + | ||
| 112 | + // Return | ||
| 113 | + return; | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | + | ||
| 117 | +/***********************************************************************//** | ||
| 118 | + * @brief Destructor | ||
| 119 | + * | ||
| 120 | + * Destructs radial profile model. | ||
| 121 | + ***************************************************************************/ | ||
| 122 | +GModelSpatialRadialProfile::~GModelSpatialRadialProfile(void) | ||
| 123 | +{ | ||
| 124 | + // Free members | ||
| 125 | + free_members(); | ||
| 126 | + | ||
| 127 | + // Return | ||
| 128 | + return; | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | + | ||
| 132 | +/*========================================================================== | ||
| 133 | + = = | ||
| 134 | + = Operators = | ||
| 135 | + = = | ||
| 136 | + ==========================================================================*/ | ||
| 137 | + | ||
| 138 | +/***********************************************************************//** | ||
| 139 | + * @brief Assignment operator | ||
| 140 | + * | ||
| 141 | + * @param[in] model Radial profile model. | ||
| 142 | + * @return Radial profile model. | ||
| 143 | + * | ||
| 144 | + * Assigns radial profile model. | ||
| 145 | + ***************************************************************************/ | ||
| 146 | +GModelSpatialRadialProfile& GModelSpatialRadialProfile::operator=(const GModelSpatialRadialProfile& model) | ||
| 147 | +{ | ||
| 148 | + // Execute only if object is not identical | ||
| 149 | + if (this != &model) { | ||
| 150 | + | ||
| 151 | + // Copy base class members | ||
| 152 | + this->GModelSpatialRadial::operator=(model); | ||
| 153 | + | ||
| 154 | + // Free members | ||
| 155 | + free_members(); | ||
| 156 | + | ||
| 157 | + // Initialise members | ||
| 158 | + init_members(); | ||
| 159 | + | ||
| 160 | + // Copy members | ||
| 161 | + copy_members(model); | ||
| 162 | + | ||
| 163 | + } // endif: object was not identical | ||
| 164 | + | ||
| 165 | + // Return | ||
| 166 | + return *this; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | + | ||
| 170 | +/*========================================================================== | ||
| 171 | + = = | ||
| 172 | + = Public methods = | ||
| 173 | + = = | ||
| 174 | + ==========================================================================*/ | ||
| 175 | + | ||
| 176 | +/***********************************************************************//** | ||
| 177 | + * @brief Evaluate function (in units of sr^-1) | ||
| 178 | + * | ||
| 179 | + * @param[in] theta Angular distance from model centre (radians). | ||
| 180 | + * @param[in] energy Photon energy. | ||
| 181 | + * @param[in] time Photon arrival time. | ||
| 182 | + * @return Model value. | ||
| 183 | + * | ||
| 184 | + * Evaluate the radial profile model for a given angular distance @p theta | ||
| 185 | + * the model centre, a given photon @p energy and a given @p time. The | ||
| 186 | + * method evaluates the model by linear interpolation. | ||
| 187 | + ***************************************************************************/ | ||
| 188 | +double GModelSpatialRadialProfile::eval(const double& theta, | ||
| 189 | + const GEnergy& energy, | ||
| 190 | + const GTime& time) const | ||
| 191 | +{ | ||
| 192 | + // Get pre-computation cache index | ||
| 193 | + int icache = cache_index(); | ||
| 194 | + | ||
| 195 | + // Get interpolation value | ||
| 196 | + double value = m_profile[icache].nodes.interpolate(theta, m_profile[icache].values); | ||
| 197 | + | ||
| 198 | + // Make sure that value is not-negative | ||
| 199 | + if (value < 0.0) { | ||
| 200 | + value = 0.0; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + // Compile option: Check for NaN/Inf | ||
| 204 | + #if defined(G_NAN_CHECK) | ||
| 205 | + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) { | ||
| 206 | + std::cout << "*** ERROR: GModelSpatialRadialProfile::eval"; | ||
| 207 | + std::cout << "(theta=" << theta << "): NaN/Inf encountered"; | ||
| 208 | + std::cout << " (value=" << value; | ||
| 209 | + std::cout << ")" << std::endl; | ||
| 210 | + } | ||
| 211 | + #endif | ||
| 212 | + | ||
| 213 | + // Return value | ||
| 214 | + return value; | ||
| 215 | +} | ||
| 216 | + | ||
| 217 | + | ||
| 218 | +/***********************************************************************//** | ||
| 219 | + * @brief Evaluate function and gradients (in units of sr^-1) | ||
| 220 | + * | ||
| 221 | + * @param[in] theta Angular distance from model centre (radians). | ||
| 222 | + * @param[in] energy Photon energy. | ||
| 223 | + * @param[in] time Photon arrival time. | ||
| 224 | + * @return Model value. | ||
| 225 | + * | ||
| 226 | + * Evaluates the function value. No gradient computation is implemented as | ||
| 227 | + * radial models will be convolved with the instrument response and thus | ||
| 228 | + * require the numerical computation of the derivatives. | ||
| 229 | + * | ||
| 230 | + * See the eval() method for more information. | ||
| 231 | + ***************************************************************************/ | ||
| 232 | +double GModelSpatialRadialProfile::eval_gradients(const double& theta, | ||
| 233 | + const GEnergy& energy, | ||
| 234 | + const GTime& time) const | ||
| 235 | +{ | ||
| 236 | + // Return value | ||
| 237 | + return (eval(theta, energy, time)); | ||
| 238 | +} | ||
| 239 | + | ||
| 240 | + | ||
| 241 | +/***********************************************************************//** | ||
| 242 | + * @brief Return MC sky direction | ||
| 243 | + * | ||
| 244 | + * @param[in] energy Photon energy. | ||
| 245 | + * @param[in] time Photon arrival time. | ||
| 246 | + * @param[in,out] ran Random number generator. | ||
| 247 | + * @return Sky direction. | ||
| 248 | + * | ||
| 249 | + * Draws an arbitrary sky direction from the radial profile using a rejection | ||
| 250 | + * method. | ||
| 251 | + ***************************************************************************/ | ||
| 252 | +GSkyDir GModelSpatialRadialProfile::mc(const GEnergy& energy, | ||
| 253 | + const GTime& time, | ||
| 254 | + GRan& ran) const | ||
| 255 | +{ | ||
| 256 | + // Get pre-computation cache index | ||
| 257 | + int icache = cache_index(); | ||
| 258 | + | ||
| 259 | + // Simulate theta angle (degrees) using a rejection method | ||
| 260 | + double theta = 0.0; | ||
| 261 | + while (true) { | ||
| 262 | + theta = ran.uniform() * theta_max(); | ||
| 263 | + double mc = m_profile[icache].nodes.interpolate(theta, m_profile[icache].mc); | ||
| 264 | + if ((ran.uniform() * m_profile[icache].mc_max) <= mc) { | ||
| 265 | + break; | ||
| 266 | + } | ||
| 267 | + } | ||
| 268 | + theta *= gammalib::rad2deg; | ||
| 269 | + | ||
| 270 | + // Simulate uniform azmiuth angle (degrees) | ||
| 271 | + double phi = 360.0 * ran.uniform(); | ||
| 272 | + | ||
| 273 | + // Rotate sky direction by offset | ||
| 274 | + GSkyDir sky_dir = dir(); | ||
| 275 | + sky_dir.rotate_deg(phi, theta); | ||
| 276 | + | ||
| 277 | + // Return sky direction | ||
| 278 | + return sky_dir; | ||
| 279 | +} | ||
| 280 | + | ||
| 281 | + | ||
| 282 | +/***********************************************************************//** | ||
| 283 | + * @brief Checks where model contains specified sky direction | ||
| 284 | + * | ||
| 285 | + * @param[in] dir Sky direction. | ||
| 286 | + * @param[in] margin Margin to be added to sky direction (degrees) | ||
| 287 | + * @return True if the model contains the sky direction. | ||
| 288 | + * | ||
| 289 | + * Signals whether a sky direction is contained in the radial disk model. | ||
| 290 | + ***************************************************************************/ | ||
| 291 | +bool GModelSpatialRadialProfile::contains(const GSkyDir& dir, | ||
| 292 | + const double& margin) const | ||
| 293 | +{ | ||
| 294 | + // Compute distance to centre (radians) | ||
| 295 | + double distance = dir.dist(this->dir()); | ||
| 296 | + | ||
| 297 | + // Return flag | ||
| 298 | + return (distance <= theta_max() + margin*gammalib::deg2rad); | ||
| 299 | +} | ||
| 300 | + | ||
| 301 | + | ||
| 302 | +/*========================================================================== | ||
| 303 | + = = | ||
| 304 | + = Private methods = | ||
| 305 | + = = | ||
| 306 | + ==========================================================================*/ | ||
| 307 | + | ||
| 308 | +/***********************************************************************//** | ||
| 309 | + * @brief Initialise class members | ||
| 310 | + ***************************************************************************/ | ||
| 311 | +void GModelSpatialRadialProfile::init_members(void) | ||
| 312 | +{ | ||
| 313 | + // Initialise members | ||
| 314 | + m_num_nodes = 100; | ||
| 315 | + | ||
| 316 | + // Initialise pre-computation cache | ||
| 317 | + m_profile.clear(); | ||
| 318 | + | ||
| 319 | + // Return | ||
| 320 | + return; | ||
| 321 | +} | ||
| 322 | + | ||
| 323 | + | ||
| 324 | +/***********************************************************************//** | ||
| 325 | + * @brief Copy class members | ||
| 326 | + * | ||
| 327 | + * @param[in] model Radial disk model. | ||
| 328 | + ***************************************************************************/ | ||
| 329 | +void GModelSpatialRadialProfile::copy_members(const GModelSpatialRadialProfile& model) | ||
| 330 | +{ | ||
| 331 | + // Copy members | ||
| 332 | + m_num_nodes = model.m_num_nodes; | ||
| 333 | + m_profile = model.m_profile; | ||
| 334 | + | ||
| 335 | + // Return | ||
| 336 | + return; | ||
| 337 | +} | ||
| 338 | + | ||
| 339 | + | ||
| 340 | +/***********************************************************************//** | ||
| 341 | + * @brief Delete class members | ||
| 342 | + ***************************************************************************/ | ||
| 343 | +void GModelSpatialRadialProfile::free_members(void) | ||
| 344 | +{ | ||
| 345 | + // Return | ||
| 346 | + return; | ||
| 347 | +} | ||
| 348 | + | ||
| 349 | + | ||
| 350 | +/***********************************************************************//** | ||
| 351 | + * @brief Return index to pre-computation cache | ||
| 352 | + * | ||
| 353 | + * @return Index to pre-computation cache | ||
| 354 | + * | ||
| 355 | + * Returns the index to the pre-computation cache. If no pre-computation | ||
| 356 | + * cache was found the method will create one and return the index to that | ||
| 357 | + * cache. | ||
| 358 | + ***************************************************************************/ | ||
| 359 | +int GModelSpatialRadialProfile::cache_index(void) const | ||
| 360 | +{ | ||
| 361 | + // Initialise index | ||
| 362 | + int index = -1; | ||
| 363 | + | ||
| 364 | + // Search for index | ||
| 365 | + for (int i = 0; i < m_profile.size(); ++i) { | ||
| 366 | + | ||
| 367 | + // Initialise found flag | ||
| 368 | + bool found = true; | ||
| 369 | + | ||
| 370 | + // Loop over all spatial parameters and check if they are equal | ||
| 371 | + // to the parameters in the pre-computation cache. Break and set | ||
| 372 | + // the found flag to false on non-equality. | ||
| 373 | + for (int k = 0; k < m_pars.size(); ++k) { | ||
| 374 | + if (m_pars[k]->value() != m_profile[i].pars[k]) { | ||
| 375 | + found = false; | ||
| 376 | + break; | ||
| 377 | + } | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + // If profile was found then set index | ||
| 381 | + if (found) { | ||
| 382 | + index = i; | ||
| 383 | + break; | ||
| 384 | + } | ||
| 385 | + | ||
| 386 | + } // endfor: looped over index | ||
| 387 | + | ||
| 388 | + // If index was not found then allocate a new pre-computation cache | ||
| 389 | + if (index == -1) { | ||
| 390 | + | ||
| 391 | + // Initialise profile | ||
| 392 | + profile prf; | ||
| 393 | + prf.nodes.clear(); | ||
| 394 | + prf.values.clear(); | ||
| 395 | + prf.mc.clear(); | ||
| 396 | + prf.mc_max = 0.0; | ||
| 397 | + | ||
| 398 | + // Set profile parameters | ||
| 399 | + for (int k = 0; k < m_pars.size(); ++k) { | ||
| 400 | + prf.pars.push_back(m_pars[k]->value()); | ||
| 401 | + } | ||
| 402 | + | ||
| 403 | + // Pre-compute radial values, MC values, and mc_max. Compute | ||
| 404 | + // also the normalization. | ||
| 405 | + double rmax = theta_max(); | ||
| 406 | + double dr = rmax / m_num_nodes; | ||
| 407 | + double r = 0.0; | ||
| 408 | + double norm = 0.0; | ||
| 409 | + for (int j = 0; j < m_num_nodes; ++j) { | ||
| 410 | + double value = profile_value(r); | ||
| 411 | + double mc = value * std::sin(r) * dr; | ||
| 412 | + norm += mc; | ||
| 413 | + if (mc > prf.mc_max) { | ||
| 414 | + prf.mc_max = mc; | ||
| 415 | + } | ||
| 416 | + prf.nodes.append(r); | ||
| 417 | + prf.values.push_back(value); | ||
| 418 | + prf.mc.push_back(mc); | ||
| 419 | + r += dr; | ||
| 420 | + } | ||
| 421 | + norm *= gammalib::twopi; | ||
| 422 | + | ||
| 423 | + // Normalize radial profile | ||
| 424 | + if (norm > 0.0) { | ||
| 425 | + double inv_norm = 1.0 / norm; | ||
| 426 | + for (int j = 0; j < m_num_nodes; ++j) { | ||
| 427 | + prf.values[j] *= inv_norm; | ||
| 428 | + } | ||
| 429 | + } | ||
| 430 | + | ||
| 431 | + // Push profile in pre-computation cache | ||
| 432 | + m_profile.push_back(prf); | ||
| 433 | + | ||
| 434 | + // Get index to last profile | ||
| 435 | + index = m_profile.size() - 1; | ||
| 436 | + | ||
| 437 | + // Log pre-computation | ||
| 438 | + #if defined(G_DEBUG_PRECOMPUTATION) | ||
| 439 | + std::cout << "GModelSpatialRadialProfile::cache_index"; | ||
| 440 | + std::cout << std::endl; | ||
| 441 | + std::cout << " dr=" << dr << std::endl; | ||
| 442 | + for (int k = 0; k < m_pars.size(); ++k) { | ||
| 443 | + std::cout << " par[" << k << "]=" << m_pars[k]->value(); | ||
| 444 | + std::cout << " (" << m_pars[k]->name(); | ||
| 445 | + std::cout << ")" << std::endl; | ||
| 446 | + } | ||
| 447 | + std::cout << " norm=" << norm << std::endl; | ||
| 448 | + #endif | ||
| 449 | + | ||
| 450 | + } // endif: allocated new pre-computation cache | ||
| 451 | + | ||
| 452 | + // Return index | ||
| 453 | + return (index); | ||
| 454 | +} |
src/model/GModelSpatialRadialProfileGauss.cpp
0 → 100644
| 1 | +/*************************************************************************** | ||
| 2 | + * GModelSpatialRadialProfileGauss.cpp - Gaussian radial profile class * | ||
| 3 | + * ----------------------------------------------------------------------- * | ||
| 4 | + * copyright (C) 2016 by Juergen Knoedlseder * | ||
| 5 | + * ----------------------------------------------------------------------- * | ||
| 6 | + * * | ||
| 7 | + * This program is free software: you can redistribute it and/or modify * | ||
| 8 | + * it under the terms of the GNU General Public License as published by * | ||
| 9 | + * the Free Software Foundation, either version 3 of the License, or * | ||
| 10 | + * (at your option) any later version. * | ||
| 11 | + * * | ||
| 12 | + * This program is distributed in the hope that it will be useful, * | ||
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
| 15 | + * GNU General Public License for more details. * | ||
| 16 | + * * | ||
| 17 | + * You should have received a copy of the GNU General Public License * | ||
| 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
| 19 | + * * | ||
| 20 | + ***************************************************************************/ | ||
| 21 | +/** | ||
| 22 | + * @file GModelSpatialRadialProfileGauss.cpp | ||
| 23 | + * @brief Radial Gaussian profile model class implementation | ||
| 24 | + * @author Juergen Knoedlseder | ||
| 25 | + */ | ||
| 26 | + | ||
| 27 | +/* __ Includes ___________________________________________________________ */ | ||
| 28 | +#ifdef HAVE_CONFIG_H | ||
| 29 | +#include <config.h> | ||
| 30 | +#endif | ||
| 31 | +#include "GException.hpp" | ||
| 32 | +#include "GTools.hpp" | ||
| 33 | +#include "GMath.hpp" | ||
| 34 | +#include "GXmlElement.hpp" | ||
| 35 | +#include "GModelSpatialRadialProfileGauss.hpp" | ||
| 36 | +#include "GModelSpatialRegistry.hpp" | ||
| 37 | + | ||
| 38 | +/* __ Constants __________________________________________________________ */ | ||
| 39 | + | ||
| 40 | +/* __ Globals ____________________________________________________________ */ | ||
| 41 | +const GModelSpatialRadialProfileGauss g_radial_disk_seed; | ||
| 42 | +const GModelSpatialRegistry g_radial_disk_registry(&g_radial_disk_seed); | ||
| 43 | + | ||
| 44 | +/* __ Method name definitions ____________________________________________ */ | ||
| 45 | +#define G_READ "GModelSpatialRadialProfileGauss::read(GXmlElement&)" | ||
| 46 | +#define G_WRITE "GModelSpatialRadialProfileGauss::write(GXmlElement&)" | ||
| 47 | + | ||
| 48 | +/* __ Macros _____________________________________________________________ */ | ||
| 49 | + | ||
| 50 | +/* __ Coding definitions _________________________________________________ */ | ||
| 51 | + | ||
| 52 | +/* __ Debug definitions __________________________________________________ */ | ||
| 53 | + | ||
| 54 | + | ||
| 55 | +/*========================================================================== | ||
| 56 | + = = | ||
| 57 | + = Constructors/destructors = | ||
| 58 | + = = | ||
| 59 | + ==========================================================================*/ | ||
| 60 | + | ||
| 61 | +/***********************************************************************//** | ||
| 62 | + * @brief Void constructor | ||
| 63 | + * | ||
| 64 | + * Constructs empty radial Gaussian profile | ||
| 65 | + ***************************************************************************/ | ||
| 66 | +GModelSpatialRadialProfileGauss::GModelSpatialRadialProfileGauss(void) : | ||
| 67 | + GModelSpatialRadialProfile() | ||
| 68 | +{ | ||
| 69 | + // Initialise members | ||
| 70 | + init_members(); | ||
| 71 | + | ||
| 72 | + // Return | ||
| 73 | + return; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | + | ||
| 77 | +/***********************************************************************//** | ||
| 78 | + * @brief XML constructor | ||
| 79 | + * | ||
| 80 | + * @param[in] xml XML element. | ||
| 81 | + * | ||
| 82 | + * Constructs radial Gaussian profile model by extracting information from | ||
| 83 | + * an XML element. See the read() method for more information about the | ||
| 84 | + * expected structure of the XML element. | ||
| 85 | + ***************************************************************************/ | ||
| 86 | +GModelSpatialRadialProfileGauss::GModelSpatialRadialProfileGauss(const GXmlElement& xml) : | ||
| 87 | + GModelSpatialRadialProfile() | ||
| 88 | +{ | ||
| 89 | + // Initialise members | ||
| 90 | + init_members(); | ||
| 91 | + | ||
| 92 | + // Read information from XML element | ||
| 93 | + read(xml); | ||
| 94 | + | ||
| 95 | + // Return | ||
| 96 | + return; | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | + | ||
| 100 | +/***********************************************************************//** | ||
| 101 | + * @brief Copy constructor | ||
| 102 | + * | ||
| 103 | + * @param[in] model Radial Gaussian profile model. | ||
| 104 | + * | ||
| 105 | + * Copies radial Gaussian profile model from another radial profile model. | ||
| 106 | + ***************************************************************************/ | ||
| 107 | +GModelSpatialRadialProfileGauss::GModelSpatialRadialProfileGauss(const GModelSpatialRadialProfileGauss& model) : | ||
| 108 | + GModelSpatialRadialProfile(model) | ||
| 109 | +{ | ||
| 110 | + // Initialise members | ||
| 111 | + init_members(); | ||
| 112 | + | ||
| 113 | + // Copy members | ||
| 114 | + copy_members(model); | ||
| 115 | + | ||
| 116 | + // Return | ||
| 117 | + return; | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | + | ||
| 121 | +/***********************************************************************//** | ||
| 122 | + * @brief Destructor | ||
| 123 | + * | ||
| 124 | + * Destructs radial Gaussian profile model. | ||
| 125 | + ***************************************************************************/ | ||
| 126 | +GModelSpatialRadialProfileGauss::~GModelSpatialRadialProfileGauss(void) | ||
| 127 | +{ | ||
| 128 | + // Free members | ||
| 129 | + free_members(); | ||
| 130 | + | ||
| 131 | + // Return | ||
| 132 | + return; | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | + | ||
| 136 | +/*========================================================================== | ||
| 137 | + = = | ||
| 138 | + = Operators = | ||
| 139 | + = = | ||
| 140 | + ==========================================================================*/ | ||
| 141 | + | ||
| 142 | +/***********************************************************************//** | ||
| 143 | + * @brief Assignment operator | ||
| 144 | + * | ||
| 145 | + * @param[in] model Radial Gaussian profile model. | ||
| 146 | + * @return Radial Gaussian profile model. | ||
| 147 | + * | ||
| 148 | + * Assigns radial Gaussian profile model. | ||
| 149 | + ***************************************************************************/ | ||
| 150 | +GModelSpatialRadialProfileGauss& GModelSpatialRadialProfileGauss::operator=(const GModelSpatialRadialProfileGauss& model) | ||
| 151 | +{ | ||
| 152 | + // Execute only if object is not identical | ||
| 153 | + if (this != &model) { | ||
| 154 | + | ||
| 155 | + // Copy base class members | ||
| 156 | + this->GModelSpatialRadialProfile::operator=(model); | ||
| 157 | + | ||
| 158 | + // Free members | ||
| 159 | + free_members(); | ||
| 160 | + | ||
| 161 | + // Initialise members | ||
| 162 | + init_members(); | ||
| 163 | + | ||
| 164 | + // Copy members | ||
| 165 | + copy_members(model); | ||
| 166 | + | ||
| 167 | + } // endif: object was not identical | ||
| 168 | + | ||
| 169 | + // Return | ||
| 170 | + return *this; | ||
| 171 | +} | ||
| 172 | + | ||
| 173 | + | ||
| 174 | +/*========================================================================== | ||
| 175 | + = = | ||
| 176 | + = Public methods = | ||
| 177 | + = = | ||
| 178 | + ==========================================================================*/ | ||
| 179 | + | ||
| 180 | +/***********************************************************************//** | ||
| 181 | + * @brief Clear radial Gaussian profile model | ||
| 182 | + * | ||
| 183 | + * Clears radial Gaussian profile model. | ||
| 184 | + ***************************************************************************/ | ||
| 185 | +void GModelSpatialRadialProfileGauss::clear(void) | ||
| 186 | +{ | ||
| 187 | + // Free class members | ||
| 188 | + free_members(); | ||
| 189 | + this->GModelSpatialRadialProfile::free_members(); | ||
| 190 | + this->GModelSpatialRadial::free_members(); | ||
| 191 | + this->GModelSpatial::free_members(); | ||
| 192 | + | ||
| 193 | + // Initialise members | ||
| 194 | + this->GModelSpatial::init_members(); | ||
| 195 | + this->GModelSpatialRadial::init_members(); | ||
| 196 | + this->GModelSpatialRadialProfile::init_members(); | ||
| 197 | + init_members(); | ||
| 198 | + | ||
| 199 | + // Return | ||
| 200 | + return; | ||
| 201 | +} | ||
| 202 | + | ||
| 203 | + | ||
| 204 | +/***********************************************************************//** | ||
| 205 | + * @brief Clone radial Gaussian profile model | ||
| 206 | + * | ||
| 207 | + * @return Pointer to deep copy of radial Gaussian profile model. | ||
| 208 | + * | ||
| 209 | + * Returns a deep copy of the radial Gaussian profile model. | ||
| 210 | + ***************************************************************************/ | ||
| 211 | +GModelSpatialRadialProfileGauss* GModelSpatialRadialProfileGauss::clone(void) const | ||
| 212 | +{ | ||
| 213 | + // Clone radial disk model | ||
| 214 | + return new GModelSpatialRadialProfileGauss(*this); | ||
| 215 | +} | ||
| 216 | + | ||
| 217 | + | ||
| 218 | +/***********************************************************************//** | ||
| 219 | + * @brief Return maximum model radius (in radians) | ||
| 220 | + * | ||
| 221 | + * @return Maximum model radius (in radians). | ||
| 222 | + ***************************************************************************/ | ||
| 223 | +double GModelSpatialRadialProfileGauss::theta_max(void) const | ||
| 224 | +{ | ||
| 225 | + // Return value | ||
| 226 | + return (m_sigma.value() * gammalib::deg2rad * 5.0); | ||
| 227 | +} | ||
| 228 | + | ||
| 229 | + | ||
| 230 | +/***********************************************************************//** | ||
| 231 | + * @brief Read model from XML element | ||
| 232 | + * | ||
| 233 | + * @param[in] xml XML element. | ||
| 234 | + * | ||
| 235 | + * Reads the Gaussian radial profile model information from an XML element. | ||
| 236 | + * The XML element shall have either the format | ||
| 237 | + * | ||
| 238 | + * <spatialModel type="GaussianProfile"> | ||
| 239 | + * <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/> | ||
| 240 | + * <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/> | ||
| 241 | + * <parameter name="Sigma" scale="1.0" value="0.45" min="0.01" max="10" free="1"/> | ||
| 242 | + * </spatialModel> | ||
| 243 | + * | ||
| 244 | + * or | ||
| 245 | + * | ||
| 246 | + * <spatialModel type="GaussianProfile"> | ||
| 247 | + * <parameter name="GLON" scale="1.0" value="83.6331" min="-360" max="360" free="1"/> | ||
| 248 | + * <parameter name="GLAT" scale="1.0" value="22.0145" min="-90" max="90" free="1"/> | ||
| 249 | + * <parameter name="Sigma" scale="1.0" value="0.45" min="0.01" max="10" free="1"/> | ||
| 250 | + * </spatialModel> | ||
| 251 | + ***************************************************************************/ | ||
| 252 | +void GModelSpatialRadialProfileGauss::read(const GXmlElement& xml) | ||
| 253 | +{ | ||
| 254 | + // Read Gaussian location | ||
| 255 | + GModelSpatialRadial::read(xml); | ||
| 256 | + | ||
| 257 | + // Read Sigma parameter | ||
| 258 | + const GXmlElement* par = gammalib::xml_get_par(G_READ, xml, "Sigma"); | ||
| 259 | + m_sigma.read(*par); | ||
| 260 | + | ||
| 261 | + // Return | ||
| 262 | + return; | ||
| 263 | +} | ||
| 264 | + | ||
| 265 | + | ||
| 266 | +/***********************************************************************//** | ||
| 267 | + * @brief Write model into XML element | ||
| 268 | + * | ||
| 269 | + * @param[in] xml XML element into which model information is written. | ||
| 270 | + * | ||
| 271 | + * Writes the Gaussian radial profile model information into an XML element. | ||
| 272 | + * The XML element will have the format | ||
| 273 | + * | ||
| 274 | + * <spatialModel type="GaussianProfile"> | ||
| 275 | + * <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/> | ||
| 276 | + * <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/> | ||
| 277 | + * <parameter name="Sigma" scale="1.0" value="0.45" min="0.01" max="10" free="1"/> | ||
| 278 | + * </spatialModel> | ||
| 279 | + ***************************************************************************/ | ||
| 280 | +void GModelSpatialRadialProfileGauss::write(GXmlElement& xml) const | ||
| 281 | +{ | ||
| 282 | + // Write Gaussian location | ||
| 283 | + GModelSpatialRadial::write(xml); | ||
| 284 | + | ||
| 285 | + // Write Sigma parameter | ||
| 286 | + GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, "Sigma"); | ||
| 287 | + m_sigma.write(*par); | ||
| 288 | + | ||
| 289 | + // Return | ||
| 290 | + return; | ||
| 291 | +} | ||
| 292 | + | ||
| 293 | + | ||
| 294 | +/***********************************************************************//** | ||
| 295 | + * @brief Print information | ||
| 296 | + * | ||
| 297 | + * @param[in] chatter Chattiness (defaults to NORMAL). | ||
| 298 | + * @return String containing model information. | ||
| 299 | + ***************************************************************************/ | ||
| 300 | +std::string GModelSpatialRadialProfileGauss::print(const GChatter& chatter) const | ||
| 301 | +{ | ||
| 302 | + // Initialise result string | ||
| 303 | + std::string result; | ||
| 304 | + | ||
| 305 | + // Continue only if chatter is not silent | ||
| 306 | + if (chatter != SILENT) { | ||
| 307 | + | ||
| 308 | + // Append header | ||
| 309 | + result.append("=== GModelSpatialRadialProfileGauss ==="); | ||
| 310 | + | ||
| 311 | + // Append parameters | ||
| 312 | + result.append("\n"+gammalib::parformat("Number of parameters")); | ||
| 313 | + result.append(gammalib::str(size())); | ||
| 314 | + for (int i = 0; i < size(); ++i) { | ||
| 315 | + result.append("\n"+m_pars[i]->print(chatter)); | ||
| 316 | + } | ||
| 317 | + | ||
| 318 | + } // endif: chatter was not silent | ||
| 319 | + | ||
| 320 | + // Return result | ||
| 321 | + return result; | ||
| 322 | +} | ||
| 323 | + | ||
| 324 | + | ||
| 325 | +/*========================================================================== | ||
| 326 | + = = | ||
| 327 | + = Private methods = | ||
| 328 | + = = | ||
| 329 | + ==========================================================================*/ | ||
| 330 | + | ||
| 331 | +/***********************************************************************//** | ||
| 332 | + * @brief Initialise class members | ||
| 333 | + ***************************************************************************/ | ||
| 334 | +void GModelSpatialRadialProfileGauss::init_members(void) | ||
| 335 | +{ | ||
| 336 | + // Initialise Gaussian sigma | ||
| 337 | + m_sigma.clear(); | ||
| 338 | + m_sigma.name("Sigma"); | ||
| 339 | + m_sigma.unit("deg"); | ||
| 340 | + m_sigma.value(2.778e-4); // 1 arcsec | ||
| 341 | + m_sigma.min(2.778e-4); // 1 arcsec | ||
| 342 | + m_sigma.free(); | ||
| 343 | + m_sigma.scale(1.0); | ||
| 344 | + m_sigma.gradient(0.0); | ||
| 345 | + m_sigma.has_grad(false); // Radial components never have gradients | ||
| 346 | + | ||
| 347 | + // Set parameter pointer(s) | ||
| 348 | + m_pars.push_back(&m_sigma); | ||
| 349 | + | ||
| 350 | + // Return | ||
| 351 | + return; | ||
| 352 | +} | ||
| 353 | + | ||
| 354 | + | ||
| 355 | +/***********************************************************************//** | ||
| 356 | + * @brief Copy class members | ||
| 357 | + * | ||
| 358 | + * @param[in] model Radial Gaussian model. | ||
| 359 | + * | ||
| 360 | + * Copies class members from another radial profile model. | ||
| 361 | + ***************************************************************************/ | ||
| 362 | +void GModelSpatialRadialProfileGauss::copy_members(const GModelSpatialRadialProfileGauss& model) | ||
| 363 | +{ | ||
| 364 | + // Copy members. We do not have to push back the members on the parameter | ||
| 365 | + // stack as this should have been done by init_members() that was called | ||
| 366 | + // before. Otherwise we would have sigma twice on the stack. | ||
| 367 | + m_sigma = model.m_sigma; | ||
| 368 | + | ||
| 369 | + // Return | ||
| 370 | + return; | ||
| 371 | +} | ||
| 372 | + | ||
| 373 | + | ||
| 374 | +/***********************************************************************//** | ||
| 375 | + * @brief Delete class members | ||
| 376 | + ***************************************************************************/ | ||
| 377 | +void GModelSpatialRadialProfileGauss::free_members(void) | ||
| 378 | +{ | ||
| 379 | + // Return | ||
| 380 | + return; | ||
| 381 | +} | ||
| 382 | + | ||
| 383 | + | ||
| 384 | +/***********************************************************************//** | ||
| 385 | + * @brief Radial profile | ||
| 386 | + * | ||
| 387 | + * @param[in] theta Angular distance from Gaussian centre (radians). | ||
| 388 | + * @return Profile value. | ||
| 389 | + ***************************************************************************/ | ||
| 390 | +double GModelSpatialRadialProfileGauss::profile_value(const double& theta) const | ||
| 391 | +{ | ||
| 392 | + // Compute value | ||
| 393 | + double sigma_rad = m_sigma.value() * gammalib::deg2rad; | ||
| 394 | + double sigma2 = sigma_rad * sigma_rad; | ||
| 395 | + double theta2 = theta * theta; | ||
| 396 | + double value = std::exp(-0.5 * theta2 / sigma2) / | ||
| 397 | + (gammalib::twopi * sigma2); | ||
| 398 | + | ||
| 399 | + // Return value | ||
| 400 | + return value; | ||
| 401 | +} |
src/model/Makefile.am
| @@ -19,6 +19,8 @@ sources = GModelPar.cpp \ | @@ -19,6 +19,8 @@ sources = GModelPar.cpp \ | ||
| 19 | GModelSpatialRadialDisk.cpp \ | 19 | GModelSpatialRadialDisk.cpp \ |
| 20 | GModelSpatialRadialGauss.cpp \ | 20 | GModelSpatialRadialGauss.cpp \ |
| 21 | GModelSpatialRadialShell.cpp \ | 21 | GModelSpatialRadialShell.cpp \ |
| 22 | + GModelSpatialRadialProfile.cpp \ | ||
| 23 | + GModelSpatialRadialProfileGauss.cpp \ | ||
| 22 | GModelSpatialElliptical.cpp \ | 24 | GModelSpatialElliptical.cpp \ |
| 23 | GModelSpatialEllipticalDisk.cpp \ | 25 | GModelSpatialEllipticalDisk.cpp \ |
| 24 | GModelSpatialEllipticalGauss.cpp \ | 26 | GModelSpatialEllipticalGauss.cpp \ |