Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to enable dev shm streaming on eiger #560

Merged
merged 5 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/dodal/devices/detector/detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class DetectorParams(BaseModel):
detector_size_constants: DetectorSizeConstants = EIGER2_X_16M_SIZE
beam_xy_converter: DetectorDistanceToBeamXYConverter
run_number: int
enable_dev_shm: bool = (
False # Remove in https://github.com/DiamondLightSource/hyperion/issues/1395
)

class Config:
arbitrary_types_allowed = True
Expand Down
8 changes: 8 additions & 0 deletions src/dodal/devices/eiger.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ def stop(self, *args):
self.disarm_detector()
stop_status &= self.disable_roi_mode()
stop_status.wait(self.GENERAL_STATUS_TIMEOUT)
# See https://github.com/DiamondLightSource/hyperion/issues/1395
LOGGER.info("Turning off Eiger dev/shm streaming")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If we have enable_dev_shm set to off, I think we will get a logging message during change_dev_shm, and in Hyperion when XRC finishes, and again here - all saying that dev shm is being disabled

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that given the consequence of leaving it on accidentally is very bad it's actually good to be very specific in the logs that we're turning it off even if that doesn't actually matter

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, makes sense

self.odin.fan.dev_shm_enable.set(0).wait()
LOGGER.info("Eiger has successfully been stopped")

def disable_roi_mode(self):
Expand Down Expand Up @@ -320,6 +323,10 @@ def forward_bit_depth_to_filewriter(self):
self.GENERAL_STATUS_TIMEOUT
)

def change_dev_shm(self, enable_dev_shm: bool):
LOGGER.info(f"{'Enabling' if enable_dev_shm else 'Disabling'} dev shm")
return self.odin.fan.dev_shm_enable.set(1 if enable_dev_shm else 0)

def disarm_detector(self):
self.cam.acquire.set(0).wait(self.GENERAL_STATUS_TIMEOUT)

Expand All @@ -330,6 +337,7 @@ def do_arming_chain(self) -> Status:
functions_to_do_arm.append(self.enable_roi_mode)

arming_sequence_funcs = [
lambda: self.change_dev_shm(detector_params.enable_dev_shm),
lambda: self.set_detector_threshold(detector_params.expected_energy_ev),
self.set_cam_pvs,
self.set_odin_number_of_frame_chunks,
Expand Down
1 change: 1 addition & 0 deletions src/dodal/devices/eiger_odin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class EigerFan(Device):
series = Component(EpicsSignalRO, "CurrentSeries_RBV")
offset = Component(EpicsSignalRO, "CurrentOffset_RBV")
forward_stream = Component(EpicsSignalWithRBV, "ForwardStream")
dev_shm_enable = Component(EpicsSignalWithRBV, "DevShmCache")


class OdinMetaListener(Device):
Expand Down
47 changes: 40 additions & 7 deletions tests/devices/unit_tests/test_eiger.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,16 @@ def test_given_failing_odin_when_stage_then_exception_raised(fake_eiger):
assert error_contents in e.value.__str__()


def set_up_eiger_to_stage_happily(fake_eiger: EigerDetector):
fake_eiger.odin.nodes.clear_odin_errors = MagicMock()
fake_eiger.odin.check_odin_initialised = MagicMock(return_value=(True, ""))
fake_eiger.odin.file_writer.file_path.put(True)


@patch("dodal.devices.eiger.await_value")
def test_stage_runs_successfully(mock_await, fake_eiger: EigerDetector):
mock_await.return_value = finished_status()
fake_eiger.odin.nodes.clear_odin_errors = MagicMock()
fake_eiger.odin.check_odin_initialised = MagicMock()
fake_eiger.odin.check_odin_initialised.return_value = (True, "")
fake_eiger.odin.file_writer.file_path.put(True)
set_up_eiger_to_stage_happily(fake_eiger)
fake_eiger.stage()
fake_eiger.arming_status.wait(1) # This should complete long before 1s

Expand All @@ -363,9 +366,7 @@ def test_given_stale_parameters_goes_high_before_callbacks_then_stale_parameters
fake_eiger: EigerDetector,
):
mock_await.return_value = Status(done=True)
fake_eiger.odin.nodes.clear_odin_errors = MagicMock()
fake_eiger.odin.check_odin_initialised = MagicMock(return_value=(True, ""))
fake_eiger.odin.file_writer.file_path.put(True)
set_up_eiger_to_stage_happily(fake_eiger)

mock_eiger_odin_statuses(fake_eiger)

Expand Down Expand Up @@ -689,3 +690,35 @@ def test_stop_eiger_waits_for_status_functions_to_complete(
):
fake_eiger.stop()
mock_wait.assert_called()


@pytest.mark.parametrize(
"enable_dev_shm, expected_set",
[
(True, 1),
(False, 0),
],
)
@patch("dodal.devices.eiger.await_value")
def test_given_dev_shm_when_stage_then_correctly_enable_disable_dev_shm(
mock_await,
enable_dev_shm: bool,
expected_set: int,
fake_eiger: EigerDetector,
):
mock_await.return_value = finished_status()
set_up_eiger_to_stage_happily(fake_eiger)

fake_eiger.detector_params.enable_dev_shm = enable_dev_shm # type:ignore

fake_eiger.stage()

assert fake_eiger.odin.fan.dev_shm_enable.get() == expected_set


def test_when_eiger_is_stopped_then_dev_shm_disabled(fake_eiger: EigerDetector):
fake_eiger.odin.fan.dev_shm_enable.sim_put(1) # type:ignore

fake_eiger.stop()

assert fake_eiger.odin.fan.dev_shm_enable.get() == 0
Loading