KaliVeda
Toolkit for HIC analysis
KVNucleus.cpp
1 /***************************************************************************
2 $Id: KVNucleus.cpp,v 1.48 2009/04/02 09:32:55 ebonnet Exp $
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 2 of the License, or *
7  * (at your option) any later version. *
8  * *
9  ***************************************************************************/
10 
11 #include "KVNucleus.h"
12 #include "KVString.h"
13 #include <KVBase.h>
14 #include "tkmanager.h"
15 
16 //Atomic mass unit in MeV
17 //Reference: 2002 CODATA recommended values Reviews of Modern Physics 77, 1-107 (2005)
18 Double_t KVNucleus::kAMU = 9.31494043e02;
19 Double_t KVNucleus::kMe = 0.510998;
20 // hbar*c in MeV.fm = 197.33....
22 // e^2/(4.pi.epsilon_0) in MeV.fm = 1.44... = hbar*alpha (fine structure constant)
23 Double_t KVNucleus::e2 = KVNucleus::hbar / 137.035999074;
24 
25 std::mutex _kvnucleus_mutex;
26 
27 using namespace std;
28 
30 
31 
32 
43 const Char_t* KVNucleus::GetSymbol(Option_t* opt) const
44 {
45  // \returns symbol of isotope corresponding to this nucleus,
46  // i.e. "238U", "12C", "3He" etc.
47  //
48  // Neutrons are represented by "n".
49  //
50  // In order to have just the symbol of the chemical element
51  // (e.g. "Pt", "Zn", "Fe"), call with opt="el" or opt="EL"
52  //
53  // \returns empty string if symbol is not known
54 
55  TString _opt(opt);
56  _opt.ToUpper();
57  auto Mpfx = _opt!="EL"; // kTRUE if mass prefix required
58 
59  fSymbolName = "";
60 
61  if(GetTkNucleus().is_known())
62  {
63  if(Mpfx)
64  fSymbolName = GetTkNucleus().get_symbol().c_str();
65  else
66  fSymbolName = GetTkNucleus().get_element_symbol().c_str();
67  }
68  else if(!gmanager->get_element_symbol(GetZ()).empty())
69  {
70  auto symbol = gmanager->get_element_symbol(GetZ());
71  if(Mpfx)
72  symbol.prepend(tkn::tkstring::form("%d", GetA()));
73  fSymbolName = symbol.c_str();
74  }
75  return fSymbolName;
76 }
77 
78 
96 
98 {
99  // Returns symbol of isotope corresponding to this nucleus,
100  // suitable for latex format in ROOT TLatex type class
101  // i.e.
102  //~~~
103  //"^{238}U", "^{12}C", "^{3}He"
104  //~~~
105  // etc.
106  //
107  // Neutrons are represented by "^{1}n".
108  //
109  // In order to have also the charge printed like this : ^{12}_{6}C
110  // call with opt="ALL" or opt="all"
111  //
112  // if you need only the chemical symbol, set opt="EL" or opt="el"
113  //
114  // \returns empty string if symbol is not known
115 
116  Int_t a = GetA();
117  Int_t z = GetZ();
118  TString _opt(opt);
119  _opt.ToUpper();
120  auto with_charge = _opt=="ALL";
121  auto just_symbol = _opt=="EL";
122 
123  TString symbol = GetSymbol("el");
124  if(!symbol.IsNull())
125  {
126  if (with_charge)
127  fSymbolName.Form("{}^{%d}_{%d}%s", a, z, symbol.Data());
128  else if (!just_symbol)
129  fSymbolName.Form("^{%d}%s", a, symbol.Data());
130  }
131  else {
132  fSymbolName = "";
133  }
134  return fSymbolName;
135 }
136 
137 
138 
148 
150 {
151  // test if the given string corresponds to the name of an isotope/element,
152  // and whether or not a mass is specified.
153  //
154  // isotope = symbol for element isotope, "C", "natSn", "13N", etc.
155  //
156  // - if the mass of the isotope is given ("13N", "233U") we return the given mass
157  // - if this is a valid element but no mass is given we return 0
158  // - if this is not a valid isotope/element, we return -1
159 
160  Int_t A;
161  Char_t name[5];
162  TString tmp(isotope);
163  if (tmp.BeginsWith("nat"))
164  tmp.Remove(0, 3);
165  if (sscanf(tmp.Data(), "%d%s", &A, name) == 2) {
166  //name given in form "208Pb"
167  Int_t z = GetZFromSymbol(name);
168  if (z < 0) return z;
169  return A;
170  }
171  Int_t z = GetZFromSymbol(tmp);
172  if (z < 0) return z;
173  return 0;
174 }
175 
176 
177 
183 
184 void KVNucleus::Set(const Char_t* isotope)
185 {
186  // Set nucleus' Z & A using chemical symbol e.g. Set("12C") or Set("233U") etc.
187  //
188  // Any failure to deduce Z from the symbol will result in this object being made
189  // a zombie i.e. IsZombie() will return kTRUE
190 
191  Int_t A;
192  Char_t name[255];
193  TString tmp(isotope);
194  if (tmp.BeginsWith("nat"))
195  tmp.Remove(0, 3);
196  if (sscanf(tmp.Data(), "%d%s", &A, name) == 2) {
197  //name given in form "208Pb"
198  if (SetZFromSymbol(name) > -1) SetA(A);
199  else MakeZombie();
200  }
201  else if (sscanf(tmp.Data(), "%s", name) == 1) {
202  //name given in form "Pb"
203  if (SetZFromSymbol(name) == -1) MakeZombie();
204  }
205 }
206 
207 
208 
212 
214 {
215  //Returns Z of nucleus with given symbol i.e. "C" => Z=6, "U" => Z=92
216  //if unknown, returns -1
217 
218  auto tknuc = tkn::tknucleus(sym);
219  if(tknuc.is_known())
220  return tknuc.get_z();
221  return -1;
222 }
223 
224 
225 
230 
232 {
233  // Set Z of nucleus with given symbol i.e. "C" => Z=6, "U" => Z=92
234  //
235  // Returns Z found, or -1 if symbol is unknown
236 
237  Int_t z = GetZFromSymbol(sym);
238  if (z > -1) SetZ(z);
239  else KVError::Error(this, "SetZFromSymbol", "%s is unknown", sym);
240  return z;
241 }
242 
243 
244 
245 
250 
252 {
253  // Default intialisations
254  // The mass formula is kBetaMass, i.e. the formula for the valley of beta-stability.
255  // Set up nuclear data table manager if not done already
256 
257  fZ = fA = 0;
258  KVBase::InitEnvironment(); // initialise environment i.e. read .kvrootrc
259  fMassFormula = kBetaMass;
260 }
261 
262 
263 
268 
270 {
271  //
272  //Default constructor.
273  //
274 
275  init();
276 }
277 
278 
279 
282 
284 {
285  //copy ctor
286  init();
287  obj.Copy(*this);
288 }
289 
290 
291 
295 
297 {
298  // Reset nucleus' properties: set A and Z to zero.
299  // For other properties, see KVParticle::Clear
300 
301  KVParticle::Clear(opt);
302  ResetBit(kIsHeavy);
303  fZ = fA = 0;
304 }
305 
306 
307 
315 
317 {
318  //Create a nucleus with atomic number Z.
319  //
320  //If the mass number A is not given, A is calculated using the
321  //parametrisation determined by the value of fMassFormula (see KVNucleus::GetAFromZ).
322  //
323  //ekin is the kinetic energy in MeV
324 
325  init();
326  fZ = (UChar_t) z;
327  if (z != 0 && a == 0) {
328  SetA(GetAFromZ(z, fMassFormula));
329  }
330  else {
331  SetA(a);
332  }
333  SetKE(ekin);
334 }
335 
336 
337 
344 
345 KVNucleus::KVNucleus(const Char_t* symbol, Double_t EperA)
346 {
347  // Create a nucleus defined by symbol e.g. "12C", "34Mg", "42Si" etc. etc.
348  //
349  // If symbol is not valid, will be made a zombie (IsZombie() returns kTRUE)
350  //
351  // The second argument is the kinetic energy per nucleon (E/A) in MeV/A unit
352 
353  init();
354  Set(symbol);
355  if (!IsZombie()) SetKE(EperA * GetA());
356 }
357 
358 
359 
366 
368 {
369 
370  //Create nucleus with given Z, kinetic energy t and direction p
371  //(p is a unit vector in the desired direction. See KVPosition for methods
372  //for generating such vectors).
373  //The mass number A is calculated from Z. See KVNucleus::GetAFromZ.
374  //
375  init();
376  fZ = (UChar_t) z;
377  SetA(GetAFromZ(z, fMassFormula));
378  SetMomentum(t, p);
379 }
380 
381 
382 
387 
389 {
390  //
391  //Create nucleus with given Z, A, and 3-momentum p
392  //
393  init();
394  fZ = (UChar_t) z;
395  SetA(a);
396  SetMomentum(p);
397 }
398 
399 
400 
402 
403 KVNucleus::~KVNucleus()
404 {
405  fZ = fA = 0;
406 }
407 
408 
409 
410 
444 
446 {
447  //Calculate nuclear mass number from the element's atomic number Z.
448  //This value is not rounded off, we just return the result of one of the following formulae:
449  //
450  //mt = KVNucleus::kVedaMass
451  //__________________________
452  //Veda - A calculated using the formula
453  // fA = (1.867*fZ+.016*fZ*fZ-1.07E-4*fZ*fZ*fZ);
454  // This corresponds to the amass.f subroutine of the old INDRA Veda
455  // calibration programme. This formula was supposed to represent
456  // the Z-dependence of isotope masses in the beta-stability valley,
457  // but is in fact a rather poor approximation, especially for large Z.
458  //
459  //mt = KVNucleus::kBetaMass
460  //_________________________
461  //Beta (default) - An improved parametrisation of the beta-stability valley,
462  // correct even for heavy nuclei up to 238U. The formula is the result
463  // of a fit to 8 stable nuclear masses from Ne20 up to U238.
464  // fA = (.2875 + 1.7622 *Z + .013879 * Z * Z - .000054875 * Z * Z * Z);
465  //
466  //mt = KVNucleus::kEALMass
467  //________________________
468  //EAL - parametrisation of the Evaporation Attractor Line (residue corridor)
469  // due to R.J. Charity (PRC 58(1998)1073) (eq 2)
470  // fA = (2.072*Z + 2.32E-03 * Z*Z) ;
471  //
472  //mt = KVNucleus::kEALResMass
473  //________________________
474  //EALRes - R.J. Charity ---- improvement of EAL parametrisation for
475  // Heavy Residue (QP for instance) (PRC 58(1998)1073) (eq 7)
476  // fA = (2.045*Z + 3.57E-03 * Z*Z) ;
477  //
478  //mt = any other value: A=2*Z
479 
480  Double_t A;
481  switch (mt) {
482 
483  case kVedaMass:
484  A = (1.867 * Z + .016 * TMath::Power(Z, 2.) -
485  1.07E-4 * TMath::Power(Z, 3.));
486  break;
487 
488  case kBetaMass:
489  A = (.2875 + 1.7622 * Z + .013879 * TMath::Power(Z, 2.) -
490  .000054875 * TMath::Power(Z, 3.));
491  break;
492 
493  case kEALMass:
494  A = (2.072 * Z + 2.32E-03 * TMath::Power(Z, 2.));
495  break;
496 
497  case kEALResMass:
498  A = (2.045 * Z + 3.57E-03 * TMath::Power(Z, 2.));
499  break;
500 
501  default:
502  A = 2. * Z;
503  }
504 
505  return A;
506 }
507 
508 
509 
514 
516 {
517  //Calculate neutron number from the element's atomic number Z.
518  //This value is not rounded off, we just return the result
519  //obtain from the chosen mass formula (mt)
520  return GetRealAFromZ(Z, mt) - Z;
521 
522 }
523 
524 
564 
566 {
567  //Calculate nuclear mass number from the element's atomic number Z.
568  //Used by default to set fA and fMass if fA not given.
569  //For light nuclei (Z<6) the values are given (not calculated) and
570  //correspond to: p, alpha, 7Li, 9Be, 11B.
571  //For heavier nuclei, several prescriptions are available
572  //by giving one of the following values to argument mt:
573  //
574  //mt = KVNucleus::kVedaMass
575  //__________________________
576  //Veda - A calculated using the formula
577  // fA = TMath::Nint(1.867*fZ+.016*fZ*fZ-1.07E-4*fZ*fZ*fZ);
578  // This corresponds to the amass.f subroutine of the old INDRA Veda
579  // calibration programme. These are the masses used in the first
580  // INDRA campaigns.
581  // For light nuclei (Z<6) the values are given (not calculated) and
582  // correspond to: p, alpha, 6Li, 8Be, 10B.
583  //
584  //mt = KVNucleus::kBetaMass
585  //_________________________
586  //Beta (default) - An improved parametrisation of the beta-stability valley,
587  // correct even for heavy nuclei up to 238U. The formula is the result
588  // of a fit to 8 stable nuclear masses from Ne20 up to U238. From carbon-12 onwards,
589  // the mass is calculated using
590  // fA = (Int_t) (.2875 + 1.7622 *Z + .013879 * Z * Z - .000054875 * Z * Z * Z) + 1;
591  //
592  //mt = KVNucleus::kEALMass
593  //________________________
594  //EAL - parametrisation of the Evaporation Attractor Line (residue corridor)
595  // due to R.J. Charity (PRC 58(1998)1073).
596  // fA = (Int_t)(2.072*Z + 2.32E-03 * Z*Z) + 1; (eq 2)
597  //
598  //mt = KVNucleus::kEALResMass
599  //________________________
600  //EALRes - R.J. Charity ---- improvement of EAL parametrisation for
601  // Heavy Residues (QP for instance) (PRC 58(1998)1073) (eq 7)
602  // fA = (Int_t)(2.045*Z + 3.57E-03 * Z*Z) + 1 ;
603  //
604  //mt = any other value: A=2*Z
605 
606  Int_t A = 0;
607  Int_t z = (Int_t) Z;
608  switch (z) { // masses for lightest nuclei
609  case 1:
610  A = 1;
611  break;
612  case 2:
613  A = 4;
614  break;
615  case 3:
616  A = (mt == kVedaMass ? 6 : 7);
617  break;
618  case 4:
619  A = (mt == kVedaMass ? 8 : 9);
620  break;
621  case 5:
622  A = (mt == kVedaMass ? 10 : 11);
623  break;
624  default:
625  if (mt == kVedaMass)
627  else
628  A = (Int_t) KVNucleus::GetRealAFromZ(Z, mt) + 1;
629  }
630  return A;
631 }
632 
633 
636 
638 {
639  //Calculate neutron number from the element's atomic number Z.
640  return GetAFromZ(Z, mt) - Int_t(Z);
641 
642 }
643 
644 
645 
657 
659 {
660  //Set mass number
661  //
662  //Be careful not to call SetZ() after SetA(), as SetZ() will
663  //reset the mass number according to one of the available
664  //parametrisations of A as a function of Z.
665  //
666  //For A>255 the kIsHeavy flag is set. Then fA will equal A-255,
667  //and GetA will return fA+255.
668  //
669  //If A<=255 the flag is reset.
670 
671  if (a > 255) {
672  fA = (UChar_t)(a - 255);
673  SetBit(kIsHeavy);
674  }
675  else {
676  fA = (UChar_t) a;
677  ResetBit(kIsHeavy);
678  }
679  SetMass(GetMassGS());
680 }
681 
682 
689 
691 {
692  //Set mass number
693  //Be careful not to call SetZ() after SetN(), as SetZ() will
694  //reset the neutron number according to one of the available
695  //parametrisations of A (N+Z) as a function of Z.
696  //
697  Int_t z = GetZ();
698  SetA(z + n);
699 }
700 
701 
702 
708 
710 {
711  //Set atomic number
712  //The mass number fA is automatically calculated and set using GetAFromZ().
713  //The optional EMassType argument allows to change the default parametrisation
714  //used for calculating A from Z.
715  fZ = (UChar_t) z;
716  if (mt > -1)
717  fMassFormula = mt;
718  SetA(GetAFromZ(z, fMassFormula));
719 }
720 
721 
722 
725 
727 {
728  //Set atomic number and mass number
729  SetZ(z);
730  SetA(a);
731 }
732 
733 
734 
737 
739 {
740  //Set atomic number, mass number, and kinetic energy in MeV
741  SetZ(z);
742  SetA(a);
743  SetKE(ekin);
744 }
745 
746 
747 
750 
752 {
753  //Set atomic number and mass number
754  SetZ(z);
755  SetN(n);
756 }
757 
758 
759 
762 
764 {
765  // Display nucleus parameters
766  cout << "Z=" << GetZ() << " A=" << GetA() << " ";
767  if (GetExcitEnergy() > 1.e-10) cout << "E*=" << GetExcitEnergy() << " ";
769 }
770 
771 
772 
775 
777 {
778  //Return the number of proton / atomic number
779  return (Int_t) fZ;
780 }
781 
782 
783 
786 
788 {
789  //Return the number of neutron
790  return (Int_t)(GetA() - GetZ());
791 }
792 
793 
794 
804 
806 {
807  //Returns mass number (A) of nucleus.
808  //
809  //The actual member variable (fA) is a UChar_t and so limited to values 0-255.
810  //In case nuclei with larger A are needed (for example in calculations of 2-body
811  //scattering, a temporary nucleus corresponding to the sum of the entrance channel
812  //nuclei is used in order to find the outgoing target-like from the outgoing
813  //projectile-like) the flag "kIsHeavy" is set and GetA returns the value (fA+255).
814  //For this reason you should always use GetA and not fA.
815 
816  if (TestBit(kIsHeavy))
817  return ((Int_t) fA + 255);
818  return (Int_t) fA;
819 }
820 
821 
823 
825 {
826 
827  if (type == kNN) return GetA() * (GetA() - 1) / 2;
828  else if (type == knn) return GetN() * (GetN() - 1) / 2;
829  else if (type == kpp) return GetZ() * (GetZ() - 1) / 2;
830  else if (type == knp) return GetZ() * GetN();
831  else return 0;
832 }
833 
834 
835 
838 
839 void KVNucleus::Copy(TObject& obj) const
840 {
841  //Copy this KVNucleus into the KVNucleus object referenced by "obj"
842  KVParticle::Copy(obj);
843  ((KVNucleus&) obj).SetZ(GetZ());
844  ((KVNucleus&) obj).SetMassFormula(fMassFormula);
845  ((KVNucleus&) obj).SetA(((KVNucleus*) this)->GetA());
846  ((KVNucleus&) obj).SetExcitEnergy(((KVNucleus*) this)->
847  GetExcitEnergy());
848 }
849 
850 
851 
853 
854 void KVNucleus::CheckZAndA(std::optional<Int_t> &z, std::optional<Int_t> &a) const
855 {
856  if (!z) z = GetZ();
857  if (!a) a = GetA();
858 }
859 
860 
861 
866 
868 {
869  // Define excitation energy of nucleus in MeV.
870  //
871  // The rest mass of the nucleus is changed: m0 -> m0 + E*
872 
873  SetMass(GetMassGS() + ex);
874 }
875 
876 
877 
880 
881 tkn::tknucleus KVNucleus::GetTkNucleus(std::optional<int> z, std::optional<int> a) const
882 {
883  // \returns the equivalent TkN nucleus for isotope, giving access to all available properties
884  CheckZAndA(z,a);
885  // the first time this method is called, we inhibit TkN warnings to
886  // avoid printing many warnings about unknown nuclei (mainly for heavy compound nuclei, e.g. 248Rf)
887  static bool first_call = true;
888  if(first_call)
889  {
890  glog.set_warnings(false);
891  first_call = false;
892  }
893  return tkn::tknucleus(*z,*a);
894 }
895 
896 
897 
898 
910 
911 Double_t KVNucleus::GetMassExcess(std::optional<int> z, std::optional<int> a) const
912 {
913  //Returns mass excess value in MeV for this nucleus.
914  //
915  //If optional arguments (z,a) are given we return the value for the
916  //required nucleus.
917  //
918  //If the nucleus is not included in the mass table, an extrapolated value
919  //using KVNucleus::LiquidDrop_BrackGuet is returned.
920  //
921  //\note This mass excess is for a fully-stripped ion i.e. it has the mass of \f$Z\f$
922  // electrons (Z*KVNucleus::kMe) removed from it.
923 
924  CheckZAndA(z, a);
925  auto nuc = GetTkNucleus(z,a);
926  Double_t val = -555;
927  if(nuc.has_property("mass_excess"))
928  val = nuc.get_mass_excess()/1000.;
929  if (val == -555) val = GetExtraMassExcess(z, a);
930  else {
931  // subtract electron mass from experimental atomic mass
932  val -= *z * kMe;
933  }
934  return val;
935 }
936 
937 
938 
945 
946 Double_t KVNucleus::GetExtraMassExcess(std::optional<int> z, std::optional<int> a) const
947 {
948  //Calculate the extrapoled mass excess value
949  // from the LiquidDrop_BrackGuet formula
950  //
951  //If optional arguments (z,a) are given we return the value for the
952  //required nucleus.
953 
954  CheckZAndA(z, a);
955  return (LiquidDrop_BrackGuet(*a, *z) - *a * kAMU);
956 
957 }
958 
959 
960 
970 
971 Double_t KVNucleus::GetAtomicMass(std::optional<int> z, std::optional<int> a) const
972 {
973  // Returns the mass of an isotope in unified atomic mass units
974  // (KVNucleus::u() MeV/c**2)
975  //
976  // This number is also the mass in grammes of 1 mole of this isotope.
977  //
978  //\note This is the mass of fully-stripped ions i.e. it has the mass of \f$Z\f$
979  // electrons (Z*KVNucleus::kMe) removed from it. GetAtomicMass(1,1)
980  // therefore returns the mass of the proton, not the mass of the Hydrogen atom.
981 
982  CheckZAndA(z, a);
983  return *a + GetMassExcess(z, a) / u();
984 }
985 
986 
987 
993 
994 std::optional<double> KVNucleus::GetSpin(std::optional<int> z, std::optional<int> a) const
995 {
996  //\returns ground state spin for this nucleus, if known
997  //
998  //If optional arguments (z,a) are given we return the value for the
999  //required nucleus.
1000 
1001  auto nuc = GetTkNucleus(z,a);
1002  if(nuc.has_property("spin_parity"))
1003  return nuc.get_spin_parity().get_spin().get_value();
1004  return {};
1005 }
1006 
1007 
1008 
1009 
1015 
1016 std::optional<int> KVNucleus::GetParity(std::optional<int> z, std::optional<int> a) const
1017 {
1018  //\returns parity value (-1 or +1) for this nucleus, if known
1019  //
1020  //If optional arguments (z,a) are given we return the value for the
1021  //required nucleus.
1022 
1023  auto nuc = GetTkNucleus(z,a);
1024  if(nuc.has_property("spin_parity"))
1025  return nuc.get_spin_parity().get_parity().get_value();
1026  return {};
1027 }
1028 
1029 
1030 
1031 
1044 
1045 std::optional<double> KVNucleus::GetLifeTime(std::optional<int> z, std::optional<int> a) const
1046 {
1047  //\returns mean life time in seconds for unstable nuclei
1048  //
1049  //For resonances (IsResonance() returns kTRUE) we calculate the mean lifetime from the width of the resonance
1050  //\f[
1051  //\tau = \hbar/\Gamma
1052  //\f]
1053  //
1054  // Note that the half-life \f$t_{1/2}\f$ is related to this lifetime by \f$t_{1/2}=\ln(2)\tau\f$
1055  //
1056  //If optional arguments (z,a) are given we return the value for the
1057  //required nucleus.
1058 
1059  auto nuc = GetTkNucleus(z,a);
1060  if(nuc.is_stable())
1061  return 1.e+100;
1062  if(nuc.has_property("lifetime"))
1063  {
1064  if(IsResonance(z,a))
1065  return nuc.get_lifetime()/std::log(2);// TkN calculates half-life for resonances
1066  else
1067  return nuc.get_lifetime();
1068  }
1069  return {};
1070 }
1071 
1072 
1073 
1082 
1083 Double_t KVNucleus::GetChargeRadius(std::optional<int> z, std::optional<int> a) const
1084 {
1085  //\returns charge radius in fm for tabulated nuclei
1086  //
1087  //If not tabulated returns the extrapolated radius
1088  //calculate in GetExtraChargeRadius
1089  //
1090  //If optional arguments (z,a) are given we return the value for the
1091  //required nucleus.
1092 
1093  auto nuc = GetTkNucleus(z,a);
1094  if(nuc.has_property("radius"))
1095  return nuc.get_radius();
1096  return GetExtraChargeRadius(a);
1097 }
1098 
1099 
1100 
1101 
1119 
1120 Double_t KVNucleus::GetExtraChargeRadius(std::optional<int> a, Int_t rct) const
1121 {
1122  //Calculate the extrapoled charge radius
1123  // Three formulae taken from Atomic Data and Nuclear Data Tables 87 (2004) 185-201
1124  // are proposed:
1125  // rct=2 (kELTON)take into account the finite surfacethickness
1126  // This rct=2 is set by default because it has the best reproduction of exp data
1127  //
1128  // rct=1 (kEMPFunc) is a purely emperical function re*A**ee
1129  // rct=0 (kLDModel) is the standard Liquid Drop model approximation
1130  //
1131  // Those formulae are valid for nuclei near the stability valley
1132  // other parametrization for xotic nuclei are proposed in the same reference
1133  // but needed extrapolation from given nuclei and I don't have time
1134  // to do it now
1135  //
1136  // If optional arguments (z,a) are given we return the value for the
1137  // required nucleus.
1138 
1139  if(!a) a = GetA();
1140  Double_t R = 0;
1141  Double_t A = Double_t(*a);
1142 
1143  Double_t rLD = 0.9542; //for kLDModel
1144 
1145  Double_t re = 1.153; //for kEMPFunc
1146  Double_t ee = 0.2938; //for kEMPFunc
1147 
1148  Double_t r0 = 0.9071; //for kELTON
1149  Double_t r1 = 1.105;
1150  Double_t r2 = -0.548;
1151 
1152  switch (rct) {
1153 
1154  case kLDModel:
1155  R = rLD * TMath::Power(A, 1. / 3.);
1156  break;
1157 
1158  case kEMPFunc:
1159  R = re * TMath::Power(A, ee);
1160  break;
1161 
1162  case kELTON:
1163  R = (r0 * TMath::Power(A, 1. / 3.) + r1 / TMath::Power(A, 1. / 3.) + r2 / A);
1164  break;
1165 
1166  }
1167 
1168  return R;
1169 
1170 }
1171 
1172 
1173 
1178 
1179 std::optional<double> KVNucleus::GetAbundance(std::optional<int> z, std::optional<int> a) const
1180 {
1181  //Returns relative abundance value (see KVAbundance class for unit details).
1182  //If optional arguments (z,a) are given we return the value for the
1183  //required nucleus.
1184 
1185  auto nuc = GetTkNucleus(z,a);
1186  if(nuc.has_property("abundance"))
1187  return nuc.get_abundance();
1188  return {};
1189 }
1190 
1191 
1192 
1193 
1196 
1197 std::optional<int> KVNucleus::GetMostAbundantA(std::optional<int> z) const
1198 {
1199  //\returns for current nucleus or the given z the A of the most abundant isotope (if known)
1200 
1201  std::optional<int> amost;
1202  if (z == -1) z = GetZ();
1203  KVNumberList ll = GetKnownARange(z);
1204  ll.Begin();
1205  Double_t abmax = 0;
1206  while (!ll.End()) {
1207  Int_t a = ll.Next();
1208  auto abund = GetAbundance(z, a);
1209  if (abund && *abund > abmax) {
1210  abmax = *abund;
1211  amost = a;
1212  }
1213  }
1214  return amost;
1215 }
1216 
1217 
1218 
1221 
1222 Bool_t KVNucleus::IsKnown(std::optional<int> z, std::optional<int> a) const
1223 {
1224  //Returns kTRUE if this nucleus or (z,a) is known
1225 
1226  return GetTkNucleus(z,a).is_known();
1227 }
1228 
1229 
1230 
1231 
1242 
1243 Double_t KVNucleus::GetBindingEnergy(std::optional<int> z, std::optional<int> a) const
1244 {
1245  //Returns ground state binding energy in MeV for this nucleus.
1246  //
1247  //The convention is : binding energy is positive if nucleus is bound.
1248  //
1249  //If optional arguments (z,a) are given we return the binding energy for the
1250  //required nucleus.
1251  //
1252  //If the nucleus is not included in the mass table, an extrapolated value
1253  //using KVNucleus::LiquidDrop_BrackGuet is returned.
1254 
1255  CheckZAndA(z, a);
1256 
1257  return *a ==
1258  0 ? 0. : (*z * GetMassExcess(1, 1) + (*a - *z) * GetMassExcess(0, 1) -
1259  GetMassExcess(*z, *a));
1260 }
1261 
1262 
1263 
1270 
1271 Double_t KVNucleus::GetLiquidDropBindingEnergy(std::optional<int> z, std::optional<int> a) const
1272 {
1273  // Returns ground state binding energy in MeV for this nucleus calculated from Brack & Guet
1274  // liquid drop formula (see KVNucleus::LiquiDrop_BrackGuet).
1275  // The convention is : binding energy is positive if nucleus is bound.
1276  // If optional arguments (z,a) are given we return the binding energy for the
1277  // required nucleus.
1278 
1279  CheckZAndA(z, a);
1280 
1281  return *a ==
1282  0 ? 0. : (*z * GetMassExcess(1, 1) + (*a - *z) * GetMassExcess(0, 1) -
1283  GetExtraMassExcess(*z, *a));
1284 }
1285 
1286 
1287 
1288 
1291 
1292 Double_t KVNucleus::GetBindingEnergyPerNucleon(std::optional<int> z, std::optional<int> a) const
1293 {
1294  //Returns binding energy in MeV/A for this nucleus.
1295 
1296  CheckZAndA(z, a);
1297 
1298  if (*a == 0) return 0;
1299  return GetBindingEnergy(*z, *a) / *a;
1300 }
1301 
1302 
1303 
1308 
1310 {
1311  //
1312  //Returns kinetic energy of nucleus per nucleon (in MeV/nucleon, donc)
1313  //
1314  return GetA() ? GetEnergy() / GetA() : GetEnergy();
1315 }
1316 
1317 
1318 
1319 
1324 
1326 {
1327  //
1328  //Returns kinetic energy of nucleus per nucleon (in MeV/nucleon, donc)
1329  //
1330  return GetEnergyPerNucleon();
1331 }
1332 
1333 
1334 
1335 
1341 
1342 KVNumberList KVNucleus::GetKnownARange(std::optional<int> zz, std::optional<double> tmin) const
1343 {
1344  //\returns range of a known mass for a given element according to the lifetime in seconds
1345  //
1346  // - tmin=0 (default) include all nuclei with known lifetime
1347  // - tmin=-1 include also nuclei for which lifetime is unknown
1348  if (!zz) zz = GetZ();
1349  KVNumberList nla;
1350  if (*zz == 0)
1351  nla.Add(1);
1352  else
1353  nla.SetMinMax(TMath::Max(*zz, 1), 6 * TMath::Max(*zz, 1));
1354  KVNumberList nlb;
1355  nla.Begin();
1356  while (!nla.End()) {
1357  Int_t aa = nla.Next();
1358  if (IsKnown(zz, aa) && (GetLifeTime(zz, aa).value_or(-1) >= tmin)) nlb.Add(aa);
1359  }
1360  return nlb;
1361 }
1362 
1363 
1364 
1367 
1368 KVNumberList KVNucleus::GetMeasuredARange(std::optional<int> zz) const
1369 {
1370  //returns range of a measured mass for a given element
1371 
1372  if (!zz) zz = GetZ();
1373  KVNumberList nla;
1374  if (*zz == 0)
1375  nla.Add(1);
1376  else
1377  nla.SetMinMax(TMath::Max(*zz, 1), 6 * TMath::Max(*zz, 1));
1378  KVNumberList nlb;
1379  nla.Begin();
1380  while (!nla.End()) {
1381  Int_t aa = nla.Next();
1382  if(GetTkNucleus(zz,aa).has_property("mass_excess"))
1383  nlb.Add(aa);
1384  }
1385  return nlb;
1386 
1387 }
1388 
1389 
1390 
1397 
1398 const Char_t* KVNucleus::GetIsotopesList(Int_t zmin, Int_t zmax, std::optional<double> tmin) const
1399 {
1400  //returns list of isotopes separated by commas
1401  //
1402  //for example: 1H,2H,3H
1403  //
1404  //according to the charge range and the minimum lifetime in seconds
1405 
1406  static KVString list;
1407  KVNucleus nn;
1408  KVNumberList nla;
1409  list = "";
1410  for (Int_t zz = zmin; zz <= zmax; zz += 1) {
1411  nla = GetKnownARange(zz, tmin);
1412  nla.Begin();
1413  while (!nla.End()) {
1414  Int_t aa = nla.Next();
1415  nn.SetZandA(zz, aa);
1416  list += nn.GetSymbol();
1417  list += ",";
1418  }
1419  }
1420  return list.Data();
1421 }
1422 
1423 
1424 
1425 
1427 
1429 {
1430 
1431  KVNumberList nla = GetKnownARange(zz);
1432  nla.Begin();
1433  Double_t emax = 0;
1434  Int_t amax = 0;
1435  while (!nla.End()) {
1436  Int_t aa = nla.Next();
1437  if (GetBindingEnergyPerNucleon(zz, aa) > emax) {
1438  emax = GetBindingEnergyPerNucleon(zz, aa);
1439  amax = aa;
1440  }
1441  }
1442  return amax;
1443 
1444 }
1445 
1446 
1447 
1448 
1451 
1453 {
1454  //KVNucleus assignment operator.
1455 
1456  if (&rhs != this) {
1457  rhs.Copy(*this);
1458  }
1459  return *this;
1460 }
1461 
1462 
1463 
1464 
1470 
1472 {
1473  // KVNucleus addition operator.
1474  //
1475  // Add two nuclei together to form a compound nucleus whose Z, A, momentum
1476  // and excitation energy are calculated from energy and momentum conservation.
1477 
1478  KVNucleus& lhs = *this;
1479  Int_t ztot = lhs.GetZ() + rhs.GetZ();
1480  Int_t atot = lhs.GetA() + ((KVNucleus&) rhs).GetA();
1481  KVNucleus CN(ztot, atot);
1482 
1483  Double_t etot = lhs.E() + rhs.E();
1484  TVector3 ptot = lhs.GetMomentum() + rhs.GetMomentum();
1485  TLorentzVector q(ptot, etot);
1486  CN.Set4Mom(q);
1487 
1488  return CN;
1489 
1490 }
1491 
1492 
1493 
1494 
1501 
1503 {
1504  // KVNucleus subtraction operator.
1505  // If the LHS is a compound nucleus and the RHS an emitted nucleus
1506  // (which may or may not be excited) then the result of the subtraction
1507  // is the residual nucleus, with recoil and residual excitation calculated
1508  // by conservation laws.
1509 
1510  KVNucleus& lhs = *this;
1511  Int_t zres = lhs.GetZ() - rhs.GetZ();
1512  Int_t ares = lhs.GetA() - ((KVNucleus&) rhs).GetA();
1513  Double_t eres = lhs.E() - rhs.E();
1514  TVector3 pres = lhs.GetMomentum() - rhs.GetMomentum();
1515 
1516  if (zres < 0 || ares < 0 || eres < 0) {
1517  KVError::Warning(this, "operator-(const KVNucleus &rhs)",
1518  "Cannot subtract nuclei, resulting Z=%d A=%d E=%lf", zres, ares, eres);
1519  KVNucleus RES;
1520  RES.Clear();
1521  return RES;
1522  }
1523  else {
1524  KVNucleus RES(zres, ares); //mass of nucleus includes mass excess
1525  TLorentzVector q(pres, eres);
1526  RES.Set4Mom(q);
1527  return RES;
1528  }
1529 }
1530 
1531 
1532 
1533 
1536 
1538 {
1539  //KVNucleus addition and assignment operator.
1540 
1541  KVNucleus temp = (*this) + rhs;
1542  (*this) = temp;
1543  return *this;
1544 }
1545 
1546 
1547 
1548 
1551 
1553 {
1554  //KVNucleus subtraction and assignment operator.
1555 
1556  KVNucleus temp = (*this) - rhs;
1557  (*this) = temp;
1558  return *this;
1559 }
1560 
1561 
1562 
1563 
1567 
1569 {
1570  //Liquid drop mass formula used for nuclei not in mass table (extrapolation).
1571  //Parameters are from Brack and Guet (copied from Simon code)
1572 
1573  Double_t A = (Double_t) aa;
1574  Double_t Z = (Double_t) zz;
1575  Double_t AVOL = 15.776;
1576  Double_t ASUR = -17.22;
1577  Double_t AC = -10.24;
1578  Double_t AZER = 8.;
1579  Double_t XJJ = -30.03;
1580  Double_t QQ = -35.4;
1581  Double_t C1 = -.737;
1582  Double_t C2 = 1.28;
1583 
1584  Double_t XNEU = A - Z;
1585  Double_t SI = (XNEU - Z) / A;
1586  Double_t X13 = TMath::Power(A, 1. / 3.);
1587  Double_t EE1 = C1 * Z * Z / X13;
1588  Double_t EE2 = C2 * Z * Z / A;
1589  Double_t AUX = 1. + (9. * XJJ / 4. / QQ / X13);
1590  Double_t EE3 = XJJ * A * SI * SI / AUX;
1591  Double_t EE4 =
1592  AVOL * A + ASUR * TMath::Power(A, 2. / 3.) + AC * X13 + AZER;
1593  Double_t TOTA = EE1 + EE2 + EE3 + EE4;
1594  return (939.55 * XNEU + 938.77 * Z - TOTA);
1595 }
1596 
1597 
1598 
1599 
1603 
1605 {
1606  //Liquid drop mass formula used for nuclei not in mass table (extrapolation).
1607  //Parameters are from Brack and Guet (copied from Simon code)
1608 
1609  Double_t av = 1.531e+01;
1610  Double_t as = 1.654e+01;
1611  Double_t ac = 6.882e-01;
1612  Double_t aa = 2.225e+01;
1613  Double_t ap = 9.399e+00;
1614  Double_t kap = 6.056e-01;
1615 
1616  Double_t eb = 0;
1617  eb += av * GetA();
1618  eb -= as * TMath::Power(GetA(), 2. / 3.);
1619  eb -= ac * GetZ() * (GetZ() - 1) / TMath::Power(GetA(), 1. / 3.);
1620  eb -= aa * TMath::Power(GetN() - GetZ(), 2.) / GetA();
1621 
1622  if (TMath::Even(GetA()))
1623  eb += ap * (TMath::Power(-1, GetN()) + TMath::Power(-1, GetZ())) / TMath::Power(GetA(), kap);
1624 
1625  return eb;
1626 
1627 }
1628 
1629 
1630 
1631 
1635 
1637 {
1638  //For sorting lists of nuclei according to their Z
1639  //Largest Z appears first in list
1640 
1641  if (GetZ() > ((KVNucleus*) obj)->GetZ()) {
1642  return -1;
1643  }
1644  else if (GetZ() < ((KVNucleus*) obj)->GetZ()) {
1645  return 1;
1646  }
1647  else {
1648  if (GetA() == ((KVNucleus*) obj)->GetA()) return 0;
1649  else if (GetA() > ((KVNucleus*) obj)->GetA()) return -1;
1650  else return 1;
1651  }
1652 }
1653 
1654 
1655 /*
1656 TH2F* KVNucleus::GetKnownNucleiChart(KVString method)
1657 {
1658  //Draw nuclei chart of tabulated nuclei and tagged as known in KaliVeda
1659  //The 2D histogram (AvsZ) has to be deleted by the user
1660  //Each content cell correponds to the method passed in argument of nucleus in MeV
1661  // Method Pattern has to be Double_t Method() or Double_t Method(obs = default value) in KVNucleus.h
1662 TH2F* chart = new TH2F("nuclei_known_charts",method.Data(),
1663  121,-0.5,120.5,
1664  351,-0.5,350.5);
1665 chart->SetXTitle("Atomic Number");
1666 chart->SetYTitle("Mass Number");
1667 
1668 TMethodCall *mt = new TMethodCall();
1669 mt->InitWithPrototype(this->IsA(),Form("%s",method.Data()),"");
1670 if (! mt->IsValid()) { delete mt; return 0; }
1671 delete mt;
1672 KVNucleus* ntemp = new KVNucleus();
1673 for (Int_t zz=0;zz<120;zz+=1){
1674  for (Int_t aa=0;aa<350;aa+=1){
1675  if (this->IsKnown(zz,aa)){
1676  mt = new TMethodCall();
1677  mt->InitWithPrototype(ntemp->IsA(),Form("%s",method.Data()),"");
1678  if (mt->ReturnType()==TMethodCall::kDouble){
1679  ntemp->SetZ(zz); ntemp->SetA(aa);
1680  Double_t ret; mt->Execute(ntemp,"",ret);
1681  chart->Fill(zz,aa,ret);
1682  }
1683  delete mt;
1684  }
1685  }
1686 }
1687 delete ntemp;
1688 return chart;
1689 
1690 }
1691 */
1692 
1693 
1698 
1700 {
1701  //Atomic mass unit in MeV
1702  //
1703  //Reference: 2002 CODATA recommended values Reviews of Modern Physics 77, 1-107 (2005)
1704  return kAMU;
1705 };
1706 
1707 
1708 
1709 
1713 
1715 {
1716  //Retourne l'energie cintetique totale (MeV) du noyau pour
1717  //une valeur de Brho et d'etat de charge (Si 0-> Etat de charge=Z)
1718  Double_t C_mparns = KVNucleus::C() * 10;
1719 
1720  if (ChargeState == 0) ChargeState = GetZ();
1721 
1722  Double_t X = Brho * C_mparns * ChargeState;
1723 
1724  Double_t MassIon = GetMass() - ChargeState * KVNucleus::kMe;
1725 
1726  Double_t Result = TMath::Sqrt(MassIon * MassIon + X * X) - MassIon;
1727 
1728  return Result;
1729 
1730 }
1731 
1732 
1733 
1736 
1738 {
1739  // Return the reltive velocity between nuc and this in cm/ns.
1740  if (!nuc) return 0.;
1741  return (GetVelocity() - nuc->GetVelocity()).Mag();
1742 }
1743 
1744 
1745 
1756 
1758 {
1759  // Average or most probable Total Kinetic Energy [MeV] expected for fission based on various systematics
1760  // for fission of highly-excited nuclei produced in heavy-ion reactions.
1761  // If nuc=0, this method returns the TKE for symmetric fission of this nucleus.
1762  // Else, it returns the expected TKE considering that nuc and the current nucleus arise
1763  // from the fisson of a compound nucleus.
1764  // - kItkis1998: M.G. Itkis & A. Ya. Rusanov, Phys. Part. Nucl. 29, 160 (1998)
1765  // - kDefaultFormula = kHinde1987: D. Hinde, J. Leigh, J. Bokhorst, J. Newton, R. Walsh, and J. Boldeman, Nuclear Physics A 472, 318 (1987).
1766  // - kViola1985: V. E. Viola, K. Kwiatkowski, and M. Walker, Physical Review C 31, 1550 (1985).
1767  // - kViola1966: V. E. Viola, Jr. , Nuclear Data Sheets. Section A 1, 391 (1965).
1768 
1769  Double_t Ztot = GetZ();
1770  Double_t Atot = GetA();
1771  if (nuc) {
1772  Ztot += nuc->GetZ();
1773  Atot += nuc->GetA();
1774  }
1775  Double_t tke = 0;
1776  switch (formula) {
1777  case kDefaultFormula:
1778  case kHinde1987:
1779  if (nuc) tke = TKE_Hinde1987(GetZ(), GetA(), nuc->GetZ(), nuc->GetA());
1780  else tke = TKE_Hinde1987(GetZ() * 0.5, GetA() * 0.5, GetZ() - (GetZ() * 0.5), GetA() - (GetA() * 0.5));
1781  break;
1782 
1783  case kViola1985:
1784  tke = TKE_Viola1985(Ztot, Atot);
1785  break;
1786 
1787  case kViola1966:
1788  tke = TKE_Viola1966(Ztot, Atot);
1789  break;
1790 
1791  case kItkis1998:
1792  tke = TKE_Itkis1998(Ztot, Atot);
1793  break;
1794  }
1795 
1796  return tke;
1797 }
1798 
1799 
1800 
1806 
1808 {
1809  // <TKE> of asymmetric QuasiFission fragments (for the fragment mass where the QFasym yield is maximal)
1810  // E.M. Kozulin et al PHYSICAL REVIEW C 90, 054608 (2014)
1811  // This depends on the entrance channel: this nucleus is assumed to be the projectile,
1812  // while the target is given as argument.
1813 
1814  return TKE_Kozulin2014(GetZ(), target->GetZ(), GetA(), target->GetA());
1815 }
1816 
1817 
1818 
1829 
1831 {
1832  // Average/most probable relative velocity [cm/ns] expected for fission based on various systematics
1833  // for fission of highly-excited nuclei produced in heavy-ion reactions.
1834  // If nuc=0, this method returns the relative velocity expected for the symmetric fission of this nucleus.
1835  // Else, it returns the expected relative velocity considering that nuc and the current nucleus arise
1836  // from the fisson of a compound nucleus.
1837  // - kItkis1998: M.G. Itkis & A. Ya. Rusanov, Phys. Part. Nucl. 29, 160 (1998)
1838  // - kDefaultFormula = kHinde1987: D. Hinde, J. Leigh, J. Bokhorst, J. Newton, R. Walsh, and J. Boldeman, Nuclear Physics A 472, 318 (1987).
1839  // - kViola1985: V. E. Viola, K. Kwiatkowski, and M. Walker, Physical Review C 31, 1550 (1985).
1840  // - kViola1966: V. E. Viola, Jr. , Nuclear Data Sheets. Section A 1, 391 (1965).
1841 
1842  Double_t vrel = 0;
1843  Double_t mu = 0;
1844  if (nuc) {
1845  mu = nuc->GetMass() * GetMass() / (nuc->GetMass() + GetMass());
1846  }
1847  else {
1848  KVNucleus ff1(0.5 * GetZ(), 0.5 * GetA());
1849  KVNucleus ff2(GetZ() - ff1.GetZ(), GetA() - ff1.GetA());
1850  mu = ff1.GetMass() * ff2.GetMass() / (ff1.GetMass() + ff2.GetMass());
1851  }
1852 
1853  Double_t TKE = GetFissionTKE(nuc, formula);
1854  vrel = sqrt(2 * TKE / mu) * C();
1855 
1856  return vrel;
1857 }
1858 
1859 
1860 
1864 
1866 {
1867  // from: D. Hinde, J. Leigh, J. Bokhorst, J. Newton, R. Walsh, and J. Boldeman, Nuclear Physics A 472, 318 (1987)
1868  // According to the authors, an extension to asymmetric fission based on TKE_Viola1985
1869  return 0.755 * z1 * z2 / (pow(a1, 1 / 3.) + pow(a2, 1 / 3.)) + 7.3;
1870 }
1871 
1872 
1873 
1876 
1878 {
1879  // from: V. E. Viola, K. Kwiatkowski, and M. Walker, Physical Review C 31, 1550 (1985).
1880  Double_t za = pow(z, 2) / pow(a, 1. / 3.);
1881  return 0.1189 * za + 7.3;
1882 }
1883 
1884 
1885 
1888 
1890 {
1891  // from: V. E. Viola, Jr., Nuclear Data Sheets. Section A 1, 391 (1965).
1892  Double_t za = pow(z, 2) / pow(a, 1. / 3.);
1893  return 0.1071 * za + 22.2;
1894 }
1895 
1896 
1897 
1902 
1904 {
1905  // from: M.G. Itkis & A. Ya. Rusanov, Phys. Part. Nucl. 29, 160 (1998)
1906  // Compared to Viola systematics, only heavy-ion induced fission is considered
1907  // A change of slope is observed for Z**2/A**1/3 > 900
1908 
1909  Double_t za = pow(z, 2) / pow(a, 1. / 3.);
1910  if (za < 900)
1911  return 0.131 * za;
1912  return 0.104 * za + 24.3;
1913 }
1914 
1915 
1916 
1920 
1922 {
1923  // <TKE> of asymmetric QuasiFission fragments (for the fragment mass where the QFasym yield is maximal)
1924  // E.M. Kozulin et al PHYSICAL REVIEW C 90, 054608 (2014)
1925 
1926  return 39.43 + .085 * pow(zp + zt, 2) / pow(ap + at, 1. / 3.);
1927 }
1928 
1929 
1930 
1931 
1938 
1940 {
1941  // \returns kTRUE if this nucleus is stable
1942  //
1943  // Definition of stable:
1944  // - if the natural abundance is defined
1945  // - or if lifetime is > min_lifetime
1946 
1947  if (GetAbundance()) return kTRUE;
1948  return !IsResonance() && GetLifeTime().value_or(0) > min_lifetime;
1949 }
1950 
1951 
1952 
1953 
1960 
1961 Bool_t KVNucleus::IsResonance(std::optional<int> z, std::optional<int> a) const
1962 {
1963  // \returns kTRUE if this nucleus is a resonance.
1964  //
1965  // In this case GetWidth() returns the width in MeV.
1966  //
1967  // \note we deduce that the nucleus is a resonance when the TkN property "lifetime" has energy units
1968 
1969  auto nuc = GetTkNucleus(z,a);
1970  return nuc.has_property("lifetime")
1971  && nuc.get_lifetime_measure()->get_unit_key() <= tkn::tkunit_manager::units_keys::TeV;
1972 }
1973 
1974 
1975 
1976 
1980 
1981 std::optional<double> KVNucleus::GetWidth(std::optional<int> z, std::optional<int> a) const
1982 {
1983  // \returns width of resonance in MeV, if this nucleus
1984  // is indeed a resonance (IsResonance() returns kTRUE)
1985 
1986  if(IsResonance(z,a))
1987  return GetTkNucleus(z,a).get_lifetime(tkn::tkunit_manager::units_keys::MeV);
1988  return {};
1989 }
1990 
1991 
1992 
1993 
1997 
1998 Double_t KVNucleus::GetNaturalA(std::optional<int> z) const
1999 {
2000  // Calculate and return the effective mass number of element Z
2001  // taking into account the abundance of naturally-occurring isotopes
2002 
2003  KVNumberList isotopes = GetKnownARange(z);
2004  isotopes.Begin();
2005  Double_t Aeff = 0, wtot = 0;
2006  while (!isotopes.End()) {
2007 
2008  int A = isotopes.Next();
2009  auto abundance = GetAbundance(z, A);
2010  if (abundance) {
2011  Aeff += A * (*abundance);
2012  wtot += *abundance;
2013  }
2014 
2015  }
2016  if (wtot > 0) Aeff /= wtot;
2017  return Aeff;
2018 }
2019 
2020 
2021 //-------------------------
2023 //-------------------------
2024 
2036 
2037 {
2038  //Nuclear Instruments and Methods 200 (1982) 605-608
2039  //Shima et al
2040  // "The present formula is useful for the collision range"
2041  // Zprojectile>=8
2042  // 4<=Ztarget<=79
2043  // Eproj<=6 MeV/A
2044  // Precision DeltaQ/Zproj <0.04.
2045  //
2046 
2047  //v=sqrt((2*E*1.6022)/(A*1.66054))*10.;
2048  //X=v/((3.6)*pow(Z,0.45));
2049 
2050  Double_t vel = GetVelocity().Mag(); // (cm/ns)
2051  vel *= 10; // (mm/ns)
2052  Double_t X = vel / ((3.6) * pow(GetZ(), 0.45));
2053 
2054  Double_t Q = GetZ() * (1 - exp(-1.25 * X + 0.32 * TMath::Power(X, 2.) - 0.11 * TMath::Power(X, 3.)));
2055  Q *= (1 - 0.0019 * (Ztarget - 6) * TMath::Sqrt(X) + 0.00001 * TMath::Power(Ztarget - 6, 2.) * X); //Correction respect to the carbon
2056 
2057  return Q;
2058 
2059 }
2060 
2061 
2062 //-------------------------
2064 //-------------------------
2065 
2067 
2068 {
2069  return 0.04 * GetZ();
2070 }
2071 
2072 
2073 
2078 
2079 void KVNucleus::Streamer(TBuffer& R__b)
2080 {
2081  // Stream an object of class KVNucleus.
2082  //
2083  // Streamer customized to correct masses of nuclei in data written with version <7
2084 
2085  UInt_t R__s, R__c;
2086  if (R__b.IsReading()) {
2087  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2088  R__b.ReadClassBuffer(KVNucleus::Class(), this, R__v, R__s, R__c);
2089  if (R__v < 7) {
2090  // Before v7, nuclear masses were actually atomic masses, including the electrons
2091  double m = GetMass();
2092  SetMass(m - GetZ()*kMe);
2093  }
2094  }
2095  else {
2096  R__b.WriteClassBuffer(KVNucleus::Class(), this);
2097  }
2098 }
2099 
2100 
int Int_t
unsigned int UInt_t
bool Bool_t
short Version_t
unsigned char UChar_t
char Char_t
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 GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
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 Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
float * q
static void InitEnvironment()
Definition: KVBase.cpp:196
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:108
Double_t ShimaChargeStatePrecision() const
Definition: KVNucleus.cpp:2063
std::optional< double > GetAbundance(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1179
@ kHinde1987
Definition: KVNucleus.h:138
@ kViola1985
Definition: KVNucleus.h:139
@ kDefaultFormula
Definition: KVNucleus.h:136
@ kViola1966
Definition: KVNucleus.h:140
@ kItkis1998
Definition: KVNucleus.h:137
static Double_t hbar
hbar*c in MeV.fm
Definition: KVNucleus.h:153
Double_t GetBindingEnergyPerNucleon(std::optional< int > z={}, std::optional< int > a={}) const
Returns binding energy in MeV/A for this nucleus.
Definition: KVNucleus.cpp:1292
const Char_t * GetSymbol(Option_t *opt="") const
Definition: KVNucleus.cpp:43
void Copy(TObject &) const override
Copy this KVNucleus into the KVNucleus object referenced by "obj".
Definition: KVNucleus.cpp:839
void SetExcitEnergy(Double_t e)
Definition: KVNucleus.cpp:867
Double_t GetExtraMassExcess(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:946
static Double_t LiquidDrop_BrackGuet(UInt_t A, UInt_t Z)
Definition: KVNucleus.cpp:1568
void Clear(Option_t *opt="") override
Definition: KVNucleus.cpp:296
Double_t GetMassExcess(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:911
void CheckZAndA(std::optional< Int_t > &z, std::optional< Int_t > &a) const
Definition: KVNucleus.cpp:854
std::optional< int > GetMostAbundantA(std::optional< int > z={}) const
Definition: KVNucleus.cpp:1197
Double_t GetBindingEnergy(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1243
void Set(const Char_t *)
Definition: KVNucleus.cpp:184
Double_t GetAMeV() const
Definition: KVNucleus.cpp:1325
static Double_t TKE_Viola1985(Double_t z, Double_t a)
from: V. E. Viola, K. Kwiatkowski, and M. Walker, Physical Review C 31, 1550 (1985).
Definition: KVNucleus.cpp:1877
static Int_t GetNFromZ(Double_t, Char_t mt)
Calculate neutron number from the element's atomic number Z.
Definition: KVNucleus.cpp:637
void Print(Option_t *t="") const override
Display nucleus parameters.
Definition: KVNucleus.cpp:763
static Double_t GetRealAFromZ(Double_t, Char_t mt)
Definition: KVNucleus.cpp:445
Double_t GetExcitEnergy() const
Definition: KVNucleus.h:257
std::optional< double > GetLifeTime(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1045
Double_t GetFissionTKE(const KVNucleus *nuc=0, Int_t formula=kDefaultFormula) const
Definition: KVNucleus.cpp:1757
void init()
Definition: KVNucleus.cpp:251
Int_t GetAWithMaxBindingEnergy(std::optional< int > z={})
Definition: KVNucleus.cpp:1428
static Double_t GetRealNFromZ(Double_t, Char_t mt)
Definition: KVNucleus.cpp:515
static Double_t u(void)
Definition: KVNucleus.cpp:1699
KVNucleus operator+(const KVNucleus &rhs)
Definition: KVNucleus.cpp:1471
void SetZandN(Int_t z, Int_t n)
Set atomic number and mass number.
Definition: KVNucleus.cpp:751
Int_t GetA() const
Definition: KVNucleus.cpp:805
static Int_t IsMassGiven(const Char_t *)
Definition: KVNucleus.cpp:149
void SetA(Int_t a)
Definition: KVNucleus.cpp:658
KVNucleus & operator=(const KVNucleus &rhs)
KVNucleus assignment operator.
Definition: KVNucleus.cpp:1452
void SetN(Int_t n)
Definition: KVNucleus.cpp:690
Double_t GetMassGS() const
Definition: KVNucleus.h:265
static Double_t kMe
electron mass in MeV/c2
Definition: KVNucleus.h:151
void SetZ(Int_t z, Char_t mt=-1)
Definition: KVNucleus.cpp:709
Double_t LiquidDrop_Weizsacker()
Definition: KVNucleus.cpp:1604
Double_t GetExtraChargeRadius(std::optional< int > a={}, Int_t rct=2) const
Definition: KVNucleus.cpp:1120
KVNucleus & operator+=(const KVNucleus &rhs)
KVNucleus addition and assignment operator.
Definition: KVNucleus.cpp:1537
Double_t GetLiquidDropBindingEnergy(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1271
Double_t GetFissionVelocity(KVNucleus *nuc=0, Int_t formula=kDefaultFormula)
Definition: KVNucleus.cpp:1830
static Double_t TKE_Itkis1998(Double_t z, Double_t a)
Definition: KVNucleus.cpp:1903
std::optional< double > GetSpin(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:994
@ kEALResMass
Definition: KVNucleus.h:126
Double_t GetAtomicMass(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:971
static Double_t e2
e^2/(4.pi.epsilon_0) in MeV.fm
Definition: KVNucleus.h:154
Bool_t IsKnown(std::optional< int > z={}, std::optional< int > a={}) const
Returns kTRUE if this nucleus or (z,a) is known.
Definition: KVNucleus.cpp:1222
tkn::tknucleus GetTkNucleus(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:881
Double_t GetRelativeVelocity(KVNucleus *nuc)
Return the reltive velocity between nuc and this in cm/ns.
Definition: KVNucleus.cpp:1737
Int_t GetN() const
Return the number of neutron.
Definition: KVNucleus.cpp:787
Double_t GetNaturalA(std::optional< int > z={}) const
Definition: KVNucleus.cpp:1998
KVNucleus & operator-=(const KVNucleus &rhs)
KVNucleus subtraction and assignment operator.
Definition: KVNucleus.cpp:1552
Int_t Compare(const TObject *obj) const override
Definition: KVNucleus.cpp:1636
KVNumberList GetMeasuredARange(std::optional< int > z={}) const
returns range of a measured mass for a given element
Definition: KVNucleus.cpp:1368
Double_t DeduceEincFromBrho(Double_t Brho, Int_t ChargeState=0)
TH2F* GetKnownNucleiChart(KVString method="GetBindingEnergyPerNucleon");.
Definition: KVNucleus.cpp:1714
Double_t ShimaChargeState(Int_t) const
Definition: KVNucleus.cpp:2022
static Double_t kAMU
atomic mass unit in MeV
Definition: KVNucleus.h:150
int SetZFromSymbol(const Char_t *)
Definition: KVNucleus.cpp:231
void SetZandA(Int_t z, Int_t a)
Set atomic number and mass number.
Definition: KVNucleus.cpp:726
const Char_t * GetLatexSymbol(Option_t *opt="") const
Definition: KVNucleus.cpp:97
Int_t GetNpairs(Int_t type=kNN) const
Definition: KVNucleus.cpp:824
const Char_t * GetIsotopesList(Int_t zmin, Int_t zmax, std::optional< double > tmin={}) const
Definition: KVNucleus.cpp:1398
void SetZAandE(Int_t z, Int_t a, Double_t ekin)
Set atomic number, mass number, and kinetic energy in MeV.
Definition: KVNucleus.cpp:738
Double_t GetQFasymTKE(KVNucleus *target)
Definition: KVNucleus.cpp:1807
static Double_t TKE_Hinde1987(Double_t z1, Double_t a1, Double_t z2, Double_t a2)
Definition: KVNucleus.cpp:1865
Double_t GetChargeRadius(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1083
KVNumberList GetKnownARange(std::optional< int > z={}, std::optional< double > tmin={}) const
Definition: KVNucleus.cpp:1342
static Int_t GetZFromSymbol(const Char_t *)
Definition: KVNucleus.cpp:213
Double_t GetEnergyPerNucleon() const
Definition: KVNucleus.cpp:1309
std::optional< int > GetParity(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1016
static Int_t GetAFromZ(Double_t, Char_t mt)
Definition: KVNucleus.cpp:565
Bool_t IsStable(Double_t min_lifetime=1.0e+15) const
Definition: KVNucleus.cpp:1939
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:776
Bool_t IsResonance(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1961
static Double_t TKE_Viola1966(Double_t z, Double_t a)
from: V. E. Viola, Jr., Nuclear Data Sheets. Section A 1, 391 (1965).
Definition: KVNucleus.cpp:1889
std::optional< double > GetWidth(std::optional< int > z={}, std::optional< int > a={}) const
Definition: KVNucleus.cpp:1981
static Double_t TKE_Kozulin2014(Double_t zp, Double_t zt, Double_t ap, Double_t at)
Definition: KVNucleus.cpp:1921
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:86
void SetMinMax(Int_t min, Int_t max, Int_t pas=1)
Set list with all values from 'min' to 'max'.
Bool_t End(void) const
Definition: KVNumberList.h:200
void Begin(void) const
void Add(Int_t)
Add value 'n' to the list.
Int_t Next(void) const
Base class for relativistic kinematics of massive particles.
Definition: KVParticle.h:396
virtual void SetMass(Double_t m)
Definition: KVParticle.h:573
TVector3 GetMomentum() const
Definition: KVParticle.h:607
void SetMomentum(const TVector3 &v)
Definition: KVParticle.h:581
Double_t GetEnergy() const
Definition: KVParticle.h:624
static Double_t C()
Definition: KVParticle.cpp:117
void SetKE(Double_t ecin)
Definition: KVParticle.cpp:246
void Copy(TObject &) const override
Definition: KVParticle.cpp:286
void Set4Mom(const TLorentzVector &p)
Definition: KVParticle.h:592
void Clear(Option_t *opt="") override
Reset particle properties i.e. before creating/reading a new event.
Definition: KVParticle.cpp:327
void Print(Option_t *t="") const override
print out characteristics of particle
Definition: KVParticle.cpp:212
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
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Double_t X() const
TLorentzVector operator-() const
void Streamer(TBuffer &) override
static TClass * Class()
Double_t E() const
Double_t Z() const
void SetBit(UInt_t f)
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
R__ALWAYS_INLINE Bool_t IsZombie() const
void ResetBit(UInt_t f)
const char * Data() const
void ToUpper()
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Bool_t IsNull() const
TString & Remove(EStripType s, char c)
Expr< UnaryOp< Sqrt< T >, SMatrix< T, D, D2, R >, T >, T, D, D2, R > sqrt(const SMatrix< T, D, D2, R > &rhs)
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
RVec< PromoteType< T > > exp(const RVec< T > &v)
const Int_t n
Double_t ex[n]
void Error(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:125
TMatrixT< Double_t > as(SEXP)
void init()
constexpr Double_t Ccgs()
Int_t Nint(T x)
constexpr Double_t Hbarcgs()
constexpr Double_t Qe()
Double_t Power(Double_t x, Double_t y)
Double_t Sqrt(Double_t x)
constexpr Double_t R()
Double_t Max(Double_t a, Double_t b)
Bool_t Even(Long_t a)
TMarker m
TArc a
ClassImp(TPyArg)
#define sym(otri1, otri2)