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