petal-qc 0.0.9__py3-none-any.whl → 0.0.11__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.

Files changed (36) hide show
  1. petal_qc/BTreport/CheckBTtests.py +2 -6
  2. petal_qc/__init__.py +17 -1
  3. petal_qc/metrology/PetalMetrology.py +0 -5
  4. petal_qc/metrology/compare_Cores.py +27 -15
  5. petal_qc/metrology/coreMetrology.py +20 -10
  6. petal_qc/metrology/do_Metrology.py +0 -5
  7. petal_qc/metrology/petal_flatness.py +0 -4
  8. petal_qc/metrology/readAVSdata.py +762 -0
  9. petal_qc/metrology/uploadPetalInformation.py +769 -0
  10. petal_qc/test/checkAVStests.py +181 -0
  11. petal_qc/test/compare_golden.py +44 -0
  12. petal_qc/test/getAVSjson.py +27 -0
  13. petal_qc/test/getAVStests.py +263 -0
  14. petal_qc/test/getPetalCoreTestSummary.py +89 -0
  15. petal_qc/test/listPetalCoreComponents.py +89 -0
  16. petal_qc/test/prepareDESYfiles.py +25 -8
  17. petal_qc/thermal/DESYdata.py +58 -0
  18. petal_qc/thermal/IRBFile.py +51 -7
  19. petal_qc/thermal/IRCore.py +1 -1
  20. petal_qc/thermal/IRDataGetter.py +43 -24
  21. petal_qc/thermal/IRPetal.py +84 -7
  22. petal_qc/thermal/IRPetalParam.py +1 -1
  23. petal_qc/thermal/Petal_IR_Analysis.py +4 -3
  24. petal_qc/thermal/PipeFit.py +12 -3
  25. petal_qc/thermal/analyze_IRCore.py +24 -15
  26. petal_qc/thermal/coreThermal.py +124 -28
  27. petal_qc/thermal/create_IRCore.py +35 -9
  28. petal_qc/thermal/create_core_report.py +31 -8
  29. petal_qc/utils/Geometry.py +2 -2
  30. petal_qc/utils/readGraphana.py +2 -1
  31. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/METADATA +2 -2
  32. petal_qc-0.0.11.dist-info/RECORD +70 -0
  33. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/WHEEL +1 -1
  34. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/entry_points.txt +3 -0
  35. petal_qc-0.0.9.dist-info/RECORD +0 -61
  36. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,769 @@
