petal-qc 0.0.15__py3-none-any.whl → 0.0.17__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.
Files changed (32) hide show
  1. petal_qc/BTreport/CheckBTtests.py +92 -33
  2. petal_qc/BTreport/bustapeReport.py +2 -1
  3. petal_qc/__init__.py +7 -2
  4. petal_qc/{test/getPetalCoreTestSummary.py → getPetalCoreTestSummary.py} +36 -14
  5. petal_qc/metrology/PetalMetrology.py +0 -13
  6. petal_qc/metrology/compare_Cores.py +44 -0
  7. petal_qc/metrology/coreMetrology.py +0 -12
  8. petal_qc/metrology/do_Metrology.py +0 -13
  9. petal_qc/metrology/petal_flatness.py +0 -13
  10. petal_qc/metrology/readAVSdata.py +2 -0
  11. petal_qc/metrology/uploadPetalInformation.py +20 -20
  12. petal_qc/test/analyzeMetrologyTable.py +119 -0
  13. petal_qc/test/checkAVStests.py +2 -2
  14. petal_qc/test/checkCoreShipments.py +57 -0
  15. petal_qc/test/createMetrologyTable.py +87 -0
  16. petal_qc/test/getAVStests.py +21 -3
  17. petal_qc/test/prepareDESYfiles.py +2 -1
  18. petal_qc/test/test_Graphana.py +2 -1
  19. petal_qc/thermal/IRPetalParam.py +2 -0
  20. petal_qc/thermal/PipeFit.py +48 -19
  21. petal_qc/thermal/analyze_IRCore.py +34 -24
  22. petal_qc/thermal/contours.py +18 -12
  23. petal_qc/thermal/create_IRCore.py +40 -9
  24. petal_qc/thermal/create_core_report.py +8 -5
  25. petal_qc/thermal/show_IR_petal.py +1 -10
  26. petal_qc/utils/ArgParserUtils.py +41 -0
  27. petal_qc/utils/docx_utils.py +18 -6
  28. {petal_qc-0.0.15.dist-info → petal_qc-0.0.17.dist-info}/METADATA +2 -2
  29. {petal_qc-0.0.15.dist-info → petal_qc-0.0.17.dist-info}/RECORD +32 -28
  30. {petal_qc-0.0.15.dist-info → petal_qc-0.0.17.dist-info}/WHEEL +1 -1
  31. {petal_qc-0.0.15.dist-info → petal_qc-0.0.17.dist-info}/entry_points.txt +1 -0
  32. {petal_qc-0.0.15.dist-info → petal_qc-0.0.17.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env python3
2
+ """Analyze the table generated by createMetrologyTable."""
3
+
4
+ import sys
5
+ from pathlib import Path
6
+ import math
7
+ import argparse
8
+ import pandas as pd
9
+ import numpy as np
10
+ from numpy.linalg import norm
11
+ import matplotlib.pyplot as plt
12
+ from lmfit.models import LinearModel
13
+
14
+ from petal_qc.utils.fit_utils import draw_best_fit
15
+
16
+ def distance(P1, P2, P3):
17
+ C = np.cross(P2-P1, P3-P1)
18
+ D = C/norm(P2-P1)
19
+ return D
20
+
21
+ def remove_outliers_indx(data, cut=2.0, debug=False):
22
+ """Remove points far away form the rest.
23
+
24
+ Args:
25
+ ----
26
+ data : The data
27
+ cut: max allowed distance
28
+ debug: be verbose if True.
29
+
30
+ Returns
31
+ -------
32
+ index of valid pints in data array.
33
+
34
+ """
35
+ d = np.abs(data - np.median(data))
36
+ mdev = np.median(d)
37
+ s = d / (mdev if mdev else 1.)
38
+ indx = np.where(s < cut)[0]
39
+ return indx
40
+
41
+
42
+ def main(options):
43
+ """main entry."""
44
+ fig_width = 12.0
45
+ fig_height = 1.2*fig_width/3.0
46
+
47
+ T = pd.read_csv(options.files[0])
48
+
49
+ if options.mould > 0:
50
+ x = 1000*T.loc[T['mould'] == options.mould, 'fd_dx'].values
51
+ y = 1000*T.loc[T['mould'] == options.mould, 'fd_dy'].values
52
+
53
+ else:
54
+ x = 1000*T['fd_dx'].values
55
+ y = 1000*T['fd_dy'].values
56
+
57
+ fig, ax = plt.subplots(nrows=1, ncols=3, tight_layout=True, figsize=(fig_width, fig_height))
58
+ fig.suptitle("Relative Position FD01-FD02")
59
+ ax[0].set_title("FD01-FD02")
60
+ ax[0].set_aspect('equal', adjustable='box')
61
+ ax[0].set_xlim(-150, 150)
62
+ ax[0].set_ylim(-150, 150)
63
+ circle = plt.Circle((0,0), 75, color="red", alpha=0.25)
64
+ ax[0].add_patch(circle)
65
+ circle = plt.Circle((0,0), 25, color="green", alpha=0.25)
66
+ ax[0].add_patch(circle)
67
+
68
+ ax[0].set_xlabel("X (µm)")
69
+ ax[0].set_ylabel("Y (µm)")
70
+ ax[0].grid()
71
+
72
+ ax[0].scatter(x, y, marker='.')
73
+
74
+ model = LinearModel()
75
+ params = model.guess(y, x=x)
76
+ result = model.fit(y, params, x=x)
77
+
78
+
79
+ P1 = np.array([0, result.eval(x=0)])
80
+ P2 = np.array([1, result.eval(x=1)])
81
+ values = []
82
+ for v, w in zip(x, y):
83
+ P3 = np.array([v, w])
84
+ values.append(distance(P1, P2, P3))
85
+
86
+ indx = remove_outliers_indx(values)
87
+
88
+ xx = x[indx]
89
+ yy = y[indx]
90
+ params = model.guess(yy, xx)
91
+ result = model.fit(yy, params, x=xx)
92
+ result.plot_fit(ax=ax[0])
93
+ print("slope {:.5f}, intercept {:.5f}".format(result.best_values['slope'], result.best_values["intercept"]))
94
+ angle = 180*math.atan( result.best_values['slope'])/math.pi
95
+ print("angle {:.5f} deg.".format(angle))
96
+
97
+ ax[1].set_xlim(-150, 150)
98
+ ax[1].set_xlabel("X (µm)")
99
+ ax[1].grid()
100
+ ax[1].hist(x)
101
+
102
+ ax[2].set_xlim(-150, 150)
103
+ ax[2].set_xlabel("Y (µm)")
104
+ ax[2].grid()
105
+ ax[2].hist(y)
106
+
107
+ plt.show()
108
+
109
+ if __name__ == "__main__":
110
+ parser = argparse.ArgumentParser()
111
+ parser.add_argument('files', nargs='*', help="Input files")
112
+ parser.add_argument('--mould', default=-1, type=int, help="mould index")
113
+
114
+ opts = parser.parse_args()
115
+ if len(opts.files) == 0:
116
+ print("I need at least one input file")
117
+ sys.exit()
118
+
119
+ main(opts)
@@ -169,8 +169,8 @@ if __name__ == "__main__":
169
169
  client = dlg.get_client()
170
170
 
171
171
  try:
172
- # main(session)
173
- the_test = analyze_avs_metrology(client, "20USEBC1000124", "PPC.015")
172
+ main(client)
173
+ # the_test = analyze_avs_metrology(client, "20USEBC1000124", "PPC.015")
174
174
  #rc = ITkDButils.upload_test(client, the_test, check_runNumber=True)
175
175
  #if rc:
176
176
  # print(rc)
@@ -0,0 +1,57 @@
1
+ """List shipments."""
2
+ import sys
3
+ from pathlib import Path
4
+ import numpy as np
5
+
6
+ from itkdb_gtk import ITkDBlogin, ITkDButils
7
+
8
+
9
+ def main(session):
10
+ """List shipments from AVS to CERN and IFIC containing CORES."""
11
+
12
+ payload = {
13
+ "filterMap": {
14
+ "sender": "AVS",
15
+ "recipient": ["CERN", "IFIC"],
16
+ "status": "delivered"
17
+ }
18
+ }
19
+ shpmts = session.get("listShipmentsByInstitution", json=payload)
20
+ for s in shpmts:
21
+ items = session.get("listShipmentItems", json={"shipment": s["id"]})
22
+ cores = []
23
+ for it in items:
24
+ if it["component"]["componentType"]['code'] == "CORE_PETAL":
25
+ if "PPC." in it["component"]["alternativeIdentifier"]:
26
+ cores.append(it["component"]["alternativeIdentifier"])
27
+
28
+ if len(cores) == 0:
29
+ continue
30
+
31
+ print("Shipment {}".format(s["name"]))
32
+ print("AVS -> {}".format(s["recipient"]["code"]))
33
+ print(":> {}".format(s["sentTs"]))
34
+ for c in cores:
35
+ print("\t{}".format(c))
36
+
37
+ print("\n")
38
+
39
+ if __name__ == "__main__":
40
+ # ITk_PB authentication
41
+ dlg = ITkDBlogin.ITkDBlogin()
42
+ client = dlg.get_client()
43
+
44
+ try:
45
+ main(client)
46
+ # the_test = analyze_avs_metrology(client, "20USEBC1000124", "PPC.015")
47
+ #rc = ITkDButils.upload_test(client, the_test, check_runNumber=True)
48
+ #if rc:
49
+ # print(rc)
50
+
51
+ except Exception as E:
52
+ print(E)
53
+
54
+ dlg.die()
55
+
56
+
57
+
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env python3
2
+ """Create table for metrology analysis."""
3
+
4
+ import sys
5
+ import re
6
+ import json
7
+ from pathlib import Path
8
+ from argparse import ArgumentParser
9
+ from petal_qc.utils.all_files import all_files
10
+ from petal_qc.utils.ArgParserUtils import RangeListAction
11
+
12
+ r_petal_id = re.compile("PPC.([0-9]*)")
13
+
14
+ db_file = Path("/Users/lacasta/cernbox/workspace/Petal-QC/PetalMould.csv")
15
+
16
+ petal_db = {}
17
+ with open(db_file, "r", encoding="utf-8") as fin:
18
+ for i, line in enumerate(fin):
19
+ if i==0:
20
+ continue
21
+
22
+ values = [x.strip() for x in line.split(",")]
23
+ petal_db[values[0]] = values[1:]
24
+
25
+ def main(options):
26
+ """Main entry."""
27
+ ifolder = Path(options.input)
28
+ if not ifolder.exists():
29
+ print("Input folder does not exist.\n{}".format(ifolder))
30
+ return
31
+
32
+ has_list = len(options.cores) != 0
33
+
34
+ ofile = open(options.out, "w", encoding="utf-8")
35
+ ofile.write("PetalID,SN,side,mould,fd_dx,fd_dy,paralelism,R0,R1,R2,R3S0,R3S1,R4S0,R4S1,R5S0,R5S1,flatness\n")
36
+
37
+ for fnam in all_files(ifolder.as_posix(), "*.json"):
38
+ fstem = fnam.stem
39
+ if "PPC." not in fstem:
40
+ continue
41
+
42
+ R = r_petal_id.search(fstem)
43
+ if R is None:
44
+ continue
45
+
46
+ petal_id = R.group(0)
47
+ pid = int(R.group(1))
48
+
49
+ if has_list and pid not in options.cores:
50
+ continue
51
+
52
+ SN = petal_db[petal_id][0]
53
+ side = 1 if "back" in fstem else 0
54
+ mould = int(petal_db[petal_id][1])
55
+
56
+ data = None
57
+ with open(fnam, "r", encoding="utf-8") as fin:
58
+ data = json.load(fin)
59
+
60
+ ofile.write("{}, {}, {}, {}".format(petal_id, SN, side, mould))
61
+ print("data SN", data["component"])
62
+ D = data["results"]["METROLOGY"]["REL_POS_DELTA"]["FD01-FD02"]
63
+ ofile.write(",{:.5f}, {:.5f}".format(D[0], D[1]))
64
+
65
+ D = data["results"]["METROLOGY"]["PARALLELISM"]
66
+ ofile.write(",{:.5f}".format(D))
67
+
68
+ for x in data["results"]["METROLOGY"]["FLATNESS_LOCAL"]:
69
+ ofile.write(", {:.5f}".format(x))
70
+
71
+ D = data["results"]["METROLOGY"]["FLATNESS_GLOBAL"]
72
+ ofile.write(", {:.5f}".format(D))
73
+
74
+ ofile.write("\n")
75
+
76
+ ofile.close()
77
+
78
+
79
+ if __name__ == "__main__":
80
+ parser = ArgumentParser()
81
+ parser.add_argument("--input-folder", dest="input", default=".", help="Input folder")
82
+ parser.add_argument("--out", default="out.csv", help="Output table.")
83
+ parser.add_argument("--cores", dest="cores", action=RangeListAction, default=[],
84
+ help="Create list of cores to analyze. The list is made with numbers or ranges (ch1:ch2 or ch1:ch2:step) ")
85
+
86
+ opts = parser.parse_args()
87
+ main(opts)
@@ -4,6 +4,7 @@ import sys
4
4
  from pathlib import Path
5
5
  import numpy as np
6
6
  import matplotlib.pyplot as plt
7
+ from argparse import ArgumentParser
7
8
 
8
9
  try:
9
10
  import petal_qc
@@ -14,7 +15,7 @@ except ImportError:
14
15
 
15
16
  from itkdb_gtk import ITkDBlogin
16
17
  import petal_qc.utils.docx_utils as docx_utils
17
-
18
+ from petal_qc.utils.ArgParserUtils import RangeListAction
18
19
 
19
20
 
20
21
  def get_value(results, code):
@@ -171,7 +172,7 @@ def plot_weighing(weights, tick_labels, document, show_total=False):
171
172
  ax.legend(loc="upper left", ncol=4)
172
173
 
173
174
 
174
- def main(session):
175
+ def main(session, options):
175
176
  """Entry point"""
176
177
  # find all cores
177
178
  # Now all the objects
@@ -200,11 +201,16 @@ def main(session):
200
201
  for T in core_tests:
201
202
  counter[T]=0
202
203
 
204
+ mould_db = {}
203
205
  for core in core_list:
204
206
  SN = core["serialNumber"]
205
207
  altid = core['alternativeIdentifier']
206
208
  if "PPC" not in altid:
207
209
  continue
210
+
211
+ pID = int(altid[4:])
212
+ if len(options.cores)>0 and pID not in options.cores:
213
+ continue
208
214
 
209
215
  petal_ids.append(altid)
210
216
  location = core["currentLocation"]['code']
@@ -243,6 +249,7 @@ def main(session):
243
249
  mould_desc = do_manufacturing(good_tests["MANUFACTURING"])
244
250
  pos = mould_desc.rfind('.')
245
251
  mould_id = mould_desc[pos+1:]
252
+ mould_db[altid] = (SN, mould_id)
246
253
  if mould_id not in Mould_values:
247
254
  Mould_values[mould_id] = {}
248
255
 
@@ -302,13 +309,24 @@ def main(session):
302
309
  plot_weighing(weights, petal_ids, document)
303
310
  plot_metrology(M_values, Mould_values, petal_ids, document)
304
311
  document.save("AVStests.docx")
312
+
313
+ with open("mould_db.csv", "w", encoding="utf-8") as fout:
314
+ fout.write("PetalID, SerialNo, MouldID\n")
315
+ for key, val in mould_db.items():
316
+ fout.write("{}, {}, {}\n".format(key, val[0], val[1]))
317
+
305
318
  plt.show()
306
319
 
307
320
  if __name__ == "__main__":
308
321
  # ITk_PB authentication
322
+ parser = ArgumentParser()
323
+ parser.add_argument("--cores", dest="cores", action=RangeListAction, default=[],
324
+ help="Create list of cores to analyze. The list is made with numbers or ranges (ch1:ch2 or ch1:ch2:step) ")
325
+
326
+
309
327
  dlg = ITkDBlogin.ITkDBlogin()
310
328
  session = dlg.get_client()
311
329
 
312
- main(session)
330
+ main(session, options)
313
331
 
314
332
  dlg.die()
@@ -96,7 +96,8 @@ def main(folder, out_folder):
96
96
  data = ""
97
97
  for data_type, fnam in values.items():
98
98
  if fnam is None:
99
- print("This should not happen.")
99
+ print("Missing file name for {} {} [{}]".format(petal_id, side, data_type))
100
+ continue
100
101
 
101
102
  with open(fnam, "r", encoding="UTF-8") as ifile:
102
103
  data += ifile.read()
@@ -19,7 +19,8 @@ from petal_qc.thermal import IRBFile
19
19
 
20
20
 
21
21
  options = IRPetalParam()
22
- options.files = [Path("~/tmp/thermal/PPC.008.irb").expanduser().resolve()]
22
+ options.institute = "IFIC"
23
+ options.files = [Path("~/tmp/thermal/IFIC-thermal/IRB_files/PPC.008.irb").expanduser().resolve()]
23
24
  getter = IRDataGetter.factory(options.institute, options)
24
25
  DB = ReadGraphana("localhost")
25
26
  irbf = IRBFile.open_file(options.files)
@@ -27,6 +27,7 @@ class IRPetalParam(object):
27
27
  self.rotate = True # Rotate to have a vertical petal in mirror image
28
28
  self.debug = False # To debug
29
29
  self.report = False #
30
+ self.graphana = None # Graphana server
30
31
 
31
32
  if values is not None:
32
33
  self.set_values(values)
@@ -61,6 +62,7 @@ class IRPetalParam(object):
61
62
  help="Either IFIC or DESY to treat the different files")
