matRad function to exportt resultGUI to dicom RT dose.
0001 function obj = matRad_exportDicomRTDoses(obj)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 matRad_cfg = MatRad_Config.instance();
0025 matRad_cfg.dispInfo('Exporting DICOM RTDose...\n');
0026
0027 env = matRad_getEnvironment();
0028 isOctave = strcmp(env,'OCTAVE');
0029
0030 if isOctave
0031 matRad_cfg.dispWarning('RTDose export currently not supported by matRad running in Octave using the dicom package! Skipping...');
0032 return;
0033 end
0034
0035
0036 ct = obj.ct;
0037 if ~any(isfield(ct,{'x','y','z'}))
0038
0039 positionOffset = ct.cubeDim ./ 2;
0040 ct.x = ct.resolution.x*[0:ct.cubeDim(2)-1] - positionOffset(2);
0041 ct.y = ct.resolution.y*[0:ct.cubeDim(1)-1] - positionOffset(1);
0042 ct.z = ct.resolution.z*[0:ct.cubeDim(3)-1] - positionOffset(3);
0043 end
0044
0045
0046 storageClass = '1.2.840.10008.5.1.4.1.1.481.2';
0047 meta.MediaStorageSOPClassUID = storageClass;
0048 meta.SOPClassUID = storageClass;
0049
0050
0051
0052
0053 meta.Modality = 'RTDOSE';
0054 meta.Manufacturer = '';
0055 meta.DoseUnits = 'GY';
0056
0057
0058
0059 meta.StudyInstanceUID = obj.StudyInstanceUID;
0060 meta.StudyID = obj.StudyID;
0061
0062
0063
0064
0065 currDate = now;
0066 currDateStr = datestr(currDate,'yyyymmdd');
0067 currTimeStr = datestr(currDate,'HHMMSS');
0068 meta.InstanceCreationDate = currDateStr;
0069 meta.InstanceCreationTime = currTimeStr;
0070 meta.StudyDate = obj.StudyDate;
0071 meta.StudyTime = obj.StudyTime;
0072
0073 meta.FrameOfReferenceUID = obj.FrameOfReferenceUID;
0074 meta.PositionReferenceIndicator = '';
0075
0076
0077
0078 meta.AccessionNumber = '';
0079 meta.StationName = '';
0080 meta.OperatorsName = obj.OperatorsName;
0081 meta.ReferringPhysicianName = obj.dicomName();
0082
0083 meta.PatientName = obj.PatientName;
0084 meta.PatientID = obj.PatientID;
0085 meta.PatientBirthDate = obj.PatientBirthDate;
0086 meta.PatientSex = obj.PatientSex;
0087
0088
0089 meta.SeriesInstanceUID = dicomuid;
0090
0091
0092 resolution = ct.resolution;
0093 meta.PixelSpacing = [resolution.y; resolution.x];
0094 meta.SliceThickness = resolution.z;
0095
0096 meta.ImagePositionPatient = [ct.x(1); ct.y(1); ct.z(1)];
0097 meta.ImageOrientationPatient = [1;0;0;0;1;0];
0098
0099
0100
0101 meta.RescaleSlope = 1;
0102 meta.RescaleIntercept = 0;
0103 meta.RescaleType = 'US';
0104
0105
0106 meta.ImagesInAcquisition = ct.cubeDim(3);
0107 meta.NumberOfFrames = ct.cubeDim(3);
0108 meta.GridFrameOffsetVector = transpose(ct.z - ct.z(1));
0109
0110
0111 try
0112 rtPlanUID = obj.rtPlanMeta.SOPInstanceUID;
0113 rtPlanClassID = obj.rtPlanMeta.SOPClassUID;
0114 meta.ReferencedRTPlanSequence.Item_1.ReferencedSOPClassUID = rtPlanClassID;
0115 meta.ReferencedRTPlanSequence.Item_1.ReferencedSOPInstanceUID = rtPlanUID;
0116 catch
0117 rtPlanUID = '';
0118 rtPlanClassID = '';
0119 end
0120
0121
0122
0123 if nargin < 4 || isempty(doseFieldNames)
0124 doseFieldNames = cell(0);
0125 fn = fieldnames(obj.resultGUI);
0126 for i = 1:numel(fn)
0127 if numel(size(obj.resultGUI.(fn{i}))) == 3
0128 doseFieldNames{end+1} = fn{i};
0129 end
0130 end
0131 end
0132
0133
0134
0135
0136
0137 obj.rtDoseMetas = struct([]);
0138 obj.rtDoseExportStatus = struct([]);
0139
0140 for i = 1:numel(doseFieldNames)
0141 doseName = doseFieldNames{i};
0142
0143
0144
0145 if strncmp(doseName,'physicalDose',12)
0146 doseType = 'PHYSICAL';
0147 elseif strncmp(doseName,'RBExDose',8)
0148 doseType = 'EFFECTIVE';
0149 else
0150 fprintf('Dose Cube ''%s'' of unknown type for DICOM. Not exported!\n',doseName);
0151 continue;
0152 end
0153
0154
0155 if ~isempty(regexp(doseName,'_beam(\d+)','once'))
0156
0157 deliveryType = 'BEAM_SESSION';
0158 else
0159 deliveryType = 'FRACTION';
0160 end
0161
0162
0163 doseCube = zeros(ct.cubeDim(1),ct.cubeDim(2),1,ct.cubeDim(3));
0164 doseCube(:,:,1,:) = obj.resultGUI.(doseFieldNames{i});
0165
0166 minDose = min(doseCube(:));
0167 maxDose = max(doseCube(:));
0168
0169 if minDose < 0
0170 fprintf('Dose Cube ''%s'' has negative values. Not exported!\n',doseName);
0171 continue;
0172 end
0173
0174 doseCubeFac = maxDose / double(uint16(Inf));
0175 doseCube = uint16(doseCube ./ doseCubeFac);
0176
0177 metaCube = meta;
0178 metaCube.DoseType = doseType;
0179 metaCube.DoseSummationType = deliveryType;
0180
0181
0182 meta.SeriesInstanceUID = dicomuid;
0183 metaCube.SeriesNumber = i;
0184 metaCube.InstanceNumber = 1;
0185 metaCube.DoseGridScaling = doseCubeFac;
0186
0187 meta.SOPInstanceUID = dicomuid;
0188 meta.MediaStorageSOPInstanceUID = meta.SOPInstanceUID;
0189
0190 fileName = [obj.rtDoseFilePrefix num2str(i) '_' doseName '.dcm'];
0191
0192 env = matRad_getEnvironment();
0193 if strcmp(env,'OCTAVE')
0194 dicomwrite(doseCube,fullfile(obj.dicomDir,fileName),metaCube);
0195 else
0196 status = dicomwrite(doseCube,fullfile(obj.dicomDir,fileName),metaCube,'CreateMode','copy');
0197 if ~isempty(status)
0198 obj.rtDoseExportStatus = obj.addStruct2StructArray(obj.rtDoseExportStatus,status,i);
0199 end
0200 end
0201
0202
0203 obj.rtDoseMetas = obj.addStruct2StructArray(obj.rtDoseMetas,metaCube);
0204
0205 obj.rtDoseNames{i} = doseFieldNames{i};
0206
0207 matRad_progress(i,numel(doseFieldNames));
0208 end
0209
0210
0211 end