gllmflndn / gifti

MATLAB/Octave GIfTI Library
https://www.gllmflndn.com/software/matlab/gifti/
MIT License
25 stars 12 forks source link

Enforcing ArrayIndexingOrder on save causes malformed files #5

Closed markusadamek closed 4 years ago

markusadamek commented 4 years ago

When opening the BrainVISA examples and storing them the stored file will have the wrong ArrayIndexingOrder. Opening the file in freeview will prompt an error (mrisReadGIFTIfile: malformed data array [2] in file test.surf.gii: num_vertices=3 num_cols=22134 expected nvertices=22134, num_cols=3)

example code: testA=gifti('\Base64\sujet01_Lwhite.surf.gii'); save(testA,'test.surf.gii','Base64Binary');

gllmflndn commented 4 years ago

Hi @markusadamek, thanks for the report.

I am not sure where the issue lies. A roundtrip with the gifti library seems to work fine, even A is using RowMajorOrder and B ColumnMajorOrder:

>> A = gifti('sujet01_Lwhite.surf.gii');
>> save(A,'test.surf.gii','Base64Binary');
>> B = gifti('test.surf.gii');
>> isequal(export(A),export(B))
ans = 1

In memory internally and when saving files, ColumnMajorOrder is used and RowMajorOrder is dealt with when loading such file: https://github.com/gllmflndn/gifti/blob/master/%40gifti/private/gifti_read.m#L200-L207

I therefore don't manage to make sense of the freeview error: both files A and B have a data array 22134x3; their content can be stored differently using either ColumnMajorOrder or RowMajorOrder but this setting shouldn't change the dimensions of the array itself. No?

markusadamek commented 4 years ago

I did not see any problems if I do everything within matlab. The problem only appears if I compare the outputs with another loader (for example, freesurfer or the javascript loader used by BrainBrowser).

It might be that the root problem is something entirely different, but the stored file is not read correctly by other readers (readers other than the Matlab implementation). I Attached a picture in which i loaded the original sujet01_Lwhite.surf.nii into BrainBrowser and the same file after being stored with the matlab tool. I am using Matlab 2019b (maybe it is a matlab versioning issue arrising from decode/encode?) .

Annotation 2020-04-11 104154

gllmflndn commented 4 years ago

I guess I have to go back and read the GifTI specifications but could you point to the source code of the other readers you have been looking at?

Are the other readers happier if the data are saved in RowMajorOrder mode? To do so, you would have to change this line: https://github.com/gllmflndn/gifti/blob/master/%40gifti/save.m#L86 and transpose this.data{i}.data before entering fprintf: https://github.com/gllmflndn/gifti/blob/master/%40gifti/save.m#L219-L248

markusadamek commented 4 years ago

(1) It looks like Freesurfer only likes RowMajorOrder, but the image still isnt looking correct. The gifti reader for the freesurfer implementation can be found here: https://github.com/freesurfer/freesurfer/blob/dev/utils/gifti.cpp Annotation 2020-04-11 190508

(2) BrainBrowser doesnt care if it is Row or ColoumnMajor but still, the resulting image is wrong The implementation for the BrainBrowser gifti is here: https://github.com/aces/brainbrowser/blob/master/src/brainbrowser/workers/gifti-reader.js

brainbrowser_2

gllmflndn commented 4 years ago

The file opens fine in Surf Ice from @neurolabusc.

It is still unclear to me why the number of rows and columns would change according to the ArrayIndexingOrder: https://github.com/freesurfer/freesurfer/blob/b156d5aee6df2c7027ea45d3824813f8dcc536ef/packages/gifti/gifti_io.c#L1673-L1702

markusadamek commented 4 years ago

I just downloaded Surf Ice for windows and I still get the same wrong result (At this point I think it has nothing to do with rows/columns but that it might be an encoding issue). What Matlab version are you using? It could be a Matlab 2019 issue surf_ice

I will also get in touch with the people from freesurfer, it might be a problem with the reader on their side. (Since I am able to at least open it with every other reader)

gllmflndn commented 4 years ago

So confusing! Are you using the gifti library from here or the one shipped with SPM (they are not in sync)? Which version of the BrainVisa files are you using from https://www.nitrc.org/frs/?group_id=75&release_id=123 ? Do you observe the same issue starting from spm12/canonical/cortex_20484.surf.gii

markusadamek commented 4 years ago

I did a more thorough check: First, the corrupted Surf Ice picture is my fault.

The first table shows the ability of each implementation to open up one of the test surfaces:

File Matlab Surfice Freeview BrainBrowser
sujet01_Lwhite.surf.gii (BV_GIFTI_1.1) no (MATLAB:typecastc:notEnoughInputElements) yes yes yes
sujet01_Lwhite.surf.gii (BV_GIFTI_1.2) yes yes yes yes
sujet01_Lwhite.surf.gii (BV_GIFTI_1.3) yes yes yes yes
cortex_20484.surf.gii yes yes yes no (unsuable picture)

This table shows the ability of the different implementations to open the file after it had been stored with the matlab implementation (tested for base64 and gzipbase64 which yield the same results)

File Matlab Surfice Freeview BrainBrowser
sujet01_Lwhite.surf.gii (BV_GIFTI_1.1)        
sujet01_Lwhite.surf.gii (BV_GIFTI_1.2) yes yes no (1) no (unsuable picture)
sujet01_Lwhite.surf.gii (BV_GIFTI_1.3) yes yes yes no (unsuable picture)
cortex_20484.surf.gii yes yes yes no (unsuable picture)

(1) mrisReadGIFTIfile: malformed data array [2] in file bv_gifti_12_lwhite.surf.gii: num_vertices=3 num_cols=22134 expected nvertices=22134, num_cols=3

gllmflndn commented 4 years ago

Thank you for the thorough testing.