dsh-origin-bridge 0.4.0 → 0.4.2

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.
package/cases/data.py ADDED
@@ -0,0 +1,120 @@
1
+ """Tiny deterministic datasets for the case bank.
2
+
3
+ Nothing here is real experimental data: every series is generated from a closed
4
+ formula so a re-run reproduces byte-identical files, and every file stays under
5
+ 24 rows. `.bin` workstation samples are deliberately NOT covered here.
6
+
7
+ build(dir) writes the files and returns {placeholder: value}; the catalogue
8
+ references them as "{dat}", "{csv}", ... so cases never hardcode a path.
9
+ """
10
+
11
+ import math
12
+ import os
13
+
14
+
15
+ def _rows(xs, ys):
16
+ return "\n".join("%g\t%g" % (x, y) for x, y in zip(xs, ys))
17
+
18
+
19
+ def _write(path, text, encoding="utf-8"):
20
+ with open(path, "w", encoding=encoding, newline="\n") as handle:
21
+ handle.write(text)
22
+ return path
23
+
24
+
25
+ def _exp(n=24, k=0.16):
26
+ xs = [float(i) for i in range(n)]
27
+ ys = [round(1.8 * math.exp(k * x), 3) for x in xs]
28
+ return xs, ys
29
+
30
+
31
+ def build(target):
32
+ os.makedirs(target, exist_ok=True)
33
+ j = lambda name: os.path.join(target, name) # noqa: E731
34
+ out = {"dir": target}
35
+
36
+ xs, ys = _exp()
37
+
38
+ out["dat"] = _write(j("curve.dat"),
39
+ "X\tY\n" + _rows(xs, ys))
40
+ out["units"] = _write(j("units.dat"),
41
+ "Long Name\tBinding Energy\tIntensity\n"
42
+ "Units\teV\tcps\n"
43
+ "Comments\tsynthetic\tpaired\n"
44
+ + _rows([round(i * 0.9, 2) for i in range(20)],
45
+ [round(500 + 40 * math.sin(i / 3.0) + i * 6, 2) for i in range(20)]))
46
+ out["xps_file"] = _write(j("xps_survey.dat"),
47
+ "Binding Energy\tIntensity\n"
48
+ + _rows([round(284 + i * 0.3, 2) for i in range(18)],
49
+ [round(900 - 12 * i + 40 * math.sin(i / 2.0)) for i in range(18)]))
50
+ out["csv"] = _write(j("curve.csv"),
51
+ "time,signal\n" + "\n".join("%g,%g" % p for p in zip(xs, ys)))
52
+ out["semi"] = _write(j("curve.txt"),
53
+ "time;signal\n" + "\n".join("%g;%g" % p for p in zip(xs, ys)))
54
+ out["spaced"] = _write(j("aligned.dat"),
55
+ "time signal\n" + "\n".join("%-6g %-9g" % p for p in zip(xs, ys)))
56
+ out["multi"] = _write(j("multi_header.dat"),
57
+ "run 1\nsample A\n\time\tmV\n" + _rows(xs[:12], ys[:12]))
58
+ out["na"] = _write(j("na_values.dat"),
59
+ "x\ty\n" + "\n".join(
60
+ "%g\t%s" % (x, ("NA" if i % 7 == 3 else ("-" if i % 11 == 5 else "%g" % y)))
61
+ for i, (x, y) in enumerate(zip(xs, ys))))
62
+ out["comment"] = _write(j("commented.dat"),
63
+ "# generated for the case bank\n# keep\nx\ty\n" + _rows(xs[:10], ys[:10]))
64
+ out["gbk"] = _write(j("gbk_units.dat"),
65
+ "名称\t电势\t电流\n单位\tmV\tuA\n" + _rows([-2.0, -1.0, 0.0, 1.0, 2.0],
66
+ [12.5, 40.0, 999.0, 38.0, 11.0]),
67
+ encoding="gbk")
68
+ out["bom"] = _write(j("bom.csv"), "\ufefftime,signal\n" + "\n".join("%g,%g" % p for p in zip(xs[:8], ys[:8])))
69
+ out["dup"] = _write(j("dup_names.dat"), "x\ty\ty\n" + "\n".join("%g\t%g\t%g" % (x, y, y / 2)
70
+ for x, y in zip(xs[:9], ys[:9])))
71
+ out["wide"] = _write(j("wide.dat"),
72
+ "x\ta\tb\tc\td\n" + "\n".join(
73
+ "%g\t%g\t%g\t%g\t%g" % (x, y, y * 0.8, y * 0.6, y * 0.4)
74
+ for x, y in zip(xs, ys)))
75
+ out["fit"] = _write(j("fit_pair.dat"),
76
+ "x\ty\n" + "\n".join("%g\t%g" % (x, 2.5 * x + 1.0 + (0.4 if i % 2 else -0.4))
77
+ for i, x in enumerate([float(i) for i in range(1, 15)])))
78
+ out["chi"] = _write(j("chi_lsv.txt"), (
79
+ "Mar. 02, 2024 09:41:07\r\n"
80
+ "Linear Sweep Voltammetry\r\n"
81
+ "File: d:\\lab\\chi_lsv.txt\r\n"
82
+ "Data Source: Experiment\r\n"
83
+ "Instrument Model: CHI660E\r\n"
84
+ "Header: \r\n"
85
+ "Note: \r\n"
86
+ "\r\n"
87
+ "Init E (V) = 0.0\r\n"
88
+ "Final E (V) = 0.6\r\n"
89
+ "Scan Rate (V/s) = 0.05\r\n"
90
+ "Sample Interval (V) = 0.001\r\n"
91
+ "Quiet Time (sec) = 2\r\n"
92
+ "Sensitivity (A/V) = 0.0001\r\n"
93
+ "\r\n"
94
+ "Results:\r\n"
95
+ "\r\n"
96
+ "Channel 1:\r\n"
97
+ "Segment 1:\r\n"
98
+ "\r\n"
99
+ "Potential/V, Current/A\r\n"
100
+ "\r\n" + "\r\n".join("%.3f, %.3e" % (i * 0.01, 1e-5 + 2e-6 * math.sin(i / 3.0))
101
+ for i in range(40)) + "\r\n"))
102
+ out["empty"] = _write(j("empty.dat"), "")
103
+ out["text"] = _write(j("text_only.dat"), "name\tnote\nalpha\tthis file has no numbers\nbeta\tnor does this\n")
104
+ out["onecol"] = _write(j("one_column.dat"), "y\n1\n2\n3\n")
105
+ out["huge"] = _write(j("long_line.dat"), "x\ty\n" + "\n".join("%g\t%g" % (i, i * i) for i in range(400)))
106
+
107
+ out["columns"] = {"t": [round(v, 2) for v in xs[:12]],
108
+ "v": [round(v, 2) for v in ys[:12]]}
109
+ out["wide_columns"] = {"t": [round(v, 2) for v in xs[:10]],
110
+ "a": [round(v, 2) for v in ys[:10]],
111
+ "b": [round(v * 0.7, 2) for v in ys[:10]],
112
+ "c": [round(v * 0.4, 2) for v in ys[:10]]}
113
+ out["headers"] = ["x", "y1", "y2"]
114
+ out["rows"] = [[round(x, 2), round(y, 2), round(y * 0.5, 2)] for x, y in zip(xs[:10], ys[:10])]
115
+ out["matrix_rows"] = [[round(math.sin(i / 2.0) + math.cos(j / 3.0), 4) for j in range(8)] for i in range(8)]
116
+ out["xps"] = {"binding_energy": [round(284.0 + i * 0.5, 2) for i in range(18)],
117
+ "intensity": [round(120 + 90 * math.exp(-((i - 9) ** 2) / 8.0), 2) for i in range(18)]}
118
+ out["cv"] = {"potential": [round(-0.2 + i * 0.02, 3) for i in range(24)],
119
+ "current": [round(1e-5 * math.sin(i / 2.4) * (1 + i / 12.0), 8) for i in range(24)]}
120
+ return out
package/docs/preview.png CHANGED
Binary file
package/edge_checks.py CHANGED
@@ -164,7 +164,7 @@ def main():
164
164
  proc.stdin.flush()
