petal-qc 0.0.9__py3-none-any.whl → 0.0.11__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 (36) hide show
  1. petal_qc/BTreport/CheckBTtests.py +2 -6
  2. petal_qc/__init__.py +17 -1
  3. petal_qc/metrology/PetalMetrology.py +0 -5
  4. petal_qc/metrology/compare_Cores.py +27 -15
  5. petal_qc/metrology/coreMetrology.py +20 -10
  6. petal_qc/metrology/do_Metrology.py +0 -5
  7. petal_qc/metrology/petal_flatness.py +0 -4
  8. petal_qc/metrology/readAVSdata.py +762 -0
  9. petal_qc/metrology/uploadPetalInformation.py +769 -0
  10. petal_qc/test/checkAVStests.py +181 -0
  11. petal_qc/test/compare_golden.py +44 -0
  12. petal_qc/test/getAVSjson.py +27 -0
  13. petal_qc/test/getAVStests.py +263 -0
  14. petal_qc/test/getPetalCoreTestSummary.py +89 -0
  15. petal_qc/test/listPetalCoreComponents.py +89 -0
  16. petal_qc/test/prepareDESYfiles.py +25 -8
  17. petal_qc/thermal/DESYdata.py +58 -0
  18. petal_qc/thermal/IRBFile.py +51 -7
  19. petal_qc/thermal/IRCore.py +1 -1
  20. petal_qc/thermal/IRDataGetter.py +43 -24
  21. petal_qc/thermal/IRPetal.py +84 -7
  22. petal_qc/thermal/IRPetalParam.py +1 -1
  23. petal_qc/thermal/Petal_IR_Analysis.py +4 -3
  24. petal_qc/thermal/PipeFit.py +12 -3
  25. petal_qc/thermal/analyze_IRCore.py +24 -15
  26. petal_qc/thermal/coreThermal.py +124 -28
  27. petal_qc/thermal/create_IRCore.py +35 -9
  28. petal_qc/thermal/create_core_report.py +31 -8
  29. petal_qc/utils/Geometry.py +2 -2
  30. petal_qc/utils/readGraphana.py +2 -1
  31. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/METADATA +2 -2
  32. petal_qc-0.0.11.dist-info/RECORD +70 -0
  33. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/WHEEL +1 -1
  34. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/entry_points.txt +3 -0
  35. petal_qc-0.0.9.dist-info/RECORD +0 -61
  36. {petal_qc-0.0.9.dist-info → petal_qc-0.0.11.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env python3
2
- """Prepara input files from DESY RAW."""
2
+ """Prepare raw data input files from DESY so that we can use them with this code."""
3
3
  import os
4
4
  import fnmatch
5
5
  import re
6
6
  from pathlib import Path
7
+ import argparse
7
8
 
8
9
  def all_files(root, patterns='*', single_level=False, yield_folders=False):
9
10
  """A generator that reruns all files in the given folder.
@@ -41,18 +42,26 @@ class PetalCore:
41
42
  self.back = {}
42
43
 
43
44
  def main(folder, out_folder):
44
- """Main entry point."""
45
+ """Main entry point.
46
+
47
+ It takes DESY raw data files and combines them into a single file for front
48
+ and back metrology.
49
+
50
+ Args:
51
+ folder: the input folder where to find the original files.
52
+ out_folder: the folder where the new fiels will be stored.
53
+ """
45
54
  outF = Path(out_folder).expanduser().resolve()
46
55
  if not outF.exists():
47
56
  os.mkdir(outF)
48
-
49
- rgx = re.compile(r"Project Name: (\w+)side_.*AlternativeID=PPC-(\d+)", re.MULTILINE|re.DOTALL)
57
+
58
+ rgx = re.compile(r"Project Name: (\w+)side_.*AlternativeID=PPC[-_](\d+)", re.MULTILINE|re.DOTALL)
50
59
  petal_cores = {}
51
60
  for fnam in all_files(folder, "*.txt"):
52
61
  P = Path(fnam).expanduser().resolve()
53
62
  with open(fnam, "r", encoding="UTF-8") as ff:
54
63
  R = rgx.search(ff.read())
55
- if R:
64
+ if R:
56
65
  petal_id = "PPC.{}".format(R.group(2))
57
66
  side = R.group(1).lower()
58
67
  if "_2D_" in P.name:
@@ -75,12 +84,20 @@ def main(folder, out_folder):
75
84
  list_file.write("{} {}-{} {}\n".format(oname, petal_id, side, petal_id))
76
85
  data = ""
77
86
  for data_type, fnam in values.items():
87
+ if fnam is None:
88
+ print("This should not happen.")
89
+
78
90
  with open(fnam, "r", encoding="UTF-8") as ifile:
79
91
  data += ifile.read()
80
-
92
+
81
93
  with open(oname, "w", encoding="UTF-8") as ofile:
82
94
  ofile.write(data)
83
-
95
+
84
96
  list_file.close()
97
+
85
98
  if __name__ == "__main__":
86
- main("/Users/lacasta/Downloads/DESY_Production", "/tmp/desy")
99
+ parser = argparse.ArgumentParser()
100
+ parser.add_argument("--input-folder", default=None, help="Input folder")
101
+ parser.add_argument("--output-folder", help="Outout fodler", default=None)
102
+
103
+ main("/Users/lacasta/Downloads/Report_QC-desy_Sep2024", "/tmp/desy")
@@ -0,0 +1,58 @@
1
+ """Dialog to get DESY IRB files."""
2
+ from pathlib import Path
3
+ import itkdb_gtk
4
+ import itkdb_gtk.dbGtkUtils
5
+
6
+ import gi
7
+ gi.require_version("Gtk", "3.0")
8
+ from gi.repository import Gtk, Gio
9
+
10
+
11
+ class DesyData(Gtk.Dialog):
12
+ """To get DESY data"""
13
+
14
+ def __init__(self, files=None):
15
+ super().__init__(title="DESY IRB files")
16
+
17
+ self.front = None
18
+ self.back = None
19
+
20
+ self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
21
+ Gtk.STOCK_OK, Gtk.ResponseType.OK)
22
+
23
+ area = self.get_content_area()
24
+ box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
25
+ area.pack_start(box, True, True, 10)
26
+
27
+ lbl = Gtk.Label(label="Choose the IRB files.")
28
+ box.pack_start(lbl, True, True, 10)
29
+
30
+ grid = Gtk.Grid(column_spacing=10, row_spacing=5)
31
+ box.pack_start(grid, True, True, 10)
32
+ grid.attach(Gtk.Label(label="Front"), 0, 0, 1, 1)
33
+ grid.attach(Gtk.Label(label="Back"), 0, 1, 1, 1)
34
+
35
+ fback = Gtk.FileChooserButton()
36
+ fback.connect("file-set", self.on_file_set, 0)
37
+ ffront = Gtk.FileChooserButton()
38
+ ffront.connect("file-set", self.on_file_set, 1)
39
+ grid.attach(ffront, 1, 0, 1, 1)
40
+ grid.attach(fback, 1, 1, 1, 1)
41
+
42
+ if files is not None and len(files)==2:
43
+ ffront.set_file(Gio.File.new_for_path(files[0]))
44
+ fback.set_file(Gio.File.new_for_path(files[1]))
45
+
46
+ def on_file_set(self, *args):
47
+ """Get back side file."""
48
+ fnam = args[0].get_filename()
49
+ if fnam is None or not Path(fnam).exists():
50
+ itkdb_gtk.dbGtkUtils.complain("Could not find Data File", fnam, parent=self)
51
+ return
52
+
53
+ if args[1] == 0:
54
+ self.back = fnam
55
+ elif args[1] == 1:
56
+ self.front = fnam
57
+ else:
58
+ itkdb_gtk.dbGtkUtils.complain("This should not happen.", fnam, parent=self)
@@ -166,11 +166,32 @@ class HeaderBlock(object):
166
166
  self.word8 = ifile.getInt()
167
167
  self.end = ifile.tell()
168
168
 
169
+ if self.end - self.where != 32:
170
+ raise RuntimeError("byte counting error in parsing of HeaderBlock")
171
+
169
172
  def get_name(self):
170
173
  """Return the header type as string."""
171
174
  return HeaderBlock.header_name[self.type]
172
175
 
173
176
 
177
+ class IRBPreview(object):
178
+ """A preview in the IRB file."""
179
+
180
+ def __init__(self, block):
181
+ """Initialize.
182
+
183
+ Args:
184
+ block: the block with the information.
185
+
186
+ """
187
+ self.block = block
188
+ old_position = block.ifile.tell()
189
+
190
+
191
+
192
+ block.ifile.seek(old_position)
193
+
194
+
174
195
  class IRBImage(object):
175
196
  """An image in the IRBis file."""
176
197
 
@@ -181,7 +202,6 @@ class IRBImage(object):
181
202
  """Initialize.
182
203
 
183
204
  Args:
184
- ----
185
205
  ifile: The input file
186
206
  block: The block with the information.
187
207
 
@@ -233,9 +253,8 @@ class IRBImage(object):
233
253
  zero = ifile.getShort()
234
254
 
235
255
  if self.width > 10000 or self.height > 10000:
236
- print("Image size out of range ({}x{})".format(
256
+ raise RuntimeError("Image size out of range ({}x{})".format(
237
257
  self.width, self.height))
238
- return
239
258
 
240
259
  flagsPosition = block.offset + IRBImage.FLAGS_OFFSET
241
260
  self.readImageFlags(flagsPosition)
@@ -314,13 +333,18 @@ class IRBImage(object):
314
333
  if v2_count < 1:
315
334
  v2_count = v2_data[v2_pos]
316
335
  v2 = v2_data[v2_pos+1]
317
- P1 = self.palette[v2+1]
336
+ if v2 < 0:
337
+ v2 += 256
338
+ P1 = self.palette[(v2+1) % 256]
318
339
  P2 = self.palette[v2]
319
340
  v2_pos += 2
320
341
 
321
342
  v2_count -= 1
322
343
 
323
344
  v1 = v1_data[i]
345
+ if v1 < 0:
346
+ v1 += 256
347
+
324
348
  f = v1/256.0
325
349
 
326
350
  # linear interpolation betweeen eighboring palette entries
@@ -423,6 +447,7 @@ class IRBFile(object):
423
447
  """
424
448
  self.concatenate = concatenate
425
449
  self.imgList = []
450
+ self.previewList = []
426
451
  self.blocks = []
427
452
  self.ifiles = []
428
453
  self.file_images = []
@@ -493,6 +518,9 @@ class IRBFile(object):
493
518
  if block.type == HeaderBlock.IMAGE:
494
519
  image = IRBImage(block)
495
520
  self.imgList.append(image)
521
+ elif block.type == HeaderBlock.PREVIEW:
522
+ image = IRBPreview(block)
523
+ self.previewList.append(image)
496
524
 
497
525
  if self.is_sequence:
498
526
  offset = -1
@@ -549,6 +577,10 @@ class IRBFile(object):
549
577
  self.current_file = i
550
578
  self.imgList = self.file_images[i]
551
579
 
580
+ def getImage_timestamp(self, i):
581
+ """Return timestamp of i-th image."""
582
+ return self.imgList[i].timestamp
583
+
552
584
  def getImage(self, i):
553
585
  """Get i-th image in current file.
554
586
 
@@ -682,7 +714,7 @@ class IRBFile(object):
682
714
  return out
683
715
 
684
716
 
685
- def open_file(fname):
717
+ def open_file(fname, concat=False):
686
718
  """Opens a file an returns a IRBFile instance.
687
719
 
688
720
  Args:
@@ -694,7 +726,19 @@ def open_file(fname):
694
726
  if is_iterable(fname):
695
727
  # we assume it is a list of IRB files...
696
728
  try:
697
- irbf = IRBFile(fname)
729
+ if concat:
730
+ irbf = IRBFile(fname)
731
+ return irbf
732
+ else:
733
+ out = []
734
+ for f in fname:
735
+ irbf = IRBFile(f)
736
+ out.append(irbf)
737
+
738
+ if len(out) == 1:
739
+ out = out[0]
740
+
741
+ return out
698
742
 
699
743
  except FileNotFoundError as eee:
700
744
  print(eee)
@@ -769,4 +813,4 @@ def main():
769
813
  plt.show()
770
814
 
771
815
  if __name__ == "__main__":
772
- main()
816
+ main()
@@ -41,7 +41,7 @@ class IRCore(object):
41
41
  self.files = []
42
42
  self.results = [] if results is None else results # list of AnalysisResults. One per side
43
43
  self.golden = [] # list of Golden results. One per side.
44
- self.inlet = -9999
44
+ self.inlet = params.tco2
45
45
 
46
46
  def set_files(self, files):
47
47
  """Set the input files."""
@@ -19,10 +19,10 @@ HAS_GRAPHANA = False
19
19
  try:
20
20
  from petal_qc.utils.readGraphana import ReadGraphana
21
21
  HAS_GRAPHANA = True
22
-
22
+
23
23
  except ImportError:
24
24
  HAS_GRAPHANA = False
25
-
25
+
26
26
 
27
27
 
28
28
  class IRDataGetter(object):
@@ -62,7 +62,7 @@ class IRDataGetter(object):
62
62
  kargs: keyword arguments to pass.
63
63
 
64
64
  """
65
- pass
65
+ return
66
66
 
67
67
  def find_reference_image(self, irbf, *args, **kargs):
68
68
  """Find first image in sequence with T < T_min.
@@ -114,7 +114,7 @@ class IRDataGetter(object):
114
114
  An array of AnalysisResult objects.
115
115
 
116
116
  """
117
- pass
117
+ return
118
118
 
119
119
  def get_analysis_frame(self, irbf):
120
120
  """Get the frame where we want to perform the analysis."""
@@ -166,12 +166,12 @@ class IRDataIFIC(IRDataGetter):
166
166
  # T_min = -22.0
167
167
  # else:
168
168
  # T_min = args[0]
169
- #
169
+ #
170
170
  # irbf.set_concatenate(True)
171
171
  # min_T, i_min, ref_img = IRPetal.find_reference_image(irbf, T_min)
172
172
  # values = self.get_IR_data(ref_img)
173
173
  # self.factor = values.shape[0]/640
174
- #
174
+ #
175
175
  # return min_T, i_min, [values, ]
176
176
 
177
177
  def get_IR_data(self, image, **kargs):
@@ -281,10 +281,10 @@ class IRDataIFIC(IRDataGetter):
281
281
  img = self.analysis_frame[0]
282
282
  X, T = self.DB.get_temperature(img.timestamp, 1)
283
283
  return np.min(T)
284
-
284
+
285
285
  else:
286
286
  return -9999
287
-
287
+
288
288
 
289
289
 
290
290
  class IRDataDESY(IRDataGetter):
@@ -343,14 +343,28 @@ class IRDataDESY(IRDataGetter):
343
343
  nframes = -1
344
344
 
345
345
  min_T = 1e50
346
- avg_img = irbf.append_average(nframes=nframes)
347
- for img in avg_img:
348
- val = np.min(img.image)
349
- if val < min_T:
350
- min_T = val
346
+ i_min = -1
347
+ try:
348
+ avg_img = irbf.append_average(nframes=nframes)
349
+ for img in avg_img:
350
+ val = np.min(img.image)
351
+ if val < min_T:
352
+ min_T = val
351
353
 
352
- i_min = irbf.nimages-1
353
- values = self.get_IR_data(avg_img)
354
+ i_min = irbf.nimages-1
355
+ values = self.get_IR_data(avg_img)
356
+
357
+ except AttributeError:
358
+ # We have 2 files, one front y the second back
359
+ values = []
360
+ factors = []
361
+ for ifile in irbf:
362
+ val = self.get_IR_data(ifile.getImage(0))
363
+ Tmin = np.min(val)
364
+ if Tmin < min_T:
365
+ min_T = Tmin
366
+ i_min = 0
367
+ values.append(val)
354
368
 
355
369
  factors = []
356
370
  for img in values:
@@ -359,25 +373,26 @@ class IRDataDESY(IRDataGetter):
359
373
 
360
374
  return min_T, i_min, values
361
375
 
362
- def extract_pipe_path(self, images, params) -> list:
376
+ def extract_pipe_path(self, image, params) -> list:
363
377
  """Extract the "pipe path" in a petal IR image.
364
378
 
365
379
  Args:
366
- ----
367
- images(list(ndarray)): The array of 2D arrays containing the images
380
+ image(list(ndarray)): The array of 2D arrays containing the images
368
381
  params: IRPetalPam object with options.
369
382
 
370
383
  Returns
371
- -------
372
384
  pipe: the list of pipe contours or paths.
373
385
 
374
386
  """
375
387
  pipes = []
376
- for img in images:
388
+ points_3d = []
389
+ for img in image:
377
390
  pipe = IRPetal.extract_pipe_path(img, params)
391
+ points_3d.append(IRPetal.get_all_3d_points())
378
392
  pipes.append(pipe)
379
393
 
380
- IRPetal.set_images(images)
394
+ IRPetal.set_all_3d_points(points_3d)
395
+ IRPetal.set_images(image)
381
396
  return pipes
382
397
 
383
398
  def analyze_IR_image(self, img, pipes, sensors, iside, params):
@@ -401,7 +416,11 @@ class IRDataDESY(IRDataGetter):
401
416
 
402
417
  DESY gets the average of all frames.
403
418
  """
404
- if not irbf.has_average:
405
- irbf.append_average(nframes=5)
419
+ try:
420
+ if not irbf.has_average:
421
+ irbf.append_average(nframes=5)
422
+
423
+ return [v[-1] for v in irbf.file_images]
406
424
 
407
- return [v[-1] for v in irbf.file_images]
425
+ except AttributeError:
426
+ return [irbf[0].getImage(0), irbf[1].getImage(0)]
@@ -35,7 +35,7 @@ debug_plot = DebugPlot.DebugPlot()
35
35
  the_segments = None # global variable to store the last segments found.
36
36
  the_contours = None # Global variable to store the last contours found
37
37
  the_images = None
38
-
38
+ the_3d_points = None
39
39
 
40
40
  class DebugTempProfile(object):
41
41
  """Stores Debug data."""
@@ -68,6 +68,16 @@ class DebugTempProfile(object):
68
68
  T_profile = None # Global to store the temp. profile.
69
69
 
70
70
 
71
+ def get_all_3d_points():
72
+ """Return all pipe path 3D points."""
73
+ return the_3d_points
74
+
75
+ def set_all_3d_points(all_3d_points):
76
+ """Set all pipe path 3D points."""
77
+ global the_3d_points
78
+ the_3d_points = all_3d_points
79
+
80
+
71
81
  def get_last_segments():
72
82
  """Return the last segments found."""
73
83
  global the_segments
@@ -145,6 +155,39 @@ class Segment(object):
145
155
 
146
156
  return points
147
157
 
158
+ @staticmethod
159
+ def get_3d_points_in_list(segments):
160
+ """Return a list with all the 3D points (x,y,T) in the list of segments.
161
+
162
+ Args:
163
+ ----
164
+ segments (list[Segment]): The list of segments
165
+
166
+ Returns
167
+ -------
168
+ np.array: array of points.
169
+
170
+ """
171
+ # Count the number of points
172
+ npts = 0
173
+ for S in segments:
174
+ if S.Pmin is not None:
175
+ npts += len(S.Pmin)
176
+
177
+ points = np.zeros([npts, 3])
178
+ ipoint = 0
179
+ for S in segments:
180
+ if S.Pmin is None:
181
+ continue
182
+
183
+ for i, Pmin in enumerate(S.Pmin):
184
+ points[ipoint, 0] = Pmin.x
185
+ points[ipoint, 1] = Pmin.y
186
+ points[ipoint, 2] = S.Tmin[i]
187
+ ipoint += 1
188
+
189
+ return points
190
+
148
191
  @staticmethod
149
192
  def get_spread_in_list(segments):
150
193
  """Return an array with spread values."""
@@ -323,7 +366,7 @@ def extract_mirrored_pipe_path(values, params):
323
366
  (left_pipe, right_pipe): The 2 paths.
324
367
 
325
368
  """
326
- global the_images
369
+ global the_images, the_3d_points
327
370
  if params.rotate:
328
371
  rotated = rotate_full_image(values)
329
372
  else:
@@ -331,11 +374,14 @@ def extract_mirrored_pipe_path(values, params):
331
374
 
332
375
  imgs = split_IR_image(rotated)
333
376
  pipes = []
377
+ points_3d = []
334
378
  for img in imgs:
335
379
  pipe = extract_pipe_path(img, params)
336
380
  pipes.append(pipe)
381
+ points_3d.append(get_all_3d_points())
337
382
 
338
383
  the_images = imgs
384
+ the_3d_points = points_3d
339
385
  return list(pipes)
340
386
 
341
387
 
@@ -684,7 +730,7 @@ def get_derivatives(T_min, x_min, x_max, coeff):
684
730
  return valid_roots, valid_values, valid_curv
685
731
 
686
732
 
687
- def show_profile(debug_plot):
733
+ def show_profile(debug_plot, title=None):
688
734
  """Plot a profile."""
689
735
  debug_plot.setup_debug("Slices", is_3d=True)
690
736
  if T_profile:
@@ -693,6 +739,12 @@ def show_profile(debug_plot):
693
739
  if T_profile._pF is not None:
694
740
  debug_plot.plotx("Slices", T_profile._pF[:, 0], T_profile._pF[:, 1], T_profile._Fn, 'b-')
695
741
 
742
+ if title:
743
+ debug_plot.set_title("Slices", title)
744
+
745
+
746
+ __call_id__ = 0
747
+ __img_num__ = 0
696
748
 
697
749
  def slice_contours(data, inner, outer, distance=50, npoints=15, do_fit=False, show=False) -> list[Segment]:
698
750
  """Make slices between contours.
@@ -712,8 +764,11 @@ def slice_contours(data, inner, outer, distance=50, npoints=15, do_fit=False, sh
712
764
  A list of Segments.
713
765
 
714
766
  """
715
- global debug_plot
767
+ global debug_plot, __call_id__, __img_num__
716
768
 
769
+ __call_id__ += 1
770
+ __img_num__ = 0
771
+ #show=True
717
772
  segments = []
718
773
  dist = 0
719
774
  npts = len(outer)
@@ -726,7 +781,15 @@ def slice_contours(data, inner, outer, distance=50, npoints=15, do_fit=False, sh
726
781
  U = contours.find_closest(x0, y0, inner)
727
782
  Tmin, Pmin, spread = get_T_profile(data, Point(x0, y0), Point(U[0], U[1]), npts=npoints, do_fit=do_fit, debug=False)
728
783
  if show:
729
- show_profile(debug_plot)
784
+ show_profile(debug_plot, "Dist {:.3f}, Tmin {:.2f} ({:.1f}, {:.1f})".format(dist, Tmin[0], Pmin[0].x, Pmin[0].y))
785
+ debug_plot.savefig("Slices", "/tmp/img_{}_{}.png".format(__call_id__, __img_num__))
786
+ __img_num__ += 1
787
+ try:
788
+ ax = debug_plot.get_ax("Contours")
789
+ ax.plot([x0, U[0]], [y0, U[1]], '-')
790
+ ax.plot(Pmin[0].x, Pmin[0].y, 'o')
791
+ except KeyError:
792
+ pass
730
793
 
731
794
  # store results: distance along segment and temperature
732
795
  T = []
@@ -764,7 +827,16 @@ def slice_contours(data, inner, outer, distance=50, npoints=15, do_fit=False, sh
764
827
 
765
828
  segments.append(Segment((x0, y0), V, Pmin, path_length, Tmin, spread))
766
829
  if show:
767
- show_profile(debug_plot)
830
+ show_profile(debug_plot, "Dist {:.3f} Tmin {:.2f} ({:.1f}, {:.1f})".format(path_length, Tmin[0], Pmin[0].x, Pmin[0].y))
831
+ debug_plot.savefig("Slices", "/tmp/img_{}_{}.png".format(__call_id__, __img_num__))
832
+ __img_num__ += 1
833
+
834
+ try:
835
+ ax = debug_plot.get_ax("Contours")
836
+ ax.plot([x0, V[0]], [y0, V[1]], '-')
837
+ ax.plot(Pmin[0].x, Pmin[0].y, 'o')
838
+ except KeyError:
839
+ pass
768
840
 
769
841
  dist = 0
770
842
 
@@ -772,6 +844,7 @@ def slice_contours(data, inner, outer, distance=50, npoints=15, do_fit=False, sh
772
844
  if show:
773
845
  debug_plot.setup_debug("SlicePipe")
774
846
  debug_plot.plot("SlicePipe", D, T, '-o')
847
+ debug_plot.savefig("SlicePipe", "/tmp/slice_pipe_{}.png".format(__call_id__))
775
848
 
776
849
  return segments
777
850
 
@@ -829,10 +902,12 @@ def find_image_contours(data, params):
829
902
  print("contour area: {:.3f}".format(area))
830
903
 
831
904
  if params.debug:
905
+ debug_plot.setup_debug("Contours", 1, 1)
832
906
  colors = ["#ff9b54", "#ff7f51"] # ["#540b0e", "#9e2a2b"]
833
907
  print("Number of countours:", len(out))
834
908
 
835
- fig, ax = plt.subplots(1, 1, tight_layout=True)
909
+ ax = debug_plot.get_ax("Contours")
910
+ ax.clear()
836
911
  ax.imshow(data, origin='lower', cmap='jet')
837
912
  for i, cnt in enumerate(out):
838
913
  ax.plot(cnt[:, 0], cnt[:, 1], linewidth=3, color=colors[i % 2])
@@ -870,6 +945,7 @@ def get_segments(data, params) -> list[Segment]:
870
945
  list of segments. See `slice_contours`
871
946
 
872
947
  """
948
+ global the_3d_points
873
949
  cntrs = find_image_contours(data, params)
874
950
  if cntrs is None:
875
951
  return None
@@ -881,6 +957,7 @@ def get_segments(data, params) -> list[Segment]:
881
957
  do_fit=params.do_fit,
882
958
  show=params.debug)
883
959
 
960
+ the_3d_points = Segment.get_3d_points_in_list(the_segments)
884
961
  return the_segments
885
962
 
886
963
 
@@ -12,7 +12,7 @@ class IRPetalParam(object):
12
12
  values: ArgParser or dict with user values-
13
13
 
14
14
  """
15
- self.institute = 'IFIC' # Either IFIC or DESY to treat the different files
15
+ self.institute = None # Either IFIC or DESY to treat the different files
16
16
  self.thrs = -22.0 # the threshold
17
17
  self.tco2 = -35.0 # Inlet temperature
18
18
  self.gauss_size = 15 # Radius of gausian filtering
@@ -30,7 +30,7 @@ class AnalysisResult(object):
30
30
  continue
31
31
 
32
32
 
33
- def show_2D_image(img, title=None):
33
+ def show_2D_image(img, title=None, show_fig=True):
34
34
  """Show a 2D image."""
35
35
  if isinstance(img, list):
36
36
  fig, ax = plt.subplots(1, len(img))
@@ -51,8 +51,9 @@ def show_2D_image(img, title=None):
51
51
  pcm = ax.imshow(img, origin='lower', cmap=HighContrast.reversed()) # cmap="jet")
52
52
  fig.colorbar(pcm, ax=ax)
53
53
 
54
- plt.draw()
55
- plt.pause(0.001)
54
+ if show_fig:
55
+ plt.draw()
56
+ plt.pause(0.001)
56
57
 
57
58
  return fig, ax
58
59
 
@@ -413,6 +413,14 @@ class PipeFit(object):
413
413
  """
414
414
  if M0 is None:
415
415
  M = self.initial_guess(data)
416
+ for i, val in enumerate(M):
417
+ if val < self.bounds[0][i]:
418
+ val = 1.01 * self.bounds[0][i]
419
+ M[i] = val
420
+ elif val > self.bounds[1][i]:
421
+ val = 0.99 * self.bounds[0][i]
422
+ M[i] = val
423
+
416
424
  if self.debug:
417
425
  print("\n** Initial guess")
418
426
  self.print_transform(M)
@@ -498,7 +506,7 @@ class PipeFit(object):
498
506
 
499
507
  return X, Y
500
508
 
501
- def plot(self):
509
+ def plot(self, show_fig=True):
502
510
  """Plot result of fit and data."""
503
511
  fig, ax = plt.subplots(1, 1, tight_layout=True)
504
512
  ax.plot(self.pipe[:, 0], self.pipe[:, 1], label="Pipe")
@@ -509,8 +517,9 @@ class PipeFit(object):
509
517
 
510
518
  ax.plot(out[:, 0], out[:, 1], 'o', label="Data")
511
519
  ax.legend()
512
- plt.draw()
513
- plt.pause(0.0001)
520
+ if show_fig:
521
+ plt.draw()
522
+ plt.pause(0.0001)
514
523
  return fig, ax
515
524
 
516
525