14.2.1. Yoon et al. (2026). Exclusive ipsilateral representation of sequential tactile differences …

Introduction

Here we present commands used in the following paper:

Abstract: Tactile perception is traditionally attributed to contralateral somatosensory (S1) processing, yet the functional role of ipsilateral S1 in human tactile discrimination remains unclear. Using fMRI during a sequential vibrotactile discrimination task, we examined how frequency information is represented when participants judged which of two successive stimuli delivered to the same fingertip was higher in frequency. Contralateral S1 showed robust activation, and ipsilateral S1 showed suppression during unilateral stimulation; however, linear mixed-effects analyses revealed reliable frequency-dependent modulation in ipsilateral S1, which was absent when no comparison was required. Multivariate representational analyses further demonstrated that fMRI activity patterns representing the differences between successive stimuli were strengthened under memory demands, particularly within ipsilateral S1 and parietal cortices. Furthermore, the representational separability predicted individual discrimination accuracy. The exclusive representation in the ipsilateral S1 was not hand-specific; that is, the results were consistent for both hands, indicating a bilateral and symmetric encoding scheme. These surprising findings demonstrate that the ipsilateral, not contralateral, S1 contributes to tactile discrimination, challenging classic contralateral models of somatosensory processing. These unprecedented findings highlight interhemispheric coordination as a key mechanism underlying perceptual decisions.

Main programs: dcm2niix_afni, afni_proc.py, 3dLMEr

Download scripts

To download, either:

  • ... click the link(s) in the following table (perhaps Rightclick -> “Save Link As…”):

    s1.convert_DICOM.zsh

    run dcm2niix_afni to convert DICOMs to NIFTI volumes

    s2-i.create_proc_M.zsh

    run afni_proc.py for full single subject processing

    s3.lme_freq_1.sh

    run 3dLMEr for group-level analysis

    s4.lme_freq_2.sh

    run 3dLMEr for group-level analysis

  • ... or copy+paste into a terminal:

    curl -O https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/codex/fmri/media/2026_YoonEtal/s1.convert_DICOM.zsh
    curl -O https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/codex/fmri/media/2026_YoonEtal/s2-i.create_proc_M.zsh
    curl -O https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/codex/fmri/media/2026_YoonEtal/s3.lme_freq_1.sh
    curl -O https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/codex/fmri/media/2026_YoonEtal/s4.lme_freq_2.sh
    

Additional code availability:
The authors’ code is also available here, including the datatable files used in the 3dLMEr commands here:

View scripts

The scripts shown here contain full examples of the per-subject commands created by the above GitHub repository’s Python implementation.

s1.convert_DICOM.zsh

 1#!/bin/zsh
 2
 3# run dcm2niix_afni to convert DICOMs to NIFTI volumes
 4# 
 5# This is an example of running dcm2niix_afni to convert raw DICOM
 6# files into NIfTI format and organize structural and functional data.
 7#
 8# Execution: 
 9# 
