-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSANDI_batch_analysis.m
110 lines (93 loc) · 5.75 KB
/
SANDI_batch_analysis.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
function SANDIinput = SANDI_batch_analysis(ProjectMainFolder, Delta, smalldelta, SNR)
% Main script to perform the SANDI analysis (on one or more datasets) using machine learning, as described in Palombo M. et al. Neuroimage 2020: https://doi.org/10.1016/j.neuroimage.2020.116835
% The code assumes that data are organized in the following way:
%
% - ProjectMainFolder
% |-> - derivatives
% |--> - preprocessed
% |---> - sub-01
% |----> - ses-01
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bval
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bvec
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_mask.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_noisemap.nii.gz
% ...
% |----> - ses-n
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bval
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bvec
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_mask.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_noisemap.nii.gz
% ...
% |---> - sub-n
% |----> - ses-01
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bval
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bvec
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_mask.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_noisemap.nii.gz
% ...
% |----> - ses-n
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bval
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_dwi.bvec
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_mask.nii.gz
% |-----> sub-<>_ses-<>_acq-<>_run-<>_desc-preproc_noisemap.nii.gz
% The OUTPUT of the analysis will be stored in a new folder
% 'ProjectMainFolder -> derivatives -> SANDI_analysis -> sub-XXX -> ses-XXX -> SANDI_Output'
% for each subject and session
% NOTE: several improvements have been introduced since the original work
% on Neuroimage 2020
% These comprises:
% 1. Calculation of the Spherical Mean signal using Spherical Harmonics
% fitting (zeroth-order SH coefficient)
% 2. The training set is built in a more accurate way:
% (i) Neurite and soma signal fraction are now sampled to cover
% uniformily the simplex fneurite + fsoma <=1
% (ii) The noise is added to simulated signals in a more realistic way:
% first the noiseless signal for a random fibre direction is simulated
% using the SANDI model, then the Rician noise floor is added using the
% RiceMean function with sigma as estimated by MPPCA (noisemap), if
% provided, then Gaussian noise is added with sigma equal to the std. of
% the residuals from the SH fit, finally the spherical mean signal is computed averaging the signal over all the directions.
% (iii) The training can be done in two ways now: minimizing the MSE
% between a) the ground truth model parameters used to simulate the training
% set and the ML prediction, or b) the model parameters estimated by NLLS with Rician likelihood and the ML prediction
% Author:
% Dr. Marco Palombo
% Cardiff University Brain Research Imaging Centre (CUBRIC)
% Cardiff University, UK
% March 2024
% Email: [email protected]
% Add the path to main and support functions used for SANDI analysis
addpath(genpath(fullfile(pwd, 'functions')));
%% Initialize analysis
SANDIinput = InitializeSANDIinput(ProjectMainFolder, Delta, smalldelta, SNR); % Edit this function to change the default options of the SANDI Toolbox
disp('***** SANDI analysis using Machine Learning based fitting method ***** ')
dt = char(datetime("now"));
disp(['***** ' dt ' ***** '])
fprintf(SANDIinput.LogFileID,'***** SANDI analysis using Machine Learning based fitting method ***** \n');
fprintf(SANDIinput.LogFileID,'***** %s ***** \n', dt);
%% STEP 1 - Preprocess the data: calculate the spherical mean signal and estimate noise distributions
SANDIinput = ProcessAllDatasets(SANDIinput); % Process all the datasets, one by one
%% STEP 2 - Train the Machine Learning (ML) model
SANDIinput = TrainMachineLearningModel(SANDIinput); % trains the ML model on synthetic data
%SANDIinput =
%investigate_exchange_effectes_NEXI_SANDI_RicianNoise(SANDIinput); % Runs
%tests to estimate the bias due to unaccounted exchange between SANDI
%compartments, using NEXI model https://doi.org/10.1016/j.neuroimage.2022.119277
% Saving the Training Set
Signals_train = SANDIinput.database_train_noisy;
Params_train = SANDIinput.params_train;
Performance_train = SANDIinput.train_perf;
Bvals_train = SANDIinput.model.bvals;
Sigma_mppca_train = SANDIinput.model.sigma_mppca;
Sigma_SHresiduals_train = SANDIinput.model.sigma_SHresiduals;
mkdir(fullfile(SANDIinput.StudyMainFolder, 'Report_ML_Training_Performance'));
save(fullfile(SANDIinput.StudyMainFolder, 'Report_ML_Training_Performance','TrainingSet.mat'), 'Signals_train',...
'Params_train','Performance_train','Bvals_train', 'Sigma_mppca_train', 'Sigma_SHresiduals_train');
%% STEP 3 - SANDI fit each subject
SANDIinput = AnalyseAllDatasets(SANDIinput); % Analyse all the datasets, one by one
fclose(SANDIinput.LogFileID);
end