Tutorial about fluopy - three state simulation

Here we outline a simulation procedure for an ideal three state system.

from pprint import pprint

%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np

import fluopy
import fluopy.analysis as an
import fluopy.blinking as bl
import fluopy.emissions as em
import fluopy.fcs as fcs_p
import fluopy.figure as fi
import fluopy.fluorophores as fl
import fluopy.formulas as fo
import fluopy.miscellaneous as mi
import fluopy.prediction as pr
import fluopy.simulation as si
import fluopy.transitions as tr
fluopy.__version__
'0.4.0.dev4+gc3c2cb30d'
rng = np.random.default_rng(seed=1)

Set up the photophysical system

Set up a single fluorophore representing a three state system (tss).

Define the transitions

transitions = {
    "tss": [
        tr.Transition(tr.TransitionType.EXCITATION, rate=1e9, fluorophore_ids=[0]),
        tr.Transition(
            tr.TransitionType.FLUORESCENT_EMISSION, rate=1e9, fluorophore_ids=[0]
        ),
        tr.Transition(
            tr.TransitionType.INTERSYSTEM_CROSSING_ST, rate=1e6, fluorophore_ids=[0]
        ),
        tr.Transition(
            tr.TransitionType.S1_S0_TRANSITIONS, rate=1e9, fluorophore_ids=[0]
        ),
        tr.Transition(
            tr.TransitionType.T1_S0_TRANSITIONS, rate=1e6, fluorophore_ids=[0]
        ),
    ]
}
pprint(transitions)
{'tss': [Transition(identity=None,
                    transition_type=<TransitionType.EXCITATION: TransitionAttributes(abbreviation='EXC', initial_state=<SingleState.S0: 0>, final_state=<SingleState.S1: 1>, photon=False)>,
                    abbreviation='EXC',
                    initial_state=<SingleState.S0: 0>,
                    final_state=<SingleState.S1: 1>,
                    rate=1000000000.0,
                    photon=False,
                    fluorophore_ids=[0]),
         Transition(identity=None,
                    transition_type=<TransitionType.FLUORESCENT_EMISSION: TransitionAttributes(abbreviation='FLU', initial_state=<SingleState.S1: 1>, final_state=<SingleState.S0: 0>, photon=True)>,
                    abbreviation='FLU',
                    initial_state=<SingleState.S1: 1>,
                    final_state=<SingleState.S0: 0>,
                    rate=1000000000.0,
                    photon=True,
                    fluorophore_ids=[0]),
         Transition(identity=None,
                    transition_type=<TransitionType.INTERSYSTEM_CROSSING_ST: TransitionAttributes(abbreviation='ISC_ST', initial_state=<SingleState.S1: 1>, final_state=<SingleState.T1: 3>, photon=False)>,
                    abbreviation='ISC_ST',
                    initial_state=<SingleState.S1: 1>,
                    final_state=<SingleState.T1: 3>,
                    rate=1000000.0,
                    photon=False,
                    fluorophore_ids=[0]),
         Transition(identity=None,
                    transition_type=<TransitionType.S1_S0_TRANSITIONS: TransitionAttributes(abbreviation='S1S0SUM', initial_state=<SingleState.S1: 1>, final_state=<SingleState.S0: 0>, photon=False)>,
                    abbreviation='S1S0SUM',
                    initial_state=<SingleState.S1: 1>,
                    final_state=<SingleState.S0: 0>,
                    rate=1000000000.0,
                    photon=False,
                    fluorophore_ids=[0]),
         Transition(identity=None,
                    transition_type=<TransitionType.T1_S0_TRANSITIONS: TransitionAttributes(abbreviation='T1S0SUM', initial_state=<SingleState.T1: 3>, final_state=<SingleState.S0: 0>, photon=False)>,
                    abbreviation='T1S0SUM',
                    initial_state=<SingleState.T1: 3>,
                    final_state=<SingleState.S0: 0>,
                    rate=1000000.0,
                    photon=False,
                    fluorophore_ids=[0])]}

Define the fluorophore system

