Exemple #1
0
    def showAxisDialog(self):

        # todo : converting to double ... check b

        dialog = pyVacGraphAxesDialog(self)

        if type(self.axisScaleEngine(Qwt.QwtPlot.yLeft)) == type(
                Qwt.QwtLog10ScaleEngine()):
            dialog.ui.LogRadioButton_1.setChecked(True)
        else:
            dialog.ui.LinRadioButton_1.setChecked(True)

        if type(self.axisScaleEngine(Qwt.QwtPlot.yRight)) == type(
                Qwt.QwtLog10ScaleEngine()):
            dialog.ui.LogRadioButton_2.setChecked(True)
        else:
            dialog.ui.LinRadioButton_2.setChecked(True)

        if self.axisAutoScale(Qwt.QwtPlot.yLeft):
            dialog.ui.AutoRangeCheckBox_1.setChecked(True)

        if self.axisAutoScale(Qwt.QwtPlot.yRight):
            dialog.ui.AutoRangeCheckBox_2.setChecked(True)

        if dialog.exec_() == QDialog.Accepted:
            # Set the axes
            if dialog.ui.LogRadioButton_1.isChecked():
                self.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                        Qwt.QwtLog10ScaleEngine())
            else:
                self.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                        Qwt.QwtLinearScaleEngine())

            if dialog.ui.LogRadioButton_2.isChecked():
                self.setAxisScaleEngine(Qwt.QwtPlot.yRight,
                                        Qwt.QwtLog10ScaleEngine())
            else:
                self.setAxisScaleEngine(Qwt.QwtPlot.yRight,
                                        Qwt.QwtLinearScaleEngine())

            if dialog.ui.AutoRangeCheckBox_1.isChecked():
                self.setAxisAutoScale(Qwt.QwtPlot.yLeft)
            else:
                min, b = dialog.ui.MinLineEdit_1.text().toDouble()
                max, b = dialog.ui.MaxLineEdit_1.text().toDouble()
                self.setAxisScale(Qwt.QwtPlot.yLeft, min, max)

            if dialog.ui.AutoRangeCheckBox_2.isChecked():
                self.setAxisAutoScale(Qwt.QwtPlot.yRight)
            else:
                min, b = dialog.ui.MinLineEdit_2.text().toDouble()
                max, b = dialog.ui.MaxLineEdit_2.text().toDouble()
                self.setAxisScale(Qwt.QwtPlot.yRight, min, max)

            self.replot()
Exemple #2
0
	def __init__(self, parent, logger):
		ClassPlot.__init__(self)

		# store the logger instance
		self.logger = logger

		# we do not need caching
		self.canvas().setPaintAttribute(Qwt.QwtPlotCanvas.PaintCached, False)
		self.canvas().setPaintAttribute(Qwt.QwtPlotCanvas.PaintPacked, False)

		# attach a grid
		grid = Qwt.QwtPlotGrid()
		grid.setMajPen(Qt.QPen(Qt.Qt.lightGray))
		grid.attach(self)

		xtitle = Qwt.QwtText('Time (ms)')
		xtitle.setFont(QtGui.QFont(8))
		self.setAxisTitle(Qwt.QwtPlot.xBottom, xtitle)
		self.setAxisScale(Qwt.QwtPlot.yLeft, -1., 1.)
		# self.setAxisTitle(Qwt.QwtPlot.xBottom, 'Time (ms)')
		self.xmin = 0.
		self.xmax = 1.

		ytitle = Qwt.QwtText('Signal')
		ytitle.setFont(QtGui.QFont(8))
		self.setAxisTitle(Qwt.QwtPlot.yLeft, ytitle)
		# self.setAxisTitle(Qwt.QwtPlot.yLeft, 'Signal')
		self.setAxisScale(Qwt.QwtPlot.yLeft, -1., 1.)
		self.setAxisScaleEngine(Qwt.QwtPlot.xBottom, Qwt.QwtLinearScaleEngine())
		
		self.paint_time = 0.
		
		self.canvas_width = 0
  
		self.dual_channel = False
  
  		# insert an additional curve for the second channel
  		# (ClassPlot already has one by default)
		self.curve2 = Qwt.QwtPlotCurve("Ch2")
		self.curve2.setPen(QtGui.QPen(Qt.Qt.blue))
		#self.curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
		#self.curve2.attach(self)

  		# gives an appropriate title to the first curve
  		# (for the legend)
		self.curve.setTitle("Ch1")
		
		# picker used to display coordinates when clicking on the canvas
		self.picker = picker(Qwt.QwtPlot.xBottom,
                               Qwt.QwtPlot.yLeft,
                               Qwt.QwtPicker.PointSelection,
                               Qwt.QwtPlotPicker.CrossRubberBand,
                               Qwt.QwtPicker.ActiveOnly,
                               self.canvas())
		
		self.cached_canvas = self.canvas()
		
		#need to replot here for the size Hints to be computed correctly (depending on axis scales...)
		self.replot()
Exemple #3
0
 def setlinfreqscale(self):
     self.logx = False
     self.horizontalScaleEngine = Qwt.QwtLinearScaleEngine()
     self.horizontalScale.setScaleDiv(
         self.horizontalScaleEngine.transformation(),
         self.horizontalScaleEngine.divideScale(self.xmin, self.xmax, 8, 5))
     self.needtransform = True
     self.draw()
Exemple #4
0
    def toggleLogScale(self):
        """Change the scale to base 10 or log scale."""

        if self.logScaleAct.isChecked():
            self.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                    Qwt.QwtLog10ScaleEngine())
            self.replot()
        else:
            self.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                    Qwt.QwtLinearScaleEngine())
            self.replot()
Exemple #5
0
        def checkbox_log_change(self, state):
            if state == QtCore.Qt.Checked:
                # Set plot to logarithmic
                self.qwtPlotFullScan.setAxisAutoScale(Qwt.QwtPlot.yLeft)
                self.qwtPlotFullScan.setAxisScaleEngine(
                    Qwt.QwtPlot.yLeft, Qwt.QwtLog10ScaleEngine())
            else:
                # Set plot to linear
                #self.qwtPlotFullScan.setAxisAutoScale(Qwt.QwtPlot.yLeft)
                self.qwtPlotFullScan.setAxisScaleEngine(
                    Qwt.QwtPlot.yLeft, Qwt.QwtLinearScaleEngine())

            self.qwtPlotFullScan.replot()
