0001 classdef matRad_MinMaxDVH < DoseConstraints.matRad_DoseConstraint 0002 % matRad_MinMaxDVH Implements a MinMaxDVH constraint 0003 % See matRad_DoseConstraint for interface description 0004 % 0005 % References 0006 % - 0007 % 0008 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0009 % 0010 % Copyright 2020 the matRad development team. 0011 % 0012 % This file is part of the matRad project. It is subject to the license 0013 % terms in the LICENSE file found in the top-level directory of this 0014 % distribution and at https://github.com/e0404/matRad/LICENSES.txt. No part 0015 % of the matRad project, including this file, may be copied, modified, 0016 % propagated, or distributed except according to the terms contained in the 0017 % LICENSE file. 0018 % 0019 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0020 0021 properties (Constant) 0022 name = 'DVH constraint'; 0023 parameterNames = {'d^{ref}', 'V^{min}', 'V^{max}'}; 0024 %parameterIsDose = logical([1 0 0]); 0025 parameterTypes = {'dose','numeric','numeric'}; 0026 end 0027 0028 properties 0029 voxelScalingRatio = 1; 0030 referenceScalingVal = 0.01; 0031 parameters = {30,0,100}; 0032 end 0033 0034 methods 0035 function obj = matRad_MinMaxDVH(dRef,vMin,vMax) 0036 0037 %If we have a struct in first argument 0038 if nargin == 1 && isstruct(dRef) 0039 inputStruct = dRef; 0040 initFromStruct = true; 0041 else 0042 initFromStruct = false; 0043 inputStruct = []; 0044 end 0045 0046 %Call Superclass Constructor (for struct initialization) 0047 obj@DoseConstraints.matRad_DoseConstraint(inputStruct); 0048 0049 %now handle initialization from other parameters 0050 if ~initFromStruct 0051 if nargin == 3 && isscalar(vMax) 0052 obj.parameters{3} = vMax; 0053 end 0054 0055 if nargin >= 1 && isscalar(dRef) 0056 obj.parameters{1} = dRef; 0057 end 0058 0059 if nargin >= 2 && isscalar(vMin) 0060 obj.parameters{2} = vMin; 0061 end 0062 end 0063 end 0064 0065 %Overloads the struct function to add constraint specific 0066 %parameters 0067 function s = struct(obj) 0068 s = struct@DoseConstraints.matRad_DoseConstraint(obj); 0069 s.voxelScalingRatio = 1; 0070 s.referenceScalingVal = 0.01; 0071 end 0072 0073 function cu = upperBounds(obj,n) 0074 cu = obj.parameters{3} / 100; 0075 end 0076 function cl = lowerBounds(obj,n) 0077 cl = obj.parameters{2} / 100; 0078 end 0079 %% Calculates the Constraint Function value 0080 function cDose = computeDoseConstraintFunction(obj,dose) 0081 0082 %Fast DVH point calculation 0083 cDose = sum(dose >= obj.parameters{1})/numel(dose); 0084 0085 %cDose = 100 * cDose; %In Percent 0086 0087 % alternative constraint calculation 3/4 % 0088 % % get reference Volume 0089 % refVol = cst{j,6}(k).volume/100; 0090 % 0091 % % calc deviation 0092 % deviation = d_i - d_ref; 0093 % 0094 % % calc d_ref2: V(d_ref2) = refVol 0095 % d_ref2 = matRad_calcInversDVH(refVol,d_i); 0096 % 0097 % % apply lower and upper dose limits 0098 % if isequal(cst{j,6}(k).type, 'max DVH constraint') 0099 % deviation(d_i < d_ref | d_i > d_ref2) = 0; 0100 % elseif isequal(cst{j,6}(k).type, 'min DVH constraint') 0101 % deviation(d_i > d_ref | d_i < d_ref2) = 0; 0102 % end 0103 % 0104 % %c = sum(deviation); % linear deviation 0105 % %c = deviation'*deviation; % square devioation 0106 % c = (1/size(cst{j,4},1))*(deviation'*deviation); % square deviation with normalization 0107 % %c = (deviation).^2'*(deviation).^2; % squared square devioation 0108 % alternative constraint calculation 3/4 % 0109 end 0110 0111 %% Calculates the Constraint jacobian 0112 function cDoseJacob = computeDoseConstraintJacobian(obj,dose) 0113 %logistic approximation 0114 0115 %Do we really need to sort two times? 0116 dose_sort = sort(dose); 0117 0118 % calculate scaling 0119 NoVoxels = max(obj.voxelScalingRatio*numel(dose),10); 0120 absDiffsort = sort(abs(obj.parameters{1} - dose_sort)); 0121 0122 deltaDoseMax = absDiffsort(min(ceil(NoVoxels/2),numel(dose))); 0123 0124 % calclulate DVHC scaling 0125 DVHCScaling = min((log(1/obj.referenceScalingVal-1))/(2*deltaDoseMax),250); 0126 0127 d_diff = dose - obj.parameters{1}; 0128 0129 cDoseJacob = (2/numel(dose))*DVHCScaling*exp(2*DVHCScaling*d_diff)./(exp(2*DVHCScaling*d_diff)+1).^2; 0130 0131 % alternative constraint calculation 4/4 % 0132 % % get reference Volume 0133 % refVol = cst{j,6}(k).volume/100; 0134 % 0135 % % calc deviation 0136 % deviation = d_i - d_ref; 0137 % 0138 % % calc d_ref2: V(d_ref2) = refVol 0139 % d_ref2 = matRad_calcInversDVH(refVol,d_i); 0140 % 0141 % % apply lower and upper dose limits 0142 % if isequal(cst{j,6}(k).type, 'max DVH constraint') 0143 % deviation(d_i < d_ref | d_i > d_ref2) = 0; 0144 % elseif isequal(cst{j,6}(k).type, 'min DVH constraint') 0145 % deviation(d_i > d_ref | d_i < d_ref2) = 0; 0146 % end 0147 % 0148 % %jacobVec = ones(size(cst{j,4})); % linear deviation 0149 % %jacobVec = 2*deviation; % square deviation 0150 % jacobVec = (1/size(cst{j,4},1))*2*deviation; % square deviation with normalization 0151 % %jacobVec = 4*(deviation).^3; % squared square devioation 0152 % alternative constraint calculation 4/4 % 0153 end 0154 end 0155 0156 end 0157 0158