| Meta | Â | ||
| Testing | |||
| PyPi | Â | ||
| Anaconda | 
FlowCyPy is a cutting-edge Python library designed to simulate flow cytometer experiments. By generating realistic Forward Scatter (FSC) and Side Scatter (SSC) signals, FlowCyPy enables detailed modeling of flow cytometry setups, making it ideal for researchers and engineers working with extracellular vesicles (EVs) or other scatterers.
- Particle Event Simulation: Create detailed FSC/SSC signals with customizable particle size and refractive index distributions.
 - Noise and Signal Modeling: Incorporate realistic noise sources (thermal, shot, dark current) and baseline shifts.
 - Detector Configurations: Simulate real-world detector behaviors, including saturation and responsivity.
 - Fluorescence Modeling: Simulate fluorescence signals for labeled particles (e.g., EV surface markers).
 - Visualization Tools: Generate advanced plots, including density maps and signal traces.
 
For full documentation and examples, visit the FlowCyPy Documentation.
Install FlowCyPy via pip or conda`:
pip install FlowCyPy
conda install FlowCyPy --channels MartinPdeSRequirements: Python 3.10 or higher with dependencies: numpy, scipy, pint, tabulate, seaborn, MPSPlots, PyMieSim, pydantic>=2.6.3
Simulate a simple flow cytometer experiment:
from TypedUnit import ureg
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
# %%
# Step 1: Define Flow Cell and Fluidics
# -------------------------------------
from FlowCyPy.flow_cell import FlowCell
from FlowCyPy.fluidics import Fluidics, ScattererCollection, distribution, population
flow_cell = FlowCell(
    sample_volume_flow=80 * ureg.microliter / ureg.minute,
    sheath_volume_flow=1 * ureg.milliliter / ureg.minute,
    width=200 * ureg.micrometer,
    height=100 * ureg.micrometer,
)
scatterer_collection = ScattererCollection(medium_refractive_index=1.33 * ureg.RIU)
population_0 = population.Sphere(
    name="Pop 0",
    particle_count=5e9 * ureg.particle / ureg.milliliter,
    diameter=distribution.RosinRammler(150 * ureg.nanometer, spread=30),
    refractive_index=distribution.Normal(1.44 * ureg.RIU, std_dev=0.002 * ureg.RIU),
)
population_1 = population.Sphere(
    name="Pop 1",
    particle_count=5e9 * ureg.particle / ureg.milliliter,
    diameter=distribution.RosinRammler(200 * ureg.nanometer, spread=30),
    refractive_index=distribution.Normal(1.44 * ureg.RIU, std_dev=0.002 * ureg.RIU),
)
scatterer_collection.add_population(population_0, population_1)
scatterer_collection.dilute(factor=30)
fluidics = Fluidics(scatterer_collection=scatterer_collection, flow_cell=flow_cell)
# %%
# Step 2: Define Optical Subsystem
# --------------------------------
from FlowCyPy.opto_electronics import (
    Detector,
    OptoElectronics,
    TransimpedanceAmplifier,
    source,
)
source = source.GaussianBeam(
    numerical_aperture=0.1 * ureg.AU,
    wavelength=450 * ureg.nanometer,
    optical_power=200 * ureg.milliwatt,
    RIN=-140,
)
detectors = [
    Detector(
        name="forward",
        phi_angle=0 * ureg.degree,
        numerical_aperture=0.3 * ureg.AU,
        responsivity=1 * ureg.ampere / ureg.watt,
    ),
    Detector(
        name="side",
        phi_angle=90 * ureg.degree,
        numerical_aperture=0.3 * ureg.AU,
        responsivity=1 * ureg.ampere / ureg.watt,
    ),
]
amplifier = TransimpedanceAmplifier(
    gain=10 * ureg.volt / ureg.ampere,
    bandwidth=10 * ureg.megahertz,
    voltage_noise_density=0.1 * ureg.nanovolt / ureg.sqrt_hertz,
    current_noise_density=0.2 * ureg.femtoampere / ureg.sqrt_hertz,
)
opto_electronics = OptoElectronics(
    detectors=detectors, source=source, amplifier=amplifier
)
# %%
# Step 3: Signal Processing Configuration
# ---------------------------------------
from FlowCyPy.signal_processing import (
    Digitizer,
    SignalProcessing,
    circuits,
    peak_locator,
    triggering_system,
)
digitizer = Digitizer(
    bit_depth="14bit", saturation_levels="auto", sampling_rate=60 * ureg.megahertz
)
analog_processing = [
    circuits.BaselineRestorator(window_size=10 * ureg.microsecond),
    circuits.BesselLowPass(cutoff=2 * ureg.megahertz, order=4, gain=2),
]
triggering = triggering_system.DynamicWindow(
    trigger_detector_name="forward",
    threshold=10 * ureg.microvolt,
    pre_buffer=20,
    post_buffer=20,
    max_triggers=-1,
)
peak_algo = peak_locator.GlobalPeakLocator(compute_width=False)
signal_processing = SignalProcessing(
    digitizer=digitizer,
    analog_processing=analog_processing,
    triggering_system=triggering,
    peak_algorithm=peak_algo,
)
# %%
# Step 4: Run Simulation
# ----------------------
from FlowCyPy import FlowCytometer
cytometer = FlowCytometer(
    opto_electronics=opto_electronics,
    fluidics=fluidics,
    signal_processing=signal_processing,
    background_power=0.001 * ureg.milliwatt,
)
run_record = cytometer.run(run_time=1.5 * ureg.millisecond)
# %%
# Step 5: Plot Events and Raw Analog Signals
# ------------------------------------------
_ = run_record.events.plot(
    x="Diameter",
    y="RefractiveIndex",
    show=False,
    save_as=f"{dir_path}/../images/readme_events.png",
)# %%
# Plot raw analog signals
# -----------------------
_ = run_record.plot_analog(
    figure_size=(12, 8),
    show=False,
    save_as=f"{dir_path}/../images/readme_analog.png",
)# %%
# Step 6: Plot Triggered Analog Segments
# --------------------------------------
_ = run_record.plot_digital(
    figure_size=(12, 8),
    show=False,
    save_as=f"{dir_path}/../images/readme_digital.png",
)Explore more examples in the FlowCyPy Examples.
Here is the architecture for a standard workflow using FlowCyPy:
git clone https://github.com/MartinPdeS/FlowCyPy.git
cd FlowCyPyInstall in editable mode with testing and documentation dependencies:
pip install -e .[testing,documentation] (on linux system)
pip install -e ".[testing,documentation]" (on macOS system)Use pytest to validate functionality:
pytestBuild the documentation locally:
cd docs
make htmlFind the documentation in docs/_build/html.
- Documentation: Full guide and API reference at FlowCyPy Documentation
 - Examples: Explore use cases in the Examples Section
 - GitHub Repository: Access the source code and contribute at FlowCyPy GitHub
 
Contributions are welcome! If you have suggestions, issues, or would like to collaborate, visit the GitHub repository.
For inquiries or collaboration, contact Martin Poinsinet de Sivry-Houle.




