Worm / app.py
Dmtlant's picture
Update app.py
9686272 verified
import streamlit as st
from brian2 import *
import numpy as np
import plotly.graph_objects as go
def run_simulation(num_neurons=12, sim_time=100*ms):
# Установка времени симуляции и временного шага
defaultclock.dt = 0.1*ms
# Определение уравнений для нейронов
eqs = '''
dv/dt = (I - v)/tau : 1 (unless refractory)
I : 1
tau : second
'''
# Создание группы нейронов
G = NeuronGroup(num_neurons, eqs, threshold='v>1', reset='v = 0', refractory=5*ms, method='euler')
# Начальные условия
G.I = np.linspace(1.5, 2.0, num_neurons) # Разные токи для разных сегментов
G.tau = 10*ms
# Создание переменной для записи результатов
M = StateMonitor(G, 'v', record=True)
# Запуск симуляции
run(sim_time)
# Моделирование механики червя
# Упрощенная модель: каждый сегмент движется в зависимости от активности нейронов
# Параметры червя
segment_length = 0.5 # Длина каждого сегмента
num_segments = num_neurons
worm_length = segment_length * num_segments
# Начальные позиции сегментов (случайные)
num_frames = len(M.t)
positions = np.zeros((num_frames, num_segments, 2))
initial_positions = np.random.rand(num_segments, 2) * 10 # Случайные начальные позиции в пространстве 10x10
positions[0, :, :] = initial_positions
# Обновление позиций сегментов на основе активности нейронов
for frame in range(1, num_frames):
for i in range(num_segments):
if i == 0:
# Головной сегмент движется случайным образом
positions[frame, i, 0] = positions[frame-1, i, 0] + (np.random.rand() - 0.5) * 0.5
positions[frame, i, 1] = positions[frame-1, i, 1] + (np.random.rand() - 0.5) * 0.5
else:
# Остальные сегменты следуют за предыдущими
positions[frame, i, 0] = positions[frame-1, i-1, 0] + segment_length
positions[frame, i, 1] = positions[frame-1, i-1, 1] + (M.v[i][frame] - 1) * 0.1
return positions, M.t
def create_plotly_animation(positions, times):
num_frames, num_segments, _ = positions.shape
# Создание фигуры Plotly
fig = go.Figure(
layout=go.Layout(
xaxis=dict(range=[-10, 20], autorange=False),
yaxis=dict(range=[-10, 20], autorange=False),
title="Движение червя",
showlegend=False,
width=800,
height=600
)
)
# Добавление кадров
frames = []
for frame in range(num_frames):
x = positions[frame, :, 0]
y = positions[frame, :, 1]
frames.append(go.Frame(data=[go.Scatter(x=x, y=y, mode='lines+markers',
marker=dict(size=10, color='blue'),
line=dict(width=2, color='blue'))],
name=f'frame{frame}',
layout=go.Layout(title_text=f'Время: {times[frame]:.1f} ms')))
fig.frames = frames
# Добавление начального состояния
initial_x = positions[0, :, 0]
initial_y = positions[0, :, 1]
fig.add_trace(go.Scatter(x=initial_x, y=initial_y, mode='lines+markers',
marker=dict(size=10, color='blue'),
line=dict(width=2, color='blue')))
# Настройка анимации
fig.update_layout(
updatemenus=[
dict(
type="buttons",
buttons=[
dict(label="▶️ Запустить",
method="animate",
args=[None, {"frame": {"duration": 100, "redraw": True},
"fromcurrent": True, "transition": {"duration": 0}}]),
dict(label="⏹️ Остановить",
method="animate",
args=[[None], {"frame": {"duration": 0, "redraw": False},
"mode": "immediate",
"transition": {"duration": 0}}])
],
showactive=False,
x=0,
y=1.05
)
]
)
return fig
def main():
st.title("Симуляция движения червя с использованием Streamlit и Brian2")
st.write("""
Это веб-приложение выполняет симуляцию нейронной активности и соответствующего движения червя.
Используется **Plotly** для отображения интерактивной анимации.
""")
st.sidebar.header("Параметры Симуляции")
num_neurons = st.sidebar.slider('Количество сегментов червя', min_value=5, max_value=20, value=12)
sim_time_ms = st.sidebar.slider('Время симуляции (мс)', min_value=50, max_value=500, value=100, step=10)
if st.button("Запустить симуляцию"):
with st.spinner('Выполнение симуляции и создание анимации...'):
try:
positions, times = run_simulation(num_neurons=num_neurons, sim_time=sim_time_ms*ms)
fig = create_plotly_animation(positions, times)
st.plotly_chart(fig, use_container_width=True)
st.success('Симуляция завершена!')
except Exception as e:
st.error(f"Произошла ошибка: {e}")
st.write("""
### Описание
- **Количество сегментов червя**: устанавливается пользователем (по умолчанию 12)
- **Длина каждого сегмента**: 0.5 единиц
- **Время симуляции**: устанавливается пользователем (по умолчанию 100 мс)
- **Модель нейронов**: Простая модель с параметрами I и tau, влияющими на потенциал v.
### Как это работает
1. **Симуляция нейронов**: Создается группа нейронов с разными токами и временем релаксации.
2. **Механика червя**: Каждому сегменту соответствует нейрон. Активность нейронов влияет на движение сегментов.
3. **Анимация**: Полученные позиции сегментов визуализируются в интерактивной анимации движения червя.
""")
if __name__ == "__main__":
main()