Skip to content

Getting started

One guided pass through the whole toolbox — design a run, build a protocol from it, set up and record a session, and analyze what you recorded — using the synthetic test board the whole way through, so you need no amplifier, no electrodes, and no participant. Budget about 20 minutes. By the end you will have a report open in your browser.

This assumes you've already followed Installation and can launch the app (ssvep-toolbox, from an activated ssvep environment), and that you have set up the screen as described in Graphics and display setup. It also assumes a fresh, unconfigured clone: no institution, no push destination, no pre-filled operator anywhere — that's the normal starting state, not something missing. See Site profile if you're later setting up an actual lab deployment.

The first time you launch, a "Set up this deployment?" dialog appears — this machine has no site profile yet, and the app is asking once whether it should have one. Click "Use generic (this machine has no lab/course)". That writes a generic profile so you won't be asked again, and it's exactly the state this walkthrough is written for.

The app has six tabs, in this order: Build run, Build Protocol, Set up Session, Run Session, Analyze and Compare. This walkthrough goes through the first five in order; Compare (between-condition contrast reports, which need several recordings) is not part of it. Build run and Build Protocol each hand their result to the next tab through a saved file (a run manifest, then a protocol) — nothing is silently carried over, so you'll be saving something at the end of both. Set up Session and Run Session are different: they're two views onto one shared, in-memory session state, not a third file — nothing to save there, just to lock.

1. Build run — design one continuous recording