fluorophore = fl.Fluorophore(name="tss", position=[0, 0])
fluorophore_system = fl.FluorophoreSystem(fluorophores=[fluorophore])
There is no FluorophoreData for Fluorophore tss in fluopy.fluo_data. Parameters have to be defined manually.
pprint(vars(fluorophore_system))
{'count': 1,
 'distances': {},
 'fluorophores': [Fluorophore(identity=0,
                              name='tss',
                              position=array([0, 0]),
                              constants=None)],
 'multi_type': False}

Alternatively: define the fluorophore system with FluorophoreData

fluorophore_data_tss = fluopy.fluo_data.FluorophoreData(
    QUANTUM_YIELD=1,
    FLUORESCENCE_LIFETIME=2e-9,
    S1_QUENCH_RATE=1e9,
    ISC_ST_RATE=1e6,
    ISC_TS_RATE=1e6,
    PHOTOBLEACH_T1_RATE=10,
)
pprint(fluorophore_data_tss)
FluorophoreData(data_files=None,
                QUANTUM_YIELD=1,
                FLUORESCENCE_LIFETIME=2e-09,
                S1_QUENCH_RATE=1000000000.0,
                ISC_ST_RATE=1000000.0,
                ISC_TS_RATE=1000000.0,
                RISC_RATE=0,
                STA_EFFICIENCY=0,
                PHOTOBLEACH_T1_RATE=10,
                PHOTOBLEACH_T2_RATE=0,
                DSTORM_PET_T_RATE_MOL=0,
                DSTORM_PET_S_RATE_MOL=0,
                DSTORM_PET_SUCCESS_RATE=0,
                DSTORM_TH_EL_RATE_1=0,
                DSTORM_TH_EL_RATE_2=0,
                DSTORM_P_EL_CROSS_SECTION=0,
                RAD_ESCAPE_EFFICIENCY=0,
                RAD_RELAX_RATE=0,
                OFRET_EFFICIENCY=0,
                ISO_RATE=0,
                BISO_CROSS_SECTION=0,
                BISO_THERMAL_RATE=0,
                BISO_EFFICIENCY=0,
                H2O_ATTACK_S=0,
                H2O_ATTACK_T=0,
                BACK_REACTION=0)
fluorophore_tss = fl.Fluorophore(
    name="tss", position=[0, 0], constants=fluorophore_data_tss
)
fluorophore_system_tss = fl.FluorophoreSystem(fluorophores=[fluorophore_tss])
pprint(vars(fluorophore_system_tss))
{'count': 1,
 'distances': {},
 'fluorophores': [Fluorophore(identity=0,
                              name='tss',
                              position=array([0, 0]),
                              constants=FluorophoreData(data_files=None,
                                                        QUANTUM_YIELD=1,
                                                        FLUORESCENCE_LIFETIME=2e-09,
                                                        S1_QUENCH_RATE=1000000000.0,
                                                        ISC_ST_RATE=1000000.0,
                                                        ISC_TS_RATE=1000000.0,
                                                        RISC_RATE=0,
                                                        STA_EFFICIENCY=0,
                                                        PHOTOBLEACH_T1_RATE=10,
                                                        PHOTOBLEACH_T2_RATE=0,
                                                        DSTORM_PET_T_RATE_MOL=0,
                                                        DSTORM_PET_S_RATE_MOL=0,
                                                        DSTORM_PET_SUCCESS_RATE=0,
                                                        DSTORM_TH_EL_RATE_1=0,
                                                        DSTORM_TH_EL_RATE_2=0,
                                                        DSTORM_P_EL_CROSS_SECTION=0,
                                                        RAD_ESCAPE_EFFICIENCY=0,
                                                        RAD_RELAX_RATE=0,
                                                        OFRET_EFFICIENCY=0,
                                                        ISO_RATE=0,
                                                        BISO_CROSS_SECTION=0,
                                                        BISO_THERMAL_RATE=0,
                                                        BISO_EFFICIENCY=0,
                                                        H2O_ATTACK_S=0,
                                                        H2O_ATTACK_T=0,
                                                        BACK_REACTION=0))],
 'multi_type': False}

THIS IS NOT YET WORKING.

Define the transition set

