Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/e0404/matRad into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
wahln committed Oct 15, 2024
2 parents 3b58857 + 205cfac commit c7ed55a
Show file tree
Hide file tree
Showing 71 changed files with 2,616 additions and 1,319 deletions.
1 change: 1 addition & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Emily Heath
* Cindy Hermann
* Noa Homolka
* Raed Ibragim
* Fabian Jäger
* Fernando Hueso-González
* Navid Khaledi
Expand Down
2 changes: 1 addition & 1 deletion examples/matRad_example13_fitAnalyticalParticleBaseData.m
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@


%% generate steering file
stf = matRad_generateStfSinglePencilBeam(ct,cst,pln);
stf = matRad_generateSingleBixelStf(ct,cst,pln);

% Select existing BDL file to load and fit
pln.loadExistingBDL = 'BDL_matRad.txt';
Expand Down
6 changes: 0 additions & 6 deletions matRad/dicom/@matRad_DicomExporter/matRad_exportDicomCt.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,6 @@
nSlices = ct.cubeDim(3);
%Create X Y Z vectors if not present
if ~any(isfield(ct,{'x','y','z'}))
%positionOffset = transpose(ct.cubeDim ./ 2);
%positionOffset = ct.cubeDim .* [ct.resolution.y, ct.resolution.x, ct.resolution.z] ./ 2;
% positionOffset = [ct.resolution.y, ct.resolution.x, ct.resolution.z] ./ 2;
% ct.x = ct.resolution.x*[0:ct.cubeDim(2)-1] - positionOffset(2);
% ct.y = ct.resolution.y*[0:ct.cubeDim(1)-1] - positionOffset(1);
% ct.z = ct.resolution.z*[0:ct.cubeDim(3)-1] - positionOffset(3);
ct = matRad_getWorldAxes(ct);
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
%Now image meta
resolution = ct.resolution;
meta.PixelSpacing = [resolution.y; resolution.x];
meta.SliceThickness = resolution.z;
meta.SliceThickness = num2str(resolution.z);

