FairShip
Loading...
Searching...
No Matches
pythia8darkphoton_conf.py
Go to the documentation of this file.
1# SPDX-License-Identifier: LGPL-3.0-or-later
2# SPDX-FileCopyrightText: Copyright CERN for the benefit of the SHiP Collaboration
3
4import contextlib
5import os
6
7import darkphoton
8import proton_bremsstrahlung
9import readDecayTable
10import ROOT
11import shipunit as u
12from method_logger import MethodLogger
13
14# Boundaries for production in meson decays
15# mass of the mesons
16pi0mass = 0.1349770
17etamass = 0.547862
18omegamass = 0.78265
19eta1mass = 0.95778
20
21
22def addDPtoROOT(pid=9900015, m=0.2, g=4.866182e-04):
23 pdg = ROOT.TDatabasePDG.Instance()
24 pdg.AddParticle("A", "DarkPhoton", m, False, g, 0.0, "A", pid)
25
26
28 FairShip = os.environ["FAIRSHIP"]
29 with open(FairShip + "/shipgen/branchingratios.dat") as ascii:
30 content = ascii.readlines()
31 h = {}
32 n = 0
33 while n < len(content):
34 line = content[n]
35 if "TH1F" in line:
36 keys = line.split("|")
37 n += 1
38 limits = content[n].split(",")
39 hname = keys[1]
40 if len(keys) < 5:
41 keys.append(",")
42 h[hname] = ROOT.TH1F(
43 hname, keys[2] + ";" + keys[3] + ";" + keys[4], int(limits[0]), float(limits[1]), float(limits[2])
44 )
45 else:
46 keys = line.split(",")
47 h[hname].SetBinContent(int(keys[0]), float(keys[1]))
48 n += 1
49 return h
50
51
52def manipulatePhysics(motherMode, mass, P8gen):
53 # changes of the table, now it is deleted and we have each meson mother for each meson production
54 # print motherMode
55 if motherMode == "pi0" and pi0mass - mass >= 0.0000001:
56 # use pi0 -> gamma A'
57 selectedMum = 111
58 P8gen.SetParameters("111:oneChannel = 1 1 0 22 9900015")
59
60 elif motherMode == "eta" and etamass - mass >= 0.000001:
61 # use eta -> gamma A'
62 # print "eta"
63 selectedMum = 221
64 P8gen.SetParameters("221:oneChannel = 1 1 0 22 9900015")
65
66 elif motherMode == "omega" and omegamass - mass >= 0.00001:
67 # use omega -> pi0 A'
68 # print "omega"
69 selectedMum = 223
70 P8gen.SetParameters("223:oneChannel = 1 1 0 111 9900015")
71
72 elif motherMode == "eta1" and eta1mass - mass >= 0.00001:
73 # use eta' -> gamma A'
74 selectedMum = 331
75 P8gen.SetParameters("331:oneChannel = 1 1 0 22 9900015")
76 # should be considered also for mass < 0.188 GeV....
77 # P8gen.SetParameters("331:oneChannel = 1 1 0 223 9900015")29%BR
78 # P8gen.SetParameters("331:oneChannel = 1 1 0 113 9900015")2.75%BR
79
80 elif motherMode == "eta11" and eta1mass - mass >= 0.00001:
81 # use eta' -> gamma A'
82 selectedMum = 331
83 P8gen.SetParameters("331:oneChannel = 1 1 0 113 9900015")
84 # should be considered also for mass < 0.188 GeV....
85 # P8gen.SetParameters("331:oneChannel = 1 1 0 223 9900015")29%BR
86 # P8gen.SetParameters("331:oneChannel = 1 1 0 113 9900015")2.75%BR
87
88 else:
89 # print "ERROR: please enter a nicer mass, for meson production it needs to be between %3.3f and %3.3f."%(pi0Start,eta1Stop)
90 return -1
91 return selectedMum
92
93
94def configure(P8gen, mass, epsilon, inclusive, motherMode, deepCopy=False, debug=True):
95 # configure pythia8 for Ship usage
96 _exit_stack = contextlib.ExitStack()
97 if debug:
98 pythia_log = _exit_stack.enter_context(open("pythia8_conf.txt", "w")) # noqa: SIM115
99 P8gen = MethodLogger(P8gen, sink=pythia_log)
100 P8gen.UseRandom3() # TRandom1 or TRandom3 ?
101 P8gen.SetMom(400) # beam momentum in GeV
102 if deepCopy:
103 P8gen.UseDeepCopy()
104 ROOT.TDatabasePDG.Instance()
105 if inclusive == "meson":
106 # let strange particle decay in Geant4
107 p8 = P8gen.getPythiaInstance()
108 n = 1
109 while n != 0:
110 n = p8.particleData.nextId(n)
111 p = p8.particleData.particleDataEntryPtr(n)
112 if p.tau0() > 1:
113 command = str(n) + ":mayDecay = false"
114 p8.readString(command)
115 print("Pythia8 configuration: Made %s stable for Pythia, should decay in Geant4" % (p.name()))
116
117 # Configuring production
118 P8gen.SetParameters("SoftQCD:nonDiffractive = on")
119
120 elif inclusive == "qcd":
121 P8gen.SetDY()
122 P8gen.SetMinDPMass(0.7)
123
124 if mass < P8gen.MinDPMass():
125 print("WARNING! Mass is too small, minimum is set to %3.3f GeV." % P8gen.MinDPMass())
126 return 0
127
128 # produce a Z' from hidden valleys model
129 p8 = P8gen.getPythiaInstance()
130 n = 1
131 while n != 0:
132 n = p8.particleData.nextId(n)
133 p = p8.particleData.particleDataEntryPtr(n)
134 if p.tau0() > 1:
135 command = str(n) + ":mayDecay = false"
136 p8.readString(command)
137 print("Pythia8 configuration: Made %s stable for Pythia, should decay in Geant4" % (p.name()))
138
139 # Configuring production
140 P8gen.SetParameters("HiddenValley:ffbar2Zv = on")
141 P8gen.SetParameters("HiddenValley:Ngauge = 1")
142
143 elif inclusive == "pbrem":
144 P8gen.SetParameters("ProcessLevel:all = off")
145 # Also allow resonance decays, with showers in them
146 # P8gen.SetParameters("Standalone:allowResDec = on")
147
148 # Optionally switch off decays.
149 # P8gen.SetParameters("HadronLevel:Decay = off")
150
151 # Switch off automatic event listing in favour of manual.
152 P8gen.SetParameters("Next:numberShowInfo = 0")
153 P8gen.SetParameters("Next:numberShowProcess = 0")
154 P8gen.SetParameters("Next:numberShowEvent = 0")
155 proton_bremsstrahlung.protonEnergy = P8gen.GetMom()
156 norm = proton_bremsstrahlung.prodRate(mass, epsilon)
157 print("A' production rate per p.o.t: \t %.8g" % norm)
158 P8gen.SetPbrem(proton_bremsstrahlung.hProdPDF(mass, epsilon, norm, 350, 1500))
159
160 # Define dark photon
161 DP_instance = darkphoton.DarkPhoton(mass, epsilon)
162 ctau = DP_instance.cTau()
163 print("ctau p8dpconf file =%3.6f cm" % ctau)
164 print("Initial particle parameters for PDGID %d :" % P8gen.GetDPId())
165 P8gen.List(P8gen.GetDPId())
166 if inclusive == "qcd":
167 dpid = P8gen.GetDPId()
168 P8gen.SetParameters(f"{dpid}:m0 = {mass:.12}")
169 # P8gen.SetParameters(str(P8gen.GetDPId())+":mWidth = "+str(u.mm/ctau))
170 P8gen.SetParameters(f"{dpid}:mWidth = {u.hbarc / ctau:.12}")
171 P8gen.SetParameters(f"{dpid}:mMin = 0.001")
172 P8gen.SetParameters(f"{dpid}:tau0 = {ctau / u.mm:.12}")
173 # P8gen.SetParameters("ParticleData:modeBreitWigner = 0")
174 # P8gen.SetParameters(str(P8gen.GetDPId())+":isResonance = false")
175 # P8gen.SetParameters(str(P8gen.GetDPId())+":all = A A 3 0 0 "+str(mass)+" 0.0 0.0 0.0 "+str(ctau/u.mm)+" 0 1 0 1 0")
176 P8gen.SetParameters(f"{dpid}:onMode = off")
177 else:
178 P8gen.SetParameters(
179 f"{P8gen.GetDPId()}:new = A A 3 0 0 {mass:.12} 0.0 0.0 0.0 {ctau / u.mm:.12} 0 1 0 1 0"
180 )
181 # if (inclusive=="pbrem"):
182
186
187 P8gen.SetParameters("Next:numberCount = 0")
188
189 # Configuring decay modes...
191 P8gen,
192 mass,
193 DP_instance,
194 conffile=os.path.expandvars("$FAIRSHIP/python/darkphotonDecaySelection.conf"),
195 verbose=True,
196 )
197 # Finish DP setup...
198 P8gen.SetParameters(f"{P8gen.GetDPId()}:mayDecay = on")
199 # P8gen.SetDPId(P8gen.GetDPId())
200 # also add to PDG
201 gamma = u.hbarc / float(ctau) # 197.3269631e-16 / float(ctau) # hbar*c = 197 MeV*fm = 197e-16 GeV*cm
202 print("gamma=%e" % gamma)
203 addDPtoROOT(pid=P8gen.GetDPId(), m=mass, g=gamma)
204
205 if inclusive == "meson":
206 # change meson decay to dark photon depending on mass
207 selectedMum = manipulatePhysics(motherMode, mass, P8gen)
208 print("selected mum is : %d" % selectedMum)
209 if selectedMum == -1:
210 return 0
211
212 # P8gen.SetParameters("Check:particleData = on")
213
214 _exit_stack.close()
215
216 return 1
def prodRate(mDarkPhoton, epsilon, tmin=-0.5 *math.pi, tmax=0.5 *math.pi)
def hProdPDF(mDarkPhoton, epsilon, norm, binsp, binstheta, tmin=-0.5 *math.pi, tmax=0.5 *math.pi, suffix="")
def configure(P8gen, mass, epsilon, inclusive, motherMode, deepCopy=False, debug=True)
def manipulatePhysics(motherMode, mass, P8gen)
def addDarkPhotondecayChannels(P8gen, mDP, DP, conffile=os.path.expandvars("$FAIRSHIP/python/darkphotonDecaySelection.conf"), verbose=True)
int open(const char *, int)
Opens a file descriptor.