.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gallery/tutorials/signal_processing.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_gallery_tutorials_signal_processing.py: Signal Processing in Flow Cytometry ===================================== This example demonstrates how to apply signal processing techniques to flow cytometry data using FlowCyPy. The simulation is set up with a Gaussian beam, a flow cell, and two detectors. A single population of scatterers (with delta distributions) is used, and the focus here is on processing the forward scatter detector signals. Three acquisitions are performed: - **Raw Signal:** No processing applied. - **Baseline Restored:** Using a baseline restorator. - **Bessel LowPass:** Using a Bessel low-pass filter. The resulting signals are plotted for comparison. .. GENERATED FROM PYTHON SOURCE LINES 17-42 .. code-block:: Python import numpy as np import matplotlib.pyplot as plt # Import necessary components from FlowCyPy from FlowCyPy import ( FlowCytometer, ScattererCollection, Detector, GaussianBeam, population, distribution, circuits, units, NoiseSetting, TransimpedanceAmplifier ) from FlowCyPy.flow_cell import FlowCell from FlowCyPy.signal_digitizer import SignalDigitizer # Enable noise settings if desired NoiseSetting.include_noises = True # Set random seed for reproducibility np.random.seed(3) # Define the optical source: a Gaussian beam. source = GaussianBeam( numerical_aperture=0.3 * units.AU, # Numerical aperture of the laser wavelength=488 * units.nanometer, # Laser wavelength: 488 nm optical_power=100 * units.milliwatt # Laser optical power: 100 mW ) .. GENERATED FROM PYTHON SOURCE LINES 43-44 Define and plot the flow cell. .. GENERATED FROM PYTHON SOURCE LINES 44-151 .. code-block:: Python 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, ) flow_cell.plot(n_samples=100) # Create a scatterer collection with a single population. # For signal processing, we use delta distributions (i.e., no variability). population = population.Sphere( name='Population', particle_count=10 * units.particle, diameter=distribution.Delta(position=150 * units.nanometer), refractive_index=distribution.Delta(position=1.39 * units.RIU) ) scatterer_collection = ScattererCollection( medium_refractive_index=1.33 * units.RIU, populations=[population] ) # Define the signal digitizer. digitizer = SignalDigitizer( bit_depth='14bit', saturation_levels='auto', sampling_rate=60 * units.megahertz # Sampling rate: 60 MHz ) # Define two detectors. detector_0 = Detector( name='side', phi_angle=90 * units.degree, numerical_aperture=0.2 * units.AU, responsivity=1 * units.ampere / units.watt, dark_current=10 * units.microampere, ) detector_1 = Detector( name='forward', phi_angle=0 * units.degree, numerical_aperture=0.2 * units.AU, responsivity=1 * units.ampere / units.watt, dark_current=1 * units.microampere, ) transimpedance_amplifier = TransimpedanceAmplifier( gain=100 * units.volt / units.ampere, bandwidth = 10 * units.megahertz ) # Setup the flow cytometer. cytometer = FlowCytometer( source=source, transimpedance_amplifier=transimpedance_amplifier, digitizer=digitizer, scatterer_collection=scatterer_collection, flow_cell=flow_cell, background_power=2 * units.microwatt, detectors=[detector_0, detector_1] ) # --------------------------------------------------------------------------- # Signal Processing: Acquisition with Different Processing Steps # --------------------------------------------------------------------------- fig, ax = plt.subplots(1, 1, figsize=(12, 6)) # Acquisition 1: Raw Signal (no processing) processing_steps_none = [] cytometer.prepare_acquisition(run_time=0.1 * units.millisecond) acquisition_none = cytometer.get_acquisition(processing_steps=processing_steps_none) ax.plot( acquisition_none['Time'].pint.to('microsecond'), acquisition_none['forward'].pint.to('millivolt'), linestyle='-', label='Raw Signal' ) # Acquisition 2: Baseline Restoration processing_steps_baseline = [circuits.BaselineRestorator(window_size=1000 * units.microsecond)] acquisition_baseline = cytometer.get_acquisition(processing_steps=processing_steps_baseline) ax.plot( acquisition_baseline['Time'].pint.to('microsecond'), acquisition_baseline['forward'].pint.to('millivolt'), linestyle='--', label='Baseline Restored' ) # Acquisition 3: Bessel LowPass Filter processing_steps_bessel = [circuits.BesselLowPass(cutoff=3 * units.megahertz, order=4, gain=2)] acquisition_bessel = cytometer.get_acquisition(processing_steps=processing_steps_bessel) ax.plot( acquisition_bessel['Time'].pint.to('microsecond'), acquisition_bessel['forward'].pint.to('millivolt'), linestyle='-.', label='Bessel LowPass' ) # Configure the plot. ax.set_title("Flow Cytometry Signal Processing") ax.set_xlabel("Time [microsecond]") ax.set_ylabel("Signal Amplitude [millivolt]") ax.legend() plt.tight_layout() plt.show() .. rst-class:: sphx-glr-horizontal * .. image-sg:: /gallery/tutorials/images/sphx_glr_signal_processing_001.png :alt: Particle Spatial Distribution and Speed :srcset: /gallery/tutorials/images/sphx_glr_signal_processing_001.png :class: sphx-glr-multi-img * .. image-sg:: /gallery/tutorials/images/sphx_glr_signal_processing_002.png :alt: Flow Cytometry Signal Processing :srcset: /gallery/tutorials/images/sphx_glr_signal_processing_002.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none /opt/hostedtoolcache/Python/3.11.12/x64/lib/python3.11/site-packages/FlowCyPy/source.py:269: 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.12/x64/lib/python3.11/site-packages/FlowCyPy/source.py:269: 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') .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.677 seconds) .. _sphx_glr_download_gallery_tutorials_signal_processing.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: signal_processing.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: signal_processing.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: signal_processing.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_