Flow Cytometry Workflow: Single Population Example#

This tutorial demonstrates a basic flow cytometry simulation using the FlowCyPy library.

The example covers the configuration of: - A fluidic channel with hydrodynamic focusing - A synthetic particle population (Exosome + HDL) - A laser source and dual-detector optical system - Scattering intensity calculation per detector

The resulting data are visualized using event-based plots.

Workflow Steps:#

  1. Define laser source and flow cell geometry

  2. Add synthetic particle populations

  3. Model optical scattering with two detectors

  4. Visualize population and scattering response

Step 0: Imports and Setup#

from TypedUnit import ureg

from FlowCyPy import OptoElectronics
from FlowCyPy.detector import PMT
from FlowCyPy.fluidics import FlowCell, Fluidics, ScattererCollection, population
from FlowCyPy.opto_electronics import TransimpedanceAmplifier, source
from FlowCyPy.signal_processing import Digitizer

Step 1: Define Optical Source#

laser = source.GaussianBeam(
    numerical_aperture=0.3 * ureg.AU,
    wavelength=750 * ureg.nanometer,
    optical_power=20 * ureg.milliwatt,
)

Step 2: Configure Flow Cell and Fluidics#

flow_cell = FlowCell(
    sample_volume_flow=0.02 * ureg.microliter / ureg.second,
    sheath_volume_flow=0.1 * ureg.microliter / ureg.second,
    width=20 * ureg.micrometer,
    height=10 * ureg.micrometer,
)

scatterer_collection = ScattererCollection(medium_refractive_index=1.33 * ureg.RIU)

# Add Exosome and HDL populations
scatterer_collection.add_population(
    population.Exosome(particle_count=5e10 * ureg.particle / ureg.milliliter),
)

fluidics = Fluidics(scatterer_collection=scatterer_collection, flow_cell=flow_cell)

Step 3: Generate Particle Event DataFrame#

event_dataframe = fluidics.generate_event_dataframe(run_time=3.5 * ureg.millisecond)

# Plot the diameter distribution of the particles
event_dataframe.plot(x="Diameter", bins="auto")
Distribution of Diameter
<Figure size 1200x500 with 1 Axes>

Step 4: Define Detectors and Amplifier#

detector_forward = PMT(
    name="forward", phi_angle=0 * ureg.degree, numerical_aperture=0.3 * ureg.AU
)

detector_side = PMT(
    name="side", phi_angle=90 * ureg.degree, numerical_aperture=0.3 * ureg.AU
)

amplifier = TransimpedanceAmplifier(
    gain=100 * ureg.volt / ureg.ampere, bandwidth=10 * ureg.megahertz
)

Step 5: Configure Digitizer and Opto-Electronics#

digitizer = Digitizer(
    bit_depth="14bit", saturation_levels="auto", sampling_rate=60 * ureg.megahertz
)

opto_electronics = OptoElectronics(
    detectors=[detector_forward, detector_side], source=laser, amplifier=amplifier
)

Step 6: Model Scattering Signals#

event_dataframe = opto_electronics.model_event(
    event_dataframe=event_dataframe, compute_cross_section=True
)
Population  ScattererID
Exosome     0               1.5795017586881102e-07
            1              -3.7054548306477813e-07
            2               1.3726862882218792e-06
            3               1.2881161137246904e-06
            4              -2.0775551048896938e-07
                                    ...
            3535            -5.950548036265585e-07
            3536           -1.1251534683360597e-06
            3537           -2.3877871043832875e-09
            3538            1.3353450892354185e-06
            3539           -1.2096358602645537e-06
Name: y, Length: 3540, dtype: pint[meter][Float64] 795.7747154594767 nanometer
/opt/hostedtoolcache/Python/3.11.13/x64/lib/python3.11/site-packages/FlowCyPy/source.py:255: UserWarning: Transverse distribution of particle flow exceed the waist of the source
  warnings.warn(
Population  ScattererID
Exosome     0               1.5795017586881102e-07
            1              -3.7054548306477813e-07
            2               1.3726862882218792e-06
            3               1.2881161137246904e-06
            4              -2.0775551048896938e-07
                                    ...
            3535            -5.950548036265585e-07
            3536           -1.1251534683360597e-06
            3537           -2.3877871043832875e-09
            3538            1.3353450892354185e-06
            3539           -1.2096358602645537e-06
Name: y, Length: 3540, dtype: pint[meter][Float64] 795.7747154594767 nanometer
/opt/hostedtoolcache/Python/3.11.13/x64/lib/python3.11/site-packages/FlowCyPy/source.py:255: UserWarning: Transverse distribution of particle flow exceed the waist of the source
  warnings.warn(

Step 7: Visualize Scattering Intensity#

event_dataframe.plot(x="side", y="Csca")  # Color-coded by scattering cross-section
Scatterer Sampling Distribution
<seaborn.axisgrid.JointGrid object at 0x7f8a3e2bd790>

Total running time of the script: (0 minutes 3.829 seconds)

Gallery generated by Sphinx-Gallery