Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/hadrontherapy/src/HadrontherapyRBE.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /examples/advanced/hadrontherapy/src/HadrontherapyRBE.cc (Version 11.3.0) and /examples/advanced/hadrontherapy/src/HadrontherapyRBE.cc (Version 10.6)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26                                                    26 
 27 #include "HadrontherapyRBE.hh"                     27 #include "HadrontherapyRBE.hh"
 28 #include "HadrontherapyMatrix.hh"                  28 #include "HadrontherapyMatrix.hh"
 29                                                    29 
 30 #include "G4UnitsTable.hh"                         30 #include "G4UnitsTable.hh"
 31 #include "G4SystemOfUnits.hh"                      31 #include "G4SystemOfUnits.hh"
 32 #include "G4GenericMessenger.hh"                   32 #include "G4GenericMessenger.hh"
 33 #include "G4Pow.hh"                                33 #include "G4Pow.hh"
 34                                                    34 
 35 #include <fstream>                                 35 #include <fstream>
 36 #include <iostream>                                36 #include <iostream>
 37 #include <iomanip>                                 37 #include <iomanip>
 38 #include <cstdlib>                                 38 #include <cstdlib>
 39 #include <algorithm>                               39 #include <algorithm>
 40 #include <sstream>                                 40 #include <sstream>
 41 #include <numeric>                                 41 #include <numeric>
 42                                                    42 
 43 #define width 15L                                  43 #define width 15L
 44                                                    44 
 45 using namespace std;                               45 using namespace std;
 46                                                    46 
 47 // TODO: Perhaps we can use the material datab     47 // TODO: Perhaps we can use the material database???
 48 const std::map<G4String, G4int> elements = {       48 const std::map<G4String, G4int> elements = {
 49     {"H", 1},                                      49     {"H", 1},
 50     {"He", 2},                                     50     {"He", 2},
 51     {"Li", 3},                                     51     {"Li", 3},
 52     {"Be", 4},                                     52     {"Be", 4},
 53     {"B", 5},                                      53     {"B", 5},
 54     {"C", 6},                                      54     {"C", 6},
 55     {"N", 7},                                      55     {"N", 7},
 56     {"O", 8},                                      56     {"O", 8},
 57     {"F", 9},                                      57     {"F", 9},
 58     {"Ne", 10}                                     58     {"Ne", 10}
 59 };                                                 59 };
 60                                                    60 
 61 HadrontherapyRBE* HadrontherapyRBE::instance =     61 HadrontherapyRBE* HadrontherapyRBE::instance = nullptr;
 62                                                    62 
 63 HadrontherapyRBE* HadrontherapyRBE::GetInstanc     63 HadrontherapyRBE* HadrontherapyRBE::GetInstance()
 64 {                                                  64 {
 65     return instance;                               65     return instance;
 66 }                                                  66 }
 67                                                    67 
 68 HadrontherapyRBE* HadrontherapyRBE::CreateInst     68 HadrontherapyRBE* HadrontherapyRBE::CreateInstance(G4int voxelX, G4int voxelY, G4int voxelZ, G4double massOfVoxel)
 69 {                                                  69 {
 70     if (instance) delete instance;                 70     if (instance) delete instance;
 71     instance = new HadrontherapyRBE(voxelX, vo     71     instance = new HadrontherapyRBE(voxelX, voxelY, voxelZ, massOfVoxel);
 72     return instance;                               72     return instance;
 73 }                                                  73 }
 74                                                    74 
 75 HadrontherapyRBE::HadrontherapyRBE(G4int voxel     75 HadrontherapyRBE::HadrontherapyRBE(G4int voxelX, G4int voxelY, G4int voxelZ, G4double massOfVoxel)
 76     : fNumberOfVoxelsAlongX(voxelX),               76     : fNumberOfVoxelsAlongX(voxelX),
 77       fNumberOfVoxelsAlongY(voxelY),               77       fNumberOfVoxelsAlongY(voxelY),
 78       fNumberOfVoxelsAlongZ(voxelZ),               78       fNumberOfVoxelsAlongZ(voxelZ),
 79       fNumberOfVoxels(voxelX * voxelY * voxelY     79       fNumberOfVoxels(voxelX * voxelY * voxelY),
 80       fMassOfVoxel(massOfVoxel)                    80       fMassOfVoxel(massOfVoxel)
 81                                                    81 
 82 {                                                  82 {
 83     CreateMessenger();                             83     CreateMessenger();
 84                                                    84     
 85     // x axis for 1-D plot                         85     // x axis for 1-D plot
 86     // TODO: Remove                                86     // TODO: Remove
 87     x = new G4double[fNumberOfVoxelsAlongX];       87     x = new G4double[fNumberOfVoxelsAlongX];
 88                                                    88 
 89     for (G4int i = 0; i < fNumberOfVoxelsAlong     89     for (G4int i = 0; i < fNumberOfVoxelsAlongX; i++)
 90     {                                              90     {
 91         x[i] = 0;                                  91         x[i] = 0;
 92     }                                              92     }
 93                                                    93 
 94 }                                                  94 }
 95                                                    95 
 96 HadrontherapyRBE::~HadrontherapyRBE()              96 HadrontherapyRBE::~HadrontherapyRBE()
 97 {                                                  97 {
 98     delete[] x;                                    98     delete[] x;
 99     delete fMessenger;                             99     delete fMessenger;
100 }                                                 100 }
101                                                   101 
102 void HadrontherapyRBE::PrintParameters()          102 void HadrontherapyRBE::PrintParameters()
103 {                                                 103 {
104     G4cout << "RBE Cell line: " << fActiveCell    104     G4cout << "RBE Cell line: " << fActiveCellLine << G4endl;
105     G4cout << "RBE Dose threshold value: " <<     105     G4cout << "RBE Dose threshold value: " << fDoseCut / gray << " gray" << G4endl;
106     G4cout << "RBE Alpha X value: " << fAlphaX    106     G4cout << "RBE Alpha X value: " << fAlphaX * gray << " 1/gray" << G4endl;
107     G4cout << "RBE Beta X value: " << fBetaX *    107     G4cout << "RBE Beta X value: " << fBetaX * pow(gray, 2.0) << " 1/gray2" << G4endl;
108 }                                                 108 }
109                                                   109 
110 /**                                               110 /**
111   * @short Split string into parts using a del    111   * @short Split string into parts using a delimiter.
112   *                                               112   *
113   * @param line a string to be splitted           113   * @param line a string to be splitted
114   * @param delimiter a string to be looked for    114   * @param delimiter a string to be looked for
115   *                                               115   *
116   * Usage: Help function for reading CSV          116   * Usage: Help function for reading CSV
117   * Also remove spaces and quotes around.         117   * Also remove spaces and quotes around.
118   * Note: If delimiter is inside a string, the    118   * Note: If delimiter is inside a string, the function fails!
119   */                                              119   */
120 vector<G4String> split(const G4String& line, c    120 vector<G4String> split(const G4String& line, const G4String& delimiter)
121 {                                                 121 {
122     vector<G4String> result;                      122     vector<G4String> result;
123                                                   123 
124     size_t current = 0;                           124     size_t current = 0;
125     size_t pos = 0;                               125     size_t pos = 0;
126                                                   126 
127     while(pos != G4String::npos)                  127     while(pos != G4String::npos)
128     {                                             128     {
129         pos = line.find(delimiter, current);      129         pos = line.find(delimiter, current);
130         G4String token = line.substr(current,     130         G4String token = line.substr(current, pos - current);
131         G4StrUtil::strip(token);               << 131         token = token.strip(G4String::both);
132         G4StrUtil::strip(token, '\"');         << 132         token = token.strip(G4String::both, '\"');
133         result.push_back(token);                  133         result.push_back(token);
134         current = pos + delimiter.size();         134         current = pos + delimiter.size();
135     }                                             135     }
136     return result;                                136     return result;
137 }                                                 137 }
138                                                   138 
139 void HadrontherapyRBE::LoadLEMTable(G4String p    139 void HadrontherapyRBE::LoadLEMTable(G4String path)
140 {                                                 140 {
141     // TODO: Check for presence? Perhaps we wa    141     // TODO: Check for presence? Perhaps we want to be able to load more
142                                                   142 
143     ifstream in(path);                            143     ifstream in(path);
144     if (!in)                                      144     if (!in)
145     {                                             145     {
146         stringstream ss;                          146         stringstream ss;
147         ss << "Cannot open LEM table input fil    147         ss << "Cannot open LEM table input file: " << path;
148         G4Exception("HadrontherapyRBE::LoadDat    148         G4Exception("HadrontherapyRBE::LoadData", "WrongTable", FatalException, ss.str().c_str());
149     }                                             149     }
150                                                   150 
151     // Start with the first line                  151     // Start with the first line
152     G4String line;                                152     G4String line;
153     if (!getline(in, line))                       153     if (!getline(in, line))
154     {                                             154     {
155         stringstream ss;                          155         stringstream ss;
156         ss << "Cannot read header from the LEM    156         ss << "Cannot read header from the LEM table file: " << path;
157         G4Exception("HadrontherapyRBE::LoadLEM    157         G4Exception("HadrontherapyRBE::LoadLEMTable", "CannotReadHeader", FatalException, ss.str().c_str());
158     }                                             158     }
159     vector<G4String> header = split(line, ",")    159     vector<G4String> header = split(line, ",");
160                                                   160 
161     // Find the order of columns                  161     // Find the order of columns
162     std::vector<G4String> columns = { "alpha_x    162     std::vector<G4String> columns = { "alpha_x", "beta_x", "D_t", "specific_energy", "alpha", "beta", "cell", "particle"};
163     std::map<G4String, int> columnIndices;        163     std::map<G4String, int> columnIndices;
164     for (auto columnName : columns)               164     for (auto columnName : columns)
165     {                                             165     {
166         auto pos = find(header.begin(), header    166         auto pos = find(header.begin(), header.end(), columnName);
167         if (pos == header.end())                  167         if (pos == header.end())
168         {                                         168         {
169             stringstream ss;                      169             stringstream ss;
170             ss << "Column " << columnName << "    170             ss << "Column " << columnName << " not present in the LEM table file.";
171             G4Exception("HadrontherapyRBE::Loa    171             G4Exception("HadrontherapyRBE::LoadLEMTable", "ColumnNotPresent", FatalException, ss.str().c_str());
172         }                                         172         }
173         else                                      173         else
174         {                                         174         {
175             columnIndices[columnName] = (G4int << 175             columnIndices[columnName] = distance(header.begin(), pos);
176         }                                         176         }
177     }                                             177     }
178                                                   178 
179     // Continue line by line                      179     // Continue line by line
180     while (getline(in, line))                     180     while (getline(in, line))
181     {                                             181     {
182         vector<G4String> lineParts = split(lin    182         vector<G4String> lineParts = split(line, ",");
183         G4String cellLine = lineParts[columnIn    183         G4String cellLine = lineParts[columnIndices["cell"]];
184         G4int element = elements.at(lineParts[    184         G4int element = elements.at(lineParts[columnIndices["particle"]]);
185                                                   185 
186         fTablesEnergy[cellLine][element].push_    186         fTablesEnergy[cellLine][element].push_back(
187             stod(lineParts[columnIndices["spec    187             stod(lineParts[columnIndices["specific_energy"]]) * MeV
188         );                                        188         );
189         fTablesAlpha[cellLine][element].push_b    189         fTablesAlpha[cellLine][element].push_back(
190             stod(lineParts[columnIndices["alph    190             stod(lineParts[columnIndices["alpha"]])
191         );                                        191         );
192         /* fTablesLet[cellLine][element].push_    192         /* fTablesLet[cellLine][element].push_back(
193             stod(lineParts[columnIndices["let"    193             stod(lineParts[columnIndices["let"]])
194         ); */                                     194         ); */
195         fTablesBeta[cellLine][element].push_ba    195         fTablesBeta[cellLine][element].push_back(
196             stod(lineParts[columnIndices["beta    196             stod(lineParts[columnIndices["beta"]])
197         );                                        197         );
198                                                   198 
199         fTablesAlphaX[cellLine] = stod(linePar    199         fTablesAlphaX[cellLine] = stod(lineParts[columnIndices["alpha_x"]]) / gray;
200         fTablesBetaX[cellLine] = stod(linePart    200         fTablesBetaX[cellLine] = stod(lineParts[columnIndices["beta_x"]]) / (gray * gray);
201         fTablesDoseCut[cellLine] = stod(linePa    201         fTablesDoseCut[cellLine] = stod(lineParts[columnIndices["D_t"]]) * gray;
202     }                                             202     }
203                                                   203 
204     // Sort the tables by energy                  204     // Sort the tables by energy
205     // (https://stackoverflow.com/a/12399290/2    205     // (https://stackoverflow.com/a/12399290/2692780)
206     for (auto aPair : fTablesEnergy)              206     for (auto aPair : fTablesEnergy)
207     {                                             207     {
208         for (auto ePair : aPair.second)           208         for (auto ePair : aPair.second)
209         {                                         209         {
210             vector<G4double>& tableEnergy = fT    210             vector<G4double>& tableEnergy = fTablesEnergy[aPair.first][ePair.first];
211             vector<G4double>& tableAlpha = fTa    211             vector<G4double>& tableAlpha = fTablesAlpha[aPair.first][ePair.first];
212             vector<G4double>& tableBeta = fTab    212             vector<G4double>& tableBeta = fTablesBeta[aPair.first][ePair.first];
213                                                   213 
214             vector<size_t> idx(tableEnergy.siz    214             vector<size_t> idx(tableEnergy.size());
215             iota(idx.begin(), idx.end(), 0);      215             iota(idx.begin(), idx.end(), 0);
216             sort(idx.begin(), idx.end(),          216             sort(idx.begin(), idx.end(),
217                 [&tableEnergy](size_t i1, size    217                 [&tableEnergy](size_t i1, size_t i2) {return tableEnergy[i1] < tableEnergy[i2];});
218                                                   218 
219             vector<vector<G4double>*> tables =    219             vector<vector<G4double>*> tables = {
220                 &tableEnergy, &tableAlpha, &ta    220                 &tableEnergy, &tableAlpha, &tableBeta
221             };                                    221             };
222             for (vector<G4double>* table : tab    222             for (vector<G4double>* table : tables)
223             {                                     223             {
224                 vector<G4double> copy = *table    224                 vector<G4double> copy = *table;
225                 for (size_t i = 0; i < copy.si    225                 for (size_t i = 0; i < copy.size(); ++i)
226                 {                                 226                 {
227                     (*table)[i] = copy[idx[i]]    227                     (*table)[i] = copy[idx[i]];
228                 }                                 228                 }
229                 // G4cout << (*table)[0];         229                 // G4cout << (*table)[0];
230                 // reorder(*table, idx);          230                 // reorder(*table, idx);
231                 G4cout << (*table)[0] << G4end    231                 G4cout << (*table)[0] << G4endl;
232             }                                     232             }
233         }                                         233         }
234     }                                             234     }
235                                                   235 
236     if (fVerboseLevel > 0)                        236     if (fVerboseLevel > 0)
237     {                                             237     {
238         G4cout << "RBE: read LEM data for the     238         G4cout << "RBE: read LEM data for the following cell lines and elements [number of points]: " << G4endl;
239         for (auto aPair : fTablesEnergy)          239         for (auto aPair : fTablesEnergy)
240         {                                         240         {
241             G4cout << "- " << aPair.first << "    241             G4cout << "- " << aPair.first << ": ";
242             for (auto ePair : aPair.second)       242             for (auto ePair : aPair.second)
243             {                                     243             {
244                 G4cout << ePair.first << "[" <    244                 G4cout << ePair.first << "[" << ePair.second.size() << "] ";
245             }                                     245             }
246             G4cout << G4endl;                     246             G4cout << G4endl;
247         }                                         247         }
248     }                                             248     }
249 }                                                 249 }
250                                                   250 
251 void HadrontherapyRBE::SetCellLine(G4String na    251 void HadrontherapyRBE::SetCellLine(G4String name)
252 {                                                 252 {
253     if (fTablesEnergy.size() == 0)                253     if (fTablesEnergy.size() == 0)
254     {                                             254     {
255         G4Exception("HadrontherapyRBE::SetCell    255         G4Exception("HadrontherapyRBE::SetCellLine", "NoCellLine", FatalException, "Cannot select cell line, probably LEM table not loaded yet?");
256     }                                             256     }
257     if (fTablesEnergy.find(name) == fTablesEne    257     if (fTablesEnergy.find(name) == fTablesEnergy.end())
258     {                                             258     {
259         stringstream str;                         259         stringstream str;
260         str << "Cell line " << name << " not f    260         str << "Cell line " << name << " not found in the LEM table.";
261         G4Exception("HadrontherapyRBE::SetCell    261         G4Exception("HadrontherapyRBE::SetCellLine", "", FatalException, str.str().c_str());
262     }                                             262     }
263     else                                          263     else
264     {                                             264     {
265         fAlphaX = fTablesAlphaX[name];            265         fAlphaX = fTablesAlphaX[name];
266         fBetaX = fTablesBetaX[name];              266         fBetaX = fTablesBetaX[name];
267         fDoseCut = fTablesDoseCut[name];          267         fDoseCut = fTablesDoseCut[name];
268                                                   268 
269         fActiveTableEnergy = &fTablesEnergy[na    269         fActiveTableEnergy = &fTablesEnergy[name];
270         fActiveTableAlpha = &fTablesAlpha[name    270         fActiveTableAlpha = &fTablesAlpha[name];
271         fActiveTableBeta = &fTablesBeta[name];    271         fActiveTableBeta = &fTablesBeta[name];
272                                                   272 
273         fMinZ = 0;                                273         fMinZ = 0;
274         fMaxZ = 0;                                274         fMaxZ = 0;
275         fMinEnergies.clear();                     275         fMinEnergies.clear();
276         fMaxEnergies.clear();                     276         fMaxEnergies.clear();
277                                                   277 
278         for (auto energyPair : *fActiveTableEn    278         for (auto energyPair : *fActiveTableEnergy)
279         {                                         279         {
280             if (!fMinZ || (energyPair.first <     280             if (!fMinZ || (energyPair.first < fMinZ)) fMinZ = energyPair.first;
281             if (energyPair.first > fMaxZ) fMax    281             if (energyPair.first > fMaxZ) fMaxZ = energyPair.first;
282                                                   282 
283             fMinEnergies[energyPair.first] = e    283             fMinEnergies[energyPair.first] = energyPair.second[0];
284             fMaxEnergies[energyPair.first] = e    284             fMaxEnergies[energyPair.first] = energyPair.second[energyPair.second.size() - 1];
285         }                                         285         }
286     }                                             286     }
287                                                   287 
288     fActiveCellLine = name;                       288     fActiveCellLine = name;
289                                                   289 
290     if (fVerboseLevel > 0)                        290     if (fVerboseLevel > 0)
291     {                                             291     {
292         G4cout << "RBE: cell line " << name <<    292         G4cout << "RBE: cell line " << name << " selected." << G4endl;
293     }                                             293     }
294 }                                                 294 }
295                                                   295 
296 std::tuple<G4double, G4double> HadrontherapyRB    296 std::tuple<G4double, G4double> HadrontherapyRBE::GetHitAlphaAndBeta(G4double E, G4int Z)
297 {                                                 297 {
298     if (!fActiveTableEnergy)                      298     if (!fActiveTableEnergy)
299     {                                             299     {
300         G4Exception("HadrontherapyRBE::GetHitA    300         G4Exception("HadrontherapyRBE::GetHitAlphaAndBeta", "NoCellLine", FatalException, "No cell line selected. Please, do it using the /rbe/cellLine command.");
301     }                                             301     }
302                                                   302 
303     // Check we are in the tables                 303     // Check we are in the tables
304     if ((Z < fMinZ) || (Z > fMaxZ))               304     if ((Z < fMinZ) || (Z > fMaxZ))
305     {                                             305     {
306         if (fVerboseLevel > 1)                    306         if (fVerboseLevel > 1)
307         {                                         307         {
308             stringstream str;                     308             stringstream str;
309             str << "Alpha & beta calculation s    309             str << "Alpha & beta calculation supported only for ";
310             str << fMinZ << " <= Z <= " << fMa    310             str << fMinZ << " <= Z <= " << fMaxZ << ", but " << Z << " requested.";
311             G4Exception("HadrontherapyRBE::Get    311             G4Exception("HadrontherapyRBE::GetHitAlphaAndBeta", "", JustWarning, str.str().c_str());
312         }                                         312         }
313         return make_tuple<G4double, G4double>(    313         return make_tuple<G4double, G4double>( 0.0, 0.0 ); //out of table!
314     }                                             314     }
315     if ((E < fMinEnergies[Z]) || (E >= fMaxEne    315     if ((E < fMinEnergies[Z]) || (E >= fMaxEnergies[Z]))
316     {                                             316     {
317         if (fVerboseLevel > 2)                    317         if (fVerboseLevel > 2)
318         {                                         318         {
319             G4cout << "RBE hit: Z=" << Z << ",    319             G4cout << "RBE hit: Z=" << Z << ", E=" << E << " => out of LEM table";
320             if (fVerboseLevel > 3)                320             if (fVerboseLevel > 3)
321             {                                     321             {
322                 G4cout << " (" << fMinEnergies    322                 G4cout << " (" << fMinEnergies[Z] << " to " << fMaxEnergies[Z] << " MeV)";
323             }                                     323             }
324             G4cout << G4endl;                     324             G4cout << G4endl;
325         }                                         325         }
326         return make_tuple<G4double, G4double>(    326         return make_tuple<G4double, G4double>( 0.0, 0.0 ); //out of table!
327     }                                             327     }
328                                                   328 
329     std::vector<G4double>& vecEnergy = (*fActi    329     std::vector<G4double>& vecEnergy = (*fActiveTableEnergy)[Z];
330     std::vector<G4double>& vecAlpha = (*fActiv    330     std::vector<G4double>& vecAlpha = (*fActiveTableAlpha)[Z];
331     std::vector<G4double>& vecBeta = (*fActive    331     std::vector<G4double>& vecBeta = (*fActiveTableBeta)[Z];
332                                                   332 
333     // Find the row in energy tables              333     // Find the row in energy tables
334     const auto eLarger = upper_bound(begin(vec    334     const auto eLarger = upper_bound(begin(vecEnergy), end(vecEnergy), E);
335     const G4int lower = (G4int) distance(begin << 335     const G4int lower = distance(begin(vecEnergy), eLarger) - 1;
336     const G4int upper = lower + 1;                336     const G4int upper = lower + 1;
337                                                   337 
338     // Interpolation                              338     // Interpolation
339     const G4double energyLower = vecEnergy[low    339     const G4double energyLower = vecEnergy[lower];
340     const G4double energyUpper = vecEnergy[upp    340     const G4double energyUpper = vecEnergy[upper];
341     const G4double energyFraction = (E - energ    341     const G4double energyFraction = (E - energyLower) / (energyUpper - energyLower);
342                                                   342 
343     //linear interpolation along E                343     //linear interpolation along E
344     const G4double alpha = ((1 - energyFractio    344     const G4double alpha = ((1 - energyFraction) * vecAlpha[lower] + energyFraction * vecAlpha[upper]);
345     const G4double beta = ((1 - energyFraction    345     const G4double beta = ((1 - energyFraction) * vecBeta[lower] + energyFraction * vecBeta[upper]);
346     if (fVerboseLevel > 2)                        346     if (fVerboseLevel > 2)
347     {                                             347     {
348         G4cout << "RBE hit: Z=" << Z << ", E="    348         G4cout << "RBE hit: Z=" << Z << ", E=" << E << " => alpha=" << alpha << ", beta=" << beta << G4endl;
349     }                                             349     }
350                                                   350 
351     return make_tuple(alpha, beta);               351     return make_tuple(alpha, beta);
352 }                                                 352 }
353                                                   353 
354 // Zaider & Rossi alpha & Beta mean               354 // Zaider & Rossi alpha & Beta mean
355 void HadrontherapyRBE::ComputeAlphaAndBeta()      355 void HadrontherapyRBE::ComputeAlphaAndBeta()
356 {                                                 356 {
357     if (fVerboseLevel > 0)                        357     if (fVerboseLevel > 0)
358     {                                             358     {
359         G4cout << "RBE: Computing alpha and be    359         G4cout << "RBE: Computing alpha and beta..." << G4endl;
360     }                                             360     }
361     //Re-inizialize the number of voxels       << 361     fAlpha = fAlphaNumerator / (fDenominator * gray);
362     fAlpha.resize(fAlphaNumerator.size()); //I << 362     
363     fBeta.resize(fBetaNumerator.size()); //Ini << 363     fBeta = pow(fBetaNumerator / fDenominator * gray, 2.0);
364     for (size_t ii=0; ii<fDenominator.size();i << 364     
365       {                                        << 365     //g4pow -> powN(fBetaNumerator / fDenominator * gray, 2)
366   if (fDenominator[ii] > 0)                    << 
367     {                                          << 
368       fAlpha[ii] = fAlphaNumerator[ii] / (fDen << 
369       fBeta[ii] = std::pow(fBetaNumerator[ii]  << 
370     }                                          << 
371   else                                         << 
372     {                                          << 
373       fAlpha[ii] = 0.;                         << 
374       fBeta[ii] = 0.;                          << 
375     }                                          << 
376       }                                        << 
377                                                << 
378 }                                                 366 }
379                                                   367 
380 void HadrontherapyRBE::ComputeRBE()               368 void HadrontherapyRBE::ComputeRBE()
381 {                                                 369 {
382     if (fVerboseLevel > 0)                        370     if (fVerboseLevel > 0)
383     {                                             371     {
384         G4cout << "RBE: Computing survival and    372         G4cout << "RBE: Computing survival and RBE..." << G4endl;
385     }                                             373     }
386     G4double smax = fAlphaX + 2 * fBetaX * fDo    374     G4double smax = fAlphaX + 2 * fBetaX * fDoseCut;
387                                                   375 
388     // Prepare matrices that were not initiali    376     // Prepare matrices that were not initialized yet
389     fLnS.resize(fNumberOfVoxels);                 377     fLnS.resize(fNumberOfVoxels);
390     fDoseX.resize(fNumberOfVoxels);               378     fDoseX.resize(fNumberOfVoxels);
391                                                   379 
392     for (G4int i = 0; i < fNumberOfVoxels; i++    380     for (G4int i = 0; i < fNumberOfVoxels; i++)
393     {                                             381     {
394         if (std::isnan(fAlpha[i]) || std::isna    382         if (std::isnan(fAlpha[i]) || std::isnan(fBeta[i]))
395         {                                         383         {
396             fLnS[i] = 0.0;                        384             fLnS[i] = 0.0;
397             fDoseX[i] = 0.0;                      385             fDoseX[i] = 0.0;
398         }                                         386         }
399         else if (fDose[i] <= fDoseCut)            387         else if (fDose[i] <= fDoseCut)
400         {                                         388         {
401             fLnS[i] = -(fAlpha[i] * fDose[i])     389             fLnS[i] = -(fAlpha[i] * fDose[i]) - (fBeta[i] * (pow(fDose[i], 2.0))) ;
402             fDoseX[i] = sqrt((-fLnS[i] / fBeta    390             fDoseX[i] = sqrt((-fLnS[i] / fBetaX) + pow((fAlphaX / (2 * fBetaX)), 2.0)) - (fAlphaX / (2 * fBetaX));
403         }                                         391         }
404         else                                      392         else
405         {                                         393         {
406             G4double ln_Scut = -(fAlpha[i] * f    394             G4double ln_Scut = -(fAlpha[i] * fDoseCut) - (fBeta[i] * (pow((fDoseCut), 2.0)));
407             fLnS[i] = ln_Scut - ((fDose[i] - f    395             fLnS[i] = ln_Scut - ((fDose[i] - fDoseCut) * smax);
408                                                   396 
409             // TODO: CHECK THIS!!!                397             // TODO: CHECK THIS!!!
410             fDoseX[i] = ( (-fLnS[i] + ln_Scut)    398             fDoseX[i] = ( (-fLnS[i] + ln_Scut) / smax ) + fDoseCut;
411         }                                         399         }
412     }                                             400     }
413     fRBE.resize(fDoseX.size());                << 401     fRBE = fDoseX / fDose;
414     for (size_t ii=0;ii<fDose.size();ii++)     << 
415       fRBE[ii] = (fDose[ii] > 0) ? fDoseX[ii]  << 
416     fSurvival = exp(fLnS);                        402     fSurvival = exp(fLnS);
417 }                                                 403 }
418                                                   404 
419 void HadrontherapyRBE::SetDenominator(const Ha    405 void HadrontherapyRBE::SetDenominator(const HadrontherapyRBE::array_type denom)
420 {                                                 406 {
421     if (fVerboseLevel > 1)                        407     if (fVerboseLevel > 1)
422     {                                             408     {
423         G4cout << "RBE: Setting denominator...    409         G4cout << "RBE: Setting denominator..."  << G4endl;
424     }                                             410     }
425     fDenominator = denom;                         411     fDenominator = denom;
426 }                                                 412 }
427                                                   413 
428 void HadrontherapyRBE::AddDenominator(const Ha    414 void HadrontherapyRBE::AddDenominator(const HadrontherapyRBE::array_type denom)
429 {                                                 415 {
430     if (fVerboseLevel > 1)                        416     if (fVerboseLevel > 1)
431     {                                             417     {
432         G4cout << "RBE: Adding denominator..."    418         G4cout << "RBE: Adding denominator...";
433     }                                             419     }
434     if (fDenominator.size())                      420     if (fDenominator.size())
435     {                                             421     {
436         fDenominator += denom;                    422         fDenominator += denom;
437     }                                             423     }
438     else                                          424     else
439     {                                             425     {
440         if (fVerboseLevel > 1)                    426         if (fVerboseLevel > 1)
441         {                                         427         {
442             G4cout << " (created empty array)"    428             G4cout << " (created empty array)";
443         }                                         429         }
444         fDenominator = denom;                     430         fDenominator = denom;
445     }                                             431     }
446     G4cout << G4endl;                             432     G4cout << G4endl;
447 }                                                 433 }
448                                                   434 
449 void HadrontherapyRBE::SetAlphaNumerator(const    435 void HadrontherapyRBE::SetAlphaNumerator(const HadrontherapyRBE::array_type alpha)
450 {                                                 436 {
451     if (fVerboseLevel > 1)                        437     if (fVerboseLevel > 1)
452     {                                             438     {
453         G4cout << "RBE: Setting alpha numerato    439         G4cout << "RBE: Setting alpha numerator..."  << G4endl;
454     }                                             440     }
455     fAlphaNumerator = alpha;                      441     fAlphaNumerator = alpha;
456 }                                                 442 }
457                                                   443 
458 void HadrontherapyRBE::SetBetaNumerator(const     444 void HadrontherapyRBE::SetBetaNumerator(const HadrontherapyRBE::array_type beta)
459 {                                                 445 {
460     if (fVerboseLevel > 1)                        446     if (fVerboseLevel > 1)
461     {                                             447     {
462         G4cout << "RBE: Setting beta numerator    448         G4cout << "RBE: Setting beta numerator..." << G4endl;
463     }                                             449     }
464     fBetaNumerator = beta;                        450     fBetaNumerator = beta;
465 }                                                 451 }
466                                                   452 
467 void HadrontherapyRBE::AddAlphaNumerator(const    453 void HadrontherapyRBE::AddAlphaNumerator(const HadrontherapyRBE::array_type alpha)
468 {                                                 454 {
469     if (fVerboseLevel > 1)                        455     if (fVerboseLevel > 1)
470     {                                             456     {
471         G4cout << "RBE: Adding alpha numerator    457         G4cout << "RBE: Adding alpha numerator...";
472     }                                             458     }
473     if (fAlphaNumerator.size())                   459     if (fAlphaNumerator.size())
474     {                                             460     {
475         fAlphaNumerator += alpha;                 461         fAlphaNumerator += alpha;
476     }                                             462     }
477     else                                          463     else
478     {                                             464     {
479         if (fVerboseLevel > 1)                    465         if (fVerboseLevel > 1)
480         {                                         466         {
481             G4cout << " (created empty array)"    467             G4cout << " (created empty array)";
482         }                                         468         }
483         fAlphaNumerator = alpha;                  469         fAlphaNumerator = alpha;
484     }                                             470     }
485     G4cout << G4endl;                             471     G4cout << G4endl;
486 }                                                 472 }
487                                                   473 
488 void HadrontherapyRBE::AddBetaNumerator(const     474 void HadrontherapyRBE::AddBetaNumerator(const HadrontherapyRBE::array_type beta)
489 {                                                 475 {
490     if (fVerboseLevel > 1)                        476     if (fVerboseLevel > 1)
491     {                                             477     {
492         G4cout << "RBE: Adding beta...";          478         G4cout << "RBE: Adding beta...";
493     }                                             479     }
494     if (fBetaNumerator.size())                    480     if (fBetaNumerator.size())
495     {                                             481     {
496         fBetaNumerator += beta;                   482         fBetaNumerator += beta;
497     }                                             483     }
498     else                                          484     else
499     {                                             485     {
500         if (fVerboseLevel > 1)                    486         if (fVerboseLevel > 1)
501         {                                         487         {
502             G4cout << " (created empty array)"    488             G4cout << " (created empty array)";
503         }                                         489         }
504         fBetaNumerator = beta;                    490         fBetaNumerator = beta;
505     }                                             491     }
506     G4cout << G4endl;                             492     G4cout << G4endl;
507 }                                                 493 }
508                                                   494 
509 void HadrontherapyRBE::SetEnergyDeposit(const     495 void HadrontherapyRBE::SetEnergyDeposit(const std::valarray<G4double> eDep)
510 {                                                 496 {
511     if (fVerboseLevel > 1)                        497     if (fVerboseLevel > 1)
512     {                                             498     {
513         G4cout << "RBE: Setting dose..." << G4    499         G4cout << "RBE: Setting dose..." << G4endl;
514     }                                             500     }
515     fDose = eDep * (fDoseScale / fMassOfVoxel)    501     fDose = eDep * (fDoseScale / fMassOfVoxel);
516 }                                                 502 }
517                                                   503 
518 void HadrontherapyRBE::AddEnergyDeposit(const     504 void HadrontherapyRBE::AddEnergyDeposit(const std::valarray<G4double> eDep)
519 {                                                 505 {
520     if (fVerboseLevel > 1)                        506     if (fVerboseLevel > 1)
521     {                                             507     {
522         G4cout << "RBE: Adding dose... (" << e    508         G4cout << "RBE: Adding dose... (" << eDep.size() << " points)" << G4endl;
523     }                                             509     }
524     if (fDose.size())                             510     if (fDose.size())
525     {                                             511     {
526         fDose += eDep * (fDoseScale / fMassOfV    512         fDose += eDep * (fDoseScale / fMassOfVoxel);
527     }                                             513     }
528     else                                          514     else
529     {                                             515     {
530         if (fVerboseLevel > 1)                    516         if (fVerboseLevel > 1)
531         {                                         517         {
532             G4cout << " (created empty array)"    518             G4cout << " (created empty array)";
533         }                                         519         }
534         fDose = eDep * (fDoseScale / fMassOfVo    520         fDose = eDep * (fDoseScale / fMassOfVoxel);
535     }                                             521     }
536 }                                                 522 }
537                                                   523 
538 void HadrontherapyRBE::StoreAlphaAndBeta()        524 void HadrontherapyRBE::StoreAlphaAndBeta()
539 {                                                 525 {
540     if (fVerboseLevel > 1)                        526     if (fVerboseLevel > 1)
541     {                                             527     {
542         G4cout << "RBE: Writing alpha and beta    528         G4cout << "RBE: Writing alpha and beta..." << G4endl;
543     }                                             529     }
544     ofstream ofs(fAlphaBetaPath);                 530     ofstream ofs(fAlphaBetaPath);
545                                                   531 
546     ComputeAlphaAndBeta();                        532     ComputeAlphaAndBeta();
547                                                   533 
548     if (ofs.is_open())                            534     if (ofs.is_open())
549     {                                             535     {
550         ofs << "alpha" << std::setw(width) <<     536         ofs << "alpha" << std::setw(width) << "beta " << std::setw(width) << "depth(slice)" << G4endl;
551         for (G4int i = 0; i < fNumberOfVoxelsA    537         for (G4int i = 0; i < fNumberOfVoxelsAlongX * fNumberOfVoxelsAlongY * fNumberOfVoxelsAlongZ; i++)
552             ofs << fAlpha[i]*gray << std::setw    538             ofs << fAlpha[i]*gray << std::setw(15L) << fBeta[i]*pow(gray, 2.0) << std::setw(15L) << i << G4endl;
553     }                                             539     }
554     if (fVerboseLevel > 0)                        540     if (fVerboseLevel > 0)
555     {                                             541     {
556         G4cout << "RBE: Alpha and beta written    542         G4cout << "RBE: Alpha and beta written to " << fAlphaBetaPath << G4endl;
557     }                                             543     }
558 }                                                 544 }
559                                                   545 
560 void HadrontherapyRBE::StoreRBE()                 546 void HadrontherapyRBE::StoreRBE()
561 {                                                 547 {
562     ofstream ofs(fRBEPath);                       548     ofstream ofs(fRBEPath);
563                                                   549 
564     // TODO: only if not yet calculated. Or in    550     // TODO: only if not yet calculated. Or in RunAction???
565     ComputeRBE();                                 551     ComputeRBE();
566                                                   552 
567     if (ofs.is_open())                            553     if (ofs.is_open())
568     {                                             554     {
569         ofs << "Dose(Gy)" << std::setw(width)     555         ofs << "Dose(Gy)" << std::setw(width) << "ln(S) " << std::setw(width) << "Survival"  << std::setw(width) << "DoseB(Gy)" << std::setw(width) << "RBE" <<  std::setw(width) << "depth(slice)" << G4endl;
570                                                   556 
571         for (G4int i = 0; i < fNumberOfVoxelsA    557         for (G4int i = 0; i < fNumberOfVoxelsAlongX * fNumberOfVoxelsAlongY * fNumberOfVoxelsAlongZ; i++)
572                                                   558 
573             ofs << (fDose[i] / gray) << std::s    559             ofs << (fDose[i] / gray) << std::setw(width) << fLnS[i] << std::setw(width) << fSurvival[i]
574                 << std::setw(width) << fDoseX[    560                 << std::setw(width) << fDoseX[i] / gray << std::setw(width) << fRBE[i] << std::setw(width)  << i << G4endl;
575     }                                             561     }
576     if (fVerboseLevel > 0)                        562     if (fVerboseLevel > 0)
577     {                                             563     {
578         G4cout << "RBE: RBE written to " << fR    564         G4cout << "RBE: RBE written to " << fRBEPath << G4endl;
579     }                                             565     }
580 }                                                 566 }
581                                                   567 
582 void HadrontherapyRBE::Reset()                    568 void HadrontherapyRBE::Reset()
583 {                                                 569 {
584     if (fVerboseLevel > 1)                        570     if (fVerboseLevel > 1)
585     {                                             571     {
586         G4cout << "RBE: Reset(): ";               572         G4cout << "RBE: Reset(): ";
587     }                                             573     }
588     fAlphaNumerator = 0.0;                        574     fAlphaNumerator = 0.0;
589     fBetaNumerator = 0.0;                         575     fBetaNumerator = 0.0;
590     fDenominator = 0.0;                           576     fDenominator = 0.0;
591     fDose = 0.0;                                  577     fDose = 0.0;
592     if (fVerboseLevel > 1)                        578     if (fVerboseLevel > 1)
593     {                                             579     {
594         G4cout << fAlphaNumerator.size() << "     580         G4cout << fAlphaNumerator.size() << " points." << G4endl;
595     }                                             581     }
596 }                                                 582 }
597                                                   583 
598 void HadrontherapyRBE::CreateMessenger()          584 void HadrontherapyRBE::CreateMessenger()
599 {                                                 585 {
600     fMessenger = new G4GenericMessenger(this,     586     fMessenger = new G4GenericMessenger(this, "/rbe/");
601     fMessenger->SetGuidance("RBE calculation")    587     fMessenger->SetGuidance("RBE calculation");
602                                                   588 
603     fMessenger->DeclareMethod("calculation", &    589     fMessenger->DeclareMethod("calculation", &HadrontherapyRBE::SetCalculationEnabled)
604             .SetGuidance("Whether to enable RB    590             .SetGuidance("Whether to enable RBE calculation")
605             .SetStates(G4State_PreInit, G4Stat    591             .SetStates(G4State_PreInit, G4State_Idle)
606             .SetToBeBroadcasted(false);           592             .SetToBeBroadcasted(false);
607                                                   593 
608     fMessenger->DeclareMethod("verbose", &Hadr    594     fMessenger->DeclareMethod("verbose", &HadrontherapyRBE::SetVerboseLevel)
609             .SetGuidance("Set verbosity level     595             .SetGuidance("Set verbosity level of RBE")
610             .SetGuidance("0 = quiet")             596             .SetGuidance("0 = quiet")
611             .SetGuidance("1 = important messag    597             .SetGuidance("1 = important messages (~10 per run)")
612             .SetGuidance("2 = debug")             598             .SetGuidance("2 = debug")
613             .SetToBeBroadcasted(false);           599             .SetToBeBroadcasted(false);
614                                                   600 
615     fMessenger->DeclareMethod("loadLemTable",     601     fMessenger->DeclareMethod("loadLemTable", &HadrontherapyRBE::LoadLEMTable)
616             .SetGuidance("Load a LEM table use    602             .SetGuidance("Load a LEM table used in calculating alpha&beta")
617             .SetStates(G4State_PreInit, G4Stat    603             .SetStates(G4State_PreInit, G4State_Idle)
618             .SetToBeBroadcasted(false);           604             .SetToBeBroadcasted(false);
619                                                   605 
620     fMessenger->DeclareMethod("cellLine", &Had    606     fMessenger->DeclareMethod("cellLine", &HadrontherapyRBE::SetCellLine)
621             .SetGuidance("Set the cell line fo    607             .SetGuidance("Set the cell line for alpha&beta calculation")
622             .SetStates(G4State_PreInit, G4Stat    608             .SetStates(G4State_PreInit, G4State_Idle)
623             .SetToBeBroadcasted(false);           609             .SetToBeBroadcasted(false);
624                                                   610 
625     fMessenger->DeclareMethod("doseScale", &Ha    611     fMessenger->DeclareMethod("doseScale", &HadrontherapyRBE::SetDoseScale)
626             .SetGuidance("Set the scaling fact    612             .SetGuidance("Set the scaling factor to calculate RBE with the real physical dose")
627             .SetGuidance("If you don't set thi    613             .SetGuidance("If you don't set this, the RBE will be incorrect")
628             .SetStates(G4State_PreInit, G4Stat    614             .SetStates(G4State_PreInit, G4State_Idle)
629             .SetToBeBroadcasted(false);           615             .SetToBeBroadcasted(false);
630                                                   616 
631     fMessenger->DeclareMethod("accumulate", &H    617     fMessenger->DeclareMethod("accumulate", &HadrontherapyRBE::SetAccumulationEnabled)
632             .SetGuidance("If false, reset the     618             .SetGuidance("If false, reset the values at the beginning of each run.")
633             .SetGuidance("If true, all runs ar    619             .SetGuidance("If true, all runs are summed together")
634             .SetStates(G4State_PreInit, G4Stat    620             .SetStates(G4State_PreInit, G4State_Idle)
635             .SetToBeBroadcasted(false);           621             .SetToBeBroadcasted(false);
636                                                   622 
637     fMessenger->DeclareMethod("reset", &Hadron    623     fMessenger->DeclareMethod("reset", &HadrontherapyRBE::Reset)
638             .SetGuidance("Reset accumulated da    624             .SetGuidance("Reset accumulated data (relevant only if accumulate mode is on)")
639             .SetStates(G4State_PreInit, G4Stat    625             .SetStates(G4State_PreInit, G4State_Idle)
640             .SetToBeBroadcasted(false);           626             .SetToBeBroadcasted(false);
641 }                                                 627 }
642                                                   628 
643 /*                                                629 /*
644 G4bool HadrontherapyRBE::LinearLookup(G4double    630 G4bool HadrontherapyRBE::LinearLookup(G4double E, G4double LET, G4int Z)
645 {                                                 631 {
646     G4int j;                                      632     G4int j;
647     G4int indexE;                                 633     G4int indexE;
648     if ( E < vecEnergy[0] || E >= vecEnergy[Ge    634     if ( E < vecEnergy[0] || E >= vecEnergy[GetRowVecEnergy() - 1]) return false; //out of table!
649                                                   635 
650     // Search E                                   636     // Search E
651     for (j = 0; j < GetRowVecEnergy(); j++)       637     for (j = 0; j < GetRowVecEnergy(); j++)
652     {                                             638     {
653         if (j + 1 == GetRowVecEnergy()) break;    639         if (j + 1 == GetRowVecEnergy()) break;
654         if (E >= vecEnergy[j] && E < vecEnergy    640         if (E >= vecEnergy[j] && E < vecEnergy[j + 1]) break;
655     }                                             641     }
656                                                   642 
657     indexE = j;                                   643     indexE = j;
658                                                   644 
659     G4int k = (indexE * column);                  645     G4int k = (indexE * column);
660                                                   646 
661     G4int l = ((indexE + 1) * column);            647     G4int l = ((indexE + 1) * column);
662                                                   648 
663     if (Z <= 8) //linear interpolation along E    649     if (Z <= 8) //linear interpolation along E for calculate alpha and beta
664     {                                             650     {
665         interpolation_onE(k, l, indexE, E, Z);    651         interpolation_onE(k, l, indexE, E, Z);
666     }                                             652     }
667     else                                          653     else
668     {                                             654     {
669                                                   655 
670         return interpolation_onLET1_onLET2_onE    656         return interpolation_onLET1_onLET2_onE(k, l, indexE, E, LET);
671                                                   657 
672     }                                             658     }
673     return true;                                  659     return true;
674 }                                                 660 }
675 */                                                661 */
676                                                   662 
677 /*                                                663 /*
678 void HadrontherapyRBE::interpolation_onE(G4int    664 void HadrontherapyRBE::interpolation_onE(G4int k, G4int l, G4int indexE, G4double E, G4int Z)
679 {                                                 665 {
680     // k=(indexE*column) identifies the positi    666     // k=(indexE*column) identifies the position of E1 known the value of E (identifies the group of 8 elements in the array at position E1)
681     // Z-1 identifies the vector ion position  << 667     // Z-1 identifies the vector ion position relative to the group of 8 values ​​found
682                                                   668 
683     k = k + (Z - 1);                              669     k = k + (Z - 1);
684     l = l + (Z - 1);                              670     l = l + (Z - 1);
685                                                   671 
686     //linear interpolation along E                672     //linear interpolation along E
687     alpha = (((vecEnergy[indexE + 1] - E) / (v    673     alpha = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecAlpha[k]) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecAlpha[l];
688                                                   674 
689     beta = (((vecEnergy[indexE + 1] - E) / (ve    675     beta = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecBeta[k]) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * vecBeta[l];
690                                                   676 
691 }                                                 677 }
692                                                   678 
693 G4bool HadrontherapyRBE::interpolation_onLET1_    679 G4bool HadrontherapyRBE::interpolation_onLET1_onLET2_onE(G4int k, G4int l, G4int indexE, G4double E, G4double LET)
694 {                                                 680 {
695     G4double LET1_2, LET3_4, LET1_2_beta, LET3    681     G4double LET1_2, LET3_4, LET1_2_beta, LET3_4_beta;
696     G4int indexLET1, indexLET2, indexLET3, ind    682     G4int indexLET1, indexLET2, indexLET3, indexLET4;
697     size_t i;                                     683     size_t i;
698     if ( (LET >= vecLET[k + column - 1] && LET    684     if ( (LET >= vecLET[k + column - 1] && LET >= vecLET[l + column - 1]) || (LET < vecLET[k] && LET < vecLET[l]) ) return false; //out of table!
699                                                   685 
700     //Find the value of E1 is detected the val << 686     //Find the value of E1 is detected the value of LET among the 8 possible values ​​corresponding to E1
701     for (i = 0; i < column - 1; i++)              687     for (i = 0; i < column - 1; i++)
702     {                                             688     {
703                                                   689 
704         if ( (i + 1 == column - 1) || (LET < v    690         if ( (i + 1 == column - 1) || (LET < vecLET[k]) ) break;
705                                                   691 
706         else if (LET >= vecLET[k] && LET < vec    692         else if (LET >= vecLET[k] && LET < vecLET[k + 1]) break;
707         k++;                                      693         k++;
708                                                   694 
709     }                                             695     }
710     indexLET1 = k;                                696     indexLET1 = k;
711     indexLET2 = k + 1;                            697     indexLET2 = k + 1;
712                                                   698 
713     //Find the value of E2 is detected the val << 699     //Find the value of E2 is detected the value of LET among the 8 possible values ​​corresponding to E2
714     for (i = 0; i < column - 1; i++)              700     for (i = 0; i < column - 1; i++)
715     {                                             701     {
716                                                   702 
717         if (i + 1 == column - 1) break;           703         if (i + 1 == column - 1) break;
718         if (LET >= vecLET[l] && LET < vecLET[l    704         if (LET >= vecLET[l] && LET < vecLET[l + 1]) break; // time to interpolate
719         l++;                                      705         l++;
720                                                   706 
721     }                                             707     }
722                                                   708 
723     indexLET3 = l;                                709     indexLET3 = l;
724     indexLET4 = l + 1;                            710     indexLET4 = l + 1;
725                                                   711 
726     //Interpolation between LET1 and LET2 on E    712     //Interpolation between LET1 and LET2 on E2 position
727     LET1_2 = (((vecLET[indexLET2] - LET) / (ve    713     LET1_2 = (((vecLET[indexLET2] - LET) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecAlpha[indexLET1]) + ((LET - vecLET[indexLET1]) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecAlpha[indexLET2];
728                                                   714 
729     LET1_2_beta = (((vecLET[indexLET2] - LET)     715     LET1_2_beta = (((vecLET[indexLET2] - LET) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecBeta[indexLET1]) + ((LET - vecLET[indexLET1]) / (vecLET[indexLET2] - vecLET[indexLET1])) * vecBeta[indexLET2];
730                                                   716 
731     //Interpolation between LET3 and LET4 on E    717     //Interpolation between LET3 and LET4 on E2 position
732     LET3_4 = (((vecLET[indexLET4] - LET) / (ve    718     LET3_4 = (((vecLET[indexLET4] - LET) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecAlpha[indexLET3]) + ((LET - vecLET[indexLET3]) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecAlpha[indexLET4];
733     LET3_4_beta = (((vecLET[indexLET4] - LET)     719     LET3_4_beta = (((vecLET[indexLET4] - LET) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecBeta[indexLET3]) + ((LET - vecLET[indexLET3]) / (vecLET[indexLET4] - vecLET[indexLET3])) * vecBeta[indexLET4];
734                                                   720 
735     //Interpolation along E between LET1_2 and    721     //Interpolation along E between LET1_2 and LET3_4
736     alpha = (((vecEnergy[indexE + 1] - E) / (v    722     alpha = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET1_2) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET3_4;
737     beta = (((vecEnergy[indexE + 1] - E) / (ve    723     beta = (((vecEnergy[indexE + 1] - E) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET1_2_beta) + ((E - vecEnergy[indexE]) / (vecEnergy[indexE + 1] - vecEnergy[indexE])) * LET3_4_beta;
738                                                   724 
739                                                   725 
740     return true;                                  726     return true;
741 }                                                 727 }
742 **/                                               728 **/
743                                                   729 
744 /* void HadrontherapyRBE::SetThresholdValue(G4    730 /* void HadrontherapyRBE::SetThresholdValue(G4double dosecut)
745 {                                                 731 {
746     fDoseCut = dosecut;                           732     fDoseCut = dosecut;
747 }                                                 733 }
748                                                   734 
749 void HadrontherapyRBE::SetAlphaX(G4double alph    735 void HadrontherapyRBE::SetAlphaX(G4double alphaX)
750 {                                                 736 {
751     fAlphaX = alphaX;                             737     fAlphaX = alphaX;
752 }                                                 738 }
753                                                   739 
754 void HadrontherapyRBE::SetBetaX(G4double betaX    740 void HadrontherapyRBE::SetBetaX(G4double betaX)
755 {                                                 741 {
756     fBetaX = betaX;                               742     fBetaX = betaX;
757 }*/                                               743 }*/
758                                                   744 
759 void HadrontherapyRBE::SetCalculationEnabled(G    745 void HadrontherapyRBE::SetCalculationEnabled(G4bool enabled)
760 {                                                 746 {
761     fCalculationEnabled = enabled;                747     fCalculationEnabled = enabled;
762 }                                                 748 }
763                                                   749 
764 void HadrontherapyRBE::SetAccumulationEnabled(    750 void HadrontherapyRBE::SetAccumulationEnabled(G4bool accumulate)
765 {                                                 751 {
766     fAccumulate = accumulate;                     752     fAccumulate = accumulate;
767     // The accumulation should start now, not     753     // The accumulation should start now, not taking into account old data
768     Reset();                                      754     Reset();
769 }                                                 755 }
770                                                   756 
771 /*                                                757 /*
772 void HadrontherapyRBE::SetLEMTablePath(G4Strin    758 void HadrontherapyRBE::SetLEMTablePath(G4String path)
773 {                                                 759 {
774     // fLEMTablePath = path;                      760     // fLEMTablePath = path;
775     LoadLEMTable(path);                           761     LoadLEMTable(path);
776 }                                                 762 }
777 */                                                763 */
778                                                   764 
779 void HadrontherapyRBE::SetDoseScale(G4double s    765 void HadrontherapyRBE::SetDoseScale(G4double scale)
780 {                                                 766 {
781     fDoseScale = scale;                           767     fDoseScale = scale;
782 }                                                 768 }
783                                                   769 
784 // Nearest neighbor interpolation                 770 // Nearest neighbor interpolation
785 /*                                                771 /*
786 G4bool HadrontherapyRBE::NearLookup(G4double E    772 G4bool HadrontherapyRBE::NearLookup(G4double E, G4double DE)
787 {                                                 773 {
788                                                   774 
789     size_t j = 0, step = 77;                      775     size_t j = 0, step = 77;
790                                                   776 
791     // Check bounds                               777     // Check bounds
792     if (E < vecE[0] || E > vecE.back() || DE <    778     if (E < vecE[0] || E > vecE.back() || DE < vecDE[0] || DE > vecDE[step - 1]) return false; //out of table!
793                                                   779 
794     // search for Energy... simple linear sear    780     // search for Energy... simple linear search. This take approx 1 us per single search on my sempron 2800+ laptop
795     for (; j < vecE.size(); j += step)            781     for (; j < vecE.size(); j += step)
796     {                                             782     {
797         if (E <= vecE[j]) break;                  783         if (E <= vecE[j]) break;
798     }                                             784     }
799     if (j == vecE.size()) j -= step;              785     if (j == vecE.size()) j -= step;
800     if (j == vecE.size() && E > vecE[j]) retur    786     if (j == vecE.size() && E > vecE[j]) return false; // out of table!
801                                                   787 
802                                                   788 
803     // find nearest (better interpolate)          789     // find nearest (better interpolate)
804     if ( j > 0 && ((vecE[j] - E) > (E - vecE[j    790     if ( j > 0 && ((vecE[j] - E) > (E - vecE[j - 1])) ) {j = j - step;}
805     bestE = vecE[j];                              791     bestE = vecE[j];
806                                                   792 
807                                                   793 
808     // search for stopping power... simple lin    794     // search for stopping power... simple linear search
809     for (; vecE[j] == bestE && j < vecE.size()    795     for (; vecE[j] == bestE && j < vecE.size(); j++)
810     {                                             796     {
811         if (DE <= vecDE[j]) break;                797         if (DE <= vecDE[j]) break;
812     }                                             798     }
813     if (j == vecE.size() &&  DE > vecDE[j])  r    799     if (j == vecE.size() &&  DE > vecDE[j])  return false;// out of table!
814                                                   800 
815     if (j == 0 && (E < vecE[j] || DE < vecDE[j    801     if (j == 0 && (E < vecE[j] || DE < vecDE[j]) ) return false;// out of table!
816                                                   802 
817     if ( (vecDE[j] - DE) > (DE - vecDE[j - 1])    803     if ( (vecDE[j] - DE) > (DE - vecDE[j - 1]) ) {j = j - 1;}
818     bestDE = vecDE[j];                            804     bestDE = vecDE[j];
819                                                   805 
820     this -> alpha = vecAlpha[j];                  806     this -> alpha = vecAlpha[j];
821     this -> beta  = vecBeta[j];                   807     this -> beta  = vecBeta[j];
822                                                   808 
823     return true;                                  809     return true;
824 }                                                 810 }
825 */                                                811 */
826                                                   812