gareth commited on
Commit
b1a989d
·
1 Parent(s): b93f644

feat: add agent parameters, more info labels

Browse files
app.py CHANGED
@@ -7,14 +7,18 @@ from ui.tabs.with_agent_tab import WithAgentTab
7
  with gr.Blocks(theme=gr.themes.Glass()) as interface:
8
  gr.Markdown("**Social distancing sim**")
9
  gr.Markdown(
10
- "Graph based disease spread simulator. Uses https://github.com/garethjns/social-distancing-sim - "
11
- "see [README](https://github.com/garethjns/social-distancing-sim/blob/master/README.MD) "
12
- "for details."
 
 
 
 
13
  )
14
  gr.Markdown(f"App version: {__version__} using `social-distancing-sim==0.11.2`")
15
- _ = SimpleExampleTab().build()
16
- _ = SinglePopTab().build()
17
- _ = WithAgentTab().build()
18
 
19
  if __name__ == "__main__":
20
  interface.launch()
 
7
  with gr.Blocks(theme=gr.themes.Glass()) as interface:
8
  gr.Markdown("**Social distancing sim**")
9
  gr.Markdown(
10
+ """Graph based disease spread simulator. Uses https://github.com/garethjns/social-distancing-sim -
11
+ see [README](https://github.com/garethjns/social-distancing-sim/blob/master/README.MD)
12
+ for details.
13
+
14
+ Individuals in the population are represented as graph nodes, with edges modelling connections
15
+ allowing the possibility of disease transmission. between individuals.
16
+ """
17
  )
18
  gr.Markdown(f"App version: {__version__} using `social-distancing-sim==0.11.2`")
19
+ SimpleExampleTab().build()
20
+ SinglePopTab().build()
21
+ WithAgentTab().build()
22
 
23
  if __name__ == "__main__":
24
  interface.launch()
ui/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.2.0"
 
1
+ __version__ = "0.3.0"
ui/functions/run_gym_env.py CHANGED
@@ -12,18 +12,28 @@ from social_distancing_sim.templates.template_base import TemplateBase
12
 
13
  import gradio as gr
14
 
 
 
 
 
 
 
 
15
 
16
- def _run_and_replay(sim):
17
- sim.run()
18
- if sim.save:
19
- sim.env.replay()
 
 
 
20
 
21
 
22
  class _EnvTemplate(TemplateBase):
23
  def build(self):
24
  seed = np.random.randint(int(1e6))
