Commit 5a80b6d4c8ff4c4e940a78d47f14306ac128ebc3
1 parent
b4150689
Fix precision issue with GCTABackground3D Monte-Carlo simulations (#2708)
Showing
4 changed files
with
55 additions
and
20 deletions
ChangeLog
| 1 | -2018-10-31 | |
| 1 | +2018-11-01 | |
| 2 | 2 | |
| 3 | 3 | * Version 1.6.0 released |
| 4 | 4 | ======================== |
| 5 | 5 | |
| 6 | + Fix precision issue with GCTABackground3D Monte-Carlo simulations (#2708) | |
| 6 | 7 | Revise GCTAEdisp class interface (#2704) |
| 7 | 8 | GCTAEdisp returns now energy dispersion values per MeV (#2704) |
| 8 | 9 | Protect GCTAInstDir from access to invalid information (#2694) | ... | ... |
NEWS
| 1 | 1 | New Features and Important Changes in GammaLib 1.6.0 |
| 2 | 2 | |
| 3 | -31 October 2018 | |
| 3 | +1 November 2018 | |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | 1. Introduction |
| ... | ... | @@ -306,6 +306,12 @@ None |
| 306 | 306 | |
| 307 | 307 | 20. CTA interface |
| 308 | 308 | ----------------- |
| 309 | +GCTABackground3D::init_mc_cache now pre-computes the Monte Carlo cache at energy | |
| 310 | +nodes of the background cube, and in addition, inserts 8 logarithmically spaced | |
| 311 | +nodes between each pair of nodes. This assures that the energy variations of the | |
| 312 | +background rate are precisely captured and reproduced in the Monte Carlo | |
| 313 | +simulations (#2708). | |
| 314 | + | |
| 309 | 315 | The GCTAEdisp::operator() now returns energy dispersion values per MeV. The |
| 310 | 316 | units are now consistent with the expectation in GResponse, and this changes |
| 311 | 317 | assurance the coherence between the various classes. In particular, no re- | ... | ... |
doc/source/admin/release_history/1.6.rst
| ... | ... | @@ -19,6 +19,8 @@ In particular, this release provides: |
| 19 | 19 | Bug fixes |
| 20 | 20 | --------- |
| 21 | 21 | |
| 22 | +* [`2708 <https://cta-redmine.irap.omp.eu/issues/2708>`_] - | |
| 23 | + Fix precision issue with ``GCTABackground3D`` Monte-Carlo simulations | |
| 22 | 24 | * [`2683 <https://cta-redmine.irap.omp.eu/issues/2683>`_] - |
| 23 | 25 | Correct handling of stacked On/Off observations without background IRF. |
| 24 | 26 | Fix bug that potentially wrote the wrong exposure time in a PHA file. | ... | ... |
inst/cta/src/GCTABackground3D.cpp
| ... | ... | @@ -912,6 +912,9 @@ int GCTABackground3D::index(const int& idetx, |
| 912 | 912 | ***************************************************************************/ |
| 913 | 913 | void GCTABackground3D::init_mc_cache(void) const |
| 914 | 914 | { |
| 915 | + // Set number of subbins per energy bin of response cube | |
| 916 | + const int nsubbins = 10; | |
| 917 | + | |
| 915 | 918 | // Initialise cache |
| 916 | 919 | m_mc_max.clear(); |
| 917 | 920 | m_mc_spectrum.clear(); |
| ... | ... | @@ -936,23 +939,50 @@ void GCTABackground3D::init_mc_cache(void) const |
| 936 | 939 | } |
| 937 | 940 | m_mc_one_minus_costheta = 1.0 - std::cos(theta); |
| 938 | 941 | |
| 939 | - // Set number of energy bins. Make sure that we compute at least 100 energy | |
| 940 | - // bins | |
| 941 | - int nbins = m_num_energy * 10; | |
| 942 | - if (nbins < 100) { | |
| 943 | - nbins = 100; | |
| 944 | - } | |
| 945 | - | |
| 946 | - // Compute DETX and DETY binsize in radians and energy binsize in log10(TeV) | |
| 942 | + // Compute DETX and DETY binsize in radians | |
| 947 | 943 | double detx_bin = (m_detx_max - m_detx_min) / m_num_detx; |
| 948 | 944 | double dety_bin = (m_dety_max - m_dety_min) / m_num_dety; |
| 949 | - double logE_bin = (m_logE_max - m_logE_min) / (nbins-1); | |
| 945 | + | |
| 946 | + // Set energy bins for Monte Carlo cache spectrum. Make sure that the | |
| 947 | + // actual energy nodes are part of the energy bins to avoid that sharp | |
| 948 | + // structures in the background rate variations are missed. | |
| 949 | + GEnergies energies; | |
| 950 | + for (int i = 0; i < m_num_energy; ++i) { | |
| 951 | + | |
| 952 | + // If this is the first node then add energies below the first node | |
| 953 | + // down to the lower energy limit of the background response | |
| 954 | + if (i == 0) { | |
| 955 | + GEnergy emin(m_background.axis_lo(m_inx_energy, i), | |
| 956 | + m_background.axis_lo_unit(m_inx_energy)); | |
| 957 | + GEnergies enodes(nsubbins/2, emin, m_energy[i]); | |
| 958 | + enodes.remove(enodes.size()-1); // avoids duplication of energy | |
| 959 | + energies.extend(enodes); | |
| 960 | + } | |
| 961 | + | |
| 962 | + // If this is not the last node then append nodes between current | |
| 963 | + // node and next node | |
| 964 | + if (i < m_num_energy-1) { | |
| 965 | + GEnergies enodes(nsubbins, m_energy[i], m_energy[i+1]); | |
| 966 | + enodes.remove(enodes.size()-1); // avoids duplication of energy | |
| 967 | + energies.extend(enodes); | |
| 968 | + } | |
| 969 | + | |
| 970 | + // ... otherwise this is the last node. Add energies above the last | |
| 971 | + // node up to the upper energy limit of the background response | |
| 972 | + else { | |
| 973 | + GEnergy emax(m_background.axis_hi(m_inx_energy, i), | |
| 974 | + m_background.axis_hi_unit(m_inx_energy)); | |
| 975 | + GEnergies enodes(nsubbins/2, m_energy[i], emax); | |
| 976 | + energies.extend(enodes); | |
| 977 | + } | |
| 978 | + | |
| 979 | + } // endfor: looped over energy bins of background response | |
| 950 | 980 | |
| 951 | 981 | // Loop over all energy bins |
| 952 | - for (int i = 0; i < nbins; ++i) { | |
| 982 | + for (int i = 0; i < energies.size(); ++i) { | |
| 953 | 983 | |
| 954 | 984 | // Get logE of energy bin |
| 955 | - double logE = m_logE_min + i * logE_bin; | |
| 985 | + double logE = energies[i].log10TeV(); | |
| 956 | 986 | |
| 957 | 987 | // Initialise cache with cumulative pixel fluxes and compute total flux |
| 958 | 988 | // in response table for normalization. Negative pixels are excluded |
| ... | ... | @@ -1007,18 +1037,14 @@ void GCTABackground3D::init_mc_cache(void) const |
| 1007 | 1037 | |
| 1008 | 1038 | } // endfor: loop over DETX |
| 1009 | 1039 | |
| 1010 | - // Set energy value (unit independent) | |
| 1011 | - GEnergy energy; | |
| 1012 | - energy.log10(logE, m_background.axis_lo_unit(m_inx_energy)); | |
| 1013 | - | |
| 1014 | - // Only append node if flux is positive | |
| 1040 | + // Append node if flux is positive | |
| 1015 | 1041 | if (total_flux > 0.0) { |
| 1016 | - m_mc_spectrum.append(energy, total_flux); | |
| 1042 | + m_mc_spectrum.append(energies[i], total_flux); | |
| 1017 | 1043 | } |
| 1018 | 1044 | |
| 1019 | 1045 | // Dump spectrum for debugging |
| 1020 | 1046 | #if defined(G_DEBUG_MC_INIT) |
| 1021 | - std::cout << "Energy=" << energy; | |
| 1047 | + std::cout << "Energy=" << energies[i]; | |
| 1022 | 1048 | std::cout << " Rate_total=" << total_flux; |
| 1023 | 1049 | std::cout << " events/s/MeV" << std::endl; |
| 1024 | 1050 | #endif | ... | ... |