helicalDosecalcSetup.m 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. %% helicalDoseCalcSetup.m
  2. % RTF 11/4/05
  3. % Sets up the run files needed for running a convolution
  4. % superposition dose calculation with helical tomotherapy photon beams.
  5. % Versions of the convolution code that run in both Windows XP, Condor, and
  6. % directly through Matlab can all be created here. The only real
  7. % differences between the files are in the access conventions, specified by
  8. % forward slashes or backslashes.
  9. % Stephen R Bowen April 2009
  10. %
  11. % The Kernels are generated from a cylindrical geometry within MCNP.
  12. % The patient CT data is contained within the MATLAB structure Geometry
  13. % and has the following format:
  14. %
  15. % Geometry.voxel_size (dx dy dz)
  16. % .start (x y z)
  17. % .data (M x N x Q single float matrix)
  18. % .ROIS {1 x Nroi cell array}
  19. %
  20. % Each index of the Geometry.ROIS cell array should contain at least the
  21. % following fields, even if manually created from Amira segmentation:
  22. %
  23. % Geometry.ROIS{1}.name 'string'
  24. % .ind (int32 sparse data array)
  25. % .dim (M N Q)
  26. % .pix_dim (dx dy dz)
  27. % .start (x y z)
  28. % .start_ind 'string'
  29. %
  30. % If your Geometry structure does not containg ROI information, then all
  31. % beamlets will be included in the calculation. Specified PTV ROIs will
  32. % turn beamlets off that do not deposit dose within a specific margin.
  33. %%
  34. %%%%% Start of user supplied inputs %%%%%
  35. % specify where kernel and geometry files are located
  36. kernel_file = 'Kernels.mat';
  37. geometry_file = '../plan/HN003/HN003final.mat';
  38. % flags used to select which calculations will be done
  39. Matlab_flag = 0;
  40. Condor_flag = 1;
  41. WinXP_flag = 0;
  42. % define the overall beam field size (cm) for each beam angle in the
  43. % tomotherapy coordinate system:
  44. %
  45. % xp: MLC leaf axis
  46. % yp: MLC jaw axis
  47. %
  48. % remember yp points in the z-axis in the CT coordinate system
  49. xpmin = -20;
  50. xpmax = 20;
  51. %ypmin = -0.05; % total jaw width is 0.1 cm
  52. %ypmax = 0.05;
  53. %ypmin = -0.125; % total jaw width is 0.25 cm
  54. %ypmax = 0.125;
  55. ypmin = -0.3125; % total jaw width is 0.625 cm
  56. ypmax = 0.3125;
  57. % ypmin = -0.5; % total jaw width is 1 cm
  58. % ypmax = 0.5;
  59. % ypmin = -1.2250; % total jaw width is 2.45 cm
  60. % ypmax = 1.2250;
  61. pitch_factor = 0.86;
  62. % helical parameter: the number of cm the beam advances in the z-direction per gantry rotation
  63. pitch = pitch_factor*(ypmax - ypmin); % pitch factor times jaw width in z-direction
  64. % 0.86 determined to be optimal
  65. % (ref.Kissick)
  66. % If a single PTV sinogram based beamlet optimization is used, specify PTV
  67. % ROI index number from Geometry file. If no particular PTV is defined,
  68. % all PTV sinograms will be used to turn beamlets off.
  69. indPTV = 18;
  70. %%%%% End of user supplied inputs %%%%%
  71. %%
  72. load(geometry_file);
  73. if size(Geometry.data,3) == 1
  74. Nrot = 1;
  75. else
  76. Nrot = ceil(Geometry.voxel_size(3).*double(size(Geometry.data,3))./pitch);
  77. end
  78. % define the limits of the angles that will be used for the calculation
  79. phimin = 0; % starting angle in radians
  80. phimax = 2*Nrot*pi;
  81. % the number of beamlets that will fill in the above-defined grid in each direction
  82. Mxp = 64/40*(xpmax - xpmin);
  83. Nyp = 1;
  84. Nphi = Nrot*51; % number of angles used in the calculation
  85. SAD = 85; % source-axis distance for the x-ray source
  86. beamlet_batch_size = 64; % number of beamlets for condor to calculate in each batch
  87. condor_folder = 'Condor';
  88. winxp_folder = 'WinXP';
  89. matlab_folder = 'Matlab';
  90. code_folder = 'convolution'; % folder where convolution code resides, relative to this code
  91. scripts_folder = 'scripts_m'; % dose calculation helper scripts
  92. orig_code_folder = 'code'; % location of the convolution code that will be used
  93. % create names for condor input and output folders
  94. input_folder = 'input';
  95. output_folder = 'output';
  96. code_folder = 'source_code';
  97. % name of the convolution/superposition executable, which will be in the
  98. % 'code' folder of each respective run type folder
  99. condor_exectuable_name = 'convolutionCondor'; % relative path on the cluster where code will be
  100. winxp_executable_name = 'convolution.exe';
  101. matlab_executable_name = 'convolution_mex'; % name of the Matlab version of the dose calculation code
  102. % set the beam parameters, assuming a helical beam trajectory
  103. % folders that will be inside the 'input' folder
  104. beamspec_folder = 'beamspecfiles'; % directory where beam files will be stored
  105. beamspec_batches_folder = 'beamspecbatches';
  106. beamspec_batch_base_name = 'beamspecbatch'; % base name for a beamlet batch file
  107. geometry_folder = 'geometryfiles';
  108. kernel_folder = 'kernelfiles'; % folder where kernel information will be saved
  109. kernel_filenames_condor = 'kernelFilenamesCondor.txt';
  110. geometry_filenames_condor = 'geometryFilenamesCondor.txt';
  111. kernel_filenames_winxp = 'kernelFilenamesWinXP.txt';
  112. geometry_filenames_winxp = 'geometryFilenamesWinXP.txt';
  113. % output folders
  114. beamlet_batches_folder = 'beamletbatches'; % folder where resulting beamlet batches will be stored
  115. beamlet_batch_base_name = 'beamletbatch'; % base name for a dose batch file
  116. batch_output_folder = 'batchoutput'; % folder to which stdout will be printed
  117. geometry_header_filename = 'geometryHeader.txt';
  118. geometry_density_filename = 'density.bin'; % save the density, not the Hounsfield units!
  119. % name for the condor submit file that will be used
  120. condor_submit_file = 'convolutionSubmit.txt';
  121. winxp_submit_file = 'convolutionSubmit.bat'; % WinXP run script format not known yet
  122. matlab_submit_file = 'matlabSubmit.m'; % Matlab run script
  123. % check the validity of the user-defined variables
  124. if xpmin >= xpmax
  125. error('xpmin must be less than xpmax.');
  126. end
  127. if ypmin >= ypmax
  128. error('ypmin must be less than ypmax.');
  129. end
  130. if phimin > phimax
  131. error('phimin must be less than or equal to phimax.');
  132. end
  133. if Mxp <= 0 | Nyp <= 0 | Nphi <= 0
  134. error('Nxp, Nyp, and Nphi must be greater than zero.');
  135. end
  136. if SAD < 50
  137. error('It is recommended that the SAD be greater than 50 cm.');
  138. end
  139. % add the Matlab script and dos calculation folders to the path
  140. path(path,[pwd '/' scripts_folder]);
  141. % the xy plane is perpendicular to the isocenter axis of the linac gantry
  142. % size of each beam aperture, making them vectors so extension to
  143. % non-uniform aperture sizes becomes obvious
  144. del_xp = (xpmax - xpmin)/Mxp;
  145. del_yp = (ypmax - ypmin)/Nyp;
  146. % Calculate the xp and yp offsets, which lie at the centers of the
  147. % apertures.
  148. xp = [xpmin:del_xp:xpmax-del_xp] + del_xp/2;
  149. yp = [ypmin:del_yp:ypmax-del_yp] + del_yp/2;
  150. % Gantry angles used. These start at phimin and go to phimax, which is
  151. % different from the way xp and yp are calculatd.
  152. if Nphi == 1 % use the average of phimin and phimax of only one gantry angle desired
  153. phi = (phimin + phimax)/2;
  154. else
  155. dphi = (phimax - phimin)/Nphi;
  156. phi = phimin:dphi:phimax;
  157. end
  158. % load data required for the dose calculator
  159. load(kernel_file);
  160. x_iso = Geometry.start(1) + (Geometry.voxel_size(1).*double(size(Geometry.data,1)))./2;
  161. y_iso = Geometry.start(2) + (Geometry.voxel_size(2).*double(size(Geometry.data,2)))./2;
  162. z_iso = Geometry.start(3);
  163. iso = [x_iso y_iso z_iso];
  164. if isfield(Geometry.ROIS) == 0
  165. sinogram = ones(Mxp,Nphi); % all beamlets are turned on
  166. elseif isfield(indPTV) == 1
  167. % PTV sinogram specifies which beams are turned on
  168. RtomoAll = tomoBeamOnOffSinogram(Geometry.ROIS{indPTV},xpmin,xpmax,Mxp,Nphi,Nrot);
  169. sinogram = RtomoAll;
  170. else
  171. sinogram = zeros(Mxp,Nphi);
  172. for i=1:length(Geometry.ROIS)
  173. if strncmp(Geometry.ROIS{i}.name,'PTV',3) == 1
  174. sinogram = sinogram + tomoBeamOnOffSinogram(Geometry.ROIS{i},xpmin,xpmax,Mxp,Nphi,Nrot);
  175. end
  176. end
  177. sinogram = double(~~sinogram);
  178. end
  179. % ensure that all data are in single precision
  180. f = fieldnames(Geometry);
  181. for k=1:length(f)
  182. if isnumeric(getfield(Geometry,f{k}))
  183. Geometry = setfield(Geometry,f{k},single(getfield(Geometry,f{k})));
  184. end
  185. end
  186. f = fieldnames(Kernels);
  187. for k=1:length(f)
  188. if isnumeric(getfield(Kernels,f{k}))
  189. Kernels = setfield(Kernels,f{k},single(getfield(Kernels,f{k})));
  190. end
  191. end
  192. % size of the CT data grid
  193. [M,N,Q] = size(Geometry.data);
  194. % Shift the isocenter
  195. Geometry.start(1) = Geometry.start(1) - iso(1);
  196. Geometry.start(2) = Geometry.start(2) - iso(2);
  197. % Make double precision copies of Geometry attributes so Matlab
  198. % mathematical operations can be performed:
  199. % voxel size
  200. dx = double(Geometry.voxel_size(1));
  201. dy = double(Geometry.voxel_size(2));
  202. dz = double(Geometry.voxel_size(3));
  203. % start location
  204. x0 = double(Geometry.start(1));
  205. y0 = double(Geometry.start(2));
  206. z0 = double(Geometry.start(3));
  207. % calculate the coordinate system for the CT in case it's needed later
  208. x = x0:dx:x0+(M-1)*dx;
  209. y = y0:dy:y0+(N-1)*dy;
  210. z = z0:dz:z0+(Q-1)*dz;
  211. % find the total number of beams
  212. Nbeam = Nphi*Mxp*Nyp;
  213. batch_num = 0; % start the count for the number of total batches
  214. % check the geometry file to ensure that it's not in Hounsfield units
  215. if length(find(Geometry.data > 20)) | length(find(Geometry.data < 0))
  216. error('Double check the Geometry structure, it may still be in Hounsfield units!');
  217. end
  218. % fill up a cell array of beam structures, grouped by batch
  219. clear batches;
  220. batch_num = 0;
  221. batches = cell(1); % start the batches cell array (cell array of beam batches)
  222. batches{1} = cell(1); % cell array of beams
  223. overall_beam_num = -1; % the first overall_beam_num will be zero
  224. % calculate beams for all source directions and apertures
  225. for k=1:Nphi % loop through all gantry angles
  226. % calculate the source location for a helical trajectory
  227. beam.SAD = single(SAD);
  228. beam.y_vec = single([SAD*sin(phi(k)) -SAD*cos(phi(k)) pitch/(2*pi)*abs(phi(k)) + iso(3)]);
  229. % the kp vector ks the beam direction, ip and jp span the beam's eye view
  230. beam.ip = single([-cos(phi(k)) -sin(phi(k)) 0]);
  231. beam.jp = single([0 0 1]);
  232. beam.kp = single([-sin(phi(k)) cos(phi(k)) 0]);
  233. for n=1:Nyp % loop through all apertures in yp-direction
  234. for m=1:Mxp % loop through all apertures in the xp-direction
  235. % calculate the beam if the tomotherapy fluence value is non-zero
  236. if sinogram(m,k) > 0
  237. num = m + (n-1)*Mxp + (k-1)*Mxp*Nyp - 1; % beamlet number (overall)
  238. overall_beam_num = overall_beam_num + 1;
  239. batch_num = floor(overall_beam_num/beamlet_batch_size); % batch number
  240. beam_num = mod(overall_beam_num,beamlet_batch_size); % beam number in this batch
  241. % set the beam aperture parameters
  242. beam.del_xp = single(del_xp);
  243. beam.del_yp = single(del_yp);
  244. beam.xp = single(-xp(m)); % this parameter is flipped in order to get the tomotherapy delivery geometry correct
  245. beam.yp = single(yp(n));
  246. beam.num = single(num); % record the beam number to avoid any later ambiguity
  247. batches{batch_num+1}{beam_num+1} = beam;
  248. end
  249. end
  250. end
  251. end
  252. % Everything else in this file is related to saving the batches in a
  253. % useable form.
  254. if Matlab_flag == 1
  255. % delete the old submission file
  256. err = rmdir(matlab_folder,'s');
  257. % create new folders for the submission
  258. mkdir([matlab_folder '/' input_folder '/' beamspec_batches_folder]);
  259. mkdir([matlab_folder '/' input_folder '/' kernel_folder]);
  260. mkdir([matlab_folder '/' input_folder '/' geometry_folder]);
  261. mkdir([matlab_folder '/' output_folder '/' batch_output_folder]);
  262. mkdir([matlab_folder '/' output_folder '/' beamlet_batches_folder]);
  263. % copy the convolution/superposition code to the submission folder
  264. copyfile(orig_code_folder,[matlab_folder '/' code_folder]);
  265. % save the kernels and geometry structures to the submission folder
  266. save([matlab_folder '/' input_folder '/' kernel_folder '/Kernels.mat'],'Kernels');
  267. fprintf(['Successfully saved Matlab kernels to ' input_folder '/' kernel_folder '\n']);
  268. save([matlab_folder '/' input_folder '/' geometry_folder '/Geometry.mat'],'Geometry');
  269. fprintf(['Successfully saved Matlab geometry to ' input_folder '/' geometry_folder '\n']);
  270. end
  271. if WinXP_flag == 1
  272. % delete the old submission file
  273. err = rmdir(winxp_folder,'s');
  274. % create folders where batch information will be sent
  275. mkdir([winxp_folder '/' input_folder '/' beamspec_batches_folder]);
  276. mkdir([winxp_folder '/' output_folder '/' beamlet_batches_folder]);
  277. mkdir([winxp_folder '/' output_folder '/' batch_output_folder]);
  278. % copy the convolution/superposition code to the submission folder
  279. copyfile(orig_code_folder,[winxp_folder '/' code_folder]);
  280. % copy the winxp executable to the submission folder
  281. copyfile([winxp_folder '/' code_folder '/Debug/' winxp_executable_name],[winxp_folder '/' winxp_executable_name]);
  282. % save the kernels and geometry files
  283. save_kernels(Kernels,[winxp_folder '/' input_folder '/' kernel_folder]);
  284. fprintf(['Successfully saved WinXP kernels to ' input_folder '/' kernel_folder '\n']);
  285. save_geometry(Geometry,[winxp_folder '/' input_folder '/' geometry_folder],geometry_header_filename,geometry_density_filename);
  286. fprintf(['Successfully saved WinXP geometry to ' input_folder '/' geometry_folder '\n']);
  287. end
  288. if Condor_flag == 1
  289. % delete the old submission file
  290. err = rmdir(condor_folder,'s');
  291. % create folders where batch information will be sent
  292. mkdir([condor_folder '/' input_folder '/' beamspec_batches_folder]);
  293. mkdir([condor_folder '/' output_folder '/' beamlet_batches_folder]);
  294. mkdir([condor_folder '/' output_folder '/' batch_output_folder]);
  295. % copy the current code folder to the new code folder
  296. copyfile(orig_code_folder,[condor_folder '/' code_folder]);
  297. % save the kernels and geometry, as this only needs to be done once
  298. save_kernels(Kernels,[condor_folder '/' input_folder '/' kernel_folder]);
  299. fprintf(['Successfully saved Condor kernels to ' input_folder '/' kernel_folder '\n']);
  300. save_geometry(Geometry,[condor_folder '/' input_folder '/' geometry_folder],geometry_header_filename,geometry_density_filename);
  301. fprintf(['Successfully saved Condor geometry to ' input_folder '/' geometry_folder '\n']);
  302. end
  303. % write the batches to files
  304. for n=1:batch_num+1
  305. batch = batches{n}; % current batch
  306. if Matlab_flag == 1
  307. save([matlab_folder '/' input_folder '/' beamspec_batches_folder '/' beamspec_batch_base_name num2str(n) '.mat'],'batch');
  308. end
  309. if WinXP_flag == 1
  310. save_beamspec_batch(batch,[winxp_folder '/' input_folder '/' beamspec_batches_folder],[beamspec_batch_base_name num2str(n-1) '.txt']);
  311. end
  312. if Condor_flag == 1
  313. save_beamspec_batch(batch,[condor_folder '/' input_folder '/' beamspec_batches_folder],[beamspec_batch_base_name num2str(n-1) '.txt']);
  314. end
  315. end
  316. if Condor_flag == 1
  317. % create geometry filenames files
  318. fid = fopen([condor_folder '/' input_folder '/' geometry_filenames_condor],'w');
  319. fprintf(fid,'geometry_header\n');
  320. fprintf(fid,['./' input_folder '/' geometry_folder '/' geometry_header_filename '\n']);
  321. fprintf(fid,'geometry_density\n');
  322. fprintf(fid,['./' input_folder '/' geometry_folder '/' geometry_density_filename '\n']);
  323. fclose(fid);
  324. % create kernel filenames files
  325. fid = fopen([condor_folder '/' input_folder '/' kernel_filenames_condor],'w');
  326. fprintf(fid,'kernel_header\n');
  327. fprintf(fid,['./' input_folder '/' kernel_folder '/kernel_header.txt\n']);
  328. fprintf(fid,'kernel_radii\n');
  329. fprintf(fid,['./' input_folder '/' kernel_folder '/radii.bin\n']);
  330. fprintf(fid,'kernel_angles\n');
  331. fprintf(fid,['./' input_folder '/' kernel_folder '/angles.bin\n']);
  332. fprintf(fid,'kernel_energies\n');
  333. fprintf(fid,['./' input_folder '/' kernel_folder '/energies.bin\n']);
  334. fprintf(fid,'kernel_primary\n');
  335. fprintf(fid,['./' input_folder '/' kernel_folder '/primary.bin\n']);
  336. fprintf(fid,'kernel_first_scatter\n');
  337. fprintf(fid,['./' input_folder '/' kernel_folder '/first_scatter.bin\n']);
  338. fprintf(fid,'kernel_second_scatter\n');
  339. fprintf(fid,['./' input_folder '/' kernel_folder '/second_scatter.bin\n']);
  340. fprintf(fid,'kernel_multiple_scatter\n');
  341. fprintf(fid,['./' input_folder '/' kernel_folder '/multiple_scatter.bin\n']);
  342. fprintf(fid,'kernel_brem_annih\n');
  343. fprintf(fid,['./' input_folder '/' kernel_folder '/brem_annih.bin\n']);
  344. fprintf(fid,'kernel_total\n');
  345. fprintf(fid,['./' input_folder '/' kernel_folder '/total.bin\n']);
  346. fprintf(fid,'kernel_fluence\n');
  347. fprintf(fid,['./' input_folder '/' kernel_folder '/fluence.bin\n']);
  348. fprintf(fid,'kernel_mu\n');
  349. fprintf(fid,['./' input_folder '/' kernel_folder '/mu.bin\n']);
  350. fprintf(fid,'kernel_mu_en\n');
  351. fprintf(fid,['./' input_folder '/' kernel_folder '/mu_en.bin\n']);
  352. fclose(fid);
  353. % write the condor submit file
  354. beamspec_batch_filename = ['./' input_folder '/' beamspec_batches_folder '/' beamspec_batch_base_name '$(Process).txt'];
  355. beamlet_batch_filename = ['./' output_folder '/' beamlet_batches_folder '/' beamlet_batch_base_name '$(Process).bin'];
  356. fid = fopen([condor_folder '/' condor_submit_file],'w');
  357. fprintf(fid,'###############################################################\n');
  358. fprintf(fid,'# Condor submission script for convolution/superposition code\n');
  359. fprintf(fid,'###############################################################\n\n');
  360. fprintf(fid,'copy_to_spool = False\n');
  361. fprintf(fid,['Executable = ' code_folder '/' condor_exectuable_name '\n']);
  362. fprintf(fid,['arguments = ' input_folder '/' kernel_filenames_condor ' ' input_folder '/' geometry_filenames_condor ' ' beamspec_batch_filename ' ' beamlet_batch_filename '\n']);
  363. fprintf(fid,['Output = ./' output_folder '/' batch_output_folder '/batchout$(Process).txt\n']);
  364. fprintf(fid,['Log = ./' output_folder '/log.txt\n']);
  365. fprintf(fid,['Queue ' num2str(batch_num + 1)]);
  366. fclose(fid);
  367. fprintf('Tomotherapy beamlet dose calculation setup complete.\n');
  368. end
  369. if WinXP_flag == 1
  370. % write the WinXP filename files
  371. fid = fopen([winxp_folder '/' input_folder '/' geometry_filenames_winxp],'w');
  372. fprintf(fid,'geometry_header\n');
  373. fprintf(fid,[input_folder '\\' geometry_folder '\\' geometry_header_filename '\n']);
  374. fprintf(fid,'geometry_density\n');
  375. fprintf(fid,[input_folder '\\' geometry_folder '\\' geometry_density_filename '\n']);
  376. fclose(fid);
  377. fid = fopen([winxp_folder '/' input_folder '/' kernel_filenames_winxp],'w');
  378. fprintf(fid,'kernel_header\n');
  379. fprintf(fid,[input_folder '\\' kernel_folder '\\kernel_header.txt\n']);
  380. fprintf(fid,'kernel_radii\n');
  381. fprintf(fid,[input_folder '\\' kernel_folder '\\radii.bin\n']);
  382. fprintf(fid,'kernel_angles\n');
  383. fprintf(fid,[input_folder '\\' kernel_folder '\\angles.bin\n']);
  384. fprintf(fid,'kernel_energies\n');
  385. fprintf(fid,[input_folder '\\' kernel_folder '\\energies.bin\n']);
  386. fprintf(fid,'kernel_primary\n');
  387. fprintf(fid,[input_folder '\\' kernel_folder '\\primary.bin\n']);
  388. fprintf(fid,'kernel_first_scatter\n');
  389. fprintf(fid,[input_folder '\\' kernel_folder '\\first_scatter.bin\n']);
  390. fprintf(fid,'kernel_second_scatter\n');
  391. fprintf(fid,[input_folder '\\' kernel_folder '\\second_scatter.bin\n']);
  392. fprintf(fid,'kernel_multiple_scatter\n');
  393. fprintf(fid,[input_folder '\\' kernel_folder '\\multiple_scatter.bin\n']);
  394. fprintf(fid,'kernel_brem_annih\n');
  395. fprintf(fid,[input_folder '\\' kernel_folder '\\brem_annih.bin\n']);
  396. fprintf(fid,'kernel_total\n');
  397. fprintf(fid,[input_folder '\\' kernel_folder '\\total.bin\n']);
  398. fprintf(fid,'kernel_fluence\n');
  399. fprintf(fid,[input_folder '\\' kernel_folder '\\fluence.bin\n']);
  400. fprintf(fid,'kernel_mu\n');
  401. fprintf(fid,[input_folder '\\' kernel_folder '\\mu.bin\n']);
  402. fprintf(fid,'kernel_mu_en\n');
  403. fprintf(fid,[input_folder '\\' kernel_folder '\\mu_en.bin\n']);
  404. fclose(fid);
  405. % line that will be used for running the code for the zeroth WinXP batch
  406. beamspec_batch_filename = [input_folder '\' beamspec_batches_folder '\' beamspec_batch_base_name num2str(0) '.txt'];
  407. beamlet_batch_filename = [output_folder '\' beamlet_batches_folder '\' beamlet_batch_base_name num2str(0) '.bin'];
  408. runline = [winxp_executable_name ' ' pwd '\' winxp_folder '\' input_folder '\' kernel_filenames_winxp ' ' pwd '\' winxp_folder '\' input_folder '\' geometry_filenames_winxp ' ' beamspec_batch_filename ' ' beamlet_batch_filename];
  409. end
  410. if Matlab_flag == 1
  411. % create a script to run the Matlab batches
  412. fid_matlab_submit = fopen([matlab_folder '\' matlab_submit_file],'w');
  413. % put all of the code into a cell array format for later printing
  414. sq = ''''; % single quote
  415. A = {...
  416. ['%% code to run matlab files'];
  417. ['Nbatches = ' num2str(prod(size(batches))) ';'];
  418. ['beamspec_batches_folder = ' sq beamspec_batches_folder sq ';'];
  419. ['beamlet_batches_folder = ' sq beamlet_batches_folder sq ';'];
  420. ['beamspec_batch_base_name = ' sq beamspec_batch_base_name sq '; %% base name for a beamspec batch file'];
  421. ['beamlet_batch_base_name = ' sq beamlet_batch_base_name sq '; %% base name for a beamlet batch file'];
  422. ['batch_output_folder = ' sq batch_output_folder sq '; %% errors sent here in future version'];
  423. ['input_folder = ' sq input_folder sq ';'];
  424. ['output_folder = ' sq output_folder sq ';'];
  425. ['kernel_folder = ' sq kernel_folder sq ';'];
  426. ['geometry_folder = ' sq geometry_folder sq ';'];
  427. ['code_folder = ' sq code_folder sq ';'];
  428. ['matlab_executable_name = ' sq matlab_executable_name sq ';'];
  429. ['%% build the Matlab code and copy the executable file to current directory'];
  430. ['curr_dir = pwd; %% current directory'];
  431. ['cd(code_folder);'];
  432. ['build; %% build command for convolution code'];
  433. ['copyfile([matlab_executable_name ' sq '.dll' sq '],curr_dir);'];
  434. ['cd(curr_dir); %% go back to the original directory'];
  435. [' '];
  436. ['%% load Geometry and Kernels'];
  437. ['load([input_folder ' sq '/' sq ' geometry_folder ' sq '/Geometry.mat' sq ']);'];
  438. ['load([input_folder ' sq '/' sq ' kernel_folder ' sq '/Kernels.mat' sq ']);'];
  439. [' '];
  440. ['for batch_num=1:Nbatches'];
  441. [' fid_batch_error = fopen([output_folder ' sq '/' sq ' batch_output_folder ' sq '/batcherr' sq ' num2str(batch_num) ' sq '.txt' sq ' ' '],' sq 'w' sq '); %% open error file for this batch'];
  442. [' fprintf([' sq 'Calculating beamlets for batch ' sq ' num2str(batch_num) ' sq ' of ' sq ' num2str(Nbatches) ' sq '.\\n' sq ']);'];
  443. [' %% open the next batch file'];
  444. [' load([input_folder ' sq '/' sq ' beamspec_batches_folder ' sq '/' sq ' beamspec_batch_base_name num2str(batch_num) ' sq '.mat' sq ']);'];
  445. [' Geometry.beam = batch;'];
  446. [' try'];
  447. [' eval([' sq 'beamlets = ' sq ' matlab_executable_name ' sq '(Kernels,Geometry);' sq ']);'];
  448. [' save([output_folder ' sq '/' sq ' beamlet_batches_folder ' sq '/' sq ' beamlet_batch_base_name num2str(batch_num) ' sq '.mat' sq '], ' sq 'beamlets' sq ');'];
  449. [' catch'];
  450. [' fprintf([' sq 'Error in the calculation for batch ' sq ' num2str(batch_num) ' sq '\\n' sq ']); %% print to stdout'];
  451. [' fprintf(fid_batch_error,[' sq 'Error in the calculation for batch ' sq ' num2str(batch_num) ' sq '\\n' sq ']); %% print to error file'];
  452. [' end'];
  453. ['end']};
  454. % print the cell array to the matlab submission file
  455. for k=1:length(A)
  456. fprintf(fid_matlab_submit,[A{k} '\n']);
  457. end
  458. fclose(fid_matlab_submit);
  459. end