25
  return env.Environment(
26
- name="visual_compare_basic_agents_custom_env",
27
  disease=env.Disease(
28
  name="COVID-19",
29
  virulence=0.01,
@@ -50,38 +60,57 @@ class CustomEnv(GymEnv):
50
  template = _EnvTemplate()
51
 
52
 
53
- AGENT_TYPE_NAMES = Literal[
54
- "dummy",
55
- "distancing",
56
- "vaccination",
57
- "treatment",
58
- "masking",
59
- ]
60
-
61
- AGENT_TYPE_MAP = {
62
- "dummy": agent.DummyAgent,
63
- "distancing": agent.DistancingPolicyAgent,
64
- "vaccination": agent.VaccinationAgent,
65
- "treatment": agent.TreatmentAgent,
66
- "masking": agent.MaskingAgent,
67
- }
68
-
69
-
70
  def run_gym_env(
71
  name: str,
72
  steps: int,
73
  test_rate: float,
74
  agents: list[AGENT_TYPE_NAMES],
75
- n_actions: int = 6,
76
- progress=gr.Progress(track_tqdm=True),
 
 
 
 
 
 
 
 
 
 
 
 
77
  ):
78
-
79
  if agents is None:
80
  # Set no agent
81
  agents = ["dummy"]
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  # Prepare agents
84
- prepared_agents = [AGENT_TYPE_MAP[a] for a in agents]
85
 
86
  # Prepare a custom environment
87
  env_name = f"SDS-CustomEnv{np.random.randint(int(2e6))}-v0"
@@ -99,8 +128,9 @@ def run_gym_env(
99
  agent_class(
100
  actions_per_turn=adjusted_actions_per_turn,
101
  name=f"{agent_class.__name__} - {n_actions} actions",
 
102
  )
103
- for agent_class in prepared_agents
104
  ]
105
 
106
  if n_agents == 1:
@@ -120,15 +150,7 @@ def run_gym_env(
120
  )
121
 
122
  # Run all the prepared Sims
123
- _run_and_replay(sim)
 
124
 
125
  return pathlib.Path(f"{sim.save_path}/replay.gif")
126
-
127
-
128
- if __name__ == "__main__":
129
- run_gym_env(
130
- name="test",
131
- steps=5,
132
- test_rate=1,
133
- agents=["dummy"],
134
- )
 
12
 
13
  import gradio as gr
14
 
15
+ AGENT_TYPE_NAMES = Literal[
16
+ "dummy",
17
+ "distancing",
18
+ "vaccination",
19
+ "treatment",
20
+ "masking",
21
+ ]
22
 
23
+ AGENT_TYPE_MAP = {
24
+ "dummy": agent.DummyAgent,
25
+ "distancing": agent.DistancingPolicyAgent,
26
+ "vaccination": agent.VaccinationAgent,
27
+ "treatment": agent.TreatmentAgent,
28
+ "masking": agent.MaskingAgent,
29
+ }
30
 
31
 
32
  class _EnvTemplate(TemplateBase):
33
  def build(self):
34
  seed = np.random.randint(int(1e6))
35
  return env.Environment(
36
+ name="custom_env",
37
  disease=env.Disease(
38
  name="COVID-19",
39
  virulence=0.01,
 
60
  template = _EnvTemplate()
61
 
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  def run_gym_env(
64
  name: str,
65
  steps: int,
66
  test_rate: float,
67
  agents: list[AGENT_TYPE_NAMES],
68
+ n_actions: int,
69
+ isolate_start: int,
70
+ reconnect_start: int,
71
+ isolate_end: int,
72
+ reconnect_end: int,
73
+ vaccination_start: int,
74
+ vaccination_end: int,
75
+ treatment_start: int,
76
+ treatment_end: int,
77
+ masking_start: int,
78
+ remove_mask_start: int,
79
+ masking_end: int,
80
+ remove_mask_end: int,
81
+ progress=gr.Progress(track_tqdm=True), # noqa
82
  ):
 
83
  if agents is None:
84
  # Set no agent
85
  agents = ["dummy"]
86
 
87
+ start_step = "start_step"
88
+ end_step = "end_step"
89
+ agent_params = {
90
+ "dummy": {start_step: 0, end_step: steps},
91
+ "distancing": {
92
+ start_step: {"isolate": isolate_start, "reconnect": reconnect_start},
93
+ end_step: {"isolate": isolate_end, "reconnect": reconnect_end},
94
+ },
95
+ "vaccination": {
96
+ start_step: {"vaccinate": vaccination_start},
97
+ end_step: {"vaccinate": vaccination_end},
98
+ },
99
+ "treatment": {
100
+ start_step: {"treat": treatment_start},
101
+ end_step: {"treat": treatment_end},
102
+ },
103
+ "masking": {
104
+ start_step: {
105
+ "provide_mask": masking_start,
106
+ "remove_mask": remove_mask_start,
107
+ },
108
+ end_step: {"provide_mask": masking_end, "remove_mask": remove_mask_end},
109
+ },
110
+ }
111
+
112
  # Prepare agents
113
+ prepared_agents = [(AGENT_TYPE_MAP[a], agent_params[a]) for a in agents]
114
 
115
  # Prepare a custom environment
116
  env_name = f"SDS-CustomEnv{np.random.randint(int(2e6))}-v0"
 
128
  agent_class(
129
  actions_per_turn=adjusted_actions_per_turn,
130
  name=f"{agent_class.__name__} - {n_actions} actions",
131
+ **agent_params,
132
  )
133
+ for agent_class, agent_params in prepared_agents
134
  ]
135
 
136
  if n_agents == 1:
 
150
  )
151
 
152
  # Run all the prepared Sims
153
+ sim.run()
154
+ sim.env.replay()
155
 
156
  return pathlib.Path(f"{sim.save_path}/replay.gif")
 
 
 
 
 
 
 
 
 
ui/functions/run_single_population.py CHANGED
@@ -8,6 +8,8 @@ import gradio as gr
8
  def run_single_population(
9
  name: str,
10
  steps: int,
 
 
11
  test_rate: float,
12
  community_n: int,
13
  community_size_mean: int,
@@ -65,6 +67,8 @@ def run_single_population(
65
  healthcare=healthcare,
66
  environment_plotting=environment_plotting,
67
  observation_space=observation_space,
 
 
68
  )
69
  # Turn logging on
70
  pop.log_to_file = True
 
8
  def run_single_population(
9
  name: str,
10
  steps: int,
11
+ n_initial_infections: int,
12
+ random_infection_chance: float,
13
  test_rate: float,
14
  community_n: int,
15
  community_size_mean: int,
 
67
  healthcare=healthcare,
68
  environment_plotting=environment_plotting,
69
  observation_space=observation_space,
70
+ initial_infections=n_initial_infections,
71
+ random_infection_chance=random_infection_chance,
72
  )
73
  # Turn logging on
74
  pop.log_to_file = True
ui/labels/disease_labels.py CHANGED
@@ -1,5 +1,16 @@
1
  TITLE = "**Disease parameters**"
2
  VIRULENCE = "Virulence"
 
 
 
 
3
  RECOVERY_RATE = "Recovery rate"
 
4
  IMMUNITY_MEAN = "Immunity after recovery"
 
 
 
5
  IMMUNITY_DECAY_MEAN = "Immunity decay rate"
 
 
 
 
1
  TITLE = "**Disease parameters**"
2
  VIRULENCE = "Virulence"
3
+ VIRULENCE_INFO = (
4
+ "Increased virulence makes the disease more likely to "
5
+ "be transferred from an infected node to a connected uninfected node each turn."
6
+ )
7
  RECOVERY_RATE = "Recovery rate"
8
+ RECOVERY_RATE_INFO = "The likelihood an individual will recover at the end of the infection period, rather than dying."
9
  IMMUNITY_MEAN = "Immunity after recovery"
10
+ IMMUNITY_MEAN_INFO = (
11
+ "The average disease immunity gained by an individual that survives infection."
12
+ )
13
  IMMUNITY_DECAY_MEAN = "Immunity decay rate"
14
+ IMMUNITY_DECAY_MEAN_INFO = (
15
+ "The average rate at which a individual's immunity decays after recovery."
16
+ )
ui/labels/healthcare_labels.py CHANGED
@@ -1,3 +1,11 @@
1
  TITLE = "**Healthcare parameters**"
2
  CAPACITY = "Capacity"
 
 
 
 
3
  MAX_PENALTY = "Max penalty when over capacity"
 
 
 
 
 
1
  TITLE = "**Healthcare parameters**"
2
  CAPACITY = "Capacity"
3
+ CAPACITY_INFO = (
4
+ "The capacity of the healthcare system. When there are are more "
5
+ "infected nodes requiring treatment than there is capacity for, chance of death is increased"
6
+ )
7
  MAX_PENALTY = "Max penalty when over capacity"
8
+ MAX_PENALTY_INFO = (
9
+ "The maximum amount by which the chance of an infected node dying is "
10
+ "increased when the healthcare system is over capacity."
11
+ )
ui/labels/population_labels.py CHANGED
@@ -1,6 +1,12 @@
1
  TITLE = "**Population parameters**"
2
  COMMUNITY_N = "Number of communities"
 
 
 
 
3
  MEAN_COMMUNITY_SIZE = "Mean community size"
4
- CONNECTION_RATE = "Connection rate within communities"
 
 
5
  COMMUNITY_P_IN = "Connection rate within communities"
6
  COMMUNITY_P_OUT = "Connection rate between communities"
 
1
  TITLE = "**Population parameters**"
2
  COMMUNITY_N = "Number of communities"
3
+ COMMUNITY_N_INFO = (
4
+ "Communities are cluster of graph nodes, with generally more connections "
5
+ "between members than with non-members."
6
+ )
7
  MEAN_COMMUNITY_SIZE = "Mean community size"
8
+ MEAN_COMMUNITY_SIZE_INFO = (
9
+ "Mean number of members (nodes) in each community (cluster of nodes)."
10
+ )
11
  COMMUNITY_P_IN = "Connection rate within communities"
12
  COMMUNITY_P_OUT = "Connection rate between communities"
ui/labels/simulation_labels.py CHANGED
@@ -1,4 +1,22 @@
1
  TITLE = "**Simulation parameters**"
2
  OUTPUT_PATH = "Output path"
3
  STEPS = "Number of steps"
 
4
  TEST_RATE = "Test rate"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  TITLE = "**Simulation parameters**"
2
  OUTPUT_PATH = "Output path"
3
  STEPS = "Number of steps"
4
+ STEPS_INFO = "The number of steps to run the simulation for"
5
  TEST_RATE = "Test rate"
6
+ TEST_RATE_INFO = (
7
+ "The rate of testing applied at each step - node disease state is not fully known "
8
+ "without testing, whereas some state is always know (e.g. death)."
9
+ "Testing is partly random, with infected nodes being tested more often than uninfected, "
10
+ "based on the assumption that having symptoms causes an individual to actively seek testing."
11
+ )
12
+ TEST_RATE_EXTRA_INFO = (
13
+ "When test rate == 1, the ground truth is fully observed and plotted. "
14
+ "When it's <1, the ground truth graph is shown on the left, and the observed graph shown on the right."
15
+ )
16
+ INITIAL_INFECTIONS = "Number of initial infections"
17
+ INITIAL_INFECTIONS_INFO = "The number of individuals randomly infected on step 0"
18
+ RANDOM_INFECTION_CHANCE = "Random infection chance"
19
+ RANDOM_INFECTION_CHANCE_INFO = (
20
+ "Chance each step that an individual is randomly infected, even without being "
21
+ "connected to another infected individual"
22
+ )
ui/tabs/compare_pop_tab.py CHANGED
@@ -1,8 +1,6 @@
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
4
- from gradio.components import FormComponent
5
-
6
  import gradio as gr
7
  from ui.labels import simulation_labels
8
  from ui.tabs.tab_builder import ITabBuilder
@@ -16,7 +14,7 @@ class ComparePopTab(ITabBuilder):
16
  output_format = "gif"
17
  button_label: str = "run"
18
 
19
- def build(self) -> tuple[list[FormComponent], list[gr.Image], gr.Button]:
20
  with gr.Tab(self.tab_name):
21
  inputs = []
22
  with gr.Row():
@@ -29,5 +27,3 @@ class ComparePopTab(ITabBuilder):
29
 
30
  button = gr.Button(self.button_label)
31
  button.click(self.f, inputs=inputs, outputs=outputs)
32
-
33
- return inputs, outputs, button
 
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
 
 
4
  import gradio as gr
5
  from ui.labels import simulation_labels
6
  from ui.tabs.tab_builder import ITabBuilder
 
14
  output_format = "gif"
15
  button_label: str = "run"
16
 
17
+ def build(self) -> None:
18
  with gr.Tab(self.tab_name):
19
  inputs = []
20
  with gr.Row():
 
27
 
28
  button = gr.Button(self.button_label)
29
  button.click(self.f, inputs=inputs, outputs=outputs)
 
 
ui/tabs/simple_example_tab.py CHANGED
@@ -1,10 +1,7 @@
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
4
- from gradio.components import FormComponent
5
-
6
  import gradio as gr
7
- from gradio import Image
8
  from ui.functions.run_single_population import run_single_population
9
  from ui.labels import population_labels, simulation_labels
10
  from ui.tabs.tab_builder import ITabBuilder
@@ -16,9 +13,9 @@ class SimpleExampleTab(ITabBuilder):
16
  tab_name = "Simple example"
17
  default_output_path: str = "./gradio/simple-example/"
18
  output_format = "gif"
19
- button_label: str = "run"
20
 
21
- def build(self) -> tuple[list[FormComponent], list[Image], gr.Button]:
22
 
23
  with gr.Tab(self.tab_name):
24
  inputs = []
@@ -42,6 +39,23 @@ class SimpleExampleTab(ITabBuilder):
42
  step=1,
43
  value=20,
44
  label=simulation_labels.STEPS,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  ),
46
  gr.Slider(
47
  minimum=0.0,
@@ -49,6 +63,7 @@ class SimpleExampleTab(ITabBuilder):
49
  step=0.01,
50
  value=1.0,
51
  label=simulation_labels.TEST_RATE,
 
52
  interactive=False,
53
  ),
54
  ]
@@ -61,8 +76,9 @@ class SimpleExampleTab(ITabBuilder):
61
  minimum=1,
62
  maximum=100,
63
  step=1,
64
- value=3,
65
  label=population_labels.COMMUNITY_N,
 
66
  ),
