9 #include "ERDecayEXP1811.h" 16 #include "TVirtualMC.h" 17 #include "TLorentzVector.h" 18 #include "TMCProcess.h" 22 #include "FairRunSim.h" 23 #include "FairLogger.h" 25 #include "ERDecayMCEventHeader.h" 26 #include "EREXP1811EventHeader.h" 27 #include "ERMCEventHeader.h" 29 #include "G4IonTable.hh" 31 ERDecayEXP1811::ERDecayEXP1811():
44 fIs7HUserMassSet(false),
45 fIs7HExcitationSet(false),
49 fDecayFileFinished(kFALSE),
50 fDecayFileCurrentEvent(0)
52 fRnd =
new TRandom3();
54 fRnd2 =
new TRandom3();
56 fReactionPhaseSpace =
new TGenPhaseSpace();
57 fDecayPhaseSpace =
new TGenPhaseSpace();
58 FairRunSim* run = FairRunSim::Instance();
59 fUnstableIon7H =
new FairIon(
"7H", 1, 7, 1);
60 fIon3He =
new FairIon(
"3He", 2, 3, 2);
61 run->AddNewIon(fUnstableIon7H);
62 run->AddNewIon(fIon3He);
64 fLv7H =
new TLorentzVector();
65 fLv3He =
new TLorentzVector();
69 ERDecayEXP1811::~ERDecayEXP1811() {
70 if (fDecayFile.is_open())
72 if (fDecayFilePath ==
""){
84 void ERDecayEXP1811::SetH7Exitation(Double_t excMean, Double_t fwhm, Double_t distibWeight) {
85 f7HExcitationMean.push_back(excMean);
86 f7HExcitationSigma.push_back(fwhm / 2.355);
87 if (!fIs7HExcitationSet) {
88 f7HExcitationWeight.push_back(distibWeight);
89 fIs7HExcitationSet =
true;
92 f7HExcitationWeight.push_back(f7HExcitationWeight.back() + distibWeight);
96 Bool_t ERDecayEXP1811::Init() {
98 cout <<
"Decayer Init." << endl;
100 f8He = TDatabasePDG::Instance()->GetParticle(
"8He");
102 std::cerr <<
"-W- ERDecayEXP1811: Ion 8He not found in database!" << endl;
106 f2H = TDatabasePDG::Instance()->GetParticle(
"Deuteron");
108 std::cerr <<
"-W- ERDecayEXP1811: Ion Deuteron not found in database!" << endl;
112 f7H = TDatabasePDG::Instance()->GetParticle(
"7H");
114 std::cerr <<
"-W- ERDecayEXP1811: Ion 7H not found in database!" << endl;
118 f3He = TDatabasePDG::Instance()->GetParticle(fIon3He->GetName());
120 std::cerr <<
"-W- ERDecayEXP1811: Ion 3He not found in database!" << endl;
124 f3H = TDatabasePDG::Instance()->GetParticle(
"Triton");
126 std::cerr <<
"-W- ERDecayEXP1811: Ion Triton not found in database!" << endl;
130 fn = TDatabasePDG::Instance()->GetParticle(
"neutron");
132 std::cerr <<
"-W- ERDecayEXP1811: Particle neutron not found in database!" << endl;
135 if (fIs7HUserMassSet) {
136 fUnstableIon7H->SetMass(f7HMass / .931494028);
138 f7HMass = f7H->Mass();
140 CalculateTargetParameters();
143 if (fDecayFilePath !=
""){
144 LOG(INFO) <<
"Use decay kinematics from external text file" << FairLogger::endl;
145 fDecayFile.open(fDecayFilePath.Data());
146 if (!fDecayFile.is_open())
147 LOG(FATAL) <<
"Can`t open decay file " << fDecayFilePath << FairLogger::endl;
150 std::getline(fDecayFile,header);
152 fLv3H =
new TLorentzVector();
153 fLvn1 =
new TLorentzVector();
154 fLvn2 =
new TLorentzVector();
155 fLvn3 =
new TLorentzVector();
156 fLvn4 =
new TLorentzVector();
163 Bool_t ERDecayEXP1811::Stepping() {
164 if(!fDecayFinish && gMC->TrackPid() == 1000020080
167 if (!fIsInterationPointFound) {
169 fDecayFinish = kTRUE;
172 fDistanceFromEntrance = 0;
175 gMC->SetMaxStep(fMinStep);
176 TLorentzVector curPos;
177 gMC->TrackPosition(curPos);
178 Double_t trackStep = gMC->TrackStep();
179 fDistanceFromEntrance += trackStep;
182 if (fDistanceFromEntrance > fDistanceToInteractPoint) {
186 TLorentzVector lv8He;
187 gMC->TrackMomentum(lv8He);
189 if (lv8He.P() == 0) {
193 TLorentzVector lv2H(0., 0., 0., 1.875612);
194 TLorentzVector lvReaction;
195 lvReaction = lv8He + lv2H;
197 const TVector3 boost = lvReaction.BoostVector();
199 TLorentzVector lv8HeCM, lv2HCM;
202 lv8HeCM.Boost(-boost);
203 lv2HCM.Boost(-boost);
204 ECM = lv8HeCM(3) + lv2HCM(3);
206 Int_t reactionHappen = kFALSE;
208 Double_t decay7HMass;
209 Int_t reactionAttempsCounter = 0;
210 Double_t excitation = 0;
211 while (reactionHappen==kFALSE) {
212 decay7HMass = f7HMass;
213 if (fIs7HExcitationSet) {
214 Double_t randWeight = gRandom->Uniform(0., f7HExcitationWeight.back());
215 Int_t distribNum = 0;
217 for (; distribNum < f7HExcitationWeight.size(); distribNum++) {
218 if (randWeight < f7HExcitationWeight[distribNum]) {
222 excitation = gRandom->Gaus(f7HExcitationMean[distribNum], f7HExcitationSigma[distribNum]);
223 fUnstableIon7H->SetExcEnergy(excitation);
225 decay7HMass += excitation;
226 const float he3_mass = G4IonTable::GetIonTable()->GetIon(2,3)->GetPDGMass() * 1e-3;
227 if((ECM - he3_mass - decay7HMass) > 0) {
228 reactionHappen = kTRUE;
229 LOG(DEBUG) <<
"[ERDecayEXP1811] Reaction is happen" << endl;
231 reactionAttempsCounter++;
232 if (reactionAttempsCounter > 1000){
233 LOG(DEBUG) <<
"[ERDecayEXP1811] Reaction is forbidden for this CM energy" << endl;
234 fDecayFinish = kTRUE;
239 ReactionPhaseGenerator(ECM, decay7HMass);
241 fLv3He->Boost(boost);
244 if (!DecayPhaseGenerator(excitation)){
245 fDecayFinish = kTRUE;
249 Int_t He8TrackNb, H7TrackNb, He3TrackNb, H3TrackNb, n1TrackNb, n2TrackNb, n3TrackNb, n4TrackNb;
251 He8TrackNb = gMC->GetStack()->GetCurrentTrackNumber();
260 gMC->GetStack()->PushTrack(1, He8TrackNb, f3He->PdgCode(),
261 fLv3He->Px(), fLv3He->Py(), fLv3He->Pz(),
262 fLv3He->E(), curPos.X(), curPos.Y(), curPos.Z(),
263 gMC->TrackTime(), 0., 0., 0.,
264 kPDecay, He3TrackNb, f3He->Mass(), 0);
265 gMC->GetStack()->PushTrack(1, He8TrackNb, f3H->PdgCode(),
266 fLv3H->Px(), fLv3H->Py(), fLv3H->Pz(),
267 fLv3H->E(), curPos.X(), curPos.Y(), curPos.Z(),
268 gMC->TrackTime(), 0., 0., 0.,
269 kPDecay, H3TrackNb, f3H->Mass(), 0);
270 gMC->GetStack()->PushTrack(1, He8TrackNb, fn->PdgCode(),
271 fLvn1->Px(),fLvn1->Py(),fLvn1->Pz(),
272 fLvn1->E(), curPos.X(), curPos.Y(), curPos.Z(),
273 gMC->TrackTime(), 0., 0., 0.,
274 kPDecay, n1TrackNb, fn->Mass(), 0);
275 gMC->GetStack()->PushTrack(1, He8TrackNb, fn->PdgCode(),
276 fLvn2->Px(),fLvn2->Py(),fLvn2->Pz(),
277 fLvn2->E(), curPos.X(), curPos.Y(), curPos.Z(),
278 gMC->TrackTime(), 0., 0., 0.,
279 kPDecay, n2TrackNb, fn->Mass(), 0);
280 gMC->GetStack()->PushTrack(1, He8TrackNb, fn->PdgCode(),
281 fLvn3->Px(),fLvn3->Py(),fLvn3->Pz(),
282 fLvn3->E(), curPos.X(), curPos.Y(), curPos.Z(),
283 gMC->TrackTime(), 0., 0., 0.,
284 kPDecay, n3TrackNb, fn->Mass(), 0);
285 gMC->GetStack()->PushTrack(1, He8TrackNb, fn->PdgCode(),
286 fLvn4->Px(),fLvn4->Py(),fLvn4->Pz(),
287 fLvn4->E(), curPos.X(), curPos.Y(), curPos.Z(),
288 gMC->TrackTime(), 0., 0., 0.,
289 kPDecay, n4TrackNb, fn->Mass(), 0);
291 fDecayFinish = kTRUE;
292 gMC->SetMaxStep(100.);
294 FairRunSim* run = FairRunSim::Instance();
295 if (TString(run->GetMCEventHeader()->ClassName()).Contains(
"ERDecayMCEventHeader")){
297 header->SetDecayPos(curPos.Vect());
298 header->SetInputIon(He8TrackNb);
299 header->AddOutputParticle(H7TrackNb);
300 header->AddOutputParticle(He3TrackNb);
301 header->AddOutputParticle(H3TrackNb);
302 header->AddOutputParticle(n1TrackNb);
303 header->AddOutputParticle(n2TrackNb);
304 header->AddOutputParticle(n3TrackNb);
305 header->AddOutputParticle(n4TrackNb);
307 if (TString(run->GetMCEventHeader()->ClassName()).Contains(
"EREXP1811EventHeader")){
309 header->SetData(curPos.Vect(), lv8He, lv2H, *fLv3He, *fLv3H, *fLv7H, *fLvn1, *fLvn2, *fLvn3, *fLvn4);
310 header->SetTrigger(1);
318 void ERDecayEXP1811::BeginEvent() {
319 fDecayFinish = kFALSE;
320 fIsInterationPointFound = kFALSE;
321 fTargetReactZ = fRnd->Uniform(-fTargetThickness / 2, fTargetThickness / 2);
322 FairRunSim* run = FairRunSim::Instance();
326 void ERDecayEXP1811::FinishEvent() {
327 FairRunSim* run = FairRunSim::Instance();
328 if (TString(run->GetMCEventHeader()->ClassName()).Contains(
"ERDecayMCEventHeader")){
332 if (TString(run->GetMCEventHeader()->ClassName()).Contains(
"EREXP1811EventHeader")){
340 Double_t m1 = h7Mass;
341 Double_t m2 = G4IonTable::GetIonTable()->GetIon(2,3)->GetPDGMass() * 1e-3;
345 Double_t E1 = 0.5 * (Ecm * Ecm + m1 * m1 - m2 * m2) / Ecm;
348 Double_t Pcm = TMath::Sqrt(E1 * E1 - m1 * m1);
352 thetaCM = TMath::ACos(gRandom->Uniform(-1, 1));
354 thetaCM =
fADFunction->GetRandom(fThetaMin, fThetaMax)*TMath::DegToRad();
356 Double_t phi = gRandom->Uniform(0., 2. * TMath::Pi());
358 Pcmv.SetMagThetaPhi(Pcm, thetaCM, phi);
360 fLv7H->SetXYZM(0., 0., 0., 0.);
361 fLv3He->SetXYZM(0., 0., 0., 0.);
362 fLv7H->SetXYZM(Pcmv(0), Pcmv(1), Pcmv(2), m1);
363 fLv3He->SetXYZM(-Pcmv(0), -Pcmv(1), -Pcmv(2), m2);
367 Bool_t ERDecayEXP1811::DecayPhaseGenerator(
const Double_t excitation) {
368 if (fDecayFilePath ==
""){
369 Double_t decayMasses[5];
370 decayMasses[0] = f3H->Mass();
371 decayMasses[1] = fn->Mass();
372 decayMasses[2] = fn->Mass();
373 decayMasses[3] = fn->Mass();
374 decayMasses[4] = fn->Mass();
375 fDecayPhaseSpace->SetDecay(*fLv7H, 5, decayMasses);
376 fDecayPhaseSpace->Generate();
377 fLv3H = fDecayPhaseSpace->GetDecay(0);
378 fLvn1 = fDecayPhaseSpace->GetDecay(1);
379 fLvn2 = fDecayPhaseSpace->GetDecay(2);
380 fLvn3 = fDecayPhaseSpace->GetDecay(3);
381 fLvn4 = fDecayPhaseSpace->GetDecay(4);
384 if (fDecayFile.eof()){
385 LOG(ERROR) <<
"Decay file finished! There are no more events in file " << fDecayFilePath
386 <<
" to be processed." << FairLogger::endl;
389 std::string event_line;
390 std::getline(fDecayFile,event_line);
391 std::istringstream iss(event_line);
392 std::vector<std::string> outputs_components((std::istream_iterator<std::string>(iss)),
393 std::istream_iterator<std::string>());
394 if (outputs_components.size() < 5*3){
395 LOG(ERROR) <<
"Wrong components number in raw in decay file!" << FairLogger::endl;
399 TVector3 pn1(std::stod(outputs_components[0]),std::stod(outputs_components[1]),
400 std::stod(outputs_components[2]));
401 TVector3 pn2(std::stod(outputs_components[3]),std::stod(outputs_components[4]),
402 std::stod(outputs_components[5]));
403 TVector3 pn3(std::stod(outputs_components[6]),std::stod(outputs_components[7]),
404 std::stod(outputs_components[8]));
405 TVector3 pn4(std::stod(outputs_components[9]),std::stod(outputs_components[10]),
406 std::stod(outputs_components[11]));
407 TVector3 p3H(std::stod(outputs_components[12]),std::stod(outputs_components[13]),
408 std::stod(outputs_components[14]));
410 const auto excitationScale = excitation > 0. ? sqrt(excitation / fDecayFileExcitation) : 1.;
411 const auto MeV2GeV = 1./1000.;
412 const auto scale = excitationScale * MeV2GeV;
418 const auto fill_output_lorentz_vectors_in_lab =
419 [
this](TLorentzVector* lv,
const TVector3& p,
const Double_t mass) {
420 lv->SetXYZM(p.X(), p.Y(), p.Z(), mass);
421 lv->Boost(fLv7H->BoostVector());
423 fill_output_lorentz_vectors_in_lab(fLvn1, pn1, fn->Mass());
424 fill_output_lorentz_vectors_in_lab(fLvn2, pn2, fn->Mass());
425 fill_output_lorentz_vectors_in_lab(fLvn3, pn3, fn->Mass());
426 fill_output_lorentz_vectors_in_lab(fLvn4, pn4, fn->Mass());
427 fill_output_lorentz_vectors_in_lab(fLv3H, p3H, f3H->Mass());
432 Double_t ERDecayEXP1811::ADEvaluate(Double_t *x, Double_t *p) {
433 if (fADInput->IsZombie()) {
434 Error(
"ERDecayEXP1811::ADEvaluate",
"AD input was not loaded");
438 return fADInput->Eval(x[0]);
443 TString ADFilePath = gSystem->Getenv(
"VMCWORKDIR");
444 ADFilePath +=
"/input/" + ADFile;
446 f.open(ADFilePath.Data());
448 LOG(FATAL) <<
"Can't open file " << ADFilePath << FairLogger::endl;
450 Int_t nPoints = std::count(std::istreambuf_iterator<char>(f),
451 std::istreambuf_iterator<char>(),
'\n');
452 f.seekg(0, std::ios::beg);
453 TVectorD tet(nPoints);
454 TVectorD sigma(nPoints);
455 LOG(DEBUG2) <<
"nPoints = " << nPoints << FairLogger::endl;
459 if (i == nPoints)
break;
460 f >> tet(i) >> sigma(i);
461 LOG(DEBUG2) << i <<
": " << tet(i) <<
"\t" << sigma(i) << FairLogger::endl;
464 fADInput =
new TGraph(tet, sigma);
465 if (fADInput->GetN() <= 0) {
466 LOG(INFO) <<
"ERDecayEXP1811::SetAngularDistribution: " 467 <<
"Too few inputs for creation of AD function!" << FairLogger::endl;
470 Double_t* angle = fADInput->GetX();
475 fThetaMin = angle[0];
476 fThetaMax = angle[fADInput->GetN()-1];
477 fADFunction =
new TF1(
"angDistr",
this, &ERDecayEXP1811::ADEvaluate,
478 fThetaMin, fThetaMax, 0,
"ERDecayEXP1811",
"ADEvaluate");
void SetAngularDistribution(TString ADfile)
Sets distribution is contained in file.
TF1 * fADFunction
distribution (angular distribution) graph containing AD input
TString GetInteractionVolumeName()
Method returns interaction volume name.
void ReactionPhaseGenerator(Double_t Ecm, Double_t h7Mass)
Body reaction in phase space approach.
Bool_t FindInteractionPoint()