Exemplo n.º 1
0
    def create_slice_dock(self):
        widget = QWidget()
        dock = QDockWidget("Slice", self)
        dock.setAllowedAreas(Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea
                             | Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.addDockWidget(Qt.BottomDockWidgetArea, dock)
        layout = QGridLayout(widget)
        self.slice_index_spin_box = QSpinBox()
        index_max = self.map_.measurement.param.axis3.get_length()
        self.slice_index_spin_box.setRange(0, index_max - 1)

        slice_slider = QSlider(Qt.Horizontal)
        slice_slider.setRange(0, index_max - 1)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     self.set_slice_index)
        self.connect(slice_slider, SIGNAL("valueChanged(int)"),
                     self.slice_index_spin_box.setValue)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     slice_slider.setValue)
        self.slice_value_spin_box = QDoubleSpinBox()
        scale = self.map_.measurement.param.axis3.get_scale()
        self.slice_value_spin_box.setRange(scale.min(), scale.max())
        self.slice_value_spin_box.setValue(scale[0])
        self.connect(self.slice_value_spin_box, SIGNAL("valueChanged(double)"),
                     self.set_slice_value)
        unit = self.map_.measurement.param.axis3.unit
        self.slice_value_spin_box.setSuffix(unit)
        layout.addWidget(slice_slider, 0, 0)
        layout.addWidget(self.slice_index_spin_box, 0, 1)
        layout.addWidget(self.slice_value_spin_box, 0, 2)
        dock.setWidget(widget)
Exemplo n.º 2
0
    def __init__(self, parent):
        super(MakeNicerWidget, self).__init__(parent)

        self.data = np.array([])  # array which holds data

        # Time domain plot
        self.tdWidget = DockablePlotWidget(self, CurveWidget)
        self.tdWidget.calcFun.addFun('fs', lambda x: x, lambda x: x)
        self.tdWidget.calcFun.addFun('µm', lambda x: x * fsDelay * 1e3,
                                     lambda x: x / fsDelay * 1e-3)
        self.tdWidget.calcFun.addFun('mm', lambda x: x * fsDelay,
                                     lambda x: x / fsDelay)
        tdPlot = self.tdWidget.get_plot()
        self.tdSignal = SignalFT(self, plot=tdPlot)
        self.tdFit = SignalFT(self, plot=tdPlot, col='r')

        # Frequency domain plot
        self.fdWidget = DockablePlotWidget(self, CurveWidget)
        self.fdWidget.calcFun.addFun('PHz', lambda x: x, lambda x: x)
        self.fdWidget.calcFun.addFun('THz', lambda x: x * 1e3,
                                     lambda x: x * 1e-3)
        self.fdWidget.calcFun.addFun('µm', lambda x: c0 / x * 1e-9,
                                     lambda x: c0 / x * 1e-9)
        self.fdWidget.calcFun.addFun('eV', lambda x: x, lambda x: x)
        fdplot = self.fdWidget.get_plot()
        self.fdSignal = SignalFT(self, plot=fdplot)
        self.fdFit = SignalFT(self, plot=fdplot, col='r')

        self.smoothNum = QSpinBox()  # gives number of smoothin points
        self.smoothNum.setMinimum(1)
        self.smoothNum.setSingleStep(2)

        # Put things together in layouts
        buttonLayout = QGridLayout()
        plotLayout = QVBoxLayout()
        layout = QHBoxLayout()
        plotLayout.addWidget(self.tdWidget)
        plotLayout.addWidget(self.fdWidget)

        buttonLayout.addWidget(QLabel('Fitting function'), 0, 0)
        buttonLayout.addWidget(
            QLineEdit("lambda x,A,f,phi: np.sin(2*np.pi*f*x+phi)"), 1, 0, 1, 2)
        buttonLayout.addWidget(QLabel('Smooth'), 2, 0)
        buttonLayout.addWidget(self.smoothNum, 2, 1)
        buttonLayout.setRowStretch(3, 20)

        layout.addLayout(buttonLayout)
        layout.addLayout(plotLayout)
        self.setLayout(layout)

        # connect signals
        self.updateTdPlot.connect(self.tdSignal.updatePlot)
        self.updateTdFitPlot.connect(self.tdFit.updatePlot)
        self.updateFdPlot.connect(lambda data: self.fdSignal.updatePlot(
            self.fdSignal.computeFFT(data)))
        self.updateFdFitPlot.connect(
            lambda data: self.fdFit.updatePlot(self.fdFit.computeFFT(data)))
        self.smoothNum.valueChanged.connect(self.smoothData)

        self.setData()
Exemplo n.º 3
0
    def create_slice_dock(self):
        widget = QWidget()
        dock = QDockWidget("Slice", self)
        dock.setAllowedAreas(Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea |
                             Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.addDockWidget(Qt.BottomDockWidgetArea, dock)
        layout = QGridLayout(widget)
        self.slice_index_spin_box = QSpinBox()
        index_max = self.map_.measurement.param.axis3.get_length()
        self.slice_index_spin_box.setRange(0, index_max-1 )

        slice_slider = QSlider(Qt.Horizontal)
        slice_slider.setRange(0, index_max-1)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     self.set_slice_index)
        self.connect(slice_slider, SIGNAL("valueChanged(int)"),
                     self.slice_index_spin_box.setValue)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     slice_slider.setValue)
        self.slice_value_spin_box = QDoubleSpinBox()
        scale = self.map_.measurement.param.axis3.get_scale()
        self.slice_value_spin_box.setRange(scale.min(),scale.max())
        self.slice_value_spin_box.setValue(scale[0])
        self.connect(self.slice_value_spin_box, SIGNAL("valueChanged(double)"),
                     self.set_slice_value)
        unit = self.map_.measurement.param.axis3.unit
        self.slice_value_spin_box.setSuffix(unit)
        layout.addWidget(slice_slider, 0, 0)
        layout.addWidget(self.slice_index_spin_box, 0, 1)
        layout.addWidget(self.slice_value_spin_box, 0, 2)
        dock.setWidget(widget)