Exemple #6
0
    def log_check(self, log, replot=True):
        self.log = log
        min_intes = self.data.intes_array.min()
        max_intes = math.ceil(self.data.intes_array.max()) + 1.0
        if log:  # most of this is changing color scaling for logarithimc
            colorMap = Qwt.QwtLinearColorMap(Qt.Qt.darkCyan, Qt.Qt.red)
            if min_intes <= 0:
                logmin = 0.01
            else:
                logmin = min_intes

            self.setAxisScale(Qwt.QwtPlot.yRight, logmin, max_intes)
            oom = int(
                math.log10(max_intes)
            )  # for log scale we will add in colours depnding on order of magnatiude (oom)
            map = [[1.0 / (10**oom), Qt.Qt.cyan], [0.1, Qt.Qt.yellow],
                   [0.01, Qt.Qt.darkGreen],
                   [1.0 / (10**(oom - 1)), Qt.Qt.blue],
                   [1.0 / (10**(oom - 2)), Qt.Qt.darkBlue],
                   [1.0 / (10**(oom - 3)), Qt.Qt.green]]
            for i in range(oom):
                colorMap.addColorStop(map[i][0], map[i][1])
            self.__spectrogram.setColorMap(colorMap)
            self.setAxisScaleEngine(Qwt.QwtPlot.yRight,
                                    Qwt.QwtLog10ScaleEngine())
        else:
            colorMap = Qwt.QwtLinearColorMap(Qt.Qt.darkCyan, Qt.Qt.red)
            self.setAxisScale(Qwt.QwtPlot.yRight, math.floor(min_intes),
                              math.ceil(max_intes))

            colorMap.addColorStop(0.25, Qt.Qt.cyan)
            colorMap.addColorStop(0.5, Qt.Qt.darkGreen)
            colorMap.addColorStop(0.75, Qt.Qt.yellow)
            self.setAxisScaleEngine(Qwt.QwtPlot.yRight,
                                    Qwt.QwtLinearScaleEngine())

            self.__spectrogram.setColorMap(colorMap)
        self.__spectrogram.attach(self)
        rightAxis = self.axisWidget(Qwt.QwtPlot.yRight)
        rightAxis.setTitle("Intensity")
        rightAxis.setColorBarEnabled(True)
        rightAxis.setColorMap(self.__spectrogram.data().range(),
                              self.__spectrogram.colorMap())
        self.enableAxis(Qwt.QwtPlot.yRight)
        if replot:
            self.replot()
Exemple #7
0
 def disableInAxis(plot, axis, scaleDraw=None, scaleEngine=None):
     '''convenience method that will disable this engine in the given
     axis. Note that it changes the ScaleDraw as well.
      
     :param plot: (Qwt5.QwtPlot) the plot to change
     :param axis: (Qwt5.QwtPlot.Axis) the id of the axis
     :param scaleDraw: (Qwt5.QwtScaleDraw) Scale draw to use. If None given, 
                       a :class:`FancyScaleDraw` will be set
     :param scaleEngine: (Qwt5.QwtScaleEngine) Scale draw to use. If None given, 
                       a :class:`Qwt5.QwtLinearScaleEngine` will be set
     '''
     if scaleDraw is None:
         scaleDraw = FancyScaleDraw()
     if scaleEngine is None:
         scaleEngine = Qwt5.QwtLinearScaleEngine()
     plot.setAxisScaleEngine(axis, scaleEngine)
     plot.setAxisScaleDraw(axis, scaleDraw)
Exemple #8
0
    def divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize):
        interval = Qwt.QwtDoubleInterval(x1, x2).normalized()
        interval = interval.limited(LOG2_MIN, LOG2_MAX)

        if interval.width() <= 0:
            return Qwt.QwtScaleDiv()

        base = 2.
        if interval.maxValue() / interval.minValue() < base:
            # scale width is less than one octave -> build linear scale

            linearScaler = Qwt.QwtLinearScaleEngine()
            linearScaler.setAttributes(self.attributes())
            linearScaler.setReference(self.reference())
            linearScaler.setMargins(self.lowerMargin(), self.upperMargin())

            return linearScaler.divideScale(x1, x2, maxMajSteps, maxMinSteps,
                                            stepSize)

        stepSize = abs(stepSize)

        if stepSize == 0.:
            if maxMajSteps < 1:
                maxMajSteps = 1

            stepSize = self.divideInterval(
                self.log2(interval).width(), maxMajSteps)

            if stepSize < 1.:
                stepSize = 1.  # major step must be >= 1 decade

        scaleDiv = Qwt.QwtScaleDiv()

        if stepSize <> 0.:
            ticks = self.buildTicks(interval, stepSize, maxMinSteps)
            scaleDiv = Qwt.QwtScaleDiv(interval, ticks[0], ticks[1], ticks[2])

        if x1 > x2:
            scaleDiv.invert()

        return scaleDiv
Exemple #9
0
    def __init__(self, *args):
        Qwt.QwtPlot.__init__(self, *args)

        self.setCanvasBackground(QColor("LightGrey"))

        self.colors = itertools.cycle([
            Qt.red, Qt.green, Qt.blue, Qt.cyan, Qt.magenta, Qt.yellow,
            Qt.darkRed, Qt.darkGreen, Qt.darkBlue, Qt.darkCyan, Qt.darkMagenta,
            Qt.darkYellow
        ])

        # legend

        self.legend = Qwt.QwtLegend()
        self.legend.setItemMode(Qwt.QwtLegend.ClickableItem)
        self.legend.setFrameStyle(QFrame.Box | QFrame.Sunken)
        self.insertLegend(self.legend, Qwt.QwtPlot.RightLegend)

        self.connect(self, SIGNAL("legendClicked(QwtPlotItem *)"),
                     self.legendClicked)
        # Axes

        self.setAxisScaleEngine(Qwt.QwtPlot.yLeft, Qwt.QwtLog10ScaleEngine())
        self.setAxisScaleEngine(Qwt.QwtPlot.yRight, Qwt.QwtLinearScaleEngine())

        self.axisScaleEngine(Qwt.QwtPlot.yLeft).setAttribute(
            Qwt.QwtScaleEngine.Floating)

        self.setAxisTitle(Qwt.QwtPlot.xBottom, "Time [h:m:s]")

        sd = TimeScaleDraw()
        self.setAxisScaleDraw(Qwt.QwtPlot.xBottom, sd)

        self.enableAxis(Qwt.QwtPlot.yRight)

        # Setup list of plots to hold

        self.curve = {}
Exemple #10
0
 def setlinfreqscale(self):
     self.plotImage.erase()
     self.logfreqscale = 0
     self.setAxisScaleEngine(Qwt.QwtPlot.yLeft, Qwt.QwtLinearScaleEngine())
     self.replot()