67
  gr.Slider(
68
  minimum=1,
@@ -70,13 +86,13 @@ class SimpleExampleTab(ITabBuilder):
70
  step=1,
71
  value=10,
72
  label=population_labels.MEAN_COMMUNITY_SIZE,
 
73
  ),
74
  ]
75
  )
76
 
77
- outputs = [gr.Image(format=self.output_format)]
78
-
79
- button = gr.Button(self.button_label)
80
- button.click(self.f, inputs=inputs, outputs=outputs)
81
 
82
- return inputs, outputs, button
 
 
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
 
 
4
  import gradio as gr
 
5
  from ui.functions.run_single_population import run_single_population
6
  from ui.labels import population_labels, simulation_labels
7
  from ui.tabs.tab_builder import ITabBuilder
 
13
  tab_name = "Simple example"
14
  default_output_path: str = "./gradio/simple-example/"
15
  output_format = "gif"
16
+ button_label: str = "Run"
17
 
18
+ def build(self) -> None:
19
 
20
  with gr.Tab(self.tab_name):
21
  inputs = []
 
39
  step=1,
40
  value=20,
41
  label=simulation_labels.STEPS,
42
+ info=simulation_labels.STEPS_INFO,
43
+ ),
44
+ gr.Slider(
45
+ minimum=1,
46
+ maximum=100,
47
+ step=1,
48
+ value=10,
49
+ label=simulation_labels.INITIAL_INFECTIONS,
50
+ info=simulation_labels.INITIAL_INFECTIONS_INFO,
51
+ ),
52
+ gr.Slider(
53
+ minimum=0,
54
+ maximum=1,
55
+ step=0.01,
56
+ value=0.02,
57
+ label=simulation_labels.RANDOM_INFECTION_CHANCE,
58
+ info=simulation_labels.RANDOM_INFECTION_CHANCE_INFO,
59
  ),
