board_config.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. """
  2. Configuration for each board
  3. """
  4. import ConfigParser
  5. import numpy as np
  6. import logging
  7. from PyQt4 import QtGui, QtCore
  8. from communication import *
  9. from .... import config as kcg_config
  10. class BoardConfiguration(QtGui.QWidget):
  11. callback_signal = QtCore.pyqtSignal(str, list)
  12. def __init__(self, identifier, config_file=None):
  13. super(BoardConfiguration, self).__init__()
  14. self.callback_signal.connect(self._notify_observers_receiver)
  15. self.identifier = identifier
  16. self._config = {}
  17. self._observers = {}
  18. self._observers_for_all = []
  19. self._set_defaults()
  20. self.set_default_observers()
  21. if config_file:
  22. self.load_config(config_file)
  23. def _set_defaults(self):
  24. self._config ={
  25. 'fpga_delay_max': 15,
  26. 'fpga_delay': 0,
  27. 'fpga_delay_factor': 150,
  28. 'chip_delay_max': 31,
  29. 'chip_1_delay': 4,
  30. 'chip_2_delay': 4,
  31. 'chip_3_delay': 4,
  32. 'chip_4_delay': 4,
  33. 'chip_delay_factor': 3,
  34. 'th_delay_max': 15,
  35. 'th_delay': 3,
  36. 'th_delay_factor': 150,
  37. 'adc_delay_max': 15,
  38. 'adc_1_delay': 4,
  39. 'adc_2_delay': 4,
  40. 'adc_3_delay': 4,
  41. 'adc_4_delay': 4,
  42. 'adc_delay_factor': 150,
  43. 'th_to_adc_cycles': 7,
  44. 'adc_1_delay_individual': -1,
  45. 'orbits_observe': 100,
  46. 'orbits_skip': 2,
  47. 'acquisition_count': 10,
  48. 'orbits_wait_time': 15,
  49. 'trigger_skip': 0,
  50. 'trigger_timeout': 12,
  51. 'trigger_method': 1,
  52. 'use_trigger': False,
  53. 'build_spectrograms': False,
  54. 'pilot_bunch': False,
  55. 'header': True if kcg_config.save_header is True else False
  56. }
  57. def set_default_observers(self):
  58. self.observe(None, self.update_header, 'header')
  59. self.observe(None, lambda x: pci.write(self.identifier, hex(x), '0x9020'), 'orbits_observe')
  60. self.observe(None, lambda x: pci.write(self.identifier, hex(x), '0x9028'), 'orbits_skip')
  61. def notify_all_observers(self):
  62. for key, value in self._config.items():
  63. self._notify_observers(key, value)
  64. # observers = self._observers.get(key, None)
  65. # if observers:
  66. # for (who, callback) in observers:
  67. # callback(self.get(key))
  68. def load_config(self, filename):
  69. if filename:
  70. config = ConfigParser.RawConfigParser()
  71. if not config.read(str(filename)):
  72. return False
  73. for key in self._config.keys():
  74. try:
  75. if type(self._config[key]) == int:
  76. self._config[key] = config.getint('Config', key)
  77. elif type(self._config[key]) == bool:
  78. self._config[key] = config.getboolean('Config', key)
  79. logging.vinfo("Read '%s' for '%s' from '%s'"%(str(self._config[key]), key, str(filename)))
  80. except ConfigParser.NoOptionError as e:
  81. pass
  82. except ConfigParser.NoSectionError as e:
  83. pass
  84. return True
  85. else:
  86. return False
  87. def save_config(self, filename):
  88. if filename:
  89. # with open(filename, 'w') as f:
  90. try:
  91. f = open(filename, 'w')
  92. cp = ConfigParser.RawConfigParser()
  93. cp.add_section('Config')
  94. for key in self._config.keys():
  95. cp.set('Config', key, self._config[key])
  96. f.write('#\n'
  97. '# KCG (KAPTURE Control Gui) Configuration file\n'
  98. '#\n'
  99. '# (c) Karlsruhe Institute of Technology, 2015\n'
  100. '# All rights reserved.\n'
  101. '#\n'
  102. '# Applicable Gui Version(s): 1.0 - 1.0.2\n'
  103. '#\n'
  104. '# Saved at: ' + time.asctime() + '\n'
  105. '#\n\n')
  106. cp.write(f)
  107. except (IOError, TypeError):
  108. return False
  109. return True
  110. else:
  111. return False
  112. def get(self, key):
  113. if not key in self._config:
  114. raise NoSuchKeyError(key+" is not registered in BoardConfiguration for board "+str(self.identifier))
  115. return self._config.get(key, None)
  116. def dump(self):
  117. s = ""
  118. for key in self._config.keys():
  119. s += key + ": " + str(self.get(key)) + ", "
  120. return s[:-1]
  121. def update(self, key, value):
  122. self._config[key] = value
  123. self._notify_observers(key, value)
  124. def updateSilent(self, key, value):
  125. self._config[key] = value
  126. def observe(self, who, callback, key):
  127. if key not in self._config.keys():
  128. raise ObserverError(str("Key '%s' is unknown." % key))
  129. if self._observers.get(key, None) is None:
  130. self._observers[key] = []
  131. self._observers[key].append([who, callback])
  132. def observe_all(self, callback):
  133. if callback not in self._observers_for_all:
  134. self._observers_for_all.append(callback)
  135. else:
  136. raise ObserverError("Observer already registered")
  137. def unobserve(self, who, key=None):
  138. if key is not None:
  139. observers = np.array(self._observers.get(key, None))
  140. if observers is None:
  141. return
  142. if who not in observers[:, 0]:
  143. return
  144. for i, _obs in enumerate(self._observers[key]):
  145. if _obs[0] is who:
  146. del self._observers[key][i]
  147. if not self._observers[key]:
  148. del self._observers[key]
  149. return
  150. for _key in self._observers.keys():
  151. for i, _obs in enumerate(self._observers[_key]):
  152. if _obs[0] is who:
  153. del self._observers[_key][i]
  154. if not self._observers[_key]:
  155. del self._observers[_key]
  156. def unobserve_all_observer(self, callback):
  157. if callback in self._observers_for_all:
  158. del self._observers_for_all[self._observers_for_all.index(callback)]
  159. def _notify_observers_receiver(self, key, value):
  160. observers = self._observers.get(str(key), None)
  161. value = value[0]
  162. if observers is None:
  163. return
  164. for (who, callback) in observers:
  165. callback(value)
  166. for cb in self._observers_for_all:
  167. cb(key, value)
  168. def _notify_observers(self, key, value):
  169. self.callback_signal.emit(key, [value])
  170. def make_uint(self, value, maximum, name=None):
  171. if value is None:
  172. raise ValueError(str("%s Value is invalid (None)" % name))
  173. val = None
  174. try:
  175. val = int(value)
  176. except ValueError:
  177. raise ValueError(str("%s Value is not a valid number" % name))
  178. if maximum is not None:
  179. if val > maximum:
  180. raise ValueError(str("%s Value is too large (>%i)" % (name, maximum)))
  181. if val < 0:
  182. raise ValueError(str("%s Values below 0 are not allowed" % name))
  183. return val
  184. def set_fpga_delay(self, value):
  185. time_factor = self.make_uint(value, self.get('fpga_delay_max'), 'FPGA_Delay')
  186. reg_value = "0x000501" + '{0:01x}'.format(time_factor) + "0"
  187. pci.write(self.identifier, reg_value, '0x9060')
  188. logging.vinfo("Set FPGA clock delay %i * %i --> %i picoseconds" % (time_factor, self.get('fpga_delay_factor'), time_factor*self.get('fpga_delay_factor')))
  189. self.update('fpga_delay', value)
  190. def set_chip_delay(self, adcs, values):
  191. if not adcs or not values:
  192. logging.vinfo("Nothing to do for chip delay.")
  193. return
  194. _adcs = []
  195. for adc in adcs:
  196. _adcs.append(self.make_uint(adc, 3, 'ADC_'))
  197. _values = []
  198. for value in values:
  199. _values.append(self.make_uint(value, self.get('chip_delay_max'), 'ADC_Value'))
  200. a_v = zip(_adcs, _values)
  201. factors = [None, None, None, None]
  202. for (adc, value) in a_v:
  203. factors[adc] = value
  204. reg_value = ''
  205. mask = ''
  206. # Chip Delays are stored as 'ADC_4 ADC_3 ADC_2 ADC_1' in the register.
  207. # Therefore, we need to traverse the factors array in reverse order
  208. for value in reversed(factors):
  209. if value is not None:
  210. reg_value += '{0:02x}'.format(value)
  211. mask += 'ff'
  212. else:
  213. reg_value += '00'
  214. mask += '00'
  215. pci.write(self.identifier, reg_value, '0x9080', hex_mask=mask)
  216. s = "Setting ADC Delays:"
  217. for (adc, value) in a_v:
  218. s += ' ADC_%i Fine Delay: %i,' % (adc, value)
  219. s = s[:-1] # cut away the last dangling ','
  220. logging.vinfo(s)
  221. for (adc, value) in a_v:
  222. s = 'chip_%i_delay'%(adc+1)
  223. self.update(s, value)
  224. def set_th_delay(self, value):
  225. time_factor = self.make_uint(value, self.get('th_delay_max'), 'TH_Delay')
  226. reg_value = "0x000501" + '{0:01x}'.format(time_factor) + "3"
  227. pci.write(self.identifier, reg_value, '0x9060')
  228. 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')))
  229. self.update('th_delay', value)
  230. def set_adc_delay(self, adc, value):
  231. if adc is None or value is None:
  232. logging.vinfo("Nothing to do for ADC delay.")
  233. return
  234. _adc = self.make_uint(adc, 3, 'ADC Number')
  235. _val = self.make_uint(value, self.get('adc_delay_max'), 'ADC Delay')
  236. reg_value = "0x000501" + '{0:01x}'.format(_val) + "%i" % (_adc+4)
  237. pci.write(self.identifier, reg_value, '0x9060')
  238. s = "Setting ADC_%i delay %i * %i --> %i picoseconds" % ((_adc+1), _val, self.get('adc_delay_factor'), _val*self.get('adc_delay_factor'))
  239. logging.vinfo(s)
  240. adc_s = 'adc_%i_delay'%(_adc+1)
  241. self.update(adc_s, _val)
  242. def set_delay(self, n, ignore_seperate_delay=False):
  243. def write_delay(value, channel):
  244. cmd = '00501' + '%01x' % value + str(channel)
  245. pci.write(self.identifier, cmd, reg='0x9060')
  246. time.sleep(0.005)
  247. logging.vinfo("Setting T/H Delay: " + str(n))
  248. write_delay(n, 3)
  249. self.update('th_delay', n)
  250. delay = n + self.get('th_to_adc_cycles')
  251. if delay > self.get('adc_delay_max'):
  252. delay -= self.get('adc_delay_max') + 1
  253. write_delay(delay, 5)
  254. self.update('adc_2_delay', delay)
  255. write_delay(delay, 6)
  256. self.update('adc_3_delay', delay)
  257. write_delay(delay, 7)
  258. self.update('adc_4_delay', delay)
  259. #ADC 1 might have an individual delay
  260. if self.get('adc_1_delay_individual') > 0:
  261. try:
  262. delay = n + self.make_uint(self.get('adc_1_delay_individual'), 16, 'ADC 1 individual delay')
  263. logging.vinfo("Setting ADC1 individual delay to " + str(delay))
  264. except ValueError:
  265. logging.vinfo(r"'adc_1_delay_individual' not set or inactive. Using default.")
  266. if delay > self.get('adc_delay_max'):
  267. delay -= self.get('adc_delay_max') + 1
  268. write_delay(delay, 4)
  269. self.update('adc_1_delay', delay)
  270. def update_header(self, state):
  271. """
  272. Set the flag to write Header to files when acquiring.
  273. :param state: True to enabling header and False to disable
  274. :return: -
  275. """
  276. try:
  277. control = pci.read(self.identifier, 1, '0x9040')[0]
  278. control_bits = '{0:032b}'.format(int(control, 16))
  279. if state:
  280. control_bits = control_bits[:3] + '1' + control_bits[4:]
  281. else:
  282. control_bits = control_bits[:3] + '0' + control_bits[4:]
  283. dec_val_bits = int(control_bits, 2)
  284. pci.write(self.identifier, hex(dec_val_bits), '0x9040')
  285. except BoardError as e:
  286. reason = str(e) if str(e) != '' else "Unknown"
  287. logging.error("Error in Board Communication, was unable to write value to board "+reason)
  288. def read_from_board(self):
  289. try:
  290. settings = ['chip_1_delay','chip_2_delay','chip_3_delay','chip_4_delay']
  291. # --[ read fine/chip delays ]
  292. val = pci.read(self.identifier, reg='9080')[0]
  293. # --[ set chip_1_delay ]--
  294. self.update('chip_1_delay', int(val[6:8], 16))
  295. # --[ set chip_2_delay ]--
  296. self.update('chip_2_delay', int(val[4:6], 16))
  297. # --[ set chip_3_delay ]--
  298. self.update('chip_3_delay', int(val[2:4], 16))
  299. # --[ set chip_4_delay ]--
  300. self.update('chip_4_delay', int(val[0:2], 16))
  301. # --[ read and set th delay ]--
  302. val = pci.read(self.identifier, reg='90a0')[0]
  303. self.update('th_delay', int(val, 16))
  304. # --[ check for seperate adc1 delay ]--
  305. val = pci.read(self.identifier, reg='9088')[0]
  306. if int(val, 16) != self.get('th_delay') + self.get('adc_1_delay_individual'):
  307. self.update('adc_1_delay_individual', int(val, 16)-self.get('th_delay'))
  308. else:
  309. self.update('adc_1_delay_individual', -1)
  310. # --[ read and set number of orbits to acquire ]--
  311. val = pci.read(self.identifier, reg='9020')[0]
  312. self.update('orbits_observe', int(val, 16))
  313. # --[ read and set number of orbits to skip ]--
  314. val = pci.read(self.identifier, reg='9028')[0]
  315. self.update('orbits_skip', int(val, 16))
  316. # --[ read and update header ]--
  317. control = pci.read(self.identifier, 1, '0x9040')[0]
  318. control_bits = '{0:032b}'.format(int(control, 16))
  319. if control_bits[3] == '1':
  320. self.update('header', True)
  321. else:
  322. self.update('header', False)
  323. except IndexError:
  324. error(0x002, "Could not Read data from Board. Pci returned wrong amount of data.")