62
63
  parser.add_argument("--thrs", type=float, default=P.thrs, help="Temperature threshold")
63
64
  parser.add_argument("--tco2", type=float, default=P.tco2, help="CO2 Inlet temperature")
65
+ parser.add_argument("--graphana", type=str, default=None, help="Graphana server.")
64
66
  parser.add_argument("--gauss_size", type=int, default=P.gauss_size, help="Radius of gausian filtering")
65
67
  parser.add_argument("--distance", type=float, default=P.distance, help="Distance in contour beteween slices")
66
68
  parser.add_argument("--npoints", type=int, default=P.npoints, help="Number of points per segment")
@@ -8,7 +8,6 @@ from pathlib import Path
8
8
  import matplotlib.path as mplPath
9
9
  import matplotlib.pyplot as plt
10
10
  import numpy as np
11
- import numpy.linalg as linalg
12
11
  from scipy.optimize import least_squares
13
12
 
14
13
  from petal_qc.thermal import contours
@@ -43,6 +42,9 @@ class PipeFit(object):
43
42
  self.bounds = [[-math.pi, 0.8, 0.8, -np.inf, -np.inf],
44
43
  [math.pi, 3.0, 3.0, np.inf, np.inf]]
45
44
 
45
+ self.core_center = None
46
+ self.core_band = None
47
+
46
48
  def set_front(self, is_front=True):
