0001 function [ fileList, patientList ] = matRad_scanDicomImportFolder( patDir )
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 matRad_cfg = MatRad_Config.instance();
0032
0033
0034 matRad_cfg.dispInfo('Dose series matched to the different plans are displayed and could be selected.\n');
0035 matRad_cfg.dispInfo('Rechecking of correct matching procedure is recommended.\n');
0036
0037 global warnDlgDICOMtagShown;
0038 warnDlgDICOMtagShown = false;
0039
0040
0041
0042
0043 if ~license('checkout','image_toolbox')
0044 matRad_cfg.dispError('image processing toolbox and/or corresponding licence not available');
0045 end
0046
0047 fileList = matRad_listAllFiles(patDir);
0048
0049 if ~isempty(fileList)
0050
0051 numOfFiles = numel(fileList(:,1));
0052 h = waitbar(0,'Please wait...');
0053
0054 steps = numOfFiles;
0055 for i = numOfFiles:-1:1
0056 waitbar((numOfFiles+1-i) / steps)
0057 try
0058 if verLessThan('matlab','9')
0059 info = dicominfo(fileList{i});
0060 else
0061 info = dicominfo(fileList{i},'UseDictionaryVR',true);
0062 end
0063 catch
0064 fileList(i,:) = [];
0065 matRad_progress(numOfFiles+1-i, numOfFiles);
0066 continue;
0067 end
0068 try
0069 fileList{i,2} = info.Modality;
0070 catch
0071 fileList{i,2} = NaN;
0072 end
0073
0074 fileList = parseDicomTag(fileList,info,'PatientID',i,3);
0075
0076 switch fileList{i,2}
0077 case 'CT'
0078
0079 fileList = parseDicomTag(fileList,info,'SeriesInstanceUID',i,4);
0080
0081 case {'RTPLAN','RTDOSE','RTSTRUCT'}
0082
0083 fileList = parseDicomTag(fileList,info,'SOPInstanceUID',i,4);
0084
0085 otherwise
0086
0087 fileList = parseDicomTag(fileList,info,'SeriesInstanceUID',i,4);
0088
0089 end
0090
0091 fileList = parseDicomTag(fileList,info,'SeriesNumber',i,5,@seriesnum2str);
0092 fileList = parseDicomTag(fileList,info,'FamilyName',i,6);
0093 fileList = parseDicomTag(fileList,info,'GivenName',i,7);
0094 fileList = parseDicomTag(fileList,info,'PatientBirthDate',i,8);
0095
0096 try
0097 if strcmp(info.Modality,'CT')
0098 fileList{i,9} = num2str(info.PixelSpacing(1));
0099 else
0100 fileList{i,9} = NaN;
0101 end
0102 catch
0103 fileList{i,9} = NaN;
0104 end
0105 try
0106 if strcmp(info.Modality,'CT')
0107 fileList{i,10} = num2str(info.PixelSpacing(2));
0108 else
0109 fileList{i,10} = NaN;
0110 end
0111 catch
0112 fileList{i,10} = NaN;
0113 end
0114 try
0115 if strcmp(info.Modality,'CT')
0116
0117
0118 if isfield(info,'SliceThickness') && ~isempty(info.SliceThickness)
0119 fileList{i,11} = num2str(info.SliceThickness);
0120 elseif isfield(info,'SpacingBetweenSlices')
0121 fileList{i,11} = num2str(info.SpacingBetweenSlices);
0122 else
0123 matRad_cfg.dispError('Could not identify spacing between slices since neither ''SliceThickness'' nor ''SpacingBetweenSlices'' are specified');
0124 end
0125 else
0126 fileList{i,11} = NaN;
0127 end
0128 catch
0129 fileList{i,11} = NaN;
0130 end
0131 try
0132 if strcmp(info.Modality,'RTDOSE')
0133 dosetext_helper = strcat('Instance','_', num2str(info.InstanceNumber),'_', ...
0134 info.DoseSummationType, '_', info.DoseType);
0135 fileList{i,12} = dosetext_helper;
0136 else
0137 fileList{i,12} = NaN;
0138 end
0139 catch
0140 fileList{i,12} = NaN;
0141 end
0142
0143 try
0144 if strcmp(fileList{i,2},'RTPLAN')
0145 corrDose = [];
0146 numDose = length(fieldnames(info.ReferencedDoseSequence));
0147 for j = 1:numDose
0148 fieldName = strcat('Item_',num2str(j));
0149 corrDose{j} = info.ReferencedDoseSequence.(fieldName).ReferencedSOPInstanceUID;
0150 end
0151 fileList{i,13} = corrDose;
0152 else
0153 fileList{i,13} = {'NaN'};
0154 end
0155
0156 catch
0157 fileList{i,13} = {'NaN'};
0158 end
0159 matRad_progress(numOfFiles+1-i, numOfFiles);
0160
0161 end
0162 close(h)
0163
0164 if ~isempty(fileList)
0165 patientList = unique(fileList(:,3));
0166
0167 if isempty(patientList)
0168 msgbox('No patient found with DICOM CT _and_ RT structure set in patient directory!', 'Error','error');
0169 end
0170 else
0171 msgbox('No DICOM files found in patient directory!', 'Error','error');
0172
0173
0174 end
0175 else
0176 msgbox('Search folder empty!', 'Error','error');
0177
0178 end
0179
0180 clear warnDlgDICOMtagShown;
0181
0182 end
0183
0184 function fileList = parseDicomTag(fileList,info,tag,row,column,parsefcn)
0185
0186 global warnDlgDICOMtagShown;
0187
0188 defaultPlaceHolder = '001';
0189
0190 if nargin < 6
0191 parsefcn = @(x) x;
0192 end
0193
0194 try
0195 if isfield(info,tag)
0196 if ~isempty(info.(tag))
0197 fileList{row,column} = parsefcn(info.(tag));
0198 else
0199 fileList{row,column} = defaultPlaceHolder;
0200 end
0201 else
0202 fileList{row,column} = defaultPlaceHolder;
0203 end
0204 catch
0205 fileList{row,column} = NaN;
0206 end
0207
0208 if ~warnDlgDICOMtagShown && strcmp(fileList{row,column},defaultPlaceHolder) && (column == 3 || column == 4)
0209
0210 dlgTitle = 'Dicom Tag import';
0211 dlgQuestion = ['matRad_scanDicomImportFolder: Could not parse dicom tag: ' tag '. Using placeholder ' defaultPlaceHolder ' instead. Please check imported data carefully! Do you want to continue?'];
0212 answer = questdlg(dlgQuestion,dlgTitle,'Yes','No', 'Yes');
0213
0214 warnDlgDICOMtagShown = true;
0215
0216 switch answer
0217 case 'No'
0218 matRad_cfg.dispError('Inconsistency in DICOM tags')
0219 end
0220 end
0221
0222 end
0223
0224 function value = seriesnum2str(value)
0225 if isnumeric(value)
0226 value = num2str(value);
0227 end
0228 end
0229
0230
0231
0232