Commit aa568ec02277cf9b1f7ed934d27c758073ac8fae
1 parent
4c2771c1
Edisp2D MC method is now working !
Showing
6 changed files
with
164 additions
and
57 deletions
inst/cta/include/GCTAEdisp2D.hpp
| ... | ... | @@ -103,8 +103,7 @@ private: |
| 103 | 103 | void update(const double& logEobs, |
| 104 | 104 | const double& logEsrc, |
| 105 | 105 | const double& theta) const; |
| 106 | - void update_cumul(const double& logEsrc, | |
| 107 | - const double& theta = 0.0, | |
| 106 | + void compute_cumul(const double& theta = 0.0, | |
| 108 | 107 | const double& phi = 0.0, |
| 109 | 108 | const double& zenith = 0.0, |
| 110 | 109 | const double& azimuth = 0.0) const; |
| ... | ... | @@ -112,9 +111,10 @@ private: |
| 112 | 111 | // Members |
| 113 | 112 | std::string m_filename; //!< Name of Edisp response file |
| 114 | 113 | GCTAResponseTable m_edisp; //!< Edisp response table |
| 115 | - mutable double m_logEsrc; | |
| 116 | - mutable double m_theta; | |
| 117 | - mutable std::vector<std::pair<double, double> > m_cumul; | |
| 114 | + | |
| 115 | + mutable bool m_cdf_computed; | |
| 116 | + mutable double m_theta; | |
| 117 | + mutable std::vector<std::vector<std::pair<double, double> > > m_cumul; | |
| 118 | 118 | }; |
| 119 | 119 | |
| 120 | 120 | ... | ... |
inst/cta/include/GCTAEdispRmf.hpp
inst/cta/src/GCTAEdisp2D.cpp
| ... | ... | @@ -183,7 +183,7 @@ double GCTAEdisp2D::operator()(const double& logEobs, |
| 183 | 183 | double EobsOverEsrc = std::exp((logEobs-logEsrc) * gammalib::ln10); |
| 184 | 184 | |
| 185 | 185 | // Compute edisp |
| 186 | - edisp = m_edisp(0, logEsrc, EobsOverEsrc, theta); | |
| 186 | + edisp = m_edisp(0, logEsrc, EobsOverEsrc, theta) * gammalib::ln10; | |
| 187 | 187 | |
| 188 | 188 | // Return |
| 189 | 189 | return edisp; |
| ... | ... | @@ -321,6 +321,9 @@ void GCTAEdisp2D::read(const GFits& fits) |
| 321 | 321 | // Set true energy axis to logarithmic scale |
| 322 | 322 | m_edisp.axis_log10(0); |
| 323 | 323 | |
| 324 | + // Set emigra axis to log scale | |
| 325 | + m_edisp.axis_log10(1); | |
| 326 | + | |
| 324 | 327 | // Set offset angle axis to radians |
| 325 | 328 | m_edisp.axis_radians(2); |
| 326 | 329 | |
| ... | ... | @@ -393,38 +396,70 @@ GEnergy GCTAEdisp2D::mc(GRan& ran, |
| 393 | 396 | const double& azimuth) const |
| 394 | 397 | { |
| 395 | 398 | |
| 396 | - // Update cumul | |
| 397 | - update_cumul(logEsrc, theta, phi, zenith, azimuth); | |
| 399 | + // Compute cumulative probability | |
| 400 | + compute_cumul(theta, phi, zenith, azimuth); | |
| 401 | + | |
| 402 | + // Find right logEsrc index with bisection search | |
| 403 | + int low = 0; | |
| 404 | + int high = m_edisp.axis(0); | |
| 405 | + double Esrc = std::exp(logEsrc*gammalib::ln10); | |
| 406 | + while ((high-low) > 1) { | |
| 407 | + int mid = (low+high) / 2; | |
| 408 | + if (Esrc < m_edisp.axis_lo(0, mid)) { | |
| 409 | + high = mid; | |
| 410 | + } | |
| 411 | + else { | |
| 412 | + low = mid; | |
| 413 | + } | |
| 414 | + } | |
| 415 | + // Index found | |
| 416 | + int isrc = low; | |
| 398 | 417 | |
| 399 | 418 | // Draw random number between 0 and 1 from uniform distribution |
| 400 | 419 | double p = ran.uniform(); |
| 401 | 420 | |
| 402 | 421 | // Find right index with bisection search |
| 403 | - int low = 0; | |
| 404 | - int high = m_cumul.size(); | |
| 422 | + low = 0; | |
| 423 | + high = m_cumul[isrc].size(); | |
| 405 | 424 | while ((high-low) > 1) { |
| 406 | 425 | int mid = (low+high) / 2; |
| 407 | - if (p < m_cumul[mid].second) { | |
| 426 | + if (p < m_cumul[isrc][mid].second) { | |
| 408 | 427 | high = mid; |
| 409 | 428 | } |
| 410 | - else if (m_cumul[mid].second <= p) { | |
| 429 | + else if (m_cumul[isrc][mid].second <= p) { | |
| 411 | 430 | low = mid; |
| 412 | 431 | } |
| 413 | 432 | } |
| 433 | + | |
| 414 | 434 | // Index found |
| 415 | - int index = low; | |
| 435 | + int index = 0; | |
| 436 | + if (low >= m_cumul[isrc].size() - 1) { | |
| 437 | + index = m_cumul[isrc].size() - 2; | |
| 438 | + } | |
| 439 | + else { | |
| 440 | + index = low; | |
| 441 | + } | |
| 442 | + | |
| 443 | + //std::cout << "p = " << p << std::endl; | |
| 444 | + //std::cout << "index = " << index << std::endl; | |
| 416 | 445 | |
| 417 | 446 | // Interpolate EobsOverEsrc value |
| 418 | - double result = (m_cumul[index+1].second - p)*m_cumul[index].first | |
| 419 | - + (p - m_cumul[index].second)*m_cumul[index+1].first; | |
| 420 | - result /= (m_cumul[index+1].second - m_cumul[index].second); | |
| 447 | + double EobsOverEsrc = 0.0; | |
| 448 | + | |
| 449 | + if (m_cumul[isrc][index+1].second == m_cumul[isrc][index].second) { | |
| 450 | + EobsOverEsrc = m_cumul[isrc][index].first; | |
| 451 | + } | |
| 452 | + else { | |
| 453 | + EobsOverEsrc = (m_cumul[isrc][index+1].second - p)*m_cumul[isrc][index].first | |
| 454 | + + (p - m_cumul[isrc][index].second)*m_cumul[isrc][index+1].first; | |
| 455 | + EobsOverEsrc /= (m_cumul[isrc][index+1].second - m_cumul[isrc][index].second); | |
| 456 | + } | |
| 421 | 457 | |
| 422 | - // Final result | |
| 423 | - double logEnergy = std::log10(result) + logEsrc; | |
| 424 | 458 | |
| 425 | 459 | // Set energy |
| 426 | 460 | GEnergy energy; |
| 427 | - energy.log10TeV(logEnergy); | |
| 461 | + energy.TeV(EobsOverEsrc * Esrc); | |
| 462 | + //std::cout << "eobs = " << EobsOverEsrc * Esrc << std::endl; | |
| 428 | 463 | |
| 429 | 464 | // Return energy |
| 430 | 465 | return energy; |
| ... | ... | @@ -639,8 +674,8 @@ void GCTAEdisp2D::init_members(void) |
| 639 | 674 | m_edisp.clear(); |
| 640 | 675 | |
| 641 | 676 | // Initialise Monte Carlo cache |
| 642 | - m_logEsrc = -30.0; | |
| 643 | - m_theta = 0.0; | |
| 677 | + m_theta = 0.0; | |
| 678 | + m_cdf_computed = false; | |
| 644 | 679 | m_cumul.clear(); |
| 645 | 680 | |
| 646 | 681 | // Return |
| ... | ... | @@ -674,51 +709,100 @@ void GCTAEdisp2D::free_members(void) |
| 674 | 709 | } |
| 675 | 710 | |
| 676 | 711 | /***********************************************************************//** |
| 677 | - * @brief Update cumulative probability | |
| 678 | - * | |
| 679 | - * TODO : vector of vectors for each Esrc and select nearest vector in mc | |
| 712 | + * @brief Compute cumulative probability | |
| 680 | 713 | * |
| 681 | 714 | ***************************************************************************/ |
| 682 | -void GCTAEdisp2D::update_cumul(const double& logEsrc, | |
| 683 | - const double& theta, | |
| 684 | - const double& phi, | |
| 685 | - const double& zenith, | |
| 686 | - const double& azimuth) const | |
| 715 | +void GCTAEdisp2D::compute_cumul(const double& theta, | |
| 716 | + const double& phi, | |
| 717 | + const double& zenith, | |
| 718 | + const double& azimuth) const | |
| 687 | 719 | { |
| 720 | + // TODO ? compute also for each theta ?? | |
| 688 | 721 | |
| 689 | - if (logEsrc != m_logEsrc || theta != m_theta) { | |
| 722 | + if (!m_cdf_computed) { | |
| 690 | 723 | |
| 691 | 724 | m_cumul.clear(); |
| 692 | 725 | |
| 693 | - m_logEsrc = logEsrc; | |
| 694 | - m_theta = theta; | |
| 726 | + //m_theta = theta; | |
| 727 | + m_cdf_computed = true; | |
| 728 | + | |
| 729 | + // Loop over Esrc | |
| 730 | + for (int isrc = 0; isrc < m_edisp.axis(0); ++isrc) { | |
| 731 | + | |
| 732 | + m_cumul.push_back(std::vector<std::pair<double, double> >()); | |
| 733 | + | |
| 734 | + //double Esrc = 0.5 * (m_edisp.axis_lo(0, isrc) + m_edisp.axis_hi(0, isrc)); | |
| 735 | + double Esrc = m_edisp.axis_lo(0, isrc); | |
| 695 | 736 | |
| 696 | 737 | // Initialize cumulative probability |
| 697 | 738 | double sum = 0.0; |
| 698 | 739 | |
| 699 | - for (int i = 0; i < m_edisp.axis(1); ++i) { | |
| 740 | + // Loop over Eobs from 0.1 TeV to 100.0 TeV | |
| 741 | + //int nsteps = (int) (m_edisp.axis_hi(1, m_edisp.axis(1)-1) * Esrc / deltaEobs); | |
| 742 | + int nsteps = 10000; | |
| 743 | + double deltaEobs = 100.0/nsteps; | |
| 744 | + double Eobs = 0.1; | |
| 700 | 745 | |
| 701 | - // Compute delta(Eobs/Etrue) and Eobs/Etrue values | |
| 702 | - double delta = m_edisp.axis_hi(1, i) - | |
| 703 | - m_edisp.axis_lo(1, i); | |
| 704 | - double EobsOverEsrc = 0.5 * (m_edisp.axis_hi(1, i) + | |
| 705 | - m_edisp.axis_lo(1, i)); | |
| 746 | + for (int iobs = 0; iobs < nsteps; ++iobs) { | |
| 747 | + | |
| 748 | + double EobsOverEsrc = Eobs/Esrc; | |
| 706 | 749 | |
| 707 | 750 | // Compute cumulative probability |
| 708 | - double add = m_edisp(0, logEsrc, EobsOverEsrc, theta) * | |
| 709 | - delta / EobsOverEsrc * gammalib::inv_ln10; | |
| 751 | + double add = m_edisp(0, std::log10(Esrc), EobsOverEsrc, theta) * | |
| 752 | + deltaEobs / Eobs; | |
| 710 | 753 | |
| 711 | 754 | // Add to sum (and keep sum lower or equal to 1) |
| 712 | 755 | sum = sum+add >= 1.0 ? 1.0 : sum+add; |
| 713 | 756 | |
| 714 | 757 | // Create pair containing EobsOverEsrc and cumulated probability |
| 715 | 758 | std::pair<double, double> pair(EobsOverEsrc, sum); |
| 716 | - std::cout << "Eobs/Esrc = " << EobsOverEsrc << ", sum = " << sum << std::endl; | |
| 717 | 759 | |
| 718 | 760 | // Add to vector |
| 719 | - m_cumul.push_back(pair); | |
| 761 | + m_cumul[isrc].push_back(pair); | |
| 762 | + | |
| 763 | + // Compute new Eobs value | |
| 764 | + Eobs += deltaEobs; | |
| 765 | + | |
| 766 | + } // endfor: looped over Eobs | |
| 767 | + | |
| 768 | + /* // Loop over EobsOverEtrue | |
| 769 | + | |
| 770 | + // Divide bin into n sub-bins | |
| 771 | + const int n = 10; | |
| 772 | + | |
| 773 | + for (int imigra = 0; imigra < m_edisp.axis(1); ++imigra) { | |
| 774 | + | |
| 775 | + // Compute delta(Eobs/Etrue) and Eobs/Etrue values | |
| 776 | + double delta = m_edisp.axis_hi(1, imigra) - | |
| 777 | + m_edisp.axis_lo(1, imigra); | |
| 778 | + double EobsOverEsrcmin = m_edisp.axis_lo(1, imigra); | |
| 779 | + | |
| 780 | + for (int i = 0; i < n; ++i) { | |
| 781 | + | |
| 782 | + double EobsOverEsrc = EobsOverEsrcmin + i*delta/n; | |
| 783 | + | |
| 784 | + // Compute cumulative probability | |
| 785 | + double add = m_edisp(0, std::log10(Esrc), EobsOverEsrc, theta) * | |
| 786 | + delta / (n * EobsOverEsrc * gammalib::ln10); | |
| 787 | + | |
| 788 | + // Add to sum (and keep sum lower or equal to 1) | |
| 789 | + sum = sum+add >= 1.0 ? 1.0 : sum+add; | |
| 790 | + | |
| 791 | + // Create pair containing EobsOverEsrc and cumulated probability | |
| 792 | + std::pair<double, double> pair(EobsOverEsrc, sum); | |
| 793 | + | |
| 794 | + //if(Esrc == 10.0 && EobsOverEsrc < 2.0) | |
| 795 | + //std::cout << "Eobs/Esrc = " << EobsOverEsrc << ", add = " << add << ", sum = " << sum << std::endl; | |
| 796 | + | |
| 797 | + // Add to vector | |
| 798 | + m_cumul[isrc].push_back(pair); | |
| 799 | + | |
| 800 | + } | |
| 720 | 801 | |
| 721 | 802 | } // endfor: looped over EobsOverEsrc |
| 803 | + */ | |
| 804 | + } | |
| 805 | + | |
| 722 | 806 | } |
| 723 | 807 | |
| 724 | 808 | // Return | ... | ... |
inst/cta/src/GCTAEdispRmf.cpp
| ... | ... | @@ -373,7 +373,7 @@ GEnergy GCTAEdispRmf::mc(GRan& ran, |
| 373 | 373 | int high = m_rmf.ntrue(); |
| 374 | 374 | while ((high-low) > 1) { |
| 375 | 375 | int mid = (low+high) / 2; |
| 376 | - if (logEsrc < m_rmf.etrue().elogmean(mid).log10TeV()) { | |
| 376 | + if (logEsrc < m_rmf.etrue().emin(mid).log10TeV()) { | |
| 377 | 377 | high = mid; |
| 378 | 378 | } |
| 379 | 379 | else { |
| ... | ... | @@ -398,19 +398,33 @@ GEnergy GCTAEdispRmf::mc(GRan& ran, |
| 398 | 398 | low = mid; |
| 399 | 399 | } |
| 400 | 400 | } |
| 401 | + | |
| 401 | 402 | // Index found |
| 402 | - int index = low; | |
| 403 | + int index = 0; | |
| 404 | + if (low >= m_cumul[isrc].size() - 1) { | |
| 405 | + index = m_cumul[isrc].size() - 2; | |
| 406 | + } | |
| 407 | + else { | |
| 408 | + index = low; | |
| 409 | + } | |
| 403 | 410 | |
| 404 | 411 | // Interpolate Eobs value |
| 405 | - double Eobs = (m_cumul[isrc][index+1].second - p)*m_cumul[isrc][index].first | |
| 406 | - + (p - m_cumul[isrc][index].second)*m_cumul[isrc][index+1].first; | |
| 407 | - Eobs /= (m_cumul[isrc][index+1].second - m_cumul[isrc][index].second); | |
| 412 | + double Eobs = 0.0; | |
| 413 | + | |
| 414 | + if (m_cumul[isrc][index+1].second == m_cumul[isrc][index].second) { | |
| 415 | + Eobs = m_cumul[isrc][index].first; | |
| 416 | + } | |
| 417 | + else { | |
| 418 | + Eobs = (m_cumul[isrc][index+1].second - p)*m_cumul[isrc][index].first | |
| 419 | + + (p - m_cumul[isrc][index].second)*m_cumul[isrc][index+1].first; | |
| 420 | + Eobs /= (m_cumul[isrc][index+1].second - m_cumul[isrc][index].second); | |
| 421 | + } | |
| 422 | + | |
| 408 | 423 | |
| 409 | 424 | // Set energy |
| 410 | 425 | GEnergy energy; |
| 411 | 426 | energy.TeV(Eobs); |
| 412 | 427 | |
| 413 | - | |
| 414 | 428 | // Return energy |
| 415 | 429 | return energy; |
| 416 | 430 | } | ... | ... |
inst/cta/test/example_sim_edisp.py
| ... | ... | @@ -31,7 +31,7 @@ import time |
| 31 | 31 | # ============== # |
| 32 | 32 | # Simulate Edisp # |
| 33 | 33 | # ============== # |
| 34 | -def sim_edisp(edisp, etrue, eobs_max=40.0, ebins=500, nmc=100000): | |
| 34 | +def sim_edisp(edisp, etrue, eobs_max=40.0, ebins=1000, nmc=100000): | |
| 35 | 35 | """ |
| 36 | 36 | Simulate Edisp and show results using matplotlib (if available). |
| 37 | 37 | """ |
| ... | ... | @@ -64,8 +64,8 @@ def sim_edisp(edisp, etrue, eobs_max=40.0, ebins=500, nmc=100000): |
| 64 | 64 | # Simulate observed energies |
| 65 | 65 | tstart = time.clock() |
| 66 | 66 | for i in range(nmc): |
| 67 | - #eobs = edisp.mc(ran, logEtrue).TeV() | |
| 68 | - eobs = edisp.mc(ran, logEtrue, float(i)).TeV() | |
| 67 | + eobs = edisp.mc(ran, logEtrue).TeV() | |
| 68 | + #eobs = edisp.mc(ran, logEtrue, float(i)).TeV() | |
| 69 | 69 | index = int(eobs/dEobs) |
| 70 | 70 | if (index < ebins): |
| 71 | 71 | counts[index] += 1.0 |
| ... | ... | @@ -89,7 +89,7 @@ def sim_edisp(edisp, etrue, eobs_max=40.0, ebins=500, nmc=100000): |
| 89 | 89 | sum += value |
| 90 | 90 | exp_edisp.append(value) |
| 91 | 91 | cumul.append(sum/nmc) |
| 92 | - print(sum) | |
| 92 | + print(sum/nmc) | |
| 93 | 93 | |
| 94 | 94 | # Create figure |
| 95 | 95 | fig, ax1 = plt.subplots() |
| ... | ... | @@ -138,11 +138,9 @@ if __name__ == '__main__': |
| 138 | 138 | print("******************************") |
| 139 | 139 | |
| 140 | 140 | # Load edisp |
| 141 | - edisp = gammalib.GCTAEdispRmf("./caldb/dc1/rmf.fits") | |
| 141 | + #edisp = gammalib.GCTAEdispRmf("./caldb/dc1/rmf.fits") | |
| 142 | 142 | #edisp = gammalib.GCTAEdispPerfTable("./caldb/cta_dummy_irf.dat") |
| 143 | - # NE MARCHE PAS /!\ | |
| 144 | - #edisp = gammalib.GCTAEdisp2D("./caldb/edisp_matrix.fits") | |
| 143 | + edisp = gammalib.GCTAEdisp2D("./caldb/edisp_matrix.fits") | |
| 145 | 144 | |
| 146 | 145 | # Simulate Edisp |
| 147 | 146 | sim_edisp(edisp, 20.0) # Energy in TeV |
| 148 | - #sim_edisp(edisp, 1.0) # Energy in TeV | ... | ... |
inst/cta/test/test_CTA.cpp
| ... | ... | @@ -611,6 +611,12 @@ void TestGCTAResponse::test_response_edisp_RMF(void) |
| 611 | 611 | // Test normalisation |
| 612 | 612 | test_edisp_integration(edisp, 0.5, 10.0); |
| 613 | 613 | |
| 614 | + std::cout << "Eobs = 1 TeV : " << edisp(0.0, 0.0) << std::endl; | |
| 615 | + std::cout << "Eobs = 10 TeV : " << edisp(1.0, 0.0) << std::endl; | |
| 616 | + | |
| 617 | + std::cout << "Eobs = 10 TeV : " << edisp(1.0, 1.0) << std::endl; | |
| 618 | + std::cout << "Eobs = 100 TeV : " << edisp(2.0, 1.0) << std::endl; | |
| 619 | + | |
| 614 | 620 | // Return |
| 615 | 621 | return; |
| 616 | 622 | } |
| ... | ... | @@ -656,6 +662,12 @@ void TestGCTAResponse::test_response_edisp_2D(void) |
| 656 | 662 | test_try_failure(e); |
| 657 | 663 | } |
| 658 | 664 | |
| 665 | + std::cout << "Eobs = 1 TeV : " << edisp(0.0, 0.0) << std::endl; | |
| 666 | + std::cout << "Eobs = 10 TeV : " << edisp(1.0, 0.0) << std::endl; | |
| 667 | + | |
| 668 | + std::cout << "Eobs = 10 TeV : " << edisp(1.0, 1.0) << std::endl; | |
| 669 | + std::cout << "Eobs = 100 TeV : " << edisp(2.0, 1.0) << std::endl; | |
| 670 | + | |
| 659 | 671 | // Return |
| 660 | 672 | return; |
| 661 | 673 | } | ... | ... |