FairShip
Loading...
Searching...
No Matches
extractMuonsAndUpdateWeight.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 os
5
6import ROOT
7
8path = "/eos/experiment/ship/data/Mbias/background-prod-2018/"
9
10# functions, should extract events with muons, update weight based on process/decay and PoT
11
12muSources = {"eta": 221, "omega": 223, "phi": 333, "rho0": 113, "eta_prime": 331}
13charmExtern = [4332, 4232, 4132, 4232, 4122, 431, 411, 421]
14
15# for 10GeV Yandex Production 65.041 Billion PoT, weight = 768.75 for 5E13 pot
16weightMbias = 768.75
17
18# for 10GeV charm Production 102.2 Billion PoT equivalent, weight = 489.24
19# added another cycle
20weightCharm = 489.24 * 2.0 / 3.0
21
22# for 10GeV charm Production 5336 Billion PoT equivalent, weight = 9.37
23weightBeauty = 9.37
24
25
26def muonUpdateWeight(sTree, diMuboost: float, xSecboost: float, noCharm=True) -> int:
27 nMu = 0
28 for v in sTree.vetoPoint:
29 mu = v.GetTrackID()
30 t = sTree.MCTrack[mu]
31 if abs(t.GetPdgCode()) != 13:
32 continue
33 moID = abs(sTree.MCTrack[t.GetMotherId()].GetPdgCode())
34 if moID in charmExtern and noCharm:
35 continue # take heavy flavours from separate production
36 nMu += 1
37 pName = t.GetProcName().Data()
38 t.SetWeight(weight)
39 if not pName.find("Hadronic inelastic") < 0:
40 t.MultiplyWeight(1.0 / diMuboost)
41 elif not pName.find("Lepton pair") < 0 or not pName.find("Positron annihilation") < 0:
42 t.MultiplyWeight(1.0 / xSecboost)
43 elif not pName.find("Primary particle") < 0 or not pName.find("Decay") < 0:
44 if moID in muSources.values():
45 t.MultiplyWeight(1.0 / diMuboost)
46 return nMu
47
48
49def PoT(f) -> tuple[float | int, float, float]:
50 nTot = 0
51 # POT = 1000000000 with ecut=10.0 diMu100.0 X100.0
52 diMuboost = 0.0
53 xSecboost = 0.0
54 ncycles = 0
55 for k in f.GetListOfKeys():
56 if k.GetName() == "FileHeader":
57 txt = k.GetTitle()
58 tmp = txt.split("=")[1]
59 tmp2 = tmp.split("with")[0]
60 if tmp2.find("E") < 0:
61 nTot += int(tmp2)
62 else:
63 nTot += float(tmp2)
64 ncycles += 1
65 i = txt.find("diMu")
66 if i < 0:
67 diMuboost += 1.0
68 else:
69 diMuboost += float(txt[i + 4 :].split(" ")[0])
70 i = txt.find("X")
71 if i < 0:
72 xSecboost += 1.0
73 else:
74 xSecboost += float(txt[i + 1 :].split(" ")[0])
75 diMuboost = diMuboost / float(ncycles)
76 xSecboost = xSecboost / float(ncycles)
77 print(
78 "POT = ",
79 nTot,
80 " number of events:",
81 f.Get("cbmsim").GetEntries(),
82 " diMuboost=",
83 diMuboost,
84 " XsecBoost=",
85 xSecboost,
86 )
87 return nTot, diMuboost, xSecboost
88
89
90def TotStat() -> None:
91 lfiles = os.listdir(path)
92 ntot = 0
93 for fn in lfiles:
94 f = ROOT.TFile(path + fn)
95 nPot, _diMuboost, _xSecboost = PoT(f)
96 ntot += nPot
97 print("Total statistics so far", ntot / 1.0e9, " billion")
98
99
100def processFile(fin: str, noCharm: bool = True) -> int:
101 f = ROOT.TFile.Open(os.environ["EOSSHIP"] + path + fin)
102 nPot, diMuboost, xSecboost = PoT(f)
103 sTree = f.Get("cbmsim")
104 outFile = fin.replace(".root", "_mu.root")
105 fmu = ROOT.TFile(outFile, "recreate")
106 newTree = sTree.CloneTree(0)
107 for n in range(sTree.GetEntries()):
108 sTree.GetEntry(n)
109 nMu = muonUpdateWeight(sTree, diMuboost, xSecboost, noCharm)
110 if nMu > 0:
111 newTree.Fill()
112 ff = f.FileHeader.Clone("Extracted Muon Background File")
113 txt = ff.GetTitle()
114 tmp = txt.split("=")[1]
115 newTxt = txt.replace(tmp.split("with")[0].replace(" ", ""), str(nPot))
116 ff.SetTitle(newTxt)
117 fmu.cd()
118 ff.Write("FileHeader", ROOT.TObject.kSingleKey)
119 newTree.AutoSave()
120 fmu.Close()
121 return 0
122
123
124def run() -> None:
125 tmp = "pythia8_Geant4_10.0_cXX.root"
126 global weight
127 weight = weightMbias
128 for run in range(0, 67000, 1000):
129 rc = processFile(tmp.replace("XX", str(run)))
130 if rc == 0:
131 fmu = tmp.replace("XX", str(run) + "_mu")
132 rc = os.system("xrdcp " + fmu + " $EOSSHIP/eos/experiment/ship/data/Mbias/background-prod-2018/" + fmu)
133 if rc != 0:
134 print("copy to EOS failed, stop", fmu)
135 else:
136 rc = os.system("rm " + fmu)
137
138
139def run4Charm() -> None:
140 tmp = "pythia8_Geant4_charm_XX-YY_10.0.root"
141 global weight
142 weight = weightCharm
143 for cycle in [0, 1, 2]:
144 for run in range(0, 100, 20):
145 crun = run + cycle * 1000
146 fname = tmp.replace("XX", str(crun)).replace("YY", str(crun + 19))
147 rc = processFile(fname, False)
148 if rc == 0:
149 fmu = fname.replace(".root", "_mu.root")
150 rc = os.system("xrdcp " + fmu + " $EOSSHIP/eos/experiment/ship/data/Mbias/background-prod-2018/" + fmu)
151 if rc != 0:
152 print("copy to EOS failed, stop", fmu)
153 else:
154 rc = os.system("rm " + fmu)
155
156
157def run4beauty() -> None:
158 global weight
159 weight = weightBeauty
160 fname = "pythia8_Geant4_beauty_5336B_10.0.root"
161 rc = processFile(fname, False)
162 if rc == 0:
163 fmu = fname.replace(".root", "_mu.root")
164 rc = os.system("xrdcp " + fmu + " $EOSSHIP/eos/experiment/ship/data/Mbias/background-prod-2018/" + fmu)
165 if rc != 0:
166 print("copy to EOS failed, stop", fmu)
167 else:
168 rc = os.system("rm " + fmu)
169
170
171# merge with beauty in a second step
172
173
174# finished one file pythia8_Geant4_10.0_withCharm44000_mu.root 2712798 1113638
175
176
177def mergeCharm() -> None:
178 tmp = "pythia8_Geant4_charm_XX-YY_10.0.root"
179 mergedFile = "pythia8_Geant4_charm_102.2B_10.0_mu.root"
180 cmd = "hadd " + mergedFile
181 for cycle in [0, 1]:
182 for run in range(0, 100, 20):
183 crun = run + cycle * 1000
184 fname = tmp.replace("XX", str(crun)).replace("YY", str(crun + 19))
185 fmu = " $EOSSHIP/eos/experiment/ship/data/Mbias/background-prod-2018/" + fname.replace(".root", "_mu.root")
186 cmd += fmu
187 os.system(cmd)
188 os.system("xrdcp " + mergedFile + " $EOSSHIP/eos/experiment/ship/data/Mbias/background-prod-2018/" + mergedFile)
189
190
191def mergeMbiasAndCharm(flavour: str = "charm") -> None:
192 done = []
193 timer = ROOT.TStopwatch()
194 timer.Start()
195 pp = os.environ["EOSSHIP"] + path
196 Rndm = ROOT.TRandom3()
197 Rndm.SetSeed(0)
198 if flavour == "charm":
199 allFiles = {"charm": "pythia8_Geant4_charm_102.2B_10.0_mu.root"}
200 tmp = "pythia8_Geant4_10.0_cXX_mu.root"
201 else:
202 allFiles = {"beauty": "pythia8_Geant4_beauty_5336B_10.0_mu.root"}
203 tmp = "pythia8_Geant4_10.0_withCharmXX_mu.root"
204 for run in range(0, 67000, 1000):
205 allFiles[str(run)] = tmp.replace("XX", str(run))
206 nEntries = {}
207 Nall = 0
208 for x in allFiles:
209 f = ROOT.TFile.Open(pp + allFiles[x])
210 nEntries[x] = f.Get("cbmsim").GetEntries()
211 Nall += nEntries[x]
212 nCharm = 0
213 frac = nEntries[flavour] / float(Nall)
214 print("debug", frac)
215 os.system("xrdcp " + pp + allFiles[flavour] + " " + allFiles[flavour])
216 for k in allFiles:
217 if k == flavour:
218 continue
219 if k in done:
220 continue
221 os.system("xrdcp " + pp + allFiles[k] + " " + allFiles[k])
222 os.system("hadd -f tmp.root " + allFiles[flavour] + " " + allFiles[k])
223 os.system("rm " + allFiles[k])
224 f = ROOT.TFile("tmp.root")
225 sTree = f.Get("cbmsim")
226 sTree.LoadBaskets(30000000000)
227 if flavour == "charm":
228 outFile = tmp.replace("cXX", "withCharm" + k)
229 else:
230 outFile = tmp.replace("XX", "andBeauty" + k)
231 fmu = ROOT.TFile(outFile, "recreate")
232 newTree = sTree.CloneTree(0)
233 nMbias = 0
234 # 0 - nEntries['charm']-1 , nEntries['charm'] - nEntries[0]-1, nEntries[0] - nEntries[1000]-1
235 # randomList = ROOT.TEntryList(chain)
236 myList = []
237 while nMbias < nEntries[k]:
238 if Rndm.Rndm() > frac:
239 # rc = randomList.Enter(nMbias+nEntries['charm'])
240 myList.append(nMbias + nEntries[flavour])
241 nMbias += 1
242 else:
243 if nEntries[flavour] > nCharm:
244 # rc = randomList.Enter(nCharm)
245 myList.append(nCharm)
246 nCharm += 1
247 else:
248 pass
249 # chain.SetEntryList(randomList)
250 # nev = randomList.GetN()
251 nev = len(myList)
252 print("start:", outFile, nev)
253 for iev in range(nev):
254 rc = sTree.GetEntry(myList[iev])
255 rc = newTree.Fill()
256 if (iev) % 100000 == 0:
257 timer.Stop()
258 print("status:", timer.RealTime(), k, iev)
259 timer.Start()
260 newTree.AutoSave()
261 print("finished one file", outFile, nMbias, nCharm)
262 if flavour == "charm":
263 ff = f.FileHeader.Clone("With Charm Merged Muon Background File")
264 else:
265 ff = f.FileHeader.Clone("With Charm and Beauty Merged Muon Background File")
266 ff.GetTitle()
267 fmu.cd()
268 ff.Write("FileHeader", ROOT.TObject.kSingleKey)
269 fmu.Close()
270 f.Close()
271 rc = os.system("xrdcp " + outFile + " $EOSSHIP/eos/experiment/ship/data/Mbias/background-prod-2018/" + outFile)
272 if rc != 0:
273 print("copy to EOS failed", outFile)
274 else:
275 rc = os.system("rm " + outFile)
276
277
278def testRatio(fname) -> None:
279 f = ROOT.TFile.Open(os.environ["EOSSHIP"] + path + fname)
280 sTree = f.Get("cbmsim")
281 Nall = sTree.GetEntries()
282 charm = 0
283 for n in range(Nall):
284 sTree.GetEvent(n)
285 for m in sTree.MCTrack:
286 pdgID = abs(m.GetPdgCode())
287 if pdgID in charmExtern:
288 charm += 1
289 break
290 print("charm found", charm, " ratio ", charm / float(Nall))
int muonUpdateWeight(sTree, float diMuboost, float xSecboost, noCharm=True)
tuple[float|int, float, float] PoT(f)
None mergeMbiasAndCharm(str flavour="charm")
int processFile(str fin, bool noCharm=True)