Commit fb5380a82d3a9471c5f2fc092f3f305e0a7c9404

Authored by Jürgen Knödlseder
1 parent e0624ca2

Correct simulations for energy dispersion.

The true energy range was used for event selection instead of the reconstructed energy range. This was a bug introduced in the recent refactoring. Now fixed.
src/ctobssim/ctobssim.cpp
@@ -39,8 +39,8 @@ @@ -39,8 +39,8 @@
39 "GModels&, GRan&, GLog*)" 39 "GModels&, GRan&, GLog*)"
40 #define G_SIMULATE_INTERVAL "ctobssim::simulate_interval(GCTAObservation*"\ 40 #define G_SIMULATE_INTERVAL "ctobssim::simulate_interval(GCTAObservation*"\
41 ", GCTAEventList*, GCTAResponseIrf*, GModels&, GTime&"\ 41 ", GCTAEventList*, GCTAResponseIrf*, GModels&, GTime&"\
42 - ", GTime&, GEnergy&, GEnergy&, GSkyDir&, double&"\  
43 - ", double&, GRan&, GLog*, int&)" 42 + ", GTime&, GEnergy&, GEnergy&, GEnergy&, GEnergy&"\
  43 + ", GSkyDir&, double&, double&, GRan&, GLog*, int&)"
