2from __future__
import print_function
3import ROOT,os,sys,getopt,time,shipRoot_conf
5from ShipGeoConfig
import ConfigRegistry
25charmInputFile = ROOT.gSystem.Getenv(
"EOSSHIP")+
"/eos/experiment/ship/data/Charm/Cascade-parp16-MSTP82-1-MSEL4-76Mpot_1.root"
48logger = logging.getLogger(os.path.splitext(os.path.basename(os.sys.argv[0]))[0])
49logger.setLevel(logging.INFO)
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)
62 global runnr, nev, ecut, G4only, tauOnly,JpsiMainly, work_dir,Debug,withEvtGen,boostDiMuon,\
63 boostFactor,charm,beauty,charmInputFile,nStart,storeOnlyMuons,chicc,chibb,npot,nStart,skipNeutrinos,FourDP
64 logger.info(
"SHiP proton-on-taget simulator (C) Thomas Ruf, 2017")
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(
'-r',
'--run-number', type=int, dest=
'runnr', default=runnr)
71 ap.add_argument(
'-e',
'--ecut', type=float, help=
"energy cut", dest=
'ecut', default=ecut)
72 ap.add_argument(
'-n',
'--num-events', type=int, help=
"number of events to generate", dest=
'nev', default=nev)
73 ap.add_argument(
'-G',
'--G4only', action=
'store_true', dest=
'G4only', default=
False, help=
"use Geant4 directly, no Pythia8")
74 ap.add_argument(
'-P',
'--PythiaDecay', action=
'store_true', dest=
'pythiaDecay', default=
False, help=
"use Pythia8 for decays")
75 ap.add_argument(
'-V',
'--EvtGen', action=
'store_true', dest=
'withEvtGen', default=withEvtGen, help=
"use EvtGen for decays")
76 ap.add_argument(
'-t',
'--tau-only', action=
'store_true', dest=
'tauOnly', default=
False)
77 ap.add_argument(
'-J',
'--Jpsi-mainly', action=
'store_true', dest=
'JpsiMainly', default=
False)
78 ap.add_argument(
'-b',
'--boostDiMuon', type=float, dest=
'boostDiMuon', default=boostDiMuon, help=
"boost Di-muon branching ratios")
79 ap.add_argument(
'-X',
'--boostFactor', type=float, dest=
'boostFactor', default=boostFactor, help=
"boost Di-muon prod cross sections")
80 ap.add_argument(
'-C',
'--charm', action=
'store_true', dest=
'charm', default=charm, help=
"generate charm decays")
81 ap.add_argument(
'-B',
'--beauty', action=
'store_true', dest=
'beauty', default=beauty, help=
"generate beauty decays")
82 ap.add_argument(
'-M',
'--storeOnlyMuons', action=
'store_true', dest=
'storeOnlyMuons', default=storeOnlyMuons, help=
"store only muons, ignore neutrinos")
83 ap.add_argument(
'-N',
'--skipNeutrinos', action=
'store_true', dest=
'skipNeutrinos', default=
False, help=
"skip neutrinos")
84 ap.add_argument(
'-D',
'--4darkPhoton', action=
'store_true', dest=
'FourDP', default=
False, help=
"enable ntuple 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', type=int, help=
"first event of input file to start", dest=
'nStart', default=nStart)
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 ap.add_argument(
'-rs',
'--seed', type=int, help=
"random seed; default value is 0, see TRrandom::SetSeed documentation", dest=
'seed', default=0)
93 args = ap.parse_args()
95 logger.setLevel(logging.DEBUG)
99 tauOnly = args.tauOnly
100 JpsiMainly = args.JpsiMainly
102 boostFactor = args.boostFactor
103 boostDiMuon = args.boostDiMuon
104 storeOnlyMuons = args.storeOnlyMuons
105 skipNeutrinos = args.skipNeutrinos
110 args.withEvtGen =
False
111 args.pythiaDecay =
False
112 elif args.pythiaDecay:
114 args.withEvtGen =
False
115 logger.info(
"use Pythia8 as primary decayer")
118 logger.info(
"use EvtGen as primary decayer")
119 withEvtGen = args.withEvtGen
123 logger.warn(
"charm and beauty decays are set! Beauty gets priority")
125 charmInputFile = args.charmInputFile
126 nStart = int(args.nStart)
128 if args.work_dir
is None:
132 work_dir = args.work_dir
133 logger.debug(
"work_dir: %s" % work_dir)
134 logger.debug(
"command line arguments: %s", args)
135 if os.path.exists(work_dir):
136 logger.warn(
"output directory '%s' already exists." % work_dir)
138 logger.warn(
"...cleaning")
139 for root, dirs, files
in os.walk(work_dir):
141 os.unlink(os.path.join(root, f))
143 shutil.rmtree(os.path.join(root, d))
145 logger.warn(
"...use '-f' option to overwrite it")
147 os.makedirs(work_dir)
153ROOT.gRandom.SetSeed(args.seed)
155ship_geo = ConfigRegistry.loadpy(
"$FAIRSHIP/geometry/geometry_config.py", Yheight = dy, tankDesign = dv, muShieldDesign = ds, nuTauTargetDesign=nud)
157txt =
'pythia8_Geant4_'
158if withEvtGen: txt =
'pythia8_evtgen_Geant4_'
159outFile = outputDir+
'/'+txt+str(runnr)+
'_'+str(ecut)+
'.root'
160parFile = outputDir+
'/ship.params.'+txt+str(runnr)+
'_'+str(ecut)+
'.root'
163timer = ROOT.TStopwatch()
167run = ROOT.FairRunSim()
169run.SetOutputFile(outFile)
170run.SetUserConfig(
"g4Config.C")
171rtdb = run.GetRuntimeDb()
174run.SetMaterials(
"media.geo")
176cave= ROOT.ShipCave(
"CAVE")
177cave.SetGeometryFileName(
"caveWithAir.geo")
180TargetStation = ROOT.ShipTargetStation(
"TargetStation",ship_geo.target.length,ship_geo.hadronAbsorber.length,
181 ship_geo.target.z,ship_geo.hadronAbsorber.z,ship_geo.targetOpt,ship_geo.target.sl)
182slices_length = ROOT.std.vector(
'float')()
183slices_material = ROOT.std.vector(
'std::string')()
184for i
in range(1,ship_geo.targetOpt+1):
185 slices_length.push_back( eval(
"ship_geo.target.L"+str(i)))
186 slices_material.push_back(eval(
"ship_geo.target.M"+str(i)))
187TargetStation.SetLayerPosMat(ship_geo.target.xy,slices_length,slices_material)
189run.AddModule(TargetStation)
190MuonShield = ROOT.ShipMuonShield(
"MuonShield",ship_geo.muShieldDesign,
"ShipMuonShield",ship_geo.muShield.z,ship_geo.muShield.dZ0,ship_geo.muShield.dZ1,\
191 ship_geo.muShield.dZ2,ship_geo.muShield.dZ3,ship_geo.muShield.dZ4,ship_geo.muShield.dZ5,ship_geo.muShield.dZ6,\
192 ship_geo.muShield.dZ7,ship_geo.muShield.dZ8,ship_geo.muShield.dXgap,ship_geo.muShield.LE,ship_geo.Yheight*4./10.,0.)
193MuonShield.SetSupports(
False)
194run.AddModule(MuonShield)
195sensPlane = ROOT.exitHadronAbsorber()
196sensPlane.SetEnergyCut(ecut*u.GeV)
197if storeOnlyMuons: sensPlane.SetOnlyMuons()
198if skipNeutrinos: sensPlane.SkipNeutrinos()
199if FourDP: sensPlane.SetOpt4DP()
201run.AddModule(sensPlane)
204primGen = ROOT.FairPrimaryGenerator()
205P8gen = ROOT.FixedTargetGenerator()
206P8gen.SetTarget(
"/TargetArea_1",0.,0.)
207P8gen.SetMom(400.*u.GeV)
208P8gen.SetEnergyCut(ecut*u.GeV)
210P8gen.SetHeartBeat(100000)
211if G4only: P8gen.SetG4only()
212if JpsiMainly: P8gen.SetJpsiMainly()
213if tauOnly: P8gen.SetTauOnly()
214if withEvtGen: P8gen.WithEvtGen()
216 P8gen.SetBoost(boostDiMuon)
218P8gen.SetSeed(args.seed)
223 print(
"--- process heavy flavours ---")
224 P8gen.InitForCharmOrBeauty(charmInputFile,nev,npot,nStart)
225primGen.AddGenerator(P8gen)
227run.SetGenerator(primGen)
231gMC = ROOT.TVirtualMC.GetMC()
232fStack = gMC.GetStack()
233fStack.SetMinPoints(1)
234fStack.SetEnergyCut(-1.)
236import AddDiMuonDecayChannelsToG4
241 ROOT.gROOT.ProcessLine(
'#include "Geant4/G4ProcessTable.hh"')
242 ROOT.gROOT.ProcessLine(
'#include "Geant4/G4AnnihiToMuPair.hh"')
243 ROOT.gROOT.ProcessLine(
'#include "Geant4/G4GammaConversionToMuons.hh"')
244 gProcessTable = ROOT.G4ProcessTable.GetProcessTable()
245 procAnnihil = gProcessTable.FindProcess(ROOT.G4String(
'AnnihiToMuPair'),ROOT.G4String(
'e+'))
246 procGMuPair = gProcessTable.FindProcess(ROOT.G4String(
'GammaToMuPair'),ROOT.G4String(
'gamma'))
247 procGMuPair.SetCrossSecFactor(boostFactor)
248 procAnnihil.SetCrossSecFactor(boostFactor)
255rtime = timer.RealTime()
256ctime = timer.CpuTime()
258print(
"Macro finished succesfully.")
259print(
"Output file is ", outFile)
260print(
"Real time ",rtime,
" s, CPU time ",ctime,
"s")
262tmpFile = outFile+
"tmp"
263if ROOT.gROOT.GetListOfFiles().GetEntries()>0:
264 fin = ROOT.gROOT.GetListOfFiles()[0]
266 fin = ROOT.TFile.Open(outFile)
267fHeader = fin.FileHeader
268fHeader.SetRunId(runnr)
271 poteq = P8gen.GetPotForCharm()
272 info =
"POT equivalent = %7.3G"%(poteq)
274 info =
"POT = "+str(nev)
276conditions =
" with ecut="+str(ecut)
277if JpsiMainly: conditions+=
" J"
278if tauOnly: conditions+=
" T"
279if withEvtGen: conditions+=
" V"
280if boostDiMuon > 1: conditions+=
" diMu"+str(boostDiMuon)
281if boostFactor > 1: conditions+=
" X"+str(boostFactor)
284fHeader.SetTitle(info)
285print(
"Data generated ", fHeader.GetTitle())
289 tf = ROOT.TFile(
'FourDP.root',
'recreate')
290 tnt = nt.CloneTree(0)
291 for i
in range(nt.GetEntries()):
293 rc = tnt.Fill(nt.id,nt.px,nt.py,nt.pz,nt.x,nt.y,nt.z)
298fout = ROOT.TFile(tmpFile,
'recreate' )
299sTree = t.CloneTree(0)
301for n
in range(t.GetEntries()):
303 if t.vetoPoint.GetEntries()>0:
308for k
in fin.GetListOfKeys():
309 x = fin.Get(k.GetName())
310 className = x.Class().GetName()
311 if className.find(
'TTree')<0
and className.find(
'TNtuple')<0:
315ff = fin.FileHeader.Clone(fout.GetName())
317ff.Write(
"FileHeader", ROOT.TObject.kSingleKey)
321rc1 = os.system(
"rm "+outFile)
322rc2 = os.system(
"mv "+tmpFile+
" "+outFile)
323print(
"removed out file, moved tmpFile to out file",rc1,rc2)
324fin.SetWritable(
False)
326print(
"Number of events produced with activity after hadron absorber:",nEvents)
329 sGeo = ROOT.gGeoManager
332 run.CreateGeometryFile(
"%s/geofile_full.root" % (outputDir))
333 import saveBasicParameters
get_work_dir(run_number, tag=None)
execute(f, ox, name='ShipGeo')
configure(darkphoton=None)