multimodalsim-viewer 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl
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.
- multimodalsim_viewer/common/__init__.py +0 -0
- multimodalsim_viewer/common/environments/.env +4 -0
- multimodalsim_viewer/common/utils.py +223 -0
- multimodalsim_viewer/server/http_routes.py +135 -125
- multimodalsim_viewer/server/log_manager.py +10 -15
- multimodalsim_viewer/server/scripts.py +106 -32
- multimodalsim_viewer/server/server.py +196 -210
- multimodalsim_viewer/server/simulation.py +167 -154
- multimodalsim_viewer/server/simulation_manager.py +570 -607
- multimodalsim_viewer/server/simulation_visualization_data_collector.py +729 -756
- multimodalsim_viewer/server/simulation_visualization_data_model.py +1552 -1693
- multimodalsim_viewer/ui/angular_app.py +40 -0
- multimodalsim_viewer/ui/static/chunk-6VAXIXEZ.js +7 -0
- multimodalsim_viewer/ui/static/{chunk-MTC2LSCT.js → chunk-IGIP6IOU.js} +1 -1
- multimodalsim_viewer/ui/static/environment.json +7 -0
- multimodalsim_viewer/ui/static/index.html +16 -15
- multimodalsim_viewer/ui/static/{main-X7OVCS3N.js → main-FGMGJ32M.js} +3648 -3648
- multimodalsim_viewer/ui/static/polyfills-FFHMD2TL.js +2 -2
- multimodalsim_viewer/ui/static/scripts/load-environment.script.js +20 -0
- multimodalsim_viewer/ui/static/styles-KU7LTPET.css +1 -1
- multimodalsim_viewer-0.0.2.dist-info/METADATA +70 -0
- multimodalsim_viewer-0.0.2.dist-info/RECORD +41 -0
- {multimodalsim_viewer-0.0.1.dist-info → multimodalsim_viewer-0.0.2.dist-info}/WHEEL +1 -1
- multimodalsim_viewer-0.0.2.dist-info/entry_points.txt +2 -0
- multimodalsim_viewer/server/server_utils.py +0 -129
- multimodalsim_viewer/ui/cli.py +0 -45
- multimodalsim_viewer/ui/server.py +0 -44
- multimodalsim_viewer/ui/static/chunk-U5CGW4P4.js +0 -7
- multimodalsim_viewer-0.0.1.dist-info/METADATA +0 -21
- multimodalsim_viewer-0.0.1.dist-info/RECORD +0 -38
- multimodalsim_viewer-0.0.1.dist-info/entry_points.txt +0 -8
- {multimodalsim_viewer-0.0.1.dist-info → multimodalsim_viewer-0.0.2.dist-info}/top_level.txt +0 -0
@@ -1,154 +1,167 @@
|
|
1
|
-
import
|
2
|
-
import
|
3
|
-
|
4
|
-
|
5
|
-
from
|
6
|
-
|
7
|
-
|
8
|
-
from
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
parser
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
)
|
83
|
-
parser.add_argument(
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
data
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
)
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
1
|
+
import argparse
|
2
|
+
import os
|
3
|
+
import sys
|
4
|
+
import threading
|
5
|
+
from argparse import ArgumentParser, Namespace
|
6
|
+
|
7
|
+
import questionary
|
8
|
+
from multimodalsim.observer.data_collector import DataContainer, StandardDataCollector
|
9
|
+
from multimodalsim.observer.environment_observer import EnvironmentObserver
|
10
|
+
from multimodalsim.simulator.simulator import Simulator
|
11
|
+
from multimodalsim.statistics.data_analyzer import FixedLineDataAnalyzer
|
12
|
+
|
13
|
+
from multimodalsim_viewer.common.utils import (
|
14
|
+
build_simulation_id,
|
15
|
+
get_available_data,
|
16
|
+
get_input_data_directory_path,
|
17
|
+
set_event_on_input,
|
18
|
+
verify_simulation_name,
|
19
|
+
)
|
20
|
+
from multimodalsim_viewer.server.simulation_visualization_data_collector import (
|
21
|
+
SimulationVisualizationDataCollector,
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
def run_simulation(
|
26
|
+
simulation_id: str,
|
27
|
+
data: str,
|
28
|
+
max_duration: float | None,
|
29
|
+
stop_event: threading.Event | None = None,
|
30
|
+
is_offline: bool = False,
|
31
|
+
) -> None:
|
32
|
+
data_container = DataContainer()
|
33
|
+
|
34
|
+
data_collector = SimulationVisualizationDataCollector(
|
35
|
+
FixedLineDataAnalyzer(data_container),
|
36
|
+
max_duration=max_duration,
|
37
|
+
simulation_id=simulation_id,
|
38
|
+
input_data_description=data,
|
39
|
+
offline=is_offline,
|
40
|
+
stop_event=stop_event,
|
41
|
+
)
|
42
|
+
|
43
|
+
environment_observer = EnvironmentObserver(
|
44
|
+
[StandardDataCollector(data_container), data_collector],
|
45
|
+
)
|
46
|
+
|
47
|
+
simulation_data_directory = get_input_data_directory_path(data) + "/"
|
48
|
+
|
49
|
+
if not os.path.exists(simulation_data_directory):
|
50
|
+
print(f"Simulation data directory {simulation_data_directory} does not exist")
|
51
|
+
return
|
52
|
+
|
53
|
+
simulator = Simulator(
|
54
|
+
simulation_data_directory,
|
55
|
+
visualizers=environment_observer.visualizers,
|
56
|
+
data_collectors=environment_observer.data_collectors,
|
57
|
+
)
|
58
|
+
simulation_thread = threading.Thread(target=simulator.simulate)
|
59
|
+
simulation_thread.start()
|
60
|
+
|
61
|
+
# Wait for the simulation to finish
|
62
|
+
while simulation_thread.is_alive() and (stop_event is None or not stop_event.is_set()):
|
63
|
+
simulation_thread.join(timeout=5) # Check every 5 seconds
|
64
|
+
|
65
|
+
if simulation_thread.is_alive():
|
66
|
+
print("Simulation is still running, stopping it")
|
67
|
+
simulator.stop()
|
68
|
+
|
69
|
+
simulation_thread.join()
|
70
|
+
|
71
|
+
if stop_event is not None:
|
72
|
+
stop_event.set()
|
73
|
+
|
74
|
+
|
75
|
+
def configure_simulation_parser(
|
76
|
+
parser: ArgumentParser | None = None, # pylint: disable=redefined-outer-name
|
77
|
+
) -> ArgumentParser:
|
78
|
+
if parser is None:
|
79
|
+
parser = argparse.ArgumentParser(description="Run a simulation")
|
80
|
+
|
81
|
+
parser.add_argument("--name", type=str, help="The name of the simulation")
|
82
|
+
parser.add_argument("--data", type=str, help="The data to use for the simulation")
|
83
|
+
parser.add_argument("--max-duration", type=float, help="The maximum duration to run the simulation")
|
84
|
+
parser.add_argument(
|
85
|
+
"--offline",
|
86
|
+
action="store_true",
|
87
|
+
help="Run the simulation in offline mode (does not connect to the server)",
|
88
|
+
)
|
89
|
+
|
90
|
+
return parser
|
91
|
+
|
92
|
+
|
93
|
+
def start_simulation_cli(parsed_arguments: Namespace) -> None:
|
94
|
+
name = parsed_arguments.name
|
95
|
+
data = parsed_arguments.data
|
96
|
+
max_duration = parsed_arguments.max_duration
|
97
|
+
is_offline = parsed_arguments.offline
|
98
|
+
|
99
|
+
name_error = verify_simulation_name(name)
|
100
|
+
|
101
|
+
while name_error is not None:
|
102
|
+
print(f"Error: {name_error}")
|
103
|
+
name = questionary.text("Enter the name of the simulation (spaces will be replaced by underscores)").ask()
|
104
|
+
|
105
|
+
if name is None:
|
106
|
+
print("Exiting")
|
107
|
+
return
|
108
|
+
|
109
|
+
name_error = verify_simulation_name(name)
|
110
|
+
|
111
|
+
name = name.replace(" ", "_")
|
112
|
+
|
113
|
+
available_data = get_available_data()
|
114
|
+
|
115
|
+
if len(available_data) == 0:
|
116
|
+
print("No input data is available, please provide some in the data folder")
|
117
|
+
sys.exit(1)
|
118
|
+
|
119
|
+
if data is None:
|
120
|
+
# Get all available data
|
121
|
+
|
122
|
+
data = questionary.select(
|
123
|
+
"Select the data to use for the simulation",
|
124
|
+
choices=available_data,
|
125
|
+
).ask()
|
126
|
+
|
127
|
+
print("Selected data:", data)
|
128
|
+
|
129
|
+
if data not in available_data:
|
130
|
+
print("The provided data is not available")
|
131
|
+
sys.exit(1)
|
132
|
+
|
133
|
+
simulation_id, _ = build_simulation_id(name)
|
134
|
+
|
135
|
+
print(
|
136
|
+
f"Running simulation with id: {simulation_id}, data: {data} and "
|
137
|
+
f"{f'max duration: {max_duration}' if max_duration is not None else 'no max duration'}"
|
138
|
+
f"{is_offline and ' in offline mode' or ''}"
|
139
|
+
)
|
140
|
+
|
141
|
+
stop_event = threading.Event()
|
142
|
+
input_listener_thread = threading.Thread(
|
143
|
+
target=set_event_on_input,
|
144
|
+
args=("stop the simulation", "q", stop_event),
|
145
|
+
name="InputListener",
|
146
|
+
# This is a daemon thread, so it will be
|
147
|
+
# automatically terminated when the main thread is terminated.
|
148
|
+
daemon=True,
|
149
|
+
)
|
150
|
+
|
151
|
+
input_listener_thread.start()
|
152
|
+
|
153
|
+
run_simulation(simulation_id, data, max_duration, stop_event, is_offline)
|
154
|
+
|
155
|
+
print("To run a simulation with the same configuration, use the following command:")
|
156
|
+
print(
|
157
|
+
f"viewer simulate --data {data} "
|
158
|
+
f"{f'--max-duration {max_duration} ' if max_duration is not None else ''}"
|
159
|
+
f"{'--offline ' if is_offline else ''}"
|
160
|
+
f"--name {name}" # Name last to allow quick name change when re-running the command
|
161
|
+
)
|
162
|
+
|
163
|
+
|
164
|
+
if __name__ == "__main__":
|
165
|
+
parser = configure_simulation_parser()
|
166
|
+
args = parser.parse_args()
|
167
|
+
start_simulation_cli(args)
|