Skip to content

Commit

Permalink
Merge pull request #51 from scipp/fix-open-times-anticlockwise
Browse files Browse the repository at this point in the history
Fix chopper open and close times when direction is anticlockwise
  • Loading branch information
nvaytet authored Oct 2, 2024
2 parents 1579314 + c300352 commit c232ce9
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
18 changes: 9 additions & 9 deletions src/tof/chopper.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,10 @@ def open_close_times(
# large
phases = sc.arange(uuid.uuid4().hex, -1, nrot) * two_pi + self.phase.to(
unit='rad'
) * ({Clockwise: 1, AntiClockwise: -1}[self.direction])
# Note that the order is important here: we need (phases + open/close) to get
# the correct dimension order when we flatten below.
open_times = (phases + self.open.to(unit='rad', copy=False)).flatten(
to=self.open.dim
)
close_times = (phases + self.close.to(unit='rad', copy=False)).flatten(
to=self.close.dim
)

open_times = self.open.to(unit='rad', copy=False)
close_times = self.close.to(unit='rad', copy=False)
# If the chopper is rotating anti-clockwise, we mirror the openings because the
# first cutout will be the last to open.
if self.direction == AntiClockwise:
Expand All @@ -130,6 +125,10 @@ def open_close_times(
unit=open_times.unit,
),
)
# Note that the order is important here: we need (phases + open/close) to get
# the correct dimension order when we flatten.
open_times = (phases + open_times).flatten(to=self.open.dim)
close_times = (phases + close_times).flatten(to=self.close.dim)
open_times /= self.omega
close_times /= self.omega
return (
Expand All @@ -141,7 +140,7 @@ def __repr__(self) -> str:
return (
f"Chopper(name={self.name}, distance={self.distance:c}, "
f"frequency={self.frequency:c}, phase={self.phase:c}, "
f"cutouts={len(self.open)})"
f"direction={self.direction.name}, cutouts={len(self.open)})"
)

def as_dict(self):
Expand All @@ -152,6 +151,7 @@ def as_dict(self):
'distance': self.distance,
'phase': self.phase,
'name': self.name,
'direction': self.direction,
}


Expand Down
37 changes: 32 additions & 5 deletions tests/chopper_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,10 @@ def test_open_close_times_counter_rotation():
direction=tof.AntiClockwise,
)

topen1, tclose1 = chopper1.open_close_times(0.2 * sec)
topen1, tclose1 = chopper1.open_close_times(0.0 * sec)
topen2, tclose2 = chopper2.open_close_times(0.0 * sec)
# Note that the first chopper will have one more rotation before t=0, so we slice
# out the first two open/close times
assert sc.allclose(topen1[2:], topen2)
assert sc.allclose(tclose1[2:], tclose2)
assert sc.allclose(topen1, topen2)
assert sc.allclose(tclose1, tclose2)


def test_open_close_times_counter_rotation_with_phase():
Expand Down Expand Up @@ -209,6 +207,35 @@ def test_open_close_times_counter_rotation_with_phase():
)


def test_open_close_anticlockwise_multiple_rotations():
chopper = tof.Chopper(
frequency=10.0 * Hz,
open=sc.array(dims=["cutout"], values=[10.0, 90.0], unit="deg"),
close=sc.array(dims=["cutout"], values=[20.0, 130.0], unit="deg"),
distance=10.0 * meter,
phase=0 * deg,
direction=tof.AntiClockwise,
)

two_rotations_open, two_rotations_close = chopper.open_close_times(0.0 * sec)
three_rotations_open, three_rotations_close = chopper.open_close_times(0.2 * sec)
four_rotations_open, four_rotations_close = chopper.open_close_times(0.3 * sec)

assert len(two_rotations_open) == 4
assert len(three_rotations_open) == 6
assert len(four_rotations_open) == 8
assert len(two_rotations_close) == 4
assert len(three_rotations_close) == 6
assert len(four_rotations_close) == 8

assert sc.allclose(two_rotations_open, three_rotations_open[:-2])
assert sc.allclose(two_rotations_close, three_rotations_close[:-2])
assert sc.allclose(three_rotations_open, four_rotations_open[:-2])
assert sc.allclose(three_rotations_close, four_rotations_close[:-2])
assert sc.allclose(two_rotations_open, four_rotations_open[:-4])
assert sc.allclose(two_rotations_close, four_rotations_close[:-4])


def test_bad_direction_raises():
f = 10.0 * Hz
op = sc.array(dims=['cutout'], values=[10.0], unit='deg')
Expand Down

0 comments on commit c232ce9

Please sign in to comment.