예제 #1
0
class PyFab(QMainWindow):
    def __init__(self, parent=None, doconfig=True):
        super(PyFab, self).__init__(parent)

        uifile = Path('pyfablib').joinpath('FabWidget.ui')
        uic.loadUi(uifile, self)

        self.configuration = Configuration(self)

        # Camera
        self.camera.close()  # remove placeholder widget from UI
        self.camera = QCamera()
        self.screen.camera = self.camera
        self.cameraLayout.addWidget(self.camera)

        # Spatial light modulator
        self.slm = QSLM(self)

        # Computation pipeline
        self.cgh.device = CGH(self, shape=self.slm.shape).start()

        # Trapping pattern is an interactive overlay
        # that translates user actions into hologram computations
        self.pattern = QTrappingPattern(parent=self)
        self.screen.addOverlay(self.pattern)

        # Process automation
        self.tasks = QTaskmanager(self)
        self.TaskManagerView.setModel(self.tasks)
        self.TaskManagerView.setSelectionMode(3)

        self.configureUi()
        self.connectSignals()

        self.doconfig = doconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.pattern.clearTraps()
        self.screen.close()
        self.slm.close()
        self.cgh.device.stop()
        self.deleteLater()

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'pyfab.avi'

        self.TaskPropertiesLayout = QStackedLayout(self.TaskPropertiesView)
        index = self.tabWidget.indexOf(self.hardware.parent())
        self.tabWidget.setTabEnabled(index, self.hardware.has_content())
        self.slmView.setRange(xRange=[0, self.slm.width()],
                              yRange=[0, self.slm.height()],
                              padding=0)
        buildTaskMenu(self)
        self.adjustSize()

    def connectSignals(self):
        # Signals associated with arrival of images from camera
        newframe = self.screen.source.sigNewFrame
        # 1. Update histograms from image data
        newframe.connect(self.histogram.updateHistogram)
        # 2. CGH computations are coordinated with camera
        newframe.connect(self.pattern.refresh)

        # Signals associated with the CGH pipeline
        # 1. Screen events trigger requests for trap updates
        self.screen.sigMousePress.connect(self.pattern.mousePress)
        self.screen.sigMouseRelease.connect(self.pattern.mouseRelease)
        self.screen.sigMouseMove.connect(self.pattern.mouseMove)
        self.screen.sigMouseWheel.connect(self.pattern.mouseWheel)
        # 2. Trap widget reflects changes to trapping pattern
        self.pattern.sigCompute.connect(self.cgh.device.compute)
        self.pattern.trapAdded.connect(self.traps.registerTrap)
        # 3. Project result when calculation is complete
        self.cgh.device.sigHologramReady.connect(self.slm.setData)
        self.cgh.device.sigHologramReady.connect(self.slmView.setData)

        # Signals associated with GUI controls
        # 1. DVR Source
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(lambda: self.setDvrSource(self.screen))

        # 2. Tab expose events
        self.tabWidget.currentChanged.connect(self.hardware.expose)
        self.tabWidget.currentChanged.connect(
            lambda n: self.slmView.setData(self.cgh.device.phi))

        # 3. Task pipeline
        self.bpausequeue.clicked.connect(self.pauseTasks)
        self.bclearqueue.clicked.connect(self.stopTasks)

        self.bpausesel.clicked.connect(self.tasks.toggleSelected)
        self.bclearsel.clicked.connect(self.tasks.removeSelected)
        self.bserialize.clicked.connect(
            lambda: self.tasks.serialize(self.experimentPath.text()))
        self.bdeserialize.clicked.connect(
            lambda: self.tasks.registerTask('QExperiment',
                                            info=self.experimentPath.text(),
                                            loop=self.loop.value()))

        self.TaskManagerView.clicked.connect(self.tasks.displayProperties)
        self.TaskManagerView.doubleClicked.connect(self.tasks.toggleCurrent)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        filename = self.configuration.filename(suffix='.png')
        if select:
            getname = QFileDialog.getSaveFileName
            filename, _ = getname(self,
                                  'Save Image',
                                  directory=filename,
                                  filter='Image files (*.png)')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveHologram(self, select=False):
        self.saveImage(self.slm.qimage, select=select)

    @pyqtSlot()
    def saveHologramAs(self):
        self.saveHologram(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)
            self.configuration.save(self.cgh)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)
            self.configuration.restore(self.cgh)

    @pyqtSlot()
    def pauseTasks(self):
        self.tasks.pauseTasks()
        msg = 'Tasks paused' if self.tasks.paused else 'Tasks running'
        self.statusBar().showMessage(msg)

    @pyqtSlot()
    def stopTasks(self):
        self.tasks.clearTasks()
        self.statusBar().showMessage('Task queue cleared')
