-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
156 lines (126 loc) · 5.36 KB
/
Copy pathapp.py
File metadata and controls
156 lines (126 loc) · 5.36 KB
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
154
155
156
import streamlit as st
st.set_page_config(
page_title="EEG Brainwave Analyzer",
page_icon="〜",
layout="wide",
initial_sidebar_state="expanded",
)
import numpy as np
from core import (BAND_NAMES, extract_band_power,
compute_relative_power, classify_signal)
from data import (run_pipeline, load_bonn_segment_from_bytes)
from benchmark import run_complexity_benchmark, theoretical_curves
from ui import (inject_css,
render_hero, render_section,
render_classification_cards, render_band_table,
render_complexity_table, render_algo_trace,
render_footer,
time_domain_chart, power_spectrum_chart,
band_bar_chart, radar_chart,
complexity_chart, recursion_tree_chart)
inject_css()
st.markdown("""
<script>
(function() {
Object.keys(localStorage).forEach(function(k) {
if (k.includes('Sidebar') || k.includes('sidebar')) {
localStorage.removeItem(k);
}
});
})();
</script>
""", unsafe_allow_html=True)
with st.sidebar:
st.markdown('<div class="sidebar-title">Dataset</div>', unsafe_allow_html=True)
file_a = st.file_uploader("**Set A** - Normal / Healthy (Z***.txt)",
type=["txt"], key="upload_a")
file_e = st.file_uploader("**Set E** - Ictal / Seizure (S***.txt)",
type=["txt"], key="upload_e")
st.divider()
st.markdown('<div class="sidebar-title">Sections</div>', unsafe_allow_html=True)
show_benchmark = st.toggle("Complexity Benchmark", value=True)
show_dnc = st.toggle("D&C Algorithm Trace", value=True)
st.divider()
st.markdown('<div class="sidebar-title">Display</div>', unsafe_allow_html=True)
freq_max = st.slider("Max Frequency (Hz)", 20, 100, 60)
st.divider()
st.markdown("""
<div style="font-size:0.72rem;color:#7a8398;line-height:1.7;
font-family:'Open Sans',sans-serif;">
<b style="color:#6a6ff0">Strategi Algoritma</b><br>
EEG Brainwave Frequency Analysis<br>
Using Recursive FFT (D&C)
</div>""", unsafe_allow_html=True)
render_hero()
signal_a = signal_e = None
label_a = label_e = None
if file_a:
signal_a = load_bonn_segment_from_bytes(file_a.read())
label_a = f"Set A — {file_a.name}"
if file_e:
signal_e = load_bonn_segment_from_bytes(file_e.read())
label_e = f"Set E — {file_e.name}"
if not file_a or not file_e:
st.markdown("""
<div class="await-box">
<div class="await-desc">
Upload <b>Set A</b> (Z***.txt) and <b>Set E</b> (S***.txt)
from the sidebar to begin analysis.<br><br>
<span style="font-size:0.78rem;color:#aab2c4">
Dataset: Bonn EEG · Andrzejak et al. 2001 ·
<a href="https://www.ukbonn.de/epileptologie/arbeitsgruppen/ag-lehnertz-neurophysik/downloads/"
target="_blank">Download here</a>
</span>
</div>
</div>""", unsafe_allow_html=True)
if signal_a is not None and signal_e is not None:
freqs_a, power_a = run_pipeline(signal_a)
freqs_e, power_e = run_pipeline(signal_e)
bp_a = extract_band_power(power_a, freqs_a)
bp_e = extract_band_power(power_e, freqs_e)
rel_a = compute_relative_power(bp_a)
rel_e = compute_relative_power(bp_e)
cls_a, dom_a = classify_signal(rel_a)
cls_e, dom_e = classify_signal(rel_e)
render_section("01", "Classification Result")
render_classification_cards(cls_a, dom_a, rel_a, cls_e, dom_e, rel_e)
render_section("02", "Raw EEG Signal - Time Domain")
st.plotly_chart(
time_domain_chart(signal_a, signal_e, label_a, label_e),
use_container_width=True,
)
render_section("03", "Power Spectrum - FFT Output (Frequency Domain)")
st.caption("Recursive FFT transforms the raw signal into frequency components. Shaded regions = 5 EEG bands.")
st.plotly_chart(
power_spectrum_chart(freqs_a, power_a, freqs_e, power_e,
label_a, label_e, freq_max=freq_max),
use_container_width=True,
)
render_section("04", "Band Power Distribution")
col_bar, col_tbl = st.columns([3, 2])
with col_bar:
st.plotly_chart(band_bar_chart(rel_a, rel_e), use_container_width=True)
with col_tbl:
st.markdown("**Band Power Summary**")
render_band_table(rel_a, rel_e, BAND_NAMES)
render_section("05", "Band Power Radar - Signal Fingerprint")
st.plotly_chart(radar_chart(rel_a, rel_e), use_container_width=True)
if show_dnc:
render_section("06", "Divide and Conquer - Algorithm Trace")
col_algo, col_tree = st.columns([1, 1])
with col_algo:
render_algo_trace()
with col_tree:
st.plotly_chart(recursion_tree_chart(demo_n=8), use_container_width=True)
if show_benchmark:
render_section("07", "Empirical Complexity Benchmark - DFT O(n²) vs FFT O(n log n)")
with st.spinner("Running benchmark…"):
bench = run_complexity_benchmark()
curves = theoretical_curves(bench)
col_chart, col_tbl = st.columns([3, 2])
with col_chart:
st.plotly_chart(complexity_chart(bench, curves), use_container_width=True)
with col_tbl:
st.markdown("<div style='margin-top:24px'></div>", unsafe_allow_html=True)
render_complexity_table(bench)
render_footer()