60
  gr.Slider(
61
  minimum=0.0,
 
63
  step=0.01,
64
  value=1.0,
65
  label=simulation_labels.TEST_RATE,
66
+ info=f"{simulation_labels.TEST_RATE_INFO} {simulation_labels.TEST_RATE_EXTRA_INFO}",
67
  interactive=False,
68
  ),
69
  ]
 
76
  minimum=1,
77
  maximum=100,
78
  step=1,
79
+ value=6,
80
  label=population_labels.COMMUNITY_N,
81
+ info=population_labels.COMMUNITY_N_INFO,
82
  ),
83
  gr.Slider(
84
  minimum=1,
 
86
  step=1,
87
  value=10,
88
  label=population_labels.MEAN_COMMUNITY_SIZE,
89
+ info=population_labels.MEAN_COMMUNITY_SIZE_INFO,
90
  ),
91
  ]
92
  )
93
 
94
+ with gr.Column():
95
+ outputs = [gr.Image(format=self.output_format)]
 
 
96
 
97
+ button = gr.Button(self.button_label)
98
+ button.click(self.f, inputs=inputs, outputs=outputs)
ui/tabs/single_pop_tab.py CHANGED
@@ -1,9 +1,6 @@
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
4
- from gradio.components.base import FormComponent
5
- from gradio.components.image import Image
6
-
7
  import gradio as gr
