GammaLib 2.0.0
Loading...
Searching...
No Matches
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 __________________________________________________________ */
39namespace {
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 ____________________________________________________________ */
47const GModelSpatialRegistry g_elliptical_gauss_registry(&g_elliptical_gauss_seed);
48#if defined(G_LEGACY_XML_FORMAT)
49const GModelSpatialEllipticalGauss g_elliptical_gauss_legacy_seed(true, "EllipticalGauss");
50const 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
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 ***************************************************************************/
356double 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
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 ***************************************************************************/
618std::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
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
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}
#define G_WRITE
#define G_READ
Exception handler interface definition.
Mathematical function definitions.
#define G_CONSTRUCTOR
Definition GMatrix.cpp:41
const GModelSpatialEllipticalGauss g_elliptical_gauss_seed
Elliptical gauss model class interface definition.
Radial disk model class interface definition.
Spatial model registry class definition.
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
Class that handles energies in a unit independent way.
Definition GEnergy.hpp:48
void write(GXmlElement &xml) const
Set or update parameter attributes in XML element.
void read(const GXmlElement &xml)
Extract parameter attributes from XML element.
virtual void set_region(void) const
Set boundary sky region.
virtual GModelSpatialEllipticalGauss * clone(void) const
Clone elliptical Gaussian model.
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 copy_members(const GModelSpatialEllipticalGauss &model)
Copy class members.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
virtual GModelSpatialEllipticalGauss & operator=(const GModelSpatialEllipticalGauss &model)
Assignment operator.
virtual void write(GXmlElement &xml) const
Write model into XML element.
virtual ~GModelSpatialEllipticalGauss(void)
Destructor.
virtual void clear(void)
Clear elliptical Gaussian model.
void update(void) const
Update precomputation cache.
virtual bool contains(const GSkyDir &dir, const double &margin=0.0) const
Checks whether model contains specified sky direction.
virtual double theta_max(void) const
Return maximum model radius (in radians)
virtual GSkyDir mc(const GEnergy &energy, const GTime &time, GRan &ran) const
Returns MC sky direction.
GModelSpatialEllipticalGauss(void)
Void constructor.
double m_sin2pos
sine of twice the position angle
double m_cospos2
squared cosine of position angle
virtual std::string print(const GChatter &chatter=NORMAL) const
Print information.
double m_sinpos2
squared sine of position angle
Abstract elliptical spatial model base class.
void init_members(void)
Initialise class members.
GModelPar m_semiminor
Semi-minor axis of ellipse (deg)
double semimajor(void) const
Return semi-major axis of ellipse.
virtual void write(GXmlElement &xml) const
Write model into XML element.
GModelPar m_semimajor
Semi-major axis of ellipse (deg)
GModelPar m_lat
Declination or Galactic latitude (deg)
void free_members(void)
Delete class members.
double posangle(void) const
Return Position Angle of model.
virtual GModelSpatialElliptical & operator=(const GModelSpatialElliptical &model)
Assignment operator.
GModelPar m_lon
Right Ascension or Galactic longitude (deg)
const GSkyDir & dir(void) const
Return position of elliptical spatial model.
std::string coordsys(void) const
Return coordinate system.
double semiminor(void) const
Return semi-minor axis of ellipse.
virtual void read(const GXmlElement &xml)
Read model from XML element.
Interface definition for the spatial model registry class.
std::string m_type
Spatial model type.
std::string type(void) const
Return model type.
const GSkyRegion * region(void) const
Return boundary sky region.
std::vector< GModelPar * > m_pars
Parameter pointers.
void init_members(void)
Initialise class members.
int size(void) const
Return number of parameters.
void free_members(void)
Delete class members.
GSkyRegionCircle m_region
Bounding circle.
const std::string & name(void) const
Return parameter name.
Class that handles photons.
Definition GPhoton.hpp:47
const GTime & time(void) const
Return photon time.
Definition GPhoton.hpp:134
const GSkyDir & dir(void) const
Return photon sky direction.
Definition GPhoton.hpp:110
const GEnergy & energy(void) const
Return photon energy.
Definition GPhoton.hpp:122
Random number generator class.
Definition GRan.hpp:44
double normal(void)
Returns normal deviates.
Definition GRan.cpp:257
Sky direction class.
Definition GSkyDir.hpp:62
void rotate_deg(const double &phi, const double &theta)
Rotate sky direction by zenith and azimuth angle.
Definition GSkyDir.cpp:424
double dist(const GSkyDir &dir) const
Compute angular distance between sky directions in radians.
Definition GSkyDir.hpp:271
Interface for the circular sky region class.
Time class.
Definition GTime.hpp:55
XML element node class.
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
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
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
void xml_check_parnum(const std::string &origin, const GXmlElement &xml, const int &number)
Checks number of parameters.
Definition GTools.cpp:1777
double atan2d(const double &y, const double &x)
Compute arc tangens in degrees.
Definition GMath.cpp:308
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