gallantlab / pycortex

Pycortex is a python-based toolkit for surface visualization of fMRI data
https://gallantlab.github.io/pycortex
BSD 2-Clause "Simplified" License
604 stars 140 forks source link

[NSD dataset] Flat image shows up in wrong orientation #488

Open uhussai7 opened 1 year ago

uhussai7 commented 1 year ago

I use the following code, vol_data = cortex.Volume(np.moveaxis(np.moveaxis(test_data,0,-1),0,1), subject, xfm) cortex.quickflat.make_figure(vol_data,recache=1) plt.show() But I do not get the nice symmetrical flat maps. Instead on the left side I see an image where the medial side is to the far left. On the right side I see an image where the posterior side is at the top of the image. I am using the flat maps from the NSD dataset (https://registry.opendata.aws/nsd/).

alexhuth commented 1 year ago

Hi @uhussai7 — could you share a screenshot?

uhussai7 commented 1 year ago

image Actually now that I think about it, it seems they both need a counter clockwise rotation by 90.

alexhuth commented 1 year ago

can you tell which way is up (superior) on each hemisphere? it might be a transpose of the x and y coordinates instead of a rotation.

uhussai7 commented 1 year ago

I don't know that immediately, but let me see if I can figure it out, will comment back.

alexhuth commented 1 year ago

Looking at this a little more I think you're right, it's a rotation. Assuming you're plotting a single EPI volume here, the bits with lots of dark red and blue voxels are likely dropout areas near the ear canals and sinuses, and so should go on the bottom.

I haven't actually used NSD before — do they supply the flatmaps directly as gifti files, or are you drawing them from the freesurfer directories? If they're giftis, I think you should probably just create copies that incorporate a 90° CCW rotation and then import those to pycortex. If they're coming directly from freesurfer, I would be confused, since they should come in the format that pycortex expects.

uhussai7 commented 1 year ago

Okay so let me just outline the steps I carried out to see if it offers any clarity.

1) I use the cortex.freesurfer.import_subj("subj01",freesurfer_subject_dir=freesurfer_path) command to import the subect 2) Then I use cortex.freesurfer.import_flat("subj01",'full') 3) I align with cortex.align.automatic('subj01','full',ref_path) where ref_path is a 3d nifti of a functional scan mean 4) Then I load the same nifti and carry out vol_data = cortex.Volume(np.moveaxis(np.moveaxis(test_data,0,-1),0,1), subject, xfm) cortex.quickflat.make_figure(vol_data,recache=1) plt.show()

Please note that the path for freesurfer for NSD can be seen here https://natural-scenes-dataset.s3.amazonaws.com/index.html#nsddata/freesurfer/subj01/surf/

And the volume path is /nsd/nsddata_betas/ppdata/subj01/func1pt8mm/betas_fithrf_GLMdenoise_RR/meanbeta.nii.gz

uhussai7 commented 1 year ago

Just a tiny update, I plotted the flat surfaces directly on mayavi using: pts_lh,polys_lh,_=get_surf('subj01','lh','patch','full'+'.flat',freesurfer_subject_dir=freesurfer_path) pts_rh,polys_rh,_=get_surf('subj01','rh','patch','full'+'.flat',freesurfer_subject_dir=freesurfer_path) mlab.triangular_mesh(pts_rh[:,0],pts_rh[:,1],pts_rh[:,2],polys_rh) mlab.triangular_mesh(pts_lh[:,0]+500,pts_lh[:,1],pts_lh[:,2],polys_lh)

And it seems to be correct from freesurfer, so likely something else: image

uhussai7 commented 1 year ago

An update: If I make the following change in cortex.freesufer.py :

for hemi in hemis:
        if flat_type == 'freesurfer':
            pts, polys, _ = get_surf(fs_subject, hemi, "patch", patch+".flat", freesurfer_subject_dir=freesurfer_subject_dir)
            # Reorder axes: X, Y, Z instead of Y, X, Z
            #flat = pts[:, [1, 0, 2]] 
            # Flip Y axis upside down
            #flat[:, 1] = -flat[:, 1] 
            flat=pts 

I seem to get the correct result which is attached below. To clarify, I commented out "Reorder axis..." and "Flip Y axis..." and just made flat=pts. Not sure why this works though...

image

kendrickkay commented 11 months ago

The shape/orientation of the most recent image as posted above is correct (you can check against https://natural-scenes-dataset.s3.amazonaws.com/nsddata/inspections/surfacevisualizations/subj01flat_curvature_subj01.png)

In preparing the various flattened surfaces, we did perform some rotations and such. So I believe what is happening is that we may have diverged from some internal FreeSurfer convention. It looks like the solution above could be workable; if not, we can look more deeply and make some tweaks

gongzix commented 7 months ago

I have met another problem, how can I add specific ROI visualization, like V1,V2,V3. Following codes above, I can not get the ROI labels