예제 #1
0
파일: acqmng.py 프로젝트: lanery/odemis
def acquire(streams, settings_obs=None):
    """ Start an acquisition task for the given streams.

    It will decide in which order the stream must be acquired.

    ..Note:
        It is highly recommended to not have any other acquisition going on.

    :param streams: [Stream] the streams to acquire
    :param settings_obs: [SettingsObserver or None] class that contains a list of all VAs
        that should be saved as metadata
    :return: (ProgressiveFuture) an object that represents the task, allow to
        know how much time before it is over and to cancel it. It also permits
        to receive the result of the task, which is a tuple:
            (list of model.DataArray): the raw acquisition data
            (Exception or None): exception raised during the acquisition
    """

    # create a future
    future = model.ProgressiveFuture()

    # create a task
    task = AcquisitionTask(streams, future, settings_obs)
    future.task_canceller = task.cancel  # let the future cancel the task

    # connect the future to the task and run in a thread
    executeAsyncTask(future, task.run)

    # return the interface to manipulate the task
    return future
예제 #2
0
def cryoTiltSample(rx, rz=0):
    """
    Provide the ability to switch between imaging and tilted position, withing bumping into anything.
    Imaging position is considered when rx and rz are equal 0, otherwise it's considered tilting
    :param rx: (float) rotation movement in x axis
    :param rz: (float) rotation movement in z axis
    :return (CancellableFuture -> None): cancellable future of the move to observe the progress, and control raising the ValueError exception
    """
    # Get the stage and align components from the backend components
    stage = model.getComponent(role='stage')
    align = model.getComponent(role='align')

    f = model.CancellableFuture()
    f.task_canceller = _cancelCryoMoveSample
    f._task_state = RUNNING
    f._task_lock = threading.Lock()
    f._running_subf = model.InstantaneousFuture()
    # Run in separate thread
    executeAsyncTask(f, _doCryoTiltSample, args=(
        f,
        stage,
        align,
        rx,
        rz,
    ))
    return f
예제 #3
0
파일: spot.py 프로젝트: ihebdelmic/odemis
def AlignSpot(ccd, stage, escan, focus, type=OBJECTIVE_MOVE, dfbkg=None, rng_f=None):
    """
    Wrapper for DoAlignSpot. It provides the ability to check the progress of
    spot mode procedure or even cancel it.
    ccd (model.DigitalCamera): The CCD
    stage (model.Actuator): The stage
    escan (model.Emitter): The e-beam scanner
    focus (model.Actuator): The optical focus
    type (string): Type of move in order to align
    dfbkg (model.DataFlow): dataflow of se- or bs- detector for background
      subtraction
    rng_f (tuple of floats): range to apply Autofocus on if needed
    returns (model.ProgressiveFuture):    Progress of DoAlignSpot,
                                         whose result() will return:
            returns (float):    Final distance to the center (m)
    """
    # Create ProgressiveFuture and update its state to RUNNING
    est_start = time.time() + 0.1
    f = model.ProgressiveFuture(start=est_start,
                                end=est_start + estimateAlignmentTime(ccd.exposureTime.value))
    f._task_state = RUNNING

    # Task to run
    f.task_canceller = _CancelAlignSpot
    f._alignment_lock = threading.Lock()
    f._done = threading.Event()

    # Create autofocus and centerspot module
    f._autofocusf = model.InstantaneousFuture()
    f._centerspotf = model.InstantaneousFuture()

    # Run in separate thread
    executeAsyncTask(f, _DoAlignSpot,
                     args=(f, ccd, stage, escan, focus, type, dfbkg, rng_f))
    return f
