Skip to content

Commit d78ae2b

Browse files
Merge pull request #17 from markmikkelsen/dev
Update to v3.3.1
2 parents aa3c724 + 01d12ad commit d78ae2b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2572
-1547
lines changed

AlignSubSpectra.m

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,39 +61,39 @@
6161
% Set HERMES subexperiment indices (A, B, C, D)
6262
if MRS_struct.p.HERMES
6363
if ~MRS_struct.p.HERCULES
64-
if length(MRS_struct.p.target) == 2 && (all(strcmp(MRS_struct.p.target, {'GABAGlx','GSH'})) ...
65-
|| all(strcmp(MRS_struct.p.target, {'GABA','GSH'})))
64+
if length(MRS_struct.p.target) == 2 && (all(strcmp(MRS_struct.p.target, {'GABAGlx', 'GSH'})) ...
65+
|| all(strcmp(MRS_struct.p.target, {'GABA', 'GSH'})))
6666
switch MRS_struct.p.vendor
6767
case 'GE'
68-
if strcmpi(MRS_struct.p.seqorig,'Lythgoe')
68+
if strcmp(MRS_struct.p.seqorig, 'Lythgoe')
6969
subSpecInd = [3 2 4 1];
7070
else
7171
subSpecInd = [3 2 1 4];
7272
end
7373
case 'NIfTI'
7474
subSpecInd = [3 2 1 4];
75-
case {'Philips','Philips_data','Philips_raw'}
75+
case {'Philips', 'Philips_data', 'Philips_raw'}
7676
subSpecInd = [1 2 3 4];
77-
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
77+
case {'Siemens_dicom', 'Siemens_rda', 'Siemens_twix'}
7878
subSpecInd = [3 1 4 2];
7979
end
80-
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target, {'EtOH','GABA','GSH'}))
80+
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target, {'EtOH', 'GABA', 'GSH'}))
8181
switch MRS_struct.p.vendor
8282
case 'GE'
8383
subSpecInd = [2 1 3 4];
84-
case {'Philips','Philips_data','Philips_raw'}
84+
case {'Philips', 'Philips_data', 'Philips_raw'}
8585
error('HERMES of EtOH/GABA/GSH has not been tested for Philips data yet. Contact the Gannet team for support.');
86-
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
86+
case {'Siemens_dicom', 'Siemens_rda', 'Siemens_twix'}
8787
subSpecInd = [3 1 4 2];
8888
end
8989
end
9090
else
9191
switch MRS_struct.p.vendor
92-
case {'GE','NIfTI'}
92+
case {'GE', 'NIfTI'}
9393
subSpecInd = [3 2 1 4];
94-
case {'Philips','Philips_data','Philips_raw'}
94+
case {'Philips', 'Philips_data', 'Philips_raw'}
9595
subSpecInd = [1 4 3 2];
96-
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
96+
case {'Siemens_dicom', 'Siemens_rda', 'Siemens_twix'}
9797
subSpecInd = [3 2 1 4];
9898
end
9999
end

AlignSubSpectra_PreAlignRef.m

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,30 @@
7676
% Set HERMES subexperiment indices (A, B, C, D)
7777
if MRS_struct.p.HERMES
7878
if ~MRS_struct.p.HERCULES
79-
if length(MRS_struct.p.target) == 2 && all(strcmp(MRS_struct.p.target,{'GABAGlx','GSH'}))
79+
if length(MRS_struct.p.target) == 2 && all(strcmp(MRS_struct.p.target, {'GABAGlx', 'GSH'}))
8080
switch MRS_struct.p.vendor
8181
case 'GE'
8282
subSpecInd = [3 2 1 4];
83-
case {'Philips','Philips_data','Philips_raw'}
83+
case {'Philips', 'Philips_data', 'Philips_raw'}
8484
subSpecInd = [1 2 3 4];
85-
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
85+
case {'Siemens_twix', 'Siemens_rda', 'Siemens_dicom'}
8686
subSpecInd = [3 1 4 2];
8787
end
88-
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target,{'EtOH','GABA','GSH'}))
88+
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target, {'EtOH', 'GABA', 'GSH'}))
8989
switch MRS_struct.p.vendor
90-
case {'Philips','Philips_data','Philips_raw'}
90+
case {'Philips', 'Philips_data', 'Philips_raw'}
9191
% throw an error for now
92-
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
92+
case {'Siemens_twix', 'Siemens_rda', 'Siemens_dicom'}
9393
subSpecInd = [3 1 4 2];
9494
end
9595
end
9696
else
9797
switch MRS_struct.p.vendor
9898
case 'GE'
9999
subSpecInd = [3 2 1 4];
100-
case {'Philips','Philips_data','Philips_raw'}
100+
case {'Philips', 'Philips_data', 'Philips_raw'}
101101
subSpecInd = [1 4 3 2];
102-
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
102+
case {'Siemens_twix', 'Siemens_rda', 'Siemens_dicom'}
103103
subSpecInd = [3 2 1 4];
104104
end
105105
end

