import React, { useState, useEffect } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import { Box, Paper, Typography, Button, Stack, Collapse } from "@mui/material"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; const DocLink = ({ href, children }) => ( ); const StepNumber = ({ number }) => ( {number} ); const CITATION = `@software{open_eeg_bench, title = {Open EEG Bench: Benchmarking parameter-efficient fine-tuning of EEG foundation models}, author = {Guetschel, Pierre and Aristimunha, Bruno and Truong, Dung and Kokate, Kuntal and Moreau, Thomas and Tangermann, Michael and Delorme, Arnaud}, year = {2026}, url = {https://github.com/braindecode/OpenEEGBench}, doi = {10.5281/zenodo.19698863} } @inproceedings{guetschel2026openeegbench, title = {Toward {OpenEEG-Bench}: A Live Community-Driven Benchmark for {EEG} Foundation Models}, author = {Guetschel, Pierre and Aristimunha, Bruno and Truong, Dung and Kokate, Kuntal and Tangermann, Michael and Delorme, Arnaud}, booktitle = {Proceedings of the 34th European Signal Processing Conference (EUSIPCO 2026)}, year = {2026}, address = {Bruges, Belgium}, month = aug, pages = {1--5}, organization = {EURASIP} }`; const TUTORIAL_STEPS = [ { title: "Install & implement the model contract", content: ( Install the benchmark with{" "} pip install open-eeg-bench. Your model must accept input of shape (batch, n_chans, n_times) and return{" "} (batch, n_outputs), exposing a named classification head module (default final_layer). theme.palette.mode === "dark" ? "grey.50" : "grey.900", borderRadius: 1, "& pre": { m: 0, p: 0, fontFamily: "monospace", fontSize: "0.875rem", color: (theme) => theme.palette.mode === "dark" ? "grey.900" : "grey.50", }, }} >
            {`import open_eeg_bench as oeb

# Your model: (batch, n_chans, n_times) -> (batch, n_outputs)
results = oeb.benchmark(
    model_cls="my_package.MyModel",
    checkpoint_url="https://my-weights.pth",
    head_module_name="final_layer",
)
print(results)  # pd.DataFrame`}
          
OpenEEGBench repository
), }, { title: "Publish your weights", content: ( Push your checkpoint to a public HuggingFace Hub repo{" "} (with a license tag) or host it at a direct{" "} checkpoint URL. The arena loads the weights to run the evaluation. Model uploading guide ), }, { title: "Sign in & fill the form", content: ( Provide your model class import path, the{" "} weights source, a{" "} fine-tuning strategy and{" "} classification head, the{" "} datasets (default: all 10), and the number of{" "} seeds. ), }, { title: "Submit & wait", content: ( The arena queues your model and a worker runs{" "} oeb.benchmark() to post official scores. Limit:{" "} 5 submissions per month. ), }, { title: "Privacy & help", content: ( Your contact email is stored privately. For help or to request removal of a submission, open an issue. OpenEEGBench issues ), }, ]; function SubmissionGuide() { const location = useLocation(); const navigate = useNavigate(); // Initialize state directly with URL value const initialExpanded = !new URLSearchParams(location.search).get("guide"); const [expanded, setExpanded] = useState(initialExpanded); // Sync expanded state with URL changes after initial render useEffect(() => { const guideOpen = !new URLSearchParams(location.search).get("guide"); if (guideOpen !== expanded) { setExpanded(guideOpen); } }, [location.search, expanded]); const handleAccordionChange = () => { const newExpanded = !expanded; setExpanded(newExpanded); const params = new URLSearchParams(location.search); if (newExpanded) { params.delete("guide"); } else { params.set("guide", "closed"); } navigate({ search: params.toString() }, { replace: true }); }; return ( theme.palette.mode === "dark" ? "grey.800" : "grey.200", overflow: "hidden", }} > theme.palette.mode === "dark" ? "grey.900" : "grey.50", borderBottom: "1px solid", borderColor: (theme) => expanded ? theme.palette.mode === "dark" ? "grey.800" : "grey.200" : "transparent", }} > Submission Guide {TUTORIAL_STEPS.map((step, index) => ( {step.title} {step.content} {index < TUTORIAL_STEPS.length - 1 && ( theme.palette.mode === "dark" ? "grey.800" : "grey.100", }} /> )} ))} theme.palette.mode === "dark" ? "grey.800" : "grey.100", }} > Citation If you use OpenEEGBench in your research, please cite it. theme.palette.mode === "dark" ? "grey.50" : "grey.900", borderRadius: 1, overflowX: "auto", "& pre": { m: 0, p: 0, fontFamily: "monospace", fontSize: "0.8125rem", whiteSpace: "pre", color: (theme) => theme.palette.mode === "dark" ? "grey.900" : "grey.50", }, }} >
{CITATION}
); } export default SubmissionGuide;