siddhant-rajhans commited on
Commit
21d9b75
·
1 Parent(s): 9b23ae9

Add Dockerfile and app.py for HuggingFace Spaces deployment

Browse files
Files changed (2) hide show
  1. Dockerfile +16 -0
  2. app.py +110 -0
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ RUN apt-get update && apt-get install -y --no-install-recommends \
6
+ build-essential \
7
+ && rm -rf /var/lib/apt/lists/*
8
+
9
+ COPY requirements.txt .
10
+ RUN pip install --no-cache-dir -r requirements.txt
11
+
12
+ COPY . .
13
+
14
+ EXPOSE 7860
15
+
16
+ CMD ["streamlit", "run", "app.py", "--server.port=7860", "--server.headless=true", "--server.address=0.0.0.0"]
app.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """CortexLab Dashboard - Home Page with Data Management."""
2
+
3
+ import streamlit as st
4
+ import numpy as np
5
+
6
+ from session import init_session, data_summary_widget, show_analysis_log, upload_npy_widget
7
+ from utils import make_roi_indices
8
+
9
+ st.set_page_config(page_title="CortexLab Dashboard", page_icon="🧠", layout="wide", initial_sidebar_state="expanded")
10
+ init_session()
11
+
12
+ st.title("CortexLab Dashboard")
13
+ st.markdown("**Research-grade analysis toolkit for multimodal fMRI brain encoding**")
14
+
15
+ # --- Data Source ---
16
+ st.divider()
17
+ st.subheader("Data Configuration")
18
+
19
+ col_src, col_params = st.columns([1, 2])
20
+
21
+ with col_src:
22
+ source = st.radio("Data source", ["Synthetic (realistic)", "Upload your data"], index=0)
23
+ st.session_state["data_source"] = "synthetic" if "Synthetic" in source else "uploaded"
24
+
25
+ with col_params:
26
+ if st.session_state["data_source"] == "synthetic":
27
+ c1, c2, c3, c4 = st.columns(4)
28
+ st.session_state["stimulus_type"] = c1.selectbox("Stimulus type", ["visual", "auditory", "language", "multimodal"])
29
+ st.session_state["n_timepoints"] = c2.slider("Duration (TRs)", 30, 200, 80)
30
+ st.session_state["tr_seconds"] = c3.slider("TR (seconds)", 0.5, 2.0, 1.0, 0.1)
31
+ st.session_state["seed"] = c4.number_input("Seed", value=42, min_value=0)
32
+
33
+ # Generate on config change
34
+ roi_indices, n_vertices = make_roi_indices()
35
+ st.session_state["roi_indices"] = roi_indices
36
+ st.session_state["n_vertices"] = n_vertices
37
+
38
+ from synthetic import generate_realistic_predictions
39
+ predictions = generate_realistic_predictions(
40
+ st.session_state["n_timepoints"], roi_indices,
41
+ st.session_state["stimulus_type"], st.session_state["tr_seconds"],
42
+ seed=st.session_state["seed"],
43
+ )
44
+ st.session_state["brain_predictions"] = predictions
45
+ else:
46
+ uploaded = upload_npy_widget("Upload brain predictions (.npy, shape: timepoints x vertices)", "upload_predictions")
47
+ if uploaded is not None:
48
+ st.session_state["brain_predictions"] = uploaded
49
+ roi_indices, _ = make_roi_indices()
50
+ st.session_state["roi_indices"] = roi_indices
51
+
52
+ # --- Data Summary ---
53
+ roi_indices = st.session_state.get("roi_indices")
54
+ predictions = st.session_state.get("brain_predictions")
55
+ if predictions is not None and roi_indices is not None:
56
+ data_summary_widget(predictions, roi_indices)
57
+
58
+ # Show HRF-convolved signal preview
59
+ with st.expander("Data Preview", expanded=False):
60
+ import plotly.graph_objects as go
61
+ from utils import ROI_GROUPS
62
+
63
+ fig = go.Figure()
64
+ t = np.arange(predictions.shape[0]) * st.session_state.get("tr_seconds", 1.0)
65
+ colors = {"Visual": "#00D2FF", "Auditory": "#FF6B6B", "Language": "#A29BFE", "Executive": "#FFEAA7"}
66
+ for group, rois in ROI_GROUPS.items():
67
+ vals = []
68
+ for roi in rois:
69
+ if roi in roi_indices:
70
+ verts = roi_indices[roi]
71
+ valid = verts[verts < predictions.shape[1]]
72
+ if len(valid) > 0:
73
+ vals.append(np.abs(predictions[:, valid]).mean(axis=1))
74
+ if vals:
75
+ mean_tc = np.mean(vals, axis=0)
76
+ fig.add_trace(go.Scatter(x=t, y=mean_tc, name=group, line=dict(color=colors.get(group, "#888"), width=2)))
77
+
78
+ fig.update_layout(
79
+ xaxis_title="Time (seconds)", yaxis_title="Mean |activation|",
80
+ height=300, template="plotly_dark",
81
+ legend=dict(orientation="h", yanchor="bottom", y=1.02),
82
+ )
83
+ st.plotly_chart(fig, use_container_width=True)
84
+ st.caption("Mean absolute activation per functional group. Note the hemodynamic response shape and modality-specific activation patterns.")
85
+
86
+ # --- Navigation ---
87
+ st.divider()
88
+ col1, col2 = st.columns(2)
89
+
90
+ with col1:
91
+ st.subheader("Analysis Tools")
92
+ st.page_link("pages/1_Brain_Alignment.py", label="Brain Alignment Benchmark", icon="🎯")
93
+ st.caption("RSA, CKA, Procrustes with permutation tests, bootstrap CIs, FDR correction, noise ceiling, and RDM visualization")
94
+
95
+ st.page_link("pages/2_Cognitive_Load.py", label="Cognitive Load Scorer", icon="📊")
96
+ st.caption("Timeline with confidence bands, dimension correlation, per-ROI breakdown, comparison mode")
97
+
98
+ with col2:
99
+ st.subheader("Advanced Analysis")
100
+ st.page_link("pages/3_Temporal_Dynamics.py", label="Temporal Dynamics", icon="⏱️")
101
+ st.caption("Raw timecourses, peak latency hierarchy, optimal lag analysis, cross-ROI lag matrix")
102
+
103
+ st.page_link("pages/4_Connectivity.py", label="ROI Connectivity", icon="🔗")
104
+ st.caption("Partial correlation, modularity, betweenness centrality, dendrogram, network graph")
105
+
106
+ # --- Analysis Log ---
107
+ show_analysis_log()
108
+
109
+ st.divider()
110
+ st.caption("[GitHub](https://github.com/siddhant-rajhans/cortexlab) | [HuggingFace](https://huggingface.co/SID2000/cortexlab) | [Dashboard Repo](https://github.com/siddhant-rajhans/cortexlab-dashboard)")