Error reading FreeSurfer's *.label file in BrainStorm

Hi everyone,

I performed First-Level analysis using FreeSurfer for a certain contrast. Now I am going to load the results into BrainStorm to use the activated area as seed points; however, I couldn't find any direct way to load the sig.nii.gz file as an overlay to the cortex model in BrainStorm.
I then used tksurfer to take the activated area as ROI and create a label for that. I stored it as *.label file. Then according to what I've read in the Forum, I tried to create a new Atlas and load the label file as an atlas; however, I got an error due to the different number of vertices.
I tried that for the lh of the cortex which has 145404 vertices in my *.label file. The whole cortex however has 292502 vertices according to BrainStorm. It seems that BrainStorm tries to split the lh and rh somehow which at the end the number of vertices is not compatible with the *.label file.
I also checked the other *label files which had been created automatically by FreeSurfer in its "label" directory. The number of vertices that they have (145192) is also different from what I got in my *.label file! And they work when I read them as a new atlas (and displaying the full resolution cortex model).

I'm totally confused how everything works with the veritces and how BrainStorm reads the anatomy from the FreeSurfer's folder.
Is there any direct way reading FreeSurfer's sig.nii.gz or tksconcat.nii files as an overlay in BrainStorm?
Could you please help me with that?

Kind regards
Tannaz

Hello,

I’m totally confused how everything works with the veritces and how BrainStorm reads the anatomy from the FreeSurfer’s folder.

This is documented here: http://neuroimage.usc.edu/brainstorm/Tutorials/LabelFreeSurfer#Manual_import_of_the_anatomy
And coded here: https://github.com/brainstorm-tools/brainstorm3/blob/master/toolbox/io/import_anatomy_fs.m#L279

The number of vertices that they have (145192) is also different from what I got in my *.label file!

Then I have no idea how you could read these files in Brainstorm. It’s probably easier not to go through this texture export…

Is there any direct way reading FreeSurfer’s sig.nii.gz or tksconcat.nii files as an overlay in BrainStorm?
Right-click on the anatomy folder > Import MRI. The options you’ll get are documented here:
http://neuroimage.usc.edu/brainstorm/Tutorials/Epileptogenicity#Volume_coregistration
http://neuroimage.usc.edu/brainstorm/Tutorials/Epileptogenicity#Import_the_anatomy

If the volumes you are trying to import are masks (0 and 1) or atlases (integer labels), you could also load them as surfaces or volume atlases: http://neuroimage.usc.edu/brainstorm/News#Volume_atlases

Francois

1 Like

Hello

Thank you, Francois, for your hints.
I’ve had a look into the links that you mentioned and also the relevant functions in BrainStorm.

I found out that BrainStorm is not configured properly to read and handle the FreeSurfer’s *.label files. There are two main issues in the FREESURFER LABEL part of the “import_lablel.m”:
1- It does not consider the down-sampled surfaces
2- It does not consider the left/right hemisphere. FreeSurfer indexes each hemisphere separately whereas BrainStorm concatenate them and indexes the whole surface. This causes confusion specially when the labels from rh are loaded.

