Skip to content

Commit

Permalink
Deploying to demo from @ 15f92d0 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Jun 12, 2024
1 parent e82c976 commit 1fc34f3
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 34 deletions.
52 changes: 26 additions & 26 deletions assets/index-xAR_-jXP.js → assets/index-kXSW97rn.js

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./niivue.css" />
<title>Niivue Neglect Predictions</title>
<script type="module" crossorigin src="./assets/index-xAR_-jXP.js"></script>
<script type="module" crossorigin src="./assets/index-kXSW97rn.js"></script>
</head>

<body>
<header>
<button id="openBtn">Open Lesion Map</button>
<input type="checkbox" id="cocCheck" checked />
<label for="cocNumber">Acute CoC Score</label>
<input style="width: 7em" type="number" id="cocNumber" min="-1" value ="0.65" max="1" />
<input style="width: 7em" type="number" id="cocNumber" min="-1" value ="0.65" max="1"/>
<button id="predictBtn">Prediction</button>
<label for="maskSlider">Mask Opacity</label>
<input
type="range"
min="1"
max="255"
value="128"
value="64"
class="slider"
id="maskSlider"
/>
Expand All @@ -33,7 +34,7 @@
class="slider"
id="lesionSlider"
/>
<button id="aboutBtn">About</button>
<button class="btn btn-success" onclick=" window.open('https://github.com/niivue/niivue-neglect','_blank')">About</button>
</header>
<main id="canvas-container">
<canvas id="gl1"></canvas>
Expand Down
Binary file added mask_noCoC.nii.gz
Binary file not shown.
6 changes: 4 additions & 2 deletions mat2nii.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
% convert model with Radial basis function kernels from matlab to NIfTI
% we could use JSON, but we want to retain precision

%fnm = 'models_5x10_diff';
fnm = 'models_noCoC';
models = load(strcat(fnm, '.mat')).models;

models = load('models_5x10_diff.mat').models;
%
v = 1;
nii(v) = numel(models);
Expand All @@ -29,4 +31,4 @@
v = v + 1;
end
end
niftiwrite(nii,'models_5x10_diff.nii')
niftiwrite(nii,strcat(fnm, '.nii'))
Binary file added models_noCoC.mat
Binary file not shown.
Binary file added models_noCoC.nii.gz
Binary file not shown.
4 changes: 2 additions & 2 deletions neglect_predict.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function neglect_predict(fnm, acuteCoC)
%Predict chronic recovery based on lesion map and acute center of
%cancellation score.
%Predict chronic neglect using lesion map and acute center of cancellation
% Assumes lesion map is normalized to 181x217x181 using SPM
%Examples
% neglect_predict; %use GUI;
% neglect_predict('M2095_lesion.nii.gz', 0.65)
Expand Down
81 changes: 81 additions & 0 deletions neglect_predict_noCoC.asv
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
function neglect_predict_noCoC(fnm)
%Predict chronic recovery based on lesion map.
% no acute CoC available (less accurate)
%Examples
% neglect_predict; %use GUI;
% neglect_predict_noCoC('M2095_lesion.nii.gz')