Exemple #11
0
    def __init__(self, *args):
        apply(Qwt.QwtPlot.__init__, (self, ) + args)

        self.setTitle('Scope')
        self.setCanvasBackground(Qt.Qt.white)

        # grid
        self.grid = Qwt.QwtPlotGrid()
        self.grid.enableXMin(True)
        self.grid.setMajPen(Qt.QPen(Qt.Qt.gray, 0, Qt.Qt.SolidLine))
        self.grid.attach(self)

        # axes
        self.enableAxis(Qwt.QwtPlot.yRight)
        self.setAxisTitle(Qwt.QwtPlot.xBottom, 'Time [s]')
        self.setAxisTitle(Qwt.QwtPlot.yLeft, 'Amplitude []')
        self.setAxisMaxMajor(Qwt.QwtPlot.xBottom, 10)
        self.setAxisMaxMinor(Qwt.QwtPlot.xBottom, 0)

        self.setAxisScaleEngine(Qwt.QwtPlot.yRight, Qwt.QwtLinearScaleEngine())
        self.setAxisMaxMajor(Qwt.QwtPlot.yLeft, 10)
        self.setAxisMaxMinor(Qwt.QwtPlot.yLeft, 0)
        self.setAxisMaxMajor(Qwt.QwtPlot.yRight, 10)
        self.setAxisMaxMinor(Qwt.QwtPlot.yRight, 0)

        # curves for scope traces: 2 first so 1 is on top
        self.curve2 = Qwt.QwtPlotCurve('Trace2')
        self.curve2.setSymbol(
            Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, Qt.QBrush(2),
                          Qt.QPen(Qt.Qt.darkMagenta), Qt.QSize(3, 3)))
        self.curve2.setPen(Qt.QPen(Qt.Qt.magenta, TIMEPENWIDTH))
        self.curve2.setYAxis(Qwt.QwtPlot.yRight)
        self.curve2.attach(self)

        self.curve1 = Qwt.QwtPlotCurve('Trace1')
        self.curve1.setSymbol(
            Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, Qt.QBrush(2),
                          Qt.QPen(Qt.Qt.darkBlue), Qt.QSize(3, 3)))
        self.curve1.setPen(Qt.QPen(Qt.Qt.blue, TIMEPENWIDTH))
        self.curve1.setYAxis(Qwt.QwtPlot.yLeft)
        self.curve1.attach(self)

        # default settings
        self.triggerval = 0.10
        self.triggerCH = None
        self.triggerslope = 0
        self.maxamp = 100.0
        self.maxamp2 = 100.0
        self.freeze = 0
        self.average = 0
        self.autocorrelation = 0
        self.avcount = 0
        self.datastream = None
        self.offset1 = 0.0
        self.offset2 = 0.0
        self.maxtime = 0.1

        # set data
        # NumPy: f, g, a and p are arrays!
        self.dt = 1.0 / samplerate
        self.f = np.arange(0.0, 10.0, self.dt)
        self.a1 = 0.0 * self.f
        self.a2 = 0.0 * self.f
        self.curve1.setData(self.f, self.a1)
        self.curve2.setData(self.f, self.a2)

        # start self.timerEvent() callbacks running
        self.timer_id = self.startTimer(self.maxtime * 100 + 50)
        # plot
        self.replot()
Exemple #12
0
 def setlinfreqscale(self):
     self.logfreqscale = False
     self.setAxisScaleEngine(Qwt.QwtPlot.xBottom,
                             Qwt.QwtLinearScaleEngine())
     self.update_xscale()
     self.needfullreplot = True
    def updateTransferFunctionDisplay(self):
        if hasattr(self, 'transfer_function_dictionary') == False:
            return
        # Get which curve we should be displaying:
        (input_select, output_select, first_modulation_frequency_in_hz,
         last_modulation_frequency_in_hz, number_of_frequencies,
         System_settling_time,
         output_amplitude) = self.readSystemIdentificationSettings()

        try:
            H_measured_openloop = -self.transfer_function_dictionary[
                (input_select, output_select, 0)]
            freq_axis_openloop = self.transfer_freq_axis_dictionary[(
                input_select, output_select, 0)]
        except:
            H_measured_openloop = np.array((1, 1))
            freq_axis_openloop = np.array((1, 1))
        try:
            H_measured_fll = -self.transfer_function_dictionary[
                (input_select, output_select, 1)]
            freq_axis_fll = self.transfer_freq_axis_dictionary[(input_select,
                                                                output_select,
                                                                1)]
        except:
            H_measured_fll = np.array((1, 1))
            freq_axis_fll = np.array((1, 1))

        # Predicted closed-loop response:
        # Add the PLL loop filter's transfer function
        ###### TODO: Have the sl object return the loop filters' transfer function instead of re-deriving it everywhere.
        P_gain = 0
        I_gain = 0

        N_delay_p = 5  # TODO: put the correct values here
        N_delay_i = 6  # TODO: put the correct values here
        H_cumsum = 1 / (
            1 - np.exp(-1j * 2 * np.pi * freq_axis_openloop / self.sl.fs))
        phase_ramp = 2 * np.pi * freq_axis_openloop / self.sl.fs

        H_controller = P_gain * np.exp(
            -1j * N_delay_p * phase_ramp) + I_gain * H_cumsum * np.exp(
                -1j * N_delay_i * phase_ramp)

        H_measured_openloop = H_measured_openloop * np.exp(
            1j * 2 * np.pi * 3 * freq_axis_openloop / self.sl.fs
        )  # we cancel 3 samples delay because these come from the VNA itself
        H_measured_fll = H_measured_fll * np.exp(
            1j * 2 * np.pi * 3 * freq_axis_fll / self.sl.fs
        )  # we cancel 3 samples delay because these come from the VNA itself
        H_predicted_fll = H_measured_openloop / (
            1 + H_measured_openloop * H_controller)

        if len(freq_axis_openloop) > 2:
            self.curve_openloop.setData(
                freq_axis_openloop,
                20 * np.log10(np.abs(H_measured_openloop * H_controller)))
            self.curve_openloop_closed.setData(
                freq_axis_openloop, 20 *
                np.log10(np.abs(1 / (1 + H_measured_openloop * H_controller))))

        # Handle the units
        # magnitude is currently in linear a linear scale units/units.
        # The units choices for the graph are:
        # self.qcombo_transfer_units.addItems(['dBunits/units', 'Hz/fullscale', 'Hz/V'])
        if self.qcombo_transfer_units.currentIndex() == 0:
            # dB units/units
            if len(freq_axis_openloop) > 2:
                self.curve_transfer_openloop.setData(
                    freq_axis_openloop,
                    20 * np.log10(np.abs(H_measured_openloop)))
                self.curve_transfer_closedloop_predicted.setData(
                    freq_axis_openloop, 20 * np.log10(np.abs(H_predicted_fll)))
            if len(freq_axis_fll) > 2:
                self.curve_transfer_closedloop.setData(
                    freq_axis_fll, 20 * np.log10(np.abs(H_measured_fll)))

            self.qplt_transfer.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                  Qwt.QwtLinearScaleEngine())
            self.qplt_transfer.setAxisTitle(Qwt.QwtPlot.yLeft,
                                            'Gain [dBunits/units]')

        elif self.qcombo_transfer_units.currentIndex() == 1:
            # Hz/fullscale
            # 2**10 is the number of fractional bits on the phase, while 2**16 is the fullscale output range in counts
            conversion_factor = self.sl.fs / 2**10 * 2**16
            if len(freq_axis_openloop) > 2:
                self.curve_transfer_openloop.setData(
                    freq_axis_openloop,
                    conversion_factor * (np.abs(H_measured_openloop)))
                self.curve_transfer_closedloop_predicted.setData(
                    freq_axis_openloop,
                    conversion_factor * (np.abs(H_predicted_fll)))
            if len(freq_axis_fll) > 2:
                self.curve_transfer_closedloop.setData(
                    freq_axis_fll,
                    conversion_factor * (np.abs(H_measured_fll)))

