Skip to content

Commit 118ed1b

Browse files
adding logic to handle no connection table object on initial run
1 parent 7a84e38 commit 118ed1b

File tree

1 file changed

+77
-65
lines changed

1 file changed

+77
-65
lines changed

blacs/front_panel_settings.py

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
from labscript_utils.connections import ConnectionTable
2626

27-
logger = logging.getLogger('BLACS.FrontPanelSettings')
27+
logger = logging.getLogger('BLACS.FrontPanelSettings')
2828

2929
def _ensure_str(s):
3030
"""convert bytestrings and numpy strings to python strings"""
@@ -36,7 +36,7 @@ def __init__(self,settings_path,connection_table):
3636
self.connection_table = connection_table
3737
with h5py.File(settings_path,'a') as h5file:
3838
pass
39-
39+
4040
def setup(self,blacs):
4141
self.tablist = blacs.tablist
4242
self.attached_devices = blacs.attached_devices
@@ -46,7 +46,10 @@ def setup(self,blacs):
4646
self.blacs = blacs
4747

4848
def restore(self):
49-
49+
50+
# See if connection table exists in apparatus h5 file
51+
# Return if not
52+
#
5053
# Get list of DO/AO
5154
# Does the object have a name?
5255
# yes: Then, find the device in the BLACS connection table that matches that name
@@ -63,31 +66,40 @@ def restore(self):
6366
# no: Restore as is
6467
#
6568
# Display errors, give option to cancel starting of BLACS so that the connection table can be edited
66-
69+
6770
# Create saved connection table
6871
settings = {}
6972
question = {}
7073
error = {}
7174
tab_data = {'BLACS settings':{}}
7275
try:
76+
with h5py.File(settings_path,'r') as h5file:
77+
if 'connection table' in h5file:
78+
logger.info('Settings connection table found in file')
79+
except:
80+
logger.info('connection table not in file yet')
81+
return settings,question,error,tab_data
82+
83+
try:
84+
7385
saved_ct = ConnectionTable(self.settings_path, logging_prefix='BLACS', exceptions_in_thread=True)
7486
ct_match,error = self.connection_table.compare_to(saved_ct)
75-
87+
7688
with h5py.File(self.settings_path,'r') as hdf5_file:
7789
# Get Tab Data
7890
dataset = hdf5_file['/front_panel'].get('_notebook_data',[])
79-
91+
8092
for row in dataset:
8193
tab_name = _ensure_str(row['tab_name'])
8294
tab_data.setdefault(tab_name,{})
8395
try:
8496
tab_data[tab_name] = {'notebook':row['notebook'], 'page':row['page'], 'visible':row['visible'], 'data':eval(_ensure_str(row['data']))}
8597
except Exception:
8698
logger.info("Could not load tab data for %s"%tab_name)
87-
99+
88100
#now get dataset attributes
89101
tab_data['BLACS settings'] = dict(dataset.attrs)
90-
102+
91103
# Get the front panel values
92104
if 'front_panel' in hdf5_file["/front_panel"]:
93105
dataset = hdf5_file["/front_panel"].get('front_panel', [])
@@ -101,7 +113,7 @@ def restore(self):
101113
else:
102114
data_dict[columns[i]] = row[i]
103115
settings,question,error = self.handle_return_code(data_dict,result,settings,question,error)
104-
116+
105117
# Else Legacy restore from GTK save data!
106118
else:
107119
# open Datasets
@@ -119,7 +131,7 @@ def restore(self):
119131
logger.info("Could not load saved settings")
120132
logger.info(str(e))
121133
return settings,question,error,tab_data
122-
134+
123135
def handle_return_code(self,row,result,settings,question,error):
124136
# 1: Restore to existing device
125137
# 2: Send to new device
@@ -131,7 +143,7 @@ def handle_return_code(self,row,result,settings,question,error):
131143
if type(result) == tuple:
132144
connection = result[1]
133145
result = result[0]
134-
146+
135147
if result == 1:
136148
settings.setdefault(row['device_name'],{})
137149
settings[row['device_name']][row['channel']] = row
@@ -145,10 +157,10 @@ def handle_return_code(self,row,result,settings,question,error):
145157
error[row['device_name']+'_'+row['channel']] = row,"missing"
146158
elif result == -2:
147159
error[row['device_name']+'_'+row['channel']] = row,"changed"
148-
160+
149161
return settings,question,error
150-
151-
def check_row(self,row,ct_match,blacs_ct,saved_ct):
162+
163+
def check_row(self,row,ct_match,blacs_ct,saved_ct):
152164
# If it has a name
153165
if row[0] != "-":
154166
if ct_match:
@@ -158,21 +170,21 @@ def check_row(self,row,ct_match,blacs_ct,saved_ct):
158170
# Find if this device is in the connection table
159171
connection = blacs_ct.find_by_name(row[0])
160172
connection2 = saved_ct.find_by_name(row[0])
161-
173+
162174
if connection:
163175
# compare the two connections, see what differs
164176
# if compare fails only on parent, connected to:
165177
# send to new parent
166178
# else:
167179
# show error, device parameters not compatible with saved data
168180
result,error = connection.compare_to(connection2)
169-
181+
170182
allowed_length = 0
171183
if "parent_port" in error:
172184
allowed_length += 1
173-
185+
174186
if len(error) > allowed_length:
175-
return -2 # failure, device parameters not compatible
187+
return -2 # failure, device parameters not compatible
176188
elif error == {} and connection.parent.name == connection2.parent.name:
177189
return 1 # All details about this device match
178190
else:
@@ -190,46 +202,46 @@ def check_row(self,row,ct_match,blacs_ct,saved_ct):
190202
else:
191203
# restore to device
192204
return 1
193-
194-
@inmain_decorator(wait_for_return=True)
205+
206+
@inmain_decorator(wait_for_return=True)
195207
def get_save_data(self):
196208
tab_data = {}
197209
notebook_data = {}
198210
window_data = {}
199211
plugin_data = {}
200-
212+
201213
# iterate over all tabs
202214
for device_name,tab in self.tablist.items():
203215
tab_data[device_name] = {'front_panel':tab.settings['front_panel_settings'], 'save_data': tab.get_all_save_data()}
204-
216+
205217
# Find the notebook the tab is in
206-
#
207-
# By default we assume it is in notebook0, on page 0. This way, if a tab gets lost somewhere,
208-
# and isn't found to be a child of any notebook we know about,
218+
#
219+
# By default we assume it is in notebook0, on page 0. This way, if a tab gets lost somewhere,
220+
# and isn't found to be a child of any notebook we know about,
209221
# it will revert back to notebook 1 when the file is loaded upon program restart!
210-
current_notebook_name = 0
222+
current_notebook_name = 0
211223
page = 0
212224
visible = False
213-
225+
214226
for notebook_name,notebook in self.notebook.items():
215-
if notebook.indexOf(tab._ui) != -1:
216-
current_notebook_name = notebook_name
217-
page = notebook.indexOf(tab._ui)
218-
visible = True if notebook.currentIndex() == page else False
227+
if notebook.indexOf(tab._ui) != -1:
228+
current_notebook_name = notebook_name
229+
page = notebook.indexOf(tab._ui)
230+
visible = True if notebook.currentIndex() == page else False
219231
break
220-
232+
221233
notebook_data[device_name] = {"notebook":current_notebook_name,"page":page, "visible":visible}
222-
234+
223235
# iterate over all plugins
224236
for module_name, plugin in self.blacs.plugins.items():
225237
try:
226238
plugin_data[module_name] = plugin.get_save_data()
227239
except Exception as e:
228240
logger.error('Could not save data for plugin %s. Error was: %s'%(module_name,str(e)))
229-
241+
230242
# save window data
231-
# Size of window
232-
window_data["_main_window"] = {"width":self.window.normalGeometry().width(),
243+
# Size of window
244+
window_data["_main_window"] = {"width":self.window.normalGeometry().width(),
233245
"height":self.window.normalGeometry().height(),
234246
"xpos":self.window.normalGeometry().x(),
235247
"ypos":self.window.normalGeometry().y(),
@@ -242,24 +254,24 @@ def get_save_data(self):
242254
# Pane positions
243255
for name,pane in self.panes.items():
244256
window_data[name] = pane.sizes()
245-
257+
246258
return tab_data,notebook_data,window_data,plugin_data
247-
259+
248260
@inmain_decorator(wait_for_return=True)
249-
def save_front_panel_to_h5(self,current_file,states,tab_positions,window_data,plugin_data,silent = {}, force_new_conn_table = False):
261+
def save_front_panel_to_h5(self,current_file,states,tab_positions,window_data,plugin_data,silent = {}, force_new_conn_table = False):
250262
# Save the front panel!
251263

252-
# Does the file exist?
264+
# Does the file exist?
253265
# Yes: Check connection table inside matches current connection table. Does it match?
254266
# Yes: Does the file have a front panel already saved in it?
255267
# Yes: Can we overwrite?
256268
# Yes: Delete front_panel group, save new front panel
257269
# No: Create error dialog!
258270
# No: Save front panel in here
259-
#
271+
#
260272
# No: Return
261273
# No: Create new file, place inside the connection table and front panel
262-
274+
263275
if os.path.isfile(current_file):
264276
save_conn_table = True if force_new_conn_table else False
265277
result = False
@@ -270,10 +282,10 @@ def save_front_panel_to_h5(self,current_file,states,tab_positions,window_data,pl
270282
except Exception:
271283
# no connection table is present, so also save the connection table!
272284
save_conn_table = True
273-
285+
274286
# if save_conn_table is True, we don't bother checking to see if the connection tables match, because save_conn_table is only true when the connection table doesn't exist in the current file
275287
# As a result, if save_conn_table is True, we ignore connection table checking, and save the connection table in the h5file.
276-
288+
277289
if save_conn_table or result:
278290
with h5py.File(current_file,'r+') as hdf5_file:
279291
if hdf5_file['/'].get('front_panel') != None:
@@ -288,18 +300,18 @@ def save_front_panel_to_h5(self,current_file,states,tab_positions,window_data,pl
288300
message.setIcon(QMessageBox.Question)
289301
message.setWindowTitle("BLACS")
290302
resp = message.exec_()
291-
303+
292304
if resp == QMessageBox.Yes :
293-
overwrite = True
305+
overwrite = True
294306
else:
295307
overwrite = silent["overwrite"]
296-
308+
297309
if overwrite:
298310
# Delete Front panel group, save new front panel
299311
del hdf5_file['/front_panel']
300312
self.store_front_panel_in_h5(hdf5_file,states,tab_positions,window_data,plugin_data,save_conn_table)
301313
else:
302-
if not silent:
314+
if not silent:
303315
message = QMessageBox()
304316
message.setText("Front Panel not saved.")
305317
message.setIcon(QMessageBox.Information)
@@ -308,7 +320,7 @@ def save_front_panel_to_h5(self,current_file,states,tab_positions,window_data,pl
308320
else:
309321
logger.info("Front Panel not saved as it already existed in the h5 file '"+current_file+"'")
310322
return
311-
else:
323+
else:
312324
# Save Front Panel in here
313325
self.store_front_panel_in_h5(hdf5_file,states,tab_positions,window_data,plugin_data,save_conn_table)
314326
else:
@@ -318,32 +330,32 @@ def save_front_panel_to_h5(self,current_file,states,tab_positions,window_data,pl
318330
message.setText("The Front Panel was not saved as the file selected contains a connection table which is not a subset of the BLACS connection table.")
319331
message.setIcon(QMessageBox.Information)
320332
message.setWindowTitle("BLACS")
321-
message.exec_()
333+
message.exec_()
322334
else:
323335
logger.info("Front Panel not saved as the connection table in the h5 file '"+current_file+"' didn't match the current connection table.")
324336
return
325337
else:
326338
with h5py.File(current_file,'w') as hdf5_file:
327-
# save connection table, save front panel
339+
# save connection table, save front panel
328340
self.store_front_panel_in_h5(hdf5_file,states,tab_positions,window_data,plugin_data,save_conn_table=True)
329-
341+
330342
@inmain_decorator(wait_for_return=True)
331343
def store_front_panel_in_h5(self, hdf5_file,tab_data,notebook_data,window_data,plugin_data,save_conn_table=False,save_queue_data=True):
332344
if save_conn_table:
333345
if 'connection table' in hdf5_file:
334346
del hdf5_file['connection table']
335347
hdf5_file.create_dataset('connection table', data=self.connection_table.raw_table)
336-
348+
337349
data_group = hdf5_file['/'].create_group('front_panel')
338-
350+
339351
front_panel_list = []
340-
other_data_list = []
352+
other_data_list = []
341353
front_panel_dtype = [('name','a256'),('device_name','a256'),('channel','a256'),('base_value',float),('locked',bool),('base_step_size',float),('current_units','a256')]
342354
max_od_length = 2 # empty dictionary
343-
355+
344356
# Iterate over each device within a class
345357
for device_name, device_state in tab_data.items():
346-
logger.debug("saving front panel for device:" + device_name)
358+
logger.debug("saving front panel for device:" + device_name)
347359
# Insert front panel data into dataset
348360
for hardware_name, data in device_state["front_panel"].items():
349361
if data != {}:
@@ -359,29 +371,29 @@ def store_front_panel_in_h5(self, hdf5_file,tab_data,notebook_data,window_data,p
359371
data['base_step_size'] if 'base_step_size' in data else 0,
360372
data['current_units'] if 'current_units' in data else ''
361373
)
362-
)
374+
)
363375
else:
364376
logger.warning('Could not save data for channel %s on device %s because the output value (in base units) was not a string or could not be coerced to a float without loss of precision'%(hardware_name, device_name))
365-
377+
366378
# Save "other data"
367379
od = repr(device_state["save_data"])
368-
other_data_list.append(od)
369-
max_od_length = len(od) if len(od) > max_od_length else max_od_length
370-
380+
other_data_list.append(od)
381+
max_od_length = len(od) if len(od) > max_od_length else max_od_length
382+
371383
# Create datasets
372384
if front_panel_list:
373385
front_panel_array = numpy.empty(len(front_panel_list),dtype=front_panel_dtype)
374386
for i, row in enumerate(front_panel_list):
375387
front_panel_array[i] = row
376388
data_group.create_dataset('front_panel',data=front_panel_array)
377-
389+
378390
# Save tab data
379391
i = 0
380392
tab_data = numpy.empty(len(notebook_data),dtype=[('tab_name','a256'),('notebook','a2'),('page',int),('visible',bool),('data','a'+str(max_od_length))])
381393
for device_name,data in notebook_data.items():
382394
tab_data[i] = (device_name,data["notebook"],data["page"],data["visible"],other_data_list[i])
383395
i += 1
384-
396+
385397
# Save BLACS Main GUI Info
386398
dataset = data_group.create_dataset("_notebook_data",data=tab_data)
387399
dataset.attrs["window_width"] = window_data["_main_window"]["width"]
@@ -398,7 +410,7 @@ def store_front_panel_in_h5(self, hdf5_file,tab_data,notebook_data,window_data,p
398410
for pane_name,pane_position in window_data.items():
399411
if pane_name != "_main_window":
400412
dataset.attrs[pane_name] = pane_position
401-
413+
402414
# Save analysis server settings:
403415
#dataset = data_group.create_group("analysis_server")
404416
#dataset.attrs['send_for_analysis'] = self.blacs.analysis_submission.toggle_analysis.get_active()

0 commit comments

Comments
 (0)