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.

Files changed (51) hide show
  1. petal_qc/BTreport/CheckBTtests.py +321 -0
  2. petal_qc/BTreport/__init__.py +0 -0
  3. petal_qc/BTreport/bustapeReport.py +144 -0
  4. petal_qc/__init__.py +14 -0
  5. petal_qc/metrology/Cluster.py +90 -0
  6. petal_qc/metrology/DataFile.py +47 -0
  7. petal_qc/metrology/PetalMetrology.py +327 -0
  8. petal_qc/metrology/__init__.py +0 -0
  9. petal_qc/metrology/all2csv.py +57 -0
  10. petal_qc/metrology/analyze_locking_points.py +597 -0
  11. petal_qc/metrology/cold_noise.py +106 -0
  12. petal_qc/metrology/comparisonTable.py +59 -0
  13. petal_qc/metrology/convert_mitutoyo.py +175 -0
  14. petal_qc/metrology/convert_smartscope.py +145 -0
  15. petal_qc/metrology/coreMetrology.py +402 -0
  16. petal_qc/metrology/data2csv.py +63 -0
  17. petal_qc/metrology/do_Metrology.py +117 -0
  18. petal_qc/metrology/flatness4nigel.py +157 -0
  19. petal_qc/metrology/gtkutils.py +120 -0
  20. petal_qc/metrology/petal_flatness.py +353 -0
  21. petal_qc/metrology/show_data_file.py +118 -0
  22. petal_qc/metrology/testSummary.py +37 -0
  23. petal_qc/metrology/test_paralelism.py +71 -0
  24. petal_qc/thermal/CSVImage.py +69 -0
  25. petal_qc/thermal/DebugPlot.py +76 -0
  26. petal_qc/thermal/IRBFile.py +768 -0
  27. petal_qc/thermal/IRCore.py +110 -0
  28. petal_qc/thermal/IRDataGetter.py +359 -0
  29. petal_qc/thermal/IRPetal.py +1338 -0
  30. petal_qc/thermal/IRPetalParam.py +71 -0
  31. petal_qc/thermal/PetalColorMaps.py +62 -0
  32. petal_qc/thermal/Petal_IR_Analysis.py +142 -0
  33. petal_qc/thermal/PipeFit.py +598 -0
  34. petal_qc/thermal/__init__.py +0 -0
  35. petal_qc/thermal/analyze_IRCore.py +417 -0
  36. petal_qc/thermal/contours.py +378 -0
  37. petal_qc/thermal/create_IRCore.py +185 -0
  38. petal_qc/thermal/pipe_read.py +182 -0
  39. petal_qc/thermal/show_IR_petal.py +420 -0
  40. petal_qc/utils/Geometry.py +756 -0
  41. petal_qc/utils/Progress.py +182 -0
  42. petal_qc/utils/__init__.py +0 -0
  43. petal_qc/utils/all_files.py +35 -0
  44. petal_qc/utils/docx_utils.py +186 -0
  45. petal_qc/utils/fit_utils.py +188 -0
  46. petal_qc/utils/utils.py +180 -0
  47. petal_qc-0.0.0.dist-info/METADATA +29 -0
  48. petal_qc-0.0.0.dist-info/RECORD +51 -0
  49. petal_qc-0.0.0.dist-info/WHEEL +5 -0
  50. petal_qc-0.0.0.dist-info/entry_points.txt +3 -0
  51. petal_qc-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,110 @@
