Where
What happens
(a) GetMollerPhiDiff returns |phi1 - phi2| - 180. Its range is [-180, 180), and a back-to-back pair gives 0. The *_hc branch cuts on GetMollerPhiDiff(mp) < 10.f without fabs, so the cut is one-sided. Any pair with |phi1 - phi2| < 170° passes, including two clusters on the same side of the beam. The GEM-matched branch uses fabs(...) < 10.f, and h_moller_phi_diff is booked symmetric (-20..20).
Numbers from run 24246 (first ~20k events, Ebeam = 3488.43 MeV):
- 847 pairs pass the energy-sum cut.
h_moller_phi_diff puts 113 of them in the underflow (Δφ < -20°), 5 in [-20, -10), 706 in [-10, 10) and 23 at 10 or above.
- 824 pairs pass the current cut. A symmetric cut would keep 706, so 118 of the 824 selected pairs (14%) are not back to back.
- Those extra pairs go into
ee_hits_hc, energy_plots/ee_E_angle_hc, ee_center_x_hc / ee_center_y_hc (through mollers_hc), ee_vertex_z_hc and moller_analysis/ee_invariant_mass.
- Example:
ee_vertex_z_hc has 824 entries with 75 in the underflow. With the fabs cut it has 706 entries and 13 in the underflow.
(b) The e-p window is |E - E_exp| < 3 * E_exp * 0.035 / sqrt(E/1000). It puts the expected energy in the numerator and the measured energy under the square root. The intended sigma is 0.035 * E_exp / sqrt(E_exp/1000), which is 0.035 * sqrt(1000 * E_exp), as used at L938-939. Because of the mix, the window is asymmetric and shifted toward low energy:
| E_exp (MeV) |
intended 3σ window |
current window |
| 3486 |
±196.0 |
-202.0 / +190.9 |
| 1100 |
±110.1 |
-116.5 / +105.2 |
| 700 |
±87.8 |
-94.5 / +83.1 |
The current window also diverges as E → 0: any E below about 11 MeV passes.
On run 24246, the fix would change 33 of the 2496 accepted hits:
- 16 hits at E - E_exp ≈ -201 to -196 MeV are accepted only by the current formula.
- 17 hits at +191 to +196 MeV are rejected by it.
The effect is small, but it biases ep_hits, ep_E_angle, ep_yield and therefore ep_ee_ratio toward the radiative tail.
Evidence
// PhysicsTools.cpp, GetMollerPhiDiff
float phi_diff = fabs(phi1 - phi2) - 180.f; // back-to-back -> 0
// quick_check.cpp L479 (*_hc branch): one-sided
if(physics.GetMollerPhiDiff(mp) < 10.f) {
// quick_check.cpp L563 (GEM-matched branch): symmetric
&& fabs(physics.GetMollerPhiDiff(mev)) < 10.f)
// quick_check.cpp L528: expectE outside, measured E under the sqrt
if (fabs(E - expectE) < 3.f * expectE * 0.035f / std::sqrt(E/1000.f)) {
To reproduce (a): run quick_check on any recon file and look at moller_analysis/h_moller_phi_diff. Every entry in the underflow and in [-20, -10) is also counted in the ee_*_hc histograms and in ee_invariant_mass.
Suggested fix
- (a)
if (std::fabs(physics.GetMollerPhiDiff(mp)) < 10.f). This matches the GEM-matched branch.
- (b)
if (fabs(E - expectE) < 3.f * 0.035f * std::sqrt(expectE * 1000.f)).
Both fixes change quick_check outputs (ee_*_hc, ee_invariant_mass, ep_*, ep_ee_ratio), so any stored reference outputs need to be regenerated.
Status: both defects are still present on the dedup-refactor branch (quick_check.cpp L392 and L428). They were left unchanged there on purpose to keep outputs identical. On that branch, the fix for (a) is PhysicsTools::isBackToBack(mp, 10.f).
Where
*_hc): https://github.com/JeffersonLab/prad2evviewer/blob/d21ae9f/analysis/tools/quick_check.cpp#L478-L479GetMollerPhiDiff: https://github.com/JeffersonLab/prad2evviewer/blob/d21ae9f/analysis/src/PhysicsTools.cpp#L445-L453h_moller_phi_diffbooking: https://github.com/JeffersonLab/prad2evviewer/blob/d21ae9f/analysis/src/PhysicsTools.cpp#L52-L54What happens
(a)
GetMollerPhiDiffreturns|phi1 - phi2| - 180. Its range is [-180, 180), and a back-to-back pair gives 0. The*_hcbranch cuts onGetMollerPhiDiff(mp) < 10.fwithoutfabs, so the cut is one-sided. Any pair with|phi1 - phi2| < 170°passes, including two clusters on the same side of the beam. The GEM-matched branch usesfabs(...) < 10.f, andh_moller_phi_diffis booked symmetric (-20..20).Numbers from run 24246 (first ~20k events, Ebeam = 3488.43 MeV):
h_moller_phi_diffputs 113 of them in the underflow (Δφ < -20°), 5 in [-20, -10), 706 in [-10, 10) and 23 at 10 or above.ee_hits_hc,energy_plots/ee_E_angle_hc,ee_center_x_hc/ee_center_y_hc(throughmollers_hc),ee_vertex_z_hcandmoller_analysis/ee_invariant_mass.ee_vertex_z_hchas 824 entries with 75 in the underflow. With thefabscut it has 706 entries and 13 in the underflow.(b) The e-p window is
|E - E_exp| < 3 * E_exp * 0.035 / sqrt(E/1000). It puts the expected energy in the numerator and the measured energy under the square root. The intended sigma is0.035 * E_exp / sqrt(E_exp/1000), which is0.035 * sqrt(1000 * E_exp), as used at L938-939. Because of the mix, the window is asymmetric and shifted toward low energy:The current window also diverges as E → 0: any E below about 11 MeV passes.
On run 24246, the fix would change 33 of the 2496 accepted hits:
The effect is small, but it biases
ep_hits,ep_E_angle,ep_yieldand thereforeep_ee_ratiotoward the radiative tail.Evidence
To reproduce (a): run
quick_checkon any recon file and look atmoller_analysis/h_moller_phi_diff. Every entry in the underflow and in [-20, -10) is also counted in theee_*_hchistograms and inee_invariant_mass.Suggested fix
if (std::fabs(physics.GetMollerPhiDiff(mp)) < 10.f). This matches the GEM-matched branch.if (fabs(E - expectE) < 3.f * 0.035f * std::sqrt(expectE * 1000.f)).Both fixes change
quick_checkoutputs (ee_*_hc,ee_invariant_mass,ep_*,ep_ee_ratio), so any stored reference outputs need to be regenerated.Status: both defects are still present on the
dedup-refactorbranch (quick_check.cppL392 and L428). They were left unchanged there on purpose to keep outputs identical. On that branch, the fix for (a) isPhysicsTools::isBackToBack(mp, 10.f).