ERDecayEXP1803.cxx

Ivan Muzalevsky, 03/20/2018 06:09 PM

Download (13.1 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 "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)