Skip to content

Commit

Permalink
Merge pull request #17 from markmikkelsen/dev
Browse files Browse the repository at this point in the history
Update to v3.3.1
  • Loading branch information
markmikkelsen authored Mar 14, 2023
2 parents aa3c724 + 01d12ad commit d78ae2b
Show file tree
Hide file tree
Showing 88 changed files with 2,572 additions and 1,547 deletions.
22 changes: 11 additions & 11 deletions AlignSubSpectra.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,39 +61,39 @@
% Set HERMES subexperiment indices (A, B, C, D)
if MRS_struct.p.HERMES
if ~MRS_struct.p.HERCULES
if length(MRS_struct.p.target) == 2 && (all(strcmp(MRS_struct.p.target, {'GABAGlx','GSH'})) ...
|| all(strcmp(MRS_struct.p.target, {'GABA','GSH'})))
if length(MRS_struct.p.target) == 2 && (all(strcmp(MRS_struct.p.target, {'GABAGlx', 'GSH'})) ...
|| all(strcmp(MRS_struct.p.target, {'GABA', 'GSH'})))
switch MRS_struct.p.vendor
case 'GE'
if strcmpi(MRS_struct.p.seqorig,'Lythgoe')
if strcmp(MRS_struct.p.seqorig, 'Lythgoe')
subSpecInd = [3 2 4 1];
else
subSpecInd = [3 2 1 4];
end
case 'NIfTI'
subSpecInd = [3 2 1 4];
case {'Philips','Philips_data','Philips_raw'}
case {'Philips', 'Philips_data', 'Philips_raw'}
subSpecInd = [1 2 3 4];
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
case {'Siemens_dicom', 'Siemens_rda', 'Siemens_twix'}
subSpecInd = [3 1 4 2];
end
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target, {'EtOH','GABA','GSH'}))
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target, {'EtOH', 'GABA', 'GSH'}))
switch MRS_struct.p.vendor
case 'GE'
subSpecInd = [2 1 3 4];
case {'Philips','Philips_data','Philips_raw'}
case {'Philips', 'Philips_data', 'Philips_raw'}
error('HERMES of EtOH/GABA/GSH has not been tested for Philips data yet. Contact the Gannet team for support.');
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
case {'Siemens_dicom', 'Siemens_rda', 'Siemens_twix'}
subSpecInd = [3 1 4 2];
end
end
else
switch MRS_struct.p.vendor
case {'GE','NIfTI'}
case {'GE', 'NIfTI'}
subSpecInd = [3 2 1 4];
case {'Philips','Philips_data','Philips_raw'}
case {'Philips', 'Philips_data', 'Philips_raw'}
subSpecInd = [1 4 3 2];
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
case {'Siemens_dicom', 'Siemens_rda', 'Siemens_twix'}
subSpecInd = [3 2 1 4];
end
end
Expand Down
16 changes: 8 additions & 8 deletions AlignSubSpectra_PreAlignRef.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,30 +76,30 @@
% Set HERMES subexperiment indices (A, B, C, D)
if MRS_struct.p.HERMES
if ~MRS_struct.p.HERCULES
if length(MRS_struct.p.target) == 2 && all(strcmp(MRS_struct.p.target,{'GABAGlx','GSH'}))
if length(MRS_struct.p.target) == 2 && all(strcmp(MRS_struct.p.target, {'GABAGlx', 'GSH'}))
switch MRS_struct.p.vendor
case 'GE'
subSpecInd = [3 2 1 4];
case {'Philips','Philips_data','Philips_raw'}
case {'Philips', 'Philips_data', 'Philips_raw'}
subSpecInd = [1 2 3 4];
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
case {'Siemens_twix', 'Siemens_rda', 'Siemens_dicom'}
subSpecInd = [3 1 4 2];
end
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target,{'EtOH','GABA','GSH'}))
elseif length(MRS_struct.p.target) == 3 && all(strcmp(MRS_struct.p.target, {'EtOH', 'GABA', 'GSH'}))
switch MRS_struct.p.vendor
case {'Philips','Philips_data','Philips_raw'}
case {'Philips', 'Philips_data', 'Philips_raw'}
% throw an error for now
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
case {'Siemens_twix', 'Siemens_rda', 'Siemens_dicom'}
subSpecInd = [3 1 4 2];
end
end
else
switch MRS_struct.p.vendor
case 'GE'
subSpecInd = [3 2 1 4];
case {'Philips','Philips_data','Philips_raw'}
case {'Philips', 'Philips_data', 'Philips_raw'}
subSpecInd = [1 4 3 2];
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
case {'Siemens_twix', 'Siemens_rda', 'Siemens_dicom'}
subSpecInd = [3 2 1 4];
end
end
Expand Down
23 changes: 14 additions & 9 deletions AlignUsingH2O.m
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
function [output MRS_struct] = AlignUsingH2O(input,MRS_struct)
%Align to water maximum (top-right plot)
A=size(input)
[number index] = max(abs(input),[],2);
index=index-A(1)/2;
for ii=1:A(2)
output(:,ii)=circshift(input(:,ii),[-A 0]);
function [output, MRS_struct] = AlignUsingH2O(input, MRS_struct)
% Align to residual water magnitude