#            if len(H_closedloop) > 2:
#                self.curve_transfer_gainwithcontroller.setData(freq_axis, np.abs(H_closedloop) * conversion_factor)
#            else:
#                self.curve_transfer_gainwithcontroller.setData(freq_axis, magnitude * conversion_factor)
            self.qplt_transfer.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                  Qwt.QwtLog10ScaleEngine())
            self.qplt_transfer.setAxisTitle(Qwt.QwtPlot.yLeft,
                                            'Gain [Hz/fullscale]')

        elif self.qcombo_transfer_units.currentIndex() == 2:
            # Hz/V, assumes 1V fullscale DAC output (which might be incorrect depending on which DAC and the output PGA gain setting)
            # 2**10 is the number of fractional bits on the phase, while 2**16 is the fullscale output range in counts
            # The 1 at the end represents 1V/fullscale
            conversion_factor = self.sl.fs / 2**10 * 2**16 * 1
            if len(freq_axis_openloop) > 2:
                self.curve_transfer_openloop.setData(
                    freq_axis_openloop,
                    conversion_factor * (np.abs(H_measured_openloop)))
                self.curve_transfer_closedloop_predicted.setData(
                    freq_axis_openloop,
                    conversion_factor * (np.abs(H_predicted_fll)))
            if len(freq_axis_fll) > 2:
                self.curve_transfer_closedloop.setData(
                    freq_axis_fll,
                    conversion_factor * (np.abs(H_measured_fll)))
#            if len(H_closedloop) > 2:
#                self.curve_transfer_gainwithcontroller.setData(freq_axis, np.abs(H_closedloop) * conversion_factor)
#            else:
#                self.curve_transfer_gainwithcontroller.setData(freq_axis, magnitude * conversion_factor)
            self.qplt_transfer.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                  Qwt.QwtLog10ScaleEngine())
            self.qplt_transfer.setAxisTitle(Qwt.QwtPlot.yLeft, 'Gain [Hz/V]')

        # The phase is unaffected by the units, it is always in radians:
        self.curve_transfer_phase.setData(freq_axis_openloop,
                                          np.angle(H_measured_openloop))

        # Refresh the display:
        self.qplt_transfer.replot()
        self.qplt_openloop.replot()

        return
    def updateGraph(self):

        if self.qcombo_units.currentIndex() == 0:
            bGraphIndBs = True
        else:
            bGraphIndBs = False
        # System sign:
        if self.qradio_signp.isChecked():
            sign = 1
        else:
            sign = -1

        # add looping over many curves...
        print "updateGraph: %d curves in list." % (len(self.curve_mag_list))
        for kCurve in range(len(self.curve_mag_list)):
            print "updateGraph: curve %d of %d." % (kCurve,
                                                    len(self.curve_mag_list))

            self.curve_phase_list[kCurve].setData(
                self.frequency_axis_list[kCurve],
                np.angle(sign * (self.transfer_function_list[kCurve]))
            )  # phase graph is usually just the phase of the transfer function, except for a few scalings

            if bGraphIndBs == True:
                self.curve_mag_list[kCurve].setData(
                    self.frequency_axis_list[kCurve],
                    20 * np.log10(np.abs(self.transfer_function_list[kCurve])))
                self.qplt_mag.setAxisTitle(
                    Qwt.QwtPlot.yLeft,
                    'dB[(%s)^2]' % self.vertical_units_list[kCurve])
                self.qplt_mag.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                 Qwt.QwtLinearScaleEngine())
            else:
                if self.qcombo_units.currentIndex() == 2:
                    # Linear real part
                    self.curve_mag_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        (np.real(self.transfer_function_list[kCurve])))
                    self.qplt_mag.setAxisTitle(
                        Qwt.QwtPlot.yLeft,
                        '%s' % self.vertical_units_list[kCurve])
                    self.qplt_mag.setAxisScaleEngine(
                        Qwt.QwtPlot.yLeft, Qwt.QwtLinearScaleEngine())
                elif self.qcombo_units.currentIndex() == 3:
                    # Linear imag part
                    self.curve_mag_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        (np.imag(self.transfer_function_list[kCurve])))
                    self.qplt_mag.setAxisTitle(
                        Qwt.QwtPlot.yLeft,
                        '%s' % self.vertical_units_list[kCurve])
                    self.qplt_mag.setAxisScaleEngine(
                        Qwt.QwtPlot.yLeft, Qwt.QwtLinearScaleEngine())
                elif self.qcombo_units.currentIndex() == 1:
                    # linear magnitude and phase
                    self.curve_mag_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        (np.abs(self.transfer_function_list[kCurve])))
                    self.qplt_mag.setAxisTitle(
                        Qwt.QwtPlot.yLeft,
                        '%s' % self.vertical_units_list[kCurve])
                    self.qplt_mag.setAxisScaleEngine(
                        Qwt.QwtPlot.yLeft, Qwt.QwtLinearScaleEngine())
                elif self.qcombo_units.currentIndex() == 4:
                    # 'Ohms, 50*Vin/Vout'
                    Zsource = 50
                    test_impedance = (Zsource /
                                      (self.transfer_function_list[kCurve]))
                    self.curve_mag_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        np.abs(test_impedance))
                    self.qplt_mag.setAxisTitle(Qwt.QwtPlot.yLeft, 'Ohms')
                    self.qplt_mag.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                     Qwt.QwtLog10ScaleEngine())
                    self.curve_phase_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        np.angle(-sign * (test_impedance)))
                elif self.qcombo_units.currentIndex() == 5:
                    # 'Ohms, shunt DUT'])
                    Zsource = 50.
                    Zinput = 50.
                    load_impedance = (
                        Zsource * (self.transfer_function_list[kCurve] /
                                   (1 - self.transfer_function_list[kCurve])))
                    # load impedance consists of the impedance that we want to measure in parallel with 50 ohms so we need to invert this too
                    load_admittance = 1 / load_impedance
                    unknown_admittance = load_admittance - 1 / Zinput
                    unknown_impedance = 1 / unknown_admittance
                    print load_admittance[0]
                    print load_impedance[0]
                    print unknown_admittance[0]
                    print unknown_impedance[0]
                    self.curve_mag_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        np.abs(unknown_impedance))
                    self.qplt_mag.setAxisTitle(Qwt.QwtPlot.yLeft, 'Ohms')
                    self.qplt_mag.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                     Qwt.QwtLog10ScaleEngine())
                    self.curve_phase_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        np.angle(sign * (unknown_impedance)))

                    print kCurve
                    print len(self.curve_mag_list) - 1
                    if kCurve == len(self.curve_mag_list) - 1:
                        strNotes = ''
                        for kFreq in range(
                                len(self.frequency_axis_list[kCurve])):
                            strNotes += '%.2e Hz: Z = %.2e + j*%.2e\n' % (
                                self.frequency_axis_list[kCurve][kFreq],
                                np.real(unknown_impedance[kFreq]),
                                np.imag(unknown_impedance[kFreq]))
                        self.qedit_comment.setText(strNotes)
                        print strNotes

                elif self.qcombo_units.currentIndex() == 6:
                    # 'Ohms, Shunt DUT, high-Z probe + Series source impedance'
                    try:
                        Zsource = float(self.qedit_SeriesImpedance.text())
                    except:
                        Zsource = 100e3 + 50.
                        pass

    #                load_impedance = (Zsource*(10.*self.transfer_function_list[kCurve]/(1-10.*self.transfer_function_list[kCurve])))
                    load_impedance = (
                        -Zsource *
                        (10. * self.transfer_function_list[kCurve] /
                         (10. * self.transfer_function_list[kCurve] - 1.)))
                    self.curve_mag_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        np.abs(load_impedance))
                    self.qplt_mag.setAxisTitle(Qwt.QwtPlot.yLeft, 'Ohms')

                    self.qplt_mag.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                     Qwt.QwtLog10ScaleEngine())
                    self.curve_phase_list[kCurve].setData(
                        self.frequency_axis_list[kCurve],
                        np.angle(sign * (load_impedance)))

                    if kCurve == len(self.curve_mag_list) - 1:
                        strNotes = ''
                        for kFreq in range(
                                len(self.frequency_axis_list[kCurve])):
                            strNotes += '%.2e Hz: Z = %.2e + j*%.2e\n' % (
                                self.frequency_axis_list[kCurve][kFreq],
                                np.real(load_impedance[kFreq]),
                                np.imag(load_impedance[kFreq]))
                        self.qedit_comment.setText(strNotes)

            print "update curve complete."

        self.qplt_phase.setAxisTitle(Qwt.QwtPlot.yLeft, 'Phase [rad]')
        self.qplt_mag.replot()
        self.qplt_phase.replot()
