Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate docs #56

Merged
merged 12 commits into from
Aug 8, 2024
22 changes: 22 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
phys2denoise: A toolbox for physiological metrics calculation
=============================================================

This package is designed for calculating physiological metrics, derived specifically cardiac and respiratory signals, to use in fMRI denoising.


.. image:: https://readthedocs.org/projects/phys2denoise/badge/?version=latest
:target: http://phys2denoise.readthedocs.io/en/latest
.. image:: https://img.shields.io/badge/license-Apache%202-blue.svg
:target: http://www.apache.org/licenses/LICENSE-2.0
.. image:: https://img.shields.io/badge/python-3.6+-blue.svg
:target: https://www.python.org/downloads/


.. _licensing:

License Information
-------------------

This codebase is licensed under the Apache License, Version 2.0. The full
license can be found in the `LICENSE <https://github.com/physiopy/phys2denoise/blob/master/LICENSE>`_ file in the ``phys2denoise`` distribution. You may also
obtain a copy of the license at: http://www.apache.org/licenses/LICENSE-2.0.
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = phys2denoise
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
34 changes: 34 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.. _api_ref:
API
===

.. py:module:: phys2denoise

Cardiac data
------------

.. automodule:: phys2denoise.metrics.cardiac
:members: heart_rate, heart_rate_variability, heart_beat_interval, cardiac_phase

Respiratory data
----------------

.. automodule:: phys2denoise.metrics.chest_belt
:members: respiratory_cariance_time, respiratory_pattern_variability, env, respiratory_variance, respiratory_phase

Multimodal data
---------------

.. autofunction:: phys2denoise.multimodal.retroicor

Response functions
------------------

.. automodule:: phys2denoise.metrics.responses
:members: crf, icrf, rrf

Utilities
---------

.. automodule:: phys2denoise.metrics.utils
:members: print_metric_call, mirrorpad_1d, rms_envelope_1d, apply_lags, apply_function_in_sliding_window, convolve_and_rescale, export_metric
113 changes: 113 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
import os
import sys

import matplotlib as mpl

mpl.use("Agg")

# -- Project information -----------------------------------------------------

# Add project name, copyright holder, and author(s)
project = "phys2denoise"
copyright = "2024, physiopy"
author = "physiopy"

# Import project to get version info
sys.path.insert(0, os.path.abspath(os.path.pardir))
import phys2denoise # noqa

# The short X.Y version
version = phys2denoise.__version__
# The full version, including alpha/beta/rc tags
release = phys2denoise.__version__

# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"matplotlib.sphinxext.plot_directive",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.mathjax",
"sphinx.ext.napoleon",
"sphinx.ext.viewcode",
]

# Generate the API documentation when building
autosummary_generate = True
numpydoc_show_class_members = False
autoclass_content = "class"

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# The suffix(es) of source filenames.
source_suffix = ".rst"

# The master toctree document.
master_doc = "index"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
import sphinx_rtd_theme # noqa

html_theme = "sphinx_rtd_theme"
html_show_sourcelink = False

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {}

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]

# -- Options for HTMLHelp output ---------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = "peakdetdoc"

# -- Extension configuration -------------------------------------------------
intersphinx_mapping = {
"matplotlib": ("https://matplotlib.org", None),
"numpy": ("https://docs.scipy.org/doc/numpy", None),
"scipy": ("https://docs.scipy.org/doc/scipy/reference", None),
}

plot_include_source = True
plot_formats = [("png", 90)]
plot_html_show_formats = False
plot_html_show_source_link = False
11 changes: 11 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.. include:: ../README.rst

Contents
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for now it is ok, but at some point it would be necessary to provide a bit more context/use cases for that package. You can check peakdet doc for an example

--------

.. toctree::
:maxdepth: 1

installation
usage
api
35 changes: 35 additions & 0 deletions docs/installation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.. _installation_setup:

Installation and setup
======================

.. _basic_installation:

Basic installation
------------------

The easiest way to install ``phys2denoise`` is to use ``pip``. Assuming you have
Python >= 3.6 installed, you can install ``phys2denoise`` by opening a terminal
and running the following:

.. code-block:: bash

pip install phys2denoise

.. warning::

If you encounter an ImportError related to numpy.core.multiarray, please try to update
your matplotlib version to 3.9.

Developer installation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if there is a reason to only have the dev installation here

----------------------

This package requires Python >= 3.6. Assuming you have the correct version of
Python installed, you can install ``phys2denoise`` by opening a terminal and running
the following:

.. code-block:: bash

git clone https://github.com/physiopy/phys2denoise.git
cd phys2denoise
pip install -e .[dev]
3 changes: 3 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-r ../requirements.txt
sphinx>=1.2
sphinx_rtd_theme
10 changes: 10 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. _usage:

