-
Notifications
You must be signed in to change notification settings - Fork 1
fMRI Fear Conditioning FSL Analysis Pipeline
To detail the fMRI Fear Conditioning (version3/design3 only) FSL Feat Analysis process and scripts. Analyses were run on run1 only by MQ but scripts will be analogous for run2 reversal if someone were to set them up. The fMRI fear conditioning paradigm is detailed in the wiki "fMRI Fear Conditioning Paradigm" and the model design themselves are detailed in the wiki "Fear Conditioning Model Overview".
Various FSL feat models (mini-block, linear, split half cue and outcome) were run with the main contrast of interest being activation to aversive face when scream is absent relative to neutral face (CS+u > CS-) or the inverse (CS- > CS+u), as is consistent with most fear conditioning literature. See the "Fear Conditioning Model Overview" wiki for more details on how these models were set up.
For more information on FSL feat in general see "FSL Feat wiki"
Final statistical testing was done using FSL randomise (see: "FSL Randomise Wiki")
Script: /data/joy/BBL/projects/conteReproc2017/fearConditioningRun1/design3_run_feat.sh
Requires:
- Subject list in the form of a text file (list of bblid/datexscanid)
Example: bblid/datexscanid - Templates for the model (template design.fsf which will be populated with subject-specific information)
Example:/import/monstrum/conte_815814/scripts/functional/fsf_templates/order1_3_run1_linear_mini_block_design.fsf
- Biascorrected brain output (either from ANTs or a different pipeline)
/data/joy/BBL/studies/conte/processedData/structural/conte_design3_n118_structural_201706051547/$bblid/*$scanid/antsCT/BrainSegmentation0N4.nii.gz
Output:
- Subject-level feat output
Script: /data/joy/BBL/projects/conteReproc2017/fearConditioningRun1/design3_run_feat.sh
-
For each subject in the list, create variables for their fear conditioning order and the subject's scanid and bblid
for i in `cat /data/joy/BBL/studies/conte/subjectData/design3InclusionsSubjectListFslFeat.txt`; do bblid=`echo $i | cut -d "," -f 1` scanid=`echo $i | cut -d "," -f 2` order=`echo $i | cut -d "," -f 3`
-
Create a variable for the design template and task depending on what order the subject is in
#if the subject is order 1_3 and you chose to run run1 then run the following feat design (the one commented in) template if [ $order == "1_3" ]; then fsf1=/import/monstrum/conte_815814/scripts/functional/fsf_templates/order1_3_run1_linear_mini_block_design.fsf #fsf1=/import/monstrum/conte_815814/scripts/functional/fsf_templates/order1_3_run1_linear.fsf #fsf1=/import/monstrum/conte_815814/scripts/functional/fsf_templates/order1_3_run1_split_half_sec1_sec5.fsf task=fearcondV3R1 fi #if the subject is order 0_2 and you chose to run run1 then run the following feat design (the one commented in) template if [ $order == "0_2" ]; then fsf1=/data/joy/BBL/studies/conte/fmriDesignFiles/order0_2/run1/fsf_templates/order0_2_run1_linear_mini_block_design.fsf #fsf1=/data/joy/BBL/studies/conte/fmriDesignFiles/order0_2/run1/fsf_templates/order0_2_run1_linear.fsf #fsf1=/data/joy/BBL/studies/conte/fmriDesignFiles/order0_2/run1/fsf_templates/order0_2_run1_split_half_sec1_sec5.fsf task=fearcondV3R1 fi #create a temp design.fsf which will hold subject specific data to replace the standard template for feat temp1=/data/joy/BBL/studies/conte/fmriDesignFiles/order0_2/run1/fsf_templates/${task}_temp1.fsf
-
Create a variable for how you want the feat output to be called in the subject's directory
suffix1=bbr_linear_mini_block.feat
-
Print to the screen the subject and order and create a variable for the subject's functional nifti image, print it to the screen and if one doesn't exist print an error and move to the next subject
echo $scanid echo $order #create a variable for the subject's functional nifti image, print it to the screen and if one doesn't exist print an error and move to the next subject func=$(ls /data/joy/BBL/studies/conte/rawData/$bblid/*$scanid/*${task}*/nifti/*fearcond*.nii.gz 2>/dev/null) echo $func if [ -z $func ]; then echo "no functional image" continue fi
-
Remove the nii.gz appendage from the file name and append the suffix you chose above for the output name then print that to the screen
func=$(echo $func | sed "s+.nii.gz++g") feat1=${func}_${suffix1} echo $feat1
-
Do the same for the subject's biascorrected structural image and then remove the .nii.gz appendage
#create a variable for the subject's biascorrected structural image, print it to the screen and if one doesn't exist print an error and move to the next subject mprage=$(ls /data/joy/BBL/studies/conte/processedData/structural/conte_design3_n118_structural_201706051547/$bblid/*$scanid/antsCT/BrainSegmentation0N4.nii.gz 2>/dev/null) if [ -z $mprage ]; then echo "no bias corrected mprage" continue fi #remove the nii.gz appendage from the file name and print that file name to the screen mprage=$(echo $mprage | sed "s+.nii.gz++g") echo $mprage
-
Copy the design template to the temp file created above
#print to the screen which feat design will be run echo $fsf1 #copy the design template to the temp file created above cp $fsf1 $temp1
-
Replace the standard template "fillers" with the subject specific paths to the output directory, functional image, and mprage image
sed -i "s|###OUTPUT###|$feat1|g" "$temp1" echo "$temp1" sed -i "s|###NIFTI###|$func|g" "$temp1" sed -i "s|###STRUCT###|$mprage|g" "$temp1"
-
Run the feat design for that subject
feat $temp1
Script: /data/joy/BBL/projects/conteReproc2017/fearConditioningRun1/conte_merge_images_mask.sh
Requires:
- Subject list in the form of a text file (list of bblid/datexscanid)
Example: bblid/datexscanid - Standardized stats output from feat for each subject in the list
Example: ``
Output:
- Merged registered copes (with as many volumes as subjects in your list)
``
Run the script first with the following parameters:
copes="cope1"
maskflag=1
Then after the first cope is merged and the mask if created, change it to maskflag=0 and copes="cope2 ..." with as many copes as your feat output has and you wish to merge. This is so you don't spend extra time and space to merge the mask each time you merge a cope. You don't need the mask to merge 32 identical times, just once.
Script: /data/joy/BBL/projects/conteReproc2017/fearConditioningRun1/conte_merge_images_mask.sh
-
Create a variable for the subject list you pass it, the path to where the output images will go, and the suffix of the feat you wish to merge images from
scanids=$(cat /data/joy/BBL/studies/conte/subjectDatadesign3InclusionsSubjectListFslFeat.txt) outdir=/data/joy/BBL/studies/conte/subjectData/fearConditioningRun1/merged_copes/ #the suffix of the feat which you want to merge images from nickname="bbr_linear_mini_block" feat=$nickname.feat
-
Select the copes you have in your feat output and wish to merge and the run of the data you wish to merge (V3R1 is run=1). Note the information above on running the script first with copes=1 and maskflag=1.
#variables for the level1 feat copes to merge-- can be multiple copes e.g., "cope1 cope2 cope3 cope7" #Note you'll see cope1 is separate in many so that cope1 can be run and merged with the maskflag set to 1, then can be commented out and the rest of the copes can be run without the mask flag to speed things up #copes="cope1" copes="cope2 cope3 cope4 cope5 cope6 cope7 cope8 cope9 cope10 cope11 cope12" mask="mask" varcopeflag=1 #if=1, also will merge varcopes maskflag=0 # if =1, also will merge masks run=1 #the fear conditioning run you are merging (run1 or run2 reversal)
-
Create a variable for the output log directory and remove any existing logs
logdir=/data/joy/BBL/projects/conteReproc2017/fearConditioningRun1/logs ####### #remove any existing log file for missing copes rm -f $logdir/conte_missing_copes_for_merge.txt
-
Print out which feat will be merged and the number of subjects to merge
echo "feat is $feat" nsubj=$(echo $scanids | wc | awk '{print $2}') echo "$nsubj subjects" echo "*********"
-
For each cope in the list, print out the cope and remove any existing cope and varcope lists
for c in $copes; do echo "" echo "" echo "********************" echo "now working on $c" echo "********************" rm -f copelist_tmp.txt rm -f varcopelist_tmp.txt
-
For each subject print out the scanid, and create a variable which gets the fear conditioning standardized cope image for each subject
for b in $scanids; do echo "" echo $b #create a variable which gets the fear conditioning standardized cope image for each subject image=$(ls -d /data/joy/BBL/studies/conte/processedData/$bblid/*$scanid/*V3R${run}*/nifti/*SEQ*${feat}/reg_standard/stats/${c}.nii.gz) #if that image doesn't exist then output an error and append it to the error text file if [ -z "$image" ]; then echo "COPE MISSING" echo -e"$b \t $c" >> $logdir/conte_missing_copes_for_merge.txt exit 1 fi #if it does exist print the path and output to a cope list echo $image echo $image >> copelist_tmp.txt
-
Create a variable which gets the fear conditioning standardized varcope image for each subject
#if you should also merge varcopes then if [ "$varcopeflag" == 1 ]; then echo "merging varcopes also" #create a variable which gets the fear conditioning standardized varcope image for each subject varimage=$(ls -d /data/joy/BBL/studies/conte/processedData/$bblid/*$scanid/*V3R${run}*/nifti/*SEQ*${feat}/reg_standard/stats/var${c}.nii.gz) #if that image doesn't exist then output an error and append it to the error text file if [ -z "$varimage" ]; then echo "VARCOPE MISSING" echo -e"$b \t var${c}" >> $logdir/conte_missing_copes_for_merge.txt exit 1 fi #if it does exist print the path and output to a varcope list echo $varimage echo $varimage >> varcopelist_tmp.txt fi
-
Create a variable which gets the fear conditioning standardized mask image for each subject
#if the mask flag is set to 1 then if [ "$maskflag" == 1 ]; then echo "merging masks also" #create a variable which gets the fear conditioning standardized mask image for each subject maskimage=$(ls -d /data/joy/BBL/studies/conte/processedData/$bblid/*$scanid/*V3R${run}*/nifti/*SEQ*${feat}/reg_standard/mask.nii.gz) #if that image doesn't exist then output an error and append it to the error text file if [ -z "$maskimage" ]; then echo "MASK MISSING" echo -e"$b \t mask" >> $logdir/conte_missing_copes_for_merge.txt exit 1 fi #if it does exist print the path and output to a mask list echo $maskimage echo $maskimage >> masklist_tmp.txt fi done
-
Print the number of subjects to be merged for copes and merge the copes in the cope list for each subject
echo "" echo "********************" echo "now merging $nsubj images for $c" #merge the copes in the cope list for each subject fslmerge -t ${outdir}/n${nsubj}_${nickname}_run${run}_${c} $(cat copelist_tmp.txt)
-
If you have the varcope flag set to equal 1 (varcopeflag=1) then do the same for the varcopes
#if varcope is set to 1 then if [ "$varcopeflag" == 1 ]; then #print the number of subjects to be merged for varcopes echo "" echo "now merging $nsubj images for var${c}" #merge the varcopes in the varcope list for each subject fslmerge -t ${outdir}/n${nsubj}_${nickname}_run${run}_var${c} $(cat varcopelist_tmp.txt) echo "********************" fi
-
If you have the mask flag set to equal 1 (maskflag=1) then do the same for the mask
#if mask is set to 1 then if [ "$maskflag" == 1 ]; then #print the number of subjects to be merged for the mask echo "" echo "now merging $nsubj images for mask" #merge the masks in the mask list for each subject and binarize the mask and get overlap fslmerge -t ${outdir}/n${nsubj}_mask $(cat masklist_tmp.txt) fslmaths ${outdir}/n${nsubj}_mask -Tmin -bin -mas /import/monstrum/Applications/fsl5/data/standard/MNI152_T1_2mm_brain_mask ${outdir}/${nickname}"_n"${nsubj}"_run"${run}"_final_maskoverlap" echo "********************" fi done
-
Print the output directory to the screen (after removing the lists of copes, etc. that you merged)
rm -f copelist_tmp.txt rm -f varcopelist_tmp.txt rm -f masklist_tmp.txt echo "output at ${outdir}/n${nsubj}_${nickname}_run${run}_${c}"
For more information on group-level feats by flame1 see the FSL Higher Level Feat Output wiki
Script: /data/joy/BBL/projects/conteReproc2017/fearConditioningRun1/group_flameo_conte_nogrid.sh
Requires:
- Merged cope output for all subject you wish to include in your group-level feat (by conte_merge_images_mask.sh)
- Example ``
Output:
- Group-level/Higher-level feat output for the model you run
- Example
/data/joy/BBL/studies/conte/processedData/fearconditioningRun1/single_group_level_feats/single_group_linear_mini_block_n110
- Example
Script: /data/joy/BBL/projects/conteReproc2017/fearConditioningRun1/group_flameo_conte_nogrid.sh
-
Create a variable for the number of subjects you want to include in your group-level feat, and for the output path
nsubj=n110 #eg n61 #create a variable for the path to where the output images will go and where the design files exist wd=/data/joy/BBL/studies/conte/processedData/fearconditioningRun1/single_group_level_feats/single_group_linear_mini_block_${nsubj}
-
Create a variable which gets the full list of copes you wish to include in your group-level output
#variables for the level1 feat copes ----can be multiple copes e.g., "cope1 cope2 cope3 cope7" copes="cope1 cope2 cope3 cope4 cope5 cope6 cope7 cope8 cope9 cope10 cope11 cope12"
-
Create a variable for the suffix of the feat which you want to run flame1 (group-level feat) on
nickname="bbr_linear_mini_block"
-
Print out the working directory and feat name and if the working directory doesn't exist then exit the script
echo "working directory is $wd" echo "" echo "nickname is $nickname" echo "" if [ ! -d "$wd" ]; then echo "working directory not found!! exiting!" exit 1 fi echo "*********" echo "for all analyses, lev2 cope is $lev2_cope" echo "*******"
-
For each cope in the list defined above (by variable "copes"), create variables for the merged cope, varcope, and mask files created by the conte_merge_images_mask.sh script
for c in $copes; do echo "" echo "working on $c" #create variables for the merged cope, varcope, and mask files created by the conte_merge_images_mask.sh script cfile=$(ls -d /data/joy/BBL/studies/conte/subjectData/fearConditioningRun1/merged_copes/${nsubj}_${nickname}_run${run}_${c}.nii.gz) vfile=$(ls -d /data/joy/BBL/studies/conte/subjectData/fearConditioningRun1/merged_copes/${nsubj}_${nickname}_run${run}_var${c}.nii.gz) mask=/data/joy/BBL/studies/conte/subjectData/fearConditioningRun1/merged_copes/${nickname}_${nsubj}_run${run}_final_maskoverlap.nii.gz
-
Create variable for output dir within working directory defined above and the cope number appended
outdir=${nickname}_${nsubj}_${c} #create a variable for the outpath directory outpath=$(ls -d $wd/$outdir 2> /dev/null)
-
Run flameo on the cope, varcope, mask specified with the design files in the working directory
flameo --cope=$cfile --varcope=$vfile --mask=$mask --dm=${wd}/design.mat --tc=${wd}/design.con --cs=${wd}/design.grp --runmode=flame1 --logdir=${wd}/${outdir} --npo done
FSL Randomise was run using the output from the mini-block models detailed above. These were the models that showed the most robust results for the CONTE study and therefore they were utilized for the final analyses for the fear conditioning run1 Quarmley et. al manuscript. Randomise was run several different ways including voxelwise however detailed below is the 3-ROI-mask method that was utilized for the paper as it showed the most robust results.
- Make a 3 ROI merged mask of the vmPFC, bilateral amygdala, and bilateral anterior insula neurosynth ROIs detailed above. This was done by running fslmaths -add and merging the three ROI masks together. This mask is saved here:
``
- Run randomise with the following parameters:
-
threshold-free cluster enhancement (-T)
-
5,000 permutations (-n 5000)
-
the 3 ROI mask made in the previous step (-m [mask path])
-
A merged subject-level cope (-i [4D image]) (the example below uses mini block cope11 for all 96 version3 included subjects merged together)
-
A design matrix which is simply the same as a higher-level feat design matrix.
/NumWaves 1 /NumPoints 96 /PPheights 1.000000e+00 /Matrix 1 1 1 1 1 1 ....96 times
-
A contrast matrix which in this example below is two-sided so that you will obtain output in both the positive (CS+u > CS-) and negative (CS+u < CS-) directions
/ContrastName1 group mean /ContrastName2 group mean negative /NumWaves 1 /NumContrasts 2 /PPheights 1 /RequiredEffect 0.484 /Matrix 1 -1
The template for randomise is:
randomise -i <4D input image> -o <output file-rootname> -d <design.mat> -t <design.con> [options]
An example run from monstrum with the parameters detailed above:
randomise -i /import/monstrum/conte_815814/group_results/merged_images/n96_bbr_linear_mini_block_run1_cope11.nii.gz -o /import/monstrum/conte_815814/group_results/randomise/fmri_paper_2017/cope11_3roi_merge_03212017 -d /import/monstrum/conte_815814/group_results/run1/single_group_level_feats/all_subj_single_group_level_feats/single_group_all_subj_linear_mini_block_run1_n96/design.mat -t /import/monstrum/conte_815814/group_results/randomise/design_2tail.con -m /import/monstrum/conte_815814/scripts/functional/roi_merge_masks/3roi_merge_fmri_paper_03312017 -n 5000 -T