Commit 2a49e2107fb4874801a6da9fccef47f628c4e2d7

Authored by Jürgen Knödlseder
1 parent ffa7e42d

Limit the sky directions drawn in GModelSpatialEllipticalGauss::mc to an effecti…

…ve radius that is consistent with the Gaussian normalization (#1561).
src/model/GModelSpatialEllipticalGauss.cpp
... ... @@ -36,6 +36,11 @@
36 36 #include "GModelSpatialRegistry.hpp"
37 37  
38 38 /* __ Constants __________________________________________________________ */
  39 +namespace {
  40 + const double c_theta_max = 2.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 +}
39 44  
40 45 /* __ Globals ____________________________________________________________ */
41 46 const GModelSpatialEllipticalGauss g_elliptical_gauss_seed;
... ... @@ -242,12 +247,13 @@ GModelSpatialEllipticalGauss* GModelSpatialEllipticalGauss::clone(void) const
242 247 * @param[in] time Photon arrival time.
243 248 * @return Model value.
244 249 *
245   - * Evaluates the spatial component for an elliptical gauss source model. The
246   - * source model is an elliptical gaussian function
  250 + * Evaluates the spatial component for an elliptical Gaussian source model.
  251 + *
  252 + * The source model is an elliptical Gaussian function
247 253 * \f$S_{\rm p}(\theta, \phi | E, t)\f$, where
248   - * \f$\theta\f$ is the angular separation between elliptical gauss centre and
249   - * the actual location and \f$\phi\f$ the position angle with respect to the
250   - * model centre, counted counterclockwise from North.
  254 + * \f$\theta\f$ is the angular separation between elliptical Gaussian centre
  255 + * and the actual location and \f$\phi\f$ the position angle with respect to
  256 + * the model centre, counted counterclockwise from North.
251 257 *
252 258 * The function \f$f(\theta, \phi)\f$ is given by
253 259 *
... ... @@ -367,7 +373,10 @@ double GModelSpatialEllipticalGauss::eval_gradients(const double&amp; theta,
367 373 * @param[in,out] ran Random number generator.
368 374 * @return Sky direction.
369 375 *
370   - * Draws an arbitrary sky position from the 2D gauss distribution.
  376 + * Draws an arbitrary sky direction from the 2D ellipital Gaussian model.
  377 + * The drawn sky direction will be truncated to \f$2 \sigma\f$ offsets from
  378 + * the ellipse centre, where \f$\sigma\f$ is the effective Gaussian size
  379 + * in the direction of a specific position angle.
371 380 ***************************************************************************/
372 381 GSkyDir GModelSpatialEllipticalGauss::mc(const GEnergy& energy,
373 382 const GTime& time,
... ... @@ -382,8 +391,16 @@ GSkyDir GModelSpatialEllipticalGauss::mc(const GEnergy&amp; energy,
382 391 photon.time(time);
383 392  
384 393 // Draw gaussian offset from each axis
385   - double theta1 = semimajor() * ran.normal();
386   - double theta2 = semiminor() * ran.normal();
  394 + double ran_major;
  395 + double ran_minor;
  396 + do {
  397 + ran_major = ran.normal();
  398 + } while (ran_major > c_theta_max);
  399 + do {
  400 + ran_minor = ran.normal();
  401 + } while (ran_minor > c_theta_max);
  402 + double theta1 = semimajor() * ran_major;
  403 + double theta2 = semiminor() * ran_minor;
387 404  
388 405 // Compute total offset from model centre
389 406 double theta = std::sqrt(theta1 * theta1 + theta2 * theta2);
... ... @@ -431,10 +448,10 @@ bool GModelSpatialEllipticalGauss::contains(const GSkyDir&amp; dir,
431 448 *
432 449 * @return Returns maximum model radius.
433 450 *
434   - * Returns the maximum of \f$2.5\f$ semimajor() and \f$2.5\f$ semiminor() as
  451 + * Returns the maximum of \f$2\f$ semimajor() and \f$2\f$ semiminor() as
435 452 * approximate edge of the Gaussian. This limit is of course arbitrary, but
436 453 * allows to limit the integration region for response computation. The value
437   - * of 2.5 has been determined by experiment. Ideally, a large value should
  454 + * of 2 has been determined by experiment. Ideally, a large value should
438 455 * be used to properly take into account the tails of the distribution, but
439 456 * this apparently leads to fit convergence problems (#1561).
440 457 ***************************************************************************/
... ... @@ -442,8 +459,8 @@ double GModelSpatialEllipticalGauss::theta_max(void) const
442 459 {
443 460 // Set maximum model radius
444 461 double theta_max = (semimajor() > semiminor())
445   - ? semimajor() * gammalib::deg2rad * 2.5
446   - : semiminor() * gammalib::deg2rad * 2.5;
  462 + ? semimajor() * gammalib::deg2rad * c_theta_max
  463 + : semiminor() * gammalib::deg2rad * c_theta_max;
447 464  
448 465 // Return value
449 466 return theta_max;
... ... @@ -768,7 +785,8 @@ void GModelSpatialEllipticalGauss::update() const
768 785 // approximation.
769 786 m_minor2 = m_minor_rad * m_minor_rad;
770 787 m_major2 = m_major_rad * m_major_rad;
771   - double denom = gammalib::twopi * m_minor_rad * m_major_rad;
  788 + double denom = gammalib::twopi * m_minor_rad * m_major_rad *
  789 + c_fraction;
772 790 m_norm = (denom > 0.0) ? 1.0 / denom : 0.0;
773 791  
774 792 } // endif: update required
... ...