update_factor.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Calculates the update factor for linear least squares optimization
  2. #include "lsq.h"
  3. extern char errstr[200]; // error string that all routines have access to
  4. extern int firstIterFlag;
  5. int calc_update_factor(GRID_ARRAY *beamlets, GRID *dose, PRESC *presc, int beamlet_num, float *update_factor, PRESCGRID *prescGrid)
  6. // Calculates a weight update factor based on the method described by
  7. // Shepard PMB 45, 69-90 (2000). The weight update factor is based on the
  8. // derivative of the objective function, which is zero when the minimum has
  9. // been reached.
  10. {
  11. int i,j,k,m;
  12. float Eplus_num, Eplus_den; // overdose penalty terms
  13. float Eminus_num, Eminus_den; // underdose penalty terms
  14. float Edvh_plus_num, Edvh_plus_den; // DVH overdose penalty terms
  15. float Edvh_minus_num, Edvh_minus_den; // DVH underdose penalty terms
  16. float numerator, denominator;
  17. float A;
  18. float diff, doseValue, dPlus, dMinus, Dij;
  19. float del_d_plus;
  20. float del_d_minus;
  21. // initialize numerator and denominator of the update factor to zero
  22. numerator = 0.0;
  23. denominator = 0.0;
  24. for (j=0;j<beamlets->array[beamlet_num].size;j++)
  25. {
  26. i = beamlets->array[beamlet_num].indices[j];
  27. Dij = beamlets->array[beamlet_num].data[j];
  28. doseValue = dose->matrix[i];
  29. // initialize objective function terms for voxel i to zero
  30. Eplus_num = 0.0;
  31. Eplus_den = 0.0;
  32. Eminus_num = 0.0;
  33. Eminus_den = 0.0;
  34. Edvh_plus_num = 0.0;
  35. Edvh_plus_den = 0.0;
  36. Edvh_minus_num = 0.0;
  37. Edvh_minus_den = 0.0;
  38. for (m=0;m<prescGrid->numNodes[i];m++)
  39. {
  40. k = prescGrid->array[i][m].tissueInd; // tissue type index
  41. A = presc->array[k].alpha/(float)presc->array[k].Nind;
  42. // overdose penalty term
  43. if (presc->array[k].betaPlus > 0.0)
  44. {
  45. dPlus = prescGrid->array[i][m].dPlus;
  46. if (doseValue > dPlus)
  47. {
  48. Eplus_num += presc->array[k].betaPlus*dPlus*A;
  49. Eplus_den += presc->array[k].betaPlus*doseValue*A;
  50. }
  51. }
  52. // underdose penalty term
  53. if (presc->array[k].betaMinus > 0.0)
  54. {
  55. dMinus = prescGrid->array[i][m].dMinus;
  56. if (doseValue < dMinus)
  57. {
  58. Eminus_num += presc->array[k].betaMinus*dMinus*A;
  59. Eminus_den += presc->array[k].betaMinus*doseValue*A;
  60. }
  61. }
  62. // DVH overdose penalty term
  63. if (presc->array[k].betaVPlus > 0.0)
  64. {
  65. del_d_plus = presc->array[k].dvh.del_d_plus;
  66. diff = doseValue - presc->array[k].dVPlus;
  67. if (diff >= 0.0 && diff <= del_d_plus)
  68. {
  69. Edvh_plus_num += presc->array[k].betaVPlus*presc->array[k].dVPlus*A;
  70. Edvh_plus_den += presc->array[k].betaVPlus*doseValue*A;
  71. }
  72. }
  73. // DVH underdose penalty term
  74. if (presc->array[k].betaVMinus > 0.0)
  75. {
  76. del_d_minus = presc->array[k].dvh.del_d_minus;
  77. diff = doseValue - presc->array[k].dVMinus;
  78. if (diff >= del_d_minus && diff <= 0.0)
  79. {
  80. Edvh_minus_num += presc->array[k].betaVMinus*presc->array[k].dVMinus*A;
  81. Edvh_minus_den += presc->array[k].betaVMinus*doseValue*A;
  82. }
  83. }
  84. }
  85. numerator += Dij*(Eplus_num + Eminus_num + Edvh_plus_num + Edvh_minus_num);
  86. denominator += Dij*(Eplus_den + Eminus_den + Edvh_plus_den + Edvh_minus_den);
  87. }
  88. // calculate the update factor, avoiding divide-by-zero errors
  89. if (denominator == 0.0)
  90. *update_factor = 0.0; // diverging update factor should be forced to zero, turning that weight off
  91. else
  92. *update_factor = numerator/denominator;
  93. return(SUCCESS);
  94. }