Update app.py
Browse files
app.py
CHANGED
@@ -5,9 +5,8 @@ import random
|
|
5 |
import time
|
6 |
from scipy.stats import entropy as scipy_entropy
|
7 |
|
8 |
-
#
|
9 |
seqlen = 60
|
10 |
-
steps = 10000
|
11 |
min_run, max_run = 1, 2
|
12 |
ANGLE_MAP = {'A': 60.0, 'C': 180.0, 'G': -60.0, 'T': -180.0, 'N': 0.0}
|
13 |
bases = ['A', 'C', 'G', 'T']
|
@@ -16,7 +15,7 @@ lags_shown = 6
|
|
16 |
st.set_page_config(layout="wide")
|
17 |
st.title("🌌 Визуализация торсионных биомашин")
|
18 |
|
19 |
-
#
|
20 |
col1, col2, col3 = st.columns([1,1,2])
|
21 |
with col1:
|
22 |
if 'running' not in st.session_state:
|
@@ -36,7 +35,7 @@ with col2:
|
|
36 |
with col3:
|
37 |
speed = st.slider("⏱ Скорость обновления (мс)", 10, 1000, 200, step=10)
|
38 |
|
39 |
-
#
|
40 |
if 'seq' not in st.session_state:
|
41 |
st.session_state.seq = ''.join(random.choices(bases, k=seqlen))
|
42 |
if 'step' not in st.session_state:
|
@@ -46,7 +45,7 @@ if 'stat_bist_counts' not in st.session_state:
|
|
46 |
st.session_state.stat_entropy = []
|
47 |
st.session_state.stat_autocorr = []
|
48 |
|
49 |
-
#
|
50 |
def find_local_min_runs(profile, min_run=1, max_run=2):
|
51 |
result = []
|
52 |
N = len(profile)
|
@@ -101,35 +100,31 @@ def bio_mutate(seq):
|
|
101 |
if len(seq) > 10:
|
102 |
start = random.randint(0, len(seq)-6)
|
103 |
end = start + random.randint(3,6)
|
104 |
-
subseq = seq[start:end]
|
105 |
-
subseq = subseq[::-1]
|
106 |
seq = seq[:start] + subseq + seq[end:]
|
107 |
while len(seq) < seqlen:
|
108 |
seq += random.choice(bases)
|
109 |
-
|
110 |
-
seq = seq[:seqlen]
|
111 |
-
return seq
|
112 |
|
113 |
-
#
|
114 |
plot_area = st.empty()
|
115 |
-
fig, axs = plt.subplots(3, 1, figsize=(10, 8))
|
116 |
-
plt.subplots_adjust(hspace=0.5)
|
117 |
|
118 |
-
# --- ЦИКЛ ВИЗУАЛИЗАЦИИ ---
|
119 |
while st.session_state.running:
|
|
|
120 |
st.session_state.seq = bio_mutate(st.session_state.seq)
|
121 |
torsion_profile = np.array([ANGLE_MAP.get(nt, 0.0) for nt in st.session_state.seq])
|
122 |
runs = find_local_min_runs(torsion_profile, min_run, max_run)
|
123 |
ent = compute_entropy(torsion_profile)
|
124 |
acorr = compute_autocorr(torsion_profile)
|
125 |
|
|
|
126 |
st.session_state.stat_bist_counts = st.session_state.stat_bist_counts[-50:] + [len(runs)]
|
127 |
st.session_state.stat_entropy = st.session_state.stat_entropy[-50:] + [ent]
|
128 |
st.session_state.stat_autocorr = st.session_state.stat_autocorr[-50:] + [acorr]
|
129 |
|
130 |
-
|
131 |
-
axs
|
132 |
-
|
133 |
|
134 |
axs[0].plot(torsion_profile, color='royalblue')
|
135 |
for start, end, val in runs:
|
@@ -142,8 +137,8 @@ while st.session_state.running:
|
|
142 |
axs[1].set_title("Число 'биомашин'")
|
143 |
|
144 |
axs[2].bar(np.arange(lags_shown), acorr[:lags_shown], color='teal')
|
145 |
-
axs[2].set_title("Автокорреляция
|
146 |
|
147 |
-
plot_area.pyplot(fig
|
148 |
st.session_state.step += 1
|
149 |
time.sleep(speed / 1000.0)
|
|
|
5 |
import time
|
6 |
from scipy.stats import entropy as scipy_entropy
|
7 |
|
8 |
+
# Константы
|
9 |
seqlen = 60
|
|
|
10 |
min_run, max_run = 1, 2
|
11 |
ANGLE_MAP = {'A': 60.0, 'C': 180.0, 'G': -60.0, 'T': -180.0, 'N': 0.0}
|
12 |
bases = ['A', 'C', 'G', 'T']
|
|
|
15 |
st.set_page_config(layout="wide")
|
16 |
st.title("🌌 Визуализация торсионных биомашин")
|
17 |
|
18 |
+
# UI
|
19 |
col1, col2, col3 = st.columns([1,1,2])
|
20 |
with col1:
|
21 |
if 'running' not in st.session_state:
|
|
|
35 |
with col3:
|
36 |
speed = st.slider("⏱ Скорость обновления (мс)", 10, 1000, 200, step=10)
|
37 |
|
38 |
+
# Init
|
39 |
if 'seq' not in st.session_state:
|
40 |
st.session_state.seq = ''.join(random.choices(bases, k=seqlen))
|
41 |
if 'step' not in st.session_state:
|
|
|
45 |
st.session_state.stat_entropy = []
|
46 |
st.session_state.stat_autocorr = []
|
47 |
|
48 |
+
# Функции
|
49 |
def find_local_min_runs(profile, min_run=1, max_run=2):
|
50 |
result = []
|
51 |
N = len(profile)
|
|
|
100 |
if len(seq) > 10:
|
101 |
start = random.randint(0, len(seq)-6)
|
102 |
end = start + random.randint(3,6)
|
103 |
+
subseq = seq[start:end][::-1]
|
|
|
104 |
seq = seq[:start] + subseq + seq[end:]
|
105 |
while len(seq) < seqlen:
|
106 |
seq += random.choice(bases)
|
107 |
+
return seq[:seqlen]
|
|
|
|
|
108 |
|
109 |
+
# Визуализация
|
110 |
plot_area = st.empty()
|
|
|
|
|
111 |
|
|
|
112 |
while st.session_state.running:
|
113 |
+
# Мутация
|
114 |
st.session_state.seq = bio_mutate(st.session_state.seq)
|
115 |
torsion_profile = np.array([ANGLE_MAP.get(nt, 0.0) for nt in st.session_state.seq])
|
116 |
runs = find_local_min_runs(torsion_profile, min_run, max_run)
|
117 |
ent = compute_entropy(torsion_profile)
|
118 |
acorr = compute_autocorr(torsion_profile)
|
119 |
|
120 |
+
# Сохраняем последние 50
|
121 |
st.session_state.stat_bist_counts = st.session_state.stat_bist_counts[-50:] + [len(runs)]
|
122 |
st.session_state.stat_entropy = st.session_state.stat_entropy[-50:] + [ent]
|
123 |
st.session_state.stat_autocorr = st.session_state.stat_autocorr[-50:] + [acorr]
|
124 |
|
125 |
+
# График
|
126 |
+
fig, axs = plt.subplots(3, 1, figsize=(10, 8))
|
127 |
+
plt.subplots_adjust(hspace=0.5)
|
128 |
|
129 |
axs[0].plot(torsion_profile, color='royalblue')
|
130 |
for start, end, val in runs:
|
|
|
137 |
axs[1].set_title("Число 'биомашин'")
|
138 |
|
139 |
axs[2].bar(np.arange(lags_shown), acorr[:lags_shown], color='teal')
|
140 |
+
axs[2].set_title("Автокорреляция")
|
141 |
|
142 |
+
plot_area.pyplot(fig)
|
143 |
st.session_state.step += 1
|
144 |
time.sleep(speed / 1000.0)
|