示例#1
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical elements
        # Grid
        self.gridButton = guitools.BetterPushButton('Grid')
        self.gridButton.setCheckable(True)
        self.gridButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                      QtWidgets.QSizePolicy.Expanding)

        # Crosshair
        self.crosshairButton = guitools.BetterPushButton('Crosshair')
        self.crosshairButton.setCheckable(True)
        self.crosshairButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Expanding)
        # liveview
        self.liveviewButton = guitools.BetterPushButton('LIVEVIEW')
        self.liveviewButton.setStyleSheet("font-size:20px")
        self.liveviewButton.setCheckable(True)
        self.liveviewButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                          QtWidgets.QSizePolicy.Expanding)
        self.liveviewButton.setEnabled(True)

        # Add elements to GridLayout
        self.viewCtrlLayout = QtWidgets.QGridLayout()
        self.setLayout(self.viewCtrlLayout)
        self.viewCtrlLayout.addWidget(self.liveviewButton, 0, 0, 1, 2)
        self.viewCtrlLayout.addWidget(self.gridButton, 1, 0)
        self.viewCtrlLayout.addWidget(self.crosshairButton, 1, 1)

        # Connect signals
        self.gridButton.toggled.connect(self.sigGridToggled)
        self.crosshairButton.toggled.connect(self.sigCrosshairToggled)
        self.liveviewButton.toggled.connect(self.sigLiveviewToggled)
示例#2
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.scanInLiveviewWar = QtWidgets.QMessageBox()
        self.scanInLiveviewWar.setInformativeText(
            "You need to be in liveview to scan")

        self.digModWarning = QtWidgets.QMessageBox()
        self.digModWarning.setInformativeText(
            "You need to be in digital laser modulation and external "
            "frame-trigger acquisition mode")

        self.saveScanBtn = guitools.BetterPushButton('Save Scan')
        self.loadScanBtn = guitools.BetterPushButton('Load Scan')

        self.seqTimePar = QtWidgets.QLineEdit('10')  # ms
        self.nrFramesPar = QtWidgets.QLabel()
        self.scanDuration = 0
        self.scanDurationLabel = QtWidgets.QLabel(str(self.scanDuration))

        self.scanDims = []

        self.scanPar = {'seqTime': self.seqTimePar}

        self.pxParameters = {}
        self.pxParValues = {}

        self.scanRadio = QtWidgets.QRadioButton('Scan')
        self.scanRadio.setChecked(True)
        self.contLaserPulsesRadio = QtWidgets.QRadioButton(
            'Cont. Laser Pulses')

        self.scanButton = guitools.BetterPushButton('Run Scan')

        self.continuousCheck = QtWidgets.QCheckBox('Repeat')

        self.graph = GraphFrame()
        self.graph.setEnabled(False)
        self.graph.setFixedHeight(128)

        self.grid = QtWidgets.QGridLayout()
        self.setLayout(self.grid)

        # Connect signals
        self.saveScanBtn.clicked.connect(self.sigSaveScanClicked)
        self.loadScanBtn.clicked.connect(self.sigLoadScanClicked)
        self.scanButton.clicked.connect(self.sigRunScanClicked)
        self.seqTimePar.textChanged.connect(self.sigSeqTimeParChanged)
        self.contLaserPulsesRadio.toggled.connect(
            self.sigContLaserPulsesToggled)
示例#3
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical elements
        detectorTitle = QtWidgets.QLabel(
            '<h2><strong>Detector settings</strong></h2>')
        detectorTitle.setTextFormat(QtCore.Qt.RichText)
        self.ROI = guitools.VispyROIVisual(rect_color='yellow',
                                           handle_color='orange')
        self.stack = QtWidgets.QStackedWidget()
        self.trees = {}

        self.detectorListBox = QtWidgets.QHBoxLayout()
        self.detectorListLabel = QtWidgets.QLabel('Current detector:')
        self.detectorList = QtWidgets.QComboBox()
        self.nextDetectorButton = guitools.BetterPushButton('Next')
        self.nextDetectorButton.hide()
        self.detectorListBox.addWidget(self.detectorListLabel)
        self.detectorListBox.addWidget(self.detectorList, 1)
        self.detectorListBox.addWidget(self.nextDetectorButton)

        # Add elements to GridLayout
        self.layout = QtWidgets.QVBoxLayout()
        self.setLayout(self.layout)
        self.layout.addWidget(detectorTitle)
        self.layout.addWidget(self.stack)
        self.layout.addLayout(self.detectorListBox)

        # Connect signals
        self.ROI.sigROIChanged.connect(self.sigROIChanged)
        self.detectorList.currentIndexChanged.connect(
            lambda index: self.sigDetectorChanged.emit(
                self.detectorList.itemData(index)))
        self.nextDetectorButton.clicked.connect(self.sigNextDetectorClicked)
示例#4
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical elements
        self.angleEdit = QtWidgets.QLineEdit('30')
        self.alignmentCheck = QtWidgets.QCheckBox('Show Alignment Tool')
        self.alignmentLineMakerButton = guitools.BetterPushButton(
            'Alignment Line')
        pen = pg.mkPen(color=(255, 255, 0),
                       width=0.5,
                       style=QtCore.Qt.SolidLine,
                       antialias=True)
        self.alignmentLine = guitools.VispyLineVisual(movable=True)

        # Add items to GridLayout
        alignmentLayout = QtWidgets.QGridLayout()
        self.setLayout(alignmentLayout)
        alignmentLayout.addWidget(QtWidgets.QLabel('Line Angle'), 0, 0)
        alignmentLayout.addWidget(self.angleEdit, 0, 1)
        alignmentLayout.addWidget(self.alignmentLineMakerButton, 1, 0)
        alignmentLayout.addWidget(self.alignmentCheck, 1, 1)

        # Connect signals
        self.alignmentLineMakerButton.clicked.connect(
            self.sigAlignmentLineMakeClicked)
        self.alignmentCheck.toggled.connect(self.sigAlignmentCheckToggled)