Exemplo n.º 4
0
    def __init__(self, parent):
        #super(ObjectFT, self).__init__(Qt.Vertical, parent)
        super().__init__(parent)

        self.scp = None  # variable to hold oscilloscope object
        self.mutex = QMutex()

        layoutWidget = QWidget()
        layout = QGridLayout()
        layoutWidget.setLayout(layout)

        self.openDevBtn = QPushButton('Open Osci')
        # channel stuff
        self.measCh = QComboBox()
        self.chSens = QComboBox()
        self.triggCh = QComboBox()
        self.frequency = QLineEdit()
        self.frequency.setValidator(QIntValidator())
        self.recordLen = QLineEdit()
        self.recordLen.setValidator(QIntValidator())
        self.delay = QLineEdit()
        self.delay.setValidator(QDoubleValidator())
        # trigger stuff
        self.triggLevel = QLineEdit()
        self.triggLevel.setToolTip(
            'http://api.tiepie.com/libtiepie/0.5/triggering_scpch.html#triggering_scpch_level'
        )
        self.triggLevel.setText(
            '0.5'
        )  # init value otherwise there's trouble with signal changing index of sensitivity
        self.triggLevel.setValidator(QDoubleValidator(0., 1., 3))
        self.hystereses = QLineEdit()
        self.hystereses.setText('0.05')
        self.hystereses.setToolTip(
            'http://api.tiepie.com/libtiepie/0.5/triggering_scpch.html#triggering_scpch_hysteresis'
        )
        self.hystereses.setValidator(QDoubleValidator(0., 1., 3))
        self.triggKind = QComboBox()
        # do averages
        self.averages = QSpinBox()
        self.averages.setValue(1)
        self.averages.setRange(1, 10000)

        # put layout together
        layout.addWidget(self.openDevBtn, 0, 0)
        layout.addWidget(QLabel('Measuring Ch'), 1, 0)
        layout.addWidget(self.measCh, 1, 1)
        layout.addWidget(QLabel('Ch sensitivity'), 2, 0)
        layout.addWidget(self.chSens, 2, 1)
        layout.addWidget(QLabel('Sample freq. (kHz)'), 3, 0)
        layout.addWidget(self.frequency, 3, 1)
        layout.addWidget(QLabel('Record length'), 4, 0)
        layout.addWidget(self.recordLen, 4, 1)
        layout.addWidget(QLabel('Delay'), 5, 0)
        layout.addWidget(self.delay, 5, 1)
        layout.addWidget(QLabel('Trigger Ch'), 6, 0)
        layout.addWidget(self.triggCh, 6, 1)
        layout.addWidget(QLabel('Trigger Level (%)'), 7, 0)
        layout.addWidget(self.triggLevel, 7, 1)
        layout.addWidget(QLabel('Hystereses'), 8, 0)
        layout.addWidget(self.hystereses, 8, 1)
        layout.addWidget(QLabel('Trigger kind'), 9, 0)
        layout.addWidget(self.triggKind, 9, 1)
        layout.addWidget(QLabel('Averages'), 10, 0)
        layout.addWidget(self.averages, 10, 1)
        layout.setRowStretch(11, 10)
        layout.setColumnStretch(2, 10)

        self.addWidget(layoutWidget)

        # connect UI to get things working
        self.openDevBtn.released.connect(self.openDev)
        self.chSens.currentIndexChanged.connect(self._changeSens)
        self.frequency.returnPressed.connect(self._changeFreq)
        self.recordLen.returnPressed.connect(self._changeRecordLength)
        self.triggCh.currentIndexChanged.connect(self._changeTrigCh)
        self.triggLevel.returnPressed.connect(self._triggLevelChanged)
        self.triggLevel.textChanged.connect(self._check_state)
        self.hystereses.returnPressed.connect(self._setHystereses)
        self.hystereses.textChanged.connect(self._check_state)