47
49
  """Sets for a front image.
48
50
 
@@ -119,6 +121,7 @@ class PipeFit(object):
119
121
  """
120
122
  DB = np.load(pipe_file)
121
123
  sensors = []
124
+ pipe = []
122
125
  for key, val in DB.items():
123
126
  if key == "pipe":
124
127
  pipe = val
@@ -213,7 +216,7 @@ class PipeFit(object):
213
216
  print("Center {:5.3f}, {:5.3f}".format(M[5], M[6]))
214
217
 
215
218
  @staticmethod
216
- def get_data_center(data, fraction=0.5, y0=None):
219
+ def get_data_center(data, fraction=0.5, y0=None, min_pts=5):
217
220
  """Compute the data center.
218
221
 
219
222
  Assumes it is in the half height, and the X is the average of the points
@@ -221,19 +224,19 @@ class PipeFit(object):
221
224
  """
222
225
  if y0 is None:
223
226
  bounding_box = contours.contour_bounds(data)
224
- y0 = fraction*(bounding_box[1]+bounding_box[3])
227
+ y0 = bounding_box[1] + fraction*(bounding_box[3]-bounding_box[1])
225
228
 
226
229
  window = 10
227
230
  while True:
228
231
  stripe = data[np.abs(data[:, 1] - y0) < window]
