Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pareto navigation #669

Open
wants to merge 42 commits into
base: dev_varRBErobOpt
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
fe06707
Updates to where objectives and constraints are stored
tobiasbecher May 31, 2023
823794f
Merge branch 'dev_Pareto' into dev_ParetoObj
tobiasbecher Jun 5, 2023
4cba6b2
Merge branch 'dev_Pareto' into dev_ParetoObj
tobiasbecher Jul 21, 2023
2e806a9
Merge branch 'dev_varRBErobOpt' into dev_ParetoObj
tobiasbecher Jul 21, 2023
bc7f21d
Fixed bug with constraints and added some comments
tobiasbecher Jul 28, 2023
0faf883
Added Pareto Sandwich support
tobiasbecher Aug 15, 2023
6b8aa22
Added navigation functionality
tobiasbecher Sep 6, 2023
21347fe
Merge branch 'e0404:master' into dev_ParetoNavigation
tobiasbecher Oct 27, 2023
22bb7e6
Changed naming convention
tobiasbecher Oct 27, 2023
fed3c63
Merge branch 'dev_varRBErobOpt' into dev_ParetoNavigation
tobiasbecher Oct 27, 2023
778b4cc
Incorporate scenario change
tobiasbecher Oct 27, 2023
8cb4398
Small fixes
tobiasbecher Oct 27, 2023
d134d85
Final updates
tobiasbecher Oct 30, 2023
23eee6a
File cleanup
tobiasbecher Oct 30, 2023
b9009b1
Delete testRun.mat
tobiasbecher Oct 30, 2023
46ec9b3
Updated documentation
tobiasbecher Nov 2, 2023
267d2b8
Reverted to default values
tobiasbecher Nov 2, 2023
823f44d
First changes based on pull request comments
tobiasbecher Jan 11, 2024
5ddce71
Moved some files and updated GUI
tobiasbecher Jan 24, 2024
e8c6218
Small bug fix
tobiasbecher Jan 24, 2024
b38a859
Added lexicographic optimization
tobiasbecher Jan 30, 2024
f19635f
Update matRad_MinMaxDose.m
tobiasbecher Jan 31, 2024
8004b74
Merge branch 'dev_varRBErobOpt' into pr/669
wahln May 13, 2024
13e4615
fix documentation
wahln May 13, 2024
ece7b7f
fix missing ct scenario index in calcCubesDoseGrid
wahln May 13, 2024
75f7513
Merge branch 'dev_varRBErobOpt' into pr/669
wahln May 13, 2024
c7dc07e
First fixes
tobiasbecher Jun 18, 2024
74ae379
Optimization Preprocessing changes
tobiasbecher Jun 20, 2024
4ceb2bf
Plotting support for Pareto optimization
tobiasbecher Jun 20, 2024
db5d715
Updates to the GUI
tobiasbecher Jun 20, 2024
b8df93d
Readded option to calculate Pareto surface from the given facets
tobiasbecher Jun 20, 2024
5baac7a
Delete matRad_plotPS.m
tobiasbecher Jun 20, 2024
41234fe
Delete matRad_ButtonWidget.m
tobiasbecher Jun 20, 2024
94d2d46
Small updates to plotting functions
tobiasbecher Jun 20, 2024
a0336fe
Removed some unnecessary functions
tobiasbecher Jun 21, 2024
130bcc7
Temporary calcCubes fix for RBExD
tobiasbecher Jun 21, 2024
f0fd213
changed default linestyle
tobiasbecher Jun 21, 2024
2210d7f
Changed linewidth for VOIContours
tobiasbecher Jun 21, 2024
e93381b
Merge branch 'dev_varRBErobOpt' into pr/669
wahln Jun 27, 2024
aa90d6a
Merge branch 'dev' into pr/669
wahln Jun 27, 2024
c0b9594
Small GUI updates
tobiasbecher Jul 4, 2024
7e1653f
Merge branch 'dev_ParetoNav' of https://github.com/tobiasbecher/matRa…
tobiasbecher Jul 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions examples/matRad_example16_paretoOptimization.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
%% Example: Photon Treatment Plan
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2017 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/LICENSES.txt. 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.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% In this example we will show
% (i) how to load patient data into matRad
% (ii) how to setup a photon dose calculation and
% (iii) how to inversely optimize beamlet intensities
% (iv) how to visually and quantitatively evaluate the result
%global timed;
%timed = [];
%% Patient Data Import
% Let's begin with a clear Matlab environment. Then, import the TG119
% phantom into your workspace. The phantom is comprised of a 'ct' and 'cst'
% structure defining the CT images and the structure set. Make sure the
% matRad root directory with all its subdirectories is added to the Matlab
% search path.

