Esempio n. 1
0
    def run(self):
        # Returns True to close config dialog box, False or None otherwise.
        # Check if the user is set to save to an already-existing file.
        if self.savePath and os.path.exists(self.savePath):
            if not guiUtils.getUserPermission(
                ("The file:\n%s\nalready exists. " % self.savePath) +
                    "Are you sure you want to overwrite it?"):
                return False

        global lastExperiment
        lastExperiment = self
        self.sanityCheckEnvironment()
        self.prepareHandlers()

        self.cameraToReadoutTime = {
            c: c.getTimeBetweenExposures(isExact=True)
            for c in self.cameras
        }
        for camera, readTime in self.cameraToReadoutTime.items():
            if type(readTime) is not decimal.Decimal:
                raise RuntimeError(
                    "Camera %s did not provide an exact (decimal.Decimal) readout time"
                    % camera.name)

        # Indicate any frame transfer cameras for reset at start of table.
        for camera in self.cameras:
            if camera.getExposureMode(
            ) == cockpit.handlers.camera.TRIGGER_AFTER:
                self.cameraToIsReady[camera] = False

        self.createValidActionTable()
        if self.numReps > 1 and self.repDuration < self.table.lastActionTime / 1000:
            warning = "Repeat duration is less than the time required to run " \
                      "one repeat. Choose:" \
                      "\n    'OK' to run repeats as fast as possible;" \
                      "\n    'Cancel' to go back and change parameters."
            if not guiUtils.getUserPermission(warning):
                return False

        # ToDo: check duration of action table against timelapse settings
        # display appropriate warnings.
        self.lastMinuteActions()

        self._run_thread = threading.Thread(target=self.execute,
                                            name="Experiment-execute")
        self._run_thread.start()

        saveThread = None
        if self.savePath and max(self.cameraToImageCount.values()):

            cameraToExcitation = {c: 0.0 for c in self.cameras}
            for cameras, lightTimePairs in self.exposureSettings:
                ## If there's multiple light sources for the same
                ## camera pick the one with highest wavelength.  Main
                ## case of multiple light sources is single molecule
                ## localisation where a lower wavelength is doing the
                ## pumping while but excitation for fluorescence is
                ## with the higher wavelength.
                if lightTimePairs:
                    max_wavelength = max(
                        [l.wavelength for l, t in lightTimePairs])
                else:
                    max_wavelength = 0.0
                for camera in cameras:
                    if camera not in self.cameras:
                        continue
                    cameraToExcitation[camera] = max(
                        cameraToExcitation[camera], max_wavelength)

            saver = dataSaver.DataSaver(self.cameras, self.numReps,
                                        self.cameraToImageCount,
                                        self.cameraToIgnoredImageIndices,
                                        self._run_thread,
                                        self.savePath, self.sliceHeight,
                                        self.generateTitles(),
                                        cameraToExcitation)
            saver.startCollecting()
            saveThread = threading.Thread(target=saver.executeAndSave,
                                          name="Experiment-execute-save")
            saveThread.start()
            generatedFilenames.append(saver.getFilenames())

        cleanup_thread = threading.Thread(target=self.cleanup,
                                          args=[self._run_thread, saveThread],
                                          name="Experiment-cleanup")
        cleanup_thread.start()
        return True
Esempio n. 2
0
    def runExperiment(self):
        # Returns True to close dialog box, None or False otherwise.
        self.saveSettings()
        # Find the Z mover with the smallest range of motion, assumed
        # to be our experiment mover.
        mover = depot.getSortedStageMovers()[2][-1]
        # Only use active cameras and enabled lights.
        # Must do list(filter) because we will iterate over the list
        # many times.
        cameras = list(
            filter(lambda c: c.getIsEnabled(),
                   depot.getHandlersOfType(depot.CAMERA)))
        if not cameras:
            wx.MessageDialog(
                self,
                message=
                "No cameras are enabled, so the experiment cannot be run.",
                style=wx.ICON_EXCLAMATION | wx.STAY_ON_TOP
                | wx.OK).ShowModal()
            return True

        exposureSettings = []
        if self.shouldExposeSimultaneously.GetValue():
            # A single exposure event with all cameras and lights.
            lightTimePairs = []
            for i, light in enumerate(self.allLights):
                if (self.allLights[i].getIsEnabled()
                        and self.lightExposureTimes[i].GetValue()):
                    lightTimePairs.append(
                        (light,
                         guiUtils.tryParseNum(self.lightExposureTimes[i],
                                              decimal.Decimal)))

            if lightTimePairs == []:
                if not guiUtils.getUserPermission(
                    ("No enabled light has a define exposure time.") +
                        "Are you sure you want to continue?"):
                    return True

            exposureSettings = [(cameras, lightTimePairs)]
        else:
            # A separate exposure for each camera.
            for camera in cameras:
                cameraSettings = self.cameraToExposureTimes[camera]
                settings = []
                for i, light in enumerate(self.allLights):
                    if not light.getIsEnabled():
                        continue
                    timeControl = cameraSettings[i]
                    if timeControl.GetValue():
                        settings.append(
                            (light,
                             guiUtils.tryParseNum(timeControl,
                                                  decimal.Decimal)))
                exposureSettings.append(([camera], settings))

        altitude = cockpit.interfaces.stageMover.getPositionForAxis(2)
        # Default to "current is bottom"
        altBottom = altitude
        zHeight = guiUtils.tryParseNum(self.stackHeight, float)
        if self.zPositionMode.GetStringSelection() == 'Current is center':
            altBottom = altitude - zHeight / 2
        elif self.zPositionMode.GetStringSelection() == 'Use saved top/bottom':
            altBottom = cockpit.interfaces.stageMover.mover.SavedBottom
            zHeight = cockpit.interfaces.stageMover.mover.SavedTop - altBottom

        sliceHeight = guiUtils.tryParseNum(self.sliceHeight, float)
        if zHeight == 0:
            # 2D mode.
            zHeight = 1e-6
            sliceHeight = 1e-6

        try:
            savePath = self.filepath_panel.GetPath()
        except Exception:
            cockpit.gui.ExceptionBox("Failed to get filename for data.",
                                     parent=self)
            return True

        params = {
            'numReps': guiUtils.tryParseNum(self.numReps),
            'repDuration': guiUtils.tryParseNum(self.repDuration, float),
            'zPositioner': mover,
            'altBottom': altBottom,
            'zHeight': zHeight,
            'sliceHeight': sliceHeight,
            'exposureSettings': exposureSettings,
            'savePath': savePath
        }
        experimentType = self.experimentType.GetStringSelection()
        module = self.experimentStringToModule[experimentType]
        if module in self.experimentModuleToPanel:
            # Add on the special parameters needed by this experiment type.
            params = self.experimentModuleToPanel[module].augmentParams(params)

        self.runner = module.EXPERIMENT_CLASS(**params)
        return self.runner.run()