petal-qc 0.0.0__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 +321 -0
- petal_qc/BTreport/__init__.py +0 -0
- petal_qc/BTreport/bustapeReport.py +144 -0
- petal_qc/__init__.py +14 -0
- petal_qc/metrology/Cluster.py +90 -0
- petal_qc/metrology/DataFile.py +47 -0
- petal_qc/metrology/PetalMetrology.py +327 -0
- petal_qc/metrology/__init__.py +0 -0
- petal_qc/metrology/all2csv.py +57 -0
- petal_qc/metrology/analyze_locking_points.py +597 -0
- petal_qc/metrology/cold_noise.py +106 -0
- petal_qc/metrology/comparisonTable.py +59 -0
- petal_qc/metrology/convert_mitutoyo.py +175 -0
- petal_qc/metrology/convert_smartscope.py +145 -0
- petal_qc/metrology/coreMetrology.py +402 -0
- petal_qc/metrology/data2csv.py +63 -0
- petal_qc/metrology/do_Metrology.py +117 -0
- petal_qc/metrology/flatness4nigel.py +157 -0
- petal_qc/metrology/gtkutils.py +120 -0
- petal_qc/metrology/petal_flatness.py +353 -0
- petal_qc/metrology/show_data_file.py +118 -0
- petal_qc/metrology/testSummary.py +37 -0
- petal_qc/metrology/test_paralelism.py +71 -0
- petal_qc/thermal/CSVImage.py +69 -0
- petal_qc/thermal/DebugPlot.py +76 -0
- petal_qc/thermal/IRBFile.py +768 -0
- petal_qc/thermal/IRCore.py +110 -0
- petal_qc/thermal/IRDataGetter.py +359 -0
- petal_qc/thermal/IRPetal.py +1338 -0
- petal_qc/thermal/IRPetalParam.py +71 -0
- petal_qc/thermal/PetalColorMaps.py +62 -0
- petal_qc/thermal/Petal_IR_Analysis.py +142 -0
- petal_qc/thermal/PipeFit.py +598 -0
- petal_qc/thermal/__init__.py +0 -0
- petal_qc/thermal/analyze_IRCore.py +417 -0
- petal_qc/thermal/contours.py +378 -0
- petal_qc/thermal/create_IRCore.py +185 -0
- petal_qc/thermal/pipe_read.py +182 -0
- petal_qc/thermal/show_IR_petal.py +420 -0
- petal_qc/utils/Geometry.py +756 -0
- petal_qc/utils/Progress.py +182 -0
- petal_qc/utils/__init__.py +0 -0
- petal_qc/utils/all_files.py +35 -0
- petal_qc/utils/docx_utils.py +186 -0
- petal_qc/utils/fit_utils.py +188 -0
- petal_qc/utils/utils.py +180 -0
- petal_qc-0.0.0.dist-info/METADATA +29 -0
- petal_qc-0.0.0.dist-info/RECORD +51 -0
- petal_qc-0.0.0.dist-info/WHEEL +5 -0
- petal_qc-0.0.0.dist-info/entry_points.txt +3 -0
- petal_qc-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""GUI to launch metrology analysis."""
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from argparse import Action
|
|
5
|
+
from argparse import ArgumentParser
|
|
6
|
+
import itkdb_gtk.ITkDButils
|
|
7
|
+
import itkdb_gtk.dbGtkUtils
|
|
8
|
+
import numpy as np
|
|
9
|
+
from contextlib import redirect_stdout
|
|
10
|
+
import itkdb_gtk
|
|
11
|
+
import itkdb_gtk.UploadTest
|
|
12
|
+
|
|
13
|
+
from petal_qc.metrology.do_Metrology import do_analysis
|
|
14
|
+
|
|
15
|
+
import gi
|
|
16
|
+
gi.require_version("Gtk", "3.0")
|
|
17
|
+
from gi.repository import Gtk, GObject, Gio, GLib
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CommaSeparatedListAction(Action):
|
|
22
|
+
"""Create a list from the comma sepparated numbers at imput."""
|
|
23
|
+
|
|
24
|
+
def __call__(self, parser, namespace, values, option_string=None):
|
|
25
|
+
"""The actual action."""
|
|
26
|
+
value = np.array(list(map(float, values.split(','))), dtype='float64')
|
|
27
|
+
if value.shape[0] < 3:
|
|
28
|
+
raise Exception("{} needs a 3D vector".format(self.dest))
|
|
29
|
+
|
|
30
|
+
setattr(namespace, self.dest, value)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CoreMetrology(itkdb_gtk.dbGtkUtils.ITkDBWindow):
|
|
34
|
+
"""Application window."""
|
|
35
|
+
|
|
36
|
+
def __init__(self, options, session=None, title="", panel_size=100):
|
|
37
|
+
"""Initialization.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
title: The title of the window.
|
|
41
|
+
pannel_size: size of message panel.
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
super().__init__(session=session, title=title)
|
|
45
|
+
|
|
46
|
+
self.data_file = None
|
|
47
|
+
self.folder = None
|
|
48
|
+
self.petal_SN = None
|
|
49
|
+
self.petal_prefix = None
|
|
50
|
+
self.options = options
|
|
51
|
+
self.alternativeID = None
|
|
52
|
+
self.outDB = None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Active button in header
|
|
56
|
+
button = Gtk.Button()
|
|
57
|
+
icon = Gio.ThemedIcon(name="document-send-symbolic")
|
|
58
|
+
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
59
|
+
button.add(image)
|
|
60
|
+
button.set_tooltip_text("Click to upload test")
|
|
61
|
+
button.connect("clicked", self.upload_test_gui)
|
|
62
|
+
self.hb.pack_end(button)
|
|
63
|
+
|
|
64
|
+
# JScon edit
|
|
65
|
+
button = Gtk.Button()
|
|
66
|
+
icon = Gio.ThemedIcon(name="accessories-text-editor-symbolic")
|
|
67
|
+
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
68
|
+
button.add(image)
|
|
69
|
+
button.set_tooltip_text("Click to see the test data")
|
|
70
|
+
button.connect("clicked", self.show_test_gui)
|
|
71
|
+
self.hb.pack_end(button)
|
|
72
|
+
|
|
73
|
+
# The file chooser
|
|
74
|
+
self.btnData = Gtk.FileChooserButton()
|
|
75
|
+
self.btnData.connect("file-set", self.on_file_set)
|
|
76
|
+
if len(options.files) > 0 :
|
|
77
|
+
ifile = Path(options.files[0]).expanduser().resolve().as_posix()
|
|
78
|
+
self.btnData.set_filename(ifile)
|
|
79
|
+
self.on_file_set()
|
|
80
|
+
|
|
81
|
+
# the folder option
|
|
82
|
+
self.btnFolder = Gtk.FileChooserButton()
|
|
83
|
+
self.btnFolder.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
|
|
84
|
+
self.btnFolder.connect("file-set", self.on_folder_set)
|
|
85
|
+
if options.folder and len(options.folder) > 0 :
|
|
86
|
+
ifile = Path(options.folder).expanduser().resolve().as_posix()
|
|
87
|
+
self.btnFolder.set_filename(ifile)
|
|
88
|
+
|
|
89
|
+
# The Serial number
|
|
90
|
+
self.SN = itkdb_gtk.dbGtkUtils.TextEntry()
|
|
91
|
+
self.SN.connect("text-changed", self.on_SN_changed)
|
|
92
|
+
if options.SN:
|
|
93
|
+
self.on_SN_changed(self.SN.entry, options.SN)
|
|
94
|
+
|
|
95
|
+
# The prefix
|
|
96
|
+
self.prefix = Gtk.Entry()
|
|
97
|
+
if options.prefix:
|
|
98
|
+
self.SN.set_text(options.prefix)
|
|
99
|
+
|
|
100
|
+
self.desy = Gtk.Switch()
|
|
101
|
+
self.desy.props.halign = Gtk.Align.START
|
|
102
|
+
|
|
103
|
+
self.back = Gtk.Switch()
|
|
104
|
+
self.back.props.halign = Gtk.Align.START
|
|
105
|
+
self.back.connect("state_set", self.change_to_back)
|
|
106
|
+
|
|
107
|
+
self.run = Gtk.Button(label="Run")
|
|
108
|
+
self.run.connect("clicked", self.run_analysis)
|
|
109
|
+
|
|
110
|
+
self.btn_state = Gtk.Button(label="Undef")
|
|
111
|
+
self.btn_state.set_name("btnState")
|
|
112
|
+
self.btn_state.connect("clicked", self.show_state)
|
|
113
|
+
self.btn_state.set_tooltip_text("If green all good. Click to see commnets and defects.")
|
|
114
|
+
|
|
115
|
+
if options.desy:
|
|
116
|
+
self.desy.set_active(True)
|
|
117
|
+
|
|
118
|
+
# Put the 3 objects in a Grid
|
|
119
|
+
grid = Gtk.Grid(column_spacing=5, row_spacing=5)
|
|
120
|
+
self.mainBox.pack_start(grid, False, True, 0)
|
|
121
|
+
|
|
122
|
+
grid.attach(Gtk.Label(label="Serial No."), 0, 0, 1, 1)
|
|
123
|
+
grid.attach(self.SN.entry, 1, 0, 1, 1)
|
|
124
|
+
|
|
125
|
+
grid.attach(self.btn_state, 2, 0, 1, 1)
|
|
126
|
+
|
|
127
|
+
grid.attach(Gtk.Label(label="DESY"), 3, 0, 1, 1)
|
|
128
|
+
grid.attach(self.desy, 4, 0, 1, 1)
|
|
129
|
+
|
|
130
|
+
grid.attach(Gtk.Label(label="Prefix"), 0, 1, 1, 1)
|
|
131
|
+
grid.attach(self.prefix, 1, 1, 1, 1)
|
|
132
|
+
|
|
133
|
+
grid.attach(Gtk.Label(label="Data File"), 0, 2, 1, 1)
|
|
134
|
+
grid.attach(self.btnData, 1, 2, 1, 1)
|
|
135
|
+
|
|
136
|
+
grid.attach(Gtk.Label(label="Back"), 2, 2, 1, 1)
|
|
137
|
+
grid.attach(self.back, 3, 2, 1, 1)
|
|
138
|
+
grid.attach(Gtk.Label(label="Front"), 4, 2, 1, 1)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
grid.attach(Gtk.Label(label="Folder"), 0, 3, 1, 1)
|
|
143
|
+
grid.attach(self.btnFolder, 1, 3, 1, 1)
|
|
144
|
+
|
|
145
|
+
grid.attach(self.run, 0, 4, 5, 1)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
self.mainBox.pack_start(self.message_panel.frame, True, True, 0)
|
|
149
|
+
|
|
150
|
+
def quit(self, *args):
|
|
151
|
+
"""Quits the application."""
|
|
152
|
+
self.hide()
|
|
153
|
+
self.destroy()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def on_file_set(self, *args):
|
|
157
|
+
"""File chosen from FileChooser."""
|
|
158
|
+
PSF = self.btnData.get_filename()
|
|
159
|
+
if PSF is None or not Path(PSF).exists():
|
|
160
|
+
itkdb_gtk.dbGtkUtils.complain("Could not find Data File", PSF, parent=self)
|
|
161
|
+
return
|
|
162
|
+
|
|
163
|
+
self.data_file = PSF
|
|
164
|
+
|
|
165
|
+
def on_folder_set(self, *args):
|
|
166
|
+
"""Folder chosen."""
|
|
167
|
+
F = self.btnFolder.get_filename()
|
|
168
|
+
if F is None or not Path(F).exists():
|
|
169
|
+
itkdb_gtk.dbGtkUtils.complain("Could not find Output folder", F, parent=self)
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
self.folder = F
|
|
173
|
+
self.options.folder = F
|
|
174
|
+
|
|
175
|
+
def on_SN_changed(self, entry, value):
|
|
176
|
+
"""New SN given. Ask in PDB,"""
|
|
177
|
+
if len(value) <= 0:
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
obj = itkdb_gtk.ITkDButils.get_DB_component(self.session, value)
|
|
182
|
+
if obj is not None:
|
|
183
|
+
entry.set_text(obj["serialNumber"])
|
|
184
|
+
self.alternativeID = obj["alternativeIdentifier"]
|
|
185
|
+
self.change_to_back(None)
|
|
186
|
+
|
|
187
|
+
else:
|
|
188
|
+
itkdb_gtk.dbGtkUtils.complain("Invalid SN", value)
|
|
189
|
+
|
|
190
|
+
def change_to_back(self, *args):
|
|
191
|
+
"""The front/back switch has changed."""
|
|
192
|
+
is_front = self.back.get_active()
|
|
193
|
+
if self.alternativeID is None:
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
if is_front:
|
|
197
|
+
txt = "{}-front".format(self.alternativeID)
|
|
198
|
+
else:
|
|
199
|
+
txt = "{}-back".format(self.alternativeID)
|
|
200
|
+
|
|
201
|
+
self.prefix.set_text(txt)
|
|
202
|
+
|
|
203
|
+
def check_SN(self, SN):
|
|
204
|
+
"""Checks the serial number."""
|
|
205
|
+
if len(SN) <= 0:
|
|
206
|
+
return None
|
|
207
|
+
|
|
208
|
+
obj = itkdb_gtk.ITkDButils.get_DB_component(self.session, SN)
|
|
209
|
+
if obj is None:
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
if self.alternativeID is None:
|
|
213
|
+
self.alternativeID = obj["alternativeIdentifier"]
|
|
214
|
+
|
|
215
|
+
self.change_to_back(None)
|
|
216
|
+
return obj["serialNumber"]
|
|
217
|
+
|
|
218
|
+
def show_state(self, *arg):
|
|
219
|
+
"""Shows the status"""
|
|
220
|
+
if self.outDB is None:
|
|
221
|
+
dialog = Gtk.MessageDialog(
|
|
222
|
+
transient_for=self,
|
|
223
|
+
flags=0,
|
|
224
|
+
message_type=Gtk.MessageType.INFO,
|
|
225
|
+
buttons=Gtk.ButtonsType.OK,
|
|
226
|
+
text="State undefined",
|
|
227
|
+
)
|
|
228
|
+
dialog.format_secondary_text(
|
|
229
|
+
"No analysis data available yet."
|
|
230
|
+
)
|
|
231
|
+
dialog.run()
|
|
232
|
+
dialog.destroy()
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
ndef = len(self.outDB["defects"])
|
|
236
|
+
ncomm = len(self.outDB["comments"])
|
|
237
|
+
|
|
238
|
+
if ndef+ncomm == 0:
|
|
239
|
+
dialog = Gtk.MessageDialog(
|
|
240
|
+
transient_for=self,
|
|
241
|
+
flags=0,
|
|
242
|
+
message_type=Gtk.MessageType.INFO,
|
|
243
|
+
buttons=Gtk.ButtonsType.OK,
|
|
244
|
+
text="All good",
|
|
245
|
+
)
|
|
246
|
+
dialog.format_secondary_text(
|
|
247
|
+
"Petal core passed without problems."
|
|
248
|
+
)
|
|
249
|
+
dialog.run()
|
|
250
|
+
dialog.destroy()
|
|
251
|
+
return
|
|
252
|
+
|
|
253
|
+
msg = ""
|
|
254
|
+
if ndef:
|
|
255
|
+
msg += "Defects\n"
|
|
256
|
+
for D in self.outDB["defects"]:
|
|
257
|
+
msg += "{}: {}\n".format(D["name"], D["description"])
|
|
258
|
+
|
|
259
|
+
if ncomm:
|
|
260
|
+
msg += "Comments\n"
|
|
261
|
+
for C in self.outDB["comments"]:
|
|
262
|
+
msg += "{}\n".format(C)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
dialog = Gtk.MessageDialog(
|
|
266
|
+
transient_for=self,
|
|
267
|
+
flags=0,
|
|
268
|
+
message_type=Gtk.MessageType.INFO,
|
|
269
|
+
buttons=Gtk.ButtonsType.OK,
|
|
270
|
+
text="Problems found",
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
dialog.format_secondary_text(msg)
|
|
274
|
+
dialog.run()
|
|
275
|
+
dialog.destroy()
|
|
276
|
+
|
|
277
|
+
def run_analysis(self, *args):
|
|
278
|
+
"""Run metrology."""
|
|
279
|
+
if self.data_file is None:
|
|
280
|
+
itkdb_gtk.dbGtkUtils.complain("No data file set", "Select one", parent=self)
|
|
281
|
+
return
|
|
282
|
+
|
|
283
|
+
if self.desy.get_active():
|
|
284
|
+
self.options.desy = True
|
|
285
|
+
|
|
286
|
+
is_front = self.back.get_active()
|
|
287
|
+
suffix = "back"
|
|
288
|
+
if is_front:
|
|
289
|
+
suffix = "front"
|
|
290
|
+
|
|
291
|
+
self.petal_prefix = self.prefix.get_text().strip()
|
|
292
|
+
if len(self.petal_prefix) == 0:
|
|
293
|
+
self.petal_prefix = "{}-{}".format(self.alternativeID, suffix)
|
|
294
|
+
self.prefix.set_text(self.petal_prefix)
|
|
295
|
+
|
|
296
|
+
self.petal_SN = self.SN.get_text().strip()
|
|
297
|
+
if len(self.petal_SN) == 0 or self.petal_SN is None:
|
|
298
|
+
itkdb_gtk.dbGtkUtils.complain("Invalid SN", "SN: {}".format(self.petal_SN), parent=self)
|
|
299
|
+
return
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
with redirect_stdout(self.message_panel):
|
|
303
|
+
self.outDB = do_analysis(self.data_file, self.petal_prefix, self.petal_SN, self.options)
|
|
304
|
+
|
|
305
|
+
if len(self.outDB["defects"]) > 0:
|
|
306
|
+
itkdb_gtk.dbGtkUtils.set_button_color(self.btn_state, "red", "white")
|
|
307
|
+
self.btn_state.set_label("FAILED")
|
|
308
|
+
elif len(self.outDB["comments"]) > 0:
|
|
309
|
+
itkdb_gtk.dbGtkUtils.set_button_color(self.btn_state, "orange", "white")
|
|
310
|
+
self.btn_state.set_label("PROBLEMS")
|
|
311
|
+
else:
|
|
312
|
+
itkdb_gtk.dbGtkUtils.set_button_color(self.btn_state, "green", "white")
|
|
313
|
+
self.btn_state.set_label("PASSED")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def show_test_gui(self, *args):
|
|
317
|
+
"""Show test data."""
|
|
318
|
+
if self.outDB is None:
|
|
319
|
+
return
|
|
320
|
+
|
|
321
|
+
values, rc = itkdb_gtk.dbGtkUtils.DictDialog.create_json_data_editor(self.outDB)
|
|
322
|
+
if rc == Gtk.ResponseType.OK:
|
|
323
|
+
self.outDB = values
|
|
324
|
+
|
|
325
|
+
def upload_test_gui(self, *args):
|
|
326
|
+
"""Uploads test and attachments."""
|
|
327
|
+
self.upload_test()
|
|
328
|
+
|
|
329
|
+
def upload_test(self):
|
|
330
|
+
"""Uploads test and attachments."""
|
|
331
|
+
if self.outDB is None:
|
|
332
|
+
return
|
|
333
|
+
uploadW = itkdb_gtk.UploadTest.UploadTest(self.session, payload=self.outDB)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def main():
|
|
337
|
+
"""Entry point."""
|
|
338
|
+
parser = ArgumentParser()
|
|
339
|
+
parser.add_argument('files', nargs='*', help="Input files")
|
|
340
|
+
parser.add_argument("--prefix", dest='prefix', default=None)
|
|
341
|
+
parser.add_argument("--SN", dest='SN', default=None)
|
|
342
|
+
parser.add_argument("--save", dest='save', action="store_true", default=False)
|
|
343
|
+
parser.add_argument("--desy", dest='desy', action="store_true", default=False)
|
|
344
|
+
parser.add_argument("--out", dest="out", default="petal_flatness.docx",
|
|
345
|
+
type=str, help="The output fiel name")
|
|
346
|
+
parser.add_argument("--bottom-lp", dest='bLP', action=CommaSeparatedListAction, default=None,
|
|
347
|
+
help="Bottom locking point fiducial coordinates")
|
|
348
|
+
parser.add_argument("--upper-lp", dest='uLP', action=CommaSeparatedListAction, default=None,
|
|
349
|
+
help="upper locking point fiducials coordinates")
|
|
350
|
+
|
|
351
|
+
parser.add_argument("--title", dest="title", default=None,
|
|
352
|
+
type=str, help="Document title")
|
|
353
|
+
parser.add_argument("--nbins", dest="nbins", default=25,
|
|
354
|
+
type=int, help="Number of bins")
|
|
355
|
+
parser.add_argument("--folder", default=None, help="Folder to store output files. Superseeds folder in --out")
|
|
356
|
+
parser.add_argument("--locking_points", action="store_true", default=False)
|
|
357
|
+
|
|
358
|
+
# This is to convert a CMM file
|
|
359
|
+
parser.add_argument("--label", default="\\w+", help="The label to select")
|
|
360
|
+
parser.add_argument("--type", default="Punto", help="The class to select")
|
|
361
|
+
|
|
362
|
+
options = parser.parse_args()
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
# ITk PDB authentication
|
|
366
|
+
dlg = None
|
|
367
|
+
try:
|
|
368
|
+
# We use here the Gtk GUI
|
|
369
|
+
from itkdb_gtk import ITkDBlogin
|
|
370
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
371
|
+
client = dlg.get_client()
|
|
372
|
+
|
|
373
|
+
except Exception:
|
|
374
|
+
# Login with "standard" if the above fails.
|
|
375
|
+
import itkdb
|
|
376
|
+
import getpass
|
|
377
|
+
client = itkdb.Client()
|
|
378
|
+
client.user._access_code1 = getpass.getpass("Access 1: ")
|
|
379
|
+
client.user._access_code2 = getpass.getpass("Access 2: ")
|
|
380
|
+
client.user.authenticate()
|
|
381
|
+
print("Hello {} !".format(client.user.name))
|
|
382
|
+
|
|
383
|
+
CM = CoreMetrology(options, session=client, title="Petal core metrology")
|
|
384
|
+
CM.write_message("Welcome !\n")
|
|
385
|
+
CM.connect("destroy", Gtk.main_quit)
|
|
386
|
+
|
|
387
|
+
CM.show_all()
|
|
388
|
+
try:
|
|
389
|
+
Gtk.main()
|
|
390
|
+
|
|
391
|
+
except KeyboardInterrupt:
|
|
392
|
+
print("Arrrgggg!!!")
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
try:
|
|
396
|
+
dlg.die()
|
|
397
|
+
|
|
398
|
+
except Exception:
|
|
399
|
+
print("Bye !")
|
|
400
|
+
|
|
401
|
+
if __name__ == "__main__":
|
|
402
|
+
main()
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Convert IFIC raw data to CVS."""
|
|
3
|
+
import io
|
|
4
|
+
from metrology.convert_mitutoyo import mitutoyo2cvs
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
def data2cvs(ifile, options):
|
|
9
|
+
"""Read CMM file and convert to CSV.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
ifile: Input file path
|
|
13
|
+
options: Program options
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
ofiles = []
|
|
17
|
+
odata = io.StringIO()
|
|
18
|
+
mitutoyo2cvs(ifile, odata, r"Punto[-|Vision-]\w", "Punto")
|
|
19
|
+
|
|
20
|
+
outfile = "{}-petal.csv".format(options.prefix)
|
|
21
|
+
with open(outfile, mode='w') as f:
|
|
22
|
+
f.write(odata.getvalue())
|
|
23
|
+
|
|
24
|
+
ofiles.append(outfile)
|
|
25
|
+
|
|
26
|
+
odata = io.StringIO()
|
|
27
|
+
mitutoyo2cvs(ifile, odata, "PuntoLocator", "Punto")
|
|
28
|
+
|
|
29
|
+
outfile = "{}-locators.csv".format(options.prefix)
|
|
30
|
+
with open(outfile, mode='w') as f:
|
|
31
|
+
f.write(odata.getvalue())
|
|
32
|
+
|
|
33
|
+
ofiles.append(outfile)
|
|
34
|
+
return ofiles
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
import argparse
|
|
38
|
+
import sys
|
|
39
|
+
|
|
40
|
+
parser = argparse.ArgumentParser()
|
|
41
|
+
parser.add_argument('files', nargs='*', help="Input files")
|
|
42
|
+
parser.add_argument("--prefix", default="out", help="Output file")
|
|
43
|
+
parser.add_argument("--show", action="store_true", default=False)
|
|
44
|
+
|
|
45
|
+
options = parser.parse_args()
|
|
46
|
+
if len(options.files) == 0:
|
|
47
|
+
print(sys.argv[0])
|
|
48
|
+
print("I need an input file")
|
|
49
|
+
sys.exit()
|
|
50
|
+
|
|
51
|
+
ofiles = data2cvs(options.files, options)
|
|
52
|
+
|
|
53
|
+
if options.show:
|
|
54
|
+
for outfile in ofiles:
|
|
55
|
+
x, y, z = np.loadtxt(outfile, unpack=True, skiprows=1, delimiter=',')
|
|
56
|
+
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
|
|
57
|
+
surf = ax.scatter(x, y, z, c=z, marker='.', cmap=plt.cm.jet)
|
|
58
|
+
ax.set_xlabel("X")
|
|
59
|
+
ax.set_ylabel("Y")
|
|
60
|
+
ax.set_zlabel("Z")
|
|
61
|
+
fig.colorbar(surf, shrink=0.5, aspect=5, location="left")
|
|
62
|
+
|
|
63
|
+
plt.show()
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Does metrology of all files listed at input file.
|
|
3
|
+
|
|
4
|
+
Examples:
|
|
5
|
+
|
|
6
|
+
python3 ~/cernbox/workspace/Petal-QC/do_Metrology.py ~/Desktop/petal-metrology-files.txt
|
|
7
|
+
python3 ~/cernbox/workspace/Petal-QC/do_Metrology.py --desy ~/Desktop/DESY-petal-metrology.txt
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
import json
|
|
11
|
+
import sys
|
|
12
|
+
import traceback
|
|
13
|
+
from argparse import Action
|
|
14
|
+
from argparse import ArgumentParser
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
import numpy as np
|
|
17
|
+
from petal_qc.utils.utils import output_folder
|
|
18
|
+
|
|
19
|
+
from petal_qc.metrology.PetalMetrology import petal_metrology
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CommaSeparatedListAction(Action):
|
|
23
|
+
"""Create a list from the comma sepparated numbers at imput."""
|
|
24
|
+
|
|
25
|
+
def __call__(self, parser, namespace, values, option_string=None):
|
|
26
|
+
"""The actual action."""
|
|
27
|
+
value = np.array(list(map(float, values.split(','))), dtype='float64')
|
|
28
|
+
if value.shape[0] < 3:
|
|
29
|
+
raise Exception("{} needs a 3D vector".format(self.dest))
|
|
30
|
+
|
|
31
|
+
setattr(namespace, self.dest, value)
|
|
32
|
+
|
|
33
|
+
def do_analysis(fnam, prefix, SN, options):
|
|
34
|
+
"""Perform analysis of a file.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
fnam (): Input data file
|
|
38
|
+
prefix (): Prefix telling if it is front or back
|
|
39
|
+
SN (): Core serial number
|
|
40
|
+
options (): Options.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
is_front = prefix.lower().find("front") >= 0
|
|
45
|
+
print(fnam, prefix)
|
|
46
|
+
options.out = prefix + '.docx'
|
|
47
|
+
options.title = prefix
|
|
48
|
+
options.is_front = is_front
|
|
49
|
+
if not hasattr(options, "SN"):
|
|
50
|
+
options.SN = ""
|
|
51
|
+
|
|
52
|
+
options.SN = SN
|
|
53
|
+
outDB = petal_metrology(fnam, options)
|
|
54
|
+
|
|
55
|
+
ofile = output_folder(options.folder, prefix + '.json')
|
|
56
|
+
with open(ofile, 'w', encoding='UTF-8') as of:
|
|
57
|
+
json.dump(outDB, of, indent=3)
|
|
58
|
+
|
|
59
|
+
return outDB
|
|
60
|
+
|
|
61
|
+
def main(ifile, options):
|
|
62
|
+
"""Main entry."""
|
|
63
|
+
with open(ifile, 'r', encoding='UTF-8') as inp:
|
|
64
|
+
|
|
65
|
+
for line in inp:
|
|
66
|
+
line = line.strip()
|
|
67
|
+
if len(line) == 0:
|
|
68
|
+
continue
|
|
69
|
+
|
|
70
|
+
if line[0] == '#':
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
SN = ""
|
|
74
|
+
try:
|
|
75
|
+
fnam, prefix = line.split()
|
|
76
|
+
except Exception:
|
|
77
|
+
fnam, prefix, SN, *_ = line.split()
|
|
78
|
+
|
|
79
|
+
do_analysis(fnam, prefix, SN, options)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
if __name__ == "__main__":
|
|
83
|
+
parser = ArgumentParser()
|
|
84
|
+
parser.add_argument('files', nargs='*', help="Input files")
|
|
85
|
+
parser.add_argument("--prefix", dest='prefix', default=None)
|
|
86
|
+
parser.add_argument("--SN", dest='SN', default=None)
|
|
87
|
+
parser.add_argument("--save", dest='save', action="store_true", default=False)
|
|
88
|
+
parser.add_argument("--desy", dest='desy', action="store_true", default=False)
|
|
89
|
+
parser.add_argument("--out", dest="out", default="petal_flatness.docx",
|
|
90
|
+
type=str, help="The output fiel name")
|
|
91
|
+
parser.add_argument("--bottom-lp", dest='bLP', action=CommaSeparatedListAction, default=None,
|
|
92
|
+
help="Bottom locking point fiducial coordinates")
|
|
93
|
+
parser.add_argument("--upper-lp", dest='uLP', action=CommaSeparatedListAction, default=None,
|
|
94
|
+
help="upper locking point fiducials coordinates")
|
|
95
|
+
|
|
96
|
+
parser.add_argument("--title", dest="title", default=None,
|
|
97
|
+
type=str, help="Document title")
|
|
98
|
+
parser.add_argument("--nbins", dest="nbins", default=25,
|
|
99
|
+
type=int, help="Number of bins")
|
|
100
|
+
parser.add_argument("--folder", default=None, help="Folder to store output files. Superseeds folder in --out")
|
|
101
|
+
parser.add_argument("--locking_points", action="store_true", default=False)
|
|
102
|
+
|
|
103
|
+
# This is to convert a CMM file
|
|
104
|
+
parser.add_argument("--label", default="\\w+", help="The label to select")
|
|
105
|
+
parser.add_argument("--type", default="Punto", help="The class to select")
|
|
106
|
+
|
|
107
|
+
options = parser.parse_args()
|
|
108
|
+
if len(options.files) == 0:
|
|
109
|
+
print(sys.argv[0])
|
|
110
|
+
print("I need an input file")
|
|
111
|
+
sys.exit()
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
main(options.files[0], options)
|
|
115
|
+
|
|
116
|
+
except Exception:
|
|
117
|
+
print(traceback.format_exc())
|