Skip to content

Commit 8aad18d

Browse files
Merge pull request #10 from markmikkelsen/dev
Merge with dev; release of v3.3.0
2 parents 287076a + b2a13e4 commit 8aad18d

Some content is hidden

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

64 files changed

+16556
-1801
lines changed

AlignSubSpectra.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
else
7171
subSpecInd = [3 2 1 4];
7272
end
73+
case 'NIfTI'
74+
subSpecInd = [3 2 1 4];
7375
case {'Philips','Philips_data','Philips_raw'}
7476
subSpecInd = [1 2 3 4];
7577
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}
@@ -87,7 +89,7 @@
8789
end
8890
else
8991
switch MRS_struct.p.vendor
90-
case 'GE'
92+
case {'GE','NIfTI'}
9193
subSpecInd = [3 2 1 4];
9294
case {'Philips','Philips_data','Philips_raw'}
9395
subSpecInd = [1 4 3 2];

AlignSubSpectra_PreAlignRef.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@
9595
end
9696
else
9797
switch MRS_struct.p.vendor
98+
case 'GE'
99+
subSpecInd = [3 2 1 4];
98100
case {'Philips','Philips_data','Philips_raw'}
99101
subSpecInd = [1 4 3 2];
100102
case {'Siemens_twix','Siemens_rda','Siemens_dicom'}

CoRegStandAlone/CoReg.m

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
% Coregistration of MRS voxel volumes to imaging datasets, based on headers.
44

