GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TKinematics.cxx
Go to the documentation of this file.
1// g++ -c -fPIC TKinematics.cc -I./ `root-config --cflags`
2
3#include "TKinematics.h"
4#include "Globals.h"
5
6TKinematics::TKinematics(double eBeam, const char* beam, const char* targ, const char* ejec, const char* reco, const char* name)
7 : fEBeam(eBeam)
8{
9 auto* projectile = new TNucleus(beam);
10 auto* target = new TNucleus(targ);
11 TNucleus* ejectile = nullptr;
12 TNucleus* recoil = nullptr;
13
14 name = Form("%s(%s,%s)%s", targ, beam, ejec, reco);
15
16 if((ejec == nullptr) || (reco == nullptr)) {
17 // without ejectile or recoil, elastic scattering is assumed
18 ejectile = projectile;
19 recoil = target;
20 } else {
21 ejectile = new TNucleus(ejec);
22 recoil = new TNucleus(reco);
23 }
24
25 fParticle[0] = projectile;
26 fParticle[1] = target;
27 fParticle[2] = ejectile;
28 fParticle[3] = recoil;
29 for(int i = 0; i < 4; i++) {
30 fM[i] = fParticle[i]->GetMass();
31 }
32
33 fQValue = (fM[0] + fM[1]) - (fM[2] + fM[3]);
34 Initial();
35 FinalCm();
36 SetName(name);
37}
38
39TKinematics::TKinematics(TNucleus* projectile, TNucleus* target, double eBeam, const char* name)
40 : fEBeam(eBeam)
41{
42 // By not providing the ejectile (only prociding projectile, target, and beam energy) elestic scattering is assumed
43 fParticle[0] = projectile;
44 fParticle[1] = target;
45 fParticle[2] = nullptr;
46 fParticle[3] = nullptr;
47 fM[0] = fParticle[0]->GetMass();
48 fM[1] = fParticle[1]->GetMass();
49 Initial();
50 FinalCm();
51 SetName(name);
52}
53
54TKinematics::TKinematics(TNucleus* projectile, TNucleus* target, TNucleus* recoil, TNucleus* ejectile, double eBeam, const char* name)
55 : fEBeam(eBeam)
56{
57 // Kinematics using the provided projectile, target, recoil, and ejectile, as well as beam energy
58 fParticle[0] = projectile;
59 fParticle[1] = target;
60 fParticle[2] = recoil;
61 fParticle[3] = ejectile;
62 for(int i = 0; i < 4; i++) {
63 fM[i] = fParticle[i]->GetMass();
64 }
65
66 fQValue = (fM[0] + fM[1]) - (fM[2] + fM[3]);
67 Initial();
68 FinalCm();
69 SetName(name);
70}
71
72TKinematics::TKinematics(TNucleus* projectile, TNucleus* target, TNucleus* recoil, TNucleus* ejectile, double eBeam, double ex3, const char* name)
73 : fEBeam(eBeam)
74{
75 // Kinematics using the provided projectile, target, recoil, ejectile, beam energy, and excited state of the recoil
76 fParticle[0] = projectile;
77 fParticle[1] = target;
78 fParticle[2] = recoil; // This is oppiste what is right below it.
79 fParticle[3] = ejectile; // we need to define a convention and stick with it pcb.
80 for(int i = 0; i < 4; i++) {
81 fM[i] = fParticle[i]->GetMass();
82 }
83
84 fQValue = (fM[0] + fM[1]) - (fM[2] + fM[3]) - ex3;
85 Initial();
86 FinalCm();
87 SetName(name);
88}
89
90TKinematics::TKinematics(const char* beam, const char* targ, const char* ejec, const char* reco, double eBeam, double ex3, const char* name)
91 : fEBeam(eBeam)
92{
93 auto* projectile = new TNucleus(beam);
94 auto* target = new TNucleus(targ);
95 TNucleus* ejectile = nullptr;
96 TNucleus* recoil = nullptr;
97
98 name = Form("%s(%s,%s)%s", targ, beam, ejec, reco);
99
100 if((ejec == nullptr) || (reco == nullptr)) {
101 // without ejectile or recoil, elastic scattering is assumed
102 ejectile = projectile;
103 recoil = target;
104 } else {
105 ejectile = new TNucleus(ejec);
106 recoil = new TNucleus(reco);
107 }
108
109 fParticle[0] = projectile;
110 fParticle[1] = target;
111 fParticle[2] = ejectile;
112 fParticle[3] = recoil;
113 for(int i = 0; i < 4; i++) {
114 fM[i] = fParticle[i]->GetMass();
115 }
116
117 fQValue = (fM[0] + fM[1]) - (fM[2] + fM[3]) - ex3;
118 Initial();
119 FinalCm();
120 SetName(name);
121}
122
123TSpline3* TKinematics::Evslab(double thmin, double thmax, double size, int part)
124{
125 if(part < 2 || part > 3) {
126 std::cout << ALERTTEXT << "WARNING: the function Evslab should use nuclei after the reaction (part 2 or part 3)" << RESET_COLOR << std::endl;
127 return nullptr;
128 }
129
130 std::vector<double> energy;
131 std::vector<double> angle;
132
133 double deg2rad = PI / 180.0;
134 double rad2deg = 180.0 / PI;
135
136 int steps = (static_cast<int>(thmax + 1) - static_cast<int>(thmin)) /
137 static_cast<int>(size); // when is size ever needed to be a double?? pcb.
138 // i am under the impression that size should always be 1.0;
139 //
140 double lastangle = 0.0;
141 for(int i = 0; i < steps; i++) {
142 Final((thmin + i * size) * deg2rad, 2); // part); //2);
143 double tmpangle = GetThetalab(part) * (1 / deg2rad);
144 double tmpeng = GetTlab(part) * 1000;
145 if(tmpangle < lastangle) {
146 std::cout << ALERTTEXT << "WARNING: the abscissa(theta) is no longer increasing; Drawing spline will fail." << RESET_COLOR << std::endl;
147 std::cout << ALERTTEXT << " try Evslab_graph to see what this looks like. " << RESET_COLOR << std::endl;
148 return nullptr;
149 }
150 lastangle = tmpangle;
151 if(tmpangle < 1 || tmpangle > (GetMaxAngle(fVcm[part]) * rad2deg) - 1) {
152 continue;
153 }
154 if(tmpeng > 1e15 || tmpeng < 0.0) {
155 continue;
156 }
157
158 angle.push_back(GetThetalab(part) * (1 / deg2rad));
159 energy.push_back(GetTlab(part) * 1000);
160 }
161
162 TGraph graph(static_cast<Int_t>(angle.size()), angle.data(), energy.data());
163 auto* spline = new TSpline3("ETh_lab", &graph);
164 return spline;
165}
166
167TGraph* TKinematics::Evslab_graph(double thmin, double thmax, double size, int part)
168{
169 if(part < 2 || part > 3) {
170 std::cout << ALERTTEXT << "WARNING: the function Evslab+graph should use nuclei after the reaction (part 2 or part 3)" << RESET_COLOR << std::endl;
171 return nullptr;
172 }
173
174 std::vector<double> energy;
175 std::vector<double> angle;
176
177 double rad2deg = 180.0 / PI;
178 double deg2rad = PI / 180.0;
179
180 int steps = (static_cast<int>(thmax + 1) - static_cast<int>(thmin)) /
181 static_cast<int>(size); // when is size ever needed to be a double?? pcb.
182 // i am under the impression that size should always be 1.0;
183 //
184 for(int i = 0; i < steps; i++) {
185 Final((thmin + i * size) * deg2rad, 2); // part); //2);
186 double tmpangle = GetThetalab(part) * (1 / deg2rad);
187 double tmpeng = GetTlab(part) * 1000;
188 if(tmpangle < 1 || tmpangle > (GetMaxAngle(fVcm[part]) * rad2deg) - 1) {
189 continue;
190 }
191 if(tmpeng > 1e15 || tmpeng < 0.0) {
192 continue;
193 }
194
195 angle.push_back(GetThetalab(part) * (1 / deg2rad));
196 energy.push_back(GetTlab(part) * 1000);
197 }
198
199 return new TGraph(static_cast<Int_t>(angle.size()), angle.data(), energy.data());
200}
201
202TSpline3* TKinematics::Evscm(double thmin, double thmax, double size, int part)
203{
204 auto* energy = new double[static_cast<int>((thmax - thmin) / size) + 1];
205 auto* angle = new double[static_cast<int>((thmax - thmin) / size) + 1];
206 int number = 0;
207 double deg2rad = PI / 180.;
208 for(int i = 0; i < ((thmax - thmin) / size); i++) {
209 Final((thmin + i * size) * deg2rad, 2);
210 angle[i] = GetThetacm(part) * 180. / PI;
211 energy[i] = GetTlab(part);
212 number++;
213 }
214 auto* graph = new TGraph(number, angle, energy);
215 auto* spline = new TSpline3("ETh_cm", graph);
216 delete graph;
217 delete[] angle;
218 delete[] energy;
219 return spline;
220}
221
222double TKinematics::GetExcEnergy(TLorentzVector recoil)
223{
224 // Gets the excitation energy of the recoil in the CM frame using a 4-vector
225 TLorentzVector ejectile;
226 recoil.Boost(0, 0, -GetBetacm()); // boost to cm system
227
228 ejectile.SetVect(-recoil.Vect()); // pr = -pe
229 ejectile.SetE(GetCmEnergy() - recoil.E()); // Ee=Ecm-Er
230
231 ejectile.Boost(0, 0, GetBetacm()); // boost to lab system
232
233 double eex = ejectile.M() - fParticle[3]->GetMass();
234
235 return eex;
236}
237
238double TKinematics::GetExcEnergy(TVector3 position, double KinE)
239{
240 // Gets the excitation energy of the recoil in the CM frame using a vector & energy
241 TLorentzVector recoil;
242
243 double TotalEnergy = fM[2] + KinE;
244
245 position.SetMag(sqrt(pow(TotalEnergy, 2) - pow(TotalEnergy - KinE, 2)));
246 recoil.SetXYZT(position.X(), position.Y(), position.Z(), TotalEnergy);
247
248 return GetExcEnergy(recoil);
249}
250
251double TKinematics::GetExcEnergy(double theta, double KinE)
252{
253
254 double val1 = (fM[0] + fM[1]) * (fM[0] + fM[1]) + fM[2] * fM[2] + 2 * fM[1] * fT[0];
255 double val2 = 2 * fGamma_cm * sqrt((fM[0] + fM[1]) * (fM[0] + fM[1]) + 2 * fM[1] * fT[0]);
256 double val3 = fM[2] + KinE - fBeta_cm * sqrt(KinE * KinE + 2 * fM[2] * KinE) * TMath::Cos(theta);
257
258 return sqrt(val1 - val2 * val3) - fM[3];
259}
260
261double TKinematics::GetBeamEnergy(double LabAngle, double LabEnergy) const
262{
263 // Returns the beam energy given the lab angle and energy of the ejectile
264 double ProjectileMass = fM[0];
265 double TargetMass = fM[1];
266
267 double ts = pow(TargetMass, 2);
268 double ps = pow(ProjectileMass, 2);
269 double cs = pow(cos(LabAngle), 2);
270 double es = pow(LabEnergy, 2);
271 double te = TargetMass * LabEnergy;
272
273 return (-8 * ProjectileMass - 4 * TargetMass + LabEnergy / cs - 2 * LabEnergy * tan(LabAngle) +
274 sqrt(16 * ts * cs +
275 LabEnergy * (LabEnergy / cs * pow(cos(LabAngle) - sin(LabAngle), 4) +
276 8 * TargetMass * (3 + sin(2 * LabAngle)))) /
277 cos(LabAngle) +
278 sqrt((24 * ts * LabEnergy * cs + 32 * ps * TargetMass * pow(cos(LabAngle), 4) +
279 2 * TargetMass * es * pow(cos(LabAngle) - sin(LabAngle), 4) +
280 16 * ts * LabEnergy * pow(cos(LabAngle), 3) * sin(LabAngle) -
281 8 * ps * LabEnergy * cs * (sin(2 * LabAngle) - 1) +
282 2 * ps * cos(3 * LabAngle) * sqrt(2 * (4 * ts + 12 * te + es) + (8 * ts - 2 * es) * cos(2 * LabAngle) + LabEnergy * (LabEnergy / cs + 8 * TargetMass * sin(2 * LabAngle) - 4 * LabEnergy * tan(LabAngle))) +
283 2 * cos(LabAngle) * (3 * ps + te - te * sin(2 * LabAngle)) *
284 sqrt(2 * (4 * ts + 12 * te + es) + (8 * ts - 2 * es) * cos(2 * LabAngle) +
285 LabEnergy *
286 (LabEnergy / cs + 8 * TargetMass * sin(2 * LabAngle) - 4 * LabEnergy * tan(LabAngle)))) /
287 (pow(cos(LabAngle), 4) * TargetMass))) /
288 8.;
289}
290
292{
293 // An initializing function that sets the energies and momenta of the beam and target in the lab and CM frame,
294 // as well as a few basic calculations.
295 fT[0] = fEBeam; // KE of beam in lab
296 fT[1] = 0; // KE of target in lab
297 fE[0] = E_tm(fT[0], fM[0]); // total E of beam in lab
298 fE[1] = E_tm(fT[1], fM[1]); // total E of target in lab
299 fP[0] = sqrt(fT[0] * fT[0] + 2 * fT[0] * fM[0]); // momentum of beam in lab
300 fP[1] = 0; // momentum of target in lab
301 fV[0] = V_pe(fP[0], fE[0]); // velocity of beam in lab
302 fV[1] = V_pe(fP[1], fE[1]); // velocity of target in lab
303
304 fEcm[0] = GetCmEnergy(fEBeam) / 2 + (fM[0] * fM[0] - fM[1] * fM[1]) / (2 * GetCmEnergy(fEBeam));
305 fEcm[1] = GetCmEnergy(fEBeam) / 2 - (fM[0] * fM[0] - fM[1] * fM[1]) / (2 * GetCmEnergy(fEBeam));
306 fTcm[0] = fEcm[0] - fM[0];
307 fTcm[1] = fEcm[1] - fM[1];
308 fPcm[0] = Pcm_em(fEcm[0], fM[0]);
309 fPcm[1] = Pcm_em(fEcm[1], fM[1]);
310 fVcm[0] = V_pe(fPcm[0], fEcm[0]);
311 fVcm[1] = V_pe(fPcm[1], fEcm[1]);
312
313 fBeta_cm = (fP[0] - fP[1]) / (fE[0] + fE[1]);
314 fBetacm[0] = betacm_tm(fTcm[0], fM[0]);
315 fBetacm[1] = -betacm_tm(fTcm[1], fM[1]);
316 fGamma_cm = 1 / sqrt(1 - fBeta_cm * fBeta_cm);
317 fTCm_i = GetCmEnergy(fEBeam) - fM[0] - fM[1];
319}
321{
322 // Calculates the recoil and ejectile energies and momenta in the CM frame
323
324 // angle of proton in cm system
325 if(fParticle[2] == nullptr && fParticle[3] == nullptr) {
326 fM[2] = fParticle[1]->GetMass();
327 fM[3] = fParticle[0]->GetMass();
328 }
329 fTcm[2] = fTCm_f / 2 * (fTCm_f + 2 * fM[3]) / GetCmEnergy(fEBeam);
330 fTcm[3] = fTCm_f / 2 * (fTCm_f + 2 * fM[2]) / GetCmEnergy(fEBeam);
331 fEcm[2] = E_tm(fTcm[2], fM[2]);
332 fEcm[3] = E_tm(fTcm[3], fM[3]);
333 fPcm[2] = Pcm_em(fEcm[2], fM[2]);
334 fPcm[3] = Pcm_em(fEcm[3], fM[3]);
335 fVcm[2] = V_pe(fPcm[2], fEcm[2]);
336 fVcm[3] = V_pe(fPcm[3], fEcm[3]);
337 fBetacm[2] = -betacm_tm(fTcm[2], fM[2]);
338 fBetacm[3] = betacm_tm(fTcm[3], fM[3]);
339}
340void TKinematics::Final(double angle, int part)
341{
342 // Calculates the recoil and ejectile energies and momenta in the lab frame
343
344 // angle of proton in lab system
345 if(angle > GetMaxAngle(fVcm[part])) {
346 SetAngles(0, part);
347 } else {
348 SetAngles(angle, part);
349 }
350 fE[2] = E_final(2);
351 fE[3] = E_final(3);
352 fT[2] = T_final(2);
353 fT[3] = T_final(3);
354 // fP[2]=fGamma_cm*(fPcm[2]+fBeta_cm*fEcm[2]);
355 // fP[3]=fGamma_cm*(fPcm[3]+fBeta_cm*fEcm[3]);
356 fP[2] = P_tm(fT[2], fM[2]);
357 // fP[2]=fGamma_cm*fPcm[2]*(cos(fThetacm[2])+fBeta_cm/fVcm[2]);
358 fP[3] = P_tm(fT[3], fM[3]);
359 // fP[3]=fGamma_cm*fPcm[3]*(cos(fThetacm[3])+fBeta_cm/fVcm[3]);
360 fV[2] = V_pe(fP[2], fE[2]);
361 fV[3] = V_pe(fP[3], fE[3]);
362}
363
364double TKinematics::ELab(double angle_lab, int part)
365{
366 // Calculates the energy of a particle "part" in the lab given the ejectile lab angle
367 Final(angle_lab, part);
368 return GetTlab(part);
369}
370
371void TKinematics::SetAngles(double angle, int part, bool upper)
372{
373 // Set the angle for a particle "part"
374 int given = 0;
375 int other = 0;
376 if(part == 2) {
377 given = 2;
378 other = 3;
379 } else if(part == 3) {
380 given = 3;
381 other = 2;
382 } else {
383 std::cout << " error in TKinematics::SetAngles(" << angle << ", " << part << ") " << std::endl;
384 std::cout << " part must be 2 or 3 " << std::endl;
385 exit(4);
386 }
387 fTheta[given] = angle;
388 fThetacm[given] = Angle_lab2cm(fVcm[given], fTheta[given]);
389 if(given == 3 && (fParticle[0]->GetMass() > fParticle[1]->GetMass())) {
390 fThetacm[given] = Angle_lab2cminverse(fVcm[given], fTheta[given], upper);
391 }
392 fThetacm[other] = PI - fThetacm[given];
393 if(fTheta[given] == 0) {
394 fTheta[other] = PI / given;
395 } else {
396 fTheta[other] = Angle_cm2lab(fVcm[other], fThetacm[other]);
397 }
398}
399
400double TKinematics::GetCmEnergy(double eBeam) const
401{
402 // Returns the total energy of the CM system, given the beam energy
403 return sqrt(fM[0] * fM[0] + fM[1] * fM[1] + 2. * fM[1] * (fM[0] + eBeam));
404}
406{
407 // Returns the total energy of the CM system
408 return GetCmEnergy(fEBeam);
409}
411{
412 // Returns the total kinetic energy of the system, assuming normal kinematics
413 return (GetCmEnergy(fEBeam) * GetCmEnergy(fEBeam) - fM[0] * fM[0] - fM[1] * fM[1]) / (2 * fM[0]) - fM[1];
414}
415
416double TKinematics::GetMaxAngle(double vcm) const
417{
418 // Returns the maximum angle of the ejectile in the CM frame
419 double x = fBeta_cm / vcm;
420 if(x * x < 1) {
421 return PI;
422 }
423 return atan2(sqrt(1 / (x * x - 1)), fGamma_cm);
424}
425double TKinematics::GetMaxAngle(int part) const
426{
427 // Returns the maximum angle of a given particle "part"
428 return GetMaxAngle(fVcm[part]);
429}
430bool TKinematics::CheckMaxAngle(double angle, int part) const
431{
432 // A check to ensure the angle for a given particle is allowed (i.e. less than the max angle)
433 return angle <= GetMaxAngle(fVcm[part]);
434}
435double TKinematics::Angle_lab2cm(double vcm, double angle_lab) const
436{
437 // Converts the lab angle to the CM angle given the velocity in the CM frame
438 double tan_lab = tan(angle_lab);
439 double gtan = tan_lab * tan_lab * fGamma_cm * fGamma_cm;
440 double x = fBeta_cm / vcm;
441
442 if(tan_lab >= 0) {
443 return acos((-x * gtan + sqrt(1 + gtan * (1 - x * x))) / (1 + gtan));
444 }
445 return acos((-x * gtan - sqrt(1 + gtan * (1 - x * x))) / (1 + gtan));
446}
447double TKinematics::Angle_lab2cminverse(double vcm, double angle_lab, bool upper) const
448{
449 // Converts the lab angle to the CM angle given the velocity in the CM frame under inverse kinematics
450 double tan_lab = tan(angle_lab);
451 double gtan = tan_lab * tan_lab * fGamma_cm * fGamma_cm;
452 double x = fBeta_cm / vcm;
453
454 if(upper) {
455 return acos((-x * gtan + sqrt(1 + gtan * (1 - x * x))) / (1 + gtan));
456 }
457 return acos((-x * gtan - sqrt(1 + gtan * (1 - x * x))) / (1 + gtan));
458}
459
460double TKinematics::Steffen_cm2labinverse(double theta_cm, int part) const
461{
462 double v_in_cm = fVcm[part];
463 double beta_of_cm = fBeta_cm;
464 double gamma_of_cm = fGamma_cm;
465
466 double theta_lab = PI - TMath::ATan2(sin(theta_cm), gamma_of_cm * (cos(theta_cm) - beta_of_cm / v_in_cm));
467
468 return theta_lab;
469}
470
472{ // assumes part = 2;
473
474 if(fCm2LabSpline == nullptr) {
475 fCm2LabSpline = Steffen_labvscminverse(0.01, 179.9, 1.0, 2);
476 }
477
478 return fCm2LabSpline->Eval(theta_lab);
479}
480
481void TKinematics::AngleErr_lab2cm(double angle, double& err) const
482{
483 // Calculates the uncertainty associated with converting the angle from the lab to CM frame
484 err = fabs(Angle_lab2cm(fVcm[2], angle + err) - Angle_lab2cm(fVcm[2], angle - err)) / 2.;
485}
486
487double TKinematics::Angle_cm2lab(double vcm, double angle_cm) const
488{
489 // Converts the CM angle to the lab angle given the velocity in the CM frame
490 double x = fBeta_cm / vcm;
491 return atan2(sin(angle_cm), fGamma_cm * (cos(angle_cm) + x));
492}
493
494TSpline3* TKinematics::labvscm(double thmin, double thmax, double size, int part) const
495{
496 auto* cm = new double[static_cast<int>((thmax - thmin) / size) + 1];
497 auto* lab = new double[static_cast<int>((thmax - thmin) / size) + 1];
498 int nr = 0;
499 for(int i = 0; i < ((thmax - thmin) / size); i++) {
500 cm[nr] = i;
501 lab[nr] = Angle_cm2lab(fVcm[part], cm[nr] * PI / 180.) * 180. / PI;
502 if(lab[nr] > 0.01 && lab[nr] < 179.99) {
503 nr++;
504 }
505 }
506 auto* graph = new TGraph(nr, cm, lab);
507 auto* spline = new TSpline3("Th_cmvslab", graph);
508 delete graph;
509 delete[] lab;
510 delete[] cm;
511 return spline;
512}
513
514TSpline3* TKinematics::cmvslab(double thmin, double thmax, double size, int part) const
515{
516 auto* cm = new double[static_cast<int>((thmax - thmin) / size) + 1];
517 auto* lab = new double[static_cast<int>((thmax - thmin) / size) + 1];
518 int nr = 0;
519 for(int i = 0; i < ((thmax - thmin) / size); i++) {
520 cm[nr] = i;
521 lab[nr] = Angle_cm2lab(fVcm[part], cm[nr] * PI / 180.) * 180. / PI;
522 if(lab[nr] > 0.01 && lab[nr] < 179.99) {
523 nr++;
524 }
525 }
526 auto* graph = new TGraph(nr, lab, cm);
527 auto* spline = new TSpline3("Th_cmvslab", graph);
528 delete graph;
529 delete[] lab;
530 delete[] cm;
531 return spline;
532}
533
534TSpline3* TKinematics::Steffen_labvscminverse(double thmin, double thmax, double size, int part) const
535{
536 auto* cm = new double[static_cast<int>((thmax - thmin) / size) + 1];
537 auto* lab = new double[static_cast<int>((thmax - thmin) / size) + 1];
538 int nr = 0;
539 for(auto i = static_cast<int>((thmax - thmin) / size); i > 0; i--) {
540 cm[nr] = i;
541 lab[nr] = Steffen_cm2labinverse(cm[nr] * PI / 180., part) * 180. / PI;
542 if(lab[nr] > 0.01 && lab[nr] < 179.99) {
543 nr++;
544 }
545 }
546 auto* graph = new TGraph(nr, lab, cm);
547 auto* spline = new TSpline3("Th_cmvslabinverse", graph);
548 delete graph;
549 delete[] lab;
550 delete[] cm;
551 return spline;
552}
553
554double TKinematics::Sigma_cm2lab(double angle_cm, double sigma_cm) const
555{
556 double gam2 = fM[0] * fM[2] / fM[1] / fM[3] * fTCm_i / fTCm_f;
557 gam2 = sqrt(gam2);
558 double wurzel = 1. + gam2 * gam2 + 2. * gam2 * cos(PI - angle_cm);
559 wurzel = sqrt(wurzel);
560 return sigma_cm * (1 / fGamma_cm * wurzel * wurzel * wurzel / (1 + gam2 * cos(PI - angle_cm)));
561}
562
563double TKinematics::Sigma_lab2cm(double angle_cm, double sigma_lab) const
564{
565 double gam2 = fM[0] * fM[2] / fM[1] / fM[3] * fTCm_i / fTCm_f;
566 gam2 = sqrt(gam2);
567 double wurzel = 1. + gam2 * gam2 + 2. * gam2 * cos(PI - angle_cm);
568 wurzel = sqrt(wurzel);
569 return sigma_lab / (1 / fGamma_cm * wurzel * wurzel * wurzel / (1 + gam2 * cos(PI - angle_cm)));
570}
571
572void TKinematics::SigmaErr_lab2cm(double angle, double err, double& sigma, double& errsigma) const
573{
574 double g = fM[0] * fM[2] / fM[1] / fM[3] * fTCm_i / fTCm_f;
575 g = sqrt(g);
576 double w = 1. + g * g + 2. * g * cos(PI - angle);
577 w = sqrt(w);
578 errsigma = fGamma_cm / pow(w, 1.5) *
579 sqrt(pow(sigma * g * sin(PI - angle) * (-2 + g * g - g * cos(PI - angle)) / w * err, 2) +
580 pow((1 + g * cos(PI - angle)) * errsigma, 2));
581}
582
583void TKinematics::Transform2cm(double& angle, double& sigma) const
584{
585 angle = PI - Angle_lab2cm(fVcm[2], angle);
586 sigma = Sigma_lab2cm(angle, sigma);
587}
588
589void TKinematics::Transform2cm(double& angle, double& errangle, double& sigma, double& errsigma) const
590{
591 AngleErr_lab2cm(angle, errangle);
592 Transform2cm(angle, sigma);
593 SigmaErr_lab2cm(angle, errangle, sigma, errsigma);
594}
595
596double TKinematics::Rutherford(double angle_cm) const
597{
598 // Returns the Rutherford scattering impact parameter, b, given the angle of the ejectile in the CM frame
599 double a = 0.5 * 1.43997649 * fParticle[0]->GetZ() * fParticle[1]->GetZ() / fTCm_i;
600 double b = sin(angle_cm / 2.) * sin(angle_cm / 2.);
601 b = b * b;
602 return a * a / b * 0.0025; // 1b=0.01fm
603}
604
605TSpline3* TKinematics::Ruthvscm(double thmin, double thmax, double size) const
606{
607 auto* cross = new double[static_cast<int>((thmax - thmin) / size) + 1];
608 auto* angle = new double[static_cast<int>((thmax - thmin) / size) + 1];
609 int number = 0;
610 for(int i = 0; i < ((thmax - thmin) / size); i++) {
611 angle[i] = thmin + i * size;
612 if(angle[i] > 179.99 || angle[i] < 0.01) {
613 break;
614 }
615 cross[i] = Rutherford(angle[i] * PI / 180.);
616 number++;
617 }
618 auto* graph = new TGraph(number, angle, cross);
619 auto* spline = new TSpline3("sigmaTh_cm", graph);
620 delete graph;
621 delete[] angle;
622 delete[] cross;
623 return spline;
624}
625
626TSpline3* TKinematics::Ruthvslab(double thmin, double thmax, double size, int part) const
627{
628 auto* cross = new double[static_cast<int>((thmax - thmin) / size) + 1];
629 auto* angle = new double[static_cast<int>((thmax - thmin) / size) + 1];
630 int number = 0;
631 for(int i = 0; i < ((thmax - thmin) / size); i++) {
632 if(part == 3 || part == 2) {
633 angle[i] = thmin + i * size; // angle[i] is in cm system
634 } else {
635 std::cout << "error " << std::endl;
636 exit(1);
637 }
638 if(angle[i] > 179.99 || angle[i] < 0.01) {
639 break;
640 }
641 cross[i] = Rutherford(angle[i] * PI / 180.);
642 number++;
643
644 cross[i] = Sigma_cm2lab(angle[i] * PI / 180., Rutherford(angle[i] * PI / 180.));
645 if(part == 2) {
646 angle[i] = 180 - angle[i];
647 }
648 angle[i] = Angle_cm2lab(fVcm[part], angle[i] * PI / 180.) * 180. / PI;
649 }
650 auto* graph = new TGraph(number, angle, cross);
651 auto* spline = new TSpline3("sigmaTh_lab", graph);
652 delete graph;
653 delete[] angle;
654 delete[] cross;
655 return spline;
656}
657
658double TKinematics::Pcm_em(double e, double m) const
659{
660 return sqrt(e * e - m * m);
661}
662double TKinematics::P_tm(double t, double m) const
663{
664 return sqrt(t * t + 2. * t * m);
665}
666double TKinematics::E_tm(double t, double m) const
667{
668 return t + m;
669}
670double TKinematics::T_em(double e, double m) const
671{
672 return e - m;
673}
674double TKinematics::betacm_tm(double t, double m) const
675{
676 return sqrt(t * t + 2 * t * m) / (t + m);
677}
678double TKinematics::V_pe(double p, double e) const
679{
680 return p / e;
681}
682double TKinematics::E_final(int i) const
683{
684 return fGamma_cm * (fEcm[i] + fBeta_cm * fPcm[i]);
685}
686double TKinematics::T_final(int i) const
687{
688 return (fGamma_cm - 1) * fM[i] + fGamma_cm * fTcm[i] + fGamma_cm * fBeta_cm * fPcm[i] * cos(fThetacm[i]);
689}
#define RESET_COLOR
Definition Globals.h:5
#define ALERTTEXT
Definition Globals.h:35
const Double_t ps
double fTCm_i
double fQValue
double fTheta[4]
double Angle_cm2lab(double vcm, double angle_cm) const
double Sigma_lab2cm(double angle_cm, double sigma_lab) const
double GetCmEnergy() const
double GetThetacm(int i) const
Definition TKinematics.h:81
double GetExcEnergy(TLorentzVector recoil)
double NormalkinEnergy() const
double fVcm[4]
void AngleErr_lab2cm(double angle, double &err) const
double GetMaxAngle(double vcm) const
double fTcm[4]
double fM[4]
double fThetacm[4]
TSpline3 * fCm2LabSpline
double fV[4]
TSpline3 * Ruthvslab(double thmin, double thmax, double size, int part) const
double Angle_lab2cminverse(double vcm, double angle_lab, bool upper=true) const
TSpline3 * labvscm(double thmin, double thmax, double size, int part=2) const
TSpline3 * cmvslab(double thmin, double thmax, double size, int part=2) const
TSpline3 * Evscm(double thmin, double thmax, double size, int part=2)
bool CheckMaxAngle(double angle, int part) const
TKinematics(double eBeam, const char *beam, const char *targ, const char *ejec=nullptr, const char *reco=nullptr, const char *name="")
double fT[4]
double Sigma_cm2lab(double angle_cm, double sigma_cm) const
double Pcm_em(double, double) const
void Transform2cm(double &angle, double &sigma) const
double P_tm(double, double) const
double betacm_tm(double, double) const
double fBetacm[4]
double V_pe(double, double) const
TNucleus * fParticle[4]
double fPcm[4]
double Rutherford(double angle_cm) const
double GetBetacm() const
Definition TKinematics.h:89
void SigmaErr_lab2cm(double angle, double err, double &sigma, double &errsigma) const
double fGamma_cm
double GetBeamEnergy(double LabAngle, double LabEnergy) const
double Steffen_cm2labinverse(double theta_cm, int part=2) const
TSpline3 * Ruthvscm(double thmin, double thmax, double size) const
double fTCm_f
TGraph * Evslab_graph(double thmin, double thmax, double size, int part=2)
double fBeta_cm
double fP[4]
TSpline3 * Steffen_labvscminverse(double thmin, double thmax, double size, int part=2) const
void SetAngles(double angle, int part, bool upper=false)
TSpline3 * Evslab(double thmin, double thmax, double size, int part=2)
void Final(double angle, int part)
double E_final(int) const
double GetTlab(int i) const
Definition TKinematics.h:70
double fE[4]
double E_tm(double, double) const
double Steffen_lab2cminverse(double theta_lab)
double fEcm[4]
double T_final(int) const
double ELab(double angle_lab, int part)
double GetThetalab(int i) const
Definition TKinematics.h:74
double T_em(double, double) const
double Angle_lab2cm(double vcm, double angle_lab) const
double fEBeam
int GetZ() const
Gets the Z (# of protons) of the nucleus.
Definition TNucleus.h:61
double GetMass() const
Gets the mass of the nucleus (in MeV)
Definition TNucleus.h:65
#define PI
Definition TKinematics.h:21