GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GModelSpectralGauss.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GModelSpectralGauss.cpp - Spectral Gaussian model class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2014-2021 by Christoph Deil & Ellis Owen *
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 GModelSpectralGauss.cpp
23  * @brief Gaussian spectral model class implementation
24  * @author Christoph Deil & Ellis Owen
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include "GException.hpp"
32 #include "GTools.hpp"
33 #include "GMath.hpp"
34 #include "GRan.hpp"
35 #include "GFunction.hpp"
36 #include "GIntegral.hpp"
37 #include "GModelSpectralGauss.hpp"
39 
40 /* __ Constants __________________________________________________________ */
41 
42 /* __ Globals ____________________________________________________________ */
44 const GModelSpectralRegistry g_spectral_gauss_registry(&g_spectral_gauss_seed);
45 
46 /* __ Method name definitions ____________________________________________ */
47 #define G_FLUX "GModelSpectralGauss::flux(GEnergy&, GEnergy&)"
48 #define G_EFLUX "GModelSpectralGauss::eflux(GEnergy&, GEnergy&)"
49 #define G_MC "GModelSpectralGauss::mc(GEnergy&, GEnergy&, GRan&)"
50 #define G_READ "GModelSpectralGauss::read(GXmlElement&)"
51 #define G_WRITE "GModelSpectralGauss::write(GXmlElement&)"
52 
53 /* __ Macros _____________________________________________________________ */
54 
55 /* __ Coding definitions _________________________________________________ */
56 
57 /* __ Debug definitions __________________________________________________ */
58 
59 
60 /*==========================================================================
61  = =
62  = Constructors/destructors =
63  = =
64  ==========================================================================*/
65 
66 /***********************************************************************//**
67  * @brief Void constructor
68  ***************************************************************************/
70 {
71  // Initialise members
72  init_members();
73 
74  // Return
75  return;
76 }
77 
78 
79 /***********************************************************************//**
80  * @brief XML constructor
81  *
82  * @param[in] xml XML element.
83  *
84  * Constructs constant spectral model by extracting information from an XML
85  * element. See the read() method for more information about the expected
86  * structure of the XML element.
87  ***************************************************************************/
90 {
91  // Initialise members
92  init_members();
93 
94  // Read information from XML element
95  read(xml);
96 
97  // Return
98  return;
99 }
100 
101 
102 /***********************************************************************//**
103  * @brief Constructor
104  *
105  * @param[in] norm Total flux under Gaussian (in ph/cm2/s).
106  * @param[in] mean Mean energy.
107  * @param[in] sigma Energy width.
108  ***************************************************************************/
110  const GEnergy& mean,
111  const GEnergy& sigma) :
113 {
114  // Initialise members
115  init_members();
116 
117  // Set parameters
118  m_norm.value(norm);
119  m_mean.value(mean.MeV());
120  m_sigma.value(sigma.MeV());
121 
122  // Autoscale parameters
123  autoscale();
124 
125  // Return
126  return;
127 }
128 
129 
130 /***********************************************************************//**
131  * @brief Copy constructor
132  *
133  * @param[in] model Spectral Gaussian model.
134  ***************************************************************************/
136  GModelSpectral(model)
137 {
138  // Initialise members
139  init_members();
140 
141  // Copy members
142  copy_members(model);
143 
144  // Return
145  return;
146 }
147 
148 
149 /***********************************************************************//**
150  * @brief Destructor
151  ***************************************************************************/
153 {
154  // Free members
155  free_members();
156 
157  // Return
158  return;
159 }
160 
161 
162 /*==========================================================================
163  = =
164  = Operators =
165  = =
166  ==========================================================================*/
167 
168 /***********************************************************************//**
169  * @brief Assignment operator
170  *
171  * @param[in] model Gauss spectral model.
172  * @return Gauss spectral model.
173  ***************************************************************************/
175 {
176  // Execute only if object is not identical
177  if (this != &model) {
178 
179  // Copy base class members
180  this->GModelSpectral::operator=(model);
181 
182  // Free members
183  free_members();
184 
185  // Initialise members
186  init_members();
187 
188  // Copy members
189  copy_members(model);
190 
191  } // endif: object was not identical
192 
193  // Return
194  return *this;
195 }
196 
197 
198 /*==========================================================================
199  = =
200  = Public methods =
201  = =
202  ==========================================================================*/
203 
204 /***********************************************************************//**
205  * @brief Clear Gaussian spectral model
206  ***************************************************************************/
208 {
209  // Free class members (base and derived classes, derived class first)
210  free_members();
212 
213  // Initialise members
215  init_members();
216 
217  // Return
218  return;
219 }
220 
221 
222 /***********************************************************************//**
223  * @brief Clone Gaussian spectral model
224  *
225  * @return Pointer to deep copy of Gaussian spectral model.
226  ***************************************************************************/
228 {
229  // Clone Gaussian spectral model
230  return new GModelSpectralGauss(*this);
231 }
232 
233 
234 /***********************************************************************//**
235  * @brief Evaluate model value
236  *
237  * @param[in] srcEng True photon energy.
238  * @param[in] srcTime True photon arrival time.
239  * @param[in] gradients Compute gradients?
240  * @return Model value (ph/cm2/s/MeV).
241  *
242  * Evaluates
243  *
244  * \f[
245  * S_{\rm E}(E | t) = \frac{m\_norm}{\sqrt{2\pi}m\_sigma}
246  * \exp(\frac{-(E-m\_mean)^2}{2 m\_sigma^2})
247  * \f]
248  *
249  * where
250  * - \f${\tt m\_norm}\f$ is the normalization,
251  * - \f${\tt m\_mean}\f$ is the mean energy, and
252  * - \f${\tt m\_sigma}\f$ is the energy width.
253  *
254  * If the @p gradients flag is true the method will also compute the
255  * partial derivatives of the model with respect to the parameters using
256  *
257  * \f[
258  * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_norm}} =
259  * \frac{S_{\rm E}(E | t)}{{\tt m\_norm}}
260  * \f]
261  *
262  * \f[
263  * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_mean}} =
264  * S_{\rm E}(E | t) \frac{E-m\_mean}{m\_sigma^2}
265  * \f]
266  *
267  * \f[
268  * \frac{\delta S_{\rm E}(E | t)}{\delta {\tt m\_sigma}} =
269  * \frac{S_{\rm E}(E | t)}{{\tt m\_sigma}}
270  * \left( \frac{(E-m\_mean)^2}{m\_sigma^2} - 1 \right)
271  * \f]
272  ***************************************************************************/
273 double GModelSpectralGauss::eval(const GEnergy& srcEng,
274  const GTime& srcTime,
275  const bool& gradients) const
276 {
277  // Get parameter values
278  double energy = srcEng.MeV();
279  double norm = m_norm.value();
280  double mean = m_mean.value();
281  double sigma = m_sigma.value();
282 
283  // Compute function terms
284  double delta = energy - mean;
285  double sigma2 = sigma * sigma;
286  double term2 = (1.0 / sigma) * gammalib::inv_sqrt2pi;
287  double term1 = norm * term2;
288  double term3 = delta * delta / (2.0 * sigma2);
289  double term4 = delta / sigma2;
290  double term5 = (norm / sigma2) * gammalib::inv_sqrt2pi;
291  double eterm3 = std::exp(-term3);
292 
293  // Compute function value
294  double value = term1 * eterm3;
295 
296  // Optionally compute gradients
297  if (gradients) {
298 
299  // Compute partial derivatives with respect to the parameter factor
300  // values (partial differentials were determined analytically).
301  double g_norm = (m_norm.is_free())
302  ? term2 * eterm3 * m_norm.scale() : 0.0;
303  double g_mean = (m_mean.is_free())
304  ? value * term4 * m_mean.scale() : 0.0;
305  double g_sigma = (m_sigma.is_free())
306  ? -term5 * eterm3 * (1.0 - (2.0 * term3)) * m_sigma.scale()
307  : 0.0;
308 
309  // Set gradients
310  m_norm.factor_gradient(g_norm);
311  m_mean.factor_gradient(g_mean);
312  m_sigma.factor_gradient(g_sigma);
313 
314  } // endif: gradient computation was requested
315 
316  // Compile option: Check for NaN/Inf
317  #if defined(G_NAN_CHECK)
318  if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
319  std::cout << "*** ERROR: GModelSpectralGauss::eval";
320  std::cout << "(srcEng=" << srcEng;
321  std::cout << ", srcTime=" << srcTime << "):";
322  std::cout << " NaN/Inf encountered";
323  std::cout << " (value=" << value;
324  std::cout << ")" << std::endl;
325  }
326  #endif
327 
328  // Return
329  return value;
330 }
331 
332 
333 /***********************************************************************//**
334  * @brief Returns model photon flux between [emin, emax] (ph/cm2/s)
335  *
336  * @param[in] emin Minimum photon energy.
337  * @param[in] emax Maximum photon energy.
338  * @return Photon flux (ph/cm2/s).
339  *
340  * Computes
341  *
342  * \f[
343  * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) dE
344  * \f]
345  *
346  * where
347  * - [@p emin, @p emax] is an energy interval, and
348  * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
349  * The integration is done analytically.
350  ***************************************************************************/
352  const GEnergy& emax) const
353 {
354  // Initialise flux
355  double flux = 0.0;
356 
357  // Compute only if integration range is valid
358  if (emin < emax) {
359 
360  // Precomputations
361  double energy_min = emin.MeV();
362  double energy_max = emax.MeV();
363  double norm = m_norm.value();
364  double mean = m_mean.value();
365  double sigma = m_sigma.value();
366  double zmin = (energy_min - mean) / sigma;
367  double zmax = (energy_max - mean) / sigma;
368 
369  // Compute flux for a constant model
370  flux = norm * gammalib::gauss_integral(zmin, zmax);
371 
372  } // endif: integration range was valid
373 
374  // Return
375  return flux;
376 }
377 
378 
379 /***********************************************************************//**
380  * @brief Returns model energy flux between [emin, emax] (erg/cm2/s)
381  *
382  * @param[in] emin Minimum photon energy.
383  * @param[in] emax Maximum photon energy.
384  * @return Energy flux (erg/cm2/s).
385  *
386  * Computes
387  *
388  * \f[
389  * \int_{\tt emin}^{\tt emax} S_{\rm E}(E | t) E \, dE
390  * \f]
391  *
392  * where
393  * - [@p emin, @p emax] is an energy interval, and
394  * - \f$S_{\rm E}(E | t)\f$ is the spectral model (ph/cm2/s/MeV).
395  * The integration is done analytically.
396  ***************************************************************************/
398  const GEnergy& emax) const
399 {
400  // Initialise flux
401  double eflux = 0.0;
402 
403  // Compute only if integration range is valid
404  if (emin < emax) {
405 
406  // Setup integration kernel
407  eflux_kernel integrand(m_norm.value(), m_mean.value(),
408  m_sigma.value());
409  GIntegral integral(&integrand);
410 
411  // Get integration boundaries in MeV
412  double e_min = emin.MeV();
413  double e_max = emax.MeV();
414 
415  // Perform integration
416  eflux = integral.romberg(e_min, e_max);
417 
418  // Convert from MeV/cm2/s to erg/cm2/s
419  eflux *= gammalib::MeV2erg;
420 
421  } // endif: integration range was valid
422 
423  // Return
424  return eflux;
425 }
426 
427 
428 /***********************************************************************//**
429  * @brief Returns MC energy between [emin, emax]
430  *
431  * @param[in] emin Minimum photon energy.
432  * @param[in] emax Maximum photon energy.
433  * @param[in] time True photon arrival time.
434  * @param[in,out] ran Random number generator.
435  * @return Energy.
436  *
437  * @exception GException::erange_invalid
438  * Energy range is invalid (emin < emax required).
439  *
440  * Returns Monte Carlo energy by randomly drawing from a constant between
441  * the minimum and maximum photon energy.
442  *
443  * Method Used: Box-Muller transform, outlined here:
444  * http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
445  *
446  * Code from: http://www.design.caltech.edu/erik/Misc/Gaussian.html
447  ***************************************************************************/
449  const GEnergy& emax,
450  const GTime& time,
451  GRan& ran) const
452 {
453  // Check energy interval
455 
456  // Get energy boundaries in MeV
457  double xmax = emax.MeV();
458  double xmin = emin.MeV();
459 
460  // Initialize return energy
461  double energy = 0.0;
462 
463  // Sample until we find a value within the requested energy range
464  do {
465 
466  // Compute random value
467  double val = ran.normal();
468 
469  // Scale to specified width and shift by mean value
470  energy = m_sigma.value() * val + m_mean.value();
471 
472  } while (energy < xmin || energy > xmax);
473 
474 
475  // Return energy
476  return GEnergy(energy, "MeV");
477 }
478 
479 
480 /***********************************************************************//**
481  * @brief Read model from XML element
482  *
483  * @param[in] xml XML element containing Gaussian model information.
484  *
485  * Read the spectral Gaussian information from an XML element.
486  * The format of the XML elements is:
487  *
488  * <spectrum type="Gaussian">
489  * <parameter name="Normalization" scale=".." value=".." min=".." max=".." free=".."/>
490  * <parameter name="Mean" scale=".." value=".." min=".." max=".." free=".."/>
491  * <parameter name="Sigma" scale=".." value=".." min=".." max=".." free=".."/>
492  * </spectrum>
493  *
494  ***************************************************************************/
496 {
497  // Verify number of model parameters
499 
500  // Get parameters
504 
505  // Read parameters
506  m_norm.read(*norm);
507  m_mean.read(*mean);
508  m_sigma.read(*sigma);
509 
510  // Return
511  return;
512 }
513 
514 
515 /***********************************************************************//**
516  * @brief Write model into XML element
517  *
518  * @param[in] xml XML element into which model information is written.
519  *
520  * Writes the spectral information into an XML element. The format of the XML
521  * element is
522  *
523  * <spectrum type="Gaussian">
524  * <parameter name="Normalization" scale=".." value=".." min=".." max=".." free=".."/>
525  * <parameter name="Mean" scale=".." value=".." min=".." max=".." free=".."/>
526  * <parameter name="Sigma" scale=".." value=".." min=".." max=".." free=".."/>
527  * </spectrum>
528  ***************************************************************************/
530 {
531  // Verify model type
533 
534  // Get XML parameters
538 
539  // Write parameters
540  m_norm.write(*norm);
541  m_mean.write(*mean);
542  m_sigma.write(*sigma);
543 
544  // Return
545  return;
546 }
547 
548 
549 /***********************************************************************//**
550  * @brief Print spectral model information
551  *
552  * @param[in] chatter Chattiness (defaults to NORMAL).
553  * @return String containing spectral model information.
554  ***************************************************************************/
555 std::string GModelSpectralGauss::print(const GChatter& chatter) const
556 {
557  // Initialise result string
558  std::string result;
559 
560  // Continue only if chatter is not silent
561  if (chatter != SILENT) {
562 
563  // Append header
564  result.append("=== GModelSpectralGauss ===");
565 
566  // Append model content
567  result.append("\n"+gammalib::parformat("Number of parameters"));
568  result.append(gammalib::str(size()));
569  for (int i = 0; i < size(); ++i) {
570  result.append("\n"+m_pars[i]->print(chatter));
571  }
572 
573  } // endif: chatter was not silent
574 
575  // Return result
576  return result;
577 }
578 
579 
580 /*==========================================================================
581  = =
582  = Private methods =
583  = =
584  ==========================================================================*/
585 
586 /***********************************************************************//**
587  * @brief Initialise class members
588  ***************************************************************************/
590 {
591  // Initialise normalisation
592  m_norm.clear();
593  m_norm.name("Normalization");
594  m_norm.unit("ph/cm2/s");
595  m_norm.scale(1.0);
596  m_norm.value(1.0); // default: 1.0
597  m_norm.min(0.0); // min: 0.0
598  m_norm.free();
599  m_norm.gradient(0.0);
600  m_norm.has_grad(false);
601 
602  // Initialise mean energy
603  m_mean.clear();
604  m_mean.name("Mean");
605  m_mean.unit("MeV");
606  m_mean.scale(1.0);
607  m_mean.value(1000.0); // default: 1000.0
608  m_mean.min(0.001); // min: 0.001 MeV
609  m_mean.free();
610  m_mean.gradient(0.0);
611  m_mean.has_grad(false);
612 
613  // Initialise energy width
614  m_sigma.clear();
615  m_sigma.name("Sigma");
616  m_sigma.unit("MeV");
617  m_sigma.scale(1.0);
618  m_sigma.value(100.0); // default: 100.0 MeV
619  m_sigma.min(0.0001); // min: 0.1 keV
620  m_sigma.free();
621  m_sigma.gradient(0.0);
622  m_sigma.has_grad(false);
623 
624  // Set parameter pointer(s)
625  m_pars.clear();
626  m_pars.push_back(&m_norm);
627  m_pars.push_back(&m_mean);
628  m_pars.push_back(&m_sigma);
629 
630  // Return
631  return;
632 }
633 
634 
635 /***********************************************************************//**
636  * @brief Copy class members
637  *
638  * @param[in] model Spectral constant model.
639  ***************************************************************************/
641 {
642  // Copy members
643  m_norm = model.m_norm;
644  m_mean = model.m_mean;
645  m_sigma = model.m_sigma;
646 
647  // Set parameter pointer(s)
648  m_pars.clear();
649  m_pars.push_back(&m_norm);
650  m_pars.push_back(&m_mean);
651  m_pars.push_back(&m_sigma);
652 
653  // Return
654  return;
655 }
656 
657 
658 /***********************************************************************//**
659  * @brief Delete class members
660  ***************************************************************************/
662 {
663  // Return
664  return;
665 }
666 
667 /***********************************************************************//**
668  * @brief Kernel for energy flux integration
669  *
670  * @param[in] energy Energy (MeV).
671  ***************************************************************************/
672 double GModelSpectralGauss::eflux_kernel::eval(const double& energy)
673 {
674  // Evaluate function value
675  double delta = energy - m_mean;
676  double term1 = (m_norm / m_sigma) * gammalib::inv_sqrt2pi;
677  double term2 = delta * delta / (2.0 * m_sigma * m_sigma);
678  double value = term1 * std::exp(- term2);
679 
680  // Return value
681  return value;
682 }
const double & factor_gradient(void) const
Return parameter factor gradient.
double norm(const GVector &vector)
Computes vector norm.
Definition: GVector.cpp:864
virtual GModelSpectralGauss & operator=(const GModelSpectralGauss &model)
Assignment operator.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print spectral model information.
const std::string & name(void) const
Return parameter name.
Random number generator class definition.
Abstract spectral model base class.
double gradient(void) const
Return parameter gradient.
int size(void) const
Return number of parameters.
virtual GModelSpectral & operator=(const GModelSpectral &model)
Assignment operator.
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
Definition: GModelPar.cpp:351
double gauss_integral(const double &x1, const double &x2)
Returns the integral of a Gaussian function.
Definition: GMath.cpp:605
std::vector< GModelPar * > m_pars
Parameter pointers.
virtual GEnergy mc(const GEnergy &emin, const GEnergy &emax, const GTime &time, GRan &ran) const
Returns MC energy between [emin, emax].
const GModelSpectralGauss g_spectral_gauss_seed
virtual void clear(void)
Clear Gaussian spectral model.
#define G_WRITE
XML element node class.
Definition: GXmlElement.hpp:48
Spectral model registry class definition.
Random number generator class.
Definition: GRan.hpp:44
double MeV(void) const
Return energy in MeV.
Definition: GEnergy.cpp:321
Time class.
Definition: GTime.hpp:55
Gammalib tools definition.
GIntegral class interface definition.
Definition: GIntegral.hpp:46
#define G_READ
double eval(const double &eng)
Kernel for energy flux integration.
double min(void) const
Return parameter minimum boundary.
bool is_free(void) const
Signal if parameter is free.
GModelPar m_norm
Normalization factor.
Gaussian spectral model class.
virtual double eflux(const GEnergy &emin, const GEnergy &emax) const
Returns model energy flux between emin, emax
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition: GTools.hpp:201
const double & scale(void) const
Return parameter scale.
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition: GTools.hpp:184
virtual GModelSpectralGauss * clone(void) const
Clone Gaussian spectral model.
#define G_MC
virtual double eval(const GEnergy &srcEng, const GTime &srcTime=GTime(), const bool &gradients=false) const
Evaluate model value.
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
void copy_members(const GModelSpectralGauss &model)
Copy class members.
Single parameter function abstract base class definition.
virtual void read(const GXmlElement &xml)
Read model from XML element.
void free(void)
Free a parameter.
virtual void write(GXmlElement &xml) const
Write model into 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.
Definition: GTools.cpp:1637
void init_members(void)
Initialise class members.
void check_energy_interval(const std::string &origin, const GEnergy &emin, const GEnergy &emax)
Checks energy interval.
Definition: GException.cpp:364
void clear(void)
Clear parameter.
GEnergy mean(void) const
Return mean energy.
GModelPar m_sigma
Gaussian energy width.
GChatter
Definition: GTypemaps.hpp:33
void free_members(void)
Delete class members.
virtual ~GModelSpectralGauss(void)
Destructor.
double norm(void) const
Return normalization.
void xml_check_parnum(const std::string &origin, const GXmlElement &xml, const int &number)
Checks number of parameters.
Definition: GTools.cpp:1777
Interface definition for the spectral model registry class.
double normal(void)
Returns normal deviates.
Definition: GRan.cpp:257
void autoscale(void)
Autoscale parameters.
virtual double flux(const GEnergy &emin, const GEnergy &emax) const
Returns model photon flux between emin, emax
virtual std::string type(void) const
Return model type.
void init_members(void)
Initialise class members.
const double MeV2erg
Definition: GTools.hpp:45
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Definition: GModelPar.cpp:229
double value(void) const
Return parameter value.
const double inv_sqrt2pi
Definition: GMath.hpp:41
const std::string & unit(void) const
Return parameter unit.
GModelSpectralGauss(void)
Void constructor.
Exception handler interface definition.
GVector exp(const GVector &vector)
Computes exponential of vector elements.
Definition: GVector.cpp:1232
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
Integration class interface definition.
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
void free_members(void)
Delete class members.
Gaussian spectral model class interface definition.
GModelPar m_mean
Gaussian mean energy.
GEnergy sigma(void) const
Return energy width.
Mathematical function definitions.
Class that handles energies in a unit independent way.
Definition: GEnergy.hpp:48
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.
Definition: GTools.cpp:1819