示例#5
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Viewbox
        self.cwidget = pg.GraphicsLayoutWidget()
        self.vb = self.cwidget.addViewBox(row=1, col=1)
        self.vb.setMouseMode(pg.ViewBox.RectMode)
        self.img = pg.ImageItem(axisOrder='row-major')
        self.img.translate(-0.5, -0.5)
        self.vb.addItem(self.img)
        self.vb.setAspectLocked(True)
        self.hist = pg.HistogramLUTItem(image=self.img)
        self.hist.vb.setLimits(yMin=0, yMax=66000)
        self.hist.gradient.loadPreset('greyclip')
        for tick in self.hist.gradient.ticks:
            tick.hide()
        self.cwidget.addItem(self.hist, row=1, col=2)

        self.roiButton = guitools.BetterPushButton('Show ROI')
        self.roiButton.setCheckable(True)
        self.runButton = QtWidgets.QCheckBox('Run')
        self.ROI = guitools.VispyROIVisual(rect_color='yellow',
                                           handle_color='orange')

        # Add elements to GridLayout
        grid = QtWidgets.QGridLayout()
        self.setLayout(grid)
        grid.addWidget(self.cwidget, 0, 0, 1, 6)
        grid.addWidget(self.roiButton, 1, 0, 1, 1)
        grid.addWidget(self.runButton, 1, 1, 1, 1)

        # Connect signals
        self.roiButton.toggled.connect(self.sigROIToggled)
        self.runButton.clicked.connect(self.sigRunClicked)
示例#6
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical Elements
        self.ulensesButton = guitools.BetterPushButton('uLenses')
        self.ulensesCheck = QtWidgets.QCheckBox('Show uLenses')
        self.xEdit = QtWidgets.QLineEdit('0')
        self.yEdit = QtWidgets.QLineEdit('0')
        self.pxEdit = QtWidgets.QLineEdit('157.5')
        self.upEdit = QtWidgets.QLineEdit('1182')
        self.ulensesPlot = guitools.VispyScatterVisual(color='red', symbol='x')

        # Add elements to GridLayout
        ulensesLayout = QtWidgets.QGridLayout()
        self.setLayout(ulensesLayout)
        ulensesLayout.addWidget(QtWidgets.QLabel('Pixel Size'), 0, 0)
        ulensesLayout.addWidget(self.pxEdit, 0, 1)
        ulensesLayout.addWidget(QtWidgets.QLabel('Periodicity'), 1, 0)
        ulensesLayout.addWidget(self.upEdit, 1, 1)
        ulensesLayout.addWidget(QtWidgets.QLabel('X offset'), 2, 0)
        ulensesLayout.addWidget(self.xEdit, 2, 1)
        ulensesLayout.addWidget(QtWidgets.QLabel('Y offset'), 3, 0)
        ulensesLayout.addWidget(self.yEdit, 3, 1)
        ulensesLayout.addWidget(self.ulensesButton, 4, 0)
        ulensesLayout.addWidget(self.ulensesCheck, 4, 1)

        # Connect signals
        self.ulensesButton.clicked.connect(self.sigULensesClicked)
        self.ulensesCheck.toggled.connect(self.sigUShowLensesChanged)
示例#7
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        guitools.addNapariGrayclipColormap()
        self.napariViewer = napari.Viewer(show=False)
        self.imgLayers = {}

        self.levelsButton = guitools.BetterPushButton('Update Levels', minMinWidth=180)
        self.levelsButton.setMinimumHeight(40)

        self.toolboxLayout = QtWidgets.QHBoxLayout()
        self.toolboxLayout.addSpacerItem(
            QtWidgets.QSpacerItem(
                40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum
            )
        )
        self.toolboxLayout.addWidget(self.levelsButton)

        self.viewCtrlLayout = QtWidgets.QVBoxLayout()
        self.viewCtrlLayout.addWidget(self.napariViewer.window._qt_window)
        self.viewCtrlLayout.addLayout(self.toolboxLayout)
        self.setLayout(self.viewCtrlLayout)

        self.grid = guitools.VispyGridVisual(color='yellow')
        self.grid.hide()
        self.addItem(self.grid)

        self.crosshair = guitools.VispyCrosshairVisual(color='yellow')
        self.crosshair.hide()
        self.addItem(self.crosshair)

        # Connect signals
        self.levelsButton.clicked.connect(self.sigUpdateLevelsClicked)
示例#8
0
    def addPositioner(self, positionerName, axes):
        for i in range(len(axes)):
            axis = axes[i]
            parNameSuffix = self._getParNameSuffix(positionerName, axis)
            label = f'{positionerName} -- {axis}' if positionerName != axis else positionerName

            self.pars['Label' + parNameSuffix] = QtWidgets.QLabel(
                f'<strong>{label}</strong>')
            self.pars['Label' + parNameSuffix].setTextFormat(
                QtCore.Qt.RichText)
            self.pars['Position' + parNameSuffix] = QtWidgets.QLabel(
                f'<strong>{0:.2f} µm</strong>')
            self.pars['Position' + parNameSuffix].setTextFormat(
                QtCore.Qt.RichText)
            self.pars['UpButton' +
                      parNameSuffix] = guitools.BetterPushButton('+')
            self.pars['DownButton' +
                      parNameSuffix] = guitools.BetterPushButton('-')
            self.pars['StepEdit' + parNameSuffix] = QtWidgets.QLineEdit('0.05')
            self.pars['StepUnit' + parNameSuffix] = QtWidgets.QLabel(' µm')

            self.grid.addWidget(self.pars['Label' + parNameSuffix],
                                self.numPositioners, 0)
            self.grid.addWidget(self.pars['Position' + parNameSuffix],
                                self.numPositioners, 1)
            self.grid.addWidget(self.pars['UpButton' + parNameSuffix],
                                self.numPositioners, 2)
            self.grid.addWidget(self.pars['DownButton' + parNameSuffix],
                                self.numPositioners, 3)
            self.grid.addWidget(QtWidgets.QLabel('Step'), self.numPositioners,
                                4)
            self.grid.addWidget(self.pars['StepEdit' + parNameSuffix],
                                self.numPositioners, 5)
            self.grid.addWidget(self.pars['StepUnit' + parNameSuffix],
                                self.numPositioners, 6)

            self.numPositioners += 1

            # Connect signals
            self.pars['UpButton' + parNameSuffix].clicked.connect(
                lambda: self.sigStepUpClicked.emit(positionerName, axis))
            self.pars['DownButton' + parNameSuffix].clicked.connect(
                lambda: self.sigStepDownClicked.emit(positionerName, axis))
