Commit 2ec38a7eec0664db97c5d22fe8028b345ff42e5d
1 parent
05fc86b0
Revise GCTAEdispRmf class (#2704)
Showing
6 changed files
with
235 additions
and
235 deletions
ChangeLog
NEWS
inst/cta/include/GCTAEdispRmf.hpp
| ... | ... | @@ -50,14 +50,12 @@ class GEbounds; |
| 50 | 50 | * The energy dispersion is defined as |
| 51 | 51 | * |
| 52 | 52 | * \f[ |
| 53 | - * E_{\rm disp}(E_{\rm true}, E_{\rm reco}) = | |
| 54 | - * \frac{E_{\rm disp}(E_{\rm true}, \log_{10} E_{\rm reco}, \theta)} | |
| 55 | - * {\log_{10} E_{\rm reco}} | |
| 53 | + * E_{\rm disp}(E_{\rm reco} | E_{\rm true}) | |
| 56 | 54 | * \f] |
| 57 | 55 | * |
| 58 | 56 | * in units of MeV\f$^{-1}\f$ where |
| 59 | - * \f$E_{\rm reco}\f$ is the reconstructed energy in units of MeV, and | |
| 60 | - * \f$E_{\rm true}\f$ is the true energy in units of MeV. | |
| 57 | + * \f$E_{\rm reco}\f$ is the reconstructed energy, and | |
| 58 | + * \f$E_{\rm true}\f$ is the true energy. | |
| 61 | 59 | ***************************************************************************/ |
| 62 | 60 | class GCTAEdispRmf : public GCTAEdisp { |
| 63 | 61 | |
| ... | ... | @@ -114,49 +112,41 @@ private: |
| 114 | 112 | void copy_members(const GCTAEdispRmf& psf); |
| 115 | 113 | void free_members(void); |
| 116 | 114 | void set_matrix(void); |
| 115 | + void set_max_edisp(void); | |
| 117 | 116 | void set_cache(void) const; |
| 118 | - void set_max_edisp(void) const; | |
| 119 | - void update(const double& logEsrc, const double& logEobs) const; | |
| 120 | - void compute_ebounds_obs(const double& theta = 0.0, | |
| 121 | - const double& phi = 0.0, | |
| 122 | - const double& zenith = 0.0, | |
| 123 | - const double& azimuth = 0.0) const; | |
| 124 | - void compute_ebounds_src(const double& theta = 0.0, | |
| 125 | - const double& phi = 0.0, | |
| 126 | - const double& zenith = 0.0, | |
| 127 | - const double& azimuth = 0.0) const; | |
| 117 | + void update(const GEnergy& ereco, const GEnergy& etrue) const; | |
| 118 | + void compute_ereco_bounds(void) const; | |
| 119 | + void compute_etrue_bounds(void) const; | |
| 128 | 120 | |
| 129 | 121 | // Members |
| 130 | 122 | GFilename m_filename; //!< Name of response file |
| 131 | 123 | GRmf m_rmf; //!< Redistribution matrix file |
| 132 | 124 | GMatrixSparse m_matrix; //!< Normalised redistribution matrix |
| 125 | + double m_max_edisp; //!< Maximum energy dispersion value for MC | |
| 133 | 126 | |
| 134 | 127 | // Interpolation cache |
| 135 | - mutable GNodeArray m_etrue; //!< Array of log10(Etrue) | |
| 136 | - mutable GNodeArray m_emeasured; //!< Array of log10(Emeasured) | |
| 137 | - mutable double m_last_etrue; //!< Last log10(Etrue) | |
| 138 | - mutable double m_last_emeasured; //!< Last log10(Emeasured) | |
| 139 | - mutable int m_itrue1; //!< Index of left Etrue | |
| 140 | - mutable int m_itrue2; //!< Index of right Etrue | |
| 141 | - mutable int m_imeas1; //!< Index of left Emeasured | |
| 142 | - mutable int m_imeas2; //!< Index of right Emeasured | |
| 143 | - mutable double m_wgt1; //!< Weight of lower left node | |
| 144 | - mutable double m_wgt2; //!< Weight of upper left node | |
| 145 | - mutable double m_wgt3; //!< Weight of lower right node | |
| 146 | - mutable double m_wgt4; //!< Weight of upper right node | |
| 147 | - | |
| 148 | - // Monte Carlo cache | |
| 149 | - mutable double m_max_edisp; | |
| 150 | - mutable double m_last_theta_obs; | |
| 151 | - mutable double m_last_theta_src; | |
| 152 | - mutable GEnergy m_last_etrue_ereco_bounds; | |
| 153 | - mutable GEnergy m_last_ereco_etrue_bounds; | |
| 154 | - mutable int m_index_obs; | |
| 155 | - mutable int m_index_src; | |
| 156 | - mutable bool m_ebounds_obs_computed; | |
| 157 | - mutable bool m_ebounds_src_computed; | |
| 158 | - mutable std::vector<GEbounds> m_ebounds_obs; | |
| 159 | - mutable std::vector<GEbounds> m_ebounds_src; | |
| 128 | + mutable GNodeArray m_etrue; //!< Array of log10(Etrue) | |
| 129 | + mutable GNodeArray m_ereco; //!< Array of log10(Ereco) | |
| 130 | + mutable GEnergy m_last_etrue; //!< Last true energy | |
| 131 | + mutable GEnergy m_last_ereco; //!< Last reconstructed energy | |
| 132 | + mutable int m_itrue1; //!< Index of left Etrue | |
| 133 | + mutable int m_itrue2; //!< Index of right Etrue | |
| 134 | + mutable int m_ireco1; //!< Index of left Ereco | |
| 135 | + mutable int m_ireco2; //!< Index of right Ereco | |
| 136 | + mutable double m_wgt1; //!< Weight of lower left node | |
| 137 | + mutable double m_wgt2; //!< Weight of upper left node | |
| 138 | + mutable double m_wgt3; //!< Weight of lower right node | |
| 139 | + mutable double m_wgt4; //!< Weight of upper right node | |
| 140 | + | |
| 141 | + // Computation cache | |
| 142 | + mutable bool m_ereco_bounds_computed; | |
| 143 | + mutable bool m_etrue_bounds_computed; | |
| 144 | + mutable GEnergy m_last_etrue_bounds; | |
| 145 | + mutable GEnergy m_last_ereco_bounds; | |
| 146 | + mutable int m_index_ereco; | |
| 147 | + mutable int m_index_etrue; | |
| 148 | + mutable std::vector<GEbounds> m_ereco_bounds; | |
| 149 | + mutable std::vector<GEbounds> m_etrue_bounds; | |
| 160 | 150 | }; |
| 161 | 151 | |
| 162 | 152 | ... | ... |
inst/cta/src/GCTAEdisp2D.cpp
| ... | ... | @@ -46,7 +46,7 @@ |
| 46 | 46 | |
| 47 | 47 | /* __ Method name definitions ____________________________________________ */ |
| 48 | 48 | #define G_READ "GCTAEdisp2D::read(GFitsTable&)" |
| 49 | -#define G_MC "GCTAEdisp2D::mc(GRan&, double&, double&, double&, double&, "\ | |
| 49 | +#define G_MC "GCTAEdisp2D::mc(GRan&, GEnergy&, double&, double&, double&, "\ | |
| 50 | 50 | "double&)" |
| 51 | 51 | #define G_FETCH "GCTAEdisp2D::fetch()" |
| 52 | 52 | |
| ... | ... | @@ -220,7 +220,7 @@ double GCTAEdisp2D::operator()(const GEnergy& ereco, |
| 220 | 220 | if ((logEsrc >= m_logEsrc_min) && (logEsrc <= m_logEsrc_max) && |
| 221 | 221 | (theta >= m_theta_min) && (theta <= m_theta_max)) { |
| 222 | 222 | |
| 223 | - // Compute migration (migra=Ereco/Etrue | |
| 223 | + // Compute migration (migra=Ereco/Etrue) | |
| 224 | 224 | double migra = ereco.MeV() / etrue.MeV(); |
| 225 | 225 | |
| 226 | 226 | // Continue only if migration is in validity range |
| ... | ... | @@ -470,13 +470,13 @@ void GCTAEdisp2D::save(const GFilename& filename, const bool& clobber) const |
| 470 | 470 | * @param[in] phi Azimuth angle in camera system (radians). Not used. |
| 471 | 471 | * @param[in] zenith Zenith angle in Earth system (radians). Not used. |
| 472 | 472 | * @param[in] azimuth Azimuth angle in Earth system (radians). Not used. |
| 473 | - * @return Observed energy. | |
| 473 | + * @return Reconstructed energy. | |
| 474 | 474 | * |
| 475 | 475 | * @exception GException::invalid_return_value |
| 476 | 476 | * No energy dispersion information found for parameters or |
| 477 | - * energy dispersion matrix is invalid. | |
| 477 | + * energy dispersion matrix is empty. | |
| 478 | 478 | * |
| 479 | - * Draws observed energy value given a true energy @p etrue and offset | |
| 479 | + * Draws reconstructed energy value given a true energy @p etrue and offset | |
| 480 | 480 | * angle @p theta. If no energy dispersion information is available the |
| 481 | 481 | * method will return the true photon energy. |
| 482 | 482 | ***************************************************************************/ | ... | ... |
inst/cta/src/GCTAEdispRmf.cpp
| ... | ... | @@ -43,10 +43,13 @@ |
| 43 | 43 | |
| 44 | 44 | /* __ Method name definitions ____________________________________________ */ |
| 45 | 45 | #define G_LOAD "GCTAEdispRmf::load(GFilename&)" |
| 46 | +#define G_MC "GCTAEdispRmf::mc(GRan&, GEnergy&, double&, double&, double&, "\ | |
| 47 | + "double&)" | |
| 46 | 48 | |
| 47 | 49 | /* __ Macros _____________________________________________________________ */ |
| 48 | 50 | |
| 49 | 51 | /* __ Coding definitions _________________________________________________ */ |
| 52 | +//#define G_LINEAR_ERECO_INTERPOLATION //!< Linear interpolation for Ereco | |
| 50 | 53 | |
| 51 | 54 | /* __ Debug definitions __________________________________________________ */ |
| 52 | 55 | |
| ... | ... | @@ -173,14 +176,12 @@ GCTAEdispRmf& GCTAEdispRmf::operator=(const GCTAEdispRmf& edisp) |
| 173 | 176 | * Returns the energy dispersion |
| 174 | 177 | * |
| 175 | 178 | * \f[ |
| 176 | - * E_{\rm disp}(E_{\rm true}, E_{\rm reco}) = | |
| 177 | - * \frac{E_{\rm disp}(E_{\rm true}, \log_{10} E_{\rm reco}, \theta)} | |
| 178 | - * {\log_{10} E_{\rm reco}} | |
| 179 | + * E_{\rm disp}(E_{\rm reco} | E_{\rm true}) | |
| 179 | 180 | * \f] |
| 180 | 181 | * |
| 181 | 182 | * in units of MeV\f$^{-1}\f$ where |
| 182 | - * \f$E_{\rm reco}\f$ is the reconstructed energy in units of MeV, and | |
| 183 | - * \f$E_{\rm true}\f$ is the true energy in units of MeV. | |
| 183 | + * \f$E_{\rm reco}\f$ is the reconstructed energy, and | |
| 184 | + * \f$E_{\rm true}\f$ is the true energy. | |
| 184 | 185 | ***************************************************************************/ |
| 185 | 186 | double GCTAEdispRmf::operator()(const GEnergy& ereco, |
| 186 | 187 | const GEnergy& etrue, |
| ... | ... | @@ -189,29 +190,20 @@ double GCTAEdispRmf::operator()(const GEnergy& ereco, |
| 189 | 190 | const double& zenith, |
| 190 | 191 | const double& azimuth) const |
| 191 | 192 | { |
| 192 | - // Get log10 of true and reconstructed photon energies | |
| 193 | - double logEsrc = etrue.log10TeV(); | |
| 194 | - double logEobs = ereco.log10TeV(); | |
| 195 | - | |
| 196 | 193 | // Update indexes and weighting factors for interpolation |
| 197 | - update(logEobs, logEsrc); | |
| 194 | + update(ereco, etrue); | |
| 198 | 195 | |
| 199 | 196 | // Perform interpolation |
| 200 | - double edisp = m_wgt1 * m_matrix(m_itrue1, m_imeas1) + | |
| 201 | - m_wgt2 * m_matrix(m_itrue1, m_imeas2) + | |
| 202 | - m_wgt3 * m_matrix(m_itrue2, m_imeas1) + | |
| 203 | - m_wgt4 * m_matrix(m_itrue2, m_imeas2); | |
| 197 | + double edisp = m_wgt1 * m_matrix(m_itrue1, m_ireco1) + | |
| 198 | + m_wgt2 * m_matrix(m_itrue1, m_ireco2) + | |
| 199 | + m_wgt3 * m_matrix(m_itrue2, m_ireco1) + | |
| 200 | + m_wgt4 * m_matrix(m_itrue2, m_ireco2); | |
| 204 | 201 | |
| 205 | 202 | // Make sure that energy dispersion is not negative |
| 206 | 203 | if (edisp < 0.0) { |
| 207 | 204 | edisp = 0.0; |
| 208 | 205 | } |
| 209 | 206 | |
| 210 | - // If the energy dispersion is positive, return it per MeV | |
| 211 | - else { | |
| 212 | - edisp /= (gammalib::ln10 * ereco.MeV()); | |
| 213 | - } | |
| 214 | - | |
| 215 | 207 | // Return energy dispersion |
| 216 | 208 | return edisp; |
| 217 | 209 | } |
| ... | ... | @@ -292,9 +284,14 @@ void GCTAEdispRmf::load(const GFilename& filename) |
| 292 | 284 | * @param[in] phi Azimuth angle in camera system (radians). Not used. |
| 293 | 285 | * @param[in] zenith Zenith angle in Earth system (radians). Not used. |
| 294 | 286 | * @param[in] azimuth Azimuth angle in Earth system (radians). Not used. |
| 295 | - * @return Energy. | |
| 287 | + * @return Reconstructed energy. | |
| 296 | 288 | * |
| 297 | - * Draws observed energy value from RMF matrix. | |
| 289 | + * @exception GException::invalid_return_value | |
| 290 | + * Energy dispersion matrix is empty. | |
| 291 | + * | |
| 292 | + * Draws reconstructed energy value from RMF matrix given a true energy | |
| 293 | + * @p etrue. If no energy dispersion information is available the method | |
| 294 | + * will return the true photon energy. | |
| 298 | 295 | ***************************************************************************/ |
| 299 | 296 | GEnergy GCTAEdispRmf::mc(GRan& ran, |
| 300 | 297 | const GEnergy& etrue, |
| ... | ... | @@ -303,25 +300,33 @@ GEnergy GCTAEdispRmf::mc(GRan& ran, |
| 303 | 300 | const double& zenith, |
| 304 | 301 | const double& azimuth) const |
| 305 | 302 | { |
| 306 | - // Initialise energies | |
| 307 | - GEnergy ereco; | |
| 303 | + // Initialise reconstructed event energy with true photon energy | |
| 304 | + GEnergy ereco = etrue; | |
| 308 | 305 | |
| 309 | - // Get boundaries for rejection method | |
| 306 | + // Get boundaries for reconstructed energy | |
| 310 | 307 | GEbounds ebounds = ereco_bounds(etrue, theta, phi, zenith, azimuth); |
| 311 | - double emin = ebounds.emin().log10TeV(); | |
| 312 | - double emax = ebounds.emax().log10TeV(); | |
| 308 | + double emin = ebounds.emin().TeV(); | |
| 309 | + double emax = ebounds.emax().TeV(); | |
| 310 | + | |
| 311 | + // Get maximum energy dispersion value (including some margin) | |
| 312 | + double max_edisp = 1.5 * m_max_edisp; | |
| 313 | + | |
| 314 | + // Throw an exception if maximum energy dispersion is zero | |
| 315 | + if (max_edisp <= 0.0) { | |
| 316 | + std::string msg = "Energy dispersion matrix is empty. Please provide " | |
| 317 | + "a valid energy dispersion matrix."; | |
| 318 | + throw GException::invalid_return_value(G_MC, msg); | |
| 319 | + } | |
| 313 | 320 | |
| 314 | 321 | // Find energy by rejection method |
| 315 | 322 | double ewidth = emax - emin; |
| 316 | - double logEobs = 0.5*(emin+emax); | |
| 317 | - if (m_max_edisp > 0.0) { | |
| 323 | + if (max_edisp > 0.0) { | |
| 318 | 324 | double f = 0.0; |
| 319 | 325 | double ftest = 1.0; |
| 320 | 326 | while (ftest > f) { |
| 321 | - logEobs = emin + ewidth * ran.uniform(); | |
| 322 | - ereco.log10TeV(logEobs); | |
| 323 | - f = operator()(ereco, etrue, theta, phi, zenith, azimuth); | |
| 324 | - ftest = ran.uniform() * m_max_edisp; | |
| 327 | + ereco.TeV(emin + ewidth * ran.uniform()); | |
| 328 | + f = operator()(ereco, etrue, theta, phi, zenith, azimuth); | |
| 329 | + ftest = ran.uniform() * max_edisp; | |
| 325 | 330 | } |
| 326 | 331 | } |
| 327 | 332 | |
| ... | ... | @@ -350,30 +355,29 @@ GEbounds GCTAEdispRmf::ereco_bounds(const GEnergy& etrue, |
| 350 | 355 | const double& azimuth) const |
| 351 | 356 | { |
| 352 | 357 | // Compute only if parameters changed |
| 353 | - if (!m_ebounds_obs_computed || theta != m_last_theta_obs) { | |
| 358 | + if (!m_ereco_bounds_computed) { | |
| 354 | 359 | |
| 355 | 360 | // Store last theta value |
| 356 | - m_ebounds_obs_computed = true; | |
| 357 | - m_last_theta_obs = theta; | |
| 358 | - m_last_etrue_ereco_bounds.log10TeV(-30.0); // force update | |
| 361 | + m_ereco_bounds_computed = true; | |
| 362 | + m_last_etrue_bounds.TeV(0.0); // force update | |
| 359 | 363 | |
| 360 | - // Compute ebounds_obs | |
| 361 | - compute_ebounds_obs(theta, phi, zenith, azimuth); | |
| 364 | + // Compute m_ereco_bounds | |
| 365 | + compute_ereco_bounds(); | |
| 362 | 366 | |
| 363 | 367 | } |
| 364 | 368 | |
| 365 | 369 | // Search index only if logEsrc has changed |
| 366 | - if (etrue != m_last_etrue_ereco_bounds) { | |
| 370 | + if (etrue != m_last_etrue_bounds) { | |
| 367 | 371 | |
| 368 | 372 | // Store last photon energy |
| 369 | - m_last_etrue_ereco_bounds = etrue; | |
| 373 | + m_last_etrue_bounds = etrue; | |
| 370 | 374 | |
| 371 | 375 | // Get true photon energy in TeV |
| 372 | 376 | double etrue_TeV = etrue.TeV(); |
| 373 | 377 | |
| 374 | 378 | // Find right index with bisection |
| 375 | 379 | int low = 0; |
| 376 | - int high = m_ebounds_obs.size() - 1; | |
| 380 | + int high = m_ereco_bounds.size() - 1; | |
| 377 | 381 | while ((high-low) > 1) { |
| 378 | 382 | int mid = (low+high) / 2; |
| 379 | 383 | double e = m_rmf.etrue().emin(mid).TeV(); |
| ... | ... | @@ -386,12 +390,12 @@ GEbounds GCTAEdispRmf::ereco_bounds(const GEnergy& etrue, |
| 386 | 390 | } |
| 387 | 391 | |
| 388 | 392 | // Index found |
| 389 | - m_index_obs = low; | |
| 393 | + m_index_ereco = low; | |
| 390 | 394 | |
| 391 | 395 | } |
| 392 | 396 | |
| 393 | 397 | // Return energy boundaries |
| 394 | - return (m_ebounds_obs[m_index_obs]); | |
| 398 | + return (m_ereco_bounds[m_index_ereco]); | |
| 395 | 399 | } |
| 396 | 400 | |
| 397 | 401 | |
| ... | ... | @@ -415,30 +419,29 @@ GEbounds GCTAEdispRmf::etrue_bounds(const GEnergy& ereco, |
| 415 | 419 | const double& azimuth) const |
| 416 | 420 | { |
| 417 | 421 | // Compute only if parameters changed |
| 418 | - if (!m_ebounds_src_computed || theta != m_last_theta_src) { | |
| 422 | + if (!m_etrue_bounds_computed) { | |
| 419 | 423 | |
| 420 | - // Store last value | |
| 421 | - m_ebounds_src_computed = true; | |
| 422 | - m_last_theta_src = theta; | |
| 423 | - m_last_ereco_etrue_bounds.log10TeV(-30.0); // force update | |
| 424 | + // Set computation flag | |
| 425 | + m_etrue_bounds_computed = true; | |
| 426 | + m_last_ereco_bounds.TeV(0.0); // force update | |
| 424 | 427 | |
| 425 | - // Compute ebounds_obs | |
| 426 | - compute_ebounds_src(theta, phi, zenith, azimuth); | |
| 428 | + // Compute m_etrue_bounds | |
| 429 | + compute_etrue_bounds(); | |
| 427 | 430 | |
| 428 | 431 | } |
| 429 | 432 | |
| 430 | 433 | // Search index only if ereco has changed |
| 431 | - if (ereco != m_last_ereco_etrue_bounds) { | |
| 434 | + if (ereco != m_last_ereco_bounds) { | |
| 432 | 435 | |
| 433 | 436 | // Store last value |
| 434 | - m_last_ereco_etrue_bounds = ereco; | |
| 437 | + m_last_ereco_bounds = ereco; | |
| 435 | 438 | |
| 436 | 439 | // Get reconstructed energy in TeV |
| 437 | 440 | double ereco_TeV = ereco.TeV(); |
| 438 | 441 | |
| 439 | 442 | // Find right index with bisection |
| 440 | 443 | int low = 0; |
| 441 | - int high = m_ebounds_src.size() - 1; | |
| 444 | + int high = m_etrue_bounds.size() - 1; | |
| 442 | 445 | while ((high-low) > 1) { |
| 443 | 446 | int mid = (low+high) / 2; |
| 444 | 447 | double e = m_rmf.emeasured().emin(mid).TeV(); |
| ... | ... | @@ -451,12 +454,12 @@ GEbounds GCTAEdispRmf::etrue_bounds(const GEnergy& ereco, |
| 451 | 454 | } |
| 452 | 455 | |
| 453 | 456 | // Index found |
| 454 | - m_index_src = low; | |
| 457 | + m_index_etrue = low; | |
| 455 | 458 | |
| 456 | 459 | } |
| 457 | 460 | |
| 458 | 461 | // Return energy boundaries |
| 459 | - return (m_ebounds_src[m_index_src]); | |
| 462 | + return (m_etrue_bounds[m_index_etrue]); | |
| 460 | 463 | } |
| 461 | 464 | |
| 462 | 465 | |
| ... | ... | @@ -474,7 +477,7 @@ GEbounds GCTAEdispRmf::etrue_bounds(const GEnergy& ereco, |
| 474 | 477 | * |
| 475 | 478 | * \f[ |
| 476 | 479 | * \int_{E_{\rm reco}^{\rm min}}^{E_{\rm reco}^{\rm max}} |
| 477 | - * E_{\rm disp}(E_{\rm true}, E_{\rm reco}) \, dE_{\rm reco} | |
| 480 | + * E_{\rm disp}(E_{\rm reco} | E_{\rm true}) \, dE_{\rm reco} | |
| 478 | 481 | * \f] |
| 479 | 482 | * |
| 480 | 483 | * where |
| ... | ... | @@ -491,8 +494,13 @@ double GCTAEdispRmf::prob_erecobin(const GEnergy& ereco_min, |
| 491 | 494 | |
| 492 | 495 | // Get log10 of energies |
| 493 | 496 | double logEsrc = etrue.log10TeV(); |
| 497 | + #if defined(G_LINEAR_ERECO_INTERPOLATION) | |
| 498 | + double logEobs_min = ereco_min.TeV(); | |
| 499 | + double logEobs_max = ereco_max.TeV(); | |
| 500 | + #else | |
| 494 | 501 | double logEobs_min = ereco_min.log10TeV(); |
| 495 | 502 | double logEobs_max = ereco_max.log10TeV(); |
| 503 | + #endif | |
| 496 | 504 | |
| 497 | 505 | // Set logEsrc for node array interpolation |
| 498 | 506 | m_etrue.set_value(logEsrc); |
| ... | ... | @@ -510,23 +518,27 @@ double GCTAEdispRmf::prob_erecobin(const GEnergy& ereco_min, |
| 510 | 518 | double f2 = 0.0; |
| 511 | 519 | |
| 512 | 520 | // Loop over all measured energy nodes |
| 513 | - for (int i = 0; i < m_emeasured.size(); ++i) { | |
| 521 | + for (int i = 0; i < m_ereco.size(); ++i) { | |
| 514 | 522 | |
| 515 | 523 | // If measured energy is below logEobs_min then skip node |
| 516 | - if (m_emeasured[i] <= logEobs_min) { | |
| 524 | + if (m_ereco[i] <= logEobs_min) { | |
| 517 | 525 | continue; |
| 518 | 526 | } |
| 519 | 527 | |
| 520 | 528 | // If measured energy is above maximum migration value then use |
| 521 | 529 | // logEobs_max as measured energy |
| 522 | - if (m_emeasured[i] > logEobs_max) { | |
| 530 | + if (m_ereco[i] > logEobs_max) { | |
| 523 | 531 | x2 = ereco_max; |
| 524 | 532 | f2 = this->operator()(x2, etrue); |
| 525 | 533 | } |
| 526 | 534 | |
| 527 | 535 | // ... otherwise use measured energy |
| 528 | 536 | else { |
| 529 | - x2.log10TeV(m_emeasured[i]); | |
| 537 | + #if defined(G_LINEAR_ERECO_INTERPOLATION) | |
| 538 | + x2.TeV(m_ereco[i]); | |
| 539 | + #else | |
| 540 | + x2.log10TeV(m_ereco[i]); | |
| 541 | + #endif | |
| 530 | 542 | f2 = wgt_left * m_matrix(inx_left, i) + |
| 531 | 543 | wgt_right * m_matrix(inx_right, i); |
| 532 | 544 | if (f2 < 0.0) { |
| ... | ... | @@ -535,14 +547,14 @@ double GCTAEdispRmf::prob_erecobin(const GEnergy& ereco_min, |
| 535 | 547 | } |
| 536 | 548 | |
| 537 | 549 | // Compute integral |
| 538 | - prob += 0.5 * (f1 + f2) * (x2.log10TeV() - x1.log10TeV()); | |
| 550 | + prob += 0.5 * (f1 + f2) * (x2.MeV() - x1.MeV()); | |
| 539 | 551 | |
| 540 | 552 | // Set second node as first node |
| 541 | 553 | x1 = x2; |
| 542 | 554 | f1 = f2; |
| 543 | 555 | |
| 544 | 556 | // If node energy is above migra_max then break now |
| 545 | - if (m_emeasured[i] > logEobs_max) { | |
| 557 | + if (m_ereco[i] > logEobs_max) { | |
| 546 | 558 | break; |
| 547 | 559 | } |
| 548 | 560 | |
| ... | ... | @@ -553,7 +565,7 @@ double GCTAEdispRmf::prob_erecobin(const GEnergy& ereco_min, |
| 553 | 565 | if (x1 < ereco_max) { |
| 554 | 566 | x2 = ereco_max; |
| 555 | 567 | f2 = this->operator()(x2, etrue); |
| 556 | - prob += 0.5 * (f1 + f2) * (x2.log10TeV() - x1.log10TeV()); | |
| 568 | + prob += 0.5 * (f1 + f2) * (x2.MeV() - x1.MeV()); | |
| 557 | 569 | } |
| 558 | 570 | |
| 559 | 571 | // Return probability |
| ... | ... | @@ -616,33 +628,31 @@ void GCTAEdispRmf::init_members(void) |
| 616 | 628 | m_filename.clear(); |
| 617 | 629 | m_rmf.clear(); |
| 618 | 630 | m_matrix.clear(); |
| 631 | + m_max_edisp = 0.0; | |
| 619 | 632 | |
| 620 | 633 | // Initialise interpolation cache |
| 621 | 634 | m_etrue.clear(); |
| 622 | - m_emeasured.clear(); | |
| 623 | - m_last_etrue = 9999.0; | |
| 624 | - m_last_emeasured = 9999.0; | |
| 625 | - m_itrue1 = 0; | |
| 626 | - m_itrue2 = 0; | |
| 627 | - m_imeas1 = 0; | |
| 628 | - m_imeas2 = 0; | |
| 629 | - m_wgt1 = 0.0; | |
| 630 | - m_wgt2 = 0.0; | |
| 631 | - m_wgt3 = 0.0; | |
| 632 | - m_wgt4 = 0.0; | |
| 633 | - | |
| 634 | - // Initialise Monte Carlo cache | |
| 635 | - m_max_edisp = 0.0; | |
| 636 | - m_last_theta_obs = -1.0; | |
| 637 | - m_last_theta_src = -1.0; | |
| 638 | - m_last_etrue_ereco_bounds.log10TeV(-30.0); | |
| 639 | - m_last_ereco_etrue_bounds.log10TeV(-30.0); | |
| 640 | - m_index_obs = 0; | |
| 641 | - m_index_src = 0; | |
| 642 | - m_ebounds_obs_computed = false; | |
| 643 | - m_ebounds_src_computed = false; | |
| 644 | - m_ebounds_obs.clear(); | |
| 645 | - m_ebounds_src.clear(); | |
| 635 | + m_ereco.clear(); | |
| 636 | + m_last_etrue.clear(); | |
| 637 | + m_last_ereco.clear(); | |
| 638 | + m_itrue1 = 0; | |
| 639 | + m_itrue2 = 0; | |
| 640 | + m_ireco1 = 0; | |
| 641 | + m_ireco2 = 0; | |
| 642 | + m_wgt1 = 0.0; | |
| 643 | + m_wgt2 = 0.0; | |
| 644 | + m_wgt3 = 0.0; | |
| 645 | + m_wgt4 = 0.0; | |
| 646 | + | |
| 647 | + // Initialise computation cache | |
| 648 | + m_ereco_bounds_computed = false; | |
| 649 | + m_etrue_bounds_computed = false; | |
| 650 | + m_index_ereco = 0; | |
| 651 | + m_index_etrue = 0; | |
| 652 | + m_last_etrue_bounds.clear(); | |
| 653 | + m_last_ereco_bounds.clear(); | |
| 654 | + m_ereco_bounds.clear(); | |
| 655 | + m_etrue_bounds.clear(); | |
| 646 | 656 | |
| 647 | 657 | // Return |
| 648 | 658 | return; |
| ... | ... | @@ -657,36 +667,34 @@ void GCTAEdispRmf::init_members(void) |
| 657 | 667 | void GCTAEdispRmf::copy_members(const GCTAEdispRmf& edisp) |
| 658 | 668 | { |
| 659 | 669 | // Copy members |
| 660 | - m_filename = edisp.m_filename; | |
| 661 | - m_rmf = edisp.m_rmf; | |
| 662 | - m_matrix = edisp.m_matrix; | |
| 670 | + m_filename = edisp.m_filename; | |
| 671 | + m_rmf = edisp.m_rmf; | |
| 672 | + m_matrix = edisp.m_matrix; | |
| 673 | + m_max_edisp = edisp.m_max_edisp; | |
| 663 | 674 | |
| 664 | 675 | // Copy interpolation cache |
| 665 | - m_etrue = edisp.m_etrue; | |
| 666 | - m_emeasured = edisp.m_emeasured; | |
| 667 | - m_last_etrue = edisp.m_last_etrue; | |
| 668 | - m_last_emeasured = edisp.m_last_emeasured; | |
| 669 | - m_itrue1 = edisp.m_itrue1; | |
| 670 | - m_itrue2 = edisp.m_itrue2; | |
| 671 | - m_imeas1 = edisp.m_imeas1; | |
| 672 | - m_imeas2 = edisp.m_imeas2; | |
| 673 | - m_wgt1 = edisp.m_wgt1; | |
| 674 | - m_wgt2 = edisp.m_wgt2; | |
| 675 | - m_wgt3 = edisp.m_wgt3; | |
| 676 | - m_wgt4 = edisp.m_wgt4; | |
| 677 | - | |
| 678 | - // Copy Monte Carlo cache | |
| 679 | - m_max_edisp = edisp.m_max_edisp; | |
| 680 | - m_last_theta_obs = edisp.m_last_theta_obs; | |
| 681 | - m_last_theta_src = edisp.m_last_theta_src; | |
| 682 | - m_last_etrue_ereco_bounds = edisp.m_last_etrue_ereco_bounds; | |
| 683 | - m_last_ereco_etrue_bounds = edisp.m_last_ereco_etrue_bounds; | |
| 684 | - m_index_obs = edisp.m_index_obs; | |
| 685 | - m_index_src = edisp.m_index_src; | |
| 686 | - m_ebounds_obs_computed = edisp.m_ebounds_obs_computed; | |
| 687 | - m_ebounds_src_computed = edisp.m_ebounds_src_computed; | |
| 688 | - m_ebounds_obs = edisp.m_ebounds_obs; | |
| 689 | - m_ebounds_src = edisp.m_ebounds_src; | |
| 676 | + m_etrue = edisp.m_etrue; | |
| 677 | + m_ereco = edisp.m_ereco; | |
| 678 | + m_last_etrue = edisp.m_last_etrue; | |
| 679 | + m_last_ereco = edisp.m_last_ereco; | |
| 680 | + m_itrue1 = edisp.m_itrue1; | |
| 681 | + m_itrue2 = edisp.m_itrue2; | |
| 682 | + m_ireco1 = edisp.m_ireco1; | |
| 683 | + m_ireco2 = edisp.m_ireco2; | |
| 684 | + m_wgt1 = edisp.m_wgt1; | |
| 685 | + m_wgt2 = edisp.m_wgt2; | |
| 686 | + m_wgt3 = edisp.m_wgt3; | |
| 687 | + m_wgt4 = edisp.m_wgt4; | |
| 688 | + | |
| 689 | + // Copy computation cache | |
| 690 | + m_ereco_bounds_computed = edisp.m_ereco_bounds_computed; | |
| 691 | + m_etrue_bounds_computed = edisp.m_etrue_bounds_computed; | |
| 692 | + m_index_ereco = edisp.m_index_ereco; | |
| 693 | + m_index_etrue = edisp.m_index_etrue; | |
| 694 | + m_last_etrue_bounds = edisp.m_last_etrue_bounds; | |
| 695 | + m_last_ereco_bounds = edisp.m_last_ereco_bounds; | |
| 696 | + m_ereco_bounds = edisp.m_ereco_bounds; | |
| 697 | + m_etrue_bounds = edisp.m_etrue_bounds; | |
| 690 | 698 | |
| 691 | 699 | // Return |
| 692 | 700 | return; |
| ... | ... | @@ -715,28 +723,42 @@ void GCTAEdispRmf::set_matrix(void) |
| 715 | 723 | // Initialize matrix |
| 716 | 724 | m_matrix = GMatrixSparse(rows, columns); |
| 717 | 725 | |
| 726 | + // Get reconstructued energy bin boundaries | |
| 727 | + GEbounds ebounds = m_rmf.emeasured(); | |
| 728 | + | |
| 718 | 729 | // Fill matrix elements |
| 719 | - for (int itrue = 0; itrue < rows; ++itrue) { | |
| 720 | - for (int imeasured = 0; imeasured < columns; ++imeasured) { | |
| 721 | - m_matrix(itrue, imeasured) = m_rmf(itrue, imeasured); | |
| 730 | + for (int ireco = 0; ireco < columns; ++ireco) { | |
| 731 | + | |
| 732 | + // Compute reconstructued energy bin width in MeV | |
| 733 | + double ewidth = ebounds.emax(ireco).MeV() - ebounds.emin(ireco).MeV(); | |
| 734 | + | |
| 735 | + // If bin width is positive then fill all matrix bins by deviding | |
| 736 | + // the RMF values by the bin width. This assures that the stored | |
| 737 | + // values are per MeV of reconstructed energy. | |
| 738 | + if (ewidth > 0.0) { | |
| 739 | + for (int itrue = 0; itrue < rows; ++itrue) { | |
| 740 | + m_matrix(itrue, ireco) = m_rmf(itrue, ireco) / ewidth; | |
| 741 | + } | |
| 722 | 742 | } |
| 723 | - } | |
| 743 | + | |
| 744 | + } // endfor: looped over all reconstructed energies | |
| 724 | 745 | |
| 725 | 746 | // Initialise row sums |
| 726 | - std::vector<double> row_sums; | |
| 727 | - row_sums.reserve(rows); | |
| 747 | + std::vector<double> row_sums(rows, 0.0); | |
| 728 | 748 | |
| 729 | 749 | // Normalize matrix elements |
| 730 | 750 | for (int itrue = 0; itrue < rows; ++itrue) { |
| 731 | 751 | |
| 752 | + // Get true energy | |
| 753 | + GEnergy etrue = m_rmf.etrue().elogmean(itrue); | |
| 754 | + | |
| 732 | 755 | // Get integration boundaries |
| 733 | - GEbounds ebounds = ereco_bounds(m_rmf.etrue().elogmean(itrue), 0.0); | |
| 756 | + GEbounds ebounds = ereco_bounds(etrue); | |
| 734 | 757 | |
| 735 | 758 | // Integrate contributions over energy boundaries |
| 736 | 759 | double sum = 0.0; |
| 737 | 760 | for (int i = 0; i < ebounds.size(); ++i) { |
| 738 | - sum += prob_erecobin(ebounds.emin(i), ebounds.emax(i), | |
| 739 | - m_rmf.etrue().elogmean(itrue), 0.0); | |
| 761 | + sum += prob_erecobin(ebounds.emin(i), ebounds.emax(i), etrue, 0.0); | |
| 740 | 762 | } |
| 741 | 763 | |
| 742 | 764 | // Store matrix sum |
| ... | ... | @@ -748,8 +770,8 @@ void GCTAEdispRmf::set_matrix(void) |
| 748 | 770 | for (int itrue = 0; itrue < rows; ++itrue) { |
| 749 | 771 | double sum = row_sums[itrue]; |
| 750 | 772 | if (sum > 0.0) { |
| 751 | - for (int imeasured = 0; imeasured < columns; ++imeasured) { | |
| 752 | - m_matrix(itrue, imeasured) /= sum; | |
| 773 | + for (int ireco = 0; ireco < columns; ++ireco) { | |
| 774 | + m_matrix(itrue, ireco) /= sum; | |
| 753 | 775 | } |
| 754 | 776 | } |
| 755 | 777 | } |
| ... | ... | @@ -768,7 +790,7 @@ void GCTAEdispRmf::set_cache(void) const |
| 768 | 790 | { |
| 769 | 791 | // Clear node arrays |
| 770 | 792 | m_etrue.clear(); |
| 771 | - m_emeasured.clear(); | |
| 793 | + m_ereco.clear(); | |
| 772 | 794 | |
| 773 | 795 | // Set log10(Etrue) nodes |
| 774 | 796 | for (int i = 0; i < m_rmf.ntrue(); ++i) { |
| ... | ... | @@ -777,7 +799,11 @@ void GCTAEdispRmf::set_cache(void) const |
| 777 | 799 | |
| 778 | 800 | // Set log10(Emeasured) nodes |
| 779 | 801 | for (int i = 0; i < m_rmf.nmeasured(); ++i) { |
| 780 | - m_emeasured.append(m_rmf.emeasured().elogmean(i).log10TeV()); | |
| 802 | + #if defined(G_LINEAR_ERECO_INTERPOLATION) | |
| 803 | + m_ereco.append(m_rmf.emeasured().elogmean(i).TeV()); | |
| 804 | + #else | |
| 805 | + m_ereco.append(m_rmf.emeasured().elogmean(i).log10TeV()); | |
| 806 | + #endif | |
| 781 | 807 | } |
| 782 | 808 | |
| 783 | 809 | // Return |
| ... | ... | @@ -788,15 +814,15 @@ void GCTAEdispRmf::set_cache(void) const |
| 788 | 814 | /***********************************************************************//** |
| 789 | 815 | * @brief Set maximum energy dispersion value |
| 790 | 816 | ***************************************************************************/ |
| 791 | -void GCTAEdispRmf::set_max_edisp(void) const | |
| 817 | +void GCTAEdispRmf::set_max_edisp(void) | |
| 792 | 818 | { |
| 793 | 819 | // Initialise maximum |
| 794 | 820 | m_max_edisp = 0.0; |
| 795 | 821 | |
| 796 | 822 | // Loop over all response table elements |
| 797 | - for (int i = 0; i < m_matrix.rows(); ++i) { | |
| 798 | - for (int k = 0; k < m_matrix.columns(); ++k) { | |
| 799 | - double value = m_matrix(i,k); | |
| 823 | + for (int itrue = 0; itrue < m_matrix.rows(); ++itrue) { | |
| 824 | + for (int ireco = 0; ireco < m_matrix.columns(); ++ireco) { | |
| 825 | + double value = m_matrix(itrue, ireco); | |
| 800 | 826 | if (value > m_max_edisp) { |
| 801 | 827 | m_max_edisp = value; |
| 802 | 828 | } |
| ... | ... | @@ -811,37 +837,45 @@ void GCTAEdispRmf::set_max_edisp(void) const |
| 811 | 837 | /***********************************************************************//** |
| 812 | 838 | * @brief Update cache |
| 813 | 839 | * |
| 814 | - * @param[in] logEsrc Log10 of true energy (\f$\log_{10}\f$ TeV). | |
| 815 | - * @param[in] logEobs Log10 of reconstructed energy (\f$\log_{10}\f$ TeV). | |
| 840 | + * @param[in] ereco Reconstructed energy. | |
| 841 | + * @param[in] etrue True energy. | |
| 816 | 842 | * |
| 817 | 843 | * Updates the interpolation cache. The interpolation cache is composed |
| 818 | 844 | * of four indices and weights that define 4 data values of the RMF matrix |
| 819 | 845 | * that are used for bilinear interpolation. |
| 820 | 846 | ***************************************************************************/ |
| 821 | -void GCTAEdispRmf::update(const double& logEsrc, const double& logEobs) const | |
| 847 | +void GCTAEdispRmf::update(const GEnergy& ereco, const GEnergy& etrue) const | |
| 822 | 848 | { |
| 823 | 849 | // Update cache only of arguments have changed |
| 824 | - if (logEsrc != m_last_etrue || logEobs != m_last_emeasured) { | |
| 850 | + if (ereco != m_last_etrue || etrue != m_last_ereco) { | |
| 825 | 851 | |
| 826 | 852 | // Store actual values |
| 827 | - m_last_etrue = logEsrc; | |
| 828 | - m_last_emeasured = logEobs; | |
| 853 | + m_last_ereco = ereco; | |
| 854 | + m_last_etrue = etrue; | |
| 855 | + | |
| 856 | + // Get log10 of true and reconstructed photon energies | |
| 857 | + double logEsrc = etrue.log10TeV(); | |
| 858 | + #if defined(G_LINEAR_ERECO_INTERPOLATION) | |
| 859 | + double logEobs = ereco.TeV(); | |
| 860 | + #else | |
| 861 | + double logEobs = ereco.log10TeV(); | |
| 862 | + #endif | |
| 829 | 863 | |
| 830 | 864 | // Set values for node arrays |
| 831 | 865 | m_etrue.set_value(logEsrc); |
| 832 | - m_emeasured.set_value(logEobs); | |
| 866 | + m_ereco.set_value(logEobs); | |
| 833 | 867 | |
| 834 | 868 | // Set indices for bi-linear interpolation |
| 835 | 869 | m_itrue1 = m_etrue.inx_left(); |
| 836 | 870 | m_itrue2 = m_etrue.inx_right(); |
| 837 | - m_imeas1 = m_emeasured.inx_left(); | |
| 838 | - m_imeas2 = m_emeasured.inx_right(); | |
| 871 | + m_ireco1 = m_ereco.inx_left(); | |
| 872 | + m_ireco2 = m_ereco.inx_right(); | |
| 839 | 873 | |
| 840 | 874 | // Set weighting factors for bi-linear interpolation |
| 841 | - m_wgt1 = m_etrue.wgt_left() * m_emeasured.wgt_left(); | |
| 842 | - m_wgt2 = m_etrue.wgt_left() * m_emeasured.wgt_right(); | |
| 843 | - m_wgt3 = m_etrue.wgt_right() * m_emeasured.wgt_left(); | |
| 844 | - m_wgt4 = m_etrue.wgt_right() * m_emeasured.wgt_right(); | |
| 875 | + m_wgt1 = m_etrue.wgt_left() * m_ereco.wgt_left(); | |
| 876 | + m_wgt2 = m_etrue.wgt_left() * m_ereco.wgt_right(); | |
| 877 | + m_wgt3 = m_etrue.wgt_right() * m_ereco.wgt_left(); | |
| 878 | + m_wgt4 = m_etrue.wgt_right() * m_ereco.wgt_right(); | |
| 845 | 879 | |
| 846 | 880 | } // endif: update requested |
| 847 | 881 | |
| ... | ... | @@ -851,33 +885,21 @@ void GCTAEdispRmf::update(const double& logEsrc, const double& logEobs) const |
| 851 | 885 | |
| 852 | 886 | |
| 853 | 887 | /***********************************************************************//** |
| 854 | - * @brief Compute ebounds_obs vector | |
| 855 | - * | |
| 856 | - * @param[in] theta Offset angle in camera system (radians). Not used. | |
| 857 | - * @param[in] phi Azimuth angle in camera system (radians). Not used. | |
| 858 | - * @param[in] zenith Zenith angle in Earth system (radians). Not used. | |
| 859 | - * @param[in] azimuth Azimuth angle in Earth system (radians). Not used. | |
| 888 | + * @brief Compute m_ereco_bounds vector | |
| 860 | 889 | ***************************************************************************/ |
| 861 | -void GCTAEdispRmf::compute_ebounds_obs(const double& theta, | |
| 862 | - const double& phi, | |
| 863 | - const double& zenith, | |
| 864 | - const double& azimuth) const | |
| 890 | +void GCTAEdispRmf::compute_ereco_bounds(void) const | |
| 865 | 891 | { |
| 866 | 892 | // Clear boundaries |
| 867 | - m_ebounds_obs.clear(); | |
| 893 | + m_ereco_bounds.clear(); | |
| 868 | 894 | |
| 869 | 895 | // Loop over Etrue |
| 870 | 896 | for (int i = 0; i < m_rmf.ntrue(); ++i) { |
| 871 | 897 | |
| 872 | 898 | // Get true photon energy |
| 873 | - double logEsrc = m_rmf.etrue().elogmean(i).log10TeV(); | |
| 874 | - | |
| 875 | - // Set true energy | |
| 876 | - GEnergy etrue; | |
| 877 | - etrue.log10TeV(logEsrc); | |
| 899 | + GEnergy etrue = m_rmf.etrue().elogmean(i); | |
| 878 | 900 | |
| 879 | 901 | // Add ebounds to vector |
| 880 | - m_ebounds_obs.push_back(m_rmf.emeasured(etrue)); | |
| 902 | + m_ereco_bounds.push_back(m_rmf.emeasured(etrue)); | |
| 881 | 903 | |
| 882 | 904 | } // endfor: looped over true photon energies |
| 883 | 905 | |
| ... | ... | @@ -887,33 +909,21 @@ void GCTAEdispRmf::compute_ebounds_obs(const double& theta, |
| 887 | 909 | |
| 888 | 910 | |
| 889 | 911 | /***********************************************************************//** |
| 890 | - * @brief Compute ebounds_src vector | |
| 891 | - * | |
| 892 | - * @param[in] theta Offset angle in camera system (radians). Not used. | |
| 893 | - * @param[in] phi Azimuth angle in camera system (radians). Not used. | |
| 894 | - * @param[in] zenith Zenith angle in Earth system (radians). Not used. | |
| 895 | - * @param[in] azimuth Azimuth angle in Earth system (radians). Not used. | |
| 912 | + * @brief Compute m_etrue_bounds vector | |
| 896 | 913 | ***************************************************************************/ |
| 897 | -void GCTAEdispRmf::compute_ebounds_src(const double& theta, | |
| 898 | - const double& phi, | |
| 899 | - const double& zenith, | |
| 900 | - const double& azimuth) const | |
| 914 | +void GCTAEdispRmf::compute_etrue_bounds(void) const | |
| 901 | 915 | { |
| 902 | 916 | // Clear boundaries |
| 903 | - m_ebounds_src.clear(); | |
| 917 | + m_etrue_bounds.clear(); | |
| 904 | 918 | |
| 905 | 919 | // Loop over Eobs |
| 906 | 920 | for (int i = 0; i < m_rmf.nmeasured(); ++i) { |
| 907 | 921 | |
| 908 | - // Get observed photon energy | |
| 909 | - double logEobs = m_rmf.emeasured().elogmean(i).log10TeV(); | |
| 910 | - | |
| 911 | - // Set measured energy | |
| 912 | - GEnergy emeasured; | |
| 913 | - emeasured.log10TeV(logEobs); | |
| 922 | + // Get reconstructed energy | |
| 923 | + GEnergy ereco = m_rmf.emeasured().elogmean(i); | |
| 914 | 924 | |
| 915 | 925 | // Add ebounds to vector |
| 916 | - m_ebounds_src.push_back(m_rmf.emeasured(emeasured)); | |
| 926 | + m_etrue_bounds.push_back(m_rmf.emeasured(ereco)); | |
| 917 | 927 | |
| 918 | 928 | } // endfor: looped over measured photon energies |
| 919 | 929 | ... | ... |
inst/cta/test/test_CTA.cpp
| ... | ... | @@ -958,7 +958,7 @@ void TestGCTAResponse::test_response_edisp_RMF(void) |
| 958 | 958 | test_value(edisp2(GEnergy(30.0,"TeV"), GEnergy(1.0,"TeV")), 0.0); |
| 959 | 959 | |
| 960 | 960 | // Test that diagonal element is non-zero |
| 961 | - test_value(edisp2(GEnergy(30.0,"TeV"), GEnergy(30.0,"TeV")), 1.0785985662216e-07); | |
| 961 | + test_value(edisp2(GEnergy(30.0,"TeV"), GEnergy(30.0,"TeV")), 1.07978131144085e-07); | |
| 962 | 962 | |
| 963 | 963 | // Test if non-diagonal element (above diagonal) is zero |
| 964 | 964 | test_value(edisp2(GEnergy(1.0,"TeV"), GEnergy(30.0,"TeV")), 0.0); |
| ... | ... | @@ -967,13 +967,13 @@ void TestGCTAResponse::test_response_edisp_RMF(void) |
| 967 | 967 | GEnergy etrue(1.0, "TeV"); |
| 968 | 968 | GEnergy emin(0.1, "TeV"); |
| 969 | 969 | GEnergy emax(10.0, "TeV"); |
| 970 | - test_value(edisp2.prob_erecobin(emin, emax, etrue, 0.0), 1.00002576227557); | |
| 971 | - test_value(edisp2.prob_erecobin(etrue, emax, etrue, 0.0), 0.42065218271377); | |
| 972 | - test_value(edisp2.prob_erecobin(emin, etrue, etrue, 0.0), 0.43096191010834); | |
| 970 | + test_value(edisp2.prob_erecobin(emin, emax, etrue, 0.0), 1.00105708071354); | |
| 971 | + test_value(edisp2.prob_erecobin(etrue, emax, etrue, 0.0), 0.50215659368534); | |
| 972 | + test_value(edisp2.prob_erecobin(emin, etrue, etrue, 0.0), 0.498805373808917); | |
| 973 | 973 | |
| 974 | 974 | // Test mc method |
| 975 | 975 | GRan ran; |
| 976 | - test_value(edisp2.mc(ran, etrue).TeV(), 0.930126476703161); | |
| 976 | + test_value(edisp2.mc(ran, etrue).TeV(), 0.923744959981026); | |
| 977 | 977 | |
| 978 | 978 | // Test normalisation |
| 979 | 979 | test_edisp_integration(edisp2, 0.5, 10.0); |
| ... | ... | @@ -1006,8 +1006,8 @@ void TestGCTAResponse::test_response_edisp_2D(void) |
| 1006 | 1006 | test_value(edisp2.ereco_bounds(GEnergy(10.0,"TeV")).emax().TeV(), 13.2011115155942); |
| 1007 | 1007 | |
| 1008 | 1008 | // Test ebounds_src method |
| 1009 | - test_value(edisp2.etrue_bounds(GEnergy(10.0,"TeV")).emin().TeV(), 7.7813808018878); | |
| 1010 | - test_value(edisp2.etrue_bounds(GEnergy(10.0,"TeV")).emax().TeV(), 15.8059295273666); | |
| 1009 | + test_value(edisp2.etrue_bounds(GEnergy(10.0,"TeV")).emin().TeV(), 7.75156710957461); | |
| 1010 | + test_value(edisp2.etrue_bounds(GEnergy(10.0,"TeV")).emax().TeV(), 15.6834030551103); | |
| 1011 | 1011 | |
| 1012 | 1012 | // Test if non-diagonal element (below diagonal) is zero |
| 1013 | 1013 | test_value(edisp2(GEnergy(30.0,"TeV"), GEnergy(1.0,"TeV")), 0.0); |
| ... | ... | @@ -1028,7 +1028,7 @@ void TestGCTAResponse::test_response_edisp_2D(void) |
| 1028 | 1028 | |
| 1029 | 1029 | // Test mc method |
| 1030 | 1030 | GRan ran; |
| 1031 | - test_value(edisp2.mc(ran, etrue).TeV(), 0.872387491302767); | |
| 1031 | + test_value(edisp2.mc(ran, etrue).TeV(), 0.991300452406315); | |
| 1032 | 1032 | |
| 1033 | 1033 | // Test normalisation |
| 1034 | 1034 | test_edisp_integration(edisp2); | ... | ... |