GammaLib 2.0.0
Loading...
Searching...
No Matches
GModelSpectralExpPlaw.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GModelSpectralExpPlaw.cpp - Exponential cut off power law model *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-2021 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 GModelSpectralExpPlaw.cpp
23 * @brief Exponential cut off power law spectral class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <cmath>
32#include "GException.hpp"
33#include "GTools.hpp"
34#include "GRan.hpp"
35#include "GIntegral.hpp"
38
39/* __ Constants __________________________________________________________ */
40
41/* __ Globals ____________________________________________________________ */
42const GModelSpectralExpPlaw g_spectral_eplaw_seed1("ExponentialCutoffPowerLaw",
43 "Prefactor",
44 "Index",
45 "PivotEnergy",
46 "CutoffEnergy");
47const GModelSpectralRegistry g_spectral_eplaw_registry1(&g_spectral_eplaw_seed1);
48#if defined(G_LEGACY_XML_FORMAT)
49const GModelSpectralExpPlaw g_spectral_eplaw_seed2("ExpCutoff",
50 "Prefactor",
51 "Index",
52 "Scale",
53 "Cutoff");
54const GModelSpectralRegistry g_spectral_eplaw_registry2(&g_spectral_eplaw_seed2);
55#endif
56
57/* __ Method name definitions ____________________________________________ */
58#define G_MC "GModelSpectralExpPlaw::mc(GEnergy&, GEnergy&, GTime&, GRan&)"
59#define G_READ "GModelSpectralExpPlaw::read(GXmlElement&)"
60#define G_WRITE "GModelSpectralExpPlaw::write(GXmlElement&)"
61
62/* __ Macros _____________________________________________________________ */
63
64/* __ Coding definitions _________________________________________________ */
65
66/* __ Debug definitions __________________________________________________ */
67//#define G_DEBUG_MC //!< Debug Monte-Carlo sampling
68
69
70/*==========================================================================
71 = =
72 = Constructors/destructors =
73 = =
74 ==========================================================================*/
75
76/***********************************************************************//**
77 * @brief Void constructor
78 ***************************************************************************/
80{
81 // Initialise members
83
84 // Return
85 return;
86}
87
88
89/***********************************************************************//**
90 * @brief Model type and parameter name constructor
91 *
92 * @param[in] type Model type.
93 * @param[in] prefactor Name of prefactor parameter.
94 * @param[in] index Name of index parameter.
95 * @param[in] pivot Name of pivot parameter.
96 * @param[in] cutoff Name of cutoff parameter.
97 ***************************************************************************/
99 const std::string& prefactor,
100 const std::string& index,
101 const std::string& pivot,
102 const std::string& cutoff) :
104{
105 // Initialise members
106 init_members();
107
108 // Set model type
109 m_type = type;
110
111 // Set parameter names
116
117 // Return
118 return;
119}
120
121
122/***********************************************************************//**
123 * @brief Constructor
124 *
125 * @param[in] prefactor Pre factor normalization (ph/cm2/s/MeV).
126 * @param[in] index Power law index.
127 * @param[in] pivot Pivot energy.
128 * @param[in] cutoff Cut off energy.
129 *
130 * Construct an exponentially cut off power law from
131 * - a prefactor value (in units of ph/cm2/s/MeV)
132 * - a spectral index,
133 * - a pivot energy, and
134 * - a cut off energy.
135 ***************************************************************************/
137 const double& index,
138 const GEnergy& pivot,
139 const GEnergy& cutoff) :
141{
142 // Initialise members
143 init_members();
144
145 // Set parameters
148 m_pivot.value(pivot.MeV()); // Internally stored in MeV
149 m_ecut.value(cutoff.MeV()); // Internally stored in MeV
150
151 // Autoscale parameters
152 autoscale();
153
154 // Return
155 return;
156}
157
158
159/***********************************************************************//**
160 * @brief XML constructor
161 *
162 * @param[in] xml XML element.
163 *
164 * Constructs an exponentially cut off power law spectral model by extracting
165 * information from an XML element. See the read() method for more
166 * information about the expected structure of the XML element.
167 ***************************************************************************/
170{
171 // Initialise members
172 init_members();
173
174 // Read information from XML element
175 read(xml);
176
177 // Return
178 return;
179}
180
181
182/***********************************************************************//**
183 * @brief Copy constructor
184 *
185 * @param[in] model Exponentially cut off power law model.
186 ***************************************************************************/
188 GModelSpectral(model)
189{
190 // Initialise members
191 init_members();
192
193 // Copy members
194 copy_members(model);
195
196 // Return
197 return;
198}
199
200
201/***********************************************************************//**
202 * @brief Destructor
203 ***************************************************************************/
205{
206 // Free members
207 free_members();
208
209 // Return
210 return;
211}
212
213
214/*==========================================================================
215 = =
216 = Operators =
217 = =
218 ==========================================================================*/
219
220/***********************************************************************//**
221 * @brief Assignment operator
222 *
223 * @param[in] model Exponentially cut off power law model.
224 * @return Exponentially cut off power law model.
225 ***************************************************************************/
227{
228 // Execute only if object is not identical
229 if (this != &model) {
230
231 // Copy base class members
232 this->GModelSpectral::operator=(model);
233
234 // Free members
235 free_members();
236
237 // Initialise members
238 init_members();
239
240 // Copy members
241 copy_members(model);
242
243 } // endif: object was not identical
244
245 // Return
246 return *this;
247}
248
249
250/*==========================================================================
251 = =
252 = Public methods =
253 = =
254 ==========================================================================*/
255
256/***********************************************************************//**
257 * @brief Clear exponentially cut off power law model
258 ***************************************************************************/
260{
261 // Free class members (base and derived classes, derived class first)
262 free_members();
264
265 // Initialise members
267 init_members();
268
269 // Return
270 return;
271}
272
273
274/***********************************************************************//**
275 * @brief Clone exponentially cut off power law model
276 *
277 * @return Pointer to deep copy of exponentially cut off power law model.
278 ***************************************************************************/
280{
281 // Clone exponentially cut off power law model
282 return new GModelSpectralExpPlaw(*this);
283}
284
285
286/***********************************************************************//**
287 * @brief Evaluate function
288 *
289 * @param[in] srcEng True photon energy.
290 * @param[in] srcTime True photon arrival time.
291 * @param[in] gradients Compute gradients?
292 * @return Model value (ph/cm2/s/MeV).
293 *
294 * Evaluates
295 *
296 * \f[
297 * S_{\rm E}(E | t) = {\tt m\_norm}
298 * \left( \frac{E}{\tt m\_pivot} \right)^{\tt m\_index}
299 * \exp \left( \frac{-E}{\tt m\_ecut} \right)
300 * \f]
301 *
302 * where
303 * - \f${\tt m\_norm}\f$ is the normalization or prefactor,
304 * - \f${\tt m\_pivot}\f$ is the pivot energy,
305 * - \f${\tt m\_index}\f$ is the spectral index, and
306 * - \f${\tt m\_ecut}\f$ is the cut off energy.
307 *
308 * If the @p gradients flag is true the method will also compute the
309 * partial derivatives of the model with respect to the parameters using
310 *
311 * \f[
312 * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_norm}} =
313 * \frac{S_{\rm E}(E | t)}{{\tt m\_norm}}
314 * \f]
315 *
316 * \f[
317 * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_index}} =
318 * S_{\rm E}(E | t) \, \ln(E/{\tt m_pivot})
319 * \f]
320 *
321 * \f[
322 * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_ecut}} =
323 * S_{\rm E}(E | t) \, \left( \frac{E}{{\tt m\_ecut}^2} \right)
324 * \f]
325 *
326 * \f[
327 * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_pivot}} =
328 * -S_{\rm E}(E | t) \,
329 * \left( \frac{{\tt m\_index}}{{\tt m\_pivot}} \right)
330 * \f]
331 *
332 * @todo The method expects that pivot!=0 and ecut!=0. Otherwise Inf or NaN
333 * may result. We should add a test that prevents using invalid
334 * values.
335 ***************************************************************************/
337 const GTime& srcTime,
338 const bool& gradients) const
339{
340 // Update the evaluation cache
341 update_eval_cache(srcEng);
342
343 // Compute function value
344 double value = m_norm.value() * m_last_power;
345
346 // Optionally compute gradients
347 if (gradients) {
348
349 // Compute partial derivatives with respect to the parameter factor
350 // values. The partial derivatives with respect to the parameter
351 // values are obtained by division by the scale factor.
352 double g_norm = (m_norm.is_free())
354 : 0.0;
355 double g_index = (m_index.is_free())
356 ? value * m_index.scale() * std::log(m_last_e_norm)
357 : 0.0;
358 double g_ecut = (m_ecut.is_free() && m_ecut.factor_value() != 0.0)
359 ? value * m_last_e_cut / m_ecut.factor_value()
360 : 0.0;
361 double g_pivot = (m_pivot.is_free() && m_pivot.factor_value() != 0.0)
362 ? -value * m_last_index / m_pivot.factor_value()
363 : 0.0;
364
365 // Set gradients
366 m_norm.factor_gradient(g_norm);
367 m_index.factor_gradient(g_index);
368 m_ecut.factor_gradient(g_ecut);
369 m_pivot.factor_gradient(g_pivot);
370
371 } // endif: gradient computation was requested
372
373 // Compile option: Check for NaN/Inf
374 #if defined(G_NAN_CHECK)
375 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
376 std::cout << "*** ERROR: GModelSpectralExpPlaw::eval";
377 std::cout << "(srcEng=" << srcEng;
378 std::cout << ", srcTime=" << srcTime << "):";
379 std::cout << " NaN/Inf encountered";
380 std::cout << " (value=" << value;
381 std::cout << ", power=" << m_last_power;
382 std::cout << ")" << std::endl;
383 }
384 #endif
385
386 // Return
387 return value;
388}
389
390
391/***********************************************************************//**
392 * @brief Returns model photon flux between [emin, emax] (units: ph/cm2/s)
393 *
394 * @param[in] emin Minimum photon energy.
395 * @param[in] emax Maximum photon energy.
396 * @return Photon flux (ph/cm2/s).
397 *
398 * Computes
399 *
400 * \f[
401 * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) dE
402 * \f]
403 *
404 * where
405 * - [@p emin, @p emax] is an energy interval, and
406 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
407 * The integration is done numerically.
408 ***************************************************************************/
410 const GEnergy& emax) const
411{
412 // Initialise flux
413 double flux = 0.0;
414
415 // Compute only if integration range is valid
416 if (emin < emax) {
417
418 // Setup integration kernel
419 flux_kernel integrand(m_norm.value(), m_index.value(),
421 GIntegral integral(&integrand);
422
423 // Get integration boundaries in MeV
424 double e_min = emin.MeV();
425 double e_max = emax.MeV();
426
427 // Perform integration
428 flux = integral.romberg(e_min, e_max);
429
430 } // endif: integration range was valid
431
432 // Return
433 return flux;
434}
435
436
437/***********************************************************************//**
438 * @brief Returns model energy flux between [emin, emax] (units: erg/cm2/s)
439 *
440 * @param[in] emin Minimum photon energy.
441 * @param[in] emax Maximum photon energy.
442 * @return Energy flux (erg/cm2/s).
443 *
444 * Computes
445 *
446 * \f[
447 * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) E \, dE
448 * \f]
449 *
450 * where
451 * - [@p emin, @p emax] is an energy interval, and
452 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
453 * The integration is done numerically.
454 ***************************************************************************/
456 const GEnergy& emax) const
457{
458 // Initialise flux
459 double eflux = 0.0;
460
461 // Compute only if integration range is valid
462 if (emin < emax) {
463
464 // Setup integration kernel
465 eflux_kernel integrand(m_norm.value(), m_index.value(),
467 GIntegral integral(&integrand);
468
469 // Get integration boundaries in MeV
470 double e_min = emin.MeV();
471 double e_max = emax.MeV();
472
473 // Perform integration
474 eflux = integral.romberg(e_min, e_max);
475
476 // Convert from MeV/cm2/s to erg/cm2/s
478
479 } // endif: integration range was valid
480
481 // Return
482 return eflux;
483}
484
485
486/***********************************************************************//**
487 * @brief Returns MC energy between [emin, emax]
488 *
489 * @param[in] emin Minimum photon energy.
490 * @param[in] emax Maximum photon energy.
491 * @param[in] time True photon arrival time.
492 * @param[in,out] ran Random number generator.
493 * @return Energy.
494 *
495 * Simulates a random energy in the interval [emin, emax] for an
496 * exponentially cut off power law. The simulation is done using a rejection
497 * method. First, a random energy within [emin, emax] is drawn from an
498 * power law distribution. Then the energy is accepted or rejected based
499 * on an acceptance fraction that is computed from the exponential cut off.
500 ***************************************************************************/
502 const GEnergy& emax,
503 const GTime& time,
504 GRan& ran) const
505{
506 // Check energy interval
508
509 // Allocate energy
510 GEnergy energy;
511
512 // Update cache
513 update_mc_cache(emin, emax);
514
515 // Initialise energy
516 double eng;
517
518 // Initialise acceptance fraction
519 double acceptance_fraction;
520 double inv_ecut = 1.0 / m_ecut.value();
521
522 // Compute random number generator normalisation for speed-up of the
523 // computations. Normally it should be sufficient to always use the
524 // minimum energy for the normalisation, yet for the case that the model
525 // grows with energy we better also test the maximum energy, and we
526 // just use the larger of both normalisations
527 double norm_emin = std::exp(-emin.MeV() * inv_ecut);
528 double norm_emax = std::exp(-emax.MeV() * inv_ecut);
529 double norm = (norm_emin > norm_emax) ? norm_emin : norm_emax;
530
531 // Debug option: initialise number of samples
532 #if defined(G_DEBUG_MC)
533 int samples = 0;
534 #endif
535
536 // Use rejection method to draw a random energy. We first draw
537 // analytically from a power law, and then compare the power law
538 // at the drawn energy to the exponentially cut off function. This
539 // gives an acceptance fraction, and we accept the energy only if
540 // a uniform random number is <= the acceptance fraction.
541 do {
542
543 // Debug option: increment number of samples
544 #if defined(G_DEBUG_MC)
545 samples++;
546 #endif
547
548 // Get uniform random number
549 double u = ran.uniform();
550
551 // Case A: Index is not -1
552 if (index() != -1.0) {
553 if (u > 0.0) {
554 eng = std::exp(std::log(u * m_mc_pow_ewidth + m_mc_pow_emin) /
556 }
557 else {
558 eng = 0.0;
559 }
560 }
561
562 // Case B: Index is -1
563 else {
564 eng = std::exp(u * m_mc_pow_ewidth + m_mc_pow_emin);
565 }
566
567 // Compute acceptance fraction
568 acceptance_fraction = std::exp(-eng * inv_ecut);
569
570 } while (ran.uniform() * norm > acceptance_fraction);
571
572 // Set energy
573 energy.MeV(eng);
574
575 // Debug option: write result
576 #if defined(G_DEBUG_MC)
577 std::cout << "GModelSpectralExpPlaw::mc(";
578 std::cout << emin.print() << "," << emax.print() << "," << time.print() << "):";
579 std::cout << " energy=" << energy.print();
580 std::cout << " samples=" << samples << std::endl;
581 #endif
582
583 // Return energy
584 return energy;
585}
586
587
588/***********************************************************************//**
589 * @brief Read model from XML element
590 *
591 * @param[in] xml XML element.
592 *
593 * Reads the spectral information from an XML element.
594 ***************************************************************************/
596{
597 // Verify number of model parameters
599
600 // Get parameter pointers
603 const GXmlElement* ecut = gammalib::xml_get_par(G_READ, xml, m_ecut.name());
605
606 // Read parameters
607 m_norm.read(*norm);
609 m_ecut.read(*ecut);
611
612 // Return
613 return;
614}
615
616
617/***********************************************************************//**
618 * @brief Write model into XML element
619 *
620 * @param[in] xml XML element.
621 *
622 * Writes the spectral information into an XML element.
623 ***************************************************************************/
625{
626 // Verify model type
628
629 // Get XML parameters
634
635 // Write parameters
636 m_norm.write(*norm);
638 m_ecut.write(*ecut);
640
641 // Return
642 return;
643}
644
645
646/***********************************************************************//**
647 * @brief Print model information
648 *
649 * @param[in] chatter Chattiness.
650 * @return String containing model information.
651 ***************************************************************************/
652std::string GModelSpectralExpPlaw::print(const GChatter& chatter) const
653{
654 // Initialise result string
655 std::string result;
656
657 // Continue only if chatter is not silent
658 if (chatter != SILENT) {
659
660 // Append header
661 result.append("=== GModelSpectralExpPlaw ===");
662
663 // Append information
664 result.append("\n"+gammalib::parformat("Number of parameters"));
665 result.append(gammalib::str(size()));
666 for (int i = 0; i < size(); ++i) {
667 result.append("\n"+m_pars[i]->print(chatter));
668 }
669
670 } // endif: chatter was not silent
671
672 // Return result
673 return result;
674}
675
676
677/*==========================================================================
678 = =
679 = Private methods =
680 = =
681 ==========================================================================*/
682
683/***********************************************************************//**
684 * @brief Initialise class members
685 ***************************************************************************/
687{
688 // Initialise model type
689 m_type = "ExponentialCutoffPowerLaw";
690
691 // Initialise powerlaw normalisation
692 m_norm.clear();
693 m_norm.name("Prefactor");
694 m_norm.unit("ph/cm2/s/MeV");
695 m_norm.scale(1.0);
696 m_norm.value(1.0); // default: 1.0
697 m_norm.min(0.0); // min: 0.0
698 m_norm.free();
699 m_norm.gradient(0.0);
700 m_norm.has_grad(true);
701
702 // Initialise powerlaw index
703 m_index.clear();
704 m_index.name("Index");
705 m_index.scale(1.0);
706 m_index.value(-2.0); // default: -2.0
707 m_index.range(-10.0,+10.0); // range: [-10,+10]
708 m_index.free();
709 m_index.gradient(0.0);
710 m_index.has_grad(true);
711
712 // Initialise cut off energy
713 m_ecut.clear();
714 m_ecut.name("CutoffEnergy");
715 m_ecut.unit("MeV");
716 m_ecut.scale(1.0);
717 m_ecut.value(1000.0); // default: 1000.0
718 m_ecut.min(0.1); // min: 0.1
719 m_ecut.free();
720 m_ecut.gradient(0.0);
721 m_ecut.has_grad(true);
722
723 // Initialise pivot energy
724 m_pivot.clear();
725 m_pivot.name("PivotEnergy");
726 m_pivot.unit("MeV");
727 m_pivot.scale(1.0);
728 m_pivot.value(100.0);
729 m_pivot.fix();
730 m_pivot.gradient(0.0);
731 m_pivot.has_grad(true);
732
733 // Set parameter pointer(s)
734 m_pars.clear();
735 m_pars.push_back(&m_norm);
736 m_pars.push_back(&m_index);
737 m_pars.push_back(&m_ecut);
738 m_pars.push_back(&m_pivot);
739
740 // Initialise eval cache
742 m_last_index = 1.0e30;
743 m_last_ecut = 1.0e30;
744 m_last_pivot = 1.0e30;
745 m_last_e_norm = 0.0;
746 m_last_e_cut = 0.0;
747 m_last_power = 0.0;
748
749 // Initialise MC cache
750 m_mc_emin = 0.0;
751 m_mc_emax = 0.0;
752 m_mc_exponent = 0.0;
753 m_mc_pow_emin = 0.0;
754 m_mc_pow_ewidth = 0.0;
755
756 // Return
757 return;
758}
759
760
761/***********************************************************************//**
762 * @brief Copy class members
763 *
764 * @param[in] model Exponential cut off power law model.
765 ***************************************************************************/
767{
768 // Copy members
769 m_type = model.m_type;
770 m_norm = model.m_norm;
771 m_index = model.m_index;
772 m_ecut = model.m_ecut;
773 m_pivot = model.m_pivot;
774
775 // Set parameter pointer(s)
776 m_pars.clear();
777 m_pars.push_back(&m_norm);
778 m_pars.push_back(&m_index);
779 m_pars.push_back(&m_ecut);
780 m_pars.push_back(&m_pivot);
781
782 // Copy eval cache
785 m_last_ecut = model.m_last_ecut;
790
791 // Copy MC cache
792 m_mc_emin = model.m_mc_emin;
793 m_mc_emax = model.m_mc_emax;
797
798 // Return
799 return;
800}
801
802
803/***********************************************************************//**
804 * @brief Delete class members
805 ***************************************************************************/
807{
808 // Return
809 return;
810}
811
812
813/***********************************************************************//**
814 * @brief Update eval precomputation cache
815 *
816 * @param[in] energy Energy.
817 *
818 * Updates the precomputation cache for eval() method.
819 ***************************************************************************/
821{
822 // Get parameter values (takes 3 multiplications which are difficult
823 // to avoid)
824 double index = m_index.value();
825 double ecut = m_ecut.value();
826 double pivot = m_pivot.value();
827
828 // If the energy or one of the parameters index, cut-off or pivot
829 // energy has changed then recompute the cache
830 if ((m_last_energy != energy) ||
831 (m_last_index != index) ||
832 (m_last_ecut != ecut) ||
833 (m_last_pivot != pivot)) {
834
835 // Store actual energy and parameter values
836 m_last_energy = energy;
838 m_last_ecut = ecut;
840
841 // Compute and store value
842 double eng = energy.MeV();
846 std::exp(-m_last_e_cut);
847 } // endif: recomputation was required
848
849 // Return
850 return;
851}
852
853
854/***********************************************************************//**
855 * @brief Update Monte Carlo pre computation cache
856 *
857 * @param[in] emin Minimum photon energy.
858 * @param[in] emax Maximum photon energy.
859 *
860 * Updates the precomputation cache for Monte Carlo simulations.
861 ***************************************************************************/
863 const GEnergy& emax) const
864
865{
866 // Case A: Index is not -1
867 if (index() != -1.0) {
868
869 // Change in energy boundaries?
870 if (emin.MeV() != m_mc_emin || emax.MeV() != m_mc_emax) {
871 m_mc_emin = emin.MeV();
872 m_mc_emax = emax.MeV();
873 m_mc_exponent = index() + 1.0;
876 }
877
878 }
879
880 // Case B: Index is -1
881 else {
882
883 // Change in energy boundaries?
884 if (emin.MeV() != m_mc_emin || emax.MeV() != m_mc_emax) {
885 m_mc_emin = emin.MeV();
886 m_mc_emax = emax.MeV();
887 m_mc_exponent = 0.0;
888 m_mc_pow_emin = std::log(m_mc_emin);
890 }
891
892 }
893
894 // Return
895 return;
896}
897
898
899/***********************************************************************//**
900 * @brief Kernel for photon flux integration
901 *
902 * @param[in] energy Energy (MeV).
903 ***************************************************************************/
905{
906 // Evaluate function value
907 double e_norm = energy * m_inv_pivot;
908 double e_cut = energy * m_inv_ecut;
909 double power = std::pow(e_norm, m_index) * std::exp(-e_cut);
910 double value = m_norm * power;
911
912 // Return value
913 return value;
914}
915
916
917/***********************************************************************//**
918 * @brief Kernel for energy flux integration
919 *
920 * @param[in] energy Energy (MeV).
921 ***************************************************************************/
923{
924 // Evaluate function value
925 double e_norm = energy * m_inv_pivot;
926 double e_cut = energy * m_inv_ecut;
927 double power = std::pow(e_norm, m_index) * std::exp(-e_cut);
928 double value = m_norm * power * energy;
929
930 // Return value
931 return value;
932}
#define G_WRITE
#define G_READ
Exception handler interface definition.
Integration class interface definition.
const GModelSpectralExpPlaw g_spectral_eplaw_seed1("ExponentialCutoffPowerLaw", "Prefactor", "Index", "PivotEnergy", "CutoffEnergy")
Exponential cut off power law spectral class interface definition.
Spectral model registry class definition.
Random number generator class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
double norm(const GVector &vector)
Computes vector norm.
Definition GVector.cpp:864
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
double MeV(void) const
Return energy in MeV.
Definition GEnergy.cpp:321
std::string print(const GChatter &chatter=NORMAL) const
Print energy.
Definition GEnergy.cpp:748
void clear(void)
Clear instance.
Definition GEnergy.cpp:261
GIntegral class interface definition.
Definition GIntegral.hpp:46
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
double eval(const double &eng)
Kernel for energy flux integration.
double eval(const double &eng)
Kernel for photon flux integration.
Exponential cut off power law spectral class.
double m_last_ecut
Last energy cut-off parameter.
double prefactor(void) const
Return pre factor.
double m_mc_emin
Minimum energy.
virtual double flux(const GEnergy &emin, const GEnergy &emax) const
Returns model photon flux between [emin, emax] (units: ph/cm2/s)
void copy_members(const GModelSpectralExpPlaw &model)
Copy class members.
double m_mc_pow_emin
Power of minimum energy.
GEnergy m_last_energy
Last energy value.
virtual GModelSpectralExpPlaw & operator=(const GModelSpectralExpPlaw &model)
Assignment operator.
void free_members(void)
Delete class members.
GModelPar m_norm
Normalization factor.
GEnergy pivot(void) const
Return pivot energy.
GModelPar m_pivot
Pivot energy.
double index(void) const
Return power law index.
double m_mc_exponent
Exponent (index+1)
double m_mc_emax
Maximum energy.
virtual void read(const GXmlElement &xml)
Read model from XML element.
void update_eval_cache(const GEnergy &energy) const
Update eval precomputation cache.
virtual ~GModelSpectralExpPlaw(void)
Destructor.
GModelSpectralExpPlaw(void)
Void constructor.
virtual GEnergy mc(const GEnergy &emin, const GEnergy &emax, const GTime &time, GRan &ran) const
Returns MC energy between [emin, emax].
virtual void clear(void)
Clear exponentially cut off power law model.
std::string m_type
Model type.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const
Evaluate function.
void update_mc_cache(const GEnergy &emin, const GEnergy &emax) const
Update Monte Carlo pre computation cache.
virtual std::string type(void) const
Return model type.
double m_last_e_cut
Last E/Ecut value.
double m_mc_pow_ewidth
Power of energy width.
virtual void write(GXmlElement &xml) const
Write model into XML element.
GModelPar m_index
Spectral index.
virtual double eflux(const GEnergy &emin, const GEnergy &emax) const
Returns model energy flux between [emin, emax] (units: erg/cm2/s)
void init_members(void)
Initialise class members.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print model information.
virtual GModelSpectralExpPlaw * clone(void) const
Clone exponentially cut off power law model.
GEnergy cutoff(void) const
Return exponential cut-off energy.
double m_last_index
Last index parameter.
GModelPar m_ecut
Exponential cut off energy.
double m_last_pivot
Last pivot parameter.
double m_last_e_norm
Last E/Epivot value.
double m_last_power
Last power value.
Interface definition for the spectral model registry class.
Abstract spectral model base class.
void free_members(void)
Delete class members.
virtual GModelSpectral & operator=(const GModelSpectral &model)
Assignment operator.
std::vector< GModelPar * > m_pars
Parameter pointers.
void autoscale(void)
Autoscale parameters.
int size(void) const
Return number of parameters.
void init_members(void)
Initialise class members.
const double & factor_value(void) const
Return parameter factor value.
bool is_free(void) const
Signal if parameter is free.
void free(void)
Free a parameter.
const double & scale(void) const
Return parameter scale.
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
void range(const double &min, const double &max)
Set minimum and maximum parameter boundaries.
const std::string & unit(void) const
Return parameter unit.
double min(void) const
Return parameter minimum boundary.
const double & factor_gradient(void) const
Return parameter factor gradient.
void fix(void)
Fix a parameter.
double gradient(void) const
Return parameter gradient.
void clear(void)
Clear parameter.
double value(void) const
Return parameter value.
const std::string & name(void) const
Return parameter name.
Random number generator class.
Definition GRan.hpp:44
double uniform(void)
Returns random double precision floating value in range 0 to 1.
Definition GRan.cpp:242
Time class.
Definition GTime.hpp:55
std::string print(const GChatter &chatter=NORMAL) const
Print time.
Definition GTime.cpp:1188
XML element node class.
void check_energy_interval(const std::string &origin, const GEnergy &emin, const GEnergy &emax)
Checks energy interval.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition GTools.hpp:184
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition GTools.hpp:201
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
const GXmlElement * xml_get_par(const std::string &origin, const GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
Definition GTools.cpp:1689
GXmlElement * xml_need_par(const std::string &origin, GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
Definition GTools.cpp:1637
void xml_check_parnum(const std::string &origin, const GXmlElement &xml, const int &number)
Checks number of parameters.
Definition GTools.cpp:1777
const double MeV2erg
Definition GTools.hpp:45
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.
Definition GTools.cpp:1819