sim_track_viz.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #!/usr/bin/env python
  2. import numpy as np
  3. from mpl_toolkits.mplot3d import Axes3D
  4. import matplotlib.pyplot as plt
  5. from uproot import open as root_open
  6. # plt.interactive(True)
  7. tree = None
  8. bsp = None
  9. def pdg_color(pdgId):
  10. return {
  11. 11: 'b',
  12. -11: 'b',
  13. 22: 'g',
  14. }.get(pdgId, 'k')
  15. def get_roots(sourceSimIdxs):
  16. roots = []
  17. for idx, sourceSimIdx in enumerate(sourceSimIdxs):
  18. if len(sourceSimIdx) == 0:
  19. roots.append(idx)
  20. return np.array(roots[:len(roots)//2])
  21. def p(px, py, pz):
  22. return np.sqrt(px**2 + py**2 + pz**2)
  23. def plot_all_roots(sim_vtxs):
  24. # ax = plt.gca(projection='3d')
  25. ax = plt.gca()
  26. xs = sim_vtxs[b'simvtx_x'] - bsp[b'bsp_x']
  27. ys = sim_vtxs[b'simvtx_y'] - bsp[b'bsp_y']
  28. zs = sim_vtxs[b'simvtx_z'] - bsp[b'bsp_z']
  29. rs = np.sqrt(xs*xs + ys*ys)
  30. roots = get_roots(sim_vtxs[b'simvtx_sourceSimIdx'])
  31. bound_z = bsp[b'bsp_sigmaz']*5
  32. # bound_z = 1
  33. bound_r = np.sqrt(bsp[b'bsp_sigmax']**2 + bsp[b'bsp_sigmay']**2)
  34. lumi_roots = []
  35. for root in roots:
  36. if abs(zs[root]) < bound_z and np.sqrt(xs[root]**2 + ys[root]**2) < bound_r:
  37. lumi_roots.append(root)
  38. # nvtx = len(xs)//2
  39. # ax.plot(xs[roots], ys[roots], zs[roots], '.')
  40. # ax.plot(zs[roots], rs[roots], '.')
  41. ax.plot(zs[lumi_roots], rs[lumi_roots], '.')
  42. # ax.plot([-bound_z, -bound_z, bound_z, bound_z], [0, bound_r, bound_r, 0], 'r')
  43. ax.set_xlabel('z')
  44. ax.set_ylabel('r')
  45. ax.set_aspect('equal')
  46. # ax.set_zlabel('z')
  47. def plot_all_vtx(sim_vtxs):
  48. ax = plt.gca(projection='3d')
  49. xs = sim_vtxs[b'simvtx_x']
  50. ys = sim_vtxs[b'simvtx_y']
  51. zs = sim_vtxs[b'simvtx_z']
  52. # nvtx = len(xs)//2
  53. ax.plot(xs, ys, zs, '.')
  54. ax.set_xlabel('x')
  55. ax.set_ylabel('y')
  56. ax.set_zlabel('z')
  57. def plot_event_tree(sim_tracks, sim_vtxs, pv_idx):
  58. print('='*80)
  59. ax = plt.gca(projection='3d')
  60. pdgIds = sim_tracks[b'sim_pdgId']
  61. decayVtxIdxs = sim_tracks[b'sim_decayVtxIdx']
  62. px = sim_tracks[b'sim_px']
  63. py = sim_tracks[b'sim_py']
  64. pz = sim_tracks[b'sim_pz']
  65. xs = sim_vtxs[b'simvtx_x']
  66. ys = sim_vtxs[b'simvtx_y']
  67. zs = sim_vtxs[b'simvtx_z']
  68. daughterSimIdxs = sim_vtxs[b'simvtx_daughterSimIdx']
  69. vtx_idxs = [(0, pv_idx)]
  70. while vtx_idxs:
  71. depth, vtx_idx = vtx_idxs.pop()
  72. print(' '*depth + str(vtx_idx), end=' -> ', flush=True)
  73. ax.plot([xs[vtx_idx]], [ys[vtx_idx]], [zs[vtx_idx]], 'r.')
  74. start_x = xs[vtx_idx]
  75. start_y = ys[vtx_idx]
  76. start_z = zs[vtx_idx]
  77. for sim_idx in daughterSimIdxs[vtx_idx]:
  78. pdgId = pdgIds[sim_idx]
  79. # print(pdgId)
  80. # if abs(pdgId) != 11:
  81. # continue
  82. # if pdgId == 22:
  83. # continue
  84. # if pdgId == 22 and p(px[sim_idx], py[sim_idx], pz[sim_idx]) < 1.0:
  85. # continue
  86. for decay_vtx_idx in decayVtxIdxs[sim_idx]:
  87. end_x = xs[decay_vtx_idx]
  88. end_y = ys[decay_vtx_idx]
  89. end_z = zs[decay_vtx_idx]
  90. # if abs(pdgId) == 11:
  91. if True:
  92. ax.plot([start_x, end_x], [start_y, end_y], [start_z, end_z],
  93. pdg_color(pdgId))
  94. vtx_idxs.append((depth+1, decay_vtx_idx))
  95. print(str(decay_vtx_idx) + ', ', end='')
  96. print()
  97. ax.plot([xs[pv_idx]], [ys[pv_idx]], [zs[pv_idx]], 'k.')
  98. # ax.set_xlim((-5, 5))
  99. # ax.set_ylim((-5, 5))
  100. # ax.set_zlim((-5, 5))
  101. ax.set_xlabel('x')
  102. ax.set_ylabel('y')
  103. ax.set_zlabel('z')
  104. def print_sim_vtxs(sim_vtxs, sim_tracks, sim_pvs, gens, gsf_tracks):
  105. daughterSimIdxs = sim_vtxs[b'simvtx_daughterSimIdx']
  106. sourceSimIdxs = sim_vtxs[b'simvtx_sourceSimIdx']
  107. processTypes = sim_vtxs[b'simvtx_processType']
  108. xs = sim_vtxs[b'simvtx_x'] - bsp[b'bsp_x']
  109. ys = sim_vtxs[b'simvtx_y'] - bsp[b'bsp_y']
  110. zs = sim_vtxs[b'simvtx_z'] - bsp[b'bsp_z']
  111. parentVtxIdxs = sim_tracks[b'sim_parentVtxIdx']
  112. decayVtxIdxs = sim_tracks[b'sim_decayVtxIdx']
  113. sim_pdgIds = sim_tracks[b'sim_pdgId']
  114. sim_pxs = sim_tracks[b'sim_px']
  115. sim_pys = sim_tracks[b'sim_py']
  116. sim_pzs = sim_tracks[b'sim_pz']
  117. gen_pdgIds = gens[b'gen_pdgId']
  118. vxs = gens[b'gen_vx'] - bsp[b'bsp_x']
  119. vys = gens[b'gen_vy'] - bsp[b'bsp_y']
  120. vzs = gens[b'gen_vz'] - bsp[b'bsp_z']
  121. gen_pxs = gens[b'gen_px']
  122. gen_pys = gens[b'gen_py']
  123. gen_pzs = gens[b'gen_pz']
  124. gen_prompt = gens[b'gen_isPrompt']
  125. gen_hadronic = gens[b'gen_isDirectHadronDecayProduct']
  126. gen_tauic = gens[b'gen_isTauDecayProduct']
  127. gsf_pdgIds = -11 * gsf_tracks[b'trk_q']
  128. gsf_vxs = gsf_tracks[b'trk_vtxx'] - bsp[b'bsp_x']
  129. gsf_vys = gsf_tracks[b'trk_vtxy'] - bsp[b'bsp_y']
  130. gsf_vzs = gsf_tracks[b'trk_vtxz'] - bsp[b'bsp_z']
  131. gsf_pxs = gsf_tracks[b'trk_px']
  132. gsf_pys = gsf_tracks[b'trk_py']
  133. gsf_pzs = gsf_tracks[b'trk_pz']
  134. # print('VTX')
  135. # for (idx, (sourceSimIdx, daughterSimIdx, processType)) in enumerate(zip(sourceSimIdxs, daughterSimIdxs, processTypes)):
  136. # if idx in sim_pvs:
  137. # print(f'*{idx}|{processType}', sourceSimIdx, daughterSimIdx, sep=" - ")
  138. # else:
  139. # print(f'{idx}|{processType}', sourceSimIdx, daughterSimIdx, sep=" - ")
  140. print('GEN')
  141. for (idx, (px, py, pz, vx, vy, vz, pdgId, prompt, hadronic, tauic)) in enumerate(zip(gen_pxs, gen_pys, gen_pzs, vxs,
  142. vys, vzs, gen_pdgIds,
  143. gen_prompt, gen_hadronic,
  144. gen_tauic)):
  145. if abs(pdgId) != 11: continue
  146. p = np.sqrt(px**2 + py**2 + pz**2)
  147. theta = np.arctan2(np.hypot(px, py), pz)
  148. phi = np.arctan2(px, py)
  149. print(f'{idx: 4d}|{pdgId: 3d} - ({vx:8.2f},{vy:8.2f},{vz:8.2f}) ({theta:5.2f},{phi:5.2f}) {p: 8.2f}GeV - ({prompt},{hadronic},{tauic}) ')
  150. print('SIM')
  151. for (idx, (px, py, pz, parentVtxIdx, decayVtxIdx, pdgId)) in enumerate(zip(sim_pxs, sim_pys, sim_pzs, parentVtxIdxs, decayVtxIdxs, sim_pdgIds)):
  152. if abs(pdgId) != 11: continue
  153. if len(sourceSimIdxs[parentVtxIdx]) > 0: continue # not from another sim track decay
  154. vx = xs[parentVtxIdx]
  155. vy = ys[parentVtxIdx]
  156. vz = zs[parentVtxIdx]
  157. p = np.sqrt(px**2 + py**2 + pz**2)
  158. theta = np.arctan2(np.hypot(px, py), pz)
  159. phi = np.arctan2(px, py)
  160. print(f'{idx: 4d}|{pdgId: 3d} - ({vx:8.2f},{vy:8.2f},{vz:8.2f}) ({theta:5.2f},{phi:5.2f}) {p: 8.2f}GeV')
  161. print('RECO')
  162. for (idx, (px, py, pz, vx, vy, vz, pdgId)) in enumerate(zip(gsf_pxs, gsf_pys, gsf_pzs, gsf_vxs, gsf_vys, gsf_vzs, gsf_pdgIds)):
  163. p = np.sqrt(px**2 + py**2 + pz**2)
  164. theta = np.arctan2(np.hypot(px, py), pz)
  165. phi = np.arctan2(px, py)
  166. print(f'{idx: 4d}|{pdgId: 3d} - ({vx:8.2f},{vy:8.2f},{vz:8.2f}) ({theta:5.2f},{phi:5.2f}) {p: 8.2f}GeV')
  167. def plot_event(sim_tracks, sim_vtxs, sim_pvs, gens, gsf_tracks, event_idx):
  168. print(f"Processing event {event_idx}")
  169. sim_tracks = {k: v[event_idx] for k, v in sim_tracks.items()}
  170. sim_vtxs = {k: v[event_idx] for k, v in sim_vtxs.items()}
  171. gens = {k: v[event_idx] for k, v in gens.items()}
  172. gsf_tracks = {k: v[event_idx] for k, v in gsf_tracks.items()}
  173. sim_pvs = sim_pvs[event_idx]
  174. print_sim_vtxs(sim_vtxs, sim_tracks, sim_pvs, gens, gsf_tracks)
  175. # print(len(sim_pvs[event_idx]))
  176. # plt.clf()
  177. # plot_all_roots(sim_vtxs)
  178. # plt.show()
  179. # for pv_idx in get_roots(sim_vtxs[b'simvtx_sourceSimIdx']):
  180. # plt.clf()
  181. # plot_event_tree(sim_tracks, sim_vtxs, pv_idx)
  182. # # plot_all_vtx(sim_vtxs)
  183. # plt.show()
  184. def main():
  185. global tree
  186. global bsp
  187. f = root_open('../data/zee.root')
  188. tree = f['trackingNtuple/tree']
  189. gsf_tracks = tree.arrays([
  190. 'trk_q',
  191. 'trk_vtxx',
  192. 'trk_vtxy',
  193. 'trk_vtxz',
  194. 'trk_px',
  195. 'trk_py',
  196. 'trk_pz',
  197. ])
  198. sim_tracks = tree.arrays([
  199. 'sim_pdgId',
  200. 'sim_parentVtxIdx',
  201. 'sim_decayVtxIdx',
  202. 'sim_pt',
  203. 'sim_eta',
  204. 'sim_px',
  205. 'sim_py',
  206. 'sim_pz',
  207. ])
  208. sim_vtxs = tree.arrays([
  209. 'simvtx_x',
  210. 'simvtx_y',
  211. 'simvtx_z',
  212. 'simvtx_sourceSimIdx',
  213. 'simvtx_daughterSimIdx',
  214. 'simvtx_processType',
  215. ])
  216. bsp = tree.arrays([
  217. 'bsp_x',
  218. 'bsp_y',
  219. 'bsp_z',
  220. 'bsp_sigmax',
  221. 'bsp_sigmay',
  222. 'bsp_sigmaz',
  223. ])
  224. gens = tree.arrays([
  225. 'gen_vx',
  226. 'gen_vy',
  227. 'gen_vz',
  228. 'gen_px',
  229. 'gen_py',
  230. 'gen_pz',
  231. 'gen_pdgId',
  232. 'gen_isTauDecayProduct',
  233. 'gen_isDirectHadronDecayProduct',
  234. 'gen_isPrompt',
  235. ])
  236. bsp = {k: v[0] for k, v in bsp.items()}
  237. sim_pvs = tree.array('simpv_idx')
  238. for event_idx in range(tree.fEntries):
  239. plot_event(sim_tracks, sim_vtxs, sim_pvs, gens, gsf_tracks, event_idx)
  240. if event_idx == 5: break
  241. # break
  242. if __name__ == '__main__':
  243. main()