Skip to content

Commit

Permalink
Merge pull request #54 from scipp/define-chopper-widths-centers
Browse files Browse the repository at this point in the history
Allow to create choppers from centers and widths of cutouts
  • Loading branch information
nvaytet authored Oct 3, 2024
2 parents c232ce9 + 8d61a48 commit 5c855ef
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/tof/chopper.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ class Chopper:
----------
frequency:
The frequency of the chopper. Must be positive.
open:
The opening angles of the chopper cutouts.
close:
The closing angles of the chopper cutouts.
distance:
The distance from the source to the chopper.
phase:
Expand All @@ -41,17 +37,32 @@ class Chopper:
to the chopper rotation direction. For example, if the chopper rotates
clockwise, a phase of 10 degrees will shift all window angles by 10 degrees
in the anticlockwise direction, which will result in the windows opening later.
open:
The opening angles of the chopper cutouts.
close:
The closing angles of the chopper cutouts.
centers:
The centers of the chopper cutouts.
widths:
The widths of the chopper cutouts.
name:
The name of the chopper.
Notes
-----
Either `open` and `close` or `centers` and `widths` must be provided, but not both.
"""

def __init__(
self,
*,
frequency: sc.Variable,
open: sc.Variable,
close: sc.Variable,
distance: sc.Variable,
phase: sc.Variable,
open: sc.Variable | None = None,
close: sc.Variable | None = None,
centers: sc.Variable | None = None,
widths: sc.Variable | None = None,
direction: Direction = Clockwise,
name: str = "",
):
Expand All @@ -64,6 +75,20 @@ def __init__(
f", got {direction}."
)
self.direction = direction
# Check that either open/close or centers/widths are provided, but not both
if tuple(x for x in (open, close, centers, widths) if x is not None) not in (
(open, close),
(centers, widths),
):
raise ValueError(
"Either open/close or centers/widths must be provided, got"
f" open={open}, close={close}, centers={centers}, widths={widths}."
)
if open is None:
half_width = widths * 0.5
open = centers - half_width
close = centers + half_width

self.open = (open if open.dims else open.flatten(to='cutout')).to(
dtype=float, copy=False
)
Expand Down
40 changes: 40 additions & 0 deletions tests/chopper_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,43 @@ def test_bad_direction_raises():
distance=d,
direction=1,
)


def test_chopper_create_from_centers_and_widths():
f = 10.0 * Hz
centers = sc.array(dims=['cutout'], values=[15.0, 46.0], unit='deg')
widths = sc.array(dims=['cutout'], values=[10.0, 16.0], unit='deg')
chopper = tof.Chopper(
frequency=f,
centers=centers,
widths=widths,
phase=0.0 * deg,
distance=5.0 * meter,
)
assert sc.allclose(chopper.open, centers - widths / 2)
assert sc.allclose(chopper.close, centers + widths / 2)

expected = tof.Chopper(
frequency=f,
open=sc.array(dims=['cutout'], values=[10.0, 38.0], unit='deg'),
close=sc.array(dims=['cutout'], values=[20.0, 54.0], unit='deg'),
phase=0.0 * deg,
distance=5.0 * meter,
)
assert sc.allclose(chopper.open, expected.open)
assert sc.allclose(chopper.close, expected.close)


def test_chopper_create_raises_when_both_edges_and_centers_are_supplied():
with pytest.raises(
ValueError, match="Either open/close or centers/widths must be provided"
):
tof.Chopper(
frequency=10.0 * Hz,
open=10.0 * deg,
close=20.0 * deg,
centers=15.0 * deg,
widths=10.0 * deg,
phase=0.0 * deg,
distance=5.0 * meter,
)

0 comments on commit 5c855ef

Please sign in to comment.