예제 #4
0
파일: spot.py 프로젝트: ihebdelmic/odemis
def CenterSpot(ccd, stage, escan, mx_steps, type=OBJECTIVE_MOVE, dfbkg=None):
    """
    Wrapper for _DoCenterSpot.
    ccd (model.DigitalCamera): The CCD
    stage (model.Actuator): The stage
    escan (model.Emitter): The e-beam scanner
    mx_steps (int): Maximum number of steps to reach the center
    type (*_MOVE or BEAM_SHIFT): Type of move in order to align
    dfbkg (model.DataFlow or None): If provided, will be used to start/stop
     the e-beam emission (it must be the dataflow of se- or bs-detector) in
     order to do background subtraction. If None, no background subtraction is
     performed.
    returns (model.ProgressiveFuture):    Progress of _DoCenterSpot,
                                         whose result() will return:
                (float):    Final distance to the center #m
                (2 floats): vector to the spot from the center (m, m)
    """
    # Create ProgressiveFuture and update its state to RUNNING
    est_start = time.time() + 0.1
    f = model.ProgressiveFuture(start=est_start,
                                end=est_start + estimateCenterTime(ccd.exposureTime.value))
    f._spot_center_state = RUNNING
    f.task_canceller = _CancelCenterSpot
    f._center_lock = threading.Lock()

    # Run in separate thread
    executeAsyncTask(f, _DoCenterSpot,
                     args=(f, ccd, stage, escan, mx_steps, type, dfbkg))
    return f
예제 #5
0
def SEMCCDAcquisition(escan, ccd, detector, light):
    f = model.ProgressiveFuture()
    f._acq_state = RUNNING

    # Task to run
    doAcquisition = _DoAcquisition
    f.task_canceller = _CancelAcquisition

    # Run in separate thread
    executeAsyncTask(f, doAcquisition, args=(f, escan, ccd, detector, light))
    return f
예제 #6
0
파일: _futures.py 프로젝트: delmic/odemis
def wrapSimpleStreamIntoFuture(stream):
    """
    Starts one stream acquisition and return a Future
    Works with streams having only .is_active and .image .
    returns (Future that returns list of DataArray): the acquisition task
    """
    # Create a Future, not started yet
    future = SimpleStreamFuture(stream)
    # run in a separate thread
    executeAsyncTask(future, future._run)
    return future
예제 #7
0
파일: _futures.py 프로젝트: effting/odemis
def wrapSimpleStreamIntoFuture(stream):
    """
    Starts one stream acquisition and return a Future
    Works with streams having only .is_active and .image .
    returns (Future that returns list of DataArray): the acquisition task
    """
    # Create a Future, not started yet
    future = SimpleStreamFuture(stream)
    # run in a separate thread
    executeAsyncTask(future, future._run)
    return future
예제 #8
0
    def do_progressive_long(self, duration=5):
        """
        return a ProgressiveFuture, which will have the estimated time shorten
        """
        # First estimate the time to 10s, and then it will be shorten
        start = time.time() + 1
        end = start + 10
        f = model.ProgressiveFuture(start, end)

        # run in a separate thread
        executeAsyncTask(f, self._long_pessimistic_task, args=(f, duration))
        return f
예제 #9
0
def SEMCCDAcquisition(escan, ccd, detector, light):
    f = model.ProgressiveFuture()
    f._acq_state = RUNNING

    # Task to run
    doAcquisition = _DoAcquisition
    f.task_canceller = _CancelAcquisition

    # Run in separate thread
    executeAsyncTask(f, doAcquisition,
                     args=(f, escan, ccd, detector, light))
    return f
예제 #10
0
    def do_progressive_long(self, duration=5):
        """
        return a ProgressiveFuture, which will have the estimated time shorten
        """
        # First estimate the time to 10s, and then it will be shorten
        start = time.time() + 1
        end = start + 10
        f = model.ProgressiveFuture(start, end)

        # run in a separate thread
        executeAsyncTask(f, self._long_pessimistic_task, args=(f, duration))
        return f
