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])
59 effective_time=iteration-dataPoint[4]
60 if(effective_time>=0):
63 effective_z=dataPoint[2]+drift_speed_posz[2]*effective_time
65 effective_z=dataPoint[2]+drift_speed_negz[2]*effective_time
66 if(abs(effective_z)<len_TPC+drift_speed_posz[2]):
67 scatter._offsets3d = (dataPoint[0:1], dataPoint[1:2], [effective_z])
68 color=[
'r','g','b','c','m','y']
70 if(abs(effective_z)<len_TPC):
71 scatter.set_color(color[int(dataPoint[3]%6)])
73 if(abs(effective_z)>=len_TPC):
74 scatter.set_color(
'white')
75 scatter.set(alpha=1.0)
77 elif(abs(effective_z)<len_TPC+2*drift_speed_posz[2]):
78 scatter._offsets3d = ([100], [-100], [100])
79 scatter.set_color(
'black')
80 scatter.set_sizes([10])
85 scatters,fig_text,time_scale,iteration_time,start_iteration):
86 iteration=iteration+start_iteration
90 iter_array=[iteration]*len(data)
91 time=(iteration)*iteration_time/time_scale*(10**3)
92 theLoop_return = [
theLoop(iteration,da,scat)
for da,scat
in zip(data,scatters)]
93 fig_text.set_text(
str(
round(time,1))+
"$\mu$s")
95 return scatters,fig_text
132 def animate_clusters(data,animation_name="Animated_clusters_TPC.mp4",save=False,start_iteration=0,no_iterations=1):
135 fig = plt.figure(figsize=[7.5,7.5],layout=
'constrained')
136 ax = fig.add_subplot(111, projection=
'3d',facecolor=
'black',alpha=0.0)
139 ax.xaxis.set_pane_color((1,1,1,0))
140 ax.xaxis.line.set_color(
'w')
141 ax.spines[
'top'].set_color(
'w')
142 ax.spines[
'bottom'].set_color(
'w')
143 ax.spines[
'left'].set_color(
'w')
144 ax.spines[
'right'].set_color(
'w')
146 ax.yaxis.set_pane_color((1,1,1,0))
147 ax.yaxis.line.set_color(
'w')
148 ax.zaxis.set_pane_color((1,1,1,0))
149 ax.zaxis.line.set_color(
'w')
152 endcap1=Wedge((0, 0), 80, 0, 360, color=
'blue',alpha=0.7)
153 endcap2=Wedge((0, 0), 80, 0, 360, color=
'blue',alpha=0.7)
154 endcap1.set_width(60)
155 endcap2.set_width(60)
157 ax.add_artist(endcap1)
158 ax.add_artist(endcap2)
160 art3d.pathpatch_2d_to_3d(endcap1, z=len_TPC, zdir=
"z")
161 art3d.pathpatch_2d_to_3d(endcap2, z=-len_TPC, zdir=
"z")
163 Xc_in,Yc_in,Xc_out,Yc_out,Zc =
TPC_surface(20,80,len_TPC)
164 ax.plot_surface(Xc_in, Yc_in, Zc, alpha=0.5)
165 ax.plot_surface(Xc_out, Yc_out, Zc, alpha=0.5)
168 ax.set_xlim3d([-100, 100])
169 ax.set_xlabel(
'X (cm)',color=
'white',fontsize=7)
170 ax.xaxis.set_tick_params(colors=
'white',labelsize=7)
172 ax.set_ylim3d([-100, 100])
173 ax.set_ylabel(
'Y (cm)',color=
'white',fontsize=7)
174 ax.yaxis.set_tick_params(colors=
'white',labelsize=7)
176 ax.set_zlim3d([-120, 120])
177 ax.set_zlabel(
'Z (cm)',color=
'white',fontsize=7)
178 ax.zaxis.set_tick_params(colors=
'white',labelsize=7)
180 ax.set_title(
'Clusters drifting in TPC')
181 fig_text=ax.text(-100,90,100,
'time', size=10,color=
'w',alpha=0.9)
182 fig_text_sPhenix=ax.text(-100,130,100,
'sPHENIX', size=10,fontweight=
'bold',style=
'italic',color=
'w',alpha=0.9)
183 fig_text_TPC=ax.text(-60,135,70,
'TPC simulation', size=10,color=
'w',alpha=0.9)
185 fig_text_sPhenix=ax.text(-100,110,100,
'p+p, $\sqrt{s_{NN}}$ = 200 GeV 4MHz', size=10,color=
'w',alpha=0.9)
189 ax.view_init(10,70,0,
'y')
192 scatters = [ ax.scatter([100],[-100],[100])
for i
in range(data.shape[0])]
193 for i
in range(data.shape[0]): scatters[i].set_color(
'black')
194 print(
"Plot initialized")
196 ani = animation.FuncAnimation(fig, animate_scatters, iterations, fargs=(data, scatters,fig_text,time_scale,iteration_time,start_iteration),
197 interval=iteration_time, blit=
False, repeat=
False)
199 print(
"Saving animation as"+animation_name)
200 ani.save(animation_name,writer=
'ffmpeg')
201 print(
"Animation saved")
208 if(inFile.lower().endswith(
'.json')):
209 print(
"Reading data from json file")
211 data_json=json.load(file)
213 dict_json = data_json.items()
214 numpy_array_json = np.array(list(dict_json))
215 mom_dict=numpy_array_json[3][1]
216 innertracker_arr=mom_dict[
'INNERTRACKER']
218 print(
"Reading clusters")
220 x_y_z_clusters=np.array([])
221 no_tracks=len(innertracker_arr)
223 for track_no
in range(no_tracks):
224 x_y_z_dict_track=innertracker_arr[track_no].copy()
225 x_y_z_clusters_track=np.array(x_y_z_dict_track[
'pts'])
226 event_and_times=np.zeros((len(x_y_z_clusters_track),1))
227 x_y_z_clusters_track=np.append(x_y_z_clusters_track,event_and_times,axis=1)
228 x_y_z_clusters_track=np.append(x_y_z_clusters_track,event_and_times,axis=1)
229 x_y_z_clusters_track=x_y_z_clusters_track[
raddist_cluster(x_y_z_clusters_track[:,:2])>30]
232 x_y_z_clusters=np.copy(x_y_z_clusters_track)
235 x_y_z_clusters=np.append(x_y_z_clusters,x_y_z_clusters_track,axis=0)
236 return x_y_z_clusters
238 if(inFile.lower().endswith(
'.root')):
239 print(
"Reading data from root file")
240 file = uproot.open(inFile)
241 ntp_cluster_tree=file[
'ntp_cluster']
242 branches=ntp_cluster_tree.arrays([
"x",
"y",
"z",
"event",
"gvt",
"layer"])
243 branches=branches[~np.isnan(branches.gvt)]
244 branches=branches[((branches.x)**2+(branches.y)**2)>900]
245 branches=branches[branches.layer>6]
246 branches=branches[branches.layer<55]
250 print(
"Reading clusters")
251 x_y_z_clusters_run=np.array([])
252 len_events=len(np.unique(branches.event))
255 event_times=np.append(event_times,np.random.poisson(mean_eventtime*1000,len_events-1))
256 event_times=np.cumsum(event_times,dtype=float)
257 for cluster
in range(len(branches)):
258 gvt_event=event_times[int(branches[cluster][
'event'])]
259 gvt_event=gvt_event*(10**(-6))*time_scale
260 gvt_event=gvt_event/(iteration_time)
261 x_y_z_clusters_track=np.array([[branches[cluster][
'x'], branches[cluster][
'y'], branches[cluster][
'z'],branches[cluster][
'event'],gvt_event]])
263 x_y_z_clusters_run=np.copy(x_y_z_clusters_track)
265 x_y_z_clusters_run=np.append(x_y_z_clusters_run,x_y_z_clusters_track,axis=0)
266 return x_y_z_clusters_run
268 print(
"Generating data for animation")
274 time_scale=4.0*(10.0**5)
276 mean_eventtime=1/collision_rate
277 print(
"Mean event time (microseconds)=")
278 print(mean_eventtime)
279 TPC_drift_speed=8.0*(10.0**3)
283 drift_speed_posz=np.array([0.0,0.0,TPC_drift_speed/time_scale*iteration_time,0.0,0.0])
284 drift_speed_negz=np.array([0.0,0.0,-TPC_drift_speed/time_scale*iteration_time,0.0,0.0])
285 print(
"Drift_speed_posz(cm/iteration)=")
286 print(drift_speed_posz)
287 print(
"Drift_speed_negz(cm/iteration)=")
288 print(drift_speed_negz)
294 no_events=np.max(data[:,3])+1
298 iterations = int((no_events-1)*mean_eventtime*time_scale/(iteration_time*1000)+len_TPC/drift_speed_posz[2])+5
301 print(
"number of iterations=")
303 print(
"Animation starting!")
307 animate_clusters(data,
"Animated_clusters_TPC.mp4",save=
True,start_iteration=0,no_iterations=iterations)