Commit 9dc8a8dd5a2df5ff6033c4fb799611d258f20095
1 parent
964b56a9
Multiply map values with solid angle in GResponse::irf_diffuse()
Showing
1 changed file
with
96 additions
and
28 deletions
src/obs/GResponse.cpp
| ... | ... | @@ -693,12 +693,13 @@ double GResponse::irf_elliptical(const GEvent& event, |
| 693 | 693 | * source and observation. The method computes |
| 694 | 694 | * |
| 695 | 695 | * \f[ |
| 696 | - * {\tt irf}(p', E', t') = \sum_p M_{\rm S}(p | E, t) \, | |
| 696 | + * {\tt irf}(p', E', t') = \sum_p M_{\rm S}(p | E, t) \, \Delta(p) | |
| 697 | 697 | * R(p', E', t' | p, E, t) |
| 698 | 698 | * \f] |
| 699 | 699 | * |
| 700 | 700 | * where |
| 701 | 701 | * * \f$M_{\rm S}(p | E, t)\f$ is the diffuse model component, |
| 702 | + * * \f$\Delta(p)\f$ is the solid angle of the map pixel | |
| 702 | 703 | * * \f$R(p', E', t' | p, E, t)\f$ is the Instrument Response Function (IRF), |
| 703 | 704 | * * \f$p'\f$ is the measured instrument direction, |
| 704 | 705 | * * \f$E'\f$ is the measured or reconstructed energy, |
| ... | ... | @@ -720,56 +721,123 @@ double GResponse::irf_diffuse(const GEvent& event, |
| 720 | 721 | // Initialise IRF |
| 721 | 722 | double irf = 0.0; |
| 722 | 723 | |
| 724 | + // Get source attributes | |
| 725 | + const GEnergy& srcEng = source.energy(); | |
| 726 | + const GTime& srcTime = source.time(); | |
| 727 | + | |
| 723 | 728 | // Initialise map |
| 724 | - GSkyMap skymap; | |
| 729 | + //GSkyMap skymap; | |
| 725 | 730 | |
| 726 | 731 | // If model is a diffuse map model then extract sky map |
| 727 | 732 | const GModelSpatialDiffuseMap* map = |
| 728 | 733 | dynamic_cast<const GModelSpatialDiffuseMap*>(source.model()); |
| 729 | 734 | if (map != NULL) { |
| 730 | - skymap = map->map(); | |
| 731 | - } | |
| 735 | + | |
| 736 | + // Get reference to sky map | |
| 737 | + const GSkyMap& skymap = map->map(); | |
| 738 | + | |
| 739 | + // Loop over all sky map pixels | |
| 740 | + for (int i = 0; i < skymap.npix(); ++i) { | |
| 741 | + | |
| 742 | + // Get map value | |
| 743 | + double value = skymap(i); | |
| 744 | + | |
| 745 | + // Go to next pixel if map value is not positive | |
| 746 | + if (value <= 0.0) { | |
| 747 | + continue; | |
| 748 | + } | |
| 749 | + | |
| 750 | + // Get sky direction | |
| 751 | + GSkyDir srcDir = skymap.inx2dir(i); | |
| 752 | + | |
| 753 | + // Setup photon | |
| 754 | + GPhoton photon(srcDir, srcEng, srcTime); | |
| 755 | + | |
| 756 | + // Add IRF multiplied by flux in map pixel. Since the map value | |
| 757 | + // is per steradian we have to multiply with the solid angle of | |
| 758 | + // the map pixel | |
| 759 | + irf += this->irf(event, photon, obs) * value * skymap.solidangle(i); | |
| 760 | + | |
| 761 | + } // endfor: looped over all sky map pixels | |
| 762 | + | |
| 763 | + } // endif: model was diffuse map | |
| 732 | 764 | |
| 733 | 765 | // ... otherwise if model is a cube map model then extract sky map |
| 734 | 766 | else { |
| 735 | 767 | const GModelSpatialDiffuseCube* cube = |
| 736 | 768 | dynamic_cast<const GModelSpatialDiffuseCube*>(source.model()); |
| 737 | 769 | if (cube != NULL) { |
| 738 | - skymap = cube->cube(); | |
| 739 | - } | |
| 770 | + | |
| 771 | + // Get reference to sky cube | |
| 772 | + const GSkyMap& skymap = cube->cube(); | |
| 773 | + | |
| 774 | + // Loop over all sky map pixels | |
| 775 | + for (int i = 0; i < skymap.npix(); ++i) { | |
| 776 | + | |
| 777 | + // Get sky direction | |
| 778 | + GSkyDir srcDir = skymap.inx2dir(i); | |
| 779 | + | |
| 780 | + // Setup photon | |
| 781 | + GPhoton photon(srcDir, srcEng, srcTime); | |
| 782 | + | |
| 783 | + // Get map value | |
| 784 | + double value = cube->eval(photon); | |
| 785 | + | |
| 786 | + // Go to next pixel if map value is not positive | |
| 787 | + if (value <= 0.0) { | |
| 788 | + continue; | |
| 789 | + } | |
| 790 | + | |
| 791 | + // Add IRF multiplied by flux in map pixel. Since the map | |
| 792 | + // value is per steradian we have to multiply with the solid | |
| 793 | + // angle of the map pixel | |
| 794 | + irf += this->irf(event, photon, obs) * value * skymap.solidangle(i); | |
| 795 | + | |
| 796 | + } // endfor: looped over all sky map pixels | |
| 797 | + | |
| 798 | + } // endelse: model was diffuse cube | |
| 740 | 799 | |
| 741 | 800 | // ... otherwise allocate all sky map with specified resolution |
| 742 | 801 | else { |
| 743 | - int nx = int(360.0/m_irf_diffuse_resolution + 0.5); | |
| 744 | - int ny = int(180.0/m_irf_diffuse_resolution + 0.5); | |
| 745 | - double dx = 360.0 / double(nx); | |
| 746 | - double dy = 180.0 / double(ny); | |
| 747 | - skymap = GSkyMap("CAR", "CEL", 0.0, 0.0, -dx, dy, nx, ny); | |
| 748 | - } | |
| 749 | 802 | |
| 750 | - } // endelse: model was not a diffuse map | |
| 803 | + // Allocate sky map | |
| 804 | + int nx = int(360.0/m_irf_diffuse_resolution + 0.5); | |
| 805 | + int ny = int(180.0/m_irf_diffuse_resolution + 0.5); | |
| 806 | + double dx = 360.0 / double(nx); | |
| 807 | + double dy = 180.0 / double(ny); | |
| 808 | + GSkyMap skymap = GSkyMap("CAR", "CEL", 0.0, 0.0, -dx, dy, nx, ny); | |
| 751 | 809 | |
| 752 | - // Get pointer to diffuse model | |
| 753 | - const GModelSpatialDiffuse* model = | |
| 754 | - static_cast<const GModelSpatialDiffuse*>(source.model()); | |
| 810 | + // Get pointer to diffuse model | |
| 811 | + const GModelSpatialDiffuse* model = | |
| 812 | + static_cast<const GModelSpatialDiffuse*>(source.model()); | |
| 755 | 813 | |
| 756 | - // Get source attributes | |
| 757 | - const GEnergy& srcEng = source.energy(); | |
| 758 | - const GTime& srcTime = source.time(); | |
| 814 | + // Loop over all sky map pixels | |
| 815 | + for (int i = 0; i < skymap.npix(); ++i) { | |
| 759 | 816 | |
| 760 | - // Loop over all sky map pixels | |
| 761 | - for (int i = 0; i < skymap.npix(); ++i) { | |
| 817 | + // Get sky direction | |
| 818 | + GSkyDir srcDir = skymap.inx2dir(i); | |
| 762 | 819 | |
| 763 | - // Get sky direction | |
| 764 | - GSkyDir srcDir = skymap.inx2dir(i); | |
| 820 | + // Setup photon | |
| 821 | + GPhoton photon(srcDir, srcEng, srcTime); | |
| 765 | 822 | |
| 766 | - // Setup photon | |
| 767 | - GPhoton photon(srcDir, srcEng, srcTime); | |
| 823 | + // Get model value | |
| 824 | + double value = model->eval(photon); | |
| 768 | 825 | |
| 769 | - // Add IRF for photon | |
| 770 | - irf += this->irf(event, photon, obs) * model->eval(photon); | |
| 826 | + // Go to next pixel if map value is not positive | |
| 827 | + if (value <= 0.0) { | |
| 828 | + continue; | |
| 829 | + } | |
| 771 | 830 | |
| 772 | - } | |
| 831 | + // Add IRF multiplied by flux in map pixel. Since the map | |
| 832 | + // value is per steradian we have to multiply with the solid | |
| 833 | + // angle of the map pixel | |
| 834 | + irf += this->irf(event, photon, obs) * value * skymap.solidangle(i); | |
| 835 | + | |
| 836 | + } // endfor: looped over sky map pixels | |
| 837 | + | |
| 838 | + } // endelse: model was not a cube | |
| 839 | + | |
| 840 | + } // endelse: model was not a map | |
| 773 | 841 | |
| 774 | 842 | // Return IRF value |
| 775 | 843 | return irf; | ... | ... |