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 | 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 = | ... | ... |