Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ function assignPropertiesFromPln(this,pln,warnWhenPropertyChanged)

resultGUI = [];

activeScenIx = find(this.multScen.scenMask);
for i = 1:this.multScen.totNumScen
scenSubIx = this.multScen.linearMask(i,:);
resultGUItmp = matRad_calcCubes(ones(dij.numOfBeams,1),dij,this.multScen.sub2scenIx(scenSubIx(1),scenSubIx(2),scenSubIx(3)));
resultGUItmp = matRad_calcCubes(ones(dij.numOfBeams,1),dij,activeScenIx(i));
if i == 1
resultGUI = resultGUItmp;
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function setDefaults(this)

for ctScen = 1:this.multScen.numOfCtScen
for rangeShiftScen = 1:this.multScen.totNumRangeScen
fullScenIdx = this.multScen.sub2scenIx(ctScen,shiftScen,rangeShiftScen);
fullScenIdx = this.multScen.sub2scenIx(ctScen,shiftScen,rangeShiftScen,'position');

if this.multScen.scenMask(fullScenIdx)
%TODO: This shows we probably need
Expand Down Expand Up @@ -673,4 +673,3 @@ function setDefaults(this)
end

end

9 changes: 8 additions & 1 deletion matRad/scenarios/matRad_NominalScenario.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,14 @@
this.totNumScen = totNumScen;
end
end

function scenIx = sub2scenIx(this,ctScen,shiftScen,rangeShiftScen,ctScenReference)
if nargin < 5
scenIx = sub2scenIx@matRad_ScenarioModel(this,ctScen,shiftScen,rangeShiftScen);
else
scenIx = sub2scenIx@matRad_ScenarioModel(this,ctScen,shiftScen,rangeShiftScen,ctScenReference);
end
end

end
end

98 changes: 91 additions & 7 deletions matRad/scenarios/matRad_ScenarioModel.m
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,15 @@ function listAllScenarios(this)
newInstance = matRad_NominalScenario();

ctScenNum = this.linearMask(scenNum,1);
ctScenProbIx = find(this.ctScenProb(:,1) == ctScenNum,1,'first');
if isempty(ctScenProbIx)
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('Could not find CT scenario %d in ctScenProb.',ctScenNum);
end

%First set properties that force an update
newInstance.numOfCtScen = 1;
newInstance.ctScenProb = this.ctScenProb(ctScenNum,:);
newInstance.ctScenProb = this.ctScenProb(ctScenProbIx,:);

%Now overwrite existing variables for correct probabilties and
%error realizations
Expand All @@ -181,14 +186,16 @@ function listAllScenarios(this)
%newInstance.updateScenarios();
end

function scenIx = sub2scenIx(this,ctScen,shiftScen,rangeShiftScen)
function scenIx = sub2scenIx(this,ctScen,shiftScen,rangeShiftScen,ctScenReference)
%Returns linear index in the scenario cell array from scenario
%subscript indices
if ~isvector(this.scenMask)
scenIx = sub2ind(size(this.scenMask),this.ctScenIx(ctScen),shiftScen,rangeShiftScen);
else
scenIx = this.ctScenIx(ctScen);
%subscript indices. The optional ctScenReference disambiguates
%whether ctScen is a local position ('position', default) or
%an absolute CT scenario id ('id').
if nargin < 5 || isempty(ctScenReference)
ctScenReference = 'position';
end
ctScenId = resolveCtScenarioId(this,ctScen,ctScenReference);
scenIx = scenarioSub2Ind(this,ctScenId,shiftScen,rangeShiftScen);
end

function scenNum = scenNum(this,fullScenIx)
Expand Down Expand Up @@ -246,3 +253,80 @@ function listAllScenarios(this)
end
end

function ctScenId = resolveCtScenarioId(scenarioModel,ctScen,ctScenReference)

validatePositiveIntegerScalar(ctScen,'ctScen');
ctScenReference = normalizeCtScenReference(ctScenReference);

switch ctScenReference
case 'position'
if ctScen > size(scenarioModel.ctScenProb,1)
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('CT scenario position %d exceeds the scenario model size.',ctScen);
end
ctScenId = scenarioModel.ctScenProb(ctScen,1);
case 'id'
if ~any(scenarioModel.ctScenProb(:,1) == ctScen)
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('Could not find CT scenario %d in the scenario model.',ctScen);
end
ctScenId = ctScen;
end

end

function ctScenReference = normalizeCtScenReference(ctScenReference)

if isstring(ctScenReference) && isscalar(ctScenReference)
ctScenReference = char(ctScenReference);
end

if ~ischar(ctScenReference)
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('ctScenReference must be ''position'' or ''id''.');
end

switch lower(ctScenReference)
case {'position','ctscenposition'}
ctScenReference = 'position';
case {'id','ctscenid'}
ctScenReference = 'id';
otherwise
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('ctScenReference must be ''position'' or ''id''.');
end

end

function scenIx = scenarioSub2Ind(scenarioModel,ctScenId,shiftScen,rangeShiftScen)

validatePositiveIntegerScalar(shiftScen,'shiftScen');
validatePositiveIntegerScalar(rangeShiftScen,'rangeShiftScen');

if ~isvector(scenarioModel.scenMask)
scenMaskSize = size(scenarioModel.scenMask);
if ctScenId > scenMaskSize(1) || shiftScen > scenMaskSize(2) || ...
rangeShiftScen > scenMaskSize(3)
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('Scenario subscript exceeds the scenario mask dimensions.');
end
scenIx = sub2ind(scenMaskSize,ctScenId,shiftScen,rangeShiftScen);
else
if ctScenId > numel(scenarioModel.scenMask)
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('CT scenario id %d exceeds the scenario mask dimensions.',ctScenId);
end
scenIx = ctScenId;
end

end

function validatePositiveIntegerScalar(value,valueName)

if ~(isnumeric(value) && isscalar(value) && isfinite(value) && ...
round(value) == value && value >= 1)
matRad_cfg = MatRad_Config.instance();
matRad_cfg.dispError('%s must be a positive integer scalar.',valueName);
end

end
14 changes: 13 additions & 1 deletion test/scenarios/test_scenarioModel.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ function test_scenarioAbstractAvailableTypes()
assertEqual(model.name,availableTypes{i});
end

function test_extractSingleScenario_accepts_sparse_ct_scenario_probabilities
ct.numOfCtScen = 3;
model = matRad_RandomScenarios(ct);
model.ctScenProb = [2 1];

scenario = model.extractSingleScenario(1);

assertEqual(scenario.ctScenProb,[2 1]);
assertEqual(scenario.ctScenIx,2);
assertEqual(scenario.sub2scenIx(1,1,1),2);
assertEqual(scenario.sub2scenIx(1,1,1,'position'),2);
assertEqual(scenario.sub2scenIx(2,1,1,'id'),2);
assertExceptionThrown(@() scenario.sub2scenIx(2,1,1,'position'),'matRad:Error');

function instanceTest_listAllScenarios(model)
model.listAllScenarios();
Expand Down Expand Up @@ -103,4 +116,3 @@ function instanceTest_TYPE(model)
function instanceTest_wcFactor(model)
%assertWarning(@() model.wcFactor,'matRad:Deprecated');
assertEqual(model.TYPE,model.name);

Loading