if nargin < 1
[p_file, p_path] = uigetfile('*.nii.gz;*.nii', 'Select lesion map');
if p_file==0
return
end
fnm = fullfile(p_path, p_file);
end
lesion = niftiread(fnm);
lesionVolTotalML = nnz(lesion) / 1000; %convert voxels to ML
mpath = fileparts(mfilename("fullpath"));
fnmMsk = fullfile(mpath, 'mask_noCoC.nii.gz');
if ~exist(fnmMsk,'file')
error('Unable to find %s', fnmMsk)
end
maskVox = uint8(niftiread(fnmMsk) > 0);
nnz(lesion(maskVox >
%PCA
fnmPCA = fullfile(mpath, 'pca_noCoC.mat');
if ~exist(fnmPCA,'file')
error('Unable to find %s', fnmPCA)
end
pca_val = load(fnmPCA).pca_val;
if size(pca_val.mu,2) ~= nnz(maskVox)
error('maskVox size does not match pca_val %d ~= %d', size(pca_val.mu,2), nnz(maskVox))
end
map_org = double(lesion(:));
mask_log = maskVox ~=0;
map = map_org(mask_log);
PC = (map'-pca_val.mu)*pca_val.coeff;
%normalize values to range 0..1
for i = 1:5
PC(i) = norm0to1(PC(i), -203.8758, 353.6057);
end
input_vector = [PC(1), PC(2), PC(3), PC(4), PC(5)];
fnmModel = fullfile(mpath, 'models_noCoC');
if ~exist(fnmPCA,'file')
error('Unable to find %s', fnmPCA)
end
models = load(fnmModel).models;
% Blank prediction-array
predictions_mdls = zeros(numel(models),1);

% For each single model (5-fold nested cross validation x 10 model repetitions)
for i = 1:numel(models)
% Extract information from the i-th model
support_vectors_i = models{i}.SVs;
coefficients_i = models{i}.sv_coef;
bias_i = -models{i}.rho;
% Define RBF kernel function
gamma_i = models{i}.Parameters(4);
rbf_kernel = @(x1, x2) exp(-gamma_i * sum((x1 - x2).^2));
% Calculate the kernel values
kernel_values_i = arrayfun(@(j) rbf_kernel(input_vector, support_vectors_i(j, :)), 1:size(support_vectors_i, 1));
% Calculate the prediction using the regression function
predictions_mdls(i) = sum(coefficients_i' .* kernel_values_i) + bias_i;
% Feature weights and bias term
% w = coefficients_i' * support_vectors_i;
% b = bias_i;
end
% Calculate mean prediction
prediction_mean = mean(predictions_mdls);
chronZ = prediction_mean * (30.1222097637568 + 1.20431863031291) - 1.20431863031291;
% calculate chronic CoC that can be interpreted by the user
chronCoC = chronZ * 0.0216 + 0.00803;
% output text
str = sprintf('Given %gml lesion, predicted chronic CoC is %g (z= %g)\n', lesionVolTotalML, chronCoC, chronZ);
disp(str);
end
function ret = norm0to1(val, mn, mx)
%return normalized 0..1, linearly interpolated min..max
range = mx - mn;
ret = (val - mn)/range;
ret = min(max(ret,0),1);
end
82 changes: 82 additions & 0 deletions neglect_predict_noCoC.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
function neglect_predict_noCoC(fnm)
%Predict chronic recovery based on lesion map.
% no acute CoC available (less accurate)
%Examples
% neglect_predict; %use GUI;
% neglect_predict_noCoC('M2095_lesion.nii.gz')

if nargin < 1
[p_file, p_path] = uigetfile('*.nii.gz;*.nii', 'Select lesion map');
if p_file==0
return
end
fnm = fullfile(p_path, p_file);
end
lesion = niftiread(fnm);
lesionVolTotalML = nnz(lesion) / 1000; %convert voxels to ML
mpath = fileparts(mfilename("fullpath"));
fnmMsk = fullfile(mpath, 'mask_noCoC.nii.gz');
if ~exist(fnmMsk,'file')
error('Unable to find %s', fnmMsk)
end
maskVox = uint8(niftiread(fnmMsk) > 0);
lesionVolMaskML = nnz(lesion(maskVox > 0)) / 1000; %convert voxels to ML
%PCA
fnmPCA = fullfile(mpath, 'pca_noCoC.mat');
if ~exist(fnmPCA,'file')
error('Unable to find %s', fnmPCA)
end
pca_val = load(fnmPCA).pca_val;
if size(pca_val.mu,2) ~= nnz(maskVox)
error('maskVox size does not match pca_val %d ~= %d', size(pca_val.mu,2), nnz(maskVox))
end
map_org = double(lesion(:));
mask_log = maskVox ~=0;
map = map_org(mask_log);
PC = (map'-pca_val.mu)*pca_val.coeff;
%normalize values to range 0..1
for i = 1:5
PC(i) = norm0to1(PC(i), -203.8758, 353.6057);
end
PC
input_vector = [PC(1), PC(2), PC(3), PC(4), PC(5)];
fnmModel = fullfile(mpath, 'models_noCoC');
if ~exist(fnmPCA,'file')
error('Unable to find %s', fnmPCA)
end
models = load(fnmModel).models;
% Blank prediction-array
predictions_mdls = zeros(numel(models),1);

% For each single model (5-fold nested cross validation x 10 model repetitions)
for i = 1:numel(models)
% Extract information from the i-th model
support_vectors_i = models{i}.SVs;
coefficients_i = models{i}.sv_coef;
bias_i = -models{i}.rho;
% Define RBF kernel function
gamma_i = models{i}.Parameters(4);
rbf_kernel = @(x1, x2) exp(-gamma_i * sum((x1 - x2).^2));
% Calculate the kernel values
kernel_values_i = arrayfun(@(j) rbf_kernel(input_vector, support_vectors_i(j, :)), 1:size(support_vectors_i, 1));
% Calculate the prediction using the regression function
predictions_mdls(i) = sum(coefficients_i' .* kernel_values_i) + bias_i;
% Feature weights and bias term
% w = coefficients_i' * support_vectors_i;
% b = bias_i;
end
% Calculate mean prediction
prediction_mean = mean(predictions_mdls);
chronZ = prediction_mean * (30.1222097637568 + 1.20431863031291) - 1.20431863031291;
% calculate chronic CoC that can be interpreted by the user
chronCoC = chronZ * 0.0216 + 0.00803;
% output text
str = sprintf('Given %gml lesion (%gml in mask), predicted chronic CoC is %g (z= %g)\n', lesionVolTotalML, lesionVolMaskML, chronCoC, chronZ);
disp(str);
end
function ret = norm0to1(val, mn, mx)
%return normalized 0..1, linearly interpolated min..max
range = mx - mn;
ret = (val - mn)/range;
ret = min(max(ret,0),1);
end
Binary file added pca_noCoC.mat
Binary file not shown.
Binary file added pca_noCoC_coeff.nii.gz
Binary file not shown.
Binary file added pca_noCoC_mu.nii.gz
Binary file not shown.

0 comments on commit 1fc34f3

Please sign in to comment.