예제 #11
0
    def acquire(self):
        """
        Runs the acquisition
        returns Future that will have as a result a DataArray with the 3D data
        """
        # Make sure the stream is prepared (= optical path set)
        # TODO: move the optical path change done in the plugin.acquire() to here
        # self.prepare().result()

        # Hard coded optical path (as the OPM doesn't know about this special mode)
        logging.info("Preparing optical path")
        # Configure the optical path for the CCD we need
        mvs = self._opm.selectorsToPath(self._detector.name)
        # On Odemis 2.9-, mvs is just a list of futures
        # On Odemis 2.10+, mvs is a list of tuples(future, comp, pos) => only keep the futures
        fs = [m[0] if isinstance(m, tuple) else m for m in mvs]
        # move lens 2 into position
        for p, n in self._lsw.axes["x"].choices.items():
            if n == "on":
                f = self._lsw.moveAbs({"x": p})
                fs.append(f)
                break

        # move big slit into position
        for p, n in self._bigslit.axes["x"].choices.items():
            if n == "off":
                f = self._bigslit.moveAbs({"x": p})
                fs.append(f)
                break

        # wait for all the moves to be over
        for f in fs:
            f.result()

        logging.debug("Optical path configured")

        est_start = time.time() + 0.1
        # Create a "Future", which is an object that can be used to follow the
        # task completion while it's going on, and get the result.
        f = model.ProgressiveFuture(start=est_start,
                                    end=est_start +
                                    self.estimateAcquisitionTime())
        f.task_canceller = self._cancelAcquisition
        f._acq_state = RUNNING
        f._acq_lock = threading.Lock()
        f._acq_done = threading.Event()

        # run task in separate thread
        executeAsyncTask(f, self._runAcquisition, args=(f, ))
        return f
예제 #12
0
파일: move.py 프로젝트: Mahmood-B/odemis
def cryoSwitchSamplePosition(target):
    """
    Provide the ability to switch between loading, imaging and coating position, without bumping into anything.
    :param target: (int) target position either one of the constants LOADING, IMAGING, COATING AND ALIGNMENT
    :return (CancellableFuture -> None): cancellable future of the move to observe the progress, and control raising the
    ValueError exception
    """
    f = model.CancellableFuture()
    f.task_canceller = _cancelCryoMoveSample
    f._task_state = RUNNING
    f._task_lock = threading.Lock()
    f._running_subf = model.InstantaneousFuture()
    # Run in separate thread
    executeAsyncTask(f, _doCryoSwitchSamplePosition, args=(f, target))
    return f
예제 #13
0
def FindOverlay(repetitions,
                dwell_time,
                max_allowed_diff,
                escan,
                ccd,
                detector,
                skew=False,
                bgsub=False):
    """
    Wrapper for DoFindOverlay. It provides the ability to check the progress of overlay procedure
    or even cancel it.
    repetitions (tuple of ints): The number of CL spots are used
    dwell_time (float): Time to scan each spot #s
    max_allowed_diff (float): Maximum allowed difference in electron coordinates #m
    escan (model.Emitter): The e-beam scanner
    ccd (model.DigitalCamera): The CCD
    detector (model.Detector): The electron detector
    skew (boolean): If True, also compute skew
    bgsub (boolean): If True, apply background substraction in grid scanning
    returns (model.ProgressiveFuture): Progress of DoFindOverlay, whose result() will return:
            tuple: Transformation parameters
                translation (Tuple of 2 floats)
                scaling (Float)
                rotation (Float)
            dict : Transformation metadata
    """
    # Create ProgressiveFuture and update its state to RUNNING
    est_start = time.time() + 0.1
    f = model.ProgressiveFuture(start=est_start,
                                end=est_start +
                                estimateOverlayTime(dwell_time, repetitions))
    f._find_overlay_state = RUNNING

    # Task to run
    f.task_canceller = _CancelFindOverlay
    f._overlay_lock = threading.Lock()
    f._done = threading.Event()

    # Create scanner for scan grid
    f._gscanner = GridScanner(repetitions, dwell_time, escan, ccd, detector,
                              bgsub)

    # Run in separate thread
    executeAsyncTask(f,
                     _DoFindOverlay,
                     args=(f, repetitions, dwell_time, max_allowed_diff, escan,
                           ccd, detector, skew))
    return f