matRad_rc; %If this throws an error, run it from the parent directory first to set the paths
matRad_rc;
matRad_cfg = MatRad_Config.instance();
%matRad_cfg.propOpt.defaultMaxIter = 50000;
%%
load('TG119.mat');
%%
cst{1,6}{1} = struct(DoseObjectives.matRad_EUD(1000,0));
cst{3,6}{1} = struct(DoseObjectives.matRad_MeanDose(1000,0));
%%
%cst{2,6}{2} = struct(DoseConstraints.matRad_MinMaxDose(45,55));

%pln.radiationMode = 'protons';
pln.radiationMode = 'photons';
pln.machine = 'Generic';

quantityOpt = 'physicalDose';
modelName = 'none';

%pln.propDoseCalc.calcLET = 0;

pln.numOfFractions = 30;
pln.propStf.gantryAngles = [0:40:359];
pln.propStf.couchAngles = zeros(1,numel(pln.propStf.gantryAngles));
pln.propStf.bixelWidth = 5;


pln.propStf.numOfBeams = numel(pln.propStf.gantryAngles);
pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(cst,ct,0);

pln.propDoseCalc.doseGrid.resolution.x = 5; % [mm]
pln.propDoseCalc.doseGrid.resolution.y = 5; % [mm]
pln.propDoseCalc.doseGrid.resolution.z = 5; % [mm]

%%
% Enable sequencing and disable direct aperture optimization (DAO) for now.
% A DAO optimization is shown in a seperate example.
pln.propOpt.runSequencing = 1;
pln.propOpt.runDAO = 0;

% retrieve bio model parameters
pln.bioParam = matRad_bioModel(pln.radiationMode,quantityOpt, modelName);

% retrieve scenarios for dose calculation and optimziation
pln.multScen = matRad_multScen(ct,'nomScen');

%%
% and et voila our treatment plan structure is ready. Lets have a look:
display(pln);


%% Generate Beam Geometry STF
% The steering file struct comprises the complete beam geometry along with
% ray position, pencil beam positions and energies, source to axis distance (SAD) etc.
stf = matRad_generateStf(ct,cst,pln);

%%
% Let's display the beam geometry information of the 6th beam
%display(stf(6));

%% Dose Calculation
% Let's generate dosimetric information by pre-computing dose influence
% matrices for unit beamlet intensities. Having dose influences available
% allows subsequent inverse optimization.
%dij = matRad_calcParticleDose(ct,stf,pln,cst);
dij = matRad_calcPhotonDose(ct,stf,pln,cst);
%% Inverse Optimization for IMRT
% The goal of the fluence optimization is to find a set of beamlet/pencil
% beam weights which yield the best possible dose distribution according to
% the clinical objectives and constraints underlying the radiation
% treatment. Once the optimization has finished, trigger once the GUI to
% visualize the optimized dose cubes.
%% Paretooptimization
% The goal of this step is to define a grid of penalty values that
% are then evaluated using the matRad_paretoGeneration method
% The VOI and their respective penalties are defined in the following way
% It is possible to have more than one objective function per VOI
% penVal stores the Grid which is then passed on. penGrid contains an
% version easier to visualize, however harder to loop over
%% Add constraints
cst{1,6}{2} = struct(DoseConstraints.matRad_MinMaxDose(0,40));
cst{3,6}{2} = struct(DoseConstraints.matRad_MinMaxDose(0,45));
cst{2,6}{2} = struct(DoseConstraints.matRad_MinMaxDose(45,57));

%%
[resultGUI,retStruct] = matRad_paretoOptimization(dij,cst,pln,3);

%%
matRadGUI
%%
matRadParetoGUI
% matRad_UIInterpolation(retStruct,dij,pln,ct,matRad_setOverlapPriorities(cst),retStruct.optiProb)
51 changes: 51 additions & 0 deletions examples/matRad_example17_lexicographicOptimization.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
matRad_rc; %If this throws an error, run it from the parent directory first to set the paths
load('TG119.mat');


pln.radiationMode = 'photons';
pln.machine = 'Generic';

quantityOpt = 'physicalDose';
modelName = 'none';

%
pln.numOfFractions = 30;
pln.propStf.gantryAngles = [0:40:359];
pln.propStf.couchAngles = zeros(1,numel(pln.propStf.gantryAngles));
pln.propStf.bixelWidth = 5;

pln.propStf.numOfBeams = numel(pln.propStf.gantryAngles);
pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(cst,ct,0);

pln.propDoseCalc.doseGrid.resolution.x = 5; % [mm]
pln.propDoseCalc.doseGrid.resolution.y = 5; % [mm]
pln.propDoseCalc.doseGrid.resolution.z = 5; % [mm]

