Skip to content

Commit

Permalink
Add ability to toggle SMuRF operation concurrency (#84)
Browse files Browse the repository at this point in the history
* Add cryo settling time between smurf operations

* Mock sleep in smurf tests

* Add concurrency flag to all SMuRF commands

* Set all SMuRF operation wait times to zero

* Add settling_time arg to SMuRF operations

* Default 0 second wait times for most operations
  • Loading branch information
BrianJKoopman authored Oct 23, 2023
1 parent 4b54283 commit a08ce5f
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 44 deletions.
177 changes: 147 additions & 30 deletions src/sorunlib/smurf.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import time

import sorunlib as run
from sorunlib._internal import check_response

# Timing between commanding separate SMuRF Controllers
# Yet to be determined in the field. Eventually might need this to be unique
# per operation. Also, move to configuration file once sorunlib has one.
CRYO_WAIT = 120


def set_targets(targets):
"""Set the target pysmurf-controller Agents that sorunlib will command.
Expand All @@ -22,104 +29,214 @@ def set_targets(targets):
run.CLIENTS['smurf'] = _smurf_clients


def bias_step(tag=None):
def bias_step(tag=None, concurrent=True, settling_time=None):
"""Perform a bias step on all SMuRF Controllers.
Args:
tag (str, optional): Tag or comma-separated listed of tags to attach to
the operation.
concurrent (bool, optional): A bool which determines how the operation
is run across the active SMuRF controllers. It runs in parallel if
True, and in series if False.
settling_time (float, optional):
Time in seconds to wait between operation runs across the active
SMuRF controlls if *not* running concurrently. If running
concurrently this is ignored. If None, defaults to a fixed wait
time of 120 seconds.
"""
for smurf in run.CLIENTS['smurf']:
smurf.take_bias_steps.start(tag=tag)
if not concurrent:
resp = smurf.take_bias_steps.wait()
check_response(resp)

for smurf in run.CLIENTS['smurf']:
resp = smurf.take_bias_steps.wait()
check_response(resp)
# Allow cryo to settle
wait = settling_time if settling_time else CRYO_WAIT
time.sleep(wait)

if concurrent:
for smurf in run.CLIENTS['smurf']:
resp = smurf.take_bias_steps.wait()
check_response(resp)


def iv_curve(tag=None):
def iv_curve(tag=None, concurrent=True, settling_time=None):
"""Perform an iv curve on all SMuRF Controllers.
Args:
tag (str, optional): Tag or comma-separated listed of tags to attach to
the operation.
concurrent (bool, optional): A bool which determines how the operation
is run across the active SMuRF controllers. It runs in parallel if
True, and in series if False.
settling_time (float, optional):
Time in seconds to wait between operation runs across the active
SMuRF controlls if *not* running concurrently. If running
concurrently this is ignored. If None, defaults to a fixed wait
time of 120 seconds.
"""
for smurf in run.CLIENTS['smurf']:
smurf.take_iv.start(tag=tag)
if not concurrent:
resp = smurf.take_iv.wait()
check_response(resp)

for smurf in run.CLIENTS['smurf']:
resp = smurf.take_iv.wait()
check_response(resp)
# Allow cryo to settle
wait = settling_time if settling_time else CRYO_WAIT
time.sleep(wait)

if concurrent:
for smurf in run.CLIENTS['smurf']:
resp = smurf.take_iv.wait()
check_response(resp)


def uxm_setup():
"""Perform first-time setup procedure for a UXM."""
def uxm_setup(concurrent=True, settling_time=0):
"""Perform first-time setup procedure for a UXM.
Args:
concurrent (bool, optional): A bool which determines how the operation
is run across the active SMuRF controllers. It runs in parallel if
True, and in series if False.
settling_time (float, optional):
Time in seconds to wait between operation runs across the active
SMuRF controlls if *not* running concurrently. If running
concurrently this is ignored. Defaults to 0 seconds.
"""
for smurf in run.CLIENTS['smurf']:
smurf.uxm_setup.start()
if not concurrent:
resp = smurf.uxm_setup.wait()
check_response(resp)

for smurf in run.CLIENTS['smurf']:
resp = smurf.uxm_setup.wait()
check_response(resp)
# Allow cryo to settle
time.sleep(settling_time)

if concurrent:
for smurf in run.CLIENTS['smurf']:
resp = smurf.uxm_setup.wait()
check_response(resp)


def uxm_relock(test_mode=False):
def uxm_relock(test_mode=False, concurrent=True, settling_time=0):
"""Relocks detectors to existing tune if setup has already been run.
Args:
test_mode (bool): Run uxm_setup() task in test_mode, removing emulated
wait times.
concurrent (bool, optional): A bool which determines how the operation
is run across the active SMuRF controllers. It runs in parallel if
True, and in series if False.
settling_time (float, optional):
Time in seconds to wait between operation runs across the active
SMuRF controlls if *not* running concurrently. If running
concurrently this is ignored. Defaults to 0 seconds.
"""
for smurf in run.CLIENTS['smurf']:
smurf.uxm_relock.start(test_mode=test_mode)
if not concurrent:
resp = smurf.uxm_relock.wait()
check_response(resp)

for smurf in run.CLIENTS['smurf']:
resp = smurf.uxm_relock.wait()
check_response(resp)
# Allow cryo to settle
time.sleep(settling_time)

if concurrent:
for smurf in run.CLIENTS['smurf']:
resp = smurf.uxm_relock.wait()
check_response(resp)


def bias_dets(concurrent=True, settling_time=0):
"""Bias the detectors on all SMuRF Controllers.
Args:
concurrent (bool, optional): A bool which determines how the operation
is run across the active SMuRF controllers. It runs in parallel if
True, and in series if False.
settling_time (float, optional):
Time in seconds to wait between operation runs across the active
SMuRF controlls if *not* running concurrently. If running
concurrently this is ignored. Defaults to 0 seconds.
def bias_dets():
"""Bias the detectors on all SMuRF Controllers."""
"""
for smurf in run.CLIENTS['smurf']:
smurf.bias_dets.start()
if not concurrent:
resp = smurf.bias_dets.wait()
check_response(resp)

for smurf in run.CLIENTS['smurf']:
resp = smurf.bias_dets.wait()
check_response(resp)
# Allow cryo to settle
time.sleep(settling_time)

if concurrent:
for smurf in run.CLIENTS['smurf']:
resp = smurf.bias_dets.wait()
check_response(resp)


def take_bgmap(tag=None):
def take_bgmap(tag=None, concurrent=True, settling_time=0):
"""Take a bgmap on all SMuRF Controllers.
Args:
tag (str, optional): Tag or comma-separated listed of tags to attach to
the operation.
concurrent (bool, optional): A bool which determines how the operation
is run across the active SMuRF controllers. It runs in parallel if
True, and in series if False.
settling_time (float, optional):
Time in seconds to wait between operation runs across the active
SMuRF controlls if *not* running concurrently. If running
concurrently this is ignored. Defaults to 0 seconds.
"""
for smurf in run.CLIENTS['smurf']:
smurf.take_bgmap.start(tag=tag)
if not concurrent:
resp = smurf.take_bgmap.wait()
check_response(resp)

for smurf in run.CLIENTS['smurf']:
resp = smurf.take_bgmap.wait()
check_response(resp)
# Allow cryo to settle
time.sleep(settling_time)

if concurrent:
for smurf in run.CLIENTS['smurf']:
resp = smurf.take_bgmap.wait()
check_response(resp)


def take_noise(tag=None):
def take_noise(tag=None, concurrent=True, settling_time=0):
"""Measure noise statistics from a short, 30 second, timestream.
Args:
tag (str, optional): Tag or comma-separated listed of tags to attach to
the operation.
concurrent (bool, optional): A bool which determines how the operation
is run across the active SMuRF controllers. It runs in parallel if
True, and in series if False.
settling_time (float, optional):
Time in seconds to wait between operation runs across the active
SMuRF controlls if *not* running concurrently. If running
concurrently this is ignored. Defaults to 0 seconds.
"""
for smurf in run.CLIENTS['smurf']:
smurf.take_noise.start(tag=tag)
if not concurrent:
resp = smurf.take_noise.wait()
check_response(resp)

for smurf in run.CLIENTS['smurf']:
resp = smurf.take_noise.wait()
check_response(resp)
# Allow cryo to settle
time.sleep(settling_time)

if concurrent:
for smurf in run.CLIENTS['smurf']:
resp = smurf.take_noise.wait()
check_response(resp)


def stream(state, tag=None, subtype=None):
Expand Down
41 changes: 27 additions & 14 deletions tests/test_smurf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from unittest.mock import MagicMock, patch

import pytest

from sorunlib import smurf


Expand Down Expand Up @@ -31,58 +33,69 @@ def test_set_targets():
assert smurf.run.CLIENTS['smurf'][0].instance_id == 'smurf1'


@patch('sorunlib.smurf.time.sleep', MagicMock())
@patch('sorunlib.create_clients', mocked_clients)
def test_bias_step():
@pytest.mark.parametrize("concurrent", [(True), (False)])
def test_bias_step(concurrent):
smurf.run.initialize(test_mode=True)
smurf.bias_step()
smurf.bias_step(concurrent=concurrent)
for client in smurf.run.CLIENTS['smurf']:
client.take_bias_steps.start.assert_called_once()


@patch('sorunlib.smurf.time.sleep', MagicMock())
@patch('sorunlib.create_clients', mocked_clients)
def test_iv_curve():
@pytest.mark.parametrize("concurrent", [(True), (False)])
def test_iv_curve(concurrent):
smurf.run.initialize(test_mode=True)
smurf.iv_curve()
smurf.iv_curve(concurrent=concurrent)
for client in smurf.run.CLIENTS['smurf']:
client.take_iv.start.assert_called_once()


@patch('sorunlib.smurf.time.sleep', MagicMock())
@patch('sorunlib.create_clients', mocked_clients)
def test_uxm_setup():
@pytest.mark.parametrize("concurrent", [(True), (False)])
def test_uxm_setup(concurrent):
smurf.run.initialize(test_mode=True)
smurf.uxm_setup()
smurf.uxm_setup(concurrent=concurrent)
for client in smurf.run.CLIENTS['smurf']:
client.uxm_setup.start.assert_called_once()


@patch('sorunlib.smurf.time.sleep', MagicMock())
@patch('sorunlib.create_clients', mocked_clients)
def test_uxm_relock():
@pytest.mark.parametrize("concurrent", [(True), (False)])
def test_uxm_relock(concurrent):
smurf.run.initialize(test_mode=True)
smurf.uxm_relock()
smurf.uxm_relock(concurrent=concurrent)
for client in smurf.run.CLIENTS['smurf']:
client.uxm_relock.start.assert_called_once()


@patch('sorunlib.create_clients', mocked_clients)
def test_bias_dets():
@pytest.mark.parametrize("concurrent", [(True), (False)])
def test_bias_dets(concurrent):
smurf.run.initialize(test_mode=True)
smurf.bias_dets()
smurf.bias_dets(concurrent=concurrent)
for client in smurf.run.CLIENTS['smurf']:
client.bias_dets.start.assert_called_once()


@patch('sorunlib.create_clients', mocked_clients)
def test_bgmap():
@pytest.mark.parametrize("concurrent", [(True), (False)])
def test_bgmap(concurrent):
smurf.run.initialize(test_mode=True)
smurf.take_bgmap()
smurf.take_bgmap(concurrent=concurrent)
for client in smurf.run.CLIENTS['smurf']:
client.take_bgmap.start.assert_called_once()


@patch('sorunlib.create_clients', mocked_clients)
def test_take_noise():
@pytest.mark.parametrize("concurrent", [(True), (False)])
def test_take_noise(concurrent):
smurf.run.initialize(test_mode=True)
smurf.take_noise()
smurf.take_noise(concurrent=concurrent)
for client in smurf.run.CLIENTS['smurf']:
client.take_noise.start.assert_called_once()

Expand Down

0 comments on commit a08ce5f

Please sign in to comment.