petal-qc 0.0.15__tar.gz → 0.0.16__tar.gz

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 (83) hide show
  1. {petal_qc-0.0.15 → petal_qc-0.0.16}/PKG-INFO +1 -1
  2. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/__init__.py +6 -1
  3. {petal_qc-0.0.15/petal_qc/test → petal_qc-0.0.16/petal_qc}/getPetalCoreTestSummary.py +28 -6
  4. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/PetalMetrology.py +0 -13
  5. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/compare_Cores.py +44 -0
  6. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/coreMetrology.py +0 -12
  7. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/do_Metrology.py +0 -13
  8. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/petal_flatness.py +0 -13
  9. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/readAVSdata.py +2 -0
  10. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/uploadPetalInformation.py +17 -17
  11. petal_qc-0.0.16/petal_qc/test/analyzeMetrologyTable.py +119 -0
  12. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/checkAVStests.py +2 -2
  13. petal_qc-0.0.16/petal_qc/test/createMetrologyTable.py +87 -0
  14. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/getAVStests.py +8 -0
  15. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/prepareDESYfiles.py +2 -1
  16. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/show_IR_petal.py +1 -10
  17. petal_qc-0.0.16/petal_qc/utils/ArgParserUtils.py +41 -0
  18. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc.egg-info/PKG-INFO +1 -1
  19. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc.egg-info/SOURCES.txt +4 -1
  20. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc.egg-info/entry_points.txt +1 -0
  21. {petal_qc-0.0.15 → petal_qc-0.0.16}/pyproject.toml +2 -1
  22. {petal_qc-0.0.15 → petal_qc-0.0.16}/README.md +0 -0
  23. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/BTreport/CheckBTtests.py +0 -0
  24. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/BTreport/__init__.py +0 -0
  25. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/BTreport/bustapeReport.py +0 -0
  26. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/PetalReceptionTests.py +0 -0
  27. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/dashBoard.py +0 -0
  28. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/Cluster.py +0 -0
  29. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/DataFile.py +0 -0
  30. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/__init__.py +0 -0
  31. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/all2csv.py +0 -0
  32. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/analyze_locking_points.py +0 -0
  33. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/cold_noise.py +0 -0
  34. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/comparisonTable.py +0 -0
  35. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/convert_mitutoyo.py +0 -0
  36. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/convert_smartscope.py +0 -0
  37. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/data2csv.py +0 -0
  38. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/flatness4nigel.py +0 -0
  39. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/gtkutils.py +0 -0
  40. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/show_data_file.py +0 -0
  41. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/testSummary.py +0 -0
  42. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/metrology/test_paralelism.py +0 -0
  43. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/compare_golden.py +0 -0
  44. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/createMetrologyFile.py +0 -0
  45. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/desyModuleBow.py +0 -0
  46. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/findRawData.py +0 -0
  47. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/getAVSjson.py +0 -0
  48. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/listPetalCoreComponents.py +0 -0
  49. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/reportFromJSon.py +0 -0
  50. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/test_Graphana.py +0 -0
  51. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/test/test_coreThermal.py +0 -0
  52. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/CSVImage.py +0 -0
  53. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/DESYdata.py +0 -0
  54. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/DebugPlot.py +0 -0
  55. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/IRBFile.py +0 -0
  56. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/IRCore.py +0 -0
  57. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/IRDataGetter.py +0 -0
  58. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/IRPetal.py +0 -0
  59. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/IRPetalParam.py +0 -0
  60. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/PetalColorMaps.py +0 -0
  61. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/Petal_IR_Analysis.py +0 -0
  62. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/PipeFit.py +0 -0
  63. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/__init__.py +0 -0
  64. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/analyze_IRCore.py +0 -0
  65. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/contours.py +0 -0
  66. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/coreThermal.py +0 -0
  67. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/create_IRCore.py +0 -0
  68. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/create_core_report.py +0 -0
  69. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/pipe_back.npz +0 -0
  70. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/pipe_front.npz +0 -0
  71. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/thermal/pipe_read.py +0 -0
  72. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/Geometry.py +0 -0
  73. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/Progress.py +0 -0
  74. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/__init__.py +0 -0
  75. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/all_files.py +0 -0
  76. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/docx_utils.py +0 -0
  77. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/fit_utils.py +0 -0
  78. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/readGraphana.py +0 -0
  79. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc/utils/utils.py +0 -0
  80. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc.egg-info/dependency_links.txt +0 -0
  81. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc.egg-info/requires.txt +0 -0
  82. {petal_qc-0.0.15 → petal_qc-0.0.16}/petal_qc.egg-info/top_level.txt +0 -0
  83. {petal_qc-0.0.15 → petal_qc-0.0.16}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: petal_qc
