Update app.py
Browse files
app.py
CHANGED
|
@@ -285,92 +285,99 @@ if 'env' not in st.session_state:
|
|
| 285 |
if 'fig' not in st.session_state:
|
| 286 |
st.session_state.fig = None
|
| 287 |
|
| 288 |
-
def
|
| 289 |
-
st.session_state.running =
|
| 290 |
-
if st.session_state.
|
| 291 |
st.session_state.env = Environment(100, 100, effects)
|
| 292 |
for _ in range(initial_cells):
|
| 293 |
cell = Cell(random.uniform(0, st.session_state.env.width), random.uniform(0, st.session_state.env.height))
|
| 294 |
st.session_state.env.add_cell(cell)
|
| 295 |
st.session_state.fig = setup_figure(st.session_state.env)
|
| 296 |
|
| 297 |
-
|
|
|
|
| 298 |
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
for _ in range(4): # Update 4 times per frame to increase simulation speed
|
| 302 |
-
initial_cell_count = len(st.session_state.env.cells)
|
| 303 |
-
st.session_state.env.update()
|
| 304 |
-
final_cell_count = len(st.session_state.env.cells)
|
| 305 |
-
|
| 306 |
-
# Check for merges
|
| 307 |
-
if final_cell_count < initial_cell_count:
|
| 308 |
-
merges = initial_cell_count - final_cell_count
|
| 309 |
-
st.session_state.total_merges += merges
|
| 310 |
-
event_log.appendleft(f"Time {st.session_state.env.time}: {merges} cell merge(s) occurred!")
|
| 311 |
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
if cell.cell_type not in st.session_state.env.population_history:
|
| 315 |
-
event_log.appendleft(f"Time {st.session_state.env.time}: New cell type '{cell.cell_type}' emerged!")
|
| 316 |
|
| 317 |
-
|
|
|
|
| 318 |
|
| 319 |
def update_chart():
|
| 320 |
-
if st.session_state.
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
st.session_state.fig.data[len(cell_data) + 1 + i].y = counts
|
| 337 |
-
|
| 338 |
-
# Update organelle distribution
|
| 339 |
-
organelle_counts = {"nucleus": 0, "mitochondria": 0, "chloroplast": 0, "endoplasmic_reticulum": 0, "golgi_apparatus": 0}
|
| 340 |
-
for cell in st.session_state.env.cells:
|
| 341 |
-
for organelle in cell.organelles:
|
| 342 |
-
organelle_counts[organelle] += 1
|
| 343 |
-
st.session_state.fig.data[-1].y = list(organelle_counts.values())
|
| 344 |
|
| 345 |
-
# Update
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 346 |
total_cells = len(st.session_state.env.cells)
|
| 347 |
total_cells_text.text(f"Total Cells: {format_number(total_cells)}")
|
| 348 |
|
| 349 |
-
cell_type_counts = {cell_type: len([
|
| 350 |
-
|
|
|
|
| 351 |
|
| 352 |
dominant_type = max(cell_type_counts, key=cell_type_counts.get)
|
| 353 |
dominant_type_text.text(f"Dominant Type: {dominant_type}")
|
| 354 |
|
| 355 |
avg_energy = sum(cell.energy for cell in st.session_state.env.cells) / total_cells if total_cells > 0 else 0
|
| 356 |
-
avg_energy_text.text(f"
|
| 357 |
|
| 358 |
total_merges_text.text(f"Total Merges: {st.session_state.total_merges}")
|
| 359 |
|
| 360 |
-
|
| 361 |
-
event_log_text.text("Recent Events:\n" + "\n".join(event_log))
|
| 362 |
-
|
| 363 |
-
chart_placeholder.plotly_chart(st.session_state.fig, use_container_width=True)
|
| 364 |
|
| 365 |
-
# Main loop
|
| 366 |
-
|
| 367 |
|
| 368 |
-
# Main loop
|
| 369 |
while True:
|
| 370 |
-
with
|
| 371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
time.sleep(update_interval)
|
| 373 |
|
| 374 |
-
|
|
|
|
|
|
|
| 375 |
if not st.session_state.running:
|
| 376 |
-
break
|
|
|
|
|
|
|
|
|
| 285 |
if 'fig' not in st.session_state:
|
| 286 |
st.session_state.fig = None
|
| 287 |
|
| 288 |
+
def start_simulation():
|
| 289 |
+
st.session_state.running = True
|
| 290 |
+
if st.session_state.env is None:
|
| 291 |
st.session_state.env = Environment(100, 100, effects)
|
| 292 |
for _ in range(initial_cells):
|
| 293 |
cell = Cell(random.uniform(0, st.session_state.env.width), random.uniform(0, st.session_state.env.height))
|
| 294 |
st.session_state.env.add_cell(cell)
|
| 295 |
st.session_state.fig = setup_figure(st.session_state.env)
|
| 296 |
|
| 297 |
+
def stop_simulation():
|
| 298 |
+
st.session_state.running = False
|
| 299 |
|
| 300 |
+
# Create two columns for start and stop buttons
|
| 301 |
+
col1, col2 = st.columns(2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
|
| 303 |
+
with col1:
|
| 304 |
+
start_button = st.button("Start Simulation", on_click=start_simulation)
|
|
|
|
|
|
|
| 305 |
|
| 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 |
while True:
|
| 359 |
+
with simulation_container.container():
|
| 360 |
+
if st.session_state.running and st.session_state.env is not None:
|
| 361 |
+
for _ in range(4): # Update 4 times per frame to increase simulation speed
|
| 362 |
+
initial_cell_count = len(st.session_state.env.cells)
|
| 363 |
+
st.session_state.env.update()
|
| 364 |
+
final_cell_count = len(st.session_state.env.cells)
|
| 365 |
+
|
| 366 |
+
# Check for merges
|
| 367 |
+
if final_cell_count < initial_cell_count:
|
| 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 |
+
update_chart()
|
| 373 |
+
update_statistics()
|
| 374 |
+
|
| 375 |
time.sleep(update_interval)
|
| 376 |
|
| 377 |
+
simulation_container.empty()
|
| 378 |
+
|
| 379 |
+
# Break the loop if the simulation is not running
|
| 380 |
if not st.session_state.running:
|
| 381 |
+
break
|
| 382 |
+
|
| 383 |
+
st.write("Simulation stopped. Click 'Start Simulation' to run again.")
|