예제 #2
0
class Jansen(QMainWindow, Ui_Jansen):

    def __init__(self, parent=None, noconfig=False):
        super(Jansen, self).__init__(parent)
        self.setupUi(self)
        self.configuration = Configuration(self)

        # Setup vision tab
        try:
            self.vision.close()
            self.vision.setObjectName("vision")
            self.vision = QVision(self.tabVision)
            self.visionLayout.addWidget(self.vision)
            self.setupVision = True
        except Exception as ex2:
            err = ex2 if ex1 is None else ex1
            msg = 'Could not import Machine Vision pipeline: {}'
            logger.warning(msg.format(err))
            self.tabWidget.setTabEnabled(2, False)
            self.setupVision = False

        # Setup camera
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

        self.configureUi()
        self.connectSignals()

        self.doconfig = not noconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.screen.close()
        self.deleteLater()

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'jansen.avi'
        if self.setupVision:
            self.vision.jansen = self
        self.adjustSize()

    def connectSignals(self):
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(
            lambda: self.setDvrSource(self.screen))
        self.actionSavePhoto.triggered.connect(self.savePhoto)
        self.actionSavePhotoAs.triggered.connect(
            lambda: self.savePhoto(True))

        # Signals associated with handling images
        self.screen.source.sigNewFrame.connect(self.histogram.updateHistogram)
        if self.setupVision:
            self.screen.sigNewFrame.connect(self.vision.process)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        if select:
            getname = QFileDialog.getSaveFileName
            filename, _ = getname(self, 'Save Image',
                                  directory=filename,
                                  filter='Image files (*.png)')
        else:
            filename = self.configuration.filename(suffix='.png')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage.mirrored(vertical=True)
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)
            if self.setupVision:
                self.configuration.save(self.vision)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)
            if self.setupVision:
                self.configuration.restore(self.vision)
예제 #3
0
class PyFab(QMainWindow, Ui_PyFab):
    def __init__(self, parent=None, doconfig=True):
        super(PyFab, self).__init__(parent)

        self.setupUi(self)
        self.configuration = Configuration(self)

        # Camera
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

        # Setup vision tab
        try:
            self.vision.close()
            self.vision.setObjectName("vision")
            self.vision = QVision(self.tabVision)
            self.visionLayout.addWidget(self.vision)
            self.setupVision = True
        except Exception as ex2:
            err = ex2 if ex1 is None else ex1
            msg = 'Could not import Machine Vision pipeline: {}'
            logger.warning(msg.format(err))
            self.tabWidget.setTabEnabled(2, False)
            self.setupVision = False

        # Spatial light modulator
        self.slm = QSLM(self)

        # Computation pipeline
        self.cgh.device = CGH(self, shape=self.slm.shape)
        self.cgh.device.start()

        # Trapping pattern is an interactive overlay
        # that translates user actions into hologram computations
        self.pattern = QTrappingPattern(parent=self)
        self.screen.addOverlay(self.pattern)

        # Trap automated assembly framework
        self.assembler = TrapAssemble(parent=self)
        self.mover = TrapMove(parent=self)

        # Process automation
        self.tasks = Taskmanager(self)

        self.configureUi()
        self.connectSignals()

        self.doconfig = doconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.pattern.clearTraps()
        self.screen.close()
        self.slm.close()
        self.cgh.device.stop()
        self.deleteLater()

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'pyfab.avi'
        if self.setupVision:
            self.vision.jansen = self
        index = 3
        self.hardware.index = index
        self.tabWidget.currentChanged.connect(self.hardware.expose)
        self.tabWidget.setTabEnabled(index, self.hardware.has_content())
        self.slmView.setRange(xRange=[0, self.slm.width()],
                              yRange=[0, self.slm.height()],
                              padding=0)
        self.slmView.setYRange(0, self.slm.height())
        buildTaskMenu(self)
        self.adjustSize()

    def connectSignals(self):
        # Signals associated with GUI controls
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(lambda: self.setDvrSource(self.screen))

        # Signals associated with handling images
        self.screen.source.sigNewFrame.connect(self.histogram.updateHistogram)
        self.screen.source.sigNewFrame.connect(self.assembler.move)
        self.screen.source.sigNewFrame.connect(self.mover.move)
        if self.setupVision:
            self.screen.sigNewFrame.connect(self.vision.process)

        # Signals associated with the CGH pipeline
        # 1. Screen events trigger requests for trap updates
        self.screen.sigMousePress.connect(self.pattern.mousePress)
        self.screen.sigMouseRelease.connect(self.pattern.mouseRelease)
        self.screen.sigMouseMove.connect(self.pattern.mouseMove)
        self.screen.sigMouseWheel.connect(self.pattern.mouseWheel)
        # 2. Updates to trapping pattern require hologram calculation
        self.pattern.sigCompute.connect(self.cgh.device.setTraps)
        self.pattern.trapAdded.connect(self.traps.registerTrap)
        # 3. Suppress requests while hologram is being computed
        self.cgh.device.sigComputing.connect(self.screen.pauseSignals)
        # 4. Project result when calculation is complete
        self.cgh.device.sigHologramReady.connect(self.slm.setData)
        self.cgh.device.sigHologramReady.connect(self.slmView.setData)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        if select:
            getname = QFileDialog.getSaveFileName
            directory = self.configuration.datadir
            filename, _ = getname(self,
                                  'Save Image',
                                  directory=directory,
                                  filter='Image files (*.png)')
        else:
            filename = self.configuration.filename(suffix='.png')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage.mirrored(vertical=True)
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveHologram(self, select=False):
        self.saveImage(self.slm.qimage, select=select)

    @pyqtSlot()
    def saveHologramAs(self):
        self.saveHologram(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)
            self.configuration.save(self.cgh)
            if self.setupVision:
                self.configuration.save(self.vision)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)
            self.configuration.restore(self.cgh)
            if self.setupVision:
                self.configuration.restore(self.vision)

    @pyqtSlot()
    def pauseTasks(self):
        self.tasks.pauseTasks()
        msg = 'Tasks paused' if self.tasks.paused() else 'Tasks running'
        self.statusBar().showMessage(msg)

    @pyqtSlot()
    def stopTasks(self):
        self.tasks.clearTasks()
        self.statusBar().showMessage('Task queue cleared')
