linlsqOptSetup.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. %% linlsqOptSetup.m
  2. % Stephen R Bowen April 2009
  3. %
  4. % Runs in MATLAB or writes setup files necessary to carry out an
  5. % optimization of photon beamlet or proton spot weight distributions by
  6. % iteratitively minimizing a linear least squares objective function. The
  7. % objective function has the following components:
  8. %
  9. % -Tissue relative importance alpha/Ntissue (alpha binary)
  10. % -Overdose and underdose relative penalties in each tissue Bplus & Bminus
  11. % -Maximum and minimum doses at each voxel within a tissue dplus & dminus
  12. % -Overdose-volume and underdose-volume relative penalties BVplus & BVminus
  13. % -Maximum and minimum doses dVplus & dVminus evaluated at each relative
  14. % tissue maximum and minimum volume percentatges Vplus & Vminus
  15. %%
  16. %%%%% Start of user supplied inputs %%%%%
  17. % specify relative location of Geometry file including ROI masks
  18. % geometryFile = '../plan/HN002b/HN002b_geometry.mat';
  19. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV003f\AV003f_geometry.mat';
  20. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV004c\AV004c_geometry.mat';
  21. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV004c\AV004c_cont_geometry.mat';
  22. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV004c\AV004c_PVC_cont_geometry.mat';
  23. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV004c\AV004c_thresh_geometry.mat';
  24. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV004c\AV004c_PVC_thresh_geometry.mat';
  25. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\HN002b\HN002b_geometry.mat';
  26. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV001c\AV001c_geometry.mat';
  27. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV001f\AV001f_geometry.mat';
  28. geometryFile = 'D:\FTP\Dose Painting\AAPM09\HN003c\HN003c_geometry.mat';
  29. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV004f\AV004f_geometry.mat';
  30. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV002f\AV002f_geometry.mat';
  31. % geometryFile = 'D:\FTP\Dose Painting\AAPM09\AV005c\AV005c_geometry.mat';
  32. % define optimization settings
  33. optSettings = [];
  34. optSettings.optInfo.Niterations = 1000; % total number of iterations of beamlet weight optimization
  35. optSettings.optInfo.Nperbatch = 250; % iteration interval between writing planned dose and weights to file
  36. optimizing = 1;
  37. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_3MM_continuous_';
  38. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_5MM_continuous_';
  39. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_7MM_continuous_';
  40. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_3MM_SUV70_threshold_';
  41. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_5MM_SUV70_threshold_';
  42. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_7MM_SUV70_threshold_';
  43. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_3MM_SUV40_CTV54_GTV72_';
  44. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_5MM_SUV40_CTV54_GTV72_';
  45. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_7MM_SUV40_CTV54_GTV72_';
  46. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_5MM_SUV40_CTV54_GTV94_';
  47. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_7MM_SUV40_CTV54_GTV99_';
  48. % optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_5MM_SUV40_CTV54_GTV65_';
  49. optSettings.optInfo.doseBatchBaseName = 'HN003c_U01_7MM_SUV40_CTV54_GTV63_';
  50. switch optimizing
  51. case 1
  52. optSettings.optInfo.optRun = 'yes'; % flag to run optimization in MATLAB
  53. optSettings.optInfo.saveOptInfo = 'no'; % save opt settings in optinput.txt file located in opt folder
  54. optSettings.beamletInfo.saveBeamletHeader = 'no'; % save beamlet info in beamlet_header.txt file located in beamlet folder
  55. optSettings.prescInfo.savePresc = 'no'; % save presc info in prescription.txt file located in input folder
  56. case 0
  57. optSettings.optInfo.optRun = 'no'; % flag to run optimization in MATLAB
  58. optSettings.optInfo.saveOptInfo = 'yes'; % save opt settings in optinput.txt file located in opt folder
  59. optSettings.beamletInfo.saveBeamletHeader = 'yes'; % save beamlet info in beamlet_header.txt file located in beamlet folder
  60. optSettings.prescInfo.savePresc = 'yes'; % save presc info in prescription.txt file located in input folder
  61. end
  62. % optSettings.optInfo.optRun = 'yes'; % flag to run optimization in MATLAB
  63. optSettings.optInfo.waitForResults = 'no'; % flag to load final dose distribution and DVH into workspace
  64. % optSettings.optInfo.saveOptInfo = 'no'; % save opt settings in optinput.txt file located in opt folder
  65. optSettings.beamletInfo.saveBeamlets = 'no'; % save beamlets when dose calc performed in MATLAB and not Condor
  66. % optSettings.beamletInfo.saveBeamletHeader = 'no'; % save beamlet info in beamlet_header.txt file located in beamlet folder
  67. % % specify location of beamlet folder relative to opt folder
  68. % optSettings.beamletInfo.beamletFolder = 'AV003fbeamlets';
  69. % optSettings.beamletInfo.beamletFolder = 'AV004cbeamlets';
  70. % optSettings.beamletInfo.beamletFolder = 'HN002bbeamlets';
  71. % optSettings.beamletInfo.beamletFolder = 'AV001cbeamlets';
  72. % optSettings.beamletInfo.beamletFolder = 'AV001fbeamlets';
  73. optSettings.beamletInfo.beamletFolder = '../../plan/HN003cbeamlets'; % specify location of beamlet folder relative to opt folder
  74. % optSettings.beamletInfo.beamletFolder = '../../plan/AV004fbeamlets'; % specify location of beamlet folder relative to opt folder
  75. % optSettings.beamletInfo.beamletFolder = '../../plan/AV002fbeamlets';
  76. % optSettings.beamletInfo.beamletFolder = '../../plan/AV005cbeamlets';
  77. optSettings.optInfo.optExeName = [optSettings.optInfo.doseBatchBaseName 'linlsqOpt.exe'];
  78. optSettings.beamletInfo.Nbeamletbatches = 222; % total number of beamlet batches
  79. optSettings.beamletInfo.Nbeamlets = 12592; % total number of non-zero weighted beamets
  80. % optSettings.prescInfo.savePresc = 'no'; % save presc info in prescription.txt file located in input folder
  81. optSettings.optInfo.optFolder = 'C:\WiscPlan\opt\linlsqOpt'; % directory where opt executable is located must be absolute path
  82. optSettings.optInfo.modFactor = 6; % mod factor truncating maximum beamlet weight relative to average weight
  83. % Prescription table
  84. % (code name) (Pinnacle tissue name) (alpha) (Bplus) (dplus) (Bminus) (dminus) (BVplus) (dVplus) (Vplus) (BVminus) (dVminus) (Vminus)
  85. prescTable = {
  86. 'cord' 'cord' 1 1 0 0 0 0 0 0 0 0 0
  87. 'GTV' 'GTV' 1 1000 70 1000 70 0 0 0 0 0 0
  88. % 'cont_base' 'cont_base' 1 1000 60 1000 60 0 0 0 0 0 0
  89. % 'cont_boost' 'cont_boost' 1 2000 80 2000 80 0 0 0 0 0 0
  90. % 'PVC_cont_base' 'PVC_cont_base' 1 1000 60 1000 60 0 0 0 0 0 0
  91. % 'PVC_cont_boost' 'PVC_cont_boost' 1 2000 80 2000 80 0 0 0 0 0 0
  92. % 'thresh_base' 'thresh_base' 1 1000 50 1000 50 0 0 0 0 0 0
  93. % 'thresh_boost' 'thresh_boost' 1 2000 70 2000 70 0 0 0 0 0 0
  94. % 'PVC_thresh_base' 'PVC_thresh_base' 1 1000 50 1000 50 0 0 0 0 0 0
  95. % 'PVC_thresh_boost' 'PVC_thresh_boost' 1 2000 70 2000 70 0 0 0 0 0 0
  96. % 'CTV60' 'CTV 60' 0 0 0 0 0 0 0 0 0 0 0
  97. % 'CTV54' 'CTV 54' 0 0 0 0 0 0 0 0 0 0 0
  98. % 'CTV-rt-scv-5' 'CTV rt scv 54' 0 0 0 0 0 0 0 0 0 0 0
  99. % 'CTV-lt-scv-50' 'CTV lt scv 50' 0 0 0 0 0 0 0 0 0 0 0
  100. % 'larynx' 'larynx' 0 1 0 0 0 0 0 0 0 0 0
  101. % 'opticApparatus' 'optic apparatus' 0 1 0 0 0 0 0 0 0 0 0
  102. 'left_parotid' 'left_parotid' 1 1 0 0 0 0 0 0 0 0 0
  103. 'normal_tissue' 'normal_tissue' 1 10 0 0 0 0 0 0 0 0 0
  104. 'oral_cavity' 'oral_cavity' 1 1 0 0 0 0 0 0 0 0 0
  105. 'right_Parotid' 'right_parotid' 1 1 0 0 0 0 0 0 0 0 0
  106. % 'Brainstem' 'Brainstem' 0 1 0 0 0 0 0 0 0 0 0
  107. % 'eyes' 'eyes' 0 1 0 0 0 0 0 0 0 0 0
  108. % 'couch' 'couch' 0 0 0 0 0 0 0 0 0 0 0
  109. % 'external' 'external' 0 0 0 0 0 0 0 0 0 0 0
  110. % 'ext+1cm' 'ext + 1 cm' 0 0 0 0 0 0 0 0 0 0 0
  111. % 'ring' 'ring' 0 1 0 0 0 0 0 0 0 0 0
  112. % 'PTV70' 'PTV 70' 0 200 70 200 70 0 0 0 0 0 0
  113. % 'PTV60' 'PTV 60' 0 0 0 0 0 0 0 0 0 0 0
  114. % 'PTV54' 'PTV 54' 0 10 0 0 0 0 0 0 0 0 0
  115. % 'PTV50' 'PTV 50' 0 10 0 0 0 0 0 0 0 0 0
  116. % 'LResidParotid' 'L resid parotid' 0 1 0 0 0 0 0 0 0 0 0
  117. % 'PTV60min70' 'PTV 60 - PTV 70' 0 10 60 200 60 0 0 0 0 0 0
  118. };
  119. %%%%% End of user supplied inputs %%%%%
  120. %%
  121. % % calc total number of initial non-zero weighted beamlets from dose calc if
  122. % % saving new beamlet header file
  123. if strcmp(optSettings.beamletInfo.saveBeamletHeader,'yes')
  124. optSettings.beamletInfo.Nbeamlets = beamletNum([optSettings.optInfo.optFolder '\' optSettings.beamletInfo.beamletFolder],optSettings.beamletInfo.Nbeamletbatches);
  125. end
  126. load(geometryFile); % load geometry file
  127. % match isocenter of coordinate system used to calculate photon beamlets or
  128. % proton spots, defined by the patient geometry
  129. x_iso = Geometry.start(1) + (Geometry.voxel_size(1).*double(size(Geometry.data,1)))./2;
  130. y_iso = Geometry.start(2) + (Geometry.voxel_size(2).*double(size(Geometry.data,2)))./2;
  131. z_iso = Geometry.start(3);
  132. iso = [x_iso y_iso z_iso];
  133. % size of CT grid
  134. [M,N,Q] = size(Geometry.data);
  135. % Create the prescription structure
  136. presc = []; % erase the old prescription structure, if it exists
  137. presc.siz = [M N Q]; % dimensions of the prescription and tissue masks
  138. ROIFlags = zeros(1,size(prescTable,1)); % flags to ensure all ROIs are found
  139. % assign the parameters to the prescription structure
  140. for j=1:size(prescTable,1)
  141. % pull out the prescription indices for each tissue
  142. tissName = prescTable{j,2}; % current tissue name
  143. % find the current tissue in the Geometry.ROIS cells
  144. for k=1:length(Geometry.ROIS)
  145. ind = 0;
  146. if strcmp(tissName,Geometry.ROIS{k}.name)
  147. ind = Geometry.ROIS{k}.ind; % extract ROI indices
  148. break;
  149. end
  150. end
  151. if ind == 0
  152. error([tissName ' can not be found in Geometry or is empty!']);
  153. end
  154. presc.tissue(j).name = prescTable{j,1};
  155. presc.tissue(j).ind = ind;
  156. presc.tissue(j).alpha = prescTable{j,3};
  157. presc.tissue(j).betaPlus = prescTable{j,4};
  158. presc.tissue(j).dPlus = single(zeros(size(ind)) + prescTable{j,5});
  159. presc.tissue(j).betaMinus = prescTable{j,6};
  160. presc.tissue(j).dMinus = single(zeros(size(ind)) + prescTable{j,7});
  161. presc.tissue(j).betaVPlus = prescTable{j,8};
  162. presc.tissue(j).dVPlus = prescTable{j,9};
  163. presc.tissue(j).vPlus = prescTable{j,10};
  164. presc.tissue(j).betaVMinus = prescTable{j,11};
  165. presc.tissue(j).dVMinus = prescTable{j,12};
  166. presc.tissue(j).vMinus = prescTable{j,13};
  167. ROIFlags(j) = 1;
  168. end
  169. % ensure that all of the ROIS were found
  170. if sum(ROIFlags) ~= length(ROIFlags)
  171. error('Missed one or more ROIS.\n');
  172. else
  173. fprintf('All ROIs located successfully for downsampled prescription.\n');
  174. end
  175. optSettings.prescInfo.presc = presc; % set prescription
  176. % Save prescription and beamlet information, which is necessary for initial
  177. % guess calculation.
  178. linlsqOptimization(optSettings);
  179. % calculate the initial guess if flagged
  180. [w0,dose0] = calcNormalizedInitialGuess([optSettings.optInfo.optFolder '/optInput.txt']);
  181. optSettings.initialGuessInfo.w0 = w0;
  182. optSettings.initialGuessInfo.saveInitialGuess = 'yes';
  183. linlsqOptimization(optSettings);
  184. if (optSettings.optInfo.optRun == 'no')
  185. fprintf('Optimization setup complete.\n');
  186. else
  187. [weights, dose] = linlsqOptimization(optSettings);
  188. fprintf('Optimization run complete.\n');
  189. if (optSettings.optInfo.waitForResults == 'yes')
  190. [optSettings,optResults] = loadOptResults([optSettings.optInfo.optFolder '/optInput.txt'],'last');
  191. frpintf('Final dose distribution and DVHs loaded.\n');
  192. end
  193. end
  194. clear all;