From 5059b3a4ca1ceb10f43e0a8245ebdd330b4fd905 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Thu, 31 Jul 2025 11:25:13 -0400 Subject: [PATCH 1/4] added test to catch the bug --- test/test_convert_python.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/test_convert_python.py b/test/test_convert_python.py index ee059757..c1e3d412 100644 --- a/test/test_convert_python.py +++ b/test/test_convert_python.py @@ -127,5 +127,39 @@ def test_stepsource_delay_converted_to_tau(): assert "tau=3.0" in code +def test_bubbler_has_reset_times(): + """Test that the bubbler node has reset times in the generated code.""" + sample_data = { + "nodes": [ + { + "id": "1", + "type": "bubbler", + "data": { + "label": "bubbler_1", + "replacement_time": "[10, 20]", + "conversion_efficiency": "1", + "vial_efficiency": "0.8", + }, + }, + ], + "edges": [], + "solverParams": { + "Solver": "SSPRK22", + "dt": "0.01", + "dt_max": "1.0", + "dt_min": "1e-6", + "extra_params": "{}", + "iterations_max": "100", + "log": "true", + "simulation_duration": "duration", + "tolerance_fpi": "1e-6", + }, + "globalVariables": [], + } + code = convert_graph_to_python(sample_data) + print(code) + assert "bubbler_1.reset()" in code + + if __name__ == "__main__": test_nested_templates() From e4dc06df22b43959c1a37e735fed8e8485b816db Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Thu, 31 Jul 2025 11:25:28 -0400 Subject: [PATCH 2/4] added new macro for bubbler block --- src/templates/block_macros.py | 21 +++++++++++++++++++++ src/templates/template_with_macros.py | 5 ++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/templates/block_macros.py b/src/templates/block_macros.py index d83b1b96..1b3d0f15 100644 --- a/src/templates/block_macros.py +++ b/src/templates/block_macros.py @@ -30,6 +30,27 @@ def reset_itg(_): {%- endmacro -%} +{% macro create_bubbler_block(node) -%} +{{ create_block(node) }} + +{%- if node["data"].get("replacement_time") %} +def reset_itg(_): + {{ node["var_name"] }}.reset() + +for t in {{ node["data"].get("replacement_time", "[]") }}: + events.append( + pathsim.events.Schedule( + t_start=t, + t_end=t, + func_act=reset_itg, + ) + ) +{%- endif %} + +{%- endmacro -%} + + + {% macro create_function_block(node) -%} def func(x): diff --git a/src/templates/template_with_macros.py b/src/templates/template_with_macros.py index 0663e630..f98480d4 100644 --- a/src/templates/template_with_macros.py +++ b/src/templates/template_with_macros.py @@ -4,7 +4,7 @@ import matplotlib.pyplot as plt import src {# Import macros #} -{% from 'block_macros.py' import create_block, create_source_block, create_integrator_block, create_function_block, create_scope_block, create_stepsource, create_connections -%} +{% from 'block_macros.py' import create_block, create_source_block, create_integrator_block, create_function_block, create_scope_block, create_stepsource, create_bubbler_block, create_connections -%} # Create global variables {% for var in globalVariables -%} @@ -22,6 +22,9 @@ {{ create_function_block(node) }} {%- elif node["type"] == "scope" -%} {{ create_scope_block(node) }} +{%- elif node["type"] == "bubbler" -%} +{{ create_bubbler_block(node) }} +{%- elif node["type"] == "source" -%} {%- else -%} {{ create_block(node) }} {%- endif %} From eff70877c6fc987458e155b8dcde16c0e6734793 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Thu, 31 Jul 2025 11:43:54 -0400 Subject: [PATCH 3/4] replacement_time to replacement_times + simplified template to use internal method --- saved_graphs/baby.json | 4 ++-- src/App.jsx | 2 +- src/custom_pathsim_blocks.py | 1 + src/pathsim_utils.py | 4 ++-- src/templates/block_macros.py | 19 +++++-------------- test/test_convert_python.py | 2 +- 6 files changed, 12 insertions(+), 20 deletions(-) diff --git a/saved_graphs/baby.json b/saved_graphs/baby.json index bd3b72df..0991b427 100644 --- a/saved_graphs/baby.json +++ b/saved_graphs/baby.json @@ -175,7 +175,7 @@ "label": "IV bubbler", "conversion_efficiency": "0.95", "vial_efficiency": "0.9", - "replacement_time": "np.arange(5, 50, step=3)" + "replacement_times": "np.arange(5, 50, step=3)" }, "measured": { "width": 230, @@ -233,7 +233,7 @@ "label": "OV bubbler", "conversion_efficiency": "0.95", "vial_efficiency": "0.9", - "replacement_time": "np.arange(5, 50, step=5)" + "replacement_times": "np.arange(5, 50, step=5)" }, "measured": { "width": 230, diff --git a/src/App.jsx b/src/App.jsx index 6f657110..c1e23543 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -470,7 +470,7 @@ export default function App() { nodeData = { ...nodeData, f1: '1/3', f2: '1/3', f3: '1/3' }; break; case 'bubbler': - nodeData = { ...nodeData, conversion_efficiency: '0.95', vial_efficiency: '0.9', replacement_time: '' }; + nodeData = { ...nodeData, conversion_efficiency: '0.95', vial_efficiency: '0.9', replacement_times: '' }; default: // For any other types, just use basic data break; diff --git a/src/custom_pathsim_blocks.py b/src/custom_pathsim_blocks.py index a7784c08..f6031fa0 100644 --- a/src/custom_pathsim_blocks.py +++ b/src/custom_pathsim_blocks.py @@ -169,4 +169,5 @@ def create_reset_events(self) -> list[pathsim.blocks.Schedule]: ) for i, vial in enumerate(self.vials): events.extend(self._create_reset_events_one_vial(vial, reset_times[i])) + return events diff --git a/src/pathsim_utils.py b/src/pathsim_utils.py index c40bc46b..f18378c7 100644 --- a/src/pathsim_utils.py +++ b/src/pathsim_utils.py @@ -144,8 +144,8 @@ def create_bubbler(node: dict) -> Bubbler: block = Bubbler( conversion_efficiency=eval(node["data"]["conversion_efficiency"]), vial_efficiency=eval(node["data"]["vial_efficiency"]), - replacement_times=eval(node["data"]["replacement_time"]) - if node["data"].get("replacement_time") != "" + replacement_times=eval(node["data"]["replacement_times"]) + if node["data"].get("replacement_times") != "" else None, ) diff --git a/src/templates/block_macros.py b/src/templates/block_macros.py index 1b3d0f15..de677dab 100644 --- a/src/templates/block_macros.py +++ b/src/templates/block_macros.py @@ -14,7 +14,7 @@ {{ create_block(node) }} {%- if node["data"].get("reset_times") %} -def reset_itg(_): +def reset_{{ node["var_name"] }}(_): {{ node["var_name"] }}.reset() for t in {{ node["data"].get("reset_times", "[]") }}: @@ -22,7 +22,7 @@ def reset_itg(_): pathsim.events.Schedule( t_start=t, t_end=t, - func_act=reset_itg, + func_act=reset_{{ node["var_name"] }}, ) ) {%- endif %} @@ -33,18 +33,9 @@ def reset_itg(_): {% macro create_bubbler_block(node) -%} {{ create_block(node) }} -{%- if node["data"].get("replacement_time") %} -def reset_itg(_): - {{ node["var_name"] }}.reset() - -for t in {{ node["data"].get("replacement_time", "[]") }}: - events.append( - pathsim.events.Schedule( - t_start=t, - t_end=t, - func_act=reset_itg, - ) - ) +{%- if node["data"].get("replacement_times") %} +events_{{ node["var_name"] }} = {{ node["var_name"] }}.create_reset_events() +events += events_{{ node["var_name"] }} {%- endif %} {%- endmacro -%} diff --git a/test/test_convert_python.py b/test/test_convert_python.py index c1e3d412..77cd28f4 100644 --- a/test/test_convert_python.py +++ b/test/test_convert_python.py @@ -136,7 +136,7 @@ def test_bubbler_has_reset_times(): "type": "bubbler", "data": { "label": "bubbler_1", - "replacement_time": "[10, 20]", + "replacement_times": "[10, 20]", "conversion_efficiency": "1", "vial_efficiency": "0.8", }, From 6544746bff018476787e6a538023f111b810ca7b Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Thu, 31 Jul 2025 11:44:47 -0400 Subject: [PATCH 4/4] fixed test --- test/test_convert_python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_convert_python.py b/test/test_convert_python.py index 77cd28f4..d70660e7 100644 --- a/test/test_convert_python.py +++ b/test/test_convert_python.py @@ -158,7 +158,7 @@ def test_bubbler_has_reset_times(): } code = convert_graph_to_python(sample_data) print(code) - assert "bubbler_1.reset()" in code + assert "bubbler_1.create_reset_events()" in code if __name__ == "__main__":