SND@LHC Software
Loading...
Searching...
No Matches
makeDecay.py
Go to the documentation of this file.
1from __future__ import print_function
2from __future__ import division
3#Use Pythia8 to decay the signals (Charm/Beauty) as produced by makeCascade.
4#Output is an ntuple with muon/neutrinos
5import ROOT,time,os,sys,random,getopt
6import rootUtils as ut
7ROOT.gROOT.LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C")
8ROOT.basiclibs()
9
10# latest production May 2016,76 M pot which produce a charm event equivalent,roughly 150 M charm hadrons
11fname='/eos/experiment/ship/data/Charm/Cascade-parp16-MSTP82-1-MSEL4-76Mpot_1'
12
13nrpotspill=5.e13 #number of pot/spill
14chicc=1.7e-3 #prob to produce primary ccbar pair/pot
15chibb=1.6e-7 #prob to produce primary bbbar pair/pot
16setByHand = False
17
18print("usage: python $FAIRSHIP/macro/makeDecay.py -f ")
19
20try:
21 opts, args = getopt.getopt(sys.argv[1:], "f:p:c:",[\
22 "pot=","chicc="])
23except getopt.GetoptError:
24 # print help information and exit:
25 print(' enter -f: input file with charm hadrons')
26 print(' for experts: p pot= number of protons on target per spill to normalize on')
27 print(' : c chicc= ccbar over mbias cross section')
28 sys.exit()
29for o, a in opts:
30 if o in ("-f",):
31 fname = a.replace('.root','')
32 if o in ("-p","--pot"):
33 nrpotspill = float(a)
34 if o in ("-c","--chicc"):
35 chicc = float(a)
36 setByHand = True
37
38FIN =fname+'.root'
39tmp = os.path.abspath(FIN).split('/')
40FOUT='Decay-'+tmp[len(tmp)-1]
41if FIN.find('eos')<0: fin = ROOT.TFile(FIN)
42else: fin = ROOT.TFile.Open(ROOT.gSystem.Getenv("EOSSHIP")+FIN)
43sTree = fin.FindObjectAny("pythia6")
44nEvents = sTree.GetEntries()
45
46#Calculate weights, for the whole file.
47#get histogram with number of pot to normalise
48hc={}
49if fin.GetKey("2") :
50 hc['2']=fin.Get("2")
51else:
52 fhin = ROOT.TFile(FIN.replace('ntuple','hists'))
53 hc['2']=fhin.Get("2")
54
55#pot are counted double, i.e. for each signal, i.e. pot/2.
56nrcpot=hc['2'].GetBinContent(1)/2.
57print('Input file: ',FIN,' with ',nEvents,' entries, corresponding to nr-pot=',nrcpot)
58#nEvents=100
59print('Output ntuples written to: ',FOUT)
60
61P8gen = ROOT.TPythia8()
62P8=P8gen.Pythia8()
63P8.readString("ProcessLevel:all = off")
64
65# let strange particle decay in Geant4
66n=1
67while n!=0:
68 n = p8.particleData.nextId(n)
69 p = p8.particleData.particleDataEntryPtr(n)
70 if p.tau0()>1:
71 command = str(n)+":mayDecay = false"
72 p8.readString(command)
73 print("Pythia8 configuration: Made %s stable for Pythia, should decay in Geant4",p.name())
74P8.init()
75
76
77#output ntuple:
78ftup = ROOT.TFile.Open(FOUT, 'RECREATE')
79Ntup = ROOT.TNtuple("Decay","pythia8 heavy flavour decays","id:px:py:pz:E:M:weight:mid:mpx:mpy:mpz:mE:pot:ptGM:pzGM")
80
81h={}
82#book hists for Genie neutrino momentum distrubition, just as check
83# type of neutrino
84PDG = ROOT.TDatabasePDG.Instance()
85for idnu in range(12,18,2):
86#nu or anti-nu
87 for idadd in range(-1,3,2):
88 idhnu=1000+idnu
89 idw=idnu
90 if idadd==-1:
91 idhnu+=1000
92 idw=-idnu
93 name=PDG.GetParticle(idw).GetName()
94 ut.bookHist(h,str(idhnu),name+' momentum (GeV)',400,0.,400.)
95 ut.bookHist(h,str(idhnu+100),name+' log10-p vs log10-pt',100,-0.3,1.7,100,-2.,0.5)
96 ut.bookHist(h,str(idhnu+200),name+' log10-p vs log10-pt',25,-0.3,1.7,100,-2.,0.5)
97
98pot=0.
99#Determine fDs on this file for primaries
100nDsprim=0
101ntotprim=0
102
103for n in range(nEvents):
104 rc = sTree.GetEvent(n)
105# check if we deal with charm or beauty:
106 if n == 0:
107 if not setByHand and sTree.M>5:
108 chicc = chibb
109 print("automatic detection of beauty, configured for beauty")
110 print('bb cross section / mbias ',chicc)
111 else:
112 print('cc cross section / mbias ',chicc)
113 #convert pot to weight corresponding to one spill of 5e13 pot
114 print('weights: ',nrpotspill,' p.o.t. per spill')
115 print(' ')
116 wspill=nrpotspill*chicc/nrcpot
117 #sanity check, count number of p.o.t. on input file.
118 pt=ROOT.TMath.Sqrt(sTree.mpx**2+sTree.mpy**2)
119 #every event appears twice, i.e.
120 if pt<1.e-5 and int(sTree.mid)==2212:
121 pot=pot+0.5
122 ntotprim+=1
123 idabs=int(abs(sTree.id))
124 if idabs==431: nDsprim+=1
125 P8.event.reset()
126 P8.event.append(int(sTree.id),1,0,0,sTree.px,sTree.py,sTree.pz,sTree.E,sTree.M,0.,9.)
127 next(P8)
128 #P8.event.list()
129 for n in range(P8.event.size()):
130 #ask for stable particles
131 if P8.event[n].isFinal():
132 #select neutrinos and mu
133 idabs=int(abs(P8.event[n].id()))
134 if idabs>11 and idabs<17:
135 par= P8.event[n]
136 ptGM = ROOT.TMath.Sqrt(sTree.mpx*sTree.mpx+sTree.mpy*sTree.mpy)
137 Ntup.Fill(par.id(),par.px(),par.py(),par.pz(),par.e(),par.m(),wspill,sTree.id,sTree.px,sTree.py,sTree.pz,sTree.E,sTree.M,ptGM,sTree.mpz)
138 #count total muons from charm/spill, and within some angluar range..
139 if idabs==16 or idabs==14 or idabs==12:
140 idhnu=idabs+1000
141 if par.id()<0: idhnu+=1000
142 pt2=par.px()**2+par.py()**2
143 ptot=ROOT.TMath.Sqrt(pt2+par.pz()**2)
144 l10ptot=min(max(ROOT.TMath.Log10(ptot),-0.3),1.69999)
145 l10pt=min(max(ROOT.TMath.Log10(ROOT.TMath.Sqrt(pt2)),-2.),0.4999)
146 h[str(idhnu)].Fill(ptot,wspill)
147 h[str(idhnu+100)].Fill(l10ptot,l10pt,wspill)
148 h[str(idhnu+200)].Fill(l10ptot,l10pt,wspill)
149
150print('Now at Ntup.Write() for pot=',pot,nrcpot)
151if (1.-pot/nrcpot)<1.e-2:
152 print('write ntuple, weight/event=',nrpotspill,'x',chicc,'/',nrcpot,'=',wspill)
153 Ntup.Write()
154 for akey in h: h[akey].Write()
155 ftup.Close()
156 print('Neutrino statistics/spill of 5.e15 pot:')
157 for idnu in range(12,18,2):
158 #nu or anti-nu
159 for idadd in range(-1,3,2):
160 idhnu=1000+idnu
161 idw=idnu
162 if idadd==-1:
163 idhnu+=1000
164 idw=-idnu
165 print(idhnu,h[str(idhnu)].GetTitle(),("%8.3E "%(h[str(idhnu)].Integral())))
166
167 fDsP6=1.*nDsprim/ntotprim
168 fDs=0.077 #Used in TP..
169 print(' ')
170 print('fDs of primary proton interactions in P6=',fDsP6, ' should be ',fDs)
171
172else:
173 print('*********** WARNING ***********')
174 print('number of POT does not agree between ntuple and hists, i.e.:',pot,'<>',nrcpot)
175 print('mu/neutrino ntuple has NOT been written')
176#
177
178
179