示例#9
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical elements
        self.roiButton = guitools.BetterPushButton('Show ROI')
        self.roiButton.setCheckable(True)
        self.resetButton = guitools.BetterPushButton('Reset graph')
        self.ROI = guitools.VispyROIVisual(rect_color='yellow',
                                           handle_color='orange')
        self.graph = guitools.SumpixelsGraph()
        self.resetButton.clicked.connect(self.graph.resetData)

        # Add items to GridLayout
        grid = QtWidgets.QGridLayout()
        self.setLayout(grid)
        grid.addWidget(self.graph, 0, 0, 1, 6)
        grid.addWidget(self.roiButton, 1, 0, 1, 1)
        grid.addWidget(self.resetButton, 1, 1, 1, 1)
        # grid.setRowMinimumHeight(0, 300)

        # Connect signals
        self.roiButton.toggled.connect(self.sigShowROIToggled)
示例#10
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.powers = {}

        self.grid = QtWidgets.QGridLayout()
        self.setLayout(self.grid)

        title = QtWidgets.QLabel('<h3>Digital modulation<h3>')
        title.setTextFormat(QtCore.Qt.RichText)
        title.setAlignment(QtCore.Qt.AlignCenter)
        title.setStyleSheet("font-size:12px")
        title.setFixedHeight(20)
        self.grid.addWidget(title, 0, 0, 1, -1)

        self.DigitalControlButton = guitools.BetterPushButton('Enable')
        self.DigitalControlButton.setCheckable(True)
        self.grid.addWidget(self.DigitalControlButton, 2, 0, 1, -1)

        # Connect signals
        self.DigitalControlButton.toggled.connect(self.sigDigitalModToggled)
示例#11
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical elements
        self.roiButton = guitools.BetterPushButton('Show ROI')
        self.roiButton.setCheckable(True)
        self.XButton = QtWidgets.QRadioButton('X dimension')
        self.YButton = QtWidgets.QRadioButton('Y dimension')
        self.ROI = guitools.VispyROIVisual(rect_color='yellow',
                                           handle_color='orange')
        self.graph = guitools.ProjectionGraph()

        # Add elements to GridLayout
        grid = QtWidgets.QGridLayout()
        self.setLayout(grid)
        grid.addWidget(self.graph, 0, 0, 1, 6)
        grid.addWidget(self.roiButton, 1, 0, 1, 1)
        grid.addWidget(self.XButton, 1, 1, 1, 1)
        grid.addWidget(self.YButton, 1, 2, 1, 1)

        # Connect signals
        self.roiButton.toggled.connect(self.sigShowROIToggled)
        self.XButton.clicked.connect(lambda: self.sigAxisChanged.emit(0))
        self.YButton.clicked.connect(lambda: self.sigAxisChanged.emit(1))
示例#12
0
    def __init__(self, name, units, wavelength, valueRange, tickInterval, singleStep,
                 initialPower, *args, **kwargs):
        super().__init__(*args, **kwargs)
        isBinary = valueRange is None

        # Graphical elements
        self.setFrameStyle(QtWidgets.QFrame.Panel | QtWidgets.QFrame.Raised)
        self.setMinimumWidth(180)

        self.name = QtWidgets.QLabel(f'<h3>{name}<h3>')
        self.name.setTextFormat(QtCore.Qt.RichText)
        self.name.setAlignment(QtCore.Qt.AlignCenter)
        color = guitools.colorutils.wavelengthToHex(wavelength)
        self.name.setStyleSheet(f'font-size:16px; border-bottom: 4px solid {color}')
        self.name.setFixedHeight(40)

        self.setPointLabel = QtWidgets.QLabel('Setpoint')
        self.setPointEdit = QtWidgets.QLineEdit(str(initialPower))
        self.setPointEdit.setFixedWidth(50)
        self.setPointEdit.setAlignment(QtCore.Qt.AlignRight)

        self.powerLabel = QtWidgets.QLabel('Power')
        self.powerIndicator = QtWidgets.QLabel(str(initialPower))
        self.powerIndicator.setFixedWidth(50)
        self.powerIndicator.setAlignment(QtCore.Qt.AlignRight)

        self.minpower = QtWidgets.QLabel()
        self.minpower.setAlignment(QtCore.Qt.AlignCenter)
        self.maxpower = QtWidgets.QLabel()
        self.maxpower.setAlignment(QtCore.Qt.AlignCenter)

        self.slider = QtWidgets.QSlider(QtCore.Qt.Vertical, self)
        self.slider.setFocusPolicy(QtCore.Qt.NoFocus)

        if not isBinary:
            valueRangeMin, valueRangeMax = valueRange

            self.minpower.setText(str(valueRangeMin))
            self.maxpower.setText(str(valueRangeMax))

            self.slider.setMinimum(valueRangeMin)
            self.slider.setMaximum(valueRangeMax)
            self.slider.setTickInterval(tickInterval)
            self.slider.setSingleStep(singleStep)
            self.slider.setValue(0)

        powerFrame = QtWidgets.QFrame(self)
        self.powerGrid = QtWidgets.QGridLayout()
        powerFrame.setFrameStyle(QtWidgets.QFrame.Panel | QtWidgets.QFrame.Plain)
        powerFrame.setLayout(self.powerGrid)

        self.powerGrid.addWidget(self.setPointLabel, 1, 0, 1, 2)
        self.powerGrid.addWidget(self.setPointEdit, 2, 0)
        self.powerGrid.addWidget(QtWidgets.QLabel(units), 2, 1)
        self.powerGrid.addWidget(self.powerLabel, 3, 0, 1, 2)
        self.powerGrid.addWidget(self.powerIndicator, 4, 0)
        self.powerGrid.addWidget(QtWidgets.QLabel(units), 4, 1)
        self.powerGrid.addWidget(self.maxpower, 0, 3)
        self.powerGrid.addWidget(self.slider, 1, 3, 8, 1)
        self.powerGrid.addWidget(self.minpower, 9, 3)

        self.enableButton = guitools.BetterPushButton('ON')
        self.enableButton.setCheckable(True)

        # Add elements to GridLayout
        self.grid = QtWidgets.QGridLayout()
        self.setLayout(self.grid)
        self.grid.addWidget(self.name, 0, 0, 1, 2)
        self.grid.addWidget(powerFrame, 1, 0, 1, 2)
        if isBinary:
            sizePolicy = powerFrame.sizePolicy()
            sizePolicy.setRetainSizeWhenHidden(True)
            powerFrame.setSizePolicy(sizePolicy)
            powerFrame.hide()
        self.grid.addWidget(self.enableButton, 8, 0, 1, 2)

        # Connect signals
        self.enableButton.toggled.connect(self.sigEnableChanged)
        self.slider.valueChanged[int].connect(
            lambda value: self.sigValueChanged.emit(float(value))
        )
        self.setPointEdit.returnPressed.connect(
            lambda: self.sigValueChanged.emit(self.getValue())
        )
