|
@@ -1,7 +1,7 @@
|
|
|
"""
|
|
|
This is the interface to the backend.
|
|
|
It is used to make the backend easily interchangable.
|
|
|
-All Functions that interface directly with the backend are prefixed with be_
|
|
|
+All Functions that interface directly with the backend are prefixed with bk\_
|
|
|
Functions only used internal in this module will be prefixed _bif_
|
|
|
"""
|
|
|
|
|
@@ -90,6 +90,11 @@ def _bif_continuous_read_is_enabled(board_id, popup_title_text=None):
|
|
|
|
|
|
|
|
|
def bk_status_readout():
|
|
|
+ """
|
|
|
+ Read Status for every connected board
|
|
|
+ """
|
|
|
+ if not available_boards.has_boards:
|
|
|
+ return
|
|
|
for brd in available_boards.board_ids:
|
|
|
_bif_status_readout(brd)
|
|
|
|
|
@@ -137,10 +142,8 @@ class PopupDialog(QtGui.QDialog):
|
|
|
QtGui.QDialog.__init__(self, parent)
|
|
|
self.text = text
|
|
|
self.setWindowTitle(title if title else tr("Dialog", "User action required"))
|
|
|
- self.do_layout()
|
|
|
self.return_value = False
|
|
|
|
|
|
- def do_layout(self):
|
|
|
size = QtCore.QSize(200, 200)
|
|
|
# self.setMaximumSize(size)
|
|
|
self.setMinimumSize(size)
|
|
@@ -160,13 +163,24 @@ class PopupDialog(QtGui.QDialog):
|
|
|
self.setLayout(box)
|
|
|
|
|
|
def on_okay(self):
|
|
|
+ """
|
|
|
+ Handler for the press of the ok button
|
|
|
+ """
|
|
|
self.return_value = True
|
|
|
self.close()
|
|
|
|
|
|
def on_cancel(self):
|
|
|
+ """
|
|
|
+ Handler for the press of the cancel button
|
|
|
+ :return:
|
|
|
+ """
|
|
|
self.close()
|
|
|
|
|
|
def get_return_value(self):
|
|
|
+ """
|
|
|
+ Get True if the Window was closed with OK else False
|
|
|
+ :return: True if OK else False
|
|
|
+ """
|
|
|
return self.return_value
|
|
|
|
|
|
|
|
@@ -305,6 +319,10 @@ def bk_calibrate(board_id, do_the_rest=None):
|
|
|
finished = QtCore.pyqtSignal()
|
|
|
|
|
|
def calibrate(self):
|
|
|
+ """
|
|
|
+ The method that is called inside the thread and that does the calibration
|
|
|
+ :return:
|
|
|
+ """
|
|
|
try:
|
|
|
logging.info('Started Board Calibration')
|
|
|
for idx, step in enumerate(sequence):
|
|
@@ -321,6 +339,10 @@ def bk_calibrate(board_id, do_the_rest=None):
|
|
|
self.finished.emit()
|
|
|
|
|
|
def thread_quit():
|
|
|
+ """
|
|
|
+ Method to handle the end of the calibration thread
|
|
|
+ :return:
|
|
|
+ """
|
|
|
thread.stop()
|
|
|
bk_status_readout()
|
|
|
progressbar.remove(0)
|
|
@@ -791,6 +813,7 @@ def _bif_start_acquisition(board_id):
|
|
|
storage.get_board_specific_storage(board_id).acquisition_progressbar.setValue(storage.storage.current_acquisition[board_id])
|
|
|
|
|
|
def on_timeout():
|
|
|
+ '''Handler for the timeout of the acquisition timer. This does the acquisition'''
|
|
|
if storage.storage.current_acquisition[board_id] < num_acquisitions:
|
|
|
storage.storage.current_acquisition[board_id] += 1
|
|
|
storage.get_board_specific_storage(board_id).acquisition_progressbar.setValue(storage.storage.current_acquisition[board_id])
|
|
@@ -898,7 +921,7 @@ def _bif_read_data(board_id):
|
|
|
data_raw = board.pci.read_data_to_variable(board_id)
|
|
|
_bif_read_and_update_data_from_string(board_id, data_raw)
|
|
|
except board.BoardError as e:
|
|
|
- logging.error("Reading failed: {}".format(str(e))) # TODO: board id
|
|
|
+ logging.error("Reading failed for board {}: {}".format(str(board_id), str(e)))
|
|
|
|
|
|
|
|
|
def bk_board_connected(board_id):
|
|
@@ -907,10 +930,10 @@ def bk_board_connected(board_id):
|
|
|
:param board_id: id of the board do manipulate
|
|
|
:return: -
|
|
|
"""
|
|
|
- # return board.is_conneced(board_id)
|
|
|
- if len(available_boards.board_ids) > 0:
|
|
|
- return True
|
|
|
- return False
|
|
|
+ if not available_boards.has_boards:
|
|
|
+ return False
|
|
|
+ else:
|
|
|
+ return board_id in available_boards.board_ids
|
|
|
|
|
|
|
|
|
def bk_get_temperature(board_id):
|
|
@@ -1027,6 +1050,7 @@ def _bif_start_time_scan(board_id, c_frm, c_to, f_frm, f_to, timescan_progressba
|
|
|
timescan_progressbar.setRange(1, ((f_to - f_frm) + 1) * ((c_to - c_frm) + 1))
|
|
|
|
|
|
class thread_time_scan(QtCore.QObject):
|
|
|
+ '''Timescan Thread class'''
|
|
|
pbarSignal = QtCore.pyqtSignal(int)
|
|
|
stopSignal = QtCore.pyqtSignal()
|
|
|
finished = QtCore.pyqtSignal()
|
|
@@ -1040,6 +1064,7 @@ def _bif_start_time_scan(board_id, c_frm, c_to, f_frm, f_to, timescan_progressba
|
|
|
self.timescan_progressbar = timescan_progressbar
|
|
|
|
|
|
def time_scan(self):
|
|
|
+ '''Method to run in the thread that does the timescan'''
|
|
|
Elements.setEnabled('acquire_{}'.format(board_id), False, exclude=Elements.getElements('start_time_scan_{}'.format(board_id)))
|
|
|
if orbits_observe:
|
|
|
if not hasattr(storage.storage, 'orbits_observe_before_timescan'):
|
|
@@ -1096,7 +1121,6 @@ def _bif_start_time_scan(board_id, c_frm, c_to, f_frm, f_to, timescan_progressba
|
|
|
# This information has to be removed here.
|
|
|
# To do so we split the output string from PCI at "Writting" (Note: Writting is correct as
|
|
|
# this is a typo in the PCI driver)
|
|
|
- # TODO: does this need board_id? (was there)
|
|
|
data = io.read_from_string(data_raw, force=True, cache=False)
|
|
|
except board.BoardError as e:
|
|
|
self.stopSignal.emit()
|
|
@@ -1126,6 +1150,7 @@ def _bif_start_time_scan(board_id, c_frm, c_to, f_frm, f_to, timescan_progressba
|
|
|
self.finished.emit()
|
|
|
|
|
|
def finished(timescan_progressbar):
|
|
|
+ '''Method to handle the end of the thread'''
|
|
|
thread.stop()
|
|
|
_bif_stop_time_scan(board_id, timescan_progressbar)
|
|
|
Elements.setEnabled('acquire_{}'.format(board_id), True, exclude=Elements.getElements('start_time_scan_{}'.format(board_id)))
|
|
@@ -1201,13 +1226,13 @@ def bk_check_for_board(board_id):
|
|
|
:param board_id: id of the board do manipulate
|
|
|
:return: -
|
|
|
"""
|
|
|
- global bk_status_readout, bk_get_temperature
|
|
|
+ # global bk_status_readout, bk_get_temperature
|
|
|
board_status = bk_board_connected(board_id)
|
|
|
if board_status:
|
|
|
if not hasattr(board.get_board_status(board_id), 'board_connected') or \
|
|
|
not board.get_board_status(board_id).board_connected:
|
|
|
- bk_status_readout = backup_readout
|
|
|
- bk_get_temperature = backup_get_temp
|
|
|
+ globals()['bk_status_readout'] = backup_readout
|
|
|
+ globals()['bk_get_temperature'] = backup_get_temp
|
|
|
board.get_board_status(board_id).board_connected = True
|
|
|
|
|
|
else:
|
|
@@ -1219,8 +1244,8 @@ def bk_check_for_board(board_id):
|
|
|
def no_temp(board_id):
|
|
|
return "-"
|
|
|
|
|
|
- bk_status_readout = do_nothing
|
|
|
- bk_get_temperature = no_temp
|
|
|
+ globals()['bk_status_readout'] = do_nothing
|
|
|
+ globals()['bk_get_temperature'] = no_temp
|
|
|
board.get_board_status(board_id).board_connected = False
|
|
|
if board_status == False:
|
|
|
board.get_board_status(board_id).status_text = tr("sw", "Board {} not connected".format(board_id))
|
|
@@ -1246,6 +1271,7 @@ def bk_toggle_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, tim
|
|
|
if thread.running:
|
|
|
# Elements.getElements("acquireTrigger_{}".format(board_id))[0].setText(tr("Button", "Start Acquisition"))
|
|
|
log(board_id=board_id, additional="Stop wait on trigger on board {}".format(board_id))
|
|
|
+ thread.quit()
|
|
|
thread.stop()
|
|
|
# for elem in Elements.getElements("acquire_{}".format(board_id)):
|
|
|
# if isinstance(elem, QtGui.QShortcut):
|
|
@@ -1299,8 +1325,8 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
board.pci.write(board_id, hex(num_of_acquisitions), "9024")
|
|
|
time.sleep(0.1)
|
|
|
board.pci.write(board_id, hex(skip), "902C")
|
|
|
- time.sleep(0.1)
|
|
|
- board.pci.write(board_id, 'ff0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
+ # time.sleep(0.1)
|
|
|
+ # board.pci.write(board_id, 'ff0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
|
|
|
# This seems to sometimes lead to segfaults of python it self. An Idea to prevent this
|
|
|
# is to use copy.deepcopy in __init__. But there is no reason to think that that causes the problem. In fact
|
|
@@ -1311,13 +1337,21 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
# Something that is likely to cause the problem is the log.debug in board.safe_call
|
|
|
# Logging (using the logging module) is directly connected to the main thread and could cause problems
|
|
|
class thread_wait_on_signal(QtCore.QObject):
|
|
|
+ '''Class to run the wait on signal functionality in a thread'''
|
|
|
countUpdate = QtCore.pyqtSignal(int)
|
|
|
stopSignal = QtCore.pyqtSignal()
|
|
|
finished = QtCore.pyqtSignal()
|
|
|
- liveplot = QtCore.pyqtSignal(str)
|
|
|
+ liveplot = QtCore.pyqtSignal(int, str) # This has to be changed if board_id is no integer
|
|
|
|
|
|
- def __init__(self, num_of_acquisitions, path, timeout):
|
|
|
+ def __init__(self):
|
|
|
super(thread_wait_on_signal, self).__init__()
|
|
|
+ self.noa = None
|
|
|
+ self.path = None
|
|
|
+ self.timeout = None
|
|
|
+ self._quit = False
|
|
|
+
|
|
|
+ def init(self, num_of_acquisitions, path, timeout):
|
|
|
+ '''initialise a new run'''
|
|
|
self.noa = num_of_acquisitions
|
|
|
self.path = path
|
|
|
self.timeout = timeout
|
|
@@ -1326,14 +1360,14 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
# Elements.setEnabled('acquireTrigger_{}'.format(board_id), False) # exclude=Elements.getElements('wait_on_trigger_{}'.format(board_id)))
|
|
|
|
|
|
def wait_rw_simul(self):
|
|
|
+ '''Wait simultaniously (with the pci command) for a trigger signal'''
|
|
|
board.pci.write(board_id, 'ff0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
for num_of_acq in xrange(self.noa):
|
|
|
# def step():
|
|
|
filename = self.path +'/{:0.3f}.out'.format(time.time())
|
|
|
board.pci.read_data_to_file(board_id, filename=filename, timeout=(self.timeout*1000000))
|
|
|
# rename with correct timestamp - last modified time
|
|
|
- # TODO: Exception handling when pci does not create file
|
|
|
- self.countUpdate.emit(num_of_acquisitions + 1)
|
|
|
+ self.countUpdate.emit(num_of_acq + 1)
|
|
|
if self._quit:
|
|
|
break
|
|
|
|
|
@@ -1343,20 +1377,21 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
continue
|
|
|
|
|
|
newfile = '{path}/trigger_{num:05}_{htime}_{unixtime}.out'.format(
|
|
|
- num=num_of_acquisitions,
|
|
|
+ num=num_of_acq,
|
|
|
htime=dt.fromtimestamp(os.path.getmtime(filename)).strftime('%Y-%m-%dT%Hh%Mm%Ss%f'),
|
|
|
unixtime=int(os.path.getmtime(filename)),
|
|
|
path=self.path
|
|
|
)
|
|
|
os.rename(filename, newfile)
|
|
|
if os.path.getsize(newfile) > 0:
|
|
|
- self.liveplot.emit(newfile)
|
|
|
+ self.liveplot.emit(board_id, newfile)
|
|
|
else:
|
|
|
logging.info("Acquired 0b, possible trigger timeout.")
|
|
|
|
|
|
self.finished.emit()
|
|
|
|
|
|
def wait_rw_seq(self):
|
|
|
+ '''Wait sequentially (in the gui) for a trigger signal'''
|
|
|
for num_of_acq in xrange(self.noa):
|
|
|
board.pci.write(board_id, '00bf0', hex_mask='CF0') # enable readout
|
|
|
pre_acq_num = board.pci.read(board_id, 1, '9034')[0]
|
|
@@ -1374,7 +1409,7 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
board.pci.write(board_id, '007f0', hex_mask='CF0') # enable transfer
|
|
|
filename = self.path +'/{:0.3f}.out'.format(time.time())
|
|
|
board.pci.read_data_to_file(board_id, filename=filename, timeout=(self.timeout*1000000))
|
|
|
- board.pci.write(board_id, '000f0', hex_mask='4F0') # disable transfer
|
|
|
+ # board.pci.write(board_id, '000f0', hex_mask='4F0') # disable transfer
|
|
|
self.countUpdate.emit(copy.deepcopy(num_of_acq+1))
|
|
|
if self._quit:
|
|
|
break
|
|
@@ -1384,13 +1419,13 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
continue
|
|
|
|
|
|
newfile = '{path}/trigger_{num:05}_{htime}_{unixtime}.out'.format(
|
|
|
- num=num_of_acquisitions,
|
|
|
+ num=num_of_acq,
|
|
|
htime=dt.fromtimestamp(os.path.getmtime(filename)).strftime('%Y-%m-%dT%Hh%Mm%Ss%f'),
|
|
|
unixtime=int(os.path.getmtime(filename)),
|
|
|
path=self.path
|
|
|
)
|
|
|
os.rename(filename, newfile)
|
|
|
- self.liveplot.emit(newfile)
|
|
|
+ self.liveplot.emit(board_id, newfile)
|
|
|
else:
|
|
|
logging.info("Trigger timeout.")
|
|
|
|
|
@@ -1398,9 +1433,11 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
self.finished.emit()
|
|
|
|
|
|
def quit(self):
|
|
|
+ '''quit this thread'''
|
|
|
self._quit = True
|
|
|
|
|
|
def __del__(self):
|
|
|
+ print 'quite'
|
|
|
board.pci.write(board_id, '0', '9024')
|
|
|
time.sleep(0.1)
|
|
|
board.pci.write(board_id, '0', '902C')
|
|
@@ -1408,6 +1445,7 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
board.pci.write(board_id, '3f0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
|
|
|
def finished():
|
|
|
+ '''Handle the end of the thread'''
|
|
|
board.pci.write(board_id, '0', '9024')
|
|
|
time.sleep(0.1)
|
|
|
board.pci.write(board_id, '0', '902C')
|
|
@@ -1430,9 +1468,15 @@ def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, ti
|
|
|
|
|
|
return
|
|
|
|
|
|
- twt = thread_wait_on_signal(num_of_acquisitions, storage.storage.save_location + '/' + storage.storage.subdirname,
|
|
|
- timeout)
|
|
|
- thread.register(twt)
|
|
|
+ # twt = thread_wait_on_signal(num_of_acquisitions, storage.storage.save_location + '/' + storage.storage.subdirname,
|
|
|
+ # timeout)
|
|
|
+ if not thread.is_registered():
|
|
|
+ twt = thread_wait_on_signal()
|
|
|
+ thread.register(twt)
|
|
|
+ else:
|
|
|
+ thread.disconnect('countUpdate', 'finished', 'liveplot')
|
|
|
+ thread.init(num_of_acquisitions, storage.storage.save_location + '/' + storage.storage.subdirname, timeout)
|
|
|
+ # reconnect signals to make sure the correct versions of methods are called
|
|
|
thread.connect('countUpdate', storage.get_board_specific_storage(board_id).trigger_progressbar.setValue)
|
|
|
thread.connect('finished', finished)
|
|
|
thread.connect('liveplot', _bif_read_and_update_data_from_file)
|