Commit 804f12cecc6f19874a7d0087a23da2014c911839
1 parent
c5844a9a
Add energy margin in response cube computation
Showing
4 changed files
with
98 additions
and
76 deletions
inst/cta/src/GCTACubeBackground.cpp
| ... | ... | @@ -57,7 +57,6 @@ |
| 57 | 57 | //#define G_DEBUG_CACHE |
| 58 | 58 | |
| 59 | 59 | /* __ Constants __________________________________________________________ */ |
| 60 | -const GEnergy g_energy_margin(1.0e-12, "TeV"); | |
| 61 | 60 | |
| 62 | 61 | |
| 63 | 62 | /*========================================================================== |
| ... | ... | @@ -345,7 +344,8 @@ void GCTACubeBackground::fill(const GObservations& obs, GLog* log) |
| 345 | 344 | for (int i = 0; i < obs.size(); ++i) { |
| 346 | 345 | |
| 347 | 346 | // Get observation and continue only if it is a CTA observation |
| 348 | - const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(obs[i]); | |
| 347 | + const GCTAObservation* cta = | |
| 348 | + dynamic_cast<const GCTAObservation*>(obs[i]); | |
| 349 | 349 | |
| 350 | 350 | // Skip observation if it's not CTA |
| 351 | 351 | if (cta == NULL) { |
| ... | ... | @@ -726,7 +726,7 @@ void GCTACubeBackground::set_eng_axis(void) |
| 726 | 726 | |
| 727 | 727 | // Compute nodes |
| 728 | 728 | for (int i = 0; i < bins; ++i) { |
| 729 | - | |
| 729 | + | |
| 730 | 730 | // Get logE/TeV |
| 731 | 731 | m_elogmeans.append(m_energies[i].log10TeV()); |
| 732 | 732 | ... | ... |
inst/cta/src/GCTACubeEdisp.cpp
| ... | ... | @@ -57,7 +57,6 @@ |
| 57 | 57 | /* __ Debug definitions __________________________________________________ */ |
| 58 | 58 | |
| 59 | 59 | /* __ Constants __________________________________________________________ */ |
| 60 | -const GEnergy g_energy_margin(1.0e-12, "TeV"); | |
| 61 | 60 | |
| 62 | 61 | |
| 63 | 62 | /*========================================================================== |
| ... | ... | @@ -642,10 +641,10 @@ GEbounds GCTACubeEdisp::ebounds(const GEnergy& obsEng) const |
| 642 | 641 | throw GException::invalid_value(G_EBOUNDS, msg); |
| 643 | 642 | } |
| 644 | 643 | |
| 645 | - // If ebounds were not computed, before, compute them now | |
| 646 | - if (m_ebounds.empty()) { | |
| 647 | - compute_ebounds(); | |
| 648 | - } | |
| 644 | + // If ebounds were not computed, before, compute them now | |
| 645 | + if (m_ebounds.empty()) { | |
| 646 | + compute_ebounds(); | |
| 647 | + } | |
| 649 | 648 | |
| 650 | 649 | // Return the index of the energy boundaries that are just below the |
| 651 | 650 | // observed energy. As the energy dispersion decreases with increasing |
| ... | ... | @@ -751,7 +750,7 @@ void GCTACubeEdisp::init_members(void) |
| 751 | 750 | m_wgt3 = 0.0; |
| 752 | 751 | m_wgt4 = 0.0; |
| 753 | 752 | m_ebounds.clear(); |
| 754 | - | |
| 753 | + | |
| 755 | 754 | // Return |
| 756 | 755 | return; |
| 757 | 756 | } |
| ... | ... | @@ -833,6 +832,9 @@ void GCTACubeEdisp::fill_cube(const GCTAObservation& obs, |
| 833 | 832 | GSkyMap* exposure, |
| 834 | 833 | GLog* log) |
| 835 | 834 | { |
| 835 | + // Set energy margin | |
| 836 | + static const GEnergy margin(1.0, "MeV"); | |
| 837 | + | |
| 836 | 838 | // Only continue if we have an event list |
| 837 | 839 | if (obs.eventtype() == "EventList") { |
| 838 | 840 | |
| ... | ... | @@ -906,7 +908,7 @@ void GCTACubeEdisp::fill_cube(const GCTAObservation& obs, |
| 906 | 908 | if (roi.centre().dir().dist_deg(dir) > roi.radius()) { |
| 907 | 909 | continue; |
| 908 | 910 | } |
| 909 | - | |
| 911 | + | |
| 910 | 912 | // Compute theta angle with respect to pointing direction in |
| 911 | 913 | // radians |
| 912 | 914 | double theta = pnt.dist(dir); |
| ... | ... | @@ -920,7 +922,11 @@ void GCTACubeEdisp::fill_cube(const GCTAObservation& obs, |
| 920 | 922 | // energy boundaries are reconstructed energies, hence |
| 921 | 923 | // this is only an approximation, but probably the only |
| 922 | 924 | // we can really do. |
| 923 | - if (!obs_ebounds.contains(m_energies[iebin])) { | |
| 925 | + // We allow here for a small margin in case of rounding | |
| 926 | + // errors in the energy boundaries. | |
| 927 | + if (!(obs_ebounds.contains(m_energies[iebin]) || | |
| 928 | + obs_ebounds.contains(m_energies[iebin]-margin) || | |
| 929 | + obs_ebounds.contains(m_energies[iebin]+margin))) { | |
| 924 | 930 | continue; |
| 925 | 931 | } |
| 926 | 932 | |
| ... | ... | @@ -961,7 +967,7 @@ void GCTACubeEdisp::fill_cube(const GCTAObservation& obs, |
| 961 | 967 | logEsrc) * weight; |
| 962 | 968 | |
| 963 | 969 | } // endfor: looped over migration bins |
| 964 | - | |
| 970 | + | |
| 965 | 971 | } // endfor: looped over energy bins |
| 966 | 972 | |
| 967 | 973 | } // endfor: looped over all pixels |
| ... | ... | @@ -989,9 +995,9 @@ void GCTACubeEdisp::update(const double& migra, const double& logEsrc) const |
| 989 | 995 | { |
| 990 | 996 | // Set node array for energy interpolation |
| 991 | 997 | m_elogmeans.set_value(logEsrc); |
| 992 | - | |
| 998 | + | |
| 993 | 999 | // Set node array for delta interpolation |
| 994 | - m_migras.set_value(migra); | |
| 1000 | + m_migras.set_value(migra); | |
| 995 | 1001 | |
| 996 | 1002 | // Set indices for bi-linear interpolation |
| 997 | 1003 | m_inx1 = offset(m_migras.inx_left(), m_elogmeans.inx_left()); |
| ... | ... | @@ -1022,7 +1028,7 @@ void GCTACubeEdisp::set_eng_axis(void) |
| 1022 | 1028 | for (int i = 0; i < m_energies.size(); ++i) { |
| 1023 | 1029 | m_elogmeans.append(m_energies[i].log10TeV()); |
| 1024 | 1030 | } |
| 1025 | - | |
| 1031 | + | |
| 1026 | 1032 | // Return |
| 1027 | 1033 | return; |
| 1028 | 1034 | } |
| ... | ... | @@ -1039,29 +1045,29 @@ void GCTACubeEdisp::set_eng_axis(void) |
| 1039 | 1045 | ***************************************************************************/ |
| 1040 | 1046 | void GCTACubeEdisp::compute_ebounds() const |
| 1041 | 1047 | { |
| 1042 | - // Set epsilon | |
| 1043 | - const double eps = 1.0e-12; | |
| 1048 | + // Set epsilon | |
| 1049 | + const double eps = 1.0e-12; | |
| 1044 | 1050 | |
| 1045 | 1051 | // Clear energy boundary vector |
| 1046 | 1052 | m_ebounds.clear(); |
| 1047 | 1053 | |
| 1048 | 1054 | // Loop over all energies |
| 1049 | - for (int i = 0; i < m_energies.size(); i++) { | |
| 1055 | + for (int i = 0; i < m_energies.size(); i++) { | |
| 1050 | 1056 | |
| 1051 | - // Initialise results | |
| 1052 | - double migra_min = 0.0; | |
| 1053 | - double migra_max = 0.0; | |
| 1054 | - bool minFound = false; | |
| 1055 | - bool maxFound = false; | |
| 1057 | + // Initialise results | |
| 1058 | + double migra_min = 0.0; | |
| 1059 | + double migra_max = 0.0; | |
| 1060 | + bool minFound = false; | |
| 1061 | + bool maxFound = false; | |
| 1056 | 1062 | |
| 1057 | - // Compute map of sky ranges to be considered | |
| 1058 | - int mapmin = m_migras.size() * i; | |
| 1059 | - int mapmax = m_migras.size() * (i + 1); | |
| 1063 | + // Compute map of sky ranges to be considered | |
| 1064 | + int mapmin = m_migras.size() * i; | |
| 1065 | + int mapmax = m_migras.size() * (i + 1); | |
| 1060 | 1066 | |
| 1061 | - // Loop over sky map entries from lower migra | |
| 1062 | - for (int imap = mapmin; imap < mapmax; ++imap) { | |
| 1067 | + // Loop over sky map entries from lower migra | |
| 1068 | + for (int imap = mapmin; imap < mapmax; ++imap) { | |
| 1063 | 1069 | |
| 1064 | - // Get maximum energy dispersion term for all sky pixels | |
| 1070 | + // Get maximum energy dispersion term for all sky pixels | |
| 1065 | 1071 | double edisp = 0.0; |
| 1066 | 1072 | for (int pixel = 0; pixel < m_cube.npix(); ++pixel) { |
| 1067 | 1073 | double value = m_cube(pixel, imap); |
| ... | ... | @@ -1070,19 +1076,19 @@ void GCTACubeEdisp::compute_ebounds() const |
| 1070 | 1076 | } |
| 1071 | 1077 | } |
| 1072 | 1078 | |
| 1073 | - // Find first non-negligible energy dispersion term | |
| 1074 | - if (edisp >= eps) { | |
| 1075 | - minFound = true; | |
| 1076 | - migra_min = m_migras[imap - mapmin]; | |
| 1077 | - break; | |
| 1078 | - } | |
| 1079 | + // Find first non-negligible energy dispersion term | |
| 1080 | + if (edisp >= eps) { | |
| 1081 | + minFound = true; | |
| 1082 | + migra_min = m_migras[imap - mapmin]; | |
| 1083 | + break; | |
| 1084 | + } | |
| 1079 | 1085 | |
| 1080 | - } // endfor: loop over maps | |
| 1086 | + } // endfor: loop over maps | |
| 1081 | 1087 | |
| 1082 | - // Loop over sky map entries from high migra | |
| 1083 | - for (int imap = mapmax-1; imap >= mapmin; --imap) { | |
| 1088 | + // Loop over sky map entries from high migra | |
| 1089 | + for (int imap = mapmax-1; imap >= mapmin; --imap) { | |
| 1084 | 1090 | |
| 1085 | - // Get maximum energy dispersion term for all sky pixels | |
| 1091 | + // Get maximum energy dispersion term for all sky pixels | |
| 1086 | 1092 | double edisp = 0.0; |
| 1087 | 1093 | for (int pixel = 0; pixel < m_cube.npix(); ++pixel) { |
| 1088 | 1094 | double value = m_cube(pixel, imap); |
| ... | ... | @@ -1091,37 +1097,37 @@ void GCTACubeEdisp::compute_ebounds() const |
| 1091 | 1097 | } |
| 1092 | 1098 | } |
| 1093 | 1099 | |
| 1094 | - // Find first non-negligible energy dispersion term | |
| 1095 | - if (edisp >= eps) { | |
| 1096 | - maxFound = true; | |
| 1097 | - migra_max = m_migras[imap - mapmin]; | |
| 1098 | - break; | |
| 1099 | - } | |
| 1100 | + // Find first non-negligible energy dispersion term | |
| 1101 | + if (edisp >= eps) { | |
| 1102 | + maxFound = true; | |
| 1103 | + migra_max = m_migras[imap - mapmin]; | |
| 1104 | + break; | |
| 1105 | + } | |
| 1100 | 1106 | |
| 1101 | - } // endfor: loop over maps | |
| 1107 | + } // endfor: loop over maps | |
| 1102 | 1108 | |
| 1103 | - // Initialise energy boundaries | |
| 1104 | - GEnergy emin; | |
| 1105 | - GEnergy emax; | |
| 1109 | + // Initialise energy boundaries | |
| 1110 | + GEnergy emin; | |
| 1111 | + GEnergy emax; | |
| 1106 | 1112 | |
| 1107 | - // Compute energy boundaries if they were found and if they are | |
| 1113 | + // Compute energy boundaries if they were found and if they are | |
| 1108 | 1114 | // valid |
| 1109 | - if (minFound && maxFound && migra_min > 0.0 && migra_max > 0.0 && | |
| 1115 | + if (minFound && maxFound && migra_min > 0.0 && migra_max > 0.0 && | |
| 1110 | 1116 | migra_max > migra_min) { |
| 1111 | - emin = m_energies[i] * migra_min; | |
| 1112 | - emax = m_energies[i] * migra_max; | |
| 1113 | - } | |
| 1114 | - | |
| 1117 | + emin = m_energies[i] * migra_min; | |
| 1118 | + emax = m_energies[i] * migra_max; | |
| 1119 | + } | |
| 1120 | + | |
| 1115 | 1121 | // ... otherwise we set the interval to a zero interval for safety |
| 1116 | - else { | |
| 1117 | - emin.log10TeV(0.0); | |
| 1118 | - emax.log10TeV(0.0); | |
| 1119 | - } | |
| 1122 | + else { | |
| 1123 | + emin.log10TeV(0.0); | |
| 1124 | + emax.log10TeV(0.0); | |
| 1125 | + } | |
| 1120 | 1126 | |
| 1121 | - // Append energy boundaries | |
| 1122 | - m_ebounds.push_back(GEbounds(emin, emax)); | |
| 1127 | + // Append energy boundaries | |
| 1128 | + m_ebounds.push_back(GEbounds(emin, emax)); | |
| 1123 | 1129 | |
| 1124 | - } // endfor: looped over all energies | |
| 1130 | + } // endfor: looped over all energies | |
| 1125 | 1131 | |
| 1126 | 1132 | // Return |
| 1127 | 1133 | return; | ... | ... |
inst/cta/src/GCTACubeExposure.cpp
| ... | ... | @@ -238,7 +238,7 @@ GCTACubeExposure& GCTACubeExposure::operator=(const GCTACubeExposure& cube) |
| 238 | 238 | * @return Exposure (in units of cm2 s) |
| 239 | 239 | ***************************************************************************/ |
| 240 | 240 | double GCTACubeExposure::operator()(const GSkyDir& dir, const GEnergy& energy) const |
| 241 | -{ | |
| 241 | +{ | |
| 242 | 242 | // Set indices and weighting factors for interpolation |
| 243 | 243 | update(energy.log10TeV()); |
| 244 | 244 | |
| ... | ... | @@ -364,7 +364,7 @@ void GCTACubeExposure::fill(const GObservations& obs, GLog* log) |
| 364 | 364 | |
| 365 | 365 | // Fill exposure cube |
| 366 | 366 | fill_cube(*cta, log); |
| 367 | - | |
| 367 | + | |
| 368 | 368 | } // endfor: looped over observations |
| 369 | 369 | |
| 370 | 370 | // Return |
| ... | ... | @@ -566,7 +566,7 @@ void GCTACubeExposure::init_members(void) |
| 566 | 566 | m_inx_right = 0; |
| 567 | 567 | m_wgt_left = 0.0; |
| 568 | 568 | m_wgt_right = 0.0; |
| 569 | - | |
| 569 | + | |
| 570 | 570 | // Return |
| 571 | 571 | return; |
| 572 | 572 | } |
| ... | ... | @@ -621,6 +621,9 @@ void GCTACubeExposure::free_members(void) |
| 621 | 621 | ***************************************************************************/ |
| 622 | 622 | void GCTACubeExposure::fill_cube(const GCTAObservation& obs, GLog* log) |
| 623 | 623 | { |
| 624 | + // Set energy margin | |
| 625 | + static const GEnergy margin(1.0, "MeV"); | |
| 626 | + | |
| 624 | 627 | // Only continue if we have an event list |
| 625 | 628 | if (obs.eventtype() == "EventList") { |
| 626 | 629 | |
| ... | ... | @@ -683,7 +686,7 @@ void GCTACubeExposure::fill_cube(const GCTAObservation& obs, GLog* log) |
| 683 | 686 | if (roi.centre().dir().dist_deg(dir) > roi.radius()) { |
| 684 | 687 | continue; |
| 685 | 688 | } |
| 686 | - | |
| 689 | + | |
| 687 | 690 | // Compute theta angle with respect to pointing direction in |
| 688 | 691 | // radians |
| 689 | 692 | double theta = pnt.dist(dir); |
| ... | ... | @@ -696,7 +699,13 @@ void GCTACubeExposure::fill_cube(const GCTAObservation& obs, GLog* log) |
| 696 | 699 | // energies while the observation energy boundaries are |
| 697 | 700 | // reconstructed energies, hence this is only an |
| 698 | 701 | // approximation, but probably the only we can really do. |
| 699 | - if (!obs_ebounds.contains(m_energies[iebin])) { | |
| 702 | + // We allow here for a small margin in case of rounding | |
| 703 | + // errors in the energy boundaries. | |
| 704 | +//std::cout << obs_ebounds.emin() << " <= " << m_energies[iebin] << " <= " << obs_ebounds.emax() << std::endl; | |
| 705 | + if (!(obs_ebounds.contains(m_energies[iebin]) || | |
| 706 | + obs_ebounds.contains(m_energies[iebin]-margin) || | |
| 707 | + obs_ebounds.contains(m_energies[iebin]+margin))) { | |
| 708 | +//std::cout << "Skip" << std::endl; | |
| 700 | 709 | continue; |
| 701 | 710 | } |
| 702 | 711 | |
| ... | ... | @@ -766,7 +775,7 @@ void GCTACubeExposure::set_eng_axis(void) |
| 766 | 775 | |
| 767 | 776 | // Compute nodes |
| 768 | 777 | for (int i = 0; i < bins; ++i) { |
| 769 | - | |
| 778 | + | |
| 770 | 779 | // Get logE/TeV |
| 771 | 780 | m_elogmeans.append(m_energies[i].log10TeV()); |
| 772 | 781 | ... | ... |
inst/cta/src/GCTACubePsf.cpp
| ... | ... | @@ -267,7 +267,7 @@ GCTACubePsf::~GCTACubePsf(void) |
| 267 | 267 | * @param[in] cube Mean PSF cube. |
| 268 | 268 | * @return Mean PSF cube. |
| 269 | 269 | ***************************************************************************/ |
| 270 | -GCTACubePsf& GCTACubePsf::operator= (const GCTACubePsf& cube) | |
| 270 | +GCTACubePsf& GCTACubePsf::operator=(const GCTACubePsf& cube) | |
| 271 | 271 | { |
| 272 | 272 | // Execute only if object is not identical |
| 273 | 273 | if (this != &cube) { |
| ... | ... | @@ -669,7 +669,7 @@ void GCTACubePsf::init_members(void) |
| 669 | 669 | m_wgt2 = 0.0; |
| 670 | 670 | m_wgt3 = 0.0; |
| 671 | 671 | m_wgt4 = 0.0; |
| 672 | - | |
| 672 | + | |
| 673 | 673 | // Return |
| 674 | 674 | return; |
| 675 | 675 | } |
| ... | ... | @@ -752,6 +752,9 @@ void GCTACubePsf::fill_cube(const GCTAObservation& obs, |
| 752 | 752 | GSkyMap* exposure, |
| 753 | 753 | GLog* log) |
| 754 | 754 | { |
| 755 | + // Set energy margin | |
| 756 | + static const GEnergy margin(1.0, "MeV"); | |
| 757 | + | |
| 755 | 758 | // Only continue if we have an event list |
| 756 | 759 | if (obs.eventtype() == "EventList") { |
| 757 | 760 | |
| ... | ... | @@ -809,7 +812,7 @@ void GCTACubePsf::fill_cube(const GCTAObservation& obs, |
| 809 | 812 | |
| 810 | 813 | // Get pixel sky direction |
| 811 | 814 | GSkyDir dir = m_cube.inx2dir(pixel); |
| 812 | - | |
| 815 | + | |
| 813 | 816 | // Skip pixel if it is outside the RoI |
| 814 | 817 | if (roi.centre().dir().dist_deg(dir) > roi.radius()) { |
| 815 | 818 | continue; |
| ... | ... | @@ -827,7 +830,11 @@ void GCTACubePsf::fill_cube(const GCTAObservation& obs, |
| 827 | 830 | // energies while the observation energy boundaries are |
| 828 | 831 | // reconstructed energies, hence this is only an |
| 829 | 832 | // approximation, but probably the only we can really do. |
| 830 | - if (!obs_ebounds.contains(m_energies[iebin])) { | |
| 833 | + // We allow here for a small margin in case of rounding | |
| 834 | + // errors in the energy boundaries. | |
| 835 | + if (!(obs_ebounds.contains(m_energies[iebin]) || | |
| 836 | + obs_ebounds.contains(m_energies[iebin]-margin) || | |
| 837 | + obs_ebounds.contains(m_energies[iebin]+margin))) { | |
| 831 | 838 | continue; |
| 832 | 839 | } |
| 833 | 840 | |
| ... | ... | @@ -876,7 +883,7 @@ void GCTACubePsf::fill_cube(const GCTAObservation& obs, |
| 876 | 883 | * |
| 877 | 884 | * @param[in] delta Angular separation between true and measured photon |
| 878 | 885 | * directions (radians). |
| 879 | - * @param[in] logE Log10 true photon energy (TeV). | |
| 886 | + * @param[in] logE Log10 true photon energy (TeV). | |
| 880 | 887 | * |
| 881 | 888 | * This method updates the PSF parameter cache. |
| 882 | 889 | ***************************************************************************/ |
| ... | ... | @@ -892,7 +899,7 @@ void GCTACubePsf::update(const double& delta, const double& logE) const |
| 892 | 899 | |
| 893 | 900 | // Set node array for energy interpolation |
| 894 | 901 | m_elogmeans.set_value(logE); |
| 895 | - | |
| 902 | + | |
| 896 | 903 | // Set indices for bi-linear interpolation |
| 897 | 904 | m_inx1 = offset(m_deltas_cache.inx_left(), m_elogmeans.inx_left()); |
| 898 | 905 | m_inx2 = offset(m_deltas_cache.inx_left(), m_elogmeans.inx_right()); |
| ... | ... | @@ -986,7 +993,7 @@ void GCTACubePsf::set_eng_axis(void) |
| 986 | 993 | |
| 987 | 994 | // Compute nodes |
| 988 | 995 | for (int i = 0; i < bins; ++i) { |
| 989 | - | |
| 996 | + | |
| 990 | 997 | // Get logE/TeV |
| 991 | 998 | m_elogmeans.append(m_energies[i].log10TeV()); |
| 992 | 999 | |
| ... | ... | @@ -1016,7 +1023,7 @@ void GCTACubePsf::set_to_smooth(void) |
| 1016 | 1023 | m_cube(pixel, idst) = m_cube(pixel, isrc); |
| 1017 | 1024 | } |
| 1018 | 1025 | } |
| 1019 | - | |
| 1026 | + | |
| 1020 | 1027 | // Get index of last delta bin |
| 1021 | 1028 | int idelta = m_deltas.size()-1; |
| 1022 | 1029 | ... | ... |