Note
Go to the end to download the full example code.
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:#
Define laser source and flow cell geometry
Add synthetic particle populations
Model optical scattering with two detectors
Visualize population and scattering response
Step 0: Imports and Setup#
import numpy as np
from FlowCyPy import units
from FlowCyPy.opto_electronics import source, TransimpedanceAmplifier
from FlowCyPy.fluidics import Fluidics, FlowCell, ScattererCollection, population
from FlowCyPy.detector import PMT
from FlowCyPy.signal_processing import Digitizer
from FlowCyPy import OptoElectronics
Step 1: Define Optical Source#
laser = source.GaussianBeam(
numerical_aperture=0.3 * units.AU,
wavelength=750 * units.nanometer,
optical_power=20 * units.milliwatt
)
Step 2: Configure Flow Cell and Fluidics#
flow_cell = FlowCell(
sample_volume_flow=0.02 * units.microliter / units.second,
sheath_volume_flow=0.1 * units.microliter / units.second,
width=20 * units.micrometer,
height=10 * units.micrometer
)
scatterer_collection = ScattererCollection(medium_refractive_index=1.33 * units.RIU)
# Add Exosome and HDL populations
scatterer_collection.add_population(
population.Exosome(particle_count=5e10 * units.particle / units.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 * units.millisecond)
# Plot the diameter distribution of the particles
event_dataframe.plot(x='Diameter', bins='auto')

<Figure size 1000x600 with 1 Axes>
Step 4: Define Detectors and Amplifier#
detector_forward = PMT(
name='forward',
phi_angle=0 * units.degree,
numerical_aperture=0.3 * units.AU
)
detector_side = PMT(
name='side',
phi_angle=90 * units.degree,
numerical_aperture=0.3 * units.AU
)
amplifier = TransimpedanceAmplifier(
gain=100 * units.volt / units.ampere,
bandwidth=10 * units.megahertz
)
Step 5: Configure Digitizer and Opto-Electronics#
digitizer = Digitizer(
bit_depth='14bit',
saturation_levels='auto',
sampling_rate=60 * units.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
)
/opt/hostedtoolcache/Python/3.11.13/x64/lib/python3.11/site-packages/FlowCyPy/source.py:266: UserWarning: Transverse distribution of particle flow exceed the waist of the source
warnings.warn('Transverse distribution of particle flow exceed the waist of the source')
/opt/hostedtoolcache/Python/3.11.13/x64/lib/python3.11/site-packages/FlowCyPy/source.py:266: UserWarning: Transverse distribution of particle flow exceed the waist of the source
warnings.warn('Transverse distribution of particle flow exceed the waist of the source')
Step 7: Visualize Scattering Intensity#
event_dataframe.plot(
x='side',
y='Csca' # Color-coded by scattering cross-section
)

<seaborn.axisgrid.JointGrid object at 0x7fcab2ccac90>
Total running time of the script: (0 minutes 3.671 seconds)