Exemple #1
0
 def test_one_center_em(self):
     em_band = (490e-9, 497e-9, 500e-9, 503e-9, 510e-9)
     em_bands = ((650e-9, 660e-9, 675e-9, 678e-9,
                  680e-9), (780e-9, 785e-9, 790e-9, 800e-9, 812e-9),
                 (1034e-9, 1080e-9, 1100e-9, 1200e-9, 1500e-9))
     # Excitation band should be smaller than the emission band used
     in_exp = [
         ((em_band, (490e-9, 510e-9)),
          fluo.get_center(em_band)),  # only one band
         ((em_bands, (490e-9, 497e-9, 500e-9, 503e-9, 510e-9)),
          fluo.get_center(em_bands[0])),  # smallest above 500nm
         ((em_bands, (690e-9, 697e-9, 700e-9, 703e-9, 710e-9)),
          fluo.get_center(em_bands[1])),  # smallest above 700nm
         ((em_bands, (790e-9, 797e-9, 800e-9, 803e-9, 810e-9)),
          fluo.get_center(em_bands[2])),  # smallest above 800nm
         ((em_bands[0:2], (790e-9, 797e-9, 800e-9, 803e-9, 810e-9)),
          fluo.get_center(em_bands[1])),  # biggest
         # Try with a pass-through
         ((em_band, BAND_PASS_THROUGH), 500e-9),
         ((em_bands, BAND_PASS_THROUGH), 1100e-9),  # biggest
         # ((BAND_PASS_THROUGH, (490e-9, 510e-9)), BAND_PASS_THROUGH),
     ]
     for args, exp in in_exp:
         out = fluo.get_one_center_em(*args)
         self.assertEqual(
             exp, out,
             "Failed while running with %s and got %s" % (args, out))
Exemple #2
0
 def test_one_center_ex(self):
     ex_band = (490e-9, 497e-9, 500e-9, 503e-9, 510e-9)
     ex_bands = ((650e-9, 660e-9, 675e-9, 678e-9, 680e-9),
                 (780e-9, 785e-9, 790e-9, 800e-9, 812e-9),
                 (1034e-9, 1080e-9, 1100e-9, 1200e-9, 1500e-9))
     # Excitation band should be smaller than the emission band used
     in_exp = [((ex_band, (490e-9, 510e-9)), fluo.get_center(ex_band)), # only one band
               ((ex_bands, (490e-9, 497e-9, 500e-9, 503e-9, 510e-9)), fluo.get_center(ex_bands[0])), # nothing fitting, but should pick the smallest
               ((ex_bands, (690e-9, 697e-9, 700e-9, 703e-9, 710e-9)), fluo.get_center(ex_bands[0])), # biggest below 700nm
               ((ex_bands, (790e-9, 797e-9, 800e-9, 803e-9, 810e-9)), fluo.get_center(ex_bands[1])), # biggest below 800nm
               ]
     for args, exp in in_exp:
         out = fluo.get_one_center_ex(*args)
         self.assertEqual(exp, out, "Failed while running with %s and got %s" % (args, out))
Exemple #3
0
    def test_center(self):
        in_exp = [
            ((490e-9, 510e-9), 500e-9),  # 2-float band
            ((490e-9, 497e-9, 500e-9, 503e-9, 510e-9), 500e-9),  # 5-float band
            (((490e-9, 510e-9), (820e-9, 900e-9)), (500e-9, 860e-9)
             )  # multi-band
        ]
        for inp, exp in in_exp:
            out = fluo.get_center(inp)
            self.assertEqual(
                exp, out,
                "Failed while running with %s and got %s" % (inp, out))

        # Special case for "pass-through": any number > 0 is fine
        out = fluo.get_center(BAND_PASS_THROUGH)
        self.assertGreaterEqual(out, 0)
Exemple #4
0
 def test_center(self):
     in_exp = [((490e-9, 510e-9), 500e-9), # 2-float band
               ((490e-9, 497e-9, 500e-9, 503e-9, 510e-9), 500e-9), # 5-float band
               (((490e-9, 510e-9), (820e-9, 900e-9)), (500e-9, 860e-9)) # multi-band
               ]
     for inp, exp in in_exp:
         out = fluo.get_center(inp)
         self.assertEqual(exp, out, "Failed while running with %s and got %s" % (inp, out))
