Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 188 additions & 0 deletions example_graphs/spectrum.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
{
"nodes": [
{
"id": "0",
"type": "spectrum",
"position": {
"x": 487.91666412353516,
"y": 247.4166660308838
},
"data": {
"label": "spectrum 0",
"alpha": "",
"freq": "np.linspace(0, 1*np.pi, 600)",
"labels": "",
"t_wait": ""
},
"measured": {
"width": 120,
"height": 140
},
"selected": false,
"dragging": false
},
{
"id": "1",
"type": "source",
"position": {
"x": 101.91666412353516,
"y": 210.4166660308838
},
"data": {
"label": "High frequency",
"func": "lambda t: np.sin(1.5*t *2*np.pi)"
},
"measured": {
"width": 205,
"height": 53
},
"selected": false,
"dragging": false
},
{
"id": "2",
"type": "scope",
"position": {
"x": 479.5833282470703,
"y": 446.0833320617676
},
"data": {
"label": "scope 2",
"labels": "",
"sampling_rate": "",
"t_wait": ""
},
"measured": {
"width": 120,
"height": 140
},
"selected": false,
"dragging": false
},
{
"id": "3",
"type": "source",
"position": {
"x": -34.083335876464844,
"y": 299.4166660308838
},
"data": {
"label": "Low frequency",
"func": "lambda t: np.sin(0.5*t * 2*np.pi)"
},
"measured": {
"width": 205,
"height": 53
},
"selected": false,
"dragging": false
},
{
"id": "4",
"type": "adder",
"position": {
"x": 283.1666603088379,
"y": 449.4166650772095
},
"data": {
"label": "adder 4",
"operations": ""
},
"measured": {
"width": 64,
"height": 64
}
}
],
"edges": [
{
"id": "e3-4",
"source": "3",
"target": "4",
"sourceHandle": null,
"targetHandle": null,
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
},
{
"id": "e4-0",
"source": "4",
"target": "0",
"sourceHandle": null,
"targetHandle": null,
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
},
{
"id": "e4-2",
"source": "4",
"target": "2",
"sourceHandle": null,
"targetHandle": null,
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
},
{
"id": "e1-4",
"source": "1",
"target": "4",
"sourceHandle": null,
"targetHandle": null,
"type": "smoothstep",
"data": {},
"style": {
"strokeWidth": 2,
"stroke": "#ECDFCC"
},
"markerEnd": {
"type": "arrowclosed",
"width": 20,
"height": 20,
"color": "#ECDFCC"
}
}
],
"nodeCounter": 5,
"solverParams": {
"dt": "0.01",
"dt_min": "1e-6",
"dt_max": "1.0",
"Solver": "SSPRK22",
"tolerance_fpi": "1e-6",
"iterations_max": "100",
"log": "true",
"simulation_duration": "2*2*np.pi",
"extra_params": "{}"
},
"globalVariables": []
}
32 changes: 0 additions & 32 deletions mwe.py

This file was deleted.

75 changes: 42 additions & 33 deletions src/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import plotly
import json as plotly_json
import inspect
import numpy as np

from .convert_to_python import convert_graph_to_python
from .pathsim_utils import make_pathsim_model, map_str_to_object
from pathsim.blocks import Scope
from pathsim.blocks import Scope, Spectrum

# Sphinx imports for docstring processing
from docutils.core import publish_parts
Expand Down Expand Up @@ -254,47 +255,55 @@ def run_pathsim():

# Generate the plot
scopes = [block for block in my_simulation.blocks if isinstance(block, Scope)]
spectra = [
block for block in my_simulation.blocks if isinstance(block, Spectrum)
]

# FIXME right now only the scopes are converted to CSV
# extra work is needed since spectra and scopes don't share the same x axis
csv_payload = make_csv_payload(scopes)

if len(scopes) == 1:
# Single subplot case
fig = go.Figure()
scope = scopes[0]
fig = make_subplots(
rows=len(scopes) + len(spectra),
cols=1,
shared_xaxes=False,
subplot_titles=[scope.label for scope in scopes]
+ [spec.label for spec in spectra],
vertical_spacing=0.2,
)

# make scope plots
for i, scope in enumerate(scopes):
time, data = scope.read()

