pycortex
pycortex copied to clipboard
ValueError when importing subject from Freesurfer
Recently came across pycortex and decided to give it a try. I'm having troubles getting it to import data from freesurfer, though, as pycortex raises a ValueError, as shown in the backtrace below. Any suggestions on how to proceed would be welcome.
In [10]: import cortex.freesurfer as fs
In [11]: fs.import_subj("spat01", whitematter_surf="white")
Are you sure you want to overwrite this existing subject?
This will delete all files for this subject in the filestore, including all blender cuts. Type YES
YES
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-11-a8a458747a00> in <module>
----> 1 fs.import_subj("spat01", whitematter_surf="white")
/home/user/anaconda3/envs/cortex/lib/python3.7/site-packages/cortex/freesurfer.py in import_subj(subject, sname, freesurfer_subject_dir, whitematter_surf)
174
175 # Make the fiducial files. Just make them.
--> 176 make_fiducial(subject, freesurfer_subject_dir=freesurfer_subject_dir)
177
178 # Freesurfer uses FOV/2 for center, let's set the surfaces to use the
/home/user/anaconda3/envs/cortex/lib/python3.7/site-packages/cortex/freesurfer.py in make_fiducial(subject, freesurfer_subject_dir)
312 """
313 for hemi in ['lh', 'rh']:
--> 314 spts, polys, _ = get_surf(subject, hemi, "smoothwm", freesurfer_subject_dir=freesurfer_subject_dir)
315 ppts, _, _ = get_surf(subject, hemi, "pial", freesurfer_subject_dir=freesurfer_subject_dir)
316 fname = get_paths(subject, hemi, "surf", freesurfer_subject_dir=freesurfer_subject_dir).format(name="fiducial")
/home/user/anaconda3/envs/cortex/lib/python3.7/site-packages/cortex/freesurfer.py in get_surf(subject, hemi, type, patch, flatten_step, freesurfer_subject_dir)
406 surf_file = get_paths(subject, hemi, 'surf', freesurfer_subject_dir=freesurfer_subject_dir).format(name=type)
407
--> 408 pts, polys = parse_surf(surf_file)
409
410 if patch is not None:
/home/user/anaconda3/envs/cortex/lib/python3.7/site-packages/cortex/freesurfer.py in parse_surf(filename)
328 print(comment)
329 verts, faces = struct.unpack('>2I', fp.read(8))
--> 330 pts = np.fromstring(fp.read(4*3*verts), dtype='f4').byteswap()
331 polys = np.fromstring(fp.read(4*3*faces), dtype='i4').byteswap()
332
ValueError: string size must be a multiple of element size
It seems there is a readline too much in parse_surf
. Removing the line fixes the issue for me. I'm on Python 3.7.3
Hi Daniel! Thanks for both posting this issue and finding a fix :) I was actually surprised upon seeing this that (1) we are still using our own code to parse freesurfer surfaces instead of nibabel (I think this module predates the introduction of nibabel as a dependency for pycortex), and (2) that we haven't run into this issue before.
Can you tell us what version of freesurfer you're using here? Also, is there something particular or strange about this surface?
Finally, can you confirm that the nibabel function freesurfer.read_geometry
can successfully load your surfaces? If so, I think it may be best for us to just switch to using nibabel to read freesurfer surfaces.
Uhm, interesting.
The surfaces were reconstructed with Freesurfer version freesurfer-local-build-dev-20190709
, and recon-all.log tells me that recon-all finished without error.
But I also cannot nib.freesurfer.read_geometry
for the smoothwm
surface, so I suppose there must be something wrong with it. The surfaces pial
and smoothwm
are "broken", but all others work. Freeview can read and display them without issues though.
I'll investigate further and report back when I find out what the issue is.
Related: https://github.com/freesurfer/freesurfer/issues/699
Oh, thanks for the pointer @dangom!