transition_set = tr.TransitionSet(transitions, fluorophore_system)
transition_set.finalize()
<fluopy.transitions.TransitionSet at 0x7a7b242463c0>
transition_set.plot(graph_type="shell", colors=None, scale=1);
../../_images/d5755163a32cbb4d2318d8af2165e01d928272d17facc2ecb654fe09aa2823bd.png
transition_set.transition_df
transition_type abbreviation initial_state final_state rate photon fluorophore_ids absorbing
Fluorophore identity
tss 0 TransitionType.EXCITATION EXC SingleState.S0 SingleState.S1 1.000000e+09 False [0] False
1 TransitionType.FLUORESCENT_EMISSION FLU SingleState.S1 SingleState.S0 1.000000e+09 True [0] False
2 TransitionType.INTERSYSTEM_CROSSING_ST ISC_ST SingleState.S1 SingleState.T1 1.000000e+06 False [0] False
3 TransitionType.S1_S0_TRANSITIONS S1S0SUM SingleState.S1 SingleState.S0 1.000000e+09 False [0] False
4 TransitionType.T1_S0_TRANSITIONS T1S0SUM SingleState.T1 SingleState.S0 1.000000e+06 False [0] False

Make a prediction

%%time
prediction = pr.Prediction(transition_set)
prediction
CPU times: user 5.69 ms, sys: 0 ns, total: 5.69 ms
Wall time: 5.54 ms
<fluopy.prediction.Prediction at 0x7a7b2428e3c0>
prediction.plot_frequency_transitions(scale=0.5)
prediction.plot_frequency_states(scale=0.5)
prediction.plot_mean_lifetimes(scale=0.5)
prediction.plot_mean_transition_times(scale=0.5)
prediction.plot_state_occupations(scale=0.5)
prediction.plot_transition_time_distributions(
    fluorophore="tss", transition_id=0, scale=0.5
);
../../_images/144621f86359ba1b4b1d26e470d75c7764be06f5cf24f10dcde80709d6c5f705.png ../../_images/ce90a6caa8c5eed69989eebaa4b8a9e0637a0b7ba9a829f4305c5388b83b73c1.png ../../_images/1f570b2457d1c2a1e290dba46baabd13e278415cd06ce333b6b8a00ef040ab98.png ../../_images/48d7b20913175f3aeb81e65b1b788c95ac411dd0384a69d84e42834178dccde6.png ../../_images/c0a8d5f74fa066c7ffbfe5fb5c9f0272858e73c8c70863705587b5b4792c6839.png ../../_images/c42b4c46103e68f631e5b68402f051d2cbc6805f73846c170c6d3ae2991ec746.png

Run a simulation

simulation = si.Simulation(transition_set)
simulation
<fluopy.simulation.Simulation at 0x7a7b24247cb0>
%%time
# simulate until it reaches given end_time
simulation.run(start_at=None, size=1e6, end_time=1e-2, seed=rng, use_memmap=None)
mi.print_class(simulation)
Floating point precision error warning:
 The smallest safe increment is 1.73e-18.
 Everything drawn below this number might be rounded to zero
 when approaching the time limit of this simulation.
 Using the highest possible rate which occurs for example in state combination [1]
 gives a probability of 3.47e-09 for a smaller increment to be drawn.
Attributes of <fluopy.simulation.Simulation object at 0x7a7b24247cb0>:
.................................................................
transition_set = <fluopy.transitions.TransitionSet object at 0x7a7b242463c0>
_________________________________________________________________
time_series = array([0.00000000e+00, 6.69779104e-10, 1.6377122...99999900e-03, 1.00000000e-02], shape=(10120486,))
_________________________________________________________________
transition_series = array([0, 3, 0, ..., 1, 0, 1], shape=(10120484,), dtype=uint32)
_________________________________________________________________
state_series = array([[0, 1, 0, ..., 0, 1, 0]], shape=(1, 10120485), dtype=int8)
_________________________________________________________________
memmap_path = None
_________________________________________________________________


CPU times: user 30 s, sys: 98.4 ms, total: 30.1 s
Wall time: 30.1 s

Analyze the simulation

analysis = an.Analysis(simulation=simulation)
mi.print_class(analysis)
Attributes of <fluopy.analysis.Analysis object at 0x7a7b24247770>:
.................................................................
simulation = <fluopy.simulation.Simulation object at 0x7a7b24247cb0>
_________________________________________________________________
frequency_transitions = array([4.99877674e-01, 2.49882812e-01, 2.44652331e-04, 2.49750210e-01,
       2.44652331e-04])