3
- Version: 0.0.15
3
+ Version: 0.0.16
4
4
  Summary: A collection of scripts for Petal CORE QC.
5
5
  Author-email: Carlos Lacasta <carlos.lacasta@cern.ch>
6
6
  Project-URL: Homepage, https://gitlab.cern.ch/atlas-itk/sw/db/itk-pdb-gtk-gui-utils
@@ -1,5 +1,5 @@
1
1
  """petal_qc python module."""
2
- __version__ = "0.0.15"
2
+ __version__ = "0.0.16"
3
3
 
4
4
 
5
5
  def coreMetrology():
@@ -48,6 +48,11 @@ def petalReceptionTests():
48
48
  from .PetalReceptionTests import main
49
49
  main()
50
50
 
51
+ def petalCoreTestSummary():
52
+ """GND/VI tests."""
53
+ from .getPetalCoreTestSummary import main
54
+ main()
55
+
51
56
  def dashBoard():
52
57
  """Launches the Core thermal analysis ahd PDB script."""
53
58
  from .dashBoard import main
@@ -1,20 +1,26 @@
1
1
  #!/usr/bin/env python3
2
2
  """Get a summery of Petal core TEsts."""
3
3
  import json
4
+ import sys
5
+ import re
6
+ from argparse import ArgumentParser
7
+
8
+
9
+ from pathlib import Path
4
10
  try:
5
11
  import itkdb_gtk
6
12
 
7
13
  except ImportError:
8
- import sys
9
- from pathlib import Path
10
14
  cwd = Path(__file__).parent.parent
11
15
  sys.path.append(cwd.as_posix())
12
16
 
13
17
  from itkdb_gtk import ITkDBlogin, ITkDButils
14
18
  from itkdb_gtk.dbGtkUtils import replace_in_container, DictDialog, ask_for_confirmation
19
+ from petal_qc.utils.ArgParserUtils import RangeListAction
15
20
 
21
+ r_petal_id = re.compile("PPC.([0-9]*)")
16
22
 
17
- def main(session, options):
23
+ def petalCoreTest(session, options):
18
24
  """Main entry point."""
19
25
 
20
26
  # find all cores
@@ -42,12 +48,23 @@ def main(session, options):
42
48
  #do_check_stage = None
43
49
  petal_id_db = {}
44
50
 
51
+ has_list = len(options.cores) != 0
52
+
45
53
  for core in core_list:
46
54
  SN = core["serialNumber"]
47
55
  altid = core['alternativeIdentifier']
48
56
  if "PPC" not in altid:
49
57
  continue
50
58
 
59
+ R = r_petal_id.search(altid)
60
+ if R is None:
61
+ continue
62
+
63
+ pid = int(R.group(1))
64
+
65
+ if has_list and pid not in options.cores:
66
+ continue
67
+
51
68
  petal_id_db[altid] = SN
52
69
  location = core["currentLocation"]['code']
53
70
  coreStage = core["currentStage"]['code']
@@ -82,10 +99,12 @@ def main(session, options):
82
99
  with open("petal_ID_db_{}.json".format(suff), "w", encoding="utf-8") as fOut:
83
100
  json.dump(petal_id_db, fOut, indent=3)
84
101
 
85
- if __name__ == "__main__":
86
- from argparse import ArgumentParser
102
+ def main():
103
+ """Main entry"""
87
104
  parser = ArgumentParser()
88
105
  parser.add_argument("--institute", default=None, help="The petal current location")
106
+ parser.add_argument("--cores", dest="cores", action=RangeListAction, default=[],
107
+ help="Create list of cores to analyze. The list is made with numbers or ranges (ch1:ch2 or ch1:ch2:step) ")
89
108
  options = parser.parse_args()
90
109
 
91
110
  # ITk_PB authentication
@@ -93,10 +112,13 @@ if __name__ == "__main__":
93
112
  session = dlg.get_client()
94
113
 
95
114
  try:
96
- main(session, options)
115
+ petalCoreTest(session, options)
97
116
 
98
117
  except Exception as E:
99
118
  print(E)
100
119
 
