76 : fNumberOfVoxelsAlongX(voxelX),
77 fNumberOfVoxelsAlongY(voxelY),
78 fNumberOfVoxelsAlongZ(voxelZ),
79 fNumberOfVoxels(voxelX * voxelY * voxelY),
80 fMassOfVoxel(massOfVoxel)
122 vector<G4String> result;
127 while(pos != G4String::npos)
129 pos = line.find(delimiter, current);
130 G4String token = line.substr(current, pos - current);
133 result.push_back(token);
134 current = pos + delimiter.size();
147 ss <<
"Cannot open LEM table input file: " << path;
153 if (!getline(in, line))
156 ss <<
"Cannot read header from the LEM table file: " << path;
159 vector<G4String> header =
split(line,
",");
162 std::vector<G4String> columns = {
"alpha_x",
"beta_x",
"D_t",
"specific_energy",
"alpha",
"beta",
"cell",
"particle"};
163 std::map<G4String, int> columnIndices;
164 for (
auto columnName : columns)
166 auto pos = find(header.begin(), header.end(), columnName);
167 if (
pos == header.end())
170 ss <<
"Column " << columnName <<
" not present in the LEM table file.";
175 columnIndices[columnName] = distance(header.begin(),
pos);
180 while (getline(in, line))
182 vector<G4String> lineParts =
split(line,
",");
183 G4String cellLine = lineParts[columnIndices[
"cell"]];
184 G4int element =
elements.at(lineParts[columnIndices[
"particle"]]);
187 stod(lineParts[columnIndices[
"specific_energy"]]) *
MeV
190 stod(lineParts[columnIndices[
"alpha"]])
196 stod(lineParts[columnIndices[
"beta"]])
208 for (
auto ePair : aPair.second)
210 vector<G4double>& tableEnergy = fTablesEnergy[aPair.first][ePair.first];
211 vector<G4double>& tableAlpha =
fTablesAlpha[aPair.first][ePair.first];
212 vector<G4double>& tableBeta =
fTablesBeta[aPair.first][ePair.first];
214 vector<size_t>
idx(tableEnergy.size());
215 iota(
idx.begin(),
idx.end(), 0);
216 sort(
idx.begin(),
idx.end(),
217 [&tableEnergy](
size_t i1,
size_t i2) {
return tableEnergy[i1] < tableEnergy[i2];});
219 vector<vector<G4double>*> tables = {
220 &tableEnergy, &tableAlpha, &tableBeta
222 for (vector<G4double>* table : tables)
224 vector<G4double>
copy = *table;
225 for (
size_t i = 0; i < copy.size(); ++i)
227 (*table)[i] = copy[
idx[i]];
238 G4cout <<
"RBE: read LEM data for the following cell lines and elements [number of points]: " <<
G4endl;
239 for (
auto aPair : fTablesEnergy)
241 G4cout <<
"- " << aPair.first <<
": ";
242 for (
auto ePair : aPair.second)
244 G4cout << ePair.first <<
"[" << ePair.second.size() <<
"] ";
255 G4Exception(
"HadrontherapyRBE::SetCellLine",
"NoCellLine",
FatalException,
"Cannot select cell line, probably LEM table not loaded yet?");
260 str <<
"Cell line " << name <<
" not found in the LEM table.";
281 if (energyPair.first >
fMaxZ)
fMaxZ = energyPair.first;
284 fMaxEnergies[energyPair.first] = energyPair.second[energyPair.second.size() - 1];
292 G4cout <<
"RBE: cell line " << name <<
" selected." <<
G4endl;
300 G4Exception(
"HadrontherapyRBE::GetHitAlphaAndBeta",
"NoCellLine",
FatalException,
"No cell line selected. Please, do it using the /rbe/cellLine command.");
309 str <<
"Alpha & beta calculation supported only for ";
310 str <<
fMinZ <<
" <= Z <= " <<
fMaxZ <<
", but " << Z <<
" requested.";
313 return make_tuple<G4double, G4double>( 0.0, 0.0 );
319 G4cout <<
"RBE hit: Z=" << Z <<
", E=" << E <<
" => out of LEM table";
326 return make_tuple<G4double, G4double>( 0.0, 0.0 );
329 std::vector<G4double>& vecEnergy = (*fActiveTableEnergy)[
Z];
330 std::vector<G4double>& vecAlpha = (*fActiveTableAlpha)[
Z];
331 std::vector<G4double>& vecBeta = (*fActiveTableBeta)[
Z];
334 const auto eLarger = upper_bound(begin(vecEnergy), end(vecEnergy), E);
335 const G4int lower = distance(begin(vecEnergy), eLarger) - 1;
336 const G4int upper = lower + 1;
339 const G4double energyLower = vecEnergy[lower];
340 const G4double energyUpper = vecEnergy[upper];
341 const G4double energyFraction = (E - energyLower) / (energyUpper - energyLower);
344 const G4double alpha = ((1 - energyFraction) * vecAlpha[lower] + energyFraction * vecAlpha[upper]);
345 const G4double beta = ((1 - energyFraction) * vecBeta[lower] + energyFraction * vecBeta[upper]);
348 G4cout <<
"RBE hit: Z=" << Z <<
", E=" << E <<
" => alpha=" << alpha <<
", beta=" << beta <<
G4endl;
351 return make_tuple(alpha, beta);
372 G4cout <<
"RBE: Computing survival and RBE..." <<
G4endl;
387 else if (
fDose[i] <= fDoseCut)
418 G4cout <<
"RBE: Adding denominator...";
428 G4cout <<
" (created empty array)";
457 G4cout <<
"RBE: Adding alpha numerator...";
467 G4cout <<
" (created empty array)";
478 G4cout <<
"RBE: Adding beta...";
488 G4cout <<
" (created empty array)";
508 G4cout <<
"RBE: Adding dose... (" << eDep.size() <<
" points)" <<
G4endl;
518 G4cout <<
" (created empty array)";
536 ofs <<
"alpha" << std::setw(
width) <<
"beta " << std::setw(
width) <<
"depth(slice)" <<
G4endl;
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;
572 G4cout <<
"RBE: Reset(): ";
597 .
SetGuidance(
"1 = important messages (~10 per run)")
602 .
SetGuidance(
"Load a LEM table used in calculating alpha&beta")
607 .
SetGuidance(
"Set the cell line for alpha&beta calculation")
612 .
SetGuidance(
"Set the scaling factor to calculate RBE with the real physical dose")
613 .
SetGuidance(
"If you don't set this, the RBE will be incorrect")
618 .
SetGuidance(
"If false, reset the values at the beginning of each run.")
619 .
SetGuidance(
"If true, all runs are summed together")
624 .
SetGuidance(
"Reset accumulated data (relevant only if accumulate mode is on)")