The app opens here. A run is one continuous period of data collection — everything recorded without stopping the amplifier (see the glossary if a word here doesn't mean what it sounds like it should). This tab designs one: which frequencies flicker where on screen, how many trials, how long each one lasts. It deliberately has no hardware fields of its own — which amplifier records a run is not a property of its design, and from here on that's chosen a tab later, on Build Protocol, for every run in the protocol at once.

Design type (the dropdown at the top of the form) says what kind of run this is: SSVEP (flickering targets, the default), Resting (eyes-open/eyes-closed blocks) or FPVS (a fast stream of pictures). It decides which design page you see and which presets the Preset dropdown lists, so choose it first. Choosing another type replaces the current design (it asks first if you have unsaved edits), and loading a run manifest sets it to that run's type.

FPVS has no presets: choose it as the Design type and build the stream on its page (a base rate, an oddball every N items, and two item lists, each from a folder of your pictures or a text list, optionally in a font file; see FPVS §1). Everything below uses the SSVEP preset.

  1. From the Preset dropdown, pick "Checkerboard reversal (4-target, 30–36 Hz)" — four flicker targets, short and quick to record, good for a first pass. Click Load preset. The form fills in: four targets at four frequencies, arranged in a small grid, with a handful of trials per target (a block is one pass through all of them; the design repeats a few blocks so every target is sampled more than once). This particular preset happens to carry an old hardware hint left over from before hardware moved to Build Protocol — ignore it; Build Protocol overwrites it regardless of what any preset says.
  2. You can leave every field as the preset set it. If you're curious, Preview flicker shows you the actual pattern on screen without recording anything — useful for confirming a design looks right before you save it, and worth knowing about for later even if you skip it now.
  3. Click Save…. This validates the design and writes it as a run manifest into run-manifests/ — the file the next tab will pull in. Give it a name you'll recognize, e.g. getting-started-demo.json.

2. Build Protocol — compose the run into a protocol

A protocol is not a session — it's the template a session is derived from: which runs, in what order, and (from here on) which hardware records them. One protocol can be run by many participants; nothing about it names any one of them.

  1. Switch to the Build Protocol tab.
  2. Click Add group. A group is how the protocol orders a set of runs together (with fixed, counterbalanced, or randomized ordering — only worth choosing between once a group holds more than one run, which yours won't today). Whether a new group also gets a break-time questionnaire depends on the site profile: a deployment lists the questionnaires a new protocol starts with, and the generic profile this walkthrough uses lists none, so the group's third column reads "— no checkpoint —". That is expected here.
  3. Select the group, click Add run…, and pick the run manifest you saved in step 1.
  4. Click Set up acquisition hardware. This is the only place hardware is chosen at design time. It is set once, for the whole session: every run is recorded on it, including any run you add later, and a run carries no hardware of its own. A protocol cannot be locked for recording until its hardware is set — even though you're about to record with no hardware attached at all. Leave the defaults (an OpenBCI Cyton at its default rate, the default headset and skin prep) and confirm; you'll override this with the synthetic test board on the next tab.
  5. Type a Name for the protocol in the Session protocol box (e.g. getting-started-demo); it starts empty. Then click Validate protocol… — it has to pass before you're allowed to save, it refuses an empty name, and it re-checks after every edit. It should pass immediately here.
  6. Click Save…, into session-protocols/. Name it something you'll recognize, e.g. getting-started-demo.json.

3. Set up Session — who, and lock it

A session is one participant's visit. This tab is where you say whose visit this is (as a de-identified code, never a name — the toolbox never records one) and where you load the protocol you just built and freeze both halves of "what is about to be recorded" before anything happens.

  1. Switch to Set up Session.
  2. Subject starts blank; once you choose a Purpose it offers the next free code (sub-001 on a fresh install, filling any gap in the numbering), and you can type a different one. For this test, type sub-000 (any sub- plus digits will do). If the code you type already has data, a dialog says so: New session (ses-NNN) moves Session to that participant's next free session, Resume ses-NNN (offered when an earlier session exists) continues that session and is recorded as your choice, and Cancel switches to the next free code. Under option 0 (observer only) the code is fixed to sub-000 and cannot be edited, since nothing is saved. A bench session defaults to sub-000 too (editable), so rig tests do not use up participant numbers. A code whose data the toolbox deleted is retired and is not offered again. Session defaults to ses-001 — leave it.
  3. Operator — type your name. On a generic profile like this one it's blank free text; Create user… remembers it on this machine so it's offered again next time. (A deployment with an approved operator list turns this into a non-editable dropdown instead, and a selection is then required before you can lock or record — enforced where the recording is actually stamped, not only by the dropdown being non-editable. See Site profile. Either way this is provenance, not an access control: it records who collected the recording, not who's allowed to — the list just keeps names spelled consistently.) Whatever you type here gets stamped into the recording.
  4. Output dir defaults to this repository's BIDS/ folder — leave it. The data you're about to record lands under paths .gitignore excludes (a handful of static scaffold files elsewhere under BIDS/ are tracked on purpose; see Data governance if you're curious which), so nothing participant-shaped from this walkthrough ends up in git.
  5. Click Load protocol… and pick the protocol you saved in step 2. It resolves immediately for the subject you typed, and a checklist appears with your one run. Loading also fills the Acquisition fields (amplifier, sampling rate, headset, skin prep) from the protocol's hardware, every time you load one. You can correct them for this session; a field you change is listed under them as differing from the protocol. Lock then draws the session's headset and asks you to pick, from a list, the one that is physically on the participant (nothing is pre-selected; Cancel leaves the session unlocked), because it decides every channel label the session records. If the headset differs from the protocol's, that same dialog says so. Your correction then stays for the whole session; preparing a run never resets it. Once locked, the hardware (amplifier, sampling rate, headset, skin prep, the synthetic-amp switch) is read-only; only the connection target, Resolve connection and the acquisition note stay editable. To change hardware, unlock first. (The protocol carries the Name you typed in the Session protocol box on Build Protocol, which starts empty and which Validate insists on; the lock message quotes that name back.) A deployment whose profile lists default questionnaires would also show a break-time and an end-of-session checkpoint row here; on the generic profile there are none. If you save the protocol again (Build Protocol) after loading it, Resolve / refresh and Lock notice: they compare the file's content with what you loaded (a plain touch does not count) and say, for example, "p was saved since you loaded it: v1 → v2, 2 → 3 runs", with a Reload button. Nothing reloads by itself, and Lock refuses until you have reloaded or loaded it again, so the session never locks against a copy you did not choose. A locked session never switches. If the file was deleted or cannot be read, you are told (at Resolve and at Lock) and the copy already loaded stays usable.
  6. Under Purpose, choose Bench (no person in the chair) — it's meant for exactly this situation, a rig test with no real participant. It is stamped into everything the session writes, and it skips questionnaires: where a deployment has checkpoints they stay on the checklist, marked skipped rather than removed (so nobody looking at a finished session has to wonder whether a checkpoint was forgotten or deliberately skipped). On the generic profile there are none to skip. The other purposes are for people: Research asks for the option the participant chose for their data (option 0, where a protocol offers it, saves nothing at all), Pilot for two attestations about a team-member volunteer.
  7. Under Acquisition, tick "Test with synthetic amp (no device attached)". This is what makes the rest of this walkthrough possible without hardware — the run will record whatever BrainFlow's synthetic board produces instead of a real amplifier, exercising every other part of the path (recording, markers, BIDS conversion, decoding) faithfully.
  8. Leave Auto-push (its checkbox reads "Push recordings to the server after each run") unticked — a fresh clone has no push destination configured, so there's nowhere for it to go.
  9. Click 🔒 Lock protocol and session details. This freezes both halves of what's about to be recorded — the design and whose session it is — so neither can drift once you start. The status line then reads LOCKED: … and includes a flicker-risk grade; this preset grades elevated, which is only reported (a high grade in a session with a person present asks you to acknowledge it first; a bench session is never asked). If it refuses, the message names exactly what's still missing (most commonly a field on this tab left blank). If you unlock and lock again after changing the protocol or the purpose and data-use choices, and the session already holds recordings, it asks whether to continue that session or start the next one; changing only the hardware keeps the session and records the change (docs/PROTOCOLS.md, "Unlocking and locking again").

4. Run Session — record it

  1. Switch to Run Session. The checklist shows your run (plus any skipped checkpoint rows a deployment's profile adds); the run is already highlighted as the next pending item.
  2. Click Prep selected run. This prepares the run and expands the QA-check pane; since you're on the synthetic board it shows "Synthetic amp — impedance is not measured (no real electrodes)" — there's nothing to check with no real electrodes, so nothing here blocks you. A dialog confirms the run is prepared; dismiss it.
  3. In the live-EEG pane below, click Start recording. This is the step that actually begins presentation and recording — "Prep selected run" only got the run ready, it doesn't start it by itself.
  4. A fullscreen flicker window opens and the run plays through its trials. Esc (in the flicker window or in the app's own window, whichever has the keyboard), or the Abort button beside Start recording in the live-EEG pane (always reachable — that pane is pinned open and cannot be collapsed while a run is recording), stops it safely at any point — the same always-available abort a real session has, because photosensitivity risk doesn't go away just because the amplifier is fake. If you let it run to completion instead, it finishes on its own. On a laptop or any single screen, the stimulus window stays on top of the toolbox, so the Abort button is hidden behind it and Esc is the stop; if Esc ever does nothing, Alt+Tab to the toolbox and press Esc there; the toolbox may stay hidden behind the stimulus, press Esc anyway, and it stops the run. Before the first trial the window measures the screen's refresh for a few seconds; if it is not getting the screen (measured far below the panel's rate), the run is refused within about 10 s and the Run tab shows why, instead of starting with the wrong timing. It is refused the same way if vsync is off or the window measures faster than the panel; Troubleshooting has the graphics-driver settings that fix it.
  5. Back in the app, the checklist item flips to done once the sidecar for that run is actually written to disk — the checklist is always read from what's really there, never from "the button was clicked," so an aborted or crashed run correctly shows as pending or partial rather than a false done.

5. Analyze — produce and open a report

  1. Switch to Analyze. BIDS root is already pointed at the same BIDS/ folder you recorded into.
  2. Click Scan. Your run appears in the tree, under its subject and session.
  3. Tick it, leave Method on its default (fbcca) and Auto spatial policy checked, and click Analyze selected. This converts the recording to BIDS if that hasn't happened yet, then runs the same offline decode/metrics pipeline the command-line analysis script uses — nothing GUI-specific about the result.
  4. When it finishes, a derivatives index opens in your browser by itself — every subject/session/run analysed so far, each linking its own report. Click through to your run's report, or use Open report / Open index in the tab to get back to either one later.

Don't expect the decoding numbers in this report to mean anything — the synthetic board fabricates a signal for exercising the pipeline, not a real one, so accuracy near chance is exactly what a correct run looks like here. What you should have is a complete, real report: figures, a confusion matrix, spectral plots — the same shape a real recording produces, just built from a rehearsal.

What you just built, on disk

  • run-manifests/getting-started-demo.json — the run design.
  • session-protocols/getting-started-demo.json — the protocol.
  • BIDS/sourcedata/sub-000/ses-001/… — the raw recording (XDF).
  • BIDS/sub-000/ses-001/eeg/… — its BIDS conversion, written when you clicked Analyze selected.
  • BIDS/derivatives/ssvep-analysis/sub-000/ses-001/… — the report you opened.

Where to next

  • Glossary — the vocabulary this walkthrough used in passing, gathered in one place.
  • Protocols and sessions — the full model behind step 2 and step 3: counterbalancing, questionnaires, and what changes once real hardware and a real participant are involved.
  • Occipital 10-10 montage and Impedance check — what step 4 looks like with a real amplifier and electrodes instead of the synthetic board.
  • Troubleshooting — if any step above didn't go the way this page said it would.