File size: 7,393 Bytes
a8cc94d 23bd555 9633bd9 bcfb38f 9633bd9 9686272 23bd555 9633bd9 23bd555 9633bd9 23bd555 9633bd9 23bd555 56aed2d 23bd555 9686272 23bd555 9686272 da47dd8 9686272 23bd555 9686272 56aed2d 23bd555 9686272 23bd555 9686272 23bd555 9686272 bcfb38f 9686272 bcfb38f 56aed2d bcfb38f 23bd555 9686272 bcfb38f 9686272 bcfb38f 23bd555 9686272 23bd555 9686272 23bd555 56aed2d 9686272 56aed2d 23bd555 c87ff7e 9686272 bcfb38f c87ff7e 23bd555 56aed2d 23bd555 9686272 23bd555 9686272 23bd555 9686272 23bd555 |
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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
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() |