_________________________________________________________________
frequency_states = {'tss': array([4.99877723e-01, 4.99877624e-01, 2.44652307e-04])}
_________________________________________________________________
transition_time_distributions = [array([6.69779104e-10, 1.16529246e-09, 5.9857602....80394562e-10, 1.09146311e-09], shape=(5059004,)), array([9.45034359e-11, 5.96391644e-10, 7.9575674....05701042e-09, 3.83651617e-10], shape=(2528935,)), array([2.39036925e-11, 3.90133768e-10, 1.1099050..., 1.57139638e-10, 2.02107909e-09], shape=(2476,)), array([9.67933119e-10, 1.41433715e-10, 3.6142563....36835611e-11, 1.36722600e-10], shape=(2527593,)), array([1.04524663e-06, 9.16961503e-07, 1.7313478..., 8.44535999e-07, 3.27647341e-06], shape=(2476,))]
_________________________________________________________________
lifetime_distributions = {'tss': [array([6.69779104e-10, 1.16529246e-09, 5.9857602....80394562e-10, 1.09146311e-09], shape=(5059004,)), array([9.67933119e-10, 9.45034359e-11, 1.4143371....05701042e-09, 3.83651617e-10], shape=(5059004,)), array([1.04524663e-06, 9.16961503e-07, 1.7313478..., 8.44535999e-07, 3.27647341e-06], shape=(2476,))]}
_________________________________________________________________
mean_transition_times = array([1.00051767e-09, 4.99896950e-10, 4.81919815e-10, 4.99877741e-10,
       9.73137520e-07])
_________________________________________________________________
mean_lifetimes = {'tss': array([1.00051767e-09, 4.99878554e-10, 9.73137520e-07])}
_________________________________________________________________
state_occupations = {'tss': array([0.50616239, 0.25288876, 0.24094885])}
_________________________________________________________________
analysis.get_fluorescence_lifetimes(fluorophore="tss")
analysis.get_emitting_transition_lifetimes(fluorophore="tss")

analysis.plot_frequency_transitions(scale=0.5, prediction=prediction)
analysis.plot_frequency_states(scale=0.5, prediction=prediction)
analysis.plot_mean_transition_times(scale=0.5, prediction=prediction)
analysis.plot_mean_lifetimes(scale=0.5, prediction=prediction)
analysis.plot_state_occupations(scale=0.5, prediction=prediction)
analysis.plot_lifetime_distributions(
    scale=0.5, prediction=prediction, fluorophore="tss", state_identity=1
)
analysis.plot_transition_time_distributions(
    scale=0.5, prediction=prediction, fluorophore="tss", transition_id=0
);
../../_images/8ede75ee59e302a2b6c0f01e2c5e965c77922ebe97bd349d90c45b67e70bbca0.png ../../_images/d129ad68eee72dc14798b684976a36703024ab5fe94486dd86c197338f6a9633.png ../../_images/6887114ce58f9991311302e2f4419eaa82427a3d7feaf52c893465b6116e41f7.png ../../_images/4540c9db11c685208ededf8d9d0e6177763f6174072ae3b449daeac86c198265.png ../../_images/2f14363a91240eef9dc0cf8c5590d3ff33f16a4359089ba867c191e685924891.png ../../_images/42d983efe4156b5b2f037ee98fd070dcc40130919101cf8f51bc9526d0b3d357.png ../../_images/d619cd88885d79e3768dba921451eeec2d64e0486c072eefb0268d0b1b128846.png

Simulation of experimentally observable (photons per frames) only

Extract photon emission events from simulation

%%time
emissions = em.Emissions(frame_time="1us", seed=rng)
emissions.extract(simulation=simulation)
emissions
CPU times: user 752 ms, sys: 12 ms, total: 764 ms
Wall time: 762 ms
<fluopy.emissions.Emissions at 0x7a7b24246e40>

Simulate photon emission events

Correct for detection efficiency and noise contributions:

emissions.add_photon_collection_objective(p=0.1, seed=rng)  # 1.
emissions.add_quantum_efficiency(p=0.9, seed=rng)  # 3.1.
emissions.add_poisson_noise(
    rate=0.05, seed=rng
)  # 3.2. (dark noise), note the frame time
emissions.add_emccd_gain(emccd_gain=10, seed=rng)  # 4.
emissions.add_gaussian_noise(mean=10, std=1, seed=rng)  # 5. (readout noise)
emissions
<fluopy.emissions.Emissions at 0x7a7b24246e40>

