Browse Source

Changed line ending convention to unix
for TimingWidget.py

Timo Dritschler 3 years ago
parent
commit
0aab1e6d75
1 changed files with 628 additions and 628 deletions
  1. 628 628
      KCG/widgets/TimingWidget.py

+ 628 - 628
KCG/widgets/TimingWidget.py

@@ -1,628 +1,628 @@
-"""
-This Module Is the Timingsettings subWindow.
-"""
-import logging
-
-from PyQt4 import QtGui, QtCore
-import pyqtgraph as pg
-import numpy as np
-import h5py
-
-from ..base import kcgwidget as kcgw
-from ..base.backend import board
-from ..base.backend.board import available_boards
-from ..base import backendinterface as bif
-from ..base.groupedelements import Elements
-from ..base.globals import glob as global_objects
-from .. import config
-from ..base import storage
-from ..base.backend.CalibrationHandle import theCalibration
-
-tr = kcgw.tr
-import os
-
-
-__widget_id__ = None
-__timing_plot_widget_id__ = {}
-__timing_plot_widget__ = None
-
-BUNCHES_PER_TURN = config.bunches_per_turn
-
-
-
-# 88888888888d8b             d8b                8888888b.                888
-#     888    Y8P             Y8P                888   Y88b               888
-#     888                                       888    888               888
-#     888    88888888b.d88b. 88888888b.  .d88b. 888   d88P 8888b. 888d888888888
-#     888    888888 "888 "88b888888 "88bd88P"88b8888888P"     "88b888P"  888
-#     888    888888  888  888888888  888888  888888       .d888888888    888
-#     888    888888  888  888888888  888Y88b 888888       888  888888    Y88b.
-#     888    888888  888  888888888  888 "Y88888888       "Y888888888     "Y888
-#                                            888
-#                                       Y8b d88P
-#                                        "Y88P"
-
-class TimingPart(kcgw.KCGWidgets):
-    """
-    The actual timing settings window
-    """
-    def __init__(self, board_id, parent=None):
-        """
-        Initialise the timing settings window
-        :param unique_id:
-        :param parent:
-        :return:
-        """
-        super(TimingPart, self).__init__()
-
-        if __timing_plot_widget__:
-            self.plotWidget = __timing_plot_widget__
-        self.parent = parent
-        self.board_id = board_id
-        self.board_config =  board.get_board_config(board_id)
-        self.layout = QtGui.QGridLayout()
-        self.outerLayout = QtGui.QVBoxLayout()
-        self.outerLayout.addLayout(self.layout)
-        self.setLayout(self.outerLayout)
-        self.show_advanced = True        
-
-
-        #  --------[ Create Labels and corresponding Fields ]---------
-
-        def update_delay(which, spinbox):
-            '''update the delays on the board'''
-            val = getattr(self, spinbox).value()
-            self.board_config.update(which, val)
-            #if not self.show_advanced and "th" in which:
-            #    key = which[:-2] + "adc"
-            #    self.board_config.update(key, val)
-
-
-        self.adc_number = self.board_config.get('adc_number')
-            #board.get_board_config(board_id).set_delay(self.coarseInput.value())
-        self.thdelayLabel = self.createLabel(tr("Label", "Total Delay"))
-        #self.adc1thdelayLabel = self.createLabel(tr("Label", "2. ADC1 T/H Delay"))
-
-        self.labelCoarseAdcDelay = self.createLabel("ADC")
-        self.labelCoarseFpgaDelay = self.createLabel("FPGA")    
-
-        if self.adc_number > 4:
-            self.thdelayLabel_2 = self.createLabel("T/H FMC2")
-            self.labelCoarseAdcDelay_2 = self.createLabel("ADC FMC2")
-            #self.labelCoarseFpgaDelay_2 = self.createLabel("FPGA FMC2")
-            self.labelCascade = self.createLabel("Cascade")
-
-        self.coarseLabel = self.createLabel(tr("Label", "330ps Coarse Delay"))
-        self.coarseInputTh   = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_th", "coarseInputTh"))
-        self.coarseInputAdc  = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_adc", "coarseInputAdc"))
-        self.coarseInputFpga = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_fpga", "coarseInputFpga"))
-
-        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)], 
-                         [
-                            #self.coarseInputFpga,
-                            #self.coarseInputAdc,
-                            self.coarseInputTh
-                         ]
-                         )
-
-        #self.coarseInputAdc.setEnabled(False)
-        #self.coarseInputFpga.setEnabled(False)
-
-        if self.board_config.is_KAPTURE2():
-
-            self.coarse2Label = self.createLabel(tr("Label", "25ps Coarse Delay"))
-            self.coarse2InputTh   = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_th", "coarse2InputTh"))
-            self.coarse2InputAdc  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_adc", "coarse2InputAdc"))
-            self.coarse2InputFpga = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_fpga", "coarse2InputFpga"))
-
-            Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)], 
-                         [
-                            #self.coarse2InputAdc,
-                            #self.coarse2InputFpga,
-                            self.coarse2InputTh
-                         ]
-                         )
-
-            self.adc1CoarseInputSwitch = self.createCheckbox(tr("Label", "Enable advanced"), connect=self.toggleAdvanced)
-
-            if self.adc_number > 4:
-                #self.coarseLabel_2 = self.createLabel(tr("Label", "330ps FMC2"))
-                self.coarseInputTh_2   = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_th_2", "coarseInputTh_2"))
-                self.coarseInputAdc_2  = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_adc_2", "coarseInputAdc_2"))
-                #self.coarseInputFpga_2 = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_fpga_2", "coarseInputFpga_2"))
-
-                #self.coarse2Label = self.createLabel(tr("Label", "25ps FMC2"))
-                self.coarse2InputTh_2   = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_th_2", "coarse2InputTh_2"))
-                self.coarse2InputAdc_2  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_adc_2", "coarse2InputAdc_2"))
-                #self.coarse2InputFpga_2 = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_fpga_2", "coarse2InputFpga_2"))
-
-                self.coarseInputCascade  = self.createSpinbox(0, self.board_config.get('delay_cascade_max'), connect=lambda: update_delay("delay_cascade", "coarseInputCascade"))
-                self.coarse2InputCascade  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_cascade_25", "coarse2InputCascade"))
-
-                Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)], 
-                             [
-                                #self.coarseInputFpga,
-                                #self.coarseInputAdc,
-                                #self.coarseInputTh_2,
-                                #self.coarse2InputAdc,
-                                #self.coarse2InputFpga,
-                                self.coarse2InputTh_2
-                             ]
-                             )
-
-        self.fineLabel = self.createLabel(tr("Label", "Fine Delay"))
-
-        self.fineAdcInput = []
-        for i in range(self.adc_number):
-            self.fineAdcInput.append(self.createSpinbox(0, 31, connect=self.on_adc_delay_changed))
-
-        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)
-
-        self.bunchShiftLabel = self.createLabel(tr("Label", "Bunch Shift"))
-
-        self.bunchShiftInput = []
-        for i in range(self.adc_number):
-            self.bunchShiftInput.append(self.createSpinbox(-2, 2, connect=self.on_bunch_shift_changed))
-
-        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)
-
-
-        #---------[ End ]---------
-
-        
-        
-
-        def setValueSilent(value, spinbox, adc):
-            '''set values silent to not trigger signals'''
-            spinbox.blockSignals(True)
-            if adc is None:
-                spinbox.setValue(value)
-            else:
-                spinbox.setValue(value[adc])
-            spinbox.blockSignals(False)
-
-
-        #Bunch Shift values are encoded 0x0 - 0x4 in Hardware
-        #but displayed as -2 to +2 in the GUI, so we need to offset
-        #the received register value by -2 when receiving an update
-        def setBunchShiftValuesSilent(values):
-            for i, v in enumerate(values):
-                self.bunchShiftInput[i].blockSignals(True)
-                self.bunchShiftInput[i].setValue(v-2)
-                self.bunchShiftInput[i].blockSignals(False)
-
-
-        # --------[ Set observers ]------------
-        def obs(who, what, adc=None):
-            '''observe something'''
-            board.get_board_config(board_id).observe(
-                who,
-                lambda value=None: setValueSilent(value=value, spinbox=who, adc=adc),
-                what
-            )
-        for i, item in enumerate(self.fineAdcInput):
-            obs(item, 'chip_delay', i)
-        
-        obs(self.coarseInputTh, 'delay_330_th')
-        obs(self.coarseInputAdc, 'delay_330_adc')
-        obs(self.coarseInputFpga, 'delay_330_fpga')
-
-        if self.board_config.is_KAPTURE2():
-            obs(self.coarse2InputTh, 'delay_25_th')
-            obs(self.coarse2InputAdc, 'delay_25_adc')
-            obs(self.coarse2InputFpga, 'delay_25_fpga')
-
-            if self.adc_number > 4:
-                obs(self.coarseInputTh_2, 'delay_330_th_2')
-                obs(self.coarseInputAdc_2, 'delay_330_adc_2')
-                #obs(self.coarseInputFpga_2, 'delay_330_fpga_2')
-                obs(self.coarseInputCascade, 'delay_cascade')
-
-                obs(self.coarse2InputTh_2, 'delay_25_th_2')
-                obs(self.coarse2InputAdc_2, 'delay_25_adc_2')
-                obs(self.coarse2InputCascade, 'delay_cascade_25')
-                #obs(self.coarse2InputFpga_2, 'delay_25_fpga_2')
-
-        #obs(self.adc1CoarseInput, 'adc_1_delay_individual')
-
-        board.get_board_config(board_id).observe(
-                self.bunchShiftInput, 
-                setBunchShiftValuesSilent,
-                'bunch_shift'
-                )
-
-        # -------[ Create outputs ]---------------
-        self.totalLabel = self.createLabel(tr("Label", "Total Delay"))
-        self.totalAdcBox = []
-        for i in range(self.adc_number):
-            self.totalAdcBox.append(self.createInput("", read_only=True))
-        self.totalAdcBoxCalib = []
-        for i in range(self.adc_number):
-            self.totalAdcBoxCalib.append(self.createInput("", read_only=True))
-
-        self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'chip_delay')
-        self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_330_th')
-        if self.board_config.is_KAPTURE2():
-            self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_25_th')
-            if self.adc_number > 4:            
-                self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_330_th_2')
-                self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_25_th_2')
-
-        #--------[ Fill Grid ]----------------
-        self.layout.addWidget(self.thdelayLabel, 0, 1)
-        self.layout.addWidget(self.labelCoarseAdcDelay, 0, 2)
-        self.layout.addWidget(self.labelCoarseFpgaDelay, 0, 3)
-        if self.board_config.is_KAPTURE2():
-            self.layout.addWidget(self.adc1CoarseInputSwitch, 0, 8,1,2)
-            if self.adc_number > 4:
-                self.layout.addWidget(self.thdelayLabel_2, 0, 4)
-                self.layout.addWidget(self.labelCoarseAdcDelay_2, 0, 5)
-                #self.layout.addWidget(self.labelCoarseFpgaDelay_2, 0, 6)
-                self.layout.addWidget(self.labelCascade, 0, 7)
-
-
-        self.layout.addWidget(self.coarseLabel, 1, 0)
-        self.layout.addWidget(self.coarseInputTh, 1, 1)
-        self.layout.addWidget(self.coarseInputAdc, 1, 2)
-        self.layout.addWidget(self.coarseInputFpga, 1, 3)
-
-        #self.layout.addWidget(self.adc1thdelayLabel, 0, 2)
-        #self.layout.addWidget(self.adc1CoarseInput, 1, 2)
-        #self.layout.addWidget(self.adc1CoarseInputSwitch, 1, 3, 1, 2)
-        
-        self.layout.addItem(QtGui.QSpacerItem(10, 15), 2, 1)
-        if self.board_config.is_KAPTURE2():
-            self.layout.addWidget(self.coarse2Label, 3, 0)
-            self.layout.addWidget(self.coarse2InputTh, 3, 1)
-            self.layout.addWidget(self.coarse2InputAdc, 3, 2)
-            self.layout.addWidget(self.coarse2InputFpga, 3, 3)   
-
-            if self.adc_number > 4:
-                self.layout.addWidget(self.coarseInputTh_2, 1, 4)
-                self.layout.addWidget(self.coarseInputAdc_2, 1, 5)
-                #self.layout.addWidget(self.coarseInputFpga_2, 1, 6) 
-                self.layout.addWidget(self.coarseInputCascade, 1, 7) 
-
-                self.layout.addWidget(self.coarse2InputTh_2, 3, 4)
-                self.layout.addWidget(self.coarse2InputAdc_2, 3, 5)
-                #self.layout.addWidget(self.coarse2InputFpga_2, 3, 6) 
-                self.layout.addWidget(self.coarse2InputCascade, 3, 7) 
-
-
-        self.layout.addItem(QtGui.QSpacerItem(10, 15), 4, 1)
-
-        # Leave some rows free for additional things (empty rows will not be shown)
-        for i in range(self.adc_number):
-            self.layout.addWidget(self.createLabel("ADC "+str(i+1)), 5, i+1)
-        self.layout.addWidget(self.fineLabel, 6, 0)
-        for i, item in enumerate(self.fineAdcInput):
-            self.layout.addWidget(item, 6, i+1)
-        self.layout.addWidget(self.bunchShiftLabel, 7, 0)
-        for i, item in enumerate(self.bunchShiftInput):
-            self.layout.addWidget(item, 7, i+1)
-        
-        self.layout.addItem(QtGui.QSpacerItem(10, 15), 7, 1)
-        line = QtGui.QFrame()
-        line.setFrameStyle(QtGui.QFrame.HLine)
-        self.layout.addWidget(line, 8, 0, 1, 0)
-        self.layout.addItem(QtGui.QSpacerItem(10, 15), 9, 1)
-        self.layout.addWidget(self.totalLabel, 10, 0)
-        for i, item in enumerate(self.totalAdcBox):
-            self.layout.addWidget(item, 10, i+1)
-            item.setFocusPolicy(QtCore.Qt.ClickFocus)
-        self.layout.addWidget(self.createLabel('Calibrated (ps)'), 11, 0)
-        for i, item in enumerate(self.totalAdcBoxCalib):
-            self.layout.addWidget(item, 11, i+1)
-        self.layout.addItem(QtGui.QSpacerItem(10, 15), 11, 1)
-        
-
-        self.board_config.notify_all_observers()
-        self.toggleAdvanced()
-        self.setWindowTitle(tr("Heading", "Timing"))
-
-
-    def delay_observer(self, x):
-        d330 = ['delay_330_th', 'delay_330_th']
-        d25  = ['delay_25_th', 'delay_25_th']
-        
-        for i, item in enumerate(self.totalAdcBox):
-            if self.board_config.is_KAPTURE2():
-                string = '%i + %i + %i' % (self.board_config.get(d330[i//4])    * self.board_config.get('delay_330_factor'),
-                                               self.board_config.get(d25[i//4])     * self.board_config.get('delay_25_factor'),
-                                               (self.board_config.get('chip_delay')[i]) * self.board_config.get('chip_delay_factor'))
-                if i < 4: 
-                    string += "+ {:d}".format(self.board_config.get("delay_330_th_2")    * self.board_config.get('delay_330_factor')
-                                            + (self.board_config.get("delay_25_th_2")- self.board_config.get("default_25_th_2"))    * self.board_config.get('delay_25_factor'))
-                item.setText(string)
-               
-                val = self.board_config.get(d25[i//4]) * self.board_config.get('delay_25_factor')+self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')
-                if val == self.board_config.get('delay_330_factor'):
-                    item.setStyleSheet("color: rgb(120, 80, 0);")
-                elif val > self.board_config.get('delay_330_factor'):
-                    item.setStyleSheet("color: rgb(200, 80, 0);")
-                else:
-                    item.setStyleSheet("color: rgb(0, 0, 0);")
-
-            else:
-                item.setText('%i  + %i' % (self.board_config.get('delay_330_th')  * self.board_config.get('delay_330_factor'),
-                                           self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')))
-        if self.board_config.is_KAPTURE2():
-            for i, item in enumerate(self.totalAdcBoxCalib):
-                value = theCalibration.calibrateX(i, self.board_config.get('delay_330_th'), self.board_config.get('delay_25_th'), self.board_config.get('chip_delay')[i], self.board_config.get("delay_25_th_2"))
-                item.setText('{}'.format(np.round(value*1e12,1)))
-            """
-            if self.fileHandle is not None:
-                for i, item in enumerate(self.totalAdcBoxCalib):
-                    item.setText('{:.1f}'.format(self.board_config.get(d330[i//4]) * self.xcalib['d330'][()] + self.xcalib[str(i)]['33'][int(self.board_config.get(d330[i//4]))] +  
-                                                 self.board_config.get(d25[i//4])  * self.xcalib['d25'][()]  + self.xcalib[str(i)]['25'][int(self.board_config.get(d25[i//4]))]  + 
-                                                 self.board_config.get('chip_delay')[i]* self.xcalib['d3'][()]   + self.xcalib[str(i)]['3'][int(self.board_config.get('chip_delay')[i])] -
-                                                 float(self.fileHandle['x'][str(i)]['offset'][()])*1e12
-                                              ))
-            else:
-                for i, item in enumerate(self.totalAdcBoxCalib):
-                    value = (self.board_config.get(d330[i//4])    * self.board_config.get('delay_330_factor')
-                            + self.board_config.get(d25[i//4])   * self.board_config.get('delay_25_factor')
-                            + (self.board_config.get('chip_delay')[i]) * self.board_config.get('chip_delay_factor'))
-                    if i>=4:
-                        value -= (self.board_config.get("delay_330_th_2")  * self.board_config.get('delay_330_factor')
-                                 + self.board_config.get("delay_25_th_2") * self.board_config.get('delay_25_factor'))
-                    item.setText(str(value))
-            """
-
-    def toggleAdvanced(self):
-        if self.show_advanced:
-            self.labelCoarseAdcDelay.setEnabled(False)
-            self.labelCoarseFpgaDelay.setEnabled(False)
-            self.coarseInputAdc.setEnabled(False)
-            self.coarseInputFpga.setEnabled(False)
-            if self.board_config.is_KAPTURE2():
-                self.coarse2InputAdc.setEnabled(False)
-                self.coarse2InputFpga.setEnabled(False)
-                if self.adc_number > 4:
-                    self.labelCoarseAdcDelay_2.setEnabled(False)
-                    #self.labelCoarseFpgaDelay_2.setEnabled(False)
-                    self.labelCascade.setEnabled(False)
-                    self.coarseInputTh_2.setEnabled(False)
-                    self.coarseInputAdc_2.setEnabled(False)
-                    #self.coarseInputFpga_2.setEnabled(False)
-                    self.coarse2InputAdc_2.setEnabled(False)
-                    #self.coarse2InputFpga_2.setEnabled(False)
-                    self.coarseInputCascade.setEnabled(False)
-                    self.coarse2InputCascade.setEnabled(False)
-            self.show_advanced = False
-        else:
-            self.labelCoarseAdcDelay.setEnabled(True)
-            self.labelCoarseFpgaDelay.setEnabled(True)
-            self.coarseInputAdc.setEnabled(True)
-            self.coarseInputFpga.setEnabled(True)
-            if self.board_config.is_KAPTURE2():
-                self.coarse2InputAdc.setEnabled(True)
-                self.coarse2InputFpga.setEnabled(True)
-                if self.adc_number > 4:
-                    self.labelCoarseAdcDelay_2.setEnabled(True)
-                    #self.labelCoarseFpgaDelay_2.setEnabled(True)
-                    self.labelCascade.setEnabled(True)
-                    self.coarseInputTh_2.setEnabled(True)
-                    self.coarseInputAdc_2.setEnabled(True)
-                    #self.coarseInputFpga_2.setEnabled(True)
-                    self.coarse2InputAdc_2.setEnabled(True)
-                    #self.coarse2InputFpga_2.setEnabled(True)
-                    self.coarseInputCascade.setEnabled(True)
-                    self.coarse2InputCascade.setEnabled(True)
-            self.show_advanced = True
-
-    def toggleAdc1IndividualDelay(self):
-        """
-        Toggle to use an individual delay for adc1 or not
-        :return: -
-        """
-        self.adc1CoarseInput.setEnabled(self.adc1CoarseInputSwitch.checkState())
-        if not self.adc1CoarseInput.isEnabled():
-            board.get_board_config(self.board_id).update('adc_1_delay_individual', -1) # Be careful this does no silent update
-
-
-    def setValueSilent(self, element, value):
-        """
-        Set Values to inputs without notifying observers
-        :param element: the input
-        :param value: the value
-        :return: -
-        """
-        element.blockSignals(True)
-        element.setValue(value)
-        element.blockSignals(False)
-
-
-    def closeEvent(self, event):
-        """
-        Event handler when this window is closed
-        """
-        
-        self.board_config.unobserve(self.totalAdcBox[0], 'chip_delay')
-        if self.board_config.is_KAPTURE2():
-            self.board_config.unobserve(self.totalAdcBox[0], 'delay_25_th')
-            if self.adc_number > 4:
-                self.board_config.unobserve(self.totalAdcBox[0], 'delay_330_th_2')
-                self.board_config.unobserve(self.totalAdcBox[0], 'delay_25_th_2')
-
-        self.board_config.unobserve(self.totalAdcBox[0], 'delay_330_th')
-
-        for i, item in enumerate(self.fineAdcInput):
-            self.board_config.unobserve(item, 'chip_delay')
-
-        self.board_config.unobserve(self.bunchShiftInput, 'bunch_shift')
-
-
-        self.board_config.unobserve(self.coarseInputTh, 'delay_330_th')
-        self.board_config.unobserve(self.coarseInputAdc, 'delay_330_adc')
-        self.board_config.unobserve(self.coarseInputFpga, 'delay_330_fpga')
-
-        if self.board_config.is_KAPTURE2():
-            self.board_config.unobserve(self.coarse2InputTh, 'delay_25_th')
-            self.board_config.unobserve(self.coarse2InputAdc, 'delay_25_adc')
-            self.board_config.unobserve(self.coarse2InputFpga, 'delay_25_fpga')
-            if self.adc_number > 4:
-                self.board_config.unobserve(self.coarseInputTh_2, 'delay_330_th_2')
-                self.board_config.unobserve(self.coarseInputAdc_2, 'delay_330_adc_2')
-                #self.board_config.unobserve(self.coarseInputFpga_2, 'delay_330_fpga_2')
-                self.board_config.unobserve(self.coarseInputCascade, 'delay_cascade')
-
-                self.board_config.unobserve(self.coarse2InputTh_2, 'delay_25_th_2')
-                self.board_config.unobserve(self.coarse2InputAdc_2, 'delay_25_adc_2')
-                self.board_config.unobserve(self.coarse2InputCascade, 'delay_cascade_25')
-                #self.board_config.unobserve(self.coarse2InputFpga_2, 'delay_25_fpga_2')
-        
-
-        Elements.emptyGroup('timing_{}'.format(self.board_id))
-        Elements.removeItem(None, self.fineAdcInput)
-        Elements.removeItem(None, self.bunchShiftInput)
-        Elements.removeItem(None, [
-                                    self.coarseInputTh,
-                                    self.coarseInputAdc,
-                                    self.coarseInputFpga
-                                  ]
-                            )
-        if self.board_config.is_KAPTURE2():
-            Elements.removeItem(None, [
-                                        self.coarse2InputTh,
-                                        self.coarse2InputAdc,
-                                        self.coarse2InputFpga
-                                      ]
-                                )
-            if self.adc_number > 4:
-                Elements.removeItem(None, [
-                                            self.coarseInputTh_2,
-                                            self.coarseInputAdc_2,
-                                            #self.coarseInputFpga_2,
-
-                                            self.coarse2InputTh_2,
-                                            self.coarse2InputAdc_2,
-                                            #self.coarse2InputFpga_2
-                                          ]
-                                    )
-        
-        
-
-        super(TimingPart, self).closeEvent(event)
-
-    def on_adc_delay_changed(self):
-        """
-        Handler that gets called when an adc delay gets changed
-        """
-        try:
-            factors = []
-            for item in self.fineAdcInput:
-                factors.extend([item.value()])
-            
-            self.board_config.update('chip_delay', factors)
-        except board.BoardError as e:
-            logging.error("ADC fine delay failed: {}".format(str(e)))
-            bif.bk_status_readout(self.board_id)
-            return
-
-
-    
-    def on_bunch_shift_changed(self):
-        """
-        Handler that gets called when a bunch shift setting gets changed
-        """
-        try:
-            factors = []
-            for item in self.bunchShiftInput:
-                #Bunch Shifts are encoded 0x0 - 0x4 in Hardware
-                #but shown as -2 to +2 in GUI, so we need a +2 offset
-                factors.extend([item.value()+2])
-            
-            self.board_config.update('bunch_shift', factors)
-        except board.BoardError as e:
-            logging.error("ADC bunch shift failed: {}".format(str(e)))
-            bif.bk_status_readout(self.board_id)
-            return
-
-        
-
-
-# 888   d8b             d8b                888       888d8b     888                888
-# 888   Y8P             Y8P                888   o   888Y8P     888                888
-# 888                                      888  d8b  888        888                888
-# 88888888888888b.d88b. 88888888b.  .d88b. 888 d888b 888888 .d88888 .d88b.  .d88b. 888888
-# 888   888888 "888 "88b888888 "88bd88P"88b888d88888b888888d88" 888d88P"88bd8P  Y8b888
-# 888   888888  888  888888888  888888  88888888P Y88888888888  888888  88888888888888
-# Y88b. 888888  888  888888888  888Y88b 8888888P   Y8888888Y88b 888Y88b 888Y8b.    Y88b.
-#  "Y888888888  888  888888888  888 "Y88888888P     Y888888 "Y88888 "Y88888 "Y8888  "Y888
-#                                       888                             888
-#                                  Y8b d88P                        Y8b d88P
-#                                   "Y88P"                          "Y88P"
-
-class TimingWidget(kcgw.KCGWidgets):
-    """
-    This is the container that holds the tab widget which contains the timing widgets for each board
-    """
-    def __init__(self, unique_id, parent=None):
-        super(TimingWidget, self).__init__()
-
-        self.id = unique_id
-        self.par = parent
-        self.setWindowTitle("Timing")
-
-        self.layout = QtGui.QHBoxLayout()
-        self.setLayout(self.layout)
-        self.widgets = {i: TimingPart(i, self) for i in available_boards}  # has to set parent with self because
-                                            # otherwise the window does not get resized correctly upon enabling timescan
-
-        if available_boards.multi_board:
-            self.tabWidget = QtGui.QTabWidget()
-            self.layout.addWidget(self.tabWidget)
-
-            for id, widget in self.widgets.items():
-                self.tabWidget.addTab(widget, available_boards.get_board_name_from_id(id))
-        else:
-            self.single_board_widget = list(self.widgets.values())[0]
-            self.layout.addWidget(self.single_board_widget)
-
-    def adjustSizeForTimeScan(self):
-        """
-        Adjust the size of the widget to accomodate the time_scan part
-        :return:
-        """
-                # self.parentWindow = self.parent().parent().parent().parent()  # one up is stacked widget, second up is
-                #                     tab widget, third up is timingWidget fourh up is KCGWSubWindow (the actual window)
-        QtCore.QCoreApplication.processEvents()
-        if self.parent().windowState() & QtCore.Qt.WindowMaximized:
-            self.parent().setWindowState(QtCore.Qt.WindowMaximized)
-        else:
-            # self.parent().resize(self.minimumSizeHint().width() * 1.2, self.minimumSizeHint().height()*1.1)
-            self.parent().adjustSize()
-
-    def closeEvent(self, event):
-        global __widget_id__
-        __widget_id__ = None
-
-        for widget in list(self.widgets.values()):
-            widget.closeEvent(event)
-        del self.par.widgets[self.id]
-        super(TimingWidget, self).closeEvent(event)
-
-
-def addTimingWidget():
-    """
-    Add this widget to the gui.
-    This function will actually open the subwindow.
-    :return: -
-    """
-    global __widget_id__
-    if __widget_id__:
-        global_objects.get_global('area').widgets[__widget_id__].setFocus()
-    else:
-        nid = kcgw.idg.genid()
-        __widget_id__ = nid
-        w = TimingWidget(nid, global_objects.get_global('area'))
-        global_objects.get_global('area').newWidget(w, tr("Heading", "Timing"), nid, widget_type=4, minSize=True) #TODO: proper type
-
-kcgw.register_widget(QtGui.QIcon(config.icon_path(config.timingIcon)), tr("Heading", "Timing"), addTimingWidget, "Ctrl+T")
+"""
+This Module Is the Timingsettings subWindow.
+"""
+import logging
+
+from PyQt4 import QtGui, QtCore
+import pyqtgraph as pg
+import numpy as np
+import h5py
+
+from ..base import kcgwidget as kcgw
+from ..base.backend import board
+from ..base.backend.board import available_boards
+from ..base import backendinterface as bif
+from ..base.groupedelements import Elements
+from ..base.globals import glob as global_objects
+from .. import config
+from ..base import storage
+from ..base.backend.CalibrationHandle import theCalibration
+
+tr = kcgw.tr
+import os
+
+
+__widget_id__ = None
+__timing_plot_widget_id__ = {}
+__timing_plot_widget__ = None
+
+BUNCHES_PER_TURN = config.bunches_per_turn
+
+
+
+# 88888888888d8b             d8b                8888888b.                888
+#     888    Y8P             Y8P                888   Y88b               888
+#     888                                       888    888               888
+#     888    88888888b.d88b. 88888888b.  .d88b. 888   d88P 8888b. 888d888888888
+#     888    888888 "888 "88b888888 "88bd88P"88b8888888P"     "88b888P"  888
+#     888    888888  888  888888888  888888  888888       .d888888888    888
+#     888    888888  888  888888888  888Y88b 888888       888  888888    Y88b.
+#     888    888888  888  888888888  888 "Y88888888       "Y888888888     "Y888
+#                                            888
+#                                       Y8b d88P
+#                                        "Y88P"
+
+class TimingPart(kcgw.KCGWidgets):
+    """
+    The actual timing settings window
+    """
+    def __init__(self, board_id, parent=None):
+        """
+        Initialise the timing settings window
+        :param unique_id:
+        :param parent:
+        :return:
+        """
+        super(TimingPart, self).__init__()
+
+        if __timing_plot_widget__:
+            self.plotWidget = __timing_plot_widget__
+        self.parent = parent
+        self.board_id = board_id
+        self.board_config =  board.get_board_config(board_id)
+        self.layout = QtGui.QGridLayout()
+        self.outerLayout = QtGui.QVBoxLayout()
+        self.outerLayout.addLayout(self.layout)
+        self.setLayout(self.outerLayout)
+        self.show_advanced = True        
+
+
+        #  --------[ Create Labels and corresponding Fields ]---------
+
+        def update_delay(which, spinbox):
+            '''update the delays on the board'''
+            val = getattr(self, spinbox).value()
+            self.board_config.update(which, val)
+            #if not self.show_advanced and "th" in which:
+            #    key = which[:-2] + "adc"
+            #    self.board_config.update(key, val)
+
+
+        self.adc_number = self.board_config.get('adc_number')
+            #board.get_board_config(board_id).set_delay(self.coarseInput.value())
+        self.thdelayLabel = self.createLabel(tr("Label", "Total Delay"))
+        #self.adc1thdelayLabel = self.createLabel(tr("Label", "2. ADC1 T/H Delay"))
+
+        self.labelCoarseAdcDelay = self.createLabel("ADC")
+        self.labelCoarseFpgaDelay = self.createLabel("FPGA")    
+
+        if self.adc_number > 4:
+            self.thdelayLabel_2 = self.createLabel("T/H FMC2")
+            self.labelCoarseAdcDelay_2 = self.createLabel("ADC FMC2")
+            #self.labelCoarseFpgaDelay_2 = self.createLabel("FPGA FMC2")
+            self.labelCascade = self.createLabel("Cascade")
+
+        self.coarseLabel = self.createLabel(tr("Label", "330ps Coarse Delay"))
+        self.coarseInputTh   = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_th", "coarseInputTh"))
+        self.coarseInputAdc  = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_adc", "coarseInputAdc"))
+        self.coarseInputFpga = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_fpga", "coarseInputFpga"))
+
+        Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)], 
+                         [
+                            #self.coarseInputFpga,
+                            #self.coarseInputAdc,
+                            self.coarseInputTh
+                         ]
+                         )
+
+        #self.coarseInputAdc.setEnabled(False)
+        #self.coarseInputFpga.setEnabled(False)
+
+        if self.board_config.is_KAPTURE2():
+
+            self.coarse2Label = self.createLabel(tr("Label", "25ps Coarse Delay"))
+            self.coarse2InputTh   = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_th", "coarse2InputTh"))
+            self.coarse2InputAdc  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_adc", "coarse2InputAdc"))
+            self.coarse2InputFpga = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_fpga", "coarse2InputFpga"))
+
+            Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)], 
+                         [
+                            #self.coarse2InputAdc,
+                            #self.coarse2InputFpga,
+                            self.coarse2InputTh
+                         ]
+                         )
+
+            self.adc1CoarseInputSwitch = self.createCheckbox(tr("Label", "Enable advanced"), connect=self.toggleAdvanced)
+
+            if self.adc_number > 4:
+                #self.coarseLabel_2 = self.createLabel(tr("Label", "330ps FMC2"))
+                self.coarseInputTh_2   = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_th_2", "coarseInputTh_2"))
+                self.coarseInputAdc_2  = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_adc_2", "coarseInputAdc_2"))
+                #self.coarseInputFpga_2 = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_fpga_2", "coarseInputFpga_2"))
+
+                #self.coarse2Label = self.createLabel(tr("Label", "25ps FMC2"))
+                self.coarse2InputTh_2   = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_th_2", "coarse2InputTh_2"))
+                self.coarse2InputAdc_2  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_adc_2", "coarse2InputAdc_2"))
+                #self.coarse2InputFpga_2 = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_fpga_2", "coarse2InputFpga_2"))
+
+                self.coarseInputCascade  = self.createSpinbox(0, self.board_config.get('delay_cascade_max'), connect=lambda: update_delay("delay_cascade", "coarseInputCascade"))
+                self.coarse2InputCascade  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_cascade_25", "coarse2InputCascade"))
+
+                Elements.addItem(["timing_{}".format(self.board_id), "no_board_{}".format(self.board_id), "acquire_{}".format(self.board_id), "continuous_read_{}".format(board_id)], 
+                             [
+                                #self.coarseInputFpga,
+                                #self.coarseInputAdc,
+                                #self.coarseInputTh_2,
+                                #self.coarse2InputAdc,
+                                #self.coarse2InputFpga,
+                                self.coarse2InputTh_2
+                             ]
+                             )
+
+        self.fineLabel = self.createLabel(tr("Label", "Fine Delay"))
+
+        self.fineAdcInput = []
+        for i in range(self.adc_number):
+            self.fineAdcInput.append(self.createSpinbox(0, 31, connect=self.on_adc_delay_changed))
+
+        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)
+
+        self.bunchShiftLabel = self.createLabel(tr("Label", "Bunch Shift"))
+
+        self.bunchShiftInput = []
+        for i in range(self.adc_number):
+            self.bunchShiftInput.append(self.createSpinbox(-2, 2, connect=self.on_bunch_shift_changed))
+
+        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)
+
+
+        #---------[ End ]---------
+
+        
+        
+
+        def setValueSilent(value, spinbox, adc):
+            '''set values silent to not trigger signals'''
+            spinbox.blockSignals(True)
+            if adc is None:
+                spinbox.setValue(value)
+            else:
+                spinbox.setValue(value[adc])
+            spinbox.blockSignals(False)
+
+
+        #Bunch Shift values are encoded 0x0 - 0x4 in Hardware
+        #but displayed as -2 to +2 in the GUI, so we need to offset
+        #the received register value by -2 when receiving an update
+        def setBunchShiftValuesSilent(values):
+            for i, v in enumerate(values):
+                self.bunchShiftInput[i].blockSignals(True)
+                self.bunchShiftInput[i].setValue(v-2)
+                self.bunchShiftInput[i].blockSignals(False)
+
+
+        # --------[ Set observers ]------------
+        def obs(who, what, adc=None):
+            '''observe something'''
+            board.get_board_config(board_id).observe(
+                who,
+                lambda value=None: setValueSilent(value=value, spinbox=who, adc=adc),
+                what
+            )
+        for i, item in enumerate(self.fineAdcInput):
+            obs(item, 'chip_delay', i)
+        
+        obs(self.coarseInputTh, 'delay_330_th')
+        obs(self.coarseInputAdc, 'delay_330_adc')
+        obs(self.coarseInputFpga, 'delay_330_fpga')
+
+        if self.board_config.is_KAPTURE2():
+            obs(self.coarse2InputTh, 'delay_25_th')
+            obs(self.coarse2InputAdc, 'delay_25_adc')
+            obs(self.coarse2InputFpga, 'delay_25_fpga')
+
+            if self.adc_number > 4:
+                obs(self.coarseInputTh_2, 'delay_330_th_2')
+                obs(self.coarseInputAdc_2, 'delay_330_adc_2')
+                #obs(self.coarseInputFpga_2, 'delay_330_fpga_2')
+                obs(self.coarseInputCascade, 'delay_cascade')
+
+                obs(self.coarse2InputTh_2, 'delay_25_th_2')
+                obs(self.coarse2InputAdc_2, 'delay_25_adc_2')
+                obs(self.coarse2InputCascade, 'delay_cascade_25')
+                #obs(self.coarse2InputFpga_2, 'delay_25_fpga_2')
+
+        #obs(self.adc1CoarseInput, 'adc_1_delay_individual')
+
+        board.get_board_config(board_id).observe(
+                self.bunchShiftInput, 
+                setBunchShiftValuesSilent,
+                'bunch_shift'
+                )
+
+        # -------[ Create outputs ]---------------
+        self.totalLabel = self.createLabel(tr("Label", "Total Delay"))
+        self.totalAdcBox = []
+        for i in range(self.adc_number):
+            self.totalAdcBox.append(self.createInput("", read_only=True))
+        self.totalAdcBoxCalib = []
+        for i in range(self.adc_number):
+            self.totalAdcBoxCalib.append(self.createInput("", read_only=True))
+
+        self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'chip_delay')
+        self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_330_th')
+        if self.board_config.is_KAPTURE2():
+            self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_25_th')
+            if self.adc_number > 4:            
+                self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_330_th_2')
+                self.board_config.observe(self.totalAdcBox[0], self.delay_observer, 'delay_25_th_2')
+
+        #--------[ Fill Grid ]----------------
+        self.layout.addWidget(self.thdelayLabel, 0, 1)
+        self.layout.addWidget(self.labelCoarseAdcDelay, 0, 2)
+        self.layout.addWidget(self.labelCoarseFpgaDelay, 0, 3)
+        if self.board_config.is_KAPTURE2():
+            self.layout.addWidget(self.adc1CoarseInputSwitch, 0, 8,1,2)
+            if self.adc_number > 4:
+                self.layout.addWidget(self.thdelayLabel_2, 0, 4)
+                self.layout.addWidget(self.labelCoarseAdcDelay_2, 0, 5)
+                #self.layout.addWidget(self.labelCoarseFpgaDelay_2, 0, 6)
+                self.layout.addWidget(self.labelCascade, 0, 7)
+
+
+        self.layout.addWidget(self.coarseLabel, 1, 0)
+        self.layout.addWidget(self.coarseInputTh, 1, 1)
+        self.layout.addWidget(self.coarseInputAdc, 1, 2)
+        self.layout.addWidget(self.coarseInputFpga, 1, 3)
+
+        #self.layout.addWidget(self.adc1thdelayLabel, 0, 2)
+        #self.layout.addWidget(self.adc1CoarseInput, 1, 2)
+        #self.layout.addWidget(self.adc1CoarseInputSwitch, 1, 3, 1, 2)
+        
+        self.layout.addItem(QtGui.QSpacerItem(10, 15), 2, 1)
+        if self.board_config.is_KAPTURE2():
+            self.layout.addWidget(self.coarse2Label, 3, 0)
+            self.layout.addWidget(self.coarse2InputTh, 3, 1)
+            self.layout.addWidget(self.coarse2InputAdc, 3, 2)
+            self.layout.addWidget(self.coarse2InputFpga, 3, 3)   
+
+            if self.adc_number > 4:
+                self.layout.addWidget(self.coarseInputTh_2, 1, 4)
+                self.layout.addWidget(self.coarseInputAdc_2, 1, 5)
+                #self.layout.addWidget(self.coarseInputFpga_2, 1, 6) 
+                self.layout.addWidget(self.coarseInputCascade, 1, 7) 
+
+                self.layout.addWidget(self.coarse2InputTh_2, 3, 4)
+                self.layout.addWidget(self.coarse2InputAdc_2, 3, 5)
+                #self.layout.addWidget(self.coarse2InputFpga_2, 3, 6) 
+                self.layout.addWidget(self.coarse2InputCascade, 3, 7) 
+
+
+        self.layout.addItem(QtGui.QSpacerItem(10, 15), 4, 1)
+
+        # Leave some rows free for additional things (empty rows will not be shown)
+        for i in range(self.adc_number):
+            self.layout.addWidget(self.createLabel("ADC "+str(i+1)), 5, i+1)
+        self.layout.addWidget(self.fineLabel, 6, 0)
+        for i, item in enumerate(self.fineAdcInput):
+            self.layout.addWidget(item, 6, i+1)
+        self.layout.addWidget(self.bunchShiftLabel, 7, 0)
+        for i, item in enumerate(self.bunchShiftInput):
+            self.layout.addWidget(item, 7, i+1)
+        
+        self.layout.addItem(QtGui.QSpacerItem(10, 15), 7, 1)
+        line = QtGui.QFrame()
+        line.setFrameStyle(QtGui.QFrame.HLine)
+        self.layout.addWidget(line, 8, 0, 1, 0)
+        self.layout.addItem(QtGui.QSpacerItem(10, 15), 9, 1)
+        self.layout.addWidget(self.totalLabel, 10, 0)
+        for i, item in enumerate(self.totalAdcBox):
+            self.layout.addWidget(item, 10, i+1)
+            item.setFocusPolicy(QtCore.Qt.ClickFocus)
+        self.layout.addWidget(self.createLabel('Calibrated (ps)'), 11, 0)
+        for i, item in enumerate(self.totalAdcBoxCalib):
+            self.layout.addWidget(item, 11, i+1)
+        self.layout.addItem(QtGui.QSpacerItem(10, 15), 11, 1)
+        
+
+        self.board_config.notify_all_observers()
+        self.toggleAdvanced()
+        self.setWindowTitle(tr("Heading", "Timing"))
+
+
+    def delay_observer(self, x):
+        d330 = ['delay_330_th', 'delay_330_th']
+        d25  = ['delay_25_th', 'delay_25_th']
+        
+        for i, item in enumerate(self.totalAdcBox):
+            if self.board_config.is_KAPTURE2():
+                string = '%i + %i + %i' % (self.board_config.get(d330[i//4])    * self.board_config.get('delay_330_factor'),
+                                               self.board_config.get(d25[i//4])     * self.board_config.get('delay_25_factor'),
+                                               (self.board_config.get('chip_delay')[i]) * self.board_config.get('chip_delay_factor'))
+                if i < 4: 
+                    string += "+ {:d}".format(self.board_config.get("delay_330_th_2")    * self.board_config.get('delay_330_factor')
+                                            + (self.board_config.get("delay_25_th_2")- self.board_config.get("default_25_th_2"))    * self.board_config.get('delay_25_factor'))
+                item.setText(string)
+               
+                val = self.board_config.get(d25[i//4]) * self.board_config.get('delay_25_factor')+self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')
+                if val == self.board_config.get('delay_330_factor'):
+                    item.setStyleSheet("color: rgb(120, 80, 0);")
+                elif val > self.board_config.get('delay_330_factor'):
+                    item.setStyleSheet("color: rgb(200, 80, 0);")
+                else:
+                    item.setStyleSheet("color: rgb(0, 0, 0);")
+
+            else:
+                item.setText('%i  + %i' % (self.board_config.get('delay_330_th')  * self.board_config.get('delay_330_factor'),
+                                           self.board_config.get('chip_delay')[i] * self.board_config.get('chip_delay_factor')))
+        if self.board_config.is_KAPTURE2():
+            for i, item in enumerate(self.totalAdcBoxCalib):
+                value = theCalibration.calibrateX(i, self.board_config.get('delay_330_th'), self.board_config.get('delay_25_th'), self.board_config.get('chip_delay')[i], self.board_config.get("delay_25_th_2"))
+                item.setText('{}'.format(np.round(value*1e12,1)))
+            """
+            if self.fileHandle is not None:
+                for i, item in enumerate(self.totalAdcBoxCalib):
+                    item.setText('{:.1f}'.format(self.board_config.get(d330[i//4]) * self.xcalib['d330'][()] + self.xcalib[str(i)]['33'][int(self.board_config.get(d330[i//4]))] +  
+                                                 self.board_config.get(d25[i//4])  * self.xcalib['d25'][()]  + self.xcalib[str(i)]['25'][int(self.board_config.get(d25[i//4]))]  + 
+                                                 self.board_config.get('chip_delay')[i]* self.xcalib['d3'][()]   + self.xcalib[str(i)]['3'][int(self.board_config.get('chip_delay')[i])] -
+                                                 float(self.fileHandle['x'][str(i)]['offset'][()])*1e12
+                                              ))
+            else:
+                for i, item in enumerate(self.totalAdcBoxCalib):
+                    value = (self.board_config.get(d330[i//4])    * self.board_config.get('delay_330_factor')
+                            + self.board_config.get(d25[i//4])   * self.board_config.get('delay_25_factor')
+                            + (self.board_config.get('chip_delay')[i]) * self.board_config.get('chip_delay_factor'))
+                    if i>=4:
+                        value -= (self.board_config.get("delay_330_th_2")  * self.board_config.get('delay_330_factor')
+                                 + self.board_config.get("delay_25_th_2") * self.board_config.get('delay_25_factor'))
+                    item.setText(str(value))
+            """
+
+    def toggleAdvanced(self):
+        if self.show_advanced:
+            self.labelCoarseAdcDelay.setEnabled(False)
+            self.labelCoarseFpgaDelay.setEnabled(False)
+            self.coarseInputAdc.setEnabled(False)
+            self.coarseInputFpga.setEnabled(False)
+            if self.board_config.is_KAPTURE2():
+                self.coarse2InputAdc.setEnabled(False)
+                self.coarse2InputFpga.setEnabled(False)
+                if self.adc_number > 4:
+                    self.labelCoarseAdcDelay_2.setEnabled(False)
+                    #self.labelCoarseFpgaDelay_2.setEnabled(False)
+                    self.labelCascade.setEnabled(False)
+                    self.coarseInputTh_2.setEnabled(False)
+                    self.coarseInputAdc_2.setEnabled(False)
+                    #self.coarseInputFpga_2.setEnabled(False)
+                    self.coarse2InputAdc_2.setEnabled(False)
+                    #self.coarse2InputFpga_2.setEnabled(False)
+                    self.coarseInputCascade.setEnabled(False)
+                    self.coarse2InputCascade.setEnabled(False)
+            self.show_advanced = False
+        else:
+            self.labelCoarseAdcDelay.setEnabled(True)
+            self.labelCoarseFpgaDelay.setEnabled(True)
+            self.coarseInputAdc.setEnabled(True)
+            self.coarseInputFpga.setEnabled(True)
+            if self.board_config.is_KAPTURE2():
+                self.coarse2InputAdc.setEnabled(True)
+                self.coarse2InputFpga.setEnabled(True)
+                if self.adc_number > 4:
+                    self.labelCoarseAdcDelay_2.setEnabled(True)
+                    #self.labelCoarseFpgaDelay_2.setEnabled(True)
+                    self.labelCascade.setEnabled(True)
+                    self.coarseInputTh_2.setEnabled(True)
+                    self.coarseInputAdc_2.setEnabled(True)
+                    #self.coarseInputFpga_2.setEnabled(True)
+                    self.coarse2InputAdc_2.setEnabled(True)
+                    #self.coarse2InputFpga_2.setEnabled(True)
+                    self.coarseInputCascade.setEnabled(True)
+                    self.coarse2InputCascade.setEnabled(True)
+            self.show_advanced = True
+
+    def toggleAdc1IndividualDelay(self):
+        """
+        Toggle to use an individual delay for adc1 or not
+        :return: -
+        """
+        self.adc1CoarseInput.setEnabled(self.adc1CoarseInputSwitch.checkState())
+        if not self.adc1CoarseInput.isEnabled():
+            board.get_board_config(self.board_id).update('adc_1_delay_individual', -1) # Be careful this does no silent update
+
+
+    def setValueSilent(self, element, value):
+        """
+        Set Values to inputs without notifying observers
+        :param element: the input
+        :param value: the value
+        :return: -
+        """
+        element.blockSignals(True)
+        element.setValue(value)
+        element.blockSignals(False)
+
+
+    def closeEvent(self, event):
+        """
+        Event handler when this window is closed
+        """
+        
+        self.board_config.unobserve(self.totalAdcBox[0], 'chip_delay')
+        if self.board_config.is_KAPTURE2():
+            self.board_config.unobserve(self.totalAdcBox[0], 'delay_25_th')
+            if self.adc_number > 4:
+                self.board_config.unobserve(self.totalAdcBox[0], 'delay_330_th_2')
+                self.board_config.unobserve(self.totalAdcBox[0], 'delay_25_th_2')
+
+        self.board_config.unobserve(self.totalAdcBox[0], 'delay_330_th')
+
+        for i, item in enumerate(self.fineAdcInput):
+            self.board_config.unobserve(item, 'chip_delay')
+
+        self.board_config.unobserve(self.bunchShiftInput, 'bunch_shift')
+
+
+        self.board_config.unobserve(self.coarseInputTh, 'delay_330_th')
+        self.board_config.unobserve(self.coarseInputAdc, 'delay_330_adc')
+        self.board_config.unobserve(self.coarseInputFpga, 'delay_330_fpga')
+
+        if self.board_config.is_KAPTURE2():
+            self.board_config.unobserve(self.coarse2InputTh, 'delay_25_th')
+            self.board_config.unobserve(self.coarse2InputAdc, 'delay_25_adc')
+            self.board_config.unobserve(self.coarse2InputFpga, 'delay_25_fpga')
+            if self.adc_number > 4:
+                self.board_config.unobserve(self.coarseInputTh_2, 'delay_330_th_2')
+                self.board_config.unobserve(self.coarseInputAdc_2, 'delay_330_adc_2')
+                #self.board_config.unobserve(self.coarseInputFpga_2, 'delay_330_fpga_2')
+                self.board_config.unobserve(self.coarseInputCascade, 'delay_cascade')
+
+                self.board_config.unobserve(self.coarse2InputTh_2, 'delay_25_th_2')
+                self.board_config.unobserve(self.coarse2InputAdc_2, 'delay_25_adc_2')
+                self.board_config.unobserve(self.coarse2InputCascade, 'delay_cascade_25')
+                #self.board_config.unobserve(self.coarse2InputFpga_2, 'delay_25_fpga_2')
+        
+
+        Elements.emptyGroup('timing_{}'.format(self.board_id))
+        Elements.removeItem(None, self.fineAdcInput)
+        Elements.removeItem(None, self.bunchShiftInput)
+        Elements.removeItem(None, [
+                                    self.coarseInputTh,
+                                    self.coarseInputAdc,
+                                    self.coarseInputFpga
+                                  ]
+                            )
+        if self.board_config.is_KAPTURE2():
+            Elements.removeItem(None, [
+                                        self.coarse2InputTh,
+                                        self.coarse2InputAdc,
+                                        self.coarse2InputFpga
+                                      ]
+                                )
+            if self.adc_number > 4:
+                Elements.removeItem(None, [
+                                            self.coarseInputTh_2,
+                                            self.coarseInputAdc_2,
+                                            #self.coarseInputFpga_2,
+
+                                            self.coarse2InputTh_2,
+                                            self.coarse2InputAdc_2,
+                                            #self.coarse2InputFpga_2
+                                          ]
+                                    )
+        
+        
+
+        super(TimingPart, self).closeEvent(event)
+
+    def on_adc_delay_changed(self):
+        """
+        Handler that gets called when an adc delay gets changed
+        """
+        try:
+            factors = []
+            for item in self.fineAdcInput:
+                factors.extend([item.value()])
+            
+            self.board_config.update('chip_delay', factors)
+        except board.BoardError as e:
+            logging.error("ADC fine delay failed: {}".format(str(e)))
+            bif.bk_status_readout(self.board_id)
+            return
+
+
+    
+    def on_bunch_shift_changed(self):
+        """
+        Handler that gets called when a bunch shift setting gets changed
+        """
+        try:
+            factors = []
+            for item in self.bunchShiftInput:
+                #Bunch Shifts are encoded 0x0 - 0x4 in Hardware
+                #but shown as -2 to +2 in GUI, so we need a +2 offset
+                factors.extend([item.value()+2])
+            
+            self.board_config.update('bunch_shift', factors)
+        except board.BoardError as e:
+            logging.error("ADC bunch shift failed: {}".format(str(e)))
+            bif.bk_status_readout(self.board_id)
+            return
+
+        
+
+
+# 888   d8b             d8b                888       888d8b     888                888
+# 888   Y8P             Y8P                888   o   888Y8P     888                888
+# 888                                      888  d8b  888        888                888
+# 88888888888888b.d88b. 88888888b.  .d88b. 888 d888b 888888 .d88888 .d88b.  .d88b. 888888
+# 888   888888 "888 "88b888888 "88bd88P"88b888d88888b888888d88" 888d88P"88bd8P  Y8b888
+# 888   888888  888  888888888  888888  88888888P Y88888888888  888888  88888888888888
+# Y88b. 888888  888  888888888  888Y88b 8888888P   Y8888888Y88b 888Y88b 888Y8b.    Y88b.
+#  "Y888888888  888  888888888  888 "Y88888888P     Y888888 "Y88888 "Y88888 "Y8888  "Y888
+#                                       888                             888
+#                                  Y8b d88P                        Y8b d88P
+#                                   "Y88P"                          "Y88P"
+
+class TimingWidget(kcgw.KCGWidgets):
+    """
+    This is the container that holds the tab widget which contains the timing widgets for each board
+    """
+    def __init__(self, unique_id, parent=None):
+        super(TimingWidget, self).__init__()
+
+        self.id = unique_id
+        self.par = parent
+        self.setWindowTitle("Timing")
+
+        self.layout = QtGui.QHBoxLayout()
+        self.setLayout(self.layout)
+        self.widgets = {i: TimingPart(i, self) for i in available_boards}  # has to set parent with self because
+                                            # otherwise the window does not get resized correctly upon enabling timescan
+
+        if available_boards.multi_board:
+            self.tabWidget = QtGui.QTabWidget()
+            self.layout.addWidget(self.tabWidget)
+
+            for id, widget in self.widgets.items():
+                self.tabWidget.addTab(widget, available_boards.get_board_name_from_id(id))
+        else:
+            self.single_board_widget = list(self.widgets.values())[0]
+            self.layout.addWidget(self.single_board_widget)
+
+    def adjustSizeForTimeScan(self):
+        """
+        Adjust the size of the widget to accomodate the time_scan part
+        :return:
+        """
+                # self.parentWindow = self.parent().parent().parent().parent()  # one up is stacked widget, second up is
+                #                     tab widget, third up is timingWidget fourh up is KCGWSubWindow (the actual window)
+        QtCore.QCoreApplication.processEvents()
+        if self.parent().windowState() & QtCore.Qt.WindowMaximized:
+            self.parent().setWindowState(QtCore.Qt.WindowMaximized)
+        else:
+            # self.parent().resize(self.minimumSizeHint().width() * 1.2, self.minimumSizeHint().height()*1.1)
+            self.parent().adjustSize()
+
+    def closeEvent(self, event):
+        global __widget_id__
+        __widget_id__ = None
+
+        for widget in list(self.widgets.values()):
+            widget.closeEvent(event)
+        del self.par.widgets[self.id]
+        super(TimingWidget, self).closeEvent(event)
+
+
+def addTimingWidget():
+    """
+    Add this widget to the gui.
+    This function will actually open the subwindow.
+    :return: -
+    """
+    global __widget_id__
+    if __widget_id__:
+        global_objects.get_global('area').widgets[__widget_id__].setFocus()
+    else:
+        nid = kcgw.idg.genid()
+        __widget_id__ = nid
+        w = TimingWidget(nid, global_objects.get_global('area'))
+        global_objects.get_global('area').newWidget(w, tr("Heading", "Timing"), nid, widget_type=4, minSize=True) #TODO: proper type
+
+kcgw.register_widget(QtGui.QIcon(config.icon_path(config.timingIcon)), tr("Heading", "Timing"), addTimingWidget, "Ctrl+T")