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

Implementation of LET modifying objectives #706

Open
wants to merge 49 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
49 commits
Select commit Hold shift + click to select a range
a2f3241
Dirty dose calculation and objectives
lisaseckler Nov 21, 2023
a3b1f91
LET Objectives
lisaseckler Dec 13, 2023
4d2c215
Merge branch 'dev_varRBErobOpt' of https://github.com/e0404/matRad in…
lisaseckler Dec 13, 2023
56b4ac4
Test change
lisaseckler Dec 20, 2023
249054b
LETd Objective
lisaseckler Dec 21, 2023
6a202f8
Objective Variance Implementation
lisaseckler Jan 11, 2024
90c3be3
LET experiments for PTCOG
lisaseckler Jan 22, 2024
593443a
Cleaning branch
lisaseckler Jan 26, 2024
b2ea438
Function Test
lisaseckler Feb 1, 2024
7e8fee4
Test DD
lisaseckler Feb 2, 2024
b3a3e12
test change
lisaseckler Feb 2, 2024
cf03bab
Delete matRad_Beam2DirtyDose.asv
lisaseckler Mar 1, 2024
0a15bfc
Delete matRad_DoseComparison.asv
lisaseckler Mar 1, 2024
4a7fec9
Delete optimization/+DoseObjectives/matRad_LETDirtyDose.asv
lisaseckler Mar 1, 2024
fab2177
Delete optimization/@matRad_OptimizationProblem/matRad_objectiveFunct…
lisaseckler Mar 1, 2024
1359231
Delete optimization/@matRad_OptimizationProblem/matRad_objectiveGradi…
lisaseckler Mar 1, 2024
c09e74f
Delete optimization/projections/matRad_DirtyDoseProjection.asv
lisaseckler Mar 1, 2024
57d5495
Delete optimization/projections/matRad_LETdProjection.asv
lisaseckler Mar 1, 2024
f5b4266
Update matRad_Beam2DirtyDose.m
lisaseckler Mar 1, 2024
c11d27a
Delete matRad_Beam2DirtyDoseMCN_WED.m
lisaseckler Mar 1, 2024
18f2aff
Delete matRad_Beam2mLETDoseMCN.m
lisaseckler Mar 1, 2024
d7537b4
Update matRad_Beam2DirtyDose.m
lisaseckler Mar 1, 2024
e5c083a
Delete matRad_UnderdosingTesting.asv
lisaseckler Mar 1, 2024
d01e7c0
Update and rename matRad_UnderdosingTesting.m to matRad_DirtyDoseUnde…
lisaseckler Mar 1, 2024
6047145
Delete matRad_calcLETmask.asv
lisaseckler Mar 1, 2024
5f71dc0
Delete matRad_fluenceOptimization.asv
lisaseckler Mar 1, 2024
c15485f
Cleaning LET Optimization
lisaseckler Mar 1, 2024
fe7a317
Merge branch 'dev_varRBErobOpt' of https://github.com/lisaseckler/mat…
lisaseckler Mar 1, 2024
c5cb8b4
Clean up
lisaseckler Mar 27, 2024
143ac52
Testing examples and deleting scripts
lisaseckler Mar 27, 2024
621e7db
renaming file
lisaseckler Mar 27, 2024
a97197d
changing variable names
lisaseckler Mar 27, 2024
0516c2e
Merge branch 'e0404:dev_varRBErobOpt' into dev_varRBErobOpt
lisaseckler Mar 27, 2024
627c2b6
Merge branch 'dev_varRBErobOpt' of https://github.com/lisaseckler/mat…
lisaseckler Mar 27, 2024
3a88bec
deleting comments
lisaseckler Mar 27, 2024
c489f32
deleting dicom
lisaseckler Mar 27, 2024
a6d4eba
delete
lisaseckler Mar 27, 2024
44eedec
delete
lisaseckler Mar 27, 2024
f120062
delete
lisaseckler Mar 27, 2024
54516f1
delete
lisaseckler Mar 27, 2024
c9c77dd
delete
lisaseckler Mar 27, 2024
d6e1040
name
lisaseckler Mar 27, 2024
969aebc
Examples
lisaseckler Apr 22, 2024
c3b26c1
Description of LETmask
lisaseckler May 3, 2024
3a3efe9
Merge branch 'dev' into pr/706
wahln Jun 28, 2024
2d05c9b
some streamlining of the calculation of dirty dose and the LET masks
wahln Jun 28, 2024
57eea22
Merge branch 'dev_varRBErobOpt' into pr/706
wahln Jun 28, 2024
1b9251b
remove the tempfile
wahln Jun 28, 2024
32a31c3
Merge branch 'dev_varRBErobOpt' into pr/706
wahln Jun 28, 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
1 change: 1 addition & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* Giuseppe Pezzano
* Daniel Ramirez
* Carsten Scholz
* Lisa Seckler
* Camilo Sevilla
* Alexander Stadler
* Uwe Titt
Expand Down
2 changes: 1 addition & 1 deletion examples/matRad_example12_simpleParticleMonteCarlo.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@

