Skip to content
This repository was archived by the owner on Oct 9, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,33 @@ The code is licensed under the [GNU GPL v3 license](http://www.gnu.org/licenses/
**Feel free to reach out for help with real-world applications.**
Feedback is much appreciated through [issues](https://github.com/DynamicsAndNeuralSystems/pyspi/issues), or [pull requests](https://github.com/DynamicsAndNeuralSystems/pyspi/pulls).

## Acknowledgement
## Acknowledgement :+1:

If you use this code, please cite the following preprint:
If you use this software, please read and cite this article:

Oliver M. Cliff, Annie G. Bryant, Joseph T. Lizier, Naotsugu Tsuchiya, Ben D. Fulcher, "Unifying Pairwise Interactions in Complex Dynamics," _arXiv_ preprint, [arXiv:2201.11941](https://arxiv.org/abs/2201.11941) (2023).
- 📗 O.M. Cliff, A.G. Bryant, J.T. Lizier, N. Tsuchiya, B.D. Fulcher [Unifying pairwise interactions in complex dynamics](https://doi.org/10.1038/s43588-023-00519-x), _Nature Computational Science_ (2023).

Note that [preprint](https://arxiv.org/abs/2201.11941) and [free-to-read](https://rdcu.be/dn3JB) versions of this article are available.

## Getting Started

See the [documentation](https://pyspi-toolkit.readthedocs.io/en/latest/) for installing and setting up _pyspi_.
Once you're done, you can learn how to use the package by checking out the:

- [Simple demo](https://github.com/olivercliff/pyspi/blob/main/demos/simple_demo.py)
- [Tutorial (finance: stock price time series)](https://github.com/olivercliff/pyspi/blob/main/demos/tutorial.ipynb)
- [Simple demo](https://github.com/DynamicsAndNeuralSystems/pyspi/blob/main/demos/simple_demo.py)
- [Tutorial (finance: stock price time series)](https://github.com/DynamicsAndNeuralSystems/pyspi/blob/main/demos/tutorial.ipynb)
- [Tutorial (neuroimaging: fMRI time series)](https://github.com/anniegbryant/CNS_2022/blob/main/pyspi_tutorial/CNS2022_pyspi_demo.ipynb).

If you have access to a PBS cluster and are processing MTS with many processes (or are analyzing many MTS), then you may find the [_pyspi_ distribute](https://github.com/DynamicsAndNeuralSystems/pyspi-distribute) repository helpful.

If your dataset is large (containing many processes and/or observations), you can use a pre-configured set of reduced statistics or create your own subsets (cf. the [documentation guide](https://pyspi-toolkit.readthedocs.io/en/latest/advanced.html#using-a-reduced-spi-set)).
If your dataset is large (containing many processes and/or observations), you may wish to start with a pre-configured set of reduced statistics or create your own subsets (cf. the [documentation guide](https://pyspi-toolkit.readthedocs.io/en/latest/advanced.html#using-a-reduced-spi-set)).

### Distributed computation on a high-performance computing (HPC) cluster

Alternatively, _pyspi_ can be configured to distribute individual jobs across an HPC cluster using the [pyspi-distribute](https://github.com/DynamicsAndNeuralSystems/pyspi-distribute) repository.
We provide some [benchmark estimates](https://pyspi-toolkit.readthedocs.io/en/latest/faq.html#how-long-does-pyspi-take-to-run) for how long a given MTS dataset will take to compute across a variety of parameters for HPC resource request purposes.
For more information about this functionality, check out the [repository readme](https://github.com/DynamicsAndNeuralSystems/pyspi-distribute#distribute-pyspi-jobs-across-a-pbs-cluster) and the [_pyspi_ documentation](https://pyspi-toolkit.readthedocs.io/en/latest/index.html).


## Other highly comparative toolboxes

Expand All @@ -43,4 +52,4 @@ If your dataset is large (containing many processes and/or observations), you ca

## SPI Wishlist

As _pyspi_ is under active development, we are always open to suggestions for new SPIs to be added via the [projects tab](https://github.com/DynamicsAndNeuralSystems/pyspi/projects) in this repo.
As _pyspi_ is under active development, we are always open to suggestions for new SPIs to be added via the [projects tab](https://github.com/DynamicsAndNeuralSystems/pyspi/projects) in this repo.
18 changes: 9 additions & 9 deletions docs/source/_build/html/usage.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->

<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
Expand All @@ -19,10 +19,10 @@
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Advanced" href="advanced.html" />
<link rel="prev" title="Welcome to PySPI’s documentation!" href="index.html" />
<link rel="prev" title="Welcome to PySPI’s documentation!" href="index.html" />
</head>

<body class="wy-body-for-nav">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
Expand Down Expand Up @@ -74,7 +74,7 @@
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">

<section id="usage">
<h1>Usage<a class="headerlink" href="#usage" title="Permalink to this headline"></a></h1>
<section id="pre-installation">
Expand All @@ -95,8 +95,8 @@ <h2>Pre-installation<a class="headerlink" href="#pre-installation" title="Permal
</section>
<section id="installation">
<h2>Installation<a class="headerlink" href="#installation" title="Permalink to this headline"></a></h2>
<p>Next, download or clone the <a class="reference external" href="https://github.com/olivercliff/pyspi">latest version</a> from GitHub, unpack and install:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>git clone https://github.com/olivercliff/pyspi.git
<p>Next, download or clone the <a class="reference external" href="https://github.com/DynamicsAndNeuralSystems/pyspi">latest version</a> from GitHub, unpack and install:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>git clone https://github.com/DynamicsAndNeuralSystems/pyspi.git
<span class="gp">$ </span><span class="nb">cd</span> pyspi
<span class="gp">$ </span>pip install .
</pre></div>
Expand Down Expand Up @@ -162,7 +162,7 @@ <h2>Getting Started<a class="headerlink" href="#getting-started" title="Permalin
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.


</footer>
</div>
Expand All @@ -173,7 +173,7 @@ <h2>Getting Started<a class="headerlink" href="#getting-started" title="Permalin
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>

</body>
</html>
</html>
45 changes: 12 additions & 33 deletions docs/source/advanced.rst
Original file line number Diff line number Diff line change
@@ -1,46 +1,25 @@
Advanced
========

The Data object
---------------------

The MTS data is contained within the :class:`~pyspi.data.Data` object, along with preprocessed properties of the MTS that allows us to efficiently compute the methods.
If you want more control over how the MTS are treated upon input, you can directly instantiate a :class:`~pyspi.data.Data` object for inputting to the calculator:

.. code-block::

from pyspi.data import Data
from pyspi.calculator import Calculator
import numpy as np

M = 10 # Number of processes
T = 1000 # Number of observations

z = np.random.rand(M,T)

# The dim_order argument specifies which dimension is a process (p) and an observation (s).
# The normalise argument specifies if we should z-score the data.
dataset = Data(data=z,dim_order='ps',normalise=False)

calc = Calculator(dataset=dataset)


Using a reduced SPI set
-----------------------

The :class:`~pyspi.calculator.Calculator` object computes 283 SPIs by default, but you may only be interested in a subset of these.
We provide three pre-configured reduced SPI subsets that you may wish to try:
We provide three pre-configured reduced SPI subsets that you may wish to try: `fast`, `sonnet`, and `fabfour`.

* :code:`fast`: Most SPIs (excluding those that are computationally expensive)
* :code:`sonnet` - 14 SPIs, one from each of the data-driven clusters as described in `Cliff et al. (2023) <https://arxiv.org/abs/2201.11941>`_
* :code:`fabfour` - 4 SPIs that are simple and computationally efficient: Pearson correlation, Spearman correlation, directed information with a Gaussian density estimator, and the power envelope correlation.
- :code:`fast`: Most SPIs (excluding those that are computationally expensive)
- :code:`sonnet` - 14 SPIs, one from each of the data-driven clusters as described in `Cliff et al. (2023) <https://doi.org/10.1038/s43588-023-00519-x>`_
- :code:`fabfour` - 4 SPIs that are simple and computationally efficient: Pearson correlation, Spearman correlation, directed information with a Gaussian density estimator, and the power envelope correlation.

You may specify any one of these subsets when you instantiate the :code:`Calculator` object:
Users can specify any of these three pre-configured subsets by passing in the corresponding argument in the :code:`Calculator` object as follows:

.. code-block::

from pyspi.calculator import Calculator
calc = Calculator(dataset=dataset, subset='sonnet')
from pyspi import Calculator
calc = Calculator(subset='fast') # or calc = Calculator(subset='sonnet') or calc = Calculator(subset='fabfour')




Alternatively, if you would like to use your own bespoke set of SPIs, you can copy a version of the :code:`config.yaml` file to your workspace and edit it to remove any SPIs that you would not like the :code:`Calculator` to compute.
First, copy the :code:`config.yaml` file to your workspace:
Expand Down Expand Up @@ -72,10 +51,10 @@ Now, when you instantiate the calculator, instead of using the default :code:`co
Then use the calculator as normal (see :ref:`Usage`).

.. note::
We have provided a detailed list of many of the statistics included in this toolkit (and the configuration file) in the Supplementary Material of our `preprint <https://arxiv.org/abs/2201.11941>`_, and will include an up-to-date list of statistics in this documentation shortly.
We have provided a detailed list of many of the statistics included in this toolkit (and the configuration file) in the Supplementary Material of our `article <https://doi.org/10.1038/s43588-023-00519-x>`_, and will include an up-to-date list of statistics in this documentation shortly.
However, if you have any questions about a particular implementation, do not hesitate to raise an issue in the `github repo <https://github.com/DynamicsAndNeuralSystems/pyspi>`_ for any assistance.

Using the toolkit without Octave
--------------------------------

If you do not wish to first install Octave before using the toolkit, remove the yaml entries for :code:`integrated_information` in the :code:`config.yaml` file (see :ref:`Using a reduced SPI set`).
If you do not wish to first install Octave before using the toolkit, remove the yaml entries for :code:`integrated_information` in the :code:`config.yaml` file (see :ref:`Using a reduced SPI set`).
13 changes: 2 additions & 11 deletions docs/source/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,9 @@ FAQ
How many SPIs should I measure for my dataset?
**********************

The :class:`~pyspi.calculator.Calculator` object computes 283 SPIs by default (see the [Supplementary information](https://www.nature.com/articles/s43588-023-00519-x#Sec15) from the _pyspi_ publication for a detailed description of all 283 SPIs).
When first starting out, we recommend that users start with a smaller subset of available SPIs first, so they get a sense of computation times and working with the output in a lower-dimensional space.
Users have the option to pass in a customized configuration `.yaml` file as described in the `Using a reduced SPI set <https://pyspi-toolkit.readthedocs.io/en/latest/advanced.html#using-a-reduced-spi-set>`_ documentation.

Alternatively, we provide two pre-defined subsets of SPIs that can serve as good starting points: `sonnet` and `fast`.
The `sonnet` subset includes 14 SPIs selected to represent the 14 modules identified through hierarchical clustering in the original paper.
To retain as many SPIs as possible while minimizing computation time, we also offer a `fast` option that omits the most computationally expensive SPIs.
Either SPI subset can be toggled by setting the corresponding flag in the `Calculator()` function call as follows:

.. code-block::

from pyspi import Calculator
calc = Calculator(sonnet=True) # or calc = Calculator(fast=True)
Users have the option to pass in a pre-defined SPI subset or define their own subset with a customized configuration `.yaml` file as described in the `Using a reduced SPI set <https://pyspi-toolkit.readthedocs.io/en/latest/advanced.html#using-a-reduced-spi-set>`_ documentation.


How long does `pyspi` take to run?
Expand Down
Binary file added docs/source/img/pyspi_DI_figure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ After `installing conda <https://docs.conda.io/projects/conda/en/latest/user-gui
Installation
------------

Download or clone the `latest version of pyspi <https://github.com/olivercliff/pyspi>`_ from GitHub, unpack and install:
Download or clone the `latest version of pyspi <https://github.com/DynamicsAndNeuralSystems/pyspi>`_ from GitHub, unpack and install:

.. code-block:: console

$ git clone https://github.com/olivercliff/pyspi.git
$ git clone https://github.com/DynamicsAndNeuralSystems/pyspi
$ cd pyspi
$ pip install .

Expand Down
40 changes: 39 additions & 1 deletion docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,42 @@ For instance, the following code will extract the covariance matrix computed wit

print(calc.table['cov_EmpiricalCovariance'])

The identifiers for many of the statistics are outlined in the Supplementary Material of our `preprint <https://arxiv.org/abs/2201.11941>`_.
The identifiers for many of the statistics are outlined in the Supplementary Material of our `paper <https://doi.org/10.1038/s43588-023-00519-x>`_.

The Data object
---------------------

The MTS data is contained within the :class:`~pyspi.data.Data` object, along with preprocessed properties of the MTS that allows us to efficiently compute the methods.
If you want more control over how the MTS are treated upon input, you can directly instantiate a :class:`~pyspi.data.Data` object for inputting to the calculator:

.. code-block::

from pyspi.data import Data
from pyspi.calculator import Calculator
import numpy as np

M = 10 # Number of processes
T = 1000 # Number of observations

z = np.random.rand(M,T)

# The dim_order argument specifies which dimension is a process (p) and an observation (s).
# The normalise argument specifies if we should z-score the data.
dataset = Data(data=z,dim_order='ps',normalise=False)

calc = Calculator(dataset=dataset)


Working with directed statistics
---------------------

Some of the SPIs are directed, meaning that the value from process A to process B will be computed separately to the value from process B to process A.
This generally results in asymmetric matrices, which can be useful for analysing the directionality of interactions.
Consider the SPI :code:`di_gaussian`, which measures the directed information from process A to process B using a Gaussian density estimator, and an MTS consisting of three processes (here reflecting three brain regions).
The resulting :code:`calc.table` object will contain a 3x3 matrix, where the entry :code:`calc.table['di_gaussian'][0,1]` will be the directed information from process 0 to process 1.
The rows in this table reflect sources while the columns in this table reflect targets, as schematically depicted below:

.. figure:: img/pyspi_DI_figure.png
:width: 550px
:height: 300px
:alt: Schematic depicting how to interpret the resulting calc.table object for a directed SPI, like di_gaussian.
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@
'data/forex.npy']},
include_package_data=True,
version='0.4.0',
description='Network analysis for time series',
description='Library for pairwise analysis of time series data.',
author='Oliver M. Cliff',
author_email='[email protected]',
url='https://github.com/olivercliff/pyspi',
url='https://github.com/DynamicsAndNeuralSystems/pyspi',
long_description=long_description,
classifiers=[
"Programming Language :: Python",
Expand Down