meta.ImagePositionPatient = [ct.x(1); ct.y(1); ct.z(1)];
meta.ImageOrientationPatient = [1;0;0;0;1;0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@


%Since we are exporting HU directly --> no rescaling in any case
%meta.SliceThickness = ct.resolution.z;
%meta.PixelSpacing = [ct.resolution.y; ct.resolution.x];
%meta.ImageOrientationPatient = [1;0;0;0;1;0]; %lps
meta.SliceThickness = num2str(ct.resolution.z);
meta.PixelSpacing = [ct.resolution.y; ct.resolution.x];
meta.ImageOrientationPatient = [1;0;0;0;1;0]; %lps

%meta.RescaleSlope = 1;
%meta.RescaleIntercept = 0;
Expand Down
133 changes: 133 additions & 0 deletions matRad/dicom/@matRad_DicomImporter/matRad_DicomImporter.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
classdef matRad_DicomImporter < handle
% matRad_DicomImporter matRad class to handle a dicom import.
%
% Example on how to use the matRad_DicomImport class
%
% dcmImpObj = matRad_DicomImporter('pathToFolder'); % create instance of matRad_DicomImporter
% dcmImpObj.matRad_importDicom(dcmImpObj); % run the import
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2020 the matRad development team.
%
% This file is part of the matRad project. It is subject to the license
% terms in the LICENSE file found in the top-level directory of this
% distribution and at https://github.com/e0404/matRad/LICENSE.md. No part
% of the matRad project, including this file, may be copied, modified,
% propagated, or distributed except according to the terms contained in the
% LICENSE file.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
properties

% path to DICOM file
patDir;

% lists of all files
allfiles;
patient;
importFiles; % all the names (directories) of files, that will be imported

% properties with data for import functions
importCT;
importRtss;
importRTDose;

% structures for .mat file
ct = [];
cst = [];
stf = [];
pln = [];
resultGUI = [];

ImportGrid;

% bools
dicomMetaBool;
visBool;



end

methods

function obj = matRad_DicomImporter(pathToFolder)

%matRad_DicomImporter Construct an instance of this class
% Can be called with the structures. If no argument is given,
% all structures will be read from the base workspace

obj.patDir = pathToFolder;
matRad_cfg = MatRad_Config.instance();

if matRad_cfg.isOctave
%Octave needs the DICOM package
try
pkg load dicom;
catch
matRad_cfg.dispError('The DICOM export requires the octave-forge package "dicom"!\n');
end
end

obj.patDir = pathToFolder;

obj.matRad_scanDicomImportFolder();

% matRad_DicomImporter imports only one structure, to select
% patients and structures within a single patient the
% matRad_importDicomWidget is used

ctFiles = strcmp(obj.allfiles(:,2),'CT');
rtssFiles = strcmpi(obj.allfiles(:,2),'rtstruct'); %note we can have multiple RT structure sets, matRad will always import the firstit finds
rtPlanFiles = strcmpi(obj.allfiles(:,2),'rtplan');
rtDoseFiles = strcmpi(obj.allfiles(:,2),'rtdose');

obj.importFiles.ct = obj.allfiles(ctFiles,:);%All CT slice filepaths stored in a cell array like {'CTSlice1.dcm','CTSlice2.dcm'};
obj.importFiles.rtss = obj.allfiles(rtssFiles,:);
obj.importFiles.rtplan = obj.allfiles(rtPlanFiles,:);
obj.importFiles.rtdose = obj.allfiles(rtDoseFiles,:);

for i = numel(obj.allfiles(:,1)):-1:1
if strcmp(obj.allfiles(i,2),'CT')
obj.importFiles.resx = obj.allfiles{i,9};
obj.importFiles.resy = obj.allfiles{i,10};
obj.importFiles.resz = obj.allfiles{i,11}; %some CT dicoms do not follow the standard and use SpacingBetweenSlices
break
end
end

obj.importFiles.useImportGrid = false;


end

matRad_importDicom(obj)

obj = matRad_importDicomCt(obj)

obj = matRad_importDicomRTDose(obj)

obj = matRad_importDicomRTPlan(obj)

obj = matRad_importDicomRtss(obj)

obj = matRad_importDicomSteeringPhotons(obj)

obj = matRad_importDicomSteeringParticles(obj)

obj = matRad_scanDicomImportFolder(obj)

obj = matRad_calcHU(obj)

obj = matRad_createCst(obj)

obj = matRad_dummyCst(obj)

% matRad_saveImport(obj);

end

end

Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
function ct = matRad_calcHU(ct)
function obj = matRad_calcHU(obj)
% matRad function to calculate Hounsfield units from a dicom ct
% that originally uses intensity values
%
% call
% ct = matRad_calcHU(ct)
% In your object, there must be a property that contains unprocessed
% dicom ct data which are stored as intensity values (IV)
%
% Output - ct structure with cube with HU
%
% input
% ct: unprocessed dicom ct data which are stored as intensity values (IV)
% HU = IV * slope + intercept
%
% HU = IV * slope + intercept
% call
% obj = matRad_calcHU(obj)
%
% output
% ct: ct struct with cube with HU
%
% References
% -
Expand All @@ -29,10 +29,10 @@
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

for i = 1:ct.numOfCtScen
ct.cubeHU{i} = double(ct.cubeIV{i}) * double(ct.dicomInfo.RescaleSlope) + double(ct.dicomInfo.RescaleIntercept);
for i = 1:obj.ct.numOfCtScen
obj.ct.cubeHU{i} = double(obj.ct.cubeIV{i}) * double(obj.ct.dicomInfo.RescaleSlope) + double(obj.ct.dicomInfo.RescaleIntercept);
end

ct = rmfield(ct,'cubeIV');
obj.ct = rmfield(obj.ct,'cubeIV');

end
82 changes: 82 additions & 0 deletions matRad/dicom/@matRad_DicomImporter/matRad_createCst.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
function obj = matRad_createCst(obj)
% matRad function to create a cst struct upon dicom import
%
% In your object, there must be a property that contains matlab structure
% containing information about rt structure set (generated with
% matRad_importDicomRtss and matRad_convRtssContours2Indices)
%
% Output - matRad cst structure
%
% call
% obj = matRad_createCst(obj)
%
%
% References
% -
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2015 the matRad development team.
%
% This file is part of the matRad project. It is subject to the license
% terms in the LICENSE file found in the top-level directory of this
% distribution and at https://github.com/e0404/matRad/LICENSE.md. No part
% of the matRad project, including this file, may be copied, modified,
% propagated, or distributed except according to the terms contained in the
% LICENSE file.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

matRad_cfg = MatRad_Config.instance();

nStructures = size(obj.importRtss.structures,2);
obj.cst = cell(nStructures,6);

%Create set of default colors
defaultColors = colorcube(nStructures);

for i = 1:size(obj.importRtss.structures,2)
obj.cst{i,1} = i - 1; % first organ has number 0
obj.cst{i,2} = obj.importRtss.structures(i).structName;

if ~isempty(regexpi(obj.cst{i,2},'tv', 'once')) || ...
~isempty(regexpi(obj.cst{i,2},'target', 'once')) || ...
~isempty(regexpi(obj.cst{i,2},'gtv', 'once')) || ...
~isempty(regexpi(obj.cst{i,2},'ctv', 'once')) || ...
~isempty(regexpi(obj.cst{i,2},'ptv', 'once')) || ...
~isempty(regexpi(obj.cst{i,2},'boost', 'once')) || ...
~isempty(regexpi(obj.cst{i,2},'tumor', 'once'))

obj.cst{i,3} = 'TARGET';

obj.cst{i,5}.Priority = 1;

% default objectives for targets
objective = DoseObjectives.matRad_SquaredDeviation;
objective.penalty = 800;
objective.parameters = {30}; %Default reference Dose
obj.cst{i,6}{1} = struct(objective);

else

obj.cst{i,3} = 'OAR';

obj.cst{i,5}.Priority = 2;

obj.cst{i,6} = []; % define no OAR dummy objcetives

end

obj.cst{i,4}{1} = obj.importRtss.structures(i).indices;

% set default parameter for biological planning
obj.cst{i,5}.alphaX = 0.1;
obj.cst{i,5}.betaX = 0.05;
obj.cst{i,5}.Visible = 1;
if isfield(obj.importRtss.structures(i),'structColor') && ~isempty(obj.importRtss.structures(i).structColor)
obj.cst{i,5}.visibleColor = obj.importRtss.structures(i).structColor' ./ 255;
else
obj.cst{i,5}.visibleColor = defaultColors(i,:);
matRad_cfg.dispInfo('No color information for structure %d "%s". Assigned default color [%f %f %f]\n',i,obj.cst{i,2},defaultColors(i,1),defaultColors(i,2),defaultColors(i,3));
end
end
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
function cst = matRad_dummyCst(ct)
function obj = matRad_dummyCst(obj)
% matRad function to create a dummy cst struct for a ct
%
% call
% cst = matRad_dummyCst(ct)
%
% input
% ct: matRad ct struct
% In your object, there should be properties that contain:
% - ct structure;
% - cst structure.
%
% output
% cst: matRad cst struct
% Output - matRad cst structure
%
% call
% obj = matRad_dummyCst(obj)
%
% References
% -
Expand All @@ -29,21 +29,21 @@
warning('Did not find RTSS. Creating dummy segmentation for matRad.');

% allocate
cst = cell(1,6);
obj.cst = cell(1,6);

% fill
cst{1,1} = 0; % first organ has number 0
cst{1,2} = 'dummyContour';
cst{1,3} = 'OAR';
cst{1,4}{1} = find(ct.cubeHU{1}>0.1);
cst{1,5}.Priority = 1;
obj.cst{1,1} = 0; % first organ has number 0
obj.cst{1,2} = 'dummyContour';
obj.cst{1,3} = 'OAR';
obj.cst{1,4}{1} = find(obj.ct.cubeHU{1}>0.1);
obj.cst{1,5}.Priority = 1;

% set default parameter for biological planning
cst{1,5}.alphaX = 0.1;
cst{1,5}.betaX = 0.05;
cst{1,5}.Visible = 1;
cst{1,5}.visibleColor = [0 0 0];
obj.cst{1,5}.alphaX = 0.1;
obj.cst{1,5}.betaX = 0.05;
obj.cst{1,5}.Visible = 1;
obj.cst{1,5}.visibleColor = [0 0 0];

% define no objcetives
cst{1,6} = [];
obj.cst{1,6} = [];

Loading

0 comments on commit c7ed55a

Please sign in to comment.