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,8 +103,7 @@ private:
103 void update(const double& logEobs, 103 void update(const double& logEobs,
104 const double& logEsrc, 104 const double& logEsrc,
105 const double& theta) const; 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 const double& phi = 0.0, 107 const double& phi = 0.0,
109 const double& zenith = 0.0, 108 const double& zenith = 0.0,
110 const double& azimuth = 0.0) const; 109 const double& azimuth = 0.0) const;
@@ -112,9 +111,10 @@ private: @@ -112,9 +111,10 @@ private:
112 // Members 111 // Members
113 std::string m_filename; //!< Name of Edisp response file 112 std::string m_filename; //!< Name of Edisp response file
114 GCTAResponseTable m_edisp; //!< Edisp response table 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,7 +129,6 @@ private:
129 mutable std::vector<GVector> m_mc_measured_cdf; 129 mutable std::vector<GVector> m_mc_measured_cdf;
130 mutable bool m_cdf_computed; 130 mutable bool m_cdf_computed;
131 mutable double m_theta; 131 mutable double m_theta;
132 -  
133 mutable std::vector<std::vector<std::pair<double, double> > > m_cumul; 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,7 +183,7 @@ double GCTAEdisp2D::operator()(const double&amp; logEobs,
183 double EobsOverEsrc = std::exp((logEobs-logEsrc) * gammalib::ln10); 183 double EobsOverEsrc = std::exp((logEobs-logEsrc) * gammalib::ln10);
184 184
185 // Compute edisp 185 // Compute edisp
186 - edisp = m_edisp(0, logEsrc, EobsOverEsrc, theta); 186 + edisp = m_edisp(0, logEsrc, EobsOverEsrc, theta) * gammalib::ln10;
187 187
188 // Return 188 // Return
189 return edisp; 189 return edisp;
@@ -321,6 +321,9 @@ void GCTAEdisp2D::read(const GFits&amp; fits) @@ -321,6 +321,9 @@ void GCTAEdisp2D::read(const GFits&amp; fits)
321 // Set true energy axis to logarithmic scale 321 // Set true energy axis to logarithmic scale
322 m_edisp.axis_log10(0); 322 m_edisp.axis_log10(0);
323 323
  324 + // Set emigra axis to log scale
  325 + m_edisp.axis_log10(1);
  326 +
324 // Set offset angle axis to radians 327 // Set offset angle axis to radians
325 m_edisp.axis_radians(2); 328 m_edisp.axis_radians(2);
326 329
@@ -393,38 +396,70 @@ GEnergy GCTAEdisp2D::mc(GRan&amp; ran, @@ -393,38 +396,70 @@ GEnergy GCTAEdisp2D::mc(GRan&amp; ran,
393 const double& azimuth) const 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 // Draw random number between 0 and 1 from uniform distribution 418 // Draw random number between 0 and 1 from uniform distribution
400 double p = ran.uniform(); 419 double p = ran.uniform();
401 420
402 // Find right index with bisection search 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 while ((high-low) > 1) { 424 while ((high-low) > 1) {
406 int mid = (low+high) / 2; 425 int mid = (low+high) / 2;
407 - if (p < m_cumul[mid].second) { 426 + if (p < m_cumul[isrc][mid].second) {
408 high = mid; 427 high = mid;
409 } 428 }
410 - else if (m_cumul[mid].second <= p) { 429 + else if (m_cumul[isrc][mid].second <= p) {
411 low = mid; 430 low = mid;
412 } 431 }
413 } 432 }
  433 +
414 // Index found 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 // Interpolate EobsOverEsrc value 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 // Set energy 459 // Set energy
426 GEnergy energy; 460 GEnergy energy;
427 - energy.log10TeV(logEnergy); 461 + energy.TeV(EobsOverEsrc * Esrc);
  462 + //std::cout << "eobs = " << EobsOverEsrc * Esrc << std::endl;
428 463
429 // Return energy 464 // Return energy
430 return energy; 465 return energy;
@@ -639,8 +674,8 @@ void GCTAEdisp2D::init_members(void) @@ -639,8 +674,8 @@ void GCTAEdisp2D::init_members(void)
639 m_edisp.clear(); 674 m_edisp.clear();
640 675
641 // Initialise Monte Carlo cache 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 m_cumul.clear(); 679 m_cumul.clear();
645 680
646 // Return 681 // Return
@@ -674,51 +709,100 @@ void GCTAEdisp2D::free_members(void) @@ -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 m_cumul.clear(); 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 // Initialize cumulative probability 737 // Initialize cumulative probability
697 double sum = 0.0; 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 // Compute cumulative probability 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 // Add to sum (and keep sum lower or equal to 1) 754 // Add to sum (and keep sum lower or equal to 1)
712 sum = sum+add >= 1.0 ? 1.0 : sum+add; 755 sum = sum+add >= 1.0 ? 1.0 : sum+add;
713 756
714 // Create pair containing EobsOverEsrc and cumulated probability 757 // Create pair containing EobsOverEsrc and cumulated probability
715 std::pair<double, double> pair(EobsOverEsrc, sum); 758 std::pair<double, double> pair(EobsOverEsrc, sum);
716 - std::cout << "Eobs/Esrc = " << EobsOverEsrc << ", sum = " << sum << std::endl;  
717 759
718 // Add to vector 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 } // endfor: looped over EobsOverEsrc 802 } // endfor: looped over EobsOverEsrc
  803 + */
  804 + }
  805 +
