Examples¶
Installation¶
To install dmd, simply run the following command (we advise you to do so in your favorite virtual environment)
pip install nidmd
Importing the adequate modules¶
For this tutorial, we will load both the Decomposition module as well as the different plotting classes.
[1]:
import plotly.io as pio
pio.renderers.default = "notebook"
[2]:
import numpy as np
import pandas as pd
from nidmd import Decomposition, TimeSeries, Radar, TimePlot, Brain, Spectre, Atlas
Loading data into a Decomposition instance¶
[3]:
# Supported filetypes: `.csv` and `.mat`
# Load from MATLAB file
dcp = Decomposition(filenames='../nidmd/tests/data/schaefer_test.mat')
[4]:
# You can also do the extraction yourself if your filetype is not supported
# Here is an example with a `.csv` file (even though they are supported)
matrix = np.genfromtxt('../nidmd/tests/data/glasser.csv', delimiter=',')
dcp_ = Decomposition(data=matrix, sampling_time=0.72)
Decomposition is a child of TimeSeries¶
[5]:
# The input files must follow certain restrictions to generate the wanted output
# One of them is that they must adhere to one of the supported cortical parcellation atlasses
# If this is not the case, a ImportError will be raised
# You can still perform the DMD, using Decomposition's parent `TimeSeries`
# Some fake data
data = np.random.rand(10, 500)
ts = TimeSeries(data=data, sampling_time=1.5)
dmd = ts.dmd()
dmd.keys(), dmd['values'][:5]
[5]:
(dict_keys(['values', 'vectors', 'indices', 'A', 'activity']),
array([ 0.19149021+0.j , -0.13420224+0.j ,
-0.08280084+0.08482337j, -0.08280084-0.08482337j,
0.1291952 +0.j ]))
Fetching the Atlas¶
[6]:
# If the atlas is identified, you can read corresponding data as well
print(dcp.atlas), list(dcp.atlas.networks.keys())
schaefer Atlas of size 400
[6]:
(None, ['DA', 'VA', 'SM', 'VIS', 'LIM', 'FP', 'DMN'])
[7]:
# You can even access the 3D annot file projected into 2D coordinates used for plotting the cortical surfaces
dcp.atlas.coords_2d.head()
[7]:
| atlas | hemi | side | .long | .lat | .id | .subid | .roi | .L1 | .L3 | .order | region | label | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | schaefer7 | left | lateral | 77.9824 | 37.6632 | 1 | 1 | 1 | 1 | 1 | 1 | NaN | NaN |
| 1 | schaefer7 | left | lateral | 77.9378 | 37.1861 | 1 | 1 | 1 | 1 | 1 | 2 | NaN | NaN |
| 2 | schaefer7 | left | lateral | 78.4289 | 36.3179 | 1 | 1 | 1 | 1 | 1 | 3 | NaN | NaN |
| 3 | schaefer7 | left | lateral | 79.4202 | 34.9920 | 1 | 1 | 1 | 1 | 1 | 4 | NaN | NaN |
| 4 | schaefer7 | left | lateral | 80.3509 | 34.1146 | 1 | 1 | 1 | 1 | 1 | 5 | NaN | NaN |
Retrieving information from a Decomposition instance¶
[8]:
# Let's say you are interested in the eigen-values of the eigen-decomposition of the auto-regressive model's matrix
# You can fetch the np.array directly
# All available attributes are defined in the documentation in the constructor 'Yields'
dcp.eig_val[:5]
# Feel free to hack in!
[8]:
array([ 0.56413247+0.3190115j, 0.56413247-0.3190115j,
-0.03441946+0.6527684j, -0.03441946-0.6527684j,
-0.50794325+0.4097298j])
[9]:
# The most important is probably the Pandas DataFrame that is computed
# It contains all modes and their relevant information
dcp.df.head()
[9]:
| mode | value | intensity | damping_time | period | conjugate | strength_real | strength_imag | activity | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | -0.034419+0.652768j | [(-0.012655198391238085-0.03277613608089217j),... | 2.352141 | 3.870205 | True | [0.026587127219590664, 0.02569015367883381, 0.... | [0.028033854040225306, 0.030361969400318163, 0... | [-3.964237936448096, -0.251766507342133, 2.547... |
| 1 | 2 | -0.507943+0.409730j | [(-0.021107785329405007-0.0540421133813644j), ... | 2.343056 | 2.551223 | True | [0.029381687031751896, 0.027642749359050808, 0... | [0.028208494658742225, 0.025607545866732896, 0... | [-1.4151377929253224, 1.6512486466854643, -0.7... |
| 2 | 3 | 0.564132+0.319012j | [(0.013203698555521668+0.039968652566025095j),... | 2.305561 | 12.208462 | True | [0.03006469800851769, 0.03480270558702691, 0.0... | [0.02730288016966112, 0.025318438695252375, 0.... | [-3.178872648091539, -3.579534391558363, -1.19... |
| 3 | 4 | -0.605041+0.209460j | [(0.02940859182897382+0.03819766844681426j), (... | 2.242842 | 2.237351 | True | [0.027911581293748263, 0.03075186173081999, 0.... | [0.03114029955310492, 0.032727595208755296, 0.... | [-3.6512764245617757, 3.709499255149587, -2.58... |
| 4 | 5 | -0.268493-0.575713j | [(0.008964801301731842-0.00868364630630098j), ... | 2.203870 | 3.130361 | True | [0.02603063026483108, 0.0297353883053019, 0.02... | [0.02936413970518554, 0.0317265066676885, 0.02... | [-0.43901115692259696, 4.161516719307512, -0.2... |
Plotting¶
[10]:
# By following the documentation and providing `dcp.df`, the calls to the plotting classes are straightforward
Radar(dcp.df, dcp.atlas).figure(imag=True, amount=6)
[11]:
# Let us plot Mode no. 2 with an specific matplotlib colormap
# I urge you to use Diverging colormaps for an accurate representation of region activity correlation
Brain(dcp_.df, 2, dcp_.atlas.coords_2d).figure(colormap='PiYG')
[12]:
Spectre(dcp_.df, ['Group 1']).figure()
[13]:
TimePlot(dcp_.df).figure(amount=3)