8
  from ui.functions.run_single_population import run_single_population
9
  from ui.labels import (
@@ -21,16 +18,15 @@ class SinglePopTab(ITabBuilder):
21
  tab_name = "Passive population"
22
  default_output_path: str = "./gradio/single-population-example/"
23
  output_format = "gif"
24
- button_label: str = "run"
 
 
25
 
26
- def build(
27
- self,
28
- ) -> tuple[list[FormComponent], list[Image], gr.Button]:
29
  with gr.Tab(self.tab_name):
30
  inputs = []
31
  gr.Markdown(
32
  "Run a customized simulation. "
33
- "With Test rate < 1.0, results will show both ground truth and observed space."
34
  )
35
 
36
  with gr.Row():
@@ -50,6 +46,23 @@ class SinglePopTab(ITabBuilder):
50
  step=1,
51
  value=50,
52
  label=simulation_labels.STEPS,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ),
54
  gr.Slider(
55
  minimum=0.0,
@@ -57,6 +70,7 @@ class SinglePopTab(ITabBuilder):
57
  step=0.01,
58
  value=0.25,
59
  label=simulation_labels.TEST_RATE,
 
60
  ),
61
  ]
62
  )
@@ -70,6 +84,7 @@ class SinglePopTab(ITabBuilder):
70
  step=1,
71
  value=50,
72
  label=population_labels.COMMUNITY_N,
 
73
  ),
74
  gr.Slider(
75
  minimum=1,
@@ -77,6 +92,7 @@ class SinglePopTab(ITabBuilder):
77
  step=1,
78
  value=15,
79
  label=population_labels.MEAN_COMMUNITY_SIZE,
 
80
  ),
81
  gr.Slider(
82
  minimum=-0.0,
@@ -106,6 +122,7 @@ class SinglePopTab(ITabBuilder):
106
  step=0.001,
107
  value=0.005,
108
  label=disease_labels.VIRULENCE,
 
109
  ),
110
  gr.Slider(
111
  minimum=-0.0,
@@ -113,6 +130,7 @@ class SinglePopTab(ITabBuilder):
113
  step=0.1,
114
  value=0.99,
115
  label=disease_labels.RECOVERY_RATE,
 
116
  ),
117
  gr.Slider(
118
  minimum=-0.0,
@@ -120,6 +138,7 @@ class SinglePopTab(ITabBuilder):
120
  step=0.1,
121
  value=0.66,
122
  label=disease_labels.IMMUNITY_MEAN,
 
123
  ),
124
  gr.Slider(
125
  minimum=-0.0,
@@ -127,6 +146,7 @@ class SinglePopTab(ITabBuilder):
127
  step=0.1,
128
  value=0.1,
129
  label=disease_labels.IMMUNITY_DECAY_MEAN,
 
130
  ),
131
  ]
132
  )
@@ -140,6 +160,7 @@ class SinglePopTab(ITabBuilder):
140
  step=1,
141
  value=200,
142
  label=healthcare_labels.CAPACITY,
 
143
  ),
144
  gr.Slider(
145
  minimum=0.0,
@@ -147,6 +168,7 @@ class SinglePopTab(ITabBuilder):
147
  step=0.01,
148
  value=0.5,
149
  label=healthcare_labels.MAX_PENALTY,
 
150
  ),
151
  ]
152
  )
@@ -154,5 +176,3 @@ class SinglePopTab(ITabBuilder):
154
  outputs = [gr.Image(format=self.output_format)]
155
  button = gr.Button(self.button_label)
