12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196 |
- """
- This Module implements the Plot Windows used in KCG
- """
- import pyqtgraph as pg
- try: # on some versions of pyqtgraph useOpenGl is no valid option
- pg.setConfigOption('useOpenGl', True)
- except:
- print('op GL not valid')
- pass
- pg.setConfigOption('background', 'w')
- pg.setConfigOption('foreground', 'k')
- import numpy as np
- from PyQt4 import QtCore, QtGui
- from PyQt4.QtGui import QColor
- from scipy.optimize import curve_fit
- import time
- import traceback
- from ..base.groupedelements import live_plot_windows
- from ..base.backend.DataSet import DataSet
- from ..base.backend import board
- from ..base.backend.board import available_boards
- from ..config import colours, coloursTrans
- from ..base import kcgwidget as kcgw
- from .. import config
- tr = kcgw.tr
- LIVE = 1
- FILE = 2
- ERROR = 99
- NO_DATA = 98
- class Enum():
- """
- Simple Enum Class (as this is not supported by clean python)
- """
- def __init__(self, *args):
- self.idx = 0
- for i in args:
- setattr(self, i, self.idx)
- self.idx += 1
- plotList = [tr("Label", "Heatmap"), tr("Label", "FFT"), tr("Label", "Trains"), tr("Label", "Combined"), tr("Label", "Compare"), "Peak"]
- PlotType = Enum(*[str(i) for i in plotList])
- # gradient = {'mode': 'rgb',
- # 'ticks': [(0.0, (0.37281, 0.11883, 3.53583, 255)),
- # (0.0390625, (4.9401150000000005, 3.858915, 22.635585, 255)),
- # (0.078125, (15.6417, 9.330449999999999, 45.29871, 255)),
- # (0.1171875, (29.74728, 12.13137, 69.44185499999999, 255)),
- # (0.15625, (46.774395000000005, 10.283895, 90.51760499999999, 255)),
- # (0.1953125, (64.1631, 9.614775, 102.86139, 255)),
- # (0.234375, (80.65191, 13.63995, 108.40458, 255)),
- # (0.2734375, (96.64525499999999, 19.444515, 110.343345, 255)),
- # (0.3125, (112.507785, 25.33119, 110.05646999999999, 255)),
- # (0.3515625, (128.390715, 31.001625, 107.95578, 255)),
- # (0.390625, (144.29277, 36.609585, 104.10579, 255)),
- # (0.4296875, (160.100985, 42.476625, 98.50038, 255)),
- # (0.46875, (175.606515, 49.020945, 91.188765, 255)),
- # (0.5078125, (190.517385, 56.70639, 82.32827999999999, 255)),
- # (0.546875, (204.477105, 65.96187, 72.190245, 255)),
- # (0.5859375, (217.10292, 77.07629999999999, 61.10718, 255)),
- # (0.625, (228.047775, 90.11674500000001, 49.36392, 255)),
- # (0.6640625, (237.05922, 104.927145, 37.068585, 255)),
- # (0.703125, (243.99726, 121.21578, 24.147225, 255)),
- # (0.7421875, (248.797635, 138.66849, 11.122589999999999, 255)),
- # (0.78125, (251.41776000000002, 157.01625, 6.52596, 255)),
- # (0.8203125, (251.80332, 176.04333, 20.397450000000003, 255)),
- # (0.859375, (249.90816, 195.543435, 42.420015, 255)),
- # (0.8984375, (245.92047, 215.18124, 69.714705, 255)),
- # (0.9375, (241.63647, 233.936745, 104.719575, 255)),
- # (0.9765625, (245.26206, 248.86062, 145.840875, 255)),
- # (0.99609375, (252.03231, 254.58282, 164.45562, 255))]}
- gradient = {'mode': 'rgb',
- 'ticks': [(0.0, (0.37281, 0.11883, 3.53583, 255)),
- (0.1171875, (29.74728, 12.13137, 69.44185499999999, 255)),
- (0.234375, (80.65191, 13.63995, 108.40458, 255)),
- (0.3515625, (128.390715, 31.001625, 107.95578, 255)),
- (0.46875, (175.606515, 49.020945, 91.188765, 255)),
- (0.5859375, (217.10292, 77.07629999999999, 61.10718, 255)),
- (0.703125, (243.99726, 121.21578, 24.147225, 255)),
- (0.8203125, (251.80332, 176.04333, 20.397450000000003, 255)),
- (0.9375, (241.63647, 233.936745, 104.719575, 255)),
- (0.99609375, (252.03231, 254.58282, 164.45562, 255))]}
- class CustomGradientEditorItem(pg.GradientEditorItem):
- """
- A Gradient Editor Item to insert a perception linear gradient
- """
- def __init__(self, **kwargs):
- pg.GradientEditorItem.__init__(self, **kwargs)
- self.customGradients = {}
- def addGrad(self, name, grad_dic):
- """
- Add a gradient to the list of gradients in the gui
- :param name: the name of the gradient
- :param grad_dic: the dictionary containing the gradient data
- """
- if name not in self.customGradients:
- self.customGradients[name] = grad_dic
- px = QtGui.QPixmap(100, 15)
- p = QtGui.QPainter(px)
- self.restoreState(grad_dic)
- length_backup = self.length
- self.length = 100
- grad = self.getGradient()
- self.length = length_backup
- brush = QtGui.QBrush(grad)
- p.fillRect(QtCore.QRect(0, 0, 100, 15), brush)
- p.end()
- label = QtGui.QLabel()
- label.setPixmap(px)
- label.setContentsMargins(1, 1, 1, 1)
- act = QtGui.QWidgetAction(self)
- act.setDefaultWidget(label)
- act.triggered.connect(self.contextMenuClicked)
- act.name = name
- if len(self.customGradients) > 1:
- self.menu.insertAction(self.menu.actions()[0], act)
- else:
- sep = self.menu.insertSeparator(self.menu.actions()[0])
- self.menu.insertAction(sep, act)
- self.restoreState(grad_dic)
- def restoreState(self, state):
- """
- Reimplemented of pyqtgraph.GradientEditorItem.restoreState to work with our custom perception linear gradient.
- :param state: the state to restore to
- """
- self.setColorMode(state['mode'])
- for t in list(self.ticks.keys()):
- self.removeTick(t, finish=False)
- self.bottomTick = [None, 10]
- self.topmostTick = [None, -1]
- for t in state['ticks']:
- c = QtGui.QColor(*t[1])
- tick = self.addTick(t[0], c, finish=False)
- if t[0] < self.bottomTick[1]:
- self.bottomTick = [tick, t[0]]
- if t[0] > self.topmostTick[1]:
- self.topmostTick = [tick, t[0]]
- self.tickPosInPercent = self.ticks.copy()
- for t in self.ticks:
- if t is self.topmostTick[0] or t is self.bottomTick[0]:
- continue
- t.hide()
- t.movable = False
- # self.bottomTick[1] *= self.length
- # self.topmostTick[1] *= self.length
- self.updateGradient()
- self.sigGradientChangeFinished.emit(self)
- def loadPreset(self, name):
- """
- Reimplemented of pyqtgraph.GradientEditorItem.loadPreset to work with our custom perception linear gradient.
- :param name: the name of the preset to load
- """
- if name in self.customGradients:
- self.restoreState(self.customGradients[name])
- else:
- super(CustomGradientEditorItem, self).loadPreset(name)
- def tickMoved(self, tick, pos):
- """
- Reimplemented of pyqtgraph.GradientEditorItem.tickMoved to work with our custom perception linear gradient,
- which has a lot of steps which would create a lot of ticks in the gradient legend. This removes all but 2
- ticks and aligns all the internal ticks accordingly.
- :param tick: the tick to move
- :param pos: the position to move to
- """
- if tick is self.bottomTick[0]:
- # self.bottomTick[1] = pos.x()
- pg.TickSliderItem.tickMoved(self, tick, pos)
- elif tick is self.topmostTick[0]:
- # self.topmostTick[1] = pos.x()
- pg.TickSliderItem.tickMoved(self, tick, pos)
- if tick in [self.bottomTick[0], self.topmostTick[0]]: # if bottom or topmost tick was moved
- if pos.x() < self.length and pos.x() > 0: # if tick is not at top or bottom
- newUnit = (self.topmostTick[0].pos().x() - self.bottomTick[0].pos().x()) # create new virtual unit length
- for t in self.ticks: # for every tick
- if t not in [self.bottomTick[0], self.topmostTick[0]]: # if tick is not bottom or topmost tick
- pos = t.pos()
- new_x = self.bottomTick[0].pos().x() + self.tickPosInPercent[t] * newUnit
- pos.setX(new_x)
- t.setPos(pos)
- pg.TickSliderItem.tickMoved(self, t, pos)
- self.updateGradient()
- # .d8888b. 888 .d8888b. 888
- # d88P Y88b 888 d88P Y88b 888
- # Y88b. 888 888 888 888
- # "Y888b. 88888b. .d88b. .d8888b888888888d888 .d88b. .d88b. 888d888 8888b. 88888b.d88b. 888 .d88b. 888 .d88b. 888d888
- # "Y88b.888 "88bd8P Y8bd88P" 888 888P" d88""88bd88P"88b888P" "88b888 "888 "88b888 d88""88b888d88""88b888P"
- # "888888 88888888888888 888 888 888 888888 888888 .d888888888 888 888888 888888 888888888 888888
- # Y88b d88P888 d88PY8b. Y88b. Y88b. 888 Y88..88PY88b 888888 888 888888 888 888Y88b d88PY88..88P888Y88..88P888
- # "Y8888P" 88888P" "Y8888 "Y8888P "Y888888 "Y88P" "Y88888888 "Y888888888 888 888 "Y8888P" "Y88P" 888 "Y88P" 888
- # 888 888
- # 888 Y8b d88P
- # 888 "Y88P"
- #
- class SpectrogramColorLegendItem(pg.GraphicsWidget):
- """
- The Item used as Legend for Heatmap and FFT Plot
- """
- gradientChanged = QtCore.pyqtSignal()
- def __init__(self, img=None):
- """
- Initialise the Legend
- :param img: (ImageItem) the image item this is the legend for
- :return: -
- """
- super(SpectrogramColorLegendItem, self).__init__()
- self.layout = QtGui.QGraphicsGridLayout()
- self.setLayout(self.layout)
- self.img = img
- # self.gei = pg.GradientEditorItem(orientation='right')
- self.gei = CustomGradientEditorItem(orientation='right', allowAdd=False)
- self.legend_axis = pg.AxisItem(orientation='left')
- # self.addItem(self.legend_axis)
- self.layout.addItem(self.legend_axis, 0, 0, alignment=QtCore.Qt.AlignVCenter)
- # self.addItem(self.gei)
- self.layout.addItem(self.gei, 0, 1)
- self.gei.sigGradientChanged.connect(self.gradient_changed)
- # self.gei.loadPreset('spectrum')
- self.gei.addGrad('inferno', gradient)
- # self.setFixedWidth(80)
- self.image_changed()
- def gradient_changed(self):
- """
- Proxy function for the gradient_cnahged event of the GradientEditorItem
- :return:
- """
- self.gradientChanged.emit()
- def set_image(self, img):
- """
- Set the Image this is the legend for (only needed if not already done upon initialisation)
- :param img: (ImageItem) The image item to use
- :return: -
- """
- self.img = img
- self.image_changed(True)
- def update_axis(self):
- """
- Update the axis of this legend
- :return: -
- """
- if self.img.getLevels() is not None:
- # min, max = self.img.getLevels()
- min, max = (np.min(self.img.image), np.max(self.img.image))
- self.legend_axis.setRange(min, max)
- def reset_gradient(self):
- """
- Reset the gradient to the preset "spectrum"
- :return: -
- """
- # self.gei.loadPreset('spectrum')
- self.gei.loadPreset('inferno')
- # self.gei.restoreState(gradient)
- def image_changed(self, reset_gradient=True):
- """
- Call this to adjust the legend when the image has changed
- :param reset_gradient: (bool) whether to reset the gradient or not
- :return:
- """
- if self.img:
- self.update_axis()
- if reset_gradient:
- self.reset_gradient()
- def getLookupTable(self, nPts, alpha=None):
- """
- Get the look up table of the imageitem
- :param nPts: (int) number of points the lookup table is defined on
- :param alpha: ??
- :return: -
- """
- return self.gei.getLookupTable(nPts, alpha=alpha)
- def resizeEvent(self, event):
- """
- Handle resizing of the window
- """
- self.legend_axis.setHeight(self.gei.length)
- # .d8888b. 888 8888888b. 888 888 888 888d8b 888 888
- # d88P Y88b 888 888 Y88b888 888 888 o 888Y8P 888 888
- # Y88b. 888 888 888888 888 888 d8b 888 888 888
- # "Y888b. 888 88888888b. 888 d88P888 .d88b. 888888888 d888b 888888 .d88888 .d88b. .d88b. 888888
- # "Y88b.888 888888 "88b8888888P" 888d88""88b888 888d88888b888888d88" 888d88P"88bd8P Y8b888
- # "888888 888888 888888 888888 888888 88888P Y88888888888 888888 88888888888888
- # Y88b d88PY88b 888888 d88P888 888Y88..88PY88b. 8888P Y8888888Y88b 888Y88b 888Y8b. Y88b.
- # "Y8888P" "Y8888888888P" 888 888 "Y88P" "Y888888P Y888888 "Y88888 "Y88888 "Y8888 "Y888
- # 888
- # Y8b d88P
- # "Y88P"
- #
- class SubPlotWidget(pg.GraphicsLayoutWidget):
- """
- The Widget actually containing the plots and images
- """
- def __init__(self, dType=FILE):
- super(SubPlotWidget, self).__init__()
- self.dType = dType
- self.adc_number = board.get_board_config(available_boards[0]).get('adc_number')
- self._type_changed = False
- # self.setStyleSheet("border: 5px solid black; margin: 10px;")
- self.plotType = 1
- self.fft_mode = 0
- self.plotItem = pg.PlotItem()
- self.img = pg.ImageItem()
- self.plotItem2 = pg.PlotItem()
- self.img2 = pg.ImageItem()
- self.plotItem2.addItem(self.img2)
- self.setFrameStyle(self.StyledPanel | self.Sunken)
- self.gradient_legend = SpectrogramColorLegendItem(self.img)
- def changelut():
- """
- Handle changing of the lookup table
- """
- self.img.setLookupTable(self.gradient_legend.getLookupTable(512))
- self.img2.setLookupTable(self.gradient_legend.getLookupTable(512))
- self.gradient_legend.gradientChanged.connect(changelut)
- self.addItem(self.plotItem)
- self.plotItem.addItem(self.img)
- self.plotItemPlotScatter = pg.PlotDataItem(pen=None, symbolPen=pg.mkPen(50, 50, 255), symbolSize=3, pxMode=True, symbolBrush=pg.mkBrush(50, 50, 255), downsample=200)
- self.plotItemPlotScatter1 = pg.PlotDataItem(pen=None, symbolPen=pg.mkPen(255, 50, 50), symbolSize=3, pxMode=True, symbolBrush=pg.mkBrush(255, 50, 50), downsample=200)
- self.plotItemFit = []
- # self.plotItemPlotScatter2 = pg.PlotDataItem(pen=None, symbolPen=pg.mkPen(50, 255, 50), symbolSize=3, pxMode=True, symbolBrush=pg.mkBrush(50, 255, 50), downsample=200)
- self.plotItemPlot = [] #pg.PlotDataItem() # pen="#000000")
- #col = [QColor(44, 62, 80), QColor(39, 174, 96), QColor(143, 156, 18), QColor(192, 57, 43), QColor(41, 128, 185), QColor(142, 68, 173), QColor(22, 160, 133,150), QColor(127, 140, 141)]
- style = [QtCore.Qt.SolidLine, QtCore.Qt.DashLine, QtCore.Qt.DotLine, QtCore.Qt.DashDotLine, QtCore.Qt.DashLine, QtCore.Qt.DotLine, QtCore.Qt.DashDotLine, QtCore.Qt.DashLine]
- for i in range(self.adc_number):
- self.plotItemPlot.append(pg.PlotDataItem(pen=pg.mkPen(colours[i], width=0.5, style=style[i]), autoDownsample=True, clipToView=True ) )#, symbolPen=pg.mkPen(col[i], width=1, style=style[i]), symbolSize=2))##, pxMode=True))
- self.plotItem.addItem(self.plotItemPlot[i])
- self.plotItem.addItem(self.plotItemPlotScatter)
- self.plotItem.addItem(self.plotItemPlotScatter1)
- # self.plotItem.addItem(self.plotItemPlotScatter2)
- self.plotItem.vb.origAutoRange = self.plotItem.vb.autoRange
- self.error_label = pg.LabelItem("Error during plot.", color=(200, 50, 50))
- self.error_label.hide()
- self.error_label.scale(1, -0.6)
- self.error_label.translate(0, -30)
- self.plotItem.addItem(self.error_label)
- self.no_data_label = pg.LabelItem("No data to plot.", color=(200, 50, 50))
- self.no_data_label.hide()
- self.no_data_label.scale(1, -0.6)
- self.no_data_label.translate(0, -30)
- self.plotItem.addItem(self.no_data_label)
- def _enableCustomAutoRange(self, data, lendata=0):
- """
- Enable custom auto range in this plot
- :param data: the data to autorange
- :return:
- """
- def newAutoRange(*args, **kwargs):
- ''' function to handle the new autorange '''
- xmax = lendata
- if lendata == 0:
- if len(data) == 0:
- return
- xmax = len(data)
- if self.plotType == PlotType.Combined:
- xmax /= self.adc_number
- if self.plotType == PlotType.Peak:
- xmax = 184
- bounds = [np.min(data), np.max(data)]
- self.plotItem.vb.setRange(xRange=[0, xmax],
- yRange=[bounds[0]-0.1*(bounds[1]-bounds[0])-1, bounds[1]+0.1*(bounds[1]-bounds[0])+1], update=True)
- self.plotItem.update()
- self.plotItem.vb.autoRange = newAutoRange
- self.plotItem.autoBtn.clicked.disconnect()
- self.plotItem.autoBtn.clicked.connect(newAutoRange)
- def _disableCustomAutoRange(self):
- """
- Disable the custom autorange and reset it to default
- :return: -
- """
- self.plotItem.vb.autoRange = self.plotItem.vb.origAutoRange
- self.plotItem.autoBtn.clicked.disconnect()
- self.plotItem.autoBtn.clicked.connect(self.plotItem.autoBtnClicked)
- @QtCore.pyqtSlot(np.ndarray, tuple, tuple)
- def plot(self, data, xvalueborders=None, yvalueborders=None, autorange=True, fft_mode=0, log=False, doFit=0):
- """
- Plot Data. The plot type depends on the type property
- :param data: (dataset.DataSet) data to plot
- :param xvalueborders: (touple) the borders for the xvalues
- :param yvalueborders: (touple) the borders for the yvalues
- :param autorange: (bool) whether to perform a autorange or not
- :return: -
- """
- self.error_label.hide()
- self.no_data_label.hide()
- for item in self.plotItemPlot:
- item.clear()
- item.hide()
- self.plotItemPlotScatter.clear()
- self.plotItemPlotScatter1.clear()
- for item in self.plotItemFit:
- item.clear()
- #self.plotItemPlotScatter2.clear()
- #self.plotItem.resetTransform()
- #self.plotItem.getAxis('bottom').setScale()
-
- self.img.clear()
- self.img2.clear()
- self.img.hide()
- self.img2.hide()
-
- self.gradient_legend.hide()
- try:
- self.removeItem(self.gradient_legend)
- pass
- except Exception as e:
- if not "Could not determine index of item" in str(e):
- raise
-
- if self._type_changed:
- #self.plotItem.autoBtnClicked()
- pass
- try:
- self.removeItem(self.plotItem2)
- except Exception as e:
- if "Could not determine index of item" in str(e):
- pass
- else:
- raise
- if self.plotType == PlotType.FFT:
- self.fft_mode = fft_mode
- if fft_mode:
- if len(data) > 9:
- data = [data]
- maxv = 0
- minv = 400000
- for i in range(len(data)):
- if len(data[i]) < 10:
- continue
- self.plotItemPlot[i].show()
- dat = np.abs(data[i]).transpose()
- if fft_mode == 1:
- dat = np.abs(data[i])
- elif fft_mode == 2:
- dat = np.mean(dat,1)
- else:
- dat = dat[:,fft_mode-2]
- if log:
- dat=np.log(dat)
- self.plotItemPlot[i].setData(dat)
- v = np.max(dat)
- if maxv < v:
- maxv = v
- v = np.min(dat)
- if minv > v:
- minv = v
- """
- if fft_mode == 1:
- dat = np.mean(data,1)
- else:
- dat = data[:,fft_mode-2]
- self.plotItemPlot[0].show()
- self.plotItemPlot[0].setData(dat)
- """
- if xvalueborders:
- self.plotItem.getAxis('bottom').setScale((xvalueborders[1]-xvalueborders[0])/float(dat.shape[0]))
- self._enableCustomAutoRange([maxv, minv], lendata=len(dat))
- else:
- if len(data) < 9:
- data= data[0]
- data = np.abs(data).transpose()
-
- self.addItem(self.gradient_legend)
- self.gradient_legend.show()
- self.img.show()
- self.img.setImage(data, scale=[1, 1/1000.])
- self.img.resetTransform()
- self.img.setAutoDownsample(True)
- if autorange:
- self.gradient_legend.image_changed()
- if xvalueborders:
- self.plotItem.getAxis('bottom').setScale((xvalueborders[1]-xvalueborders[0])/float(data.shape[0]))
- self.img.translate(xvalueborders[0]/self.plotItem.getAxis('bottom').scale, 0)
- else:
- self.plotItem.getAxis('bottom').setScale()
- if yvalueborders:
- self.img.translate(0, yvalueborders[0])
- self.plotItem.getAxis('left').setScale(yvalueborders[1]/float(data.shape[1]))
- self._disableCustomAutoRange()
- self.plotItem.setClipToView(True)
- if self.plotType == PlotType.Heatmap:
-
- self.addItem(self.gradient_legend)
- self.gradient_legend.show()
- self.img.show()
- self.img.setImage(data, scale=[1, 1/1000.])
- self.img.resetTransform()
- self.img.setAutoDownsample(True)
- if autorange:
- self.gradient_legend.image_changed()
- if xvalueborders:
- self.plotItem.getAxis('bottom').setScale((xvalueborders[1]-xvalueborders[0])/float(data.shape[0]))
- self.img.translate(xvalueborders[0]/self.plotItem.getAxis('bottom').scale, 0)
- else:
- self.plotItem.getAxis('bottom').setScale()
- if yvalueborders:
- self.img.translate(0, yvalueborders[0])
- self.plotItem.getAxis('left').setScale(yvalueborders[1]/float(data.shape[1]))
- self._disableCustomAutoRange()
- self.plotItem.setClipToView(True)
- if self.plotType == PlotType.Compare:
- self.addItem(self.plotItem2)
- self.plotItem2.vb.linkView(self.plotItem2.vb.XAxis, self.plotItem.vb)
- self.plotItem2.vb.linkView(self.plotItem2.vb.YAxis, self.plotItem.vb)
- self.addItem(self.gradient_legend)
- self.gradient_legend.show()
- self.img.setImage(data[0], scale=[1, 1/1000.])
- self.img.show()
- self.img.resetTransform()
- self.img2.setImage(data[1], scale=[1, 1/1000.])
- self.img2.show()
- self.img2.resetTransform()
- self.img.setAutoDownsample(True)
- self.img2.setAutoDownsample(True)
- if autorange:
- self.gradient_legend.image_changed()
- pass
- if xvalueborders:
- self.plotItem.getAxis('bottom').setScale((xvalueborders[1]-xvalueborders[0])/float(data[0].shape[0]))
- self.plotItem2.getAxis('bottom').setScale((xvalueborders[1]-xvalueborders[0])/float(data[1].shape[0]))
- self.img.translate(xvalueborders[0]/self.plotItem.getAxis('bottom').scale, 0)
- self.img2.translate(xvalueborders[0]/self.plotItem.getAxis('bottom').scale, 0)
- else:
- self.plotItem.getAxis('bottom').setScale()
- self.plotItem2.getAxis('bottom').setScale()
- if yvalueborders:
- self.img.translate(0, yvalueborders[0])
- self.img2.translate(0, yvalueborders[0])
- self.plotItem.getAxis('left').setScale(yvalueborders[1]/float(data[0].shape[1]))
- self.plotItem2.getAxis('left').setScale(yvalueborders[1]/float(data[1].shape[1]))
- self._disableCustomAutoRange()
- self.plotItem.setClipToView(True)
- if self.plotType == PlotType.Trains:
-
- if len(data) < 9:
- maxv = 0
- minv = 4000
- maxl = 0
- for i in range(len(data)):
- if np.mean(data[i]) == 0:
- continue
- self.plotItemPlot[i].show()
- self.plotItemPlot[i].setData(data[i])
- l = len(data[i])
- if maxl < l:
- maxl = l
- v = np.max(data[i])
- if maxv < v:
- maxv = v
- v = np.min(data[i])
- if minv > v:
- minv = v
- self._enableCustomAutoRange([maxv, minv], lendata=maxl)
- else:
- self.plotItemPlot[0].show()
- self.plotItemPlot[0].setData(data)
- self._enableCustomAutoRange(data)
-
- if self.plotType in [PlotType.Combined]:
- self.img.clear()
- self.plotItemPlotScatter.show()
- self.plotItemPlotScatter1.show()
-
- self.plotItemPlotScatter.setData(data[0].transpose())
- self.plotItemPlotScatter1.setData(data[1].transpose())
- self._enableCustomAutoRange(data[0][1])
- self.plotItem.setClipToView(False) # NOTE: otherwise only a very small portion of data is visible :wonder:
- if self.plotType == PlotType.Peak:
- self.img.clear()
- self.plotItemPlotScatter.show()
- self.plotItemPlotScatter1.show()
-
- baseline = []
- if doFit > 0:
-
- x = np.reshape(data[0][0], (-1, doFit))
- y = np.reshape(data[0][1], (-1, doFit))
- valmax = np.max(y)
- valmin = np.min(y)
- positive = np.abs(valmax) > np.abs(valmin)
- #print('positive', positive)
-
- tmp = y.T
- for line in tmp:
- if positive:
- baseline.append(np.mean(line[np.where(line < 15)]))
- else:
- baseline.append(np.mean(line[np.where(line > -15)]))
-
- #print(baseline)
- y = y-baseline
-
- def gauss(x, sigma, mu, A):
- return A*np.exp(-0.5*((x-mu)/sigma)**2)
-
- fitx = np.linspace(np.min(x[0])*0.5, np.max(x[0])*1.5, 25)
- for i, line in enumerate(x):
- if len(self.plotItemFit) < i+1:
- item = pg.PlotDataItem(pen=pg.mkPen(QColor(192, 57, 43), width=0.5), autoDownsample=True, clipToView=True )
- self.plotItemFit.append(item)
- self.plotItem.addItem(item)
- if (np.mean(y[i]) < 15 and positive) or (np.mean(y[i]) > -15 and not positive):
- #if np.mean(y[i]) > 15*(1 if positive else -1):
- #print('skip ', i)
- continue
- try:
- #print(i)
- popt, pcov = curve_fit(gauss, x[i]-i%184, y[i])
- self.plotItemFit[i].setData(fitx+i%184, gauss(fitx, *popt))
- except:
- traceback.print_exc()
- pass
- if doFit:
- self.plotItemPlotScatter.setData(np.reshape(x,-1), np.reshape(y,-1))
- else:
- self.plotItemPlotScatter.setData(data[0].transpose())
- self.plotItemPlotScatter1.setData(data[1].transpose())
-
- self._enableCustomAutoRange(data[0][1])
- self.plotItem.setClipToView(False)
- if self.plotType == ERROR or self.plotType == NO_DATA:
- self.img.hide()
- self.gradient_legend.hide()
- self.img2.hide()
- #self.plotItemPlot.hide()
- self.plotItemPlotScatter.hide()
- self.plotItemPlotScatter1.hide()
- if self.plotType == ERROR:
- self.error_label.show()
- else:
- self.no_data_label.show()
-
- if autorange:
- self.plotItem.getViewBox().autoRange()
- self.labelAxes()
- if self.plotType in [PlotType.Heatmap, PlotType.Compare]:
- self.gradient_legend.update_axis()
- if self.plotType == PlotType.FFT and self.fft_mode == 0:
- self.gradient_legend.update_axis()
- def labelAxes(self):
- """
- Add Labels to the axis depending on the self.plotType property.
- :return: -
- """
- if self.plotType == PlotType.Heatmap:
- self.plotItem.setLabel('bottom', 'Turn', '')
- self.plotItem.setLabel('left', 'Bunch Position', '')
- elif self.plotType == PlotType.FFT:
- self.plotItem.setLabel('left', 'Bunch Position', '')
- self.plotItem.setLabel('bottom', 'Frequency', 'Hz')
- elif self.plotType == PlotType.Trains:
- self.plotItem.setLabel('left', '', '')
- self.plotItem.setLabel('bottom', 'Sample Point', '')
- elif self.plotType == PlotType.Combined:
- self.plotItem.setLabel('left', '', '')
- self.plotItem.setLabel('bottom', '', '')
- if self.plotType == PlotType.Compare:
- self.plotItem.setLabel('bottom', 'Turn', '')
- self.plotItem.setLabel('left', 'Bunch Position', '')
- self.plotItem2.setLabel('bottom', 'Turn', '')
- self.plotItem2.setLabel('left', 'Bunch Position', '')
- def changeType(self, type):
- """
- Change the plot Type
- :param type: (int) the new type
- :return: -
- """
- if type != self.plotType:
- self._type_changed = True
- self.plotType = type
- # if type in [PlotType.FFT, PlotType.Compare, PlotType.Heatmap]: # this will generate an error
- # self.gradient_legend.image_changed()
- # 8888888b. 888 888 888 888d8b 888 888
- # 888 Y88b888 888 888 o 888Y8P 888 888
- # 888 888888 888 888 d8b 888 888 888
- # 888 d88P888 .d88b. 888888888 d888b 888888 .d88888 .d88b. .d88b. 888888
- # 8888888P" 888d88""88b888 888d88888b888888d88" 888d88P"88bd8P Y8b888
- # 888 888888 888888 88888P Y88888888888 888888 88888888888888
- # 888 888Y88..88PY88b. 8888P Y8888888Y88b 888Y88b 888Y8b. Y88b.
- # 888 888 "Y88P" "Y888888P Y888888 "Y88888 "Y88888 "Y8888 "Y888
- # 888
- # Y8b d88P
- # "Y88P"
- #
- class PlotWidget(kcgw.KCGWidgets):
- """
- The container Class holding various buttons and controls and the actual plots as SubPlotWidgets instance
- """
- close_signal = QtCore.pyqtSignal()
- change_type_signal = QtCore.pyqtSignal(int, int, str)
- def __init__(self, board_id, parent=None, name=None, unique_id=None, type=None, datatype=None, prefix=None, fName=None, data=None):
- """
- Initialise the Plot Widgt
- :param parent: (QWidget) the parent widget
- :param name: (str) name of this widget
- :param unique_id: (int) unique id of this widget
- :param type: (int) type of this widget
- :param datatype: (int) datatype (LIVE or FILE)
- :param prefix: (str) prefix for text in the listview in LeftBar
- :param fName: (str) the filename (this is only used if datatype is FILE)
- :param data: (dataset.DataSet) the data to be plotted
- :return: -
- """
- super(PlotWidget, self).__init__()
- self.board_id = board_id
- self.board_config = board.get_board_config(available_boards[0])
- if name != None:
- self.theName = name
- if unique_id != None:
- self.theId = unique_id
- if type != None:
- self.theType = type
- self._old_type = type
- if datatype != None:
- self.theDataType = datatype
- if prefix != None:
- self.thePrefix = prefix
- if self.theDataType == FILE:
- self.fName = fName
- if self.theDataType == FILE:
- self.data = data
- else:
- self.data = None
- self.close_silent = False
- self.parent = parent
- self.adc = 1
- self.secadc = 2
- self._single_adc_checked = False
- self.initUI()
- self.changePlotType(self.theType) # initially mark the correct button
- self.setWindowTitle(self.theName + " - " + plotList[type] + " - " + str(self.thePrefix))
- if self.theDataType == FILE:
- self.plot(type)
- else:
- live_plot_windows.addWindow(board_id, self)
- if board.get_board_status(board_id).last_file is not None:
- self.data = DataSet(board.get_board_status(board_id).last_file, tRev=config.tRev, bunchesPerTurn=config.bunches_per_turn, shiftFMC2=config.shiftFMC2)
- self.plot(type)
- def initUI(self):
- """
- Initialise the UI
- :return: -
- """
- self.plot_widget = SubPlotWidget(dType=self.theDataType)
- self.layout = QtGui.QVBoxLayout()
- self.plot_buttons_layout = QtGui.QHBoxLayout()
- self.heatmap_button = self.createButton(text=tr("Button", "Heatmap"), connect=lambda: self.plot(type=PlotType.Heatmap))
- self.fft_button = self.createButton(text=tr("Button", "FFT"), connect=lambda: self.plot(type=PlotType.FFT))
- self.trains_button = self.createButton(text=tr("Button", "Trains"), connect=lambda: self.plot(type=PlotType.Trains))
- self.combined_button = self.createButton(text=tr("Button", "Combined"), connect=lambda: self.plot(type=PlotType.Combined))
- self.compare_button = self.createButton(text=tr("Button", "Compare"), connect=lambda: self.plot(type=PlotType.Compare))
- self.peak_button = self.createButton(text="Peak", connect=lambda: self.plot(type=PlotType.Peak))
- self.type_buttons = {PlotType.Heatmap:self.heatmap_button, PlotType.FFT:self.fft_button,
- PlotType.Trains:self.trains_button, PlotType.Combined:self.combined_button,
- PlotType.Compare:self.compare_button, PlotType.Peak:self.peak_button}
- self.defaultButtonStyleSheet = self.heatmap_button.styleSheet()
- self.plot_buttons_layout.addWidget(self.heatmap_button)
- self.plot_buttons_layout.addWidget(self.fft_button)
- self.plot_buttons_layout.addWidget(self.trains_button)
- self.plot_buttons_layout.addWidget(self.combined_button)
- self.plot_buttons_layout.addWidget(self.compare_button)
- self.plot_buttons_layout.addWidget(self.peak_button)
- self.adcCheckBox = []
- self.adc_checkbox_layout = QtGui.QHBoxLayout()
- self.group = QtGui.QButtonGroup()
- for i in range(int(self.board_config.get('adc_number'))):
- self.adcCheckBox.append(self.createCheckbox(text="ADC "+str(i+1), connect=self.change_adc, color=colours[i]))
- self.adc_checkbox_layout.addWidget(self.adcCheckBox[i])
- self.group.addButton(self.adcCheckBox[i], i+1)
-
- self.adcCheckBox[0].setChecked(True)
- self.groupWidget = QtGui.QWidget()
- self.groupWidget.setLayout(self.adc_checkbox_layout)
- self.group.setExclusive(True)
- self.compare_heading_left = self.createLabel("ADC 1")
- self.compare_heading_left.setAlignment(QtCore.Qt.AlignCenter)
- self.compare_heading_right = self.createLabel("ADC 2")
- self.compare_heading_right.setAlignment(QtCore.Qt.AlignCenter)
- self.compare_heading = QtGui.QWidget()
- self.compare_heading_layout = QtGui.QHBoxLayout()
- self.compare_heading_layout.addWidget(self.compare_heading_left)
- self.compare_heading_layout.addWidget(self.compare_heading_right)
- self.compare_heading.setLayout(self.compare_heading_layout)
- self.compare_heading.hide()
- self.adc1Compare = self.createCheckbox(text="ADC 1", connect=lambda: self.change_adc_compare(who=1))
- self.adc2Compare = self.createCheckbox(text="ADC 2", connect=lambda: self.change_adc_compare(who=2))
- self.adc3Compare = self.createCheckbox(text="ADC 3", connect=lambda: self.change_adc_compare(who=3))
- self.adc4Compare = self.createCheckbox(text="ADC 4", connect=lambda: self.change_adc_compare(who=4))
- if int(self.board_config.get('adc_number')) > 4:
- self.adc5Compare = self.createCheckbox(text="ADC 5", connect=lambda: self.change_adc_compare(who=8))
- self.adc6Compare = self.createCheckbox(text="ADC 6", connect=lambda: self.change_adc_compare(who=6))
- self.adc7Compare = self.createCheckbox(text="ADC 7", connect=lambda: self.change_adc_compare(who=7))
- self.adc8Compare = self.createCheckbox(text="ADC 8", connect=lambda: self.change_adc_compare(who=8))
- self.adc1Compare.setChecked(True)
- self.adc2Compare.setChecked(True)
- self.adc_checkbox_compare_layout = QtGui.QHBoxLayout()
- self.adc_checkbox_compare_layout.addWidget(self.adc1Compare)
- self.adc_checkbox_compare_layout.addWidget(self.adc2Compare)
- self.adc_checkbox_compare_layout.addWidget(self.adc3Compare)
- self.adc_checkbox_compare_layout.addWidget(self.adc4Compare)
- self.groupWidgetCompare = QtGui.QWidget()
- self.groupWidgetCompare.setLayout(self.adc_checkbox_compare_layout)
- self.groupCompare = QtGui.QButtonGroup()
- self.groupCompare.setExclusive(False)
- self.groupCompare.addButton(self.adc1Compare, 1)
- self.groupCompare.addButton(self.adc2Compare, 2)
- self.groupCompare.addButton(self.adc3Compare, 3)
- self.groupCompare.addButton(self.adc4Compare, 4)
- if int(self.board_config.get('adc_number')) > 4:
- self.groupCompare.addButton(self.adc4Compare, 5)
- self.groupCompare.addButton(self.adc4Compare, 6)
- self.groupCompare.addButton(self.adc4Compare, 7)
- self.groupCompare.addButton(self.adc4Compare, 8)
- self.groupWidgetCompare.hide()
-
- self.fft_mode = QtGui.QComboBox(self)
- self.fft_mode.addItem("Image") #0
- self.fft_mode.addItem("All") #1
- self.fft_mode.addItem("Mean") #1
- for i in range(184):
- self.fft_mode.addItem("Bucket {}".format(i))
- self.fft_mode.currentIndexChanged.connect(lambda: [self.change_adc(), self.changePlotType(self.theType)])
- self.fft_log = self.createCheckbox(text="Log", connect=lambda: self.change_adc())
- self.from_to_layout = QtGui.QHBoxLayout()
- self.from_spinbox = self.createSpinbox(0, 100000000, interval=100, connect=lambda: self.plot(self.theType))
- self.to_spinbox = self.createSpinbox(0, 100000000, start_value=1000, interval=100, connect=lambda: self.plot(self.theType))
-
- self.from_to_layout.addWidget(self.fft_mode)
- self.from_to_layout.addWidget(self.fft_log)
- self.from_to_layout.addStretch()
- self.from_to_layout.addWidget(self.createLabel(tr("Label", "From:")))
- self.from_to_layout.addWidget(self.from_spinbox)
- self.from_to_layout.addWidget(self.createLabel(tr("Label", "To:")))
- self.from_to_layout.addWidget(self.to_spinbox)
- self.useCalib=self.createCheckbox('use Calib', connect=lambda: self.plot(self.theType))
- self.from_to_layout.addWidget(self.useCalib)
- self.makeMean=self.createCheckbox('Mean', connect=lambda: self.plot(self.theType))
- self.from_to_layout.addWidget(self.makeMean)
- self.fittGauss=self.createCheckbox('Fitt', connect=lambda: self.plot(self.theType))
- self.from_to_layout.addWidget(self.fittGauss)
- self.layout.addLayout(self.plot_buttons_layout)
- self.layout.addWidget(self.compare_heading)
- self.layout.addWidget(self.plot_widget)
- self.layout.addWidget(self.groupWidget)
- self.layout.addWidget(self.groupWidgetCompare)
- self.layout.addLayout(self.from_to_layout)
- self.setLayout(self.layout)
- self.board_config.observe(self, self.observeDataSet, 'lastDataSet')
- def observeDataSet(self, data):
- self.plot_live(data=data)
- def change_adc(self):
- """
- Change the adc for which data is plotted
- :return: -
- """
- if self.theType in [PlotType.Trains, PlotType.FFT]:
- self.adc=[]
- for i, item in enumerate(self.adcCheckBox):
- if item.isChecked(): self.adc.extend([i])
- if len(self.adc) == 0:
- self.adc = 1
- self.adcCheckBox[0].setChecked(True)
- else:
- self.adc = self.group.checkedId()-1
-
- self.change_identifier_text()
- self.plot(self.theType)
- def change_adc_compare(self, who):
- """
- Change the adcs displayed in a compare plot
- :return:
- """
- if not self._single_adc_checked:
- for b in self.groupCompare.buttons():
- b.setChecked(False)
- #self.adc1Compare.setChecked(False)
- #self.adc2Compare.setChecked(False)
- #self.adc3Compare.setChecked(False)
- #self.adc4Compare.setChecked(False)
- getattr(self, 'adc'+str(who)+'Compare').setChecked(True)
- self._single_adc_checked = True
- else:
- checked = [i.isChecked() for i in self.groupCompare.buttons()]
- self._single_adc_checked = False
- self.adc = np.where(np.array(checked) == True)[0][0] + 1 # +1 because adcs are 1 based and indices 0
- self.secadc = np.where(np.array(checked) == True)[0][1] + 1 # +1 because adcs are 1 based and indices 0
- self.compare_heading_left.setText("ADC "+str(self.adc))
- self.compare_heading_right.setText("ADC "+str(self.secadc))
- self.change_identifier_text()
- if self.theType in [ERROR, NO_DATA]:
- self.plot(self._old_type)
- else:
- self.plot(self.theType)
- def disable_buttons(self, b_bool):
- """
- Disable the buttons on this widget
- This is not used at the moment
- :param b_bool: (bool) disable(False) or enable(True)
- :return: -
- """
- self.heatmap_button.setDisabled(b_bool)
- self.fft_button.setDisabled(b_bool)
- self.trains_button.setDisabled(b_bool)
- self.combined_button.setDisabled(b_bool)
- def changePlotType(self, type):
- """
- Change the plot type to the given type.
- :param type: the new type
- """
- if type not in [ERROR, NO_DATA]:
- self._old_type = type
- self.theType = type
- self.plot_widget.changeType(type)
- for btype, button in self.type_buttons.items():
- style = ""
- if btype == type:
- style += "QPushButton {background-color:lightgreen;}"
- else:
- style += self.defaultButtonStyleSheet
- style += "QPushButton:focus{background-color: lightgrey!important; border-color: lightblue;}" # Note: this does not work
- button.setStyleSheet(style)
-
-
- if self.theType == PlotType.Trains:
- self.group.setExclusive(False)
- else:
- for item in self.adcCheckBox:
- item.setChecked(False)
- self.adcCheckBox[0].setChecked(True)
- self.group.setExclusive(True)
- if self.theType == PlotType.Peak:
- self.makeMean.show()
- self.fittGauss.show()
- else:
- self.makeMean.hide()
- self.fittGauss.hide()
-
- if self.theType == PlotType.FFT:
- self.fft_mode.show()
- self.fft_log.show()
- if self.fft_mode.currentIndex() > 0:
- self.group.setExclusive(False)
- else:
- self.group.setExclusive(True)
- else:
- self.fft_mode.hide()
- self.fft_log.hide()
- def plot(self, type=None):
- """
- Wrapper function to call the correct plot function depending on type
- :param type: (int) the plot type
- :return: -
- """
- try:
- if type == None:
- if self.theType in [ERROR, NO_DATA]:
- type = self._old_type
- else:
- type = self.theType
- self.do_plot(type)
- except Exception as e:
- print('plot wrapper except')
-
- traceback.print_exc()
- if self.data is None or len(self.data.array) == 0:
- self.changePlotType(NO_DATA)
- else:
- self.changePlotType(ERROR)
- self.plot_widget.plot(None)
- def plot_live(self, type=None, data=None):
- """
- Function to call when livedata is to be plotted
- :param type: (int) plot type
- :param data: (dataset.DataSet) data to plot
- :return: -
- """
- self.data = data
- try:
- if type == None:
- if self.theType in [ERROR, NO_DATA]:
- type = self._old_type
- else:
- type = self.theType
- if type == PlotType.Trains or type == PlotType.Combined:
- self.do_plot(type, autorange=True)
- else:
- self.do_plot(type, autorange=False)
- except Exception:
- traceback.print_exc()
- if len(self.data.array) == 0:
- self.changePlotType(NO_DATA)
- else:
- self.changePlotType(ERROR)
- self.plot_widget.plot(None)
- def do_plot(self, type, autorange=True):
- #print(time.time(), 'do_plot start')
- """
- Actually perform a plot (this calls SubPlotWidget.plot)
- :param type: (int) plot type
- :param autorange: (bool) whether to perform a autorange upon plot
- :return: -
- """
- if self.theType != type:
- if type == PlotType.Combined:
- self.groupWidget.hide()
- elif self.theType == PlotType.Combined:
- self.groupWidget.show()
- if type == PlotType.Compare:
- self.groupWidget.hide()
- self.groupWidgetCompare.show()
- self.compare_heading.show()
- else:
- self.groupWidget.show()
- self.groupWidgetCompare.hide()
- self.compare_heading.hide()
- self.changePlotType(type)
- self.setWindowTitle(self.theName + " - " + plotList[type] + " - " + str(self.thePrefix))
- self.change_identifier_text()
- if self.theType == PlotType.Compare:
- self.change_identifier_text()
- if self.theType == PlotType.Compare:
- self.groupWidget.hide()
- self.groupWidgetCompare.show()
- self.compare_heading.show()
- else:
- self.groupWidgetCompare.hide()
- self.compare_heading.hide()
- f = self.from_spinbox.value()
- t = self.to_spinbox.value() if self.to_spinbox.value() > f else f+1
- if type == PlotType.FFT:
- self.plot_widget.plot(self.data.fft(adc=self.adc, frm=f, to=t+1, drop_first_bin=True, nobunching=self.fft_mode.currentIndex()==1),
- autorange=autorange,
- xvalueborders=[self.data.fftFreqDist(), self.data.fftMaxFreq()],
- fft_mode = self.fft_mode.currentIndex(),
- log=self.fft_log.isChecked())
- if type == PlotType.Heatmap:
- self.plot_widget.plot( self.data.heatmap(adc=self.adc, frm=f, to=t).transpose(), autorange=autorange)
- if type == PlotType.Compare:
- self.plot_widget.plot([self.data.heatmap(adc=self.adc, frm=f, to=t).transpose(), self.data.heatmap(adc=self.secadc, frm=f, to=t).transpose()], autorange=autorange)
- if type == PlotType.Trains:
- self.plot_widget.plot(self.data.train(adc=self.adc, frm=f, to=t, calibrate=self.useCalib.isChecked()), autorange=autorange)
- if type == PlotType.Combined:
- self.plot_widget.plot(self.data.combined(adc=self.adc, frm=f, to=t, calibrate=self.useCalib.isChecked(), workingChannels=config.working_channels), autorange=autorange)
- if type == PlotType.Peak:
- t = t+184
- self.plot_widget.plot(self.data.combined(adc=self.adc, frm=f, to=t, calibrate=self.useCalib.isChecked(), workingChannels=config.working_channels, turnbyturn=False, mean=self.makeMean.isChecked()), autorange=autorange, doFit=(6 if self.fittGauss.isChecked() else 0))
- #print(time.time(), 'do_plot stop'))
- def change_identifier_text(self):
- """
- Change the text that identifies the plot in the left bar
- :return:
- """
- if self.theType is PlotType.Compare:
- the_text = str(self.adc)+"+"+str(self.secadc)
- else:
- the_text = str(self.adc)
- if self.theType in [ERROR, NO_DATA]:
- type = self._old_type
- else:
- type = self.theType
- if self.theDataType is LIVE:
- self.change_type_signal.emit(self.theId, type,
- the_text+" B: "+available_boards.get_board_name_from_id(self.board_id))
- else:
- self.change_type_signal.emit(self.theId, type, the_text)
- def closeEvent(self, event):
- """
- Event Handler to handle the event of closing this window
- :param event: QEvent
- :return: -
- """
- self.board_config.unobserve(self, 'lastDataSet')
- if not self.close_silent:
- if not self.parent.remove_plot(self.theId, silent=self.close_silent):
- event.ignore()
- return
- del self.data
- del self.plot_widget
- super(PlotWidget, self).closeEvent(event)
- if self.theDataType == LIVE:
- live_plot_windows.removeWindow(self.board_id, self)
- self.close_signal.emit()
- del self
|