itkdb-gtk 0.10.10.dev4__tar.gz → 0.10.10.dev5__tar.gz
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-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/PKG-INFO +1 -1
- itkdb_gtk-0.10.10.dev5/itkdb_gtk/ModuleVisualInspection.py +247 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/UploadMultipleTests.py +53 -9
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/UploadTest.py +5 -4
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/WireBondGui.py +252 -147
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/__init__.py +6 -1
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/dashBoard.py +28 -6
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk.egg-info/PKG-INFO +1 -1
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk.egg-info/SOURCES.txt +1 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk.egg-info/entry_points.txt +1 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/pyproject.toml +2 -1
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/README.md +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/CreateShipments.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/GetShipments.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/GlueWeight.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/ITkDB.desktop +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/ITkDB.svg +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/ITkDBlogin.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/ITkDButils.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/PanelVisualInspection.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/PetalReceptionTests.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/SensorUtils.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/ShowAttachments.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/ShowComments.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/ShowDefects.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/UploadModuleIV.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/UploadPetalInformation.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/dbGtkUtils.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/readAVSdata.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/readGoogleSheet.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk/untrash_component.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk.egg-info/dependency_links.txt +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk.egg-info/requires.txt +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/itkdb_gtk.egg-info/top_level.txt +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/setup.cfg +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/test/testAnimated.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/test/testBatch.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/test/testComponent.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/test/test_attachment.py +0 -0
- {itkdb_gtk-0.10.10.dev4 → itkdb_gtk-0.10.10.dev5}/test/test_holes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: itkdb_gtk
|
|
3
|
-
Version: 0.10.10.
|
|
3
|
+
Version: 0.10.10.dev5
|
|
4
4
|
Summary: A collection of Gtk based GUI to access ITkDB.
|
|
5
5
|
Author-email: Carlos Lacasta <carlos.lacasta@cern.ch>
|
|
6
6
|
Project-URL: Homepage, https://gitlab.cern.ch/atlas-itk/sw/db/itk-pdb-gtk-gui-utils
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Module Visual inspection GUI."""
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
import itkdb_gtk
|
|
8
|
+
|
|
9
|
+
except ImportError:
|
|
10
|
+
cwd = Path(__file__).parent.parent
|
|
11
|
+
sys.path.append(cwd.as_posix())
|
|
12
|
+
|
|
13
|
+
from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
|
|
14
|
+
from itkdb_gtk.ShowComments import ShowComments
|
|
15
|
+
from itkdb_gtk.ShowDefects import ShowDefects
|
|
16
|
+
from itkdb_gtk.ShowAttachments import ShowAttachments
|
|
17
|
+
from itkdb_gtk.UploadTest import UploadTest
|
|
18
|
+
|
|
19
|
+
import gi
|
|
20
|
+
gi.require_version("Gtk", "3.0")
|
|
21
|
+
from gi.repository import Gtk, Gio
|
|
22
|
+
|
|
23
|
+
HELP_LINK="https://itkdb-gtk.docs.cern.ch/moduleVisualInspection.html"
|
|
24
|
+
|
|
25
|
+
class ModuleVisualInspection(dbGtkUtils.ITkDBWindow):
|
|
26
|
+
"""Module Visual Inspection."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, session, title="Module Visual Inspection", help_link=HELP_LINK):
|
|
29
|
+
super().__init__(title=title,
|
|
30
|
+
session=session,
|
|
31
|
+
show_search="Find object with given SN.",
|
|
32
|
+
help_link=help_link)
|
|
33
|
+
|
|
34
|
+
self.institute = self.pdb_user["institutions"][0]["code"]
|
|
35
|
+
self.global_image = None
|
|
36
|
+
self.global_link = None
|
|
37
|
+
self.data = None
|
|
38
|
+
self.attachments = []
|
|
39
|
+
self.comments = []
|
|
40
|
+
self.defects = []
|
|
41
|
+
|
|
42
|
+
# action button in header
|
|
43
|
+
button = Gtk.Button()
|
|
44
|
+
icon = Gio.ThemedIcon(name="document-send-symbolic")
|
|
45
|
+
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
46
|
+
button.add(image)
|
|
47
|
+
button.set_tooltip_text("Click to upload the test.")
|
|
48
|
+
button.connect("clicked", self.upload_test)
|
|
49
|
+
self.hb.pack_end(button)
|
|
50
|
+
|
|
51
|
+
grid = Gtk.Grid(column_spacing=5, row_spacing=5)
|
|
52
|
+
self.mainBox.pack_start(grid, False, False, 5)
|
|
53
|
+
|
|
54
|
+
irow = 0
|
|
55
|
+
receiver = self.create_institute_combo(only_user=True)
|
|
56
|
+
receiver.connect("changed", self.on_institute)
|
|
57
|
+
receiver.set_tooltip_text("Select the Institute making the test.")
|
|
58
|
+
dbGtkUtils.set_combo_iter(receiver, self.institute)
|
|
59
|
+
|
|
60
|
+
lbl = Gtk.Label(label="Institute")
|
|
61
|
+
lbl.set_xalign(0)
|
|
62
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
63
|
+
grid.attach(receiver, 1, irow, 1, 1)
|
|
64
|
+
|
|
65
|
+
irow += 1
|
|
66
|
+
lbl = Gtk.Label(label="Serial Number")
|
|
67
|
+
lbl.set_xalign(0)
|
|
68
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
69
|
+
|
|
70
|
+
self.SN = dbGtkUtils.TextEntry(small=True)
|
|
71
|
+
self.SN.connect("text_changed", self.SN_ready)
|
|
72
|
+
self.SN.widget.set_tooltip_text("Enter SN of module.")
|
|
73
|
+
grid.attach(self.SN.widget, 1, irow, 1, 1)
|
|
74
|
+
|
|
75
|
+
irow += 1
|
|
76
|
+
lbl = Gtk.Label(label="Date")
|
|
77
|
+
lbl.set_xalign(0)
|
|
78
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
79
|
+
|
|
80
|
+
self.date = dbGtkUtils.TextEntry(small=True)
|
|
81
|
+
grid.attach(self.date.widget, 1, irow, 1, 1)
|
|
82
|
+
self.date.entry.set_text(ITkDButils.get_db_date())
|
|
83
|
+
self.date.connect("text_changed", self.new_date)
|
|
84
|
+
|
|
85
|
+
irow +=1
|
|
86
|
+
self.passed = Gtk.Switch()
|
|
87
|
+
self.passed.props.halign = Gtk.Align.START
|
|
88
|
+
self.passed.set_active(True)
|
|
89
|
+
lbl = Gtk.Label(label="Passed")
|
|
90
|
+
lbl.set_xalign(0)
|
|
91
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
92
|
+
grid.attach(self.passed, 1, irow, 1, 1)
|
|
93
|
+
|
|
94
|
+
irow +=1
|
|
95
|
+
self.problems = Gtk.Switch()
|
|
96
|
+
self.problems.props.halign = Gtk.Align.START
|
|
97
|
+
self.problems.set_active(False)
|
|
98
|
+
lbl = Gtk.Label(label="Problems")
|
|
99
|
+
lbl.set_xalign(0)
|
|
100
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
101
|
+
grid.attach(self.problems, 1, irow, 1, 1)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# The "Add attachment" button.
|
|
105
|
+
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
106
|
+
self.mainBox.pack_start(box, False, False, 0)
|
|
107
|
+
self.btn_attch = dbGtkUtils.add_button_to_container(box, "Attachments",
|
|
108
|
+
"Click to edit attachments.",
|
|
109
|
+
self.edit_attachments)
|
|
110
|
+
|
|
111
|
+
self.btn_comments = dbGtkUtils.add_button_to_container(box, "Comments",
|
|
112
|
+
"Click to edit comments.",
|
|
113
|
+
self.edit_comments)
|
|
114
|
+
|
|
115
|
+
self.btn_defects = dbGtkUtils.add_button_to_container(box, "Defects",
|
|
116
|
+
"Click to edit defects.",
|
|
117
|
+
self.edit_defects)
|
|
118
|
+
|
|
119
|
+
self.mainBox.pack_start(self.message_panel.frame, True, True, 5)
|
|
120
|
+
self.write_message("Module Visual Inspection\n")
|
|
121
|
+
self.show_all()
|
|
122
|
+
|
|
123
|
+
dbGtkUtils.setup_scanner(self.get_qrcode)
|
|
124
|
+
|
|
125
|
+
def on_institute(self, combo):
|
|
126
|
+
"""A new recipient has been chosen."""
|
|
127
|
+
name = self.get_institute_from_combo(combo)
|
|
128
|
+
if name:
|
|
129
|
+
self.institute = name
|
|
130
|
+
|
|
131
|
+
def new_date(self, entry, value):
|
|
132
|
+
"""new date given at input."""
|
|
133
|
+
d = dbGtkUtils.parse_date_as_string(value)
|
|
134
|
+
if d is not None:
|
|
135
|
+
self.date.set_text(d)
|
|
136
|
+
|
|
137
|
+
def SN_ready(self, *args):
|
|
138
|
+
"""SN is ready in the TextEnttry."""
|
|
139
|
+
SN = self.SN.get_text()
|
|
140
|
+
# GEt children.
|
|
141
|
+
module = ITkDButils.get_DB_component(self.session, SN)
|
|
142
|
+
if module is None:
|
|
143
|
+
self.write_message(ITkDButils.get_db_response())
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
SN = module["serialNumber"]
|
|
147
|
+
args[0].set_text(SN)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def edit_attachments(self, *args):
|
|
151
|
+
"""Edit test attachmetns."""
|
|
152
|
+
SA = ShowAttachments("Test Attachments", self.session, self.attachments, parent=self)
|
|
153
|
+
response = SA.run()
|
|
154
|
+
if response == Gtk.ResponseType.OK:
|
|
155
|
+
self.attachments = SA.attachments
|
|
156
|
+
|
|
157
|
+
SA.hide()
|
|
158
|
+
SA.destroy()
|
|
159
|
+
|
|
160
|
+
if len(self.attachments) > 0:
|
|
161
|
+
self.btn_attch.set_label("Attachments ({})".format(len(self.attachments)))
|
|
162
|
+
|
|
163
|
+
def edit_comments(self, *args):
|
|
164
|
+
"""Edit test comments."""
|
|
165
|
+
SC = ShowComments("Test Comments", self.comments, self)
|
|
166
|
+
rc = SC.run()
|
|
167
|
+
if rc == Gtk.ResponseType.OK:
|
|
168
|
+
self.comments = SC.comments
|
|
169
|
+
|
|
170
|
+
SC.hide()
|
|
171
|
+
SC.destroy()
|
|
172
|
+
|
|
173
|
+
if len(self.comments) > 0:
|
|
174
|
+
self.btn_comments.set_label("Comments ({})".format(len(self.comments)))
|
|
175
|
+
|
|
176
|
+
def edit_defects(self, *args):
|
|
177
|
+
"""Edit test defects."""
|
|
178
|
+
SD = ShowDefects("Test Defects", self.defects, self)
|
|
179
|
+
rc = SD.run()
|
|
180
|
+
if rc == Gtk.ResponseType.OK:
|
|
181
|
+
self.defects = SD.defects
|
|
182
|
+
|
|
183
|
+
SD.hide()
|
|
184
|
+
SD.destroy()
|
|
185
|
+
|
|
186
|
+
if len(self.defects) > 0:
|
|
187
|
+
self.btn_defects.set_label("Defects ({})".format(len(self.defects)))
|
|
188
|
+
|
|
189
|
+
def upload_test(self, *args):
|
|
190
|
+
"""Upload the test."""
|
|
191
|
+
SN = self.SN.get_text()
|
|
192
|
+
if len(SN) == 0:
|
|
193
|
+
dbGtkUtils.complain("Invalid Serial Number", SN)
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
defaults = {
|
|
197
|
+
"component": SN,
|
|
198
|
+
"institution": self.institute,
|
|
199
|
+
"passed": self.passed.get_active(),
|
|
200
|
+
"problems": self.problems.get_active(),
|
|
201
|
+
"runNumber": "1",
|
|
202
|
+
"date": self.date.get_text()
|
|
203
|
+
}
|
|
204
|
+
self.data = ITkDButils.get_test_skeleton(self.session,
|
|
205
|
+
"MODULE",
|
|
206
|
+
"VISUAL_INSPECTION",
|
|
207
|
+
defaults)
|
|
208
|
+
|
|
209
|
+
self.data["comments"] = self.comments
|
|
210
|
+
self.data["defects"] = self.defects
|
|
211
|
+
uploadW = UploadTest(self.session, self.data, self.attachments)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def get_qrcode(self, fd, state, reader):
|
|
216
|
+
"""Read SN from scanner."""
|
|
217
|
+
txt = dbGtkUtils.scanner_get_line(reader)
|
|
218
|
+
self.write_message("SN: {}\n".format(txt))
|
|
219
|
+
self.SN_ready(txt, self.SN.widget)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def main():
|
|
223
|
+
"""Main entry."""
|
|
224
|
+
# DB login
|
|
225
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
226
|
+
client = dlg.get_client()
|
|
227
|
+
if client is None:
|
|
228
|
+
print("Could not connect to DB with provided credentials.")
|
|
229
|
+
dlg.die()
|
|
230
|
+
sys.exit()
|
|
231
|
+
|
|
232
|
+
client.user_gui = dlg
|
|
233
|
+
|
|
234
|
+
gTest = ModuleVisualInspection(client)
|
|
235
|
+
|
|
236
|
+
gTest.present()
|
|
237
|
+
gTest.connect("destroy", Gtk.main_quit)
|
|
238
|
+
try:
|
|
239
|
+
Gtk.main()
|
|
240
|
+
|
|
241
|
+
except KeyboardInterrupt:
|
|
242
|
+
print("Arrrgggg!!!")
|
|
243
|
+
|
|
244
|
+
dlg.die()
|
|
245
|
+
|
|
246
|
+
if __name__ == "__main__":
|
|
247
|
+
main()
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""GUI to upload tests."""
|
|
3
|
-
import argparse
|
|
4
3
|
import fnmatch
|
|
5
4
|
import json
|
|
6
5
|
import os
|
|
@@ -64,7 +63,26 @@ def all_files(root, patterns='*', single_level=False, yield_folders=False):
|
|
|
64
63
|
|
|
65
64
|
|
|
66
65
|
class TestList(object):
|
|
67
|
-
|
|
66
|
+
"""Enumeration with TreeView model columns."""
|
|
67
|
+
(
|
|
68
|
+
SN,
|
|
69
|
+
TestType,
|
|
70
|
+
RunNumber,
|
|
71
|
+
Date,
|
|
72
|
+
Institute,
|
|
73
|
+
Stage,
|
|
74
|
+
currentStage,
|
|
75
|
+
Path,
|
|
76
|
+
Json,
|
|
77
|
+
Nattch,
|
|
78
|
+
Attachments,
|
|
79
|
+
Ncomm,
|
|
80
|
+
Comments,
|
|
81
|
+
Ndef,
|
|
82
|
+
Defects,
|
|
83
|
+
Color,
|
|
84
|
+
ALL,
|
|
85
|
+
) = range(17)
|
|
68
86
|
|
|
69
87
|
|
|
70
88
|
def check_data(data):
|
|
@@ -113,6 +131,7 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
113
131
|
self.tests = []
|
|
114
132
|
self.data = None
|
|
115
133
|
self.tree = None
|
|
134
|
+
self.def_color = None
|
|
116
135
|
|
|
117
136
|
self.init_window()
|
|
118
137
|
|
|
@@ -174,7 +193,23 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
174
193
|
|
|
175
194
|
def create_tree_view(self, size=150):
|
|
176
195
|
"""Creates the tree vew with the attachments."""
|
|
177
|
-
model = Gtk.ListStore(str,
|
|
196
|
+
model = Gtk.ListStore(str, # SN
|
|
197
|
+
str, # test type
|
|
198
|
+
str, # runNumber
|
|
199
|
+
str, # date
|
|
200
|
+
str, # institute
|
|
201
|
+
str, # stage
|
|
202
|
+
str, # stage
|
|
203
|
+
str, # ifile
|
|
204
|
+
object, # data
|
|
205
|
+
int, # num. attch.
|
|
206
|
+
object, # attachments
|
|
207
|
+
int, # num. comments
|
|
208
|
+
object, # comments
|
|
209
|
+
int, # num defects
|
|
210
|
+
object, # defects
|
|
211
|
+
str # color
|
|
212
|
+
)
|
|
178
213
|
self.tree = Gtk.TreeView(model=model)
|
|
179
214
|
self.tree.connect("button-press-event", self.button_pressed)
|
|
180
215
|
scrolled = Gtk.ScrolledWindow()
|
|
@@ -187,7 +222,8 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
187
222
|
self.tree.append_column(column)
|
|
188
223
|
|
|
189
224
|
renderer = Gtk.CellRendererText()
|
|
190
|
-
|
|
225
|
+
self.def_color = renderer.get_property("foreground-rgba").to_string()
|
|
226
|
+
column = Gtk.TreeViewColumn("Test Type", renderer, text=TestList.TestType, foreground=TestList.Color)
|
|
191
227
|
self.tree.append_column(column)
|
|
192
228
|
|
|
193
229
|
renderer = Gtk.CellRendererText()
|
|
@@ -376,7 +412,7 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
376
412
|
"""Set the test stage."""
|
|
377
413
|
model, lv_iter, val = data
|
|
378
414
|
SN = val[TestList.SN]
|
|
379
|
-
combo,
|
|
415
|
+
combo, _ = self.get_component_stages(SN)
|
|
380
416
|
|
|
381
417
|
dlg = Gtk.Dialog(title="Add Attachment")
|
|
382
418
|
|
|
@@ -429,7 +465,7 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
429
465
|
return combo, currentStage
|
|
430
466
|
|
|
431
467
|
except Exception:
|
|
432
|
-
self.write_message("Something went
|
|
468
|
+
self.write_message("Something went wrong with the stages\n")
|
|
433
469
|
return [None, None]
|
|
434
470
|
|
|
435
471
|
def add_tests_to_view(self, files):
|
|
@@ -473,8 +509,8 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
473
509
|
path = folder / path.name
|
|
474
510
|
|
|
475
511
|
if path.exists():
|
|
476
|
-
attachments.append(ITkDButils.Attachment(path=path,
|
|
477
|
-
title=att["title"],
|
|
512
|
+
attachments.append(ITkDButils.Attachment(path=path,
|
|
513
|
+
title=att["title"],
|
|
478
514
|
desc=att["description"]))
|
|
479
515
|
else:
|
|
480
516
|
self.write_message("Ignoring atachment {}".format(data["path"]))
|
|
@@ -487,10 +523,18 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
487
523
|
defects = data.get("defects", [])
|
|
488
524
|
the_date = handle_test_date(data["date"])
|
|
489
525
|
combo, currentStage = self.get_component_stages(data["component"])
|
|
526
|
+
if data["passed"]:
|
|
527
|
+
if data["problems"]:
|
|
528
|
+
color = "orange"
|
|
529
|
+
else:
|
|
530
|
+
color = self.def_color
|
|
531
|
+
else:
|
|
532
|
+
color = "firebrick"
|
|
533
|
+
|
|
490
534
|
model.append([data["component"], data["testType"], data["runNumber"], the_date,
|
|
491
535
|
data["institution"], currentStage, currentStage,
|
|
492
536
|
ifile, data, len(attachments), attachments,
|
|
493
|
-
len(comments), comments, len(defects), defects])
|
|
537
|
+
len(comments), comments, len(defects), defects, color])
|
|
494
538
|
|
|
495
539
|
except Exception as E:
|
|
496
540
|
self.write_message("Cannot load file {}\n".format(ifile))
|
|
@@ -9,7 +9,6 @@ try:
|
|
|
9
9
|
import itkdb_gtk
|
|
10
10
|
|
|
11
11
|
except ImportError:
|
|
12
|
-
from pathlib import Path
|
|
13
12
|
cwd = Path(__file__).parent.parent
|
|
14
13
|
sys.path.append(cwd.as_posix())
|
|
15
14
|
|
|
@@ -93,6 +92,7 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
93
92
|
self.attachments = []
|
|
94
93
|
self.comments = []
|
|
95
94
|
self.defects = []
|
|
95
|
+
self.currentStage = None
|
|
96
96
|
if attachment is not None:
|
|
97
97
|
if isinstance(attachment, ITkDButils.Attachment):
|
|
98
98
|
if attachment.path is not None:
|
|
@@ -219,6 +219,7 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
219
219
|
except TypeError:
|
|
220
220
|
self.load_payload(self.payload)
|
|
221
221
|
self.write_message("Loaded memory payload.\n")
|
|
222
|
+
self.testF.set_sensitive(False)
|
|
222
223
|
|
|
223
224
|
if len(self.attachments) > 0:
|
|
224
225
|
self.btn_attch.set_label("Attachments ({})".format(len(self.attachments)))
|
|
@@ -293,7 +294,7 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
293
294
|
self.objStage.set_active(indx)
|
|
294
295
|
|
|
295
296
|
except Exception:
|
|
296
|
-
self.write_message("Something went
|
|
297
|
+
self.write_message("Something went wrong with the stages\n")
|
|
297
298
|
|
|
298
299
|
|
|
299
300
|
def on_test_file(self, fdlg):
|
|
@@ -303,7 +304,7 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
303
304
|
|
|
304
305
|
# The file exists by definition
|
|
305
306
|
try:
|
|
306
|
-
self.data = json.loads(open(fnam).read())
|
|
307
|
+
self.data = json.loads(open(fnam, encoding="UTF-8").read())
|
|
307
308
|
errors, missing = check_data(self.data)
|
|
308
309
|
self.complete_missing(missing, errors)
|
|
309
310
|
self.set_stages()
|
|
@@ -326,7 +327,7 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
326
327
|
self.write_message("Setting Institution to {}\n".format(self.data["institution"]))
|
|
327
328
|
|
|
328
329
|
else:
|
|
329
|
-
dbGtkUtils.complain("Invalid JSON data".format('\n'.join(errors)))
|
|
330
|
+
dbGtkUtils.complain("Invalid JSON data\n{}".format('\n'.join(errors)))
|
|
330
331
|
|
|
331
332
|
self.find_attachments()
|
|
332
333
|
self.find_comments()
|
|
@@ -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,31 @@ module_param = {
|
|
|
103
92
|
],
|
|
104
93
|
}
|
|
105
94
|
|
|
106
|
-
def
|
|
107
|
-
"""Convert
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
rng = hyb[irow]
|
|
111
|
-
if iwire>= rng[0] and iwire<=rng[1]:
|
|
112
|
-
if irow % 2:
|
|
113
|
-
ichan = 2*(iwire-rng[0]) + 1
|
|
114
|
-
else:
|
|
115
|
-
ichan = 2*(iwire-rng[0])
|
|
95
|
+
def range_to_list(V):
|
|
96
|
+
"""Convert a range (ch1-ch2) to a list."""
|
|
97
|
+
if '-' not in V and ',' not in V:
|
|
98
|
+
return [V]
|
|
116
99
|
|
|
117
|
-
|
|
100
|
+
out = []
|
|
101
|
+
values = V.split(',')
|
|
102
|
+
for V in values:
|
|
103
|
+
if '-' in V:
|
|
104
|
+
endpoints = list(map(int, V.split('-')))
|
|
105
|
+
endpoints.sort()
|
|
106
|
+
for i in range(endpoints[0], endpoints[1]+1):
|
|
107
|
+
out.append(str(i))
|
|
108
|
+
else:
|
|
109
|
+
out.append(V)
|
|
110
|
+
|
|
111
|
+
return out
|
|
118
112
|
|
|
119
|
-
|
|
113
|
+
def count_items(items):
|
|
114
|
+
"""Count number of channels from results."""
|
|
115
|
+
nitems = 0
|
|
116
|
+
for key in items.keys():
|
|
117
|
+
nitems += len(range_to_list(key))
|
|
120
118
|
|
|
119
|
+
return nitems
|
|
121
120
|
|
|
122
121
|
def find_holes(chan_list, min_chan=0, max_chan=999999):
|
|
123
122
|
"""Find groups of consecutive channels."""
|
|
@@ -161,19 +160,41 @@ def find_holes(chan_list, min_chan=0, max_chan=999999):
|
|
|
161
160
|
return holes
|
|
162
161
|
|
|
163
162
|
|
|
163
|
+
def wire2strip(iwire, irow, first_chan):
|
|
164
|
+
"""From bond to strip number."""
|
|
165
|
+
if irow % 2:
|
|
166
|
+
istrip = 2*(iwire-first_chan) + 1
|
|
167
|
+
else:
|
|
168
|
+
istrip = 2*(iwire-first_chan)
|
|
169
|
+
|
|
170
|
+
return istrip
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class Hole:
|
|
174
|
+
"""A range of consecutive unconnected channels."""
|
|
175
|
+
def __init__(self, *args):
|
|
176
|
+
for i, name in enumerate(['sensor', 'hybrid', 'row', 'chan', 'width']):
|
|
177
|
+
setattr(self, name, args[i])
|
|
178
|
+
|
|
179
|
+
def __repr__(self):
|
|
180
|
+
return "sensor: {} hyb: {} row: {} chan: {} width: {}".format(
|
|
181
|
+
self.sensor, self.hybrid, self.row, self.chan, self.width
|
|
182
|
+
)
|
|
183
|
+
|
|
164
184
|
class HybridHoles:
|
|
165
|
-
"""Holes in hybrid
|
|
185
|
+
"""Holes in hybrid bonds.
|
|
166
186
|
|
|
167
187
|
Holes are defined by a list [first_chan, n_chan].
|
|
168
188
|
"""
|
|
169
189
|
|
|
170
|
-
def __init__(self, param, hid=0):
|
|
190
|
+
def __init__(self, param, win=None, hid=0):
|
|
171
191
|
"""Initialization.
|
|
172
192
|
|
|
173
193
|
Args:
|
|
174
194
|
param: Hybrid wirebon parameters.
|
|
175
195
|
|
|
176
196
|
"""
|
|
197
|
+
self.win = win
|
|
177
198
|
self.id = hid
|
|
178
199
|
self.param = param
|
|
179
200
|
self.nchan = 0
|
|
@@ -182,12 +203,25 @@ class HybridHoles:
|
|
|
182
203
|
|
|
183
204
|
self.holes = [[] for irow in range(4)]
|
|
184
205
|
self.channels = [[] for irow in range(4)]
|
|
206
|
+
# Sensor strips for each of the strip rows "served" by a hybrid.
|
|
207
|
+
self.sensor_channels = [[], []]
|
|
208
|
+
self.sensor_holes = [[], []]
|
|
209
|
+
|
|
210
|
+
def ready(self):
|
|
211
|
+
"""Call when all channels are in."""
|
|
212
|
+
for irow, C in enumerate(self.channels):
|
|
213
|
+
C.sort()
|
|
214
|
+
self.holes[irow] = find_holes(C)
|
|
215
|
+
|
|
216
|
+
for irow, S in enumerate(self.sensor_channels):
|
|
217
|
+
S.sort()
|
|
218
|
+
self.sensor_holes[irow] = find_holes(S)
|
|
185
219
|
|
|
186
220
|
def add_channel(self, irow, ichan)->bool:
|
|
187
221
|
"""Add a new channel in row.
|
|
188
222
|
|
|
189
223
|
Args:
|
|
190
|
-
irow:
|
|
224
|
+
irow: row number
|
|
191
225
|
ichan: channel number
|
|
192
226
|
|
|
193
227
|
Returns:
|
|
@@ -196,102 +230,93 @@ class HybridHoles:
|
|
|
196
230
|
"""
|
|
197
231
|
first_chan = self.param[irow][0]
|
|
198
232
|
last_chan = self.param[irow][1]
|
|
233
|
+
strip_row = int(irow/2)
|
|
234
|
+
|
|
235
|
+
|
|
199
236
|
if isinstance(ichan, list) or isinstance(ichan, tuple):
|
|
200
237
|
nadded = 0
|
|
201
238
|
for ich in ichan:
|
|
202
|
-
if
|
|
239
|
+
if first_chan <= ich <= last_chan:
|
|
203
240
|
self.channels[irow].append(ich)
|
|
204
241
|
nadded += 1
|
|
205
242
|
|
|
206
243
|
self.channels[irow] = sorted(self.channels[irow])
|
|
244
|
+
for iwire in self.channels[irow]:
|
|
245
|
+
istrip = wire2strip(iwire, irow, first_chan)
|
|
246
|
+
self.sensor_channels[strip_row].append(istrip)
|
|
247
|
+
|
|
207
248
|
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
249
|
|
|
215
|
-
|
|
250
|
+
if first_chan <= ichan <= last_chan:
|
|
251
|
+
self.channels[irow].append(ichan)
|
|
252
|
+
istrip = wire2strip(ichan, irow, first_chan)
|
|
253
|
+
self.sensor_channels[strip_row].append(istrip)
|
|
254
|
+
return True
|
|
255
|
+
|
|
256
|
+
return False
|
|
257
|
+
|
|
258
|
+
def get_n_unconnected(self) -> list:
|
|
216
259
|
"""Count number of unconnected channels.
|
|
217
260
|
|
|
218
261
|
Return a list, one item per row.
|
|
219
262
|
"""
|
|
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
|
-
|
|
263
|
+
nchan = [len(C) for C in self.channels]
|
|
228
264
|
return nchan
|
|
229
265
|
|
|
230
|
-
def
|
|
231
|
-
"""
|
|
266
|
+
def get_max_consecutive_from_list(self, holes):
|
|
267
|
+
"""Return max widht of holes."""
|
|
232
268
|
mx_width = []
|
|
269
|
+
lst_holes = []
|
|
270
|
+
for irow, row in enumerate(holes):
|
|
271
|
+
if len(row) == 0:
|
|
272
|
+
mxW = 0
|
|
233
273
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
mxW = h[1]
|
|
274
|
+
else:
|
|
275
|
+
mxW = -1
|
|
276
|
+
for h in row:
|
|
277
|
+
lst_holes.append(Hole(0, self.id, irow, h[0], h[1]))
|
|
278
|
+
mxW = max(mxW, h[1])
|
|
239
279
|
|
|
240
280
|
mx_width.append(mxW)
|
|
241
281
|
|
|
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).
|
|
249
|
-
|
|
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)
|
|
282
|
+
return mx_width, lst_holes
|
|
264
283
|
|
|
265
|
-
channels[isegment] = sorted(channels[isegment])
|
|
266
284
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
holes.extend(out)
|
|
272
|
-
|
|
273
|
-
return holes
|
|
285
|
+
def get_max_consecutive(self):
|
|
286
|
+
"""Returns the largest 'hole'."""
|
|
287
|
+
mx_width, _ = self.get_max_consecutive_from_list(self.holes)
|
|
288
|
+
return mx_width
|
|
274
289
|
|
|
290
|
+
def get_max_sensor_consecutive(self):
|
|
291
|
+
"""Return largest hole in sensor."""
|
|
292
|
+
mx_width, holes = self.get_max_consecutive_from_list(self.sensor_holes)
|
|
293
|
+
return mx_width, holes
|
|
275
294
|
|
|
276
295
|
class SensorHoles:
|
|
277
296
|
"""Holes in sensor."""
|
|
278
297
|
|
|
279
|
-
def __init__(self, param, sid=0):
|
|
298
|
+
def __init__(self, param, win=None, sid=0):
|
|
280
299
|
"""Initialization.
|
|
281
300
|
|
|
282
301
|
Args:
|
|
283
302
|
param: sensor wirebon params
|
|
284
303
|
"""
|
|
304
|
+
self.win = win
|
|
285
305
|
self.id = sid
|
|
286
306
|
self.param = param
|
|
287
307
|
self.nchan = 0
|
|
288
308
|
self.nhybrid = len(param)
|
|
289
309
|
self.hybrids = []
|
|
290
310
|
for i, P in enumerate(param):
|
|
291
|
-
H = HybridHoles(P, hid=i)
|
|
311
|
+
H = HybridHoles(P, hid=i, win=win)
|
|
292
312
|
self.hybrids.append(H)
|
|
293
313
|
self.nchan += H.nchan
|
|
294
314
|
|
|
315
|
+
def ready(self):
|
|
316
|
+
"""Call when all channels are in."""
|
|
317
|
+
for H in self.hybrids:
|
|
318
|
+
H.ready()
|
|
319
|
+
|
|
295
320
|
def get_n_hyb(self):
|
|
296
321
|
"""Return number of hybrids."""
|
|
297
322
|
return len(self.hybrids)
|
|
@@ -305,15 +330,30 @@ class SensorHoles:
|
|
|
305
330
|
|
|
306
331
|
This is ordered by row.
|
|
307
332
|
"""
|
|
308
|
-
|
|
333
|
+
n_strip_row = 2*len(self.hybrids)
|
|
334
|
+
mx_width = [0 for x in range(n_strip_row)]
|
|
309
335
|
for hyb in self.hybrids:
|
|
310
336
|
mxW = hyb.get_max_consecutive()
|
|
311
337
|
for j in range(4):
|
|
312
|
-
|
|
313
|
-
mx_width[j] = mxW[j]
|
|
338
|
+
mx_width[j] = max(mx_width[j] , mxW[j])
|
|
314
339
|
|
|
315
340
|
return mx_width
|
|
316
341
|
|
|
342
|
+
def get_max_sensor_consecutive(self):
|
|
343
|
+
"""MAx widht of holes in sensor."""
|
|
344
|
+
mx_width = -1
|
|
345
|
+
holes = []
|
|
346
|
+
for hyb in self.hybrids:
|
|
347
|
+
mxW, hyb_holes = hyb.get_max_sensor_consecutive()
|
|
348
|
+
for H in hyb_holes:
|
|
349
|
+
H.sensor = self.id
|
|
350
|
+
|
|
351
|
+
holes.extend(hyb_holes)
|
|
352
|
+
for v in mxW:
|
|
353
|
+
mx_width = max(mx_width, v)
|
|
354
|
+
|
|
355
|
+
return mx_width, holes
|
|
356
|
+
|
|
317
357
|
def get_n_unconnected(self):
|
|
318
358
|
"""Count number of unconnected channels.
|
|
319
359
|
|
|
@@ -327,37 +367,30 @@ class SensorHoles:
|
|
|
327
367
|
|
|
328
368
|
return nchan
|
|
329
369
|
|
|
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
370
|
|
|
344
371
|
class ModuleHoles:
|
|
345
372
|
"""Holes in Modules."""
|
|
346
373
|
|
|
347
|
-
def __init__(self, param):
|
|
374
|
+
def __init__(self, param, win=None):
|
|
348
375
|
"""Initialization.
|
|
349
376
|
|
|
350
377
|
Args:
|
|
351
378
|
param: module wirebond params
|
|
352
379
|
"""
|
|
380
|
+
self.win = win
|
|
353
381
|
self.nsensor = len(param)
|
|
354
382
|
self.nchan = 0
|
|
355
383
|
self.sensors = []
|
|
356
384
|
for i, P in enumerate(param):
|
|
357
|
-
S = SensorHoles(P, sid=i)
|
|
385
|
+
S = SensorHoles(P, sid=i, win=win)
|
|
358
386
|
self.sensors.append(S)
|
|
359
387
|
self.nchan += S.nchan
|
|
360
388
|
|
|
389
|
+
def ready(self):
|
|
390
|
+
"""Call when all channels are in."""
|
|
391
|
+
for S in self.sensors:
|
|
392
|
+
S.ready()
|
|
393
|
+
|
|
361
394
|
def get_max_consecutive(self):
|
|
362
395
|
"""Max number of consecutive unconnected channels.
|
|
363
396
|
|
|
@@ -367,22 +400,21 @@ class ModuleHoles:
|
|
|
367
400
|
for S in self.sensors:
|
|
368
401
|
mxW = S.get_max_consecutive()
|
|
369
402
|
for j in range(4):
|
|
370
|
-
|
|
371
|
-
mx_width[j] = mxW[j]
|
|
403
|
+
mx_width[j] = max(mx_width[j], mxW[j])
|
|
372
404
|
|
|
373
405
|
return mx_width
|
|
374
406
|
|
|
375
|
-
def
|
|
376
|
-
"""
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
"""
|
|
380
|
-
holes = []
|
|
407
|
+
def get_max_sensor_consecutive(self):
|
|
408
|
+
"""The maximum number of consecutive channels per strip row."""
|
|
409
|
+
mx_width = -1
|
|
410
|
+
module_holes = []
|
|
381
411
|
for S in self.sensors:
|
|
382
|
-
|
|
383
|
-
|
|
412
|
+
width, holes = S.get_max_sensor_consecutive()
|
|
413
|
+
module_holes.extend(holes)
|
|
414
|
+
mx_width = max(mx_width, width)
|
|
415
|
+
|
|
416
|
+
return mx_width, module_holes
|
|
384
417
|
|
|
385
|
-
return holes
|
|
386
418
|
|
|
387
419
|
def get_n_unconnected(self) -> list:
|
|
388
420
|
"""Count number of unconnected channels.
|
|
@@ -575,12 +607,35 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
575
607
|
lut = {}
|
|
576
608
|
module_map = {}
|
|
577
609
|
section = None
|
|
610
|
+
i_local = 0
|
|
611
|
+
i_std = 1
|
|
612
|
+
indx = ["local", "standard"]
|
|
613
|
+
found_format = False
|
|
578
614
|
with open(fnam, 'r', encoding="UTF-8") as fin:
|
|
579
615
|
for line in fin:
|
|
580
616
|
line = line.strip()
|
|
581
617
|
|
|
582
618
|
# Remove comments.
|
|
583
619
|
ipos = line.find('#')
|
|
620
|
+
jpos = line.find("#!")
|
|
621
|
+
if jpos>=0 and ipos==jpos:
|
|
622
|
+
if found_format:
|
|
623
|
+
dbGtkUtils.complain("A second format line was found.",
|
|
624
|
+
"Onely one is allowed. stopr map parsing.")
|
|
625
|
+
return
|
|
626
|
+
|
|
627
|
+
indx = [x.lower() for x in line[ipos+2:].split()]
|
|
628
|
+
try:
|
|
629
|
+
i_local = indx.index("local")
|
|
630
|
+
i_std = indx.index("standard")
|
|
631
|
+
found_format = True
|
|
632
|
+
except ValueError:
|
|
633
|
+
dbGtkUtils.complain("Wrong format desciption string.",
|
|
634
|
+
"The words 'local' and 'standard' should be there.\n{}".format(line))
|
|
635
|
+
return
|
|
636
|
+
|
|
637
|
+
continue
|
|
638
|
+
|
|
584
639
|
if ipos >= 0:
|
|
585
640
|
line = line[:ipos].strip()
|
|
586
641
|
|
|
@@ -602,13 +657,13 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
602
657
|
if section is None:
|
|
603
658
|
continue
|
|
604
659
|
|
|
605
|
-
values =
|
|
606
|
-
if len(values)!=
|
|
660
|
+
values = line.split()
|
|
661
|
+
if len(values)!=len(indx):
|
|
607
662
|
dbGtkUtils.complain("Cannot read Lookup table.", "Wrong line format: {}".format(line))
|
|
608
663
|
return
|
|
609
664
|
|
|
610
|
-
v_local = range_to_list(values[
|
|
611
|
-
v_std = range_to_list(values[
|
|
665
|
+
v_local = range_to_list(values[i_local])
|
|
666
|
+
v_std = range_to_list(values[i_std])
|
|
612
667
|
|
|
613
668
|
if len(v_local) != len(v_std):
|
|
614
669
|
dbGtkUtils.complain("Wrong Lookup table.",
|
|
@@ -669,7 +724,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
669
724
|
view_model = self.models[param]
|
|
670
725
|
self.tree.set_model(view_model)
|
|
671
726
|
else:
|
|
672
|
-
self.write_message("Cannot find model for {}".format(param))
|
|
727
|
+
self.write_message("Cannot find model for {}\n".format(param))
|
|
673
728
|
|
|
674
729
|
def create_combo(self):
|
|
675
730
|
"""Create the combo."""
|
|
@@ -813,7 +868,42 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
813
868
|
self.hide()
|
|
814
869
|
self.destroy()
|
|
815
870
|
|
|
816
|
-
def
|
|
871
|
+
def compute_repaired(self, skeleton):
|
|
872
|
+
"""Compute number of repaired."""
|
|
873
|
+
nrepaired = 0
|
|
874
|
+
for key, values in skeleton["results"].items():
|
|
875
|
+
if key.find("REPAIRED")<0 or key.find("ROW")<0:
|
|
876
|
+
continue
|
|
877
|
+
|
|
878
|
+
nrepaired += len(values)
|
|
879
|
+
|
|
880
|
+
if nrepaired>0:
|
|
881
|
+
skeleton["problems"] = True
|
|
882
|
+
skeleton["comments"].append("Number of repaired FE bonds: {}".format(nrepaired))
|
|
883
|
+
|
|
884
|
+
return nrepaired
|
|
885
|
+
|
|
886
|
+
def compute_hybrid_to_pb(self, skeleton):
|
|
887
|
+
"""Compute number of failures and repairs."""
|
|
888
|
+
n = count_items(skeleton["results"]["REPAIRED_HYBRID_TO_PB"])
|
|
889
|
+
n = count_items(skeleton["results"]["FAILED_HYBRID_TO_PB"])
|
|
890
|
+
if n:
|
|
891
|
+
msg = "Hybrid to PB: {} failing bonds.".format(n)
|
|
892
|
+
skeleton["comments"].append(msg)
|
|
893
|
+
skeleton["passed"] = False
|
|
894
|
+
self.write_message("{}\n".format(msg))
|
|
895
|
+
|
|
896
|
+
def compute_module_to_frame(self, skeleton):
|
|
897
|
+
"""Compute number of failures and repairs."""
|
|
898
|
+
n = count_items(skeleton["results"]["REPAIRED_MODULE_TO_FRAME"])
|
|
899
|
+
n = count_items(skeleton["results"]["FAILED_MODULE_TO_FRAME"])
|
|
900
|
+
if n:
|
|
901
|
+
msg = "Module to test frame: {} failing bonds.".format(n)
|
|
902
|
+
skeleton["comments"].append(msg)
|
|
903
|
+
skeleton["passed"] = False
|
|
904
|
+
self.write_message("{}\n".format(msg))
|
|
905
|
+
|
|
906
|
+
def compute_unconnected(self, results):
|
|
817
907
|
"""Compute number of unconnected."""
|
|
818
908
|
try:
|
|
819
909
|
param = get_module_param(self.SN.get_text())
|
|
@@ -821,9 +911,9 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
821
911
|
dbGtkUtils.complain("Wrong SN number", str(E))
|
|
822
912
|
return None
|
|
823
913
|
|
|
824
|
-
M = ModuleHoles(param=param)
|
|
914
|
+
M = ModuleHoles(param=param, win=self)
|
|
825
915
|
|
|
826
|
-
for test in
|
|
916
|
+
for test, values in results.items():
|
|
827
917
|
if test.find("FAILED") < 0:
|
|
828
918
|
continue
|
|
829
919
|
if test.find("ROW") < 0:
|
|
@@ -832,16 +922,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
832
922
|
irow = int(test[-1]) - 1
|
|
833
923
|
|
|
834
924
|
# 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
|
-
|
|
925
|
+
out = [int(x) for x in values.keys()]
|
|
845
926
|
# Translate to sensor, hybrids, etc.
|
|
846
927
|
for S in M.sensors:
|
|
847
928
|
for H in S.hybrids:
|
|
@@ -850,41 +931,66 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
850
931
|
|
|
851
932
|
|
|
852
933
|
# Now get sensor strips.
|
|
934
|
+
M.ready()
|
|
853
935
|
unconnected = M.get_n_unconnected()
|
|
854
936
|
mx_consecutive = M.get_max_consecutive()
|
|
855
|
-
module_holes = M.
|
|
937
|
+
mx_sensor_width, module_holes = M.get_max_sensor_consecutive()
|
|
856
938
|
|
|
857
939
|
out = {}
|
|
940
|
+
out["comments"] = []
|
|
941
|
+
out["defects"] = []
|
|
858
942
|
for irow in range(4):
|
|
859
943
|
key = "MAX_CONT_UNCON_ROW{}".format(irow+1)
|
|
860
944
|
out[key] = mx_consecutive[irow]
|
|
861
945
|
|
|
862
|
-
mxW = 0
|
|
863
946
|
self.write_message("Found {} clusters of unconnected strips in sensor.\n".format(len(module_holes)))
|
|
864
947
|
for H in module_holes:
|
|
865
|
-
self.write_message("{}\n".format(
|
|
866
|
-
if H[-1] > mxW:
|
|
867
|
-
mxW = H[-1]
|
|
948
|
+
self.write_message("{}\n".format(H))
|
|
868
949
|
|
|
869
|
-
if
|
|
870
|
-
self.write_message("Max width: {}". format(
|
|
950
|
+
if mx_sensor_width > 0:
|
|
951
|
+
self.write_message("Max width of consecutive unconnected strips: {}\n". format(mx_sensor_width))
|
|
952
|
+
|
|
953
|
+
out["MAX_UNCON_SENSOR_CHAN"] = mx_sensor_width
|
|
954
|
+
if mx_sensor_width > 8:
|
|
955
|
+
out["passed"] = False
|
|
956
|
+
out["comments"].append("Too many consecutive sensor strips unconnected: {}".format(mx_sensor_width))
|
|
871
957
|
|
|
872
|
-
out["MAX_UNCON_SENSOR_CHAN"] = mxW
|
|
873
958
|
nstrips = 0
|
|
874
959
|
for v in unconnected:
|
|
875
960
|
nstrips += v
|
|
876
961
|
|
|
877
|
-
|
|
962
|
+
percent = 100*nstrips/M.nchan
|
|
963
|
+
out["TOTAL_PERC_UNCON_SENSOR_CHAN"] = percent
|
|
964
|
+
if out["TOTAL_PERC_UNCON_SENSOR_CHAN"] > 1.0:
|
|
965
|
+
out["passed"] = False
|
|
966
|
+
out["comments"].append("More than 1%% of channels unconnected: {:.1f}%%".format(percent))
|
|
878
967
|
|
|
879
968
|
return out
|
|
880
969
|
|
|
881
970
|
def get_unconnected(self, skeleton):
|
|
882
971
|
"""Fill the test DTO with unconnected information."""
|
|
883
|
-
out = self.compute_unconnected()
|
|
972
|
+
out = self.compute_unconnected(skeleton["results"])
|
|
884
973
|
if out is None:
|
|
885
974
|
raise ValueError("Wrong SN")
|
|
886
975
|
|
|
887
976
|
for key, val in out.items():
|
|
977
|
+
if key in ["passed", "problems"]:
|
|
978
|
+
skeleton[key] = out[key]
|
|
979
|
+
continue
|
|
980
|
+
|
|
981
|
+
if key == "comments":
|
|
982
|
+
for C in out[key]:
|
|
983
|
+
skeleton[key].append(C)
|
|
984
|
+
|
|
985
|
+
continue
|
|
986
|
+
|
|
987
|
+
if key == "defects":
|
|
988
|
+
for D in out[key]:
|
|
989
|
+
skeleton[key].append(D)
|
|
990
|
+
|
|
991
|
+
continue
|
|
992
|
+
|
|
993
|
+
|
|
888
994
|
skeleton["results"][key] = val
|
|
889
995
|
|
|
890
996
|
def read_file(self, *args):
|
|
@@ -921,7 +1027,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
921
1027
|
try:
|
|
922
1028
|
dbGtkUtils.set_combo_iter(self.inst_combo, data["institution"])
|
|
923
1029
|
except KeyError:
|
|
924
|
-
self.write_message("institution value is not in the loaded file.")
|
|
1030
|
+
self.write_message("institution value is not in the loaded file\n.")
|
|
925
1031
|
|
|
926
1032
|
self.operator.set_text(data["properties"]["OPERATOR"])
|
|
927
1033
|
self.machine.set_text(data["properties"]["BOND_MACHINE"])
|
|
@@ -971,12 +1077,8 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
971
1077
|
continue
|
|
972
1078
|
|
|
973
1079
|
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))
|
|
1080
|
+
for i in range_to_list(V):
|
|
1081
|
+
added_items.append((str(i), comment))
|
|
980
1082
|
|
|
981
1083
|
for key in range_items:
|
|
982
1084
|
section.pop(key)
|
|
@@ -1052,7 +1154,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
1052
1154
|
if len(values) == 4:
|
|
1053
1155
|
SN, operator, machine = values
|
|
1054
1156
|
else:
|
|
1055
|
-
self.write_message("Something went wrong while requesting missing information
|
|
1157
|
+
self.write_message("Something went wrong while requesting missing information.\n")
|
|
1056
1158
|
|
|
1057
1159
|
data["component"] = SN
|
|
1058
1160
|
data["properties"]["OPERATOR"] = operator
|
|
@@ -1090,6 +1192,9 @@ class WireBond(dbGtkUtils.ITkDBWindow):
|
|
|
1090
1192
|
self.fix_list_of_channels(skeleton)
|
|
1091
1193
|
try:
|
|
1092
1194
|
self.get_unconnected(skeleton)
|
|
1195
|
+
self.compute_repaired(skeleton)
|
|
1196
|
+
self.compute_hybrid_to_pb(skeleton)
|
|
1197
|
+
self.compute_module_to_frame(skeleton)
|
|
1093
1198
|
|
|
1094
1199
|
except ValueError:
|
|
1095
1200
|
return
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
""" itkdb-gtk python module
|
|
2
2
|
"""
|
|
3
|
-
__version__ = "0.10.10.
|
|
3
|
+
__version__ = "0.10.10.dev5"
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def dash_board():
|
|
@@ -62,3 +62,8 @@ def panelVisualInspection():
|
|
|
62
62
|
"""Visual inspection of PWB or HYB panels."""
|
|
63
63
|
from .PanelVisualInspection import main
|
|
64
64
|
main()
|
|
65
|
+
|
|
66
|
+
def moduleVisualInspection():
|
|
67
|
+
"""Visual inspection of Modules."""
|
|
68
|
+
from .ModuleVisualInspection import main
|
|
69
|
+
main()
|
|
@@ -22,6 +22,7 @@ from itkdb_gtk import GlueWeight
|
|
|
22
22
|
from itkdb_gtk import UploadModuleIV
|
|
23
23
|
from itkdb_gtk import WireBondGui
|
|
24
24
|
from itkdb_gtk import PanelVisualInspection
|
|
25
|
+
from itkdb_gtk import ModuleVisualInspection
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
HAS_PETALQC=False
|
|
@@ -53,8 +54,9 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
53
54
|
MOD_IV = 7
|
|
54
55
|
WIRE_BOND = 8
|
|
55
56
|
PANEL_VI = 9
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
MODULE_VI = 10
|
|
58
|
+
PETAL_CORE_METRO = 11
|
|
59
|
+
PETAL_CORE_THERMAL = 12
|
|
58
60
|
|
|
59
61
|
|
|
60
62
|
def __init__(self, session):
|
|
@@ -107,9 +109,13 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
107
109
|
grid.attach(btnWireBond, 1, irow, 1, 1)
|
|
108
110
|
|
|
109
111
|
irow += 1
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
grid.attach(
|
|
112
|
+
btnPanelVI = Gtk.Button(label="Panel Visual Insp.")
|
|
113
|
+
btnPanelVI.connect("clicked", self.panel_VI)
|
|
114
|
+
grid.attach(btnPanelVI, 1, irow, 1, 1)
|
|
115
|
+
|
|
116
|
+
btnModVI = Gtk.Button(label="Module Visual Insp.")
|
|
117
|
+
btnModVI.connect("clicked", self.module_VI)
|
|
118
|
+
grid.attach(btnModVI, 0, irow, 1, 1)
|
|
113
119
|
|
|
114
120
|
|
|
115
121
|
if HAS_PETALQC:
|
|
@@ -242,7 +248,23 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
242
248
|
return
|
|
243
249
|
|
|
244
250
|
self.mask |= bt
|
|
245
|
-
W = PanelVisualInspection.PanelVisualInspection(session=self.session,
|
|
251
|
+
W = PanelVisualInspection.PanelVisualInspection(session=self.session,
|
|
252
|
+
title="Panel Visual Inspection",
|
|
253
|
+
help_link=HELP_LINK)
|
|
254
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
255
|
+
W.show_all()
|
|
256
|
+
|
|
257
|
+
def module_VI(self, *args):
|
|
258
|
+
"""Panel VI tests."""
|
|
259
|
+
bitn = DashWindow.MODULE_VI
|
|
260
|
+
bt = 1 << bitn
|
|
261
|
+
if self.mask & bt:
|
|
262
|
+
return
|
|
263
|
+
|
|
264
|
+
self.mask |= bt
|
|
265
|
+
W = ModuleVisualInspection.ModuleVisualInspection(session=self.session,
|
|
266
|
+
title="Module Visual Inspection",
|
|
267
|
+
help_link=HELP_LINK)
|
|
246
268
|
W.connect("destroy", self.app_closed, bitn)
|
|
247
269
|
W.show_all()
|
|
248
270
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: itkdb_gtk
|
|
3
|
-
Version: 0.10.10.
|
|
3
|
+
Version: 0.10.10.dev5
|
|
4
4
|
Summary: A collection of Gtk based GUI to access ITkDB.
|
|
5
5
|
Author-email: Carlos Lacasta <carlos.lacasta@cern.ch>
|
|
6
6
|
Project-URL: Homepage, https://gitlab.cern.ch/atlas-itk/sw/db/itk-pdb-gtk-gui-utils
|
|
@@ -3,6 +3,7 @@ createShipments = itkdb_gtk:createShipments
|
|
|
3
3
|
getShipments = itkdb_gtk:getShipments
|
|
4
4
|
glueWeight = itkdb_gtk:glueWeight
|
|
5
5
|
itkdb_dashBoard = itkdb_gtk:dash_board
|
|
6
|
+
moduleVisualInspection = itkdb_gtk:moduleVisualInspection
|
|
6
7
|
panelVisualInspection = itkdb_gtk:panelVisualInspection
|
|
7
8
|
petalReceptionTests = itkdb_gtk:petalReceptionTests
|
|
8
9
|
uploadModuleIV = itkdb_gtk:uploadModuleIV
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "itkdb_gtk"
|
|
7
|
-
version = "0.10.10.
|
|
7
|
+
version = "0.10.10.dev5"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Carlos Lacasta", email="carlos.lacasta@cern.ch" },
|
|
10
10
|
]
|
|
@@ -38,6 +38,7 @@ uploadModuleIV = "itkdb_gtk:uploadModuleIV"
|
|
|
38
38
|
wirebondTest = "itkdb_gtk:wirebondTest"
|
|
39
39
|
uploadPetalInformation = "itkdb_gtk:uploadPetalInformation"
|
|
40
40
|
panelVisualInspection = "itkdb_gtk:panelVisualInspection"
|
|
41
|
+
moduleVisualInspection = "itkdb_gtk:moduleVisualInspection"
|
|
41
42
|
|
|
42
43
|
[tool.setuptools]
|
|
43
44
|
include-package-data = true
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|