Modern neuroscience relies on brain imaging techniques that balance competing priorities such as spatial versus temporal resolution, depth penetration versus portability, and precision versus cost (Deffieux et al., 2021). Functional magnetic resonance imaging (fMRI) provides detailed, whole-brain visualization of hemodynamic activity but remains slow, immobile, and expensive. In contrast, functional near-infrared spectroscopy (fNIRS) offers lightweight, wearable monitoring of cortical blood oxygenation, yet its depth penetration is limited to superficial cortical regions (Scarapiccha et al., 2017). To bridge this divide, this paper proposes an optimized hybrid system that combines fMRI and fNIRS. The aim of this paper is to integrate the spatial precision and whole-brain mapping of fMRI with the temporal flexibility and portability of fNIRS. Together, these modalities could enable researchers to map deep-brain networks within the scanner and then monitor corresponding cortical activity continuously in natural environments (see Figure 1 for an overview of the proposed workflow).
An Integrated fMRIโfNIRS Calibration Framework for Portable and High-Resolution Brain Imaging
Introduction
Which Modalities and Why
Functional MRI (fMRI) measures brain activity by detecting changes in the magnetic properties of blood, known as the blood-oxygen-level-dependent (BOLD) signal, which reflects local neural metabolism (Buxton, 2013). It provides millimeter-scale spatial resolution across the entire brain, including deep structures such as the thalamus and basal ganglia. However, because the BOLD response depends on slow vascular changes, the temporal resolution of fMRI is limited to approximately one to two seconds. Although fMRI remains indispensable for identifying precise activation patterns during cognitive tasks, its immobility, cost, and sensitivity to motion restrict its use to controlled laboratory environments.
Functional near-infrared spectroscopy (fNIRS), by contrast, emits light in the near-infrared range (700โ900 nm) to quantify relative changes in oxy- and deoxy-hemoglobin concentrations in the upper layers of the cortex (Kim et al., 2017). It is completely noninvasive, silent, and portable, allowing researchers to record brain activity in naturalistic settings such as classrooms, clinics, or workplaces. fNIRS offers superior temporal sampling (up to 10โ100 Hz) and greater tolerance to movement compared to fMRI, though it cannot image deep brain structures.
Combining these modalities leverages their complementary strengths. fMRI can establish an individualโs baseline neural architecture with sub-millimeter accuracy, while fNIRS can track those same cortical regions repeatedly and flexibly in real-world environments. Together, they offer a new level of multimodal coverage that no single imaging technique can achieve alone (Scarapiccha et al., 2017).
Integration of the Two Modalities
In the proposed hybrid system, participants would first undergo an fMRI session while wearing a fiber-optic, MR-compatible fNIRS cap. Adopting the methodology of a study conducted by Zhang et al. (2006), the cap would be constructed using non-metallic components to prevent magnetic interference and would allow simultaneous recording of BOLD and optical signals. These initial calibration sessions would align each fNIRS channel with its corresponding fMRI voxel, creating a subject-specific map that links optical signals to anatomical coordinates. Once the calibration is complete, the same fNIRS cap could then be used in portable, real-world settings, where new data would be continuously compared to the original fMRI reference (as shown in Figure 1).
The temporal synchronization between modalities presents another challenge. While fMRI records one volume roughly every two seconds, fNIRS can sample between ten and fifty times per second. To merge these signals, temporal interpolation and lag-compensation algorithms would be used to align the slower hemodynamic trends of fMRI with the faster optical measurements (Yuan & Ye, 2013). Shared event markers, such as auditory tones or button presses, would further help synchronize data across both systems. A Kalman-filter model could combine the BOLD signal with the rapid fNIRS fluctuations, producing a continuous and temporally smoothed estimate of neural activity at sub-second precision (Durantin et al., 2016).
Spatial integration would rely on using the individualโs high-resolution structural MRI scan as a three-dimensional anatomical template. Each fNIRS optode position could be co-registered to the scalp landmarks visible in that MRI, ensuring accurate localization of surface signals. Advanced machine-learning models could even use fNIRS surface patterns to predict deeper BOLD activity, effectively extending optical coverage beyond its natural limit (Liu et al., 2015). In this way, fMRI provides the scaffolding, and fNIRS supplies the dynamic, real-time updates.
Nature of the Multimodal Data
The hybrid system would produce data at multiple scales. fMRI generates volumetric voxel matrices representing BOLD intensity over time, whereas fNIRS provides continuous time-series traces of changes in oxy- and deoxy-hemoglobin concentration (Yuan & Ye, 2013). Once co-registered and temporally aligned, the combined output could be visualized as dynamic cortical activation maps, with color-coded oxygenation changes overlaid on the anatomical brain model. An example of this type of fused data visualization is illustrated in Figure 2.
Technical and Practical Challenges
Developing and deploying such a hybrid system involves several engineering and logistical challenges. Magnetic compatibility remains a key issue, as conventional optodes can distort the MRI field. This can be mitigated by constructing optodes from plastic fiber housings and employing optical isolation to prevent interference (Duffy et al., 2015). Differences in sampling rates between fMRI and fNIRS can be addressed through temporal resampling and model-based fusion algorithms.
Motion artifacts are another persistent concern in fNIRS, particularly when subjects move freely during real-world data collection. Incorporating motion sensors and short-channel regression techniques can help correct for this problem (Brigadoi et al., 2014). The enormous volume of multimodal data also requires significant computational power; real-time compression and GPU-based analysis could help maintain manageable data loads (Tran & Cambria, 2018). Cost represents an additional challenge, but this could be offset by using a single fMRI session for calibration and relying on affordable fNIRS hardware for extended field use. Finally, user comfort must be prioritized through the development of lightweight, flexible, and wireless fNIRS caps that participants can wear for hours without discomfort.
Real-World Applications
A hybrid fMRIโfNIRS system could transform both basic neuroscience and clinical practice. In rehabilitation, fMRI could identify the networks impaired by stroke, while portable fNIRS would track cortical reorganization during months of therapy (Golestani et al., 2013; Cao et al., 2015). In mental-health research, baseline fMRI scans could characterize emotion-regulation networks, and ongoing fNIRS monitoring could detect subtle shifts signaling relapse or recovery (Ellard et al., 2018; Huang et al., 2025). The system could also advance neuroergonomics by monitoring cognitive workload in pilots, drivers, and surgeons. fNIRS caps, calibrated to each userโs fMRI profile, could detect fatigue or attentional lapses in real time (Harrivel et al., 2012). In developmental neuroscience and education, researchers could use the hybrid approach to follow brain maturation over time, combining laboratory precision with naturalistic observation in real-world learning environments (Atteveldt et al., 2018).
Limitations and Future Directions
Despite its potential, this hybrid approach faces several inherent limitations. fNIRS remains restricted to superficial cortical layers, making it difficult to directly observe deep-brain networks. Both modalities rely on hemodynamic responses, which are indirect and temporally delayed indicators of neuronal activity. Furthermore, fMRI calibration sessions are expensive and limited to specialized facilities.
Future advances may help overcome these constraints. The emergence of low-field or portable MRI systems could make calibration more accessible (Morris, 2025). Improvements in optode design, such as quantum-dotโbased light sources and ultrafast photodiodes, may enhance sensitivity and penetration depth. Finally, AI-driven real-time fusion algorithms could predict whole-brain dynamics from a reduced set of surface measurements, paving the way for truly wearable neuroimaging systems. Together, these innovations would evolve the hybrid model into a continuous, scalable, and ecologically valid method for mapping the human brain.
Conclusion
By combining fMRIโs unparalleled spatial resolution with fNIRSโs accessibility and temporal responsiveness, this hybrid framework represents a powerful bridge between laboratory-based neuroimaging and real-world monitoring. It offers a scientifically rigorous yet flexible approach for studying cognition, emotion, and clinical recovery over time. Integrating these modalities not only enhances the quality and continuity of neural data but also moves neuroscience closer to achieving truly comprehensive, multiscale mapping of the human brain.
๐ References
- Deffieux, T., Demenรฉ, C., & Tanter, M. (2021). Functional Ultrasound Imaging: A New Imaging Modality for Neuroscience. Neuroscience, 474, 110-121.
- Scarapicchia, V., Brown, C., Mayo, C., & Gawryluk, J. R. (2017). Functional Magnetic Resonance Imaging and Functional Near-Infrared Spectroscopy: Insights from Combined Recording Studies. Frontiers in human neuroscience, 11, 419. https://doi.org/10.3389/fnhum.2017.00419
- Buxton, R. B. (2013). The physics of functional magnetic resonance imaging (fMRI). Reports on Progress in Physics, 76(9). https://doi.org/10.1088/0034-4885/76/9/096601
- Kim, H. Y., Seo, K., Jeon, H. J., Lee, U., & Lee, H. (2017). Application of Functional Near-Infrared Spectroscopy to the Study of Brain Function in Humans and Animal Models. Molecules and Cells, 40(8), 523โ532. https://doi.org/10.14348/molcells.2017.0153
- Zhang, X., Toronov, V. Y., & Webb, A. G. (2006). Integrated measurement system for simultaneous functional magnetic resonance imaging and diffuse optical tomography in human brain mapping. Review of Scientific Instruments, 77(11), 114301. https://doi.org/10.1063/1.2364138
- Yuan, Z., & Ye, J. (2013). Fusion of fNIRS and fMRI data: identifying when and where hemodynamic signals are changing in human brains. Frontiers in Human Neuroscience, 7. https://doi.org/10.3389/fnhum.2013.00676
- Durantin, G., Scannella, S., Gateau, T., Delorme, A., & Dehais, F. (2016). Processing Functional Near Infrared Spectroscopy Signal with a Kalman Filter to Assess Working Memory during Simulated Flight. Frontiers in Human Neuroscience, 9. https://doi.org/10.3389/fnhum.2015.00707
- Liu, N., Cui, X., Bryant, D. M., Glover, G. H., & Reiss, A. L. (2015). Inferring deep-brain activity from cortical activity using functional near-infrared spectroscopy. Biomedical Optics Express, 6(3), 1074. https://doi.org/10.1364/boe.6.001074
- Yang, L., & Wang, Z. (2025). Applications and advances of combined fMRI-fNIRs techniques in brain functional research. Frontiers in Neurology, 16. https://doi.org/10.3389/fneur.2025.1542075
- Boubela, R. N., Kalcher, K., Huf, W., Naลกel, C., & Moser, E. (2016). Big Data Approaches for the Analysis of Large-Scale fMRI Data Using Apache Spark and GPU Processing: A Demonstration on Resting-State fMRI Data from the Human Connectome Project. Frontiers in Neuroscience, 9. https://doi.org/10.3389/fnins.2015.00492
- Duffy, B. A., Choy, M., Chuapoco, M. R., Madsen, M., & Lee, J. H. (2015). MRI compatible optrodes for simultaneous LFP and optogenetic fMRI investigation of seizure-like afterdischarges. NeuroImage, 123, 173โ184. https://doi.org/10.1016/j.neuroimage.2015.07.038
- Brigadoi, S., Ceccherini, L., Cutini, S., Scarpa, F., Scatturin, P., Selb, J., Gagnon, L., Boas, D. A., & Cooper, R. J. (2014). Motion artifacts in functional near-infrared spectroscopy: A comparison of motion correction techniques applied to real cognitive data. NeuroImage, 85, 181โ191. https://doi.org/10.1016/j.neuroimage.2013.04.082
- Tran, H.N., & Cambria, E. (2018). GPU-based Commonsense Paradigms Reasoning for Real-Time Query Answering and Multimodal Analysis. ArXiv, abs/1807.08804.
- Golestani, A.-M., Tymchuk, S., Demchuk, A., & Goodyear, B. G. (2012). Longitudinal Evaluation of Resting-State fMRI After Acute Stroke With Hemiparesis. Neurorehabilitation and Neural Repair, 27(2), 153โ163. https://doi.org/10.1177/1545968312457827
- Cao, J., Khan, B., Hervey, N., Tian, F., Delgado, M. R., Clegg, N. J., Smith, L., Roberts, H., Tulchin-Francis, K., Shierk, A., Shagman, L., MacFarlane, D., Liu, H., & Alexandrakis, G. (2015). FNIRS-based evaluation of cortical plasticity in children with cerebral palsy undergoing constraint-induced movement therapy. Proceedings of SPIE, the International Society for Optical Engineering/Proceedings of SPIE, 9305, 93050N93050N. https://doi.org/10.1117/12.2076995
- Huang, A., Wang, R., Wen, A., Xu, L., Li, N., Gao, Y., Lu, W., Guo, S., Wang, J., & Wang, L. (2025). Clinical value of predicting relapse within 3 months in alcohol-dependent patients using fNIRS in verbal fluency task. Scientific Reports, 15(1), 5283โ5283. https://doi.org/10.1038/s41598-025-89775-7
- Harrivel, A.R., Hylton, A., & Hearn, T.A. (2012). Best Practices for the Application of Functional Near Infrared Spectroscopy to Operator State Sensing.
- van Atteveldt, N. M., van Kesteren, M., Braams, B., & Krabbendam, L. (2018). Neuroimaging of learning and development: improving ecological validity. Frontline Learning Research, 6(3), 186โ203. https://doi.org/10.14786/flr.v6i3.366
- Morris, J.W. (2025). Slug-Mapper: Magnetic Scanner for Ultra Low-Field MRI Scanners.
Other Course Work
๐ Assignment 1: EEG Analysis
๐ PSYCH 403 โ Assignment 1 - Zainab Samiuddin.pdf
View Original PDFEEG Data Loading and Basic Filtering
Zainab Samiuddin
2025-09-22
Explanation : EEG signals from the fi rst 10 channels over 10 seconds. The left panel
shows the raw data, while the right panel shows the same signals after applying a 1โ40
Hz band-pass fi lter to remove slow drifts and high-frequency noise.
Explanation: This side by side plot compares the power spectra of raw and fi ltered EEG
signals. In the raw condition (left), power is spread across the entire frequency range,
with large contributions at very low frequencies (<1 Hz) and high-frequency noise above
40 Hz. After applying a 1โ40 Hz band-pass fi lter (right), these unwanted components
are removed. The fi ltered spectrum highlights meaningful EEG rhythms, with visible
power in the Delta (0.5โ4 Hz), Theta (4โ8 Hz), Alpha (8โ13 Hz), and Beta (13โ30 Hz)
bands.
Code
# EEG Data Analysis Assignment
# PSYCH 403A1 - Assignment 1
import mne
import matplotlib.pyplot as plt
import numpy as np
from pathlib import Path
# ---------------------------------------------------------
# 1) Download and load the sample EEG dataset
# ---------------------------------------------------------
print(" ๐ฅ Loading EEG data...")
sample_data_folder = Path(mne.datasets.sample.data_path())
raw_ fi le = sample_data_folder / 'MEG' / 'sample' / 'sample_audvis_raw. fi f'
# Load EEG fi le into memory
raw = mne.io.read_raw_ fi f(raw_ fi le, preload=True)
# Keep only EEG channels
raw.pick_types(meg=False, eeg=True, stim=False, exclude='bads')
# ---------------------------------------------------------
# 2) Plot 10 seconds of raw EEG data ( fi rst 10 channels)
# ---------------------------------------------------------
print(" ๐ Plotting raw EEG ( fi rst 10s)...")
sfreq = int(raw.info["sfreq"]) # sampling frequency
start_sample = 0
stop_sample = start_sample + 10 * sfreq
raw_data, times = raw[:, start_sample:stop_sample]
ch_names = raw.ch_names
channels_to_plot = list(range(10)) # only fi rst 10 channels
offset = 40 # vertical spacing
# ---------------------------------------------------------
# 3) Apply a band-pass fi lter (1โ40 Hz)
# ---------------------------------------------------------
print(" ๐ Applying band-pass fi lter (1โ40 Hz)...")
raw_ fi ltered = raw.copy(). fi lter(l_freq=1.0, h_freq=40.0)
fi lt_data, _ = raw_ fi ltered[:, start_sample:stop_sample]
# ---------------------------------------------------------
# 4) Side-by-side comparison: Raw vs Filtered (10s, 10 channels)
# ---------------------------------------------------------
print(" ๐ Creating side-by-side comparison plots...")
fi g, axes = plt.subplots(1, 2, fi gsize=(14, 6), sharey=True)
# Raw EEG
for idx, ch in enumerate(channels_to_plot):
axes[0].plot(times, raw_data[ch] * 1e6 + idx * offset, color="black", linewidth=0.6)
axes[0].set_title("Raw EEG (10s, fi rst 10 channels)")
axes[0].set_xlabel("Time (s)")
axes[0].set_yticks(np.arange(0, len(channels_to_plot) * offset, offset))
axes[0].set_yticklabels([ch_names[ch] for ch in channels_to_plot])
axes[0].set_ylabel("Channels")
# Filtered EEG
for idx, ch in enumerate(channels_to_plot):
axes[1].plot(times, fi lt_data[ch] * 1e6 + idx * offset, color="blue", linewidth=0.6)
axes[1].set_title("Filtered EEG (10s, fi rst 10 channels)")
axes[1].set_xlabel("Time (s)")
axes[1].set_yticks(np.arange(0, len(channels_to_plot) * offset, offset))
axes[1].set_yticklabels([ch_names[ch] for ch in channels_to_plot])
plt.suptitle("Side-by-Side Comparison: Raw vs Filtered EEG", fontsize=16)
plt.tight_layout()
plt.show()
# ---------------------------------------------------------
# 5) Power Spectral Density (PSD) for Raw vs Filtered EEG
# ---------------------------------------------------------
print(" ๐ Calculating PSD for raw and fi ltered data...")
psd_raw, freqs = mne.time_frequency.psd_array_welch(
raw.get_data(picks="eeg"), sfreq=raw.info["sfreq"], fmax=60, average="mean"
)
psd_ fi lt, freqs = mne.time_frequency.psd_array_welch(
raw_ fi ltered.get_data(picks="eeg"), sfreq=raw_ fi ltered.info["sfreq"], fmax=60,
average="mean"
)
# Convert to decibels
psd_raw_db = 10 * np.log10(psd_raw.mean(axis=0))
psd_ fi lt_db = 10 * np.log10(psd_ fi lt.mean(axis=0))
# Plot PSDs
fi g, axes = plt.subplots(1, 2, fi gsize=(14, 6), sharey=True)
# Raw PSD
axes[0].plot(freqs, psd_raw_db, color="red", linewidth=1.2, label="Raw EEG")
axes[0].set_title("Raw EEG Power Spectrum")
axes[0].set_xlabel("Frequency (Hz)")
axes[0].set_ylabel("Power (dB)")
axes[0].axvspan(0.5, 4, color="purple", alpha=0.1, label="Delta")
axes[0].axvspan(4, 8, color="green", alpha=0.1, label="Theta")
axes[0].axvspan(8, 13, color="yellow", alpha=0.1, label="Alpha")
axes[0].axvspan(13, 30, color="orange", alpha=0.1, label="Beta")
axes[0].legend(loc="upper right")
axes[0].grid(True, linestyle="--", alpha=0.5)
# Filtered PSD
axes[1].plot(freqs, psd_ fi lt_db, color="blue", linewidth=1.2, label="Filtered EEG (1โ40
Hz)")
axes[1].set_title("Filtered EEG Power Spectrum")
axes[1].set_xlabel("Frequency (Hz)")
axes[1].axvspan(0.5, 4, color="purple", alpha=0.1, label="Delta")
axes[1].axvspan(4, 8, color="green", alpha=0.1, label="Theta")
axes[1].axvspan(8, 13, color="yellow", alpha=0.1, label="Alpha")
axes[1].axvspan(13, 30, color="orange", alpha=0.1, label="Beta")
axes[1].legend(loc="upper right")
axes[1].grid(True, linestyle="--", alpha=0.5)
plt.suptitle("Power Spectrum Comparison: Raw vs Filtered EEG", fontsize=16)
plt.tight_layout()
plt.show()
๐ assignment1_eeg_filtering - Zainab Samiuddin.ipynb
Jupyter Notebook๐ก Opens in Google Colab for interactive execution. Requires Google account.
๐จ Assignment 2: BrainImation
๐ ZainabS_Psych 403 Assignment 2 Write up.pdf
View Original PDFBrainImation Project Writeup โ โExpanding Galaxyโ
Concept
My project visualizes mental states through an interactive cosmic scene that changes based on
brainwave activity. The concept is inspired by the idea that a calm mind expands and glows like
a peaceful galaxy, while intense focus releases bursts of energy like supernovas. The animation
reacts in real time to EEG inputs or simulated data, transforming brain activity into a living art
piece.
The sketch was built in P5.js using BrainImationโs EEG interface. I used multiple EEG signals to
control different visual behaviors:
โ Meditation: increases star size, brightness, and shimmer, turning the galaxy calm blue.
When there is a very high/max meditation frequency, smiley faces appear on the stars to
reflect peace and happiness.
โ Attention: changes star hue to red and triggers explosion forces and glowing debris
fragments to represent bursts of cognitive energy.
โ Alpha & Beta: influence particle movement speed and direction, giving each star subtle
natural motion.
โ Theta: modulates rhythmic pulsing of star sizes, making the animation feel alive.
To make the project uniquely mine, I made several major modifications to the original
BrainImation template. I replaced the simple circular particles drawn with ellipse(p.x,
p.y, size); with a custom star-drawing function using beginShape() and vertex() to
create five-pointed stars, giving the animation a more celestial appearance. I then introduced an
explosion effect controlled by attention levels, where higher attention triggers bursts of motion
through random velocity changes, and at maximum attention, stars emit glowing debris
fragments using the createExplosion() function. To complement the calm side of the
experience, I added a smiley overlay that appears when meditation is very high, using a custom
drawSmiley() function to display eyes and a curved mouth. For the background, I coded a
drifting galaxy effect using faint ellipses and points to mimic distant stars, along with a shimmer
effect that activates when meditation is above 0.8. Finally, I tied star size to meditation values
using let size = 5 + eegData.theta * 15 + eegData.meditation * 10; ,
allowing the stars to grow and โbreatheโ as calmness increases. Together, these changes
transformed the simple EEG visualization into a dynamic, emotional galaxy that visually
represents both relaxation and focus.
I also added a nebula-style background made from drifting translucent ellipses and hundreds of
twinkling background stars to create depth. Connection lines fade in and out based on alpha and
attention values, resembling a neural network.
The final system behaves as a full particle environment smooth, reactive, and expressive of brain
state changes.
Challenges
One challenge was balancing responsiveness and aesthetics. When using EEG simulation sliders,
large changes could cause chaotic motion or visual flickering. I solved this by applying damping
and with the help of AI I was able to get a smoother transition. Another challenge was designing
a cohesive color system so the blue calm and red focus phases felt visually distinct. I also
struggled getting the background to change but with trial and error I was able to make it look like
a galaxy.
What I Learned
Through this project, I learned how to map EEG data to creative visual parameters and how to
combine neurofeedback principles with digital art. I gained deeper experience with particle
systems, color blending, and interactive motion design in P5.js. Most importantly, I learned how
to turn raw brainwave signals into expressive, meaningful visual feedback that reflects the
mindโs shifting states. I also learned the importance of trial and error by manipulating small
things to figure out what changes when I do to be able to change it in a more meaningful way.
๐ ZainabS_Psych 403 Assignment 2 Code.pdf
View Original PDF// ๐ง BrainImation: Live EEG + P5.js
// Blue Calm โ Red Explosion + Fragments + Expanding Galaxy
// - Meditation high โ blue calm + smiley faces + stars grow larger
// - Attention high โ red explosion + fragments
// - Dynamic galaxy background with nebula + twinkling stars
let particles = [];
let fragments = [];
let bgStars = [];
let time = 0;
// ๐งฉ Simulated EEG Data (remove this block when connecting a real headset)
let eegData = {
attention: 0,
meditation: 0,
alpha: 0.5,
beta: 0.5,
theta: 0.5,
connected: false
};
function simulateEEG() {
eegData.attention = noise(time * 0.4) * 1.0;
eegData.meditation = noise(time * 0.3 + 100) * 1.0;
eegData.alpha = noise(time * 0.2 + 200);
eegData.beta = noise(time * 0.25 + 300);
eegData.theta = noise(time * 0.15 + 400);
}
function setup() {
createCanvas(windowWidth, windowHeight);
colorMode(HSB, 360, 100, 100, 1);
noStroke();
// Floating EEG-reactive stars
for (let i = 0; i < 50; i++) {
particles.push({
x: random(width),
y: random(height),
vx: random(-1, 1),
vy: random(-1, 1),
shimmerOffset: random(1000)
});
}
// Background galaxy stars
for (let i = 0; i < 300; i++) {
bgStars.push({
x: random(width),
y: random(height),
brightness: random(60, 100),
size: random(0.5, 2),
twinkleSpeed: random(0.01, 0.05),
phase: random(TWO_PI)
});
}
}
function draw() {
// Simulate EEG when not connected
simulateEEG();
// โจ Galaxy backdrop
drawNebula();
drawBackgroundStars();
time += 0.01;
let explosionForce = map(eegData.attention, 0, 1, 0, 20);
for (let p of particles) {
// Movement influenced by alpha & beta
let alphaForce = eegData.alpha * 2;
let betaForce = eegData.beta * 3;
p.vx += random(-alphaForce - betaForce, alphaForce + betaForce) * 0.01;
p.vy += random(-alphaForce - betaForce, alphaForce + betaForce) * 0.01;
// ๐ฅ Explosion kick from attention
if (explosionForce > 5) {
let angle = random(TWO_PI);
p.vx += cos(angle) * explosionForce * 0.05;
p.vy += sin(angle) * explosionForce * 0.05;
}
// Damping and update
p.vx *= 0.98;
p.vy *= 0.98;
p.x += p.vx;
p.y += p.vy;
// Wrap edges
if (p.x < 0) p.x = width;
if (p.x > width) p.x = 0;
if (p.y < 0) p.y = height;
if (p.y > height) p.y = 0;
// ๐ Color transition
let meditationHue = 210; // blue calm
let attentionHue = 0; // red focus
let hueVal = lerp(meditationHue, attentionHue, eegData.attention);
let satVal = lerp(30, 90, max(eegData.meditation, eegData.attention));
let brightVal = 100;
// โจ Shimmer with meditation
let shimmer = 0;
if (eegData.meditation > 0.8) shimmer = sin(time * 5 + p.shimmerOffset) * 10;
fill(hueVal, satVal, brightVal + shimmer, 0.9);
noStroke();
// ๐ Size increases with meditation + theta
let baseSize = 5 + eegData.theta * 15;
let meditationGrowth = map(eegData.meditation, 0, 1, 1, 1.8);
let size = baseSize * meditationGrowth;
drawStar(p.x, p.y, size / 2.5, size, 5);
// ๐ Smiley faces when very calm
if (eegData.meditation > 0.9) drawSmiley(p.x, p.y, size * 0.6);
// ๐ฅ Explosion fragments when attention maxed
if (eegData.attention > 0.95 && random() < 0.1) createExplosion(p.x, p.y, hueVal);
// Connection lines fade with attention
for (let p2 of particles) {
let d = dist(p.x, p.y, p2.x, p2.y);
if (d < 80) {
let alphaLine = map(d, 0, 80, 0.5, 0) * eegData.alpha * (1 -
eegData.attention);
stroke(hueVal, satVal, 100, alphaLine);
strokeWeight(1);
line(p.x, p.y, p2.x, p2.y);
}
}
}
// ๐ Fragments from explosions
for (let i = fragments.length - 1; i >= 0; i--) {
let f = fragments[i];
f.x += f.vx;
f.y += f.vy;
f.vx *= 0.97;
f.vy *= 0.97;
f.life -= 0.02;
fill(f.hue, 80, 100, f.life);
noStroke();
ellipse(f.x, f.y, 4);
if (f.life <= 0) fragments.splice(i, 1);
}
// Info text
if (!eegData.connected) {
fill(0, 0, 100, 0.9);
textAlign(CENTER, CENTER);
textSize(20);
text("Simulating EEG Data...", width / 2, height / 2 - 10);
textSize(16);
fill(0, 0, 80, 0.7);
text("โ Meditation = calm blue expanding galaxy ๐ | โ Attention = red explosion
๐ฅ ", width / 2, height / 2 + 20);
}
}
// ๐ Nebula glow: drifting cosmic mist
function drawNebula() {
noStroke();
for (let i = 0; i < 3; i++) {
let hue = [260, 300, 200][i];
let x = width / 2 + sin(time * 0.1 + i) * width * 0.3;
let y = height / 2 + cos(time * 0.1 + i) * height * 0.3;
let size = width * 1.2;
fill(hue, 50, 40, 0.05);
ellipse(x, y, size);
}
}
// ๐ Background twinkling stars
function drawBackgroundStars() {
noStroke();
for (let s of bgStars) {
let twinkle = sin(time / 2 + s.phase) * 10;
fill(220, 20, s.brightness + twinkle, 1);
ellipse(s.x, s.y, s.size);
}
}
// โญ Draw a 5-pointed star
function drawStar(x, y, radius1, radius2, npoints) {
let angle = TWO_PI / npoints;
let halfAngle = angle / 2.0;
beginShape();
for (let a = 0; a < TWO_PI; a += angle) {
let sx = x + cos(a) * radius2;
let sy = y + sin(a) * radius2;
vertex(sx, sy);
sx = x + cos(a + halfAngle) * radius1;
sy = y + sin(a + halfAngle) * radius1;
vertex(sx, sy);
}
endShape(CLOSE);
}
// ๐ Draw a simple smiley face
function drawSmiley(x, y, s) {
push();
translate(x, y);
fill(60, 30, 100, 1);
ellipse(0, 0, s);
fill(0, 0, 0);
ellipse(-s * 0.2, -s * 0.15, s * 0.1);
ellipse(s * 0.2, -s * 0.15, s * 0.1);
noFill();
stroke(0, 0, 0);
strokeWeight(1);
arc(0, s * 0.05, s * 0.5, s * 0.3, 0, PI);
pop();
}
// ๐ฅ Create glowing debris fragments
function createExplosion(x, y, hueVal) {
for (let i = 0; i < 10; i++) {
fragments.push({
x: x,
y: y,
vx: random(-3, 3),
vy: random(-3, 3),
life: 1.0,
hue: hueVal
});
}
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
๐ฅ ZainabS_BrainImation_ Live EEG + P5.js Creative Coding - Google Chrome 2025-10-20 16-56-22 (1).mp4
๐ก Videos require Google Drive access. Open in new tab if it doesn't load.
๐ฎ ZainabS_brainimation-2025-10-19T23-27-57.js
๐ก Code is embedded in this portfolio - opens instantly in the live BrainImation editor (no internet required!)
๐ฏ Midterm Project
๐ samiuddin_midterm_part1and2_writeup - Zainab Samiuddin.pdf
View Original PDFPART 1 WRITE UP (link to video โ
My project is an EEG-based neurofeedback system that visualizes focus and calmness using a
real-time simulated brain-computer interface. The goal is to train users to reach a target brain
state with a meditation value of 0.8, representing an ideal level of calm attention. When this state
is reached, the visuals change clearly: the galaxy becomes bright and still, the stars turn white
and stop moving, and a teal halo begins to pulse smoothly. This visual stability acts as positive
feedback, signaling that the user has achieved the target mental state (image of ideal state below).
The system combines multiple EEG frequency bands to drive the visuals. Alpha and beta waves
are used to control the speed and stability of the stars. High alpha and balanced beta levels
produce still, smooth visuals that reflect calm focus. Low alpha or high beta leads to chaotic
movement and visual instability, representing stress or distraction. Theta waves affect the size
and expansion of the stars, showing deeper relaxation. The attention variable determines whether
the scene is calm or chaotic, and the meditation variable controls the color and pulse of the halo.
When attention is low, the galaxy becomes unstable. The stars turn red, move quickly, and
explode into small glowing fragments, representing an unfocused or stressed state. As attention
increases, movement slows, the stars fade to white, and the explosions stop. When attention
becomes high, the stars freeze completely, creating a still and peaceful galaxy that reflects mental
focus. The halo in the center changes from purple to teal as meditation rises, becoming opaque
and beginning to pulse when meditation reaches 0.8. Below that threshold, the halo remains faint
and still, showing the user has not yet reached the desired calmness.
The project also includes an adaptive difficulty system that provides real-time feedback on
mental control. The difficulty percentage increases as attention drops and decreases when
attention improves. When attention is low, difficulty rises to around 80โ100%, and the galaxy
becomes fast and hard to stabilize. When attention is high, difficulty drops to around 0โ20%, and
the galaxy becomes calm and easy to control. This encourages the user to maintain concentration
to keep the scene stable and visually balanced.
This system goes beyond basic BCI models that map a single brainwave to one simple visual
parameter like color or shape. Instead, it uses multiple EEG signals that interact dynamically to
shape the entire environment. The alpha, beta, and theta waves each control different visual
aspects such as motion, growth, and brightness, while attention and meditation values drive
global behavior. The result is a closed-loop feedback system that mirrors the userโs internal state
in a complex but intuitive way.
From creating this project, I learned how to build a smooth neurofeedback loop that reacts
naturally to brainwave changes. I also learned how multiple EEG features can be combined to
represent mental processes such as attention and relaxation through motion, color, and rhythm.
The system shows how brain-computer interfaces can train users to reach and maintain specific
brain states through meaningful, real-time visual feedback.
Summary of adaptive visual feedback and difficulty scaling in response to varying
meditation and attention levels during EEG-based neurofeedback.
State Meditation Attention Visuals Difficulty (%)
Low Calm +
Low Focus
Low Low Red stars
moving quickly,
frequent
explosions, halo
dim and still
80 - 100
High Calm +
Low Focus
High Low Red stars still
moving fast,
slight glow in
halo, some chaos
remains
70 - 90
Low Calm +
High Focus
Low High White stars
slowing down,
few explosions,
halo brighter
20 - 40
High Calm +
High Focus
High High White still stars,
glowing teal
halo gently
pulsing, stable
galaxy
0 - 20
PART 2 WRITE UP (link to video โ ttps://youtu.be/V5ErzVjCMmA)
My ERP experiment measures the N170 component, which is an event-related potential
associated with face perception. The N170 is a negative deflection that peaks around 170
milliseconds after a face stimulus, especially at posterior-temporal electrode sites. In this
simulation, EEG data are sampled from four virtual channels: TP9, AF7, AF8, and TP10. These
sites were chosen because the temporal electrodes (TP9 and TP10) are sensitive to facial
processing, while the frontal electrodes (AF7 and AF8) reflect early perceptual activity.
Each trial lasts 1 second (1000 milliseconds) and is recorded at 256 Hz, which produces 256
samples per epoch. The stimuli alternate between two categories: โfaceโ and โobject.โ
Even-numbered trials present a simple cartoon face drawn with ellipses and arcs, while
odd-numbered trials present a square object. This alternating pattern ensures equal representation
of both stimulus types and allows for clear comparison between the two conditions.
The epoch window extends from โ200 milliseconds to +800 milliseconds relative to the onset of
the stimulus. The first 200 milliseconds represent the pre-stimulus baseline, and the following
800 milliseconds capture the post-stimulus neural response. The code performs baseline
correction by averaging the voltage of the first 20 percent of samples (approximately the โ200
millisecond period) and subtracting this mean from all subsequent samples. This step removes
slow drifts and ensures that voltage changes reflect activity caused by the stimulus.
The program stores up to 20 recent trials per channel. Each trial is labeled as either โfaceโ or
โobject,โ and the data are averaged separately for each category. The averaged ERP waveforms
are updated continuously and displayed in real time. Red traces represent face trials, while blue
traces represent object trials. The x-axis shows time from โ200 to +800 milliseconds, with 0
marking stimulus onset. A counter is included at the ends of their corresponding epoch window.
If this system were connected to real EEG data, a larger negative deflection around 170
milliseconds would be expected for face stimuli compared to object stimuli at TP9 and TP10.
This pattern would indicate the presence of the N170 component and confirm greater neural
sensitivity to facial information (Wikipedia, 2025).
๐ฅ samiuddin_midterm_part1_video - Zainab Samiuddin.mp4
๐ก Videos require Google Drive access. Open in new tab if it doesn't load.
๐ฅ samiuddin_midterm_part2_video - Zainab Samiuddin.mp4
๐ก Videos require Google Drive access. Open in new tab if it doesn't load.
๐ samiuddin_midterm_part1 - Zainab Samiuddin.txt
๐ก Code is embedded in this portfolio - opens instantly in the live BrainImation editor (no internet required!)
๐ samiuddin_midterm_part2 - Zainab Samiuddin.txt
๐ก Code is embedded in this portfolio - opens instantly in the live BrainImation editor (no internet required!)