Browse Source

Reorganized Layout for Coarse seetings
in TimingWidget

Timo Dritschler 3 years ago
parent
commit
d3b325b299
3 changed files with 328 additions and 341 deletions
  1. 166 166
      KCG/kcg.py
  2. 161 174
      KCG/widgets/TimingWidget.py
  3. 1 1
      KCG/widgets/__init__.py

+ 166 - 166
KCG/kcg.py

@@ -1,166 +1,166 @@
-#!/usr/bin/python
-"""
-This is the main program for KCG
-It imports all modules and starts the Gui
-"""
-from PyQt4 import QtGui, QtCore
-import sys
-import os
-import argparse as ap
-import logging
-from logging import handlers
-from . import config
-
-# -------[ Register Logger here to enable logging before anything of this app is performed ]---------------
-logging.getLogger().setLevel(0)
-if not os.path.isdir(config.config_path()):
-    os.makedirs(config.config_path())
-fileLogHandler = handlers.RotatingFileHandler(config.config_path("kcg.log.full"), maxBytes=10**7, backupCount=5)
-fileLogHandler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s: %(message)s'))
-fileLogHandler.setLevel(0)
-logging.getLogger().addHandler(fileLogHandler)
-logging.addLevelName(logging.INFO-1, 'VINFO')
-logging.info("==========[Start Application]===========")
-try:
-    import subprocess
-    val = subprocess.check_output(["git", "describe", "--always"]).strip().decode()
-    val = str(val)
-    print('current commit '+ val)
-    if "fatal" not in val:
-        logging.info('Current Git Hash: ' + val)
-
-except Exception as e:
-    print(e)
-    pass
-
-import KCG.base.kcgwidget as kcgw
-import KCG.config as config
-from KCG.config import Configuration
-
-
-
-
-translator = QtCore.QTranslator()
-kcgw.translator = translator
-# kcgw.tr = translator.translate
-kcgw.tr = QtCore.QCoreApplication.translate
-
-config.install_path = os.path.dirname(config.__file__)
-
-
-try:  # Try to use Erax for exception logging
-    sys.path.append(os.path.join(os.path.expanduser('~'),"Documents","PythonProjects"))
-    from erax import Erax
-
-    exception_log_handler = Erax('https://psraspi.no-ip.biz/p/erax/insert/78e55a9524a191f7628f82a20bcaa167:kcg',
-                                 no_epl_errors=True, cert='/tmp/raspi.pem')
-    exception_log_handler.install()
-except ImportError:
-    pass
-
-
-def print_version(verbose=False):
-    """
-    Print the version of the current used KCG instance
-    :param verbose: print verbose?
-    """
-    # print "KCG - KAPTURE Control Gui"
-    # print "=" * 30
-    print("KCG")
-    with open(os.path.join(config.install_path,'VERSION'), 'r') as v:
-        print(v.read().strip())
-    if verbose:
-        print("=" * 30)
-        print("Using Python:")
-        print(sys.version)
-        print("=" * 30)
-        print("From: " + config.install_path)
-
-
-def inject_setting(section, setting, value, args):
-    """
-    Inject a setting from the command line
-    :param section: the section to inject to
-    :param setting: the setting to inject
-    :param value: the value of this setting
-    :param args: the argparse parsed instance
-    """
-    args.config += section + '->' + setting + '=' + str(value) + ';'
-
-
-def log_type(level):
-    """
-    Method to validate and cast the log level
-    :param level: the level to validate and cast
-    :return: a valid logging level
-    """
-    try:
-        return int(level)
-    except ValueError:
-        try:
-            return logging._checkLevel(level)
-        except ValueError:
-            raise ap.ArgumentTypeError("No valid log level.")
-
-
-def run():
-    """
-    Main Function, gets called when GUI is started
-    :return:
-    """
-    app = QtGui.QApplication(sys.argv)
-    app.installTranslator(translator)
-    app.processEvents()
-
-    """
-    pixmap = QtGui.QPixmap(config.icon_path('einstellungen.svg')).scaled(400, 400)
-    splash_screen = QtGui.QSplashScreen(pixmap)
-    splash_screen.setMask(pixmap.mask())
-    splash_screen.show()
-    splash_screen.update()
-    splash_screen.showMessage("Loading KCG", QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom, QtCore.Qt.red)
-    splash_screen.update()
-    app.processEvents()
-    """
-    parser = ap.ArgumentParser("KCG - KAPTURE Control Gui")
-    parser.add_argument('--config', type=str, default='', help='Override Configuration file settings.'
-                        'Format: "Section->setting=content;Section->setting2=content;Section2->setting3=content" etc.')
-    parser.add_argument('--version', action='store_true', help="Print Version and exit")
-    parser.add_argument('--vversion', action='store_true', help="Print Version verbose and exit")
-    parser.add_argument('--fpga-detection', action='store_true', help="If Present, use 'dev' detection mode (detect"
-                                                                      "boards by using /dev/fpga# files.)")
-    parser.add_argument('--log', type=log_type, default=config.logging.INFO, help="Set the log level")
-    parser.add_argument('--testing', action='store_true', default=False,
-                        help="start KCG in testing version. DO NOT USE THIS IN PRODUCTION.")
-    args = parser.parse_args()
-    if args.version or args.vversion:
-        print_version(args.vversion)
-        sys.exit()
-
-    kcgw.testing = args.testing
-
-    if args.fpga_detection:
-        inject_setting('Misc', 'board_detection_method', '"dev"', args)
-
-    # logger = logging.getLogger()
-    # logger.setLevel(args.log)
-    # logging.logger = logger
-    def vinfo(content):
-        '''log with level VINFO'''
-        logging.log(logging.getLevelName('VINFO'), content)
-    logging.vinfo = vinfo
-
-    conf = Configuration(args.config, log_level=args.log)
-    conf.setup()
-    while conf.error:
-        conf.doSetup()
-    if args.testing:
-        config.default_subdirectory_name = 't'
-        config.board_detection_method = 'dummy'
-
-    import KCG.base.kcg as kcg
-
-    gui = kcg.Gui()
-    # splash_screen.finish(gui)
-    gui.show()
-    sys.exit(app.exec_())
+#!/usr/bin/python
+"""
+This is the main program for KCG
+It imports all modules and starts the Gui
+"""
+from PyQt4 import QtGui, QtCore
+import sys
+import os
+import argparse as ap
+import logging
+from logging import handlers
+from . import config
+
+# -------[ Register Logger here to enable logging before anything of this app is performed ]---------------
+logging.getLogger().setLevel(0)
+if not os.path.isdir(config.config_path()):
+    os.makedirs(config.config_path())
+fileLogHandler = handlers.RotatingFileHandler(config.config_path("kcg.log.full"), maxBytes=10**7, backupCount=5)
+fileLogHandler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s: %(message)s'))
+fileLogHandler.setLevel(0)
+logging.getLogger().addHandler(fileLogHandler)
+logging.addLevelName(logging.INFO-1, 'VINFO')
+logging.info("==========[Start Application]===========")
+try:
+    import subprocess
+    val = subprocess.check_output(["git", "describe", "--always"]).strip().decode()
+    val = str(val)
+    print('current commit '+ val)
+    if "fatal" not in val:
+        logging.info('Current Git Hash: ' + val)
+
+except Exception as e:
+    print(e)
+    pass
+
+import KCG.base.kcgwidget as kcgw
+import KCG.config as config
+from KCG.config import Configuration
+
+
+
+
+translator = QtCore.QTranslator()
+kcgw.translator = translator
+# kcgw.tr = translator.translate
+kcgw.tr = QtCore.QCoreApplication.translate
+
+config.install_path = os.path.dirname(config.__file__)
+
+
+try:  # Try to use Erax for exception logging
+    sys.path.append(os.path.join(os.path.expanduser('~'),"Documents","PythonProjects"))
+    from erax import Erax
+
+    exception_log_handler = Erax('https://psraspi.no-ip.biz/p/erax/insert/78e55a9524a191f7628f82a20bcaa167:kcg',
+                                 no_epl_errors=True, cert='/tmp/raspi.pem')
+    exception_log_handler.install()
+except ImportError:
+    pass
+
+
+def print_version(verbose=False):
+    """
+    Print the version of the current used KCG instance
+    :param verbose: print verbose?
+    """
+    # print "KCG - KAPTURE Control Gui"
+    # print "=" * 30
+    print("KCG")
+    with open(os.path.join(config.install_path,'VERSION'), 'r') as v:
+        print(v.read().strip())
+    if verbose:
+        print("=" * 30)
+        print("Using Python:")
+        print(sys.version)
+        print("=" * 30)
+        print("From: " + config.install_path)
+
+
+def inject_setting(section, setting, value, args):
+    """
+    Inject a setting from the command line
+    :param section: the section to inject to
+    :param setting: the setting to inject
+    :param value: the value of this setting
+    :param args: the argparse parsed instance
+    """
+    args.config += section + '->' + setting + '=' + str(value) + ';'
+
+
+def log_type(level):
+    """
+    Method to validate and cast the log level
+    :param level: the level to validate and cast
+    :return: a valid logging level
+    """
+    try:
+        return int(level)
+    except ValueError:
+        try:
+            return logging._checkLevel(level)
+        except ValueError:
+            raise ap.ArgumentTypeError("No valid log level.")
+
+
+def run():
+    """
+    Main Function, gets called when GUI is started
+    :return:
+    """
+    app = QtGui.QApplication(sys.argv)
+    app.installTranslator(translator)
+    app.processEvents()
+
+    """
+    pixmap = QtGui.QPixmap(config.icon_path('einstellungen.svg')).scaled(400, 400)
+    splash_screen = QtGui.QSplashScreen(pixmap)
+    splash_screen.setMask(pixmap.mask())
+    splash_screen.show()
+    splash_screen.update()
+    splash_screen.showMessage("Loading KCG", QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom, QtCore.Qt.red)
+    splash_screen.update()
+    app.processEvents()
+    """
+    parser = ap.ArgumentParser("KCG - KAPTURE Control Gui")
+    parser.add_argument('--config', type=str, default='', help='Override Configuration file settings.'
+                        'Format: "Section->setting=content;Section->setting2=content;Section2->setting3=content" etc.')
+    parser.add_argument('--version', action='store_true', help="Print Version and exit")
+    parser.add_argument('--vversion', action='store_true', help="Print Version verbose and exit")
+    parser.add_argument('--fpga-detection', action='store_true', help="If Present, use 'dev' detection mode (detect"
+                                                                      "boards by using /dev/fpga# files.)")
+    parser.add_argument('--log', type=log_type, default=config.logging.INFO, help="Set the log level")
+    parser.add_argument('--testing', action='store_true', default=False,
+                        help="start KCG in testing version. DO NOT USE THIS IN PRODUCTION.")
+    args = parser.parse_args()
+    if args.version or args.vversion:
+        print_version(args.vversion)
+        sys.exit()
+
+    kcgw.testing = args.testing
+
+    if args.fpga_detection:
+        inject_setting('Misc', 'board_detection_method', '"dev"', args)
+
+    # logger = logging.getLogger()
+    # logger.setLevel(args.log)
+    # logging.logger = logger
+    def vinfo(content):
+        '''log with level VINFO'''
+        logging.log(logging.getLevelName('VINFO'), content)
+    logging.vinfo = vinfo
+
+    conf = Configuration(args.config, log_level=args.log)
+    conf.setup()
+    while conf.error:
+        conf.doSetup()
+    if args.testing:
+        config.default_subdirectory_name = 't'
+        config.board_detection_method = 'dummy'
+
+    import KCG.base.kcg as kcg
+
+    gui = kcg.Gui()
+    # splash_screen.finish(gui)
+    gui.show()
+    sys.exit(app.exec_())

