Commit bc051b101bfaaa066644f382692f4765837a849f

Authored by Jürgen Knödlseder
1 parent 62f78c5d

Accelerate IRF and RING background methods in ctskymap (#2309)

ChangeLog
1 -2018-02-08 1 +2018-02-10
2 2
3 * Version 1.6.0 released 3 * Version 1.6.0 released
4 ======================== 4 ========================
5 5
  6 + Accelerate IRF and RING background methods in ctskymap (#2309)
  7 +
6 8
7 * Bug fix version 1.5.1 released 9 * Bug fix version 1.5.1 released
8 ================================ 10 ================================
1 New Features and Important Changes in ctools 1.6.0 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 Introduction 6 Introduction
@@ -106,7 +106,7 @@ None @@ -106,7 +106,7 @@ None
106 106
107 ctskymap - CTA sky mapping 107 ctskymap - CTA sky mapping
108 -------------------------- 108 --------------------------
109 -None 109 +Accelerate the IRF and RING background methods (#2309).
110 110
111 111
112 cttsmap - Generation of Test Statistic map 112 cttsmap - Generation of Test Statistic map
doc/source/admin/release_history/1.6.rst
@@ -22,7 +22,8 @@ Bug fixes @@ -22,7 +22,8 @@ Bug fixes
22 Improvements 22 Improvements
23 ------------ 23 ------------
24 24
25 -* ... 25 +* [`2309 <https://cta-redmine.irap.omp.eu/issues/2309>`_] -
  26 + Accelerate `IRF` and `RING` background methods in :ref:`ctskymap`
26 27
27 28
28 New features 29 New features
src/ctskymap/ctskymap.cpp
1 /*************************************************************************** 1 /***************************************************************************
2 * ctskymap - Sky mapping tool * 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 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -30,7 +30,6 @@ @@ -30,7 +30,6 @@
30 #endif 30 #endif
31 #include <cstdio> 31 #include <cstdio>
32 #include "ctskymap.hpp" 32 #include "ctskymap.hpp"
33 -#include "GSkyRegions.hpp"  
34 33
35 /* __ Method name definitions ____________________________________________ */ 34 /* __ Method name definitions ____________________________________________ */
36 #define G_GET_PARAMETERS "ctskymap::get_parameter()" 35 #define G_GET_PARAMETERS "ctskymap::get_parameter()"
@@ -694,15 +693,14 @@ void ctskymap::map_background_irf(GCTAObservation* obs) @@ -694,15 +693,14 @@ void ctskymap::map_background_irf(GCTAObservation* obs)
694 throw GException::invalid_value(G_MAP_BACKGROUND_IRF, msg); 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 // Extract region of interest from observation 700 // Extract region of interest from observation
702 GCTARoi roi = obs->roi(); 701 GCTARoi roi = obs->roi();
703 702
704 // Initialise statistics 703 // Initialise statistics
705 - int calls = 0;  
706 double total = 0.0; 704 double total = 0.0;
707 705
708 // Loop over all background map pixels 706 // Loop over all background map pixels
@@ -720,20 +718,9 @@ void ctskymap::map_background_irf(GCTAObservation* obs) @@ -720,20 +718,9 @@ void ctskymap::map_background_irf(GCTAObservation* obs)
720 continue; 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 // Multiply background rate with livetime and solid angle 724 // Multiply background rate with livetime and solid angle
738 value *= obs->livetime() * m_solidangle[i]; 725 value *= obs->livetime() * m_solidangle[i];
739 726
@@ -747,7 +734,6 @@ void ctskymap::map_background_irf(GCTAObservation* obs) @@ -747,7 +734,6 @@ void ctskymap::map_background_irf(GCTAObservation* obs)
747 734
748 // Log background subtraction results 735 // Log background subtraction results
749 log_value(NORMAL, "Events in background", int(total+0.5)); 736 log_value(NORMAL, "Events in background", int(total+0.5));
750 - log_value(NORMAL, "Background evaluations", calls);  
751 737
752 // Return 738 // Return
753 return; 739 return;
@@ -794,15 +780,14 @@ void ctskymap::map_background_ring(GCTAObservation* obs) @@ -794,15 +780,14 @@ void ctskymap::map_background_ring(GCTAObservation* obs)
794 throw GException::invalid_value(G_MAP_BACKGROUND_RING, msg); 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 // Extract region of interest from observation 787 // Extract region of interest from observation
802 GCTARoi roi = obs->roi(); 788 GCTARoi roi = obs->roi();
803 789
804 - // Initialise statistics  
805 - int calls = 0; 790 + // Extract exposure
806 double exposure = obs->livetime(); 791 double exposure = obs->livetime();
807 792
808 // Loop over all map pixels 793 // Loop over all map pixels
@@ -820,30 +805,15 @@ void ctskymap::map_background_ring(GCTAObservation* obs) @@ -820,30 +805,15 @@ void ctskymap::map_background_ring(GCTAObservation* obs)
820 continue; 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 m_solidangle[i] * exposure; 810 m_solidangle[i] * exposure;
835 811
836 // Store the counts in this bin 812 // Store the counts in this bin
837 m_onmap(i,0) += m_skymap(i,0); 813 m_onmap(i,0) += m_skymap(i,0);
838 814
839 - // Update number of background function calls  
840 - calls += integral.calls();  
841 -  
842 } // endfor: Loop for caching bkg IRF sensitivity 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 // Zero out the counts map to prepare it for the next observation 817 // Zero out the counts map to prepare it for the next observation
848 m_skymap = 0.0; 818 m_skymap = 0.0;
849 819
@@ -995,10 +965,14 @@ void ctskymap::compute_ring_values(const GSkyMap&amp; counts, @@ -995,10 +965,14 @@ void ctskymap::compute_ring_values(const GSkyMap&amp; counts,
995 double alpha_on = 0.0; 965 double alpha_on = 0.0;
996 double alpha_off = 0.0; 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 // Loop over every pixel in the observation to compute Non, Noff 977 // Loop over every pixel in the observation to compute Non, Noff
1004 for (int j = 0; j < counts.npix(); ++j) { 978 for (int j = 0; j < counts.npix(); ++j) {
@@ -1006,28 +980,32 @@ void ctskymap::compute_ring_values(const GSkyMap&amp; counts, @@ -1006,28 +980,32 @@ void ctskymap::compute_ring_values(const GSkyMap&amp; counts,
1006 // Get the index and sky direction of this pixel 980 // Get the index and sky direction of this pixel
1007 GSkyDir& skydir = m_dirs[j]; 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 } // endfor: looped over pixels 1010 } // endfor: looped over pixels
1033 1011