Commit 10f11c99e165ee48cd3438a04770bddc2ed08aac
Merge branch '1706-composite-models' into integration
# Conflicts: # AUTHORS # include/GTools.hpp # src/support/GTools.cpp
Showing
26 changed files
with
2259 additions
and
11 deletions
AUTHORS
| ... | ... | @@ -16,4 +16,5 @@ Michael Mayer (michael.mayer@physik.hu-berlin.de) |
| 16 | 16 | Ellis Owen (Ellis.Owen@mpi-hd.mpg.de) |
| 17 | 17 | Anneli Schulz (anneli.schulz@desy.de) |
| 18 | 18 | Hubert Siejkowski (h.siejkowski@cyfronet.pl) |
| 19 | +Domenico Tiziani (domenico.tiziani@fau.de) | |
| 19 | 20 | Alexander Ziegler (alexander.ziegler@fau.de) | ... | ... |
include/GModelSpatialComposite.hpp
0 → 100644
| 1 | +/*************************************************************************** | |
| 2 | + * GModelSpatialPointSource.hpp - Spatial point source model class * | |
| 3 | + * ----------------------------------------------------------------------- * | |
| 4 | + * copyright (C) 2016 by Domenico Tiziani * | |
| 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 GModelSpatialComposite.hpp | |
| 23 | + * @brief Spatial composite model class interface definition | |
| 24 | + * @author Domenico Tiziani | |
| 25 | + */ | |
| 26 | + | |
| 27 | +#ifndef GMODELSPATIALCOMPOSITE_HPP | |
| 28 | +#define GMODELSPATIALCOMPOSITE_HPP | |
| 29 | + | |
| 30 | +/* __ Includes ___________________________________________________________ */ | |
| 31 | +#include <string> | |
| 32 | +#include "GModelSpatial.hpp" | |
| 33 | +#include "GModelPar.hpp" | |
| 34 | +#include "GSkyDir.hpp" | |
| 35 | +#include "GXmlElement.hpp" | |
| 36 | + | |
| 37 | + | |
| 38 | +/***********************************************************************//** | |
| 39 | + * @class GModelSpatialComposite | |
| 40 | + * | |
| 41 | + * @brief Spatial composite model | |
| 42 | + * | |
| 43 | + * This class implements the spatial model for a composition of spatial | |
| 44 | + * models. | |
| 45 | + ***************************************************************************/ | |
| 46 | +class GModelSpatialComposite : public GModelSpatial { | |
| 47 | + | |
| 48 | +public: | |
| 49 | + // Constructors and destructors | |
| 50 | + GModelSpatialComposite(void); | |
| 51 | + GModelSpatialComposite(const bool& dummy, const std::string& type); | |
| 52 | + explicit GModelSpatialComposite(const GXmlElement& xml); | |
| 53 | + GModelSpatialComposite(const GModelSpatialComposite& model); | |
| 54 | + virtual ~GModelSpatialComposite(void); | |
| 55 | + | |
| 56 | + // Operators | |
| 57 | + virtual GModelSpatialComposite& operator=(const GModelSpatialComposite& model); | |
| 58 | + | |
| 59 | + // Implemented pure virtual methods | |
| 60 | + virtual void clear(void); | |
| 61 | + virtual GModelSpatialComposite* clone(void) const; | |
| 62 | + virtual std::string classname(void) const; | |
| 63 | + virtual std::string type(void) const; | |
| 64 | + virtual GClassCode code(void) const; | |
| 65 | + virtual double eval(const GPhoton& photon, | |
| 66 | + const bool& gradients = false) const; | |
| 67 | + virtual GSkyDir mc(const GEnergy& energy, | |
| 68 | + const GTime& time, | |
| 69 | + GRan& ran) const; | |
| 70 | + virtual double mc_norm(const GSkyDir& dir, | |
| 71 | + const double& radius) const; | |
| 72 | + virtual bool contains(const GSkyDir& dir, | |
| 73 | + const double& margin = 0.0) const; | |
| 74 | + virtual void read(const GXmlElement& xml); | |
| 75 | + virtual void write(GXmlElement& xml) const; | |
| 76 | + virtual std::string print(const GChatter& chatter = NORMAL) const; | |
| 77 | + | |
| 78 | + // Other methods | |
| 79 | + int components(void) const; | |
| 80 | + void append(const GModelSpatial& component, | |
| 81 | + const std::string& name = ""); | |
| 82 | + const GModelSpatial* component(const int& index) const; | |
| 83 | + const GModelSpatial* component(const std::string& name) const; | |
| 84 | + | |
| 85 | + | |
| 86 | +protected: | |
| 87 | + // Protected methods | |
| 88 | + void init_members(void); | |
| 89 | + void copy_members(const GModelSpatialComposite& model); | |
| 90 | + void free_members(void); | |
| 91 | + | |
| 92 | + // Protected members | |
| 93 | + std::string m_type; //!< Model type | |
| 94 | + std::vector<GModelSpatial*> m_components; //!< Components | |
| 95 | + std::vector<std::string> m_component_names; //!< Component names | |
| 96 | +}; | |
| 97 | + | |
| 98 | + | |
| 99 | +/***********************************************************************//** | |
| 100 | + * @brief Return class name | |
| 101 | + * | |
| 102 | + * @return String containing the class name ("GModelSpatialComposite"). | |
| 103 | + ***************************************************************************/ | |
| 104 | +inline | |
| 105 | +std::string GModelSpatialComposite::classname(void) const | |
| 106 | +{ | |
| 107 | + return ("GModelSpatialComposite"); | |
| 108 | +} | |
| 109 | + | |
| 110 | + | |
| 111 | +/***********************************************************************//** | |
| 112 | + * @brief Return model type | |
| 113 | + * | |
| 114 | + * @return Model type. | |
| 115 | + * | |
| 116 | + * Returns the type of the spatial model. | |
| 117 | + ***************************************************************************/ | |
| 118 | +inline | |
| 119 | +std::string GModelSpatialComposite::type(void) const | |
| 120 | +{ | |
| 121 | + return (m_type); | |
| 122 | +} | |
| 123 | + | |
| 124 | + | |
| 125 | +/***********************************************************************//** | |
| 126 | + * @brief Return class code | |
| 127 | + * | |
| 128 | + * @return GModelSpatialComposite. | |
| 129 | + * | |
| 130 | + * Returns the code GModelSpatialComposite of the class. | |
| 131 | + ***************************************************************************/ | |
| 132 | +inline | |
| 133 | +GClassCode GModelSpatialComposite::code(void) const | |
| 134 | +{ | |
| 135 | + return GMODEL_SPATIAL_COMPOSITE; | |
| 136 | +} | |
| 137 | + | |
| 138 | + | |
| 139 | +/***********************************************************************//** | |
| 140 | + * @brief Return normalization of composite source for Monte Carlo | |
| 141 | + * simulations | |
| 142 | + * | |
| 143 | + * @param[in] dir Centre of simulation cone. | |
| 144 | + * @param[in] radius Radius of simulation cone (degrees). | |
| 145 | + * @return Normalization. | |
| 146 | + * | |
| 147 | + * Returns unity. | |
| 148 | + ***************************************************************************/ | |
| 149 | +inline | |
| 150 | +double GModelSpatialComposite::mc_norm(const GSkyDir& dir, | |
| 151 | + const double& radius) const | |
| 152 | +{ | |
| 153 | + return 1.0; | |
| 154 | +} | |
| 155 | + | |
| 156 | + | |
| 157 | +/***********************************************************************//** | |
| 158 | + * @brief Return number of model components | |
| 159 | + * | |
| 160 | + * @return Number of model components. | |
| 161 | + ***************************************************************************/ | |
| 162 | +inline | |
| 163 | +int GModelSpatialComposite::components(void) const | |
| 164 | +{ | |
| 165 | + return m_components.size(); | |
| 166 | +} | |
| 167 | + | |
| 168 | +#endif /* GMODELSPATIALCOMPOSITE_HPP */ | ... | ... |
include/GModelSpectralComposite.hpp
0 → 100644
| 1 | +/*************************************************************************** | |
| 2 | + * GModelSpectralComposite.hpp - Spectral power law model class * | |
| 3 | + * ----------------------------------------------------------------------- * | |
| 4 | + * copyright (C) 2016 by Michael Mayer * | |
| 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 GModelSpectralComposite.hpp | |
| 23 | + * @brief Composite spectral model class interface definition | |
| 24 | + * @author Michael Mayer | |
| 25 | + */ | |
| 26 | + | |
| 27 | +#ifndef GMODELSPECTRALCOMPOSITE_HPP | |
| 28 | +#define GMODELSPECTRALCOMPOSITE_HPP | |
| 29 | + | |
| 30 | +/* __ Includes ___________________________________________________________ */ | |
| 31 | +#include <string> | |
| 32 | +#include "GModelSpectral.hpp" | |
| 33 | +#include "GModelPar.hpp" | |
| 34 | +#include "GEnergy.hpp" | |
| 35 | + | |
| 36 | +/* __ Forward declarations _______________________________________________ */ | |
| 37 | +class GRan; | |
| 38 | +class GTime; | |
| 39 | +class GXmlElement; | |
| 40 | + | |
| 41 | + | |
| 42 | +/***********************************************************************//** | |
| 43 | + * @class GModelSpectralComposite | |
| 44 | + * | |
| 45 | + * @brief Composite spectral model class | |
| 46 | + * | |
| 47 | + * This class implements a composite spectrum. The model is defined by the sum | |
| 48 | + * of several individual spectral models. Each spectral model can be added via | |
| 49 | + * the XML interface or using the append() method. | |
| 50 | + * | |
| 51 | + ***************************************************************************/ | |
| 52 | +class GModelSpectralComposite : public GModelSpectral { | |
| 53 | + | |
| 54 | +public: | |
| 55 | + // Constructors and destructors | |
| 56 | + GModelSpectralComposite(void); | |
| 57 | + explicit GModelSpectralComposite(const GXmlElement& xml); | |
| 58 | + GModelSpectralComposite(const GModelSpectralComposite& model); | |
| 59 | + virtual ~GModelSpectralComposite(void); | |
| 60 | + | |
| 61 | + // Operators | |
| 62 | + virtual GModelSpectralComposite& operator=(const GModelSpectralComposite& model); | |
| 63 | + | |
| 64 | + // Implemented pure virtual methods | |
| 65 | + virtual void clear(void); | |
| 66 | + virtual GModelSpectralComposite* clone(void) const; | |
| 67 | + virtual std::string classname(void) const; | |
| 68 | + virtual std::string type(void) const; | |
| 69 | + virtual double eval(const GEnergy& srcEng, | |
| 70 | + const GTime& srcTime = GTime(), | |
| 71 | + const bool& gradients = false) const; | |
| 72 | + virtual double flux(const GEnergy& emin, | |
| 73 | + const GEnergy& emax) const; | |
| 74 | + virtual double eflux(const GEnergy& emin, | |
| 75 | + const GEnergy& emax) const; | |
| 76 | + virtual GEnergy mc(const GEnergy& emin, | |
| 77 | + const GEnergy& emax, | |
| 78 | + const GTime& time, | |
| 79 | + GRan& ran) const; | |
| 80 | + virtual void read(const GXmlElement& xml); | |
| 81 | + virtual void write(GXmlElement& xml) const; | |
| 82 | + virtual std::string print(const GChatter& chatter = NORMAL) const; | |
| 83 | + | |
| 84 | + // Other methods | |
| 85 | + void append(const GModelSpectral& spec, const std::string& name=""); | |
| 86 | + int components(void) const; | |
| 87 | + const GModelSpectral* component(const int& index) const; | |
| 88 | + const GModelSpectral* component(const std::string& name) const; | |
| 89 | + | |
| 90 | +protected: | |
| 91 | + // Protected methods | |
| 92 | + void init_members(void); | |
| 93 | + void copy_members(const GModelSpectralComposite& model); | |
| 94 | + void free_members(void); | |
| 95 | + void update_mc_cache(const GEnergy& emin, const GEnergy& emax) const; | |
| 96 | + | |
| 97 | + // Protected members | |
| 98 | + std::string m_type; //!< Model type | |
| 99 | + std::vector<GModelSpectral*> m_spectral; //!< Container of spectral models | |
| 100 | + std::vector<std::string> m_components; //!< Names of components | |
| 101 | + | |
| 102 | + // MC cache | |
| 103 | + mutable double m_mc_flux; //!< Flux cache | |
| 104 | + mutable std::vector<double> m_mc_probs; //!< Probailities of individual components | |
| 105 | + mutable GEnergy m_mc_emin; //!< Last minimum energy | |
| 106 | + mutable GEnergy m_mc_emax; //!< Last maximum energy | |
| 107 | + | |
| 108 | +}; | |
| 109 | + | |
| 110 | + | |
| 111 | +/***********************************************************************//** | |
| 112 | + * @brief Return class name | |
| 113 | + * | |
| 114 | + * @return String containing the class name ("GModelSpectralComposite"). | |
| 115 | + ***************************************************************************/ | |
| 116 | +inline | |
| 117 | +std::string GModelSpectralComposite::classname(void) const | |
| 118 | +{ | |
| 119 | + return ("GModelSpectralComposite"); | |
| 120 | +} | |
| 121 | + | |
| 122 | + | |
| 123 | +/***********************************************************************//** | |
| 124 | + * @brief Return model type | |
| 125 | + * | |
| 126 | + * @return Model type. | |
| 127 | + * | |
| 128 | + * Returns the type of the spectral composite model. | |
| 129 | + ***************************************************************************/ | |
| 130 | +inline | |
| 131 | +std::string GModelSpectralComposite::type(void) const | |
| 132 | +{ | |
| 133 | + return (m_type); | |
| 134 | +} | |
| 135 | + | |
| 136 | + | |
| 137 | +/***********************************************************************//** | |
| 138 | + * @brief Return number of spectral components | |
| 139 | + * | |
| 140 | + * @return Number of model components. | |
| 141 | + * | |
| 142 | + * Returns the number of spectral components. | |
| 143 | + ***************************************************************************/ | |
| 144 | +inline | |
| 145 | +int GModelSpectralComposite::components(void) const | |
| 146 | +{ | |
| 147 | + return (m_spectral.size()); | |
| 148 | +} | |
| 149 | + | |
| 150 | + | |
| 151 | +#endif /* GMODELSPECTRALCOMPOSITE_HPP */ | ... | ... |
include/GTools.hpp
| ... | ... | @@ -109,7 +109,7 @@ namespace gammalib { |
| 109 | 109 | bool is_notanumber(const double& x); |
| 110 | 110 | bool contains(const std::string& str, |
| 111 | 111 | const std::string& substring); |
| 112 | - bool contains(const std::vector<std::string>& strings, | |
| 112 | + bool contains(const std::vector<std::string> strings, | |
| 113 | 113 | const std::string& string); |
| 114 | 114 | void warning(const std::string& origin, |
| 115 | 115 | const std::string& message); | ... | ... |
include/GTypemaps.hpp
| ... | ... | @@ -43,7 +43,8 @@ typedef enum { |
| 43 | 43 | GMODEL_SPATIAL_POINT_SOURCE, |
| 44 | 44 | GMODEL_SPATIAL_RADIAL, |
| 45 | 45 | GMODEL_SPATIAL_ELLIPTICAL, |
| 46 | - GMODEL_SPATIAL_DIFFUSE | |
| 46 | + GMODEL_SPATIAL_DIFFUSE, | |
| 47 | + GMODEL_SPATIAL_COMPOSITE | |
| 47 | 48 | } GClassCode; |
| 48 | 49 | |
| 49 | 50 | /* __ Typemaps ___________________________________________________________ */ | ... | ... |
include/GammaLib.hpp
| ... | ... | @@ -208,6 +208,7 @@ |
| 208 | 208 | #include "GModelSpatialDiffuseConst.hpp" |
| 209 | 209 | #include "GModelSpatialDiffuseCube.hpp" |
| 210 | 210 | #include "GModelSpatialDiffuseMap.hpp" |
| 211 | +#include "GModelSpatialComposite.hpp" | |
| 211 | 212 | #include "GModelSpectral.hpp" |
| 212 | 213 | #include "GModelSpectralRegistry.hpp" |
| 213 | 214 | #include "GModelSpectralBrokenPlaw.hpp" |
| ... | ... | @@ -223,6 +224,7 @@ |
| 223 | 224 | #include "GModelSpectralPlaw.hpp" |
| 224 | 225 | #include "GModelSpectralPlawPhotonFlux.hpp" |
| 225 | 226 | #include "GModelSpectralPlawEnergyFlux.hpp" |
| 227 | +#include "GModelSpectralComposite.hpp" | |
| 226 | 228 | #include "GModelTemporal.hpp" |
| 227 | 229 | #include "GModelTemporalRegistry.hpp" |
| 228 | 230 | #include "GModelTemporalConst.hpp" | ... | ... |
include/Makefile.am
| ... | ... | @@ -166,6 +166,7 @@ pkginclude_HEADERS = GammaLib.hpp \ |
| 166 | 166 | GModelSpatialDiffuseConst.hpp \ |
| 167 | 167 | GModelSpatialDiffuseCube.hpp \ |
| 168 | 168 | GModelSpatialDiffuseMap.hpp \ |
| 169 | + GModelSpatialComposite.hpp \ | |
| 169 | 170 | GModelSpectral.hpp \ |
| 170 | 171 | GModelSpectralRegistry.hpp \ |
| 171 | 172 | GModelSpectralBrokenPlaw.hpp \ |
| ... | ... | @@ -181,6 +182,7 @@ pkginclude_HEADERS = GammaLib.hpp \ |
| 181 | 182 | GModelSpectralPlaw.hpp \ |
| 182 | 183 | GModelSpectralPlawPhotonFlux.hpp \ |
| 183 | 184 | GModelSpectralPlawEnergyFlux.hpp \ |
| 185 | + GModelSpectralComposite.hpp \ | |
| 184 | 186 | GModelTemporal.hpp \ |
| 185 | 187 | GModelTemporalRegistry.hpp \ |
| 186 | 188 | GModelTemporalConst.hpp | ... | ... |
inst/cta/include/GCTAResponseCube.hpp
| ... | ... | @@ -136,6 +136,9 @@ private: |
| 136 | 136 | double irf_diffuse(const GEvent& event, |
| 137 | 137 | const GSource& source, |
| 138 | 138 | const GObservation& obs) const; |
| 139 | + double irf_composite(const GEvent& event, | |
| 140 | + const GSource& source, | |
| 141 | + const GObservation& obs) const; | |
| 139 | 142 | |
| 140 | 143 | // Private data members |
| 141 | 144 | GCTACubeExposure m_exposure; //!< Exposure cube | ... | ... |
inst/cta/include/GCTAResponseIrf.hpp
| ... | ... | @@ -176,6 +176,9 @@ private: |
| 176 | 176 | double irf_diffuse(const GEvent& event, |
| 177 | 177 | const GSource& source, |
| 178 | 178 | const GObservation& obs) const; |
| 179 | + double irf_composite(const GEvent& event, | |
| 180 | + const GSource& source, | |
| 181 | + const GObservation& obs) const; | |
| 179 | 182 | double nroi_ptsrc(const GModelSky& model, |
| 180 | 183 | const GEnergy& srcEng, |
| 181 | 184 | const GTime& srcTime, |
| ... | ... | @@ -200,6 +203,12 @@ private: |
| 200 | 203 | const GEnergy& obsEng, |
| 201 | 204 | const GTime& obsTime, |
| 202 | 205 | const GObservation& obs) const; |
| 206 | + double nroi_composite(const GModelSky& model, | |
| 207 | + const GEnergy& srcEng, | |
| 208 | + const GTime& srcTime, | |
| 209 | + const GEnergy& obsEng, | |
| 210 | + const GTime& obsTime, | |
| 211 | + const GObservation& obs) const; | |
| 203 | 212 | |
| 204 | 213 | // Private data members |
| 205 | 214 | GCaldb m_caldb; //!< Calibration database | ... | ... |
inst/cta/src/GCTAResponseCube.cpp
| ... | ... | @@ -40,6 +40,7 @@ |
| 40 | 40 | #include "GModelSpatialRadial.hpp" |
| 41 | 41 | #include "GModelSpatialRadialShell.hpp" |
| 42 | 42 | #include "GModelSpatialElliptical.hpp" |
| 43 | +#include "GModelSpatialComposite.hpp" | |
| 43 | 44 | #include "GModelSpatialDiffuse.hpp" |
| 44 | 45 | #include "GPhoton.hpp" |
| 45 | 46 | #include "GSource.hpp" |
| ... | ... | @@ -417,6 +418,9 @@ double GCTAResponseCube::irf(const GEvent& event, |
| 417 | 418 | case GMODEL_SPATIAL_DIFFUSE: |
| 418 | 419 | irf = irf_diffuse(event, source, obs); |
| 419 | 420 | break; |
| 421 | + case GMODEL_SPATIAL_COMPOSITE: | |
| 422 | + irf = irf_composite(event, source, obs); | |
| 423 | + break; | |
| 420 | 424 | default: |
| 421 | 425 | break; |
| 422 | 426 | } |
| ... | ... | @@ -1493,3 +1497,47 @@ double GCTAResponseCube::irf_diffuse(const GEvent& event, |
| 1493 | 1497 | // Return IRF value |
| 1494 | 1498 | return irf; |
| 1495 | 1499 | } |
| 1500 | + | |
| 1501 | + | |
| 1502 | +/***********************************************************************//** | |
| 1503 | + * @brief Return instrument response to composite source | |
| 1504 | + * | |
| 1505 | + * @param[in] event Observed event. | |
| 1506 | + * @param[in] source Source. | |
| 1507 | + * @param[in] obs Observation. | |
| 1508 | + * @return Instrument response to composite source. | |
| 1509 | + * | |
| 1510 | + * Returns the instrument response to a specified composite source. | |
| 1511 | + ***************************************************************************/ | |
| 1512 | +double GCTAResponseCube::irf_composite(const GEvent& event, | |
| 1513 | + const GSource& source, | |
| 1514 | + const GObservation& obs) const | |
| 1515 | +{ | |
| 1516 | + // Initialise IRF | |
| 1517 | + double irf = 0.0; | |
| 1518 | + | |
| 1519 | + // Get pointer to composite model | |
| 1520 | + const GModelSpatialComposite* model = | |
| 1521 | + dynamic_cast<const GModelSpatialComposite*>(source.model()); | |
| 1522 | + | |
| 1523 | + // Loop over model components | |
| 1524 | + for (int i = 0; i < model->components(); ++i) { | |
| 1525 | + | |
| 1526 | + // Get pointer to spatial component | |
| 1527 | + GModelSpatial* spat = const_cast<GModelSpatial*>(model->component(i)); | |
| 1528 | + | |
| 1529 | + // Create new GSource object | |
| 1530 | + GSource src(source.name(), spat, source.energy(), source.time()); | |
| 1531 | + | |
| 1532 | + // Compute irf value | |
| 1533 | + irf += this->irf(event, source, obs); | |
| 1534 | + | |
| 1535 | + } | |
| 1536 | + | |
| 1537 | + // Divide by number of model components | |
| 1538 | + if (model->components() > 0) { | |
| 1539 | + irf /= double(model->components()); | |
| 1540 | + } | |
| 1541 | + | |
| 1542 | + return irf; | |
| 1543 | +} | ... | ... |
inst/cta/src/GCTAResponseIrf.cpp
| ... | ... | @@ -44,6 +44,7 @@ |
| 44 | 44 | #include "GModelSpatialRadial.hpp" |
| 45 | 45 | #include "GModelSpatialRadialShell.hpp" |
| 46 | 46 | #include "GModelSpatialElliptical.hpp" |
| 47 | +#include "GModelSpatialComposite.hpp" | |
| 47 | 48 | #include "GCTAObservation.hpp" |
| 48 | 49 | #include "GCTAResponseIrf.hpp" |
| 49 | 50 | #include "GCTAResponse_helpers.hpp" |
| ... | ... | @@ -431,6 +432,9 @@ double GCTAResponseIrf::irf(const GEvent& event, |
| 431 | 432 | case GMODEL_SPATIAL_DIFFUSE: |
| 432 | 433 | irf = irf_diffuse(event, source, obs); |
| 433 | 434 | break; |
| 435 | + case GMODEL_SPATIAL_COMPOSITE: | |
| 436 | + irf = irf_composite(event, source, obs); | |
| 437 | + break; | |
| 434 | 438 | default: |
| 435 | 439 | break; |
| 436 | 440 | } |
| ... | ... | @@ -1864,6 +1868,9 @@ double GCTAResponseIrf::nroi(const GModelSky& model, |
| 1864 | 1868 | case GMODEL_SPATIAL_DIFFUSE: |
| 1865 | 1869 | nroi = nroi_diffuse(model, srcEng, srcTime, obsEng, obsTime, obs); |
| 1866 | 1870 | break; |
| 1871 | + case GMODEL_SPATIAL_COMPOSITE: | |
| 1872 | + nroi = nroi_composite(model, srcEng, srcTime, obsEng, obsTime, obs); | |
| 1873 | + break; | |
| 1867 | 1874 | default: |
| 1868 | 1875 | break; |
| 1869 | 1876 | } |
| ... | ... | @@ -2846,6 +2853,51 @@ double GCTAResponseIrf::irf_diffuse(const GEvent& event, |
| 2846 | 2853 | |
| 2847 | 2854 | |
| 2848 | 2855 | /***********************************************************************//** |
| 2856 | + * @brief Return instrument response to composite source | |
| 2857 | + * | |
| 2858 | + * @param[in] event Observed event. | |
| 2859 | + * @param[in] source Source. | |
| 2860 | + * @param[in] obs Observation. | |
| 2861 | + * @return Instrument response to composite source. | |
| 2862 | + * | |
| 2863 | + * Returns the instrument response to a specified composite source. | |
| 2864 | + ***************************************************************************/ | |
| 2865 | +double GCTAResponseIrf::irf_composite(const GEvent& event, | |
| 2866 | + const GSource& source, | |
| 2867 | + const GObservation& obs) const | |
| 2868 | +{ | |
| 2869 | + // Initialise IRF | |
| 2870 | + double irf = 0.0; | |
| 2871 | + | |
| 2872 | + // Get pointer to composite model | |
| 2873 | + const GModelSpatialComposite* model = | |
| 2874 | + dynamic_cast<const GModelSpatialComposite*>(source.model()); | |
| 2875 | + | |
| 2876 | + // Loop over model components | |
| 2877 | + for (int i = 0; i < model->components(); ++i) { | |
| 2878 | + | |
| 2879 | + // Get pointer to spatial component | |
| 2880 | + GModelSpatial* spat = const_cast<GModelSpatial*>(model->component(i)); | |
| 2881 | + | |
| 2882 | + // Create new GSource object | |
| 2883 | + GSource src(source.name(), spat, source.energy(), source.time()); | |
| 2884 | + | |
| 2885 | + // Compute irf value | |
| 2886 | + irf += this->irf(event, src, obs); | |
| 2887 | + | |
| 2888 | + } | |
| 2889 | + | |
| 2890 | + // Divide by number of model components | |
| 2891 | + if (model->components() > 0) { | |
| 2892 | + irf /= double(model->components()); | |
| 2893 | + } | |
| 2894 | + | |
| 2895 | + // Return IRF value | |
| 2896 | + return irf; | |
| 2897 | +} | |
| 2898 | + | |
| 2899 | + | |
| 2900 | +/***********************************************************************//** | |
| 2849 | 2901 | * @brief Return spatial integral of point source model |
| 2850 | 2902 | * |
| 2851 | 2903 | * @param[in] model Sky Model. |
| ... | ... | @@ -3432,3 +3484,68 @@ double GCTAResponseIrf::nroi_diffuse(const GModelSky& model, |
| 3432 | 3484 | // Return Nroi |
| 3433 | 3485 | return nroi; |
| 3434 | 3486 | } |
| 3487 | + | |
| 3488 | + | |
| 3489 | +/***********************************************************************//** | |
| 3490 | + * @brief Return spatial integral of composite source model | |
| 3491 | + * | |
| 3492 | + * @param[in] model Sky Model. | |
| 3493 | + * @param[in] srcEng True photon energy. | |
| 3494 | + * @param[in] srcTime True photon arrival time. | |
| 3495 | + * @param[in] obsEng Observed event energy. | |
| 3496 | + * @param[in] obsTime Observed event arrival time. | |
| 3497 | + * @param[in] obs Observation. | |
| 3498 | + * | |
| 3499 | + * Computes the integral | |
| 3500 | + * | |
| 3501 | + * \f[ | |
| 3502 | + * N_{\rm ROI}(E',t'|E,t) = \int_{\rm ROI} P(p',E',t'|E,t) dp' | |
| 3503 | + * \f] | |
| 3504 | + * | |
| 3505 | + * of | |
| 3506 | + * | |
| 3507 | + * \f[ | |
| 3508 | + * P(p',E',t'|E,t) = \int | |
| 3509 | + * S(p,E,t) \times R(p',E',t'|p,E,t) \, dp | |
| 3510 | + * \f] | |
| 3511 | + * | |
| 3512 | + * over the Region of Interest (ROI) for a composite source model | |
| 3513 | + * \f$S(p,E,t)\f$ and the response function \f$R(p',E',t'|p,E,t)\f$. | |
| 3514 | + ***************************************************************************/ | |
| 3515 | +double GCTAResponseIrf::nroi_composite(const GModelSky& model, | |
| 3516 | + const GEnergy& srcEng, | |
| 3517 | + const GTime& srcTime, | |
| 3518 | + const GEnergy& obsEng, | |
| 3519 | + const GTime& obsTime, | |
| 3520 | + const GObservation& obs) const | |
| 3521 | +{ | |
| 3522 | + // Initialise nroi | |
| 3523 | + double nroi = 0.0; | |
| 3524 | + | |
| 3525 | + // Get composite model | |
| 3526 | + GModelSpatialComposite* comp = | |
| 3527 | + dynamic_cast<GModelSpatialComposite*>(model.spatial()); | |
| 3528 | + | |
| 3529 | + // Loop over model components | |
| 3530 | + for (int i = 0; i < comp->components(); ++i) { | |
| 3531 | + | |
| 3532 | + // Create new sky model | |
| 3533 | + GModelSky sky = GModelSky(model); | |
| 3534 | + | |
| 3535 | + // Assign spatial part | |
| 3536 | + sky.spatial(comp->component(i)); | |
| 3537 | + | |
| 3538 | + // Compute nroi | |
| 3539 | + nroi += this->nroi(sky, srcEng, srcTime, obsEng, obsTime, obs); | |
| 3540 | + | |
| 3541 | + } | |
| 3542 | + | |
| 3543 | + // Divide by number of model components | |
| 3544 | + if (comp->components() > 0) { | |
| 3545 | + nroi /= double(comp->components()); | |
| 3546 | + } | |
| 3547 | + | |
| 3548 | + // Return nroi | |
| 3549 | + return nroi; | |
| 3550 | + | |
| 3551 | +} | ... | ... |
pyext/GModelSpatialComposite.i
0 → 100644
| 1 | +/*************************************************************************** | |
| 2 | + * GModelSpatialComposite.i - Spatial point source model class * | |
| 3 | + * ----------------------------------------------------------------------- * | |
| 4 | + * copyright (C) 2016 by Domenico Tiziani * | |
| 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 GModelSpatialComposite.i | |
| 23 | + * @brief Spatial composite model class Python interface | |
| 24 | + * @author Domenico Tiziani | |
| 25 | + */ | |
| 26 | +%{ | |
| 27 | +/* Put headers and other declarations here that are needed for compilation */ | |
| 28 | +#include "GModelSpatialComposite.hpp" | |
| 29 | +%} | |
| 30 | + | |
| 31 | + | |
| 32 | +/***********************************************************************//** | |
| 33 | + * @class GModelSpatialComposite | |
| 34 | + * | |
| 35 | + * @brief Spatial composite model | |
| 36 | + ***************************************************************************/ | |
| 37 | +class GModelSpatialComposite : public GModelSpatial { | |
| 38 | + | |
| 39 | +public: | |
| 40 | + // Constructors and destructors | |
| 41 | + GModelSpatialComposite(void); | |
| 42 | + explicit GModelSpatialComposite(const GXmlElement& xml); | |
| 43 | + GModelSpatialComposite(const GModelSpatialComposite& model); | |
| 44 | + virtual ~GModelSpatialComposite(void); | |
| 45 | + | |
| 46 | + // Implemented virtual methods | |
| 47 | + virtual void clear(void); | |
| 48 | + virtual GModelSpatialComposite* clone(void) const; | |
| 49 | + virtual std::string classname(void) const; | |
| 50 | + virtual std::string type(void) const; | |
| 51 | + virtual double eval(const GPhoton& photon, | |
| 52 | + const bool& gradients = false) const; | |
| 53 | + virtual GSkyDir mc(const GEnergy& energy, | |
| 54 | + const GTime& time, | |
| 55 | + GRan& ran) const; | |
| 56 | + virtual double mc_norm(const GSkyDir& dir, | |
| 57 | + const double& radius) const; | |
| 58 | + virtual bool contains(const GSkyDir& dir, | |
| 59 | + const double& margin = 0.0) const; | |
| 60 | + virtual void read(const GXmlElement& xml); | |
| 61 | + virtual void write(GXmlElement& xml) const; | |
| 62 | + | |
| 63 | + // Other methods | |
| 64 | + int components(void) const; | |
| 65 | + void append(const GModelSpatial& component, | |
| 66 | + const std::string& name = ""); | |
| 67 | + const GModelSpatial* component(const int& index) const; | |
| 68 | + const GModelSpatial* component(const std::string& name) const; | |
| 69 | +}; | |
| 70 | + | |
| 71 | + | |
| 72 | +/***********************************************************************//** | |
| 73 | + * @brief GModelSpatialComposite class extension | |
| 74 | + ***************************************************************************/ | |
| 75 | +%extend GModelSpatialComposite { | |
| 76 | + GModelSpatialComposite copy() { | |
| 77 | + return (*self); | |
| 78 | + } | |
| 79 | +}; | ... | ... |
pyext/GModelSpectralComposite.i
0 → 100644
| 1 | +/*************************************************************************** | |
| 2 | + * GModelSpectralComposite.i - Spectral power law model class * | |
| 3 | + * ----------------------------------------------------------------------- * | |
| 4 | + * copyright (C) 2016 Michael Mayer * | |
| 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 GModelSpecComposite spectral model class interface definition | |
| 23 | + * @author Michael Mayer | |
| 24 | + */ | |
| 25 | +%{ | |
| 26 | +/* Put headers and other declarations here that are needed for compilation */ | |
| 27 | +#include "GModelSpectralComposite.hpp" | |
| 28 | +%} | |
| 29 | + | |
| 30 | + | |
| 31 | +/***********************************************************************//** | |
| 32 | + * @class GModelSpectralComposite | |
| 33 | + * | |
| 34 | + * @brief Composite spectral model class | |
| 35 | + ***************************************************************************/ | |
| 36 | +class GModelSpectralComposite : public GModelSpectral { | |
| 37 | +public: | |
| 38 | + // Constructors and destructors | |
| 39 | + GModelSpectralComposite(void); | |
| 40 | + explicit GModelSpectralComposite(const GXmlElement& xml); | |
| 41 | + GModelSpectralComposite(const GModelSpectralComposite& model); | |
| 42 | + virtual ~GModelSpectralComposite(void); | |
| 43 | + | |
| 44 | + // Implemented pure virtual methods | |
| 45 | + virtual void clear(void); | |
| 46 | + virtual GModelSpectralComposite* clone(void) const; | |
| 47 | + virtual std::string classname(void) const; | |
| 48 | + virtual std::string type(void) const; | |
| 49 | + virtual double eval(const GEnergy& srcEng, | |
| 50 | + const GTime& srcTime = GTime(), | |
| 51 | + const bool& gradients = false) const; | |
| 52 | + virtual double flux(const GEnergy& emin, | |
| 53 | + const GEnergy& emax) const; | |
| 54 | + virtual double eflux(const GEnergy& emin, | |
| 55 | + const GEnergy& emax) const; | |
| 56 | + virtual GEnergy mc(const GEnergy& emin, | |
| 57 | + const GEnergy& emax, | |
| 58 | + const GTime& time, | |
| 59 | + GRan& ran) const; | |
| 60 | + virtual void read(const GXmlElement& xml); | |
| 61 | + virtual void write(GXmlElement& xml) const; | |
| 62 | + | |
| 63 | + // Other methods | |
| 64 | + void append(const GModelSpectral& spec, const std::string& name=""); | |
| 65 | + int components(void) const; | |
| 66 | + GModelSpectral* component(const int& index) const; | |
| 67 | + GModelSpectral* component(const std::string& name) const; | |
| 68 | + | |
| 69 | +}; | |
| 70 | + | |
| 71 | + | |
| 72 | +/***********************************************************************//** | |
| 73 | + * @brief GModelSpectralComposite class extension | |
| 74 | + ***************************************************************************/ | |
| 75 | +%extend GModelSpectralComposite { | |
| 76 | + GModelSpectralComposite copy() { | |
| 77 | + return (*self); | |
| 78 | + } | |
| 79 | +}; | ... | ... |
pyext/gammalib/model.i
| ... | ... | @@ -141,6 +141,7 @@ |
| 141 | 141 | %include "GModelSpatialDiffuseConst.i" |
| 142 | 142 | %include "GModelSpatialDiffuseCube.i" |
| 143 | 143 | %include "GModelSpatialDiffuseMap.i" |
| 144 | +%include "GModelSpatialComposite.i" | |
| 144 | 145 | %include "GModelSpectral.i" |
| 145 | 146 | %include "GModelSpectralRegistry.i" |
| 146 | 147 | %include "GModelSpectralBrokenPlaw.i" |
| ... | ... | @@ -155,6 +156,7 @@ |
| 155 | 156 | %include "GModelSpectralPlaw.i" |
| 156 | 157 | %include "GModelSpectralPlawPhotonFlux.i" |
| 157 | 158 | %include "GModelSpectralPlawEnergyFlux.i" |
| 159 | +%include "GModelSpectralComposite.i" | |
| 158 | 160 | %include "GModelTemporal.i" |
| 159 | 161 | %include "GModelTemporalRegistry.i" |
| 160 | 162 | %include "GModelTemporalConst.i" | ... | ... |
src/model/GModelSky.cpp
| ... | ... | @@ -48,9 +48,11 @@ |
| 48 | 48 | const GModelSky g_pointsource_seed("PointSource"); |
| 49 | 49 | const GModelSky g_extendedsource_seed("ExtendedSource"); |
| 50 | 50 | const GModelSky g_diffusesource_seed("DiffuseSource"); |
| 51 | +const GModelSky g_compositesource_seed("CompositeSource"); | |
| 51 | 52 | const GModelRegistry g_pointsource_registry(&g_pointsource_seed); |
| 52 | 53 | const GModelRegistry g_extendedsource_registry(&g_extendedsource_seed); |
| 53 | 54 | const GModelRegistry g_diffusesource_registry(&g_diffusesource_seed); |
| 55 | +const GModelRegistry g_compositesource_registry(&g_compositesource_seed); | |
| 54 | 56 | |
| 55 | 57 | /* __ Method name definitions ____________________________________________ */ |
| 56 | 58 | #define G_NPRED "GModelSky::npred(GEnergy&, GTime&, GObservation&)" | ... | ... |
src/model/GModelSpatialComposite.cpp
0 → 100644
| 1 | +/*************************************************************************** | |
| 2 | + * GModelSpatialComposite.cpp - Spatial composite model class * | |
| 3 | + * ----------------------------------------------------------------------- * | |
| 4 | + * copyright (C) 2016 by Domenico Tiziani * | |
| 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 GModelSpatialComposite.cpp | |
| 23 | + * @brief Spatial composite model class implementation | |
| 24 | + * @author Domenico Tiziani | |
| 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 "GModelSpatialComposite.hpp" | |
| 35 | +#include "GModelSpatialRegistry.hpp" | |
| 36 | + | |
| 37 | +/* __ Constants __________________________________________________________ */ | |
| 38 | + | |
| 39 | + | |
| 40 | +/* __ Globals ____________________________________________________________ */ | |
| 41 | +const GModelSpatialComposite g_spatial_comp_seed; | |
| 42 | +const GModelSpatialRegistry g_spatial_comp_registry(&g_spatial_comp_seed); | |
| 43 | + | |
| 44 | +/* __ Method name definitions ____________________________________________ */ | |
| 45 | +#define G_READ "GModelSpatialComposite::read(GXmlElement&)" | |
| 46 | +#define G_WRITE "GModelSpatialComposite::write(GXmlElement&)" | |
| 47 | +#define G_COMPONENT_INDEX "GModelSpatialComposite::component(int&)" | |
| 48 | +#define G_COMPONENT_NAME "GModelSpatialComposite::component(std::string&)" | |
| 49 | +#define G_APPEND "GModelSpatialComposite::append(GModelSpatial&, "\ | |
| 50 | + "std::string&)" | |
| 51 | + | |
| 52 | +/* __ Macros _____________________________________________________________ */ | |
| 53 | + | |
| 54 | +/* __ Coding definitions _________________________________________________ */ | |
| 55 | + | |
| 56 | +/* __ Debug definitions __________________________________________________ */ | |
| 57 | + | |
| 58 | + | |
| 59 | +/*========================================================================== | |
| 60 | + = = | |
| 61 | + = Constructors/destructors = | |
| 62 | + = = | |
| 63 | + ==========================================================================*/ | |
| 64 | + | |
| 65 | +/***********************************************************************//** | |
| 66 | + * @brief Void constructor | |
| 67 | + * | |
| 68 | + * Constructs empty spatial composite model. | |
| 69 | + ***************************************************************************/ | |
| 70 | +GModelSpatialComposite::GModelSpatialComposite(void) : GModelSpatial() | |
| 71 | +{ | |
| 72 | + // Initialise members | |
| 73 | + init_members(); | |
| 74 | + | |
| 75 | + // Return | |
| 76 | + return; | |
| 77 | +} | |
| 78 | + | |
| 79 | + | |
| 80 | +/***********************************************************************//** | |
| 81 | + * @brief Model type constructor | |
| 82 | + * | |
| 83 | + * @param[in] dummy Dummy flag. | |
| 84 | + * @param[in] type Model type. | |
| 85 | + * | |
| 86 | + * Constructs empty spatial composite model by specifying a model @p type. | |
| 87 | + ***************************************************************************/ | |
| 88 | +GModelSpatialComposite::GModelSpatialComposite(const bool& dummy, | |
| 89 | + const std::string& type) : | |
| 90 | + GModelSpatial() | |
| 91 | +{ | |
| 92 | + // Initialise members | |
| 93 | + init_members(); | |
| 94 | + | |
| 95 | + // Set model type | |
| 96 | + m_type = type; | |
| 97 | + | |
| 98 | + // Return | |
| 99 | + return; | |
| 100 | +} | |
| 101 | + | |
| 102 | + | |
| 103 | +/***********************************************************************//** | |
| 104 | + * @brief XML constructor | |
| 105 | + * | |
| 106 | + * @param[in] xml XML element. | |
| 107 | + * | |
| 108 | + * Construct a spatial composite model by extracting information from an | |
| 109 | + * XML element. See the read() method for more information about the expected | |
| 110 | + * structure of the XML element. | |
| 111 | + ***************************************************************************/ | |
| 112 | +GModelSpatialComposite::GModelSpatialComposite(const GXmlElement& xml) : | |
| 113 | + GModelSpatial() | |
| 114 | +{ | |
| 115 | + // Initialise members | |
| 116 | + init_members(); | |
| 117 | + | |
| 118 | + // Read information from XML element | |
| 119 | + read(xml); | |
| 120 | + | |
| 121 | + // Return | |
| 122 | + return; | |
| 123 | +} | |
| 124 | + | |
| 125 | + | |
| 126 | +/***********************************************************************//** | |
| 127 | + * @brief Copy constructor | |
| 128 | + * | |
| 129 | + * @param[in] model Spatial composite model. | |
| 130 | + ***************************************************************************/ | |
| 131 | +GModelSpatialComposite::GModelSpatialComposite(const GModelSpatialComposite& model) : | |
| 132 | + GModelSpatial(model) | |
| 133 | +{ | |
| 134 | + // Initialise members | |
| 135 | + init_members(); | |
| 136 | + | |
| 137 | + // Copy members | |
| 138 | + copy_members(model); | |
| 139 | + | |
| 140 | + // Return | |
| 141 | + return; | |
| 142 | +} | |
| 143 | + | |
| 144 | + | |
| 145 | +/***********************************************************************//** | |
| 146 | + * @brief Destructor | |
| 147 | + ***************************************************************************/ | |
| 148 | +GModelSpatialComposite::~GModelSpatialComposite(void) | |
| 149 | +{ | |
| 150 | + // Free members | |
| 151 | + free_members(); | |
| 152 | + | |
| 153 | + // Return | |
| 154 | + return; | |
| 155 | +} | |
| 156 | + | |
| 157 | + | |
| 158 | +/*========================================================================== | |
| 159 | + = = | |
| 160 | + = Operators = | |
| 161 | + = = | |
| 162 | + ==========================================================================*/ | |
| 163 | + | |
| 164 | +/***********************************************************************//** | |
| 165 | + * @brief Assignment operator | |
| 166 | + * | |
| 167 | + * @param[in] model Spatial composite model. | |
| 168 | + * @return Spatial composite model. | |
| 169 | + ***************************************************************************/ | |
| 170 | +GModelSpatialComposite& GModelSpatialComposite::operator=(const GModelSpatialComposite& model) | |
| 171 | +{ | |
| 172 | + // Execute only if object is not identical | |
| 173 | + if (this != &model) { | |
| 174 | + | |
| 175 | + // Copy base class members | |
| 176 | + this->GModelSpatial::operator=(model); | |
| 177 | + | |
| 178 | + // Free members | |
| 179 | + free_members(); | |
| 180 | + | |
| 181 | + // Initialise members | |
| 182 | + init_members(); | |
| 183 | + | |
| 184 | + // Copy members | |
| 185 | + copy_members(model); | |
| 186 | + | |
| 187 | + } // endif: object was not identical | |
| 188 | + | |
| 189 | + // Return | |
| 190 | + return *this; | |
| 191 | +} | |
| 192 | + | |
| 193 | + | |
| 194 | +/*========================================================================== | |
| 195 | + = = | |
| 196 | + = Public methods = | |
| 197 | + = = | |
| 198 | + ==========================================================================*/ | |
| 199 | + | |
| 200 | +/***********************************************************************//** | |
| 201 | + * @brief Clear spatial composite model | |
| 202 | + ***************************************************************************/ | |
| 203 | +void GModelSpatialComposite::clear(void) | |
| 204 | +{ | |
| 205 | + // Free class members (base and derived classes, derived class first) | |
| 206 | + free_members(); | |
| 207 | + this->GModelSpatial::free_members(); | |
| 208 | + | |
| 209 | + // Initialise members | |
| 210 | + this->GModelSpatial::init_members(); | |
| 211 | + init_members(); | |
| 212 | + | |
| 213 | + // Return | |
| 214 | + return; | |
| 215 | +} | |
| 216 | + | |
| 217 | + | |
| 218 | +/***********************************************************************//** | |
| 219 | + * @brief Clone spatial composite model | |
| 220 | + * | |
| 221 | + * @return Pointer to deep copy of spatial composite model. | |
| 222 | + ***************************************************************************/ | |
| 223 | +GModelSpatialComposite* GModelSpatialComposite::clone(void) const | |
| 224 | +{ | |
| 225 | + // Clone point source model | |
| 226 | + return new GModelSpatialComposite(*this); | |
| 227 | +} | |
| 228 | + | |
| 229 | + | |
| 230 | +/***********************************************************************//** | |
| 231 | + * @brief Evaluate function | |
| 232 | + * | |
| 233 | + * @param[in] photon Incident photon. | |
| 234 | + * @param[in] gradients Compute gradients? | |
| 235 | + * @return Model value. | |
| 236 | + * | |
| 237 | + * Evaluates the spatial composite model by summing all model components and | |
| 238 | + * dividing the sum by the number of components. | |
| 239 | + ***************************************************************************/ | |
| 240 | +double GModelSpatialComposite::eval(const GPhoton& photon, | |
| 241 | + const bool& gradients) const | |
| 242 | +{ | |
| 243 | + // Initalise value | |
| 244 | + double value = 0.0; | |
| 245 | + | |
| 246 | + // Sum over all components | |
| 247 | + for (int i = 0; i < m_components.size(); ++i) { | |
| 248 | + value += m_components[i]->eval(photon, gradients); | |
| 249 | + } | |
| 250 | + | |
| 251 | + // Normalise sum by the number of components | |
| 252 | + if (m_components.size() > 0) { | |
| 253 | + value /= double(m_components.size()); | |
| 254 | + } | |
| 255 | + | |
| 256 | + // Return value | |
| 257 | + return value; | |
| 258 | +} | |
| 259 | + | |
| 260 | + | |
| 261 | +/***********************************************************************//** | |
| 262 | + * @brief Returns MC sky direction | |
| 263 | + * | |
| 264 | + * @param[in] energy Photon energy. | |
| 265 | + * @param[in] time Photon arrival time. | |
| 266 | + * @param[in,out] ran Random number generator. | |
| 267 | + * @return Sky direction. | |
| 268 | + * | |
| 269 | + * Draws an arbitrary model component and an arbitrary direction from that | |
| 270 | + * component. | |
| 271 | + ***************************************************************************/ | |
| 272 | +GSkyDir GModelSpatialComposite::mc(const GEnergy& energy, | |
| 273 | + const GTime& time, | |
| 274 | + GRan& ran) const | |
| 275 | +{ | |
| 276 | + // Randomly choose one model component | |
| 277 | + int index = int(ran.uniform() * double(m_components.size())); | |
| 278 | + if (index >= m_components.size()) { | |
| 279 | + index = m_components.size(); | |
| 280 | + } | |
| 281 | + | |
| 282 | + // Draw random sky direction from the selected component | |
| 283 | + GSkyDir sky_dir = m_components[index]->mc(energy, time, ran); | |
| 284 | + | |
| 285 | + // Return sky direction | |
| 286 | + return (sky_dir); | |
| 287 | +} | |
| 288 | + | |
| 289 | + | |
| 290 | +/***********************************************************************//** | |
| 291 | + * @brief Checks where model contains specified sky direction | |
| 292 | + * | |
| 293 | + * @param[in] dir Sky direction. | |
| 294 | + * @param[in] margin Margin to be added to sky direction (degrees) | |
| 295 | + * @return True if the model contains the sky direction. | |
| 296 | + * | |
| 297 | + * Signals whether a sky direction is contained in one of the | |
| 298 | + * model components. | |
| 299 | + ***************************************************************************/ | |
| 300 | +bool GModelSpatialComposite::contains(const GSkyDir& dir, | |
| 301 | + const double& margin) const | |
| 302 | +{ | |
| 303 | + // Initialise containment flag | |
| 304 | + bool containment = false; | |
| 305 | + | |
| 306 | + // Loop over all components | |
| 307 | + for (int i = 0; i < m_components.size(); ++i) { | |
| 308 | + if (m_components[i]->contains(dir, margin)) { | |
| 309 | + containment = true; | |
| 310 | + break; | |
| 311 | + } | |
| 312 | + } | |
| 313 | + | |
| 314 | + // Return containment | |
| 315 | + return containment; | |
| 316 | +} | |
| 317 | + | |
| 318 | + | |
| 319 | +/***********************************************************************//** | |
| 320 | + * @brief Read model from XML element | |
| 321 | + * | |
| 322 | + * @param[in] xml XML element. | |
| 323 | + * | |
| 324 | + * Reads the spatial information from an XML element. | |
| 325 | + ***************************************************************************/ | |
| 326 | +void GModelSpatialComposite::read(const GXmlElement& xml) | |
| 327 | +{ | |
| 328 | + // Get number of spatial components | |
| 329 | + int n_comp = xml.elements("spatialModel"); | |
| 330 | + | |
| 331 | + // Loop over spatial elements | |
| 332 | + for (int i = 0; i < n_comp; ++i) { | |
| 333 | + | |
| 334 | + // Get spatial XML element | |
| 335 | + const GXmlElement* spec = xml.element("spatialModel", i); | |
| 336 | + | |
| 337 | + // Initialise a spatial registry object | |
| 338 | + GModelSpatialRegistry registry; | |
| 339 | + | |
| 340 | + // Read spatial model | |
| 341 | + GModelSpatial* ptr = registry.alloc(*spec); | |
| 342 | + | |
| 343 | + // Get component attribute from XML file | |
| 344 | + std::string component_name = spec->attribute("component"); | |
| 345 | + | |
| 346 | + // Append spatial component to container | |
| 347 | + append(*ptr, component_name); | |
| 348 | + | |
| 349 | + } // endfor: loop over components | |
| 350 | + | |
| 351 | + // Return | |
| 352 | + return; | |
| 353 | +} | |
| 354 | + | |
| 355 | + | |
| 356 | +/***********************************************************************//** | |
| 357 | + * @brief Write model into XML element | |
| 358 | + * | |
| 359 | + * @param[in] xml XML element into which model information is written. | |
| 360 | + * | |
| 361 | + * @exception GException::model_invalid_spatial | |
| 362 | + * Existing XML element is not of type 'SkyDirFunction' | |
| 363 | + * @exception GException::model_invalid_parnum | |
| 364 | + * Invalid number of model parameters found in XML element. | |
| 365 | + * @exception GException::model_invalid_parnames | |
| 366 | + * Invalid model parameter names found in XML element. | |
| 367 | + * | |
| 368 | + * Write the spatial information into an XML element. | |
| 369 | + ***************************************************************************/ | |
| 370 | +void GModelSpatialComposite::write(GXmlElement& xml) const | |
| 371 | +{ | |
| 372 | + // Set model type | |
| 373 | + if (xml.attribute("type") == "") { | |
| 374 | + xml.attribute("type", type()); | |
| 375 | + } | |
| 376 | + | |
| 377 | + // Verify model type | |
| 378 | + if (xml.attribute("type") != type()) { | |
| 379 | + throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"), | |
| 380 | + "Spatial model is not of type \""+type()+"\"."); | |
| 381 | + } | |
| 382 | + | |
| 383 | + // Write all model components | |
| 384 | + for (int i = 0; i < m_components.size(); ++i) { | |
| 385 | + | |
| 386 | + // Get spatial component | |
| 387 | + GModelSpatial* component = m_components[i]; | |
| 388 | + | |
| 389 | + // Fall through if component is empty | |
| 390 | + if (component == NULL) { | |
| 391 | + continue; | |
| 392 | + } | |
| 393 | + | |
| 394 | + // Find XML element with matching name | |
| 395 | + GXmlElement *matching_model = NULL; | |
| 396 | + for (int k = 0; k < xml.elements("spatialModel"); ++k) { | |
| 397 | + if (xml.element("spatialModel", k)->attribute("name") == | |
| 398 | + m_component_names[i]) { | |
| 399 | + matching_model = xml.element("spatialModel", k); | |
| 400 | + break; | |
| 401 | + } | |
| 402 | + } // endfor: loop over all XML elements | |
| 403 | + | |
| 404 | + // Create copy of the spatial model | |
| 405 | + GModelSpatial* spatial = component->clone(); | |
| 406 | + | |
| 407 | + // Loop over all parameters of component and strip prefix | |
| 408 | + for (int k = 0; k < spatial->size(); ++k) { | |
| 409 | + | |
| 410 | + // Get model parameter | |
| 411 | + GModelPar& par = (*spatial)[k]; | |
| 412 | + | |
| 413 | + // If name contains colon then strip the prefix and the colon from | |
| 414 | + // the name | |
| 415 | + std::string name = par.name(); | |
| 416 | + int found = name.find(":"); | |
| 417 | + if (found != std::string::npos) { | |
| 418 | + name = name.substr(found+1, std::string::npos); | |
| 419 | + par.name(name); | |
| 420 | + } | |
| 421 | + | |
| 422 | + } // endfor looped over all parameters | |
| 423 | + | |
| 424 | + // If an XML element exists then use it ... | |
| 425 | + if (matching_model != NULL) { | |
| 426 | + spatial->write(*matching_model); | |
| 427 | + } | |
| 428 | + | |
| 429 | + // ... otherwise create new XML element | |
| 430 | + else { | |
| 431 | + GXmlElement element("spatialModel"); | |
| 432 | + spatial->write(element); | |
| 433 | + xml.append(element); | |
| 434 | + } | |
| 435 | + | |
| 436 | + // Delete clone | |
| 437 | + delete spatial; | |
| 438 | + | |
| 439 | + } // endfor: loop over all components | |
| 440 | + | |
| 441 | + // TODO: Remove unused xml elements | |
| 442 | + | |
| 443 | + // Return | |
| 444 | + return; | |
| 445 | +} | |
| 446 | + | |
| 447 | + | |
| 448 | +/***********************************************************************//** | |
| 449 | + * @brief Append spatial component | |
| 450 | + * | |
| 451 | + * @param[in] component Spatial model component to append | |
| 452 | + * @param[in] name Name of spatial model (can be empty) | |
| 453 | + * | |
| 454 | + * Appends a spatial component to the composite model | |
| 455 | + ***************************************************************************/ | |
| 456 | +void GModelSpatialComposite::append(const GModelSpatial& component, | |
| 457 | + const std::string& name) | |
| 458 | +{ | |
| 459 | + // Append model container | |
| 460 | + m_components.push_back(component.clone()); | |
| 461 | + | |
| 462 | + // Get index of latest model | |
| 463 | + int index = m_components.size()-1; | |
| 464 | + | |
| 465 | + // Use model index if component name is empty | |
| 466 | + std::string component_name = !name.empty() ? name | |
| 467 | + : gammalib::str(m_components.size()); | |
| 468 | + | |
| 469 | + // Check if component name is unique, throw exception if not | |
| 470 | + if (gammalib::contains(m_component_names, component_name)) { | |
| 471 | + std::string msg = "Attempt to append component \""+component_name+"\" " | |
| 472 | + "to composite spatial model, but a component with the " | |
| 473 | + "same name exists already. Each component needs a " | |
| 474 | + "unique name."; | |
| 475 | + throw GException::invalid_value(G_APPEND, msg); | |
| 476 | + } | |
| 477 | + | |
| 478 | + // Add component name | |
| 479 | + m_component_names.push_back(component_name); | |
| 480 | + | |
| 481 | + // Get number of spectral parameters from model | |
| 482 | + int npars = m_components[index]->size(); | |
| 483 | + | |
| 484 | + // Loop over model parameters | |
| 485 | + for (int ipar = 0; ipar < npars; ++ipar) { | |
| 486 | + | |
| 487 | + // Get model parameter | |
| 488 | + GModelPar* par = &(m_components[index]->operator[](ipar)); | |
| 489 | + | |
| 490 | + // Modify parameter name | |
| 491 | + par->name(component_name+":"+par->name()); | |
| 492 | + | |
| 493 | + // Append model parameter with new name to internal container | |
| 494 | + m_pars.push_back(par); | |
| 495 | + | |
| 496 | + } // endfor: loop over model parameters | |
| 497 | + | |
| 498 | + // Return | |
| 499 | + return; | |
| 500 | +} | |
| 501 | + | |
| 502 | + | |
| 503 | +/***********************************************************************//** | |
| 504 | + * @brief Returns pointer to spatial component element | |
| 505 | + * | |
| 506 | + * @param[in] index Index of spatial component [0,...,components()-1]. | |
| 507 | + * @return Spatial model. | |
| 508 | + * | |
| 509 | + * @exception GException::out_of_range | |
| 510 | + * Index is out of range. | |
| 511 | + * | |
| 512 | + * Returns a spatial component to the composite model | |
| 513 | + ***************************************************************************/ | |
| 514 | +const GModelSpatial* GModelSpatialComposite::component(const int& index) const | |
| 515 | +{ | |
| 516 | + // Check if index is in validity range | |
| 517 | + if (index < 0 || index >= m_components.size()) { | |
| 518 | + throw GException::out_of_range(G_COMPONENT_INDEX, "Component Index", | |
| 519 | + index, m_components.size()); | |
| 520 | + } | |
| 521 | + | |
| 522 | + // Return spatial component | |
| 523 | + return m_components[index]; | |
| 524 | +} | |
| 525 | + | |
| 526 | + | |
| 527 | +/***********************************************************************//** | |
| 528 | + * @brief Returns pointer to specific spatial component | |
| 529 | + * | |
| 530 | + * @param[in] name Name of spatial component. | |
| 531 | + * @return Spatial model. | |
| 532 | + * | |
| 533 | + * @exception GException::invalid_argument | |
| 534 | + * Spatial model not found. | |
| 535 | + * | |
| 536 | + * Returns a spatial component of the composite model | |
| 537 | + ***************************************************************************/ | |
| 538 | +const GModelSpatial* GModelSpatialComposite::component(const std::string& name) const | |
| 539 | +{ | |
| 540 | + // Check if model name is found | |
| 541 | + int index = -1; | |
| 542 | + for (int i = 0; i < m_component_names.size(); ++i) { | |
| 543 | + if (m_component_names[i] == name) { | |
| 544 | + index = i; | |
| 545 | + break; | |
| 546 | + } | |
| 547 | + } | |
| 548 | + | |
| 549 | + // Check if component name was found | |
| 550 | + if (index == -1) { | |
| 551 | + std::string msg = "Model component \""+name+"\" not found in composite " | |
| 552 | + "spatial model."; | |
| 553 | + throw GException::invalid_argument(G_COMPONENT_NAME, msg); | |
| 554 | + } | |
| 555 | + | |
| 556 | + // Return spatial component | |
| 557 | + return m_components[index]; | |
| 558 | +} | |
| 559 | + | |
| 560 | + | |
| 561 | +/***********************************************************************//** | |
| 562 | + * @brief Print composite spatial model information | |
| 563 | + * | |
| 564 | + * @param[in] chatter Chattiness. | |
| 565 | + * @return String containing composite spatial model information. | |
| 566 | + ***************************************************************************/ | |
| 567 | +std::string GModelSpatialComposite::print(const GChatter& chatter) const | |
| 568 | +{ | |
| 569 | + // Initialise result string | |
| 570 | + std::string result; | |
| 571 | + | |
| 572 | + // Continue only if chatter is not silent | |
| 573 | + if (chatter != SILENT) { | |
| 574 | + | |
| 575 | + // Append header | |
| 576 | + result.append("=== GModelSpatialComposite ==="); | |
| 577 | + | |
| 578 | + // Append information | |
| 579 | + result.append("\n"+gammalib::parformat("Number of components")); | |
| 580 | + result.append(gammalib::str(components())); | |
| 581 | + result.append("\n"+gammalib::parformat("Number of parameters")); | |
| 582 | + result.append(gammalib::str(size())); | |
| 583 | + | |
| 584 | + // Print parameter information | |
| 585 | + for (int i = 0; i < size(); ++i) { | |
| 586 | + result.append("\n"+m_pars[i]->print(chatter)); | |
| 587 | + } | |
| 588 | + | |
| 589 | + } // endif: chatter was not silent | |
| 590 | + | |
| 591 | + // Return result | |
| 592 | + return result; | |
| 593 | +} | |
| 594 | + | |
| 595 | + | |
| 596 | +/*========================================================================== | |
| 597 | + = = | |
| 598 | + = Private methods = | |
| 599 | + = = | |
| 600 | + ==========================================================================*/ | |
| 601 | + | |
| 602 | +/***********************************************************************//** | |
| 603 | + * @brief Initialise class members | |
| 604 | + ***************************************************************************/ | |
| 605 | +void GModelSpatialComposite::init_members(void) | |
| 606 | +{ | |
| 607 | + // Initialise model type | |
| 608 | + m_type = "Composite"; | |
| 609 | + | |
| 610 | + // Initialise models vector | |
| 611 | + m_components.clear(); | |
| 612 | + m_component_names.clear(); | |
| 613 | + | |
| 614 | + // Return | |
| 615 | + return; | |
| 616 | +} | |
| 617 | + | |
| 618 | + | |
| 619 | +/***********************************************************************//** | |
| 620 | + * @brief Copy class members | |
| 621 | + * | |
| 622 | + * @param[in] model Spatial composite model. | |
| 623 | + ***************************************************************************/ | |
| 624 | +void GModelSpatialComposite::copy_members(const GModelSpatialComposite& model) | |
| 625 | +{ | |
| 626 | + // Copy members | |
| 627 | + m_type = model.m_type; | |
| 628 | + m_component_names = model.m_component_names; | |
| 629 | + | |
| 630 | + // Initialise components | |
| 631 | + m_components.clear(); | |
| 632 | + m_pars.clear(); | |
| 633 | + | |
| 634 | + // Copy components | |
| 635 | + for (int i = 0; i < model.m_components.size(); ++i) { | |
| 636 | + | |
| 637 | + // Clone component | |
| 638 | + m_components.push_back(model.m_components[i]->clone()); | |
| 639 | + | |
| 640 | + // Get number of parameters to append | |
| 641 | + int npars = m_components[i]->size(); | |
| 642 | + | |
| 643 | + // Append parameter references | |
| 644 | + for (int ipar = 0; ipar < npars; ++ipar) { | |
| 645 | + GModelPar& par = (*m_components[i])[ipar]; | |
| 646 | + m_pars.push_back(&par); | |
| 647 | + } | |
| 648 | + | |
| 649 | + } // endfor: looped over all components | |
| 650 | + | |
| 651 | + // Return | |
| 652 | + return; | |
| 653 | +} | |
| 654 | + | |
| 655 | + | |
| 656 | +/***********************************************************************//** | |
| 657 | + * @brief Delete class members | |
| 658 | + ***************************************************************************/ | |
| 659 | +void GModelSpatialComposite::free_members(void) | |
| 660 | +{ | |
| 661 | + // Free model components | |
| 662 | + for (int i = 0; i < m_components.size(); ++i) { | |
| 663 | + | |
| 664 | + // Delete component i | |
| 665 | + delete m_components[i]; | |
| 666 | + | |
| 667 | + // Signal free pointer | |
| 668 | + m_components[i] = NULL; | |
| 669 | + | |
| 670 | + } | |
| 671 | + | |
| 672 | + // Return | |
| 673 | + return; | |
| 674 | +} | ... | ... |
src/model/GModelSpatialEllipticalDisk.cpp
| ... | ... | @@ -599,7 +599,7 @@ void GModelSpatialEllipticalDisk::write(GXmlElement& xml) const |
| 599 | 599 | /***********************************************************************//** |
| 600 | 600 | * @brief Print information |
| 601 | 601 | * |
| 602 | - * @param[in] chatter Chattiness (defaults to NORMAL). | |
| 602 | + * @param[in] chatter Chattiness. | |
| 603 | 603 | * @return String containing model information. |
| 604 | 604 | ***************************************************************************/ |
| 605 | 605 | std::string GModelSpatialEllipticalDisk::print(const GChatter& chatter) const | ... | ... |
src/model/GModelSpatialPointSource.cpp
| ... | ... | @@ -501,6 +501,7 @@ void GModelSpatialPointSource::write(GXmlElement& xml) const |
| 501 | 501 | /***********************************************************************//** |
| 502 | 502 | * @brief Print point source information |
| 503 | 503 | * |
| 504 | + * @param[in] chatter Chattiness. | |
| 504 | 505 | * @return String containing point source information. |
| 505 | 506 | ***************************************************************************/ |
| 506 | 507 | std::string GModelSpatialPointSource::print(const GChatter& chatter) const | ... | ... |
src/model/GModelSpectralComposite.cpp
0 → 100644
| 1 | +/*************************************************************************** | |
| 2 | + * GModelSpectralComposite.cpp - Spectral composite model class * | |
| 3 | + * ----------------------------------------------------------------------- * | |
| 4 | + * copyright (C) 2016 by Michael Mayer * | |
| 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 GModelSpectralComposite.cpp | |
| 23 | + * @brief Composite spectral model class implementation | |
| 24 | + * @author Michael Mayer | |
| 25 | + */ | |
| 26 | + | |
| 27 | +/* __ Includes ___________________________________________________________ */ | |
| 28 | +#ifdef HAVE_CONFIG_H | |
| 29 | +#include <config.h> | |
| 30 | +#endif | |
| 31 | +#include <cmath> | |
| 32 | +#include "GException.hpp" | |
| 33 | +#include "GTools.hpp" | |
| 34 | +#include "GRan.hpp" | |
| 35 | +#include "GModelSpectralComposite.hpp" | |
| 36 | +#include "GModelSpectralRegistry.hpp" | |
| 37 | + | |
| 38 | +/* __ Constants __________________________________________________________ */ | |
| 39 | + | |
| 40 | +/* __ Globals ____________________________________________________________ */ | |
| 41 | +const GModelSpectralComposite g_spectral_comp_seed; | |
| 42 | +const GModelSpectralRegistry g_spectral_comp_registry(&g_spectral_comp_seed); | |
| 43 | + | |
| 44 | +/* __ Method name definitions ____________________________________________ */ | |
| 45 | +#define G_MC "GModelSpectralComposite::mc(GEnergy&, GEnergy&, GTime&, GRan&)" | |
| 46 | +#define G_WRITE "GModelSpectralComposite::write(GXmlElement&)" | |
| 47 | +#define G_COMPONENT_INDEX "GModelSpectralComposite::component(const int&)" | |
| 48 | +#define G_COMPONENT_NAME "GModelSpectralComposite::component(const std::string&)" | |
| 49 | +#define G_APPEND "GModelSpectralComposite::append(const GModelSpectral&, const std::string&)" | |
| 50 | + | |
| 51 | +/* __ Macros _____________________________________________________________ */ | |
| 52 | + | |
| 53 | +/* __ Coding definitions _________________________________________________ */ | |
| 54 | + | |
| 55 | +/* __ Debug definitions __________________________________________________ */ | |
| 56 | + | |
| 57 | + | |
| 58 | +/*========================================================================== | |
| 59 | + = = | |
| 60 | + = Constructors/destructors = | |
| 61 | + = = | |
| 62 | + ==========================================================================*/ | |
| 63 | + | |
| 64 | +/***********************************************************************//** | |
| 65 | + * @brief Void constructor | |
| 66 | + ***************************************************************************/ | |
| 67 | +GModelSpectralComposite::GModelSpectralComposite(void) : GModelSpectral() | |
| 68 | +{ | |
| 69 | + // Initialise private members for clean destruction | |
| 70 | + init_members(); | |
| 71 | + | |
| 72 | + // Return | |
| 73 | + return; | |
| 74 | +} | |
| 75 | + | |
| 76 | + | |
| 77 | +/***********************************************************************//** | |
| 78 | + * @brief XML constructor | |
| 79 | + * | |
| 80 | + * @param[in] xml XML element containing position information. | |
| 81 | + * | |
| 82 | + * Constructs a power law spectral model by extracting information from an | |
| 83 | + * XML element. See the read() method for more information about the expected | |
| 84 | + * structure of the XML element. | |
| 85 | + ***************************************************************************/ | |
| 86 | +GModelSpectralComposite::GModelSpectralComposite(const GXmlElement& xml) : GModelSpectral() | |
| 87 | +{ | |
| 88 | + // Initialise members | |
| 89 | + init_members(); | |
| 90 | + | |
| 91 | + // Read information from XML element | |
| 92 | + read(xml); | |
| 93 | + | |
| 94 | + // Return | |
| 95 | + return; | |
| 96 | +} | |
| 97 | + | |
| 98 | + | |
| 99 | +/***********************************************************************//** | |
| 100 | + * @brief Copy constructor | |
| 101 | + * | |
| 102 | + * @param[in] model Spectral power law model. | |
| 103 | + ***************************************************************************/ | |
| 104 | +GModelSpectralComposite::GModelSpectralComposite(const GModelSpectralComposite& model) | |
| 105 | + : GModelSpectral(model) | |
| 106 | +{ | |
| 107 | + // Initialise members | |
| 108 | + init_members(); | |
| 109 | + | |
| 110 | + // Copy members | |
| 111 | + copy_members(model); | |
| 112 | + | |
| 113 | + // Return | |
| 114 | + return; | |
| 115 | +} | |
| 116 | + | |
| 117 | + | |
| 118 | +/***********************************************************************//** | |
| 119 | + * @brief Destructor | |
| 120 | + ***************************************************************************/ | |
| 121 | +GModelSpectralComposite::~GModelSpectralComposite(void) | |
| 122 | +{ | |
| 123 | + // Free members | |
| 124 | + free_members(); | |
| 125 | + | |
| 126 | + // Return | |
| 127 | + return; | |
| 128 | +} | |
| 129 | + | |
| 130 | + | |
| 131 | +/*========================================================================== | |
| 132 | + = = | |
| 133 | + = Operators = | |
| 134 | + = = | |
| 135 | + ==========================================================================*/ | |
| 136 | + | |
| 137 | +/***********************************************************************//** | |
| 138 | + * @brief Assignment operator | |
| 139 | + * | |
| 140 | + * @param[in] model Spectral power law model. | |
| 141 | + * @return Spectral power law model. | |
| 142 | + ***************************************************************************/ | |
| 143 | +GModelSpectralComposite& GModelSpectralComposite::operator=(const GModelSpectralComposite& model) | |
| 144 | +{ | |
| 145 | + // Execute only if object is not identical | |
| 146 | + if (this != &model) { | |
| 147 | + | |
| 148 | + // Copy base class members | |
| 149 | + this->GModelSpectral::operator=(model); | |
| 150 | + | |
| 151 | + // Free members | |
| 152 | + free_members(); | |
| 153 | + | |
| 154 | + // Initialise members | |
| 155 | + init_members(); | |
| 156 | + | |
| 157 | + // Copy members | |
| 158 | + copy_members(model); | |
| 159 | + | |
| 160 | + } // endif: object was not identical | |
| 161 | + | |
| 162 | + // Return | |
| 163 | + return *this; | |
| 164 | +} | |
| 165 | + | |
| 166 | + | |
| 167 | +/*========================================================================== | |
| 168 | + = = | |
| 169 | + = Public methods = | |
| 170 | + = = | |
| 171 | + ==========================================================================*/ | |
| 172 | + | |
| 173 | +/***********************************************************************//** | |
| 174 | + * @brief Clear spectral power law model | |
| 175 | + ***************************************************************************/ | |
| 176 | +void GModelSpectralComposite::clear(void) | |
| 177 | +{ | |
| 178 | + // Free class members (base and derived classes, derived class first) | |
| 179 | + free_members(); | |
| 180 | + this->GModelSpectral::free_members(); | |
| 181 | + | |
| 182 | + // Initialise members | |
| 183 | + this->GModelSpectral::init_members(); | |
| 184 | + init_members(); | |
| 185 | + | |
| 186 | + // Return | |
| 187 | + return; | |
| 188 | +} | |
| 189 | + | |
| 190 | + | |
| 191 | +/***********************************************************************//** | |
| 192 | + * @brief Clone spectral power law model | |
| 193 | + * | |
| 194 | + * @return Pointer to deep copy of spectral power law model. | |
| 195 | + ***************************************************************************/ | |
| 196 | +GModelSpectralComposite* GModelSpectralComposite::clone(void) const | |
| 197 | +{ | |
| 198 | + // Clone spectral power law model | |
| 199 | + return new GModelSpectralComposite(*this); | |
| 200 | +} | |
| 201 | + | |
| 202 | + | |
| 203 | +/***********************************************************************//** | |
| 204 | + * @brief Evaluate function | |
| 205 | + * | |
| 206 | + * @param[in] srcEng True photon energy. | |
| 207 | + * @param[in] srcTime True photon arrival time. | |
| 208 | + * @param[in] gradients Compute gradients? | |
| 209 | + * @return Model value (ph/cm2/s/MeV). | |
| 210 | + * | |
| 211 | + * Evaluates | |
| 212 | + * | |
| 213 | + * \f[ | |
| 214 | + * \sum_{i=0}^{N} {M_{\rm i}}(\rm srcEng, srcTime) | |
| 215 | + * \f] | |
| 216 | + * | |
| 217 | + * where \f${M_{\rm i}}\f$ is the model evaluation of the i-th model | |
| 218 | + * | |
| 219 | + * If the @p gradients flag is true the method will also compute the | |
| 220 | + * partial derivatives of each model component with respect to the parameters using | |
| 221 | + * | |
| 222 | + * @todo The method expects that energy!=0. Otherwise Inf or NaN may result. | |
| 223 | + ***************************************************************************/ | |
| 224 | +double GModelSpectralComposite::eval(const GEnergy& srcEng, | |
| 225 | + const GTime& srcTime, | |
| 226 | + const bool& gradients) const | |
| 227 | +{ | |
| 228 | + // Initialise result | |
| 229 | + double value = 0.0; | |
| 230 | + | |
| 231 | + // Loop over model components | |
| 232 | + for (int i = 0; i < m_spectral.size(); ++i) { | |
| 233 | + | |
| 234 | + // Add model component | |
| 235 | + value += m_spectral[i]->eval(srcEng, srcTime, gradients); | |
| 236 | + | |
| 237 | + } // endfor: loop over model components | |
| 238 | + | |
| 239 | + // Compile option: Check for NaN/Inf | |
| 240 | + #if defined(G_NAN_CHECK) | |
| 241 | + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) { | |
| 242 | + std::cout << "*** ERROR: GModelSpectralComposite::eval"; | |
| 243 | + std::cout << "(srcEng=" << srcEng; | |
| 244 | + std::cout << ", srcTime=" << srcTime << "):"; | |
| 245 | + std::cout << " NaN/Inf encountered"; | |
| 246 | + std::cout << " (value=" << value; | |
| 247 | + std::cout << ")" << std::endl; | |
| 248 | + } | |
| 249 | + #endif | |
| 250 | + | |
| 251 | + // Return | |
| 252 | + return value; | |
| 253 | +} | |
| 254 | + | |
| 255 | + | |
| 256 | +/***********************************************************************//** | |
| 257 | + * @brief Returns model photon flux between [emin, emax] (units: ph/cm2/s) | |
| 258 | + * | |
| 259 | + * @param[in] emin Minimum photon energy. | |
| 260 | + * @param[in] emax Maximum photon energy. | |
| 261 | + * @return Photon flux (ph/cm2/s). | |
| 262 | + * | |
| 263 | + * Computes the sum of all photon fluxes of each individual component | |
| 264 | + * | |
| 265 | + ***************************************************************************/ | |
| 266 | +double GModelSpectralComposite::flux(const GEnergy& emin, | |
| 267 | + const GEnergy& emax) const | |
| 268 | +{ | |
| 269 | + // Initialise flux | |
| 270 | + double flux = 0.0; | |
| 271 | + | |
| 272 | + // Compute only if integration range is valid | |
| 273 | + if (emin < emax) { | |
| 274 | + | |
| 275 | + // Loop over model components | |
| 276 | + for (int i = 0; i < m_spectral.size(); ++i) { | |
| 277 | + | |
| 278 | + // Add model component | |
| 279 | + flux += m_spectral[i]->flux(emin, emax); | |
| 280 | + | |
| 281 | + } // endfor: loop over model components | |
| 282 | + | |
| 283 | + } // endif: integration range was valid | |
| 284 | + | |
| 285 | + // Return flux | |
| 286 | + return flux; | |
| 287 | +} | |
| 288 | + | |
| 289 | + | |
| 290 | +/***********************************************************************//** | |
| 291 | + * @brief Returns model energy flux between [emin, emax] (units: erg/cm2/s) | |
| 292 | + * | |
| 293 | + * @param[in] emin Minimum photon energy. | |
| 294 | + * @param[in] emax Maximum photon energy. | |
| 295 | + * @return Energy flux (erg/cm2/s). | |
| 296 | + * | |
| 297 | + * Computes the sum of all energy fluxes of each individual component | |
| 298 | + * | |
| 299 | + ***************************************************************************/ | |
| 300 | +double GModelSpectralComposite::eflux(const GEnergy& emin, | |
| 301 | + const GEnergy& emax) const | |
| 302 | +{ | |
| 303 | + // Initialise eflux | |
| 304 | + double eflux = 0.0; | |
| 305 | + | |
| 306 | + // Compute only if integration range is valid | |
| 307 | + if (emin < emax) { | |
| 308 | + | |
| 309 | + // Loop over model components | |
| 310 | + for (int i = 0; i < m_spectral.size(); ++i) { | |
| 311 | + | |
| 312 | + // Add model component | |
| 313 | + eflux += m_spectral[i]->flux(emin, emax); | |
| 314 | + | |
| 315 | + } // endfor: loop over model components | |
| 316 | + | |
| 317 | + } // endif: integration range was valid | |
| 318 | + | |
| 319 | + // Return flux | |
| 320 | + return eflux; | |
| 321 | +} | |
| 322 | + | |
| 323 | + | |
| 324 | +/***********************************************************************//** | |
| 325 | + * @brief Returns Monte Carlo energy between [emin, emax] | |
| 326 | + * | |
| 327 | + * @param[in] emin Minimum photon energy. | |
| 328 | + * @param[in] emax Maximum photon energy. | |
| 329 | + * @param[in] time True photon arrival time. | |
| 330 | + * @param[in,out] ran Random number generator. | |
| 331 | + * @return Energy. | |
| 332 | + * | |
| 333 | + * @exception GException::erange_invalid | |
| 334 | + * Energy range is invalid (emin < emax required). | |
| 335 | + * | |
| 336 | + * Returns Monte Carlo energy by randomly drawing from a power law. | |
| 337 | + ***************************************************************************/ | |
| 338 | +GEnergy GModelSpectralComposite::mc(const GEnergy& emin, | |
| 339 | + const GEnergy& emax, | |
| 340 | + const GTime& time, | |
| 341 | + GRan& ran) const | |
| 342 | +{ | |
| 343 | + // Throw an exception if energy range is invalid | |
| 344 | + if (emin >= emax) { | |
| 345 | + throw GException::erange_invalid(G_MC, emin.MeV(), emax.MeV(), | |
| 346 | + "Minimum energy < maximum energy required."); | |
| 347 | + } | |
| 348 | + | |
| 349 | + // Throw exception if model container is empty | |
| 350 | + if (m_spectral.size() == 0) { | |
| 351 | + throw GException::runtime_error(G_MC, | |
| 352 | + "Composite spectral model is empty. It is required to have at"\ | |
| 353 | + " least one spectral model to run simulations"); | |
| 354 | + } | |
| 355 | + | |
| 356 | + // Update MC cache | |
| 357 | + update_mc_cache(emin, emax); | |
| 358 | + | |
| 359 | + // Get random value | |
| 360 | + double u = ran.uniform(); | |
| 361 | + | |
| 362 | + // Initialise index of model to use for simulation | |
| 363 | + int index = 0; | |
| 364 | + | |
| 365 | + // Loop over spectral components and compute relative probabilites | |
| 366 | + for (int i = 0; i < m_mc_probs.size(); ++i) { | |
| 367 | + | |
| 368 | + if (u <= m_mc_probs[i]) { | |
| 369 | + index = i; | |
| 370 | + break; | |
| 371 | + } | |
| 372 | + } | |
| 373 | + | |
| 374 | + // Set energy | |
| 375 | + GEnergy energy = m_spectral[index]->mc(emin, emax, time, ran); | |
| 376 | + | |
| 377 | + // Return energy | |
| 378 | + return energy; | |
| 379 | +} | |
| 380 | + | |
| 381 | + | |
| 382 | +/***********************************************************************//** | |
| 383 | + * @brief Read model from XML element | |
| 384 | + * | |
| 385 | + * @param[in] xml XML element. | |
| 386 | + * | |
| 387 | + * Reads the spectral information from an XML element. | |
| 388 | + ***************************************************************************/ | |
| 389 | +void GModelSpectralComposite::read(const GXmlElement& xml) | |
| 390 | +{ | |
| 391 | + // Get number of spectral components | |
| 392 | + int n_spectrals = xml.elements("spectrum"); | |
| 393 | + | |
| 394 | + // Loop over spectral elements | |
| 395 | + for(int i = 0; i < n_spectrals; ++i) { | |
| 396 | + | |
| 397 | + // Get spectral XML element | |
| 398 | + const GXmlElement* spec = xml.element("spectrum", i); | |
| 399 | + | |
| 400 | + // Initialise a spectral registry object | |
| 401 | + GModelSpectralRegistry registry; | |
| 402 | + | |
| 403 | + // Read spectral model | |
| 404 | + GModelSpectral* ptr = registry.alloc(*spec); | |
| 405 | + | |
| 406 | + // Get component attribute from XML file | |
| 407 | + std::string component_name = spec->attribute("component"); | |
| 408 | + | |
| 409 | + // Append spectral component to container | |
| 410 | + append(*ptr, component_name); | |
| 411 | + | |
| 412 | + } // endfor: loop over components | |
| 413 | + | |
| 414 | + // Return | |
| 415 | + return; | |
| 416 | +} | |
| 417 | + | |
| 418 | + | |
| 419 | +/***********************************************************************//** | |
| 420 | + * @brief Write model into XML element | |
| 421 | + * | |
| 422 | + * @param[in] xml XML element. | |
| 423 | + * | |
| 424 | + * @exception GException::model_invalid_spectral | |
| 425 | + * Existing XML element is not of the expected type. | |
| 426 | + * | |
| 427 | + * Writes the spectral information into an XML element. | |
| 428 | + ***************************************************************************/ | |
| 429 | +void GModelSpectralComposite::write(GXmlElement& xml) const | |
| 430 | +{ | |
| 431 | + // Set model type | |
| 432 | + if (xml.attribute("type") == "") { | |
| 433 | + xml.attribute("type", type()); | |
| 434 | + } | |
| 435 | + | |
| 436 | + // Verify model type | |
| 437 | + if (xml.attribute("type") != type()) { | |
| 438 | + throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), | |
| 439 | + "Spectral model is not of type \""+type()+"\"."); | |
| 440 | + } | |
| 441 | + | |
| 442 | + // Loop over model components | |
| 443 | + for(int i = 0; i < m_spectral.size(); i++) { | |
| 444 | + | |
| 445 | + // Write spectral model | |
| 446 | + if (m_spectral[i] != NULL) { | |
| 447 | + | |
| 448 | + // Create new spectrum node | |
| 449 | + xml.append(GXmlElement("spectrum")); | |
| 450 | + | |
| 451 | + // Get new spectrum node | |
| 452 | + GXmlElement* spec = xml.element("spectrum", xml.elements("spectrum")-1); | |
| 453 | + | |
| 454 | + // Create temporary copy of the spectral model | |
| 455 | + // This is a kluge to write out the original parameters. | |
| 456 | + GModelSpectral* cpy = m_spectral[i]->clone(); | |
| 457 | + | |
| 458 | + // Loop over parameters of model | |
| 459 | + for (int j = 0; j < cpy->size(); ++j) { | |
| 460 | + | |
| 461 | + // Get model parameter and name | |
| 462 | + GModelPar& par = (*cpy)[j]; | |
| 463 | + std::string parname = par.name(); | |
| 464 | + | |
| 465 | + // Check if name contains colon | |
| 466 | + if (gammalib::contains(parname, ":")) { | |
| 467 | + | |
| 468 | + // Split at the colon | |
| 469 | + std::vector<std::string> splits = gammalib::split(parname, ":"); | |
| 470 | + | |
| 471 | + // Use second part of the string to recover original parameter name | |
| 472 | + par.name(splits[1]); | |
| 473 | + } | |
| 474 | + | |
| 475 | + } // endfor: loop over parameters | |
| 476 | + | |
| 477 | + // Write spectral component | |
| 478 | + cpy->write(*spec); | |
| 479 | + | |
| 480 | + // Add component name if previously available | |
| 481 | + if (m_components[i] != gammalib::str(i+1)) { | |
| 482 | + spec->attribute("component", m_components[i]); | |
| 483 | + } | |
| 484 | + | |
| 485 | + // Remove temporary copy | |
| 486 | + delete cpy; | |
| 487 | + | |
| 488 | + } // endif: spectral model was not NULL | |
| 489 | + | |
| 490 | + } // endfor: loop over model components | |
| 491 | + | |
| 492 | + // Return | |
| 493 | + return; | |
| 494 | +} | |
| 495 | + | |
| 496 | + | |
| 497 | +/***********************************************************************//** | |
| 498 | + * @brief Print powerlaw information | |
| 499 | + * | |
| 500 | + * @param[in] chatter Chattiness (defaults to NORMAL). | |
| 501 | + * @return String containing model information. | |
| 502 | + ***************************************************************************/ | |
| 503 | +std::string GModelSpectralComposite::print(const GChatter& chatter) const | |
| 504 | +{ | |
| 505 | + // Initialise result string | |
| 506 | + std::string result; | |
| 507 | + | |
| 508 | + // Continue only if chatter is not silent | |
| 509 | + if (chatter != SILENT) { | |
| 510 | + | |
| 511 | + // Append header | |
| 512 | + result.append("=== GModelSpectralComposite ==="); | |
| 513 | + | |
| 514 | + // Append information | |
| 515 | + result.append("\n"+gammalib::parformat("Number of components")); | |
| 516 | + result.append(gammalib::str(components())); | |
| 517 | + result.append("\n"+gammalib::parformat("Number of parameters")); | |
| 518 | + result.append(gammalib::str(size())); | |
| 519 | + | |
| 520 | + // Print parameter information | |
| 521 | + for (int i = 0; i < size(); ++i) { | |
| 522 | + result.append("\n"+m_pars[i]->print(chatter)); | |
| 523 | + } | |
| 524 | + | |
| 525 | + } // endif: chatter was not silent | |
| 526 | + | |
| 527 | + // Return result | |
| 528 | + return result; | |
| 529 | +} | |
| 530 | + | |
| 531 | + | |
| 532 | +/***********************************************************************//** | |
| 533 | + * @brief Append spectral component | |
| 534 | + * | |
| 535 | + * @param[in] spec Spectral model component | |
| 536 | + * @param[in] name Name of spectral component (can be empty) | |
| 537 | + * | |
| 538 | + * Appends a spectral component to the composite model | |
| 539 | + ***************************************************************************/ | |
| 540 | +void GModelSpectralComposite::append(const GModelSpectral& spec, const std::string& name) | |
| 541 | +{ | |
| 542 | + // Append model container | |
| 543 | + m_spectral.push_back(spec.clone()); | |
| 544 | + | |
| 545 | + // Get index of latest model | |
| 546 | + int index = m_spectral.size()-1; | |
| 547 | + | |
| 548 | + // Use model index if component name is empty | |
| 549 | + std::string component_name = !name.empty() ? name : gammalib::str(m_spectral.size()); | |
| 550 | + | |
| 551 | + // Check if component name is unique, throw exception if not | |
| 552 | + if (gammalib::contains(m_components, component_name)) { | |
| 553 | + std::string msg = | |
| 554 | + "Attempt to append component with name \""+component_name+"\" to composite" | |
| 555 | + " spectral model container, but a component with the same name exists already.\n" | |
| 556 | + "Every component in the container needs a unique name. On default the system will" | |
| 557 | + "increment an integer if no component name is provided."; | |
| 558 | + throw GException::invalid_value(G_APPEND, msg); | |
| 559 | + } | |
| 560 | + | |
| 561 | + // Add component name (for now simple number) | |
| 562 | + m_components.push_back(component_name); | |
| 563 | + | |
| 564 | + // Get number of spectral parameters from model | |
| 565 | + int npars = m_spectral[index]->size(); | |
| 566 | + | |
| 567 | + // Loop over model parameters | |
| 568 | + for (int ipar = 0; ipar < npars; ++ipar) { | |
| 569 | + | |
| 570 | + // Get model parameter | |
| 571 | + GModelPar* par = &(m_spectral[index]->operator[](ipar)); | |
| 572 | + | |
| 573 | + // Modify parameter name | |
| 574 | + par->name(component_name+":"+par->name()); | |
| 575 | + | |
| 576 | + // Append model parameter with new name to internal container | |
| 577 | + m_pars.push_back(par); | |
| 578 | + | |
| 579 | + } // endfor: loop over model parameters | |
| 580 | +} | |
| 581 | + | |
| 582 | + | |
| 583 | +/***********************************************************************//** | |
| 584 | + * @brief Returns spectral component element | |
| 585 | + * | |
| 586 | + * @param[in] index Index of spectral component. | |
| 587 | + * @return Spectral model. | |
| 588 | + * | |
| 589 | + * Returns a spectral component to the composite model | |
| 590 | + ***************************************************************************/ | |
| 591 | +const GModelSpectral* GModelSpectralComposite::component(const int& index) const | |
| 592 | +{ | |
| 593 | + // Check if index is in validity range | |
| 594 | + if (index >= m_spectral.size() || index < 0) { | |
| 595 | + throw GException::out_of_range(G_COMPONENT_INDEX, "Component Index", index, m_spectral.size(),""); | |
| 596 | + } | |
| 597 | + | |
| 598 | + // Return spectral component | |
| 599 | + return m_spectral[index]; | |
| 600 | + | |
| 601 | +} | |
| 602 | + | |
| 603 | + | |
| 604 | +/***********************************************************************//** | |
| 605 | + * @brief Returns pointer to specific spectral component | |
| 606 | + * | |
| 607 | + * @param[in] name Name of spectral component. | |
| 608 | + * @return Spectral model. | |
| 609 | + * | |
| 610 | + * Returns a spectral component of the composite model | |
| 611 | + ***************************************************************************/ | |
| 612 | +const GModelSpectral* GModelSpectralComposite::component(const std::string& name) const | |
| 613 | +{ | |
| 614 | + // Check if model name is found | |
| 615 | + int index = -1; | |
| 616 | + for(int i = 0; i < m_components.size(); ++i) { | |
| 617 | + if (m_components[i] == name) { | |
| 618 | + index = i; | |
| 619 | + break; | |
| 620 | + } | |
| 621 | + } | |
| 622 | + | |
| 623 | + // Check if component name was found | |
| 624 | + if (index == -1) { | |
| 625 | + throw GException::model_not_found(G_COMPONENT_NAME, name,""); | |
| 626 | + } | |
| 627 | + | |
| 628 | + // Return spectral component | |
| 629 | + return m_spectral[index]; | |
| 630 | + | |
| 631 | +} | |
| 632 | + | |
| 633 | +/*========================================================================== | |
| 634 | + = = | |
| 635 | + = Private methods = | |
| 636 | + = = | |
| 637 | + ==========================================================================*/ | |
| 638 | + | |
| 639 | +/***********************************************************************//** | |
| 640 | + * @brief Initialise class members | |
| 641 | + ***************************************************************************/ | |
| 642 | +void GModelSpectralComposite::init_members(void) | |
| 643 | +{ | |
| 644 | + // Initialise model type | |
| 645 | + m_type = "Composite"; | |
| 646 | + | |
| 647 | + // Clear spectral models | |
| 648 | + m_spectral.clear(); | |
| 649 | + m_components.clear(); | |
| 650 | + | |
| 651 | + // Clear MC cache | |
| 652 | + m_mc_probs.clear(); | |
| 653 | + m_mc_emin.clear(); | |
| 654 | + m_mc_emax.clear(); | |
| 655 | + m_mc_flux = 0.0; | |
| 656 | + | |
| 657 | + // Return | |
| 658 | + return; | |
| 659 | +} | |
| 660 | + | |
| 661 | + | |
| 662 | +/***********************************************************************//** | |
| 663 | + * @brief Copy class members | |
| 664 | + * | |
| 665 | + * @param[in] model GModelSpectralComposite members which should be copied. | |
| 666 | + ***************************************************************************/ | |
| 667 | +void GModelSpectralComposite::copy_members(const GModelSpectralComposite& model) | |
| 668 | +{ | |
| 669 | + // Copy members | |
| 670 | + m_type = model.m_type; | |
| 671 | + m_components = model.m_components; | |
| 672 | + | |
| 673 | + // Copy MC cache | |
| 674 | + m_mc_probs = model.m_mc_probs; | |
| 675 | + m_mc_emin = model.m_mc_emin; | |
| 676 | + m_mc_emax = model.m_mc_emax; | |
| 677 | + m_mc_flux = model.m_mc_flux; | |
| 678 | + | |
| 679 | + // Copy pointer(s) of spectral component | |
| 680 | + m_spectral.clear(); | |
| 681 | + | |
| 682 | + // Clear parameters and copy the pointers from the clone | |
| 683 | + m_pars.clear(); | |
| 684 | + for(int i = 0; i < model.components(); ++i) { | |
| 685 | + m_spectral.push_back(model.m_spectral[i]->clone()); | |
| 686 | + | |
| 687 | + // Retrieve spectral model | |
| 688 | + GModelSpectral* spec = m_spectral[i]; | |
| 689 | + | |
| 690 | + // Loop over parameters and store pointers | |
| 691 | + for (int ipar = 0; ipar < spec->size(); ++ipar) { | |
| 692 | + | |
| 693 | + // Get model parameter reference | |
| 694 | + GModelPar& par = spec->operator[](ipar); | |
| 695 | + | |
| 696 | + // Append model parameter pointer to internal container | |
| 697 | + m_pars.push_back(&par); | |
| 698 | + | |
| 699 | + } // endfor: loop over parameters | |
| 700 | + | |
| 701 | + } // endfor: loop over spectral models | |
| 702 | + | |
| 703 | + // Return | |
| 704 | + return; | |
| 705 | +} | |
| 706 | + | |
| 707 | + | |
| 708 | +/***********************************************************************//** | |
| 709 | + * @brief Delete class members | |
| 710 | + ***************************************************************************/ | |
| 711 | +void GModelSpectralComposite::free_members(void) | |
| 712 | +{ | |
| 713 | + // Free memory | |
| 714 | + for(int i = 0; i < m_spectral.size(); ++i) { | |
| 715 | + | |
| 716 | + // Delete component i | |
| 717 | + if (m_spectral[i] != NULL) delete m_spectral[i]; | |
| 718 | + | |
| 719 | + // Signal free pointer | |
| 720 | + m_spectral[i] = NULL; | |
| 721 | + } | |
| 722 | + | |
| 723 | + // Return | |
| 724 | + return; | |
| 725 | +} | |
| 726 | + | |
| 727 | + | |
| 728 | +/***********************************************************************//** | |
| 729 | + * @brief Update Monte Carlo pre computation cache | |
| 730 | + * | |
| 731 | + * @param[in] emin Minimum photon energy. | |
| 732 | + * @param[in] emax Maximum photon energy. | |
| 733 | + * | |
| 734 | + * Updates the precomputation cache for Monte Carlo simulations. | |
| 735 | + ***************************************************************************/ | |
| 736 | +void GModelSpectralComposite::update_mc_cache(const GEnergy& emin, | |
| 737 | + const GEnergy& emax) const | |
| 738 | + | |
| 739 | +{ | |
| 740 | + // Update cache if energy range has changed | |
| 741 | + if (emin != m_mc_emin || emax != m_mc_emax) { | |
| 742 | + m_mc_emin = emin; | |
| 743 | + m_mc_emax = emax; | |
| 744 | + m_mc_flux = flux(m_mc_emin, m_mc_emax); | |
| 745 | + | |
| 746 | + // Initialise sum and probabilites | |
| 747 | + double sum = 0.0; | |
| 748 | + m_mc_probs.clear(); | |
| 749 | + | |
| 750 | + // Loop over spectral components and compute relative probabilites | |
| 751 | + for (int i = 0; i < m_spectral.size(); ++i) { | |
| 752 | + | |
| 753 | + // Relative probability | |
| 754 | + double prob = m_spectral[i]->flux(emin, emax) / m_mc_flux; | |
| 755 | + | |
| 756 | + // Add probability | |
| 757 | + m_mc_probs.push_back(prob + sum); | |
| 758 | + | |
| 759 | + // Increment sum | |
| 760 | + sum += prob; | |
| 761 | + | |
| 762 | + } //endfor: looped over spectral components | |
| 763 | + | |
| 764 | + } // endif: emin and emax have changed | |
| 765 | + | |
| 766 | + // Return | |
| 767 | + return; | |
| 768 | +} | ... | ... |
src/model/Makefile.am
| ... | ... | @@ -45,6 +45,7 @@ sources = GModelPar.cpp \ |
| 45 | 45 | GModelSpatialDiffuseConst.cpp \ |
| 46 | 46 | GModelSpatialDiffuseCube.cpp \ |
| 47 | 47 | GModelSpatialDiffuseMap.cpp \ |
| 48 | + GModelSpatialComposite.cpp \ | |
| 48 | 49 | GModelSpectral.cpp \ |
| 49 | 50 | GModelSpectralRegistry.cpp \ |
| 50 | 51 | GModelSpectralBrokenPlaw.cpp \ |
| ... | ... | @@ -60,6 +61,7 @@ sources = GModelPar.cpp \ |
| 60 | 61 | GModelSpectralPlaw.cpp \ |
| 61 | 62 | GModelSpectralPlawPhotonFlux.cpp \ |
| 62 | 63 | GModelSpectralPlawEnergyFlux.cpp \ |
| 64 | + GModelSpectralComposite.cpp \ | |
| 63 | 65 | GModelTemporal.cpp \ |
| 64 | 66 | GModelTemporalRegistry.cpp \ |
| 65 | 67 | GModelTemporalConst.cpp \ | ... | ... |
src/obs/GResponse.cpp
| ... | ... | @@ -43,7 +43,6 @@ |
| 43 | 43 | #include "GEbounds.hpp" // will become obsolete |
| 44 | 44 | #include "GObservation.hpp" |
| 45 | 45 | #include "GModelSky.hpp" |
| 46 | -#include "GModelSpatialPointSource.hpp" | |
| 47 | 46 | |
| 48 | 47 | /* __ Method name definitions ____________________________________________ */ |
| 49 | 48 | #define G_IRF_RADIAL "GResponse::irf_radial(GEvent&, GSource&,"\ |
| ... | ... | @@ -322,9 +321,8 @@ double GResponse::eval_prob(const GModelSky& model, |
| 322 | 321 | |
| 323 | 322 | // Set source |
| 324 | 323 | GSource source(model.name(), model.spatial(), srcEng, srcTime); |
| 325 | - | |
| 326 | - // Get IRF value. This method returns the spatial component of the | |
| 327 | - // source model. | |
| 324 | + | |
| 325 | + // Compute IRF value | |
| 328 | 326 | double irf = this->irf(event, source, obs); |
| 329 | 327 | |
| 330 | 328 | // If required, apply instrument specific model scaling | ... | ... |
src/support/GTools.cpp
| ... | ... | @@ -1180,7 +1180,7 @@ bool gammalib::contains(const std::string& str, const std::string& substring) |
| 1180 | 1180 | bool result = false; |
| 1181 | 1181 | |
| 1182 | 1182 | // checks if substring is in str |
| 1183 | - if (str.find(substring) != std::string::npos){ | |
| 1183 | + if (str.find(substring) != std::string::npos) { | |
| 1184 | 1184 | result = true; |
| 1185 | 1185 | } |
| 1186 | 1186 | |
| ... | ... | @@ -1193,13 +1193,13 @@ bool gammalib::contains(const std::string& str, const std::string& substring) |
| 1193 | 1193 | * @brief Checks if a string is contained in a vector of strings |
| 1194 | 1194 | * |
| 1195 | 1195 | * @param[in] strings Vector of strings you want to search in. |
| 1196 | - * @param[in] string String you are looking for in strings. | |
| 1196 | + * @param[in] string string you are looking for in strings. | |
| 1197 | 1197 | * @return True if a string is contained a vector. |
| 1198 | 1198 | * |
| 1199 | 1199 | * Checks if a string is contained in a vector of strings |
| 1200 | 1200 | ***************************************************************************/ |
| 1201 | -bool gammalib::contains(const std::vector<std::string>& strings, | |
| 1202 | - const std::string& string) | |
| 1201 | +bool gammalib::contains(const std::vector<std::string> strings, | |
| 1202 | + const std::string& string) | |
| 1203 | 1203 | { |
| 1204 | 1204 | // Compute result |
| 1205 | 1205 | bool result = std::find(strings.begin(), strings.end(), string) != | ... | ... |
test/data/model_spatial_composite.xml
0 → 100644
| 1 | +<?xml version="1.0" standalone="no"?> | |
| 2 | +<source_library title="source library"> | |
| 3 | + <source name="Crab" type="CompositeSource"> | |
| 4 | + <spectrum type="PowerLaw"> | |
| 5 | + <parameter name="Prefactor" scale="1e-16" value="5.7" min="1e-07" max="1000.0" free="1"/> | |
| 6 | + <parameter name="Index" scale="-1" value="2.48" min="0.0" max="+5.0" free="1"/> | |
| 7 | + <parameter name="PivotEnergy" scale="1e6" value="0.3" min="0.01" max="1000.0" free="0"/> | |
| 8 | + </spectrum> | |
| 9 | + <spatialModel type="Composite"> | |
| 10 | + <spatialModel type="PointSource" component="PointSource"> | |
| 11 | + <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/> | |
| 12 | + <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/> | |
| 13 | + </spatialModel> | |
| 14 | + <spatialModel type="RadialGaussian"> | |
| 15 | + <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/> | |
| 16 | + <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/> | |
| 17 | + <parameter name="Sigma" scale="1.0" value="0.20" min="0.01" max="10" free="1"/> | |
| 18 | + </spatialModel> | |
| 19 | + </spatialModel> | |
| 20 | + </source> | |
| 21 | +</source_library> | ... | ... |
test/data/model_spectral_composite.xml
0 → 100644
| 1 | +<?xml version="1.0" standalone="no"?> | |
| 2 | +<source_library title="source library"> | |
| 3 | + <source name="Crab" type="PointSource"> | |
| 4 | + <spectrum type="Composite"> | |
| 5 | + <spectrum type="PowerLaw" component="SoftComponent"> | |
| 6 | + <parameter name="Prefactor" scale="1e-17" value="3" min="1e-07" max="1000.0" free="1"/> | |
| 7 | + <parameter name="Index" scale="-1" value="3.5" min="0.0" max="+5.0" free="1"/> | |
| 8 | + <parameter name="PivotEnergy" scale="1e6" value="1" min="0.01" max="1000.0" free="0"/> | |
| 9 | + </spectrum> | |
| 10 | + <spectrum type="PowerLaw" component="HardComponent"> | |
| 11 | + <parameter name="Prefactor" scale="1e-17" value="5" min="1e-07" max="1000.0" free="1"/> | |
| 12 | + <parameter name="Index" scale="-1" value="2.0" min="0.0" max="+5.0" free="1"/> | |
| 13 | + <parameter name="PivotEnergy" scale="1e6" value="1" min="0.01" max="1000.0" free="0"/> | |
| 14 | + </spectrum> | |
| 15 | + </spectrum> | |
| 16 | + <spatialModel type="PointSource"> | |
| 17 | + <parameter free="0" max="360" min="-360" name="RA" scale="1" value="83.6331" /> | |
| 18 | + <parameter free="0" max="90" min="-90" name="DEC" scale="1" value="22.0145" /> | |
| 19 | + </spatialModel> | |
| 20 | + </source> | |
| 21 | +</source_library> | ... | ... |
test/test_GModel.cpp
| ... | ... | @@ -67,6 +67,7 @@ void TestGModel::set(void) |
| 67 | 67 | m_xml_point_multiplicative = datadir + "/model_point_multiplicative.xml"; |
| 68 | 68 | m_xml_model_point_nodes = datadir + "/model_point_nodes.xml"; |
| 69 | 69 | m_xml_model_point_filefct = datadir + "/model_point_filefct.xml"; |
| 70 | + m_xml_model_spectral_composite = datadir + "/model_spectral_composite.xml"; | |
| 70 | 71 | m_xml_model_diffuse_const = datadir + "/model_diffuse_const.xml"; |
| 71 | 72 | m_xml_model_diffuse_cube = datadir + "/model_diffuse_cube.xml"; |
| 72 | 73 | m_xml_model_diffuse_map = datadir + "/model_diffuse_map.xml"; |
| ... | ... | @@ -75,6 +76,7 @@ void TestGModel::set(void) |
| 75 | 76 | m_xml_model_radial_shell = datadir + "/model_radial_shell.xml"; |
| 76 | 77 | m_xml_model_elliptical_disk = datadir + "/model_elliptical_disk.xml"; |
| 77 | 78 | m_xml_model_elliptical_gauss = datadir + "/model_elliptical_gauss.xml"; |
| 79 | + m_xml_model_spatial_composite = datadir + "/model_spatial_composite.xml"; | |
| 78 | 80 | |
| 79 | 81 | // Set legacy model definition XML files |
| 80 | 82 | m_xml_legacy_radial_disk = datadir + "/legacy_radial_disk.xml"; |
| ... | ... | @@ -116,6 +118,8 @@ void TestGModel::set(void) |
| 116 | 118 | "Test GModelSpatialDiffuseCube"); |
| 117 | 119 | append(static_cast<pfunction>(&TestGModel::test_diffuse_map), |
| 118 | 120 | "Test GModelSpatialDiffuseMap"); |
| 121 | + append(static_cast<pfunction>(&TestGModel::test_spatial_composite), | |
| 122 | + "Test GModelSpatialComposite"); | |
| 119 | 123 | append(static_cast<pfunction>(&TestGModel::test_spatial_model), |
| 120 | 124 | "Test spatial model XML I/O"); |
| 121 | 125 | |
| ... | ... | @@ -146,6 +150,8 @@ void TestGModel::set(void) |
| 146 | 150 | "Test GModelSpectralNodes"); |
| 147 | 151 | append(static_cast<pfunction>(&TestGModel::test_filefct), |
| 148 | 152 | "Test GModelSpectralFunc"); |
| 153 | + append(static_cast<pfunction>(&TestGModel::test_spectral_composite), | |
| 154 | + "Test GModelSpectralComposite"); | |
| 149 | 155 | append(static_cast<pfunction>(&TestGModel::test_spectral_model), |
| 150 | 156 | "Test spectral model XML I/O"); |
| 151 | 157 | |
| ... | ... | @@ -1402,6 +1408,49 @@ void TestGModel::test_elliptical_gauss(void) |
| 1402 | 1408 | } |
| 1403 | 1409 | |
| 1404 | 1410 | |
| 1411 | +/***********************************************************************//** | |
| 1412 | + * @brief Test GModelSpatialComposite class | |
| 1413 | + ***************************************************************************/ | |
| 1414 | +void TestGModel::test_spatial_composite(void) | |
| 1415 | +{ | |
| 1416 | + // Test void constructor | |
| 1417 | + GModelSpatialComposite model1; | |
| 1418 | + test_value(model1.type(), "Composite", "Check void model type"); | |
| 1419 | + | |
| 1420 | + // Set sky direction | |
| 1421 | + GSkyDir dir = GSkyDir(); | |
| 1422 | + dir.radec_deg(83.6331, 22.01); | |
| 1423 | + | |
| 1424 | + // Test append method | |
| 1425 | + model1.append(GModelSpatialPointSource(dir)); | |
| 1426 | + model1.append(GModelSpatialRadialGauss(dir, 0.2)); | |
| 1427 | + test_value(model1.components(), 2); | |
| 1428 | + test_value(model1.size(), 5); | |
| 1429 | + | |
| 1430 | + // Test XML constructor | |
| 1431 | + GXml xml(m_xml_model_spatial_composite); | |
| 1432 | + GXmlElement* element = xml.element(0)->element(0)->element("spatialModel", 0); | |
| 1433 | + GModelSpatialComposite model2(*element); | |
| 1434 | + test_value(model2.size(), 5); | |
| 1435 | + test_value(model2.type(), "Composite", "Check model type"); | |
| 1436 | + | |
| 1437 | + // Test access of individual parameters | |
| 1438 | + test_value(model2["2:RA"].value(), 83.6331); | |
| 1439 | + test_value(model2["2:DEC"].value(), 22.0145); | |
| 1440 | + test_value(model2["2:Sigma"].value(), 0.2); | |
| 1441 | + test_value(model2["PointSource:RA"].value(), 83.6331); | |
| 1442 | + test_value(model2["2:RA"].value(), 83.6331); | |
| 1443 | + model2["2:RA"].value(83.1331); | |
| 1444 | + test_value(model2["2:RA"].value(), 83.1331); | |
| 1445 | + model2["2:DEC"].value(22.51); | |
| 1446 | + test_value(model2["2:DEC"].value(), 22.51); | |
| 1447 | + model2["2:Sigma"].value(0.6); | |
| 1448 | + test_value(model2["2:Sigma"].value(), 0.6); | |
| 1449 | + | |
| 1450 | + // Exit test | |
| 1451 | + return; | |
| 1452 | +} | |
| 1453 | + | |
| 1405 | 1454 | |
| 1406 | 1455 | /***********************************************************************//** |
| 1407 | 1456 | * @brief Test GModelSpectralConst class |
| ... | ... | @@ -2194,6 +2243,51 @@ void TestGModel::test_filefct(void) |
| 2194 | 2243 | return; |
| 2195 | 2244 | } |
| 2196 | 2245 | |
| 2246 | +/***********************************************************************//** | |
| 2247 | + * @brief Test GModelSpectralComposite class | |
| 2248 | + ***************************************************************************/ | |
| 2249 | +void TestGModel::test_spectral_composite(void) | |
| 2250 | +{ | |
| 2251 | + // Test void constructor | |
| 2252 | + GModelSpectralComposite model1; | |
| 2253 | + test_value(model1.type(), "Composite", "Check void model type"); | |
| 2254 | + | |
| 2255 | + // Test append method | |
| 2256 | + model1.append(GModelSpectralPlaw(3e-17,-3.5, GEnergy(1, "TeV"))); | |
| 2257 | + model1.append(GModelSpectralPlaw(5e-17,-2.0, GEnergy(1, "TeV"))); | |
| 2258 | + test_value(model1.size(), 6); | |
| 2259 | + test_value(model1.components(), 2); | |
| 2260 | + test_value(model1.eval(GEnergy(1.0, "TeV")), 8.0e-17); | |
| 2261 | + | |
| 2262 | + // Test XML constructor | |
| 2263 | + GXml xml(m_xml_model_spectral_composite); | |
| 2264 | + GXmlElement* element = xml.element(0)->element(0)->element("spectrum", 0); | |
| 2265 | + GModelSpectralComposite model2(*element); | |
| 2266 | + test_value(model2.size(), 6); | |
| 2267 | + test_value(model2.components(), 2); | |
| 2268 | + test_value(model2.type(), "Composite", "Check model type"); | |
| 2269 | + | |
| 2270 | + // Test access of individual parameters | |
| 2271 | + test_value(model2["HardComponent:Prefactor"].value(), 5e-17); | |
| 2272 | + test_value(model2["HardComponent:Index"].value(), -2.0); | |
| 2273 | + test_value(model2["HardComponent:PivotEnergy"].value(), 1.0e6); | |
| 2274 | + | |
| 2275 | + // Test prefactor method | |
| 2276 | + model2["SoftComponent:Prefactor"].value(2.3e-16); | |
| 2277 | + test_value(model2["SoftComponent:Prefactor"].value(), 2.3e-16); | |
| 2278 | + | |
| 2279 | + // Test index method | |
| 2280 | + model2["SoftComponent:Index"].value(-2.6); | |
| 2281 | + test_value(model2["SoftComponent:Index"].value(), -2.6); | |
| 2282 | + | |
| 2283 | + // Test pivot method | |
| 2284 | + model2["SoftComponent:PivotEnergy"].value(0.5e6); | |
| 2285 | + test_value(model2["SoftComponent:PivotEnergy"].value(), 0.5e6); | |
| 2286 | + | |
| 2287 | + // Exit test | |
| 2288 | + return; | |
| 2289 | +} | |
| 2290 | + | |
| 2197 | 2291 | |
| 2198 | 2292 | /***********************************************************************//** |
| 2199 | 2293 | * @brief Test GModelTemporalConst class |
| ... | ... | @@ -2297,6 +2391,7 @@ void TestGModel::test_spectral_model(void) |
| 2297 | 2391 | test_xml_model("GModelSpectralLogParabola", m_xml_model_point_logparabola); |
| 2298 | 2392 | test_xml_model("GModelSpectralNodes", m_xml_model_point_nodes); |
| 2299 | 2393 | test_xml_model("GModelSpectralFunc", m_xml_model_point_filefct); |
| 2394 | + test_xml_model("GModelSpectralComposite", m_xml_model_spectral_composite); | |
| 2300 | 2395 | |
| 2301 | 2396 | // Return |
| 2302 | 2397 | return; | ... | ... |
test/test_GModel.hpp
| ... | ... | @@ -58,6 +58,7 @@ public: |
| 58 | 58 | void test_radial_shell(void); |
| 59 | 59 | void test_elliptical_disk(void); |
| 60 | 60 | void test_elliptical_gauss(void); |
| 61 | + void test_spatial_composite(void); | |
| 61 | 62 | void test_spatial_model(void); |
| 62 | 63 | void test_const(void); |
| 63 | 64 | void test_gauss(void); |
| ... | ... | @@ -72,6 +73,7 @@ public: |
| 72 | 73 | void test_multiplicative(void); |
| 73 | 74 | void test_nodes(void); |
| 74 | 75 | void test_filefct(void); |
| 76 | + void test_spectral_composite(void); | |
| 75 | 77 | void test_spectral_model(void); |
| 76 | 78 | void test_temp_const(void); |
| 77 | 79 | void test_model(void); |
| ... | ... | @@ -115,6 +117,7 @@ private: |
| 115 | 117 | std::string m_xml_point_multiplicative; |
| 116 | 118 | std::string m_xml_model_point_nodes; |
| 117 | 119 | std::string m_xml_model_point_filefct; |
| 120 | + std::string m_xml_model_spectral_composite; | |
| 118 | 121 | std::string m_xml_model_diffuse_const; |
| 119 | 122 | std::string m_xml_model_diffuse_cube; |
| 120 | 123 | std::string m_xml_model_diffuse_map; |
| ... | ... | @@ -123,6 +126,7 @@ private: |
| 123 | 126 | std::string m_xml_model_radial_shell; |
| 124 | 127 | std::string m_xml_model_elliptical_disk; |
| 125 | 128 | std::string m_xml_model_elliptical_gauss; |
| 129 | + std::string m_xml_model_spatial_composite; | |
| 126 | 130 | |
| 127 | 131 | // Legacy model definition XML files |
| 128 | 132 | std::string m_xml_legacy_radial_disk; | ... | ... |