heb 86 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036
  1. #! python
  2. import sys
  3. import os
  4. import argparse
  5. import logging
  6. import time
  7. from PyQt4 import QtGui, QtCore
  8. from matplotlib.figure import Figure
  9. from matplotlib.backends.backend_qt4agg import (
  10. FigureCanvasQTAgg as FigureCanvas,
  11. NavigationToolbar2QTAgg as NavigationToolbar)
  12. from heb.board import write_pci
  13. import heb.io
  14. import heb.plot
  15. import heb.board
  16. import numpy as np
  17. from array import array as pArr
  18. import struct
  19. import matplotlib.cm as cm
  20. import matplotlib.colors as colors
  21. OPT_3D_MAP = "3D Map"
  22. OPT_TRAIN = "Train"
  23. OPT_COMBINED = "Combined"
  24. OPT_FFT = "Fourier transform"
  25. # OPT_RECONSTRUCTED = "Reconstructed"
  26. OPT_ADC_1 = "ADC 1"
  27. OPT_ADC_2 = "ADC 2"
  28. OPT_ADC_3 = "ADC 3"
  29. OPT_ADC_4 = "ADC 4"
  30. def enable_wait_cursor():
  31. QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))
  32. def disable_wait_cursor():
  33. QtGui.QApplication.restoreOverrideCursor()
  34. class Spinbox(QtGui.QSpinBox):
  35. def __init__(self, minimum, maximum, default):
  36. QtGui.QSpinBox.__init__(self)
  37. self.setMinimum(minimum)
  38. self.setMaximum(maximum)
  39. self.setValue(default)
  40. def setValueSilent(self, value):
  41. self.blockSignals(True)
  42. self.setValue(value)
  43. self.blockSignals(False)
  44. class GraphicalLED(QtGui.QWidget):
  45. def __init__(self, parent=None, colorRGB=(255, 0, 0), height=20, width=20):
  46. QtGui.QWidget.__init__(self, parent)
  47. self.width = width
  48. self.height = height
  49. self.color = QtGui.QColor(colorRGB[0], colorRGB[1], colorRGB[2])
  50. self.center = QtCore.QPoint(width, height)
  51. self.setMinimumSize(2 * width, 2 * height)
  52. self.setMaximumSize(2 * width, 2 * height)
  53. def paintEvent(self, event):
  54. paint = QtGui.QPainter()
  55. paint.begin(self)
  56. paint.setRenderHint(QtGui.QPainter.Antialiasing)
  57. # draw a grey 'socket' for the LED
  58. paint.setPen(QtGui.QColor(160, 160, 160))
  59. paint.setBrush(QtGui.QColor(180, 180, 180))
  60. paint.drawEllipse(self.center, self.width, self.height)
  61. # draw the body of the LED
  62. paint.setBrush(self.color)
  63. paint.drawEllipse(self.center, self.width*0.85, self.height*0.85)
  64. # Some versions of Qt4 differ in the way their QLinearGradients
  65. # work... But i don't want to remove the functionality :)
  66. if False:
  67. self.draw_light_reflex(paint)
  68. def draw_light_reflex(self, paint):
  69. # set up a light reflex ellipse on the LED
  70. paint.translate(self.center)
  71. paint.rotate(-45.0)
  72. paint.setPen(QtGui.QColor(255, 255, 255, 0))
  73. highlight_center = QtCore.QPoint(0, self.width*(-0.34))
  74. # light reflex is pure white and fades to transparent at top of LED
  75. gradient = QtGui.QLinearGradient(highlight_center*1.5, QtCore.QPoint(0, 0))
  76. gradient.setColorAt(0.0, QtGui.QColor(255, 255, 255, 120))
  77. gradient.setColorAt(1.0, QtGui.QColor(255, 255, 255, 0))
  78. # draw the light reflex using the gradient brush
  79. paint.setBrush(gradient)
  80. paint.drawEllipse(highlight_center, self.width*0.63, self.width*0.42)
  81. paint.end()
  82. def set_color(self, colorRGB=(255, 0, 0)):
  83. self.color = QtGui.QColor(colorRGB[0], colorRGB[1], colorRGB[2])
  84. self.update()
  85. class BitsDisplayTable(QtGui.QTableWidget):
  86. def __init__(self, value, parent=None, optimalSize=True):
  87. QtGui.QTableWidget.__init__(self, parent)
  88. self.numbers = str(value)
  89. if len(self.numbers) == 0:
  90. raise ValueError("Cant create a table for a value of length 0.")
  91. self.length = len(self.numbers)
  92. self.do_style()
  93. if optimalSize is True:
  94. self.do_optimal_size()
  95. def do_style(self):
  96. self.horizontalHeader().setDefaultSectionSize(35)
  97. self.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
  98. self.horizontalHeader().setVisible(True)
  99. self.verticalHeader().setDefaultSectionSize(17)
  100. self.verticalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
  101. self.verticalHeader().setVisible(False)
  102. self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
  103. self.setRowCount(1)
  104. self.setColumnCount(self.length)
  105. # If self.length would be 5, this line would generate ('4', '3',
  106. # '2', '1', '0')
  107. headers = tuple([str(i) for i in reversed(range(0, self.length))])
  108. self.setHorizontalHeaderLabels(headers)
  109. for i in range(len(self.numbers)):
  110. item = QtGui.QTableWidgetItem(self.numbers[i])
  111. item.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
  112. self.setItem(0, i, item)
  113. def width(self):
  114. width = 6
  115. if self.verticalHeader().isHidden() is False:
  116. width = self.verticalHeader().width() + 6
  117. for i in range(self.columnCount()):
  118. width = width + self.columnWidth(i)
  119. return width
  120. def height(self):
  121. height = 6
  122. if self.horizontalHeader().isHidden() is False:
  123. height = self.horizontalHeader().height() + 6
  124. for i in range(self.rowCount()):
  125. height = height + self.rowHeight(i)
  126. return height
  127. def do_optimal_size(self):
  128. size = QtCore.QSize(self.width(), self.height())
  129. self.setMaximumSize(size)
  130. self.setMinimumSize(size)
  131. def stretch_to_width(self, width_in):
  132. width = self.width()
  133. if width >= width_in:
  134. return
  135. factor = width_in/float(width)
  136. error = 0
  137. for i in range(self.length):
  138. current_cell_size = self.columnWidth(i)
  139. new_cell_size = int(current_cell_size * factor)
  140. error += new_cell_size - (current_cell_size * factor)
  141. if (error >= 1.0) or (error <= -1.0):
  142. new_cell_size -= int(error)
  143. error -= int(error)
  144. self.horizontalHeader().resizeSection(i, new_cell_size)
  145. self.do_optimal_size()
  146. def set_item(self, row, col, value):
  147. item = QtGui.QTableWidgetItem(str(value))
  148. item.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
  149. width = self._get_table_item_width(QtGui.QTableWidgetItem(value))
  150. if width > self.columnWidth(col):
  151. self.horizontalHeader().resizeSection(col, width)
  152. self.setItem(row, col, item)
  153. def set_numbers(self, value):
  154. new_numbers = str(value)
  155. if len(new_numbers) == 0:
  156. raise ValueError("Cant create a table for a value of length 0.")
  157. if len(new_numbers) != len(self.numbers):
  158. raise ValueError("New Values for table don't match size."
  159. "Expected size %i but got %i" % (len(self.numbers), len(new_numbers)))
  160. self.numbers = new_numbers
  161. for i in range(len(self.numbers)):
  162. item = self.item(0, i)
  163. item.setText(self.numbers[i])
  164. def set_label(self, start, end, label, color=None):
  165. if (start < 0) or (end > self.columnCount()-1) or (start > end):
  166. raise ValueError("Invalid Start and End positions for Label: %s" % label)
  167. if self.rowCount() < 2:
  168. self.insertRow(1)
  169. for i in range(self.length):
  170. self.setItem(1, i, QtGui.QTableWidgetItem(''))
  171. span = (end-start)+1
  172. if span > 1:
  173. self.setSpan(1, start, 1, span)
  174. item = QtGui.QTableWidgetItem(label)
  175. item.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
  176. if color:
  177. item.setBackground(color)
  178. self.setItem(1, start, item)
  179. # Check if the label is larger then then cells it spans and resize the cells
  180. # accordingly, if the label ends up larger then the cells.
  181. label_width = self._get_table_item_width(QtGui.QTableWidgetItem(label))
  182. cells_width = 0
  183. for i in range(start, end+1):
  184. cells_width = cells_width + self.columnWidth(i)
  185. if label_width > cells_width:
  186. new_cell_size = label_width/span
  187. for i in range(start, end+1):
  188. self.horizontalHeader().resizeSection(i, new_cell_size)
  189. self.do_optimal_size()
  190. def grey_out_column(self, column):
  191. if (column < 0) or (column > self.length):
  192. raise ValueError("Supplied column is out of range for this table")
  193. for i in range(self.rowCount()):
  194. self.item(i, column).setForeground(QtGui.QColor(120, 120, 120))
  195. self.item(i, column).setBackground(QtGui.QColor(200, 200, 200))
  196. def undo_grey_out_column(self, column):
  197. if (column < 0) or (column > self.length):
  198. raise ValueError("Supplied column is out of range for this table")
  199. for i in range(self.rowCount()):
  200. self.item(i, column).setForeground(QtGui.QColor(0, 0, 0))
  201. self.item(i, column).setBackground(QtGui.QColor(255, 255, 255))
  202. # Create a table just to insert our item and show how large its width ends up...
  203. # We have to use this stupid workaround since QTableWidgetItem has no width() property...
  204. def _get_table_item_width(self, item):
  205. table = QtGui.QTableWidget()
  206. table.horizontalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)
  207. table.setRowCount(1)
  208. table.setColumnCount(1)
  209. table.setItem(0, 0, item)
  210. width = table.columnWidth(0)
  211. table.deleteLater()
  212. return width
  213. class BitsEditTable(BitsDisplayTable):
  214. def __init__(self, value, parent=None, optimalSize=True):
  215. BitsDisplayTable.__init__(self, value, parent, optimalSize)
  216. self.checkboxes = []
  217. self.populate_checkboxes()
  218. self.verticalHeader().setDefaultSectionSize(35)
  219. self.do_optimal_size()
  220. def populate_checkboxes(self):
  221. for i in range(self.length):
  222. widget = QtGui.QWidget()
  223. self.checkboxes += [QtGui.QCheckBox()]
  224. layout = QtGui.QHBoxLayout(widget)
  225. layout.addWidget(self.checkboxes[i])
  226. layout.setAlignment(QtCore.Qt.AlignCenter)
  227. layout.setContentsMargins(0, 0, 0, 0)
  228. widget.setLayout(layout)
  229. self.setCellWidget(0, i, widget)
  230. def set_numbers(self, value):
  231. new_numbers = str(value)
  232. if len(new_numbers) == 0:
  233. raise ValueError("Cant create a table for a value of length 0.")
  234. if len(new_numbers) != len(self.numbers):
  235. raise ValueError("New Values for table dont match size."
  236. "Expected size %i but got %i" % (len(self.numbers), len(new_numbers)))
  237. self.numbers = new_numbers
  238. for i in range(len(self.numbers)):
  239. if self.numbers[i] == '1':
  240. self.checkboxes[i].setChecked(True)
  241. else:
  242. self.checkboxes[i].setChecked(False)
  243. def get_bits(self):
  244. bits = ''
  245. for i in range(self.length):
  246. if self.checkboxes[i].isChecked():
  247. bits += '1'
  248. else:
  249. bits += '0'
  250. return bits
  251. def get_bit(self, bit):
  252. if bit > self.length:
  253. return None
  254. return self.checkboxes[(self.length - bit) - 1].isChecked()
  255. def clear_all_bits(self):
  256. for i in range(self.length):
  257. self.checkboxes[i].setChecked(False)
  258. class PlotCanvas(FigureCanvas):
  259. def __init__(self, parent=None, width=5, height=4, dpi=100):
  260. self.figure = Figure(figsize=(width, height), dpi=dpi)
  261. FigureCanvas.__init__(self, self.figure)
  262. self.setParent(parent)
  263. FigureCanvas.setSizePolicy(self,
  264. QtGui.QSizePolicy.Expanding,
  265. QtGui.QSizePolicy.Expanding)
  266. FigureCanvas.updateGeometry(self)
  267. def update_figure(self, opt_widgets, data, frm, to, label=None):
  268. adcs = [w for w in (('ADC {}'.format(i), i) for i in range(1, 5))
  269. if opt_widgets[w[0]].isChecked()]
  270. def is_active(mode):
  271. return opt_widgets[mode].isChecked() and adcs
  272. if not data or frm == to:
  273. return
  274. self.figure.clear()
  275. self.figure.subplots_adjust(right=0.9)
  276. self.figure.suptitle(os.path.basename(data.filename))
  277. if is_active(OPT_3D_MAP):
  278. self.plot_heatmaps(adcs, data, frm, to)
  279. if is_active(OPT_TRAIN):
  280. args = {'label': label} if label else {}
  281. self.plot_train(adcs, data, frm, to, **args)
  282. if opt_widgets[OPT_COMBINED].isChecked() and adcs:
  283. self.plot_combined(adcs, data, frm, to, False)
  284. if is_active(OPT_FFT):
  285. self.plot_fft(adcs, data, frm, to)
  286. self.draw()
  287. def plot_heatmaps(self, adcs, data, frm, to):
  288. n_adcs = len(adcs)
  289. n_rows = 2 if n_adcs > 2 else 1
  290. n_cols = 2 if n_adcs > 1 else 1
  291. for i, (name, adc) in enumerate(adcs):
  292. axis = self.figure.add_subplot(n_rows, n_cols, i+1)
  293. axis.set_title(name)
  294. heatmap = data.heatmap(adc, frm, to)
  295. image = heb.plot.heatmap(heatmap, axis)
  296. bar_axis = self.figure.add_axes([0.85, 0.15, 0.05, 0.7])
  297. self.figure.subplots_adjust(right=0.8)
  298. self.figure.colorbar(image, cax=bar_axis)
  299. def plot_train(self, adcs, data, frm, to, **kwargs):
  300. n_adcs = len(adcs)
  301. n_rows = 2 if n_adcs > 2 else 1
  302. n_cols = 2 if n_adcs > 1 else 1
  303. for i, (name, adc) in enumerate(adcs):
  304. axis = self.figure.add_subplot(n_rows, n_cols, i+1)
  305. heb.plot.train(data, axis, adc, frm, to, **kwargs)
  306. def plot_combined(self, adcs, data, frm, to, show_reconstructed):
  307. axis = self.figure.add_subplot(111)
  308. heb.plot.combined(data, axis, adcs, frm, to, show_reconstructed)
  309. def plot_fft(self, adcs, data, frm, to):
  310. n_adcs = len(adcs)
  311. n_rows = 2 if n_adcs > 2 else 1
  312. n_cols = 2 if n_adcs > 1 else 1
  313. for i, (name, adc) in enumerate(adcs):
  314. axis = self.figure.add_subplot(n_rows, n_cols, i+1)
  315. axis.set_title(name)
  316. image = heb.plot.fft(data, axis, adc, frm, to) # <-- This needs to also pass the 'skipped' value!
  317. bar_axis = self.figure.add_axes([0.85, 0.15, 0.05, 0.7])
  318. self.figure.subplots_adjust(right=0.8)
  319. self.figure.colorbar(image, cax=bar_axis)
  320. class SimpleStatusDisplay(QtGui.QWidget):
  321. def __init__(self, parent=None):
  322. QtGui.QWidget.__init__(self, parent)
  323. self.do_layout()
  324. def do_layout(self):
  325. self.setWindowTitle("Board Status")
  326. status_displays = QtGui.QGridLayout()
  327. status_displays.addWidget(QtGui.QLabel("Board Status Readouts"))
  328. # First Label + LED Group
  329. self.data_flow_pipeline_led = GraphicalLED(self, (128, 128, 128), 10, 10)
  330. led_group_1_layout = QtGui.QGridLayout(self)
  331. label_group_1 = QtGui.QLabel("DataFlow Pipeline")
  332. label_group_1.setMinimumWidth(100)
  333. led_group_1_layout.addWidget(label_group_1, 0, 1)
  334. led_group_1_layout.addWidget(self.data_flow_pipeline_led, 0, 0)
  335. led_group_1_layout.setColumnStretch(2, 1)
  336. led_group_1_widget = QtGui.QWidget(self)
  337. led_group_1_widget.setLayout(led_group_1_layout)
  338. status_displays.addWidget(led_group_1_widget, 1, 0)
  339. # Second Label + LED Group
  340. self.master_ctrl_led = GraphicalLED(self, (128, 128, 128), 10, 10)
  341. led_group_2_layout = QtGui.QGridLayout(self)
  342. label_group_2 = QtGui.QLabel("Master Control")
  343. label_group_2.setMinimumWidth(100)
  344. led_group_2_layout.addWidget(label_group_2, 0, 1)
  345. led_group_2_layout.addWidget(self.master_ctrl_led, 0, 0)
  346. led_group_2_layout.setColumnStretch(2, 1)
  347. led_group_2_widget = QtGui.QWidget(self)
  348. led_group_2_widget.setLayout(led_group_2_layout)
  349. status_displays.addWidget(led_group_2_widget, 2, 0)
  350. # Third Label + LED Group
  351. self.data_check_led = GraphicalLED(self, (128, 128, 128), 10, 10)
  352. led_group_3_layout = QtGui.QGridLayout(self)
  353. label_group_3 = QtGui.QLabel("Data Check")
  354. label_group_3.setMinimumWidth(100)
  355. led_group_3_layout.addWidget(label_group_3, 0, 1)
  356. led_group_3_layout.addWidget(self.data_check_led, 0, 0)
  357. led_group_3_layout.setColumnStretch(2, 1)
  358. led_group_3_widget = QtGui.QWidget(self)
  359. led_group_3_widget.setLayout(led_group_3_layout)
  360. status_displays.addWidget(led_group_3_widget, 3, 0)
  361. # Fourth Label + LED Group
  362. self.pll_ld_led = GraphicalLED(self, (128, 128, 128), 10, 10)
  363. led_group_4_layout = QtGui.QGridLayout(self)
  364. label_group_4 = QtGui.QLabel("PLL_LD")
  365. label_group_4.setMinimumWidth(100)
  366. led_group_4_layout.addWidget(label_group_4, 0, 1)
  367. led_group_4_layout.addWidget(self.pll_ld_led, 0, 0)
  368. led_group_4_layout.setColumnStretch(2, 1)
  369. led_group_4_widget = QtGui.QWidget(self)
  370. led_group_4_widget.setLayout(led_group_4_layout)
  371. status_displays.addWidget(led_group_4_widget, 4, 0)
  372. status_displays.setColumnStretch(5, 2)
  373. status_displays.setRowStretch(5, 1)
  374. self.setLayout(status_displays)
  375. def update_status(self, registers):
  376. try:
  377. bits = []
  378. bits += ['{0:032b}'.format(registers[0])]
  379. bits += ['{0:032b}'.format(registers[1])]
  380. bits += ['{0:032b}'.format(registers[2])]
  381. s1 = heb.board.get_dec_from_bits(bits[0], 2, 0)
  382. if s1 == 0:
  383. # Pipeline in reset mode
  384. self.data_flow_pipeline_led.set_color((255, 255, 0))
  385. elif s1 == 1:
  386. # Pipeline is idle
  387. self.data_flow_pipeline_led.set_color((0, 190, 0))
  388. elif s1 == 6:
  389. # Pipeline in error state
  390. self.data_flow_pipeline_led.set_color((255, 0, 0))
  391. else:
  392. # Should not happen!
  393. self.data_flow_pipeline_led.set_color((128, 128, 128))
  394. s2 = heb.board.get_dec_from_bits(bits[0], 29, 26)
  395. if s2 == 0:
  396. # Master Control in reset mode
  397. self.master_ctrl_led.set_color((255, 255, 0))
  398. elif s2 == 1:
  399. # Master Control is idle
  400. self.master_ctrl_led.set_color((0, 190, 0))
  401. elif s2 == 8:
  402. # Master Control in error state
  403. self.master_ctrl_led.set_color((255, 0, 0))
  404. else:
  405. # Should not happen!
  406. self.master_ctrl_led.set_color((128, 128, 128))
  407. s3 = heb.board.get_dec_from_bits(bits[2], 15, 12)
  408. if s3 == 15:
  409. # Data Check Idle
  410. self.data_check_led.set_color((0, 190, 0))
  411. else:
  412. # Data Check Error
  413. self.data_check_led.set_color((255, 255, 0))
  414. s4 = int(bits[0][7])
  415. if s4 == 0:
  416. # PLL_LD not active
  417. self.pll_ld_led.set_color((255, 255, 0))
  418. elif s4 == 1:
  419. # PLL_LD is active
  420. self.pll_ld_led.set_color((0, 190, 0))
  421. except IndexError:
  422. QtGui.QMessageBox.critical(self, "Status Update Error", "Not enough registers give for status update.")
  423. return
  424. class AdvancedBoardInterface(QtGui.QWidget):
  425. def __init__(self, parent=None):
  426. QtGui.QWidget.__init__(self, parent)
  427. self.parent = parent
  428. self.do_layout()
  429. self.data_flow_pipeline_status = None
  430. def do_layout(self):
  431. table_grid = QtGui.QGridLayout()
  432. table_grid.addWidget(QtGui.QLabel("Status1 Register 0x9050 (Readonly)"), 0, 0)
  433. self.status1_table = BitsDisplayTable(32*'0', self)
  434. self.do_status1_table_layout(self.status1_table)
  435. table_grid.addWidget(self.status1_table, 1, 0)
  436. table_grid.addWidget(QtGui.QLabel("Status2 Register 0x9054 (Readonly)"), 2, 0)
  437. self.status2_table = BitsDisplayTable(32*'0', self)
  438. self.do_status2_table_layout(self.status2_table)
  439. table_grid.addWidget(self.status2_table, 3, 0)
  440. table_grid.addWidget(QtGui.QLabel("Status3 Register 0x9058 (Readonly)"), 4, 0)
  441. self.status3_table = BitsDisplayTable(32*'0', self)
  442. self.do_status3_table_layout(self.status3_table)
  443. table_grid.addWidget(self.status3_table, 5, 0)
  444. table_grid.addItem(QtGui.QSpacerItem(1, 20), 6, 0)
  445. table_grid.addWidget(QtGui.QLabel("Control Register 0x9040"), 7, 0)
  446. buttons_box = QtGui.QHBoxLayout()
  447. buttons_box.setAlignment(QtCore.Qt.AlignLeft)
  448. self.write_control_button = QtGui.QPushButton("Write Values to board")
  449. self.write_control_button.setMaximumWidth(200)
  450. buttons_box.addWidget(self.write_control_button)
  451. self.clear_control_button = QtGui.QPushButton("Clear Input")
  452. self.clear_control_button.setMaximumWidth(200)
  453. buttons_box.addWidget(self.clear_control_button)
  454. self.check_status_control_button = QtGui.QPushButton("Check Status")
  455. self.check_status_control_button.setMaximumWidth(200)
  456. buttons_box.addWidget(self.check_status_control_button)
  457. buttons_widget = QtGui.QWidget()
  458. buttons_widget.setLayout(buttons_box)
  459. table_grid.addWidget(buttons_widget, 8, 0)
  460. self.control_table = BitsEditTable(32*'0', self)
  461. self.do_control_table_layout(self.control_table)
  462. table_grid.addWidget(self.control_table, 9, 0)
  463. self.write_control_button.clicked.connect(self.send_control_to_board)
  464. self.clear_control_button.clicked.connect(self.control_table.clear_all_bits)
  465. self.check_status_control_button.clicked.connect(self.parent.do_status_readout)
  466. width1 = self.status1_table.width()
  467. width2 = self.status2_table.width()
  468. width3 = self.status3_table.width()
  469. width4 = self.control_table.width()
  470. max_width = max(width1, max(width2, max(width3, width4)))
  471. self.status1_table.stretch_to_width(max_width)
  472. self.status2_table.stretch_to_width(max_width)
  473. self.status3_table.stretch_to_width(max_width)
  474. self.control_table.stretch_to_width(max_width)
  475. self.setLayout(table_grid)
  476. def send_control_to_board(self):
  477. if not self.parent._check_for_no_continuous_read():
  478. logging.log("Cant write to board while continuous readout is active")
  479. return
  480. bits = self.control_table.get_bits()
  481. dec_val_bits = int(bits, 2)
  482. self.parent.text_area.write("Writing to board Register 0x9040: %s" % ('0x{0:08x}'.format(dec_val_bits)))
  483. try:
  484. heb.board.write_pci(hex(dec_val_bits), '0x9040')
  485. except heb.board.BoardError as e:
  486. QtGui.QMessageBox.critical(self, "Board communication",
  487. "Was unable to write value to board!\nReason: "+str(e))
  488. self.parent.do_status_readout()
  489. def do_status1_table_layout(self, table):
  490. # from right to left
  491. table.set_label(29, 31, "FSM_Data_Pipeline_Status", QtCore.Qt.green)
  492. table.grey_out_column(28)
  493. table.set_label(27, 27, "FULL", QtCore.Qt.green)
  494. table.set_label(26, 26, "EMPTY", QtCore.Qt.green)
  495. table.grey_out_column(25)
  496. table.grey_out_column(24)
  497. table.set_label(14, 23, "RD_data_Counts", QtCore.Qt.green)
  498. table.set_label(13, 13, "OVR_ADC", QtGui.QColor(210, 210, 0))
  499. table.grey_out_column(12)
  500. table.grey_out_column(11)
  501. table.grey_out_column(10)
  502. table.grey_out_column(9)
  503. table.grey_out_column(8)
  504. table.set_label(7, 7, "PLL_LD", QtGui.QColor(210, 210, 0))
  505. table.grey_out_column(6)
  506. table.set_label(2, 5, "Master Control", QtCore.Qt.green)
  507. table.grey_out_column(1)
  508. table.set_label(0, 0, "1")
  509. def do_status2_table_layout(self, table):
  510. #from right to left
  511. table.set_label(31, 31, "FIFO 128 255 empty", QtCore.Qt.green)
  512. table.set_label(30, 30, "FIFO 128 255 full", QtCore.Qt.green)
  513. table.grey_out_column(29)
  514. table.grey_out_column(28)
  515. table.set_label(17, 27, "wr data count 128 255", QtGui.QColor(210, 210, 0))
  516. table.grey_out_column(16)
  517. table.set_label(15, 15, "FIFO 255 64 empty", QtCore.Qt.green)
  518. table.set_label(14, 14, "FIFO 255 64 full", QtCore.Qt.green)
  519. table.grey_out_column(13)
  520. table.grey_out_column(12)
  521. table.set_label(2, 11, "rd data count 255 64", QtGui.QColor(210, 210, 0))
  522. table.grey_out_column(1)
  523. table.grey_out_column(0)
  524. def do_status3_table_layout(self, table):
  525. #from right to left
  526. table.set_label(29, 31, "FSM_ARBITER_DDR3", QtCore.Qt.green)
  527. table.grey_out_column(28)
  528. table.set_label(25, 27, "FSM_WR_DDR3", QtCore.Qt.green)
  529. table.grey_out_column(24)
  530. table.set_label(21, 23, "FSM_R_DDR3", QtCore.Qt.green)
  531. table.grey_out_column(20)
  532. table.set_label(16, 19, "BC_ERROR", QtGui.QColor(210, 210, 0))
  533. table.set_label(1, 15, "Number of wrong BC", QtGui.QColor(255, 255, 0))
  534. table.grey_out_column(0)
  535. def do_control_table_layout(self, table):
  536. #from right to left
  537. table.set_label(31, 31, "reset", QtGui.QColor(0, 255, 255))
  538. table.grey_out_column(30)
  539. table.grey_out_column(29)
  540. table.grey_out_column(28)
  541. table.set_label(27, 27, "ADC_1(A+D)", QtGui.QColor(0, 255, 255))
  542. table.set_label(26, 26, "ADC_2(A+D)2", QtGui.QColor(0, 255, 255))
  543. table.set_label(25, 25, "T/H_1", QtGui.QColor(210, 210, 0))
  544. table.set_label(24, 24, "T/H_2", QtGui.QColor(210, 210, 0))
  545. table.set_label(23, 23, "T/H_3", QtGui.QColor(210, 210, 0))
  546. table.set_label(22, 22, "T/H_4", QtGui.QColor(210, 210, 0))
  547. table.set_label(21, 21, "EN_data_Trans", QtCore.Qt.yellow)
  548. table.set_label(20, 20, "EN_readout", QtCore.Qt.yellow)
  549. table.set_label(18, 19, "ADC_1", QtCore.Qt.yellow)
  550. table.set_label(16, 17, "ADC_2", QtCore.Qt.yellow)
  551. table.set_label(14, 15, "ADC_3", QtCore.Qt.yellow)
  552. table.set_label(12, 13, "ADC_4", QtCore.Qt.yellow)
  553. table.grey_out_column(11)
  554. table.grey_out_column(10)
  555. table.grey_out_column(9)
  556. table.grey_out_column(8)
  557. table.grey_out_column(7)
  558. table.grey_out_column(6)
  559. table.grey_out_column(5)
  560. table.grey_out_column(4)
  561. table.set_label(3, 3, "Header", QtCore.Qt.green)
  562. table.grey_out_column(2)
  563. table.set_label(1, 1, "Pilot Bunch by FPGA", QtGui.QColor(0, 255, 255))
  564. table.set_label(0, 0, "FPGA Temp monitor Reset", QtGui.QColor(0, 255, 255))
  565. def update_status(self, registers):
  566. try:
  567. self.status1_table.set_numbers('{0:032b}'.format(registers[0]))
  568. self.status2_table.set_numbers('{0:032b}'.format(registers[1]))
  569. self.status3_table.set_numbers('{0:032b}'.format(registers[2]))
  570. except:
  571. return
  572. class PopupDialog(QtGui.QDialog):
  573. def __init__(self, text, parent=None):
  574. QtGui.QDialog.__init__(self, parent)
  575. self.text = text
  576. self.setWindowTitle("User action required")
  577. self.do_layout()
  578. self.return_value = False
  579. def do_layout(self):
  580. size = QtCore.QSize(200, 200)
  581. #self.setMaximumSize(size)
  582. self.setMinimumSize(size)
  583. box = QtGui.QVBoxLayout()
  584. self.text_label = QtGui.QLabel(self.text)
  585. self.text_label.setAlignment(QtCore.Qt.AlignCenter)
  586. box.addWidget(self.text_label)
  587. self.okay_btn = QtGui.QPushButton("Okay")
  588. self.okay_btn.setStyleSheet("padding: 15px;")
  589. self.okay_btn.clicked.connect(self.on_okay)
  590. box.addWidget(self.okay_btn)
  591. box.addSpacerItem(QtGui.QSpacerItem(1, 20))
  592. self.cancel_btn = QtGui.QPushButton("Cancel")
  593. self.cancel_btn.setStyleSheet("padding: 15px;")
  594. self.cancel_btn.clicked.connect(self.on_cancel)
  595. box.addWidget(self.cancel_btn)
  596. self.setLayout(box)
  597. def on_okay(self):
  598. self.return_value = True
  599. self.close()
  600. def on_cancel(self):
  601. self.close()
  602. def get_return_value(self):
  603. return self.return_value
  604. class RegisterBitsDialog(QtGui.QDialog):
  605. def __init__(self, n_bits, parent=None):
  606. QtGui.QDialog.__init__(self, parent)
  607. self.n_bits = n_bits
  608. self.setWindowTitle("Register Bit Input Helper")
  609. self.do_layout()
  610. self.return_bits = None
  611. def do_layout(self):
  612. size = QtCore.QSize(200, 200)
  613. #self.setMaximumSize(size)
  614. self.setMinimumSize(size)
  615. box = QtGui.QVBoxLayout()
  616. self.table = BitsEditTable("0"*self.n_bits)
  617. box.addWidget(self.table)
  618. self.okay_btn = QtGui.QPushButton("Okay")
  619. self.okay_btn.setStyleSheet("padding: 15px;")
  620. self.okay_btn.clicked.connect(self.on_okay)
  621. box.addWidget(self.okay_btn)
  622. box.addSpacerItem(QtGui.QSpacerItem(1, 20))
  623. self.cancel_btn = QtGui.QPushButton("Cancel")
  624. self.cancel_btn.setStyleSheet("padding: 15px;")
  625. self.cancel_btn.clicked.connect(self.on_cancel)
  626. box.addWidget(self.cancel_btn)
  627. self.setLayout(box)
  628. def on_okay(self):
  629. self.return_bits = self.table.get_bits()
  630. self.close()
  631. def on_cancel(self):
  632. self.close()
  633. def get_return_value(self):
  634. return self.return_bits
  635. class FileLikeQTextEdit(QtGui.QTextEdit):
  636. def __init__(self, parent=None):
  637. QtGui.QTextEdit.__init__(self, parent)
  638. def write(self, str_in):
  639. self.append(str_in)
  640. def flush(self):
  641. pass
  642. def close(self):
  643. pass
  644. class LogHandler(logging.Handler):
  645. def __init__(self, text_area):
  646. logging.Handler.__init__(self)
  647. self.text_area = text_area
  648. def emit(self, record):
  649. self.text_area.write(self.format(record))
  650. class ApplicationWindow(QtGui.QMainWindow):
  651. def __init__(self, args):
  652. QtGui.QMainWindow.__init__(self)
  653. self.args = args
  654. self.board_config = heb.board.BoardConfiguration(self.args.config if self.args.config else None)
  655. self.opt_widgets = {}
  656. self.data = None
  657. self.continuous_read = False
  658. self.do_layout()
  659. self.register_observers()
  660. if args.input:
  661. self.read_and_update_data_from_file(args.input)
  662. def new_checkbox(self, name, func):
  663. checkbox = QtGui.QCheckBox(name)
  664. checkbox.clicked.connect(func)
  665. self.opt_widgets[name] = checkbox
  666. return checkbox
  667. def new_radiobutton(self, name, func):
  668. button = QtGui.QRadioButton(name)
  669. button.clicked.connect(func)
  670. self.opt_widgets[name] = button
  671. return button
  672. def new_datawidget(self):
  673. splitter = QtGui.QSplitter(self)
  674. self.canvas = PlotCanvas(splitter)
  675. self.mpl_toolbar = NavigationToolbar(self.canvas, splitter)
  676. canvas_box = QtGui.QVBoxLayout()
  677. canvas_box.addWidget(self.canvas)
  678. canvas_box.addWidget(self.mpl_toolbar)
  679. canvas_widget = QtGui.QWidget()
  680. canvas_widget.setLayout(canvas_box)
  681. sidebar = QtGui.QGridLayout()
  682. data_view_groupbox = QtGui.QGroupBox()
  683. data_view_groupbox.setTitle('Data View Settings')
  684. data_view_layout = QtGui.QGridLayout()
  685. data_view_layout.setVerticalSpacing(5)
  686. data_view_layout.addWidget(self.new_radiobutton(OPT_3D_MAP, self.on_option_change), 1, 0)
  687. data_view_layout.addWidget(self.new_radiobutton(OPT_TRAIN, self.on_option_change), 2, 0)
  688. data_view_layout.addWidget(self.new_radiobutton(OPT_FFT, self.on_option_change), 3, 0)
  689. data_view_layout.addWidget(self.new_radiobutton(OPT_COMBINED, self.on_option_change), 4, 0)
  690. # sidebar.addWidget(self.new_checkbox(OPT_RECONSTRUCTED, self.on_option_change))
  691. data_view_layout.addWidget(self.new_checkbox(OPT_ADC_1, self.on_option_change), 1, 1)
  692. data_view_layout.addWidget(self.new_checkbox(OPT_ADC_2, self.on_option_change), 2, 1)
  693. data_view_layout.addWidget(self.new_checkbox(OPT_ADC_3, self.on_option_change), 3, 1)
  694. data_view_layout.addWidget(self.new_checkbox(OPT_ADC_4, self.on_option_change), 4, 1)
  695. self.from_spinbox = Spinbox(0, 999, 0)
  696. self.from_spinbox.valueChanged.connect(self.on_option_change)
  697. self.to_spinbox = Spinbox(-1, 10000000, 1000)
  698. self.to_spinbox.valueChanged.connect(self.on_to_changed)
  699. data_view_layout.addWidget(QtGui.QLabel("Data range"), 5, 0)
  700. data_view_layout.addWidget(self.from_spinbox, 6, 0)
  701. data_view_layout.addWidget(self.to_spinbox, 6, 1)
  702. self.opt_widgets[OPT_ADC_1].setChecked(True)
  703. data_view_groupbox.setLayout(data_view_layout)
  704. sidebar.addWidget(data_view_groupbox, 0, 0, 1, 2) # Span both columns
  705. adc_settings_groupbox = QtGui.QGroupBox()
  706. adc_settings_groupbox.setTitle('Timing Settings')
  707. adc_delay_grid = QtGui.QGridLayout()
  708. adc_delay_grid.setVerticalSpacing(5)
  709. adc_delay_grid.addWidget(QtGui.QLabel("T/H Delay"), 0, 1, 1, 2)
  710. self.th_delay_spinbox = Spinbox(0, 15, 0)
  711. self.th_delay_spinbox.setMaximumWidth(80)
  712. self.th_delay_spinbox.valueChanged.connect(self.on_adc_delay_changed)
  713. adc_delay_grid.addWidget(self.th_delay_spinbox, 1, 1)
  714. adc_delay_grid.addWidget(QtGui.QLabel("Coarse Delay"), 1, 0)
  715. adc_delay_grid.addWidget(QtGui.QLabel("ADC_1"), 2, 1)
  716. adc_delay_grid.addWidget(QtGui.QLabel("ADC_2"), 2, 2)
  717. adc_delay_grid.addWidget(QtGui.QLabel("ADC_3"), 2, 3)
  718. adc_delay_grid.addWidget(QtGui.QLabel("ADC_4"), 2, 4)
  719. self.adc_1_delay_spinbox = Spinbox(0, 31, 0)
  720. self.adc_1_delay_spinbox.setMaximumWidth(80)
  721. self.adc_1_delay_spinbox.valueChanged.connect(self.on_adc_delay_changed)
  722. self.adc_2_delay_spinbox = Spinbox(0, 31, 0)
  723. self.adc_2_delay_spinbox.setMaximumWidth(80)
  724. self.adc_2_delay_spinbox.valueChanged.connect(self.on_adc_delay_changed)
  725. self.adc_3_delay_spinbox = Spinbox(0, 31, 0)
  726. self.adc_3_delay_spinbox.setMaximumWidth(80)
  727. self.adc_3_delay_spinbox.valueChanged.connect(self.on_adc_delay_changed)
  728. self.adc_4_delay_spinbox = Spinbox(0, 31, 0)
  729. self.adc_4_delay_spinbox.setMaximumWidth(80)
  730. self.adc_4_delay_spinbox.valueChanged.connect(self.on_adc_delay_changed)
  731. adc_delay_grid.addWidget(QtGui.QLabel("Fine Delay"), 3, 0)
  732. adc_delay_grid.addWidget(self.adc_1_delay_spinbox, 3, 1)
  733. adc_delay_grid.addWidget(self.adc_2_delay_spinbox, 3, 2)
  734. adc_delay_grid.addWidget(self.adc_3_delay_spinbox, 3, 3)
  735. adc_delay_grid.addWidget(self.adc_4_delay_spinbox, 3, 4)
  736. self.adc_1_delay_text = QtGui.QLineEdit()
  737. self.adc_1_delay_text.setReadOnly(True)
  738. self.adc_1_delay_text.setMaximumWidth(80)
  739. self.adc_2_delay_text = QtGui.QLineEdit()
  740. self.adc_2_delay_text.setReadOnly(True)
  741. self.adc_2_delay_text.setMaximumWidth(80)
  742. self.adc_3_delay_text = QtGui.QLineEdit()
  743. self.adc_3_delay_text.setReadOnly(True)
  744. self.adc_3_delay_text.setMaximumWidth(80)
  745. self.adc_4_delay_text = QtGui.QLineEdit()
  746. self.adc_4_delay_text.setReadOnly(True)
  747. self.adc_4_delay_text.setMaximumWidth(80)
  748. adc_delay_grid.addWidget(QtGui.QLabel("Total Delay"), 4, 0)
  749. adc_delay_grid.addWidget(self.adc_1_delay_text, 4, 1)
  750. adc_delay_grid.addWidget(self.adc_2_delay_text, 4, 2)
  751. adc_delay_grid.addWidget(self.adc_3_delay_text, 4, 3)
  752. adc_delay_grid.addWidget(self.adc_4_delay_text, 4, 4)
  753. adc_settings_groupbox.setLayout(adc_delay_grid)
  754. sidebar.addWidget(adc_settings_groupbox, 1, 0, 1, 2) # Span both columns
  755. self.set_adc_delay_spinboxes_active(False)
  756. aquisition_settings_groupbox = QtGui.QGroupBox()
  757. aquisition_settings_groupbox.setTitle('Acquisition Settings')
  758. aquisition_settings_layout = QtGui.QGridLayout()
  759. aquisition_settings_layout.setVerticalSpacing(5)
  760. self.simulate_checkbox = QtGui.QCheckBox("Simulate Pilot Bunch")
  761. aquisition_settings_layout.addWidget(self.simulate_checkbox, 0, 0)
  762. self.number_of_orbits_spinbox = Spinbox(1, 10000000, 0)
  763. self.number_of_orbits_spinbox.valueChanged.connect(self.on_number_of_orbits_changed)
  764. aquisition_settings_layout.addWidget(self.number_of_orbits_spinbox, 1, 0)
  765. aquisition_settings_layout.addWidget(QtGui.QLabel("Number of orbits to observe"), 1, 1)
  766. self.number_of_skipped_orbits_spinbox = Spinbox(0, 100, 0)
  767. self.number_of_skipped_orbits_spinbox.valueChanged.connect(self.on_number_of_skipped_orbits_changed)
  768. aquisition_settings_layout.addWidget(self.number_of_skipped_orbits_spinbox, 2, 0)
  769. aquisition_settings_layout.addWidget(QtGui.QLabel("Number of orbits to skip"), 2, 1)
  770. aquisition_settings_groupbox.setLayout(aquisition_settings_layout)
  771. sidebar.addWidget(aquisition_settings_groupbox, 2, 0, 1, 2)
  772. data_consistency_groupbox = QtGui.QGroupBox()
  773. data_consistency_groupbox.setTitle('Data Consistency')
  774. data_consistency_layout = QtGui.QHBoxLayout()
  775. self.data_consistency_led = GraphicalLED(self, (128, 128, 128), 10, 10)
  776. data_consistency_layout.addWidget(self.data_consistency_led)
  777. data_consistency_layout.addWidget(QtGui.QLabel("Consistency Indicator"))
  778. data_consistency_groupbox.setLayout(data_consistency_layout)
  779. sidebar.addWidget(data_consistency_groupbox, 3, 0, 1, 2)
  780. read_data_toolbox = QtGui.QToolBox()
  781. single_and_timed_read_layout = QtGui.QGridLayout()
  782. single_and_timed_read_layout.setVerticalSpacing(10)
  783. single_and_timed_read_layout.addWidget(QtGui.QLabel("Read every n-Milliseconds"), 0, 0)
  784. self.continuous_read_interval_spinbox = Spinbox(0, 10000, 100)
  785. self.continuous_read_checkbox = self.new_checkbox("Continuous Readout", self.on_continuous_read)
  786. single_and_timed_read_layout.addWidget(self.continuous_read_interval_spinbox, 1, 0)
  787. single_and_timed_read_layout.addWidget(self.continuous_read_checkbox, 1, 1)
  788. self.start_button = QtGui.QPushButton("Single Read")
  789. self.start_button.clicked.connect(self.on_single_read)
  790. single_and_timed_read_layout.addWidget(self.start_button, 2, 0)
  791. single_and_timed_read_layout.setRowStretch(2, 1) # Otherwise, the label in row 0 will take all the space...
  792. single_and_timed_read_wdgt = QtGui.QWidget()
  793. single_and_timed_read_wdgt.setLayout(single_and_timed_read_layout)
  794. read_data_toolbox.addItem(single_and_timed_read_wdgt, 'Single and Continuous Readout')
  795. acquisition_layout = QtGui.QGridLayout()
  796. acquisition_layout.setVerticalSpacing(10)
  797. self.acquisitions_spinbox = Spinbox(1, 10000000, 10)
  798. acquisition_layout.addWidget(self.acquisitions_spinbox, 0, 0)
  799. acquisition_layout.addWidget(QtGui.QLabel("Count"), 0, 1)
  800. self.wait_time_spinbox = Spinbox(1, 60, 15)
  801. acquisition_layout.addWidget(self.wait_time_spinbox, 1, 0)
  802. acquisition_layout.addWidget(QtGui.QLabel("Wait (s)"), 1, 1)
  803. self.spectrogram_checkbox = QtGui.QCheckBox("Build Spectrograms")
  804. acquisition_layout.addWidget(self.spectrogram_checkbox, 2, 0)
  805. self.acquire_button = QtGui.QPushButton("Acquire")
  806. self.acquire_button.clicked.connect(self.on_acquire)
  807. acquisition_layout.addWidget(self.acquire_button, 3, 0)
  808. self.stop_button = QtGui.QPushButton("Stop")
  809. self.stop_button.setEnabled(False)
  810. self.stop_button.clicked.connect(self.on_stop)
  811. acquisition_layout.addWidget(self.stop_button, 3, 1)
  812. self.acquisition_progressbar = QtGui.QProgressBar()
  813. acquisition_layout.addWidget(self.acquisition_progressbar, 4, 0, 1, 2)
  814. acquisition_wdgt = QtGui.QWidget()
  815. acquisition_wdgt.setLayout(acquisition_layout)
  816. read_data_toolbox.addItem(acquisition_wdgt, 'Acquisition')
  817. timescan_layout = QtGui.QGridLayout()
  818. timescan_layout.setVerticalSpacing(10)
  819. self.scan_button = QtGui.QPushButton("Time scan")
  820. self.scan_button.clicked.connect(self.on_scan)
  821. timescan_layout.addWidget(self.scan_button, 0, 0)
  822. self.scan_stop_button = QtGui.QPushButton("Stop scan")
  823. self.scan_stop_button.setEnabled(False)
  824. timescan_layout.addWidget(self.scan_stop_button, 0, 1)
  825. self.timescan_progressbar = QtGui.QProgressBar()
  826. timescan_layout.addWidget(self.timescan_progressbar, 1, 0, 1, 2)
  827. timescan_layout.addWidget(QtGui.QLabel('Coarse Scan Range'), 2, 0, 1, 2)
  828. self.time_scan_coarse_from = Spinbox(0, self.board_config.get('th_delay_max'), 0)
  829. timescan_layout.addWidget(self.time_scan_coarse_from, 3, 0)
  830. self.time_scan_coarse_to = Spinbox(0, self.board_config.get('th_delay_max'), self.board_config.get('th_delay_max'))
  831. timescan_layout.addWidget(self.time_scan_coarse_to, 3, 1)
  832. timescan_layout.addWidget(QtGui.QLabel('Fine Scan Range'), 4, 0, 1, 2)
  833. self.time_scan_fine_from = Spinbox(0, self.board_config.get('chip_delay_max'), 0)
  834. timescan_layout.addWidget(self.time_scan_fine_from, 5, 0)
  835. self.time_scan_fine_to = Spinbox(0, self.board_config.get('chip_delay_max'), self.board_config.get('chip_delay_max'))
  836. timescan_layout.addWidget(self.time_scan_fine_to, 5, 1)
  837. timescan_wdgt = QtGui.QWidget()
  838. timescan_wdgt.setLayout(timescan_layout)
  839. read_data_toolbox.addItem(timescan_wdgt, 'Time Scan')
  840. read_data_toolbox.setMinimumHeight(240)
  841. sidebar.addWidget(read_data_toolbox, 4, 0, 1, 2)
  842. sidebar.setVerticalSpacing(10)
  843. sidebar.setRowStretch(5, 1)
  844. sidebar_group = QtGui.QGroupBox("sidebar")
  845. sidebar_group.setLayout(sidebar)
  846. sidebar_group.setFlat(True)
  847. splitter.addWidget(canvas_widget)
  848. splitter.addWidget(sidebar_group)
  849. splitter.setStretchFactor(0, 4)
  850. splitter.setStretchFactor(1, 2)
  851. return splitter
  852. def do_layout(self):
  853. self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
  854. self.setWindowTitle("HEB analysis")
  855. self.file_menu = QtGui.QMenu('&File', self)
  856. self.file_menu.addAction('&Open Datafile', self.on_open,
  857. QtCore.Qt.CTRL + QtCore.Qt.Key_O)
  858. self.file_menu.addAction('O&pen Config', self.on_open_config,
  859. QtCore.Qt.CTRL + QtCore.Qt.Key_P)
  860. self.file_menu.addAction('&Save Config', self.on_save_config,
  861. QtCore.Qt.CTRL + QtCore.Qt.Key_S)
  862. self.file_menu.addAction('&Quit', self.on_close,
  863. QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
  864. self.menuBar().addMenu(self.file_menu)
  865. self.tab_views = QtGui.QTabWidget(self)
  866. self.setCentralWidget(self.tab_views)
  867. # Group the board control buttons together
  868. control_buttons = QtGui.QGridLayout()
  869. control_buttons.addWidget(QtGui.QLabel("Board Control"), 0, 0)
  870. self.start_board_button = QtGui.QPushButton("Start Board")
  871. self.start_board_button.clicked.connect(self.on_start_board)
  872. control_buttons.addWidget(self.start_board_button, 1, 0)
  873. self.calibrate_board_button = QtGui.QPushButton("Calibrate")
  874. self.calibrate_board_button.clicked.connect(self.on_calibrate_board)
  875. self.calibrate_board_button.setEnabled(False)
  876. control_buttons.addWidget(self.calibrate_board_button, 2, 0)
  877. self.sync_board_button = QtGui.QPushButton("Synchronize")
  878. self.sync_board_button.clicked.connect(self.on_sync_board)
  879. self.sync_board_button.setEnabled(False)
  880. control_buttons.addWidget(self.sync_board_button, 3, 0)
  881. self.set_defaults_button = QtGui.QPushButton("Set Defaults")
  882. self.set_defaults_button.clicked.connect(self.on_set_defaults)
  883. self.set_defaults_button.setEnabled(False)
  884. control_buttons.addWidget(self.set_defaults_button, 4, 0)
  885. self.soft_reset_button = QtGui.QPushButton("Soft Reset")
  886. self.soft_reset_button.clicked.connect(self.on_soft_reset)
  887. self.soft_reset_button.setEnabled(False)
  888. control_buttons.addWidget(self.soft_reset_button, 5, 0)
  889. self.stop_board_button = QtGui.QPushButton("Board Off")
  890. self.stop_board_button.clicked.connect(self.on_stop_board)
  891. control_buttons.addWidget(self.stop_board_button, 6, 0)
  892. #self.show_advanced_tick = QtGui.QCheckBox("Show advanced Interface")
  893. #self.show_advanced_tick.setEnabled(True)
  894. #self.show_advanced_tick.clicked.connect(self.do_show_advanced_interface)
  895. #control_buttons.addWidget(self.show_advanced_tick, 6, 0)
  896. control_buttons.setRowStretch(7, 1)
  897. buttons_widget = QtGui.QWidget()
  898. buttons_widget.setLayout(control_buttons)
  899. buttons_widget.setMinimumWidth(200)
  900. buttons_widget.setMaximumWidth(200)
  901. # Group the Simple status display together with the "Check Status" button
  902. status_box = QtGui.QGridLayout()
  903. self.simple_status_display = SimpleStatusDisplay()
  904. status_box.addWidget(self.simple_status_display, 0, 0)
  905. self.get_status_button = QtGui.QPushButton("Check Status")
  906. self.get_status_button.setEnabled(True)
  907. self.get_status_button.clicked.connect(self.do_status_readout)
  908. self.get_status_button.setMinimumWidth(150)
  909. self.get_status_button.setMaximumWidth(150)
  910. status_box.addWidget(self.get_status_button, 1, 0)
  911. status_box.setRowStretch(2, 1)
  912. simple_status_widget = QtGui.QWidget()
  913. simple_status_widget.setLayout(status_box)
  914. #Text Area for logging of inconsistent readouts
  915. self.error_text_area = FileLikeQTextEdit(self)
  916. self.error_text_area.setFont(QtGui.QFont('monospace', 9))
  917. self.error_text_area.setTextColor(QtCore.Qt.red)
  918. self.error_text_area.setMaximumWidth(300)
  919. self.error_text_area.setReadOnly(True)
  920. clear_error_text_btn = QtGui.QPushButton("Clear List")
  921. clear_error_text_btn.clicked.connect(self.error_text_area.clear)
  922. error_text_box = QtGui.QVBoxLayout()
  923. error_text_box.addWidget(QtGui.QLabel("Inconsistent Files List"))
  924. error_text_box.addWidget(self.error_text_area)
  925. error_text_box.addWidget(clear_error_text_btn)
  926. error_text_wdgt = QtGui.QWidget()
  927. error_text_wdgt.setLayout(error_text_box)
  928. #Now bundle the Board Control buttons and the Status LEDS together
  929. top_box = QtGui.QHBoxLayout()
  930. top_box.addWidget(buttons_widget)
  931. top_box.addWidget(simple_status_widget)
  932. top_box.addWidget(error_text_wdgt)
  933. top_box.insertStretch(-1, 1)
  934. top_box_w = QtGui.QWidget()
  935. top_box_w.setLayout(top_box)
  936. #Create the Timing Indication Block
  937. self.fpga_delay_table = BitsDisplayTable('0', self)
  938. self.fpga_delay_table.set_label(0, 0, "FPGA Delay")
  939. self.th_delay_table = BitsDisplayTable('0', self)
  940. self.th_delay_table.set_label(0, 0, "T/H Delay")
  941. self.fpga_temperature = QtGui.QLineEdit()
  942. self.fpga_temperature.setMaximumWidth(60)
  943. self.fpga_temperature.setReadOnly(True)
  944. self.adc_delay_table = BitsDisplayTable(4*'0', self)
  945. self.adc_delay_table.set_label(0, 0, "ADC 1")
  946. self.adc_delay_table.set_label(1, 1, "ADC 2")
  947. self.adc_delay_table.set_label(2, 2, "ADC 3")
  948. self.adc_delay_table.set_label(3, 3, "ADC 4")
  949. timing_line_1 = QtGui.QHBoxLayout()
  950. timing_line_1.setAlignment(QtCore.Qt.AlignLeft)
  951. timing_line_1.addWidget(self.fpga_delay_table)
  952. timing_line_1.addWidget(self.th_delay_table)
  953. timing_line_1.addWidget(self.adc_delay_table)
  954. timing_line_1_wdgt = QtGui.QWidget()
  955. timing_line_1_wdgt.setLayout(timing_line_1)
  956. timing_line_2 = QtGui.QGridLayout()
  957. timing_line_2.addWidget(QtGui.QLabel("FPGA Temperature"), 0, 0)
  958. timing_line_2.addWidget(self.fpga_temperature, 0, 1)
  959. timing_line_2.setColumnStretch(2, 1)
  960. timing_line_2_wdgt = QtGui.QWidget()
  961. timing_line_2_wdgt.setLayout(timing_line_2)
  962. timing_box = QtGui.QVBoxLayout()
  963. timing_box.addWidget(QtGui.QLabel(" Timings in Pico Seconds"), 0, QtCore.Qt.AlignLeft)
  964. timing_box.addWidget(timing_line_1_wdgt, 0, QtCore.Qt.AlignLeft)
  965. timing_box.addWidget(timing_line_2_wdgt, 0, QtCore.Qt.AlignLeft)
  966. timing_box_wdgt = QtGui.QWidget()
  967. timing_box_wdgt.setLayout(timing_box)
  968. #Create the the "Write Registers" block
  969. sub_box = QtGui.QGridLayout()
  970. sub_box.addWidget(QtGui.QLabel("Register Address"), 0, 0)
  971. sub_box.addWidget(QtGui.QLabel("Register Value"), 0, 1)
  972. self.adv_register_address = QtGui.QLineEdit()
  973. self.adv_register_address.setText("0x9040")
  974. self.adv_register_address.setInputMask(r"\0\xHhhhhhhh")
  975. sub_box.addWidget(self.adv_register_address, 1, 0)
  976. self.adv_register_value = QtGui.QLineEdit()
  977. self.adv_register_value.setText("0x0")
  978. self.adv_register_value.setInputMask(r"\0\xHhhhhhhh")
  979. sub_box.addWidget(self.adv_register_value, 1, 1)
  980. helper_btn = QtGui.QPushButton("Open Input Help")
  981. helper_btn.clicked.connect(self.show_input_helper)
  982. sub_box.addWidget(helper_btn, 2, 0)
  983. adv_write_reg_val_btn = QtGui.QPushButton("Write Value")
  984. adv_write_reg_val_btn.clicked.connect(self.write_register_adv)
  985. sub_box.addWidget(adv_write_reg_val_btn, 2, 1)
  986. sub_box.setRowStretch(3, 1)
  987. self.sub_box_w = QtGui.QWidget()
  988. self.sub_box_w.setLayout(sub_box)
  989. self.sub_box_w.setVisible(False)
  990. #Pack Board Control / Status LEDs / Timing Indication / "Write Register" together
  991. control_block = QtGui.QGridLayout()
  992. control_block.addWidget(top_box_w, 0, 0)
  993. control_block.addWidget(timing_box_wdgt, 1, 0)
  994. control_block.addWidget(self.sub_box_w, 3, 0)
  995. control_block.setRowStretch(2, 1)
  996. control_block_wdgt = QtGui.QWidget()
  997. control_block_wdgt.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
  998. control_block_wdgt.setLayout(control_block)
  999. #Split the area vertically and add a text area in the bottom half
  1000. splitter = QtGui.QSplitter()
  1001. splitter.setOrientation(QtCore.Qt.Vertical)
  1002. splitter.addWidget(control_block_wdgt)
  1003. self.text_area = FileLikeQTextEdit(self)
  1004. self.text_area.setFont(QtGui.QFont('monospace', 9))
  1005. self.text_area.setReadOnly(True)
  1006. splitter.addWidget(self.text_area)
  1007. # Let log handler write to text area
  1008. log_handler = LogHandler(self.text_area)
  1009. log_handler.setFormatter(logging.Formatter('%(asctime)s - %(funcName)s(): %(message)s'))
  1010. logger = logging.getLogger()
  1011. logger.addHandler(log_handler)
  1012. logger.setLevel(logging.INFO)
  1013. self.board_config.logger = logger
  1014. # Create a widget for the Advanced Board Interface
  1015. self.advanced_interface = AdvancedBoardInterface(self)
  1016. self.advanced_interface.setVisible(False)
  1017. #set up tabs for the main window
  1018. self.tab_views.addTab(splitter, "Control")
  1019. self.tab_views.addTab(self.advanced_interface, "Registers")
  1020. self.tab_views.addTab(self.new_datawidget(), "Data")
  1021. self.tab_views.setCurrentIndex(2)
  1022. def do_show_advanced_interface(self):
  1023. show = self.show_advanced_tick.isChecked()
  1024. self.advanced_interface.setVisible(show)
  1025. self.sub_box_w.setVisible(show)
  1026. def register_observers(self):
  1027. sbo = self.board_config.observe
  1028. sbo(self.adc_1_delay_spinbox, self.adc_1_delay_spinbox.setValueSilent, 'chip_1_delay')
  1029. sbo(self.adc_2_delay_spinbox, self.adc_2_delay_spinbox.setValueSilent, 'chip_2_delay')
  1030. sbo(self.adc_3_delay_spinbox, self.adc_3_delay_spinbox.setValueSilent, 'chip_3_delay')
  1031. sbo(self.adc_4_delay_spinbox, self.adc_4_delay_spinbox.setValueSilent, 'chip_4_delay')
  1032. sbo(self.adc_1_delay_text, lambda x: self.adc_1_delay_text.setText('%i + %i' % (self.board_config.get('th_delay')*self.board_config.get('th_delay_factor'),x*self.board_config.get('chip_delay_factor'))), 'chip_1_delay')
  1033. sbo(self.adc_2_delay_text, lambda x: self.adc_2_delay_text.setText('%i + %i'%(self.board_config.get('th_delay')*self.board_config.get('th_delay_factor'),x*self.board_config.get('chip_delay_factor'))), 'chip_2_delay')
  1034. sbo(self.adc_3_delay_text, lambda x: self.adc_3_delay_text.setText('%i + %i'%(self.board_config.get('th_delay')*self.board_config.get('th_delay_factor'),x*self.board_config.get('chip_delay_factor'))), 'chip_3_delay')
  1035. sbo(self.adc_4_delay_text, lambda x: self.adc_4_delay_text.setText('%i + %i'%(self.board_config.get('th_delay')*self.board_config.get('th_delay_factor'),x*self.board_config.get('chip_delay_factor'))), 'chip_4_delay')
  1036. sbo(self.fpga_delay_table, lambda x: self.fpga_delay_table.set_item(0, 0, x*self.board_config.get('fpga_delay_factor')), 'fpga_delay')
  1037. sbo(self.th_delay_table, lambda x: self.th_delay_table.set_item(0, 0, x*self.board_config.get('th_delay_factor')), 'th_delay')
  1038. sbo(self.th_delay_spinbox, self.th_delay_spinbox.setValueSilent, 'th_delay')
  1039. sbo(self.number_of_orbits_spinbox, self.number_of_orbits_spinbox.setValueSilent, 'orbits_observe')
  1040. sbo(self.number_of_skipped_orbits_spinbox, self.number_of_skipped_orbits_spinbox.setValueSilent, 'orbits_skip')
  1041. sbo(self.adc_delay_table, lambda x: self.adc_delay_table.set_item(0, 0, x * self.board_config.get('adc_delay_factor')), 'adc_1_delay')
  1042. sbo(self.adc_delay_table, lambda x: self.adc_delay_table.set_item(0, 1, x * self.board_config.get('adc_delay_factor')), 'adc_2_delay')
  1043. sbo(self.adc_delay_table, lambda x: self.adc_delay_table.set_item(0, 2, x * self.board_config.get('adc_delay_factor')), 'adc_3_delay')
  1044. sbo(self.adc_delay_table, lambda x: self.adc_delay_table.set_item(0, 3, x * self.board_config.get('adc_delay_factor')), 'adc_4_delay')
  1045. def do_status_readout(self):
  1046. try:
  1047. registers = heb.board.read_pci(3, '0x9050', decimal=True)
  1048. self.simple_status_display.update_status(registers)
  1049. self.advanced_interface.update_status(registers)
  1050. control = heb.board.read_pci(1, '0x9040')[0]
  1051. control_bits = '{0:032b}'.format(int(control, 16))
  1052. self.advanced_interface.control_table.set_numbers(control_bits)
  1053. if control_bits[22:26] == "1111":
  1054. self.start_board_button.setEnabled(False)
  1055. self.soft_reset_button.setEnabled(True)
  1056. self.calibrate_board_button.setEnabled(True)
  1057. else:
  1058. self.start_board_button.setEnabled(True)
  1059. self.soft_reset_button.setEnabled(False)
  1060. self.calibrate_board_button.setEnabled(False)
  1061. fpga_temp_raw_hex = heb.board.read_pci(1,'0x9110')[0]
  1062. fpga_temp_raw_hex = fpga_temp_raw_hex[-3:]
  1063. fpga_temp_raw_bin = '{0:012b}'.format(int(fpga_temp_raw_hex, 16))
  1064. fpga_temp_encoded = heb.board.get_dec_from_bits(fpga_temp_raw_bin, 9, 0)
  1065. fpga_temp_celsius = '{0:2.2f}'.format(((fpga_temp_encoded*503.975)/1024)-273.15)
  1066. self.fpga_temperature.setText(fpga_temp_celsius + " C")
  1067. except heb.board.BoardError as e:
  1068. logging.error("Reading board status failed: {}".format(str(e)))
  1069. def write_register_adv(self):
  1070. # First cast both texts to integers (base 16) and let python check
  1071. # if the entered values are valid hex-numbers
  1072. try:
  1073. addr = int("%s"%self.adv_register_address.text(), 16)
  1074. except ValueError as e:
  1075. logging.error("Register address is invalid!")
  1076. self.adv_register_address.setStyleSheet("QLineEdit { background-color : #FF6666; }")
  1077. return
  1078. try:
  1079. value = int("%s"%self.adv_register_value.text(), 16)
  1080. except ValueError as e:
  1081. logging.error("Register value is invalid!")
  1082. self.adv_register_value.setStyleSheet("QLineEdit { background-color : #FF6666; }")
  1083. return
  1084. # Now use the numbers
  1085. addr = "%s"%self.adv_register_address.text()
  1086. value = "%s"%self.adv_register_value.text()
  1087. self.adv_register_address.setStyleSheet("QLineEdit { background-color : white; }")
  1088. self.adv_register_value.setStyleSheet("QLineEdit { background-color : white; }")
  1089. try:
  1090. heb.board.write_pci(value, addr)
  1091. except heb.board.BoardError as e:
  1092. QtGui.QMessageBox.critical(self, "Board communication", "'pci' " + str(e))
  1093. logging.error("Could not write values to board due to an error!")
  1094. return
  1095. # Intercept writes to the "Timing" Registers to catch the input and put it into their
  1096. # respective displays
  1097. if addr == "0x9060":
  1098. if value[:8] == "0x000501":
  1099. #We are writing a timing value. Decide which one
  1100. if value[-1:] == "0":
  1101. #FPGA
  1102. self.board_config.update('fpga_delay', int(value[8:9], 16))
  1103. elif value[-1:] == "3":
  1104. #T/H
  1105. self.board_config.update('th_delay', int(value[8:9], 16))
  1106. elif value[-1:] == "4":
  1107. #ADC_1
  1108. self.board_config.update('adc_1_delay', int(value[8:9], 16))
  1109. elif value[-1:] == "5":
  1110. #ADC_2
  1111. self.board_config.update('adc_1_delay', int(value[8:9], 16))
  1112. elif value[-1:] == "6":
  1113. #ADC_3
  1114. self.board_config.update('adc_1_delay', int(value[8:9], 16))
  1115. elif value[-1:] == "7":
  1116. #ADC_4
  1117. self.board_config.update('adc_1_delay', int(value[8:9], 16))
  1118. self.do_status_readout()
  1119. logging.info("Written '%s' to register '%s'." % (value, addr))
  1120. def show_input_helper(self):
  1121. dialog = RegisterBitsDialog(32)
  1122. dialog.exec_()
  1123. dialog.deleteLater()
  1124. bits = dialog.get_return_value()
  1125. if bits:
  1126. hex_str = hex(int(bits, 2))
  1127. self.adv_register_value.setText(hex_str)
  1128. def _check_for_no_continuous_read(self):
  1129. if self.continuous_read is True:
  1130. dialog = PopupDialog("Continuous Read is currently active!\n"
  1131. "Stop continuous read and still perform this action?")
  1132. dialog.exec_()
  1133. dialog.deleteLater()
  1134. ret = dialog.get_return_value()
  1135. if ret is False:
  1136. return False
  1137. else:
  1138. self._set_continuous_read_inactive()
  1139. self.continuous_read_checkbox.setChecked(False)
  1140. return True
  1141. else:
  1142. return True
  1143. def on_start_board(self):
  1144. enable_wait_cursor()
  1145. if not self._check_for_no_continuous_read():
  1146. disable_wait_cursor()
  1147. return
  1148. try:
  1149. if heb.board.is_active():
  1150. disable_wait_cursor()
  1151. self.do_status_readout()
  1152. return
  1153. logging.info("##### Activating Board #####")
  1154. heb.board.start_dma()
  1155. #cmd = ['pci', '--list-dma-engines']
  1156. #logging.info(heb.board.safe_call(cmd))
  1157. heb.board.write_pci('0x20001000', '0x9100')
  1158. heb.board.write_pci('0x05', '0x9040')
  1159. time.sleep(1.0)
  1160. dialog1 = PopupDialog("Switch On the power supply --> FIRST <--")
  1161. dialog1.exec_()
  1162. dialog1.deleteLater()
  1163. if not dialog1.get_return_value():
  1164. logging.error("Starting procedure canceled")
  1165. disable_wait_cursor()
  1166. return
  1167. logging.info("Switch ON T/Hs")
  1168. heb.board.write_pci('0x3C1', '0x9040')
  1169. logging.info("9040: " + str(heb.board.read_pci(1, '0x9040')[0]))
  1170. time.sleep(0.1)
  1171. dialog2 = PopupDialog("Switch On the power supply --> SECOND <--")
  1172. dialog2.exec_()
  1173. dialog2.deleteLater()
  1174. if not dialog2.get_return_value():
  1175. self.test_area.write("Starting procedure canceled")
  1176. disable_wait_cursor()
  1177. return
  1178. logging.info("Switch ON ADCs")
  1179. heb.board.write_pci('0x3F1', '0x9040')
  1180. logging.info("9040: " + str(heb.board.read_pci(1, '0x9040')[0]))
  1181. time.sleep(0.1)
  1182. heb.board.write_pci('0x3F0', '0x9040')
  1183. logging.info("9040: " + str(heb.board.read_pci(1, '0x9040')[0]))
  1184. time.sleep(1.0)
  1185. logging.info("Board started successfully!")
  1186. except heb.board.BoardError as e:
  1187. logging.error("Starting board failed: {}".format(str(e)))
  1188. disable_wait_cursor()
  1189. self.do_status_readout()
  1190. def on_calibrate_board(self):
  1191. enable_wait_cursor()
  1192. if not self._check_for_no_continuous_read():
  1193. disable_wait_cursor()
  1194. return
  1195. try:
  1196. logging.info("##### Calibrating Board #####")
  1197. logging.info("Removing Board Reset")
  1198. heb.board.write_pci('0x2000003f0', '0x9040')
  1199. time.sleep(0.5)
  1200. logging.info("SPI Fanout Programming...")
  1201. heb.board.write_pci('0x083', '0x9068')
  1202. time.sleep(0.5)
  1203. heb.board.write_pci('0x6a2', '0x9068')
  1204. time.sleep(0.5)
  1205. logging.info("PLL calibration start...")
  1206. logging.info("PLL Reset...")
  1207. heb.board.write_pci('0x80000000', '0x9060')
  1208. time.sleep(0.5)
  1209. logging.info("Set CH_0 (FPGA) clock FPGA ...")
  1210. heb.board.write_pci('0x00050000', '0x9060')
  1211. time.sleep(0.5)
  1212. logging.info("Set CH_3 clock fanout ...")
  1213. heb.board.write_pci('0x00050003', '0x9060')
  1214. time.sleep(0.5)
  1215. logging.info("Set CH_4 clock ADC 1 ...")
  1216. heb.board.write_pci('0x00050004', '0x9060')
  1217. time.sleep(0.5)
  1218. logging.info("Set CH_5 clock ADC 2 ...")
  1219. heb.board.write_pci('0x00050005', '0x9060')
  1220. time.sleep(0.5)
  1221. logging.info("Set CH_6 clock ADC 3 ...")
  1222. heb.board.write_pci('0x00050006', '0x9060')
  1223. time.sleep(0.5)
  1224. logging.info("Set CH_7 clock ADC 4 ...")
  1225. heb.board.write_pci('0x00050007', '0x9060')
  1226. time.sleep(0.5)
  1227. logging.info("Set R8 ...")
  1228. heb.board.write_pci('0x10000908', '0x9060')
  1229. time.sleep(0.5)
  1230. logging.info("Set R11 ...")
  1231. heb.board.write_pci('0x0082800B', '0x9060')
  1232. time.sleep(0.5)
  1233. logging.info("Set R13 ...")
  1234. heb.board.write_pci('0x029F400D', '0x9060')
  1235. time.sleep(0.5)
  1236. logging.info("Set R14 (F_out and Global_EN => ON) ...")
  1237. heb.board.write_pci('0x0830040E', '0x9060')
  1238. time.sleep(0.5)
  1239. logging.info("Set R15 ...")
  1240. heb.board.write_pci('0xD000100F', '0x9060')
  1241. time.sleep(0.5)
  1242. except heb.board.BoardError as e:
  1243. logging.error("Calibration failed: {}".format(str(e)))
  1244. disable_wait_cursor()
  1245. self.do_status_readout()
  1246. return
  1247. logging.info("Board Calibration successful!")
  1248. self.sync_board_button.setEnabled(True)
  1249. disable_wait_cursor()
  1250. self.do_status_readout()
  1251. def on_sync_board(self):
  1252. enable_wait_cursor()
  1253. if not self._check_for_no_continuous_read():
  1254. disable_wait_cursor()
  1255. return
  1256. try:
  1257. logging.info("##### Synchronize PLLs #####")
  1258. logging.info("Send the PLL sync signals ...")
  1259. heb.board.write_pci('0x1003f0', '0x9040')
  1260. time.sleep(1.0)
  1261. logging.info("Done!")
  1262. heb.board.write_pci('0x0003f0', '0x9040')
  1263. except heb.board.BoardError as e:
  1264. logging.error("Synchronization failed: {}".format(str(e)))
  1265. disable_wait_cursor()
  1266. self.do_status_readout()
  1267. return
  1268. logging.info("Board synchronization successful!")
  1269. self.set_defaults_button.setEnabled(True)
  1270. disable_wait_cursor()
  1271. self.do_status_readout()
  1272. def on_set_defaults(self):
  1273. enable_wait_cursor()
  1274. if not self._check_for_no_continuous_read():
  1275. disable_wait_cursor()
  1276. return
  1277. try:
  1278. logging.info("##### Setting default Values #####")
  1279. logging.info("Set Defaults delay value in the board...")
  1280. #Set_FPGA_clock_delay.sh 0
  1281. self.board_config.set_fpga_delay(self.board_config.get('fpga_delay'))
  1282. time.sleep(0.1)
  1283. #Set_Delay_chip.sh 16 16 16 16
  1284. factors = [self.board_config.get('chip_1_delay'), self.board_config.get('chip_2_delay'),
  1285. self.board_config.get('chip_3_delay'), self.board_config.get('chip_4_delay')]
  1286. self.board_config.set_chip_delay([0, 1, 2, 3], factors)
  1287. time.sleep(0.6)
  1288. #Set_TH_Delay.sh 12
  1289. self.board_config.set_th_delay(self.board_config.get('th_delay'))
  1290. time.sleep(0.1)
  1291. #Set_ADC_1_Delay.sh 4
  1292. self.board_config.set_adc_delay(0, self.board_config.get('adc_1_delay'))
  1293. time.sleep(0.1)
  1294. #Set_ADC_2_Delay.sh 4
  1295. self.board_config.set_adc_delay(1, self.board_config.get('adc_2_delay'))
  1296. time.sleep(0.1)
  1297. #Set_ADC_3_Delay.sh 4
  1298. self.board_config.set_adc_delay(2, self.board_config.get('adc_3_delay'))
  1299. time.sleep(0.1)
  1300. #Set_ADC_4_Delay.sh 4
  1301. self.board_config.set_adc_delay(3, self.board_config.get('adc_4_delay'))
  1302. time.sleep(0.1)
  1303. heb.board.write_pci('{0:08x}'.format(self.board_config.get('orbits_observe')), '0x9020')
  1304. self.number_of_orbits_spinbox.setValueSilent(self.board_config.get('orbits_observe'))
  1305. heb.board.write_pci('{0:08x}'.format(self.board_config.get('orbits_skip')), '0x9028')
  1306. self.number_of_skipped_orbits_spinbox.setValueSilent(self.board_config.get('orbits_skip'))
  1307. except heb.board.BoardError as e:
  1308. logging.error("Setting defaults failed: {}".format(str(e)))
  1309. disable_wait_cursor()
  1310. self.do_status_readout()
  1311. return
  1312. logging.info("Default values set successfully!")
  1313. self.set_adc_delay_spinboxes_active(True)
  1314. disable_wait_cursor()
  1315. self.do_status_readout()
  1316. def on_stop_board(self):
  1317. enable_wait_cursor()
  1318. if not self._check_for_no_continuous_read():
  1319. disable_wait_cursor()
  1320. return
  1321. try:
  1322. logging.info("##### Switching Off Board #####")
  1323. heb.board.write_pci('0x01', '0x9040')
  1324. heb.board.stop_dma()
  1325. cmd = ['pci', '--list-dma-engines']
  1326. logging.info(heb.board.safe_call(cmd))
  1327. time.sleep(0.5)
  1328. except heb.board.BoardError as e:
  1329. logging.error("Sequence failed: {}".format(str(e)))
  1330. disable_wait_cursor()
  1331. self.do_status_readout()
  1332. return
  1333. logging.info("Board switched off successfully!")
  1334. self.start_board_button.setEnabled(True)
  1335. self.calibrate_board_button.setEnabled(False)
  1336. self.sync_board_button.setEnabled(False)
  1337. self.set_defaults_button.setEnabled(False)
  1338. self.set_adc_delay_spinboxes_active(False)
  1339. disable_wait_cursor()
  1340. self.do_status_readout()
  1341. def on_soft_reset(self):
  1342. enable_wait_cursor()
  1343. if not self._check_for_no_continuous_read():
  1344. disable_wait_cursor()
  1345. return
  1346. try:
  1347. logging.info("Soft-Resetting Board ...")
  1348. heb.board.write_pci('0x1', '0x9040', hex_mask='0x1')
  1349. time.sleep(1)
  1350. heb.board.write_pci('0x0', '0x9040', hex_mask='0x1')
  1351. except heb.board.BoardError as e:
  1352. logging.error("Sequence failed: {}".format(str(e)))
  1353. disable_wait_cursor()
  1354. self.do_status_readout()
  1355. return
  1356. logging.info("Soft-Reset successful.")
  1357. disable_wait_cursor()
  1358. self.do_status_readout()
  1359. return
  1360. def disable_acquisition_input(self):
  1361. self.start_button.setEnabled(False)
  1362. self.acquire_button.setEnabled(False)
  1363. def enable_acquisition_input(self):
  1364. self.start_button.setEnabled(True)
  1365. self.acquire_button.setEnabled(True)
  1366. def set_adc_delay_spinboxes_active(self, value=True):
  1367. self.th_delay_spinbox.setEnabled(value)
  1368. self.adc_1_delay_spinbox.setEnabled(value)
  1369. self.adc_2_delay_spinbox.setEnabled(value)
  1370. self.adc_3_delay_spinbox.setEnabled(value)
  1371. self.adc_4_delay_spinbox.setEnabled(value)
  1372. def on_single_read(self):
  1373. self.continuous_read_checkbox.setEnabled(False)
  1374. self.disable_acquisition_input()
  1375. self.read_data_and_safe()
  1376. self.enable_acquisition_input()
  1377. self.continuous_read_checkbox.setEnabled(True)
  1378. def _set_continuous_read_active(self):
  1379. self.start_button.setEnabled(False)
  1380. self.acquire_button.setEnabled(False)
  1381. self.scan_button.setEnabled(False)
  1382. self.continuous_read = True
  1383. def _set_continuous_read_inactive(self):
  1384. if self.continuous_read:
  1385. self.continuous_read = False
  1386. self.timer.stop()
  1387. self.start_button.setEnabled(True)
  1388. self.acquire_button.setEnabled(True)
  1389. self.scan_button.setEnabled(True)
  1390. def on_continuous_read(self):
  1391. if self.continuous_read_checkbox.isChecked():
  1392. self._set_continuous_read_active()
  1393. self.do_continuous_read()
  1394. else:
  1395. self._set_continuous_read_inactive()
  1396. def do_continuous_read(self):
  1397. self.timer = QtCore.QTimer()
  1398. logging.info("Start continuous read")
  1399. def continuous_read_step():
  1400. if self.continuous_read:
  1401. self.read_data()
  1402. self.timer.start(self.continuous_read_interval_spinbox.value())
  1403. else:
  1404. self.timer.stop()
  1405. self.timer.timeout.connect(continuous_read_step)
  1406. self.timer.start(self.continuous_read_interval_spinbox.value())
  1407. def read_and_update(self, read_func, *args):
  1408. enable_wait_cursor()
  1409. # Remove all references as soon as possible
  1410. if self.data:
  1411. del self.data
  1412. self.data = None
  1413. header = self.advanced_interface.control_table.get_bit(28)
  1414. self.data = read_func(*args, force=self.args.force_read, header=header, cache=self.args.cache_data)
  1415. if heb.io.is_data_consistent(self.data):
  1416. self.data_consistency_led.set_color((0, 190, 0))
  1417. else:
  1418. self.data_consistency_led.set_color((255, 0, 0))
  1419. if read_func is heb.io.read_from_file:
  1420. self.error_text_area.write(str(args[0]))
  1421. disable_wait_cursor()
  1422. frm = self.from_spinbox.value()
  1423. to = self.to_spinbox.value()
  1424. self.canvas.update_figure(self.opt_widgets, self.data, frm, to)
  1425. def read_and_update_data_from_file(self, filename):
  1426. self.read_and_update(heb.io.read_from_file, str(filename))
  1427. def read_and_update_data_from_string(self, raw_data):
  1428. self.read_and_update(heb.io.read_from_string, raw_data)
  1429. def read_data_and_safe(self):
  1430. now = time.time()
  1431. filename = '{:0.3f}.out'.format(now)
  1432. try:
  1433. simulate = self.simulate_checkbox.isChecked()
  1434. heb.board.acquire_data(filename, simulate=simulate, duration=2.0)
  1435. #heb.board.run_status('/home/heb/StatusComparison.sh')
  1436. self.read_and_update_data_from_file(filename)
  1437. except heb.board.BoardError as e:
  1438. logging.error("Reading failed: {}".format(str(e)))
  1439. def read_data(self):
  1440. try:
  1441. if self.simulate_checkbox.isChecked():
  1442. heb.board.start_pilot_bunch_emulator()
  1443. heb.board.start_acquisition()
  1444. heb.board.wait_for_revolutions()
  1445. heb.board.stop_acquisition()
  1446. heb.board.enable_transfer()
  1447. cmd = ['pci', '-r', 'dma0', '-o', '/dev/stdout', '--multipacket']
  1448. data_raw = heb.board.safe_call(cmd)
  1449. heb.board.flush_dma()
  1450. # Sadly, the PCI software also outputs the Information, that it has
  1451. # written data to the desired file. This is recorded by our
  1452. # software and needs to be removed, so we split the returned string
  1453. # at the 'Writting data to file blah, blah" Btw: YES this
  1454. # 'Writting' is actually correct. No, i don't know why it is
  1455. # grammatically wrong in the first place :D
  1456. data_split = data_raw.split('Writting')[0]
  1457. self.read_and_update_data_from_string(data_split)
  1458. except heb.board.BoardError as e:
  1459. logging.error("Reading failed: {}".format(str(e)))
  1460. # return data
  1461. def iterate_spectrograms(self, path):
  1462. if not os.path.isdir("./"+str(path)):
  1463. return
  1464. transform = self.data.fft(1, frm=0, to=-1)
  1465. for i in range(heb.BUNCHES_PER_TURN-1):
  1466. filename = os.path.join(".", str(path), "%i.hsp" % i)
  1467. write_header = False
  1468. if not os.path.isfile(filename):
  1469. write_header = True
  1470. f = open(filename, 'ab')
  1471. if write_header:
  1472. f.write("#hsp\n") # heb spectrogram magic number
  1473. #f.write(b'\x40') # 64bit
  1474. #f.write('64') # 64bit
  1475. #f.write(sytruct.pack('>I', self.number_of_skipped_orbits_spinbox.value()))
  1476. f.write("#"+str(self.number_of_skipped_orbits_spinbox.value()))
  1477. f.write("\n")
  1478. line = transform[i,:]
  1479. # f.write(struct.pack('>I', len(line)))
  1480. #f.write(str(len(line)))
  1481. f.write('{:0.3f} '.format(time.time()))
  1482. #data = pArr('d', line)
  1483. #data.tofile(f)
  1484. for e in line:
  1485. f.write("%s "%np.absolute(e))
  1486. f.write("\n")
  1487. f.close()
  1488. def stop_acquisition(self):
  1489. self.timer.stop()
  1490. self.enable_acquisition_input()
  1491. self.continuous_read_checkbox.setEnabled(True)
  1492. self.acquisition_progressbar.reset()
  1493. def on_acquire(self):
  1494. self.disable_acquisition_input()
  1495. self.continuous_read_checkbox.setEnabled(False)
  1496. self.stop_button.setEnabled(True)
  1497. self.timer = QtCore.QTimer()
  1498. num_acquisitions = self.acquisitions_spinbox.value()
  1499. self.acquisition_progressbar.setRange(1, num_acquisitions)
  1500. spectrogram_dir = "./spectrograms_{:0.3f}".format(time.time())
  1501. if self.spectrogram_checkbox.isChecked():
  1502. os.mkdir(spectrogram_dir)
  1503. # We increase already once because we do a single acquisition before the
  1504. # timer is started, otherwise we have to wait until the timer fires the
  1505. # first time.
  1506. self.current_acquisition = 1
  1507. self.read_data_and_safe()
  1508. if self.spectrogram_checkbox.isChecked():
  1509. self.iterate_spectrograms(spectrogram_dir)
  1510. def on_timeout():
  1511. if self.current_acquisition < num_acquisitions:
  1512. self.current_acquisition += 1
  1513. self.acquisition_progressbar.setValue(self.current_acquisition)
  1514. self.read_data_and_safe()
  1515. self.iterate_spectrograms(spectrogram_dir)
  1516. else:
  1517. self.stop_acquisition()
  1518. self.timer.timeout.connect(on_timeout)
  1519. self.timer.start(self.wait_time_spinbox.value() * 1000)
  1520. def on_stop(self):
  1521. self.stop_acquisition()
  1522. def on_scan(self):
  1523. c_frm = self.time_scan_coarse_from.value()
  1524. c_to = self.time_scan_coarse_to.value()
  1525. if c_frm > c_to:
  1526. logging.info('Coarse Scan Interval is invalid: (%i > %i)' % (c_frm, c_to))
  1527. return
  1528. f_frm = self.time_scan_fine_from.value()
  1529. f_to = self.time_scan_fine_to.value()
  1530. if f_frm > f_to:
  1531. logging.info('Fine Scan Interval is invalid: (%i > %i)' % (f_frm, f_to))
  1532. return
  1533. self.disable_acquisition_input()
  1534. self.continuous_read_checkbox.setEnabled(False)
  1535. self.scan_button.setEnabled(False)
  1536. self.set_adc_delay_spinboxes_active(False)
  1537. self.canvas.figure.clear()
  1538. th_old = self.board_config.get('th_delay')
  1539. adc_1_old = self.board_config.get('adc_1_delay')
  1540. adc_2_old = self.board_config.get('adc_2_delay')
  1541. adc_3_old = self.board_config.get('adc_3_delay')
  1542. adc_4_old = self.board_config.get('adc_4_delay')
  1543. minimum = [None, None, None, None]
  1544. maximum = np.zeros((4, 3))
  1545. heatmap = np.zeros((4, (f_to - f_frm + 1), (c_to - c_frm + 1)))
  1546. self.timescan_progressbar.setRange(1, ((f_to - f_frm) + 1) * ((c_to - c_frm) + 1))
  1547. self.stop_requested = False
  1548. def time_scan_stop():
  1549. self.stop_requested = True
  1550. self.board_config.set_delay(th_old)
  1551. self.board_config.set_chip_delay([0, 1, 2, 3], [adc_1_old, adc_2_old, adc_3_old, adc_4_old])
  1552. self.enable_acquisition_input()
  1553. self.continuous_read_checkbox.setEnabled(True)
  1554. self.scan_button.setEnabled(True)
  1555. self.scan_stop_button.setEnabled(False)
  1556. self.set_adc_delay_spinboxes_active(True)
  1557. self.timescan_progressbar.reset()
  1558. self.scan_stop_button.clicked.connect(time_scan_stop)
  1559. self.scan_stop_button.setEnabled(True)
  1560. c_step = 0
  1561. for coarse in range(c_frm, c_to + 1):
  1562. try:
  1563. self.board_config.set_delay(coarse)
  1564. except heb.board.BoardError as e:
  1565. QtGui.QMessageBox.critical(self, "Board communication", str(e))
  1566. time_scan_stop()
  1567. return
  1568. f_step = 0
  1569. for fine in range(f_frm, f_to + 1):
  1570. self.board_config.set_chip_delay([0, 1, 2, 3], [fine, fine, fine, fine])
  1571. try:
  1572. if self.simulate_checkbox.isChecked() is True:
  1573. heb.board.start_pilot_bunch_emulator()
  1574. heb.board.start_acquisition()
  1575. heb.board.wait_for_revolutions()
  1576. heb.board.stop_acquisition()
  1577. heb.board.enable_transfer()
  1578. cmd = ['pci', '-r', 'dma0', '-o', '/dev/stdout', '--multipacket']
  1579. data_raw = heb.board.safe_call(cmd)
  1580. heb.board.flush_dma()
  1581. #Sadly, the PCI software also outputs the Information, that it has written data to the desired file.
  1582. #This is recorded by our software and needs to be removed, so we split the returned string at the
  1583. # "Writting data to file blah, blah" string.
  1584. #Btw: YES this 'Writting' is actually correct. Its a typo in the 'pci' driver...
  1585. data_split = data_raw.split('Writting')[0]
  1586. data = heb.io.read_from_string(data_split, force=True, cache=False)
  1587. except heb.board.BoardError as e:
  1588. QtGui.QMessageBox.critical(self, "Board communication", str(e))
  1589. time_scan_stop()
  1590. return
  1591. for adc in range(4):
  1592. buckets = data.array[:, adc:adc+1].reshape(-1)
  1593. heatmap[adc, f_step, c_step] = float(buckets.sum())/buckets.shape[0]
  1594. if heatmap[adc, f_step, c_step] > maximum[adc, 0]:
  1595. maximum[adc, 0] = heatmap[adc, f_step, c_step]
  1596. maximum[adc, 1] = coarse
  1597. maximum[adc, 2] = fine
  1598. if minimum[adc] is None or minimum[adc] > heatmap[adc, f_step, c_step]:
  1599. minimum[adc] = heatmap[adc, f_step, c_step]
  1600. self.timescan_progressbar.setValue(((c_step * (f_to - f_frm + 1)) + f_step) + 1)
  1601. #GUI is blocked in our tight loop. Give it an opportunity to handle events
  1602. QtGui.QApplication.processEvents()
  1603. if self.stop_requested is True:
  1604. # Time Scan Stop is already performed by button press. Nothing else to do but leave
  1605. return
  1606. f_step += 1
  1607. c_step += 1
  1608. self.canvas.figure.clear()
  1609. self.canvas.figure.suptitle("Timing Analysis")
  1610. if True:
  1611. now = time.time()
  1612. filename = 'timescan_{:0.3f}.out'.format(now)
  1613. f = open(filename, 'wr')
  1614. for adc in range(4):
  1615. if True:
  1616. f.write("#ADC_%s\n" % adc)
  1617. for coarse, curr_cor in enumerate(np.transpose(heatmap[adc])):
  1618. for fine, value in enumerate(curr_cor):
  1619. f.write("%i;%i;%f\n" % ((coarse+c_frm), (fine+f_frm), value))
  1620. f.write('\n')
  1621. axis = self.canvas.figure.add_subplot(2, 2, adc+1)
  1622. image = axis.imshow(heatmap[adc, :, :], interpolation='nearest', aspect='auto')
  1623. axis.set_xticks(range((c_to - c_frm) + 1))
  1624. axis.set_xticklabels(range(c_frm, c_to + 1))
  1625. axis.set_yticks(range((f_to - f_frm) + 1))
  1626. axis.set_yticklabels(range(f_frm, f_to + 1))
  1627. axis.invert_yaxis()
  1628. if adc > 1:
  1629. axis.set_xlabel('Coarse Delay')
  1630. if adc is 0 or adc is 2:
  1631. axis.set_ylabel('Fine Delay')
  1632. axis.set_title("ADC_%i, C:%i, F:%i" % (adc+1, maximum[adc, 1], maximum[adc, 2]))
  1633. if True:
  1634. f.close()
  1635. f = open(filename+'.gnuplot', 'wr')
  1636. f.write('set datafile separator ";"\n')
  1637. f.write('set multiplot layout 2,2\n')
  1638. f.write('unset key\n')
  1639. for i in range(4):
  1640. f.write('set label 1 "ADC_%i" at graph 0.7,0.95 font ",8"\n'%(i+1))
  1641. f.write('plot "%s" every :::%i::%i using 3 with lines\n'%(filename, i, i))
  1642. f.write('unset multiplot\n')
  1643. f.close()
  1644. bar_axis = self.canvas.figure.add_axes([0.85, 0.15, 0.05, 0.7])
  1645. self.canvas.figure.subplots_adjust(right=0.8)
  1646. self.canvas.figure.colorbar(image, cax=bar_axis)
  1647. self.canvas.draw()
  1648. time_scan_stop()
  1649. def on_to_changed(self, value):
  1650. if value > 0:
  1651. self.from_spinbox.setMaximum(value - 1)
  1652. self.on_option_change()
  1653. def on_option_change(self):
  1654. frm = self.from_spinbox.value()
  1655. to = self.to_spinbox.value()
  1656. enable_wait_cursor()
  1657. self.canvas.update_figure(self.opt_widgets, self.data, frm, to)
  1658. disable_wait_cursor()
  1659. def on_adc_delay_changed(self):
  1660. try:
  1661. self.board_config.set_delay(self.th_delay_spinbox.value())
  1662. factors = [self.adc_1_delay_spinbox.value(), self.adc_2_delay_spinbox.value(),
  1663. self.adc_3_delay_spinbox.value(), self.adc_4_delay_spinbox.value()]
  1664. self.board_config.set_chip_delay([0, 1, 2, 3], factors)
  1665. except heb.board.BoardError as e:
  1666. logging.error("ADC fine delay failed: {}".format(str(e)))
  1667. self.do_status_readout()
  1668. return
  1669. def on_number_of_orbits_changed(self):
  1670. number = self.number_of_orbits_spinbox.value()
  1671. hex_str = hex(number)
  1672. try:
  1673. heb.board.write_pci(hex_str, '0x9020')
  1674. except heb.board.BoardError as e:
  1675. logging.error("Setting orbits failed: {}".format(str(e)))
  1676. self.do_status_readout()
  1677. return
  1678. def on_number_of_skipped_orbits_changed(self):
  1679. number = self.number_of_skipped_orbits_spinbox.value()
  1680. hex_str = hex(number)
  1681. try:
  1682. heb.board.write_pci(hex_str, '0x9028')
  1683. except heb.board.BoardError as e:
  1684. logging.error("Could not set ob skipped orbits due to an error!")
  1685. self.do_status_readout()
  1686. return
  1687. def on_open(self):
  1688. filename = QtGui.QFileDialog.getOpenFileName(self, 'Open Datafile', '')
  1689. if filename:
  1690. self.read_and_update_data_from_file(filename)
  1691. def on_open_config(self):
  1692. filename = QtGui.QFileDialog.getOpenFileName(self, 'Open Configuration', '')
  1693. if filename:
  1694. self.board_config.load_config(filename)
  1695. self.on_set_defaults()
  1696. def on_save_config(self):
  1697. filename = QtGui.QFileDialog.getSaveFileName(self, 'Save Configuration', '')
  1698. if filename:
  1699. self.board_config.save_config(filename)
  1700. def on_close(self):
  1701. self.close()
  1702. def main():
  1703. parser = argparse.ArgumentParser()
  1704. parser.add_argument('-i', '--input', metavar='FILE', type=str,
  1705. help="HEB file")
  1706. parser.add_argument('-c', '--config', metavar='FILE', type=str,
  1707. help="Board Configuration File")
  1708. parser.add_argument('--force-read', action='store_true',
  1709. help="Ignore cache and force re-computation.")
  1710. parser.add_argument('--check', action='store_true',
  1711. help="Check contents of file before proceeding")
  1712. parser.add_argument('--cache-data', action='store_true',
  1713. help="Save already processed NumPy arrays")
  1714. parser.add_argument('-v', '--verbose', action='store_true',
  1715. help="Increase verbosity.")
  1716. args = parser.parse_args()
  1717. if args.verbose:
  1718. logging.basicConfig(level=logging.DEBUG)
  1719. else:
  1720. logging.basicConfig(level=logging.INFO)
  1721. app = QtGui.QApplication(sys.argv)
  1722. window = ApplicationWindow(args)
  1723. window.show()
  1724. try:
  1725. window.do_status_readout()
  1726. except heb.board.BoardError as e:
  1727. QtGui.QMessageBox.critical(window, "Board Communication Error",
  1728. "Could not communicate with the Board!\nError was: 'pci' " + str(e)
  1729. + "\nMake sure the HEB Board is connected correctly and run 'Check Status'.")
  1730. sys.exit(app.exec_())
  1731. if __name__ == '__main__':
  1732. main()