From f0fc4bbc408e4a29ce97bce7eb1bcfcbac196533 Mon Sep 17 00:00:00 2001 From: s742o Date: Mon, 3 Nov 2025 10:14:39 +0100 Subject: [PATCH 1/3] Changes to topas interface to enable multiple radiosensitivities --- .../+DoseEngines/matRad_TopasMCEngine.m | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m b/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m index 58ab20995..9fb480a2d 100644 --- a/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m +++ b/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m @@ -246,8 +246,21 @@ function writeAllFiles(obj,ct,cst,stf,machine,w) end end + tmpAlphaX = []; + tmpBetaX = []; + for idx = 1:size(cst, 1) + if ~isempty(cst{idx,5}) && isfield(cst{idx,5}, 'alphaX') + tmpAlphaX = [tmpAlphaX cst{idx,5}.alphaX]; + tmpBetaX = [tmpBetaX cst{idx,5}.betaX]; + end + end + abX = [tmpAlphaX(:) tmpBetaX(:)]; + unique_abX = unique(abX, 'rows'); + obj.bioParameters.AlphaX = unique_abX(:, 1); + obj.bioParameters.BetaX = unique_abX(:, 2); + % Get alpha beta parameters from bioParam struct - if isfield(obj.bioParameters, 'tissuseAlphaX') + if isfield(obj.bioParameters, 'tissueAlphaX') obj.bioParameters.AlphaX = obj.bioModel.tissueAlphaX(1); obj.bioParameters.BetaX = obj.bioModel.tissueBetaX(1); end @@ -508,10 +521,15 @@ function writeAllFiles(obj,ct,cst,stf,machine,w) end % Get photon parameters for RBExDose calculation - if this.calcBioDose + if this.calcBioDose || this.scorer.RBE this.scorer.RBE = true; - [dij.ax,dij.bx] = matRad_getPhotonLQMParameters(cst,dij.doseGrid.numOfVoxels,1,VdoseGrid); - dij.abx(dij.bx>0) = dij.ax(dij.bx>0)./dij.bx(dij.bx>0); + this.calcBioDose = true; + [dij.ax,dij.bx] = matRad_getPhotonLQMParameters(cst,dij.doseGrid.numOfVoxels,this.VdoseGrid); + dij.abx = zeros(size(dij.ax{1})); + ax = dij.ax{1}; + bx = dij.bx{1}; + dij.abx(bx>0) = ax(bx>0)./bx(bx>0); + dij.abx = {dij.abx}; end % save current directory to revert back to later @@ -1355,7 +1373,40 @@ function writeScorers(obj,fID,beamIx) % Read appropriate scorer from file and write to config file matRad_cfg.dispDebug('Reading RBE Scorer from %s\n',fname); scorerName = fileread(fname); - fprintf(fID,'\n%s\n\n',scorerName); + + if length(obj.bioParameters.AlphaX) ==1 + fprintf(fID,'\n%s\n\n',scorerName); + else + idxRep = strfind(scorerName, '/McNamaraAlpha/'); + for idxCell = 1:length(obj.bioParameters.AlphaX) + insertText = ['_CellType_' num2str(idxCell)]; + for idxInsert = 1:length(idxRep)% contains(scorerName, '/McNamaraAlpha/') + tmp = strfind(scorerName, '/McNamaraAlpha/'); + scorerName = [scorerName(1:tmp(1)+13) insertText scorerName(tmp(1)+14:end)]; + tmp = strfind(scorerName, '/McNamaraBeta/'); + scorerName = [scorerName(1:tmp(1)+12) insertText scorerName(tmp(1)+13:end)]; + end + for idxInsert = 1:length(strfind(scorerName, 'Sc/PrescribedDose Gy')) %while contains(scorerName, 'Sc/PrescribedDose Gy') && ~contains(scorerName, 'Sc/PrescribedDose_CellType') + tmp = strfind(scorerName, 'Sc/PrescribedDose Gy'); + scorerName = [scorerName(1:tmp(1)+16) insertText scorerName(tmp(1)+17:end)]; + end + while contains(scorerName, 'Sc/CellLines') && ~contains(scorerName, 'Sc/CellLines_CellType') + tmp = strfind(scorerName, 'Sc/CellLines'); + scorerName = [scorerName(1:tmp(1)+11) insertText scorerName(tmp(1)+12:end)]; + end + while contains(scorerName, 'Sc/SimultaneousExposure') && ~contains(scorerName, 'Sc/SimultaneousExposure_CellType') + tmp = strfind(scorerName, 'Sc/SimultaneousExposure'); + scorerName = [scorerName(1:tmp(1)+22) insertText scorerName(tmp(1)+23:end)]; + end + while contains(scorerName, 'Sim/ScoreLabel') && ~contains(scorerName, 'Sim/ScoreLabel + "_CellType') + tmp = strfind(scorerName, 'Sim/ScoreLabel'); + scorerName = [scorerName(1:tmp(1)+17) insertText scorerName(tmp(1)+18:end)]; + end + + end + + fprintf(fID,'\n%s\n\n',scorerName); + end if obj.calc4DInterplay for PhaseNum = obj.MCparam.Phases{beamIx}' From 42d0e7c15e69262c45cdcd9dd75c002f3f912970 Mon Sep 17 00:00:00 2001 From: s742o Date: Mon, 1 Dec 2025 10:31:53 +0100 Subject: [PATCH 2/3] Writing and reading modification to TOPAS engine for multi alpha beta calculation --- .../+DoseEngines/matRad_TopasMCEngine.m | 108 ++++++++++++++---- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m b/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m index 9fb480a2d..1627d1561 100644 --- a/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m +++ b/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m @@ -944,6 +944,10 @@ function writeAllFiles(obj,ct,cst,stf,machine,w) end end end + + if sum(contains(obj.MCparam.tallies, 'CellType')) + topasCube = + end end function dataOut = readBinCsvData(~,genFullFile) @@ -1192,7 +1196,13 @@ function writeAllFiles(obj,ct,cst,stf,machine,w) modelName = strsplit(topasCubesTallies{j},'_'); modelName = modelName{end}; if isfield(topasCubes,[topasCubesTallies{j} '_beam' num2str(d)]) && iscell(topasCubes.([topasCubesTallies{j} '_beam' num2str(d)])) + + if contains(topasCubesTallies{j}, 'CellType_1') + + else + dij.(['mAlphaDose_' modelName]){ctScen}(:,d) = reshape(topasCubes.([topasCubesTallies{j} '_beam',num2str(d)]){ctScen},[],1) .* dij.physicalDose{ctScen}(:,d); + end end elseif ~isempty(strfind(lower(topasCubesTallies{j}),'beta')) modelName = strsplit(topasCubesTallies{j},'_'); @@ -1373,12 +1383,14 @@ function writeScorers(obj,fID,beamIx) % Read appropriate scorer from file and write to config file matRad_cfg.dispDebug('Reading RBE Scorer from %s\n',fname); scorerName = fileread(fname); + generalScorer = scorerName; if length(obj.bioParameters.AlphaX) ==1 fprintf(fID,'\n%s\n\n',scorerName); else idxRep = strfind(scorerName, '/McNamaraAlpha/'); for idxCell = 1:length(obj.bioParameters.AlphaX) + scorerName = generalScorer; insertText = ['_CellType_' num2str(idxCell)]; for idxInsert = 1:length(idxRep)% contains(scorerName, '/McNamaraAlpha/') tmp = strfind(scorerName, '/McNamaraAlpha/'); @@ -1390,22 +1402,24 @@ function writeScorers(obj,fID,beamIx) tmp = strfind(scorerName, 'Sc/PrescribedDose Gy'); scorerName = [scorerName(1:tmp(1)+16) insertText scorerName(tmp(1)+17:end)]; end - while contains(scorerName, 'Sc/CellLines') && ~contains(scorerName, 'Sc/CellLines_CellType') - tmp = strfind(scorerName, 'Sc/CellLines'); - scorerName = [scorerName(1:tmp(1)+11) insertText scorerName(tmp(1)+12:end)]; + for idxInsert = 1:length(strfind(scorerName, 'Sc/CellLines')) + tmp = strfind(scorerName, 'Sc/CellLines'); + scorerName = [scorerName(1:tmp(idxInsert)+11) insertText scorerName(tmp(idxInsert)+12:end)]; end - while contains(scorerName, 'Sc/SimultaneousExposure') && ~contains(scorerName, 'Sc/SimultaneousExposure_CellType') + for idxInsert = 1:length(strfind(scorerName, 'Sc/SimultaneousExposure')) + %while contains(scorerName, 'Sc/SimultaneousExposure') && ~contains(scorerName, 'Sc/SimultaneousExposure_CellType') tmp = strfind(scorerName, 'Sc/SimultaneousExposure'); - scorerName = [scorerName(1:tmp(1)+22) insertText scorerName(tmp(1)+23:end)]; + scorerName = [scorerName(1:tmp(idxInsert)+22) insertText scorerName(tmp(idxInsert)+23:end)]; end - while contains(scorerName, 'Sim/ScoreLabel') && ~contains(scorerName, 'Sim/ScoreLabel + "_CellType') + for idxInsert = 1:length(strfind(scorerName, 'Sim/ScoreLabel')) + %while contains(scorerName, 'Sim/ScoreLabel') && ~contains(scorerName, 'Sim/ScoreLabel + "_CellType') tmp = strfind(scorerName, 'Sim/ScoreLabel'); - scorerName = [scorerName(1:tmp(1)+17) insertText scorerName(tmp(1)+18:end)]; + scorerName = [scorerName(1:tmp(idxInsert)+17) insertText scorerName(tmp(idxInsert)+18:end)]; end + fprintf(fID,'\n%s\n\n',scorerName); end - fprintf(fID,'\n%s\n\n',scorerName); end if obj.calc4DInterplay @@ -1453,28 +1467,60 @@ function writeScorers(obj,fID,beamIx) % Begin writing biological scorer components: cell lines switch obj.radiationMode case 'protons' - fprintf(fID,'\n### Biological Parameters ###\n'); - fprintf(fID,'sv:Sc/CellLines = 1 "CellLineGeneric"\n'); - fprintf(fID,'d:Sc/CellLineGeneric/Alphax = Sc/AlphaX /Gy\n'); - fprintf(fID,'d:Sc/CellLineGeneric/Betax = Sc/BetaX /Gy2\n'); - fprintf(fID,'d:Sc/CellLineGeneric/AlphaBetaRatiox = Sc/AlphaBetaX Gy\n\n'); + if length(obj.bioParameters.AlphaX) ==1 + fprintf(fID,'\n### Biological Parameters ###\n'); + fprintf(fID,'sv:Sc/CellLines = 1 "CellLineGeneric"\n'); + fprintf(fID,'d:Sc/CellLineGeneric/Alphax = Sc/AlphaX /Gy\n'); + fprintf(fID,'d:Sc/CellLineGeneric/Betax = Sc/BetaX /Gy2\n'); + fprintf(fID,'d:Sc/CellLineGeneric/AlphaBetaRatiox = Sc/AlphaBetaX Gy\n\n'); + else + for idxCell = 1:length(obj.bioParameters.AlphaX) + insertText = ['_CellType_' num2str(idxCell)]; + fprintf(fID,'\n### Biological Parameters ###\n'); + fprintf(fID, ['sv:Sc/CellLines' insertText ' = 1 "CellLineGeneric' insertText '"\n']); + fprintf(fID, ['d:Sc/CellLineGeneric' insertText '/Alphax = Sc/AlphaX' insertText ' /Gy\n']); + fprintf(fID, ['d:Sc/CellLineGeneric' insertText '/Betax = Sc/BetaX' insertText ' /Gy2\n']); + fprintf(fID, ['d:Sc/CellLineGeneric' insertText '/AlphaBetaRatiox = Sc/AlphaBetaX' insertText ' Gy\n\n']); + end + end case {'carbon','helium'} - fprintf(fID,'\n### Biological Parameters ###\n'); - fprintf(fID,'sv:Sc/CellLines = 1 "CellGeneric_abR2"\n'); - fprintf(fID,'d:Sc/CellGeneric_abR2/Alphax = Sc/AlphaX /Gy\n'); - fprintf(fID,'d:Sc/CellGeneric_abR2/Betax = Sc/BetaX /Gy2\n\n'); - % fprintf(fID,'d:Sc/CellGeneric_abR2/AlphaBetaRatiox = Sc/AlphaBetaX Gy\n'); + if length(obj.bioParameters.AlphaX) ==1 + fprintf(fID,'\n### Biological Parameters ###\n'); + fprintf(fID,'sv:Sc/CellLines = 1 "CellGeneric_abR2"\n'); + fprintf(fID,'d:Sc/CellGeneric_abR2/Alphax = Sc/AlphaX /Gy\n'); + fprintf(fID,'d:Sc/CellGeneric_abR2/Betax = Sc/BetaX /Gy2\n\n'); + % fprintf(fID,'d:Sc/CellGeneric_abR2/AlphaBetaRatiox = Sc/AlphaBetaX Gy\n'); + else + for idxCell = 1:length(obj.bioParameters.AlphaX) + insertText = ['_CellType_' num2str(idxCell)]; + fprintf(fID,'\n### Biological Parameters ###\n'); + fprintf(fID, ['sv:Sc/CellLines' insertText ' = 1 "CellLineGeneric_abR2' insertText '"\n']); + fprintf(fID, ['d:Sc/CellLineGeneric_abR2' insertText '/Alphax = Sc/AlphaX' inserText ' /Gy\n']); + fprintf(fID, ['d:Sc/CellLineGeneric_abR2' insertText '/Betax = Sc/BetaX' insertText ' /Gy2\n\n']); + end + end otherwise matRad_cfg.dispError([obj.radiationMode ' not implemented']); end % write biological scorer components: dose parameters matRad_cfg.dispDebug('Writing Biologial Scorer components.\n'); - fprintf(fID,'d:Sc/PrescribedDose = %.4f Gy\n',obj.bioParameters.PrescribedDose); - fprintf(fID,'b:Sc/SimultaneousExposure = %s\n',obj.bioParameters.SimultaneousExposure); - fprintf(fID,'d:Sc/AlphaX = %.4f /Gy\n',obj.bioParameters.AlphaX); - fprintf(fID,'d:Sc/BetaX = %.4f /Gy2\n',obj.bioParameters.BetaX); - fprintf(fID,'d:Sc/AlphaBetaX = %.4f Gy\n',obj.bioParameters.AlphaX/obj.bioParameters.BetaX); + if length(obj.bioParameters.AlphaX) ==1 + fprintf(fID,'d:Sc/PrescribedDose = %.4f Gy\n',obj.bioParameters.PrescribedDose); + fprintf(fID,'b:Sc/SimultaneousExposure = %s\n',obj.bioParameters.SimultaneousExposure); + fprintf(fID,'d:Sc/AlphaX = %.4f /Gy\n',obj.bioParameters.AlphaX); + fprintf(fID,'d:Sc/BetaX = %.4f /Gy2\n',obj.bioParameters.BetaX); + fprintf(fID,'d:Sc/AlphaBetaX = %.4f Gy\n',obj.bioParameters.AlphaX/obj.bioParameters.BetaX); + else + for idxCell = 1:length(obj.bioParameters.AlphaX) + insertText = ['_CellType_' num2str(idxCell)]; + fprintf(fID, ['d:Sc/PrescribedDose' insertText ' = %.4f Gy\n'],obj.bioParameters.PrescribedDose); + fprintf(fID, ['b:Sc/SimultaneousExposure' insertText ' = %s\n'],obj.bioParameters.SimultaneousExposure); + fprintf(fID, ['d:Sc/AlphaX' insertText ' = %.4f /Gy\n'],obj.bioParameters.AlphaX(idxCell)); + fprintf(fID, ['d:Sc/BetaX' insertText ' = %.4f /Gy2\n'],obj.bioParameters.BetaX(idxCell)); + fprintf(fID, ['d:Sc/AlphaBetaX' insertText ' = %.4f Gy\n\n'],obj.bioParameters.AlphaX(idxCell)/obj.bioParameters.BetaX(idxCell)); + end + end % Update MCparam.tallies with processed scorer for i = 1:length(obj.scorer.RBE_model) @@ -1502,9 +1548,23 @@ function writeScorers(obj,fID,beamIx) % Write subscorer to config files for s = 1:length(scorerNames) if strcmp(obj.radiationMode,'protons') - fprintf(fID,'s:Sc/%s%s/ReferencedSubScorer_LET = "ProtonLET"\n',scorerPrefix,scorerNames{s}); + if length(obj.bioParameters.AlphaX) ==1 + fprintf(fID,'s:Sc/%s%s/ReferencedSubScorer_LET = "ProtonLET"\n',scorerPrefix,scorerNames{s}); + else + for idxCell = 1:length(obj.bioParameters.AlphaX) + insertText = ['_CellType_' num2str(idxCell)]; + fprintf(fID,['s:Sc/%s%s' insertText '/ReferencedSubScorer_LET = "ProtonLET"\n'],scorerPrefix,scorerNames{s}); + end + end end + if length(obj.bioParameters.AlphaX) ==1 fprintf(fID,'s:Sc/%s%s/ReferencedSubScorer_Dose = "Tally_DoseToWater"\n',scorerPrefix,scorerNames{s}); + else + for idxCell = 1:length(obj.bioParameters.AlphaX) + insertText = ['_CellType_' num2str(idxCell)]; + fprintf(fID,['s:Sc/%s%s' insertText '/ReferencedSubScorer_Dose = "Tally_DoseToWater"\n'],scorerPrefix,scorerNames{s}); + end + end if obj.calc4DInterplay for PhaseNum = obj.MCparam.Phases{beamIx}' if strcmp(obj.radiationMode,'protons') From dba9f96ca63b4e53d80974aac5436b280c3a0168 Mon Sep 17 00:00:00 2001 From: s742o Date: Mon, 2 Feb 2026 13:34:22 +0100 Subject: [PATCH 3/3] Multi Alpha/Beta implementation concept for proton plans with TOPAS --- .../+DoseEngines/matRad_TopasMCEngine.m | 78 +++++++++---------- matRad/planAnalysis/matRad_compareDose.m | 3 + 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m b/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m index 1627d1561..efd950bd5 100644 --- a/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m +++ b/matRad/doseCalc/+DoseEngines/matRad_TopasMCEngine.m @@ -261,12 +261,12 @@ function writeAllFiles(obj,ct,cst,stf,machine,w) % Get alpha beta parameters from bioParam struct if isfield(obj.bioParameters, 'tissueAlphaX') - obj.bioParameters.AlphaX = obj.bioModel.tissueAlphaX(1); - obj.bioParameters.BetaX = obj.bioModel.tissueBetaX(1); - end - if numel(obj.bioParameters.AlphaX)>1 - matRad_cfg.dispWarning('!!! Only a unique alpha/beta ratio supported at the moment. Found multiple, only the first one will be used !!!!'); + obj.bioParameters.AlphaX = obj.bioModel.tissueAlphaX; + obj.bioParameters.BetaX = obj.bioModel.tissueBetaX; end + %if numel(obj.bioParameters.AlphaX)>1 + % matRad_cfg.dispWarning('!!! Only a unique alpha/beta ratio supported at the moment. Found multiple, only the first one will be used !!!!'); + %end end if obj.scorer.LET @@ -944,10 +944,6 @@ function writeAllFiles(obj,ct,cst,stf,machine,w) end end end - - if sum(contains(obj.MCparam.tallies, 'CellType')) - topasCube = - end end function dataOut = readBinCsvData(~,genFullFile) @@ -1193,22 +1189,39 @@ function writeAllFiles(obj,ct,cst,stf,machine,w) end % Handle RBE-related quantities (not multiplied by sum(w)!) elseif ~isempty(strfind(lower(topasCubesTallies{j}),'alpha')) - modelName = strsplit(topasCubesTallies{j},'_'); - modelName = modelName{end}; + talliesFlags = strsplit(topasCubesTallies{j},'_'); + modelName = talliesFlags{end}; if isfield(topasCubes,[topasCubesTallies{j} '_beam' num2str(d)]) && iscell(topasCubes.([topasCubesTallies{j} '_beam' num2str(d)])) - if contains(topasCubesTallies{j}, 'CellType_1') - + if contains(topasCubesTallies{j}, 'CellType') + ab_idx = str2num(talliesFlags{2}); + organAlpha = obj.bioParameters.AlphaX(ab_idx); + organBeta = obj.bioParameters.BetaX(ab_idx); + mask = find( (dij.ax{1} == organAlpha) & (dij.bx{1} == organBeta)); + topasCube_values = reshape(topasCubes.([topasCubesTallies{j} '_beam',num2str(d)]){ctScen},[],1); + topasCube_values = topasCube_values(mask,d); + dij.(['mAlphaDose_' modelName]){ctScen}(mask,d) = topasCube_values .* dij.physicalDose{ctScen}(mask,d); else - dij.(['mAlphaDose_' modelName]){ctScen}(:,d) = reshape(topasCubes.([topasCubesTallies{j} '_beam',num2str(d)]){ctScen},[],1) .* dij.physicalDose{ctScen}(:,d); + dij.(['mAlphaDose_' modelName]){ctScen}(:,d) = reshape(topasCubes.([topasCubesTallies{j} '_beam',num2str(d)]){ctScen},[],1) .* dij.physicalDose{ctScen}(:,d); end end elseif ~isempty(strfind(lower(topasCubesTallies{j}),'beta')) modelName = strsplit(topasCubesTallies{j},'_'); modelName = modelName{end}; if isfield(topasCubes,[topasCubesTallies{j} '_beam' num2str(d)]) && iscell(topasCubes.([topasCubesTallies{j} '_beam' num2str(d)])) + if contains(topasCubesTallies{j}, 'CellType') + ab_idx = str2num(talliesFlags{2}); + organAlpha = obj.bioParameters.AlphaX(ab_idx); + organBeta = obj.bioParameters.BetaX(ab_idx); + mask = find( (dij.ax{1} == organAlpha) & (dij.bx{1} == organBeta)); + topasCube_values = reshape(topasCubes.([topasCubesTallies{j} '_beam',num2str(d)]){ctScen},[],1); + topasCube_values = topasCube_values(mask,d); + dij.(['mBetaDose_' modelName]){ctScen}(mask,d) = topasCube_values .* dij.physicalDose{ctScen}(mask,d); + else + dij.(['mSqrtBetaDose_' modelName]){ctScen}(:,d) = sqrt(reshape(topasCubes.([topasCubesTallies{j} '_beam',num2str(d)]){ctScen},[],1)) .* dij.physicalDose{ctScen}(:,d); + end end elseif ~isempty(strfind(topasCubesTallies{j},'LET')) if isfield(topasCubes,[topasCubesTallies{j} '_beam' num2str(d)]) && iscell(topasCubes.([topasCubesTallies{j} '_beam' num2str(d)])) @@ -1388,34 +1401,21 @@ function writeScorers(obj,fID,beamIx) if length(obj.bioParameters.AlphaX) ==1 fprintf(fID,'\n%s\n\n',scorerName); else - idxRep = strfind(scorerName, '/McNamaraAlpha/'); for idxCell = 1:length(obj.bioParameters.AlphaX) scorerName = generalScorer; insertText = ['_CellType_' num2str(idxCell)]; - for idxInsert = 1:length(idxRep)% contains(scorerName, '/McNamaraAlpha/') - tmp = strfind(scorerName, '/McNamaraAlpha/'); - scorerName = [scorerName(1:tmp(1)+13) insertText scorerName(tmp(1)+14:end)]; - tmp = strfind(scorerName, '/McNamaraBeta/'); - scorerName = [scorerName(1:tmp(1)+12) insertText scorerName(tmp(1)+13:end)]; - end - for idxInsert = 1:length(strfind(scorerName, 'Sc/PrescribedDose Gy')) %while contains(scorerName, 'Sc/PrescribedDose Gy') && ~contains(scorerName, 'Sc/PrescribedDose_CellType') - tmp = strfind(scorerName, 'Sc/PrescribedDose Gy'); - scorerName = [scorerName(1:tmp(1)+16) insertText scorerName(tmp(1)+17:end)]; - end - for idxInsert = 1:length(strfind(scorerName, 'Sc/CellLines')) - tmp = strfind(scorerName, 'Sc/CellLines'); - scorerName = [scorerName(1:tmp(idxInsert)+11) insertText scorerName(tmp(idxInsert)+12:end)]; - end - for idxInsert = 1:length(strfind(scorerName, 'Sc/SimultaneousExposure')) - %while contains(scorerName, 'Sc/SimultaneousExposure') && ~contains(scorerName, 'Sc/SimultaneousExposure_CellType') - tmp = strfind(scorerName, 'Sc/SimultaneousExposure'); - scorerName = [scorerName(1:tmp(idxInsert)+22) insertText scorerName(tmp(idxInsert)+23:end)]; - end - for idxInsert = 1:length(strfind(scorerName, 'Sim/ScoreLabel')) - %while contains(scorerName, 'Sim/ScoreLabel') && ~contains(scorerName, 'Sim/ScoreLabel + "_CellType') - tmp = strfind(scorerName, 'Sim/ScoreLabel'); - scorerName = [scorerName(1:tmp(idxInsert)+17) insertText scorerName(tmp(idxInsert)+18:end)]; - end + scorerName = strrep(scorerName, ... + 'Alpha/', ['Alpha' insertText '/']); + scorerName = strrep(scorerName, ... + 'Beta/', ['Beta' insertText '/']); + scorerName = strrep(scorerName, ... + 'Sc/PrescribedDose Gy', ['Sc/PrescribedDose' insertText ' Gy']); + scorerName = strrep(scorerName, ... + 'Sc/CellLines', ['Sc/CellLines' insertText]); + scorerName = strrep(scorerName, ... + 'Sc/SimultaneousExposure', ['Sc/SimultaneousExposure' insertText]); + scorerName = strrep(scorerName, ... + 'Sim/ScoreLabel + "', ['Sim/ScoreLabel + "' insertText]); fprintf(fID,'\n%s\n\n',scorerName); end diff --git a/matRad/planAnalysis/matRad_compareDose.m b/matRad/planAnalysis/matRad_compareDose.m index f79feb831..3adcd050b 100644 --- a/matRad/planAnalysis/matRad_compareDose.m +++ b/matRad/planAnalysis/matRad_compareDose.m @@ -148,6 +148,9 @@ % Calculate absolute difference cube and dose windows for plots differenceCube = cube1-cube2; doseDiffWindow = [-max(abs(differenceCube(:))) max(abs(differenceCube(:)))]; + if doseDiffWindow(1)==0 && doseDiffWindow(2)==0 + doseDiffWindow(2) = 1; + end %doseGammaWindow = [0 max(gammaCube(:))]; doseGammaWindow = [0 2]; %We choose 2 as maximum value since the gamma colormap has a sharp cut in the middle