1
+ """Thermal result of core."""
2
+ import json
3
+
4
+ import numpy as np
5
+
6
+ from petal_qc.thermal import Petal_IR_Analysis
7
+ from petal_qc.thermal import IRPetalParam
8
+
9
+
10
+ class NumpyArrayEncoder(json.JSONEncoder):
11
+ """Encoder to dump in JSon."""
12
+
13
+ def default(self, obj):
14
+ if isinstance(obj, np.integer):
15
+ return int(obj)
16
+ elif isinstance(obj, np.floating):
17
+ return float(obj)
18
+ elif isinstance(obj, np.ndarray):
19
+ return obj.tolist()
20
+ else:
21
+ return vars(obj)
22
+
23
+
24
+ class IRCore(object):
25
+ """All the thermal data needed for one core."""
26
+
27
+ def __init__(self, SN, alias="", results=None, params=None) -> None:
28
+ """Initializarion.
29
+
30
+ Args:
31
+ SN (str): Serial number of the core
32
+ alias (str): Alternative ID for the core
33
+ params (IRPetalParam): Parameters
34
+
35
+ """
36
+ self.coreID = SN
37
+ self.aliasID = alias
38
+ self.date = None
39
+ self.institute = params.institute if params is not None else None
40
+ self.params = params
41
+ self.files = []
42
+ self.results = [] if results is None else results # list of AnalysisResults. One per side
43
+ self.golden = [] # list of Golden results. One per side.
44
+
45
+ def set_files(self, files):
46
+ """Set the input files."""
47
+ self.files = []
48
+ for F in files:
49
+ self.files.append(F)
50
+
51
+ print(self.files)
52
+
53
+ def set_results(self, results):
54
+ """Set results.
55
+
56
+ Args:
57
+ results (list): list of AnalysisResults
58
+
59
+ """
60
+ self.results = results
61
+
62
+ def add_file(self, fnam):
63
+ """Add a new file path."""
64
+ self.files.append(fnam)
65
+
66
+ def to_json(self, pf=None):
67
+ """Dumps to JSon."""
68
+ out = json.dumps(self, indent=3, cls=NumpyArrayEncoder)
69
+ if pf:
70
+ pf.write(out)
71
+
72
+ return out
73
+
74
+ def apply_deltaT(self, deltaT):
75
+ """Applies a delta T correction."""
76
+ for i in range(2):
77
+ self.results[i].path_temp = np.array(self.results[i].path_temp) + deltaT
78
+ self.results[i].sensor_avg = np.array(self.results[i].sensor_avg) + deltaT
79
+
80
+ @staticmethod
81
+ def read_json(fnam):
82
+ """Read a JSon file."""
83
+ js = None
84
+ with open(fnam, 'r', encoding='UTF-8') as ifp:
85
+ js = json.load(ifp)
86
+
87
+ return IRCore.from_json(js)
88
+
89
+ @staticmethod
90
+ def from_json(J):
91
+ """Loads a JSon object."""
92
+ param = IRPetalParam.IRPetalParam(J["params"])
93
+ results = []
94
+ for o in J["results"]:
95
+ r = Petal_IR_Analysis.AnalysisResult()
96
+ r.from_json(o)
97
+ results.append(r)
98
+
99
+ C = IRCore(J["coreID"], J["aliasID"], results=results, params=param)
100
+ C.date = J["date"]
101
+ for F in J["files"]:
102
+ C.add_file(F)
103
+
104
+ return C
105
+
106
+
107
+ if __name__ == "__main__":
108
+ with open("core.json", "r", encoding="UTF-8") as ifp:
109
+ O = IRCore.from_json(json.load(ifp))
110
+ print(O)
@@ -0,0 +1,359 @@
1
+ """Encapsulates different data structure at DESY and IFIC.
2
+ """
3
+
4
+
5
+ import numpy as np
6
+ from petal_qc.thermal import IRPetal
7
+ from petal_qc.thermal import Petal_IR_Analysis
8
+
9
+
10
+ class IRDataGetter(object):
11
+ """BAse class defining the interface."""
12
+
13
+ def __init__(self):
14
+ """Initialization."""
15
+ self.factor = 1
16
+ return
17
+
18
+ @staticmethod
19
+ def factory(institute, params):
20
+ """Returns the data getter corresponding to the given institute."""
21
+ if institute == "DESY":
22
+ out = IRDataDESY()
23
+
24
+ elif institute == "IFIC":
25
+ out = IRDataIFIC()
26
+
27
+ else:
28
+ raise NotImplementedError
29
+
30
+ out.fine_tune_params(params)
31
+ return out
32
+
33
+ def fine_tune_params(self, param):
34
+ """Set default values for the parameters."""
35
+ return
36
+
37
+ def get_IR_data(self, image, **kargs):
38
+ """_summary_
39
+
40
+ Args:
41
+ ----
42
+ image (IRBImage): the input IRB image
43
+ kargs: keyword arguments to pass.
44
+
45
+ """
46
+ pass
47
+
48
+ def find_reference_image(self, irbf, *args, **kargs):
49
+ """Find first image in sequence with T < T_min.
50
+
51
+ Args:
52
+ ----
53
+ irbf: The sequence of IR images
54
+ T_min: The temperature threshold
55
+ kargs (keyword arguments): keyword arguments
56
+
57
+ Returns
58
+ -------
59
+ min_T, i_min, values: The actual temperature of the image,
60
+ the sequence nubmer
61
+ and the array of values (a 2d array)
62
+
63
+
64
+ """
65
+ return 0, 0, []
66
+
67
+ def extract_pipe_path(self, image, params) -> list:
68
+ """Extract the "pipe path" in a petal IR image.
69
+
70
+ Args:
71
+ ----
72
+ image (mdarray): The 2D array containing the input image
73
+ params: IRPetalPam object with options.
74
+
75
+ Returns
76
+ -------
77
+ pipe: the list of pipe contours or paths.
78
+
79
+ """
80
+ return []
81
+
82
+ def analyze_IR_image(self, img, pipe, sensors, iside, params):
83
+ """Analyze the IR image at input.
84
+
85
+ Args:
86
+ ----
87
+ img (IRBImage): THe image
88
+ pipes: The pipe
89
+ sensors: The sensor areas
90
+ iside: petal image with EoS on the left(0) or right (1)
91
+ params: IRPetal parameters
92
+
93
+ Returns
94
+ -------
95
+ An array of AnalysisResult objects.
96
+
97
+ """
98
+ pass
99
+
100
+ def get_analysis_frame(self, irbf):
101
+ """Get the frame where we want to perform the analysis."""
102
+ return None
103
+
104
+
105
+ class IRDataIFIC(IRDataGetter):
106
+ """Gets data for IFIC analysis."""
107
+
108
+ def __init__(self) -> None:
109
+ """Initialization."""
110
+ super().__init__()
111
+
112
+ def find_reference_image(self, irbf, *args, **kargs):
113
+ """Find first image in sequence with T < T_min.
114
+
115
+ Args:
116
+ ----
117
+ irbf: The sequence of IR images
118
+ T_min: The temperature threshold
119
+ kargs (keyword arguments): keyword arguments
120
+
121
+ Returns
122
+ -------
123
+ min_T, i_min, values: The actual temperature of the image,
124
+ the sequence nubmer
125
+ and the array of values (a 2d array)
126
+
127
+
128
+ """
129
+ if len(args) == 0:
130
+ T_min = -22.0
131
+ else:
132
+ T_min = args[0]
133
+
134
+ irbf.set_concatenate(True)
135
+ min_T, i_min, ref_img = IRPetal.find_reference_image(irbf, T_min)
136
+ values = self.get_IR_data(ref_img)
137
+ self.factor = values.shape[0]/640
138
+
139
+ return min_T, i_min, [values, ]
140
+
141
+ def get_IR_data(self, image, **kargs):
142
+ """Get the data from the image in the proper orientation.
143
+
144
+ Proper orientation means that petals are vertical (in the mirror image).
145
+ It will eventually try to rotate the image to compensate a camera rotation.
146
+
147
+ Args:
148
+ ----
149
+ image: IRBimage. If a list of IRBFile objects is given, only the frist is taken.
150
+ rotate: True to make the rotation compensation.
151
+
152
+ Returns
153
+ -------
154
+ 2d array: The 2d array wit the temperature data.
155
+
156
+ """
157
+ if isinstance(image, list) or isinstance(image, tuple):
158
+ image = image[0]
159
+
160
+ nrow, ncol = image.image.shape
161
+ landscape = (ncol > nrow)
162
+
163
+ if landscape:
164
+ values = image.image.T
165
+ else:
166
+ values = image.image
167
+
168
+ rotate = False
169
+ if 'rotate' in kargs:
170
+ rotate = kargs['rotate']
171
+
172
+ if rotate:
173
+ values = IRPetal.rotate_full_image(values)
174
+
175
+ return values
176
+
177
+ def extract_pipe_path(self, image, params) -> list:
178
+ """Extract the "pipe path" in a petal IR image.
179
+
180
+ Args:
181
+ ----
182
+ image(ndarray): The 2D array containing the 2 specular images
183
+ params: IRPetalPam object with options.
184
+
185
+ Returns
186
+ -------
187
+ pipe: the list of pipe contours or paths.
188
+
189
+ """
190
+ try:
191
+ pipes = IRPetal.extract_mirrored_pipe_path(image, params)
192
+ except Exception:
193
+ pipes = IRPetal.extract_mirrored_pipe_path(image[0], params)
194
+ return pipes
195
+
196
+ def analyze_IR_image(self, img, pipe, sensors, iside, params):
197
+ """IFIC implementation.
198
+
199
+ Analyzes an image with specular images of petal core.
200
+
201
+ Inputs have same meaning as bas eclass but are arrays with the 2 core sides.
202
+ """
203
+ res, _ = Petal_IR_Analysis.analyze_IR_mirrored_image(img, pipe, sensors, params)
204
+ return res
205
+
206
+ @staticmethod
207
+ def find_minimum(values):
208
+ """Find minima in series."""
209
+ indx = []
210
+
211
+ for i, v in enumerate(values):
212
+ if i == 0:
213
+ vprev = v
214
+ continue
215
+
216
+ try:
217
+ vnext = values[i+1]
218
+ except IndexError:
219
+ continue
220
+
221
+ if vprev > v and vnext > v:
222
+ indx.append(i)
223
+
224
+ vprev = v
225
+
226
+ return indx
227
+
228
+ def get_analysis_frame(self, irbf):
229
+ """Get the frame where we want to perform the analysis.
230
+
231
+ IFIC takes the minimum of the last cycle.
232
+ """
233
+ # Get all the temperatures
234
+ min_T = []
235
+ for img in irbf.images():
236
+ min_T.append(np.min(img[0].image))
237
+
238
+ indx = IRDataIFIC.find_minimum(min_T)
239
+ return [irbf.getImage(indx[-1])]
240
+
241
+
242
+ class IRDataDESY(IRDataGetter):
243
+ """Gets data for DESY."""
244
+
245
+ def __init__(self) -> None:
246
+ """Initialization."""
247
+ super().__init__()
248
+
249
+ def fine_tune_params(self, param):
250
+ """Set default values for the parameters."""
251
+ param.distance = 16
252
+ param.width = 16
253
+
254
+ def get_IR_data(self, image, **kargs):
255
+ """Get the data from the image in the proper orientation.
256
+
257
+ Args:
258
+ ----
259
+ image: IRBimage
260
+ kargs: keyword arguments
261
+
262
+ Returns
263
+ -------
264
+ 2d array: The 2d array wit the temperature data.
265
+
266
+ """
267
+ try:
268
+ values = np.rot90(image.image)
269
+ except Exception:
270
+ values = []
271
+ for img in image:
272
+ values.append(np.rot90(img.image))
273
+
274
+ return values
275
+
276
+ def find_reference_image(self, irbf, *args, **kargs):
277
+ """DESY wants the average of all images in the sequence.
278
+
279
+ Args:
280
+ ----
281
+ irbf: The sequence of IR images
282
+ args: The temperature threshold
283
+ kargs (keyword arguments): keyword arguments
284
+
285
+ Returns
286
+ -------
287
+ min_T, i_min, values: The actual temperature of the image,
288
+ the sequence nubmer
289
+ and the array of values (a 2d array)
290
+
291
+ """
292
+ if 'nframes' in kargs:
293
+ nframes = kargs['nframes']
294
+ else:
295
+ nframes = -1
296
+
297
+ min_T = 1e50
298
+ avg_img = irbf.append_average(nframes=nframes)
299
+ for img in avg_img:
300
+ val = np.min(img.image)
301
+ if val < min_T:
302
+ min_T = val
303
+
304
+ i_min = irbf.nimages-1
305
+ values = self.get_IR_data(avg_img)
306
+
307
+ factors = []
308
+ for img in values:
309
+ factors.append(img.shape[0]/640)
310
+ self.factor = max(factors)
311
+
312
+ return min_T, i_min, values
313
+
314
+ def extract_pipe_path(self, images, params) -> list:
315
+ """Extract the "pipe path" in a petal IR image.
316
+
317
+ Args:
318
+ ----
319
+ images(list(ndarray)): The array of 2D arrays containing the images
320
+ params: IRPetalPam object with options.
321
+
322
+ Returns
323
+ -------
324
+ pipe: the list of pipe contours or paths.
325
+
326
+ """
327
+ pipes = []
328
+ for img in images:
329
+ pipe = IRPetal.extract_pipe_path(img, params)
330
+ pipes.append(pipe)
331
+
332
+ IRPetal.set_images(images)
333
+ return pipes
334
+
335
+ def analyze_IR_image(self, img, pipes, sensors, iside, params):
336
+ """DESY implementation.
337
+
338
+ Only one petal side at imput.
339
+ """
340
+ if isinstance(img, list):
341
+ res = Petal_IR_Analysis.analyze_IR_image_list(img, pipes, sensors, params)
342
+ return res
343
+
344
+ else:
345
+ res = Petal_IR_Analysis.analyze_IR_image(img, pipes[0], sensors[0], iside[0], params)
346
+ if iside[0]:
347
+ return [None, res]
348
+ else:
349
+ return [res, None]
350
+
351
+ def get_analysis_frame(self, irbf):
352
+ """Get the frame where we want to perform the analysis.
353
+
354
+ DESY gets the average of all frames.
355
+ """
356
+ if not irbf.has_average:
357
+ irbf.append_average(nframes=5)
358
+
359
+ return [v[-1] for v in irbf.file_images]