User guide
==========

.. toctree::
:numbered:

user_guide/metrics.rst
user_guide/exporting.rst
33 changes: 33 additions & 0 deletions docs/user_guide/exporting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.. _usage_exporting:

Exporting physiological data metrics
------------------------------------
Another feature of the :py:mod:`phys2denoise` package is the ability to export the computed physiological data metrics to a file, with various parameters.
This can be done using the :py:func:`export_metric` function, which provides the following capabilities:

- Exporting the computed metrics, resampled at the TR of the fMRI data, along with the original data.
- Flagging if the exported data is the convolved version or if the metric contains lags of itself, resulting in appropriate file naming.
- Defining the output file extension and file prefix.
- Defining the number of timepoints to be considered.

The following example shows how to export the computed respiratory variance time using a Physio object. In the following example,
we consider that the Physio object is ``resp``, containing the respiratory data, peaks and troughs.

.. code-block:: python

from phys2denoise.metrics.chest_belt import respiratory_variance_time
from phys2denoise.metrics.utils import export_metric

RVT = respiratory_variance_time(
resp.data, resp.peaks, resp.troughs, resp.fs, lags=(0, 4, 8, 12)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might have missed it but I don't see where resp was defined previously

)

export_metric(
RVT,
resp.fs,
tr=1.5,
fileprefix="data/sub-002_ses-01_task-rest_run-01_RVT",
ntp=400,
is_convolved=False,
has_lags=True,
)
76 changes: 76 additions & 0 deletions docs/user_guide/metrics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
.. _usage_metrics:

Computing physiological data metrics
-------------------------------------
The :py:mod:`phys2denoise` package provides a set of functions to compute physiological data metrics. The set of supported metrics
includes:

- Cardiac metrics
- Cardiac phase
- Heart rate
- Heart rate variability
- Heart beat interval
- Respiratory metrics
- Respiratory phase
- Respiratory variance
- Respiratory pattern variability
- Envelope
- Multimodal metrics
- RETROICOR

All of the metrics computation function definitions, descriptions and references can be found in :ref:`api_ref`.


Using a Physio object
#####################

Physiological data metrics can be easily computed using Physio objects, from the :py:mod:`physutils` module,
on which the physiological data will be loaded.

The following example shows how to compute the respiratory variance time using a Physio object.

.. code-block:: python

from physutils import io
from phys2denoise.metrics.chest_belt import respiratory_variance_time
# peakdet is an example package that provides peak/trough detection for the respiratory signal
from peakdet import operations

# Load the physiological data
sample_rate = 1000
physio = io.load_physio('path/to/physiological/data', fs=sample_rate)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point it would be nice to provide actual data for people to play around


# Peak/trough detection for the respiratory signal, using the peakdet package
physio = operations.peakfind_physio(physio)

# Compute RVT
physio, rvt = respiratory_variance_time(physio)

:py:func:`respiratory_variance_time` returns a tuple with the updated Physio object and the computed respiratory variance time.

:py:mod:`peakdet` is used in this example as it is also compatible with the Physio object. However, any other peak/trough detection
package can be used. In this case, the peak and trough values should be stored in the Physio object manually as follows:

.. code-block:: python

# Store the peak and trough values in the Physio object
physio._metadata["peaks"] = peaks
physio._metadata["troughs"] = troughs

The benefit of using a Physio object other than the encapsulation of all the desired parameters in a single object is the fact that
the object retains a history of all the operations performed on it. This allows for easy debugging and reproducibility of the results.
For further information refer to the :py:mod:`physutils` documentation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm not aware of it, but it looks like for the moment there is not physutils documentation. So since you are referring to it, I'm wondering if we should work on the physutils docs before merging that PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can generate some docs only including API for the time being.


Without using a Physio object
#############################

However, if the use of the ``Physio`` object from the :py:mod:`physutils` module is not preferred, the metrics can be also computed without it. The following
example shows how to compute the heart rate and the heart rate variability using the :py:mod:`phys2denoise` package.

.. code-block:: python

from phys2denoise.metrics.chest_belt import respiratory_variance_time

# Given that the respiratory signal is stored in `data`, the peaks in `peaks`, the troughs in `troughs`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here do you mean the respiratory signal is stored in physio ? However I think it might be less confusing to keep the name you used in the comment and use data in the function i.e. respiratory_variance_time(data, peaks, troughs, sample_rate)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also do you think it would be a good idea to show in that example how users would load their data ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, good catch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think loading the data is really dependent on the format the user is using, idk if it would be fitting here

# and the sample rate in `sample_rate`
_, rvt = respiratory_variance_time(data, peaks, troughs, sample_rate)