示例#13
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.slmFrame = pg.GraphicsLayoutWidget()
        self.vb = self.slmFrame.addViewBox(row=1, col=1)
        self.img = pg.ImageItem()
        self.img.setImage(np.zeros((792, 600)),
                          autoLevels=True,
                          autoDownsample=True,
                          autoRange=True)
        self.vb.addItem(self.img)
        self.vb.setAspectLocked(True)

        self.slmParameterTree = ParameterTree()
        self.generalparams = [
            {
                'name':
                'General parameters',
                'type':
                'group',
                'children': [
                    {
                        'name': 'Radius',
                        'type': 'float',
                        'value': 100,
                        'limits': (0, 600),
                        'step': 1,
                        'suffix': 'px'
                    },
                    {
                        'name': 'Sigma',
                        'type': 'float',
                        'value': 35,
                        'limits': (1, 599),
                        'step': 0.1,
                        'suffix': 'px'
                    },
                    # {'name': 'Angle', 'type': 'float', 'value': 0.15, 'limits': (0, 0.3), 'step': 0.01, 'suffix': 'rad'},
                    # {'name': 'Wavelength', 'type': 'float', 'value': 775, 'limits': (0, 1200), 'step': 1, 'suffix': 'nm'},
                    # {'name': 'Helix rotation', 'type': 'bool', 'value': True},
                ]
            },
            {
                'name': 'Apply',
                'type': 'action'
            }
        ]
        self.slmParameterTree.setStyleSheet("""
        QTreeView::item, QAbstractSpinBox, QComboBox {
            padding-top: 0;
            padding-bottom: 0;
            border: none;
        }

        QComboBox QAbstractItemView {
            min-width: 128px;
        }
        """)
        self.slmParameterTree.p = pg.parametertree.Parameter.create(
            name='params', type='group', children=self.generalparams)
        self.slmParameterTree.setParameters(self.slmParameterTree.p,
                                            showTop=False)
        self.slmParameterTree._writable = True

        self.aberParameterTree = pg.parametertree.ParameterTree()
        aberlim = 2
        self.aberparams = [{
            'name':
            'Donut',
            'type':
            'group',
            'children': [{
                'name': 'Tilt factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Tip factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Defocus factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Spherical factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Vertical coma factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Horizontal coma factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Vertical astigmatism factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Oblique astigmatism factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }]
        }, {
            'name':
            'Tophat',
            'type':
            'group',
            'children': [{
                'name': 'Tilt factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Tip factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Defocus factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Spherical factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Vertical coma factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Horizontal coma factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Vertical astigmatism factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }, {
                'name': 'Oblique astigmatism factor',
                'type': 'float',
                'value': 0,
                'limits': (-aberlim, aberlim),
                'step': 0.01
            }]
        }, {
            'name': 'Apply',
            'type': 'action'
        }]
        self.aberParameterTree.setStyleSheet("""
        QTreeView::item, QAbstractSpinBox, QComboBox {
            padding-top: 0;
            padding-bottom: 0;
            border: none;
        }

        QComboBox QAbstractItemView {
            min-width: 128px;
        }
        """)
        self.aberParameterTree.p = pg.parametertree.Parameter.create(
            name='params', type='group', children=self.aberparams)
        self.aberParameterTree.setParameters(self.aberParameterTree.p,
                                             showTop=False)
        self.aberParameterTree._writable = True

        self.paramtreeDockArea = pg.dockarea.DockArea()
        pmtreeDock = pg.dockarea.Dock('Phase mask parameters', size=(1, 1))
        pmtreeDock.addWidget(self.slmParameterTree)
        self.paramtreeDockArea.addDock(pmtreeDock)
        abertreeDock = pg.dockarea.Dock('Aberration correction parameters',
                                        size=(1, 1))
        abertreeDock.addWidget(self.aberParameterTree)
        self.paramtreeDockArea.addDock(abertreeDock, 'above', pmtreeDock)

        # Control panel with most buttons
        self.controlPanel = QtWidgets.QFrame()
        self.controlPanel.choiceInterfaceLayout = QtWidgets.QGridLayout()
        self.controlPanel.choiceInterface = QtWidgets.QWidget()
        self.controlPanel.choiceInterface.setLayout(
            self.controlPanel.choiceInterfaceLayout)

        # Choose which mask to modify
        self.controlPanel.maskComboBox = QtWidgets.QComboBox()
        self.controlPanel.maskComboBox.addItem("Donut (left)")
        self.controlPanel.maskComboBox.addItem("Top hat (right)")
        self.controlPanel.choiceInterfaceLayout.addWidget(
            QtWidgets.QLabel('Select mask:'), 0, 0)
        self.controlPanel.choiceInterfaceLayout.addWidget(
            self.controlPanel.maskComboBox, 0, 1)

        # Choose which objective is in use
        self.controlPanel.objlensComboBox = QtWidgets.QComboBox()
        self.controlPanel.objlensComboBox.addItem("No objective")
        self.controlPanel.objlensComboBox.addItem("Oil")
        self.controlPanel.objlensComboBox.addItem("Glycerol")
        self.controlPanel.choiceInterfaceLayout.addWidget(
            QtWidgets.QLabel('Select objective:'), 1, 0)
        self.controlPanel.choiceInterfaceLayout.addWidget(
            self.controlPanel.objlensComboBox, 1, 1)

        # Phase mask moving buttons
        self.controlPanel.arrowButtons = []
        self.controlPanel.upButton = guitools.BetterPushButton('Up (YZ)')
        self.controlPanel.arrowButtons.append(self.controlPanel.upButton)
        self.controlPanel.downButton = guitools.BetterPushButton('Down (YZ)')
        self.controlPanel.arrowButtons.append(self.controlPanel.downButton)
        self.controlPanel.leftButton = guitools.BetterPushButton('Left (XZ)')
        self.controlPanel.arrowButtons.append(self.controlPanel.leftButton)
        self.controlPanel.rightButton = guitools.BetterPushButton('Right (XZ)')
        self.controlPanel.arrowButtons.append(self.controlPanel.rightButton)

        for button in self.controlPanel.arrowButtons:
            button.setCheckable(False)
            button.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                 QtWidgets.QSizePolicy.Expanding)
            button.setFixedSize(self.controlPanel.upButton.sizeHint())

        # Interface to change the amount of displacement induced by the arrows
        self.controlPanel.incrementInterface = QtWidgets.QWidget()
        self.controlPanel.incrementInterfaceLayout = QtWidgets.QVBoxLayout()
        self.controlPanel.incrementInterface.setLayout(
            self.controlPanel.incrementInterfaceLayout)
        self.controlPanel.incrementlabel = QtWidgets.QLabel("Step (px)")
        self.controlPanel.incrementSpinBox = QtWidgets.QSpinBox()
        self.controlPanel.incrementSpinBox.setRange(1, 50)
        self.controlPanel.incrementSpinBox.setValue(1)
        self.controlPanel.incrementInterfaceLayout.addWidget(
            self.controlPanel.incrementlabel)
        self.controlPanel.incrementInterfaceLayout.addWidget(
            self.controlPanel.incrementSpinBox)

        # Interface to change the rotation angle of phase pattern
        self.controlPanel.rotationInterface = QtWidgets.QWidget()
        self.controlPanel.rotationInterfaceLayout = QtWidgets.QVBoxLayout()
        self.controlPanel.rotationInterface.setLayout(
            self.controlPanel.rotationInterfaceLayout)
        self.controlPanel.rotationLabel = QtWidgets.QLabel(
            'Pattern angle (rad)')
        self.controlPanel.rotationEdit = QtWidgets.QLineEdit('0')
        self.controlPanel.rotationInterfaceLayout.addWidget(
            self.controlPanel.rotationLabel)
        self.controlPanel.rotationInterfaceLayout.addWidget(
            self.controlPanel.rotationEdit)

        # Buttons for saving, loading, and controlling the various phase patterns
        self.controlPanel.saveButton = guitools.BetterPushButton("Save")
        self.controlPanel.loadButton = guitools.BetterPushButton("Load")

        self.controlPanel.donutButton = guitools.BetterPushButton("Donut")
        self.controlPanel.tophatButton = guitools.BetterPushButton("Tophat")

        self.controlPanel.blackButton = guitools.BetterPushButton(
            "Black frame")
        self.controlPanel.gaussianButton = guitools.BetterPushButton(
            "Gaussian")

        self.controlPanel.halfButton = guitools.BetterPushButton(
            "Half pattern")
        self.controlPanel.quadrantButton = guitools.BetterPushButton(
            "Quad pattern")
        self.controlPanel.hexButton = guitools.BetterPushButton("Hex pattern")
        self.controlPanel.splitbullButton = guitools.BetterPushButton(
            "Split pattern")

        # Defining layout
        self.controlPanel.arrowsFrame = QtWidgets.QFrame()
        self.controlPanel.arrowsLayout = QtWidgets.QGridLayout()
        self.controlPanel.arrowsFrame.setLayout(self.controlPanel.arrowsLayout)

        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.upButton, 0,
                                                 1)
        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.leftButton,
                                                 1, 0)
        self.controlPanel.arrowsLayout.addWidget(
            self.controlPanel.incrementInterface, 1, 1)
        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.rightButton,
                                                 1, 2)
        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.downButton,
                                                 2, 1)

        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.loadButton,
                                                 0, 3)
        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.saveButton,
                                                 1, 3)

        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.donutButton,
                                                 3, 0)
        self.controlPanel.arrowsLayout.addWidget(
            self.controlPanel.tophatButton, 3, 1)

        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.blackButton,
                                                 4, 0)
        self.controlPanel.arrowsLayout.addWidget(
            self.controlPanel.gaussianButton, 4, 1)

        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.halfButton,
                                                 5, 0)
        self.controlPanel.arrowsLayout.addWidget(
            self.controlPanel.quadrantButton, 5, 1)
        self.controlPanel.arrowsLayout.addWidget(self.controlPanel.hexButton,
                                                 6, 0)
        self.controlPanel.arrowsLayout.addWidget(
            self.controlPanel.splitbullButton, 6, 1)
        self.controlPanel.arrowsLayout.addWidget(
            self.controlPanel.rotationInterface, 5, 2, 2, 1)

        # Definition of the box layout:
        self.controlPanel.boxLayout = QtWidgets.QVBoxLayout()
        self.controlPanel.setLayout(self.controlPanel.boxLayout)

        self.controlPanel.boxLayout.addWidget(
            self.controlPanel.choiceInterface)
        self.controlPanel.boxLayout.addWidget(self.controlPanel.arrowsFrame)

        self.grid = QtWidgets.QGridLayout()
        self.setLayout(self.grid)
