Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
weiym97 committed Mar 7, 2024
2 parents e620b39 + 99e48cc commit 7e35637
Show file tree
Hide file tree
Showing 48 changed files with 37,195 additions and 259 deletions.
3,029 changes: 3,029 additions & 0 deletions NiBabel.ipynb

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions evaluate_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import sys
import yaml
from osl_dynamics.config_api.batch import IndexParser, BatchTrain, batch_check

def main(index,config_path,analysis_config_path=None):
'''
This is the main function of all the analysis.
Parameters
----------
index: int
index == -1 represents post training checkk or analysis.
config_path: str
where read the config path.
analysis_config_path: str
if analysis_config_path is not None, and index == -1
then implement the analysis code.
'''
with open(config_path, 'r') as file:
config_batch = yaml.safe_load(file)
if index > -1:
if isinstance(config_batch,list):
with open(f'{config_batch[index]}batch_config.yaml','r') as file:
config = yaml.safe_load(file)
else:
index_parser = IndexParser(config_batch)
config = index_parser.parse(index)
batch_train = BatchTrain(config)
batch_train.model_train()
else:
# Step 1: batch check whether training is successful
# return the list where training is not successful
batch_check(config_batch)

# Step 2: if analysis_config_path is not None, implement the analayis code.
if analysis_config_path is not None:
pass




if __name__ == '__main__':
index = int(sys.argv[1]) - 1
config_path = sys.argv[2]

if len(sys.argv) > 3:
analysis_config_path = sys.argv[3]
else:
analysis_config_path = None

main(index,config_path,analysis_config_path)


Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "61de8eb3",
"metadata": {},
"source": [
"# Tutorial of fMRI state visualisation using workbench"
]
},
{
"cell_type": "markdown",
"id": "e8df7865",
"metadata": {},
"source": [
"Author: Yiming Wei\n",
"\n",
"Date: 22nd January 2024"
]
},
{
"cell_type": "markdown",
"id": "c2704308",
"metadata": {},
"source": [
"The aim of this tutorial is to provide a first example of fMRI data visualisation using osl-dynamics toolbox within OHBA analysis group. We will utilise the HCP workbench and tools in osl_dynamics.analysis. This tutorial should enable us (Chet, Ben, Brian and myself) to compare dynamic FC models (HMM, Dynemo and mDynemo) trained on different large-scale datasets (HCP, UKBiobank and Cam-CAN). Several prerequisites are listed below:\n",
"\n",
"1. BMRC cluster. \n",
"\n",
"We need to set up workbench properly on BMRC cluster so that `wb_command` can be run properly in the command line. The easiest way is to run `module load ConnectomeWorkbench` before starting this tutorial. (TODO: It seems to me that this command does not work properly if run in jupyter notebook or python subprocess. Why?).\n",
"P.S. There's a `setup` function in `osl_dynamics.analysis.workbench.py` to setup workbench, which requires to specify the workbench path. However, the BMRC CPUs work on two architectures (refer to this [page](https://www.medsci.ox.ac.uk/for-staff/resources/bmrc/python-on-the-bmrc-cluster) for more info), which means that the path is dependent on the actual node. (Maybe different ideas?).\n",
"\n",
"2. Brain surface map.\n",
"\n",
"By default, osl-dynamics uses ParcellationPilot. HCP S1200 map, which is available on the HCP database, might be another option.\n",
"\n",
"3. Spatial map.\n",
"Obtained from group-level spatial ICA. Should be specific to the dataset.\n",
"HCP: surface map.\n",
"UKB: was volumetric, but now surface map - I'll email Fidel.\n",
"CAM-CAN: not sure.\n",
"\n",
"4. State mean activation and FC map.\n",
"These are the parameters in the observation model. For example, if we train HMM model with K states on ICA results with N channels, the state mean activation should be a numpy array with shape K * N, the FC map should be a 3D numpy array with shape K * N * N."
]
},
{
"cell_type": "markdown",
"id": "8646ad8d",
"metadata": {},
"source": [
"We give a simple example below. Note some of the functions are in `rotation/utils.py`, which is my own function toolbox."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "bd6720c5",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import nibabel as nib\n",
"from rotation.utils import IC2surface,first_eigenvector\n",
"from osl_dynamics.analysis.workbench import render"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "ca0845c9",
"metadata": {},
"outputs": [],
"source": [
"# Specify the directories\n",
"spatial_map_dir = '../../../data/spatial_maps/groupICA_3T_HCP1200_MSMAll_d25.ica/melodic_IC.dscalar.nii'\n",
"mean_activation_dir = '../../../results_202310/HMM_ICA_25_state_8/state_means.npy'\n",
"fc_dir = '../../../results_202310/HMM_ICA_25_state_8/state_correlations.npy'\n",
"save_dir ='./'"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "09731120",
"metadata": {},
"outputs": [],
"source": [
"# Load files\n",
"spatial_surface_map = nib.load(spatial_map_dir)\n",
"state_means = np.load(mean_activation_dir)\n",
"correlations = np.load(fc_dir)\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "b773c4ef",
"metadata": {},
"outputs": [],
"source": [
"# Calculate surface map of mean activation\n",
"mean_activation_surface_map = IC2surface(spatial_surface_map,state_means.T)\n",
"mean_activation_surface_map.to_filename(f'{save_dir}mean_activation_surface_map.dscalar.nii')"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "1ed26bc5",
"metadata": {},
"outputs": [],
"source": [
"# Rank-one approximation\n",
"r1_approxs = []\n",
"for i in range(len(correlations)):\n",
" correlation = correlations[i,:,:]\n",
" r1_approxs.append(first_eigenvector(correlation))\n",
"r1_approxs = np.array(r1_approxs)\n",
"np.save(f'{save_dir}r1_approx_FC.npy', r1_approxs)\n",
"\n",
"# Calculate surface map of FC\n",
"FC_degree_surface_map = IC2surface(spatial_surface_map,r1_approxs.T)\n",
"FC_degree_surface_map.to_filename(f'{save_dir}FC_surface_map.dscalar.nii')"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "4614726b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Saving images: 100%|██████████████████████████████| 8/8 [00:09<00:00, 1.15s/it]\n",
"Saving images: 100%|██████████████████████████████| 8/8 [00:07<00:00, 1.02it/s]\n"
]
}
],
"source": [
"# Render\n",
"render(nii=f'{save_dir}mean_activation_surface_map.dscalar.nii',\n",
" save_dir=f'{save_dir}/visualisation',\n",
" gui=False,\n",
" inflation=0,\n",
" image_name='./visualisation/mean_mid_thickness',\n",
" input_cifti=True\n",
" )\n",
"render(nii=f'{save_dir}FC_surface_map.dscalar.nii',\n",
" save_dir=f'{save_dir}/visualisation',\n",
" gui=False,\n",
" inflation=0,\n",
" image_name='./visualisation/FC_mid_thickness',\n",
" input_cifti=True\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef3c0bdd",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading

0 comments on commit 7e35637

Please sign in to comment.