10 #include <FairParticle.h>
11 #include <FairPrimaryGenerator.h>
12 #include <FairRunSim.h>
14 #include <TDatabasePDG.h>
17 #include <TParticle.h>
18 #include <TParticlePDG.h>
32 Int_t AtTPCXSReader::fgNIon = 0;
41 Int_t mult, std::vector<Double_t> *px, std::vector<Double_t> *py,
42 std::vector<Double_t> *pz, std::vector<Double_t> *mass)
43 : fMult(mult), fPx(0.), fPy(0.), fPz(0.), fVx(0.), fVy(0.), fVz(0.), fIon(0), fPType(0.), fQ(0)
52 TString dir = getenv(
"VMCWORKDIR");
53 TString XSFileName = dir +
"/AtGenerators/" + fXSFileName;
54 std::cout <<
" AtTPCXSReader: Opening input file " << XSFileName << std::endl;
55 auto fInputXSFile = std::ifstream(XSFileName);
58 if (!fInputXSFile.is_open())
59 Fatal(
"AtTPCXSReader",
"Cannot open input file.");
61 std::cout <<
"AtTPCXSReader: opening PACE cross sections..." << std::endl;
67 for (Int_t energies = 0; energies < 31; energies++) {
68 fInputXSFile >> ene[energies];
70 for (Int_t xsvalues = 0; xsvalues < 18; xsvalues++) {
71 fInputXSFile >> xs[energies][xsvalues];
77 fh_pdf =
new TH2F(
"pdf",
"pdf", 31, 0, 31, 18, 0, 180);
78 for (Int_t energies = 0; energies < 31; energies++) {
79 for (Int_t xsvalues = 0; xsvalues < 18; xsvalues++) {
80 fh_pdf->SetBinContent(energies + 1, xsvalues + 1, xs[energies][xsvalues]);
85 auto *kProton =
new TParticle();
86 kProton->SetPdgCode(2212);
88 auto *kNeutron =
new TParticle();
89 kNeutron->SetPdgCode(2112);
92 for (Int_t i = 0; i < fMult; i++) {
93 fPx.push_back(Double_t(a->at(i)) * px->at(i));
94 fPy.push_back(Double_t(a->at(i)) * py->at(i));
95 fPz.push_back(Double_t(a->at(i)) * pz->at(i));
96 Masses.push_back(mass->at(i) * 1000.0);
97 fWm.push_back(mass->at(i) * 1000.0);
99 FairParticle *ParticleBuff;
100 sprintf(buffer,
"Product_Ion%d", i);
103 IonBuff =
new FairIon(buffer, z->at(i), a->at(i), q->at(i), 0.0,
106 new FairParticle(
"dummyPart", 1, 1, 1.0, 0, 0.0, 0.0);
107 fPType.emplace_back(
"Ion");
108 std::cout <<
" Adding : " << buffer << std::endl;
109 }
else if (a->at(i) == 1 && z->at(i) == 1) {
110 IonBuff =
new FairIon(
"dummyIon", 50, 50, 0, 0.0, 100);
111 ParticleBuff =
new FairParticle(2212, kProton);
112 fPType.emplace_back(
"Proton");
113 }
else if (a->at(i) == 1 && z->at(i) == 0) {
114 IonBuff =
new FairIon(
"dummyIon", 50, 50, 0, 0.0, 100);
115 ParticleBuff =
new FairParticle(2112, kNeutron);
116 fPType.emplace_back(
"Neutron");
119 std::cout <<
" Z " << z->at(i) <<
" A " << a->at(i) << std::endl;
121 fIon.push_back(IonBuff);
122 fParticle.push_back(ParticleBuff);
125 FairRunSim *run = FairRunSim::Instance();
127 std::cout <<
"-E- FairIonGenerator: No FairRun instantised!" << std::endl;
128 Fatal(
"FairIonGenerator",
"No FairRun instantised!");
131 for (Int_t i = 0; i < fMult; i++) {
132 if (fPType.at(i) ==
"Ion") {
133 std::cout <<
" In position " << i <<
" adding an : " << fPType.at(i) << std::endl;
134 run->AddNewIon(fIon.at(i));
135 std::cout <<
" fIon name :" << fIon.at(i)->GetName() << std::endl;
136 std::cout <<
" fParticle name :" << fParticle.at(i)->GetName() << std::endl;
137 }
else if (fPType.at(i) ==
"Proton") {
138 std::cout <<
" In position " << i <<
" adding an : " << fPType.at(i) << std::endl;
140 std::cout <<
" fIon name :" << fIon.at(i)->GetName() << std::endl;
141 std::cout <<
" fParticle name :" << fParticle.at(i)->GetName() << std::endl;
142 std::cout << fParticle.at(i)->GetName() << std::endl;
143 }
else if (fPType.at(i) ==
"Neutron") {
144 std::cout <<
" In position " << i <<
" adding an : " << fPType.at(i) << std::endl;
146 std::cout <<
" fIon name :" << fIon.at(i)->GetName() << std::endl;
147 std::cout <<
" fParticle name :" << fParticle.at(i)->GetName() << std::endl;
148 std::cout << fParticle.at(i)->GetName() << std::endl;
155 const Double_t rad2deg = 0.0174532925;
157 std::vector<Double_t> Ang;
158 std::vector<Double_t> Ene;
173 Double_t energyFromPDF, thetaFromPDF;
174 fh_pdf->GetRandom2(energyFromPDF, thetaFromPDF);
176 Ang.push_back(thetaFromPDF * TMath::Pi() / 180);
177 Ene.push_back(energyFromPDF);
184 Double_t pb2 = fBeamEnergy * fBeamEnergy + 2.0 * fBeamEnergy * fWm.at(0);
188 Double_t e = fBeamEnergy + fWm.at(0) + fWm.at(1);
189 Double_t e_cm2 = e * e - pb2;
190 Double_t e_cm = TMath::Sqrt(e_cm2);
191 Double_t t_cm = e_cm - fWm.at(2) - fWm.at(3);
199 Double_t t_scatter = 0;
200 if (t_cm - energyFromPDF > 0)
201 t_scatter = t_cm - energyFromPDF;
203 std::cout <<
"Kinetic Energy of scatter particle negative!" << std::endl;
205 Double_t theta_scatter = 0.05;
207 Ang.push_back(theta_scatter);
208 Ene.push_back(t_scatter);
223 Double_t phi1 = 0., phi2 = 0.;
224 phi1 = 2 * TMath::Pi() * gRandom->Uniform();
225 phi2 = phi1 + TMath::Pi();
231 TVector3 direction1 = TVector3(sin(Ang.at(0)) * cos(phi1), sin(Ang.at(0)) * sin(phi1),
234 TVector3 direction2 = TVector3(sin(Ang.at(1)) * cos(phi2), sin(Ang.at(1)) * sin(phi2),
237 Double_t p2_recoil = Ene.at(0) * Ene.at(0) + 2.0 * Ene.at(0) * fWm.at(3);
238 Double_t p2_scatter = Ene.at(1) * Ene.at(1) + 2.0 * Ene.at(1) * fWm.at(2);
239 if (p2_recoil < 0 || p2_scatter < 0)
240 std::cout <<
"Particle momentum negative!" << std::endl;
242 Double_t p_recoil = TMath::Sqrt(p2_recoil);
243 Double_t p_scatter = TMath::Sqrt(p2_scatter);
245 fPx.at(2) = p_scatter * direction2.X() / 1000.0;
246 fPy.at(2) = p_scatter * direction2.Y() / 1000.0;
247 fPz.at(2) = p_scatter * direction2.Z() / 1000.0;
249 fPx.at(3) = p_recoil * direction1.X() / 1000.0;
250 fPy.at(3) = p_recoil * direction1.Y() / 1000.0;
251 fPz.at(3) = p_recoil * direction1.Z() / 1000.0;
254 for (Int_t i = 0; i < fMult; i++) {
255 TParticlePDG *thisPart;
256 if (fPType.at(i) ==
"Ion")
257 thisPart = TDatabasePDG::Instance()->GetParticle(fIon.at(i)->GetName());
258 else if (fPType.at(i) ==
"Proton")
259 thisPart = TDatabasePDG::Instance()->GetParticle(fParticle.at(i)->GetName());
260 else if (fPType.at(i) ==
"Neutron")
261 thisPart = TDatabasePDG::Instance()->GetParticle(fParticle.at(i)->GetName());
264 if (fPType.at(i) ==
"Ion")
265 std::cout <<
"-W- FairIonGenerator: Ion " << fIon.at(i)->GetName() <<
" not found in database!"
267 else if (fPType.at(i) ==
"Proton")
268 std::cout <<
"-W- FairIonGenerator: Particle " << fParticle.at(i)->GetName() <<
" not found in database!"
270 else if (fPType.at(i) ==
"Neutron")
271 std::cout <<
"-W- FairIonGenerator: Particle " << fParticle.at(i)->GetName() <<
" not found in database!"
276 int pdgType = thisPart->PdgCode();
285 fPType.at(i) ==
"Ion") {
286 std::cout <<
"-I- FairIonGenerator: Generating ions of type " << fIon.at(i)->GetName() <<
" (PDG code "
287 << pdgType <<
")" << std::endl;
288 std::cout <<
" Momentum (" << fPx.at(i) <<
", " << fPy.at(i) <<
", " << fPz.at(i)
289 <<
") Gev from vertex (" << fVx <<
", " << fVy <<
", " << fVz <<
") cm" << std::endl;
290 primGen->AddTrack(pdgType, fPx.at(i), fPy.at(i), fPz.at(i), fVx, fVy, fVz);
292 fPType.at(i) ==
"Proton") {
293 std::cout <<
"-I- FairIonGenerator: Generating ions of type " << fParticle.at(i)->GetName() <<
" (PDG code "
294 << pdgType <<
")" << std::endl;
295 std::cout <<
" Momentum (" << fPx.at(i) <<
", " << fPy.at(i) <<
", " << fPz.at(i)
296 <<
") Gev from vertex (" << fVx <<
", " << fVy <<
", " << fVz <<
") cm" << std::endl;
297 primGen->AddTrack(pdgType, fPx.at(i), fPy.at(i), fPz.at(i), fVx, fVy, fVz);
299 fPType.at(i) ==
"Neutron") {
300 std::cout <<
"-I- FairIonGenerator: Generating ions of type " << fParticle.at(i)->GetName() <<
" (PDG code "
301 << pdgType <<
")" << std::endl;
302 std::cout <<
" Momentum (" << fPx.at(i) <<
", " << fPy.at(i) <<
", " << fPz.at(i)
303 <<
") Gev from vertex (" << fVx <<
", " << fVy <<
", " << fVz <<
") cm" << std::endl;
304 primGen->AddTrack(pdgType, fPx.at(i), fPy.at(i), fPz.at(i), fVx, fVy, fVz);