1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
#include "ERDecay10Heto8He.h"
|
10
|
|
11
|
#include <iostream>
|
12
|
#include <string>
|
13
|
#include <sstream>
|
14
|
using namespace std;
|
15
|
|
16
|
#include "TVirtualMC.h"
|
17
|
#include "TLorentzVector.h"
|
18
|
#include "TMCProcess.h"
|
19
|
#include "TRandom.h"
|
20
|
#include "TVector.h"
|
21
|
|
22
|
#include "FairRunSim.h"
|
23
|
#include "FairLogger.h"
|
24
|
|
25
|
#include "ERDecayMCEventHeader.h"
|
26
|
#include "ER10Heto8HeEventHeader.h"
|
27
|
#include "ERMCEventHeader.h"
|
28
|
|
29
|
ERDecay10Heto8He::ERDecay10Heto8He():
|
30
|
ERDecay("10Heto8He"),
|
31
|
fDecayFinish(kFALSE),
|
32
|
fTargetReactZ(0.),
|
33
|
fMinStep(0.01),
|
34
|
f8He(NULL),
|
35
|
f10He(NULL),
|
36
|
f3H(NULL),
|
37
|
fn(NULL),
|
38
|
f1H(NULL),
|
39
|
f10HeMass(0.),
|
40
|
fIs10HeUserMassSet(false),
|
41
|
fIs10HeExcitationSet(false),
|
42
|
fADInput(NULL),
|
43
|
fADFunction(NULL),
|
44
|
fDecayFilePath(""),
|
45
|
fDecayFileFinished(kFALSE),
|
46
|
fDecayFileCurrentEvent(0)
|
47
|
{
|
48
|
fRnd = new TRandom3();
|
49
|
|
50
|
fRnd2 = new TRandom3();
|
51
|
fRnd2->SetSeed();
|
52
|
fReactionPhaseSpace = new TGenPhaseSpace();
|
53
|
fDecayPhaseSpace = new TGenPhaseSpace();
|
54
|
FairRunSim* run = FairRunSim::Instance();
|
55
|
fUnstableIon10He = new FairIon("10He", 2, 10, 2);
|
56
|
|
57
|
run->AddNewIon(fUnstableIon10He);
|
58
|
|
59
|
|
60
|
fLv1H = new TLorentzVector();
|
61
|
fLv10He = new TLorentzVector();
|
62
|
}
|
63
|
|
64
|
|
65
|
ERDecay10Heto8He::~ERDecay10Heto8He() {
|
66
|
if (fDecayFile.is_open())
|
67
|
fDecayFile.close();
|
68
|
if (fDecayFilePath == ""){
|
69
|
if (fLv8Hed){
|
70
|
delete fLv8Hed;
|
71
|
delete fLvn1;
|
72
|
delete fLvn2;
|
73
|
|
74
|
|
75
|
}
|
76
|
}
|
77
|
}
|
78
|
|
79
|
|
80
|
void ERDecay10Heto8He::SetHe10Exitation(Double_t excMean, Double_t fwhm, Double_t distibWeight) {
|
81
|
f10HeExcitationMean.push_back(excMean);
|
82
|
f10HeExcitationSigma.push_back(fwhm / 2.355);
|
83
|
if (!fIs10HeExcitationSet) {
|
84
|
f10HeExcitationWeight.push_back(distibWeight);
|
85
|
fIs10HeExcitationSet = true;
|
86
|
return ;
|
87
|
}
|
88
|
f10HeExcitationWeight.push_back(f10HeExcitationWeight.back() + distibWeight);
|
89
|
}
|
90
|
|
91
|
|
92
|
Bool_t ERDecay10Heto8He::Init() {
|
93
|
|
94
|
cout << "Decayer Init." << endl;
|
95
|
|
96
|
f8He = TDatabasePDG::Instance()->GetParticle("8He");
|
97
|
if ( ! f8He ) {
|
98
|
std::cerr << "-W- ERDecay10Heto8He: Ion 8He not found in database!" << endl;
|
99
|
return kFALSE;
|
100
|
}
|
101
|
|
102
|
f3H = TDatabasePDG::Instance()->GetParticle("Triton");
|
103
|
if ( ! f3H ) {
|
104
|
std::cerr << "-W- ERDecay10Heto8He: Ion Triton not found in database!" << endl;
|
105
|
return kFALSE;
|
106
|
}
|
107
|
|
108
|
fn = TDatabasePDG::Instance()->GetParticle("neutron");
|
109
|
if ( ! fn ) {
|
110
|
std::cerr << "-W- ERDecay10Heto8He: Particle neutron not found in database!" << endl;
|
111
|
return kFALSE;
|
112
|
}
|
113
|
|
114
|
f1H = TDatabasePDG::Instance()->GetParticle("proton");
|
115
|
if ( ! f1H ) {
|
116
|
std::cerr << "-W- ERDecay10Heto8He: Particle proton not found in database!" << endl;
|
117
|
return kFALSE;
|
118
|
}
|
119
|
|
120
|
if (fIs10HeUserMassSet) {
|
121
|
fUnstableIon10He->SetMass(f10HeMass / .931494028);
|
122
|
} else {
|
123
|
f10HeMass = f10He->Mass();
|
124
|
}
|
125
|
CalculateTargetParameters();
|
126
|
|
127
|
|
128
|
if (fDecayFilePath != ""){
|
129
|
LOG(INFO) << "Use decay kinematics from external text file" << FairLogger::endl;
|
130
|
fDecayFile.open(fDecayFilePath.Data());
|
131
|
if (!fDecayFile.is_open())
|
132
|
LOG(FATAL) << "Can`t open decay file " << fDecayFilePath << FairLogger::endl;
|
133
|
|
134
|
std::string header;
|
135
|
std::getline(fDecayFile,header);
|
136
|
|
137
|
fLv8Hed = new TLorentzVector();
|
138
|
fLvn1 = new TLorentzVector();
|
139
|
fLvn2 = new TLorentzVector();
|
140
|
|
141
|
|
142
|
}
|
143
|
|
144
|
return kTRUE;
|
145
|
}
|
146
|
|
147
|
|
148
|
Bool_t ERDecay10Heto8He::Stepping() {
|
149
|
if(!fDecayFinish && gMC->TrackPid() == 1000020080
|
150
|
&& TString(gMC->CurrentVolName()).Contains(GetInteractionVolumeName()))
|
151
|
{
|
152
|
if (!fIsInterationPointFound) {
|
153
|
if (!FindInteractionPoint()) {
|
154
|
fDecayFinish = kTRUE;
|
155
|
return kTRUE;
|
156
|
} else {
|
157
|
fDistanceFromEntrance = 0;
|
158
|
}
|
159
|
}
|
160
|
gMC->SetMaxStep(fMinStep);
|
161
|
TLorentzVector curPos;
|
162
|
gMC->TrackPosition(curPos);
|
163
|
Double_t trackStep = gMC->TrackStep();
|
164
|
fDistanceFromEntrance += trackStep;
|
165
|
|
166
|
|
167
|
if (fDistanceFromEntrance > fDistanceToInteractPoint) {
|
168
|
|
169
|
|
170
|
|
171
|
|
172
|
TLorentzVector lv8Heb;
|
173
|
gMC->TrackMomentum(lv8Heb);
|
174
|
|
175
|
if (lv8Heb.P() == 0) {
|
176
|
return kTRUE;
|
177
|
}
|
178
|
|
179
|
TLorentzVector lv3H(0., 0., 0., f3H->Mass());
|
180
|
TLorentzVector lvReaction;
|
181
|
lvReaction = lv8Heb + lv3H;
|
182
|
|
183
|
const TVector3 boost = lvReaction.BoostVector();
|
184
|
Double_t ECM = 0;
|
185
|
TLorentzVector lv8HebCM, lv3HCM;
|
186
|
lv8HebCM = lv8Heb;
|
187
|
lv3HCM = lv3H;
|
188
|
lv8HebCM.Boost(-boost);
|
189
|
lv3HCM.Boost(-boost);
|
190
|
ECM = lv8HebCM(3) + lv3HCM(3);
|
191
|
|
192
|
Int_t reactionHappen = kFALSE;
|
193
|
|
194
|
Double_t decay10HeMass;
|
195
|
Int_t reactionAttempsCounter = 0;
|
196
|
Double_t excitation = 0;
|
197
|
while (reactionHappen==kFALSE) {
|
198
|
decay10HeMass = f10HeMass;
|
199
|
if (fIs10HeExcitationSet) {
|
200
|
Double_t randWeight = gRandom->Uniform(0., f10HeExcitationWeight.back());
|
201
|
Int_t distribNum = 0;
|
202
|
|
203
|
for (; distribNum < f10HeExcitationWeight.size(); distribNum++) {
|
204
|
if (randWeight < f10HeExcitationWeight[distribNum]) {
|
205
|
break;
|
206
|
}
|
207
|
}
|
208
|
excitation = gRandom->Gaus(f10HeExcitationMean[distribNum], f10HeExcitationSigma[distribNum]);
|
209
|
fUnstableIon10He->SetExcEnergy(excitation);
|
210
|
}
|
211
|
decay10HeMass += excitation;
|
212
|
if((ECM - f1H->Mass() - decay10HeMass) > 0) {
|
213
|
reactionHappen = kTRUE;
|
214
|
LOG(DEBUG) << "[ERDecayEXP1811] Reaction is happen" << endl;
|
215
|
}
|
216
|
reactionAttempsCounter++;
|
217
|
if (reactionAttempsCounter > 1000){
|
218
|
LOG(DEBUG) << "[ERDecayEXP1811] Reaction is forbidden for this CM energy" << endl;
|
219
|
fDecayFinish = kTRUE;
|
220
|
return kTRUE;
|
221
|
}
|
222
|
}
|
223
|
|
224
|
ReactionPhaseGenerator(ECM, decay10HeMass);
|
225
|
fLv10He->Boost(boost);
|
226
|
fLv1H->Boost(boost);
|
227
|
|
228
|
|
229
|
|
230
|
if (!DecayPhaseGenerator(excitation)){
|
231
|
fDecayFinish = kTRUE;
|
232
|
return kTRUE;
|
233
|
}
|
234
|
|
235
|
Int_t He8bTrackNb, He10TrackNb,H1TrackNb, He8dTrackNb, n1TrackNb, n2TrackNb;
|
236
|
|
237
|
He8bTrackNb = gMC->GetStack()->GetCurrentTrackNumber();
|
238
|
|
239
|
|
240
|
|
241
|
|
242
|
|
243
|
|
244
|
|
245
|
|
246
|
gMC->GetStack()->PushTrack(1, He8bTrackNb, f1H->PdgCode(),
|
247
|
fLv1H->Px(), fLv1H->Py(), fLv1H->Pz(),
|
248
|
fLv1H->E(), curPos.X(), curPos.Y(), curPos.Z(),
|
249
|
gMC->TrackTime(), 0., 0., 0.,
|
250
|
kPDecay, H1TrackNb, f1H->Mass(), 0);
|
251
|
gMC->GetStack()->PushTrack(1, He8bTrackNb, f8He->PdgCode(),
|
252
|
fLv8Hed->Px(), fLv8Hed->Py(), fLv8Hed->Pz(),
|
253
|
fLv8Hed->E(), curPos.X(), curPos.Y(), curPos.Z(),
|
254
|
gMC->TrackTime(), 0., 0., 0.,
|
255
|
kPDecay, He8dTrackNb, f8He->Mass(), 0);
|
256
|
gMC->GetStack()->PushTrack(1, He8bTrackNb, fn->PdgCode(),
|
257
|
fLvn1->Px(),fLvn1->Py(),fLvn1->Pz(),
|
258
|
fLvn1->E(), curPos.X(), curPos.Y(), curPos.Z(),
|
259
|
gMC->TrackTime(), 0., 0., 0.,
|
260
|
kPDecay, n1TrackNb, fn->Mass(), 0);
|
261
|
gMC->GetStack()->PushTrack(1, He8bTrackNb, fn->PdgCode(),
|
262
|
fLvn2->Px(),fLvn2->Py(),fLvn2->Pz(),
|
263
|
fLvn2->E(), curPos.X(), curPos.Y(), curPos.Z(),
|
264
|
gMC->TrackTime(), 0., 0., 0.,
|
265
|
kPDecay, n2TrackNb, fn->Mass(), 0);
|
266
|
gMC->StopTrack();
|
267
|
fDecayFinish = kTRUE;
|
268
|
gMC->SetMaxStep(100.);
|
269
|
|
270
|
FairRunSim* run = FairRunSim::Instance();
|
271
|
if (TString(run->GetMCEventHeader()->ClassName()).Contains("ERDecayMCEventHeader")){
|
272
|
ERDecayMCEventHeader* header = (ERDecayMCEventHeader*)run->GetMCEventHeader();
|
273
|
header->SetDecayPos(curPos.Vect());
|
274
|
header->SetInputIon(He8bTrackNb);
|
275
|
header->AddOutputParticle(He10TrackNb);
|
276
|
header->AddOutputParticle(H1TrackNb);
|
277
|
header->AddOutputParticle(He8dTrackNb);
|
278
|
header->AddOutputParticle(n1TrackNb);
|
279
|
header->AddOutputParticle(n2TrackNb);
|
280
|
}
|
281
|
if (TString(run->GetMCEventHeader()->ClassName()).Contains("ER10Heto8HeEventHeader")){
|
282
|
ER10Heto8HeEventHeader* header = (ER10Heto8HeEventHeader*)run->GetMCEventHeader();
|
283
|
header->SetData(curPos.Vect(), lv8Heb, lv3H, *fLv1H, *fLv8Hed, *fLv10He, *fLvn1, *fLvn2);
|
284
|
header->SetTrigger(1);
|
285
|
}
|
286
|
}
|
287
|
}
|
288
|
return kTRUE;
|
289
|
}
|
290
|
|
291
|
|
292
|
void ERDecay10Heto8He::BeginEvent() {
|
293
|
fDecayFinish = kFALSE;
|
294
|
fIsInterationPointFound = kFALSE;
|
295
|
fTargetReactZ = fRnd->Uniform(-fTargetThickness / 2, fTargetThickness / 2);
|
296
|
FairRunSim* run = FairRunSim::Instance();
|
297
|
}
|
298
|
|
299
|
|
300
|
void ERDecay10Heto8He::FinishEvent() {
|
301
|
FairRunSim* run = FairRunSim::Instance();
|
302
|
if (TString(run->GetMCEventHeader()->ClassName()).Contains("ERDecayMCEventHeader")){
|
303
|
ERDecayMCEventHeader* header = (ERDecayMCEventHeader*)run->GetMCEventHeader();
|
304
|
header->Clear();
|
305
|
}
|
306
|
if (TString(run->GetMCEventHeader()->ClassName()).Contains("ER10Heto8HeEventHeader")){
|
307
|
ER10Heto8HeEventHeader* header = (ER10Heto8HeEventHeader*)run->GetMCEventHeader();
|
308
|
header->Clear();
|
309
|
}
|
310
|
}
|
311
|
|
312
|
|
313
|
void ERDecay10Heto8He::ReactionPhaseGenerator(Double_t Ecm, Double_t he10Mass) {
|
314
|
Double_t m1 = he10Mass;
|
315
|
Double_t m2 = f1H->Mass();
|
316
|
|
317
|
|
318
|
|
319
|
Double_t E1 = 0.5 * (Ecm * Ecm + m1 * m1 - m2 * m2) / Ecm;
|
320
|
|
321
|
|
322
|
Double_t Pcm = TMath::Sqrt(E1 * E1 - m1 * m1);
|
323
|
|
324
|
Double_t thetaCM;
|
325
|
if(!fADInput) {
|
326
|
thetaCM = TMath::ACos(gRandom->Uniform(-1, 1));
|
327
|
} else {
|
328
|
thetaCM = fADFunction->GetRandom(fThetaMin, fThetaMax)*TMath::DegToRad();
|
329
|
}
|
330
|
Double_t phi = gRandom->Uniform(0., 2. * TMath::Pi());
|
331
|
TVector3 Pcmv;
|
332
|
Pcmv.SetMagThetaPhi(Pcm, thetaCM, phi);
|
333
|
|
334
|
fLv10He->SetXYZM(0., 0., 0., 0.);
|
335
|
fLv1H->SetXYZM(0., 0., 0., 0.);
|
336
|
fLv10He->SetXYZM(Pcmv(0), Pcmv(1), Pcmv(2), m1);
|
337
|
fLv1H->SetXYZM(-Pcmv(0), -Pcmv(1), -Pcmv(2), m2);
|
338
|
}
|
339
|
|
340
|
|
341
|
Bool_t ERDecay10Heto8He::DecayPhaseGenerator(const Double_t excitation) {
|
342
|
if (fDecayFilePath == ""){
|
343
|
Double_t decayMasses[5];
|
344
|
decayMasses[0] = f8He->Mass();
|
345
|
decayMasses[1] = fn->Mass();
|
346
|
decayMasses[2] = fn->Mass();
|
347
|
|
348
|
fDecayPhaseSpace->SetDecay(*fLv10He, 3, decayMasses);
|
349
|
fDecayPhaseSpace->Generate();
|
350
|
fLv8Hed = fDecayPhaseSpace->GetDecay(0);
|
351
|
fLvn1 = fDecayPhaseSpace->GetDecay(1);
|
352
|
fLvn2 = fDecayPhaseSpace->GetDecay(2);
|
353
|
return kTRUE;
|
354
|
}
|
355
|
if (fDecayFile.eof()){
|
356
|
LOG(ERROR) << "Decay file finished! There are no more events in file " << fDecayFilePath
|
357
|
<< " to be processed." << FairLogger::endl;
|
358
|
return kFALSE;
|
359
|
}
|
360
|
std::string event_line;
|
361
|
std::getline(fDecayFile,event_line);
|
362
|
std::istringstream iss(event_line);
|
363
|
std::vector<std::string> outputs_components((std::istream_iterator<std::string>(iss)),
|
364
|
std::istream_iterator<std::string>());
|
365
|
if (outputs_components.size() < 5*3){
|
366
|
LOG(ERROR) << "Wrong components number in raw in decay file!" << FairLogger::endl;
|
367
|
return kFALSE;
|
368
|
}
|
369
|
|
370
|
TVector3 pn1(std::stod(outputs_components[0]),std::stod(outputs_components[1]),
|
371
|
std::stod(outputs_components[2]));
|
372
|
TVector3 pn2(std::stod(outputs_components[3]),std::stod(outputs_components[4]),
|
373
|
std::stod(outputs_components[5]));
|
374
|
TVector3 p8Hed(std::stod(outputs_components[12]),std::stod(outputs_components[13]),
|
375
|
std::stod(outputs_components[14]));
|
376
|
|
377
|
const auto excitationScale = excitation > 0. ? sqrt(excitation / fDecayFileExcitation) : 1.;
|
378
|
const auto MeV2GeV = 1./1000.;
|
379
|
const auto scale = excitationScale * MeV2GeV;
|
380
|
pn1 *= scale;
|
381
|
pn2 *= scale;
|
382
|
p8Hed *= scale;
|
383
|
const auto fill_output_lorentz_vectors_in_lab =
|
384
|
[this](TLorentzVector* lv, const TVector3& p, const Double_t mass) {
|
385
|
lv->SetXYZM(p.X(), p.Y(), p.Z(), mass);
|
386
|
lv->Boost(fLv10He->BoostVector());
|
387
|
};
|
388
|
fill_output_lorentz_vectors_in_lab(fLvn1, pn1, fn->Mass());
|
389
|
fill_output_lorentz_vectors_in_lab(fLvn2, pn2, fn->Mass());
|
390
|
fill_output_lorentz_vectors_in_lab(fLv8Hed, p8Hed, f8He->Mass());
|
391
|
return kTRUE;
|
392
|
}
|
393
|
|
394
|
|
395
|
Double_t ERDecay10Heto8He::ADEvaluate(Double_t *x, Double_t *p) {
|
396
|
if (fADInput->IsZombie()) {
|
397
|
Error("ERDecay10Heto8He::ADEvaluate", "AD input was not loaded");
|
398
|
return -1;
|
399
|
}
|
400
|
|
401
|
return fADInput->Eval(x[0]);
|
402
|
}
|
403
|
|
404
|
|
405
|
void ERDecay10Heto8He::SetAngularDistribution(TString ADFile) {
|
406
|
TString ADFilePath = gSystem->Getenv("VMCWORKDIR");
|
407
|
ADFilePath += "/input/" + ADFile;
|
408
|
std::ifstream f;
|
409
|
f.open(ADFilePath.Data());
|
410
|
if (!f.is_open()) {
|
411
|
LOG(FATAL) << "Can't open file " << ADFilePath << FairLogger::endl;
|
412
|
}
|
413
|
Int_t nPoints = std::count(std::istreambuf_iterator<char>(f),
|
414
|
std::istreambuf_iterator<char>(), '\n');
|
415
|
f.seekg(0, std::ios::beg);
|
416
|
TVectorD tet(nPoints);
|
417
|
TVectorD sigma(nPoints);
|
418
|
LOG(DEBUG2) << "nPoints = " << nPoints << FairLogger::endl;
|
419
|
Int_t i = 0;
|
420
|
while (!f.eof()) {
|
421
|
|
422
|
if (i == nPoints) break;
|
423
|
f >> tet(i) >> sigma(i);
|
424
|
LOG(DEBUG2) << i << ": " << tet(i) << "\t" << sigma(i) << FairLogger::endl;
|
425
|
i++;
|
426
|
}
|
427
|
fADInput = new TGraph(tet, sigma);
|
428
|
if (fADInput->GetN() <= 0) {
|
429
|
LOG(INFO) << "ERDecay10Heto8He::SetAngularDistribution: "
|
430
|
<< "Too few inputs for creation of AD function!" << FairLogger::endl;
|
431
|
return;
|
432
|
}
|
433
|
Double_t* angle = fADInput->GetX();
|
434
|
|
435
|
|
436
|
|
437
|
|
438
|
fThetaMin = angle[0];
|
439
|
fThetaMax = angle[fADInput->GetN()-1];
|
440
|
fADFunction = new TF1("angDistr", this, &ERDecay10Heto8He::ADEvaluate,
|
441
|
fThetaMin, fThetaMax, 0, "ERDecay10Heto8He", "ADEvaluate");
|
442
|
fADFunction->Eval(1.);
|
443
|
}
|
444
|
|
445
|
ClassImp(ERDecay10Heto8He)
|