ERDecay10Heto8He.cxx

Софья Рымжанова, 05/14/2020 03:28 PM

Download (17 KB)

 
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 "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
  // fRnd->SetSeed();
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
  // fIon1H        = new FairIon("1H", 1, 1, 1);
57
  run->AddNewIon(fUnstableIon10He);
58
  // run->AddNewIon(fIon1H);
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 == ""){ // LV from TGenPhaseSpace will be deleted in TGenPhaseSpace
69
    if (fLv8Hed){
70
      delete fLv8Hed;
71
      delete fLvn1;
72
      delete fLvn2;
73
      // delete fLvn3;
74
      // delete fLvn4;
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(); // if user mass is not defined in ERDecay10Heto8He::SetHe10Mass() than get a GEANT 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
    // fLvn3 = new TLorentzVector();
141
    // fLvn4 = new TLorentzVector();
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
    // std::cout << "Track step: " << fDistanceFromEntrance << "; Diff " << (curPos.Vect() - fInputPoint).Mag() <<  endl;    
166
    // std::cout << "Track step: " << fDistanceFromEntrance <<  endl;    
167
    if (fDistanceFromEntrance > fDistanceToInteractPoint) {
168
      // std::cout << "Start reation in target. Defined pos: " << fDistanceToInteractPoint << ", current pos: " << curPos.Z() << endl;
169
      
170
      // 8He + 2H → 3He + 7H
171
          // 8He + 3H -> 1H + 10He
172
      TLorentzVector lv8Heb;
173
      gMC->TrackMomentum(lv8Heb);
174
      
175
      if (lv8Heb.P() == 0) { // temporary fix of bug with zero kinetic energy
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(); //Get Pcm 3 vector
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;  // excitation energy
197
      while (reactionHappen==kFALSE) { // while reaction condition is not fullfilled   
198
        decay10HeMass = f10HeMass;
199
        if (fIs10HeExcitationSet) {
200
          Double_t randWeight = gRandom->Uniform(0., f10HeExcitationWeight.back());
201
          Int_t distribNum = 0;
202
          // choose distribution by weight
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) { // выход из цикла while для PhaseGenerator
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
      //7H → f3H + n +n +n +n
229
          //10He -> 8He + n + n
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
      // std::cout << "He8TrackNb " << He8TrackNb << std::endl;
239
      /*                                                                                                                                                                        //???????????
240
      gMC->GetStack()->PushTrack(1, He8TrackNb, f7H->PdgCode(),                                                
241
                                 fLv7H->Px(), fLv7H->Py(), fLv7H->Pz(),
242
                                 fLv7H->E(), curPos.X(), curPos.Y(), curPos.Z(),
243
                                 gMC->TrackTime(), 0., 0., 0.,
244
                                 kPDecay, H7TrackNb, decay7HMass, 0);*/
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
  // Energy of 1-st particle in cm.
318
  // total energy of the first particle is calculated as
319
  Double_t E1 = 0.5 * (Ecm * Ecm + m1 * m1 - m2 * m2) / Ecm;
320

    
321
  //Impulse in CM
322
  Double_t Pcm = TMath::Sqrt(E1 * E1 - m1 * m1);
323
  //Generate angles of particles in CM
324
  Double_t thetaCM;
325
  if(!fADInput) { // if file with angular distribution isn't setted than isotropic distribution is generated
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 == ""){ // if decay file not defined, per morm decay using phase space
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
  // Fill momentum vectors in CM.
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
  // Apply scale factor
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
  // on each step of creating distribution function returns interpolated value of input data
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) { //if there are no points in input file
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();  // get first column variables that contains number of point 
434

    
435
  // Creation of angular distribution function using class member function.
436
  // Constructor divides interval (0; fADInput->GetN()-1) into grid.
437
  // On each step of grid it calls ADEvaluate() to get interpolated values of input data.
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)