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,182 @@
1
+ #!/usr/bin/env python3
2
+ """Read the real pipe and create the pipe contour to compare with.
3
+
4
+ It reads PNG files produced from the petal 3D CAD model and extracts the pipe
5
+ path and the sensor areas. It stores all this information in files that are
6
+ later read by PipeFit.
7
+
8
+ To create the files one needs to run the script twice, one for the front side
9
+ (--front) and anther for the back side (--back).
10
+
11
+ """
12
+ import random
13
+ import sys
14
+ from argparse import ArgumentParser
15
+ from pathlib import Path
16
+
17
+ import matplotlib.pyplot as plt
18
+ import numpy as np
19
+ import skimage
20
+
21
+ from petal_qc.thermal.contours import adjust_contour
22
+ from petal_qc.thermal.contours import contour_simplify
23
+ from petal_qc.thermal.contours import find_closest
24
+
25
+ script_path = Path(__file__).absolute().parent
26
+
27
+
28
+ def crange(start, end, modulo):
29
+ """Circular range.
30
+
31
+ Args:
32
+ ----
33
+ start: Start
34
+ end: End
35
+ modulo: Max value
36
+
37
+ Yields
38
+ ------
39
+ int: the following value
40
+
41
+ """
42
+ if start > end:
43
+ while start < modulo:
44
+ yield start
45
+ start += 1
46
+ start = 0
47
+
48
+ while start < end:
49
+ yield start
50
+ start += 1
51
+
52
+
53
+ def get_pipe_path(im, P1_i, P2_i, debug=False):
54
+ """Find pipe path and save to file.
55
+
56
+ Given the inlet and outlet point, creates the path of the pipe.
57
+
58
+ Args:
59
+ ----
60
+ im: THe image with the pipe
61
+ P1_i: Starting point
62
+ P2_i: End point
63
+ debug: show stuff
64
+
65
+ """
66
+ contours = skimage.measure.find_contours(im)
67
+ pipe = adjust_contour(np.array(contours[0]))
68
+
69
+ npts = len(pipe)
70
+ i1, P1 = find_closest(P1_i[0], P1_i[1], pipe, True)
71
+ i2, P2 = find_closest(P2_i[0], P2_i[1], pipe, True)
72
+
73
+ indx = list(crange(i1, i2, npts))
74
+ inner = pipe[indx, :]
75
+ linner = len(inner)
76
+
77
+ indx = list(crange(i2, i1, npts))
78
+ outer = np.flipud(pipe[indx, :])
79
+ louter = len(outer)
80
+
81
+ if linner > louter:
82
+ indx = random.sample(range(0, linner), linner - louter)
83
+ inner = np.delete(inner, indx, 0)
84
+ else:
85
+ indx = random.sample(range(0, louter), louter - linner)
86
+ outer = np.delete(outer, indx, 0)
87
+
88
+ center = (inner + outer)/2.0
89
+
90
+ small_center = contour_simplify(center - P1, 0.5)
91
+ print("original len {}, small len {}".format(len(center), len(small_center)))
92
+
93
+ if debug:
94
+ fig, ax = plt.subplots(1, 2, tight_layout=True)
95
+ ax[0].plot(inner[:, 0], inner[:, 1])
96
+ ax[0].plot(outer[:, 0], outer[:, 1])
97
+ ax[0].plot(center[:, 0], center[:, 1])
98
+ ax[1].plot(center[:, 0], center[:, 1])
99
+ ax[1].plot(small_center[:, 0], small_center[:, 1])
100
+
101
+ return small_center, P1
102
+
103
+
104
+ def get_sensor_area(ims, P1, debug=False):
105
+ """Find sensor area."""
106
+ if debug:
107
+ fig, ax = plt.subplots(1, 1, tight_layout=True)
108
+
109
+ contours = skimage.measure.find_contours(ims)
110
+
111
+ ncontours = len(contours)
112
+ sensors = []
113
+ for i in range(ncontours):
114
+ sensor = adjust_contour(contours[i]) - P1
115
+ sensor = contour_simplify(sensor, 1)
116
+ sensors.append(sensor)
117
+ if debug:
118
+ ax.plot(sensor[:, 0], sensor[:, 1])
119
+
120
+ return sensors
121
+
122
+
123
+ def main(opts):
124
+ """Main entry."""
125
+ global script_path
126
+ front = opts.front
127
+ if opts.folder:
128
+ folder = Path(opts.folder).expanduser().absolute()
129
+ if folder.exists():
130
+ script_path = folder
131
+ else:
132
+ print("Folder {} does not exist.".format(opts.folder))
133
+ sys.exit()
134
+
135
+ if front:
136
+ in_file = "pipe-front.png"
137
+ in_sensors = "pipe-front-sensors-only.png"
138
+ out_file = "pipe_front.npz"
139
+ P1_i = [608, 817] # [602.9, 779.5] # [568.915, 768.52]
140
+ P2_i = [593.5, 818.7] # [588.7, 781.0] # [582.9, 766.7]
141
+
142
+ else:
143
+ in_file = "pipe-back.png"
144
+ in_sensors = "pipe-back-sensors-only.png"
145
+ out_file = "pipe_back.npz"
146
+ P1_i = [251.8, 817.9] # [256.0, 779.0]
147
+ P2_i = [266.1, 818.3] # [270.5, 781.2]
148
+
149
+ # Get the pipe
150
+ im = skimage.io.imread(script_path.joinpath(in_file), as_gray=True)
151
+ im = np.flipud(im)
152
+
153
+ pipe, P1 = get_pipe_path(im, P1_i, P2_i, debug=opts.debug)
154
+
155
+ # Now gethte sensors
156
+ ims = skimage.io.imread(script_path.joinpath(in_sensors), as_gray=True)
157
+ ims = np.flipud(ims)
158
+
159
+ sensors = get_sensor_area(ims, P1, debug=opts.debug)
160
+
161
+ # Save stuff
162
+ np.savez_compressed(out_file, pipe=pipe, *sensors)
163
+
164
+ fig, ax = plt.subplots(1, 1, tight_layout=True)
165
+ ax.plot(pipe[:, 0], pipe[:, 1])
166
+
167
+ for S in sensors:
168
+ ax.plot(S[:, 0], S[:, 1])
169
+
170
+ plt.show()
171
+
172
+
173
+ if __name__ == "__main__":
174
+ parser = ArgumentParser(description="PipeContour")
175
+ parser.add_argument("--folder", default=None, help="Folder to find the pictures.")
176
+ parser.add_argument("--front", action="store_true", dest='front', default=True, help="Front side")
177
+ parser.add_argument("--back", action="store_false", dest='front', help="Back side")
178
+ parser.add_argument("--debug", action="store_true", default=False, help="Debug.")
179
+
180
+ opts = parser.parse_args()
181
+
182
+ main(opts)
@@ -0,0 +1,420 @@
1
+ #!/usr/bin/env python3
2
+ """Do the thermal analysis of the petal core."""
3
+ import os
4
+ import subprocess
5
+ import sys
6
+ import tempfile
7
+ from argparse import Action
8
+ from argparse import ArgumentParser
9
+ from pathlib import Path
10
+ from pathlib import PurePath
11
+
12
+ import matplotlib.pyplot as plt
13
+ import matplotlib.ticker as ticker
14
+ import numpy as np
15
+ from petal_qc.thermal import contours
16
+ from petal_qc.thermal import IRBFile
17
+ from petal_qc.thermal import IRPetal
18
+ from petal_qc.thermal import PipeFit
19
+ from petal_qc.thermal.Petal_IR_Analysis import AnalysisResult
20
+ from petal_qc.thermal.Petal_IR_Analysis import show_2D_image
21
+ from petal_qc.thermal.PetalColorMaps import HighContrast
22
+
23
+ import petal_qc.utils.Progress as Progress
24
+ import petal_qc.utils.utils as utils
25
+
26
+
27
+ class CommaSeparatedListAction(Action):
28
+ """Create a list from the comma sepparated numbers at imput."""
29
+
30
+ def __call__(self, parser, namespace, values, option_string=None):
31
+ """The actual action."""
32
+ setattr(namespace, self.dest, list(map(int, values.split(','))))
33
+
34
+
35
+ def get_min_max(values, step=1.0):
36
+ """Return min and max.
37
+
38
+ The values are alined with step.
39
+
40
+ Args:
41
+ ----
42
+ values: Array of values
43
+ step (optional): The step_. Defaults to 1.0.
44
+
45
+ Returns
46
+ -------
47
+ min, max.
48
+
49
+ """
50
+ vmax = np.amax(values)
51
+ vmin = np.amin(values)
52
+ ivmax = round(vmax)
53
+ if ivmax < vmax:
54
+ ivmax += step
55
+ if abs(ivmax-vmax) < 0.25*step:
56
+ ivmax += step
57
+
58
+ ivmin = np.round(vmin)
59
+ if ivmin > vmin:
60
+ ivmin -= step
61
+ if abs(ivmin-vmin) < 0.25*step:
62
+ ivmin -= step
63
+
64
+ return ivmin, ivmax
65
+
66
+
67
+ def find_ffmpeg():
68
+ """Returns the path of ffmpeg."""
69
+ folders = os.environ['PATH'].split(':')
70
+
71
+ ffmpeg = None
72
+ for p in folders:
73
+ exe = Path(PurePath(p, "ffmpeg"))
74
+ if exe.exists():
75
+ ffmpeg = exe
76
+ break
77
+
78
+ if not ffmpeg:
79
+ raise Exception("Could not find ffmpeg")
80
+
81
+ return ffmpeg
82
+
83
+
84
+ def create_movie(template, fout):
85
+ """Creates a movie frm a set of files.
86
+
87
+ The name of the files should be passed as a template, ej.,
88
+
89
+ <dir_name>/fig%3d.png
90
+
91
+ """
92
+ pout = utils.find_out_file_name(fout)
93
+ ffmpeg = find_ffmpeg()
94
+
95
+ try:
96
+ out = subprocess.run([ffmpeg, '-r', "10", '-i', template, '-c:v', "libx264", pout],
97
+ capture_output=True,
98
+ text=True,
99
+ timeout=1,
100
+ shell=False)
101
+ print(out)
102
+ print("Movie is ready.")
103
+
104
+ except subprocess.CalledProcessError as xx:
105
+ print("Error")
106
+ print("create_movie: error rc=%d.\n%s" % (xx.returncode, xx.output))
107
+
108
+ except Exception as xx:
109
+ print("Error")
110
+ print("create_movie: error rc=%d.\n%s" % (xx.returncode, xx.output))
111
+
112
+
113
+ def show_cycle(irbf):
114
+ """Show thermal cycle.
115
+
116
+ Args:
117
+ ----
118
+ irbf: IRB file with sequence.
119
+
120
+ """
121
+ # Thermal cycle
122
+ T = []
123
+ D = []
124
+ prg = Progress.ShowProgress(irbf.n_images(), width=20)
125
+ prg.start()
126
+ for i, img in enumerate(irbf.images()):
127
+ prg.increase(1, True)
128
+ T.append(np.min(img.image))
129
+ D.append(img.timestamp)
130
+
131
+ prg.stop
132
+ fig, ax = plt.subplots(1, 1)
133
+ ax.plot(D, T, 'o-')
134
+
135
+
136
+ def save_frame_data(the_frame, path_length, path_temp, sensor_avg, sensor_std):
137
+ """Save the frame data.
138
+
139
+ The input data are 2D arrays.
140
+ i=0 corresponds to the left image
141
+ i=1 corresponds to the right image
142
+
143
+ Args:
144
+ ----
145
+ the_frame: frams index in IRBFile
146
+ path_length: array with positions along the pipe
147
+ path_temp: array with temperatures in path_length positions
148
+ sensor_avg: Average T in sensor areas.
149
+ sensor_std: Temperature std in sensor area.
150
+
151
+ """
152
+ onam = "pipe_temp_{}.csv".format(the_frame)
153
+ ofile = open(onam, 'w')
154
+ ofile.write("x, T, x, T\n")
155
+ ll = [len(path_length[0]), len(path_length[1])]
156
+ nitems = max(ll[0], ll[1])
157
+ for i in range(nitems):
158
+ for j in range(2):
159
+ if i < ll[j]:
160
+ ofile.write("{:.4f}, {:.4f},".format(path_length[j][i], path_temp[j][i]))
161
+ else:
162
+ ofile.write(",,")
163
+
164
+ ofile.write('\n')
165
+ ofile.close()
166
+
167
+ onam = "sensor_temp_{}.csv".format(the_frame)
168
+ ofile = open(onam, 'w')
169
+ ofile.write("T, std, T, std\n")
170
+ ll = [len(sensor_avg[0]), len(sensor_avg[1])]
171
+ nitems = max(ll[0], ll[1])
172
+ for i in range(nitems):
173
+ for j in range(2):
174
+ if i < ll[j]:
175
+ ofile.write("{:.4f}, {:.4f},".format(sensor_avg[j][i], sensor_std[j][i]))
176
+ else:
177
+ ofile.write(",,")
178
+
179
+ ofile.write('\n')
180
+ ofile.close()
181
+
182
+
183
+ def analyze_petal(ifileS, options):
184
+ """Main entry."""
185
+ from IRDataGetter import IRDataGetter
186
+ # Obtain the Data getter.
187
+ try:
188
+ getter = IRDataGetter.factory(options.institute, options)
189
+
190
+ except NotImplemented:
191
+ print("*** Invalid institute name. ***")
192
+ return
193
+
194
+ # Load parameters from IRPetalParam
195
+ params = IRPetal.IRPetalParam(options)
196
+ params.debug = False
197
+
198
+ # Check if we are going to save the images
199
+ tmp_dir = None
200
+ if options.save_fig:
201
+ tmp_dir = tempfile.TemporaryDirectory()
202
+
203
+ # Open the sequence file
204
+ irbf = IRBFile.open_file(ifileS)
205
+
206
+ # Find first image below the threshold
207
+ # we will use the pipe obtained from here as the reference
208
+ # for the next
209
+ try:
210
+ min_T, i_min, values = getter.find_reference_image(irbf, params.thrs, nframes=2)
211
+ print("Image size: {} x {}".format(values[0].shape[0], values[0].shape[1]))
212
+
213
+ if options.debug:
214
+ show_2D_image(values)
215
+
216
+ except LookupError as e:
217
+ print(e)
218
+ sys.exit()
219
+
220
+ # Get the pipes
221
+ print("Extract pipes.")
222
+ pipes = getter.extract_pipe_path(values, params)
223
+ npipes = len(pipes)
224
+
225
+ # plot pipe paths on top of image
226
+ imgs = IRPetal.get_last_images()
227
+ nimgs = len(imgs)
228
+ if options.debug:
229
+ fig, ax = plt.subplots(1, nimgs, tight_layout=True)
230
+ if nimgs == 1:
231
+ ax = [ax, ]
232
+
233
+ for i, img in enumerate(imgs):
234
+ ax[i].imshow(imgs[i], origin="lower", cmap="jet")
235
+ ax[i].plot(pipes[i][:, 0], pipes[i][:, 1], linewidth=3, color="black")
236
+
237
+ # We now need to fit to the reference pipes to get the proper distance along
238
+ # the pipe.
239
+ transforms = [None, None]
240
+ fitter = [None, None]
241
+ sensors = [None, None]
242
+ ordered_pipes = [None, None]
243
+
244
+ print("Fit pipes and find sensor positions.")
245
+ for i in range(npipes):
246
+ # Fit the points to the "pipes"
247
+ pipe_type = PipeFit.PipeFit.guess_pipe_type(pipes[i])
248
+
249
+ PF = PipeFit.PipeFit(pipe_type)
250
+ R = PF.fit_ex(pipes[i])
251
+
252
+ transforms[pipe_type] = R
253
+ fitter[pipe_type] = PF
254
+
255
+ # Reorder points in pipe contour so that first point corresponds to
256
+ # the U-shape pipe minimum.
257
+ pipes[i] = IRPetal.reorder_pipe_points(pipes[i], pipe_type, R)
258
+ if ordered_pipes[pipe_type] is not None:
259
+ print("### Expect probles. 2 pipes of sme type")
260
+
261
+ ordered_pipes[pipe_type] = pipes[i]
262
+
263
+ # Now make the inverse transform of the area of sernsors and EoS
264
+ S = []
265
+ for s in PF.sensors:
266
+ o = PF.transform_inv(s, R)
267
+ S.append(o)
268
+ sensors[pipe_type] = S
269
+
270
+ pipes = ordered_pipes
271
+ if pipes[0] is None and pipes[1] is not None:
272
+ pipes[0] = pipes[1]
273
+ pipes[1] = None
274
+
275
+ sensors[0] = sensors[1]
276
+ sensors[1] = None
277
+
278
+ fitter[0] = fitter[1]
279
+ fitter[1] = None
280
+
281
+ transforms[0] = transforms[1]
282
+ transforms[1] = None
283
+
284
+ if options.debug:
285
+ fig, ax = plt.subplots(1, npipes, tight_layout=True)
286
+ if npipes == 1:
287
+ if fitter[0]:
288
+ ax = [ax, ]
289
+ else:
290
+ ax = [None, ax]
291
+
292
+ fig.suptitle("Fit result")
293
+ for i, F in enumerate(fitter):
294
+ if F is None:
295
+ continue
296
+
297
+ ax[i].plot(F.pipe[:, 0], F.pipe[:, 1])
298
+
299
+ out = F.transform_data(F.data, transforms[i])
300
+ ax[i].plot(out[:, 0], out[:, 1], 'o')
301
+
302
+ # Now go again through all the sequence and get the temperature along the pipes.
303
+ panels = [['P1', 'P2', 'T1', 'S1', 'SP1'],
304
+ ['P1', 'P2', 'T2', 'S2', 'SP2']]
305
+ labels = ["left", "right"]
306
+ tick_labels = ["R0", "R1", "R2", "R3", "R3", "R4", "R4", "R5", "R5", "EoS"]
307
+ fig, ax = plt.subplot_mosaic(panels,
308
+ tight_layout=True,
309
+ figsize=(10, 5),
310
+ gridspec_kw={'width_ratios': (0.25, 0.25, 0.17, 0.16, 0.17)})
311
+
312
+ print("Let's go")
313
+ for j, img in enumerate(irbf.images(options.first_frame, nframes=options.nframe)):
314
+ the_frame = options.first_frame + j
315
+ tmin = np.min(img[0].image)
316
+
317
+ sss = "Image {} - T {:.2f}".format(the_frame, tmin)
318
+ fig.suptitle(sss)
319
+ print(sss)
320
+ values = getter.get_IR_data(img, rotate=True)
321
+ results = getter.analyze_IR_image(values, pipes, sensors, 0, params)
322
+
323
+ # TODO: re-implement this with AnalysisResults
324
+ # if the_frame in options.frames:
325
+ # save_frame_data(the_frame, path_length, path_temp, sensor_avg, sensor_std)
326
+
327
+ ii = 0
328
+ for i in range(2):
329
+ try:
330
+ if results[i] is None:
331
+ continue
332
+ except IndexError:
333
+ continue
334
+
335
+ pmn, pmx = get_min_max(results[i].path_temp)
336
+ spmn, spmx = get_min_max(results[i].path_spread)
337
+ smn, smx = get_min_max(results[i].sensor_avg)
338
+
339
+ pan = "P{}".format(i+1)
340
+ cpan = "T{}".format(i+1)
341
+ span = "S{}".format(i+1)
342
+ sspan = "SP{}".format(i+1)
343
+ ax[pan].clear()
344
+ ax[pan].set_title("Image {}".format(labels[i]))
345
+ ax[pan].imshow(imgs[ii], origin='lower', cmap=HighContrast.reversed()) # , cmap='jet')
346
+ ax[pan].plot(pipes[ii][:, 0], pipes[ii][:, 1], linewidth=2, color="#000000")
347
+ for s in sensors[ii]:
348
+ ax[pan].plot(s[:, 0], s[:, 1], linewidth=2, color="#000000")
349
+
350
+ ax[cpan].clear()
351
+ ax[cpan].yaxis.set_major_locator(ticker.MultipleLocator(1))
352
+ ax[cpan].set_ylim(pmn, pmx)
353
+ ax[cpan].set_title("Pipe {}".format(labels[i]))
354
+ ax[cpan].plot(results[i].path_length, results[i].path_temp)
355
+
356
+ ax[sspan].clear()
357
+ ax[sspan].yaxis.set_major_locator(ticker.MultipleLocator(1))
358
+ ax[sspan].set_ylim(spmn, spmx)
359
+ ax[sspan].set_title("Spread {}".format(labels[i]))
360
+ ax[sspan].plot(results[i].path_length, results[i].path_spread)
361
+
362
+ ax[span].clear()
363
+ ax[span].yaxis.set_major_locator(ticker.MultipleLocator(1))
364
+ ax[span].set_ylim(smn, smx)
365
+ ax[span].set_xticks(range(10), labels=tick_labels)
366
+
367
+ ax[span].set_title("Sensors {}".format(labels[i]))
368
+ ax[span].plot(results[i].sensor_avg, 'o-')
369
+
370
+ ii += 1
371
+
372
+ plt.draw()
373
+ plt.pause(0.0001)
374
+ if the_frame in options.frames:
375
+ ofile = "frame_{:03d}.png".format(the_frame)
376
+ fig.savefig(ofile)
377
+
378
+ if tmp_dir:
379
+ ofile = "{}/fig{:03d}.png".format(tmp_dir.name, j)
380
+ fig.savefig(ofile)
381
+
382
+ if tmp_dir:
383
+ print("Creating movie")
384
+ template = "{}/fig%03d.png".format(tmp_dir.name)
385
+ print("template {}".format(template))
386
+ create_movie(template, options.save_fig)
387
+
388
+ print("Min temperature is {} @ {}".format(min_T, i_min))
389
+ for P in pipes:
390
+ if P is not None:
391
+ print("Pipe shape: {}".format(P.shape))
392
+
393
+ plt.show()
394
+
395
+
396
+ if __name__ == "__main__":
397
+ # This class contains the parameters needed for tha analysis.
398
+ from IRPetalParam import IRPetalParam
399
+
400
+ parser = ArgumentParser()
401
+ parser.add_argument('files', nargs='*', help="Input files")
402
+ parser.add_argument("--save_frames", dest="frames", default=[],
403
+ action=CommaSeparatedListAction,
404
+ help="Frames to save")
405
+ parser.add_argument("--nframe", type=int, default=-1, help="Number of frames. (negative means all.")
406
+ parser.add_argument('--first_frame', type=int, default=0, help="First frame to start.")
407
+ parser.add_argument("--orig", action="store_true", default=False, help="plot the original image")
408
+ parser.add_argument("--save_fig", default=None, help="Save all figures to make a film. Provide output file name")
409
+ parser.add_argument("--show_cycle", action="store_true", default=False, help="Show the thermal cycle.")
410
+
411
+ # Add default parameters to the parser
412
+ IRPetalParam.add_parameters(parser)
413
+
414
+ options = parser.parse_args()
415
+ nfiles = len(options.files)
416
+ if nfiles == 0:
417
+ print("I need an input file")
418
+ sys.exit()
419
+
420
+ analyze_petal(options.files, options)