emissions = em.Emissions(frame_time=”5ms”, seed=rng, bandpass=(660, 700)) emissions.extract(simulation=approximation)

# 2.
# at this point, the bandpass filter was applied
# yet, the effect of photon collection by the objective is missing
# the order is not relevant for two consecutive binomial distributions
# it is more convenient to apply the bandpass first because it needs the
# information about the emitting fluorophore whereas all the other effects are
# roughly wavelength independent
p_photon_collection = fo.calculate_photon_collection_rate(NA=1.45, n1=1.51)
emissions.add_photon_collection_objective(p=p_photon_collection)  # 1.
emissions.add_quantum_efficiency(p=0.9)  # 4.1.
emissions.add_transmittance(p=0.99)  # 3 (depending on number of components of optical
# path, may be applied multiple times)
emissions.add_poisson_noise(rate=0.05)  # 4.2. (dark noise), note the frame time
emissions.add_emccd_gain(emccd_gain=10)  # 5. (+ multiplicative noise)
emissions.add_gaussian_noise(mean=10, std=1, seed=rng)  # 6. (readout noise)
# CIC (spurious noise) neglected since low probability to happen in the pixels of
# interest
emissions.apply_threshold(threshold=100)  # 7 (thresholding)
emissions.plot_cumulative_events(scale=1)
emissions.plot_histogram(scale=1)
emissions.plot_time_series(scale=1)

# to save the time_series and time_points
# emissions.save(path='', name_extension='test')

# to load time_series and time_points
# emissions.load(path='', name_extension='test')
array([[<Axes: xlabel='Time (s)', ylabel='$\\frac{photons}{frame}$'>]],
      dtype=object)
../../_images/f1c89619178c008add26c27ae2b16fffa06cc5f825845b318a0665a954ce577b.png ../../_images/4146eb1837083cbd0f3c199187b227db6c9ab0d18bf2f1b8c9dcc4614d873988.png ../../_images/03a46631df94387d3284e5c0be606209c7f61d79abd60bfb69b7d6a467cd7577.png

Simulation of pulsed excitation

%%time
emissions_tcspc = em.Emissions(frame_time="10us", seed=rng, bandpass=None)
lifetimes_DA, lifetimes_D, lifetimes_all, simulation_object = emissions_tcspc.tcspc(
    transition_set=transition_set,
    number_pulses=1e5,
    pulse_duration=1e-11,
    time_between_pulses=1e-7,
    excitation_rates={"tss": 1e11},
    size=1e5,
    store_time_points=True,
    # details = True
)
the last frame (of index 0.01) has 1.00e+00 times the pulses of other frames.
CPU times: user 18.9 s, sys: 282 ms, total: 19.2 s
Wall time: 18.9 s
emissions_tcspc.plot_time_series()
fi.universal_figure(
    type_="hist", data=lifetimes_all, ylabel="PD", density=True, xlabel="Lifetime (s)"
)
array([[<Axes: xlabel='Lifetime (s)', ylabel='PD'>]], dtype=object)
../../_images/720ac40c40867da14c27fbeec17f95feab4035d3a6c6fa3303c84855114c6030.png ../../_images/f66d9b4c1f0d0f1df2922a8dab037978af7ce8d75d8ab07794cd01e64737fdbb.png

Fluorescence correlation spectroscopy

Observed fluorescence emission events can be analyzed by a correlation analysis.

fcs = fcs_p.FCS(emissions)
list(vars(fcs).keys())
['emissions', 'autocorrelation', 'tau']

Autocorrelation of time points