Exemple #15
0
    def __init__(self, parent=None, logger=None):
        super(GLPlotWidget, self).__init__()

        self.glWidget = GLWidget(self)

        self.xmin = 0.1
        self.xmax = 1.
        self.ymin = 0.1
        self.ymax = 1.

        self.peaks_enabled = True
        self.peak = zeros((3, ))
        self.peak_int = zeros((3, ))
        self.peak_decay = ones((3, )) * PEAK_DECAY_RATE

        self.x1 = array([0.1, 0.5, 1.])
        self.x2 = array([0.5, 1., 2.])
        self.y = array([0., 0., 0.])

        self.fmax = 1e3

        self.transformed_x1 = self.x1
        self.transformed_x2 = self.x2

        self.baseline_transformed = False
        self.baseline = 0.

        self.topDist = 0
        self.bottomDist = 0
        self.leftDist = 0
        self.rightDist = 0

        self.needtransform = False

        self.verticalScaleEngine = Qwt.QwtLinearScaleEngine()

        self.verticalScale = Qwt.QwtScaleWidget(self)
        vtitle = Qwt.QwtText("PSD (dB)")
        vtitle.setFont(QtGui.QFont(8))
        self.verticalScale.setTitle(vtitle)
        self.verticalScale.setScaleDiv(
            self.verticalScaleEngine.transformation(),
            self.verticalScaleEngine.divideScale(self.ymin, self.ymax, 8, 5))
        self.verticalScale.setMargin(2)

        self.logx = False
        self.horizontalScaleEngine = Qwt.QwtLinearScaleEngine()

        self.horizontalScale = Qwt.QwtScaleWidget(self)
        htitle = Qwt.QwtText("Frequency (Hz)")
        htitle.setFont(QtGui.QFont(8))
        self.horizontalScale.setTitle(htitle)
        self.horizontalScale.setScaleDiv(
            self.horizontalScaleEngine.transformation(),
            self.horizontalScaleEngine.divideScale(self.xmin, self.xmax, 8, 5))
        self.horizontalScale.setAlignment(Qwt.QwtScaleDraw.BottomScale)
        self.horizontalScale.setMargin(2)
        self.horizontalScale.setSizePolicy(QtGui.QSizePolicy.Preferred,
                                           QtGui.QSizePolicy.Preferred)

        plotLayout = QtGui.QGridLayout()
        plotLayout.setSpacing(0)
        plotLayout.setContentsMargins(0, 0, 0, 0)
        plotLayout.addWidget(self.verticalScale, 0, 0)
        plotLayout.addWidget(self.glWidget, 0, 1)
        plotLayout.addWidget(self.horizontalScale, 1, 1)

        self.setLayout(plotLayout)
    def displayFreqCounter(self):
        #        (freq_counter_samples, time_axis, DAC0_output, DAC1_output, DAC2_output) = self.sl.read_zero_deadtime_freq_counter(self.output_number)
        try:
            (freq_counter_samples, time_axis, DAC0_output, DAC1_output,
             DAC2_output) = self.sl.read_dual_mode_counter(self.output_number)
            # print (freq_counter_samples, time_axis, DAC0_output, DAC1_output, DAC2_output)

        except:
            print(
                'Exception occured reading counter data. disabling further updates.'
            )
            self.killTimer(self.timerID)
            freq_counter_samples = 0
            time_axis = 0
            DAC0_output = 0
            DAC1_output = 0
            DAC2_output = 0

            raise

        try:
            if time_axis is not None:
                # scale to seconds:
                time_axis = time_axis.astype(float) * self.gate_time
                # Write data to disk:
                self.file_output_time.write(time_axis)

            if DAC0_output is not None:
                # Scale to minimum and maximum limits: 0 means minimum, 1 means maximum
                DAC0_output = (DAC0_output - self.sl.DACs_limit_low[0]).astype(
                    np.float) / float(self.sl.DACs_limit_high[0] -
                                      self.sl.DACs_limit_low[0])
                # Write data to disk:
                self.file_output_dac0.write(DAC0_output)

            if DAC1_output is not None:
                # Scale to minimum and maximum limits: 0 means minimum, 1 means maximum
                DAC1_output = (DAC1_output - self.sl.DACs_limit_low[1]).astype(
                    np.float) / float(self.sl.DACs_limit_high[1] -
                                      self.sl.DACs_limit_low[1])
                # Write data to disk:
                self.file_output_dac1.write(DAC1_output)

            if DAC2_output is not None:
                # Scale to minimum and maximum limits: 0 means minimum, 1 means maximum
                DAC2_output = (DAC2_output - self.sl.DACs_limit_low[2]).astype(
                    np.float) / float(self.sl.DACs_limit_high[2] -
                                      self.sl.DACs_limit_low[2])
                # Write data to disk:
                self.file_output_dac2.write(DAC2_output)

                self.runTempControlLoop(time.clock(), DAC2_output[-1:])

            if freq_counter_samples is not None:
                if self.bVeryFirst == True:
                    # We flush the first two samples because the system isn't fully initialized and they always force the plot scale too wide
                    freq_counter_samples = freq_counter_samples[2:]
                    if self.output_number == 0 and (DAC0_output is not None):
                        DAC0_output = DAC0_output[2:]
                    if self.output_number == 1 and (DAC1_output is not None):
                        DAC1_output = DAC1_output[2:]
                        DAC2_output = DAC2_output[2:]
                    self.bVeryFirst = False
                    return

                self.runFreqControlLoop(time.clock(),
                                        freq_counter_samples[-1:])

                # Write data to disk:
                if self.output_number == 0:
                    self.file_output_counter0.write(freq_counter_samples)
                elif self.output_number == 1:
                    self.file_output_counter1.write(freq_counter_samples)

                # Record the new chunk of data in the buffer:
#                print('len = %d' % len(freq_counter_samples))
                self.freq_history[:-len(freq_counter_samples
                                        )] = self.freq_history[
                                            len(freq_counter_samples):]
                self.freq_history[-len(freq_counter_samples
                                       ):] = freq_counter_samples

                if self.output_number == 0:
                    self.DAC0_history[:-len(DAC0_output)] = self.DAC0_history[
                        len(DAC0_output):]
                    self.DAC0_history[-len(DAC0_output):] = DAC0_output
                    self.bValid_dacs[:-len(DAC0_output)] = self.bValid_dacs[
                        len(DAC0_output):]
                    self.bValid_dacs[-len(DAC0_output):] = True
                if self.output_number == 1:
                    self.DAC1_history[:-len(DAC1_output)] = self.DAC1_history[
                        len(DAC1_output):]
                    self.DAC1_history[-len(DAC1_output):] = DAC1_output
                    self.DAC2_history[:-len(DAC1_output)] = self.DAC2_history[
                        len(DAC1_output):]
                    self.DAC2_history[-len(DAC1_output):] = DAC2_output
                    self.bValid_dacs[:-len(DAC1_output)] = self.bValid_dacs[
                        len(DAC1_output):]
                    self.bValid_dacs[-len(DAC1_output):] = True

    #            self.time_history[:-len(freq_counter_samples)] = self.time_history[len(freq_counter_samples):]
    #            self.time_history[-len(freq_counter_samples):] = time_axis

                self.bValid_counters[:-len(freq_counter_samples
                                           )] = self.bValid_counters[
                                               len(freq_counter_samples):]
                self.bValid_counters[-len(freq_counter_samples):] = True

                channelName = ''
                if self.output_number == 0:
                    channelName = 'CEO'
                if self.output_number == 1:
                    channelName = 'Optical'

                # Update graph:
                self.curve_freq_error.setData(
                    self.time_history_counters[self.bValid_counters] -
                    self.time_history_counters[len(self.time_history_counters)
                                               - 1],
                    self.freq_history[self.bValid_counters])
                self.qplt_freq.setTitle(
                    '%s Lock Freq error, mean = %.6f Hz, std = %.3f mHz' %
                    (channelName,
                     np.mean(self.freq_history[self.bValid_counters]),
                     1e3 * np.std(self.freq_history[self.bValid_counters])))
                if self.qchk_fullscale_freq.isChecked():
                    self.qplt_freq.setAxisScaleEngine(
                        Qwt.QwtPlot.yLeft, Qwt.QwtLinearScaleEngine())
                    try:
                        ymin = float(self.qedit_ymin.text())
                        ymax = float(self.qedit_ymax.text())
                    except:
                        ymin = -25e6
                        ymax = 25e6

                    self.qplt_freq.setAxisScale(Qwt.QwtPlot.yLeft, ymin, ymax)
                else:
                    self.qplt_freq.setAxisAutoScale(Qwt.QwtPlot.yLeft)

                self.qplt_freq.replot()

                # Update graph:
                if self.output_number == 0:
                    self.curve_dac0.setData(
                        self.time_history_dacs[self.bValid_dacs] -
                        self.time_history_dacs[len(self.time_history_dacs) -
                                               1],
                        self.DAC0_history[self.bValid_dacs])
                    self.qplt_dac.setTitle(
                        '%s Lock DAC outputs, last raw code = %f' %
                        (channelName, self.DAC0_history[-1]))

                if self.output_number == 1:
                    self.curve_dac1.setData(
                        self.time_history_dacs[self.bValid_dacs] -
                        self.time_history_dacs[len(self.time_history_dacs) -
                                               1],
                        self.DAC1_history[self.bValid_dacs])
                    self.curve_dac2.setData(
                        self.time_history_dacs[self.bValid_dacs] -
                        self.time_history_dacs[len(self.time_history_dacs) -
                                               1],
                        self.DAC2_history[self.bValid_dacs])
                    self.qplt_dac.setTitle(
                        '%s Lock DAC outputs, last raw codes = %f, %f' %
                        (channelName, self.DAC1_history[-1],
                         self.DAC2_history[-1]))

                if self.qchk_fullscale_dac.isChecked():
                    self.qplt_dac.setAxisScaleEngine(
                        Qwt.QwtPlot.yLeft, Qwt.QwtLinearScaleEngine())
                    self.qplt_dac.setAxisScale(Qwt.QwtPlot.yLeft, 0, 1)
                else:
                    self.qplt_dac.setAxisAutoScale(Qwt.QwtPlot.yLeft)

                self.qplt_dac.replot()

        except:
            print(
                'Exception occured parsing counter data. disabling further updates.'
            )
            self.killTimer(self.timerID)
            freq_counter_samples = 0
            time_axis = 0
            DAC0_output = 0
            DAC1_output = 0
            DAC2_output = 0

            raise
    def __init__(self, module, *args):
        ''' Constructor
        @param module: parent module
        '''
        apply(Qt.QDialog.__init__, (self, ) + args)
        self.setupUi(self)
        self.module = module
        self.params = None  # last received parameter block
        self.data = None  # last received data block

        # create table view grid (10x16 eeg electrodes + 1 row for ground electrode)
        cc = 10
        rc = 16
        self.tableWidgetValues.setColumnCount(cc)
        self.tableWidgetValues.setRowCount(rc + 1)
        self.tableWidgetValues.horizontalHeader().setResizeMode(
            Qt.QHeaderView.Stretch)
        self.tableWidgetValues.horizontalHeader().setDefaultAlignment(
            Qt.Qt.Alignment(Qt.Qt.AlignCenter))
        self.tableWidgetValues.verticalHeader().setResizeMode(
            Qt.QHeaderView.Stretch)
        self.tableWidgetValues.verticalHeader().setDefaultAlignment(
            Qt.Qt.Alignment(Qt.Qt.AlignCenter))
        # add ground electrode row
        self.tableWidgetValues.setSpan(rc, 0, 1, cc)
        # row headers
        rheader = Qt.QStringList()
        for r in xrange(rc):
            rheader.append("%d - %d" % (r * cc + 1, r * cc + cc))
        rheader.append("GND")
        self.tableWidgetValues.setVerticalHeaderLabels(rheader)
        # create cell items
        fnt = Qt.QFont()
        fnt.setPointSize(8)
        for r in xrange(rc):
            for c in xrange(cc):
                item = Qt.QTableWidgetItem()
                item.setTextAlignment(Qt.Qt.AlignCenter)
                item.setFont(fnt)
                self.tableWidgetValues.setItem(r, c, item)
        # GND electrode cell
        item = Qt.QTableWidgetItem()
        item.setTextAlignment(Qt.Qt.AlignCenter)
        item.setFont(fnt)
        item.setText("GND")
        self.tableWidgetValues.setItem(rc, 0, item)
        self.defaultColor = item.backgroundColor()

        # set range list
        self.comboBoxRange.clear()
        self.comboBoxRange.addItem("15")
        self.comboBoxRange.addItem("50")
        self.comboBoxRange.addItem("100")
        self.comboBoxRange.addItem("500")

        # set validators
        validator = Qt.QIntValidator(self)
        validator.setBottom(15)
        validator.setTop(500)
        self.comboBoxRange.setValidator(validator)
        self.comboBoxRange.setEditText(str(self.module.range_max))

        # setup color scale
        self.linearscale = False
        self.scale_engine = Qwt.QwtLinearScaleEngine()
        self.scale_interval = Qwt.QwtDoubleInterval(0, self.module.range_max)
        self.scale_map = Qwt.QwtLinearColorMap(Qt.Qt.green, Qt.Qt.red)
        if self.linearscale:
            self.scale_map.addColorStop(0.45, Qt.Qt.yellow)
            self.scale_map.addColorStop(0.55, Qt.Qt.yellow)
            self.scale_map.setMode(Qwt.QwtLinearColorMap.ScaledColors)
        else:
            self.scale_map.addColorStop(0.33, Qt.Qt.yellow)
            self.scale_map.addColorStop(0.66, Qt.Qt.red)
            self.scale_map.setMode(Qwt.QwtLinearColorMap.FixedColors)
        self.ScaleWidget.setColorMap(self.scale_interval, self.scale_map)
        self.ScaleWidget.setColorBarEnabled(True)
        self.ScaleWidget.setColorBarWidth(30)
        self.ScaleWidget.setBorderDist(10, 10)

        # set default values
        self.setColorRange(0, self.module.range_max)
        self.checkBoxValues.setChecked(self.module.show_values)

        # actions
        self.connect(self.comboBoxRange, Qt.SIGNAL("editTextChanged(QString)"),
                     self._rangeChanged)
        self.connect(self.checkBoxValues, Qt.SIGNAL("stateChanged(int)"),
                     self._showvalues_changed)
        self.connect(self.module, Qt.SIGNAL('update(PyQt_PyObject)'),
                     self._updateValues)
    def displayFreqCounter(self):
        (freq_counter_samples, time_axis, DAC0_output, DAC1_output,
         DAC2_output) = self.sl.read_zero_deadtime_freq_counter(
             self.output_number)

        if type(time_axis) != type(0):
            # scale to seconds:
            time_axis = time_axis.astype(float) * self.gate_time
            # Write data to disk:
            self.file_output_time.write(time_axis)

        if type(DAC0_output) != type(0):
            # Scale to minimum and maximum limits: 0 means minimum, 1 means maximum
            DAC0_output = (DAC0_output - self.sl.DACs_limit_low[0]).astype(
                np.float) / float(self.sl.DACs_limit_high[0] -
                                  self.sl.DACs_limit_low[0])
            # Write data to disk:
            self.file_output_dac0.write(DAC0_output)

        if type(DAC1_output) != type(0):
            # Scale to minimum and maximum limits: 0 means minimum, 1 means maximum
            DAC1_output = (DAC1_output - self.sl.DACs_limit_low[1]).astype(
                np.float) / float(self.sl.DACs_limit_high[1] -
                                  self.sl.DACs_limit_low[1])
            # Write data to disk:
            self.file_output_dac1.write(DAC1_output)

        if type(DAC2_output) != type(0):
            # Scale to minimum and maximum limits: 0 means minimum, 1 means maximum
            DAC2_output = (DAC2_output - self.sl.DACs_limit_low[2]).astype(
                np.float) / float(self.sl.DACs_limit_high[2] -
                                  self.sl.DACs_limit_low[2])
            # Write data to disk:
            self.file_output_dac2.write(DAC2_output)

            self.runTempControlLoop(time.clock(), DAC2_output[-1:])

        if type(freq_counter_samples) != type(0):
            if self.bVeryFirst == True:
                # We flush the first two samples because the system isn't fully initialized and they always force the plot scale too wide
                freq_counter_samples = freq_counter_samples[2:]
                if self.output_number == 0:
                    DAC0_output = DAC0_output[2:]
                if self.output_number == 1:
                    DAC1_output = DAC1_output[2:]
                    DAC2_output = DAC2_output[2:]
                self.bVeryFirst = False

            # Write data to disk:
            if self.output_number == 0:
                self.file_output_counter0.write(freq_counter_samples)
            elif self.output_number == 1:
                self.file_output_counter1.write(freq_counter_samples)

            # Record the new chunk of data in the buffer:
            self.freq_history[:-len(freq_counter_samples)] = self.freq_history[
                len(freq_counter_samples):]
            self.freq_history[-len(freq_counter_samples
                                   ):] = freq_counter_samples

            if self.output_number == 0:
                self.DAC0_history[:-len(freq_counter_samples
                                        )] = self.DAC0_history[
                                            len(freq_counter_samples):]
                self.DAC0_history[-len(freq_counter_samples):] = DAC0_output
            if self.output_number == 1:
                self.DAC1_history[:-len(freq_counter_samples
                                        )] = self.DAC1_history[
                                            len(freq_counter_samples):]
                self.DAC1_history[-len(freq_counter_samples):] = DAC1_output
                self.DAC2_history[:-len(freq_counter_samples
                                        )] = self.DAC2_history[
                                            len(freq_counter_samples):]
                self.DAC2_history[-len(freq_counter_samples):] = DAC2_output

