GammaLib 2.0.0
Loading...
Searching...
No Matches
GModelSpectralFunc.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GModelSpectralFunc.cpp - Spectral function model class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-2022 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 GModelSpectralFunc.cpp
23 * @brief Spectral function 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 "GCsv.hpp"
35#include "GRan.hpp"
36#include "GEnergies.hpp"
39
40/* __ Constants __________________________________________________________ */
41
42/* __ Globals ____________________________________________________________ */
44const GModelSpectralRegistry g_spectral_func_registry(&g_spectral_func_seed);
45
46/* __ Method name definitions ____________________________________________ */
47#define G_FLUX "GModelSpectralFunc::flux(GEnergy&, GEnergy&)"
48#define G_EFLUX "GModelSpectralFunc::eflux(GEnergy&, GEnergy&)"
49#define G_MC "GModelSpectralFunc::mc(GEnergy&, GEnergy&, GTime&, GRan&)"
50#define G_READ "GModelSpectralFunc::read(GXmlElement&)"
51#define G_WRITE "GModelSpectralFunc::write(GXmlElement&)"
52#define G_APPEND "GModelSpectralFunc::append(GEnergy&, double&)"
53#define G_INSERT "GModelSpectralFunc::insert(GEnergy&, double&)"
54#define G_REMOVE "GModelSpectralFunc::remove(int&)"
55#define G_ENERGY1 "GModelSpectralFunc::energy(int&)"
56#define G_ENERGY2 "GModelSpectralFunc::energy(int&, GEnergy&)"
57#define G_INTENSITY1 "GModelSpectralFunc::intensity(int&)"
58#define G_INTENSITY2 "GModelSpectralFunc::intensity(int&, double&)"
59#define G_LOAD_NODES "GModelSpectralFunc::load_nodes(GFilename&)"
60
61/* __ Macros _____________________________________________________________ */
62
63/* __ Coding definitions _________________________________________________ */
64
65/* __ Debug definitions __________________________________________________ */
66
67
68/*==========================================================================
69 = =
70 = Constructors/destructors =
71 = =
72 ==========================================================================*/
73
74/***********************************************************************//**
75 * @brief Void constructor
76 ***************************************************************************/
78{
79 // Initialise members
81
82 // Return
83 return;
84}
85
86
87/***********************************************************************//**
88 * @brief File constructor
89 *
90 * @param[in] filename File name of nodes.
91 * @param[in] norm Normalization factor.
92 *
93 * Constructs spectral file function model from a list of nodes that is found
94 * in the specified ASCII file. See the load_nodes() method for more
95 * information about the expected structure of the file.
96 ***************************************************************************/
98 const double& norm) :
100{
101 // Initialise members
102 init_members();
103
104 // Load nodes
106
107 // Set normalization
109
110 // Return
111 return;
112}
113
114
115/***********************************************************************//**
116 * @brief XML constructor
117 *
118 * @param[in] xml XML element.
119 *
120 * Constructs spectral file function model by extracting information from an
121 * XML element. See the read() method for more information about the expected
122 * structure of the XML element.
123 ***************************************************************************/
126{
127 // Initialise members
128 init_members();
129
130 // Read information from XML element
131 read(xml);
132
133 // Return
134 return;
135}
136
137
138/***********************************************************************//**
139 * @brief Spectral model constructor
140 *
141 * @param[in] model Spectral model.
142 * @param[in] energies File function node energies.
143 *
144 * Constructs a spectral file function model from any spectral model.
145 * The file function normalisation will be set to unity.
146 ***************************************************************************/
148 const GEnergies& energies) :
150{
151 // Initialise members
152 init_members();
153
154 // Reserve space for file function nodes
155 reserve(energies.size());
156
157 // Append nodes for all energies
158 for (int i = 0; i < energies.size(); ++i) {
159 append(energies[i], model.eval(energies[i]));
160 }
161
162 // Return
163 return;
164}
165
166
167/***********************************************************************//**
168 * @brief Copy constructor
169 *
170 * @param[in] model File function model.
171 ***************************************************************************/
173 GModelSpectral(model)
174{
175 // Initialise members
176 init_members();
177
178 // Copy members
179 copy_members(model);
180
181 // Return
182 return;
183}
184
185
186/***********************************************************************//**
187 * @brief Destructor
188 ***************************************************************************/
190{
191 // Free members
192 free_members();
193
194 // Return
195 return;
196}
197
198
199/*==========================================================================
200 = =
201 = Operators =
202 = =
203 ==========================================================================*/
204
205/***********************************************************************//**
206 * @brief Assignment operator
207 *
208 * @param[in] model File function model.
209 * @return File function model.
210 ***************************************************************************/
212{
213 // Execute only if object is not identical
214 if (this != &model) {
215
216 // Copy base class members
217 this->GModelSpectral::operator=(model);
218
219 // Free members
220 free_members();
221
222 // Initialise members
223 init_members();
224
225 // Copy members
226 copy_members(model);
227
228 } // endif: object was not identical
229
230 // Return
231 return *this;
232}
233
234
235/*==========================================================================
236 = =
237 = Public methods =
238 = =
239 ==========================================================================*/
240
241/***********************************************************************//**
242 * @brief Clear file function
243***************************************************************************/
245{
246 // Free class members (base and derived classes, derived class first)
247 free_members();
249
250 // Initialise members
252 init_members();
253
254 // Return
255 return;
256}
257
258
259/***********************************************************************//**
260 * @brief Clone file function
261***************************************************************************/
263{
264 // Clone file function
265 return new GModelSpectralFunc(*this);
266}
267
268
269/***********************************************************************//**
270 * @brief Evaluate function
271 *
272 * @param[in] srcEng True photon energy.
273 * @param[in] srcTime True photon arrival time.
274 * @param[in] gradients Compute gradients?
275 * @return Model value (ph/cm2/s/MeV).
276 *
277 * Evaluates
278 *
279 * \f[
280 * S_{\rm E}(E | t) = {\tt m\_norm} F(E)
281 * \f]
282 *
283 * where
284 * - \f${\tt m\_norm}\f$ is the normalization factor and
285 * - \f${F(E)}\f$ is the spectral function.
286 *
287 * If the @p gradients flag is true the method will also compute the
288 * partial derivatives of the model with respect to the parameters using
289 *
290 * \f[
291 * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_norm}} =
292 * \frac{S_{\rm E}(E | t)}{{\tt m\_norm}}
293 * \f]
294 ***************************************************************************/
296 const GTime& srcTime,
297 const bool& gradients) const
298{
299 // Interpolate function. This is done in log10-log10 space, but the
300 // linear value is returned.
301 double arg = m_log_nodes.interpolate(srcEng.log10MeV(), m_log_values);
302 double func = std::pow(10.0, arg);
303
304 // Compute function value
305 double value = m_norm.value() * func;
306
307 // Optionally compute gradients
308 if (gradients) {
309
310 // Compute partial derivatives of the parameter values
311 double g_norm = (m_norm.is_free()) ? m_norm.scale() * func : 0.0;
312
313 // Set gradients
314 m_norm.factor_gradient(g_norm);
315
316 } // endif: gradient computation was requested
317
318 // Compile option: Check for NaN/Inf
319 #if defined(G_NAN_CHECK)
320 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
321 std::cout << "*** ERROR: GModelSpectralFunc::eval";
322 std::cout << "(srcEng=" << srcEng;
323 std::cout << ", srcTime=" << srcTime << "):";
324 std::cout << " NaN/Inf encountered";
325 std::cout << " (value=" << value;
326 std::cout << ", norm=" << norm();
327 std::cout << ", func=" << func;
328 std::cout << ")" << std::endl;
329 }
330 #endif
331
332 // Return
333 return value;
334}
335
336
337/***********************************************************************//**
338 * @brief Returns model photon flux between [emin, emax] (units: ph/cm2/s)
339 *
340 * @param[in] emin Minimum photon energy.
341 * @param[in] emax Maximum photon energy.
342 * @return Photon flux (ph/cm2/s).
343 *
344 * Computes
345 *
346 * \f[
347 * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) dE
348 * \f]
349 *
350 * where
351 * - [@p emin, @p emax] is an energy interval, and
352 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
353 ***************************************************************************/
354double GModelSpectralFunc::flux(const GEnergy& emin, const GEnergy& emax) const
355{
356 // Initialise flux
357 double flux = 0.0;
358
359 // Compute only if integration range is valid
360 if (emin < emax) {
361
362 // Get energy range in MeV
363 double e_min = emin.MeV();
364 double e_max = emax.MeV();
365
366 // Determine left node index for minimum energy
367 m_lin_nodes.set_value(e_min);
368 int inx_emin = m_lin_nodes.inx_left();
369
370 // Determine left node index for maximum energy
371 m_lin_nodes.set_value(e_max);
372 int inx_emax = m_lin_nodes.inx_left();
373
374 // If both energies are within the same nodes then simply
375 // integrate over the energy interval using the appropriate power
376 // law parameters
377 if (inx_emin == inx_emax) {
378 flux = m_prefactor[inx_emin] *
380 e_max,
381 m_epivot[inx_emin],
382 m_gamma[inx_emin]);
383 }
384
385 // ... otherwise integrate over the nodes where emin and emax
386 // resides and all the remaining nodes
387 else {
388
389 // If we are requested to extrapolate beyond first node,
390 // the use the first nodes lower energy and upper energy
391 // boundary for the initial integration.
392 int i_start = (e_min < m_lin_nodes[0]) ? inx_emin : inx_emin+1;
393
394 // Integrate from emin to the node boundary
395 flux = m_prefactor[inx_emin] *
397 m_lin_nodes[i_start],
398 m_epivot[inx_emin],
399 m_gamma[inx_emin]);
400
401 // Integrate over all nodes between
402 for (int i = i_start; i < inx_emax; ++i) {
403 flux += m_flux[i];
404 }
405
406 // Integrate from node boundary to emax
407 flux += m_prefactor[inx_emax] *
409 e_max,
410 m_epivot[inx_emax],
411 m_gamma[inx_emax]);
412
413 } // endelse: emin and emax not between same nodes
414
415 // Multiply flux by normalisation factor
416 flux *= norm();
417
418 } // endif: integration range was valid
419
420 // Return
421 return flux;
422}
423
424
425/***********************************************************************//**
426 * @brief Returns model energy flux between [emin, emax] (units: erg/cm2/s)
427 *
428 * @param[in] emin Minimum photon energy.
429 * @param[in] emax Maximum photon energy.
430 * @return Energy flux (erg/cm2/s).
431 *
432 * Computes
433 *
434 * \f[
435 * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) E \, dE
436 * \f]
437 *
438 * where
439 * - [@p emin, @p emax] is an energy interval, and
440 * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
441 ***************************************************************************/
442double GModelSpectralFunc::eflux(const GEnergy& emin, const GEnergy& emax) const
443{
444 // Initialise flux
445 double eflux = 0.0;
446
447 // Compute only if integration range is valid
448 if (emin < emax) {
449
450 // Get energy range in MeV
451 double e_min = emin.MeV();
452 double e_max = emax.MeV();
453
454 // Determine left node index for minimum energy
455 m_lin_nodes.set_value(e_min);
456 int inx_emin = m_lin_nodes.inx_left();
457
458 // Determine left node index for maximum energy
459 m_lin_nodes.set_value(e_max);
460 int inx_emax = m_lin_nodes.inx_left();
461
462 // If both energies are within the same nodes then simply
463 // integrate over the energy interval using the appropriate power
464 // law parameters
465 if (inx_emin == inx_emax) {
466 eflux = m_prefactor[inx_emin] *
468 e_max,
469 m_epivot[inx_emin],
470 m_gamma[inx_emin]) *
472 }
473
474 // ... otherwise integrate over the nodes where emin and emax
475 // resides and all the remaining nodes
476 else {
477
478 // If we are requested to extrapolate beyond first node,
479 // the use the first nodes lower energy and upper energy
480 // boundary for the initial integration.
481 int i_start = (e_min < m_lin_nodes[0]) ? inx_emin : inx_emin+1;
482
483 // Integrate from emin to the node boundary
484 eflux = m_prefactor[inx_emin] *
486 m_lin_nodes[i_start],
487 m_epivot[inx_emin],
488 m_gamma[inx_emin]) *
490
491 // Integrate over all nodes between
492 for (int i = i_start; i < inx_emax; ++i) {
493 eflux += m_eflux[i];
494 }
495
496 // Integrate from node boundary to emax
497 eflux += m_prefactor[inx_emax] *
499 e_max,
500 m_epivot[inx_emax],
501 m_gamma[inx_emax]) *
503
504 } // endelse: emin and emax not between same nodes
505
506 // Multiply flux by normalisation factor
507 eflux *= norm();
508
509 } // endif: integration range was valid
510
511 // Return flux
512 return eflux;
513}
514
515
516/***********************************************************************//**
517 * @brief Returns MC energy between [emin, emax]
518 *
519 * @param[in] emin Minimum photon energy.
520 * @param[in] emax Maximum photon energy.
521 * @param[in] time True photon arrival time.
522 * @param[in,out] ran Random number generator.
523 * @return Energy.
524 *
525 * @exception GException::erange_invalid
526 * Energy range is invalid (emin < emax required).
527 *
528 * Returns Monte Carlo energy by randomly drawing from a broken power law
529 * defined by the file function.
530 ***************************************************************************/
532 const GEnergy& emax,
533 const GTime& time,
534 GRan& ran) const
535{
536 // Check energy interval
538
539 // Allocate energy
541
542 // Update cache
543 mc_update(emin, emax);
544
545 // Determine in which bin we reside
546 int inx = 0;
547 if (m_mc_cum.size() > 1) {
548 double u = ran.uniform();
549 for (inx = m_mc_cum.size()-1; inx > 0; --inx) {
550 if (m_mc_cum[inx-1] <= u) {
551 break;
552 }
553 }
554 }
555
556 // Get random energy for specific bin
557 if (m_mc_exp[inx] != 0.0) {
558 double e_min = m_mc_min[inx];
559 double e_max = m_mc_max[inx];
560 double u = ran.uniform();
561 double eng = (u > 0.0)
562 ? std::exp(std::log(u * (e_max - e_min) + e_min) / m_mc_exp[inx])
563 : 0.0;
564 energy.MeV(eng);
565 }
566 else {
567 double e_min = m_mc_min[inx];
568 double e_max = m_mc_max[inx];
569 double u = ran.uniform();
570 double eng = std::exp(u * (e_max - e_min) + e_min);
571 energy.MeV(eng);
572 }
573
574 // Return energy
575 return energy;
576}
577
578
579/***********************************************************************//**
580 * @brief Read model from XML element
581 *
582 * @param[in] xml XML element containing power law model information.
583 *
584 * Reads the spectral information from an XML element. The format of the XML
585 * elements is
586 *
587 * <spectrum type="FileFunction" file="..">
588 * <parameter name="Normalization" scale=".." value=".." min=".." max=".." free=".."/>
589 * </spectrum>
590 ***************************************************************************/
592{
593 // Verify number of model parameters
595
596 // Get parameter
598
599 // Read parameter
600 m_norm.read(*norm);
601
602 // Load nodes from file
604
605 // Return
606 return;
607}
608
609
610/***********************************************************************//**
611 * @brief Write model into XML element
612 *
613 * @param[in] xml XML element into which model information is written.
614 *
615 * Writes the spectral information into an XML element. The format of the XML
616 * element is
617 *
618 * <spectrum type="FileFunction" file="..">
619 * <parameter name="Normalization" scale=".." value=".." min=".." max=".." free=".."/>
620 * </spectrum>
621 *
622 * Note that the function nodes will not be written since they will not be
623 * altered by any method.
624 ***************************************************************************/
626{
627 // Verify model type
629
630 // Get or create parameter
632
633 // Write parameter
634 m_norm.write(*norm);
635
636 // Set file attribute
638
639 // Return
640 return;
641}
642
643
644/***********************************************************************//**
645 * @brief Append node to file function
646 *
647 * @param[in] energy Energy.
648 * @param[in] intensity Intensity.
649 *
650 * @exception GException::invalid_argument
651 * Energy not larger than energy of last node or energy or
652 * intensity are not positive.
653 *
654 * Appends one node to the file function.
655 ***************************************************************************/
656void GModelSpectralFunc::append(const GEnergy& energy, const double& intensity)
657{
658 // Check that energy is larger than energy of last node
659 if (nodes() > 0) {
660 if (energy.MeV() <= m_lin_nodes[nodes()-1]) {
661 GEnergy last(m_lin_nodes[nodes()-1], "MeV");
662 std::string msg = "Specified energy "+energy.print()+" is not "
663 "larger than the energy "+last.print()+" of the "
664 "last node of the file function. Please append "
665 "nodes in increasing order of energy.";
667 }
668 }
669
670 // Check that energy is positive
671 if (energy.MeV() <= 0.0) {
672 std::string msg = "Specified energy "+energy.print()+" is not "
673 "positive. Please append only nodes with positive "
674 "energies.";
676 }
677
678 // Check that intensity is positive
679 if (intensity <= 0.0) {
680 std::string msg = "Specified intensity "+gammalib::str(intensity)+" is "
681 "not positive. Please append only nodes with positive "
682 "intensities.";
684 }
685
686 // Append node
689 m_lin_values.push_back(intensity);
690 m_log_values.push_back(std::log10(intensity));
691
692 // Set pre-computation cache
693 set_cache();
694
695 // Return
696 return;
697}
698
699
700/***********************************************************************//**
701 * @brief Insert node into file function
702 *
703 * @param[in] energy Energy.
704 * @param[in] intensity Intensity.
705 *
706 * @exception GException::invalid_argument
707 * Energy or intensity are not positive, or energy does already
708 * exist in file function.
709 *
710 * Inserts one node at the appropriate location into the file function.
711 ***************************************************************************/
712void GModelSpectralFunc::insert(const GEnergy& energy, const double& intensity)
713{
714 // Get energy in MeV
715 double energy_MeV = energy.MeV();
716
717 // Check that energy is positive
718 if (energy_MeV <= 0.0) {
719 std::string msg = "Specified energy "+energy.print()+" is not "
720 "positive. Please append only nodes with positive "
721 "energies.";
723 }
724
725 // Check that intensity is positive
726 if (intensity <= 0.0) {
727 std::string msg = "Specified intensity "+gammalib::str(intensity)+" is "
728 "not positive. Please append only nodes with positive "
729 "intensities.";
731 }
732
733 // Find index before which the node should be inserted
734 int index = 0;
735 for (int i = 0; i < nodes(); ++i) {
736 if (m_lin_nodes[i] == energy_MeV) {
737 std::string msg = "A node with the specified energy "+
738 energy.print()+" exists already in the file "
739 "function. Please insert only nodes with "
740 "energies that do not yet exist.";
742 }
743 else if (m_lin_nodes[i] > energy_MeV) {
744 break;
745 }
746 index++;
747 }
748
749 // Insert node
750 m_lin_nodes.insert(index, energy_MeV);
752 m_lin_values.insert(m_lin_values.begin()+index, intensity);
753 m_log_values.insert(m_log_values.begin()+index, std::log10(intensity));
754
755 // Set pre-computation cache
756 set_cache();
757
758 // Return
759 return;
760}
761
762
763/***********************************************************************//**
764 * @brief Remove node from file function
765 *
766 * @param[in] index Node index [0,...,nodes()-1].
767 *
768 * @exception GException::out_of_range
769 * Node index is out of range.
770 *
771 * Removes the node of specified @p index from the file function.
772 ***************************************************************************/
773void GModelSpectralFunc::remove(const int& index)
774{
775 // Compile option: raise exception if index is out of range
776 #if defined(G_RANGE_CHECK)
777 if (index < 0 || index >= nodes()) {
778 throw GException::out_of_range(G_REMOVE, "Node index", index, nodes());
779 }
780 #endif
781
782 // Delete node
783 m_lin_nodes.remove(index);
784 m_log_nodes.remove(index);
785 m_lin_values.erase(m_lin_values.begin() + index);
786 m_log_values.erase(m_log_values.begin() + index);
787
788 // Set pre-computation cache
789 set_cache();
790
791 // Return
792 return;
793}
794
795
796/***********************************************************************//**
797 * @brief Append file function
798 *
799 * @param[in] filefct File function.
800 *
801 * Appends file function to the existing file function.
802 ***************************************************************************/
804{
805 // Do nothing if file function is empty
806 if (!filefct.is_empty()) {
807
808 // Get file function size
809 int num = filefct.nodes();
810
811 // Reserve enough space
812 reserve(nodes() + num);
813
814 // Append all nodes
815 for (int i = 0; i < num; ++i) {
816 append(filefct.energy(i), filefct.intensity(i));
817 }
818
819 } // endif: file function was not empty
820
821 // Set pre-computation cache
822 set_cache();
823
824 // Return
825 return;
826}
827
828
829/***********************************************************************//**
830 * @brief Return energy of node
831 *
832 * @param[in] index Node index [0,...,nodes()-1].
833 *
834 * @exception GException::out_of_range
835 * Node index is out of range.
836 *
837 * Returns the energy of node with specified @p index in the file function.
838 ***************************************************************************/
839GEnergy GModelSpectralFunc::energy(const int& index) const
840{
841 // Compile option: raise exception if index is out of range
842 #if defined(G_RANGE_CHECK)
843 if (index < 0 || index >= nodes()) {
844 throw GException::out_of_range(G_ENERGY1, "Node index", index, nodes());
845 }
846 #endif
847
848 // Set energy
850 energy.MeV(m_lin_nodes[index]);
851
852 // Return energy
853 return energy;
854}
855
856
857/***********************************************************************//**
858 * @brief Set energy of node
859 *
860 * @param[in] index Node index [0,...,nodes()-1].
861 * @param[in] energy Energy.
862 *
863 * @exception GException::out_of_range
864 * Node index is out of range.
865 * @exception GException::invalid_argument
866 * Specified energy is not larger than energy of preceeding node
867 * or not smaller than energy of following node.
868 *
869 * Sets the energy of node with specified @p index in the file function.
870 ***************************************************************************/
871void GModelSpectralFunc::energy(const int& index, const GEnergy& energy)
872{
873 // Compile option: raise exception if index is out of range
874 #if defined(G_RANGE_CHECK)
875 if (index < 0 || index >= nodes()) {
876 throw GException::out_of_range(G_ENERGY2, "Node index", index, nodes());
877 }
878 #endif
879
880 // Check that energy is larger than energy of precedent node
881 if (index > 0) {
882 if (energy.MeV() <= m_lin_nodes[index-1]) {
883 GEnergy precedent(m_lin_nodes[index-1], "MeV");
884 std::string msg = "Specified energy "+energy.print()+" is not "
885 "larger than energy "+precedent.print()+" of "
886 "precedent node. Please specify an energy that "
887 "is larger than "+precedent.print()+".";
889 }
890 }
891
892 // Check that energy is smaller than energy of following node
893 if (index < nodes()-1) {
894 if (energy.MeV() >= m_lin_nodes[index+1]) {
895 GEnergy following(m_lin_nodes[index+1], "MeV");
896 std::string msg = "Specified energy "+energy.print()+" is not "
897 "smaller than energy "+following.print()+" of "
898 "following node. Please specify an energy that "
899 "is smaller than "+following.print()+".";
901 }
902 }
903
904 // Set node
905 m_lin_nodes[index] = energy.MeV();
906 m_log_nodes[index] = energy.log10MeV();
907
908 // Set pre-computation cache
909 set_cache();
910
911 // Return
912 return;
913}
914
915
916/***********************************************************************//**
917 * @brief Return intensity of node
918 *
919 * @param[in] index Node index [0,...,nodes()-1].
920 * @return Intensity (ph/cm2/s/MeV).
921 *
922 * @exception GException::out_of_range
923 * Node index is out of range.
924 *
925 * Returns the intensity of node with specified @p index in the file function.
926 ***************************************************************************/
927double GModelSpectralFunc::intensity(const int& index) const
928{
929 // Compile option: raise exception if index is out of range
930 #if defined(G_RANGE_CHECK)
931 if (index < 0 || index >= nodes()) {
932 throw GException::out_of_range(G_INTENSITY1, "Node index", index, nodes());
933 }
934 #endif
935
936 // Return intensity
937 return (m_lin_values[index]);
938}
939
940
941/***********************************************************************//**
942 * @brief Set intensity of node
943 *
944 * @param[in] index Node index [0,...,nodes()-1].
945 * @param[in] intensity Intensity (ph/cm2/s/MeV).
946 *
947 * @exception GException::out_of_range
948 * Node index is out of range.
949 * @exception GException::invalid_argument
950 * Intensity is not positive.
951 *
952 * Sets the intensity of node with specified @p index in the file function.
953 ***************************************************************************/
954void GModelSpectralFunc::intensity(const int& index, const double& intensity)
955{
956 // Compile option: raise exception if index is out of range
957 #if defined(G_RANGE_CHECK)
958 if (index < 0 || index >= nodes()) {
959 throw GException::out_of_range(G_INTENSITY2, "Node index", index, nodes());
960 }
961 #endif
962
963 // Check that intensity is positive
964 if (intensity <= 0.0) {
965 std::string msg = "Specified intensity "+gammalib::str(intensity)+" is "
966 "not positive. Please set only positive intensities.";
968 }
969
970 // Set intensity
971 m_lin_values[index] = intensity;
972 m_log_values[index] = std::log10(intensity);
973
974 // Set pre-computation cache
975 set_cache();
976
977 // Return
978 return;
979}
980
981
982/***********************************************************************//**
983 * @brief Save file function in ASCII file
984 *
985 * @param[in] filename ASCII filename.
986 * @param[in] clobber Overwrite existing file?
987 *
988 * Saves file function in ASCII file.
989 ***************************************************************************/
990void GModelSpectralFunc::save(const GFilename& filename, const bool& clobber) const
991{
992 // Allocate CSV file
993 GCsv csv(nodes(), 2);
994
995 // Fill CSV file
996 for (int i = 0; i < nodes(); ++i) {
997 csv(i,0) = gammalib::str(m_lin_nodes[i]);
998 csv(i,1) = gammalib::str(m_lin_values[i]);
999 }
1000
1001 // Save CSV file
1002 csv.save(filename, " ", clobber);
1003
1004 // Store filename
1006
1007 // Return
1008 return;
1009}
1010
1011
1012/***********************************************************************//**
1013 * @brief Print file function information
1014 *
1015 * @param[in] chatter Chattiness.
1016 * @return String containing file function information.
1017 ***************************************************************************/
1018std::string GModelSpectralFunc::print(const GChatter& chatter) const
1019{
1020 // Initialise result string
1021 std::string result;
1022
1023 // Continue only if chatter is not silent
1024 if (chatter != SILENT) {
1025
1026 // Append header
1027 result.append("=== GModelSpectralFunc ===");
1028
1029 // Append information
1030 result.append("\n"+gammalib::parformat("Function file"));
1031 result.append(m_filename.url());
1032 result.append("\n"+gammalib::parformat("Number of nodes"));
1033 result.append(gammalib::str(nodes()));
1034 result.append("\n"+gammalib::parformat("Number of parameters"));
1035 result.append(gammalib::str(size()));
1036 for (int i = 0; i < size(); ++i) {
1037 result.append("\n"+m_pars[i]->print(chatter));
1038 }
1039
1040 // Append node information
1041 for (int i = 0; i < m_prefactor.size(); ++i) {
1042 result.append("\n"+gammalib::parformat("Node "+gammalib::str(i+1)));
1043 result.append("Epivot="+gammalib::str(m_epivot[i]));
1044 result.append(" Prefactor="+gammalib::str(m_prefactor[i]));
1045 result.append(" Gamma="+gammalib::str(m_gamma[i]));
1046 result.append(" Flux="+gammalib::str(m_flux[i]));
1047 result.append(" EFlux="+gammalib::str(m_eflux[i]));
1048 }
1049
1050 } // endif: chatter was not silent
1051
1052 // Return result
1053 return result;
1054}
1055
1056
1057/*==========================================================================
1058 = =
1059 = Private methods =
1060 = =
1061 ==========================================================================*/
1062
1063/***********************************************************************//**
1064 * @brief Initialise class members
1065 ***************************************************************************/
1067{
1068 // Initialise powerlaw normalisation
1069 m_norm.clear();
1070 m_norm.name("Normalization");
1071 m_norm.scale(1.0);
1072 m_norm.value(1.0);
1073 m_norm.range(0.0,1000.0);
1074 m_norm.free();
1075 m_norm.gradient(0.0);
1076 m_norm.has_grad(true);
1077
1078 // Set parameter pointer(s)
1079 m_pars.clear();
1080 m_pars.push_back(&m_norm);
1081
1082 // Initialise members
1085 m_lin_values.clear();
1086 m_log_values.clear();
1087 m_filename.clear();
1088
1089 // Initialise flux cache
1090 m_prefactor.clear();
1091 m_gamma.clear();
1092 m_epivot.clear();
1093 m_flux.clear();
1094 m_eflux.clear();
1095
1096 // Initialise MC cache
1097 m_mc_emin.clear();
1098 m_mc_emax.clear();
1099 m_mc_cum.clear();
1100 m_mc_min.clear();
1101 m_mc_max.clear();
1102 m_mc_exp.clear();
1103
1104 // Return
1105 return;
1106}
1107
1108
1109/***********************************************************************//**
1110 * @brief Copy class members
1111 *
1112 * @param[in] model Spectral function model.
1113 ***************************************************************************/
1115{
1116 // Copy members
1117 m_norm = model.m_norm;
1118 m_lin_nodes = model.m_lin_nodes;
1119 m_log_nodes = model.m_log_nodes;
1120 m_lin_values = model.m_lin_values;
1121 m_log_values = model.m_log_values;
1122 m_filename = model.m_filename;
1123
1124 // Copy flux cache
1125 m_prefactor = model.m_prefactor;
1126 m_gamma = model.m_gamma;
1127 m_epivot = model.m_epivot;
1128 m_flux = model.m_flux;
1129 m_eflux = model.m_eflux;
1130
1131 // Copy MC cache
1132 m_mc_emin = model.m_mc_emin;
1133 m_mc_emax = model.m_mc_emax;
1134 m_mc_cum = model.m_mc_cum;
1135 m_mc_min = model.m_mc_min;
1136 m_mc_max = model.m_mc_max;
1137 m_mc_exp = model.m_mc_exp;
1138
1139 // Set parameter pointer(s)
1140 m_pars.clear();
1141 m_pars.push_back(&m_norm);
1142
1143 // Return
1144 return;
1145}
1146
1147
1148/***********************************************************************//**
1149 * @brief Delete class members
1150 ***************************************************************************/
1152{
1153 // Return
1154 return;
1155}
1156
1157
1158/***********************************************************************//**
1159 * @brief Load nodes from file
1160 *
1161 * @param[in] filename File name.
1162 *
1163 * @exception GException::invalid_argument
1164 * Empty @p filename specified.
1165 * GException::invalid_value
1166 * Invalid file function ASCII file.
1167 *
1168 * The file function is stored as a column separated value table (CSV) in an
1169 * ASCII file with (at least) 2 columns. The first column specifies the
1170 * energy in MeV while the second column specifies the intensity at this
1171 * energy in units of ph/cm2/s/MeV.
1172 *
1173 * The node energies and values will be stored both linearly and as log10.
1174 * The log10 storing requires that node energies and node values are
1175 * positive. Also, at least 2 nodes and 2 columns are required in the file
1176 * function.
1177 ***************************************************************************/
1179{
1180 // Clear nodes and values
1183 m_lin_values.clear();
1184 m_log_values.clear();
1185
1186 // Throw an exception if the filename is empty
1187 if (filename.is_empty()) {
1188 std::string msg = "Empty file function ASCII file name specified. "
1189 "Please specify a valid file function ASCII file "
1190 "name.";
1192 }
1193
1194 // Set filename
1196
1197 // Load file
1198 GCsv csv = GCsv(filename.url());
1199
1200 // Check if there are at least 2 nodes
1201 if (csv.nrows() < 2) {
1202 std::string msg = "File function ASCII file \""+filename.url()+
1203 "\" contains "+gammalib::str(csv.nrows())+
1204 " rows but at least 2 rows are required. Please "
1205 "specify a file function ASCII file with at "
1206 "least two rows.";
1208 }
1209
1210 // Check if there are at least 2 columns
1211 if (csv.ncols() < 2) {
1212 std::string msg = "File function ASCII file \""+filename.url()+
1213 "\" contains "+gammalib::str(csv.ncols())+
1214 " columns but at least 2 columns are required. "
1215 "Please specify a file function ASCII file with "
1216 "at least two columns.";
1218 }
1219
1220 // Setup nodes
1221 double last_energy = 0.0;
1222 for (int i = 0; i < csv.nrows(); ++i) {
1223
1224 // Get log10 of node energy and value. Make sure they are valid.
1225 double log10energy;
1226 double log10value;
1227 if (csv.real(i,0) > 0.0) {
1228 log10energy = std::log10(csv.real(i,0));
1229 }
1230 else {
1231 std::string msg = "Non-positive energy "+
1232 gammalib::str(csv.real(i,0))+" encountered "
1233 "in row "+gammalib::str(i)+" of file "
1234 "function ASCII file. Please specify only "
1235 "positive energies in file function.";
1237 }
1238 if (csv.real(i,1) > 0.0) {
1239 log10value = std::log10(csv.real(i,1));
1240 }
1241 else {
1242 std::string msg = "Non-positive intensity "+
1243 gammalib::str(csv.real(i,1))+" encountered "
1244 "in row "+gammalib::str(i)+" of file "
1245 "function ASCII file. Please specify only "
1246 "positive intensities in file function.";
1248 }
1249
1250 // Make sure that energies are increasing
1251 if (csv.real(i,0) <= last_energy) {
1252 std::string msg = "Energy "+gammalib::str(csv.real(i,0))+
1253 "in row "+gammalib::str(i)+" of file "
1254 "function ASCII file is equal or smaller "
1255 "than preceding energy "+
1256 gammalib::str(last_energy)+". Please specify "
1257 "monotonically increasing energies in the "
1258 "file function ASCII file.";
1260 }
1261
1262 // Append log10 of node energy and value
1263 m_lin_nodes.append(csv.real(i,0));
1264 m_log_nodes.append(log10energy);
1265 m_lin_values.push_back(csv.real(i,1));
1266 m_log_values.push_back(log10value);
1267
1268 // Store last energy for monotonically increasing check
1269 last_energy = csv.real(i,0);
1270
1271 } // endfor: looped over nodes
1272
1273 // Set pre-computation cache
1274 set_cache();
1275
1276 // Return
1277 return;
1278}
1279
1280
1281/***********************************************************************//**
1282 * @brief Set pre-computation cache
1283 ***************************************************************************/
1285{
1286 // Clear any existing values
1287 m_prefactor.clear();
1288 m_gamma.clear();
1289 m_epivot.clear();
1290 m_flux.clear();
1291 m_eflux.clear();
1292
1293 // Loop over all nodes-1
1294 for (int i = 0; i < nodes()-1; ++i) {
1295
1296 // Get energies and function values
1297 double emin = m_lin_nodes[i];
1298 double emax = m_lin_nodes[i+1];
1299 double fmin = m_lin_values[i];
1300 double fmax = m_lin_values[i+1];
1301
1302 // Compute pivot energy (MeV). We use here the geometric mean of
1303 // the node boundaries.
1304 double epivot = std::sqrt(emin*emax);
1305
1306 // Compute spectral index
1307 double gamma = std::log(fmin/fmax) / std::log(emin/emax);
1308
1309 // Compute power law normalisation
1310 double prefactor = fmin / std::pow(emin/epivot, gamma);
1311
1312 // Compute photon flux between nodes
1313 double flux = prefactor *
1314 gammalib::plaw_photon_flux(emin, emax, epivot, gamma);
1315
1316 // Compute energy flux between nodes
1317 double eflux = prefactor *
1318 gammalib::plaw_energy_flux(emin, emax, epivot, gamma);
1319
1320 // Convert energy flux from MeV/cm2/s to erg/cm2/s
1322
1323 // Push back values on pre-computation cache
1324 m_prefactor.push_back(prefactor);
1325 m_gamma.push_back(gamma);
1326 m_epivot.push_back(epivot);
1327 m_flux.push_back(flux);
1328 m_eflux.push_back(eflux);
1329
1330 } // endfor: looped over all nodes
1331
1332 // Return
1333 return;
1334}
1335
1336
1337/***********************************************************************//**
1338 * @brief Set MC pre-computation cache
1339 *
1340 * @param[in] emin Minimum energy.
1341 * @param[in] emax Maximum energy.
1342 *
1343 * This method sets up an array of indices and the cumulative distribution
1344 * function needed for MC simulations.
1345 ***************************************************************************/
1347 const GEnergy& emax) const
1348{
1349 // Check if we need to update the cache
1350 if (emin != m_mc_emin || emax != m_mc_emax) {
1351
1352 // Store new energy interval
1353 m_mc_emin = emin;
1354 m_mc_emax = emax;
1355
1356 // Initialise cache
1357 m_mc_cum.clear();
1358 m_mc_min.clear();
1359 m_mc_max.clear();
1360 m_mc_exp.clear();
1361
1362 // Get energy range in MeV
1363 double e_min = emin.MeV();
1364 double e_max = emax.MeV();
1365
1366 // Continue only if e_max > e_min
1367 if (e_max > e_min) {
1368
1369 // Allocate flux
1370 double flux;
1371
1372 // Determine left node index for minimum energy
1373 m_lin_nodes.set_value(e_min);
1374 int inx_emin = m_lin_nodes.inx_left();
1375
1376 // Determine left node index for maximum energy
1377 m_lin_nodes.set_value(e_max);
1378 int inx_emax = m_lin_nodes.inx_left();
1379
1380 // If both energies are within the same node then just
1381 // add this one node on the stack
1382 if (inx_emin == inx_emax) {
1383 flux = m_prefactor[inx_emin] *
1385 e_max,
1386 m_epivot[inx_emin],
1387 m_gamma[inx_emin]);
1388 m_mc_cum.push_back(flux);
1389 m_mc_min.push_back(e_min);
1390 m_mc_max.push_back(e_max);
1391 m_mc_exp.push_back(m_gamma[inx_emin]);
1392 }
1393
1394 // ... otherwise integrate over the nodes where emin and emax
1395 // resides and all the remaining nodes
1396 else {
1397
1398 // If we are requested to extrapolate beyond first node,
1399 // the use the first nodes lower energy and upper energy
1400 // boundary for the initial integration.
1401 int i_start = (e_min < m_lin_nodes[0]) ? inx_emin : inx_emin+1;
1402
1403 // Add emin to the node boundary
1404 flux = m_prefactor[inx_emin] *
1406 m_lin_nodes[i_start],
1407 m_epivot[inx_emin],
1408 m_gamma[inx_emin]);
1409 m_mc_cum.push_back(flux);
1410 m_mc_min.push_back(e_min);
1411 m_mc_max.push_back(m_lin_nodes[i_start]);
1412 m_mc_exp.push_back(m_gamma[inx_emin]);
1413
1414 // Add all nodes between
1415 for (int i = i_start; i < inx_emax; ++i) {
1416 flux = m_flux[i];
1417 m_mc_cum.push_back(flux);
1418 m_mc_min.push_back(m_lin_nodes[i]);
1419 m_mc_max.push_back(m_lin_nodes[i+1]);
1420 m_mc_exp.push_back(m_gamma[i]);
1421 }
1422
1423 // Add node boundary to emax
1424 flux = m_prefactor[inx_emax] *
1426 e_max,
1427 m_epivot[inx_emax],
1428 m_gamma[inx_emax]);
1429 m_mc_cum.push_back(flux);
1430 m_mc_min.push_back(m_lin_nodes[inx_emax]);
1431 m_mc_max.push_back(e_max);
1432 m_mc_exp.push_back(m_gamma[inx_emax]);
1433
1434 } // endelse: emin and emax not between same nodes
1435
1436 // Build cumulative distribution
1437 for (int i = 1; i < m_mc_cum.size(); ++i) {
1438 m_mc_cum[i] += m_mc_cum[i-1];
1439 }
1440 double norm = m_mc_cum[m_mc_cum.size()-1];
1441 if (norm > 0.0) {
1442 for (int i = 0; i < m_mc_cum.size(); ++i) {
1443 m_mc_cum[i] /= norm;
1444 }
1445 }
1446
1447 // Set MC values
1448 for (int i = 0; i < m_mc_cum.size(); ++i) {
1449
1450 // Compute exponent
1451 double exponent = m_mc_exp[i] + 1.0;
1452
1453 // Exponent dependend computation
1454 if (std::abs(exponent) > 1.0e-11) {
1455
1456 // If the exponent is too small then use lower energy
1457 // boundary
1458 if (exponent < -50.0) {
1459 m_mc_exp[i] = 0.0;
1460 m_mc_min[i] = std::log(m_mc_min[i]);
1461 m_mc_max[i] = m_mc_min[i];
1462 }
1463
1464 // ... otherwise if exponent is too large then use
1465 // upper energy boundary
1466 else if (exponent > +50.0) {
1467 m_mc_exp[i] = 0.0;
1468 m_mc_min[i] = std::log(m_mc_max[i]);
1469 m_mc_max[i] = m_mc_min[i];
1470 }
1471
1472 // ... otherwise use transformation formula
1473 else {
1474 m_mc_exp[i] = exponent;
1475 m_mc_min[i] = std::pow(m_mc_min[i], exponent);
1476 m_mc_max[i] = std::pow(m_mc_max[i], exponent);
1477 }
1478 }
1479 else {
1480 m_mc_exp[i] = 0.0;
1481 m_mc_min[i] = std::log(m_mc_min[i]);
1482 m_mc_max[i] = std::log(m_mc_max[i]);
1483 }
1484
1485 } // endfor: set MC values
1486
1487 } // endif: e_max > e_min
1488
1489 } // endif: Update was required
1490
1491 // Return
1492 return;
1493}
#define G_WRITE
#define G_READ
#define G_APPEND
Comma-separated values table class definition.
Energy container class definition.
Exception handler interface definition.
#define G_INSERT
#define G_REMOVE
#define G_INTENSITY2
const GModelSpectralFunc g_spectral_func_seed
#define G_ENERGY1
#define G_ENERGY2
#define G_INTENSITY1
#define G_LOAD_NODES
Spectral function 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
Comma-separated values table class.
Definition GCsv.hpp:57
const int & nrows(void) const
Return number of rows.
Definition GCsv.hpp:149
double real(const int &row, const int &col) const
Get double precision value.
Definition GCsv.cpp:324
void save(const GFilename &filename, const std::string &sep=" ", const bool &clobber=false) const
Save CSV table.
Definition GCsv.cpp:519
const int & ncols(void) const
Return number of columns.
Definition GCsv.hpp:137
Energy container class.
Definition GEnergies.hpp:60
int size(void) const
Return number of energies in container.
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
double log10MeV(void) const
Return log10 of energy in MeV.
Definition GEnergy.cpp:423
std::string print(const GChatter &chatter=NORMAL) const
Print energy.
Definition GEnergy.cpp:748
void clear(void)
Clear instance.
Definition GEnergy.cpp:261
Filename class.
Definition GFilename.hpp:62
std::string url(void) const
Return Uniform Resource Locator (URL)
bool is_empty(void) const
Signal if filename is empty.
void clear(void)
Clear file name.
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 function model class.
GModelPar m_norm
Normalization factor.
virtual void clear(void)
Clear file function.
GNodeArray m_log_nodes
log10(Energy) nodes of function
virtual double flux(const GEnergy &emin, const GEnergy &emax) const
Returns model photon flux between [emin, emax] (units: ph/cm2/s)
std::vector< double > m_flux
Photon fluxes.
int nodes(void) const
Return number of nodes in file function.
void init_members(void)
Initialise class members.
void save(const GFilename &filename, const bool &clobber=false) const
Save file function in ASCII file.
GEnergy energy(const int &index) const
Return energy of node.
virtual std::string type(void) const
Return model type.
virtual void read(const GXmlElement &xml)
Read model from XML element.
std::vector< double > m_eflux
Energy fluxes.
void set_cache(void) const
Set pre-computation cache.
void copy_members(const GModelSpectralFunc &model)
Copy class members.
void insert(const GEnergy &energy, const double &intensity)
Insert node into file function.
double intensity(const int &index) const
Return intensity of node.
std::vector< double > m_prefactor
Power-law normalisations.
virtual ~GModelSpectralFunc(void)
Destructor.
std::vector< double > m_mc_max
Upper boundary for MC.
virtual GModelSpectralFunc * clone(void) const
Clone file function.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print file function information.
std::vector< double > m_lin_values
Function values at nodes.
virtual double eflux(const GEnergy &emin, const GEnergy &emax) const
Returns model energy flux between [emin, emax] (units: erg/cm2/s)
std::vector< double > m_mc_min
Lower boundary for MC.
void remove(const int &index)
Remove node from file function.
const GFilename & filename(void) const
Return file name.
void extend(const GModelSpectralFunc &filefct)
Append file function.
void load_nodes(const GFilename &filename)
Load nodes from file.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const
Evaluate function.
double norm(void) const
Return normalization factor.
std::vector< double > m_epivot
Power-law pivot energies.
void reserve(const int &num)
Reserves space for nodes in file function.
GEnergy m_mc_emax
Maximum energy.
std::vector< double > m_mc_cum
Cumulative distribution.
void mc_update(const GEnergy &emin, const GEnergy &emax) const
Set MC pre-computation cache.
std::vector< double > m_log_values
log10(Function) values at nodes
void append(const GEnergy &energy, const double &intensity)
Append node to file function.
virtual GEnergy mc(const GEnergy &emin, const GEnergy &emax, const GTime &time, GRan &ran) const
Returns MC energy between [emin, emax].
std::vector< double > m_gamma
Power-law indices.
GFilename m_filename
Name of file function.
GNodeArray m_lin_nodes
Energy nodes of function.
virtual GModelSpectralFunc & operator=(const GModelSpectralFunc &model)
Assignment operator.
std::vector< double > m_mc_exp
Exponent for MC.
virtual void write(GXmlElement &xml) const
Write model into XML element.
bool is_empty(void) const
Signals if there are nodes in file function.
void free_members(void)
Delete class members.
GEnergy m_mc_emin
Minimum energy.
GModelSpectralFunc(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.
void set_value(const double &value) const
Set indices and weighting factors for interpolation.
double interpolate(const double &value, const std::vector< double > &vector) const
Interpolate value.
const int & inx_left(void) const
Returns left node index.
void remove(const int &index)
Remove one node into array.
void insert(const int &index, const double &node)
Insert one node into array.
void clear(void)
Clear node array.
void append(const double &node)
Append one node to array.
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 double & factor_gradient(void) const
Return parameter factor gradient.
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.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
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
GFilename xml_file_reduce(const GXmlElement &xml, const std::string &filename)
Reduce file name provided for writing as XML attribute.
Definition GTools.cpp:1946
void xml_check_parnum(const std::string &origin, const GXmlElement &xml, const int &number)
Checks number of parameters.
Definition GTools.cpp:1777
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
GFilename xml_file_expand(const GXmlElement &xml, const std::string &filename)
Expand file name provided as XML attribute for loading.
Definition GTools.cpp:1889
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.
Definition GTools.cpp:1819