SND@LHC Software
Loading...
Searching...
No Matches
g4Ex.py
Go to the documentation of this file.
1from __future__ import print_function
2debug = False
3withNtuple = True
4muonNuclear = True
5model = "QGSP_BERT_EMX"
6runnr = 1
7nev = 100
8nevTot = 0
9myEventnr = 0
10mytrack = 1
11scoreLog = 1
12myTimer = {'total':0,'pythia':0,'geant4_conv':0}
13ecut = 10 # GeV with 1 : ~1sec / event, with 2: 0.4sec / event, 10: 0.13sec
14 # pythia = geant4 conversion = 0.4/100
15# should divide number of events over different ecut values.
16import os
17
18tauOnly = False
19if len(os.sys.argv)>1:
20 runnr = int(os.sys.argv[1])
21 nev = int(os.sys.argv[2])
22 ecut = float(os.sys.argv[3])
23 if len(os.sys.argv)>4: tauOnly = True
24
25# ==================================================================
26# ROOT IMPORT #
27# ==================================================================
28import ROOT,time
29from ROOT import TLorentzVector
30# ==================================================================
31# GEANT4 IMPORT #
32# ==================================================================
33from Geant4 import *
34import g4py.NISTmaterials
35import g4py.ezgeom
36from g4py.ezgeom import G4EzVolume
37# ==================================================================
38# PYTHIA8 PART #
39# ==================================================================
40ROOT.gSystem.Load("libEG")
41ROOT.gSystem.Load("libpythia8")
42ROOT.gSystem.Load("libEGPythia8")
43myPythia = ROOT.TPythia8()
44rnr = ROOT.TRandom()
45# Configure myPythia.listAll()
46# myPythia.list(431)
47
48myPythia.ReadString("SoftQCD:inelastic = on")
49myPythia.ReadString("SoftQCD:singleDiffractive = on")
50myPythia.ReadString("SoftQCD:doubleDiffractive = on")
51myPythia.ReadString("SoftQCD:centralDiffractive = on")
52myPythia.ReadString("PhotonCollision:gmgm2mumu = on")
53myPythia.ReadString("PromptPhoton:all = on")
54myPythia.ReadString("WeakBosonExchange:all = on")
55# http://home.thep.lu.se/~torbjorn/pythia81html/ParticleDecays.html
56if tauOnly :
57 myPythia.ReadString("431:new D_s+ D_s- 1 3 0 1.96849 0.00000 0.00000 0.00000 1.49900e-01 0 1 0 1 0")
58 myPythia.ReadString("431:addChannel = 1 0.0640000 0 -15 16")
59
60
61# set random number seed
62myPythia.ReadString("Random:setSeed = On")
63R = int(time.time()%900000000)
64myPythia.ReadString("Random:seed = "+str(R))
65# Initialize proton (400GeV) on proton at rest
66myPythia.Initialize(2212,2212,400.,0.) # required to hack TPythia8 in root !
67# W = 74 protons and 184-74= 110 neutrons
68
69if tauOnly: myPythia.Plist(431)
70
71# Open an output file
72h = {}
73if withNtuple:
74 f = ROOT.TFile.Open('pythia8_Geant4_'+str(runnr)+'_'+str(ecut)+'.root', 'RECREATE')
75 h['ntuple'] = ROOT.TNtuple("pythia8-Geant4","muon/nu flux","id:px:py:pz:x:y:z:pythiaid:parentid")
76
77leptons = [12,13,14,15,16] # nu_e, mu, nu_mu, tau, nu_tau
78pionkaons = [211,321]
79rest = [130,310,3122]
80allPart = []
81allPart.extend(leptons)
82allPart.extend(pionkaons)
83allPart.extend(rest)
84notWanted = [22,11,-11,990]
85# ==================================================================
86# Geant4 PART #
87# ==================================================================
88# ------------------------------------------------------------------
89# randum number
90# ------------------------------------------------------------------
91rand_engine = Ranlux64Engine()
92HepRandom.setTheEngine(rand_engine)
93HepRandom.setTheSeed(runnr)
94# ==================================================================
95# user actions in python
96# ==================================================================
97# ------------------------------------------------------------------
98class MyGeneratorAction(G4VUserPrimaryGeneratorAction):
99 " My Generator Action"
100 def GeneratePrimaries(self,anEvent):
101 global debug,nevTot
102 t_0 = time.time()
103 npart = 0
104 while npart == 0:
105 myPythia.GenerateEvent()
106 nevTot+=1
107 myTimer['pythia']+=time.time()-t_0
108# pythia interaction happens at 0,0,0
109 #x = rnr.Uniform(-3.,3.)
110 #y = rnr.Uniform(-3.,3.)
111 # leave this smearing for later
112 pos = G4ThreeVector(0*cm, 0*cm, -50*m)
113 vertex = G4PrimaryVertex(pos,0.)
114 # create new primaries and set them to the vertex
115 particles = myPythia.GetListOfParticles()
116 for p in particles:
117 if p.GetStatusCode()!=1 : continue
118 pid = p.GetPdgCode()
119 if tauOnly and abs(pid) != 16: continue
120 if pid in notWanted : continue
121 G4particle = G4PrimaryParticle( pid )
122 v = TLorentzVector()
123 p.Momentum(v)
124 if v.E()*GeV < ecut : continue
125 G4particle.Set4Momentum( v.Px()*GeV,v.Py()*GeV,v.Pz()*GeV,v.E()*GeV )
126 vertex.SetPrimary( G4particle )
127# store mother ID
128 mkey = p.GetMother(0)+1
129 mother = myPythia.GetParticle(mkey)
130 curPid = p.GetPdgCode() + 10000 # make it positive
131 moPid = mother.GetPdgCode() + 10000
132 w = curPid + moPid * 100000
133 G4particle.SetWeight(w)
134 npart += 1
135 if tauOnly and debug: myPythia.EventListing()
136 anEvent.AddPrimaryVertex( vertex )
137 myTimer['geant4_conv']+=time.time()-t_0
138class MyRunAction(G4UserRunAction):
139 "My Run Action"
140
141 def EndOfRunAction(self, run):
142 global debug,nevTot
143 print("*** End of Run")
144 print("- Run summary : (id= %d, #events= %d)" \
145 % (run.GetRunID(), nevTot))
146 h['ntuple'].Fill(-1., float(nevTot) )
147 h['ntuple'].Write()
148 print('lepton masses used')
149 for l in leptons:
150 G4particle = G4PrimaryParticle( l )
151 G4def = G4particle.GetParticleDefinition()
152 print(l, G4def.GetParticleName(), G4particle.GetMass())
153
154# ------------------------------------------------------------------
155class MyEventAction(G4UserEventAction):
156 "My Event Action"
157 def EndOfEventAction(self, event):
158 global myEventnr
159 myEventnr += 1
160 # self.myPrintout(event)
161 def myPrintout(self, event):
162 prim = event.GetPrimaryVertex()
163 print('vertex ',prim.GetX0()/m,prim.GetY0()/m,prim.GetZ0()/m)
164 for k in range( prim.GetNumberOfParticle() ):
165 p = prim.GetPrimary(k)
166 print('event',p.GetPDGcode(),p.GetPx()/GeV,p.GetPy()/GeV,p.GetPz()/GeV)
167# ------------------------------------------------------------------
168class MySteppingAction(G4UserSteppingAction):
169 "My Stepping Action"
170
171 def UserSteppingAction(self, step):
172 pass
173
174# ------------------------------------------------------------------
175class MyTrackingAction(G4UserTrackingAction):
176 def PostUserTrackingAction(self,atrack):
177 pass
178 def PreUserTrackingAction(self,atrack):
179 # self.myPrintout(atrack)
180 if atrack.GetTotalEnergy()/GeV < ecut :
181 G4TrackingManager().SetStoreTrajectory(False)
182 atrack.SetTrackStatus(atrack.GetTrackStatus().fStopAndKill)
183 part = atrack.GetDynamicParticle()
184 pid = part.GetPDGcode()
185 if pid in notWanted:
186 G4TrackingManager().SetStoreTrajectory(False)
187 atrack.SetTrackStatus(atrack.GetTrackStatus().fStopAndKill)
188
189 def myPrintout(self, atrack):
190 part = atrack.GetDynamicParticle()
191 pid = part.GetPDGcode()
192 print('TA',pid,atrack.GetTotalEnergy()/GeV,ecut*GeV)
193
194# ------------------------------------------------------------------
195class ScoreSD(G4VSensitiveDetector):
196 "SD for score voxels"
197
198 def __init__(self,Name):
199 G4VSensitiveDetector.__init__(self, Name)
200
201 def ProcessHits(self, step, rohist):
202 preStepPoint = step.GetPreStepPoint()
203 track = step.GetTrack()
204 part = track.GetDynamicParticle()
205 pid = part.GetPDGcode()
206 if abs(pid) in leptons :
207 mom = track.GetMomentum()
208 pos = track.GetPosition()
209#
210 # primPart = part.GetPrimaryParticle()
211 w = track.GetWeight()
212 parentid = int(w)/100000-10000
213 pythiaid = int(w)%100000-10000
214 h['ntuple'].Fill(float(pid), float(mom.x/GeV),float(mom.y/GeV),float(mom.z/GeV),
215 float(pos.x/m),float(pos.y/m),float(pos.z/m),pythiaid,parentid)
216 #print 'xxx',pid, float(mom.x/GeV),float(mom.y/GeV),float(mom.z/GeV),pythiaid,parentid,float(pos.x/m),float(pos.y/m),float(pos.z/m)
217 #myPythia.EventListing()
218
220 print("* Constructing geometry...")
221 world_r = 100.*m
222 # reset world material
223 vac = G4Material.GetMaterial("G4_Galactic")
224 g4py.ezgeom.SetWorldMaterial(vac)
225 g4py.ezgeom.ResizeWorld(world_r, world_r, world_r)
226 # a snoopy world is placed
227 global snoopy,snoopyPhys,scoreLog
228 snoopy = G4EzVolume("Snoopy")
229 snoopy.CreateTubeVolume(vac, 0., 10*m, 50.*m)
230 snoopyPhys = snoopy.PlaceIt(G4ThreeVector(0.,0.,0.*m))
231 snoopyLog = snoopyPhys.GetLogicalVolume()
232 snoopy.SetVisibility(False)
233 # a target box is placed
234 global target,targetPhys
235 iron = G4Material.GetMaterial("G4_Fe")
236 air = G4Material.GetMaterial("G4_AIR")
237 tungsten = G4Material.GetMaterial("G4_W")
238 lead = G4Material.GetMaterial("G4_Pb")
239 alum = G4Material.GetMaterial("G4_Al")
240 target = G4EzVolume("Target")
241 target.CreateTubeVolume(tungsten, 0., 25.*cm, 25.*cm)
242 targetPhys = target.PlaceIt(G4ThreeVector(0.,0.,-50.*m+25.*cm),1,snoopy)
243 target.SetColor(G4Color(0.0,0.5,0.5,1.0))
244 target.SetVisibility(True)
245 # = 0.1m3 = 2t
246 # a hadron absorber is placed
247 absorber = G4EzVolume("Absorber")
248# iron alloys saturate at 1.6-2.2T
249 # inner radius outer radius length
250 absorber.CreateTubeVolume(iron, 0., 100.*cm, 150.*cm)
251 absorberPhys = absorber.PlaceIt(G4ThreeVector(0.,0.,-50*m+2*25.*cm+150.*cm),1,snoopy)
252 absorber.SetColor(G4Color(0.898,0.902,0.91,1.0))
253 absorber.SetVisibility(True)
254 xx = G4VisAttributes()
255 xx.SetForceWireframe(True)
256 absorberlog = absorberPhys.GetLogicalVolume()
257 absorberlog.SetVisAttributes(xx)
258# scoring plane
259 scorez = -50.*m+2*25.*cm+2*150.*cm+1*mm
260 score = G4EzVolume("Score")
261 score.CreateTubeVolume(vac, 0., 50.*m, 1.*mm)
262 scorePhys = score.PlaceIt(G4ThreeVector(0.,0.,scorez),1,snoopy)
263 scoreLog = scorePhys.GetLogicalVolume()
264 g4py.ezgeom.Construct()
265
266g4py.NISTmaterials.Construct()
267#print Geant4.gMaterialTable
268if not muonNuclear:
269 physList = Geant4.FTFP_BERT()
270 gRunManager.SetUserInitialization(physList)
271# with muon nuclear
272else:
273 if 'G4PhysListFactory' in dir(G4physicslists):
274 factory = G4physicslists.G4PhysListFactory()
275 xx = factory.GetReferencePhysList(model)
276 else: xx = G4physicslists.GetReferencePhysList(model)
277 gRunManager.SetUserInitialization(xx)
278
280gRunManager.SetUserAction(myGE)
281#
283gRunManager.SetUserAction(myTA)
284#
285
287
289gRunManager.SetUserAction(myRA)
290
292gRunManager.SetUserAction(myEA)
293
294# initialize
295gRunManager.Initialize()
296# scoring should be set after geometry construction
297sens = ScoreSD('Score')
298scoreLog.SetSensitiveDetector(sens)
299
300t0 = time.time()
301gRunManager.BeamOn(nev)
302t1 = time.time()
303print('Time used',t1-t0, ' seconds')
304for x in myTimer:
305 print(x,myTimer[x])
306
myPrintout(self, event)
Definition g4Ex.py:161
EndOfEventAction(self, event)
Definition g4Ex.py:157
GeneratePrimaries(self, anEvent)
Definition g4Ex.py:100
EndOfRunAction(self, run)
Definition g4Ex.py:141
UserSteppingAction(self, step)
Definition g4Ex.py:171
PostUserTrackingAction(self, atrack)
Definition g4Ex.py:176
myPrintout(self, atrack)
Definition g4Ex.py:189
PreUserTrackingAction(self, atrack)
Definition g4Ex.py:178
__init__(self, Name)
Definition g4Ex.py:198
ProcessHits(self, step, rohist)
Definition g4Ex.py:201
ConstructGeom()
Definition g4Ex.py:219