petal-qc 0.0.12__py3-none-any.whl → 0.0.15__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 petal-qc might be problematic. Click here for more details.
- petal_qc/PetalReceptionTests.py +330 -0
- petal_qc/__init__.py +11 -2
- petal_qc/dashBoard.py +26 -9
- petal_qc/metrology/PetalMetrology.py +17 -17
- petal_qc/metrology/analyze_locking_points.py +4 -4
- petal_qc/metrology/compare_Cores.py +25 -4
- petal_qc/metrology/do_Metrology.py +30 -3
- petal_qc/test/createMetrologyFile.py +77 -0
- petal_qc/test/desyModuleBow.py +126 -0
- petal_qc/test/findRawData.py +92 -0
- petal_qc/test/getAVStests.py +70 -19
- petal_qc/test/getPetalCoreTestSummary.py +18 -5
- petal_qc/test/prepareDESYfiles.py +23 -8
- petal_qc/test/reportFromJSon.py +51 -0
- petal_qc/thermal/create_core_report.py +7 -3
- {petal_qc-0.0.12.dist-info → petal_qc-0.0.15.dist-info}/METADATA +4 -4
- {petal_qc-0.0.12.dist-info → petal_qc-0.0.15.dist-info}/RECORD +20 -15
- {petal_qc-0.0.12.dist-info → petal_qc-0.0.15.dist-info}/WHEEL +1 -1
- {petal_qc-0.0.12.dist-info → petal_qc-0.0.15.dist-info}/entry_points.txt +2 -0
- {petal_qc-0.0.12.dist-info → petal_qc-0.0.15.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Test dashboard."""
|
|
3
|
+
import sys
|
|
4
|
+
import copy
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
import itkdb_gtk
|
|
9
|
+
|
|
10
|
+
except ImportError:
|
|
11
|
+
cwd = Path(__file__).parent.parent
|
|
12
|
+
sys.path.append(cwd.as_posix())
|
|
13
|
+
import itkdb_gtk
|
|
14
|
+
|
|
15
|
+
from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
|
|
16
|
+
from itkdb_gtk import UploadTest, UploadMultipleTests
|
|
17
|
+
|
|
18
|
+
HELP_LINK="https://itkdb-gtk.docs.cern.ch"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
import gi
|
|
22
|
+
gi.require_version("Gtk", "3.0")
|
|
23
|
+
from gi.repository import Gtk, Gio
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def find_children(W):
|
|
27
|
+
"""Find DictDialog among the children."""
|
|
28
|
+
try:
|
|
29
|
+
for c in W.get_children():
|
|
30
|
+
if "DictDialog" in c.get_name():
|
|
31
|
+
return c
|
|
32
|
+
|
|
33
|
+
else:
|
|
34
|
+
return find_children(c)
|
|
35
|
+
|
|
36
|
+
except Exception:
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
43
|
+
"""Petl Reception Test GUI."""
|
|
44
|
+
|
|
45
|
+
def __init__(self, session, help_link=None):
|
|
46
|
+
"""Initialization."""
|
|
47
|
+
super().__init__(title="Petal Reception Tests",
|
|
48
|
+
session=session,
|
|
49
|
+
show_search="Find object with given SN.",
|
|
50
|
+
help_link=help_link)
|
|
51
|
+
|
|
52
|
+
# Members
|
|
53
|
+
self.dbObject = None
|
|
54
|
+
|
|
55
|
+
# action button in header
|
|
56
|
+
button = Gtk.Button()
|
|
57
|
+
icon = Gio.ThemedIcon(name="document-send-symbolic")
|
|
58
|
+
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
59
|
+
button.add(image)
|
|
60
|
+
button.set_tooltip_text("Click to upload ALL tests.")
|
|
61
|
+
button.connect("clicked", self.upload_tests)
|
|
62
|
+
self.hb.pack_end(button)
|
|
63
|
+
|
|
64
|
+
grid = Gtk.Grid(column_spacing=5, row_spacing=1)
|
|
65
|
+
self.mainBox.pack_start(grid, False, False, 5)
|
|
66
|
+
|
|
67
|
+
lbl = Gtk.Label(label="Serial Number")
|
|
68
|
+
lbl.set_xalign(0)
|
|
69
|
+
grid.attach(lbl, 0, 0, 1, 1)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
self.SN = itkdb_gtk.dbGtkUtils.TextEntry()
|
|
73
|
+
self.SN.connect("text-changed", self.on_SN_changed)
|
|
74
|
+
|
|
75
|
+
#self.SN = Gtk.Entry()
|
|
76
|
+
#self.SN.connect("focus-in-event", self.on_sn_enter)
|
|
77
|
+
#self.SN.connect("focus-out-event", self.on_sn_leave)
|
|
78
|
+
grid.attach(self.SN.entry, 1, 0, 1, 1)
|
|
79
|
+
|
|
80
|
+
self.alias = Gtk.Label(label="")
|
|
81
|
+
grid.attach(self.alias, 2, 0, 1, 1)
|
|
82
|
+
|
|
83
|
+
self.stage = Gtk.Label(label="")
|
|
84
|
+
grid.attach(self.stage, 3, 0, 1, 1)
|
|
85
|
+
|
|
86
|
+
lbl = Gtk.Label(label="Institute")
|
|
87
|
+
lbl.set_xalign(0)
|
|
88
|
+
grid.attach(lbl, 0, 1, 1, 1)
|
|
89
|
+
|
|
90
|
+
self.institute = self.pdb_user["institutions"][0]["code"]
|
|
91
|
+
inst = self.create_institute_combo(only_user=True)
|
|
92
|
+
inst.connect("changed", self.new_institute)
|
|
93
|
+
inst.set_tooltip_text("Select the Institute.")
|
|
94
|
+
grid.attach(inst, 1, 1, 1, 1)
|
|
95
|
+
self.inst_cmb = inst
|
|
96
|
+
|
|
97
|
+
# The "Add/Remove/Send Item" buttons.
|
|
98
|
+
box = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL)
|
|
99
|
+
box.set_layout(Gtk.ButtonBoxStyle.END)
|
|
100
|
+
self.mainBox.pack_start(box, False, False, 0)
|
|
101
|
+
dbGtkUtils.add_button_to_container(box, "Upload test", "Upload this test", self.upload_single_test)
|
|
102
|
+
dbGtkUtils.add_button_to_container(box, "Add Defect", "Click to add a defect", self.add_defect)
|
|
103
|
+
dbGtkUtils.add_button_to_container(box, "Add Comment", "Click to add a comment", self.add_comment)
|
|
104
|
+
|
|
105
|
+
# The notebook
|
|
106
|
+
self.notebook = Gtk.Notebook()
|
|
107
|
+
self.notebook.set_tab_pos(Gtk.PositionType.LEFT)
|
|
108
|
+
self.notebook.set_size_request(-1, 250)
|
|
109
|
+
self.mainBox.pack_start(self.notebook, True, True, 0)
|
|
110
|
+
|
|
111
|
+
# Create the Notebook pages
|
|
112
|
+
self.create_test_box("Visual Inspection", "VISUAL_INSPECTION")
|
|
113
|
+
self.create_test_box("Grounding", "GROUNDING_CHECK")
|
|
114
|
+
self.create_test_box("Pipe bending", "BENDING120")
|
|
115
|
+
self.create_test_box("Weight", "PETAL_CORE_WEIGHT")
|
|
116
|
+
self.create_test_box("Bot. loc. Diam", "PETAL_CORE_LOC_DIAM")
|
|
117
|
+
self.create_test_box("Slot loc. Diam", "PETAL_CORE_SLOT_DIAM")
|
|
118
|
+
self.create_test_box("X-rays", "XRAYIMAGING")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# The text view
|
|
122
|
+
self.mainBox.pack_end(self.message_panel.frame, True, True, 5)
|
|
123
|
+
|
|
124
|
+
# Set the default institute
|
|
125
|
+
dbGtkUtils.set_combo_iter(inst, self.institute)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
self.show_all()
|
|
129
|
+
|
|
130
|
+
def on_SN_changed(self, entry, value):
|
|
131
|
+
"""New SN given. Ask in PDB,"""
|
|
132
|
+
if len(value) <= 0:
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
self.query_db()
|
|
136
|
+
current_location = self.dbObject["currentLocation"]["code"]
|
|
137
|
+
dbGtkUtils.set_combo_iter(self.inst_cmb, current_location, 0)
|
|
138
|
+
|
|
139
|
+
stg = self.dbObject["currentStage"]["name"]
|
|
140
|
+
self.stage.set_text(stg)
|
|
141
|
+
|
|
142
|
+
entry.set_text(self.dbObject["serialNumber"])
|
|
143
|
+
|
|
144
|
+
alias = self.dbObject["alternativeIdentifier"]
|
|
145
|
+
self.alias.set_text(alias)
|
|
146
|
+
|
|
147
|
+
npages = self.notebook.get_n_pages()
|
|
148
|
+
for i in range(npages):
|
|
149
|
+
page = self.notebook.get_nth_page(i)
|
|
150
|
+
page.dict_dialog.factory_reset()
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def create_test_box(self, label, test_name, institute=None):
|
|
154
|
+
"""Create and add to notebook a test dialog.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
label: The label for the Notebook
|
|
158
|
+
test_name: The DB name of the test
|
|
159
|
+
institute: The institute.
|
|
160
|
+
|
|
161
|
+
"""
|
|
162
|
+
if institute is None:
|
|
163
|
+
institute = self.institute
|
|
164
|
+
|
|
165
|
+
defaults = {
|
|
166
|
+
"institution": institute,
|
|
167
|
+
"runNumber": "1",
|
|
168
|
+
}
|
|
169
|
+
dto = ITkDButils.get_test_skeleton(self.session, "CORE_PETAL", test_name, defaults)
|
|
170
|
+
if test_name == "VISUAL_INSPECTION":
|
|
171
|
+
scrolled, gM = dbGtkUtils.create_scrolled_dictdialog(dto, ("component", "testType", "results"))
|
|
172
|
+
else:
|
|
173
|
+
scrolled, gM = dbGtkUtils.create_scrolled_dictdialog(dto)
|
|
174
|
+
|
|
175
|
+
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
176
|
+
box.set_border_width(5)
|
|
177
|
+
box.pack_end(scrolled, True, True, 0)
|
|
178
|
+
box.dict_dialog = gM
|
|
179
|
+
gM.box = box
|
|
180
|
+
|
|
181
|
+
self.notebook.append_page(box, Gtk.Label(label=label))
|
|
182
|
+
|
|
183
|
+
return gM
|
|
184
|
+
|
|
185
|
+
def query_db(self, *args):
|
|
186
|
+
"""Search button clicked."""
|
|
187
|
+
SN = self.SN.get_text()
|
|
188
|
+
if len(SN) == 0:
|
|
189
|
+
dbGtkUtils.complain("Empty Serial number",
|
|
190
|
+
"You should enter a valid Serial number for the petal core.",
|
|
191
|
+
parent=self)
|
|
192
|
+
|
|
193
|
+
try:
|
|
194
|
+
self.dbObject = ITkDButils.get_DB_component(self.session, SN)
|
|
195
|
+
|
|
196
|
+
except Exception as E:
|
|
197
|
+
self.write_message(str(E)+'\n')
|
|
198
|
+
dbGtkUtils.complain("Could not find object in DB", str(E))
|
|
199
|
+
self.dbObject = None
|
|
200
|
+
return
|
|
201
|
+
|
|
202
|
+
#print(json.dumps(self.dbObject, indent=3))
|
|
203
|
+
|
|
204
|
+
def add_defect(self, btn):
|
|
205
|
+
"""Add a new defect."""
|
|
206
|
+
page = self.notebook.get_nth_page(self.notebook.get_current_page())
|
|
207
|
+
values = dbGtkUtils.get_a_list_of_values("Insert new defect", ("Type", "Description/v"))
|
|
208
|
+
if len(values)>0:
|
|
209
|
+
defect = {"name": values[0], "description": values[1]}
|
|
210
|
+
page.dict_dialog.values["defects"].append(defect)
|
|
211
|
+
page.dict_dialog.refresh()
|
|
212
|
+
|
|
213
|
+
def add_comment(self, btn):
|
|
214
|
+
"""Add a new comment."""
|
|
215
|
+
page = self.notebook.get_nth_page(self.notebook.get_current_page())
|
|
216
|
+
comment = dbGtkUtils.get_a_value("Insert new comment", is_tv=True)
|
|
217
|
+
if comment:
|
|
218
|
+
page.dict_dialog.values["comments"].append(comment)
|
|
219
|
+
page.dict_dialog.refresh()
|
|
220
|
+
|
|
221
|
+
def new_institute(self, combo):
|
|
222
|
+
"""A new institute has been selected."""
|
|
223
|
+
inst = self.get_institute_from_combo(combo)
|
|
224
|
+
if inst:
|
|
225
|
+
self.institute = inst
|
|
226
|
+
|
|
227
|
+
npages = self.notebook.get_n_pages()
|
|
228
|
+
for i in range(npages):
|
|
229
|
+
page = self.notebook.get_nth_page(i)
|
|
230
|
+
page.dict_dialog.values["institution"] = self.institute
|
|
231
|
+
page.dict_dialog.refresh()
|
|
232
|
+
|
|
233
|
+
def upload_this_test(self, values):
|
|
234
|
+
"""Upload a single test."""
|
|
235
|
+
# print(json.dumps(values, indent=2))
|
|
236
|
+
|
|
237
|
+
attachments = []
|
|
238
|
+
if values["testType"] == "XRAYIMAGING":
|
|
239
|
+
fnam = values["results"]["IMAGELINK"]
|
|
240
|
+
if fnam is not None and len(fnam)>0:
|
|
241
|
+
P = Path(fnam).expanduser().resolve()
|
|
242
|
+
if P.exists():
|
|
243
|
+
A = ITkDButils.Attachment(path=P.as_posix(), title=P.name, desc="X-ray image")
|
|
244
|
+
values["results"]["IMAGELINK"] = P.name
|
|
245
|
+
attachments.append(A)
|
|
246
|
+
|
|
247
|
+
# rc = ITkDButils.upload_test(self.session, values, attachments=attachments, check_runNumber=True)
|
|
248
|
+
# if rc is not None:
|
|
249
|
+
# dbGtkUtils.complain("Could not upload test", rc)
|
|
250
|
+
#
|
|
251
|
+
# else:
|
|
252
|
+
# self.write_message("Test uploaded. {} - {}\n".format(values["component"], values["testType"]))
|
|
253
|
+
uploadW = UploadTest.UploadTest(self.session, values, attachments)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def upload_single_test(self, *args):
|
|
257
|
+
"""Upload the current test."""
|
|
258
|
+
SN = self.SN.get_text()
|
|
259
|
+
if len(SN) == 0:
|
|
260
|
+
dbGtkUtils.complain("Petal SN is empty")
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
page = self.notebook.get_nth_page(self.notebook.get_current_page())
|
|
264
|
+
dctD = find_children(page)
|
|
265
|
+
if dctD is None:
|
|
266
|
+
return
|
|
267
|
+
|
|
268
|
+
values = copy.deepcopy(dctD.values)
|
|
269
|
+
values["component"] = SN
|
|
270
|
+
self.upload_this_test(values)
|
|
271
|
+
|
|
272
|
+
def upload_tests(self, *args):
|
|
273
|
+
"""Upload the current test."""
|
|
274
|
+
SN = self.SN.get_text()
|
|
275
|
+
if len(SN) == 0:
|
|
276
|
+
dbGtkUtils.complain("Petal SN is empty")
|
|
277
|
+
return
|
|
278
|
+
|
|
279
|
+
W = UploadMultipleTests.UploadMultipleTests(
|
|
280
|
+
self.session,
|
|
281
|
+
help_link="{}/uploadMultipleTests.html".format(HELP_LINK)
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
for ipage in range(self.notebook.get_n_pages()):
|
|
285
|
+
page = self.notebook.get_nth_page(ipage)
|
|
286
|
+
dctD = find_children(page)
|
|
287
|
+
if dctD is None:
|
|
288
|
+
continue
|
|
289
|
+
|
|
290
|
+
values = dctD.values
|
|
291
|
+
if values["testType"] == "XRAYIMAGING":
|
|
292
|
+
if values["institution"] != "IFIC":
|
|
293
|
+
continue
|
|
294
|
+
|
|
295
|
+
fnam = values["results"]["IMAGELINK"]
|
|
296
|
+
if fnam is None or len(fnam)==0:
|
|
297
|
+
continue
|
|
298
|
+
|
|
299
|
+
values["component"] = SN
|
|
300
|
+
W.add_test_data_to_view(values)
|
|
301
|
+
|
|
302
|
+
def main():
|
|
303
|
+
"""Main entry."""
|
|
304
|
+
# DB login
|
|
305
|
+
HELP_LINK="https://petal-qc.docs.cern.ch/petalReceptionTests.html"
|
|
306
|
+
|
|
307
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
308
|
+
client = dlg.get_client()
|
|
309
|
+
if client is None:
|
|
310
|
+
print("Could not connect to DB with provided credentials.")
|
|
311
|
+
dlg.die()
|
|
312
|
+
sys.exit()
|
|
313
|
+
|
|
314
|
+
client.user_gui = dlg
|
|
315
|
+
|
|
316
|
+
gTest = PetalReceptionTests(client, help_link=HELP_LINK)
|
|
317
|
+
|
|
318
|
+
gTest.present()
|
|
319
|
+
gTest.connect("destroy", Gtk.main_quit)
|
|
320
|
+
try:
|
|
321
|
+
Gtk.main()
|
|
322
|
+
|
|
323
|
+
except KeyboardInterrupt:
|
|
324
|
+
print("Arrrgggg!!!")
|
|
325
|
+
|
|
326
|
+
dlg.die()
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
if __name__ == "__main__":
|
|
330
|
+
main()
|
petal_qc/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""petal_qc python module."""
|
|
2
|
-
__version__ = "0.0.
|
|
2
|
+
__version__ = "0.0.15"
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def coreMetrology():
|
|
@@ -9,9 +9,14 @@ def coreMetrology():
|
|
|
9
9
|
|
|
10
10
|
def doMetrology():
|
|
11
11
|
"""Launches the Core metrology analysis in the command line."""
|
|
12
|
-
from .metrology.
|
|
12
|
+
from .metrology.do_Metrology import main
|
|
13
13
|
main()
|
|
14
14
|
|
|
15
|
+
def coreMetrologyTTY():
|
|
16
|
+
"""Launches the Core metrology analysis in the command line."""
|
|
17
|
+
from .metrology.do_Metrology import analyze_core_metrology
|
|
18
|
+
analyze_core_metrology()
|
|
19
|
+
|
|
15
20
|
def coreThermal():
|
|
16
21
|
"""Launches the Core thermal analysis ahd PDB script."""
|
|
17
22
|
from .thermal.coreThermal import main
|
|
@@ -38,6 +43,10 @@ def analyzeIRCore():
|
|
|
38
43
|
from .thermal.analyze_IRCore import main
|
|
39
44
|
main()
|
|
40
45
|
|
|
46
|
+
def petalReceptionTests():
|
|
47
|
+
"""GND/VI tests."""
|
|
48
|
+
from .PetalReceptionTests import main
|
|
49
|
+
main()
|
|
41
50
|
|
|
42
51
|
def dashBoard():
|
|
43
52
|
"""Launches the Core thermal analysis ahd PDB script."""
|
petal_qc/dashBoard.py
CHANGED
|
@@ -3,7 +3,7 @@ import sys
|
|
|
3
3
|
|
|
4
4
|
try:
|
|
5
5
|
import petal_qc
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
except ImportError:
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
cwd = Path(__file__).parent
|
|
@@ -12,6 +12,7 @@ except ImportError:
|
|
|
12
12
|
from petal_qc.metrology.coreMetrology import CoreMetrology, CoreMetrologyOptions
|
|
13
13
|
from petal_qc.thermal.coreThermal import CoreThermal
|
|
14
14
|
from petal_qc.thermal.IRPetalParam import IRPetalParam
|
|
15
|
+
from petal_qc.PetalReceptionTests import PetalReceptionTests
|
|
15
16
|
|
|
16
17
|
from itkdb_gtk import dbGtkUtils
|
|
17
18
|
from itkdb_gtk import ITkDBlogin
|
|
@@ -27,7 +28,8 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
27
28
|
"""Dashboard class."""
|
|
28
29
|
PETAL_CORE_METRO = 1
|
|
29
30
|
PETAL_CORE_THERMAL = 2
|
|
30
|
-
|
|
31
|
+
PETAL_RECEPTION_TEST = 3
|
|
32
|
+
|
|
31
33
|
|
|
32
34
|
def __init__(self, session):
|
|
33
35
|
"""Initialization."""
|
|
@@ -40,7 +42,7 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
40
42
|
# Prepare dashboard
|
|
41
43
|
grid = Gtk.Grid(column_spacing=5, row_spacing=5)
|
|
42
44
|
self.mainBox.pack_start(grid, False, True, 5)
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
irow = 0
|
|
45
47
|
lbl = Gtk.Label()
|
|
46
48
|
lbl.set_markup("<b>Tests</b>")
|
|
@@ -51,19 +53,34 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
51
53
|
btnPetalMetrology = Gtk.Button(label="Petal Core Metrology")
|
|
52
54
|
btnPetalMetrology.connect("clicked", self.petal_metrology)
|
|
53
55
|
grid.attach(btnPetalMetrology, 0, irow, 1, 1)
|
|
54
|
-
|
|
56
|
+
|
|
55
57
|
btnPetalThermal = Gtk.Button(label="Petal Core Thermal")
|
|
56
58
|
btnPetalThermal.connect("clicked", self.petal_thermal)
|
|
57
59
|
grid.attach(btnPetalThermal, 1, irow, 1, 1)
|
|
58
|
-
|
|
60
|
+
|
|
59
61
|
|
|
60
62
|
irow += 1
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
btnReception = Gtk.Button(label="Reception Tests")
|
|
64
|
+
btnReception.connect("clicked", self.petal_reception_test)
|
|
65
|
+
grid.attach(btnReception, 0, irow, 1, 1)
|
|
66
|
+
|
|
63
67
|
self.mainBox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), False, True, 5)
|
|
64
68
|
|
|
65
69
|
self.show_all()
|
|
66
|
-
|
|
70
|
+
|
|
71
|
+
def petal_reception_test(self, *args):
|
|
72
|
+
"""Do petal reception test."""
|
|
73
|
+
bitn = DashWindow.PETAL_RECEPTION_TEST
|
|
74
|
+
bt = 1 << bitn
|
|
75
|
+
if self.mask & bt:
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
self.mask |= bt
|
|
79
|
+
W = PetalReceptionTests(
|
|
80
|
+
self.session,
|
|
81
|
+
help_link="{}/petalReceptionTests.html".format(HELP_LINK)
|
|
82
|
+
)
|
|
83
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
67
84
|
|
|
68
85
|
def petal_metrology(self, *args):
|
|
69
86
|
"""Do petal metrology"""
|
|
@@ -103,7 +120,7 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
103
120
|
bt = 1 << args[1]
|
|
104
121
|
self.mask &= ~bt
|
|
105
122
|
# print(bt, self.mask)
|
|
106
|
-
|
|
123
|
+
|
|
107
124
|
def main():
|
|
108
125
|
"""Main entry"""
|
|
109
126
|
# DB login
|
|
@@ -243,34 +243,34 @@ def petal_metrology(ifile, options):
|
|
|
243
243
|
if key == "LOCATION_DELTA":
|
|
244
244
|
for k, v in val.items():
|
|
245
245
|
delta = np.linalg.norm(v)
|
|
246
|
-
if not check_spec(delta, 0.
|
|
246
|
+
if not check_spec(delta, 0.075):
|
|
247
247
|
dbOut["defects"].append({
|
|
248
248
|
"name": key,
|
|
249
|
-
"description": "Delta {} is {:.3f} mm > 0.
|
|
249
|
+
"description": "Delta {} is {:.3f} mm > 0.075 mm.".format(k, delta)
|
|
250
250
|
})
|
|
251
251
|
|
|
252
252
|
elif key == "REL_POS_DELTA":
|
|
253
253
|
for k, v in val.items():
|
|
254
254
|
delta = np.linalg.norm(v)
|
|
255
|
-
if not check_spec(delta, 0.
|
|
255
|
+
if not check_spec(delta, 0.075):
|
|
256
256
|
dbOut["defects"].append({
|
|
257
257
|
"name": key,
|
|
258
|
-
"description": "Delta {} is {:.3f} mm > 0.
|
|
258
|
+
"description": "Delta {} is {:.3f} mm > 0.075 mm.".format(k, delta)
|
|
259
259
|
})
|
|
260
260
|
|
|
261
|
-
elif "CHECK_" in key:
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
261
|
+
# elif "CHECK_" in key:
|
|
262
|
+
# if "OVERSIZE" in key:
|
|
263
|
+
# if not check_spec(abs(val), 0.050):
|
|
264
|
+
# dbOut["defects"].append({
|
|
265
|
+
# "name": key,
|
|
266
|
+
# "description": "LOC DIAM delta is {:.3f} mm > 0.050 mm.".format(abs(val))
|
|
267
|
+
# })
|
|
268
|
+
# else:
|
|
269
|
+
# if val < 0 or val > 0.012:
|
|
270
|
+
# dbOut["defects"].append({
|
|
271
|
+
# "name": key,
|
|
272
|
+
# "description": "LOC DIAM is not H7 0 <= {:.3f} <= 0.012 mm.".format(val)
|
|
273
|
+
# })
|
|
274
274
|
|
|
275
275
|
ofile.close()
|
|
276
276
|
|
|
@@ -513,12 +513,12 @@ def locking_point_positions(positions, document=None):
|
|
|
513
513
|
dPL2 = np.linalg.norm(positions[1, 0:2] - positions[4, 0:2])
|
|
514
514
|
deltaPL1 = (nPL1-dPL1)
|
|
515
515
|
deltaPL2 = (nPL2-dPL2)
|
|
516
|
-
fPL1 = "PASSED" if abs(deltaPL1) <= 0.
|
|
517
|
-
fPL2 = "PASSED" if abs(deltaPL2) <= 0.
|
|
516
|
+
fPL1 = "PASSED" if abs(deltaPL1) <= 0.075 else "FAILED"
|
|
517
|
+
fPL2 = "PASSED" if abs(deltaPL2) <= 0.075 else "FAILED"
|
|
518
518
|
|
|
519
519
|
for key, val in outDB["REL_POS_DELTA"].items():
|
|
520
520
|
deltaPL = np.linalg.norm(val)
|
|
521
|
-
fPL = "PASSED" if abs(deltaPL) <= 0.
|
|
521
|
+
fPL = "PASSED" if abs(deltaPL) <= 0.075 else "FAILED"
|
|
522
522
|
print("Distance {}: {:.3f} mm ({})".format(key, deltaPL, fPL))
|
|
523
523
|
|
|
524
524
|
if document:
|
|
@@ -559,7 +559,7 @@ def locking_point_positions(positions, document=None):
|
|
|
559
559
|
document.add_paragraph("")
|
|
560
560
|
for key, val in outDB["REL_POS_DELTA"].items():
|
|
561
561
|
deltaPL = np.linalg.norm(val)
|
|
562
|
-
fPL = "PASSED" if abs(deltaPL) <= 0.
|
|
562
|
+
fPL = "PASSED" if abs(deltaPL) <= 0.075 else "FAILED"
|
|
563
563
|
document.add_paragraph("Distance {}: {:.3f} mm ({})".format(key, deltaPL, fPL))
|
|
564
564
|
|
|
565
565
|
return outDB
|
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
import argparse
|
|
6
6
|
import glob
|
|
7
7
|
import json
|
|
8
|
+
import math
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
import numpy as np
|
|
10
11
|
import matplotlib.pyplot as plt
|
|
@@ -100,17 +101,22 @@ def draw_deltas(data, keys, fnam=None, title="Front", draw_text=True):
|
|
|
100
101
|
P = [np.zeros([nfiles, 2]),
|
|
101
102
|
np.zeros([nfiles, 2]),
|
|
102
103
|
np.zeros([nfiles, 2])]
|
|
104
|
+
D = [[],[],[]]
|
|
105
|
+
|
|
103
106
|
fig_width = 12.0
|
|
104
107
|
fig_height = 1.2*fig_width/3.0
|
|
105
108
|
fig, ax = plt.subplots(nrows=1, ncols=3, tight_layout=True, figsize=(fig_width, fig_height))
|
|
106
109
|
fig.suptitle(title)
|
|
110
|
+
figb, bx = plt.subplots(nrows=1, ncols=3, tight_layout=True, figsize=(fig_width, fig_height))
|
|
111
|
+
figb.suptitle(title)
|
|
112
|
+
|
|
107
113
|
for i in range(3):
|
|
108
114
|
LBL = [[],[],[]]
|
|
109
115
|
ax[i].set_title(keys[i])
|
|
110
116
|
ax[i].set_aspect('equal', adjustable='box')
|
|
111
|
-
ax[i].set_xlim(-
|
|
112
|
-
ax[i].set_ylim(-
|
|
113
|
-
circle = plt.Circle((0,0),
|
|
117
|
+
ax[i].set_xlim(-150, 150)
|
|
118
|
+
ax[i].set_ylim(-150, 150)
|
|
119
|
+
circle = plt.Circle((0,0), 75, color="red", alpha=0.25)
|
|
114
120
|
ax[i].add_patch(circle)
|
|
115
121
|
circle = plt.Circle((0,0), 25, color="green", alpha=0.25)
|
|
116
122
|
ax[i].add_patch(circle)
|
|
@@ -118,20 +124,34 @@ def draw_deltas(data, keys, fnam=None, title="Front", draw_text=True):
|
|
|
118
124
|
ax[i].set_xlabel("X (µm)")
|
|
119
125
|
ax[i].set_ylabel("Y (µm)")
|
|
120
126
|
ax[i].grid()
|
|
127
|
+
|
|
128
|
+
bx[i].set_title(keys[i])
|
|
129
|
+
bx[i].set_xlabel("Distance (µm)")
|
|
130
|
+
bx[i].grid()
|
|
131
|
+
|
|
121
132
|
|
|
122
133
|
for j, v in enumerate(data.items()):
|
|
123
134
|
label, values = v
|
|
124
135
|
for k in range(3):
|
|
125
136
|
ky = key_table[keys[k]]
|
|
126
|
-
|
|
137
|
+
point = 1000*np.array(values[ky])
|
|
138
|
+
P[k][j, :] = point
|
|
139
|
+
D[k].append(math.sqrt(point[0]**2+point[1]**2))
|
|
127
140
|
LBL[k].append(label.split('.')[1].lstrip('0'))
|
|
128
141
|
|
|
142
|
+
bx[i].hist(D[i], bins=15, range=(0, 150))
|
|
129
143
|
ax[i].scatter(P[i][:,0], P[i][:,1])
|
|
130
144
|
if draw_text:
|
|
131
145
|
for j in range(len(LBL[i])):
|
|
132
146
|
ax[i].text(P[i][j,0], P[i][j,1], LBL[i][j]) #, ha='center', va='top')
|
|
133
147
|
|
|
148
|
+
ofile = Path(fnam).expanduser().resolve()
|
|
149
|
+
print("* parent: ", ofile.parent)
|
|
150
|
+
print("* stem: ", ofile.stem)
|
|
151
|
+
bnam = ofile.parent / "{}-h.png".format(ofile.stem)
|
|
152
|
+
print(bnam.as_posix())
|
|
134
153
|
save_figure(fig, fnam, prefix=title)
|
|
154
|
+
save_figure(figb, bnam, prefix=title)
|
|
135
155
|
|
|
136
156
|
|
|
137
157
|
def show_positions(options):
|
|
@@ -184,6 +204,7 @@ def show_flatness(options):
|
|
|
184
204
|
a.set_ylim(0, 1.2*max(y_lim[0][1], y_lim[1][1]))
|
|
185
205
|
x_lim = a.get_xlim()
|
|
186
206
|
a.fill_between(x_lim, 0, 0.050, facecolor="darkseagreen", alpha=0.1)
|
|
207
|
+
a.fill_between(x_lim, 0.050, 0.100, facecolor="mediumseagreen", alpha=0.1)
|
|
187
208
|
if not options.no_legend:
|
|
188
209
|
a.legend(ncol=3, fontsize="x-small")
|
|
189
210
|
|
|
@@ -68,6 +68,7 @@ def do_analysis(fnam, prefix, SN, options):
|
|
|
68
68
|
|
|
69
69
|
def analyze_files(ifile, options):
|
|
70
70
|
"""Main entry."""
|
|
71
|
+
failed_files = []
|
|
71
72
|
with open(ifile, 'r', encoding='UTF-8') as inp:
|
|
72
73
|
|
|
73
74
|
for line in inp:
|
|
@@ -84,10 +85,26 @@ def analyze_files(ifile, options):
|
|
|
84
85
|
except Exception:
|
|
85
86
|
fnam, prefix, SN, *_ = line.split()
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
try:
|
|
89
|
+
with open(fnam, "r", encoding="ISO-8859-1") as fin:
|
|
90
|
+
ss = fin.read()
|
|
91
|
+
if ss.find("Punto:")<0:
|
|
92
|
+
options.desy=True
|
|
93
|
+
else:
|
|
94
|
+
options.desy=False
|
|
95
|
+
|
|
96
|
+
do_analysis(fnam, prefix, SN, options)
|
|
97
|
+
print("\n\n")
|
|
98
|
+
except Exception as E:
|
|
99
|
+
failed_files.append([fnam, E])
|
|
100
|
+
continue
|
|
88
101
|
|
|
89
|
-
|
|
90
|
-
|
|
102
|
+
if len(failed_files)>0:
|
|
103
|
+
for fnam, E in failed_files:
|
|
104
|
+
print("### Failed file {}\n{}".format(fnam, E))
|
|
105
|
+
|
|
106
|
+
def parse_options():
|
|
107
|
+
"""Parse command line options."""
|
|
91
108
|
parser = ArgumentParser()
|
|
92
109
|
parser.add_argument('files', nargs='*', help="Input files")
|
|
93
110
|
parser.add_argument("--prefix", dest='prefix', default=None, help="prefix telling if it is front or back.")
|
|
@@ -113,11 +130,21 @@ def main():
|
|
|
113
130
|
print("I need an input file")
|
|
114
131
|
sys.exit()
|
|
115
132
|
|
|
133
|
+
return options
|
|
134
|
+
|
|
135
|
+
def main():
|
|
136
|
+
"Main entry."
|
|
137
|
+
options = parse_options()
|
|
116
138
|
try:
|
|
117
139
|
analyze_files(options.files[0], options)
|
|
118
140
|
|
|
119
141
|
except Exception:
|
|
120
142
|
print(traceback.format_exc())
|
|
121
143
|
|
|
144
|
+
def analyze_core_metrology():
|
|
145
|
+
"""Do a single file analysis."""
|
|
146
|
+
options = parse_options()
|
|
147
|
+
do_analysis(options.files[0], options.prefix, options.SN, options)
|
|
148
|
+
|
|
122
149
|
if __name__ == "__main__":
|
|
123
150
|
main()
|