예제 #4
0
파일: jansen.py 프로젝트: davidgrier/pyfab
class Jansen(QMainWindow):
    def __init__(self, parent=None, noconfig=False):
        super(Jansen, self).__init__(parent)

        uifile = Path('jansenlib').joinpath('JansenWidget.ui')
        uic.loadUi(uifile, self)

        self.configuration = Configuration(self)

        self.setupCamera()
        self.configureUi()
        self.connectSignals()

        self.doconfig = not noconfig
        if self.doconfig:
            self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        self.screen.close()
        self.deleteLater()

    def setupCamera(self):
        self.camera.close()  # remove placeholder widget from UI
        camera = QCamera()
        self.camera = camera
        self.screen.camera = camera
        self.cameraLayout.addWidget(camera)

    def configureUi(self):
        self.filters.screen = self.screen
        self.histogram.screen = self.screen
        self.dvr.screen = self.screen
        self.dvr.source = self.screen.default
        self.dvr.filename = self.configuration.datadir + 'jansen.avi'
        self.adjustSize()

    def connectSignals(self):
        self.bcamera.clicked.connect(
            lambda: self.setDvrSource(self.screen.default))
        self.bfilters.clicked.connect(lambda: self.setDvrSource(self.screen))
        self.actionSavePhoto.triggered.connect(self.savePhoto)
        self.actionSavePhotoAs.triggered.connect(lambda: self.savePhoto(True))

        # Signals associated with handling images
        self.screen.source.sigNewFrame.connect(self.histogram.updateHistogram)

    @pyqtSlot()
    def setDvrSource(self, source):
        self.dvr.source = source

    #
    # Slots for menu actions
    #
    def saveImage(self, qimage, select=False):
        if qimage is None:
            return
        filename = self.configuration.filename(suffix='.png')
        if select:
            getname = QFileDialog.getSaveFileName
            filename, _ = getname(self,
                                  'Save Image',
                                  directory=filename,
                                  filter='Image files (*.png)')
        if filename:
            qimage.save(filename)
            self.statusBar().showMessage('Saved ' + filename)

    @pyqtSlot()
    def savePhoto(self, select=False):
        qimage = self.screen.imageItem.qimage.mirrored(vertical=True)
        self.saveImage(qimage, select=select)

    @pyqtSlot()
    def savePhotoAs(self):
        self.savePhoto(select=True)

    @pyqtSlot()
    def saveSettings(self):
        if self.doconfig:
            self.configuration.save(self.camera)

    @pyqtSlot()
    def restoreSettings(self):
        if self.doconfig:
            self.configuration.restore(self.camera)