10 #include <FairLogger.h>
11 #include <FairParticle.h>
12 #include <FairPrimaryGenerator.h>
13 #include <FairRunSim.h>
15 #include <TDatabasePDG.h>
16 #include <TGenPhaseSpace.h>
17 #include <TLorentzVector.h>
19 #include <TParticle.h>
20 #include <TParticlePDG.h>
33 constexpr
float amu = 931.494;
35 Int_t AtTPCIonDecay::fgNIon = 0;
37 constexpr
auto cRED =
"\033[1;31m";
40 constexpr
auto cGREEN =
"\033[1;32m";
41 constexpr
auto cBLUE =
"\033[1;34m";
46 : fMult(0), fPx(0.), fPy(0.), fPz(0.), fVx(0.), fVy(0.), fVz(0.), fIon(0), fParticle(0), fPType(0), fNbCases(0),
47 fSepEne(0), fMasses(0), fQ(0), fPxBeam(0.), fPyBeam(0.), fPzBeam(0.)
55 std::vector<std::vector<Int_t>> *q, std::vector<std::vector<Double_t>> *mass, Int_t ZB,
56 Int_t AB, Double_t BMass, Double_t TMass, Double_t ExEnergy, std::vector<Double_t> *SepEne)
57 : fMult(0), fNbCases(a->size()), fPx(0.), fPy(0.), fPz(0.), fVx(0.), fVy(0.), fVz(0.), fIon(0), fParticle(0),
58 fPType(0), fSepEne(0), fMasses(0), fQ(0), fPxBeam(0.), fPyBeam(0.), fPzBeam(0.)
65 for (Int_t i = 0; i < fNbCases; i++)
66 fMult.push_back(a->at(i).size());
67 fParticle.resize(fNbCases);
68 fIon.resize(fNbCases);
69 fPType.resize(fNbCases);
73 fBeamMass = BMass *
amu / 1000.0;
74 fTargetMass = TMass *
amu / 1000.0;
77 fIsSequentialDecay = kFALSE;
80 FairRunSim *run = FairRunSim::Instance();
82 std::cout <<
"-E- FairIonGenerator: No FairRun instantised!" << std::endl;
83 Fatal(
"FairIonGenerator",
"No FairRun instantised!");
87 for (Int_t k = 0; k < fNbCases; k++) {
88 for (Int_t i = 0; i < fMult.at(k); i++) {
90 std::unique_ptr<FairIon> IonBuff =
nullptr;
91 std::unique_ptr<FairParticle> ParticleBuff =
nullptr;
92 sprintf(buffer,
"Product_Ion_dec%d_%d", k, i);
93 if (a->at(k).at(i) != 1) {
94 IonBuff = std::make_unique<FairIon>(buffer, z->at(k).at(i), a->at(k).at(i), q->at(k).at(i), 0.0,
95 mass->at(k).at(i) *
amu / 1000.0);
96 ParticleBuff = std::make_unique<FairParticle>(
"dummyPart", 1, 1, 1.0, 0, 0.0, 0.0);
97 fPType.at(k).push_back(
"Ion");
98 run->AddNewIon(IonBuff.get());
100 }
else if (a->at(k).at(i) == 1 && z->at(k).at(i) == 1) {
101 IonBuff = std::make_unique<FairIon>(buffer, z->at(k).at(i), a->at(k).at(i), q->at(k).at(i), 0.0,
102 mass->at(k).at(i) *
amu / 1000.0);
103 auto *kProton =
new TParticle();
104 kProton->SetPdgCode(2212);
105 ParticleBuff = std::make_unique<FairParticle>(2212, kProton);
106 fPType.at(k).push_back(
"Proton");
108 }
else if (a->at(k).at(i) == 1 && z->at(k).at(i) == 0) {
109 IonBuff = std::make_unique<FairIon>(buffer, z->at(k).at(i), a->at(k).at(i), q->at(k).at(i), 0.0,
110 mass->at(k).at(i) *
amu / 1000.0);
111 auto *kNeutron =
new TParticle();
112 kNeutron->SetPdgCode(2112);
113 ParticleBuff = std::make_unique<FairParticle>(2112, kNeutron);
114 fPType.at(k).push_back(
"Neutron");
116 fIon.at(k).push_back(std::move(IonBuff));
117 fParticle.at(k).push_back(std::move(ParticleBuff));
127 Bool_t IsGoodCase = kFALSE;
129 Double_t excitationEnergy = 0.0;
131 LOG(INFO) <<
cBLUE <<
" AtTPCIonDecay - Decay energy - Excitation energy from reaction : " << ExEject
132 <<
" and from task : " << fExEnergy
134 << fIsSequentialDecay <<
cNORMAL <<
"\n";
136 <<
" AtTPCIonDecay - Warning: Temporary warning message to control the flow of generators.Please, check "
137 "that if the decay comes from beam fusion, the energy from reaction is 0"
140 if (ExEject > 0.0 && !fIsSequentialDecay) {
142 <<
" AtTPCIonDecay - Warning, Inconsistent variables: Recoil excitation energy from Vertex propagator "
143 "greater than 0 but sequential decay not enabled! Continue at your own risk!"
146 }
else if (fIsSequentialDecay && fExEnergy > 0.0) {
149 <<
" AtTPCIonDecay - Warning, Inconsistent variables: Sequential decay should take the Ex energy from "
150 "the reaction generator! Continue at your own risk!"
153 }
else if (ExEject > 0.0 && fExEnergy > 0.0) {
156 <<
" AtTPCIonDecay - Warning, Inconsistent variables: Both, excitation energy from Vertex propagator and "
157 "excitation energy from task (introduced through the macro) are positive! Continue at your own risk!"
161 std::vector<Int_t> GoodCases;
164 for (Int_t i = 0; i < fNbCases; i++) {
167 GoodCases.push_back(i);
172 int RandVar = (int)(GoodCases.size()) * gRandom->Uniform();
173 auto it = GoodCases.begin();
174 std::advance(it, RandVar);
180 Double_t mass_1[10] = {0.0};
183 TLorentzVector fEnergyImpulsionLab_beam;
184 TLorentzVector fEnergyImpulsionLab_Total;
185 TLorentzVector fEnergyImpulsionLab_target;
186 TLorentzVector fEnergyImpulsionFinal;
188 TVector3 fImpulsionLab_beam;
189 std::vector<TLorentzVector *> p_vector;
190 TGenPhaseSpace event1;
196 fPx.resize(fMult.at(Case));
197 fPy.resize(fMult.at(Case));
198 fPz.resize(fMult.at(Case));
204 if (fIsSequentialDecay)
211 excitationEnergy = ExEject;
217 excitationEnergy = fExEnergy;
220 TParticlePDG *thisPart0 =
nullptr;
221 thisPart0 = TDatabasePDG::Instance()->GetParticle(
222 fIon.at(Case).at(0)->GetName());
223 int pdgType0 = thisPart0->PdgCode();
225 LOG(INFO) <<
cBLUE <<
" Ejectile info : " << pdgType0 <<
" " << fBeamMass <<
" " << fPxBeam <<
" " << fPyBeam
226 <<
" " << fPzBeam <<
" " << fBeamEnergy <<
" " << excitationEnergy <<
cNORMAL <<
"\n";
230 fImpulsionLab_beam = TVector3(fPxBeam, fPyBeam, fPzBeam);
231 fEnergyImpulsionLab_beam = TLorentzVector(fImpulsionLab_beam, fBeamMass + fBeamEnergy + ExEject);
232 fEnergyImpulsionLab_target = TLorentzVector(TVector3(0, 0, 0), fTargetMass);
234 if (fTargetMass > 0 && fIsSequentialDecay) {
237 <<
" AtTPCIonDecay - Warning, Inconsistent variables: Target Impulsion included in sequential decay. "
238 "Continue at your own risk!"
242 fEnergyImpulsionLab_Total = fEnergyImpulsionLab_beam + fEnergyImpulsionLab_target;
244 s = fEnergyImpulsionLab_Total.M2();
247 for (Int_t i = 0; i < fMult.at(Case); i++) {
248 M_tot += fMasses.at(Case).at(i) *
amu / 1000.0;
249 mass_1[i] = fMasses.at(Case).at(i) *
amu / 1000.0;
250 std::cout << fMasses.at(Case).at(i) *
amu / 1000.0 <<
" " << M_tot <<
" " << fBeamMass <<
" "
251 << fBeamMass - M_tot <<
" " << ExEject <<
" " << sqrt(s) <<
" " << (sqrt(s) - M_tot) * 1000.0
258 if (s > pow(M_tot, 2)) {
261 event1.SetDecay(fEnergyImpulsionLab_Total, fMult.at(Case), mass_1);
263 std::vector<Double_t> KineticEnergy;
264 std::vector<Double_t> ThetaLab;
266 LOG(INFO) <<
cBLUE <<
" AtTPCIonDecay - Phase Space Information "
268 for (Int_t i = 0; i < fMult.at(Case); i++) {
269 p_vector.push_back(event1.GetDecay(i));
270 fPx.at(i) = p_vector.at(i)->Px();
271 fPy.at(i) = p_vector.at(i)->Py();
272 fPz.at(i) = p_vector.at(i)->Pz();
273 KineticEnergy.push_back((p_vector.at(i)->E() - mass_1[i]) * 1000.0);
274 ThetaLab.push_back(p_vector.at(i)->Theta() * 180. / TMath::Pi());
275 LOG(INFO) <<
" Particle " << i <<
" - TKE (MeV) : " << KineticEnergy.at(i)
276 <<
" - Lab Angle (deg) : " << ThetaLab.at(i) <<
"\n";
282 LOG(INFO) <<
cYELLOW <<
"AtTPCIonDecay - Warning, kinematical conditions for decay not fulfilled " <<
cNORMAL
284 LOG(INFO) <<
cYELLOW <<
" s = " << s <<
" - pow(M_tot,2) = " << pow(M_tot, 2) <<
cNORMAL <<
"\n";
289 for (Int_t i = 0; i < fMult.at(Case); i++) {
290 TParticlePDG *thisPart =
nullptr;
292 if (fPType.at(Case).at(i) ==
"Ion")
293 thisPart = TDatabasePDG::Instance()->GetParticle(fIon.at(Case).at(i)->GetName());
294 else if (fPType.at(Case).at(i) ==
"Proton")
295 thisPart = TDatabasePDG::Instance()->GetParticle(fParticle.at(Case).at(i)->GetName());
296 else if (fPType.at(Case).at(i) ==
"Neutron")
297 thisPart = TDatabasePDG::Instance()->GetParticle(fParticle.at(Case).at(i)->GetName());
300 if (fPType.at(Case).at(i) ==
"Ion")
301 std::cout <<
"-W- FairIonGenerator: Ion " << fIon.at(Case).at(i)->GetName() <<
" not found in database!"
303 else if (fPType.at(Case).at(i) ==
"Proton")
304 std::cout <<
"-W- FairIonGenerator: Particle " << fParticle.at(Case).at(i)->GetName()
305 <<
" not found in database!" << std::endl;
306 else if (fPType.at(Case).at(i) ==
"Neutron")
307 std::cout <<
"-W- FairIonGenerator: Particle " << fParticle.at(Case).at(i)->GetName()
308 <<
" not found in database!" << std::endl;
312 int pdgType = thisPart->PdgCode();
332 primGen->AddTrack(pdgType, fPx.at(i), fPy.at(i), fPz.at(i), fVx, fVy, fVz);