SND@LHC Software
Loading...
Searching...
No Matches
darkphoton.py
Go to the documentation of this file.
1from __future__ import division
2from __future__ import print_function
3import math
4import os
5import ROOT as r
6
7#from settings import *
8#from functions import *
9from hnl import mass
10from hnl import PDGname
11
12# constants
13alphaQED = 1./137.
14ccm = 2.99792458e+10
15hGeV = 6.58211928*pow(10.,-16)* pow(10.,-9) # no units or it messes up!!
16
17#utilities
18# sigma(e+e- -> hadrons) / sigma(e+e- -> mu+mu-)
19
21 "dark photon setup"
22
23 def __init__(self, mass, eps):
24 self.mDarkPhoton = mass
25 self.epsilon = eps
26 self.dataEcm,self.dataR = self.readPDGtable()
28
29 def readPDGtable(self):
30 """ Returns R data from PDG in a easy to use format """
31 ecm=r.vector('double')()
32 ratio=r.vector('double')()
33 """ecm,ratio = [],[]"""
34 with open(os.path.expandvars('$FAIRSHIP/input/rpp2012-hadronicrpp_page1001.dat'),'r') as f:
35 for line in f:
36 line = line.split()
37 try:
38 numEcm = float(line[0])
39 numR = float(line[3])
40 strType = line[7]
41 strBis = line[8]
42 #if numEcm<2:
43 # print numEcm,numR,strType
44 if (('EXCLSUM' in strType) or ('EDWARDS' in strType) or ('BLINOV' in strType)):
45 ecm.push_back(numEcm)
46 ratio.push_back(numR)
47 #print numEcm,numR,strType
48 if 'BAI' in strType and '01' in strBis:
49 ecm.push_back(numEcm)
50 ratio.push_back(numR)
51 #print numEcm,numR,strType
52 except:
53 continue
54 return ecm,ratio
55
56
58 """ Find the best value for R for the given center-of-mass energy """
59 fun = r.Math.Interpolator(self.dataEcm.size(),r.Math.Interpolation.kLINEAR)
60 fun.SetData(self.dataEcm,self.dataR);
61 return fun
62
63 def Ree_interp(self,s): # s in GeV
64 """ Using PDG values for sigma(e+e- -> hadrons) / sigma(e+e- -> mu+mu-) """
65 # Da http://pdg.lbl.gov/2012/hadronic-xsections/hadron.html#miscplots
66 #ecm = math.sqrt(s)
67 ecm = s
68 if ecm>=10.29:
69 print('Warning! Asking for interpolation beyond 10.29 GeV: not implemented, needs extending! Taking value at 10.29 GeV')
70 result=float(self.PdgR.Eval(10.29))
71 elif ecm>=self.dataEcm[0]:
72 result = float(self.PdgR.Eval(ecm))
73 else:
74 result=0
75 #print 'Ree_interp for mass %3.3f is %.3e'%(s,result)
76 return result
77
78 def leptonicDecayWidth(self,lepton): # mDarkPhoton in GeV
79 """ Dark photon decay width into leptons, in GeV (input short name of lepton family) """
80 ml = mass(lepton)
81 #print 'lepton %s mass %.3e'%(lepton,ml)
82
83 constant = (1./3.) * alphaQED * self.mDarkPhoton * pow(self.epsilon, 2.)
84 if 2.*ml < self.mDarkPhoton:
85 rad = math.sqrt( 1. - (4.*ml*ml)/(self.mDarkPhoton*self.mDarkPhoton) )
86 else:
87 rad = 0.
88
89 par = 1. + (2.*ml*ml)/(self.mDarkPhoton*self.mDarkPhoton)
90 tdw=math.fabs(constant*rad*par)
91 #print 'Leptonic decay width to %s is %.3e'%(lepton,tdw)
92 return tdw
93
94 def leptonicBranchingRatio(self,lepton):
95 return self.leptonicDecayWidth(lepton) / self.totalDecayWidth()
96
98 """ Dark photon decay into hadrons """
99 """(mumu)*R"""
100 gmumu=self.leptonicDecayWidth('mu-')
101 tdw=gmumu*self.Ree_interp(self.mDarkPhoton)
102 #print 'Hadronic decay width is %.3e'%(tdw)
103 return tdw;
104
105 def hadronicBranchingRatio(self):
106 return self.hadronicDecayWidth() / self.totalDecayWidth()
107
108 def totalDecayWidth(self): # mDarkPhoton in GeV
109 """ Total decay width in GeV """
110 #return hGeV*c / cTau(mDarkPhoton, epsilon)
111 tdw = (self.leptonicDecayWidth('e-')
112 + self.leptonicDecayWidth('mu-')
113 + self.leptonicDecayWidth('tau-')
114 + self.hadronicDecayWidth())
115
116 #print 'Total decay width %e'%(tdw)
117
118 return tdw
119
120 def cTau(self): # decay length in meters, dark photon mass in GeV
121 """ Dark Photon lifetime in cm"""
122 ctau=hGeV*ccm/self.totalDecayWidth()
123 #print "ctau dp.py %.3e"%(ctau)
124 return ctau #GeV/MeV conversion
125
126 def lifetime(self):
127 return self.cTau()/ccm
128
129 def findBranchingRatio(self,decayString):
130 br = 0.
131 if decayString == 'A -> e- e+': br = self.leptonicBranchingRatio('e-')
132 elif decayString == 'A -> mu- mu+': br = self.leptonicBranchingRatio('mu-')
133 elif decayString == 'A -> tau- tau+': br = self.leptonicBranchingRatio('tau-')
134 elif decayString == 'A -> hadrons': br = self.hadronicBranchingRatio()
135 else:
136 print('findBranchingRatio ERROR: unknown decay %s'%decayString)
137 quit()
138
139 return br
140
141 def allowedChannels(self):
142 print("Allowed channels for dark photon mass = %3.3f"%self.mDarkPhoton)
143 allowedDecays = {'A -> hadrons':'yes'}
144 if self.mDarkPhoton > 2.*mass('e-'):
145 allowedDecays.update({'A -> e- e+':'yes'})
146 print("allowing decay to e")
147 if self.mDarkPhoton > 2.*mass('mu-'):
148 allowedDecays.update({'A -> mu- mu+':'yes'})
149 print("allowing decay to mu")
150 if self.mDarkPhoton > 2.*mass('tau-'):
151 allowedDecays.update({'A -> tau- tau+':'yes'})
152 print("allowing decay to tau")
153
154 return allowedDecays
155
156
157 def scaleNEventsIncludingHadrons(self,n):
158 """ Very simple patch to take into account A' -> hadrons """
159 brh = self.hadronicBranchingRatio()
160 #print brh
161 # if M > m(c cbar):
162 if self.mDarkPhoton > 2.*mass('c'):
163 visible_frac = 1.
164 else:
165 visible_frac = 2./3.
166
167 increase = brh*visible_frac
168 #print increase
169 return n*(1. + increase)
170
171
leptonicBranchingRatio(self, lepton)
Definition darkphoton.py:94
leptonicDecayWidth(self, lepton)
Definition darkphoton.py:78
__init__(self, mass, eps)
Definition darkphoton.py:23