예제 #14
0
파일: light.py 프로젝트: ihebdelmic/odemis
def turnOnLight(bl, ccd):
    """
    Turn on a light and wait until it detects a signal change on the ccd
    bl (Light): the light, which should initially be turned off.
    ccd (DigitalCamera): detector to use to check for the signal
    returns (CancellableFuture): a future that will finish when a significant
      signal increase is detected. Can also be used to stop the procedure. 
    """
    f = CancellableFuture()
    f.task_canceller = _cancelTurnOnLight
    f._task_state = RUNNING
    f._task_lock = threading.Lock()
    f._was_stopped = False  # if cancel was successful
    # Run in separate thread
    executeAsyncTask(f, _doTurnOnLight, args=(f, bl, ccd))
    return f
예제 #15
0
파일: light.py 프로젝트: delmic/odemis
def turnOnLight(bl, ccd):
    """
    Turn on a light and wait until it detects a signal change on the ccd
    bl (Light): the light, which should initially be turned off.
    ccd (DigitalCamera): detector to use to check for the signal
    returns (CancellableFuture): a future that will finish when a significant
      signal increase is detected. Can also be used to stop the procedure. 
    """
    f = CancellableFuture()
    f.task_canceller = _cancelTurnOnLight
    f._task_state = RUNNING
    f._task_lock = threading.Lock()
    f._was_stopped = False  # if cancel was successful
    # Run in separate thread
    executeAsyncTask(f, _doTurnOnLight, args=(f, bl, ccd))
    return f
예제 #16
0
    def acquire(self):
        """
        Runs the acquisition
        returns Future that will have as a result a DataArray with the 3D data
        """
        # Make sure the stream is prepared (= optical path set)
        # TODO: move the optical path change done in the plugin.acquire() to here
        # self.prepare().result()

        # Hard coded optical path (as the OPM doesn't know about this special mode)
        logging.info("Preparing optical path")
        # Configure the optical path for the CCD we need
        fs = self._opm.selectorsToPath(self._detector.name)
        # move lens 2 into position
        for p, n in self._lsw.axes["x"].choices.items():
            if n == "on":
                f = self._lsw.moveAbs({"x": p})
                fs.append(f)
                break

        # move big slit into position
        for p, n in self._bigslit.axes["x"].choices.items():
            if n == "off":
                f = self._bigslit.moveAbs({"x": p})
                fs.append(f)
                break

        # wait for all the moves to be over
        for f in fs:
            f.result()

        logging.debug("Optical path configured")

        est_start = time.time() + 0.1
        # Create a "Future", which is an object that can be used to follow the
        # task completion while it's going on, and get the result.
        f = model.ProgressiveFuture(start=est_start,
                                    end=est_start + self.estimateAcquisitionTime())
        f.task_canceller = self._cancelAcquisition
        f._acq_state = RUNNING
        f._acq_lock = threading.Lock()
        f._acq_done = threading.Event()

        # run task in separate thread
        executeAsyncTask(f, self._runAcquisition, args=(f,))
        return f
예제 #17
0
def cryoSwitchAlignPosition(target):
    """
    Provide the ability to switch between loading, imaging and alignment position, without bumping into anything.
    :param target: (int) target position either one of the constants LOADING, IMAGING or ALIGNMENT
    :return (CancellableFuture -> None): cancellable future of the move to observe the progress, and control the raise
    ValueError exception
    """
    # Get the aligner from backend components
    align = model.getComponent(role='align')

    f = model.CancellableFuture()
    f.task_canceller = _cancelCryoMoveSample
    f._task_state = RUNNING
    f._task_lock = threading.Lock()
    f._running_subf = model.InstantaneousFuture()
    # Run in separate thread
    executeAsyncTask(f, _doCryoSwitchAlignPosition, args=(f, align, target))
    return f
