Commit 68717400d5ac5edb64e44187e6cc8d03998d7cb6
1 parent
4518c159
first go at flux from circular region, does not work for small sources
Showing
3 changed files
with
241 additions
and
0 deletions
include/GModelSpatial.hpp
| ... | ... | @@ -34,10 +34,13 @@ |
| 34 | 34 | #include "GModelPar.hpp" |
| 35 | 35 | #include "GPhoton.hpp" |
| 36 | 36 | #include "GSkyDir.hpp" |
| 37 | +#include "GSkyRegionCircle.hpp" | |
| 37 | 38 | #include "GEnergy.hpp" |
| 38 | 39 | #include "GTime.hpp" |
| 39 | 40 | #include "GXmlElement.hpp" |
| 40 | 41 | #include "GRan.hpp" |
| 42 | +#include "GFunction.hpp" | |
| 43 | +#include "GIntegral.hpp" | |
| 41 | 44 | |
| 42 | 45 | /* __ Forward declarations _______________________________________________ */ |
| 43 | 46 | class GSkyRegion; |
| ... | ... | @@ -102,6 +105,7 @@ public: |
| 102 | 105 | virtual void write(GXmlElement& xml) const = 0; |
| 103 | 106 | virtual GSkyRegion* region(void) const = 0; |
| 104 | 107 | virtual std::string print(const GChatter& chatter = NORMAL) const = 0; |
| 108 | + | |
| 105 | 109 | |
| 106 | 110 | // Methods |
| 107 | 111 | GModelPar& at(const int& index); |
| ... | ... | @@ -110,6 +114,9 @@ public: |
| 110 | 114 | bool has_free_pars(void) const; |
| 111 | 115 | int size(void) const; |
| 112 | 116 | void autoscale(void); |
| 117 | + double flux(const GSkyRegionCircle& reg, | |
| 118 | + const GEnergy& srcEng = GEnergy(), | |
| 119 | + const GTime& srcTime = GTime()) const; | |
| 113 | 120 | |
| 114 | 121 | protected: |
| 115 | 122 | // Protected methods |
| ... | ... | @@ -117,6 +124,87 @@ protected: |
| 117 | 124 | void copy_members(const GModelSpatial& model); |
| 118 | 125 | void free_members(void); |
| 119 | 126 | |
| 127 | + /***********************************************************************//** | |
| 128 | + * @class circle_int_kern_rho | |
| 129 | + * | |
| 130 | + * @brief Kernel for circular sky region radial integration | |
| 131 | + * | |
| 132 | + * This class implements the integration kernel \f$K(\rho)\f$ for the | |
| 133 | + * integration | |
| 134 | + * | |
| 135 | + * \f[ | |
| 136 | + * \int_{\rho_{\rm min}}^{\rho_{\rm max}} K(\rho | E, t) d\rho | |
| 137 | + * \f] | |
| 138 | + * | |
| 139 | + * of a spatial model over a circular region. The eval() method computes | |
| 140 | + * | |
| 141 | + * \f[ | |
| 142 | + * K(\rho | E, t) = \sin \rho \times | |
| 143 | + * \int_{\omega} M(\rho, \omega | E, t) d\omega | |
| 144 | + * \f] | |
| 145 | + * | |
| 146 | + * where | |
| 147 | + * \f$M(\rho, \omega | E, t)\f$ is the spatial model, | |
| 148 | + * \f$\rho\f$ is the distance from the region centre, and | |
| 149 | + * \f$\omega\f$ is the position angle with respect to the connecting line | |
| 150 | + * between the region centre and the direction on the sky. | |
| 151 | + ***************************************************************************/ | |
| 152 | + class circle_int_kern_rho : public GFunction { | |
| 153 | + public: | |
| 154 | + circle_int_kern_rho(const GModelSpatial* model, | |
| 155 | + const GSkyRegionCircle& reg, | |
| 156 | + const GEnergy& srcEng, | |
| 157 | + const GTime& srcTime) : | |
| 158 | + m_model(model), | |
| 159 | + m_reg(reg), | |
| 160 | + m_srcEng(srcEng), | |
| 161 | + m_srcTime(srcTime) { } | |
| 162 | + double eval(const double& rho); | |
| 163 | + public: | |
| 164 | + const GModelSpatial* m_model; //!< Model | |
| 165 | + GSkyRegionCircle m_reg; //!< Region | |
| 166 | + GEnergy m_srcEng; //!< Photon energy | |
| 167 | + GTime m_srcTime; //!< Photon time | |
| 168 | + }; | |
| 169 | + | |
| 170 | + /***********************************************************************//** | |
| 171 | + * @class circle_int_kern_omega | |
| 172 | + * | |
| 173 | + * @brief Kernel for circular sky region azimuth angle integration | |
| 174 | + * | |
| 175 | + * This class implements the computation of | |
| 176 | + * | |
| 177 | + * \f[ | |
| 178 | + * K(\omega | \rho, E, t) = M(\omega | \rho) | |
| 179 | + * \f] | |
| 180 | + * | |
| 181 | + * where | |
| 182 | + * \fM(\omega | \rho)\f$ is the spatial model, | |
| 183 | + * \f$\rho\f$ is the distance from the region centre, and | |
| 184 | + * \f$\omega\f$ is the position angle with respect to the connecting line | |
| 185 | + * between the region centre and the direction on the sky. | |
| 186 | + ***************************************************************************/ | |
| 187 | + class circle_int_kern_omega : public GFunction { | |
| 188 | + public: | |
| 189 | + circle_int_kern_omega(const GModelSpatial* model, | |
| 190 | + const GSkyRegionCircle& reg, | |
| 191 | + const double& rho, | |
| 192 | + const GEnergy& srcEng, | |
| 193 | + const GTime& srcTime) : | |
| 194 | + m_model(model), | |
| 195 | + m_reg(reg), | |
| 196 | + m_rho(rho), | |
| 197 | + m_srcEng(srcEng), | |
| 198 | + m_srcTime(srcTime) { } | |
| 199 | + double eval(const double& omega); | |
| 200 | + public: | |
| 201 | + const GModelSpatial* m_model; //!< Model | |
| 202 | + GSkyRegionCircle m_reg; //!< Region | |
| 203 | + double m_rho; //!< Offset from center of the region | |
| 204 | + GEnergy m_srcEng; //!< Photon energy | |
| 205 | + GTime m_srcTime; //!< Photon time | |
| 206 | + }; | |
| 207 | + | |
| 120 | 208 | // Proteced members |
| 121 | 209 | std::vector<GModelPar*> m_pars; //!< Parameter pointers |
| 122 | 210 | }; | ... | ... |
pyext/GModelSpatial.i
src/model/GModelSpatial.cpp
| ... | ... | @@ -307,6 +307,57 @@ void GModelSpatial::autoscale(void) |
| 307 | 307 | return; |
| 308 | 308 | } |
| 309 | 309 | |
| 310 | +/***********************************************************************//** | |
| 311 | + * @brief Returns model flux integrated in circular sky region | |
| 312 | + * | |
| 313 | + * @param[in] reg Sky region. | |
| 314 | + * @param[in] srcEng Energy. | |
| 315 | + * @param[in] srcTime Time. | |
| 316 | + * @return flux (adimensional or or ph/cm2/s). | |
| 317 | + * | |
| 318 | + * Computes | |
| 319 | + * | |
| 320 | + * \f[ | |
| 321 | + * \int_{\rho_{\rm min}}^{\rho_{\rm max}} \sin \rho \times | |
| 322 | + * \int_{\omega} M(\rho, \omega | E, t) d\omega d\rho | |
| 323 | + * \f] | |
| 324 | + * | |
| 325 | + * where | |
| 326 | + * \f$M(\rho, \omega | E, t)\f$ is the spatial model, | |
| 327 | + * \f$\rho\f$ is the distance from the region centre, and | |
| 328 | + * \f$\omega\f$ is the position angle with respect to the connecting line | |
| 329 | + * between the region centre and the direction on the sky. | |
| 330 | + ***************************************************************************/ | |
| 331 | +double GModelSpatial::flux(const GSkyRegionCircle& reg, | |
| 332 | + const GEnergy& srcEng, | |
| 333 | + const GTime& srcTime) const | |
| 334 | +{ | |
| 335 | + // Set number of iterations for Romberg integration. | |
| 336 | + // Need to test!!!! | |
| 337 | + static const int iter_rho = 5; | |
| 338 | + | |
| 339 | + // Initialise flux | |
| 340 | + double flux = 0.0; | |
| 341 | + | |
| 342 | + // Define radial integration boundaries from 0 to ROI radius (in radians) | |
| 343 | + double rho_min = 0.; | |
| 344 | + double rho_max = reg.radius() * gammalib::deg2rad; | |
| 345 | + | |
| 346 | + // Setup integration kernel | |
| 347 | + GModelSpatial::circle_int_kern_rho integrand(this, | |
| 348 | + reg, | |
| 349 | + srcEng, | |
| 350 | + srcTime); | |
| 351 | + GIntegral integral(&integrand); | |
| 352 | + | |
| 353 | + // Perform integration | |
| 354 | + flux = integral.romberg(rho_min, rho_max); | |
| 355 | + | |
| 356 | + // Return | |
| 357 | + return flux; | |
| 358 | + | |
| 359 | +} | |
| 360 | + | |
| 310 | 361 | |
| 311 | 362 | /*========================================================================== |
| 312 | 363 | = = |
| ... | ... | @@ -350,3 +401,102 @@ void GModelSpatial::free_members(void) |
| 350 | 401 | // Return |
| 351 | 402 | return; |
| 352 | 403 | } |
| 404 | + | |
| 405 | +/***********************************************************************//** | |
| 406 | + * @brief Kernel for circular sky region radial integration | |
| 407 | + * | |
| 408 | + * @param[in] rho Radial distance from region centre (radians). | |
| 409 | + * @return Integration kernel defined as | |
| 410 | + * | |
| 411 | + * \f[ | |
| 412 | + * \int_{\rho_{\rm min}}^{\rho_{\rm max}} K(\rho | E, t) d\rho | |
| 413 | + * \f] | |
| 414 | + * | |
| 415 | + * of a spatial model over a circular region. The eval() method computes | |
| 416 | + * | |
| 417 | + * \f[ | |
| 418 | + * K(\rho | E, t) = \sin \rho \times | |
| 419 | + * \int_{\omega} M(\rho, \omega | E, t) d\omega | |
| 420 | + * \f] | |
| 421 | + * | |
| 422 | + * where | |
| 423 | + * \f$M(\rho, \omega | E, t)\f$ is the spatial model, | |
| 424 | + * \f$\rho\f$ is the distance from the region centre, and | |
| 425 | + * \f$\omega\f$ is the position angle with respect to the connecting line | |
| 426 | + * between the region centre and the direction on the sky. | |
| 427 | + ***************************************************************************/ | |
| 428 | +double GModelSpatial::circle_int_kern_rho::eval(const double& rho) | |
| 429 | +{ | |
| 430 | + // Initialise model value | |
| 431 | + double flux = 0.0; | |
| 432 | + | |
| 433 | + // Continue only if rho is positive | |
| 434 | + if (rho > 0.0) { | |
| 435 | + | |
| 436 | + // Integrate over entire circular region | |
| 437 | + // omega between 0 and 2pi | |
| 438 | + double omega_min = 0.; | |
| 439 | + double omega_max = 2 * gammalib::pi; | |
| 440 | + | |
| 441 | + // Setup integration kernel for azimuth integration | |
| 442 | + GModelSpatial::circle_int_kern_omega integrand(m_model, | |
| 443 | + m_reg, | |
| 444 | + rho, | |
| 445 | + m_srcEng, | |
| 446 | + m_srcTime); | |
| 447 | + | |
| 448 | + // Setup integrator | |
| 449 | + GIntegral integral(&integrand); | |
| 450 | + | |
| 451 | + // Compute sine term for radial integration | |
| 452 | + double sin_rho = std::sin(rho); | |
| 453 | + | |
| 454 | + // Integrate over omega | |
| 455 | + flux = integral.romberg(omega_min, omega_max) * sin_rho; | |
| 456 | + | |
| 457 | + } // endif: rho was positive | |
| 458 | + | |
| 459 | + | |
| 460 | + // Return | |
| 461 | + return flux; | |
| 462 | +} | |
| 463 | + | |
| 464 | +/***********************************************************************//** | |
| 465 | + * @brief Kernel for circular sky region azimuth angle integration | |
| 466 | + * | |
| 467 | + * @param[in] omega Azimuth angle (radians). | |
| 468 | +* Computes | |
| 469 | + * | |
| 470 | + * \f[ | |
| 471 | + * K(\omega | \rho, E, t) = M(\omega | \rho) | |
| 472 | + * \f] | |
| 473 | + * | |
| 474 | + * where | |
| 475 | + * \fM(\omega | \rho)\f$ is the spatial model, | |
| 476 | + * \f$\rho\f$ is the distance from the region centre, and | |
| 477 | + * \f$\omega\f$ is the position angle with respect to the connecting line | |
| 478 | + * between the region centre and the direction on the sky. | |
| 479 | + ***************************************************************************/ | |
| 480 | +double GModelSpatial::circle_int_kern_omega::eval(const double& omega) | |
| 481 | +{ | |
| 482 | + // Initialise model value | |
| 483 | + double flux = 0.0; | |
| 484 | + | |
| 485 | + // Precompute rho and omega in degrees | |
| 486 | + double omega_deg = omega * gammalib::rad2deg; | |
| 487 | + double rho_deg = m_rho * gammalib::rad2deg; | |
| 488 | + | |
| 489 | + // Compute sky direction corresponding to given rho, omega | |
| 490 | + // Deep copy of region centre | |
| 491 | + GSkyDir dir = GSkyDir(m_reg.centre()); | |
| 492 | + // Rotate to otain requested sky direction | |
| 493 | + dir.rotate_deg(omega_deg,rho_deg); | |
| 494 | + | |
| 495 | + // Evaluate model for this sky direction | |
| 496 | + GPhoton photon = GPhoton(dir,m_srcEng,m_srcTime); | |
| 497 | + flux = m_model->eval(photon); | |
| 498 | + | |
| 499 | + // Return | |
| 500 | + return flux; | |
| 501 | + | |
| 502 | +} | ... | ... |