Exemple #5
0
def _weight_stream(stream):
    """
    Defines how much a stream is of priority (should be done first) for
      acquisition.
    stream (acq.stream.Stream): a stream to weight
    returns (number): priority (the higher the more it should be done first)
    """
    if isinstance(stream, (FluoStream, ScannedFluoMDStream)):
        # Fluorescence ASAP to avoid bleaching
        if isinstance(stream, ScannedFluoMDStream):
            # Just take one of the streams, to keep things "simple"
            stream = stream.streams[0]

        # If multiple fluorescence acquisitions: prefer the long emission
        # wavelengths first because there is no chance their emission light
        # affects the other dyes (and which could lead to a little bit of
        # bleaching).
        ewl_center = fluo.get_center(stream.emission.value)
        if isinstance(ewl_center, collections.Iterable):
            # multi-band filter, so fallback to guess based on excitation
            xwl_center = fluo.get_center(stream.excitation.value)
            if isinstance(ewl_center, collections.Iterable):
                # also unguessable => just pick one "randomly"
                ewl_bonus = ewl_center[0]
            else:
                ewl_bonus = xwl_center + 50e-6  # add 50nm as guesstimate for emission
        else:
            ewl_bonus = ewl_center  # normally, between 0 and 1
        return 100 + ewl_bonus
    elif isinstance(stream, OpticalStream):
        return 90  # any other kind of optical after fluorescence
    elif isinstance(stream, ScannedRemoteTCStream):
        return 85  # Stream for FLIM acquisition with time correlator
    elif isinstance(stream, EMStream):
        return 50  # can be done after any light
    elif isinstance(stream,
                    (SEMCCDMDStream, SEMMDStream, SEMTemporalMDStream)):
        return 40  # after standard (=survey) SEM
    elif isinstance(stream, OverlayStream):
        return 10  # after everything (especially after SEM and optical)
    else:
        logging.debug("Unexpected stream of type %s",
                      stream.__class__.__name__)
        return 0
Exemple #6
0
 def test_center(self):
     in_exp = [
         ((490e-9, 510e-9), 500e-9),  # 2-float band
         ((490e-9, 497e-9, 500e-9, 503e-9, 510e-9), 500e-9),  # 5-float band
         (((490e-9, 510e-9), (820e-9, 900e-9)), (500e-9, 860e-9)
          )  # multi-band
     ]
     for inp, exp in in_exp:
         out = fluo.get_center(inp)
         self.assertEqual(
             exp, out,
             "Failed while running with %s and got %s" % (inp, out))
Exemple #7
0
 def test_one_center_ex(self):
     ex_band = (490e-9, 497e-9, 500e-9, 503e-9, 510e-9)
     ex_bands = ((650e-9, 660e-9, 675e-9, 678e-9,
                  680e-9), (780e-9, 785e-9, 790e-9, 800e-9, 812e-9),
                 (1034e-9, 1080e-9, 1100e-9, 1200e-9, 1500e-9))
     # Excitation band should be smaller than the emission band used
     in_exp = [
         ((ex_band, (490e-9, 510e-9)),
          fluo.get_center(ex_band)),  # only one band
         ((ex_bands, (490e-9, 497e-9, 500e-9, 503e-9, 510e-9)),
          fluo.get_center(ex_bands[0])
          ),  # nothing fitting, but should pick the smallest
         ((ex_bands, (690e-9, 697e-9, 700e-9, 703e-9, 710e-9)),
          fluo.get_center(ex_bands[0])),  # biggest below 700nm
         ((ex_bands, (790e-9, 797e-9, 800e-9, 803e-9, 810e-9)),
          fluo.get_center(ex_bands[1])),  # biggest below 800nm
     ]
     for args, exp in in_exp:
         out = fluo.get_one_center_ex(*args)
         self.assertEqual(
             exp, out,
             "Failed while running with %s and got %s" % (args, out))
Exemple #8
0
def _weight_stream(stream):
    """
    Defines how much a stream is of priority (should be done first) for
      acquisition.
    stream (acq.stream.Stream): a stream to weight
    returns (number): priority (the higher the more it should be done first)
    """
    if isinstance(stream, FluoStream):
        # Fluorescence ASAP to avoid bleaching
        # If multiple fluorescence acquisitions: prefer the long emission
        # wavelengths first because there is no chance their emission light
        # affects the other dyes (and which could lead to a little bit of
        # bleaching).
        ewl_center = fluo.get_center(stream.emission.value)
        if isinstance(ewl_center, collections.Iterable):
            # multi-band filter, so fallback to guess based on excitation
            xwl_center = fluo.get_center(stream.excitation.value)
            if isinstance(ewl_center, collections.Iterable):
                # also unguessable => just pick one "randomly"
                ewl_bonus = ewl_center[0]
            else:
                ewl_bonus = xwl_center + 50e-6 # add 50nm as guesstimate for emission
        else:
            ewl_bonus = ewl_center # normally, between 0 and 1
        return 100 + ewl_bonus
    elif isinstance(stream, OpticalStream):
        return 90 # any other kind of optical after fluorescence
    elif isinstance(stream, EMStream):
        return 50 # can be done after any light
    elif isinstance(stream, (SEMCCDMDStream, SEMMDStream)):
        return 40 # after standard (=survey) SEM
    elif isinstance(stream, OverlayStream):
        return 10 # after everything (especially after SEM and optical)
    else:
        logging.debug("Unexpected stream of type %s", stream.__class__.__name__)
        return 0
