Commit a949aa5a6d59e751794dff19d00d714bbe78da98

Authored by Michael Mayer
1 parent 548f06e8

Renamed PowerLaw2 into PowerLawPhotonFlux and added GModelSpectralPlawEnergyFlux…

… including docs and unit tests
doc/dev/maths/gammalib_maths.tex
... ... @@ -347,9 +347,9 @@ The parameter value gradients for the power law are given by
347 347  
348 348  
349 349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350   -\subsection{PowerLaw2}
  350 +\subsection{PowerLawPhotonFlux}
351 351  
352   -This flavour of the power law spectral model uses the integral flux $f$ within the
  352 +This flavour of the power law spectral model uses the integral photon flux $f$ within the
353 353 energy range $E_{\rm min}$ and $E_{\rm max}$ as free parameter instead of
354 354 the normalization $k$.
355 355 The integral flux $f$ is given by
... ... @@ -380,7 +380,7 @@ is obtained from Eq.~(\ref{eq:fluxint}).
380 380 Each of the 4 parameters is factorised into a scaling factor and a value, e.g.
381 381 $f=f_s f_v$ and $\gamma=\gamma_s \gamma_v$.
382 382 It is assumed that $E_{\rm min}$ and $E_{\rm max}$ are fixed parameters,
383   -and {\tt GModelSpectralPlaw2::eval\_gradients} returns valid gradients only for
  383 +and {\tt GModelSpectralPlawPhotonFlux::eval\_gradients} returns valid gradients only for
