FairShip
Loading...
Searching...
No Matches
ana_ShipMuon.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
4# analyze muon background /media/Data/HNL/PythiaGeant4Production/pythia8_Geant4_total.root
5import multiprocessing as mp
6import os
7from io import TextIOWrapper
8
9import ROOT
10from ShipGeoConfig import load_from_root_file
11
12ROOT.gInterpreter.ProcessLine("typedef double Double32_t")
13local = False
14if not os.uname()[1].lower().find("ubuntu") < 0:
15 local = True
16
17parallel = True
18if parallel:
19 # Define an output queue
20 output = mp.Queue()
21 processes = []
22
23
24# 11-19 with QGSP_BERT_EMV instead of QGSP_BERT_HP_PEN
25# 51-59 passive shielding
26# 41-49 fixed field horizontal
27# 61-69 chamber with vacuum
28# 71-79 without field in the wings
29# 81-89 add shielding
30# 91-99 switch off muBrems, muPair
31# 101-109 vacuum tube as cone, Al->Steel
32
33# prefix = 'muon4' # default
34# prefix = 'muon6' # Al -> vacuum
35# prefix = 'muon7' # no field in wings
36# prefix = 'muon8' # entry window + additional shielding
37# prefix = 'muon9' # switch off muBrems, muPair
38# prefix = 'muon10' # vacuum tube as cone, Al->Steel
39# prefix = 'muon14' # vacuum tube as cone, Al->Steel, slightly smaller lead shield
40# prefix = 'muon12' # switch off muIoni
41# prefix = 'muon13' # switch off muBrems, muPair AND muIoni
42# prefix = 'muon15' # vacuum tube as cone, Al->Steel, cave with air
43# prefix = 'muon 161-169 new geometry
44# prefix = 'muon 251-259 passive shielding with concrete walls
45# prefix = 'muon 171-179 new increased Bdl, 2.5m clearance from start, 9m space for tau
46# 181-189 narrow tunnel around first magnet, add 2m hadron absorber, fixed problem with B-field -> G4
47# 191-199 narrow tunnel bug fix, also bug fix for top/bottom, now with tungsten core in add absorber
48# 201-209 test with reduced field, 1.5T
49# 211-219 many bug fixes, overlaps, added Goliath magnet
50# 221-229 bug fix for Goliath
51# 231-239 reduce field to 1T
52# 311-314 change numbering of veto volumes
53# 321-324 1 Teslas
54# 331-339 added TauSensitive, fixed C1, using muons from Yandex
55# 341-349 should be the same as 331-339
56# 361-364 4m high magnets!
57# 371-374 new strawpoints
58# 381-389 yandex file, overwrite with magC1 fixed
59# 391-399 change to dY = 2m
60# 401-409 change to dY = 2m Yandex
61# 411-419 back to dY = 4m, add sensitive plance downstream det2
62# 421-429 reduce size of vacuum tank before veto station, add pdgcode for muonPoint, move det2 closer
63# 431-439 reduce size of vacuum tank before veto station, add pdgcode for muonPoint, move det2 closer Yandex
64# 441-449 try with increased tau mu detector, and reduced height of active muon shield, dy=1m
65# 451-459 try with increased tau mu detector, and reduced height of active muon shield, dy=1m Yandex
66# 461-469 dy=4m and then 1m, RPC fixed, display on
67# 471-479 dy=4m and then 1m, RPC fixed, Yandex
68# 481-489 dy=4m and then 1m, RPC fixed, display OFF
69# 491-499 back to dy=1m display on
70# 551-554 ultimate slim design
71# 561-564 fixing overlaps hcal and almost overlaps in magnets
72# 571-574 more undetected overlaps fixed
73# 581-584 test with replacing tungsten core with iron, 10m height
74# 591-599 test with replacing tungsten core with iron, 6m height, display
75# 601-609 replacing tungsten core with iron, 6m height, Yandex data, display
76# 610-619 replacing tungsten core with iron, 10m height, display
77# 620-629 replacing tungsten core with iron, 10m height, Yandex data, display
78# 630-639 10m height, change RPC width 4.5->3.6m
79# 640-649 10m height, change RPC width 4.5->3.6m Yandex
80# 650-669 6m height, change RPC width 4.5->3.6m
81# 660-669 6m height, change RPC width 4.5->3.6m Yandex
82# makeProd("muon700",10,False,False) # switch off field of active shielding # prefix,DY,y=False,phiRandom=False,X=None
83# makeProd("muon710",10,False,False) # start production with beam smeared on r=3cm disk
84# makeProd("muon720",10,True,False)
85# makeProd("muon711",10,False,True) # start production with beam smeared on r=3cm disk
86# makeProd("muon721",10,True,True)
87# makeProd("muon712",10,False,True) # start production with beam smeared on r=3cm disk
88# makeProd("muon722",10,True,True)
89# makeProd("muon713",10,False,True) # start production with beam smeared on r=3cm disk
90# makeProd("muon723",10,True,True)
91# makeProd("muon714",10,False,True) # start production with beam smeared on r=3cm disk
92# makeProd("muon724",10,True,True)
93# makeProd("muon715",10,False,True) # start production with beam smeared on r=3cm disk
94# makeProd("muon725",10,True,True)
95# makeProd("muon716",10,False,True) # start production with beam smeared on r=3cm disk
96# makeProd("muon726",10,True,True)
97# makeProd("muon717",10,False,True) # start production with beam smeared on r=3cm disk
98# makeProd("muon777",10,False,True) # in case the other one does not work 717
99# makeProd("muon727",10,True,True) # ?
100# makeProd("muon718",10,False,True) # start production with beam smeared on r=3cm disk
101# makeProd("muon728",10,True,True)
102# makeProd("muon719",10,False,True) # start production with beam smeared on r=3cm disk
103# makeProd("muon729",10,True,True)
104# makeProd("muon730",10,'Jpsi',False)
105# makeProd("muon731",10,'Jpsi',True)
106# makeProd("muon732",10,'Jpsi',True)
107# makeProd("muon733",10,'Jpsi',True) # back to pencil beam
108# makeProd("muon630",10,False,True) # test with new muonShield code, 3cm smearing
109# makeProd("muon631",10,False,True) # run with concrete wall enabled as sensitive
110# makeProd("muon632",10,False,True) # run with concrete wall enabled as sensitive, active shielding polarity fixed
111# but wrong geometry
112# makeProd("muon810",10,False,False) # start production with latest geometry
113# makeProd("muon820",10,True,False)
114# makeProd("muon811",10,False,True) #
115# makeProd("muon821",10,True,True)
116
123
124# makeProd("muon814",10,False,True) #
125# makeProd("muon824",10,True,True)
126# makeProd("muon815",10,False,True)
127# makeProd("muon825",10,True,True)
128# makeProd("muon816",10,False,True)
129# makeProd("muon826",10,True,True)
130# makeProd("muon817",10,False,True)
131# makeProd("muon827",10,True,True)
132# makeProd("muon818",10,False,True)
133# makeProd("muon828",10,True,True)
134# makeProd("muon819",10,False,True)
135# makeProd("muon829",10,True,True)
136# makeProd("muon910",10,False,True)
137# makeProd("muon920",10,True,True)
138# makeProd("muon911",10,False,True)
139# makeProd("muon921",10,True,True)
140
141# makeProd("muon912",10,False,True)
142# makeProd("muon922",10,True,True)
143
144# makeProd("muon913",10,False,True)
145# makeProd("muon923",10,True,True)
146# makeProd("muon914",10,False,True)
147# makeProd("muon924",10,True,True)
148# makeProd("muon915",10,False,True)
149# makeProd("muon925",10,True,True)
150# makeProd("muon916",10,False,True)
151# makeProd("muon926",10,True,True)
152# makeProd("muon917",10,False,True)
153# makeProd("muon927",10,True,True)
154# makeProd("muon927",10,True,True,8)
155# makeProd("muon918",10,False,True)
156# makeProd("muon928",10,True,True)
157# makeProd("muon919",10,False,True)
158# makeProd("muon929",10,True,True)
159# makeProd("muon1019",10,False,True)
160# makeProd("muon1029",10,True,True)
161# makeProd("muon1018",10,False,True)
162# makeProd("muon1028",10,True,True)
163# makeProd("muon1017",10,False,True)
164# makeProd("muon1027",10,True,True)
165# makeProd("muon1016",10,False,True)
166# makeProd("muon1026",10,True,True)
167# makeProd("muon1015",10,False,True)
168# makeProd("muon1025",10,True,True)
169# makeProd("muon1014",10,False,True)
170# makeProd("muon1024",10,True,True)
171# makeProd("muon1013",10,False,True)
172# makeProd("muon1023",10,True,True)
173# makeProd("muon1012",10,False,True)
174# makeProd("muon1022",10,True,True)
175# makeProd("muon633",10,'concrete',False) # run with concrete wall enabled as sensitive
176# makeProd("muon1111",10,'False',False) # try iron for first shield
177# makeProd("muon1121",10,'True',False) # try iron for first shield
178# makeProd("muon1112",10,'False',True) # try iron for first shield
179# makeProd("muon1122",10,'True',True) # try iron for first shield
180# restart with also rockS sensitive and &&->||
181# makeProd("muon634",10,'concrete',False) # run with concrete wall enabled as sensitive, and active shield too
182# makeProd("muon635",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
183# makeProd("muon636",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
184# makeProd("muon637",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
185# makeProd("muon638",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
186# makeProd("muon639",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
187# makeProd("muon640",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
188# makeProd("muon641",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
189# makeProd("muon642",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
190# makeProd("muon643",10,'concrete',True) # run with concrete wall enabled as sensitive, and active shield too
191# makeProd("muon650",10,'concrete',False) # run with concrete wall enabled as sensitive, first tunnel 10m wide
192# makeProd("muon651",10,'concrete',False) # run with concrete wall enabled as sensitive, first tunnel 10m wide
193# makeProd("muon652",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
194# makeProd("muon653",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
195# makeProd("muon654",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
196# makeProd("muon655",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
197# makeProd("muon656",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
198# makeProd("muon657",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
199# makeProd("muon658",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
200# makeProd("muon659",10,'concrete',True) # run with concrete wall enabled as sensitive, first tunnel 10m wide
201# makeProd("muon660",10,'concrete',False) # liter magnet
202# makeProd("muon661",10,'concrete',True) # liter magnet
203# makeProd("muon662",10,'concrete',True) # liter magnet
204# makeProd("muon663",10,'concrete',True) # liter magnet
205# makeProd("muon664",10,'concrete',True) # liter magnet
206# makeProd("muon665",10,'concrete',True) # liter magnet
207# makeProd("muon666",10,'concrete',True) # liter magnet
208# makeProd("muon667",10,'concrete',True) # liter magnet
209# makeProd("muon668",10,'concrete',True) # liter magnet
210# makeProd("muon669",10,'concrete',True) # liter magnet
211# makeProd("muon670",10,'concrete',False) # even liter magnet
212# makeProd("muon671",10,'concrete',True) # even liter magnet
213# makeProd("muon672",10,'concrete',True) # even liter magnet
214# makeProd("muon673",10,'concrete',True) # even liter magnet
215# makeProd("muon674",10,'concrete',True) # even liter magnet
216# makeProd("muon675",10,'concrete',True) # even liter magnet
217# makeProd("muon676",10,'concrete',True) # even liter magnet
218# makeProd("muon677",10,'concrete',True) # even liter magnet
219# makeProd("muon678",10,'concrete',True) # even liter magnet
220# makeProd("muon679",10,'concrete',True) # even liter magnet
221# new attempt, previous did not worked out
222# makeProd("muon680",10,'concrete',False) # even liter magnet
223# makeProd("muon681",10,'concrete',True) # even liter magnet
224# makeProd("muon682",10,'concrete',True) # even liter magnet
225# makeProd("muon683",10,'concrete',True) # even liter magnet
226# makeProd("muon684",10,'concrete',True) # even liter magnet
227# makeProd("muon685",10,'concrete',True) # even liter magnet
228# makeProd("muon686",10,'concrete',True) # even liter magnet
229# makeProd("muon687",10,'concrete',True) # even liter magnet
230# makeProd("muon688",10,'concrete',True) # even liter magnet
231# makeProd("muon689",10,'concrete',True) # even liter magnet
232# new attempt, increase height of first magnet, previous did not worked out either
233# makeProd("muon690",10,'concrete',False) # even liter magnet
234# makeProd("muon691",10,'concrete',True) # even liter magnet
235# makeProd("muon692",10,'concrete',True) # even liter magnet
236# makeProd("muon693",10,'concrete',True) # even liter magnet
237# makeProd("muon694",10,'concrete',True) # even liter magnet
238# makeProd("muon695",10,'concrete',True) # even liter magnet
239# makeProd("muon696",10,'concrete',True) # even liter magnet
240# makeProd("muon697",10,'concrete',True) # even liter magnet
241# makeProd("muon698",10,'concrete',True) # even liter magnet
242# makeProd("muon699",10,'concrete',True) # even liter magnet
243# testing height 4m->2m
244# makeProd("muon700",10,'concrete',False) # even liter magnet
245# makeProd("muon701",10,'concrete',True) # even liter magnet
246# makeProd("muon702",10,'concrete',True) # even liter magnet
247# makeProd("muon703",10,'concrete',True) # even liter magnet
248# makeProd("muon704",10,'concrete',True) # even liter magnet
249# makeProd("muon705",10,'concrete',True) # even liter magnet
250# makeProd("muon706",10,'concrete',True) # even liter magnet
251# makeProd("muon707",10,'concrete',True) # even liter magnet
252# makeProd("muon708",10,'concrete',True) # even liter magnet
253# makeProd("muon709",10,'concrete',True) # even liter magnet
254# testing height 4m->2m + new magnets
255# makeProd("muon800",10,'concrete',False) # even liter magnet
256# makeProd("muon801",10,'concrete',True) # even liter magnet
257# makeProd("muon802",10,'concrete',True) # even liter magnet
258# makeProd("muon803",10,'concrete',True) # even liter magnet
259# makeProd("muon804",10,'concrete',True) # even liter magnet
260# makeProd("muon805",10,'concrete',True) # even liter magnet
261# makeProd("muon806",10,'concrete',True) # even liter magnet
262# makeProd("muon807",10,'concrete',True) # even liter magnet
263# makeProd("muon808",10,'concrete',True) # even liter magnet
264# makeProd("muon809",10,'concrete',True) # even liter magnet
265# new iteration, and ship_geo.Yheight*1./10.
266# makeProd("muon710",10,'concrete',False) # even liter magnet
267# makeProd("muon711",10,'concrete',True) # even liter magnet
268# makeProd("muon712",10,'concrete',True) # even liter magnet
269# makeProd("muon713",10,'concrete',True) # even liter magnet
270# makeProd("muon714",10,'concrete',True) # even liter magnet
271# makeProd("muon715",10,'concrete',True) # even liter magnet
272# makeProd("muon716",10,'concrete',True) # even liter magnet
273# makeProd("muon717",10,'concrete',True) # even liter magnet
274# makeProd("muon718",10,'concrete',True) # even liter magnet
275# makeProd("muon719",10,'concrete',True) # even liter magnet
276# new iteration, and back to ship_geo.Yheight*2./10.
277# makeProd("muon720",10,'concrete',False) # even liter magnet
278# makeProd("muon721",10,'concrete',True) # even liter magnet
279# makeProd("muon722",10,'concrete',True) # even liter magnet
280# makeProd("muon723",10,'concrete',True) # even liter magnet
281# makeProd("muon724",10,'concrete',True) # even liter magnet
282# makeProd("muon725",10,'concrete',True) # even liter magnet
283# makeProd("muon726",10,'concrete',True) # even liter magnet
284# makeProd("muon727",10,'concrete',True) # even liter magnet
285# makeProd("muon728",10,'concrete',True) # even liter magnet
286# makeProd("muon729",10,'concrete',True) # even liter magnet
287# new iteration, and back to ship_geo.Yheight*2./10. but with more info in vetoPoint
288# makeProd("muon730",10,'concrete',False) # even liter magnet
289# makeProd("muon740",10,'concrete',False) # even liter magnet
290# new iteration, ship_geo.Yheight*1./10.
291# makeProd("muon750",10,'concrete',False) #
292# new iteration, ship_geo.Yheight*1.5/10.
293# makeProd("muon760",10,'concrete',False) #
294# makeProd("muon761",10,'concrete',True) #
295# as before but now with full simulation
296# makeProd("muon1710",10,False,False)
297# makeProd("muon1720",10,True,False)
298# makeProd("muon1711",10,False,True)
299# makeProd("muon1721",10,True,True)
300# makeProd("muon1712",10,False,True)
301# makeProd("muon1722",10,True,True)
302# makeProd("muon1713",10,False,True)
303# makeProd("muon1723",10,True,True)
304# makeProd("muon1714",10,False,True)
305# makeProd("muon1724",10,True,True)
306# makeProd("muon1715",10,False,True)
307# makeProd("muon1725",10,True,True)
308# makeProd("muon1716",10,False,True)
309# makeProd("muon1726",10,True,True)
310# another one, hopefully better
311# makeProd("muon1717",10,'concrete',False) #
312# another one, increasing height to 3m
313# makeProd("muon1718",10,'concrete',False) #
314
315prefixes = []
316withChain = 0
317pref = "muon"
318xx = os.path.abspath(".").lower()
319if not xx.find("neutrino") < 0:
320 pref = "neutrino"
321if not xx.find("vdis") < 0:
322 pref = "disV"
323elif not xx.find("clby") < 0:
324 pref = "disCLBY"
325elif not xx.find("dis") < 0:
326 pref = "dis"
327
328if len(os.sys.argv) > 1:
329 for i in range(1, len(os.sys.argv)):
330 for prefix in os.sys.argv[i].split(","):
331 if prefix.find(pref) < 0:
332 prefix = pref + prefix
333 prefixes.append(prefix)
334 withChain += 1
335else:
336 prefixes = [""]
337
338testdir = "."
339path = ""
340# if local: path = "/media/Data/HNL/muonBackground/"
341if prefixes[0] != "":
342 testdir = path + prefixes[0] + "1"
343# figure out which setup
344for f in os.listdir(testdir):
345 if not f.find("geofile_full") < 0:
346 fgeo = ROOT.TFile(testdir + "/" + f)
347 sGeo = fgeo.Get("FAIRGeom")
348 inputFile = f.replace("geofile_full", "ship")
349 break
350# try to extract from input file name
351tmp = inputFile.split(".")
352try:
353 dy = float(tmp[1] + "." + tmp[2])
354except Exception:
355 dy = 10.0
356
357if not inputFile.find("_D.") < 0:
358 inputFile1 = inputFile.replace("_D.", ".")
359 inputFile2 = inputFile
360else:
361 inputFile1 = inputFile
362 inputFile2 = inputFile.replace(".root", "_D.root")
363
364import rootUtils as ut
365import shipunit as u
366
367PDG = ROOT.TDatabasePDG.Instance()
368import geometry_config
369
370# init geometry and mag. field
371if not fgeo.FindKey("ShipGeo"):
372 # old geofile, missing Shipgeo dictionary
373 # re-create geometry and mag. field
374 ShipGeo = geometry_config.create_config(Yheight=dy)
375else:
376 # new geofile, load Shipgeo dictionary written by run_simScript.py
377 ShipGeo = load_from_root_file(fgeo, "ShipGeo")
378
379# -----Create geometry----------------------------------------------
380import shipDet_conf
381
382run = ROOT.FairRunSim()
383modules = shipDet_conf.configure(run, ShipGeo)
384
385
386rz_inter = -1.0, 0.0
387
388
389def origin(sTree, it) -> None:
390 at = sTree.MCTrack[it]
391 im = at.GetMotherId()
392 if im > 0:
393 origin(sTree, im)
394 if im < 0:
395 # print 'does not come from muon'
396 pass
397 if im == 0:
398 # print 'origin z',at.GetStartZ()
399 ROOT.TMath.Sqrt(at.GetStartX() ** 2 + at.GetStartY() ** 2), at.GetStartZ()
400
401
402otherPhysList = False
403noField = False
404passive = False
405#
406top = sGeo.GetTopVolume()
407muon = top.GetNode("MuonDetector_1")
408mvol = muon.GetVolume()
409zmuon = muon.GetMatrix().GetTranslation()[2]
410totl = (zmuon + mvol.GetShape().GetDZ()) / u.m
411ztarget = -100.0
412
413fchain = []
414fchainRec = []
415# first time trying to read a chain of Fairship files, doesn't seem to work out of the box, try some tricks.
416testdir = "."
417if path != "":
418 testdir = path
419if withChain > 0:
420 for prefix in prefixes:
421 for i in range(1, 10):
422 if prefix + str(i) not in os.listdir(testdir):
423 continue
424 q1 = inputFile1 in os.listdir(path + prefix + str(i))
425 q2 = inputFile2 in os.listdir(path + prefix + str(i))
426 recFile1 = inputFile1.replace(".root", "_rec.root")
427 recFile2 = inputFile2.replace(".root", "_rec.root")
428 r1 = recFile1 in os.listdir(path + prefix + str(i))
429 r2 = recFile2 in os.listdir(path + prefix + str(i))
430 if q1 or r1:
431 inputFile = inputFile1
432 elif q2 or r2:
433 inputFile = inputFile2
434 else:
435 continue
436 fname = path + prefix + str(i) + "/" + inputFile
437 recFile = inputFile.replace(".root", "_rec.root")
438 if recFile not in os.listdir(path + prefix + str(i)):
439 fchain.append(fname)
440 continue
441 fname = path + prefix + str(i) + "/" + recFile
442 fchainRec.append(fname)
443 fchain.append(fname) # take rec file if exist
444else:
445 fchain.append(inputFile)
446 prefix = ""
447
448
449def makeProd() -> None:
450 ntot = 736406
451 ncpu = 4
452 n3 = int(ntot / ncpu)
453 cmd = "python $FAIRSHIP/macro/run_simScript.py --MuonBack -f $SHIPSOFT/data/pythia8_Geant4_onlyMuons.root " # --display"
454 ns = 0
455 prefix = "muon18"
456 for i in range(1, ncpu + 1):
457 d = prefix + str(i)
458 if d not in os.listdir("."):
459 os.system("mkdir " + d)
460 os.chdir("./" + prefix + "1")
461 for i in range(1, ncpu + 1):
462 if i == ncpu:
463 n3 = ntot - i * n3
464 os.system("cp $FAIRSHIP/macro/run_simScript.py .")
465 os.system(cmd + " -n " + str(n3) + " -i " + str(ns) + " > log &")
466 # print " -n "+str(n3)+" -i "+str(ns)
467 ns += n3
468 if i == ncpu:
469 break
470 os.chdir("../" + prefix + str(i + 1))
471
472
473def detMap():
474 sGeo = ROOT.gGeoManager
475 detList = {}
476 for v in sGeo.GetListOfVolumes():
477 nm = v.GetName()
478 i = sGeo.FindVolumeFast(nm).GetNumber()
479 detList[i] = nm
480 return detList
481
482
483def fitSingleGauss(x, ba=None, be=None) -> None:
484 name = "myGauss_" + x
485 myGauss = h[x].GetListOfFunctions().FindObject(name)
486 if not myGauss:
487 if not ba:
488 ba = h[x].GetBinCenter(1)
489 if not be:
490 be = h[x].GetBinCenter(h[x].GetNbinsX())
491 bw = h[x].GetBinWidth(1)
492 mean = h[x].GetMean()
493 sigma = h[x].GetRMS()
494 norm = h[x].GetEntries() * 0.3
495 myGauss = ROOT.TF1(name, "[0]*" + str(bw) + "/([2]*sqrt(2*pi))*exp(-0.5*((x-[1])/[2])**2)+[3]", 4)
496 myGauss.SetParameter(0, norm)
497 myGauss.SetParameter(1, mean)
498 myGauss.SetParameter(2, sigma)
499 myGauss.SetParameter(3, 1.0)
500 myGauss.SetParName(0, "Signal")
501 myGauss.SetParName(1, "Mean")
502 myGauss.SetParName(2, "Sigma")
503 h[x].Fit(myGauss, "", "", ba, be)
504
505
506h = {}
507histlist = {}
508txt = {}
509labels = {}
510logVols = detMap()
511
512
513def bookHist(detName) -> None:
514 for mu in ["", "_mu", "_muV0"]:
515 tag = detName + mu
516 if detName.find("LS") < 0:
517 ut.bookHist(h, tag, "x/y " + detName, 100, -3.0, 3.0, 100, -6.0, 6.0)
518 else:
519 ut.bookHist(h, tag, "z phi " + detName, 100, -50.0, 50.0, 100, -1.0, 1.0)
520 ut.bookHist(h, tag + "_E", "deposited energy MeV " + detName, 100, 0.0, 2.0)
521 ut.bookHist(h, tag + "_P", "particle mom GeV " + detName, 500, 0.0, 50.0)
522 ut.bookHist(h, tag + "_LP", "particle mom GeV " + detName, 100, 0.0, 1.0)
523 ut.bookHist(h, tag + "_OP", "original particle mom GeV " + detName, 400, 0.0, 400.0)
524 ut.bookHist(h, tag + "_id", "particle id " + detName, 5001, -2499.5, 2499.5)
525 ut.bookHist(h, tag + "_mul", "multiplicity of hits/tracks " + detName, 100, -0.5, 99.5)
526 ut.bookHist(h, tag + "_evmul", "multiplicity of hits/event " + detName, 100, -0.5, 9999.5)
527 ut.bookHist(h, tag + "_origin", "r vs z", 100, ztarget, totl, 100, 0.0, 12.0)
528 ut.bookHist(h, tag + "_originmu", "r vs z", 100, ztarget, totl, 100, 0.0, 12.0)
529
530
531ut.bookHist(h, "origin", "r vs z", 100, ztarget, totl, 100, 0.0, 15.0)
532ut.bookHist(h, "borigin", "r vs z", 100, ztarget, totl, 500, 0.0, 30.0)
533ut.bookHist(h, "porigin", "r vs z secondary", 100, ztarget, totl, 500, 0.0, 30.0)
534ut.bookHist(h, "mu-inter", "r vs z", 100, ztarget, totl, 50, 0.0, 3.0)
535ut.bookHist(h, "muonP", "muon momentum", 100, 0.0, 400.0)
536ut.bookHist(h, "weight", "muon weight", 1000, 1.0e3, 1.0e6)
537ut.bookHist(h, "delx13", "x diff first and last point, mu-", 100, -10.0, 10.0)
538ut.bookHist(h, "delx-13", "x diff first and last point, mu+", 100, -10.0, 10.0)
539ut.bookHist(h, "deltaElec", "energy of delta electrons", 100, 0.0, 10.0)
540ut.bookHist(h, "secondaries", "energy of delta electrons", 100, 0.0, 10.0)
541ut.bookHist(h, "prop_deltaElec", "energy of delta elec / muon energy", 100, 0.0, 1.0)
542ut.bookHist(h, "dummy", "", 10, 0.0, 1.0)
543ut.bookHist(h, "dE", "", 100, 0.0, 10.0, 100, 0.0, 10.0)
544h["dummy"].SetMaximum(10.0)
545
546histlistAll = {
547 1: "strawstation_5",
548 2: "strawstation_1",
549 3: "strawstation_4",
550 4: "Ecal",
551 5: "muondet",
552 6: "VetoTimeDet",
553 7: "T1LiSc",
554 8: "T2LiSc",
555 9: "T3LiSc",
556 10: "T5LiSc",
557 11: "ShipRpc",
558 12: "volHPT",
559 13: "Target",
560 14: "TimeDet",
561 15: "Det2",
562}
563hLiSc = {1: {}}
564for i in range(1, 7):
565 hLiSc[1][i] = "T1LiSc_" + str(i)
566hLiSc[2] = {}
567for i in range(1, 48):
568 hLiSc[2][i] = "T2LiSc_" + str(i)
569hLiSc[3] = {}
570for i in range(1, 3):
571 hLiSc[3][i] = "T3LiSc_" + str(i)
572hLiSc[5] = {}
573for i in range(1, 3):
574 hLiSc[5][i] = "T5LiSc_" + str(i)
575hMuon = {}
576for i in range(0, 4):
577 hMuon[i] = "muondet" + str(i)
578
579
580# start event loop
581mom = ROOT.TVector3()
582pos = ROOT.TVector3()
583
584
585def BigEventLoop() -> None:
586 pid = 1
587 for fn in fchain:
588 if os.path.islink(fn):
589 rfn = os.path.realpath(fn).split("eos")[1]
590 fn = ROOT.gSystem.Getenv("EOSSHIP") + "/eos/" + rfn
591 elif not os.path.isfile(fn):
592 raise RuntimeError("Don't know what to do with " + fn)
593 if parallel:
594 # process files parallel instead of sequential
595 processes.append(mp.Process(target=executeOneFile, args=(fn, output, pid)))
596 pid += 1
597 else:
598 processes.append(fn)
599 # Run processes
600 n = 0
601 for p in processes:
602 if parallel:
603 p.start()
604 n += 1
605 else:
607 if parallel:
608 # Exit the completed processes
609 for p in processes:
610 p.join()
611 # clean histos before reading in the new ones
612 for x in h:
613 h[x].Reset()
614 print("now, collect the output")
615 pid = 1
616 for p in processes:
617 ut.readHists(h, "tmpHists_" + str(pid) + ".root")
618 pid += 1
619 # compactify liquid scintillator
620 for mu in ["", "_mu", "_muV0"]:
621 for x in ["", "_E", "_P", "_LP", "_OP", "_id", "_mul", "_evmul", "_origin", "_originmu"]:
622 for k in [1, 2, 3, 5]:
623 first = True
624 for j in hLiSc[k]:
625 detName = hLiSc[k][j]
626 tag = detName + mu + x
627 newh = detName[0:2] + "LiSc" + mu + x
628 if tag not in h:
629 continue
630 if first:
631 h[newh] = h[tag].Clone(newh)
632 h[newh].SetTitle(h[tag].GetTitle().split("_")[0])
633 first = False
634 else:
635 h[newh].Add(h[tag])
636 # compactify muon stations
637 for mu in ["", "_mu", "_muV0"]:
638 for x in ["", "_E", "_P", "_LP", "_OP", "_id", "_mul", "_evmul", "_origin", "_originmu"]:
639 first = True
640 for j in hMuon:
641 detName = hMuon[j]
642 tag = detName + mu + x
643 newh = "muondet" + mu + x
644 if first:
645 h[newh] = h[tag].Clone(newh)
646 h[newh].SetTitle(h[tag].GetTitle().split(" ")[0] + " " + newh)
647 first = False
648 else:
649 h[newh].Add(h[tag])
650
651 # make list of hists with entries
652 k = 1
653 for x in histlistAll:
654 if histlistAll[x] in h:
655 histlist[k] = histlistAll[x]
656 # make cumulative histograms
657 for c in ["", "_E", "_P", "_LP", "_OP", "_id", "_mul", "_evmul", "_origin", "_originmu"]:
658 h[histlist[k] + "_mu" + c].Add(h[histlist[k] + "_muV0" + c])
659 h[histlist[k] + c].Add(h[histlist[k] + "_mu" + c])
660 h[histlist[k] + c].SetMinimum(0.0)
661 h[histlist[k] + "_mu" + c].SetMinimum(0.0)
662 h[histlist[k] + "_muV0" + c].SetMinimum(0.0)
663 k += 1
664 nstations = len(histlist)
665 makePlots(nstations)
666
667
668def executeOneFile(fn, output=None, pid=None) -> None:
669 f = ROOT.TFile.Open(fn)
670 sTree = f.Get("cbmsim")
671 nEvents = sTree.GetEntries()
672 if sTree.GetBranch("GeoTracks"):
673 sTree.SetBranchStatus("GeoTracks", 0)
674 sTree.GetEntry(0)
675 hitContainers = [
676 sTree.vetoPoint,
677 sTree.muonPoint,
678 sTree.EcalPointLite,
679 sTree.strawtubesPoint,
680 sTree.ShipRpcPoint,
681 sTree.TargetPoint,
682 ]
683 ntot = 0
684 for n in range(nEvents):
685 sTree.GetEntry(n)
686 theMuon = sTree.MCTrack[0]
687 if len(sTree.MCTrack) > 1:
688 w = sTree.MCTrack[1].GetWeight() # also works for neutrinos
689 else:
690 print("should not happen with new files", n, fn)
691 w = sTree.MCTrack[0].GetWeight() # also works for neutrinos
692 if w == 0:
693 w = 1.0
694 h["weight"].Fill(w)
695 h["muonP"].Fill(theMuon.GetP() / u.GeV, w)
696 ntot += 1
697 if ntot % 10000 == 0:
698 print("read event", f.GetName(), n)
699 hitmult = {}
700 esum = 0
701 for mcp in sTree.MCTrack:
702 if mcp.GetMotherId() == 0: # mother is original muon
703 E = mcp.GetEnergy()
704 if mcp.GetPdgCode() == 11:
705 h["deltaElec"].Fill(E, w)
706 esum += E
707 h["secondaries"].Fill(E, w)
708 h["prop_deltaElec"].Fill(
709 esum / sTree.MCTrack[0].GetP(), w
710 ) # until energy is really made persistent GetEnergy()
711 for c in hitContainers:
712 for ahit in c:
713 if not ahit.GetEnergyLoss() > 0:
714 continue
715 detID = ahit.GetDetectorID()
716 if ahit.GetName() == "strawtubesPoint":
717 detName = "strawstation_" + str(ahit.GetStationNumber())
718 x = ahit.GetX()
719 y = ahit.GetY()
720 E = ahit.GetEnergyLoss()
721 else:
722 if detID not in logVols:
723 detName = c.GetName().replace("Points", "")
724 if detName not in histlistAll.values():
725 print(detID, detName, c.GetName())
726 else:
727 detName = logVols[detID]
728 x = ahit.GetX()
729 y = ahit.GetY()
730 ahit.GetZ()
731 E = ahit.GetEnergyLoss()
732 if detName not in h:
733 bookHist(detName)
734 mu = ""
735 pdgID = -2
736 if "PdgCode" in dir(ahit):
737 pdgID = ahit.PdgCode()
738 trackID = ahit.GetTrackID()
739 phit = -100.0
740 mom = ROOT.TVector3()
741 if not trackID < 0:
742 aTrack = sTree.MCTrack[trackID]
743 pdgID = aTrack.GetPdgCode()
744 aTrack.GetMomentum(mom) # ! this is not momentum of particle at Calorimeter place
745 phit = mom.Mag() / u.GeV
746 if abs(pdgID) == 13:
747 mu = "_mu"
748 if phit > 3 and abs(pdgID) == 13:
749 mu = "_muV0"
750 detName = detName + mu
751 if detName.find("LS") < 0:
752 h[detName].Fill(x / u.m, y / u.m, w)
753 else:
754 h[detName].Fill(ahit.GetZ() / u.m, ROOT.TMath.ATan2(y, x) / ROOT.TMath.Pi(), w)
755 h[detName + "_E"].Fill(E / u.MeV, w)
756 if detName not in hitmult:
757 hitmult[detName] = {-1: 0}
758 if trackID not in hitmult[detName]:
759 hitmult[detName][trackID] = 0
760 hitmult[detName][trackID] += 1
761 hitmult[detName][-1] += 1
762 h[detName + "_id"].Fill(pdgID, w)
763 h[detName + "_P"].Fill(phit, w)
764 h[detName + "_LP"].Fill(phit, w)
765 if not trackID < 0:
766 r = ROOT.TMath.Sqrt(aTrack.GetStartX() ** 2 + aTrack.GetStartY() ** 2) / u.m
767 h["origin"].Fill(aTrack.GetStartZ() / u.m, r, w)
768 h[detName + "_origin"].Fill(aTrack.GetStartZ() / u.m, r, w)
769 if abs(pdgID) == 13:
770 h[detName + "_originmu"].Fill(aTrack.GetStartZ() / u.m, r, w)
771 h["borigin"].Fill(aTrack.GetStartZ() / u.m, r, w)
772 aTrack.GetMomentum(mom)
773 h[detName + "_OP"].Fill(mom.Mag() / u.GeV, w)
774 if trackID > 0:
775 origin(sTree, trackID)
776 h["porigin"].Fill(
777 aTrack.GetStartZ() / u.m,
778 ROOT.TMath.Sqrt(aTrack.GetStartX() ** 2 + aTrack.GetStartY() ** 2) / u.m,
779 w,
780 )
781 h["mu-inter"].Fill(rz_inter[1] / u.m, rz_inter[0] / u.m, w)
782 for detName in hitmult:
783 h[detName + "_evmul"].Fill(hitmult[detName][-1], w)
784 for tr in hitmult[detName]:
785 h[detName + "_mul"].Fill(hitmult[detName][tr], w)
786 if output:
787 ut.writeHists(h, "tmpHists_" + str(pid) + ".root")
788 output.put("ok")
789 f.Close()
790
791
792#
793def makePlots(nstations: int) -> None:
794 cxcy = {
795 1: [2, 1],
796 2: [3, 1],
797 3: [2, 2],
798 4: [3, 2],
799 5: [3, 2],
800 6: [3, 2],
801 7: [3, 3],
802 8: [3, 3],
803 9: [3, 3],
804 10: [4, 3],
805 11: [4, 3],
806 12: [4, 3],
807 13: [5, 3],
808 14: [5, 3],
809 15: [5, 3],
810 }
811 ut.bookCanvas(
812 h,
813 key="ResultsI",
814 title="hit occupancies",
815 nx=1100,
816 ny=600 * cxcy[nstations][1],
817 cx=cxcy[nstations][0],
818 cy=cxcy[nstations][1],
819 )
820 ut.bookCanvas(
821 h,
822 key="ResultsImu",
823 title="hit occupancies",
824 nx=1100,
825 ny=600 * cxcy[nstations][1],
826 cx=cxcy[nstations][0],
827 cy=cxcy[nstations][1],
828 )
829 ut.bookCanvas(
830 h,
831 key="ResultsImuV0",
832 title="hit occupancies",
833 nx=1100,
834 ny=600 * cxcy[nstations][1],
835 cx=cxcy[nstations][0],
836 cy=cxcy[nstations][1],
837 )
838 ut.bookCanvas(
839 h,
840 key="ResultsII",
841 title="deposited energies",
842 nx=1100,
843 ny=600 * cxcy[nstations][1],
844 cx=cxcy[nstations][0],
845 cy=cxcy[nstations][1],
846 )
847 ut.bookCanvas(
848 h,
849 key="ResultsIII",
850 title="track info",
851 nx=1100,
852 ny=600 * cxcy[nstations][1],
853 cx=cxcy[nstations][0],
854 cy=cxcy[nstations][1],
855 )
856 ut.bookCanvas(
857 h,
858 key="ResultsIV",
859 title="track info",
860 nx=1100,
861 ny=600 * cxcy[nstations][1],
862 cx=cxcy[nstations][0],
863 cy=cxcy[nstations][1],
864 )
865 ut.bookCanvas(h, key="ResultsV", title="origin info", nx=600, ny=400, cx=1, cy=1)
866 txt[0] = "occupancy 1sec 5E13pot "
867 h["dummy"].Fill(-1)
868 nSpills = len(prefixes)
869 for i in histlist:
870 tc = h["ResultsI"].cd(i)
871 hn = histlist[i]
872 if hn not in h:
873 continue
874 h[hn].SetStats(0)
875 h[hn].Draw("colz")
876 txt[i] = "%5.2G" % (h[hn].GetSumOfWeights() / nSpills)
877 labels[i] = ROOT.TLatex().DrawLatexNDC(0.15, 0.85, txt[i])
878 #
879 hn = histlist[i] + "_mu"
880 tc = h["ResultsImu"].cd(i)
881 h[hn].SetStats(0)
882 h[hn].Draw("colz")
883 txt[i + 100] = "%5.2G" % (h[hn].GetSumOfWeights() / nSpills)
884 labels[i + 100] = ROOT.TLatex().DrawLatexNDC(0.15, 0.85, txt[i + 100])
885 #
886 hn = histlist[i] + "_muV0"
887 tc = h["ResultsImuV0"].cd(i)
888 h[hn].SetStats(0)
889 h[hn].Draw("colz")
890 txt[i + 200] = "%5.2G" % (h[hn].GetSumOfWeights() / nSpills)
891 labels[i + 200] = ROOT.TLatex().DrawLatexNDC(0.15, 0.85, txt[i + 200])
892 #
893 for i in histlist:
894 tc = h["ResultsII"].cd(i)
895 h[histlist[i] + "_E"].Draw("colz")
896 #
897 for i in histlist:
898 tc = h["ResultsIII"].cd(i)
899 tc.SetLogy(1)
900 hn = histlist[i]
901 drawBoth("_P", hn)
902 hid = h[hn + "_id"]
903 print("particle statistics for " + histlist[i])
904 for k in range(hid.GetNbinsX()):
905 ncont = hid.GetBinContent(k + 1)
906 pid = hid.GetBinCenter(k + 1)
907 if ncont > 0:
908 temp = int(abs(pid) + 0.5) * int(pid / abs(pid))
909 nm = PDG.GetParticle(temp).GetName()
910 print(f"{nm} :{ncont:5.2g}")
911 hid = h[histlist[i] + "_mu_id"]
912 for k in range(hid.GetNbinsX()):
913 ncont = hid.GetBinContent(k + 1)
914 pid = hid.GetBinCenter(k + 1)
915 if ncont > 0:
916 temp = int(abs(pid) + 0.5) * int(pid / abs(pid))
917 nm = PDG.GetParticle(temp).GetName()
918 print(f"{nm} :{ncont:5.2g}")
919 #
920 tc = h["ResultsV"].cd(1)
921 h["origin"].SetStats(0)
922 h["origin"].Draw("colz")
923 #
924 for i in histlist:
925 tc = h["ResultsIV"].cd(i)
926 tc.SetLogy(1)
927 hn = histlist[i]
928 drawBoth("_OP", hn)
930
931
932#
933def AnaEventLoop() -> None:
934 fout = open("rareEvents.txt", "w") # noqa: SIM115
935 for fn in fchainRec:
936 f = ROOT.TFile(fn)
937 if not f.FindObjectAny("cbmsim"):
938 print("skip file ", f.GetName())
939 continue
940 sTree = f.Get("cbmsim")
941 sTree.GetEvent(0)
942 if sTree.GetBranch("GeoTracks"):
943 sTree.SetBranchStatus("GeoTracks", 0)
944 nEvents = sTree.GetEntries()
945 for n in range(nEvents):
946 sTree.GetEntry(n)
947 if n == 0:
948 print("now at event ", n, f.GetName())
949 if len(sTree.MCTrack) > 1:
950 wg = sTree.MCTrack[1].GetWeight() # also works for neutrinos
951 else:
952 wg = sTree.MCTrack[0].GetWeight() # also works for neutrinos
953 i = -1
954 for atrack in sTree.FitTracks:
955 i += 1
956 fitStatus = atrack.getFitStatus()
957 if not fitStatus.isFitConverged():
958 continue
959 nmeas = atrack.getNumPoints()
960 chi2 = fitStatus.getChi2() / nmeas
961 fittedState = atrack.getFittedState()
962 P = fittedState.getMomMag()
963 fout.write("rare event with track %i, %s, %8.2F \n" % (n, f.GetName(), wg))
964 originOfMuon(fout, n, f.GetName(), nEvents)
965 fout.write("reco %i,%5.3F,%8.2F \n" % (nmeas, chi2, P))
966 mcPartKey = sTree.fitTrack2MC[i]
967 mcPart = sTree.MCTrack[mcPartKey]
968 for ahit in sTree.strawtubesPoint:
969 if ahit.GetTrackID() == mcPartKey:
970 fout.write(
971 "P when making hit %i, %8.2F \n"
972 % (
973 ahit.PdgCode(),
974 ROOT.TMath.Sqrt(ahit.GetPx() ** 2 + ahit.GetPy() ** 2 + ahit.GetPz() ** 2) / u.GeV,
975 )
976 )
977 break
978 if not mcPart:
979 continue
980 Ptruth = mcPart.GetP()
981 fout.write("Ptruth %i %8.2F \n" % (mcPart.GetPdgCode(), Ptruth / u.GeV))
982
983
984#
985def muDISntuple(fn) -> None:
986 # take as input the rare events
987 fout = ROOT.TFile("muDISVetoCounter.root", "recreate")
988 h["ntuple"] = ROOT.TNtuple("muons", "muon flux VetoCounter", "id:px:py:pz:x:y:z:w")
989 f = ROOT.TFile(fn)
990 sTree = f.Get("cbmsim")
991 nEvents = sTree.GetEntries()
992 for n in range(nEvents):
993 sTree.GetEntry(n)
994 if len(sTree.MCTrack) > 1:
995 wg = sTree.MCTrack[1].GetWeight()
996 else:
997 wg = sTree.MCTrack[0].GetWeight()
998 for ahit in sTree.vetoPoint:
999 detID = ahit.GetDetectorID()
1000 if logVols[detID] != "VetoTimeDet":
1001 continue
1002 pid = ahit.PdgCode()
1003 if abs(pid) != 13:
1004 continue
1005 P = ROOT.TMath.Sqrt(ahit.GetPx() ** 2 + ahit.GetPy() ** 2 + ahit.GetPz() ** 2)
1006 if 3 / u.GeV < P:
1007 h["ntuple"].Fill(
1008 float(pid),
1009 float(ahit.GetPx() / u.GeV),
1010 float(ahit.GetPy() / u.GeV),
1011 float(ahit.GetPz() / u.GeV),
1012 float(ahit.GetX() / u.m),
1013 float(ahit.GetY() / u.m),
1014 float(ahit.GetZ() / u.m),
1015 float(wg),
1016 )
1017 fout.cd()
1018 h["ntuple"].Write()
1019
1020
1021def analyzeConcrete() -> None:
1022 h["fout"] = ROOT.TFile("muConcrete.root", "recreate")
1023 h["ntuple"] = ROOT.TNtuple("muons", "muon flux concrete", "id:px:py:pz:x:y:z:w")
1024 for m in ["", "mu", "V0"]:
1025 ut.bookHist(h, "conc_hitz" + m, "concrete hit z " + m, 100, -100.0, 100.0)
1026 ut.bookHist(h, "conc_hitzP" + m, "concrete hit z vs P" + m, 100, -100.0, 100.0, 100, 0.0, 25.0)
1027 ut.bookHist(h, "conc_hity" + m, "concrete hit y " + m, 100, -15.0, 15.0)
1028 ut.bookHist(h, "conc_p" + m, "concrete hit p " + m, 1000, 0.0, 400.0)
1029 ut.bookHist(h, "conc_pt" + m, "concrete hit pt " + m, 100, 0.0, 20.0)
1030 ut.bookHist(h, "conc_hitzy" + m, "concrete hit zy " + m, 100, -100.0, 100.0, 100, -15.0, 15.0)
1031 top = sGeo.GetTopVolume()
1032 magn = top.GetNode("magyoke_1")
1033 z0 = magn.GetMatrix().GetTranslation()[2] / u.m
1034 for fn in fchain:
1035 f = ROOT.TFile(fn)
1036 if not f.FindObjectAny("cbmsim"):
1037 print("skip file ", f.GetName())
1038 continue
1039 sTree = f.Get("cbmsim")
1040 nEvents = sTree.GetEntries()
1041 ROOT.gROOT.cd()
1042 for n in range(nEvents):
1043 sTree.GetEntry(n)
1044 if len(sTree.MCTrack) > 1:
1045 wg = sTree.MCTrack[1].GetWeight()
1046 else:
1047 wg = sTree.MCTrack[0].GetWeight()
1048 for ahit in sTree.vetoPoint:
1049 detID = ahit.GetDetectorID()
1050 if logVols[detID] != "rockD":
1051 continue
1052 m = ""
1053 pid = ahit.PdgCode()
1054 if abs(pid) == 13:
1055 m = "mu"
1056 P = ROOT.TMath.Sqrt(ahit.GetPx() ** 2 + ahit.GetPy() ** 2 + ahit.GetPz() ** 2)
1057 if abs(pid) == 13 and 3 / u.GeV < P:
1058 m = "V0"
1059 h["ntuple"].Fill(
1060 float(pid),
1061 float(ahit.GetPx() / u.GeV),
1062 float(ahit.GetPy() / u.GeV),
1063 float(ahit.GetPz() / u.GeV),
1064 float(ahit.GetX() / u.m),
1065 float(ahit.GetY() / u.m),
1066 float(ahit.GetZ() / u.m),
1067 float(wg),
1068 )
1069 h["conc_hitz" + m].Fill(ahit.GetZ() / u.m - z0, wg)
1070 h["conc_hity" + m].Fill(ahit.GetY() / u.m, wg)
1071 h["conc_p" + m].Fill(P / u.GeV, wg)
1072 h["conc_hitzP" + m].Fill(ahit.GetZ() / u.m, P / u.GeV, wg)
1073 Pt = ROOT.TMath.Sqrt(ahit.GetPx() ** 2 + ahit.GetPy() ** 2)
1074 h["conc_pt" + m].Fill(Pt / u.GeV, wg)
1075 h["conc_hitzy" + m].Fill(ahit.GetZ() / u.m - z0, ahit.GetY() / u.m, wg)
1076 #
1077 # start = [ahit.GetX()/u.m,ahit.GetY()/u.m,ahit.GetZ()/u.m]
1078 # direc = [-ahit.GetPx()/P,-ahit.GetPy()/P,-ahit.GetPz()/P]
1079 # t = - start[0]/direc[0]
1080
1081 ut.bookCanvas(h, key="ResultsV0", title="muons hitting concrete, p>3GeV", nx=1000, ny=600, cx=2, cy=2)
1082 ut.bookCanvas(h, key="Resultsmu", title="muons hitting concrete", nx=1000, ny=600, cx=2, cy=2)
1083 ut.bookCanvas(h, key="Results", title="hitting concrete", nx=1000, ny=600, cx=2, cy=2)
1084 for m in ["", "mu", "V0"]:
1085 tc = h["Results" + m].cd(1)
1086 h["conc_hity" + m].Draw()
1087 tc = h["Results" + m].cd(2)
1088 h["conc_hitz" + m].Draw()
1089 tc = h["Results" + m].cd(3)
1090 tc.SetLogy(1)
1091 h["conc_pt" + m].Draw()
1092 tc = h["Results" + m].cd(4)
1093 tc.SetLogy(1)
1094 h["conc_p" + m].Draw()
1095 h["fout"].cd()
1096 h["ntuple"].Write()
1097
1098
1099def rareEventEmulsion(fname: str = "rareEmulsion.txt") -> None:
1100 fout = open(fname, "w") # noqa: SIM115
1101 for fn in fchainRec:
1102 f = ROOT.TFile(fn)
1103 if not f.FindObjectAny("cbmsim"):
1104 print("skip file ", f.GetName())
1105 continue
1106 sTree = f.Get("cbmsim")
1107 sTree.GetEvent(0)
1108 if sTree.GetBranch("GeoTracks"):
1109 sTree.SetBranchStatus("GeoTracks", 0)
1110 nEvents = sTree.GetEntries()
1111 for n in range(nEvents):
1112 sTree.GetEntry(n)
1113 if n == 0:
1114 print("now at event ", n, f.GetName())
1115 for ahit in sTree.vetoPoint:
1116 detID = ahit.GetDetectorID()
1117 if logVols[detID] != "Emulsion":
1118 continue
1119 ahit.GetX()
1120 ahit.GetY()
1121 ahit.GetZ()
1122 if len(sTree.MCTrack) > 1:
1123 wg = sTree.MCTrack[1].GetWeight() # also works for neutrinos
1124 else:
1125 wg = sTree.MCTrack[0].GetWeight() # also works for neutrinos
1126 fout.write("rare emulsion hit %i, %s, %8.3F, %i \n" % (n, f.GetName(), wg, ahit.PdgCode()))
1127 if ahit.GetPz() / u.GeV > 1.0:
1128 fout.write(
1129 "V,P when making hit %8.3F,%8.3F,%8.3F %8.3F,%8.3F,%8.3F (GeV) \n"
1130 % (
1131 ahit.GetX() / u.m,
1132 ahit.GetY() / u.m,
1133 ahit.GetZ() / u.m,
1134 ahit.GetPx() / u.GeV,
1135 ahit.GetPy() / u.GeV,
1136 ahit.GetPz() / u.GeV,
1137 )
1138 )
1139 else:
1140 fout.write(
1141 "V,P when making hit %8.3F,%8.3F,%8.3F %8.3F,%8.3F,%8.3F (MeV)\n"
1142 % (
1143 ahit.GetX() / u.m,
1144 ahit.GetY() / u.m,
1145 ahit.GetZ() / u.m,
1146 ahit.GetPx() / u.MeV,
1147 ahit.GetPy() / u.MeV,
1148 ahit.GetPz() / u.MeV,
1149 )
1150 )
1151 originOfMuon(fout, n, f.GetName(), nEvents)
1152
1153
1154#
1155def extractRareEvents(single=None) -> None:
1156 for fn in fchainRec:
1157 if single:
1158 if fn.find(str(single)) < 0:
1159 continue
1160 f = ROOT.TFile(fn)
1161 if not f.FindObjectAny("cbmsim"):
1162 print("skip file ", f.GetName())
1163 continue
1164 sTree = f.Get("cbmsim")
1165 nEvents = sTree.GetEntries()
1166 raref = ROOT.TFile(fn.replace(".root", "_rare.root"), "recreate")
1167 newTree = sTree.CloneTree(0)
1168 for n in range(nEvents):
1169 sTree.GetEntry(n)
1170 if n == 0:
1171 print("now at event ", n, f.GetName())
1172 # count fitted tracks which have converged and nDF>20:
1173 n = 0
1174 for fT in sTree.FitTracks:
1175 fst = fT.getFitStatus()
1176 if not fst.isFitConverged():
1177 continue
1178 if fst.getNdf() < 20:
1179 continue
1180 n += 1
1181 if n > 0:
1182 rc = newTree.Fill()
1183 print("filled newTree", rc)
1184 sTree.Clear()
1185 newTree.AutoSave()
1186 print(" --> events saved:", newTree.GetEntries())
1187 f.Close()
1188 raref.Close()
1189
1190
1191#
1192def extractMuCloseByEvents(single=None) -> None:
1193 mom = ROOT.TVector3()
1194 pos = ROOT.TVector3()
1195 # Goliath magnet has been removed from geometry
1196 goliath_node = top.GetNode("volGoliath_1")
1197 if goliath_node:
1198 golmx = goliath_node.GetMatrix()
1199 zGol = golmx.GetTranslation()[2]
1200 else:
1201 zGol = -9999.0 # No Goliath, accept all z positions
1202 for fn in fchainRec:
1203 if single:
1204 if fn.find(str(single)) < 0:
1205 continue
1206 f = ROOT.TFile(fn)
1207 if not f.FindObjectAny("cbmsim"):
1208 print("skip file ", f.GetName())
1209 continue
1210 sTree = f.Get("cbmsim")
1211 nEvents = sTree.GetEntries()
1212 raref = ROOT.TFile(fn.replace(".root", "_clby.root"), "recreate")
1213 newTree = sTree.CloneTree(0)
1214 for n in range(nEvents):
1215 sTree.GetEntry(n)
1216 if n == 0:
1217 print("now at event ", n, f.GetName())
1218 # look for muons p>3 hitting something
1219 n = 0
1220 for c in [sTree.vetoPoint, sTree.strawtubesPoint, sTree.ShipRpcPoint]:
1221 for ahit in c:
1222 if abs(ahit.PdgCode()) != 13:
1223 continue
1224 ahit.Momentum(mom)
1225 if mom.Mag() < 3.0:
1226 continue
1227 ahit.Position(pos)
1228 if pos.z() < zGol:
1229 continue
1230 n += 1
1231 if n > 0:
1232 newTree.Fill()
1233 # print 'filled newTree',rc
1234 sTree.Clear()
1235 newTree.AutoSave()
1236 print(" --> events saved:", newTree.GetEntries())
1237 f.Close()
1238 raref.Close()
1239
1240
1241#
1242def MergeRareEvents(runs: list[str] | None = None) -> None:
1243 if runs is None:
1244 runs = ["61", "62"]
1245 for prefix in runs:
1246 cmd = "$ROOTSYS/bin/hadd rareEvents_" + prefix + ".root -f "
1247 for fn in fchainRec:
1248 if fn.find("muon" + prefix) < 0:
1249 continue
1250 fr = fn.replace(".root", "_rare.root")
1251 cmd = cmd + " " + fr
1252 os.system(cmd)
1253
1254
1255#
1256def persistency() -> None:
1257 printAndCopy(prefix)
1258 ut.writeHists(h, prefix + ".root", plusCanvas=True)
1259
1260
1261def reDraw(fn) -> None:
1262 if fn.find("root") < 0:
1263 fn = fn + ".root"
1264 if "tc" not in h:
1265 h["tc"] = ROOT.TFile(fn)
1266 for x in ["ResultsI", "ResultsII", "ResultsImu", "ResultsImuV0", "ResultsIII", "ResultsIV", "ResultsV"]:
1267 h[x] = h["tc"].FindObjectAny(x)
1268 h[x].Draw()
1269
1270
1271def printAndCopy(prefix: str | None = None) -> None:
1272 if not prefix:
1273 prefix = (h["tc"].GetName()).replace(".root", "")
1274 for x in ["ResultsI", "ResultsII", "ResultsImu", "ResultsImuV0", "ResultsIII", "ResultsIV", "ResultsV"]:
1275 h[x].Update()
1276 if prefix not in os.listdir("."):
1277 os.mkdir(prefix)
1278 os.chdir(prefix)
1279 h["ResultsI"].Print(prefix + "Back_occ.png")
1280 h["ResultsII"].Print(prefix + "Back_depE.png")
1281 h["ResultsImu"].Print(prefix + "muBack_occ.png")
1282 h["ResultsImuV0"].Print(prefix + "muV0Back_occ.png")
1283 h["ResultsIII"].Print(prefix + "Back_P.png")
1284 h["ResultsIV"].Print(prefix + "Back_OP.png")
1285 h["ResultsV"].Print(prefix + "origin.png")
1286 os.chdir("../")
1287
1288
1289def drawBoth(tag: str, hn) -> None:
1290 n1 = h[hn + "_mu" + tag].GetMaximum()
1291 n2 = h[hn + tag].GetMaximum()
1292 if n1 > n2:
1293 h[hn + tag].SetMaximum(n1)
1294 h[hn + "_mu" + tag].SetLineColor(4)
1295 h[hn + tag].SetLineColor(3)
1296 h[hn + "_mu" + tag].Draw()
1297 h[hn + tag].Draw("same")
1298
1299
1300def debugGeoTracks(sTree) -> None:
1301 for i in range(sTree.GetEntries()):
1302 sTree.GetEntry(i)
1303 n = 0
1304 for gt in sTree.GeoTracks:
1305 print(
1306 i, n, gt.GetFirstPoint()[2], gt.GetLastPoint()[2], gt.GetParticle().GetPdgCode(), gt.GetParticle().P()
1307 )
1308 n += 1
1309
1310
1312 sTree = fchain[i].Get("cbmsim")
1313 mom = ROOT.TVector3()
1314 for i in range(sTree.GetEntries()):
1315 sTree.GetEntry(i)
1316 nS = len(sTree.strawtubesPoint)
1317 if nS > 0:
1318 mu = sTree.MCTrack[0]
1319 mu.GetMomentum(mom)
1320 print(i, nS)
1321 mom.Print()
1322 sp = sTree.strawtubesPoint[(max(0, nS - 3))]
1323 sp.Momentum(mom)
1324 mom.Print()
1325 print("-----------------------")
1326
1327
1329 sTree = fchain[i].Get("cbmsim")
1330 mom = ROOT.TVector3()
1331 for i in range(sTree.GetEntries()):
1332 sTree.GetEntry(i)
1333 np = 0
1334 for vp in sTree.vetoPoint:
1335 detName = logVols[vp.GetDetectorID()]
1336 if detName == "VetoTimeDet":
1337 np += 0 # ??
1338 vp.Momentum(mom)
1339 print(i, detName, vp.PdgCode())
1340 mom.Print()
1341 print("-----------------------")
1342
1343
1344def depEnergy(sTree) -> None:
1345 for n in range(sTree.GetEntries()):
1346 sTree.GetEntry(n)
1347 for ahit in sTree.strawtubesPoint:
1348 dE = ahit.GetEnergyLoss() / u.keV
1349 ahit.Momentum(mom)
1350 pa = PDG.GetParticle(ahit.PdgCode())
1351 mpa = pa.Mass()
1352 E = ROOT.TMath.Sqrt(mom.Mag2() + mpa**2)
1353 ekin = E - mpa
1354 h["dE"].Fill(dE, ekin / u.MeV)
1355 h["dE"].SetXTitle("keV")
1356 h["dE"].SetYTitle("MeV")
1357
1358
1359def originOfMuon(fout: TextIOWrapper, n: int, fn, nEvents) -> None:
1360 # from fn extract Yandex or CERN/cracow
1361 ncpu = 9
1362 x = fn.find("/")
1363 ni = int(fn[x - 1 : x]) - 1
1364 if nEvents < 100000:
1365 fm = "$SHIPSOFT/data/pythia8_Geant4_onlyMuons.root"
1366 else:
1367 fm = "$SHIPSOFT/data/pythia8_Geant4_Yandex_onlyMuons.root"
1368 fmuon = ROOT.TFile(fm)
1369 ntupl = fmuon.Get("pythia8-Geant4")
1370 ntot = ntupl.GetEntries()
1371 n3 = int(ntot / ncpu)
1372 N = n3 * ni + n
1373 ntupl.GetEvent(N)
1374 P = ROOT.TMath.Sqrt(ntupl.pz * ntupl.pz + ntupl.py * ntupl.py + ntupl.px * ntupl.px)
1375 fout.write("original muon %i, %i, %8.2F \n" % (ntupl.parentid, ntupl.pythiaid, P))
1376 fmuon.Close()
1377
1378
1379#
1380# BigEventLoop()
1381# makePlots()
1382# AnaEventLoop()
1383
1384
1385# ShipAna
1386def pers() -> None:
1387 xdisk = "/media/Work/HNL/"
1388 for x in h:
1389 if isinstance(h[x], ROOT.TCanvas):
1390 h[x].Update()
1391 tn = h[x].GetName() + ".png"
1392 h[x].Print(tn)
1393 rpath = os.path.abspath(".").split("/HNL/")[1]
1394 lp = rpath.split("/")
1395 prefix = xdisk
1396 for i in range(len(lp)):
1397 if lp[i] not in os.listdir(prefix):
1398 os.system("mkdir " + prefix + "/" + lp[i])
1399 prefix = prefix + "/" + lp[i]
1400 os.system("cp " + tn + " " + xdisk + rpath)
1401
1402
1403from operator import itemgetter
1404
1405
1406def makeNicePrintout(x: list[str] | None = None):
1407 if x is None:
1408 x = ["rareEvents_61-62.txt", "rareEvents_71-72.txt"]
1409 result = []
1410 cor = 1.0
1411 for fn in x:
1412 with open(fn) as f:
1413 recTrack = None
1414 if fn == "rareEvents_81-102.txt":
1415 cor = 30.0
1416 for lx in f.readlines():
1417 line = lx.replace("\n", "")
1418 if not line.find("rare event") < 0:
1419 if recTrack:
1420 result.append(recTrack)
1421 tmp = line.split(",")
1422 w = tmp[2].replace(" ", "")
1423 ff = tmp[1].split("/")[0].replace(" ", "")
1424 recTrack = {"w": w, "file": ff}
1425 elif not line.find("original") < 0:
1426 tmp = line.split(",")
1427 recTrack["origin"] = tmp[0].split(" ")[2]
1428 recTrack["pytiaid"] = tmp[1].replace(" ", "")
1429 recTrack["o-mom"] = tmp[2].replace(" ", "")
1430 elif not line.find("reco ") < 0:
1431 tmp = line.split(",")
1432 recTrack["nmeas"] = tmp[0].split(" ")[1]
1433 recTrack["chi2"] = tmp[1]
1434 recTrack["p_rec"] = tmp[2].replace(" ", "")
1435 elif not line.find("making") < 0:
1436 tmp = line.split(",")
1437 recTrack["p_hit"] = tmp[1].replace(" ", "")
1438 recTrack["fp_hit"] = float(tmp[1].replace(" ", ""))
1439 elif not line.find("Ptruth") < 0:
1440 tmp = line.split(" ")
1441 recTrack["id_hit"] = tmp[1].replace(" ", "")
1442 # print a table
1443 print(
1444 "%4s %8s %8s %4s %8s %8s %8s %8s %8s %8s "
1445 % ("nr", "origin", "pythiaID", "ID", "p_orig", "p_hit", "chi2", "weight", "file", "cor w")
1446 )
1447 # sort according to p_hit
1448 tmp = sorted(result, key=itemgetter("fp_hit"))
1449 muonrate1 = 0
1450 muonrate2 = 0
1451 muonrate3 = 0
1452 for i in range(len(tmp)):
1453 tr = tmp[i]
1454 corw = float(tr["w"]) / cor
1455 if float(tr["p_hit"]) > 1:
1456 muonrate1 += corw
1457 if float(tr["p_hit"]) > 2:
1458 muonrate2 += corw
1459 if float(tr["p_hit"]) > 3:
1460 muonrate3 += corw
1461 print(
1462 "%4i %8s %8s %4s %8s %8s %8s %8s %8s %8s "
1463 % (
1464 i,
1465 tr["origin"],
1466 tr["pytiaid"],
1467 tr["id_hit"],
1468 tr["o-mom"],
1469 tr["p_hit"],
1470 tr["chi2"],
1471 tr["w"],
1472 tr["file"],
1473 corw,
1474 )
1475 )
1476 print("guestimate for muonrate above 1GeV = ", muonrate1)
1477 print("guestimate for muonrate above 2GeV = ", muonrate2)
1478 print("guestimate for muonrate above 3GeV = ", muonrate3)
1479 # guestimate for muonrate above 1GeV = 56025.4793333
1480 # guestimate for muonrate above 2GeV = 25584.9546667
1481 # guestimate for muonrate above 3GeV = 14792.8113333
1482 return tmp
1483
1484
1485#
1486def readAndMergeHistos(prods) -> None:
1487 for p in prods:
1488 x = p
1489 if p.find(".root") < 0:
1490 x = p + ".root"
1491 ut.readHists(h, x)
1492 # make list of hists with entries
1493 k = 1
1494 for x in histlistAll:
1495 if histlistAll[x] in h:
1496 histlist[k] = histlistAll[x]
1497 k += 1
1498 nstations = len(histlist)
1499 print("make plots for ", nstations)
1500 makePlots(nstations)
1501 printAndCopy(prods[0].replace(".root", ""))
1502
1503
1504# python -i $HNL/ana_ShipMuon.py 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
1505# python -i $HNL/ana_ShipMuon.py 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
1506# python -i $HNL/ana_ShipMuon.py 1012 1013 1014 1015 1016 1017 1018 1019 1022 1023 1024 1025 1026 1027 1028 1029
1507# python -i $HNL/ana_ShipMuon.py 634 635 636 637 638 639 640 641 642 643
1508# combine all cern-cracow
1509# python -i $HNL/ana_ShipMuon.py 810 811 812 813 814 815 816 817 818 819 910 911 912 913 914 915 916 917 918 919 1012 1013 1014 1015 1016 1017 1018 1019
1510# python -i $HNL/ana_ShipMuon.py 820 821 822 823 824 825 826 827 828 829 920 921 922 923 924 925 926 927 928 929 1022 1023 1024 1025 1026 1027 1028 1029
1511# make muonDIS ntuple: muDISntuple("/media/Data/HNL/muonBackground/rareEvents_81-102.root") -> 'muDISVetoCounter.root'
1512# second step python $FAIRSHIP/muonShieldOptimization/makeMuonDIS.py 1 10000 muDISVetoCounter.root
1513# third step run_simScript.py --MuDIS -n 10 -f muonDis_1.root
1514# for concrete
1515# analyzeConcrete() -> muConcrete.root
None eventsWithEntryPoints(i)
None rareEventEmulsion(str fname="rareEmulsion.txt")
None origin(sTree, it)
None originOfMuon(TextIOWrapper fout, int n, fn, nEvents)
None MergeRareEvents(list[str]|None runs=None)
None makePlots(int nstations)
None fitSingleGauss(x, ba=None, be=None)
None bookHist(detName)
None debugGeoTracks(sTree)
None eventsWithStrawPoints(i)
def makeNicePrintout(list[str]|None x=None)
None readAndMergeHistos(prods)
None AnaEventLoop()
None BigEventLoop()
None extractRareEvents(single=None)
None makeProd()
None depEnergy(sTree)
None analyzeConcrete()
None executeOneFile(fn, output=None, pid=None)
None reDraw(fn)
None drawBoth(str tag, hn)
None printAndCopy(str|None prefix=None)
None muDISntuple(fn)
None persistency()
None extractMuCloseByEvents(single=None)
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)
def configure(run, ship_geo)
int open(const char *, int)
Opens a file descriptor.