.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gallery/studies/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_studies_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-50 .. code-block:: Python import matplotlib.pyplot as plt from TypedUnit import ureg from FlowCyPy import FlowCytometer from FlowCyPy.fluidics import distributions from FlowCyPy.fluidics import ( FlowCell, Fluidics, ScattererCollection, populations, ) from FlowCyPy.opto_electronics import ( Detector, Digitizer, circuits, OptoElectronics, Amplifier, source, ) from FlowCyPy.digital_processing import DigitalProcessing source = source.Gaussian( waist_z=10 * ureg.micrometer, waist_y=60 * ureg.micrometer, wavelength=488 * ureg.nanometer, optical_power=100 * ureg.milliwatt, bandwidth=10 * ureg.megahertz, rin=-100 * ureg.dB_per_Hz, ) .. GENERATED FROM PYTHON SOURCE LINES 51-52 Define and plot the flow cell. .. GENERATED FROM PYTHON SOURCE LINES 52-112 .. code-block:: Python 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, ) # Create a scatterer collection with a single populations. # For signal processing, we use delta distributions (i.e., no variability). population = populations.SpherePopulation( name="Population", concentration=5e9 * ureg.particle / ureg.milliliter, diameter=distributions.Delta(value=150 * ureg.nanometer), refractive_index=distributions.Delta(value=1.39), medium_refractive_index=1.33, ) scatterer_collection = ScattererCollection(populations=[population]) fluidics = Fluidics(scatterer_collection=scatterer_collection, flow_cell=flow_cell) # Define the signal digitizer. digitizer = Digitizer( bit_depth=14, use_auto_range=True, sampling_rate=60 * ureg.megahertz, ) # Define two detectors. detector_0 = Detector( name="side", phi_angle=90 * ureg.degree, numerical_aperture=0.2 * ureg.AU, responsivity=1 * ureg.ampere / ureg.watt, dark_current=10 * ureg.microampere, ) detector_1 = Detector( name="forward", phi_angle=0 * ureg.degree, numerical_aperture=0.2 * ureg.AU, responsivity=1 * ureg.ampere / ureg.watt, dark_current=1 * ureg.microampere, ) amplifier = Amplifier(gain=100 * ureg.volt / ureg.ampere, bandwidth=10 * ureg.megahertz) opto_electronics = OptoElectronics( detectors=[detector_0, detector_1], source=source, amplifier=amplifier, digitizer=digitizer, analog_processing=[], ) # Setup the flow cytometer. flow_cytometer = FlowCytometer( fluidics=fluidics, background_power=2 * ureg.microwatt, ) .. GENERATED FROM PYTHON SOURCE LINES 113-116 --------------------------------------------------------------------------- Signal Processing: Acquisition with Different Processing Steps --------------------------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 116-169 .. code-block:: Python fig, ax = plt.subplots(1, 1, figsize=(12, 6)) run_time = 0.1 * ureg.millisecond # Acquisition 1: Raw Signal (no processing) opto_electronics.analog_processing = [] run_record = flow_cytometer.run( run_time=run_time, opto_electronics=opto_electronics, ) ax.plot( run_record.signal.analog["Time"].to("microsecond"), run_record.signal.analog["forward"].to("millivolt"), linestyle="-", label="Raw Signal", ) # Acquisition 2: Baseline Restoration opto_electronics.analog_processing = [ circuits.BaselineRestorationServo(time_constant=10 * ureg.microsecond) ] run_record = flow_cytometer.run( run_time=run_time, opto_electronics=opto_electronics, ) ax.plot( run_record.signal.analog["Time"].to("microsecond"), run_record.signal.analog["forward"].to("millivolt"), linestyle="--", label="Baseline Restored", ) # Acquisition 3: Bessel LowPass Filter opto_electronics.analog_processing = [ circuits.BesselLowPass(cutoff_frequency=3 * ureg.megahertz, order=4, gain=2) ] run_record = flow_cytometer.run( run_time=run_time, opto_electronics=opto_electronics, ) ax.plot( run_record.signal.analog["Time"].to("microsecond"), run_record.signal.analog["forward"].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() .. image-sg:: /gallery/studies/images/sphx_glr_signal_processing_001.png :alt: Flow Cytometry Signal Processing :srcset: /gallery/studies/images/sphx_glr_signal_processing_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.056 seconds) .. _sphx_glr_download_gallery_studies_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 `_