.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/08-custom_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_auto_examples_08-custom_detection.py: Custom detection function ========================= This tutorial shows how to implement a custom detection function and use it with :func:`massphoto.fit`: 1. Download an example movie. 2. Set a contrast-to-mass calibration. 3. Define a custom detection function using a Gaussian Laplace filter. 4. Run detection + PSF fitting with the custom function. 5. Visualize the mass distribution and the detection map values. .. GENERATED FROM PYTHON SOURCE LINES 14-16 .. code-block:: Python :dedent: 1 .. GENERATED FROM PYTHON SOURCE LINES 18-21 Imports ------- We first import necessary packages and modules. .. GENERATED FROM PYTHON SOURCE LINES 21-28 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import scipy as sp import massphoto as mp .. GENERATED FROM PYTHON SOURCE LINES 29-34 Download example data --------------------- This tutorial uses a short example movie from Zenodo. You can replace this block with a direct file path if you have a local movie. .. GENERATED FROM PYTHON SOURCE LINES 34-49 .. code-block:: Python from zenodozipdownloader import ZenodoZipDownloader files = ZenodoZipDownloader( doi="10.5281/zenodo.15800729", download_dir="example_data", ).download("Figure 2.zip/006_dynamin_6.mp") if not files: raise RuntimeError( "Failed to download example data. Please download it manually from https://zenodo.org/record/15800729 " "or set path_movie to your own movie." ) path_movie = files[0] print(f"Using movie: {path_movie}") .. rst-class:: sphx-glr-script-out .. code-block:: none Using movie: /home/runner/work/massphoto/massphoto/docs/source/_examples/example_data/006_dynamin_6.mp .. GENERATED FROM PYTHON SOURCE LINES 50-56 Set up calibration ------------------ Set mass calibration parameters. See the mass calibration example for how to obtain these from a calibration movie: :ref:`sphx_glr_auto_examples_01-mass_calibration.py`. .. GENERATED FROM PYTHON SOURCE LINES 56-63 .. code-block:: Python # Disable progress bars for cleaner output in this tutorial mp.defaults.set("progress_bar", False) # Set contrast-to-mass calibration parameters (intercept, slope). Adjust to match your calibration. mp.defaults.set("mass_calibration", (-5.2, 3.1e4)) .. GENERATED FROM PYTHON SOURCE LINES 64-80 .. _define_custom_detection_function: Define a custom detection function ------------------------------------ A custom detection function must accept one or two input movie as np.ndarray and return a DataFrame of detected events. Annotating the movie argument with :class:`massphoto.NativeMovie` or :class:`massphoto.RatiometricMovie` tells the pipeline which movie representation to pass; the values themselves are plain ``np.ndarray`` instances. Similarly, :class:`massphoto.EventList` annotates the output but is just a ``pd.DataFrame``. Any additional parameters can be exposed as keyword arguments which can be passed via ``detection_args``. Here we use :func:`scipy.ndimage.gaussian_laplace` as the spatial filter. You can swap in any filter that returns an array of the same shape. .. GENERATED FROM PYTHON SOURCE LINES 80-136 .. code-block:: Python def custom_detect( movie: mp.RatiometricMovie, sigma: float = 2.5, threshold: float = 1e-4, **kwargs, ) -> mp.EventList: """Detect events using a Gaussian Laplace filter on the ratiometric movie. Applies :func:`scipy.ndimage.gaussian_laplace` frame-by-frame and then calls :func:`massphoto.detect_on_map` on the resulting filter response. Parameters ---------- movie : mp.RatiometricMovie Ratiometric movie array (np.ndarray: T x H x W). Using this type annotation ensures that the ratiometric movie is passed to the function by the pipeline. sigma : float, optional Standard deviation of the Gaussian kernel. Default is 2.5. threshold : float, optional Absolute detection threshold on the Gaussian Laplace response. Default is 1e-4. **kwargs Additional keyword arguments forwarded to :func:`scipy.ndimage.gaussian_laplace`. Returns ------- mp.EventList DataFrame of detected events with columns ``frame``, ``y``, ``x``, and map values. Notes ----- Custom detection functions must handle empty input (``movie.shape[0] == 0``) correctly, because the parallel pipeline calls them with a zero-frame chunk to infer the output schema before processing real data. Any filter or helper used inside the function must therefore also tolerate empty arrays. :func:`massphoto.filter.stack_apply_filter` satisfies this requirement. """ detection_map = mp.filter.stack_apply_filter(sp.ndimage.gaussian_laplace, movie, sigma=sigma, **kwargs) detections = mp.detect_on_map( (detection_map, movie), thresholds=[threshold, 0.0], threshold_absolute=True, min_distance_temp=15, min_distance_spat=9, position_map=0, contrast_map=1, output_map_values=True, ) return detections .. GENERATED FROM PYTHON SOURCE LINES 137-142 Run detection and fitting ------------------------- Pass the custom function via ``detection_func``. Any parameters it exposes can be tuned through ``detection_args``. .. GENERATED FROM PYTHON SOURCE LINES 142-149 .. code-block:: Python fitres = mp.fit(path_movie, detection_func=custom_detect, detection_args={"sigma": 2.5, "threshold": 1e-4}) # Fit mass distribution histfit = mp.distfit.fit(fitres["masses_kDa"], bins=np.arange(-100, 700, 2.5), include_background=False) histfit.peaks[["mu", "sigma", "A"]].round(2) .. raw:: html
mu sigma A
0 89.69 6.90 3294.80
1 181.95 7.68 4954.61
2 369.94 9.67 3305.41
3 557.02 13.31 407.40


.. GENERATED FROM PYTHON SOURCE LINES 150-151 Plot results .. GENERATED FROM PYTHON SOURCE LINES 151-159 .. code-block:: Python plt.figure(figsize=(6, 3)) plt.bar(histfit.bin_centers, histfit.counts, width=histfit.bin_widths, edgecolor="none", label="Data") plt.plot(histfit.model_x, histfit.model_y, color="black", lw=1, label="Fit") plt.xlabel("Mass (kDa)") plt.ylabel("Counts") plt.legend() plt.tight_layout() .. image-sg:: /auto_examples/images/sphx_glr_08-custom_detection_001.png :alt: 08 custom detection :srcset: /auto_examples/images/sphx_glr_08-custom_detection_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 160-169 Detection map value vs mass --------------------------- The Gaussian Laplace response scales with event contrast (and therefore mass), so larger events are easier to detect above the threshold. The default filters are normalised to have a more mass-independent response. We have passed ``output_map_values=True`` to the detection function which lets us inspect the detection map values for each event. Here we plot these values against the fitted masses to see how they correlate. .. GENERATED FROM PYTHON SOURCE LINES 169-177 .. code-block:: Python plt.figure(figsize=(6, 3)) plt.scatter(fitres["masses_kDa"], fitres["map_0"], alpha=0.2) plt.xlim(-50, 700) plt.ylim(0, 1e-3) plt.xlabel("Mass (kDa)") plt.ylabel("Detection map value") plt.tight_layout() .. image-sg:: /auto_examples/images/sphx_glr_08-custom_detection_002.png :alt: 08 custom detection :srcset: /auto_examples/images/sphx_glr_08-custom_detection_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 11.636 seconds) .. _sphx_glr_download_auto_examples_08-custom_detection.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 08-custom_detection.ipynb <08-custom_detection.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 08-custom_detection.py <08-custom_detection.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 08-custom_detection.zip <08-custom_detection.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_