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
|
@@ -32,27 +32,27 @@ def save_figure(fig, fnam, prefix=None, dpi=192):
|
|
|
32
32
|
name = prefix + P.name
|
|
33
33
|
out = P.parent / name
|
|
34
34
|
fnam = out
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
print("out: {}".format(fnam))
|
|
37
37
|
fig.savefig(fnam, dpi=dpi)
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
|
|
40
40
|
def read_data_files(options):
|
|
41
41
|
"""Read the data files.
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
It assumes the data file names are in the format:
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
<AlternativeID>-<side>.json
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
AlternativeID is PPC.nnn side is either front or back.
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
Returns the values for front and back petal tests.
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
The results are a dictionary with the file label as key and the requested
|
|
52
|
-
value, which can be a number of an array.
|
|
53
|
-
|
|
52
|
+
value, which can be a number of an array.
|
|
53
|
+
|
|
54
54
|
the file labels are also returned.
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
"""
|
|
57
57
|
labels = []
|
|
58
58
|
front = {}
|
|
@@ -60,7 +60,6 @@ def read_data_files(options):
|
|
|
60
60
|
|
|
61
61
|
for fnam in options.files:
|
|
62
62
|
ifile = Path(fnam).expanduser().resolve()
|
|
63
|
-
print(ifile.name)
|
|
64
63
|
if not ifile.exists():
|
|
65
64
|
print("File does not exist: ", fnam)
|
|
66
65
|
continue
|
|
@@ -83,9 +82,9 @@ def read_data_files(options):
|
|
|
83
82
|
front[label] = val
|
|
84
83
|
else:
|
|
85
84
|
back[label] = val
|
|
86
|
-
|
|
85
|
+
|
|
87
86
|
labels.sort()
|
|
88
|
-
|
|
87
|
+
|
|
89
88
|
return front, back, labels
|
|
90
89
|
|
|
91
90
|
def draw_deltas(data, keys, fnam=None, title="Front"):
|
|
@@ -97,12 +96,12 @@ def draw_deltas(data, keys, fnam=None, title="Front"):
|
|
|
97
96
|
P = [np.zeros([nfiles, 2]),
|
|
98
97
|
np.zeros([nfiles, 2]),
|
|
99
98
|
np.zeros([nfiles, 2])]
|
|
100
|
-
|
|
101
99
|
fig_width = 12.0
|
|
102
100
|
fig_height = 1.2*fig_width/3.0
|
|
103
101
|
fig, ax = plt.subplots(nrows=1, ncols=3, tight_layout=True, figsize=(fig_width, fig_height))
|
|
104
102
|
fig.suptitle(title)
|
|
105
103
|
for i in range(3):
|
|
104
|
+
LBL = [[],[],[]]
|
|
106
105
|
ax[i].set_title(keys[i])
|
|
107
106
|
ax[i].set_aspect('equal', adjustable='box')
|
|
108
107
|
ax[i].set_xlim(-100, 100)
|
|
@@ -121,15 +120,18 @@ def draw_deltas(data, keys, fnam=None, title="Front"):
|
|
|
121
120
|
for k in range(3):
|
|
122
121
|
ky = key_table[keys[k]]
|
|
123
122
|
P[k][j, :] = 1000*np.array(values[ky])
|
|
123
|
+
LBL[k].append(label.split('.')[1].lstrip('0'))
|
|
124
124
|
|
|
125
125
|
ax[i].scatter(P[i][:,0], P[i][:,1])
|
|
126
|
+
for j in range(len(LBL[i])):
|
|
127
|
+
ax[i].text(P[i][j,0], P[i][j,1], LBL[i][j]) #, ha='center', va='top')
|
|
126
128
|
|
|
127
129
|
save_figure(fig, fnam, prefix=title)
|
|
128
130
|
|
|
129
131
|
|
|
130
132
|
def show_positions(options):
|
|
131
133
|
"""Make position plots."""
|
|
132
|
-
|
|
134
|
+
|
|
133
135
|
if "LOCATION" in options.value:
|
|
134
136
|
keys = ["Bot.", "Slot", "Top"]
|
|
135
137
|
elif "REL_POS" in options.value:
|
|
@@ -154,58 +156,58 @@ def show_flatness(options):
|
|
|
154
156
|
nfiles = len(labels)
|
|
155
157
|
npts = len(tick_labels)
|
|
156
158
|
X = np.array([float(x) for x in range(npts)])
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
|
|
160
|
+
|
|
159
161
|
fig, ax = plt.subplots(nrows=1, ncols=2, tight_layout=True, figsize=(9., 5.))
|
|
160
162
|
fig.suptitle(options.value)
|
|
161
|
-
|
|
163
|
+
|
|
162
164
|
P = [ np.zeros([nfiles, npts]), np.zeros([nfiles, npts]) ]
|
|
163
165
|
y_lim = []
|
|
164
166
|
for i, V in enumerate([front, back]):
|
|
165
167
|
ax[i].set_title(cindx[i])
|
|
166
168
|
ax[i].set_xticks(range(npts), labels=tick_labels)
|
|
167
169
|
ax[i].grid()
|
|
168
|
-
|
|
170
|
+
|
|
169
171
|
for lbl in labels:
|
|
170
172
|
ax[i].plot(X, V[lbl], '-', label=lbl)
|
|
171
|
-
|
|
173
|
+
|
|
172
174
|
y_lim.append(ax[i].get_ylim())
|
|
173
|
-
|
|
175
|
+
|
|
174
176
|
for a in ax:
|
|
175
177
|
a.set_ylim(0, 1.2*max(y_lim[0][1], y_lim[1][1]))
|
|
178
|
+
x_lim = a.get_xlim()
|
|
179
|
+
a.fill_between(x_lim, 0, 0.050, facecolor="darkseagreen", alpha=0.1)
|
|
176
180
|
a.legend(ncol=3, fontsize="x-small")
|
|
177
|
-
|
|
178
|
-
save_figure(fig, options.out, prefix=
|
|
181
|
+
|
|
182
|
+
save_figure(fig, options.out, prefix=opts.prefix)
|
|
179
183
|
|
|
180
184
|
def main(options):
|
|
181
185
|
"""Main entry."""
|
|
182
|
-
|
|
186
|
+
|
|
183
187
|
if "LOCATION" in options.value or "REL_POS" in options.value:
|
|
184
188
|
show_positions(options)
|
|
185
|
-
return
|
|
186
189
|
|
|
187
|
-
|
|
190
|
+
elif "FLATNESS_LOCAL" in options.value:
|
|
188
191
|
show_flatness(options)
|
|
189
|
-
return
|
|
190
192
|
|
|
193
|
+
else:
|
|
194
|
+
front, back, labels = read_data_files(options)
|
|
191
195
|
|
|
192
|
-
|
|
196
|
+
labels.sort()
|
|
197
|
+
X = np.arange(0, len(labels))
|
|
198
|
+
fig, ax = plt.subplots(1, 1, tight_layout=True)
|
|
199
|
+
fig.suptitle(options.value)
|
|
200
|
+
ax.set_xticks(range(len(labels)), labels=labels, rotation="vertical")
|
|
201
|
+
ax.grid()
|
|
193
202
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
ax.grid()
|
|
203
|
+
vfront = [front[x] for x in labels]
|
|
204
|
+
vback = [back[x] for x in labels]
|
|
205
|
+
ax.plot(X, vfront, '*', label="Front")
|
|
206
|
+
ax.plot(X, vback, 'o', label="Back")
|
|
207
|
+
ax.legend()
|
|
200
208
|
|
|
201
|
-
|
|
202
|
-
vback = [back[x] for x in labels]
|
|
203
|
-
ax.plot(X, vfront, '*', label="Front")
|
|
204
|
-
ax.plot(X, vback, 'o', label="Back")
|
|
205
|
-
ax.legend()
|
|
209
|
+
save_figure(fig, options.out, prefix=options.prefix)
|
|
206
210
|
|
|
207
|
-
save_figure(fig, options.out)
|
|
208
|
-
|
|
209
211
|
plt.show()
|
|
210
212
|
|
|
211
213
|
|
|
@@ -214,6 +216,7 @@ if __name__ == "__main__":
|
|
|
214
216
|
parser = argparse.ArgumentParser()
|
|
215
217
|
parser.add_argument('files', nargs='*', help="Input files")
|
|
216
218
|
parser.add_argument("--value", default=None, help="Value to plot")
|
|
219
|
+
parser.add_argument("--prefix", default=None, help="prefix for out file")
|
|
217
220
|
parser.add_argument("--out", default=None, help="File to store the figure.")
|
|
218
221
|
|
|
219
222
|
opts = parser.parse_args()
|
|
@@ -221,7 +224,7 @@ if __name__ == "__main__":
|
|
|
221
224
|
print("I need at least one input file")
|
|
222
225
|
sys.exit()
|
|
223
226
|
|
|
224
|
-
|
|
227
|
+
elif len(opts.files) == 1:
|
|
225
228
|
xxx = any(elem in opts.files[0] for elem in r"*?")
|
|
226
229
|
if xxx:
|
|
227
230
|
opts.files = glob.glob(opts.files[0])
|
|
@@ -10,15 +10,15 @@ import matplotlib.pyplot as plt
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
from petal_qc.metrology import DataFile
|
|
13
|
-
from .analyze_locking_points import analyze_locking_point_data
|
|
13
|
+
#from .analyze_locking_points import analyze_locking_point_data
|
|
14
14
|
|
|
15
15
|
def get_data_chunck(flist, data_type, ofile):
|
|
16
16
|
"""Get one data type chunk from file
|
|
17
17
|
|
|
18
18
|
Args:
|
|
19
|
-
fname
|
|
20
|
-
data_tyle
|
|
21
|
-
ofile
|
|
19
|
+
fname: input file
|
|
20
|
+
data_tyle: data type
|
|
21
|
+
ofile: file object for output.
|
|
22
22
|
|
|
23
23
|
"""
|
|
24
24
|
rgx = "Step Name:\\s+({}).*?=".format(data_type)
|
|
@@ -41,7 +41,7 @@ def get_data_chunck(flist, data_type, ofile):
|
|
|
41
41
|
ofile.write(txt.group(0)+'\n')
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def read_smartscope(fnam, ofile, data_type, keep=False
|
|
44
|
+
def read_smartscope(fnam, ofile, data_type, keep=False):
|
|
45
45
|
"""Convert a SmartScope txt file into CVS
|
|
46
46
|
|
|
47
47
|
Args:
|
|
@@ -58,7 +58,11 @@ def read_smartscope(fnam, ofile, data_type, keep=False,):
|
|
|
58
58
|
if isinstance(ofile, io.IOBase):
|
|
59
59
|
fout = ofile
|
|
60
60
|
else:
|
|
61
|
-
|
|
61
|
+
try:
|
|
62
|
+
fout = open(ofile, 'w', encoding="utf-8")
|
|
63
|
+
except TypeError:
|
|
64
|
+
fout = ofile
|
|
65
|
+
|
|
62
66
|
is_file = True
|
|
63
67
|
|
|
64
68
|
if keep:
|
|
@@ -106,7 +110,84 @@ def read_smartscope(fnam, ofile, data_type, keep=False,):
|
|
|
106
110
|
values = [ float(x) for x in items[2:5]]
|
|
107
111
|
fout.write("{:6f}, {:6f}, {:6f}\n".format(values[1], values[0], values[2]))
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
if is_file:
|
|
114
|
+
fout.close()
|
|
115
|
+
|
|
116
|
+
def get_smarscope_locator_positions(fnam, ofile, data_type, keep=False):
|
|
117
|
+
"""REad DESY 2D file.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
fnam: Input file
|
|
121
|
+
ofile: Output file
|
|
122
|
+
data_type: Label to search
|
|
123
|
+
keep (bool, optional): If tre keep label. Defaults to False.
|
|
124
|
+
"""
|
|
125
|
+
ifile = Path(fnam).expanduser().resolve()
|
|
126
|
+
|
|
127
|
+
is_file = False
|
|
128
|
+
if isinstance(ofile, io.IOBase):
|
|
129
|
+
fout = ofile
|
|
130
|
+
else:
|
|
131
|
+
try:
|
|
132
|
+
fout = open(ofile, 'w', encoding="utf-8")
|
|
133
|
+
except TypeError:
|
|
134
|
+
fout = ofile
|
|
135
|
+
|
|
136
|
+
is_file = True
|
|
137
|
+
|
|
138
|
+
if keep:
|
|
139
|
+
fout.write("X,Y,Z, label\n")
|
|
140
|
+
else:
|
|
141
|
+
fout.write("X,Y,Z\n")
|
|
142
|
+
|
|
143
|
+
rgx = "^Step Name:\\s+(?P<label>{})".format(data_type)
|
|
144
|
+
start = re.compile(rgx, re.DOTALL)
|
|
145
|
+
finder = re.compile("^Finder Name")
|
|
146
|
+
|
|
147
|
+
out = {}
|
|
148
|
+
with open(ifile, 'r', encoding='ISO-8859-1') as fin:
|
|
149
|
+
while True:
|
|
150
|
+
line = fin.readline()
|
|
151
|
+
if not line:
|
|
152
|
+
break
|
|
153
|
+
|
|
154
|
+
r = start.match(line)
|
|
155
|
+
if not r:
|
|
156
|
+
continue
|
|
157
|
+
|
|
158
|
+
label = r.group('label').strip()
|
|
159
|
+
eof = False
|
|
160
|
+
out[label] = [0. for i in range(3)]
|
|
161
|
+
for i in range(3):
|
|
162
|
+
line = fin.readline()
|
|
163
|
+
|
|
164
|
+
while True:
|
|
165
|
+
line = fin.readline().strip()
|
|
166
|
+
if len(line)==0:
|
|
167
|
+
break
|
|
168
|
+
|
|
169
|
+
values = line.split()
|
|
170
|
+
val = float(values[3])
|
|
171
|
+
if values[0] in ["Diame", "Width"]:
|
|
172
|
+
out[label][2] = val
|
|
173
|
+
elif values[0] == "X":
|
|
174
|
+
out[label][1] = val
|
|
175
|
+
elif values[0] == "Y":
|
|
176
|
+
out[label][0] = val
|
|
177
|
+
|
|
178
|
+
lbls = ["BottomPL", "SlotPL", "OversizedPL", "Bottom_Fiducial", "Slot_Fiducial"]
|
|
179
|
+
for L in lbls:
|
|
180
|
+
try:
|
|
181
|
+
V = [float(x) for x in out[L]]
|
|
182
|
+
fout.write("{:.6f}, {:.6f}, {:.6f}".format(V[0], V[1], V[2]))
|
|
183
|
+
if keep:
|
|
184
|
+
fout.write(", {}".format(L))
|
|
185
|
+
fout.write('\n')
|
|
186
|
+
except KeyError:
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
if is_file:
|
|
190
|
+
fout.close()
|
|
110
191
|
|
|
111
192
|
def do_locking_points(args):
|
|
112
193
|
ifile = args.smartscope_files[0]
|
|
@@ -120,14 +201,14 @@ if __name__ == "__main__":
|
|
|
120
201
|
import argparse
|
|
121
202
|
|
|
122
203
|
parser = argparse.ArgumentParser()
|
|
123
|
-
parser.add_argument("
|
|
204
|
+
parser.add_argument("files", nargs='*',
|
|
124
205
|
help="The SmartScope files to parse")
|
|
125
206
|
parser.add_argument("--label", default="\\w+", help="The label to select")
|
|
126
207
|
parser.add_argument("--out", help="Output CSV file", default="out.csv")
|
|
127
208
|
parser.add_argument("--keep_label", dest="keep", default=False, action="store_true", help="Store label in output")
|
|
128
209
|
|
|
129
210
|
args = parser.parse_args()
|
|
130
|
-
if len(args.
|
|
211
|
+
if len(args.files) == 0:
|
|
131
212
|
print("I need an input file")
|
|
132
213
|
sys.exit()
|
|
133
214
|
|
|
@@ -135,11 +216,13 @@ if __name__ == "__main__":
|
|
|
135
216
|
|
|
136
217
|
# do_locking_points(args)
|
|
137
218
|
|
|
138
|
-
fout = open(Path(args.out).expanduser().resolve(), 'w')
|
|
139
|
-
get_data_chunck(args.smartscope_files, args.label, fout)
|
|
140
|
-
fout.close()
|
|
219
|
+
#fout = open(Path(args.out).expanduser().resolve(), 'w')
|
|
220
|
+
#get_data_chunck(args.smartscope_files, args.label, fout)
|
|
221
|
+
#fout.close()
|
|
141
222
|
|
|
142
223
|
|
|
143
224
|
#read_smartscope(args.smartscope_files[0], args.out, args.label, args.keep)
|
|
144
225
|
|
|
226
|
+
get_smarscope_locator_positions(args.files[0], args.out, args.label)
|
|
227
|
+
|
|
145
228
|
plt.show()
|
|
@@ -16,7 +16,7 @@ import gi
|
|
|
16
16
|
gi.require_version("Gtk", "3.0")
|
|
17
17
|
from gi.repository import Gtk, GObject, Gio, GLib
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
__HELP__ = "https://petal-qc.docs.cern.ch"
|
|
20
20
|
|
|
21
21
|
class CommaSeparatedListAction(Action):
|
|
22
22
|
"""Create a list from the comma sepparated numbers at imput."""
|
|
@@ -25,7 +25,7 @@ class CommaSeparatedListAction(Action):
|
|
|
25
25
|
"""The actual action."""
|
|
26
26
|
value = np.array(list(map(float, values.split(','))), dtype='float64')
|
|
27
27
|
if value.shape[0] < 3:
|
|
28
|
-
raise
|
|
28
|
+
raise ValueError("{} needs a 3D vector".format(self.dest))
|
|
29
29
|
|
|
30
30
|
setattr(namespace, self.dest, value)
|
|
31
31
|
|
|
@@ -41,7 +41,7 @@ class CoreMetrology(itkdb_gtk.dbGtkUtils.ITkDBWindow):
|
|
|
41
41
|
pannel_size: size of message panel.
|
|
42
42
|
|
|
43
43
|
"""
|
|
44
|
-
super().__init__(session=session, title=title)
|
|
44
|
+
super().__init__(session=session, title=title, help=__HELP__)
|
|
45
45
|
|
|
46
46
|
self.data_file = None
|
|
47
47
|
self.folder = None
|
|
@@ -42,13 +42,13 @@ def do_analysis(fnam, prefix, SN, options):
|
|
|
42
42
|
"""Perform analysis of a file.
|
|
43
43
|
|
|
44
44
|
Args:
|
|
45
|
-
fnam
|
|
46
|
-
prefix
|
|
47
|
-
SN
|
|
48
|
-
options
|
|
49
|
-
|
|
45
|
+
fnam: Input data file
|
|
46
|
+
prefix: Prefix telling if it is front or back
|
|
47
|
+
SN: Core serial number
|
|
48
|
+
options: Options.
|
|
49
|
+
|
|
50
50
|
"""
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
is_front = prefix.lower().find("front") >= 0
|
|
53
53
|
print(fnam, prefix)
|
|
54
54
|
options.out = prefix + '.docx'
|
|
@@ -63,10 +63,10 @@ def do_analysis(fnam, prefix, SN, options):
|
|
|
63
63
|
ofile = output_folder(options.folder, prefix + '.json')
|
|
64
64
|
with open(ofile, 'w', encoding='UTF-8') as of:
|
|
65
65
|
json.dump(outDB, of, indent=3)
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
return outDB
|
|
68
68
|
|
|
69
|
-
def
|
|
69
|
+
def analyze_files(ifile, options):
|
|
70
70
|
"""Main entry."""
|
|
71
71
|
with open(ifile, 'r', encoding='UTF-8') as inp:
|
|
72
72
|
|
|
@@ -86,25 +86,25 @@ def main(ifile, options):
|
|
|
86
86
|
|
|
87
87
|
do_analysis(fnam, prefix, SN, options)
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
def main():
|
|
90
|
+
"Main entry."
|
|
91
91
|
parser = ArgumentParser()
|
|
92
92
|
parser.add_argument('files', nargs='*', help="Input files")
|
|
93
|
-
parser.add_argument("--prefix", dest='prefix', default=None)
|
|
94
|
-
parser.add_argument("--SN", dest='SN', default=None)
|
|
93
|
+
parser.add_argument("--prefix", dest='prefix', default=None, help="prefix telling if it is front or back.")
|
|
94
|
+
parser.add_argument("--SN", dest='SN', default=None, help="The petal core Serial Number")
|
|
95
95
|
parser.add_argument("--save", dest='save', action="store_true", default=False)
|
|
96
|
-
parser.add_argument("--desy", dest='desy', action="store_true", default=False)
|
|
96
|
+
parser.add_argument("--desy", dest='desy', action="store_true", default=False, help="True if data is from DESY's SmartScope")
|
|
97
97
|
parser.add_argument("--out", dest="out", default="petal_flatness.docx",
|
|
98
|
-
type=str, help="The output
|
|
98
|
+
type=str, help="The output file name")
|
|
99
99
|
parser.add_argument("--bottom-lp", dest='bLP', action=CommaSeparatedListAction, default=None,
|
|
100
100
|
help="Bottom locking point fiducial coordinates")
|
|
101
101
|
parser.add_argument("--upper-lp", dest='uLP', action=CommaSeparatedListAction, default=None,
|
|
102
102
|
help="upper locking point fiducials coordinates")
|
|
103
103
|
|
|
104
104
|
parser.add_argument("--title", dest="title", default=None,
|
|
105
|
-
type=str, help="Document title")
|
|
105
|
+
type=str, help="Report Document title")
|
|
106
106
|
parser.add_argument("--nbins", dest="nbins", default=25,
|
|
107
|
-
type=int, help="Number of bins")
|
|
107
|
+
type=int, help="Number of bins in the histograms")
|
|
108
108
|
parser.add_argument("--folder", default=None, help="Folder to store output files. Superseeds folder in --out")
|
|
109
109
|
parser.add_argument("--locking_points", action="store_true", default=False)
|
|
110
110
|
|
|
@@ -119,7 +119,10 @@ if __name__ == "__main__":
|
|
|
119
119
|
sys.exit()
|
|
120
120
|
|
|
121
121
|
try:
|
|
122
|
-
|
|
122
|
+
analyze_files(options.files[0], options)
|
|
123
123
|
|
|
124
124
|
except Exception:
|
|
125
125
|
print(traceback.format_exc())
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
main()
|
|
@@ -218,7 +218,7 @@ def petal_flatness(orig_data, options, document=None):
|
|
|
218
218
|
# add allsensor area
|
|
219
219
|
cell = table.add_row().cells
|
|
220
220
|
cell[0].text = "All sensor area"
|
|
221
|
-
cell[1].text = "{:.4f}".format(flatness_all_sensor_area)
|
|
221
|
+
cell[1].text = "{:.4f}".format(flatness_all_sensor_area*1000)
|
|
222
222
|
|
|
223
223
|
return TM, avg, Zmean, outF
|
|
224
224
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Prepara input files from DESY RAW."""
|
|
3
|
+
import os
|
|
4
|
+
import fnmatch
|
|
5
|
+
import re
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
def all_files(root, patterns='*', single_level=False, yield_folders=False):
|
|
9
|
+
"""A generator that reruns all files in the given folder.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
----
|
|
13
|
+
root (file path): The folder
|
|
14
|
+
patterns (str, optional): The pattern of the files. Defaults to '*'.
|
|
15
|
+
single_level (bool, optional): If true, do not go into sub folders. Defaults to False.
|
|
16
|
+
yield_folders (bool, optional): If True, return folders as well. Defaults to False.
|
|
17
|
+
|
|
18
|
+
Yields
|
|
19
|
+
------
|
|
20
|
+
str: file path name
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
patterns = patterns.split(';')
|
|
24
|
+
for path, subdirs, files in os.walk(root):
|
|
25
|
+
if yield_folders:
|
|
26
|
+
files.extend(subdirs)
|
|
27
|
+
|
|
28
|
+
files.sort()
|
|
29
|
+
for name in files:
|
|
30
|
+
for pattern in patterns:
|
|
31
|
+
if fnmatch.fnmatch(name, pattern):
|
|
32
|
+
yield os.path.join(path, name)
|
|
33
|
+
break
|
|
34
|
+
|
|
35
|
+
if single_level:
|
|
36
|
+
break
|
|
37
|
+
|
|
38
|
+
class PetalCore:
|
|
39
|
+
def __init__(self, front, back):
|
|
40
|
+
self.front = {}
|
|
41
|
+
self.back = {}
|
|
42
|
+
|
|
43
|
+
def main(folder, out_folder):
|
|
44
|
+
"""Main entry point."""
|
|
45
|
+
outF = Path(out_folder).expanduser().resolve()
|
|
46
|
+
if not outF.exists():
|
|
47
|
+
os.mkdir(outF)
|
|
48
|
+
|
|
49
|
+
rgx = re.compile(r"Project Name: (\w+)side_.*AlternativeID=PPC-(\d+)", re.MULTILINE|re.DOTALL)
|
|
50
|
+
petal_cores = {}
|
|
51
|
+
for fnam in all_files(folder, "*.txt"):
|
|
52
|
+
P = Path(fnam).expanduser().resolve()
|
|
53
|
+
with open(fnam, "r", encoding="UTF-8") as ff:
|
|
54
|
+
R = rgx.search(ff.read())
|
|
55
|
+
if R:
|
|
56
|
+
petal_id = "PPC.{}".format(R.group(2))
|
|
57
|
+
side = R.group(1).lower()
|
|
58
|
+
if "_2D_" in P.name:
|
|
59
|
+
test_type = "2D"
|
|
60
|
+
else:
|
|
61
|
+
test_type = "3D"
|
|
62
|
+
|
|
63
|
+
if not petal_id in petal_cores:
|
|
64
|
+
petal_cores[petal_id] = {
|
|
65
|
+
"back":{"2D":None, "3D":None},
|
|
66
|
+
"front":{"2D":None, "3D":None},
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
petal_cores[petal_id][side][test_type] = P
|
|
70
|
+
|
|
71
|
+
list_file = open("{}/Desy-cores.txt".format(outF.as_posix()), "w", encoding="UTF-8")
|
|
72
|
+
for petal_id, sides in petal_cores.items():
|
|
73
|
+
for side, values in sides.items():
|
|
74
|
+
oname = "{}/{}-{}.txt".format(outF.as_posix(), petal_id, side)
|
|
75
|
+
list_file.write("{} {}-{} {}\n".format(oname, petal_id, side, petal_id))
|
|
76
|
+
data = ""
|
|
77
|
+
for data_type, fnam in values.items():
|
|
78
|
+
with open(fnam, "r", encoding="UTF-8") as ifile:
|
|
79
|
+
data += ifile.read()
|
|
80
|
+
|
|
81
|
+
with open(oname, "w", encoding="UTF-8") as ofile:
|
|
82
|
+
ofile.write(data)
|
|
83
|
+
|
|
84
|
+
list_file.close()
|
|
85
|
+
if __name__ == "__main__":
|
|
86
|
+
main("/Users/lacasta/Downloads/DESY_Production", "/tmp/desy")
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
6
|
+
import bisect
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
8
9
|
import matplotlib.dates as pldates
|
|
@@ -19,6 +20,14 @@ from petal_qc.thermal import Petal_IR_Analysis
|
|
|
19
20
|
|
|
20
21
|
CO2_Temp_setting = -35
|
|
21
22
|
|
|
23
|
+
def get_array_as_string(A):
|
|
24
|
+
"""Return a string rerpresentation."""
|
|
25
|
+
sss="["
|
|
26
|
+
for v in A:
|
|
27
|
+
sss += " {:5.3f}".format(v)
|
|
28
|
+
|
|
29
|
+
sss+=" ]"
|
|
30
|
+
return sss
|
|
22
31
|
|
|
23
32
|
def get_acceptance_band():
|
|
24
33
|
"""returns the width of the acceptance band."""
|
|
@@ -362,6 +371,9 @@ def compare_golden(core, golden, value):
|
|
|
362
371
|
golden (AnalysisResult): The golden avrage
|
|
363
372
|
value (str): The name of the variable to compare
|
|
364
373
|
|
|
374
|
+
Returns:
|
|
375
|
+
(pass, max difference, array of location of outsiders)
|
|
376
|
+
|
|
365
377
|
"""
|
|
366
378
|
Y = getattr(core, value)
|
|
367
379
|
gY = getattr(golden, value)
|
|
@@ -373,18 +385,23 @@ def compare_golden(core, golden, value):
|
|
|
373
385
|
X = np.array([float(x) for x in range(10)])
|
|
374
386
|
gX = X
|
|
375
387
|
|
|
376
|
-
# convert to golden X
|
|
377
|
-
spln = CubicSpline(X, Y)
|
|
378
|
-
gC = np.array([spln(x) for x in gX])
|
|
379
|
-
|
|
380
388
|
# compute difference
|
|
381
389
|
band = get_acceptance_band()
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
390
|
+
outsiders = []
|
|
391
|
+
mxval = -1
|
|
392
|
+
indx = 1
|
|
393
|
+
for x, y in zip(X, Y):
|
|
394
|
+
indx = bisect.bisect_left(gX, x, lo=(indx-1 if indx>1 else 0))
|
|
395
|
+
val = gY[indx]
|
|
396
|
+
diff = abs(y-val)
|
|
397
|
+
if diff > mxval:
|
|
398
|
+
mxval = diff
|
|
399
|
+
|
|
400
|
+
if diff>band:
|
|
401
|
+
outsiders.append(x)
|
|
385
402
|
|
|
386
403
|
rc = mxval < band
|
|
387
|
-
return rc, mxval,
|
|
404
|
+
return rc, mxval, outsiders
|
|
388
405
|
|
|
389
406
|
|
|
390
407
|
def analyze_petal_cores(files, golden, options):
|
|
@@ -456,16 +473,17 @@ def analyze_petal_cores(files, golden, options):
|
|
|
456
473
|
if val[0]:
|
|
457
474
|
continue
|
|
458
475
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
476
|
+
noutsiders = len(val[2])
|
|
477
|
+
#if noutsiders < 2:
|
|
478
|
+
# dbOut["comments"].append(
|
|
479
|
+
# "{} in side {}: 1 point out of acceptance band. {}".format(
|
|
480
|
+
# key, iside, val[2])
|
|
481
|
+
# )
|
|
482
|
+
if noutsiders>0:
|
|
465
483
|
dbOut["defects"].append(
|
|
466
484
|
{"name": key,
|
|
467
|
-
|
|
468
|
-
|
|
485
|
+
"description": "{} in side {}: {} points out of acceptance band. {}".format(key, iside, noutsiders, get_array_as_string(val[2])),
|
|
486
|
+
"properties": {"msg": "{} > {}".format(val[1], get_acceptance_band())}
|
|
469
487
|
}
|
|
470
488
|
)
|
|
471
489
|
dbOut["passed"] = (len(dbOut["defects"]) == 0)
|
petal_qc/thermal/coreThermal.py
CHANGED
|
@@ -11,6 +11,7 @@ import itkdb_gtk.ITkDButils
|
|
|
11
11
|
import itkdb_gtk.dbGtkUtils
|
|
12
12
|
import itkdb_gtk.UploadTest
|
|
13
13
|
|
|
14
|
+
__HELP__ = "https://petal-qc.docs.cern.ch"
|
|
14
15
|
|
|
15
16
|
try:
|
|
16
17
|
import petal_qc
|
|
@@ -45,7 +46,7 @@ class CoreThermal(itkdb_gtk.dbGtkUtils.ITkDBWindow):
|
|
|
45
46
|
title: Window title.
|
|
46
47
|
panel_size: size of message pannel.
|
|
47
48
|
"""
|
|
48
|
-
super().__init__(session=session, title=title)
|
|
49
|
+
super().__init__(session=session, title=title, help_link=__HELP__ )
|
|
49
50
|
|
|
50
51
|
self.petal_SN = None
|
|
51
52
|
self.param = params if params else IRPetalParam()
|