%% Compare LET
if isfield(resultGUI,'LET') && isfield(resultGUI_MC,'LET')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change LET to LETd, then this need to really be done rigorously. Also here the isfield checks need to do this.

I am not entirely sure if I want to have that change, probably just using LET is better.

matRad_compareDose(resultGUI.LET, resultGUI.(['LET_' pln.propDoseCalc.engine]), ct, cst, [1, 1, 0] , 'off', pln, [2, 2], 1, 'global');
matRad_compareDose(resultGUI.LETd, resultGUI.(['LET_' pln.propDoseCalc.engine]), ct, cst, [1, 1, 0] , 'off', pln, [2, 2], 1, 'global');
end

%% GUI
Expand Down
170 changes: 170 additions & 0 deletions examples/matRad_example16_LETd.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
%% Welcome to a LETd example script
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 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.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% open matRad files and delete everything in the workspace
matRad_rc

%% load an easy phantom like the TG119.mat
load("TG119.mat")

%% Plan and Geometry
pln.radiationMode = 'protons'; % either photons / protons / helium / carbon
pln.machine = 'Generic';
pln.numOfFractions = 30;


% beam geometry settings
pln.propStf.bixelWidth = 5; % [mm] / also corresponds to lateral spot spacing for particles
pln.propStf.gantryAngles = [45 0 -45];
pln.propStf.couchAngles = zeros(numel(pln.propStf.gantryAngles),1);
pln.propStf.numOfBeams = numel(pln.propStf.gantryAngles);
pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(cst,ct,0);
% optimization settings
pln.propDoseCalc.calcLET = 1; % very important, don't forget that one!

pln.propOpt.runDAO = false; % 1/true: run DAO, 0/false: don't / will be ignored for particles
pln.propOpt.runSequencing = false; % 1/true: run sequencing, 0/false: don't / will be ignored for particles and also triggered by runDAO below
pln.propOpt.spatioTemp = 0;

% dose calculation settings
pln.propDoseCalc.doseGrid.resolution.x = 3; % [mm]
pln.propDoseCalc.doseGrid.resolution.y = 3; % [mm]
pln.propDoseCalc.doseGrid.resolution.z = 3; % [mm]
% pln(1).propDoseCalc.doseGrid.resolution = ct.resolution;
quantityOpt = 'RBExD'; % options: physicalDose, effect, RBExD
%=======================================> Model check error in bioModel
modelName = 'constRBE'; % none: for photons, protons, carbon % constRBE: constant RBE for photons and protons
% MCN: McNamara-variable RBE model for protons % WED: Wedenberg-variable RBE model for protons
% LEM: Local Effect Model for carbon ions


scenGenType = 'nomScen'; % scenario creation type 'nomScen' 'wcScen' 'impScen' 'rndScen'

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

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

%% Dose calculation
% Dij Calculation --> only for dose
dij = matRad_calcParticleDose(ct,stf,pln,cst);

% Dirty Dose Calculation --> compute dirty dose influence matrix
% arg: LET threshold (keV/um)
dij = matRad_calcDirtyDose(2,dij);

%% Optimization
resultGUI = matRad_fluenceOptimization(dij,cst,pln);

%% Plotting
% Let's see how it looks
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETd;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETd without LETd objective')
zoom(4)

%% Adding LETd objective
% adding a LETd objective to the Core
cst{1,6}{2} = struct(LETdObjectives.matRad_SquaredOverdosingLETd(100,0));

%% Optimization
resultGUI = matRad_fluenceOptimization(dij,cst,pln);

%% Well done your first LETd calculation is ready!
% Let's see how it looks
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETd;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETd with LETd objective in Core')
zoom(4)

%% Now with the Target
%% Adding LETd
% for adding a LETd objective to OuterTarget
cst{2,6}{2} = struct(LETdObjectives.matRad_SquaredUnderdosingLETd(100,20));
resultGUI = matRad_fluenceOptimization(dij,cst,pln);
%% Plotting
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETd;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETd with LETd objective in Target')
zoom(4)

