.. _meg-arabic-language-localizer: ----------------------------------------------------------------------- Experiment example (Psychtoolbox): Arabic language functional localizer ----------------------------------------------------------------------- .. contents:: :local: :depth: 2 Description =========== This passive visual localizer presents four stimulus classes for identifying language- and category-responsive cortex in the KIT MEG system: - Arabic words; - pronounceable Arabic nonwords; - faces; - houses. There are 20 unique stimuli in each class (80 total). Every stimulus appears once in each of two separately randomized passes, subject to cross-pass constraints, giving **160 presentations**. The participant simply looks at the centre of the screen; there are no targets, decisions, or response-box events. This is the MEG adaptation of ``arabic_localizer_minimal`` from the SEEG experiment collection. It preserves the stimuli, passive task, timing, and constrained randomization while replacing the Arduino marker with condition-specific DataPixx pixel-mode triggers. Presentation sequence ^^^^^^^^^^^^^^^^^^^^^ .. important:: The source SEEG task requested a 60 Hz display. This MEG adaptation deliberately targets the MEG PROPixx projector's **120 Hz** refresh rate. Each 1 s stimulus and blank is nominally 120 refreshes, the 2 s baseline is nominally 240 refreshes, and a one-refresh trigger pulse is nominally 8.33 ms. Production aborts unless Psychtoolbox measures 120 +/- 0.5 Hz. After the operator presses SPACE, a run-start pulse begins a 2 s black baseline. Each trial then displays its 255x255 px source image in a centred 500x500 px destination rectangle for 1 s, followed by a black screen for 1 s. There is no fixation mark and no break between the two passes. The stimulus/blank sequence therefore lasts **320 s (5 min 20 s)**, plus the 2 s pre-run baseline. At stimulus onset, the condition's RGB value is written into the 1x1 top-left trigger rectangle and the texture is drawn before the **same** ``Screen('Flip')``. On the next 120 Hz refresh, the same texture is redrawn with a black trigger pixel. The stimulus remains continuous for 1 s while the trigger pulse is scheduled for one refresh (nominally 8.33 ms). The script checks the two flip timestamps; the electrical pulse width must still be verified on the acquisition system. .. figure:: figures-arabic-localizer/trial-timeline.png :width: 100% :alt: Timeline for the Arabic language localizer Operator start, the pre-run baseline, and one stimulus/blank cycle. .. figure:: figures-arabic-localizer/screen-trigger-map.png :width: 100% :alt: Schematic screen layout and trigger map for the Arabic language localizer Conceptual screen layout and condition trigger map. The orange trigger square is magnified and recoloured for explanation; it is exactly 1x1 px in production and its real RGB value depends on the event. The figure is reproducible from the :github-file:`MATLAB diagram generator `. Conditions and randomization ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. list-table:: :header-rows: 1 :widths: 26 18 56 * - Condition - Unique items - Composition * - Arabic word - 20 - Five items in each ``Artificial/Natural x length 4/5`` cell * - Arabic nonword - 20 - Ten length-4 and ten length-5 items * - Face - 20 - Pre-rendered face images * - House - 20 - Pre-rendered house images Each pass is randomized separately. The scheduler applies constraints both within and across the passes so that: - every selected item occurs exactly once per pass; - no condition occurs more than three times consecutively, including across the pass boundary; and - the last item of pass 1 cannot immediately repeat as the first item of pass 2. The realized sequence and MATLAB RNG states from before and after schedule generation are saved. A headless self-test generates and checks 100 schedules to protect these invariants. MEG setup ========= Trigger protocol ^^^^^^^^^^^^^^^^ The experiment uses ``single_channel`` trigger coding. RGB values below are the lab's direct 0--255 DataPixx pixel-mode values. .. list-table:: :header-rows: 1 :widths: 27 18 22 33 * - Event - KIT channel - Trigger-pixel RGB - When it occurs * - Arabic word - 224 - ``[4 0 0]`` - First refresh of the stimulus * - Arabic nonword - 225 - ``[16 0 0]`` - First refresh of the stimulus * - Face - 226 - ``[64 0 0]`` - First refresh of the stimulus * - House - 227 - ``[0 1 0]`` - First refresh of the stimulus * - Run start - 228 - ``[0 4 0]`` - First refresh of the 2 s pre-run baseline * - Trigger off - - - ``[0 0 0]`` - Every non-triggered flip The mapping is defined once in :github-file:`meg_trigger_map.m `. Channels 224--228 are the confirmed mapping for this protocol. If facility wiring or acquisition configuration changes later, update that function and this table together, then repeat the channel test before collecting data. Channels 224--227 encode the condition, not the stimulus identifier or presentation number. For a completed production run, first confirm during preprocessing that the recording contains exactly 160 ordered condition pulses and one run-start pulse on channel 228. Resolve any dropped or extra pulse before assigning stimulus identities by sequentially aligning the trigger stream to the saved schedule. For an aborted run, use the recovery trial table's ``presented`` rows as the expected partial sequence. The trigger marks the start of video scan-out rather than the instant the projected image reaches the participant. For the measured KIT/PROPixx delay and the current correction, see :doc:`Display and trigger timing `. Display and DataPixx safety ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Production mode follows the lab's pixel-mode rules: #. DataPixx is opened, set to DLP sequence program 0, and left with pixel mode **disabled** while the operator instruction page is visible. #. The top-left trigger rectangle is drawn black before pixel mode is enabled. #. Pixel mode is enabled only after the operator starts the run. #. A black trigger rectangle is drawn before every flip that is not meant to emit an event. #. The final frame is black; pixel mode is disabled before end text is drawn. #. Success, abort, and crash paths all reset priority and keyboard state, clear the trigger, disable pixel mode, close DataPixx, restore the cursor, and close Psychtoolbox. Production uses the highest-numbered display in full-screen mode, leaves Psychtoolbox synchronization tests enabled, measures the flip interval, and requires **120 +/- 0.5 Hz**. It aborts if a stimulus, blank, or trigger pulse falls outside its configured timing tolerance. No screen resolution is changed by the script. Before collection, confirm that the highest-numbered display is actually the PROPixx output and record the 500 px square's physical size and resulting visual angle. The protocol's nominal eye-to-screen viewing distance is **approximately 60 cm**; record the actual session geometry if it differs materially. Running the experiment ====================== Operator launcher ^^^^^^^^^^^^^^^^^ Open :github-file:`main.m ` in the MATLAB Editor and click **Run**. With no input arguments, the script first opens a standard MATLAB setup window; it does not initialize DataPixx or Psychtoolbox merely to show this window. Enter the subject ID, review the run preset, and click the preset-specific Start button. The subject field starts blank to prevent an accidental production run being saved as a test/default participant. **Production is selected by default.** The details panel updates immediately and explicitly shows whether DataPixx/VPixx output, Psychtoolbox ``Screen``, and the PsychHID operator keyboard are on, as well as the window type, schedule length, and timing policy. .. list-table:: Launcher presets :header-rows: 1 :widths: 20 15 30 35 * - Preset - DataPixx - Display and operator input - Intended use * - Production (default) - On - Full-screen Psychtoolbox; PsychHID keyboard - 160-presentation MEG collection at required 120 Hz * - Full rehearsal - Off - Full-screen Psychtoolbox; PsychHID keyboard - Complete rehearsal without emitting hardware triggers * - Short PTB debug - Off - Windowed Psychtoolbox; PsychHID keyboard - 16-presentation display/timing rehearsal * - Local visual preview - Off - Standard MATLAB figure; no PsychHID - 16-presentation content check without Psychtoolbox MEX files These are coupled, validated presets rather than independent hardware checkboxes. In particular, the launcher cannot combine live DataPixx output with the enlarged debug trigger patch or the non-Psychtoolbox visual backend. Cancel, the window close button, and Escape leave without creating run files. Scripted launch and validation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Calls with a nonempty subject ID bypass the launcher and remain available for automation and developer testing. Validation also remains headless. Passing only a mode with an empty subject ID opens the launcher with that preset selected: .. code-block:: matlab cd('C:\path\to\nw-main\experiments\psychtoolbox\arabic_localizer') main('P001') % production: DataPixx + 120 Hz, 160 trials main('TEST', 'nohardware') % full rehearsal without DataPixx main('TEST', 'debug') % windowed 16-presentation rehearsal main('TEST', 'visual') % local figure; no DataPixx or PTB MEX main([], 'validate') % headless asset/schedule self-test Use ``visual`` on a local computer when the aim is only to inspect the images, layout, sequence, and enlarged trigger patch. It opens a short standard MATLAB-figure preview with 16 presentations and starts automatically after 1.5 s. This path calls neither DataPixx/VPixx nor any Psychtoolbox ``Screen`` or PsychHID function, so it also works when those native MEX files cannot load. Close the preview window to stop early and save an abort snapshot. The visual preview retains the 1 s image, 1 s black interval, and 2 s pre-run baseline, but it is **not synchronized to vertical blanking** and performs no 120 Hz or flip-timing validation. To make the trigger location inspectable, it enlarges the production 1x1 pixel to 50x50 pixels and targets a 0.25 s patch rather than the production one-refresh 8.33 ms. Ordinary figure-rendering overhead can extend that visible interval. The patch uses the real, deliberately low-intensity RGB code and may look nearly black on an ordinary monitor; the window title also shows its condition, channel, and RGB value. MATLAB/operating-system display scaling can make 500 figure pixels physically different from 500 PROPixx pixels. Treat this mode only as a content and sequence check, never as a timing or MEG rehearsal. ``debug`` is the interactive version of the same short preview: SPACE starts it and ESC/Q abort it, so a working PsychHID installation is required. ``nohardware`` runs the complete full-screen rehearsal without DataPixx but also uses the PsychHID operator keyboard. Unlike ``visual``, both modes use Psychtoolbox ``Screen``; ``debug`` enlarges the trigger rectangle to 50x50 px, while ``nohardware`` otherwise retains production display settings. Never use preview or no-hardware output as MEG data. Windows Psychtoolbox dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Before a Psychtoolbox-backed preset initializes ``Screen`` or PsychHID, the experiment calls ``PsychStartup`` explicitly. This exposes the installed 64-bit MSVC GStreamer runtime and Psychtoolbox's bundled 64-bit ``libusb-1.0.dll`` to the current MATLAB process even when the user's global MATLAB ``startup.m`` omitted the normal Psychtoolbox startup hook. It does not install missing dependencies: Windows still requires a complete 64-bit MSVC GStreamer 1.22 or newer installation. ``visual`` does not call ``PsychStartup`` or load any Psychtoolbox MEX file. Before a production session: #. Wake the PROPixx and confirm the production display is running at 120 Hz. #. Run :github-file:`test_all_meg_channels_triggers.m ` and verify channels 224--228 at acquisition when the setup or wiring has changed. #. Run ``main([], 'validate')`` after changing stimuli, the manifest, trigger mapping, or scheduler. #. Start KIT acquisition before leaving the operator instruction page. #. Confirm the participant is ready, then press SPACE on the stimulus computer. In the interactive modes, SPACE is an **operator keyboard** action and ESC/Q aborts while saving recoverable partial data; ``visual`` mode has no keyboard handling and auto-starts. Participant response boxes are never initialized or polled because this is intentionally a passive task. Protocol decisions before collection ==================================== .. warning:: **Protocol decisions remain open.** Resolve stimulus provenance/licensing, Arabic proficiency criteria, the 500 px stimulus's measured physical size/visual angle, and planned contrasts before participant collection. This implementation deliberately preserves the minimal SEEG task rather than adding an attention check or fixation mark. Consequently, it provides no behavioral measure of attention and no fixation-quality measure. The face and house PNG files also contain circular alpha masks, but the original SEEG code ignored their alpha channel. The confirmed MEG protocol preserves that SEEG behavior: alpha is discarded and the stored RGB image is presented as an opaque square on the black background. Document the stimuli's provenance, citation, and licence together with the participant inclusion criteria for Arabic literacy/proficiency. Predefine the intended contrasts as well: the word/nonword images differ substantially from the face/house images in low-level visual properties, so a broad language versus object contrast is not automatically specific to language. Saved data ========== Runtime output is written below the experiment's Git-ignored ``data/`` and ``logs/`` directories. An initialized checkpoint is written before the hardware run, while the unqualified final files are written after the stimulus sequence and timing checks complete. ``visual`` writes the same diagnostic file set and console transcript, but its saved ``display_info.backend`` is ``matlab_figure_preview``, every ``hardware_emitted`` value is false, and its timing-valid flag is false. These files help audit the local content check; they are not MEG acquisition data. Each timestamped run writes: - ``*_beh.mat``: complete snapshot containing configuration, participant/run metadata, manifest validation, trigger map, RNG states, display and hardware information, and the trial schedule; - ``*_trials.csv``: one row per planned presentation with identity, condition, trigger mapping, planned and actual VBL times, flip diagnostics, durations, timing checks, and run status. In ``visual`` mode the figure-clock onsets and durations are diagnostic, while Psychtoolbox-specific VBL/flip fields remain unavailable; - ``*_events.tsv``: a trigger-alignment staging table using BIDS/MNE-BIDS column names. Its first columns are ``onset``, ``duration``, ``trial_type``, ``value``, and ``sample``. It also retains ``channel``, ``stim_file``, ``stimulus_id``, ``presentation_index``, ``planned_duration``, and ``hardware_emitted``. ``value`` equals the KIT channel and supplies the integer MNE event ID. The numeric ``channel`` is a lab-specific KIT field used by the trigger sanity checker. ``onset`` and ``sample`` are written as ``n/a`` because only preprocessing can align the recorded trigger stream to the raw MEG acquisition. The file is not validator-ready raw BIDS because BIDS requires numeric ``onset`` values. MNE-BIDS drops rows with a missing onset, so it produces no usable annotations until preprocessing fills those onsets. Stimulus ``duration`` records the measured display interval, or ``n/a`` if an abort or crash interrupted the interval before it could be measured; run-start ``duration`` is zero. The custom ``planned_duration`` retains the configured 1 s target, while detailed VBL timing remains in ``*_trials.csv``; - ``*_events.json``: the accompanying data dictionary describing every standard and experiment-specific event column. Its top-level ``"TriggerMode": "single_channel"`` declaration is required by the lab's KIT trigger-count and event-computation pipelines; and - ``*_desc-matlabconsole_log.txt``: a unique timestamp-and-token MATLAB console transcript for every accepted run attempt, starting before schedule generation. The file is pre-created to prevent accidental appending, and a cleanup guard closes and flushes the diary on success, operator abort, or crash. Configuration/manifest validation and the subject prompt occur before a run is accepted, so failures or cancellation during that preflight stage do not create a run log. BIDS does not define a separate ``offset`` event column: offset is represented by ``onset + duration``. Likewise, the middle column of an MNE three-column event array is the preceding trigger-channel value, not a BIDS TSV column. The relevant BIDS/MNE-BIDS names are therefore ``onset``, ``duration``, ``trial_type``, ``value``, and ``sample``. This repository's converter targets BIDS 1.8.0; see the `BIDS 1.8 task-events specification `_ and `MNE-BIDS event-file behavior `_. These timestamped runtime artifacts are intentionally not final BIDS files: their mode, timestamp, and uniqueness token prevent one attempt from overwriting another. Preprocessing must align triggers, fill numeric acquisition-relative ``onset`` (and ``sample`` for explicit sample alignment), and rename/move the TSV and JSON so their entities match the corresponding raw MEG file. It must also copy the versioned ``arabic/``, ``faces/``, and ``houses/`` asset directories into ``/stimuli/``, preserving their relative paths, so each ``stim_file`` value resolves from the dataset-level ``stimuli`` directory. The lab's scoped event resolver accepts both standard ``.tsv`` and legacy ``.csv`` tables. The script writes ``*_desc-initialized_*`` before presentation. Psychtoolbox-backed runs update a separate autosave every ten trials and at the pass boundary; the short ``visual`` preview writes initialized and final files without intermediate autosaves. An operator abort writes ``*_desc-abort_*`` files; another error writes ``*_desc-crash_*`` files with the full MATLAB error report. In partial trial CSV files, use ``presented`` and ``status`` to distinguish completed rows from the remainder of the planned schedule. Code access =========== - :github-file:`Experiment directory ` - :github-file:`Main experiment ` - :github-file:`Configuration ` - :github-file:`Constrained scheduler ` - :github-file:`BIDS-named event staging exporter ` - :github-file:`Manifest validator ` - :github-file:`Headless self-test ` Verification ============ The validator checks all 80 manifest rows, condition balance, word/nonword subcells, unique identifiers and asset paths, file existence, 255x255 image dimensions, and the white-on-black Arabic render. This does not replace a scanner-room dry run: verify the displayed size, all five trigger channels, and the scheduled one-refresh pulse widths on the real MEG hardware before the first participant.