예제 #18
0
파일: util_test.py 프로젝트: delmic/odemis
 def test_execute(self):
     f = CancellableFuture()
     t = executeAsyncTask(f, self.long_task, args=(42,), kwargs={"d": 3})
     self.assertFalse(f.done())
     time.sleep(0.1)
     self.assertTrue(f.running())
     r = f.result()
     self.assertEqual(r, -1)
     self.assertEqual(self._v, 42)
     self.assertEqual(self._d, 3)
예제 #19
0
파일: move.py 프로젝트: lanery/odemis
def cryoLoadSample(target):
    """
    Provide the ability to switch between loading position and imaging position, without bumping into anything.
    :param target: (int) target position either one of the constants LOADING or IMAGING
    :return (CancellableFuture -> None): cancellable future of the move to observe the progress, and control the
   raise ValueError exception
    """
    # Get the stage and focus components from the backend components
    stage = model.getComponent(role='stage')
    focus = model.getComponent(role='focus')

    f = model.CancellableFuture()
    f.task_canceller = _cancelCryoMoveSample
    f._task_state = RUNNING
    f._task_lock = threading.Lock()
    f._running_subf = model.InstantaneousFuture()
    # Run in separate thread
    executeAsyncTask(f, _doCryoLoadSample, args=(f, stage, focus, target))
    return f
예제 #20
0
 def test_execute(self):
     f = CancellableFuture()
     t = executeAsyncTask(f, self.long_task, args=(42, ), kwargs={"d": 3})
     self.assertFalse(f.done())
     time.sleep(0.1)
     self.assertTrue(f.running())
     r = f.result()
     self.assertEqual(r, -1)
     self.assertEqual(self._v, 42)
     self.assertEqual(self._d, 3)
예제 #21
0
    def acquire(self):
        """
        Runs the acquisition
        returns Future that will have as a result a DataArray with the spectrum
        """
        # Make sure every stream is prepared, not really necessary to check _prepared
        f = self.prepare()
        f.result()

        est_start = time.time() + 0.1
        f = model.ProgressiveFuture(start=est_start,
                                    end=est_start + self.estimateAcquisitionTime())
        f.task_canceller = self._cancelAcquisition
        f._acq_state = RUNNING
        f._acq_lock = threading.Lock()
        f._acq_done = threading.Event()

        # run task in separate thread
        executeAsyncTask(f, self._runAcquisition, args=(f,))
        return f
예제 #22
0
def AutoFocus(detector, emt, focus, dfbkg=None, good_focus=None, rng_focus=None, method=MTD_BINARY):
    """
    Wrapper for DoAutoFocus. It provides the ability to check the progress of autofocus
    procedure or even cancel it.
    detector (model.DigitalCamera or model.Detector): Detector on which to
      improve the focus quality
    emt (None or model.Emitter): In case of a SED this is the scanner used
    focus (model.Actuator): The focus actuator
    dfbkg (model.DataFlow or None): If provided, will be used to start/stop
     the e-beam emission (it must be the dataflow of se- or bs-detector) in
     order to do background subtraction. If None, no background subtraction is
     performed.
    good_focus (float): if provided, an already known good focus position to be
      taken into consideration while autofocusing
    rng_focus (tuple): if provided, the search of the best focus position is limited
      within this range
    method (MTD_*): focusing method, if BINARY we follow a dichotomic method while in
      case of EXHAUSTIVE we iterate through the whole provided range
    returns (model.ProgressiveFuture):  Progress of DoAutoFocus, whose result() will return:
            Focus position (m)
            Focus level
    """
    # Create ProgressiveFuture and update its state to RUNNING
    est_start = time.time() + 0.1
    f = model.ProgressiveFuture(start=est_start,
                                end=est_start + estimateAutoFocusTime(detector, emt))
    f._autofocus_state = RUNNING
    f._autofocus_lock = threading.Lock()
    f.task_canceller = _CancelAutoFocus

    # Run in separate thread
    if method == MTD_EXHAUSTIVE:
        autofocus_fn = _DoExhaustiveFocus
    elif method == MTD_BINARY:
        autofocus_fn = _DoBinaryFocus
    else:
        raise ValueError("Unknown autofocus method")

    executeAsyncTask(f, autofocus_fn,
                     args=(f, detector, emt, focus, dfbkg, good_focus, rng_focus))
    return f