+ 161 - 174
KCG/widgets/TimingWidget.py

@@ -60,11 +60,14 @@ class TimingPart(kcgw.KCGWidgets):
         self.parent = parent
         self.board_id = board_id
         self.board_config =  board.get_board_config(board_id)
-        self.layout = QtGui.QGridLayout()
+        self.coarseLayout = QtGui.QGridLayout()
+        self.fineLayout = QtGui.QGridLayout()
+        self.layout = QtGui.QVBoxLayout()
+        self.layout.addLayout(self.coarseLayout)
+        self.layout.addLayout(self.fineLayout)
         self.outerLayout = QtGui.QVBoxLayout()
         self.outerLayout.addLayout(self.layout)
         self.setLayout(self.outerLayout)
-        self.show_advanced = True        
 
 
         #  --------[ Create Labels and corresponding Fields ]---------
@@ -73,31 +76,23 @@ class TimingPart(kcgw.KCGWidgets):
             '''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.delayLabel = self.createLabel(tr("Label", "T/H Coarse Delays"))
+        self.thdelayLabel = self.createLabel(tr("Label", "FMC 1"))
 
-        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.thdelayLabel_2 = self.createLabel("FMC 2")
+        self.coarseLabel = self.createLabel(tr("Label", "330ps"))
+        self.coarseLabel.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
 
-        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"))
+        #Coarse delay settings for FMC2 might have to be replicated from FMC1, so we need a run the update of the FMC1 spinbox through a helper-function,
+        #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), "continuous_read_{}".format(board_id)],
                          [
                             #self.coarseInputFpga,
                             #self.coarseInputAdc,
@@ -105,17 +100,14 @@ class TimingPart(kcgw.KCGWidgets):
                          ]
                          )
 
-        #self.coarseInputAdc.setEnabled(False)
-        #self.coarseInputFpga.setEnabled(False)
+        self.expertSwitch = self.createCheckbox(tr("Label", "Expert Settings"), connect=self.toggleExpert)
 
         if self.board_config.is_KAPTURE2():
-
-            self.coarse2Label = self.createLabel(tr("Label", "25ps Coarse Delay"))
+            self.coarse2Label = self.createLabel(tr("Label", "25ps"))
+            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"))
-            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)], 
+            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,
@@ -123,23 +115,14 @@ class TimingPart(kcgw.KCGWidgets):
                          ]
                          )
 
-            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.linkTHSwitch = self.createCheckbox(tr("Label", "Link to FMC 1"), connect=self.toggleFMC2IndividualDelay)
+                self.linkTHSwitch.setCheckState(QtCore.Qt.Checked)
 
-                #self.coarse2Label = self.createLabel(tr("Label", "25ps 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.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)], 
+                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,
@@ -150,6 +133,23 @@ class TimingPart(kcgw.KCGWidgets):
                              ]
                              )
 
+
+            #Controls for Expert mode
+            self.labelFpgaDelay = self.createLabel("FPGA Delay")
+            self.labelADCDelay = self.createLabel("FMC 1 ADC Delays")
+            self.coarse330Adc  = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_adc", "coarse330Adc"))
+            self.coarse330Fpga = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_fpga", "coarse330Fpga"))
+            self.coarse25Adc  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_adc", "coarse25Adc"))
+            self.coarse25Fpga = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_fpga", "coarse25Fpga"))
+
+            if self.adc_number > 4:
+                self.labelADCDelay_2 = self.createLabel("FMC 2 ADC Delays")
+                self.coarse330Adc_2  = self.createSpinbox(0, self.board_config.get('delay_330_max'), connect=lambda: update_delay("delay_330_adc_2", "coarse330Adc_2"))
+                self.coarse25Adc_2  = self.createSpinbox(0, self.board_config.get('delay_25_max'), connect=lambda: update_delay("delay_25_adc_2", "coarse25Adc_2"))
+
+
+
+
         self.fineLabel = self.createLabel(tr("Label", "Fine Delay"))
 
         self.fineAdcInput = []
@@ -175,8 +175,8 @@ class TimingPart(kcgw.KCGWidgets):
 
         #---------[ End ]---------
 
-        
-        
+
+
 
         def setValueSilent(value, spinbox, adc):
             '''set values silent to not trigger signals'''
@@ -208,31 +208,25 @@ class TimingPart(kcgw.KCGWidgets):
             )
         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')
+        obs(self.coarse330Adc, 'delay_330_adc')
+        obs(self.coarse330Fpga, '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')
+            obs(self.coarse25Adc, 'delay_25_adc')
+            obs(self.coarse25Fpga, '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.coarse330Adc_2, 'delay_330_adc_2')
                 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.coarse25Adc_2, 'delay_25_adc_2')
 
-        #obs(self.adc1CoarseInput, 'adc_1_delay_individual')
 
         board.get_board_config(board_id).observe(
-                self.bunchShiftInput, 
+                self.bunchShiftInput,
                 setBunchShiftValuesSilent,
                 'bunch_shift'
                 )
@@ -250,97 +244,97 @@ class TimingPart(kcgw.KCGWidgets):
         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:            
+            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)
+        self.coarseLayout.addWidget(self.delayLabel, 0, 0)
+        self.coarseLayout.addWidget(self.thdelayLabel, 0, 1)
         if self.board_config.is_KAPTURE2():
-            self.layout.addWidget(self.adc1CoarseInputSwitch, 0, 8,1,2)
+            self.coarseLayout.addWidget(self.expertSwitch, 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)
+                self.coarseLayout.addWidget(self.thdelayLabel_2, 0, 2)
+
+        self.coarseLayout.addWidget(self.coarseLabel, 1, 0)
+        self.coarseLayout.addWidget(self.coarseInputTh, 1, 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)   
+            self.coarseLayout.addWidget(self.coarse2Label, 2, 0)
+            self.coarseLayout.addWidget(self.coarse2InputTh, 2, 1)
 
             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.coarseLayout.addWidget(self.coarseInputTh_2, 1, 2)
+                self.coarseLayout.addWidget(self.linkTHSwitch, 1, 3)
+                self.coarseLayout.addWidget(self.coarse2InputTh_2, 2, 2)
+
 
-                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) 
+            #Controls for Expert mode
+            self.coarseLayout.addWidget(self.labelFpgaDelay, 0, 7)
+            self.coarseLayout.addWidget(self.labelADCDelay, 0, 6)
+
+            self.coarseLayout.addWidget(self.coarse330Fpga, 1, 7)
+            self.coarseLayout.addWidget(self.coarse330Adc, 1, 6)
+
+            self.coarseLayout.addWidget(self.coarse25Fpga, 2, 7)
+            self.coarseLayout.addWidget(self.coarse25Adc, 2, 6)
+
+            if self.adc_number > 4:
+                self.coarseLayout.addWidget(self.labelADCDelay_2, 0, 5)
+                self.coarseLayout.addWidget(self.coarse330Adc_2, 1, 5)
+                self.coarseLayout.addWidget(self.coarse25Adc_2, 2, 5)
 
 
-        self.layout.addItem(QtGui.QSpacerItem(10, 15), 4, 1)
 
         # Leave some rows free for additional things (empty rows will not be shown)
+        self.fineLayout.addItem(QtGui.QSpacerItem(10, 15), 0, 1)
+        self.fineLayout.addItem(QtGui.QSpacerItem(10, 15), 1, 1)
+
+        ### FINE DELAYS ###
         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)
+            self.fineLayout.addWidget(self.createLabel("ADC "+str(i+1)), 2, i+1)
+        self.fineLayout.addWidget(self.fineLabel, 3, 0)
         for i, item in enumerate(self.fineAdcInput):
-            self.layout.addWidget(item, 6, i+1)
-        self.layout.addWidget(self.bunchShiftLabel, 7, 0)
+            self.fineLayout.addWidget(item, 3, i+1)
+        self.fineLayout.addWidget(self.bunchShiftLabel, 4, 0)
         for i, item in enumerate(self.bunchShiftInput):
-            self.layout.addWidget(item, 7, i+1)
-        
-        self.layout.addItem(QtGui.QSpacerItem(10, 15), 7, 1)
+            self.fineLayout.addWidget(item, 4, i+1)
+
+        self.fineLayout.addItem(QtGui.QSpacerItem(10, 15), 4, 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)
+        self.fineLayout.addWidget(line, 5, 0, 1, 0)
+        self.fineLayout.addItem(QtGui.QSpacerItem(10, 15), 6, 1)
+        self.fineLayout.addWidget(self.totalLabel, 7, 0)
         for i, item in enumerate(self.totalAdcBox):
-            self.layout.addWidget(item, 10, i+1)
+            self.fineLayout.addWidget(item, 7, i+1)
             item.setFocusPolicy(QtCore.Qt.ClickFocus)
-        self.layout.addWidget(self.createLabel('Calibrated (ps)'), 11, 0)
+        self.fineLayout.addWidget(self.createLabel('Calibrated (ps)'), 8, 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.fineLayout.addWidget(item, 8, i+1)
+        self.fineLayout.addItem(QtGui.QSpacerItem(10, 15), 8, 1)
+
 
         self.board_config.notify_all_observers()
-        self.toggleAdvanced()
+        self.toggleExpert()
+        self.toggleFMC2IndividualDelay()
         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: 
+                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);")
@@ -359,8 +353,8 @@ class TimingPart(kcgw.KCGWidgets):
             """
             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]))]  + 
+                    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
                                               ))
@@ -375,56 +369,53 @@ class TimingPart(kcgw.KCGWidgets):
                     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
+    def toggleExpert(self):
+        if self.expertSwitch.checkState():
+            self.labelFpgaDelay.setVisible(True)
+            self.coarse330Fpga.setVisible(True)
+            self.coarse25Fpga.setVisible(True)
+            self.labelADCDelay.setVisible(True)
+            self.coarse330Adc.setVisible(True)
+            self.coarse25Adc.setVisible(True)
+            if self.adc_number > 4:
+                self.labelADCDelay_2.setVisible(True)
+                self.coarse330Adc_2.setVisible(True)
+                self.coarse25Adc_2.setVisible(True)
         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):
+            self.labelFpgaDelay.setVisible(False)
+            self.coarse330Fpga.setVisible(False)
+            self.coarse25Fpga.setVisible(False)
+            self.labelADCDelay.setVisible(False)
+            self.coarse330Adc.setVisible(False)
+            self.coarse25Adc.setVisible(False)
+            if self.adc_number > 4:
+                self.labelADCDelay_2.setVisible(False)
+                self.coarse330Adc_2.setVisible(False)
+                self.coarse25Adc_2.setVisible(False)
+
+
+    def toggleFMC2IndividualDelay(self):
         """
-        Toggle to use an individual delay for adc1 or not
+        Toggle to use an individual delay for FMC2 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
+        self.coarseInputTh_2.setEnabled(not self.linkTHSwitch.checkState())
+
+        if self.linkTHSwitch.checkState():
+            self.coarseInputTh_2.setValue(self.coarseInputTh.value())
+
+
+    def linkFMCCoarseDelay(self, value):
+        """
+        Check if FMC2 is linked to FMC1 and replicate the value accordingly
+        :value: The value from the FMC1 SpinBox Update
+        :return: -
+        """
+
+        if self.linkTHSwitch.checkState():
+            self.coarseInputTh_2.setValue(value)
+
+        self.board_config.update("delay_330_th", value)
 
 
     def setValueSilent(self, element, value):
@@ -443,7 +434,7 @@ class TimingPart(kcgw.KCGWidgets):
         """
         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')
@@ -460,24 +451,20 @@ class TimingPart(kcgw.KCGWidgets):
 
 
         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')
+        self.board_config.unobserve(self.coarse330Adc, 'delay_330_adc')
+        self.board_config.unobserve(self.coarse330Fpga, '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')
+            self.board_config.unobserve(self.coarse25Adc, 'delay_25_adc')
+            self.board_config.unobserve(self.coarse25Fpga, '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.coarse330Adc_2, 'delay_330_adc_2')
 
                 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')
-        
+                self.board_config.unobserve(self.coarse25Adc_2, 'delay_25_adc_2')
+
 
         Elements.emptyGroup('timing_{}'.format(self.board_id))
         Elements.removeItem(None, self.fineAdcInput)
@@ -506,8 +493,8 @@ class TimingPart(kcgw.KCGWidgets):
                                             #self.coarse2InputFpga_2
                                           ]
                                     )
-        
-        
+
+
 
         super(TimingPart, self).closeEvent(event)
 
@@ -519,7 +506,7 @@ class TimingPart(kcgw.KCGWidgets):
             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)))
@@ -527,7 +514,7 @@ class TimingPart(kcgw.KCGWidgets):
             return
 
 
-    
+
     def on_bunch_shift_changed(self):
         """
         Handler that gets called when a bunch shift setting gets changed
@@ -538,14 +525,14 @@ class TimingPart(kcgw.KCGWidgets):
                 #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

+ 1 - 1
KCG/widgets/__init__.py

@@ -1 +1 @@
-__all__ = ['AcquireSettingsWidget', 'SingleReadWidget', 'TimingWidget', 'TimescanWidget', 'UpdateCalibrationWidget', 'EpicsWidget', 'CorrelationWidget']#, 'AdcWidget', 'TestingWidget']#, 'CudaWidget'] #, 'ExampleWidget']
+__all__ = ['AcquireSettingsWidget', 'SingleReadWidget', 'TimingWidget', 'TimescanWidget', 'UpdateCalibrationWidget', 'EpicsWidget', 'CorrelationWidget', 'HardwareTimeScanWidget', 'AdcWidget', 'TestingWidget']#, 'CudaWidget'] #, 'ExampleWidget']