384 384 $f_v$ and $\gamma_v$.
385 385  
386 386 The flux value gradient $f_v$ is given by
... ... @@ -429,4 +429,88 @@ Note that for $\gamma \ne -1$
429 429 {\left( E_{\rm max}^{\gamma+1}-E_{\rm min}^{\gamma+1} \right)}
430 430 \end{equation}
431 431  
  432 +
  433 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  434 +\subsection{PowerLawEnergyFlux}
  435 +
  436 +This flavour of the power law spectral model uses the integral energy flux $F$ within the
  437 +energy range $E_{\rm min}$ and $E_{\rm max}$ as free parameter instead of
  438 +the normalization $k$.
  439 +The integral energy flux $F$ is given by
  440 +\begin{equation}
  441 +F = \int_{E_{\rm min}}^{E_{\rm max}} I(E) {\rm d}E
  442 +\label{eq:fluxint}
  443 +\end{equation}
  444 +The power law model is then defined by
  445 +\begin{equation}
  446 +I(E) = \tilde{k} \, E^{\gamma}
  447 +\end{equation}
  448 +where
  449 +\begin{equation}
  450 + \tilde{k} = \left \{
  451 + \begin{array}{l l}
  452 + \displaystyle
  453 + \frac{F}{\ln E_{\rm max} - \ln E_{\rm min}}
  454 + & \mbox{if $\gamma = -2$} \\
  455 + \\
  456 + \displaystyle
  457 + \frac{F (2+\gamma)}{E_{\rm max}^{\gamma+2}-E_{\rm min}^{\gamma+2}}
  458 + & \mbox{else}
  459 + \end{array}
  460 + \right .
  461 +\end{equation}
  462 +is obtained from Eq.~(\ref{eq:fluxenergy}).
  463 +
  464 +Each of the 4 parameters is factorised into a scaling factor and a value, e.g.
  465 +$F=F_s F_v$ and $\gamma=\gamma_s \gamma_v$.
  466 +It is assumed that $E_{\rm min}$ and $E_{\rm max}$ are fixed parameters,
  467 +and {\tt GModelSpectralPlawEnergyFlux::eval\_gradients} returns valid gradients only for
  468 +$F_v$ and $\gamma_v$.
  469 +
  470 +The flux value gradient $f_v$ is given by
  471 +\begin{equation}
  472 +\frac{\delta I}{\delta F_v} =
  473 + \frac{\delta I}{\delta F} \frac{\delta F}{\delta F_v} =
  474 + \frac{\delta I}{\delta F} F_s =
  475 + \frac{\delta \tilde{k}}{\delta F} \, E^{\gamma} F_s =
  476 + \frac{\tilde{k}}{F} \, E^{\gamma} F_s =
  477 + \frac{I(E)}{F} F_s =
  478 + \frac{I(E)}{F_v}
  479 +\end{equation}
  480 +
  481 +The index value gradient $\gamma_v$ is given by
  482 +\begin{equation}
  483 +\frac{\delta I}{\delta \gamma_v} =
  484 + \frac{\delta I}{\delta \gamma} \frac{\delta \gamma}{\delta \gamma_v} =
  485 + \frac{\delta I}{\delta \gamma} \gamma_s =
  486 + \left( \frac{\delta \tilde{k}}{\delta \gamma} \, E^{\gamma} + \tilde{k} \, E^{\gamma} \ln E \right) \gamma_s =
  487 + \left( \frac{1}{\tilde{k}} \frac{\delta \tilde{k}}{\delta \gamma} + \ln E \right) \tilde{k} E^{\gamma} \gamma_s =
  488 + \left( \frac{1}{\tilde{k}} \frac{\delta \tilde{k}}{\delta \gamma} + \ln E \right) I(E) \gamma_s
  489 +\end{equation}
  490 +where
  491 +\begin{equation}
  492 + \frac{\delta \tilde{k}}{\delta \gamma} = \left \{
  493 + \begin{array}{l l}
  494 + \displaystyle
  495 + 0 & \mbox{if $\gamma = -2$} \\
  496 + \\
  497 + \\
  498 + \displaystyle
  499 + \frac{F \left( E_{\rm max}^{\gamma+2}-E_{\rm min}^{\gamma+2} \right) -
  500 + F (1+\gamma) \left( E_{\rm max}^{\gamma+2} \ln E_{\rm max} -
  501 + E_{\rm min}^{\gamma+2} \ln E_{\rm min} \right)}
  502 + {\left( E_{\rm max}^{\gamma+2}-E_{\rm min}^{\gamma+2} \right)^2}
  503 + & \mbox{else}
  504 + \end{array}
  505 + \right .
  506 +\end{equation}
  507 +Note that for $\gamma \ne -2$
  508 +\begin{equation}
  509 +\frac{1}{\tilde{k}} \frac{\delta \tilde{k}}{\delta \gamma} =
  510 + \frac{1}{2+\gamma} -
  511 + \frac{\left( E_{\rm max}^{\gamma+2} \ln E_{\rm max} -
  512 + E_{\rm min}^{\gamma+2} \ln E_{\rm min} \right)}
  513 + {\left( E_{\rm max}^{\gamma+2}-E_{\rm min}^{\gamma+2} \right)}
  514 +\end{equation}
  515 +
432 516 \end{document}
... ...
doc/source/develop/coding/design.rst
... ... @@ -397,11 +397,11 @@ non-accessible class members need then to be declared ``mutable`` to avoid
397 397 compiler errors. Alternatively, the ``const_cast`` declaration can be used
398 398 to allow member modifications within a ``const`` method.
399 399  
400   -As example we show here part of the definition of :doxy:`GModelSpectralPlaw2`:
  400 +As example we show here part of the definition of :doxy:`GModelSpectralPlawPhotonFlux`:
401 401  
402 402 .. code-block:: cpp
403 403  
404   - class GModelSpectralPlaw2 : public GModelSpectral {
  404 + class GModelSpectralPlawPhotonFlux : public GModelSpectral {
405 405 public:
406 406 virtual double eval(const GEnergy& srcEng) const;
407 407 virtual void read(const GXmlElement& xml);
... ... @@ -430,11 +430,11 @@ As example we show here part of the definition of :doxy:`GModelSpectralPlaw2`:
430 430 mutable double m_last_g_index; //!< Last spectral index gradient
431 431  
432 432 This class has an internal cache for precomputation, which is
433   -potentially updated when :doxy:`GModelSpectralPlaw2::eval` is called. Here the corresponding code:
  433 +potentially updated when :doxy:`GModelSpectralPlawPhotonFlux::eval` is called. Here the corresponding code:
434 434  
435 435 .. code-block:: cpp
436 436  
437   - double GModelSpectralPlaw2::eval(const GEnergy& srcEng) const
  437 + double GModelSpectralPlawPhotonFlux::eval(const GEnergy& srcEng) const
438 438 {
439 439 // Update precomputed values
440 440 update(srcEng);
... ...
doc/source/users/user_manual/modules/model.rst
... ... @@ -445,17 +445,17 @@ format:
445 445 <parameter name="Scale" scale="1e6" value="0.3" min="0.01" max="1000.0" free="0"/>
446 446 </spectrum>
447 447  
448   -An alternative power law function is defined by the :doxy:`GModelSpectralPlaw2`
  448 +An alternative power law function is defined by the :doxy:`GModelSpectralPlawPhotonFlux`
449 449 class that uses the integral photon flux as parameter rather than the
450 450 Prefactor:
451 451  
452 452 .. math::
453   - \frac{dN}{dE} = \frac{N(\gamma+1)E^{\gamma}}
  453 + \frac{dN}{dE} = \frac{F_{\rm Ph}(\gamma+1)E^{\gamma}}
454 454 {E_{\rm max}^{\gamma+1} - E_{\rm min}^{\gamma+1}}
455 455  
456 456 where the parameters in the XML definition have the following mappings:
457 457  
458   -* :math:`N` = ``PhotonFlux``
  458 +* :math:`F_{\rm Ph}` = ``PhotonFlux``
459 459 * :math:`\gamma` = ``Index``
460 460 * :math:`E_{\rm min}` = ``LowerLimit``
461 461 * :math:`E_{\rm max}` = ``UpperLimit``
... ... @@ -487,12 +487,47 @@ format:
487 487 .. note::
488 488  
489 489 The UpperLimit and LowerLimit parameters are always treated as fixed and,
490   - as should be apparent from this definition, the flux given by the Integral
  490 + as should be apparent from this definition, the flux given by the PhotonFlux
491 491 parameter is over the range (LowerLimit, UpperLimit). Use of this model
492   - allows the errors on the integrated flux to be evaluated directly by
  492 + allows the errors on the integrated photon flux to be evaluated directly by
493 493 likelihood, obviating the need to propagate the errors if one is using
494 494 the PowerLaw form.
495 495  
  496 +Another alternative power law function is defined by the :doxy:`GModelSpectralPlawEnergyFlux`
  497 +class that uses the integral energy flux as parameter rather than the
  498 +Prefactor:
  499 +
  500 +.. math::
  501 + \frac{dN}{dE} = \frac{F_{\rm E}(\gamma+2)E^{\gamma}}
  502 + {E_{\rm max}^{\gamma+2} - E_{\rm min}^{\gamma+2}}
  503 +
  504 +where the parameters in the XML definition have the following mappings:
  505 +
  506 +* :math:`F_{\rm E}` = ``EnergyFlux``
  507 +* :math:`\gamma` = ``Index``
  508 +* :math:`E_{\rm min}` = ``LowerLimit``
  509 +* :math:`E_{\rm max}` = ``UpperLimit``
  510 +
  511 +The XML format for specifying a power law defined by the integral energy flux
  512 +is:
  513 +
  514 +.. code-block:: xml
  515 +
  516 + <spectrum type="PowerLaw">
  517 + <parameter scale="1e-07" name="EnergyFlux" min="1e-07" max="1000.0" value="1.0" free="1"/>
  518 + <parameter scale="1.0" name="Index" min="-5.0" max="+5.0" value="-2.0" free="1"/>
  519 + <parameter scale="1.0" name="LowerLimit" min="10.0" max="1000000.0" value="100.0" free="0"/>
  520 + <parameter scale="1.0" name="UpperLimit" min="10.0" max="1000000.0" value="500000.0" free="0"/>
  521 + </spectrum>
  522 +
  523 +.. note::
  524 +
  525 + The UpperLimit and LowerLimit parameters are always treated as fixed and,
  526 + as should be apparent from this definition, the flux given by the EnergyFlux
  527 + parameter is over the range (LowerLimit, UpperLimit). Use of this model
  528 + allows the errors on the integrated energy flux to be evaluated directly by
  529 + likelihood, obviating the need to propagate the errors if one is using
  530 + the PowerLaw form.
496 531  
497 532 Exponentially cut-off power law
498 533 ===============================
... ...
include/GModelSpectralPlaw2.hpp renamed to include/GModelSpectralPlawEnergyFlux.hpp
1 1 /***************************************************************************
2   - * GModelSpectralPlaw2.hpp - Spectral power law model class *
  2 + * GModelSpectralPlawEnergyFlux.hpp - Spectral power law model class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2011-2016 by Juergen Knoedlseder *
  4 + * copyright (C) 2016 by Michael Mayer *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -19,13 +19,13 @@
19 19 * *
20 20 ***************************************************************************/
21 21 /**
22   - * @file GModelSpectralPlaw2.hpp
23   - * @brief Flux normalized power law spectral model class interface definition
24   - * @author Juergen Knoedlseder
  22 + * @file GModelSpectralPlawEnergyFlux.hpp
  23 + * @brief Energy flux normalized power law spectral model class interface definition
  24 + * @author Michael Mayer
25 25 */
26 26  
27   -#ifndef GMODELSPECTRALPLAW2_HPP
28   -#define GMODELSPECTRALPLAW2_HPP
  27 +#ifndef GMODELSPECTRALPLAWENERGYFLUX_HPP
  28 +#define GMODELSPECTRALPLAWENERGYFLUX_HPP
29 29  
30 30 /* __ Includes ___________________________________________________________ */
31 31 #include <string>
... ... @@ -40,60 +40,60 @@ class GXmlElement;
40 40  
41 41  
42 42 /***********************************************************************//**
43   - * @class GModelSpectralPlaw2
  43 + * @class GModelSpectralPlawEnergyFlux
44 44 *
45   - * @brief Flux normalized power law spectral model class
  45 + * @brief Energy flux normalized power law spectral model class
46 46 *
47 47 * This class implements a power law spectrum. The model is defined by
48 48 *
49 49 * \f[
50   - * S_{\rm E}(E | t) = {\tt m\_integral}
  50 + * S_{\rm E}(E | t) = {\tt m\_energy\_flux}
51 51 * \frac{{\tt m\_index}+1}
52   - * {{\tt e\_max}^{{\tt m\_index}+1} -
53   - * {\tt e\_min}^{{\tt m\_index}+1}}
  52 + * {{\tt e\_max}^{{\tt m\_index}+2} -
  53 + * {\tt e\_min}^{{\tt m\_index}+2}}
54 54 * E^{\tt m\_index}
55 55 * \f]
56 56 *
57   - * for \f${\tt m\_index} \ne -1\f$ and
  57 + * for \f${\tt m\_index} \ne -2\f$ and
58 58 *
59 59 * \f[
60 60 * S_{\rm E}(E | t) =
61   - * \frac{{\tt m\_integral}}
  61 + * \frac{{\tt m\_energy\_flux}}
62 62 * {\log {\tt e\_max} - \log {\tt e\_min}}
63 63 * E^{\tt m\_index}
64 64 * \f]
65 65 *
66   - * for \f${\tt m\_index} = -1\f$, where
  66 + * for \f${\tt m\_index} = -2\f$, where
67 67 * - \f${\tt e\_min}\f$ is the minimum energy of an interval,
68 68 * - \f${\tt e\_max}\f$ is the maximum energy of an interval,
69   - * - \f${\tt m\_integral}\f$ is the integral flux between
  69 + * - \f${\tt m\_energy\_flux}\f$ is the energy flux between
70 70 * \f${\tt e\_min}\f$ and \f${\tt e\_max}\f$, and
71 71 * - \f${\tt m\_index}\f$ is the spectral index.
72 72 ***************************************************************************/
73   -class GModelSpectralPlaw2 : public GModelSpectral {
  73 +class GModelSpectralPlawEnergyFlux : public GModelSpectral {
74 74  
75 75 public:
76 76 // Constructors and destructors
77   - GModelSpectralPlaw2(void);
78   - GModelSpectralPlaw2(const std::string& type,
79   - const std::string& integral,
  77 + GModelSpectralPlawEnergyFlux(void);
  78 + GModelSpectralPlawEnergyFlux(const std::string& type,
  79 + const std::string& energy_flux,
80 80 const std::string& index,
81 81 const std::string& emin,
82 82 const std::string& emax);
83   - GModelSpectralPlaw2(const double& integral,
84   - const double& index,
85   - const GEnergy& emin,
86   - const GEnergy& emax);
87   - explicit GModelSpectralPlaw2(const GXmlElement& xml);
88   - GModelSpectralPlaw2(const GModelSpectralPlaw2& model);
89   - virtual ~GModelSpectralPlaw2(void);
  83 + explicit GModelSpectralPlawEnergyFlux(const double& eflux,
  84 + const double& index,
  85 + const GEnergy& emin,
  86 + const GEnergy& emax);
  87 + explicit GModelSpectralPlawEnergyFlux(const GXmlElement& xml);
  88 + GModelSpectralPlawEnergyFlux(const GModelSpectralPlawEnergyFlux& model);
  89 + virtual ~GModelSpectralPlawEnergyFlux(void);
90 90  
91 91 // Operators
92   - virtual GModelSpectralPlaw2& operator=(const GModelSpectralPlaw2& model);
  92 + virtual GModelSpectralPlawEnergyFlux& operator=(const GModelSpectralPlawEnergyFlux& model);
93 93  
94 94 // Implemented pure virtual base class methods
95 95 virtual void clear(void);
96   - virtual GModelSpectralPlaw2* clone(void) const;
  96 + virtual GModelSpectralPlawEnergyFlux* clone(void) const;
97 97 virtual std::string classname(void) const;
98 98 virtual std::string type(void) const;
99 99 virtual double eval(const GEnergy& srcEng,
... ... @@ -113,8 +113,8 @@ public:
113 113 virtual std::string print(const GChatter& chatter = NORMAL) const;
114 114  
115 115 // Other methods
116   - double integral(void) const;
117   - void integral(const double& integral);
  116 + double energy_flux(void) const;
  117 + void energy_flux(const double& energy_flux);
118 118 double index(void) const;
119 119 void index(const double& index);
120 120 GEnergy emin(void) const;
... ... @@ -125,45 +125,45 @@ public:
125 125 protected:
126 126 // Protected methods
127 127 void init_members(void);
128   - void copy_members(const GModelSpectralPlaw2& model);
  128 + void copy_members(const GModelSpectralPlawEnergyFlux& model);
129 129 void free_members(void);
130 130 void update(const GEnergy& srcEng) const;
131 131  
132 132 // Protected members
133   - std::string m_type; //!< Model type
134   - GModelPar m_integral; //!< Integral flux
135   - GModelPar m_index; //!< Spectral index
136   - GModelPar m_emin; //!< Lower energy limit (MeV)
137   - GModelPar m_emax; //!< Upper energy limit (MeV)
138   -
139   - // Cached members used for pre-computations
140   - mutable double m_log_emin; //!< Log(emin)
141   - mutable double m_log_emax; //!< Log(emax)
142   - mutable double m_pow_emin; //!< emin^(index+1)
143   - mutable double m_pow_emax; //!< emax^(index+1)
144   - mutable double m_norm; //!< Power-law normalization (for pivot energy 1 MeV)
145   - mutable double m_g_norm; //!< Power-law normalization gradient
146   - mutable double m_power; //!< Power-law factor
147   - mutable double m_last_integral; //!< Last integral flux
148   - mutable double m_last_index; //!< Last spectral index (MeV)
149   - mutable GEnergy m_last_emin; //!< Last lower energy limit
150   - mutable GEnergy m_last_emax; //!< Last upper energy limit
151   - mutable GEnergy m_last_energy; //!< Last source energy
152   - mutable double m_last_value; //!< Last function value
153   - mutable double m_last_g_integral; //!< Last integral flux gradient
154   - mutable double m_last_g_index; //!< Last spectral index gradient
  133 + std::string m_type; //!< Model type
  134 + GModelPar m_energy_flux; //!< Energy flux
  135 + GModelPar m_index; //!< Spectral index
  136 + GModelPar m_emin; //!< Lower energy limit (MeV)
  137 + GModelPar m_emax; //!< Upper energy limit (MeV)
  138 +
  139 + // Cached members used for pre-computations
  140 + mutable double m_log_emin; //!< Log(emin)
  141 + mutable double m_log_emax; //!< Log(emax)
  142 + mutable double m_pow_emin; //!< emin^(index+1)
  143 + mutable double m_pow_emax; //!< emax^(index+1)
  144 + mutable double m_norm; //!< Power-law normalization (for pivot energy 1 MeV)
  145 + mutable double m_g_norm; //!< Power-law normalization gradient
  146 + mutable double m_power; //!< Power-law factor
  147 + mutable double m_last_phflux; //!< Last energy flux
  148 + mutable double m_last_index; //!< Last spectral index (MeV)
  149 + mutable GEnergy m_last_emin; //!< Last lower energy limit
  150 + mutable GEnergy m_last_emax; //!< Last upper energy limit
  151 + mutable GEnergy m_last_energy; //!< Last source energy
  152 + mutable double m_last_value; //!< Last function value
  153 + mutable double m_last_g_phflux; //!< Last energy flux gradient
  154 + mutable double m_last_g_index; //!< Last spectral index gradient
155 155 };
156 156  
157 157  
158 158 /***********************************************************************//**
159 159 * @brief Return class name
160 160 *
161   - * @return String containing the class name ("GModelSpectralPlaw2").
  161 + * @return String containing the class name ("GModelSpectralPlawEnergyFlux").
162 162 ***************************************************************************/
163 163 inline
164   -std::string GModelSpectralPlaw2::classname(void) const
  164 +std::string GModelSpectralPlawEnergyFlux::classname(void) const
165 165 {
166   - return ("GModelSpectralPlaw2");
  166 + return ("GModelSpectralPlawEnergyFlux");
167 167 }
168 168  
169 169  
... ... @@ -175,43 +175,41 @@ std::string GModelSpectralPlaw2::classname(void) const
175 175 * Returns the type of the spectral power law model.
176 176 ***************************************************************************/
177 177 inline
178   -std::string GModelSpectralPlaw2::type(void) const
  178 +std::string GModelSpectralPlawEnergyFlux::type(void) const
179 179 {
180 180 return (m_type);
181 181 }
182 182  
183 183  
184 184 /***********************************************************************//**
185   - * @brief Return integral flux
  185 + * @brief Return energy flux
186 186 *
187   - * @return Integral flux (ph/cm2/s).
  187 + * @return Energy flux (erg/cm2/s).
188 188 *
189   - * Returns the integral flux.
  189 + * Returns the energy flux.
190 190 ***************************************************************************/
191 191 inline
192   -double GModelSpectralPlaw2::integral(void) const
  192 +double GModelSpectralPlawEnergyFlux::energy_flux(void) const
193 193 {
194   - return (m_integral.value());
  194 + return (m_energy_flux.value());
195 195 }
196 196  
197 197  
198 198 /***********************************************************************//**
199   - * @brief Set integral flux
  199 + * @brief Set energy flux
200 200 *
201   - * @param[in] integral Integral flux (ph/cm2/s).
  201 + * @param[in] energy_flux Energy flux (erg/cm2/s).
202 202 *
203   - * Sets the integral flux.
  203 + * Sets the energy flux.
204 204 ***************************************************************************/
205 205 inline
206   -void GModelSpectralPlaw2::integral(const double& integral)
  206 +void GModelSpectralPlawEnergyFlux::energy_flux(const double& energy_flux)
207 207 {
208   - m_integral.value(integral);
  208 + m_energy_flux.value(energy_flux);
209 209 return;
210 210 }
211 211  
212 212  
213   -
214   -
215 213 /***********************************************************************//**
216 214 * @brief Return power law index
217 215 *
... ... @@ -220,7 +218,7 @@ void GModelSpectralPlaw2::integral(const double&amp; integral)
220 218 * Returns the power law index.
221 219 ***************************************************************************/
222 220 inline
223   -double GModelSpectralPlaw2::index(void) const
  221 +double GModelSpectralPlawEnergyFlux::index(void) const
224 222 {
225 223 return (m_index.value());
226 224 }
... ... @@ -234,7 +232,7 @@ double GModelSpectralPlaw2::index(void) const
234 232 * Sets the power law index.
235 233 ***************************************************************************/
236 234 inline
237   -void GModelSpectralPlaw2::index(const double& index)
  235 +void GModelSpectralPlawEnergyFlux::index(const double& index)
238 236 {
239 237 m_index.value(index);
240 238 return;
... ... @@ -249,7 +247,7 @@ void GModelSpectralPlaw2::index(const double&amp; index)
249 247 * Returns the minimum energy.
250 248 ***************************************************************************/
251 249 inline
252   -GEnergy GModelSpectralPlaw2::emin(void) const
  250 +GEnergy GModelSpectralPlawEnergyFlux::emin(void) const
253 251 {
254 252 GEnergy energy;
255 253 energy.MeV(m_emin.value());
... ... @@ -265,7 +263,7 @@ GEnergy GModelSpectralPlaw2::emin(void) const
265 263 * Sets the minimum energy.
266 264 ***************************************************************************/
267 265 inline
268   -void GModelSpectralPlaw2::emin(const GEnergy& emin)
  266 +void GModelSpectralPlawEnergyFlux::emin(const GEnergy& emin)
269 267 {
270 268 m_emin.value(emin.MeV());
271 269 return;
... ... @@ -280,7 +278,7 @@ void GModelSpectralPlaw2::emin(const GEnergy&amp; emin)
280 278 * Returns the maximum energy.
281 279 ***************************************************************************/
282 280 inline
283   -GEnergy GModelSpectralPlaw2::emax(void) const
  281 +GEnergy GModelSpectralPlawEnergyFlux::emax(void) const
284 282 {
285 283 GEnergy energy;
286 284 energy.MeV(m_emax.value());
... ... @@ -296,10 +294,10 @@ GEnergy GModelSpectralPlaw2::emax(void) const
296 294 * Sets the maximum energy.
297 295 ***************************************************************************/
298 296 inline
299   -void GModelSpectralPlaw2::emax(const GEnergy& emax)
  297 +void GModelSpectralPlawEnergyFlux::emax(const GEnergy& emax)
300 298 {
301 299 m_emax.value(emax.MeV());
302 300 return;
303 301 }
304 302  
305   -#endif /* GMODELSPECTRALPLAW2_HPP */
  303 +#endif /* GMODELSPECTRALPLAWENERGYFLUX_HPP */
... ...
include/GModelSpectralPlawPhotonFlux.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * GModelSpectralPlawPhotonFlux.hpp - Spectral power law model class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2011-2016 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GModelSpectralPlawPhotonFlux.hpp
  23 + * @brief Flux normalized power law spectral model class interface definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef GMODELSPECTRALPLAWPHOTONFLUX_HPP
  28 +#define GMODELSPECTRALPLAWPHOTONFLUX_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 GModelSpectralPlawPhotonFlux
  44 + *
  45 + * @brief Photon flux normalized power law spectral model class
  46 + *
  47 + * This class implements a power law spectrum. The model is defined by
  48 + *
  49 + * \f[
  50 + * S_{\rm E}(E | t) = {\tt m\_photon\_flux}
  51 + * \frac{{\tt m\_index}+1}
  52 + * {{\tt e\_max}^{{\tt m\_index}+1} -
  53 + * {\tt e\_min}^{{\tt m\_index}+1}}
  54 + * E^{\tt m\_index}
  55 + * \f]
  56 + *
  57 + * for \f${\tt m\_index} \ne -1\f$ and
  58 + *
  59 + * \f[
  60 + * S_{\rm E}(E | t) =
  61 + * \frac{{\tt m\_photon\_flux}}
  62 + * {\log {\tt e\_max} - \log {\tt e\_min}}
  63 + * E^{\tt m\_index}
  64 + * \f]
  65 + *
  66 + * for \f${\tt m\_index} = -1\f$, where
  67 + * - \f${\tt e\_min}\f$ is the minimum energy of an interval,
  68 + * - \f${\tt e\_max}\f$ is the maximum energy of an interval,
  69 + * - \f${\tt m\_photon\_flux}\f$ is the photon flux between
  70 + * \f${\tt e\_min}\f$ and \f${\tt e\_max}\f$, and
  71 + * - \f${\tt m\_index}\f$ is the spectral index.
  72 + ***************************************************************************/
  73 +class GModelSpectralPlawPhotonFlux : public GModelSpectral {
  74 +
  75 +public:
  76 + // Constructors and destructors
  77 + GModelSpectralPlawPhotonFlux(void);
  78 + GModelSpectralPlawPhotonFlux(const std::string& type,
  79 + const std::string& integral,
  80 + const std::string& index,
  81 + const std::string& emin,
  82 + const std::string& emax);
  83 + GModelSpectralPlawPhotonFlux(const double& integral,
  84 + const double& index,
  85 + const GEnergy& emin,
  86 + const GEnergy& emax);
  87 + explicit GModelSpectralPlawPhotonFlux(const GXmlElement& xml);
  88 + GModelSpectralPlawPhotonFlux(const GModelSpectralPlawPhotonFlux& model);
  89 + virtual ~GModelSpectralPlawPhotonFlux(void);
  90 +
  91 + // Operators
  92 + virtual GModelSpectralPlawPhotonFlux& operator=(const GModelSpectralPlawPhotonFlux& model);
  93 +
  94 + // Implemented pure virtual base class methods
  95 + virtual void clear(void);
  96 + virtual GModelSpectralPlawPhotonFlux* clone(void) const;
  97 + virtual std::string classname(void) const;
  98 + virtual std::string type(void) const;
  99 + virtual double eval(const GEnergy& srcEng,
  100 + const GTime& srcTime = GTime()) const;
  101 + virtual double eval_gradients(const GEnergy& srcEng,
  102 + const GTime& srcTime = GTime());
  103 + virtual double flux(const GEnergy& emin,
  104 + const GEnergy& emax) const;
  105 + virtual double eflux(const GEnergy& emin,
  106 + const GEnergy& emax) const;
  107 + virtual GEnergy mc(const GEnergy& emin,
  108 + const GEnergy& emax,
  109 + const GTime& time,
  110 + GRan& ran) const;
  111 + virtual void read(const GXmlElement& xml);
  112 + virtual void write(GXmlElement& xml) const;
  113 + virtual std::string print(const GChatter& chatter = NORMAL) const;
  114 +
  115 + // Other methods
  116 + double photon_flux(void) const;
  117 + void photon_flux(const double& photon_flux);
  118 + double index(void) const;
  119 + void index(const double& index);
  120 + GEnergy emin(void) const;
  121 + void emin(const GEnergy& emin);
  122 + GEnergy emax(void) const;
  123 + void emax(const GEnergy& emax);
  124 +
  125 +protected:
  126 + // Protected methods
  127 + void init_members(void);
  128 + void copy_members(const GModelSpectralPlawPhotonFlux& model);
  129 + void free_members(void);
  130 + void update(const GEnergy& srcEng) const;
  131 +
  132 + // Protected members
  133 + std::string m_type; //!< Model type
  134 + GModelPar m_photon_flux; //!< Photon flux
  135 + GModelPar m_index; //!< Spectral index
  136 + GModelPar m_emin; //!< Lower energy limit (MeV)
  137 + GModelPar m_emax; //!< Upper energy limit (MeV)
  138 +
  139 + // Cached members used for pre-computations
  140 + mutable double m_log_emin; //!< Log(emin)
  141 + mutable double m_log_emax; //!< Log(emax)
  142 + mutable double m_pow_emin; //!< emin^(index+1)
  143 + mutable double m_pow_emax; //!< emax^(index+1)
  144 + mutable double m_norm; //!< Power-law normalization (for pivot energy 1 MeV)
  145 + mutable double m_g_norm; //!< Power-law normalization gradient
  146 + mutable double m_power; //!< Power-law factor
  147 + mutable double m_last_phflux; //!< Last photon flux
  148 + mutable double m_last_index; //!< Last spectral index (MeV)
  149 + mutable GEnergy m_last_emin; //!< Last lower energy limit
  150 + mutable GEnergy m_last_emax; //!< Last upper energy limit
  151 + mutable GEnergy m_last_energy; //!< Last source energy
  152 + mutable double m_last_value; //!< Last function value
  153 + mutable double m_last_g_phflux; //!< Last photon flux gradient
  154 + mutable double m_last_g_index; //!< Last spectral index gradient
  155 +};
  156 +
  157 +
  158 +/***********************************************************************//**
  159 + * @brief Return class name
  160 + *
  161 + * @return String containing the class name ("GModelSpectralPlawPhotonFlux").
  162 + ***************************************************************************/
  163 +inline
  164 +std::string GModelSpectralPlawPhotonFlux::classname(void) const
  165 +{
  166 + return ("GModelSpectralPlawPhotonFlux");
  167 +}
  168 +
  169 +
  170 +/***********************************************************************//**
  171 + * @brief Return model type
  172 + *
  173 + * @return Model type.
  174 + *
  175 + * Returns the type of the spectral power law model.
  176 + ***************************************************************************/
  177 +inline
  178 +std::string GModelSpectralPlawPhotonFlux::type(void) const
  179 +{
  180 + return (m_type);
  181 +}
  182 +
  183 +
  184 +/***********************************************************************//**
  185 + * @brief Return photon flux
  186 + *
  187 + * @return Photon flux (ph/cm2/s).
  188 + *
  189 + * Returns the photon flux.
  190 + ***************************************************************************/
  191 +inline
  192 +double GModelSpectralPlawPhotonFlux::photon_flux(void) const
  193 +{
  194 + return (m_photon_flux.value());
  195 +}
  196 +
  197 +
  198 +/***********************************************************************//**
  199 + * @brief Set photon flux
  200 + *
  201 + * @param[in] photon_flux Photon flux (ph/cm2/s).
  202 + *
  203 + * Sets the photon flux.
  204 + ***************************************************************************/
  205 +inline
  206 +void GModelSpectralPlawPhotonFlux::photon_flux(const double& photon_flux)
  207 +{
  208 + m_photon_flux.value(photon_flux);
  209 + return;
  210 +}
  211 +
  212 +
  213 +
  214 +
  215 +/***********************************************************************//**
  216 + * @brief Return power law index
  217 + *
  218 + * @return Power law index.
  219 + *
  220 + * Returns the power law index.
  221 + ***************************************************************************/
  222 +inline
  223 +double GModelSpectralPlawPhotonFlux::index(void) const
  224 +{
  225 + return (m_index.value());
  226 +}
  227 +
  228 +
  229 +/***********************************************************************//**
  230 + * @brief Set power law index
  231 + *
  232 + * @param[in] index Power law index.
  233 + *
  234 + * Sets the power law index.
  235 + ***************************************************************************/
  236 +inline
  237 +void GModelSpectralPlawPhotonFlux::index(const double& index)
  238 +{
  239 + m_index.value(index);
  240 + return;
  241 +}
  242 +
  243 +
  244 +/***********************************************************************//**
  245 + * @brief Return minimum energy
  246 + *
  247 + * @return Minimum energy.
  248 + *
  249 + * Returns the minimum energy.
  250 + ***************************************************************************/
  251 +inline
  252 +GEnergy GModelSpectralPlawPhotonFlux::emin(void) const
  253 +{
  254 + GEnergy energy;
  255 + energy.MeV(m_emin.value());
  256 + return energy;
  257 +}
  258 +
  259 +
  260 +/***********************************************************************//**
  261 + * @brief Set minimum energy
  262 + *
  263 + * @param[in] emin Minimum energy.
  264 + *
  265 + * Sets the minimum energy.
  266 + ***************************************************************************/
  267 +inline
  268 +void GModelSpectralPlawPhotonFlux::emin(const GEnergy& emin)
  269 +{
  270 + m_emin.value(emin.MeV());
  271 + return;
  272 +}
  273 +
  274 +
  275 +/***********************************************************************//**
  276 + * @brief Return maximum energy
  277 + *
  278 + * @return Maximum energy.
  279 + *
  280 + * Returns the maximum energy.
  281 + ***************************************************************************/
  282 +inline
  283 +GEnergy GModelSpectralPlawPhotonFlux::emax(void) const
  284 +{
  285 + GEnergy energy;
  286 + energy.MeV(m_emax.value());
  287 + return energy;
  288 +}
  289 +
  290 +
  291 +/***********************************************************************//**
  292 + * @brief Set maximum energy
  293 + *
  294 + * @param[in] emax Maximum energy.
  295 + *
  296 + * Sets the maximum energy.
  297 + ***************************************************************************/
  298 +inline
  299 +void GModelSpectralPlawPhotonFlux::emax(const GEnergy& emax)
  300 +{
  301 + m_emax.value(emax.MeV());
  302 + return;
  303 +}
  304 +
  305 +#endif /* GMODELSPECTRALPLAWPHOTONFLUX_HPP */
... ...
include/GammaLib.hpp
... ... @@ -215,7 +215,8 @@
215 215 #include "GModelSpectralLogParabola.hpp"
216 216 #include "GModelSpectralNodes.hpp"
217 217 #include "GModelSpectralPlaw.hpp"
218   -#include "GModelSpectralPlaw2.hpp"
  218 +#include "GModelSpectralPlawPhotonFlux.hpp"
  219 +#include "GModelSpectralPlawenergyFlux.hpp"
219 220 #include "GModelTemporal.hpp"
220 221 #include "GModelTemporalRegistry.hpp"
221 222 #include "GModelTemporalConst.hpp"
... ...
include/Makefile.am
... ... @@ -173,7 +173,8 @@ pkginclude_HEADERS = GammaLib.hpp \
173 173 GModelSpectralLogParabola.hpp \
174 174 GModelSpectralNodes.hpp \
175 175 GModelSpectralPlaw.hpp \
176   - GModelSpectralPlaw2.hpp \
  176 + GModelSpectralPlawPhotonFlux.hpp \
  177 + GModelSpectralPlawEnergyFlux.hpp \
177 178 GModelTemporal.hpp \
178 179 GModelTemporalRegistry.hpp \
179 180 GModelTemporalConst.hpp
... ...
pyext/GModelSpectralPlawEnergyFlux.i 0 → 100644
  1 +/***************************************************************************
  2 + * GModelSpectralPlawEnergyFlux.i - 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 GModelSpectralPlawEnergyFlux.i
  23 + * @brief Energy flux normalized power law spectral model class Python interface definition
  24 + * @author Michael Mayer
  25 + */
  26 +%{
  27 +/* Put headers and other declarations here that are needed for compilation */
  28 +#include "GModelSpectralPlawEnergyFlux.hpp"
  29 +%}
  30 +
  31 +
  32 +/***********************************************************************//**
  33 + * @class GModelSpectralPlawEnergyFlux
  34 + *
  35 + * @brief Flux normalized power law spectral model class
  36 + ***************************************************************************/
  37 +class GModelSpectralPlawEnergyFlux : public GModelSpectral {
  38 +public:
  39 + // Constructors and destructors
  40 + GModelSpectralPlawEnergyFlux(void);
  41 + GModelSpectralPlawEnergyFlux(const std::string& type,
  42 + const std::string& energy_flux,
  43 + const std::string& index,
  44 + const std::string& emin,
  45 + const std::string& emax);
  46 + explicit GModelSpectralPlawEnergyFlux(const double& energy_flux,
  47 + const double& index,
  48 + const GEnergy& emin,
  49 + const GEnergy& emax);
  50 + explicit GModelSpectralPlawEnergyFlux(const GXmlElement& xml);
  51 + GModelSpectralPlawEnergyFlux(const GModelSpectralPlawEnergyFlux& model);
  52 + virtual ~GModelSpectralPlawEnergyFlux(void);
  53 +
  54 + // Implemented pure virtual methods
  55 + virtual void clear(void);
  56 + virtual GModelSpectralPlawEnergyFlux* clone(void) const;
  57 + virtual std::string classname(void) const;
  58 + virtual std::string type(void) const;
  59 + virtual double eval(const GEnergy& srcEng,
  60 + const GTime& srcTime = GTime()) const;
  61 + virtual double eval_gradients(const GEnergy& srcEng,
  62 + const GTime& srcTime = GTime());
  63 + virtual double flux(const GEnergy& emin,
  64 + const GEnergy& emax) const;
  65 + virtual double eflux(const GEnergy& emin,
  66 + const GEnergy& emax) const;
  67 + virtual GEnergy mc(const GEnergy& emin,
  68 + const GEnergy& emax,
  69 + const GTime& time,
  70 + GRan& ran) const;
  71 + virtual void read(const GXmlElement& xml);
  72 + virtual void write(GXmlElement& xml) const;
  73 +
  74 + // Other methods
  75 + double energy_flux(void) const;
  76 + void energy_flux(const double& energy_flux);
  77 + double index(void) const;
  78 + void index(const double& index);
  79 + GEnergy emin(void) const;
  80 + void emin(const GEnergy& emin);
  81 + GEnergy emax(void) const;
  82 + void emax(const GEnergy& emax);
  83 +};
  84 +
  85 +
  86 +/***********************************************************************//**
  87 + * @brief GModelSpectralPlawEnergyFlux class extension
  88 + ***************************************************************************/
  89 +%extend GModelSpectralPlawEnergyFlux {
  90 + GModelSpectralPlawEnergyFlux copy() {
  91 + return (*self);
  92 + }
  93 +};
... ...
pyext/GModelSpectralPlaw2.i renamed to pyext/GModelSpectralPlawPhotonFlux.i
1 1 /***************************************************************************
2   - * GModelSpectralPlaw2.i - Spectral power law model class *
  2 + * GModelSpectralPlawPhotonFlux.i - Spectral power law model class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2011-2016 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -19,41 +19,41 @@
19 19 * *
20 20 ***************************************************************************/
21 21 /**
22   - * @file GModelSpectralPlaw2.i
  22 + * @file GModelSpectralPlawPhotonFlux.i
23 23 * @brief Flux normalized power law spectral model class Python interface definition
24 24 * @author Juergen Knoedlseder
25 25 */
26 26 %{
27 27 /* Put headers and other declarations here that are needed for compilation */
28   -#include "GModelSpectralPlaw2.hpp"
  28 +#include "GModelSpectralPlawPhotonFlux.hpp"
29 29 %}
30 30  
31 31  
32 32 /***********************************************************************//**
33   - * @class GModelSpectralPlaw2
  33 + * @class GModelSpectralPlawPhotonFlux
34 34 *
35 35 * @brief Flux normalized power law spectral model class
36 36 ***************************************************************************/
37   -class GModelSpectralPlaw2 : public GModelSpectral {
  37 +class GModelSpectralPlawPhotonFlux : public GModelSpectral {
38 38 public:
39 39 // Constructors and destructors
40   - GModelSpectralPlaw2(void);
41   - GModelSpectralPlaw2(const std::string& type,
42   - const std::string& integral,
  40 + GModelSpectralPlawPhotonFlux(void);
  41 + GModelSpectralPlawPhotonFlux(const std::string& type,
  42 + const std::string& photon_flux,
43 43 const std::string& index,
44 44 const std::string& emin,
45 45 const std::string& emax);
46   - GModelSpectralPlaw2(const double& integral,
  46 + GModelSpectralPlawPhotonFlux(const double& photon_flux,
47 47 const double& index,
48 48 const GEnergy& emin,
49 49 const GEnergy& emax);
50   - explicit GModelSpectralPlaw2(const GXmlElement& xml);
51   - GModelSpectralPlaw2(const GModelSpectralPlaw2& model);
52   - virtual ~GModelSpectralPlaw2(void);
  50 + explicit GModelSpectralPlawPhotonFlux(const GXmlElement& xml);
  51 + GModelSpectralPlawPhotonFlux(const GModelSpectralPlawPhotonFlux& model);
  52 + virtual ~GModelSpectralPlawPhotonFlux(void);
53 53  
54 54 // Implemented pure virtual methods
55 55 virtual void clear(void);
56   - virtual GModelSpectralPlaw2* clone(void) const;
  56 + virtual GModelSpectralPlawPhotonFlux* clone(void) const;
57 57 virtual std::string classname(void) const;
58 58 virtual std::string type(void) const;
59 59 virtual double eval(const GEnergy& srcEng,
... ... @@ -72,8 +72,8 @@ public:
72 72 virtual void write(GXmlElement& xml) const;
73 73  
74 74 // Other methods
75   - double integral(void) const;
76   - void integral(const double& integral);
  75 + double photon_flux(void) const;
  76 + void photon_flux(const double& photon_flux);
77 77 double index(void) const;
78 78 void index(const double& index);
79 79 GEnergy emin(void) const;
... ... @@ -84,10 +84,10 @@ public:
84 84  
85 85  
86 86 /***********************************************************************//**
87   - * @brief GModelSpectralPlaw2 class extension
  87 + * @brief GModelSpectralPlawPhotonFlux class extension
88 88 ***************************************************************************/
89   -%extend GModelSpectralPlaw2 {
90   - GModelSpectralPlaw2 copy() {
  89 +%extend GModelSpectralPlawPhotonFlux {
  90 + GModelSpectralPlawPhotonFlux copy() {
91 91 return (*self);
92 92 }
93 93 };
... ...
pyext/gammalib/model.i
... ... @@ -152,7 +152,8 @@
152 152 %include "GModelSpectralLogParabola.i"
153 153 %include "GModelSpectralNodes.i"
154 154 %include "GModelSpectralPlaw.i"
155   -%include "GModelSpectralPlaw2.i"
  155 +%include "GModelSpectralPlawPhotonFlux.i"
  156 +%include "GModelSpectralPlawEnergyFlux.i"
156 157 %include "GModelTemporal.i"
157 158 %include "GModelTemporalRegistry.i"
158 159 %include "GModelTemporalConst.i"
... ...
src/model/GModelSpectralPlawEnergyFlux.cpp 0 → 100644
  1 +/***************************************************************************
  2 + * GModelSpectralPlawEnergyFlux.cpp - 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 GModelSpectralPlawEnergyFlux.cpp
  23 + * @brief Energy flux normalized power law 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 "GMath.hpp"
  35 +#include "GRan.hpp"
  36 +#include "GModelSpectralPlawEnergyFlux.hpp"
  37 +#include "GModelSpectralRegistry.hpp"
  38 +
  39 +/* __ Constants __________________________________________________________ */
  40 +
  41 +/* __ Globals ____________________________________________________________ */
  42 +const GModelSpectralPlawEnergyFlux g_spectral_plaw_eflux_seed("PowerLaw",
  43 + "EnergyFlux",
  44 + "Index",
  45 + "LowerLimit",
  46 + "UpperLimit");
  47 +const GModelSpectralRegistry g_spectral_plaw_eflux_registry(&g_spectral_plaw_eflux_seed);
  48 +
  49 +/* __ Method name definitions ____________________________________________ */
  50 +#define G_FLUX "GModelSpectralPlawEnergyFlux::flux(GEnergy&, GEnergy&)"
  51 +#define G_EFLUX "GModelSpectralPlawEnergyFlux::eflux(GEnergy&, GEnergy&)"
  52 +#define G_MC "GModelSpectralPlawEnergyFlux::mc(GEnergy&, GEnergy&, GTime&, GRan&)"
  53 +#define G_READ "GModelSpectralPlawEnergyFlux::read(GXmlElement&)"
  54 +#define G_WRITE "GModelSpectralPlawEnergyFlux::write(GXmlElement&)"
  55 +
  56 +/* __ Macros _____________________________________________________________ */
  57 +
  58 +/* __ Coding definitions _________________________________________________ */
  59 +
  60 +/* __ Debug definitions __________________________________________________ */
  61 +
  62 +
  63 +/*==========================================================================
  64 + = =
  65 + = Constructors/destructors =
  66 + = =
  67 + ==========================================================================*/
  68 +
  69 +/***********************************************************************//**
  70 + * @brief Void constructor
  71 + ***************************************************************************/
  72 +GModelSpectralPlawEnergyFlux::GModelSpectralPlawEnergyFlux(void) : GModelSpectral()
  73 +{
  74 + // Initialise members
  75 + init_members();
  76 +
  77 + // Return
  78 + return;
  79 +}
  80 +
  81 +
  82 +/***********************************************************************//**
  83 + * @brief Model type and parameter name constructor
  84 + *
  85 + * @param[in] type Model type.
  86 + * @param[in] energy_flux Name of energy flux parameter.
  87 + * @param[in] index Name of index parameter.
  88 + * @param[in] emin Name of emin parameter.
  89 + * @param[in] emax Name of emax parameter.
  90 + ***************************************************************************/
  91 +GModelSpectralPlawEnergyFlux::GModelSpectralPlawEnergyFlux(const std::string& type,
  92 + const std::string& energy_flux,
  93 + const std::string& index,
  94 + const std::string& emin,
  95 + const std::string& emax) :
  96 + GModelSpectral()
  97 +{
  98 + // Initialise members
  99 + init_members();
  100 +
  101 + // Set model type
  102 + m_type = type;
  103 +
  104 + // Set parameter names
  105 + m_energy_flux.name(energy_flux);
  106 + m_index.name(index);
  107 + m_emin.name(emin);
  108 + m_emax.name(emax);
  109 +
  110 + // Return
  111 + return;
  112 +}
  113 +
  114 +
  115 +/***********************************************************************//**
  116 + * @brief Constructor
  117 + *
  118 + * @param[in] energy_flux Energy flux (erg/cm2/s).
  119 + * @param[in] index Power law index.
  120 + * @param[in] emin Minimum energy.
  121 + * @param[in] emax Maximum energy.
  122 + *
  123 + * Construct a spectral power law from the
  124 + * - energy flux (in erg/cm2/s),
  125 + * - spectral index,
  126 + * - minimum energy and
  127 + * - maximum energy.
  128 + ***************************************************************************/
  129 +GModelSpectralPlawEnergyFlux::GModelSpectralPlawEnergyFlux(const double& energy_flux,
  130 + const double& index,
  131 + const GEnergy& emin,
  132 + const GEnergy& emax) :
  133 + GModelSpectral()
  134 +{
  135 + // Initialise members
  136 + init_members();
  137 +
  138 + // Set parameters
  139 + m_energy_flux.value(energy_flux);
  140 + m_index.value(index);
  141 + m_emin.value(emin.MeV());
  142 + m_emax.value(emax.MeV());
  143 +
  144 + // Return
  145 + return;
  146 +}
  147 +
  148 +
  149 +/***********************************************************************//**
  150 + * @brief XML constructor
  151 + *
  152 + * @param[in] xml XML element.
  153 + *
  154 + * Constructs energy flux normalized power law spectral model by extracting
  155 + * information from an XML element. See the read() method for more
  156 + * information about the expected structure of the XML element.
  157 + ***************************************************************************/
  158 +GModelSpectralPlawEnergyFlux::GModelSpectralPlawEnergyFlux(const GXmlElement& xml) :
  159 + GModelSpectral()
  160 +{
  161 + // Initialise members
  162 + init_members();
  163 +
  164 + // Read information from XML element
  165 + read(xml);
  166 +
  167 + // Return
  168 + return;
  169 +}
  170 +
  171 +
  172 +/***********************************************************************//**
  173 + * @brief Copy constructor
  174 + *
  175 + * @param[in] model Spectral power law model.
  176 + ***************************************************************************/
  177 +GModelSpectralPlawEnergyFlux::GModelSpectralPlawEnergyFlux(const GModelSpectralPlawEnergyFlux& model) :
  178 + GModelSpectral(model)
  179 +{
  180 + // Initialise members
  181 + init_members();
  182 +
  183 + // Copy members
  184 + copy_members(model);
  185 +
  186 + // Return
  187 + return;
  188 +}
  189 +
  190 +
  191 +/***********************************************************************//**
  192 + * @brief Destructor
  193 + ***************************************************************************/
  194 +GModelSpectralPlawEnergyFlux::~GModelSpectralPlawEnergyFlux(void)
  195 +{
  196 + // Free members
  197 + free_members();
  198 +
  199 + // Return
  200 + return;
  201 +}
  202 +
  203 +
  204 +/*==========================================================================
  205 + = =
  206 + = Operators =
  207 + = =
  208 + ==========================================================================*/
  209 +
  210 +/***********************************************************************//**
  211 + * @brief Assignment operator
  212 + *
  213 + * @param[in] model Spectral power law model.
  214 + * @return Spectral power law model.
  215 + ***************************************************************************/
  216 +GModelSpectralPlawEnergyFlux& GModelSpectralPlawEnergyFlux::operator=(const GModelSpectralPlawEnergyFlux& model)
  217 +{
  218 + // Execute only if object is not identical
  219 + if (this != &model) {
  220 +
  221 + // Copy base class members
  222 + this->GModelSpectral::operator=(model);
  223 +
  224 + // Free members
  225 + free_members();
  226 +
  227 + // Initialise members
  228 + init_members();
  229 +
  230 + // Copy members
  231 + copy_members(model);
  232 +
  233 + } // endif: object was not identical
  234 +
  235 + // Return
  236 + return *this;
  237 +}
  238 +
  239 +
  240 +/*==========================================================================
  241 + = =
  242 + = Public methods =
  243 + = =
  244 + ==========================================================================*/
  245 +
  246 +/***********************************************************************//**
  247 + * @brief Clear power law model
  248 + ***************************************************************************/
  249 +void GModelSpectralPlawEnergyFlux::clear(void)
  250 +{
  251 + // Free class members (base and derived classes, derived class first)
  252 + free_members();
  253 + this->GModelSpectral::free_members();
  254 +
  255 + // Initialise members
  256 + this->GModelSpectral::init_members();
  257 + init_members();
  258 +
  259 + // Return
  260 + return;
  261 +}
  262 +
  263 +
  264 +/***********************************************************************//**
  265 + * @brief Clone power law model
  266 + *
  267 + * @return Pointer to deep copy of power law model
  268 + ***************************************************************************/
  269 +GModelSpectralPlawEnergyFlux* GModelSpectralPlawEnergyFlux::clone(void) const
  270 +{
  271 + // Clone power law model
  272 + return new GModelSpectralPlawEnergyFlux(*this);
  273 +}
  274 +
  275 +
  276 +/***********************************************************************//**
  277 + * @brief Evaluate function
  278 + *
  279 + * @param[in] srcEng True photon energy.
  280 + * @param[in] srcTime True photon arrival time.
  281 + * @return Model value (ph/cm2/s/MeV).
  282 + *
  283 + * Computes
  284 + *
  285 + * \f[
  286 + * S_{\rm E}(E | t) = {\tt m\_energy\_flux}
  287 + * \frac{{\tt m\_index}+2}
  288 + * {{\tt e\_max}^{{\tt m\_index}+2} -
  289 + * {\tt e\_min}^{{\tt m\_index}+2}}
  290 + * E^{\tt m\_index}
  291 + * \f]
  292 + *
  293 + * for \f${\tt m\_index} \ne -2\f$ and
  294 + *
  295 + * \f[
  296 + * S_{\rm E}(E | t) =
  297 + * \frac{{\tt m\_energy\_flux}}
  298 + * {\log {\tt e\_max} - \log {\tt e\_min}}
  299 + * E^{\tt m\_index}
  300 + * \f]
  301 + *
  302 + * for \f${\tt m\_index} = -2\f$, where
  303 + * - \f${\tt e\_min}\f$ is the minimum energy of an interval,
  304 + * - \f${\tt e\_max}\f$ is the maximum energy of an interval,
  305 + * - \f${\tt m\_energy\_flux}\f$ is the energy flux between
  306 + * \f${\tt e\_min}\f$ and \f${\tt e\_max}\f$, and
  307 + * - \f${\tt m\_index}\f$ is the spectral index.
  308 + ***************************************************************************/
  309 +double GModelSpectralPlawEnergyFlux::eval(const GEnergy& srcEng,
  310 + const GTime& srcTime) const
  311 +{
  312 + // Update precomputed values
  313 + update(srcEng);
  314 +
  315 + // Compute function value
  316 + double value = m_energy_flux.value() * gammalib::erg2MeV * m_norm * m_power;
  317 +
  318 + // Compile option: Check for NaN/Inf
  319 + #if defined(G_NAN_CHECK)
  320 + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
  321 + std::cout << "*** ERROR: GModelSpectralPlawEnergyFlux::eval";
  322 + std::cout << "(srcEng=" << srcEng;
  323 + std::cout << ", srcTime=" << srcTime << "):";
  324 + std::cout << " NaN/Inf encountered";
  325 + std::cout << " (value=" << value;
  326 + std::cout << ", energy flux=" << energy_flux();
  327 + std::cout << ", m_norm=" << m_norm;
  328 + std::cout << ", m_power=" << m_power;
  329 + std::cout << ")" << std::endl;
  330 + }
  331 + #endif
  332 +
  333 + // Return
  334 + return value;
  335 +}
  336 +
  337 +
  338 +/***********************************************************************//**
  339 + * @brief Evaluate function and gradients
  340 + *
  341 + * @param[in] srcEng True photon energy.
  342 + * @param[in] srcTime True photon arrival time.
  343 + * @return Model value (ph/cm2/s/MeV).
  344 + *
  345 + * Computes
  346 + *
  347 + * \f[
  348 + * S_{\rm E}(E | t) = {\tt m\_energy\_flux}
  349 + * \frac{{\tt m\_index}+2}
  350 + * {{\tt e\_max}^{{\tt m\_index}+2} -
  351 + * {\tt e\_min}^{{\tt m\_index}+2}}
  352 + * E^{\tt m\_index}
  353 + * \f]
  354 + *
  355 + * for \f${\tt m\_index} \ne -2\f$ and
  356 + *
  357 + * \f[
  358 + * S_{\rm E}(E | t) =
  359 + * \frac{{\tt m\_energy\_flux}}
  360 + * {\log {\tt e\_max} - \log {\tt e\_min}}
  361 + * E^{\tt m\_index}
  362 + * \f]
  363 + *
  364 + * for \f${\tt m\_index} = -2\f$, where
  365 + * - \f${\tt e\_min}\f$ is the minimum energy of an interval,
  366 + * - \f${\tt e\_max}\f$ is the maximum energy of an interval,
  367 + * - \f${\tt m\_energy\_flux}\f$ is the energy flux between
  368 + * \f${\tt e\_min}\f$ and \f${\tt e\_max}\f$, and
  369 + * - \f${\tt m\_index}\f$ is the spectral index.
  370 + *
  371 + * The method also evaluates the partial derivatives of the model with
  372 + * respect to the parameters using
  373 + *
  374 + * \f[
  375 + * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_energy\_flux}} =
  376 + * \frac{S_{\rm E}(E | t)}{{\tt m\_energy\_flux}}
  377 + * \f]
  378 + *
  379 + * \f[
  380 + * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_index}} =
  381 + * S_{\rm E}(E | t) \,
  382 + * \left( \frac{1}{{\tt m\_index}+2} -
  383 + * \frac{\log({\tt e\_max}) {\tt e\_max}^{{\tt m\_index}+2} -
  384 + * \log({\tt e\_min}) {\tt e\_min}^{{\tt m\_index}+2}}
  385 + * {{\tt e\_max}^{{\tt m\_index}+2} -
  386 + * {\tt e\_min}^{{\tt m\_index}+2}}
  387 + * + \ln(E) \right)
  388 + * \f]
  389 + *
  390 + * for \f${\tt m\_index} \ne -2\f$ and
  391 + *
  392 + * \f[
  393 + * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_index}} =
  394 + * S_{\rm E}(E | t) \, \ln(E)
  395 + * \f]
  396 + *
  397 + * for \f${\tt m\_index} = -2\f$.
  398 + *
  399 + * No partial derivatives are supported for the energy boundaries.
  400 + ***************************************************************************/
  401 +double GModelSpectralPlawEnergyFlux::eval_gradients(const GEnergy& srcEng,
  402 + const GTime& srcTime)
  403 +{
  404 + // Initialise gradients
  405 + double g_energy_flux = 0.0;
  406 + double g_index = 0.0;
  407 +
  408 + // Update precomputed values
  409 + update(srcEng);
  410 +
  411 + // Compute function value
  412 + double value = m_energy_flux.value() * gammalib::erg2MeV * m_norm * m_power;
  413 +
  414 + // Integral flux gradient
  415 + if (m_energy_flux.is_free() && m_energy_flux.factor_value() > 0.0) {
  416 + g_energy_flux = value / m_energy_flux.factor_value();
  417 + }
  418 +
  419 + // Index gradient
  420 + if (m_index.is_free()) {
  421 + g_index = value * (m_g_norm + gammalib::ln10 * srcEng.log10MeV()) *
  422 + m_index.scale();
  423 + }
  424 +
  425 + // Set gradients
  426 + m_energy_flux.factor_gradient(g_energy_flux);
  427 + m_index.factor_gradient(g_index);
  428 +
  429 + // Compile option: Check for NaN/Inf
  430 + #if defined(G_NAN_CHECK)
  431 + if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
  432 + std::cout << "*** ERROR: GModelSpectralPlawEnergyFlux::eval_gradients";
  433 + std::cout << "(srcEng=" << srcEng;
  434 + std::cout << ", srcTime=" << srcTime << "):";
  435 + std::cout << " NaN/Inf encountered";
  436 + std::cout << " (value=" << value;
  437 + std::cout << ", energy flux=" << energy_flux();
  438 + std::cout << ", m_norm=" << m_norm;
  439 + std::cout << ", m_power=" << m_power;
  440 + std::cout << ", g_energy_flux=" << g_energy_flux;
  441 + std::cout << ", g_index=" << g_index;
  442 + std::cout << ")" << std::endl;
  443 + }
  444 + #endif
  445 +
  446 + // Return
  447 + return value;
  448 +}
  449 +
  450 +
  451 +/***********************************************************************//**
  452 + * @brief Returns model photon flux between [emin, emax] (units: ph/cm2/s)
  453 + *
  454 + * @param[in] emin Minimum photon energy.
  455 + * @param[in] emax Minimum photon energy.
  456 + * @return Photon flux (ph/cm2/s).
  457 + *
  458 + * Computes
  459 + *
  460 + * \f[
  461 + * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) dE
  462 + * \f]
  463 + *
  464 + * where
  465 + * - [@p emin, @p emax] is an energy interval, and
  466 + * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
  467 + ***************************************************************************/
  468 +double GModelSpectralPlawEnergyFlux::flux(const GEnergy& emin,
  469 + const GEnergy& emax) const
  470 +{
  471 + // Initialise flux
  472 + double flux = 0.0;
  473 +
  474 + // Compute only if integration range is valid
  475 + if (emin < emax) {
  476 +
  477 + // Compute power law normalization
  478 + double norm = 0.0;
  479 + if (index() != -2.0) {
  480 + double gamma = m_index.value() + 2.0;
  481 + double pow_ref_emin = std::pow(this->emin().MeV(), gamma);
  482 + double pow_ref_emax = std::pow(this->emax().MeV(), gamma);
  483 + norm = m_energy_flux.value() * gammalib::erg2MeV * gamma / (pow_ref_emax - pow_ref_emin);
  484 + }
  485 + else {
  486 + double log_ref_emin = std::log(this->emin().MeV());
  487 + double log_ref_emax = std::log(this->emax().MeV());
  488 + norm = m_energy_flux.value() * gammalib::erg2MeV / (log_ref_emax - log_ref_emin);
  489 + }
  490 +
  491 + // Compute photon flux
  492 + if (index() != -1.0) {
  493 + double gamma = m_index.value() + 1.0;
  494 + double pow_emin = std::pow(emin.MeV(), gamma);
  495 + double pow_emax = std::pow(emax.MeV(), gamma);
  496 + flux = norm / gamma * (pow_emax - pow_emin);
  497 + }
  498 +
  499 + // Case B: Index is -1
  500 + else {
  501 + double log_emin = std::log(emin.MeV());
  502 + double log_emax = std::log(emax.MeV());
  503 + flux = norm * (log_emax - log_emin);
  504 + }
  505 +
  506 + } // endif: integration range was valid
  507 +
  508 + // Return flux
  509 + return flux;
  510 +}
  511 +
  512 +
  513 +/***********************************************************************//**
  514 + * @brief Returns model energy flux between [emin, emax] (units: erg/cm2/s)
  515 + *
  516 + * @param[in] emin Minimum photon energy.
  517 + * @param[in] emax Minimum photon energy.
  518 + * @return Energy flux (erg/cm2/s).
  519 + *
  520 + * Computes
  521 + *
  522 + * \f[
  523 + * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) E \, dE
  524 + * \f]
  525 + *
  526 + * where
  527 + * - [@p emin, @p emax] is an energy interval, and
  528 + * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
  529 + ***************************************************************************/
  530 +double GModelSpectralPlawEnergyFlux::eflux(const GEnergy& emin,
  531 + const GEnergy& emax) const
  532 +{
  533 + // Initialise flux
  534 + double eflux = 0.0;
  535 +
  536 + // Compute only if integration range is valid
  537 + if (emin < emax) {
  538 +
  539 + // Compute power law normalization
  540 + double norm;
  541 + if (index() != -2.0) {
  542 + double gamma = m_index.value() + 2.0;
  543 + double pow_ref_emin = std::pow(this->emin().MeV(), gamma);
  544 + double pow_ref_emax = std::pow(this->emax().MeV(), gamma);
  545 + double pow_emin = std::pow(emin.MeV(), gamma);
  546 + double pow_emax = std::pow(emax.MeV(), gamma);
  547 + double factor = (pow_emax - pow_emin) /
  548 + (pow_ref_emax - pow_ref_emin);
  549 + eflux = m_energy_flux.value() * factor;
  550 + }
  551 + else {
  552 + double log_emin = std::log(emin.MeV());
  553 + double log_emax = std::log(emax.MeV());
  554 + double log_ref_emin = std::log(this->emin().MeV());
  555 + double log_ref_emax = std::log(this->emax().MeV());
  556 + double factor = (log_emax - log_emin) /
  557 + (log_ref_emax - log_ref_emin);
  558 + eflux = m_energy_flux.value() * factor;
  559 + }
  560 +
  561 + } // endif: integration range was valid
  562 +
  563 + // Return flux
  564 + return eflux;
  565 +}
  566 +
  567 +
  568 +/***********************************************************************//**
  569 + * @brief Returns MC energy between [emin, emax]
  570 + *
  571 + * @param[in] emin Minimum photon energy.
  572 + * @param[in] emax Maximum photon energy.
  573 + * @param[in] time True photon arrival time.
  574 + * @param[in,out] ran Random number generator.
  575 + * @return Energy.
  576 + *
  577 + * @exception GException::erange_invalid
  578 + * Energy range is invalid (emin < emax required).
  579 + *
  580 + * Returns Monte Carlo energy by randomly drawing from a power law.
  581 + ***************************************************************************/
  582 +GEnergy GModelSpectralPlawEnergyFlux::mc(const GEnergy& emin,
  583 + const GEnergy& emax,
  584 + const GTime& time,
  585 + GRan& ran) const
  586 +{
  587 + // Throw an exception if energy range is invalid
  588 + if (emin >= emax) {
  589 + throw GException::erange_invalid(G_MC, emin.MeV(), emax.MeV(),
  590 + "Minimum energy < maximum energy required.");
  591 + }
  592 +
  593 + // Allocate energy
  594 + GEnergy energy;
  595 +
  596 + // Case A: Index is not -1
  597 + if (index() != -1.0) {
  598 + double exponent = index() + 1.0;
  599 + double e_max = std::pow(emax.MeV(), exponent);
  600 + double e_min = std::pow(emin.MeV(), exponent);
  601 + double u = ran.uniform();
  602 + double eng = (u > 0.0)
  603 + ? std::exp(std::log(u * (e_max - e_min) + e_min) / exponent)
  604 + : 0.0;
  605 + energy.MeV(eng);
  606 + }
  607 +
  608 + // Case B: Index is -1
  609 + else {
  610 + double e_max = std::log(emax.MeV());
  611 + double e_min = std::log(emin.MeV());
  612 + double u = ran.uniform();
  613 + double eng = std::exp(u * (e_max - e_min) + e_min);
  614 + energy.MeV(eng);
  615 + }
  616 +
  617 + // Return energy
  618 + return energy;
  619 +}
  620 +
  621 +
  622 +/***********************************************************************//**
  623 + * @brief Read model from XML element
  624 + *
  625 + * @param[in] xml XML element.
  626 + *
  627 + * Reads the spectral information from an XML element.
  628 + ***************************************************************************/
  629 +void GModelSpectralPlawEnergyFlux::read(const GXmlElement& xml)
  630 +{
  631 + // Get parameter pointers
  632 + const GXmlElement* eflux = gammalib::xml_get_par(G_READ, xml, m_energy_flux.name());
  633 + const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name());
  634 + const GXmlElement* emin = gammalib::xml_get_par(G_READ, xml, m_emin.name());
  635 + const GXmlElement* emax = gammalib::xml_get_par(G_READ, xml, m_emax.name());
  636 +
  637 + // Read parameters
  638 + m_energy_flux.read(*eflux);
  639 + m_index.read(*index);
  640 + m_emin.read(*emin);
  641 + m_emax.read(*emax);
  642 +
  643 + // Return
  644 + return;
  645 +}
  646 +
  647 +
  648 +/***********************************************************************//**
  649 + * @brief Write model into XML element
  650 + *
  651 + * @param[in] xml XML element.
  652 + *
  653 + * @exception GException::model_invalid_spectral
  654 + * Existing XML element is not of type "PowerLaw"
  655 + *
  656 + * Writes the spectral information into an XML element.
  657 + ***************************************************************************/
  658 +void GModelSpectralPlawEnergyFlux::write(GXmlElement& xml) const
  659 +{
  660 + // Set model type
  661 + if (xml.attribute("type") == "") {
  662 + xml.attribute("type", type());
  663 + }
  664 +
  665 + // Verify model type
  666 + if (xml.attribute("type") != type()) {
  667 + throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"),
  668 + "Spectral model is not of type \""+type()+"\".");
  669 + }
  670 +
  671 + // Get XML parameters
  672 + GXmlElement* eflux = gammalib::xml_need_par(G_WRITE, xml, m_energy_flux.name());
  673 + GXmlElement* index = gammalib::xml_need_par(G_WRITE, xml, m_index.name());
  674 + GXmlElement* emin = gammalib::xml_need_par(G_WRITE, xml, m_emin.name());
  675 + GXmlElement* emax = gammalib::xml_need_par(G_WRITE, xml, m_emax.name());
  676 +
  677 + // Write parameters
  678 + m_energy_flux.write(*eflux);
  679 + m_index.write(*index);
  680 + m_emin.write(*emin);
  681 + m_emax.write(*emax);
  682 +
  683 + // Return
  684 + return;
  685 +}
  686 +
  687 +
  688 +/***********************************************************************//**
  689 + * @brief Print power law information
  690 + *
  691 + * @param[in] chatter Chattiness (defaults to NORMAL).
  692 + * @return String containing power law information.
  693 + ***************************************************************************/
  694 +std::string GModelSpectralPlawEnergyFlux::print(const GChatter& chatter) const
  695 +{
  696 + // Initialise result string
  697 + std::string result;
  698 +
  699 + // Continue only if chatter is not silent
  700 + if (chatter != SILENT) {
  701 +
  702 + // Append header
  703 + result.append("=== GModelSpectralPlawEnergyFlux ===");
  704 +
  705 + // Append information
  706 + result.append("\n"+gammalib::parformat("Number of parameters"));
  707 + result.append(gammalib::str(size()));
  708 + for (int i = 0; i < size(); ++i) {
  709 + result.append("\n"+m_pars[i]->print(chatter));
  710 + }
  711 +
  712 + } // endif: chatter was not silent
  713 +
  714 + // Return result
  715 + return result;
  716 +}
  717 +
  718 +
  719 +/*==========================================================================
  720 + = =
  721 + = Private methods =
  722 + = =
  723 + ==========================================================================*/
  724 +
  725 +/***********************************************************************//**
  726 + * @brief Initialise class members
  727 + ***************************************************************************/
  728 +void GModelSpectralPlawEnergyFlux::init_members(void)
  729 +{
  730 + // Initialise model type
  731 + m_type = "PowerLaw";
  732 +
  733 + // Initialise energy flux
  734 + m_energy_flux.clear();
  735 + m_energy_flux.name("EnergyFlux");
  736 + m_energy_flux.unit("erg/cm2/s");
  737 + m_energy_flux.scale(1.0);
  738 + m_energy_flux.value(1.0); // default: 1.0
  739 + m_energy_flux.range(0.0, 10.0); // range: [0,10]
  740 + m_energy_flux.free();
  741 + m_energy_flux.gradient(0.0);
  742 + m_energy_flux.has_grad(true);
  743 +
  744 + // Initialise powerlaw index
  745 + m_index.clear();
  746 + m_index.name("Index");
  747 + m_index.scale(1.0);
  748 + m_index.value(-2.0); // default: -2.0
  749 + m_index.range(-10.0,+10.0); // range: [-10,+10]
  750 + m_index.free();
  751 + m_index.gradient(0.0);
  752 + m_index.has_grad(true);
  753 +
  754 + // Initialise lower limit
  755 + m_emin.clear();
  756 + m_emin.name("LowerLimit");
  757 + m_emin.unit("MeV");
  758 + m_emin.scale(1.0);
  759 + m_emin.value(100.0); // default: 100
  760 + m_emin.range(0.001, 1.0e15); // range: [0.001, 1e15]
  761 + m_emin.fix();
  762 + m_emin.gradient(0.0);
  763 + m_emin.has_grad(false);
  764 +
  765 + // Initialise upper limit
  766 + m_emax.clear();
  767 + m_emax.name("UpperLimit");
  768 + m_emax.unit("MeV");
  769 + m_emax.scale(1.0);
  770 + m_emax.value(500000.0); // default: 500000
  771 + m_emin.range(0.001, 1.0e15); // range: [0.001, 1e15]
  772 + m_emax.fix();
  773 + m_emax.gradient(0.0);
  774 + m_emax.has_grad(false);
  775 +
  776 + // Set parameter pointer(s)
  777 + m_pars.clear();
  778 + m_pars.push_back(&m_energy_flux);
  779 + m_pars.push_back(&m_index);
  780 + m_pars.push_back(&m_emin);
  781 + m_pars.push_back(&m_emax);
  782 +
  783 + // Initialise last parameters (for fast computation)
  784 + m_log_emin = 0.0;
  785 + m_log_emax = 0.0;
  786 + m_pow_emin = 0.0;
  787 + m_pow_emax = 0.0;
  788 + m_norm = 0.0;
  789 + m_power = 0.0;
  790 + m_last_index = 1000.0;
  791 + m_last_emin.MeV(0.0);
  792 + m_last_emax.MeV(0.0);
  793 + m_last_energy.MeV(0.0);
  794 + m_last_value = 0.0;
  795 + m_last_g_index = 0.0;
  796 +
  797 + // Return
  798 + return;
  799 +}
  800 +
  801 +
  802 +/***********************************************************************//**
  803 + * @brief Copy class members
  804 + *
  805 + * @param[in] model Spectral power law model.
  806 + ***************************************************************************/
  807 +void GModelSpectralPlawEnergyFlux::copy_members(const GModelSpectralPlawEnergyFlux& model)
  808 +{
  809 + // Copy members
  810 + m_type = model.m_type;
  811 + m_energy_flux = model.m_energy_flux;
  812 + m_index = model.m_index;
  813 + m_emin = model.m_emin;
  814 + m_emax = model.m_emax;
  815 +
  816 + // Set parameter pointer(s)
  817 + m_pars.clear();
  818 + m_pars.push_back(&m_energy_flux);
  819 + m_pars.push_back(&m_index);
  820 + m_pars.push_back(&m_emin);
  821 + m_pars.push_back(&m_emax);
  822 +
  823 + // Copy bookkeeping information
  824 + m_log_emin = model.m_log_emin;
  825 + m_log_emax = model.m_log_emax;
  826 + m_pow_emin = model.m_pow_emin;
  827 + m_pow_emax = model.m_pow_emax;
  828 + m_norm = model.m_norm;
  829 + m_power = model.m_power;
  830 + m_last_index = model.m_last_index;
  831 + m_last_emin = model.m_last_emin;
  832 + m_last_emax = model.m_last_emax;
  833 + m_last_energy = model.m_last_energy;
  834 + m_last_value = model.m_last_value;
  835 + m_last_g_index = model.m_last_g_index;
  836 +
  837 + // Return
  838 + return;
  839 +}
  840 +
  841 +
  842 +/***********************************************************************//**
  843 + * @brief Delete class members
  844 + ***************************************************************************/
  845 +void GModelSpectralPlawEnergyFlux::free_members(void)
  846 +{
  847 + // Return
  848 + return;
  849 +}
  850 +
  851 +
  852 +/***********************************************************************//**
  853 + * @brief Update precomputed values
  854 + *
  855 + * @param[in] srcEng Source energy
  856 + ***************************************************************************/
  857 +void GModelSpectralPlawEnergyFlux::update(const GEnergy& srcEng) const
  858 +{
  859 + // Compute index+1
  860 + double gamma = index() + 2.0;
  861 +
  862 + // Change in spectral index?
  863 + if (index() != m_last_index) {
  864 +
  865 + // Save actual spectral index
  866 + m_last_index = index();
  867 +
  868 + // Change in energy boundaries?
  869 + if (emin() != m_last_emin || emax() != m_last_emax) {
  870 + m_log_emin = std::log(emin().MeV());
  871 + m_last_emin = emin();
  872 + m_log_emax = std::log(emax().MeV());
  873 + m_last_emax = emax();
  874 + }
  875 +
  876 + // Compute normalization factors
  877 + if (gamma != 0.0) {
  878 + m_pow_emin = std::pow(emin().MeV(), gamma);
  879 + m_pow_emax = std::pow(emax().MeV(), gamma);
  880 + double d = m_pow_emax - m_pow_emin;
  881 + m_norm = gamma / d;
  882 + m_g_norm = 1.0/gamma -
  883 + (m_pow_emax*m_log_emax - m_pow_emin*m_log_emin)/d;
  884 + }
  885 + else {
  886 + m_norm = 1.0 / (m_log_emax - m_log_emin);
  887 + m_g_norm = 0.0;
  888 + }
  889 +
  890 + // Update power law factor
  891 + m_power = std::pow(srcEng.MeV(), index());
  892 + m_last_energy = srcEng;
  893 +
  894 + } // endif: change in spectral index
  895 +
  896 + // ... no change in spectral index
  897 + else {
  898 +
  899 + // Change in energy boundaries?
  900 + if (emin() != m_last_emin || emax() != m_last_emax) {
  901 +
  902 + // Update energy boundaries
  903 + m_log_emin = std::log(emin().MeV());
  904 + m_last_emin = emin();
  905 + m_log_emax = std::log(emax().MeV());
  906 + m_last_emax = emax();
  907 +
  908 + // Compute power law normalization
  909 + if (gamma != 0.0) {
  910 + m_pow_emin = std::pow(emin().MeV(), gamma);
  911 + m_pow_emax = std::pow(emax().MeV(), gamma);
  912 + double d = m_pow_emax - m_pow_emin;
  913 + m_norm = gamma / d;
  914 + m_g_norm = 1.0/gamma -
  915 + (m_pow_emax*m_log_emax - m_pow_emin*m_log_emin)/d;
  916 + }
  917 + else {
  918 + m_norm = 1.0 / (m_log_emax - m_log_emin);
  919 + m_g_norm = 0.0;
  920 + }
  921 +
  922 + } // endif: change in energy boundaries
  923 +
  924 + // Change in energy?
  925 + if (srcEng != m_last_energy) {
  926 + m_power = std::pow(srcEng.MeV(), index());
  927 + m_last_energy = srcEng;
  928 + }
  929 +
  930 + } // endelse: no change in spectral index
  931 +
  932 + // Return
  933 + return;
  934 +}
... ...
src/model/GModelSpectralPlaw2.cpp renamed to src/model/GModelSpectralPlawPhotonFlux.cpp
1 1 /***************************************************************************
2   - * GModelSpectralPlaw2.cpp - Spectral power law model class *
  2 + * GModelSpectralPlawPhotonFlux.cpp - Spectral power law model class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2010-2016 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -19,7 +19,7 @@
19 19 * *
20 20 ***************************************************************************/
21 21 /**
22   - * @file GModelSpectralPlaw2.cpp
  22 + * @file GModelSpectralPlawPhotonFlux.cpp
23 23 * @brief Flux normalized power law spectral model class implementation
24 24 * @author Juergen Knoedlseder
25 25 */
... ... @@ -33,33 +33,33 @@
33 33 #include "GTools.hpp"
34 34 #include "GMath.hpp"
35 35 #include "GRan.hpp"
36   -#include "GModelSpectralPlaw2.hpp"
  36 +#include "GModelSpectralPlawPhotonFlux.hpp"
37 37 #include "GModelSpectralRegistry.hpp"
38 38  
39 39 /* __ Constants __________________________________________________________ */
40 40  
41 41 /* __ Globals ____________________________________________________________ */
42   -const GModelSpectralPlaw2 g_spectral_plaw2_seed1("PowerLaw",
  42 +const GModelSpectralPlawPhotonFlux g_spectral_plaw_phflux_seed1("PowerLaw",
43 43 "PhotonFlux",
44 44 "Index",
45 45 "LowerLimit",
46 46 "UpperLimit");
47   -const GModelSpectralRegistry g_spectral_plaw2_registry1(&g_spectral_plaw2_seed1);
  47 +const GModelSpectralRegistry g_spectral_plaw_phflux_registry1(&g_spectral_plaw_phflux_seed1);
48 48 #if defined(G_LEGACY_XML_FORMAT)
49   -const GModelSpectralPlaw2 g_spectral_plaw2_seed2("PowerLaw2",
  49 +const GModelSpectralPlawPhotonFlux g_spectral_plaw_phflux_seed2("PowerLaw2",
50 50 "Integral",
51 51 "Index",
52 52 "LowerLimit",
53 53 "UpperLimit");
54   -const GModelSpectralRegistry g_spectral_plaw2_registry2(&g_spectral_plaw2_seed2);
  54 +const GModelSpectralRegistry g_spectral_plaw_phflux_registry2(&g_spectral_plaw_phflux_seed2);
55 55 #endif
56 56  
57 57 /* __ Method name definitions ____________________________________________ */
58   -#define G_FLUX "GModelSpectralPlaw2::flux(GEnergy&, GEnergy&)"
59   -#define G_EFLUX "GModelSpectralPlaw2::eflux(GEnergy&, GEnergy&)"
60   -#define G_MC "GModelSpectralPlaw2::mc(GEnergy&, GEnergy&, GTime&, GRan&)"
61   -#define G_READ "GModelSpectralPlaw2::read(GXmlElement&)"
62   -#define G_WRITE "GModelSpectralPlaw2::write(GXmlElement&)"
  58 +#define G_FLUX "GModelSpectralPlawPhotonFlux::flux(GEnergy&, GEnergy&)"
  59 +#define G_EFLUX "GModelSpectralPlawPhotonFlux::eflux(GEnergy&, GEnergy&)"
  60 +#define G_MC "GModelSpectralPlawPhotonFlux::mc(GEnergy&, GEnergy&, GTime&, GRan&)"
  61 +#define G_READ "GModelSpectralPlawPhotonFlux::read(GXmlElement&)"
  62 +#define G_WRITE "GModelSpectralPlawPhotonFlux::write(GXmlElement&)"
63 63  
64 64 /* __ Macros _____________________________________________________________ */
65 65  
... ... @@ -79,7 +79,7 @@ const GModelSpectralRegistry g_spectral_plaw2_registry2(&amp;g_spectral_plaw2_seed2)
79 79 *
80 80 * Constructs empty power law photon flux model.
81 81 ***************************************************************************/
82   -GModelSpectralPlaw2::GModelSpectralPlaw2(void) : GModelSpectral()
  82 +GModelSpectralPlawPhotonFlux::GModelSpectralPlawPhotonFlux(void) : GModelSpectral()
83 83 {
84 84 // Initialise members
85 85 init_members();
... ... @@ -93,13 +93,13 @@ GModelSpectralPlaw2::GModelSpectralPlaw2(void) : GModelSpectral()
93 93 * @brief Model type and parameter name constructor
94 94 *
95 95 * @param[in] type Model type.
96   - * @param[in] integral Name of integral parameter.
  96 + * @param[in] photon_flux Name of photon flux parameter.
97 97 * @param[in] index Name of index parameter.
98 98 * @param[in] emin Name of emin parameter.
99 99 * @param[in] emax Name of emax parameter.
100 100 ***************************************************************************/
101   -GModelSpectralPlaw2::GModelSpectralPlaw2(const std::string& type,
102   - const std::string& integral,
  101 +GModelSpectralPlawPhotonFlux::GModelSpectralPlawPhotonFlux(const std::string& type,
  102 + const std::string& photon_flux,
103 103 const std::string& index,
104 104 const std::string& emin,
105 105 const std::string& emax) :
... ... @@ -112,7 +112,7 @@ GModelSpectralPlaw2::GModelSpectralPlaw2(const std::string&amp; type,
112 112 m_type = type;
113 113  
114 114 // Set parameter names
115   - m_integral.name(integral);
  115 + m_photon_flux.name(photon_flux);
116 116 m_index.name(index);
117 117 m_emin.name(emin);
118 118 m_emax.name(emax);
... ... @@ -125,18 +125,18 @@ GModelSpectralPlaw2::GModelSpectralPlaw2(const std::string&amp; type,
125 125 /***********************************************************************//**
126 126 * @brief Constructor
127 127 *
128   - * @param[in] integral Integral flux (ph/cm2/s).
  128 + * @param[in] photon_flux Photon flux (ph/cm2/s).
129 129 * @param[in] index Power law index.
130 130 * @param[in] emin Minimum energy.
131 131 * @param[in] emax Maximum energy.
132 132 *
133 133 * Construct a spectral power law from the
134   - * - integral flux (in ph/cm2/s),
  134 + * - integral photon flux (in ph/cm2/s),
135 135 * - spectral index,
136 136 * - minimum energy and
137 137 * - maximum energy.
138 138 ***************************************************************************/
139   -GModelSpectralPlaw2::GModelSpectralPlaw2(const double& integral,
  139 +GModelSpectralPlawPhotonFlux::GModelSpectralPlawPhotonFlux(const double& photon_flux,
140 140 const double& index,
141 141 const GEnergy& emin,
142 142 const GEnergy& emax) :
... ... @@ -146,7 +146,7 @@ GModelSpectralPlaw2::GModelSpectralPlaw2(const double&amp; integral,
146 146 init_members();
147 147  
148 148 // Set parameters
149   - m_integral.value(integral);
  149 + m_photon_flux.value(photon_flux);
150 150 m_index.value(index);
151 151 m_emin.value(emin.MeV());
152 152 m_emax.value(emax.MeV());
... ... @@ -165,7 +165,7 @@ GModelSpectralPlaw2::GModelSpectralPlaw2(const double&amp; integral,
165 165 * information from an XML element. See the read() method for more
166 166 * information about the expected structure of the XML element.
167 167 ***************************************************************************/
168   -GModelSpectralPlaw2::GModelSpectralPlaw2(const GXmlElement& xml) :
  168 +GModelSpectralPlawPhotonFlux::GModelSpectralPlawPhotonFlux(const GXmlElement& xml) :
169 169 GModelSpectral()
170 170 {
171 171 // Initialise members
... ... @@ -184,7 +184,7 @@ GModelSpectralPlaw2::GModelSpectralPlaw2(const GXmlElement&amp; xml) :
184 184 *
185 185 * @param[in] model Spectral power law model.
186 186 ***************************************************************************/
187   -GModelSpectralPlaw2::GModelSpectralPlaw2(const GModelSpectralPlaw2& model) :
  187 +GModelSpectralPlawPhotonFlux::GModelSpectralPlawPhotonFlux(const GModelSpectralPlawPhotonFlux& model) :
188 188 GModelSpectral(model)
189 189 {
190 190 // Initialise members
... ... @@ -201,7 +201,7 @@ GModelSpectralPlaw2::GModelSpectralPlaw2(const GModelSpectralPlaw2&amp; model) :
201 201 /***********************************************************************//**
202 202 * @brief Destructor
203 203 ***************************************************************************/
204   -GModelSpectralPlaw2::~GModelSpectralPlaw2(void)
  204 +GModelSpectralPlawPhotonFlux::~GModelSpectralPlawPhotonFlux(void)
205 205 {
206 206 // Free members
207 207 free_members();
... ... @@ -223,7 +223,7 @@ GModelSpectralPlaw2::~GModelSpectralPlaw2(void)
223 223 * @param[in] model Spectral power law model.
224 224 * @return Spectral power law model.
225 225 ***************************************************************************/
226   -GModelSpectralPlaw2& GModelSpectralPlaw2::operator=(const GModelSpectralPlaw2& model)
  226 +GModelSpectralPlawPhotonFlux& GModelSpectralPlawPhotonFlux::operator=(const GModelSpectralPlawPhotonFlux& model)
227 227 {
228 228 // Execute only if object is not identical
229 229 if (this != &model) {
... ... @@ -256,7 +256,7 @@ GModelSpectralPlaw2&amp; GModelSpectralPlaw2::operator=(const GModelSpectralPlaw2&amp; m
256 256 /***********************************************************************//**
257 257 * @brief Clear power law model
258 258 ***************************************************************************/
259   -void GModelSpectralPlaw2::clear(void)
  259 +void GModelSpectralPlawPhotonFlux::clear(void)
260 260 {
261 261 // Free class members (base and derived classes, derived class first)
262 262 free_members();
... ... @@ -276,10 +276,10 @@ void GModelSpectralPlaw2::clear(void)
276 276 *
277 277 * @return Pointer to deep copy of power law model
278 278 ***************************************************************************/
279   -GModelSpectralPlaw2* GModelSpectralPlaw2::clone(void) const
  279 +GModelSpectralPlawPhotonFlux* GModelSpectralPlawPhotonFlux::clone(void) const
280 280 {
281 281 // Clone power law model
282   - return new GModelSpectralPlaw2(*this);
  282 + return new GModelSpectralPlawPhotonFlux(*this);
283 283 }
284 284  
285 285  
... ... @@ -293,7 +293,7 @@ GModelSpectralPlaw2* GModelSpectralPlaw2::clone(void) const
293 293 * Computes
294 294 *
295 295 * \f[
296   - * S_{\rm E}(E | t) = {\tt m\_integral}
  296 + * S_{\rm E}(E | t) = {\tt m\_photon\_flux}
297 297 * \frac{{\tt m\_index}+1}
298 298 * {{\tt e\_max}^{{\tt m\_index}+1} -
299 299 * {\tt e\_min}^{{\tt m\_index}+1}}
... ... @@ -304,7 +304,7 @@ GModelSpectralPlaw2* GModelSpectralPlaw2::clone(void) const
304 304 *
305 305 * \f[
306 306 * S_{\rm E}(E | t) =
307   - * \frac{{\tt m\_integral}}
  307 + * \frac{{\tt m\_photon\_flux}}
308 308 * {\log {\tt e\_max} - \log {\tt e\_min}}
309 309 * E^{\tt m\_index}
310 310 * \f]
... ... @@ -312,28 +312,28 @@ GModelSpectralPlaw2* GModelSpectralPlaw2::clone(void) const
312 312 * for \f${\tt m\_index} = -1\f$, where
313 313 * - \f${\tt e\_min}\f$ is the minimum energy of an interval,
314 314 * - \f${\tt e\_max}\f$ is the maximum energy of an interval,
315   - * - \f${\tt m\_integral}\f$ is the integral flux between
  315 + * - \f${\tt m\_photon\_flux}\f$ is the photon flux flux between
316 316 * \f${\tt e\_min}\f$ and \f${\tt e\_max}\f$, and
317 317 * - \f${\tt m\_index}\f$ is the spectral index.
318 318 ***************************************************************************/
319   -double GModelSpectralPlaw2::eval(const GEnergy& srcEng,
  319 +double GModelSpectralPlawPhotonFlux::eval(const GEnergy& srcEng,
320 320 const GTime& srcTime) const
321 321 {
322 322 // Update precomputed values
323 323 update(srcEng);
324 324  
325 325 // Compute function value
326   - double value = m_integral.value() * m_norm * m_power;
  326 + double value = m_photon_flux.value() * m_norm * m_power;
327 327  
328 328 // Compile option: Check for NaN/Inf
329 329 #if defined(G_NAN_CHECK)
330 330 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
331   - std::cout << "*** ERROR: GModelSpectralPlaw2::eval";
  331 + std::cout << "*** ERROR: GModelSpectralPlawPhotonFlux::eval";
332 332 std::cout << "(srcEng=" << srcEng;
333 333 std::cout << ", srcTime=" << srcTime << "):";
334 334 std::cout << " NaN/Inf encountered";
335 335 std::cout << " (value=" << value;
336   - std::cout << ", integral=" << integral();
  336 + std::cout << ", photon_flux=" << photon_flux();
337 337 std::cout << ", m_norm=" << m_norm;
338 338 std::cout << ", m_power=" << m_power;
339 339 std::cout << ")" << std::endl;
... ... @@ -355,7 +355,7 @@ double GModelSpectralPlaw2::eval(const GEnergy&amp; srcEng,
355 355 * Computes
356 356 *
357 357 * \f[
358   - * S_{\rm E}(E | t) = {\tt m\_integral}
  358 + * S_{\rm E}(E | t) = {\tt m\_photon\_flux}
359 359 * \frac{{\tt m\_index}+1}
360 360 * {{\tt e\_max}^{{\tt m\_index}+1} -
361 361 * {\tt e\_min}^{{\tt m\_index}+1}}
... ... @@ -366,7 +366,7 @@ double GModelSpectralPlaw2::eval(const GEnergy&amp; srcEng,
366 366 *
367 367 * \f[
368 368 * S_{\rm E}(E | t) =
369   - * \frac{{\tt m\_integral}}
  369 + * \frac{{\ttm\_photon\_flux}}
370 370 * {\log {\tt e\_max} - \log {\tt e\_min}}
371 371 * E^{\tt m\_index}
372 372 * \f]
... ... @@ -374,7 +374,7 @@ double GModelSpectralPlaw2::eval(const GEnergy&amp; srcEng,
374 374 * for \f${\tt m\_index} = -1\f$, where
375 375 * - \f${\tt e\_min}\f$ is the minimum energy of an interval,
376 376 * - \f${\tt e\_max}\f$ is the maximum energy of an interval,
377   - * - \f${\tt m\_integral}\f$ is the integral flux between
  377 + * - \f${\tt m\_photon\_flux}\f$ is the photon flux between
378 378 * \f${\tt e\_min}\f$ and \f${\tt e\_max}\f$, and
379 379 * - \f${\tt m\_index}\f$ is the spectral index.
380 380 *
... ... @@ -382,8 +382,8 @@ double GModelSpectralPlaw2::eval(const GEnergy&amp; srcEng,
382 382 * respect to the parameters using
383 383 *
384 384 * \f[
385   - * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_integral}} =
386   - * \frac{S_{\rm E}(E | t)}{{\tt m\_integral}}
  385 + * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_photon\_flux}} =
  386 + * \frac{S_{\rm E}(E | t)}{{\tt m\_photon\_flux}}
387 387 * \f]
388 388 *
389 389 * \f[
... ... @@ -408,22 +408,22 @@ double GModelSpectralPlaw2::eval(const GEnergy&amp; srcEng,
408 408 *
409 409 * No partial derivatives are supported for the energy boundaries.
410 410 ***************************************************************************/
411   -double GModelSpectralPlaw2::eval_gradients(const GEnergy& srcEng,
  411 +double GModelSpectralPlawPhotonFlux::eval_gradients(const GEnergy& srcEng,
412 412 const GTime& srcTime)
413 413 {
414 414 // Initialise gradients
415   - double g_integral = 0.0;
  415 + double g_photon_flux = 0.0;
416 416 double g_index = 0.0;
417 417  
418 418 // Update precomputed values
419 419 update(srcEng);
420 420  
421 421 // Compute function value
422   - double value = m_integral.value() * m_norm * m_power;
  422 + double value = m_photon_flux.value() * m_norm * m_power;
423 423  
424   - // Integral flux gradient
425   - if (m_integral.is_free() && m_integral.factor_value() > 0.0) {
426   - g_integral = value / m_integral.factor_value();
  424 + // Photon flux gradient
  425 + if (m_photon_flux.is_free() && m_photon_flux.factor_value() > 0.0) {
  426 + g_photon_flux = value / m_photon_flux.factor_value();
427 427 }
428 428  
429 429 // Index gradient
... ... @@ -433,21 +433,21 @@ double GModelSpectralPlaw2::eval_gradients(const GEnergy&amp; srcEng,
433 433 }
434 434  
435 435 // Set gradients
436   - m_integral.factor_gradient(g_integral);
  436 + m_photon_flux.factor_gradient(g_photon_flux);
437 437 m_index.factor_gradient(g_index);
438 438  
439 439 // Compile option: Check for NaN/Inf
440 440 #if defined(G_NAN_CHECK)
441 441 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
442   - std::cout << "*** ERROR: GModelSpectralPlaw2::eval_gradients";
  442 + std::cout << "*** ERROR: GModelSpectralPlawPhotonFlux::eval_gradients";
443 443 std::cout << "(srcEng=" << srcEng;
444 444 std::cout << ", srcTime=" << srcTime << "):";
445 445 std::cout << " NaN/Inf encountered";
446 446 std::cout << " (value=" << value;
447   - std::cout << ", integral=" << integral();
  447 + std::cout << ", photon_flux=" << photon_flux();
448 448 std::cout << ", m_norm=" << m_norm;
449 449 std::cout << ", m_power=" << m_power;
450   - std::cout << ", g_integral=" << g_integral;
  450 + std::cout << ", g_photon_flux=" << g_photon_flux;
451 451 std::cout << ", g_index=" << g_index;
452 452 std::cout << ")" << std::endl;
453 453 }
... ... @@ -475,7 +475,7 @@ double GModelSpectralPlaw2::eval_gradients(const GEnergy&amp; srcEng,
475 475 * - [@p emin, @p emax] is an energy interval, and
476 476 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
477 477 ***************************************************************************/
478   -double GModelSpectralPlaw2::flux(const GEnergy& emin,
  478 +double GModelSpectralPlawPhotonFlux::flux(const GEnergy& emin,
479 479 const GEnergy& emax) const
480 480 {
481 481 // Initialise flux
... ... @@ -493,7 +493,7 @@ double GModelSpectralPlaw2::flux(const GEnergy&amp; emin,
493 493 double pow_ref_emax = std::pow(this->emax().MeV(), gamma);
494 494 double factor = (pow_emax - pow_emin) /
495 495 (pow_ref_emax - pow_ref_emin);
496   - flux = m_integral.value() * factor;
  496 + flux = m_photon_flux.value() * factor;
497 497 }
498 498  
499 499 // Case B: Index is -1
... ... @@ -504,7 +504,7 @@ double GModelSpectralPlaw2::flux(const GEnergy&amp; emin,
504 504 double log_ref_emax = std::log(this->emax().MeV());
505 505 double factor = (log_emax - log_emin) /
506 506 (log_ref_emax - log_ref_emin);
507   - flux = m_integral.value() * factor;
  507 + flux = m_photon_flux.value() * factor;
508 508 }
509 509  
510 510 } // endif: integration range was valid
... ... @@ -531,7 +531,7 @@ double GModelSpectralPlaw2::flux(const GEnergy&amp; emin,
531 531 * - [@p emin, @p emax] is an energy interval, and
532 532 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
533 533 ***************************************************************************/
534   -double GModelSpectralPlaw2::eflux(const GEnergy& emin,
  534 +double GModelSpectralPlawPhotonFlux::eflux(const GEnergy& emin,
535 535 const GEnergy& emax) const
536 536 {
537 537 // Initialise flux
... ... @@ -546,12 +546,12 @@ double GModelSpectralPlaw2::eflux(const GEnergy&amp; emin,
546 546 double gamma = m_index.value() + 1.0;
547 547 double pow_ref_emin = std::pow(this->emin().MeV(), gamma);
548 548 double pow_ref_emax = std::pow(this->emax().MeV(), gamma);
549   - norm = m_integral.value() * gamma / (pow_ref_emax - pow_ref_emin);
  549 + norm = m_photon_flux.value() * gamma / (pow_ref_emax - pow_ref_emin);
550 550 }
551 551 else {
552 552 double log_ref_emin = std::log(this->emin().MeV());
553 553 double log_ref_emax = std::log(this->emax().MeV());
554   - norm = m_integral.value() / (log_ref_emax - log_ref_emin);
  554 + norm = m_photon_flux.value() / (log_ref_emax - log_ref_emin);
555 555 }
556 556  
557 557 // Compute energy flux
... ... @@ -593,7 +593,7 @@ double GModelSpectralPlaw2::eflux(const GEnergy&amp; emin,
593 593 *
594 594 * Returns Monte Carlo energy by randomly drawing from a power law.
595 595 ***************************************************************************/
596   -GEnergy GModelSpectralPlaw2::mc(const GEnergy& emin,
  596 +GEnergy GModelSpectralPlawPhotonFlux::mc(const GEnergy& emin,
597 597 const GEnergy& emax,
598 598 const GTime& time,
599 599 GRan& ran) const
... ... @@ -640,16 +640,16 @@ GEnergy GModelSpectralPlaw2::mc(const GEnergy&amp; emin,
640 640 *
641 641 * Reads the spectral information from an XML element.
642 642 ***************************************************************************/
643   -void GModelSpectralPlaw2::read(const GXmlElement& xml)
  643 +void GModelSpectralPlawPhotonFlux::read(const GXmlElement& xml)
644 644 {
645 645 // Get parameter pointers
646   - const GXmlElement* integral = gammalib::xml_get_par(G_READ, xml, m_integral.name());
647   - const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name());
648   - const GXmlElement* emin = gammalib::xml_get_par(G_READ, xml, m_emin.name());
649   - const GXmlElement* emax = gammalib::xml_get_par(G_READ, xml, m_emax.name());
  646 + const GXmlElement* phflux = gammalib::xml_get_par(G_READ, xml, m_photon_flux.name());
  647 + const GXmlElement* index = gammalib::xml_get_par(G_READ, xml, m_index.name());
  648 + const GXmlElement* emin = gammalib::xml_get_par(G_READ, xml, m_emin.name());
  649 + const GXmlElement* emax = gammalib::xml_get_par(G_READ, xml, m_emax.name());
650 650  
651 651 // Read parameters
652   - m_integral.read(*integral);
  652 + m_photon_flux.read(*phflux);
653 653 m_index.read(*index);
654 654 m_emin.read(*emin);
655 655 m_emax.read(*emax);
... ... @@ -665,11 +665,11 @@ void GModelSpectralPlaw2::read(const GXmlElement&amp; xml)
665 665 * @param[in] xml XML element.
666 666 *
667 667 * @exception GException::model_invalid_spectral
668   - * Existing XML element is not of type "PowerLaw2"
  668 + * Existing XML element is not of type "PowerLaw"
669 669 *
670 670 * Writes the spectral information into an XML element.
671 671 ***************************************************************************/
672   -void GModelSpectralPlaw2::write(GXmlElement& xml) const
  672 +void GModelSpectralPlawPhotonFlux::write(GXmlElement& xml) const
673 673 {
674 674 // Set model type
675 675 if (xml.attribute("type") == "") {
... ... @@ -683,13 +683,13 @@ void GModelSpectralPlaw2::write(GXmlElement&amp; xml) const
683 683 }
684 684  
685 685 // Get XML parameters
686   - GXmlElement* integral = gammalib::xml_need_par(G_WRITE, xml, m_integral.name());
687   - GXmlElement* index = gammalib::xml_need_par(G_WRITE, xml, m_index.name());
688   - GXmlElement* emin = gammalib::xml_need_par(G_WRITE, xml, m_emin.name());
689   - GXmlElement* emax = gammalib::xml_need_par(G_WRITE, xml, m_emax.name());
  686 + GXmlElement* phflux = gammalib::xml_need_par(G_WRITE, xml, m_photon_flux.name());
  687 + GXmlElement* index = gammalib::xml_need_par(G_WRITE, xml, m_index.name());
  688 + GXmlElement* emin = gammalib::xml_need_par(G_WRITE, xml, m_emin.name());
  689 + GXmlElement* emax = gammalib::xml_need_par(G_WRITE, xml, m_emax.name());
690 690  
691 691 // Write parameters
692   - m_integral.write(*integral);
  692 + m_photon_flux.write(*phflux);
693 693 m_index.write(*index);
694 694 m_emin.write(*emin);
695 695 m_emax.write(*emax);
... ... @@ -705,7 +705,7 @@ void GModelSpectralPlaw2::write(GXmlElement&amp; xml) const
705 705 * @param[in] chatter Chattiness (defaults to NORMAL).
706 706 * @return String containing power law information.
707 707 ***************************************************************************/
708   -std::string GModelSpectralPlaw2::print(const GChatter& chatter) const
  708 +std::string GModelSpectralPlawPhotonFlux::print(const GChatter& chatter) const
709 709 {
710 710 // Initialise result string
711 711 std::string result;
... ... @@ -714,7 +714,7 @@ std::string GModelSpectralPlaw2::print(const GChatter&amp; chatter) const
714 714 if (chatter != SILENT) {
715 715  
716 716 // Append header
717   - result.append("=== GModelSpectralPlaw2 ===");
  717 + result.append("=== GModelSpectralPlawPhotonFlux ===");
718 718  
719 719 // Append information
720 720 result.append("\n"+gammalib::parformat("Number of parameters"));
... ... @@ -739,21 +739,21 @@ std::string GModelSpectralPlaw2::print(const GChatter&amp; chatter) const
739 739 /***********************************************************************//**
740 740 * @brief Initialise class members
741 741 ***************************************************************************/
742   -void GModelSpectralPlaw2::init_members(void)
  742 +void GModelSpectralPlawPhotonFlux::init_members(void)
743 743 {
744 744 // Initialise model type
745 745 m_type = "PowerLaw";
746 746  
747   - // Initialise integral flux
748   - m_integral.clear();
749   - m_integral.name("PhotonFlux");
750   - m_integral.unit("ph/cm2/s");
751   - m_integral.scale(1.0);
752   - m_integral.value(1.0); // default: 1.0
753   - m_integral.range(0.0, 10.0); // range: [0,10]
754   - m_integral.free();
755   - m_integral.gradient(0.0);
756   - m_integral.has_grad(true);
  747 + // Initialise photon flux
  748 + m_photon_flux.clear();
  749 + m_photon_flux.name("PhotonFlux");
  750 + m_photon_flux.unit("ph/cm2/s");
  751 + m_photon_flux.scale(1.0);
  752 + m_photon_flux.value(1.0); // default: 1.0
  753 + m_photon_flux.range(0.0, 10.0); // range: [0,10]
  754 + m_photon_flux.free();
  755 + m_photon_flux.gradient(0.0);
  756 + m_photon_flux.has_grad(true);
757 757  
758 758 // Initialise powerlaw index
759 759 m_index.clear();
... ... @@ -789,7 +789,7 @@ void GModelSpectralPlaw2::init_members(void)
789 789  
790 790 // Set parameter pointer(s)
791 791 m_pars.clear();
792   - m_pars.push_back(&m_integral);
  792 + m_pars.push_back(&m_photon_flux);
793 793 m_pars.push_back(&m_index);
794 794 m_pars.push_back(&m_emin);
795 795 m_pars.push_back(&m_emax);
... ... @@ -801,13 +801,13 @@ void GModelSpectralPlaw2::init_members(void)
801 801 m_pow_emax = 0.0;
802 802 m_norm = 0.0;
803 803 m_power = 0.0;
804   - m_last_integral = 0.0;
  804 + m_last_phflux = 0.0;
805 805 m_last_index = 1000.0;
806 806 m_last_emin.MeV(0.0);
807 807 m_last_emax.MeV(0.0);
808 808 m_last_energy.MeV(0.0);
809 809 m_last_value = 0.0;
810   - m_last_g_integral = 0.0;
  810 + m_last_g_phflux = 0.0;
811 811 m_last_g_index = 0.0;
812 812  
813 813 // Return
... ... @@ -820,18 +820,18 @@ void GModelSpectralPlaw2::init_members(void)
820 820 *
821 821 * @param[in] model Spectral power law model.
822 822 ***************************************************************************/
823   -void GModelSpectralPlaw2::copy_members(const GModelSpectralPlaw2& model)
  823 +void GModelSpectralPlawPhotonFlux::copy_members(const GModelSpectralPlawPhotonFlux& model)
824 824 {
825 825 // Copy members
826   - m_type = model.m_type;
827   - m_integral = model.m_integral;
828   - m_index = model.m_index;
829   - m_emin = model.m_emin;
830   - m_emax = model.m_emax;
  826 + m_type = model.m_type;
  827 + m_photon_flux = model.m_photon_flux;
  828 + m_index = model.m_index;
  829 + m_emin = model.m_emin;
  830 + m_emax = model.m_emax;
831 831  
832 832 // Set parameter pointer(s)
833 833 m_pars.clear();
834   - m_pars.push_back(&m_integral);
  834 + m_pars.push_back(&m_photon_flux);
835 835 m_pars.push_back(&m_index);
836 836 m_pars.push_back(&m_emin);
837 837 m_pars.push_back(&m_emax);
... ... @@ -843,13 +843,13 @@ void GModelSpectralPlaw2::copy_members(const GModelSpectralPlaw2&amp; model)
843 843 m_pow_emax = model.m_pow_emax;
844 844 m_norm = model.m_norm;
845 845 m_power = model.m_power;
846   - m_last_integral = model.m_last_integral;
  846 + m_last_phflux = model.m_last_phflux;
847 847 m_last_index = model.m_last_index;
848 848 m_last_emin = model.m_last_emin;
849 849 m_last_emax = model.m_last_emax;
850 850 m_last_energy = model.m_last_energy;
851 851 m_last_value = model.m_last_value;
852   - m_last_g_integral = model.m_last_g_integral;
  852 + m_last_g_phflux = model.m_last_g_phflux;
853 853 m_last_g_index = model.m_last_g_index;
854 854  
855 855 // Return
... ... @@ -860,7 +860,7 @@ void GModelSpectralPlaw2::copy_members(const GModelSpectralPlaw2&amp; model)
860 860 /***********************************************************************//**
861 861 * @brief Delete class members
862 862 ***************************************************************************/
863   -void GModelSpectralPlaw2::free_members(void)
  863 +void GModelSpectralPlawPhotonFlux::free_members(void)
864 864 {
865 865 // Return
866 866 return;
... ... @@ -872,7 +872,7 @@ void GModelSpectralPlaw2::free_members(void)
872 872 *
873 873 * @param[in] srcEng Source energy
874 874 ***************************************************************************/
875   -void GModelSpectralPlaw2::update(const GEnergy& srcEng) const
  875 +void GModelSpectralPlawPhotonFlux::update(const GEnergy& srcEng) const
876 876 {
877 877 // Compute index+1
878 878 double gamma = index() + 1.0;
... ...
src/model/Makefile.am
... ... @@ -56,7 +56,8 @@ sources = GModelPar.cpp \
56 56 GModelSpectralLogParabola.cpp \
57 57 GModelSpectralNodes.cpp \
58 58 GModelSpectralPlaw.cpp \
59   - GModelSpectralPlaw2.cpp \
  59 + GModelSpectralPlawPhotonFlux.cpp \
  60 + GModelSpectralPlawEnergyFlux.cpp \
60 61 GModelTemporal.cpp \
61 62 GModelTemporalRegistry.cpp \
62 63 GModelTemporalConst.cpp \
... ...
test/data/model_point_plaw_eflux.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="PowerLaw">
  5 + <parameter scale="1e-07" name="EnergyFlux" min="1e-07" max="1000.0" value="1.0" free="1"/>
  6 + <parameter scale="1.0" name="Index" min="-5.0" max="+5.0" value="-2.0" free="1"/>
  7 + <parameter scale="1.0" name="LowerLimit" min="10.0" max="1000000.0" value="100.0" free="0"/>
  8 + <parameter scale="1.0" name="UpperLimit" min="10.0" max="1000000.0" value="500000.0" free="0"/>
  9 + </spectrum>
  10 + <spatialModel type="PointSource">
  11 + <parameter free="0" max="360" min="-360" name="RA" scale="1" value="83.6331" />
  12 + <parameter free="0" max="90" min="-90" name="DEC" scale="1" value="22.0145" />
  13 + </spatialModel>
  14 + </source>
  15 +</source_library>
... ...
test/data/model_point_plaw2.xml renamed to test/data/model_point_plaw_phflux.xml
test/test_GModel.cpp
... ... @@ -58,7 +58,8 @@ void TestGModel::set(void)
58 58 m_xml_model_point_const = datadir + "/model_point_const.xml";
59 59 m_xml_model_point_gauss = datadir + "/model_point_gauss.xml";
60 60 m_xml_model_point_plaw = datadir + "/model_point_plaw.xml";
61   - m_xml_model_point_plaw2 = datadir + "/model_point_plaw2.xml";
  61 + m_xml_model_point_plaw_phflux = datadir + "/model_point_plaw_phflux.xml";
  62 + m_xml_model_point_plaw_eflux = datadir + "/model_point_plaw_eflux.xml";
62 63 m_xml_model_point_eplaw = datadir + "/model_point_eplaw.xml";
63 64 m_xml_model_point_bplaw = datadir + "/model_point_bplaw.xml";
64 65 m_xml_model_point_supeplaw = datadir + "/model_point_supeplaw.xml";
... ... @@ -124,8 +125,10 @@ void TestGModel::set(void)
124 125 "Test GModelSpectralGauss");
125 126 append(static_cast<pfunction>(&TestGModel::test_plaw),
126 127 "Test GModelSpectralPlaw");
127   - append(static_cast<pfunction>(&TestGModel::test_plaw2),
128   - "Test GModelSpectralPlaw2");
  128 + append(static_cast<pfunction>(&TestGModel::test_plaw_phflux),
  129 + "Test GModelSpectralPlawPhotonFkux");
  130 + append(static_cast<pfunction>(&TestGModel::test_plaw_eflux),
  131 + "Test GModelSpectralPlawEnergyFlux");
129 132 append(static_cast<pfunction>(&TestGModel::test_eplaw),
130 133 "Test GModelSpectralExpPlaw");
131 134 append(static_cast<pfunction>(&TestGModel::test_supeplaw),
... ... @@ -1551,35 +1554,35 @@ void TestGModel::test_plaw(void)
1551 1554  
1552 1555  
1553 1556 /***********************************************************************//**
1554   - * @brief Test GModelSpectralPlaw2 class
  1557 + * @brief Test GModelSpectralPlawPhotonFlux class
1555 1558 ***************************************************************************/
1556   -void TestGModel::test_plaw2(void)
  1559 +void TestGModel::test_plaw_phflux(void)
1557 1560 {
1558 1561 // Test void constructor
1559   - GModelSpectralPlaw2 model1;
  1562 + GModelSpectralPlawPhotonFlux model1;
1560 1563 test_value(model1.type(), "PowerLaw", "Check type of void model");
1561 1564  
1562 1565 // Test value constructor
1563   - GModelSpectralPlaw2 model2(2.0, -2.1, GEnergy(10.0, "MeV"), GEnergy(100.0, "MeV"));
1564   - test_value(model2.integral(), 2.0);
  1566 + GModelSpectralPlawPhotonFlux model2(2.0, -2.1, GEnergy(10.0, "MeV"), GEnergy(100.0, "MeV"));
  1567 + test_value(model2.photon_flux(), 2.0);
1565 1568 test_value(model2.index(), -2.1);
1566 1569 test_value(model2.emin().MeV(), 10.0);
1567 1570 test_value(model2.emax().MeV(), 100.0);
1568   -
  1571 +
1569 1572 // Test XML constructor and value
1570   - GXml xml(m_xml_model_point_plaw2);
  1573 + GXml xml(m_xml_model_point_plaw_phflux);
1571 1574 GXmlElement* element = xml.element(0)->element(0)->element("spectrum", 0);
1572   - GModelSpectralPlaw2 model3(*element);
  1575 + GModelSpectralPlawPhotonFlux model3(*element);
1573 1576 test_value(model3.size(), 4);
1574 1577 test_value(model3.type(), "PowerLaw", "Check model type");
1575   - test_value(model3.integral(), 1.0e-7);
  1578 + test_value(model3.photon_flux(), 1.0e-7);
1576 1579 test_value(model3.index(), -2.0);
1577 1580 test_value(model3.emin().MeV(), 100.0);
1578 1581 test_value(model3.emax().MeV(), 500000.0);
1579 1582  
1580 1583 // Test integral method
1581   - model3.integral(2.1e-7);
1582   - test_value(model3.integral(), 2.1e-7);
  1584 + model3.photon_flux(2.1e-7);
  1585 + test_value(model3.photon_flux(), 2.1e-7);
1583 1586  
1584 1587 // Test index method
1585 1588 model3.index(-2.3);
... ... @@ -1612,6 +1615,67 @@ void TestGModel::test_plaw2(void)
1612 1615  
1613 1616  
1614 1617 /***********************************************************************//**
  1618 + * @brief Test GModelSpectralPlawEnergyFlux class
  1619 + ***************************************************************************/
  1620 +void TestGModel::test_plaw_eflux(void)
  1621 +{
  1622 + // Test void constructor
  1623 + GModelSpectralPlawEnergyFlux model1;
  1624 + test_value(model1.type(), "PowerLaw", "Check type of void model");
  1625 +
  1626 + // Test value constructor
  1627 + GModelSpectralPlawEnergyFlux model2(2.0, -2.1, GEnergy(10.0, "MeV"), GEnergy(100.0, "MeV"));
  1628 + test_value(model2.energy_flux(), 2.0);
  1629 + test_value(model2.index(), -2.1);
  1630 + test_value(model2.emin().MeV(), 10.0);
  1631 + test_value(model2.emax().MeV(), 100.0);
  1632 +
  1633 + // Test XML constructor and value
  1634 + GXml xml(m_xml_model_point_plaw_eflux);
  1635 + GXmlElement* element = xml.element(0)->element(0)->element("spectrum", 0);
  1636 + GModelSpectralPlawEnergyFlux model3(*element);
  1637 + test_value(model3.size(), 4);
  1638 + test_value(model3.type(), "PowerLaw", "Check model type");
  1639 + test_value(model3.energy_flux(), 1.0e-7);
  1640 + test_value(model3.index(), -2.0);
  1641 + test_value(model3.emin().MeV(), 100.0);
  1642 + test_value(model3.emax().MeV(), 500000.0);
  1643 +
  1644 + // Test integral method
  1645 + model3.energy_flux(2.1e-7);
  1646 + test_value(model3.energy_flux(), 2.1e-7);
  1647 +
  1648 + // Test index method
  1649 + model3.index(-2.3);
  1650 + test_value(model3.index(), -2.3);
  1651 +
  1652 + // Test emin method
  1653 + model3.emin(GEnergy(10.0, "MeV"));
  1654 + test_value(model3.emin().MeV(), 10.0);
  1655 +
  1656 + // Test emax method
  1657 + model3.emax(GEnergy(10.0, "MeV"));
  1658 + test_value(model3.emax().MeV(), 10.0);
  1659 +
  1660 + // Test operator access
  1661 + const char* strarray[] = {"EnergyFlux", "Index", "LowerLimit", "UpperLimit"};
  1662 + for (int i = 0; i < 4; ++i) {
  1663 + std::string keyname(strarray[i]);
  1664 + model3[keyname].remove_range(); // To allow setting of any value
  1665 + model3[keyname].value(2.1);
  1666 + model3[keyname].error(1.9);
  1667 + model3[keyname].gradient(0.8);
  1668 + test_value(model3[keyname].value(), 2.1);
  1669 + test_value(model3[keyname].error(), 1.9);
  1670 + test_value(model3[keyname].gradient(), 0.8);
  1671 + }
  1672 +
  1673 + // Exit test
  1674 + return;
  1675 +}
  1676 +
  1677 +
  1678 +/***********************************************************************//**
1615 1679 * @brief Test GModelSpectralExpPlaw class
1616 1680 ***************************************************************************/
1617 1681 void TestGModel::test_eplaw(void)
... ... @@ -2094,15 +2158,16 @@ void TestGModel::test_spatial_model(void)
2094 2158 void TestGModel::test_spectral_model(void)
2095 2159 {
2096 2160 // Test spectral models XML interface
2097   - test_xml_model("GModelSpectralConst", m_xml_model_point_const);
2098   - test_xml_model("GModelSpectralPlaw", m_xml_model_point_plaw);
2099   - test_xml_model("GModelSpectralPlaw2", m_xml_model_point_plaw2);
2100   - test_xml_model("GModelSpectralExpPaw", m_xml_model_point_eplaw);
2101   - test_xml_model("GModelSpectralBrokenPlaw", m_xml_model_point_bplaw);
2102   - test_xml_model("GModelSpectralSuperExpPlaw", m_xml_model_point_supeplaw);
2103   - test_xml_model("GModelSpectralLogParabola", m_xml_model_point_logparabola);
2104   - test_xml_model("GModelSpectralNodes", m_xml_model_point_nodes);
2105   - test_xml_model("GModelSpectralFunc", m_xml_model_point_filefct);
  2161 + test_xml_model("GModelSpectralConst", m_xml_model_point_const);
  2162 + test_xml_model("GModelSpectralPlaw", m_xml_model_point_plaw);
  2163 + test_xml_model("GModelSpectralPlawPhotonFlux", m_xml_model_point_plaw_phflux);
  2164 + test_xml_model("GModelSpectralPlawEnergyFlux", m_xml_model_point_plaw_eflux);
  2165 + test_xml_model("GModelSpectralExpPaw", m_xml_model_point_eplaw);
  2166 + test_xml_model("GModelSpectralBrokenPlaw", m_xml_model_point_bplaw);
  2167 + test_xml_model("GModelSpectralSuperExpPlaw", m_xml_model_point_supeplaw);
  2168 + test_xml_model("GModelSpectralLogParabola", m_xml_model_point_logparabola);
  2169 + test_xml_model("GModelSpectralNodes", m_xml_model_point_nodes);
  2170 + test_xml_model("GModelSpectralFunc", m_xml_model_point_filefct);
2106 2171  
2107 2172 // Return
2108 2173 return;
... ... @@ -2823,13 +2888,13 @@ void TestGModel::test_legacy_model_point_plaw2(void)
2823 2888 GModels models(m_xml_legacy_point_plaw2);
2824 2889  
2825 2890 // Extract spectral component
2826   - GModelSpectralPlaw2* spectral = static_cast<GModelSpectralPlaw2*>(
  2891 + GModelSpectralPlawPhotonFlux* spectral = static_cast<GModelSpectralPlawPhotonFlux*>(
2827 2892 static_cast<GModelSky*>(
2828 2893 models[0])->spectral());
2829 2894  
2830 2895 // Test model values
2831 2896 test_value(spectral->type(), "PowerLaw2", "Check model type");
2832   - test_value(spectral->integral(), 1.0e-7, 1.0e-7, "Check integral photon flux");
  2897 + test_value(spectral->photon_flux(), 1.0e-7, 1.0e-7, "Check integral photon flux");
2833 2898 test_value(spectral->index(), -2.0, 1.0e-7, "Check index");
2834 2899 test_value(spectral->emin().MeV(), 100.0, 1.0e-7, "Check minimum energy");
2835 2900 test_value(spectral->emax().MeV(), 500000.0, 1.0e-7, "Check maximum energy");
... ... @@ -2840,12 +2905,12 @@ void TestGModel::test_legacy_model_point_plaw2(void)
2840 2905 models.load("test_xml_legacy_point_plaw2.xml");
2841 2906  
2842 2907 // Extract spectral component
2843   - spectral = static_cast<GModelSpectralPlaw2*>(
  2908 + spectral = static_cast<GModelSpectralPlawPhotonFlux*>(
2844 2909 static_cast<GModelSky*>(models[0])->spectral());
2845 2910  
2846 2911 // Re-test model values
2847 2912 test_value(spectral->type(), "PowerLaw2", "Check model type");
2848   - test_value(spectral->integral(), 1.0e-7, 1.0e-7, "Check integral photon flux");
  2913 + test_value(spectral->photon_flux(), 1.0e-7, 1.0e-7, "Check integral photon flux");
2849 2914 test_value(spectral->index(), -2.0, 1.0e-7, "Check index");
2850 2915 test_value(spectral->emin().MeV(), 100.0, 1.0e-7, "Check minimum energy");
2851 2916 test_value(spectral->emax().MeV(), 500000.0, 1.0e-7, "Check maximum energy");
... ...
test/test_GModel.hpp
... ... @@ -62,7 +62,8 @@ public:
62 62 void test_const(void);
63 63 void test_gauss(void);
64 64 void test_plaw(void);
65   - void test_plaw2(void);
  65 + void test_plaw_phflux(void);
  66 + void test_plaw_eflux(void);
66 67 void test_eplaw(void);
67 68 void test_bplaw(void);
68 69 void test_supeplaw(void);
... ... @@ -102,7 +103,8 @@ private:
102 103 std::string m_xml_model_point_const;
103 104 std::string m_xml_model_point_gauss;
104 105 std::string m_xml_model_point_plaw;
105   - std::string m_xml_model_point_plaw2;
  106 + std::string m_xml_model_point_plaw_phflux;
  107 + std::string m_xml_model_point_plaw_eflux;
106 108 std::string m_xml_model_point_eplaw;
107 109 std::string m_xml_model_point_bplaw;
108 110 std::string m_xml_model_point_supeplaw;
... ...