5 #include <FairLogger.h>
13 void AtELossTable::LoadTable(
const std::vector<double> &energy,
const std::vector<double> &dEdX)
15 if (energy.size() > 0)
16 LOG(info) <<
"Loading dE/dX from " << energy.front() <<
" MeV to " << energy.back() <<
" MeV ";
18 LOG(error) <<
"Passed table was empty!";
20 std::vector<double> dXdE;
21 for (
auto &elem : dEdX)
22 dXdE.push_back(1 / elem);
29 LoadTable(energy, dEdX);
34 double dedx = 1 /
fdXdE(energy);
40 if (energyIni == energyFin)
50 if (energyIni < 1e-6 ||
GetRange(energyIni) < distance)
55 double guessEnergy = energyIni -
GetdEdx(energyIni) * distance;
56 for (
int i = 0; i < maxIt; ++i) {
58 double range =
GetRange(energyIni, guessEnergy);
59 if (fabs(range - distance) <
fDistErr) {
60 LOG(debug) <<
"Energy converged in " << i + 1 <<
" iterations.";
63 LOG(debug) <<
"guessE: " << guessEnergy <<
" d: " << distance <<
" R: " << range
64 <<
" dEdX: " <<
GetdEdx(guessEnergy) <<
" dEnergy: " <<
GetdEdx(guessEnergy) * (distance - range);
66 guessEnergy +=
GetdEdx(guessEnergy) * (range - distance);
69 LOG(error) <<
"Energy calculation (" << energyIni <<
" MeV through " << distance <<
" mm) failed to converge in "
70 << maxIt <<
" iterations!";
81 double maxRange =
GetRange(energyIni);
83 if (distance > maxRange)
89 double highGuess = energyIni;
90 double guessEnergy = energyIni / 2.0;
91 double range =
GetRange(energyIni, guessEnergy);
92 double distErr = 1.0e-4;
95 while (fabs(range - distance) > distErr) {
98 if (range > distance) {
99 lowGuess = guessEnergy;
100 guessEnergy = (lowGuess + highGuess) / 2.0;
103 highGuess = guessEnergy;
104 guessEnergy = (lowGuess + highGuess) / 2.0;
106 range =
GetRange(energyIni, guessEnergy);
109 LOG(info) <<
"Energy converged in " << numIt <<
" iterations.";
115 std::ifstream file(fileName);
117 LOG(fatal) <<
"Failed to open SRIM file " << fileName;
119 bool atConversion =
false;
120 double conversion = 0;
121 std::vector<double> energy;
122 std::vector<double> dEdX;
124 while (!file.eof()) {
127 std::getline(file, line);
129 LOG(debug) <<
"Processing line " << line;
132 if (tokens[0] ==
"Target" && tokens[1] ==
"Density") {
133 LOG(info) <<
"Setting target density to: " << tokens[3] <<
" g/cm^3";
139 atConversion |= (tokens[0] ==
"Multiply");
140 LOG(debug) <<
"At converion: " << atConversion;
144 if (atConversion && tokens.at(1) ==
"MeV" && tokens.at(3) ==
"mm") {
146 LOG(info) <<
"Using conversion factor of " << conversion;
151 double en =
std::stod(tokens.at(0)) * GetUnitConversion(tokens.at(1));
155 energy.push_back(en);
156 dEdX.push_back(dedx);
158 LOG(debug) << en <<
" " << dedx;
164 for (
auto &dedx : dEdX)
167 LoadTable(energy, dEdX);
172 std::ifstream file(fileName);
174 LOG(fatal) <<
"Failed to open SRIM file " << fileName;
176 std::vector<double> energy;
177 std::vector<double> dEdX;
180 while (!file.eof()) {
183 std::getline(file, line);
185 LOG(debug) <<
"Processing line " << line;
189 double en =
std::stod(tokens.at(0 + column * 2)) * mass;
190 double dedx =
std::stod(tokens.at(1 + column * 2));
193 dedx *= (100 * density);
197 LOG(debug) <<
"En: " << en <<
" dEdX " << dedx;
199 energy.push_back(en);
200 dEdX.push_back(dedx);
205 LoadTable(energy, dEdX);
208 double AtELossTable::GetUnitConversion(
const std::string &unit)