FairShip
Loading...
Searching...
No Matches
makeMuonDIS.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 sys
5import time
6
7import ROOT
8
9ROOT.gROOT.LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C")
10ROOT.basiclibs()
11
12nJob = 2
13nMult = 10 # number of events / muon
14muonIn = "$SHIPSOFT/data/muConcrete.root"
15nPerJob = 20000
16
17if len(sys.argv) > 1:
18 nJob = int(sys.argv[1])
19if len(sys.argv) > 2:
20 nMult = int(sys.argv[2])
21if len(sys.argv) > 3:
22 muonIn = sys.argv[3]
23if len(sys.argv) > 4:
24 nPerJob = int(sys.argv[4])
25
26#
27from array import array
28
29PDG = ROOT.TDatabasePDG.Instance()
30myPythia = ROOT.TPythia6()
31myPythia.SetMSEL(2) # msel 2 includes diffractive parts
32myPythia.SetPARP(2, 2) # To get below 10 GeV, you have to change PARP(2)
33for kf in [211, 321, 130, 310, 3112, 3122, 3222, 3312, 3322, 3334]:
34 kc = myPythia.Pycomp(kf)
35 myPythia.SetMDCY(kc, 1, 0)
36
37masssq = {}
38
39
40def getMasssq(pid):
41 apid = abs(int(pid))
42 if apid not in masssq:
43 masssq[apid] = PDG.GetParticle(apid).Mass() ** 2
44 return masssq[apid]
45
46
47R = int(time.time() % 900000000)
48myPythia.SetMRPY(1, R)
49mutype = {-13: "gamma/mu+", 13: "gamma/mu-"}
50
51# DIS event
52# incoming muon, id:px:py:pz:x:y:z:w
53# outgoing particles, id:px:py:pz
54fout = ROOT.TFile("muonDis_" + str(nJob) + ".root", "recreate")
55dTree = ROOT.TTree("DIS", "muon DIS")
56iMuon = ROOT.TClonesArray("TVectorD")
57iMuonBranch = dTree.Branch("InMuon", iMuon, 32000, -1)
58dPart = ROOT.TClonesArray("TVectorD")
59dPartBranch = dTree.Branch("Particles", dPart, 32000, -1)
60
61# read file with muons hitting concrete wall
62fin = ROOT.TFile(muonIn) # id:px:py:pz:x:y:z:w
63sTree = fin.muons
64
65
66def rotate(ctheta, stheta, cphi, sphi, px, py, pz):
67 # rotate around y-axis
68 px1 = ctheta * px + stheta * pz
69 pzr = -stheta * px + ctheta * pz
70 # rotate around z-axis
71 pxr = cphi * px1 - sphi * py
72 pyr = sphi * px1 + cphi * py
73 return pxr, pyr, pzr
74
75
76nTOT = sTree.GetEntries()
77
78nStart = nPerJob * nJob
79nEnd = min(nTOT, nStart + nPerJob)
80if muonIn.find("Concrete") < 0:
81 nStart = 0
82 nEnd = nTOT
83
84# stop pythia printout during loop
85myPythia.SetMSTU(11, 11)
86print("start production ", nStart, nEnd)
87nMade = 0
88for k in range(nStart, nEnd):
89 rc = sTree.GetEvent(k)
90 # make n events / muon
91 px, py, pz = sTree.px, sTree.py, sTree.pz
92 x, y, z = sTree.x, sTree.y, sTree.z
93 pid, w = sTree.id, sTree.w
94 p = ROOT.TMath.Sqrt(px * px + py * py + pz * pz)
95 E = ROOT.TMath.Sqrt(getMasssq(pid) + p * p)
96 # px=p*sin(theta)cos(phi),py=p*sin(theta)sin(phi),pz=p*cos(theta)
97 theta = ROOT.TMath.ACos(pz / p)
98 phi = ROOT.TMath.ATan2(py, px)
99 ctheta, stheta = ROOT.TMath.Cos(theta), ROOT.TMath.Sin(theta)
100 cphi, sphi = ROOT.TMath.Cos(phi), ROOT.TMath.Sin(phi)
101 mu = array("d", [pid, px, py, pz, E, x, y, z, w])
102 myPythia.Initialize("FIXT", mutype[pid], "p+", p)
103 for n in range(nMult):
104 dPart.Clear()
105 iMuon.Clear()
106 tca_vec = iMuon.ConstructedAt(0)
107 muPart = ROOT.TVectorD(9, mu)
108 tca_vec.ResizeTo(muPart)
109 ROOT.std.swap(tca_vec, muPart)
110 myPythia.GenerateEvent()
111 # remove all unnecessary stuff
112 myPythia.Pyedit(2)
113 for itrk in range(1, myPythia.GetN() + 1):
114 did = myPythia.GetK(itrk, 2)
115 dpx, dpy, dpz = rotate(
116 ctheta, stheta, cphi, sphi, myPythia.GetP(itrk, 1), myPythia.GetP(itrk, 2), myPythia.GetP(itrk, 3)
117 )
118 psq = dpx**2 + dpy**2 + dpz**2
119 E = ROOT.TMath.Sqrt(getMasssq(did) + psq)
120 m = array("d", [did, dpx, dpy, dpz, E])
121 part = ROOT.TVectorD(5, m)
122 # copy to branch
123 nPart = len(dPart)
124 if dPart.GetSize() == nPart:
125 dPart.Expand(nPart + 10)
126 tca_vec = dPart.ConstructedAt(nPart)
127 tca_vec.ResizeTo(part)
128 ROOT.std.swap(tca_vec, part)
129 nMade += 1
130 if nMade % 10000 == 0:
131 print("made so far ", nMade)
132 dTree.Fill()
133fout.cd()
134dTree.Write()
135myPythia.SetMSTU(11, 6)
136print("created nJob ", nJob, ":", nStart, " - ", nEnd, " events")
def rotate(px, py, pz, theta, phi)
Definition: makeMuonDIS.py:55
def getMasssq(pid)
Definition: makeMuonDIS.py:40