GammaLib 2.0.0
Loading...
Searching...
No Matches
GModelSpectralBins.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GModelSpectralBins.cpp - Spectral bins model class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 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 GModelSpectralBins.cpp
23 * @brief Spectral bins model 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 "GEbounds.hpp"
38
39/* __ Constants __________________________________________________________ */
40
41/* __ Globals ____________________________________________________________ */
43const GModelSpectralRegistry g_spectral_bins_registry(&g_spectral_bins_seed);
44
45/* __ Method name definitions ____________________________________________ */
46#define G_FLUX "GModelSpectralBins::flux(GEnergy&, GEnergy&)"
47#define G_EFLUX "GModelSpectralBins::eflux(GEnergy&, GEnergy&)"
48#define G_MC "GModelSpectralBins::mc(GEnergy&, GEnergy&, GTime&, GRan&)"
49#define G_READ "GModelSpectralBins::read(GXmlElement&)"
50#define G_WRITE "GModelSpectralBins::write(GXmlElement&)"
51#define G_APPEND "GModelSpectralBins::append(GEnergy&, GEnergy&, double&)"
52#define G_INSERT "GModelSpectralBins::insert(int&, GEnergy&, GEnergy&, "\
53 "double&)"
54#define G_REMOVE "GModelSpectralBins::remove(int&)"
55#define G_EMIN_GET "GModelSpectralBins::emin(int&)"
56#define G_EMAX_GET "GModelSpectralBins::emax(int&)"
57#define G_EMIN_SET "GModelSpectralBins::emin(int&, GEnergy&)"
58#define G_EMAX_SET "GModelSpectralBins::emax(int&, GEnergy&)"
59#define G_INTENSITY_GET "GModelSpectralBins::intensity(int&)"
60#define G_INTENSITY_SET "GModelSpectralBins::intensity(int&, double&)"
61#define G_ERROR_GET "GModelSpectralBins::error(int&)"
62
63/* __ Macros _____________________________________________________________ */
64
65/* __ Coding definitions _________________________________________________ */
66
67/* __ Debug definitions __________________________________________________ */
68
69
70/*==========================================================================
71 = =
72 = Constructors/destructors =
73 = =
74 ==========================================================================*/
75
76/***********************************************************************//**
77 * @brief Void constructor
78 *
79 * Constructs an empty spectral bin model.
80 ***************************************************************************/
82{
83 // Initialise members
85
86 // Return
87 return;
88}
89
90
91/***********************************************************************//**
92 * @brief Spectral model constructor
93 *
94 * @param[in] model Spectral model.
95 * @param[in] ebounds Energy boundaries.
96 * @param[in] index Spectral index.
97 *
98 * Constructs a spectral bins model from any spectral model using the
99 * energy boundaries that are specified by @p ebounds. Within each spectral
100 * bin the intensity follows a power law with spectral index @p index.
101 ***************************************************************************/
103 const GEbounds& ebounds,
104 const double& index) :
106{
107 // Initialise members
108 init_members();
109
110 // Append bins for all energies
111 for (int i = 0; i < ebounds.size(); ++i) {
112 append(ebounds.emin(i), ebounds.emax(i), model.eval(ebounds.elogmean(i)));
113 }
114
115 // Store index
116 this->index(index);
117
118 // Return
119 return;
120}
121
122
123/***********************************************************************//**
124 * @brief XML constructor
125 *
126 * @param[in] xml XML element.
127 *
128 * Construct spectral bins model by extracting information from an XML
129 * element. See the read() method for more information about the expected
130 * structure of the XML element.
131 ***************************************************************************/
134{
135 // Initialise members
136 init_members();
137
138 // Read information from XML element
139 read(xml);
140
141 // Return
142 return;
143}
144
145
146/***********************************************************************//**
147 * @brief Copy constructor
148 *
149 * @param[in] model Spectral bins model.
150 ***************************************************************************/
152 GModelSpectral(model)
153{
154 // Initialise members
155 init_members();
156
157 // Copy members
158 copy_members(model);
159
160 // Return
161 return;
162}
163
164
165/***********************************************************************//**
166 * @brief Destructor
167 ***************************************************************************/
169{
170 // Free members
171 free_members();
172
173 // Return
174 return;
175}
176
177
178/*==========================================================================
179 = =
180 = Operators =
181 = =
182 ==========================================================================*/
183
184/***********************************************************************//**
185 * @brief Assignment operator
186 *
187 * @param[in] model Spectral bins model.
188 * @return Spectral bins model.
189 ***************************************************************************/
191{
192 // Execute only if object is not identical
193 if (this != &model) {
194
195 // Copy base class members
196 this->GModelSpectral::operator=(model);
197
198 // Free members
199 free_members();
200
201 // Initialise members
202 init_members();
203
204 // Copy members
205 copy_members(model);
206
207 } // endif: object was not identical
208
209 // Return
210 return *this;
211}
212
213
214/*==========================================================================
215 = =
216 = Public methods =
217 = =
218 ==========================================================================*/
219
220/***********************************************************************//**
221 * @brief Clear spectral bins model
222 ***************************************************************************/
224{
225 // Free class members (base and derived classes, derived class first)
226 free_members();
228
229 // Initialise members
231 init_members();
232
233 // Return
234 return;
235}
236
237
238/***********************************************************************//**
239 * @brief Clone spectral bins model
240***************************************************************************/
242{
243 // Clone spectral bins model
244 return new GModelSpectralBins(*this);
245}
246
247
248/***********************************************************************//**
249 * @brief Evaluate function
250 *
251 * @param[in] srcEng True photon energy.
252 * @param[in] srcTime True photon arrival time.
253 * @param[in] gradients Compute gradients?
254 * @return Model value (ph/cm2/s/MeV).
255 *
256 * @todo Document method.
257 ***************************************************************************/
259 const GTime& srcTime,
260 const bool& gradients) const
261{
262 // Initialise value
263 double value = 0.0;
264
265 // Optionally initialise partial derivatives
266 if (gradients) {
268 for (int i = 0; i < m_values.size(); ++i) {
269 m_values[i].factor_gradient(0.0);
270 }
271 }
272
273 // Get bin index
274 int ibin = bin_index(srcEng);
275
276 // Continue only if index is valid
277 if (ibin >= 0) {
278
279 // Get power-law index
280 double index = m_index.value();
281
282 // Compute and store value
283 double eng = srcEng.MeV();
284 double e_norm = eng / m_epivot[ibin];
285 double power = (index != 0.0) ? std::pow(e_norm, index) : 1.0;
286
287 // Compute function value
288 value = m_values[ibin].value() * power;
289
290 // Compute gradients
291 if (gradients) {
292
293 // Compute partial derivatives of the parameter values
294 double g_norm = (m_values[ibin].is_free())
295 ? m_values[ibin].scale() * power : 0.0;
296 double g_index = (m_index.is_free())
297 ? value * m_index.scale() * std::log(e_norm) : 0.0;
298
299 // Set gradients
300 m_values[ibin].factor_gradient(g_norm);
301 m_index.factor_gradient(g_index);
302
303 } // endif: gradient computation was requested
304
305 // Compile option: Check for NaN/Inf
306 #if defined(G_NAN_CHECK)
307 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
308 std::cout << "*** ERROR: GModelSpectralBins::eval";
309 std::cout << "(srcEng=" << srcEng;
310 std::cout << ", srcTime=" << srcTime << "):";
311 std::cout << " NaN/Inf encountered";
312 std::cout << " (value=" << value;
313 std::cout << ", power=" << power;
314 std::cout << ")" << std::endl;
315 }
316 #endif
317
318 } // endif: bin index was valid
319
320 // Return
321 return value;
322}
323
324
325/***********************************************************************//**
326 * @brief Returns model photon flux between [emin, emax] (units: ph/cm2/s)
327 *
328 * @param[in] emin Minimum photon energy.
329 * @param[in] emax Maximum photon energy.
330 * @return Photon flux (ph/cm2/s).
331 *
332 * Computes
333 *
334 * \f[
335 * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) dE
336 * \f]
337 *
338 * where
339 * - [@p emin, @p emax] is an energy interval, and
340 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
341 ***************************************************************************/
343 const GEnergy& emax) const
344{
345 // Initialise flux
346 double flux = 0.0;
347
348 // Compute only if integration range is valid
349 if (emin < emax) {
350
351 // Get energy range in MeV
352 double e_min = emin.MeV();
353 double e_max = emax.MeV();
354
355 // Loop over all bins
356 for (int ibin = 0; ibin < bins(); ++ibin) {
357
358 // Get energy boundaires of bin in MeV
359 double e_bin_min = m_emin[ibin].value();
360 double e_bin_max = m_emax[ibin].value();
361
362 // Skip bins that do not overlap with energy range
363 if (e_min >= e_bin_max || e_max < e_bin_min) {
364 continue;
365 }
366
367 // Raise lower boundary to minimum energy
368 if (e_bin_min < e_min) {
369 e_bin_min = e_min;
370 }
371
372 // Lower upper boundary to maximum energy
373 if (e_bin_max > e_max) {
374 e_bin_max = e_max;
375 }
376
377 // If energy interval is positive then compute flux
378 if (e_bin_max > e_bin_min) {
379
380 // Add photon flux
381 flux += m_values[ibin].value() *
383 e_bin_max,
384 m_epivot[ibin],
385 m_index.value());
386
387 } // endif: energy interval was positive
388
389 } // endfor: looped over all spectral bins
390
391 } // endif: integration range was valid
392
393 // Return
394 return flux;
395}
396
397
398/***********************************************************************//**
399 * @brief Returns model energy flux between [emin, emax] (units: erg/cm2/s)
400 *
401 * @param[in] emin Minimum photon energy.
402 * @param[in] emax Maximum photon energy.
403 * @return Energy flux (erg/cm2/s).
404 *
405 * Computes
406 *
407 * \f[
408 * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) E \, dE
409 * \f]
410 *
411 * where
412 * - [@p emin, @p emax] is an energy interval, and
413 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
414 ***************************************************************************/
416 const GEnergy& emax) const
417{
418 // Initialise flux
419 double eflux = 0.0;
420
421 // Compute only if integration range is valid
422 if (emin < emax) {
423
424
425 // Get energy range in MeV
426 double e_min = emin.MeV();
427 double e_max = emax.MeV();
428
429 // Loop over all bins
430 for (int ibin = 0; ibin < bins(); ++ibin) {
431
432 // Get energy boundaires of bin in MeV
433 double e_bin_min = m_emin[ibin].value();
434 double e_bin_max = m_emax[ibin].value();
435
436 // Skip bins that do not overlap with energy range
437 if (e_min >= e_bin_max || e_max < e_bin_min) {
438 continue;
439 }
440
441 // Raise lower boundary to minimum energy
442 if (e_bin_min < e_min) {
443 e_bin_min = e_min;
444 }
445
446 // Lower upper boundary to maximum energy
447 if (e_bin_max > e_max) {
448 e_bin_max = e_max;
449 }
450
451 // If energy interval is positive then compute flux
452 if (e_bin_max > e_bin_min) {
453
454 // Add energy flux
455 eflux += m_values[ibin].value() *
457 e_bin_max,
458 m_epivot[ibin],
459 m_index.value());
460
461 } // endif: energy interval was positive
462
463 } // endfor: looped over all spectral bins
464
465 // Convert from MeV/cm2/s to erg/cm2/s
467
468 } // endif: integration range was valid
469
470 // Return flux
471 return eflux;
472}
473
474
475/***********************************************************************//**
476 * @brief Returns MC energy between [emin, emax]
477 *
478 * @param[in] emin Minimum photon energy.
479 * @param[in] emax Maximum photon energy.
480 * @param[in] time True photon arrival time.
481 * @param[in,out] ran Random number generator.
482 * @return Energy.
483 *
484 * @exception GException::invalid_return_value
485 * No valid Monte Carlo cache
486 *
487 * Returns Monte Carlo energy by randomly drawing from bin function.
488 ***************************************************************************/
490 const GEnergy& emax,
491 const GTime& time,
492 GRan& ran) const
493{
494 // Check energy interval
496
497 // Allocate energy
498 GEnergy energy;
499
500 // Update cache
502
503 // Determine in which bin we reside. If this fails then thrown an
504 // exception
505 int inx = 0;
506 if (m_mc_cum.size() > 1) {
507 double u = ran.uniform();
508 for (inx = m_mc_cum.size()-1; inx > 0; --inx) {
509 if (m_mc_cum[inx-1] <= u) {
510 break;
511 }
512 }
513 }
514 else if (m_mc_cum.size() == 0) {
515 std::string msg = "No valid bins found for energy interval ["+
516 emin.print()+","+emax.print()+"]. Either restrict "
517 "the energy range to the one covered by the "
518 "spectral bins or extend the spectral bins "
519 "in energy.";
521 }
522
523 // Get random energy for specific bin
524 if (m_mc_exp[inx] != 0.0) {
525 double e_min = m_mc_min[inx];
526 double e_max = m_mc_max[inx];
527 double u = ran.uniform();
528 double eng = (u > 0.0)
529 ? std::exp(std::log(u * (e_max - e_min) + e_min) / m_mc_exp[inx])
530 : 0.0;
531 energy.MeV(eng);
532 }
533 else {
534 double e_min = m_mc_min[inx];
535 double e_max = m_mc_max[inx];
536 double u = ran.uniform();
537 double eng = std::exp(u * (e_max - e_min) + e_min);
538 energy.MeV(eng);
539 }
540
541 // Return energy
542 return energy;
543}
544
545
546/***********************************************************************//**
547 * @brief Read model from XML element
548 *
549 * @param[in] xml XML element.
550 *
551 * @exception GException::invalid_value
552 * Lower energy limit larger than upper energy limit.
553 *
554 * Reads the spectral information from an XML element. The format of the XML
555 * elements is
556 *
557 * <spectrum type="BinFunction">
558 * <parameter name="Index" ../>
559 * <bin>
560 * <parameter name="LowerLimit" ../>
561 * <parameter name="UpperLimit" ../>
562 * <parameter name="Intensity" ../>
563 * </bin>
564 * ...
565 * <bin>
566 * <parameter name="LowerLimit" ../>
567 * <parameter name="UpperLimit" ../>
568 * <parameter name="Intensity" ../>
569 * </bin>
570 * </spectrum>
571 *
572 * @todo Check that bins are ordered
573 * @todo Check that energy boundaries are not overlapping
574 ***************************************************************************/
576{
577 // Free space for bins
578 m_emin.clear();
579 m_emax.clear();
580 m_values.clear();
581
582 // Get index parameter pointer
584
585 // Read index parameter
587
588 // Get number of bins from XML file
589 int bins = xml.elements("bin");
590
591 // Loop over all bins
592 for (int i = 0; i < bins; ++i) {
593
594 // Allocate bin parameters
598
599 // Get bins
600 const GXmlElement* bin = xml.element("bin", i);
601
602 // Get parameters
603 const GXmlElement* lpar = gammalib::xml_get_par(G_READ, *bin, "LowerLimit");
604 const GXmlElement* upar = gammalib::xml_get_par(G_READ, *bin, "UpperLimit");
605 const GXmlElement* ipar = gammalib::xml_get_par(G_READ, *bin, "Intensity");
606
607 // Read parameters
608 emin.read(*lpar);
609 emax.read(*upar);
610 intensity.read(*ipar);
611
612 // Throw an exception if either LowerLimit is larger than UpperLimit
613 if (emin.value() > emax.value()) {
614 std::string msg = "Lower energy limit "+gammalib::str(emin.value())+
615 " MeV is larger than upper energy limit "+
616 gammalib::str(emax.value())+" MeV. Please "
617 "specify lower energy limits that are smaller "
618 "than the upper energy limits.";
620 }
621
622 // Push bin parameters on list
623 m_emin.push_back(emin);
624 m_emax.push_back(emax);
625 m_values.push_back(intensity);
626
627 } // endfor: looped over bins
628
629 // Update parameter mapping
630 update_pars();
631
632 // Set pre-computation cache
633 set_cache();
634
635 // Return
636 return;
637}
638
639
640/***********************************************************************//**
641 * @brief Write model into XML element
642 *
643 * @param[in] xml XML element into which model information is written.
644 *
645 * @exception GException::invalid_value
646 * Existing XML element is not of required type
647 * Invalid number of model parameters or bins found in XML element.
648 *
649 * Writes the spectral information into an XML element. The format of the XML
650 * element is
651 *
652 * <spectrum type="BinFunction">
653 * <parameter name="Index" ../>
654 * <bin>
655 * <parameter name="LowerLimit" ../>
656 * <parameter name="UpperLimit" ../>
657 * <parameter name="Intensity" ../>
658 * </bin>
659 * ...
660 * <bin>
661 * <parameter name="LowerLimit" ../>
662 * <parameter name="UpperLimit" ../>
663 * <parameter name="Intensity" ../>
664 * </bin>
665 * </spectrum>
666 ***************************************************************************/
668{
669 // Verify model type
671
672 // Get index parameter
674
675 // Write index parameter
677
678 // Determine number of bins
679 int bins = this->bins();
680
681 // If XML element has 0 bins then append bins
682 if (xml.elements("bin") == 0) {
683 for (int i = 0; i < bins; ++i) {
684 xml.append(GXmlElement("bin"));
685 }
686 }
687
688 // Verify that XML element has the required number of bins and elements.
689 // Recall that the power-law index also counts as one element.
690 if (xml.elements() != bins+1) {
691 std::string msg = "Spectral bins model contains "+
692 gammalib::str(xml.elements())+
693 " elements but "+gammalib::str(bins+1)+" elements "
694 "were expected.";
696 }
697 if (xml.elements("bin") != bins) {
698 std::string msg = "Spectral bins model contains "+
699 gammalib::str(xml.elements("bin"))+
700 " \"bin\" elements but "+gammalib::str(bins)+
701 " \"bin\" elements were expected.";
703 }
704
705 // Loop over all bins
706 for (int i = 0; i < bins; ++i) {
707
708 // Get bins
709 GXmlElement* bin = xml.element("bin", i);
710
711 // Get copy of parameters so that we can change their names
712 GModelPar emin = m_emin[i];
713 GModelPar emax = m_emax[i];
715
716 // Set names since we appended for internal usage the indices to the
717 // parameter names, and we want to get rid of them for writing the
718 // model into the XML element
719 emin.name("LowerLimit");
720 emax.name("UpperLimit");
721 intensity.name("Intensity");
722
723 // Get XML parameters
724 GXmlElement* lpar = gammalib::xml_need_par(G_WRITE, *bin, emin.name());
725 GXmlElement* upar = gammalib::xml_need_par(G_WRITE, *bin, emax.name());
727
728 // Write parameters
729 emin.write(*lpar);
730 emax.write(*upar);
731 intensity.write(*ipar);
732
733 } // endfor: looped over bins
734
735 // Return
736 return;
737}
738
739
740/***********************************************************************//**
741 * @brief Append bin
742 *
743 * @param[in] emin Lower energy limit.
744 * @param[in] emax Upper energy limit.
745 * @param[in] intensity Bin intensity.
746 *
747 * @exception GException::invalid_argument
748 * Lower energy limit is larger than upper energy limit.
749 *
750 * Appends one bin to the bin function. By default the lower and upper energy
751 * limit of the bin is fixed while the intensity of the bin is free.
752 ***************************************************************************/
754 const GEnergy& emax,
755 const double& intensity)
756{
757 // Throw an exception if lower limit is larger than upper limit
758 if (emin > emax) {
759 std::string msg = "Lower energy limit "+emin.print()+" is larger than "
760 "upper energy limit "+emax.print()+". Please "
761 "specify a lower energy limit that is smaller "
762 "than the upper energy limit.";
764 }
765
766 // Allocate bin parameters
767 GModelPar par_emin;
768 GModelPar par_emax;
769 GModelPar par_intensity;
770
771 // Set emin attributes
772 par_emin.name("LowerLimit");
773 par_emin.value(emin.MeV());
774 par_emin.unit("MeV");
775 par_emin.has_grad(false);
776 par_emin.fix();
777
778 // Set emax attributes
779 par_emax.name("UpperLimit");
780 par_emax.value(emax.MeV());
781 par_emax.unit("MeV");
782 par_emax.has_grad(false);
783 par_emax.fix();
784
785 // Set intensity attributes
786 par_intensity.name("Intensity");
787 par_intensity.value(intensity);
788 par_intensity.unit("ph/cm2/s/MeV");
789 par_intensity.has_grad(true);
790 par_intensity.free();
791
792 // Append to bins
793 m_emin.push_back(par_emin);
794 m_emax.push_back(par_emax);
795 m_values.push_back(par_intensity);
796
797 // Update parameter mapping
798 update_pars();
799
800 // Set pre-computation cache
801 set_cache();
802
803 // Return
804 return;
805}
806
807
808/***********************************************************************//**
809 * @brief Insert bin
810 *
811 * @param[in] index Bin index [0,...,bins()-1].
812 * @param[in] emin Lower energy limit.
813 * @param[in] emax Upper energy limit.
814 * @param[in] intensity Bin intensity.
815 *
816 * @exception GException::out_of_range
817 * Bin index is out of range.
818 * @exception GException::invalid_argument
819 * Lower energy limit is larger than upper energy limit.
820 *
821 * Inserts a bin into the bin function before the bin with the specified
822 * @p index. By default the lower and upper energy limit of the bin is fixed
823 * while the intensity of the bin is free.
824 ***************************************************************************/
825void GModelSpectralBins::insert(const int& index,
826 const GEnergy& emin,
827 const GEnergy& emax,
828 const double& intensity)
829{
830 // Raise exception if index is outside boundary
831 #if defined(G_RANGE_CHECK)
832 if (index < 0 || index >= bins()) {
833 throw GException::out_of_range(G_INSERT, "Bin index", index, bins());
834 }
835 #endif
836
837 // Throw an exception if lower limit is larger than upper limit
838 if (emin > emax) {
839 std::string msg = "Lower energy limit "+emin.print()+" is larger than "
840 "upper energy limit "+emax.print()+". Please "
841 "specify a lower energy limit that is smaller "
842 "than the upper energy limit.";
844 }
845
846 // Allocate bin parameters
847 GModelPar par_emin;
848 GModelPar par_emax;
849 GModelPar par_intensity;
850
851 // Set emin attributes
852 par_emin.name("LowerLimit");
853 par_emin.value(emin.MeV());
854 par_emin.unit("MeV");
855 par_emin.has_grad(false);
856 par_emin.fix();
857
858 // Set emax attributes
859 par_emax.name("UpperLimit");
860 par_emax.value(emax.MeV());
861 par_emax.unit("MeV");
862 par_emax.has_grad(false);
863 par_emax.fix();
864
865 // Set intensity attributes
866 par_intensity.name("Intensity");
867 par_intensity.value(intensity);
868 par_intensity.unit("ph/cm2/s/MeV");
869 par_intensity.has_grad(true);
870 par_intensity.free();
871
872 // Insert bin
873 m_emin.insert(m_emin.begin()+index, par_emin);
874 m_emax.insert(m_emax.begin()+index, par_emax);
875 m_values.insert(m_values.begin()+index, par_intensity);
876
877 // Update parameter mapping
878 update_pars();
879
880 // Set pre-computation cache
881 set_cache();
882
883 // Return
884 return;
885}
886
887
888/***********************************************************************//**
889 * @brief Remove bin
890 *
891 * @param[in] index Bin index [0,...,bins()-1].
892 *
893 * @exception GException::out_of_range
894 * Bin index is out of range.
895 *
896 * Removes bin of specified @p index from the bin function.
897 ***************************************************************************/
898void GModelSpectralBins::remove(const int& index)
899{
900 // Raise exception if index is outside boundary
901 #if defined(G_RANGE_CHECK)
902 if (index < 0 || index >= bins()) {
903 throw GException::out_of_range(G_REMOVE, "Bin index", index, bins());
904 }
905 #endif
906
907 // Erase energy and intensity
908 m_emin.erase(m_emin.begin() + index);
909 m_emax.erase(m_emax.begin() + index);
910 m_values.erase(m_values.begin() + index);
911
912 // Update parameter mapping
913 update_pars();
914
915 // Set pre-computation cache
916 set_cache();
917
918 // Return
919 return;
920}
921
922
923/***********************************************************************//**
924 * @brief Reserve space for bins
925 *
926 * @param[in] num Number of reserved bins.
927 *
928 * Reserves space for @p num bins.
929 ***************************************************************************/
930void GModelSpectralBins::reserve(const int& num)
931{
932 // Reserve space
933 m_emin.reserve(num);
934 m_emax.reserve(num);
935 m_values.reserve(num);
936
937 // Return
938 return;
939}
940
941
942/***********************************************************************//**
943 * @brief Append bins from bin function
944 *
945 * @param[in] bins Bin function.
946 *
947 * Appends all bins from a bin function to current object.
948 ***************************************************************************/
950{
951 // Get number of bins in bin function. Note that we extract the size
952 // first to avoid an endless loop that arises when a container is
953 // appended to itself.
954 int num = bins.bins();
955
956 // Continue only if bin function is not empty
957 if (num > 0) {
958
959 // Reserve enough space
960 reserve(this->bins() + num);
961
962 // Loop over all bins and append them to the bin function
963 for (int i = 0; i < num; ++i) {
964 m_emin.push_back(bins.m_emin[i]);
965 m_emax.push_back(bins.m_emax[i]);
966 m_values.push_back(bins.m_values[i]);
967 }
968
969 // Update parameter mapping
970 update_pars();
971
972 // Set pre-computation cache
973 set_cache();
974
975 } // endif: bin function was not empty
976
977 // Return
978 return;
979}
980
981
982/***********************************************************************//**
983 * @brief Return spectral power law index
984 *
985 * @return Spectrel power law index.
986 *
987 * Returns the spectral power law index.
988 ***************************************************************************/
990{
991 // Return spectral power law index
992 return (m_index.value());
993}
994
995
996/***********************************************************************//**
997 * @brief Set spectral power law index
998 *
999 * @param[in] index Spectrel power law index.
1000 *
1001 * Set spectral power law index.
1002 ***************************************************************************/
1003void GModelSpectralBins::index(const double& index)
1004{
1005 // Set m_index
1007
1008 // Return
1009 return;
1010}
1011
1012
1013/***********************************************************************//**
1014 * @brief Return lower energy limit of bin
1015 *
1016 * @param[in] index Bin index [0,...,bins()-1].
1017 * @return Lower energy limit of bin @p index.
1018 *
1019 * @exception GException::out_of_range
1020 * Index is out of range.
1021 *
1022 * Returns the lower energy limit of bin @p index.
1023 ***************************************************************************/
1024GEnergy GModelSpectralBins::emin(const int& index) const
1025{
1026 // Raise an exception if index is out of range
1027 #if defined(G_RANGE_CHECK)
1028 if (index < 0 || index >= bins()) {
1029 throw GException::out_of_range(G_EMIN_GET, "Bin index", index, bins());
1030 }
1031 #endif
1032
1033 // Retrieve energy
1034 GEnergy energy;
1035 energy.MeV(m_emin[index].value());
1036
1037 // Return energy
1038 return energy;
1039}
1040
1041
1042/***********************************************************************//**
1043 * @brief Return upper energy limit of bin
1044 *
1045 * @param[in] index Bin index [0,...,bins()-1].
1046 * @return Upper energy limit of bin @p index.
1047 *
1048 * @exception GException::out_of_range
1049 * Index is out of range.
1050 *
1051 * Returns the upper energy limit of bin @p index.
1052 ***************************************************************************/
1053GEnergy GModelSpectralBins::emax(const int& index) const
1054{
1055 // Raise an exception if index is out of range
1056 #if defined(G_RANGE_CHECK)
1057 if (index < 0 || index >= bins()) {
1058 throw GException::out_of_range(G_EMAX_GET, "Bin index", index, bins());
1059 }
1060 #endif
1061
1062 // Retrieve energy
1063 GEnergy energy;
1064 energy.MeV(m_emax[index].value());
1065
1066 // Return energy
1067 return energy;
1068}
1069
1070
1071/***********************************************************************//**
1072 * @brief Set lower energy limit of bin
1073 *
1074 * @param[in] index Bin index [0,...,bins()-1].
1075 * @param[in] emin Lower energy limit of bin @p index.
1076 *
1077 * @exception GException::out_of_range
1078 * Index is out of range.
1079 *
1080 * Sets the lower energy limit of bin @p index.
1081 ***************************************************************************/
1082void GModelSpectralBins::emin(const int& index, const GEnergy& emin)
1083{
1084 // Raise an exception if index is out of range
1085 #if defined(G_RANGE_CHECK)
1086 if (index < 0 || index >= bins()) {
1087 throw GException::out_of_range(G_EMIN_SET, "Bin index", index, bins());
1088 }
1089 #endif
1090
1091 // Set energy
1092 m_emin[index].value(emin.MeV());
1093
1094 // Set pre-computation cache
1095 set_cache();
1096
1097 // Return
1098 return;
1099}
1100
1101
1102/***********************************************************************//**
1103 * @brief Set upper energy limit of bin
1104 *
1105 * @param[in] index Bin index [0,...,bins()-1].
1106 * @param[in] emax Upper energy limit of bin @p index.
1107 *
1108 * @exception GException::out_of_range
1109 * Index is out of range.
1110 *
1111 * Sets the upper energy limit of bin @p index.
1112 ***************************************************************************/
1113void GModelSpectralBins::emax(const int& index, const GEnergy& emax)
1114{
1115 // Raise an exception if index is out of range
1116 #if defined(G_RANGE_CHECK)
1117 if (index < 0 || index >= bins()) {
1118 throw GException::out_of_range(G_EMAX_SET, "Bin index", index, bins());
1119 }
1120 #endif
1121
1122 // Set energy
1123 m_emax[index].value(emax.MeV());
1124
1125 // Set pre-computation cache
1126 set_cache();
1127
1128 // Return
1129 return;
1130}
1131
1132
1133/***********************************************************************//**
1134 * @brief Return bin intensity
1135 *
1136 * @param[in] index Bin index [0,...,bins()-1].
1137 * @return Intensity of bin @p index.
1138 *
1139 * @exception GException::out_of_range
1140 * Index is out of range.
1141 *
1142 * Returns the intensity of bin @p index.
1143 ***************************************************************************/
1144double GModelSpectralBins::intensity(const int& index) const
1145{
1146 // Raise an exception if index is out of range
1147 #if defined(G_RANGE_CHECK)
1148 if (index < 0 || index >= bins()) {
1149 throw GException::out_of_range(G_INTENSITY_GET, "Bin index", index, bins());
1150 }
1151 #endif
1152
1153 // Return intensity
1154 return (m_values[index].value());
1155}
1156
1157
1158/***********************************************************************//**
1159 * @brief Return intensity error of bin
1160 *
1161 * @param[in] index Bin index [0,...,bins()-1].
1162 * @return Intensity error of bin @p index.
1163 *
1164 * @exception GException::out_of_range
1165 * Index is out of range.
1166 *
1167 * Returns the intensity error of bin @p index.
1168 ***************************************************************************/
1169double GModelSpectralBins::error(const int& index) const
1170{
1171 // Raise an exception if index is out of range
1172 #if defined(G_RANGE_CHECK)
1173 if (index < 0 || index >= bins()) {
1174 throw GException::out_of_range(G_ERROR_GET, "Bin index", index, bins());
1175 }
1176 #endif
1177
1178 // Return intensity error
1179 return (m_values[index].error());
1180}
1181
1182
1183/***********************************************************************//**
1184 * @brief Set bin intensity
1185 *
1186 * @param[in] index Bin index [0,...,bins()-1].
1187 * @param[in] intensity Intensity of bin @p index.
1188 *
1189 * @exception GException::out_of_range
1190 * Index is out of range.
1191 *
1192 * Set the intensity of bin @p index.
1193 ***************************************************************************/
1194void GModelSpectralBins::intensity(const int& index, const double& intensity)
1195{
1196 // Raise an exception if index is out of range
1197 #if defined(G_RANGE_CHECK)
1198 if (index < 0 || index >= bins()) {
1199 throw GException::out_of_range(G_INTENSITY_SET, "Bin index", index, bins());
1200 }
1201 #endif
1202
1203 // Set intensity
1204 m_values[index].value(intensity);
1205
1206 // Return
1207 return;
1208}
1209
1210
1211/***********************************************************************//**
1212 * @brief Print bin function information
1213 *
1214 * @param[in] chatter Chattiness.
1215 * @return String containing bin function information.
1216 ***************************************************************************/
1217std::string GModelSpectralBins::print(const GChatter& chatter) const
1218{
1219 // Initialise result string
1220 std::string result;
1221
1222 // Continue only if chatter is not silent
1223 if (chatter != SILENT) {
1224
1225 // Append header
1226 result.append("=== GModelSpectralBins ===");
1227
1228 // Append information
1229 result.append("\n"+gammalib::parformat("Number of bins"));
1230 result.append(gammalib::str(bins()));
1231 result.append("\n"+gammalib::parformat("Number of parameters"));
1232 result.append(gammalib::str(size()));
1233 for (int i = 0; i < size(); ++i) {
1234 result.append("\n"+m_pars[i]->print(chatter));
1235 }
1236
1237 } // endif: chatter was not silent
1238
1239 // Return result
1240 return result;
1241}
1242
1243
1244/*==========================================================================
1245 = =
1246 = Private methods =
1247 = =
1248 ==========================================================================*/
1249
1250/***********************************************************************//**
1251 * @brief Initialise class members
1252 ***************************************************************************/
1254{
1255 // Initialise powerlaw index
1256 m_index.clear();
1257 m_index.name("Index");
1258 m_index.scale(1.0);
1259 m_index.value(-2.0); // default: -2.0
1260 m_index.range(-10.0,+10.0); // range: [-10,+10]
1261 m_index.fix();
1262 m_index.gradient(0.0);
1263 m_index.has_grad(true);
1264
1265 // Initialise bin parameter vectors
1266 m_emin.clear();
1267 m_emax.clear();
1268 m_values.clear();
1269
1270 // Initialise evaluation cache
1271 m_epivot.clear();
1272
1273 // Initialise MC cache
1274 m_mc_emin.clear();
1275 m_mc_emax.clear();
1276 m_mc_cum.clear();
1277 m_mc_min.clear();
1278 m_mc_max.clear();
1279 m_mc_exp.clear();
1280
1281 // Update parameter mapping
1282 update_pars();
1283
1284 // Return
1285 return;
1286}
1287
1288
1289/***********************************************************************//**
1290 * @brief Copy class members
1291 *
1292 * @param[in] model Spectral bin function.
1293 ***************************************************************************/
1295{
1296 // Copy bin energies and values
1297 m_index = model.m_index;
1298 m_emin = model.m_emin;
1299 m_emax = model.m_emax;
1300 m_values = model.m_values;
1301
1302 // Copy evluation cache
1303 m_epivot = model.m_epivot;
1304
1305 // Copy MC cache
1306 m_mc_emin = model.m_mc_emin;
1307 m_mc_emax = model.m_mc_emax;
1308 m_mc_cum = model.m_mc_cum;
1309 m_mc_min = model.m_mc_min;
1310 m_mc_max = model.m_mc_max;
1311 m_mc_exp = model.m_mc_exp;
1312
1313 // Update parameter mapping
1314 update_pars();
1315
1316 // Return
1317 return;
1318}
1319
1320
1321/***********************************************************************//**
1322 * @brief Delete class members
1323 ***************************************************************************/
1325{
1326 // Return
1327 return;
1328}
1329
1330
1331/***********************************************************************//**
1332 * @brief Return bin index for energy
1333 *
1334 * @param[in] energy Energy.
1335 * @return Bin index (-1 if energy bin was not found).
1336 ***************************************************************************/
1338{
1339 // Initialise bin index
1340 int bin = -1;
1341
1342 // Get energy in MeV
1343 double energy_MeV = energy.MeV();
1344
1345 // Search bin index
1346 for (int i = 0; i < bins(); ++i) {
1347 if (energy_MeV >= m_emin[i].value() && energy_MeV < m_emax[i].value()) {
1348 bin = i;
1349 break;
1350 }
1351 }
1352
1353 // Return bin index
1354 return bin;
1355}
1356
1357
1358/***********************************************************************//**
1359 * @brief Update parameter mapping
1360 *
1361 * Sets the parameter pointers in the m_pars array, enabling iterating over
1362 * all model parameters. This method needs to be called after changing the
1363 * number of bins in the spectral model. The method needs not to be called
1364 * after value update.
1365 ***************************************************************************/
1367{
1368 // Clear parameter pointer(s)
1369 m_pars.clear();
1370
1371 // Push back common spectral index
1372 m_pars.push_back(&m_index);
1373
1374 // Set parameter pointers for all bins
1375 for (int i = 0; i < bins(); ++i) {
1376
1377 // Set parameter names
1378 std::string lowerlimit_name = "LowerLimit" + gammalib::str(i);
1379 std::string upperlimit_name = "UpperLimit" + gammalib::str(i);
1380 std::string intensity_name = "Intensity" + gammalib::str(i);
1381
1382 // Set lower limit attributes
1383 m_emin[i].name(lowerlimit_name);
1384 m_emin[i].unit("MeV");
1385 m_emin[i].has_grad(false);
1386
1387 // Set upper limit attributes
1388 m_emax[i].name(upperlimit_name);
1389 m_emax[i].unit("MeV");
1390 m_emax[i].has_grad(false);
1391
1392 // Set intensity attributes
1393 m_values[i].name(intensity_name);
1394 m_values[i].unit("ph/cm2/s/MeV");
1395 m_values[i].has_grad(true);
1396
1397 // Set pointer
1398 m_pars.push_back(&(m_emin[i]));
1399 m_pars.push_back(&(m_emax[i]));
1400 m_pars.push_back(&(m_values[i]));
1401
1402 } // endfor: looped over bins
1403
1404 // Return
1405 return;
1406}
1407
1408
1409/***********************************************************************//**
1410 * @brief Set cache
1411 *
1412 * Sets the computation cache. The method computes for the time being the
1413 * pivot energies for all bins in MeV.
1414 ***************************************************************************/
1416{
1417 // Clear cache
1418 m_epivot.clear();
1419
1420 // Compute pivot energies for all bins
1421 for (int i = 0; i < bins(); ++i) {
1422 double epivot = std::sqrt(m_emin[i].value() * m_emax[i].value());
1423 m_epivot.push_back(epivot);
1424 }
1425
1426 // Return
1427 return;
1428}
1429
1430
1431/***********************************************************************//**
1432 * @brief Set MC pre-computation cache
1433 *
1434 * @param[in] emin Minimum energy.
1435 * @param[in] emax Maximum energy.
1436 *
1437 * This method sets up an array of indices and the cumulative distribution
1438 * function needed for MC simulations.
1439 ***************************************************************************/
1441 const GEnergy& emax) const
1442{
1443 // Check if we need to update the cache
1444 if (emin != m_mc_emin || emax != m_mc_emax) {
1445
1446 // Store new energy interval
1447 m_mc_emin = emin;
1448 m_mc_emax = emax;
1449
1450 // Initialise cache
1451 m_mc_cum.clear();
1452 m_mc_min.clear();
1453 m_mc_max.clear();
1454 m_mc_exp.clear();
1455
1456 // Get energy range in MeV
1457 double e_min = emin.MeV();
1458 double e_max = emax.MeV();
1459
1460 // Continue only if e_max > e_min
1461 if (e_max > e_min) {
1462
1463 // Loop over all bins
1464 for (int ibin = 0; ibin < bins(); ++ibin) {
1465
1466 // Get energy boundaires of bin in MeV
1467 double e_bin_min = m_emin[ibin].value();
1468 double e_bin_max = m_emax[ibin].value();
1469
1470 // Skip bins that do not overlap with energy range
1471 if (e_min >= e_bin_max || e_max < e_bin_min) {
1472 continue;
1473 }
1474
1475 // Raise lower boundary to minimum energy
1476 if (e_bin_min < e_min) {
1477 e_bin_min = e_min;
1478 }
1479
1480 // Lower upper boundary to maximum energy
1481 if (e_bin_max > e_max) {
1482 e_bin_max = e_max;
1483 }
1484
1485 // If energy interval is positive then compute flux
1486 if (e_bin_max > e_bin_min) {
1487
1488 // Get index
1489 double index = m_index.value();
1490
1491 // Compute flux
1492 double flux = m_values[ibin].value() *
1494 e_bin_max,
1495 m_epivot[ibin],
1496 index);
1497
1498 // Push results in cache
1499 m_mc_cum.push_back(flux);
1500 m_mc_min.push_back(e_bin_min);
1501 m_mc_max.push_back(e_bin_max);
1502 m_mc_exp.push_back(index);
1503
1504 } // endif: energy interval was positive
1505
1506 } // endfor: looped over all spectral bins
1507
1508 // Build cumulative distribution
1509 for (int i = 1; i < m_mc_cum.size(); ++i) {
1510 m_mc_cum[i] += m_mc_cum[i-1];
1511 }
1512 double norm = m_mc_cum[m_mc_cum.size()-1];
1513 if (norm > 0.0) {
1514 for (int i = 0; i < m_mc_cum.size(); ++i) {
1515 m_mc_cum[i] /= norm;
1516 }
1517 }
1518
1519 // Set MC values
1520 for (int i = 0; i < m_mc_cum.size(); ++i) {
1521
1522 // Compute exponent
1523 double exponent = m_mc_exp[i] + 1.0;
1524
1525 // Exponent dependend computation
1526 if (std::abs(exponent) > 1.0e-11) {
1527
1528 // If the exponent is too small then use lower energy
1529 // boundary
1530 if (exponent < -50.0) {
1531 m_mc_exp[i] = 0.0;
1532 m_mc_min[i] = std::log(m_mc_min[i]);
1533 m_mc_max[i] = m_mc_min[i];
1534 }
1535
1536 // ... otherwise if exponent is too large then use
1537 // upper energy boundary
1538 else if (exponent > +50.0) {
1539 m_mc_exp[i] = 0.0;
1540 m_mc_min[i] = std::log(m_mc_max[i]);
1541 m_mc_max[i] = m_mc_min[i];
1542 }
1543
1544 // ... otherwise use transformation formula
1545 else {
1546 m_mc_exp[i] = exponent;
1547 m_mc_min[i] = std::pow(m_mc_min[i], exponent);
1548 m_mc_max[i] = std::pow(m_mc_max[i], exponent);
1549 }
1550 }
1551 else {
1552 m_mc_exp[i] = 0.0;
1553 m_mc_min[i] = std::log(m_mc_min[i]);
1554 m_mc_max[i] = std::log(m_mc_max[i]);
1555 }
1556
1557 } // endfor: set MC values
1558
1559 } // endif: e_max > e_min
1560
1561 } // endif: Update was required
1562
1563 // Return
1564 return;
1565}
#define G_WRITE
#define G_READ
#define G_APPEND
Energy boundaries class interface definition.
Exception handler interface definition.
#define G_INSERT
#define G_REMOVE
const GModelSpectralBins g_spectral_bins_seed
#define G_EMAX_SET
#define G_ERROR_GET
#define G_EMAX_GET
#define G_EMIN_GET
#define G_INTENSITY_GET
#define G_INTENSITY_SET
#define G_EMIN_SET
Spectral bins model class 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
Energy boundaries container class.
Definition GEbounds.hpp:60
const GEnergy & emax(void) const
Return maximum energy of all intervals.
Definition GEbounds.hpp:199
int size(void) const
Return number of energy boundaries.
Definition GEbounds.hpp:163
GEnergy elogmean(const int &index) const
Returns logarithmic mean energy for a given energy interval.
const GEnergy & emin(void) const
Return minimum energy of all intervals.
Definition GEbounds.hpp:187
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
Model parameter class.
Definition GModelPar.hpp:87
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Spectral bins model class.
std::vector< GModelPar > m_emax
Upper energy limits.
GEnergy emax(const int &index) const
Return upper energy limit of bin.
void reserve(const int &num)
Reserve space for bins.
int bin_index(const GEnergy &energy) const
Return bin index for energy.
virtual GModelSpectralBins & operator=(const GModelSpectralBins &model)
Assignment operator.
virtual GModelSpectralBins * clone(void) const
Clone spectral bins model.
GModelPar m_index
Spectral index of all bins.
void free_members(void)
Delete class members.
void mc_update(const GEnergy &emin, const GEnergy &emax) const
Set MC pre-computation cache.
std::vector< double > m_mc_cum
Cumulative distribution.
void copy_members(const GModelSpectralBins &model)
Copy class members.
void insert(const int &index, const GEnergy &emin, const GEnergy &emax, const double &intensity)
Insert bin.
std::vector< double > m_mc_exp
Exponent for MC.
GEnergy emin(const int &index) const
Return lower energy limit of bin.
virtual void read(const GXmlElement &xml)
Read model from XML element.
virtual double eflux(const GEnergy &emin, const GEnergy &emax) const
Returns model energy flux between [emin, emax] (units: erg/cm2/s)
void update_pars(void)
Update parameter mapping.
std::vector< double > m_mc_min
Lower boundary for MC.
GEnergy m_mc_emax
Maximum energy.
std::vector< double > m_mc_max
Upper boundary for MC.
void append(const GEnergy &emin, const GEnergy &emax, const double &intensity)
Append bin.
virtual ~GModelSpectralBins(void)
Destructor.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const
Evaluate function.
virtual void write(GXmlElement &xml) const
Write model into XML element.
void init_members(void)
Initialise class members.
void set_cache(void) const
Set cache.
double index(void) const
Return spectral power law index.
std::vector< GModelPar > m_values
Bin values.
GEnergy m_mc_emin
Minimum energy.
virtual GEnergy mc(const GEnergy &emin, const GEnergy &emax, const GTime &time, GRan &ran) const
Returns MC energy between [emin, emax].
int bins(void) const
Return number of bins.
std::vector< GModelPar > m_emin
Lower energy limits.
double error(const int &index) const
Return intensity error of bin.
double intensity(const int &index) const
Return bin intensity.
void extend(const GModelSpectralBins &bins)
Append bins from bin function.
virtual void clear(void)
Clear spectral bins model.
virtual double flux(const GEnergy &emin, const GEnergy &emax) const
Returns model photon flux between [emin, emax] (units: ph/cm2/s)
void remove(const int &index)
Remove bin.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print bin function information.
virtual std::string type(void) const
Return model type.
std::vector< double > m_epivot
Power-law pivot energies in MeV.
GModelSpectralBins(void)
Void constructor.
Interface definition for the spectral model registry class.
Abstract spectral model base class.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const =0
void free_members(void)
Delete class members.
virtual GModelSpectral & operator=(const GModelSpectral &model)
Assignment operator.
std::vector< GModelPar * > m_pars
Parameter pointers.
int size(void) const
Return number of parameters.
void init_members(void)
Initialise class members.
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.
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
XML element node class.
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
Definition GXmlNode.cpp:287
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
Definition GXmlNode.cpp:640
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition GXmlNode.cpp:586
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
double plaw_photon_flux(const double &emin, const double &emax, const double &epivot, const double &gamma)
Compute photon flux between two energies for a power law.
Definition GTools.cpp:1200
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
double plaw_energy_flux(const double &emin, const double &emax, const double &epivot, const double &gamma)
Compute energy flux between two energies for a power law.
Definition GTools.cpp:1248
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