Skip to content

Fix TAGH/TAGM tagger-overlap efficiency double-counting (closes #850) - #1153

Merged
sdobbs merged 3 commits into
masterfrom
Hao_Dev_TaggerOverlapEfficiencyFix
Jul 29, 2026
Merged

Fix TAGH/TAGM tagger-overlap efficiency double-counting (closes #850)#1153
sdobbs merged 3 commits into
masterfrom
Hao_Dev_TaggerOverlapEfficiencyFix

Conversation

@lihaoahil

Copy link
Copy Markdown
Contributor

Base: master Head: Hao_Dev_TaggerOverlapEfficiencyFix

Summary

DBeamPhoton_factory_TAGGEDMCGEN (the reconstruction-efficiency denominator source) derived its single output photon from DBeamPhoton_factory_MCGEN's already-collapsed, TAGM-preferring system choice. In the small TAGH/TAGM overlap windows (TAGH#127/TAGM#1 near 8.9 GeV, TAGH#179/TAGM#102 near 7.86-7.87 GeV) a thrown photon legitimately registers truth hits in both systems — real detector behavior, correctly left un-merged by the reconstructed DBeamPhoton_factory and correctly treated as two independent counts by DBeamPhoton_factory_TRUTH and the official flux tool (psflux). Because TAGGEDMCGEN collapsed to one entry regardless, the denominator stayed at 1 while the numerator was 2, producing a spurious ~2x efficiency spike inside the overlap windows.

Full root-cause discussion, the fix rationale, and testing are posted on #850 — this PR implements what's described there.

Changes

  • a296bbcffDBeamPhoton_factory_TAGGEDMCGEN::Process() now iterates over all primary (bg==0) "TRUTH"-tagged systems and matches each independently against the reconstructed list, instead of inheriting MCGEN's single collapsed choice. Non-overlap events unaffected; overlap events emit up to two entries, but only for truth systems that actually find a reconstructed match (partial-reconstruction still correctly reports 1). MCGEN itself is untouched.
  • c3deea4b6DEventWriterROOT::Fill_ThrownTree had the same [0]-collapsing bug on the thrown side; now writes one Thrown_Tree row per TAGGEDMCGEN entry so the thrown-side denominator symmetrically tracks the fixed reconstructed-side numerator. Fill_DataTree has the same pattern but is intentionally left untouched (used by all physics reaction trees — much larger blast radius, out of scope here).
  • e7d960f25 — Two additions for downstream consumers:
    • ThrownBeam__IsTAGH boolean branch on Thrown_Tree (true=TAGH, false=TAGM/SYS_NULL) so analyses can tell the two rows of an overlap event apart.
    • ANALYSIS:STORE_TAGGEDMCGEN_PER_SYSTEM_ROWS JANA parameter (default true) to fall back to the exact pre-fix single-row-per-event Fill_ThrownTree behavior, for anyone who needs the old row count preserved.

Testing

Tested natively against the GlueX stack pinned by version_7.5.0.xml (halld_recon baseline 5.11.0 + this branch, halld_sim 5.7.0, ROOT 6.32.20, geant4 10.07.p04, hdgeant4 3.3.1, gluex_MCwrapper v2.13.0). Full details and figures on #850.

Notes for reviewers

  • STORE_TAGGEDMCGEN_PER_SYSTEM_ROWS defaults to true (the fixed behavior) — this changes Thrown_Tree's row count (not its per-row content) inside overlap windows for every consumer, not just this analysis. The toggle exists specifically so anyone who needs the exact old row count can opt back in without a rebuild.

resolves #850

@lihaoahil
lihaoahil requested a review from sdobbs July 29, 2026 02:21
@gluex

gluex commented Jul 29, 2026

Copy link
Copy Markdown

Build status for this pull request: FAILURE

Build log: make_Hao_Dev_TaggerOverlapEfficiencyFix.log
Build report: report_Hao_Dev_TaggerOverlapEfficiencyFix.txt

DBeamPhoton_factory_TAGGEDMCGEN previously derived its single output
photon from MCGEN's already-collapsed system choice (TAGM-preferring),
so when a thrown photon genuinely registered truth hits in both TAGH
and TAGM (as real coincident detector hits do in their overlap
regions, e.g. TAGH#127/TAGM#1), the reconstruction-efficiency
denominator stayed at 1 while the (correctly un-merged) reconstructed
DBeamPhoton numerator was 2, producing the ~2x efficiency spike in
issue #850.

Iterate over all primary (bg==0) TRUTH-tagged systems instead, and
match each independently against the reconstructed list, so the
denominator tracks the numerator symmetrically -- mirroring how
DBeamPhoton_factory_TRUTH and the official flux tool (psflux) already
treat TAGH/TAGM overlap hits as two independent, additive counts
rather than collapsing them.

Verified against MC test data spanning both known overlap windows
(TAGH#127/TAGM#1 near 8.9 GeV, TAGH#179/TAGM#102 near 7.86-7.87 GeV):
TAGGEDMCGEN counts now match reconstructed DBeamPhoton counts
event-by-event in every observed case, including partial-overlap bins
where only one of the two truth-tagged systems is actually
reconstructed. Non-overlap bins are byte-for-byte unchanged.

Fixes #850
DEventWriterROOT::Fill_ThrownTree collapsed to
DBeamPhoton:TAGGEDMCGEN[0], writing exactly one row per event
regardless of how many truth-tagged systems TAGGEDMCGEN actually
holds. In TAGH/TAGM overlap regions, TAGGEDMCGEN correctly holds one
entry per truth-tagged system (mirroring DBeamPhoton_factory_TRUTH,
per the #850 fix in ef49cb4), and the reconstructed side is
likewise left un-merged -- so collapsing the thrown side to a single
row undercounts the "thrown" denominator relative to the reconstructed
numerator whenever an analysis divides by this tree's row count (e.g.
via the mcthrown_tree plugin) instead of querying
DBeamPhoton:TAGGEDMCGEN object counts directly via hd_dump.

Loop over all TAGGEDMCGEN entries and fill one tree row per entry, so
overlap events produce two rows (matching TAGGEDMCGEN/DBeamPhoton/
TRUTH object counts) instead of one.

Verified on 500 MC events at 8.880-8.890 GeV (full TAGH#127/TAGM#1
overlap): Thrown_Tree row count goes from 500 (1/event, always) to
905, exactly matching the DBeamPhoton and DBeamPhoton:TAGGEDMCGEN
object totals for the same sample.

Fill_DataTree (used by all physics reaction trees) has the same
[0]-only pattern but is intentionally left untouched here -- out of
scope for this change, much larger blast radius.

Related to #850
Adds a ThrownBeam__IsTAGH boolean branch to Thrown_Tree (true = TAGH,
false = TAGM/SYS_NULL, always written), so downstream analyses can tell
apart the two rows an overlap event now produces after c3deea4.

Also adds ANALYSIS:STORE_TAGGEDMCGEN_PER_SYSTEM_ROWS (default true), a
JANA parameter toggling Fill_ThrownTree between the current
one-row-per-TAGGEDMCGEN-entry behavior and the pre-c3deea4b6
single-row-per-event collapse, for consumers that need the old row
count preserved.

Verified via native build against both raw hd_root/mcthrown_tree output
and the DSelector_Thrown_Tree/DSelector_antip__B4_Tree pipeline, at
both single-bin and wider-range (8.85-8.92 GeV) statistics -- see
work/halld_recon_issue_850/FINDINGS.md.
@lihaoahil
lihaoahil force-pushed the Hao_Dev_TaggerOverlapEfficiencyFix branch from e7d960f to 57136b3 Compare July 29, 2026 02:58
@gluex

gluex commented Jul 29, 2026

Copy link
Copy Markdown

Test status for this pull request: SUCCESS

Summary: summary.txt
Logs: results/log

Build log: make_Hao_Dev_TaggerOverlapEfficiencyFix.log
Build report: report_Hao_Dev_TaggerOverlapEfficiencyFix.txt

@sdobbs sdobbs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, thanks for the thorough work!

@sdobbs
sdobbs merged commit 21de058 into master Jul 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistently counted beam photon in reconstructed MC/thrown MC at beam energies where TAGH and TAGM overlaps

3 participants