SND@LHC Software
Loading...
Searching...
No Matches
HNLPythia8Generator.cxx
Go to the documentation of this file.
1#include <math.h>
2#include "TSystem.h"
3#include "TROOT.h"
4#include "TMath.h"
5#include "FairPrimaryGenerator.h"
6#include "TDatabasePDG.h" // for TDatabasePDG
8const Double_t cm = 10.; // pythia units are mm
9const Double_t c_light = 2.99792458e+10; // speed of light in cm/sec (c_light = 2.99792458e+8 * m/s)
10const Bool_t debug = false;
11//using namespace Pythia8;
12
13// ----- Default constructor -------------------------------------------
15{
16 fId = 2212; // proton
17 fMom = 400; // proton
18 fHNL = 9900015; // HNL pdg code
19 fLmin = 5000.*cm; // mm minimum decay position z ROOT units !
20 fLmax = 12000.*cm; // mm maximum decay position z
21 fFDs = 7.7/10.4; // correction for Pythia6 to match measured Ds production
22 fextFile = "";
23 fInputFile = NULL;
24 fnRetries = 0;
25 fShipEventNr = 0;
26 fPythia = new Pythia8::Pythia();
27}
28// -------------------------------------------------------------------------
29
30// ----- Default constructor -------------------------------------------
32{
33 if ( debug ){List(9900015);}
36 fPythia->setRndmEnginePtr(fRandomEngine);
37 fn = 0;
38 if (fextFile && *fextFile) {
39 if (0 == strncmp("/eos",fextFile,4) ) {
40 TString tmp = gSystem->Getenv("EOSSHIP");
41 tmp+=fextFile;
42 fInputFile = TFile::Open(tmp);
43 LOGF(info, "Open external file with charm or beauty hadrons on eos: %s", tmp.Data());
44 if (!fInputFile) {
45 LOG(FATAL) << "Error opening input file. You may have forgotten to provide a krb5 token. Try kinit username@lxplus.cern.ch";
46 return kFALSE; }
47 }else{
48 LOGF(info, "Open external file with charm or beauty hadrons: %s", fextFile);
49 fInputFile = new TFile(fextFile);
50 if (!fInputFile) {
51 LOG(FATAL) << "Error opening input file";
52 return kFALSE; }
53 }
54 if (fInputFile->IsZombie()) {
55 LOG(FATAL) << "File is corrupted";
56 return kFALSE; }
57 fTree = (TTree *)fInputFile->Get("pythia6");
58 fNevents = fTree->GetEntries();
59 fn = firstEvent;
60 fTree->SetBranchAddress("id",&hid); // particle id
61 fTree->SetBranchAddress("px",&hpx); // momentum
62 fTree->SetBranchAddress("py",&hpy);
63 fTree->SetBranchAddress("pz",&hpz);
64 fTree->SetBranchAddress("E",&hE);
65 fTree->SetBranchAddress("M",&hM);
66 fTree->SetBranchAddress("mid",&mid); // mother
67 fTree->SetBranchAddress("mpx",&mpx); // momentum
68 fTree->SetBranchAddress("mpy",&mpy);
69 fTree->SetBranchAddress("mpz",&mpz);
70 fTree->SetBranchAddress("mE",&mE);
71 }else{
72 if ( debug ){std::cout<<"Beam Momentum "<<fMom<<std::endl;}
73 fPythia->settings.mode("Beams:idA", fId);
74 fPythia->settings.mode("Beams:idB", 2212);
75 fPythia->settings.mode("Beams:frameType", 2);
76 fPythia->settings.parm("Beams:eA",fMom);
77 fPythia->settings.parm("Beams:eB",0.);
78 }
79 TDatabasePDG* pdgBase = TDatabasePDG::Instance();
80 Double_t root_ctau = pdgBase->GetParticle(fHNL)->Lifetime();
81 fctau = fPythia->particleData.tau0(fHNL); //* 3.3333e-12
82 if ( debug ){
83 std::cout<<"tau root "<<root_ctau<< "[s] ctau root = " << root_ctau*3e10 << "[cm]"<<std::endl;
84 std::cout<<"ctau pythia "<<fctau<<"[mm]"<<std::endl;
85 List(9900015);
86 }
87 fPythia->init();
88 return kTRUE;
89}
90// -------------------------------------------------------------------------
91
92
93// ----- Destructor ----------------------------------------------------
97// -------------------------------------------------------------------------
98
99// ----- Passing the event ---------------------------------------------
100Bool_t HNLPythia8Generator::ReadEvent(FairPrimaryGenerator* cpg)
101{
102 Double_t tp,td,tS,zp,xp,yp,zd,xd,yd,zS,xS,yS,pz,px,py,e,w;
103 Double_t tm,zm,xm,ym,pmz,pmx,pmy,em;
104 Int_t im;
105// take HNL decay of Pythia, move it to the SHiP decay region
106// recalculate decay time
107// weight event with exp(-t_ship/tau_HNL) / exp(-t_pythia/tau_HNL)
108
109 int iHNL = 0; // index of the chosen HNL (the 1st one), also ensures that at least 1 HNL is produced
110 std::vector<int> dec_chain; // pythia indices of the particles to be stored on the stack
111 std::vector<int> hnls; // pythia indices of HNL particles
112 do {
113
114 if (fextFile && *fextFile) {
115// take charm or beauty hadron from external file
116// correct for too much Ds produced by pythia6
117 bool x = true;
118 while(x){
119 if (fn==fNevents) {LOG(WARNING) << "End of input file. Rewind.";}
120 fTree->GetEntry(fn%fNevents);
121 fn++;
122 if ( int(fabs(hid[0]) ) != 431){ x = false; }
123 else {
124 Double_t rnr = gRandom->Uniform(0,1);
125 if( rnr<fFDs ) { x = false; };
126 //cout<<"what is x "<<x<<" id "<<int(fabs(hid[0]))<<" rnr " << rnr <<" "<< fFDs <<std::endl ;
127 }
128 }
129 fPythia->event.reset();
130 fPythia->event.append( (Int_t)hid[0], 1, 0, 0, hpx[0], hpy[0], hpz[0], hE[0], hM[0], 0., 9. );
131 }
132 fPythia->next();
133 for(int i=0; i<fPythia->event.size(); i++){
134// find first HNL
135 if (abs(fPythia->event[i].id())==fHNL){
136 hnls.push_back( i );
137 }
138 }
139 iHNL = hnls.size();
140 if ( iHNL == 0 ){
141 //fLogger->Info(MESSAGE_ORIGIN,"Event without HNL. Retry.");
142 //fPythia->event.list();
143 fnRetries+=1; // can happen if phasespace does not allow charm hadron to decay to HNL
144 }else{
145 int r = int( gRandom->Uniform(0,iHNL) );
146 // cout << " ----> debug 2 " << r << endl;
147 int i = hnls[r];
148 // production vertex
149 zp =fPythia->event[i].zProd();
150 xp =fPythia->event[i].xProd();
151 yp =fPythia->event[i].yProd();
152 tp =fPythia->event[i].tProd();
153 // momentum
154 pz =fPythia->event[i].pz();
155 px =fPythia->event[i].px();
156 py =fPythia->event[i].py();
157 e =fPythia->event[i].e();
158 // old decay vertex
159 Int_t ida =fPythia->event[i].daughter1();
160 zd =fPythia->event[ida].zProd();
161 xd =fPythia->event[ida].xProd();
162 yd =fPythia->event[ida].yProd();
163 td =fPythia->event[ida].tProd();
164 // new decay vertex
165 Double_t LS = gRandom->Uniform(fLmin,fLmax); // mm, G4 and Pythia8 units
166 Double_t p = TMath::Sqrt(px*px+py*py+pz*pz);
167 Double_t lam = LS/p;
168 xS = xp + lam * px;
169 yS = yp + lam * py;
170 zS = zp + lam * pz;
171 Double_t gam = e/TMath::Sqrt(e*e-p*p);
172 Double_t beta = p/e;
173 tS = tp + LS/beta; // units ? [mm/c] + [mm/beta] (beta is dimensionless speed, and c=1 here)
174 // if one would use [s], then tS = tp/(cm*c_light) + (LS/cm)/(beta*c_light) = tS/(cm*c_light) i.e. units look consisent
175 w = TMath::Exp(-LS/(beta*gam*fctau))*( (fLmax-fLmin)/(beta*gam*fctau) );
176 im = (Int_t)fPythia->event[i].mother1();
177 zm =fPythia->event[im].zProd();
178 xm =fPythia->event[im].xProd();
179 ym =fPythia->event[im].yProd();
180 pmz =fPythia->event[im].pz();
181 pmx =fPythia->event[im].px();
182 pmy =fPythia->event[im].py();
183 em =fPythia->event[im].e();
184 tm =fPythia->event[im].tProd();
185// foresee finite beam size
186 Double_t dx=0;
187 Double_t dy=0;
188 if (fsmearBeam>0){
189 Double_t test = fsmearBeam*fsmearBeam;
190 Double_t Rsq = test+1.;
191 while(Rsq>test){
192 dx = gRandom->Uniform(-1.,1.) * fsmearBeam;
193 dy = gRandom->Uniform(-1.,1.) * fsmearBeam;
194 Rsq = dx*dx+dy*dy;
195 }
196 }
197 if (fextFile && *fextFile) {
198// take grand mother particle from input file, to know if primary or secondary production
199 cpg->AddTrack((Int_t)mid[0],mpx[0],mpy[0],mpz[0],xm/cm+dx,ym/cm+dy,zm/cm,-1,false,mE[0],0.,1.);
200 cpg->AddTrack((Int_t)fPythia->event[im].id(),pmx,pmy,pmz,xm/cm+dx,ym/cm+dy,zm/cm,0,false,em,tm/cm/c_light,w); // convert pythia's (x,y,z[mm], t[mm/c]) to ([cm], [s])
201 cpg->AddTrack(fHNL, px, py, pz, xp/cm+dx,yp/cm+dy,zp/cm, 1,false,e,tp/cm/c_light,w);
202 }else{
203 cpg->AddTrack((Int_t)fPythia->event[im].id(),pmx,pmy,pmz,xm/cm+dx,ym/cm+dy,zm/cm,-1,false,em,tm/cm/c_light,w); // convert pythia's (x,y,z[mm], t[mm/c]) to ([cm], [s])
204 cpg->AddTrack(fHNL, px, py, pz, xp/cm+dx,yp/cm+dy,zp/cm, 0,false,e,tp/cm/c_light,w);
205 }
206 // bookkeep the indices of stored particles
207 dec_chain.push_back( im );
208 dec_chain.push_back( i );
209 //cout << endl << " insert mother pdg=" <<fPythia->event[im].id() << " pmz = " << pmz << " [GeV], zm = " << zm << " [mm] tm = " << tm << " [mm/c]" << endl;
210 //cout << " ----> insert HNL =" << fHNL << " pz = " << pz << " [GeV] zp = " << zp << " [mm] tp = " << tp << " [mm/c]" << endl;
211 iHNL = i;
212 }
213 } while ( iHNL == 0 ); // ----------- avoid rare empty events w/o any HNL's produced
214
215 if (fShipEventNr%100==0) {
216 LOGF(info, "ship event %i / pythia event-nr %i", fShipEventNr, fn);
217 }
218 fShipEventNr += 1;
219 // fill a container with pythia indices of the HNL decay chain
220 for(int k=0; k<fPythia->event.size(); k++){
221 // if daughter of HNL, copy
222 im =fPythia->event[k].mother1();
223 while (im>0){
224 if ( im == iHNL ){break;} // pick the decay products of only 1 chosen HNL
225 // if ( abs(fPythia->event[im].id())==fHNL && im == iHNL ){break;}
226 else {im =fPythia->event[im].mother1();}
227 }
228 if (im < 1) {continue;}
229 dec_chain.push_back( k );
230 }
231
232 // go over daughters and store them on the stack, starting from 2 to account for HNL and its mother
233 for(std::vector<int>::iterator it = dec_chain.begin() + 2; it != dec_chain.end(); ++it){
234 // pythia index of the paricle to store
235 int k = *it;
236 // find mother position on the output stack: impy -> im
237 int impy =fPythia->event[k].mother1();
238 std::vector<int>::iterator itm = std::find( dec_chain.begin(), dec_chain.end(), impy);
239 im =-1; // safety
240 if ( itm != dec_chain.end() )
241 im = itm - dec_chain.begin(); // convert iterator into sequence number
242
243 Bool_t wanttracking=false;
244 if(fPythia->event[k].isFinal()){ wanttracking=true;}
245 pz =fPythia->event[k].pz();
246 px =fPythia->event[k].px();
247 py =fPythia->event[k].py();
248 e =fPythia->event[k].e();
249 if (fextFile && *fextFile) {im+=1;}
250 cpg->AddTrack((Int_t)fPythia->event[k].id(),px,py,pz,xS/cm,yS/cm,zS/cm,im,wanttracking,e,tS/cm/c_light,w);
251 // std::cout <<k<< " insert pdg =" <<fPythia->event[k].id() << " pz = " << pz << " [GeV] zS = " << zS << " [mm] tS = " << tS << "[mm/c]" << endl;
252 }
253 return kTRUE;
254}
255// -------------------------------------------------------------------------
257{
258 // Set Parameters
259 fPythia->readString(par);
260 if ( debug ){std::cout<<"fPythia->readString(\""<<par<<"\")"<<std::endl;}
261}
262
263// -------------------------------------------------------------------------
264
const Double_t c_light
const Double_t cm
const Double_t c_light
const Bool_t debug
Double_t cm
Pythia8::RndmEngine * fRandomEngine
TTree * fTree
pointer to a file
Bool_t ReadEvent(FairPrimaryGenerator *)
Pythia8::Pythia * fPythia
ClassImp(ecalContFact) ecalContFact