-
-
Save mikbuch/fb28aef0f77c7c7aeeff92a61b109d16 to your computer and use it in GitHub Desktop.
import argparse | |
import re | |
import subprocess as sp | |
''' | |
Script to automatize mapping neuroimaging data from volumes (NIfTI) to brain | |
surface (workbench). | |
Edit data: 2021-04-28 | |
Author: Mikolaj Buchwald, mikolaj.buchwald@gmail.com | |
Affiliation: Adam Mickiewicz University in Poznań, Poland | |
This scirpt takes a *.nii.gz file and maps results from this file to workbench | |
surface. | |
### Download | |
curl https://gist.githubusercontent.com/mikbuch/fb28aef0f77c7c7aeeff92a61b109d16/raw/84ae6f3afe30f98ae37b81ebb5765dff1e4ea5f6/workbench_volume_to_surface.py -o workbench_volume_to_surface.py | |
### Example | |
Usage: | |
The ouptut filename is generated based on the input file and some postfixes, | |
hence you don't have to specify. | |
You pass the arguments in the following manner: | |
python workbench_volume_to_surface.py \ | |
--in_nifti thresh_zstat.nii.gz \ | |
--in_left_surf /Applications/workbench/HCP_S1200_GroupAvg_v1/S1200.L.midthickness_MSMAll.32k_fs_LR.surf.gii \ | |
--in_right_surf /Applications/workbench/HCP_S1200_GroupAvg_v1/S1200.R.midthickness_MSMAll.32k_fs_LR.surf.gii | |
For this command the following output files will be created: | |
* thresh_zstat_hemi-L_.func.gii | |
* thresh_zstat_hemi-R_.func.gii | |
* thresh_zstat_upper-X_.info -- explained below | |
The underscore before the extentions was put there on purpose -- for easier | |
reading of the filename. | |
Additionally, an empty file with information on the upper bound (highest value) | |
of the NIfTI file will be created, e.g., Z-max value, e.g.: | |
* thresh_zstat_hemi_upper-6.45_.info | |
The underscore before the extentions was put there on purpose -- for easier | |
reading of the filename/upper value. | |
In order to run in debugging mode (no files will be generated), use | |
the following command: | |
python workbench_volume_to_surface.py \ | |
--in_nifti thresh_zstat.nii.gz \ | |
--in_left_surf /Applications/workbench/HCP_S1200_GroupAvg_v1/S1200.L.midthickness_MSMAll.32k_fs_LR.surf.gii \ | |
--in_right_surf /Applications/workbench/HCP_S1200_GroupAvg_v1/S1200.R.midthickness_MSMAll.32k_fs_LR.surf.gii \ | |
--debug | |
This script is available as public gists here: | |
https://gist.github.com/mikbuch/fb28aef0f77c7c7aeeff92a61b109d16 | |
''' | |
parser = argparse.ArgumentParser(description='Volume to surface mapping \ | |
in Workbench') | |
parser.add_argument('--in_nifti', '-n', | |
help="Input NIfTI file") | |
parser.add_argument('--in_left_surf', '-l', | |
help="Input left hemishphere surface.") | |
parser.add_argument('--in_right_surf', '-r', | |
help="Input right hemishphere surface.") | |
parser.add_argument('--debug', | |
action='store_true', | |
help='Use debugging mode, no files will be created.') | |
args = parser.parse_args() | |
hemispheres = [{'code': 'L', 'surface': args.in_left_surf}, | |
{'code': 'R', 'surface': args.in_right_surf}] | |
for hemi in hemispheres: | |
########################################################################### | |
# | |
# Surface file | |
# | |
out_surf_file = re.sub('.nii.gz', | |
'_hemi-%s_.func.gii' % hemi['code'], | |
args.in_nifti) | |
cmd = 'wb_command -volume-to-surface-mapping %s %s %s ' \ | |
'-trilinear' % (args.in_nifti, hemi['surface'], out_surf_file) | |
print('\n\n' + cmd + '\n') | |
if not args.debug: | |
process = sp.Popen(cmd, stdout=sp.PIPE, shell=True) | |
output = process.communicate()[0] | |
else: | |
print(' --- Debugging mode: Surface ---') | |
########################################################################### | |
# | |
# Info file | |
# | |
out_info_file = re.sub('.nii.gz', '_upper-%.2f_.info', args.in_nifti) | |
# Get highest value for info file. | |
cmd = 'fslstats %s -R' % (args.in_nifti) | |
if not args.debug: | |
print('\n\n' + cmd + '\n') | |
process = sp.Popen(cmd, stdout=sp.PIPE, shell=True) | |
output = process.communicate()[0] | |
print(output) | |
hi_value = float(str(output).split(' ')[1]) | |
with open(out_info_file % hi_value, 'w') as f: | |
f.write('') | |
else: | |
print(' --- Debugging mode: Info ---') | |
print('\n\n Info file written as:\n' + out_info_file + '\n') |
Hi Forough, what is the file name of the volume you are trying to map to a surface?
I mean, e.g.: "thresh_zstat1.nii.gz"
Hi
I am using bold.nii data and also these lines before your code for masking
path_bold = r'D:\data\sub-CC00060XX03_ses-12501_task-rest_desc-preproc_bold.nii'
path_mask = r'D:\data\sub-CC00060XX03_ses-12501_task-rest_desc-preproc_space-bold_brainmask.nii'
bold = nib.load(path_bold)
mask = nib.load(path_mask)
brain_masker = NiftiMasker(mask_img=mask, standardize=True,t_r=0.392)
brain_ts =np.array(brain_masker.fit_transform(bold))
new_image = brain_masker.inverse_transform(brain_ts)
func_file = new_image
surfacemidthick1 = r'D:\data\sub-CC00060XX03_ses-12501_hemi-L_space-T2w_midthickness.surf.gii'
surfacemidthick2 = r'D:\data\sub-CC00060XX03_ses-12501_hemi-R_space-T2w_midthickness.surf.gii'
#label_out = 'D:\data\sub-CC00060XX03_ses-12501_hemi-L_space-T2w_midthickness.func.gii'
parser = argparse.ArgumentParser(description='Volume to surface mapping
in Workbench')
parser.add_argument('--func_file', '-n',
help="Input NIfTI file")
parser.add_argument('--surfacemidthick1', '-l',
help="Input left hemishphere surface.")
parser.add_argument('--surfacemidthick2', '-r',
help="Input right hemishphere surface.")
parser.add_argument('--debug',
action='store_true',
help='Use debugging mode, no files will be created.')
args = parser.parse_args()
hemispheres = [{'code': 'L', 'surface': args.surfacemidthick1},
{'code': 'R', 'surface': args.surfacemidthick2}]
for hemi in hemispheres:
###########################################################################
#
# Surface file
#
out_surf_file = re.sub('.nii',
'_hemi-%s_.func.gii' % hemi['code'],
str(args.func_file))
cmd = 'wb_command -volume-to-surface-mapping %s %s %s ' \
'-trilinear' % (args.func_file, hemi['surface'], out_surf_file)
Hi, my code is intended for command line use (i.e., in the bash). If you wish to use it in a script (specify paths, etc. in the Python script), you have to get rid of the parser
part, and use your variable names, e.g.:
path_bold = r'D:\data\sub-CC00060XX03_ses-12501_task-rest_desc-preproc_bold.nii'
path_mask = r'D:\data\sub-CC00060XX03_ses-12501_task-rest_desc-preproc_space-bold_brainmask.nii'
bold = nib.load(path_bold)
mask = nib.load(path_mask)
brain_masker = NiftiMasker(mask_img=mask, standardize=True,t_r=0.392)
brain_ts =np.array(brain_masker.fit_transform(bold))
new_image = brain_masker.inverse_transform(brain_ts)
func_file = new_image
surfacemidthick1 = r'D:\data\sub-CC00060XX03_ses-12501_hemi-L_space-T2w_midthickness.surf.gii'
surfacemidthick2 = r'D:\data\sub-CC00060XX03_ses-12501_hemi-R_space-T2w_midthickness.surf.gii'
#label_out = 'D:\data\sub-CC00060XX03_ses-12501_hemi-L_space-T2w_midthickness.func.gii'
##############
# Left hemisphere
out_surf_file = re.sub('.nii',
'_hemi-l_.func.gii',
func_file)
cmd = 'wb_command -volume-to-surface-mapping %s %s %s ' \
'-trilinear' % (func_file, surfacemidthick1, out_surf_file)
process = sp.Popen(cmd, stdout=sp.PIPE, shell=True)
output = process.communicate()[0]
###############
# Right hemisphere
out_surf_file = re.sub('.nii',
'_hemi-r_.func.gii',
func_file)
cmd = 'wb_command -volume-to-surface-mapping %s %s %s ' \
'-trilinear' % (func_file, surfacemidthick2, out_surf_file)
process = sp.Popen(cmd, stdout=sp.PIPE, shell=True)
output = process.communicate()[0]
OH! You're right.
I am new in this field and facing many challenges in this way.
Thank you for your explanation and guidance.
No problem, everybody started at some point.
Good luck with your research!
I appreciate it, Thanks.
Hi Mikolaj!
I am using yous codes for dHCP data and getting this error:
While running:
wb_command -volume-to-surface-mapping None None None -trilinear
ERROR: NAME OF FILE: None
File does not exist.
Would you please help me to fix this error?
I don't know the reason of the input argument convertion to None type.
Best regards,
Forough