File indexing completed on 2025-08-03 08:15:39
0001 import numpy as np
0002 import json
0003 import matplotlib.pyplot as plt
0004 import pandas as pd
0005 import uproot
0006 import awkward as ak
0007 import mpl_toolkits.mplot3d.art3d as art3d
0008 from matplotlib.patches import Wedge
0009 import matplotlib.animation as animation
0010 import array
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 def TPC_surface(inner_radius,outer_radius, length_z):
0026 ngridpoints=30
0027 z = np.linspace(-length_z, length_z, ngridpoints)
0028 phi = np.linspace(0, 2*np.pi, ngridpoints)
0029 phi_grid, z_grid=np.meshgrid(phi, z)
0030 x_grid_inner = inner_radius*np.cos(phi_grid)
0031 y_grid_inner = inner_radius*np.sin(phi_grid)
0032 x_grid_outer = outer_radius*np.cos(phi_grid)
0033 y_grid_outer = outer_radius*np.sin(phi_grid)
0034
0035 return x_grid_inner,y_grid_inner,x_grid_outer,y_grid_outer,z_grid
0036
0037 def TPC_endcap(inner_radius,outer_radius, length_z):
0038 ngridpoints=30
0039 radius = np.linspace(inner_radius, outer_radius, 5)
0040 phi = np.linspace(0, 2*np.pi, ngridpoints)
0041 phi_grid, r_grid=np.meshgrid(phi, radius)
0042 x_grid=[]
0043 y_grid=[]
0044 for r in radius:
0045 x_grid_radius = r*np.cos(phi_grid)
0046 y_grid_radius = r*np.sin(phi_grid)
0047 x_grid=np.append(x_grid,x_grid_radius)
0048 y_grid=np.append(y_grid,y_grid_radius)
0049
0050 z_grid=x_grid
0051 return x_grid,y_grid,z_grid
0052
0053
0054 def raddist_cluster(cluster_pos):
0055 radius=np.sqrt(cluster_pos[0]*cluster_pos[0]+cluster_pos[1]*cluster_pos[1])
0056 return radius
0057
0058 def theLoop(iteration,dataPoint,scatter):
0059
0060 effective_time=iteration
0061 if(effective_time>=0):
0062 effective_z = 0
0063 if(dataPoint[2]>0):
0064 effective_z=dataPoint[2]+drift_speed_posz[2]*effective_time
0065 if(dataPoint[2]<0):
0066 effective_z=dataPoint[2]+drift_speed_negz[2]*effective_time
0067 if(abs(effective_z)<len_TPC+drift_speed_posz[2]):
0068 scatter._offsets3d = (dataPoint[0:1], dataPoint[1:2], [effective_z])
0069 color=['r','g','b','c','m','y']
0070
0071 if(abs(effective_z)<len_TPC):
0072
0073 scatter.set_color('r')
0074 scatter.set_sizes([0.1])
0075 if(abs(effective_z)>=len_TPC):
0076 scatter.set_color('white')
0077 scatter.set(alpha=1.0)
0078 scatter.set_sizes([0.1])
0079
0080 elif(abs(effective_z)<len_TPC+2*drift_speed_posz[2]):
0081 scatter._offsets3d = ([100], [-100], [100])
0082 scatter.set_color('black')
0083 scatter.set_sizes([0.1])
0084 return 0
0085
0086
0087 def animate_scatters(iteration, data,
0088 scatters,fig_text,time_scale,iteration_time,start_iteration):
0089 iteration=iteration+start_iteration
0090 if(iteration%1==0):
0091 print("iteration=")
0092 print(iteration)
0093 iter_array=[iteration]*len(data)
0094 time=(iteration)*iteration_time/time_scale*(10**3)
0095 theLoop_return = [theLoop(iteration,da,scat) for da,scat in zip(data,scatters)]
0096 fig_text.set_text(str(round(time,1))+"$\mu$s")
0097
0098 return scatters,fig_text
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 def animate_clusters(data,animation_name="Animated_clusters_TPC.mp4",save=False,start_iteration=0,no_iterations=1):
0136
0137
0138 fig = plt.figure(figsize=[7.5,7.5],layout='constrained')
0139 ax = fig.add_subplot(111, projection='3d',facecolor='black',alpha=0.0)
0140 ax.grid(False)
0141 ax.margins(0.0)
0142 ax.xaxis.set_pane_color((1,1,1,0))
0143 ax.xaxis.line.set_color('w')
0144 ax.spines['top'].set_color('w')
0145 ax.spines['bottom'].set_color('w')
0146 ax.spines['left'].set_color('w')
0147 ax.spines['right'].set_color('w')
0148
0149 ax.yaxis.set_pane_color((1,1,1,0))
0150 ax.yaxis.line.set_color('w')
0151 ax.zaxis.set_pane_color((1,1,1,0))
0152 ax.zaxis.line.set_color('w')
0153
0154
0155 endcap1=Wedge((0, 0), 80, 0, 360, color='blue',alpha=0.7)
0156 endcap2=Wedge((0, 0), 80, 0, 360, color='blue',alpha=0.7)
0157 endcap1.set_width(60)
0158 endcap2.set_width(60)
0159
0160 ax.add_artist(endcap1)
0161 ax.add_artist(endcap2)
0162
0163 art3d.pathpatch_2d_to_3d(endcap1, z=len_TPC, zdir="z")
0164 art3d.pathpatch_2d_to_3d(endcap2, z=-len_TPC, zdir="z")
0165
0166 Xc_in,Yc_in,Xc_out,Yc_out,Zc = TPC_surface(20,80,len_TPC)
0167 ax.plot_surface(Xc_in, Yc_in, Zc, alpha=0.5)
0168 ax.plot_surface(Xc_out, Yc_out, Zc, alpha=0.5)
0169
0170
0171 ax.set_xlim3d([-100, 100])
0172 ax.set_xlabel('X (cm)',color='white',fontsize=7)
0173 ax.xaxis.set_tick_params(colors='white',labelsize=7)
0174
0175 ax.set_ylim3d([-100, 100])
0176 ax.set_ylabel('Y (cm)',color='white',fontsize=7)
0177 ax.yaxis.set_tick_params(colors='white',labelsize=7)
0178
0179 ax.set_zlim3d([-120, 120])
0180 ax.set_zlabel('Z (cm)',color='white',fontsize=7)
0181 ax.zaxis.set_tick_params(colors='white',labelsize=7)
0182
0183 ax.set_title('Clusters drifting in TPC')
0184 fig_text=ax.text(-100,80,100, 'time', size=10,color='w',alpha=0.9)
0185 fig_text_sPhenix=ax.text(-100,130,100, 'sPHENIX', size=10,fontweight='bold',style='italic',color='w',alpha=0.9)
0186 fig_text_TPC=ax.text(-60,134,70, 'Time Projection Chamber', size=10,color='w',alpha=0.9)
0187 fig_text_collisions=ax.text(-130,110,90, 'Diffused laser with TPC HV on and Laser 98% ALL ON Trigger modebit@2', size=10,color='w',alpha=0.9)
0188 fig_text_frame=ax.text(-130,95,90, '2023-07-06, Run 11011', size=10,color='w',alpha=0.9)
0189
0190
0191
0192
0193
0194 ax.view_init(10,70,0,'y')
0195
0196
0197 scatters = [ ax.scatter([100],[-100],[100]) for i in range(data.shape[0])]
0198 for i in range(data.shape[0]): scatters[i].set_color('black')
0199 print("Plot initialized")
0200
0201 ani = animation.FuncAnimation(fig, animate_scatters, iterations, fargs=(data, scatters,fig_text,time_scale,iteration_time,start_iteration),
0202 interval=iteration_time, blit=False, repeat=False)
0203 if save:
0204 print("Saving animation as"+animation_name)
0205 ani.save(animation_name,writer='ffmpeg')
0206 print("Animation saved")
0207
0208
0209
0210 plt.show()
0211
0212 def read_cluster_pos(inFile):
0213 if(inFile.lower().endswith('.json')):
0214 print("Reading data from json file")
0215 file=open(inFile)
0216 data_json=json.load(file)
0217 file.close()
0218 dict_json = data_json.items()
0219 numpy_array_json = np.array(list(dict_json))
0220
0221 mom_dict=numpy_array_json[2][1]
0222
0223 innertracker_arr=mom_dict['TRACKHITS']
0224
0225
0226 print("Reading clusters")
0227
0228 x_y_z_clusters=np.array([])
0229
0230 no_hits=len(innertracker_arr)
0231 print(no_hits)
0232
0233 for hit_no in range(no_hits):
0234 x_y_z_dict_track=innertracker_arr[hit_no].copy()
0235
0236 x_y_z_clusters_track=np.array(list(x_y_z_dict_track.values()))
0237 x_y_z_clusters_track=x_y_z_clusters_track[:3]
0238
0239
0240 if(raddist_cluster(x_y_z_clusters_track)<30 or x_y_z_clusters_track[2]==0.0):
0241 continue
0242 else:
0243 if(hit_no==0):
0244 x_y_z_clusters=[np.copy(x_y_z_clusters_track)]
0245
0246 else:
0247
0248
0249
0250 x_y_z_clusters=np.vstack([x_y_z_clusters,x_y_z_clusters_track])
0251
0252
0253 return x_y_z_clusters
0254
0255 if(inFile.lower().endswith('.root')):
0256 print("Reading data from root file")
0257 file = uproot.open(inFile)
0258 ntp_cluster_tree=file['hitTree']
0259 branches=ntp_cluster_tree.arrays(["x","y","z"])
0260
0261 branches=branches[((branches.x)**2+(branches.y)**2)>900]
0262
0263
0264
0265
0266
0267 print("Reading clusters")
0268 x_y_z_clusters_run=np.array([])
0269 len_events=len(np.unique(branches.event))
0270 len_events=200
0271 event_times=[0]
0272 event_times=np.append(event_times,np.random.poisson(mean_eventtime*1000,len_events-1))
0273 event_times=np.cumsum(event_times,dtype=float)
0274 for cluster in range(len(branches)):
0275
0276 gvt_event=1
0277 gvt_event=gvt_event*(10**(-6))*time_scale
0278 gvt_event=gvt_event/(iteration_time)
0279 x_y_z_clusters_track=np.array([[branches[cluster]['x'], branches[cluster]['y'], branches[cluster]['z'],branches[cluster]['event'],gvt_event]])
0280 if(cluster==0):
0281 x_y_z_clusters_run=np.copy(x_y_z_clusters_track)
0282 else:
0283 x_y_z_clusters_run=np.append(x_y_z_clusters_run,x_y_z_clusters_track,axis=0)
0284 return x_y_z_clusters_run
0285
0286 print("Generating data for animation")
0287
0288
0289
0290 np.random.seed(3)
0291
0292 time_scale=4.0*(10.0**5)
0293 collision_rate=4.0
0294 mean_eventtime=1/collision_rate
0295 print("Mean event time (microseconds)=")
0296 print(mean_eventtime)
0297 TPC_drift_speed=8.0*(10.0**3)
0298 iteration_time=100.0
0299 len_TPC=105.0
0300
0301 drift_speed_posz=np.array([0.0,0.0,TPC_drift_speed/time_scale*iteration_time,0.0,0.0])
0302 drift_speed_negz=np.array([0.0,0.0,-TPC_drift_speed/time_scale*iteration_time,0.0,0.0])
0303 print("Drift_speed_posz(cm/iteration)=")
0304 print(drift_speed_posz)
0305 print("Drift_speed_negz(cm/iteration)=")
0306 print(drift_speed_negz)
0307
0308
0309
0310 data=read_cluster_pos("Data_files/TPCEventDisplay_11011.json")
0311 print(data)
0312
0313
0314 no_events=1
0315 print("no_events=")
0316 print(no_events)
0317
0318 iterations = int((no_events-1)*mean_eventtime*time_scale/(iteration_time*1000)+len_TPC/drift_speed_posz[2])+5
0319
0320
0321 print("number of iterations=")
0322 print(iterations)
0323 print("Animation starting!")
0324
0325
0326
0327 animate_clusters(data,"Animated_clusters_TPC_beam.mp4",save=True,start_iteration=50,no_iterations=iterations)
0328
0329
0330