فهرست منبع

Implements Switchable Timing result Plots

Patrick Schreiber 8 سال پیش
والد
کامیت
804597c585
9فایلهای تغییر یافته به همراه245 افزوده شده و 54 حذف شده
  1. 5 3
      base/backendinterface.py
  2. 3 1
      base/controlwidget.py
  3. 30 0
      base/kcgwidget.py
  4. BIN
      icons/SwitchButtonLeft.png
  5. BIN
      icons/SwitchButtonRight.png
  6. 4 0
      kcg.py
  7. 1 1
      style/blue.css
  8. 0 2
      style/style.css
  9. 202 47
      widgets/timingWidget.py

+ 5 - 3
base/backendinterface.py

@@ -110,6 +110,8 @@ def _bif_continuous_read_is_enabled(popup_title_text=None):
 def _bif_status_readout():
     # TODO: NOTE: Problem with this is that certain buttons will be greyed out until other buttons are pressed
     # TODO: even if only the gui is restarted and the board is in the same state
+    if kcgw.testing:
+        return # TODO: IMPORTANT REMOVE THIS !!!!!
     if board.is_active():
         Buttons.setEnabled("after_start", True)
         Buttons.setEnabled("start_board", False)
@@ -945,9 +947,9 @@ def _bif_start_time_scan(c_frm, c_to, f_frm, f_to, timescan_progressbar, plot_fu
                         board.flush_dma()
                         # ----------------------------------------------
 
-                        #f_name = "/home/blaxxun/Documents/Hiwi/KaptureSimulator/timescan/" + str(coarse) + "_" + str(fine) + ".str"
-                        #f = open(f_name, 'r')
-                        #data_raw = f.read()
+                        # f_name = "/home/blaxxun/Documents/Hiwi/KaptureSimulator/timescan/" + str(coarse) + "_" + str(fine) + ".str"
+                        # f = open(f_name, 'r')
+                        # data_raw = f.read()
 
                         #Sadly, the PCI software also outputs the Information, that it has written data to the desired file.
                         #This is recorded by our software and needs to be removed, so we split the returned string at the

+ 3 - 1
base/controlwidget.py

@@ -199,7 +199,9 @@ class ControlWidget(kcgw.KCGWidgets):
         self.set_default_button = self.createButton(text=tr("Button", "Set Defaults"), connect=bif.bk_set_defaults)
         self.soft_reset_button = self.createButton(text=tr("Button", "Soft Reset"), connect=bif.bk_soft_reset)
         self.off_button = self.createButton(text=tr("Button", "Board Off"), connect=bif.bk_stop_board)
-        self.all_in_one_button = self.createButton(text=tr("Button", "Prepare Board"), connect=self.all_in_one)
+        self.all_in_one_button = self.createButton(text=tr("Button", "Prepare Board"), connect=self.all_in_one,
+                                                   tooltip=tr("Tooltip", "Start, Calibrate, Synchronize and set Defaults\nCtrl+A"))
+        self.all_in_one_button.setShortcut("Ctrl+A")
         self.all_in_one_button.setObjectName("all_in_one")
         self.off_button.setObjectName("off")
 

+ 30 - 0
base/kcgwidget.py

@@ -21,6 +21,30 @@ class clickLabel(QtGui.QLabel):
     def mouseReleaseEvent(self, QMouseEvent):
         self.clicked.emit()
 
+class switchLabel(QtGui.QLabel):
+    clicked = QtCore.pyqtSignal()
+    def __init__(self, startRight=False): # self.state: True->Right False->Left
+        super(switchLabel, self).__init__()
+        self.leftSwitch = QtGui.QPixmap("icons/SwitchButtonLeft.png")
+        self.leftSwitch = self.leftSwitch.scaled(40, 20, transformMode=QtCore.Qt.SmoothTransformation)
+        self.rightSwitch = QtGui.QPixmap("icons/SwitchButtonRight.png")
+        self.rightSwitch = self.rightSwitch.scaled(40, 20, transformMode=QtCore.Qt.SmoothTransformation)
+        if startRight:
+            self.setPixmap(self.rightSwitch)
+            self.state = True
+        else:
+            self.setPixmap(self.leftSwitch)
+            self.state = False
+    def mouseReleaseEvent(self, QMouseEvent):
+        if self.state:
+            self.state = False
+            self.setPixmap(self.leftSwitch)
+        else:
+            self.state = True
+            self.setPixmap(self.rightSwitch)
+        self.clicked.emit()
+
+
 class ClickableSVG(QtGui.QWidget):
     clicked = QtCore.pyqtSignal()
     def __init__(self, path, width, height, wwidth=None, wheight=None, parent=None):
@@ -154,6 +178,12 @@ class KCGWidgets(QtGui.QWidget):
             cb.clicked.connect(connect)
         return cb
 
+    def createSwitch(self, startRight=False, connect=None):
+        sw = switchLabel(startRight)
+        if connect:
+            sw.clicked.connect(connect)
+        return sw
+
     def closeEvent(self, event):
         super(KCGWidgets, self).closeEvent(event)
         self.closeSignal.emit()

BIN
icons/SwitchButtonLeft.png


BIN
icons/SwitchButtonRight.png


+ 4 - 0
kcg.py

@@ -15,6 +15,10 @@ import base.kcg as kcg
 # exception_log_handler = Erax('http://psraspi.no-ip.biz:5000/insert/78e55a9524a191f7628f82a20bcaa167:kcg')
 # exception_log_handler.install()
 
+if 'testing' in sys.argv:
+    kcgw.testing = True
+else:
+    kcgw.testing = False
 
 gui=None
 def main():

+ 1 - 1
style/blue.css

@@ -55,4 +55,4 @@ QScrollBar
     background-color:lightgrey;
     color: black;
 }