A = size(input);
[~, index] = max(abs(input),[],1);
index = index - A(1)/2;

for ii = 1:A(2)
output(:,ii) = circshift(input(:,ii), -index(ii), 1); %#ok<AGROW>
end

MRS_struct.out.reject(:,MRS_struct.ii) = zeros(A(2),1);
end
MRS_struct.out.reject{MRS_struct.ii} = zeros(1,A(2));

fprintf('\n');

end
4 changes: 4 additions & 0 deletions BaselineModel.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function F = BaselineModel(x, freq)
% Function for baseline model

F = x(2) * (freq - x(1)) + x(3);
105 changes: 105 additions & 0 deletions CalcIU.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
function MRS_struct = CalcIU(MRS_struct, vox, metab, ii)
% Function for quantifying concentration in institutional units
% Convert metabolite and water areas to institutional units
% (pseudo-concentration in mmol/L)

TR = MRS_struct.p.TR(ii)/1e3;
TE = MRS_struct.p.TE(ii)/1e3;
if isfield(MRS_struct.p,'TR_water')
TR_water = MRS_struct.p.TR_water(ii)/1e3;
else
TR_water = TR;
end
if isfield(MRS_struct.p,'TE_water')
TE_water = MRS_struct.p.TE_water(ii)/1e3;
else
TE_water = TE;
end
PureWaterConc = 55.51*1e3; % mol/kg
WaterVisibility = 0.65; % this is approx the value from Ernst, Kreis, Ross (1993, JMR)
T1_Water = 1.100; % average of WM and GM, Wansapura et al. 1999 (JMRI)
T2_Water = 0.095; % average of WM and GM, Wansapura et al. 1999 (JMRI)
N_H_Water = 2;

switch metab
case 'GABA'
EditingEfficiency = 0.5; % For TE = 68 ms
T1_Metab = 1.31; % Puts et al. 2013 (JMRI)
T2_Metab = 0.088; % Edden et al. 2012 (JMRI)
N_H_Metab = 2;
MM = 0.45; % MM correction: fraction of GABA in GABA+ peak. (In TrypDep, 30 subjects: 55% of GABA+ was MM)
% This fraction is platform- and implementation-dependent, based on length and
% shape of editing pulses and ifis Henry method

case 'Glx'
EditingEfficiency = 0.4; % determined by FID-A simulations (for TE = 68 ms)
T1_Metab = 1.23; % Posse et al. 2007 (MRM)
T2_Metab = 0.18; % Ganji et al. 2012 (NMR Biomed)
N_H_Metab = 1;
MM = 1;

case 'GSH'
EditingEfficiency = 0.74; % At 3T based on Quantification of Glutathione in the Human Brain by MR Spectroscopy at 3 Tesla:
% Comparison of PRESS and MEGA-PRESS
% Faezeh Sanaei Nezhad etal. DOI 10.1002/mrm.26532, 2016
T1_Metab = 0.40; % At 3T based on Doubly selective multiple quantum chemical shift imaging and
% T1 relaxation time measurement of glutathione (GSH) in the human brain in vivo
% In-Young Choi et al. NMR Biomed. 2013; 26: 28-34
T2_Metab = 0.12; % At 3T based on the ISMRM abstract
% T2 relaxation times of 18 brain metabolites determined in 83 healthy volunteers in vivo
% Milan Scheidegger et al. Proc. Intl. Soc. Mag. Reson. Med. 22 (2014)
N_H_Metab = 2;
MM = 1;

case 'Lac'
EditingEfficiency = 0.94; % determined by FID-A simulations (for TE = 140 ms)
T1_Metab = 1.50; % Wijnen et al. 2015 (NMR Biomed)
T2_Metab = 0.24; % Madan et al. 2015 (MRM) (NB: this was estimated in brain tumors)
N_H_Metab = 3;
MM = 1;

case 'EtOH'
EditingEfficiency = 0.5; % assuming same as GABA for now
T1_Metab = 1.31; % assuming same as GABA
T2_Metab = 0.088; % assuming same as GABA
N_H_Metab = 3;
MM = 1;

