From 98ace2c4b76e40409b0f3b71787f614f4e6da59d Mon Sep 17 00:00:00 2001 From: Stephen Thompson Date: Wed, 4 Oct 2023 08:40:00 +0100 Subject: [PATCH] Issue #28 added note re smoothing in docs and a test to check it's working --- sksurgerynditracker/nditracker.py | 5 +- tests/polaris_mocks.py | 15 +- ...st_sksurgerynditracker_mockndi_getframe.py | 151 ++++++++++++++++++ 3 files changed, 162 insertions(+), 9 deletions(-) diff --git a/sksurgerynditracker/nditracker.py b/sksurgerynditracker/nditracker.py index 8f9f490..cc21639 100644 --- a/sksurgerynditracker/nditracker.py +++ b/sksurgerynditracker/nditracker.py @@ -116,7 +116,10 @@ def __init__(self, configuration): ports to probe: - use quaternions: + use quaternions: default is false + + smoothing buffer: specify a buffer over which to average the + tracking, defaults to 1 :raises Exception: IOError, KeyError, OSError """ diff --git a/tests/polaris_mocks.py b/tests/polaris_mocks.py index a92a04f..2b5d3a8 100644 --- a/tests/polaris_mocks.py +++ b/tests/polaris_mocks.py @@ -13,14 +13,13 @@ "data/8700339.rom"] } -SETTINGS_POLARIS_QUAT = { - "tracker type": "polaris", - "ports to probe": 20, - "romfiles" : [ - "data/something_else.rom", - "data/8700339.rom"], - "use quaternions": "true" - } +SETTINGS_POLARIS_QUAT = SETTINGS_POLARIS.copy() +SETTINGS_POLARIS_QUAT["use quaternions"] = "true" + +SETTINGS_POLARIS_SMOOTH = SETTINGS_POLARIS.copy() +SETTINGS_POLARIS_QUAT_SMOOTH = SETTINGS_POLARIS_QUAT.copy() +SETTINGS_POLARIS_SMOOTH["smoothing buffer"] = 2 +SETTINGS_POLARIS_QUAT_SMOOTH["smoothing buffer"] = 2 class MockPort: """A fake serial port for ndi""" diff --git a/tests/test_sksurgerynditracker_mockndi_getframe.py b/tests/test_sksurgerynditracker_mockndi_getframe.py index 3814057..02e1500 100644 --- a/tests/test_sksurgerynditracker_mockndi_getframe.py +++ b/tests/test_sksurgerynditracker_mockndi_getframe.py @@ -6,6 +6,7 @@ from sksurgerynditracker.nditracker import NDITracker from tests.polaris_mocks import SETTINGS_POLARIS, SETTINGS_POLARIS_QUAT, \ + SETTINGS_POLARIS_SMOOTH, SETTINGS_POLARIS_QUAT_SMOOTH, \ mockndiProbe, \ mockndiOpen, mockndiGetError, mockComports, \ mockndiGetPHSRHandle, mockndiVER, \ @@ -160,3 +161,153 @@ def test_getframe_missing(mocker): assert np.all(np.isnan(tracking_quality)) del tracker + +def test_getframe_smooth_mock(mocker): + """ + connects and configures, mocks ndicapy.ndiProbe to pass + reqs: 03, 04 + """ + tracker = None + bxsource = MockBXFrameSource() + ndidevice = MockNDIDevice() + mocker.patch('serial.tools.list_ports.comports', mockComports) + mocker.patch('ndicapy.ndiProbe', mockndiProbe) + mocker.patch('ndicapy.ndiOpen', mockndiOpen) + mocker.patch('ndicapy.ndiCommand', ndidevice.mockndiCommand) + mocker.patch('ndicapy.ndiGetError', mockndiGetError) + mocker.patch('ndicapy.ndiClose') + mocker.patch('ndicapy.ndiGetPHSRNumberOfHandles', + ndidevice.mockndiGetPHSRNumberOfHandles) + mocker.patch('ndicapy.ndiGetPHRQHandle', ndidevice.mockndiGetPHRQHandle) + mocker.patch('ndicapy.ndiPVWRFromFile') + mocker.patch('ndicapy.ndiGetPHSRHandle', mockndiGetPHSRHandle) + mocker.patch('ndicapy.ndiVER', mockndiVER) + mocker.patch('ndicapy.ndiGetBXFrame', bxsource.mockndiGetBXFrame) + mocker.patch('ndicapy.ndiGetBXTransform', bxsource.mockndiGetBXTransform) + + tracker = NDITracker(SETTINGS_POLARIS_SMOOTH) + + bxsource.setdevice(ndidevice) + + (port_handles, time_stamps, frame_numbers, tracking, + tracking_quality ) = tracker.get_frame() + + assert len(port_handles) == 2 + assert len(time_stamps) == 2 + assert frame_numbers.count(1) == 2 + expected_tracking_0 = np.array([[1.,0.,0.,10.], + [0.,1.,0.,-20.], + [0.,0.,1.,5.], + [0.,0.,0.,1.]]) + assert np.array_equal(expected_tracking_0, tracking[0]) + expected_tracking_1 = np.array([[1.,0.,0.,0.], + [0.,1.,0.,0.], + [0.,0.,1.,0.], + [0.,0.,0.,1.]]) + assert np.array_equal(expected_tracking_1, tracking[1]) + assert tracking_quality.count(1.) == 2 + + (port_handles, time_stamps, frame_numbers, tracking, + tracking_quality ) = tracker.get_frame() + + assert len(port_handles) == 2 + assert len(time_stamps) == 2 + assert frame_numbers.count(2) == 2 + expected_tracking_0 = np.array([[1.,0.,0.,15.], + [0.,1.,0.,-30.], + [0.,0.,1.,7.5], + [0.,0.,0.,1.]]) + assert np.array_equal(expected_tracking_0, tracking[0]) + assert np.array_equal(expected_tracking_1, tracking[1]) + assert tracking_quality.count(1.) == 2 + + del tracker + +def test_getframe_smooth_mock_quat(mocker): + """ + Checks that get frame works with quaternions + """ + tracker = None + bxsource = MockBXFrameSource() + ndidevice = MockNDIDevice() + mocker.patch('serial.tools.list_ports.comports', mockComports) + mocker.patch('ndicapy.ndiProbe', mockndiProbe) + mocker.patch('ndicapy.ndiOpen', mockndiOpen) + mocker.patch('ndicapy.ndiCommand', ndidevice.mockndiCommand) + mocker.patch('ndicapy.ndiGetError', mockndiGetError) + mocker.patch('ndicapy.ndiClose') + mocker.patch('ndicapy.ndiGetPHSRNumberOfHandles', + ndidevice.mockndiGetPHSRNumberOfHandles) + mocker.patch('ndicapy.ndiGetPHRQHandle', ndidevice.mockndiGetPHRQHandle) + mocker.patch('ndicapy.ndiPVWRFromFile') + mocker.patch('ndicapy.ndiGetPHSRHandle', mockndiGetPHSRHandle) + mocker.patch('ndicapy.ndiVER', mockndiVER) + mocker.patch('ndicapy.ndiGetBXFrame', bxsource.mockndiGetBXFrame) + mocker.patch('ndicapy.ndiGetBXTransform', bxsource.mockndiGetBXTransform) + + tracker = NDITracker(SETTINGS_POLARIS_QUAT_SMOOTH) + + bxsource.setdevice(ndidevice) + + (port_handles, time_stamps, frame_numbers, tracking, + tracking_quality ) = tracker.get_frame() + + assert len(port_handles) == 2 + assert len(time_stamps) == 2 + assert frame_numbers.count(1) == 2 + expected_tracking_0 = np.array([[1.,0.,0.,0.,10.,-20,5.]]) + assert np.array_equal(expected_tracking_0, tracking[0]) + expected_tracking_1 = np.array([[1.,0.,0.,0.,0.,0.,0.]]) + assert np.array_equal(expected_tracking_1, tracking[1]) + assert tracking_quality.count(1.) == 2 + + (port_handles, time_stamps, frame_numbers, tracking, + tracking_quality ) = tracker.get_frame() + + assert len(port_handles) == 2 + assert len(time_stamps) == 2 + assert frame_numbers.count(2) == 2 + expected_tracking_0 = np.array([[1.,0.,0.,0.,15.,-30,7.5]]) + assert np.array_equal(expected_tracking_0, tracking[0]) + assert np.array_equal(expected_tracking_1, tracking[1]) + assert tracking_quality.count(1.) == 2 + + del tracker + +def test_getframe_missing_smooth(mocker): + """ + connects and configures, mocks ndicapy.ndiProbe to pass + reqs: 03, 04 + """ + tracker = None + bxsource = MockBXFrameSource() + ndidevice = MockNDIDevice() + mocker.patch('serial.tools.list_ports.comports', mockComports) + mocker.patch('ndicapy.ndiProbe', mockndiProbe) + mocker.patch('ndicapy.ndiOpen', mockndiOpen) + mocker.patch('ndicapy.ndiCommand', ndidevice.mockndiCommand) + mocker.patch('ndicapy.ndiGetError', mockndiGetError) + mocker.patch('ndicapy.ndiClose') + mocker.patch('ndicapy.ndiGetPHSRNumberOfHandles', + ndidevice.mockndiGetPHSRNumberOfHandles) + mocker.patch('ndicapy.ndiGetPHRQHandle', ndidevice.mockndiGetPHRQHandle) + mocker.patch('ndicapy.ndiPVWRFromFile') + mocker.patch('ndicapy.ndiGetPHSRHandle', mockndiGetPHSRHandle) + mocker.patch('ndicapy.ndiVER', mockndiVER) + mocker.patch('ndicapy.ndiGetBXFrame', bxsource.mockndiGetBXFrame) + mocker.patch('ndicapy.ndiGetBXTransform', + bxsource.mockndiGetBXTransformMissing) + + tracker = NDITracker(SETTINGS_POLARIS_SMOOTH) + + bxsource.setdevice(ndidevice) + (port_handles, time_stamps, frame_numbers, tracking, + tracking_quality ) = tracker.get_frame() + + assert len(port_handles) == 2 + assert len(time_stamps) == 2 + assert frame_numbers.count(1) == 2 + assert np.all(np.isnan(tracking)) + assert np.all(np.isnan(tracking_quality)) + + del tracker