Projecting Electrodes onto Surface via Script Problem

Hello,

I am having trouble with my script. I am compute the head model fine, but upon attempting to project the electrodes onto the scalp, nothing occurs (the green dots in the space, I believe).

When I go into Channels→MRI registration→Edit→Project electrodes onto surface, it works correctly. However, using a script does not work. I have searched and found the following threads, but they did not work:

From the process1 tab, this is the function that I ran:

% Script generated by Brainstorm (28-Jul-2025)

% Input files
sFiles = {...
    'EEGonly_001/@rawClinical_epoch_0_1-S1/data_0raw_Clinical_epoch_0_1-S1.mat'};

% Start a new report
bst_report('Start', sFiles);

% Process: Project electrodes on scalp
sFiles = bst_process('CallProcess', 'process_channel_project', sFiles, [], ...
    'sensortypes', 'EEG');

% Save and display report
ReportFile = bst_report('Save', sFiles);
bst_report('Open', ReportFile);
% bst_report('Export', ReportFile, ExportDir);
% bst_report('Email', ReportFile, username, to, subject, isFullReport);

% Delete temporary files
% gui_brainstorm('EmptyTempFolder');

Running this generated script from the process1 tab did not work. My custom script also did not work:

function headFiles = esiHeadModel(subjectStruct,subNum,epFileMatrix,adaptive)

    subjectID_input = subjectStruct.subjectID(subNum);
    disp(string(datetime('now')) + ": Creating Head Model @" + string(subjectID_input))
    
    % store names for epochs so brainstorm knows where to look. using a for
    % loop makes it so that we can add more epochs down the line if desired
    for i=1:length(epFileMatrix)
        headFileTemp = epFileMatrix(i).FileName;
        headFileNames{i} = char(headFileTemp);
    end
   
    % Process: Compute head model
    headFiles = bst_process('CallProcess', 'process_headmodel', headFileNames, [], ...
        'Comment',     '', ...
        'sourcespace', 1, ...  % Cortex surface
        'meg',         4, ...  % OpenMEEG BEM
        'eeg',         3, ...  % OpenMEEG BEM
        'ecog',        2, ...  % OpenMEEG BEM
        'seeg',        2, ...  % OpenMEEG BEM
        'openmeeg',    struct(...
             'BemFiles',     {{}}, ...
             'BemNames',     {{'Scalp', 'Skull', 'Brain'}}, ...
             'BemCond',      [1, 0.0125, 1], ...
             'BemSelect',    [1, 1, 1], ...
             'isAdjoint',    0, ...
             'isAdaptative', adaptive, ...
             'isSplit',      0, ...
             'SplitLength',  4000), ...
        'channelfile', '');
    
    bst_process('CallProcess', 'process_channel_project', headFiles, []);
end

Does anyone have any idea what could be going on? Thank you

The green dots are the head points, that they are not projected on the scalp.
The most similar operation is to Refine the registration using these head points, which would would compute the translation that improves the fit between the scalp surface and these points:

Hi @willbanks,

We have tested the process, and it is properly working.
It seems the issue comes from your side. Here some things you can test and try:

  1. Did you notice any error message in the Report that is generated after running the process?

  2. Did you check your channel file, to verify that the electrodes are in fact Type EEG, as in the way the process is called only EEG electrodes are projected on the scalp.

  3. Can you share screenshots of the electrodes (right-click on Channel file, Display sensors > EEG (Head)) for before and after the process?

In your script, you are trying to project the electrodes on the scalp after computing the head model. This is incorrect. The head model is computed using the electrode locations, so if you change these locations after computing the head model, the head model is not longer valid, it makes reference to the old locations.

To make you pipeline simpler, and less prone to errors. Project the electrodes in the raw file, so the projected positions are the ones that are used when epochs are imported. If you project the electrodes for each imported epoch, there is the risk that you will miss projecting for an epoch, so the channel locations will differ for different epochs.

i believe i got it now, thank you