Skip to content

Commit 606d5f5

Browse files
fixed bubbler issue
1 parent 29e8d06 commit 606d5f5

File tree

4 files changed

+237
-19
lines changed

4 files changed

+237
-19
lines changed

src/pathsim_utils.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,8 @@ def create_bubbler(node: dict) -> Bubbler:
153153
Create a Bubbler block based on the node data.
154154
"""
155155
# Extract parameters from node data
156-
block = Bubbler(
157-
conversion_efficiency=eval(node["data"]["conversion_efficiency"]),
158-
vial_efficiency=eval(node["data"]["vial_efficiency"]),
159-
replacement_times=eval(node["data"]["replacement_times"])
160-
if node["data"].get("replacement_times") != ""
161-
else None,
162-
)
156+
parameters = get_parameters_for_block_class(Bubbler, node, eval_namespace=globals())
157+
block = Bubbler(**parameters)
163158

164159
events = block.create_reset_events()
165160

@@ -193,7 +188,11 @@ def create_scope(node: dict, edges, nodes) -> Scope:
193188
if edge["sourceHandle"]:
194189
labels[i] += f" ({edge['sourceHandle']})"
195190

196-
block = Scope(labels=labels)
191+
parameters = get_parameters_for_block_class(Scope, node, eval_namespace=globals())
192+
# remove labels from parameters, as they are set separately
193+
parameters.pop("labels", None)
194+
195+
block = Scope(labels=labels, **parameters)
197196
block._connections_order = connections_order
198197

199198
return block
@@ -297,17 +296,19 @@ def auto_block_construction(node: dict, eval_namespace: dict = None) -> Block:
297296
if eval_namespace is None:
298297
eval_namespace = globals()
299298

300-
block_type = node["type"]
299+
if node["type"] not in map_str_to_object:
300+
raise ValueError(f"Unknown block type: {node['type']}")
301301

302-
if eval_namespace is None:
303-
eval_namespace = globals()
302+
block_class = map_str_to_object[node["type"]]
304303

305-
block_type = node["type"]
306-
if block_type not in map_str_to_object:
307-
raise ValueError(f"Unknown block type: {block_type}")
304+
parameters = get_parameters_for_block_class(
305+
block_class, node, eval_namespace=eval_namespace
306+
)
307+
308+
return block_class(**parameters)
308309

309-
block_class = map_str_to_object[block_type]
310310

311+
def get_parameters_for_block_class(block_class, node, eval_namespace):
311312
parameters_for_class = inspect.signature(block_class.__init__).parameters
312313
parameters = {}
313314
for k, value in parameters_for_class.items():
@@ -321,13 +322,12 @@ def auto_block_construction(node: dict, eval_namespace: dict = None) -> Block:
321322
if user_input == "":
322323
if value.default is inspect._empty:
323324
raise ValueError(
324-
f"expected parameter for {k} in {block_type} ({node['label']})"
325+
f"expected parameter for {k} in {node['type']} ({node['label']})"
325326
)
326327
parameters[k] = value.default
327328
else:
328329
parameters[k] = eval(user_input, eval_namespace)
329-
330-
return block_class(**parameters)
330+
return parameters
331331

332332

333333
def make_blocks(

test/test_backend.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
create_integrator,
33
auto_block_construction,
44
create_function,
5+
create_bubbler,
56
)
6-
from src.custom_pathsim_blocks import Process, Splitter2, Splitter3
7+
from src.custom_pathsim_blocks import Process, Splitter2, Splitter3, Bubbler
78

89
import pathsim.blocks
910

@@ -28,6 +29,14 @@
2829
"type": "integrator",
2930
"data": {"initial_value": "0.0", "label": "Integrator", "reset_times": ""},
3031
},
32+
"bubbler": {
33+
"type": "bubbler",
34+
"data": {
35+
"conversion_efficiency": "",
36+
"replacement_times": "",
37+
"vial_efficiency": "",
38+
},
39+
},
3140
"function": {
3241
"type": "function",
3342
"data": {"expression": "3*x**2", "label": "Function"},
@@ -186,3 +195,22 @@ def test_create_function():
186195
block = create_function(node, eval_namespace={"b": 2.5})
187196
assert isinstance(block, pathsim.blocks.Function)
188197
assert block.func(2) == 3 * 2**2 + 2.5
198+
199+
200+
def test_create_bubbler():
201+
node = {
202+
"id": "6",
203+
"type": "bubbler",
204+
"position": {"x": 627, "y": 357},
205+
"data": {
206+
"label": "bubbler 6",
207+
"conversion_efficiency": "",
208+
"replacement_times": "[1, 2, 3]",
209+
"vial_efficiency": "",
210+
},
211+
"measured": {"width": 230, "height": 160},
212+
"selected": False,
213+
"dragging": False,
214+
}
215+
block, events = create_bubbler(node)
216+
assert isinstance(block, Bubbler)

test/test_convert_python.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"test_files/constant_delay_scope.json",
103103
"test_files/custom_nodes.json",
104104
"test_files/same_label.json",
105+
"test_files/bubbler.json",
105106
],
106107
)
107108
def test_nested_templates(data):

test/test_files/bubbler.json

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
{
2+
"nodes": [
3+
{
4+
"id": "1",
5+
"type": "bubbler",
6+
"position": {
7+
"x": 644,
8+
"y": 335
9+
},
10+
"data": {
11+
"label": "bubbler 1",
12+
"conversion_efficiency": "",
13+
"replacement_times": "",
14+
"vial_efficiency": ""
15+
},
16+
"measured": {
17+
"width": 230,
18+
"height": 160
19+
},
20+
"selected": true,
21+
"dragging": false
22+
},
23+
{
24+
"id": "2",
25+
"type": "constant",
26+
"position": {
27+
"x": 250,
28+
"y": 200
29+
},
30+
"data": {
31+
"label": "constant 2",
32+
"value": ""
33+
},
34+
"measured": {
35+
"width": 205,
36+
"height": 53
37+
}
38+
},
39+
{
40+
"id": "3",
41+
"type": "scope",
42+
"position": {
43+
"x": 1165,
44+
"y": 314
45+
},
46+
"data": {
47+
"label": "scope 3",
48+
"labels": "",
49+
"sampling_rate": "",
50+
"t_wait": ""
51+
},
52+
"measured": {
53+
"width": 120,
54+
"height": 140
55+
},
56+
"selected": false,
57+
"dragging": false
58+
}
59+
],
60+
"edges": [
61+
{
62+
"id": "e2-1-to_sample_in_soluble",
63+
"source": "2",
64+
"target": "1",
65+
"sourceHandle": null,
66+
"targetHandle": "sample_in_soluble",
67+
"type": "smoothstep",
68+
"data": {},
69+
"style": {
70+
"strokeWidth": 2,
71+
"stroke": "#ECDFCC"
72+
},
73+
"markerEnd": {
74+
"type": "arrowclosed",
75+
"width": 20,
76+
"height": 20,
77+
"color": "#ECDFCC"
78+
}
79+
},
80+
{
81+
"id": "e2-1-to_sample_in_insoluble",
82+
"source": "2",
83+
"target": "1",
84+
"sourceHandle": null,
85+
"targetHandle": "sample_in_insoluble",
86+
"type": "smoothstep",
87+
"data": {},
88+
"style": {
89+
"strokeWidth": 2,
90+
"stroke": "#ECDFCC"
91+
},
92+
"markerEnd": {
93+
"type": "arrowclosed",
94+
"width": 20,
95+
"height": 20,
96+
"color": "#ECDFCC"
97+
}
98+
},
99+
{
100+
"id": "e1-3-from_vial1",
101+
"source": "1",
102+
"target": "3",
103+
"sourceHandle": "vial1",
104+
"targetHandle": null,
105+
"type": "smoothstep",
106+
"data": {},
107+
"style": {
108+
"strokeWidth": 2,
109+
"stroke": "#ECDFCC"
110+
},
111+
"markerEnd": {
112+
"type": "arrowclosed",
113+
"width": 20,
114+
"height": 20,
115+
"color": "#ECDFCC"
116+
}
117+
},
118+
{
119+
"id": "e1-3-from_vial2",
120+
"source": "1",
121+
"target": "3",
122+
"sourceHandle": "vial2",
123+
"targetHandle": null,
124+
"type": "smoothstep",
125+
"data": {},
126+
"style": {
127+
"strokeWidth": 2,
128+
"stroke": "#ECDFCC"
129+
},
130+
"markerEnd": {
131+
"type": "arrowclosed",
132+
"width": 20,
133+
"height": 20,
134+
"color": "#ECDFCC"
135+
}
136+
},
137+
{
138+
"id": "e1-3-from_vial3",
139+
"source": "1",
140+
"target": "3",
141+
"sourceHandle": "vial3",
142+
"targetHandle": null,
143+
"type": "smoothstep",
144+
"data": {},
145+
"style": {
146+
"strokeWidth": 2,
147+
"stroke": "#ECDFCC"
148+
},
149+
"markerEnd": {
150+
"type": "arrowclosed",
151+
"width": 20,
152+
"height": 20,
153+
"color": "#ECDFCC"
154+
}
155+
},
156+
{
157+
"id": "e1-3-from_vial4",
158+
"source": "1",
159+
"target": "3",
160+
"sourceHandle": "vial4",
161+
"targetHandle": null,
162+
"type": "smoothstep",
163+
"data": {},
164+
"style": {
165+
"strokeWidth": 2,
166+
"stroke": "#ECDFCC"
167+
},
168+
"markerEnd": {
169+
"type": "arrowclosed",
170+
"width": 20,
171+
"height": 20,
172+
"color": "#ECDFCC"
173+
}
174+
}
175+
],
176+
"nodeCounter": 4,
177+
"solverParams": {
178+
"dt": "0.01",
179+
"dt_min": "1e-6",
180+
"dt_max": "1.0",
181+
"Solver": "SSPRK22",
182+
"tolerance_fpi": "1e-6",
183+
"iterations_max": "100",
184+
"log": "true",
185+
"simulation_duration": "50.0",
186+
"extra_params": "{}"
187+
},
188+
"globalVariables": []
189+
}

0 commit comments

Comments
 (0)