예제 #23
0
    def acquire(self):
        """
        Runs the acquisition
        returns Future that will have as a result a DataArray with the spectrum
        """
        # Make sure every stream is prepared, not really necessary to check _prepared
        f = self.prepare()
        f.result()

        est_start = time.time() + 0.1
        f = model.ProgressiveFuture(start=est_start,
                                    end=est_start +
                                    self.estimateAcquisitionTime())
        f.task_canceller = self._cancelAcquisition
        f._acq_state = RUNNING
        f._acq_lock = threading.Lock()
        f._acq_done = threading.Event()

        # run task in separate thread
        executeAsyncTask(f, self._runAcquisition, args=(f, ))
        return f
예제 #24
0
def AutoFocusSpectrometer(spectrograph, focuser, detectors, selector=None, streams=None):
    """
    Run autofocus for a spectrograph. It will actually run autofocus on each
    gratings, and for each detectors. The input slit should already be in a
    good position (typically, almost closed), and a light source should be
    active.
    Note: it's currently tailored to the Andor Shamrock SR-193i. It's recommended
    to put the detector on the "direct" output as first detector.
    spectrograph (Actuator): should have grating and wavelength.
    focuser (Actuator): should have a z axis
    detectors (Detector or list of Detectors): all the detectors available on
      the spectrometer.
    selector (Actuator or None): must have a rx axis with each position corresponding
     to one of the detectors. If there is only one detector, selector can be None.
    return (ProgressiveFuture -> dict((grating, detector)->focus position)): a progressive future
      which will eventually return a map of grating/detector -> focus position.
    """
    if not isinstance(detectors, collections.Iterable):
        detectors = [detectors]
    if not detectors:
        raise ValueError("At least one detector must be provided")
    if len(detectors) > 1 and selector is None:
        raise ValueError("No selector provided, but multiple detectors")

    if streams is None:
        streams=[]

    # Create ProgressiveFuture and update its state to RUNNING
    est_start = time.time() + 0.1
    #calculate the time for the AutoFocusSpectrometer procedure to be completed
    a_time = _totalAutoFocusTime(spectrograph, detectors)
    f = model.ProgressiveFuture(start=est_start, end=est_start + a_time)
    f.task_canceller = _CancelAutoFocusSpectrometer
    # Extra info for the canceller
    f._autofocus_state = RUNNING
    f._autofocus_lock = threading.Lock()
    f._subfuture = InstantaneousFuture()
    # Run in separate thread
    executeAsyncTask(f, _DoAutoFocusSpectrometer, args=(f, spectrograph, focuser, detectors, selector, streams))
    return f