Exemplo n.º 5
0
class TiePieUi(QSplitter):
    '''
    Handling user interface to manage TiePie HS4/Diff Oscilloscope
    '''
    scpConnected = Signal()
    xAxeChanged = Signal(object, object)
    yAxeChanged = Signal(object, object)
    triggLevelChanged = Signal(object)

    def __init__(self, parent):
        #super(ObjectFT, self).__init__(Qt.Vertical, parent)
        super().__init__(parent)

        self.scp = None  # variable to hold oscilloscope object
        self.mutex = QMutex()

        layoutWidget = QWidget()
        layout = QGridLayout()
        layoutWidget.setLayout(layout)

        self.openDevBtn = QPushButton('Open Osci')
        # channel stuff
        self.measCh = QComboBox()
        self.chSens = QComboBox()
        self.triggCh = QComboBox()
        self.frequency = QLineEdit()
        self.frequency.setValidator(QIntValidator())
        self.recordLen = QLineEdit()
        self.recordLen.setValidator(QIntValidator())
        self.delay = QLineEdit()
        self.delay.setValidator(QDoubleValidator())
        # trigger stuff
        self.triggLevel = QLineEdit()
        self.triggLevel.setToolTip(
            'http://api.tiepie.com/libtiepie/0.5/triggering_scpch.html#triggering_scpch_level'
        )
        self.triggLevel.setText(
            '0.5'
        )  # init value otherwise there's trouble with signal changing index of sensitivity
        self.triggLevel.setValidator(QDoubleValidator(0., 1., 3))
        self.hystereses = QLineEdit()
        self.hystereses.setText('0.05')
        self.hystereses.setToolTip(
            'http://api.tiepie.com/libtiepie/0.5/triggering_scpch.html#triggering_scpch_hysteresis'
        )
        self.hystereses.setValidator(QDoubleValidator(0., 1., 3))
        self.triggKind = QComboBox()
        # do averages
        self.averages = QSpinBox()
        self.averages.setValue(1)
        self.averages.setRange(1, 10000)

        # put layout together
        layout.addWidget(self.openDevBtn, 0, 0)
        layout.addWidget(QLabel('Measuring Ch'), 1, 0)
        layout.addWidget(self.measCh, 1, 1)
        layout.addWidget(QLabel('Ch sensitivity'), 2, 0)
        layout.addWidget(self.chSens, 2, 1)
        layout.addWidget(QLabel('Sample freq. (kHz)'), 3, 0)
        layout.addWidget(self.frequency, 3, 1)
        layout.addWidget(QLabel('Record length'), 4, 0)
        layout.addWidget(self.recordLen, 4, 1)
        layout.addWidget(QLabel('Delay'), 5, 0)
        layout.addWidget(self.delay, 5, 1)
        layout.addWidget(QLabel('Trigger Ch'), 6, 0)
        layout.addWidget(self.triggCh, 6, 1)
        layout.addWidget(QLabel('Trigger Level (%)'), 7, 0)
        layout.addWidget(self.triggLevel, 7, 1)
        layout.addWidget(QLabel('Hystereses'), 8, 0)
        layout.addWidget(self.hystereses, 8, 1)
        layout.addWidget(QLabel('Trigger kind'), 9, 0)
        layout.addWidget(self.triggKind, 9, 1)
        layout.addWidget(QLabel('Averages'), 10, 0)
        layout.addWidget(self.averages, 10, 1)
        layout.setRowStretch(11, 10)
        layout.setColumnStretch(2, 10)

        self.addWidget(layoutWidget)

        # connect UI to get things working
        self.openDevBtn.released.connect(self.openDev)
        self.chSens.currentIndexChanged.connect(self._changeSens)
        self.frequency.returnPressed.connect(self._changeFreq)
        self.recordLen.returnPressed.connect(self._changeRecordLength)
        self.triggCh.currentIndexChanged.connect(self._changeTrigCh)
        self.triggLevel.returnPressed.connect(self._triggLevelChanged)
        self.triggLevel.textChanged.connect(self._check_state)
        self.hystereses.returnPressed.connect(self._setHystereses)
        self.hystereses.textChanged.connect(self._check_state)

    def openDev(self):
        # search for devices
        libtiepie.device_list.update()
        # try to open an oscilloscope with block measurement support
        for item in libtiepie.device_list:
            if item.can_open(libtiepie.DEVICETYPE_OSCILLOSCOPE):
                self.scp = item.open_oscilloscope()
                if self.scp.measure_modes & libtiepie.MM_BLOCK:
                    break
                else:
                    self.scp = None
        # init UI
        #print(self.scp.name, 'found')
        if self.scp is not None:
            # Set measure mode:
            self.scp.measure_mode = libtiepie.MM_BLOCK

            # Set sample frequency:
            self.scp.sample_frequency = 1e6  # 1 MHz

            # Set record length:
            self.scp.record_length = 10000  # 10000 samples

            # Set pre sample ratio:
            self.scp.pre_sample_ratio = 0  # 0 %

            # Set trigger timeout:
            self.scp.trigger_time_out = 100e-3  # 100 ms

            # Enable channel 1 for measurement
            # http://api.tiepie.com/libtiepie/0.5/group__scp__ch__enabled.html
            self.scp.channels[
                0].enabled = True  # by default all channels are enabled
            self.scp.range = 0.2
            self.scp.coupling = libtiepie.CK_DCV  # DC Volt

            # Disable all channel trigger sources
            for ch in self.scp.channels:
                ch.trigger.enabled = False
            # Setup channel trigger on 1
            ch = self.scp.channels[0]
            ch.trigger.enabled = True
            ch.trigger.kind = libtiepie.TK_RISINGEDGE
            ch.trigger.levels[0] = 0.5  # 50%
            ch.trigger.hystereses[0] = 0.05  # 5%

            # update UI
            # channel
            self.measCh.addItems(
                ['Ch{:d}'.format(i) for i in range(self.scp.channels.count)])
            self.chSens.addItems(
                ['{:.1f} V'.format(i) for i in self.scp.channels[0].ranges])
            self.frequency.setValidator(
                QIntValidator(1, 1e-3 * self.scp.sample_frequency_max))
            self.frequency.setText('{:d}'.format(
                int(self.scp.sample_frequency * 1e-3)))
            self.recordLen.setValidator(
                QIntValidator(1, self.scp.record_length_max))
            self.recordLen.setText('{:d}'.format(self.scp.record_length))
            # trigger
            self.triggCh.addItems(
                ['Ch{:d}'.format(i) for i in range(self.scp.channels.count)])
            # TODO: doen't work in module anymore!!
            #self.triggLevel.setText(str(ch.trigger.levels[0]))
            #self.hystereses.setText(str(ch.trigger.hystereses[0]))
            self.triggKind.addItems([
                '{:s}'.format(i) for i in libtiepie.trigger_kind_str(
                    ch.trigger.kinds).split(', ')
            ])

            self.openDevBtn.setEnabled(False)

            # tell the world that the scope is connected
            self.xAxeChanged.emit(
                0, 1 / int(self.frequency.text()) * 1e-3 *
                int(self.recordLen.text()))
            self.yAxeChanged.emit(-1 * self.scp.range, self.scp.range)
            self.triggLevelChanged.emit(ch.trigger.levels[0] * 2 *
                                        self.scp.range - self.scp.range)
            self.scpConnected.emit()

        else:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText('No supported device found')
            msg.exec_()

    def getData(self):
        # function called thread for updating plot
        avg = int(self.averages.text())
        with QMutexLocker(self.mutex):
            x = np.linspace(
                0, 1 / self.scp.sample_frequency * self.scp.record_length,
                self.scp.record_length)
            y = np.zeros((avg, self.scp.record_length))
            for i in range(avg):
                self.scp.start()
                while not self.scp.is_data_ready:
                    time.sleep(0.01)
                y[i, :] = self.scp.get_data()[self.measCh.currentIndex()]
        return np.column_stack((x, y.mean(axis=0)))

    #@Slot
    def _changeSens(self, i):
        with QMutexLocker(self.mutex):
            yMax = self.scp.channels[0].ranges[i]
            self.scp.range = yMax
            self.yAxeChanged.emit(-1 * yMax, yMax)
            self.triggLevelChanged.emit(
                float(self.triggLevel.text()) * 2 * yMax - yMax)

    def _changeTrigCh(self, newTrig):
        print('new trigger channel', newTrig)
        scope = self.scp
        with QMutexLocker(self.mutex):
            # Disable all channel trigger sources
            for ch in scope.channels:
                ch.trigger.enabled = False
            # enable trigger on newly selected channel
            ch = scope.channels[newTrig]
            ch.trigger.enabled = True
            ch.trigger.kind = libtiepie.TK_RISINGEDGE
            ch.trigger.levels[0] = float(self.triggLevel.text())
            ch.trigger.hystereses[0] = float(self.hystereses.text())

    def _triggLevelChanged(self):
        with QMutexLocker(self.mutex):
            idx = self.triggCh.currentIndex()
            ch = self.scp.channels[idx]
            ch.trigger.levels[0] = float(self.triggLevel.text())
            self.triggLevelChanged.emit(
                float(self.triggLevel.text()) * 2 * self.scp.range -
                self.scp.range)

    def _changeFreq(self):
        with QMutexLocker(self.mutex):
            self.scp.sample_frequency = int(self.frequency.text()) * 1e3
            self.xAxeChanged.emit(
                0, 1 / self.scp.sample_frequency * self.scp.record_length)

    def _changeRecordLength(self):
        with QMutexLocker(self.mutex):
            self.scp.record_length = int(self.recordLen.text())
            self.xAxeChanged.emit(
                0, 1 / self.scp.sample_frequency * self.scp.record_length)

    def _setHystereses(self):
        with QMutexLocker(self.mutex):
            self.scp.hystereses = float(self.hystereses.text())

    def _check_state(self, *args, **kwargs):
        '''https://snorfalorpagus.net/blog/2014/08/09/validating-user-input-in-pyqt4-using-qvalidator/'''
        sender = self.sender()
        validator = sender.validator()
        state = validator.validate(sender.text(), 0)[0]
        if state == QValidator.Acceptable:
            color = '#FFFFFF'  # green
        elif state == QValidator.Intermediate:
            color = '#fff79a'  # yellow
        else:
            color = '#f6989d'  # red
        sender.setStyleSheet('QLineEdit { background-color: %s }' % color)