101
120
  dlg.die()
121
+
122
+ if __name__ == "__main__":
123
+ main()
102
124
 
@@ -45,19 +45,6 @@ def check_spec(val, nom, fraction=0.0):
45
45
  rc = val <= (1+fraction)*nom
46
46
  return rc
47
47
 
48
-
49
- class CommaSeparatedListAction(Action):
50
- """Create a list from the comma sepparated numbers at imput."""
51
-
52
- def __call__(self, args_parser, namespace, values, option_string=None):
53
- """The actual action."""
54
- value = np.array(list(map(float, values.split(','))), dtype='float64')
55
- if value.shape[0] < 3:
56
- raise ValueError("{} needs a 3D vector".format(self.dest))
57
-
58
- setattr(namespace, self.dest, value)
59
-
60
-
61
48
  def petal_metrology(ifile, options):
62
49
  """Do the analysis of the petal metrology data.
63
50
 
@@ -2,6 +2,8 @@
2
2
  """Compare quantities."""
3
3
 
4
4
  import sys
5
+ import re
6
+
5
7
  import argparse
6
8
  import glob
7
9
  import json
@@ -10,6 +12,33 @@ from pathlib import Path
10
12
  import numpy as np
11
13
  import matplotlib.pyplot as plt
12
14
 
15
+ r_petal_id = re.compile("PPC.([0-9]*)")
16
+
17
+ class PetalCoreListAction(argparse.Action):
18
+ """Create a list from the comma sepparated numbers at imput."""
19
+
20
+ def __call__(self, parser, namespace, values, option_string=None):
21
+ """The actual action."""
22
+ value = []
23
+ for V in values.split(','):
24
+ try:
25
+ value.append(int(V))
26
+ except ValueError:
27
+ if ':' not in V:
28
+ continue
29
+
30
+ items = V.split(':')
31
+ if len(items)==1:
32
+ continue
33
+
34
+ ival = list(map(int, items))
35
+ ival[1] += 1
36
+ for x in range(*ival):
37
+ value.append(int(x))
38
+
39
+
40
+ setattr(namespace, self.dest, value)
41
+
13
42
 
14
43
  def get_value(data, value_path):
15
44
  """Get the value from the path given."""
@@ -59,12 +88,25 @@ def read_data_files(options):
59
88
  front = {}
60
89
  back = {}
61
90
 
91
+ has_list = len(options.cores) != 0
92
+
62
93
  for fnam in options.files:
63
94
  ifile = Path(fnam).expanduser().resolve()
64
95
  if not ifile.exists():
65
96
  print("File does not exist: ", fnam)
66
97
  continue
67
98
 
99
+ R = r_petal_id.search(fnam)
100
+ if R is None:
101
+ continue
102
+
103
+ petal_id = R.group(0)
104
+ pid = int(R.group(1))
105
+
106
+ if has_list and pid not in options.cores:
107
+ continue
108
+
109
+
68
110
  data = None
69
111
  with open(ifile, 'r', encoding="UTF-8") as fp:
70
112
  data = json.load(fp)
@@ -251,6 +293,8 @@ if __name__ == "__main__":
251
293
  parser.add_argument("--out", default=None, help="File to store the figure.")
252
294
  parser.add_argument("--no-legend", dest="no_legend", default=False, action="store_true", help="Do not draw the legend")
253
295
  parser.add_argument("--no-show", dest="no_show", default=False, action="store_true", help="Do not show the figure")
296
+ parser.add_argument("--cores", dest="cores", action=PetalCoreListAction, default=[],
297
+ help="Create list of cores to analyze. The list is made with numbers or ranges (ch1:ch2 or ch1:ch2:step) ")
254
298
 
255
299
  opts = parser.parse_args()
256
300
  if len(opts.files) == 0:
@@ -18,18 +18,6 @@ from gi.repository import Gtk, GObject, Gio, GLib
18
18
 
19
19
  __HELP__ = "https://petal-qc.docs.cern.ch/metrology.html"
20
20
 
21
- class CommaSeparatedListAction(Action):
22
- """Create a list from the comma sepparated numbers at imput."""
23
-
24
- def __call__(self, parser, namespace, values, option_string=None):
25
- """The actual action."""
26
- value = np.array(list(map(float, values.split(','))), dtype='float64')
27
- if value.shape[0] < 3:
28
- raise ValueError("{} needs a 3D vector".format(self.dest))
29
-
30
- setattr(namespace, self.dest, value)
31
-
32
-
33
21
  class CoreMetrology(itkdb_gtk.dbGtkUtils.ITkDBWindow):
34
22
  """Application window."""
35
23
 
@@ -23,21 +23,8 @@ except ImportError:
23
23
  sys.path.append(cwd.as_posix())
24
24
 
25
25
  from petal_qc.utils.utils import output_folder
26
-
27
26
  from petal_qc.metrology.PetalMetrology import petal_metrology
28
27
 
29
-
30
- class CommaSeparatedListAction(Action):
31
- """Create a list from the comma sepparated numbers at imput."""
32
-
33
- def __call__(self, parser, namespace, values, option_string=None):
34
- """The actual action."""
35
- value = np.array(list(map(float, values.split(','))), dtype='float64')
36
- if value.shape[0] < 3:
37
- raise Exception("{} needs a 3D vector".format(self.dest))
38
-
39
- setattr(namespace, self.dest, value)
40
-
41
28
  def do_analysis(fnam, prefix, SN, options):
42
29
  """Perform analysis of a file.