I applied the following modification and now it’s working:

  • In “toolbox/anatomy/tess_concatenate.m”, keep the offsetVertices in the database by changing all “offsetVertices” to “NewTess.offsetVertices”

  • In “toolbox/db/db_template.m” for the case “loadedsurface”, I added the “offsetVertices” to the template as:

    ‘offsetVertices’, [], …`

  • In “toolbox/core/bst_memomry.m” line 204, I added:

    if isfield(surfMat,‘offsetVertices’)
    sSurf.offsetVertices = surfMat.offsetVertices;
    end

  • In “toolbox/io/import_label.m”, I modified the FREESURFER LABEL part as:

        % ==== FREESURFER LABEL ====
        case 'FS-LABEL'
            % === READ FILE ===
            % Read label file
            LabelMat = mne_read_label_file(LabelFiles{iFile});
            % Convert indices from 0-based to 1-based
            LabelMat.vertices = LabelMat.vertices + 1;           
         
            rhFlag = false;
            % Detect if right/left hemisphere
            if ~isempty(strfind(LabelFiles{iFile}, 'rh.'))
                rhFlag = true;
            elseif isempty(strfind(LabelFiles{iFile}, 'lh.'))
                Messages = [Messages, sprintf('\nNot able to detect Left/Right hemisphere! Please use lh./rh. in the label file name to specify!\n')];
                continue
            end            
            
            % Check if the full resolution is not used, load the full
            % resolution surface
            if ~contains(SurfaceFile, 'high.mat')
                fName = strsplit(SurfaceFile,'/');
                sName = fName{1};
                fName = strsplit(fName{2},'_'); 
                fullSurf = bst_memory('LoadSurface', file_short([sName '/tess_' fName{2} '_' fName{3} '_high.mat']));
                
                % handle right hemishphere
                if rhFlag
                    LabelMat.vertices = LabelMat.vertices + fullSurf.offsetVertices;
                end
                
                % Extract the coordinates of the label points from the
                % surface.
                tmpVert = fullSurf.Vertices(LabelMat.vertices,:);
            
                % Find the corresponding vertices to the label vertices in
                % the lower resolution surface.
                [~, I, J] = intersect(sSurf.Vertices, tmpVert, 'rows');      
                Jval = LabelMat.values(J);            
            else
                % handle right hemishphere
                if rhFlag
                    LabelMat.vertices = LabelMat.vertices + sSurf.offsetVertices;
                end                
                I = LabelMat.vertices;
                Jval = LabelMat.values;                
            end
                                                   
            % Check sizes
            if (max(I) > length(Vertices))
                Messages = [Messages, sprintf('%s:\nNumbers of vertices in the label file (%d) exceeds the number of vertices in the surface (%d)\n', fBase, max(LabelMat.vertices), length(Vertices))];
                continue
            end
        ....
    

Best
Tannaz

Hello,

Thanks for the suggestion.
Could you share an example to illustrate this modification? Including:

Thanks
Francois

Hello

I performed first level analysis on an fmri data. Then in order to take a RoI as a label in freesurfer, I used TkSurfer according to:
https://surfer.nmr.mgh.harvard.edu/fswiki/TkSurfer

After loading a surface (e.g., lh inflated), I selected a RoI as the following:

Right click in the graphics window to clear any marked vertices. Then make a series of left clicks on the surface to outline the label you want to draw. (This works best on the inflated surface.) Then click the "Make Closed Fill Boundary" button, which is second from the left in the group of four buttons mentioned above. It looks like a pencil drawing a closed line. This should connect the points you clicked, drawing a yellow or red line between them. (If it seems to hang for a while, press ctrl-c to cancel the line.)
Now click once in the middle of the polygon. Then click on the "Custom Fill" button, to the right of the close line tool. It looks like a paintbucket on top of a blue blob. This will bring up a dialog box with several fill options. Click the one that says "Up to and including boundaries" and then click the fill button. This should create a label which you can now save with the File command you noted before.
http://surfer.nmr.mgh.harvard.edu/faqomatic/cache/30.html

Then I selected the label by clicking on the RoI and saved it as *.label file:

File>Label>Save Selected Label

TkSurfer saves the label file in the label folder of the freesurfer's anatomy folder; however, it can be changed to any path.

In BrainStorm, after modifying the codes as I mentioned in my previous comment, I loaded the anatomy according to the BrainStorm's tutorial. Now the "offsetVertice" is stored together with the surface files into the BrainStorm's database.

In order to load my *.label file, I displayed a surface by clicking on the BrainStorm's panel.
Then in the Scout field, I created a new atlas as:

Atlas>New atlas>Empty atlas

After that, I clicked on the "Load atlas" button. In the "Import label" window, I set the format type to "FreeSurfer atlas (*.label)" and selected my label file.

Here are the screenshots of the results,

       TkSurfer (freesurfer)                               BrainStorm

Best
Tannaz

If you want us to work on this, please send us all the files needed for reproducing this in Brainstorm (the freesurfer segmentation, the .label files, and possibly other files).
Zip everything, upload it somewhere (eg. dropbox, google drive) and post the link here.

Hi Francois,
I created a label file of my ROI using TkSurfer, the procedure was similar with Tannaz's. But when I tried to load this label file as an atlas in the Brainstorm, I got the following error: Number of vertices in the label file exceeds the number of vertices in the surface. I wonder how to fix it.
I found TkSurfer used the fsaverage template, which had 163842 vertices in each hemisphere. But in Brainstorm, the number of vertices for each hemisphere was usually set 7500.
Thanks in advance

Duo

To load these FreeSurfer parcellation files properly, you have to import them separately for the left and right hemispheres, before they are merged and downsampled to create the cortex surfaces as used by Brainstorm.
Instead of using the automated pipeline "Import anatomy folder", you should load manually the FreeSurfer output as described in this tutorial:
https://neuroimage.usc.edu/brainstorm/Tutorials/LabelFreeSurfer#Manual_import_of_the_anatomy

Thank you for your answer!
I wonder how to import the label file created by freesurfer to the default anatomy in Brainstorm, for I want to project the individual result to the default anatomy to do the group analysis. I just couldn't find the MRI and surface files for the default anatomy.

I think that the easier solution might be to process the template brain you want to use with FreeSurfer recon-all, and import it with the manual instructions I pointed at before.

To export an MRI from the Brainstorm database to a .nii: right-click on it > File > Export file, and select the appropriate file format in the dialog box.