ophyd_devices/tests/test_grashopper_tomcat.py

227 lines
8.8 KiB
Python

# pylint: skip-file
import pytest
from unittest import mock
from ophyd_devices.epics.devices.grashopper_tomcat import (
GrashopperTOMCATSetup,
AutoMode,
ImageMode,
DetectorState,
ImageBinning,
VideoMode,
PixelFormat,
COLORMODE,
TriggerSource,
MemoryPolling,
GrashopperError,
GrashopperTimeoutError,
)
def patch_dual_pvs(device):
for walk in device.walk_signals():
if not hasattr(walk.item, "_read_pv"):
continue
if not hasattr(walk.item, "_write_pv"):
continue
if walk.item._read_pv.pvname.endswith("_RBV"):
walk.item._read_pv = walk.item._write_pv
@pytest.fixture(scope="function")
def mock_GrashopperSetup():
mock_Grashopper = mock.MagicMock()
yield GrashopperTOMCATSetup(parent=mock_Grashopper)
# Fixture for scaninfo
@pytest.fixture(
params=[
{
"scanID": "1234",
"scan_type": "step",
"num_points": 500,
"frames_per_trigger": 1,
"exp_time": 0.1,
"readout_time": 0.1,
},
{
"scanID": "1234",
"scan_type": "step",
"num_points": 500,
"frames_per_trigger": 5,
"exp_time": 0.01,
"readout_time": 0,
},
{
"scanID": "1234",
"scan_type": "fly",
"num_points": 500,
"frames_per_trigger": 1,
"exp_time": 1,
"readout_time": 0.2,
},
{
"scanID": "1234",
"scan_type": "fly",
"num_points": 500,
"frames_per_trigger": 5,
"exp_time": 0.1,
"readout_time": 0.4,
},
]
)
def scaninfo(request):
return request.param
def test_initialize_detector(mock_GrashopperSetup):
"""Test the initialize_detector method."""
# Call the function you want to test
mock_GrashopperSetup.initialize_detector()
# Assert the correct methods are called with the expected arguments
mock_GrashopperSetup.parent.cam.acquire.put.assert_called_once_with(0)
mock_GrashopperSetup.parent.cam.acquire_time_auto.put.assert_called_once_with(
AutoMode.CONTINUOUS
)
mock_GrashopperSetup.parent.cam.gain_auto.put.assert_called_once_with(AutoMode.CONTINUOUS)
mock_GrashopperSetup.parent.cam.image_mode.put.assert_called_once_with(ImageMode.MULTIPLE)
mock_GrashopperSetup.parent.cam.image_binning.put.assert_called_once_with(ImageBinning.X1)
mock_GrashopperSetup.parent.cam.video_mode.put.assert_called_once_with(VideoMode.MODE0)
mock_GrashopperSetup.parent.cam.pixel_format.put.assert_called_once_with(PixelFormat.MONO16)
mock_GrashopperSetup.parent.cam.trigger_source.put.assert_called_once_with(
TriggerSource.SOFTWARE
)
mock_GrashopperSetup.parent.cam.memory_polling.put.assert_called_once_with(
MemoryPolling.SECONDS1
)
mock_GrashopperSetup.parent.cam.set_image_counter.put.assert_called_once_with(0)
def test_initialize_detector_backend(mock_GrashopperSetup):
"""Test the initialize_detector_backend method."""
# Call the function you want to test
mock_GrashopperSetup.initialize_detector_backend()
# Assert the correct methods are called with the expected arguments
mock_GrashopperSetup.parent.image.queue_size.put.assert_called_once_with(5)
mock_GrashopperSetup.parent.image.array_port.put.assert_called_once_with(
mock_GrashopperSetup.parent.cam.port_name.get()
)
mock_GrashopperSetup.parent.image.enable_cb.put.assert_called_once_with(1)
mock_GrashopperSetup.parent.image.set_array_counter.put.assert_called_once_with(0)
@pytest.mark.parametrize("exposure_time", [1, 0.1, 0.01, 0.001, 0.0001])
def test_set_exposure_time(mock_GrashopperSetup, exposure_time):
"""Test the set_exposure_time method."""
# Call the function you want to test
frame_rate = 1 / exposure_time
if frame_rate > mock_GrashopperSetup.low_frame_rate:
with pytest.raises(GrashopperError):
mock_GrashopperSetup.set_exposure_time(exposure_time)
else:
mock_GrashopperSetup.set_exposure_time(exposure_time)
mock_GrashopperSetup.parent.cam.frame_rate.put.assert_called_once_with(frame_rate)
def test_prepare_detector(mock_GrashopperSetup, scaninfo):
"""Test the prepare_detector method."""
# setup scaninof
for k, v in scaninfo.items():
setattr(mock_GrashopperSetup.parent.scaninfo, k, v)
# Call the function you want to test
with mock.patch.object(
mock_GrashopperSetup, "set_acquisition_params"
) as mock_set_acquisition_params, mock.patch.object(
mock_GrashopperSetup, "set_exposure_time"
) as mock_set_exposure_time:
mock_GrashopperSetup.prepare_detector()
# Assert the correct methods are called with the expected arguments
mock_GrashopperSetup.parent.cam.image_mode.put.assert_called_once_with(ImageMode.MULTIPLE)
mock_GrashopperSetup.parent.cam.acquire_time_auto.put.assert_called_once_with(
AutoMode.CONTINUOUS
)
mock_GrashopperSetup.parent.set_trigger.assert_called_once_with(TriggerSource.SOFTWARE)
mock_GrashopperSetup.parent.cam.set_image_counter.put.assert_called_once_with(0)
mock_set_acquisition_params.assert_called_once()
mock_set_exposure_time.assert_called_once_with(scaninfo["exp_time"])
def test_prepare_detector_backend(mock_GrashopperSetup):
"""Test the prepare_detector_backend method."""
# Call the function you want to test
with mock.patch.object(mock_GrashopperSetup, "run_monitor") as mock_run_monitor:
mock_GrashopperSetup.prepare_detector_backend()
# Assert the correct methods are called with the expected arguments
mock_GrashopperSetup.parent.image.set_array_counter.put.assert_called_once_with(0)
assert mock_GrashopperSetup.monitor_thread is None
assert not mock_GrashopperSetup.stop_monitor
mock_run_monitor.assert_called_once()
@pytest.mark.parametrize("detector_state", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
def test_arm_acquisition(mock_GrashopperSetup, detector_state):
"""Test the arm_acquisition method."""
# Call the function you want to test
mock_GrashopperSetup.parent.cam.detector_state.get.return_value = detector_state
mock_GrashopperSetup.parent.timeout = 0.1
if detector_state != DetectorState.WAITING:
with pytest.raises(GrashopperTimeoutError):
mock_GrashopperSetup.arm_acquisition()
assert mock_GrashopperSetup.parent.cam.acquire.put.call_count == 1
assert mock_GrashopperSetup.parent.cam.acquire.put.call_args == mock.call(1)
else:
mock_GrashopperSetup.arm_acquisition()
assert mock_GrashopperSetup.parent.cam.acquire.put.call_count == 1
assert mock_GrashopperSetup.parent.cam.acquire.put.call_args == mock.call(1)
@pytest.mark.parametrize("trigger_source", [0, 1, 2, 3])
def test_on_trigger(mock_GrashopperSetup, trigger_source):
"""Test the on_trigger method."""
# Call the function you want to test
mock_GrashopperSetup.parent.cam.trigger_source.get.return_value = trigger_source
mock_GrashopperSetup.on_trigger()
# Assert the correct methods are called with the expected arguments
if trigger_source == TriggerSource.SOFTWARE:
mock_GrashopperSetup.parent.cam.software_trigger.put.assert_called_once_with(1)
def test_set_acquisition_params(mock_GrashopperSetup, scaninfo):
"""Test the set_acquisition_params method."""
# Setup scaninfo
mock_GrashopperSetup.parent.scaninfo.num_points = scaninfo["num_points"]
mock_GrashopperSetup.parent.scaninfo.frames_per_trigger = scaninfo["frames_per_trigger"]
# Call the function you want to test
mock_GrashopperSetup.set_acquisition_params()
# Assert the correct methods are called with the expected arguments
expected_num_images = scaninfo["num_points"] * scaninfo["frames_per_trigger"]
mock_GrashopperSetup.parent.cam.num_images.put.assert_called_once_with(expected_num_images)
@pytest.mark.parametrize("detector_state", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
def test_stop_detector(mock_GrashopperSetup, detector_state):
"""Test the arm_acquisition method."""
# Call the function you want to test
mock_GrashopperSetup.parent.cam.detector_state.get.return_value = detector_state
mock_GrashopperSetup.parent.timeout = 0.1
if detector_state != DetectorState.IDLE:
with pytest.raises(GrashopperTimeoutError):
mock_GrashopperSetup.stop_detector()
assert mock_GrashopperSetup.parent.cam.acquire.put.call_count == 2
assert mock_GrashopperSetup.parent.cam.acquire.put.call_args == mock.call(0)
else:
mock_GrashopperSetup.stop_detector()
assert mock_GrashopperSetup.parent.cam.acquire.put.call_count == 1
assert mock_GrashopperSetup.parent.cam.acquire.put.call_args == mock.call(0)