#            self.time_history[:-len(freq_counter_samples)] = self.time_history[len(freq_counter_samples):]
#            self.time_history[-len(freq_counter_samples):] = time_axis

            self.bValid[:-len(freq_counter_samples
                              )] = self.bValid[len(freq_counter_samples):]
            self.bValid[-len(freq_counter_samples):] = True

            # Update graph:
            self.curve_freq_error.setData(
                self.time_history[self.bValid] -
                self.time_history[len(self.time_history) - 1],
                self.freq_history[self.bValid])
            self.qplt_freq.setTitle(
                'Lock #%d Frequency error, mean = %f Hz, std = %.3f Hz' %
                (self.output_number, np.mean(self.freq_history[self.bValid]),
                 np.std(self.freq_history[self.bValid])))
            if self.qchk_fullscale_freq.isChecked():
                self.qplt_freq.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                  Qwt.QwtLinearScaleEngine())
                self.qplt_freq.setAxisScale(Qwt.QwtPlot.yLeft, -5e6, 5e6)
            else:
                self.qplt_freq.setAxisAutoScale(Qwt.QwtPlot.yLeft)

            self.qplt_freq.replot()

            # Update graph:
            if self.output_number == 0:
                self.curve_dac0.setData(
                    self.time_history[self.bValid] -
                    self.time_history[len(self.time_history) - 1],
                    self.DAC0_history[self.bValid])
                self.qplt_dac.setTitle(
                    'Lock #%d DAC outputs, last raw code = %f' %
                    (self.output_number, self.DAC0_history[-1]))

            if self.output_number == 1:
                self.curve_dac1.setData(
                    self.time_history[self.bValid] -
                    self.time_history[len(self.time_history) - 1],
                    self.DAC1_history[self.bValid])
                self.curve_dac2.setData(
                    self.time_history[self.bValid] -
                    self.time_history[len(self.time_history) - 1],
                    self.DAC2_history[self.bValid])
                self.qplt_dac.setTitle(
                    'Lock #%d DAC outputs, last raw codes = %f, %f' %
                    (self.output_number, self.DAC1_history[-1],
                     self.DAC2_history[-1]))

            if self.qchk_fullscale_dac.isChecked():
                self.qplt_dac.setAxisScaleEngine(Qwt.QwtPlot.yLeft,
                                                 Qwt.QwtLinearScaleEngine())
                self.qplt_dac.setAxisScale(Qwt.QwtPlot.yLeft, 0, 1)
            else:
                self.qplt_dac.setAxisAutoScale(Qwt.QwtPlot.yLeft)

            self.qplt_dac.replot()
    def plotSelection(self):
        if not self.measurementIsSelected() or not self.parameterIsSelected():
            return

        # Clear already plotted Curves
        self.qwtPlot.detachItems()

        data = self.selectedParameterData()
        frequencies = self.currentProject().fft_frequencies()

        if self.useFrequencyRangeLimits:
            # We cast to float64 - equality on python-floats is a very risky thing
            lowerDisplayedFrequency = np.float64(self.dsbLowerDisplayedFrequency.value())
            upperDisplayedFrequency = np.float64(self.dsbUpperDisplayedFrequency.value())
            fftRes = self.currentProject().fft_resolution

            start_index = np.where(np.isclose(frequencies, lowerDisplayedFrequency))[0][0]
            stop_index = np.where(np.isclose(frequencies, upperDisplayedFrequency))[0][0] + 1

            data = data[start_index:stop_index]
            frequencies = frequencies[start_index:stop_index]

        # Set Y Axis Title
        self.qwtPlot.setAxisTitle(Qwt5.QwtPlot.yLeft, self.selectedParameterName())

        if self.graphConfig.showReal:
            curve = Qwt5.QwtPlotCurve('Realteil')
            curve.setData(frequencies, data.real)
            curve.setPen(QtGui.QPen(QtCore.Qt.red))
            curve.setRenderHint(Qwt5.QwtPlotItem.RenderAntialiased)
            curve.attach(self.qwtPlot)

        if self.graphConfig.showImag:
            curve = Qwt5.QwtPlotCurve('Imaginaerteil')
            curve.setData(frequencies, data.imag)
            curve.setPen(QtGui.QPen(QtCore.Qt.yellow))
            curve.setRenderHint(Qwt5.QwtPlotItem.RenderAntialiased)
            curve.attach(self.qwtPlot)

        if self.graphConfig.showAbs:
            curve = Qwt5.QwtPlotCurve('Betrag')
            curve.setData(frequencies, np.abs(data))
            curve.setPen(QtGui.QPen(QtCore.Qt.blue))
            curve.setRenderHint(Qwt5.QwtPlotItem.RenderAntialiased)
            curve.attach(self.qwtPlot)

        if self.graphConfig.showPhase:
            curve = Qwt5.QwtPlotCurve('Phase')

            if self.graphConfig.unwrapPhase:
                curve.setData(frequencies, np.unwrap(np.angle(data), self.graphConfig.unwrapDiscont))
            else:
                curve.setData(frequencies, np.angle(data))
            curve.setPen(QtGui.QPen(QtCore.Qt.green))
            curve.setRenderHint(Qwt5.QwtPlotItem.RenderAntialiased)
            curve.attach(self.qwtPlot)

        # Build Legend
        legend = Qwt5.QwtLegend()
        legend.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Sunken)
        self.qwtPlot.insertLegend(legend, Qwt5.QwtPlot.RightLegend)

        # Set Axis Scaling
        if self.graphConfig.xAxisLinear:
            self.qwtPlot.setAxisScaleEngine(Qwt5.QwtPlot.xBottom, Qwt5.QwtLinearScaleEngine())
        else:
            self.qwtPlot.setAxisScaleEngine(Qwt5.QwtPlot.xBottom, Qwt5.QwtLog10ScaleEngine())

        if self.graphConfig.yAxisLinear:
            self.qwtPlot.setAxisScaleEngine(Qwt5.QwtPlot.yLeft, Qwt5.QwtLinearScaleEngine())
        else:
            self.qwtPlot.setAxisScaleEngine(Qwt5.QwtPlot.yLeft, Qwt5.QwtLog10ScaleEngine())

        # See this: http://stackoverflow.com/questions/14685010/qwt-plot-auto-scale-not-working
        self.qwtPlot.axisScaleEngine(Qwt5.QwtPlot.xBottom).setAttribute(Qwt5.QwtScaleEngine.Floating, True)
        self.qwtPlot.axisScaleEngine(Qwt5.QwtPlot.yLeft).setAttribute(Qwt5.QwtScaleEngine.Floating, True)

        self.qwtPlot.replot()