Skip to content
Snippets Groups Projects

Draft: Added support for plotting result from many simulations. Solves #209

Open Petter Källström requested to merge MultiSimPlot into master
4 unresolved threads
Files
2
@@ -23,6 +23,7 @@ from qtpy.QtWidgets import ( # QFrame,; QScrollArea,; QLineEdit,; QSizePolicy,;
@@ -23,6 +23,7 @@ from qtpy.QtWidgets import ( # QFrame,; QScrollArea,; QLineEdit,; QSizePolicy,;
QWidget,
QWidget,
)
)
 
from b_asic import Simulation
from b_asic.gui_utils.icons import get_icon
from b_asic.gui_utils.icons import get_icon
from b_asic.operation import ResultKey
from b_asic.operation import ResultKey
from b_asic.types import Num
from b_asic.types import Num
@@ -30,12 +31,13 @@ from b_asic.types import Num
@@ -30,12 +31,13 @@ from b_asic.types import Num
class PlotWindow(QWidget):
class PlotWindow(QWidget):
"""
"""
Dialog for plotting the result of a simulation.
Dialog for plotting the result of simulations.
Parameters
Parameters
----------
----------
sim_result : dict
sim_result : dict
Simulation results of the form obtained from :attr:`~b_asic.simulation.Simulation.results`.
Simulation results of the form obtained from :attr:`~b_asic.simulation.Simulation.results`.
 
Alternative, sim_result can be a list, ['name1', sim_result1, 'name2', sim_result2, ...]
sfg_name : str, optional
sfg_name : str, optional
The name of the SFG.
The name of the SFG.
parent : optional
parent : optional
@@ -62,8 +64,60 @@ class PlotWindow(QWidget):
@@ -62,8 +64,60 @@ class PlotWindow(QWidget):
self.setWindowTitle(title)
self.setWindowTitle(title)
self._auto_redraw = False
self._auto_redraw = False
 
########### Flattening sim_result, if it is a list of results #######
 
# take: sim_result (possibly on form ['name1', simres1, 'name2', simres2, ...]
 
# generate: sim_result (dict)
 
if type(sim_result) == Simulation:
Please register or sign in to reply
 
sim_result = sim_result._results
 
assert type(sim_result) == dict, TypeError(
 
"Parsing sim_result as a Simulation, but the _result seems broken."
 
)
 
elif type(sim_result) == list:
Please register or sign in to reply
 
new_result = dict()
 
nr = 0 # value number. Used for automatic names.
 
name = None
 
for element in sim_result:
 
if type(element) == str:
 
assert not name, Exception(
 
"Parsing sim_result as a list. Did you provide two names after"
 
" each other?"
 
)
 
name = element
 
else:
 
if not name:
 
nr = nr + 1
 
name = "(res" + str(nr) + ")"
 
if type(element) == dict:
 
res = element
 
elif type(element) == Simulation:
 
res = element._results
 
assert type(res) == dict, TypeError(
 
f"Parsing sim_result as a list. Result '{name}' is a"
 
" Simulation, and its _result seems broken."
 
)
 
else:
 
raise TypeError(
 
"Parsing sim_result as a list. Supported results are dict"
 
f" and Simulation, but result '{name}' is {type(element)}"
 
)
 
for key, result in res.items():
 
if re.fullmatch("[0-9]+", key): # it's an output
 
key = "out" + key
 
new_result[name + "." + key] = result
 
name = None
 
assert not name, Exception(
 
"Parsing sim_result as a list. Did you provide a name as the last item"
 
" in the list?"
 
)
 
sim_result = new_result
 
elif type(sim_result) != dict:
 
raise TypeError(
 
"sim_result must be a dict, Simulation or list. Found"
 
f" {type(sim_result)}"
 
)
 
