itkdb-gtk 0.0.14__tar.gz → 0.0.16.dev0__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.0.14 → itkdb_gtk-0.0.16.dev0}/PKG-INFO +9 -1
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/README.md +3 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/ITkDBlogin.py +1 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/ITkDButils.py +6 -2
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/__init__.py +7 -3
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/dashBoard.py +30 -7
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/dbGtkUtils.py +14 -1
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/groundVITests.py +1 -0
- itkdb_gtk-0.0.16.dev0/itkdb_gtk/untrash_component.py +35 -0
- itkdb_gtk-0.0.16.dev0/itkdb_gtk/uploadIVfiles.py +484 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/uploadPetalInformation.py +1 -1
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/uploadTest.py +35 -10
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk.egg-info/PKG-INFO +10 -2
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk.egg-info/SOURCES.txt +2 -4
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk.egg-info/entry_points.txt +1 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/pyproject.toml +2 -1
- itkdb_gtk-0.0.14/itkdb_gtk/checkComponent.py +0 -151
- itkdb_gtk-0.0.14/itkdb_gtk/checkComponentTests.py +0 -116
- itkdb_gtk-0.0.14/itkdb_gtk/checkJSon.py +0 -56
- itkdb_gtk-0.0.14/itkdb_gtk/recover_component.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/GlueWeight.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/ITkDB.desktop +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/ITkDB.svg +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/ShowAttachments.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/ShowComments.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/ShowDefects.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/getShipments.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/readAVSdata.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/readGoogleSheet.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/sendShipments.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk/uploadMultipleTests.py +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk.egg-info/dependency_links.txt +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk.egg-info/requires.txt +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/itkdb_gtk.egg-info/top_level.txt +0 -0
- {itkdb_gtk-0.0.14 → itkdb_gtk-0.0.16.dev0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: itkdb_gtk
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.16.dev0
|
|
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
|
|
@@ -9,6 +9,11 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Operating System :: OS Independent
|
|
10
10
|
Requires-Python: >=3.7
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: itkdb>=0.4.0
|
|
13
|
+
Requires-Dist: openpyxl
|
|
14
|
+
Requires-Dist: pyserial
|
|
15
|
+
Requires-Dist: python_dateutil
|
|
16
|
+
Requires-Dist: requests
|
|
12
17
|
|
|
13
18
|
# Interaction with the ITk PDB.
|
|
14
19
|
|
|
@@ -57,6 +62,9 @@ GUI dialog. One can add comments and attachments to the shipment.
|
|
|
57
62
|
Allows to upload and enter valueos, comments and defects for those items in the gounding
|
|
58
63
|
and visual instpections tests of the petal core.
|
|
59
64
|
|
|
65
|
+
## uploadIVfiles.py
|
|
66
|
+
The idea behind this is that we messure the IV on a Ring module and on only one of the to Half modules. The IV of the remaining half modules is derived from the other 2. Eventually the IV test can be uploaded to the DB.
|
|
67
|
+
|
|
60
68
|
## dashBoard.py
|
|
61
69
|
This is an launcher application from which we can start most of the other
|
|
62
70
|
applications. It is a very good starting point. There is a Gnome desktop file (ITkDB.desktop)
|
|
@@ -45,6 +45,9 @@ GUI dialog. One can add comments and attachments to the shipment.
|
|
|
45
45
|
Allows to upload and enter valueos, comments and defects for those items in the gounding
|
|
46
46
|
and visual instpections tests of the petal core.
|
|
47
47
|
|
|
48
|
+
## uploadIVfiles.py
|
|
49
|
+
The idea behind this is that we messure the IV on a Ring module and on only one of the to Half modules. The IV of the remaining half modules is derived from the other 2. Eventually the IV test can be uploaded to the DB.
|
|
50
|
+
|
|
48
51
|
## dashBoard.py
|
|
49
52
|
This is an launcher application from which we can start most of the other
|
|
50
53
|
applications. It is a very good starting point. There is a Gnome desktop file (ITkDB.desktop)
|
|
@@ -235,9 +235,13 @@ def set_object_stage(client, SN, stage):
|
|
|
235
235
|
def get_DB_component(client, SN):
|
|
236
236
|
"""Get ta component by its serial number."""
|
|
237
237
|
global db_response
|
|
238
|
-
|
|
239
|
-
|
|
238
|
+
try:
|
|
239
|
+
db_response = client.get('getComponent', json={'component': SN})
|
|
240
|
+
return db_response
|
|
240
241
|
|
|
242
|
+
except Exception as e:
|
|
243
|
+
db_response = str(e)
|
|
244
|
+
return None
|
|
241
245
|
|
|
242
246
|
def upload_test(client, data, attachments=None):
|
|
243
247
|
"""Upload a test to the DB.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
__version__ = "0.0.14"
|
|
1
|
+
__version__ = "0.0.16.dev0"
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
def dash_board():
|
|
7
5
|
"""Launches the dash board."""
|
|
6
|
+
from .dashBoard import main
|
|
8
7
|
dashBoard.main()
|
|
9
8
|
|
|
10
9
|
|
|
@@ -42,3 +41,8 @@ def uploadMultipleTests():
|
|
|
42
41
|
"""Upload multiple tests."""
|
|
43
42
|
from .uploadMultipleTests import main
|
|
44
43
|
main()
|
|
44
|
+
|
|
45
|
+
def uploadIVfiles():
|
|
46
|
+
"""Upload IV files of single and double modules"""
|
|
47
|
+
from .uploadIVfiles import main
|
|
48
|
+
main()
|
|
@@ -10,9 +10,10 @@ try:
|
|
|
10
10
|
import sendShipments
|
|
11
11
|
import uploadMultipleTests
|
|
12
12
|
import GlueWeight
|
|
13
|
+
import uploadIVfiles
|
|
13
14
|
|
|
14
15
|
except Exception:
|
|
15
|
-
from itkdb_gtk import dbGtkUtils, getShipments, groundVITests
|
|
16
|
+
from itkdb_gtk import dbGtkUtils, getShipments, groundVITests, uploadIVfiles
|
|
16
17
|
from itkdb_gtk import ITkDBlogin, sendShipments, uploadMultipleTests, GlueWeight
|
|
17
18
|
|
|
18
19
|
import gi
|
|
@@ -23,7 +24,13 @@ from gi.repository import Gtk
|
|
|
23
24
|
|
|
24
25
|
class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
25
26
|
"""Dashboard class."""
|
|
26
|
-
|
|
27
|
+
UPLOAD_TEST = 1
|
|
28
|
+
CREATE_SHIPMNT = 2
|
|
29
|
+
RECV_SHIPMNT = 3
|
|
30
|
+
PETAL_GND = 4
|
|
31
|
+
GLUE_WEIGHT = 5
|
|
32
|
+
MOD_IV = 6
|
|
33
|
+
|
|
27
34
|
def __init__(self, session):
|
|
28
35
|
"""Initialization."""
|
|
29
36
|
super().__init__(title="ITkDB Dashboard", session=session)
|
|
@@ -60,6 +67,11 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
60
67
|
btnWeight.connect("clicked", self.glue_weight)
|
|
61
68
|
grid.attach(btnWeight, 0, irow, 1, 1)
|
|
62
69
|
|
|
70
|
+
btnModIV = Gtk.Button(label="Module IV")
|
|
71
|
+
btnModIV.connect("clicked", self.module_IV)
|
|
72
|
+
grid.attach(btnModIV, 1, irow, 1, 1)
|
|
73
|
+
|
|
74
|
+
|
|
63
75
|
irow += 1
|
|
64
76
|
grid.attach(Gtk.Label(), 0, irow, 1, 1)
|
|
65
77
|
|
|
@@ -84,7 +96,7 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
84
96
|
|
|
85
97
|
def upload_test(self, *args):
|
|
86
98
|
"""Launch upload test."""
|
|
87
|
-
bitn =
|
|
99
|
+
bitn = DashWindow.UPLOAD_TEST
|
|
88
100
|
bt = 1 << bitn
|
|
89
101
|
if self.mask & bt:
|
|
90
102
|
return
|
|
@@ -95,7 +107,7 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
95
107
|
|
|
96
108
|
def create_shipment(self, *args):
|
|
97
109
|
"""Launch sendShipment."""
|
|
98
|
-
bitn =
|
|
110
|
+
bitn = DashWindow.CREATE_SHIPMNT
|
|
99
111
|
bt = 1 << bitn
|
|
100
112
|
if self.mask & bt:
|
|
101
113
|
return
|
|
@@ -106,7 +118,7 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
106
118
|
|
|
107
119
|
def receive_shipment(self, *args):
|
|
108
120
|
"""Launch getShipments."""
|
|
109
|
-
bitn =
|
|
121
|
+
bitn = DashWindow.RECV_SHIPMNT
|
|
110
122
|
bt = 1 << bitn
|
|
111
123
|
if self.mask & bt:
|
|
112
124
|
return
|
|
@@ -117,7 +129,7 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
117
129
|
|
|
118
130
|
def petal_gnd(self, *args):
|
|
119
131
|
"""Petal GND/VI test."""
|
|
120
|
-
bitn =
|
|
132
|
+
bitn = DashWindow.PETAL_GND
|
|
121
133
|
bt = 1 << bitn
|
|
122
134
|
if self.mask & bt:
|
|
123
135
|
return
|
|
@@ -128,7 +140,7 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
128
140
|
|
|
129
141
|
def glue_weight(self, *args):
|
|
130
142
|
"""Glue Weight test."""
|
|
131
|
-
bitn =
|
|
143
|
+
bitn = DashWindow.GLUE_WEIGHT
|
|
132
144
|
bt = 1 << bitn
|
|
133
145
|
if self.mask & bt:
|
|
134
146
|
return
|
|
@@ -137,6 +149,17 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
137
149
|
W = GlueWeight.GlueWeight(self.session)
|
|
138
150
|
W.connect("destroy", self.app_closed, bitn)
|
|
139
151
|
|
|
152
|
+
def module_IV(self, *args):
|
|
153
|
+
"""Module IV tests."""
|
|
154
|
+
bitn = DashWindow.MOD_IV
|
|
155
|
+
bt = 1 << bitn
|
|
156
|
+
if self.mask & bt:
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
self.mask |= bt
|
|
160
|
+
W = uploadIVfiles.IVwindow(self.session)
|
|
161
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
162
|
+
|
|
140
163
|
def app_closed(self, *args):
|
|
141
164
|
"""Application window closed. Clear mask."""
|
|
142
165
|
bt = 1 << args[1]
|
|
@@ -7,6 +7,8 @@ from datetime import datetime
|
|
|
7
7
|
|
|
8
8
|
import dateutil.parser
|
|
9
9
|
import gi
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
gi.require_version("Gtk", "3.0")
|
|
12
14
|
from gi.repository import Gtk, Gio, GLib
|
|
@@ -17,7 +19,7 @@ def is_a_date(txt):
|
|
|
17
19
|
try:
|
|
18
20
|
dateutil.parser.parse(txt, fuzzy=False)
|
|
19
21
|
return True
|
|
20
|
-
|
|
22
|
+
|
|
21
23
|
except Exception:
|
|
22
24
|
return False
|
|
23
25
|
|
|
@@ -65,6 +67,12 @@ class MyEncoder(json.JSONEncoder):
|
|
|
65
67
|
if isinstance(o, datetime):
|
|
66
68
|
text = o.astimezone().isoformat()
|
|
67
69
|
return text
|
|
70
|
+
elif isinstance(o, np.integer):
|
|
71
|
+
return int(o)
|
|
72
|
+
elif isinstance(o, np.floating):
|
|
73
|
+
return float(o)
|
|
74
|
+
elif isinstance(o, np.ndarray):
|
|
75
|
+
return o.tolist()
|
|
68
76
|
else:
|
|
69
77
|
return super().default(o)
|
|
70
78
|
|
|
@@ -310,6 +318,8 @@ def add_button_to_container(box, label, tooltip=None, callback=None):
|
|
|
310
318
|
btn.connect("clicked", callback)
|
|
311
319
|
|
|
312
320
|
box.pack_start(btn, True, False, 0)
|
|
321
|
+
|
|
322
|
+
return btn
|
|
313
323
|
|
|
314
324
|
|
|
315
325
|
class ITkDBWindow(Gtk.Window):
|
|
@@ -361,6 +371,9 @@ class ITkDBWindow(Gtk.Window):
|
|
|
361
371
|
|
|
362
372
|
# Create main content box
|
|
363
373
|
self.mainBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
374
|
+
self.mainBox.set_property("margin-left", 6)
|
|
375
|
+
self.mainBox.set_property("margin-right", 6)
|
|
376
|
+
|
|
364
377
|
self.add(self.mainBox)
|
|
365
378
|
|
|
366
379
|
# The text view and buffer
|
|
@@ -99,6 +99,7 @@ class GroundingTest(dbGtkUtils.ITkDBWindow):
|
|
|
99
99
|
# Create the Notebook pages
|
|
100
100
|
self.create_test_box("Visual Inspection", "VISUAL_INSPECTION")
|
|
101
101
|
self.create_test_box("Grounding", "GROUNDING_CHECK")
|
|
102
|
+
self.create_test_box("Pipe bending", "BENDING120")
|
|
102
103
|
|
|
103
104
|
# The text view
|
|
104
105
|
frame = self.create_text_view()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Un trash a trashed component."""
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def untrash_component(client, SN, reason="Accidentally trashed"):
|
|
6
|
+
"""Un trash given component.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
SN (str): Serial number of component to recover.
|
|
10
|
+
reason (str): message for the DB
|
|
11
|
+
Return:
|
|
12
|
+
dict: PDB response.
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
DTO = {
|
|
16
|
+
'component': SN,
|
|
17
|
+
'trashed': False,
|
|
18
|
+
'reason': reason
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
response = client.post('setComponentTrashed', json=DTO)
|
|
22
|
+
return response
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__":
|
|
26
|
+
import sys
|
|
27
|
+
from itkdb_gtk import ITkDBlogin
|
|
28
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
29
|
+
client = dlg.get_client()
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
response = untrash_component(client, sys.argv[1])
|
|
33
|
+
|
|
34
|
+
except Exception as E:
|
|
35
|
+
print(str(E))
|
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Read IV files and create plots."""
|
|
3
|
+
import os
|
|
4
|
+
import json
|
|
5
|
+
import math
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import gi
|
|
9
|
+
import tempfile
|
|
10
|
+
|
|
11
|
+
gi.require_version("Gtk", "3.0")
|
|
12
|
+
from gi.repository import Gtk, Gio
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
|
|
16
|
+
from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar
|
|
17
|
+
import numpy as np
|
|
18
|
+
import matplotlib as mpl
|
|
19
|
+
import matplotlib.pyplot as plt
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import dbGtkUtils
|
|
23
|
+
import ITkDBlogin
|
|
24
|
+
import ITkDButils
|
|
25
|
+
import uploadTest
|
|
26
|
+
|
|
27
|
+
except ModuleNotFoundError:
|
|
28
|
+
from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils, uploadTest
|
|
29
|
+
|
|
30
|
+
# Check if Gtk can be open
|
|
31
|
+
gtk_runs, gtk_args = Gtk.init_check()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def remove_files(W, flist):
|
|
35
|
+
for f in flist:
|
|
36
|
+
os.unlink(f)
|
|
37
|
+
|
|
38
|
+
def scale_iv(I, T1, T2):
|
|
39
|
+
"""Normalize corrent to given temperature (T2)
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
I (array): Current
|
|
43
|
+
T1 (float): Original temperature
|
|
44
|
+
T2 (float): New temperature.
|
|
45
|
+
|
|
46
|
+
Return:
|
|
47
|
+
Array with scaled currents.
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
factor = (T2 / T1) ** 2 * math.exp((-1.2 / 8.62) * (1 / T2 - 1 / T1))
|
|
51
|
+
return factor * I
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class IVwindow(dbGtkUtils.ITkDBWindow):
|
|
55
|
+
"""GUI for IV file handling."""
|
|
56
|
+
|
|
57
|
+
def __init__(self, session, title="IV window", options=None):
|
|
58
|
+
"""Initialization."""
|
|
59
|
+
super().__init__(
|
|
60
|
+
session=session, title=title, show_search=None, gtk_runs=gtk_runs
|
|
61
|
+
)
|
|
62
|
+
self.mdata = {}
|
|
63
|
+
self.mod_type = {}
|
|
64
|
+
self.mod_SN = {}
|
|
65
|
+
self.difference = None
|
|
66
|
+
self.canvas = None
|
|
67
|
+
|
|
68
|
+
self.init_window()
|
|
69
|
+
|
|
70
|
+
def init_window(self):
|
|
71
|
+
"""Prepare the Gtk window."""
|
|
72
|
+
self.hb.props.title = "IV data"
|
|
73
|
+
|
|
74
|
+
button = Gtk.Button()
|
|
75
|
+
icon = Gio.ThemedIcon(name="view-refresh-symbolic")
|
|
76
|
+
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
77
|
+
button.add(image)
|
|
78
|
+
button.set_tooltip_text("Click to refresh canvas.")
|
|
79
|
+
button.connect("clicked", self.on_refresh)
|
|
80
|
+
self.hb.pack_end(button)
|
|
81
|
+
|
|
82
|
+
# Button to upload
|
|
83
|
+
button = Gtk.Button()
|
|
84
|
+
icon = Gio.ThemedIcon(name="document-send-symbolic")
|
|
85
|
+
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
86
|
+
button.add(image)
|
|
87
|
+
button.set_tooltip_text("Click to upload test")
|
|
88
|
+
button.connect("clicked", self.upload_test)
|
|
89
|
+
self.hb.pack_end(button)
|
|
90
|
+
|
|
91
|
+
# File entry and search button
|
|
92
|
+
self.single_file = Gtk.FileChooserButton()
|
|
93
|
+
self.single_file.connect("file-set", self.on_single_file_set)
|
|
94
|
+
|
|
95
|
+
self.double_file = Gtk.FileChooserButton()
|
|
96
|
+
self.double_file.connect("file-set", self.on_double_file_set)
|
|
97
|
+
|
|
98
|
+
self.single_SN = Gtk.Label(label="(None)")
|
|
99
|
+
self.double_SN = Gtk.Label(label="(None)")
|
|
100
|
+
|
|
101
|
+
grid = Gtk.Grid(column_spacing=5, row_spacing=1)
|
|
102
|
+
|
|
103
|
+
grid.attach(Gtk.Label(label="Files"), 1, 0, 1, 1)
|
|
104
|
+
grid.attach(Gtk.Label(label="Serial No."), 2, 0, 1, 1)
|
|
105
|
+
|
|
106
|
+
grid.attach(Gtk.Label(label="Single Data File"), 0, 1, 1, 1)
|
|
107
|
+
grid.attach(self.single_file, 1, 1, 1, 1)
|
|
108
|
+
grid.attach(self.single_SN, 2, 1, 1, 1)
|
|
109
|
+
|
|
110
|
+
grid.attach(Gtk.Label(label="Double Data File"), 0, 2, 1, 1)
|
|
111
|
+
grid.attach(self.double_file, 1, 2, 1, 1)
|
|
112
|
+
grid.attach(self.double_SN, 2, 2, 1, 1)
|
|
113
|
+
|
|
114
|
+
btn = Gtk.Button(label="Compute difference")
|
|
115
|
+
btn.connect("clicked", self.on_difference)
|
|
116
|
+
grid.attach(btn, 1, 3, 1, 1)
|
|
117
|
+
|
|
118
|
+
self.mainBox.pack_start(grid, False, True, 0)
|
|
119
|
+
|
|
120
|
+
self.fig = mpl.figure.Figure()
|
|
121
|
+
self.fig.tight_layout()
|
|
122
|
+
sw = Gtk.ScrolledWindow() # Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
123
|
+
|
|
124
|
+
# A scrolled window border goes outside the scrollbars and viewport
|
|
125
|
+
sw.set_border_width(10)
|
|
126
|
+
sw.set_size_request(310, 310)
|
|
127
|
+
|
|
128
|
+
self.canvas = FigureCanvas(self.fig) # a Gtk.DrawingArea
|
|
129
|
+
self.canvas.set_size_request(400, 300)
|
|
130
|
+
sw.add(self.canvas)
|
|
131
|
+
self.mainBox.pack_start(sw, True, True, 0)
|
|
132
|
+
|
|
133
|
+
# Create toolbar
|
|
134
|
+
toolbar = NavigationToolbar(self.canvas)
|
|
135
|
+
self.mainBox.pack_start(toolbar, False, False, 0)
|
|
136
|
+
|
|
137
|
+
# The text view
|
|
138
|
+
frame = self.create_text_view()
|
|
139
|
+
self.mainBox.pack_start(frame, True, True, 5)
|
|
140
|
+
|
|
141
|
+
self.show_all()
|
|
142
|
+
|
|
143
|
+
def upload_test(self, *args):
|
|
144
|
+
"""Upload available tests."""
|
|
145
|
+
test = ITkDButils.get_test_skeleton(
|
|
146
|
+
self.session, "MODULE", self.mdata["double"]["TestType"]
|
|
147
|
+
)
|
|
148
|
+
mdata = self.mdata["double"]
|
|
149
|
+
V = mdata["curve"]["V"]
|
|
150
|
+
I = np.abs(mdata["curve"]["I"])
|
|
151
|
+
|
|
152
|
+
indx = np.where(V == 500)[0]
|
|
153
|
+
i_500 = I[indx][0]
|
|
154
|
+
|
|
155
|
+
indx = np.where(V == 700)
|
|
156
|
+
rms = np.std(I[indx])
|
|
157
|
+
|
|
158
|
+
test["component"] = self.mod_SN["double"]
|
|
159
|
+
test["institution"] = mdata["Institute"]
|
|
160
|
+
test["runNumber"] = mdata["RunNumber"]
|
|
161
|
+
test["date"] = ITkDButils.get_db_date(
|
|
162
|
+
"{} {}".format(mdata["Date"], mdata["Time"])
|
|
163
|
+
)
|
|
164
|
+
test["passed"] = True
|
|
165
|
+
test["problems"] = False
|
|
166
|
+
test["properties"]["VBIAS_SMU"] = mdata["Vbias_SMU"]
|
|
167
|
+
test["properties"]["RSERIES"] = mdata["Rseries"]
|
|
168
|
+
test["properties"]["TEST_DMM"] = mdata["Test_DMM"]
|
|
169
|
+
test["properties"]["RSHUNT"] = mdata["Rshunt"]
|
|
170
|
+
test["properties"]["RUNNUMBER"] = mdata["RunNumber"]
|
|
171
|
+
test["properties"]["COMMENTS"] = mdata["Comments"]
|
|
172
|
+
test["properties"]["ALGORITHM_VERSION"] = "0.0.0"
|
|
173
|
+
test["properties"]["SOFTWARE_TYPE_VERSION"] = "pyProbe"
|
|
174
|
+
test["properties"]["MODULE_STAGE"] = mdata["Module_Stage"]
|
|
175
|
+
test["results"]["TEMPERATURE"] = mdata["Temperature"]
|
|
176
|
+
test["results"]["HUMIDITY"] = mdata["Humidity"]
|
|
177
|
+
test["results"]["VBD"] = mdata["curve"]["V"][-1]
|
|
178
|
+
test["results"]["I_500V"] = i_500
|
|
179
|
+
test["results"]["VOLTAGE"] = V
|
|
180
|
+
test["results"]["CURRENT"] = I
|
|
181
|
+
test["results"]["RMS_STABILITY"] = 0.0
|
|
182
|
+
test["results"]["SHUNT_VOLTAGE"] = np.zeros(V.shape)
|
|
183
|
+
|
|
184
|
+
# write attachment.
|
|
185
|
+
items = [
|
|
186
|
+
"Type",
|
|
187
|
+
"Wafer",
|
|
188
|
+
"Module_SN",
|
|
189
|
+
"Module_Stage",
|
|
190
|
+
"Date",
|
|
191
|
+
"Time",
|
|
192
|
+
"Institute",
|
|
193
|
+
"TestType",
|
|
194
|
+
"Vbias_SMU",
|
|
195
|
+
"Rseries",
|
|
196
|
+
"Test_DMM",
|
|
197
|
+
"Rshunt",
|
|
198
|
+
"Software type and version, fw version",
|
|
199
|
+
"RunNumber",
|
|
200
|
+
"Temperature",
|
|
201
|
+
"Humidity",
|
|
202
|
+
"Comments",
|
|
203
|
+
]
|
|
204
|
+
fnam = "{}_{}_IV_{}-".format(self.mod_SN["double"], mdata["Module_Stage"], mdata["RunNumber"])
|
|
205
|
+
data_out = tempfile.NamedTemporaryFile('w', prefix=fnam, suffix=".dat", delete=False)
|
|
206
|
+
data_out.write("{}\n".format(fnam))
|
|
207
|
+
for key in items:
|
|
208
|
+
if key == "Module_SN":
|
|
209
|
+
data_out.write("{}: {}\n".format(key, self.mod_SN["double"]))
|
|
210
|
+
else:
|
|
211
|
+
data_out.write("{}: {}\n".format(key, mdata[key]))
|
|
212
|
+
|
|
213
|
+
for il, label in enumerate(mdata["curve"]["labels"]):
|
|
214
|
+
if il:
|
|
215
|
+
data_out.write('\t')
|
|
216
|
+
data_out.write(label)
|
|
217
|
+
data_out.write("\n")
|
|
218
|
+
|
|
219
|
+
ndata = len(mdata["curve"]["V"])
|
|
220
|
+
for i in range(ndata):
|
|
221
|
+
data_out.write("{:.2f}\t{:.2f}\t{:.2f}\n".format(V[i], self.difference[i], 0.0))
|
|
222
|
+
|
|
223
|
+
print(data_out.name)
|
|
224
|
+
data_out.close()
|
|
225
|
+
|
|
226
|
+
js_out = tempfile.NamedTemporaryFile('w', prefix="payload-", suffix=".json", delete=False)
|
|
227
|
+
js_out.write(json.dumps(test, indent=3, cls=dbGtkUtils.MyEncoder))
|
|
228
|
+
js_out.close()
|
|
229
|
+
|
|
230
|
+
attachment = ITkDButils.Attachment(data_out.name, "resultsFile", fnam)
|
|
231
|
+
uploadW = uploadTest.UploadTest(self.session, js_out.name, attachment)
|
|
232
|
+
uploadW.connect("destroy", remove_files, [data_out.name, js_out.name])
|
|
233
|
+
|
|
234
|
+
def on_refresh(self, *args):
|
|
235
|
+
"""Refresh canvas."""
|
|
236
|
+
if self.fig and self.canvas:
|
|
237
|
+
self.fig.tight_layout()
|
|
238
|
+
self.canvas.draw()
|
|
239
|
+
|
|
240
|
+
def find_module(self, SN):
|
|
241
|
+
"""Find module (SN) on database
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
----
|
|
245
|
+
SN (str): Module Serial number
|
|
246
|
+
"""
|
|
247
|
+
md = ITkDButils.get_DB_component(self.session, SN)
|
|
248
|
+
if md is None:
|
|
249
|
+
dbGtkUtils.complain(
|
|
250
|
+
"Could not find {}".format(SN), str(ITkDButils.get_db_response())
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
return md
|
|
254
|
+
|
|
255
|
+
def on_single_file_set(self, *args):
|
|
256
|
+
"""File chosen."""
|
|
257
|
+
fnam = self.single_file.get_filename()
|
|
258
|
+
if fnam is None or not Path(fnam).exists():
|
|
259
|
+
dbGtkUtils.complain("Could not find data file", fnam, parent=self)
|
|
260
|
+
|
|
261
|
+
mdata = self.read_file(fnam)
|
|
262
|
+
|
|
263
|
+
SN = mdata["Module_SN"]
|
|
264
|
+
self.write_message("Reading data for module {}\n".format(SN))
|
|
265
|
+
md = self.find_module(SN)
|
|
266
|
+
if md is None:
|
|
267
|
+
self.write_message("...object does not exist.\n")
|
|
268
|
+
self.single_file.unselect_all()
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
# All good
|
|
272
|
+
self.mod_SN["single"] = SN
|
|
273
|
+
self.mdata["single"] = mdata
|
|
274
|
+
self.mod_type["single"] = md["type"]["code"]
|
|
275
|
+
print(self.mod_type["single"])
|
|
276
|
+
|
|
277
|
+
self.single_SN.set_text("{} - {}".format(SN, md["type"]["name"]))
|
|
278
|
+
self.show_curve(
|
|
279
|
+
131,
|
|
280
|
+
mdata["curve"]["V"],
|
|
281
|
+
mdata["curve"]["I"],
|
|
282
|
+
self.mod_type["single"][0:4],
|
|
283
|
+
mdata["curve"]["labels"][0],
|
|
284
|
+
mdata["curve"]["labels"][1],
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
def on_double_file_set(self, *args):
|
|
288
|
+
"File chosen for the 'double module'"
|
|
289
|
+
fnam = self.double_file.get_filename()
|
|
290
|
+
if fnam is None or not Path(fnam).exists():
|
|
291
|
+
dbGtkUtils.complain("Could not find data file", fnam, parent=self)
|
|
292
|
+
|
|
293
|
+
mdata = self.read_file(fnam)
|
|
294
|
+
|
|
295
|
+
# Check SN in data file
|
|
296
|
+
SN = mdata["Module_SN"]
|
|
297
|
+
halfM_SN = SN
|
|
298
|
+
if "single" in self.mod_SN:
|
|
299
|
+
if self.mod_SN["single"] == SN:
|
|
300
|
+
dbGtkUtils.complain("Wrong module SN", "{} already used.".format(SN))
|
|
301
|
+
self.double_file.unselect_all()
|
|
302
|
+
return
|
|
303
|
+
|
|
304
|
+
# Check that it exists in the DB
|
|
305
|
+
self.write_message("Reading data for module {}\n".format(SN))
|
|
306
|
+
md = self.find_module(SN)
|
|
307
|
+
if md is None:
|
|
308
|
+
self.write_message("...object does not exist.\n")
|
|
309
|
+
self.double_file.unselect_all()
|
|
310
|
+
return
|
|
311
|
+
|
|
312
|
+
found_child = False
|
|
313
|
+
if md["type"]["name"].find("Ring"):
|
|
314
|
+
self.write_message("...This is a Ring module. Searching children in DB\n")
|
|
315
|
+
for child in md["children"]:
|
|
316
|
+
if child["component"]:
|
|
317
|
+
ctype = child["type"]["code"]
|
|
318
|
+
if ctype.find("MODULE")<0:
|
|
319
|
+
continue
|
|
320
|
+
|
|
321
|
+
cSN = child["component"]["serialNumber"]
|
|
322
|
+
if cSN == self.mod_SN["single"]:
|
|
323
|
+
continue
|
|
324
|
+
|
|
325
|
+
halfM_SN = cSN
|
|
326
|
+
found_child = True
|
|
327
|
+
self.write_message("...found {}\n".format(halfM_SN))
|
|
328
|
+
break
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
if not found_child:
|
|
332
|
+
self.write_message("Requesting a Half Module SN\n")
|
|
333
|
+
halfM_SN = dbGtkUtils.get_a_value("Give Half Module SN", "Serial Number")
|
|
334
|
+
|
|
335
|
+
md = ITkDButils.get_DB_component(self.session, halfM_SN)
|
|
336
|
+
if md is None:
|
|
337
|
+
dbGtkUtils.complain(
|
|
338
|
+
"Could not find {}".format(halfM_SN),
|
|
339
|
+
str(ITkDButils.get_db_response()),
|
|
340
|
+
)
|
|
341
|
+
self.double_file.unselect_all()
|
|
342
|
+
return
|
|
343
|
+
|
|
344
|
+
self.write_message("... {}".format(halfM_SN))
|
|
345
|
+
|
|
346
|
+
if "single" in self.mod_type:
|
|
347
|
+
if self.mod_type["single"] == md["type"]["code"]:
|
|
348
|
+
dbGtkUtils.complain(
|
|
349
|
+
"Wrong module type.",
|
|
350
|
+
"Module type cannot be {}".format(self.mod_type["single"]),
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
self.double_file.unselect_all()
|
|
354
|
+
return
|
|
355
|
+
|
|
356
|
+
self.mod_SN["double"] = halfM_SN
|
|
357
|
+
self.mod_type["double"] = md["type"]["code"]
|
|
358
|
+
self.mdata["double"] = mdata
|
|
359
|
+
|
|
360
|
+
self.double_SN.set_text("{} - {}".format(SN, md["type"]["name"]))
|
|
361
|
+
self.show_curve(
|
|
362
|
+
133,
|
|
363
|
+
mdata["curve"]["V"],
|
|
364
|
+
mdata["curve"]["I"],
|
|
365
|
+
"Double",
|
|
366
|
+
mdata["curve"]["labels"][0],
|
|
367
|
+
None,
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
# Compute difference if single already available
|
|
371
|
+
if "single" in self.mdata:
|
|
372
|
+
self.on_difference()
|
|
373
|
+
|
|
374
|
+
def on_difference(self, *args):
|
|
375
|
+
"""Compute difference."""
|
|
376
|
+
if "single" not in self.mdata or "double" not in self.mdata:
|
|
377
|
+
dbGtkUtils.complain(
|
|
378
|
+
"Data needed", "Check if single oand doubel module data are available"
|
|
379
|
+
)
|
|
380
|
+
return
|
|
381
|
+
|
|
382
|
+
single_I = scale_iv(
|
|
383
|
+
self.mdata["single"]["curve"]["I"],
|
|
384
|
+
self.mdata["single"]["Temperature"] + 273.0,
|
|
385
|
+
self.mdata["double"]["Temperature"] + 273.0,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
self.difference = self.mdata["double"]["curve"]["I"] - single_I
|
|
389
|
+
|
|
390
|
+
self.show_curve(
|
|
391
|
+
132,
|
|
392
|
+
self.mdata["double"]["curve"]["V"],
|
|
393
|
+
self.difference,
|
|
394
|
+
self.mod_type["double"][0:4],
|
|
395
|
+
self.mdata["double"]["curve"]["labels"][0],
|
|
396
|
+
None,
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
def show_curve(self, subplot, X, Y, title=None, xlabel="X", ylabel="Y"):
|
|
400
|
+
"""Shows data"""
|
|
401
|
+
ax = self.fig.add_subplot(subplot)
|
|
402
|
+
if xlabel:
|
|
403
|
+
ax.set_xlabel(xlabel)
|
|
404
|
+
|
|
405
|
+
if ylabel:
|
|
406
|
+
ax.set_ylabel(ylabel)
|
|
407
|
+
|
|
408
|
+
if title:
|
|
409
|
+
ax.set_title(title)
|
|
410
|
+
|
|
411
|
+
ax.plot(X, Y)
|
|
412
|
+
ax.grid()
|
|
413
|
+
self.on_refresh()
|
|
414
|
+
|
|
415
|
+
@staticmethod
|
|
416
|
+
def read_file(fnam):
|
|
417
|
+
"""Read a data file. Return dictionary with all teh data."""
|
|
418
|
+
labels = []
|
|
419
|
+
metadata = {}
|
|
420
|
+
with open(fnam, "r", encoding="utf-8") as ifile:
|
|
421
|
+
first = True
|
|
422
|
+
for line in ifile:
|
|
423
|
+
if first:
|
|
424
|
+
first = False
|
|
425
|
+
ipos = line.rfind('.')
|
|
426
|
+
metadata["fname"] = line[:ipos]
|
|
427
|
+
continue
|
|
428
|
+
|
|
429
|
+
if line.find("Voltage [V]") >= 0:
|
|
430
|
+
labels = line.split("\t")
|
|
431
|
+
break
|
|
432
|
+
|
|
433
|
+
rc = line.find(":")
|
|
434
|
+
if rc >= 0:
|
|
435
|
+
key = line[:rc].strip()
|
|
436
|
+
val = line[rc + 1 :].strip()
|
|
437
|
+
if key in ["Temperature", "Humidity"]:
|
|
438
|
+
metadata[key] = float(val)
|
|
439
|
+
else:
|
|
440
|
+
metadata[key] = val
|
|
441
|
+
|
|
442
|
+
V = []
|
|
443
|
+
I = []
|
|
444
|
+
for line in ifile:
|
|
445
|
+
data = [float(s) for s in line.split()]
|
|
446
|
+
V.append(data[0])
|
|
447
|
+
I.append(data[1])
|
|
448
|
+
|
|
449
|
+
metadata["curve"] = {
|
|
450
|
+
"V": np.array(V),
|
|
451
|
+
"I": np.array(I),
|
|
452
|
+
"labels": labels[0:2],
|
|
453
|
+
}
|
|
454
|
+
return metadata
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
if __name__ == "__main__":
|
|
458
|
+
import sys
|
|
459
|
+
|
|
460
|
+
# DB login
|
|
461
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
462
|
+
client = dlg.get_client()
|
|
463
|
+
if client is None:
|
|
464
|
+
print("Could not connect to DB with provided credentials.")
|
|
465
|
+
dlg.die()
|
|
466
|
+
sys.exit()
|
|
467
|
+
|
|
468
|
+
client.user_gui = dlg
|
|
469
|
+
|
|
470
|
+
# Start the Application
|
|
471
|
+
win = IVwindow(client)
|
|
472
|
+
win.show_all()
|
|
473
|
+
win.set_accept_focus(True)
|
|
474
|
+
win.present()
|
|
475
|
+
win.connect("destroy", Gtk.main_quit)
|
|
476
|
+
|
|
477
|
+
try:
|
|
478
|
+
Gtk.main()
|
|
479
|
+
except KeyboardInterrupt:
|
|
480
|
+
print("Arrggggg !!!")
|
|
481
|
+
|
|
482
|
+
dlg.die()
|
|
483
|
+
print("Bye !!")
|
|
484
|
+
sys.exit()
|
|
@@ -88,7 +88,7 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
88
88
|
----
|
|
89
89
|
session: ITkDB session
|
|
90
90
|
payload: path of test file
|
|
91
|
-
attachment: an Attachment object.
|
|
91
|
+
attachment: an Attachment object or list of attachments.
|
|
92
92
|
|
|
93
93
|
"""
|
|
94
94
|
self.payload = payload
|
|
@@ -101,7 +101,12 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
101
101
|
if attachment.path is not None:
|
|
102
102
|
self.attachments.append(attachment)
|
|
103
103
|
else:
|
|
104
|
-
|
|
104
|
+
try:
|
|
105
|
+
for att in attachment:
|
|
106
|
+
self.attachments.append(att)
|
|
107
|
+
|
|
108
|
+
except TypeError:
|
|
109
|
+
print("Wrong attachment: {}".format(attachment))
|
|
105
110
|
|
|
106
111
|
global gtk_runs
|
|
107
112
|
if gtk_runs:
|
|
@@ -168,15 +173,15 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
168
173
|
# The "Add attachment" button.
|
|
169
174
|
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
170
175
|
self.mainBox.pack_start(box, False, False, 0)
|
|
171
|
-
dbGtkUtils.add_button_to_container(box, "Attachments",
|
|
176
|
+
self.btn_attch = dbGtkUtils.add_button_to_container(box, "Attachments",
|
|
172
177
|
"Click to edit attachments.",
|
|
173
178
|
self.edit_attachments)
|
|
174
179
|
|
|
175
|
-
dbGtkUtils.add_button_to_container(box, "Comments",
|
|
180
|
+
self.btn_comments = dbGtkUtils.add_button_to_container(box, "Comments",
|
|
176
181
|
"Click to edit comments.",
|
|
177
182
|
self.edit_comments)
|
|
178
183
|
|
|
179
|
-
dbGtkUtils.add_button_to_container(box, "Defects",
|
|
184
|
+
self.btn_defects = dbGtkUtils.add_button_to_container(box, "Defects",
|
|
180
185
|
"Click to edit defects.",
|
|
181
186
|
self.edit_defects)
|
|
182
187
|
|
|
@@ -200,11 +205,21 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
200
205
|
else:
|
|
201
206
|
print("Input file does not exists: {}".format(self.payload))
|
|
202
207
|
|
|
203
|
-
if len(self.attachments):
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
#if len(self.attachments):
|
|
209
|
+
# dC = [A for A in self.attachments]
|
|
210
|
+
# self.attachments.clear()
|
|
211
|
+
# for A in dC:
|
|
212
|
+
# self.append_attachment_to_view(A)
|
|
213
|
+
|
|
214
|
+
if len(self.attachments) > 0:
|
|
215
|
+
self.btn_attch.set_label("Attachments ({})".format(len(self.attachments)))
|
|
216
|
+
|
|
217
|
+
if len(self.comments) > 0:
|
|
218
|
+
self.btn_comments.set_label("Comments ({})".format(len(self.comments)))
|
|
219
|
+
|
|
220
|
+
if len(self.defects) > 0:
|
|
221
|
+
self.btn_defects.set_label("Defects ({})".format(len(self.defects)))
|
|
222
|
+
|
|
208
223
|
|
|
209
224
|
def get_test_institute(self):
|
|
210
225
|
"""Select an institue."""
|
|
@@ -286,6 +301,10 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
286
301
|
SA.hide()
|
|
287
302
|
SA.destroy()
|
|
288
303
|
|
|
304
|
+
if len(self.attachments) > 0:
|
|
305
|
+
self.btn_attch.set_label("Attachments ({})".format(len(self.attachments)))
|
|
306
|
+
|
|
307
|
+
|
|
289
308
|
def edit_comments(self, *args):
|
|
290
309
|
"""Edit test comments."""
|
|
291
310
|
SC = ShowComments("Test Comments", self.comments, self)
|
|
@@ -296,6 +315,9 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
296
315
|
SC.hide()
|
|
297
316
|
SC.destroy()
|
|
298
317
|
|
|
318
|
+
if len(self.comments) > 0:
|
|
319
|
+
self.btn_comments.set_label("Comments ({})".format(len(self.comments)))
|
|
320
|
+
|
|
299
321
|
def edit_defects(self, *args):
|
|
300
322
|
"""Edit test defects."""
|
|
301
323
|
SD = ShowDefects("Test Defects", self.defects, self)
|
|
@@ -306,6 +328,9 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
|
|
|
306
328
|
SD.hide()
|
|
307
329
|
SD.destroy()
|
|
308
330
|
|
|
331
|
+
if len(self.defects) > 0:
|
|
332
|
+
self.btn_defects.set_label("Defects ({})".format(len(self.defects)))
|
|
333
|
+
|
|
309
334
|
def upload_test_gui(self, *args):
|
|
310
335
|
"""Uploads test and attachments."""
|
|
311
336
|
self.upload_test()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
|
-
Name:
|
|
3
|
-
Version: 0.0.
|
|
2
|
+
Name: itkdb_gtk
|
|
3
|
+
Version: 0.0.16.dev0
|
|
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
|
|
@@ -9,6 +9,11 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Operating System :: OS Independent
|
|
10
10
|
Requires-Python: >=3.7
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: itkdb>=0.4.0
|
|
13
|
+
Requires-Dist: openpyxl
|
|
14
|
+
Requires-Dist: pyserial
|
|
15
|
+
Requires-Dist: python_dateutil
|
|
16
|
+
Requires-Dist: requests
|
|
12
17
|
|
|
13
18
|
# Interaction with the ITk PDB.
|
|
14
19
|
|
|
@@ -57,6 +62,9 @@ GUI dialog. One can add comments and attachments to the shipment.
|
|
|
57
62
|
Allows to upload and enter valueos, comments and defects for those items in the gounding
|
|
58
63
|
and visual instpections tests of the petal core.
|
|
59
64
|
|
|
65
|
+
## uploadIVfiles.py
|
|
66
|
+
The idea behind this is that we messure the IV on a Ring module and on only one of the to Half modules. The IV of the remaining half modules is derived from the other 2. Eventually the IV test can be uploaded to the DB.
|
|
67
|
+
|
|
60
68
|
## dashBoard.py
|
|
61
69
|
This is an launcher application from which we can start most of the other
|
|
62
70
|
applications. It is a very good starting point. There is a Gnome desktop file (ITkDB.desktop)
|
|
@@ -9,17 +9,15 @@ itkdb_gtk/ShowAttachments.py
|
|
|
9
9
|
itkdb_gtk/ShowComments.py
|
|
10
10
|
itkdb_gtk/ShowDefects.py
|
|
11
11
|
itkdb_gtk/__init__.py
|
|
12
|
-
itkdb_gtk/checkComponent.py
|
|
13
|
-
itkdb_gtk/checkComponentTests.py
|
|
14
|
-
itkdb_gtk/checkJSon.py
|
|
15
12
|
itkdb_gtk/dashBoard.py
|
|
16
13
|
itkdb_gtk/dbGtkUtils.py
|
|
17
14
|
itkdb_gtk/getShipments.py
|
|
18
15
|
itkdb_gtk/groundVITests.py
|
|
19
16
|
itkdb_gtk/readAVSdata.py
|
|
20
17
|
itkdb_gtk/readGoogleSheet.py
|
|
21
|
-
itkdb_gtk/recover_component.py
|
|
22
18
|
itkdb_gtk/sendShipments.py
|
|
19
|
+
itkdb_gtk/untrash_component.py
|
|
20
|
+
itkdb_gtk/uploadIVfiles.py
|
|
23
21
|
itkdb_gtk/uploadMultipleTests.py
|
|
24
22
|
itkdb_gtk/uploadPetalInformation.py
|
|
25
23
|
itkdb_gtk/uploadTest.py
|
|
@@ -4,5 +4,6 @@ glueWeight = itkdb_gtk:glueWeight
|
|
|
4
4
|
groundVITests = itkdb_gtk:groundVITests
|
|
5
5
|
itkdb_dashBoard = itkdb_gtk:dash_board
|
|
6
6
|
sendShipments = itkdb_gtk:sendShipments
|
|
7
|
+
uploadIVfiles = itkdb_gtk:uploadIVfiles
|
|
7
8
|
uploadMultipleTests = itkdb_gtk:uploadMultipleTests
|
|
8
9
|
uploadTest = itkdb_gtk:uploadTest
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "itkdb_gtk"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.16.dev0"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Carlos Lacasta", email="carlos.lacasta@cern.ch" },
|
|
10
10
|
]
|
|
@@ -31,6 +31,7 @@ groundVITests = "itkdb_gtk:groundVITests"
|
|
|
31
31
|
sendShipments = "itkdb_gtk:sendShipments"
|
|
32
32
|
uploadTest = "itkdb_gtk:uploadTest"
|
|
33
33
|
uploadMultipleTests = "itkdb_gtk:uploadMultipleTests"
|
|
34
|
+
uploadIVfiles = "itkdb_gtk:uploadIVfiles"
|
|
34
35
|
|
|
35
36
|
[tool.setuptools]
|
|
36
37
|
include-package-data = true
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Check children of DB component."""
|
|
3
|
-
|
|
4
|
-
try:
|
|
5
|
-
import readAVSdata
|
|
6
|
-
import ITkDBlogin
|
|
7
|
-
import ITkDButils
|
|
8
|
-
|
|
9
|
-
from dbGtkUtils import replace_in_container, DictDialog, ask_for_confirmation
|
|
10
|
-
|
|
11
|
-
except ModuleNotFoundError:
|
|
12
|
-
from itkdb_gtk import readAVSdata, ITkDBlogin, ITkDButils
|
|
13
|
-
from itkdb_gtk.dbGtkUtils import replace_in_container, DictDialog, ask_for_confirmation
|
|
14
|
-
|
|
15
|
-
import json
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def ascii_complain(main_msg, secondary_msg=None):
|
|
19
|
-
"""Prints an error message
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
-----
|
|
23
|
-
main (): Main message
|
|
24
|
-
secondary (): Seconday message
|
|
25
|
-
"""
|
|
26
|
-
print("**Error\n{}".format(main_msg))
|
|
27
|
-
if secondary_msg:
|
|
28
|
-
msg = secondary_msg.replace("\n", "\n\t")
|
|
29
|
-
print("\t{}".format(msg))
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def find_petal(session, SN, silent=False):
|
|
33
|
-
"""Finds petal with given SN."""
|
|
34
|
-
try:
|
|
35
|
-
petal_core = ITkDButils.get_DB_component(session, SN)
|
|
36
|
-
|
|
37
|
-
except Exception as E:
|
|
38
|
-
if not silent:
|
|
39
|
-
ascii_complain("Could not find Petal Core in DB", str(E))
|
|
40
|
-
|
|
41
|
-
petal_core = None
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
try:
|
|
45
|
-
if petal_core["type"]["code"] != "CORE_AVS":
|
|
46
|
-
ascii_complain("Wrong component type", "This is not an AVS petal core")
|
|
47
|
-
|
|
48
|
-
# print(json.dumps(petal_core, indent=3))
|
|
49
|
-
|
|
50
|
-
except KeyError:
|
|
51
|
-
# Petal is not there
|
|
52
|
-
petal_core = None
|
|
53
|
-
|
|
54
|
-
return petal_core
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def get_type(child):
|
|
58
|
-
"""Return object type
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
-----
|
|
62
|
-
child (): object
|
|
63
|
-
|
|
64
|
-
Returns
|
|
65
|
-
-------
|
|
66
|
-
str: object type
|
|
67
|
-
|
|
68
|
-
"""
|
|
69
|
-
if child["type"] is not None:
|
|
70
|
-
ctype = child["type"]["code"]
|
|
71
|
-
else:
|
|
72
|
-
ctype = child["componentType"]["code"]
|
|
73
|
-
|
|
74
|
-
return ctype
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def main():
|
|
78
|
-
"""Main entry point."""
|
|
79
|
-
# ITk_PB authentication
|
|
80
|
-
dlg = ITkDBlogin.ITkDBlogin()
|
|
81
|
-
session = dlg.get_client()
|
|
82
|
-
|
|
83
|
-
final_stage = {
|
|
84
|
-
"BT_PETAL_FRONT": "COMPLETED",
|
|
85
|
-
"BT_PETAL_BACK": "COMPLETED",
|
|
86
|
-
"COOLING_LOOP_PETAL": "CLINCORE",
|
|
87
|
-
"THERMALFOAMSET_PETAL": "IN_CORE"
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
# find all cores
|
|
91
|
-
# Now all the objects
|
|
92
|
-
payload = {
|
|
93
|
-
"componentType": ["BT"],
|
|
94
|
-
"componentType": ["CORE_PETAL"],
|
|
95
|
-
"type": ["CORE_AVS"],
|
|
96
|
-
}
|
|
97
|
-
core_list = session.get("listComponents", json=payload)
|
|
98
|
-
|
|
99
|
-
for obj in core_list:
|
|
100
|
-
SN = obj["serialNumber"]
|
|
101
|
-
id = obj['alternativeIdentifier']
|
|
102
|
-
if "PPB" not in id:
|
|
103
|
-
continue
|
|
104
|
-
|
|
105
|
-
core = find_petal(session, SN)
|
|
106
|
-
if core is None:
|
|
107
|
-
print("SN: not a petal core.")
|
|
108
|
-
continue
|
|
109
|
-
|
|
110
|
-
location = core["currentLocation"]['code']
|
|
111
|
-
stage = core["currentStage"]['code']
|
|
112
|
-
if stage != "AT_QC_SITE":
|
|
113
|
-
rc = ITkDButils.set_object_stage(session, SN, "AT_QC_SITE")
|
|
114
|
-
if rc is not None:
|
|
115
|
-
print("problems setting stage")
|
|
116
|
-
|
|
117
|
-
if "children" not in core:
|
|
118
|
-
ascii_complain("{}[{}]".format(SN, id), "Not assembled")
|
|
119
|
-
continue
|
|
120
|
-
|
|
121
|
-
print("Petal {} [{}] - {}. {}".format(SN, id, stage, location))
|
|
122
|
-
clist = []
|
|
123
|
-
for child in core["children"]:
|
|
124
|
-
cstage = "Missing"
|
|
125
|
-
if child["component"] is None:
|
|
126
|
-
ctype = get_type(child)
|
|
127
|
-
clist.append((ctype, cstage, None, None))
|
|
128
|
-
|
|
129
|
-
else:
|
|
130
|
-
SN = child["component"]["serialNumber"]
|
|
131
|
-
ctype = get_type(child)
|
|
132
|
-
cobj = ITkDButils.get_DB_component(session, child["component"]["id"])
|
|
133
|
-
cstage = cobj["currentStage"]['code']
|
|
134
|
-
if cstage != final_stage[ctype]:
|
|
135
|
-
rc = ITkDButils.set_object_stage(session, SN, final_stage[ctype])
|
|
136
|
-
if rc is not None:
|
|
137
|
-
cstage = final_stage[ctype]
|
|
138
|
-
|
|
139
|
-
clocation = cobj["currentLocation"]['code']
|
|
140
|
-
clist.append((ctype, cstage, SN, clocation))
|
|
141
|
-
|
|
142
|
-
for item in clist:
|
|
143
|
-
print("\t{} [{}] - {} at {}".format(item[2], item[0], item[1], item[3]))
|
|
144
|
-
|
|
145
|
-
print()
|
|
146
|
-
|
|
147
|
-
dlg.die()
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if __name__ == "__main__":
|
|
151
|
-
main()
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Check children of DB component."""
|
|
3
|
-
|
|
4
|
-
try:
|
|
5
|
-
import ITkDBlogin
|
|
6
|
-
import ITkDButils
|
|
7
|
-
|
|
8
|
-
from dbGtkUtils import replace_in_container, DictDialog, ask_for_confirmation
|
|
9
|
-
|
|
10
|
-
except ModuleNotFoundError:
|
|
11
|
-
from itkdb_gtk import ITkDBlogin, ITkDButils
|
|
12
|
-
from itkdb_gtk.dbGtkUtils import replace_in_container, DictDialog, ask_for_confirmation
|
|
13
|
-
|
|
14
|
-
import json
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def ascii_complain(main_msg, secondary_msg=None):
|
|
18
|
-
"""Prints an error message
|
|
19
|
-
|
|
20
|
-
Args:
|
|
21
|
-
-----
|
|
22
|
-
main (): Main message
|
|
23
|
-
secondary (): Seconday message
|
|
24
|
-
"""
|
|
25
|
-
print("**Error\n{}".format(main_msg))
|
|
26
|
-
if secondary_msg:
|
|
27
|
-
msg = secondary_msg.replace("\n", "\n\t")
|
|
28
|
-
print("\t{}".format(msg))
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def find_petal(session, SN, silent=False):
|
|
32
|
-
"""Finds petal with given SN."""
|
|
33
|
-
try:
|
|
34
|
-
petal_core = ITkDButils.get_DB_component(session, SN)
|
|
35
|
-
|
|
36
|
-
except Exception as E:
|
|
37
|
-
if not silent:
|
|
38
|
-
ascii_complain("Could not find Petal Core in DB", str(E))
|
|
39
|
-
|
|
40
|
-
petal_core = None
|
|
41
|
-
return
|
|
42
|
-
|
|
43
|
-
try:
|
|
44
|
-
if petal_core["type"]["code"] != "CORE_AVS":
|
|
45
|
-
ascii_complain("Wrong component type", "This is not an AVS petal core")
|
|
46
|
-
|
|
47
|
-
# print(json.dumps(petal_core, indent=3))
|
|
48
|
-
|
|
49
|
-
except KeyError:
|
|
50
|
-
# Petal is not there
|
|
51
|
-
petal_core = None
|
|
52
|
-
|
|
53
|
-
return petal_core
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def get_type(child):
|
|
57
|
-
"""Return object type
|
|
58
|
-
|
|
59
|
-
Args:
|
|
60
|
-
-----
|
|
61
|
-
child (): object
|
|
62
|
-
|
|
63
|
-
Returns
|
|
64
|
-
-------
|
|
65
|
-
str: object type
|
|
66
|
-
|
|
67
|
-
"""
|
|
68
|
-
if child["type"] is not None:
|
|
69
|
-
ctype = child["type"]["code"]
|
|
70
|
-
else:
|
|
71
|
-
ctype = child["componentType"]["code"]
|
|
72
|
-
|
|
73
|
-
return ctype
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def main():
|
|
77
|
-
"""Main entry point."""
|
|
78
|
-
# ITk_PB authentication
|
|
79
|
-
dlg = ITkDBlogin.ITkDBlogin()
|
|
80
|
-
session = dlg.get_client()
|
|
81
|
-
|
|
82
|
-
# find all cores
|
|
83
|
-
# Now all the objects
|
|
84
|
-
payload = {
|
|
85
|
-
"componentType": ["BT"],
|
|
86
|
-
"componentType": ["CORE_PETAL"],
|
|
87
|
-
"type": ["CORE_AVS"],
|
|
88
|
-
"currentLocation": "IFIC"
|
|
89
|
-
}
|
|
90
|
-
core_list = session.get("listComponents", json=payload)
|
|
91
|
-
|
|
92
|
-
for core in core_list:
|
|
93
|
-
SN = core["serialNumber"]
|
|
94
|
-
id = core['alternativeIdentifier']
|
|
95
|
-
if "PPB" not in id:
|
|
96
|
-
continue
|
|
97
|
-
|
|
98
|
-
location = core["currentLocation"]['code']
|
|
99
|
-
stage = core["currentStage"]['code']
|
|
100
|
-
print("Petal {} [{}] - {}. {}".format(SN, id, stage, location))
|
|
101
|
-
|
|
102
|
-
# get list of tests
|
|
103
|
-
test_list = session.get("listTestRunsByComponent", json={"component": SN})
|
|
104
|
-
for tst in test_list:
|
|
105
|
-
ttype = tst["testType"]["code"]
|
|
106
|
-
inst = tst["institution"]["code"]
|
|
107
|
-
stage = tst["stage"]["code"]
|
|
108
|
-
print("\t{:<18} {:<16} {:>8} {:>3} {}".format(ttype, stage, inst, tst["runNumber"], tst["date"][:10]))
|
|
109
|
-
|
|
110
|
-
print()
|
|
111
|
-
|
|
112
|
-
dlg.die()
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if __name__ == "__main__":
|
|
116
|
-
main()
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Check tha a given JSon is valid."""
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
import json
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
import ITkDBlogin
|
|
8
|
-
import ITkDButils
|
|
9
|
-
except ModuleNotFoundError:
|
|
10
|
-
from itkdb_gtk import ITkDBlogin, ITkDButils
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def checkJSOn(session, ifile):
|
|
14
|
-
"""Check teh validity of a JSon test file
|
|
15
|
-
|
|
16
|
-
Args:
|
|
17
|
-
fname (): File or data.
|
|
18
|
-
"""
|
|
19
|
-
fnam = Path(ifile).expanduser().resolve()
|
|
20
|
-
with open(fnam, 'r') as fin:
|
|
21
|
-
user_file = json.load(fin)
|
|
22
|
-
|
|
23
|
-
test_type = user_file["testType"]
|
|
24
|
-
component = ITkDButils.get_DB_component(session, user_file["component"])
|
|
25
|
-
|
|
26
|
-
skeleton = ITkDButils.get_test_skeleton(session,
|
|
27
|
-
component["componentType"]["code"],
|
|
28
|
-
test_type)
|
|
29
|
-
|
|
30
|
-
for key in skeleton.keys():
|
|
31
|
-
if key in ["comments", "defects"]:
|
|
32
|
-
continue
|
|
33
|
-
|
|
34
|
-
if key not in user_file:
|
|
35
|
-
print("Missing key {}".format(key))
|
|
36
|
-
if key == "institution":
|
|
37
|
-
sites = session.get("listInstitutions", json={})
|
|
38
|
-
print(sites)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if __name__ == "__main__":
|
|
42
|
-
import sys
|
|
43
|
-
dlg = ITkDBlogin.ITkDBlogin()
|
|
44
|
-
client = dlg.get_client()
|
|
45
|
-
if client is None:
|
|
46
|
-
print("Could not connect to DB with provided credentials.")
|
|
47
|
-
dlg.die()
|
|
48
|
-
sys.exit()
|
|
49
|
-
|
|
50
|
-
try:
|
|
51
|
-
checkJSOn(client, sys.argv[1])
|
|
52
|
-
|
|
53
|
-
except Exception as ex:
|
|
54
|
-
print(ex)
|
|
55
|
-
|
|
56
|
-
dlg.die()
|
|
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
|