KaliVeda
Toolkit for HIC analysis
KVLevelScheme.cpp
1 //Created by KVClassFactory on Fri Nov 20 12:23:35 2015
2 //Author: gruyer,,,
3 
4 #include "KVLevelScheme.h"
5 #include "KVExcitedState.h"
6 #include "TH2F.h"
7 #include "TLine.h"
8 #include "TCanvas.h"
9 #include "TRandom.h"
10 #include "TStyle.h"
11 #include "TLatex.h"
12 
13 #include "tknucleus.h"
14 
15 using namespace std;
16 using namespace tkn;
17 
19 
20 
21 
22 
23 
26 KVLevelScheme::KVLevelScheme(const char* symb)
27 {
28  // Default constructor
29  ncol = 1;
30  dy = 300;
31  dx = 1.3;
32  txs = 22;
33  ddx = .6;
34  hh = 0;
35  cc = 0;
36 
37  fCompNuc = new KVNucleus(symb);
38  fCompNuc->SetExcitEnergy(0);
39 
40  fFunc = new TF1("ExciEnergy", this, &KVLevelScheme::Evaluate, 0, 20000, 1);
41  fFunc->SetNpx(5000);
42 
43  fFuncErel = new TF1("RelEnergy", this, &KVLevelScheme::EvaluateErel, 0, 20000, 1);
44  fFuncErel->SetNpx(5000);
45 
46  ReadLevels();
47 }
48 
49 
50 
53 
55 {
56  // Destructor
57  if (fFunc) delete fFunc;
58 }
59 
60 
61 
64 
66 {
67  // Add all known levels for current isotope to internal list
68 
69  tknucleus nuc(fCompNuc->GetSymbol());
70  auto levels = nuc.get_level_scheme()->get_levels();
71  for(auto &lev : levels)
72  {
73  auto ll = new KVExcitedState;
74  ll->set(lev->get_energy(),
75  lev->is_stable() ? 0 : lev->get_lifetime(tkunit_manager::units_keys::keV),
76  lev->get_spin_parity()->get_spin().get_value(), lev->get_spin_parity()->get_parity().get_value());
77  fLevels.AddLast(ll);
78  }
79 }
80 
81 
82 
84 
86 {
87  cout << endl;
88  cout << " n." << " Jpi" << " E" << " T1/2" << endl;
89  cout << endl;
90  for (Int_t ii = (int)fLevels.GetSize() - 1; ii >= 0; ii--) {
91  KVExcitedState* ll = (KVExcitedState*)fLevels.At(ii);
92  cout << Form("%3d", ii) << ".";
93  ll->print();
94  }
95  cout << endl;
96  cout << " " << Form("%5s", fCompNuc->GetSymbol()) << endl;
97  cout << endl;
98 }
99 
100 
101 
103 
104 double KVLevelScheme::func(double xx, double tt)
105 {
106  double yy = 0.;
107  for (Int_t ii = 0; ii < fLevels.GetSize(); ii++) {
108  KVExcitedState* ll = (KVExcitedState*)fLevels.At(ii);
109  yy += ll->eval(xx);
110  }
111  yy *= TMath::Exp(-xx / tt);
112  return yy;
113 }
114 
115 
116 
118 
119 double KVLevelScheme::getWidth(double gam, TString unit)
120 {
121  unit.ToUpper();
122  if (unit.EqualTo("EV")) gam *= 1e-3;
123  else if (unit.EqualTo("KEV")) gam *= 1;
124  else if (unit.EqualTo("MEV")) gam *= 1e3;
125  else if (unit.Contains("S")) gam *= 1e-6;
126  return gam;
127 }
128 
129 
130 
132 
133 int KVLevelScheme::getJ(TString jpi)
134 {
135  jpi.ReplaceAll("(", "");
136  jpi.ReplaceAll(")", "");
137 
138  int j = 0;
139 
140  if (jpi.EqualTo("")) return 0;
141  if (jpi.EqualTo("GE")) return 0;
142 
143  if (jpi.Contains("-")) jpi = jpi(0, jpi.Index("-"));
144  if (jpi.Contains("+")) jpi = jpi(0, jpi.Index("+"));
145  if (jpi.Contains("/2")) jpi = jpi(0, jpi.Index("/"));
146  if (jpi.Contains(",")) jpi = jpi(0, jpi.Index(","));
147 
148  j = jpi.Atoi();
149  return j;
150 }
151 
152 
153 
155 
157 {
158  if (il > (int)fLevels.GetSize()) return 0;
159  else return ((KVExcitedState*) fLevels.At(il))->fEnergy;
160 }
161 
162 
163 
165 
167 {
168  if (il > (int)fLevels.GetSize()) return 0;
169  else return ((KVExcitedState*) fLevels.At(il))->fWidth;
170 }
171 
172 
173 
175 
177 {
178  if (il > (int)fLevels.GetSize()) return 0;
179  else return ((KVExcitedState*) fLevels.At(il))->fSpin;
180 }
181 
182 
183 
185 
187 {
188  if (il > (int)fLevels.GetSize()) return 0;
189  else return ((KVExcitedState*) fLevels.At(il))->fParity;
190 }
191 
192 
193 
195 
196 const char* KVLevelScheme::GetJPiStr(int il)
197 {
198  if (il > (int)fLevels.GetSize()) return "";
199  else return ((KVExcitedState*) fLevels.At(il))->fJPi.Data();
200 }
201 
202 
204 
205 const char* KVLevelScheme::GetEGammaStr(int il)
206 {
207  if (il > (int)fLevels.GetSize()) return 0;
208  KVString gam = ((KVExcitedState*) fLevels.At(il))->fGamma.Data();
210  gam.ReplaceAll("-1.0", "-");
211  return Form("%d (%s)", TMath::Nint(((KVExcitedState*) fLevels.At(il))->fEnergy), gam.Data());
212 }
213 
214 
215 
217 
218 int KVLevelScheme::getPI(TString jpi)
219 {
220  jpi.ReplaceAll("(", "");
221  jpi.ReplaceAll(")", "");
222 
223 // int j = 0;
224  Int_t pi = 0;
225 
226  if (jpi.EqualTo("")) return 0;
227  if (jpi.EqualTo("GE")) return 0;
228 
229  // determination of pi
230  if ((jpi.Contains("-")) && (jpi.Contains("+"))) {
231  if (jpi.Index("+") < jpi.Index("-")) pi = 1;
232  else pi = -1;
233  }
234  else if (jpi.Contains("-")) pi = -1;
235  else pi = 1;
236 
237  return pi;
238 }
239 
240 
241 
242 
244 
245 double KVLevelScheme::Evaluate(double* x, double* p)
246 {
247  double xx = x[0];
248  double tt = p[0];
249  return func(xx, tt);
250 }
251 
252 
253 
255 
256 double KVLevelScheme::EvaluateErel(double* x, double* p)
257 {
258  double xx = x[0];
259  double tt = p[0];
260  return func(xx - fQvalue * 1000, tt);
261 }
262 
263 
264 
266 
267 void KVLevelScheme::GetParticlesFromErel(KVNucleus* n1, KVNucleus* n2, double erel, bool randAngle, TVector3* vsrc)
268 {
269  KVNucleus nuc1(n1->GetZ(), n1->GetA());
270  KVNucleus nuc2(n2->GetZ(), n2->GetA());
271 
272  double m1 = nuc1.GetMass();
273  double m2 = nuc2.GetMass();
274  double e1 = (m2 / (m1 + m2)) * erel;
275  double e2 = (m1 / (m1 + m2)) * erel;
276 
277  nuc1.SetKE(e1);
278  nuc1.SetTheta(0);
279  nuc2.SetKE(e2);
280  nuc2.SetTheta(180);
281 
282  if (randAngle) {
283  TVector3 v1r = nuc1.GetVelocity();
284  TVector3 v2r = nuc2.GetVelocity();
285  TRotation rr;
286  rr.SetXEulerAngles(gRandom->Rndm() * 2.*TMath::Pi(), TMath::ACos(gRandom->Rndm() * 2. - 1.), gRandom->Rndm() * 2.*TMath::Pi());
287  v1r *= rr;
288  nuc1.SetVelocity(v1r);
289  v2r *= rr;
290  nuc2.SetVelocity(v2r);
291  }
292 
293  if (vsrc) {
294  *vsrc *= -1;
295  nuc1.SetFrame("src", *vsrc);
296  nuc2.SetFrame("src", *vsrc);
297  n1->SetVelocity(nuc1.GetFrame("src")->GetVelocity());
298  n2->SetVelocity(nuc2.GetFrame("src")->GetVelocity());
299  }
300 
301 }
302 
303 
304 
306 
307 void KVLevelScheme::GetParticlesFromExci(KVNucleus* nuc1, KVNucleus* nuc2, double erel, bool randAngle, TVector3* vsrc)
308 {
309  KVNucleus comp = *nuc1 + *nuc2;
310  double qq = -1 * (comp.GetExcitEnergy());
311  GetParticlesFromErel(nuc1, nuc2, erel + qq, randAngle, vsrc);
312 }
313 
314 
315 
317 
318 void KVLevelScheme::GetRandomParticles(KVNucleus* n1, KVNucleus* n2, double T/*keV*/, bool randAngle, TVector3* vsrc)
319 {
320  if (!fLevels.GetSize()) cout << "KVLevelScheme::GetRandomParticles: please initialize the level scheme firts..." << endl;
321  fFunc->SetParameter(0, T);
322  double excit = fFunc->GetRandom();
323 
324  GetParticlesFromExci(n1, n2, excit, randAngle, vsrc);
325 }
326 
327 
328 
330 
331 void KVLevelScheme::SetDrawStyle(double deMin, double fullWidth, double lineWidth, int textSize)
332 {
333  dy = deMin;
334  dx = fullWidth;
335  ddx = lineWidth;
336  txs = textSize;
337 }
338 
339 
340 
342 
343 void KVLevelScheme::Draw(Option_t* /*option*/)
344 {
345  ncol = 1;
346  int icol = 0;
347 
348  int cols[20];
349  for (int ic = 0; ic < 20; ic++) cols[ic] = 0;
350  cols[0] = GetLevelEnergy(0);
351 
352  for (int ii = 0; ii < GetNLevels(); ii++) {
353  for (int ic = 0; ic < TMath::Max(ii, 20); ic++) {
354  if ((GetLevelEnergy(ii) - cols[ic] > dy)) {
355  cols[ic] = GetLevelEnergy(ii);
356  icol = ic;
357  if (icol + 1 > ncol) ncol = icol + 1;
358  break;
359  }
360  }
361  }
362 
363  double max = GetLevelEnergy(GetNLevels() - 1);
364  if (hh) delete hh;
365  hh = new TH2F(Form("dumhist%s", fCompNuc->GetSymbol()), "", 1, 0, ncol * dx + 0.5 * dx, 1000, -200, max + 200);
366 
367 // TString opt = option;
368  gStyle->SetOptStat(0);
369 // if (!opt.Contains("same")) {
370  if (cc) delete cc;
371  cc = new TCanvas(Form("levels%s", fCompNuc->GetSymbol()), Form("levels%s", fCompNuc->GetSymbol()), (ncol) * (dx) * 0.4 * 400, 800);
372  cc->SetTickx(1);
373  cc->SetTicky(1);
374  cc->SetTopMargin(0.02);
375  cc->SetBottomMargin(0.02);
376  cc->SetRightMargin(0.02);
377  cc->SetLeftMargin(0.02);
378 
379  hh->GetXaxis()->SetAxisColor(0);
380  hh->GetYaxis()->SetAxisColor(0);
381 
382  hh->GetXaxis()->SetLabelSize(0);
383  hh->GetYaxis()->SetNdivisions(0);
384 
385  hh->Draw();
386 // }
387 
388  for (int ic = 0; ic < 20; ic++) cols[ic] = 0;
389  cols[0] = GetLevelEnergy(0);
390 
391  icol = 0;
392  for (int ii = 0; ii < GetNLevels(); ii++) {
393  for (int ic = 0; ic < TMath::Max(ii, 20); ic++) {
394  if ((GetLevelEnergy(ii) - cols[ic] > dy)) {
395  cols[ic] = GetLevelEnergy(ii);
396  icol = ic;
397  break;
398  }
399  }
400 
401  TLine* ll = new TLine(0.5 + dx * icol, GetLevelEnergy(ii), ddx + .5 + dx * icol, GetLevelEnergy(ii));
402  ll->Draw("same");
403  TString jpi = GetJPiStr(ii);
404  jpi.ReplaceAll("+", "^{+}");
405  jpi.ReplaceAll("-", "^{-}");
406  TLatex* tex = new TLatex(.4 + dx * icol, GetLevelEnergy(ii), jpi.Data());
407  tex->SetTextAlign(32);
408  tex->SetTextFont(133);
409  tex->SetTextSize(txs);
410  // tex->Draw();
411 
412  tex = new TLatex(ddx + .6 + dx * icol, GetLevelEnergy(ii), Form("%d", TMath::Nint(GetLevelEnergy(ii)))); //GetEGammaStr(ii));
413  tex->SetTextAlign(12);
414  tex->SetTextFont(133);
415  tex->SetTextSize(txs);
416  tex->Draw();
417  }
418 
419  TLatex* tte = new TLatex(0.5, 0.95, Form("^{%d}%s", fCompNuc->GetA(), fCompNuc->GetSymbol("EL")));
420  tte->SetNDC(1);
421  tte->SetTextAlign(23);
422  tte->SetTextFont(133);
423  tte->SetTextSize(txs);
424  tte->Draw();
425 
426  hh->GetXaxis()->SetLimits(0, dx * (ncol + 0.5));
427 }
428 
429 
430 
432 
433 void KVLevelScheme::DrawThreshold(const char* symb, Option_t* option, double ex)
434 {
435  TString opt = option;
436  ncol++;
437  KVNucleus a(symb);
438 
439  KVNucleus tmp = *fCompNuc - a;
440  double qa = tmp.GetExcitEnergy() * -1.;
441 
442  TLatex* tte = 0;
443  TLine* lq = 0;
444 
445  TString decay = Form("^{%d}%s + ^{%d}%s", a.GetA(), a.GetSymbol("EL"), tmp.GetA(), tmp.GetSymbol("EL"));
446  tte = new TLatex(0.5 + (0.5 * ddx) + dx * (ncol - 1), qa * 1000 - 100, decay.Data());
447  tte->SetTextAlign(23);
448  tte->SetTextFont(133);
449  tte->SetTextSize(txs);
450  tte->Draw();
451 
452 
453  if (opt.Contains("l")) {
454  lq = new TLine(0.5, qa * 1000, 0.5 + dx * (ncol - 1), qa * 1000);
455  lq->SetLineColor(kGray);
456  lq->SetLineStyle(7);
457  lq->Draw();
458  }
459 
460  lq = new TLine(0.5 + dx * (ncol - 1), qa * 1000, 0.5 + ddx + dx * (ncol - 1), qa * 1000);
461  lq->Draw();
462 
463  tte = new TLatex(ddx + .6 + dx * (ncol - 1), qa * 1000, Form("%d", TMath::Nint(1000 * qa)));
464  tte->SetTextAlign(12);
465  tte->SetTextFont(133);
466  tte->SetTextSize(txs);
467  tte->Draw();
468 
469  if (ex > 0) {
470  a.SetExcitEnergy(ex / 1000.);
471  tmp = *fCompNuc - a;
472  qa = tmp.GetExcitEnergy() * -1.;
473 
474  if (opt.Contains("l")) {
475  lq = new TLine(0.5, qa * 1000, 0.5 + dx * (ncol - 1), qa * 1000);
476  lq->SetLineColor(kGray);
477  lq->SetLineStyle(7);
478  lq->Draw();
479  }
480 
481  lq = new TLine(0.5 + dx * (ncol - 1), qa * 1000, 0.5 + ddx + dx * (ncol - 1), qa * 1000);
482  lq->Draw();
483  tte = new TLatex(ddx + .6 + dx * (ncol - 1), qa * 1000, Form("%d", TMath::Nint(1000 * qa)));
484  tte->SetTextAlign(12);
485  tte->SetTextFont(133);
486  tte->SetTextSize(txs);
487  tte->Draw();
488  }
489  cc->SetWindowSize((ncol) * (dx) * 0.35 * 400, 800);
490  hh->GetXaxis()->SetLimits(0, dx * (ncol + 0.5));
491 }
492 
493 
494 
496 
497 double KVLevelScheme::GetThreshold(const char* outnuc)
498 {
499  if (!strcmp(outnuc, "")) outnuc = "1H";
500  KVNucleus a(outnuc);
501  KVNucleus tmp = *fCompNuc - a;
502  return tmp.GetExcitEnergy() * -1000.; //returns the threshold in keV
503 }
504 
505 
506 
508 
509 void KVLevelScheme::SetDecayProduct(KVNucleus* nuc, double excit_energy)
510 {
511  fDecayProd = nuc;
512  fDecayProd->SetExcitEnergy(excit_energy * 0.001);
513  KVNucleus tmp = *fCompNuc - *fDecayProd;
514  fQvalue = tmp.GetExcitEnergy() * -1.;
515 }
516 
517 
int Int_t
#define e(i)
double Double_t
const char Option_t
kGray
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
int * lq
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Excited state of atomic nucleus.
void set(Double_t ee, Double_t ww, Double_t jj, Int_t pi)
Double_t eval(Double_t excit)
Tool to simulate nucleus multi-particle decay.
Definition: KVLevelScheme.h:23
Int_t GetLevelParity(int il)
double EvaluateErel(double *x, double *p)
void SetDrawStyle(double deMin=300., double fullWidth=1.3, double lineWidth=0.6, int textSize=22)
const char * GetEGammaStr(int il)
void DrawThreshold(const char *symb, Option_t *option="", double ex=0.)
double GetThreshold(const char *outnuc="")
static void GetParticlesFromExci(KVNucleus *n1, KVNucleus *n2, double erel, bool randAngle=0, TVector3 *vsrc=0)
virtual ~KVLevelScheme()
Destructor.
static void GetParticlesFromErel(KVNucleus *n1, KVNucleus *n2, double erel, bool randAngle=0, TVector3 *vsrc=0)
Double_t GetLevelEnergy(int il)
Int_t GetLevelSpin(int il)
void ReadLevels()
Add all known levels for current isotope to internal list.
void SetDecayProduct(KVNucleus *nuc, double excit_energy=0)
void Draw(Option_t *option="")
double Evaluate(double *x, double *p)
const char * GetJPiStr(int il)
void GetRandomParticles(KVNucleus *n1, KVNucleus *n2, double T, bool randAngle=0, TVector3 *vsrc=0)
Double_t GetLevelWidth(int il)
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:108
const Char_t * GetSymbol(Option_t *opt="") const
Definition: KVNucleus.cpp:43
void SetExcitEnergy(Double_t e)
Definition: KVNucleus.cpp:867
Double_t GetExcitEnergy() const
Definition: KVNucleus.h:257
Int_t GetA() const
Definition: KVNucleus.cpp:805
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:776
void SetTheta(Double_t theta)
Definition: KVParticle.h:696
void SetVelocity(const TVector3 &)
Set velocity of particle (in cm/ns units)
void SetKE(Double_t ecin)
Definition: KVParticle.cpp:246
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
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 RemoveAllExtraWhiteSpace()
Definition: KVString.cpp:1253
virtual void SetTextAlign(Short_t align=11)
virtual void SetTextFont(Font_t tfont=62)
virtual void SetTextSize(Float_t tsize=1)
virtual void Draw(Option_t *option="")
Double_t Rndm() override
TRotation & SetXEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Int_t Atoi() const
const char * Data() const
Bool_t EqualTo(const char *cs, ECaseCompare cmp=kExact) const
void ToUpper()
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
void SetOptStat(Int_t stat=1)
virtual void SetNDC(Bool_t isNDC=kTRUE)
Double_t x[n]
Double_t ex[n]
double T(double x)
double max(double x, double y)
Double_t ACos(Double_t)
Int_t Nint(T x)
Double_t Exp(Double_t x)
constexpr Double_t Pi()
Double_t Max(Double_t a, Double_t b)
TArc a
auto * tt
ClassImp(TPyArg)