Commit df53f488232c9d156bd6ba97e3e6e6e999ca6d0c
1 parent
fb713040
Correct computation of alpha in On/Off observations.
Showing
2 changed files
with
39 additions
and
41 deletions
inst/cta/src/GCTAOnOffObservation.cpp
| @@ -536,7 +536,9 @@ void GCTAOnOffObservation::write(GXmlElement& xml) const | @@ -536,7 +536,9 @@ void GCTAOnOffObservation::write(GXmlElement& xml) const | ||
| 536 | * @exception GException::invalid_value | 536 | * @exception GException::invalid_value |
| 537 | * No CTA event list found in CTA observation. | 537 | * No CTA event list found in CTA observation. |
| 538 | * | 538 | * |
| 539 | - * @todo Set the PHA spectra to zero before filling. | 539 | + * Fills events from an observation into the On and Off spectra and cumulates |
| 540 | + * their livetime. This method adds to any existing content in the On and | ||
| 541 | + * Off spectra. | ||
| 540 | ***************************************************************************/ | 542 | ***************************************************************************/ |
| 541 | void GCTAOnOffObservation::fill(const GCTAObservation& obs) | 543 | void GCTAOnOffObservation::fill(const GCTAObservation& obs) |
| 542 | { | 544 | { |
| @@ -1027,14 +1029,20 @@ void GCTAOnOffObservation::free_members(void) | @@ -1027,14 +1029,20 @@ void GCTAOnOffObservation::free_members(void) | ||
| 1027 | 1029 | ||
| 1028 | 1030 | ||
| 1029 | /***********************************************************************//** | 1031 | /***********************************************************************//** |
| 1030 | - * @brief Compute alpha parameter (ratio of On to Off effective areas) | 1032 | + * @brief Compute vector of alpha parameters |
| 1031 | * | 1033 | * |
| 1032 | * @param[in] obs CTA observation. | 1034 | * @param[in] obs CTA observation. |
| 1033 | * | 1035 | * |
| 1034 | * @exception GException::invalid_value | 1036 | * @exception GException::invalid_value |
| 1035 | * No CTA response found in CTA observation. | 1037 | * No CTA response found in CTA observation. |
| 1036 | * | 1038 | * |
| 1037 | - * @todo What about the livetime? What about the solid angle of the regions? | 1039 | + * Compute the alpha parameters for all energy bins. The alpha parameter |
| 1040 | + * gives the ratio between the On and Off region background acceptance | ||
| 1041 | + * multiplied by the ratio between On and Off region solid angles. | ||
| 1042 | + * | ||
| 1043 | + * @todo Implement for general sky regions, not only circles | ||
| 1044 | + * @todo Integrate over the sky region instead of taking the values at the | ||
| 1045 | + * sky region centre | ||
| 1038 | ***************************************************************************/ | 1046 | ***************************************************************************/ |
| 1039 | void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | 1047 | void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) |
| 1040 | { | 1048 | { |
| @@ -1044,7 +1052,7 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | @@ -1044,7 +1052,7 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | ||
| 1044 | // Continue only if there are spectral bins | 1052 | // Continue only if there are spectral bins |
| 1045 | int nreco = ereco.size(); | 1053 | int nreco = ereco.size(); |
| 1046 | if (nreco > 0) { | 1054 | if (nreco > 0) { |
| 1047 | - | 1055 | + |
| 1048 | // Initialise On/Off exposure ratios | 1056 | // Initialise On/Off exposure ratios |
| 1049 | m_alpha.assign(nreco, 0.0); | 1057 | m_alpha.assign(nreco, 0.0); |
| 1050 | 1058 | ||
| @@ -1061,8 +1069,6 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | @@ -1061,8 +1069,6 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | ||
| 1061 | // Get CTA observation pointing direction, zenith, and azimuth | 1069 | // Get CTA observation pointing direction, zenith, and azimuth |
| 1062 | GCTAPointing obspnt = obs.pointing(); | 1070 | GCTAPointing obspnt = obs.pointing(); |
| 1063 | GSkyDir obsdir = obspnt.dir(); | 1071 | GSkyDir obsdir = obspnt.dir(); |
| 1064 | - double zenith = obspnt.zenith(); | ||
| 1065 | - double azimuth = obspnt.azimuth(); | ||
| 1066 | 1072 | ||
| 1067 | // Loop over reconstructed energies | 1073 | // Loop over reconstructed energies |
| 1068 | for (int i = 0; i < nreco; ++i) { | 1074 | for (int i = 0; i < nreco; ++i) { |
| @@ -1071,8 +1077,8 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | @@ -1071,8 +1077,8 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | ||
| 1071 | double logEreco = ereco.elogmean(i).log10TeV(); | 1077 | double logEreco = ereco.elogmean(i).log10TeV(); |
| 1072 | 1078 | ||
| 1073 | // Initialise effective area totals | 1079 | // Initialise effective area totals |
| 1074 | - double aon = 0.0; | ||
| 1075 | - double aoff = 0.0; | 1080 | + double aon(0.0); |
| 1081 | + double aoff(0.0); | ||
| 1076 | 1082 | ||
| 1077 | // Loop over ON sky regions | 1083 | // Loop over ON sky regions |
| 1078 | for (int m = 0; m < m_on_regions.size(); ++m) { | 1084 | for (int m = 0; m < m_on_regions.size(); ++m) { |
| @@ -1085,18 +1091,14 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | @@ -1085,18 +1091,14 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | ||
| 1085 | // Get centre of circular region | 1091 | // Get centre of circular region |
| 1086 | GSkyDir centreg = skyreg->centre(); | 1092 | GSkyDir centreg = skyreg->centre(); |
| 1087 | 1093 | ||
| 1088 | - // Compute position of region centre in instrument | ||
| 1089 | - // coordinates (should be replaced by proper method to | ||
| 1090 | - // yield theta and phi) | ||
| 1091 | - double theta = obsdir.dist(centreg); | ||
| 1092 | - double phi = obsdir.posang(centreg); | ||
| 1093 | - | ||
| 1094 | - // Add up effective area | ||
| 1095 | - aon += response->aeff(theta, | ||
| 1096 | - phi, | ||
| 1097 | - zenith, | ||
| 1098 | - azimuth, | ||
| 1099 | - logEreco); | 1094 | + // Compute instrument direction from region centre |
| 1095 | + GCTAInstDir instdir(obspnt.instdir(centreg)); | ||
| 1096 | + | ||
| 1097 | + // Add up acceptance | ||
| 1098 | + aon += (*response->background())(logEreco, | ||
| 1099 | + instdir.detx(), | ||
| 1100 | + instdir.dety()) * | ||
| 1101 | + skyreg->solidangle(); | ||
| 1100 | 1102 | ||
| 1101 | } // endif: sky region is of type GSkyRegionCircle | 1103 | } // endif: sky region is of type GSkyRegionCircle |
| 1102 | 1104 | ||
| @@ -1113,18 +1115,14 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | @@ -1113,18 +1115,14 @@ void GCTAOnOffObservation::compute_alpha(const GCTAObservation& obs) | ||
| 1113 | // Get centre of circular region | 1115 | // Get centre of circular region |
| 1114 | GSkyDir centreg = skyreg->centre(); | 1116 | GSkyDir centreg = skyreg->centre(); |
| 1115 | 1117 | ||
| 1116 | - // Compute position of region centre in instrument | ||
| 1117 | - // coordinates (should be replaced by proper method to | ||
| 1118 | - // yield theta and phi) | ||
| 1119 | - double theta = obsdir.dist(centreg); | ||
| 1120 | - double phi = obsdir.posang(centreg); | ||
| 1121 | - | ||
| 1122 | - // Add up effective area | ||
| 1123 | - aoff += response->aeff(theta, | ||
| 1124 | - phi, | ||
| 1125 | - zenith, | ||
| 1126 | - azimuth, | ||
| 1127 | - logEreco); | 1118 | + // Compute instrument direction from region centre |
| 1119 | + GCTAInstDir instdir(obspnt.instdir(centreg)); | ||
| 1120 | + | ||
| 1121 | + // Add up acceptance | ||
| 1122 | + aoff += (*response->background())(logEreco, | ||
| 1123 | + instdir.detx(), | ||
| 1124 | + instdir.dety()) * | ||
| 1125 | + skyreg->solidangle(); | ||
| 1128 | 1126 | ||
| 1129 | } // endif: sky region is of type GSkyRegionCircle | 1127 | } // endif: sky region is of type GSkyRegionCircle |
| 1130 | 1128 |
inst/cta/test/test_CTA.py
| @@ -252,7 +252,7 @@ class Test(gammalib.GPythonTestSuite): | @@ -252,7 +252,7 @@ class Test(gammalib.GPythonTestSuite): | ||
| 252 | crab = gammalib.GSkyDir() | 252 | crab = gammalib.GSkyDir() |
| 253 | crab.radec_deg(83.6331, 22.0145) | 253 | crab.radec_deg(83.6331, 22.0145) |
| 254 | on = gammalib.GSkyRegions() | 254 | on = gammalib.GSkyRegions() |
| 255 | - on.append(gammalib.GSkyRegionCircle(crab, 0.5)) | 255 | + on.append(gammalib.GSkyRegionCircle(crab, 0.2)) |
| 256 | 256 | ||
| 257 | # Create Off region | 257 | # Create Off region |
| 258 | crab.radec_deg(83.6331, 23.5145) | 258 | crab.radec_deg(83.6331, 23.5145) |
| @@ -291,21 +291,21 @@ class Test(gammalib.GPythonTestSuite): | @@ -291,21 +291,21 @@ class Test(gammalib.GPythonTestSuite): | ||
| 291 | # Test On/Off model fitting results | 291 | # Test On/Off model fitting results |
| 292 | sky = outobs.models()['Crab'] | 292 | sky = outobs.models()['Crab'] |
| 293 | bgd = outobs.models()['Background'] | 293 | bgd = outobs.models()['Background'] |
| 294 | - self.test_value(sky['Prefactor'].value(), 6.15281e-16, 1.0e-20, | 294 | + self.test_value(sky['Prefactor'].value(), 5.95777e-16, 1.0e-20, |
| 295 | 'Check sky model prefactor value') | 295 | 'Check sky model prefactor value') |
| 296 | - self.test_value(sky['Prefactor'].error(), 2.35727e-17, 1.0e-20, | 296 | + self.test_value(sky['Prefactor'].error(), 2.02034e-17, 1.0e-20, |
| 297 | 'Check sky model prefactor error') | 297 | 'Check sky model prefactor error') |
| 298 | - self.test_value(sky['Index'].value(), -2.51599, 1.0e-4, | 298 | + self.test_value(sky['Index'].value(), -2.50932, 1.0e-4, |
| 299 | 'Check sky model index value') | 299 | 'Check sky model index value') |
| 300 | - self.test_value(sky['Index'].error(), 0.037628, 1.0e-4, | 300 | + self.test_value(sky['Index'].error(), 0.0304839, 1.0e-4, |
| 301 | 'Check sky model index error') | 301 | 'Check sky model index error') |
| 302 | - self.test_value(bgd['Prefactor'].value(), 1.04038, 1.0e-4, | 302 | + self.test_value(bgd['Prefactor'].value(), 1.09509, 1.0e-4, |
| 303 | 'Check background model prefactor value') | 303 | 'Check background model prefactor value') |
| 304 | - self.test_value(bgd['Prefactor'].error(), 0.130852, 1.0e-4, | 304 | + self.test_value(bgd['Prefactor'].error(), 0.140468, 1.0e-4, |
| 305 | 'Check background model prefactor error') | 305 | 'Check background model prefactor error') |
| 306 | - self.test_value(bgd['Index'].value(), 0.539376, 1.0e-4, | 306 | + self.test_value(bgd['Index'].value(), 0.54909, 1.0e-4, |
| 307 | 'Check background model index value') | 307 | 'Check background model index value') |
| 308 | - self.test_value(bgd['Index'].error(), 0.0855112, 1.0e-4, | 308 | + self.test_value(bgd['Index'].error(), 0.0872644, 1.0e-4, |
| 309 | 'Check background model index error') | 309 | 'Check background model index error') |
| 310 | 310 | ||
| 311 | # Save PHA, ARF and RMFs | 311 | # Save PHA, ARF and RMFs |