15 EvD = std::make_shared<TGraph>();
20 Double_t _IonEnergy = 0;
21 Double_t _dEdx_e = 0, _dEdx_n = 0;
23 Double_t _Stragg_lon = 0, _Stragg_lat = 0;
26 std::ifstream Read(Eloss_file.c_str());
29 if (!Read.is_open()) {
30 std::cout <<
"*** EnergyLoss Error: File " << Eloss_file <<
" was not found."
32 GoodELossFile =
false;
35 Read >> aux >> aux >> aux >> aux >> aux >> aux;
39 Read >> _IonEnergy >> _dEdx_e >> _dEdx_n >> _Range >> _Stragg_lon >> _Stragg_lat;
42 }
while (!Read.eof());
47 Read.open(Eloss_file.c_str());
48 Read >> aux >> aux >> aux >> aux;
50 for (
int p = 0; p < points; p++) {
51 Read >> _IonEnergy >> _dEdx_e >> _dEdx_n >> _Range;
53 IonEnergy.push_back(_IonEnergy);
54 dEdx_e.push_back(_dEdx_e);
55 dEdx_n.push_back(_dEdx_n);
56 Range.push_back(_Range);
59 Energy_in_range =
true;
62 EvD = std::make_shared<TGraph>();
76 for (
int p = 0; p < points - 1; p++) {
78 if (energy >= IonEnergy[p] && energy < IonEnergy[p + 1]) {
91 Energy_in_range =
false;
98 Double_t E1 = IonEnergy[i - 1];
99 Double_t E2 = IonEnergy[i];
101 Double_t dEdx_e1 = dEdx_e[i - 1];
102 Double_t dEdx_e2 = dEdx_e[i];
104 Double_t dEdx_n1 = dEdx_n[i - 1];
105 Double_t dEdx_n2 = dEdx_n[i];
108 Double_t dEdx_e1e = dEdx_e1 + (energy - E1) * (dEdx_e2 - dEdx_e1) / (E2 - E1);
111 Double_t dEdx_n1e = dEdx_n1 + (energy - E1) * (dEdx_n2 - dEdx_n1) / (E2 - E1);
114 return ((dEdx_e1e + dEdx_n1e) * 10 * distance);
124 Float_t a11 = 0.0, a12 = 0.0, a21 = 0.0, a22 = 0.0, a23 = 0.0, a32 = 0.0, a33 = 0.0;
125 Float_t b11 = 0.0, b22 = 0.0, b33 = 0.0;
126 Float_t a1 = 0.0, a2 = 0.0, b1 = 0.0, b2 = 0.0;
127 Float_t K0 = 0.0, K1 = 0.0, K2 = 0.0;
128 Float_t N1 = 0.0, N2 = 0.0, N3 = 0.0;
129 Float_t T1 = 0.0, T2 = 0.0, q1 = 0.0, q2 = 0.0;
144 for (
int p = 0; p < points - 1; p++) {
146 if (energy >= IonEnergy[p] && energy < IonEnergy[p + 1]) {
158 std::cout <<
"*** EnergyLoss Error: energy not within range: " << energy <<
"\n";
160 Energy_in_range =
false;
165 Float_t x0 = IonEnergy[i - 1];
166 Float_t x1 = IonEnergy[i];
167 Float_t x2 = IonEnergy[i + 1];
170 Float_t y0 = dEdx_e[i - 1] + dEdx_n[i - 1];
171 Float_t y1 = dEdx_e[i] + dEdx_n[i];
172 Float_t y2 = dEdx_e[i + 1] + dEdx_n[i + 1];
177 a22 = 2 * ((1 / (x1 - x0)) + (1 / (x2 - x1)));
182 b11 = 3 * ((y1 - y0) / ((x1 - x0) * (x1 - x0)));
183 b22 = 3 * (((y1 - y0) / ((x1 - x0) * (x1 - x0))) + ((y2 - y1) / ((x2 - x1) * (x2 - x1))));
184 b33 = 3 * ((y2 - y1) / ((x2 - x1) * (x2 - x1)));
187 N1 = (a21 * a33 * a12 - a11 * (a22 * a33 - a23 * a32)) / (a33 * a12);
188 N2 = (b22 * a33 - a23 * b33) / a33;
189 N3 = b11 * (a22 * a33 - a23 * a32) / (a33 * a12);
194 K1 = (b11 - a11 * K0) / a12;
198 a1 = K0 * (x1 - x0) - (y1 - y0);
199 b1 = -K1 * (x1 - x0) + (y1 - y0);
204 T1 = (energy - x0) / (x1 - x0);
208 q1 = (1 - T1) * y0 + T1 * y1 + T1 * (1 - T1) * (a1 * (1 - T1) + b1 * T1);
213 return (q1 * 10 * distance);
220 Double_t Energy = FinalEnergy;
221 int Steps = (int)floor(PathLength / StepSize);
227 Energy_in_range =
true;
229 for (
int s = 0; s < Steps; s++) {
231 Energy = Energy + GetEnergyLoss(Energy, PathLength / Steps);
233 if (!Energy_in_range) {
237 Energy = Energy + GetEnergyLoss(Energy, PathLength - Steps * StepSize);
239 if (!Energy_in_range)
250 Double_t Energy = InitialEnergy;
251 int Steps = (int)floor(PathLength / StepSize);
256 Energy_in_range =
true;
258 for (
int s = 0; s < Steps; s++) {
260 Energy = Energy - GetEnergyLoss(Energy, PathLength / Steps);
262 if (!Energy_in_range) {
268 Energy = Energy - GetEnergyLoss(Energy, PathLength - Steps * StepSize);
270 if (!Energy_in_range) {
284 Double_t E = 0, Elast = 0;
292 E = E - GetEnergyLoss(E, StepSize);
295 return ((dist - StepSize) - (StepSize * (Elast - FinalE) / (E - Elast)));
304 Double_t L = 0, DeltaX = 0;
305 Double_t Kn = InitialEnergy;
306 Double_t Kn1 = InitialEnergy;
310 std::cout <<
"*** EnergyLoss Error: Path length cannot be calculated for IonMass = 0."
317 while (Kn > FinalEnergy && Kn1 > FinalEnergy && n < (
int)pow(10.0, 6)) {
320 L += sqrt((Kn + Kn1) / 2) * sqrt(2 / IonMass) * DeltaT *
c;
324 DeltaX = sqrt((Kn + Kn1) / IonMass) * DeltaT *
c;
328 Kn -= GetEnergyLoss((Kn + Kn1) / 2, DeltaX);
333 if (n >= (
int)pow(10.0, 6)) {
334 std::cout <<
"*** EnergyLoss Warning: Full path length wasn't reached after 10^6 iterations."
350 if (energy1 >= 0.01) {
352 for (Int_t p = last_point1 - 1; p < points1 - 1; p++) {
353 if (last_point1 >= 0)
354 if (energy1 >= IonEnergy[p] && energy1 < IonEnergy[p + 1]) {
362 for (Int_t p = 0; p < last_point1 - 1; p++) {
363 if (energy1 >= IonEnergy[p] && energy1 < IonEnergy[p + 1]) {
372 std::cout <<
"*** EnergyLoss Error: energy not within range: " << energy1 <<
"\n";
373 Energy_in_range =
false;
389 Double_t Kn = InitialEnergy;
390 int Steps = (int)(PathLength / StepSize);
393 std::cout <<
"Error: Time of flight cannot be calculated because mass is zero."
399 for (
int n = 0; n < Steps; n++) {
401 TOF += sqrt(IonMass / (2 * Kn)) * StepSize /
c;
402 Kn -= GetEnergyLoss(Kn, StepSize);
420 int noE = (int)ceil(MaximumEnergy / DeltaE);
421 int noD = (int)ceil(MaximumDistance / DeltaD);
423 fMaximumEnergy = MaximumEnergy;
424 fMaximumDistance = MaximumDistance;
434 DtoEtab[0] = MaximumEnergy;
435 std::cout <<
" Number of distance entries " << noD <<
"\n";
437 for (i = 1; i < noD; i++) {
441 DtoEtab[i] = GetFinalEnergy(DtoEtab[i - 1], DeltaD, 0.05 * DeltaD);
452 std::cout <<
" Number of Energy entries " << noE <<
"\n";
455 for (j = 1; j < noE; j++) {
458 EtoDtab[j] = EtoDtab[j - 1] +
459 GetDistance((MaximumEnergy - (j - 1) * DeltaE), (MaximumEnergy - (j)*DeltaE), (0.05 * DeltaD));
488 int noE = (int)ceil(fMaximumEnergy / fDeltaE);
489 int noD = (int)ceil(fMaximumDistance / fDeltaD);
491 std::cout <<
"Maximum Energy = " << fMaximumEnergy <<
" " << fDeltaE << noE <<
"\n";
492 for (i = 0; i < noE; i++) {
493 std::cout <<
"E,D= " << fMaximumEnergy - fDeltaE * i <<
"," << EtoDtab[i] <<
"\n";
495 std::cout <<
"Maximum Distance = " << fMaximumDistance <<
" " << fDeltaD << noD <<
"\n";
496 for (i = 0; i < noD; i++) {
497 std::cout <<
"D,E= " << fDeltaE * i <<
"," << DtoEtab[i] <<
"\n";
509 if (InitialEnergy < 0 || InitialEnergy > fMaximumEnergy) {
514 index = (int)floor((fMaximumEnergy - InitialEnergy) / fDeltaE);
517 D2 = EtoDtab[index + 1];
519 E1 = fMaximumEnergy - index * fDeltaE;
520 E2 = fMaximumEnergy - (index + 1) * fDeltaE;
522 D = (InitialEnergy - E1) / (E2 - E1) * (D2 - D1) + D1;
526 if (((D + distance <= 0)) || ((D + distance) > fMaximumDistance)) {
529 std::cout <<
"i m here"
536 index = (int)floor((D + distance) / fDeltaD);
539 E2 = DtoEtab[index + 1];
541 D1 = index * fDeltaD;
542 D2 = (index + 1) * fDeltaD;
544 E = ((D + distance) - D1) / (D2 - D1) * (E2 - E1) + E1;