44 #define G_GET_AREA "ctobssim::get_area(GCTAObservation* obs, GEnergy&, "\ 44 #define G_GET_AREA "ctobssim::get_area(GCTAObservation* obs, GEnergy&, "\
45 "GEnergy&)" 45 "GEnergy&)"
46 46
@@ -711,7 +711,8 @@ void ctobssim::simulate_source(GCTAObservation* obs, @@ -711,7 +711,8 @@ void ctobssim::simulate_source(GCTAObservation* obs,
711 GCTAEventList* events = static_cast<GCTAEventList*>(obs->events()); 711 GCTAEventList* events = static_cast<GCTAEventList*>(obs->events());
712 712
713 // Get CTA response 713 // Get CTA response
714 - const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(obs->response()); 714 + const GCTAResponseIrf* rsp =
  715 + dynamic_cast<const GCTAResponseIrf*>(obs->response());
715 if (rsp == NULL) { 716 if (rsp == NULL) {
716 std::string cls = std::string(typeid(obs->response()).name()); 717 std::string cls = std::string(typeid(obs->response()).name());
717 std::string msg = "Response of type \""+cls+"\" is not a CTA " 718 std::string msg = "Response of type \""+cls+"\" is not a CTA "
@@ -767,28 +768,28 @@ void ctobssim::simulate_source(GCTAObservation* obs, @@ -767,28 +768,28 @@ void ctobssim::simulate_source(GCTAObservation* obs,
767 // Loop over all energy boundaries 768 // Loop over all energy boundaries
768 for (int ie = 0; ie < ebounds.size(); ++ie) { 769 for (int ie = 0; ie < ebounds.size(); ++ie) {
769 770
770 - // Set energy interval  
771 - GEnergy emin = ebounds.emin(ie);  
772 - GEnergy emax = ebounds.emax(ie); 771 + // Set reconstructed energy interval
  772 + GEnergy ereco_min = ebounds.emin(ie);
  773 + GEnergy ereco_max = ebounds.emax(ie);
773 774
774 // Set true photon energy limits for simulation. If the 775 // Set true photon energy limits for simulation. If the
775 // observation has energy dispersion then add a margin. 776 // observation has energy dispersion then add a margin.
776 - GEnergy e_true_min = emin;  
777 - GEnergy e_true_max = emax; 777 + GEnergy etrue_min = ereco_min;
  778 + GEnergy etrue_max = ereco_max;
778 if (rsp->use_edisp()) { 779 if (rsp->use_edisp()) {
779 - e_true_min = rsp->ebounds(e_true_min).emin();  
780 - e_true_max = rsp->ebounds(e_true_max).emax(); 780 + etrue_min = rsp->ebounds(etrue_min).emin();
  781 + etrue_max = rsp->ebounds(etrue_max).emax();
781 } 782 }
782 783
783 // Determine simulation area 784 // Determine simulation area
784 - double area = get_area(obs, emin, emax); 785 + double area = get_area(obs, ereco_min, ereco_max);
785 786
786 // Log energy range and simulation area 787 // Log energy range and simulation area
787 if (logNormal()) { 788 if (logNormal()) {
788 *wrklog << gammalib::parformat("Photon energy range", indent); 789 *wrklog << gammalib::parformat("Photon energy range", indent);
789 - *wrklog << e_true_min << " - " << e_true_max << std::endl; 790 + *wrklog << etrue_min << " - " << etrue_max << std::endl;
790 *wrklog << gammalib::parformat("Event energy range", indent); 791 *wrklog << gammalib::parformat("Event energy range", indent);
791 - *wrklog << emin << " - " << emax << std::endl; 792 + *wrklog << ereco_min << " - " << ereco_max << std::endl;
792 } 793 }
793 794
794 // Increment indentation if there are several energy 795 // Increment indentation if there are several energy
@@ -811,7 +812,8 @@ void ctobssim::simulate_source(GCTAObservation* obs, @@ -811,7 +812,8 @@ void ctobssim::simulate_source(GCTAObservation* obs,
811 812
812 // Simulate events for this time and energy interval 813 // Simulate events for this time and energy interval
813 simulate_interval(obs, rsp, events, models, tmin, tmax, 814 simulate_interval(obs, rsp, events, models, tmin, tmax,
814 - e_true_min, e_true_max, dir, rad, area, 815 + etrue_min, etrue_max, ereco_min, ereco_max,
  816 + dir, rad, area,
815 ran, wrklog, indent, nphotons, nevents); 817 ran, wrklog, indent, nphotons, nevents);
816 818
817 // Log simulation results 819 // Log simulation results
@@ -887,8 +889,10 @@ void ctobssim::simulate_source(GCTAObservation* obs, @@ -887,8 +889,10 @@ void ctobssim::simulate_source(GCTAObservation* obs,
887 * @param[in] models Model list. 889 * @param[in] models Model list.
888 * @param[in] tmin Start time. 890 * @param[in] tmin Start time.
889 * @param[in] tmax Stop time. 891 * @param[in] tmax Stop time.
890 - * @param[in] emin Minimum energy.  
891 - * @param[in] emax Maximum energy. 892 + * @param[in] etrue_min Minimum true energy.
  893 + * @param[in] etrue_max Maximum true energy.
  894 + * @param[in] ereco_min Minimum reconstructed energy.
  895 + * @param[in] ereco_max Maximum reconstructed energy.
892 * @param[in] dir Simulation cone centre. 896 * @param[in] dir Simulation cone centre.
893 * @param[in] rad Simulation cone radius (degrees). 897 * @param[in] rad Simulation cone radius (degrees).
894 * @param[in] area Simulation area (cm^2). 898 * @param[in] area Simulation area (cm^2).
@@ -906,8 +910,10 @@ void ctobssim::simulate_interval(GCTAObservation* obs, @@ -906,8 +910,10 @@ void ctobssim::simulate_interval(GCTAObservation* obs,
906 const GModels& models, 910 const GModels& models,
907 const GTime& tmin, 911 const GTime& tmin,
908 const GTime& tmax, 912 const GTime& tmax,
909 - const GEnergy& emin,  
910 - const GEnergy& emax, 913 + const GEnergy& etrue_min,
  914 + const GEnergy& etrue_max,
  915 + const GEnergy& ereco_min,
  916 + const GEnergy& ereco_max,
911 const GSkyDir& dir, 917 const GSkyDir& dir,
912 const double& rad, 918 const double& rad,
913 const double& area, 919 const double& area,
@@ -938,7 +944,7 @@ void ctobssim::simulate_interval(GCTAObservation* obs, @@ -938,7 +944,7 @@ void ctobssim::simulate_interval(GCTAObservation* obs,
938 // simulated photons to m_max_photons. The photon rate is estimated 944 // simulated photons to m_max_photons. The photon rate is estimated
939 // from the model flux and used to set the duration of the time 945 // from the model flux and used to set the duration of the time
940 // slice. 946 // slice.
941 - double flux = get_model_flux(model, emin, emax, dir, rad, 947 + double flux = get_model_flux(model, etrue_min, etrue_max, dir, rad,
942 indent, wrklog); 948 indent, wrklog);
943 double rate = flux * area; 949 double rate = flux * area;
944 double duration = 1800.0; // default: 1800 sec 950 double duration = 1800.0; // default: 1800 sec
@@ -1017,7 +1023,8 @@ void ctobssim::simulate_interval(GCTAObservation* obs, @@ -1017,7 +1023,8 @@ void ctobssim::simulate_interval(GCTAObservation* obs,
1017 1023
1018 // Simulate time slice 1024 // Simulate time slice
1019 simulate_time_slice(obs, rsp, events, model, tstart, tstop, 1025 simulate_time_slice(obs, rsp, events, model, tstart, tstop,
1020 - emin, emax, dir, rad, area, 1026 + etrue_min, etrue_max, ereco_min, ereco_max,
  1027 + dir, rad, area,
1021 ran, wrklog, indent, 1028 ran, wrklog, indent,
1022 nphotons[i], nevents[i]); 1029 nphotons[i], nevents[i]);
1023 1030
@@ -1067,8 +1074,10 @@ void ctobssim::simulate_interval(GCTAObservation* obs, @@ -1067,8 +1074,10 @@ void ctobssim::simulate_interval(GCTAObservation* obs,
1067 * @param[in] models Model list. 1074 * @param[in] models Model list.
1068 * @param[in] tmin Start time. 1075 * @param[in] tmin Start time.
1069 * @param[in] tmax Stop time. 1076 * @param[in] tmax Stop time.
1070 - * @param[in] emin Minimum energy.  
1071 - * @param[in] emax Maximum energy. 1077 + * @param[in] etrue_min Minimum true energy.
  1078 + * @param[in] etrue_max Maximum true energy.
  1079 + * @param[in] ereco_min Minimum reconstructed energy.
  1080 + * @param[in] ereco_max Maximum reconstructed energy.
1072 * @param[in] dir Simulation cone centre. 1081 * @param[in] dir Simulation cone centre.
1073 * @param[in] rad Simulation cone radius (degrees). 1082 * @param[in] rad Simulation cone radius (degrees).
1074 * @param[in] area Simulation area (cm^2). 1083 * @param[in] area Simulation area (cm^2).
@@ -1086,8 +1095,10 @@ void ctobssim::simulate_time_slice(GCTAObservation* obs, @@ -1086,8 +1095,10 @@ void ctobssim::simulate_time_slice(GCTAObservation* obs,
1086 const GModelSky* model, 1095 const GModelSky* model,
1087 const GTime& tstart, 1096 const GTime& tstart,
1088 const GTime& tstop, 1097 const GTime& tstop,
1089 - const GEnergy& emin,  
1090 - const GEnergy& emax, 1098 + const GEnergy& etrue_min,
  1099 + const GEnergy& etrue_max,
  1100 + const GEnergy& ereco_min,
  1101 + const GEnergy& ereco_max,
1091 const GSkyDir& dir, 1102 const GSkyDir& dir,
1092 const double& rad, 1103 const double& rad,
1093 const double& area, 1104 const double& area,
@@ -1098,8 +1109,8 @@ void ctobssim::simulate_time_slice(GCTAObservation* obs, @@ -1098,8 +1109,8 @@ void ctobssim::simulate_time_slice(GCTAObservation* obs,
1098 int& nevents) 1109 int& nevents)
1099 { 1110 {
1100 // Get photons 1111 // Get photons
1101 - GPhotons photons = model->mc(area, dir, rad, emin, emax, tstart, tstop,  
1102 - ran); 1112 + GPhotons photons = model->mc(area, dir, rad, etrue_min, etrue_max,
  1113 + tstart, tstop, ran);
1103 1114
1104 // Dump number of simulated photons 1115 // Dump number of simulated photons
1105 if (logExplicit()) { 1116 if (logExplicit()) {
@@ -1122,11 +1133,11 @@ void ctobssim::simulate_time_slice(GCTAObservation* obs, @@ -1122,11 +1133,11 @@ void ctobssim::simulate_time_slice(GCTAObservation* obs,
1122 GCTAEventAtom* event = rsp->mc(area, photons[i], *obs, ran); 1133 GCTAEventAtom* event = rsp->mc(area, photons[i], *obs, ran);
1123 1134
1124 // Use event only if it exists and if it falls within ROI, the 1135 // Use event only if it exists and if it falls within ROI, the
1125 - // energy interval and the time slice 1136 + // reconstructed energy interval and the time slice
1126 if (event != NULL) { 1137 if (event != NULL) {
1127 if (events->roi().contains(*event) && 1138 if (events->roi().contains(*event) &&
1128 - event->energy() >= emin &&  
1129 - event->energy() <= emax && 1139 + event->energy() >= ereco_min &&
  1140 + event->energy() <= ereco_max &&
1130 event->time() >= tstart && 1141 event->time() >= tstart &&
1131 event->time() <= tstop) { 1142 event->time() <= tstop) {
1132 event->event_id(m_event_id); 1143 event->event_id(m_event_id);
src/ctobssim/ctobssim.hpp
@@ -85,8 +85,10 @@ protected: @@ -85,8 +85,10 @@ protected:
85 const GModels& models, 85 const GModels& models,
86 const GTime& tmin, 86 const GTime& tmin,
87 const GTime& tmax, 87 const GTime& tmax,
88 - const GEnergy& emin,  
89 - const GEnergy& emax, 88 + const GEnergy& etrue_min,
  89 + const GEnergy& etrue_max,
  90 + const GEnergy& ereco_min,
  91 + const GEnergy& ereco_max,
90 const GSkyDir& dir, 92 const GSkyDir& dir,
91 const double& rad, 93 const double& rad,
92 const double& area, 94 const double& area,
@@ -101,8 +103,10 @@ protected: @@ -101,8 +103,10 @@ protected:
101 const GModelSky* model, 103 const GModelSky* model,
102 const GTime& tstart, 104 const GTime& tstart,
103 const GTime& tstop, 105 const GTime& tstop,
104 - const GEnergy& emin,  
105 - const GEnergy& emax, 106 + const GEnergy& etrue_min,
  107 + const GEnergy& etrue_max,
  108 + const GEnergy& ereco_min,
  109 + const GEnergy& ereco_max,
106 const GSkyDir& dir, 110 const GSkyDir& dir,
107 const double& rad, 111 const double& rad,
108 const double& area, 112 const double& area,