convolutionCondor_orig.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /* Cconvolution.cpp */
  2. #include "defs.h"
  3. //function prototypes
  4. int load_kernels(MONO_KERNELS *, char []);
  5. int load_geometry(DOUBLE_GRID *, char []);
  6. int load_beam(BEAM *, char []);
  7. int calc_deff(DOUBLE_GRID *,DOUBLE_GRID *, DOUBLE_GRID *, BEAM *);
  8. int terma_kerma(DOUBLE_GRID *,DOUBLE_GRID *,DOUBLE_GRID *,MONO_KERNELS *,DOUBLE_GRID *);
  9. int make_poly_kernel(MONO_KERNELS *, KERNEL *);
  10. int calc_dose(DOUBLE_GRID *,DOUBLE_GRID *,DOUBLE_GRID *,KERNEL *,BEAM *, DOUBLE_GRID *);
  11. int terma_dose_masks(DOUBLE_GRID *, DOUBLE_GRID *, BEAM *);
  12. int convolution(MONO_KERNELS *, BEAM *, DOUBLE_GRID *, char *);
  13. char errstr[200]; // error string that all routines have access to
  14. int main(int argc, char *argv[])
  15. // Expects four input arguments:
  16. // 1) kernel_filenames -- contains a list of the kernel files
  17. // 2) geometry_filenames -- contains a list of the geometry files
  18. // 3) beamspec batch file -- locations of beamspec files in batch
  19. // 4) beamlet batch file -- locations of resulting beamlets in batch
  20. {
  21. int i,j;
  22. char beamspec_filename[100];
  23. char dose_filename[100];
  24. char tmpstr[200];
  25. DOUBLE_GRID density;
  26. MONO_KERNELS mono_kernels;
  27. BEAM beam;
  28. FILE *beam_batch_file;
  29. FILE *dose_batch_file;
  30. FILE *beam_file;
  31. /* // print the arguments
  32. printf("Input arguments:\n");
  33. for (j=1;j<argc;j++)
  34. printf("%s\n",argv[j]); */
  35. if (argc != 5)
  36. {
  37. printf("Expecting four input command line arguments, received %d.\n",argc);
  38. return(FAILURE);
  39. }
  40. if (load_kernels(&mono_kernels,argv[1]) == FAILURE)
  41. {
  42. sprintf(tmpstr,"Failed at loading the kernels.\n");
  43. strcat(tmpstr,errstr);
  44. strcpy(errstr,tmpstr);
  45. printf("%s\n",errstr);
  46. return(FAILURE);
  47. }
  48. if (load_geometry(&density,argv[2]) == FAILURE)
  49. {
  50. sprintf(tmpstr,"Failed at loading the geometry.\n");
  51. strcat(tmpstr,errstr);
  52. strcpy(errstr,tmpstr);
  53. printf("%s\n",errstr);
  54. return(FAILURE);
  55. }
  56. /*
  57. // diagnostic lines
  58. printf("SAD = %lf \n",beam.SAD);
  59. printf("xp = %lf \n",beam.xp);
  60. printf("yp = %lf \n",beam.yp);
  61. printf("del_xp = %lf \n",beam.del_xp);
  62. printf("del_yp = %lf \n",beam.del_yp);
  63. printf("y_vec = (%lf,%lf,%lf) \n",beam.y_vec[0],beam.y_vec[1],beam.y_vec[2]);
  64. printf("ip = (%lf,%lf,%lf) \n",beam.ip[0],beam.ip[1],beam.ip[2]);
  65. printf("jp = (%lf,%lf,%lf) \n",beam.jp[0],beam.jp[1],beam.jp[2]);
  66. printf("kp = (%lf,%lf,%lf) \n",beam.kp[0],beam.kp[1],beam.kp[2]);
  67. printf("Xcount = %d, Ycount = %d, Zcount = %d \n",density.x_count,density.y_count,density.z_count);
  68. printf("start = (%lf,%lf,%lf) \n",density.start.x,density.start.y,density.start.z);
  69. printf("inc = (%lf,%lf,%lf) \n",density.inc.x,density.inc.y,density.inc.z); */
  70. // open the beam specification batch file
  71. if ((beam_batch_file = fopen(argv[3],"r")) == NULL)
  72. {
  73. printf("Failed to open beamspec batch file %s\n",argv[3]);
  74. return(FAILURE);
  75. }
  76. // open the dose batch file
  77. if ((dose_batch_file = fopen(argv[4],"r")) == NULL)
  78. {
  79. printf("Failed to open dose batch file %s\n",argv[4]);
  80. return(FAILURE);
  81. }
  82. // Do convolution calculations for all consistent beamspec and dose
  83. // filenames. If a calculation for a beamlet fails, print an error
  84. // and move on to the next beamspec file.
  85. while ((fscanf(beam_batch_file,"%s",beamspec_filename) != EOF)
  86. && (fscanf(dose_batch_file,"%s",dose_filename) != EOF))
  87. {
  88. // open the beamspec and dose files
  89. if ((beam_file = fopen(beamspec_filename,"r")) == NULL)
  90. printf("Failed to open beamspec file %s\n",beamspec_filename);
  91. else
  92. {
  93. // load the information for the current beam
  94. if (load_beam(&beam,beamspec_filename) == FAILURE)
  95. printf("Failed at to load beamspec file %s\n",beamspec_filename);
  96. else if (convolution(&mono_kernels,&beam,&density,dose_filename) == FAILURE)
  97. // an error occurred, so print the error string to standard out
  98. // but do not terminate the remaining beam batches
  99. {
  100. printf("Error in the calculation for beamlet file %s\n",dose_filename);
  101. printf("%s\n",errstr);
  102. }
  103. else
  104. printf("Successfully calculated %s\n",dose_filename);
  105. }
  106. }
  107. // free the density grid
  108. free(density.matrix);
  109. // only need to free angular and radial boundaries for the first
  110. // kernel, since other kernel boundaries just point to the same place
  111. free(mono_kernels.kernel[0].angular_boundary);
  112. free(mono_kernels.kernel[0].radial_boundary);
  113. // free the kernels
  114. free(mono_kernels.energy);
  115. free(mono_kernels.fluence);
  116. free(mono_kernels.mu);
  117. free(mono_kernels.mu_en);
  118. for (i=0;i<mono_kernels.nkernels;i++)
  119. for (j=0;j<N_KERNEL_CATEGORIES;j++)
  120. free(mono_kernels.kernel[i].matrix[j]);
  121. return(SUCCESS);
  122. }
  123. int convolution(MONO_KERNELS *mono_kernels, BEAM *beam, DOUBLE_GRID *density, char *dose_filename)
  124. // routine that actually performs the convolution for a given kernel, beam, and geometry
  125. {
  126. int i,j,M,N,Q,Nind,Ntotal; // dimensions of the CT density grid
  127. int *dose_ind;
  128. double *dose_data;
  129. char tmpstr[200]; // temporary string
  130. FILE *dose_file;
  131. DOUBLE_GRID terma_mask;
  132. DOUBLE_GRID dose_mask;
  133. DOUBLE_GRID deff;
  134. DOUBLE_GRID terma;
  135. DOUBLE_GRID kermac;
  136. DOUBLE_GRID dose;
  137. KERNEL poly_kernel;
  138. // copy the density grid dimensions to the calculation grids
  139. copy_grid_geometry(density,&terma_mask);
  140. copy_grid_geometry(density,&dose_mask);
  141. copy_grid_geometry(density,&deff);
  142. copy_grid_geometry(density,&terma);
  143. copy_grid_geometry(density,&kermac);
  144. copy_grid_geometry(density,&dose);
  145. // dimensions of all the grids
  146. M = density->x_count;
  147. N = density->y_count;
  148. Q = density->z_count;
  149. Ntotal = M*N*Q;
  150. // attempt to open the dose file
  151. if ((dose_file = fopen(dose_filename,"wb")) == NULL)
  152. {
  153. sprintf(errstr,"Failed to open dose file");
  154. return(FAILURE);
  155. }
  156. // Allocate memory for all of the grids and fill them all with zeros
  157. if ((terma_mask.matrix = (double *)malloc(sizeof(double)*Ntotal)) == NULL)
  158. {
  159. sprintf(errstr,"Could not allocate memory for terma_mask.");
  160. return(FAILURE);
  161. }
  162. if ((dose_mask.matrix = (double *)malloc(sizeof(double)*Ntotal)) == NULL)
  163. {
  164. sprintf(errstr,"Could not allocate memory for dose_mask.");
  165. return(FAILURE);
  166. }
  167. if ((deff.matrix = (double *)malloc(sizeof(double)*Ntotal)) == NULL)
  168. {
  169. sprintf(errstr,"Could not allocate memory for deff.");
  170. return(FAILURE);
  171. }
  172. if ((terma.matrix = (double *)malloc(sizeof(double)*Ntotal)) == NULL)
  173. {
  174. sprintf(errstr,"Could not allocate memory for terma.");
  175. return(FAILURE);
  176. }
  177. if ((kermac.matrix = (double *)malloc(sizeof(double)*Ntotal)) == NULL)
  178. {
  179. sprintf(errstr,"Could not allocate memory for kermac.");
  180. return(FAILURE);
  181. }
  182. if ((dose.matrix = (double *)malloc(sizeof(double)*Ntotal)) == NULL)
  183. {
  184. sprintf(errstr,"Could not allocate memory for dose.");
  185. return(FAILURE);
  186. }
  187. for (i=0;i<Ntotal;i++)
  188. {
  189. terma_mask.matrix[i] = 0.0;
  190. dose_mask.matrix[i] = 0.0;
  191. deff.matrix[i] = 0.0;
  192. terma.matrix[i] = 0.0;
  193. kermac.matrix[i] = 0.0;
  194. dose.matrix[i] = 0.0;
  195. }
  196. /* start calculations */
  197. // If a failure occurs in any calculation, append the error
  198. // onto the error string and then return a FAILURE.
  199. // create terma and dose masks
  200. if (SUCCESS != terma_dose_masks(&terma_mask,&dose_mask,beam))
  201. {
  202. sprintf(tmpstr,"Failed in terma_dose_masks!\n");
  203. strcat(tmpstr,errstr);
  204. strcpy(errstr,tmpstr);
  205. return(FAILURE);
  206. }
  207. //create polyenergetic kernel from mono kernels and fluence,mu data
  208. if (SUCCESS != make_poly_kernel(mono_kernels,&poly_kernel) )
  209. {
  210. sprintf(tmpstr,"Failed making polyenergetic kernel!\n");
  211. strcat(tmpstr,errstr);
  212. strcpy(errstr,tmpstr);
  213. return(FAILURE);
  214. }
  215. //create effective depth array from density array
  216. if (SUCCESS != calc_deff(density,&deff,&terma_mask,beam))
  217. {
  218. sprintf(tmpstr,"Failed in calc_deff!\n");
  219. strcat(tmpstr,errstr);
  220. strcpy(errstr,tmpstr);
  221. return(FAILURE);
  222. }
  223. //create kerma and terma arrays
  224. //note kerma is collision kerma and is used for a kernel hardening correction
  225. if (SUCCESS != terma_kerma(&deff,&terma,&kermac,mono_kernels,&terma_mask))
  226. {
  227. sprintf(tmpstr,"Failed in terma_kerma calculation!\n");
  228. strcat(tmpstr,errstr);
  229. strcpy(errstr,tmpstr);
  230. return(FAILURE);
  231. }
  232. //use all this stuff to calculate dose
  233. if ( (SUCCESS != calc_dose(density,&terma,&dose,&poly_kernel,beam,&dose_mask)) )
  234. {
  235. sprintf(tmpstr,"Failed calculating dose!\n");
  236. strcat(tmpstr,errstr);
  237. strcpy(errstr,tmpstr);
  238. return(FAILURE);
  239. }
  240. // count the number of non-zero dose values
  241. Nind = 0;
  242. for (i=0;i<Ntotal;i++)
  243. if (dose.matrix[i] > 0.0)
  244. Nind++;
  245. // allocate memory for sparse dose data
  246. dose_ind = (int *)malloc(sizeof(int)*Nind);
  247. dose_data = (double *)malloc(sizeof(double)*Nind);
  248. // store the sparse data
  249. j = 0; // index just for the sparse data
  250. for (i=0;i<Ntotal;i++)
  251. if (dose.matrix[i] > 0.0)
  252. {
  253. dose_ind[j] = i;
  254. dose_data[j] = dose.matrix[i];
  255. j++;
  256. }
  257. // save dose to a file
  258. // save the total file size first, then the number of non-zero elements
  259. fwrite(&M,sizeof(int),1,dose_file);
  260. fwrite(&N,sizeof(int),1,dose_file);
  261. fwrite(&Q,sizeof(int),1,dose_file);
  262. fwrite(&Nind,sizeof(int),1,dose_file);
  263. fwrite(dose_ind,sizeof(int),Nind,dose_file);
  264. fwrite(dose_data,sizeof(double),Nind,dose_file);
  265. fclose(dose_file);
  266. //diagnostic lines:
  267. /* FILE *fid;
  268. fid = fopen("dose.bin","wb");
  269. fwrite(dose.matrix,sizeof(double),Ntotal,fid);
  270. fclose(fid);
  271. fid = fopen("terma.bin","wb");
  272. fwrite(terma.matrix,sizeof(double),Ntotal,fid);
  273. fclose(fid);
  274. fid = fopen("kermac.bin","wb");
  275. fwrite(kermac.matrix,sizeof(double),Ntotal,fid);
  276. fclose(fid);
  277. fid = fopen("deff.bin","wb");
  278. fwrite(deff.matrix,sizeof(double),Ntotal,fid);
  279. fclose(fid);
  280. fid = fopen("terma_mask.bin","wb");
  281. fwrite(terma_mask.matrix,sizeof(double),Ntotal,fid);
  282. fclose(fid);
  283. fid = fopen("dose_mask.bin","wb");
  284. fwrite(dose_mask.matrix,sizeof(double),Ntotal,fid);
  285. fclose(fid);
  286. fid = fopen("density.bin","wb");
  287. fwrite(density->matrix,sizeof(double),Ntotal,fid);
  288. fclose(fid); */
  289. // free the calculation grids
  290. free(terma_mask.matrix);
  291. free(dose_mask.matrix);
  292. free(deff.matrix);
  293. free(terma.matrix);
  294. free(kermac.matrix);
  295. free(dose.matrix);
  296. free(poly_kernel.angular_boundary);
  297. free(poly_kernel.radial_boundary);
  298. // free(poly_kernel.total_matrix);
  299. for (j=0;j<N_KERNEL_CATEGORIES;j++)
  300. free(poly_kernel.matrix[j]);
  301. return(SUCCESS);
  302. }