示例#14
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Focus lock
        self.kpEdit = QtWidgets.QLineEdit('5')
        self.kpLabel = QtWidgets.QLabel('kp')
        self.kiEdit = QtWidgets.QLineEdit('0.1')
        self.kiLabel = QtWidgets.QLabel('ki')

        self.lockButton = guitools.BetterPushButton('Lock')
        self.lockButton.setCheckable(True)
        self.lockButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                      QtWidgets.QSizePolicy.Expanding)

        self.zStackBox = QtWidgets.QCheckBox('Z-stack')
        self.twoFociBox = QtWidgets.QCheckBox('Two foci')

        self.zStepFromEdit = QtWidgets.QLineEdit('40')
        self.zStepFromLabel = QtWidgets.QLabel('Min step (nm)')
        self.zStepToEdit = QtWidgets.QLineEdit('100')
        self.zStepToLabel = QtWidgets.QLabel('Max step (nm)')

        # self.focusDataBox = QtWidgets.QCheckBox('Save data')  # Connect to exportData
        self.camDialogButton = guitools.BetterPushButton('Camera Dialog')

        # Piezo absolute positioning
        self.positionLabel = QtWidgets.QLabel(
            'Position (µm)'
        )  # Potentially disregard this and only use in the positioning widget?
        self.positionEdit = QtWidgets.QLineEdit('50')
        self.positionSetButton = guitools.BetterPushButton('Set')

        # Focus lock calibration
        self.calibFromLabel = QtWidgets.QLabel('From (µm)')
        self.calibFromEdit = QtWidgets.QLineEdit('49')
        self.calibToLabel = QtWidgets.QLabel('To (µm)')
        self.calibToEdit = QtWidgets.QLineEdit('51')
        self.focusCalibButton = guitools.BetterPushButton('Calib')
        self.focusCalibButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                            QtWidgets.QSizePolicy.Expanding)
        self.calibCurveButton = guitools.BetterPushButton('See calib')
        self.calibrationDisplay = QtWidgets.QLineEdit(
            'Previous calib: none'
        )  # Edit this from the controller with calibration values
        self.calibrationDisplay.setReadOnly(True)
        # CREATE CALIBRATION CURVE WINDOW AND FOCUS CALIBRATION GRAPH SOMEHOW

        # Focus lock graph
        self.focusLockGraph = pg.GraphicsLayoutWidget()
        self.focusLockGraph.setAntialiasing(True)
        self.focusPlot = self.focusLockGraph.addPlot(row=1, col=0)
        self.focusPlot.setLabels(bottom=('Time', 's'),
                                 left=('Laser position', 'px'))
        self.focusPlot.showGrid(x=True, y=True)
        self.focusPlotCurve = self.focusPlot.plot(
            pen='y'
        )  # update this (self.focusPlotCurve.setData(X,Y)) with update(focusSignal) function

        # Webcam graph
        self.webcamGraph = pg.GraphicsLayoutWidget()
        self.camImg = pg.ImageItem(border='w')
        self.camImg.setImage(np.zeros((100, 100)))
        self.vb = self.webcamGraph.addViewBox(invertY=True, invertX=False)
        self.vb.setAspectLocked(True)
        self.vb.addItem(self.camImg)

        # PROCESS DATA THREAD - ADD SOMEWHERE ELSE, NOT HERE, AS IT HAS NO GRAPHICAL ELEMENTS!

        # GUI layout below
        grid = QtWidgets.QGridLayout()
        self.setLayout(grid)
        grid.addWidget(self.focusLockGraph, 0, 0, 1, 9)
        grid.addWidget(self.webcamGraph, 0, 9, 4, 1)
        grid.addWidget(self.focusCalibButton, 1, 2, 2, 1)
        grid.addWidget(self.calibrationDisplay, 3, 0, 1, 2)
        grid.addWidget(self.kpLabel, 1, 3)
        grid.addWidget(self.kpEdit, 1, 4)
        grid.addWidget(self.kiLabel, 2, 3)
        grid.addWidget(self.kiEdit, 2, 4)
        grid.addWidget(self.lockButton, 1, 5, 2, 1)
        grid.addWidget(self.zStackBox, 4, 2)
        grid.addWidget(self.twoFociBox, 4, 6)
        grid.addWidget(self.zStepFromLabel, 3, 4)
        grid.addWidget(self.zStepFromEdit, 4, 4)
        grid.addWidget(self.zStepToLabel, 3, 5)
        grid.addWidget(self.zStepToEdit, 4, 5)
        # grid.addWidget(self.focusDataBox, 4, 0, 1, 2)
        grid.addWidget(self.calibFromLabel, 1, 0)
        grid.addWidget(self.calibFromEdit, 1, 1)
        grid.addWidget(self.calibToLabel, 2, 0)
        grid.addWidget(self.calibToEdit, 2, 1)
        grid.addWidget(self.calibCurveButton, 3, 2)
        grid.addWidget(self.positionLabel, 1, 6)
        grid.addWidget(self.positionEdit, 1, 7)
        grid.addWidget(self.positionSetButton, 2, 6, 1, 2)
        grid.addWidget(self.camDialogButton, 3, 6, 1, 2)
