.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gallery/studies/limit_of_detection.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_limit_of_detection.py: Limit of Detection ================== This example simulates the detection of small nanoparticles (90-150 nm diameter) in a flow cytometry setup using a dual-detector configuration (side and forward scatter). The simulation includes noise models, realistic fluidics, analog signal conditioning, digitization, triggering, and peak detection. The main goal is to evaluate whether such particles produce detectable and distinguishable scatter signals in the presence of system noise and fluidic variability. .. GENERATED FROM PYTHON SOURCE LINES 13-37 .. code-block:: Python from FlowCyPy.units import ureg from FlowCyPy import FlowCytometer from FlowCyPy.fluidics import ( distributions, FlowCell, Fluidics, ScattererCollection, populations, ) from FlowCyPy.opto_electronics import ( Detector, OptoElectronics, Digitizer, Amplifier, source, circuits, ) from FlowCyPy.digital_processing import ( DigitalProcessing, peak_locator, discriminator, ) .. GENERATED FROM PYTHON SOURCE LINES 38-39 Optical Source .. GENERATED FROM PYTHON SOURCE LINES 39-46 .. code-block:: Python source = source.Gaussian( waist_z=10 * ureg.micrometer, waist_y=60 * ureg.micrometer, wavelength=405 * ureg.nanometer, optical_power=100 * ureg.milliwatt, ) .. GENERATED FROM PYTHON SOURCE LINES 47-48 Flow Cell Configuration .. GENERATED FROM PYTHON SOURCE LINES 48-55 .. 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, ) .. GENERATED FROM PYTHON SOURCE LINES 56-57 Define Scatterer Populations (90–150 nm spheres) .. GENERATED FROM PYTHON SOURCE LINES 57-77 .. code-block:: Python scatterer_collection = ScattererCollection() for size in [150, 125, 100, 75, 50]: pop = populations.SpherePopulation( name=f"{size} nm", concentration=5e9 * ureg.particle / ureg.milliliter, diameter=distributions.Delta(value=size * ureg.nanometer), refractive_index=distributions.Delta(value=1.36), medium_refractive_index=1.33, ) scatterer_collection.add_population(pop) scatterer_collection.dilute(factor=100) fluidics = Fluidics(scatterer_collection=scatterer_collection, flow_cell=flow_cell) digitizer = Digitizer( bit_depth=14, use_auto_range=True, sampling_rate=60 * ureg.megahertz ) .. GENERATED FROM PYTHON SOURCE LINES 78-79 Detectors .. GENERATED FROM PYTHON SOURCE LINES 79-95 .. code-block:: Python detector_side = Detector( name="side", phi_angle=90 * ureg.degree, numerical_aperture=0.2, responsivity=1 * ureg.ampere / ureg.watt, dark_current=0.1 * ureg.nanoampere, ) detector_forward = Detector( name="forward", phi_angle=0 * ureg.degree, numerical_aperture=0.2, responsivity=1 * ureg.ampere / ureg.watt, dark_current=0.1 * ureg.nanoampere, ) .. GENERATED FROM PYTHON SOURCE LINES 96-97 Opto-Electronics Processing Pipeline .. GENERATED FROM PYTHON SOURCE LINES 97-114 .. code-block:: Python amplifier = Amplifier( gain=10_000 * ureg.volt / ureg.ampere, bandwidth=10 * ureg.megahertz ) analog_processing = [ circuits.BesselLowPass(cutoff_frequency=0.4 * ureg.megahertz, order=4, gain=2), circuits.BaselineRestorationServo(time_constant=50 * ureg.microsecond), ] opto_electronics = OptoElectronics( digitizer=digitizer, analog_processing=analog_processing, detectors=[detector_side, detector_forward], source=source, amplifier=amplifier, ) .. GENERATED FROM PYTHON SOURCE LINES 115-116 Digital Processing Pipeline .. GENERATED FROM PYTHON SOURCE LINES 116-129 .. code-block:: Python discriminator = discriminator.FixedWindow( trigger_channel="side", threshold="4sigma", max_triggers=-1, pre_buffer=128, post_buffer=128, ) digital_processing = DigitalProcessing( discriminator=discriminator, peak_algorithm=peak_locator.GlobalPeakLocator(), ) .. GENERATED FROM PYTHON SOURCE LINES 130-141 .. code-block:: Python cytometer = FlowCytometer( fluidics=fluidics, background_power=0.1 * ureg.nanowatt, ) run_record = cytometer.run( run_time=10.0 * ureg.millisecond, digital_processing=digital_processing, opto_electronics=opto_electronics, ) .. GENERATED FROM PYTHON SOURCE LINES 142-143 Plot Raw Analog Signal .. GENERATED FROM PYTHON SOURCE LINES 143-145 .. code-block:: Python run_record.plot_analog() .. image-sg:: /gallery/studies/images/sphx_glr_limit_of_detection_001.png :alt: limit of detection :srcset: /gallery/studies/images/sphx_glr_limit_of_detection_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none
.. GENERATED FROM PYTHON SOURCE LINES 146-147 Plot Triggered Analog Signal Segments .. GENERATED FROM PYTHON SOURCE LINES 147-148 .. code-block:: Python run_record.plot_digital() .. image-sg:: /gallery/studies/images/sphx_glr_limit_of_detection_002.png :alt: limit of detection :srcset: /gallery/studies/images/sphx_glr_limit_of_detection_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none
.. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 4.810 seconds) .. _sphx_glr_download_gallery_studies_limit_of_detection.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: limit_of_detection.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: limit_of_detection.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: limit_of_detection.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_