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