Skip to content

Commit c0ab18d

Browse files
Merge pull request #633 from scipp/fix-coord-conv-position-unit-mismatch-exception
Fix coord conversion position unit mismatch exceptions
2 parents 5acb18b + a13c773 commit c0ab18d

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

src/scippneutron/conversion/beamline.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@
117117
from .._utils import elem_dtype, elem_unit
118118

119119

120+
def _canonical_length(var: VariableLike) -> VariableLike:
121+
"""Convert a beam length to the canonical unit (meter)."""
122+
return var.to(unit='m', copy=False)
123+
124+
120125
def L1(*, incident_beam: VariableLike) -> VariableLike:
121126
"""Compute the length of the incident beam.
122127
@@ -141,7 +146,7 @@ def L1(*, incident_beam: VariableLike) -> VariableLike:
141146
straight_incident_beam:
142147
Compute the incident beam for a straight beamline.
143148
"""
144-
return sc.norm(incident_beam)
149+
return _canonical_length(sc.norm(incident_beam))
145150

146151

147152
def L2(*, scattered_beam: VariableLike) -> VariableLike:
@@ -168,7 +173,7 @@ def L2(*, scattered_beam: VariableLike) -> VariableLike:
168173
straight_scattered_beam:
169174
Compute the scattered beam for a straight beamline.
170175
"""
171-
return sc.norm(scattered_beam)
176+
return _canonical_length(sc.norm(scattered_beam))
172177

173178

174179
def straight_incident_beam(
@@ -196,7 +201,7 @@ def straight_incident_beam(
196201
:
197202
``incident_beam``
198203
"""
199-
return sample_position - source_position
204+
return _canonical_length(sample_position) - _canonical_length(source_position)
200205

201206

202207
def straight_scattered_beam(
@@ -223,7 +228,7 @@ def straight_scattered_beam(
223228
:
224229
``scattered_beam``
225230
"""
226-
return position - sample_position
231+
return _canonical_length(position) - _canonical_length(sample_position)
227232

228233

229234
def total_beam_length(*, L1: VariableLike, L2: VariableLike) -> VariableLike:
@@ -247,7 +252,7 @@ def total_beam_length(*, L1: VariableLike, L2: VariableLike) -> VariableLike:
247252
:
248253
:math:`L_\\mathsf{total}`
249254
"""
250-
return L1 + L2
255+
return _canonical_length(L1) + _canonical_length(L2)
251256

252257

253258
def total_straight_beam_length_no_scatter(
@@ -274,7 +279,7 @@ def total_straight_beam_length_no_scatter(
274279
:
275280
:math:`L_\\mathsf{total}`
276281
"""
277-
return sc.norm(position - source_position.to(unit=position.unit, copy=False))
282+
return sc.norm(_canonical_length(position) - _canonical_length(source_position))
278283

279284

280285
def two_theta(
@@ -324,6 +329,8 @@ def two_theta(
324329
# and 'it never errs by more than a modest multiple of epsilon'
325330
# where 'epsilon is the roundoff threshold for individual arithmetic
326331
# operations'.
332+
incident_beam = _canonical_length(incident_beam)
333+
scattered_beam = _canonical_length(scattered_beam)
327334
b1 = incident_beam / L1(incident_beam=incident_beam)
328335
b2 = scattered_beam / L2(scattered_beam=scattered_beam)
329336

@@ -543,6 +550,8 @@ def scattering_angles_with_gravity(
543550
Ignores the ``x`` component when computing ``theta``.
544551
This is used in reflectometry.
545552
"""
553+
incident_beam = _canonical_length(incident_beam)
554+
scattered_beam = _canonical_length(scattered_beam)
546555
if sc.any(
547556
abs(sc.dot(gravity, incident_beam))
548557
> sc.scalar(1e-10, unit=incident_beam.unit) * sc.norm(gravity)

tests/conversion/beamline_conversions_test.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ def test_straight_incident_beam():
3535
)
3636
sc.testing.assert_allclose(
3737
incident_beam,
38-
sc.vectors(dims=['siti'], values=[[-33, -75, -17], [-23, -5, -47]], unit='mm'),
38+
sc.vectors(
39+
dims=['siti'], values=[[-33, -75, -17], [-23, -5, -47]], unit='mm'
40+
).to(unit='m'),
3941
)
4042

4143

@@ -47,7 +49,9 @@ def test_straight_scattered_beam():
4749
)
4850
sc.testing.assert_allclose(
4951
scattered_beam,
50-
sc.vectors(dims=['on'], values=[[5.6, 2.4, 8.8], [7.6, 2.4, 0.8]], unit='km'),
52+
sc.vectors(
53+
dims=['on'], values=[[5.6, 2.4, 8.8], [7.6, 2.4, 0.8]], unit='km'
54+
).to(unit='m'),
5155
)
5256

5357

@@ -57,7 +61,10 @@ def test_L1():
5761
)
5862
L1 = beamline.L1(incident_beam=incident_beam)
5963
sc.testing.assert_allclose(
60-
L1, sc.array(dims=['inc'], values=[1.870828693386, 1.122497216032], unit='um')
64+
L1,
65+
sc.array(dims=['inc'], values=[1.870828693386, 1.122497216032], unit='um').to(
66+
unit='m'
67+
),
6168
)
6269

6370

@@ -68,7 +75,9 @@ def test_L2():
6875
L2 = beamline.L2(scattered_beam=scattered_beam)
6976
sc.testing.assert_allclose(
7077
L2,
71-
sc.array(dims=['scat'], values=[41.158231254513, 146.321563687653], unit='am'),
78+
sc.array(
79+
dims=['scat'], values=[41.158231254513, 146.321563687653], unit='am'
80+
).to(unit='m'),
7281
)
7382

7483

@@ -78,7 +87,9 @@ def test_total_beam_length():
7887
Ltotal = beamline.total_beam_length(L1=L1, L2=L2)
7988
sc.testing.assert_allclose(
8089
Ltotal,
81-
sc.array(dims=['secondary'], values=[8.27559, 47.134, 1004.134], unit='cm'),
90+
sc.array(dims=['secondary'], values=[8.27559, 47.134, 1004.134], unit='cm').to(
91+
unit='m'
92+
),
8293
)
8394

8495

@@ -672,7 +683,7 @@ def test_scattering_angles_with_gravity_supports_mismatching_units(g: list[float
672683
sc.testing.assert_allclose(
673684
res['two_theta'], expected['two_theta'], rtol=sc.scalar(1e-6)
674685
)
675-
sc.testing.assert_allclose(res['phi'], expected['phi'])
686+
sc.testing.assert_allclose(res['phi'], expected['phi'], rtol=sc.scalar(1e-6))
676687

677688

678689
@given(rotation=rotations())

0 commit comments

Comments
 (0)