5-
MRS_struct.version.coreg = '210701';
5+
loadFile = which('GannetCoRegister');
6+
fileID = fopen(loadFile, 'rt');
7+
str = fread(fileID, Inf, '*uchar');
8+
fclose(fileID);
9+
str = char(str(:)');
10+
expression = '(?<field>MRS_struct.version.coreg = )''(?<version>.*?)''';
11+
out = regexp(str, expression, 'names');
12+
MRS_struct.version.coreg = out.version;
613

714
warning('off'); % temporarily suppress warning messages
815

@@ -33,6 +40,17 @@
3340

3441
%Ultimately this switch will not be necessary...
3542
switch MRS_struct.p.vendor
43+
44+
case 'GE'
45+
[~,~,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);
48+
else
49+
MRS_struct = GannetMask_GE(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
50+
end
51+
52+
case 'NIfTI'
53+
MRS_struct = GannetMask_NIfTI(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
3654

3755
case 'Philips'
3856
sparname = [MRS_struct.metabfile{ii}(1:(end-4)) MRS_struct.p.spar_string];
@@ -66,24 +84,20 @@
6684
case 'Siemens_rda'
6785
MRS_struct = GannetMask_SiemensRDA(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
6886

69-
case {'Siemens_twix', 'Siemens_dicom', 'dicom'}
87+
case {'Siemens_twix', 'Siemens_dicom', 'DICOM'}
7088
MRS_struct = GannetMask_SiemensTWIX(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
7189

72-
case 'GE'
73-
[~,~,ext] = fileparts(struc{ii});
74-
if strcmp(ext,'.nii')
75-
MRS_struct = GannetMask_GE_nii(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
76-
else
77-
MRS_struct = GannetMask_GE(MRS_struct.metabfile{ii}, struc{ii}, MRS_struct, ii, vox, kk);
78-
end
79-
8090
end
8191

8292
% Build output figure
8393
if ishandle(103)
8494
clf(103);
8595
end
86-
h = figure(103);
96+
if MRS_struct.p.hide
97+
h = figure('Visible', 'off');
98+
else
99+
h = figure(103);
100+
end
87101
scr_sz = get(0,'ScreenSize');
88102
fig_w = 1000;
89103
fig_h = 707;
@@ -150,16 +164,16 @@
150164
imagesc(squeeze(MRS_struct.mask.(vox{kk}).img{ii}));
151165
colormap('gray');
152166
img = MRS_struct.mask.(vox{kk}).img{ii}(:);
153-
caxis([0 mean(img(img > 0.01)) + 3*std(img(img > 0.01))]);
167+
caxis([0 mean(img(img > 0.01)) + 3*std(img(img > 0.01))]); %#ok<*CAXIS>
154168
axis equal tight off;
155169
text(10, size(MRS_struct.mask.(vox{kk}).img{ii},1)/2, 'L', 'Color', [1 1 1], 'FontSize', 20);
156170
text(size(MRS_struct.mask.(vox{kk}).img{ii},2) - 20, size(MRS_struct.mask.(vox{kk}).img{ii},1)/2, 'R', 'Color', [1 1 1], 'FontSize', 20);
157171
set(ha,'pos',[0 0.15 1 1]);
158172
title(t, 'FontName', 'Arial', 'FontSize', 15, 'Interpreter', 'none');
159173

160174
% Gannet logo
161-
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.png');
162-
I = imread(Gannet_logo,'png','BackgroundColor',[1 1 1]);
175+
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.jpg');
176+
I = imread(Gannet_logo);
163177
axes('Position', [0.825, 0.05, 0.125, 0.125]);
164178
imshow(I);
165179
text(0.9, 0, MRS_struct.version.Gannet, 'Units', 'normalized', 'FontName', 'Arial', 'FontSize', 14, 'FontWeight', 'bold', 'HorizontalAlignment', 'left');
@@ -209,5 +223,10 @@
209223

210224
warning('on'); % turn warnings back on
211225

226+
% Need to close hidden figures to show figures after Gannet is done running
227+
if MRS_struct.p.hide
228+
close(figTitle);
229+
end
230+
212231

213232

CoRegStandAlone/CoRegStandAlone.m

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,40 @@
3939
% 2020-07-29: Some minor cosmetic changes.
4040
% 2022-06-03: Fixed bug related to target metabolite
4141

42+
if nargin == 0
43+
error('MATLAB:minrhs','Not enough input arguments.');
44+
end
45+
4246
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4347
% 1. Pre-initialise
4448
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4549

46-
MRS_struct.version.Gannet = '3.2.1';
47-
MRS_struct.version.load = '220607';
50+
loadFile = which('GannetLoad');
51+
fileID = fopen(loadFile, 'rt');
52+
str = fread(fileID, Inf, '*uchar');
53+
fclose(fileID);
54+
str = char(str(:)');
55+
expression = '(?<field>MRS_struct.version.Gannet = )''(?<version>.*?)''';
56+
out = regexp(str, expression, 'names');
57+
MRS_struct.version.Gannet = out.version;
58+
59+
expression = '(?<field>MRS_struct.version.load = )''(?<version>.*?)''';
60+
out = regexp(str, expression, 'names');
61+
MRS_struct.version.load = out.version;
62+
4863
MRS_struct.ii = 0;
4964
if size(metabfile,2) == 1
5065
metabfile = metabfile';
5166
end
5267
MRS_struct.metabfile = metabfile;
53-
MRS_struct.p.HERMES = 0;
68+
MRS_struct.p.HERMES = 0;
5469

5570
% Flags
56-
MRS_struct.p.mat = 1; % Save results in *.mat file? (0 = NO, 1 = YES (default)).
71+
MRS_struct.p.mat = 0; % Save results in *.mat file? (0 = NO, 1 = YES (default)).
5772
MRS_struct.p.csv = 1; % Save results in *.csv file? (0 = NO, 1 = YES (default)).
5873
MRS_struct.p.vox = {'vox1'}; % Name of the voxel
5974
MRS_struct.p.target = {'GABAGlx'}; % Name of the target metabolite
75+
MRS_struct.p.hide = 0; % Do not display output figures
6076

6177
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6278
% 2. Determine data parameters from header
@@ -75,20 +91,14 @@
7591

7692
switch MRS_struct.p.vendor
7793

94+
case 'DICOM'
95+
MRS_struct = DICOMRead(MRS_struct, metabfile{ii});
96+
7897
case 'GE'
7998
MRS_struct = GERead(MRS_struct, metabfile{ii});
8099

81-
case 'Siemens_twix'
82-
MRS_struct = SiemensTwixRead(MRS_struct, metabfile{ii});
83-
84-
case 'Siemens_dicom'
85-
MRS_struct = SiemensDICOMRead(MRS_struct, metabfile{ii});
86-
87-
case 'dicom'
88-
MRS_struct = DICOMRead(MRS_struct, metabfile{ii});
89-
90-
case 'Siemens_rda'
91-
MRS_struct = SiemensRead(MRS_struct, metabfile{ii}, metabfile{ii});
100+
case 'NIfTI'
101+
MRS_struct = NIfTIMRSRead(MRS_struct, metabfile{ii});
92102

93103
case 'Philips'
94104
MRS_struct = PhilipsRead(MRS_struct, metabfile{ii});
@@ -99,6 +109,15 @@
99109
case 'Philips_raw'
100110
MRS_struct = PhilipsRawLoad(MRS_struct, metabfile{ii}, 3, 0);
101111

112+
case 'Siemens_dicom'
113+
MRS_struct = SiemensDICOMRead(MRS_struct, metabfile{ii});
114+
115+
case 'Siemens_rda'
116+
MRS_struct = SiemensRead(MRS_struct, metabfile{ii}, metabfile{ii});
117+
118+
case 'Siemens_twix'
119+
MRS_struct = SiemensTwixRead(MRS_struct, metabfile{ii});
120+
102121
end
103122

104123
end

CoRegStandAlone/Seg.m

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@
1111
% This is useful if only the tissue segmentation information is supposed to
1212
% be obtained.
1313

14-
MRS_struct.version.segment = '220607';
15-
vox = MRS_struct.p.vox(1);
14+
loadFile = which('GannetSegment');
15+
fileID = fopen(loadFile, 'rt');
16+
str = fread(fileID, Inf, '*uchar');
17+
fclose(fileID);
18+
str = char(str(:)');
19+
expression = '(?<field>MRS_struct.version.segment = )''(?<version>.*?)''';
20+
out = regexp(str, expression, 'names');
21+
MRS_struct.version.segment = out.version;
1622

1723
warning('off'); % temporarily suppress warning messages
1824

@@ -29,6 +35,7 @@
2935
error(msg);
3036
end
3137

38+
vox = MRS_struct.p.vox(1);
3239
kk = 1;
3340
setup_spm = 1;
3441

@@ -159,7 +166,11 @@
159166
if ishandle(104)
160167
clf(104);
161168
end
162-
h = figure(104);
169+
if MRS_struct.p.hide
170+
h = figure('Visible', 'off');
171+
else
172+
h = figure(104);
173+
end
163174
% Open figure in center of screen
164175
scr_sz = get(0,'ScreenSize');
165176
fig_w = 1000;
@@ -237,8 +248,8 @@
237248
title(t, 'FontName', 'Arial', 'FontSize', 15, 'Interpreter', 'none');
238249

239250
% Gannet logo
240-
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.png');
241-
I = imread(Gannet_logo,'png','BackgroundColor',[1 1 1]);
251+
Gannet_logo = fullfile(fileparts(which('GannetLoad')), 'Gannet3_logo.jpg');
252+
I = imread(Gannet_logo);
242253
axes('Position', [0.825, 0.05, 0.125, 0.125]);
243254
imshow(I);
244255
text(0.9, 0, MRS_struct.version.Gannet, 'Units', 'normalized', 'FontName', 'Arial', 'FontSize', 14, 'FontWeight', 'bold', 'HorizontalAlignment', 'left');
@@ -296,6 +307,11 @@
296307

297308
warning('on'); % turn warnings back on
298309

310+
% Need to close hidden figures to show figures after Gannet is done running
311+
if MRS_struct.p.hide
312+
close(figTitle);
313+
end
314+
299315

300316
function img_montage = PlotSegmentedVoxels(struc, voxoff, voxmaskvol, O_GMvox, O_WMvox, O_CSFvox)
301317

DICOMRead.m

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
folder = '.';
5050
end
5151
dcm_file_list = dir(fullfile(folder, '*.dcm')); % GO 11/16/2016
52-
fprintf('\n%d water-suppressed DCM files detected in %s', length(dcm_file_list), folder);
52+
fprintf('\n%d water-suppressed DICOM files found in %s', length(dcm_file_list), folder);
5353

5454
% Ordering of these files is not correct (i.e. 1,10,100,101...). Sort
5555
% naturally.
@@ -60,40 +60,39 @@
6060
%%% /PREPARATION %%%
6161

6262
%%% HEADER INFO PARSING %%%
63-
DicomHeader = read_dcm_header(metabfile);
64-
MRS_struct.p.seq = DicomHeader.sequenceFileName;
65-
MRS_struct.p.TR(ii) = DicomHeader.TR;
66-
MRS_struct.p.TE(ii) = DicomHeader.TE;
67-
MRS_struct.p.npoints(ii) = DicomHeader.vectorSize;
68-
MRS_struct.p.Navg(ii) = 2*DicomHeader.nAverages;
69-
MRS_struct.p.nrows(ii) = 2*DicomHeader.nAverages;
70-
MRS_struct.p.sw(ii) = 1/DicomHeader.dwellTime * 1E9 * 0.5; % check with oversampling? hence factor 0.5, need to figure out why <=> probably dataset with 512 points, oversampled is 1024
71-
MRS_struct.p.LarmorFreq(ii) = DicomHeader.tx_freq * 1E-6;
72-
MRS_struct.p.voxdim(ii,1) = DicomHeader.VoI_PeFOV;
73-
MRS_struct.p.voxdim(ii,2) = DicomHeader.VoI_RoFOV;
74-
MRS_struct.p.voxdim(ii,3) = DicomHeader.VoIThickness;
63+
DicomHeader = read_dcm_header(metabfile);
64+
MRS_struct.p.seq = DicomHeader.sequenceFileName;
65+
MRS_struct.p.TR(ii) = DicomHeader.TR;
66+
MRS_struct.p.TE(ii) = DicomHeader.TE;
67+
MRS_struct.p.npoints(ii) = DicomHeader.vectorSize;
68+
MRS_struct.p.Navg(ii) = 2*DicomHeader.nAverages;
69+
MRS_struct.p.nrows(ii) = 2*DicomHeader.nAverages;
70+
MRS_struct.p.sw(ii) = 1/DicomHeader.dwellTime * 1E9 * 0.5; % check with oversampling? hence factor 0.5, need to figure out why <=> probably dataset with 512 points, oversampled is 1024
71+
MRS_struct.p.LarmorFreq(ii) = DicomHeader.tx_freq * 1E-6;
72+
MRS_struct.p.voxdim(ii,1) = DicomHeader.VoI_PeFOV;
73+
MRS_struct.p.voxdim(ii,2) = DicomHeader.VoI_RoFOV;
74+
MRS_struct.p.voxdim(ii,3) = DicomHeader.VoIThickness;
7575
MRS_struct.p.VoI_InPlaneRot(ii) = DicomHeader.VoI_InPlaneRot;
76-
MRS_struct.p.voxoff(ii,1) = DicomHeader.PosSag;
77-
MRS_struct.p.voxoff(ii,2) = DicomHeader.PosCor;
78-
MRS_struct.p.voxoff(ii,3) = DicomHeader.PosTra;
79-
MRS_struct.p.NormCor(ii) = DicomHeader.NormCor;
80-
MRS_struct.p.NormSag(ii) = DicomHeader.NormSag;
81-
MRS_struct.p.NormTra(ii) = DicomHeader.NormTra;
76+
MRS_struct.p.voxoff(ii,1) = DicomHeader.PosSag;
77+
MRS_struct.p.voxoff(ii,2) = DicomHeader.PosCor;
78+
MRS_struct.p.voxoff(ii,3) = DicomHeader.PosTra;
79+
MRS_struct.p.NormCor(ii) = DicomHeader.NormCor;
80+
MRS_struct.p.NormSag(ii) = DicomHeader.NormSag;
81+
MRS_struct.p.NormTra(ii) = DicomHeader.NormTra;
8282
%%% /HEADER INFO PARSING %%%
8383

8484
%%% DATA LOADING %%%
8585
% Preallocate array in which the FIDs are to be extracted.
86-
MRS_struct.fids.data = zeros(MRS_struct.p.npoints(ii),length(dcm_file_names));
86+
MRS_struct.fids.data = zeros(MRS_struct.p.npoints(ii), length(dcm_file_names));
8787

8888
% Collect all FIDs and sort them into MRS_struct
8989
for kk = 1:length(dcm_file_names)
90-
9190
% Open IMA
9291
fd = dicom_open(dcm_file_names{kk});
93-
92+
9493
% read the signal in as a complex FID
9594
MRS_struct.fids.data(:,kk) = dicom_get_spectrum_siemens(fd);
96-
95+
9796
fclose(fd);
9897
end
9998

@@ -116,30 +115,35 @@
116115

117116
% Set up the file name array.
118117
if nargin == 3
118+
119119
%%% WATER HEADER INFO PARSING %%%
120120
DicomHeaderWater = read_dcm_header(waterfile);
121121
MRS_struct.p.TR_water(ii) = DicomHeaderWater.TR;
122122
MRS_struct.p.TE_water(ii) = DicomHeaderWater.TE;
123123
%%% /WATER HEADER INFO PARSING %%%
124-
124+
125125
waterfolder = fileparts(waterfile);
126+
if isempty(waterfile)
127+
waterfolder = '.';
128+
end
126129
water_file_list = dir(fullfile(waterfolder, '*.dcm'));
127-
fprintf('\n%d water-unsuppressed DCM files detected in %s', length(water_file_list), waterfolder);
130+
fprintf('\n%d water-unsuppressed DICOM files found in %s', length(water_file_list), waterfolder);
128131
water_file_names = sort_nat({water_file_list.name});
129132
water_file_names = strcat(waterfolder, filesep, water_file_names);
130-
133+
131134
% Load the actual water-unsuppressed data.
132135
MRS_struct.fids.waterdata = zeros(MRS_struct.p.npoints(ii), length(water_file_names));
133-
136+
134137
% Collect all FIDs and sort them into MRS_struct
135-
for kk = 1:length(water_file_names)
138+
for kk = 1:length(water_file_names)
136139
% Open IMA
137-
fd = dicom_open(water_file_names{kk});
140+
fd = dicom_open(water_file_names{kk});
138141
% read the signal in as a complex FID
139-
MRS_struct.fids.data_water(:,kk) = dicom_get_spectrum_siemens(fd);
142+
MRS_struct.fids.data_water(:,kk) = dicom_get_spectrum_siemens(fd);
140143
fclose(fd);
141144
end
142145
MRS_struct.fids.data_water = mean(MRS_struct.fids.data_water,2);
146+
143147
end
144148
%%% /WATER DATA LOADING %%%
145149

0 commit comments

Comments
 (0)