
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/plot_peptides.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_plot_peptides.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_plot_peptides.py:


Measure the curvature of a peptide
==================================

In this example, we measure the curvature of a peptide in an AFM image.

Image credit: Yiwei Zheng, `LBNI <https://www.epfl.ch/labs/lbni/>`_, `EPFL <https://www.epfl.ch/en/>`_

.. GENERATED FROM PYTHON SOURCE LINES 9-19

.. code-block:: Python



    import matplotlib.pyplot as plt
    import numpy as np
    import scipy
    import skan
    import skimage
    import splinebox
    import tifffile








.. GENERATED FROM PYTHON SOURCE LINES 21-23

1. Load and Inspect the Data
----------------------------

.. GENERATED FROM PYTHON SOURCE LINES 23-28

.. code-block:: Python

    img = tifffile.imread("peptides.tif")

    plt.imshow(img, cmap="afmhot")
    plt.show()




.. image-sg:: /auto_examples/images/sphx_glr_plot_peptides_001.png
   :alt: plot peptides
   :srcset: /auto_examples/images/sphx_glr_plot_peptides_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 29-31

2. Segmentation and Skeletonization
-----------------------------------

.. GENERATED FROM PYTHON SOURCE LINES 31-41

.. code-block:: Python

    thresh = skimage.filters.threshold_otsu(img)
    mask = img > thresh
    skeleton = skimage.morphology.skeletonize(mask)
    label_img = skimage.measure.label(skeleton)
    label_biggest = np.argmax(np.bincount(label_img.flatten())[1:]) + 1
    skeleton = label_img == label_biggest

    plt.imshow(skeleton)
    plt.show()




.. image-sg:: /auto_examples/images/sphx_glr_plot_peptides_002.png
   :alt: plot peptides
   :srcset: /auto_examples/images/sphx_glr_plot_peptides_002.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 42-44

3. Select longest path
----------------------

.. GENERATED FROM PYTHON SOURCE LINES 44-57

.. code-block:: Python


    graph, coords = skan.csr.skeleton_to_csgraph(skeleton)
    coords = np.stack(coords, axis=-1)

    dist_matrix, predecessors = scipy.sparse.csgraph.shortest_path(graph, return_predecessors=True)
    stop_index, start_index = np.unravel_index(np.argmax(dist_matrix), dist_matrix.shape)
    i = start_index
    skeleton_points = []
    while i != stop_index:
        skeleton_points.append(coords[i])
        i = predecessors[stop_index, i]
    skeleton_points = np.array(skeleton_points)








.. GENERATED FROM PYTHON SOURCE LINES 58-60

4. Fit Spline
-------------

.. GENERATED FROM PYTHON SOURCE LINES 60-75

.. code-block:: Python


    M = 20
    basis_function = splinebox.basis_functions.B3()
    initial_spline = splinebox.spline_curves.Spline(M=M, basis_function=basis_function, closed=False)
    initial_spline.fit(skeleton_points)

    t = np.linspace(0, M - 1, M * 100)
    initial_vals = initial_spline.eval(t)
    initial_knots = initial_spline.knots

    plt.imshow(img, cmap="afmhot")
    plt.plot(initial_vals[:, 1], initial_vals[:, 0])
    plt.scatter(initial_knots[:, 1], initial_knots[:, 0])
    plt.show()




.. image-sg:: /auto_examples/images/sphx_glr_plot_peptides_003.png
   :alt: plot peptides
   :srcset: /auto_examples/images/sphx_glr_plot_peptides_003.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 76-78

5. Refine Spline
----------------

.. GENERATED FROM PYTHON SOURCE LINES 78-112

.. code-block:: Python



    def loss_function(control_points, alpha):
        spline.control_points = control_points.reshape((-1, 2))
        coords = spline.eval(t)
        pixel_values = scipy.ndimage.map_coordinates(img, coords.T)
        image_energy = np.mean(pixel_values)
        internal_energy = np.mean(spline.eval(t, derivative=2) ** 2)
        energy = -1 * image_energy + alpha * internal_energy
        return energy


    initial_control_points = initial_spline.control_points
    spline = initial_spline.copy()
    scipy.optimize.minimize(
        loss_function,
        initial_control_points.flatten(),
        args=(0.3,),
        method="Powell",
        tol=0.01,
    )

    vals = spline.eval(t)
    knots = spline.knots

    plt.figure()
    plt.imshow(img, cmap="afmhot")
    plt.plot(initial_vals[:, 1], initial_vals[:, 0], label="initial spline", alpha=0.3)
    plt.scatter(initial_knots[:, 1], initial_knots[:, 0], alpha=0.3)
    plt.plot(vals[:, 1], vals[:, 0], label="refined spline")
    plt.scatter(knots[:, 1], knots[:, 0])
    plt.legend()
    plt.show()




.. image-sg:: /auto_examples/images/sphx_glr_plot_peptides_004.png
   :alt: plot peptides
   :srcset: /auto_examples/images/sphx_glr_plot_peptides_004.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 113-115

6. Curvature Comb
-----------------

.. GENERATED FROM PYTHON SOURCE LINES 115-137

.. code-block:: Python


    total_length = spline.arc_length()
    lengths = np.linspace(0, total_length, 200)
    t = spline.arc_length_to_parameter(lengths)

    vals = spline.eval(t)
    curvature = spline.curvature(t)
    normals = spline.normal(t)

    comb = vals + 500 * curvature[:, np.newaxis] * normals

    plt.figure()
    plt.imshow(img, cmap="afmhot")
    plt.plot(comb[:, 1], comb[:, 0], label="Curvature comb", color="yellowgreen")
    for p in range(0, len(t), 3):
        plt.plot([vals[p, 1], comb[p, 1]], [vals[p, 0], comb[p, 0]], color="yellowgreen")
    plt.plot(vals[:, 1], vals[:, 0], label="spline")
    plt.xlim((0, img.shape[1]))
    plt.ylim((img.shape[0], 0))
    plt.legend()
    plt.show()




.. image-sg:: /auto_examples/images/sphx_glr_plot_peptides_005.png
   :alt: plot peptides
   :srcset: /auto_examples/images/sphx_glr_plot_peptides_005.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 138-140

7. Plot Curvature vs. Length
----------------------------

.. GENERATED FROM PYTHON SOURCE LINES 140-147

.. code-block:: Python


    plt.figure()
    plt.axhline(0, linestyle="--", color="black", alpha=0.5)
    plt.plot(lengths, curvature)
    plt.xlabel("length [px]")
    plt.ylabel("curvature")
    plt.show()



.. image-sg:: /auto_examples/images/sphx_glr_plot_peptides_006.png
   :alt: plot peptides
   :srcset: /auto_examples/images/sphx_glr_plot_peptides_006.png
   :class: sphx-glr-single-img






.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 3.658 seconds)


.. _sphx_glr_download_auto_examples_plot_peptides.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_peptides.ipynb <plot_peptides.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_peptides.py <plot_peptides.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_peptides.zip <plot_peptides.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
