How to import a weight file (generated by freesurfer) into brainstorm?

Hi, I want to import a weight file (xxx-lh.w) into brainstorm to show the areas. It seems like brainstorm do not support import w file direclty, so I convert it into .mat file, but when I try to import the .mat file (after import mri file, and the surface file, right click the surface and choose import texture), it said "the number of vertices in the surface(163842) and the source map (206182) do not match". I double checked the .mat which is 163842 vertices, so which step is wrong, can anyone provide some detail steps about how to import the w file?
I can only import surface files and label files.

Any variable in the .mat file you are trying to import that would have a dimension of 206182 by any chance?

I have no idea, I thought the souce map (206182) is some default file in the brainstorm?
I am trying another way now, I read the .mat file in the matlab window (eg: vol = load('test-r-rh.w', '-mat'); ), and then
in the brainstorm window, select import from Matlab, I can find the vol variable, but it said this structure cannot be imported. However if I convert it into 163842x1 as full_vtx_value, it cannot be found in the brainstorm window. It seems like brainstorm can only insert variable with data class struct? But in my case, i have a struct class vol and the struct with field is 163842x1 double and it cannot be imported. So which kind of structure I should do to import it?

The import structure feature only supports a limited number of file formats, listed in the pulldown menu of the import GUI. I am not sure what you are trying to visualize: is this a series of values that you wish to map onto the cortical surface? If yes, the best option is to import them as a source file.
One hack I sometimes use is to first compute a EEG/MEG source file by following the procedures described in the tutorial. Once the source file is created, you can duplicate it and replace the values in the ImageGridAmp variable of the structure stored in this Matlab file (right click over the source fil: File>Import from Matlab. ImageGridAmp is a vector of length n_sources, which is the number of vertices of the surface.

Hi @travis,

The 206182 value information was obtained from the file that selected to import.

When using the menu Import texture with the 'FreeSurfer maps (*.*)' file format a file with the curv file is expected.

Thus that option does not work with weighted (aka vertex-wise) files .w as they do not contain values for all the vertices, they are a pair of variables indicated the vertexNumbers and their vertexValues. As such, while it may have 163842 elements, it can make reference to vertices with number larger than that.

I'm curious how you got the first error with the .w file, as this format is not supported in Brainstorm. In fact, when I try to import a .w file it gives an error at reading it.

Adding support for Freesurfer .w files in Brainstorm should simple.
Could you help us with these questions?


I am doing similar; I'm loading in .mgh surfaces from freesurfer. I modified import_sources.m to run the function "load_mgh.m". With some extra database management (see below) I'm able to successfully ilmport all my surface files.

Maybe the "import texture" can support .mgh?

function SurfFile = BST_Load_FS_Surface(SubjectName, surf_type, path_FS)
% import_sources.m needs to be altered to include 'FS_MGH' type
% See: import_anatomy_fs line 573
% 2023-05-10 Foldes: Created

sProtocolSubjects = bst_get('ProtocolSubjects');
iSubject = find(strcmpi(SubjectName, {sProtocolSubjects.Subject.Name}));

% Create a condition
iStudy = db_add_condition(iSubject, surf_type);

SurfFile_LH = file_find(path_FS, ['lh.' surf_type '.mgh'], 2);
SurfFile_RH = file_find(path_FS, ['rh.' surf_type '.mgh'], 2);
CortexHiFile = [SubjectName '/tess_cortex_pial_high.mat'];

% Import cortical thickness
SurfFile = import_sources(iStudy, CortexHiFile, SurfFile_LH, SurfFile_RH, 'FS_MGH');

Thanks for your reply, I did not import the .w file directly, I will give you 4 files, the 2 sample .w files I have (i-lh.w and r-rh.w), and the .m file I used to convert .w to .mat, and an output .mat file. Let me know if you need any other help. (1.6 MB)

On the other hand, you said the 206182 value information was obtained from the file that selected to import, but I tried to open that file in matlab, it shows that I only have a variable full_vtx_value which contain a 163842*1 double, so where it gets 206182?

Thanks for your reply. I tried to use mri_surf2surf function to convert my .w files to .mgh/.mgz files, and both cannot be imported as texture in brainstorm.
I can import the surface files from freesurfer, such rh.inflated_avg, lh.inflated_avg... in freesurfer7.2.
My problem is I cannot import .w file which is generated by freesurfer using mri_surf2surf function.

It seems to be the result of reading a .w file as .curv, i.e., garbage.
With the files you shared I "get" the error but with "2 vertices":

** Error: The number of vertices in the surface (163842) and the source map (2) do not match.

In the good news: FreeSurfer .w files are now supported in Brainstorm:

When using Import texture, select both the lh and rh file

1 Like

Thanks for your updates, and I tried the new version but still not working. Perhaps, I should give you my detailed steps?

  1. Import the MRI file (T1.mgz)
  2. Import the surface files eg: lh.inflated_avg, rh.inlfated_avg
  3. Select both lh and rh surface files and merge them to build cortex_327684V
  4. Import texture and select both rh and lh .weight files.

And then It said "Left and right hemisphere files must be provided in pairs" and
"The number of vertices in the surface (327684) and the source map (163842)".

I can understand the second error message, which is correct because I combine the 2 surfaces to form a 327684 cortex, so the vertices do not match, but I tried the 'less vertices function' (make the cortex from 327684 to 163842) or set the lh.inflated_avg surface as cortex and import the weight files, it said "File could not be read xxxx/xxxx/fsavg_lh.w"

What I am trying to do is simple, read a surface file, and then read a .w file to show the vertices in the surface. The result should be like the first image I have shown on this topic.

PS: In your last post, you mentioned we should select both the lh and rh files, why is that (is it compulsory?)? What if I only want to show an lh surface and import an lh weight file?

Also, the weight files I shared with you were generated by freesurfer and it is working when I use it, (the first image on the left side was created after reading the w file in tksurfer).

Those are the surface files I use

The idea with Import texture is to import a file (either .curv or .w) that contains values for all the surface.

In the case of left and hemisphere files, they are expected by pairs, so there are values for all the cortex surface. What it is going with these errors is that the .w file (fsavg_lh.w) contains information only for the left hemisphere, thus Brainstorm indicates that the pair (its right file is missing) must be provided: "Left and right hemisphere files must be provided in pairs". Then it tries to apply it to the surface, but it only has data for the left hemisphere, thus the error: "The number of vertices in the surface (327684) and the source map (163842)".

This is incorrect. By reducing the vertices in the cortex, they do not correspond any more to the other files. As the indices of the weight files are matched with the full resolution cortex (327684 vertices)

Yes, they need to be provided in pairs (left and right .w files), they will be combined to have a weighted array to apply on the whole selected surface. Files are recognized as pairs if-and-only-if the only difference in their names is lh and rh.

In case you really want to use only one hemisphere weight file, you can make a dummy file for the other hemisphere, the dummy file will not have weights at all. Then select both in Import texture.

This code shows how to create a dummy wfile without weights.

% Full path of the dummy FreeSurfer wfile
fileFullPath = '~/Desktop/dummy_rh.w';
% Create binary big-endian file
fid = fopen(fileFullPath, 'wb', 'b');
% Int16 for Latency
fwrite(fid, 0, 'int16');
% Count of vertex-value pairs to follow (3-bytes)
fwrite(fid, [0, 0, 0], 'uchar') ;
% Close file

There is some issue with the shared files, I don't have access to them

Hi, sorry for the late reply. I tried some other w files, and it works, but there are other problems, why is the previous data not working? I tried 4 different data sets (S1 to S4), but only S1 and S2 were successfully imported. And I tried to see the difference between them in structure in Matlab using readw_file.m, and it shows that basically, it has no difference. S1 and S4 both contain 163842*1 double vertices but S4 cannot be imported.

Here comes an interesting part(or I should say confusing part), The way I import the .w files is the same, but when the Brainstorm formed a texture file it contains a different size of ImageGrideAmp (I found this in file, view file content), below is the summary.
Sample Data
ImageGridAmp: [327684x2 double]

ImageGridAmp: [327684x2 double]

ImageGridAmp: [163842x2 double]

ImageGridAmp: [163842x2 double]

Why is that? I have no idea.
Below is the link to a folder containing all the files I use for testing (This time should work), the surface files are also included.

Hi, I know why it cannot import S3-S4, it was my mistake, I select the wrong w file (I should select the w file of lh with the real number, not the Imaginary numbers), and it can be imported now. Thanks for your help.

Glad to hear it's working now! :smiley:

Thanks for the help, can I ask one more question? After importing the rh and lh w files to form a texture file, I tried to see the structure and the data by exporting the texture file in Matlab. And then I found that the first column contains the vertices values from w files. From 1 to 163842 are getting from the lh file, while 163843 to 327684 vertices values are from the rh file. I can understand that it is combining two arrays. And the second column is just the same as the first one. So what is the usage for the second column? Why not just form a ‘327684 x 1 double’ data instead of forming a ‘3276842 x 2 double’ data( since the first column is good enough)? I tried to understand it by reading the source code from GitHub but did not find the answer.

Nice question! The usage has to do more with how data is expected in Brainstorm, the values are copied so the can represent a time (slice) window, which should be of at least two elements (columns). For example, if you added N pairs of lh/rh w-files, the N textures will be available as one texture file, with an array of [nVertices, nLhRhPairs], and you can change the visualization with the Next sample [>>] button.

Ok, I understand now, thx :laughing:

1 Like