KaliVeda
Toolkit for HIC analysis
KVGemini.cpp
1 //Created by KVClassFactory on Fri Jul 25 10:05:03 2014
2 //Author: John Frankland,,,
3 #include "TTree.h"
4 
5 #include "KVGemini.h"
6 #include "KVSimEvent.h"
7 #include "KVSimNucleus.h"
8 
9 #include "CNucleus.h"
10 #include "CYrast.h"
11 
13 
14 
15 
16 //CYrast * KVGemini::yrast;
17 
18 
19 
26 KVGemini::KVGemini() : KVBase("gemini++", "Calculate statistical decay of excited nuclei")
27 {
28  // Default constructor
29  // enhanceIMF=true: call CWeight::setWeightIMF() before any decay
30  // (enhance the probabilty of IMF emission)
31  // in this case the event weights returned by
32 
33  // yrast = CYrast::instance(); //!< gives fission barriers and rotational energies
34 
35 }
36 
37 
38 
41 
43 {
44  // Destructor
45 }
46 
47 
48 
70 
71 void KVGemini::DecaySingleNucleus(KVSimNucleus& toDecay, KVSimEvent* decayProducts, bool addRotationalEnergy)
72 {
73  // Calculate decay products of excited nucleus toDecay
74  // Takes into account Z, A, E*, v and angular momentum of nucleus.
75  // Adds all decay products to decayProducts event:
76  // - call decayProducts->Clear() before calling this method
77  // if you just want to keep the products of a single nucleus
78  //
79  //
80  // \param[in] addRotationalEnergy
81  //\parblock
82  // enable or not the addition of the Yrast rotational energy to the excitation energy E*.
83  //
84  // Up to now, two cases are known:
85  // - HIPSE and DIT model => the excitation energy consists just in the thermal energy, the addition of the rotational energy is needed
86  //
87  // This is done because Gemini systematically subtracts the Yrast energy from the given excitation energy of each nucleus
88  // in order to calculate the thermal excitation energy.
89  //\endparblock
90  //
91  // If there is a problem with the decay of the nucleus,
92  // we throw an exception of type gemini_bad_decay
93 
94  CNucleus CN(toDecay.GetZ(), toDecay.GetA());
95  try {
96  // Adding rotationnal energy following K.Mazurek and M. Ciemala suggestion
97  // so if and J>0, E* is never 0 in CNucleus but follow the yrast line
98  // Could induce some problems for very exotic nuclei since yrast->getYrast()
99  // is defined only for a defined range of isotopes per element.
100 
101  // Info("DecaySingleNucleus", "Decaying: Z=%d A=%d E*=%g S=%g", toDecay.GetZ(), toDecay.GetA(), toDecay.GetExcitEnergy(), toDecay.GetAngMom().Mag());
102  if (addRotationalEnergy) CN.setCompoundNucleus(toDecay.GetExcitEnergy() + CYrast::instance()->getYrast(toDecay.GetZ(), toDecay.GetA(), toDecay.GetAngMom().Mag()), toDecay.GetAngMom().Mag());
103  else CN.setCompoundNucleus(toDecay.GetExcitEnergy(), toDecay.GetAngMom().Mag());
104  // set velocity
105  CN.setVelocityCartesian(toDecay.GetVelocity().X(), toDecay.GetVelocity().Y(), toDecay.GetVelocity().Z());
106 
107  // set angle of spin axis
108  CAngle ang(toDecay.GetAngMom().Theta(), toDecay.GetAngMom().Phi());
109  CN.setSpinAxis(ang);
110 
111  // Info("DecaySingleNucleus", "again Decaying: Z=%d A=%d E*=%g S=%g", toDecay.GetZ(), toDecay.GetA(), toDecay.GetExcitEnergy(), toDecay.GetAngMom().Mag());
112 
113  CN.decay();
114  // Info("DecaySingleNucleus", "decay done...");
115 
116  }
117  catch (std::exception& e) {
118  Info("DecaySingleNucleus", "Caught std::exception: %s", e.what());
119  Info("DecaySingleNucleus", "While decaying: Z=%d A=%d E*=%g S=%g", toDecay.GetZ(), toDecay.GetA(), toDecay.GetExcitEnergy(), toDecay.GetAngMom().Mag());
120  CN.reset();
121  throw gemini_bad_decay();
122  }
123  catch (...) {
124  Info("DecaySingleNucleus", "Caught unknown exception");
125  Info("DecaySingleNucleus", "While decaying: Z=%d A=%d E*=%g S=%g", toDecay.GetZ(), toDecay.GetA(), toDecay.GetExcitEnergy(), toDecay.GetAngMom().Mag());
126  CN.reset();
127  throw gemini_bad_decay();
128  }
129 
130  if (CN.abortEvent) { //problem with decay?
131  // throw exception on gemini++ error
132  CN.reset();
133  Info("DecaySingleNucleus", "Bad Gemini decay (CNucleus::abortEvent=true)");
134  Info("DecaySingleNucleus", "While decaying: Z=%d A=%d E*=%g S=%g", toDecay.GetZ(), toDecay.GetA(), toDecay.GetExcitEnergy(), toDecay.GetAngMom().Mag());
135  throw gemini_bad_decay();
136  }
137 
138  CNucleus* nuc = CN.getProducts(0);
139 
140  while (nuc) {
141 
142  KVNucleus* N = decayProducts->AddParticle();
143  N->SetParameter("GEMINI_PARENT_INDEX", part_index); //set parameter with index of parent nucleus in 'hot' event
144  N->SetZ(nuc->iZ);
145  N->SetA(nuc->iA);
146  N->SetExcitEnergy(nuc->fEx);
147  float* v = nuc->getVelocityVector();
148  TVector3 vv(v);
149  N->SetVelocity(vv);
150  nuc = CN.getProducts();
151 
152  }
153 
154  CN.reset();//<-- essential!
155 }
156 
157 
158 
172 
173 void KVGemini::DecayEvent(const KVSimEvent* hot, KVSimEvent* cold, bool addRotationalEnergy)
174 {
175  // Perform statistical decay of all nuclei in 'hot' event
176  // Takes into account Z, A, E*, v and spin of nuclei.
177  // Adds all decay products to 'cold' output event (the event is first reset, i.e. KVEvent::Clear()
178  // method is called, removing all particles AND parameters from the event).
179  //
180  // If there is a problem with the decay of any of the nuclei in the event,
181  // we throw an exception of type gemini_bad_decay
182  //
183  // \param[in] addRotationalEnergy defines whether or not to add Yrast rotational energy to E* of each nucleus
184  //
185  // \sa DecaySingleNucleus()
186  // \note Do not set any parameters for the `cold` event before calling this method, they will be cleared before decay
187 
188  cold->Clear();
189  part_index = 1;
190  for (auto& hotnuc : SimEventIterator(hot)) {
191  try {
192  DecaySingleNucleus(hotnuc, cold, addRotationalEnergy);
193  ++part_index;
194  }
195  catch (...) {
196  // rethrow any exceptions
197  throw;
198  }
199  }
200 }
201 
202 
203 
208 
209 void KVGemini::FillTreeWithEvents(KVSimNucleus& toDecay, bool addRotationalEnergy, Int_t nDecays, TTree* theTree, TString branchname)
210 {
211  // Perform nDecays decays of nucleus toDecay and write the events
212  // containing all decay products of each decay in theTree
213  // If no branchname is given, branch is called "gemini"
214 
215  if (branchname == "") branchname = "gemini";
216  KVSimEvent* decayProducts = new KVSimEvent;
217  KVEvent::MakeEventBranch(theTree, branchname, decayProducts);
218 
219  while (nDecays--) {
220  decayProducts->Clear();
221  try {
222  DecaySingleNucleus(toDecay, decayProducts, addRotationalEnergy);
223  }
224  catch (std::exception& e) {
225  continue;
226  }
227  theTree->Fill();
228  std::cout << "\xd" << "Gemini++ processing, " << nDecays << " decays left ..." << std::flush;
229  }
230  std::cout << std::endl;
231 
232 }
233 
234 
235 
239 
241 {
242  // Maximum angular momentum with non-zero fission barrier (Sierk model)
243  // Only for 19<=Z<=111
244  if (z < 19 || z > 111) {
245  Error("GetMaxSpinWithFissionBarrier", "Only use for 19<=Z<=111");
246  return -1;
247  }
248  float amin = 1.2 * z + 0.01 * pow(z, 2);
249  float amax = 5.8 * z - 0.024 * pow(z, 2);
250 
251  if (a < amin || a > amax) {
252  Error("GetMaxSpinWithFissionBarrier", "Only valid for Z=%d with %d<=A<=%d",
253  z, (int)amin, (int)amax);
254  return -1;
255  }
256  return CYrast::instance()->getJmaxSierk(z, a);
257 }
258 
259 
260 
263 
265 {
266  // Return Rotating Liquid Drop Model fission barrier for given spin in hbar units
267  return CYrast::instance()->getBarrierFissionRLDM(z, a, J);
268 }
269 
270 
273 
275 {
276  // Return Sierk fission barrier for zero angular momentum
277  if (GetMaxSpinWithFissionBarrier(z, a) < 0) return -1;
278  return CYrast::instance()->getBarrierFissionSierk(0.);
279 }
280 
281 
int Int_t
#define e(i)
float Float_t
#define N
winID h TVirtualViewer3D vv
Base class for KaliVeda framework.
Definition: KVBase.h:142
void Clear(Option_t *opt="")
Definition: KVEvent.h:238
static void MakeEventBranch(TTree *tree, const TString &branchname, T &event, Int_t bufsize=10000000)
Definition: KVEvent.h:210
Interface to GEMINI++.
Definition: KVGemini.h:37
void FillTreeWithEvents(KVSimNucleus &, bool, Int_t, TTree *, TString branchname="")
Definition: KVGemini.cpp:209
void DecayEvent(const KVSimEvent *, KVSimEvent *, bool=true)
Definition: KVGemini.cpp:173
Float_t GetMaxSpinWithFissionBarrier(int, int)
Definition: KVGemini.cpp:240
int part_index
Definition: KVGemini.h:39
void DecaySingleNucleus(KVSimNucleus &, KVSimEvent *, bool=true)
Definition: KVGemini.cpp:71
Float_t GetFissionBarrierSierk(int z, int a)
Return Sierk fission barrier for zero angular momentum.
Definition: KVGemini.cpp:274
Float_t GetFissionBarrierRLDM(int z, int a, float J)
Return Rotating Liquid Drop Model fission barrier for given spin in hbar units.
Definition: KVGemini.cpp:264
virtual ~KVGemini()
Destructor.
Definition: KVGemini.cpp:42
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:126
Double_t GetExcitEnergy() const
Definition: KVNucleus.h:283
Int_t GetA() const
Definition: KVNucleus.cpp:802
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:773
TVector3 GetVelocity() const
returns velocity vector in cm/ns units
Container class for simulated nuclei, KVSimNucleus.
Definition: KVSimEvent.h:22
Nucleus in a simulated event.
Definition: KVSimNucleus.h:32
const TVector3 * GetAngMom() const
Definition: KVSimNucleus.h:126
Particle * AddParticle()
Wrapper class for iterating over nuclei in KVSimEvent accessed through base pointer or reference.
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
virtual Int_t Fill()
Double_t Z() const
Double_t Phi() const
Double_t Y() const
Double_t X() const
Double_t Mag() const
Double_t Theta() const
Exception(s) thrown by KVGemini.
Definition: KVGemini.h:60
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
v
TArc a
ClassImp(TPyArg)