catm-python-lib
Loading...
Searching...
No Matches
basepad.py
1"""!
2# @file basepad.py
3# @version 1
4# @author Fumitaka ENDO
5# @date 2025-01-28T09:21:35+09:00
6# @brief Basic readout pad generation package
7"""
8import matplotlib
9import matplotlib.pyplot as plt
10import numpy as np
11
12plt.rcParams['font.family'] = 'serif'
13plt.rcParams['font.serif'] = ['Times New Roman'] + plt.rcParams['font.serif']
14
15class TBasePadShapeClass():
16 """!
17 @class TBasePadShapeClass
18 @brief Generate pad information
19 """
20
21 def __init__(self):
22 """!
23 @brief initialze object
24 @param mapping label of axsis (0:x, 1:y, 2:z)
25 @param center center position in pad
26 @param polygon list of vertices
27 @return None
28 """
29 self.mapping = {'x': 0, 'y': 1, 'z': 2}
30 self.center = [0, 0, 0]
31 self.polygon = []
32
33 def set_center(self, x, y, z):
34 """!
35 @brief set center position
36 @return None
37 """
38 self.center = [x, y, z]
39
40 def add_polygon(self, position):
41 """!
42 @brief add vertex positio to list(self.polygon)
43 @return None
44 """
45 self.polygon.append(position)
46
47 def get_center(self):
48 """!
49 @brief return center position
50 @return self.center
51 """
52 return self.center
53
54 def get_polygon(self):
55 """!
56 @brief return vertices list
57 @return self.polygon
58 """
59 return self.polygon
60
61 def get_center_polygon_distance(self):
62 """!
63 @brief caculate and return center position from vertices list
64 @return three component list ([x, y, z])
65 """
66 distances = []
67
68 for i in range(len(self.polygon)):
69 dx = self.center[0] - self.polygon[i][0]
70 dy = self.center[1] - self.polygon[i][1]
71 dz = self.center[2] - self.polygon[i][2]
72 distances.append( np.sqrt(dx**2 + dy**2 + dz**2) )
73
74 return distances
75
76 def get_polygon_vertex_distance(self):
77 """!
78 @brief caculate and return distance between each vertices
79 @return distance list ([01, 12, 23, ...])
80 """
81 distances = []
82 for i in range(len(self.polygon)):
83 for j in range(i+1, len(self.polygon)):
84 dx = self.polygon[i][0] - self.polygon[j][0]
85 dy = self.polygon[i][1] - self.polygon[j][1]
86 dz = self.polygon[i][2] - self.polygon[j][2]
87 distances.append( np.sqrt(dx**2 + dy**2 + dz**2) )
88 return distances
89
90 def show_polygon(self, plane='xz'):
91 """!
92 @brief plot polygon
93 @param plane Select projection plane by str (e.g. 'xz')
94 @return None
95 """
96 index1 = self.mapping.get(plane[0], 0)
97 index2 = self.mapping.get(plane[1], 0)
98
99 xs = [vertex[index1] for vertex in self.polygon ]
100 ys = [vertex[index2] for vertex in self.polygon ]
101
102 fig=plt.figure(figsize=(6, 5))
103 ax = fig.add_subplot(111)
104 fig.patch.set_alpha(0.)
105 ax.fill(xs, ys, edgecolor='black', facecolor='#d3d3d3')
106 ax.set_aspect('equal')
107
108 plt.xlabel(str(plane[0])+"position [mm]")
109 plt.ylabel(str(plane[1])+"position [mm]")
110 plt.show()
111
112class TReadoutPadArray():
113 """!
114 @class TReadoutPadArray
115 @brief pad information array
116 """
117
118 def __init__(self):
119 """!
120 @brief initialze object
121 @param mapping label of axsis (0:x, 1:y, 2:z)
122 @param basepadlist list of base pad information
123 @param pads list of vertices
124 @param ids list of id
125 @param centers list of center
126 @param charges list of charge
127 @return None
128 """
129 self.mapping = {'x': 0, 'y': 1, 'z': 2}
130 self.basepadlist = []
131 self.pads = []
132 self.ids = []
133 self.centers = []
134 self.charges = []
135
136 def rotate_x(self, position, degree):
137 """!
138 @brief rotate position with x axis
139 @param position origninal position
140 @degree rotation angle [deg]
141 @return converted position [x, y, z]
142 """
143 theta = 0.0174533*degree
144 x = position[0]
145 y = position[1] * np.cos(theta) - position[2] * np.sin(theta)
146 z = position[1] * np.sin(theta) + position[2] * np.cos(theta)
147 return [x, y, z]
148
149 def rotate_y(self, position, degree):
150 """!
151 @brief rotate position with y axis
152 @param position origninal position
153 @degree rotation angle [deg]
154 @return converted position [x, y, z]
155 """
156 theta = 0.0174533*degree
157 x = position[0] * np.cos(theta) + position[2] * np.sin(theta)
158 y = position[1]
159 z = -position[0] * np.sin(theta) + position[2] * np.cos(theta)
160 return [x, y, z]
161
162 def rotate_z(self, position, degree):
163 """!
164 @brief rotate position with z axis
165 @param position origninal position
166 @degree rotation angle [deg]
167 @return converted position [x, y, z]
168 """
169 theta = 0.0174533*degree
170 x = position[0] * np.cos(theta) - position[1] * np.sin(theta)
171 y = position[0] * np.sin(theta) + position[1] * np.cos(theta)
172 z = position[2]
173 return [x, y, z]
174
175 def add_basepad(self,baseinfo):
176 """!
177 @brief add pad info (TBasePadShapeClass)
178 @param baseinfo objerct of TBasePadShapeClass
179 @return None
180 """
181 self.basepadlist.append(baseinfo)
182
183 def add_pads(self, center, baseid, degX=0, degY=0, degZ=0, id=0):
184 """!
185 @brief set pad with position and id
186 @param center center new center postion for adding pad
187 @param center baseid id of base pad object
188 @param center degX rotation angle by X
189 @param center degY rotation angle by Y
190 @param center degZ rotation angle by Z
191 @param center label od each id
192 @return None
193 """
194 padshape = self.basepadlist[baseid]
195 polygon_origin = padshape.get_polygon()
196
197 polygon_new = []
198
199 for i in range(len(polygon_origin)):
200
201 polygon_rot = self.rotate_x(polygon_origin[i], degX)
202 polygon_rot = self.rotate_y(polygon_rot, degY)
203 polygon_rot = self.rotate_z(polygon_rot, degZ)
204
205 for j in range(len(polygon_rot)):
206 polygon_rot[j] = polygon_rot[j] + center[j]
207
208 polygon_new.append(polygon_rot)
209
210 self.pads.append(polygon_new)
211 self.ids.append(id)
212 self.centers.append(np.mean(polygon_new, axis=0))
213 self.charges.append(0)
214
215 def show_pads(self, plane='xz'):
216 """!
217 # @brief plot polygon
218 # @param plane Select projection plane by str (e.g. 'xz')
219 # @return None
220 """
221 index1 = self.mapping.get(plane[0], 0)
222 index2 = self.mapping.get(plane[1], 0)
223
224 fig=plt.figure(figsize=(6, 5))
225 ax = fig.add_subplot(111)
226 fig.patch.set_alpha(0.)
227
228 for i in range(len(self.pads)):
229 xs = [vertex[index1] for vertex in self.pads[i] ]
230 ys = [vertex[index2] for vertex in self.pads[i] ]
231 ax.fill(xs, ys, edgecolor='black', facecolor='#d3d3d3',lw=0.5)
232
233 ax.set_aspect('equal')
234
235 plt.xlabel(str(plane[0])+" position [mm]")
236 plt.ylabel(str(plane[1])+" position [mm]")
237 plt.show()
238
239def generate_regular_n_polygon(n=3, length=3, theta=0, flag=True):
240 """!
241 @brief generate regular n polygon
242 @param n number of vertex
243 @param length length of daistance between each vertex
244 @param theta rotation angle
245 @param flag plot pad (default:True)
246 @return object of TBasePadShapeClass
247 """
248 base_padinfo = TBasePadShapeClass()
249
250 if n<3:
251 print("n must be greater than 2")
252 else:
253 radius = length / (2 * np.sin(np.pi / n))
254 angles = np.linspace(0, 2 * np.pi, n, endpoint=False)
255 vertices = [(radius * np.cos(angle), radius * np.sin(angle)) for angle in angles]
256
257 theta = np.radians(theta)
258 rotation_matrix = np.array([[np.cos(theta), -np.sin(theta)],[np.sin(theta), np.cos(theta)]])
259 rotated_vertices = [np.dot(rotation_matrix, vertex) for vertex in vertices]
260
261 for i in range(len(vertices)):
262 base_padinfo.add_polygon([rotated_vertices[i][0], 0, rotated_vertices[i][1]])
263
264 if flag:
265 base_padinfo.show_polygon('xz')
266 return base_padinfo
267
268def generate_oblong_4_polygon(longlength=4, shortlength=2, plane='yz', flag=True):
269 """!
270 @brief oblong 4 polygon
271 @param longlength length of long side
272 @param shortlength length of short side
273 @param plane projection plane
274 @param flag plot pad (default:True)
275 @return object of TBasePadShapeClass
276 """
277 base_padinfo = TBasePadShapeClass()
278
279 if plane=='yz' or plane=='zy':
280 base_padinfo.add_polygon([0, shortlength/2, longlength/2])
281 base_padinfo.add_polygon([0, shortlength/2, -longlength/2])
282 base_padinfo.add_polygon([0, -shortlength/2, -longlength/2])
283 base_padinfo.add_polygon([0, -shortlength/2, longlength/2])
284
285 elif plane=='xy' or plane=='xy':
286 base_padinfo.add_polygon([ longlength/2, shortlength/2, 0])
287 base_padinfo.add_polygon([ longlength/2, -shortlength/2, 0])
288 base_padinfo.add_polygon([-longlength/2, -shortlength/2, 0])
289 base_padinfo.add_polygon([-longlength/2, shortlength/2, 0])
290
291 elif plane=='xz' or plane=='xz':
292 base_padinfo.add_polygon([ longlength/2, 0, shortlength/2])
293 base_padinfo.add_polygon([ longlength/2, 0, -shortlength/2])
294 base_padinfo.add_polygon([-longlength/2, 0, -shortlength/2])
295 base_padinfo.add_polygon([-longlength/2, 0, shortlength/2])
296
297 if flag:
298 base_padinfo.show_polygon(plane)
299 return base_padinfo
Generate pad information.
Definition basepad.py:15
pad information array
Definition basepad.py:112
generate_regular_n_polygon(n=3, length=3, theta=0, flag=True)
generate regular n polygon
Definition basepad.py:239
generate_oblong_4_polygon(longlength=4, shortlength=2, plane='yz', flag=True)
oblong 4 polygon
Definition basepad.py:268