Where
What happens
HyCalCluster::ReconstructHits returns positions in the HyCal module frame (center_mod.x + ..., the same frame as mod->x/y). ApplyToHyCal undoes the target shift that LoadRunConfig applied, so it is only correct for lab-frame points. That is how g_hit uses it, since g_hit went through ApplyToLab. hc_hit never went through ApplyToLab, so calling ApplyToHyCal on it moves the cluster position by (+target_x, +target_y) away from where it really is.
All projected-energy outputs are then computed at the wrong point: h1_seed_project, h1_neighbor_project(2) and h1_*_fraction_proj(2). The shower sector choice (get_sector_id) is affected too. The measured energies and the GEM-based xd/yd selection are not affected.
The size of the error depends on the run, taken from beam_target_positions in database/runinfo/general.json:
- runs 24185–25307: target (0, 0), no effect
- runs ≥ 25308: (0.805, 1.486) mm
- runs ≥ 25655: (-0.108, 1.601) mm
- runs ≥ 26000: (0.85, 1.5) mm
A shift of about 1.5 mm is roughly 7% of a 20.75 mm PbWO4 module. For comparison, the position cut keeps |xd|, |yd| < 0.2 module.
Also minor: the theta cut at L413 uses the same HyCal-frame hc_hit rather than a beam-centred position. The error there is about 0.01° and hardly matters.
Evidence
hc_hit.x = hits[0].x; // HyCal module frame
hc_hit.y = hits[0].y;
...
ApplyToHyCal(hc_hit, gRunConfig); // += target_x/y -> no longer the HyCal frame
ApplyToHyCal(g_hit, gRunConfig); // correct: g_hit is lab-frame
...
hycal.qdist(hc_hit.x, hc_hit.y, profile_sector, mod->x, mod->y, mod->sector, dx, dy);
leakage_correction_check.cpp does the same projection with the unshifted hits[0].x/y: https://github.com/JeffersonLab/prad2evviewer/blob/d21ae9f/analysis/tools/leakage_correction_check.cpp#L335-L343.
To reproduce, run hycal_shower_profile on a raw replay of any run ≥ 25308 with and without L511. The *_proj histograms will differ. For runs < 25308 the two outputs are identical.
Suggested fix
Remove ApplyToHyCal(hc_hit, gRunConfig); (L511) and keep the one on g_hit. hc_hit is already in the frame that qdist and get_sector_id expect. If a beam-centred position is wanted for the theta cut, use the lab-frame cluster instead: ApplyToLab(hc_xform, ...) followed by GetProjection, as done at L469–L475.
Status
Still present on the dedup-refactor branch. hc_hit is still seeded from hits[0] and passed through ApplyToHyCal before clusterer.ProfileFractionAt(hc_hit.x, hc_hit.y, ...).
Where
hc_hitis taken directly fromhits[0](HyCal module frame)ApplyToHyCal(hc_hit, gRunConfig)hc_hitfeedsget_sector_id/qdistfor the projected energiesApplyToHyCaladdstarget_x/target_yLoadRunConfigsubtracts the target offset from the detector positions, so the lab frame is beam-centredWhat happens
HyCalCluster::ReconstructHitsreturns positions in the HyCal module frame (center_mod.x + ..., the same frame asmod->x/y).ApplyToHyCalundoes the target shift thatLoadRunConfigapplied, so it is only correct for lab-frame points. That is howg_hituses it, sinceg_hitwent throughApplyToLab.hc_hitnever went throughApplyToLab, so callingApplyToHyCalon it moves the cluster position by(+target_x, +target_y)away from where it really is.All projected-energy outputs are then computed at the wrong point:
h1_seed_project,h1_neighbor_project(2)andh1_*_fraction_proj(2). The shower sector choice (get_sector_id) is affected too. The measured energies and the GEM-basedxd/ydselection are not affected.The size of the error depends on the run, taken from
beam_target_positionsindatabase/runinfo/general.json:A shift of about 1.5 mm is roughly 7% of a 20.75 mm PbWO4 module. For comparison, the position cut keeps |xd|, |yd| < 0.2 module.
Also minor: the
thetacut at L413 uses the same HyCal-framehc_hitrather than a beam-centred position. The error there is about 0.01° and hardly matters.Evidence
leakage_correction_check.cppdoes the same projection with the unshiftedhits[0].x/y: https://github.com/JeffersonLab/prad2evviewer/blob/d21ae9f/analysis/tools/leakage_correction_check.cpp#L335-L343.To reproduce, run
hycal_shower_profileon a raw replay of any run ≥ 25308 with and without L511. The*_projhistograms will differ. For runs < 25308 the two outputs are identical.Suggested fix
Remove
ApplyToHyCal(hc_hit, gRunConfig);(L511) and keep the one ong_hit.hc_hitis already in the frame thatqdistandget_sector_idexpect. If a beam-centred position is wanted for thethetacut, use the lab-frame cluster instead:ApplyToLab(hc_xform, ...)followed byGetProjection, as done at L469–L475.Status
Still present on the
dedup-refactorbranch.hc_hitis still seeded fromhits[0]and passed throughApplyToHyCalbeforeclusterer.ProfileFractionAt(hc_hit.x, hc_hit.y, ...).