3 import matplotlib.pyplot
as plt
7 import mpl_toolkits.mplot3d.art3d
as art3d
8 from matplotlib.patches
import Wedge
9 import matplotlib.animation
as animation
27 z = np.linspace(-length_z, length_z, ngridpoints)
28 phi = np.linspace(0, 2*np.pi, ngridpoints)
29 phi_grid, z_grid=np.meshgrid(phi, z)
30 x_grid_inner = inner_radius*np.cos(phi_grid)
31 y_grid_inner = inner_radius*np.sin(phi_grid)
32 x_grid_outer = outer_radius*np.cos(phi_grid)
33 y_grid_outer = outer_radius*np.sin(phi_grid)
35 return x_grid_inner,y_grid_inner,x_grid_outer,y_grid_outer,z_grid
39 radius = np.linspace(inner_radius, outer_radius, 5)
40 phi = np.linspace(0, 2*np.pi, ngridpoints)
41 phi_grid, r_grid=np.meshgrid(phi, radius)
45 x_grid_radius = r*np.cos(phi_grid)
46 y_grid_radius = r*np.sin(phi_grid)
47 x_grid=np.append(x_grid,x_grid_radius)
48 y_grid=np.append(y_grid,y_grid_radius)
51 return x_grid,y_grid,z_grid
55 radius=np.sqrt(cluster_pos[0]*cluster_pos[0]+cluster_pos[1]*cluster_pos[1])
60 effective_time=iteration
61 if(effective_time>=0):
64 effective_z=dataPoint[2]+drift_speed_posz[2]*effective_time
66 effective_z=dataPoint[2]+drift_speed_negz[2]*effective_time
67 if(abs(effective_z)<len_TPC+drift_speed_posz[2]):
68 scatter._offsets3d = (dataPoint[0:1], dataPoint[1:2], [effective_z])
69 color=[
'r','g','b','c','m','y']
71 if(abs(effective_z)<len_TPC):
73 scatter.set_color(
'r')
74 scatter.set_sizes([0.1])
75 if(abs(effective_z)>=len_TPC):
76 scatter.set_color('white')
77 scatter.set(alpha=1.0)
78 scatter.set_sizes([0.1])
80 elif(abs(effective_z)<len_TPC+2*drift_speed_posz[2]):
81 scatter._offsets3d = ([100], [-100], [100])
82 scatter.set_color(
'black')
83 scatter.set_sizes([0.1])
88 scatters,fig_text,time_scale,iteration_time,start_iteration):
89 iteration=iteration+start_iteration
93 iter_array=[iteration]*len(data)
94 time=(iteration)*iteration_time/time_scale*(10**3)
95 theLoop_return = [
theLoop(iteration,da,scat)
for da,scat
in zip(data,scatters)]
96 fig_text.set_text(
str(
round(time,1))+
"$\mu$s")
98 return scatters,fig_text
135 def animate_clusters(data,animation_name="Animated_clusters_TPC.mp4",save=False,start_iteration=0,no_iterations=1):
138 fig = plt.figure(figsize=[7.5,7.5],layout=
'constrained')
139 ax = fig.add_subplot(111, projection=
'3d',facecolor=
'black',alpha=0.0)
142 ax.xaxis.set_pane_color((1,1,1,0))
143 ax.xaxis.line.set_color(
'w')
144 ax.spines[
'top'].set_color(
'w')
145 ax.spines[
'bottom'].set_color(
'w')
146 ax.spines[
'left'].set_color(
'w')
147 ax.spines[
'right'].set_color(
'w')
149 ax.yaxis.set_pane_color((1,1,1,0))
150 ax.yaxis.line.set_color(
'w')
151 ax.zaxis.set_pane_color((1,1,1,0))
152 ax.zaxis.line.set_color(
'w')
155 endcap1=Wedge((0, 0), 80, 0, 360, color=
'blue',alpha=0.7)
156 endcap2=Wedge((0, 0), 80, 0, 360, color=
'blue',alpha=0.7)
157 endcap1.set_width(60)
158 endcap2.set_width(60)
160 ax.add_artist(endcap1)
161 ax.add_artist(endcap2)
163 art3d.pathpatch_2d_to_3d(endcap1, z=len_TPC, zdir=
"z")
164 art3d.pathpatch_2d_to_3d(endcap2, z=-len_TPC, zdir=
"z")
166 Xc_in,Yc_in,Xc_out,Yc_out,Zc =
TPC_surface(20,80,len_TPC)
167 ax.plot_surface(Xc_in, Yc_in, Zc, alpha=0.5)
168 ax.plot_surface(Xc_out, Yc_out, Zc, alpha=0.5)
171 ax.set_xlim3d([-100, 100])
172 ax.set_xlabel(
'X (cm)',color=
'white',fontsize=7)
173 ax.xaxis.set_tick_params(colors=
'white',labelsize=7)
175 ax.set_ylim3d([-100, 100])
176 ax.set_ylabel(
'Y (cm)',color=
'white',fontsize=7)
177 ax.yaxis.set_tick_params(colors=
'white',labelsize=7)
179 ax.set_zlim3d([-120, 120])
180 ax.set_zlabel(
'Z (cm)',color=
'white',fontsize=7)
181 ax.zaxis.set_tick_params(colors=
'white',labelsize=7)
183 ax.set_title(
'Clusters drifting in TPC')
184 fig_text=ax.text(-100,80,100,
'time', size=10,color=
'w',alpha=0.9)
185 fig_text_sPhenix=ax.text(-100,130,100,
'sPHENIX', size=10,fontweight=
'bold',style=
'italic',color=
'w',alpha=0.9)
186 fig_text_TPC=ax.text(-60,134,70,
'Time Projection Chamber', size=10,color=
'w',alpha=0.9)
187 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)
188 fig_text_frame=ax.text(-130,95,90,
'2023-07-06, Run 11011', size=10,color=
'w',alpha=0.9)
194 ax.view_init(10,70,0,
'y')
197 scatters = [ ax.scatter([100],[-100],[100])
for i
in range(data.shape[0])]
198 for i
in range(data.shape[0]): scatters[i].set_color(
'black')
199 print(
"Plot initialized")
201 ani = animation.FuncAnimation(fig, animate_scatters, iterations, fargs=(data, scatters,fig_text,time_scale,iteration_time,start_iteration),
202 interval=iteration_time, blit=
False, repeat=
False)
204 print(
"Saving animation as"+animation_name)
205 ani.save(animation_name,writer=
'ffmpeg')
206 print(
"Animation saved")
213 if(inFile.lower().endswith(
'.json')):
214 print(
"Reading data from json file")
216 data_json=json.load(file)
218 dict_json = data_json.items()
219 numpy_array_json = np.array(list(dict_json))
221 mom_dict=numpy_array_json[2][1]
223 innertracker_arr=mom_dict[
'TRACKHITS']
226 print(
"Reading clusters")
228 x_y_z_clusters=np.array([])
230 no_hits=len(innertracker_arr)
233 for hit_no
in range(no_hits):
234 x_y_z_dict_track=innertracker_arr[hit_no].copy()
236 x_y_z_clusters_track=np.array(list(x_y_z_dict_track.values()))
237 x_y_z_clusters_track=x_y_z_clusters_track[:3]
244 x_y_z_clusters=[np.copy(x_y_z_clusters_track)]
250 x_y_z_clusters=np.vstack([x_y_z_clusters,x_y_z_clusters_track])
253 return x_y_z_clusters
255 if(inFile.lower().endswith(
'.root')):
256 print(
"Reading data from root file")
257 file = uproot.open(inFile)
258 ntp_cluster_tree=file[
'hitTree']
259 branches=ntp_cluster_tree.arrays([
"x",
"y",
"z"])
261 branches=branches[((branches.x)**2+(branches.y)**2)>900]
267 print(
"Reading clusters")
268 x_y_z_clusters_run=np.array([])
269 len_events=len(np.unique(branches.event))
272 event_times=np.append(event_times,np.random.poisson(mean_eventtime*1000,len_events-1))
273 event_times=np.cumsum(event_times,dtype=float)
274 for cluster
in range(len(branches)):
277 gvt_event=gvt_event*(10**(-6))*time_scale
278 gvt_event=gvt_event/(iteration_time)
279 x_y_z_clusters_track=np.array([[branches[cluster][
'x'], branches[cluster][
'y'], branches[cluster][
'z'],branches[cluster][
'event'],gvt_event]])
281 x_y_z_clusters_run=np.copy(x_y_z_clusters_track)
283 x_y_z_clusters_run=np.append(x_y_z_clusters_run,x_y_z_clusters_track,axis=0)
284 return x_y_z_clusters_run
286 print(
"Generating data for animation")
292 time_scale=4.0*(10.0**5)
294 mean_eventtime=1/collision_rate
295 print(
"Mean event time (microseconds)=")
296 print(mean_eventtime)
297 TPC_drift_speed=8.0*(10.0**3)
301 drift_speed_posz=np.array([0.0,0.0,TPC_drift_speed/time_scale*iteration_time,0.0,0.0])
302 drift_speed_negz=np.array([0.0,0.0,-TPC_drift_speed/time_scale*iteration_time,0.0,0.0])
303 print(
"Drift_speed_posz(cm/iteration)=")
304 print(drift_speed_posz)
305 print(
"Drift_speed_negz(cm/iteration)=")
306 print(drift_speed_negz)
318 iterations = int((no_events-1)*mean_eventtime*time_scale/(iteration_time*1000)+len_TPC/drift_speed_posz[2])+5
321 print(
"number of iterations=")
323 print(
"Animation starting!")
327 animate_clusters(data,
"Animated_clusters_TPC_beam.mp4",save=
True,start_iteration=50,no_iterations=iterations)