Exemplo n.º 6
0
class MakeNicerWidget(DockableTabWidget):
    LOCATION = Qt.LeftDockWidgetArea
    updateTdPlot    = Signal(object)
    updateTdFitPlot = Signal(object)
    updateFdPlot    = Signal(object)
    updateFdFitPlot = Signal(object)
    def __init__(self, parent):
        super(MakeNicerWidget, self).__init__(parent)

        self.data = np.array([]) # array which holds data
        
        # Time domain plot
        self.tdWidget = DockablePlotWidget(self, CurveWidget)
        self.tdWidget.calcFun.addFun('fs', lambda x: x,
                                           lambda x: x)
        self.tdWidget.calcFun.addFun('µm', lambda x: x*fsDelay*1e3,
                                           lambda x: x/fsDelay*1e-3)
        self.tdWidget.calcFun.addFun('mm', lambda x: x*fsDelay,
                                           lambda x: x/fsDelay)
        tdPlot = self.tdWidget.get_plot()
        self.tdSignal  = SignalFT(self, plot=tdPlot)
        self.tdFit     = SignalFT(self, plot=tdPlot, col='r')

        # Frequency domain plot
        self.fdWidget = DockablePlotWidget(self, CurveWidget)
        self.fdWidget.calcFun.addFun('PHz', lambda x: x,
                                            lambda x: x)
        self.fdWidget.calcFun.addFun('THz', lambda x: x*1e3,
                                            lambda x: x*1e-3)
        self.fdWidget.calcFun.addFun('µm', lambda x: c0/x*1e-9,
                                           lambda x: c0/x*1e-9)
        self.fdWidget.calcFun.addFun('eV', lambda x: x,
                                           lambda x: x)
        fdplot = self.fdWidget.get_plot()
        self.fdSignal  = SignalFT(self, plot=fdplot)
        self.fdFit     = SignalFT(self, plot=fdplot, col='r')

        self.smoothNum = QSpinBox() # gives number of smoothin points
        self.smoothNum.setMinimum(1)
        self.smoothNum.setSingleStep(2)

        # Put things together in layouts
        buttonLayout = QGridLayout()
        plotLayout   = QVBoxLayout()
        layout       = QHBoxLayout()
        plotLayout.addWidget(self.tdWidget)
        plotLayout.addWidget(self.fdWidget)

        buttonLayout.addWidget(QLabel('Fitting function'), 0, 0)
        buttonLayout.addWidget(
            QLineEdit("lambda x,A,f,phi: np.sin(2*np.pi*f*x+phi)"), 1, 0, 1, 2)
        buttonLayout.addWidget(QLabel('Smooth'), 2, 0)
        buttonLayout.addWidget(self.smoothNum, 2, 1)
        buttonLayout.setRowStretch(3, 20)

        layout.addLayout(buttonLayout)
        layout.addLayout(plotLayout)
        self.setLayout(layout)
        
        # connect signals
        self.updateTdPlot.connect(self.tdSignal.updatePlot)
        self.updateTdFitPlot.connect(self.tdFit.updatePlot)
        self.updateFdPlot.connect(lambda data:
            self.fdSignal.updatePlot(self.fdSignal.computeFFT(data)))
        self.updateFdFitPlot.connect(lambda data:
            self.fdFit.updatePlot(self.fdFit.computeFFT(data)))
        self.smoothNum.valueChanged.connect(self.smoothData)

        self.setData()


    def setData(self):
        data = np.loadtxt('testData.txt', delimiter=',')
        data[:,1] = (data[:,1]-data[:,1].min())/(data[:,1]-data[:,1].min()).max()
        self.data = data
        self.updateTdPlot.emit(data)
        self.updateFdPlot.emit(data)

    def smoothData(self, i):
        x = self.data[:,0]
        x = np.linspace(x[0], x[-1], x.shape[0]+i-1) # get x axis for smooth
        y = self.data[:,1]
        self.updateTdPlot.emit(np.column_stack((x, self.tdSignal.smooth(y, i))))
        self.updateFdPlot.emit(self.fdSignal.computeFFT(
            np.column_stack((x, self.fdSignal.smooth(y, i)))))

    def runFitDialog(self):
        x = self.plot4Curve.get_data()[0]
        y = self.plot4Curve.get_data()[1]
        
        def fit(x, params):
            y0, a, x0, s, tau= params
            
            return y0+a*0.5*(erf((x-x0)/(s/(2*np.sqrt(2*np.log(2)))))+1)*np.exp(-(x-x0)/tau)

        y0 = FitParam("Offset", 0., -100., 100.)
        a = FitParam("Amplitude", y.max(), 0., 10000.)
        x0 = FitParam("x0", x[y.argmax()], -10., 10.)
        s = FitParam("FWHM", 0.5, 0., 10.)
        tau = FitParam("tau", 0.5, 0., 10.)
        params = [y0, a, x0, s, tau]
        values = guifit(x, y, fit, params, xlabel="Time (s)", ylabel="Power (a.u.)")
        self.fitParam = values
Exemplo n.º 7
0
class MapWindow(ImageWindow):
    def set_map(self, item):
        self.map_ = item

    def wheelEvent(self, event):

        if self.map_ is None:
            return

        # from qt example
        num_degrees = event.delta() / 8.
        num_steps = int(round(num_degrees / 15.))

        if event.orientation() == Qt.Vertical:
            try:  # maybe the map has not been set
                new_index = self.map_.get_current_index() + num_steps
                max_index = self.map_.measurement.param.axis3.get_length()
                if new_index > max_index:
                    new_index = max_index
                new_index = int(new_index)
                self.slice_index_spin_box.setValue(new_index)
            except NameError:
                pass

    def set_slice_index(self, index):
        self.map_.set_slice_index(index)
        self.replot()

        scale = self.map_.measurement.param.axis3.get_scale()
        value = scale[index]
        self.slice_value_spin_box.blockSignals(True)
        self.slice_value_spin_box.setValue(value)
        self.slice_value_spin_box.blockSignals(False)

    def set_slice_value(self, value):
        self.map_.set_slice_value(value)
        self.replot()

        index = self.map_.get_current_index()
        self.slice_index_spin_box.blockSignals(True)
        self.slice_index_spin_box.setValue(index)
        self.slice_index_spin_box.blockSignals(False)

    def replot(self):
        plot = self.get_plot()
        plot.replot()
        self.update_cross_sections()
        contrast = self.get_contrast_panel()
        if contrast is not None:
            contrast.histogram.selection_changed(plot)
            #self.set_contrast_range(min, max)

    def create_slice_dock(self):
        widget = QWidget()
        dock = QDockWidget("Slice", self)
        dock.setAllowedAreas(Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea
                             | Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.addDockWidget(Qt.BottomDockWidgetArea, dock)
        layout = QGridLayout(widget)
        self.slice_index_spin_box = QSpinBox()
        index_max = self.map_.measurement.param.axis3.get_length()
        self.slice_index_spin_box.setRange(0, index_max - 1)

        slice_slider = QSlider(Qt.Horizontal)
        slice_slider.setRange(0, index_max - 1)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     self.set_slice_index)
        self.connect(slice_slider, SIGNAL("valueChanged(int)"),
                     self.slice_index_spin_box.setValue)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     slice_slider.setValue)
        self.slice_value_spin_box = QDoubleSpinBox()
        scale = self.map_.measurement.param.axis3.get_scale()
        self.slice_value_spin_box.setRange(scale.min(), scale.max())
        self.slice_value_spin_box.setValue(scale[0])
        self.connect(self.slice_value_spin_box, SIGNAL("valueChanged(double)"),
                     self.set_slice_value)
        unit = self.map_.measurement.param.axis3.unit
        self.slice_value_spin_box.setSuffix(unit)
        layout.addWidget(slice_slider, 0, 0)
        layout.addWidget(self.slice_index_spin_box, 0, 1)
        layout.addWidget(self.slice_value_spin_box, 0, 2)
        dock.setWidget(widget)