case 'Cr' % 3 ppm moiety
EditingEfficiency = 1; % not edited, so 1
T1_Metab = (1.46 + 1.24)/2; % Mlynárik et al. 2001 (NMR in Biomed)
T2_Metab = (166 + 144 + 148)/3/1e3; % Wyss et al. 2018 (MRM)
N_H_Metab = 3;
MM = 1;

case 'Cho' % 3.2 ppm moiety
EditingEfficiency = 1; % not edited, so 1
T1_Metab = (1.30 + 1.08)/2; % Mlynárik et al. 2001 (NMR in Biomed)
T2_Metab = (218 + 222 + 274)/3/1e3; % Wyss et al. 2018 (MRM)
N_H_Metab = 9;
MM = 1;

case 'NAA' % 2 ppm moiety
EditingEfficiency = 1; % not edited, so 1
T1_Metab = (1.47 + 1.35)/2; % Mlynárik et al. 2001 (NMR in Biomed)
T2_Metab = (343 + 263 + 253)/3/1e3; % Wyss et al. 2018 (MRM)
N_H_Metab = 3;
MM = 1;
end

T1_Factor = (1 - exp(-TR_water./T1_Water)) ./ (1 - exp(-TR./T1_Metab));
T2_Factor = exp(-TE_water./T2_Water) ./ exp(-TE./T2_Metab);

if strcmp(MRS_struct.p.vendor, 'Siemens_rda')
% Factor of 2 is appropriate for averaged Siemens data (read in separately as ON and OFF)
MRS_struct.out.(vox).(metab).ConcIU(ii) = (MRS_struct.out.(vox).(metab).Area(ii) ./ MRS_struct.out.(vox).water.Area(ii)) ...
.* PureWaterConc .* WaterVisibility .* T1_Factor .* T2_Factor .* (N_H_Water ./ N_H_Metab) ...
.* MM ./ 2 ./ EditingEfficiency;
else
MRS_struct.out.(vox).(metab).ConcIU(ii) = (MRS_struct.out.(vox).(metab).Area(ii) ./ MRS_struct.out.(vox).water.Area(ii)) ...
.* PureWaterConc .* WaterVisibility .* T1_Factor .* T2_Factor .* (N_H_Water ./ N_H_Metab) ...
.* MM ./ EditingEfficiency;
end



26 changes: 17 additions & 9 deletions CheckTargets.m
Original file line number Diff line number Diff line change
@@ -1,48 +1,56 @@
function CheckTargets(MRS_struct)

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

