petal-qc 0.0.4__py3-none-any.whl → 0.0.6__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/BTreport/CheckBTtests.py +16 -45
- petal_qc/__init__.py +12 -3
- petal_qc/dashBoard.py +117 -10
- petal_qc/metrology/PetalMetrology.py +94 -53
- petal_qc/metrology/analyze_locking_points.py +4 -4
- petal_qc/metrology/compare_Cores.py +45 -42
- petal_qc/metrology/convert_smartscope.py +95 -12
- petal_qc/metrology/coreMetrology.py +3 -3
- petal_qc/metrology/do_Metrology.py +20 -17
- petal_qc/metrology/petal_flatness.py +1 -1
- petal_qc/test/prepareDESYfiles.py +86 -0
- petal_qc/thermal/analyze_IRCore.py +34 -16
- petal_qc/thermal/coreThermal.py +2 -1
- petal_qc/thermal/create_core_report.py +21 -3
- petal_qc/utils/Geometry.py +8 -3
- {petal_qc-0.0.4.dist-info → petal_qc-0.0.6.dist-info}/METADATA +1 -1
- {petal_qc-0.0.4.dist-info → petal_qc-0.0.6.dist-info}/RECORD +20 -19
- {petal_qc-0.0.4.dist-info → petal_qc-0.0.6.dist-info}/WHEEL +1 -1
- {petal_qc-0.0.4.dist-info → petal_qc-0.0.6.dist-info}/entry_points.txt +2 -0
- {petal_qc-0.0.4.dist-info → petal_qc-0.0.6.dist-info}/top_level.txt +0 -0
|
@@ -19,6 +19,7 @@ import datetime
|
|
|
19
19
|
import dateutil.parser
|
|
20
20
|
import itkdb
|
|
21
21
|
from itkdb_gtk import ITkDBlogin
|
|
22
|
+
from itkdb_gtk import ITkDButils
|
|
22
23
|
|
|
23
24
|
def complain(main_msg, secondary_msg=None):
|
|
24
25
|
"""Prints an error message
|
|
@@ -34,42 +35,6 @@ def complain(main_msg, secondary_msg=None):
|
|
|
34
35
|
print("\t{}".format(msg))
|
|
35
36
|
|
|
36
37
|
|
|
37
|
-
def find_petal(session, SerialN, silent=False, complain_func=complain):
|
|
38
|
-
"""Find petal with given SerialN.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
-----
|
|
42
|
-
session (itkdb.Client): The DB session
|
|
43
|
-
SerialN (str): The petal SerialNumber
|
|
44
|
-
silent (bool, optional): No compllaint writen. Defaults to False.
|
|
45
|
-
|
|
46
|
-
Returns
|
|
47
|
-
-------
|
|
48
|
-
dict: A petal (JSon)
|
|
49
|
-
|
|
50
|
-
Raises
|
|
51
|
-
------
|
|
52
|
-
LookupError if petal not found
|
|
53
|
-
TypeError if SerialN is not a CORE_AVS
|
|
54
|
-
"""
|
|
55
|
-
try:
|
|
56
|
-
petal_core = session.get('getComponent', json={'component': SerialN})
|
|
57
|
-
|
|
58
|
-
except Exception as ex:
|
|
59
|
-
if not silent:
|
|
60
|
-
complain_func("Could not find Petal Core in DB", str(ex))
|
|
61
|
-
|
|
62
|
-
raise LookupError("Could not find Petal core with SN {}".format(SerialN)) from ex
|
|
63
|
-
|
|
64
|
-
if petal_core["type"]["code"] != "CORE_AVS":
|
|
65
|
-
if not silent:
|
|
66
|
-
complain_func("Wrong component type", "This is not an AVS petal core")
|
|
67
|
-
|
|
68
|
-
raise TypeError("This is not an AVS petal core")
|
|
69
|
-
|
|
70
|
-
return petal_core
|
|
71
|
-
|
|
72
|
-
|
|
73
38
|
def get_type(child):
|
|
74
39
|
"""Return object type
|
|
75
40
|
|
|
@@ -143,7 +108,10 @@ def find_but_tape_tests(session, petal_date, bt_sn, complain_func=complain):
|
|
|
143
108
|
dict: dict with all tests. key is the test type code.
|
|
144
109
|
|
|
145
110
|
"""
|
|
146
|
-
test_list = session.get("listTestRunsByComponent",
|
|
111
|
+
test_list = session.get("listTestRunsByComponent",
|
|
112
|
+
json={"filterMap":{"serialNumber": bt_sn,
|
|
113
|
+
"stage": "COMPLETED"}
|
|
114
|
+
})
|
|
147
115
|
bt_tests = {}
|
|
148
116
|
for tst in test_list:
|
|
149
117
|
test_type = tst["testType"]["name"]
|
|
@@ -187,13 +155,13 @@ def BTreport(session, SerialN, complain_func=complain):
|
|
|
187
155
|
SerialN (str): The Petal core SB
|
|
188
156
|
"""
|
|
189
157
|
# get petal frm DB.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
except Exception as ex:
|
|
194
|
-
print(str(ex))
|
|
158
|
+
petal = ITkDButils.get_DB_component(session, SerialN)
|
|
159
|
+
if petal is None:
|
|
160
|
+
complain_func(SerialN, "Could not find petal core.")
|
|
195
161
|
return None
|
|
196
162
|
|
|
163
|
+
SerialN = petal["serialNumber"]
|
|
164
|
+
|
|
197
165
|
print("+++ Petal core {} [{}]".format(SerialN, petal["alternativeIdentifier"]))
|
|
198
166
|
petal_date = dateutil.parser.parse(petal["stateTs"])
|
|
199
167
|
comp_type = get_type(petal)
|
|
@@ -291,7 +259,7 @@ def main():
|
|
|
291
259
|
try:
|
|
292
260
|
SN = sys.argv[1]
|
|
293
261
|
except IndexError:
|
|
294
|
-
print("I need a petal core SN")
|
|
262
|
+
print("I need a petal core SN or AlternativeID")
|
|
295
263
|
sys.exit()
|
|
296
264
|
|
|
297
265
|
# ITk PDB authentication
|
|
@@ -314,8 +282,11 @@ def main():
|
|
|
314
282
|
out = BTreport(client, SN)
|
|
315
283
|
# Upload test
|
|
316
284
|
if out:
|
|
317
|
-
|
|
318
|
-
|
|
285
|
+
try:
|
|
286
|
+
db_response = client.post("uploadTestRunResults", json=out)
|
|
287
|
+
except Exception as ex:
|
|
288
|
+
print("Could not upload test.")
|
|
289
|
+
print(ex)
|
|
319
290
|
|
|
320
291
|
|
|
321
292
|
except Exception:
|
petal_qc/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""petal_qc python module."""
|
|
2
|
-
__version__ = "0.0.
|
|
2
|
+
__version__ = "0.0.6"
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def coreMetrology():
|
|
@@ -7,14 +7,23 @@ def coreMetrology():
|
|
|
7
7
|
from .metrology.coreMetrology import main
|
|
8
8
|
main()
|
|
9
9
|
|
|
10
|
+
def doMetrology():
|
|
11
|
+
"""Launches the Core metrology analysis in the command line."""
|
|
12
|
+
from .metrology.do_metrology import main
|
|
13
|
+
main()
|
|
14
|
+
|
|
10
15
|
def coreThermal():
|
|
11
16
|
"""Launches the Core thermal analysis ahd PDB script."""
|
|
12
17
|
from .thermal.coreThermal import main
|
|
13
18
|
main()
|
|
14
19
|
|
|
15
|
-
|
|
16
20
|
def bustapeReport():
|
|
17
21
|
"""Launches the Core metrology analysis ahd PDB script."""
|
|
18
|
-
from .BTreport.
|
|
22
|
+
from .BTreport.CheckBTtests import main
|
|
23
|
+
# from .BTreport.bustapeReport import main
|
|
19
24
|
main()
|
|
20
25
|
|
|
26
|
+
def dashBoard():
|
|
27
|
+
"""Launches the Core thermal analysis ahd PDB script."""
|
|
28
|
+
from .dashBoard import main
|
|
29
|
+
main()
|
petal_qc/dashBoard.py
CHANGED
|
@@ -6,16 +6,123 @@ try:
|
|
|
6
6
|
|
|
7
7
|
except ImportError:
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
cwd = Path(__file__).parent
|
|
9
|
+
cwd = Path(__file__).parent
|
|
10
10
|
sys.path.append(cwd.as_posix())
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
from petal_qc.metrology.coreMetrology import CoreMetrology, CoreMetrologyOptions
|
|
13
|
+
from petal_qc.thermal.coreThermal import CoreThermal
|
|
14
|
+
from petal_qc.thermal.IRPetalParam import IRPetalParam
|
|
15
|
+
|
|
12
16
|
from itkdb_gtk import dbGtkUtils
|
|
13
|
-
from itkdb_gtk import GetShipments
|
|
14
|
-
from itkdb_gtk import PetalReceptionTests
|
|
15
17
|
from itkdb_gtk import ITkDBlogin
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
from
|
|
21
|
-
|
|
18
|
+
|
|
19
|
+
import gi
|
|
20
|
+
|
|
21
|
+
gi.require_version("Gtk", "3.0")
|
|
22
|
+
from gi.repository import Gtk
|
|
23
|
+
|
|
24
|
+
HELP_LINK="https://petal-qc.docs.cern.ch"
|
|
25
|
+
|
|
26
|
+
class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
27
|
+
"""Dashboard class."""
|
|
28
|
+
PETAL_CORE_METRO = 1
|
|
29
|
+
PETAL_CORE_THERMAL = 2
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def __init__(self, session):
|
|
33
|
+
"""Initialization."""
|
|
34
|
+
super().__init__(title="Petal-QC Dashboard", session=session, help_link=HELP_LINK)
|
|
35
|
+
self.mask = 0
|
|
36
|
+
|
|
37
|
+
# set border width
|
|
38
|
+
self.set_border_width(10)
|
|
39
|
+
|
|
40
|
+
# Prepare dashboard
|
|
41
|
+
grid = Gtk.Grid(column_spacing=5, row_spacing=5)
|
|
42
|
+
self.mainBox.pack_start(grid, False, True, 5)
|
|
43
|
+
|
|
44
|
+
irow = 0
|
|
45
|
+
lbl = Gtk.Label()
|
|
46
|
+
lbl.set_markup("<b>Tests</b>")
|
|
47
|
+
lbl.set_xalign(0)
|
|
48
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
49
|
+
|
|
50
|
+
irow += 1
|
|
51
|
+
btnPetalMetrology = Gtk.Button(label="Petal Core Metrology")
|
|
52
|
+
btnPetalMetrology.connect("clicked", self.petal_metrology)
|
|
53
|
+
grid.attach(btnPetalMetrology, 0, irow, 1, 1)
|
|
54
|
+
|
|
55
|
+
btnPetalThermal = Gtk.Button(label="Petal Core Thermal")
|
|
56
|
+
btnPetalThermal.connect("clicked", self.petal_thermal)
|
|
57
|
+
grid.attach(btnPetalThermal, 1, irow, 1, 1)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
irow += 1
|
|
61
|
+
grid.attach(Gtk.Label(), 0, irow, 1, 1)
|
|
62
|
+
|
|
63
|
+
self.mainBox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), False, True, 5)
|
|
64
|
+
|
|
65
|
+
self.show_all()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def petal_metrology(self, *args):
|
|
69
|
+
"""Do petal metrology"""
|
|
70
|
+
bitn = DashWindow.PETAL_CORE_METRO
|
|
71
|
+
bt = 1 << bitn
|
|
72
|
+
if self.mask & bt:
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
self.mask |= bt
|
|
76
|
+
opts = CoreMetrologyOptions()
|
|
77
|
+
W = CoreMetrology(opts, session=self.session, title="Petal Core Metrology")
|
|
78
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
79
|
+
W.show_all()
|
|
80
|
+
|
|
81
|
+
def petal_thermal(self, *args):
|
|
82
|
+
"""Do petal thermal."""
|
|
83
|
+
bitn = DashWindow.PETAL_CORE_THERMAL
|
|
84
|
+
bt = 1 << bitn
|
|
85
|
+
if self.mask & bt:
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
self.mask |= bt
|
|
89
|
+
opt = IRPetalParam()
|
|
90
|
+
opt.folder = None
|
|
91
|
+
opt.out = None
|
|
92
|
+
opt.alias = None
|
|
93
|
+
opt.SN = None
|
|
94
|
+
W = CoreThermal(opt, self.session, title="Petal Thermal Test.")
|
|
95
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
96
|
+
W.show_all()
|
|
97
|
+
|
|
98
|
+
def app_closed(self, *args):
|
|
99
|
+
"""Application window closed. Clear mask."""
|
|
100
|
+
bt = 1 << args[1]
|
|
101
|
+
self.mask &= ~bt
|
|
102
|
+
# print(bt, self.mask)
|
|
103
|
+
|
|
104
|
+
def main():
|
|
105
|
+
"""Main entry"""
|
|
106
|
+
# DB login
|
|
107
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
108
|
+
client = dlg.get_client()
|
|
109
|
+
if client is None:
|
|
110
|
+
print("Could not connect to DB with provided credentials.")
|
|
111
|
+
dlg.die()
|
|
112
|
+
sys.exit()
|
|
113
|
+
|
|
114
|
+
client.user_gui = dlg
|
|
115
|
+
|
|
116
|
+
dashW = DashWindow(client)
|
|
117
|
+
dashW.connect("destroy", Gtk.main_quit)
|
|
118
|
+
try:
|
|
119
|
+
Gtk.main()
|
|
120
|
+
|
|
121
|
+
except KeyboardInterrupt:
|
|
122
|
+
print("Arrrgggg!!!")
|
|
123
|
+
|
|
124
|
+
dlg.die()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
main()
|
|
@@ -4,6 +4,8 @@ import io
|
|
|
4
4
|
import json
|
|
5
5
|
import sys
|
|
6
6
|
import traceback
|
|
7
|
+
from tempfile import NamedTemporaryFile
|
|
8
|
+
|
|
7
9
|
from argparse import Action
|
|
8
10
|
from argparse import ArgumentParser
|
|
9
11
|
from datetime import datetime
|
|
@@ -19,6 +21,7 @@ from petal_qc.metrology import DataFile
|
|
|
19
21
|
from petal_qc.metrology.analyze_locking_points import analyze_locking_point_data
|
|
20
22
|
from petal_qc.metrology.analyze_locking_points import locking_point_positions
|
|
21
23
|
from petal_qc.metrology.convert_mitutoyo import mitutoyo2cvs
|
|
24
|
+
from petal_qc.metrology.convert_smartscope import get_smarscope_locator_positions
|
|
22
25
|
from petal_qc.metrology.petal_flatness import petal_flatness
|
|
23
26
|
|
|
24
27
|
|
|
@@ -46,11 +49,11 @@ def check_spec(val, nom, fraction=0.0):
|
|
|
46
49
|
class CommaSeparatedListAction(Action):
|
|
47
50
|
"""Create a list from the comma sepparated numbers at imput."""
|
|
48
51
|
|
|
49
|
-
def __call__(self,
|
|
52
|
+
def __call__(self, args_parser, namespace, values, option_string=None):
|
|
50
53
|
"""The actual action."""
|
|
51
54
|
value = np.array(list(map(float, values.split(','))), dtype='float64')
|
|
52
55
|
if value.shape[0] < 3:
|
|
53
|
-
raise
|
|
56
|
+
raise ValueError("{} needs a 3D vector".format(self.dest))
|
|
54
57
|
|
|
55
58
|
setattr(namespace, self.dest, value)
|
|
56
59
|
|
|
@@ -59,12 +62,10 @@ def petal_metrology(ifile, options):
|
|
|
59
62
|
"""Do the analysis of the petal metrology data.
|
|
60
63
|
|
|
61
64
|
Args:
|
|
62
|
-
----
|
|
63
65
|
ifile: Input file from Mitutoyo.
|
|
64
66
|
options: Command line options.
|
|
65
67
|
|
|
66
68
|
Return
|
|
67
|
-
------
|
|
68
69
|
Dictionary with DB values
|
|
69
70
|
|
|
70
71
|
"""
|
|
@@ -111,7 +112,8 @@ def petal_metrology(ifile, options):
|
|
|
111
112
|
"PARALLELISM": 0,
|
|
112
113
|
"CHECK_BOT_LOC_DIAM": True,
|
|
113
114
|
"CHECK_SLOT_LOC_DIAM": True,
|
|
114
|
-
"CHECK_OVERSIZE_LOC_DIAM": True
|
|
115
|
+
"CHECK_OVERSIZE_LOC_DIAM": True,
|
|
116
|
+
"DIAM": {"FD01": 0., "FD02":0, "PL01":0, "PL02":0, "PL03":0}
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
# Open the output doc.
|
|
@@ -152,7 +154,7 @@ def petal_metrology(ifile, options):
|
|
|
152
154
|
# Do locator flatness analysis
|
|
153
155
|
TM = None # TODO: fix this
|
|
154
156
|
if options.desy:
|
|
155
|
-
locator_data = DataFile.read(ifile, ".*_FineFlatness")
|
|
157
|
+
locator_data = DataFile.read(ifile, "PL[0-9]+_Plane") #".*_FineFlatness")
|
|
156
158
|
else:
|
|
157
159
|
locator_data = DataFile.read(ifile, "PuntoLocator", "Punto")
|
|
158
160
|
locator_data[:, 2] -= Fmean
|
|
@@ -179,8 +181,8 @@ def petal_metrology(ifile, options):
|
|
|
179
181
|
dbOut["comments"].append("Offset of locator plane w.r.t BT is {:.3f} mm".format(val))
|
|
180
182
|
|
|
181
183
|
# Analyze locking point positions
|
|
184
|
+
ofile = io.StringIO()
|
|
182
185
|
if not options.desy:
|
|
183
|
-
ofile = io.StringIO()
|
|
184
186
|
mitutoyo2cvs([ifile], ofile,
|
|
185
187
|
label=r"agujero_inf|Locator\w*|Slot\w+|Fiducial\w+",
|
|
186
188
|
data_type="Círculo|Punto",
|
|
@@ -190,61 +192,85 @@ def petal_metrology(ifile, options):
|
|
|
190
192
|
tbl = pd.read_csv(ofile, names=["X", "Y", "Z", "D", "R", "C", "Name"], sep=',', skiprows=1, index_col="Name")
|
|
191
193
|
print(tbl)
|
|
192
194
|
|
|
193
|
-
keywords = [n for n in tbl.index]
|
|
195
|
+
# keywords = [n for n in tbl.index]
|
|
194
196
|
# if "FiducialBot" in keywords:
|
|
195
197
|
# indx = ["agujero_inf", "LocatorTop", "FiducialBot", "FiducialTop"]
|
|
196
198
|
# offset = 0
|
|
197
199
|
# else:
|
|
198
200
|
# indx = ["LocatorBot", "LocatorTop", "agujero_inf", "FiducialTop"]
|
|
199
201
|
# offset = 3
|
|
200
|
-
|
|
202
|
+
|
|
201
203
|
indx = ["LocatorBot", "LocatorTop", "agujero_inf", "FiducialTop"]
|
|
202
204
|
offset = 3
|
|
203
|
-
|
|
204
205
|
|
|
206
|
+
# Compute Slot center (get average of diameter)
|
|
205
207
|
slot_center = np.mean(tbl.loc[["SlotSup", "SlotInf"]][["X", "Y", "D"]].values, axis=0)
|
|
206
208
|
|
|
207
209
|
print("")
|
|
208
210
|
print()
|
|
209
211
|
print(tbl.loc[indx][["X", "Y", "D"]])
|
|
210
|
-
|
|
212
|
+
tvalues = tbl.loc[indx][["X", "Y", "D"]].values
|
|
211
213
|
|
|
212
|
-
ninput = np.insert(
|
|
214
|
+
ninput = np.insert(tvalues, 1, slot_center, axis=0)
|
|
215
|
+
ninput[:, 1] += offset
|
|
216
|
+
|
|
217
|
+
else:
|
|
218
|
+
get_smarscope_locator_positions(ifile, ofile, "\\w+(PL|_Fiducial)\\s+", keep=True)
|
|
219
|
+
ofile.seek(0)
|
|
220
|
+
tbl = pd.read_csv(ofile, names=["X", "Y", "D", "Name"], sep=',', skiprows=1, index_col="Name")
|
|
221
|
+
print("")
|
|
222
|
+
print()
|
|
223
|
+
print(tbl)
|
|
224
|
+
ninput = tbl[["X", "Y", "D"]].values
|
|
225
|
+
offset = 3
|
|
213
226
|
ninput[:, 1] += offset
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
227
|
+
|
|
228
|
+
# Input array is
|
|
229
|
+
# 0 - Bottom locator (PL01)
|
|
230
|
+
# 1 - Top Slot (PL02)
|
|
231
|
+
# 2 - Oversized (PL03)
|
|
232
|
+
# 3 - Bottom Fid (FD01)
|
|
233
|
+
# 4 - Top Fid (FD02)
|
|
234
|
+
results["DIAM"]["FD01"] = ninput[3, 2]
|
|
235
|
+
results["DIAM"]["FD02"] = ninput[4, 2]
|
|
236
|
+
results["DIAM"]["PL01"] = ninput[0, 2]
|
|
237
|
+
results["DIAM"]["PL02"] = ninput[1, 2]
|
|
238
|
+
results["DIAM"]["PL03"] = ninput[2, 2]
|
|
239
|
+
|
|
240
|
+
out = locking_point_positions(ninput, document)
|
|
241
|
+
for key, val in out.items():
|
|
242
|
+
results[key] = val
|
|
243
|
+
if key == "LOCATION_DELTA":
|
|
244
|
+
for k, v in val.items():
|
|
245
|
+
delta = np.linalg.norm(v)
|
|
246
|
+
if not check_spec(delta, 0.050):
|
|
247
|
+
dbOut["defects"].append({
|
|
248
|
+
"name": key,
|
|
249
|
+
"description": "Delta {} is {:.3f} mm > 0.050 mm.".format(k, delta)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
elif key == "REL_POS_DELTA":
|
|
253
|
+
for k, v in val.items():
|
|
254
|
+
delta = np.linalg.norm(v)
|
|
255
|
+
if not check_spec(delta, 0.025):
|
|
256
|
+
dbOut["defects"].append({
|
|
257
|
+
"name": key,
|
|
258
|
+
"description": "Delta {} is {:.3f} mm > 0.025 mm.".format(k, delta)
|
|
259
|
+
})
|
|
260
|
+
|
|
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.025 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
|
+
})
|
|
248
274
|
|
|
249
275
|
ofile.close()
|
|
250
276
|
|
|
@@ -282,8 +308,8 @@ def petal_metrology(ifile, options):
|
|
|
282
308
|
|
|
283
309
|
return dbOut
|
|
284
310
|
|
|
285
|
-
|
|
286
|
-
|
|
311
|
+
def do_petal_metrology():
|
|
312
|
+
"""main entry."""
|
|
287
313
|
parser = ArgumentParser()
|
|
288
314
|
parser.add_argument('files', nargs='*', help="Input files")
|
|
289
315
|
parser.add_argument("--SN", default="SNxxxx", help="Petal core serial nunber")
|
|
@@ -309,19 +335,34 @@ if __name__ == "__main__":
|
|
|
309
335
|
parser.add_argument("--label", default="\\w+", help="The label to select")
|
|
310
336
|
parser.add_argument("--type", default="Punto", help="The class to select")
|
|
311
337
|
|
|
312
|
-
|
|
313
|
-
if len(
|
|
338
|
+
args = parser.parse_args()
|
|
339
|
+
if len(args.files) == 0:
|
|
314
340
|
print(sys.argv[0])
|
|
315
341
|
print("I need an input file")
|
|
316
342
|
sys.exit()
|
|
317
343
|
|
|
344
|
+
if len(args.files) == 1:
|
|
345
|
+
ifile = args.files[0]
|
|
346
|
+
else:
|
|
347
|
+
ifnam = NamedTemporaryFile(delete_on_close=False)
|
|
348
|
+
ifile = ifnam.name
|
|
349
|
+
for ff in args.files:
|
|
350
|
+
with open(ff, 'rb') as F:
|
|
351
|
+
ifnam.write(F.read())
|
|
352
|
+
|
|
353
|
+
ifnam.close()
|
|
354
|
+
|
|
355
|
+
|
|
318
356
|
try:
|
|
319
|
-
outDB = petal_metrology(
|
|
320
|
-
ofile = output_folder(
|
|
321
|
-
with open(ofile, 'w') as of:
|
|
357
|
+
outDB = petal_metrology(ifile, args)
|
|
358
|
+
ofile = output_folder(args.folder, args.prefix + '.json')
|
|
359
|
+
with open(ofile, 'w', encoding="UTF-8") as of:
|
|
322
360
|
json.dump(outDB, of)
|
|
323
361
|
|
|
324
362
|
except Exception:
|
|
325
363
|
print(traceback.format_exc())
|
|
326
364
|
|
|
327
365
|
plt.show()
|
|
366
|
+
|
|
367
|
+
if __name__ == "__main__":
|
|
368
|
+
do_petal_metrology()
|
|
@@ -14,7 +14,7 @@ import petal_qc.utils.docx_utils as docx_utils
|
|
|
14
14
|
from petal_qc.metrology import DataFile
|
|
15
15
|
from petal_qc.metrology.Cluster import cluster_points
|
|
16
16
|
from petal_qc.utils.Geometry import fit_plane
|
|
17
|
-
from petal_qc.utils.Geometry import flatness_conhull
|
|
17
|
+
from petal_qc.utils.Geometry import flatness_conhull, flatness_LSPL
|
|
18
18
|
from petal_qc.utils.Geometry import project_to_plane
|
|
19
19
|
from petal_qc.utils.Geometry import vector_angle
|
|
20
20
|
from petal_qc.utils.utils import get_min_max
|
|
@@ -400,15 +400,15 @@ def analyze_locking_point_data(orig_data, nbins=50, plane_fit=True, cut=3, docum
|
|
|
400
400
|
print("{:7.3f} {:7.3f} {:7.3f}".format(C.x, C.y, C.z))
|
|
401
401
|
|
|
402
402
|
if len(good):
|
|
403
|
-
flatness =
|
|
404
|
-
print("Locking point flatness: {:.1f}".format(1000*flatness))
|
|
403
|
+
flatness = flatness_LSPL(plane[good, :])
|
|
404
|
+
print("Locking point flatness (LSPL): {:.1f}".format(1000*flatness))
|
|
405
405
|
else:
|
|
406
406
|
print("Not enough points to compute flatness.")
|
|
407
407
|
flatness = -1.e-3
|
|
408
408
|
|
|
409
409
|
outDB["COPLANARITY_LOCATORS"] = flatness
|
|
410
410
|
if document:
|
|
411
|
-
document.add_paragraph("Locking point flatness (
|
|
411
|
+
document.add_paragraph("Locking point flatness (LSPL): {:.1f} µm.".format(1000*flatness))
|
|
412
412
|
|
|
413
413
|
# Show all data
|
|
414
414
|
fig = show_data(plane[good, :], "All", nbins=nbins, color_bar=True)
|