46 #define G_FLUX "GModelSpectralNodes::flux(GEnergy&, GEnergy&)"
47 #define G_EFLUX "GModelSpectralNodes::eflux(GEnergy&, GEnergy&)"
48 #define G_MC "GModelSpectralNodes::mc(GEnergy&, GEnergy&, GTime&, GRan&)"
49 #define G_READ "GModelSpectralNodes::read(GXmlElement&)"
50 #define G_WRITE "GModelSpectralNodes::write(GXmlElement&)"
51 #define G_APPEND "GModelSpectralNodes::append(GEnergy&, double&)"
52 #define G_INSERT "GModelSpectralNodes::insert(int&, GEnergy&, double&)"
53 #define G_REMOVE "GModelSpectralNodes::remove(int&)"
54 #define G_ENERGY_GET "GModelSpectralNodes::energy(int&)"
55 #define G_ENERGY_SET "GModelSpectralNodes::energy(int&, GEnergy&)"
56 #define G_INTENSITY_GET "GModelSpectralNodes::intensity(int&)"
57 #define G_INTENSITY_SET "GModelSpectralNodes::intensity(int&, double&)"
58 #define G_ERROR_GET "GModelSpectralNodes::error(int&)"
107 for (
int i = 0; i < energies.
size(); ++i) {
186 if (
this != &model) {
280 const GTime& srcTime,
281 const bool& gradients)
const
300 double value =
std::pow(10.0, exponent);
306 for (
int i = 0; i <
m_values.size(); ++i) {
311 if (
m_values[inx_left].is_free() &&
m_values[inx_left].factor_value() != 0.0) {
312 double grad = value * wgt_left /
m_values[inx_left].factor_value();
313 m_values[inx_left].factor_gradient(grad);
317 if (
m_values[inx_right].is_free() &&
m_values[inx_right].factor_value() != 0.0) {
318 double grad = value * wgt_right /
m_values[inx_right].factor_value();
319 m_values[inx_right].factor_gradient(grad);
325 #if defined(G_NAN_CHECK)
327 std::cout <<
"*** ERROR: GModelSpectralNodes::eval";
328 std::cout <<
"(srcEng=" << srcEng;
329 std::cout <<
", srcTime=" << srcTime <<
"):";
330 std::cout <<
" NaN/Inf encountered";
331 std::cout <<
" (value=" << value;
332 std::cout <<
", exponent=" << exponent;
333 std::cout <<
")" << std::endl;
371 double e_min = emin.
MeV();
372 double e_max = emax.
MeV();
385 if (inx_emin == inx_emax) {
400 int i_start = (e_min <
m_lin_energies[0]) ? inx_emin : inx_emin+1;
410 for (
int i = i_start; i < inx_emax; ++i) {
458 double e_min = emin.
MeV();
459 double e_max = emax.
MeV();
472 if (inx_emin == inx_emax) {
488 int i_start = (e_min <
m_lin_energies[0]) ? inx_emin : inx_emin+1;
499 for (
int i = i_start; i < inx_emax; ++i) {
553 for (inx =
m_mc_cum.size()-1; inx > 0; --inx) {
560 std::string msg =
"No valid nodes found for energy interval ["+
561 emin.
print()+
","+emax.
print()+
"]. Either restrict "
562 "the energy range to the one covered by the "
563 "spectral nodes or extend the spectral nodes "
573 double eng = (u > 0.0)
582 double eng =
std::exp(u * (e_max - e_min) + e_min);
631 std::string msg =
"Node function model contains "+
gammalib::str(nodes)+
632 " but requires at least one node. Please specify at "
638 for (
int i = 0; i <
nodes; ++i) {
653 intensity.
read(*ipar);
656 if (energy.
value() <= 0.0) {
657 std::string msg =
"Non positive energy "+
659 "in model definition XML file. Please specify "
660 "only nodes with positive energy.";
663 if (intensity.
value() <= 0.0) {
664 std::string msg =
"Non positive intensity "+
666 "encountered in model definition XML file. "
667 "Please specify only nodes with positive "
677 energy.
name(energy_name);
682 intensity.
name(intensity_name);
683 intensity.
unit(
"ph/cm2/s/MeV");
736 for (
int i = 0; i <
nodes; ++i) {
744 " child elements in XML file does not correspond "
746 " elements. Please verify the XML format.";
750 if (npars != nodes) {
751 std::string msg =
"Number of "+
gammalib::str(npars)+
" \"node\" "
752 "child elements in XML file does not correspond to "
754 " elements. Please verify the XML format.";
759 for (
int i = 0; i <
nodes; ++i) {
771 energy.
name(
"Energy");
772 intensity.
name(
"Intensity");
780 intensity.
write(*val);
802 const double& intensity)
805 if (energy.
MeV() <= 0.0) {
806 std::string msg =
"Non-positive energy "+energy.
print()+
" not allowed. "
807 "Please specify only positive energies.";
810 if (intensity <= 0.0) {
811 std::string msg =
"Non-positive intensity "+
813 "not allowed. Please specify only positive "
823 e_par.
name(
"Energy");
830 i_par.
name(
"Intensity");
831 i_par.
value(intensity);
832 i_par.
unit(
"ph/cm2/s/MeV");
869 const double& intensity)
872 #if defined(G_RANGE_CHECK)
880 if (index < 0 || index >=
nodes()) {
888 if (energy.
MeV() <= 0.0) {
889 std::string msg =
"Non-positive energy "+energy.
print()+
" not allowed. "
890 "Please specify only positive energies.";
893 if (intensity <= 0.0) {
894 std::string msg =
"Non-positive intensity "+
896 "not allowed. Please specify only positive "
906 e_par.
name(
"Energy");
913 i_par.
name(
"Intensity");
914 i_par.
value(intensity);
915 i_par.
unit(
"ph/cm2/s/MeV");
947 #if defined(G_RANGE_CHECK)
948 if (index < 0 || index >=
nodes()) {
999 int num = nodes.
nodes();
1008 for (
int i = 0; i < num; ++i) {
1040 #if defined(G_RANGE_CHECK)
1041 if (index < 0 || index >=
nodes()) {
1072 #if defined(G_RANGE_CHECK)
1073 if (index < 0 || index >=
nodes()) {
1080 if (energy.
MeV() <= 0.0) {
1081 std::string msg =
"Non-positive energy "+energy.
print()+
" not allowed. "
1082 "Please specify only positive energies.";
1111 #if defined(G_RANGE_CHECK)
1112 if (index < 0 || index >=
nodes()) {
1137 #if defined(G_RANGE_CHECK)
1138 if (index < 0 || index >=
nodes()) {
1165 #if defined(G_RANGE_CHECK)
1166 if (index < 0 || index >=
nodes()) {
1173 if (intensity <= 0.0) {
1174 std::string msg =
"Non-positive intensity "+
1176 "not allowed. Please specify only positive "
1207 result.append(
"=== GModelSpectralNodes ===");
1214 for (
int i = 0; i <
size(); ++i) {
1352 for (
int i = 0; i <
nodes; ++i) {
1412 for (
int i = 0; i <
m_energies.size(); ++i) {
1450 for (
int i = 0; i <
m_energies.size(); ++i) {
1456 for (
int i = 0; i <
m_energies.size()-1; ++i) {
1462 double fmax =
m_values[i+1].value();
1472 double prefactor = fmin /
std::pow(emin/epivot, gamma);
1475 double flux = prefactor *
1479 double eflux = prefactor *
1510 for (
int i = 0; i <
m_energies.size(); ++i) {
1519 for (
int i = 0; i <
m_values.size(); ++i) {
1520 double value =
m_values[i].value();
1542 for (
int i = 0; i <
m_energies.size(); ++i) {
1580 double e_min = emin.
MeV();
1581 double e_max = emax.
MeV();
1584 if (e_max > e_min) {
1599 if (inx_emin == inx_emax) {
1618 int i_start = (e_min <
m_lin_energies[0]) ? inx_emin : inx_emin+1;
1632 for (
int i = i_start; i < inx_emax; ++i) {
1654 for (
int i = 1; i <
m_mc_cum.size(); ++i) {
1659 for (
int i = 0; i <
m_mc_cum.size(); ++i) {
1665 for (
int i = 0; i <
m_mc_cum.size(); ++i) {
1668 double exponent =
m_mc_exp[i] + 1.0;
1671 if (
std::abs(exponent) > 1.0e-11) {
1675 if (exponent < -50.0) {
1683 else if (exponent > +50.0) {
std::vector< double > m_flux
Photon fluxes.
void update_flux_cache(void) const
Update flux computation cache.
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_eflux
Energy fluxes.
double norm(const GVector &vector)
Computes vector norm.
virtual GModelSpectralNodes & operator=(const GModelSpectralNodes &model)
Assignment operator.
const std::string & name(void) const
Return parameter name.
Random number generator class definition.
Abstract spectral model base class.
virtual std::string type(void) const
Return model type.
int size(void) const
Return number of parameters.
void insert(const int &index, const GEnergy &energy, const double &intensity)
Insert node.
GVector abs(const GVector &vector)
Computes absolute of vector elements.
virtual GModelSpectral & operator=(const GModelSpectral &model)
Assignment operator.
void extend(const GModelSpectralNodes &nodes)
Append nodes from node function.
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
std::vector< double > m_mc_max
Upper boundary for MC.
std::vector< double > m_old_energies
Old energies.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const =0
std::vector< GModelPar * > m_pars
Parameter pointers.
const double & wgt_left(void) const
Returns left node weight.
Spectral model registry class definition.
void clear(void)
Clear node array.
Random number generator class.
virtual double flux(const GEnergy &emin, const GEnergy &emax) const
Returns model photon flux between emin, emax
virtual double eflux(const GEnergy &emin, const GEnergy &emax) const
Returns model energy flux between emin, emax
Spectral nodes model class definition.
std::vector< double > m_epivot
Power-law pivot energies.
double MeV(void) const
Return energy in MeV.
virtual int elements(void) const
Return number of GXMLElement children of node.
std::vector< double > m_mc_cum
Cumulative distribution.
void reserve(const int &num)
Reserve space for nodes.
void set_value(const double &value) const
Set indices and weighting factors for interpolation.
GNodeArray m_lin_energies
Energy of nodes.
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.
double log10MeV(void) const
Return log10 of energy in MeV.
Spectral nodes model class.
std::vector< double > m_log_values
log10(value) of nodes
std::vector< GModelPar > m_values
Node values.
bool is_notanumber(const double &x)
Signal if argument is not a number.
void set_flux_cache(void) const
Set flux computation cache.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print node function information.
bool is_infinite(const double &x)
Signal if argument is infinite.
void append(const GEnergy &energy, const double &intensity)
Append node.
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
const double & wgt_right(void) const
Returns right node weight.
virtual GModelSpectralNodes * clone(void) const
Clone spectral nodes model.
void copy_members(const GModelSpectralNodes &model)
Copy class members.
std::string print(const GChatter &chatter=NORMAL) const
Print energy.
void free(void)
Free a parameter.
virtual void write(GXmlElement &xml) const
Write model into XML element.
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const
Evaluate function.
Energy container class definition.
void fix(void)
Fix a parameter.
int size(void) const
Return number of energies in container.
GXmlElement * xml_need_par(const std::string &origin, GXmlElement &xml, const std::string &name)
Return pointer to parameter with given name in XML element.
GVector log(const GVector &vector)
Computes natural logarithm of vector elements.
GModelSpectralNodes(void)
Void constructor.
double uniform(void)
Returns random double precision floating value in range 0 to 1.
void check_energy_interval(const std::string &origin, const GEnergy &emin, const GEnergy &emax)
Checks energy interval.
virtual ~GModelSpectralNodes(void)
Destructor.
std::vector< double > m_mc_exp
Exponent for MC.
void update_pars(void)
Update parameter mapping.
void set_eval_cache(void) const
Set evaluation cache.
GEnergy m_mc_emax
Maximum energy.
const int & inx_left(void) const
Returns left node index.
GEnergy energy(const int &index) const
Return node energy.
std::vector< double > m_lin_values
Values of nodes.
const GModelSpectralNodes g_spectral_nodes_seed
Interface definition for the spectral model registry class.
const int & inx_right(void) const
Returns right node index.
double intensity(const int &index) const
Return node intensity.
std::vector< double > m_mc_min
Lower boundary for MC.
void free_members(void)
Delete class members.
double error(const int &index) const
Return intensity error of node.
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
void update_eval_cache(void) const
Update evaluation cache.
virtual void clear(void)
Clear spectral nodes model.
void init_members(void)
Initialise class members.
std::vector< GModelPar > m_energies
Node energies.
void init_members(void)
Initialise class members.
int nodes(void) const
Return number of nodes.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
double value(void) const
Return parameter value.
const std::string & unit(void) const
Return parameter unit.
GVector pow(const GVector &vector, const double &power)
Computes tanh of vector elements.
std::vector< double > m_prefactor
Power-law normalisations.
GEnergy m_mc_emin
Minimum energy.
Exception handler interface definition.
virtual void read(const GXmlElement &xml)
Read model from XML element.
void mc_update(const GEnergy &emin, const GEnergy &emax) const
Set MC pre-computation cache.
GVector exp(const GVector &vector)
Computes exponential of vector elements.
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
void append(const double &node)
Append one node to array.
void remove(const int &index)
Remove node.
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.
void free_members(void)
Delete class members.
void clear(void)
Clear instance.
void set_cache(void) const
Set pre-computation cache.
std::vector< double > m_old_values
Old values.
GVector log10(const GVector &vector)
Computes base10 logarithm of vector elements.
Class that handles energies in a unit independent way.
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.
std::vector< double > m_gamma
Power-law indices.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
GNodeArray m_log_energies
log10(energy) of nodes
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.