229
- if len(stripe) > 5:
232
+ if len(stripe) > min_pts:
230
233
  break
231
234
 
232
235
  window += 1
233
236
 
234
237
  m0 = np.mean(stripe, axis=0)
235
238
  center = np.array([m0[0], y0])
236
- return center
239
+ return center, (np.min(stripe[:, 0]), np.max(stripe[:, 0]))
237
240
 
238
241
  @staticmethod
239
242
  def guess_pipe_type(data, fraction=0.25) -> int:
@@ -256,7 +259,7 @@ class PipeFit(object):
256
259
 
257
260
  D = data[:, 0:2] - P0
258
261
  m0 = np.mean(D, axis=0)
259
- center = PipeFit.get_data_center(D, y0=m0[1])
262
+ center, _ = PipeFit.get_data_center(D, y0=m0[1])
260
263
  # fig, ax = plt.subplots(1,1)
261
264
  # ax.plot(D[:,0], D[:, 1], 'o', label="Data")
262
265
  # ax.plot(center[0], center[1], '*', label="Center")
@@ -273,9 +276,16 @@ class PipeFit(object):
273
276
  @staticmethod
274
277
  def guess_pipe_angle(data, center):
275
278
  """Get an estimation of th epipe angle."""
276
- c1 = PipeFit.get_data_center(data, 0.6)
277
- delta = c1 - center
278
- angle = math.atan(delta[0]/delta[1])
279
+ c1, _ = PipeFit.get_data_center(data, 0.)
280
+ delta = np.abs(c1 - center)
281
+ angle = math.atan(delta[1]/delta[0])
282
+ while angle<0:
283
+ angle += 2.0*math.pi
284
+
285
+ if angle > 1.5*math.pi:
286
+ angle -= math.pi/2.0
287
+
288
+ angle = 0.5*math.pi - angle
279
289
  return angle