165
165
  line = proc.stdout.readline()
166
166
  info = json.loads(line)["result"]["serverInfo"]
167
- check("bin/origin-bridge.mjs launcher", info.get("name") == "optima-plot", info)
167
+ check("bin/origin-bridge.mjs launcher", info.get("name") == "origin-bridge", info)
168
168
  except Exception as exc:
169
169
  check("bin/origin-bridge.mjs launcher", False, repr(exc)[:120])
170
170
  finally:
@@ -173,6 +173,16 @@ def main():
173
173
  print("SKIP node launcher (node not on PATH)")
174
174
 
175
175
  bad = [n for n, ok in results if not ok]
176
+ # Same teardown as smoke_test: reclaim only the windowless instances this run
177
+ # started; an older one may belong to a live dsh session.
178
+ late = [r for r in S.originlab._process_rows()
179
+ if not r["window"] and str(r.get("started") or "") >= S.STARTED_AT]
180
+ for row in late:
181
+ S.originlab._close_pid(row["pid"])
182
+ left = [r for r in S.originlab._process_rows()
183
+ if not r["window"] and str(r.get("started") or "") >= S.STARTED_AT]
184
+ check("run leaves no Origin instance", not left, left)
185
+
176
186
  print("\n%d/%d passed" % (len(results) - len(bad), len(results)))
177
187
  if bad:
178
188
  print("FAILED:", ", ".join(bad))