Imports BIDS folder

Hello,

I am currently trying to replicate the following article in Brainstorm: https://www.sciencedirect.com/science/article/pii/S0165027024001389

Nicely, the author put the data in BIDS online: OSF | Localizing hidden Interictal Epileptic Discharges with simultaneous intracerebral and scalp high-density EEG recordings

I was wondering if you could help me import it in brainstorm.

1/ I noticed that there was no dataset_description.json file needed by brainstorm so I created one from an other study:

{
  "Name": "",
  "BIDSVersion": "1.7.0",
  "DatasetType": "raw",
  "License": "",
  "Authors": [
    "",
    "",
    ""
  ],
  "Acknowledgements": "",
  "HowToAcknowledge": "",
  "Funding": [
    "",
    "",
    ""
  ],
  "EthicsApprovals": [""],
  "ReferencesAndLinks": [
    "",
    "",
    ""
  ],
  "DatasetDOI": "doi:"
}

2/ The EEG data are in derivative while anat is in the root folder
Brainstorm doesn't import the data from derivatives. So I copied the anat folder from the root to the derivatives

3/ Issue with the channel

I get the following error:

The subject folder looks like this:

So the file contains sub-01_coordsystem.json:

{
    "EEGCoordinateSystem": "T1w",
    "EEGCoordinateUnits": "mm",
    "AnatomicalLandmarkCoordinates": {
        "LPA": [
            -71.0715,
            5.01604,
            -19.5648
        ],
        "NAS": [
            25.1881,
            89.3942,
            14.9043
        ],
        "RPA": [
            78.7842,
            -7.95071,
            -16.9084
        ]
    },
    "AnatomicalLandmarkCoordinateSystem": "T1w",
    "IntendedFor": "/sub-01/anat/sub-01_T1.nii",
    "AnatomicalLandmarkCoordinateUnits": "mm"
}

Edit: I tried to remove the line IntendedFor but then it doesn't import anything. or to change it to "/sub-01/anat/sub-01_T1w.nii" or sub-01_T1w.nii without success

I think we manage to replicate the article that it can be a nice tutorial for Brainstorm. I'd be happy to help writting it if you want :slight_smile: (note: actually; it seems they are not sharing the entire SEEG recording but only the data of one contact so less interesting ... still interesting to see if we can import it :))

Edouard

Hi @edelaire, thanks for testing this.
The tutorial would be a nice addition, please DM to set the plan.

hello,

So i have been able to import the data in Brainstorm using the following script :
The script is using GitHub - kwikteam/npy-matlab: Experimental code to read/write NumPy .NPY files in MATLAB to load the npy data.



% Script to import data from coreg-spikes

bids_data_folder = {'/Users/edelaire1/Downloads/coreg-spikes'};
selectsubj = {'sub-01','sub-02','sub-03','sub-04','sub-05','sub-06','sub-07','sub-08'};

% Start a new report
bst_report('Start', []);

% Process: Import BIDS dataset
 sFiles = bst_process('CallProcess', 'process_import_bids', [], [], ...
     'bidsdir',       {bids_data_folder(1), 'BIDS'}, ...
     'selectsubj',    strjoin(selectsubj,','), ...
     'nvertices',     15000, ...
     'mni',           'maff8', ...  % Linear
     'anatregister',  'spm12', ...  % SPM12
     'groupsessions', 1, ...
     'channelalign',  1);


