Skip to content

Commit

Permalink
Add minimum duration argument for scans
Browse files Browse the repository at this point in the history
This ensures that scans are at least `min_duration` long, otherwise it skips
the scan entirely.
  • Loading branch information
BrianJKoopman committed Oct 17, 2024
1 parent 1fc4725 commit f1ad98b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
19 changes: 18 additions & 1 deletion src/sorunlib/seq.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import datetime as dt

import sorunlib as run

from sorunlib.commands import _timestamp_to_utc_datetime
from sorunlib._internal import check_response, check_started, monitor_process


OP_TIMEOUT = 60


def scan(description, stop_time, width, az_drift=0, tag=None, subtype=None):
def scan(description, stop_time, width, az_drift=0, tag=None, subtype=None,
min_duration=None):
"""Run a constant elevation scan, collecting detector data.
Args:
Expand All @@ -19,8 +24,20 @@ def scan(description, stop_time, width, az_drift=0, tag=None, subtype=None):
tag (str, optional): Tag or comma-separated listed of tags to attach to
the operation. Passed through to the smurf stream command.
subtype (str, optional): Operation subtype used to tag the stream.
min_duration (float, optional): Minimum duration required to scan,
specified in seconds. If not enough time exists between now and the
``stop_time`` the scan is not executed. Defaults to None.
"""
now = dt.datetime.now(dt.timezone.utc)
scan_stop = _timestamp_to_utc_datetime(stop_time)

# Check there is enough time to perform scan
if min_duration is not None:
start_by_time = scan_stop - dt.timedelta(seconds=min_duration)
if now > start_by_time:
return

acu = run.CLIENTS['acu']

# Enable SMuRF streams
Expand Down
12 changes: 10 additions & 2 deletions tests/test_seq.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,22 @@ def test_scan(patch_clients):
seq.scan(description='test', stop_time=target.isoformat(), width=20.)


@patch('sorunlib._internal.time.sleep', MagicMock())
def test_scan_passed_min_duration(patch_clients):
# This affects test runtime duration keep it short
target = dt.datetime.now(dt.timezone.utc) + dt.timedelta(seconds=10)
seq.scan(description='test', stop_time=target.isoformat(), width=20., min_duration=60)
seq.run.CLIENTS['acu'].generate_scan.start.assert_not_called()


@patch('sorunlib.commands.time.sleep', MagicMock())
def test_scan_no_session(patch_clients):
# Setup mock OCSReply without session object
mock_reply = MagicMock()
mock_reply.session = None
sorunlib.CLIENTS['acu'].generate_scan.start = MagicMock(return_value=mock_reply)

target = dt.datetime.now() + dt.timedelta(seconds=1)
target = dt.datetime.now(dt.timezone.utc) + dt.timedelta(seconds=1)
with pytest.raises(Exception):
seq.scan(description='test', stop_time=target.isoformat(), width=20.)

Expand Down Expand Up @@ -60,6 +68,6 @@ def test_scan_failed_to_start(patch_clients):
# other keys in .session: op_code, data
print(mock_reply)

target = dt.datetime.now() + dt.timedelta(seconds=1)
target = dt.datetime.now(dt.timezone.utc) + dt.timedelta(seconds=10)
with pytest.raises(RuntimeError):
seq.scan(description='test', stop_time=target.isoformat(), width=20.)

0 comments on commit f1ad98b

Please sign in to comment.