GammaLib 2.0.0
Loading...
Searching...
No Matches
GCTAModelRadialPolynom.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCTAModelRadialPolynom.cpp - Radial Polynom CTA model class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2011-2021 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 GCTAModelRadialPolynom.cpp
23 * @brief Radial Polynom 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 "GMath.hpp"
35#include "GRan.hpp"
36#include "GIntegral.hpp"
37#include "GCTAObservation.hpp"
38#include "GCTAInstDir.hpp"
42
43/* __ Constants __________________________________________________________ */
45
46/* __ Globals ____________________________________________________________ */
48const GCTAModelRadialRegistry g_cta_radial_polynom_registry(&g_cta_radial_polynom_seed);
49const GCTAModelSpatialRegistry g_cta_radial_polynom_spatial_registry(&g_cta_radial_polynom_seed);
50
51/* __ Method name definitions ____________________________________________ */
52#define G_READ "GCTAModelRadialPolynom::read(GXmlElement&)"
53#define G_WRITE "GCTAModelRadialPolynom::write(GXmlElement&)"
54
55/* __ Macros _____________________________________________________________ */
56
57/* __ Coding definitions _________________________________________________ */
58//#define G_DEBUG_MC //!< Debug MC method
59
60/* __ Debug definitions __________________________________________________ */
61
62
63/*==========================================================================
64 = =
65 = Constructors/destructors =
66 = =
67 ==========================================================================*/
68
69/***********************************************************************//**
70 * @brief Void constructor
71 ***************************************************************************/
73{
74 // Initialise members
76
77 // Return
78 return;
79}
80
81
82/***********************************************************************//**
83 * @brief Constructor
84 *
85 * @param[in] coeffs Vector of polynomial coefficients.
86 ***************************************************************************/
87GCTAModelRadialPolynom::GCTAModelRadialPolynom(const std::vector<double>& coeffs) :
89{
90 // Initialise members
92
93 // Assign coefficients
94 for (int i = 0; i < coeffs.size(); ++i) {
95
96 // Allocate parameter
97 GModelPar par;
98
99 // Set value
100 par.value(coeffs[i]);
101
102 // Set other attributes
103 std::string name = "Coeff" + gammalib::str(i);
104 par.name(name);
105 par.unit("");
106 par.free();
107 par.scale(1.0);
108 par.gradient(0.0);
109 par.has_grad(true);
110
111 // Push coefficient on list
112 m_coeffs.push_back(par);
113
114 } // endfor: looped over coefficients
115
116 // Update parameter mapping
117 update_pars();
118
119 // Return
120 return;
121}
122
123
124/***********************************************************************//**
125 * @brief XML constructor
126 *
127 * @param[in] xml XML element.
128 *
129 * Creates instance of a radial Polynom model by extracting information
130 * from an XML element. See GCTAModelRadialPolynom::read() for more
131 * information about the expected structure of the XML element.
132 ***************************************************************************/
135{
136 // Initialise members
137 init_members();
138
139 // Read information from XML element
140 read(xml);
141
142 // Return
143 return;
144}
145
146
147/***********************************************************************//**
148 * @brief Copy constructor
149 *
150 * @param[in] model Radial Polynom model.
151 ***************************************************************************/
153 : GCTAModelRadial(model)
154{
155 // Initialise members
156 init_members();
157
158 // Copy members
159 copy_members(model);
160
161 // Return
162 return;
163}
164
165
166/***********************************************************************//**
167 * @brief Destructor
168 ***************************************************************************/
170{
171 // Free members
172 free_members();
173
174 // Return
175 return;
176}
177
178
179/*==========================================================================
180 = =
181 = Operators =
182 = =
183 ==========================================================================*/
184
185/***********************************************************************//**
186 * @brief Assignment operator
187 *
188 * @param[in] model Radial Polynom model.
189 ***************************************************************************/
191{
192 // Execute only if object is not identical
193 if (this != &model) {
194
195 // Copy base class members
196 this->GCTAModelRadial::operator=(model);
197
198 // Free members
199 free_members();
200
201 // Initialise members
202 init_members();
203
204 // Copy members
205 copy_members(model);
206
207 } // endif: object was not identical
208
209 // Return
210 return *this;
211}
212
213
214/*==========================================================================
215 = =
216 = Public methods =
217 = =
218 ==========================================================================*/
219
220/***********************************************************************//**
221 * @brief Clear instance
222***************************************************************************/
224{
225 // Free class members (base and derived classes, derived class first)
226 free_members();
228
229 // Initialise members
231 init_members();
232
233 // Return
234 return;
235}
236
237
238/***********************************************************************//**
239 * @brief Clone instance
240***************************************************************************/
245
246
247/***********************************************************************//**
248 * @brief Evaluate function
249 *
250 * @param[in] offset Offset angle [degrees].
251 * @param[in] gradients Compute gradients?
252 * @return Function value
253 *
254 * Evaluates the radial polynomial model for a given offset. The model is
255 * defined as
256 * \f[f(\theta) = \sum_{i=0}^m c_i \theta^i\f]
257 * where
258 * \f$\theta\f$ is the offset angle (in degrees), and
259 * \f$c_i\f$ are the polynomial coefficients.
260 *
261 * If the @p gradients flag is true the method will also compute the partial
262 * derivatives of the parameters. The partial derivative of the Polynom are
263 * given by
264 * \f[\frac{df}{d{c_i}_v} = {c_i}_s \theta^i\f]
265 * where
266 * \f${c_i}_v\f$ is the value part,
267 * \f${c_i}_s\f$ is the scaling part, and
268 * \f$c_i = {c_i}_v {c_i}_s\f$.
269 ***************************************************************************/
270double GCTAModelRadialPolynom::eval(const double& offset,
271 const bool& gradients) const
272{
273 // Initialise result
274 double value = 0.0;
275
276 // Determine polynomial degree
277 int ncoeffs = m_coeffs.size();
278
279 // Compute value and gradients (only if there are coefficients)
280 if (ncoeffs > 0) {
281
282 // Compute value
283 value = m_coeffs[ncoeffs-1].value();
284 for (int i = ncoeffs-2; i >= 0; i--) {
285 value = value * offset + m_coeffs[i].value();
286 }
287
288 // Optionally compute partial derivatives
289 if (gradients) {
290
291 // Initialise theta^i for the first coefficient
292 double offset_power = 1.0;
293
294 // Compute gradients for all coefficients
295 for (int i = 0; i < ncoeffs; ++i) {
296
297 // Compute gradient
298 double grad = offset_power * m_coeffs[i].scale();
299
300 // Store gradient
301 m_coeffs[i].factor_gradient(grad);
302
303 // Increase offset power for next coefficient
304 offset_power *= offset;
305
306 } // endfor: looped over all coefficients
307
308 } // endif: computed partial derivatives
309
310 } // endif: there were coefficients
311
312 // Compile option: Check for NaN/Inf
313 #if defined(G_NAN_CHECK)
314 if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
315 std::cout << "*** ERROR: GCTAModelRadialPolynom::eval";
316 std::cout << "(offset=" << offset << "): NaN/Inf encountered";
317 std::cout << " (value=" << value;
318 for (int i = 0; i < ncoeffs; ++i) {
319 std::cout << ", c" << i << "=" << m_coeffs[i].value();
320 }
321 std::cout << ")" << std::endl;
322 }
323 #endif
324
325 // Return value
326 return value;
327}
328
329
330/***********************************************************************//**
331 * @brief Returns MC instrument direction
332 *
333 * @param[in,out] ran Random number generator.
334 * @return CTA instrument direction.
335 *
336 * Draws an arbitrary CTA instrument position from
337 * \f[f(\theta) = \sin(\theta) \left( \sum_{i=0}^m c_i \theta^i \right)\f]
338 * where
339 * \f$\theta\f$ is the offset angle (in degrees), and
340 * \f$c_i\f$ are the polynomial coefficients,
341 * using the rejection method.
342 *
343 * Note that the maximum offset angle is fixed by the constant
344 * g_cta_radial_polynom_offset_max.
345 * This needs eventually adjusting on real data. The main reason for the
346 * tight limit is to avoid divergence at large offset angles.
347 *
348 * @todo This method actually assumes that the polynom is always < 1, which
349 * may not be necessarily the case. Ideally, the method should
350 * determine the maximum of the polynomial to throw events. This is
351 * a severe limitation and should rapidly be corrected.
352 ***************************************************************************/
354{
355 // Set constants
356 const double u_max = std::sin(g_cta_radial_polynom_offset_max *
358
359 // Debug option: initialise number if samples thrown for one value
360 #if defined(G_DEBUG_MC)
361 int n_samples = 0;
362 #endif
363
364 // Simulate offset from photon arrival direction until we're not
365 // rejected anymore
366 double value = 0.0;
367 double u = 1.0;
368 double offset = 0.0;
369 do {
370 // Throw offset angle
372
373 // Compute function value at this offset angle
374 value = std::sin(offset * gammalib::deg2rad) * eval(offset);
375
376 // Throw value for rejection method
377 u = ran.uniform() * u_max;
378
379 // Debug option: update number of samples
380 #if defined(G_DEBUG_MC)
381 n_samples++;
382 #endif
383
384 } while (u > value);
385
386 // Debug option: print number if samples thrown for one value
387 #if defined(G_DEBUG_MC)
388 std::cout << "#=" << n_samples << " ";
389 #endif
390
391 // Simulate azimuth angle
392 double phi = 360.0 * ran.uniform();
393
394 // Convert from degrees to radians
395 offset *= gammalib::deg2rad;
396 phi *= gammalib::deg2rad;
397
398 // Compute DETX and DETY coordinates
399 double detx(0.0);
400 double dety(0.0);
401 if (offset > 0.0 ) {
402 detx = offset * std::cos(phi);
403 dety = offset * std::sin(phi);
404 }
405
406 // Set instrument direction
407 GCTAInstDir dir(detx, dety);
408
409 // Return instrument direction
410 return dir;
411}
412
413
414/***********************************************************************//**
415 * @brief Return maximum function value for Monte Carlo simulations
416 *
417 * @param[in] obs CTA Observation (not used).
418 * @return Maximum function value for Monte Carlo simulations.
419 ***************************************************************************/
421{
422 // Set constants
423 const double u_max = std::sin(g_cta_radial_polynom_offset_max *
425
426 // Return maximum value
427 return u_max;
428}
429
430
431/***********************************************************************//**
432 * @brief Returns integral over radial model (in steradians)
433 *
434 * Computes
435 * \f[\Omega = 2 \pi \int_0^{\pi} \sin \theta f(\theta) d\theta\f]
436 * where
437 * \f[f(\theta) = \sum_{i=0}^m c_i \theta^i\f]
438 * \f$\theta\f$ is the offset angle (in degrees), and
439 * \f$c_i\f$ are the polynomial coefficients.
440 *
441 * The integration is performed numerically, and the upper integration bound
442 * \f$\pi\f$
443 * is fixed to < g_cta_radial_polynom_offset_max.
444 * This needs eventually adjusting on real data. The main reason for the
445 * tight limit is to avoid divergence at large offset angles.
446 ***************************************************************************/
448{
449 // Set constants
450 const double offset_max_rad = g_cta_radial_polynom_offset_max *
452
453 // Allocate integrand
455
456 // Allocate intergal
457 GIntegral integral(&integrand);
458
459 // Perform numerical integration
460 double omega = integral.romberg(0.0, offset_max_rad) * gammalib::twopi;
461
462 // Return integral
463 return omega;
464}
465
466
467/***********************************************************************//**
468 * @brief Read model from XML element
469 *
470 * @param[in] xml XML element.
471 *
472 * @exception GException::invalid_value
473 * Invalid XML format encountered.
474 *
475 * Read the radial Polynom model information from an XML element in the
476 * following format
477 *
478 * <radialModel type="...">
479 * <parameter name="Coeff0" scale="1.0" value="1.5" min="0.1" max="10.0" free="1"/>
480 * <parameter name="Coeff1" scale="1.0" value="3.0" min="1.0" max="10.0" free="1"/>
481 * <parameter name="Coeff2" scale="1.0" value="5.0" min="1.0" max="10.0" free="1"/>
482 * ...
483 * </radialModel>
484 *
485 * @todo Implement a test of the coefficient boundaries.
486 ***************************************************************************/
488{
489 // Free space for coefficients
490 m_coeffs.clear();
491
492 // Get maximum number of coefficients from XML file
493 int max_coeffs = xml.elements("parameter");
494
495 // Throw an error if no parameters were found
496 if (max_coeffs < 1) {
497 std::string msg = "Radial polynomial model requires at least one "
498 "coefficient. Please verify the XML format.";
500 }
501
502 // Verify XML file consistency and determine number of coefficients
503 int ncoeffs = 0;
504 std::vector<int> npar;
505 npar.assign(max_coeffs, 0);
506 for (int i = 0; i < max_coeffs; ++i) {
507
508 // Get parameter element
509 const GXmlElement* par = xml.element("parameter", i);
510
511 // Verify that parameter is indeed a coefficient
512 if (par->attribute("name").compare(0,5,"Coeff") != 0) {
513 std::string msg = "Invalid parameter \""+par->attribute("name")+
514 "\" encountered. Parameter name needs to start "
515 "with \"Coeff\". Please verify the XML format.";
517 }
518
519 // Verify that parameter coefficient has index in valid range
520 int index = -1;
521 size_t nchars = par->attribute("name").length() - 5;
522 if (nchars > 0) {
523 index = gammalib::toint(par->attribute("name").substr(5, nchars));
524 }
525 else {
526 std::string msg = "Radial polynomial \"Coeff\" parameter has no "
527 "index. Please verify the XML format.";
529 }
530 if (index < 0) {
531 std::string msg = "Radial polynomial \"Coeff\" parameter has "
532 "negative index "+gammalib::str(index)+". Please "
533 "verify the XML format.";
535 }
536 if (index >= max_coeffs) {
537 std::string msg = "There are "+gammalib::str(max_coeffs)+
538 " parameters, hence polynomial coefficients are "
539 "expected to run from 0 to "+
540 gammalib::str(max_coeffs-1)+", yet a coefficient "
541 "with index "+gammalib::str(index)+" was "
542 "encountered. Please verify the XML format.";
544 }
545
546 // Increment parameter counter
547 npar[index]++;
548
549 // Update number of coefficients
550 if (index+1 > ncoeffs) {
551 ncoeffs = index + 1;
552 }
553
554 } // endfor: verified XML file consistency
555
556 // Verify that the number of coefficients is between 1 and max_coeffs
557 if (ncoeffs < 0 || ncoeffs > max_coeffs) {
558 std::string msg = "Radial polynomial model requires between 1 and "+
559 gammalib::str(max_coeffs)+" parameters. Please "
560 "verify the XML format.";
562 }
563
564 // Verify that all parameters were found
565 for (int i = 0; i < ncoeffs; ++i) {
566 if (npar[i] == 0) {
567 std::string msg = "Parameter \"Coeff"+gammalib::str(i)+
568 "\" not found in XML file. Please verify the "
569 "XML format.";
571 }
572 else if (npar[i] > 1) {
573 std::string msg = "Multiple parameters \"Coeff"+gammalib::str(i)+
574 "\" found in XML file. Please verify the XML "
575 "format.";
577 }
578 }
579
580 // Finally get all coefficients in order
581 for (int i = 0; i < ncoeffs; ++i) {
582
583 // Set parameter name
584 std::string name = "Coeff"+gammalib::str(i);
585
586 // Get corresponding parameter element
587 const GXmlElement* par = NULL;
588 for (int k = 0; k < ncoeffs; ++k) {
589 const GXmlElement* element = xml.element("parameter", k);
590 if (element->attribute("name") == name) {
591 par = element;
592 break;
593 }
594 }
595
596 // Make sure that we really have one (just a double check, this should
597 // never fail)
598 if (par == NULL) {
599 std::string msg = "Required parameter \""+name+"\" not found. "
600 "Please verify the XML format.";
602 }
603
604 // Now read that parameter ...
605 GModelPar coeff;
606 coeff.read(*par);
607
608 // ... set other attributes ...
609 coeff.name(name);
610 coeff.unit("");
611
612 //TODO: Check parameter
613
614 // ... and push it on the list
615 m_coeffs.push_back(coeff);
616
617 } // endfor: looped over all parameters
618
619 // Update parameter mapping
620 update_pars();
621
622 // Return
623 return;
624}
625
626
627/***********************************************************************//**
628 * @brief Write model into XML element
629 *
630 * @param[in] xml XML element.
631 *
632 * Write the polynomial radial model information into an XML element in the
633 * following format
634 *
635 * <radialModel type="...">
636 * <parameter name="Coeff0" scale="1.0" value="1.5" min="0.1" max="10.0" free="1"/>
637 * <parameter name="Coeff1" scale="1.0" value="3.0" min="1.0" max="10.0" free="1"/>
638 * <parameter name="Coeff2" scale="1.0" value="5.0" min="1.0" max="10.0" free="1"/>
639 * ...
640 * </radialModel>
641 ***************************************************************************/
643{
644 // Determine number of coefficients
645 int ncoeffs = m_coeffs.size();
646
647 // Check model type
649
650 // Write model parameters
651 for (int i = 0; i < ncoeffs; ++i) {
652
653 // Set parameter name
654 std::string name = "Coeff"+gammalib::str(i);
655
656 // Get or create parameter
657 GXmlElement* coeff = gammalib::xml_need_par(G_WRITE, xml, name);
658
659 // Write parameter
660 m_coeffs[i].write(*coeff);
661
662 } // endfor: looped over all parameters
663
664 // Return
665 return;
666}
667
668
669/***********************************************************************//**
670 * @brief Print point source information
671 *
672 * @param[in] chatter Chattiness (defaults to NORMAL).
673 * @return String containing point source information.
674 ***************************************************************************/
675std::string GCTAModelRadialPolynom::print(const GChatter& chatter) const
676{
677 // Initialise result string
678 std::string result;
679
680 // Continue only if chatter is not silent
681 if (chatter != SILENT) {
682
683 // Append header
684 result.append("=== GCTAModelRadialPolynom ===");
685
686 // Append information
687 result.append("\n"+gammalib::parformat("Number of parameters") +
689 for (int i = 0; i < size(); ++i) {
690 result.append("\n"+m_pars[i]->print(chatter));
691 }
692
693 } // endif: chatter was not silent
694
695 // Return result
696 return result;
697}
698
699
700/*==========================================================================
701 = =
702 = Private methods =
703 = =
704 ==========================================================================*/
705
706/***********************************************************************//**
707 * @brief Initialise class members
708 ***************************************************************************/
710{
711 // Initialise polynomial coefficients
712 m_coeffs.clear();
713
714 // Update parameter mapping
715 update_pars();
716
717 // Return
718 return;
719}
720
721
722/***********************************************************************//**
723 * @brief Copy class members
724 *
725 * @param[in] model Radial Polynomian model.
726 ***************************************************************************/
728{
729 // Copy members
730 m_coeffs = model.m_coeffs;
731
732 // Update parameter mapping
733 update_pars();
734
735 // Return
736 return;
737}
738
739
740/***********************************************************************//**
741 * @brief Delete class members
742 ***************************************************************************/
744{
745 // Return
746 return;
747}
748
749
750/***********************************************************************//**
751 * @brief Update parameter mapping
752 ***************************************************************************/
754{
755 // Clear parameter pointer(s)
756 m_pars.clear();
757
758 // Get number of coefficients
759 int ncoeffs = m_coeffs.size();
760
761 // Set parameter pointers for all coefficients
762 for (int i = 0; i < ncoeffs; ++i) {
763
764 // Signal that we have gradients
765 m_coeffs[i].has_grad(true);
766
767 // Set pointer
768 m_pars.push_back(&(m_coeffs[i]));
769
770 } // endfor: looped over coefficients
771
772 // Return
773 return;
774}
775
776
777/*==========================================================================
778 = =
779 = Friends =
780 = =
781 ==========================================================================*/
#define G_WRITE
#define G_READ
CTA instrument direction class interface definition.
const double g_cta_radial_polynom_offset_max
const GCTAModelRadialPolynom g_cta_radial_polynom_seed
Radial Polynom model class interface definition.
CTA radial model registry class definition.
Spatial model registry class definition.
CTA observation class interface definition.
Exception handler interface definition.
Integration class interface definition.
Mathematical function definitions.
Random number generator class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
CTA instrument direction class.
Radial Polynom CTA model class.
virtual double eval(const double &offset, const bool &gradients=false) const
Evaluate function.
virtual void read(const GXmlElement &xml)
Read model from XML element.
virtual void clear(void)
Clear instance.
virtual double mc_max_value(const GCTAObservation &obs) const
Return maximum function value for Monte Carlo simulations.
std::vector< GModelPar > m_coeffs
Coefficients.
void free_members(void)
Delete class members.
void copy_members(const GCTAModelRadialPolynom &model)
Copy class members.
virtual GCTAModelRadialPolynom & operator=(const GCTAModelRadialPolynom &model)
Assignment operator.
virtual void write(GXmlElement &xml) const
Write model into XML element.
virtual GCTAModelRadialPolynom * clone(void) const
Clone instance.
virtual GCTAInstDir mc(GRan &ran) const
Returns MC instrument direction.
virtual ~GCTAModelRadialPolynom(void)
Destructor.
GCTAModelRadialPolynom(void)
Void constructor.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print point source information.
void update_pars(void)
Update parameter mapping.
void init_members(void)
Initialise class members.
virtual std::string type(void) const
Return model type.
virtual double omega(void) const
Returns integral over radial model (in steradians)
Interface definition for the CTA radial model registry class.
Abstract radial acceptance model class.
virtual GCTAModelRadial & operator=(const GCTAModelRadial &model)
Assignment operator.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
Interface definition for the spatial model registry class.
std::vector< GModelPar * > m_pars
Parameter pointers.
int size(void) const
Return number of model parameters.
CTA observation class.
GIntegral class interface definition.
Definition GIntegral.hpp:46
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
Model parameter class.
Definition GModelPar.hpp:87
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
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.
const std::string & unit(void) const
Return parameter unit.
double gradient(void) const
Return parameter gradient.
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
XML element node class.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
Definition GXmlNode.cpp:640
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition GXmlNode.cpp:586
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
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
int toint(const std::string &arg)
Convert string into integer value.
Definition GTools.cpp:821
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
const double deg2rad
Definition GMath.hpp:43
const double twopi
Definition GMath.hpp:36
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.
Definition GTools.cpp:1819