156
  button.click(self.f, inputs=inputs, outputs=outputs)
157
-
158
- return inputs, outputs, button
 
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
 
 
 
4
  import gradio as gr
5
  from ui.functions.run_single_population import run_single_population
6
  from ui.labels import (
 
18
  tab_name = "Passive population"
19
  default_output_path: str = "./gradio/single-population-example/"
20
  output_format = "gif"
21
+ button_label: str = "Run"
22
+
23
+ def build(self) -> None:
24
 
 
 
 
25
  with gr.Tab(self.tab_name):
26
  inputs = []
27
  gr.Markdown(
28
  "Run a customized simulation. "
29
+ "With Test rate <= 1.0, results will show both ground truth and observed space."
30
  )
31
 
32
  with gr.Row():
 
46
  step=1,
47
  value=50,
48
  label=simulation_labels.STEPS,
49
+ info=simulation_labels.STEPS_INFO,
50
+ ),
51
+ gr.Slider(
52
+ minimum=1,
53
+ maximum=100,
54
+ step=1,
55
+ value=2,
56
+ label=simulation_labels.INITIAL_INFECTIONS,
57
+ info=simulation_labels.INITIAL_INFECTIONS_INFO,
58
+ ),
59
+ gr.Slider(
60
+ minimum=0,
61
+ maximum=1,
62
+ step=0.01,
63
+ value=0.02,
64
+ label=simulation_labels.RANDOM_INFECTION_CHANCE,
65
+ info=simulation_labels.RANDOM_INFECTION_CHANCE_INFO,
66
  ),
67
  gr.Slider(
68
  minimum=0.0,
 
70
  step=0.01,
71
  value=0.25,
72
  label=simulation_labels.TEST_RATE,
73
+ info=simulation_labels.TEST_RATE_INFO,
74
  ),
75
  ]
76
  )
 
84
  step=1,
85
  value=50,
86
  label=population_labels.COMMUNITY_N,
87
+ info=population_labels.COMMUNITY_N_INFO,
88
  ),
89
  gr.Slider(
90
  minimum=1,
 
92
  step=1,
93
  value=15,
94
  label=population_labels.MEAN_COMMUNITY_SIZE,
95
+ info=population_labels.MEAN_COMMUNITY_SIZE_INFO,
96
  ),
97
  gr.Slider(
98
  minimum=-0.0,
 
122
  step=0.001,
123
  value=0.005,
124
  label=disease_labels.VIRULENCE,
125
+ info=disease_labels.VIRULENCE_INFO,
126
  ),
127
  gr.Slider(
128
  minimum=-0.0,
 
130
  step=0.1,
131
  value=0.99,
132
  label=disease_labels.RECOVERY_RATE,
133
+ info=disease_labels.RECOVERY_RATE_INFO,
134
  ),
135
  gr.Slider(
136
  minimum=-0.0,
 
138
  step=0.1,
139
  value=0.66,
140
  label=disease_labels.IMMUNITY_MEAN,
141
+ info=disease_labels.IMMUNITY_MEAN_INFO,
142
  ),
143
  gr.Slider(
144
  minimum=-0.0,
 
146
  step=0.1,
147
  value=0.1,
148
  label=disease_labels.IMMUNITY_DECAY_MEAN,
149
+ info=disease_labels.IMMUNITY_DECAY_MEAN_INFO,
150
  ),
151
  ]
152
  )
 
160
  step=1,
161
  value=200,
162
  label=healthcare_labels.CAPACITY,
163
+ info=healthcare_labels.CAPACITY_INFO,
164
  ),
165
  gr.Slider(
166
  minimum=0.0,
 
168
  step=0.01,
169
  value=0.5,
170
  label=healthcare_labels.MAX_PENALTY,
171
+ info=healthcare_labels.MAX_PENALTY_INFO,
172
  ),
173
  ]
174
  )
 
176
  outputs = [gr.Image(format=self.output_format)]
177
  button = gr.Button(self.button_label)
178
  button.click(self.f, inputs=inputs, outputs=outputs)
 
 
ui/tabs/tab_builder.py CHANGED
@@ -1,15 +1,11 @@
1
  import abc
2
  from typing import Callable
3
 
4
- from gradio.components import FormComponent
5
-
6
- import gradio as gr
7
-
8
 
9
  class ITabBuilder(abc.ABC):
10
  f: Callable
11
  name: str
12
 
13
  @abc.abstractmethod
14
- def build(self) -> tuple[list[FormComponent], list[gr.Image], gr.Button]:
15
  """Compose the tab components."""
 
1
  import abc
2
  from typing import Callable
3
 
 
 
 
 
4
 
5
  class ITabBuilder(abc.ABC):
6
  f: Callable
7
  name: str
8
 
9
  @abc.abstractmethod
