Commit aa568ec02277cf9b1f7ed934d27c758073ac8fae

Authored by Florent Forest
1 parent 4c2771c1

Edisp2D MC method is now working !

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
... ... @@ -129,7 +129,6 @@ private:
129 129 mutable std::vector<GVector> m_mc_measured_cdf;
130 130 mutable bool m_cdf_computed;
131 131 mutable double m_theta;
132   -
133 132 mutable std::vector<std::vector<std::pair<double, double> > > m_cumul;
134 133  
135 134 };
... ...
inst/cta/src/GCTAEdisp2D.cpp
... ... @@ -183,7 +183,7 @@ double GCTAEdisp2D::operator()(const double&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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__ == &#39;__main__&#39;:
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 }
... ...