add: unbinned detector calibration, unit normalization, and tilt (3/4) - #138
Conversation
6c8c969 to
5cf7012
Compare
|
@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 Rebased onto the fixed |
5cf7012 to
d575f4c
Compare
91924cf to
f0a44b2
Compare
3b9b10c to
5b43d9c
Compare
769f952 to
336ce0d
Compare
5b43d9c to
66fb8e7
Compare
66fb8e7 to
8682fdf
Compare
|
@Osayi-ANL this is ready for your review whenever you get a chance — marked out of draft and rebased up to date with |
Osayi-ANL
left a comment
There was a problem hiding this comment.
Nice, can't test the Units at this beam line
Stack 3 of 4. Base
rsm/02-naxis-issue132— retarget tomainas 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.UNITSwas 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.pyis 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-fieldDISTANCE_UNITS/SIZE_UNITS/PIXEL_SIZE_UNITSoverride the section default.ENERGY_UNITSdefaults to keV so existing profiles keep their scale.Units are validated at parse time but converted only when the
DetectorModelis 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_shapesilently 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,shapeandpixel_widthare now explicitly the unbinned full-frame calibration. ROI and binning go to xrayutilities asroi/Nav, which applies them itself — verified inQConversion._get_detparam_area, which doescch/nav,pwidth*nav, and maps an unbinned ROI into binned channels. Pre-shifting the centre here would double-apply that. The legacySIZE/frame_shapederivation 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
ceilit 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, andFRAME_AXIS_ORDERmaking 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-builtxu.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 atatol=0, exact-divisibility rejection, frame-axis transposition, tilt/detrot parity, andsampleor='det'continuity asdetrot → 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