5"""Script to generate DIS events for muons in Pythia6, and save them to a ROOT file (along with the original muon's soft interactions)."""
11from array
import array
14from tabulate
import tabulate
16logging.basicConfig(level=logging.INFO)
17PDG = r.TDatabasePDG.Instance()
18PDG.AddParticle(
"C12",
"Carbon-12", 12.0,
True, 0, 6.0,
"nucleus", 1000060120)
19PDG.AddParticle(
"C13",
"Carbon-13", 13.003355,
True, 0, 6.0,
"nucleus", 1000060130)
21parser = argparse.ArgumentParser(description=__doc__)
22parser.add_argument(
"-f",
"--inputFile", help=
"Input file to use", required=
True)
26 dest=
"first_mu_event",
27 help=
"First event of muon file to use",
36 help=
"Number of muons to generate DIS for",
44 help=
"Number of DIS per muon to generate",
50args = parser.parse_args()
51n_events = args.n_events
52first_mu_event = args.first_mu_event
56 """Rotate the daughter particle momentum to align with respect to the muon's momentum."""
57 momentum = r.TVector3(px, py, pz)
59 rotation = r.TRotation()
60 rotation.RotateY(theta)
64 rotated_momentum = rotation * momentum
66 return rotated_momentum.X(), rotated_momentum.Y(), rotated_momentum.Z()
70 """Update the DIS cross section of the muon to the converged value from Pythia."""
71 file = r.TFile.Open(filename,
"read")
73 original_tree = file.DIS
75 temp_filename = filename +
".tmp"
76 temp_file = r.TFile.Open(temp_filename,
"recreate")
78 updated_tree = original_tree.CloneTree(0)
80 for i, event
in enumerate(original_tree):
82 mu[10] = final_xsec[int(first_mu_event + i / args.nDIS)]
85 updated_tree.Write(
"DIS", r.TObject.kOverwrite)
90 os.rename(temp_filename, filename)
91 logging.info(
"Muon DIS events successfully updated with converged cross sections.")
97 "nParticles in event",
103Fixtarget = {1:
"p+", 0:
"n0"}
107 """Inspect the contents of muonDis file."""
108 file = r.TFile.Open(filename,
"READ")
113 for i, event
in enumerate(tree):
114 muon = event.InMuon[0]
115 isProton = int(muon[9])
116 fix_target = Fixtarget.get(isProton,
"unknown")
119 nParticles = len(event.DISParticles)
120 nSoftTracks = len(event.SoftParticles)
121 nSBThits = len(event.muon_vetoPoints)
122 nUBThits = len(event.muon_UpstreamTaggerPoints)
124 table_rows.append([i, fix_target, nParticles, nSoftTracks, nSBThits, nUBThits, cross_sec])
127 logging.info(
"\n" + tabulate(table_rows, headers=headers, tablefmt=
"grid"))
131 """Generate DIS events."""
134 logging.info(f
"Opening input file: {args.inputFile}")
135 muonFile = r.TFile.Open(args.inputFile,
"read")
138 muon_tree = muonFile.MuonAndSoftInteractions
139 except Exception
as e:
144 logging.debug(f
"Total entries in the tree: {muon_tree.GetEntries()}")
145 last_mu_event = min(muon_tree.GetEntries(), first_mu_event + n_events)
147 logging.info(
"Creating output file: muonDis.root")
149 outputFile = r.TFile.Open(
"muonDis.root",
"recreate")
150 output_tree = r.TTree(
"DIS",
"muon DIS")
152 iMuon = r.TClonesArray(
"TVectorD")
153 output_tree.Branch(
"InMuon", iMuon, 32000, -1)
155 dPartDIS = r.TClonesArray(
"TVectorD")
156 output_tree.Branch(
"DISParticles", dPartDIS, 32000, -1)
158 dPartSoft = r.TClonesArray(
"TVectorD")
159 output_tree.Branch(
"SoftParticles", dPartSoft, 32000, -1)
161 muon_vetoPoints = r.TClonesArray(
"vetoPoint")
162 output_tree.Branch(
"muon_vetoPoints", muon_vetoPoints, 32000, -1)
164 muon_UpstreamTaggerPoints = r.TClonesArray(
"UpstreamTaggerPoint")
165 output_tree.Branch(
"muon_UpstreamTaggerPoints", muon_UpstreamTaggerPoints, 32000, -1)
167 myPythia = r.TPythia6()
169 myPythia.SetPARP(2, 2)
170 for kf
in [211, 321, 130, 310, 3112, 3122, 3222, 3312, 3322, 3334]:
171 kc = myPythia.Pycomp(kf)
172 myPythia.SetMDCY(kc, 1, 0)
174 seed = int(time.time() % 900000000)
175 myPythia.SetMRPY(1, seed)
176 mutype = {-13:
"gamma/mu+", 13:
"gamma/mu-"}
178 myPythia.SetMSTU(11, 11)
179 logging.info(f
"Processing muon events from {first_mu_event} to {last_mu_event - 1}...")
183 for k
in range(first_mu_event, last_mu_event):
187 muon_tree.GetEvent(k)
189 imuondata = muon_tree.imuondata
199 time_muon = imuondata[8]
200 nmuons = imuondata[9]
202 p = r.TMath.Sqrt(px**2 + py**2 + pz**2)
203 mass = PDG.GetParticle(abs(int(pid))).Mass()
204 E = r.TMath.Sqrt(mass**2 + p**2)
206 theta = r.TMath.ACos(pz / p)
207 phi = r.TMath.ATan2(py, px)
231 muPart = r.TVectorD(14, mu)
232 myPythia.Initialize(
"FIXT", mutype[pid],
"p+", p)
235 for a
in range(args.nDIS):
236 if a == args.nDIS // 2:
237 myPythia.Initialize(
"FIXT", mutype[pid],
"n0", p)
245 myPythia.GenerateEvent()
248 for itrk
in range(1, myPythia.GetN() + 1):
249 xsec = myPythia.GetPARI(1)
252 did = myPythia.GetK(itrk, 2)
254 myPythia.GetP(itrk, 1),
255 myPythia.GetP(itrk, 2),
256 myPythia.GetP(itrk, 3),
260 psq = dpx**2 + dpy**2 + dpz**2
261 masssq = PDG.GetParticle(did).Mass() ** 2
262 E = r.TMath.Sqrt(masssq + psq)
263 m = array(
"d", [did, dpx, dpy, dpz, E])
264 part = r.TVectorD(5, m)
265 nPart = len(dPartDIS)
266 if dPartDIS.GetSize() == nPart:
267 dPartDIS.Expand(nPart + 10)
269 dPartDIS[nPart] = part
271 cross_sections.append(xsec)
275 for softTrack
in muon_tree.tracks:
276 did = softTrack.GetPdgCode()
277 dpx = softTrack.GetPx()
278 dpy = softTrack.GetPy()
279 dpz = softTrack.GetPz()
281 psq = dpx**2 + dpy**2 + dpz**2
282 masssq = PDG.GetParticle(did).Mass() ** 2
283 E = r.TMath.Sqrt(masssq + psq)
285 softx = softTrack.GetStartX()
286 softy = softTrack.GetStartY()
287 softz = softTrack.GetStartZ()
288 time_ = softTrack.GetStartT()
290 m = array(
"d", [did, dpx, dpy, dpz, E, softx, softy, softz, time_])
292 part = r.TVectorD(9, m)
293 nPart = len(dPartSoft)
294 if dPartSoft.GetSize() == nPart:
295 dPartSoft.Expand(nPart + 10)
297 dPartSoft[nPart] = part
299 muon_vetoPoints.Clear()
302 for hit
in muon_tree.muon_vetoPoints:
303 if muon_vetoPoints.GetSize() == index:
304 muon_vetoPoints.Expand(index + 1)
306 muon_vetoPoints[index] = hit
309 muon_UpstreamTaggerPoints.Clear()
312 for hit
in muon_tree.muon_UpstreamTaggerPoints:
313 if muon_UpstreamTaggerPoints.GetSize() == ubt_index:
314 muon_UpstreamTaggerPoints.Expand(ubt_index + 1)
316 muon_UpstreamTaggerPoints[ubt_index] = hit
326 len(muon_vetoPoints),
327 len(muon_UpstreamTaggerPoints),
336 f
"\nMuon index:{k} \n\tPID = {pid}, weight = {w}, converged_cross_section= {final_xsec[k]}\n\tpx = {px}, py = {py}, pz = {pz}, E = {E},\n\tx = {x}, y = {y}, z = {z}\n\n\tDIS Events Summary\n{tabulate(DIS_table, headers=headers, tablefmt='grid')}"
339 logging.info(f
"Muons processed: {nMade}")
343 myPythia.SetMSTU(11, 6)
345 f
"DIS generated for muons (index {first_mu_event} - {last_mu_event - 1}) , output saved in muonDis.root, nDISPerMuon = {args.nDIS}"
353if __name__ ==
"__main__":
def rotate(px, py, pz, theta, phi)
None update_file(str filename, final_xsec)
None inspect_file(str filename)