switch num2str(length(MRS_struct.p.target))
case '1'
if any(strcmp(MRS_struct.p.target,{'GABA','Glx','GABAGlx','GSH','Lac','EtOH'}))
if MRS_struct.p.phantom && strcmp(MRS_struct.p.target,'GABAGlx')
if any(strcmp(MRS_struct.p.target, {'GABA', 'Glx', 'GABAGlx', 'GSH', 'Lac', 'EtOH'}))
if MRS_struct.p.phantom && strcmp(MRS_struct.p.target, 'GABAGlx')
fprintf('\n');
error(msg);
end
if MRS_struct.p.HERMES
msg = 'MRS_struct.p.HERMES is set to 1 in GannetPreInitialise.m. Add a second target metabolite or set flag to 0.';
msg = hyperlink(['matlab: opentoline(''' filepath ''', 4, 0)'], 'Add a second target metabolite', msg);
msg = hyperlink(['matlab: opentoline(''' filepath ''', 33, 0)'], 'set flag to 0', msg);
fprintf('\n');
error(msg);
end
else
fprintf('\n');
error(msg);
end
case '2'
if any([all(strcmp(MRS_struct.p.target,{'GABAGlx','GSH'})) ...
all(strcmp(MRS_struct.p.target,{'GABA','GSH'})) ...
all(strcmp(MRS_struct.p.target,{'Glx','GSH'})) ...
all(strcmp(MRS_struct.p.target,{'Lac','GSH'}))])
if MRS_struct.p.phantom && any(strcmp(MRS_struct.p.target,'GABAGlx'))
if any([all(strcmp(MRS_struct.p.target, {'GABAGlx', 'GSH'})) ...
all(strcmp(MRS_struct.p.target, {'GABA', 'GSH'})) ...
all(strcmp(MRS_struct.p.target, {'Glx', 'GSH'})) ...
all(strcmp(MRS_struct.p.target, {'Lac', 'GSH'}))])
if MRS_struct.p.phantom && any(strcmp(MRS_struct.p.target, 'GABAGlx'))
fprintf('\n');
error(msg);
end
if ~MRS_struct.p.HERMES
msg = 'Two target metabolites detected. MRS_struct.p.HERMES must be set to 1 in GannetPreInitialise.m.';
msg = hyperlink(['matlab: opentoline(''' filepath ''', 33, 0)'], 'MRS_struct.p.HERMES must be set to 1', msg);
fprintf('\n');
error(msg);
end
else
fprintf('\n');
error(msg);
end
case '3'
if all(strcmp(MRS_struct.p.target,{'EtOH','GABA','GSH'}))
if all(strcmp(MRS_struct.p.target, {'EtOH', 'GABA', 'GSH'}))
if ~MRS_struct.p.HERMES
msg = 'Three target metabolites detected. MRS_struct.p.HERMES must be set to 1 in GannetPreInitialise.m.';
msg = hyperlink(['matlab: opentoline(''' filepath ''', 33, 0)'], 'MRS_struct.p.HERMES must be set to 1', msg);
fprintf('\n');
error(msg);
end
else
fprintf('\n');
error(msg);
end
end
Expand Down
42 changes: 27 additions & 15 deletions CoRegStandAlone/CoReg.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,37 @@
spm_version = fileparts(which('spm'));
if isempty(spm_version)
msg = 'SPM not found! Please install SPM12 and make sure it is in your search path.';
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12', 'SPM12', msg);
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12/', 'SPM12', msg);
fprintf('\n');
error(msg);
elseif strcmpi(spm_version(end-3:end),'spm8')
msg = ['SPM8 detected. Gannet no longer supports SPM8. ' ...
'Please install SPM12 and make sure it is in your search path.'];
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12', 'SPM12', msg);
msg = hyperlink('https://www.fil.ion.ucl.ac.uk/spm/software/spm12/', 'SPM12', msg);
fprintf('\n');
error(msg);
end

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

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

for ii = 1:numscans

[~,b,c] = fileparts(MRS_struct.metabfile{ii});
[~,e,f] = fileparts(struc{ii});
if ii == 1
fprintf('\nCo-registering voxel from %s to %s...\n', [b c], [e f]);
else
fprintf('Co-registering voxel from %s to %s...\n', [b c], [e f]);
end

fname = MRS_struct.metabfile{ii};

% Loop over voxels if PRIAM
for kk = 1:length(vox)

Expand All @@ -43,19 +56,18 @@

case 'GE'
[~,~,ext] = fileparts(struc{ii});
if strcmp(ext,'.nii')
MRS_struct = GannetMask_GE_nii(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
if strcmp(ext, '.nii')
MRS_struct = GannetMask_GE_nii(fname, struc{ii}, MRS_struct, ii, vox, kk);
else
MRS_struct = GannetMask_GE(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
MRS_struct = GannetMask_GE(fname, struc{ii}, MRS_struct, ii, vox, kk);
end

case 'NIfTI'
MRS_struct = GannetMask_NIfTI(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
MRS_struct = GannetMask_NIfTI(fname, struc{ii}, MRS_struct, ii, vox, kk);

case 'Philips'
sparname = [MRS_struct.metabfile{ii}(1:(end-4)) MRS_struct.p.spar_string];
MRS_struct = GannetMask_Philips(sparname, struc{ii}, MRS_struct, ii, vox, kk);

MRS_struct = GannetMask_Philips(fname, struc{ii}, MRS_struct, ii, vox, kk);

case 'Philips_data'
if exist(MRS_struct.metabfile_sdat,'file')
MRS_struct.p.vendor = 'Philips';
Expand All @@ -82,10 +94,10 @@
end

case 'Siemens_rda'
MRS_struct = GannetMask_SiemensRDA(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
MRS_struct = GannetMask_SiemensRDA(fname, struc{ii}, MRS_struct, ii, vox, kk);

case {'Siemens_twix', 'Siemens_dicom', 'DICOM'}
MRS_struct = GannetMask_SiemensTWIX(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
MRS_struct = GannetMask_SiemensTWIX(fname, struc{ii}, MRS_struct, ii, vox, kk);

end

Expand Down Expand Up @@ -172,11 +184,11 @@
title(t, 'FontName', 'Arial', 'FontSize', 15, 'Interpreter', 'none');

% Gannet logo
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.jpg');
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.png');
I = imread(Gannet_logo);
axes('Position', [0.825, 0.05, 0.125, 0.125]);
axes('Position', [0.85, 0.05, 0.125, 0.125]);
imshow(I);
text(0.9, 0, MRS_struct.version.Gannet, 'Units', 'normalized', 'FontName', 'Arial', 'FontSize', 14, 'FontWeight', 'bold', 'HorizontalAlignment', 'left');
text(0.925, 0, MRS_struct.version.Gannet, 'Units', 'normalized', 'FontName', 'Arial', 'FontSize', 14, 'FontWeight', 'bold', 'HorizontalAlignment', 'left');
axis off square;

% Gannet documentation
Expand Down
Loading

0 comments on commit d78ae2b

Please sign in to comment.