Skip to content

Commit 1c7e633

Browse files
committed
Fixed bug where transition_to_manual would complete when the PrawnBlaster was a secondary pseudoclock even if it hadn't finished (e.g. was still running or waiting for a trigger).
Also formatted files with black.
1 parent d7e5300 commit 1c7e633

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

labscript_devices/PrawnBlaster/blacs_workers.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,12 @@ def transition_to_buffered(self, device_name, h5file, initial_values, fresh):
229229
if self.smart_cache[pseudoclock][i] != instruction:
230230
self.prawnblaster.write(
231231
b"set %d %d %d %d\r\n"
232-
% (pseudoclock, i, instruction["half_period"], instruction["reps"])
232+
% (
233+
pseudoclock,
234+
i,
235+
instruction["half_period"],
236+
instruction["reps"],
237+
)
233238
)
234239
response = self.prawnblaster.readline().decode()
235240
assert (
@@ -273,7 +278,9 @@ def wait_for_trigger(self):
273278
# if we are not in TRANSITION_TO_RUNNING, then something has gone wrong
274279
# and we should raise an exception
275280
elif run_status != 1:
276-
raise RuntimeError(f"Prawnblaster did not return an expected status. Status was {run_status}")
281+
raise RuntimeError(
282+
f"Prawnblaster did not return an expected status. Status was {run_status}"
283+
)
277284
time.sleep(0.01)
278285

279286
# set started = True
@@ -302,6 +309,22 @@ def transition_to_manual(self):
302309
hdf5_file.create_dataset("/data/waits", data=data)
303310

304311
self.wait_durations_analysed.post(self.h5_file)
312+
313+
# If PrawnBlaster is master pseudoclock, then it will have it's status checked
314+
# in the BLACS tab status check before any transition to manual is called.
315+
# However, if it's not the master pseudoclock, we need to check here instead!
316+
if not self.is_master_pseudoclock:
317+
# Wait until shot completes
318+
while True:
319+
run_status, clock_status = self.read_status()
320+
if run_status == 0:
321+
break
322+
if run_status in [3, 4, 5]:
323+
raise RuntimeError(
324+
f"Prawnblaster status returned run-status={run_status} during transition to manual"
325+
)
326+
time.sleep(0.01)
327+
305328
return True
306329

307330
def shutdown(self):

labscript_devices/PrawnBlaster/labscript_devices.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,9 @@ def generate_code(self, hdf5_file):
339339
reduced_instructions[-1]["reps"] += reps
340340
else:
341341
# New instruction
342-
reduced_instructions.append({"half_period": half_period, "reps": reps})
342+
reduced_instructions.append(
343+
{"half_period": half_period, "reps": reps}
344+
)
343345

344346
# Only add this if there is room in the instruction table. The PrawnBlaster
345347
# firmware has extre room at the end for an instruction that is always 0

labscript_devices/PrawnBlaster/runviewer_parsers.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ def get_traces(self, add_trace, clock=None):
3737

3838
# get the pulse program
3939
pulse_programs = []
40-
with h5py.File(self.path, 'r') as f:
40+
with h5py.File(self.path, "r") as f:
4141
# Get the device properties
42-
device_props = properties.get(f, self.name, 'device_properties')
43-
conn_props = properties.get(f, self.name, 'connection_table_properties')
42+
device_props = properties.get(f, self.name, "device_properties")
43+
conn_props = properties.get(f, self.name, "connection_table_properties")
4444

4545
self.clock_resolution = device_props["clock_resolution"]
4646
self.trigger_delay = device_props["trigger_delay"]
@@ -49,8 +49,8 @@ def get_traces(self, add_trace, clock=None):
4949
# Extract the pulse programs
5050
num_pseudoclocks = conn_props["num_pseudoclocks"]
5151
for i in range(num_pseudoclocks):
52-
pulse_programs.append(f[f'devices/{self.name}/PULSE_PROGRAM_{i}'][:])
53-
52+
pulse_programs.append(f[f"devices/{self.name}/PULSE_PROGRAM_{i}"][:])
53+
5454
# Generate clocklines and triggers
5555
clocklines_and_triggers = {}
5656
for pulse_program in pulse_programs:
@@ -64,7 +64,7 @@ def get_traces(self, add_trace, clock=None):
6464

6565
last_instruction_was_wait = False
6666
for row in pulse_program:
67-
if row['reps'] == 0 and not last_instruction_was_wait: # WAIT
67+
if row["reps"] == 0 and not last_instruction_was_wait: # WAIT
6868
last_instruction_was_wait = True
6969
if clock is not None:
7070
t = clock_ticks[trigger_index] + self.trigger_delay
@@ -78,11 +78,11 @@ def get_traces(self, add_trace, clock=None):
7878
continue
7979
else:
8080
last_instruction_was_wait = False
81-
for i in range(row['reps']):
81+
for i in range(row["reps"]):
8282
for j in range(1, -1, -1):
8383
time.append(t)
8484
states.append(j)
85-
t += row['half_period'] * clock_factor
85+
t += row["half_period"] * clock_factor
8686

8787
clock = (np.array(time), np.array(states))
8888

@@ -91,6 +91,8 @@ def get_traces(self, add_trace, clock=None):
9191
# Ignore the dummy internal wait monitor clockline
9292
if clock_line.parent_port.startswith("GPIO"):
9393
clocklines_and_triggers[clock_line_name] = clock
94-
add_trace(clock_line_name, clock, self.name, clock_line.parent_port)
94+
add_trace(
95+
clock_line_name, clock, self.name, clock_line.parent_port
96+
)
9597

9698
return clocklines_and_triggers

0 commit comments

Comments
 (0)