示例#15
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.scanInLiveviewWar = QtWidgets.QMessageBox()
        self.scanInLiveviewWar.setInformativeText(
            "You need to be in liveview to scan")

        self.digModWarning = QtWidgets.QMessageBox()
        self.digModWarning.setInformativeText(
            "You need to be in digital laser modulation and external "
            "frame-trigger acquisition mode")

        self.saveScanBtn = guitools.BetterPushButton('Save Scan')
        self.loadScanBtn = guitools.BetterPushButton('Load Scan')

        self.seqTimePar = QtWidgets.QLineEdit('10')  # ms
        self.nrFramesPar = QtWidgets.QLabel()
        self.scanDuration = 0
        self.scanDurationLabel = QtWidgets.QLabel(str(self.scanDuration))

        self.scanDims = []

        self.scanPar = {'seqTime': self.seqTimePar}

        self.pxParameters = {}
        self.pxParValues = {}

        self.scanRadio = QtWidgets.QRadioButton('Scan')
        self.scanRadio.setChecked(True)
        self.contLaserPulsesRadio = QtWidgets.QRadioButton(
            'Cont. Laser Pulses')

        self.scanButton = guitools.BetterPushButton('Run Scan')

        self.continuousCheck = QtWidgets.QCheckBox('Repeat')

        self.graph = GraphFrame()
        self.graph.setEnabled(False)
        self.graph.setFixedHeight(128)

        self.scrollContainer = QtWidgets.QGridLayout()
        self.scrollContainer.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.scrollContainer)

        self.grid = QtWidgets.QGridLayout()
        self.gridContainer = QtWidgets.QWidget()
        self.gridContainer.setLayout(self.grid)

        self.scrollArea = QtWidgets.QScrollArea()
        self.scrollArea.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.scrollArea.setHorizontalScrollBarPolicy(
            QtCore.Qt.ScrollBarAsNeeded)
        self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
        self.scrollArea.setWidget(self.gridContainer)
        self.scrollArea.setWidgetResizable(True)
        self.scrollContainer.addWidget(self.scrollArea)
        self.gridContainer.installEventFilter(self)

        # Connect signals
        self.saveScanBtn.clicked.connect(self.sigSaveScanClicked)
        self.loadScanBtn.clicked.connect(self.sigLoadScanClicked)
        self.scanButton.clicked.connect(self.sigRunScanClicked)
        self.seqTimePar.textChanged.connect(self.sigSeqTimeParChanged)
        self.contLaserPulsesRadio.toggled.connect(
            self.sigContLaserPulsesToggled)