for p, d in enumerate(data):
lb = scope.labels[p] if p < len(scope.labels) else f"port {p}"
fig.add_trace(go.Scatter(x=time, y=d, mode="lines", name=lb))

fig.update_layout(
title=scope.label,
xaxis_title="Time",
yaxis_title="Value",
hovermode="x unified",
)
else:
# Multiple subplots case
fig = make_subplots(
rows=len(scopes),
cols=1,
shared_xaxes=True,
subplot_titles=[scope.label for scope in scopes],
vertical_spacing=0.1,
)

for i, scope in enumerate(scopes):
time, data = scope.read()

for p, d in enumerate(data):
lb = scope.labels[p] if p < len(scope.labels) else f"port {p}"
fig.add_trace(
go.Scatter(x=time, y=d, mode="lines", name=lb), row=i + 1, col=1
)

fig.update_layout(height=400 * len(scopes), hovermode="x unified")
if isinstance(scope, Spectrum):
d = abs(d)
fig.add_trace(
go.Scatter(x=time, y=d, mode="lines", name=lb), row=i + 1, col=1
)

fig.update_xaxes(title_text="Time", row=len(scopes), col=1)

# make spectrum plots
for i, spec in enumerate(spectra):
time, data = spec.read()

for p, d in enumerate(data):
lb = spec.labels[p] if p < len(spec.labels) else f"port {p}"
d = abs(d)
fig.add_trace(
go.Scatter(x=time, y=d, mode="lines", name=lb),
row=len(scopes) + i + 1,
col=1,
)
fig.update_xaxes(title_text="Frequency", row=len(scopes) + i + 1, col=1)

fig.update_layout(
height=400 * (len(scopes) + len(spectra)), hovermode="x unified"
)

# Convert plot to JSON
plot_data = plotly_json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

Expand Down
4 changes: 3 additions & 1 deletion src/nodeConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const nodeTypes = {
bubbler: BubblerNode,
white_noise: SourceNode,
pink_noise: SourceNode,
spectrum: ScopeNode,
differentiator: DefaultNode
};

Expand All @@ -65,7 +66,7 @@ export const nodeCategories = {
description: 'Fuel cycle specific nodes'
},
'Output': {
nodes: ['scope'],
nodes: ['scope', 'spectrum'],
description: 'Output and visualization nodes'
}
};
Expand Down Expand Up @@ -96,6 +97,7 @@ export const getNodeDisplayName = (nodeType) => {
'bubbler': 'Bubbler',
'wall': 'Wall',
'scope': 'Scope',
'spectrum': 'Spectrum',
'differentiator': 'Differentiator',
};

Expand Down
8 changes: 5 additions & 3 deletions src/pathsim_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Delay,
RNG,
PID,
Spectrum,
Differentiator,
Schedule,
)
Expand Down Expand Up @@ -64,6 +65,7 @@
"wall": FestimWall,
"white_noise": WhiteNoise,
"pink_noise": PinkNoise,
"spectrum": Spectrum,
}


Expand All @@ -78,7 +80,7 @@ def find_block_by_id(block_id: str, blocks: list[Block]) -> Block:
def make_global_variables(global_vars):
# Validate and exec global variables so that they are usable later in this script.
# Return a namespace dictionary containing the global variables
global_namespace = {}
global_namespace = globals()

for var in global_vars:
var_name = var.get("name", "").strip()
Expand All @@ -105,7 +107,7 @@ def make_global_variables(global_vars):

try:
# Execute in global namespace for backwards compatibility
exec(f"{var_name} = {var_value}", globals())
exec(f"{var_name} = {var_value}", global_namespace)
# Also store in local namespace for eval calls
global_namespace[var_name] = eval(var_value)
except Exception as e:
Expand Down Expand Up @@ -313,7 +315,7 @@ def make_connections(nodes, edges, blocks) -> list[Connection]:
input_index = get_input_index(target_block, edge, block_to_input_index)

# if it's a scope, add labels if not already present
if isinstance(target_block, Scope):
if isinstance(target_block, (Scope, Spectrum)):
if target_block.labels == []:
scopes_without_labels.append(target_block)
if target_block in scopes_without_labels:
Expand Down
Loading
Loading