9from argparse
import ArgumentParser
10from array
import array
18DownScaleDiMuon =
False
21theHNLMass = 1.0 * u.GeV
22theProductionCouplings = theDecayCouplings =
None
25theDPmass = 0.2 * u.GeV
34MCTracksWithHitsOnly =
False
35MCTracksWithEnergyCutOnly =
True
36MCTracksWithHitsOrEnergyCut =
False
41inputFile =
"$EOSSHIP/eos/experiment/ship/data/Charm/Cascade-parp16-MSTP82-1-MSEL4-978Bpot.root"
42defaultInputFile =
True
44parser = ArgumentParser()
46parser.add_argument(
"--evtcalc", help=
"Use EventCalc", action=
"store_true")
47parser.add_argument(
"--Pythia6", dest=
"pythia6", help=
"Use Pythia6", action=
"store_true")
48parser.add_argument(
"--Pythia8", dest=
"pythia8", help=
"Use Pythia8", action=
"store_true")
51 dest=
"evtgen_decayer",
52 help=
"Use TEvtGenDecayer for J/psi and other quarkonium decays",
55subparsers = parser.add_subparsers(dest=
"command", help=
"Which mode to run")
57pg_parser = subparsers.add_parser(
"PG", help=
"Use Particle Gun")
59pg_parser.add_argument(
60 "--multiplePG", help=
"Multiple particle guns in a x-y plane at a fixed z or in a 3D volume", action=
"store_true"
62pg_parser.add_argument(
"--pID", dest=
"pID", default=22, type=int, help=
"id of particle used by the gun (default=22)")
63pg_parser.add_argument(
64 "--Estart", default=10, type=float, help=
"start of energy range of particle gun (default=10 GeV)"
66pg_parser.add_argument(
"--Eend", default=10, type=float, help=
"end of energy range of particle gun (default=10 GeV)")
67pg_parser.add_argument(
"--Vx", dest=
"Vx", default=0, type=float, help=
"x position of particle gun (default=0 cm)")
68pg_parser.add_argument(
"--Vy", dest=
"Vy", default=0, type=float, help=
"y position of particle gun (default=0 cm)")
69pg_parser.add_argument(
"--Vz", dest=
"Vz", default=0, type=float, help=
"z position of particle gun (default=0 cm)")
70pg_parser.add_argument(
71 "--Dx", dest=
"Dx", type=float, help=
"size of the full uniform spread of PG xpos: (Vx - Dx/2, Vx + Dx/2)"
73pg_parser.add_argument(
74 "--Dy", dest=
"Dy", type=float, help=
"size of the full uniform spread of PG ypos: (Vy - Dy/2, Vy + Dy/2)"
78genie_parser = subparsers.add_parser(
"Genie", help=
"Genie for reading and processing neutrino interactions")
79genie_parser.add_argument(
84 help=
"Genie neutrino start z start position (default=2844.2850 cm)",
86genie_parser.add_argument(
91 help=
"Genie neutrino end z position (default=3180.4350 cm)",
94parser.add_argument(
"-A", help=
"b: signal from b, c: from c (default), bc: from Bc, or inclusive", default=
"c")
98 help=
"misuse GenieGenerator for neutrino radiography and geometry timing test",
101parser.add_argument(
"--Ntuple", dest=
"ntuple", help=
"Use ntuple as input", action=
"store_true")
105 help=
"Generate events from muon background file, --Cosmics=0 for cosmic generator data",
109 "--FollowMuon", dest=
"followMuon", help=
"Make muonshield active to follow muons", action=
"store_true"
114 help=
"Only transport muons for a fast muon only background estimate",
117parser.add_argument(
"--phiRandom", help=
"only relevant for muon background generator, random phi", action=
"store_true")
119 "--SmearBeam", dest=
"SmearBeam", help=
"Standard deviation of beam smearing [cm]", default=0.8, type=float
121parser.add_argument(
"--PaintBeam", dest=
"PaintBeam", help=
"Radius of beam painting [cm]", default=5, type=float)
123 "--Cosmics", dest=
"cosmics", help=
"Use cosmic generator, argument switch for cosmic generator 0 or 1", default=
None
125parser.add_argument(
"--MuDIS", dest=
"mudis", help=
"Use muon deep inelastic scattering generator", action=
"store_true")
126parser.add_argument(
"--RpvSusy", dest=
"RPVSUSY", help=
"Generate events based on RPV neutralino", action=
"store_true")
127parser.add_argument(
"--FixedTarget", dest=
"fixedTarget", help=
"Enable fixed target simulation", action=
"store_true")
128parser.add_argument(
"--DarkPhoton", help=
"Generate dark photons", action=
"store_true")
129parser.add_argument(
"--SusyBench", dest=
"RPVSUSYbench", help=
"Generate HP Susy", default=2)
134 help=f
"Mass of hidden particle, default {theHNLMass} GeV for HNL, {theDPmass} GeV for DP",
143 help=
"couplings 'U2e,U2mu,U2tau' or -c 'U2e,U2mu,U2tau' to set list of HNL couplings.\
144 TP default for HNL, ctau=53.3km",
145 default=
"0.447e-9,7.15e-9,1.88e-9",
149 "--production-couplings",
150 dest=
"theprodcouplings",
151 help=
"production couplings 'U2e,U2mu,U2tau' to set the couplings for HNL production only",
157 dest=
"thedeccouplings",
158 help=
"decay couplings 'U2e,U2mu,U2tau' to set the couplings for HNL decay only",
162 "-e",
"--epsilon", dest=
"theDPepsilon", help=
"to set mixing parameter epsilon", default=0.00000008, type=float
164parser.add_argument(
"-n",
"--nEvents", dest=
"nEvents", help=
"Number of events to generate", default=100, type=int)
165parser.add_argument(
"-i",
"--firstEvent", help=
"First event of input file to use", default=0, type=int)
170 help=
"Seed for random number. Only for experts, see TRrandom::SetSeed documentation",
178 help=
"can be set to an integer for the muonBackground simulation with specific seed for each muon, only for experts!",
186 help=
"Input file (repeat -f for multiple files)",
189parser.add_argument(
"--nFiles", dest=
"nFiles", help=
"Number of input files to process", default=-1, type=int)
190parser.add_argument(
"-g", dest=
"geofile", help=
"geofile for muon shield geometry, for experts only", default=
None)
191parser.add_argument(
"-o",
"--output", dest=
"outputDir", help=
"Output directory", default=
".")
192parser.add_argument(
"-Y", dest=
"dy", help=
"max height of vacuum tank", default=6.0, type=float)
195 help=
"Tracker station frame material: 4=aluminium; 10=steel (default)",
203 help=
"default = False: copy only stable particles to stack, except for HNL events",
206parser.add_argument(
"-t",
"--test", dest=
"testFlag", help=
"quick test", action=
"store_true")
207parser.add_argument(
"--dry-run", dest=
"dryrun", help=
"stop after initialize", action=
"store_true")
208parser.add_argument(
"-D",
"--display", dest=
"eventDisplay", help=
"store trajectories", action=
"store_true")
211 help=
"The name of the muon shield in the database to use.",
213 choices=[
"TRY_2025"],
216 "--MesonMother", dest=
"MM", help=
"Choose DP production meson source: pi0, eta, omega, eta1, eta11", default=
"pi0"
220 help=
"Control FairLogger verbosity: 0=info (default), 1=+debug, 2=+debug1, 3=+debug2",
225parser.add_argument(
"--print-fields", help=
"Print VMC fields and weights information", action=
"store_true")
226parser.add_argument(
"--check-overlaps", help=
"Perform geometry overlap checking", action=
"store_true")
227parser.add_argument(
"--field_map", default=
None, help=
"Specify spectrometer field map.")
229 "--z-offset", dest=
"z_offset", help=
"z-offset for the FixedTargetGenerator [mm]", default=-84.0, type=float
234 help=
"Set Decay Volume medium to helium. NOOP, as default is helium",
235 action=
"store_const",
242 help=
"Set Decay Volume medium to vacuum(vessel structure changes)",
243 action=
"store_const",
248parser.add_argument(
"--SND", dest=
"SND", help=
"Activate SND.", action=
"store_true")
251 help=
"Choose SND design(s) among [1,2,...] or 'all' to enable all. 1: EmulsionTarget, 2: MTC + SiliconTarget",
256 "--noSND", dest=
"SND", help=
"Deactivate SND. NOOP, as it currently defaults to off.", action=
"store_false"
260 help=
"Path to the yaml target config file",
261 default=os.path.expandvars(
"$FAIRSHIP/geometry/target_config.yaml"),
264 "--tag", dest=
"output_tag", help=
"Custom tag for output files instead of auto-generated UUID", default=
None
268options = parser.parse_args()
270available_snd_designs = [1, 2]
271if any(str(x).lower() ==
"all" for x
in options.SND_design):
272 options.SND_design = available_snd_designs
275 options.SND_design = [
int(x)
for x
in options.SND_design]
277 print(
"Invalid value for --SND_design. Use integers or 'all'.")
281 inclusive = options.A
283 inputFile =
"$EOSSHIP/eos/experiment/ship/data/Beauty/Cascade-run0-19-parp16-MSTP82-1-MSEL5-5338Bpot.root"
284 if options.A.lower() ==
"charmonly":
287 if options.A
not in [
"b",
"c",
"bc",
"meson",
"pbrem",
"qcd"]:
290 motherMode = options.MM
292 Opt_high =
int(options.cosmics)
294 if options.inputFile == [
"none"]:
295 options.inputFile =
None
297 for _f
in options.inputFile:
298 inputFile.extend(glob.glob(_f))
299 inputFile = list(set(inputFile))
300 if options.nFiles > 0:
301 inputFile = inputFile[: options.nFiles]
302 defaultInputFile =
False
305if options.DarkPhoton:
307if not options.theMass:
308 if options.DarkPhoton:
309 options.theMass = theDPmass
311 options.theMass = theHNLMass
312if options.thecouplings:
313 theCouplings = [
float(c)
for c
in options.thecouplings.split(
",")]
314if options.theprodcouplings:
315 theProductionCouplings = [
float(c)
for c
in options.theprodcouplings.split(
",")]
316if options.thedeccouplings:
317 theDecayCouplings = [
float(c)
for c
in options.thedeccouplings.split(
",")]
319 inputFile =
"$FAIRSHIP/files/Cascade-parp16-MSTP82-1-MSEL4-76Mpot_1_5000.root"
323if (HNL
and options.RPVSUSY)
or (HNL
and options.DarkPhoton)
or (options.DarkPhoton
and options.RPVSUSY):
324 print(
"cannot have HNL and SUSY or DP at the same time, abort")
327if (options.command ==
"Genie" or options.nuradio)
and defaultInputFile:
328 inputFile =
"$EOSSHIP/eos/experiment/ship/data/GenieEvents/genie-nu_mu.root"
329if options.mudis
and defaultInputFile:
330 print(
"input file required if simEngine = muonDIS")
331 print(
" for example -f $EOSSHIP/eos/experiment/ship/data/muonDIS/muonDis_1.root")
334if (options.ntuple
or options.muonback)
and defaultInputFile:
335 print(
"input file required if simEngine = Ntuple or MuonBack")
336 print(
" for example -f $EOSSHIP/eos/experiment/ship/data/Mbias/pythia8_Geant4-withCharm_onlyMuons_4magTarget.root")
340seed = options.theSeed
342 ROOT.gRandom.SetSeed(0)
343 seed = ROOT.gRandom.GetSeed()
346 seed = seed % 900000000
347ROOT.gRandom.SetSeed(seed)
351ROOT.gInterpreter.ProcessLine(
'#include "FairLogger.h"')
352if options.debug == 0:
353 ROOT.gInterpreter.ProcessLine(
'fair::Logger::SetConsoleSeverity("info");')
354elif options.debug == 1:
355 ROOT.gInterpreter.ProcessLine(
'fair::Logger::SetConsoleSeverity("debug");')
356elif options.debug == 2:
357 ROOT.gInterpreter.ProcessLine(
'fair::Logger::SetConsoleSeverity("debug1");')
358elif options.debug == 3:
359 ROOT.gInterpreter.ProcessLine(
'fair::Logger::SetConsoleSeverity("debug2");')
362 strawDesign=options.strawDesign,
363 muShieldGeo=options.geofile,
364 shieldName=options.shieldName,
365 DecayVolumeMedium=options.decayVolMed,
367 SND_design=options.SND_design,
368 TARGET_YAML=options.target_yaml,
371if not options.command:
372 for g
in [
"pythia8",
"evtcalc",
"pythia6",
"nuradio",
"ntuple",
"muonback",
"mudis",
"fixedTarget",
"cosmics"]:
373 if getattr(options, g):
376 options.pythia8 =
True
380run_identifier = options.output_tag
if options.output_tag
else str(uuid.uuid4())
381if not os.path.exists(options.outputDir):
382 os.makedirs(options.outputDir)
383outFile = f
"{options.outputDir}/sim_{run_identifier}.root"
386parFile = f
"{options.outputDir}/params_{run_identifier}.root"
392timer = ROOT.TStopwatch()
396run = ROOT.FairRunSim()
398run.SetSink(ROOT.FairRootFileSink(outFile))
399run.SetUserConfig(
"g4Config.C")
400rtdb = run.GetRuntimeDb()
408primGen = ROOT.FairPrimaryGenerator()
410 primGen.SetTarget(ship_geo.target.z0, 0.0)
412 if HNL
or options.RPVSUSY:
413 P8gen = ROOT.HNLPythia8Generator()
417 print(
"Generating HNL events of mass %.3f GeV" % options.theMass)
418 if theProductionCouplings
is None and theDecayCouplings
is None:
419 print(
"and with couplings=", theCouplings)
420 theProductionCouplings = theDecayCouplings = theCouplings
421 elif theProductionCouplings
is not None and theDecayCouplings
is not None:
422 print(
"and with couplings", theProductionCouplings,
"at production")
423 print(
"and", theDecayCouplings,
"at decay")
425 raise ValueError(
"Either both production and decay couplings must be specified, or neither.")
427 P8gen, options.theMass, theProductionCouplings, theDecayCouplings, inclusive, options.deepCopy
430 print(
"Generating RPVSUSY events of mass %.3f GeV" % theHNLMass)
431 print(f
"and with couplings=[{theCouplings[0]:.3f},{theCouplings[1]:.3f}]")
432 print(
"and with stop mass=%.3f GeV\n" % theCouplings[2])
436 [theCouplings[0], theCouplings[1]],
438 options.RPVSUSYbench,
442 P8gen.SetParameters(
"ProcessLevel:all = off")
444 ut.checkFileExists(inputFile)
446 P8gen.UseExternalFile(inputFile, options.firstEvent)
447 if options.DarkPhoton:
448 P8gen = ROOT.DPPythia8Generator()
449 if inclusive ==
"qcd":
450 P8gen.SetDPId(4900023)
452 P8gen.SetDPId(9900015)
453 import pythia8darkphoton_conf
456 P8gen, options.theMass, options.theDPepsilon, inclusive, motherMode, options.deepCopy
460 if HNL
or options.RPVSUSY
or options.DarkPhoton:
461 P8gen.SetSmearBeam(options.SmearBeam * u.cm)
462 P8gen.SetPaintRadius(options.PaintBeam * u.cm)
463 P8gen.SetLmin((ship_geo.Chamber1.z - ship_geo.chambers.Tub1length) - ship_geo.target.z0)
464 P8gen.SetLmax(ship_geo.TrackStation1.z - ship_geo.target.z0)
466 primGen.SetTarget(0.0, 0.0)
467 ut.checkFileExists(inputFile)
468 if ship_geo.Box.gausbeam:
469 primGen.SetBeam(0.0, 0.0, 0.5, 0.5)
470 primGen.SmearGausVertexXY(
True)
473 0.0, 0.0, ship_geo.Box.TX - 1.0, ship_geo.Box.TY - 1.0
475 primGen.SmearVertexXY(
True)
476 P8gen = ROOT.Pythia8Generator()
477 P8gen.UseExternalFile(inputFile, options.firstEvent)
479 P8gen.SetTargetCoordinates(ship_geo.target.z0, ship_geo.target.z0 + ship_geo.target.length)
483 primGen.AddGenerator(P8gen)
484if options.fixedTarget:
486 P8gen = ROOT.FixedTargetGenerator()
487 P8gen.SetZoffset(options.z_offset * u.mm)
489 P8gen.SetTargetCoordinates(ship_geo.target.z0, ship_geo.target.z0 + ship_geo.target.length)
490 P8gen.SetMom(400.0 * u.GeV)
491 P8gen.SetSmearBeam(options.SmearBeam * u.cm)
492 P8gen.SetPaintRadius(options.PaintBeam * u.cm)
493 P8gen.SetEnergyCut(0.0)
494 P8gen.SetHeartBeat(100000)
496 primGen.AddGenerator(P8gen)
499 primGen.SetTarget(ship_geo.target.z0 + ship_geo.muShield.length, 0.0)
501 test = ROOT.TPythia6()
502 P6gen = ROOT.tPythia6Generator()
503 P6gen.SetMom(50.0 * u.GeV)
504 P6gen.SetTarget(
"gamma/mu+",
"n0")
505 primGen.AddGenerator(P6gen)
509 primGen.SetTarget(0.0, 0.0)
510 print(f
"Opening input file for EvtCalc generator: {inputFile}")
511 ut.checkFileExists(inputFile)
512 EvtCalcGen = ROOT.EvtCalcGenerator()
513 EvtCalcGen.Init(inputFile, options.firstEvent)
514 EvtCalcGen.SetPositions(zTa=ship_geo.target.z, zDV=ship_geo.decayVolume.z)
515 primGen.AddGenerator(EvtCalcGen)
517 EvtCalcGen.GetNevents()
if options.nEvents == -1
else min(options.nEvents, EvtCalcGen.GetNevents())
519 print(f
"Generate {options.nEvents} with EvtCalc input. First event: {options.firstEvent}")
522if options.command ==
"PG":
523 myPgun = ROOT.FairBoxGenerator(options.pID, 1)
524 myPgun.SetPRange(options.Estart, options.Eend)
525 myPgun.SetPhiRange(0, 360)
526 myPgun.SetThetaRange(0, 0)
527 if options.multiplePG:
530 (options.Vx - options.Dx / 2) * u.cm,
531 (options.Vy - options.Dy / 2) * u.cm,
532 (options.Vx + options.Dx / 2) * u.cm,
533 (options.Vy + options.Dy / 2) * u.cm,
538 myPgun.SetXYZ(options.Vx * u.cm, options.Vy * u.cm, options.Vz * u.cm)
539 primGen.AddGenerator(myPgun)
542 ut.checkFileExists(inputFile)
543 primGen.SetTarget(0.0, 0.0)
544 DISgen = ROOT.MuDISGenerator()
549 mu_start, mu_end = ship_geo.Chamber1.z - ship_geo.chambers.Tub1length - 10.0 * u.cm, ship_geo.TrackStation1.z
550 print(
"MuDIS position info input=", mu_start, mu_end)
551 DISgen.SetPositions(mu_start, mu_end)
552 DISgen.Init(inputFile, options.firstEvent)
553 primGen.AddGenerator(DISgen)
554 options.nEvents = DISgen.GetNevents()
if options.nEvents == -1
else min(options.nEvents, DISgen.GetNevents())
555 print(
"Generate ", options.nEvents,
" with DIS input",
" first event", options.firstEvent)
557if options.command ==
"Genie":
559 ut.checkFileExists(inputFile)
560 primGen.SetTarget(0.0, 0.0)
561 Geniegen = ROOT.GenieGenerator()
562 Geniegen.Init(inputFile, options.firstEvent)
563 Geniegen.SetPositions(ship_geo.target.z0, options.z_start_nu, options.z_end_nu)
564 primGen.AddGenerator(Geniegen)
565 options.nEvents = Geniegen.GetNevents()
if options.nEvents == -1
else min(options.nEvents, Geniegen.GetNevents())
566 run.SetPythiaDecayer(
"DecayConfigNuAge.C")
567 print(
"Generate ", options.nEvents,
" with Genie input",
" first event", options.firstEvent)
569 ut.checkFileExists(inputFile)
570 primGen.SetTarget(0.0, 0.0)
571 Geniegen = ROOT.GenieGenerator()
572 Geniegen.Init(inputFile, options.firstEvent)
574 Geniegen.SetPositions(ship_geo.target.z0, ship_geo.tauMudet.zMudetC, ship_geo.MuonStation3.z)
576 primGen.AddGenerator(Geniegen)
577 print(
"Generate ", options.nEvents,
" for nuRadiography",
" first event", options.firstEvent)
579 pdg = ROOT.TDatabasePDG.Instance()
580 pdg.AddParticle(
"W",
"Ion", 1.71350e02,
True, 0.0, 74,
"XXX", 1000741840)
582 run.SetPythiaDecayer(
"DecayConfigPy8.C")
588 ut.checkFileExists(inputFile)
589 primGen.SetTarget(ship_geo.target.z0 + 50 * u.m, 0.0)
590 Ntuplegen = ROOT.NtupleGenerator()
591 Ntuplegen.Init(inputFile, options.firstEvent)
592 primGen.AddGenerator(Ntuplegen)
593 options.nEvents = Ntuplegen.GetNevents()
if options.nEvents == -1
else min(options.nEvents, Ntuplegen.GetNevents())
594 print(
"Process ", options.nEvents,
" from input file")
598 fileType = ut.checkFileExists(inputFile)
599 if fileType ==
"tree":
601 primGen.SetTarget(ship_geo.target.z0 + 70.845 * u.m, 0.0)
603 primGen.SetTarget(ship_geo.target.z0 + 50 * u.m, 0.0)
605 MuonBackgen = ROOT.MuonBackGenerator()
607 MuonBackgen.Init(inputFile, options.firstEvent)
608 MuonBackgen.SetPaintRadius(options.PaintBeam * u.cm)
609 MuonBackgen.SetSmearBeam(options.SmearBeam * u.cm)
610 MuonBackgen.SetPhiRandomize(options.phiRandom)
612 testf = ROOT.TFile.Open(inputFile[0])
613 if not testf.FileHeader.GetTitle().find(
"diMu100.0") < 0:
614 MuonBackgen.SetDownScaleDiMuon()
615 print(
"MuonBackgenerator: set downscale for dimuon on")
618 MuonBackgen.SetSameSeed(options.sameSeed)
619 primGen.AddGenerator(MuonBackgen)
621 MuonBackgen.GetNevents()
if options.nEvents == -1
else min(options.nEvents, MuonBackgen.GetNevents())
623 MCTracksWithHitsOnly =
True
627 " from input file, with 𝜎 = ",
629 ", with smear radius r = ",
630 options.SmearBeam * u.cm,
631 "with MCTracksWithHitsOnly",
632 MCTracksWithHitsOnly,
634 if options.followMuon:
635 options.fastMuon =
True
636 modules[
"Veto"].SetFollowMuon()
638 modules[
"Veto"].SetFastMuon()
644 primGen.SetTarget(0.0, 0.0)
645 Cosmicsgen = ROOT.CosmicsGenerator()
649 if not Cosmicsgen.Init(Opt_high):
650 print(
"initialization of cosmic background generator failed ", Opt_high)
652 Cosmicsgen.n_EVENTS = options.nEvents
653 primGen.AddGenerator(Cosmicsgen)
654 print(
"Process ", options.nEvents,
" Cosmic events with option ", Opt_high)
657run.SetGenerator(primGen)
662if options.eventDisplay:
663 run.SetStoreTraj(ROOT.kTRUE)
665 run.SetStoreTraj(ROOT.kFALSE)
669if options.evtgen_decayer:
670 run.SetPythiaDecayer(
"DecayConfigTEvtGen.C")
671 print(
"Using TEvtGenDecayer for J/psi and quarkonium decays with EvtGen")
677gMC = ROOT.TVirtualMC.GetMC()
678fStack = gMC.GetStack()
682EnergyCut = 10.0 * u.MeV
if options.mudis
else 100.0 * u.MeV
684if MCTracksWithHitsOnly:
685 fStack.SetMinPoints(1)
686 fStack.SetEnergyCut(-100.0 * u.MeV)
687elif MCTracksWithEnergyCutOnly:
688 fStack.SetMinPoints(-1)
689 fStack.SetEnergyCut(EnergyCut)
690elif MCTracksWithHitsOrEnergyCut:
691 fStack.SetMinPoints(1)
692 fStack.SetEnergyCut(EnergyCut)
693elif options.deepCopy:
694 fStack.SetMinPoints(0)
695 fStack.SetEnergyCut(0.0 * u.MeV)
697if options.eventDisplay:
699 trajFilter = ROOT.FairTrajFilter.Instance()
700 trajFilter.SetStepSizeCut(1 * u.mm)
701 trajFilter.SetVertexCut(-20 * u.m, -20 * u.m, ship_geo.target.z0 - 1 * u.m, 20 * u.m, 20 * u.m, 200.0 * u.m)
702 trajFilter.SetMomentumCutP(0.1 * u.GeV)
703 trajFilter.SetEnergyCut(0.0, 400.0 * u.GeV)
704 trajFilter.SetStorePrimaries(ROOT.kTRUE)
705 trajFilter.SetStoreSecondaries(ROOT.kTRUE)
715if hasattr(ship_geo.Bfield,
"fieldMap"):
716 if options.field_map:
717 ship_geo.Bfield.fieldMap = options.field_map
721if options.print_fields:
724 onlyWithField=
True, exclude=[
"DecayVolume",
"Tr1",
"Tr2",
"Tr3",
"Tr4",
"Veto",
"MuonDetector",
"SplitCal"]
731run.Run(options.nEvents)
733kParameterMerged = ROOT.kTRUE
734parOut = ROOT.FairParRootFileIo(kParameterMerged)
736rtdb.setOutput(parOut)
738rtdb.printParamContexts()
741geofile_name = f
"{options.outputDir}/geo_{run_identifier}.root"
742run.CreateGeometryFile(geofile_name)
744import saveBasicParameters
749if options.check_overlaps:
750 ROOT.gROOT.SetWebDisplay(
"off")
751 fGeo = ROOT.gGeoManager
752 fGeo.SetNmeshPoints(10000)
753 fGeo.CheckOverlaps(0.1)
756 for x
in fGeo.GetTopNode().GetNodes():
757 x.CheckOverlaps(0.0001)
761rtime = timer.RealTime()
762ctime = timer.CpuTime()
764print(
"Macro finished successfully.")
765if "P8gen" in globals():
767 print(
"number of retries, events without HNL ", P8gen.nrOfRetries())
768 elif options.DarkPhoton:
769 print(
"number of retries, events without Dark Photons ", P8gen.nrOfRetries())
770 print(
"total number of dark photons (including multiple meson decays per single collision) ", P8gen.nrOfDP())
772print(
"Output file is ", outFile)
773print(
"Parameter file is ", parFile)
774print(
"Geometry file is ", geofile_name)
775print(
"Real time ", rtime,
" s, CPU time ", ctime,
"s")
779 tmpFile = outFile +
"tmp"
780 xxx = outFile.split(
"/")
781 check = xxx[len(xxx) - 1]
783 for ff
in ROOT.gROOT.GetListOfFiles():
784 nm = ff.GetName().split(
"/")
785 if nm[len(nm) - 1] == check:
788 fin = ROOT.TFile.Open(outFile)
790 fout = ROOT.TFile(tmpFile,
"recreate")
791 fSink = ROOT.FairRootFileSink(fout)
793 sTree = t.CloneTree(0)
797 for branch
in sTree.GetListOfBranches():
798 name = branch.GetName()
800 pointContainers.append(name)
805 for containerName
in pointContainers:
806 container = getattr(sTree, containerName)
807 if container.size() > 0:
815 branches = ROOT.TList()
816 branches.SetName(
"BranchList")
817 branches.Add(ROOT.TObjString(
"MCTrack"))
818 branches.Add(ROOT.TObjString(
"vetoPoint"))
819 branches.Add(ROOT.TObjString(
"ShipRpcPoint"))
820 branches.Add(ROOT.TObjString(
"TargetPoint"))
821 branches.Add(ROOT.TObjString(
"TTPoint"))
822 branches.Add(ROOT.TObjString(
"ScoringPoint"))
823 branches.Add(ROOT.TObjString(
"strawtubesPoint"))
824 branches.Add(ROOT.TObjString(
"TimeDetPoint"))
825 branches.Add(ROOT.TObjString(
"MCEventHeader"))
826 branches.Add(ROOT.TObjString(
"UpstreamTaggerPoint"))
827 branches.Add(ROOT.TObjString(
"MTCdetPoint"))
828 branches.Add(ROOT.TObjString(
"SiliconTargetPoint"))
829 branches.Add(ROOT.TObjString(
"sGeoTracks"))
832 fSink.WriteObject(branches,
"BranchList", ROOT.TObject.kSingleKey)
833 fSink.SetOutTree(sTree)
836 print(
"removed empty events, left with:", nEvents)
837 rc1 = os.system(
"rm " + outFile)
838 rc2 = os.system(
"mv " + tmpFile +
" " + outFile)
839 fin.SetWritable(
False)
842 temp_filename = outFile.replace(
".root",
"_tmp.root")
845 ROOT.TFile.Open(outFile,
"read")
as f_outputfile,
846 ROOT.TFile.Open(temp_filename,
"recreate")
as f_temp,
848 output_tree = f_outputfile[
"cbmsim"]
849 muondis_tree = ROOT.TChain(
"DIS")
853 new_tree = output_tree.CloneTree(0)
855 cross_section = array(
"f", [0.0])
856 cross_section_leaf = new_tree.Branch(
"CrossSection", cross_section,
"CrossSection/F")
858 for output_event, muondis_event
in zip(output_tree, muondis_tree):
859 mu = muondis_event.InMuon[0]
860 cross_section[0] = mu[10]
863 new_tree.Write(
"", ROOT.TObject.kOverwrite)
865 os.replace(temp_filename, outFile)
866 print(
"Successfully added DISCrossSection to the output file:", outFile)
868if options.command ==
"Genie":
871 f_input = ROOT.TFile.Open(inputFile[0],
"READ")
875 selection_string =
"(Entry$ >= " + str(options.firstEvent) +
")"
876 if (options.firstEvent + options.nEvents) < gst.GetEntries():
877 selection_string +=
"&&(Entry$ < " + str(options.firstEvent + options.nEvents) +
")"
880 f_output = ROOT.TFile.Open(outFile,
"UPDATE")
883 gst_copy = gst.CopyTree(selection_string)
899 mygMC = ROOT.TGeant4.GetMC()
900 mygMC.ProcessGeantCommand(
"/geometry/test/recursion_start 0")
901 mygMC.ProcessGeantCommand(
"/geometry/test/recursion_depth 2")
902 mygMC.ProcessGeantCommand(
"/geometry/test/run")
def configure(CMBG, ship_geo)
None printWeightsandFields(bool onlyWithField=True, exclude=None)
def addVMCFields(shipGeo, str controlFile="", bool verbose=False, bool withVirtualMC=True)
def create_config(str DecayVolumeMedium="helium", float Yheight=6.0, int strawDesign=10, muShieldGeo=None, str shieldName="New_HA_Design", int nuTargetPassive=1, bool SND=True, SND_design=None, TARGET_YAML=None)
None configurerpvsusy(P8gen, mass, couplings, sfermionmass, benchmark, inclusive, bool deepCopy=False, bool debug=True)
None configure(P8gen, mass, production_couplings, decay_couplings, process_selection, bool deepCopy=False, bool debug=True)
def configure(P8gen, mass, epsilon, inclusive, motherMode, deepCopy=False, debug=True)
None checkOverlapsWithGeant4()
None visualizeMagFields()
def execute(f, ox, name="ShipGeo")
def configure(run, ship_geo)
None configure(darkphoton=None)