예제 #25
0
def FindOverlay(repetitions, dwell_time, max_allowed_diff, escan, ccd, detector, skew=False, bgsub=False):
    """
    Wrapper for DoFindOverlay. It provides the ability to check the progress of overlay procedure
    or even cancel it.
    repetitions (tuple of ints): The number of CL spots are used
    dwell_time (float): Time to scan each spot #s
    max_allowed_diff (float): Maximum allowed difference in electron coordinates #m
    escan (model.Emitter): The e-beam scanner
    ccd (model.DigitalCamera): The CCD
    detector (model.Detector): The electron detector
    skew (boolean): If True, also compute skew
    bgsub (boolean): If True, apply background substraction in grid scanning
    returns (model.ProgressiveFuture): Progress of DoFindOverlay, whose result() will return:
            tuple: Transformation parameters
                translation (Tuple of 2 floats)
                scaling (Float)
                rotation (Float)
            dict : Transformation metadata
    """
    # Create ProgressiveFuture and update its state to RUNNING
    est_start = time.time() + 0.1
    f = model.ProgressiveFuture(start=est_start,
                                end=est_start + estimateOverlayTime(dwell_time,
                                                                    repetitions))
    f._find_overlay_state = RUNNING

    # Task to run
    f.task_canceller = _CancelFindOverlay
    f._overlay_lock = threading.Lock()
    f._done = threading.Event()

    # Create scanner for scan grid
    f._gscanner = GridScanner(repetitions, dwell_time, escan, ccd, detector, bgsub)

    # Run in separate thread
    executeAsyncTask(f, _DoFindOverlay,
                     args=(f, repetitions, dwell_time, max_allowed_diff, escan,
                           ccd, detector, skew))
    return f
예제 #26
0
    def acquire(self):
        """
        Runs the acquisition
        returns Future that will have as a result a DataArray with the 3D data
        """
        # Make sure the stream is prepared (= optical path set)
        # TODO: on the SPARCv1, which doesn't support time-correlator mode,
        # this fails => need to use a different (and supported) mode.
        self.prepare().result()

        est_start = time.time() + 0.1
        # Create a "Future", which is an object that can be used to follow the
        # task completion while it's going on, and get the result.
        f = model.ProgressiveFuture(start=est_start,
                                    end=est_start + self.estimateAcquisitionTime())
        f.task_canceller = self._cancelAcquisition
        f._acq_state = RUNNING
        f._acq_lock = threading.Lock()
        f._acq_done = threading.Event()

        # run task in separate thread
        executeAsyncTask(f, self._runAcquisition, args=(f,))
        return f
예제 #27
0
    def acquire(self):
        """
        Runs the acquisition
        returns Future that will have as a result a DataArray with the 3D data
        """
        # Make sure the stream is prepared (= optical path set)
        # TODO: on the SPARCv1, which doesn't support time-correlator mode,
        # this fails => need to use a different (and supported) mode.
        self.prepare().result()

        est_start = time.time() + 0.1
        # Create a "Future", which is an object that can be used to follow the
        # task completion while it's going on, and get the result.
        f = model.ProgressiveFuture(start=est_start,
                                    end=est_start + self.estimateAcquisitionTime())
        f.task_canceller = self._cancelAcquisition
        f._acq_state = RUNNING
        f._acq_lock = threading.Lock()
        f._acq_done = threading.Event()

        # run task in separate thread
        executeAsyncTask(f, self._runAcquisition, args=(f,))
        return f
예제 #28
0
def acquireZStack(streams, zlevels, settings_obs=None):
    """
    The acquisition manager of a zstack
    streams (list of Stream): the streams to be acquired
    zlevels (dict Stream -> list of floats): a dictionary containing the streams and the
    corresponding lists of actuator z positions
    settings_obs (SettingsObserver): VAs to be integrated in the acquired data as metadata
    return (ProgressiveFuture): the future that will be executing the task
    """
    # create future
    future = model.ProgressiveFuture()
    # create acquisition task
    acqui_task = ZStackAcquisitionTask(future, streams, zlevels, settings_obs)
    # add the ability of cancelling the future during execution
    future.task_canceller = acqui_task.cancel

    # set the progress of the future
    total_duration = acqui_task.estimate_total_duration()
    future.set_end_time(time.time() + total_duration)

    # assign the acquisition task to the future
    executeAsyncTask(future, acqui_task.run)

    return future
