Commit 08d936ce65b62ee8e7f2e8671988f56fc3ae767b

Authored by knodlseder
1 parent 3e182460

add roi_kern class and use it in npred() method

inst/cta/src/GCTAModelRadialAcceptance.cpp
... ... @@ -26,10 +26,13 @@
26 26 #include "GModelSpectralRegistry.hpp"
27 27 #include "GModelTemporalRegistry.hpp"
28 28 #include "GModelTemporalConst.hpp"
  29 +#include "GIntegral.hpp"
29 30 #include "GCTAException.hpp"
30 31 #include "GCTAInstDir.hpp"
  32 +#include "GCTARoi.hpp"
31 33 #include "GCTAModelRadialRegistry.hpp"
32 34 #include "GCTAModelRadialAcceptance.hpp"
  35 +#include "GCTASupport.hpp"
33 36  
34 37 /* __ Constants __________________________________________________________ */
35 38  
... ... @@ -43,6 +46,8 @@ const GModelRegistry g_cta_radial_acceptance_registry(&g_cta_radial_a
43 46 " GObservation&)"
44 47 #define G_EVAL_GRADIENTS "GCTAModelRadialAcceptance::eval_gradients(GEvent&,"\
45 48 " GObservation&)"
  49 +#define G_NPRED "GCTAModelRadialAcceptance::npred(GEnergy&, GTime&,"\
  50 + " GObservation&)"
46 51 #define G_MC "GCTAModelRadialAcceptance::mc(GObservation&, GRan&)"
47 52 #define G_XML_RADIAL "GCTAModelRadialAcceptance::xml_radial(GXmlElement&)"
48 53 #define G_XML_SPECTRAL "GCTAModelRadialAcceptance::xml_spectral(GXmlElement&)"
... ... @@ -251,6 +256,9 @@ double GCTAModelRadialAcceptance::eval(const GEvent& event, const GObservation&
251 256 * @param[in] event Observed event.
252 257 * @param[in] obs Observation (not used).
253 258 *
  259 + * @exception GCTAException::no_pointing
  260 + * No valid CTA pointing found in observation
  261 + *
254 262 * @todo Add bookkeeping of last value and evaluate only if argument
255 263 * changed
256 264 * @todo Verify that CTA instrument direction pointer is valid, or better,
... ... @@ -317,6 +325,72 @@ double GCTAModelRadialAcceptance::eval_gradients(const GEvent& event,
317 325  
318 326  
319 327 /***********************************************************************//**
  328 + * @brief Return spatially integrated data model
  329 + *
  330 + * @param[in] obsEng Measured event energy.
  331 + * @param[in] obsTime Measured event time.
  332 + * @param[in] obs Observation.
  333 + *
  334 + * @exception GException::no_roi
  335 + * No valid region of interest found in observation
  336 + * @exception GCTAException::no_pointing
  337 + * No valid CTA pointing found in observation
  338 + *
  339 + * Spatially integrates the data model for a given measured event energy
  340 + * and event time.
  341 + ***************************************************************************/
  342 +double GCTAModelRadialAcceptance::npred(const GEnergy& obsEng,
  343 + const GTime& obsTime,
  344 + const GObservation& obs)
  345 +{
  346 + // Initialise result
  347 + double npred = 0.0;
  348 +
  349 + // Evaluate only if model is valid
  350 + if (valid_model()) {
  351 +
  352 + // Circumvent const correctness
  353 + GCTAObservation* cta = (GCTAObservation*)(&obs);
  354 +
  355 + // Extract CTA ROI information. Throw an exception if ROI has not
  356 + // been defined
  357 + GCTARoi* roi = (GCTARoi*)cta->roi();
  358 + if (roi == NULL)
  359 + throw GException::no_roi(G_NPRED);
  360 +
  361 + // Extract CTA pointing direction. Throw an exception if pointing
  362 + // has not been defined
  363 + GCTAPointing* pnt = cta->pointing(obsTime);
  364 + if (pnt == NULL)
  365 + throw GCTAException::no_pointing(G_NPRED);
  366 +
  367 + // Get ROI radius in radians
  368 + double roi_radius = roi->radius() * deg2rad;
  369 +
  370 + // Get distance from ROI centre in radians
  371 + double roi_distance = roi->centre().dist(pnt->dir());
  372 +
  373 + // Setup integration function
  374 + GCTAModelRadialAcceptance::roi_kern integrand(radial(), roi_radius, roi_distance);
  375 +
  376 + // Setup integrator
  377 + GIntegral integral(&integrand);
  378 +
  379 + // Spatially integrate radial component
  380 + npred = integral.romb(0.0, roi_radius);
  381 +
  382 + // Multiply in spectral and temporal components
  383 + npred *= spectral()->eval(obsEng);
  384 + npred *= temporal()->eval(obsTime);
  385 +
  386 + } // endif: model was valid
  387 +
  388 + // Return
  389 + return npred;
  390 +}
  391 +
  392 +
  393 +/***********************************************************************//**
320 394 * @brief Return simulated list of events
321 395 *
322 396 * @param[in] obs Observation.
... ... @@ -804,6 +878,38 @@ GModelTemporal* GCTAModelRadialAcceptance::xml_temporal(const GXmlElement& tempo
804 878 }
805 879  
806 880  
  881 +/***********************************************************************//**
  882 + * @brief Integration kernel for the Npred method
  883 + *
  884 + * @param[in] offset Offset angle (radians).
  885 + *
  886 + * Computes
  887 + * \f[N_{\rm pred} = \int_{\rm ROI} r(\theta) \sin \theta {\rm d}\phi\f]
  888 + * where
  889 + * \f$r(\theta)\f$ is the radial acceptance function,
  890 + * \f$\theta\f$ is the measured offset angle from the pointing direction
  891 + * in radians, and
  892 + * \f$\phi\f$ is the measured azimuth angle. The integration is done over
  893 + * the arc of the azimuth angle that lies within the ROI. This integration
  894 + * is done analytically using the "cta_roi_arclength" support function.
  895 + ***************************************************************************/
  896 +double GCTAModelRadialAcceptance::roi_kern::eval(double offset)
  897 +{
  898 + // Circumvent const correctness
  899 + GCTAModelRadial* radial = (GCTAModelRadial*)m_parent;
  900 +
  901 + // Get arclength for given radius in radians.
  902 + double phi = cta_roi_arclength(offset, m_dist, m_cosdist, m_sindist,
  903 + m_roi, m_cosroi);
  904 +
  905 + // Get PSF value
  906 + double value = radial->eval(offset*rad2deg) * phi * sin(offset);
  907 +
  908 + // Return
  909 + return value;
  910 +}
  911 +
  912 +
807 913 /*==========================================================================
808 914 = =
809 915 = Friends =
... ...