%%time
fcs.autocorrelate_time_points(
    exp_min=-20, exp_max=-2, points_per_base=4, base=4, normalize=True
)
The exp_max -2 yields a base to the power of exp_max 0.0625 that is larger than the last time point 0.009999998997343471. Therefore, exp_max is adjusted to -4.
CPU times: user 4.82 s, sys: 342 ms, total: 5.16 s
Wall time: 5.16 s
<fluopy.fcs.FCS at 0x7a7b24247380>
mi.print_class(fcs)
fcs.plot(normalize_to=None, unit="s", scale=1);
Attributes of <fluopy.fcs.FCS object at 0x7a7b24247380>:
.................................................................
emissions = <fluopy.emissions.Emissions object at 0x7a7b24246e40>
_________________________________________________________________
autocorrelation = array([0.        , 0.00586969, 0.008301  , 0.014... 1.02426268, 1.03786409, 1.05680552, 1.0876308 ])
_________________________________________________________________
tau = array([1.09785722e-12, 1.55260457e-12, 2.1957144... 1.66709647e-03, 2.35763043e-03, 3.33419293e-03])
_________________________________________________________________
../../_images/16fc230779f6b3fe3c854f33773e1b8c6b4d71df148bceb98911791abb0ef131.png

Autocorrelation of time series

fcs.autocorrelate_time_series(log=True, m=4, normalize=True)
<fluopy.fcs.FCS at 0x7a7b24247380>
fcs.plot(normalize_to=None, unit="s", scale=1);
../../_images/598a65ea5ecfc8dc9362a869201fd48c9e800d648ea6fabd8e8be5e6c3a91cff.png

Antibunching

Alternatively, you can focus on fast time scales in a linear scale and observe antibunching.

# sensible to tau_max and bin_width, see coincidence notebook
hist, bins = fcs_p.coincidence(
    emissions.event_time_points[: int(2e5)], tau_max=1e-8, bin_width=1e-10, seed=rng
)
fi.universal_figure(
    type_="line",
    data=[bins, hist],
    xlabel=r"$\tau$ (s)",
    ylabel=r"$g^{(2)}(\tau)$",
    scale=1,
);
../../_images/d40ef10d516e3d83d1a659d77bc31826914b1051eb8a15d705b2d5447ac3ae0a.png

Blinking

Emissions from a short simulation

%%time
emissions = em.Emissions(frame_time="200ns", seed=rng, bandpass=None)
emissions.simulate(transition_set=transition_set, store_time_points=False, frames=2000)
emissions
CPU times: user 2.7 s, sys: 2.93 ms, total: 2.7 s
Wall time: 2.7 s
<fluopy.emissions.Emissions at 0x7a7b21fc6990>
threshold: int = 40
emissions.plot_time_series(scale=1)
plt.hlines(threshold, xmin=0, xmax=0.0004)
<matplotlib.collections.LineCollection at 0x7a7b21202e40>
../../_images/9c363f4498f391d9bac79fb0a378104f8b42393299339e3aa3e58da00294c177.png
blinks = bl.Blinking(emissions, threshold=threshold)
blinks
<fluopy.blinking.Blinking at 0x7a7b21263b60>
mi.print_class(blinks)
Attributes of <fluopy.blinking.Blinking object at 0x7a7b21263b60>:
.................................................................
emissions = <fluopy.emissions.Emissions object at 0x7a7b21fc6990>
_________________________________________________________________
on_periods = array([19,  2, 26,  5, 23, 12, 18, 68, 22, 12, 1... 23,  4,  2, 13,  9,  2,  6, 34, 18,  1,  9, 15])
_________________________________________________________________
off_periods = array([11,  9, 31,  6,  1,  3,  1,  2,  3,  4,  ...  4,  7, 11,  2,  1,  8,  9, 13,  7,  1,  7,  1])
_________________________________________________________________
on_periods_frames = array([   1,   31,   42,   99,  110,  134,  149,...1869,
       1879, 1894, 1941, 1966, 1968, 1984])
_________________________________________________________________
off_periods_frames = array([  20,   33,   68,  104,  133,  146,  167,...1871,
       1885, 1928, 1959, 1967, 1977, 1999])
_________________________________________________________________
# plot a histogram of OFF times
blinks.plot(
    mode="off_histogram", density=True, display_mean=True, as_time="s", scale=0.5
)

# plot a histogram of ON times
blinks.plot(
    mode="on_histogram", density=True, display_mean=True, as_time="ms", scale=0.5
)

# plot a time series of OFF times
blinks.plot(mode="off_frame_series", scale=0.5)

# plot a time series of ON times
blinks.plot(mode="on_frame_series", scale=0.5)
array([[<Axes: xlabel='identity', ylabel='consecutive ON frames'>]],
      dtype=object)