1
+ #!/usr/bin/env python3
2
+ """Uploads data from AVS pdf."""
3
+ import json
4
+ import sys
5
+ from argparse import ArgumentParser
6
+ from datetime import datetime, timezone
7
+ from pathlib import Path
8
+ import dateutil.parser
9
+ import gi
10
+
11
+ gi.require_version("Gtk", "3.0")
12
+ from gi.repository import Gtk, Gio
13
+
14
+ try:
15
+ import itkdb_gtk
16
+
17
+ except ImportError:
18
+ cwd = Path(__file__).parent.parent
19
+ sys.path.append(cwd.as_posix())
20
+
21
+ from itkdb_gtk import ITkDBlogin, ITkDButils, dbGtkUtils
22
+ from petal_qc.metrology import readAVSdata
23
+
24
+ __HELP_LINK__="https://petal-qc.docs.cern.ch/uploadPetalInformation.html"
25
+
26
+ def create_scrolled_dictdialog(the_dict, hidden=("component", "testType")):
27
+ """Create a DictDialog within a scrolled window.
28
+
29
+ Return:
30
+ ------
31
+ scrolled: the scrolled window
32
+ gM: the DictDialog
33
+
34
+ """
35
+ gM = dbGtkUtils.DictDialog(the_dict, hidden)
36
+ scrolled = Gtk.ScrolledWindow()
37
+ scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
38
+ scrolled.add(gM)
39
+ return scrolled, gM
40
+
41
+
42
+ def get_type(child):
43
+ """Return object type
44
+
45
+ Args:
46
+ child (): object
47
+
48
+ Returns:
49
+ str: object type
50
+
51
+ """
52
+ if child["type"] is not None:
53
+ ctype = child["type"]["code"]
54
+ else:
55
+ ctype = child["componentType"]["code"]
56
+
57
+ return ctype
58
+
59
+ class AVSPanel(dbGtkUtils.ITkDBWindow):
60
+ """Dialog for interaction with DB."""
61
+
62
+ def __init__(self, session, options):
63
+ """Initialization."""
64
+ super().__init__(session=session, title="Upload AVS Data", show_search="Click to search SN in DB", help_link=__HELP_LINK__)
65
+ self.test_uploaded = {}
66
+ self.test_list = []
67
+ self.test_index = {}
68
+ self.test_panel = {}
69
+ self.test_map = {}
70
+ self.petal_core = None
71
+ self.alias = None
72
+ self.petal_weight = -1
73
+ self.DESY_comp = {}
74
+ # self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
75
+
76
+ #
77
+ # Prepare HeaderBar
78
+ self.hb.props.title = "DB Upload Petal Data"
79
+
80
+ button = Gtk.Button()
81
+ icon = Gio.ThemedIcon(name="document-send-symbolic")
82
+ image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
83
+ button.add(image)
84
+ button.set_tooltip_text("Click to upload test shown in notebook.")
85
+ button.connect("clicked", self.upload_current_test)
86
+ self.hb.pack_end(button)
87
+
88
+ button = Gtk.Button()
89
+ icon = Gio.ThemedIcon(name="emblem-documents-symbolic")
90
+ image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
91
+ button.add(image)
92
+ button.set_tooltip_text("Click to upload AVS files.")
93
+ button.connect("clicked", self.upload_avs_files)
94
+ self.hb.pack_end(button)
95
+
96
+ # PS file entry and search button
97
+ self.btnPSF = Gtk.FileChooserButton()
98
+ self.btnPSF.connect("file-set", self.on_psf_set)
99
+ if options.PS:
100
+ ifile = Path(options.PS).expanduser().resolve().as_posix()
101
+ self.btnPSF.set_filename(ifile)
102
+ self.on_psf_set()
103
+
104
+ # FAT file entry and seach buttin
105
+ self.btnFAT = Gtk.FileChooserButton()
106
+ self.btnFAT.connect("file-set", self.on_fat_set)
107
+ if options.FAT:
108
+ ifile = Path(options.FAT).expanduser().resolve().as_posix()
109
+ self.btnFAT.set_filename(ifile)
110
+
111
+ # The Serial number
112
+ self.SN = Gtk.Entry()
113
+ # self.SN.connect("changed", self.SN_changed)
114
+ if options.SN:
115
+ self.SN.set_text(options.SN)
116
+
117
+ # Put the 3 objects in a Grid
118
+ grid = Gtk.Grid(column_spacing=5, row_spacing=1)
119
+ self.mainBox.pack_start(grid, False, True, 0)
120
+
121
+ self.btn_state = Gtk.Button(label="Undef")
122
+ self.btn_state.set_name("btnState")
123
+ self.btn_state.connect("clicked", self.show_state)
124
+ self.btn_state.set_tooltip_text("If green all good. Click to see commnets and defects.")
125
+
126
+ grid.attach(Gtk.Label(label="Serial No."), 0, 0, 1, 1)
127
+ grid.attach(self.SN, 1, 0, 1, 1)
128
+ grid.attach(self.btn_state, 2, 0, 1, 1)
129
+
130
+
131
+ grid.attach(Gtk.Label(label="Prod. Sheet"), 0, 1, 1, 1)
132
+ grid.attach(self.btnPSF, 1, 1, 1, 1)
133
+
134
+ btn = Gtk.Button(label="Reset")
135
+ btn.connect("clicked", self.on_reset)
136
+ grid.attach(btn, 2, 1, 1, 1)
137
+
138
+ grid.attach(Gtk.Label(label="FAT file"), 0, 2, 1, 1)
139
+ grid.attach(self.btnFAT, 1, 2, 1, 1)
140
+
141
+ # Add a Separator
142
+ self.mainBox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.VERTICAL), False, True, 0)
143
+
144
+ # The notebook
145
+ self.notebook = Gtk.Notebook()
146
+ self.notebook.set_tab_pos(Gtk.PositionType.LEFT)
147
+ self.mainBox.pack_start(self.notebook, True, True, 20)
148
+
149
+ # Create the Notebook pages
150
+ defaults = {
151
+ "institution": "AVS",
152
+ "runNumber": 1,
153
+ }
154
+
155
+ self.manufacture = self.create_test_window(
156
+ ITkDButils.get_test_skeleton(
157
+ self.session, "CORE_PETAL", "MANUFACTURING", defaults),
158
+ "manufacture", "Manufacture")
159
+
160
+ self.weights = self.create_test_window(
161
+ ITkDButils.get_test_skeleton(
162
+ self.session, "CORE_PETAL", "WEIGHING", defaults),
163
+ "weights", "Weights")
164
+
165
+ self.delamination = self.create_test_window(
166
+ ITkDButils.get_test_skeleton(
167
+ self.session, "CORE_PETAL", "DELAMINATION", defaults),
168
+ "delamination", "Delamination")
169
+
170
+ self.grounding = self.create_test_window(
171
+ ITkDButils.get_test_skeleton(
172
+ self.session, "CORE_PETAL", "GROUNDING_CHECK", defaults),
173
+ "grounding", "Grounding")
174
+
175
+ self.metrology = self.create_test_window(
176
+ ITkDButils.get_test_skeleton(
177
+ self.session, "CORE_PETAL", "METROLOGY_AVS", defaults),
178
+ "metrology", "Metrology")
179
+
180
+ self.visual_inspection = self.create_test_window(
181
+ ITkDButils.get_test_skeleton(
182
+ self.session, "CORE_PETAL", "VISUAL_INSPECTION", defaults),
183
+ "visual_inspection", "Visual Inspection")
184
+
185
+ # List componentes
186
+ self.components = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
187
+ self.components.set_border_width(5)
188
+ self.notebook.append_page(self.components, Gtk.Label(label="Components"))
189
+
190
+ # The button box
191
+ btnBox = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL)
192
+
193
+ # btn = Gtk.Button(label="Reload AVS files")
194
+ # btn.connect("clicked", self.read_avs_files)
195
+ # btnBox.add(btn)
196
+
197
+ btn = Gtk.Button(label="Assemble")
198
+ btn.set_tooltip_text("Assemble components in DB")
199
+ btn.connect("clicked", self.on_assembly)
200
+ btnBox.add(btn)
201
+
202
+ btn = Gtk.Button(label="Check Components")
203
+ btn.set_tooltip_text("Check components in DB")
204
+ btn.connect("clicked", self.on_check_components)
205
+ btnBox.add(btn)
206
+
207
+ btn = Gtk.Button(label="Check Tests")
208
+ btn.set_tooltip_text("Check test results")
209
+ btn.connect("clicked", self.on_check_tests)
210
+ btnBox.add(btn)
211
+
212
+ btn = Gtk.Button(label="Upload Tests")
213
+ btn.set_tooltip_text("Upload all tests")
214
+
215
+ btn.connect("clicked", self.on_upload)
216
+ btnBox.add(btn)
217
+
218
+ self.mainBox.pack_start(btnBox, False, True, 0)
219
+ self.connect("destroy", Gtk.main_quit)
220
+
221
+
222
+ # The text view
223
+ self.mainBox.pack_start(self.message_panel.frame, True, True, 5)
224
+
225
+ self.show_all()
226
+
227
+
228
+ def show_state(self, *arg):
229
+ """Shows the status"""
230
+ msg = ""
231
+ for test in self.test_list:
232
+ values = test.values
233
+ ndef = len(values["defects"])
234
+ ncomm = len(values["comments"])
235
+ if ndef==0 and ncomm==0:
236
+ continue
237
+
238
+ msg += "{}\n".format(values["testType"])
239
+ if ndef:
240
+ msg += "Defects\n"
241
+
242
+ for D in values["defects"]:
243
+ msg += "{}: {}\n".format(D["name"], D["description"])
244
+
245
+ if ncomm:
246
+ msg += "Comments\n"
247
+
248
+ for C in values["comments"]:
249
+ msg += "{}\n".format(C)
250
+
251
+ msg += "\n"
252
+
253
+ dialog = Gtk.MessageDialog(
254
+ transient_for=self,
255
+ flags=0,
256
+ message_type=Gtk.MessageType.INFO,
257
+ buttons=Gtk.ButtonsType.OK,
258
+ text="Problems found",
259
+ )
260
+
261
+ dialog.format_secondary_text(msg)
262
+ dialog.run()
263
+ dialog.destroy()
264
+
265
+ def on_reset(self, *args):
266
+ """Reset SN"""
267
+ self.petal_core = None
268
+ self.alias = None
269
+ self.SN.set_text("")
270
+ self.btnPSF.unselect_all()
271
+ self.btnFAT.unselect_all()
272
+ self.btn_state.set_label("Undef")
273
+ dbGtkUtils.set_button_color(self.btn_state, "azure", "black")
274
+
275
+
276
+ def create_test_window(self, test_json, test_name, label):
277
+ """Create the dialog for a DB test and add it to the notebook.
278
+
279
+ Args:
280
+ test_json: The JSon-like dict with the values
281
+ test_name: The name of the test for internal indexing
282
+ label: The label for the Notebook
283
+
284
+ Returns:
285
+ The box containing the data.
286
+
287
+ """
288
+ scrolled, gM = create_scrolled_dictdialog(test_json)
289
+ self.test_list.append(gM)
290
+ self.test_index[test_name] = len(self.test_list) - 1
291
+ self.test_map[test_json["testType"]] = test_name
292
+
293
+ box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
294
+ box.set_border_width(5)
295
+ box.pack_end(scrolled, True, True, 0)
296
+ box.dict_dialog = gM
297
+ gM.box = box
298
+ self.test_panel[test_name] = box
299
+ self.notebook.append_page(box, Gtk.Label(label=label))
300
+
301
+ return box
302
+
303
+ def update_scroll_window(self, key, data):
304
+ """Update panel for a given test."""
305
+ scrolled, gM = create_scrolled_dictdialog(data, ("component", "testType"))
306
+ self.test_list[self.test_index[key]] = gM
307
+ dbGtkUtils.replace_in_container(self.test_panel[key], scrolled)
308
+
309
+ def check_register_petal(self, SN):
310
+ """Register petal core in DB.
311
+
312
+ Args:
313
+ SN: The petal Serial Number.
314
+
315
+ """
316
+ if self.petal_core:
317
+ return
318
+
319
+ self.find_petal(SN, silent=True)
320
+ if self.petal_core:
321
+ return
322
+
323
+ dialog = Gtk.MessageDialog(
324
+ transient_for=self,
325
+ flags=0,
326
+ message_type=Gtk.MessageType.INFO,
327
+ text="Register Petal Core\n{}".format(SN)
328
+ )
329
+ dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
330
+ Gtk.STOCK_OK, Gtk.ResponseType.OK)
331
+ dialog.set_border_width(10)
332
+ dialog.format_secondary_text("Enter Petal Core Alias")
333
+ alias = Gtk.Entry(text=self.alias)
334
+ box = dialog.get_content_area()
335
+ box.add(alias)
336
+ dialog.show_all()
337
+ out = dialog.run()
338
+ if out == Gtk.ResponseType.OK:
339
+ petal_alias = alias.get_text().strip()
340
+ if len(petal_alias) == 0:
341
+ petal_alias = self.alias
342
+
343
+ rc = ITkDButils.registerPetalCore(self.session, SN, petal_alias)
344
+ if rc is None:
345
+ dbGtkUtils.complain("Could not Register petal {} ({})".format(SN, petal_alias))
346
+
347
+ dialog.hide()
348
+ dialog.destroy()
349
+
350
+ def get_app_petal_serial_number(self):
351
+ """Get the SN from the text box."""
352
+ txt_SN = self.SN.get_text().strip()
353
+ return txt_SN
354
+
355
+ def check_petal_serial_number(self, SN):
356
+ """Check tha the given SN is consistent."""
357
+ txt_SN = self.get_app_petal_serial_number()
358
+ if txt_SN and len(txt_SN):
359
+ if txt_SN != SN.strip():
360
+ return False
361
+
362
+ else:
363
+ return True
364
+
365
+ else:
366
+ self.check_register_petal(SN)
367
+ self.SN.set_text(SN)
368
+ return True
369
+
370
+ def on_psf_set(self, *args):
371
+ """Production Sheet file selected."""
372
+ PSF = self.btnPSF.get_filename()
373
+ if PSF is None or not Path(PSF).exists():
374
+ dbGtkUtils.complain("Could not find Production File", PSF, parent=self)
375
+ return
376
+
377
+ try:
378
+ manuf_json, weights_json, self.DESY_comp, self.alias = readAVSdata.readProductionSheet(self.session, PSF, "SNnnnn")
379
+ if self.petal_weight > 0:
380
+ weights_json["results"]["WEIGHT_CORE"] = self.petal_weight
381
+
382
+ except readAVSdata.AVSDataException as E:
383
+ dbGtkUtils.complain("Wrong Production Sheet file", str(E))
384
+ self.btnPSF.unselect_all()
385
+ return
386
+
387
+ SN = manuf_json["component"]
388
+ if not self.check_petal_serial_number(SN):
389
+ dbGtkUtils.complain("Inconsistent Serial number found.",
390
+ "Wrong Serial number extracted from the Production Sheet document.\n{}".format(PSF))
391
+ self.btnPSF.unselect_all()
392
+ return
393
+
394
+ scrolled, gM = create_scrolled_dictdialog(manuf_json, ("component", "testType"))
395
+ self.test_list[self.test_index["manufacture"]] = gM
396
+ dbGtkUtils.replace_in_container(self.manufacture, scrolled)
397
+
398
+ scrolled, gM = create_scrolled_dictdialog(weights_json, ("component", "testType"))
399
+ self.test_list[self.test_index["weights"]] = gM
400
+ dbGtkUtils.replace_in_container(self.weights, scrolled)
401
+
402
+ gD = dbGtkUtils.DictDialog(self.DESY_comp)
403
+ dbGtkUtils.replace_in_container(self.components, gD)
404
+
405
+ # Check if we need to assemble the module
406
+ self.check_assembly(self.DESY_comp)
407
+
408
+ self.check_components()
409
+
410
+ def on_fat_set(self, *args):
411
+ """FAT file selected."""
412
+ FAT = self.btnFAT.get_filename()
413
+ if FAT is None or not Path(FAT).exists():
414
+ dbGtkUtils.complain("Could not find FAT File", FAT, parent=self)
415
+
416
+ try:
417
+ SN = self.get_app_petal_serial_number()
418
+ if SN and not SN.startswith("20USEBC"):
419
+ SN = None
420
+
421
+ j_vi, j_del, j_gnd, j_mtr, batch, self.petal_weight = readAVSdata.readFATfile(self.session, FAT, SN)
422
+ self.test_list[self.test_index["weights"]].set_value("results.WEIGHT_CORE", self.petal_weight)
423
+
424
+ except readAVSdata.AVSDataException as E:
425
+ dbGtkUtils.complain("Wrong FAT file", str(E))
426
+ self.btnFAT.unselect_all()
427
+ return
428
+
429
+ SN = j_vi["component"]
430
+ if not self.check_petal_serial_number(SN):
431
+ dbGtkUtils.complain("Inconsistent Serial number found.",
432
+ "Wrong Serial number extracted from the FAT document.\n{}".format(FAT))
433
+ self.btnFAT.unselect_all()
434
+ return
435
+
436
+ self.update_scroll_window("visual_inspection", j_vi)
437
+ self.update_scroll_window("delamination", j_del)
438
+ self.update_scroll_window("grounding", j_gnd)
439
+ self.update_scroll_window("metrology", j_mtr)
440
+
441
+ self.check_tests(True)
442
+
443
+ def read_avs_files(self, widgets):
444
+ """Read AVS files."""
445
+ PSF = self.btnPSF.get_filename()
446
+ if PSF is not None:
447
+ self.on_psf_set(None)
448
+
449
+ FAT = self.btnFAT.get_filename()
450
+ if FAT is not None:
451
+ self.on_fat_set(None)
452
+
453
+ return
454
+
455
+ def find_petal(self, SN, silent=False):
456
+ """Finds petal with given SN."""
457
+ try:
458
+ self.petal_core = ITkDButils.get_DB_component(self.session, SN)
459
+
460
+ except Exception as E:
461
+ if not silent:
462
+ dbGtkUtils.complain("Could not find Petal Core in DB", str(E))
463
+
464
+ self.petal_core = None
465
+ return
466
+
467
+ if self.petal_core is None:
468
+ return
469
+
470
+ try:
471
+ if self.petal_core["type"]["code"] != "CORE_AVS":
472
+ dbGtkUtils.complain("Wrong component type", "This is not an AVS petal core")
473
+
474
+ if self.petal_core["currentStage"]["code"] != "ASSEMBLY":
475
+ dbGtkUtils.complain("Wrong component stage", "Wrong stage: {}".format(self.petal_core["currentStage"]["code"]))
476
+
477
+ self.write_message("{}\n".format(json.dumps(self.petal_core, indent=3)))
478
+
479
+ except KeyError:
480
+ # Petal is not there
481
+ self.petal_core = None
482
+
483
+ def query_db(self, *args):
484
+ """Called when QueryDB button clicked."""
485
+ SN = self.SN.get_text()
486
+ if len(SN) == 0:
487
+ dbGtkUtils.complain("Empty Serial number",
488
+ "You should enter a valid Serial number for the petal core.",
489
+ parent=self)
490
+ self.petal_core = None
491
+ return
492
+
493
+ # if not checkSerialNumber(SN):
494
+ # dbGtkUtils.complain("Wrong Serial number",
495
+ # "You should enter a valid Serial number for the petal core.",
496
+ # parent=self)
497
+ # return
498
+ self.find_petal(SN)
499
+
500
+ if self.btnFAT.get_filename() is None and self.btnPSF.get_filename() is None:
501
+ # update tests from DB
502
+ for test in self.petal_core["tests"]:
503
+ latest = None
504
+ latest_time = datetime(year=1, month=1, day=1, tzinfo=timezone.utc)
505
+ testType = test["code"]
506
+ for T in test["testRuns"]:
507
+ test_date = dateutil.parser.parse(T["cts"])
508
+ if test_date > latest_time:
509
+ latest_time = test_date
510
+ latest = T["id"]
511
+
512
+ dbT = ITkDButils.get_testrun(self.session, latest)
513
+ testDB = ITkDButils.from_full_test_to_test_data(dbT)
514
+ self.update_scroll_window(self.test_map[testType], testDB)
515
+
516
+ def on_check_components(self, *args):
517
+ """Button clicked."""
518
+ self.check_components()
519
+
520
+ def check_components(self):
521
+ """Check that components are in DB."""
522
+ for cmp, cmp_SN in self.DESY_comp.items():
523
+ if not (isinstance(cmp_SN, str) and cmp_SN.startswith("20U")):
524
+ continue
525
+
526
+ out = ITkDButils.get_DB_component(self.session, cmp_SN)
527
+ if out is None:
528
+ self.write_message("{}: not in DB\n".format(cmp))
529
+ else:
530
+ self.write_message("{}: in {}\n".format(cmp, out["currentLocation"]["code"]))
531
+
532
+
533
+ def check_assembly(self, components):
534
+ """Check if we need to assemble components to core."""
535
+ if self.petal_core is None:
536
+ self.query_db()
537
+ if self.petal_core is None:
538
+ return
539
+
540
+ comp_map = {
541
+ "BT_PETAL_FRONT": "FacingFront",
542
+ "BT_PETAL_BACK": "FacingBack",
543
+ "COOLING_LOOP_PETAL": "CoolingLoop",
544
+ "THERMALFOAMSET_PETAL": "AllcompSet"
545
+ }
546
+ final_stage = {
547
+ "BT_PETAL_FRONT": "COMPLETED",
548
+ "BT_PETAL_BACK": "COMPLETED",
549
+ "COOLING_LOOP_PETAL": "CLINCORE",
550
+ "THERMALFOAMSET_PETAL": "IN_CORE"
551
+ }
552
+ missing = []
553
+ for child in self.petal_core["children"]:
554
+ if child["component"] is None:
555
+ if child["type"] is not None:
556
+ ctype = child["type"]["code"]
557
+ else:
558
+ ctype = child["componentType"]["code"]
559
+
560
+ missing.append(ctype)
561
+
562
+ if len(missing) == 0:
563
+ return
564
+
565
+ error_txt = []
566
+ txt = "Click OK to add\n\t{}".format("\n\t".join(missing))
567
+ if dbGtkUtils.ask_for_confirmation("Missing components", txt, parent=self):
568
+ this_petal = self.SN.get_text()
569
+ for cmp in missing:
570
+ SN = components[comp_map[cmp]]
571
+ if SN[0:5] == "20USE":
572
+ rc = ITkDButils.assemble_component(self.session, this_petal, SN)
573
+ if rc is None:
574
+ error_txt.append("Problem assembling {} into Petal\n".format(cmp))
575
+
576
+ # Check for child stage
577
+ cobj = ITkDButils.get_DB_component(self.session, SN)
578
+ ctype = get_type(cobj)
579
+ cstage = cobj["currentStage"]['code']
580
+ if cstage != final_stage[ctype]:
581
+ rc = ITkDButils.set_object_stage(self.session, SN, final_stage[ctype])
582
+ if rc is None:
583
+ print("Could not set final stage of {} [{}]".format(ctype, SN))
584
+
585
+ # Check for HonneyComb set
586
+ for P in self.petal_core["properties"]:
587
+ if P["code"] == "HC_ID" and P["value"] is None:
588
+ if dbGtkUtils.is_iterable(components["HoneyCombSet"]):
589
+ val = ' '.join(components["HoneyCombSet"])
590
+ else:
591
+ val = str(components["HoneyCombSet"])
592
+ rc = ITkDButils.set_component_property(self.session,
593
+ this_petal,
594
+ "HC_ID",
595
+ val)
596
+ if rc is None:
597
+ error_txt.append("Problems setting HoneyCombSet ID.\n")
598
+
599
+ break
600
+
601
+ # Check the final stage of the assembled objects
602
+ # for child in self.petal_core["children"]:
603
+ # if child["component"]:
604
+ # cSN = child["component"]["serialNumber"]
605
+ # ctype = get_type(child)
606
+ # cobj = ITkDButils.get_DB_component(self.session, cSN)
607
+ # cstage = cobj["currentStage"]['code']
608
+ # if cstage != final_stage[ctype]:
609
+ # rc = ITkDButils.set_object_stage(self.session, cSN, final_stage[ctype])
610
+ # if rc is None:
611
+ # print("Could not set final stage of {}".format(cSN))
612
+ #
613
+ if len(error_txt)>0:
614
+ dbGtkUtils.complain("Assembly of {} could not be completeed:".format(this_petal),
615
+ "\n".join(error_txt))
616
+
617
+ def upload_current_test(self, *args):
618
+ """Called with upload button clcked."""
619
+ SN = self.SN.get_text()
620
+ if len(SN) == 0:
621
+ dbGtkUtils.complain("Petal SN is empty")
622
+ return
623
+
624
+ def find_children(W):
625
+ try:
626
+ for c in W.get_children():
627
+ if "DictDialog" in c.get_name():
628
+ return c
629
+
630
+ else:
631
+ return find_children(c)
632
+
633
+ except Exception:
634
+ return None
635
+
636
+ return None
637
+
638
+ page = self.notebook.get_nth_page(self.notebook.get_current_page())
639
+ dctD = find_children(page)
640
+ if dctD is None:
641
+ return
642
+
643
+ values = dctD.values
644
+ values["component"] = SN
645
+ print(json.dumps(values, indent=2))
646
+ rc = ITkDButils.upload_test(self.session, values)
647
+ if rc is not None:
648
+ dbGtkUtils.complain("Could not upload test", rc)
649
+
650
+ else:
651
+ dbGtkUtils.ask_for_confirmation("Test uploaded.",
652
+ "{} - {}".format(values["component"], values["testType"]))
653
+
654
+ def upload_avs_files(self, *args):
655
+ """Called when upload AVS files clicked."""
656
+ SN = self.SN.get_text()
657
+ if len(SN) == 0:
658
+ dbGtkUtils.complain("Petal SN is empty")
659
+ return
660
+
661
+ def upload_file(file_path, title, desc):
662
+ if file_path is not None:
663
+ if not Path(file_path).exists():
664
+ dbGtkUtils.complain("Could not find {}".format(title))
665
+
666
+ else:
667
+ try:
668
+ ITkDButils.create_component_attachment(self.session, SN, file_path, description=desc)
669
+
670
+ except Exception as e:
671
+ dbGtkUtils.complain("Could not Upload {}".format(desc), str(e))
672
+
673
+ PSF = self.btnPSF.get_filename()
674
+ upload_file(PSF, "Production File", "AVS Production file")
675
+
676
+ FAT = self.btnFAT.get_filename()
677
+ upload_file(FAT, "FAT file", "AVS FAT file")
678
+
679
+ def on_check_tests(self, *args):
680
+ """Button clicked."""
681
+ self.check_tests(True)
682
+
683
+ def check_tests(self, do_write=False):
684
+ """Check whether all tests are find"""
685
+ nbad = 0
686
+ bad = []
687
+ for test in self.test_list:
688
+ values = test.values
689
+ if not values["passed"]:
690
+ nbad +=1
691
+ bad.append(values["testType"])
692
+
693
+ if nbad:
694
+ dbGtkUtils.set_button_color(self.btn_state, "red", "white")
695
+ self.btn_state.set_label("FAILED")
696
+ else:
697
+ dbGtkUtils.set_button_color(self.btn_state, "green", "white")
698
+ self.btn_state.set_label("PASSED")
699
+
700
+ if do_write:
701
+ if nbad:
702
+ self.write_message("Petal Failed:\n")
703
+ for T in bad:
704
+ self.write_message("\t{}\n".format(T))
705
+ else:
706
+ if len(self.test_list)>0:
707
+ self.write_message("All tests are PASSED\n")
708
+
709
+ return nbad
710
+
711
+ def on_assembly(self, widget):
712
+ """Assembly button clicked."""
713
+ self.check_assembly(self.DESY_comp)
714
+
715
+ def on_upload(self, widget):
716
+ """Upload tests to DB."""
717
+ if self.petal_core is None:
718
+ self.query_db()
719
+ if self.petal_core is None:
720
+ return
721
+
722
+ for test in self.test_list:
723
+ values = test.values
724
+ self.write_message("{}\n".format(values["testType"]))
725
+ res = ITkDButils.upload_test(self.session, values, check_runNumber=True)
726
+ if res is not None:
727
+ dbGtkUtils.complain("Could not upload test {}".format(values["testType"]), res)
728
+
729
+
730
+ class AVSOptions:
731
+ def __init__(self):
732
+ self.PS = None
733
+ self.FAT = None
734
+ self.SN = None
735
+
736
+ def main():
737
+ """The main entry."""
738
+ # Parse command line options
739
+ parser = ArgumentParser()
740
+ parser.add_argument('files', nargs='*', help="Input files")
741
+ parser.add_argument("--SN", dest="SN", type=str, default=None,
742
+ help="Module serial number")
743
+ parser.add_argument("--PS", dest="PS", type=str, default=None,
744
+ help="Produc tion Sheet file")
745
+ parser.add_argument("--FAT", dest="FAT", type=str, default=None,
746
+ help="FAT file")
747
+
748
+ options = parser.parse_args()
749
+
750
+ # ITk_PB authentication
751
+ dlg = ITkDBlogin.ITkDBlogin()
752
+ session = dlg.get_client()
753
+
754
+ # Start the Application
755
+ win = AVSPanel(session, options)
756
+ win.show_all()
757
+ win.set_accept_focus(True)
758
+ win.present()
759
+ try:
760
+ Gtk.main()
761
+ except KeyboardInterrupt:
762
+ print("Arrggggg !!!")
763
+
764
+ print("Bye !!")
765
+ dlg.die()
766
+ sys.exit()
767
+
768
+ if __name__ == "__main__":
769
+ main()