for iSubject = 1:length(selectsubj)
    fprintf('Importing data of subject %s \n',selectsubj{iSubject})
    
    data_folder = fullfile("derivatives/","epochs/",selectsubj{iSubject});
    
    iEEG_folder = fullfile(data_folder,"ieeg");
    EEG_folder  = fullfile(data_folder,"eeg");

    json_EEG = bst_jsondecode(fullfile(EEG_folder,sprintf("%s_coordsystem.json",selectsubj{iSubject} ) ));
    sFid = process_import_bids('GetFiducials',json_EEG, 'mm');


    electrodes_file = fullfile(EEG_folder, sprintf('%s_electrodes.tsv',selectsubj{iSubject} ));


    % Create new study
    iStudy = db_add_condition(selectsubj{iSubject}, 'EEG');
    sStudy = bst_get('Study', iStudy);

    % Load Channels
    
    channel_info = in_tsv(fullfile(EEG_folder, sprintf('%s_task-rest_run-01_channels.tsv', selectsubj{iSubject})));
    electrodes_info = in_tsv(fullfile(EEG_folder, sprintf('%s_electrodes.tsv', selectsubj{iSubject})));

    nChan = size(channel_info,1);
    factor = 0.001;

    ChannelMat = db_template('channelmat');
    ChannelMat.Comment = 'BIDS channels';
    ChannelMat.Channel = repmat(db_template('channeldesc'), [1, nChan+1]);
    [ChannelMat.Channel.Loc] = deal([0;0;0]);

    ChannelMat.SCS.NAS = sFid.NAS;
    ChannelMat.SCS.LPA = sFid.LPA;
    ChannelMat.SCS.RPA = sFid.RPA;

    for iChan = 1:nChan
        % Name
        ChannelMat.Channel(iChan).Name = electrodes_info{iChan,1};

        % Type
        ChannelMat.Channel(iChan).Type = 'EEG';

        % Loc
        ChannelMat.Channel(iChan).Loc = [str2num(electrodes_info{iChan,2}); str2num(electrodes_info{iChan,3}); str2num(electrodes_info{iChan,4})] .* factor;
    
        % other
        ChannelMat.Channel(iChan).Orient  = [];
        ChannelMat.Channel(iChan).Weight  = 1;
        ChannelMat.Channel(iChan).Comment = [];

    end

    electrodes_info_SEEG = in_tsv(fullfile(iEEG_folder, sprintf('%s_space-T1w_electrodes.tsv', selectsubj{iSubject})));
    
    ChannelMat.Channel(end).Name = electrodes_info_SEEG{1,1};
    ChannelMat.Channel(end).Type = 'SEEG';
    ChannelMat.Channel(end).Loc = [str2num(electrodes_info_SEEG{1,2}); str2num(electrodes_info_SEEG{1,3}); str2num(electrodes_info_SEEG{1,4})] .* factor;

    % other
    ChannelMat.Channel(end).Orient  = [];
    ChannelMat.Channel(end).Weight  = 1;
    ChannelMat.Channel(end).Comment = [];

    [tmp, iChannelStudy] = bst_get('ChannelForStudy', iStudy);
    db_set_channel(iChannelStudy, ChannelMat, 2, 2);


    % Load data :
    data = readNPY( fullfile(EEG_folder, sprintf('%s_task-rest_run-01_epochs.npy', selectsubj{iSubject})));
    dataSEEG = readNPY( fullfile(iEEG_folder, sprintf('%s_task-rest_run-01_epochs.npy', selectsubj{iSubject})));

    ChannelFlag = ones(nChan+1,1);
    ChannelFlag( strcmp(channel_info(:,7), 'bad')) = -1;

    epochs_info = in_tsv(fullfile(EEG_folder, sprintf('%s_task-rest_run-01_epochs.tsv', selectsubj{iSubject})));

    timeVector = linspace(-str2double(epochs_info{1,2}),str2double(epochs_info{1,2}),  size(data,3));

    for iEpoch = 1:size(data,1)
        
        sDataOut = db_template('data');
        tmp = zeros(nChan+1, length(timeVector));
        tmp(1:size(data,2),:)  = squeeze(data(iEpoch,:,:));
        tmp(end,:)  = squeeze(dataSEEG(iEpoch,:,:));


        sDataOut.F            = tmp;
        sDataOut.Comment      = sprintf('Epooch %d', iEpoch);
        sDataOut.ChannelFlag  = ChannelFlag; 
        sDataOut.Time         = timeVector;
        sDataOut.DataType     = 'recordings'; 
        sDataOut.nAvg         = 1;

        OutputFile = bst_process('GetNewFilename', bst_fileparts(sStudy.FileName), 'data_spikes');
        sDataOut.FileName = file_short(OutputFile);
        bst_save(OutputFile, sDataOut, 'v7');
        % Register in database
        db_add_data(iStudy, OutputFile, sDataOut);
    end

end

The only issue is with the optodes coordinates as it seems brainstorm is not doing the co-registration as expected:

If I use the GUI to then import the coordinate; it is working (add electrodes position > EEG BIDS electrodes.tsv)