10
+ def build(self) -> None:
11
  """Compose the tab components."""
ui/tabs/with_agent_tab.py CHANGED
@@ -1,8 +1,6 @@
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
4
- from gradio.components import FormComponent
5
-
6
  import gradio as gr
7
  from ui.functions.run_gym_env import run_gym_env
8
  from ui.labels import simulation_labels
@@ -15,36 +13,39 @@ class WithAgentTab(ITabBuilder):
15
  tab_name = "With agent(s)"
16
  default_output_path: str = "./gradio/agent-example/"
17
  output_format = "gif"
18
- button_label: str = "run"
19
 
20
  def build(
21
  self,
22
- ) -> tuple[list[FormComponent], list[gr.Image], gr.Button]:
23
-
24
  with gr.Tab(self.tab_name):
25
- inputs = []
26
  gr.Markdown(
27
- "Run a simulation with fixed parameters and optional agents. "
28
- "Agents and number of actions they perform each turn can be configured."
29
- )
30
 
 
 
 
31
  with gr.Row():
32
  with gr.Column():
33
  gr.Markdown(simulation_labels.TITLE)
34
-
 
 
 
 
 
 
 
 
 
 
 
 
35
  inputs.extend(
36
  [
37
- gr.Text(
38
- value=self.default_output_path,
39
- label=simulation_labels.OUTPUT_PATH,
40
- ),
41
- gr.Slider(
42
- minimum=5,
43
- maximum=200,
44
- step=1,
45
- value=100,
46
- label=simulation_labels.STEPS,
47
- ),
48
  gr.Slider(
49
  minimum=0.0,
50
  maximum=1.0,
@@ -56,34 +57,168 @@ class WithAgentTab(ITabBuilder):
56
  ]
57
  )
58
 
59
- with gr.Row():
60
- with gr.Accordion("Agents"):
61
- gr.Markdown("In here")
62
- inputs.extend(
63
- [
64
- gr.Checkboxgroup(
65
- choices=[
66
- ("Dummy", "dummy"),
67
- ("Distancing", "distancing"),
68
- ("Vaccination", "vaccination"),
69
- ("Treatment", "treatment"),
70
- ("Masking", "masking"),
71
- ],
72
- value=["distancing"],
73
- ),
74
- gr.Slider(
75
- minimum=0,
76
- maximum=20,
77
- step=1,
78
- value=6,
79
- label="Total number of actions allowed per turn",
80
- interactive=True,
81
- ),
82
- ]
83
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- outputs = [gr.Image(format=self.output_format)]
86
- button = gr.Button(self.button_label)
87
- button.click(self.f, inputs=inputs, outputs=outputs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
- return inputs, outputs, button
 
 
1
  from dataclasses import dataclass
2
  from typing import Callable
3
 
 
 
4
  import gradio as gr
5
  from ui.functions.run_gym_env import run_gym_env
6
  from ui.labels import simulation_labels
 
13
  tab_name = "With agent(s)"
14
  default_output_path: str = "./gradio/agent-example/"
15
  output_format = "gif"
16
+ button_label: str = "Run"
17
 
18
  def build(
19
  self,
20
+ ) -> None:
21
+ inputs = []
22
  with gr.Tab(self.tab_name):
 
23
  gr.Markdown(
24
+ """
25
+ Run a simulation with fixed parameters and optional agents.
 
26
 
27
+ Agents have fixed efficiency, and number of actions they perform each turn can be configured.
28
+ """
29
+ )
30
  with gr.Row():
31
  with gr.Column():
32
  gr.Markdown(simulation_labels.TITLE)
33
+ inputs.append(
34
+ gr.Text(
35
+ value=self.default_output_path,
36
+ label=simulation_labels.OUTPUT_PATH,
37
+ )
38
+ )
39
+ steps_slider_component = gr.Slider(
40
+ minimum=5,
41
+ maximum=200,
42
+ step=1,
43
+ value=100,
44
+ label=simulation_labels.STEPS,
45
+ )
46
  inputs.extend(
47
  [
48
+ steps_slider_component,
 
 
 
 
 
 
 
 
 
 
49
  gr.Slider(
50
  minimum=0.0,
51
  maximum=1.0,
 
57
  ]
58
  )
59
 
60
+ with gr.Accordion("Agents"):
61
+ agents_selection_component = gr.Checkboxgroup(
62
+ choices=[
63
+ ("Distancing", "distancing"),
64
+ ("Vaccination", "vaccination"),
65
+ ("Treatment", "treatment"),
66
+ ("Masking", "masking"),
67
+ ],
68
+ value=["distancing"],
69
+ label="Enabled agents",
70
+ )
71
+ inputs.extend(
72
+ [
73
+ agents_selection_component,
74
+ gr.Slider(
75
+ minimum=0,
76
+ maximum=20,
77
+ step=1,
78
+ value=6,
79
+ label="Total number of actions allowed per turn",
80
+ info="Number of actions per turn, split equally between active agents (rounded down where required.)",
81
+ interactive=True,
82
+ ),
83
+ ]
84
+ )
85
+
86
+ with gr.Group():
87
+ gr.Markdown(
88
+ """
89
+ **Distancing agent params**
90
+
91
+ The distancing agent disconnects nodes wth 95% efficiency."""
92
+ )
93
+ inputs.extend(
94
+ [
95
+ gr.Slider(
96
+ label="Start isolating on step",
97
+ minimum=steps_slider_component.minimum,
98
+ value=5,
99
+ maximum=steps_slider_component.maximum,
100
+ interactive=True,
101
+ ),
102
+ gr.Slider(
103
+ label="Stop isolating on step",
104
+ minimum=steps_slider_component.minimum,
105
+ value=50,
106
+ maximum=steps_slider_component.maximum,
107
+ interactive=True,
108
+ ),
109
+ gr.Slider(
110
+ label="Start reconnecting on step",
111
+ minimum=steps_slider_component.minimum,
112
+ value=40,
113
+ maximum=steps_slider_component.maximum,
114
+ interactive=True,
115
+ ),
116
+ gr.Slider(
117
+ label="Stop reconnecting on step",
118
+ minimum=steps_slider_component.minimum,
119
+ value=steps_slider_component.maximum,
120
+ maximum=steps_slider_component.maximum,
121
+ interactive=True,
122
+ ),
123
+ ]
124
+ )
125
+
126
+ with gr.Group():
127
+ gr.Markdown(
128
+ """
129
+ **Vaccination agent params**
130
 
131
+ The vaccination agent adds 95% immunity to targeted uninfected nodes."""
132
+ )
133
+ inputs.extend(
134
+ [
135
+ gr.Slider(
136
+ label="Start vaccinating on step",
137
+ minimum=steps_slider_component.minimum,
138
+ value=5,
139
+ maximum=steps_slider_component.maximum,
140
+ interactive=True,
141
+ ),
142
+ gr.Slider(
143
+ label="Stop vaccinating on step",
144
+ minimum=steps_slider_component.minimum,
145
+ value=50,
146
+ maximum=steps_slider_component.maximum,
147
+ interactive=True,
148
+ ),
149
+ ]
150
+ )
151
+
152
+ with gr.Group():
153
+ gr.Markdown(
154
+ """
155
+ **Vaccination agent params**
156
+
157
+ "The treatment agent treats infected nodes with 60% immediate recovery,
158
+ and a boost to recovery rate otherwise."""
159
+ )
160
+ inputs.extend(
161
+ [
162
+ gr.Slider(
163
+ label="Start treating on step",
164
+ minimum=steps_slider_component.minimum,
165
+ value=5,
166
+ maximum=steps_slider_component.maximum,
167
+ interactive=True,
168
+ ),
169
+ gr.Slider(
170
+ label="Stop treating on step",
171
+ minimum=steps_slider_component.minimum,
172
+ value=50,
173
+ maximum=steps_slider_component.maximum,
174
+ interactive=True,
175
+ ),
176
+ ]
177
+ )
178
+
179
+ with gr.Group():
180
+ gr.Markdown(
181
+ """
182
+ **Masking agent params**
183
+
184
+ The masking agent gives nodes masks (indicated by circles in plot),
185
+ which reduces disease spread to/from the node by 25%."""
186
+ )
187
+ inputs.extend(
188
+ [
189
+ gr.Slider(
190
+ label="Start masking on step",
191
+ minimum=steps_slider_component.minimum,
192
+ value=5,
193
+ maximum=steps_slider_component.maximum,
194
+ interactive=True,
195
+ ),
196
+ gr.Slider(
197
+ label="Stop masking on step",
198
+ minimum=steps_slider_component.minimum,
199
+ value=50,
200
+ maximum=steps_slider_component.maximum,
201
+ interactive=True,
202
+ ),
203
+ gr.Slider(
204
+ label="Start removing masks on step",
205
+ minimum=steps_slider_component.minimum,
206
+ value=40,
207
+ maximum=steps_slider_component.maximum,
208
+ interactive=True,
209
+ ),
210
+ gr.Slider(
211
+ label="Stop removing masks on step",
212
+ minimum=steps_slider_component.minimum,
213
+ value=steps_slider_component.maximum,
214
+ maximum=steps_slider_component.maximum,
215
+ interactive=True,
216
+ ),
217
+ ]
218
+ )
219
+
220
+ with gr.Column():
221
+ outputs = [gr.Image(format=self.output_format)]
222
 
223
+ button = gr.Button(self.button_label)
224
+ button.click(self.f, inputs=inputs, outputs=outputs)