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
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env python3
2
+ """Analize AVS metrology tests."""
3
+ import sys
4
+ from pathlib import Path
5
+ import numpy as np
6
+
7
+ try:
8
+ import itkdb_gtk
9
+
10
+ except ImportError:
11
+ cwd = Path(__file__).parent.parent
12
+ sys.path.append(cwd.as_posix())
13
+
14
+ from itkdb_gtk import ITkDBlogin, ITkDButils
15
+ from petal_qc.metrology.readAVSdata import readFATfile
16
+
17
+
18
+ def set_pos(V, results, obj):
19
+ """Update positions."""
20
+ results["{}_X".format(obj)] = V[0]
21
+ results["{}_Y".format(obj)] = V[1]
22
+
23
+
24
+ def get_pos(results, obj):
25
+ """Return position."""
26
+ try:
27
+ X = results["{}_X".format(obj)]
28
+ Y = results["{}_Y".format(obj)]
29
+
30
+ if abs(X) > 1000:
31
+ X /= 1000
32
+ if abs(Y)>1000:
33
+ Y /= 1000
34
+ except KeyError:
35
+ X = 0.0
36
+ Y = 0.0
37
+
38
+ P = np.array([X, Y], dtype="float64")
39
+ return P
40
+
41
+
42
+ def check_locators(results):
43
+ """Accumulate metrology values."""
44
+ points = ["LOCATOR1", "LOCATOR2", "LOCATOR3", "FIDUCIAL1", "FIDUCIAL2"]
45
+ coord = {}
46
+ for P in points:
47
+ coord[P] = get_pos(results, P)
48
+
49
+ changed = False
50
+ fd1 = np.array(coord["FIDUCIAL1"], dtype="float64")
51
+ if fd1[0]!=0.0 or fd1[1]!=0:
52
+ changed = True
53
+ for V in coord.values():
54
+ V -= fd1
55
+
56
+ for O, P in coord.items():
57
+ set_pos(coord[O], results, O)
58
+
59
+ return changed
60
+
61
+ ROOT_DIR = Path("/Users/lacasta/Nextcloud/ITk/5-Petal_cores")
62
+
63
+
64
+
65
+ def analyze_avs_metrology(session, SN, altid):
66
+ """Regenerate test json from FAT file."""
67
+ P = ROOT_DIR / altid
68
+ files = list(P.glob("AVS.P052.FRT.*.xlsx"))
69
+ if len(files)==0:
70
+ print("Cannot find FAT file for {}".format(altid))
71
+ return None
72
+ elif len(files)>1:
73
+ print("More than one FAT file for {}".format(altid))
74
+ for i, f in enumerate(files):
75
+ print("{} - {}".format(i, Path/f).name)
76
+
77
+ ifile = int(input("Choose file (-1 to discard): "))
78
+ if ifile < 0:
79
+ return None
80
+
81
+ the_file = files[ifile]
82
+
83
+ else:
84
+ the_file = files[0]
85
+
86
+
87
+ tests = readFATfile(session, the_file, SN)
88
+ the_test = tests[3]
89
+ check_locators(the_test["results"])
90
+ the_test["isRetroactive"] = True
91
+ the_test["stage"] = "ASSEMBLY"
92
+
93
+ return the_test
94
+
95
+ def main(session):
96
+ """Entry point"""
97
+ # find all cores
98
+ # Now all the objects
99
+ payload = {
100
+ "filterMap": {
101
+ "componentType": ["CORE_PETAL"],
102
+ "type": ["CORE_AVS"],
103
+ #"currentLocation": ["IFIC"],
104
+ },
105
+ "sorterList": [
106
+ {"key": "alternativeIdentifier", "descending": False }
107
+ ],
108
+ }
109
+
110
+ core_list = session.get("listComponents", json=payload)
111
+ core_tests = ["METROLOGY_AVS"]
112
+
113
+ petal_ids = []
114
+ for core in core_list:
115
+ SN = core["serialNumber"]
116
+ altid = core['alternativeIdentifier']
117
+ if "PPC" not in altid:
118
+ continue
119
+
120
+ petal_ids.append(altid)
121
+
122
+ location = core["currentLocation"]['code']
123
+ coreStage = core["currentStage"]['code']
124
+
125
+ print("\nPetal {} [{}] - {}. {}".format(SN, altid, coreStage, location))
126
+ test_list = session.get("listTestRunsByComponent", json={"filterMap":{"serialNumber": SN, "state": "ready", "testType":core_tests}})
127
+
128
+ good_tests = {}
129
+ for tst in test_list:
130
+ ttype = tst["testType"]["code"]
131
+ if ttype not in core_tests:
132
+ print(ttype)
133
+ continue
134
+
135
+ T = session.get("getTestRun", json={"testRun": tst["id"]})
136
+ if T["state"] != "ready":
137
+ continue
138
+
139
+ if ttype in good_tests:
140
+ if good_tests[ttype]["runNumber"] < T["runNumber"]:
141
+ good_tests[ttype] = T
142
+ else:
143
+ good_tests[ttype] = T
144
+
145
+ for ttype, T in good_tests.items():
146
+ if ttype != "METROLOGY_AVS":
147
+ continue
148
+
149
+ found = False
150
+ for value in T["results"]:
151
+ if value["code"] == "LOCATOR1_X":
152
+ found = True
153
+ break
154
+
155
+ if not found:
156
+ print("LOCATOR1 is not here")
157
+ the_test = analyze_avs_metrology(session, SN, altid)
158
+ if the_test is None:
159
+ continue
160
+
161
+ rc = ITkDButils.upload_test(session, the_test, check_runNumber=True)
162
+ if rc:
163
+ print(rc)
164
+
165
+
166
+ if __name__ == "__main__":
167
+ # ITk_PB authentication
168
+ dlg = ITkDBlogin.ITkDBlogin()
169
+ client = dlg.get_client()
170
+
171
+ try:
172
+ # main(session)
173
+ the_test = analyze_avs_metrology(client, "20USEBC1000124", "PPC.015")
174
+ #rc = ITkDButils.upload_test(client, the_test, check_runNumber=True)
175
+ #if rc:
176
+ # print(rc)
177
+
178
+ except Exception as E:
179
+ print(E)
180
+
181
+ dlg.die()
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env python3
2
+ """Compara golden files."""
3
+ import json
4
+ import sys
5
+ from pathlib import Path
6
+ from argparse import ArgumentParser
7
+ import numpy as np
8
+ import matplotlib.pyplot as plt
9
+
10
+
11
+ def compare_golden(files):
12
+ """Go through files."""
13
+ fig, ax = plt.subplots(2, 1, tight_layout=True)
14
+ for ff in files:
15
+ ifile = Path(ff).expanduser().resolve()
16
+ if not ifile.exists():
17
+ print("ff does not exist.")
18
+ continue
19
+
20
+ js = None
21
+ with open(ifile, "r", encoding="utf-8") as fp:
22
+ js = json.load(fp)
23
+
24
+ if js is None:
25
+ print("Cannot load {}".format(ff))
26
+ continue
27
+
28
+ for iside in range(2):
29
+ ax[iside].plot(js[iside]["path_length"], js[iside]["path_temp"], '-', label=ifile.name)
30
+
31
+ for iside in range(2):
32
+ ax[iside].legend()
33
+ plt.show()
34
+
35
+ if __name__ == "__main__":
36
+ parser = ArgumentParser()
37
+ parser.add_argument('files', nargs='*', help="Input files")
38
+
39
+ options = parser.parse_args()
40
+ if len(options.files) == 0:
41
+ print("I need an input file")
42
+ sys.exit()
43
+
44
+ compare_golden(options.files)
@@ -0,0 +1,27 @@
1
+ import json
2
+ from itkdb_gtk import ITkDBlogin
3
+ from petal_qc.metrology import readAVSdata
4
+ dlg = ITkDBlogin.ITkDBlogin()
5
+ session = dlg.get_client()
6
+
7
+ ofile = "weights_ppc16.json"
8
+ PSF = "/Users/lacasta/Nextcloud/ITk/5-Petal_cores/PPC.016/AVS.P052.PSH.035 - Petal 016.xlsx"
9
+
10
+ ofile = "weights_ppc17.json"
11
+ ofat = "metrology_test_ppc17.json"
12
+ PSF = "/Users/lacasta/Nextcloud/ITk/5-Petal_cores/PPC.017/AVS.P052.PSH.036 - Petal 017.xlsx"
13
+ FAT = "/Users/lacasta/Nextcloud/ITk/5-Petal_cores/PPC.017/AVS.P052.FRT.036 r0 - FAT_Serie_017.xlsx"
14
+ manuf_json, weights_json, DESY_comp, alias = readAVSdata.readProductionSheet(session, PSF, "SNnnnn")
15
+
16
+ vi_test, delamination_test, grounding_test, metrology_test, batch, petal_weight = readAVSdata.readFATfile(session, FAT, "SNnnn")
17
+
18
+ with open(ofile, "w", encoding="UTF-8") as fin:
19
+ json.dump(weights_json, fin, indent=3)
20
+
21
+
22
+ with open(ofat, "w", encoding="UTF-8") as fin:
23
+ json.dump(metrology_test, fin, indent=3)
24
+
25
+
26
+ print("done")
27
+ dlg.die()
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env python3
2
+ """Analize AVS metrology tests."""
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+
6
+ try:
7
+ import itkdb_gtk
8
+
9
+ except ImportError:
10
+ import sys
11
+ from pathlib import Path
12
+ cwd = Path(__file__).parent.parent
13
+ sys.path.append(cwd.as_posix())
14
+
15
+ from itkdb_gtk import ITkDBlogin, ITkDButils
16
+
17
+
18
+ def get_value(results, code):
19
+ """Return the value of the test parameter."""
20
+ for param in results:
21
+ if param["code"] == code:
22
+ return param["value"]
23
+
24
+ raise KeyError
25
+
26
+ def distance(P1, P2):
27
+ """Distance between 2 points."""
28
+ P = (P2-P1)
29
+ S = np.sum(np.square(P))
30
+ D = np.sqrt(S)
31
+ return D
32
+
33
+ nominal_values = {
34
+ "LOCATOR1": np.array([0, -3]),
35
+ "LOCATOR2": np.array([127.916, 589.618]),
36
+ "LOCATOR3": np.array([127.916, 589.618]),
37
+ "FIDUCIAL1": np.array([0, 0]),
38
+ "FIDUCIAL2": np.array([131.104, 586.526]),
39
+ }
40
+
41
+ def get_pos(results, obj):
42
+ """Return position."""
43
+ try:
44
+ X = get_value(results, "{}_X".format(obj))
45
+ Y = get_value(results, "{}_Y".format(obj))
46
+
47
+ if abs(X) > 1000:
48
+ X /= 1000
49
+ if abs(Y)>1000:
50
+ Y /= 1000
51
+ except KeyError:
52
+ X = 0.0
53
+ Y = 0.0
54
+
55
+ P = np.array([X, Y], dtype="float64")
56
+ return P
57
+
58
+ def distance_to_nominal(results, obj):
59
+ """Return position of given locator or fiducial."""
60
+ P = get_pos(results, obj)
61
+ N = nominal_values[obj]
62
+ D = distance(P, N)
63
+ if abs(D-3)<0.5:
64
+ P[1] -= 3
65
+ D = distance(P, N)
66
+ return D
67
+
68
+ def do_metrology(results, M_values, Mould_values):
69
+ """Accumulate metrology values."""
70
+ points = ["LOCATOR1", "LOCATOR2", "LOCATOR3", "FIDUCIAL1", "FIDUCIAL2"]
71
+ coord = {}
72
+ for P in points:
73
+ coord[P] = get_pos(results, P)
74
+
75
+ fd1 = np.array(coord["FIDUCIAL1"], dtype="float64")
76
+ if fd1[0]!=0.0 or fd1[1]!=0:
77
+ for V in coord.values():
78
+ V -= fd1
79
+
80
+ for O, P in coord.items():
81
+ D = distance(P, nominal_values[O])
82
+ if D<1.0:
83
+ M_values.setdefault(O, []).append(D)
84
+ Mould_values.setdefault(O, []).append(D)
85
+
86
+ else:
87
+ print("Possibly wrong data in FAT: {} D={:.3f}".format(O, D))
88
+
89
+ def do_manufacturing(T):
90
+ """Return mould."""
91
+ mould_id = None
92
+ for prop in T["properties"]:
93
+ if prop["code"] == "MOULD_ID":
94
+ mould_id = prop["value"]
95
+ break
96
+
97
+ return mould_id
98
+
99
+ def do_weighing(results, weights):
100
+ """Accumulates weighing values to produce stack plot.
101
+
102
+ Args:
103
+ results (): Results from DB
104
+ weights (): Dict with the values.
105
+ """
106
+ for value in results:
107
+ ipos = value["code"].find("_")
108
+ weights.setdefault(value["code"][ipos+1:], []).append(value["value"])
109
+
110
+
111
+ def plot_metrology(M_values, Mould_values, petal_ids):
112
+ """Plot metrology values."""
113
+ for key, values in M_values.items():
114
+ fig, ax = plt.subplots(ncols=1, nrows=1, tight_layout=True)
115
+ ax.hist(values, bins=15, range=(0, 0.150))
116
+ ax.set_title(key)
117
+
118
+ for obj in M_values.keys():
119
+ fig, ax = plt.subplots(ncols=1, nrows=4, tight_layout=True)
120
+ fig.suptitle("{} - Mould".format(obj))
121
+ for mould, m_values in Mould_values.items():
122
+ im = int(mould) - 1
123
+ ax[im].hist(m_values[obj], bins=15, range=(0, 0.150), label="Mould {}".format(mould))
124
+
125
+ for i in range(4):
126
+ ax[i].set_title("Mould {}".format(i+1))
127
+
128
+ def plot_weighing(weights, tick_labels, show_total=False):
129
+ """Make the plot of weights."""
130
+ labels = ["COOLINGLOOPASSEMBLY", "LOCATOR_A", "LOCATOR_B", "LOCATOR_C",
131
+ "HONEYCOMBSET", "FACING_FRONT", "FACING_BACK",
132
+ "EPOXYADHESIVE", "EPOXYPUTTY", "EPOXYCONDUCTIVE"]
133
+
134
+ fig = plt.figure(tight_layout=True)
135
+ fig.suptitle("Petal Core weight (gr)")
136
+ ax = fig.add_subplot(1, 1, 1)
137
+ ax.set_ylabel("Weight [gr]")
138
+ ax.set_ylim(0, 300)
139
+ npoints = len(weights["CORE"])
140
+ X = np.arange(npoints)
141
+
142
+ values = [ weights[k] for k in labels]
143
+ Y = np.vstack(values)
144
+ ax.stackplot(X, Y, labels=labels)
145
+ ax.set_xticks(range(npoints), labels=tick_labels, rotation="vertical")
146
+
147
+ if not show_total:
148
+ ax.plot(X, [225.0 for x in range(npoints)], linestyle="dashed", color="black", linewidth=1)
149
+ ax.plot(X, [250.0 for x in range(npoints)], '-', color="black", linewidth=1, label="Nominal")
150
+ ax.plot(X, [275.0 for x in range(npoints)], linestyle="dashed", color="black", linewidth=1,)
151
+
152
+
153
+ ax.legend(loc="upper left", ncol=4)
154
+
155
+
156
+ def main(session):
157
+ """Entry point"""
158
+ # find all cores
159
+ # Now all the objects
160
+ payload = {
161
+ "filterMap": {
162
+ "componentType": ["CORE_PETAL"],
163
+ "type": ["CORE_AVS"],
164
+ #"currentLocation": ["IFIC"],
165
+ },
166
+ "sorterList": [
167
+ {"key": "alternativeIdentifier", "descending": False }
168
+ ],
169
+ }
170
+
171
+ core_list = session.get("listComponents", json=payload)
172
+ core_tests = ["METROLOGY_AVS", "WEIGHING", "MANUFACTURING"]
173
+
174
+ weights = {}
175
+ petal_ids = []
176
+ M_values = {}
177
+ Mould_values = {}
178
+ mould_id = None
179
+ for core in core_list:
180
+ SN = core["serialNumber"]
181
+ altid = core['alternativeIdentifier']
182
+ if "PPC" not in altid:
183
+ continue
184
+
185
+ petal_ids.append(altid)
186
+ location = core["currentLocation"]['code']
187
+ coreStage = core["currentStage"]['code']
188
+
189
+ print("\nPetal {} [{}] - {}. {}".format(SN, altid, coreStage, location))
190
+ test_list = session.get(
191
+ "listTestRunsByComponent",
192
+ json={
193
+ "filterMap": {
194
+ "serialNumber": SN,
195
+ "state": "ready",
196
+ "testType": core_tests,
197
+ }
198
+ },
199
+ )
200
+
201
+ good_tests = {}
202
+ for tst in test_list:
203
+ ttype = tst["testType"]["code"]
204
+ if ttype not in core_tests:
205
+ print(ttype)
206
+ continue
207
+
208
+ T = session.get("getTestRun", json={"testRun": tst["id"]})
209
+ if T["state"] != "ready":
210
+ continue
211
+
212
+ print("-- {} [{}]".format(T["testType"]["name"], T["runNumber"]))
213
+ if ttype in good_tests:
214
+ if good_tests[ttype]["runNumber"] < T["runNumber"]:
215
+ good_tests[ttype] = T
216
+ else:
217
+ good_tests[ttype] = T
218
+
219
+ mould_desc = do_manufacturing(good_tests["MANUFACTURING"])
220
+ pos = mould_desc.rfind('.')
221
+ mould_id = mould_desc[pos+1:]
222
+ if mould_id not in Mould_values:
223
+ Mould_values[mould_id] = {}
224
+
225
+ for ttype, T in good_tests.items():
226
+
227
+ if ttype == "WEIGHING":
228
+ do_weighing(T["results"], weights)
229
+
230
+ elif ttype == "METROLOGY_AVS":
231
+ do_metrology(T["results"], M_values, Mould_values[mould_id])
232
+
233
+ elif ttype == "MANUFACTURING":
234
+ continue
235
+
236
+ else:
237
+ for value in T["results"]:
238
+ print("\t{} - {}".format(value["code"], value["value"]))
239
+
240
+ if not T["passed"]:
241
+ print("## test {} FAILED".format(T["testType"]["code"]))
242
+
243
+ if len(T["defects"]):
244
+ print("+ Defects:")
245
+ for D in T["defects"]:
246
+ print("\t{} - {}".format(D["name"], D["description"]))
247
+
248
+ plot_weighing(weights, petal_ids)
249
+ plot_metrology(M_values, Mould_values, petal_ids)
250
+ plt.show()
251
+
252
+ if __name__ == "__main__":
253
+ # ITk_PB authentication
254
+ dlg = ITkDBlogin.ITkDBlogin()
255
+ session = dlg.get_client()
256
+
257
+ try:
258
+ main(session)
259
+
260
+ except Exception as E:
261
+ print(E)
262
+
263
+ dlg.die()
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env python3
2
+ """Get a summery of Petal core TEsts."""
3
+
4
+ try:
5
+ import itkdb_gtk
6
+
7
+ except ImportError:
8
+ import sys
9
+ from pathlib import Path
10
+ cwd = Path(__file__).parent.parent
11
+ sys.path.append(cwd.as_posix())
12
+
13
+ from itkdb_gtk import ITkDBlogin, ITkDButils
14
+ from itkdb_gtk.dbGtkUtils import replace_in_container, DictDialog, ask_for_confirmation
15
+
16
+
17
+ def main(session):
18
+ """Main entry point."""
19
+
20
+ # find all cores
21
+ # Now all the objects
22
+ payload = {
23
+ "filterMap": {
24
+ #"componentType": ["BT"],
25
+ "componentType": ["CORE_PETAL"],
26
+ "type": ["CORE_AVS"],
27
+ "currentLocation": ["IFIC"],
28
+ },
29
+ "sorterList": [
30
+ {"key": "alternativeIdentifier", "descending": False }
31
+ ],
32
+ }
33
+ core_list = session.get("listComponents", json=payload)
34
+ core_tests = ["PETAL_METROLOGY_FRONT", "PETAL_METROLOGY_BACK", "XRAYIMAGING", "THERMAL_EVALUATION", "BTTESTING"]
35
+
36
+ do_check_stage = "AT_QC_SITE"
37
+ #do_check_stage = None
38
+
39
+ for core in core_list:
40
+ SN = core["serialNumber"]
41
+ altid = core['alternativeIdentifier']
42
+ if "PPC" not in altid:
43
+ continue
44
+
45
+
46
+ location = core["currentLocation"]['code']
47
+ coreStage = core["currentStage"]['code']
48
+ if do_check_stage:
49
+ if coreStage != do_check_stage:
50
+ rc = ITkDButils.set_object_stage(session, SN, do_check_stage)
51
+ if rc is None:
52
+ print("Could not change stage")
53
+ return False
54
+
55
+ print("\n\nPetal {} [{}] - {}. {}".format(SN, altid, coreStage, location))
56
+
57
+ test_list = session.get("listTestRunsByComponent", json={"filterMap":{"serialNumber": SN, "state": "ready", "testType":core_tests}})
58
+
59
+ for tst in test_list:
60
+ ttype = tst["testType"]["code"]
61
+ if ttype not in core_tests:
62
+ print(ttype)
63
+ continue
64
+
65
+ T = session.get("getTestRun", json={"testRun": tst["id"]})
66
+ if T["state"] != "ready":
67
+ print(T)
68
+
69
+ print("-- {} [{}]".format(T["testType"]["name"], T["runNumber"]))
70
+ if not T["passed"]:
71
+ print("\t## test FAILED")
72
+
73
+ for D in T["defects"]:
74
+ print("\t{} - {}".format(D["name"], D["description"]))
75
+
76
+
77
+ if __name__ == "__main__":
78
+ # ITk_PB authentication
79
+ dlg = ITkDBlogin.ITkDBlogin()
80
+ session = dlg.get_client()
81
+
82
+ try:
83
+ main(session)
84
+
85
+ except Exception as E:
86
+ print(E)
87
+
88
+ dlg.die()
89
+
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env python3
2
+ """List petal core components."""
3
+
4
+ from itkdb_gtk import ITkDBlogin
5
+ from itkdb_gtk import ITkDButils
6
+
7
+ def get_type(child):
8
+ """Return object type.
9
+
10
+ Args:
11
+ child: object
12
+
13
+ Returns
14
+ str: object type
15
+ """
16
+ if child["type"] is not None:
17
+ comp_type = child["type"]["code"]
18
+
19
+ else:
20
+ comp_type = child["componentType"]["code"]
21
+
22
+ return comp_type
23
+
24
+
25
+ def listPetalCoreComponents(session):
26
+ """List petal core components.
27
+
28
+ Args:
29
+ session: The itkdb session
30
+ """
31
+ final_stage = {
32
+ "BT_PETAL_FRONT": "COMPLETED",
33
+ "BT_PETAL_BACK": "COMPLETED",
34
+ "COOLING_LOOP_PETAL": "CLINCORE",
35
+ "THERMALFOAMSET_PETAL": "IN_CORE"
36
+ }
37
+ # find all cores
38
+ # Now all the objects
39
+ payload = {
40
+ "filterMap": {
41
+ "componentType": ["CORE_PETAL"],
42
+ "type": ["CORE_AVS"],
43
+ "currentLocation": ["IFIC"],
44
+ },
45
+ "sorterList": [
46
+ {"key": "alternativeIdentifier", "descending": False }
47
+ ],
48
+ }
49
+ core_list = session.get("listComponents", json=payload)
50
+
51
+ for core in core_list:
52
+ SN = core["serialNumber"]
53
+ altid = core['alternativeIdentifier']
54
+ if "PPC" not in altid:
55
+ continue
56
+
57
+
58
+ location = core["currentLocation"]['code']
59
+ coreStage = core["currentStage"]['code']
60
+ print("\n\nPetal {} [{}] - {}. {}".format(SN, altid, coreStage, location))
61
+
62
+ for child in core["children"]:
63
+ obj = ITkDButils.get_DB_component(session, child["component"])
64
+ child_type = get_type(obj)
65
+ child_stage = obj["currentStage"]["code"]
66
+ child_sn = obj["serialNumber"]
67
+ print("+-- {}: {} [{}]".format(child_sn, child_type, child_stage))
68
+ if child_stage != final_stage[child_type]:
69
+ print("Updating child stage.")
70
+ rc = ITkDButils.set_object_stage(session, child_sn, final_stage[child_type])
71
+ if rc is None:
72
+ print("Could not set final stage of {} [{}]".format(child_type, child_sn))
73
+
74
+
75
+ if __name__ == "__main__":
76
+ # ITk PDB authentication
77
+ dlg = None
78
+ try:
79
+ # We use here the Gtk GUI
80
+ dlg = ITkDBlogin.ITkDBlogin()
81
+ client = dlg.get_client()
82
+
83
+ except Exception:
84
+ # Login with "standard" if the above fails.
85
+ client = ITkDButils.create_client()
86
+
87
+ listPetalCoreComponents(client)
88
+ if dlg:
89
+ dlg.die()