itkdb-gtk 0.10.10.dev4__py3-none-any.whl → 0.10.10.dev6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of itkdb-gtk might be problematic. Click here for more details.
- itkdb_gtk/UploadMultipleTests.py +64 -11
- itkdb_gtk/UploadTest.py +5 -4
- itkdb_gtk/VisualInspection.py +272 -0
- itkdb_gtk/WireBondGui.py +296 -148
- itkdb_gtk/__init__.py +6 -6
- itkdb_gtk/dashBoard.py +52 -6
- {itkdb_gtk-0.10.10.dev4.dist-info → itkdb_gtk-0.10.10.dev6.dist-info}/METADATA +1 -1
- {itkdb_gtk-0.10.10.dev4.dist-info → itkdb_gtk-0.10.10.dev6.dist-info}/RECORD +11 -12
- {itkdb_gtk-0.10.10.dev4.dist-info → itkdb_gtk-0.10.10.dev6.dist-info}/WHEEL +1 -1
- {itkdb_gtk-0.10.10.dev4.dist-info → itkdb_gtk-0.10.10.dev6.dist-info}/entry_points.txt +1 -1
- itkdb_gtk/UploadPetalInformation.py +0 -749
- itkdb_gtk/readAVSdata.py +0 -693
- {itkdb_gtk-0.10.10.dev4.dist-info → itkdb_gtk-0.10.10.dev6.dist-info}/top_level.txt +0 -0
itkdb_gtk/WireBondGui.py
CHANGED
|
@@ -6,6 +6,7 @@ import re
|
|
|
6
6
|
import json
|
|
7
7
|
import copy
|
|
8
8
|
from pathlib import Path
|
|
9
|
+
from collections import namedtuple
|
|
9
10
|
import gi
|
|
10
11
|
|
|
11
12
|
gi.require_version("Gtk", "3.0")
|
|
@@ -28,18 +29,6 @@ from itkdb_gtk import ITkDBlogin, ITkDButils, UploadTest
|
|
|
28
29
|
#valid_channel = re.compile("(^[0-9]+)-([0-9]+)")
|
|
29
30
|
valid_channel = re.compile("^[0-9]+[\\s*\\,\\s,-[0-9]+]*")
|
|
30
31
|
|
|
31
|
-
def range_to_list(V):
|
|
32
|
-
"""Convert a range (ch1-ch2) to a list."""
|
|
33
|
-
if '-' not in V:
|
|
34
|
-
return [V]
|
|
35
|
-
|
|
36
|
-
out = []
|
|
37
|
-
endpoints = list(map(int, V.split('-')))
|
|
38
|
-
endpoints.sort()
|
|
39
|
-
for i in range(endpoints[0], endpoints[1]+1):
|
|
40
|
-
out.append(str(i))
|
|
41
|
-
|
|
42
|
-
return out
|
|
43
32
|
|
|
44
33
|
test_parameters = {
|
|
45
34
|
"Repaired Row 1": "REPAIRED_FRONTEND_ROW1",
|
|
@@ -103,21 +92,75 @@ module_param = {
|
|
|
103
92
|
],
|
|
104
93
|
}
|
|
105
94
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
95
|
+
module_to_tf = {
|
|
96
|
+
0: [],
|
|
97
|
+
1: [],
|
|
98
|
+
2: [],
|
|
99
|
+
3: [],
|
|
100
|
+
4: [],
|
|
101
|
+
5: []
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
hyb_to_pb = {
|
|
105
|
+
0: [],
|
|
106
|
+
1: [],
|
|
107
|
+
2: [],
|
|
108
|
+
3: [],
|
|
109
|
+
4: [],
|
|
110
|
+
5: []
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def range_to_list(V):
|
|
115
|
+
"""Convert a range to a list.
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
ch1-ch2 or ch1:ch2 -> [ch1, ch1+1, ch1+2, ..., ch2] or
|
|
118
|
+
ch1:step:ch2 -> [ch1, ch1+sep, ch1+2*step, ..., ch2]
|
|
119
|
+
"""
|
|
120
|
+
nfound = 0
|
|
121
|
+
for c in "-:,":
|
|
122
|
+
if c in V:
|
|
123
|
+
nfound += 1
|
|
124
|
+
break
|
|
125
|
+
|
|
126
|
+
if nfound == 0:
|
|
127
|
+
return [V]
|
|
128
|
+
|
|
129
|
+
out = []
|
|
130
|
+
values = V.split(',')
|
|
131
|
+
for V in values:
|
|
132
|
+
if '-' in V:
|
|
133
|
+
endpoints = list(map(int, V.split('-')))
|
|
134
|
+
endpoints.sort()
|
|
135
|
+
for i in range(endpoints[0], endpoints[1]+1):
|
|
136
|
+
out.append(str(i))
|
|
137
|
+
elif ':' in V:
|
|
138
|
+
endpoints = list(map(int, V.split(':')))
|
|
139
|
+
if len(endpoints) == 2:
|
|
140
|
+
endpoints.sort()
|
|
141
|
+
for i in range(endpoints[0], endpoints[1]+1):
|
|
142
|
+
out.append(str(i))
|
|
143
|
+
|
|
144
|
+
elif len(endpoints) == 3:
|
|
145
|
+
for i in range(endpoints[0], endpoints[2]+1, endpoints[1]):
|
|
146
|
+
out.append(str(i))
|
|
147
|
+
|
|
148
|
+
else:
|
|
149
|
+
print("Wring range specification. {}".format(V))
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
else:
|
|
153
|
+
out.append(V)
|
|
154
|
+
|
|
155
|
+
return out
|
|
118
156
|
|
|
119
|
-
|
|
157
|
+
def count_items(items):
|
|
158
|
+
"""Count number of channels from results."""
|
|
159
|
+
nitems = 0
|
|
160
|
+
for key in items.keys():
|
|
161
|
+
nitems += len(range_to_list(key))
|
|
120
162
|
|
|
163
|
+
return nitems
|
|
121
164
|
|
|
122
165
|
def find_holes(chan_list, min_chan=0, max_chan=999999):
|
|
123
166
|
"""Find groups of consecutive channels."""
|
|
@@ -161,19 +204,41 @@ def find_holes(chan_list, min_chan=0, max_chan=999999):
|
|
|
161
204
|
return holes
|
|
162
205
|
|
|
163
206
|
|
|
207
|
+
def wire2strip(iwire, irow, first_chan):
|
|
208
|
+
"""From bond to strip number."""
|
|
209
|
+
if irow % 2:
|
|
210
|
+
istrip = 2*(iwire-first_chan) + 1
|
|
211
|
+
else:
|
|
212
|
+
istrip = 2*(iwire-first_chan)
|
|
213
|
+
|
|
214
|
+
return istrip
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class Hole:
|
|
218
|
+
"""A range of consecutive unconnected channels."""
|
|
219
|
+
def __init__(self, *args):
|
|
220
|
+
for i, name in enumerate(['sensor', 'hybrid', 'row', 'chan', 'width']):
|
|
221
|
+
setattr(self, name, args[i])
|
|
222
|
+
|
|
223
|
+
def __repr__(self):
|
|
224
|
+
return "sensor: {} hyb: {} row: {} chan: {} width: {}".format(
|
|
225
|
+
self.sensor, self.hybrid, self.row, self.chan, self.width
|
|
226
|
+
)
|
|
227
|
+
|
|
164
228
|
class HybridHoles:
|
|
165
|
-
"""Holes in hybrid
|
|
229
|
+
"""Holes in hybrid bonds.
|
|
166
230
|
|
|
167
231
|
Holes are defined by a list [first_chan, n_chan].
|
|
168
232
|
"""
|
|
169
233
|
|
|
170
|
-
def __init__(self, param, hid=0):
|
|
234
|
+
def __init__(self, param, win=None, hid=0):
|
|
171
235
|
"""Initialization.
|
|
172
236
|
|
|
173
237
|
Args:
|
|
174
238
|
param: Hybrid wirebon parameters.
|
|
175
239
|
|
|
176
240
|
"""
|
|
241
|
+
self.win = win
|
|
177
242
|
self.id = hid
|
|
178
243
|
self.param = param
|
|
179
244
|
self.nchan = 0
|
|
@@ -182,12 +247,25 @@ class HybridHoles:
|
|
|
182
247
|
|
|
183
248
|
self.holes = [[] for irow in range(4)]
|
|
184
249
|
self.channels = [[] for irow in range(4)]
|
|
250
|
+
# Sensor strips for each of the strip rows "served" by a hybrid.
|
|
251
|
+
self.sensor_channels = [[], []]
|
|
252
|
+
self.sensor_holes = [[], []]
|
|
253
|
+
|
|
254
|
+
def ready(self):
|
|
255
|
+
"""Call when all channels are in."""
|
|
256
|
+
for irow, C in enumerate(self.channels):
|
|
257
|
+
C.sort()
|
|
258
|
+
self.holes[irow] = find_holes(C)
|
|
259
|
+
|
|
260
|
+
for irow, S in enumerate(self.sensor_channels):
|
|
261
|
+
S.sort()
|
|
262
|
+
self.sensor_holes[irow] = find_holes(S)
|
|
185
263
|
|
|
186
264
|
def add_channel(self, irow, ichan)->bool:
|
|
187
265
|
"""Add a new channel in row.
|
|
188
266
|
|
|
189
267
|
Args:
|
|
190
|
-
irow:
|
|
268
|
+
irow: row number
|
|
191
269
|
ichan: channel number
|
|
192
270
|
|
|
193
271
|
Returns:
|
|
@@ -196,102 +274,93 @@ class HybridHoles:
|
|
|
196
274
|
"""
|
|
197
275
|
first_chan = self.param[irow][0]
|
|
198
276
|
last_chan = self.param[irow][1]
|
|
277
|
+
strip_row = int(irow/2)
|
|
278
|
+
|
|
279
|
+
|
|
199
280
|
if isinstance(ichan, list) or isinstance(ichan, tuple):
|
|
200
281
|
nadded = 0
|
|
201
282
|
for ich in ichan:
|
|
202
|
-
if
|
|
283
|
+
if first_chan <= ich <= last_chan:
|
|
203
284
|
self.channels[irow].append(ich)
|
|
204
285
|
nadded += 1
|
|
205
286
|
|
|
206
287
|
self.channels[irow] = sorted(self.channels[irow])
|
|
288
|
+
for iwire in self.channels[irow]:
|
|
289
|
+
istrip = wire2strip(iwire, irow, first_chan)
|
|
290
|
+
self.sensor_channels[strip_row].append(istrip)
|
|
291
|
+
|
|
207
292
|
return nadded>0
|
|
208
|
-
else:
|
|
209
|
-
if ichan >= first_chan and ichan <= last_chan:
|
|
210
|
-
self.channels[irow].append(ichan)
|
|
211
|
-
return True
|
|
212
|
-
else:
|
|
213
|
-
return False
|
|
214
293
|
|
|
215
|
-
|
|
294
|
+
if first_chan <= ichan <= last_chan:
|
|
295
|
+
self.channels[irow].append(ichan)
|
|
296
|
+
istrip = wire2strip(ichan, irow, first_chan)
|
|
297
|
+
self.sensor_channels[strip_row].append(istrip)
|
|
298
|
+
return True
|
|
299
|
+
|
|
300
|
+
return False
|
|
301
|
+
|
|
302
|
+
def get_n_unconnected(self) -> list:
|
|
216
303
|
"""Count number of unconnected channels.
|
|
217
304
|
|
|
218
305
|
Return a list, one item per row.
|
|
219
306
|
"""
|
|
220
|
-
nchan = []
|
|
221
|
-
for row in self.holes:
|
|
222
|
-
nch = 0
|
|
223
|
-
for h in row:
|
|
224
|
-
nch += h[1]
|
|
225
|
-
|
|
226
|
-
nchan.append(nch)
|
|
227
|
-
|
|
307
|
+
nchan = [len(C) for C in self.channels]
|
|
228
308
|
return nchan
|
|
229
309
|
|
|
230
|
-
def
|
|
231
|
-
"""
|
|
310
|
+
def get_max_consecutive_from_list(self, holes):
|
|
311
|
+
"""Return max widht of holes."""
|
|
232
312
|
mx_width = []
|
|
313
|
+
lst_holes = []
|
|
314
|
+
for irow, row in enumerate(holes):
|
|
315
|
+
if len(row) == 0:
|
|
316
|
+
mxW = 0
|
|
233
317
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
mxW = h[1]
|
|
318
|
+
else:
|
|
319
|
+
mxW = -1
|
|
320
|
+
for h in row:
|
|
321
|
+
lst_holes.append(Hole(0, self.id, irow, h[0], h[1]))
|
|
322
|
+
mxW = max(mxW, h[1])
|
|
239
323
|
|
|
240
324
|
mx_width.append(mxW)
|
|
241
325
|
|
|
242
|
-
return mx_width
|
|
243
|
-
|
|
244
|
-
def get_sensor_holes(self):
|
|
245
|
-
"""Compute holes in 'sensor' strips.
|
|
246
|
-
|
|
247
|
-
Each hybrid has 2 sensor segments corresponding to
|
|
248
|
-
rows (1,2) and (3, 4).
|
|
326
|
+
return mx_width, lst_holes
|
|
249
327
|
|
|
250
|
-
Return a list of [sensor, hybrid, segment, ichan, width]
|
|
251
|
-
"""
|
|
252
|
-
holes = []
|
|
253
|
-
channels = [[], []]
|
|
254
|
-
for irow, row in enumerate(self.channels):
|
|
255
|
-
isegment = int(irow/2)
|
|
256
|
-
for ich in row:
|
|
257
|
-
rng = self.param[irow]
|
|
258
|
-
if irow % 2:
|
|
259
|
-
chan = 2*(ich-rng[0]) + 1
|
|
260
|
-
else:
|
|
261
|
-
chan = 2*(ich-rng[0])
|
|
262
|
-
|
|
263
|
-
channels[isegment].append(chan)
|
|
264
328
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
if len(H)>0:
|
|
270
|
-
out = [ [0, self.id, isegment, chan, width] for chan, width in H ]
|
|
271
|
-
holes.extend(out)
|
|
272
|
-
|
|
273
|
-
return holes
|
|
329
|
+
def get_max_consecutive(self):
|
|
330
|
+
"""Returns the largest 'hole'."""
|
|
331
|
+
mx_width, _ = self.get_max_consecutive_from_list(self.holes)
|
|
332
|
+
return mx_width
|
|
274
333
|
|
|
334
|
+
def get_max_sensor_consecutive(self):
|
|
335
|
+
"""Return largest hole in sensor."""
|
|
336
|
+
mx_width, holes = self.get_max_consecutive_from_list(self.sensor_holes)
|
|
337
|
+
return mx_width, holes
|
|
275
338
|
|
|
276
339
|
class SensorHoles:
|
|
277
340
|
"""Holes in sensor."""
|
|
278
341
|
|
|
279
|
-
def __init__(self, param, sid=0):
|
|
342
|
+
def __init__(self, param, win=None, sid=0):
|
|
280
343
|
"""Initialization.
|
|
281
344
|
|
|
282
345
|
Args:
|
|
283
346
|
param: sensor wirebon params
|
|
284
347
|
"""
|
|
348
|
+
self.win = win
|
|
285
349
|
self.id = sid
|
|
286
350
|
self.param = param
|
|
287
351
|
self.nchan = 0
|
|
288
352
|
self.nhybrid = len(param)
|
|
289
353
|
self.hybrids = []
|
|
290
354
|
for i, P in enumerate(param):
|
|
291
|
-
H = HybridHoles(P, hid=i)
|
|
355
|
+
H = HybridHoles(P, hid=i, win=win)
|
|
292
356
|
self.hybrids.append(H)
|
|
293
357
|
self.nchan += H.nchan
|
|
294
358
|
|
|
359
|
+
def ready(self):
|
|
360
|
+
"""Call when all channels are in."""
|
|
361
|
+
for H in self.hybrids:
|
|
362
|
+
H.ready()
|
|
363
|
+
|
|
295
364
|
def get_n_hyb(self):
|
|
296
365
|
"""Return number of hybrids."""
|
|
297
366
|
return len(self.hybrids)
|
|
@@ -305,15 +374,29 @@ class SensorHoles:
|
|
|
305
374
|
|
|
306
375
|
This is ordered by row.
|
|
307
376
|
"""
|
|
308
|
-
mx_width = [0
|
|
377
|
+
mx_width = [0 for x in range(4)]
|
|
309
378
|
for hyb in self.hybrids:
|
|
310
379
|
mxW = hyb.get_max_consecutive()
|
|
311
|
-
for j in
|
|
312
|
-
|
|
313
|
-
mx_width[j] = mxW[j]
|
|
380
|
+
for j, val in enumerate(mxW):
|
|
381
|
+
mx_width[j] = max(mx_width[j] , val)
|
|
314
382
|
|
|
315
383
|
return mx_width
|
|
316
384
|
|
|
385
|
+
def get_max_sensor_consecutive(self):
|
|
386
|
+
"""MAx widht of holes in sensor."""
|
|
387
|
+
mx_width = -1
|
|
388
|
+
holes = []
|
|
389
|
+
for hyb in self.hybrids:
|
|
390
|
+
mxW, hyb_holes = hyb.get_max_sensor_consecutive()
|
|
391
|
+
for H in hyb_holes:
|
|
392
|
+
H.sensor = self.id
|
|
393
|
+
|
|
394
|
+
holes.extend(hyb_holes)
|
|
395
|
+
for v in mxW:
|
|
396
|
+
mx_width = max(mx_width, v)
|
|
397
|
+
|
|
398
|
+
return mx_width, holes
|
|
399
|
+
|
|
317
400
|
def get_n_unconnected(self):
|
|
318
401
|
"""Count number of unconnected channels.
|
|
319
402
|
|
|
@@ -327,37 +410,30 @@ class SensorHoles:
|
|
|
327
410
|
|
|
328
411
|
return nchan
|
|
329
412
|
|
|
330
|
-
def get_sensor_holes(self):
|
|
331
|
-
"""Return holes sensor.
|
|
332
|
-
|
|
333
|
-
Return a list of [sensor, hybrid, segment, ichan, width]
|
|
334
|
-
"""
|
|
335
|
-
holes = []
|
|
336
|
-
for hyb in self.hybrids:
|
|
337
|
-
H = hyb.get_sensor_holes()
|
|
338
|
-
for _, ih, isegment, ichan, width in H:
|
|
339
|
-
holes.append([self.id, ih, isegment, ichan, width])
|
|
340
|
-
|
|
341
|
-
return holes
|
|
342
|
-
|
|
343
413
|
|
|
344
414
|
class ModuleHoles:
|
|
345
415
|
"""Holes in Modules."""
|
|
346
416
|
|
|
347
|
-
def __init__(self, param):
|
|
417
|
+
def __init__(self, param, win=None):
|
|
348
418
|
"""Initialization.
|
|
349
419
|
|
|
350
420
|
Args:
|
|
351
421
|
param: module wirebond params
|
|
352
422
|
"""
|
|
423
|
+
self.win = win
|
|
353
424
|
self.nsensor = len(param)
|
|
354
425
|
self.nchan = 0
|
|
355
426
|
self.sensors = []
|
|
356
427
|
for i, P in enumerate(param):
|
|
357
|
-
S = SensorHoles(P, sid=i)
|
|
428
|
+
S = SensorHoles(P, sid=i, win=win)
|
|
358
429
|
self.sensors.append(S)
|
|
359
430
|
self.nchan += S.nchan
|
|
360
431
|
|
|
432
|
+
def ready(self):
|
|
433
|
+
"""Call when all channels are in."""
|
|
434
|
+
for S in self.sensors:
|
|
435
|
+
S.ready()
|
|
436
|
+
|
|
361
437
|
def get_max_consecutive(self):
|
|
362
438
|
"""Max number of consecutive unconnected channels.
|
|
363
439
|
|
|
@@ -367,22 +443,21 @@ class ModuleHoles:
|
|
|
367
443
|
for S in self.sensors:
|
|
368
444
|
mxW = S.get_max_consecutive()
|
|
369
445
|
for j in range(4):
|
|
370
|
-
|
|
371
|
-
mx_width[j] = mxW[j]
|
|
446
|
+
mx_width[j] = max(mx_width[j], mxW[j])
|
|
372
447
|
|
|
373
448
|
return mx_width
|
|
374
449
|
|
|
375
|
-
def
|
|
376
|
-
"""
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
"""
|
|
380
|
-
holes = []
|
|
450
|
+
def get_max_sensor_consecutive(self):
|
|
451
|
+
"""The maximum number of consecutive channels per strip row."""
|
|
452
|
+
mx_width = -1
|
|
453
|
+
module_holes = []
|
|
381
454
|
for S in self.sensors:
|
|
382
|
-
|
|
383
|
-
|
|
455
|
+
width, holes = S.get_max_sensor_consecutive()
|
|
456
|
+
module_holes.extend(holes)
|
|
457
|
+
mx_width = max(mx_width, width)
|
|
458
|
+
|
|
459
|
+
return mx_width, module_holes
|
|
384
460
|
|
|
385
|
-
return holes
|
|
386
461
|
|
|
387
462
|
def get_n_unconnected(self) -> list:
|
|
388
463
|
"""Count number of unconnected channels.
|
|
@@ -575,12 +650,35 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
575
650
|
lut = {}
|
|
576
651
|
module_map = {}
|
|
577
652
|
section = None
|
|
653
|
+
i_local = 0
|
|
654
|
+
i_std = 1
|
|
655
|
+
indx = ["local", "standard"]
|
|
656
|
+
found_format = False
|
|
578
657
|
with open(fnam, 'r', encoding="UTF-8") as fin:
|
|
579
658
|
for line in fin:
|
|
580
659
|
line = line.strip()
|
|
581
660
|
|
|
582
661
|
# Remove comments.
|
|
583
662
|
ipos = line.find('#')
|
|
663
|
+
jpos = line.find("#!")
|
|
664
|
+
if jpos>=0 and ipos==jpos:
|
|
665
|
+
if found_format:
|
|
666
|
+
dbGtkUtils.complain("A second format line was found.",
|
|
667
|
+
"Onely one is allowed. stopr map parsing.")
|
|
668
|
+
return
|
|
669
|
+
|
|
670
|
+
indx = [x.lower() for x in line[ipos+2:].split()]
|
|
671
|
+
try:
|
|
672
|
+
i_local = indx.index("local")
|
|
673
|
+
i_std = indx.index("standard")
|
|
674
|
+
found_format = True
|
|
675
|
+
except ValueError:
|
|
676
|
+
dbGtkUtils.complain("Wrong format desciption string.",
|
|
677
|
+
"The words 'local' and 'standard' should be there.\n{}".format(line))
|
|
678
|
+
return
|
|
679
|
+
|
|
680
|
+
continue
|
|
681
|
+
|
|
584
682
|
if ipos >= 0:
|
|
585
683
|
line = line[:ipos].strip()
|
|
586
684
|
|
|
@@ -602,13 +700,13 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
602
700
|
if section is None:
|
|
603
701
|
continue
|
|
604
702
|
|
|
605
|
-
values =
|
|
606
|
-
if len(values)!=
|
|
703
|
+
values = line.split()
|
|
704
|
+
if len(values)!=len(indx):
|
|
607
705
|
dbGtkUtils.complain("Cannot read Lookup table.", "Wrong line format: {}".format(line))
|
|
608
706
|
return
|
|
609
707
|
|
|
610
|
-
v_local = range_to_list(values[
|
|
611
|
-
v_std = range_to_list(values[
|
|
708
|
+
v_local = range_to_list(values[i_local])
|
|
709
|
+
v_std = range_to_list(values[i_std])
|
|
612
710
|
|
|
613
711
|
if len(v_local) != len(v_std):
|
|
614
712
|
dbGtkUtils.complain("Wrong Lookup table.",
|
|
@@ -669,7 +767,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
669
767
|
view_model = self.models[param]
|
|
670
768
|
self.tree.set_model(view_model)
|
|
671
769
|
else:
|
|
672
|
-
self.write_message("Cannot find model for {}".format(param))
|
|
770
|
+
self.write_message("Cannot find model for {}\n".format(param))
|
|
673
771
|
|
|
674
772
|
def create_combo(self):
|
|
675
773
|
"""Create the combo."""
|
|
@@ -813,7 +911,42 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
813
911
|
self.hide()
|
|
814
912
|
self.destroy()
|
|
815
913
|
|
|
816
|
-
def
|
|
914
|
+
def compute_repaired(self, skeleton):
|
|
915
|
+
"""Compute number of repaired."""
|
|
916
|
+
nrepaired = 0
|
|
917
|
+
for key, values in skeleton["results"].items():
|
|
918
|
+
if key.find("REPAIRED")<0 or key.find("ROW")<0:
|
|
919
|
+
continue
|
|
920
|
+
|
|
921
|
+
nrepaired += len(values)
|
|
922
|
+
|
|
923
|
+
if nrepaired>0:
|
|
924
|
+
skeleton["problems"] = True
|
|
925
|
+
skeleton["comments"].append("Number of repaired FE bonds: {}".format(nrepaired))
|
|
926
|
+
|
|
927
|
+
return nrepaired
|
|
928
|
+
|
|
929
|
+
def compute_hybrid_to_pb(self, skeleton):
|
|
930
|
+
"""Compute number of failures and repairs."""
|
|
931
|
+
n = count_items(skeleton["results"]["REPAIRED_HYBRID_TO_PB"])
|
|
932
|
+
n = count_items(skeleton["results"]["FAILED_HYBRID_TO_PB"])
|
|
933
|
+
if n:
|
|
934
|
+
msg = "Hybrid to PB: {} failing bonds.".format(n)
|
|
935
|
+
skeleton["comments"].append(msg)
|
|
936
|
+
skeleton["passed"] = False
|
|
937
|
+
self.write_message("{}\n".format(msg))
|
|
938
|
+
|
|
939
|
+
def compute_module_to_frame(self, skeleton):
|
|
940
|
+
"""Compute number of failures and repairs."""
|
|
941
|
+
n = count_items(skeleton["results"]["REPAIRED_MODULE_TO_FRAME"])
|
|
942
|
+
n = count_items(skeleton["results"]["FAILED_MODULE_TO_FRAME"])
|
|
943
|
+
if n:
|
|
944
|
+
msg = "Module to test frame: {} failing bonds.".format(n)
|
|
945
|
+
skeleton["comments"].append(msg)
|
|
946
|
+
skeleton["passed"] = False
|
|
947
|
+
self.write_message("{}\n".format(msg))
|
|
948
|
+
|
|
949
|
+
def compute_unconnected(self, results):
|
|
817
950
|
"""Compute number of unconnected."""
|
|
818
951
|
try:
|
|
819
952
|
param = get_module_param(self.SN.get_text())
|
|
@@ -821,9 +954,9 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
821
954
|
dbGtkUtils.complain("Wrong SN number", str(E))
|
|
822
955
|
return None
|
|
823
956
|
|
|
824
|
-
M = ModuleHoles(param=param)
|
|
957
|
+
M = ModuleHoles(param=param, win=self)
|
|
825
958
|
|
|
826
|
-
for test in
|
|
959
|
+
for test, values in results.items():
|
|
827
960
|
if test.find("FAILED") < 0:
|
|
828
961
|
continue
|
|
829
962
|
if test.find("ROW") < 0:
|
|
@@ -832,16 +965,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
832
965
|
irow = int(test[-1]) - 1
|
|
833
966
|
|
|
834
967
|
# Get list of all channels with wirebond notation.
|
|
835
|
-
|
|
836
|
-
it = model.get_iter_first()
|
|
837
|
-
out = []
|
|
838
|
-
while it:
|
|
839
|
-
chan, _ = model[it]
|
|
840
|
-
if len(chan) > 0:
|
|
841
|
-
out.append(int(chan))
|
|
842
|
-
|
|
843
|
-
it = model.iter_next(it)
|
|
844
|
-
|
|
968
|
+
out = [int(x) for x in values.keys()]
|
|
845
969
|
# Translate to sensor, hybrids, etc.
|
|
846
970
|
for S in M.sensors:
|
|
847
971
|
for H in S.hybrids:
|
|
@@ -850,41 +974,66 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
850
974
|
|
|
851
975
|
|
|
852
976
|
# Now get sensor strips.
|
|
977
|
+
M.ready()
|
|
853
978
|
unconnected = M.get_n_unconnected()
|
|
854
979
|
mx_consecutive = M.get_max_consecutive()
|
|
855
|
-
module_holes = M.
|
|
980
|
+
mx_sensor_width, module_holes = M.get_max_sensor_consecutive()
|
|
856
981
|
|
|
857
982
|
out = {}
|
|
983
|
+
out["comments"] = []
|
|
984
|
+
out["defects"] = []
|
|
858
985
|
for irow in range(4):
|
|
859
986
|
key = "MAX_CONT_UNCON_ROW{}".format(irow+1)
|
|
860
987
|
out[key] = mx_consecutive[irow]
|
|
861
988
|
|
|
862
|
-
mxW = 0
|
|
863
989
|
self.write_message("Found {} clusters of unconnected strips in sensor.\n".format(len(module_holes)))
|
|
864
990
|
for H in module_holes:
|
|
865
|
-
self.write_message("{}\n".format(
|
|
866
|
-
|
|
867
|
-
|
|
991
|
+
self.write_message("{}\n".format(H))
|
|
992
|
+
|
|
993
|
+
if mx_sensor_width > 0:
|
|
994
|
+
self.write_message("Max width of consecutive unconnected strips: {}\n". format(mx_sensor_width))
|
|
868
995
|
|
|
869
|
-
|
|
870
|
-
|
|
996
|
+
out["MAX_UNCON_SENSOR_CHAN"] = mx_sensor_width
|
|
997
|
+
if mx_sensor_width > 8:
|
|
998
|
+
out["passed"] = False
|
|
999
|
+
out["comments"].append("Too many consecutive sensor strips unconnected: {}".format(mx_sensor_width))
|
|
871
1000
|
|
|
872
|
-
out["MAX_UNCON_SENSOR_CHAN"] = mxW
|
|
873
1001
|
nstrips = 0
|
|
874
1002
|
for v in unconnected:
|
|
875
1003
|
nstrips += v
|
|
876
1004
|
|
|
877
|
-
|
|
1005
|
+
percent = 100*nstrips/M.nchan
|
|
1006
|
+
out["TOTAL_PERC_UNCON_SENSOR_CHAN"] = percent
|
|
1007
|
+
if out["TOTAL_PERC_UNCON_SENSOR_CHAN"] > 1.0:
|
|
1008
|
+
out["passed"] = False
|
|
1009
|
+
out["comments"].append("More than 1%% of channels unconnected: {:.1f}%%".format(percent))
|
|
878
1010
|
|
|
879
1011
|
return out
|
|
880
1012
|
|
|
881
1013
|
def get_unconnected(self, skeleton):
|
|
882
1014
|
"""Fill the test DTO with unconnected information."""
|
|
883
|
-
out = self.compute_unconnected()
|
|
1015
|
+
out = self.compute_unconnected(skeleton["results"])
|
|
884
1016
|
if out is None:
|
|
885
1017
|
raise ValueError("Wrong SN")
|
|
886
1018
|
|
|
887
1019
|
for key, val in out.items():
|
|
1020
|
+
if key in ["passed", "problems"]:
|
|
1021
|
+
skeleton[key] = out[key]
|
|
1022
|
+
continue
|
|
1023
|
+
|
|
1024
|
+
if key == "comments":
|
|
1025
|
+
for C in out[key]:
|
|
1026
|
+
skeleton[key].append(C)
|
|
1027
|
+
|
|
1028
|
+
continue
|
|
1029
|
+
|
|
1030
|
+
if key == "defects":
|
|
1031
|
+
for D in out[key]:
|
|
1032
|
+
skeleton[key].append(D)
|
|
1033
|
+
|
|
1034
|
+
continue
|
|
1035
|
+
|
|
1036
|
+
|
|
888
1037
|
skeleton["results"][key] = val
|
|
889
1038
|
|
|
890
1039
|
def read_file(self, *args):
|
|
@@ -921,7 +1070,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
921
1070
|
try:
|
|
922
1071
|
dbGtkUtils.set_combo_iter(self.inst_combo, data["institution"])
|
|
923
1072
|
except KeyError:
|
|
924
|
-
self.write_message("institution value is not in the loaded file.")
|
|
1073
|
+
self.write_message("institution value is not in the loaded file\n.")
|
|
925
1074
|
|
|
926
1075
|
self.operator.set_text(data["properties"]["OPERATOR"])
|
|
927
1076
|
self.machine.set_text(data["properties"]["BOND_MACHINE"])
|
|
@@ -971,12 +1120,8 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
971
1120
|
continue
|
|
972
1121
|
|
|
973
1122
|
for V in values:
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
added_items.append((str(i), comment))
|
|
977
|
-
|
|
978
|
-
elif len(V)>0:
|
|
979
|
-
added_items.append((V, comment))
|
|
1123
|
+
for i in range_to_list(V):
|
|
1124
|
+
added_items.append((str(i), comment))
|
|
980
1125
|
|
|
981
1126
|
for key in range_items:
|
|
982
1127
|
section.pop(key)
|
|
@@ -1052,7 +1197,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
1052
1197
|
if len(values) == 4:
|
|
1053
1198
|
SN, operator, machine = values
|
|
1054
1199
|
else:
|
|
1055
|
-
self.write_message("Something went wrong while requesting missing information
|
|
1200
|
+
self.write_message("Something went wrong while requesting missing information.\n")
|
|
1056
1201
|
|
|
1057
1202
|
data["component"] = SN
|
|
1058
1203
|
data["properties"]["OPERATOR"] = operator
|
|
@@ -1090,6 +1235,9 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
1090
1235
|
self.fix_list_of_channels(skeleton)
|
|
1091
1236
|
try:
|
|
1092
1237
|
self.get_unconnected(skeleton)
|
|
1238
|
+
self.compute_repaired(skeleton)
|
|
1239
|
+
self.compute_hybrid_to_pb(skeleton)
|
|
1240
|
+
self.compute_module_to_frame(skeleton)
|
|
1093
1241
|
|
|
1094
1242
|
except ValueError:
|
|
1095
1243
|
return
|