-*/
+*/

+ 0 - 2
style/style.css

@@ -20,5 +20,3 @@
 #leftright:hover {
     background-color: grey;
 }
-
-

+ 202 - 47
widgets/timingWidget.py

@@ -23,32 +23,114 @@ class timingPlotWidget(kcgw.KCGWidgets):
         self.id = unique_id
         self.par = parent
 
+        self.plot_type = "colour"
+        self.x = None
+        self.y = None
+        self.data = None
+        self.levels = None
+
         self.inputsSet = False
 
         self.adc1_plot_widget = pg.PlotWidget(title="ADC 1")
+        self.adc2_plot_widget = pg.PlotWidget(title="ADC 2")
+        self.adc3_plot_widget = pg.PlotWidget(title="ADC 3")
+        self.adc4_plot_widget = pg.PlotWidget(title="ADC 4")
+
+        self.outerLayout = QtGui.QVBoxLayout()
+        self.setLayout(self.outerLayout)
+        self.headerLayout = QtGui.QHBoxLayout()
+        self.outerLayout.addLayout(self.headerLayout)
+
+        self.position_label = self.createLabel("")
+        self.position_label.setAlignment(QtCore.Qt.AlignCenter)
+        self.plot_type_switcher = self.createSwitch(connect=self.switch)
+        self.headerLayout.addWidget(self.position_label)
+        self.headerLayout.addWidget(self.createLabel("Colour Plot"))
+        self.headerLayout.addWidget(self.plot_type_switcher)
+        self.headerLayout.addWidget(self.createLabel("Line Plot"))
+        self.headerLayout.setAlignment(QtCore.Qt.AlignRight)
+        self.layout = QtGui.QGridLayout()
+        self.layout.addWidget(self.adc1_plot_widget, 0, 0)
+        self.layout.addWidget(self.adc2_plot_widget, 0, 1)
+        self.layout.addWidget(self.adc3_plot_widget, 1, 0)
+        self.layout.addWidget(self.adc4_plot_widget, 1, 1)
+        self.outerLayout.addLayout(self.layout)
+        self.setWindowTitle(tr("Heading", "Timescan Results"))
+
+        # Initially show the colour plot
+        self.colour_plot()
+
+    def switch(self):
+        if self.plot_type == 'colour':
+            self.remove_colour_plot()
+            self.line_plot()
+            self.plot()
+        else:
+            self.adc1_plot_widget.plotItem.clearPlots()
+            self.adc2_plot_widget.plotItem.clearPlots()
+            self.adc3_plot_widget.plotItem.clearPlots()
+            self.adc4_plot_widget.plotItem.clearPlots()
+            self.colour_plot()
+            self.plot()
+
+    def colour_plot(self):
+        self.plot_type = "colour"
         self.adc1 = pg.ImageItem()