示例#16
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical elements
        self.showCheck = QtWidgets.QCheckBox('Show FFT')
        self.showCheck.setCheckable(True)
        self.posCheck = guitools.BetterPushButton('Period (pix)')
        self.posCheck.setCheckable(True)
        self.linePos = QtWidgets.QLineEdit('4')
        self.lineRate = QtWidgets.QLineEdit('0')
        self.labelRate = QtWidgets.QLabel('Update rate')

        # Vertical and horizontal lines
        self.vline = pg.InfiniteLine()
        self.hline = pg.InfiniteLine()
        self.rvline = pg.InfiniteLine()
        self.lvline = pg.InfiniteLine()
        self.uhline = pg.InfiniteLine()
        self.dhline = pg.InfiniteLine()

        # Viewbox
        self.cwidget = pg.GraphicsLayoutWidget()
        self.vb = self.cwidget.addViewBox(row=1, col=1)
        self.vb.setMouseMode(pg.ViewBox.RectMode)
        self.img = guitools.OptimizedImageItem(axisOrder='row-major')
        self.img.translate(-0.5, -0.5)
        self.vb.addItem(self.img)
        self.vb.setAspectLocked(True)
        self.hist = pg.HistogramLUTItem(image=self.img)
        self.hist.vb.setLimits(yMin=0, yMax=66000)
        self.hist.gradient.loadPreset('greyclip')
        for tick in self.hist.gradient.ticks:
            tick.hide()
        self.cwidget.addItem(self.hist, row=1, col=2)

        # Add lines to viewbox
        self.vb.addItem(self.vline)
        self.vb.addItem(self.hline)
        self.vb.addItem(self.lvline)
        self.vb.addItem(self.rvline)
        self.vb.addItem(self.uhline)
        self.vb.addItem(self.dhline)

        # Add elements to GridLayout
        grid = QtWidgets.QGridLayout()
        self.setLayout(grid)
        grid.addWidget(self.cwidget, 0, 0, 1, 6)
        grid.addWidget(self.showCheck, 1, 0, 1, 1)
        grid.addWidget(self.posCheck, 2, 0, 1, 1)
        grid.addWidget(self.linePos, 2, 1, 1, 1)
        grid.addWidget(self.labelRate, 2, 2, 1, 1)
        grid.addWidget(self.lineRate, 2, 3, 1, 1)
        # grid.setRowMinimumHeight(0, 300)

        # Connect signals
        self.showCheck.toggled.connect(self.sigShowToggled)
        self.posCheck.toggled.connect(self.sigPosToggled)
        self.linePos.textChanged.connect(
            lambda: self.sigPosChanged.emit(self.getPos()))
        self.lineRate.textChanged.connect(
            lambda: self.sigUpdateRateChanged.emit(self.getUpdateRate()))
        self.vb.sigResized.connect(self.sigResized)
