6 Commits 18925d106d ... 8273c838b7

Author SHA1 Message Date
  kapture2 8273c838b7 Changed default DMA Read Timeout to 1s 3 years ago
  kapture2 69a182bbef Continuous Acquisition button now turns green on active 3 years ago
  kapture2 73b9f7482d Untangled 'acquire' and 'continuous_read' Element groups 3 years ago
  kapture2 885e33745f Fixed Timescan not properly setting FMC2 settings 3 years ago
  kapture2 a90b0800a7 Fixed Timescan not properly showing progress percentage 3 years ago
  kapture2 8d0c8ea0e9 Changed Line Ending convention to Unix 3 years ago
4 changed files with 1143 additions and 1126 deletions
  1. 1093 1094
      KCG/base/backendinterface.py
  2. 29 9
      KCG/widgets/SingleReadWidget.py
  3. 9 10
      KCG/widgets/TimescanWidget.py
  4. 12 13
      KCG/widgets/TimingWidget.py

+ 1093 - 1094
KCG/base/backendinterface.py

@@ -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")

+ 29 - 9
KCG/widgets/SingleReadWidget.py

@@ -45,7 +45,7 @@ class SingleReadWidget(kcgw.KCGWidgets):
         self.continuous_read_button = self.createButton(tr("Button", "Continuous Acquisition"),
                 connect=lambda: self.on_continuous_read(available_boards[0]))
         self.single_read_input  = self.createInput()
-        self.interval_spinbox = self.createSpinbox(0, 100000, start_value=1000)
+        self.interval_spinbox = self.createSpinbox(0, 100000, start_value=100)
         self.interval_spinbox.valueChanged.connect(self.set_interval)
 
         self.board_ticks = {board_id: self.createCheckbox(str(board_id), checked=True if board_id==0 else False) for board_id in available_boards}
@@ -56,14 +56,28 @@ class SingleReadWidget(kcgw.KCGWidgets):
             for board_id in available_boards
             }
 
+
         for board_id, tick in list(self.board_ticks_continuous_read.items()):
             Elements.addItem('acquireTrigger_{}'.format(board_id), tick)
             Elements.addItem(["acquire_{}".format(board_id), "no_board_{}".format(board_id)], tick)
             Elements.addItem('continuous_read_{}'.format(board_id), tick)
+
         for board_id, tick in self.board_ticks.items():
             Elements.addItem('acquireTrigger_{}'.format(board_id), tick)
             Elements.addItem(["acquire_{}".format(board_id), "no_board_{}".format(board_id)], tick)
 
+        board_id = available_boards[0]
+        Elements.addItem(
+                [
+                    "acquire_{}".format(board_id),
+                    "no_board_{}".format(board_id)
+                ],
+                [
+                    self.single_read_button,
+                    self.continuous_read_button
+                ])
+        Elements.addItem('continuous_read_{}'.format(board_id), self.single_read_button)
+
         # --------[ Fill Grid ]----------------
         self.layout.addWidget(self.continuous_read_button, 0, 1)
         self.layout.addWidget(self.single_read_button, 1, 1)
@@ -129,11 +143,10 @@ class SingleReadWidget(kcgw.KCGWidgets):
         if not board.get_board_status(board_id).continuous_read:
             self.continuous_read_button.setText(tr("Button", "Stop Acquisition"))
             self.single_read_button.setEnabled(False)
-            # self.continuous_read[id] = True
-            # self.board_ticks_continuous_read[board_id].setStyleSheet("border-color: green; border-width: 3px;")
+            self.continuous_read_button.setStyleSheet("QPushButton {background-color: green; color: black;}")
         else:
             self.continuous_read_button.setText(tr("Button", "Continuous Acquisition"))
-            #self.board_ticks_continuous_read[board_id].setStyleSheet("")
+            self.continuous_read_button.setStyleSheet("")
             self.single_read_button.setEnabled(True)
 
         #Note:
@@ -157,11 +170,18 @@ class SingleReadWidget(kcgw.KCGWidgets):
         global __widget_id__
         __widget_id__ = None
         del self.par.widgets[self.id]