10#     zsh s1.convert_DICOM.zsh -s TMN01
11# 
12##############################################################
13
14## Process command line arguments
15while (( $# )); do
16   key="$1"
17   case $key in
18      -s | --subject)
19         subj="$2"
20         shift # Shift twice if the subject is given
21      ;;
22   esac
23   shift ##takes one argument
24done
25
26# Check if subject is set
27if [ -z "$subj" ]; then
28    echo "Error: Subject is not set."
29    echo "Use -s or --subject to specify the subject."
30    exit 1
31fi
32
33##############################################################
34
35dir_root="/mnt/ext4/TMN/fmri_data"
36dir_raw="$dir_root/raw_data/$subj"
37
38dir_output="$dir_raw/convert_data/$subj"
39if [ ! -d "$dir_output" ]; then
40   mkdir -p -m 755 "$dir_output"
41fi
42
43##############################################################
44
45## T1
46dname_T1=$(find "$dir_raw" -type d -name "T1")
47dcm2niix_afni                                       \
48   -a y -o "$dir_output" -f T1.$subj                \
49   "$dname_T1"
50
51## EPI1
52for rr in {1..6}; do
53   dname_E1=$(find "$dir_raw" -type d -name "Nomemory_RUN${rr}")
54   run=$(printf "r%02d" "$rr")
55   dcm2niix_afni                                    \
56      -a y -o "$dir_output" -f func.NM.$run.$subj   \
57      "$dname_E1"
58done
59
60##############################################################
61
62## EPI1 reverse
63dname_ER=$(find "$dir_raw" -type d -name "Reverse")
64dcm2niix_afni                                       \
65    -a y -o "$dir_output" -f func.REV.$subj         \
66    "$dname_ER"
67
68## EPI2
69for rr in {1..6}; do
70   dname_E2=$(find "$dir_raw" -type d -name "memory_RUN${rr}")
71   run=$(printf "r%02d" "$rr")
72   dcm2niix_afni                                    \
73      -a y -o "$dir_output" -f func.M.$run.$subj    \
74      "$dname_E2"
75done

s2-i.create_proc_M.zsh

  1#!/bin/zsh
  2
  3# run afni_proc.py to perform full single subject regression
  4# 
  5# This script demonstrates how to construct a single subject
  6# afni_proc.py pipeline for the memory condition including EPI
  7# distortion correction and nonlinear standard space
  8# registration. Running this script automatically creates an
  9# afni_proc.py directory and generates the proc.TMN01 execution script
 10# inside it.
 11# 
 12# Execution: 
 13#    
 14#    zsh s2-i.create_proc_M.zsh -s TMN01
 15# 
 16# The above command creates proc.TMN01. This is the generated
 17# execution script running the full preprocessing steps for one
 18# subject.  It is then executed, for example, with:
 19#
 20#    tcsh -xef proc.TMN01 |& tee output.proc.TMN01
 21#
 22#
 23## ==================================================== ##
 24
 25## $# = the number of arguments
 26while (( $# )); do
 27   key="$1"
 28   case $key in
 29      -s | --subject)
 30         subj="$2"
 31      ;;
 32   esac
 33   shift ##takes one argument
 34done
 35
 36## ==================================================== ##
 37
 38dir_root="/mnt/ext4/TMN/fmri_data"
 39dir_raw="$dir_root/raw_data/$subj"
 40dir_nifti="$dir_raw/convert_data/$subj"
 41dir_preproc="$dir_root/preproc_data/M/$subj"
 42
 43dir_script="/home/harry/TM_pj/Experiment/afni_proc.py"
 44if [ ! -d "$dir_script" ]; then
 45   mkdir -p -m 755 "$dir_script"
 46fi
 47
 48dir_output="$dir_preproc"
 49
 50## ==================================================== ##
 51
 52dsets=($(find "$dir_nifti" -type f -name "func.M.r??.$subj.nii" | sort))
 53
 54## ==================================================== ##
 55
 56cd "$dir_script"  # Only if needed; otherwise, remove this line
 57
 58# Notes on options, for resting state FMRI processing
 59#
 60# + blip up/down (=reverse phase-encoded) datasets are used to reduce 
 61#   distortion due to B0 inhomogeneity
 62# + LFF-based bandpassing is _not_ used, to preserve degrees of freedom
 63# + while typically the lpc+ZZ cost function is used to align the EPI and 
 64#   anatomical datasets, in this case the lpa cost function performed well
 65# + nonlinear alignment and anatomical skullstripping are both
 66#   performed within this command, but these could be done beforehand
 67#   with sswarper2, passing the results to afni_proc.py
 68
 69afni_proc.py                                                                 \
 70    -subj_id                  "$subj"                                        \
 71    -out_dir                  "$dir_output"                                  \
 72    -blocks                   despike tshift align tlrc volreg blur mask     \
 73                              scale regress                                  \
 74    -copy_anat                "$dir_nifti/T1.$subj.nii"                      \
 75    -anat_has_skull           yes                                            \
 76    -anat_uniform_method      unifize                                        \
 77    -anat_unif_GM             yes                                            \
 78    -dsets                    $dsets                                         \
 79    -radial_correlate_blocks  tcat volreg                                    \
 80    -tcat_remove_first_trs    0                                              \
 81    -blip_forward_dset        "$dir_nifti/func.M.r01.$subj.nii"              \
 82    -blip_reverse_dset        "$dir_nifti/func.REV.$subj.nii"                \
 83    -align_opts_aea           -cost lpa                                      \
 84                              -giant_move                                    \
 85                              -check_flip                                    \
 86    -tlrc_NL_warp                                                            \
 87    -tlrc_base                MNI152_2009_template_SSW.nii.gz                \
 88    -volreg_align_to          MIN_OUTLIER                                    \
 89    -volreg_align_e2a                                                        \
 90    -volreg_tlrc_warp                                                        \
 91    -blur_size                4.0                                            \
 92    -mask_epi_anat            yes                                            \
 93    -regress_motion_per_run                                                  \
 94    -regress_censor_motion    0.4                                            \
 95    -regress_censor_outliers  0.05                                           \
 96    -regress_apply_mot_types  demean deriv                                   \
 97    -html_review_style        pythonic
 98#   -execute  # Uncomment if you want to run it immediately
 99
100#echo $dsets
101#echo "Directory NIFTI: $dir_nifti"
102#echo "Datasets: $dsets"

s3.lme_freq_1.sh

 1#!/bin/bash
 2
 3# run 3dLMEr for group-level linear mixed effects analysis modeling
 4# the continuous frequency variable with random intercepts.
 5#
 6# The model (-model "Freq+(1|Subj)+(1|Subj:Run)") is designed to
 7# control for random effects across individual subjects and specific
 8# runs, while -gltCode is used to explicitly extract the main linear
 9# effect of the frequency.
10
11# ============================================================================
12
13p1=/mnt/ext4/TMN/fmri_data/preproc_data/M/TMN
14
153dLMEr                                                                       \
16    -prefix     output_LME_1_fin.nii                                         \
17    -jobs       16                                                           \
18    -model      "Freq+(1|Subj)+(1|Subj:Run)"                                 \
19    -qVars      'Freq'                                                       \
20    -gltCode    'Freq_effect' 'Freq :'                                       \
21    -mask       ${p1}/full_mask.group.M.nii                                  \
22    -dataTable  @newDataTable_fin_SK.txt

s4.lme_freq_2.sh

 1#!/bin/bash
 2
 3# run 3dLMEr for group-level linear mixed effects analysis modeling
 4# the continuous frequency variable with random intercepts.
 5#
 6# This script runs a parallel 3dLMEr analysis (to s3*.sh) using an
 7# alternative input data table structure for comparative evaluation,
 8# applying the same model specifications as in the other 3dLMEr command.
 9
10# ============================================================================
11
12p1=/mnt/ext4/TMN/fmri_data/preproc_data/M/TMN
13
143dLMEr                                                                       \
15    -prefix     output_LME_2.nii                                             \
16    -jobs       16                                                           \
17    -model      "Freq+(1|Subj)+(1|Subj:Run)"                                 \
18    -qVars      'Freq'                                                       \
19    -gltCode    'Freq_effect' 'Freq :'                                       \
20    -mask       ${p1}/full_mask.group.M.nii                                  \
21    -dataTable  @newDataTable_fin_SK_2.txt