Update app.py
Browse files
app.py
CHANGED
@@ -275,6 +275,20 @@ event_log_text = st.sidebar.empty()
|
|
275 |
# Create placeholders for the chart
|
276 |
chart_placeholder = st.empty()
|
277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
# Initialize session state
|
279 |
if 'running' not in st.session_state:
|
280 |
st.session_state.running = False
|
@@ -306,78 +320,34 @@ with col1:
|
|
306 |
with col2:
|
307 |
stop_button = st.button("Stop Simulation", on_click=stop_simulation)
|
308 |
|
309 |
-
def update_chart():
|
310 |
-
if st.session_state.env is not None and st.session_state.fig is not None:
|
311 |
-
cell_data, population_history, colors = st.session_state.env.get_visualization_data()
|
312 |
-
|
313 |
-
# Update cell distribution
|
314 |
-
for i, (cell_type, data) in enumerate(cell_data.items()):
|
315 |
-
st.session_state.fig.data[i].x = data["x"]
|
316 |
-
st.session_state.fig.data[i].y = data["y"]
|
317 |
-
st.session_state.fig.data[i].marker.size = data["size"]
|
318 |
-
|
319 |
-
# Update total population
|
320 |
-
total_population = [sum(counts) for counts in zip(*population_history.values())]
|
321 |
-
st.session_state.fig.data[5].y = total_population
|
322 |
-
|
323 |
-
# Update population by cell type
|
324 |
-
for i, (cell_type, counts) in enumerate(population_history.items()):
|
325 |
-
st.session_state.fig.data[6+i].y = counts
|
326 |
-
|
327 |
-
# Update organelle distribution
|
328 |
-
organelle_counts = {"nucleus": 0, "mitochondria": 0, "chloroplast": 0, "endoplasmic_reticulum": 0, "golgi_apparatus": 0}
|
329 |
-
for cell in st.session_state.env.cells:
|
330 |
-
for organelle in cell.organelles:
|
331 |
-
organelle_counts[organelle] += 1
|
332 |
-
st.session_state.fig.data[11].y = list(organelle_counts.values())
|
333 |
-
|
334 |
-
chart_placeholder.plotly_chart(st.session_state.fig, use_container_width=True)
|
335 |
-
|
336 |
-
def update_statistics():
|
337 |
-
if st.session_state.env is not None:
|
338 |
-
total_cells = len(st.session_state.env.cells)
|
339 |
-
total_cells_text.text(f"Total Cells: {format_number(total_cells)}")
|
340 |
-
|
341 |
-
cell_type_counts = {cell_type: len([cell for cell in st.session_state.env.cells if cell.cell_type == cell_type]) for cell_type in st.session_state.env.population_history.keys()}
|
342 |
-
breakdown = "\n".join([f"{cell_type}: {format_number(count)}" for cell_type, count in cell_type_counts.items()])
|
343 |
-
cell_type_breakdown.text(f"Cell Type Breakdown:\n{breakdown}")
|
344 |
-
|
345 |
-
dominant_type = max(cell_type_counts, key=cell_type_counts.get)
|
346 |
-
dominant_type_text.text(f"Dominant Type: {dominant_type}")
|
347 |
-
|
348 |
-
avg_energy = sum(cell.energy for cell in st.session_state.env.cells) / total_cells if total_cells > 0 else 0
|
349 |
-
avg_energy_text.text(f"Average Energy: {avg_energy:.2f}")
|
350 |
-
|
351 |
-
total_merges_text.text(f"Total Merges: {st.session_state.total_merges}")
|
352 |
-
|
353 |
-
event_log_text.text("\n".join(event_log))
|
354 |
-
|
355 |
# Main simulation loop
|
356 |
simulation_container = st.empty()
|
357 |
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
|
366 |
-
|
367 |
-
|
368 |
-
merges = initial_cell_count - final_cell_count
|
369 |
-
st.session_state.total_merges += merges
|
370 |
-
event_log.appendleft(f"Time {st.session_state.env.time}: {merges} cell merges occurred")
|
371 |
|
372 |
-
|
373 |
-
update_statistics()
|
374 |
|
375 |
-
|
376 |
-
|
377 |
-
simulation_container.empty()
|
378 |
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
|
383 |
-
st.
|
|
|
|
275 |
# Create placeholders for the chart
|
276 |
chart_placeholder = st.empty()
|
277 |
|
278 |
+
import streamlit as st
|
279 |
+
import time
|
280 |
+
from collections import deque
|
281 |
+
import threading
|
282 |
+
|
283 |
+
# ... (keep all the imports and class definitions)
|
284 |
+
|
285 |
+
# ... (keep all the function definitions)
|
286 |
+
|
287 |
+
# Streamlit app
|
288 |
+
st.title("Continuous Cell Evolution Simulation")
|
289 |
+
|
290 |
+
# ... (keep all the sidebar controls and placeholders)
|
291 |
+
|
292 |
# Initialize session state
|
293 |
if 'running' not in st.session_state:
|
294 |
st.session_state.running = False
|
|
|
320 |
with col2:
|
321 |
stop_button = st.button("Stop Simulation", on_click=stop_simulation)
|
322 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
# Main simulation loop
|
324 |
simulation_container = st.empty()
|
325 |
|
326 |
+
def run_simulation():
|
327 |
+
while st.session_state.running:
|
328 |
+
with simulation_container.container():
|
329 |
+
if st.session_state.env is not None:
|
330 |
+
for _ in range(4): # Update 4 times per frame to increase simulation speed
|
331 |
+
initial_cell_count = len(st.session_state.env.cells)
|
332 |
+
st.session_state.env.update()
|
333 |
+
final_cell_count = len(st.session_state.env.cells)
|
334 |
+
|
335 |
+
# Check for merges
|
336 |
+
if final_cell_count < initial_cell_count:
|
337 |
+
merges = initial_cell_count - final_cell_count
|
338 |
+
st.session_state.total_merges += merges
|
339 |
+
event_log.appendleft(f"Time {st.session_state.env.time}: {merges} cell merges occurred")
|
340 |
|
341 |
+
update_chart()
|
342 |
+
update_statistics()
|
|
|
|
|
|
|
343 |
|
344 |
+
time.sleep(update_interval)
|
|
|
345 |
|
346 |
+
st.experimental_rerun()
|
|
|
|
|
347 |
|
348 |
+
if st.session_state.running:
|
349 |
+
simulation_thread = threading.Thread(target=run_simulation)
|
350 |
+
simulation_thread.start()
|
351 |
|
352 |
+
if not st.session_state.running:
|
353 |
+
st.write("Simulation stopped. Click 'Start Simulation' to run again.")
|