pln.propSeq.runSequencing = 1;
pln.propOpt.runDAO = 0;

% retrieve bio model parameters
pln.bioParam = matRad_bioModel(pln.radiationMode,quantityOpt, modelName);

% retrieve scenarios for dose calculation and optimziation
pln.multScen = matRad_multScen(ct,'nomScen');
%%
stf = matRad_generateStf(ct,cst,pln);
dij = matRad_calcPhotonDose(ct,stf,pln,cst);

%%
PriorityList1 = matRad_PriorityList1();
PriorityList1.addObjective(1,DoseObjectives.matRad_SquaredDeviation(100,50),4,2);
PriorityList1.addObjective(2,DoseObjectives.matRad_EUD(100,0),10,1);
PriorityList1.addObjective(3,DoseObjectives.matRad_MeanDose(100,0),5,3);

%constraints
%PriorityList1.addConstraint(DoseConstraints.matRad_MinMaxDose(0,40),1);
%PriorityList1.addConstraint(DoseConstraints.matRad_MinMaxDose(45,57),2);
%PriorityList1.addConstraint(DoseConstraints.matRad_MinMaxDose(0,45),3);
%%
PriorityList1.printPriorityList(cst)
%%
[resultGUIs1,resultGUIs2,cst1,cst2,PriorityList2] = matRad_2pecOptimization(PriorityList1,dij,cst,pln);
%%
PriorityList1.printPriorityList(cst)
8 changes: 3 additions & 5 deletions matRad/MatRad_Config.m
Original file line number Diff line number Diff line change
Expand Up @@ -210,18 +210,16 @@ function setDefaultProperties(obj)

%Optimization Options
obj.defaults.propOpt.optimizer = 'IPOPT';
obj.defaults.propOpt.maxIter = 500;
obj.defaults.propOpt.maxIter = 1000;
obj.defaults.propOpt.runDAO = 0;
obj.defaults.propOpt.clearUnusedVoxels = false;

%Sequencing Options
obj.defaults.propSeq.sequencer = 'siochi';

obj.defaults.samplingScenarios = 25;



obj.disableGUI = false;

obj.defaults.samplingScenarios = 25;

obj.devMode = false;
obj.eduMode = false;
Expand Down
47 changes: 47 additions & 0 deletions matRad/gui/matRadParetoGUI.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
function hGUI = matRadParetoGUI(varargin)
% matRad compatability function to call the matRad_MainGUI
% The function checks input parameters and handles the GUI as a
% singleton, so following calls will not create new windows
%
% call
% hGUI = matRadGUI
% matRadGUI
%
% 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/LICENSES.txt. 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.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


persistent hMatRadParetoGUI;

%Initialize navigation structures -> Check for retStruct etc.
retStruct = evalin('base','retStruct');
finds = retStruct.finds;
weights = retStruct.weights;

%Matrix storing objective function values of all calculated plans
assignin('base','finds',finds);

%Matrix storing the plans' associated weights
assignin('base','weights',weights);

matRad_ParetoGUI();







75 changes: 75 additions & 0 deletions matRad/gui/pareto/matRad_ParetoDVHWidget.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
classdef matRad_ParetoDVHWidget < matRad_Widget
% matRad_ParetoDVHWidget class creates a widget for the Pareto GUI to
% display plan DVH's
%
%
% References
% -
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2024 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/LICENSES.txt. 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
DVHPlotAxes
end

methods
function this = matRad_ParetoDVHWidget(handleParent)
this = this@matRad_Widget(handleParent);
this.DVHPlotAxes = axes(this.widgetHandle,'Position',[0.09 0.1 0.9 0.89]);
this.plotInitialDVH();
end

function this = initialize(this)
this.update();
end

end

methods (Access = protected)
function this = createLayout(this)

parent = this.widgetHandle;

matRad_cfg = MatRad_Config.instance();


this.createHandles();
end

function this = doUpdate(this,evt)
%getFromWorkspace(this);
%updateInWorkspace(this);
end
end

methods (Access = private)
function plotInitialDVH(this)
ParetoHelperObject = evalin('base','ParetoHelperObject');
%Shows the DVH for the current plan
resultGUI = matRad_calcCubes(ParetoHelperObject.currentWeights,evalin('base','dij'));
dvh = matRad_calcDVH(evalin('base','cst'),resultGUI.physicalDose,'cum');

matRad_showDVH(this.DVHPlotAxes,...
dvh,evalin('base','cst'),evalin('base','pln'),ParetoHelperObject.linestyle);
if ParetoHelperObject.linestyle < 4
ParetoHelperObject.linestyle = ParetoHelperObject.linestyle + 1;
else
ParetoHelperObject.linestyle = 1;
end
end
end

end


Loading
Loading