280
290
 
281
291
  @staticmethod
@@ -289,8 +299,11 @@ class PipeFit(object):
289
299
 
290
300
  def initial_guess(self, data):
291
301
  """Make a first guess of the transform."""
292
- Mdata = self.get_data_center(data)
302
+ Mdata, _ = self.get_data_center(data)
293
303
  theta = self.guess_pipe_angle(data, Mdata)
304
+ if self.front:
305
+ theta = -theta
306
+
294
307
  T = -Mdata
295
308
  dxd = np.amax(data, axis=0) - np.amin(data, axis=0)
296
309
  dxp = np.amax(self.cpipe, axis=0) - np.amin(self.cpipe, axis=0)
@@ -313,7 +326,11 @@ class PipeFit(object):
313
326
  def get_residuals(self, M):
314
327
  """Compute intersecting area."""
315
328
  out = self.transform_data(self.data, M)
316
- use_area = True
329
+ y_max = np.max(out[:,1])
330
+ y_min = np.min(out[:,1])
331
+
332
+ height = y_max - y_min
333
+ use_area = False
317
334
  if use_area:
318
335
  path = mplPath.Path(out)
319
336
  ngood = 0.0
@@ -327,20 +344,29 @@ class PipeFit(object):
327
344
  real_area = 100*ngood/ntot