AlignUsingH2O.m

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
function [output MRS_struct] = AlignUsingH2O(input,MRS_struct)
2-
%Align to water maximum (top-right plot)
3-
A=size(input)
4-
[number index] = max(abs(input),[],2);
5-
index=index-A(1)/2;
6-
for ii=1:A(2)
7-
output(:,ii)=circshift(input(:,ii),[-A 0]);
1+
function [output, MRS_struct] = AlignUsingH2O(input, MRS_struct)
2+
% Align to residual water magnitude
3+
4+
A = size(input);
5+
[~, index] = max(abs(input),[],1);
6+
index = index - A(1)/2;
7+
8+
for ii = 1:A(2)
9+
output(:,ii) = circshift(input(:,ii), -index(ii), 1); %#ok<AGROW>
810
end
911

10-
MRS_struct.out.reject(:,MRS_struct.ii) = zeros(A(2),1);
11-
end
12+
MRS_struct.out.reject{MRS_struct.ii} = zeros(1,A(2));
13+
14+
fprintf('\n');
15+
16+
end

BaselineModel.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function F = BaselineModel(x, freq)
2+
% Function for baseline model
3+
4+
F = x(2) * (freq - x(1)) + x(3);

CalcIU.m

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
function MRS_struct = CalcIU(MRS_struct, vox, metab, ii)
2+
% Function for quantifying concentration in institutional units
3+
% Convert metabolite and water areas to institutional units
4+
% (pseudo-concentration in mmol/L)
5+
6+
TR = MRS_struct.p.TR(ii)/1e3;
7+
TE = MRS_struct.p.TE(ii)/1e3;
8+
if isfield(MRS_struct.p,'TR_water')
9+
TR_water = MRS_struct.p.TR_water(ii)/1e3;
10+
else
11+
TR_water = TR;
12+
end
13+
if isfield(MRS_struct.p,'TE_water')
14+
TE_water = MRS_struct.p.TE_water(ii)/1e3;
15+
else
16+
TE_water = TE;
17+
end
18+
PureWaterConc = 55.51*1e3; % mol/kg
19+
WaterVisibility = 0.65; % this is approx the value from Ernst, Kreis, Ross (1993, JMR)
20+
T1_Water = 1.100; % average of WM and GM, Wansapura et al. 1999 (JMRI)
21+
T2_Water = 0.095; % average of WM and GM, Wansapura et al. 1999 (JMRI)
22+
N_H_Water = 2;
23+
24+
switch metab
25+
case 'GABA'
26+
EditingEfficiency = 0.5; % For TE = 68 ms
27+
T1_Metab = 1.31; % Puts et al. 2013 (JMRI)
28+
T2_Metab = 0.088; % Edden et al. 2012 (JMRI)
29+
N_H_Metab = 2;
30+
MM = 0.45; % MM correction: fraction of GABA in GABA+ peak. (In TrypDep, 30 subjects: 55% of GABA+ was MM)
31+
% This fraction is platform- and implementation-dependent, based on length and
32+
% shape of editing pulses and ifis Henry method
33+
34+
case 'Glx'
35+
EditingEfficiency = 0.4; % determined by FID-A simulations (for TE = 68 ms)
36+
T1_Metab = 1.23; % Posse et al. 2007 (MRM)
37+
T2_Metab = 0.18; % Ganji et al. 2012 (NMR Biomed)
38+
N_H_Metab = 1;
39+
MM = 1;
40+
41+
case 'GSH'
42+
EditingEfficiency = 0.74; % At 3T based on Quantification of Glutathione in the Human Brain by MR Spectroscopy at 3 Tesla:
43+
% Comparison of PRESS and MEGA-PRESS
44+
% Faezeh Sanaei Nezhad etal. DOI 10.1002/mrm.26532, 2016
45+
T1_Metab = 0.40; % At 3T based on Doubly selective multiple quantum chemical shift imaging and
46+
% T1 relaxation time measurement of glutathione (GSH) in the human brain in vivo
47+
% In-Young Choi et al. NMR Biomed. 2013; 26: 28-34
48+
T2_Metab = 0.12; % At 3T based on the ISMRM abstract
49+
% T2 relaxation times of 18 brain metabolites determined in 83 healthy volunteers in vivo
50+
% Milan Scheidegger et al. Proc. Intl. Soc. Mag. Reson. Med. 22 (2014)
51+
N_H_Metab = 2;
52+
MM = 1;
53+
54+
case 'Lac'
55+
EditingEfficiency = 0.94; % determined by FID-A simulations (for TE = 140 ms)
56+
T1_Metab = 1.50; % Wijnen et al. 2015 (NMR Biomed)
57+
T2_Metab = 0.24; % Madan et al. 2015 (MRM) (NB: this was estimated in brain tumors)
58+
N_H_Metab = 3;
59+
MM = 1;
60+
61+
case 'EtOH'
62+
EditingEfficiency = 0.5; % assuming same as GABA for now
63+
T1_Metab = 1.31; % assuming same as GABA
64+
T2_Metab = 0.088; % assuming same as GABA
65+
N_H_Metab = 3;
66+
MM = 1;
67+
68+
case 'Cr' % 3 ppm moiety
69+
EditingEfficiency = 1; % not edited, so 1
70+
T1_Metab = (1.46 + 1.24)/2; % Mlynárik et al. 2001 (NMR in Biomed)
71+
T2_Metab = (166 + 144 + 148)/3/1e3; % Wyss et al. 2018 (MRM)
72+
N_H_Metab = 3;
73+
MM = 1;
74+
75+
case 'Cho' % 3.2 ppm moiety
76+
EditingEfficiency = 1; % not edited, so 1
77+
T1_Metab = (1.30 + 1.08)/2; % Mlynárik et al. 2001 (NMR in Biomed)
78+
T2_Metab = (218 + 222 + 274)/3/1e3; % Wyss et al. 2018 (MRM)
79+
N_H_Metab = 9;
80+
MM = 1;
81+
82+
case 'NAA' % 2 ppm moiety
83+
EditingEfficiency = 1; % not edited, so 1
84+
T1_Metab = (1.47 + 1.35)/2; % Mlynárik et al. 2001 (NMR in Biomed)
85+
T2_Metab = (343 + 263 + 253)/3/1e3; % Wyss et al. 2018 (MRM)
86+
N_H_Metab = 3;
87+
MM = 1;
88+
end
89+
90+
T1_Factor = (1 - exp(-TR_water./T1_Water)) ./ (1 - exp(-TR./T1_Metab));
91+
T2_Factor = exp(-TE_water./T2_Water) ./ exp(-TE./T2_Metab);
92+
93+
if strcmp(MRS_struct.p.vendor, 'Siemens_rda')
94+
% Factor of 2 is appropriate for averaged Siemens data (read in separately as ON and OFF)
95+
MRS_struct.out.(vox).(metab).ConcIU(ii) = (MRS_struct.out.(vox).(metab).Area(ii) ./ MRS_struct.out.(vox).water.Area(ii)) ...
96+
.* PureWaterConc .* WaterVisibility .* T1_Factor .* T2_Factor .* (N_H_Water ./ N_H_Metab) ...
97+
.* MM ./ 2 ./ EditingEfficiency;
98+
else
99+
MRS_struct.out.(vox).(metab).ConcIU(ii) = (MRS_struct.out.(vox).(metab).Area(ii) ./ MRS_struct.out.(vox).water.Area(ii)) ...
100+
.* PureWaterConc .* WaterVisibility .* T1_Factor .* T2_Factor .* (N_H_Water ./ N_H_Metab) ...
101+
.* MM ./ EditingEfficiency;
102+
end
103+
104+
105+