-        Elements.removeItem(['no_board', 'acquire'],
-                            [
-                                self.single_read_button,
-                                # self.continuous_read_button
-                            ])
+        Elements.removeItem(
+                [
+                    #"acquireTrigger_{}".format(board_id),
+                    "acquire_{}".format(board_id),
+                    "no_board_{}".format(board_id)
+                ], 
+                [
+                    self.single_read_button,
+                    #self.continuous_read_button
+                ])
+        Elements.removeItem('continuous_read_{}'.format(board_id), self.single_read_button)
+
         for board_id, tick in list(self.board_ticks_continuous_read.items()):
             Elements.removeItem(
                 [

+ 9 - 10
KCG/widgets/TimescanWidget.py

@@ -84,11 +84,11 @@ class ScanThread(QtCore.QObject):
 
     def setDelay(self, value):
         board.get_board_config(self.board_id).update('delay_330_th', value)
-        #board.get_board_config(self.board_id).update('delay_330_th_2', value)
+        board.get_board_config(self.board_id).update('delay_330_th_2', value)
 
     def setDelay25(self, value):
         board.get_board_config(self.board_id).update('delay_25_th', value)
-        #board.get_board_config(self.board_id).update('delay_25_th_2', value)
+        board.get_board_config(self.board_id).update('delay_25_th_2', value)
 
     def setDelayB(self, value):
         board.get_board_config(self.board_id).update('delay_330_th_2', value)
@@ -255,14 +255,13 @@ class ScanThread(QtCore.QObject):
             self.timescan.appendData(mean,std,adc, c_step, c25_step, f_step, c25_step_b)
 
             
-        if c25_step_b == 4 and c_step_b == 0:
-            #print('{:4.3f} emit pbar'.format(time.time()-self.startTime))
-            tmpScan = copy.deepcopy(self.timescan)
-            self.pbarSignal.emit(tmpScan, 
-                                 ((c_step-self.c_min)*(self.c25_max-self.c25_min+1.0) * (self.f_max-self.f_min+1.0) + (c25_step-self.c25_min)*(self.f_max-self.f_min+1.0) + (f_step-self.f_min))/
-                                 ((self.c_max-self.c_min+1.0) * (self.c25_max-self.c25_min+1.0) * (self.f_max-self.f_min+1.0))
-                                )
-            #print('{:4.3f} emit pbar done'.format(time.time()-self.startTime))
+        #print('{:4.3f} emit pbar'.format(time.time()-self.startTime))
+        tmpScan = copy.deepcopy(self.timescan)
+        self.pbarSignal.emit(tmpScan, 
+                             ((c_step-self.c_min)*(self.c25_max-self.c25_min+1.0) * (self.f_max-self.f_min+1.0) + (c25_step-self.c25_min)*(self.f_max-self.f_min+1.0) + (f_step-self.f_min))/
+                             ((self.c_max-self.c_min+1.0) * (self.c25_max-self.c25_min+1.0) * (self.f_max-self.f_min+1.0))
+                            )
+        #print('{:4.3f} emit pbar done'.format(time.time()-self.startTime))
 
     def finished(self, c_step=0, c25_step=0, f_step=0):
         '''Method to handle the end of the thread'''

+ 12 - 13
KCG/widgets/TimingWidget.py

@@ -92,7 +92,7 @@ class TimingPart(kcgw.KCGWidgets):
         #instead directly through update_delay
         self.coarseInputTh   = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=self.linkFMCCoarseDelay)
 
-        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)],
+        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id)],
                          [
                             #self.coarseInputFpga,
                             #self.coarseInputAdc,
@@ -107,7 +107,7 @@ class TimingPart(kcgw.KCGWidgets):
             self.coarse2Label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
             self.coarse2InputTh   = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_th", "coarse2InputTh"))
 
-            Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)],
+            Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id)],
                          [
                             #self.coarse2InputAdc,
                             #self.coarse2InputFpga,
@@ -122,14 +122,15 @@ class TimingPart(kcgw.KCGWidgets):
                 self.coarseInputTh_2   = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_th_2", "coarseInputTh_2"))
                 self.coarse2InputTh_2   = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_th_2", "coarse2InputTh_2"))
 
-                Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)],
+                Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id)],
                              [
                                 #self.coarseInputFpga,
                                 #self.coarseInputAdc,
-                                self.coarseInputTh_2,
+                                #self.coarseInputTh_2,
                                 #self.coarse2InputAdc,
                                 #self.coarse2InputFpga,
-                                self.coarse2InputTh_2
+                                self.coarse2InputTh_2,
+                                self.linkTHSwitch
                              ]
                              )
 
@@ -158,9 +159,8 @@ class TimingPart(kcgw.KCGWidgets):
 
         Elements.addItem(["timing_{}".format(self.board_id),
             "no_board_{}".format(self.board_id),
-            "acquire_{}".format(self.board_id),
-            "continuous_read_{}".format(board_id)], 
-            self.fineAdcInput
+            "acquire_{}".format(self.board_id)
+            ], self.fineAdcInput
             )
 
         self.bunchShiftLabel = self.createLabel(tr("Label", "Bunch Shift"))
@@ -171,9 +171,8 @@ class TimingPart(kcgw.KCGWidgets):
 
         Elements.addItem(["timing_{}".format(self.board_id),
             "no_board_{}".format(self.board_id),
-            "acquire_{}".format(self.board_id),
-            "continuous_read_{}".format(board_id)], 
-            self.bunchShiftInput
+            "acquire_{}".format(self.board_id)
+            ], self.bunchShiftInput
             )
 
 
@@ -503,10 +502,10 @@ class TimingPart(kcgw.KCGWidgets):
                                 )
             if self.adc_number > 4:
                 Elements.removeItem(None, [
-                                            self.coarseInputTh_2,
+                                            #self.coarseInputTh_2,
                                             #self.coarseInputAdc_2,
                                             #self.coarseInputFpga_2,
-
+                                            self.linkTHSwitch,
                                             self.coarse2InputTh_2,
                                             #self.coarse2InputAdc_2,
                                             #self.coarse2InputFpga_2