43
30
 
@@ -31,19 +31,6 @@ from .show_data_file import show_data, TOP_VIEW
31
31
 
32
32
  figure_width = 14
33
33
 
34
-
35
- class CommaSeparatedListAction(Action):
36
- """Create a list from the comma sepparated numbers at imput."""
37
-
38
- def __call__(self, parser, namespace, values, option_string=None):
39
- """The actual action."""
40
- value = np.array(list(map(float, values.split(','))), dtype='float64')
41
- if value.shape[0] < 3:
42
- raise Exception("{} needs a 3D vector".format(self.dest))
43
-
44
- setattr(namespace, self.dest, value)
45
-
46
-
47
34
  def plot_sensor(Spoints, ax, marker='o', cmap='magma'):
48
35
  """Plot the points given in a scatter plot."""
49
36
  ax.scatter(Spoints[:, 0], Spoints[:, 1], Spoints[:, 2],
@@ -696,6 +696,8 @@ def readProductionSheet(session, file_path, SN):
696
696
  manufacturing["results"]["LOCATOR_B"] = sheet["{}{}".format(id_col, i_items+3)].value
697
697
  manufacturing["results"]["LOCATOR_C"] = sheet["{}{}".format(id_col, i_items+4)].value
698
698
  manufacturing["results"]["HONEYCOMBSET"] = split_comp_list( sheet["{}{}".format(id_col, i_items+5)].value)
699
+ manufacturing["results"]["HONEYCOMBSET"] = [ str(x) for x in manufacturing["results"]["HONEYCOMBSET"]]
700
+
699
701
  manufacturing["results"]["EPOXY_ADHESIVE"] = split_comp_list(sheet["{}{}".format(id_col, i_items+8)].value)
700
702
  manufacturing["results"]["EPOXY_PUTTY"] = split_comp_list( sheet["{}{}".format(id_col, i_items+9)].value)
701
703
  manufacturing["results"]["EPOXY_CONDUCTIVE"] = split_comp_list( sheet["{}{}".format(id_col, i_items+10)].value)
@@ -537,6 +537,23 @@ class AVSPanel(dbGtkUtils.ITkDBWindow):
537
537
  if self.petal_core is None:
538
538
  return
539
539
 
540
+ this_petal = self.SN.get_text()
541
+ # Check for HonneyComb set
542
+ for P in self.petal_core["properties"]:
543
+ if P["code"] == "HC_ID" and P["value"] is None:
544
+ if dbGtkUtils.is_iterable(components["HoneyCombSet"]):
545
+ val = ','.join([str(x) for x in components["HoneyCombSet"]])
546
+ else:
547
+ val = str(components["HoneyCombSet"])
548
+ rc = ITkDButils.set_component_property(self.session,
549
+ this_petal,
550
+ "HC_ID",
551
+ val)
552
+ if rc is None:
553
+ error_txt.append("Problems setting HoneyCombSet ID.\n")
554
+
555
+ break
556
+
540
557
  comp_map = {
541
558
  "BT_PETAL_FRONT": "FacingFront",
542
559
  "BT_PETAL_BACK": "FacingBack",
@@ -565,7 +582,6 @@ class AVSPanel(dbGtkUtils.ITkDBWindow):
565
582
  error_txt = []
566
583
  txt = "Click OK to add\n\t{}".format("\n\t".join(missing))
567
584
  if dbGtkUtils.ask_for_confirmation("Missing components", txt, parent=self):
568
- this_petal = self.SN.get_text()
569
585
  for cmp in missing:
570
586
  SN = components[comp_map[cmp]]
571
587
  if SN[0:5] == "20USE":
@@ -582,22 +598,6 @@ class AVSPanel(dbGtkUtils.ITkDBWindow):
582
598
  if rc is None:
583
599
  print("Could not set final stage of {} [{}]".format(ctype, SN))
584
600
 
585
- # Check for HonneyComb set
586
- for P in self.petal_core["properties"]:
587
- if P["code"] == "HC_ID" and P["value"] is None:
588
- if dbGtkUtils.is_iterable(components["HoneyCombSet"]):
589
- val = ' '.join(components["HoneyCombSet"])
590
- else:
591
- val = str(components["HoneyCombSet"])
592
- rc = ITkDButils.set_component_property(self.session,
593
- this_petal,
594
- "HC_ID",
595
- val)
596
- if rc is None:
597
- error_txt.append("Problems setting HoneyCombSet ID.\n")
598
-
599
- break
600
-
601
601
  # Check the final stage of the assembled objects
602
602
  # for child in self.petal_core["children"]:
603
603
  # if child["component"]:
@@ -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,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)
@@ -200,6 +200,7 @@ def main(session):
200
200
  for T in core_tests:
201
201
  counter[T]=0
202
202
 
203
+ mould_db = {}
203
204
  for core in core_list:
204
205
  SN = core["serialNumber"]
205
206
  altid = core['alternativeIdentifier']
@@ -243,6 +244,7 @@ def main(session):
243
244
  mould_desc = do_manufacturing(good_tests["MANUFACTURING"])
244
245
  pos = mould_desc.rfind('.')
245
246
  mould_id = mould_desc[pos+1:]
247
+ mould_db[altid] = (SN, mould_id)
246
248
  if mould_id not in Mould_values:
247
249
  Mould_values[mould_id] = {}
248
250
 
@@ -302,6 +304,12 @@ def main(session):
302
304
  plot_weighing(weights, petal_ids, document)
303
305
  plot_metrology(M_values, Mould_values, petal_ids, document)
304
306
  document.save("AVStests.docx")
307
+
308
+ with open("mould_db.csv", "w", encoding="utf-8") as fout:
309
+ fout.write("PetalID, SerialNo, MouldID\n")
310
+ for key, val in mould_db.items():
311
+ fout.write("{}, {}, {}\n".format(key, val[0], val[1]))
312
+
305
313
  plt.show()
306
314
 
307
315
  if __name__ == "__main__":
@@ -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()
@@ -24,21 +24,12 @@ from petal_qc.thermal import contours
24
24
  from petal_qc.thermal import IRBFile
25
25
  from petal_qc.thermal import IRPetal
26
26
  from petal_qc.thermal import PipeFit
27
- from petal_qc.thermal.Petal_IR_Analysis import AnalysisResult
28
27
  from petal_qc.thermal.Petal_IR_Analysis import show_2D_image
29
28
  from petal_qc.thermal.PetalColorMaps import HighContrast
30
29
 
31
30
  import petal_qc.utils.Progress as Progress
32
31
  import petal_qc.utils.utils as utils
33
-
34
-
35
- class CommaSeparatedListAction(Action):
36
- """Create a list from the comma sepparated numbers at imput."""
37
-
38
- def __call__(self, parser, namespace, values, option_string=None):
39
- """The actual action."""
40
- setattr(namespace, self.dest, list(map(int, values.split(','))))
41
-
32
+ from petal_qc.utils.ArgParserUtils import CommaSeparatedListAction
42
33
 
43
34
  def get_min_max(values, step=1.0):
44
35
  """Return min and max.
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env python3
2
+ """A number of utilities for argument parser."""
3
+
4
+ from argparse import Action
5
+
6
+ class CommaSeparatedListAction(Action):
7
+ """Create a list from the comma sepparated numbers at imput."""
8
+
9
+ def __call__(self, parser, namespace, values, option_string=None):
10
+ """The actual action."""
11
+ setattr(namespace, self.dest, list(map(int, values.split(','))))
12
+
13
+
14
+ class RangeListAction(Action):
15
+ """Create a list from a range expresion at input.
16
+
17
+ The list is made with numbers or ranges (ch1:ch2 or ch1:ch2:step)
18
+ """
19
+
20
+ def __call__(self, parser, namespace, values, option_string=None):
21
+ """The actual action."""
22
+ value = []
23
+ for V in values.split(','):
24
+ try:
25
+ value.append(int(V))
26
+ except ValueError:
27
+ if ':' not in V:
28
+ continue
29
+
30
+ items = V.split(':')
31
+ if len(items)==1:
32
+ continue
33
+
34
+ ival = list(map(int, items))
35
+ ival[1] += 1
36
+ for x in range(*ival):
37
+ value.append(int(x))
38
+
39
+
40
+ setattr(namespace, self.dest, value)
41
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: petal_qc
3
- Version: 0.0.15
3
+ Version: 0.0.16
4
4
  Summary: A collection of scripts for Petal CORE QC.
5
5
  Author-email: Carlos Lacasta <carlos.lacasta@cern.ch>
6
6
  Project-URL: Homepage, https://gitlab.cern.ch/atlas-itk/sw/db/itk-pdb-gtk-gui-utils
@@ -3,6 +3,7 @@ pyproject.toml
3
3
  petal_qc/PetalReceptionTests.py
4
4
  petal_qc/__init__.py
5
5
  petal_qc/dashBoard.py
6
+ petal_qc/getPetalCoreTestSummary.py
6
7
  petal_qc.egg-info/PKG-INFO
7
8
  petal_qc.egg-info/SOURCES.txt
8
9
  petal_qc.egg-info/dependency_links.txt
@@ -35,14 +36,15 @@ petal_qc/metrology/show_data_file.py
35
36
  petal_qc/metrology/testSummary.py
36
37
  petal_qc/metrology/test_paralelism.py
37
38
  petal_qc/metrology/uploadPetalInformation.py
39
+ petal_qc/test/analyzeMetrologyTable.py
38
40
  petal_qc/test/checkAVStests.py
39
41
  petal_qc/test/compare_golden.py
40
42
  petal_qc/test/createMetrologyFile.py
43
+ petal_qc/test/createMetrologyTable.py
41
44
  petal_qc/test/desyModuleBow.py
42
45
  petal_qc/test/findRawData.py
43
46
  petal_qc/test/getAVSjson.py
44
47
  petal_qc/test/getAVStests.py
45
- petal_qc/test/getPetalCoreTestSummary.py
46
48
  petal_qc/test/listPetalCoreComponents.py
47
49
  petal_qc/test/prepareDESYfiles.py
48
50
  petal_qc/test/reportFromJSon.py
@@ -69,6 +71,7 @@ petal_qc/thermal/pipe_back.npz
69
71
  petal_qc/thermal/pipe_front.npz
70
72
  petal_qc/thermal/pipe_read.py
71
73
  petal_qc/thermal/show_IR_petal.py
74
+ petal_qc/utils/ArgParserUtils.py
72
75
  petal_qc/utils/Geometry.py
73
76
  petal_qc/utils/Progress.py
74
77
  petal_qc/utils/__init__.py
@@ -6,6 +6,7 @@ coreMetrologyTTY = petal_qc:coreMetrologyTTY
6
6
  coreThermal = petal_qc:coreThermal
7
7
  createCoreThermalReport = petal_qc:createCoreThermalReport
8
8
  doMetrology = petal_qc:doMetrology
9
+ petalCoreTestSummary = petal_qc:petalCoreTestSummary
9
10
  petalReceptionTests = petal_qc:petalReceptionTests
10
11
  petalqc_dashBoard = petal_qc:dashBoard
11
12
  uploadPetalInformation = petal_qc:uploadPetalInformation
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "petal_qc"
7
- version = "0.0.15"
7
+ version = "0.0.16"
8
8
  authors = [
9
9
  { name="Carlos Lacasta", email="carlos.lacasta@cern.ch" },
10
10
  ]
@@ -40,6 +40,7 @@ petalqc_dashBoard = "petal_qc:dashBoard"
40
40
  createCoreThermalReport = "petal_qc:createCoreThermalReport"
41
41
  analyzeIRCore = "petal_qc:analyzeIRCore"
42
42
  petalReceptionTests = "petal_qc:petalReceptionTests"
43
+ petalCoreTestSummary = "petal_qc:petalCoreTestSummary"
43
44
 
44
45
  [tool.setuptools]
45
46
  include-package-data = true
File without changes
File without changes