Exemplo n.º 8
0
class MapWindow(ImageWindow):

    def set_map(self, item):
        self.map_ = item

    def wheelEvent(self, event):

        if self.map_ is None:
            return

        # from qt example
        num_degrees = event.delta() / 8.
        num_steps = int(round(num_degrees / 15.))

        if event.orientation() == Qt.Vertical :
            try: # maybe the map has not been set
                new_index = self.map_.get_current_index() + num_steps
                max_index = self.map_.measurement.param.axis3.get_length()
                if new_index > max_index:
                    new_index = max_index
                new_index = int(new_index)
                self.slice_index_spin_box.setValue(new_index)
            except NameError:
                pass

    def set_slice_index(self, index):
        self.map_.set_slice_index(index)
        self.replot()

        scale = self.map_.measurement.param.axis3.get_scale()
        value = scale[index]
        self.slice_value_spin_box.blockSignals(True)
        self.slice_value_spin_box.setValue(value)
        self.slice_value_spin_box.blockSignals(False)

    def set_slice_value(self, value):
        self.map_.set_slice_value(value)
        self.replot()

        index = self.map_.get_current_index()
        self.slice_index_spin_box.blockSignals(True)
        self.slice_index_spin_box.setValue(index)
        self.slice_index_spin_box.blockSignals(False)

    def replot(self):
        plot = self.get_plot()
        plot.replot()
        self.update_cross_sections()
        contrast = self.get_contrast_panel()
        if contrast is not None:
            contrast.histogram.selection_changed(plot)
            #self.set_contrast_range(min, max)

    def create_slice_dock(self):
        widget = QWidget()
        dock = QDockWidget("Slice", self)
        dock.setAllowedAreas(Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea |
                             Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.addDockWidget(Qt.BottomDockWidgetArea, dock)
        layout = QGridLayout(widget)
        self.slice_index_spin_box = QSpinBox()
        index_max = self.map_.measurement.param.axis3.get_length()
        self.slice_index_spin_box.setRange(0, index_max-1 )

        slice_slider = QSlider(Qt.Horizontal)
        slice_slider.setRange(0, index_max-1)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     self.set_slice_index)
        self.connect(slice_slider, SIGNAL("valueChanged(int)"),
                     self.slice_index_spin_box.setValue)
        self.connect(self.slice_index_spin_box, SIGNAL("valueChanged(int)"),
                     slice_slider.setValue)
        self.slice_value_spin_box = QDoubleSpinBox()
        scale = self.map_.measurement.param.axis3.get_scale()
        self.slice_value_spin_box.setRange(scale.min(),scale.max())
        self.slice_value_spin_box.setValue(scale[0])
        self.connect(self.slice_value_spin_box, SIGNAL("valueChanged(double)"),
                     self.set_slice_value)
        unit = self.map_.measurement.param.axis3.unit
        self.slice_value_spin_box.setSuffix(unit)
        layout.addWidget(slice_slider, 0, 0)
        layout.addWidget(self.slice_index_spin_box, 0, 1)
        layout.addWidget(self.slice_value_spin_box, 0, 2)
        dock.setWidget(widget)