328
345
 
329
346
  else:
330
- area = 0.0
331
- real_area = 0
347
+ area = 1.0
348
+ real_area = 1
332
349
 
333
350
  npts = len(self.data)
334
351
  D = np.zeros([npts, 2])
335
352
  ddd = np.zeros(npts)
353
+ sum_weights = 0.0
354
+ weights = np.zeros(npts)
336
355
  for i in range(npts):
337
356
  X = out[i, :]
338
357
  dst, P = contours.find_closest_point(X[0], X[1], self.cpipe)
339
358
  D[i, :] = P - X
340
359
  ddd[i] = dst
360
+ W = 1 + 1.6*(y_max - X[1])/height
361
+ weights[i] = W
362
+ sum_weights += W
341
363
 
342
364
  # return value
343
- res = D.flatten()*area
365
+ if use_area:
366
+ res = D.flatten()*area
367
+
368
+ else:
369
+ res = np.dot(ddd, weights)/sum_weights
344
370
 
345
371
  if self.debug:
346
372
  dbg_ax. clear()
@@ -420,14 +446,17 @@ class PipeFit(object):
420
446
  elif val > self.bounds[1][i]:
421
447
  val = 0.99 * self.bounds[0][i]
422
448
  M[i] = val
423
-
449
+
424
450
  if self.debug:
425
451
  print("\n** Initial guess")
426
452
  self.print_transform(M)
427
453
  else:
428
454
  M = M0
429
455
 
430
- self.data = contours.contour_simplify(data, 1.5*factor)
456
+ self.core_center, self.core_band = self.get_data_center(data)
457
+
458
+
459
+ self.data = contours.contour_simplify(data, 1.25*factor)
431
460
  # self.data = data
432
461
  verbose = 0
433
462
  if self.debug:
@@ -436,7 +465,7 @@ class PipeFit(object):
436
465
  res = least_squares(self.get_residuals, M,
437
466
  method='trf',
438
467
  # ftol=5e-16,
439
- # xtol=None,
468
+ #xtol=1.0e-10,
440
469
  # max_nfev=10000,
441
470
  # diff_step=[0.05, 0.02, 0.02, 50, 50],
442
471
  bounds=self.bounds,
@@ -551,7 +580,7 @@ def main(data_file, opts):
551
580
  ax[0].plot(PF.center[0], PF.center[1], 'o')
552
581
  ax[0].set_title("Pipe")
553
582
 
554
- center = PF.get_data_center(data)
583
+ center, _ = PF.get_data_center(data)
555
584
  ax[1].plot(data[:, 0], data[:, 1])
556
585
  ax[1].plot(center[0], center[1], 'o')
557
586
  ax[1].set_title("Data on IR")
@@ -560,7 +589,7 @@ def main(data_file, opts):
560
589
  plt.figure(fign)
561
590
  out = PF.transform_data(PF.data, R)
562
591
  aout = PF.transform_data(data, R)
563
- center = PF.get_data_center(aout)
592
+ center, _ = PF.get_data_center(aout)
564
593
  ax[2].plot(PF.pipe[:, 0], PF.pipe[:, 1])
565
594
  ax[2].plot(out[:, 0], out[:, 1], 'o')
566
595
  ax[2].plot(center[0], center[1], 'o')