GammaLib  2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GModelSpatialEllipticalGauss.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GModelSpatialEllipticalGauss.cpp - Elliptical gauss source model class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2015-2022 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 GModelSpatialEllipticalGauss.cpp
23  * @brief Elliptical gauss 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 namespace {
40  const double c_theta_max = 3.0; //!< semiaxis multiplied for theta_max()
41  const double c_max_exponent = 0.5 * c_theta_max * c_theta_max;
42  const double c_fraction = 1.0 - std::exp(-c_max_exponent);
43 }
44 
45 /* __ Globals ____________________________________________________________ */
47 const GModelSpatialRegistry g_elliptical_gauss_registry(&g_elliptical_gauss_seed);
48 #if defined(G_LEGACY_XML_FORMAT)
49 const GModelSpatialEllipticalGauss g_elliptical_gauss_legacy_seed(true, "EllipticalGauss");
50 const GModelSpatialRegistry g_elliptical_gauss_legacy_registry(&g_elliptical_gauss_legacy_seed);
51 #endif
52 
53 /* __ Method name definitions ____________________________________________ */
54 #define G_CONSTRUCTOR "GModelSpatialEllipticalGauss::"\
55  "GModelSpatialEllipticalGauss(GSkyDir&, double&, double&, "\
56  "double&, std::string&)"
57 #define G_READ "GModelSpatialEllipticalGauss::read(GXmlElement&)"
58 #define G_WRITE "GModelSpatialEllipticalGauss::write(GXmlElement&)"
59 
60 /* __ Macros _____________________________________________________________ */
61 
62 /* __ Coding definitions _________________________________________________ */
63 #define G_SMALL_ANGLE_APPROXIMATION //!< Use small angle approximation
64 
65 /* __ Debug definitions __________________________________________________ */
66 
67 
68 /*==========================================================================
69  = =
70  = Constructors/destructors =
71  = =
72  ==========================================================================*/
73 
74 /***********************************************************************//**
75  * @brief Void constructor
76  ***************************************************************************/
79 {
80  // Initialise members
81  init_members();
82 
83  // Return
84  return;
85 }
86 
87 
88 /***********************************************************************//**
89  * @brief Model type constructor
90  *
91  * @param[in] dummy Dummy flag.
92  * @param[in] type Model type.
93  *
94  * Constructs empty elliptical Gaussian model by specifying a model @p type.
95  ***************************************************************************/
97  const std::string& type) :
99 {
100  // Initialise members
101  init_members();
102 
103  // Set model type
104  m_type = type;
105 
106  // Return
107  return;
108 }
109 
110 
111 /***********************************************************************//**
112  * @brief Elliptical Gaussian constructor
113  *
114  * @param[in] dir Centre of elliptical Gaussian.
115  * @param[in] semimajor Semi-major axis (degrees).
116  * @param[in] semiminor Semi-minor axis (degrees).
117  * @param[in] posangle Position angle of semi-major axis (degrees).
118  * @param[in] coordsys Coordinate system (either "CEL" or "GAL")
119  *
120  * @exception GException::invalid_argument
121  * Invalid @p coordsys argument specified.
122  *
123  * Construct elliptical Gaussian model from the ellipse centre direction
124  * (@p dir), the @p semimajor and @p semiminor axes, and the position
125  * angle (@p posangle). The @p coordsys parameter specifies whether the sky
126  * direction should be interpreted in the celestial or Galactic coordinate
127  * system.
128  ***************************************************************************/
130  const double& semimajor,
131  const double& semiminor,
132  const double& posangle,
133  const std::string& coordsys) :
135 {
136  // Throw an exception if the coordinate system is invalid
137  if ((coordsys != "CEL") && (coordsys != "GAL")) {
138  std::string msg = "Invalid coordinate system \""+coordsys+"\" "
139  "specified. Please specify either \"CEL\" or "
140  "\"GAL\".";
142  }
143 
144  // Initialise members
145  init_members();
146 
147  // Set parameter names
148  if (coordsys == "CEL") {
149  m_lon.name("RA");
150  m_lat.name("DEC");
151  }
152  else {
153  m_lon.name("GLON");
154  m_lat.name("GLAT");
155  }
156 
157  // Assign parameters
158  this->dir(dir);
159  this->semiminor(semiminor);
160  this->semimajor(semimajor);
161  this->posangle(posangle);
162 
163  // Return
164  return;
165 }
166 
167 
168 /***********************************************************************//**
169  * @brief XML constructor
170  *
171  * @param[in] xml XML element.
172  *
173  * Constructs elliptical Gaussian model by extracting information from an XML
174  * element. See the read() method for more information about the expected
175  * structure of the XML element.
176  ***************************************************************************/
179 {
180  // Initialise members
181  init_members();
182 
183  // Read information from XML element
184  read(xml);
185 
186  // Return
187  return;
188 }
189 
190 
191 /***********************************************************************//**
192  * @brief Copy constructor
193  *
194  * @param[in] model Elliptical Gaussian model.
195  ***************************************************************************/
198 {
199  // Initialise members
200  init_members();
201 
202  // Copy members
203  copy_members(model);
204 
205  // Return
206  return;
207 }
208 
209 
210 /***********************************************************************//**
211  * @brief Destructor
212  ***************************************************************************/
214 {
215  // Free members
216  free_members();
217 
218  // Return
219  return;
220 }
221 
222 
223 /*==========================================================================
224  = =
225  = Operators =
226  = =
227  ==========================================================================*/
228 
229 /***********************************************************************//**
230  * @brief Assignment operator
231  *
232  * @param[in] model Elliptical gauss model.
233  * @return Elliptical Gaussian model.
234  ***************************************************************************/
236 {
237  // Execute only if object is not identical
238  if (this != &model) {
239 
240  // Copy base class members
242 
243  // Free members
244  free_members();
245 
246  // Initialise members
247  init_members();
248 
249  // Copy members
250  copy_members(model);
251 
252  } // endif: object was not identical
253 
254  // Return
255  return *this;
256 }
257 
258 
259 /*==========================================================================
260  = =
261  = Public methods =
262  = =
263  ==========================================================================*/
264 
265 /***********************************************************************//**
266  * @brief Clear elliptical Gaussian model
267  ***************************************************************************/
269 {
270  // Free class members (base and derived classes, derived class first)
271  free_members();
274 
275  // Initialise members
278  init_members();
279 
280  // Return
281  return;
282 }
283 
284 
285 /***********************************************************************//**
286  * @brief Clone elliptical Gaussian model
287  *
288  * @return Pointer to deep copy of elliptical Gaussian model.
289  ***************************************************************************/
291 {
292  // Clone elliptical Gaussian model
293  return new GModelSpatialEllipticalGauss(*this);
294 }
295 
296 
297 /***********************************************************************//**
298  * @brief Evaluate function (in units of sr^-1)
299  *
300  * @param[in] theta Angular distance from disk centre (radians).
301  * @param[in] posangle Position angle (counterclockwise from North) (radians).
302  * @param[in] energy Photon energy.
303  * @param[in] time Photon arrival time.
304  * @param[in] gradients Compute gradients?
305  * @return Model value.
306  *
307  * Evaluates the spatial component for an elliptical Gaussian source model.
308  *
309  * The elliptical Gaussian function is defined by
310  * \f$S_{\rm p}(\theta, \phi | E, t)\f$, where
311  * \f$\theta\f$ is the angular separation between elliptical Gaussian centre
312  * and the actual location and \f$\phi\f$ the position angle with respect to
313  * the model centre, counted counterclockwise from North.
314  *
315  * The function \f$S_{\rm p}(\theta, \phi | E, t)\f$ is given by
316  *
317  * \f[
318  * S_{\rm p}(\theta, \phi | E, t) = {\tt m\_norm} \times
319  * \exp \left( -\frac{\theta^2}{2 r_{\rm eff}^2} \right)
320  * \f]
321  *
322  * where the effective ellipse radius \f$r_{\rm eff}\f$ towards a given
323  * position angle is given by
324  *
325  * \f[
326  * r_{\rm eff} = \frac{ab}
327  * {\sqrt{\left( a \sin (\phi - \phi_0) \right)^2} +
328  * \sqrt{\left( b \cos (\phi - \phi_0) \right)^2}}
329  * \f]
330  * and
331  * \f$a\f$ is the semi-major axis of the ellipse,
332  * \f$b\f$ is the semi-minor axis, and
333  * \f$\phi_0\f$ is the position angle of the ellipse, counted
334  * counterclockwise from North.
335  * \f${\tt m\_norm}\f$ is a normalization constant given by
336  *
337  * \f[
338  * {\tt m\_norm} = \frac{1}{2 \pi \times a \times b}
339  * \f]
340  *
341  * The method will not compute analytical parameter gradients, even if the
342  * @p gradients argument is set to true. Radial disk parameter gradients
343  * need to be computed numerically.
344  *
345  * @warning
346  * The above formula for an elliptical Gaussian are accurate for small
347  * angles, with semimajor and semiminor axes below a few degrees. This
348  * should be fine for most use cases, but you should be aware that the
349  * ellipse will get distorted for larger angles.
350  *
351  * @warning
352  * For numerical reasons the elliptical Gaussian will be truncated for
353  * \f$\theta\f$ angles that correspond to 3.0 times the effective ellipse
354  * radius.
355  ***************************************************************************/
356 double GModelSpatialEllipticalGauss::eval(const double& theta,
357  const double& posangle,
358  const GEnergy& energy,
359  const GTime& time,
360  const bool& gradients) const
361 {
362  // Initialise value
363  double value = 0.0;
364 
365  // Continue only if we're inside circle enclosing the ellipse
366  if (theta <= theta_max()) {
367 
368  // Update precomputation cache
369  update();
370 
371  // Perform computations to compute exponent
372  #if defined(G_SMALL_ANGLE_APPROXIMATION)
373  double rel_posangle = posangle - this->posangle() * gammalib::deg2rad;
374  double cosinus = std::cos(rel_posangle);
375  double sinus = std::sin(rel_posangle);
376  double arg1 = m_minor_rad * cosinus;
377  double arg2 = m_major_rad * sinus;
378  double r_ellipse = m_minor_rad * m_major_rad /
379  std::sqrt(arg1*arg1 + arg2*arg2); //!< small angle
380  double r_relative = theta/r_ellipse;
381  double exponent = 0.5*r_relative*r_relative;
382  #else
383  // Perform computations
384  double sinphi = std::sin(posangle);
385  double cosphi = std::cos(posangle);
386 
387  // Compute help term
388  double term1 = m_term1 * cosphi * cosphi;
389  double term2 = m_term2 * sinphi * sinphi;
390  double term3 = m_term3 * sinphi * cosphi;
391 
392  // Compute exponent
393  double exponent = theta * theta * (term1 + term2 + term3);
394  #endif
395 
396  // Set value if the exponent is within the truncation region
397  if (exponent <= c_max_exponent) {
398  value = m_norm * std::exp(-exponent);
399  }
400 
401  // Compile option: Check for NaN/Inf
402  #if defined(G_NAN_CHECK)
403  if (gammalib::is_notanumber(value) || gammalib::is_infinite(value)) {
404  std::cout << "*** ERROR: GModelSpatialEllipticalGauss::eval";
405  std::cout << "(theta=" << theta << "): NaN/Inf encountered";
406  std::cout << "(posangle=" << posangle << "): NaN/Inf encountered";
407  std::cout << " (value=" << value;
408  std::cout << ", MinorAxis^2=" << m_minor2;
409  std::cout << ", MaxjorAxis^2=" << m_major2;
410  std::cout << ", m_norm=" << m_norm;
411  std::cout << ")" << std::endl;
412  }
413  #endif
414 
415  } // endif: position was inside enclosing circle
416 
417  // Return value
418  return value;
419 }
420 
421 
422 /***********************************************************************//**
423  * @brief Returns MC sky direction
424  *
425  * @param[in] energy Photon energy.
426  * @param[in] time Photon arrival time.
427  * @param[in,out] ran Random number generator.
428  * @return Sky direction.
429  *
430  * Draws an arbitrary sky direction from the elliptical Gaussian model.
431  *
432  * @warning
433  * For numerical reasons the elliptical Gaussian will be truncated for
434  * \f$\theta\f$ angles that correspond to 3.0 times the effective ellipse
435  * radius.
436  ***************************************************************************/
438  const GTime& time,
439  GRan& ran) const
440 {
441  // Update precomputation cache
442  update();
443 
444  // Initialise photon
445  GPhoton photon;
446  photon.energy(energy);
447  photon.time(time);
448 
449  // Draw gaussian offset from each axis
450  double ran_major;
451  double ran_minor;
452  do {
453  ran_major = ran.normal();
454  } while (ran_major > c_theta_max);
455  do {
456  ran_minor = ran.normal();
457  } while (ran_minor > c_theta_max);
458  double theta1 = semimajor() * ran_major;
459  double theta2 = semiminor() * ran_minor;
460 
461  // Compute total offset from model centre in small angle approximation
462  double theta = std::sqrt(theta1 * theta1 + theta2 * theta2);
463 
464  // Compute rotation angle, taking into account given position angle
465  double phi = gammalib::atan2d(theta2, theta1) + posangle();
466 
467  // Rotate sky direction by offset
468  GSkyDir sky_dir = dir();
469  sky_dir.rotate_deg(phi , theta);
470 
471  // Set photon sky direction
472  photon.dir(sky_dir);
473 
474  // Return photon direction
475  return (photon.dir());
476 }
477 
478 
479 /***********************************************************************//**
480  * @brief Checks whether model contains specified sky direction
481  *
482  * @param[in] dir Sky direction.
483  * @param[in] margin Margin to be added to sky direction (degrees)
484  * @return True if the model contains the sky direction.
485  *
486  * Signals whether a sky direction is contained in the elliptical gauss
487  * model.
488  *
489  * @todo Implement correct evaluation of effective ellipse radius.
490  ***************************************************************************/
492  const double& margin) const
493 {
494  // Compute distance to centre (radian)
495  double distance = dir.dist(this->dir());
496 
497  // Return flag
498  return (distance <= theta_max() + margin*gammalib::deg2rad);
499 }
500 
501 
502 /***********************************************************************//**
503  * @brief Return maximum model radius (in radians)
504  *
505  * @return Returns maximum model radius.
506  *
507  * Returns the maximum of 3.0 semimajor() and 3.0 semiminor() as
508  * approximate edge of the Gaussian. This limit is of course arbitrary, but
509  * allows to limit the integration region for response computation. The value
510  * of 3.0 has been determined by experiment (#1561).
511  ***************************************************************************/
513 {
514  // Set maximum model radius
515  double theta_max = (semimajor() > semiminor())
516  ? semimajor() * gammalib::deg2rad * c_theta_max
517  : semiminor() * gammalib::deg2rad * c_theta_max;
518 
519  // Return value
520  return theta_max;
521 }
522 
523 
524 /***********************************************************************//**
525  * @brief Read model from XML element
526  *
527  * @param[in] xml XML element.
528  *
529  * Reads the elliptical gauss model information from an XML element. The XML
530  * element shall have either the format
531  *
532  * <spatialModel type="EllipticalGaussian">
533  * <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
534  * <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/>
535  * <parameter name="PA" scale="1.0" value="45.0" min="-360" max="360" free="1"/>
536  * <parameter name="MinorRadius" scale="1.0" value="0.5" min="0.001" max="10" free="1"/>
537  * <parameter name="MajorRadius" scale="1.0" value="2.0" min="0.001" max="10" free="1"/>
538  * </spatialModel>
539  *
540  * or
541  *
542  * <spatialModel type="EllipticalGaussian">
543  * <parameter name="GLON" scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
544  * <parameter name="GLAT" scale="1.0" value="22.0145" min="-90" max="90" free="1"/>
545  * <parameter name="PA" scale="1.0" value="45.0" min="-360" max="360" free="1"/>
546  * <parameter name="MinorRadius" scale="1.0" value="0.5" min="0.001" max="10" free="1"/>
547  * <parameter name="MajorRadius" scale="1.0" value="2.0" min="0.001" max="10" free="1"/>
548  * </spatialModel>
549  *
550  * @todo Implement a test of the ellipse boundary. The axes
551  * and axes minimum should be >0.
552  ***************************************************************************/
554 {
555  // Verify number of model parameters
557 
558  // Read gauss location
560 
561  // Get parameters
562  const GXmlElement* minor = gammalib::xml_get_par(G_READ, xml, m_semiminor.name());
563  const GXmlElement* major = gammalib::xml_get_par(G_READ, xml, m_semimajor.name());
564 
565  // Read parameters
566  m_semiminor.read(*minor);
567  m_semimajor.read(*major);
568 
569  // Return
570  return;
571 }
572 
573 
574 /***********************************************************************//**
575  * @brief Write model into XML element
576  *
577  * @param[in] xml XML element into which model information is written.
578  *
579  * Write the elliptical gauss model information into an XML element. The XML
580  * element will have the format
581  *
582  * <spatialModel type="EllipticalGaussian">
583  * <parameter name="RA" scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
584  * <parameter name="DEC" scale="1.0" value="22.0145" min="-90" max="90" free="1"/>
585  * <parameter name="PA" scale="1.0" value="45.0" min="-360" max="360" free="1"/>
586  * <parameter name="MinorRadius" scale="1.0" value="0.5" min="0.001" max="10" free="1"/>
587  * <parameter name="MajorRadius" scale="1.0" value="2.0" min="0.001" max="10" free="1"/>
588  * </spatialModel>
589  *
590  ***************************************************************************/
592 {
593  // Verify model type
595 
596  // Write disk location
598 
599  // Get or create parameters
602 
603  // Write parameters
604  m_semiminor.write(*minor);
605  m_semimajor.write(*major);
606 
607  // Return
608  return;
609 }
610 
611 
612 /***********************************************************************//**
613  * @brief Print information
614  *
615  * @param[in] chatter Chattiness.
616  * @return String containing model information.
617  ***************************************************************************/
618 std::string GModelSpatialEllipticalGauss::print(const GChatter& chatter) const
619 {
620  // Initialise result string
621  std::string result;
622 
623  // Continue only if chatter is not silent
624  if (chatter != SILENT) {
625 
626  // Append header
627  result.append("=== GModelSpatialEllipticalGauss ===");
628 
629  // Append parameters
630  result.append("\n"+gammalib::parformat("Number of parameters"));
631  result.append(gammalib::str(size()));
632  for (int i = 0; i < size(); ++i) {
633  result.append("\n"+m_pars[i]->print(chatter));
634  }
635 
636  } // endif: chatter was not silent
637 
638  // Return result
639  return result;
640 }
641 
642 
643 /*==========================================================================
644  = =
645  = Private methods =
646  = =
647  ==========================================================================*/
648 
649 /***********************************************************************//**
650  * @brief Initialise class members
651  ***************************************************************************/
653 {
654  // Initialise model type
655  m_type = "EllipticalGaussian";
656 
657  // Initialise precomputation cache. Note that zero values flag
658  // uninitialised as a zero radius is not meaningful
659  m_last_minor = 0.0;
660  m_last_major = 0.0;
661  m_minor_rad = 0.0;
662  m_major_rad = 0.0;
663  m_norm = 0.0;
664  m_last_posangle = 9999.0; // Signals that has not been initialised
665  m_sin2pos = 0.0;
666  m_cospos2 = 0.0;
667  m_sinpos2 = 0.0;
668  m_minor2 = 0.0;
669  m_major2 = 0.0;
670  m_term1 = 0.0;
671  m_term2 = 0.0;
672  m_term3 = 0.0;
673 
674  // Return
675  return;
676 }
677 
678 
679 /***********************************************************************//**
680  * @brief Copy class members
681  *
682  * @param[in] model Elliptical Gaussian model.
683  ***************************************************************************/
685 {
686  // Copy members
687  m_type = model.m_type; // Needed to conserve model type
688 
689  // Copy precomputation cache
690  m_last_minor = model.m_last_minor;
691  m_last_major = model.m_last_major;
692  m_minor_rad = model.m_minor_rad;
693  m_major_rad = model.m_major_rad;
694  m_norm = model.m_norm;
696  m_sin2pos = model.m_sin2pos;
697  m_cospos2 = model.m_cospos2;
698  m_sinpos2 = model.m_sinpos2;
699  m_minor2 = model.m_minor2;
700  m_major2 = model.m_major2;
701  m_term1 = model.m_term1;
702  m_term2 = model.m_term2;
703  m_term3 = model.m_term3;
704 
705  // Return
706  return;
707 }
708 
709 
710 /***********************************************************************//**
711  * @brief Delete class members
712  ***************************************************************************/
714 {
715  // Return
716  return;
717 }
718 
719 
720 /***********************************************************************//**
721  * @brief Update precomputation cache
722  *
723  * Computes the normalization
724  * \f[
725  * {\tt m\_norm} = \frac{1}{2 \pi \times a \times b}
726  * \f]
727  * where
728  * \f$a\f$ is the semi-major axis and
729  * \f$b\f$ is the semi-minor axis of the ellipse.
730  *
731  * @warning
732  * The normalization of the elliptical Gaussian is only valid in the small
733  * angle approximation.
734  ***************************************************************************/
736 {
737  // Initialise flag if something has changed
738  bool changed = false;
739 
740  // Update if one axis has changed
741  if (m_last_minor != semiminor() || m_last_major != semimajor()) {
742 
743  // Signal parameter changes
744  changed = true;
745 
746  // Store last values
749 
750  // Compute axes in radians
753 
754  // Perform precomputations. Note that I verified the normalization
755  // by numerical integration of the resulting Gaussian. Note also
756  // also that the normalization is only correct in the small angle
757  // approximation.
760  double denom = gammalib::twopi * m_minor_rad * m_major_rad *
761  c_fraction;
762  m_norm = (denom > 0.0) ? 1.0 / denom : 0.0;
763 
764  } // endif: update required
765 
766  // Update chache if position angle changed
767  #if !defined(G_SMALL_ANGLE_APPROXIMATION)
768  if (m_last_posangle != posangle()) {
769 
770  // Signal parameter changes
771  changed = true;
772 
773  // Store last value
775 
776  // Compute angle in radians
777  double posangle_rad = m_last_posangle * gammalib::deg2rad;
778 
779  // Compute sine and cosine
780  double cospos = std::cos(posangle_rad);
781  double sinpos = std::sin(posangle_rad);
782 
783  // Cache important values for further computations
784  m_cospos2 = cospos * cospos;
785  m_sinpos2 = sinpos * sinpos;
786  m_sin2pos = std::sin(2.0 * posangle_rad);
787 
788  } // endif: position angle update required
789 
790  // Perform precomputations in case anything has changed
791  if (changed) {
792 
793  // Compute help terms
794  m_term1 = 0.5 * (m_cospos2 / m_minor2 + m_sinpos2 / m_major2);
795  m_term2 = 0.5 * (m_cospos2 / m_major2 + m_sinpos2 / m_minor2);
796  m_term3 = 0.5 * (m_sin2pos / m_major2 - m_sin2pos / m_minor2);
797 
798  } // endif: something has changed
799  #endif
800 
801  // Return
802  return;
803 }
804 
805 
806 /***********************************************************************//**
807  * @brief Set boundary sky region
808  ***************************************************************************/
810 {
811  // Set maximum model radius
812  double max_radius = (semimajor() > semiminor()) ? semimajor() : semiminor();
813 
814  // Set sky region circle (maximum Gaussian sigma times a scaling
815  // factor (actually 3))
816  GSkyRegionCircle region(dir(), max_radius * c_theta_max);
817 
818  // Set region (circumvent const correctness)
819  const_cast<GModelSpatialEllipticalGauss*>(this)->m_region = region;
820 
821  // Return
822  return;
823 }
GModelPar m_semimajor
Semi-major axis of ellipse (deg)
double m_last_major
Last semi-major axis.
virtual void write(GXmlElement &xml) const
Write model into XML element.
double m_sinpos2
squared sine of position angle
void free_members(void)
Delete class members.
virtual GModelSpatialEllipticalGauss * clone(void) const
Clone elliptical Gaussian model.
virtual bool contains(const GSkyDir &dir, const double &margin=0.0) const
Checks whether model contains specified sky direction.
virtual void write(GXmlElement &xml) const
Write model into XML element.
Abstract elliptical spatial model base class.
const std::string & name(void) const
Return parameter name.
GModelSpatialEllipticalGauss(void)
Void constructor.
virtual GModelSpatialEllipticalGauss & operator=(const GModelSpatialEllipticalGauss &model)
Assignment operator.
GModelPar m_lon
Right Ascension or Galactic longitude (deg)
virtual void clear(void)
Clear elliptical Gaussian model.
int size(void) const
Return number of parameters.
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)
virtual void read(const GXmlElement &xml)
Read model from XML element.
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
Definition: GModelPar.cpp:351
GVector cos(const GVector &vector)
Computes cosine of vector elements.
Definition: GVector.cpp:1190
double m_minor_rad
Minor axis in radians.
virtual GModelSpatialElliptical & operator=(const GModelSpatialElliptical &model)
Assignment operator.
XML element node class.
Definition: GXmlElement.hpp:48
const GSkyDir & dir(void) const
Return position of elliptical spatial model.
Random number generator class.
Definition: GRan.hpp:44
Time class.
Definition: GTime.hpp:55
Gammalib tools definition.
Interface for the circular sky region class.
Interface definition for the spatial model registry class.
double m_cospos2
squared cosine of position angle
void init_members(void)
Initialise class members.
GSkyRegionCircle m_region
Bounding circle.
virtual void set_region(void) const
Set boundary sky region.
bool is_notanumber(const double &x)
Signal if argument is not a number.
Definition: GTools.hpp:201
#define G_CONSTRUCTOR
Class that handles photons.
Definition: GPhoton.hpp:47
bool is_infinite(const double &x)
Signal if argument is infinite.
Definition: GTools.hpp:184
void update(void) const
Update precomputation cache.
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:1358
double m_last_minor
Last semi-minor axis.
Radial disk model class interface definition.
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:424
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
double m_sin2pos
sine of twice the position angle
Spatial model registry class definition.
const GTime & time(void) const
Return photon time.
Definition: GPhoton.hpp:134
GChatter
Definition: GTypemaps.hpp:33
void init_members(void)
Initialise class members.
virtual void read(const GXmlElement &xml)
Read model from XML element.
GModelPar m_semiminor
Semi-minor axis of ellipse (deg)
std::string type(void) const
Return model type.
virtual GSkyDir mc(const GEnergy &energy, const GTime &time, GRan &ran) const
Returns MC sky direction.
void xml_check_parnum(const std::string &origin, const GXmlElement &xml, const int &number)
Checks number of parameters.
Definition: GTools.cpp:1777
const GModelSpatialEllipticalGauss g_elliptical_gauss_seed
double normal(void)
Returns normal deviates.
Definition: GRan.cpp:257
const GSkyRegion * region(void) const
Return boundary sky region.
void free_members(void)
Delete class members.
double atan2d(const double &y, const double &x)
Compute arc tangens in degrees.
Definition: GMath.cpp:308
std::string m_type
Spatial model type.
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 m_last_posangle
Last position angle.
GModelPar m_lat
Declination or Galactic latitude (deg)
virtual std::string print(const GChatter &chatter=NORMAL) const
Print information.
void copy_members(const GModelSpatialEllipticalGauss &model)
Copy class members.
GVector sin(const GVector &vector)
Computes sine of vector elements.
Definition: GVector.cpp:1316
const GEnergy & energy(void) const
Return photon energy.
Definition: GPhoton.hpp:122
Exception handler interface definition.
double dist(const GSkyDir &dir) const
Compute angular distance between sky directions in radians.
Definition: GSkyDir.hpp:271
GVector exp(const GVector &vector)
Computes exponential of vector elements.
Definition: GVector.cpp:1232
Elliptical gauss model class interface definition.
void init_members(void)
Initialise class members.
const double twopi
Definition: GMath.hpp:36
virtual ~GModelSpatialEllipticalGauss(void)
Destructor.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
void free_members(void)
Delete class members.
Sky direction class.
Definition: GSkyDir.hpp:62
double m_major_rad
Major axis in radians.
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:1689
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
virtual double theta_max(void) const
Return maximum model radius (in radians)
void xml_check_type(const std::string &origin, GXmlElement &xml, const std::string &type)
Checks the model type.
Definition: GTools.cpp:1819