CheckTargets.m

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,56 @@
11
function CheckTargets(MRS_struct)
22

33
filepath = fullfile(fileparts(which(mfilename('fullpath'))), 'GannetPreInitialise.m');
4-
msg = 'Incorrect targets entered in GannetPreInitialise.m. Check spelling, allowable options and order of targets.';
4+
msg = 'Incorrect targets entered in GannetPreInitialise.m. Check spelling, allowable options, and order of targets.';
55
msg = hyperlink(['matlab: opentoline(''' filepath ''', 4, 0)'], 'Incorrect targets entered in GannetPreInitialise.m', msg);
66

77
switch num2str(length(MRS_struct.p.target))
88
case '1'
9-
if any(strcmp(MRS_struct.p.target,{'GABA','Glx','GABAGlx','GSH','Lac','EtOH'}))
10-
if MRS_struct.p.phantom && strcmp(MRS_struct.p.target,'GABAGlx')
9+
if any(strcmp(MRS_struct.p.target, {'GABA', 'Glx', 'GABAGlx', 'GSH', 'Lac', 'EtOH'}))
10+
if MRS_struct.p.phantom && strcmp(MRS_struct.p.target, 'GABAGlx')
11+
fprintf('\n');
1112
error(msg);
1213
end
1314
if MRS_struct.p.HERMES
1415
msg = 'MRS_struct.p.HERMES is set to 1 in GannetPreInitialise.m. Add a second target metabolite or set flag to 0.';
1516
msg = hyperlink(['matlab: opentoline(''' filepath ''', 4, 0)'], 'Add a second target metabolite', msg);
1617
msg = hyperlink(['matlab: opentoline(''' filepath ''', 33, 0)'], 'set flag to 0', msg);
18+
fprintf('\n');
1719
error(msg);
1820
end
1921
else
22+
fprintf('\n');
2023
error(msg);
2124
end
2225
case '2'
23-
if any([all(strcmp(MRS_struct.p.target,{'GABAGlx','GSH'})) ...
24-
all(strcmp(MRS_struct.p.target,{'GABA','GSH'})) ...
25-
all(strcmp(MRS_struct.p.target,{'Glx','GSH'})) ...
26-
all(strcmp(MRS_struct.p.target,{'Lac','GSH'}))])
27-
if MRS_struct.p.phantom && any(strcmp(MRS_struct.p.target,'GABAGlx'))
26+
if any([all(strcmp(MRS_struct.p.target, {'GABAGlx', 'GSH'})) ...
27+
all(strcmp(MRS_struct.p.target, {'GABA', 'GSH'})) ...
28+
all(strcmp(MRS_struct.p.target, {'Glx', 'GSH'})) ...
29+
all(strcmp(MRS_struct.p.target, {'Lac', 'GSH'}))])
30+
if MRS_struct.p.phantom && any(strcmp(MRS_struct.p.target, 'GABAGlx'))
31+
fprintf('\n');
2832
error(msg);
2933
end
3034
if ~MRS_struct.p.HERMES
3135
msg = 'Two target metabolites detected. MRS_struct.p.HERMES must be set to 1 in GannetPreInitialise.m.';
3236
msg = hyperlink(['matlab: opentoline(''' filepath ''', 33, 0)'], 'MRS_struct.p.HERMES must be set to 1', msg);
37+
fprintf('\n');
3338
error(msg);
3439
end
3540
else
41+
fprintf('\n');
3642
error(msg);
3743
end
3844
case '3'
39-
if all(strcmp(MRS_struct.p.target,{'EtOH','GABA','GSH'}))
45+
if all(strcmp(MRS_struct.p.target, {'EtOH', 'GABA', 'GSH'}))
4046
if ~MRS_struct.p.HERMES
4147
msg = 'Three target metabolites detected. MRS_struct.p.HERMES must be set to 1 in GannetPreInitialise.m.';
4248
msg = hyperlink(['matlab: opentoline(''' filepath ''', 33, 0)'], 'MRS_struct.p.HERMES must be set to 1', msg);
49+
fprintf('\n');
4350
error(msg);
4451
end
4552
else
53+
fprintf('\n');
4654
error(msg);
4755
end
4856
end

CoRegStandAlone/CoReg.m

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,37 @@
1717
spm_version = fileparts(which('spm'));
1818
if isempty(spm_version)
1919
msg = 'SPM not found! Please install SPM12 and make sure it is in your search path.';
20-
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12', 'SPM12', msg);
20+
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12/', 'SPM12', msg);
21+
fprintf('\n');
2122
error(msg);
2223
elseif strcmpi(spm_version(end-3:end),'spm8')
2324
msg = ['SPM8 detected. Gannet no longer supports SPM8. ' ...
2425
'Please install SPM12 and make sure it is in your search path.'];
25-
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12', 'SPM12', msg);
26+
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12/', 'SPM12', msg);
27+
fprintf('\n');
2628
error(msg);
2729
end
2830

2931
if MRS_struct.ii ~= length(struc)
30-
error('The number of NIfTI files does not match the number of MRS files processed by CoRegStandAlone.');
32+
fprintf('\n');
33+
error('The number of structural image files does not match the number of MRS files.');
3134
end
3235

3336
numscans = numel(MRS_struct.metabfile);
3437
vox = MRS_struct.p.vox(1);
3538

3639
for ii = 1:numscans
40+
41+
[~,b,c] = fileparts(MRS_struct.metabfile{ii});
42+
[~,e,f] = fileparts(struc{ii});
43+
if ii == 1
44+
fprintf('\nCo-registering voxel from %s to %s...\n', [b c], [e f]);
45+
else
46+
fprintf('Co-registering voxel from %s to %s...\n', [b c], [e f]);
47+
end
3748

49+
fname = MRS_struct.metabfile{ii};
50+
3851
% Loop over voxels if PRIAM
3952
for kk = 1:length(vox)
4053

@@ -43,19 +56,18 @@
4356

4457
case 'GE'
4558
[~,~,ext] = fileparts(struc{ii});
46-
if strcmp(ext,'.nii')
47-
MRS_struct = GannetMask_GE_nii(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
59+
if strcmp(ext, '.nii')
60+
MRS_struct = GannetMask_GE_nii(fname, struc{ii}, MRS_struct, ii, vox, kk);
4861
else
49-
MRS_struct = GannetMask_GE(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
62+
MRS_struct = GannetMask_GE(fname, struc{ii}, MRS_struct, ii, vox, kk);
5063
end
5164

5265
case 'NIfTI'
53-
MRS_struct = GannetMask_NIfTI(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
66+
MRS_struct = GannetMask_NIfTI(fname, struc{ii}, MRS_struct, ii, vox, kk);
5467

5568
case 'Philips'
56-
sparname = [MRS_struct.metabfile{ii}(1:(end-4)) MRS_struct.p.spar_string];
57-
MRS_struct = GannetMask_Philips(sparname, struc{ii}, MRS_struct, ii, vox, kk);
58-
69+
MRS_struct = GannetMask_Philips(fname, struc{ii}, MRS_struct, ii, vox, kk);
70+
5971
case 'Philips_data'
6072
if exist(MRS_struct.metabfile_sdat,'file')
6173
MRS_struct.p.vendor = 'Philips';
@@ -82,10 +94,10 @@
8294
end
8395

8496
case 'Siemens_rda'
85-
MRS_struct = GannetMask_SiemensRDA(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
97+
MRS_struct = GannetMask_SiemensRDA(fname, struc{ii}, MRS_struct, ii, vox, kk);
8698

8799
case {'Siemens_twix', 'Siemens_dicom', 'DICOM'}
88-
MRS_struct = GannetMask_SiemensTWIX(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
100+
MRS_struct = GannetMask_SiemensTWIX(fname, struc{ii}, MRS_struct, ii, vox, kk);
89101

90102
end
91103

@@ -172,11 +184,11 @@
172184
title(t, 'FontName', 'Arial', 'FontSize', 15, 'Interpreter', 'none');
173185

174186
% Gannet logo
175-
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.jpg');
187+
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.png');
176188
I = imread(Gannet_logo);
177-
axes('Position', [0.825, 0.05, 0.125, 0.125]);
189+
axes('Position', [0.85, 0.05, 0.125, 0.125]);
178190
imshow(I);
179-
text(0.9, 0, MRS_struct.version.Gannet, 'Units', 'normalized', 'FontName', 'Arial', 'FontSize', 14, 'FontWeight', 'bold', 'HorizontalAlignment', 'left');
191+
text(0.925, 0, MRS_struct.version.Gannet, 'Units', 'normalized', 'FontName', 'Arial', 'FontSize', 14, 'FontWeight', 'bold', 'HorizontalAlignment', 'left');
180192
axis off square;
181193

182194
% Gannet documentation

0 commit comments

Comments
 (0)