SND@LHC Software
Loading...
Searching...
No Matches
run_MufluxfixedTarget.py
Go to the documentation of this file.
1#!/usr/bin/env python
2from __future__ import print_function
3import ROOT,os,sys,getopt,time,shipRoot_conf
4import shipunit as u
5from ShipGeoConfig import ConfigRegistry
6
7mcEngine = "TGeant4"
8simEngine = "Pythia8"
9runnr = 1000
10nev = 500
11checkOverlap = False
12G4only = False
13storeOnlyMuons = False
14withEvtGen = True
15boostDiMuon = 1.
16boostFactor = 1.
17charm = False
18beauty = False
19chicc = 1.7e-3
20chibb = 1.6e-7
21npot = 5E13
22nStart = 0
23
24charmInputFile = "root://eoslhcb.cern.ch//eos/ship/data/Charm/Cascade-parp16-MSTP82-1-MSEL4-76Mpot_1.root"
25nStart = 0
26
27outputDir = "."
28theSeed = int(10000 * time.time() % 10000000)
29work_dir = "./"
30ecut = 0.5 # GeV with 1 : ~1sec / event, with 2: 0.4sec / event, 10: 0.13sec
31
32dy = 10.
33dv = 5 # 4=TP elliptical tank design, 5 = optimized conical rectangular design
34ds = 7 # 5=TP muon shield, 6=magnetized hadron, 7=short magnet design
35nud = 1 # 0=TP, 1=new magnet option for short muon shield, 2= no magnet surrounding neutrino detector
36
37# example for primary interaction, nobias: python $FAIRSHIP/muonShieldOptimization/run_fixedTarget.py -n 10000 -e 10 -f -r 10
38# 10000 events, energy cut 10GeV, run nr 10, override existing output folder
39# example for charm decays, python $FAIRSHIP/muonShieldOptimization/run_fixedTarget.py -C -M -n 10000 -e 10 -r 60 -b 50 -f
40# 10000 events, charm decays, energy cut 10GeV, run nr 60, override existing output folder
41# increase di-muon BRs for resonances < 1.1GeV by a factor 50
42
43#----------------------------- Yandex production ------------------------------
44import shutil
45import argparse
46import logging
47logging.info("")
48logger = logging.getLogger(os.path.splitext(os.path.basename(os.sys.argv[0]))[0])
49logger.setLevel(logging.INFO)
50
51
52def get_work_dir(run_number,tag=None):
53 import socket
54 host = socket.gethostname()
55 job_base_name = os.path.splitext(os.path.basename(os.sys.argv[0]))[0]
56 if tag: out_dir = "{host}_{base}_{runnr}_{comment}".format(host=host, base=job_base_name, runnr=run_number, comment=tag)
57 else: out_dir = "{host}_{base}_{runnr}".format(host=host, base=job_base_name, runnr=run_number)
58 return out_dir
59
60
61def init():
62 global runnr, nev, ecut, G4only, tauOnly,JpsiMainly, work_dir,Debug,withEvtGen,boostDiMuon,\
63 boostFactor,charm,beauty,charmInputFile,nStart,storeOnlyMuons,chicc,chibb,npot, nStart
64 logger.info("SHiP proton-on-taget simulator (C) Thomas Ruf, 2017")
65
66 ap = argparse.ArgumentParser(
67 description='Run SHiP "pot" simulation')
68 ap.add_argument('-d', '--debug', action='store_true', dest='debug')
69 ap.add_argument('-f', '--force', action='store_true', help="force overwriting output directory")
70 ap.add_argument('-cs', '--CharmdetSetup', type=int, dest='CharmdetSetup',help="setting detector setup", default=0)
71 ap.add_argument('-ct', '--CharmTarget', type=int, dest='CharmTarget',help="choosing target configuration for charm exposure", default=3)
72 ap.add_argument('-r', '--run-number', type=int, dest='runnr', default=runnr)
73 ap.add_argument('-e', '--ecut', type=float, help="energy cut", dest='ecut', default=ecut)
74 ap.add_argument('-n', '--num-events', type=int, help="number of events to generate", dest='nev', default=nev)
75 ap.add_argument('-G', '--G4only', action='store_true', dest='G4only', default=False, help="use Geant4 directly, no Pythia8")
76 ap.add_argument('-P', '--PythiaDecay', action='store_true', dest='pythiaDecay', default=False, help="use Pythia8 for decays")
77 ap.add_argument('-V', '--EvtGen', action='store_true', dest='withEvtGen', default=withEvtGen, help="use EvtGen for decays")
78 ap.add_argument('-t', '--tau-only', action='store_true', dest='tauOnly', default=False)
79 ap.add_argument('-J', '--Jpsi-mainly', action='store_true', dest='JpsiMainly', default=False)
80 ap.add_argument('-b', '--boostDiMuon', type=float, dest='boostDiMuon', default=boostDiMuon, help="boost Di-muon branching ratios")
81 ap.add_argument('-X', '--boostFactor', type=float, dest='boostFactor', default=boostFactor, help="boost Di-muon prod cross sections")
82 ap.add_argument('-C', '--charm', action='store_true', dest='charm', default=charm, help="generate charm decays")
83 ap.add_argument('-B', '--beauty', action='store_true', dest='beauty', default=beauty, help="generate beauty decays")
84 ap.add_argument('-M', '--storeOnlyMuons', action='store_true', dest='storeOnlyMuons', default=storeOnlyMuons, help="store only muons, ignore neutrinos")
85# for charm production
86 ap.add_argument('-cc','--chicc',action='store_true', dest='chicc', default=chicc, help="ccbar over mbias cross section")
87 ap.add_argument('-bb','--chibb',action='store_true', dest='chibb', default=chibb, help="bbbar over mbias cross section")
88 ap.add_argument('-p','--pot',action='store_true', dest='npot', default=npot, help="number of protons on target per spill to normalize on")
89 ap.add_argument('-S','--nStart',action='store_true', dest='nStart', default=nStart, help="first event of input file to start")
90 ap.add_argument('-I', '--InputFile', type=str, dest='charmInputFile', default=charmInputFile, help="input file for charm/beauty decays")
91 ap.add_argument('-o','--output' , type=str, help="output directory", dest='work_dir', default=None)
92 args = ap.parse_args()
93 if args.debug:
94 logger.setLevel(logging.DEBUG)
95 runnr = args.runnr
96 nev = args.nev
97 ecut = args.ecut
98 tauOnly = args.tauOnly
99 JpsiMainly = args.JpsiMainly
100 G4only = args.G4only
101 boostFactor = args.boostFactor
102 boostDiMuon = args.boostDiMuon
103 storeOnlyMuons = args.storeOnlyMuons
104 if G4only:
105 args.charm = False
106 args.beauty = False
107 args.withEvtGen = False
108 args.pythiaDecay = False
109 elif args.pythiaDecay:
110 withEvtGen = False
111 args.withEvtGen = False
112 logger.info("use Pythia8 as primary decayer")
113 else:
114 withEvtGen = True
115 logger.info("use EvtGen as primary decayer")
116 withEvtGen = args.withEvtGen
117 charm = args.charm
118 beauty = args.beauty
119 if charm and beauty:
120 logger.warn("charm and beauty decays are set! Beauty gets priority")
121 charm = False
122 charmInputFile = args.charmInputFile
123 nStart = int(args.nStart)
124 Debug = args.debug
125 if args.work_dir is None:
126 if charm: args.work_dir = get_work_dir(runnr,"charm")
127 if beauty: args.work_dir = get_work_dir(runnr,"beauty")
128 else: args.work_dir = get_work_dir(runnr)
129 work_dir = args.work_dir
130 logger.debug("work_dir: %s" % work_dir)
131 logger.debug("command line arguments: %s", args)
132 if os.path.exists(work_dir):
133 logger.warn("output directory '%s' already exists." % work_dir)
134 if args.force:
135 logger.warn("...cleaning")
136 for root, dirs, files in os.walk(work_dir):
137 for f in files:
138 os.unlink(os.path.join(root, f))
139 for d in dirs:
140 shutil.rmtree(os.path.join(root, d))
141 else:
142 logger.warn("...use '-f' option to overwrite it")
143 else:
144 os.makedirs(work_dir)
145 return args
146
147args = init()
148os.chdir(work_dir)
149# -------------------------------------------------------------------
150ROOT.gRandom.SetSeed(theSeed) # this should be propagated via ROOT to Pythia8 and Geant4VMC
151shipRoot_conf.configure() # load basic libraries, prepare atexit for python
152#this is for the muon flux geometry
153ship_geo = ConfigRegistry.loadpy("$FAIRSHIP/geometry/charm-geometry_config.py", Setup = args.CharmdetSetup, cTarget = args.CharmTarget)
154
155txt = 'pythia8_Geant4_'
156if withEvtGen: txt = 'pythia8_evtgen_Geant4_'
157outFile = outputDir+'/'+txt+str(runnr)+'_'+str(ecut)+'.root'
158parFile = outputDir+'/ship.params.'+txt+str(runnr)+'_'+str(ecut)+'.root'
159
160# -----Timer--------------------------------------------------------
161timer = ROOT.TStopwatch()
162timer.Start()
163
164# -----Create simulation run----------------------------------------
165run = ROOT.FairRunSim()
166run.SetName(mcEngine) # Transport engine
167run.SetOutputFile(outFile) # Output file
168run.SetUserConfig("g4Config.C") # user configuration file default g4Config.C
169rtdb = run.GetRuntimeDb()
170
171# -----Materials----------------------------------------------
172run.SetMaterials("media.geo")
173# -----Create geometry----------------------------------------------
174import charmDet_conf as shipDet_conf
175modules = shipDet_conf.configure(run,ship_geo)
176
177# -----Create PrimaryGenerator--------------------------------------
178primGen = ROOT.FairPrimaryGenerator()
179P8gen = ROOT.FixedTargetGenerator()
180if (ship_geo.MufluxSpectrometer.muflux==True):
181 P8gen.SetTarget("/TargetArea_1",0.,0.) # will distribute PV inside target, beam offset x=y=0.
182else:
183 P8gen.SetCharmTarget() #looks for charm target instead of SHiP standard target
184 P8gen.SetTarget("volTarget_1",0.,0.) # will distribute PV inside target, beam offset x=y=0.
185 if ship_geo.Box.gausbeam:
186 primGen.SetBeam(0.,0., 0.5, 0.5) #more central beam, for hits in downstream detectors
187 primGen.SmearGausVertexXY(True) #sigma = x
188 else:
189 primGen.SetBeam(0.,0., ship_geo.Box.TX-1., ship_geo.Box.TY-1.) #Uniform distribution in x/y on the target (0.5 cm of margin at both sides)
190 primGen.SmearVertexXY(True)
191P8gen.SetMom(400.*u.GeV)
192P8gen.SetEnergyCut(ecut*u.GeV)
193P8gen.SetDebug(Debug)
194if G4only: P8gen.SetG4only()
195if withEvtGen: P8gen.WithEvtGen()
196if boostDiMuon > 1:
197 P8gen.SetBoost(boostDiMuon) # will increase BR for rare eta,omega,rho ... mesons decaying to 2 muons in Pythia8
198 # and later copied to Geant4
199P8gen.SetSeed(theSeed)
200# for charm/beauty
201# print ' for experts: p pot= number of protons on target per spill to normalize on'
202# print ' : c chicc= ccbar over mbias cross section'
203if charm or beauty:
204 P8gen.InitForCharmOrBeauty("root://eoslhcb.cern.ch//eos/ship/data/Charm/Cascade-parp16-MSTP82-1-MSEL4-76Mpot_1.root",nev,npot,nStart)
205primGen.AddGenerator(P8gen)
206#
207run.SetGenerator(primGen)
208
209# -----Initialize simulation run------------------------------------
210run.Init()
211
212gMC = ROOT.TVirtualMC.GetMC()
213fStack = gMC.GetStack()
214fStack.SetMinPoints(1)
215fStack.SetEnergyCut(-1.)
216#
217import AddDiMuonDecayChannelsToG4
219
220# boost gamma2muon conversion
221if boostFactor > 1:
222 ROOT.gROOT.ProcessLine('#include "Geant4/G4ProcessTable.hh"')
223 ROOT.gROOT.ProcessLine('#include "Geant4/G4AnnihiToMuPair.hh"')
224 ROOT.gROOT.ProcessLine('#include "Geant4/G4GammaConversionToMuons.hh"')
225 gProcessTable = ROOT.G4ProcessTable.GetProcessTable()
226 procAnnihil = gProcessTable.FindProcess(ROOT.G4String('AnnihiToMuPair'),ROOT.G4String('e+'))
227 procGMuPair = gProcessTable.FindProcess(ROOT.G4String('GammaToMuPair'),ROOT.G4String('gamma'))
228 procGMuPair.SetCrossSecFactor(boostFactor)
229 procAnnihil.SetCrossSecFactor(boostFactor)
230
231
232# -----Start run----------------------------------------------------
233run.Run(nev)
234
235# -----Finish-------------------------------------------------------
236timer.Stop()
237rtime = timer.RealTime()
238ctime = timer.CpuTime()
239print(' ')
240print("Macro finished succesfully.")
241print("Output file is ", outFile)
242print("Real time ",rtime, " s, CPU time ",ctime,"s")
243
244if (ship_geo.MufluxSpectrometer.muflux==True):
245# ---post processing--- remove empty events --- save histograms
246 tmpFile = outFile+"tmp"
247 fin = ROOT.gROOT.GetListOfFiles()[0]
248
249 fHeader = fin.FileHeader
250 fHeader.SetRunId(runnr)
251 if charm or beauty:
252 # normalization for charm
253 poteq = P8gen.GetPotForCharm()
254 fHeader.SetTitle("POT equivalent = %7.3G"%(poteq))
255 else:
256 fHeader.SetTitle("POT = "+str(nev))
257 print("Data generated ", fHeader.GetTitle())
258 t = fin.cbmsim
259 fout = ROOT.TFile(tmpFile,'recreate' )
260 sTree = t.CloneTree(0)
261 nEvents = 0
262 for n in range(t.GetEntries()):
263 rc = t.GetEvent(n)
264 if (t.ScintillatorPoint.GetEntries()>0):
265 rc = sTree.Fill()
266 nEvents+=1
267 #t.Clear()
268 fout.cd()
269 for x in fin.GetList():
270 if not x.Class().GetName().find('TH')<0:
271 xcopy = x.Clone()
272 rc = xcopy.Write()
273 sTree.AutoSave()
274 ff = fin.FileHeader.Clone(fout.GetName())
275 fout.cd()
276 ff.Write("FileHeader", ROOT.TObject.kSingleKey)
277 sTree.Write()
278 fout.Close()
279 os.system("mv "+tmpFile+" "+outFile)
280
281 print("Number of events produced with activity after hadron absorber:",nEvents)
282
283else:
284 print("No post processing done")
285
286sGeo = ROOT.gGeoManager
287run.CreateGeometryFile("%s/geofile_full.root" % (outputDir))
288
289if checkOverlap:
290 sGeo = ROOT.gGeoManager
291 sGeo.CheckOverlaps()
292 sGeo.PrintOverlaps()
293 run.CreateGeometryFile("%s/geofile_full.root" % (outputDir))
294 import saveBasicParameters
295 saveBasicParameters.execute("%s/geofile_full.root" % (outputDir),ship_geo)
296
get_work_dir(run_number, tag=None)
execute(f, ox, name='ShipGeo')
configure(run, ship_geo)
configure(darkphoton=None)