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,378 @@
|
|
|
1
|
+
"""Utilities for contours.
|
|
2
|
+
|
|
3
|
+
A Contour is a a list of 2D points tha tdefine a curve or contour.
|
|
4
|
+
This provides aset of utilities to operate on these lists.
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
import random
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
import matplotlib.path as mplPath
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
from petal_qc.utils.Geometry import Point
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def pldist(point, start, end):
|
|
17
|
+
"""Return distance of point to line formed by start-end.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
----
|
|
21
|
+
point: The point
|
|
22
|
+
start: Starting point of line
|
|
23
|
+
end: End point of line
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
if np.all(np.equal(start, end)):
|
|
27
|
+
return np.linalg.norm(point - start)
|
|
28
|
+
|
|
29
|
+
return np.divide(np.abs(np.linalg.norm(np.cross(end - start, start - point))),
|
|
30
|
+
np.linalg.norm(end - start))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def closest_segment_point(P, A, B):
|
|
34
|
+
"""Return distance to segment and closest point in segment.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
----
|
|
38
|
+
P: point
|
|
39
|
+
A: start of segment
|
|
40
|
+
B: end of segment
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
try:
|
|
44
|
+
M = B - A
|
|
45
|
+
|
|
46
|
+
except TypeError:
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
t0 = np.dot(P-A, M)/np.dot(M, M)
|
|
50
|
+
C = A + t0*M
|
|
51
|
+
d = np.linalg.norm(P-C)
|
|
52
|
+
|
|
53
|
+
return d, C
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def find_closest(x0, y0, cont, return_index=False):
|
|
57
|
+
"""Find point in contour closest to given point.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
----
|
|
61
|
+
x0: X of point
|
|
62
|
+
y0: Y of point
|
|
63
|
+
cont: The contour
|
|
64
|
+
return_index: if True returns the index in array
|
|
65
|
+
|
|
66
|
+
Return:
|
|
67
|
+
------
|
|
68
|
+
min_point: the coordinates of closest point
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
npts = len(cont)
|
|
72
|
+
min_dist = sys.float_info.max
|
|
73
|
+
min_point = None
|
|
74
|
+
imin = -1
|
|
75
|
+
for ipt in range(npts):
|
|
76
|
+
x, y = cont[ipt, :]
|
|
77
|
+
dist = (x-x0)**2+(y-y0)**2
|
|
78
|
+
if dist < min_dist:
|
|
79
|
+
imin = ipt
|
|
80
|
+
min_dist = dist
|
|
81
|
+
min_point = (x, y)
|
|
82
|
+
|
|
83
|
+
if return_index:
|
|
84
|
+
return imin, min_point
|
|
85
|
+
else:
|
|
86
|
+
return min_point
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def generate_points_inside_contour(C, n, region=None):
|
|
90
|
+
"""Generate n points that are inside the contour.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
----
|
|
94
|
+
C: the contour
|
|
95
|
+
n: number of points to generate
|
|
96
|
+
region: if given generate withing region (Xmin, Ymin, Xwidth, Ywidth)
|
|
97
|
+
|
|
98
|
+
Returns
|
|
99
|
+
-------
|
|
100
|
+
Array with points
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
out = np.zeros([n, 2])
|
|
104
|
+
if region:
|
|
105
|
+
min_x = region[0]
|
|
106
|
+
min_y = region[1]
|
|
107
|
+
max_x = min_x + region[2]
|
|
108
|
+
max_y = min_y + region[3]
|
|
109
|
+
else:
|
|
110
|
+
min_x, min_y, max_x, max_y = contour_bounds(C)
|
|
111
|
+
|
|
112
|
+
npts = 0
|
|
113
|
+
path = mplPath.Path(C)
|
|
114
|
+
while npts < n:
|
|
115
|
+
P = [random.uniform(min_x, max_x), random.uniform(min_y, max_y)]
|
|
116
|
+
if path.contains_point(P):
|
|
117
|
+
out[npts, :] = P
|
|
118
|
+
npts += 1
|
|
119
|
+
|
|
120
|
+
return out
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def find_closest_point(x0, y0, C):
|
|
124
|
+
"""Find the closest point in contour."""
|
|
125
|
+
P = np.array([x0, y0])
|
|
126
|
+
indx, A = find_closest(x0, y0, C, return_index=True)
|
|
127
|
+
|
|
128
|
+
i1 = indx - 1
|
|
129
|
+
if indx == 0:
|
|
130
|
+
i1 -= 1
|
|
131
|
+
|
|
132
|
+
i2 = indx + 1
|
|
133
|
+
if indx == len(C)-1:
|
|
134
|
+
i2 = 2
|
|
135
|
+
|
|
136
|
+
d1, P1 = closest_segment_point(P, C[i1, :], A)
|
|
137
|
+
d2, P2 = closest_segment_point(P, A, C[i2, :])
|
|
138
|
+
if d1 <= d2:
|
|
139
|
+
return d1, P1
|
|
140
|
+
|
|
141
|
+
else:
|
|
142
|
+
return d2, P2
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def contour_simplify(C, epsilon, return_mask=False):
|
|
146
|
+
"""Simplyfy the contour using RDP algorithm.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
----
|
|
150
|
+
C: the contour
|
|
151
|
+
epsilon: RDP alg epsilon
|
|
152
|
+
return_mask: if True, return the indices of selected points
|
|
153
|
+
rather than the list of points.
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
stk = []
|
|
157
|
+
|
|
158
|
+
start_index = 0
|
|
159
|
+
last_index = len(C) - 1
|
|
160
|
+
stk.append([start_index, last_index])
|
|
161
|
+
|
|
162
|
+
global_start_index = start_index
|
|
163
|
+
indices = np.ones(last_index - start_index + 1, dtype=bool)
|
|
164
|
+
|
|
165
|
+
while stk:
|
|
166
|
+
start_index, last_index = stk.pop()
|
|
167
|
+
|
|
168
|
+
dmax = 0.0
|
|
169
|
+
index = start_index
|
|
170
|
+
|
|
171
|
+
for i in range(index + 1, last_index):
|
|
172
|
+
if indices[i - global_start_index]:
|
|
173
|
+
d = pldist(C[i], C[start_index], C[last_index])
|
|
174
|
+
if d > dmax:
|
|
175
|
+
index = i
|
|
176
|
+
dmax = d
|
|
177
|
+
|
|
178
|
+
if dmax > epsilon:
|
|
179
|
+
stk.append([start_index, index])
|
|
180
|
+
stk.append([index, last_index])
|
|
181
|
+
else:
|
|
182
|
+
for i in range(start_index + 1, last_index):
|
|
183
|
+
indices[i - global_start_index] = False
|
|
184
|
+
|
|
185
|
+
if return_mask:
|
|
186
|
+
return indices
|
|
187
|
+
else:
|
|
188
|
+
return C[indices]
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def contour_smooth(C, distance):
|
|
192
|
+
"""Removes outliers that are at distance > distance from neighbours."""
|
|
193
|
+
npts = len(C)
|
|
194
|
+
for i in range(npts-2):
|
|
195
|
+
dst, P = closest_segment_point(C[i, :], C[i-1, :], C[i+1, :])
|
|
196
|
+
if dst > distance:
|
|
197
|
+
C[i] = P
|
|
198
|
+
|
|
199
|
+
return C
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def contour_length(C):
|
|
203
|
+
"""Return the length of a contour."""
|
|
204
|
+
n = len(C)
|
|
205
|
+
dst = 0.0
|
|
206
|
+
for i in range(n-1):
|
|
207
|
+
dd = np.linalg.norm(C[i, :] - C[i+1, :])
|
|
208
|
+
dst += dd
|
|
209
|
+
|
|
210
|
+
return dst
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def contour_path_length(C, norm=False):
|
|
214
|
+
"""Return the path length of a contour.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
----
|
|
218
|
+
C: the contour
|
|
219
|
+
norm: if true, the lenght wil be normalized to 1.
|
|
220
|
+
|
|
221
|
+
Returns
|
|
222
|
+
-------
|
|
223
|
+
An array with the length of the contour at each points.
|
|
224
|
+
0 for the first point total_length (or 1) for tha last.
|
|
225
|
+
|
|
226
|
+
"""
|
|
227
|
+
npts = len(C)
|
|
228
|
+
D = np.zeros(npts)
|
|
229
|
+
dst = 0
|
|
230
|
+
X0 = 0
|
|
231
|
+
for i in range(npts):
|
|
232
|
+
X = C[i, :]
|
|
233
|
+
if i:
|
|
234
|
+
dst += np.linalg.norm(X-X0)
|
|
235
|
+
|
|
236
|
+
D[i] = dst
|
|
237
|
+
X0 = X
|
|
238
|
+
|
|
239
|
+
D = D/dst
|
|
240
|
+
return D
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def contour_area(C):
|
|
244
|
+
"""Return the area of a contour."""
|
|
245
|
+
def Ia(i, j):
|
|
246
|
+
return (C[i, 0]-C[j, 0])*(C[i, 1]+C[j, 1])
|
|
247
|
+
|
|
248
|
+
n = len(C)
|
|
249
|
+
area = Ia(0, n-1)
|
|
250
|
+
for i in range(n-2):
|
|
251
|
+
area += Ia(i+1, i)
|
|
252
|
+
|
|
253
|
+
return 0.5*abs(area)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def in_contour(x, y, C):
|
|
257
|
+
"""Tell if it is inside the contour."""
|
|
258
|
+
path = mplPath.Path(C)
|
|
259
|
+
return path.contains_point(x, y, C)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def get_average_in_contour(img, C):
|
|
263
|
+
"""Gets average and std of points within contour.
|
|
264
|
+
|
|
265
|
+
We are assuming here that coordinates are integers, ie,
|
|
266
|
+
indices of the matrix of values.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
----
|
|
270
|
+
img: The image
|
|
271
|
+
C: The contour
|
|
272
|
+
|
|
273
|
+
Returns
|
|
274
|
+
-------
|
|
275
|
+
avg, std: averate and std.
|
|
276
|
+
|
|
277
|
+
"""
|
|
278
|
+
values = []
|
|
279
|
+
path = mplPath.Path(C)
|
|
280
|
+
my, mx = img.shape
|
|
281
|
+
min_x, min_y, max_x, max_y = contour_bounds(C)
|
|
282
|
+
for ix in range(int(min_x), int(max_x+1)):
|
|
283
|
+
if ix < 0 or ix >= mx:
|
|
284
|
+
continue
|
|
285
|
+
|
|
286
|
+
for iy in range(int(min_y), int(max_y)+1):
|
|
287
|
+
if iy < 0 or iy >= my:
|
|
288
|
+
continue
|
|
289
|
+
|
|
290
|
+
if path.contains_point([ix, iy]):
|
|
291
|
+
values.append(img[iy, ix])
|
|
292
|
+
|
|
293
|
+
return np.mean(values), np.std(values)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def contour_bounds(C):
|
|
297
|
+
"""Compute the contour bounds.
|
|
298
|
+
|
|
299
|
+
Returns
|
|
300
|
+
-------
|
|
301
|
+
(min_x, min_y, max_x, maxy)
|
|
302
|
+
|
|
303
|
+
"""
|
|
304
|
+
cmin = np.amin(C, axis=0)
|
|
305
|
+
cmax = np.amax(C, axis=0)
|
|
306
|
+
return cmin[0], cmin[1], cmax[0], cmax[1]
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def contour_CM(C):
|
|
310
|
+
"""Return the contour center of mass."""
|
|
311
|
+
return np.mean(C, axis=0)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def inset_contour(C, dist):
|
|
315
|
+
"""Create an inset of the controur.
|
|
316
|
+
|
|
317
|
+
Args:
|
|
318
|
+
----
|
|
319
|
+
C: Input contour
|
|
320
|
+
dist: distance inwards
|
|
321
|
+
|
|
322
|
+
Return:
|
|
323
|
+
------
|
|
324
|
+
array: output contour
|
|
325
|
+
|
|
326
|
+
"""
|
|
327
|
+
n = len(C)
|
|
328
|
+
out = np.zeros(C.shape)
|
|
329
|
+
M = Point(np.mean(C[:, 0]), np.mean([C[:, 1]]))
|
|
330
|
+
for i in range(n-1):
|
|
331
|
+
A = Point(C[i, :])
|
|
332
|
+
B = Point(C[i+1, :])
|
|
333
|
+
delta = (B - A).norm().cw()
|
|
334
|
+
|
|
335
|
+
O = A + dist*delta
|
|
336
|
+
out[i, 0] = O.x
|
|
337
|
+
out[i, 1] = O.y
|
|
338
|
+
|
|
339
|
+
out[-1, :] = out[0, :]
|
|
340
|
+
return out
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def adjust_contour(cont):
|
|
344
|
+
"""Swap contour axis (x<->y) and flip Y."""
|
|
345
|
+
out = np.zeros(cont.shape)
|
|
346
|
+
out[:, 0] = cont[:, 1]
|
|
347
|
+
out[:, 1] = cont[:, 0]
|
|
348
|
+
return out
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def contour_eval(C, x):
|
|
352
|
+
"""Interpolate contour Y value at X.
|
|
353
|
+
|
|
354
|
+
For this to work properly we need that the contour behaves somehow as a 1D
|
|
355
|
+
as a function (monotonic).
|
|
356
|
+
|
|
357
|
+
"""
|
|
358
|
+
value = np.interp(x, C[:, 0], C[:, 1])
|
|
359
|
+
return value
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
if __name__ == "__main__":
|
|
363
|
+
C = np.loadtxt("long_contour.csv")
|
|
364
|
+
|
|
365
|
+
CM0 = contour_CM(C)
|
|
366
|
+
d0, pt0 = find_closest_point(CM0[0], CM0[1], C)
|
|
367
|
+
|
|
368
|
+
Cs = contour_simplify(C, 1.)
|
|
369
|
+
CMs = contour_CM(Cs)
|
|
370
|
+
ds, pts = find_closest_point(CM0[0], CM0[1], Cs)
|
|
371
|
+
d = np.linalg.norm(pt0-pts)
|
|
372
|
+
print("no. of points {}".format(len(C)))
|
|
373
|
+
print("no. of points {}".format(len(Cs)))
|
|
374
|
+
print(d0)
|
|
375
|
+
print(ds)
|
|
376
|
+
print(pt0)
|
|
377
|
+
print(pts)
|
|
378
|
+
print("Distance:", d)
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Create IRCore object from file."""
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import dateutil
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
|
|
12
|
+
from petal_qc.thermal import IRBFile
|
|
13
|
+
from petal_qc.thermal import IRCore
|
|
14
|
+
from petal_qc.thermal import IRPetal
|
|
15
|
+
from petal_qc.thermal import Petal_IR_Analysis
|
|
16
|
+
from petal_qc.thermal import PipeFit
|
|
17
|
+
from petal_qc.thermal.IRDataGetter import IRDataGetter
|
|
18
|
+
from petal_qc.thermal.IRPetalParam import IRPetalParam
|
|
19
|
+
from petal_qc.utils.utils import output_folder
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_db_date(timestamp=None):
|
|
23
|
+
"""Convert a date string into the expected DB format.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
----
|
|
27
|
+
timestamp: A date in string format
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
def date2string(the_date):
|
|
31
|
+
out = the_date.isoformat(timespec='milliseconds')
|
|
32
|
+
if out[-1] not in ['zZ']:
|
|
33
|
+
out += 'Z'
|
|
34
|
+
|
|
35
|
+
return out
|
|
36
|
+
# return the_date.strftime("%Y-%m-%dT%H:%M:%S.000Z")
|
|
37
|
+
|
|
38
|
+
out = None
|
|
39
|
+
if timestamp is None:
|
|
40
|
+
out = date2string(datetime.now())
|
|
41
|
+
elif isinstance(timestamp, datetime):
|
|
42
|
+
out = date2string(timestamp)
|
|
43
|
+
else:
|
|
44
|
+
try:
|
|
45
|
+
this_date = dateutil.parser.parse(timestamp)
|
|
46
|
+
out = date2string(this_date)
|
|
47
|
+
except Exception:
|
|
48
|
+
out = ""
|
|
49
|
+
|
|
50
|
+
return out
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def create_IR_core(options):
|
|
54
|
+
"""Entry point."""
|
|
55
|
+
# Obtain the Data getter.
|
|
56
|
+
try:
|
|
57
|
+
getter = IRDataGetter.factory(options.institute, options)
|
|
58
|
+
|
|
59
|
+
except NotImplemented:
|
|
60
|
+
print("*** Invalid institute name. ***")
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
# Set parameters from command line
|
|
64
|
+
params = IRPetal.IRPetalParam(options)
|
|
65
|
+
params.debug = False
|
|
66
|
+
|
|
67
|
+
# Open the sequence file
|
|
68
|
+
print("## ", options.files)
|
|
69
|
+
irbf = IRBFile.open_file(options.files)
|
|
70
|
+
|
|
71
|
+
# FInd first image below the threshold or the corresponding frame
|
|
72
|
+
# We will use the pipe obtained from here as the reference
|
|
73
|
+
# for the next
|
|
74
|
+
try:
|
|
75
|
+
print("Get the reference image.")
|
|
76
|
+
min_T, i_min, values = getter.find_reference_image(irbf, params.thrs, nframes=10)
|
|
77
|
+
print("Image size: {} x {}".format(values[0].shape[0], values[0].shape[1]))
|
|
78
|
+
|
|
79
|
+
if options.debug:
|
|
80
|
+
Petal_IR_Analysis.show_2D_image(values)
|
|
81
|
+
|
|
82
|
+
except LookupError as e:
|
|
83
|
+
print(e)
|
|
84
|
+
sys.exit()
|
|
85
|
+
|
|
86
|
+
# Get the pipes
|
|
87
|
+
print("Get the pipes.")
|
|
88
|
+
pipes = getter.extract_pipe_path(values, params)
|
|
89
|
+
npipes = len(pipes)
|
|
90
|
+
transforms = [None, None]
|
|
91
|
+
fitter = [None, None]
|
|
92
|
+
sensors = [None, None]
|
|
93
|
+
|
|
94
|
+
print("Fit pipes and find sensor positions.")
|
|
95
|
+
ordered_pipes = [None, None]
|
|
96
|
+
pipe_order = [0, 0]
|
|
97
|
+
for i in range(2):
|
|
98
|
+
pipe_type = PipeFit.PipeFit.guess_pipe_type(pipes[i])
|
|
99
|
+
pipe_order[i] = pipe_type
|
|
100
|
+
PF = PipeFit.PipeFit(pipe_type)
|
|
101
|
+
R = PF.fit_ex(pipes[i], factor=getter.factor)
|
|
102
|
+
if options.debug:
|
|
103
|
+
PF.plot()
|
|
104
|
+
|
|
105
|
+
transforms[pipe_type] = R
|
|
106
|
+
fitter[pipe_type] = PF
|
|
107
|
+
|
|
108
|
+
# Reorder points in pipe contour so that first point corresponds to
|
|
109
|
+
# the U-shape pipe minimum.
|
|
110
|
+
pipes[i] = IRPetal.reorder_pipe_points(pipes[i], pipe_type, R)
|
|
111
|
+
if ordered_pipes[pipe_type] is not None:
|
|
112
|
+
print("### Expect probles. 2 pipes of sme type")
|
|
113
|
+
|
|
114
|
+
ordered_pipes[pipe_type] = pipes[i]
|
|
115
|
+
|
|
116
|
+
# Now make the inverse transform of the area of sernsors and EoS
|
|
117
|
+
S = []
|
|
118
|
+
for s in PF.sensors:
|
|
119
|
+
o = PF.transform_inv(s, R)
|
|
120
|
+
S.append(o)
|
|
121
|
+
|
|
122
|
+
sensors[pipe_type] = S
|
|
123
|
+
|
|
124
|
+
pipes = ordered_pipes
|
|
125
|
+
deltaT = 0.0
|
|
126
|
+
if options.tco2 != 0:
|
|
127
|
+
deltaT = -35.0 - options.tco2
|
|
128
|
+
|
|
129
|
+
# get the framea from where extract the data
|
|
130
|
+
# reorder if needed
|
|
131
|
+
frames = getter.get_analysis_frame(irbf)
|
|
132
|
+
if pipe_order[0]:
|
|
133
|
+
tmp = frames[0]
|
|
134
|
+
frames[0] = frames[1]
|
|
135
|
+
frames[1] = tmp
|
|
136
|
+
|
|
137
|
+
values = getter.get_IR_data(frames, rotate=True)
|
|
138
|
+
results = getter.analyze_IR_image(values, pipes, sensors, 0, params)
|
|
139
|
+
if options.debug:
|
|
140
|
+
fig, ax = plt.subplots(2, 2, tight_layout=True)
|
|
141
|
+
ax[0][0].set_title("Side 0")
|
|
142
|
+
ax[0][1].set_title("Side 1")
|
|
143
|
+
|
|
144
|
+
for iside in range(2):
|
|
145
|
+
R = results[iside]
|
|
146
|
+
ax[0][iside].plot(R.path_length, R.path_temp)
|
|
147
|
+
ax[1][iside].plot([x for x in range(10)], R.sensor_avg)
|
|
148
|
+
|
|
149
|
+
core = IRCore.IRCore(options.SN, options.alias, results, params)
|
|
150
|
+
core.set_files(options.files)
|
|
151
|
+
core.date = get_db_date(frames[0].timestamp)
|
|
152
|
+
core.institute = params.institute
|
|
153
|
+
core.apply_deltaT(deltaT)
|
|
154
|
+
|
|
155
|
+
# Check if we are given an output folder
|
|
156
|
+
ofile = output_folder(options.folder, options.out)
|
|
157
|
+
with open(ofile, "w") as ofile:
|
|
158
|
+
core.to_json(ofile)
|
|
159
|
+
|
|
160
|
+
if options.debug:
|
|
161
|
+
plt.show()
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
if __name__ == "__main__":
|
|
165
|
+
from argparse import ArgumentParser
|
|
166
|
+
|
|
167
|
+
# Argument parser
|
|
168
|
+
parser = ArgumentParser()
|
|
169
|
+
parser.add_argument('files', nargs='*', help="Input files")
|
|
170
|
+
parser.add_argument("--nframe", type=int, default=-1, help="Number of frames. (negative means all.")
|
|
171
|
+
parser.add_argument('--frame', type=int, default=-1, help="First frame to start.")
|
|
172
|
+
parser.add_argument("--tco2", default=0, type=float, help="CO2 inlet temperature.")
|
|
173
|
+
parser.add_argument("--out", default="core.json", help="Output file name")
|
|
174
|
+
parser.add_argument("--alias", default="", help="Alias")
|
|
175
|
+
parser.add_argument("--SN", default="", help="serial number")
|
|
176
|
+
parser.add_argument("--folder", default=None, help="Folder to store output files. Superseeds folder in --out")
|
|
177
|
+
|
|
178
|
+
IRPetalParam.add_parameters(parser)
|
|
179
|
+
|
|
180
|
+
options = parser.parse_args()
|
|
181
|
+
if len(options.files) == 0:
|
|
182
|
+
print("I need an input file")
|
|
183
|
+
sys.exit()
|
|
184
|
+
|
|
185
|
+
create_IR_core(options)
|