Skip to content
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
6 changes: 6 additions & 0 deletions .codespellrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
skip = .git*,.codespellrc
check-hidden = true
ignore-regex = ((^\s*"image/\S+": "|"output_type":"stream").*|Ather SH|Hussain Ather)
ignore-words-list = numer
25 changes: 25 additions & 0 deletions .github/workflows/codespell.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Codespell configuration is within .codespellrc
---
name: Codespell

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
- name: Annotate locations with typos
uses: codespell-project/codespell-problem-matcher@v1
- name: Codespell
uses: codespell-project/actions-codespell@v2
8 changes: 4 additions & 4 deletions doc/about_whobpyt/architecture.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Code Architecture
===================================

The package is a collection of interchangable Whole Brain Models, Objective Functions Components, and Parameter Fitting Paradigms. This code base is still in alpha phase and not all combinations of these components are currently supported.
The package is a collection of interchangeable Whole Brain Models, Objective Functions Components, and Parameter Fitting Paradigms. This code base is still in alpha phase and not all combinations of these components are currently supported.

## Simplified Usage Pseudo Code

Expand Down Expand Up @@ -30,7 +30,7 @@ plot(fitting.trainingStats)
verify_model = NumPyNMM(model.params)
simulated_data = verify_model.simulate()

# Preform Analysis
# Perform Analysis
...

```
Expand All @@ -41,7 +41,7 @@ These models implement the numerical simulation of a CNMM (or modified CNMM). Th

The built in models are:

- RWWExcInb - Two variations are avaliable
- RWWExcInb - Two variations are available
- JansenRit - With Lead Field, Delays, Laplacian Connections
- Linear (needs updating)
- Robinson (Future Addition)
Expand All @@ -64,7 +64,7 @@ Paradigms for fitting model parameters.

The built in parameter fitting paradigms are:

- Model Fitting - Uses a approch to train on windowed sections of neuroimaging recordings
- Model Fitting - Uses a approach to train on windowed sections of neuroimaging recordings
- Fitting FNGFPG - A technique to run true time scale BOLD


Expand Down
2 changes: 1 addition & 1 deletion doc/about_whobpyt/background.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The Whole Brain Models are of the form of Connectome-based Neural Mass Models (C

## Neuroimaging Data

The following items may be requried (in a consistent parcellated format), depending on the CNMM model and empirical data:
The following items may be required (in a consistent parcellated format), depending on the CNMM model and empirical data:

- Structural Connectivity Matrix : For connection strengths
- Distance Matrix : For connection delays
Expand Down
4 changes: 2 additions & 2 deletions doc/about_whobpyt/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Overview

Whole Brain Modelling in PyTorch (WhoBPyT) is a Python package for fitting parameters of Whole Brain Models (WBM) to neuroimaging data. In particular, differential equation based WBMs such as Connectome-based Neural Mass Models (CNMM) can be implemented in PyTorch, and by doing so the simulated neuoimaging data can be backpropagated through time to update model parameters. This is the deep learning approach that WhoBPyT uses.

In order to use this package, a brain model, objective function, and parameter fitting paradigm must be chosen. The appropriate choices will depend on the research question and the neuroimaging data avaliable. Data must be processed ahead of time into a consistent parcellated format.
In order to use this package, a brain model, objective function, and parameter fitting paradigm must be chosen. The appropriate choices will depend on the research question and the neuroimaging data available. Data must be processed ahead of time into a consistent parcellated format.

After fitting, the result will be one or more sets of paramters. It's important to verify these parameters in another model implementation, as the models implemented in PyTorch may have default or optional moditications that deviate from the original model's dynamics.
After fitting, the result will be one or more sets of parameters. It's important to verify these parameters in another model implementation, as the models implemented in PyTorch may have default or optional moditications that deviate from the original model's dynamics.

If you use this package, please consider citing the following papers:

Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# build, prefer to use the version of the theme in this repo, not the installed
# version of the theme.
def is_development_build():
# PR builds have an interger version
# PR builds have an integer version
re_version = re.compile(r'^[\d]+$')
if 'READTHEDOCS' in os.environ:
version = os.environ.get('READTHEDOCS_VERSION', '')
Expand Down
4 changes: 2 additions & 2 deletions examples/LinearRNN_Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"# When calculating the correlation error we only use the upper or lower triangle (Functional Connectivity is symmetric)\n",
"\n",
"# The generation of this synthetic FC is not important.\n",
"# You can replace this syntetic FC with an empirical FC matrix if you like!\n",
"# You can replace this synthetic FC with an empirical FC matrix if you like!\n",
"num_regions = 40\n",
"temp = (2*torch.rand(num_regions,num_regions)-1)\n",
"temp[range(num_regions), range(num_regions)] = 1\n",
Expand Down Expand Up @@ -228,7 +228,7 @@
" #noise = torch.randn(input_length, 1, num_regions) # Create input noise to RNN\n",
" output, hn = rnn(init_state, sim_len) # Run the RNN\n",
" simFC = torch.corrcoef(torch.transpose(torch.squeeze(output, 1), 0, 1)) # Calculate the Functional Connectivity of the RNN output\n",
" simFCvec = simFC[triIdx[0], triIdx[1]] #Extract upper traingle of RNN Functional Connectivity\n",
" simFCvec = simFC[triIdx[0], triIdx[1]] #Extract upper triangle of RNN Functional Connectivity\n",
" corVal = torch.corrcoef(torch.stack((targetFCvec, simFCvec)))[0,1] # Correlated RNN FC (upper triangle) with Target FC (upper triangle)\n",
"\n",
" # Choose one of the below loss functions (NOTE: Only 1 should be uncommented)\n",
Expand Down
4 changes: 2 additions & 2 deletions examples/Multimodal_Simulation_Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"skip_trans = int(500/step_size)\n",
"\n",
"# Initial Conditions\n",
"S_E = 0.6; S_I = 0.1; x = 0.0000; f = 2.4286; v = 1.3283; q = 0.6144 # x,f,v,q might be choosen for different initial S_E\n",
"S_E = 0.6; S_I = 0.1; x = 0.0000; f = 2.4286; v = 1.3283; q = 0.6144 # x,f,v,q might be chosen for different initial S_E\n",
"init_state = torch.tensor([[S_E, S_I, x, f, v, q]]).repeat(num_regions, 1)\n",
"\n",
"# Add randomness\n",
Expand Down Expand Up @@ -298,7 +298,7 @@
"outputs": [],
"source": [
"## Written in such as way as to be able to adjust the relative importance of components that make up the objective function.\n",
"## Also, written in such a way as to be able to track and plot indiviual components losses over time. \n",
"## Also, written in such a way as to be able to track and plot individual components losses over time. \n",
"\n",
"class objectiveFunction():\n",
" def __init__(self):\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"skip_trans = int(2000/step_size)\n",
"\n",
"# Initial Conditions\n",
"S_E = 0.20; S_I = 0.05; x = 0.0000; f = 2.4286; v = 1.3283; q = 0.6144 # x,f,v,q might be choosen for different initial S_E\n",
"S_E = 0.20; S_I = 0.05; x = 0.0000; f = 2.4286; v = 1.3283; q = 0.6144 # x,f,v,q might be chosen for different initial S_E\n",
"init_state = torch.tensor([[S_E, S_I, x, f, v, q]]).repeat(num_regions, 1)\n",
"\n",
"# Add randomness\n",
Expand Down
6 changes: 3 additions & 3 deletions examples/eg002r__multimodal_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import seaborn as sns
import matplotlib.pyplot as plt

print("Is cuda avaliable?")
print("Is cuda available?")
print(torch.cuda.is_available())

device = torch.device("cpu") #Options: "cpu" or "cuda"
Expand All @@ -60,7 +60,7 @@
skip_trans = int(500/step_size)

# Initial Conditions
S_E = 0.6; S_I = 0.1; x = 0.0000; f = 2.4286; v = 1.3283; q = 0.6144 # x,f,v,q might be choosen for different initial S_E
S_E = 0.6; S_I = 0.1; x = 0.0000; f = 2.4286; v = 1.3283; q = 0.6144 # x,f,v,q might be chosen for different initial S_E
init_state = torch.tensor([[S_E, S_I, x, f, v, q]]).repeat(num_regions, 1)

# Add randomness
Expand Down Expand Up @@ -113,7 +113,7 @@
# ---------------------------------------------------
#
# Written in such as way as to be able to adjust the relative importance of components that make up the objective function.
# Also, written in such a way as to be able to track and plot indiviual components losses over time.
# Also, written in such a way as to be able to track and plot individual components losses over time.

class mmObjectiveFunction():
def __init__(self):
Expand Down
4 changes: 2 additions & 2 deletions examples/eg005r__gpu_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Evaluating CPU vs. GPU Performance
=================================

GPU Support has been added to mutiple classes in WhoBPyT. This code is for evaluating the difference in speed between CPU and GPU. The relative performance will depend on the hardware being used.
GPU Support has been added to multiple classes in WhoBPyT. This code is for evaluating the difference in speed between CPU and GPU. The relative performance will depend on the hardware being used.

This code is set to run on CPU by default, and then GPU can be tested by updating the device (See Importage Section).

Expand Down Expand Up @@ -38,7 +38,7 @@
import seaborn as sns
import matplotlib.pyplot as plt

print("Is cuda avaliable?")
print("Is cuda available?")
print(torch.cuda.is_available())

device = torch.device("cpu") #Options: "cpu" or "cuda"
Expand Down
4 changes: 2 additions & 2 deletions whobpyt/data/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def syntheticSC(numRegions, seed = None, maxConDist = 50):

Args:
numRegions (int): The number of regions in the connectome (must be an even number).
seed (int, optional): value to use as np.random.seed() for reproducability.. Defaults to None.
seed (int, optional): value to use as np.random.seed() for reproducibility.. Defaults to None.
maxConDist (int, optional): The max distance between regions such that less than this distance there can still be a connection strength. May wish to scale this based on `numRegions`. Defaults to 50.

Raises:
Expand Down Expand Up @@ -147,7 +147,7 @@ def syntheticSC(numRegions, seed = None, maxConDist = 50):
continue
dist = np.linalg.norm(np.array(loc[x]) - np.array(loc[y])) #Distance between two regions
if dist < maxConDist:
# If the distance between two regions is less than maxConDist, then connection strenth is calculated as follows
# If the distance between two regions is less than maxConDist, then connection strength is calculated as follows
con[x,y] = (maxConDist-dist)/maxConDist

return con, loc
2 changes: 1 addition & 1 deletion whobpyt/datatypes/AbstractMode.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import torch

class AbstractMode:
# Neuroimaging Modalities such as EEG and fMRI BOLD may be seperate from the NMM model
# Neuroimaging Modalities such as EEG and fMRI BOLD may be separate from the NMM model
# and implemented by inheriting from this class.
# Going forward, the recommendation is to have the modalities integrated with the model.

Expand Down
4 changes: 2 additions & 2 deletions whobpyt/datatypes/AbstractParams.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

class AbstractParams:
# This class stores the parameters used by a model. The parameters may be for the Neural Mass Model and/or Neuroimaging Modality.
# It should be useable by both the pytorch model for training and a numpy model for parameter verification.
# It should be usable by both the pytorch model for training and a numpy model for parameter verification.

def __init__(self, **kwargs):
# Define the parameters using the par data structure
pass

def getFittedNames(self):
# Returns a named list of paramters that are being fitted
# Returns a named list of parameters that are being fitted
# Assumes the par datastructure is being used for parameters

fp = []
Expand Down
2 changes: 1 addition & 1 deletion whobpyt/datatypes/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def reset(self):

def appendLoss(self, newValue):
"""
Append Trainig Loss
Append Training Loss

Parameters
-----------
Expand Down
10 changes: 5 additions & 5 deletions whobpyt/depr/fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(self, model, ts, num_epoches, cost):
ts: array with num_tr x node_size
empirical EEG time-series
num_epoches: int
the times for repeating trainning
the times for repeating training
"""
self.model = model
self.num_epoches = num_epoches
Expand Down Expand Up @@ -84,7 +84,7 @@ def train(self, u=0):
hE = torch.tensor(np.random.uniform(state_lb, state_ub, (self.model.node_size, delays_max)),
dtype=torch.float32)

# define masks for geting lower triangle matrix
# define masks for getting lower triangle matrix
mask = np.tril_indices(self.model.node_size, -1)
mask_e = np.tril_indices(self.model.output_size, -1)

Expand Down Expand Up @@ -142,7 +142,7 @@ def train(self, u=0):

next_batch, hE_new = self.model(external, X, hE)

# Get the batch of emprical EEG signal.
# Get the batch of empirical EEG signal.
ts_batch = torch.tensor(
(eeg.T[i_batch * self.model.batch_size:(i_batch + 1) * self.model.batch_size, :]).T,
dtype=torch.float32)
Expand Down Expand Up @@ -298,7 +298,7 @@ def test(self, x0, he0, base_batch_num, u=0):

# placeholders for model parameters

# define mask for geting lower triangle matrix
# define mask for getting lower triangle matrix
mask = np.tril_indices(self.model.node_size, -1)
mask_e = np.tril_indices(self.model.output_size, -1)

Expand Down Expand Up @@ -421,4 +421,4 @@ def test_realtime(self, num_batches):
tmp_ls = getattr(self.output_sim, name + '_test')
setattr(self.output_sim, name + '_test', np.concatenate(tmp_ls, axis=1))
else:
print("only WWD model for the test_realtime funcion")
print("only WWD model for the test_realtime function")
18 changes: 9 additions & 9 deletions whobpyt/depr/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def forward(self, init_state, sim_len, useDelays = False, useLaplacian = False,
if(useLaplacian & (not useDelays)):
# WARNING: This has not been tested

# NOTE: We are acutally using the NEGATIVE Laplacian
# NOTE: We are actually using the NEGATIVE Laplacian

Laplacian_diagonal = -torch.diag(torch.sum(self.Con_Mtx, axis=1)) #Con_Mtx should be normalized, so this should just add a diagonal of -1's
S_E_laplacian = torch.matmul(self.Con_Mtx + Laplacian_diagonal, S_E)
Expand All @@ -236,7 +236,7 @@ def forward(self, init_state, sim_len, useDelays = False, useLaplacian = False,
if(useDelays & useLaplacian):
# WARNING: This has not been tested

# NOTE: We are acutally using the NEGATIVE Laplacian
# NOTE: We are actually using the NEGATIVE Laplacian

Laplacian_diagonal = -torch.diag(torch.sum(self.Con_Mtx, axis=1)) #Con_Mtx should be normalized, so this should just add a diagonal of -1's

Expand Down Expand Up @@ -393,7 +393,7 @@ def __init__(self):
#Starting Condition
#x = 1 # vasodilatory signal
#f = 1 # inflow
#v = 1 # blood volumne
#v = 1 # blood volume
#q = 1 # deoxyhemoglobin content

class BOLD_Layer(torch.nn.Module):
Expand Down Expand Up @@ -429,7 +429,7 @@ def __init__(self, num_regions, params, useBC = False):
#Starting Condition
#x = 1 # vasodilatory signal
#f = 1 # inflow
#v = 1 # blood volumne
#v = 1 # blood volume
#q = 1 # deoxyhemoglobin content

#############################################
Expand Down Expand Up @@ -950,7 +950,7 @@ def __init__(self, model_name, **kwargs):
class RNNJANSEN(torch.nn.Module):
"""
A module for forward model (JansenRit) to simulate a batch of EEG signals
Attibutes
Attributes
---------
state_size : int
the number of states in the JansenRit model
Expand Down Expand Up @@ -1136,7 +1136,7 @@ def forward(self, input, hx, hE):
self.delays = (self.dist / (conduct_lb * con_1 + m(self.mu))).type(torch.int64)
# print(torch.max(self.delays), self.delays.shape)

# placeholder for the updated corrent state
# placeholder for the updated current state
current_state = torch.zeros_like(hx)

# placeholders for output BOLD, history of E I x f v and q
Expand Down Expand Up @@ -1331,7 +1331,7 @@ def h_tf(a, b, d, z):
class RNNWWD(torch.nn.Module):
"""
A module for forward model (WWD) to simulate a batch of BOLD signals
Attibutes
Attributes
---------
state_size : int
the number of states in the WWD model
Expand Down Expand Up @@ -1516,7 +1516,7 @@ def forward(self, external, hx, hE):
l_s = torch.tensor(np.zeros((1, 1)), dtype=torch.float32)


# placeholder for the updated corrent state
# placeholder for the updated current state
current_state = torch.zeros_like(hx)

# placeholders for output BOLD, history of E I x f v and q
Expand Down Expand Up @@ -1638,7 +1638,7 @@ class WWD_np( ):
"""
A module for forward model (WWD) to simulate a batch of BOLD signals

Attibutes
Attributes
---------
state_size : int
the number of states in the WWD model
Expand Down
2 changes: 1 addition & 1 deletion whobpyt/depr/objective.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def calcLoss(self, simData):
class functionalConnectivityLoss():
# Right now this fit's to a fixed "empirical" FC matrix, but in the future
# will change to fit to a time series of FC
# Furthermore, for computational effeciency a batch of overlapping FC's will
# Furthermore, for computational efficiency a batch of overlapping FC's will
# be calculated to create a kind of mini-batch back propagation

def __init__(self, num_regions, varIdx, targetValue = None, empiricalData = None):
Expand Down
2 changes: 1 addition & 1 deletion whobpyt/functions/arg_type_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
def method_arg_type_check(method_obj, exclude = []):
"""
Takes the method object of a given function (e.g. RNNJANSEN) and checks that the passed arguments abide by their
expected data types. If there is a discrepency, raises a ValueError.
expected data types. If there is a discrepancy, raises a ValueError.

Optional argument: exclude
List of strings containing argument names to exclude from the check (e.g. ['step_size', 'params']).
Expand Down
2 changes: 1 addition & 1 deletion whobpyt/models/BOLD/BOLD.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def createIC(self, ver):
#Starting Condition
#x = 1 # vasodilatory signal
#f = 1 # inflow
#v = 1 # blood volumne
#v = 1 # blood volume
#q = 1 # deoxyhemoglobin content
pass

Expand Down
Loading