Commit bc051b101bfaaa066644f382692f4765837a849f
1 parent
62f78c5d
Accelerate IRF and RING background methods in ctskymap (#2309)
Showing
4 changed files
with
46 additions
and
65 deletions
ChangeLog
NEWS
| 1 | 1 | New Features and Important Changes in ctools 1.6.0 |
| 2 | 2 | |
| 3 | -8 February 2018 | |
| 3 | +10 February 2018 | |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | Introduction |
| ... | ... | @@ -106,7 +106,7 @@ None |
| 106 | 106 | |
| 107 | 107 | ctskymap - CTA sky mapping |
| 108 | 108 | -------------------------- |
| 109 | -None | |
| 109 | +Accelerate the IRF and RING background methods (#2309). | |
| 110 | 110 | |
| 111 | 111 | |
| 112 | 112 | cttsmap - Generation of Test Statistic map | ... | ... |
doc/source/admin/release_history/1.6.rst
src/ctskymap/ctskymap.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * ctskymap - Sky mapping tool * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2011-2017 by Juergen Knoedlseder * | |
| 4 | + * copyright (C) 2011-2018 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -30,7 +30,6 @@ |
| 30 | 30 | #endif |
| 31 | 31 | #include <cstdio> |
| 32 | 32 | #include "ctskymap.hpp" |
| 33 | -#include "GSkyRegions.hpp" | |
| 34 | 33 | |
| 35 | 34 | /* __ Method name definitions ____________________________________________ */ |
| 36 | 35 | #define G_GET_PARAMETERS "ctskymap::get_parameter()" |
| ... | ... | @@ -694,15 +693,14 @@ void ctskymap::map_background_irf(GCTAObservation* obs) |
| 694 | 693 | throw GException::invalid_value(G_MAP_BACKGROUND_IRF, msg); |
| 695 | 694 | } |
| 696 | 695 | |
| 697 | - // Compute natural logarithm of energy range in MeV | |
| 698 | - double lnEmin = std::log(m_emin * 1.0e6); | |
| 699 | - double lnEmax = std::log(m_emax * 1.0e6); | |
| 696 | + // Set minimum and maximum energy as GEnergy instances | |
| 697 | + GEnergy emin(m_emin, "TeV"); | |
| 698 | + GEnergy emax(m_emax, "TeV"); | |
| 700 | 699 | |
| 701 | 700 | // Extract region of interest from observation |
| 702 | 701 | GCTARoi roi = obs->roi(); |
| 703 | 702 | |
| 704 | 703 | // Initialise statistics |
| 705 | - int calls = 0; | |
| 706 | 704 | double total = 0.0; |
| 707 | 705 | |
| 708 | 706 | // Loop over all background map pixels |
| ... | ... | @@ -720,20 +718,9 @@ void ctskymap::map_background_irf(GCTAObservation* obs) |
| 720 | 718 | continue; |
| 721 | 719 | } |
| 722 | 720 | |
| 723 | - // Setup integration function | |
| 724 | - ctskymap::irf_kern integrand(bkg, &instdir); | |
| 725 | - GIntegral integral(&integrand); | |
| 721 | + // Compute background value | |
| 722 | + double value = bkg->rate_ebin(instdir, emin, emax); | |
| 726 | 723 | |
| 727 | - // Set precision (has been carefully adjusted using a test simulation | |
| 728 | - // over the energy range 20 GeV - 120 TeV) | |
| 729 | - integral.eps(1.0e-6); | |
| 730 | - | |
| 731 | - // Do Romberg integration | |
| 732 | - double value = integral.romberg(lnEmin, lnEmax); | |
| 733 | - | |
| 734 | - // Update number of background function calls | |
| 735 | - calls += integral.calls(); | |
| 736 | - | |
| 737 | 724 | // Multiply background rate with livetime and solid angle |
| 738 | 725 | value *= obs->livetime() * m_solidangle[i]; |
| 739 | 726 | |
| ... | ... | @@ -747,7 +734,6 @@ void ctskymap::map_background_irf(GCTAObservation* obs) |
| 747 | 734 | |
| 748 | 735 | // Log background subtraction results |
| 749 | 736 | log_value(NORMAL, "Events in background", int(total+0.5)); |
| 750 | - log_value(NORMAL, "Background evaluations", calls); | |
| 751 | 737 | |
| 752 | 738 | // Return |
| 753 | 739 | return; |
| ... | ... | @@ -794,15 +780,14 @@ void ctskymap::map_background_ring(GCTAObservation* obs) |
| 794 | 780 | throw GException::invalid_value(G_MAP_BACKGROUND_RING, msg); |
| 795 | 781 | } |
| 796 | 782 | |
| 797 | - // Compute natural logarithm of energy range in MeV | |
| 798 | - double lnEmin = std::log(m_emin * 1.0e6); | |
| 799 | - double lnEmax = std::log(m_emax * 1.0e6); | |
| 783 | + // Set minimum and maximum energy as GEnergy instances | |
| 784 | + GEnergy emin(m_emin, "TeV"); | |
| 785 | + GEnergy emax(m_emax, "TeV"); | |
| 800 | 786 | |
| 801 | 787 | // Extract region of interest from observation |
| 802 | 788 | GCTARoi roi = obs->roi(); |
| 803 | 789 | |
| 804 | - // Initialise statistics | |
| 805 | - int calls = 0; | |
| 790 | + // Extract exposure | |
| 806 | 791 | double exposure = obs->livetime(); |
| 807 | 792 | |
| 808 | 793 | // Loop over all map pixels |
| ... | ... | @@ -820,30 +805,15 @@ void ctskymap::map_background_ring(GCTAObservation* obs) |
| 820 | 805 | continue; |
| 821 | 806 | } |
| 822 | 807 | |
| 823 | - // Setup integration function | |
| 824 | - ctskymap::irf_kern integrand(bkg, &instdir); | |
| 825 | - GIntegral integral(&integrand); | |
| 826 | - | |
| 827 | - // Set precision | |
| 828 | - integral.eps(1.0e-6); | |
| 829 | - | |
| 830 | - // Do Romberg integration to get the sensitivity (note: this assumes | |
| 831 | - // the background IRF is a good approximation for the radial | |
| 832 | - // sensitivity) | |
| 833 | - m_alphamap(i,0) += integral.romberg(lnEmin, lnEmax) * | |
| 808 | + // Compute background value | |
| 809 | + m_alphamap(i,0) += bkg->rate_ebin(instdir, emin, emax) * | |
| 834 | 810 | m_solidangle[i] * exposure; |
| 835 | 811 | |
| 836 | 812 | // Store the counts in this bin |
| 837 | 813 | m_onmap(i,0) += m_skymap(i,0); |
| 838 | 814 | |
| 839 | - // Update number of background function calls | |
| 840 | - calls += integral.calls(); | |
| 841 | - | |
| 842 | 815 | } // endfor: Loop for caching bkg IRF sensitivity |
| 843 | 816 | |
| 844 | - // Log background subtraction results | |
| 845 | - log_value(NORMAL, "Alpha map evaluations", calls); | |
| 846 | - | |
| 847 | 817 | // Zero out the counts map to prepare it for the next observation |
| 848 | 818 | m_skymap = 0.0; |
| 849 | 819 | |
| ... | ... | @@ -995,10 +965,14 @@ void ctskymap::compute_ring_values(const GSkyMap& counts, |
| 995 | 965 | double alpha_on = 0.0; |
| 996 | 966 | double alpha_off = 0.0; |
| 997 | 967 | |
| 998 | - // Define the regions necessary to do the pixel checks | |
| 999 | - GSkyRegionCircle roi_reg(position, m_roiradius); | |
| 1000 | - GSkyRegionCircle inner_reg(position, m_inradius); | |
| 1001 | - GSkyRegionCircle outer_reg(position, m_outradius); | |
| 968 | + // Compute cosine of radii. We use the cosine of the radius here to | |
| 969 | + // mimimize as much as possible the trigonometric computations. Note that | |
| 970 | + // the cosine of an angle is maximal for an angle of zero. This explains | |
| 971 | + // later why we chose ">=" to test whether an angle is smaller than a | |
| 972 | + // given radius. | |
| 973 | + double cos_roiradius = std::cos(m_roiradius * gammalib::deg2rad); | |
| 974 | + double cos_inradius = std::cos(m_inradius * gammalib::deg2rad); | |
| 975 | + double cos_outradius = std::cos(m_outradius * gammalib::deg2rad); | |
| 1002 | 976 | |
| 1003 | 977 | // Loop over every pixel in the observation to compute Non, Noff |
| 1004 | 978 | for (int j = 0; j < counts.npix(); ++j) { |
| ... | ... | @@ -1006,28 +980,32 @@ void ctskymap::compute_ring_values(const GSkyMap& counts, |
| 1006 | 980 | // Get the index and sky direction of this pixel |
| 1007 | 981 | GSkyDir& skydir = m_dirs[j]; |
| 1008 | 982 | |
| 1009 | - // Check if pixel is inside the background region | |
| 1010 | - if ((m_exclmap(j,0) == 0.0) && outer_reg.contains(skydir) && | |
| 1011 | - !inner_reg.contains(skydir)) { | |
| 983 | + // Only consider pixels within the outer radius of the background region | |
| 984 | + if (position.cos_dist(skydir) >= cos_outradius) { | |
| 1012 | 985 | |
| 1013 | - // Update n_off | |
| 1014 | - noff += counts(j,0); | |
| 986 | + // Check if pixel is inside the background region | |
| 987 | + if ((m_exclmap(j,0) == 0.0) && position.cos_dist(skydir) < cos_inradius) { | |
| 1015 | 988 | |
| 1016 | - // Update alpha_off | |
| 1017 | - alpha_off += sensitivity(j,0); | |
| 989 | + // Update n_off | |
| 990 | + noff += counts(j,0); | |
| 1018 | 991 | |
| 1019 | - } | |
| 992 | + // Update alpha_off | |
| 993 | + alpha_off += sensitivity(j,0); | |
| 994 | + | |
| 995 | + } | |
| 996 | + | |
| 997 | + // ... otherwise check if pixel is inside source region | |
| 998 | + else if (position.cos_dist(skydir) >= cos_roiradius) { | |
| 1020 | 999 | |
| 1021 | - // ... otherwise check if pixel is inside source region | |
| 1022 | - else if (roi_reg.contains(skydir)) { | |
| 1000 | + // Update n_on for significance computation | |
| 1001 | + non += counts(j,0); | |
| 1023 | 1002 | |
| 1024 | - // Update n_on for significance computation | |
| 1025 | - non += counts(j,0); | |
| 1003 | + // Update alpha_on | |
| 1004 | + alpha_on += sensitivity(j,0); | |
| 1026 | 1005 | |
| 1027 | - // Update alpha_on | |
| 1028 | - alpha_on += sensitivity(j,0); | |
| 1006 | + } // endif: source and background region check | |
| 1029 | 1007 | |
| 1030 | - } // endif: source and background region check | |
| 1008 | + } // endif: pixel is within outer radius of background region | |
| 1031 | 1009 | |
| 1032 | 1010 | } // endfor: looped over pixels |
| 1033 | 1011 | ... | ... |