GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GModelSpatialEllipticalDisk.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GModelSpatialEllipticalDisk.cpp - Elliptical disk source model class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2013-2018 by Michael Mayer *
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 GModelSpatialEllipticalDisk.cpp
23  * @brief Elliptical disk model class implementation
24  * @author Michael Mayer
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"
37 
38 /* __ Constants __________________________________________________________ */
39 
40 /* __ Globals ____________________________________________________________ */
42 const GModelSpatialRegistry g_elliptical_disk_registry(&g_elliptical_disk_seed);
43 
44 /* __ Method name definitions ____________________________________________ */
45 #define G_READ "GModelSpatialEllipticalDisk::read(GXmlElement&)"
46 #define G_WRITE "GModelSpatialEllipticalDisk::write(GXmlElement&)"
47 
48 /* __ Macros _____________________________________________________________ */
49 
50 /* __ Coding definitions _________________________________________________ */
51 
52 /* __ Debug definitions __________________________________________________ */
53 
54 
55 /*==========================================================================
56  = =
57  = Constructors/destructors =
58  = =
59  ==========================================================================*/
60 
61 /***********************************************************************//**
62  * @brief Void constructor
63  ***************************************************************************/
66 {
67  // Initialise members
68  init_members();
69 
70  // Return
71  return;
72 }
73 
74 
75 /***********************************************************************//**
76  * @brief Disk constructor
77  *
78  * @param[in] dir Sky position of disk centre.
79  * @param[in] semimajor Semi-major axis (degrees).
80  * @param[in] semiminor Semi-minor axis (degrees).
81  * @param[in] posangle Position angle of semi-major axis (degrees).
82  *
83  * Construct elliptical disk model from sky position of the ellipse centre
84  * (@p dir), the @p semimajor and @p semiminor axes, and the position
85  * angle (@p posangle).
86  ***************************************************************************/
88  const double& semimajor,
89  const double& semiminor,
90  const double& posangle) :
92 {
93  // Initialise members
94  init_members();
95 
96  // Assign parameters
97  this->dir(dir);
98  this->semiminor(semiminor);
99  this->semimajor(semimajor);
100  this->posangle(posangle);
101 
102  // Return
103  return;
104 }
105 
106 
107 /***********************************************************************//**
108  * @brief XML constructor
109  *
110  * @param[in] xml XML element.
111  *
112  * Constructs elliptical disk model by extracting information from an XML
113  * element. See the read() method for more information about the expected
114  * structure of the XML element.
115  ***************************************************************************/
118 {
119  // Initialise members
120  init_members();
121 
122  // Read information from XML element
123  read(xml);
124 
125  // Return
126  return;
127 }
128 
129 
130 /***********************************************************************//**
131  * @brief Copy constructor
132  *
133  * @param[in] model Elliptical disk model.
134  ***************************************************************************/
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 Elliptical disk model.
172  * @return Elliptical disk model.
173  ***************************************************************************/
175 {
176  // Execute only if object is not identical
177  if (this != &model) {
178 
179  // Copy base class members
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 elliptical disk model
206  ***************************************************************************/
208 {
209  // Free class members (base and derived classes, derived class first)
210  free_members();
213 
214  // Initialise members
217  init_members();
218 
219  // Return
220  return;
221 }
222 
223 
224 /***********************************************************************//**
225  * @brief Clone elliptical disk model
226  *
227  * @return Pointer to deep copy of elliptical disk model.
228  ***************************************************************************/
230 {
231  // Clone elliptical disk model
232  return new GModelSpatialEllipticalDisk(*this);
233 }
234 
235 
236 /***********************************************************************//**
237  * @brief Evaluate function (in units of sr^-1)
238  *
239  * @param[in] theta Angular distance from disk centre (radians).
240  * @param[in] posangle Position angle (counterclockwise from North) (radians).
241  * @param[in] energy Photon energy.
242  * @param[in] time Photon arrival time.
243  * @param[in] gradients Compute gradients?
244  * @return Model value.
245  *
246  * Evaluates the spatial component for an elliptical disk source model. The
247  * disk source model is an elliptical function
248  * \f$S_{\rm p}(\theta, \phi | E, t)\f$, where
249  * \f$\theta\f$ is the angular separation between elliptical disk centre and
250  * the actual location and \f$\phi\f$ the position angle with respect to the
251  * ellipse centre, counted counterclockwise from North.
252  *
253  * The function \f$f(\theta, \phi)\f$ is given by
254  *
255  * \f[
256  * S_{\rm p}(\theta, \phi | E, t) = \left \{
257  * \begin{array}{l l}
258  * {\tt m\_norm}
259  * & \mbox{if} \, \, \theta \le \theta_0 \\
260  * \\
261  * 0 & \mbox{else}
262  * \end{array}
263  * \right .
264  * \f]
265  *
266  * where \f$\theta_0\f$ is the effective radius of the ellipse on the sphere
267  * given by
268  *
269  * \f[\theta_0\ =
270  * \frac{ab}{\sqrt{b^2 \cos^2(\phi-\phi_0) + a^2 \sin^2(\phi-\phi_0)}}\f]
271  *
272  * and
273  * \f$a\f$ is the semi-major axis of the ellipse,
274  * \f$b\f$ is the semi-minor axis, and
275  * \f$\phi_0\f$ is the position angle of the ellipse, counted
276  * counterclockwise from North.
277  *
278  * The normalisation constant \f${\tt m\_norm}\f$ which is the inverse of the
279  * solid angle subtended by an ellipse is given by
280  *
281  * The method will not compute analytical parameter gradients, even if the
282  * @p gradients argument is set to true. Radial disk parameter gradients
283  * need to be computed numerically.
284  *
285  * @todo Quote formula for ellipse solid angle
286  *
287  * (see the update() method).
288  ***************************************************************************/
289 double GModelSpatialEllipticalDisk::eval(const double& theta,
290  const double& posangle,
291  const GEnergy& energy,
292  const GTime& time,
293  const bool& gradients) const
294 {
295  // Initialise value
296  double value = 0.0;
297 
298  // Continue only if we're inside circle enclosing the ellipse
299  if (theta <= theta_max()) {
300 
301  // Update precomputation cache
302  update();
303 
304  // Perform computations
305  double diff_angle = posangle - m_posangle.value() * gammalib::deg2rad;
306  double cosinus = std::cos(diff_angle);
307  double sinus = std::sin(diff_angle);
308  double arg1 = m_semiminor_rad * cosinus;
309  double arg2 = m_semimajor_rad * sinus;
310  double r_ell = m_semiminor_rad * m_semimajor_rad /
311  std::sqrt(arg1*arg1 + arg2*arg2);
312 
313  // Set value
314  value = (theta <= r_ell) ? m_norm : 0.0;
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: GModelSpatialEllipticalDisk::eval";
320  std::cout << "(theta=" << theta << "): NaN/Inf encountered";
321  std::cout << "(posangle=" << posangle << "): NaN/Inf encountered";
322  std::cout << " (value=" << value;
323  std::cout << ", R_ellipse=" << r_ell;
324  std::cout << ", diff_angle=" << diff_angle;
325  std::cout << ", m_norm=" << m_norm;
326  std::cout << ")" << std::endl;
327  }
328  #endif
329 
330  } // endif: position was inside enclosing circle
331 
332  // Return value
333  return value;
334 }
335 
336 
337 /***********************************************************************//**
338  * @brief Returns MC sky direction
339  *
340  * @param[in] energy Photon energy.
341  * @param[in] time Photon arrival time.
342  * @param[in,out] ran Random number generator.
343  * @return Sky direction.
344  *
345  * Draws an arbitrary sky position from the 2D disk distribution.
346  *
347  * @todo Test function
348  ***************************************************************************/
350  const GTime& time,
351  GRan& ran) const
352 {
353  // Update precomputation cache
354  update();
355 
356  // Initialise photon
357  GPhoton photon;
358  photon.energy(energy);
359  photon.time(time);
360 
361  // Draw randomly from the radial disk
362  // and reject the value if its outside the ellipse
363  do {
364 
365  // Simulate offset from photon arrival direction
366  double cosrad = std::cos(semimajor() * gammalib::deg2rad);
367  double theta = std::acos(1.0 - ran.uniform() * (1.0 - cosrad)) *
369  double phi = 360.0 * ran.uniform();
370 
371  // Rotate sky direction by offset
372  GSkyDir sky_dir = dir();
373  sky_dir.rotate_deg(phi, theta);
374 
375  // Set photon sky direction
376  photon.dir(sky_dir);
377 
378  } while(GModelSpatialElliptical::eval(photon) <= 0.0);
379 
380  // Return photon direction
381  return (photon.dir());
382 
383 }
384 
385 
386 /***********************************************************************//**
387  * @brief Checks where model contains specified sky direction
388  *
389  * @param[in] dir Sky direction.
390  * @param[in] margin Margin to be added to sky direction (degrees)
391  * @return True if the model contains the sky direction.
392  *
393  * Signals whether a sky direction is contained in the elliptical disk
394  * model.
395  *
396  * @todo Implement correct evaluation of effective ellipse radius.
397  ***************************************************************************/
399  const double& margin) const
400 {
401  // Compute distance to centre (radian)
402  double distance = dir.dist(this->dir());
403 
404  // Return flag
405  return (distance <= theta_max() + margin*gammalib::deg2rad);
406 }
407 
408 
409 /***********************************************************************//**
410  * @brief Return maximum model radius (in radians)
411  *
412  * @return Returns maximum model radius.
413  ***************************************************************************/
415 {
416  // Set maximum model radius
417  double theta_max = (semimajor() > semiminor())
420 
421  // Return value
422  return theta_max;
423 }
424 
425 
426 /***********************************************************************//**
427  * @brief Read model from XML element
428  *
429  * @param[in] xml XML element.
430  *
431  * @exception GException::model_invalid_parnum
432  * Invalid number of model parameters found in XML element.
433  * @exception GException::model_invalid_parnames
434  * Invalid model parameter names found in XML element.
435  *
436  * Reads the elliptical disk model information from an XML element. The XML
437  * element shall have either the format
438  *
439  * <spatialModel type="EllipticalDisk">
440  * <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
441  * <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/>
442  * <parameter name="PA" scale="1.0" value="45.0" min="-360" max="360" free="1"/>
443  * <parameter name="MinorRadius" scale="1.0" value="0.5" min="0.001" max="10" free="1"/>
444  * <parameter name="MajorRadius" scale="1.0" value="2.0" min="0.001" max="10" free="1"/>
445  * </spatialModel>
446  *
447  * or
448  *
449  * <spatialModel type="EllipticalDisk">
450  * <parameter name="GLON" scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
451  * <parameter name="GLAT" scale="1.0" value="22.0145" min="-90" max="90" free="1"/>
452  * <parameter name="PA" scale="1.0" value="45.0" min="-360" max="360" free="1"/>
453  * <parameter name="MinorRadius" scale="1.0" value="0.5" min="0.001" max="10" free="1"/>
454  * <parameter name="MajorRadius" scale="1.0" value="2.0" min="0.001" max="10" free="1"/>
455  * </spatialModel>
456  *
457  * @todo Implement a test of the ellipse boundary. The axes
458  * and axes minimum should be >0.
459  ***************************************************************************/
461 {
462  // Determine number of parameter nodes in XML element
463  int npars = xml.elements("parameter");
464 
465  // Verify that XML element has exactly 5 parameters
466  if (xml.elements() != 5 || npars != 5) {
468  "Elliptical disk model requires exactly 5 parameters.");
469  }
470 
471  // Read disk location
473 
474  // Get parameters
475  const GXmlElement* minor = gammalib::xml_get_par(G_READ, xml, m_semiminor.name());
476  const GXmlElement* major = gammalib::xml_get_par(G_READ, xml, m_semimajor.name());
477 
478  // Read parameters
479  m_semiminor.read(*minor);
480  m_semimajor.read(*major);
481 
482  // Return
483  return;
484 }
485 
486 
487 /***********************************************************************//**
488  * @brief Write model into XML element
489  *
490  * @param[in] xml XML element into which model information is written.
491  *
492  * @exception GException::model_invalid_parnum
493  * Invalid number of model parameters found in XML element.
494  * @exception GException::model_invalid_parnames
495  * Invalid model parameter names found in XML element.
496  *
497  * Write the elliptical disk model information into an XML element. The XML
498  * element will have the format
499  *
500  * <spatialModel type="EllipticalDisk">
501  * <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
502  * <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/>
503  * <parameter name="PA" scale="1.0" value="45.0" min="-360" max="360" free="1"/>
504  * <parameter name="MinorRadius" scale="1.0" value="0.5" min="0.001" max="10" free="1"/>
505  * <parameter name="MajorRadius" scale="1.0" value="2.0" min="0.001" max="10" free="1"/>
506  * </spatialModel>
507  *
508  ***************************************************************************/
510 {
511  // Write disk location
513 
514  // Get or create parameters
517 
518  // Write parameters
519  m_semiminor.write(*minor);
520  m_semimajor.write(*major);
521 
522  // Return
523  return;
524 }
525 
526 
527 /***********************************************************************//**
528  * @brief Print information
529  *
530  * @param[in] chatter Chattiness.
531  * @return String containing model information.
532  ***************************************************************************/
533 std::string GModelSpatialEllipticalDisk::print(const GChatter& chatter) const
534 {
535  // Initialise result string
536  std::string result;
537 
538  // Continue only if chatter is not silent
539  if (chatter != SILENT) {
540 
541  // Append header
542  result.append("=== GModelSpatialEllipticalDisk ===");
543 
544  // Append parameters
545  result.append("\n"+gammalib::parformat("Number of parameters"));
546  result.append(gammalib::str(size()));
547  for (int i = 0; i < size(); ++i) {
548  result.append("\n"+m_pars[i]->print(chatter));
549  }
550 
551  } // endif: chatter was not silent
552 
553  // Return result
554  return result;
555 }
556 
557 
558 /*==========================================================================
559  = =
560  = Private methods =
561  = =
562  ==========================================================================*/
563 
564 /***********************************************************************//**
565  * @brief Initialise class members
566  ***************************************************************************/
568 {
569  // Initialise precomputation cache. Note that zero values flag
570  // uninitialised as a zero radius is not meaningful
571  m_last_semiminor = 0.0;
572  m_last_semimajor = 0.0;
573  m_semiminor_rad = 0.0;
574  m_semimajor_rad = 0.0;
575  m_norm = 0.0;
576 
577  // Initialise other members
578  m_region.clear();
579 
580  // Return
581  return;
582 }
583 
584 
585 /***********************************************************************//**
586  * @brief Copy class members
587  *
588  * @param[in] model Elliptical disk model.
589  *
590  * We do not have to push back the members on the parameter stack as this
591  * should have been done by init_members() that was called before. Otherwise
592  * we would have the radius twice on the stack.
593  ***************************************************************************/
595 {
596  // Copy members
597  m_region = model.m_region;
598 
599  // Copy precomputation cache
604  m_norm = model.m_norm;
605 
606  // Return
607  return;
608 }
609 
610 
611 /***********************************************************************//**
612  * @brief Delete class members
613  ***************************************************************************/
615 {
616  // Return
617  return;
618 }
619 
620 
621 /***********************************************************************//**
622  * @brief Update precomputation cache
623  *
624  * Computes the normalization
625  * \f[
626  * {\tt m\_norm} = \frac{1}{2 \pi (1 - \cos a) (1 - \cos b)}
627  * \f]
628  *
629  * @todo check this formula
630  ***************************************************************************/
632 {
633  // Update if one axis has changed
635 
636  // Store last values
639 
640  // Compute axes in radians
643 
644  // Perform precomputations
645  double denom = gammalib::twopi *
647  (1.0 - std::cos(m_semimajor_rad)));
648  m_norm = (denom > 0.0) ? 1.0 / denom : 0.0;
649 
650  } // endif: update required
651 
652  // Return
653  return;
654 }
655 
656 
657 /***********************************************************************//**
658  * @brief Set boundary sky region
659  ***************************************************************************/
661 {
662  // Set sky region centre to disk centre
664 
665  // Set maximum model radius
666  double max_radius = (semimajor() > semiminor()) ? semimajor() : semiminor();
667 
668  // Set sky region radius to maximum disk radius
669  m_region.radius(max_radius);
670 
671  // Return
672  return;
673 }
GModelPar m_semimajor
Semi-major axis of ellipse (deg)
GSkyDir dir(void) const
Return position of elliptical spatial model.
virtual void write(GXmlElement &xml) const
Write model into XML element.
void free_members(void)
Delete class members.
void update(void) const
Update precomputation cache.
Abstract elliptical spatial model base class.
const std::string & name(void) const
Return parameter name.
GModelPar m_ra
Right Ascension (deg)
void set_region(void) const
Set boundary sky region.
int size(void) const
Return number of parameters.
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
Definition: GModelPar.cpp:353
GVector cos(const GVector &vector)
Computes cosine of vector elements.
Definition: GVector.cpp:1100
Elliptical disk model class interface definition.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print information.
virtual double theta_max(void) const
Return maximum model radius (in radians)
virtual GModelSpatialElliptical & operator=(const GModelSpatialElliptical &model)
Assignment operator.
void init_members(void)
Initialise class members.
virtual void write(GXmlElement &xml) const
Write model into XML element.
void copy_members(const GModelSpatialEllipticalDisk &model)
Copy class members.
virtual GSkyDir mc(const GEnergy &energy, const GTime &time, GRan &ran) const
Returns MC sky direction.
XML element node class.
Definition: GXmlElement.hpp:47
double acos(const double &arg)
Computes acos by avoiding NaN due to rounding errors.
Definition: GMath.cpp:69
Random number generator class.
Definition: GRan.hpp:44
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition: GXmlNode.cpp:580
GModelPar m_dec
Declination (deg)
Time class.
Definition: GTime.hpp:54
Gammalib tools definition.
GModelPar m_posangle
Position angle from North, counterclockwise (deg)
virtual void read(const GXmlElement &xml)
Read model from XML element.
const GModelSpatialEllipticalDisk g_elliptical_disk_seed
virtual bool contains(const GSkyDir &dir, const double &margin=0.0) const
Checks where model contains specified sky direction.
double m_last_semiminor
Last semi-minor axis.
Interface definition for the spatial model registry class.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition: GTools.hpp:184
const double & radius(void) const
Return circular region radius (in degrees)
Class that handles photons.
Definition: GPhoton.hpp:47
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition: GTools.hpp:167
double semiminor(void) const
Return semi-minor axis of ellipse.
const double deg2rad
Definition: GMath.hpp:43
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
Definition: GVector.cpp:1268
virtual GModelSpatialEllipticalDisk * clone(void) const
Clone elliptical disk model.
virtual void clear(void)
Clear elliptical disk model.
Radial disk model class interface definition.
double m_last_semimajor
Last semi-major axis.
std::vector< GModelPar * > m_pars
Parameter pointers.
void rotate_deg(const double &phi, const double &theta)
Rotate sky direction by zenith and azimuth angle.
Definition: GSkyDir.cpp:321
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:1513
double uniform(void)
Returns random double precision floating value in range 0 to 1.
Definition: GRan.cpp:242
Spatial model registry class definition.
GModelSpatialEllipticalDisk(void)
Void constructor.
const GTime & time(void) const
Return photon time.
Definition: GPhoton.hpp:134
GChatter
Definition: GTypemaps.hpp:33
virtual void read(const GXmlElement &xml)
Read model from XML element.
GModelPar m_semiminor
Semi-minor axis of ellipse (deg)
double m_semimajor_rad
Radius in radians.
const GSkyDir & centre(void) const
Return circular region centre.
void free_members(void)
Delete class members.
double posangle(void) const
Return Position Angle of model.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Definition: GModelPar.cpp:229
double value(void) const
Return parameter value.
GVector sin(const GVector &vector)
Computes sine of vector elements.
Definition: GVector.cpp:1226
virtual double eval(const double &theta, const double &posangle, const GEnergy &energy, const GTime &time, const bool &gradients=false) const
Evaluate function (in units of sr^-1)
const GEnergy & energy(void) const
Return photon energy.
Definition: GPhoton.hpp:122
Exception handler interface definition.
GSkyRegionCircle m_region
Bounding circle.
double dist(const GSkyDir &dir) const
Compute angular distance between sky directions in radians.
Definition: GSkyDir.hpp:265
virtual GModelSpatialEllipticalDisk & operator=(const GModelSpatialEllipticalDisk &model)
Assignment operator.
virtual ~GModelSpatialEllipticalDisk(void)
Destructor.
void init_members(void)
Initialise class members.
const double twopi
Definition: GMath.hpp:36
virtual double eval(const double &theta, const double &posangle, const GEnergy &energy, const GTime &time, const bool &gradients=false) const =0
double m_semiminor_rad
Radius in radians.
const double rad2deg
Definition: GMath.hpp:44
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1022
Sky direction class.
Definition: GSkyDir.hpp:62
double semimajor(void) const
Return semi-major axis of ellipse.
const GSkyDir & dir(void) const
Return photon sky direction.
Definition: GPhoton.hpp:110
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:1562
Mathematical function definitions.
void clear(void)
Clear instance.
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:413