722 } 806 }
723 807
724 // Return 808 // Return
inst/cta/src/GCTAEdispRmf.cpp
@@ -373,7 +373,7 @@ GEnergy GCTAEdispRmf::mc(GRan&amp; ran, @@ -373,7 +373,7 @@ GEnergy GCTAEdispRmf::mc(GRan&amp; ran,
373 int high = m_rmf.ntrue(); 373 int high = m_rmf.ntrue();
374 while ((high-low) > 1) { 374 while ((high-low) > 1) {
375 int mid = (low+high) / 2; 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 high = mid; 377 high = mid;
378 } 378 }
379 else { 379 else {
@@ -398,19 +398,33 @@ GEnergy GCTAEdispRmf::mc(GRan&amp; ran, @@ -398,19 +398,33 @@ GEnergy GCTAEdispRmf::mc(GRan&amp; ran,
398 low = mid; 398 low = mid;
399 } 399 }
400 } 400 }
  401 +
401 // Index found 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 // Interpolate Eobs value 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 // Set energy 424 // Set energy
410 GEnergy energy; 425 GEnergy energy;
411 energy.TeV(Eobs); 426 energy.TeV(Eobs);
412 427
413 -  
414 // Return energy 428 // Return energy
415 return energy; 429 return energy;
416 } 430 }
inst/cta/test/example_sim_edisp.py
@@ -31,7 +31,7 @@ import time @@ -31,7 +31,7 @@ import time
31 # ============== # 31 # ============== #
32 # Simulate Edisp # 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 Simulate Edisp and show results using matplotlib (if available). 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,8 +64,8 @@ def sim_edisp(edisp, etrue, eobs_max=40.0, ebins=500, nmc=100000):
64 # Simulate observed energies 64 # Simulate observed energies
65 tstart = time.clock() 65 tstart = time.clock()
66 for i in range(nmc): 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 index = int(eobs/dEobs) 69 index = int(eobs/dEobs)
70 if (index < ebins): 70 if (index < ebins):
71 counts[index] += 1.0 71 counts[index] += 1.0
@@ -89,7 +89,7 @@ def sim_edisp(edisp, etrue, eobs_max=40.0, ebins=500, nmc=100000): @@ -89,7 +89,7 @@ def sim_edisp(edisp, etrue, eobs_max=40.0, ebins=500, nmc=100000):
89 sum += value 89 sum += value
90 exp_edisp.append(value) 90 exp_edisp.append(value)
91 cumul.append(sum/nmc) 91 cumul.append(sum/nmc)
92 - print(sum) 92 + print(sum/nmc)
93 93
94 # Create figure 94 # Create figure
95 fig, ax1 = plt.subplots() 95 fig, ax1 = plt.subplots()
@@ -138,11 +138,9 @@ if __name__ == &#39;__main__&#39;: @@ -138,11 +138,9 @@ if __name__ == &#39;__main__&#39;:
138 print("******************************") 138 print("******************************")
139 139
140 # Load edisp 140 # Load edisp
141 - edisp = gammalib.GCTAEdispRmf("./caldb/dc1/rmf.fits") 141 + #edisp = gammalib.GCTAEdispRmf("./caldb/dc1/rmf.fits")
142 #edisp = gammalib.GCTAEdispPerfTable("./caldb/cta_dummy_irf.dat") 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 # Simulate Edisp 145 # Simulate Edisp
147 sim_edisp(edisp, 20.0) # Energy in TeV 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,6 +611,12 @@ void TestGCTAResponse::test_response_edisp_RMF(void)
611 // Test normalisation 611 // Test normalisation
612 test_edisp_integration(edisp, 0.5, 10.0); 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 // Return 620 // Return
615 return; 621 return;
616 } 622 }
@@ -656,6 +662,12 @@ void TestGCTAResponse::test_response_edisp_2D(void) @@ -656,6 +662,12 @@ void TestGCTAResponse::test_response_edisp_2D(void)
656 test_try_failure(e); 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 // Return 671 // Return
660 return; 672 return;
661 } 673 }