KaliVeda
Toolkit for HIC analysis
KV2Body.cpp
1 /***************************************************************************
2  KV2Body.cpp - description
3  -------------------
4  begin : 28/11/2003
5  copyright : (C) 2003 by J.D. Frankland
6  email : frankland@ganil.fr
7 
8 $Id: KV2Body.cpp,v 1.4 2009/02/02 13:52:29 ebonnet Exp $
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
20 #include "KV2Body.h"
21 #include "TROOT.h"
22 
23 using namespace std;
24 
26 
27 
28 
29 
32 void KV2Body::init()
33 {
34  //Default initialisations
35  WLT = WCT = 0.;
36  for (int i = 0; i < 5; i++) {
37  WC[i] = 0.;
38  VC[i] = 0.;
39  EC[i] = 0.;
40  K[i] = 0.;
41  TETAMAX[i] = 0.;
42  TETAMIN[i] = 0.;
43  fThetaLabVsThetaCM[i] = nullptr;
44  fELabVsThetaCM[i] = nullptr;
45  fELabVsThetaLab[i] = nullptr;
46  }
47  fKoxReactionXSec = nullptr;
48  fEqbmChargeState = nullptr;
49  fEqbmChargeStateShSol = nullptr;
50  fEqbmChargeStateShGas = nullptr;
51  fSetOutgoing = kFALSE;
52 
53  SetIntegralPrecision(1e-10);
54 }
55 
56 
57 
60 
61 KV2Body::KV2Body(): fNuclei(5), fEDiss(0)
62 {
63  //default ctor
64  init();
65 }
66 
67 
68 
86 
87 KV2Body::KV2Body(const Char_t* systemname) : fNuclei(5), fEDiss(0)
88 {
89  //Set up calculation defining entrance channel following this prescription:
90  //
91  // [Projectile_Symbol]+[Target_Symbol]@[Incident_Energy]MeV/A
92  // [Projectile_Symbol]+[Target_Symbol]@[Incident_Energy]MeV/u
93  // [Projectile_Symbol]+[Target_Symbol]
94  //
95  //Any spaces will be ignored.
96  //
97  //Valid examples:
98  //
99  // 129Xe+119Sn@50.0MeV/A
100  // 58Ni + 64Ni @ 32 MeV/u
101  // U+U@5MeV/A
102  // Ta+Zn
103  //
104  //If the format is not respected, this object will be a zombie (IsZombie() returns kTRUE)
105 
106  init();
107  KVString sener = "";
108  Double_t ee = 0;
109  KVString syst(systemname);
110  syst.ReplaceAll(" ", "");
111  KVString scouple(syst);
112 
113  if (syst.Contains("@")) {
114  syst.Begin("@");
115  scouple = syst.Next();
116  sener = syst.Next();
117  }
118  if (sener != "") {
119  if (sener.Contains("MeV/A")) {
120  sener.ReplaceAll("MeV/A", "");
121  ee = sener.Atof();
122  }
123  else if (sener.Contains("MeV/u")) {
124  sener.ReplaceAll("MeV/u", "");
125  ee = sener.Atof();
126  }
127  else {
128  MakeZombie();
129  }
130  }
131  scouple.Begin("+");
132  KVNucleus nnuc1(scouple.Next(), ee);
133  if (nnuc1.IsZombie()) MakeZombie();
134  else {
135  fNuclei[1] = nnuc1;
136  KVNucleus nnuc2(scouple.Next());
137  if (nnuc2.IsZombie()) MakeZombie();
138  else {
139  fNuclei[2] = nnuc2;
140  }
141  }
142  if (!IsZombie()) {
143  SetTitle(Form("%s + %s %.1f MeV/A", fNuclei[1].GetSymbol(), fNuclei[2].GetSymbol(), ee));
144  }
145 }
146 
147 
148 
151 
152 KV2Body::KV2Body(KVNucleus*, KVNucleus* cib, KVNucleus* proj_out, Double_t): fNuclei(5), fEDiss(0)
153 {
154  // Deprecated. Do not use.
155 
156  Obsolete("KV2Body(KVNucleus*, KVNucleus*, KVNucleus*, Double_t)", "1.11", "1.12");
157 
158  if (!cib) {
159  Info("KV2Body", "Use constructor KV2Body(const KVNucleus& compound) to simulate binary decay of compound");
160  }
161  else if (!proj_out) {
162  Info("KV2Body", "Use constructor KV2Body(const KVNucleus& proj, const KVNucleus& targ) to define entrance channel");
163  }
164  else {
165  Info("KV2Body", "Use constructor KV2Body(const KVNucleus& proj, const KVNucleus& targ, const KVNucleus& outgoing) to define entrance & exit channels");
166  }
167  init();
168 }
169 
170 
171 
195 
196 KV2Body::KV2Body(const KVNucleus& compound, double Exx)
197  : fNuclei(5), fEDiss(-Exx)
198 {
199  // Set up kinematics of binary decay of compound nucleus.
200  //
201  // The excitation energy of the CN (in MeV) is either given:
202  //
203  // - in the KVNucleus object itself (i.e. compound.GetExcitEnergy() gives the E* of CN)
204  // - or in the variable Exx: in this case any E* in the KVNucleus will be ignored
205  // - or by calling SetExcitEnergy or SetDissipatedEnergy after this constructor with the NEGATIVE E*
206  //
207  //Usage:
208  //~~~~~~~~~~{.cpp}
209  // KVNucleus CN("204Pb");
210  // CN.SetExcitEnergy(1.5*CN.GetA());
211  // KV2Body CNdecay(CN);
212  //
213  // /* or: KV2Body CNdecay("204Pb", 1.5*204);
214  // * or: KV2Body CNdecay("204Pb");
215  // * CNdecay.SetExcitEnergy(-1.5*204); */
216  //
217  // // calculate decay
218  // KVNucleus alpha("4He", 67.351/4.);
219  // CNdecay.SetOutgoing(alpha);
220  //~~~~~~~~~~
221 
222  init();
223  fNuclei[1] = compound;
224  if (fEDiss == 0) fEDiss = compound.GetExcitEnergy();
225 }
226 
227 
228 
241 
242 KV2Body::KV2Body(const KVNucleus& proj, const KVNucleus& targ, double Ediss):
243  fNuclei(5), fEDiss(Ediss)
244 {
245  //Set up calculation of basic binary reaction for given projectile and target.
246  //
247  //By default the dissipated energy Ediss is zero (elastic reaction).
248  //
249  //Usage:
250  //~~~~~~~~~~{.cpp}
251  // KV2Body reaction(KVNucleus("129Xe",50), "natSn");
252  //
253  // // or with C++11 (ROOT6):
254  // KV2Body reaction({"129Xe",50}, "natSn");
255  //~~~~~~~~~~
256 
257  init();
258  fNuclei[1] = proj;
259  fNuclei[2] = targ;
260  SetTitle(Form("%s + %s %.1f MeV/A", fNuclei[1].GetSymbol(), fNuclei[2].GetSymbol(), fNuclei[1].GetAMeV()));
261 }
262 
263 
264 
281 
282 KV2Body::KV2Body(const KVNucleus& proj, const KVNucleus& targ, const KVNucleus& outgoing, double Ediss):
283  fNuclei(5), fEDiss(Ediss)
284 {
285  //Set up calculation of basic binary reaction for given projectile and target with definition
286  //of exit channel (outgoing projectile- or target-like fragment).
287  //
288  //By default the dissipated energy is zero (elastic reaction).
289  //
290  //Any excitation energy of the outgoing fragment will be taken into account, e.g.
291  //for quasi-elastic scattering leaving the target in an excited state.
292  //
293  //Usage:
294  //~~~~~~~~~~{.cpp}
295  // KV2Body reaction(KVNucleus("129Xe",50), "natSn", KVNucleus("24Mg",35));
296  //
297  // // or with C++11 (ROOT6):
298  // KV2Body reaction({"129Xe",50}, "natSn", {"24Mg",35});
299  //~~~~~~~~~~
300 
301  init();
302  fNuclei[1] = proj;
303  fNuclei[2] = targ;
304  if (outgoing.GetExcitEnergy() > 0) fEDiss += outgoing.GetExcitEnergy();
305  SetOutgoing(outgoing);
306  SetTitle(Form("%s + %s %.1f MeV/A", fNuclei[1].GetSymbol(), fNuclei[2].GetSymbol(), fNuclei[1].GetAMeV()));
307 }
308 
309 
310 
313 
314 void KV2Body::SetTarget(const KVNucleus& targ)
315 {
316  //Set target for reaction.
317  fNuclei[2] = targ;
319 }
320 
321 
322 
325 
327 {
328  //Set target for reaction
329 
330  fNuclei[2].SetZandA(z, a);
332 }
333 
334 
335 
338 
340 {
341  //Set projectile for reaction.
342  fNuclei[1] = proj;
344 }
345 
346 
347 
350 
352 {
353  //Set projectile for reaction
354  fNuclei[1].SetZandA(z, a);
356 }
357 
358 
359 
361 
362 KV2Body::~KV2Body()
363 {
366  for (int i = 0; i < 5; i++) {
367  if (fThetaLabVsThetaCM[i]) delete fThetaLabVsThetaCM[i];
368  if (fELabVsThetaCM[i]) delete fELabVsThetaCM[i];
369  if (fELabVsThetaLab[i]) delete fELabVsThetaLab[i];
370  }
371 }
372 
373 
374 
375 
379 
381 {
382  //Static function, calculates relativistic velocity (in cm/ns) from rest mass and total
383  //energy (i.e. KE + mass) 'E' for any particle
384 
385  Double_t p = TMath::Sqrt(E * E - mass * mass);
386  return KVParticle::C() * p / E;
387 }
388 
389 
390 
391 
396 
397 void KV2Body::SetOutgoing(const KVNucleus& proj_out)
398 {
399  // Set outgoing projectile-like nucleus properties.
400  //
401  // The properties of the outgoing target-like nucleus will be deduced from mass, charge and momentum/energy conservation.
402 
403  SetTitle(Form("%s + %s %.1f MeV/A", fNuclei[1].GetSymbol(), fNuclei[2].GetSymbol(), fNuclei[1].GetAMeV()));
405  fNuclei[3] = proj_out;
406  Set4thNucleus();
407  // all nuclei should now have E* set to zero in order to use ground state masses in kinematics
408  for (unsigned i = 1; i <= 4; ++i) if (fNuclei[i].IsDefined()) fNuclei[i].SetExcitEnergy(0);
409 }
410 
411 
412 
413 
421 
423 {
424  // Private method, used to deduce 4th nucleus (target-like) from projectile, target
425  // and outgoing projectile using conservation of mass, momentum and energy.
426  //
427  // if the outgoing nucleus set by the user is equal to the compound nucleus
428  // formed by projectile and target, but the excitation energy of the CN
429  // was not set by the user, we calculate it here.
430 
431  KVNucleus sum;
432  if (GetNucleus(2))
433  sum = *GetNucleus(1) + *GetNucleus(2);
434  else sum = *GetNucleus(1);
435  KVNucleus tmp4 = sum - *GetNucleus(3);
436  if (!tmp4.IsDefined()) {
437  // nucleus 3 is the CN proj+targ
438  // has E* been defined ?
439  if (fEDiss == 0) fEDiss = sum.GetExcitEnergy();
440  }
441  fNuclei[4] = tmp4;
442 }
443 
444 
445 
446 
455 
457 {
458  //Return pointer to nucleus i (1 <= i <= 4)
459  //
460  // Entrance channel nuclei ..... i=1 : projectile i=2 : target
461  //
462  // Exit channel nuclei ..... i=3 : projectile-like i=4 : target-like
463  //
464  // Will return `nullptr` if any nucleus is undefined
465 
466  if (i > 0 && i < 5) {
467  if (fNuclei[i].IsDefined()) return (KVNucleus*) &fNuclei[i];
468  return nullptr;
469  }
470  Warning("GetNucleus(Int_t i)", "Index i out of bounds, i=%d", i);
471  return nullptr;
472 }
473 
474 
475 
476 
479 
481 {
482  //Calculate Q-value for reaction, including dissipated (excitation) energy
483 
484  if (!fSetOutgoing) {
485  Warning("GetQReaction", "Parameters for outgoing nuclei not set");
486  return 0.0;
487  }
489 
490  return QR;
491 }
492 
493 
494 
495 
498 
500 {
501  //Calculate Q-value for reaction, assuming all nuclei in ground state
502 
503  if (!fSetOutgoing) {
504  Warning("GetQGroundStates",
505  "Parameters for outgoing nuclei not set");
506  return 0.0;
507  }
508  Double_t QGG =
509  GetNucleus(1)->GetMassExcess() +
510  (GetNucleus(2) ? GetNucleus(2)->GetMassExcess() : 0.)
511  - GetNucleus(3)->GetMassExcess() -
512  (GetNucleus(4) ? GetNucleus(4)->GetMassExcess() : 0.);
513  return QGG;
514 }
515 
516 
517 
518 
521 
523 {
524  //Return available kinetic energy in centre of mass
525 
526  return WCT - (GetNucleus(1)->GetMass() +
527  (GetNucleus(2) ? GetNucleus(2)->GetMass() : 0.));
528 }
529 
530 
531 
535 
537 {
538  //Returns maximum scattering angle in lab for nuclei i=3 (quasiproj)
539  //and i=4 (quasitarget)
540  if (i < 3 || i > 4) {
541  Warning("GetMaxAngleLab(Int_t i)",
542  "Returns maximum scattering angle in lab for nuclei i=3 (quasiproj) and i=4 (quasitarget)");
543  return 0.;
544  }
545  return TETAMAX[i];
546 }
547 
548 
549 
553 
555 {
556  //Returns minimum scattering angle in lab for nuclei i=3 (quasiproj)
557  //and i=4 (quasitarget)
558  if (i < 3 || i > 4) {
559  Warning("GetMinAngleLab(Int_t i)",
560  "Returns minimum scattering angle in lab for nuclei i=3 (quasiproj) and i=4 (quasitarget)");
561  return 0.;
562  }
563  return TETAMIN[i];
564 }
565 
566 
567 
568 
571 
573 {
574  //Return vector velocity of centre of mass of reaction (units: cm/ns)
575 
576  return VCM;
577 }
578 
579 
580 
581 
586 
588 {
589  //Return velocity of nucleus "i" in the centre of mass of the reaction
590  // Entrance channel nuclei ..... i=1 : projectile i=2 : target
591  // Exit channel nuclei ..... i=3 : projectile-like i=4 : target-like
592  return VC[i];
593 }
594 
595 
596 
597 
602 
604 {
605  //Calculate laboratory grazing angle.
606  // i = 1 (default) : projectile
607  // i = 2 : target
608 
609  if (i < 1 || i > 2) {
610  Warning("GetLabGrazingAngle(Int_t i)",
611  "i should be 1 (proj) or 2 (targ)");
612  return 0.0;
613  }
614  if (!GetNucleus(2)) {
615  Warning("GetLabGrazingAngle(Int_t i)",
616  "No target defined for reaction");
617  return 0.0;
618  }
619  Double_t RP = 1.28 * TMath::Power(GetNucleus(1)->GetA(), 1. / 3.)
620  - 0.76 + 0.8 * TMath::Power(GetNucleus(1)->GetA(), -1. / 3.);
621  Double_t RT = 1.28 * TMath::Power(GetNucleus(2)->GetA(), 1. / 3.)
622  - 0.76 + 0.8 * TMath::Power(GetNucleus(2)->GetA(), -1. / 3.);
623  Double_t CP = RP * (1. - TMath::Power(1. / RP, 2.));
624  Double_t CT = RT * (1. - TMath::Power(1. / RT, 2.));
625  Double_t RINT = CP + CT + 4.49 - (CT + CP) / 6.35;
626  Double_t BAR =
627  1.44 * GetNucleus(1)->GetZ() * GetNucleus(2)->GetZ() / RINT;
628  if (GetCMEnergy() < BAR) {
629  //below Coulomb barrier
630  switch (i) {
631  case 1:
632  return 180.;
633  break;
634  case 2:
635  return 90.;
636  break;
637  }
638  }
639  Double_t X = 2. * RINT * GetCMEnergy();
640  Double_t Y =
641  X / (GetNucleus(1)->GetZ() * GetNucleus(2)->GetZ() * 1.44) - 1.;
642  Double_t U = 1. / Y;
643  Double_t GR = 2. * TMath::ASin(U);
644  Double_t GPART = TMath::Pi() - GR;
645  Double_t ARAZ =
646  TMath::Sin(GR) / (TMath::Cos(GR) +
647  GetNucleus(1)->GetA() / (1.0 *
648  GetNucleus(2)->GetA()));
649  Double_t GRAZ = TMath::ATan(ARAZ);
650  if (GRAZ <= 0.)
651  GRAZ += TMath::Pi();
652 
653  switch (i) {
654  case 1: //projectile
655  return (GRAZ * TMath::RadToDeg());
656  break;
657  case 2: //target
658  return (GPART * TMath::RadToDeg() / 2.);
659  break;
660  }
661  return -99.;
662 }
663 
664 
665 
666 
676 
678 {
679  // Called to make kinematics calculation for all nuclei, use once properties of
680  // entrance-channel (and, if necessary, exit-channel) nuclei have been defined.
681  //
682  // If a compound decay is to be calculated (only 1 nucleus in entrance channel),
683  // outgoing (decay) product must be defined before calling this method.
684  //
685  // For a 2-body entrance channel, if no exit-channel nuclei are defined,
686  // we assume elastic scattering (i.e. identical outgoing nuclei)
687 
688  KVNucleus* Nuc1 = GetNucleus(1);
689  KVNucleus* Nuc2 = GetNucleus(2);
690 
691  // compound decay ?
692  if (!Nuc2 && !fSetOutgoing) {
693  Error("CalculateKinematics", "Set outgoing (decay) product first");
694  return;
695  }
696 
697  // call SetOutgoing if not already done
698  if (!fSetOutgoing) SetOutgoing(*Nuc1);
699 
700  // set everything to zero
701  WLT = WCT = BCM = 0.;
702  for (int i = 0; i < 5; i++) {
703  WC[i] = 0.;
704  VC[i] = 0.;
705  EC[i] = 0.;
706  K[i] = 0.;
707  TETAMAX[i] = 0.;
708  TETAMIN[i] = 0.;
709  }
710  VCM.SetXYZ(0., 0., 0.);
711 
712  //total energy (T + m) of entrance channel
713  WLT = Nuc1->E();
714  //velocity of CM
715  VCM = Nuc1->GetMomentum();
716  if (Nuc2) {
717  WLT += Nuc2->E();
718  VCM += Nuc2->GetMomentum();
719  }
720 
721  //beta of CM
722  BCM = VCM.Mag() / WLT;
723 
724  VCM *= (1. / WLT) * KVParticle::C();
725  Nuc1->SetFrame("CM", KVFrameTransform(VCM, kFALSE));
726  if (Nuc2)
727  Nuc2->SetFrame("CM", KVFrameTransform(VCM, kFALSE));
728 
729  //total energy in CM
730  WCT = (GetCMGamma() > 0.0 ? WLT / GetCMGamma() : 0.);
731  if (WCT == 0.0)
732  return;
733 
734  //total energy proj in CM
735  WC[1] = Nuc1->GetFrame("CM")->E();
736  //kinetic energy proj in CM
737  EC[1] = Nuc1->GetFrame("CM")->GetKE();
738  VC[1] = Nuc1->GetFrame("CM")->GetVelocity().Mag();
739  K[1] = VCM.Mag() / VC[1];
740  if (Nuc2) {
741  WC[2] = Nuc2->GetFrame("CM")->E();
742  EC[2] = Nuc2->GetFrame("CM")->GetKE();
743  VC[2] = Nuc2->GetFrame("CM")->GetVelocity().Mag();
744  K[2] = VCM.Mag() / VC[2];
745  }
746 
747  Double_t AM3 = GetNucleus(3)->GetMass();
748  Double_t AM4 = (GetNucleus(4) ? GetNucleus(4)->GetMass() : 0.0);
749  //total cm energy of nucleus 3 (quasiproj)
750  WC[3] = (WCT - GetEDiss()) / 2. + (AM3 - AM4) * (AM3 + AM4)
751  / (2. * (WCT - GetEDiss()));
752  VC[3] = GetVelocity(AM3, WC[3]);
753  //cm kinetic energy
754  EC[3] = WC[3] - AM3;
755  if (VC[3] > 0.) K[3] = VCM.Mag() / VC[3];
756 
757  Double_t T3MAX = 0.;
758  if (TMath::AreEqualAbs(K[3], 1., 1.e-16))
759  T3MAX = TMath::PiOver2();
760  else if (K[3] < 1.)
761  T3MAX = TMath::Pi();
762  else
763  T3MAX = TMath::ATan((1. / TMath::Sqrt(K[3] * K[3] - 1.)) / GetCMGamma());
764  TETAMAX[3] = T3MAX * TMath::RadToDeg();
765 
766  if (!GetNucleus(4))
767  return; //only valid for binary channels
768  //total cm energy of nucleus 4 (quasitarg)
769  WC[4] = WCT - GetEDiss() - WC[3];
770  VC[4] = GetVelocity(AM4, WC[4]);
771  //cm kinetic energy
772  EC[4] = WC[4] - AM4;
773  if (VC[4] > 0.) K[4] = VCM.Mag() / VC[4];
774 
775  Double_t T4MAX = 0.;
776  if (TMath::AreEqualAbs(K[4], 1., 1.e-16))
777  T4MAX = TMath::PiOver2();
778  else if (K[4] < 1.)
779  T4MAX = TMath::Pi();
780  else
781  T4MAX = TMath::ATan((1. / TMath::Sqrt(K[4] * K[4] - 1.)) / GetCMGamma());
782  if (TMath::Abs(GetQReaction()) < 1.E-08 && K[4] < 1.)
783  T4MAX = TMath::PiOver2();
784  TETAMAX[4] = T4MAX * TMath::RadToDeg();
785 }
786 
787 
788 
798 
800 {
801  // \return symbolic representation of the reaction as \f$A(X,Y)B\f$
802  // where
803  // + \f$A\f$ is the target nucleus;
804  // + \f$X\f$ is the projectile nucleus;
805  // + \f$Y\f$ is the outgoing projectile-like nucleus;
806  // + \f$B\f$ is the outgoing target-like nucleus.
807  //
808  // If dissipated/excitation energy is non-zero, we add \f$E_{X}=...\f$ at the end.
809 
810  TString eqn;
811  if (GetNucleus(2) && GetNucleus(4))
812  eqn.Form("%s(%s,%s)%s",
813  GetNucleus(2)->GetLatexSymbol(), GetNucleus(1)->GetLatexSymbol(),
814  GetNucleus(3)->GetLatexSymbol(), GetNucleus(4)->GetLatexSymbol());
815  else if (GetNucleus(3) && !GetNucleus(4)) // fusion
816  eqn.Form("%s(%s,%s)",
817  GetNucleus(2)->GetLatexSymbol(), GetNucleus(1)->GetLatexSymbol(),
818  GetNucleus(3)->GetLatexSymbol());
819  else if (!GetNucleus(2) && GetNucleus(4)) // fission
820  eqn.Form("(%s,%s)%s",
821  GetNucleus(1)->GetLatexSymbol(),
822  GetNucleus(3)->GetLatexSymbol(), GetNucleus(4)->GetLatexSymbol());
823  else if (!GetNucleus(3) && !GetNucleus(4)) // elastic scattering
824  eqn.Form("%s(%s,%s)%s",
825  GetNucleus(2)->GetLatexSymbol(), GetNucleus(1)->GetLatexSymbol(),
826  GetNucleus(1)->GetLatexSymbol(), GetNucleus(2)->GetLatexSymbol());
827  if (TMath::Abs(GetEDiss()) > 0)
828  eqn.Append(Form(" E_{X}=%.1f MeV", GetEDiss()));
829  return eqn;
830 }
831 
832 
833 
834 
839 
841 {
842  //Returns kinetic energy of nucleus "i" in the centre of mass of the reaction
843  // Entrance channel nuclei ..... i=1 : projectile i=2 : target
844  // Exit channel nuclei ..... i=3 : projectile-like i=4 : target-like
845  return EC[i];
846 }
847 
848 
849 
850 
857 
858 void KV2Body::Print(Option_t* opt) const
859 {
860  // Print out characteristics of reaction.
861  //
862  // If a two-body exit channel has been defined, you can use the following options:
863  // opt = "ruth" : list Rutherford scattering cross-sections as a function of angle in laboratory frame
864  // opt = "lab" : list energies and angles in laboratory frame
865 
866  cout << " ***** REACTION " << GetNucleus(1)->GetSymbol();
867  if (GetNucleus(2))
868  cout << " + " << GetNucleus(2)->GetSymbol();
869  if (GetNucleus(3)) {
870  cout << " ---> " << GetNucleus(3)->GetSymbol();
871  }
872  if (GetNucleus(4))
873  cout << " + " << GetNucleus(4)->GetSymbol();
874  cout << " ******" << endl;
875 
876  cout << " E.LAB = " << GetNucleus(1)->GetEnergy() << " MEV";
877  if (GetNucleus(3)) {
878  cout << " QGG = " << GetQGroundStates() << " MEV";
879  }
880  cout << endl;
881  cout << " E.EXC = " << GetExcitEnergy() << " MEV";
882  if (GetNucleus(3)) {
883  cout << " ==> Q-REACTION = " << GetQReaction() << " MEV";
884  }
885  cout << endl;
886  cout << " AVAILABLE ENERGY IN C.M. : ECM = " << GetCMEnergy() <<
887  " MEV (" << GetCMEnergy() / (GetNucleus(1)->GetA() +
888  (GetNucleus(2) ? GetNucleus(2)->
889  GetA() : 0.)) << " MEV/A)" << endl;
890  cout << " PROJECTILE VELOCITY IN LAB " << GetNucleus(1)->GetV().Mag()
891  << " CM/NS ( " << GetNucleus(1)->Beta() << " * C )" << endl;
892  cout << " VELOCITY OF C.M. " << GetCMVelocity().
893  Mag() << " CM/NS" << endl;
894 
895  for (int i = 1; i <= 4; i++) {
896  if (GetNucleus(i))
897  cout << " ENERGY - VELOCITY OF NUCLEUS " << i << " IN CM : " <<
898  GetCMEnergy(i) << " MEV " << GetCMVelocity(i) << " CM/NS (K=" << K[i] << ")" <<
899  endl;
900  }
901  if (GetNucleus(3)) {
902  cout << " MAXIMUM SCATTERING ANGLE IN LABORATORY" << endl;
903  cout << " THETA #3# " << GetMaxAngleLab(3) << " DEG." <<
904  endl;
905  if (GetNucleus(4))
906  cout << " THETA #4# " << GetMaxAngleLab(4) << " DEG." <<
907  endl;
908  }
909  if (GetNucleus(2)) {
910  cout << " GRAZING ANGLE IN LABORATORY : PROJECTILE " <<
911  GetLabGrazingAngle(1) << " DEG." << endl;
912  cout << " GRAZING ANGLE IN LABORATORY : TARGET " <<
913  GetLabGrazingAngle(2) << " DEG." << endl;
914  }
915 
916  if (GetNucleus(3)) {
917  Int_t nsteps = 15;
918 
919  if (!strcmp(opt, "lab") || !strcmp(opt, "LAB")
920  || !strcmp(opt, "Lab")) {
921  //laboratory angular distribution
922  cout << endl <<
923  " LABORATORY ANGULAR DISTRIBUTION" << endl
924  << endl;
925  cout <<
926  " TETA 3 EN.DIF.3 V3 TETA 4 EN.DIF.4 TETA 3"
927  << endl;
928  cout <<
929  " (LAB) (LAB) (LAB) (LAB) (LAB) (C.M)"
930  << endl;
931  Double_t dtheta = GetMaxAngleLab(3) / nsteps;
932  for (int step = 0; step <= nsteps; step++) {
933  Double_t theta = dtheta * step;
934 
935  Double_t elabP1, elabP2;
936  Double_t tcmP1, tcmP2;
937  Double_t vP1, vP2;
938  Double_t tlT1, tlT2;
939  Double_t elabT1, elabT2;
940  GetELab(3, theta, 3, elabP1, elabP2);
941  GetThetaCM(theta, 3, tcmP1, tcmP2);
942  GetVLab(3, theta, 3, vP1, vP2);
943  GetThetaLab(4, theta, 3, tlT1, tlT2);
944  GetELab(4, theta, 3, elabT1, elabT2);
945  printf
946  (" %6.2f %7.2f/%7.2f %5.2f/%5.2f %6.2f/%6.2f %7.2f/%7.2f %6.2f/%6.2f\n",
947  theta, elabP1, elabP2, vP1, vP2,
948  tlT1, tlT2, elabT1, elabT2,
949  tcmP1, tcmP2);
950  }
951  }
952  if (GetNucleus(2) && (!strcmp(opt, "ruth") || !strcmp(opt, "RUTH")
953  || !strcmp(opt, "Ruth"))) {
954  //laboratory angular distribution with Rutherford x-section
955  cout << endl <<
956  " RUTHERFORD LABORATORY ANGULAR DISTRIBUTION" <<
957  endl << endl;
958  cout <<
959  " TETA 3 TETA 3 EN.DIF.3 SIG.RUT. SIG.RUT."
960  << endl;
961  cout <<
962  " (LAB) (CM) (LAB) (LAB) (b/sr) (CM) (b/sr)"
963  << endl;
964  //go up to grazing angle
965  Double_t dtheta = GetLabGrazingAngle(1) / nsteps;
966  for (int step = 0; step < nsteps; step++) {
967  Double_t theta = dtheta * (step + 1);
968  Double_t elabP1, elabP2;
969  Double_t tcm1, tcm2;
970  GetELab(3, theta, 3, elabP1, elabP2);
971  GetThetaCM(theta, 3, tcm1, tcm2);
972  printf
973  (" %6.2f %6.2f %7.2f %10.4g %10.4g\n",
974  theta, tcm1, elabP1,
975  GetXSecRuthLab(theta), GetXSecRuthCM(theta));
976  }
977  }
978  }
979 }
980 
981 
982 
989 
990 Int_t KV2Body::GetELab(Int_t OfNucleus, Double_t ThetaLab, Int_t AngleNucleus, Double_t& e1, Double_t& e2) const
991 {
992  // Calculate laboratory kinetic energy of nucleus OfNucleus as a function of the lab angle of
993  // nucleus AngleNucleus.
994  //
995  // In general there may be two solutions for a given angle, therefore we return the number
996  // of solutions (0 if ThetaLab > max lab angle for nucleus in question).
997 
998  e1 = e2 = -1.;
999  if (ThetaLab > TETAMAX[AngleNucleus]) return 0;
1000  // calculate CM angle(s)
1001  Double_t TCM1, TCM2;
1002  Int_t nsol = GetThetaCM(ThetaLab, AngleNucleus, TCM1, TCM2);
1003  TCM1 = GetThetaCM(OfNucleus, TCM1, AngleNucleus);
1004  if (nsol > 1) TCM2 = GetThetaCM(OfNucleus, TCM2, AngleNucleus);
1005  // calculate lab energie(s) of corresponding to CM angle(s)
1006  e1 = GetELab(TCM1, OfNucleus);
1007  if (nsol == 2) e2 = GetELab(TCM2, OfNucleus);
1008  return nsol;
1009 }
1010 
1011 
1012 
1016 
1017 Int_t KV2Body::GetThetaCM(Double_t ThetaLab, Int_t OfNucleus, Double_t& t1, Double_t& t2) const
1018 {
1019  // Calculate CM angle of nucleus OfNucleus as a function of its lab angle.
1020  // Returns number of solutions (there may be <=2 solutions).
1021 
1022  t1 = t2 = -1.;
1023  KV2Body* kin = const_cast<KV2Body*>(this);
1024  TF1* TLF = kin->GetThetaLabVsThetaCMFunc(OfNucleus);
1025  Int_t nsol = FindRoots(TLF, 0., 180., ThetaLab, t1, t2);
1026  return nsol;
1027 }
1028 
1029 
1030 
1033 
1035 {
1036  // Function calculating lab energy of nucleus par[0] for any lab angle x[0]
1037 
1038  Double_t e1, e2;
1039  Int_t nsol = GetELab((Int_t)par[0], x[0], (Int_t)par[0], e1, e2);
1040  if (!nsol) return 0;
1041  //if(nsol>1) Warning("ELabVsThetaLab", "Two energies are possible for %f deg. : %f and %f",
1042  // x[0],e1,e2);
1043  return e1;
1044 }
1045 
1046 
1047 
1050 
1052 {
1053  // Function calculating lab energy of nucleus par[0] for any CM angle x[0]
1054 
1055  Int_t OfNucleus = (Int_t)par[0];
1056  Double_t TCM = x[0] * TMath::DegToRad();
1057  Double_t WL =
1058  WC[OfNucleus] * GetCMGamma() * (1. +
1059  BCM * (VC[OfNucleus] / KVParticle::C()) *
1060  TMath::Cos(TCM));
1061  return (WL - GetNucleus(OfNucleus)->GetMass());
1062 }
1063 
1064 
1065 
1069 
1071 {
1072  // Calculate Lab angle of nucleus as function of CM angle x[0]
1073  // par[0] = index of nucleus = 1, 2, 3, 4
1074 
1075  Double_t ThetaCM = x[0] * TMath::DegToRad();
1076  Int_t OfNucleus = (Int_t)par[0];
1077  Double_t ThetaL = TMath::ATan2(TMath::Sin(ThetaCM) + 1e-10, (K[OfNucleus] + TMath::Cos(ThetaCM)) * GetCMGamma()) * TMath::RadToDeg();
1078 
1079  if (ThetaL < 0.) ThetaL += 180.;
1080  return ThetaL;
1081 }
1082 
1083 
1084 
1088 
1090 {
1091  // Return TF1 giving lab energy of nucleus as function of CM angle
1092  // OfNucleus = 1 or 2 (entrance channel) or 3 or 4 (exit channel)
1093 
1094  if (!fELabVsThetaCM[OfNucleus]) {
1095  fELabVsThetaCM[OfNucleus] = new TF1(Form("KV2Body:ELabVsThetaCM:%d", OfNucleus),
1096  const_cast<KV2Body*>(this), &KV2Body::ELabVsThetaCM, 0, 180, 1, "KV2Body", "ELabVsThetaCM");
1097  fELabVsThetaCM[OfNucleus]->SetNpx(1000);
1098  fELabVsThetaCM[OfNucleus]->SetParameter(0, OfNucleus);
1099  }
1100  return fELabVsThetaCM[OfNucleus];
1101 }
1102 
1103 
1104 
1108 
1110 {
1111  // Return TF1 giving lab energy of nucleus as function of its lab angle
1112  // OfNucleus = 1 or 2 (entrance channel) or 3 or 4 (exit channel)
1113 
1114  if (!fELabVsThetaLab[OfNucleus]) {
1115  fELabVsThetaLab[OfNucleus] = new TF1(Form("KV2Body:ELabVsThetaLab:%d", OfNucleus),
1116  const_cast<KV2Body*>(this), &KV2Body::ELabVsThetaLab, 0, 180, 1, "KV2Body", "ELabVsThetaLab");
1117  fELabVsThetaLab[OfNucleus]->SetNpx(1000);
1118  fELabVsThetaLab[OfNucleus]->SetParameter(0, OfNucleus);
1119  }
1120  return fELabVsThetaLab[OfNucleus];
1121 }
1122 
1123 
1124 
1125 
1132 
1133 Int_t KV2Body::GetVLab(Int_t OfNucleus, Double_t ThetaLab, Int_t AngleNucleus, Double_t& v1, Double_t& v2) const
1134 {
1135  // Calculate laboratory velocity of nucleus OfNucleus as a function of the lab angle of
1136  // nucleus AngleNucleus.
1137  //
1138  // In general there may be two solutions for a given angle, therefore we return the number
1139  // of solutions (0 if ThetaLab > max lab angle for nucleus in question).
1140 
1141  Double_t e1, e2;
1142  v1 = v2 = 0.;
1143  Int_t nsol = GetELab(OfNucleus, ThetaLab, AngleNucleus, e1, e2);
1144  if (!nsol) return nsol;
1145  Double_t etot1 = e1 + GetNucleus(OfNucleus)->GetMass();
1146  Double_t etot2 = e2 + GetNucleus(OfNucleus)->GetMass();
1147  v1 = GetVelocity(GetNucleus(OfNucleus)->GetMass(), etot1);
1148  if (nsol > 1) v2 = GetVelocity(GetNucleus(OfNucleus)->GetMass(), etot2);
1149  return nsol;
1150 }
1151 
1152 
1153 
1154 
1161 
1162 Int_t KV2Body::GetThetaLab(Int_t OfNucleus, Double_t ThetaLab, Int_t AngleNucleus, Double_t& t1, Double_t& t2) const
1163 {
1164  // Calculate laboratory angle of nucleus OfNucleus as a function of the laboratory angle of
1165  // nucleus AngleNucleus.
1166  //
1167  // In general there may be two solutions for a given angle, therefore we return the number
1168  // of solutions (0 if ThetaLab > max lab angle for nucleus in question).
1169 
1170  t1 = t2 = -1.;
1171  if (ThetaLab > TETAMAX[AngleNucleus]) return 0;
1172  if (!(TMath::Abs(OfNucleus - AngleNucleus) % 2)) {
1173  // same nucleus!
1174  t1 = ThetaLab;
1175  return 1;
1176  }
1177  // calculate CM angle(s)
1178  Double_t TCM1, TCM2;
1179  Int_t nsol = GetThetaCM(ThetaLab, AngleNucleus, TCM1, TCM2);
1180  TCM1 = GetThetaCM(OfNucleus, TCM1, AngleNucleus);
1181  if (nsol > 1) TCM2 = GetThetaCM(OfNucleus, TCM2, AngleNucleus);
1182  // calculate lab angle(s) of corresponding CM angle(s)
1183  t1 = GetThetaLab(TCM1, OfNucleus);
1184  if (nsol == 2) t2 = GetThetaLab(TCM2, OfNucleus);
1185  return nsol;
1186 }
1187 
1188 
1189 
1193 
1195 {
1196  // Return TF1 giving lab angle of nucleus as function of CM angle
1197  // OfNucleus = 1 or 2 (entrance channel) or 3 or 4 (exit channel)
1198 
1199  if (!fThetaLabVsThetaCM[OfNucleus]) {
1200  fThetaLabVsThetaCM[OfNucleus] = new TF1(Form("KV2Body:ThetaLabVsThetaCM:%d", OfNucleus),
1201  const_cast<KV2Body*>(this), &KV2Body::ThetaLabVsThetaCM, 0, 180, 1, "KV2Body", "ThetaLabVsThetaCM");
1202  fThetaLabVsThetaCM[OfNucleus]->SetNpx(1000);
1203  fThetaLabVsThetaCM[OfNucleus]->SetParameter(0, OfNucleus);
1204  }
1205  return fThetaLabVsThetaCM[OfNucleus];
1206 }
1207 
1208 
1209 
1216 
1217 Double_t KV2Body::GetXSecRuthCM(Double_t ThetaLab, Int_t OfNucleus) const
1218 {
1219  //Calculate Rutherford cross-section (b/sr) in the CM as a
1220  //function of projectile (OfNucleus=3) or target (OfNucleus=4) lab scattering angle
1221  //
1222  // WARNING: in inverse kinematics, projectile lab angles generally have
1223  // two corresponding CM angles. We only use the most forward (smallest) CM angle.
1224 
1225  Double_t par = OfNucleus;
1226  return const_cast<KV2Body*>(this)->XSecRuthCM(&ThetaLab, &par);
1227 }
1228 
1229 
1230 
1237 
1239 {
1240  //Calculate Rutherford cross-section (b/sr) in the CM as a
1241  //function of projectile (OfNucleus=3) or target (OfNucleus=4) lab scattering angle
1242  //
1243  // WARNING: in inverse kinematics, projectile lab angles generally have
1244  // two corresponding CM angles. We only use the most forward (smallest) CM angle.
1245 
1246  if (!GetNucleus(2)) {
1247  Warning("GetXSecRuthCM", "No target defined for reaction");
1248  return 0.;
1249  }
1250  Double_t PB =
1251  1.44 * GetNucleus(1)->GetZ() * GetNucleus(2)->GetZ() /
1252  GetCMEnergy();
1253  // get projectile CM angle from lab angle of nucleus par[0]
1254  Double_t TCM = GetMinThetaCMFromThetaLab(1, x[0], par[0]);
1255  if (TCM < 0) return 0;
1256  Double_t D = 1. / (16. * (TMath::Power(TMath::Sin(TCM * TMath::DegToRad() / 2.), 4.)));
1257 
1258  return ((TMath::Power(PB, 2.)) * D / 100.);
1259 }
1260 
1261 
1262 
1268 
1269 Double_t KV2Body::GetMinThetaCMFromThetaLab(Int_t OfNucleus, Double_t theta, Int_t OtherNucleus) const
1270 {
1271  // Return the smallest (i.e. most forward) CM angle of nucleus OfNucleus
1272  // corresponding to laboratory angle theta of nucleus OtherNucleus
1273  //
1274  // If theta>max lab angle for nucleus, returns -1.0
1275 
1276  if (theta > TETAMAX[OtherNucleus]) return -1;
1277  Double_t t1, t2;
1278  Int_t nsol = GetThetaCM(theta, OtherNucleus, t1, t2);
1279  if (!nsol) return -1.;
1280  Double_t Pt1 = GetThetaCM(OfNucleus, t1, OtherNucleus);
1281  Double_t Pt2 = GetThetaCM(OfNucleus, t2, OtherNucleus);
1282  Double_t Pt;
1283  if (nsol > 1)
1284  Pt = TMath::Min(Pt1, Pt2);
1285  else
1286  Pt = Pt1;
1287  return Pt;
1288 }
1289 
1290 
1291 
1311 
1313 {
1314  // Fill and return TGraph with complete correlation between lab energy [MeV] and angle [deg]
1315  //
1316  // \param ofNuc index of outgoing nucleus for which to draw correlation:
1317  // + ofNuc=3: projectile-like
1318  // + ofNuc=4: target-like
1319  // \param npoints number of points in graph [default=50]
1320  //
1321  // \returns a KVDrawable<TGraph> object which can either be used directly as a TGraph with the `->` operator:
1322  //~~~{.cpp}
1323  //KV2Body toto;
1324  //toto.GraphELabVsThetaLab()->Draw("al");
1325  //~~~
1326  // or with a chain of instructions to define the colour, style, etc. of the lines, points:
1327  //~~~{.cpp}
1328  //toto.GraphELabVsThetaLab().LineColor(kRed).LineWidth(2).LineStyle(kDashed)->Draw("al");
1329  //~~~
1330  //
1331  // See \ref Example_KV2Body.C for a full example of use.
1332 
1333  auto gr = new TGraph;
1334  gr->SetTitle(Form("%s: %s", GetNucleus(ofNuc)->GetLatexSymbol(), GetReactionEquation().Data()));
1335  double dth = 180. / (npoints - 1.);
1336  int i = 0;
1337  while (i < npoints) {
1338  auto thcm = i * dth;
1339  auto thlab = GetThetaLabVsThetaCMFunc(ofNuc)->Eval(thcm);
1340  auto elab = GetELabVsThetaCMFunc(ofNuc)->Eval(thcm);
1341  gr->AddPoint(thlab, elab);
1342  ++i;
1343  }
1344  return KVDrawable{gr};
1345 }
1346 
1347 
1348 
1352 
1354 {
1355  // Calculate CM Rutherford cross-section (b/sr) in the CM as a function of
1356  // scattering angle in the CM frame for nucleus par[0]
1357 
1358  if (!GetNucleus(2)) {
1359  Warning("XSecRuthCMVsThetaCM", "No target defined for reaction");
1360  return 0.;
1361  }
1362  Double_t PB =
1363  1.44 * GetNucleus(1)->GetZ() * GetNucleus(2)->GetZ() /
1364  GetCMEnergy();
1365  Double_t TCM = x[0] * TMath::DegToRad();
1366  Int_t OfNucleus = (Int_t)par[0];
1367  if (OfNucleus == 2 || OfNucleus == 4) TCM = TMath::Pi() - TCM; // get projectile CM angle from target CM angle
1368  Double_t D = 1. / (16. * (TMath::Power(TMath::Sin(TCM / 2.), 4.)));
1369  return ((TMath::Power(PB, 2.)) * D / 100.);
1370 }
1371 
1372 
1373 
1380 
1382 {
1383  //Calculate Rutherford cross-section (b/sr) in the Lab as a
1384  //function of projectile (OfNucleus=3) or target (OfNucleus=4) lab scattering angle
1385  //
1386  // WARNING: in inverse kinematics, projectile lab angles generally have
1387  // two corresponding CM angles. We only use the most forward (smallest) CM angle.
1388 
1389  Double_t par = OfNucleus;
1390  return const_cast<KV2Body*>(this)->XSecRuthLab(&ThetaLab, &par);
1391 }
1392 
1393 
1394 
1401 
1403 {
1404  //Calculate Rutherford cross-section (b/sr) in the Lab as a
1405  //function of projectile (OfNucleus=3) or target (OfNucleus=4) lab scattering angle
1406  //
1407  // WARNING: in inverse kinematics, projectile lab angles generally have
1408  // two corresponding CM angles. We only use the most forward (smallest) CM angle.
1409 
1410  Double_t DSIDTB = XSecRuthCM(x, par);
1411  if (DSIDTB > 0) {
1412  // get projectile CM angle from lab angle of nucleus par[0]
1413  Double_t T3CM = GetMinThetaCMFromThetaLab(par[0], x[0], par[0]);
1414  Double_t T3L = GetThetaLab(T3CM, par[0]) * TMath::DegToRad();
1415  T3CM *= TMath::DegToRad();
1416  Double_t RLC = (TMath::Power(TMath::Sin(T3CM), 3.)) /
1417  ((TMath::Power(TMath::Sin(T3L), 3.)) * GetCMGamma() *
1418  (1. + K[(int)par[0]] * TMath::Cos(T3CM)));
1419  if (DSIDTB * RLC < 0) {
1420  Warning("GetXSecRuthLab", "negative value for choosen parameters : %lf %d\n", x[0], (Int_t)par[0]);
1421  return 0;
1422  }
1423  DSIDTB *= RLC;
1424  }
1425  return DSIDTB;
1426 }
1427 
1428 
1429 
1434 
1436 {
1437  //Rutherford cross-section (b/sr) function in the Lab as a
1438  //function of projectile (OfNucleus=3) or target (OfNucleus=4) lab scattering angle x[0]
1439  //including 'sin theta' factor needed for integrating over solid angles.
1440 
1441  return XSecRuthLab(x, par) * TMath::Sin(x[0] * TMath::DegToRad());
1442 }
1443 
1444 
1445 //Double_t KV2Body::GetIntegratedXSecRuthLab(KVTelescope* tel, Int_t OfNucleus)
1446 //{
1447 // //Calculate Integrated Rutherford cross-section (barns) in the Lab using
1448 // //polar and azimuthal angular range of the given KVTelescope.
1449 // // if (OfNucleus==3) => X-section for scattered projectile
1450 // // if (OfNucleus==4) => X-section for scattered target
1451 // //
1452 // //The returned value is in barns
1453 //
1454 // return GetIntegratedXSecRuthLab(tel->GetThetaMin(), tel->GetThetaMax(), tel->GetPhiMin(), tel->GetPhiMax(), OfNucleus);
1455 //}
1456 //
1458 //Double_t KV2Body::GetIntegratedXSecRuthLab(KVDetector* det, Int_t OfNucleus)
1459 //{
1460 // //Calculate Integrated Rutherford cross-section (barns) in the Lab using
1461 // //polar and azimuthal angular range of the given KVDetector. These will be taken
1462 // //from the parent KVTelescope of the detector.
1463 // // if (OfNucleus==3) => X-section for scattered projectile
1464 // // if (OfNucleus==4) => X-section for scattered target
1465 // //
1466 // //The returned value is in barns
1467 //
1468 // KVTelescope* tel = (KVTelescope*)det->GetParentStructure("TELESCOPE");
1469 // if (!det) {
1470 // Error("GetIntegratedXSecRuthLab(KVDetector*,Int_t)",
1471 // "Detector has no parent telescope: it has not been positioned in a multidetector geometry");
1472 // return 0;
1473 // }
1474 // return GetIntegratedXSecRuthLab(tel, OfNucleus);
1475 //}
1476 
1477 
1488 
1490 {
1491  //Calculate Integrated Rutherford cross-section (barns) in the Lab using
1492  //polar and azimuthal angular range expressed in degree
1493  // if (OfNucleus==3) This angular range is considered to be the scattered projectile one
1494  // if (OfNucleus==4) This angular range is considered to be the scattered target one
1495  //
1496  //If phi1 ou phi2 ==-1 the azimuthal width is set to 2pi
1497  //Else if phi1=phi2 the azimuthal width is set to 1 ie the integral is only on theta
1498  //
1499  //The returned value is in barns
1500 
1501  if (th2 < th1) return 0;
1502  Double_t dphi = 0;
1503  //azimuthal width expressed in rad
1504  if (phi1 == -1 || phi2 == -1) dphi = 2 * TMath::Pi();
1505  else if (phi1 == phi2) dphi = 1;
1506  else {
1507  dphi = phi2 - phi1;
1508  dphi *= TMath::DegToRad();
1509  }
1510  Double_t theta_min = 1.;
1511  Double_t theta_max = 179.;
1512  if (th1 < theta_min) theta_min = th1;
1513  if (th2 > theta_max) theta_max = th2;
1514 
1515 #if ROOT_VERSION_CODE > ROOT_VERSION(5,99,01)
1516  return GetXSecRuthLabIntegralFunc(OfNucleus, theta_min, theta_max)->Integral(th1, th2, fIntPrec) * TMath::DegToRad() * dphi;
1517 #else
1518  const Double_t* para = 0;
1519  return GetXSecRuthLabIntegralFunc(OfNucleus, theta_min, theta_max)->Integral(th1, th2, para, fIntPrec) * TMath::DegToRad() * dphi;
1520 #endif
1521 }
1522 
1523 
1524 
1529 
1530 TF1* KV2Body::GetXSecRuthCMFunc(Int_t OfNucleus, Double_t theta_cm_min, Double_t theta_cm_max) const
1531 {
1532  // Return pointer to TF1 giving Rutherford cross-section (b/sr) in the CM as a
1533  // function of projectile (OfNucleus=3) or target (OfNucleus=4) CM scattering angle
1534  // By default, theta_min = 1 degree & theta_max = 179 degrees
1535 
1536  TString name = "RuthXSecCM: ";
1537  name += GetNucleus(1)->GetSymbol();
1538  name += " + ";
1539  name += GetNucleus(2)->GetSymbol();
1540  name += " ";
1541  Double_t elab = GetNucleus(1)->GetEnergy() / GetNucleus(1)->GetA();
1542  name += Form("%6.1f AMeV ", elab);
1543  if (OfNucleus == 3) name += "(projectile)";
1544  else name += "(target)";
1545  TF1* fXSecRuthCM = (TF1*)gROOT->GetListOfFunctions()->FindObject(name.Data());
1546  if (!fXSecRuthCM) {
1547  fXSecRuthCM = new TF1(name.Data(),
1548  const_cast<KV2Body*>(this), &KV2Body::XSecRuthCMVsThetaCM,
1549  theta_cm_min, theta_cm_max, 1, "KV2Body", "XSecRuthCMVsThetaCM");
1550  fXSecRuthCM->SetParameter(0, OfNucleus);
1551  fXSecRuthCM->SetNpx(1000);
1552  }
1553  fXSecRuthCM->SetRange(theta_cm_min, theta_cm_max); //in case TF1 already exists, but new range is required
1554  return fXSecRuthCM;
1555 }
1556 
1557 
1558 
1559 
1564 
1566 {
1567  // calculate Bass interaction barrier B_int
1568  //
1569  // r0 = 1.07 fm
1570 
1571  const Double_t r0 = 1.07;
1572  const Double_t e2 = 1.44;
1573  Double_t A1third = pow(GetNucleus(1)->GetA(), 1. / 3.);
1574  Double_t A2third = pow(GetNucleus(2)->GetA(), 1. / 3.);
1575  Double_t R12 = r0 * (A1third + A2third);
1576 
1577  Double_t Bint = GetNucleus(1)->GetZ() * GetNucleus(2)->GetZ() * e2 / (R12 + 2.7)
1578  - 2.9 * A1third * A2third / (A1third + A2third);
1579 
1580  return Bint;
1581 }
1582 
1583 
1584 
1585 
1591 
1593 {
1594  // calculate Kox reaction X-section (in barns) for a given lab energy of projectile (in MeV/nucleon)
1595  //
1596  // c parameter fitted with Landau function vs. Log10(E/A) (see Fig. 12 of PRC Kox 87)
1597  // by imposing c=0.1 at E/A=10 MeV (goes to 0 as E/A->0)
1598 
1599  const Double_t r0 = 1.05;
1600  const Double_t rc = 1.3;
1601  const Double_t e2 = 1.44;
1602  const Double_t a = 1.9;
1603 
1604  KVNucleus* proj = GetNucleus(1);
1605  KVNucleus* targ = GetNucleus(2);
1606  proj->SetEnergy(eproj[0]*proj->GetA());
1608  Double_t ECM = GetCMEnergy();
1609 
1610  Double_t c = 11.3315 * TMath::Landau(TMath::Log10(eproj[0]), 2.47498, 0.554937);
1611  Double_t A1third = pow(proj->GetA(), 1. / 3.);
1612  Double_t A2third = pow(targ->GetA(), 1. / 3.);
1613  Double_t BC = proj->GetZ() * targ->GetZ() * e2 / (rc * (A1third + A2third));
1614  Double_t EFac = 1 - BC / ECM;
1615 
1616  Double_t Xsec = TMath::Pi() * pow(r0, 2) *
1617  pow((A1third + A2third + a * A1third * A2third / (A1third + A2third) - c), 2) *
1618  EFac;
1619 
1620  return Xsec / 100.;
1621 }
1622 
1623 
1624 
1625 
1629 
1631 {
1632  // calculate Reaction Cross Section with the "Sphere Dure"
1633  // approximation
1634 
1635  Double_t A1third = pow(GetNucleus(1)->GetA(), 1. / 3.);
1636  Double_t A2third = pow(GetNucleus(2)->GetA(), 1. / 3.);
1637 
1638  Double_t Xsec = TMath::Pi() * pow(r0, 2) *
1639  pow(A1third + A2third, 2);
1640 
1641  return Xsec / 100.;
1642 }
1643 
1644 
1645 
1646 
1650 
1652 {
1653 
1654  // Deduce the maximum impact parameter (in fm) from a given reaction cross section (in barn)
1655  // in the approximation Xsec = \int(0,bmax) 2Pi b db
1656 
1657  return 10 * TMath::Sqrt(ReacXsec / TMath::Pi());
1658 
1659 }
1660 
1661 
1662 
1663 
1664 
1665 
1669 
1671 {
1672 
1673  // Integrate the cross section between two impact parameter (in fm)
1674  // and give the result in barn
1675 
1676  return TMath::Pi() * (TMath::Power(b2, 2.) - TMath::Power(b1, 2.)) / 100;
1677 
1678 }
1679 
1680 
1681 
1682 
1688 
1690 {
1691  // Return pointer to TF1 with Kox reaction X-section in barns as a
1692  // function of projectile lab energy (in Mev/nucleon) for this reaction.
1693  // By default the range of the function is [20,100] MeV/nucleon.
1694  // Change with TF1::SetRange.
1695 
1696  if (!fKoxReactionXSec) {
1697  TString name = GetNucleus(1)->GetSymbol();
1698  name += " + ";
1699  name += GetNucleus(2)->GetSymbol();
1700  fKoxReactionXSec = new TF1(name.Data(),
1701  const_cast<KV2Body*>(this), &KV2Body::KoxReactionXSec, 20, 100, 0, "KV2Body", "KoxReactionXSec");
1702  fKoxReactionXSec->SetNpx(1000);
1703  }
1704  return fKoxReactionXSec;
1705 }
1706 
1707 
1708 
1709 
1736 
1738 {
1739  // Calculate the mean charge state of the projectile after passage through the target,
1740  // assuming that the equilibrium charge state distribution is achieved*.
1741  // t[0] = energy of projectile after the target (in MeV/nucleon)
1742  //
1743  // We use the empirical parameterization of Leon et al., At. Dat. and Nucl. Dat. Tab. 69, 217 (1998)
1744  // developed for heavy ions in the GANIL energy range (it represents a fit to data measured using
1745  // GANIL beams).
1746  //
1747  // *N.B. Concerning equilibrium charge state distributions, it is not easy to know whether, for a given
1748  // combination of projectile, projectile energy, target, and target thickness, the equilibrium
1749  // distribution is reached or not. Here are some comments from the paper cited above which
1750  // may give some guidelines:
1751  //
1752  // "The energies available at the GANIL accelerator range from 24 to 95 MeV/u. Within this energy range,
1753  // the equilibrium charge state is reached only for fairly thick targets (~1 mg/cm2 for C foils)."
1754  //
1755  // "Mean Charge State as a Function of the Target Thickness
1756  // A typical example of the variation of the mean charge as a function of the foil thickness is shown ... It is seen
1757  // that the mean charge initially increases due to the ionization process. Then, the equilibrium state is reached at
1758  // a certain thickness, the so-called equilibrium thickness, due to the equilibration of electron loss and
1759  // capture processes. Finally, for foils thicker than the equilibrium thickness, the mean charge decreases due to the
1760  // slowing down of the ions in matter leading to higher capture cross sections."
1761  //
1762  // It should be noted that, according to the data published in this and other papers, the equilibrium thickness
1763  // decreases with increasing atomic number of the target, and increases with increasing energy of the projectile.
1764 
1765  KVNucleus* proj = GetNucleus(1);
1766  Double_t Zp = proj->GetZ();
1767  proj->SetEnergy(t[0]*proj->GetA());
1768  Double_t beta = proj->Beta();
1769  Double_t vp = beta * KVParticle::C();
1770  Double_t Zt = GetNucleus(2)->GetZ();
1771 
1772  Double_t q = Zp * (1. - TMath::Exp(-83.275 * beta / pow(Zp, 0.477)));
1773 
1774  // correction for target Z
1775  Double_t g = 0.929 + 0.269 * TMath::Exp(-0.16 * Zt) + (0.022 - 0.249 * TMath::Exp(-0.322 * Zt)) * vp / pow(Zp, 0.477);
1776  q *= g;
1777 
1778  if (Zp > 54) {
1779  // f(Zp) - correction for projectiles with Z>54
1780  Double_t f = 1. - TMath::Exp(-12.905 + 0.2124 * Zp - 0.00122 * pow(Zp, 2));
1781  q *= f;
1782  }
1783 
1784  return q;
1785 }
1786 
1787 
1788 
1789 
1799 
1801 {
1802  // Return pointer to TF1 giving mean charge state of the projectile after passage through the target,
1803  // assuming that the equilibrium charge state distribution is achieved, as a function of projectile
1804  // energy after the target (in MeV/nucleon).
1805  // We use the empirical parameterization of Leon et al., At. Dat. and Nucl. Dat. Tab. 69, 217 (1998)
1806  // (see EqbmChargeState(Double_t *t,Double_t*) for details)
1807  //
1808  // By default the range of the function is [5,100] MeV/nucleon.
1809  // Change with TF1::SetRange.
1810 
1811  if (!fEqbmChargeState) {
1812  TString name = GetNucleus(1)->GetSymbol();
1813  name += " + ";
1814  name += GetNucleus(2)->GetSymbol();
1815  name += " LEON";
1816  fEqbmChargeState = new TF1(name.Data(),
1817  const_cast<KV2Body*>(this), &KV2Body::EqbmChargeState, 5, 100, 0, "KV2Body", "EqbmChargeState");
1818  fEqbmChargeState->SetNpx(1000);
1819  }
1820  return fEqbmChargeState;
1821 }
1822 
1823 
1824 
1828 
1830 {
1831  // G. Shiwietz et al Nucl. Instr. and Meth. in Phys. Res. B 175-177 (2001) 125-131
1832  // for solid targets
1833 
1834  KVNucleus* proj = GetNucleus(1);
1835  Double_t Zp = proj->GetZ();
1836  proj->SetEnergy(t[0]*proj->GetA());
1837  KVNucleus* targ = GetNucleus(2);
1838  Double_t Zt = targ->GetZ();
1839  Double_t Vp = proj->Beta();
1840  const Double_t V0 = 2.19e+06 / TMath::C();
1841  Double_t x = -0.019 * pow(Zp, -0.52) * Vp / V0;
1842  x = Vp / V0 * pow(Zp, -0.52) * pow(Zt, x) / 1.68;
1843  x = pow(x, 1. + 1.8 / Zp);
1844  Double_t q = 0.07 / x + 6. + 0.3 * pow(x, 0.5) + 10.37 * x + pow(x, 4);
1845  q = (Zp * (12 * x + pow(x, 4.))) / q;
1846  return q;
1847 }
1848 
1849 
1859 
1861 {
1862  // Return pointer to TF1 giving mean charge state of the projectile after passage through the target,
1863  // assuming that the equilibrium charge state distribution is achieved, as a function of projectile
1864  // energy after the target (in MeV/nucleon).
1865  // G. Shiwietz et al Nucl. Instr. and Meth. in Phys. Res. B 175-177 (2001) 125-131
1866  // This formula is valid for solid targets.
1867  //
1868  // By default the range of the function is [5,100] MeV/nucleon.
1869  // Change with TF1::SetRange.
1870 
1871  if (!fEqbmChargeStateShSol) {
1872  TString name = GetNucleus(1)->GetSymbol();
1873  name += " + ";
1874  name += GetNucleus(2)->GetSymbol();
1875  name += " SHIWIETZ-SOLID";
1876  fEqbmChargeStateShSol = new TF1(name.Data(),
1877  const_cast<KV2Body*>(this), &KV2Body::eqbm_charge_state_shiwietz_solid, 5, 100, 0, "KV2Body", "eqbm_charge_state_shiwietz_solid");
1879  }
1880  return fEqbmChargeStateShSol;
1881 }
1882 
1883 
1884 
1888 
1890 {
1891  // G. Shiwietz et al Nucl. Instr. and Meth. in Phys. Res. B 175-177 (2001) 125-131
1892  // for gas targets
1893 
1894  KVNucleus* proj = GetNucleus(1);
1895  Double_t Zp = proj->GetZ();
1896  proj->SetEnergy(t[0]*proj->GetA());
1897  KVNucleus* targ = GetNucleus(2);
1898  Double_t Zt = targ->GetZ();
1899  Double_t Vp = proj->Beta();
1900  const Double_t V0 = 2.19e+06 / TMath::C();
1901  Double_t x = 0.03 - 0.017 * pow(Zp, -0.52) * Vp / V0;
1902  x = Vp / V0 * pow(Zp, -0.52) * pow(Zt, x);
1903  x = pow(x, 1. + 0.4 / Zp);
1904  Double_t q = 1428. - 1206.*pow(x, 0.5) + 690 * x + pow(x, 6.);
1905  q = (Zp * (376.*x + pow(x, 6.))) / q;
1906  return q;
1907 }
1908 
1909 
1910 
1920 
1922 {
1923  // Return pointer to TF1 giving mean charge state of the projectile after passage through the target,
1924  // assuming that the equilibrium charge state distribution is achieved, as a function of projectile
1925  // energy after the target (in MeV/nucleon).
1926  // G. Shiwietz et al Nucl. Instr. and Meth. in Phys. Res. B 175-177 (2001) 125-131
1927  // This formula is valid for gas targets.
1928  //
1929  // By default the range of the function is [5,100] MeV/nucleon.
1930  // Change with TF1::SetRange.
1931 
1932  if (!fEqbmChargeStateShGas) {
1933  TString name = GetNucleus(1)->GetSymbol();
1934  name += " + ";
1935  name += GetNucleus(2)->GetSymbol();
1936  name += " SHIWIETZ-GAS";
1937  fEqbmChargeStateShGas = new TF1(name.Data(),
1938  const_cast<KV2Body*>(this), &KV2Body::eqbm_charge_state_shiwietz_gas, 5, 100, 0, "KV2Body", "eqbm_charge_state_shiwietz_gas");
1940  }
1941  return fEqbmChargeStateShGas;
1942 }
1943 
1944 
1945 
1946 
1951 
1952 TF1* KV2Body::GetXSecRuthLabFunc(Int_t OfNucleus, Double_t theta_min, Double_t theta_max) const
1953 {
1954  // Return pointer to TF1 giving Rutherford cross-section (b/sr) in the Lab as a
1955  // function of projectile (OfNucleus=3) or target (OfNucleus=4) lab scattering angle
1956  // By default, theta_min = 1 degree & theta_max = 179 degrees
1957 
1958  if (theta_max > GetMaxAngleLab(OfNucleus)) {
1959  theta_max = GetMaxAngleLab(OfNucleus);
1960  Info("GetXSecRuthLabFunc", "Maximum angle set to %lf degrees", theta_max);
1961  }
1962 
1963  TString name = "RuthXSec: ";
1964  name += GetNucleus(1)->GetSymbol();
1965  name += " + ";
1966  name += GetNucleus(2)->GetSymbol();
1967  name += " ";
1968  Double_t elab = GetNucleus(1)->GetEnergy() / GetNucleus(1)->GetA();
1969  name += Form("%6.1f AMeV ", elab);
1970  if (OfNucleus == 3) name += "(projectile)";
1971  else name += "(target)";
1972  TF1* fXSecRuthLab = (TF1*)gROOT->GetListOfFunctions()->FindObject(name.Data());
1973  if (!fXSecRuthLab) {
1974  fXSecRuthLab = new TF1(name.Data(),
1975  const_cast<KV2Body*>(this), &KV2Body::XSecRuthLab, theta_min, theta_max, 1, "KV2Body", "XSecRuthLab");
1976  fXSecRuthLab->SetParameter(0, OfNucleus);
1977  fXSecRuthLab->SetNpx(1000);
1978  }
1979  fXSecRuthLab->SetRange(theta_min, theta_max); //in case TF1 already exists, but new range is required
1980  return fXSecRuthLab;
1981 }
1982 
1983 
1984 
1997 
1998 TF1* KV2Body::GetXSecRuthLabIntegralFunc(Int_t OfNucleus, Double_t theta_min, Double_t theta_max) const
1999 {
2000  // Return pointer to TF1 giving Rutherford cross-section (b/sr) in the Lab as a
2001  // function of projectile (OfNucleus=3) or target (OfNucleus=4) lab scattering angle
2002  //
2003  // This function is equal to sin(theta)*dsigma/domega, i.e. it is the integrand
2004  // needed for calculating total cross-sections integrated over solid angle.
2005  //
2006  // WARNING: when integrating this function using TF1::Integral, the result must
2007  // be multiplied by TMath::DegToRad(), because 'x' is in degrees rather than radians,
2008  // e.g. the integrated cross-section in barns is given by
2009  //
2010  // GetXSecRuthLabIntegralFunc(OfNucleus)->Integral(theta_min, theta_max)*TMath::DegToRad()
2011 
2012  TString name = "RuthXSecInt: ";
2013  name += GetNucleus(1)->GetSymbol();
2014  name += " + ";
2015  name += GetNucleus(2)->GetSymbol();
2016  name += " ";
2017  Double_t elab = GetNucleus(1)->GetEnergy() / GetNucleus(1)->GetA();
2018  name += Form("%6.1f AMeV ", elab);
2019  if (OfNucleus == 3) name += "(projectile)";
2020  else name += "(target)";
2021 
2022  TF1* fXSecRuthLab = (TF1*)gROOT->GetListOfFunctions()->FindObject(name.Data());
2023  if (!fXSecRuthLab) {
2024  fXSecRuthLab = new TF1(name.Data(),
2025  const_cast<KV2Body*>(this), &KV2Body::XSecRuthLabInt, theta_min, theta_max, 1, "KV2Body", "XSecRuthLabInt");
2026  fXSecRuthLab->SetParameter(0, OfNucleus);
2027  fXSecRuthLab->SetNpx(1000);
2028  }
2029  fXSecRuthLab->SetRange(theta_min, theta_max); //in case TF1 already exists, but new range is required
2030  return fXSecRuthLab;
2031 }
2032 
2033 
2034 
2035 
2045 
2046 Int_t KV2Body::FindRoots(TF1* fonc, Double_t xmin, Double_t xmax, Double_t val, Double_t& x1, Double_t& x2) const
2047 {
2048  // Find at most two solutions x1 and x2 between xmin and xmax for which fonc->Eval(x) = val
2049  // i.e. we use TF1::GetX for a function which may be (at most) double-valued in range (xmin, xmax)
2050  // This is adapted to the case of the lab angle vs. CM angle of scattered particles.
2051  // if fonc has a maximum between xmin and xmax, and if val < max, we look for x1 between
2052  // xmin and the maximum, and x2 between the maximum and xmax.
2053  // If not (single-valued function) we look for x1 between xmin and xmax.
2054  // This method returns the number of roots found.
2055  // If val > maximum of fonc between xmin and xmax, there is no solution: we return 0.
2056 
2057  x1 = x2 = xmin - 1.;
2058  Double_t max = fonc->GetMaximum(xmin, xmax);
2059  Int_t nRoots = 0;
2060  if (val > max) return nRoots;
2061  Double_t maxX = fonc->GetMaximumX(xmin, xmax);
2062  nRoots = 1;
2063  if (TMath::AreEqualAbs(val, max, 1.e-10)) {
2064  // value corresponds to maximum of function
2065  x1 = maxX;
2066  return nRoots;
2067  }
2068  // 2 roots if 'fonc' has a maximum xmin<maxX<xmax and if fonc(xmin)<val && fonc(xmax)<val
2069  if ((maxX < xmax) && (maxX > xmin) && (fonc->Eval(xmin) < val) && (fonc->Eval(xmax) < val)) nRoots = 2;
2070  Double_t xmax1 = (nRoots == 2 ? maxX : xmax);
2071  x1 = fonc->GetX(val, xmin, xmax1);
2072  if (nRoots == 1) return nRoots;
2073  else
2074  x2 = fonc->GetX(val, maxX, xmax);
2075  return nRoots;
2076 }
2077 
2078 
int Int_t
#define f(i)
#define c(i)
#define e(i)
char Char_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
#define X(type, name)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
char name[80]
float xmin
float * q
float xmax
#define gROOT
char * Form(const char *fmt,...)
Relativistic binary kinematics calculator.
Definition: KV2Body.h:168
Double_t XSecRuthLabInt(Double_t *, Double_t *)
Definition: KV2Body.cpp:1435
Double_t TETAMIN[5]
defined only for nuclei 3 et 4
Definition: KV2Body.h:183
Double_t eqbm_charge_state_shiwietz_gas(Double_t *t, Double_t *)
Definition: KV2Body.cpp:1889
Double_t VC[5]
cm velocities
Definition: KV2Body.h:179
void SetTarget(const KVNucleus &)
Set target for reaction.
Definition: KV2Body.cpp:314
TF1 * GetEqbmChargeStateFunc() const
Definition: KV2Body.cpp:1800
TString GetReactionEquation() const
Definition: KV2Body.cpp:799
void Set4thNucleus()
Definition: KV2Body.cpp:422
TF1 * fELabVsThetaLab[5]
Definition: KV2Body.h:201
TF1 * GetXSecRuthLabFunc(Int_t OfNucleus=3, Double_t theta_min=1., Double_t theta_max=179.) const
Definition: KV2Body.cpp:1952
Double_t K[5]
ratio of c.m. velocity to velocity of nucleus in c.m. v_cm/v_i_cm
Definition: KV2Body.h:181
Double_t GetMaxAngleLab(Int_t i) const
Definition: KV2Body.cpp:536
std::vector< KVNucleus > fNuclei
nuclei involved in calculation
Definition: KV2Body.h:170
TF1 * GetXSecRuthLabIntegralFunc(Int_t OfNucleus=3, Double_t theta_min=1., Double_t theta_max=179.) const
Definition: KV2Body.cpp:1998
Double_t WCT
total cm energy
Definition: KV2Body.h:176
Double_t GetSphereDureReactionXSec(Double_t r0=1.05)
Definition: KV2Body.cpp:1630
Double_t ELabVsThetaLab(Double_t *, Double_t *)
Function calculating lab energy of nucleus par[0] for any lab angle x[0].
Definition: KV2Body.cpp:1034
TF1 * fThetaLabVsThetaCM[5]
Definition: KV2Body.h:199
Double_t GetMinAngleLab(Int_t i) const
Definition: KV2Body.cpp:554
Double_t GetThetaLab(Double_t ThetaCM, Int_t OfNucleus) const
Definition: KV2Body.h:289
void SetProjectile(const KVNucleus &)
Set projectile for reaction.
Definition: KV2Body.cpp:339
Double_t fIntPrec
Precision of the TF1::Integral method.
Definition: KV2Body.h:209
Double_t GetXSecRuthLab(Double_t ThetaLab_Proj, Int_t OfNucleus=3) const
Definition: KV2Body.cpp:1381
Double_t GetQReaction() const
Calculate Q-value for reaction, including dissipated (excitation) energy.
Definition: KV2Body.cpp:480
TF1 * fEqbmChargeStateShSol
function equilibrium charge state of projectile vs. E/A projectile (Shiwietz et al solid)
Definition: KV2Body.h:187
Double_t EqbmChargeState(Double_t *t, Double_t *)
Definition: KV2Body.cpp:1737
TF1 * GetThetaLabVsThetaCMFunc(Int_t OfNucleus) const
Definition: KV2Body.cpp:1194
void SetOutgoing(const KVNucleus &proj_out)
Definition: KV2Body.cpp:397
TF1 * fKoxReactionXSec
function Kox reaction cross-section [barns] vs. E/A projectile
Definition: KV2Body.h:185
TF1 * GetELabVsThetaCMFunc(Int_t OfNucleus) const
Definition: KV2Body.cpp:1089
Double_t XSecRuthCM(Double_t *, Double_t *)
Definition: KV2Body.cpp:1238
TF1 * GetShiwietzEqbmChargeStateFuncForGasTargets() const
Definition: KV2Body.cpp:1921
Double_t XSecRuthLab(Double_t *, Double_t *)
Definition: KV2Body.cpp:1402
TF1 * GetKoxReactionXSecFunc() const
Definition: KV2Body.cpp:1689
Double_t BCM
beta of centre of mass
Definition: KV2Body.h:174
TF1 * fEqbmChargeStateShGas
function equilibrium charge state of projectile vs. E/A projectile (Shiwietz et al gas)
Definition: KV2Body.h:188
Double_t GetELab(Double_t ThetaCM, Int_t OfNucleus) const
Definition: KV2Body.h:294
Int_t FindRoots(TF1 *, Double_t, Double_t, Double_t, Double_t &, Double_t &) const
Definition: KV2Body.cpp:2046
Double_t GetEDiss() const
Definition: KV2Body.h:254
static Double_t GetVelocity(Double_t mass, Double_t E)
Definition: KV2Body.cpp:380
Double_t GetIntegratedXSecRuthLab(Float_t th1, Float_t th2, Float_t phi1=-1, Float_t phi2=-1, Int_t OfNucleus=3)
Definition: KV2Body.cpp:1489
Double_t GetBmaxFromReactionXSec(Double_t ReacXsec)
Definition: KV2Body.cpp:1651
TVector3 VCM
velocity of centre of mass
Definition: KV2Body.h:173
Double_t KoxReactionXSec(Double_t *, Double_t *)
Definition: KV2Body.cpp:1592
Double_t ELabVsThetaCM(Double_t *, Double_t *)
Function calculating lab energy of nucleus par[0] for any CM angle x[0].
Definition: KV2Body.cpp:1051
Double_t ThetaLabVsThetaCM(Double_t *, Double_t *)
Definition: KV2Body.cpp:1070
Double_t GetCMGamma() const
Definition: KV2Body.h:272
Double_t TETAMAX[5]
defined only for nuclei 3 et 4
Definition: KV2Body.h:182
Bool_t fSetOutgoing
= kTRUE if SetOutgoing is called before CalculateKinematics
Definition: KV2Body.h:206
Double_t WC[5]
cm energy of each nucleus
Definition: KV2Body.h:177
KVDrawable< TGraph > GraphELabVsThetaLab(int ofNuc=3, int npoints=50) const
Definition: KV2Body.cpp:1312
Double_t EC[5]
cm energies
Definition: KV2Body.h:180
Double_t GetExcitEnergy() const
Definition: KV2Body.h:244
Double_t GetMinThetaCMFromThetaLab(Int_t OfNucleus, Double_t theta, Int_t OtherNucleus) const
Definition: KV2Body.cpp:1269
Double_t WLT
total lab energy
Definition: KV2Body.h:175
Int_t GetVLab(Int_t OfNucleus, Double_t ThetaLab, Int_t AngleNucleus, Double_t &e1, Double_t &e2) const
Definition: KV2Body.cpp:1133
TF1 * fXSecRuthLab[5]
Definition: KV2Body.h:204
Double_t BassIntBarrier()
Definition: KV2Body.cpp:1565
TVector3 GetCMVelocity() const
Return vector velocity of centre of mass of reaction (units: cm/ns)
Definition: KV2Body.cpp:572
void CalculateKinematics()
Definition: KV2Body.cpp:677
void Print(Option_t *opt="") const override
Definition: KV2Body.cpp:858
void init()
Default initialisations.
Definition: KV2Body.cpp:32
KV2Body()
default ctor
Definition: KV2Body.cpp:61
Double_t GetIntegratedXsec(Double_t b1, Double_t b2)
Definition: KV2Body.cpp:1670
TF1 * GetXSecRuthCMFunc(Int_t OfNucleus=3, Double_t theta_cm_min=1., Double_t theta_cm_max=179.) const
Definition: KV2Body.cpp:1530
Double_t GetLabGrazingAngle(Int_t i=1) const
Definition: KV2Body.cpp:603
Double_t GetQGroundStates() const
Calculate Q-value for reaction, assuming all nuclei in ground state.
Definition: KV2Body.cpp:499
KVNucleus * GetNucleus(Int_t i) const
Definition: KV2Body.cpp:456
Double_t XSecRuthCMVsThetaCM(Double_t *, Double_t *)
Definition: KV2Body.cpp:1353
Double_t GetCMEnergy() const
Return available kinetic energy in centre of mass.
Definition: KV2Body.cpp:522
TF1 * fEqbmChargeState
function equilibrium charge state of projectile vs. E/A projectile (Leon et al)
Definition: KV2Body.h:186
Double_t eqbm_charge_state_shiwietz_solid(Double_t *t, Double_t *)
Definition: KV2Body.cpp:1829
Double_t GetXSecRuthCM(Double_t ThetaLab_Proj, Int_t OfNucleus=3) const
Definition: KV2Body.cpp:1217
Double_t fEDiss
dissipated energy, 0 means elastic scattering
Definition: KV2Body.h:171
TF1 * fELabVsThetaCM[5]
Definition: KV2Body.h:200
Int_t GetThetaCM(Double_t ThetaLab, Int_t OfNucleus, Double_t &t1, Double_t &t2) const
Definition: KV2Body.cpp:1017
TF1 * GetShiwietzEqbmChargeStateFuncForSolidTargets() const
Definition: KV2Body.cpp:1860
TF1 * GetELabVsThetaLabFunc(Int_t OfNucleus) const
Definition: KV2Body.cpp:1109
void Error(const char *method, const char *msgfmt,...) const override
Definition: KVBase.cpp:1674
void Warning(const char *method, const char *msgfmt,...) const override
Definition: KVBase.cpp:1661
Simple wrapper for objects which can be drawn (graphs, histograms)
Definition: KVDrawable.h:29
Utility class for kinematical transformations of KVParticle class.
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:123
const Char_t * GetSymbol(Option_t *opt="") const
Definition: KVNucleus.cpp:71
Double_t GetExcitEnergy() const
Definition: KVNucleus.h:279
Double_t GetMassExcess(Int_t z=-1, Int_t a=-1) const
Definition: KVNucleus.cpp:880
Bool_t IsDefined() const
Definition: KVNucleus.h:198
Int_t GetA() const
Definition: KVNucleus.cpp:796
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:767
TVector3 GetMomentum() const
Definition: KVParticle.h:607
Double_t GetEnergy() const
Definition: KVParticle.h:624
static Double_t C()
Definition: KVParticle.cpp:117
Double_t GetKE() const
Definition: KVParticle.h:617
void SetFrame(const Char_t *frame, const KVFrameTransform &)
Definition: KVParticle.cpp:775
KVParticle const * GetFrame(const Char_t *frame, Bool_t warn_and_return_null_if_unknown=kTRUE) const
Definition: KVParticle.cpp:897
TVector3 GetV() const
Definition: KVParticle.h:674
void SetEnergy(Double_t e)
Definition: KVParticle.h:602
Double_t GetMass() const
Definition: KVParticle.h:577
TVector3 GetVelocity() const
returns velocity vector in cm/ns units
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Begin(TString delim) const
Definition: KVString.cpp:565
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
virtual void SetRange(Double_t xmin, Double_t xmax)
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
virtual void SetNpx(Int_t npx=100)
virtual Double_t GetX(Double_t y, Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
virtual Double_t GetMaximum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual void SetParameter(const TString &name, Double_t value)
virtual Double_t GetMaximumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual void AddPoint(Double_t x, Double_t y)
void SetTitle(const char *title="") override
Double_t Beta() const
Double_t E() const
virtual void SetTitle(const char *title="")
R__ALWAYS_INLINE Bool_t IsZombie() const
void MakeZombie()
virtual void Info(const char *method, const char *msgfmt,...) const
void Obsolete(const char *method, const char *asOfVers, const char *removedFromVers) const
Double_t Atof() const
TString & Append(char c, Ssiz_t rep=1)
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
void SetXYZ(Double_t x, Double_t y, Double_t z)
Double_t Mag() const
void compound()
double beta(double x, double y)
T Mag(const SVector< T, D > &rhs)
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
Double_t x[n]
TGraphErrors * gr
double max(double x, double y)
Double_t Min(Double_t a, Double_t b)
constexpr Double_t C()
Double_t ASin(Double_t)
Double_t Exp(Double_t x)
Double_t ATan(Double_t)
constexpr Double_t K()
Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE)
constexpr Double_t PiOver2()
Double_t ATan2(Double_t y, Double_t x)
Double_t Power(Double_t x, Double_t y)
constexpr Double_t E()
constexpr Double_t DegToRad()
Double_t Sqrt(Double_t x)
Double_t Cos(Double_t)
constexpr Double_t Pi()
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Double_t Abs(Double_t d)
Double_t Sin(Double_t)
constexpr Double_t RadToDeg()
Double_t Log10(Double_t x)
v2
v1
auto * th2
auto * th1
TArc a
auto * t1
ClassImp(TPyArg)