Update app.py
Browse files
app.py
CHANGED
@@ -19,7 +19,6 @@ class Cell:
|
|
19 |
self.size = 1
|
20 |
self.color = "lightblue"
|
21 |
self.division_threshold = 150
|
22 |
-
|
23 |
self.update_properties()
|
24 |
|
25 |
def update_properties(self):
|
@@ -64,11 +63,11 @@ class Cell:
|
|
64 |
return new_cell
|
65 |
return None
|
66 |
|
67 |
-
def
|
68 |
return (self.cell_type == other.cell_type and
|
69 |
-
random.random() < 0.
|
70 |
|
71 |
-
def
|
72 |
new_cell_type = self.cell_type
|
73 |
if self.cell_type == "prokaryote":
|
74 |
new_cell_type = "early_eukaryote"
|
@@ -86,7 +85,7 @@ class Cell:
|
|
86 |
return new_cell
|
87 |
|
88 |
class Environment:
|
89 |
-
def __init__(self, width, height):
|
90 |
self.width = width
|
91 |
self.height = height
|
92 |
self.grid = np.random.rand(height, width) * 10
|
@@ -97,6 +96,7 @@ class Environment:
|
|
97 |
"prokaryote": [], "early_eukaryote": [],
|
98 |
"advanced_eukaryote": [], "plant_like": [], "complete": []
|
99 |
}
|
|
|
100 |
|
101 |
def add_cell(self, cell):
|
102 |
self.cells.append(cell)
|
@@ -120,15 +120,23 @@ class Environment:
|
|
120 |
if new_cell:
|
121 |
new_cells.append(new_cell)
|
122 |
|
123 |
-
# Handle cell
|
124 |
for i, cell1 in enumerate(self.cells):
|
125 |
for cell2 in self.cells[i+1:]:
|
126 |
-
if cell1.
|
127 |
-
new_cell = cell1.
|
128 |
new_cells.append(new_cell)
|
129 |
cells_to_remove.extend([cell1, cell2])
|
130 |
|
131 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
self.cells.extend(new_cells)
|
133 |
self.cells = [cell for cell in self.cells if cell not in cells_to_remove]
|
134 |
|
@@ -137,6 +145,33 @@ class Environment:
|
|
137 |
count = len([cell for cell in self.cells if cell.cell_type == cell_type])
|
138 |
self.population_history[cell_type].append(count)
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
def get_visualization_data(self):
|
141 |
cell_data = {cell_type: {"x": [], "y": [], "size": []} for cell_type in self.population_history.keys()}
|
142 |
colors = {"prokaryote": "lightblue", "early_eukaryote": "green", "advanced_eukaryote": "red", "plant_like": "darkgreen", "complete": "purple"}
|
@@ -198,8 +233,20 @@ def setup_figure(env):
|
|
198 |
# Streamlit app
|
199 |
st.title("Advanced Cell Evolution Simulation")
|
200 |
|
201 |
-
initial_cells = st.slider("Initial number of cells", 10,
|
202 |
-
update_interval = st.slider("Update interval (seconds)", 0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
203 |
|
204 |
# Create placeholders for the chart and stop button
|
205 |
chart_placeholder = st.empty()
|
@@ -215,7 +262,7 @@ def toggle_simulation():
|
|
215 |
start_stop_button = st.button("Start/Stop Simulation", on_click=toggle_simulation)
|
216 |
|
217 |
if st.session_state.running:
|
218 |
-
env = Environment(100, 100)
|
219 |
for _ in range(initial_cells):
|
220 |
cell = Cell(random.uniform(0, env.width), random.uniform(0, env.height))
|
221 |
env.add_cell(cell)
|
@@ -223,7 +270,8 @@ if st.session_state.running:
|
|
223 |
fig = setup_figure(env)
|
224 |
|
225 |
while st.session_state.running:
|
226 |
-
|
|
|
227 |
|
228 |
with fig.batch_update():
|
229 |
cell_data, population_history, colors = env.get_visualization_data()
|
|
|
19 |
self.size = 1
|
20 |
self.color = "lightblue"
|
21 |
self.division_threshold = 150
|
|
|
22 |
self.update_properties()
|
23 |
|
24 |
def update_properties(self):
|
|
|
63 |
return new_cell
|
64 |
return None
|
65 |
|
66 |
+
def can_merge(self, other):
|
67 |
return (self.cell_type == other.cell_type and
|
68 |
+
random.random() < 0.01) # 1% chance of merging
|
69 |
|
70 |
+
def merge(self, other):
|
71 |
new_cell_type = self.cell_type
|
72 |
if self.cell_type == "prokaryote":
|
73 |
new_cell_type = "early_eukaryote"
|
|
|
85 |
return new_cell
|
86 |
|
87 |
class Environment:
|
88 |
+
def __init__(self, width, height, effects):
|
89 |
self.width = width
|
90 |
self.height = height
|
91 |
self.grid = np.random.rand(height, width) * 10
|
|
|
96 |
"prokaryote": [], "early_eukaryote": [],
|
97 |
"advanced_eukaryote": [], "plant_like": [], "complete": []
|
98 |
}
|
99 |
+
self.effects = effects
|
100 |
|
101 |
def add_cell(self, cell):
|
102 |
self.cells.append(cell)
|
|
|
120 |
if new_cell:
|
121 |
new_cells.append(new_cell)
|
122 |
|
123 |
+
# Handle cell merging
|
124 |
for i, cell1 in enumerate(self.cells):
|
125 |
for cell2 in self.cells[i+1:]:
|
126 |
+
if cell1.can_merge(cell2):
|
127 |
+
new_cell = cell1.merge(cell2)
|
128 |
new_cells.append(new_cell)
|
129 |
cells_to_remove.extend([cell1, cell2])
|
130 |
|
131 |
+
# Apply effects
|
132 |
+
if self.effects['radiation']:
|
133 |
+
self.apply_radiation()
|
134 |
+
if self.effects['predation']:
|
135 |
+
self.apply_predation()
|
136 |
+
if self.effects['symbiosis']:
|
137 |
+
self.apply_symbiosis()
|
138 |
+
|
139 |
+
# Add new cells and remove dead/merged cells
|
140 |
self.cells.extend(new_cells)
|
141 |
self.cells = [cell for cell in self.cells if cell not in cells_to_remove]
|
142 |
|
|
|
145 |
count = len([cell for cell in self.cells if cell.cell_type == cell_type])
|
146 |
self.population_history[cell_type].append(count)
|
147 |
|
148 |
+
def apply_radiation(self):
|
149 |
+
for cell in self.cells:
|
150 |
+
if random.random() < 0.01: # 1% chance of mutation
|
151 |
+
cell.energy *= 0.8
|
152 |
+
if random.random() < 0.5:
|
153 |
+
cell.organelles.add(random.choice(["nucleus", "mitochondria", "chloroplast", "endoplasmic_reticulum", "golgi_apparatus"]))
|
154 |
+
else:
|
155 |
+
if cell.organelles:
|
156 |
+
cell.organelles.remove(random.choice(list(cell.organelles)))
|
157 |
+
cell.update_properties()
|
158 |
+
|
159 |
+
def apply_predation(self):
|
160 |
+
for i, predator in enumerate(self.cells):
|
161 |
+
if predator.cell_type in ["advanced_eukaryote", "plant_like", "complete"]:
|
162 |
+
for prey in self.cells[i+1:]:
|
163 |
+
if prey.cell_type in ["prokaryote", "early_eukaryote"] and random.random() < 0.05:
|
164 |
+
predator.energy += prey.energy * 0.5
|
165 |
+
self.cells.remove(prey)
|
166 |
+
|
167 |
+
def apply_symbiosis(self):
|
168 |
+
for i, cell1 in enumerate(self.cells):
|
169 |
+
for cell2 in self.cells[i+1:]:
|
170 |
+
if cell1.cell_type != cell2.cell_type and random.random() < 0.01:
|
171 |
+
shared_energy = (cell1.energy + cell2.energy) * 0.1
|
172 |
+
cell1.energy += shared_energy
|
173 |
+
cell2.energy += shared_energy
|
174 |
+
|
175 |
def get_visualization_data(self):
|
176 |
cell_data = {cell_type: {"x": [], "y": [], "size": []} for cell_type in self.population_history.keys()}
|
177 |
colors = {"prokaryote": "lightblue", "early_eukaryote": "green", "advanced_eukaryote": "red", "plant_like": "darkgreen", "complete": "purple"}
|
|
|
233 |
# Streamlit app
|
234 |
st.title("Advanced Cell Evolution Simulation")
|
235 |
|
236 |
+
initial_cells = st.slider("Initial number of cells", 10, 500, 200)
|
237 |
+
update_interval = st.slider("Update interval (seconds)", 0.01, 1.0, 0.05) # Increased speed
|
238 |
+
|
239 |
+
# Effect options
|
240 |
+
st.sidebar.header("Environmental Effects")
|
241 |
+
radiation = st.sidebar.checkbox("Radiation")
|
242 |
+
predation = st.sidebar.checkbox("Predation")
|
243 |
+
symbiosis = st.sidebar.checkbox("Symbiosis")
|
244 |
+
|
245 |
+
effects = {
|
246 |
+
"radiation": radiation,
|
247 |
+
"predation": predation,
|
248 |
+
"symbiosis": symbiosis
|
249 |
+
}
|
250 |
|
251 |
# Create placeholders for the chart and stop button
|
252 |
chart_placeholder = st.empty()
|
|
|
262 |
start_stop_button = st.button("Start/Stop Simulation", on_click=toggle_simulation)
|
263 |
|
264 |
if st.session_state.running:
|
265 |
+
env = Environment(100, 100, effects)
|
266 |
for _ in range(initial_cells):
|
267 |
cell = Cell(random.uniform(0, env.width), random.uniform(0, env.height))
|
268 |
env.add_cell(cell)
|
|
|
270 |
fig = setup_figure(env)
|
271 |
|
272 |
while st.session_state.running:
|
273 |
+
for _ in range(4): # Update 4 times per frame to increase simulation speed
|
274 |
+
env.update()
|
275 |
|
276 |
with fig.batch_update():
|
277 |
cell_data, population_history, colors = env.get_visualization_data()
|