########### Categorizing/sorting/renaming sim_results: ##############
########### Categorizing/sorting/renaming sim_results: ##############
# take: sim_results
# take: sim_result
# generate: key_order, initially_checked
# generate: key_order, initially_checked
# generate: updated_result
# generate: updated_result
initially_checked = []
initially_checked = []
@@ -72,12 +126,16 @@ class PlotWindow(QWidget):
@@ -72,12 +126,16 @@ class PlotWindow(QWidget):
n = 0
n = 0
for key, result in sim_result.items():
for key, result in sim_result.items():
key2 = key # in most cases
key2 = key # in most cases
if re.fullmatch("in[0-9]+", key):
if re.fullmatch(r"(.*\.)?in[0-9]+", key):
m = 4
m = 4
elif re.fullmatch("[0-9]+", key):
elif re.fullmatch(r"[0-9]+", key): # It's an output as just a number.
m = 3
m = 3
key2 = 'o' + key
key2 = 'out' + key
elif re.fullmatch("t[0-9]+", key):
elif re.fullmatch(
 
r"(.*\.)?out[0-9]+", key
 
): # It's an output already formulated.
 
m = 3
 
elif re.fullmatch(r"(.*\.)?t[0-9]+", key):
m = 2
m = 2
else:
else:
m = 1
m = 1
@@ -130,8 +188,16 @@ class PlotWindow(QWidget):
@@ -130,8 +188,16 @@ class PlotWindow(QWidget):
self._plot_axes.xaxis.set_major_locator(MaxNLocator(integer=True))
self._plot_axes.xaxis.set_major_locator(MaxNLocator(integer=True))
self._lines = {}
self._lines = {}
 
markers = ".ov<^>s+*xd|_"
 
fmt = '-'
 
ix = 0 # index bytes in markers
for key in key_order:
for key in key_order:
line = self._plot_axes.plot(updated_result[key], label=key)
if len(updated_result[key]) <= 100:
 
fmt = markers[ix] + '-'
 
ix = (ix + 1) % len(markers)
 
else:
 
fmt = '-'
 
line = self._plot_axes.plot(updated_result[key], fmt, label=key)
self._lines[key] = line[0]
self._lines[key] = line[0]
self._plot_canvas = FigureCanvas(self._plot_fig)
self._plot_canvas = FigureCanvas(self._plot_fig)
@@ -254,6 +320,7 @@ def start_simulation_dialog(
@@ -254,6 +320,7 @@ def start_simulation_dialog(
----------
----------
sim_results : dict
sim_results : dict
Simulation results of the form obtained from :attr:`~b_asic.simulation.Simulation.results`.
Simulation results of the form obtained from :attr:`~b_asic.simulation.Simulation.results`.
 
Alternative, sim_result can be a list, ['name1', sim_result1, 'name2', sim_result2, ...]
sfg_name : str, optional
sfg_name : str, optional
The name of the SFG.
The name of the SFG.
"""
"""
@@ -268,7 +335,19 @@ def start_simulation_dialog(
@@ -268,7 +335,19 @@ def start_simulation_dialog(
# Simple test of the dialog
# Simple test of the dialog
if __name__ == "__main__":
if __name__ == "__main__":
sim_res = {
sim_res1 = {
 
'0': [1.5, 1.6, 1.5, 1],
 
'1': [1.0, 2.0, 1.5, 1.1],
 
'add1': [1.5, 1.5, 1, 1],
 
'cmul1': [1, 1.5, 1, 1],
 
'cmul2': [1.5, 1, 1, 1],
 
'in1': [2, 1, 1, 1],
 
'in2': [1.1, 3, 1, 1],
 
't1': [1, 2, 1, 1],
 
't2': [1, 1, 2, 1],
 
't3': [1, 1, 1, 2],
 
}
 
sim_res2 = {
'0': [0.5, 0.6, 0.5, 0],
'0': [0.5, 0.6, 0.5, 0],
'1': [0.0, 1.0 + 0.3j, 0.5, 0.1j],
'1': [0.0, 1.0 + 0.3j, 0.5, 0.1j],
'add1': [0.5, 0.5, 0, 0],
'add1': [0.5, 0.5, 0, 0],
@@ -280,4 +359,11 @@ if __name__ == "__main__":
@@ -280,4 +359,11 @@ if __name__ == "__main__":
't2': [0, 0, 1, 0],
't2': [0, 0, 1, 0],
't3': [0, 0, 0, 1],
't3': [0, 0, 0, 1],
}
}
start_simulation_dialog(sim_res, "Test data")
sim_res3 = {
 
'0': np.random.rand(200).tolist(),
 
'1': np.random.rand(200).tolist(),
 
}
 
# start_simulation_dialog(sim_res3)
 
start_simulation_dialog(
 
['simReal', sim_res1, 'simCpx', sim_res2, sim_res3], "Test data"
 
)
Loading