Exemple #9
0
    def __init__(self, name, detector, dataflow, emitter, em_filter):
        """
        name (string): user-friendly name of this stream
        detector (Detector): the detector which has the dataflow
        dataflow (Dataflow): the dataflow from which to get the data
        emitter (Light): the HwComponent to modify the light excitation
        filter (Filter): the HwComponent to modify the emission light filtering
        """
        CameraStream.__init__(self, name, detector, dataflow, emitter)
        self._em_filter = em_filter

        # Emission and excitation are based on the hardware capacities.
        # For excitation, compared to the hardware, only one band at a time can
        # be selected. The difficulty comes to pick the default value. The best
        # would be to use the current hardware value, but if the light is off
        # there is no default value. In that case, we pick the emission value
        # and try to pick a compatible excitation value: the first excitation
        # wavelength below the emission. However, the emission value might also
        # be difficult to know if there is a multi-band filter. In that case we
        # just pick the lowest value.
        # TODO: once the streams have their own version of the hardware settings
        # and in particular light.power, it should be possible to turn off the
        # light just by stopping the power, and so leaving the emissions as is.

        em_choices = em_filter.axes["band"].choices.copy()
        # convert any list into tuple, as lists cannot be put in a set
        for k, v in em_choices.items():
            em_choices[k] = conversion.ensureTuple(v)

        # invert the dict, to directly convert the emission to the position value
        self._emission_to_idx = dict((v, k) for k, v in em_choices.items())

        cur_pos = em_filter.position.value["band"]
        current_em = em_choices[cur_pos]
        if isinstance(current_em[0], collections.Iterable):
            # if multiband => pick the first one
            em_band = current_em[0]
        else:
            em_band = current_em
        center_em = fluo.get_center(em_band)

        exc_choices = set(emitter.spectra.value)
        current_exc = self._get_current_excitation()
        if current_exc is None:
            # pick the closest below the current emission
            current_exc = min(exc_choices, key=lambda b: b[2]) # default to the smallest
            for b in exc_choices:
                # Works because exc_choices only contains 5-float tuples
                if (b[2] < center_em and
                    center_em - b[2] < center_em - current_exc[2]):
                    current_exc = b
            logging.debug("Guessed excitation is %s, based on emission %s",
                          current_exc, current_em)

        self.excitation = model.VAEnumerated(current_exc, choices=exc_choices,
                                             unit="m")
        self.excitation.subscribe(self.onExcitation)

        # The wavelength band on the out path (set when emission changes)
        self.emission = model.VAEnumerated(current_em, choices=set(em_choices.values()),
                                           unit="m")
        self.emission.subscribe(self.onEmission)

        # colouration of the image
        default_tint = conversion.wave2rgb(center_em)
        self.tint = model.ListVA(default_tint, unit="RGB") # 3-tuple R,G,B
        self.tint.subscribe(self.onTint)
Exemple #10
0
    def __init__(self, name, detector, dataflow, emitter, em_filter, **kwargs):
        """
        name (string): user-friendly name of this stream
        detector (Detector): the detector which has the dataflow
        dataflow (Dataflow): the dataflow from which to get the data
        emitter (Light): the HwComponent to modify the light excitation
        em_filter (Filter): the HwComponent to modify the emission light filtering
        """
        super(FluoStream, self).__init__(name, detector, dataflow, emitter, **kwargs)
        self._em_filter = em_filter

        # Emission and excitation are based on the hardware capacities.
        # For excitation, compared to the hardware, only one band at a time can
        # be selected. The difficulty comes to pick the default value. The best
        # would be to use the current hardware value, but if the light is off
        # there is no default value. In that case, we pick the emission value
        # and try to pick a compatible excitation value: the first excitation
        # wavelength below the emission. However, the emission value might also
        # be difficult to know if there is a multi-band filter. In that case we
        # just pick the lowest value.
        # TODO: once the streams have their own version of the hardware settings
        # and in particular light.power, it should be possible to turn off the
        # light just by stopping the power, and so leaving the emissions as is.

        em_choices = em_filter.axes["band"].choices.copy()
        # convert any list into tuple, as lists cannot be put in a set
        for k, v in em_choices.items():
            em_choices[k] = conversion.ensure_tuple(v)

        # invert the dict, to directly convert the emission to the position value
        self._emission_to_idx = {v: k for k, v in em_choices.items()}

        cur_pos = em_filter.position.value["band"]
        current_em = em_choices[cur_pos]
        if isinstance(current_em[0], collections.Iterable):
            # if multiband => pick the first one
            em_band = current_em[0]
        else:
            em_band = current_em
        center_em = fluo.get_center(em_band)

        exc_choices = set(emitter.spectra.value)
        current_exc = self._get_current_excitation()
        if current_exc is None:
            # pick the closest below the current emission
            current_exc = min(exc_choices, key=lambda b: b[2])  # default to the smallest
            for b in exc_choices:
                # Works because exc_choices only contains 5-float tuples
                if (b[2] < center_em and
                    center_em - b[2] < center_em - current_exc[2]):
                    current_exc = b
            logging.debug("Guessed excitation is %s, based on emission %s",
                          current_exc, current_em)

        self.excitation = model.VAEnumerated(current_exc, choices=exc_choices,
                                             unit="m")
        self.excitation.subscribe(self.onExcitation)

        # The wavelength band on the out path (set when emission changes)
        self.emission = model.VAEnumerated(current_em, choices=set(em_choices.values()),
                                           unit="m")
        self.emission.subscribe(self.onEmission)

        # colouration of the image
        self.tint.value = conversion.wave2rgb(center_em)