Exemplo n.º 9
0
    def __init__(self, parent):
        #super(ObjectFT, self).__init__(Qt.Vertical, parent)
        super().__init__(parent)

        self.meter = None
        self.collectData = True # bool for data collection thread
        self.avgData = Queue() # need data for averaging and set for holding all
        self.measure = False
        self.runDataThr = True
        self.measureData = []
        self.startTime = None


        layoutWidget = QWidget()
        layout = QGridLayout()
        layoutWidget.setLayout(layout)

        ##############
        # gui elements
        self.ipEdit = QLineEdit()
        rx = QRegExp("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
        self.ipEdit.setValidator(QRegExpValidator(rx))
        self.ipEdit.setText('127.0.0.1')
        self.portEdit = QLineEdit()
        self.portEdit.setValidator(QIntValidator(1, 65535, self))
        self.portEdit.setText('5000')
        self.connectBtn = QPushButton('Connect')
        self.avgSpin = QSpinBox()
        self.avgSpin.setValue(1)
        self.avgSpin.setRange(1, 10000)
        self.currValDisp = QLabel('0.0')
        self.startMeasBtn = QPushButton('Start aq')
        self.stopMeasBtn  = QPushButton('Stop aq')

        ##############
        # put layout together
        layout.addWidget(QLabel('IP Address:'), 0, 0)
        layout.addWidget(self.ipEdit, 1, 0)
        layout.addWidget(QLabel('Port:'), 0, 1)
        layout.addWidget(self.portEdit, 1, 1)
        layout.addWidget(self.connectBtn, 2, 1)
        layout.addWidget(QLabel('Averages'), 4, 0)
        layout.addWidget(self.avgSpin, 5, 0)
        layout.addWidget(self.currValDisp, 5, 1)
        layout.addWidget(self.startMeasBtn, 6, 0)
        layout.addWidget(self.stopMeasBtn, 6, 1)
        layout.setRowStretch(7, 10)
        self.addWidget(layoutWidget)

        ##############
        # Network stuff
        self.tcpClient = QtNetwork.QTcpSocket()
        self.tcpClient.readyRead.connect(self.__getSocketData)
        self.tcpClient.error.connect(lambda x: print(x))

        ##############
        # make button and stuff functional
        self.connectBtn.released.connect(self.connectMeter)
        self.avgSpin.valueChanged.connect(self.changeAverage)
        self.startMeasBtn.released.connect(self._startMeasure)
        self.stopMeasBtn.released.connect(self._stopMeasure)

        ##############
        # thread for getting data from socket
        self.updateAvgTxt.connect(self.__updateAvgTxt)
        self.dataAq_Thr = QThread()
        self.dataAq_Thr.start()
        self.dataAq_worker = GenericWorker(self.__getData)
        self.dataAq_worker.moveToThread(self.dataAq_Thr)
Exemplo n.º 10
0
class MaestroUi(QSplitter):
    connected = Signal() # gets emitted if stage was sucessfully connected
    newPlotData = Signal(object)
    updateAvgTxt = Signal(object)
    def __init__(self, parent):
        #super(ObjectFT, self).__init__(Qt.Vertical, parent)
        super().__init__(parent)

        self.meter = None
        self.collectData = True # bool for data collection thread
        self.avgData = Queue() # need data for averaging and set for holding all
        self.measure = False
        self.runDataThr = True
        self.measureData = []
        self.startTime = None


        layoutWidget = QWidget()
        layout = QGridLayout()
        layoutWidget.setLayout(layout)

        ##############
        # gui elements
        self.ipEdit = QLineEdit()
        rx = QRegExp("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
        self.ipEdit.setValidator(QRegExpValidator(rx))
        self.ipEdit.setText('127.0.0.1')
        self.portEdit = QLineEdit()
        self.portEdit.setValidator(QIntValidator(1, 65535, self))
        self.portEdit.setText('5000')
        self.connectBtn = QPushButton('Connect')
        self.avgSpin = QSpinBox()
        self.avgSpin.setValue(1)
        self.avgSpin.setRange(1, 10000)
        self.currValDisp = QLabel('0.0')
        self.startMeasBtn = QPushButton('Start aq')
        self.stopMeasBtn  = QPushButton('Stop aq')

        ##############
        # put layout together
        layout.addWidget(QLabel('IP Address:'), 0, 0)
        layout.addWidget(self.ipEdit, 1, 0)
        layout.addWidget(QLabel('Port:'), 0, 1)
        layout.addWidget(self.portEdit, 1, 1)
        layout.addWidget(self.connectBtn, 2, 1)
        layout.addWidget(QLabel('Averages'), 4, 0)
        layout.addWidget(self.avgSpin, 5, 0)
        layout.addWidget(self.currValDisp, 5, 1)
        layout.addWidget(self.startMeasBtn, 6, 0)
        layout.addWidget(self.stopMeasBtn, 6, 1)
        layout.setRowStretch(7, 10)
        self.addWidget(layoutWidget)

        ##############
        # Network stuff
        self.tcpClient = QtNetwork.QTcpSocket()
        self.tcpClient.readyRead.connect(self.__getSocketData)
        self.tcpClient.error.connect(lambda x: print(x))

        ##############
        # make button and stuff functional
        self.connectBtn.released.connect(self.connectMeter)
        self.avgSpin.valueChanged.connect(self.changeAverage)
        self.startMeasBtn.released.connect(self._startMeasure)
        self.stopMeasBtn.released.connect(self._stopMeasure)

        ##############
        # thread for getting data from socket
        self.updateAvgTxt.connect(self.__updateAvgTxt)
        self.dataAq_Thr = QThread()
        self.dataAq_Thr.start()
        self.dataAq_worker = GenericWorker(self.__getData)
        self.dataAq_worker.moveToThread(self.dataAq_Thr)


    def connectMeter(self):
        print('connected')
        self.tcpClient.connectToHost(self.ipEdit.text(), int(self.portEdit.text()))
        self.tcpClient.write('start\n'.encode())
        self.dataAq_worker.start.emit()

    def _startMeasure(self):
        self.measure = True
        self.measureData = [] # reinitialize measure data array
        time.sleep(0.1) # time to wait for first data to arrive
        self.startTime = datetime.now() # datetime object
        
    def _stopMeasure(self):
        self.measure = False

    #@Slot
    def __updateAvgTxt(self, text):
        '''
        update current value label
        '''
        self.currValDisp.setText(text)


    def changeAverage(self):
        shape = int(self.avgSpin.value())
        self.dispData = np.zeros(shape)
    
    def __getData(self):
        '''
        Function run in thread
        '''
        while self.runDataThr:
            tmpData = np.array(int(self.avgSpin.text())*[[datetime.now(), 0]])
            for i in range(len(tmpData)):
                tmpData[i] = self.avgData.get()
                if self.measure:
                    self.measureData.append(
                        (tmpData[i,0].isoformat().encode(),
                         (tmpData[i,0]-self.startTime).total_seconds(),
                         tmpData[i,1]))
            #print('mean', tmpData.mean())
            self.updateAvgTxt.emit(str(tmpData[:,1].mean()))
            if self.measure:
                self.newPlotData.emit(np.float_(np.asarray(self.measureData)[:,1:]))
        self.avgData.task_done()

    #@Slot()
    def __getSocketData(self):
        '''
        to be called if network buffer has more data
        push data to queue
        '''
        self.avgData.put([datetime.now(), float(self.tcpClient.readLine(1024).decode().rstrip())])

    def closeEvent(self, event):
        if self.tcpClient.isOpen():
            self.RunDataThr = False
            self.tcpClient.write('stop\n'.encode())
            time.sleep(0.1)
            self.tcpClient.close()
            print(self.tcpClient.isOpen())
        #if self.console is not None:
        #    self.console.exit_interpreter()
        event.accept()
Exemplo n.º 11
0
    def __init__(self, parent):
        super().__init__(parent)

        self.camera = None
        self.cameraSettings = None
        self.aquireData = False
        self.directory = 'N:/4all/mpsd_drive/xtsfasta/Data'

        layoutWidget = QWidget()
        layout = QGridLayout()
        layoutWidget.setLayout(layout)

        ###############
        # GUI elements
        self.openCamBtn = QPushButton('Connect camera')
        self.startAquBtn = QPushButton('Start aquisiton')
        self.readoutSpeedCombo = QComboBox()
        # this really should not be hard coded but received from dll
        self.readoutSpeedCombo.addItems(["1 MHz", 
            "1.8 MHz",
            "2.3 MHz",
            "2.8 MHz",
            "250 kHz",
            "500 kHz"])
        self.exposureTimeSpin = QSpinBox()
        self.exposureTimeSpin.setRange(1, 1e6)
        self.exposureTimeSpin.setValue(1e3) # default exposure 1s
        self.exposureTimeSpin.setSingleStep(100)
        self.exposureTimeSpin.setSuffix(' ms')
        #self.exposureTimeSpin.setValidator(QIntValidator(1, 2**31)) # ms
        self.binningXCombo = QComboBox()
        self.binningXCombo.addItems(["No binning",
                  "Binning of 2 columns",
                  "Binning of 4 columns",
                  "Binning of 8 columns",
                  "Binning of 16 columns",
                  "Binning of 32 columns",
                  "Binning of 64 columns",
                  "Binning of 128 columns",
                  "Full horizontal binning"])
        self.binningYCombo = QComboBox()
        self.binningYCombo.addItems(["No binning",
                  "Binning of 2 lines",
                  "Binning of 4 lines",
                  "Binning of 8 lines",
                  "Binning of 16 lines",
                  "Binning of 32 lines",
                  "Binning of 64 lines",
                  "Binning of 128 lines",
                  "Binning of 256 lines"])
        self.temperatureSpin = QSpinBox()
        self.temperatureSpin.setRange(-100, 20)
        self.temperatureSpin.setValue(-10)
        self.temperatureSpin.setSuffix('°C')
        self.updateInterSpin = QSpinBox()
        self.updateInterSpin.setRange(1, 3600)
        self.updateInterSpin.setValue(5)
        self.updateInterSpin.setSuffix(' s')
        #self.updateInterSpin.setText("2")
        #self.updateInterEdit.setValidator(QIntValidator(1, 3600))
        self.loi = QSpinBox()
        self.loi.setRange(1, 511) # one pixel less as the camera has
        self.deltaPixels = QSpinBox()
        self.deltaPixels.setRange(0, 256)
        self.autoSave = QCheckBox("Auto save")
        self.getDirectory = QPushButton('Choose Dir')
        self.dirPath = QLineEdit(self.directory)
        self.comment = QPlainTextEdit()

        ##############
        # put elements in layout
        layout.addWidget(self.openCamBtn, 0, 0)
        layout.addWidget(self.startAquBtn, 0, 1)
        layout.addWidget(QLabel('readout speed'), 1, 0)
        layout.addWidget(self.readoutSpeedCombo, 1, 1)
        layout.addWidget(QLabel('exposure time'), 2, 0)
        layout.addWidget(self.exposureTimeSpin, 2, 1)
        layout.addWidget(QLabel('binning X'), 3, 0)
        layout.addWidget(self.binningXCombo, 3, 1)
        layout.addWidget(QLabel('binning Y'), 4, 0)
        layout.addWidget(self.binningYCombo, 4, 1)
        layout.addWidget(QLabel('temperature'), 5, 0)
        layout.addWidget(self.temperatureSpin, 5, 1)
        layout.addWidget(QLabel('update every n-seconds'), 6, 0)
        layout.addWidget(self.updateInterSpin, 6, 1)
        layout.addWidget(QLabel('Pixel of interest'), 7, 0)
        layout.addWidget(self.loi, 7, 1)
        layout.addWidget(QLabel('Δ pixels'), 8, 0)
        layout.addWidget(self.deltaPixels, 8, 1)
        layout.addWidget(self.autoSave, 9, 1)
        layout.addWidget(self.getDirectory, 10, 0)
        layout.addWidget(self.dirPath, 10, 1)
        layout.addWidget(QLabel('Comment:'), 11, 0)
        layout.addWidget(self.comment, 12, 0, 1, 2)
        layout.setRowStretch(13, 10)

        self.addWidget(layoutWidget)


        #################
        # connect elements for functionality
        self.openCamBtn.released.connect(self.__openCam)
        self.getDirectory.released.connect(self.__chooseDir)
        self.temperatureSpin.valueChanged.connect(self.__setTemperature)
        self.exposureTimeSpin.valueChanged.connect(self.__setCamParameter)
        self.readoutSpeedCombo.currentIndexChanged.connect(self.__setCamParameter)
        self.startAquBtn.released.connect(self.__startCurrImageThr)
        
        ################
        # thread for updating position
        self.currImage_thread = QThread() # create the QThread
        self.currImage_thread.start()

        # This causes my_worker.run() to eventually execute in my_thread:
        self.currImage_worker = GenericWorker(self.__getCurrImage)
        self.currImage_worker.moveToThread(self.currImage_thread)
 
        self.startAquBtn.setEnabled(False) 
        self.readoutSpeedCombo.setEnabled(False)
        self.exposureTimeSpin.setEnabled(False)
        self.binningXCombo.setEnabled(False)
        self.binningYCombo.setEnabled(False)
        self.temperatureSpin.setEnabled(False)
        self.updateInterSpin.setEnabled(False)
Exemplo n.º 12
0
class GreatEyesUi(QSplitter):
    '''
    Handling user interface to manage greateys cameras
    '''
    newPlotData = Signal(object, object)
    message = Signal(object)
    def __init__(self, parent):
        super().__init__(parent)

        self.camera = None
        self.cameraSettings = None
        self.aquireData = False
        self.directory = 'N:/4all/mpsd_drive/xtsfasta/Data'

        layoutWidget = QWidget()
        layout = QGridLayout()
        layoutWidget.setLayout(layout)

        ###############
        # GUI elements
        self.openCamBtn = QPushButton('Connect camera')
        self.startAquBtn = QPushButton('Start aquisiton')
        self.readoutSpeedCombo = QComboBox()
        # this really should not be hard coded but received from dll
        self.readoutSpeedCombo.addItems(["1 MHz", 
            "1.8 MHz",
            "2.3 MHz",
            "2.8 MHz",
            "250 kHz",
            "500 kHz"])
        self.exposureTimeSpin = QSpinBox()
        self.exposureTimeSpin.setRange(1, 1e6)
        self.exposureTimeSpin.setValue(1e3) # default exposure 1s
        self.exposureTimeSpin.setSingleStep(100)
        self.exposureTimeSpin.setSuffix(' ms')
        #self.exposureTimeSpin.setValidator(QIntValidator(1, 2**31)) # ms
        self.binningXCombo = QComboBox()
        self.binningXCombo.addItems(["No binning",
                  "Binning of 2 columns",
                  "Binning of 4 columns",
                  "Binning of 8 columns",
                  "Binning of 16 columns",
                  "Binning of 32 columns",
                  "Binning of 64 columns",
                  "Binning of 128 columns",
                  "Full horizontal binning"])
        self.binningYCombo = QComboBox()
        self.binningYCombo.addItems(["No binning",
                  "Binning of 2 lines",
                  "Binning of 4 lines",
                  "Binning of 8 lines",
                  "Binning of 16 lines",
                  "Binning of 32 lines",
                  "Binning of 64 lines",
                  "Binning of 128 lines",
                  "Binning of 256 lines"])
        self.temperatureSpin = QSpinBox()
        self.temperatureSpin.setRange(-100, 20)
        self.temperatureSpin.setValue(-10)
        self.temperatureSpin.setSuffix('°C')
        self.updateInterSpin = QSpinBox()
        self.updateInterSpin.setRange(1, 3600)
        self.updateInterSpin.setValue(5)
        self.updateInterSpin.setSuffix(' s')
        #self.updateInterSpin.setText("2")
        #self.updateInterEdit.setValidator(QIntValidator(1, 3600))
        self.loi = QSpinBox()
        self.loi.setRange(1, 511) # one pixel less as the camera has
        self.deltaPixels = QSpinBox()
        self.deltaPixels.setRange(0, 256)
        self.autoSave = QCheckBox("Auto save")
        self.getDirectory = QPushButton('Choose Dir')
        self.dirPath = QLineEdit(self.directory)
        self.comment = QPlainTextEdit()

        ##############
        # put elements in layout
        layout.addWidget(self.openCamBtn, 0, 0)
        layout.addWidget(self.startAquBtn, 0, 1)
        layout.addWidget(QLabel('readout speed'), 1, 0)
        layout.addWidget(self.readoutSpeedCombo, 1, 1)
        layout.addWidget(QLabel('exposure time'), 2, 0)
        layout.addWidget(self.exposureTimeSpin, 2, 1)
        layout.addWidget(QLabel('binning X'), 3, 0)
        layout.addWidget(self.binningXCombo, 3, 1)
        layout.addWidget(QLabel('binning Y'), 4, 0)
        layout.addWidget(self.binningYCombo, 4, 1)
        layout.addWidget(QLabel('temperature'), 5, 0)
        layout.addWidget(self.temperatureSpin, 5, 1)
        layout.addWidget(QLabel('update every n-seconds'), 6, 0)
        layout.addWidget(self.updateInterSpin, 6, 1)
        layout.addWidget(QLabel('Pixel of interest'), 7, 0)
        layout.addWidget(self.loi, 7, 1)
        layout.addWidget(QLabel('Δ pixels'), 8, 0)
        layout.addWidget(self.deltaPixels, 8, 1)
        layout.addWidget(self.autoSave, 9, 1)
        layout.addWidget(self.getDirectory, 10, 0)
        layout.addWidget(self.dirPath, 10, 1)
        layout.addWidget(QLabel('Comment:'), 11, 0)
        layout.addWidget(self.comment, 12, 0, 1, 2)
        layout.setRowStretch(13, 10)

        self.addWidget(layoutWidget)


        #################
        # connect elements for functionality
        self.openCamBtn.released.connect(self.__openCam)
        self.getDirectory.released.connect(self.__chooseDir)
        self.temperatureSpin.valueChanged.connect(self.__setTemperature)
        self.exposureTimeSpin.valueChanged.connect(self.__setCamParameter)
        self.readoutSpeedCombo.currentIndexChanged.connect(self.__setCamParameter)
        self.startAquBtn.released.connect(self.__startCurrImageThr)
        
        ################
        # thread for updating position
        self.currImage_thread = QThread() # create the QThread
        self.currImage_thread.start()

        # This causes my_worker.run() to eventually execute in my_thread:
        self.currImage_worker = GenericWorker(self.__getCurrImage)
        self.currImage_worker.moveToThread(self.currImage_thread)
 
        self.startAquBtn.setEnabled(False) 
        self.readoutSpeedCombo.setEnabled(False)
        self.exposureTimeSpin.setEnabled(False)
        self.binningXCombo.setEnabled(False)
        self.binningYCombo.setEnabled(False)
        self.temperatureSpin.setEnabled(False)
        self.updateInterSpin.setEnabled(False)
      


    def __openCam(self):
        self.camera = greatEyes()
        if not self.camera.connected:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText('Sorry, could not connect to camera :(\n' + 
                    self.camera.status)
            msg.exec_()
            return
        self.openCamBtn.setText('Connected')
        self.message.emit('Camera connected')
        self.openCamBtn.setStyleSheet('QPushButton {color: green;}')

        self.readoutSpeedCombo.setEnabled(True)
        self.exposureTimeSpin.setEnabled(True)
        self.binningXCombo.setEnabled(False)
        self.binningYCombo.setEnabled(False)
        self.temperatureSpin.setEnabled(True)
        self.updateInterSpin.setEnabled(True)

        self.openCamBtn.setEnabled(False)
        self.startAquBtn.setEnabled(True) 

    def __chooseDir(self):
        self.directory = QFileDialog.getExistingDirectory(self,
                "Choose directory",
                self.directory)
        self.dirPath.setText(self.directory)


    def __startCurrImageThr(self):
        if not self.aquireData:
            self.aquireData = True
            self.currImage_worker.start.emit()
            self.startAquBtn.setText('Stop aquisition')
            self.message.emit('Starting aqusition')
        else:
            self.__stopCurrImageThr()
            self.startAquBtn.setText('Start aquisition')
            self.message.emit('Stopping aqusition')
    def __stopCurrImageThr(self):
        self.aquireData = False
        #while(self.currPosThr.isRunning()):
        #    time.sleep(0.03)
    def __getCurrImage(self):
        #from scipy import mgrid
        #import numpy as np
        #X, Y = mgrid[-256:256, -1024:1025]
        i = self.updateInterSpin.value()
        while self.aquireData:
            # seconds over which to record a new image
            imageIntervall = self.updateInterSpin.value()
            # sleep for n seconds to check if intervall was changed
            sleepy = 1
            if i >= imageIntervall:
                # dummy image
                #z = np.exp(-0.5*(X**2+Y**2)/np.random.uniform(30000, 40000))*np.cos(0.1*X+0.1*Y)
                z = self.camera.getImage()
                timeStamp = datetime.datetime.now()
                self.cameraSettings = {
                        'temperature': self.camera.getTemperature(),
                        'exposure_time': self.exposureTimeSpin.value(),
                        'readout_speed': self.readoutSpeedCombo.currentText()
                        'time_stamp': timeStamp}
                self.newPlotData.emit(z, timeStamp)
                i = 0 # restart counter
            i += sleepy
            time.sleep(sleepy)

    def __setTemperature(self, temp):
        self.camera.setTemperture(temp)
        self.message.emit('Temperature set to {:d}°C'.format(temp))

    def __setCamParameter(self, param):
        self.camera.setCameraParameter(
                self.readoutSpeedCombo.currentIndex(), 
                self.exposureTimeSpin.value(), 
                0, 0)
        self.message.emit('Readout: {:s}, Exposure: {:d}, binningX: 0, binningY: 0'.format(self.readoutSpeedCombo.currentText(),
               self.exposureTimeSpin.value()))