../../_images/cb9063bd90553315a27fa539759e69a8d2d00e3fcb4a00e0e38bfa3abaa766e7.png ../../_images/66abf363ef70b0d1d1151a6da352537f86443f2472171aed592f09fb6a1054a0.png ../../_images/300f00dd97fae49a582440cfb192689eda7f7be431946b87a1011d48e5d6bf7f.png ../../_images/49b0d0778df7ed194ccdb27984ef5dfb64ef74b55e317108b34f55c6a5092c8b.png
# to get the analytical OFF statistics as the same view, use
on_off_times_analytic, on_off_values_analytic = bl.get_analytical_off_statistics(
    off_frames=blinks.off_periods_frames,
    off_periods=blinks.off_periods,
    on_frames=blinks.on_periods_frames,
    frame_time=blinks.emissions.parameters["frame_time"],
)

# plot the analytical OFF statistics (no differentiation between fluorophores)
bl.plot_off_statistics(
    on_off_times_analytic, on_off_values_analytic, scale=1, title="analytical OFF"
);
../../_images/7b5bbc95be8d7b2904e55eada225056f7bb9f246d12cb4c0b320a4b15f7d3411.png

Emissions from the long simulation

Get more detailed information from a complete simulation:

%%time
emissions = em.Emissions(frame_time="200ns", seed=rng, bandpass=None)
emissions.extract(simulation=simulation)
emissions
CPU times: user 747 ms, sys: 22 ms, total: 769 ms
Wall time: 769 ms
<fluopy.emissions.Emissions at 0x7a7b20928770>
blinks = bl.Blinking(emissions, threshold=threshold)
blinks
<fluopy.blinking.Blinking at 0x7a7b20760190>
mi.print_class(blinks)
Attributes of <fluopy.blinking.Blinking object at 0x7a7b20760190>:
.................................................................
emissions = <fluopy.emissions.Emissions object at 0x7a7b20928770>
_________________________________________________________________
on_periods = array([ 8,  8, 12, ..., 22, 12, 58], shape=(2152,))
_________________________________________________________________
off_periods = array([ 6,  5,  9, ..., 11,  5, 17], shape=(2152,))
_________________________________________________________________
on_periods_frames = array([    1,    15,    28, ..., 49864, 49897, 49914], shape=(2152,))
_________________________________________________________________
off_periods_frames = array([    9,    23,    40, ..., 49886, 49909, 49972], shape=(2152,))
_________________________________________________________________
# plot a histogram of OFF times
blinks.plot(
    mode="off_histogram", density=True, display_mean=True, as_time="s", scale=0.5
)

# plot a histogram of ON times
blinks.plot(
    mode="on_histogram", density=True, display_mean=True, as_time="ms", scale=0.5
)

# plot a time series of OFF times
blinks.plot(mode="off_frame_series", scale=0.5)

# plot a time series of ON times
blinks.plot(mode="on_frame_series", scale=0.5)
array([[<Axes: xlabel='identity', ylabel='consecutive ON frames'>]],
      dtype=object)
../../_images/edd704ede6802721eaca927c3c3244b4dc0254d14352151f024b268474efb90c.png ../../_images/61053a2c88f13d9e31c632566d1c29107438a3e9e7dab1e90d6b505fec7c64b4.png ../../_images/4bf89bf7ad2e0a22c38d2a73e688ad14eddb3544cd9a7ccf0b055d246249d90d.png ../../_images/ebf6ca3c11abe142ad9b89278e953f7ba80cf12a23689d37a61825f1521d9176.png

Get more detailed information from a complete simulation:

# to get the analytical OFF statistics as the same view, use
on_off_times_analytic, on_off_values_analytic = bl.get_analytical_off_statistics(
    off_frames=blinks.off_periods_frames,
    off_periods=blinks.off_periods,
    on_frames=blinks.on_periods_frames,
    frame_time=blinks.emissions.parameters["frame_time"],
)

# plot the analytical OFF statistics (no differentiation between fluorophores)
bl.plot_off_statistics(
    on_off_times_analytic, on_off_values_analytic, scale=1, title="analytical OFF"
);
../../_images/7c558565f3d63d55be04f7ccf2c3b6941ef7ef1bda57855f3bb94f416bd85e2d.png