CRVResponse: fix defects found by a static sweep of the package - #1956
Open
oksuzian wants to merge 1 commit into
Open
CRVResponse: fix defects found by a static sweep of the package#1956oksuzian wants to merge 1 commit into
oksuzian wants to merge 1 commit into
Conversation
CrvPhotonGenerator dedups MakeCrvPhotons instances by lookup-table filename and
shares one instance between sectors, but SetScintillationYield is only called on
the first-load branch, so the shared instance keeps the first sector's yield. In
prolog_v12.fcl, T3/T4/T5 all name LookupTable_6000_0 with yields 39794, 39794,
30482: T3 loads first, T4 matches by luck, and T5 silently runs at 39794 instead
of its configured 30482, a +30.5% light-yield overestimate. It is the only
mismatched filename group in the file, and the debug print reports the
configured value rather than the one in use, so the log conceals it. The same
filenames and yields are in prolog_v11.fcl; v10 and v09 list only T1-T4, all at
39400, so this entered when T5 was added at v11. Dedup now requires the yields
to agree as well as the filename.
MakeCrvSiPMCharges::FindFiberPhotonsPixelId returned lrint of an unbounded
GetRandom2 sample, so the outermost bin could yield pixel id 40 in a 40x40
array. That phantom pixel carried its own discharge state. Clamp to the array.
MakeCrvPhotons::LoadLookupTable never checked the stream after reading the
Cerenkov map and bin definitions, so a truncated table left bin boundaries and
yield curves holding whatever was in the buffers and the job continued with
silently wrong photon yields. Throw instead.
MakeCrvDigis::SetWaveform narrowed each sample to int16_t before applying the
[minADC,maxADC] clamp, so an extreme sample wrapped around and landed back
inside the range instead of saturating. Clamp in double, then narrow.
MakeCrvWaveforms::LoadSinglePEWaveform called max_element on the waveform vector
without checking it is non-empty.
CrvWidebandTest reset the five track-fit arrays after the continue that skips
trigger sector types, so for every index in triggerSectorTypes those branches
held whatever new[] returned on event 1 and were persisted to the ntuple every
event. Reset before the continue. Its destructor also freed 3 of its 18 new[]
arrays.
CrvPlot dereferenced four art::Handles with no isValid() check, where
CrvMCHelper and CrvCoincidenceClusterMatchMC guard the same case; declared
`double scale[4]={NAN}` and `maxADC[4]={NAN}`, which sets only element 0 to NAN
and value-initializes 1-3 to 0.0, defeating the isnan() "no digis" guard for
SiPMs 1-3; and its CMakeLists omitted Offline::GlobalConstantsService despite
calling GlobalConstantsHandle<PhysicsParams>.
Found by a static review of the package at 0ef02a6. Not built locally --
relying on CI for the build.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Collaborator
|
☀️ The build tests passed at 90abf94.
N.B. These results were obtained from a build of this Pull Request at 90abf94 after being merged into the base branch at 0ef02a6. For more information, please check the job page here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Nine defects found by a static review of
CRVResponseat0ef02a66d. I have not built this locally — relying onmu2e/buildtest.1. 🟠 CRV sector T5 is simulated at +30.5% light yield — and has been since
prolog_v11src/CrvPhotonGenerator_module.cc:198-210dedupsMakeCrvPhotonsinstances by lookup-table filename. On a hit it shares the existingshared_ptrandcontinues, soSetScintillationYield— which only runs on the first-load branch at:223— is never called for the second sector. The shared instance keeps the first sector's yield.In
prolog_v12.fcl, T3/T4/T5 all nameCRVConditions/v6_0/LookupTable_6000_0withscintillationYields39794, 39794, 30482:It is the only mismatched filename group in the file — every other duplicate group (R1/R2/R5/L1… on
4550_0, T1/T2 on6000_1) has identical yields. The_debug>0line at:205prints_scintillationYields[i], the configured value rather than the one in use, so the log actively conceals the substitution.Scope beyond the current prolog:
prolog_v11.fclcarries the identical filenames and yields.v10/v09list only T1–T4, all at 39400, so no mismatch existed. The defect entered when T5 was added at v11 and is therefore in already-produced datasets, not only future ones.Fixed by requiring the yields to agree as well as the filename before sharing an instance.
2. 🟠 SiPM pixel id can be one past the last pixel
src/MakeCrvSiPMCharges.cc:44-49returnedlrintof an unboundedGetRandom2sample. The outermost[39,40)bin yields pixel id 40 in a 40×40 array — a phantom pixel with its own discharge state, inflating simulated SiPM charge. Clamped to the array.3. 🟠
LoadLookupTablenever checks stream statesrc/MakeCrvPhotons.cc:275-280reads the Cerenkov map and all three bin arrays with no check afterwards. A truncated table leaves bin boundaries and yield curves holding whatever was in the buffers and the job continues with silently wrong photon yields. Now throws.4. 🟠
CrvWidebandTestpersists indeterminate track-fit values for trigger sectorssrc/CrvWidebandTest_module.cc:397-410: thecontinuethat skipstriggerSectorTypesfires before the reset block, so for every index intriggerSectorTypes([5,6]inwideband4modules.fcl,[2,3,4,5]inwidebandMuonTaggers.fcl)trackSlope/trackIntercept/trackPEs/trackPoints/trackChi2hold whatevernew[]returned on event 1 — and_tree->Fill()persists them every event, where the adjacent lines clearly intend the0/-1"no fit" sentinel. Moved the resets above thecontinue.5. 🟡
MakeCrvDigisnarrows before it saturatessrc/MakeCrvDigis.cc:12-14cast toint16_tand then applied the[minADC,maxADC]clamp, so an extreme sample wraps around and lands back inside the range instead of saturating. Clamp indouble, then narrow.6. 🟡
max_elementon a possibly-empty vectorsrc/MakeCrvWaveforms.cc:51—LoadSinglePEWaveformopens the file and checksgood(), but a file that opens and yields no points reachesmax_elementon an empty vector.7. 🟡
CrvPlot:{NAN}initializes only element 0src/CrvPlot_module.cc:236-237—double scale[4]={NAN};sets element 0 to NAN and value-initializes 1–3 to 0.0. Theisnan(scale[SiPM])"no digis" guard at:305therefore fails open for SiPM 1–3 and a flat y=0 curve is drawn; SiPM 0 conversely builds aTGaxiswith a NaN bound at:287. Same bug inmaxADC[4].8. 🟡
CrvPlot: four uncheckedart::Handles:113-124usesgetByLabeland never checksisValid().CrvMCHelper.cc:12andCrvCoincidenceClusterMatchMC_module.cc:119guard the same case. Now throws naming the missing product.9. 🟡
CrvPlot's CMakeLists omitsOffline::GlobalConstantsServiceDespite
GlobalConstantsHandle<PhysicsParams>at:102. It resolves transitively today, so this is hygiene, not a build break.Also fixed alongside 4:
CrvWidebandTest's destructor freed 3 of its 18new[]arrays.Validation
Productionandmu2e-trig-config, plus grep. Please letbuildtestbe the arbiter.debug > 0and compare the printed T5 yield againstGetScintillationYield()on the instance actually used — the print is the very line that hides it.CRVConditions/v6_0/*anddata/singlePEWaveform*.txtwere taken as given; finding 3 is about the absent read check, not the data.prolog_v03..v11were not audited except where finding 1 required it — they are frozen history for reproducing old datasets.triggerSectorTypesis a mandatory key with no default and is unset in the Production wideband config — that fix belongs inProduction, not here. TwoCRVTestissues (mandatory keys absent from 5 of its 6test/fcl; unguarded division filling NaN into two histograms) are hand-run-only and left out to keep this PR to code that production runs. Happy to open an issue with the full 16.