+        self.adc2 = pg.ImageItem()
+        self.adc3 = pg.ImageItem()
+        self.adc4 = pg.ImageItem()
+
+        self.adc1.mouseClickEvent = lambda x: self.click("ADC 1", x)
+        self.adc2.mouseClickEvent = lambda x: self.click("ADC 2", x)
+        self.adc3.mouseClickEvent = lambda x: self.click("ADC 3", x)
+        self.adc4.mouseClickEvent = lambda x: self.click("ADC 4", x)
+
+        def tickStrings(values, scale, spacing):
+            return [str(i) for i in range(len(values))]
+
         self.adc1_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Coarse delay"))
         self.adc1_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Fine delay"))
-        self.adc1.mouseClickEvent = lambda x: self.click("ADC 1", x)
         self.adc1_plot_widget.plotItem.addItem(self.adc1)
-        self.adc2_plot_widget = pg.PlotWidget(title="ADC 2")
-        self.adc2 = pg.ImageItem()
+        bax = self.adc1_plot_widget.plotItem.getAxis('bottom')
+        lax = self.adc1_plot_widget.plotItem.getAxis('left')
+        bax.setTickSpacing(levels=[(1, 1.5),])
+        bax.tickStrings = tickStrings
+        lax.setTickSpacing(levels=[(1, 1.5),])
+        lax.tickStrings = tickStrings
+
         self.adc2_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Coarse delay"))
         self.adc2_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Fine delay"))
-        self.adc2.mouseClickEvent = lambda x: self.click("ADC 2", x)
         self.adc2_plot_widget.plotItem.addItem(self.adc2)
-        self.adc3_plot_widget = pg.PlotWidget(title="ADC 3")
-        self.adc3 = pg.ImageItem()
+        bax = self.adc2_plot_widget.plotItem.getAxis('bottom')
+        lax = self.adc2_plot_widget.plotItem.getAxis('left')
+        bax.setTickSpacing(levels=[(1, 1.5),])
+        bax.tickStrings = tickStrings
+        lax.setTickSpacing(levels=[(1, 1.5),])
+        lax.tickStrings = tickStrings
+
+
         self.adc3_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Coarse delay"))
         self.adc3_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Fine delay"))
-        self.adc3.mouseClickEvent = lambda x: self.click("ADC 3", x)
         self.adc3_plot_widget.plotItem.addItem(self.adc3)
-        self.adc4_plot_widget = pg.PlotWidget(title="ADC 4")
-        self.adc4 = pg.ImageItem()
+        bax = self.adc3_plot_widget.plotItem.getAxis('bottom')
+        lax = self.adc3_plot_widget.plotItem.getAxis('left')
+        bax.setTickSpacing(levels=[(1, 1.5),])
+        bax.tickStrings = tickStrings
+        lax.setTickSpacing(levels=[(1, 1.5),])
+        lax.tickStrings = tickStrings
+
+
         self.adc4_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Coarse delay"))
         self.adc4_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Fine delay"))
-        self.adc4.mouseClickEvent = lambda x: self.click("ADC 4", x)
         self.adc4_plot_widget.plotItem.addItem(self.adc4)
+        bax = self.adc4_plot_widget.plotItem.getAxis('bottom')
+        lax = self.adc4_plot_widget.plotItem.getAxis('left')
+        bax.setTickSpacing(levels=[(1, 1.5),])
+        bax.tickStrings = tickStrings
+        lax.setTickSpacing(levels=[(1, 1.5),])
+        lax.tickStrings = tickStrings
+
+
 
         pos = np.array([0, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1])
         color = np.array([[0, 0, 255, 255], [0, 255, 255, 255], [0, 255, 0, 255], [130, 255, 0, 255], [255, 255, 0, 255], [255, 180, 0, 255], [255, 100, 0, 255], [255, 0, 0, 255]])
@@ -59,18 +141,80 @@ class timingPlotWidget(kcgw.KCGWidgets):
         self.adc3.setLookupTable(lut)
         self.adc4.setLookupTable(lut)
 