示例#17
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Graphical elements
        recTitle = QtWidgets.QLabel('<h2><strong>Recording settings</strong></h2>')
        recTitle.setTextFormat(QtCore.Qt.RichText)

        # Detector list
        self.detectorList = QtWidgets.QComboBox()

        # Folder and filename fields
        baseOutputFolder = self._options.recording.outputFolder
        if self._options.recording.includeDateInOutputFolder:
            self.initialDir = os.path.join(baseOutputFolder, time.strftime('%Y-%m-%d'))
        else:
            self.initialDir = baseOutputFolder

        self.folderEdit = QtWidgets.QLineEdit(self.initialDir)
        self.openFolderButton = guitools.BetterPushButton('Open')
        self.specifyfile = QtWidgets.QCheckBox('Specify file name')
        self.filenameEdit = QtWidgets.QLineEdit('Current time')

        # Snap and recording buttons
        self.snapTIFFButton = guitools.BetterPushButton('Snap')
        self.snapTIFFButton.setStyleSheet("font-size:16px")
        self.snapTIFFButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                          QtWidgets.QSizePolicy.Expanding)
        self.recButton = guitools.BetterPushButton('REC')
        self.recButton.setStyleSheet("font-size:16px")
        self.recButton.setCheckable(True)
        self.recButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                     QtWidgets.QSizePolicy.Expanding)
        # Number of frames and measurement timing
        modeTitle = QtWidgets.QLabel('<strong>Recording mode</strong>')
        modeTitle.setTextFormat(QtCore.Qt.RichText)
        self.specifyFrames = QtWidgets.QRadioButton('Number of frames')
        self.specifyTime = QtWidgets.QRadioButton('Time (s)')
        self.recScanOnceBtn = QtWidgets.QRadioButton('Scan once')
        self.recScanLapseBtn = QtWidgets.QRadioButton('Time-lapse scan')
        self.currentLapse = QtWidgets.QLabel('0 / ')
        self.timeLapseEdit = QtWidgets.QLineEdit('5')
        self.freqLabel = QtWidgets.QLabel('Freq [s]')
        self.freqEdit = QtWidgets.QLineEdit('0')
        self.stepSizeLabel = QtWidgets.QLabel('Step size [um]')
        self.stepSizeEdit = QtWidgets.QLineEdit('0.05')
        self.untilSTOPbtn = QtWidgets.QRadioButton('Run until STOP')
        self.timeToRec = QtWidgets.QLineEdit('1')
        self.currentTime = QtWidgets.QLabel('0 / ')
        self.currentTime.setAlignment((QtCore.Qt.AlignRight |
                                       QtCore.Qt.AlignVCenter))
        self.currentFrame = QtWidgets.QLabel('0 /')
        self.currentFrame.setAlignment((QtCore.Qt.AlignRight |
                                        QtCore.Qt.AlignVCenter))
        self.numExpositionsEdit = QtWidgets.QLineEdit('100')
        self.tRemaining = QtWidgets.QLabel()
        self.tRemaining.setAlignment((QtCore.Qt.AlignCenter |
                                      QtCore.Qt.AlignVCenter))

        self.saveModeLabel = QtWidgets.QLabel('<strong>Save mode:</strong>')
        self.saveModeList = QtWidgets.QComboBox()
        self.saveModeList.addItems(['Save on disk',
                                    'Save in memory for reconstruction',
                                    'Save on disk and keep in memory'])

        # Add items to GridLayout
        buttonWidget = QtWidgets.QWidget()
        buttonGrid = QtWidgets.QGridLayout()
        buttonWidget.setLayout(buttonGrid)
        buttonGrid.addWidget(self.snapTIFFButton, 0, 0)
        buttonWidget.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                   QtWidgets.QSizePolicy.Expanding)
        buttonGrid.addWidget(self.recButton, 0, 2)

        recGrid = QtWidgets.QGridLayout()
        self.setLayout(recGrid)

        recGrid.addWidget(recTitle, 0, 0, 1, 3)
        recGrid.addWidget(QtWidgets.QLabel('Detector to capture'), 1, 0)
        recGrid.addWidget(self.detectorList, 1, 1, 1, 4)
        recGrid.addWidget(QtWidgets.QLabel('Folder'), 2, 0)
        recGrid.addWidget(self.folderEdit, 2, 1, 1, 3)
        recGrid.addWidget(self.openFolderButton, 2, 4)
        recGrid.addWidget(self.filenameEdit, 3, 1, 1, 3)

        recGrid.addWidget(self.specifyfile, 3, 0)

        recGrid.addWidget(modeTitle, 4, 0)
        recGrid.addWidget(self.specifyFrames, 5, 0, 1, 5)
        recGrid.addWidget(self.currentFrame, 5, 1)
        recGrid.addWidget(self.numExpositionsEdit, 5, 2)
        recGrid.addWidget(self.specifyTime, 6, 0, 1, 5)
        recGrid.addWidget(self.currentTime, 6, 1)
        recGrid.addWidget(self.timeToRec, 6, 2)
        recGrid.addWidget(self.tRemaining, 6, 3, 1, 2)
        recGrid.addWidget(self.recScanOnceBtn, 7, 0, 1, 5)
        recGrid.addWidget(self.recScanLapseBtn, 8, 0, 1, 5)
        recGrid.addWidget(self.currentLapse, 8, 1)
        recGrid.addWidget(self.timeLapseEdit, 8, 2)
        recGrid.addWidget(self.freqLabel, 8, 3)
        recGrid.addWidget(self.freqEdit, 8, 4)
        recGrid.addWidget(self.untilSTOPbtn, 10, 0, 1, -1)
        recGrid.addWidget(self.saveModeLabel, 12, 0)
        recGrid.addWidget(self.saveModeList, 12, 1, 1, -1)
        recGrid.addWidget(buttonWidget, 13, 0, 1, -1)

        # Initial condition of fields and checkboxes.
        self.writable = True
        self.readyToRecord = False
        self.filenameEdit.setEnabled(False)
        self.untilSTOPbtn.setChecked(True)

        # Connect signals
        self.detectorList.currentIndexChanged.connect(self.sigDetectorChanged)
        self.openFolderButton.clicked.connect(self.sigOpenRecFolderClicked)
        self.specifyfile.toggled.connect(self.sigSpecFileToggled)
        self.snapTIFFButton.clicked.connect(self.sigSnapRequested)
        self.recButton.toggled.connect(self.sigRecToggled)
        self.specifyFrames.clicked.connect(self.sigSpecFramesPicked)
        self.specifyTime.clicked.connect(self.sigSpecTimePicked)
        self.recScanOnceBtn.clicked.connect(self.sigScanOncePicked)
        self.recScanLapseBtn.clicked.connect(self.sigScanLapsePicked)
        self.untilSTOPbtn.clicked.connect(self.sigUntilStopPicked)