SND@LHC Software
Loading...
Searching...
No Matches
MuonBackGenerator.cxx
Go to the documentation of this file.
1#include <math.h>
2#include "TSystem.h"
3#include "TROOT.h"
4#include "TRandom.h"
5#include "TFile.h"
6#include "TVector.h"
7#include "FairPrimaryGenerator.h"
8#include "MuonBackGenerator.h"
9#include "TDatabasePDG.h" // for TDatabasePDG
10#include "TMath.h" // for Sqrt
11#include "vetoPoint.h"
12#include "ShipMCTrack.h"
13#include "TMCProcess.h"
14#include <algorithm>
15#include <unordered_map>
16
17// read events from Pythia8/Geant4 base simulation (only target + hadron absorber
18
19// ----- Default constructor -------------------------------------------
23// -------------------------------------------------------------------------
24// ----- Default constructor -------------------------------------------
25Bool_t MuonBackGenerator::Init(const char* fileName) {
26 return Init(fileName, 0, false);
27}
28// ----- Default constructor -------------------------------------------
29Bool_t MuonBackGenerator::Init(const char* fileName, const int firstEvent, const Bool_t fl = false ) {
30 LOGF(info, "Opening input file %s", fileName);
31 if (0 == strncmp("/eos",fileName,4) ) {
32 TString tmp = gSystem->Getenv("EOSSHIP");
33 tmp+=fileName;
34 fInputFile = TFile::Open(tmp);
35 }else{
36 fInputFile = new TFile(fileName);
37 }
38 if (fInputFile->IsZombie()) {
39 LOGF(fatal, "Error opening the Signal file:%s", fileName);
40 }
41 fn = firstEvent;
42 fPhiRandomize = fl;
43 fSameSeed = 0;
44 fsmearBeam = 0; // default no beam smearing, use SetSmearBeam(sb) if different, sb [cm]
45 fdownScaleDiMuon = kFALSE; // only needed for muflux simulation
46 fTree = (TTree *)fInputFile->Get("pythia8-Geant4");
47 if (fTree){
48 fNevents = fTree->GetEntries();
49 // count only events with muons
50 // fMuons = fTree->Draw("id","abs(id)==13","goff");
51 fTree->SetBranchAddress("id",&id); // particle id
52 fTree->SetBranchAddress("parentid",&parentid); // parent id, could be different
53 fTree->SetBranchAddress("pythiaid",&pythiaid); // pythiaid original particle
54 fTree->SetBranchAddress("ecut",&ecut); // energy cut used in simulation
55 fTree->SetBranchAddress("w",&w); // weight of event
56// check if ntuple has information of momentum at origin
57 if (fTree->GetListOfLeaves()->GetSize() < 17){
58 fTree->SetBranchAddress("x",&vx); // position with respect to startOfTarget at -89.27m
59 fTree->SetBranchAddress("y",&vy);
60 fTree->SetBranchAddress("z",&vz);
61 fTree->SetBranchAddress("px",&px); // momentum
62 fTree->SetBranchAddress("py",&py);
63 fTree->SetBranchAddress("pz",&pz);
64 }else{
65 fTree->SetBranchAddress("ox",&vx); // position with respect to startOfTarget at -50m
66 fTree->SetBranchAddress("oy",&vy);
67 fTree->SetBranchAddress("oz",&vz);
68 fTree->SetBranchAddress("opx",&px); // momentum
69 fTree->SetBranchAddress("opy",&py);
70 fTree->SetBranchAddress("opz",&pz);
71 }
72 }else{
73 id = -1;
74 fTree = (TTree *)fInputFile->Get("cbmsim");
75 fNevents = fTree->GetEntries();
76 MCTrack = new TClonesArray("ShipMCTrack");
77 vetoPoints = new TClonesArray("vetoPoint");
78 fTree->SetBranchAddress("MCTrack",&MCTrack);
79 fTree->SetBranchAddress("vetoPoint",&vetoPoints);
80 }
81 return kTRUE;
82}
83// ----- Destructor ----------------------------------------------------
87// -------------------------------------------------------------------------
88Bool_t MuonBackGenerator::checkDiMuon(Int_t muIndex){
89 Bool_t check = false;
90 ShipMCTrack* mu = (ShipMCTrack*)MCTrack->At(muIndex);
91 TString pName = mu->GetProcName();
92 if ( strncmp("Hadronic inelastic", pName.Data(),18)==0 ||
93 strncmp("Positron annihilation" ,pName.Data(),21)==0 ||
94 strncmp("Lepton pair production",pName.Data(),22)==0){
95 check = true;}
96 Int_t Pcode = TMath::Abs( ((ShipMCTrack*)MCTrack->At(mu->GetMotherId()))->GetPdgCode());
97 if (Pcode==221 || Pcode==223 || Pcode==333 || Pcode==113 || Pcode == 331){
98 check = true;}
99 return check;
100}
101
102// ----- Passing the event ---------------------------------------------
103Bool_t MuonBackGenerator::ReadEvent(FairPrimaryGenerator* cpg)
104{
105 TDatabasePDG* pdgBase = TDatabasePDG::Instance();
106 Double_t mass,e,tof,phi;
107 Double_t dx = 0, dy = 0;
108 std::unordered_map<int, int> muList;
109 std::unordered_map<int, std::vector<int>> moList;
110 while (fn<fNevents) {
111 fTree->GetEntry(fn);
112 muList.clear();
113 moList.clear();
114 fn++;
115 if (fn%100000==0) {
116 LOGF(info, "Reading event %i", fn);
117 }
118// test if we have a muon, don't look at neutrinos:
119 if (TMath::Abs(int(id))==13) {
120 mass = pdgBase->GetParticle(id)->Mass();
121 e = TMath::Sqrt( px*px+py*py+pz*pz+mass*mass );
122 tof = 0;
123 break;}
124 if (id==-1){ // use tree as input file
125 Bool_t found = false;
126 for (int i = 0; i < vetoPoints->GetEntries(); i++) {
127 vetoPoint *v = (vetoPoint*)vetoPoints->At(i);
128 Int_t abspid = TMath::Abs(v->PdgCode());
129 if (abspid==13 or (not followMuons and abspid!=12 and abspid!=14) ){
130 found = true;
131 Int_t muIndex = v->GetTrackID();
132 if (!fdownScaleDiMuon) {muList.insert( { muIndex,i }); }
133 else if (abspid==13 ){
134 if ( checkDiMuon(muIndex) ){
135 moList[ ((ShipMCTrack*)MCTrack->At(muIndex))->GetMotherId()].push_back(i);
136 }
137 else{
138 muList.insert( { muIndex,i });
139 }
140 }
141 }
142 }
143// reject muon if comes from boosted channel
144
145 std::unordered_map<int, std::vector<int>>::iterator it = moList.begin();
146 while( it!=moList.end()){
147 if (gRandom->Uniform(0.,1.)>0.99){
148 std::vector<int> list = it->second;
149 for ( Int_t i=0;i < list.size(); i++){
150 vetoPoint *v = (vetoPoint*)vetoPoints->At(list.at(i));
151 Int_t muIndex = v->GetTrackID();
152 muList.insert( { muIndex,i });
153 }
154 }
155 it++;
156 }
157 if (!found) {
158 LOGF(warn, "No muon found %i", fn-1);
159 }
160 if (found) {break;}
161 }
162 }
163 if (fn>fNevents-1){
164 LOGF(info, "End of file reached %i", fNevents);
165 return kFALSE;
166 }
167 if (fSameSeed) {
168 Int_t theSeed = fn + fSameSeed * fNevents;
169 LOGF(debug, "Seed: %d", theSeed);
170 gRandom->SetSeed(theSeed);
171 }
172 if (fPhiRandomize){phi = gRandom->Uniform(0.,2.) * TMath::Pi();}
173 if (fsmearBeam > 0) {
174 Double_t r = fsmearBeam + 0.8 * gRandom->Gaus();
175 Double_t _phi = gRandom->Uniform(0., 2.) * TMath::Pi();
176 dx = r * TMath::Cos(_phi);
177 dy = r * TMath::Sin(_phi);
178 }
179 if (id==-1){
180 for (unsigned i = 0; i< MCTrack->GetEntries(); i++ ){
181 ShipMCTrack* track = (ShipMCTrack*)MCTrack->At(i);
182 Int_t abspid = TMath::Abs(track->GetPdgCode());
183 px = track->GetPx();
184 py = track->GetPy();
185 pz = track->GetPz();
186 if (fPhiRandomize){
187 Double_t phi0 = TMath::ATan2(py,px);
188 Double_t pt = track->GetPt();
189 px = pt*TMath::Cos(phi+phi0);
190 py = pt*TMath::Sin(phi+phi0);
191 }
192 vx = track->GetStartX()+dx;
193 vy = track->GetStartY()+dy;
194 vz = track->GetStartZ();
195 tof = track->GetStartT()/1E9; // convert back from ns to sec;
196 e = track->GetEnergy();
197 Bool_t wanttracking = false; // only transport muons
198 for (std::pair<int, int> element : muList){
199 if (element.first==i){
200 wanttracking = true;
201 if (not followMuons){
202 vetoPoint* v = (vetoPoint*)vetoPoints->At(element.second);
203 TVector3 lpv = v->LastPoint();
204 TVector3 lmv = v->LastMom();
205 if (abspid == 22){ e=lmv.Mag();}
206 else{ e = TMath::Sqrt(lmv.Mag2()+(track->GetMass())*(track->GetMass()));}
207 px = lmv[0];
208 py = lmv[1];
209 pz = lmv[2];
210 vx = lpv[0];
211 vy = lpv[1];
212 vz = lpv[2];
213 tof = v->GetTime()/1E9; // convert back from ns to sec
214 }
215 break;
216 }
217 }
218 cpg->AddTrack(track->GetPdgCode(),px,py,pz,vx,vy,vz,track->GetMotherId(),wanttracking,e,tof,track->GetWeight(),(TMCProcess)track->GetProcID());
219 }
220 }else{
221 vx += dx/100.;
222 vy += dy/100.;
223 if (fPhiRandomize){
224 Double_t pt = TMath::Sqrt( px*px+py*py );
225 px = pt*TMath::Cos(phi);
226 py = pt*TMath::Sin(phi);
227 }
228 cpg->AddTrack(int(pythiaid),px,py,pz,vx*100.,vy*100.,vz*100.,-1.,false,e,pythiaid,parentid);
229 cpg->AddTrack(int(id),px,py,pz,vx*100.,vy*100.,vz*100.,-1.,true,e,tof,w);
230 }
231 return kTRUE;
232}
233
234// -------------------------------------------------------------------------
236{
237 return fNevents;
238}
240{
241 fInputFile->Close();
242 fInputFile->Delete();
243 delete fInputFile;
244}
245
TClonesArray * MCTrack
TClonesArray * vetoPoints
Bool_t checkDiMuon(Int_t muIndex)
virtual Bool_t Init(const char *, int, const Bool_t fl)
Bool_t ReadEvent(FairPrimaryGenerator *)
ClassImp(ecalContFact) ecalContFact