geom_common_MDC2020.txt and every other geometry on calorimeter_CsI_v1.txt now throw at geometry construction:
SimpleConfig: No such parameter calorimeter.diskCrystalFile in file
Offline/Mu2eG4/geom/geom_common_MDC2020.txt
Reproduced on main @ 1891b3289 via Mu2eG4/fcl/gdmldump_MDC2020.fcl; originally reported from a nightly build.
Cause
#1908 (521583d3) added an unconditional read in GeometryService/src/DiskCalorimeterMaker.cc:76:
calo_->G4Info_.set("diskCrystalFile", config.getString("calorimeter.diskCrystalFile"));
but added the key to calorimeter_CsI_v2.txt only. The two calorimeter geometry files on main now differ by exactly this:
$ diff Mu2eG4/geom/calorimeter_CsI_v1.txt Mu2eG4/geom/calorimeter_CsI_v2.txt
22a23
> string calorimeter.diskCrystalFile = "Offline/CalorimeterGeom/data/crystalPos.txt";
86c87
< double calorimeter.FEBToDiskZOffset = 1.98;
---
> double calorimeter.FEBToDiskZOffset = 35;
SimpleConfig::getString with no default throws when the key is absent, so any geometry reaching v1 dies at construction — before any event is processed.
Blast radius
Resolving the include graph over all 53 top-level geom*.txt on main, three reach v1 and therefore throw:
| Top-level geometry |
Reaches |
geom_common_MDC2020.txt |
calorimeter_CsI_v1.txt |
geom_2021_PhaseI_v03.txt |
calorimeter_CsI_v1.txt |
geom_reduced_DSTS_shielding.txt |
calorimeter_CsI_v1.txt |
The first two are the same chain: geom_common_MDC2020.txt → geom_2021_PhaseI_v03.txt → calorimeter_CsI_v1.txt.
Known consumers:
- Offline:
Mu2eG4/fcl/gdmldump_MDC2020.fcl, EventDisplay/fcl/EventDisplayMDC2020.fcl
- Production @
MDC2020 branch: JobConfig/common/epilog.fcl:10 pins this geometry for every MDC2020 job, plus Validation/{ceSimReco,ceDigi,ceSteps,muDauSteps,potSim}.fcl
Production@main has no references, so current production is unaffected.
Why CI stayed green
geom_common.txt → geom_run1_a_stickman.txt → calorimeter_CsI_v2.txt. Nightly and PR validation both run the default geometry, which has the key. Nothing in Offline CI exercises a frozen campaign geometry.
This is the same shape as the SurfaceIdEnum invalid enum name : CRV_C3 breakage a few weeks ago: a change validated only against current geometry, silently breaking a frozen campaign geometry that no CI job loads. It may be worth adding a cheap geometry-construction smoke test over the frozen top-level geoms — gdmldump on each is fast and would have caught both at PR time.
Suggested fix
The obvious one-liner — copying the diskCrystalFile line into calorimeter_CsI_v1.txt — is not behaviour-preserving, and I don't think it should be applied without a calorimeter sign-off.
#1908 also removed Disk::fillCrystalsIdeal() and made Disk::fillCrystals() the only path. Before #1908, Disk was constructed with fillCrystalsIdeal(...) (the fillCrystals call was present but commented out), so crystals sat at idealized map positions. Pointing v1 at crystalPos.txt would move MDC2020 crystals to measured positions — a real geometry change to a frozen campaign, retroactively inconsistent with every MDC2020 dataset already on tape.
Two options, in my order of preference:
-
Restore an idealized path for geometries that don't specify a crystal file. Make the config read optional (config.getString("calorimeter.diskCrystalFile", "")) and have Disk fall back to idealized positions when the name is empty. Disk::fillCrystals currently hard-throws on a missing file (CalorimeterGeom/src/Disk.cc:52-54), so this needs a real branch, not just an empty string. Preserves MDC2020 exactly.
-
Add the key to v1 pointing at measured positions — one line, but changes MDC2020 calorimeter geometry. Only acceptable with an explicit decision that MDC2020 reproducibility is not required here.
@bechenard — you own #1908, so I'd rather you pick the intended semantics than have someone guess. Happy to open the PR for whichever you prefer.
Related: #1914 (missing CalorimeterGeom/data install) and the install-rule blocker in #1919 were also fallout from the same refactor — this looks like the third instance of the data/config side of #1908 not reaching all consumers.
geom_common_MDC2020.txtand every other geometry oncalorimeter_CsI_v1.txtnow throw at geometry construction:Reproduced on
main@1891b3289viaMu2eG4/fcl/gdmldump_MDC2020.fcl; originally reported from a nightly build.Cause
#1908 (
521583d3) added an unconditional read inGeometryService/src/DiskCalorimeterMaker.cc:76:but added the key to
calorimeter_CsI_v2.txtonly. The two calorimeter geometry files onmainnow differ by exactly this:SimpleConfig::getStringwith no default throws when the key is absent, so any geometry reaching v1 dies at construction — before any event is processed.Blast radius
Resolving the include graph over all 53 top-level
geom*.txtonmain, three reach v1 and therefore throw:geom_common_MDC2020.txtcalorimeter_CsI_v1.txtgeom_2021_PhaseI_v03.txtcalorimeter_CsI_v1.txtgeom_reduced_DSTS_shielding.txtcalorimeter_CsI_v1.txtThe first two are the same chain:
geom_common_MDC2020.txt→geom_2021_PhaseI_v03.txt→calorimeter_CsI_v1.txt.Known consumers:
Mu2eG4/fcl/gdmldump_MDC2020.fcl,EventDisplay/fcl/EventDisplayMDC2020.fclMDC2020branch:JobConfig/common/epilog.fcl:10pins this geometry for every MDC2020 job, plusValidation/{ceSimReco,ceDigi,ceSteps,muDauSteps,potSim}.fclProduction@mainhas no references, so current production is unaffected.Why CI stayed green
geom_common.txt→geom_run1_a_stickman.txt→calorimeter_CsI_v2.txt. Nightly and PR validation both run the default geometry, which has the key. Nothing in Offline CI exercises a frozen campaign geometry.This is the same shape as the
SurfaceIdEnum invalid enum name : CRV_C3breakage a few weeks ago: a change validated only against current geometry, silently breaking a frozen campaign geometry that no CI job loads. It may be worth adding a cheap geometry-construction smoke test over the frozen top-level geoms —gdmldumpon each is fast and would have caught both at PR time.Suggested fix
The obvious one-liner — copying the
diskCrystalFileline intocalorimeter_CsI_v1.txt— is not behaviour-preserving, and I don't think it should be applied without a calorimeter sign-off.#1908 also removed
Disk::fillCrystalsIdeal()and madeDisk::fillCrystals()the only path. Before #1908,Diskwas constructed withfillCrystalsIdeal(...)(thefillCrystalscall was present but commented out), so crystals sat at idealized map positions. Pointing v1 atcrystalPos.txtwould move MDC2020 crystals to measured positions — a real geometry change to a frozen campaign, retroactively inconsistent with every MDC2020 dataset already on tape.Two options, in my order of preference:
Restore an idealized path for geometries that don't specify a crystal file. Make the config read optional (
config.getString("calorimeter.diskCrystalFile", "")) and haveDiskfall back to idealized positions when the name is empty.Disk::fillCrystalscurrently hard-throws on a missing file (CalorimeterGeom/src/Disk.cc:52-54), so this needs a real branch, not just an empty string. Preserves MDC2020 exactly.Add the key to v1 pointing at measured positions — one line, but changes MDC2020 calorimeter geometry. Only acceptable with an explicit decision that MDC2020 reproducibility is not required here.
@bechenard — you own #1908, so I'd rather you pick the intended semantics than have someone guess. Happy to open the PR for whichever you prefer.
Related: #1914 (missing
CalorimeterGeom/datainstall) and the install-rule blocker in #1919 were also fallout from the same refactor — this looks like the third instance of the data/config side of #1908 not reaching all consumers.