Skip to content

add: unbinned detector calibration, unit normalization, and tilt (3/4) - #138

Merged
pecomyint merged 2 commits into
mainfrom
rsm/03-detector-physics
Aug 31, 2026
Merged

add: unbinned detector calibration, unit normalization, and tilt (3/4)#138
pecomyint merged 2 commits into
mainfrom
rsm/03-detector-physics

Conversation

@pecomyint

@pecomyint pecomyint commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Stack 3 of 4. Base rsm/02-naxis-issue132 — retarget to main as the stack merges.

Draft: this is the beam-physics gate. The axis-0 mapping and the tilt/detrot sign conventions cannot be settled without a known reflection. Everything else is verified against xrayutilities directly.

Two silent assumptions removed

DETECTOR_SETUP.UNITS was in every profile and never read, so millimetres were assumed regardless of what the beamline declared. Energy was blindly × 1000, correct only for a keV source. Both produced a plausible-looking, wrong Q with no error.

New dashpva/utils/units.py is one table for length, energy and angle; internal geometry is always eV, mm, degrees. Unknown units raise rather than defaulting — a mis-declared unit is a calibration error, and guessing would reintroduce exactly what this removes. Per-field DISTANCE_UNITS / SIZE_UNITS / PIXEL_SIZE_UNITS override the section default. ENERGY_UNITS defaults to keV so existing profiles keep their scale.

Units are validated at parse time but converted only when the DetectorModel is built. Converting during normalization would leave the stored value and stored unit disagreeing, so a second pass would convert again — caught by the idempotence test.

The binning bug

pixel_width = SIZE / frame_shape silently absorbed binning into the pixel size: a 2×-binned scan produced a Q scale wrong by a factor of two, with no error raised.

center_channel, shape and pixel_width are now explicitly the unbinned full-frame calibration. ROI and binning go to xrayutilities as roi/Nav, which applies them itself — verified in QConversion._get_detparam_area, which does cch/nav, pwidth*nav, and maps an unbinned ROI into binned channels. Pre-shifting the centre here would double-apply that. The legacy SIZE/frame_shape derivation is now permitted only for full-frame unbinned data and rejected by name otherwise.

ROI is half-open in unbinned channels and its span must divide exactly by the binning — xrayutilities would otherwise ceil it and hand back a frame larger than the detector produced. require_frame_shape() rejects a calibration that disagrees with the data instead of yielding a plausible, wrongly-scaled volume.

New degrees of freedom

DETROT / TILT / TILTAZIMUTH, and FRAME_AXIS_ORDER making the detector axis-0 convention explicit and configurable — a transposed volume becomes a profile edit rather than a source change. Q is transposed to the acquired layout so intensity, mask and Q index identically.

detector_model_from_setup() is the single boundary where declared units become canonical; the offline converter and both live paths go through it, and a setup with none of the new keys reproduces the previous model exactly.

Verification

test_detector_physics.py — every Q assertion checked against a hand-built xu.HXRD, not a stored value, so it fails if we stop agreeing with xrayutilities rather than merely changing. Unit equivalence (keV/eV, cm/mm/µm give identical Q), ROI+binning parity at atol=0, exact-divisibility rejection, frame-axis transposition, tilt/detrot parity, and sampleor='det' continuity as detrot → 0 (detrot appends a beam-axis rotation as the innermost detector axis; 'det' ignores beam-parallel rotations, so the limit must be smooth). I also mutation-checked that tilt and detrot genuinely move Q, so the parity tests are not vacuous.

Calibration literals persist to HDF5 through a type-preserving writer — the plain string writer would have reintroduced the repr bug fixed in 687e943.

Blocked on beam

  • Detector axis-0 mapping against a known Bragg peak
  • Tilt / detrot sign conventions vs the beamline's own calibration

@pecomyint

Copy link
Copy Markdown
Collaborator Author

@Osayi-ANL when you get a chance — this one is still unreviewed and it's the beam-physics gate for the trip.

It's the PR whose correctness can't be settled from CI: the detector axis-0 mapping and the tilt/detrot sign conventions need a known reflection. A wrong axis-0 produces a transposed volume that still looks like a plausible diffraction pattern, so it needs a second pair of eyes on the reasoning before we rely on it at the beamline.

Everything else in it is checked against a hand-built xu.HXRD rather than stored values — unit equivalence, ROI+binning parity at atol=0, and sampleor='det' continuity as detrot → 0.

Rebased onto the fixed rsm/02, so git pull first.

@pecomyint
pecomyint force-pushed the rsm/03-detector-physics branch from 5cf7012 to d575f4c Compare August 14, 2026 20:12
@pecomyint

Copy link
Copy Markdown
Collaborator Author

Nudging — this one's still unreviewed and it's the beam-physics gate for the whole stack (unbinned detector calibration, unit normalization, tilt/detrot). #136 is approved, #137 and #139 have fixes in for your latest comments and are re-requested. Would appreciate a look here when you get a chance.

@pecomyint
pecomyint force-pushed the rsm/02-naxis-issue132 branch from 91924cf to f0a44b2 Compare August 24, 2026 22:02
@pecomyint
pecomyint force-pushed the rsm/03-detector-physics branch 2 times, most recently from 3b9b10c to 5b43d9c Compare August 24, 2026 22:11
@pecomyint
pecomyint force-pushed the rsm/02-naxis-issue132 branch from 769f952 to 336ce0d Compare August 24, 2026 22:13
@pecomyint
pecomyint force-pushed the rsm/03-detector-physics branch from 5b43d9c to 66fb8e7 Compare August 24, 2026 22:14
@pecomyint
pecomyint changed the base branch from rsm/02-naxis-issue132 to main August 24, 2026 22:16
@pecomyint
pecomyint force-pushed the rsm/03-detector-physics branch from 66fb8e7 to 8682fdf Compare August 24, 2026 22:16
@pecomyint
pecomyint marked this pull request as ready for review August 29, 2026 00:13
@pecomyint

Copy link
Copy Markdown
Collaborator Author

@Osayi-ANL this is ready for your review whenever you get a chance — marked out of draft and rebased up to date with main (merged in the Python-version-cap fix, no conflicts). CI is green. PR #139 is stacked on top of this one, so it'd be great to get this moving.

@Osayi-ANL Osayi-ANL left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice, can't test the Units at this beam line

@pecomyint
pecomyint merged commit 55951e2 into main Aug 31, 2026
3 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.

2 participants