5"""Script to collect muons hitting the SBT (including soft interaction products) to a ROOT file."""
14from tabulate
import tabulate
16pdg = r.TDatabasePDG.Instance()
19logging.basicConfig(level=logging.INFO)
22parser = argparse.ArgumentParser(description=__doc__)
23parser.add_argument(
"--test", dest=
"testing_code", help=
"Run Test", action=
"store_true")
27 default=
"muonsProduction_wsoft_SBT.root",
28 help=
"custom outputfile name",
33 help=
"path to muon background files",
34 default=
"/eos/experiment/ship/simulation/bkg/MuonBack_2024helium/8070735",
36args = parser.parse_args()
39 logging.info(
"test code, output file name overwritten as: muonsProduction_wsoft_SBT_test.root")
40 args.outputfile =
"muonsProduction_wsoft_SBT_test.root"
41 selectedmuons =
"SelectedMuonsSBT_test.txt"
43 selectedmuons =
"SelectedMuonsSBT.txt"
46logging.info(f
"Path to MuonBackground : {path}")
48fsel =
open(selectedmuons,
"w")
49csvwriter = csv.writer(fsel)
51output_file = r.TFile.Open(args.outputfile,
"recreate")
52output_tree = r.TTree(
"MuonAndSoftInteractions",
"Muon information and soft interaction tracks")
54imuondata = r.TVectorD(10)
55output_tree.Branch(
"imuondata", imuondata)
57track_array = r.TObjArray()
58output_tree.Branch(
"tracks", track_array)
60muon_vetoPoints = r.TClonesArray(
"vetoPoint")
61output_tree.Branch(
"muon_vetoPoints", muon_vetoPoints)
63muon_UpstreamTaggerPoints = r.TClonesArray(
"UpstreamTaggerPoint")
64output_tree.Branch(
"muon_UpstreamTaggerPoints", muon_UpstreamTaggerPoints)
67h[
"PvPt_muon"] = r.TH2F(
69 "The momentum of the muons hitting the SBT(unweighted);P(GeV/c);Pt(GeV/c)",
79 "Number of muons hitting the SBT per Event;number of mu- per event (unweighted) bin width =1;number of mu+ per event (unweighted) bin width=1",
87h[
"n_softtracks"] = r.TH1I(
"n_softtracks",
"Number of soft tracks per muon;;(unweighted)", 200, 0, 2000)
88h[
"n_sbthits"] = r.TH1I(
"n_sbthits",
"Number of SBT hits per muon;n_sbthits(unweighted);", 900, 0, 900)
92 """Print MCTrack truth."""
99 particle_name = pdg.GetParticle(mcp.GetPdgCode()).GetName()
101 if particle_name ==
"mu+" or particle_name ==
"mu-":
102 particle_name = f
"{RED}{particle_name}{RESET} "
105 " %6s %-10s %10i %6.3F %6.3F %7.3F %7.3F %7.3F %7.3F %6s %10.3F %28s"
113 mcp.GetStartX() / u.m,
114 mcp.GetStartY() / u.m,
115 mcp.GetStartZ() / u.m,
118 mcp.GetProcName().Data(),
123 " %6s %-10s %10i %6.3F %6.3F %7.3F %7.3F %7.3F %7.3F %6s %10.3F %28s"
131 mcp.GetStartX() / u.m,
132 mcp.GetStartY() / u.m,
133 mcp.GetStartZ() / u.m,
136 mcp.GetProcName().Data(),
141def dump(event, pcut: float = 0, print_whole_event: bool =
True) ->
None:
142 """Dump the whole event."""
143 if print_whole_event:
145 "\n %6s %-10s %10s %6s %6s %7s %7s %7s %7s %6s %10s %18s"
162 " %6s %10s %10s %6s %6s %7s %7s %7s %7s %6s %10s %18s\n "
179 for mcp
in event.MCTrack:
181 if mcp.GetP() / u.GeV < pcut:
183 if print_whole_event:
194 f
"nMuons in event>{P_threshold}GeV",
207csvwriter.writerow(headers)
209for inputFolder
in os.listdir(path):
210 if not os.path.isdir(os.path.join(path, inputFolder)):
213 if args.testing_code
and global_event_nr >= 100000:
216 logging.info(f
"Processing folder: {inputFolder}")
221 os.path.join(path, inputFolder,
"ship.conical.MuonBack-TGeant4.root"),
225 except Exception
as e:
226 logging.debug(f
"Error :{e}")
232 for eventNr, event
in enumerate(tree):
237 nmu = {
"mu+": 0,
"mu-": 0}
242 for hit
in event.vetoPoint:
243 detID = hit.GetDetectorID()
245 track_id = hit.GetTrackID()
246 P = r.TMath.Sqrt(hit.GetPx() ** 2 + hit.GetPy() ** 2 + hit.GetPz() ** 2)
248 if 1000 < detID < 999999
and abs(pid) == 13
and P_threshold / u.GeV < P:
249 particle_name = pdg.GetParticle(hit.PdgCode()).GetName()
250 if track_id
not in muon_ids:
251 muon_ids.append(track_id)
252 muon_hits[track_id] = 0
253 nmu[particle_name] += 1
254 muon_hits[track_id] += 1
256 if not len(muon_ids):
259 logging.debug(f
"\n\nEVENT ID:{global_event_nr}")
260 logging.debug(f
"Muon Track Available:{muon_hits.keys()}\n Number of SBT hits within:{muon_hits}")
262 for muon_
in muon_ids:
268 for track
in event.MCTrack:
269 if track.GetMotherId() == muon_
and track.GetProcName().Data() !=
"Muon nuclear interaction":
270 track_array.Add(track)
274 muon_UpstreamTaggerPoints.Clear()
278 for hit
in event.UpstreamTaggerPoint:
279 track_id = hit.GetTrackID()
281 if track_id != muon_:
284 if muon_UpstreamTaggerPoints.GetSize() == ubt_index:
285 muon_UpstreamTaggerPoints.Expand(ubt_index + 1)
286 muon_UpstreamTaggerPoints[ubt_index] = hit
292 muon_vetoPoints.Clear()
294 for hit
in event.vetoPoint:
295 detID = hit.GetDetectorID()
297 track_id = hit.GetTrackID()
299 P = r.TMath.Sqrt(hit.GetPx() ** 2 + hit.GetPy() ** 2 + hit.GetPz() ** 2)
300 Pt = r.TMath.Sqrt(hit.GetPx() ** 2 + hit.GetPy() ** 2)
302 if 1000 < detID < 999999
and track_id == muon_
and P_threshold / u.GeV < P:
303 if global_event_nr
not in processed_events:
304 processed_events[global_event_nr] = []
306 if muon_vetoPoints.GetSize() == index:
307 muon_vetoPoints.Expand(index + 1)
308 muon_vetoPoints[index] = hit
312 weight = event.MCTrack[track_id].GetWeight()
314 if track_id
not in processed_events[global_event_nr]:
315 processed_events[global_event_nr].append(track_id)
317 imuondata[0] = float(pid)
318 imuondata[1] = float(hit.GetPx() / u.GeV)
319 imuondata[2] = float(hit.GetPy() / u.GeV)
320 imuondata[3] = float(hit.GetPz() / u.GeV)
321 imuondata[4] = float(hit.GetX() / u.m)
322 imuondata[5] = float(hit.GetY() / u.m)
323 imuondata[6] = float(hit.GetZ() / u.m)
324 imuondata[7] = float(weight)
325 imuondata[8] = float(hit.GetTime())
326 imuondata[9] = len(muon_ids)
338 len(muon_vetoPoints),
339 len(muon_UpstreamTaggerPoints),
344 h[
"PvPt_muon"].Fill(P, Pt)
345 h[
"n_softtracks"].Fill(len(track_array))
347 muon_table[-1][-2] = len(muon_vetoPoints)
349 h[
"n_sbthits"].Fill(len(muon_vetoPoints))
353 h[
"n_muon"].Fill(nmu[
"mu-"], nmu[
"mu+"])
354 csvwriter.writerows(row[1:]
for row
in muon_table)
356 logging.debug(f
"Muon Summary:\n{tabulate(muon_table, headers=headers, tablefmt='grid')}\n\n")
361total_muons = sum(len(values)
for values
in processed_events.values())
362print(f
"nMuons saved: {total_muons}, File: {args.outputfile}")
372 "------------------------------------------------------file saved, inspecting",
374 "now----------------------------------------------------------------",
378with r.TFile.Open(args.outputfile,
"read")
as file:
380 tree = file.MuonAndSoftInteractions
381 except Exception
as e:
385 print(f
"Processing tree: {tree.GetName()}")
386 print(f
"Total number of entries: {tree.GetEntries()}")
389 imuondata = event.imuondata
398 weight = imuondata[7]
399 time_hit = imuondata[8]
400 nmuons = imuondata[9]
402 num_tracks = len(event.tracks)
403 num_muonhits = len(event.muon_vetoPoints)
404 num_ubthits = len(event.muon_UpstreamTaggerPoints)
406 P = r.TMath.Sqrt(px**2 + py**2 + pz**2)
424print(tabulate(event_data, headers=headers, tablefmt=
"grid"))
None printMCTrack(int n, MCTrack)
None dump(event, float pcut=0, bool print_whole_event=True)
int open(const char *, int)
Opens a file descriptor.