Commit 85fdb567c623d5f5018a90f2f478a90a08be548c

Authored by Jürgen Knödlseder
1 parent 5fbb6c3e

Integrate smoothly broken power law spectrum (#1948)

1 1 Rolf Buehler (rolf.buehler@desy.de)
2 2 François Brun (brun@cenbg.in2p3.fr)
  3 +Joshua Cardenzana (jcardenzana@irap.omp.eu)
3 4 Jean-Baptiste Cayrou (cayrou@etud.insa-toulouse.fr)
4 5 Christoph Deil (Christoph.Deil@mpi-hd.mpg.de)
5 6 Alex Donath (Axel.Donath@mpi-hd.mpg.de)
... ...
ChangeLog
1   -2017-03-22
  1 +2017-03-24
2 2  
3 3 * Version 1.3.0 released
4 4 =========================
5 5  
  6 + Add GModelSpectralSmoothBrokenPlaw class (#1948)
6 7 Implement lazy loading of energy dispersion in GCTAEdisp2D (#1940)
7 8 Add GCTARoi::contains method
8 9 Do no longer interpret a CTA calibration database as file path (#1969)
... ...
1 1 New Features and Important Changes in GammaLib 1.3.0.dev1
2 2  
3   -22 March 2017
  3 +24 March 2017
4 4  
5 5  
6 6 1. Introduction
... ... @@ -14,6 +14,7 @@ made since the last release of GammaLib.
14 14 The following classes have been added:
15 15 - GWcsGLS
16 16 - GWcsSFL
  17 +- GModelSpectralSmoothBrokenPlaw
17 18  
18 19 The following classes have been removed:
19 20 - ...
... ... @@ -69,6 +70,9 @@ None
69 70 The GModelSpectralNodes class now throws an exception if the energy or
70 71 intensity of a node is set to a non-positive value (#990).
71 72  
  73 +The GModelSpectralSmoothBrokenPlaw class that implements a smoothly broken
  74 +power law spectrum has been added (#1948).
  75 +
72 76  
73 77 9. Numerics module
74 78 ------------------
... ...
include/GModelSpectralSmoothBrokenPlaw.hpp
1 1 /***************************************************************************
2   - * GModelSpectralSmoothBrokenPlaw.cpp - *
3   - * Smoothly broken power law spectrum class *
  2 + * GModelSpectralSmoothBrokenPlaw.hpp *
  3 + * Smoothly broken power law spectrum class *
4 4 * ----------------------------------------------------------------------- *
5 5 * copyright (C) 2017 by Josh Cardenzana *
6 6 * ----------------------------------------------------------------------- *
... ... @@ -40,6 +40,7 @@ class GRan;
40 40 class GTime;
41 41 class GXmlElement;
42 42  
  43 +
43 44 /***********************************************************************//**
44 45 * @class GModelSpectralSmoothBrokenPlaw
45 46 *
... ... @@ -65,13 +66,13 @@ class GXmlElement;
65 66 * Notes:
66 67 * - The pivot energy should be set far away from the expected break energy
67 68 * value.
68   - * - When the two indices are close together, the beta parameter becomes poorly
69   - * constrained. Since the beta parameter also scales the indices, this can
70   - * cause very large errors in the estimates of the various spectral parameters.
71   - * In this case, consider fixing beta.
  69 + * - When the two indices are close together, the beta parameter becomes
  70 + * poorly constrained. Since the beta parameter also scales the indices, this
  71 + * can cause very large errors in the estimates of the various spectral
  72 + * parameters. In this case, consider fixing beta.
72 73 ***************************************************************************/
73 74 class GModelSpectralSmoothBrokenPlaw : public GModelSpectral {
74   -
  75 +
75 76 public:
76 77 // Constructors and destructors
77 78 GModelSpectralSmoothBrokenPlaw(void);
... ... @@ -116,14 +117,12 @@ public:
116 117 virtual std::string print(const GChatter& chatter = NORMAL) const;
117 118  
118 119 // Other methods
119   - // Methods for getting the current values
120 120 double prefactor(void) const;
121 121 double index1(void) const;
122 122 double index2(void) const;
123 123 GEnergy pivot(void) const;
124 124 GEnergy breakenergy(void) const;
125 125 double beta(void) const;
126   - // Methods for setting the parameter values
127 126 void prefactor(const double& prefactor);
128 127 void index1(const double& index1);
129 128 void index2(const double& index2);
... ... @@ -149,15 +148,14 @@ protected:
149 148 const double& index2,
150 149 const GEnergy& breakenergy,
151 150 const double& beta) :
152   - m_prefactor(prefactor),
153   - m_index1(index1),
154   - m_index2(index2),
155   - m_pivot(pivot),
156   - m_breakenergy(breakenergy),
157   - m_beta(beta)
158   - {};
  151 + m_prefactor(prefactor),
  152 + m_index1(index1),
  153 + m_index2(index2),
  154 + m_pivot(pivot),
  155 + m_breakenergy(breakenergy),
  156 + m_beta(beta) {};
159 157  
160   - // Method
  158 + // Evaluation method
161 159 double eval(const double& energy) {
162 160 double epivot = energy / m_pivot.MeV();
163 161 double ebreak = energy / m_breakenergy.MeV();
... ... @@ -185,10 +183,10 @@ protected:
185 183 const double& index2,
186 184 const GEnergy& breakenergy,
187 185 const double& beta):
188   - flux_kern(prefactor, index1, pivot, index2, breakenergy, beta)
189   - {};
  186 + flux_kern(prefactor, index1, pivot, index2, breakenergy, beta)
  187 + {};
190 188  
191   - // Method
  189 + // Evaluation method
192 190 double eval(const double& energy) {
193 191 return energy * flux_kern::eval(energy);
194 192 }
... ... @@ -204,18 +202,18 @@ protected:
204 202 GModelPar m_beta; //!< Break smoothness
205 203  
206 204 // Cached members used for pre-computations
207   - mutable GEnergy m_last_energy; //!< Last energy value
208   - mutable double m_last_index1; //!< Last index1 parameter
209   - mutable double m_last_index2; //!< Last index2 parameter
210   - mutable double m_last_pivot; //!< Last pivot parameter
211   - mutable double m_last_breakenergy; //!< Last breakenergy parameter
212   - mutable double m_last_beta; //!< Last beta parameter
213   - mutable double m_last_epivot_norm; //!< Last E/Epivot value
214   - mutable double m_last_ebreak_norm; //!< Last E/Ebreakenergy value
  205 + mutable GEnergy m_last_energy; //!< Last energy value
  206 + mutable double m_last_index1; //!< Last index1 parameter
  207 + mutable double m_last_index2; //!< Last index2 parameter
  208 + mutable double m_last_pivot; //!< Last pivot parameter
  209 + mutable double m_last_breakenergy; //!< Last breakenergy parameter
  210 + mutable double m_last_beta; //!< Last beta parameter
  211 + mutable double m_last_epivot_norm; //!< Last E/Epivot value
  212 + mutable double m_last_ebreak_norm; //!< Last E/Ebreakenergy value
215 213 mutable double m_last_log_epivot_norm; //!< Last ln(E/Epivot) value
216 214 mutable double m_last_log_ebreak_norm; //!< Last ln(E/Ebreakenergy) value
217   - mutable double m_last_epivot_pow; //!< Last pow(E/Epivot,index1) value
218   - mutable double m_last_ebreak_pow; //!< Last pow(E/Ebreakenergy,(index1-index2)/beta)
  215 + mutable double m_last_epivot_pow; //!< Last pow(E/Epivot,index1) value
  216 + mutable double m_last_ebreak_pow; //!< Last pow(E/Ebreakenergy,(index1-index2)/beta)
219 217  
220 218 mutable double m_mc_emin; //!< Minimum energy
221 219 mutable double m_mc_emax; //!< Maximum energy
... ...
src/model/GModelSpectralSmoothBrokenPlaw.cpp
1 1 /***************************************************************************
2   - * GModelSpectralSmoothBrokenPlaw.cpp - *
3   - * Smoothly broken power law spectrum class *
  2 + * GModelSpectralSmoothBrokenPlaw.cpp *
  3 + * Smoothly broken power law spectrum class *
4 4 * ----------------------------------------------------------------------- *
5 5 * copyright (C) 2017 by Joshua Cardenzana *
6 6 * ----------------------------------------------------------------------- *
... ... @@ -21,7 +21,7 @@
21 21 ***************************************************************************/
22 22 /**
23 23 * @file GModelSpectralSmoothBrokenPlaw.cpp
24   - * @brief Broken power law spectrum class implementation
  24 + * @brief Smoothly broken power law spectrum class implementation
25 25 * @author Joshua Cardenzana
26 26 */
27 27  
... ... @@ -47,7 +47,7 @@ const GModelSpectralSmoothBrokenPlaw g_spectral_sblaw_seed1(&quot;SmoothBrokenPowerLa
47 47 "Index2",
48 48 "BreakEnergy",
49 49 "BreakSmoothness");
50   -const GModelSpectralRegistry g_spectral_sblaw_registry1(&g_spectral_sblaw_seed1);
  50 +const GModelSpectralRegistry g_spectral_sblaw_registry1(&g_spectral_sblaw_seed1);
51 51 const GModelSpectralSmoothBrokenPlaw g_spectral_sblaw_seed2("SmoothBrokenPowerLaw",
52 52 "Prefactor",
53 53 "Index1",
... ... @@ -55,13 +55,13 @@ const GModelSpectralSmoothBrokenPlaw g_spectral_sblaw_seed2(&quot;SmoothBrokenPowerLa
55 55 "Index2",
56 56 "BreakValue",
57 57 "Beta");
58   -const GModelSpectralRegistry g_spectral_sblaw_registry2(&g_spectral_sblaw_seed2);
  58 +const GModelSpectralRegistry g_spectral_sblaw_registry2(&g_spectral_sblaw_seed2);
59 59  
60 60 /* __ Method name definitions ____________________________________________ */
61   -#define G_MC "GModelSpectralSmoothBrokenPlaw::mc(GEnergy&, GEnergy&, GTime&,"\
62   -" GRan&)"
63   -#define G_READ "GModelSpectralSmoothBrokenPlaw::read(GXmlElement&)"
64   -#define G_WRITE "GModelSpectralSmoothBrokenPlaw::write(GXmlElement&)"
  61 +#define G_MC "GModelSpectralSmoothBrokenPlaw::mc(GEnergy&, GEnergy&, GTime&,"\
  62 + " GRan&)"
  63 +#define G_READ "GModelSpectralSmoothBrokenPlaw::read(GXmlElement&)"
  64 +#define G_WRITE "GModelSpectralSmoothBrokenPlaw::write(GXmlElement&)"
65 65  
66 66 /* __ Macros _____________________________________________________________ */
67 67  
... ... @@ -80,7 +80,7 @@ const GModelSpectralRegistry g_spectral_sblaw_registry2(&amp;g_spectral_sblaw_seed2
80 80 * @brief Void constructor
81 81 ***************************************************************************/
82 82 GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(void) :
83   - GModelSpectral()
  83 + GModelSpectral()
84 84 {
85 85 // Initialise private members for clean destruction
86 86 init_members();
... ... @@ -93,13 +93,13 @@ GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(void) :
93 93 /***********************************************************************//**
94 94 * @brief Model type and parameter name constructor
95 95 *
96   - * @param[in] type Model type.
97   - * @param[in] prefactor Name of prefactor parameter.
98   - * @param[in] index1 Name of index1 parameter.
99   - * @param[in] pivot Name of pivot parameter.
100   - * @param[in] index2 Name of index2 parameter.
101   - * @param[in] breakenergy Name of breakenergy parameter.
102   - * @param[in] beta Name of beta parameter.
  96 + * @param[in] type Model type.
  97 + * @param[in] prefactor Name of prefactor parameter.
  98 + * @param[in] index1 Name of index1 parameter.
  99 + * @param[in] pivot Name of pivot parameter.
  100 + * @param[in] index2 Name of index2 parameter.
  101 + * @param[in] breakenergy Name of breakenergy parameter.
  102 + * @param[in] beta Name of beta parameter.
103 103 ***************************************************************************/
104 104 GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(
105 105 const std::string& type,
... ... @@ -109,7 +109,7 @@ GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(
109 109 const std::string& index2,
110 110 const std::string& breakenergy,
111 111 const std::string& beta) :
112   -GModelSpectral()
  112 + GModelSpectral()
113 113 {
114 114 // Initialise members
115 115 init_members();
... ... @@ -133,14 +133,14 @@ GModelSpectral()
133 133 /***********************************************************************//**
134 134 * @brief Parameter constructor
135 135 *
136   - * @param[in] prefactor Smoothly broken Plaw pre factor (ph/cm2/s/MeV).
137   - * @param[in] index1 Smoothly broken Plaw index1.
138   - * @param[in] pivot Smoothly broken Plaw pivot energy
139   - * @param[in] index2 Smoothly broken Plaw index1.
140   - * @param[in] breakenergy Break energy.
141   - * @param[in] beta Break smoothness parameter
  136 + * @param[in] prefactor Smoothly broken power law pre factor (ph/cm2/s/MeV).
  137 + * @param[in] index1 Smoothly broken power law index1.
  138 + * @param[in] pivot Smoothly broken power law pivot energy
  139 + * @param[in] index2 Smoothly broken power law index1.
  140 + * @param[in] breakenergy Break energy.
  141 + * @param[in] beta Break smoothness parameter
142 142 *
143   - * Constructs a spectral power law using the model parameters
  143 + * Constructs a smoothly broken power law using the model parameters
144 144 *
145 145 * power law @p prefactor (ph/cm2/s/MeV)
146 146 * spectral @p index1
... ... @@ -156,7 +156,7 @@ GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(
156 156 const double& index2,
157 157 const GEnergy& breakenergy,
158 158 const double& beta) :
159   -GModelSpectral()
  159 + GModelSpectral()
160 160 {
161 161 // Initialise members
162 162 init_members();
... ... @@ -182,13 +182,12 @@ GModelSpectral()
182 182 *
183 183 * @param[in] xml XML element containing position information.
184 184 *
185   - * Constructs a power law spectral model by extracting information from an
186   - * XML element. See the read() method for more information about the expected
187   - * structure of the XML element.
  185 + * Constructs a smoothly broken power law spectral model by extracting
  186 + * information from an XML element. See the read() method for more
  187 + * information about the expected structure of the XML element.
188 188 ***************************************************************************/
189   -GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(
190   - const GXmlElement& xml) :
191   - GModelSpectral()
  189 +GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(const GXmlElement& xml) :
  190 + GModelSpectral()
192 191 {
193 192 // Initialise members
194 193 init_members();
... ... @@ -208,7 +207,7 @@ GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(
208 207 ***************************************************************************/
209 208 GModelSpectralSmoothBrokenPlaw::GModelSpectralSmoothBrokenPlaw(
210 209 const GModelSpectralSmoothBrokenPlaw& model) :
211   - GModelSpectral(model)
  210 + GModelSpectral(model)
212 211 {
213 212 // Initialise members
214 213 init_members();
... ... @@ -409,6 +408,7 @@ double GModelSpectralSmoothBrokenPlaw::eval(const GEnergy&amp; srcEng,
409 408 ? value * m_index2.scale() * m_last_log_ebreak_norm *
410 409 m_last_ebreak_pow / (1.0 + m_last_ebreak_pow)
411 410 : 0.0;
  411 +
412 412 // Compute pivot and break energy value gradients
413 413 double g_pivot = (m_pivot.is_free())
414 414 ? -value * m_last_index1 / m_pivot.factor_value()
... ... @@ -417,6 +417,7 @@ double GModelSpectralSmoothBrokenPlaw::eval(const GEnergy&amp; srcEng,
417 417 ? value * (m_last_index1-m_last_index2) * m_last_ebreak_pow /
418 418 ((1.0+m_last_ebreak_pow) * m_breakenergy.factor_value())
419 419 : 0.0;
  420 +
420 421 // Compute beta gradient
421 422 double g_beta = (m_beta.is_free())
422 423 ? value * m_beta.scale() *
... ... @@ -435,7 +436,7 @@ double GModelSpectralSmoothBrokenPlaw::eval(const GEnergy&amp; srcEng,
435 436 } // endif: gradient computation was requested
436 437  
437 438 // Compile option: Check for NaN/Inf
438   -#if defined(G_NAN_CHECK)
  439 + #if defined(G_NAN_CHECK)
439 440 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
440 441 std::cout << "*** ERROR: GModelSpectralSmoothBrokenPlaw::eval";
441 442 std::cout << "(srcEng=" << srcEng;
... ... @@ -456,7 +457,7 @@ double GModelSpectralSmoothBrokenPlaw::eval(const GEnergy&amp; srcEng,
456 457 std::cout << ", m_last_ebreak_pow=" << m_last_ebreak_pow;
457 458 std::cout << ")" << std::endl;
458 459 }
459   -#endif
  460 + #endif
460 461  
461 462 // Return
462 463 return value;
... ... @@ -572,7 +573,8 @@ double GModelSpectralSmoothBrokenPlaw::eflux(const GEnergy&amp; emin,
572 573 * @exception GException::erange_invalid
573 574 * Energy range is invalid (emin < emax required).
574 575 *
575   - * Returns Monte Carlo energy by randomly drawing from a smoothly broken power law.
  576 + * Returns Monte Carlo energy by randomly drawing from a smoothly broken
  577 + * power law.
576 578 ***************************************************************************/
577 579 GEnergy GModelSpectralSmoothBrokenPlaw::mc(const GEnergy& emin,
578 580 const GEnergy& emax,
... ... @@ -611,16 +613,19 @@ GEnergy GModelSpectralSmoothBrokenPlaw::mc(const GEnergy&amp; emin,
611 613  
612 614 // Case 1: indices are the same (things are simple)
613 615 if (m_mc_exponentH == m_mc_exponentS) {
  616 +
614 617 // Case 1A: Both indices are -1
615 618 if (m_mc_exponentH == 0.0) {
616 619 eng = std::exp(u * m_mc_norm + std::log(m_mc_emin));
617 620  
618 621 }
  622 +
619 623 // Case 1B: Indices are not equal to -1
620 624 else {
621 625 eng = std::exp(std::log(u * m_mc_norm +
622 626 std::pow(m_mc_emin,m_mc_exponentH)) / m_mc_exponentH);
623 627 }
  628 +
624 629 // There is no differentiation between the powerlaws when the
625 630 // exponents are the same.
626 631 e_norm = eng / breakenergy().MeV();
... ... @@ -654,12 +659,14 @@ GEnergy GModelSpectralSmoothBrokenPlaw::mc(const GEnergy&amp; emin,
654 659 }
655 660 // Case 2B: Random number suggests energy above breakenergy
656 661 else {
  662 +
657 663 // Case 2B-1: Soft index is not -1
658 664 if (m_mc_exponentS != 0.0) {
659 665 eng = std::exp(std::log(u * m_mc_norm +
660 666 std::pow(m_mc_ebreak, m_mc_exponentS) -
661 667 m_mc_pow_ewidth_low) / m_mc_exponentS) ;
662 668 }
  669 +
663 670 // Case 2B-2: Soft index is -1
664 671 else {
665 672 eng = std::exp(u * m_mc_norm +
... ... @@ -741,7 +748,7 @@ void GModelSpectralSmoothBrokenPlaw::write(GXmlElement&amp; xml) const
741 748 // Verify model type
742 749 if (xml.attribute("type") != type()) {
743 750 throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"),
744   - "Spectral model is not of type \""+type()+"\".");
  751 + "Spectral model is not of type \""+type()+"\".");
745 752 }
746 753  
747 754 // Get XML parameters
... ... @@ -768,7 +775,7 @@ void GModelSpectralSmoothBrokenPlaw::write(GXmlElement&amp; xml) const
768 775 /***********************************************************************//**
769 776 * @brief Print smooth broken powerlaw information
770 777 *
771   - * @param[in] chatter Chattiness (defaults to NORMAL).
  778 + * @param[in] chatter Chattiness.
772 779 * @return String containing model information.
773 780 ***************************************************************************/
774 781 std::string GModelSpectralSmoothBrokenPlaw::print(const GChatter& chatter) const
... ... @@ -882,17 +889,17 @@ void GModelSpectralSmoothBrokenPlaw::init_members(void)
882 889  
883 890 // Initialise eval cache
884 891 m_last_energy.clear();
885   - m_last_index1 = 1.0e30;
886   - m_last_index2 = 1.0e30;
887   - m_last_pivot = 1.0e30;
888   - m_last_breakenergy = 1.0e30;
889   - m_last_beta = 1.0e30;
890   - m_last_epivot_norm = 1.0e30;
891   - m_last_ebreak_norm = 1.0e30;
  892 + m_last_index1 = 1.0e30;
  893 + m_last_index2 = 1.0e30;
  894 + m_last_pivot = 1.0e30;
  895 + m_last_breakenergy = 1.0e30;
  896 + m_last_beta = 1.0e30;
  897 + m_last_epivot_norm = 1.0e30;
  898 + m_last_ebreak_norm = 1.0e30;
892 899 m_last_log_epivot_norm = 1.0e30;
893 900 m_last_log_ebreak_norm = 1.0e30;
894   - m_last_epivot_pow = 1.0e30;
895   - m_last_ebreak_pow = 1.0e30;
  901 + m_last_epivot_pow = 1.0e30;
  902 + m_last_ebreak_pow = 1.0e30;
896 903  
897 904 // Initialise MC cache
898 905 m_mc_emin = 0.0;
... ... @@ -912,9 +919,10 @@ void GModelSpectralSmoothBrokenPlaw::init_members(void)
912 919 /***********************************************************************//**
913 920 * @brief Copy class members
914 921 *
915   - * @param[in] model GModelSpectralSmoothBrokenPlaw members which should be copied.
  922 + * @param[in] model Smooth broken power law.
916 923 ***************************************************************************/
917   -void GModelSpectralSmoothBrokenPlaw::copy_members(const GModelSpectralSmoothBrokenPlaw& model)
  924 +void GModelSpectralSmoothBrokenPlaw::copy_members(
  925 + const GModelSpectralSmoothBrokenPlaw& model)
918 926 {
919 927 // Copy members
920 928 m_type = model.m_type;
... ... @@ -935,18 +943,18 @@ void GModelSpectralSmoothBrokenPlaw::copy_members(const GModelSpectralSmoothBrok
935 943 m_pars.push_back(&m_beta);
936 944  
937 945 // Copy eval cache
938   - m_last_energy = model.m_last_energy;
939   - m_last_index1 = model.m_last_index1;
940   - m_last_index2 = model.m_last_index2;
941   - m_last_pivot = model.m_last_pivot;
942   - m_last_breakenergy = model.m_last_breakenergy;
943   - m_last_beta = model.m_last_beta;
944   - m_last_epivot_norm = model.m_last_epivot_norm;
945   - m_last_ebreak_norm = model.m_last_ebreak_norm;
  946 + m_last_energy = model.m_last_energy;
  947 + m_last_index1 = model.m_last_index1;
  948 + m_last_index2 = model.m_last_index2;
  949 + m_last_pivot = model.m_last_pivot;
  950 + m_last_breakenergy = model.m_last_breakenergy;
  951 + m_last_beta = model.m_last_beta;
  952 + m_last_epivot_norm = model.m_last_epivot_norm;
  953 + m_last_ebreak_norm = model.m_last_ebreak_norm;
946 954 m_last_log_epivot_norm = model.m_last_log_epivot_norm;
947 955 m_last_log_ebreak_norm = model.m_last_log_ebreak_norm;
948   - m_last_epivot_pow = model.m_last_epivot_pow;
949   - m_last_ebreak_pow = model.m_last_ebreak_pow;
  956 + m_last_epivot_pow = model.m_last_epivot_pow;
  957 + m_last_ebreak_pow = model.m_last_ebreak_pow;
950 958  
951 959 // Copy MC cache
952 960 m_mc_emin = model.m_mc_emin;
... ... @@ -991,24 +999,24 @@ void GModelSpectralSmoothBrokenPlaw::update_eval_cache(const GEnergy&amp; energy) co
991 999  
992 1000 // If the energy or one of the parameters index1, index2, breakenergy
993 1001 // energy, or beta has changed then recompute the cache
994   - if ((m_last_energy != energy) ||
995   - (m_last_index1 != index1) ||
996   - (m_last_index2 != index2) ||
997   - (m_last_pivot != pivot_eng) ||
998   - (m_last_breakenergy != break_eng) ||
999   - (m_last_beta != beta)) {
  1002 + if ((m_last_energy != energy) ||
  1003 + (m_last_index1 != index1) ||
  1004 + (m_last_index2 != index2) ||
  1005 + (m_last_pivot != pivot_eng) ||
  1006 + (m_last_breakenergy != break_eng) ||
  1007 + (m_last_beta != beta)) {
1000 1008  
1001 1009 // Store actual energy and parameter values
1002   - m_last_energy = energy;
1003   - m_last_index1 = index1;
1004   - m_last_index2 = index2;
1005   - m_last_pivot = pivot_eng;
1006   - m_last_breakenergy = break_eng;
1007   - m_last_beta = beta;
  1010 + m_last_energy = energy;
  1011 + m_last_index1 = index1;
  1012 + m_last_index2 = index2;
  1013 + m_last_pivot = pivot_eng;
  1014 + m_last_breakenergy = break_eng;
  1015 + m_last_beta = beta;
1008 1016  
1009 1017 // Compute and store value
1010   - double eng = energy.MeV();
1011   - m_last_epivot_norm = eng / m_last_pivot;
  1018 + double eng = energy.MeV();
  1019 + m_last_epivot_norm = eng / m_last_pivot;
1012 1020 m_last_ebreak_norm = eng / m_last_breakenergy;
1013 1021 m_last_log_epivot_norm = std::log(m_last_epivot_norm);
1014 1022 m_last_log_ebreak_norm = std::log(m_last_ebreak_norm);
... ... @@ -1057,6 +1065,7 @@ void GModelSpectralSmoothBrokenPlaw::update_mc_cache(const GEnergy&amp; emin,
1057 1065 m_mc_exponentH = index1() + 1.0; // Hard index + 1
1058 1066 m_mc_exponentS = index2() + 1.0; // Soft index + 1
1059 1067 }
  1068 +
1060 1069 // CASE: index2 is harder, or index1==index2
1061 1070 else {
1062 1071 m_mc_exponentH = index2() + 1.0; // Hard index + 1
... ... @@ -1070,7 +1079,8 @@ void GModelSpectralSmoothBrokenPlaw::update_mc_cache(const GEnergy&amp; emin,
1070 1079 m_mc_ebreak = breakenergy().MeV();
1071 1080 if (m_mc_emax <= m_mc_ebreak) {
1072 1081 m_mc_ebreak = m_mc_emax;
1073   - } else if (m_mc_emin >= m_mc_ebreak) {
  1082 + }
  1083 + else if (m_mc_emin >= m_mc_ebreak) {
1074 1084 m_mc_ebreak = m_mc_emin;
1075 1085 }
1076 1086  
... ... @@ -1082,6 +1092,7 @@ void GModelSpectralSmoothBrokenPlaw::update_mc_cache(const GEnergy&amp; emin,
1082 1092 m_mc_pow_ewidth_low = 0.0 ;
1083 1093 m_mc_norm = std::log(m_mc_emax) - std::log(m_mc_emin);
1084 1094 }
  1095 +
1085 1096 // CASE: Only harder exponent is -1
1086 1097 else {
1087 1098 m_mc_pow_ewidth_low = std::log(m_mc_ebreak/m_mc_emin);
... ...
test/data/legacy_point_smoothbplaw.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="SmoothBrokenPowerLaw">
  5 + <parameter name="Prefactor" scale="1e-16" value="5.7" min="1e-07" max="1000.0" free="1"/>
  6 + <parameter name="Index1" scale="-1" value="2.48" min="0.0" max="+5.0" free="1"/>
  7 + <parameter name="Scale" scale="1e6" value="1.0" min="0.01" max="1000.0" free="0"/>
  8 + <parameter name="Index2" scale="-1" value="2.70" min="0.01" max="+5.0" free="1"/>
  9 + <parameter name="BreakValue" scale="1e6" value="0.3" min="0.01" max="1000.0" free="1"/>
  10 + <parameter name="Beta" scale="1.0" value="0.2" min="0.01" max="10.0" free="1"/>
  11 + </spectrum>
  12 + <spatialModel type="PointSource">
  13 + <parameter free="0" max="360" min="-360" name="RA" scale="1" value="83.6331" />
  14 + <parameter free="0" max="90" min="-90" name="DEC" scale="1" value="22.0145" />
  15 + </spatialModel>
  16 + </source>
  17 +</source_library>
... ...
test/data/model_point_smoothbplaw.xml
1 1 <?xml version="1.0" standalone="no"?>
2 2 <source_library title="source library">
3   - <source name="Crab1" type="PointSource">
4   - <spectrum type="SmoothBrokenPowerLaw">
5   - <parameter name="Prefactor" scale="1e-16" value="5.7" min="1e-07" max="1000.0" free="1"/>
6   - <parameter name="Index1" scale="-1" value="2.48" min="0.0" max="+5.0" free="1"/>
7   - <parameter name="PivotEnergy" scale="1e6" value="1.0" min="0.01" max="1000.0" free="0"/>
8   - <parameter name="Index2" scale="-1" value="2.70" min="0.01" max="+5.0" free="1"/>
9   - <parameter name="BreakEnergy" scale="1e6" value="0.3" min="0.01" max="1000.0" free="1"/>
10   - <parameter name="BreakSmoothness" scale="1.0" value="0.2" min="0.01" max="10.0" free="1"/>
11   - </spectrum>
12   - <spatialModel type="PointSource">
13   - <parameter free="0" max="360" min="-360" name="RA" scale="1" value="83.6331" />
14   - <parameter free="0" max="90" min="-90" name="DEC" scale="1" value="22.0145" />
15   - </spatialModel>
16   - </source>
17   - <source name="Crab2" type="PointSource">
18   - <spectrum type="SmoothBrokenPowerLaw">
19   - <parameter name="Prefactor" scale="1e-16" value="5.7" min="1e-07" max="1000.0" free="1"/>
20   - <parameter name="Index1" scale="-1" value="2.48" min="0.0" max="+5.0" free="1"/>
21   - <parameter name="Scale" scale="1e6" value="1.0" min="0.01" max="1000.0" free="0"/>
22   - <parameter name="Index2" scale="-1" value="2.70" min="0.01" max="+5.0" free="1"/>
23   - <parameter name="BreakValue" scale="1e6" value="0.3" min="0.01" max="1000.0" free="1"/>
24   - <parameter name="Beta" scale="1.0" value="0.2" min="0.01" max="10.0" free="1"/>
25   - </spectrum>
26   - <spatialModel type="PointSource">
27   - <parameter free="0" max="360" min="-360" name="RA" scale="1" value="83.6331" />
28   - <parameter free="0" max="90" min="-90" name="DEC" scale="1" value="22.0145" />
29   - </spatialModel>
30   - </source>
  3 + <source name="Crab" type="PointSource">
  4 + <spectrum type="SmoothBrokenPowerLaw">
  5 + <parameter name="Prefactor" scale="1e-16" value="5.7" min="1e-07" max="1000.0" free="1"/>
  6 + <parameter name="Index1" scale="-1" value="2.48" min="0.0" max="+5.0" free="1"/>
  7 + <parameter name="PivotEnergy" scale="1e6" value="1.0" min="0.01" max="1000.0" free="0"/>
  8 + <parameter name="Index2" scale="-1" value="2.70" min="0.01" max="+5.0" free="1"/>
  9 + <parameter name="BreakEnergy" scale="1e6" value="0.3" min="0.01" max="1000.0" free="1"/>
  10 + <parameter name="BreakSmoothness" scale="1.0" value="0.2" min="0.01" max="10.0" free="1"/>
  11 + </spectrum>
  12 + <spatialModel type="PointSource">
  13 + <parameter free="0" max="360" min="-360" name="RA" scale="1" value="83.6331" />
  14 + <parameter free="0" max="90" min="-90" name="DEC" scale="1" value="22.0145" />
  15 + </spatialModel>
  16 + </source>
31 17 </source_library>
... ...
test/test_GModel.cpp
... ... @@ -97,6 +97,7 @@ void TestGModel::set(void)
97 97 m_xml_legacy_point_plaw = datadir + "/legacy_point_plaw.xml";
98 98 m_xml_legacy_point_plaw2 = datadir + "/legacy_point_plaw2.xml";
99 99 m_xml_legacy_point_eplaw = datadir + "/legacy_point_eplaw.xml";
  100 + m_xml_legacy_point_smoothbplaw = datadir + "/legacy_point_smoothbplaw.xml";
100 101 m_xml_legacy_point_supeplaw = datadir + "/legacy_point_supeplaw.xml";
101 102 m_xml_legacy_point_logparabola = datadir + "/legacy_point_logparabola.xml";
102 103  
... ... @@ -204,6 +205,8 @@ void TestGModel::set(void)
204 205 "Test GModelSpectralPlaw legacy model");
205 206 append(static_cast<pfunction>(&TestGModel::test_legacy_model_point_plaw2),
206 207 "Test GModelSpectralPlaw2 legacy model");
  208 + append(static_cast<pfunction>(&TestGModel::test_legacy_model_point_smoothbplaw),
  209 + "Test GModelSpectralSmoothBrokenPlaw legacy model");
207 210 append(static_cast<pfunction>(&TestGModel::test_legacy_model_point_eplaw),
208 211 "Test GModelSpectralExpPlaw legacy model");
209 212 append(static_cast<pfunction>(&TestGModel::test_legacy_model_point_supeplaw),
... ... @@ -1861,63 +1864,51 @@ void TestGModel::test_smoothbplaw(void)
1861 1864 test_value(model2.beta(), 2.0);
1862 1865  
1863 1866  
1864   - // Test XML constructor - 1
1865   - GModels models(m_xml_model_point_smoothbplaw);
1866   - GModelSpectralSmoothBrokenPlaw* model3 = static_cast<GModelSpectralSmoothBrokenPlaw*>(
1867   - static_cast<GModelSky*>(
1868   - models[0])->spectral());
1869   - test_value(model3->size(), 6);
1870   - test_value(model3->type(), "SmoothBrokenPowerLaw", "Check model type");
1871   - test_value(model3->prefactor(), 5.7e-16);
1872   - test_value(model3->index1(), -2.48);
1873   - test_value(model3->pivot().TeV(), 1.0);
1874   - test_value(model3->index2(), -2.70);
1875   - test_value(model3->breakenergy().TeV(), 0.3);
  1867 + // Test XML constructor
  1868 + GXml xml(m_xml_model_point_smoothbplaw);
  1869 + GXmlElement* element = xml.element(0)->element(0)->element("spectrum", 0);
  1870 + GModelSpectralSmoothBrokenPlaw model3(*element);
  1871 + test_value(model3.size(), 6);
  1872 + test_value(model3.type(), "SmoothBrokenPowerLaw", "Check model type");
  1873 + test_value(model3.prefactor(), 5.7e-16);
  1874 + test_value(model3.index1(), -2.48);
  1875 + test_value(model3.pivot().TeV(), 1.0);
  1876 + test_value(model3.index2(), -2.70);
  1877 + test_value(model3.breakenergy().TeV(), 0.3);
1876 1878  
1877   - // Test XML constructor - 2
1878   - GModelSpectralSmoothBrokenPlaw* model4 = static_cast<GModelSpectralSmoothBrokenPlaw*>(
1879   - static_cast<GModelSky*>(
1880   - models[1])->spectral());
1881   - test_value(model4->size(), 6);
1882   - test_value(model4->type(), "SmoothBrokenPowerLaw", "Check model type");
1883   - test_value(model4->prefactor(), 5.7e-16);
1884   - test_value(model4->index1(), -2.48);
1885   - test_value(model4->pivot().TeV(), 1.0);
1886   - test_value(model4->index2(), -2.70);
1887   - test_value(model4->breakenergy().TeV(), 0.3);
1888 1879  
1889 1880 // Test prefactor method
1890   - model3->prefactor(2.3e-16);
1891   - test_value(model3->prefactor(), 2.3e-16);
  1881 + model3.prefactor(2.3e-16);
  1882 + test_value(model3.prefactor(), 2.3e-16);
1892 1883  
1893 1884 // Test index1 method
1894   - model3->index1(-2.6);
1895   - test_value(model3->index1(), -2.6);
  1885 + model3.index1(-2.6);
  1886 + test_value(model3.index1(), -2.6);
1896 1887  
1897 1888 // Test pivot method
1898   - model3->pivot(GEnergy(0.5, "TeV"));
1899   - test_value(model3->pivot().TeV(), 0.5);
  1889 + model3.pivot(GEnergy(0.5, "TeV"));
  1890 + test_value(model3.pivot().TeV(), 0.5);
1900 1891  
1901 1892 // Test index2 method
1902   - model3->index2(-3.6);
1903   - test_value(model3->index2(), -3.6);
  1893 + model3.index2(-3.6);
  1894 + test_value(model3.index2(), -3.6);
1904 1895  
1905 1896 // Test breakenergy method
1906   - model3->breakenergy(GEnergy(0.5, "TeV"));
1907   - test_value(model3->breakenergy().TeV(), 0.5);
  1897 + model3.breakenergy(GEnergy(0.5, "TeV"));
  1898 + test_value(model3.breakenergy().TeV(), 0.5);
1908 1899  
1909 1900 // Test operator access
1910 1901 const char* strarray[] = {"Prefactor", "Index1", "PivotEnergy", "Index2",
1911 1902 "BreakEnergy", "BreakSmoothness"};
1912 1903 for (int i = 0; i < 4; ++i) {
1913 1904 std::string keyname(strarray[i]);
1914   - (*model3)[keyname].remove_range(); // To allow setting of any value
1915   - (*model3)[keyname].value(2.1);
1916   - (*model3)[keyname].error(1.9);
1917   - (*model3)[keyname].gradient(0.8);
1918   - test_value((*model3)[keyname].value(), 2.1);
1919   - test_value((*model3)[keyname].error(), 1.9);
1920   - test_value((*model3)[keyname].gradient(), 0.8);
  1905 + model3[keyname].remove_range(); // To allow setting of any value
  1906 + model3[keyname].value(2.1);
  1907 + model3[keyname].error(1.9);
  1908 + model3[keyname].gradient(0.8);
  1909 + test_value(model3[keyname].value(), 2.1);
  1910 + test_value(model3[keyname].error(), 1.9);
  1911 + test_value(model3[keyname].gradient(), 0.8);
1921 1912 }
1922 1913  
1923 1914 // Exit test
... ... @@ -3192,6 +3183,52 @@ void TestGModel::test_legacy_model_point_plaw2(void)
3192 3183  
3193 3184  
3194 3185 /***********************************************************************//**
  3186 + * @brief Test smooth broken power law legacy model
  3187 + ***************************************************************************/
  3188 +void TestGModel::test_legacy_model_point_smoothbplaw(void)
  3189 +{
  3190 + // Load model from XML file
  3191 + GModels models(m_xml_legacy_point_smoothbplaw);
  3192 +
  3193 + // Extract spectral component
  3194 + GModelSpectralSmoothBrokenPlaw* spectral =
  3195 + static_cast<GModelSpectralSmoothBrokenPlaw*>
  3196 + (static_cast<GModelSky*>(models[0])->spectral());
  3197 +
  3198 +
  3199 + // Test model values
  3200 + test_value(spectral->size(), 6);
  3201 + test_value(spectral->type(), "SmoothBrokenPowerLaw");
  3202 + test_value(spectral->prefactor(), 5.7e-16);
  3203 + test_value(spectral->index1(), -2.48);
  3204 + test_value(spectral->pivot().TeV(), 1.0);
  3205 + test_value(spectral->index2(), -2.70);
  3206 + test_value(spectral->breakenergy().TeV(), 0.3);
  3207 +
  3208 + // Save file to disk and reload file (tests the proper saving and loading)
  3209 + models.save("test_xml_legacy_point_smoothbplaw.xml");
  3210 + models.clear();
  3211 + models.load("test_xml_legacy_point_smoothbplaw.xml");
  3212 +
  3213 + // Extract spectral component
  3214 + spectral = static_cast<GModelSpectralSmoothBrokenPlaw*>
  3215 + (static_cast<GModelSky*>(models[0])->spectral());
  3216 +
  3217 + // Test model values
  3218 + test_value(spectral->size(), 6);
  3219 + test_value(spectral->type(), "SmoothBrokenPowerLaw");
  3220 + test_value(spectral->prefactor(), 5.7e-16);
  3221 + test_value(spectral->index1(), -2.48);
  3222 + test_value(spectral->pivot().TeV(), 1.0);
  3223 + test_value(spectral->index2(), -2.70);
  3224 + test_value(spectral->breakenergy().TeV(), 0.3);
  3225 +
  3226 + // Exit test
  3227 + return;
  3228 +}
  3229 +
  3230 +
  3231 +/***********************************************************************//**
3195 3232 * @brief Test exponentially cut off power law legacy model
3196 3233 ***************************************************************************/
3197 3234 void TestGModel::test_legacy_model_point_eplaw(void)
... ...
test/test_GModel.hpp
... ... @@ -92,6 +92,7 @@ public:
92 92 void test_legacy_model_point_const(void);
93 93 void test_legacy_model_point_plaw(void);
94 94 void test_legacy_model_point_plaw2(void);
  95 + void test_legacy_model_point_smoothbplaw(void);
95 96 void test_legacy_model_point_eplaw(void);
96 97 void test_legacy_model_point_supeplaw(void);
97 98 void test_legacy_model_point_logparabola(void);
... ... @@ -147,6 +148,7 @@ private:
147 148 std::string m_xml_legacy_point_const;
148 149 std::string m_xml_legacy_point_plaw;
149 150 std::string m_xml_legacy_point_plaw2;
  151 + std::string m_xml_legacy_point_smoothbplaw;
150 152 std::string m_xml_legacy_point_eplaw;
151 153 std::string m_xml_legacy_point_supeplaw;
152 154 std::string m_xml_legacy_point_logparabola;
... ...