|
@@ -1,1094 +1,1093 @@
|
|
|
-"""
|
|
|
-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 bk
|
|
|
-Functions only used internal in this module will be prefixed _bif_
|
|
|
-"""
|
|
|
-
|
|
|
-import logging
|
|
|
-import time
|
|
|
-from datetime import datetime as dt
|
|
|
-import os
|
|
|
-import copy
|
|
|
-import shutil
|
|
|
-from PyQt4 import QtGui, QtCore
|
|
|
-import numpy as np
|
|
|
-from .backend import board
|
|
|
-from .backend.board import available_boards
|
|
|
-from .backend.DataSet import DataSet
|
|
|
-from .backend.CalibrationHandle import theCalibration
|
|
|
-from .groupedelements import Buttons, Elements, live_plot_windows, cuda_windows
|
|
|
-from . import storage
|
|
|
-from .. import config
|
|
|
-from . import kcgwidget as kcgw
|
|
|
-from .kcgwidget import error
|
|
|
-from .callbacks import callbacks
|
|
|
-from .log import log
|
|
|
-from .globals import glob as global_objects
|
|
|
-
|
|
|
-from time import sleep
|
|
|
-
|
|
|
-tr = kcgw.tr
|
|
|
-
|
|
|
-livePlotData = None
|
|
|
-
|
|
|
-PRINTDEBUG = False
|
|
|
-
|
|
|
-def initStatus(st):
|
|
|
- """
|
|
|
- Initialize Status variables. These variables are used to transfer status variables over different modules.
|
|
|
- :param st: variable to use (most likely a DummyStorage instance)
|
|
|
- :return: -
|
|
|
- """
|
|
|
- st.continuous_read = False
|
|
|
- st.calibrated = False
|
|
|
- st.synced = False
|
|
|
- st.defaults_set = False
|
|
|
- st.status_text = tr("sw", "Ready")
|
|
|
- st.time_scan = False
|
|
|
- st.wait_on_trigger = False
|
|
|
- st.last_file = None
|
|
|
- st.board_connected = True
|
|
|
- st.continuous_interval = 1000
|
|
|
-
|
|
|
-
|
|
|
-# -----------[ Backend Interface ]----------------------
|
|
|
-def _bif_enable_wait_cursor():
|
|
|
- """
|
|
|
- Show the "Wait Cursor"
|
|
|
- """
|
|
|
- QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
|
|
|
-
|
|
|
-
|
|
|
-def _bif_disable_wait_cursor():
|
|
|
- """
|
|
|
- Show the normal Cursor
|
|
|
- """
|
|
|
- QtGui.QApplication.restoreOverrideCursor()
|
|
|
-
|
|
|
-
|
|
|
-def _bif_continuous_read_is_enabled(board_id, popup_title_text=None):
|
|
|
- """
|
|
|
- Checks if continuous read is enabled and if yes shows a popup dialog to ask if it shall be disabled
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param popup_title_text: Text to display in the popup that asks to disable continuous read
|
|
|
- :return: bool (True if continuous read is enabled and not disabled in popup else False)
|
|
|
- """
|
|
|
- if board.get_board_status(board_id).continuous_read:
|
|
|
- if not available_boards.multi_board:
|
|
|
- popup = kcgw.PopupDialog(tr("Dialog", "Continuous read is currently active!\nStop continuous read and proceed?"),
|
|
|
- title=popup_title_text)
|
|
|
- else:
|
|
|
- popup = kcgw.PopupDialog(tr("Dialog", "Board {board_id}\nContinuous read is currently active!\nStop continuous read and proceed?").format(board_id=board_id),
|
|
|
- title=popup_title_text)
|
|
|
- popup.exec_()
|
|
|
- popup.deleteLater()
|
|
|
- if popup.get_return_value() is False:
|
|
|
- return False
|
|
|
- else:
|
|
|
- _bif_set_continuous_read_inactive(board_id)
|
|
|
- Elements.setChecked("continuousread_"+str(board_id), False)
|
|
|
- return True
|
|
|
- else:
|
|
|
- return False
|
|
|
-
|
|
|
-
|
|
|
-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)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_status_readout(board_id):
|
|
|
- """
|
|
|
- Read Status from board and update variables
|
|
|
- as well as enable and disable corresponding Buttons
|
|
|
- :return: -
|
|
|
- """
|
|
|
- # part_TODO: NOTE: Problem with this is that certain buttons will be greyed out until other buttons are pressed
|
|
|
- # part_TODO: even if only the gui is restarted and the board is in the same state
|
|
|
- """
|
|
|
- if kcgw.testing:
|
|
|
- return
|
|
|
- if board.is_active(board_id):
|
|
|
- Buttons.setEnabled("after_start_{}".format(board_id), True)
|
|
|
- Buttons.setEnabled("start_board_{}".format(board_id), False)
|
|
|
- Buttons.setEnabled("continuous_read_{}".format(board_id), True)
|
|
|
-
|
|
|
- # MenuItems.setEnabled("continuous_read", True)
|
|
|
- else:
|
|
|
- board.get_board_status(board_id).calibrated = False
|
|
|
- board.get_board_status(board_id).synced = False
|
|
|
- board.get_board_status(board_id).defaults_set = False
|
|
|
- Buttons.setEnabled("after_start_{}".format(board_id), False)
|
|
|
- Buttons.setEnabled("continuous_read_{}".format(board_id), False)
|
|
|
- Buttons.setEnabled("synchronize_{}".format(board_id), board.get_board_status(board_id).calibrated)
|
|
|
- Buttons.setEnabled("set_defaults_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
- Buttons.setEnabled("acquire_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
- Buttons.setEnabled("acquireTrigger_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
- Elements.setEnabled("timing_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
- """
|
|
|
- storage.get_board_specific_storage(board_id).update_LED()
|
|
|
-
|
|
|
-
|
|
|
-backup_readout = bk_status_readout
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-class _bif_ProgressBar(QtGui.QProgressBar):
|
|
|
- """
|
|
|
- Simple Progressbar class.
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self, min, max, text):
|
|
|
- super(_bif_ProgressBar, self).__init__()
|
|
|
- self.setRange(min, max)
|
|
|
- self.setMaximumHeight(18)
|
|
|
- # kcgw.statusbar.clearMessage()
|
|
|
- self.label = QtGui.QLabel(text)
|
|
|
- global_objects.get_global('statusbar').insertWidget(0, self.label)
|
|
|
- global_objects.get_global('statusbar').insertWidget(1, self)
|
|
|
- self.setValue(0)
|
|
|
- QtGui.qApp.processEvents()
|
|
|
-
|
|
|
- def remove(self, timeout=None):
|
|
|
- """
|
|
|
- Remove this instance of a progressbar
|
|
|
- :param timeout: the time from calling this function to wanishing of the progressbar
|
|
|
- :return: -
|
|
|
- """
|
|
|
-
|
|
|
- def remove_progressbar():
|
|
|
- global_objects.get_global('statusbar').removeWidget(self)
|
|
|
- global_objects.get_global('statusbar').removeWidget(self.label)
|
|
|
- # kcgw.statusbar.showMessage(board.status.status_text)
|
|
|
- self.destroy()
|
|
|
-
|
|
|
- if timeout:
|
|
|
- QtCore.QTimer.singleShot(timeout, remove_progressbar)
|
|
|
- else:
|
|
|
- remove_progressbar()
|
|
|
-
|
|
|
-
|
|
|
-def bk_run_sequence(board_id, name):
|
|
|
- print("________________bk_run_sequence__________________________________________")
|
|
|
- log(board_id=board_id, additional=str(name))
|
|
|
- comment = board.get_board_config(board_id).get_sequence_comment(name)
|
|
|
-
|
|
|
-
|
|
|
- _bif_enable_wait_cursor()
|
|
|
- if _bif_continuous_read_is_enabled(board_id, tr("Button", "Calibrate Board")):
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- return
|
|
|
-
|
|
|
- def fin():
|
|
|
- bk_status_readout()
|
|
|
- progressbar.remove(0)
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- board.get_board_config(board_id).update('header', board.get_board_config(board_id)._config['header'])
|
|
|
- board.get_board_config(board_id).update('pilot_bunch', board.get_board_config(board_id)._config['pilot_bunch'])
|
|
|
-
|
|
|
- progressbar = _bif_ProgressBar(0, 10, tr("sw", comment))
|
|
|
-
|
|
|
- logging.info('Started ' + comment)
|
|
|
- try:
|
|
|
- if not board.get_board_config(board_id).run_sequence(name, progressbar):
|
|
|
- logging.error(comment + " failed")
|
|
|
- fin()
|
|
|
- return
|
|
|
-
|
|
|
- statval = board.get_board_config(board_id).get_sequence_status(name)
|
|
|
- if statval == "calibrated": board.get_board_status(board_id).calibrated = True
|
|
|
- elif statval == "synced": board.get_board_status(board_id).synced = True
|
|
|
- elif statval == "PLL500M": board.get_board_config(board_id).update('samplingrate', 1)
|
|
|
- elif statval == "PLL1G": board.get_board_config(board_id).update('samplingrate', 2)
|
|
|
-
|
|
|
- except board.BoardError as e:
|
|
|
- logging.error(comment + " failed: {}".format(str(e)))
|
|
|
- fin()
|
|
|
- return
|
|
|
-
|
|
|
-
|
|
|
- logging.info(comment + " successful!")
|
|
|
- fin()
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-def bk_write_values(board_id, defaults=False):
|
|
|
- """
|
|
|
- Write values to board.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param defaults: (bool) if True Writes default values
|
|
|
- :return: -
|
|
|
- """
|
|
|
- _bif_enable_wait_cursor()
|
|
|
- if defaults:
|
|
|
- log(board_id=board_id, additional="Set Default Values")
|
|
|
- else:
|
|
|
- log(board_id=board_id, additional="Update Values on board")
|
|
|
- if _bif_continuous_read_is_enabled(board_id, tr("Dialog", "Update Values on Board")):
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- return
|
|
|
-
|
|
|
-
|
|
|
- if defaults:
|
|
|
- board.get_board_config(board_id)._set_defaults()
|
|
|
- logging.info("Setting default Values")
|
|
|
- else:
|
|
|
- logging.info("Updating Values")
|
|
|
-
|
|
|
- try:
|
|
|
- board.get_board_config(board_id).notify_all_observers(write=True)
|
|
|
- except board.BoardError as e:
|
|
|
- logging.error("Updating Values failed: {}".format(str(e)))
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- bk_status_readout()
|
|
|
- return
|
|
|
-
|
|
|
- board.get_board_status(board_id).defaults_set = True
|
|
|
-
|
|
|
-
|
|
|
- if defaults:
|
|
|
- logging.info("Default values set successfully!")
|
|
|
- else:
|
|
|
- logging.info("Updated values successfully!")
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- bk_status_readout()
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-def bk_stop_board(board_id):
|
|
|
- """
|
|
|
- Stops the board and shuts it down
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- _bif_enable_wait_cursor()
|
|
|
- log(board_id=board_id, additional="Stop Board")
|
|
|
- if _bif_continuous_read_is_enabled(board_id, tr("Dialog", "Soft Reset Board")):
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- return
|
|
|
-
|
|
|
- try:
|
|
|
- logging.info("Switching Off Board {}".format(board_id))
|
|
|
- board.pci.write(board_id, '0x9040')
|
|
|
- board.pci.stop_dma(board_id)
|
|
|
- board.stop_board(board_id)
|
|
|
- time.sleep(0.5)
|
|
|
- except board.BoardError as e:
|
|
|
- logging.error("Sequence failed: {}".format(str(e)))
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- bk_status_readout()
|
|
|
- return
|
|
|
-
|
|
|
- logging.info("Board switched off successfully!")
|
|
|
- Buttons.setEnabled("after_start_{}".format(board_id), False)
|
|
|
- Buttons.setEnabled("start_board_{}".format(board_id), True)
|
|
|
- board.get_board_status(board_id).calibrated = False
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- bk_status_readout()
|
|
|
-
|
|
|
-def bk_soft_reset(board_id):
|
|
|
- """
|
|
|
- Perform a soft reset.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return:
|
|
|
- """
|
|
|
- _bif_enable_wait_cursor()
|
|
|
- log(board_id=board_id, additional="Soft Reset")
|
|
|
- if _bif_continuous_read_is_enabled(board_id, tr("Dialog", "Soft Reset Board")):
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- return
|
|
|
-
|
|
|
- try:
|
|
|
- logging.info("Soft-Resetting Board {}...".format(board_id))
|
|
|
- board.soft_reset(board_id)
|
|
|
- except board.BoardError as e:
|
|
|
- logging.error("Sequence failed: {}".format(str(e)))
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- bk_status_readout()
|
|
|
- return
|
|
|
-
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- bk_status_readout()
|
|
|
- board.get_board_config(board_id).update('header', True) # reset header (might be reset by soft reset)
|
|
|
- logging.info("Soft-Reset successful.")
|
|
|
-
|
|
|
-
|
|
|
-def bk_update_config(board_id, key, value, silent=False):
|
|
|
- """
|
|
|
- Interface to the update command of the BoardConfiguration class.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param key: Key to update
|
|
|
- :param value: Value to set for key
|
|
|
- :param silent: (bool) if True do not inform observers on update
|
|
|
- :return: -
|
|
|
- """
|
|
|
- try:
|
|
|
- if silent:
|
|
|
- board.get_board_config(board_id).updateSilent(key, value)
|
|
|
- else:
|
|
|
- board.get_board_config(board_id).update(key, value)
|
|
|
- #print(key, value)
|
|
|
- except board.BoardError as e:
|
|
|
- logging.error("Setting value of {} failed: {}".format(key, str(e)))
|
|
|
-
|
|
|
-
|
|
|
-def bk_get_config(board_id, key,entry=None):
|
|
|
- """
|
|
|
- Interface to the get command of the BoardConfiguration class.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param key: Key to get the value for
|
|
|
- :return: value stored for key
|
|
|
- """
|
|
|
- if entry == None:
|
|
|
- return board.get_board_config(board_id).get(key)
|
|
|
- else:
|
|
|
- return board.get_board_config(board_id).get(key)[entry]
|
|
|
-
|
|
|
-
|
|
|
-def bk_get_board_status(board_id, status_variable):
|
|
|
- """
|
|
|
- Interface to the status class for each board.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param status_variable: Key to get the value for
|
|
|
- :return: value stored for key
|
|
|
- """
|
|
|
- return getattr(board.get_board_status(board_id), status_variable, None)
|
|
|
-
|
|
|
-
|
|
|
-def bk_get_status(board_id):
|
|
|
- """
|
|
|
- Interface to the get_status of the board
|
|
|
- NOTE: This is not get_board_status
|
|
|
- :return: status dictionary
|
|
|
- """
|
|
|
- return board.get_status(board_id)
|
|
|
-
|
|
|
-
|
|
|
-def bk_change_num_of_turns(board_id, value, silent=False):
|
|
|
- """
|
|
|
- Send new number of turns to board and update in config
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param value: the value to send
|
|
|
- :param silent: (bool) if True do not inform observers on update
|
|
|
- :return: -
|
|
|
- """
|
|
|
- bk_update_config(board_id, "turns_observe", value, silent=silent)
|
|
|
-
|
|
|
-
|
|
|
-def bk_change_num_of_skipped_turns(board_id, value, silent=False):
|
|
|
- """
|
|
|
- Send new number of turns to skip to board and update in config
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param value: the value to send
|
|
|
- :param silent: (bool) if True do not inform observers on update
|
|
|
- :return: -
|
|
|
- """
|
|
|
- bk_update_config(board_id, "turns_skip", value, silent=silent)
|
|
|
-
|
|
|
-
|
|
|
-def bk_change_count(board_id, value, silent=False):
|
|
|
- """
|
|
|
- Change the number of acquisitions you want to make.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param value: (int) Number of acquisitions
|
|
|
- :param silent: (bool) if True do not inform observers on update
|
|
|
- :return: -
|
|
|
- """
|
|
|
- bk_update_config(board_id, "acquisition_count", value, silent=silent)
|
|
|
-
|
|
|
-
|
|
|
-def bk_change_wait(board_id, value, silent=False):
|
|
|
- """
|
|
|
- Change the time between acquisitions.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param value: (bool) Time in seconds
|
|
|
- :param silent: (bool) if True do not inform observers on update
|
|
|
- :return: -
|
|
|
- """
|
|
|
- bk_update_config(board_id, "turns_wait_time", value, silent=silent)
|
|
|
-
|
|
|
-
|
|
|
-def bk_change_build_spectrograms(board_id, value, silent=False):
|
|
|
- """
|
|
|
- Change if spectrograms are built or not)
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param value: (bool) True or False built or not
|
|
|
- :param silent: (bool) if True do not inform observers on update
|
|
|
- :return:
|
|
|
- """
|
|
|
- bk_update_config(board_id, "build_spectrograms", value, silent=silent)
|
|
|
-
|
|
|
-
|
|
|
-def bk_change_pilot_bunch(board_id, value, silent=False):
|
|
|
- """
|
|
|
- Change if pilot bunch is simulated
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param value: (bool) True or False to simulate or not
|
|
|
- :param silent: (bool) if True do not inform observers on update
|
|
|
- :return:
|
|
|
- """
|
|
|
- bk_update_config(board_id, "pilot_bunch", value, silent=silent)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_update_working_dir():
|
|
|
- """
|
|
|
- make Shure the currently set directory exists and a calibration File is present
|
|
|
- """
|
|
|
- path = str(os.path.join(storage.storage.save_location, storage.storage.subdirname))
|
|
|
- print(path)
|
|
|
- if not os.path.isdir(path):
|
|
|
- os.makedirs(path)
|
|
|
- shutil.copy(config.config_path("calibration.hdf"), path)
|
|
|
- theCalibration.openFile(os.path.join(path,'calibration.hdf'))
|
|
|
- return path
|
|
|
-
|
|
|
-def _bif_iterate_spectrograms(board_id, path):
|
|
|
- """
|
|
|
- BROKEN (DOES NOT GET ANY DATA)
|
|
|
- Built Spectrograms line by line
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param path: where to built the spectrogram
|
|
|
- :return: -
|
|
|
- """
|
|
|
- #print('_bif_iterate_spectrograms')
|
|
|
- return # because it is broken
|
|
|
- if not os.path.isdir(str(path)):
|
|
|
- return
|
|
|
-
|
|
|
- # how does this get data? dataset.data does not exist
|
|
|
- transform = dataset.data.fft(1, frm=0, to=-1)
|
|
|
- for i in range(config.bunches_per_turn - 1):
|
|
|
- filename = os.path.join(storage.storage.save_location, storage.storage.subdirname, str(path), "%i.hsp" % i)
|
|
|
- write_header = False
|
|
|
- if not os.path.isfile(filename):
|
|
|
- write_header = True
|
|
|
- f = open(filename, 'ab')
|
|
|
- if write_header:
|
|
|
- f.write("#hsp\n") # heb spectrogram magic number
|
|
|
- f.write("#"+str(board.get_board_config(board_id).get("turns_skip")))
|
|
|
- f.write("\n")
|
|
|
- line = transform[i, :]
|
|
|
- f.write('{:0.3f} '.format(time.time()))
|
|
|
- for e in line:
|
|
|
- f.write("%s " % np.absolute(e))
|
|
|
- f.write("\n")
|
|
|
- f.close()
|
|
|
-
|
|
|
-
|
|
|
-def _bif_read_data_and_save(board_id):
|
|
|
- """
|
|
|
- Tell the pci command to start acquisition and save data
|
|
|
- Also generates the filename from settings
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return:
|
|
|
- """
|
|
|
- if PRINTDEBUG: print(time.time(), '_bif_read_data_and_save start')
|
|
|
- now = time.time()
|
|
|
- _bif_update_working_dir()
|
|
|
- filename = os.path.join(storage.storage.save_location, storage.storage.subdirname,'{:0.3f}.out'.format(now))
|
|
|
- board.get_board_status(board_id).last_file = filename
|
|
|
-
|
|
|
- try:
|
|
|
- simulate = board.get_board_config(board_id).get("pilot_bunch")
|
|
|
- try:
|
|
|
- if PRINTDEBUG: print(time.time(), '_bif_read_data_and_save acquire_data')
|
|
|
- board.acquire_data(board_id, filename, simulate=simulate)
|
|
|
- if not os.path.isfile(filename):
|
|
|
- error(0x001, "No File Created")
|
|
|
- except IndexError:
|
|
|
- error(0x002, "Unexpected output of pci for number of turns to observe. Returning")
|
|
|
- return
|
|
|
- _bif_read_and_update_data_from_file(board_id, filename)
|
|
|
- except board.BoardError as e:
|
|
|
- logging.error("Reading failed: {}".format(str(e)))
|
|
|
-
|
|
|
- if PRINTDEBUG: print(time.time(), '_bif_read_data_and_save stop')
|
|
|
-
|
|
|
-
|
|
|
-def _bif_read_and_update_data_from_file(board_id, filename):
|
|
|
- """
|
|
|
- Proxy function for _bif_read_and_update to call with correct read_func
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param filename: filename to read data from
|
|
|
- :return: -
|
|
|
- """
|
|
|
- if kcgw.testing:
|
|
|
- filename = os.path.join(storage.storage.save_location, storage.storage.subdirname,'testing.out')
|
|
|
- _bif_read_and_update(board_id, 1, str(filename))
|
|
|
-
|
|
|
-
|
|
|
-def _bif_read_and_update_data_from_string(board_id, raw_data):
|
|
|
- """
|
|
|
- Proxy function for _bif_read_and_update to call with correct read_func
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param raw_data: Data as string
|
|
|
- :return: -
|
|
|
- """
|
|
|
- _bif_read_and_update(board_id, 0, raw_data)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_read_and_update(board_id, read_type, dataOrName):
|
|
|
- """
|
|
|
- Function to read data from file or string (depending on read_func) and update plots etc.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param read_type: 0 - from String; 1 - from File
|
|
|
- :param dataOrName: filename or raw_data
|
|
|
- :return: -
|
|
|
- """
|
|
|
- if PRINTDEBUG: print(time.time(), '_bif_read_and_update start')
|
|
|
- _bif_enable_wait_cursor()
|
|
|
-
|
|
|
- header = board.get_board_config(board_id).get('header')
|
|
|
- # TODO: force_read: meaning ignore cache and read new -> in the old gui this was a commandline option
|
|
|
- # TODO: cache_data: meaning cache already processed numpy data -> in the old gui this was a commandline option
|
|
|
- delays = {'c330':board.get_board_config(board_id).get('delay_330_th'), 'c25':board.get_board_config(board_id).get('delay_25_th'),
|
|
|
- 'c25b':board.get_board_config(board_id).get('delay_25_th_2'), 'f':board.get_board_config(board_id).get('chip_delay')}
|
|
|
- if read_type == 0:
|
|
|
- data = DataSet(stringData=dataOrName, delays=delays, tRev=config.tRev, bunchesPerTurn=config.bunches_per_turn, shiftFMC2=config.shiftFMC2)
|
|
|
- else:
|
|
|
- data = DataSet(filename=dataOrName, delays=delays, tRev=config.tRev, bunchesPerTurn=config.bunches_per_turn, shiftFMC2=config.shiftFMC2)
|
|
|
-
|
|
|
- board.get_board_config(board_id).update('lastDataSet', data)
|
|
|
-
|
|
|
- QtGui.qApp.processEvents()
|
|
|
-
|
|
|
- _bif_disable_wait_cursor()
|
|
|
- if PRINTDEBUG: print(time.time(), '_bif_read_and_update stop')
|
|
|
-
|
|
|
-def bk_acquire(board_id):
|
|
|
- """
|
|
|
- Toggle Acqisition
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return:
|
|
|
- """
|
|
|
- if not bk_get_config(board_id, 'use_trigger'):
|
|
|
- if board.get_board_status(board_id).acquisition == True:
|
|
|
- log(board_id=board_id, additional="Manually Stopped Acquisition\nPerformed Acquisitions: " + str(storage.storage.current_acquisition))
|
|
|
- _bif_stop_acquisition(board_id)
|
|
|
- else:
|
|
|
- _bif_start_acquisition(board_id)
|
|
|
- else:
|
|
|
- bk_toggle_wait_on_trigger(board_id)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_stop_acquisition(board_id):
|
|
|
- """
|
|
|
- Stop acquisition
|
|
|
- This does stop the timer started by _bif_start_acquisition()
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- board.get_board_status(board_id).acquisition = False
|
|
|
- storage.get_board_specific_storage(board_id).acquisition_progressbar.remove(0)
|
|
|
- storage.get_board_specific_storage(board_id).acquisition_timer.stop()
|
|
|
- # for elem in Elements.getElements("acquireTrigger_{}".format(board_id)):
|
|
|
- # if isinstance(elem, QtGui.QShortcut) or isinstance(elem, QtGui.QCheckBox):
|
|
|
- # continue
|
|
|
- # elem.setIcon(QtGui.QIcon(config.install_path + config.startIcon))
|
|
|
- # elem.setText(tr("Button", "Start Acquisition"))
|
|
|
- Elements.setEnabled('acquire_{}'.format(board_id), True)
|
|
|
- callbacks.callback('acquisition_stopped', board_id)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_start_acquisition(board_id):
|
|
|
- """
|
|
|
- Start acquisition.
|
|
|
- This will start a timer to automatically acquire data.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- log(board_id=board_id, additional="Started Acquisition")
|
|
|
- board.get_board_status(board_id).acquisition = True
|
|
|
- Elements.setEnabled('acquire_{}'.format(board_id), False)
|
|
|
- # for elem in Elements.getElements("acquireTrigger_{}".format(board_id)):
|
|
|
- # if isinstance(elem, QtGui.QShortcut) or isinstance(elem, QtGui.QCheckBox):
|
|
|
- # continue
|
|
|
- # elem.setIcon(QtGui.QIcon(config.install_path + config.stopIcon))
|
|
|
- # elem.setText(tr("Button", "Stop Acquisition"))
|
|
|
- callbacks.callback('acquisition_started', board_id)
|
|
|
- storage.get_board_specific_storage(board_id).acquisition_timer = QtCore.QTimer()
|
|
|
- num_acquisitions = board.get_board_config(board_id).get("acquisition_count")
|
|
|
- storage.get_board_specific_storage(board_id).acquisition_progressbar = \
|
|
|
- _bif_ProgressBar(0, num_acquisitions, tr("sw", "Acquiring with board ")+str(board_id))
|
|
|
- # storage.storage.acquisition_progressbar = acquisition_progressbar
|
|
|
-
|
|
|
- # We increase already once because we do a single acquisition before the
|
|
|
- # timer is started, otherwise we have to wait until the timer fires the
|
|
|
- # first time.
|
|
|
- try:
|
|
|
- if isinstance(storage.storage.current_acquisition, dict):
|
|
|
- storage.storage.current_acquisition[board_id] = 1
|
|
|
- else:
|
|
|
- storage.storage.current_acquisition = {board_id: 1}
|
|
|
- except storage.StorageError:
|
|
|
- storage.storage.current_acquisition = {board_id: 1}
|
|
|
- _bif_read_data_and_save(board_id)
|
|
|
-
|
|
|
- if board.get_board_config(board_id).get("build_spectrograms"):
|
|
|
- spectrogram_dir = os.path.join(storage.storage.save_location, storage.storage.subdirname, "spectrograms_{:0.3f}".format(time.time()))
|
|
|
- os.makedirs(spectrogram_dir)
|
|
|
- _bif_iterate_spectrograms(board_id, spectrogram_dir) # TODO: not here?
|
|
|
-
|
|
|
- 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])
|
|
|
- _bif_read_data_and_save(board_id)
|
|
|
- log(board_id=board_id, additional="Acquisition {:3d}\n".format(storage.storage.current_acquisition[board_id]) + "Filename: "+board.get_board_status(board_id).last_file.split('/')[-1])
|
|
|
- if board.get_board_config(board_id).get("build_spectrograms"):
|
|
|
- _bif_iterate_spectrograms(board_id, spectrogram_dir) # TODO: not here ?
|
|
|
- else:
|
|
|
- log(board_id=board_id, additional="Stopped Acquisition")
|
|
|
- _bif_stop_acquisition(board_id)
|
|
|
- storage.get_board_specific_storage(board_id).acquisition_progressbar.remove(0)
|
|
|
-
|
|
|
- storage.get_board_specific_storage(board_id).acquisition_timer.timeout.connect(on_timeout)
|
|
|
- storage.get_board_specific_storage(board_id).acquisition_timer.start(board.get_board_config(board_id).get('turns_wait_time') * 1000)
|
|
|
-
|
|
|
-
|
|
|
-def bk_single_read(board_id, info=""):
|
|
|
- """
|
|
|
- Perform a single read of data
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return:
|
|
|
- """
|
|
|
- if info != "":
|
|
|
- info += "\n"
|
|
|
- Elements.setEnabled("acquire_{}".format(board_id), False)
|
|
|
- _bif_read_data_and_save(board_id)
|
|
|
- log(board_id=board_id, additional="Single Read\n" + info + "Filename: "+board.get_board_status(board_id).last_file.split('/')[-1])
|
|
|
- Elements.setEnabled("acquire_{}".format(board_id), True)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_set_continuous_read_active(board_id):
|
|
|
- """
|
|
|
- Enable continuous read
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- Elements.setEnabled("acquire_{}".format(board_id), False)
|
|
|
- Elements.setEnabled("acquireTrigger_{}".format(board_id), False)
|
|
|
- Elements.setEnabled("continuous_read_{}".format(board_id), True)
|
|
|
- board.get_board_status(board_id).continuous_read = True
|
|
|
-
|
|
|
-
|
|
|
-def _bif_set_continuous_read_inactive(board_id):
|
|
|
- """
|
|
|
- Disable continuous read
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- if board.get_board_status(board_id).continuous_read:
|
|
|
- board.get_board_status(board_id).continuous_read = False
|
|
|
- storage.get_board_specific_storage(board_id).continuous_read_timer.stop()
|
|
|
- Elements.setEnabled('acquire_{}'.format(board_id), True)
|
|
|
- Elements.setEnabled('acquireTrigger_{}'.format(board_id), True)
|
|
|
-
|
|
|
-
|
|
|
-def bk_continuous_read(board_id, interval=100):
|
|
|
- """
|
|
|
- Toggle continuous read
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param interval: Time between two consecutive reads.
|
|
|
- :return: -
|
|
|
- """
|
|
|
- if not board.get_board_status(board_id).continuous_read:
|
|
|
- _bif_set_continuous_read_active(board_id)
|
|
|
- _bif_continuous_read(board_id, interval)
|
|
|
- else:
|
|
|
- _bif_set_continuous_read_inactive(board_id)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_continuous_read(board_id, interval=None):
|
|
|
- """
|
|
|
- Perform continuous read based on a timer.
|
|
|
- :param interval:
|
|
|
- :return:
|
|
|
- """
|
|
|
- if interval is not None:
|
|
|
- # TODO: ueberall checken, dass der board specific storage verwendet wird
|
|
|
- storage.get_board_specific_storage(board_id).continuous_interval = interval
|
|
|
- storage.get_board_specific_storage(board_id).continuous_read_timer = QtCore.QTimer()
|
|
|
- logging.info("Start continuous read")
|
|
|
-
|
|
|
- def continuous_read_step():
|
|
|
- if board.get_board_status(board_id).continuous_read:
|
|
|
- _bif_read_data(board_id)
|
|
|
- storage.get_board_specific_storage(board_id).continuous_read_timer.singleShot(storage.storage.continuous_interval, continuous_read_step)
|
|
|
-
|
|
|
- storage.get_board_specific_storage(board_id).continuous_read_timer.singleShot(storage.storage.continuous_interval, continuous_read_step)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_read_data(board_id, returnBack=False):
|
|
|
- """
|
|
|
- Reads data acquired by board.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return:
|
|
|
- """
|
|
|
- board.pci.start = time.time()
|
|
|
- if PRINTDEBUG: print('{:4.3f} _bif_read_data start'.format(time.time()-board.pci.start))
|
|
|
- try:
|
|
|
- if board.get_board_config(board_id).get('pilot_bunch'):
|
|
|
- board.start_pilot_bunch_emulator(board_id)
|
|
|
-
|
|
|
- board.start_acquisition(board_id)
|
|
|
- try:
|
|
|
- board.wait_for_revolutions(board_id)
|
|
|
- except IndexError:
|
|
|
- error(0x002, "Unexpected output of pci for number of turns to observe. Returning")
|
|
|
- return None
|
|
|
- board.stop_acquisition(board_id)
|
|
|
- board.enable_transfer(board_id)
|
|
|
- if PRINTDEBUG: print('{:4.3f} _bif_read_data.read_data_to_variable'.format(time.time()-board.pci.start))
|
|
|
- data_raw = board.pci.read_data_to_variable(board_id)
|
|
|
- if PRINTDEBUG: print('{:4.3f} _bif_read_data.read_data_to_variable done'.format(time.time()-board.pci.start))
|
|
|
-
|
|
|
- if returnBack:
|
|
|
- if PRINTDEBUG: print('{:4.3f} _bif_read_data return data_raw'.format(time.time()-board.pci.start))
|
|
|
- return data_raw
|
|
|
- else:
|
|
|
- if PRINTDEBUG: print('{:4.3f} _bif_read_data call'.format(time.time()-board.pci.start))
|
|
|
- _bif_read_and_update_data_from_string(board_id, data_raw)
|
|
|
- if PRINTDEBUG: print('{:4.3f} _bif_read_data call done'.format(time.time()-board.pci.start))
|
|
|
-
|
|
|
- except board.BoardError as e:
|
|
|
- logging.error("Reading failed for board {}: {}".format(str(board_id), str(e)))
|
|
|
-
|
|
|
- if PRINTDEBUG: print('{:4.3f} _bif_read_data return None'.format(time.time()-board.pci.start))
|
|
|
- return None
|
|
|
-
|
|
|
-def bk_board_connected(board_id):
|
|
|
- """
|
|
|
- Interface to the board to check if it is connected.
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- if not available_boards.has_boards:
|
|
|
- return False
|
|
|
- else:
|
|
|
- return board_id in available_boards.board_ids
|
|
|
-
|
|
|
-
|
|
|
-def bk_get_temperature(board_id):
|
|
|
- """
|
|
|
- Get Temperature from board and format it
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- fpga_temp_raw_hex = board.pci.read(board_id, 1, '0x9110')[0]
|
|
|
- fpga_temp_raw_hex = fpga_temp_raw_hex[-3:]
|
|
|
- fpga_temp_raw_bin = '{0:012b}'.format(int(fpga_temp_raw_hex, 16))
|
|
|
- fpga_temp_encoded = board.get_dec_from_bits(fpga_temp_raw_bin, 9, 0)
|
|
|
- fpga_temp_celsius = '{0:2.2f}'.format(((fpga_temp_encoded * 503.975) / 1024) - 273.15)
|
|
|
- return fpga_temp_celsius
|
|
|
-
|
|
|
-
|
|
|
-backup_get_temp = bk_get_temperature
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-def bk_check_for_board(board_id):
|
|
|
- """
|
|
|
- Check if board is connected
|
|
|
- Also overrides the bk_status_readout function with a function that does nothing (suppresses read attempts that
|
|
|
- generate errors - if no board is connected, there is nothing to read from)
|
|
|
- Also overrides the bk_get_temperature function as of the same reasons
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :return: -
|
|
|
- """
|
|
|
- # 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:
|
|
|
- globals()['bk_status_readout'] = backup_readout
|
|
|
- globals()['bk_get_temperature'] = backup_get_temp
|
|
|
- board.get_board_status(board_id).board_connected = True
|
|
|
-
|
|
|
- else:
|
|
|
- Elements.setEnabled('no_board_{}'.format(board_id), False)
|
|
|
-
|
|
|
- def do_nothing():
|
|
|
- pass
|
|
|
-
|
|
|
- def no_temp(board_id):
|
|
|
- return "-"
|
|
|
-
|
|
|
- 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))
|
|
|
- elif board_status == None:
|
|
|
- board.get_board_status(board_id).status_text = tr("sw", "Software Interface not found")
|
|
|
-
|
|
|
-
|
|
|
-def bk_toggle_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, timeout=None, method=None):
|
|
|
- """
|
|
|
- Toggle waiting for trigger signal to acquire
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param num_of_acquisitions: number of acquisitions to wait for
|
|
|
- :param skip: how much trigger signals to skip between acquisitions
|
|
|
- :param timeout: the timeout for the pci to wait for date
|
|
|
- :param method: wait method to use
|
|
|
- 1 for wait in pci command and 2 for waiting until register is set that KAPTURE has read data
|
|
|
- NOTE: this also means that method 1 enables simultaneous read and write to dma and method 2 does write and
|
|
|
- read sequentially
|
|
|
- :return:
|
|
|
- """
|
|
|
- thread = storage.get_board_specific_storage(board_id).setdefault('TriggerThread', storage.ThreadStorage())
|
|
|
- if thread.running:
|
|
|
- Elements.getElements("acquireTrigger_{}".format(board_id))[0].setText(tr("Button", "Stopping Acquisition"))
|
|
|
- # FIXME: Button not updated otherwise:
|
|
|
- QtGui.qApp.processEvents()
|
|
|
- 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):
|
|
|
- # continue
|
|
|
- # elem.setText(tr("Button", "Stopping Acquisition"))
|
|
|
- # elem.setEnabled(False)
|
|
|
- else:
|
|
|
- log(board_id=board_id, additional="Start wait on trigger on board {}".format(board_id))
|
|
|
- # for elem in Elements.getElements("acquireTrigger_{}".format(board_id)):
|
|
|
- # if isinstance(elem, QtGui.QShortcut):
|
|
|
- # continue
|
|
|
- # elem.setIcon(QtGui.QIcon(config.install_path + config.stopIcon))
|
|
|
- # elem.setText(tr("Button", "Stop Acquisition"))
|
|
|
- Elements.setEnabled('acquire_{}'.format(board_id), False)
|
|
|
- callbacks.callback('acquisition_started', board_id)
|
|
|
- _bif_start_wait_on_trigger(board_id, num_of_acquisitions, skip, timeout, method)
|
|
|
-
|
|
|
-
|
|
|
-def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, timeout=None, method=None):
|
|
|
- """
|
|
|
- Start waiting on external acquisition trigger. This starts the timer
|
|
|
- :param board_id: id of the board do manipulate
|
|
|
- :param num_of_acquisitions: number of acquisitions to do
|
|
|
- :param count_label: Handle for the countlabel
|
|
|
- :param method: wait method to use
|
|
|
- 1 for wait in pci command and 2 for waiting until register is set that KAPTURE has read data
|
|
|
- NOTE: this also means that method 1 enables simultaneous read and write to dma and method 2 does write and
|
|
|
- read sequentially
|
|
|
- :return: -
|
|
|
- """
|
|
|
-
|
|
|
- # FIXme: This is a work around, for method 2 to work everytime a standard single read needs to be perform before acquisition is started
|
|
|
- board.acquire_data(board_id, '/dev/null')
|
|
|
- #with workaround no flush dema need, because it is done at end of board.acquire_data() anyway.
|
|
|
- #board.flush_dma(board_id) # TODO: really at begining and end of function necessary?
|
|
|
- thread = storage.get_board_specific_storage(board_id).setdefault('TriggerThread', storage.ThreadStorage())
|
|
|
- if thread.running:
|
|
|
- logging.info("Wait already running on board {}".format(board_id))
|
|
|
- return
|
|
|
- log(board_id=board_id, additional="Start wait on trigger")
|
|
|
- board.get_board_status(board_id).wait_on_trigger = True
|
|
|
- _bif_update_working_dir()
|
|
|
-
|
|
|
- if not num_of_acquisitions:
|
|
|
- num_of_acquisitions = bk_get_config(board_id, 'acquisition_count')
|
|
|
- if not skip:
|
|
|
- skip = bk_get_config(board_id, 'trigger_skip')
|
|
|
- if not timeout:
|
|
|
- timeout = bk_get_config(board_id, 'trigger_timeout')
|
|
|
- if not method:
|
|
|
- method = bk_get_config(board_id, 'trigger_method')
|
|
|
-
|
|
|
- storage.get_board_specific_storage(board_id).trigger_progressbar = \
|
|
|
- _bif_ProgressBar(0, num_of_acquisitions, tr("sw", "Acquiring with board ")+str(board_id))
|
|
|
- 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
|
|
|
-
|
|
|
- # 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
|
|
|
- # I don't have an idea why it crashes.
|
|
|
- # A possible reason could the os.rename be (or even the board.safe_call as that saves data to the disk) But I think
|
|
|
- # this is rather unlikely
|
|
|
- # ~~NOTE~~: the thread of calibration also triggered segfaults sometimes. But this seems to be miraculously solved.
|
|
|
- # 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(int, str) # This has to be changed if board_id is no integer
|
|
|
-
|
|
|
- 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
|
|
|
- self._quit = False
|
|
|
-
|
|
|
- # Elements.setEnabled('acquireTrigger_{}'.format(board_id), False) # exclude=Elements.getElements('wait_on_trigger_{}'.format(board_id)))
|
|
|
-
|
|
|
- def wait_rw_simul(self): # Method 1
|
|
|
- '''Wait simultaniously (with the pci command) for a trigger signal'''
|
|
|
- if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
- board.pci.write(board_id, 'f00', hex_mask='f00') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
- else:
|
|
|
- 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 range(self.noa):
|
|
|
- # def step():
|
|
|
- if self._quit:
|
|
|
- break
|
|
|
-
|
|
|
- timestamp = time.time()
|
|
|
- filename = os.path.join(self.path, '{:0.3f}.out'.format(timestamp))
|
|
|
- board.pci.read_data_to_file(board_id, filename=filename, timeout=(self.timeout*1000000))
|
|
|
- # rename with correct timestamp - last modified time
|
|
|
- self.countUpdate.emit(num_of_acq + 1)
|
|
|
-
|
|
|
- # file operations
|
|
|
- if not os.path.isfile(filename):
|
|
|
- error(0x001, "No File Created")
|
|
|
- continue
|
|
|
-
|
|
|
- newfile = os.path.join(self.path, 'trigger_{num:05}_{htime}_{unixtime}.out'.format(
|
|
|
- num=num_of_acq,
|
|
|
- htime=dt.fromtimestamp(os.path.getmtime(filename)).strftime('%Y-%m-%dT%Hh%Mm%Ss%f'),
|
|
|
- unixtime=np.round(timestamp, 3)
|
|
|
- ))
|
|
|
- os.rename(filename, newfile)
|
|
|
- if os.path.getsize(newfile) > 0:
|
|
|
- self.liveplot.emit(board_id, newfile)
|
|
|
- log(board_id=board_id, additional="Acquisition {:3d}\n".format(num_of_acq) + "Filename: " + newfile.split('/')[-1])
|
|
|
- else:
|
|
|
- logging.info("Acquired 0b, possible trigger timeout.")
|
|
|
-
|
|
|
- self.finished.emit()
|
|
|
-
|
|
|
- def wait_rw_seq(self): # Method 2
|
|
|
- '''Wait sequentially (in the gui) for a trigger signal'''
|
|
|
- for num_of_acq in range(self.noa):
|
|
|
- if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
- board.pci.write(board_id, '00b00', hex_mask='C00') # enable readout
|
|
|
- else:
|
|
|
- board.pci.write(board_id, '00bf0', hex_mask='CF0') # enable readout
|
|
|
- pre_acq_num = board.pci.read(board_id, 1, '9034')[0]
|
|
|
- time_a = time.time()
|
|
|
- timeout = False
|
|
|
- while pre_acq_num == board.pci.read(board_id, 1, '9034')[0]:
|
|
|
- if time.time() - time_a > self.timeout:
|
|
|
- timeout = True
|
|
|
- break
|
|
|
- if self._quit:
|
|
|
- self.finished.emit()
|
|
|
- return
|
|
|
- if not timeout:
|
|
|
- if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
- board.pci.write(board_id, '00000', hex_mask='800') # disable readout
|
|
|
- board.pci.write(board_id, '00700', hex_mask='C00') # enable transfer
|
|
|
- else:
|
|
|
- board.pci.write(board_id, '000f0', hex_mask='8F0') # disable readout
|
|
|
- board.pci.write(board_id, '007f0', hex_mask='CF0') # enable transfer
|
|
|
-
|
|
|
- filename = os.path.join(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
|
|
|
- self.countUpdate.emit(copy.deepcopy(num_of_acq+1))
|
|
|
- if self._quit: # is this really the correct position? file is taken but not renamed!
|
|
|
- self.finished.emit()
|
|
|
- break
|
|
|
-
|
|
|
- if not os.path.isfile(filename):
|
|
|
- error(0x001, "No File Created")
|
|
|
- continue
|
|
|
-
|
|
|
- newfile = os.path.join(self.path, 'trigger_{num:05}_{htime}_{unixtime}.out'.format(
|
|
|
- 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))
|
|
|
- ))
|
|
|
- os.rename(filename, newfile)
|
|
|
- self.liveplot.emit(board_id, newfile)
|
|
|
- else:
|
|
|
- logging.info("Trigger timeout.")
|
|
|
-
|
|
|
-
|
|
|
- self.finished.emit()
|
|
|
-
|
|
|
- def quit(self):
|
|
|
- '''quit this thread'''
|
|
|
- self._quit = True
|
|
|
-
|
|
|
- def __del__(self):
|
|
|
- board.pci.write(board_id, '0', '9024')
|
|
|
- time.sleep(0.1)
|
|
|
- board.pci.write(board_id, '0', '902C')
|
|
|
- time.sleep(0.1)
|
|
|
- if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
- board.pci.write(board_id, '300', hex_mask='f00') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
- else:
|
|
|
- board.pci.write(board_id, '3f0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
- board.flush_dma(board_id)
|
|
|
-
|
|
|
- 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')
|
|
|
- time.sleep(0.1)
|
|
|
- if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
- board.pci.write(board_id, '300', hex_mask='f00') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
- else:
|
|
|
- board.pci.write(board_id, '3f0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
- board.flush_dma(board_id)
|
|
|
-
|
|
|
- thread.stop()
|
|
|
- board.get_board_status(board_id).wait_on_trigger = False
|
|
|
- storage.get_board_specific_storage(board_id).trigger_progressbar.remove(0)
|
|
|
- log(board_id=board_id, additional="Stop wait on trigger")
|
|
|
- Elements.setEnabled('acquire_{}'.format(board_id), True)
|
|
|
- callbacks.callback('acquisition_stopped', board_id)
|
|
|
-
|
|
|
- # for elem in Elements.getElements("acquire_{}".format(board_id)):
|
|
|
- # if isinstance(elem, QtGui.QShortcut):
|
|
|
- # continue
|
|
|
- # elem.setIcon(QtGui.QIcon(config.install_path + config.startIcon))
|
|
|
- # elem.setText(tr("Button", "Start Acquisition"))
|
|
|
- # elem.setEnabled(True)
|
|
|
-
|
|
|
- return
|
|
|
-
|
|
|
- # 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, os.path.join(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)
|
|
|
- if method == 1:
|
|
|
- thread.start('wait_rw_simul')
|
|
|
- elif method == 2:
|
|
|
- thread.start('wait_rw_seq')
|
|
|
- else:
|
|
|
- raise ValueError("Wrong method")
|
|
|
+"""
|
|
|
+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 bk
|
|
|
+Functions only used internal in this module will be prefixed _bif_
|
|
|
+"""
|
|
|
+
|
|
|
+import logging
|
|
|
+import time
|
|
|
+from datetime import datetime as dt
|
|
|
+import os
|
|
|
+import copy
|
|
|
+import shutil
|
|
|
+from PyQt4 import QtGui, QtCore
|
|
|
+import numpy as np
|
|
|
+from .backend import board
|
|
|
+from .backend.board import available_boards
|
|
|
+from .backend.DataSet import DataSet
|
|
|
+from .backend.CalibrationHandle import theCalibration
|
|
|
+from .groupedelements import Buttons, Elements, live_plot_windows, cuda_windows
|
|
|
+from . import storage
|
|
|
+from .. import config
|
|
|
+from . import kcgwidget as kcgw
|
|
|
+from .kcgwidget import error
|
|
|
+from .callbacks import callbacks
|
|
|
+from .log import log
|
|
|
+from .globals import glob as global_objects
|
|
|
+
|
|
|
+from time import sleep
|
|
|
+
|
|
|
+tr = kcgw.tr
|
|
|
+
|
|
|
+livePlotData = None
|
|
|
+
|
|
|
+PRINTDEBUG = False
|
|
|
+
|
|
|
+def initStatus(st):
|
|
|
+ """
|
|
|
+ Initialize Status variables. These variables are used to transfer status variables over different modules.
|
|
|
+ :param st: variable to use (most likely a DummyStorage instance)
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ st.continuous_read = False
|
|
|
+ st.calibrated = False
|
|
|
+ st.synced = False
|
|
|
+ st.defaults_set = False
|
|
|
+ st.status_text = tr("sw", "Ready")
|
|
|
+ st.time_scan = False
|
|
|
+ st.wait_on_trigger = False
|
|
|
+ st.last_file = None
|
|
|
+ st.board_connected = True
|
|
|
+ st.continuous_interval = 1000
|
|
|
+
|
|
|
+
|
|
|
+# -----------[ Backend Interface ]----------------------
|
|
|
+def _bif_enable_wait_cursor():
|
|
|
+ """
|
|
|
+ Show the "Wait Cursor"
|
|
|
+ """
|
|
|
+ QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
|
|
|
+
|
|
|
+
|
|
|
+def _bif_disable_wait_cursor():
|
|
|
+ """
|
|
|
+ Show the normal Cursor
|
|
|
+ """
|
|
|
+ QtGui.QApplication.restoreOverrideCursor()
|
|
|
+
|
|
|
+
|
|
|
+def _bif_continuous_read_is_enabled(board_id, popup_title_text=None):
|
|
|
+ """
|
|
|
+ Checks if continuous read is enabled and if yes shows a popup dialog to ask if it shall be disabled
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param popup_title_text: Text to display in the popup that asks to disable continuous read
|
|
|
+ :return: bool (True if continuous read is enabled and not disabled in popup else False)
|
|
|
+ """
|
|
|
+ if board.get_board_status(board_id).continuous_read:
|
|
|
+ if not available_boards.multi_board:
|
|
|
+ popup = kcgw.PopupDialog(tr("Dialog", "Continuous read is currently active!\nStop continuous read and proceed?"),
|
|
|
+ title=popup_title_text)
|
|
|
+ else:
|
|
|
+ popup = kcgw.PopupDialog(tr("Dialog", "Board {board_id}\nContinuous read is currently active!\nStop continuous read and proceed?").format(board_id=board_id),
|
|
|
+ title=popup_title_text)
|
|
|
+ popup.exec_()
|
|
|
+ popup.deleteLater()
|
|
|
+ if popup.get_return_value() is False:
|
|
|
+ return False
|
|
|
+ else:
|
|
|
+ _bif_set_continuous_read_inactive(board_id)
|
|
|
+ Elements.setChecked("continuousread_"+str(board_id), False)
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ return False
|
|
|
+
|
|
|
+
|
|
|
+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)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_status_readout(board_id):
|
|
|
+ """
|
|
|
+ Read Status from board and update variables
|
|
|
+ as well as enable and disable corresponding Buttons
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ # part_TODO: NOTE: Problem with this is that certain buttons will be greyed out until other buttons are pressed
|
|
|
+ # part_TODO: even if only the gui is restarted and the board is in the same state
|
|
|
+ """
|
|
|
+ if kcgw.testing:
|
|
|
+ return
|
|
|
+ if board.is_active(board_id):
|
|
|
+ Buttons.setEnabled("after_start_{}".format(board_id), True)
|
|
|
+ Buttons.setEnabled("start_board_{}".format(board_id), False)
|
|
|
+ Buttons.setEnabled("continuous_read_{}".format(board_id), True)
|
|
|
+
|
|
|
+ # MenuItems.setEnabled("continuous_read", True)
|
|
|
+ else:
|
|
|
+ board.get_board_status(board_id).calibrated = False
|
|
|
+ board.get_board_status(board_id).synced = False
|
|
|
+ board.get_board_status(board_id).defaults_set = False
|
|
|
+ Buttons.setEnabled("after_start_{}".format(board_id), False)
|
|
|
+ Buttons.setEnabled("continuous_read_{}".format(board_id), False)
|
|
|
+ Buttons.setEnabled("synchronize_{}".format(board_id), board.get_board_status(board_id).calibrated)
|
|
|
+ Buttons.setEnabled("set_defaults_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
+ Buttons.setEnabled("acquire_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
+ Buttons.setEnabled("acquireTrigger_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
+ Elements.setEnabled("timing_{}".format(board_id), board.get_board_status(board_id).synced)
|
|
|
+ """
|
|
|
+ storage.get_board_specific_storage(board_id).update_LED()
|
|
|
+
|
|
|
+
|
|
|
+backup_readout = bk_status_readout
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+class _bif_ProgressBar(QtGui.QProgressBar):
|
|
|
+ """
|
|
|
+ Simple Progressbar class.
|
|
|
+ """
|
|
|
+
|
|
|
+ def __init__(self, min, max, text):
|
|
|
+ super(_bif_ProgressBar, self).__init__()
|
|
|
+ self.setRange(min, max)
|
|
|
+ self.setMaximumHeight(18)
|
|
|
+ # kcgw.statusbar.clearMessage()
|
|
|
+ self.label = QtGui.QLabel(text)
|
|
|
+ global_objects.get_global('statusbar').insertWidget(0, self.label)
|
|
|
+ global_objects.get_global('statusbar').insertWidget(1, self)
|
|
|
+ self.setValue(0)
|
|
|
+ QtGui.qApp.processEvents()
|
|
|
+
|
|
|
+ def remove(self, timeout=None):
|
|
|
+ """
|
|
|
+ Remove this instance of a progressbar
|
|
|
+ :param timeout: the time from calling this function to wanishing of the progressbar
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+
|
|
|
+ def remove_progressbar():
|
|
|
+ global_objects.get_global('statusbar').removeWidget(self)
|
|
|
+ global_objects.get_global('statusbar').removeWidget(self.label)
|
|
|
+ # kcgw.statusbar.showMessage(board.status.status_text)
|
|
|
+ self.destroy()
|
|
|
+
|
|
|
+ if timeout:
|
|
|
+ QtCore.QTimer.singleShot(timeout, remove_progressbar)
|
|
|
+ else:
|
|
|
+ remove_progressbar()
|
|
|
+
|
|
|
+
|
|
|
+def bk_run_sequence(board_id, name):
|
|
|
+ print("________________bk_run_sequence__________________________________________")
|
|
|
+ log(board_id=board_id, additional=str(name))
|
|
|
+ comment = board.get_board_config(board_id).get_sequence_comment(name)
|
|
|
+
|
|
|
+
|
|
|
+ _bif_enable_wait_cursor()
|
|
|
+ if _bif_continuous_read_is_enabled(board_id, tr("Button", "Calibrate Board")):
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ return
|
|
|
+
|
|
|
+ def fin():
|
|
|
+ bk_status_readout()
|
|
|
+ progressbar.remove(0)
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ board.get_board_config(board_id).update('header', board.get_board_config(board_id)._config['header'])
|
|
|
+ board.get_board_config(board_id).update('pilot_bunch', board.get_board_config(board_id)._config['pilot_bunch'])
|
|
|
+
|
|
|
+ progressbar = _bif_ProgressBar(0, 10, tr("sw", comment))
|
|
|
+
|
|
|
+ logging.info('Started ' + comment)
|
|
|
+ try:
|
|
|
+ if not board.get_board_config(board_id).run_sequence(name, progressbar):
|
|
|
+ logging.error(comment + " failed")
|
|
|
+ fin()
|
|
|
+ return
|
|
|
+
|
|
|
+ statval = board.get_board_config(board_id).get_sequence_status(name)
|
|
|
+ if statval == "calibrated": board.get_board_status(board_id).calibrated = True
|
|
|
+ elif statval == "synced": board.get_board_status(board_id).synced = True
|
|
|
+ elif statval == "PLL500M": board.get_board_config(board_id).update('samplingrate', 1)
|
|
|
+ elif statval == "PLL1G": board.get_board_config(board_id).update('samplingrate', 2)
|
|
|
+
|
|
|
+ except board.BoardError as e:
|
|
|
+ logging.error(comment + " failed: {}".format(str(e)))
|
|
|
+ fin()
|
|
|
+ return
|
|
|
+
|
|
|
+
|
|
|
+ logging.info(comment + " successful!")
|
|
|
+ fin()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def bk_write_values(board_id, defaults=False):
|
|
|
+ """
|
|
|
+ Write values to board.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param defaults: (bool) if True Writes default values
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ _bif_enable_wait_cursor()
|
|
|
+ if defaults:
|
|
|
+ log(board_id=board_id, additional="Set Default Values")
|
|
|
+ else:
|
|
|
+ log(board_id=board_id, additional="Update Values on board")
|
|
|
+ if _bif_continuous_read_is_enabled(board_id, tr("Dialog", "Update Values on Board")):
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ return
|
|
|
+
|
|
|
+
|
|
|
+ if defaults:
|
|
|
+ board.get_board_config(board_id)._set_defaults()
|
|
|
+ logging.info("Setting default Values")
|
|
|
+ else:
|
|
|
+ logging.info("Updating Values")
|
|
|
+
|
|
|
+ try:
|
|
|
+ board.get_board_config(board_id).notify_all_observers(write=True)
|
|
|
+ except board.BoardError as e:
|
|
|
+ logging.error("Updating Values failed: {}".format(str(e)))
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ bk_status_readout()
|
|
|
+ return
|
|
|
+
|
|
|
+ board.get_board_status(board_id).defaults_set = True
|
|
|
+
|
|
|
+
|
|
|
+ if defaults:
|
|
|
+ logging.info("Default values set successfully!")
|
|
|
+ else:
|
|
|
+ logging.info("Updated values successfully!")
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ bk_status_readout()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def bk_stop_board(board_id):
|
|
|
+ """
|
|
|
+ Stops the board and shuts it down
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ _bif_enable_wait_cursor()
|
|
|
+ log(board_id=board_id, additional="Stop Board")
|
|
|
+ if _bif_continuous_read_is_enabled(board_id, tr("Dialog", "Soft Reset Board")):
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ return
|
|
|
+
|
|
|
+ try:
|
|
|
+ logging.info("Switching Off Board {}".format(board_id))
|
|
|
+ board.pci.write(board_id, '0x9040')
|
|
|
+ board.pci.stop_dma(board_id)
|
|
|
+ board.stop_board(board_id)
|
|
|
+ time.sleep(0.5)
|
|
|
+ except board.BoardError as e:
|
|
|
+ logging.error("Sequence failed: {}".format(str(e)))
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ bk_status_readout()
|
|
|
+ return
|
|
|
+
|
|
|
+ logging.info("Board switched off successfully!")
|
|
|
+ Buttons.setEnabled("after_start_{}".format(board_id), False)
|
|
|
+ Buttons.setEnabled("start_board_{}".format(board_id), True)
|
|
|
+ board.get_board_status(board_id).calibrated = False
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ bk_status_readout()
|
|
|
+
|
|
|
+def bk_soft_reset(board_id):
|
|
|
+ """
|
|
|
+ Perform a soft reset.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ _bif_enable_wait_cursor()
|
|
|
+ log(board_id=board_id, additional="Soft Reset")
|
|
|
+ if _bif_continuous_read_is_enabled(board_id, tr("Dialog", "Soft Reset Board")):
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ return
|
|
|
+
|
|
|
+ try:
|
|
|
+ logging.info("Soft-Resetting Board {}...".format(board_id))
|
|
|
+ board.soft_reset(board_id)
|
|
|
+ except board.BoardError as e:
|
|
|
+ logging.error("Sequence failed: {}".format(str(e)))
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ bk_status_readout()
|
|
|
+ return
|
|
|
+
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ bk_status_readout()
|
|
|
+ board.get_board_config(board_id).update('header', True) # reset header (might be reset by soft reset)
|
|
|
+ logging.info("Soft-Reset successful.")
|
|
|
+
|
|
|
+
|
|
|
+def bk_update_config(board_id, key, value, silent=False):
|
|
|
+ """
|
|
|
+ Interface to the update command of the BoardConfiguration class.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param key: Key to update
|
|
|
+ :param value: Value to set for key
|
|
|
+ :param silent: (bool) if True do not inform observers on update
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ if silent:
|
|
|
+ board.get_board_config(board_id).updateSilent(key, value)
|
|
|
+ else:
|
|
|
+ board.get_board_config(board_id).update(key, value)
|
|
|
+ #print(key, value)
|
|
|
+ except board.BoardError as e:
|
|
|
+ logging.error("Setting value of {} failed: {}".format(key, str(e)))
|
|
|
+
|
|
|
+
|
|
|
+def bk_get_config(board_id, key,entry=None):
|
|
|
+ """
|
|
|
+ Interface to the get command of the BoardConfiguration class.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param key: Key to get the value for
|
|
|
+ :return: value stored for key
|
|
|
+ """
|
|
|
+ if entry == None:
|
|
|
+ return board.get_board_config(board_id).get(key)
|
|
|
+ else:
|
|
|
+ return board.get_board_config(board_id).get(key)[entry]
|
|
|
+
|
|
|
+
|
|
|
+def bk_get_board_status(board_id, status_variable):
|
|
|
+ """
|
|
|
+ Interface to the status class for each board.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param status_variable: Key to get the value for
|
|
|
+ :return: value stored for key
|
|
|
+ """
|
|
|
+ return getattr(board.get_board_status(board_id), status_variable, None)
|
|
|
+
|
|
|
+
|
|
|
+def bk_get_status(board_id):
|
|
|
+ """
|
|
|
+ Interface to the get_status of the board
|
|
|
+ NOTE: This is not get_board_status
|
|
|
+ :return: status dictionary
|
|
|
+ """
|
|
|
+ return board.get_status(board_id)
|
|
|
+
|
|
|
+
|
|
|
+def bk_change_num_of_turns(board_id, value, silent=False):
|
|
|
+ """
|
|
|
+ Send new number of turns to board and update in config
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param value: the value to send
|
|
|
+ :param silent: (bool) if True do not inform observers on update
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ bk_update_config(board_id, "turns_observe", value, silent=silent)
|
|
|
+
|
|
|
+
|
|
|
+def bk_change_num_of_skipped_turns(board_id, value, silent=False):
|
|
|
+ """
|
|
|
+ Send new number of turns to skip to board and update in config
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param value: the value to send
|
|
|
+ :param silent: (bool) if True do not inform observers on update
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ bk_update_config(board_id, "turns_skip", value, silent=silent)
|
|
|
+
|
|
|
+
|
|
|
+def bk_change_count(board_id, value, silent=False):
|
|
|
+ """
|
|
|
+ Change the number of acquisitions you want to make.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param value: (int) Number of acquisitions
|
|
|
+ :param silent: (bool) if True do not inform observers on update
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ bk_update_config(board_id, "acquisition_count", value, silent=silent)
|
|
|
+
|
|
|
+
|
|
|
+def bk_change_wait(board_id, value, silent=False):
|
|
|
+ """
|
|
|
+ Change the time between acquisitions.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param value: (bool) Time in seconds
|
|
|
+ :param silent: (bool) if True do not inform observers on update
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ bk_update_config(board_id, "turns_wait_time", value, silent=silent)
|
|
|
+
|
|
|
+
|
|
|
+def bk_change_build_spectrograms(board_id, value, silent=False):
|
|
|
+ """
|
|
|
+ Change if spectrograms are built or not)
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param value: (bool) True or False built or not
|
|
|
+ :param silent: (bool) if True do not inform observers on update
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ bk_update_config(board_id, "build_spectrograms", value, silent=silent)
|
|
|
+
|
|
|
+
|
|
|
+def bk_change_pilot_bunch(board_id, value, silent=False):
|
|
|
+ """
|
|
|
+ Change if pilot bunch is simulated
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param value: (bool) True or False to simulate or not
|
|
|
+ :param silent: (bool) if True do not inform observers on update
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ bk_update_config(board_id, "pilot_bunch", value, silent=silent)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_update_working_dir():
|
|
|
+ """
|
|
|
+ make Shure the currently set directory exists and a calibration File is present
|
|
|
+ """
|
|
|
+ path = str(os.path.join(storage.storage.save_location, storage.storage.subdirname))
|
|
|
+ print(path)
|
|
|
+ if not os.path.isdir(path):
|
|
|
+ os.makedirs(path)
|
|
|
+ shutil.copy(config.config_path("calibration.hdf"), path)
|
|
|
+ theCalibration.openFile(os.path.join(path,'calibration.hdf'))
|
|
|
+ return path
|
|
|
+
|
|
|
+def _bif_iterate_spectrograms(board_id, path):
|
|
|
+ """
|
|
|
+ BROKEN (DOES NOT GET ANY DATA)
|
|
|
+ Built Spectrograms line by line
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param path: where to built the spectrogram
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ #print('_bif_iterate_spectrograms')
|
|
|
+ return # because it is broken
|
|
|
+ if not os.path.isdir(str(path)):
|
|
|
+ return
|
|
|
+
|
|
|
+ # how does this get data? dataset.data does not exist
|
|
|
+ transform = dataset.data.fft(1, frm=0, to=-1)
|
|
|
+ for i in range(config.bunches_per_turn - 1):
|
|
|
+ filename = os.path.join(storage.storage.save_location, storage.storage.subdirname, str(path), "%i.hsp" % i)
|
|
|
+ write_header = False
|
|
|
+ if not os.path.isfile(filename):
|
|
|
+ write_header = True
|
|
|
+ f = open(filename, 'ab')
|
|
|
+ if write_header:
|
|
|
+ f.write("#hsp\n") # heb spectrogram magic number
|
|
|
+ f.write("#"+str(board.get_board_config(board_id).get("turns_skip")))
|
|
|
+ f.write("\n")
|
|
|
+ line = transform[i, :]
|
|
|
+ f.write('{:0.3f} '.format(time.time()))
|
|
|
+ for e in line:
|
|
|
+ f.write("%s " % np.absolute(e))
|
|
|
+ f.write("\n")
|
|
|
+ f.close()
|
|
|
+
|
|
|
+
|
|
|
+def _bif_read_data_and_save(board_id):
|
|
|
+ """
|
|
|
+ Tell the pci command to start acquisition and save data
|
|
|
+ Also generates the filename from settings
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ if PRINTDEBUG: print(time.time(), '_bif_read_data_and_save start')
|
|
|
+ now = time.time()
|
|
|
+ _bif_update_working_dir()
|
|
|
+ filename = os.path.join(storage.storage.save_location, storage.storage.subdirname,'{:0.3f}.out'.format(now))
|
|
|
+ board.get_board_status(board_id).last_file = filename
|
|
|
+
|
|
|
+ try:
|
|
|
+ simulate = board.get_board_config(board_id).get("pilot_bunch")
|
|
|
+ try:
|
|
|
+ if PRINTDEBUG: print(time.time(), '_bif_read_data_and_save acquire_data')
|
|
|
+ board.acquire_data(board_id, filename, simulate=simulate)
|
|
|
+ if not os.path.isfile(filename):
|
|
|
+ error(0x001, "No File Created")
|
|
|
+ except IndexError:
|
|
|
+ error(0x002, "Unexpected output of pci for number of turns to observe. Returning")
|
|
|
+ return
|
|
|
+ _bif_read_and_update_data_from_file(board_id, filename)
|
|
|
+ except board.BoardError as e:
|
|
|
+ logging.error("Reading failed: {}".format(str(e)))
|
|
|
+
|
|
|
+ if PRINTDEBUG: print(time.time(), '_bif_read_data_and_save stop')
|
|
|
+
|
|
|
+
|
|
|
+def _bif_read_and_update_data_from_file(board_id, filename):
|
|
|
+ """
|
|
|
+ Proxy function for _bif_read_and_update to call with correct read_func
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param filename: filename to read data from
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ if kcgw.testing:
|
|
|
+ filename = os.path.join(storage.storage.save_location, storage.storage.subdirname,'testing.out')
|
|
|
+ _bif_read_and_update(board_id, 1, str(filename))
|
|
|
+
|
|
|
+
|
|
|
+def _bif_read_and_update_data_from_string(board_id, raw_data):
|
|
|
+ """
|
|
|
+ Proxy function for _bif_read_and_update to call with correct read_func
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param raw_data: Data as string
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ _bif_read_and_update(board_id, 0, raw_data)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_read_and_update(board_id, read_type, dataOrName):
|
|
|
+ """
|
|
|
+ Function to read data from file or string (depending on read_func) and update plots etc.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param read_type: 0 - from String; 1 - from File
|
|
|
+ :param dataOrName: filename or raw_data
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ if PRINTDEBUG: print(time.time(), '_bif_read_and_update start')
|
|
|
+ _bif_enable_wait_cursor()
|
|
|
+
|
|
|
+ header = board.get_board_config(board_id).get('header')
|
|
|
+ # TODO: force_read: meaning ignore cache and read new -> in the old gui this was a commandline option
|
|
|
+ # TODO: cache_data: meaning cache already processed numpy data -> in the old gui this was a commandline option
|
|
|
+ delays = {'c330':board.get_board_config(board_id).get('delay_330_th'), 'c25':board.get_board_config(board_id).get('delay_25_th'),
|
|
|
+ 'c25b':board.get_board_config(board_id).get('delay_25_th_2'), 'f':board.get_board_config(board_id).get('chip_delay')}
|
|
|
+ if read_type == 0:
|
|
|
+ data = DataSet(stringData=dataOrName, delays=delays, tRev=config.tRev, bunchesPerTurn=config.bunches_per_turn, shiftFMC2=config.shiftFMC2)
|
|
|
+ else:
|
|
|
+ data = DataSet(filename=dataOrName, delays=delays, tRev=config.tRev, bunchesPerTurn=config.bunches_per_turn, shiftFMC2=config.shiftFMC2)
|
|
|
+
|
|
|
+ board.get_board_config(board_id).update('lastDataSet', data)
|
|
|
+
|
|
|
+ QtGui.qApp.processEvents()
|
|
|
+
|
|
|
+ _bif_disable_wait_cursor()
|
|
|
+ if PRINTDEBUG: print(time.time(), '_bif_read_and_update stop')
|
|
|
+
|
|
|
+def bk_acquire(board_id):
|
|
|
+ """
|
|
|
+ Toggle Acqisition
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ if not bk_get_config(board_id, 'use_trigger'):
|
|
|
+ if board.get_board_status(board_id).acquisition == True:
|
|
|
+ log(board_id=board_id, additional="Manually Stopped Acquisition\nPerformed Acquisitions: " + str(storage.storage.current_acquisition))
|
|
|
+ _bif_stop_acquisition(board_id)
|
|
|
+ else:
|
|
|
+ _bif_start_acquisition(board_id)
|
|
|
+ else:
|
|
|
+ bk_toggle_wait_on_trigger(board_id)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_stop_acquisition(board_id):
|
|
|
+ """
|
|
|
+ Stop acquisition
|
|
|
+ This does stop the timer started by _bif_start_acquisition()
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ board.get_board_status(board_id).acquisition = False
|
|
|
+ storage.get_board_specific_storage(board_id).acquisition_progressbar.remove(0)
|
|
|
+ storage.get_board_specific_storage(board_id).acquisition_timer.stop()
|
|
|
+ # for elem in Elements.getElements("acquireTrigger_{}".format(board_id)):
|
|
|
+ # if isinstance(elem, QtGui.QShortcut) or isinstance(elem, QtGui.QCheckBox):
|
|
|
+ # continue
|
|
|
+ # elem.setIcon(QtGui.QIcon(config.install_path + config.startIcon))
|
|
|
+ # elem.setText(tr("Button", "Start Acquisition"))
|
|
|
+ Elements.setEnabled('acquire_{}'.format(board_id), True)
|
|
|
+ callbacks.callback('acquisition_stopped', board_id)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_start_acquisition(board_id):
|
|
|
+ """
|
|
|
+ Start acquisition.
|
|
|
+ This will start a timer to automatically acquire data.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ log(board_id=board_id, additional="Started Acquisition")
|
|
|
+ board.get_board_status(board_id).acquisition = True
|
|
|
+ Elements.setEnabled('acquire_{}'.format(board_id), False)
|
|
|
+ # for elem in Elements.getElements("acquireTrigger_{}".format(board_id)):
|
|
|
+ # if isinstance(elem, QtGui.QShortcut) or isinstance(elem, QtGui.QCheckBox):
|
|
|
+ # continue
|
|
|
+ # elem.setIcon(QtGui.QIcon(config.install_path + config.stopIcon))
|
|
|
+ # elem.setText(tr("Button", "Stop Acquisition"))
|
|
|
+ callbacks.callback('acquisition_started', board_id)
|
|
|
+ storage.get_board_specific_storage(board_id).acquisition_timer = QtCore.QTimer()
|
|
|
+ num_acquisitions = board.get_board_config(board_id).get("acquisition_count")
|
|
|
+ storage.get_board_specific_storage(board_id).acquisition_progressbar = \
|
|
|
+ _bif_ProgressBar(0, num_acquisitions, tr("sw", "Acquiring with board ")+str(board_id))
|
|
|
+ # storage.storage.acquisition_progressbar = acquisition_progressbar
|
|
|
+
|
|
|
+ # We increase already once because we do a single acquisition before the
|
|
|
+ # timer is started, otherwise we have to wait until the timer fires the
|
|
|
+ # first time.
|
|
|
+ try:
|
|
|
+ if isinstance(storage.storage.current_acquisition, dict):
|
|
|
+ storage.storage.current_acquisition[board_id] = 1
|
|
|
+ else:
|
|
|
+ storage.storage.current_acquisition = {board_id: 1}
|
|
|
+ except storage.StorageError:
|
|
|
+ storage.storage.current_acquisition = {board_id: 1}
|
|
|
+ _bif_read_data_and_save(board_id)
|
|
|
+
|
|
|
+ if board.get_board_config(board_id).get("build_spectrograms"):
|
|
|
+ spectrogram_dir = os.path.join(storage.storage.save_location, storage.storage.subdirname, "spectrograms_{:0.3f}".format(time.time()))
|
|
|
+ os.makedirs(spectrogram_dir)
|
|
|
+ _bif_iterate_spectrograms(board_id, spectrogram_dir) # TODO: not here?
|
|
|
+
|
|
|
+ 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])
|
|
|
+ _bif_read_data_and_save(board_id)
|
|
|
+ log(board_id=board_id, additional="Acquisition {:3d}\n".format(storage.storage.current_acquisition[board_id]) + "Filename: "+board.get_board_status(board_id).last_file.split('/')[-1])
|
|
|
+ if board.get_board_config(board_id).get("build_spectrograms"):
|
|
|
+ _bif_iterate_spectrograms(board_id, spectrogram_dir) # TODO: not here ?
|
|
|
+ else:
|
|
|
+ log(board_id=board_id, additional="Stopped Acquisition")
|
|
|
+ _bif_stop_acquisition(board_id)
|
|
|
+ storage.get_board_specific_storage(board_id).acquisition_progressbar.remove(0)
|
|
|
+
|
|
|
+ storage.get_board_specific_storage(board_id).acquisition_timer.timeout.connect(on_timeout)
|
|
|
+ storage.get_board_specific_storage(board_id).acquisition_timer.start(board.get_board_config(board_id).get('turns_wait_time') * 1000)
|
|
|
+
|
|
|
+
|
|
|
+def bk_single_read(board_id, info=""):
|
|
|
+ """
|
|
|
+ Perform a single read of data
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ if info != "":
|
|
|
+ info += "\n"
|
|
|
+ Elements.setEnabled("acquire_{}".format(board_id), False)
|
|
|
+ _bif_read_data_and_save(board_id)
|
|
|
+ log(board_id=board_id, additional="Single Read\n" + info + "Filename: "+board.get_board_status(board_id).last_file.split('/')[-1])
|
|
|
+ Elements.setEnabled("acquire_{}".format(board_id), True)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_set_continuous_read_active(board_id):
|
|
|
+ """
|
|
|
+ Enable continuous read
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ Elements.setEnabled("acquireTrigger_{}".format(board_id), False)
|
|
|
+ Elements.setEnabled("continuous_read_{}".format(board_id), False)
|
|
|
+ board.get_board_status(board_id).continuous_read = True
|
|
|
+
|
|
|
+
|
|
|
+def _bif_set_continuous_read_inactive(board_id):
|
|
|
+ """
|
|
|
+ Disable continuous read
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ if board.get_board_status(board_id).continuous_read:
|
|
|
+ board.get_board_status(board_id).continuous_read = False
|
|
|
+ storage.get_board_specific_storage(board_id).continuous_read_timer.stop()
|
|
|
+ Elements.setEnabled('continuous_read_{}'.format(board_id), True)
|
|
|
+ Elements.setEnabled('acquireTrigger_{}'.format(board_id), True)
|
|
|
+
|
|
|
+
|
|
|
+def bk_continuous_read(board_id, interval=100):
|
|
|
+ """
|
|
|
+ Toggle continuous read
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param interval: Time between two consecutive reads.
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ if not board.get_board_status(board_id).continuous_read:
|
|
|
+ _bif_set_continuous_read_active(board_id)
|
|
|
+ _bif_continuous_read(board_id, interval)
|
|
|
+ else:
|
|
|
+ _bif_set_continuous_read_inactive(board_id)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_continuous_read(board_id, interval=None):
|
|
|
+ """
|
|
|
+ Perform continuous read based on a timer.
|
|
|
+ :param interval:
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ if interval is not None:
|
|
|
+ # TODO: ueberall checken, dass der board specific storage verwendet wird
|
|
|
+ storage.get_board_specific_storage(board_id).continuous_interval = interval
|
|
|
+ storage.get_board_specific_storage(board_id).continuous_read_timer = QtCore.QTimer()
|
|
|
+ logging.info("Start continuous read")
|
|
|
+
|
|
|
+ def continuous_read_step():
|
|
|
+ if board.get_board_status(board_id).continuous_read:
|
|
|
+ _bif_read_data(board_id)
|
|
|
+ storage.get_board_specific_storage(board_id).continuous_read_timer.singleShot(storage.storage.continuous_interval, continuous_read_step)
|
|
|
+
|
|
|
+ storage.get_board_specific_storage(board_id).continuous_read_timer.singleShot(storage.storage.continuous_interval, continuous_read_step)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_read_data(board_id, returnBack=False):
|
|
|
+ """
|
|
|
+ Reads data acquired by board.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ board.pci.start = time.time()
|
|
|
+ if PRINTDEBUG: print('{:4.3f} _bif_read_data start'.format(time.time()-board.pci.start))
|
|
|
+ try:
|
|
|
+ if board.get_board_config(board_id).get('pilot_bunch'):
|
|
|
+ board.start_pilot_bunch_emulator(board_id)
|
|
|
+
|
|
|
+ board.start_acquisition(board_id)
|
|
|
+ try:
|
|
|
+ board.wait_for_revolutions(board_id)
|
|
|
+ except IndexError:
|
|
|
+ error(0x002, "Unexpected output of pci for number of turns to observe. Returning")
|
|
|
+ return None
|
|
|
+ board.stop_acquisition(board_id)
|
|
|
+ board.enable_transfer(board_id)
|
|
|
+ if PRINTDEBUG: print('{:4.3f} _bif_read_data.read_data_to_variable'.format(time.time()-board.pci.start))
|
|
|
+ data_raw = board.pci.read_data_to_variable(board_id)
|
|
|
+ if PRINTDEBUG: print('{:4.3f} _bif_read_data.read_data_to_variable done'.format(time.time()-board.pci.start))
|
|
|
+
|
|
|
+ if returnBack:
|
|
|
+ if PRINTDEBUG: print('{:4.3f} _bif_read_data return data_raw'.format(time.time()-board.pci.start))
|
|
|
+ return data_raw
|
|
|
+ else:
|
|
|
+ if PRINTDEBUG: print('{:4.3f} _bif_read_data call'.format(time.time()-board.pci.start))
|
|
|
+ _bif_read_and_update_data_from_string(board_id, data_raw)
|
|
|
+ if PRINTDEBUG: print('{:4.3f} _bif_read_data call done'.format(time.time()-board.pci.start))
|
|
|
+
|
|
|
+ except board.BoardError as e:
|
|
|
+ logging.error("Reading failed for board {}: {}".format(str(board_id), str(e)))
|
|
|
+
|
|
|
+ if PRINTDEBUG: print('{:4.3f} _bif_read_data return None'.format(time.time()-board.pci.start))
|
|
|
+ return None
|
|
|
+
|
|
|
+def bk_board_connected(board_id):
|
|
|
+ """
|
|
|
+ Interface to the board to check if it is connected.
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ if not available_boards.has_boards:
|
|
|
+ return False
|
|
|
+ else:
|
|
|
+ return board_id in available_boards.board_ids
|
|
|
+
|
|
|
+
|
|
|
+def bk_get_temperature(board_id):
|
|
|
+ """
|
|
|
+ Get Temperature from board and format it
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ fpga_temp_raw_hex = board.pci.read(board_id, 1, '0x9110')[0]
|
|
|
+ fpga_temp_raw_hex = fpga_temp_raw_hex[-3:]
|
|
|
+ fpga_temp_raw_bin = '{0:012b}'.format(int(fpga_temp_raw_hex, 16))
|
|
|
+ fpga_temp_encoded = board.get_dec_from_bits(fpga_temp_raw_bin, 9, 0)
|
|
|
+ fpga_temp_celsius = '{0:2.2f}'.format(((fpga_temp_encoded * 503.975) / 1024) - 273.15)
|
|
|
+ return fpga_temp_celsius
|
|
|
+
|
|
|
+
|
|
|
+backup_get_temp = bk_get_temperature
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def bk_check_for_board(board_id):
|
|
|
+ """
|
|
|
+ Check if board is connected
|
|
|
+ Also overrides the bk_status_readout function with a function that does nothing (suppresses read attempts that
|
|
|
+ generate errors - if no board is connected, there is nothing to read from)
|
|
|
+ Also overrides the bk_get_temperature function as of the same reasons
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+ # 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:
|
|
|
+ globals()['bk_status_readout'] = backup_readout
|
|
|
+ globals()['bk_get_temperature'] = backup_get_temp
|
|
|
+ board.get_board_status(board_id).board_connected = True
|
|
|
+
|
|
|
+ else:
|
|
|
+ Elements.setEnabled('no_board_{}'.format(board_id), False)
|
|
|
+
|
|
|
+ def do_nothing():
|
|
|
+ pass
|
|
|
+
|
|
|
+ def no_temp(board_id):
|
|
|
+ return "-"
|
|
|
+
|
|
|
+ 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))
|
|
|
+ elif board_status == None:
|
|
|
+ board.get_board_status(board_id).status_text = tr("sw", "Software Interface not found")
|
|
|
+
|
|
|
+
|
|
|
+def bk_toggle_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, timeout=1, method=None):
|
|
|
+ """
|
|
|
+ Toggle waiting for trigger signal to acquire
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param num_of_acquisitions: number of acquisitions to wait for
|
|
|
+ :param skip: how much trigger signals to skip between acquisitions
|
|
|
+ :param timeout: the timeout for the pci to wait for date
|
|
|
+ :param method: wait method to use
|
|
|
+ 1 for wait in pci command and 2 for waiting until register is set that KAPTURE has read data
|
|
|
+ NOTE: this also means that method 1 enables simultaneous read and write to dma and method 2 does write and
|
|
|
+ read sequentially
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ thread = storage.get_board_specific_storage(board_id).setdefault('TriggerThread', storage.ThreadStorage())
|
|
|
+ if thread.running:
|
|
|
+ Elements.getElements("acquireTrigger_{}".format(board_id))[0].setText(tr("Button", "Stopping Acquisition"))
|
|
|
+ # FIXME: Button not updated otherwise:
|
|
|
+ QtGui.qApp.processEvents()
|
|
|
+ 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):
|
|
|
+ # continue
|
|
|
+ # elem.setText(tr("Button", "Stopping Acquisition"))
|
|
|
+ # elem.setEnabled(False)
|
|
|
+ else:
|
|
|
+ log(board_id=board_id, additional="Start wait on trigger on board {}".format(board_id))
|
|
|
+ # for elem in Elements.getElements("acquireTrigger_{}".format(board_id)):
|
|
|
+ # if isinstance(elem, QtGui.QShortcut):
|
|
|
+ # continue
|
|
|
+ # elem.setIcon(QtGui.QIcon(config.install_path + config.stopIcon))
|
|
|
+ # elem.setText(tr("Button", "Stop Acquisition"))
|
|
|
+ Elements.setEnabled('acquire_{}'.format(board_id), False)
|
|
|
+ callbacks.callback('acquisition_started', board_id)
|
|
|
+ _bif_start_wait_on_trigger(board_id, num_of_acquisitions, skip, timeout, method)
|
|
|
+
|
|
|
+
|
|
|
+def _bif_start_wait_on_trigger(board_id, num_of_acquisitions=None, skip=None, timeout=None, method=None):
|
|
|
+ """
|
|
|
+ Start waiting on external acquisition trigger. This starts the timer
|
|
|
+ :param board_id: id of the board do manipulate
|
|
|
+ :param num_of_acquisitions: number of acquisitions to do
|
|
|
+ :param count_label: Handle for the countlabel
|
|
|
+ :param method: wait method to use
|
|
|
+ 1 for wait in pci command and 2 for waiting until register is set that KAPTURE has read data
|
|
|
+ NOTE: this also means that method 1 enables simultaneous read and write to dma and method 2 does write and
|
|
|
+ read sequentially
|
|
|
+ :return: -
|
|
|
+ """
|
|
|
+
|
|
|
+ # FIXme: This is a work around, for method 2 to work everytime a standard single read needs to be perform before acquisition is started
|
|
|
+ board.acquire_data(board_id, '/dev/null')
|
|
|
+ #with workaround no flush dema need, because it is done at end of board.acquire_data() anyway.
|
|
|
+ #board.flush_dma(board_id) # TODO: really at begining and end of function necessary?
|
|
|
+ thread = storage.get_board_specific_storage(board_id).setdefault('TriggerThread', storage.ThreadStorage())
|
|
|
+ if thread.running:
|
|
|
+ logging.info("Wait already running on board {}".format(board_id))
|
|
|
+ return
|
|
|
+ log(board_id=board_id, additional="Start wait on trigger")
|
|
|
+ board.get_board_status(board_id).wait_on_trigger = True
|
|
|
+ _bif_update_working_dir()
|
|
|
+
|
|
|
+ if not num_of_acquisitions:
|
|
|
+ num_of_acquisitions = bk_get_config(board_id, 'acquisition_count')
|
|
|
+ if not skip:
|
|
|
+ skip = bk_get_config(board_id, 'trigger_skip')
|
|
|
+ if not timeout:
|
|
|
+ timeout = bk_get_config(board_id, 'trigger_timeout')
|
|
|
+ if not method:
|
|
|
+ method = bk_get_config(board_id, 'trigger_method')
|
|
|
+
|
|
|
+ storage.get_board_specific_storage(board_id).trigger_progressbar = \
|
|
|
+ _bif_ProgressBar(0, num_of_acquisitions, tr("sw", "Acquiring with board ")+str(board_id))
|
|
|
+ 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
|
|
|
+
|
|
|
+ # 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
|
|
|
+ # I don't have an idea why it crashes.
|
|
|
+ # A possible reason could the os.rename be (or even the board.safe_call as that saves data to the disk) But I think
|
|
|
+ # this is rather unlikely
|
|
|
+ # ~~NOTE~~: the thread of calibration also triggered segfaults sometimes. But this seems to be miraculously solved.
|
|
|
+ # 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(int, str) # This has to be changed if board_id is no integer
|
|
|
+
|
|
|
+ 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
|
|
|
+ self._quit = False
|
|
|
+
|
|
|
+ # Elements.setEnabled('acquireTrigger_{}'.format(board_id), False) # exclude=Elements.getElements('wait_on_trigger_{}'.format(board_id)))
|
|
|
+
|
|
|
+ def wait_rw_simul(self): # Method 1
|
|
|
+ '''Wait simultaniously (with the pci command) for a trigger signal'''
|
|
|
+ if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
+ board.pci.write(board_id, 'f00', hex_mask='f00') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
+ else:
|
|
|
+ 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 range(self.noa):
|
|
|
+ # def step():
|
|
|
+ if self._quit:
|
|
|
+ break
|
|
|
+
|
|
|
+ timestamp = time.time()
|
|
|
+ filename = os.path.join(self.path, '{:0.3f}.out'.format(timestamp))
|
|
|
+ board.pci.read_data_to_file(board_id, filename=filename, timeout=(self.timeout*1000000))
|
|
|
+ # rename with correct timestamp - last modified time
|
|
|
+ self.countUpdate.emit(num_of_acq + 1)
|
|
|
+
|
|
|
+ # file operations
|
|
|
+ if not os.path.isfile(filename):
|
|
|
+ error(0x001, "No File Created")
|
|
|
+ continue
|
|
|
+
|
|
|
+ newfile = os.path.join(self.path, 'trigger_{num:05}_{htime}_{unixtime}.out'.format(
|
|
|
+ num=num_of_acq,
|
|
|
+ htime=dt.fromtimestamp(os.path.getmtime(filename)).strftime('%Y-%m-%dT%Hh%Mm%Ss%f'),
|
|
|
+ unixtime=np.round(timestamp, 3)
|
|
|
+ ))
|
|
|
+ os.rename(filename, newfile)
|
|
|
+ if os.path.getsize(newfile) > 0:
|
|
|
+ self.liveplot.emit(board_id, newfile)
|
|
|
+ log(board_id=board_id, additional="Acquisition {:3d}\n".format(num_of_acq) + "Filename: " + newfile.split('/')[-1])
|
|
|
+ else:
|
|
|
+ logging.info("Acquired 0b, possible trigger timeout.")
|
|
|
+
|
|
|
+ self.finished.emit()
|
|
|
+
|
|
|
+ def wait_rw_seq(self): # Method 2
|
|
|
+ '''Wait sequentially (in the gui) for a trigger signal'''
|
|
|
+ for num_of_acq in range(self.noa):
|
|
|
+ if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
+ board.pci.write(board_id, '00b00', hex_mask='C00') # enable readout
|
|
|
+ else:
|
|
|
+ board.pci.write(board_id, '00bf0', hex_mask='CF0') # enable readout
|
|
|
+ pre_acq_num = board.pci.read(board_id, 1, '9034')[0]
|
|
|
+ time_a = time.time()
|
|
|
+ timeout = False
|
|
|
+ while pre_acq_num == board.pci.read(board_id, 1, '9034')[0]:
|
|
|
+ if time.time() - time_a > self.timeout:
|
|
|
+ timeout = True
|
|
|
+ break
|
|
|
+ if self._quit:
|
|
|
+ self.finished.emit()
|
|
|
+ return
|
|
|
+ if not timeout:
|
|
|
+ if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
+ board.pci.write(board_id, '00000', hex_mask='800') # disable readout
|
|
|
+ board.pci.write(board_id, '00700', hex_mask='C00') # enable transfer
|
|
|
+ else:
|
|
|
+ board.pci.write(board_id, '000f0', hex_mask='8F0') # disable readout
|
|
|
+ board.pci.write(board_id, '007f0', hex_mask='CF0') # enable transfer
|
|
|
+
|
|
|
+ filename = os.path.join(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
|
|
|
+ self.countUpdate.emit(copy.deepcopy(num_of_acq+1))
|
|
|
+ if self._quit: # is this really the correct position? file is taken but not renamed!
|
|
|
+ self.finished.emit()
|
|
|
+ break
|
|
|
+
|
|
|
+ if not os.path.isfile(filename):
|
|
|
+ error(0x001, "No File Created")
|
|
|
+ continue
|
|
|
+
|
|
|
+ newfile = os.path.join(self.path, 'trigger_{num:05}_{htime}_{unixtime}.out'.format(
|
|
|
+ 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))
|
|
|
+ ))
|
|
|
+ os.rename(filename, newfile)
|
|
|
+ self.liveplot.emit(board_id, newfile)
|
|
|
+ else:
|
|
|
+ logging.info("Trigger timeout.")
|
|
|
+
|
|
|
+
|
|
|
+ self.finished.emit()
|
|
|
+
|
|
|
+ def quit(self):
|
|
|
+ '''quit this thread'''
|
|
|
+ self._quit = True
|
|
|
+
|
|
|
+ def __del__(self):
|
|
|
+ board.pci.write(board_id, '0', '9024')
|
|
|
+ time.sleep(0.1)
|
|
|
+ board.pci.write(board_id, '0', '902C')
|
|
|
+ time.sleep(0.1)
|
|
|
+ if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
+ board.pci.write(board_id, '300', hex_mask='f00') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
+ else:
|
|
|
+ board.pci.write(board_id, '3f0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
+ board.flush_dma(board_id)
|
|
|
+
|
|
|
+ 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')
|
|
|
+ time.sleep(0.1)
|
|
|
+ if board.get_board_config(board_id).is_KAPTURE2():
|
|
|
+ board.pci.write(board_id, '300', hex_mask='f00') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
+ else:
|
|
|
+ board.pci.write(board_id, '3f0', hex_mask='ff0') # TODO: This writes t/h 3/4 but enable_transfer etc do not
|
|
|
+ board.flush_dma(board_id)
|
|
|
+
|
|
|
+ thread.stop()
|
|
|
+ board.get_board_status(board_id).wait_on_trigger = False
|
|
|
+ storage.get_board_specific_storage(board_id).trigger_progressbar.remove(0)
|
|
|
+ log(board_id=board_id, additional="Stop wait on trigger")
|
|
|
+ Elements.setEnabled('acquire_{}'.format(board_id), True)
|
|
|
+ callbacks.callback('acquisition_stopped', board_id)
|
|
|
+
|
|
|
+ # for elem in Elements.getElements("acquire_{}".format(board_id)):
|
|
|
+ # if isinstance(elem, QtGui.QShortcut):
|
|
|
+ # continue
|
|
|
+ # elem.setIcon(QtGui.QIcon(config.install_path + config.startIcon))
|
|
|
+ # elem.setText(tr("Button", "Start Acquisition"))
|
|
|
+ # elem.setEnabled(True)
|
|
|
+
|
|
|
+ return
|
|
|
+
|
|
|
+ # 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, os.path.join(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)
|
|
|
+ if method == 1:
|
|
|
+ thread.start('wait_rw_simul')
|
|
|
+ elif method == 2:
|
|
|
+ thread.start('wait_rw_seq')
|
|
|
+ else:
|
|
|
+ raise ValueError("Wrong method")
|