GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GCTAModelRadialPolynom.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GCTAModelRadialPolynom.cpp - Radial Polynom CTA model class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2011-2018 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 ____________________________________________________________ */
48 const GCTAModelRadialRegistry g_cta_radial_polynom_registry(&g_cta_radial_polynom_seed);
49 const 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
75  init_members();
76 
77  // Return
78  return;
79 }
80 
81 
82 /***********************************************************************//**
83  * @brief Constructor
84  *
85  * @param[in] coeffs Vector of polynomial coefficients.
86  ***************************************************************************/
87 GCTAModelRadialPolynom::GCTAModelRadialPolynom(const std::vector<double>& coeffs) :
89 {
90  // Initialise members
91  init_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  ***************************************************************************/
134  : GCTAModelRadial()
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 ***************************************************************************/
242 {
243  return new GCTAModelRadialPolynom(*this);
244 }
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  ***************************************************************************/
270 double 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
371  offset = ran.uniform() * g_cta_radial_polynom_offset_max;
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::model_invalid_parnum
473  * Invalid number of model parameters found in XML element.
474  * @exception GException::model_invalid_parnames
475  * Invalid model parameter names found in XML element.
476  *
477  * Read the radial Polynom model information from an XML element. The XML
478  * element is required to have at least one parameter. Parameters are named
479  * "CoeffX", where "X" starts from "0".
480  *
481  * @todo Implement a test of the coefficient boundaries.
482  ***************************************************************************/
484 {
485  // Free space for coefficients
486  m_coeffs.clear();
487 
488  // Get maximum number of coefficients from XML file
489  int max_coeffs = xml.elements("parameter");
490 
491  // Throw an error if no parameters were found
492  if (max_coeffs < 1) {
493  std::string message = "Radial polynomial model requires at least"
494  " one coefficient.";
495  throw GException::model_invalid_parnum(G_READ, xml, message);
496  }
497 
498  // Verify XML file consistency and determine number of coefficients
499  int ncoeffs = 0;
500  std::vector<int> npar;
501  npar.assign(max_coeffs, 0);
502  for (int i = 0; i < max_coeffs; ++i) {
503 
504  // Get parameter element
505  const GXmlElement* par = xml.element("parameter", i);
506 
507  // Verify that parameter is indeed a coefficient
508  if (par->attribute("name").compare(0,5,"Coeff") != 0) {
510  par->attribute("name"));
511  }
512 
513  // Verify that parameter coefficient has index in valid range
514  int index = -1;
515  size_t nchars = par->attribute("name").length() - 5;
516  if (nchars > 0) {
517  index = gammalib::toint(par->attribute("name").substr(5, nchars));
518  }
519  else {
521  "Radial polynomial \"Coeff\" parameter has no index.");
522  }
523  if (index < 0) {
525  "Radial polynomial \"Coeff\" parameter index < 0.");
526  }
527  if (index >= max_coeffs) {
528  std::string message = "There are "+gammalib::str(max_coeffs)+" parameters,"
529  " hence polynomial coefficients are expected"
530  " to run from 0 to "+gammalib::str(max_coeffs-1)+", yet"
531  " a coefficient with index "+gammalib::str(index)+" was"
532  " encountered.";
533  throw GException::model_invalid_parnames(G_READ, xml, message);
534  }
535 
536  // Increment parameter counter
537  npar[index]++;
538 
539  // Update number of coefficients
540  if (index+1 > ncoeffs) {
541  ncoeffs = index + 1;
542  }
543 
544  } // endfor: verified XML file consistency
545 
546  // Verify that the number of coefficients is between 1 and max_coeffs
547  if (ncoeffs < 0 || ncoeffs > max_coeffs) {
548  std::string message = "Radial polynomial model requires at between"
549  " 1 and "+gammalib::str(max_coeffs)+" parameters.";
550  throw GException::model_invalid_parnum(G_READ, xml, message);
551  }
552 
553  // Verify that all parameters were found
554  for (int i = 0; i < ncoeffs; ++i) {
555  if (npar[i] == 0) {
556  std::string message = "Parameter \"Coeff"+gammalib::str(i)+"\" required,"
557  " but not found in XML file.";
558  throw GException::model_invalid_parnames(G_READ, xml, message);
559  }
560  else if (npar[i] > 1) {
561  std::string message = "Multiple parameters \"Coeff"+gammalib::str(i)+"\""
562  " found in XML file.";
563  throw GException::model_invalid_parnames(G_READ, xml, message);
564  }
565  }
566 
567  // Finally get all coefficients in order
568  for (int i = 0; i < ncoeffs; ++i) {
569 
570  // Set parameter name
571  std::string name = "Coeff"+gammalib::str(i);
572 
573  // Get corresponding parameter element
574  const GXmlElement* par = NULL;
575  for (int k = 0; k < ncoeffs; ++k) {
576  const GXmlElement* element = xml.element("parameter", k);
577  if (element->attribute("name") == name) {
578  par = element;
579  break;
580  }
581  }
582 
583  // Make sure that we really have one (just a double check, this should
584  // never fail)
585  if (par == NULL) {
586  std::string message = "Required parameter \""+name+"\" not found.";
587  throw GException::model_invalid_parnames(G_READ, xml, message);
588  }
589 
590  // Now read that parameter ...
591  GModelPar coeff;
592  coeff.read(*par);
593 
594  // ... set other attributes ...
595  coeff.name(name);
596  coeff.unit("");
597 
598  //TODO: Check parameter
599 
600  // ... and push it on the list
601  m_coeffs.push_back(coeff);
602 
603  } // endfor: looped over all parameters
604 
605  // Update parameter mapping
606  update_pars();
607 
608  // Return
609  return;
610 }
611 
612 
613 /***********************************************************************//**
614  * @brief Write model into XML element
615  *
616  * @param[in] xml XML element.
617  *
618  * @exception GException::model_invalid_spatial
619  * Existing XML element is not of type 'Polynom'
620  * @exception GException::model_invalid_parnum
621  * Invalid number of model parameters found in XML element.
622  * @exception GException::model_invalid_parnames
623  * Invalid model parameter names found in XML element.
624  *
625  * Write the polynomial radial model information into an XML element. The XML
626  * element will have 1-10 parameter leafs named "CoeffX", where X runs from
627  * 0 to 9.
628  ***************************************************************************/
630 {
631  // Determine number of coefficients
632  int ncoeffs = m_coeffs.size();
633 
634  // Set model type
635  if (xml.attribute("type") == "") {
636  xml.attribute("type", type());
637  }
638 
639  // Verify model type
640  if (xml.attribute("type") != type()) {
642  "Radial polynomial model is not of type \""+type()+"\".");
643  }
644 
645  // If XML element has 0 nodes then append nodes for coefficients
646  if (xml.elements() == 0) {
647  for (int i = 0; i < ncoeffs; ++i) {
648  std::string name = "parameter name=\"Coeff"+gammalib::str(i)+"\"";
649  xml.append(GXmlElement(name));
650  }
651  }
652 
653  // Verify that XML element has one parameter per coefficient
654  if (xml.elements() != ncoeffs || xml.elements("parameter") != ncoeffs) {
655  std::string message = "Radial polynomial model requires exactly " +
656  gammalib::str(ncoeffs) + " parameters.";
657  throw GException::model_invalid_parnum(G_WRITE, xml, message);
658  }
659 
660  // Set or update model parameter attributes
661  std::vector<int> npar;
662  npar.assign(ncoeffs, 0);
663  for (int i = 0; i < ncoeffs; ++i) {
664 
665  // Set parameter name
666  std::string name = "Coeff"+gammalib::str(i);
667 
668  // Get corresponding parameter element
669  GXmlElement* par = NULL;
670  for (int k = 0; k < ncoeffs; ++k) {
671  GXmlElement* element = xml.element("parameter", k);
672  if (element->attribute("name") == name) {
673  par = element;
674  break;
675  }
676  }
677 
678  // Make sure that we really have one (just a double check, this should
679  // never fail)
680  if (par == NULL) {
681  std::string message = "Required parameter \""+name+"\" not found.";
682  throw GException::model_invalid_parnames(G_WRITE, xml, message);
683  }
684 
685  // Write parameter
686  m_coeffs[i].write(*par);
687 
688  // Increment parameter counter
689  npar[i]++;
690 
691  } // endfor: looped over all parameters
692 
693  // Verify that all parameters were present
694  for (int i = 0; i < ncoeffs; ++i) {
695  if (npar[i] != 1) {
696  std::string message = "Parameter \"Coeff"+gammalib::str(i)+"\" required,"
697  " but not found in XML file.";
698  throw GException::model_invalid_parnames(G_WRITE, xml, message);
699  }
700  }
701 
702  // Return
703  return;
704 }
705 
706 
707 /***********************************************************************//**
708  * @brief Print point source information
709  *
710  * @param[in] chatter Chattiness (defaults to NORMAL).
711  * @return String containing point source information.
712  ***************************************************************************/
713 std::string GCTAModelRadialPolynom::print(const GChatter& chatter) const
714 {
715  // Initialise result string
716  std::string result;
717 
718  // Continue only if chatter is not silent
719  if (chatter != SILENT) {
720 
721  // Append header
722  result.append("=== GCTAModelRadialPolynom ===");
723 
724  // Append information
725  result.append("\n"+gammalib::parformat("Number of parameters") +
726  gammalib::str(size()));
727  for (int i = 0; i < size(); ++i) {
728  result.append("\n"+m_pars[i]->print(chatter));
729  }
730 
731  } // endif: chatter was not silent
732 
733  // Return result
734  return result;
735 }
736 
737 
738 /*==========================================================================
739  = =
740  = Private methods =
741  = =
742  ==========================================================================*/
743 
744 /***********************************************************************//**
745  * @brief Initialise class members
746  ***************************************************************************/
748 {
749  // Initialise polynomial coefficients
750  m_coeffs.clear();
751 
752  // Update parameter mapping
753  update_pars();
754 
755  // Return
756  return;
757 }
758 
759 
760 /***********************************************************************//**
761  * @brief Copy class members
762  *
763  * @param[in] model Radial Polynomian model.
764  ***************************************************************************/
766 {
767  // Copy members
768  m_coeffs = model.m_coeffs;
769 
770  // Update parameter mapping
771  update_pars();
772 
773  // Return
774  return;
775 }
776 
777 
778 /***********************************************************************//**
779  * @brief Delete class members
780  ***************************************************************************/
782 {
783  // Return
784  return;
785 }
786 
787 
788 /***********************************************************************//**
789  * @brief Update parameter mapping
790  ***************************************************************************/
792 {
793  // Clear parameter pointer(s)
794  m_pars.clear();
795 
796  // Get number of coefficients
797  int ncoeffs = m_coeffs.size();
798 
799  // Set parameter pointers for all coefficients
800  for (int i = 0; i < ncoeffs; ++i) {
801 
802  // Signal that we have gradients
803  m_coeffs[i].has_grad(true);
804 
805  // Set pointer
806  m_pars.push_back(&(m_coeffs[i]));
807 
808  } // endfor: looped over coefficients
809 
810  // Return
811  return;
812 }
813 
814 
815 /*==========================================================================
816  = =
817  = Friends =
818  = =
819  ==========================================================================*/
void free_members(void)
Delete class members.
virtual double omega(void) const
Returns integral over radial model (in steradians)
double romberg(std::vector< double > bounds, const int &order=5)
Perform Romberg integration.
Definition: GIntegral.cpp:380
Radial Polynom model class interface definition.
const std::string & name(void) const
Return parameter name.
Random number generator class definition.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print point source information.
void free_members(void)
Delete class members.
double gradient(void) const
Return parameter gradient.
virtual void write(GXmlElement &xml) const
Write model into XML element.
void copy_members(const GCTAModelRadialPolynom &model)
Copy class members.
GVector cos(const GVector &vector)
Computes cosine of vector elements.
Definition: GVector.cpp:1100
virtual double mc_max_value(const GCTAObservation &obs) const
Return maximum function value for Monte Carlo simulations.
XML element node class.
Definition: GXmlElement.hpp:47
Random number generator class.
Definition: GRan.hpp:44
void init_members(void)
Initialise class members.
const GCTAModelRadialPolynom g_cta_radial_polynom_seed
virtual int elements(void) const
Return number of GXMLElement children of node.
Definition: GXmlNode.cpp:580
Gammalib tools definition.
GIntegral class interface definition.
Definition: GIntegral.hpp:45
CTA radial model registry class definition.
Interface definition for the spatial model registry class.
void update_pars(void)
Update parameter mapping.
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition: GTools.hpp:184
const double & scale(void) const
Return parameter scale.
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition: GTools.hpp:167
Model parameter class.
Definition: GModelPar.hpp:87
virtual ~GCTAModelRadialPolynom(void)
Destructor.
const double deg2rad
Definition: GMath.hpp:43
bool has_grad(void) const
Signal if parameter gradient is computed analytically.
void init_members(void)
Initialise class members.
virtual GCTAInstDir mc(GRan &ran) const
Returns MC instrument direction.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
Radial Polynom CTA model class.
void free(void)
Free a parameter.
double uniform(void)
Returns random double precision floating value in range 0 to 1.
Definition: GRan.cpp:242
CTA instrument direction class interface definition.
int size(void) const
Return number of model parameters.
GChatter
Definition: GTypemaps.hpp:33
GCTAModelRadialPolynom(void)
Void constructor.
CTA observation class interface definition.
virtual GCTAModelRadialPolynom & operator=(const GCTAModelRadialPolynom &model)
Assignment operator.
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
Definition: GXmlNode.cpp:634
virtual void read(const GXmlElement &xml)
Read model from XML element.
virtual void clear(void)
Clear instance.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
Definition: GModelPar.cpp:229
double value(void) const
Return parameter value.
const std::string & unit(void) const
Return parameter unit.
Interface definition for the CTA radial model registry class.
GVector sin(const GVector &vector)
Computes sine of vector elements.
Definition: GVector.cpp:1226
Exception handler interface definition.
virtual std::string type(void) const
Return model type.
CTA instrument direction class.
Definition: GCTAInstDir.hpp:59
int toint(const std::string &arg)
Convert string into integer value.
Definition: GTools.cpp:700
Abstract radial acceptance model class.
const double twopi
Definition: GMath.hpp:36
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
Definition: GXmlNode.cpp:284
CTA observation class.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1022
std::vector< GModelPar * > m_pars
Parameter pointers.
Integration class interface definition.
std::vector< GModelPar > m_coeffs
Coefficients.
#define G_READ
virtual double eval(const double &offset, const bool &gradients=false) const
Evaluate function.
#define G_WRITE
virtual GCTAModelRadial & operator=(const GCTAModelRadial &model)
Assignment operator.
Spatial model registry class definition.
virtual GCTAModelRadialPolynom * clone(void) const
Clone instance.
Mathematical function definitions.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:413
const double g_cta_radial_polynom_offset_max