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&, "\
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&)"
104 const double& index) :
111 for (
int i = 0; i < ebounds.
size(); ++i) {
193 if (
this != &model) {
259 const GTime& srcTime,
260 const bool& gradients)
const
268 for (
int i = 0; i <
m_values.size(); ++i) {
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;
288 value =
m_values[ibin].value() * power;
294 double g_norm = (
m_values[ibin].is_free())
295 ?
m_values[ibin].scale() * power : 0.0;
300 m_values[ibin].factor_gradient(g_norm);
306 #if defined(G_NAN_CHECK)
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;
356 for (
int ibin = 0; ibin <
bins(); ++ibin) {
359 double e_bin_min =
m_emin[ibin].value();
360 double e_bin_max =
m_emax[ibin].value();
363 if (e_min >= e_bin_max || e_max < e_bin_min) {
368 if (e_bin_min < e_min) {
373 if (e_bin_max > e_max) {
378 if (e_bin_max > e_bin_min) {
430 for (
int ibin = 0; ibin <
bins(); ++ibin) {
433 double e_bin_min =
m_emin[ibin].value();
434 double e_bin_max =
m_emax[ibin].value();
437 if (e_min >= e_bin_max || e_max < e_bin_min) {
442 if (e_bin_min < e_min) {
447 if (e_bin_max > e_max) {
452 if (e_bin_max > e_bin_min) {
508 for (inx =
m_mc_cum.size()-1; inx > 0; --inx) {
515 std::string msg =
"No valid bins found for energy interval ["+
517 "the energy range to the one covered by the "
518 "spectral bins or extend the spectral bins "
528 double eng = (u > 0.0)
529 ? std::exp(std::log(u * (e_max - e_min) + e_min) /
m_mc_exp[inx])
537 double eng = std::exp(u * (e_max - e_min) + e_min);
592 for (
int i = 0; i <
bins; ++i) {
615 " MeV is larger than upper energy limit "+
617 "specify lower energy limits that are smaller "
618 "than the upper energy limits.";
683 for (
int i = 0; i <
bins; ++i) {
691 std::string msg =
"Spectral bins model contains "+
698 std::string msg =
"Spectral bins model contains "+
701 " \"bin\" elements were expected.";
706 for (
int i = 0; i <
bins; ++i) {
719 emin.name(
"LowerLimit");
720 emax.name(
"UpperLimit");
755 const double& intensity)
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.";
772 par_emin.
name(
"LowerLimit");
774 par_emin.
unit(
"MeV");
779 par_emax.
name(
"UpperLimit");
781 par_emax.
unit(
"MeV");
786 par_intensity.
name(
"Intensity");
788 par_intensity.
unit(
"ph/cm2/s/MeV");
790 par_intensity.
free();
793 m_emin.push_back(par_emin);
794 m_emax.push_back(par_emax);
828 const double& intensity)
831 #if defined(G_RANGE_CHECK)
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.";
852 par_emin.
name(
"LowerLimit");
854 par_emin.
unit(
"MeV");
859 par_emax.
name(
"UpperLimit");
861 par_emax.
unit(
"MeV");
866 par_intensity.
name(
"Intensity");
868 par_intensity.
unit(
"ph/cm2/s/MeV");
870 par_intensity.
free();
901 #if defined(G_RANGE_CHECK)
954 int num =
bins.bins();
963 for (
int i = 0; i < num; ++i) {
1027 #if defined(G_RANGE_CHECK)
1056 #if defined(G_RANGE_CHECK)
1085 #if defined(G_RANGE_CHECK)
1116 #if defined(G_RANGE_CHECK)
1147 #if defined(G_RANGE_CHECK)
1172 #if defined(G_RANGE_CHECK)
1197 #if defined(G_RANGE_CHECK)
1226 result.append(
"=== GModelSpectralBins ===");
1233 for (
int i = 0; i <
size(); ++i) {
1343 double energy_MeV = energy.
MeV();
1346 for (
int i = 0; i <
bins(); ++i) {
1347 if (energy_MeV >=
m_emin[i].value() && energy_MeV <
m_emax[i].value()) {
1375 for (
int i = 0; i <
bins(); ++i) {
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);
1383 m_emin[i].name(lowerlimit_name);
1385 m_emin[i].has_grad(
false);
1388 m_emax[i].name(upperlimit_name);
1390 m_emax[i].has_grad(
false);
1421 for (
int i = 0; i <
bins(); ++i) {
1422 double epivot = std::sqrt(
m_emin[i].value() *
m_emax[i].value());
1461 if (e_max > e_min) {
1464 for (
int ibin = 0; ibin <
bins(); ++ibin) {
1467 double e_bin_min =
m_emin[ibin].value();
1468 double e_bin_max =
m_emax[ibin].value();
1471 if (e_min >= e_bin_max || e_max < e_bin_min) {
1476 if (e_bin_min < e_min) {
1481 if (e_bin_max > e_max) {
1486 if (e_bin_max > e_bin_min) {
1509 for (
int i = 1; i <
m_mc_cum.size(); ++i) {
1514 for (
int i = 0; i <
m_mc_cum.size(); ++i) {
1520 for (
int i = 0; i <
m_mc_cum.size(); ++i) {
1523 double exponent =
m_mc_exp[i] + 1.0;
1526 if (std::abs(exponent) > 1.0e-11) {
1530 if (exponent < -50.0) {
1538 else if (exponent > +50.0) {
Energy boundaries class interface definition.
Exception handler interface definition.
const GModelSpectralBins g_spectral_bins_seed
Spectral bins model class definition.
Spectral model registry class definition.
Random number generator class definition.
double norm(const GVector &vector)
Computes vector norm.
Energy boundaries container class.
const GEnergy & emax(void) const
Return maximum energy of all intervals.
int size(void) const
Return number of energy boundaries.
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.
Class that handles energies in a unit independent way.
double MeV(void) const
Return energy in MeV.
std::string print(const GChatter &chatter=NORMAL) const
Print energy.
void clear(void)
Clear instance.
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.
double uniform(void)
Returns random double precision floating value in range 0 to 1.
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
virtual int elements(void) const
Return number of GXMLElement children of node.
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.
bool is_infinite(const double &x)
Signal if argument is infinite.
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.
bool is_notanumber(const double &x)
Signal if argument is not a number.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
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.
GXmlElement * xml_need_par(const std::string &origin, GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
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.
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.