-        self.outerLayout = QtGui.QVBoxLayout()
-        self.setLayout(self.outerLayout)
-        self.position_label = self.createLabel("")
-        self.position_label.setAlignment(QtCore.Qt.AlignCenter)
-        self.outerLayout.addWidget(self.position_label)
-        self.layout = QtGui.QGridLayout()
-        self.layout.addWidget(self.adc1_plot_widget, 0, 0)
-        self.layout.addWidget(self.adc2_plot_widget, 0, 1)
-        self.layout.addWidget(self.adc3_plot_widget, 1, 0)
-        self.layout.addWidget(self.adc4_plot_widget, 1, 1)
-        self.outerLayout.addLayout(self.layout)
-        self.setWindowTitle(tr("Heading", "Timescan Results"))
+    def remove_colour_plot(self):
+        self.adc1_plot_widget.plotItem.removeItem(self.adc1)
+        self.adc2_plot_widget.plotItem.removeItem(self.adc2)
+        self.adc3_plot_widget.plotItem.removeItem(self.adc3)
+        self.adc4_plot_widget.plotItem.removeItem(self.adc4)
+
+    def line_plot_axis_strings(self, values, scale, spacing):
+        coarses = [i//(self.x+1) for i in values]
+        fines = [i%(self.x+1) for i in values]
+        return [str(int(c))+"\n"+str(int(f)) for c, f in zip(coarses, fines)]
+
+    def spacing(self, minVal, maxVal, size):
+        if maxVal - minVal < 20.:
+            return [(1, 0),]
+        else:
+            return [((maxVal-minVal)/20., 0),]
+
+    def y_axis_strings(self, values, scale, spacing):
+        strs = []
+        # for v in values:
+        #     if v >= 1000:
+        #         strs.append(str(int(v/10)/100.)+"k")
+        #     else:
+        #         strs.append(str(v))
+        # return strs
+        return [str(int(v)) for v in values]
+
+    def line_plot(self):
+        self.plot_type = "line"
+        self.adc1_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Intensity"))
+        self.adc1_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Coarse over Fine"))
+        self.adc1_plot_widget.plotItem.getAxis('bottom').tickSpacing = self.spacing
+        self.adc1_plot_widget.plotItem.getAxis('bottom').tickStrings = self.line_plot_axis_strings
+        self.adc1_plot_widget.plotItem.getAxis('left').setTickSpacing()
+        # self.adc1_plot_widget.plotItem.getAxis('left').tickStrings = lambda x, y, z: pg.AxisItem.tickStrings(
+        #     self.adc1_plot_widget.plotItem.getAxis('left'), x, y, z
+        # )
+        self.adc1_plot_widget.plotItem.getAxis('left').tickStrings = self.y_axis_strings
+
+
+        self.adc2_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Intensity"))
+        self.adc2_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Coarse over Fine"))
+        self.adc2_plot_widget.plotItem.getAxis('bottom').tickSpacing = self.spacing
+        self.adc2_plot_widget.plotItem.getAxis('bottom').tickStrings = self.line_plot_axis_strings
+        self.adc2_plot_widget.plotItem.getAxis('left').setTickSpacing()
+        # self.adc2_plot_widget.plotItem.getAxis('left').tickStrings = lambda x, y, z: pg.AxisItem.tickStrings(
+        #     self.adc2_plot_widget.plotItem.getAxis('left'), x, y, z
+        # )
+        self.adc2_plot_widget.plotItem.getAxis('left').tickStrings = self.y_axis_strings
+
+
+        self.adc3_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Intensity"))
+        self.adc3_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Coarse over Fine"))
+        self.adc3_plot_widget.plotItem.getAxis('bottom').tickSpacing = self.spacing
+        self.adc3_plot_widget.plotItem.getAxis('bottom').tickStrings = self.line_plot_axis_strings
+        self.adc3_plot_widget.plotItem.getAxis('left').setTickSpacing()
+        # self.adc3_plot_widget.plotItem.getAxis('left').tickStrings = lambda x, y, z: pg.AxisItem.tickStrings(
+        #     self.adc3_plot_widget.plotItem.getAxis('left'), x, y, z
+        # )
+        self.adc3_plot_widget.plotItem.getAxis('left').tickStrings = self.y_axis_strings
+
+
+        self.adc4_plot_widget.getPlotItem().setLabel("left", tr("Heading", "Intensity"))
+        self.adc4_plot_widget.getPlotItem().setLabel("bottom", tr("Heading", "Coarse over Fine"))
+        self.adc4_plot_widget.plotItem.getAxis('bottom').tickSpacing = self.spacing
+        self.adc4_plot_widget.plotItem.getAxis('bottom').tickStrings = self.line_plot_axis_strings
+        self.adc4_plot_widget.plotItem.getAxis('left').setTickSpacing()
+        # self.adc4_plot_widget.plotItem.getAxis('left').tickStrings = lambda x, y, z: pg.AxisItem.tickStrings(
+        #     self.adc4_plot_widget.plotItem.getAxis('left'), x, y, z
+        # )
+        self.adc4_plot_widget.plotItem.getAxis('left').tickStrings = self.y_axis_strings
+
+
+
 
     def setInputs(self, coarse_input, fine_inputs):
         self.c_input = coarse_input
@@ -98,31 +242,42 @@ class timingPlotWidget(kcgw.KCGWidgets):
             self.adc4_f_input.setValue(int(pos.x()))
 
 
-    def move(self, adc, event):
-        event.accept()
-        pos = event.pos()
-        self.position_label.setText(adc + " - " + str(pos.x()) + ":"+str(pos.y()))
-        print 'test'
-
-
-    def plot(self, data, levels=None, newTitle=None, maxima=None):
-        self.adc1.setImage(data[0])
-        self.adc2.setImage(data[1])
-        self.adc3.setImage(data[2])
-        self.adc4.setImage(data[3])
-        if levels:
-            self.adc1.setLevels(levels)
-            self.adc2.setLevels(levels)
-            self.adc3.setLevels(levels)
-            self.adc4.setLevels(levels)
-        if newTitle:
-            self.setWindowTitle(tr("Heading", "Timescan Result:") + " " + newTitle)
-
-        if maxima is not None:
-            self.adc1_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[0, 1]), f=int(maxima[0, 2])))
-            self.adc2_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[1, 1]), f=int(maxima[1, 2])))
-            self.adc3_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[2, 1]), f=int(maxima[2, 2])))
-            self.adc4_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[3, 1]), f=int(maxima[3, 2])))
+    def plot(self, data=None, levels=None, newTitle=None, maxima=None):
+        if self.data is not None and data is not None:
+            return
+        if data is not None:
+            self.data = data # if called with no data a replot is performed (if data is set previously)
+        if levels is not None:
+            self.levels = levels
+        self.x = self.data.shape[0]
+        self.y = self.data.shape[1]
+        if self.plot_type == 'colour':
+            # self.colour_plot()
+            self.adc1.setImage(self.data[0])
+            self.adc2.setImage(self.data[1])
+            self.adc3.setImage(self.data[2])
+            self.adc4.setImage(self.data[3])
+            if self.levels:
+                self.adc1.setLevels(self.levels)
+                self.adc2.setLevels(self.levels)
+                self.adc3.setLevels(self.levels)
+                self.adc4.setLevels(self.levels)
+            if newTitle:
+                self.setWindowTitle(tr("Heading", "Timescan Result:") + " " + newTitle)
+
+            if maxima is not None:
+                self.adc1_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[0, 1]), f=int(maxima[0, 2])))
+                self.adc2_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[1, 1]), f=int(maxima[1, 2])))
+                self.adc3_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[2, 1]), f=int(maxima[2, 2])))
+                self.adc4_plot_widget.getPlotItem().setTitle(str(tr("Heading", "Maximum C:{c} F:{f}")).format(c=int(maxima[3, 1]), f=int(maxima[3, 2])))
+        if self.plot_type == 'line':
+            # self.line_plot()
+            def reshape(data):
+                return np.reshape(data, data.shape[0]*data.shape[1])
+            self.adc1_plot_widget.plotItem.plot(reshape(self.data[0]))
+            self.adc2_plot_widget.plotItem.plot(reshape(self.data[1]))
+            self.adc3_plot_widget.plotItem.plot(reshape(self.data[2]))
+            self.adc4_plot_widget.plotItem.plot(reshape(self.data[3]))
 
         self.parent().show()
         self.show()