예제 #29
0
def Sparc2AutoFocus(align_mode, opm, streams=None, start_autofocus=True):

    """
    It provides the ability to check the progress of the complete Sparc2 autofocus
    procedure in a Future or even cancel it.
        Pick the hardware components
        Turn on the light and wait for it to be complete
        Change the optical path (closing the slit)
        Run AutoFocusSpectrometer
        Acquire one last image
        Turn off the light
    align_mode (str): OPM mode, spec-focus or spec-fiber-focus, streak-focus
    opm: OpticalPathManager
    streams: list of streams
    return (ProgressiveFuture -> dict((grating, detector)->focus position)): a progressive future
          which will eventually return a map of grating/detector -> focus position, the same as AutoFocusSpectrometer
    raises:
            CancelledError if cancelled
            LookupError if procedure failed
    """
    focuser = None
    if align_mode in ("spec-focus", "streak-focus"):
        focuser = model.getComponent(role='focus')
    elif align_mode == "spec-fiber-focus":
        # The "right" focuser is the one which affects the same detectors as the fiber-aligner
        aligner = model.getComponent(role='fiber-aligner')
        aligner_affected = aligner.affects.value  # List of component names
        for f in ("spec-ded-focus", "focus"):
            try:
                focus = model.getComponent(role=f)
            except LookupError:
                logging.debug("No focus component %s found", f)
                continue
            focuser_affected = focus.affects.value
            # Does the focus affects _at least_ one component also affected by the fiber-aligner?
            if set(focuser_affected) & set(aligner_affected):
                focuser = focus
                break
    else:
        raise ValueError("Unknown align_mode %s", align_mode)

    if focuser is None:
        raise LookupError("Failed to find the focuser for align mode %s", align_mode)

    if streams is None:
        streams = []

    for s in streams:
        if s.focuser is None:
            logging.debug("Stream %s has no focuser, will assume it's fine", s)
        elif s.focuser != focuser:
            logging.warning("Stream %s has focuser %s, while expected %s", s, s.focuser, focuser)

    # Get all the detectors, spectrograph and selectors affected by the focuser
    try:
        spgr, dets, selector = _getSpectrometerFocusingComponents(focuser)  # type: (object, List[Any], Optional[Any])
    except LookupError as ex:
        # TODO: just run the standard autofocus procedure instead?
        raise LookupError("Failed to focus in mode %s: %s" % (align_mode, ex))

    for s in streams:
        if s.detector.role not in (d.role for d in dets):
            logging.warning("The detector of the stream is not found to be one of the picked detectors %s")

    # Create ProgressiveFuture and update its state to RUNNING
    est_start = time.time() + 0.1

    # Rough approximation of the times of each action:
    # * 5 s to turn on the light
    # * 5 s to close the slit
    # * af_time s for the AutoFocusSpectrometer procedure to be completed
    # * 0.2 s to acquire one last image
    # * 0.1 s to turn off the light
    if start_autofocus:
        # calculate the time needed for the AutoFocusSpectrometer procedure to be completed
        af_time = _totalAutoFocusTime(spgr, dets)
        autofocus_loading_times = (5, 5, af_time, 0.2, 5) # a list with the time that each action needs
    else:
        autofocus_loading_times = (5, 5)

    f = model.ProgressiveFuture(start=est_start, end=est_start + sum(autofocus_loading_times))
    f._autofocus_state = RUNNING
    # Time for each action left
    f._actions_time = list(autofocus_loading_times)
    f.task_canceller = _CancelSparc2AutoFocus
    f._autofocus_lock = threading.Lock()
    f._running_subf = model.InstantaneousFuture()

    # Run in separate thread
    executeAsyncTask(f, _DoSparc2AutoFocus, args=(f, streams, align_mode, opm, dets, spgr, selector, focuser, start_autofocus))
    return f
예제 #30
0
 def _prepare_opm(self):
     # Return a future which calls the OPM _and_ updates the "special" axes
     f = futures.Future()
     executeAsyncTask(f, self._set_optical_path)
     return f
예제 #31
0
파일: la_spec.py 프로젝트: delmic/odemis
 def _prepare_opm(self):
     # Return a future which calls the OPM _and_ updates the "special" axes
     f = futures.Future()
     executeAsyncTask(f, self._set_optical_path)
     return f