ERDecayEXP1803.cxx
1 |
/********************************************************************************
|
---|---|
2 |
* Copyright (C) Joint Institute for Nuclear Research *
|
3 |
* *
|
4 |
* This software is distributed under the terms of the *
|
5 |
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
|
6 |
* copied verbatim in the file "LICENSE" *
|
7 |
********************************************************************************/
|
8 |
|
9 |
#include "ERDecayEXP1803.h" |
10 |
|
11 |
#include <iostream> |
12 |
using namespace std; |
13 |
|
14 |
#include "TVirtualMC.h" |
15 |
#include "TLorentzVector.h" |
16 |
#include "TMCProcess.h" |
17 |
#include "TRandom.h" |
18 |
|
19 |
#include "FairRunSim.h" |
20 |
#include "FairLogger.h" |
21 |
|
22 |
#include "ERDecayMCEventHeader.h" |
23 |
#include "ERMCEventHeader.h" |
24 |
|
25 |
ERDecayEXP1803::ERDecayEXP1803(): |
26 |
ERDecay("EXP1803"),
|
27 |
fDecayFinish(kFALSE), |
28 |
fTargetReactZ(0.),
|
29 |
fMinStep(0.01), |
30 |
f6He(NULL),
|
31 |
f2H (NULL),
|
32 |
f3He(NULL),
|
33 |
f5H (NULL),
|
34 |
f3H (NULL),
|
35 |
fn (NULL),
|
36 |
fIon3He(NULL),
|
37 |
f5HMass(0.),
|
38 |
fIs5HUserMassSet(false),
|
39 |
fIs5HExcitationSet(false)
|
40 |
{ |
41 |
fRnd = new TRandom3();
|
42 |
fReactionPhaseSpace = new TGenPhaseSpace();
|
43 |
fDecayPhaseSpace = new TGenPhaseSpace();
|
44 |
FairRunSim* run = FairRunSim::Instance(); |
45 |
fUnstableIon5H = new FairIon("5H", 1, 5, 1); |
46 |
fIon3He = new FairIon("3He", 2, 3, 2); |
47 |
run->AddNewIon(fUnstableIon5H); |
48 |
run->AddNewIon(fIon3He); |
49 |
|
50 |
fADInput = NULL;
|
51 |
fADFunction = NULL;
|
52 |
|
53 |
flv5H = new TLorentzVector();
|
54 |
flv3He = new TLorentzVector();
|
55 |
|
56 |
cout << "ERDecayEXP1803 constructed." << endl;
|
57 |
} |
58 |
|
59 |
//-------------------------------------------------------------------------------------------------
|
60 |
ERDecayEXP1803::~ERDecayEXP1803() { |
61 |
if (fADInput) {
|
62 |
delete fADInput;
|
63 |
fADInput = NULL;
|
64 |
} |
65 |
if (fADFunction) {
|
66 |
delete fADFunction;
|
67 |
fADFunction = NULL;
|
68 |
} |
69 |
|
70 |
////if (flv5H) { delete flv5H; flv5H = NULL; }
|
71 |
////if (flv3He) { delete flv3He; flv3He = NULL; }
|
72 |
|
73 |
} |
74 |
|
75 |
//-------------------------------------------------------------------------------------------------
|
76 |
void ERDecayEXP1803::SetH5Exitation(Double_t excMean, Double_t fwhm, Double_t distibWeight) {
|
77 |
f5HExcitationMean.push_back(excMean); |
78 |
f5HExcitationSigma.push_back(fwhm / 2.355); |
79 |
if (!fIs5HExcitationSet) {
|
80 |
f5HExcitationWeight.push_back(distibWeight); |
81 |
fIs5HExcitationSet = true;
|
82 |
return ;
|
83 |
} |
84 |
f5HExcitationWeight.push_back(f5HExcitationWeight.back() + distibWeight); |
85 |
} |
86 |
|
87 |
//-------------------------------------------------------------------------------------------------
|
88 |
Bool_t ERDecayEXP1803::Init() { |
89 |
|
90 |
cout << "Decayer Init." << endl;
|
91 |
|
92 |
f6He = TDatabasePDG::Instance()->GetParticle("6He");
|
93 |
if ( ! f6He ) {
|
94 |
std::cerr << "-W- ERDecayEXP1803: Ion 6He not found in database!" << endl;
|
95 |
return kFALSE;
|
96 |
} |
97 |
|
98 |
f2H = TDatabasePDG::Instance()->GetParticle("Deuteron");
|
99 |
if ( ! f2H ) {
|
100 |
std::cerr << "-W- ERDecayEXP1803: Ion Deuteron not found in database!" << endl;
|
101 |
return kFALSE;
|
102 |
} |
103 |
|
104 |
f5H = TDatabasePDG::Instance()->GetParticle("5H");
|
105 |
if ( ! f5H ) {
|
106 |
std::cerr << "-W- ERDecayEXP1803: Ion 5H not found in database!" << endl;
|
107 |
return kFALSE;
|
108 |
} |
109 |
|
110 |
f3He = TDatabasePDG::Instance()->GetParticle(fIon3He->GetName()); |
111 |
if ( ! f3He ) {
|
112 |
std::cerr << "-W- ERDecayEXP1803: Ion 3He not found in database!" << endl;
|
113 |
return kFALSE;
|
114 |
} |
115 |
|
116 |
f3H = TDatabasePDG::Instance()->GetParticle("Triton");
|
117 |
if ( ! f3H ) {
|
118 |
std::cerr << "-W- ERDecayEXP1803: Ion Triton not found in database!" << endl;
|
119 |
return kFALSE;
|
120 |
} |
121 |
|
122 |
fn = TDatabasePDG::Instance()->GetParticle("neutron");
|
123 |
if ( ! fn ) {
|
124 |
std::cerr << "-W- ERDecayEXP1803: Particle neutron not found in database!" << endl;
|
125 |
return kFALSE;
|
126 |
} |
127 |
if (fIs5HUserMassSet) {
|
128 |
fUnstableIon5H->SetMass(f5HMass / .931494028);
|
129 |
} else {
|
130 |
f5HMass = f5H->Mass(); // if user mass is not defined in ERDecayEXP1803::SetH5Mass() than get a GEANT mass
|
131 |
} |
132 |
return kTRUE;
|
133 |
} |
134 |
|
135 |
//-------------------------------------------------------------------------------------------------
|
136 |
Bool_t ERDecayEXP1803::Stepping() { |
137 |
if(!fDecayFinish && gMC->TrackPid() == 1000020060 && TString(gMC->CurrentVolName()).Contains(fVolumeName)){ |
138 |
gMC->SetMaxStep(fMinStep); |
139 |
TLorentzVector curPos; |
140 |
gMC->TrackPosition(curPos); |
141 |
if (curPos.Z() > fTargetReactZ){
|
142 |
// std::cout << "Start reation in target. Defined pos: " << fTargetReactZ << ", current pos: " << curPos.Z() << endl;
|
143 |
// 6He + 2H → 3He + 5H
|
144 |
TLorentzVector lv6He; |
145 |
gMC->TrackMomentum(lv6He); |
146 |
|
147 |
TLorentzVector lv2H(0., 0., 0., f2H->Mass()); |
148 |
TLorentzVector lvReaction; |
149 |
lvReaction = lv6He + lv2H; |
150 |
|
151 |
const TVector3 boost = lvReaction.BoostVector(); //Get Pcm 3 vector |
152 |
Double_t ECM = 0;
|
153 |
TLorentzVector lv6HeCM, lv2HCM; |
154 |
lv6HeCM = lv6He; |
155 |
lv2HCM = lv2H; |
156 |
lv6HeCM.Boost(-boost); |
157 |
lv2HCM.Boost(-boost); |
158 |
ECM = lv6HeCM(3) + lv2HCM(3); |
159 |
|
160 |
Int_t decayHappen = kFALSE; |
161 |
// while decay condition is not fullfilled
|
162 |
Double_t decay5HMass; |
163 |
while (decayHappen==kFALSE) { // сделать условие, что если не получается разыграть такой распад, то приступать к следующему событию (энергия пучка слигшком мала.) |
164 |
decay5HMass = f5HMass; |
165 |
Double_t excitation = 0; // excitation energy |
166 |
if (fIs5HExcitationSet) {
|
167 |
Double_t randWeight = gRandom->Uniform(0., f5HExcitationWeight.back());
|
168 |
Int_t distribNum = 0;
|
169 |
// choose distribution by weight
|
170 |
for (; distribNum < f5HExcitationWeight.size(); distribNum++) {
|
171 |
if (randWeight < f5HExcitationWeight[distribNum]) {
|
172 |
break;
|
173 |
} |
174 |
} |
175 |
excitation = gRandom->Gaus(f5HExcitationMean[distribNum], f5HExcitationSigma[distribNum]); |
176 |
fUnstableIon5H->SetExcEnergy(excitation); |
177 |
} |
178 |
decay5HMass += excitation; |
179 |
if((ECM - f3He->Mass() - decay5HMass) > 0) { // выход из цикла while для phasegen2 |
180 |
decayHappen = kTRUE; |
181 |
} |
182 |
|
183 |
// Double_t reactMasses[2];
|
184 |
//reactMasses[0] = f3He->Mass();
|
185 |
// reactMasses[1] = decay5HMass;
|
186 |
|
187 |
//decayHappen = fReactionPhaseSpace->SetDecay(lvReaction, 2, reactMasses);
|
188 |
|
189 |
//if(decayHappen == kFALSE) cout << " forbidden " << ECM - f3He->Mass() - decay5HMass << endl;
|
190 |
//cout << lv6HeCM(3) << " " << lv2HCM(3) << " " << f3He->Mass() << " " << decay5HMass << endl;
|
191 |
cout << lv6He(0) << " " << lv6He(1) << " " << lv6He(2)<< " " <<lv6He(3) << endl; |
192 |
} |
193 |
cout << " allowed " << ECM - f3He->Mass() - decay5HMass << endl;
|
194 |
// cout << " MASS 5H " << decay5HMass << endl;
|
195 |
//// TLorentzVector *flv3He;
|
196 |
//// TLorentzVector *lv5H;
|
197 |
|
198 |
phasegen2(ECM, decay5HMass); |
199 |
flv5H->Boost(boost); |
200 |
flv3He->Boost(boost); |
201 |
|
202 |
// fReactionPhaseSpace->Generate();
|
203 |
// flv3He = fReactionPhaseSpace->GetDecay(0); // ?
|
204 |
// flv5H = fReactionPhaseSpace->GetDecay(1); // ?
|
205 |
|
206 |
//5H → f3H + n +n.
|
207 |
Double_t decayMasses[3];
|
208 |
decayMasses[0] = f3H->Mass();
|
209 |
decayMasses[1] = fn->Mass();
|
210 |
decayMasses[2] = fn->Mass();
|
211 |
|
212 |
//cout << flv5H.E() << " its fine! " << decay5HMass << endl;
|
213 |
|
214 |
fDecayPhaseSpace->SetDecay(*flv5H, 3, decayMasses);
|
215 |
fDecayPhaseSpace->Generate(); |
216 |
|
217 |
TLorentzVector *lv3H = fDecayPhaseSpace->GetDecay(0);
|
218 |
TLorentzVector *lvn1 = fDecayPhaseSpace->GetDecay(1);
|
219 |
TLorentzVector *lvn2 = fDecayPhaseSpace->GetDecay(2);
|
220 |
|
221 |
|
222 |
Int_t He6TrackNb, H5TrackNb, He3TrackNb, H3TrackNb, n1TrackNb, n2TrackNb; |
223 |
|
224 |
He6TrackNb = gMC->GetStack()->GetCurrentTrackNumber(); |
225 |
|
226 |
gMC->GetStack()->PushTrack(1, He6TrackNb, f5H->PdgCode(),
|
227 |
flv5H->Px(), flv5H->Py(), flv5H->Pz(), |
228 |
flv5H->E(), curPos.X(), curPos.Y(), curPos.Z(), |
229 |
gMC->TrackTime(), 0., 0., 0., |
230 |
kPDecay, H5TrackNb, decay5HMass, 0);
|
231 |
gMC->GetStack()->PushTrack(1, He6TrackNb, f3He->PdgCode(),
|
232 |
flv3He->Px(), flv3He->Py(), flv3He->Pz(), |
233 |
flv3He->E(), curPos.X(), curPos.Y(), curPos.Z(), |
234 |
gMC->TrackTime(), 0., 0., 0., |
235 |
kPDecay, He3TrackNb, f3He->Mass(), 0);
|
236 |
gMC->GetStack()->PushTrack(1, He6TrackNb, f3H->PdgCode(),
|
237 |
lv3H->Px(), lv3H->Py(), lv3H->Pz(), |
238 |
lv3H->E(), curPos.X(), curPos.Y(), curPos.Z(), |
239 |
gMC->TrackTime(), 0., 0., 0., |
240 |
kPDecay, H3TrackNb, f3H->Mass(), 0);
|
241 |
gMC->GetStack()->PushTrack(1, He6TrackNb, fn->PdgCode(),
|
242 |
lvn1->Px(),lvn1->Py(),lvn1->Pz(), |
243 |
lvn1->E(), curPos.X(), curPos.Y(), curPos.Z(), |
244 |
gMC->TrackTime(), 0., 0., 0., |
245 |
kPDecay, n1TrackNb, fn->Mass(), 0);
|
246 |
gMC->GetStack()->PushTrack(1, He6TrackNb, fn->PdgCode(),
|
247 |
lvn2->Px(),lvn2->Py(),lvn2->Pz(), |
248 |
lvn2->E(), curPos.X(), curPos.Y(), curPos.Z(), |
249 |
gMC->TrackTime(), 0., 0., 0., |
250 |
kPDecay, n2TrackNb, fn->Mass(), 0);
|
251 |
LOG(INFO) << He6TrackNb << " " << H5TrackNb << " " << He3TrackNb << FairLogger::endl; |
252 |
gMC->StopTrack(); |
253 |
fDecayFinish = kTRUE; |
254 |
gMC->SetMaxStep(100.); |
255 |
|
256 |
FairRunSim* run = FairRunSim::Instance(); |
257 |
if (TString(run->GetMCEventHeader()->ClassName()).Contains("ERDecayMCEventHeader")){ |
258 |
ERDecayMCEventHeader* header = (ERDecayMCEventHeader*)run->GetMCEventHeader(); |
259 |
header->SetDecayPos(curPos.Vect()); |
260 |
header->SetInputIon(He6TrackNb); |
261 |
header->AddOutputParticle(H5TrackNb); |
262 |
header->AddOutputParticle(He3TrackNb); |
263 |
header->AddOutputParticle(H3TrackNb); |
264 |
header->AddOutputParticle(n1TrackNb); |
265 |
header->AddOutputParticle(n2TrackNb); |
266 |
} |
267 |
} |
268 |
} |
269 |
return kTRUE;
|
270 |
} |
271 |
|
272 |
//-------------------------------------------------------------------------------------------------
|
273 |
void ERDecayEXP1803::BeginEvent() {
|
274 |
fDecayFinish = kFALSE; |
275 |
fTargetReactZ = fRnd->Uniform(-fTargetThickness / 2, fTargetThickness / 2); |
276 |
FairRunSim* run = FairRunSim::Instance(); |
277 |
} |
278 |
|
279 |
//-------------------------------------------------------------------------------------------------
|
280 |
void ERDecayEXP1803::FinishEvent() {
|
281 |
} |
282 |
|
283 |
//-------------------------------------------------------------------------------------------------
|
284 |
void ERDecayEXP1803::phasegen2(Double_t Ecm, Double_t h5Mass) {
|
285 |
//generate 2 - body decay in phase space approach.
|
286 |
//Ecm -Total energy in CM
|
287 |
//No security checks, cause it should be fast!
|
288 |
|
289 |
//todo !!Vratislav: set excited masses should be function
|
290 |
//it is the same algorithm for phasegen2 and phasegen3
|
291 |
|
292 |
|
293 |
Double_t m1 = h5Mass; |
294 |
Double_t m2 = f3He->Mass(); |
295 |
|
296 |
// Energy of 1-st particle in cm:
|
297 |
//TODO Vratislav: check this statement
|
298 |
//is it true also for binary reaction?
|
299 |
Double_t E1 = 0.5 * (Ecm * Ecm + m1 * m1 - m2 * m2) / Ecm; |
300 |
|
301 |
//Impulse in CM
|
302 |
Double_t Pcm = TMath::Sqrt(E1 * E1 - m1 * m1); |
303 |
|
304 |
//Generate angles of particles in CM
|
305 |
|
306 |
Double_t thetaCM = TMath::ACos(gRandom->Uniform(-1., 1.)); |
307 |
//Double_t thetaCM = fADFunction->GetRandom(1.,150.)*TMath::DegToRad();
|
308 |
Double_t phi = gRandom->Uniform(0., 2. * TMath::Pi()); |
309 |
|
310 |
TVector3 Pcmv; |
311 |
Pcmv.SetMagThetaPhi(Pcm, thetaCM, phi); |
312 |
|
313 |
flv5H->SetXYZM(0., 0., 0., 0.); |
314 |
flv3He->SetXYZM(0., 0., 0., 0.); |
315 |
flv5H->SetXYZM(Pcmv(0), Pcmv(1), Pcmv(2), m1); |
316 |
flv3He->SetXYZM(-Pcmv(0), -Pcmv(1), -Pcmv(2), m2); |
317 |
} |
318 |
|
319 |
//-------------------------------------------------------------------------------------------------
|
320 |
Double_t ERDecayEXP1803::ADEvaluate(Double_t *x, Double_t *p) { |
321 |
//this function is necessary for TF1 constructor
|
322 |
if (fADInput->IsZombie()) {
|
323 |
Error("ERDecayEXP1803::ADEvaluate", "AD input was not loaded"); |
324 |
return -1; |
325 |
} |
326 |
return fADInput->Eval(x[0]); |
327 |
} |
328 |
|
329 |
//-------------------------------------------------------------------------------------------------
|
330 |
void ERDecayEXP1803::ReadADInput(TString ADfile) {
|
331 |
fADFile = ADfile; |
332 |
|
333 |
if (fADInput) {
|
334 |
delete fADInput;
|
335 |
fADInput = NULL;
|
336 |
} |
337 |
fADInput = new TGraph(fADFile, "%lg %*lg %lg"); |
338 |
|
339 |
//create function from external input
|
340 |
|
341 |
if (fADInput->IsZombie()) {
|
342 |
Error("ERDecayEXP1803::CreateADFunction", "AD input cannot be read and AD function won't be initialized"); |
343 |
return;
|
344 |
} |
345 |
if (fADInput->GetN() <= 0) { |
346 |
Info("ERDecayEXP1803::CreateADFunction","Too few inputs for creation of AD function!"); |
347 |
return;
|
348 |
} |
349 |
Double_t* angle = fADInput->GetX(); |
350 |
|
351 |
if (fADFunction) {
|
352 |
delete fADFunction;
|
353 |
fADFunction = NULL;
|
354 |
} |
355 |
fADFunction = new TF1("angDistr", this, &ERDecayEXP1803::ADEvaluate, angle[0], angle[fADInput->GetN()-1], 0, "ERDecayEXP1803", "ADEvaluate"); |
356 |
|
357 |
/*cout << "++++++++++++++++" << endl;
|
358 |
for(Int_t i=0; i<fADInput->GetN(); i++) {
|
359 |
cout << angle[i] << " " << fADFunction->Eval(angle[i]) << endl;
|
360 |
}
|
361 |
cout << "++++++++++++++++" << endl;*/
|
362 |
|
363 |
} |
364 |
|
365 |
//-------------------------------------------------------------------------------------------------
|
366 |
ClassImp(ERDecayEXP1803) |