Repository navigation
HelixTool: don't count straws without signal in the helix hit ratio - #2035
michaelmackenzie wants to merge 4 commits into
Conversation
The hit ratio (measured straw hits / expected plane-face crossings) counted every face the helix crosses inside the tracker active radius as an expected hit, so dead panels and straws (TrackerStatus noSignal/suppress) biased it low and made minHitRatio cuts depend on the tracker conditions. - HelixTool takes an optional StrawNoSignal function. With it, each face crossing is weighted by the live fraction of the nearest straw in each layer at the crossing point. A function is used instead of TrackerStatus to avoid a Mu2eUtilities -> TrackerConditions library dependency. - The hit ratio is evaluated lazily, on the first hitRatio() call; the filters apply it as the last cut, and skip it when minHitRatio <= 0. - HelixFilter and MultiHelixFilter: new useTrackerStatus parameter (default true) passes TrackerStatus noSignal || suppress; false keeps the previous behavior. ReadTriggerInfo uses the same definition. - Removed the unused HelixTool::nMinHitsLoop() (never set) and _trackerLength; nstrawhits() returns int. With the Sim_commissioning reduced-tracker conditions (31% of straws without signal) the median CE helix hit ratio goes from 0.56 to 1.0, so minHitRatio 0.4 keeps its meaning. With useTrackerStatus false the trigger results are identical to before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hi @michaelmackenzie,
which require these tests: build. @Mu2e/fnalbuild-users, @Mu2e/write have access to CI actions on main. ⌛ The following tests have been triggered for 8265839: build (Build queue - API unavailable) |
|
☔ The build tests failed for 8265839.
N.B. These results were obtained from a build of this Pull Request at 8265839 after being merged into the base branch at 24a1aa5. For more information, please check the job page here. |
|
@FNALbuild run build test |
|
⌛ The following tests have been triggered for 8265839: build (Build queue - API unavailable) |
|
☀️ The build tests passed at 8265839.
N.B. These results were obtained from a build of this Pull Request at 8265839 after being merged into the base branch at fd9bfbd. For more information, please check the job page here. |
|
@FNALbuild run build test |
|
⌛ The following tests have been triggered for 8265839: build (Build queue - API unavailable) |
|
☀️ The build tests passed at 8265839.
N.B. These results were obtained from a build of this Pull Request at 8265839 after being merged into the base branch at fd9bfbd. For more information, please check the job page here. |
oksuzian
left a comment
There was a problem hiding this comment.
PR Review Summary — #2035
Reviewed at head 8265839752040f071149dbb565bbde1790489563. first pass
Decision
- 🟢 approve. The change does what the description says, and the build passes at this head. Two minor items and one follow-up for the trigger CI reference are below; none of them blocks.
Scope understood
- The helix hit ratio (straw hits on the helix / expected plane-face crossings) no longer counts a crossing in full when the straws there cannot give a signal.
HelixTooltakes an optional "this straw has no signal" function and weights each face crossing by the live fraction of the nearest straw in each of its two layers. HelixFilterandMultiHelixFilterget a newuseTrackerStatuskey (defaulttrue) that passesTrackerStatusnoSignal || suppress.ReadTriggerInfoalways uses it.- The ratio is computed on first use, and the filters skip it when
minHitRatio <= 0.nMinHitsLoop()and_trackerLengthare removed, andnstrawhits()now returnsint.
Findings
-
🟡 [S2]
useTrackerStatushas a C++ default oftrue, and it changes trigger decisions.- Evidence:
HelixFilter_module.ccandMultiHelixFilter_module.cc,fhicl::Atom<bool> useTrackerStatus{..., true}. No fcl inmu2e-trig-configor Production sets the key, so every helix filter in the trigger menu picks up the new behaviour without its config saying so. Every one of those filters cuts on the ratio:minHitRatiois 0.4 or 0.5 at 18 sites incore/filters/trig{Apr,Cpr,Mpr,Tpr}Filters.fcl. - Impact: the house rule is that a parameter whose right value depends on the physics context stays mandatory and gets its value from a prolog. The CI trigger job shows the effect is real (see Validation check). Whether a path uses the tracker status is then visible only in the C++ source.
- Suggested fix: make the key mandatory (two-argument
fhicl::Atom) and set it in the trigger filter prolog tables, with a companionmu2e-trig-configPR. If you prefer to keep the default, say so in the description so the trigger change is on record.
- Evidence:
-
⚪ [S3]
liveFractionfalls back to the end straws when no straw on that face is at the crossing point.- Evidence:
HelixTool.cc,liveFraction. If the crossing's distance along the panel normal (bestRho) is below straw 0 or above straw 95,sEstis clamped to 0 ornStraws-1. The weight then comes from the innermost or outermost straw pair, which is not at that point. The same holds when the point is inside the radial range but beyond the end of the straw. Both happen in the gaps between the three panels of one face. - Impact: small. Before this PR such a crossing counted 1. Now it counts 1 unless the end straws of that panel are dead. Counting a face with no straw at the point as expected is older than this PR. The header comment ("the fraction of live straws (nearest straw in each layer) at the crossing point") reads as if this case cannot happen.
- Suggested fix: either say in the comment that out-of-panel crossings take the end straws' status, or return 1 (the old weight) when
bestRhois outside[rho0, rhoMax].
- Evidence:
-
⚪ [S3]
ReadTriggerInfoalways applies the tracker status, with no switch.- Evidence:
ReadTriggerInfo_module.cc,analyze()sets_noSignalunconditionally. The comment says "same definition of the helix hit ratio as in HelixFilter". - Impact: if a
HelixFilteris run withuseTrackerStatus: false, the hit-ratio histogram no longer matches the cut that filter applied. No fcl in Offline ormu2e-trig-configconfiguresReadTriggerInfo, so nothing is affected today.
- Evidence:
🟢 Verified at this head:
- The "no signal" definition matches hit reconstruction.
noSignal || suppressis the same testStrawHitRecoUtils.cc:96uses to drop or flag-as-dead hits from a straw. So the denominator now excludes exactly the straws the numerator could never have hits from.noSignalcovers absent, no wire, no HV/LV, no gas, low gas gain, no preamp and disabled.noisystraws still count as live, which is right, since they do give signals. - Face and layer indexing is correct.
StrawId::face()is the low bit of the panel number (_facemsk = 0x80, the low bit of the panel field), sogetPanel(face)and theipn += _nfacesloop visit exactly the three panels on that face.layer()is the straw-number parity (_layermsk = 0x1), so straws alternate layers. The ±2 window around the interpolated straw index always holds at least one straw of each layer, including when it is clamped at either end. - Choosing the panel is right. Each panel's outward normal is built from its straw-0 midpoint minus the along-straw component. Taking the largest projection picks the panel whose centre is closest in azimuth to the crossing. Straw 0 is the innermost straw (
Panel.hh, "In the Tracker the primary straw is the innermost straw";tracker.innermostLayer = 0intracker_v7.txt). - The reordered cuts give the same decisions. In
MultiHelixFilter, moving the ratio test afterrequireCaloClusterdoes not change the result, since each test returns early. InHelixFilter,_minHitRatiodefaults to 0, so skipping the ratio when_minHitRatio <= 0matches the oldhRatio >= 0(always true).MultiHelixFilterdefaults to -1, the same case. - The lazy cache is safe.
HelixToolis always a function-local object, one per helix. Themutable _hitRatiois never shared between threads or helices. - The removed members had no users. At
main,nMinHitsLoop()has no callers outsideMu2eUtilities. The otherHelixToolusers (AgnosticHelixFinder,CalHelixFinder,RobustHelixFinder,ValHelixSeed) construct it with two arguments and use onlydirOfProp,nLoops,meanHitRadialDistandnstrawhits. The default argument keeps them building and unchanged.nstrawhits()going fromfloattointmatches every caller, which already stored it in anint. - Link lines.
TrkFiltersandTriggeraddTrackerConditionsandProditionsService(CMake) andmu2e_TrackerConditionsandmu2e_DbTables(scons).Mu2eUtilitiesgains no dependency, as the description says. Bothcheck_cmakeand the scons build pass.
Validation check
- Build/tests run: FNALbuild passed at this head (build 3449, merged at
fd9bfbdb), with all sim/reco jobs,check_cmakeand whitespace green.-
triggershows ❓, return code 1. I read the log. Return code 1 is the checker's "minor change" class: eight helix paths changed their pass counts againstci/reference_log_file.log, all by less than 1σ:path reference this PR tpr_HlxDe_70m50p1236 1264 tpr_HlxUe_50m30p1619 1646 tpr_HlxDe_30p_IPA488 498 tpr_HlxDe_30p_IPAPhi116 118 cpr_HlxUe_4021 22 apr_Hlx_50_Hlx_3013 14 apr_Hlx_50,apr_Hlx_30685 687 The time per event is within 6% of the reference. This is the expected effect of the default-on key on the
Sim_bestconditions the CI job loads (which has panel and straw status tables), on 20000 events. -
#2040, built on the same base
fd9bfbdba few hours later, has a cleantrigger. So the change comes from this PR, not from the base. Your two earlier builds (3444, 3445) failedtriggerwith return code 2. That failure mode also hit #2045 once and cleared on rerun at the same commit, so I read it as the known flaky failure, not this PR. -
Locally I read the diff, the call sites and the CI log. I did not run the code. I could not check the description's two numbers, the median ratio 0.56 to 1.0 with
Sim_commissioningand identical results withuseTrackerStatus: false. CI ran only the defaulttrue.
-
- Config contract check: pass. The new key is validated; see finding 1 for its default.
- Cross-repo consistency: needs a follow-up. Once this merges, every Offline PR's
triggercheck will show the same ❓ untilmu2e-trig-configci/reference_log_file.logis regenerated. No other repository callsHelixTool, and EventNtuple#423 does not touch it. - Merge order: #2038 is stacked on this PR (this commit is its first), so this one goes first.
Residual risk
- The online trigger uses
DbServicepurposeEMPTY, so I expect itsTrackerStatusto have no status rows and the online decision to be unchanged. I did not run it to confirm. Once run-time status tables are loaded online (the commentedtextFileincore/trigServices.fcl), the online hit-ratio cut changes with them. That is the intent, but it is a change in online trigger behaviour that follows the conditions, not the menu.
Author follow-ups
- Finding 1: make
useTrackerStatusmandatory and set it in the trigger filter tables, or state in the description that the default is deliberate. - Regenerate the
mu2e-trig-configCI reference log after this merges. - Optional: findings 2 and 3.
…rackerStatus - liveFraction: a face crossing with no straw of that face at the point (radially outside the panel's straws, or beyond the straw ends, e.g. between the panels of the face) keeps the old weight 1 instead of taking the end straws' status. - ReadTriggerInfo: add useTrackerStatus (default true, as in HelixFilter) so the hit-ratio histograms can match a filter run without the tracker status. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks @oksuzian. Addressed in 8e8b3d1:
Local check: build OK, and |
|
@FNALbuild run build test with Mu2e/mu2e-trig-config#178 |
|
⌛ The following tests have been triggered for 4c77950: build (Build queue - API unavailable) |
|
☀️ The build tests passed at 4c77950.
N.B. These results were obtained from a build of this Pull Request at 4c77950 after being merged into the base branch at b8cfd1d. For more information, please check the job page here. |
|
📝 The HEAD of |
oksuzian
left a comment
There was a problem hiding this comment.
PR Review Summary — #2035
Reviewed at head 4c77950ac4e68e22f0eeadd045cbad35271414d2. re-review of 8e8b3d1a
Decision
- 🟢 approve. The last open item from my review is fixed:
useTrackerStatusis now a required key, and mu2e-trig-config#178 sets it in every helix filter table. Merge the two together; each breaks the other's CI on its own.
Scope understood
- One new commit,
4c77950a. It drops thetruedefault fromuseTrackerStatusinHelixFilter,MultiHelixFilterandReadTriggerInfo(+4/−4). Companion: mu2e-trig-config#178.
Findings
- ⚪ [S3] In
ReadTriggerInfo,bool _useTrackerStatus;(ReadTriggerInfo_module.cc:267) lost its in-class= trueand is now set in the constructor body (:293). That is correct, since the constructor always sets it. But the two filters initialise the same member in the initialiser list (HelixFilter_module.cc:258,MultiHelixFilter_module.cc:290), and house rule 6 prefers that or an in-class initialiser. Optional.
🟢 Fixed since 8e8b3d1a, verified at this head:
- [was S2] C++ default for
useTrackerStatus. The key is now mandatory in all three modules, and every member is set fromconfig().useTrackerStatus(). - Every table that builds these modules sets the key. I searched for
module_type(quoted and unquoted) forHelixFilter,MultiHelixFilterandReadTriggerInfo:- mu2e-trig-config#178 at
db1ddaa7: 35 tables (Apr 16, Cpr 11, Tpr 7, Mpr 1), each withuseTrackerStatus: true. Thegen/menus are generated from these at build time. - None in Production
main, nor in this PR's Offline fcl. - None in shallow clones of PassN, DQM, EventNtuple, EventDisplay, Tutorial, RefAna or ArtAnalysis.
ReadTriggerInfohas no configured user anywhere, so no table needs the new key for it.
- mu2e-trig-config#178 at
- The full trigger menu validates and its decisions are unchanged.
- I built this PR merged onto
mainb8cfd1d7, as FNALbuild merges it. It was a sparse build of the six packages that includeHelixTool.hh, against the CI backingmain/b8cfd1d7_efebc0a2_3b4e7393, together with mu2e-trig-config#178 and Productionmain. fhicl-dumpoftest/triggerTest.fclsucceeds and carries all 35 keys.- The trig-config CI trigger test, run exactly as FNALbuild runs it on all 20000 events, gives return code 0 against #178's reference.
- All 52 path counts equal both #178's reference and FNALbuild build 3476. They also equal build 3469 at
8e8b3d1a, so making the key required changed no decision.
- I built this PR merged onto
Validation check
- Build/tests run:
- FNALbuild passed at this head with mu2e-trig-config#178 included at
e179cced(build 3476).triggerwas ❓ there because the reference log had not yet been updated; #178's second commitdb1ddaa7regenerates it from that build. - Locally: the build,
fhicl-dumpand full trigger test above, all passing. - Scripts and logs are in
claude-scratch/pr2035_r3/(build_run.sh,trigger_local.log,check_local.txt).
- FNALbuild passed at this head with mu2e-trig-config#178 included at
- Config contract check: pass.
- Cross-repo consistency: pass with mu2e-trig-config#178.
Residual risk
- Merge order: once this PR merges, trig-config
mainwithout #178 fails config validation in every job that builds the trigger menu. Once #178 merges, Offlinemainwithout this PR rejects the unknownuseTrackerStatuskey. Merge them together, as with Offline#2045 and #176 earlier today.
Author follow-ups
- Optional: initialise
_useTrackerStatusinReadTriggerInfo's initialiser list, like the filters (finding 1).
|
@FNALbuild run build test |
|
⌛ The following tests have been triggered for 115db19: build (Build queue - API unavailable) |
|
☔ The build tests failed for 115db19.
N.B. These results were obtained from a build of this Pull Request at 115db19 after being merged into the base branch at 51a5125. For more information, please check the job page here. |
|
@FNALbuild run build test with Mu2e/mu2e-trig-config#178 |
|
⌛ The following tests have been triggered for 115db19: build (Build queue - API unavailable) |
|
The hit ratio (measured straw hits / expected plane-face crossings) counted every face the helix crosses inside the tracker active radius as an expected hit, so dead panels and straws (TrackerStatus noSignal/suppress) biased it low and made minHitRatio cuts depend on the tracker conditions.
With the Sim_commissioning reduced-tracker conditions (31% of straws without signal) the median CE helix hit ratio goes from 0.56 to 1.0, so minHitRatio 0.4 keeps its meaning. With useTrackerStatus false the trigger results are identical to before.
Note on the useTrackerStatus default. The default
trueis deliberate: the hit ratio should follow the tracker conditions in every configuration, and with no status entries (e.g. the onlineEMPTYDbService purpose) it is identical to the old ratio. Making the key mandatory would require a simultaneous Offline and mu2e-trig-config merge (35 HelixFilter/MultiHelixFilter tables), since either one alone breaks the other's CI. This changes the trigger CI pass counts for some helix paths by < 1 sigma on the Sim_best conditions; the mu2e-trig-configci/reference_log_file.logwill be regenerated after this merges.