Skip to content

Commit

Permalink
allow to create choppers from centers and widths of cutouts in additi…
Browse files Browse the repository at this point in the history
…on to open and close angles
  • Loading branch information
nvaytet committed Oct 2, 2024
1 parent c232ce9 commit be6bc9c
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.
center:
The center of the chopper cutouts.
width:
The width of the chopper cutouts.
name:
The name of the chopper.
Notes
-----
Either `open` and `close` or `center` and `width` 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,
center: sc.Variable | None = None,
width: 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 center/width are provided, but not both
if tuple(x for x in (open, close, center, width) if x is not None) not in (
(open, close),
(center, width),
):
raise ValueError(
"Either open/close or center/width must be provided, got"
f" open={open}, close={close}, center={center}, width={width}."
)
if open is None:
half_width = width * 0.5
open = center - half_width
close = center + 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
center = sc.array(dims=['cutout'], values=[15.0, 46.0], unit='deg')
width = sc.array(dims=['cutout'], values=[10.0, 16.0], unit='deg')
chopper = tof.Chopper(
frequency=f,
center=center,
width=width,
phase=0.0 * deg,
distance=5.0 * meter,
)
assert sc.allclose(chopper.open, center - width / 2)
assert sc.allclose(chopper.close, center + width / 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 center/width must be provided"
):
tof.Chopper(
frequency=10.0 * Hz,
open=10.0 * deg,
close=20.0 * deg,
center=15.0 * deg,
width=10.0 * deg,
phase=0.0 * deg,
distance=5.0 * meter,
)

0 comments on commit be6bc9c

Please sign in to comment.