%% Now with the Core and Target
%% Adding LETd
% for adding a LETd objective choose two structures: Core and OuterTarget
cst{1,6}{2} = struct(LETdObjectives.matRad_SquaredOverdosingLETd(100,0));
cst{2,6}{2} = struct(LETdObjectives.matRad_SquaredUnderdosingLETd(100,20));
%% Optimization
resultGUI = matRad_fluenceOptimization(dij,cst,pln);
%% Plotting
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETd;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETd with LETd objective in Core and Target')
zoom(4)
170 changes: 170 additions & 0 deletions examples/matRad_example17_LETxDose.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
%% Welcome to a LETxDose example script
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 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.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% open matRad files and delete everything in the workspace
matRad_rc

%% load an easy phantom like the TG119.mat
load("TG119.mat")

%% Plan and Geometry
pln.radiationMode = 'protons'; % either photons / protons / helium / carbon
pln.machine = 'Generic';
pln.numOfFractions = 30;


% beam geometry settings
pln.propStf.bixelWidth = 5; % [mm] / also corresponds to lateral spot spacing for particles
pln.propStf.gantryAngles = [45 0 -45];
pln.propStf.couchAngles = zeros(numel(pln.propStf.gantryAngles),1);
pln.propStf.numOfBeams = numel(pln.propStf.gantryAngles);
pln.propStf.isoCenter = ones(pln.propStf.numOfBeams,1) * matRad_getIsoCenter(cst,ct,0);
% optimization settings
pln.propDoseCalc.calcLET = 1; % very important, don't forget that one!

pln.propOpt.runDAO = false; % 1/true: run DAO, 0/false: don't / will be ignored for particles
pln.propOpt.runSequencing = false; % 1/true: run sequencing, 0/false: don't / will be ignored for particles and also triggered by runDAO below
pln.propOpt.spatioTemp = 0;

% dose calculation settings
pln.propDoseCalc.doseGrid.resolution.x = 3; % [mm]
pln.propDoseCalc.doseGrid.resolution.y = 3; % [mm]
pln.propDoseCalc.doseGrid.resolution.z = 3; % [mm]
% pln(1).propDoseCalc.doseGrid.resolution = ct.resolution;
quantityOpt = 'RBExD'; % options: physicalDose, effect, RBExD
%=======================================> Model check error in bioModel
modelName = 'constRBE'; % none: for photons, protons, carbon % constRBE: constant RBE for photons and protons
% MCN: McNamara-variable RBE model for protons % WED: Wedenberg-variable RBE model for protons
% LEM: Local Effect Model for carbon ions


scenGenType = 'nomScen'; % scenario creation type 'nomScen' 'wcScen' 'impScen' 'rndScen'

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

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

%% Dose calculation
% Dij Calculation --> only for dose
dij = matRad_calcParticleDose(ct,stf,pln,cst);

% Dirty Dose Calculation --> compute dirty dose influence matrix
% arg: LET threshold (keV/um)
dij = matRad_calcDirtyDose(2,dij);

%% Optimization
resultGUI = matRad_fluenceOptimization(dij,cst,pln);

%% Plotting
% Let's see how it looks
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETxDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETxDose without LETxDose objective')
zoom(4)

%% Adding LETxDose objective
% adding a LETxDose objective to the Core
cst{1,6}{2} = struct(LETxDoseObjectives.matRad_SquaredOverdosingLETxDose(6,0));

%% Optimization
resultGUI = matRad_fluenceOptimization(dij,cst,pln);

%% Well done your first LETxDose calculation is ready!
% Let's see how it looks
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETxDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETxDose with LETxDose objective in Core')
zoom(4)

%% Now with the Target
%% Adding LETxDose
% for adding a LETxDose objective to OuterTarget
cst{2,6}{2} = struct(LETxDoseObjectives.matRad_SquaredUnderdosingLETxDose(6,20));
resultGUI = matRad_fluenceOptimization(dij,cst,pln);
%% Plotting
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETxDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETxDose with LETxDose objective in Target')
zoom(4)

%% Now with the Core and Target
%% Adding LETxDose
% for adding a LETxDose objective choose two structures: Core and OuterTarget
cst{1,6}{2} = struct(LETxDoseObjectives.matRad_SquaredOverdosingLETxDose(6,0));
cst{2,6}{2} = struct(LETxDoseObjectives.matRad_SquaredUnderdosingLETxDose(6,20));
%% Optimization
resultGUI = matRad_fluenceOptimization(dij,cst,pln);
%% Plotting
cube = resultGUI.physicalDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
figure
subplot(2,1,1)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('physicalDose')
zoom(4)

cube = resultGUI.LETxDose;
plane = 3;
slice = 80;
doseWindow = [min(cube(:)) max(cube(:))];
subplot(2,1,2)
matRad_plotSliceWrapper(gca,ct,cst,1,cube,plane,slice,[],[],colorcube,[],doseWindow,[],[]);
title('LETxDose with LETxDose objective in Core and Target')
zoom(4)
Loading
Loading