Commit 08d936ce65b62ee8e7f2e8671988f56fc3ae767b
1 parent
3e182460
add roi_kern class and use it in npred() method
Showing
1 changed file
with
106 additions
and
0 deletions
inst/cta/src/GCTAModelRadialAcceptance.cpp
| @@ -26,10 +26,13 @@ | @@ -26,10 +26,13 @@ | ||
| 26 | #include "GModelSpectralRegistry.hpp" | 26 | #include "GModelSpectralRegistry.hpp" |
| 27 | #include "GModelTemporalRegistry.hpp" | 27 | #include "GModelTemporalRegistry.hpp" |
| 28 | #include "GModelTemporalConst.hpp" | 28 | #include "GModelTemporalConst.hpp" |
| 29 | +#include "GIntegral.hpp" | ||
| 29 | #include "GCTAException.hpp" | 30 | #include "GCTAException.hpp" |
| 30 | #include "GCTAInstDir.hpp" | 31 | #include "GCTAInstDir.hpp" |
| 32 | +#include "GCTARoi.hpp" | ||
| 31 | #include "GCTAModelRadialRegistry.hpp" | 33 | #include "GCTAModelRadialRegistry.hpp" |
| 32 | #include "GCTAModelRadialAcceptance.hpp" | 34 | #include "GCTAModelRadialAcceptance.hpp" |
| 35 | +#include "GCTASupport.hpp" | ||
| 33 | 36 | ||
| 34 | /* __ Constants __________________________________________________________ */ | 37 | /* __ Constants __________________________________________________________ */ |
| 35 | 38 | ||
| @@ -43,6 +46,8 @@ const GModelRegistry g_cta_radial_acceptance_registry(&g_cta_radial_a | @@ -43,6 +46,8 @@ const GModelRegistry g_cta_radial_acceptance_registry(&g_cta_radial_a | ||
| 43 | " GObservation&)" | 46 | " GObservation&)" |
| 44 | #define G_EVAL_GRADIENTS "GCTAModelRadialAcceptance::eval_gradients(GEvent&,"\ | 47 | #define G_EVAL_GRADIENTS "GCTAModelRadialAcceptance::eval_gradients(GEvent&,"\ |
| 45 | " GObservation&)" | 48 | " GObservation&)" |
| 49 | +#define G_NPRED "GCTAModelRadialAcceptance::npred(GEnergy&, GTime&,"\ | ||
| 50 | + " GObservation&)" | ||
| 46 | #define G_MC "GCTAModelRadialAcceptance::mc(GObservation&, GRan&)" | 51 | #define G_MC "GCTAModelRadialAcceptance::mc(GObservation&, GRan&)" |
| 47 | #define G_XML_RADIAL "GCTAModelRadialAcceptance::xml_radial(GXmlElement&)" | 52 | #define G_XML_RADIAL "GCTAModelRadialAcceptance::xml_radial(GXmlElement&)" |
| 48 | #define G_XML_SPECTRAL "GCTAModelRadialAcceptance::xml_spectral(GXmlElement&)" | 53 | #define G_XML_SPECTRAL "GCTAModelRadialAcceptance::xml_spectral(GXmlElement&)" |
| @@ -251,6 +256,9 @@ double GCTAModelRadialAcceptance::eval(const GEvent& event, const GObservation& | @@ -251,6 +256,9 @@ double GCTAModelRadialAcceptance::eval(const GEvent& event, const GObservation& | ||
| 251 | * @param[in] event Observed event. | 256 | * @param[in] event Observed event. |
| 252 | * @param[in] obs Observation (not used). | 257 | * @param[in] obs Observation (not used). |
| 253 | * | 258 | * |
| 259 | + * @exception GCTAException::no_pointing | ||
| 260 | + * No valid CTA pointing found in observation | ||
| 261 | + * | ||
| 254 | * @todo Add bookkeeping of last value and evaluate only if argument | 262 | * @todo Add bookkeeping of last value and evaluate only if argument |
| 255 | * changed | 263 | * changed |
| 256 | * @todo Verify that CTA instrument direction pointer is valid, or better, | 264 | * @todo Verify that CTA instrument direction pointer is valid, or better, |
| @@ -317,6 +325,72 @@ double GCTAModelRadialAcceptance::eval_gradients(const GEvent& event, | @@ -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 | * @brief Return simulated list of events | 394 | * @brief Return simulated list of events |
| 321 | * | 395 | * |
| 322 | * @param[in] obs Observation. | 396 | * @param[in] obs Observation. |
| @@ -804,6 +878,38 @@ GModelTemporal* GCTAModelRadialAcceptance::xml_temporal(const GXmlElement& tempo | @@ -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 | = Friends = | 915 | = Friends = |