OSCR

Modeling 2D spatio-tactile population receptive fields of the fingertip in human primary somatosensory cortex.

Code ↔ Paper

8 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 8 matches · 4 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § Methods › Preprocessing ↔ toolboxes/falkluesebrink/pRF/pRF_pipeline_nonlinear_BBR_01.sh, lines 138–190 · score 0.85 · largest component, masked functional template, morphologically closing, nearest neighbor, holes, BBR
  2. [2] § Methods › Preprocessing ↔ toolboxes/falkluesebrink/pRF/preproc_pRF.m, the whole file · a weak match · score 0.78 · bias field corrected, brain mask, high resolution, probabilistic, segmentation, Preprocessing
  3. [3] § Methods › Data analysis › Simulations › Implausibility ↔ toolboxes/ss_toolbox/ss_matlab/ss_samsrf/ss_samsrf_simprf.m, the whole file · a weak match · score 0.66 · random Gaussian noise, add noise, ground truth, dg, simulated, fitting
  4. [4] § Methods › Data analysis › Simulations › Meaningfulness ↔ toolboxes/ss_toolbox/ss_matlab/ss_samsrf/ss_samsrf_simprf.m, the whole file · a weak match · score 0.64 · random Gaussian noise, spatial tuning, onoff model, dg fix, simulated, fit
  5. [5] § Methods › Preprocessing ↔ toolboxes/falkluesebrink/pRF/pRF_pipeline_nonlinear_BBR_01.sh, lines 349–381 · score 0.60 · nearest neighbor, coregistration, unmasked, downsampled, bias, template
  6. [6] § Methods › Data analysis › PRF modeling ↔ toolboxes/falkluesebrink/pRF/pRF_pipeline_nonlinear_BBR_01.sh, lines 1–54 · score 0.59 · magnetic resonance imaging, population receptive field, pipeline, tactile, PRF
  7. [7] § Methods › Procedure ↔ toolboxes/ss_toolbox/ss_matlab/ss_zoomprf_main/ss_zoomprf_main_genapt_pins.m, the whole file · a weak match · score 0.58 · movement direction, perceive, scanner, edge, bar, pins
  8. [8] § Methods › Data analysis › PRF modeling ↔ toolboxes/ss_toolbox/ss_matlab/ss_samsrf/ss_samsrf_fit.m, lines 51–174 · score 0.53 · spatial tuning, onoff model, amplitude, dg fix, Gaussian, fit

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Shell · 535 lines · 24 KB · CC0-1.0 · 3 matches

  1. #!/bin/bash
  2. # Pipeline for preprocessing cleaned, converted, and BIDS-standardized functional
  3. # and structural magnetic resonance imaging data acquired at 7T in the scope of
  4. # a tactile population receptive field (pRF) experiment.
  5. # ***************************************
  6. # Generated: 13.10.2022 (FL)
  7. # Last modified: 23.08.2024 (SS)
  8. # ***************************************
  9. # * Please define variables here
  10. # ***************************************
  11. # Define subject(s) to be processed
  12. sub="01 02 03"
  13. # Define kernels to be used
  14. FWHM="0 1"
  15. # Define sessions to be processed
  16. ses="01 02 03 04"
  17. # Specify path to data directory
  18. input_directory=/home/sstoll/projects/zoomprf_main/data
  19. # Specify paths to toolbox directories
  20. prf_directory=/home/sstoll/projects/toolboxes/postdoc-kuehn-tuebingen/falkluesebrink/pRF
  21. spm_directory=/home/sstoll/projects/toolboxes/postdoc-kuehn-tuebingen/spm12
  22. biascorr_directory=/home/sstoll/projects/toolboxes/postdoc-kuehn-tuebingen/falkluesebrink/biasCorrection
  23. # Projection fraction for surface projection of functional data with FreeSurfer
  24. projFrac=0.5
  25. # Maximum number of threads used for processing functional data using ANTs
  26. ants_threads_functional=16
  27. # ***************************************
  28. # * Software used
  29. # ***************************************
  30. ### For setting up the pipeline and initial validation
  31. # FreeSurfer: freesurfer-linux-ubuntu18_x86_64-7.3.2-20220804-6354275
  32. # ANTs: 2.3.5
  33. # MATLAB: 9.12.0.1884302 (R2022a)
  34. # SPM12: 7771 (for more details, see 'Custom scripts/files used')
  35. # Bash: 4.4.20(1)-release (x86_64-pc-linux-gnu)
  36. # Ubuntu: 18
  37. # biasCorrection: -/- (https://github.com/fluese/biasCorrection)
  38. #
  39. ### For finalizing the pipeline and final validation
  40. # FreeSurfer: freesurfer-linux-ubuntu22_x86_64-7.3.2-20220804-6354275
  41. # ANTs: 2.3.5.dev208-g6f137
  42. # MATLAB: 9.13.0.2193358 (R2022b) Update 5
  43. # SPM12: 7771 (for more details, see 'Custom scripts/files used')
  44. # Bash: 5.1.16(1)-release (x86_64-pc-linux-gnu)
  45. # Ubuntu: 22.04.2 LTS
  46. # biasCorrection: 1 parent 5447c4c commit d85f05f (https://github.com/fluese/biasCorrection)
  47. # ***************************************
  48. # * Custom scripts/files used
  49. # ***************************************
  50. # antsIntrasubjectAverage_NearestNeighbor.sh
  51. # antsRegistrationSyN_NearestNeighbor.sh
  52. # removeBiasfield_pRF.sh
  53. # preproc_pRF.m
  54. # ****************************************
  55. # biasCorrection.m
  56. # defjob.mat
  57. # spm_preproc_run_fl_standalone.m (changed based on SPM12: 6365)
  58. # spm_preproc_write8_fl_standalone.m (changed based on SPM12: 6137)
  59. # ***************************************
  60. # * Setup
  61. # ***************************************
  62. # Make sure that at least one thread is used, but no more than four. A template is to be generated from four files. Therefore, it can be parallized by a factor of four at max.
  63. ants_threads_anatomical=${ants_threads_functional}
  64. if (( ants_threads_anatomical > 4 )); then
  65. ants_threads_anatomical=4
  66. elif (( ants_threads_anatomical < 1 )); then
  67. ants_threads_anatomical=1
  68. fi
  69. # Make sure that at least one thread is used, but no more than eight. More than eight threads are said to not improve speed for FreeSurfer.
  70. freesurfer_threads=${ants_threads_functional}
  71. if (( freesurfer_threads > 8 )); then
  72. freesurfer_threads=8
  73. elif (( freesurfer_threads < 1 )); then
  74. freesurfer_threads=1
  75. fi
  76. subCounter=0
  77. for sub_ID in $sub; do
  78. echo "***************************************"
  79. echo "* Processing of subject ${sub_ID} started."
  80. echo "***************************************"
  81. # Set up variables for paths
  82. output_directory=${input_directory}/derivatives/sub-${sub_ID}/
  83. SUBJECTS_DIR=${input_directory}/derivatives/FreeSurfer/
  84. # Create folders
  85. for ses_ID in $ses; do
  86. mkdir -p ${output_directory}/ses-${ses_ID}/func/
  87. mkdir -p ${output_directory}/ses-${ses_ID}/anat/
  88. done
  89. mkdir -p ${output_directory}/ses-all/func/
  90. mkdir -p ${output_directory}/ses-all/anat/
  91. mkdir -p ${SUBJECTS_DIR}/
  92. # 4. Disassemble time series of each functional run, average, and mask it
  93. echo ""
  94. echo "***************************************"
  95. echo "* Disassemble time series of each functional run, average, and mask it"
  96. echo "***************************************"
  97. for ses_ID in $ses; do
  98. num_runs=$(find ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/ -name "*run-*_bold.nii.gz" | wc -l)
  99. for run_ID in $( eval echo {01..${num_runs}} ); do
  100. if [ -f "${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_masked.nii.gz" ]; then
  101. echo "Average and mask for functional data of session ${ses_ID} and run ${run_ID} exist already. Skipping re-processing it."
  102. else
  103. # Dissemble time series of each functional run again... [Better way?]
  104. ImageMath 4 \
  105. ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_disassemble.nii.gz \
  106. TimeSeriesDisassemble \
  107. ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold.nii.gz
  108. # Create average of each functional run
  109. AverageImages 3 \
  110. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean.nii.gz \
  111. 0 \
  112. ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_disassemble*.nii.gz
  113. # Remove dissembled time series of each functional run again
  114. rm -f ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_disassemble*.nii.gz
  115. # Create brain mask of each functional average
  116. ThresholdImage 3 \
  117. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean.nii.gz \
  118. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_brainmask.nii.gz \
  119. 700 100000
  120. # Get largest component of mask
  121. ImageMath 3 \
  122. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_brainmask.nii.gz \
  123. GetLargestComponent \
  124. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_brainmask.nii.gz
  125. # Morphologically close mask to fill holes
  126. ImageMath 3 \
  127. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_brainmask.nii.gz \
  128. MC \
  129. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_brainmask.nii.gz \
  130. 2
  131. # Mask each functional average
  132. ImageMath 3 \
  133. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_masked.nii.gz \
  134. m \
  135. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean.nii.gz \
  136. ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_brainmask.nii.gz
  137. fi
  138. done
  139. done
  140. # 5. Create unbiased template of all masked functional averages across sessions
  141. echo ""
  142. echo "***************************************"
  143. echo "* Create unbiased template of all masked functional averages across sessions"
  144. echo "***************************************"
  145. if [ -f "${output_directory}/ses-all/func/sub-${sub_ID}_ses-all_task-pRF_run-all_bold_mean_masked_template0.nii.gz" ]; then
  146. echo "Functional template of all masked functional averages across sessions exists already. Skipping re-processing it."
  147. else
  148. find ${output_directory}/ses-0*/ \
  149. -name "sub-${sub_ID}_ses-*_task-pRF_run-*_bold_mean_masked.nii.gz" \
  150. | sort > ${output_directory}/ses-all/func/sub-${sub_ID}_ses-all_task-pRF_run-all_paths.txt
  151. antsIntrasubjectAverage_NearestNeighbor.sh \
  152. -d 3 \
  153. -i 4 \
  154. -c 2 \
  155. -a 2 \
  156. -b 0 \
  157. -n 0 \
  158. -e 1 \
  159. -k 1 \
  160. -r 1 \
  161. -j ${ants_threads_functional} \
  162. -f 8x4x2x1 \
  163. -s 4x2x1x0 \
  164. -q 1000x1000x500x250 \
  165. -t Rigid \
  166. -o ${output_directory}/ses-all/func/sub-${sub_ID}_ses-all_task-pRF_run-all_bold_mean_masked_ \
  167. ${output_directory}/ses-all/func/sub-${sub_ID}_ses-all_task-pRF_run-all_paths.txt
  168. fi
  169. # 6. Resample structural data to the resolution of functional data
  170. echo ""
  171. echo "***************************************"
  172. echo "* Resample structural data to the resolution of functional data"
  173. echo "***************************************"
  174. for ses_ID in $ses; do
  175. if [ -f "${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled.nii.gz" ]; then
  176. echo "Structural data of session ${ses_ID} already resampled. Skipping re-processing it."
  177. else
  178. # Get resolution of functional data
  179. voxel_sizes=$(mri_info ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-01_bold.nii.gz | grep "voxel sizes")
  180. # res: col (x), row (y), slice (z) and frame resolution
  181. read x y z <<< $(awk -F'[:,]' '{print $2, $3, $4}' <<< "$voxel_sizes")
  182. # Resample
  183. mri_convert \
  184. -rt cubic \
  185. -vs $x $y $z \
  186. -i ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w.nii.gz \
  187. -o ${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled.nii.gz
  188. # -vs, --voxsize <size_x> <size_y> <size_z>
  189. fi
  190. done
  191. # 7. Bias-correct structural data
  192. echo ""
  193. echo "***************************************"
  194. echo "* Bias-correct structural data"
  195. echo "***************************************"
  196. for ses_ID in $ses; do
  197. if [ -f "${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled_biasCorrected.nii.gz" ]; then
  198. echo "Structural data of session ${ses_ID} already bias-corrected. Skipping re-processing it."
  199. else
  200. removeBiasfield_pRF.sh ${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled.nii.gz ${prf_directory} ${spm_directory} ${biascorr_directory}
  201. fi
  202. done
  203. # 8. Mask structural data
  204. echo ""
  205. echo "***************************************"
  206. echo "* Mask structural data"
  207. echo "***************************************"
  208. for ses_ID in $ses; do
  209. if [ -f "${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled_biasCorrected_masked.nii.gz" ]; then
  210. echo "Structural data of session ${ses_ID} already masked. Skipping re-processing it."
  211. else
  212. mri_synthstrip \
  213. -i ${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled_biasCorrected.nii.gz \
  214. -o ${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled_biasCorrected_masked.nii.gz \
  215. -b 1 #\
  216. #--no-csf
  217. fi
  218. done
  219. # 9. Create unbiased template of all masked structural data across sessions
  220. echo ""
  221. echo "***************************************"
  222. echo "* Create unbiased template of all masked structural data across sessions"
  223. echo "***************************************"
  224. if [ -f "${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_masked_template0.nii.gz" ]; then
  225. echo "Structural template of all masked structural data across sessions exists already. Skipping re-processing it."
  226. else
  227. antsIntrasubjectAverage_NearestNeighbor.sh \
  228. -d 3 \
  229. -i 4 \
  230. -c 2 \
  231. -g 0.1 \
  232. -e 1 \
  233. -k 1 \
  234. -a 2 \
  235. -b 0 \
  236. -n 0 \
  237. -r 1 \
  238. -j ${ants_threads_anatomical} \
  239. -f 8x4x2x1 \
  240. -s 4x2x1x0 \
  241. -q 1000x1000x500x250 \
  242. -t Rigid \
  243. -o ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_masked_ \
  244. ${output_directory}/ses-0[1-4]/anat/*biasCorrected_masked.nii.gz
  245. fi
  246. # 10. Apply transformations for generating masked structural template to UNMASKED structural data
  247. echo ""
  248. echo "***************************************"
  249. echo "* Apply transformations for generating masked structural template to UNMASKED structural data"
  250. echo "***************************************"
  251. counter=0
  252. for ses_ID in $ses; do
  253. if [ -f "${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz" ]; then
  254. echo "Transformations to UNMASKED structural data of session ${ses_ID} already applied. Skipping re-processing it."
  255. else
  256. antsApplyTransforms \
  257. -d 3 \
  258. -e 0 \
  259. -v 1 \
  260. -n NearestNeighbor \
  261. --float \
  262. -r ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_masked_template0.nii.gz \
  263. -t ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_masked_sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled_biasCorrected_masked${counter}0GenericAffine.mat \
  264. -i ${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled_biasCorrected.nii.gz \
  265. -o ${output_directory}/ses-${ses_ID}/anat/sub-${sub_ID}_ses-${ses_ID}_T1w_downsampled_biasCorrected_Warped.nii.gz
  266. counter=$((counter+1))
  267. fi
  268. done
  269. # 11. Create unbiased template of all UNMASKED structural data across sessions
  270. echo ""
  271. echo "***************************************"
  272. echo "* Create unbiased template of all UNMASKED structural data across sessions"
  273. echo "***************************************"
  274. if [ -f "${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz" ]; then
  275. echo "Structural template of all UNMASKED structural data acrosss sessions exists already. Skipping re-processing it."
  276. else
  277. ls ${output_directory}/ses-0[1-4]/anat/sub-${sub_ID}_ses-0[1-4]_T1w_downsampled_biasCorrected_Warped.nii.gz > \
  278. ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_Warped_paths.txt
  279. ImageSetStatistics 3 \
  280. ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_Warped_paths.txt \
  281. ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz \
  282. 0
  283. fi
  284. # 12. Mask UNMASKED structural template
  285. echo ""
  286. echo "***************************************"
  287. echo "* Mask UNMASKED structural template"
  288. echo "***************************************"
  289. if [ -f "${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_masked.nii.gz" ]; then
  290. echo "UNMASKED structural template already masked. Skipping re-processing it."
  291. else
  292. mri_synthstrip \
  293. -i ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz \
  294. -o ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_masked.nii.gz \
  295. -b 1 #\
  296. #--no-csf
  297. fi
  298. # 13. Register novel masked structural template to masked functional template
  299. echo ""
  300. echo "***************************************"
  301. echo "* Register novel masked structural template to masked functional template"
  302. echo "***************************************"
  303. # This yields better results than the other way round. The inverse transformation will be used in stage 14 as it yields the information to transform the functional template data into the space of the structural template data.
  304. if [ -f "${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_masked_registered_to_sub-${sub_ID}_ses-all_task-pRF_run-all_bold_mean_masked_template0_0GenericAffine.mat" ]; then
  305. echo "Novel masked structural template already registered to masked functional template. Skipping re-processing it."
  306. else
  307. antsRegistrationSyN_NearestNeighbor.sh \
  308. -d 3 \
  309. -t r \
  310. -n ${ants_threads_functional} \
  311. -f ${output_directory}/ses-all/func/sub-${sub_ID}_ses-all_task-pRF_run-all_bold_mean_masked_template0.nii.gz \
  312. -m ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_masked.nii.gz \
  313. -o ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_masked_registered_to_sub-${sub_ID}_ses-all_task-pRF_run-all_bold_mean_masked_template0_
  314. fi
  315. # 14. Coarse function-to-structure coregistration: Apply forward transformations for generating masked functional template and inversetransformations for coregistering masked structural and masked functional template to each unmasked functional run.
  316. # Thus, each unmasked functional image (from each run and session) will be warped into the space of the masked structural template.
  317. echo ""
  318. echo "***************************************"
  319. echo "* Coarse function-to-structure coregistration of each unmasked functional run by applying"
  320. echo "* forward transformations for generating masked functional template and"
  321. echo "* inverse transformations for coregistering novel masked structural template and masked functional template"
  322. echo "***************************************"
  323. counter=0
  324. for ses_ID in $ses; do
  325. num_runs=$(find ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/ -name "*ses-${ses_ID}*run-*_bold.nii.gz" \
  326. | wc -l)
  327. for run_ID in $( eval echo {01..${num_runs}} ); do
  328. if [ -f "${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_registered_to_sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz" ]; then
  329. echo "Foward and inverse transformations to unmasked functional data of session ${ses_ID} and run ${run_ID} already applied. Skipping re-processing it."
  330. else
  331. antsApplyTransforms \
  332. -d 3 \
  333. -e 3 \
  334. -n NearestNeighbor \
  335. --float 1 \
  336. --verbose 1 \
  337. -r ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz \
  338. -t [${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_masked_registered_to_sub-${sub_ID}_ses-all_task-pRF_run-all_bold_mean_masked_template0_0GenericAffine.mat,1] \
  339. -t ${output_directory}/ses-all/func/sub-${sub_ID}_ses-all_task-pRF_run-all_bold_mean_masked_sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_mean_masked${counter}0GenericAffine.mat \
  340. -i ${input_directory}/sub-${sub_ID}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold.nii.gz \
  341. -o ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_registered_to_sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz
  342. # Note that we skip the affix "masked" here entirely to wipe the slate clean and omit potential confusion when output images are masked again.
  343. fi
  344. counter=$((counter+1))
  345. done
  346. done
  347. # 15. Run recon-all on unmasked structural template
  348. echo ""
  349. echo "***************************************"
  350. echo "* Run recon-all on unmasked structural template"
  351. echo "***************************************"
  352. if [ -f "${SUBJECTS_DIR}/sub-${sub_ID}/mri/aseg.mgz" ]; then
  353. echo "Recon-all finished already. Skipping re-processing it."
  354. else
  355. echo ""
  356. echo "***************************************"
  357. echo "* Run autorecon 1"
  358. echo "***************************************"
  359. if [ -f "${SUBJECTS_DIR}/sub-${sub_ID}/mri/brainmask.mgz" ]; then
  360. echo "Autorecon 1 completed already. Skipping re-processing it."
  361. echo ""
  362. else
  363. if [ -d "${SUBJECTS_DIR}/sub-${sub_ID}/" ]; then
  364. echo "Subject folder exists already."
  365. recon-all \
  366. -autorecon1 \
  367. -hires \
  368. -threads ${freesurfer_threads} \
  369. -parallel \
  370. -s sub-${sub_ID}
  371. else
  372. recon-all \
  373. -autorecon1 \
  374. -hires \
  375. -threads ${freesurfer_threads} \
  376. -parallel \
  377. -i ${output_directory}/ses-all/anat/sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz \
  378. -s sub-${sub_ID}
  379. fi
  380. fi
  381. echo ""
  382. echo "***************************************"
  383. echo "* Create brainmask.mgz"
  384. echo "***************************************"
  385. if [ -f "${SUBJECTS_DIR}/sub-${sub_ID}/mri/brainmask.synthstrip.mgz" ]; then
  386. echo "Brainmask created already. Skipping re-processing it."
  387. echo ""
  388. else
  389. # A backup of the original brainmask can be found here: /mri/brainmask.auto.mgz
  390. mri_synthstrip \
  391. -i ${SUBJECTS_DIR}/sub-${sub_ID}/mri/T1.mgz \
  392. -o ${SUBJECTS_DIR}/sub-${sub_ID}/mri/brainmask.synthstrip.mgz \
  393. -b 1 \
  394. --no-csf
  395. cp \
  396. ${SUBJECTS_DIR}/sub-${sub_ID}/mri/brainmask.synthstrip.mgz \
  397. ${SUBJECTS_DIR}/sub-${sub_ID}/mri/brainmask.mgz
  398. fi
  399. echo ""
  400. echo "***************************************"
  401. echo "* Run autorecon 2+3"
  402. echo "***************************************"
  403. # [It seems odd, but careg is not part of autorecon2? This may be a bug and should be reported potentially.]
  404. recon-all \
  405. -autorecon2 \
  406. -autorecon3 \
  407. -careg \
  408. -no-isrunning \
  409. -hires \
  410. -threads ${freesurfer_threads} \
  411. -parallel \
  412. -s sub-${sub_ID}
  413. fi
  414. # 16. Fine function-to-structure coregistration of each coarsely-registered functional runs via boundary-based registration and surface projection
  415. # Create folder for surface projection
  416. vol2surf=${SUBJECTS_DIR}/sub-${sub_ID}/vol2surf/
  417. mkdir -p ${vol2surf}
  418. echo ""
  419. echo "***************************************"
  420. echo "* Fine function-to-structure coregistration of each coarsely-registered functional run"
  421. echo "* via boundary-based registration, followed by surface projection"
  422. echo "***************************************"
  423. for ses_ID in $ses; do
  424. num_runs=$(find ${output_directory}/ses-${ses_ID}/func/ -name "*run-*_bold_mean.nii.gz" | wc -l)
  425. for run_ID in $( eval echo {01..${num_runs}} ); do
  426. # Fine coregistration via boundary-based segmentation
  427. if [ -f ${vol2surf}/sub-${sub_ID}_ses-${ses_ID}_run-${run_ID}.lta ]; then
  428. echo ""
  429. echo "Fine coregistration of coarsely-registered functional data for session ${ses_ID} and run ${run_ID} exists already. Skipping re-processing it."
  430. else
  431. bbregister \
  432. --s sub-${sub_ID} \
  433. --mov ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_registered_to_sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz \
  434. --init-header \
  435. --bold \
  436. --nearest \
  437. --reg ${vol2surf}/sub-${sub_ID}_ses-${ses_ID}_run-${run_ID}.lta
  438. fi
  439. # Surface projection
  440. for hemi in lh rh; do
  441. for FWHM_ID in $FWHM; do
  442. if [ -f "${vol2surf}/${hemi}_sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_registered_to_sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_FWHM-${FWHM_ID//./p}_BBR.mgh" ]; then
  443. if [[ ${hemi} == lh ]]; then
  444. echo "Surface projection of left hemisphere of finely-registered functional data for session ${ses_ID} and run ${run_ID} using a FWHM of ${FWHM_ID} exists already. Skipping re-processing it."
  445. elif [[ ${hemi} == rh ]]; then
  446. echo "Surface projection of right hemisphere of finely-registered functional data for session ${ses_ID} and run ${run_ID} using a FWHM of ${FWHM_ID} exists already. Skipping re-processing it."
  447. fi
  448. else
  449. mri_vol2surf \
  450. --mov ${output_directory}/ses-${ses_ID}/func/sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_registered_to_sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0.nii.gz \
  451. --reg ${vol2surf}/sub-${sub_ID}_ses-${ses_ID}_run-${run_ID}.lta \
  452. --hemi ${hemi} \
  453. --o ${vol2surf}/${hemi}_sub-${sub_ID}_ses-${ses_ID}_task-pRF_run-${run_ID}_bold_registered_to_sub-${sub_ID}_ses-all_T1w_downsampled_biasCorrected_template0_FWHM-${FWHM_ID//./p}_BBR.mgh \
  454. --projfrac ${projFrac} \
  455. --surf-fwhm ${FWHM_ID}
  456. fi
  457. done
  458. done
  459. done
  460. done
  461. # 17. Atlas generation
  462. # Create folder for atlas
  463. atlas=${SUBJECTS_DIR}/sub-${sub_ID}/atlas/
  464. mkdir -p ${atlas}
  465. # Generate atlas using rh.aparc.annot and lh.aparc.annot (defaults)
  466. echo ""
  467. echo "***************************************"
  468. echo "* Generation of atlas"
  469. echo "***************************************"
  470. for hemi in lh rh; do
  471. if [ -f "${atlas}/${hemi}.postcentral.label" ]; then
  472. if [[ ${hemi} == lh ]]; then
  473. echo "Atlas generation for left hemisphere done already. Skipping re-processing it."
  474. elif [[ ${hemi} == rh ]]; then
  475. echo "Atlas generation for right hemisphere done already. Skipping re-processing it."
  476. fi
  477. else
  478. mri_annotation2label --subject sub-${sub_ID} --hemi ${hemi} --outdir ${atlas}
  479. fi
  480. done
  481. echo ""
  482. echo "***************************************"
  483. echo "* Processing of subject ${sub_ID} finished successfully."
  484. echo "***************************************"
  485. subCounter=$((subCounter+1))
  486. done

pRF_pipeline_nonlinear_BBR_01.sh at commit f90e9b5, under CC0-1.0 · at the source

Overview

Authors: Susanne Stoll1,2,3,4,5, Falk Luesebrink3,6,7, D Samuel Schwarzkopf8,9, Hendrik Mattern3,6,10, Peng Liu1,2,3,5, Johanna Noelle2,3, Esther Kuehn1,2,3,5,10
  1. Hertie Institute for Clinical Brain Research, Tuebingen, Germany
  2. Institute for Cognitive Neurology and Dementia Research, Otto-von-Guericke University Magdeburg, Germany
  3. German Center for Neurodegenerative Diseases, Magdeburg, Germany
  4. Max Planck Institute for Biological Cybernetics, Tuebingen, Germany
  5. German Center for Neurodegenerative Diseases, Tuebingen, Germany
  6. Biomedical Magnetic Resonance, Otto-von-Guericke-University Magdeburg, Germany
  7. Nuclear Magnetic Resonance Methods & Development Group, Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig, Germany
  8. School of Optometry and Vision Science, The University of Auckland, New Zealand
  9. Experimental Psychology, University College London, United Kingdom
  10. Center for Behavioral Brain Sciences, Magdeburg, Germany
Journal: Imaging neuroscience (Cambridge, Mass.), volume 4, article IMAG.a.1210
Dates: received 3 June 2025; accepted 16 March 2026; published online 26 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1162/imag.a.1210 · PMID 42212224 · PMCID PMC13214571 · OpenAlex W7143466424
Open access: diamond, a free copy (OpenAlex)
Status: code verified
Categories: fMRI (modality), human (organism), systems (subfield)
Methods: Connectivity, Machine learning, Statistics, Preprocessing, fMRI & imaging
Keywords: functional magnetic resonance imaging, population receptive field modeling, ultra-high field, 7T, spatial, tactile, primary somatosensory cortex, human, exploratory research, simulations
Topic: Tactile and Sensory Interactions (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: European Research Council (949609); European Structure and Investment Fund (ZS/2020/05/141591); Deutsche Forschungsgemeinschaft (MA, 9235/3-1, 501214112, KU 3711/4-1, 528318902); European Research Council under the European Union's Horizon 2020 Research and Innovation Programme (949609)
Citations: cited by 2 papers (Europe PMC); 97 references in the paper

Abstract

Tactile fingertip sensations are critical for everyday life. Accordingly, tactile fingertip maps have been extensively studied in human primary somatosensory cortex. However, the fine-grained functional architecture of these maps remains largely unknown. To uncover this architecture, we sought to estimate 2D spatio-tactile population receptive fields (pRFs) of the tip of the index finger in human Brodmann area 3b (BA3b). Using functional magnetic resonance imaging at 7T and submillimeter resolution along with prospective motion correction, we recorded brain responses while participants sensed a row of vibrotactile pins sweeping along cardinal axes over a portion of the fingertip. To estimate pRF position and size, we initially fit a 2D Gaussian pRF model to the data, which, however, produced largely implausible pRF estimates. Simulations indicated that this likely occurred because the size of pRFs in BA3b surpasses the portion of the fingertip we stimulated, resulting in an incomplete mapping of pRFs. To address this issue, we constrained the fitting procedure and refined the 2D Gaussian pRF model by keeping pRF size constant. Our results for pRF position then revealed that the ulnar-to-radial axis spanning the fingertip maps onto a superior-to-inferior axis in BA3b. Both the putatively large pRF size (relative to the mapping area) and the pRF position gradient we uncover here appear compatible with receptive field properties quantified in monkeys. Our study provides the first comprehensive investigation into the fine-grained functional architecture of human fingertip maps and brings us one step closer to a thorough understanding thereof.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 8 matches between paragraphs and lines of code.

Kriaese/manuscript-zoomprf

License: CC0-1.0
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: f90e9b5c4fc3e825d98ed8c9097b072f73a77497, 28 May 2026
Languages: MATLAB (122), Shell (4)
Size: 131 files, 126 scripts
Software Heritage: not archived
Found in: “Data and Code Availability”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: SPM (5 files), ANTs (3 files), Statistics and Machine Learning Toolbox (3 files), Image Processing Toolbox (2 files), Parallel Computing Toolbox (2 files), FreeSurfer (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
128 files

openneuro:ds006128

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: the link answers
Software Heritage: not checked
Found in: “Data and Code Availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
  • 28 September 2026: the link answers (HTTP 200)

OSF 4drz6

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Size: 35 files, 0 scripts
Software Heritage: not checked
Found in: the references
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
  • 28 September 2026: the link answers (HTTP 200)
1 file, to read at the source

This repository has no license: its authors keep all rights. Read it at the source.

  • README.md — Text, 211 lines, not shown here
At the source:

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 3 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 126 scripts, each with its path and the digest of its content;
  • 8 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data and Code Availability

Custom code associated with this manuscript is available via our GitHub (https://github.com/Kriaese/manuscript-zoomprf) repository (Stoll et al., 2026a). Data associated with this manuscript including data produced by executing the custom code are available via our OpenNeuro (https://openneuro.org/datasets/ds006128) repository (Stoll et al., 2026c). These repositories are linked components of our Open Science Framework (OSF (https://osf.io/4drz6/overview)) repository (Stoll et al., 2026b) that contains general instructions for repository usage and preparatory steps (see README.md). The OSF (https://osf.io/4drz6/overview) repository also hosts additional materials, such as the figures and videos presented in this manuscript.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 28 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 7 authors, 10 keywords, 4 funders, 94 references.

Cite

This paper

Stoll, S., Luesebrink, F., Schwarzkopf, D. S., Mattern, H., Liu, P., Noelle, J., & Kuehn, E. (2026). Modeling 2D spatio-tactile population receptive fields of the fingertip in human primary somatosensory cortex. Imaging neuroscience (Cambridge, Mass.), 4, IMAG.a.1210. https://doi.org/10.1162/imag.a.1210

BibTeX

@article{stoll2026modeling,
author = {Stoll, Susanne and Luesebrink, Falk and Schwarzkopf, D Samuel and Mattern, Hendrik and Liu, Peng and Noelle, Johanna and Kuehn, Esther},
title = {{Modeling 2D spatio-tactile population receptive fields of the fingertip in human primary somatosensory cortex}},
journal = {Imaging neuroscience (Cambridge, Mass.)},
year = {2026},
month = may,
volume = {4},
pages = {IMAG.a.1210},
publisher = {MIT Press},
issn = {2837-6056},
doi = {10.1162/imag.a.1210},
url = {https://doi.org/10.1162/imag.a.1210},
pmid = {42212224},
pmcid = {PMC13214571}
}

RIS

TY - JOUR
AU - Stoll, Susanne
AU - Luesebrink, Falk
AU - Schwarzkopf, D Samuel
AU - Mattern, Hendrik
AU - Liu, Peng
AU - Noelle, Johanna
AU - Kuehn, Esther
TI - Modeling 2D spatio-tactile population receptive fields of the fingertip in human primary somatosensory cortex
T2 - Imaging neuroscience (Cambridge, Mass.)
J2 - Imaging Neurosci (Camb)
PY - 2026
DA - 2026/05/26
VL - 4
SP - IMAG.a.1210
SN - 2837-6056
PB - MIT Press
DO - 10.1162/imag.a.1210
UR - https://doi.org/10.1162/imag.a.1210
LA - en
ER -

CSL-JSON

{
"id": "10.1162/imag.a.1210",
"type": "article-journal",
"title": "Modeling 2D spatio-tactile population receptive fields of the fingertip in human primary somatosensory cortex",
"container-title": "Imaging neuroscience (Cambridge, Mass.)",
"author": [
{
"family": "Stoll",
"given": "Susanne"
},
{
"family": "Luesebrink",
"given": "Falk"
},
{
"family": "Schwarzkopf",
"given": "D Samuel"
},
{
"family": "Mattern",
"given": "Hendrik"
},
{
"family": "Liu",
"given": "Peng"
},
{
"family": "Noelle",
"given": "Johanna"
},
{
"family": "Kuehn",
"given": "Esther"
}
],
"container-title-short": "Imaging Neurosci (Camb)",
"volume": "4",
"page": "IMAG.a.1210",
"DOI": "10.1162/imag.a.1210",
"PMID": "42212224",
"PMCID": "PMC13214571",
"ISSN": "2837-6056",
"publisher": "MIT Press",
"URL": "https://doi.org/10.1162/imag.a.1210",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
26
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.7554/elife.108408 [code]
Frequency and laminar profile of feature-specific visual activity revealed by interleaved EEG-fMRI.
Journal: eLife
In common: ANTs, FreeSurfer, SPM, 2 other tools, systems, fMRI, 5 references
[2] doi:10.1016/j.neuron.2026.04.011 [code]
Precision fMRI reveals densely interdigitated network patches with conserved motifs in the lateral prefrontal cortex.
Journal: Neuron
In common: ANTs, Parallel Computing Toolbox, FreeSurfer, 3 other tools, systems, fMRI, 3 references
[3] doi:10.1371/journal.pcbi.1014434 [code]
Non-invasive mapping of the temporal processing hierarchy in the human visual cortex.
Journal: PLoS computational biology
In common: systems, fMRI, 7 references
[4] doi:10.1371/journal.pcbi.1014563 [code]
Single pulse electrical stimulation in white matter modulates iEEG visual responses in human early visual cortex.
Journal: PLoS computational biology
In common: ANTs, Parallel Computing Toolbox, FreeSurfer, 3 other tools, systems, 2 references
[5] doi:10.1038/s41467-026-71151-2 [code]
Common and distinct neural correlates of social interaction processing and theory of mind in narratives.
Journal: Nature communications
In common: ANTs, Parallel Computing Toolbox, FreeSurfer, 3 other tools, 2 references
[6] doi:10.1162/imag.a.1222 [code]
Network-based near-scalp personalized brain stimulation targets.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: ANTs, FreeSurfer, SPM, 2 other tools, systems, 2 references
[7] doi:10.1038/s41598-026-58377-2 [code]
A novel distortion-matched anatomical imaging sequence for high-fidelity functional mapping in submillimeter-resolution fMRI.
Journal: Scientific reports
In common: FreeSurfer, Image Processing Toolbox, fMRI, 4 references
[8] doi:10.1016/j.celrep.2026.117404 [code]
Action and rest tremor map to distinct networks within the primary motor cortex.
Journal: Cell reports
In common: ANTs, Parallel Computing Toolbox, FreeSurfer, 3 other tools, systems
[9] doi:10.1038/s41593-026-02359-0 [code]
The cross-site reproducibility of MRI morphometric phenotypes in psychiatric disorders.
Journal: Nature neuroscience
In common: FreeSurfer, SPM, Image Processing Toolbox, 1 other tool, 4 references
[10] doi:10.1162/imag.a.1262 [code]
Frame-wise multi-echo distortion correction for superior functional MRI.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Parallel Computing Toolbox, FreeSurfer, SPM, 2 other tools, fMRI, 2 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.