123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- """
- Configuration for each board
- """
- import ConfigParser
- import numpy as np
- import logging
- from PyQt4 import QtGui, QtCore
- from communication import *
- from .... import config as kcg_config
- class BoardConfiguration(QtGui.QWidget):
- callback_signal = QtCore.pyqtSignal(str, list)
- def __init__(self, identifier, config_file=None):
- super(BoardConfiguration, self).__init__()
- self.callback_signal.connect(self._notify_observers_receiver)
- self.identifier = identifier
- self._config = {}
- self._observers = {}
- self._observers_for_all = []
- self._set_defaults()
- self.set_default_observers()
- if config_file:
- self.load_config(config_file)
- def _set_defaults(self):
- self._config ={
- 'fpga_delay_max': 15,
- 'fpga_delay': 0,
- 'fpga_delay_factor': 150,
- 'chip_delay_max': 31,
- 'chip_1_delay': 4,
- 'chip_2_delay': 4,
- 'chip_3_delay': 4,
- 'chip_4_delay': 4,
- 'chip_delay_factor': 3,
- 'th_delay_max': 15,
- 'th_delay': 3,
- 'th_delay_factor': 150,
- 'adc_delay_max': 15,
- 'adc_1_delay': 4,
- 'adc_2_delay': 4,
- 'adc_3_delay': 4,
- 'adc_4_delay': 4,
- 'adc_delay_factor': 150,
- 'th_to_adc_cycles': 7,
- 'adc_1_delay_individual': -1,
- 'orbits_observe': 100,
- 'orbits_skip': 2,
- 'acquisition_count': 10,
- 'orbits_wait_time': 15,
- 'trigger_skip': 0,
- 'trigger_timeout': 12,
- 'trigger_method': 1,
- 'use_trigger': False,
- 'build_spectrograms': False,
- 'pilot_bunch': False,
- 'header': True if kcg_config.save_header is True else False
- }
- def set_default_observers(self):
- self.observe(None, self.update_header, 'header')
- self.observe(None, lambda x: pci.write(self.identifier, hex(x), '0x9020'), 'orbits_observe')
- self.observe(None, lambda x: pci.write(self.identifier, hex(x), '0x9028'), 'orbits_skip')
- def notify_all_observers(self):
- for key, value in self._config.items():
- self._notify_observers(key, value)
- # observers = self._observers.get(key, None)
- # if observers:
- # for (who, callback) in observers:
- # callback(self.get(key))
- def load_config(self, filename):
- if filename:
- config = ConfigParser.RawConfigParser()
- if not config.read(str(filename)):
- return False
- for key in self._config.keys():
- try:
- if type(self._config[key]) == int:
- self._config[key] = config.getint('Config', key)
- elif type(self._config[key]) == bool:
- self._config[key] = config.getboolean('Config', key)
- logging.vinfo("Read '%s' for '%s' from '%s'"%(str(self._config[key]), key, str(filename)))
- except ConfigParser.NoOptionError as e:
- pass
- except ConfigParser.NoSectionError as e:
- pass
- return True
- else:
- return False
- def save_config(self, filename):
- if filename:
- # with open(filename, 'w') as f:
- try:
- f = open(filename, 'w')
- cp = ConfigParser.RawConfigParser()
- cp.add_section('Config')
- for key in self._config.keys():
- cp.set('Config', key, self._config[key])
- f.write('#\n'
- '# KCG (KAPTURE Control Gui) Configuration file\n'
- '#\n'
- '# (c) Karlsruhe Institute of Technology, 2015\n'
- '# All rights reserved.\n'
- '#\n'
- '# Applicable Gui Version(s): 1.0 - 1.0.2\n'
- '#\n'
- '# Saved at: ' + time.asctime() + '\n'
- '#\n\n')
- cp.write(f)
- except (IOError, TypeError):
- return False
- return True
- else:
- return False
- def get(self, key):
- if not key in self._config:
- raise NoSuchKeyError(key+" is not registered in BoardConfiguration for board "+str(self.identifier))
- return self._config.get(key, None)
- def dump(self):
- s = ""
- for key in self._config.keys():
- s += key + ": " + str(self.get(key)) + ", "
- return s[:-1]
- def update(self, key, value):
- self._config[key] = value
- self._notify_observers(key, value)
- def updateSilent(self, key, value):
- self._config[key] = value
- def observe(self, who, callback, key):
- if key not in self._config.keys():
- raise ObserverError(str("Key '%s' is unknown." % key))
- if self._observers.get(key, None) is None:
- self._observers[key] = []
- self._observers[key].append([who, callback])
- def observe_all(self, callback):
- if callback not in self._observers_for_all:
- self._observers_for_all.append(callback)
- else:
- raise ObserverError("Observer already registered")
- def unobserve(self, who, key=None):
- if key is not None:
- observers = np.array(self._observers.get(key, None))
- if observers is None:
- return
- if who not in observers[:, 0]:
- return
- for i, _obs in enumerate(self._observers[key]):
- if _obs[0] is who:
- del self._observers[key][i]
- if not self._observers[key]:
- del self._observers[key]
- return
- for _key in self._observers.keys():
- for i, _obs in enumerate(self._observers[_key]):
- if _obs[0] is who:
- del self._observers[_key][i]
- if not self._observers[_key]:
- del self._observers[_key]
- def unobserve_all_observer(self, callback):
- if callback in self._observers_for_all:
- del self._observers_for_all[self._observers_for_all.index(callback)]
- def _notify_observers_receiver(self, key, value):
- observers = self._observers.get(str(key), None)
- value = value[0]
- if observers is None:
- return
- for (who, callback) in observers:
- callback(value)
- for cb in self._observers_for_all:
- cb(key, value)
- def _notify_observers(self, key, value):
- self.callback_signal.emit(key, [value])
- def make_uint(self, value, maximum, name=None):
- if value is None:
- raise ValueError(str("%s Value is invalid (None)" % name))
- val = None
- try:
- val = int(value)
- except ValueError:
- raise ValueError(str("%s Value is not a valid number" % name))
- if maximum is not None:
- if val > maximum:
- raise ValueError(str("%s Value is too large (>%i)" % (name, maximum)))
- if val < 0:
- raise ValueError(str("%s Values below 0 are not allowed" % name))
- return val
- def set_fpga_delay(self, value):
- time_factor = self.make_uint(value, self.get('fpga_delay_max'), 'FPGA_Delay')
- reg_value = "0x000501" + '{0:01x}'.format(time_factor) + "0"
- pci.write(self.identifier, reg_value, '0x9060')
- logging.vinfo("Set FPGA clock delay %i * %i --> %i picoseconds" % (time_factor, self.get('fpga_delay_factor'), time_factor*self.get('fpga_delay_factor')))
- self.update('fpga_delay', value)
- def set_chip_delay(self, adcs, values):
- if not adcs or not values:
- logging.vinfo("Nothing to do for chip delay.")
- return
- _adcs = []
- for adc in adcs:
- _adcs.append(self.make_uint(adc, 3, 'ADC_'))
- _values = []
- for value in values:
- _values.append(self.make_uint(value, self.get('chip_delay_max'), 'ADC_Value'))
- a_v = zip(_adcs, _values)
- factors = [None, None, None, None]
- for (adc, value) in a_v:
- factors[adc] = value
- reg_value = ''
- mask = ''
- # Chip Delays are stored as 'ADC_4 ADC_3 ADC_2 ADC_1' in the register.
- # Therefore, we need to traverse the factors array in reverse order
- for value in reversed(factors):
- if value is not None:
- reg_value += '{0:02x}'.format(value)
- mask += 'ff'
- else:
- reg_value += '00'
- mask += '00'
- pci.write(self.identifier, reg_value, '0x9080', hex_mask=mask)
- s = "Setting ADC Delays:"
- for (adc, value) in a_v:
- s += ' ADC_%i Fine Delay: %i,' % (adc, value)
- s = s[:-1] # cut away the last dangling ','
- logging.vinfo(s)
- for (adc, value) in a_v:
- s = 'chip_%i_delay'%(adc+1)
- self.update(s, value)
- def set_th_delay(self, value):
- time_factor = self.make_uint(value, self.get('th_delay_max'), 'TH_Delay')
- reg_value = "0x000501" + '{0:01x}'.format(time_factor) + "3"
- pci.write(self.identifier, reg_value, '0x9060')
- logging.vinfo("Set T/H Signal delay %i * %i --> %i picoseconds" % (time_factor, self.get('th_delay_factor'), time_factor*self.get('th_delay_factor')))
- self.update('th_delay', value)
- def set_adc_delay(self, adc, value):
- if adc is None or value is None:
- logging.vinfo("Nothing to do for ADC delay.")
- return
- _adc = self.make_uint(adc, 3, 'ADC Number')
- _val = self.make_uint(value, self.get('adc_delay_max'), 'ADC Delay')
- reg_value = "0x000501" + '{0:01x}'.format(_val) + "%i" % (_adc+4)
- pci.write(self.identifier, reg_value, '0x9060')
- s = "Setting ADC_%i delay %i * %i --> %i picoseconds" % ((_adc+1), _val, self.get('adc_delay_factor'), _val*self.get('adc_delay_factor'))
- logging.vinfo(s)
- adc_s = 'adc_%i_delay'%(_adc+1)
- self.update(adc_s, _val)
- def set_delay(self, n, ignore_seperate_delay=False):
- def write_delay(value, channel):
- cmd = '00501' + '%01x' % value + str(channel)
- pci.write(self.identifier, cmd, reg='0x9060')
- time.sleep(0.005)
- logging.vinfo("Setting T/H Delay: " + str(n))
- write_delay(n, 3)
- self.update('th_delay', n)
- delay = n + self.get('th_to_adc_cycles')
- if delay > self.get('adc_delay_max'):
- delay -= self.get('adc_delay_max') + 1
- write_delay(delay, 5)
- self.update('adc_2_delay', delay)
- write_delay(delay, 6)
- self.update('adc_3_delay', delay)
- write_delay(delay, 7)
- self.update('adc_4_delay', delay)
- #ADC 1 might have an individual delay
- if self.get('adc_1_delay_individual') > 0:
- try:
- delay = n + self.make_uint(self.get('adc_1_delay_individual'), 16, 'ADC 1 individual delay')
- logging.vinfo("Setting ADC1 individual delay to " + str(delay))
- except ValueError:
- logging.vinfo(r"'adc_1_delay_individual' not set or inactive. Using default.")
- if delay > self.get('adc_delay_max'):
- delay -= self.get('adc_delay_max') + 1
- write_delay(delay, 4)
- self.update('adc_1_delay', delay)
- def update_header(self, state):
- """
- Set the flag to write Header to files when acquiring.
- :param state: True to enabling header and False to disable
- :return: -
- """
- try:
- control = pci.read(self.identifier, 1, '0x9040')[0]
- control_bits = '{0:032b}'.format(int(control, 16))
- if state:
- control_bits = control_bits[:3] + '1' + control_bits[4:]
- else:
- control_bits = control_bits[:3] + '0' + control_bits[4:]
- dec_val_bits = int(control_bits, 2)
- pci.write(self.identifier, hex(dec_val_bits), '0x9040')
- except BoardError as e:
- reason = str(e) if str(e) != '' else "Unknown"
- logging.error("Error in Board Communication, was unable to write value to board "+reason)
- def read_from_board(self):
- try:
- settings = ['chip_1_delay','chip_2_delay','chip_3_delay','chip_4_delay']
- # --[ read fine/chip delays ]
- val = pci.read(self.identifier, reg='9080')[0]
- # --[ set chip_1_delay ]--
- self.update('chip_1_delay', int(val[6:8], 16))
- # --[ set chip_2_delay ]--
- self.update('chip_2_delay', int(val[4:6], 16))
- # --[ set chip_3_delay ]--
- self.update('chip_3_delay', int(val[2:4], 16))
- # --[ set chip_4_delay ]--
- self.update('chip_4_delay', int(val[0:2], 16))
- # --[ read and set th delay ]--
- val = pci.read(self.identifier, reg='90a0')[0]
- self.update('th_delay', int(val, 16))
- # --[ check for seperate adc1 delay ]--
- val = pci.read(self.identifier, reg='9088')[0]
- if int(val, 16) != self.get('th_delay') + self.get('adc_1_delay_individual'):
- self.update('adc_1_delay_individual', int(val, 16)-self.get('th_delay'))
- else:
- self.update('adc_1_delay_individual', -1)
- # --[ read and set number of orbits to acquire ]--
- val = pci.read(self.identifier, reg='9020')[0]
- self.update('orbits_observe', int(val, 16))
- # --[ read and set number of orbits to skip ]--
- val = pci.read(self.identifier, reg='9028')[0]
- self.update('orbits_skip', int(val, 16))
- # --[ read and update header ]--
- control = pci.read(self.identifier, 1, '0x9040')[0]
- control_bits = '{0:032b}'.format(int(control, 16))
- if control_bits[3] == '1':
- self.update('header', True)
- else:
- self.update('header', False)
- except IndexError:
- error(0x002, "Could not Read data from Board. Pci returned wrong amount of data.")
|