-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
111 lines (89 loc) · 4.43 KB
/
server.py
1
2
3
4
5
6
7
8
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
79
80
81
82
83
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
import mesa
import random
import warnings
from tumor.classes.tumor_growth import TumorGrowth
from mesa.datacollection import DataCollector
# surpress warning about new PropertyLayer class of mesa
warnings.simplefilter(action='ignore', category=FutureWarning)
class TumorWrapper(TumorGrowth):
"""
To accomodate the interactive simulation, the TumorGrowth model
is slightly modified.
We add a datacollector for the dynamic graph, modify the step method and add a description.
"""
description = (
"""
Interactive simulation of tumor growth. Agents are cancerous cells and will multiply and try to invade healthy tissue.
\n Adjustable model parameters are: Proliferation inhibition: This will reduce multiplication of cells \n
Invasiveness enhancement: This will make agents more likely to attempt to migrate and less likely to multiply.\n
Nutrient threshold: If the local nutrient concentration drops below this value, all agents at that location will die (necrotic). \n
ECM degradation speed: How fast the tumor cells degrade healthy tissue. Increasing this value will significantly impact radial growth speed of the tumor \n
Distribution of the ECM: density field of healthy tissue, either completely random or Voronoi tessellation.
"""
)
def __init__(self, height=201, width=201, steps=1000, delta_d=100, D=1 * 10 ** -4, k=0.02, gamma=5 * 10 ** -4, phi_c=0.02, theta_p=0.2, theta_i=0.2, app=-0.1, api=-0.02, bip=0.02, bii=0.1, seed=random.randint(0, 1000), distribution=False):
distribution = 'voronoi' if distribution == True else 'uniform'
super().__init__(height, width, steps, delta_d, D, k, gamma, phi_c, theta_p, theta_i, app, api, bip, bii, seed, distribution)
self.datacollector = DataCollector(
{"proliferative":lambda m: m.proliferating_cells[-1],
"invasive": lambda m: m.invasive_cells[-1],
"necrotic": lambda m: m.necrotic_cells[-1]
}
)
def step(self):
for i in range(5):
self.degredation()
self.diffusion()
self.cell_death()
self.new_state()
self.scheduler.step()
self.count_states()
self.datacollector.collect(self)
if self.touches_border():
self.running = False
# model settings
model_params = {
"height": 50,
"width": 50,
"app": mesa.visualization.Slider(name="proliferation inhibition", value=-0.1, min_value=-1, max_value=0, step=0.1),
"bii": mesa.visualization.Slider(name="invasiveness enhancement", value=0.1, min_value=0.00, max_value=1.0, step=0.1),
"phi_c":mesa.visualization.Slider(name="nutrient threshold (phi_c)", value=0.02, min_value=0.00, max_value=0.1, step=0.02),
"gamma":mesa.visualization.Slider(name="ECM degradation speed", value=5*10**-4, min_value=0.00, max_value=0.005, step=0.0005),
"distribution":mesa.visualization.Choice("distribution of healthy tissue (ECM)", value="random", choices=["random", "voronoi"])
}
def agent_portrayal(agent):
"""
Portrayal Method for canvas
"""
agents_in_cell = len(agent.model.grid.get_cell_list_contents([agent.pos]))
radius = 0.2 * agents_in_cell
radius = radius if radius <= 0.95 else 0.95
portrayal = {"Shape": "rect", "w": radius, "h":radius, "Filled": "true", "Layer": 2, "Color": "Green"}
if agent.state == 'invasive':
portrayal["Color"] = 'Red'
portrayal['Layer'] = 1
return portrayal
# create the grid
grid = mesa.visualization.CanvasGrid(agent_portrayal, model_params['height'], model_params['width'], 400, 400)
# create a dynamic linegraph
chart = mesa.visualization.ChartModule(
[
{"Label": "proliferating", "Color": "green"},
{"Label": "invasive", "Color": "red"},
{"Label":"necrotic", "Color":"blue"}
],
data_collector_name='datacollector')
# text elements
class ChartDescription(mesa.visualization.TextElement):
def __init__(self):
pass
def render(self, model):
return "Progression of cell types"
class ModelDescription(mesa.visualization.TextElement):
def __init__(self):
pass
def render(self, model):
return "Tumor growth model"
# finally, create the server and launch
server = mesa.visualization.ModularServer(TumorWrapper, [ModelDescription(), grid, ChartDescription(), chart], "Tumor Growth", model_params)
server.launch()