fix: make SBT beam placement frames right-handed#70
Conversation
The corner-beam and stiffening-frame builders constructed the local placement frame with columns (b, n, d) but computed b = d x n, giving det = -1: every such placement carried a reflection instead of a pure rotation. GeoModel2G4 forwards these matrices to CLHEP::HepRotation, which emitted a ZMxpvImproperRotation warning for each of the 180 affected placements at Geant4 initialisation. Use b = n x d so the frame is right-handed. The placed shapes are boxes symmetric under local X -> -X and all offsets are applied along n, so the resulting geometry is unchanged: the regenerated database differs only in the sign of the first rotation column of the 180 formerly-improper transforms.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe H-beam placement rotation frames now use the opposite cross-product operand order for inclined beams and apply the corresponding orientation update to longitudinal beams. ChangesBeam rotation-frame orientation
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai rate limit |
|
Your plan includes PR reviews subject to rate limits. More reviews will be available in 1 minute. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
matclim
left a comment
There was a problem hiding this comment.
Verified the claims against the code rather than the description:
det = −1→+1confirmed for all beam directions including the degenerate branch; the new expression is exactlyn × d.- "Geometry unchanged" confirmed independently: rebuilding all 572 SBT volumes under both conventions gives 572/572 identical occupied regions, 0 moved, and exactly 180 with permuted vertex ordering — matching your count from a completely separate construction.
- Fix is complete: these are the only two hand-built frames in
DecayVolume;rotZinSBTSensorBuildercomes fromAngleAxisdand is proper by construction.
Worth stating in the description that negating b rather than n is the only safe fix: offsets are applied along n, so negating n would swap TF and BF, and the inner flange is what bounds the helium in Y.
One suggestion, non-blocking: add a test asserting getXToChildVol(i).linear().determinant() > 0 over the tree. test_decayvolume already walks it for the overlap check, so it's ~10 lines, and it pins this permanently — including for any future builder, given the frame construction is duplicated across both sites.
Also: #68 touches the same file. Should auto-merge, but re-run whichever lands second.
Problem
Running any Geant4 job on the generated geometry emits 180 CLHEP warnings at initialisation:
The corner-beam and stiffening-frame builders in
SBTStructureBuilder.cppconstruct the local placement frame with columns (b, n, d) but compute b = d × n. For that column order det[b n d] = (d×n)·(n×d) = −|n×d|² < 0, so the frame is left-handed and every such placement carries a reflection instead of a pure rotation — despite the comment claiming a right-handed frame. GeoModel2G4 forwards these matrices toCLHEP::HepRotation, which warns once per placement: 40 corner beams × 3 pieces + 30 stiffening-frame long beams × 2 flanges = 180.Fix
Compute b = n × d at both sites so the frame is right-handed.
This does not change the geometry: the placed shapes are
GeoBoxes symmetric under local X → −X, and all piece offsets are applied along n (local Y), so negating the local X axis places identical boxes identically.Verification
ship_geometry.dbbefore/after the fix at the same commit: reflection transforms (det < 0) go from 180 → 0, and the diff shows exactly the 180 formerly-improper transforms with only the first rotation column negated — all 316,418 other transforms are byte-identical (translations, other columns, and all other tables unchanged).pixi run test: 39/39 pass, including the overlap check;validate_geometryis clean.gun_st_geomodel, thenfixed_target_mt): old DB produces the warnings, regenerated DB produces none, runs complete normally.Summary by CodeRabbit