#!/bin/tcsh -f # recon-all-nmr - script to run all of the reconstruction routines # recon-all - script to run all of the reconstruction routines # # NOTE! This file is under revision control. Make sure to use # the appropriate checkin-checkout procedures when making # modifications # # NOTE! the script called recon-all is created from this script # by filtering out all the lines with the string dASEGd: # cat recon-all-nmr | grep -v dASEGd > recon-all # # Author: Douglas N. Greve, MGH-NMR, greve@nmr.mgh.harvard.edu # umask 002; set VERSION = '$Id: recon-all-nmr,v 1.72 2005/07/12 15:56:32 greve Exp $'; # MNI tool requires the following setenv LANG C setenv FS_ENABLE_AUTOSEG 1 set ProgName = `basename $0`; set inputargs = ($argv); set subjid = (); set hemilist = (rh lh); set mailuser = (); set WaitForFile = (); set nWaitsMax = 1000; set WaitSleep = 1m; set NotifyFile = (); set MGZ = (); set PrintHelp = 0; set LF = (); set SF = (); set CF = (); set AppendLog = 1; set AppendStatus = 1; set UseCOR = 0; # Expert preferences set ControlPointsFile = (); set SegKeepWMEdits = 0; # Keep wm edits when segmenting set FillPonsXYZ = (); # XYZ center of pons for mri_fill # set FillCCXYZ = (); # XYZ center of corpus callosum for mri_fill # set FillRHXYZ = (); # XYZ point in the right hemi wm for mri_fill # set FillLHXYZ = (); # XYZ point in the left hemi wm for mri_fill # set FillWithASeg = 0; # Use ASeg when filling set WaterShed = 1; # 0=no WS, 1= WS normal, 2 = WS only, 3 = WS+1st set WSLess = 0; # Shrinks skull surface set WSMore = 0; # Expands skull surface set WSPctPreFlood = (); # Pre-flooding height set WSSeedPoint = (); # C R S set WSAtlas = 0; # Use an atlas set NuIterations = 4; # Number of iterations for nu intensity correction set HiRes = ''; # hires option (currently only conformed to min) set Norm3dIters = 0; # passed as -n to mri_normalize # For subcortical segmentation set GCA = $FREESURFER_HOME/average/talairach_mixed.gca set GCA_TL = (); # For cortical parcellation # set CPAnnotTable = $FREESURFER_HOME/Simple_surface_labels2002.txt # Set this to 0 to do everything but run the command. # This is good for debugging. set RunIt = 1; # Set this to keep volumes and surfaces that would # normally be overwritten in the editing/recon # process. set SvInit = 0; set SvInitInflated = 0; #----- Volume -----------# set DoMotionCor = 0; set DoTalairach = 0; set DoNuIntensityCor = 0; set UseNuIntensityCor = 0; # Use nu as input to inorm set DoNormalization = 0; set DoNormalization2 = 0; set UseControlPoints = 0; set DoSkullStrip = 0; set DoSegmentation = 0; set DoGCAReg = 0; set DoCANormalize = 0; set DoCAReg = 0; set DoCALabel = 0; set EditWMwithASeg = 0; set DoFill = 0; #----- Surface -----------# set DoTessellate = 0; set SvInitOrigSurf = 0; set DoSmooth1 = 0; set DoInflate1 = 0; set DoQSphere = 0; set DoFix = 0; set FixWithGA = 1; set DoEuler = 0; set DoSmooth2 = 0; set DoInflate2 = 0; set DoSphere = 0; set DoSurfReg = 0; set DoContraSurfReg = 0; set DoAvgCurv = 0; set DoAvgLabels = 0; set DoMorphRGB = 0; set DoFinalSurfs = 0; set DoCortParc = 0; set DoParcStats = 0; set DoCortRibbonVolMask = 0; #---- Look at env variable to allow autoseg ----# if(! $?FS_ENABLE_AUTOSEG) setenv FS_ENABLE_AUTOSEG 1 set PWD = pwd; if($#argv == 0) goto usage_exit; set n = `echo $argv | egrep -e -help | wc -l` if($n != 0) then set PrintHelp = 1; goto usage_exit; endif set n = `echo $argv | egrep -e -version | wc -l` if($n != 0) then echo $VERSION exit 0; endif goto parse_args; parse_args_return: goto check_params; check_params_return: cd $subjdir # This variable is set in check_params mkdir -p scripts set CF = $subjdir/scripts/recon-all.cmd rm -f $CF # Create the log file # if($#LF == 0) then set LF = ($subjdir/scripts/recon-all.log) if(-e $LF) then if(! $AppendLog) then mv $LF $LF.old else echo "\n\n" >> $LF echo "New invokation of recon-all " >> $LF echo "\n\n" >> $LF endif endif else if(-e $LF) then echo "\n\n" >> $LF echo "New invokation of recon-all " >> $LF echo "\n\n" >> $LF endif endif date >> $LF echo $0 >> $LF echo $inputargs >> $LF $PWD >> $LF echo "subjid $subjid" >> $LF echo "SUBJECTS_DIR $SUBJECTS_DIR" >> $LF echo "FREESURFER_HOME $FREESURFER_HOME" >> $LF echo "AutoSeg Enable = $FS_ENABLE_AUTOSEG" >> $LF uname >> $LF #df . >> $LF ## gather all verisions here echo "########################################" | tee -a $LF echo "program versions used" | tee -a $LF echo $VERSION | tee -a $LF mri_motion_correct2 -version | tee -a $LF talairach2 -version | tee -a $LF set prog = `which nu_correct` strings $prog | grep Id | tee -a $LF mri_normalize --version | tee -a $LF mri_watershed --version | tee -a $LF mri_segment --version | tee -a $LF mri_fill --version | tee -a $LF mri_tessellate --version | tee -a $LF mris_smooth --version | tee -a $LF mris_inflate --version | tee -a $LF mris_sphere --version | tee -a $LF mris_fix_topology --version | tee -a $LF mris_euler_number --version | tee -a $LF mris_make_surfaces --version | tee -a $LF mris_sphere --version | tee -a $LF mris_register --version | tee -a $LF mrisp_paint --version | tee -a $LF mri_label2label --version | tee -a $LF mris2rgb --version | tee -a $LF mri_em_register --version | tee -a $LF mri_ca_normalize --version | tee -a $LF mri_ca_register --version | tee -a $LF mri_ca_label --version | tee -a $LF echo "#######################################" | tee -a $LF set CSDF = $subjdir/scripts/csurfdir if(-e $CSDF) then set tmp = `cat $CSDF`; if($tmp != $FREESURFER_HOME) then echo "WARNING: current FREESURFER_HOME does not match that of previous processing." | tee -a $LF echo " Current: $FREESURFER_HOME" | tee -a $LF echo " Previous: $tmp" | tee -a $LF sleep 1; endif else echo $FREESURFER_HOME > $CSDF endif # Create the status file # if($#SF == 0) then set SF = $subjdir/scripts/recon-all.status if(-e $SF) then if(! $AppendStatus) then mv $SF $SF.old else echo "\n\n" >> $SF echo "New invokation of recon-all " >> $SF echo "\n\n" >> $SF endif endif else if(-e $SF) then echo "\n\n" >> $SF echo "New invokation of recon-all " >> $SF echo "\n\n" >> $SF endif endif echo "status file for recon-all" >> $SF date >> $SF # Wait for a file to appear # if($#WaitForFile != 0) then echo "Waiting for $WaitForFile" |& tee -a $SF |& tee -a $LF echo " WaitSleep $WaitSleep" |& tee -a $SF |& tee -a $LF echo " nWaitsMax $nWaitsMax" |& tee -a $SF |& tee -a $LF @ nWaits = 1; while(! -e $WaitForFile && $nWaits < $nWaitsMax) sleep $WaitSleep; @ nWaits = $nWaits + 1; end if(! -e $WaitForFile ) then echo "ERROR: timed out waiting for $WaitForFile" goto error_exit; endif echo "Finished Waiting `date`" |& tee -a $SF |& tee -a $LF endif if(! $#MGZ && ! $UseCOR) then # Automatically determine format # If mgzs exist, then assume mgz pushd $subjdir/mri > /dev/null # Look for runs as mgz in orig or orig.mgz set tmp = `ls orig/[0-9][0-9][0-9].mgz >& /dev/null`; if(! $status || -e orig.mgz) set MGZ = .mgz; popd; endif if($#MGZ == 0) echo "Using COR format" |& tee -a $LF if($#MGZ != 0) echo "Using mgz format" |& tee -a $LF #----------- Motion Correct and Average ------------------# if($DoMotionCor && $#MGZ == 0 ) then echo "---------------------------------------------"|& tee -a $LF echo "MotionCor `date`" |& tee -a $SF |& tee -a $LF if(! -e $subjdir/mri/orig) then echo "ERROR: cannot find $subjdir/mri/orig" goto error_exit; endif pushd $subjdir/mri/orig > /dev/null # Get list of input run directories # set RunList = (); set run = 1; set nohit = 0; while($nohit < 100) set runid = `printf %03d $run`; if( -e $runid/COR-.info ) then set RunList = ($RunList $runid); else @ nohit = $nohit + 1; endif @ run = $run + 1; end if($#RunList == 0) then set cor = $subjdir/mri/orig/COR; if( -e $cor-.info && -e $cor-001 && -e $cor-256) then echo "" | tee -a $LF echo "INFO: no runs were found in $subjdir/mri/orig/XXX," | tee -a $LF echo "however, there is a volume in $subjdir/mri/orig,"| tee -a $LF echo "so I am just going to proceed with that as the input."| tee -a $LF sleep 2 else echo "ERROR: no data found in $subjdir/mri/orig" |& tee -a $LF goto error_exit; endif endif if($#RunList == 1) then echo "WARNING: only one run found. This is OK, but motion"|& tee -a $LF echo "correction cannot be performed on one run, so I'll"|& tee -a $LF echo "copy the run to orig and continue."|& tee -a $LF sleep 2s; if($RunIt) cp $RunList/COR* . |& tee -a $LF endif if($#RunList > 1) then #set cmd = (mri_motion_correct . $RunList) # mri_motion_correct is a shell script set cmd = (mri_motion_correct2 ${HiRes} -o . ) foreach run ($RunList) set cmd = ($cmd -i $run) end $PWD |& tee -a $LF echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_motion_correct exited with non-zero status"|& tee -a $LF goto error_exit; endif endif endif # End motion correct with COR # Now handle motion correction with MGZ if($DoMotionCor && $#MGZ != 0 ) then echo "---------------------------------------------"|& tee -a $LF echo "MotionCor `date`" |& tee -a $SF |& tee -a $LF # Get list of input run directories # set RunList = (); set run = 1; set nohit = 0; while($nohit < 100) set runid = `printf %03d $run`; set tmp = $subjdir/mri/orig/$runid.mgz if( -e $tmp ) then set RunList = ($RunList $tmp); else @ nohit = $nohit + 1; endif @ run = $run + 1; end set origvol = $subjdir/mri/orig.mgz set rawavg = $subjdir/mri/rawavg.mgz if($#RunList == 0) then if( -e $rawavg) then echo "" | tee -a $LF echo "INFO: no runs were found in $subjdir/mri," | tee -a $LF echo "however, there is a volume $rawavg,"| tee -a $LF echo "so I am just going to proceed with that as the input."| tee -a $LF sleep 2 else echo "ERROR: no run data found in $subjdir/mri" |& tee -a $LF goto error_exit; endif endif if($#RunList == 1) then echo "WARNING: only one run found. This is OK, but motion"|& tee -a $LF echo "correction cannot be performed on one run, so I'll"|& tee -a $LF echo "copy the run to rawavg and continue."|& tee -a $LF sleep 2s; if($RunIt) cp $RunList $rawavg |& tee -a $LF endif if($#RunList > 1) then set cmd = (mri_motion_correct2 ${HiRes} -o $rawavg ) foreach run ($RunList) set cmd = ($cmd -i $run) end $PWD |& tee -a $LF echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_motion_correct exited with non-zero status"|& tee -a $LF goto error_exit; endif # Now conform to COR FOV (but keep mgz format) set cmd = (mri_convert $rawavg $origvol --conform) $PWD |& tee -a $LF echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_convert exited with non-zero status"|& tee -a $LF goto error_exit; endif endif endif # Motion Correction using MGZ #----------- Nu Intensity Correction ------------------# if($DoNuIntensityCor) then echo "---------------------------------------------"|& tee -a $LF echo "Nu Intensity Correction `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null set incor = orig/COR-.info if($#MGZ) then set incor = orig.mgz else mkdir -p nu endif if(! -e $incor ) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif # Convert orig to minc # set cmd = (mri_convert ${HiRes} orig$MGZ nu0.mnc) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: converting orig to minc" |& tee -a $LF goto error_exit; endif # Run intensity correction # @ nthIter = 1; while($nthIter <= $NuIterations) @ m = $nthIter - 1 set cmd = (nu_correct -clobber nu${m}.mnc nu${nthIter}.mnc) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: nu_correct" |& tee -a $LF goto error_exit; endif if($RunIt) rm -f nu${m}.mnc nu${m}.imp @ nthIter = $nthIter + 1; end # Convert nu back to cor or mgz # set numnc = nu$NuIterations.mnc set cmd = (mri_convert ${HiRes} $numnc nu$MGZ) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: converting nu to COR/mgz" |& tee -a $LF goto error_exit; endif if($RunIt) rm -f nu$NuIterations.*; # Copy the COR-.info from orig to nu to keep transform, etc if(! $#MGZ) cp orig/COR-.info nu/COR-.info endif #----------- Talairach ------------------# if($DoTalairach) then echo "---------------------------------------------"|& tee -a $LF echo "Talairach `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null set incor = orig/COR-.info if($#MGZ) set incor = orig.mgz if(! -e $incor) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif mkdir -p mri/transforms # talairach2 is a shell script set cmd = (talairach2 $subjid $MGZ) $PWD |& tee -a $LF echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: talairach2 exited with non-zero status" |& tee -a $LF goto error_exit; endif endif #----------- Intensity Normalization ------------------# if($DoNormalization) then echo "---------------------------------------------"|& tee -a $LF echo "Intensity Normalization `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null if($UseNuIntensityCor) then set incor = nu$MGZ else set incor = orig$MGZ endif if(! -e $incor/COR-.info && ! $#MGZ) then echo "ERROR: cannot find $incor/COR-.info" |& tee -a $LF goto error_exit; endif if(! $#MGZ) mkdir -p T1 set cmd = (mri_normalize); if($UseControlPoints) set cmd = ($cmd -f $ControlPointsFile) if($Norm3dIters > 0) set cmd = ($cmd -n $Norm3dIters) set cmd = ($cmd $incor T1$MGZ) $PWD |& tee -a $LF echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_normalize exited with non-zero status" |& tee -a $LF goto error_exit; endif if( $RunIt && ! $#MGZ ) then # This cmd must be done on a separate line from the "if", # otherwise it tries to cat the result into the file, which # will fail when MGZ is used. Strange behavior. In other words, # the following command will fail: # if( $RunIt && ! $#MGZ ) echo "$incor" > mri/T1/input-source echo "$incor" > T1/input-source endif endif #----------- Skull Stripping ------------------# if($DoSkullStrip) then echo "---------------------------------------------"|& tee -a $LF echo "Skull Stripping `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null set incor = T1/COR-.info if($#MGZ) then set incor = T1.mgz else mkdir -p brain endif if(! -e $incor) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif $PWD |& tee -a $LF set opts = (); if($WaterShed == 0) set opts = ($opts -n); if($WaterShed == 2) set opts = ($opts -wat); if($WaterShed == 3) set opts = ($opts -wat+temp); if($WaterShed == 4) set opts = ($opts -atlas); if($WSLess) set opts = ($opts -less); if($WSMore) set opts = ($opts -more); if($WSAtlas) set opts = ($opts -atlas); if($#WSPctPreFlood != 0) set opts = ($opts -h $WSPctPreFlood); if($#WSSeedPoint != 0) set opts = ($opts -s $WSSeedPoint); set cmd = (mri_watershed $opts T1$MGZ brain$MGZ) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_watershed exited with non-zero status" |& tee -a $LF goto error_exit; endif endif #-------------- GCA Registration -------------------------# # Input: # Output: talarach.lta if($DoGCAReg) then echo "--------------------------------------"|& tee -a $LF echo "GCARegistration `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null set incor = nu/COR-.info if($#MGZ) set incor = nu.mgz if(! -e $incor) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif if(! $#MGZ) mkdir -p fsamples norm $PWD |& tee -a $LF set cmd = (mri_em_register -mask brain$MGZ -p .5 ) set cmd = ($cmd -fsamples fsamples$MGZ nu$MGZ) set cmd = ($cmd $GCA transforms/talairach.lta) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_em_register with non-zero status" |& tee -a $LF goto error_exit; endif endif #------------ Cannonical Normalization --------------# # Input: # Output: norm if($DoCANormalize) then echo "---------------------------------------"|& tee -a $LF echo "CA Normalize `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null $PWD |& tee -a $LF set cmd = (mri_ca_normalize -mask brain$MGZ nu$MGZ $GCA) set cmd = ($cmd transforms/talairach.lta norm$MGZ) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_ca_normalize with non-zero status" |& tee -a $LF goto error_exit; endif endif #------------ Cannonical Registration --------------# # Input: # Output: transforms/talairach.m3z if($DoCAReg) then echo "---------------------------------------"|& tee -a $LF echo "CA Reg `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null $PWD |& tee -a $LF set cmd = (mri_ca_register -cross-sequence -mask brain$MGZ) set cmd = ($cmd -T transforms/talairach.lta norm$MGZ) set cmd = ($cmd $GCA transforms/talairach.m3z) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_ca_register with non-zero status" |& tee -a $LF goto error_exit; endif endif #-------------- SubCort Segmentation --------------# # Input: # Output: aseg if($DoCALabel) then echo "---------------------------------------"|& tee -a $LF echo "SubCort Seg `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null set incor = brain/COR-.info if($#MGZ) then set incor = brain.mgz else mkdir -p aseg endif if(! -e $incor) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif $PWD |& tee -a $LF set cmd = (mri_ca_label -cross-sequence) set cmd = ($cmd norm$MGZ); set cmd = ($cmd transforms/talairach.m3z $GCA aseg$MGZ); echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_ca_label with non-zero status" |& tee -a $LF goto error_exit; endif endif if($DoNormalization2) then # Intensity norm works better with skull stripped image echo "---------------------------------------------"|& tee -a $LF echo "Intensity Normalization2 `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null if($UseNuIntensityCor) then set incor = nu$MGZ else set incor = orig$MGZ endif if(! -e $incor/COR-.info && ! $#MGZ) then echo "ERROR: cannot find $incor/COR-.info" |& tee -a $LF goto error_exit; endif if(! $#MGZ) mkdir -p T1 set cmd = (mri_normalize); if($UseControlPoints) set cmd = ($cmd -f $ControlPointsFile) set cmd = ($cmd -mask brain$MGZ $incor T1$MGZ) $PWD |& tee -a $LF echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_normalize exited with non-zero status" |& tee -a $LF goto error_exit; endif if( $RunIt && ! $#MGZ ) then echo "$incor" > T1/input-source endif set cmd = (mri_mask T1$MGZ brain$MGZ brain$MGZ) $PWD |& tee -a $LF echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_mask exited with non-zero status" |& tee -a $LF goto error_exit; endif endif #---------------- Segmentation --------------------------# # Input: brain volume # Output: wm volume (copied to wm-init) if($DoSegmentation) then echo "---------------------------------------------"|& tee -a $LF echo "Segmentation `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null set incor = brain/COR-.info if($#MGZ) then set incor = brain.mgz else mkdir -p wm endif if(! -e $incor) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif $PWD |& tee -a $LF set cmd = (mri_segment); if($SegKeepWMEdits) set cmd = ($cmd -keep) set cmd = ($cmd brain$MGZ wm$MGZ) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_segment exited with non-zero status" |& tee -a $LF goto error_exit; endif if($RunIt) then if(! $#MGZ) then cp -R wm wm-init else cp wm.mgz wm-init.mgz endif endif endif # --------Use subcortical segmentation to edit wm volume # Input: wm # Output: wm if($EditWMwithASeg) then echo "---------------------------------------"|& tee -a $LF echo "Editing WM with SubCort Seg `date`" |& tee -a $SF pushd $subjdir/mri > /dev/null set cmd = (mri_edit_wm_with_aseg wm$MGZ aseg$MGZ wm$MGZ) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_edit_wm_with_aseg with non-zero status" |& tee -a $LF goto error_exit; endif endif #---------------- Fill --------------------------# # Input: wm volume # Output: filled volume (copied to filled-init) if($DoFill) then echo "---------------------------------------------"|& tee -a $LF echo "Fill `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null set incor = wm/COR-.info if($#MGZ) then set incor = wm.mgz else mkdir -p filled endif if(! -e $incor) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif set cmd = (mri_fill -a ../scripts/ponscc.cut.log); if($#FillPonsXYZ != 0) set cmd = ($cmd -P $FillPonsXYZ) if($#FillCCXYZ != 0) set cmd = ($cmd -C $FillCCXYZ) if($#FillRHXYZ != 0) set cmd = ($cmd -rh $FillRHXYZ) if($#FillLHXYZ != 0) set cmd = ($cmd -lh $FillLHXYZ) if (-e transforms/talairach.xfm) then echo "INFO: Uses mri/transforms/talairach.xfm" |& tee -a $LF set cmd = ($cmd -xform transforms/talairach.xfm) endif if($FillWithASeg) set cmd = ($cmd -segmentation aseg$MGZ) set cmd = ($cmd wm$MGZ filled$MGZ) echo $cmd |& tee -a $LF |& tee -a $CF $PWD |& tee -a $LF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_fill exited with non-zero status" |& tee -a $LF goto error_exit; endif if($RunIt && $SvInit) then if($#MGZ) then cp filled.mgz filled-init.mgz else cp -R filled filled-init endif endif endif ######################################################### # Per-Hemisphere # ######################################################### echo "INFO: starting per-hemisphere operations" |& tee -a $SF |& tee -a $LF foreach hemi ($hemilist) echo "----- Starting Hemisphere $hemi --------" |& tee -a $SF |& tee -a $LF #---------------- Tessellate --------------------------# # Input: filled volume # Output: ?h.orig (copied to ?h.orig-init) if($DoTessellate) then if($hemi == "lh") then set hemivalue = 255; else set hemivalue = 127; endif echo "---------------------------------------------"|& tee -a $LF echo "Tessellate $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null set incor = $subjdir/mri/filled/COR-.info if($#MGZ) set incor = $subjdir/mri/filled.mgz if(! -e $incor) then echo "ERROR: cannot find $incor" |& tee -a $LF goto error_exit; endif mkdir -p $subjdir/surf set cmd = (mri_tessellate $subjdir/mri/filled$MGZ $hemivalue \ $subjdir/surf/$hemi.orig) echo $cmd |& tee -a $LF |& tee -a $CF $PWD |& tee -a $LF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_tessellate exited with non-zero status" goto error_exit; endif if(($SvInitOrigSurf || ! -e $subjdir/surf/$hemi.orig-init) && $RunIt) then cp -R $subjdir/surf/$hemi.orig $subjdir/surf/$hemi.orig-init endif endif #---------------- Smooth1 --------------------------# # Input: ?h.orig # Output: ?h.smoothwm if($DoSmooth1) then echo "---------------------------------------------"|& tee -a $LF echo "Smooth1 $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null set cmd = (mris_smooth $subjdir/surf/$hemi.orig $subjdir/surf/$hemi.smoothwm) echo $cmd |& tee -a $LF |& tee -a $CF $PWD |& tee -a $LF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_smooth exited with non-zero status" goto error_exit; endif endif #---------------- Inflate1 --------------------------# # Input: ?h.smoothwm # Output: ?h.inflated if($DoInflate1) then echo "---------------------------------------------"|& tee -a $LF echo "Inflation1 $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null set cmd = (mris_inflate -dist 0 $subjdir/surf/$hemi.smoothwm) set cmd = ($cmd $subjdir/surf/$hemi.inflated) echo $cmd |& tee -a $LF |& tee -a $CF $PWD |& tee -a $LF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_inflate exited with non-zero status" goto error_exit; endif if(($SvInitInflated || ! -e $subjdir/surf/$hemi.inflated-init) && $RunIt) \ cp $subjdir/surf/$hemi.inflated $subjdir/surf/$hemi.inflated-init endif #---------------- QSphere --------------------------# # Input: ?h.inflated # Output: ?h.qsphere if($DoQSphere) then echo "---------------------------------------------"|& tee -a $LF echo "QSphere $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null $PWD |& tee -a $LF set cmd = (mris_sphere -w 0 -inflate -in 200) set cmd = ($cmd -q $subjdir/surf/$hemi.inflated $subjdir/surf/$hemi.qsphere) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_sphere exited with non-zero status" goto error_exit; endif endif #---------------- Fix Topology --------------------------# # Input: ?h.orig, ?h.inflated # Output: ?h.orig (?h.inflated if -wi is set) if($DoFix) then echo "---------------------------------------------"|& tee -a $LF echo "Fix Topology $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null if($RunIt && $SvInit) then cp $subjdir/surf/$hemi.orig $subjdir/surf/$hemi.orig-prefix cp $subjdir/surf/$hemi.inflated $subjdir/surf/$hemi.inflated-prefix endif $PWD |& tee -a $LF set cmd = (mris_fix_topology) if($FixWithGA) set cmd = ($cmd -ga) if($#MGZ) set cmd = ($cmd -mgz) set cmd = ($cmd $subjid $hemi) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_fix_topology exited with non-zero status" goto error_exit; endif endif #---------------- Euler Number --------------------------# # Input: ?h.orig, ??? # Output: ?h.orig.euler if($DoEuler) then echo "---------------------------------------------"|& tee -a $LF echo "Euler Number $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir $PWD |& tee -a $LF set surffile = $subjdir/surf/$hemi.orig; set outfile = $surffile.euler set cmd = (mris_euler_number $subjdir/surf/$hemi.orig) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) then $cmd |& tee $outfile |& tee -a $LF if($status) then echo "ERROR: mris_euler_number exited with non-zero status" goto error_exit; endif set NHoles = `cat $outfile | awk '{if(NR==1) print $15}'`; echo "Euler: NHoles = $NHoles" |& tee -a $SF |& tee -a $LF if($NHoles != 0) then echo "WARNING: Number of holes is not zero"|& tee -a $SF |& tee -a $LF endif endif endif #---------------- Smooth2 --------------------------# # Input: ?h.orig # Output: ?h.smoothwm (overwrite the 1st smooth data) if($DoSmooth2) then echo "---------------------------------------------"|& tee -a $LF echo "Smooth2 $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null set cmd = (mris_smooth $subjdir/surf/$hemi.orig $subjdir/surf/$hemi.smoothwm) echo $cmd |& tee -a $LF |& tee -a $CF $PWD |& tee -a $LF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_smooth exited with non-zero status" goto error_exit; endif endif #---------------- Inflate2 --------------------------# # Input: ?h.smoothwm # Output: ?h.inflated (overwrite the 1st inflated data) if($DoInflate2) then echo "---------------------------------------------"|& tee -a $LF echo "Inflation2 $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null $PWD |& tee -a $LF set cmd = (mris_inflate -dist 0 $subjdir/surf/$hemi.smoothwm ) set cmd = ($cmd $subjdir/surf/$hemi.inflated) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_inflate exited with non-zero status" goto error_exit; endif endif #---------------- Make Final Surfaces --------------------------# # Input: filled, brain, wm, ?h.orig, talairach.xfm # Output: white, pial, thickness if($DoFinalSurfs) then echo "---------------------------------------------"|& tee -a $LF echo "Make Final Surf $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null $PWD |& tee -a $LF set cmd = (mris_make_surfaces) if($#MGZ) set cmd = ($cmd -mgz) set cmd = ($cmd -w 0 $subjid $hemi); echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_make_surfaces exited with non-zero status" goto error_exit; endif endif if($DoCortRibbonVolMask) then echo "---------------------------------------------"|& tee -a $LF echo "Making vol mask of cortical ribbon $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/mri > /dev/null $PWD |& tee -a $LF set cmd = (mri_surf2vol --mkmask --hemi $hemi) set cmd = ($cmd --fillribbon --template orig$MGZ) set cmd = ($cmd --volregidentity $subjid --outvol $hemi.ribbon.mgz) # Use MGZ regardless echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_surf2vol exited with non-zero status" goto error_exit; endif endif #---------------Begin Morph --------------------------------# #---------------- Sphere --------------------------# # Input: inflated # Output: sphere if($DoSphere) then echo "---------------------------------------------"|& tee -a $LF echo "Sphere $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null $PWD |& tee -a $LF set cmd = (mris_sphere -w 0 $subjdir/surf/$hemi.inflated \ $subjdir/surf/$hemi.sphere) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_sphere exited with non-zero status" goto error_exit; endif endif #---------------- Surface Registration --------------------------# # Input: sphere # Output: sphere.reg if($DoSurfReg) then echo "---------------------------------------------"|& tee -a $LF echo "Surf Reg $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null set AvgTif = $FREESURFER_HOME/average/$hemi.average.tif $PWD |& tee -a $LF set cmd = (mris_register -w 0 -curv $subjdir/surf/$hemi.sphere) set cmd = ($cmd $AvgTif $subjdir/surf/$hemi.sphere.reg) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_register exited with non-zero status" goto error_exit; endif endif #-------- Contra Surface Registration ----------------# # Input: sphere # Output: ?h.sphere.reg if($DoContraSurfReg) then if($hemi == lh) then set nothemi = rh; else set nothemi = lh; endif echo "---------------------------------------------"|& tee -a $LF echo "Contra Surf Reg $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null set AvgTif = $FREESURFER_HOME/average/$hemi.average.tif $PWD |& tee -a $LF set cmd = (mris_register -w 0 -curv -reverse $subjdir/surf/$hemi.sphere) set cmd = ($cmd $AvgTif $subjdir/surf/$hemi.$nothemi.sphere.reg) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_register exited with non-zero status" goto error_exit; endif endif #---------------- Average Curv for Display----------------------# # Input: ?h.sphere.reg # Output: ?h.avg_curv if($DoAvgCurv) then echo "---------------------------------------------"|& tee -a $LF echo "AvgCurv $hemi `date`" |& tee -a $SF |& tee -a $LF set AvgTif = $FREESURFER_HOME/average/$hemi.average.tif pushd $subjdir/scripts > /dev/null $PWD |& tee -a $LF set cmd = (mrisp_paint -a 5 "$AvgTif#6") set cmd = ($cmd $subjdir/surf/$hemi.sphere.reg $subjdir/surf/$hemi.avg_curv) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mrisp_paint exited with non-zero status" goto error_exit; endif endif #---------------- Map Average Labels ----------------------# # Input: ?h.sphere.reg # Output: ?h.avg_curv if($DoAvgLabels) then echo "---------------------------------------------"|& tee -a $LF echo "AvgLabels $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null mkdir -p $subjdir/label $PWD |& tee -a $LF foreach label (calcarine_sulcus central_sulcus superior_temporal_sulcus) set labelfile = $SUBJECTS_DIR/average7/label/$hemi-avg_$label.label if(! -e $labelfile ) then echo "ERROR: cannot find $labelfile" |& tee -a $LF goto error_exit; endif set outlabelfile = $subjdir/label/$hemi-avg_$label.label set cmd = (mri_label2label --hemi $hemi --regmethod surface) set cmd = ($cmd --srcsubject average7 --srclabel $labelfile) set cmd = ($cmd --trgsubject $subjid --trglabel $outlabelfile) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mri_label2label exited with non-zero status"|& tee -a $LF goto error_exit; endif end endif #---------------- Morph RGB --------------------------# # Input: # Output: if($DoMorphRGB) then echo "---------------------------------------------"|& tee -a $LF echo "Morph RGB $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null mkdir -p $subjdir/rgb $PWD |& tee -a $LF set cmd = (mris2rgb -o $subjid.reg -both -c $subjdir/surf/$hemi.sulc) set cmd = ($cmd -canon $subjdir/surf/$hemi.sphere.reg ) set cmd = ($cmd $subjdir/surf/$hemi.sphere.reg) set cmd = ($cmd $subjdir/rgb) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris2rgb exited with non-zero status" goto error_exit; endif endif #---------------- Cortical Parcellation------------------------# # Input: sphere.reg, _trans_toSulc.gcs # Output: ?h_aparc.annot if($DoCortParc) then echo "------------------------------------------"|& tee -a $LF echo "Cortical Parcellation $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir/scripts > /dev/null $PWD |& tee -a $LF set CPAtlas = $FREESURFER_HOME/average/$hemi.atlas2002_simple.gcs set sphreg = $subjdir/surf/$hemi.sphere.reg if(! -e $sphreg) then echo "ERROR: cannot find $hemi.sphere.reg. This is " |& tee -a $SF |& tee -a $LF echo "necessary to do cortical parcellation." |& tee -a $SF |& tee -a $LF exit 1; endif set cmd = (mris_ca_label -t $CPAnnotTable $subjid $hemi ) set cmd = ($cmd sphere.reg $CPAtlas) set cmd = ($cmd $hemi.aparc.annot) echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_ca_label exited with non-zero status" |& tee -a $LF goto error_exit; endif cp $CPAnnotTable $subjdir/label endif if($DoParcStats) then echo "------------------------------------------"|& tee -a $LF echo "Parcellation Stats $hemi `date`" |& tee -a $SF |& tee -a $LF pushd $subjdir > /dev/null $PWD |& tee -a $LF set cmd = (mris_anatomical_stats) set cmd = ($cmd -f scripts/$hemi.aparc.stats -b -a label/$hemi.aparc.annot) set cmd = ($cmd $subjid $hemi); echo $cmd |& tee -a $LF |& tee -a $CF if($RunIt) $cmd |& tee -a $LF if($status) then echo "ERROR: mris_anatomical_stats exited with non-zero status" |& tee -a $LF goto error_exit; endif endif end # Loop over hemilist echo "" |& tee -a $LF echo "-------------------------------------------" |& tee -a $LF echo "" |& tee -a $LF if($#NotifyFile != 0) then echo "INFO: touching notification file $NotifyFile" |& tee -a $LF touch $NotifyFile endif echo "recon-all finished without error at `date`" |& tee -a $LF |& tee -a $SF if($#mailuser != 0) then echo "recon-all $subjid finished without error at `date`" | \ mail -s "$subjid DONE `date`" $mailuser endif echo "done" exit 0 #############------------------------------------####################### ##################>>>>>>>>>>>>>.<<<<<<<<<<<<<<<<<####################### #############------------------------------------####################### ############--------------################## error_exit: #echo "------------------------------------------" |& tee -a $LF #df . |& tee -a $LF #echo "------------------------------------------" |& tee -a $LF echo "recon-all exited with errors at `date`" |& tee -a $LF |& tee -a $SF if($#mailuser != 0) then echo "recon-all $subjid finished with errors at `date`" | \ mail -s "$subjid ERROR `date`" $mailuser endif exit 1; endif ############--------------################## parse_args: set cmdline = ($argv); while( $#argv != 0 ) set flag = $argv[1]; shift; switch($flag) case "-subjid": case "-sid": case "-s": if ( $#argv < 1) goto arg1err; set subjid = $argv[1]; shift; set subjid = `basename $subjid`; # remove trailing / breaksw case "-sd": if ( $#argv < 1) goto arg1err; setenv SUBJECTS_DIR $argv[1]; shift; breaksw case "-hemi": if ( $#argv < 1) goto arg1err; set hemilist = $argv[1]; shift; if($hemilist != lh && $hemilist != rh) then echo "ERROR: hemi = $hemilist, must be either lh or rh" exit 1; endif breaksw case "-mail": if ( $#argv < 1) goto arg1err; set mailuser = $argv[1]; shift; breaksw case "-motioncor": set DoMotionCor = 1; breaksw case "-nomotioncor": set DoMotionCor = 0; breaksw case "-talairach": set DoTalairach = 1; breaksw case "-notalairach": set DoTalairach = 0; breaksw case "-nuintensitycor": set DoNuIntensityCor = 1; breaksw case "-nonuintensitycor": set DoNuIntensityCor = 0; breaksw case "-usenuintensitycor": set UseNuIntensityCor = 1; breaksw case "-nousenuintensitycor": set UseNuIntensityCor = 0; breaksw case "-nuinterations": case "-nuiterations": if ( $#argv < 1) goto arg1err; set NuIterations = $argv[1]; shift; breaksw case "-norm3diters": if ( $#argv < 1) goto arg1err; set Norm3dIters = $argv[1]; shift; breaksw case "-normalization": set DoNormalization = 1; breaksw case "-nonormalization": set DoNormalization = 0; breaksw case "-normalization2": set DoNormalization2 = 1; breaksw case "-nonormalization2": set DoNormalization2 = 0; breaksw case "-usecontrolpoints": set UseControlPoints = 1; breaksw case "-skullstrip": set DoSkullStrip = 1; breaksw case "-noskullstrip": set DoSkullStrip = 0; breaksw case "-segmentation": set DoSegmentation = 1; breaksw case "-nosegmentation": set DoSegmentation = 0; breaksw case "-keepwmedits" set SegKeepWMEdits = 1; breaksw case "-gcareg": set DoGCAReg = 1; breaksw case "-nogcareg": set DoGCAReg = 0; breaksw case "-canorm": set DoCANormalize = 1; breaksw case "-nocanorm": set DoCANormalize = 0; breaksw case "-careg": set DoCAReg = 1; breaksw case "-nocareg": set DoCAReg = 0; breaksw case "-calabel": set DoCALabel = 1; breaksw case "-nocalabel": set DoCALabel = 0; breaksw case "-subcortseg": set DoGCAReg = 1; set DoCANormalize = 1; set DoCAReg = 1; set DoCALabel = 1; #??set EditWMwithASeg = 1; breaksw case "-nosubcortseg": set DoGCAReg = 0; set DoCANormalize = 0; set DoCAReg = 0; set DoCALabel = 0; breaksw case "-edit_wm_with_aseg": set EditWMwithASeg = 1; breaksw case "-noedit_wm_with_aseg": set EditWMwithASeg = 0; breaksw case "-gca": if ( $#argv < 1) goto arg1err; set GCA = $argv[1]; shift; breaksw case "-mgz": set MGZ = ".mgz"; breaksw case "-COR": set UseCOR = 1; set MGZ = (); breaksw case "-fill": set DoFill = 1; breaksw case "-nofill": set DoFill = 0; breaksw case "-pons-xyz": if ( $#argv < 3) goto arg3err; set FillPonsXYZ = ($argv[1] $argv[2] $argv[3]); shift;shift;shift; breaksw case "-cc-xyz": if ( $#argv < 3) goto arg3err; set FillCCXYZ = ($argv[1] $argv[2] $argv[3]); shift;shift;shift; breaksw case "-lh-xyz": if ( $#argv < 3) goto arg3err; set FillLHXYZ = ($argv[1] $argv[2] $argv[3]); shift;shift;shift; breaksw case "-rh-xyz": if ( $#argv < 3) goto arg3err; set FillRHXYZ = ($argv[1] $argv[2] $argv[3]); shift;shift;shift; breaksw case "-fill-with-aseg" set FillWithASeg = 1; breaksw case "-watershed": echo $argv[1]; if ( $#argv < 1 ) goto arg1err; switch($argv[1]) case "nowatershed": set WaterShed = 0; breaksw; case "normal": set WaterShed = 1; breaksw; case "watershedonly": set WaterShed = 2; breaksw; case "watershedtemplate": set WaterShed = 3; breaksw; case "atlas": set WaterShed = 4; breaksw; default: echo "ERROR: -watershed argument $argv[1] unrecognized." echo "Valid arguments are: atlas, nowatershed, normal, watershedonly," echo "and watershedtemplate." exit 1; breaksw; endsw # YO. You got shift to absorb argv[] for this guy shift; endif breaksw case "-wsless": set WSLess = 1; breaksw case "-wsmore": set WSMore = 1; breaksw case "-wsatlas": set WSAtlas = 1; breaksw case "-wsthresh": if ( $#argv < 1) goto arg1err; set WSPctPreFlood = $argv[1]; shift; breaksw case "-wsseed": if ( $#argv < 3) goto arg3err; set WSSeedPoint = ($argv[1] $argv[2] $argv[3]); shift;shift;shift; breaksw case "-tessellate": case "-tess": set DoTessellate = 1; breaksw case "-notessellate": case "-notess": set DoTessellate = 0; breaksw case "-svinitorigsurf": set SvInitOrigSurf = 1; breaksw case "-nosvinitorigsurf": set SvInitOrigSurf = 0; breaksw case "-smooth1": set DoSmooth1 = 1; breaksw case "-nosmooth1": set DoSmooth1 = 0; breaksw case "-inflate1": set DoInflate1 = 1; breaksw case "-noinflate1": set DoInflate1 = 0; breaksw case "-svinitinflated": set SvInitInflated = 1; breaksw case "-nosvinitinflated": set SvInitInflated = 0; breaksw case "-qsphere": set DoQSphere = 1; breaksw case "-noqsphere": set DoQSphere = 0; breaksw case "-fix": set DoFix = 1; breaksw case "-nofix": set DoFix = 0; breaksw case "-fix-with-ga": set FixWithGA = 1; breaksw case "-no-fix-with-ga": set FixWithGA = 0; breaksw case "-euler": set DoEuler = 1; breaksw case "-noeuler": set DoEuler = 0; breaksw case "-smooth2": set DoSmooth2 = 1; breaksw case "-nosmooth2": set DoSmooth2 = 0; breaksw case "-inflate2": set DoInflate2 = 1; breaksw case "-noinflate2": set DoInflate2 = 0; breaksw case "-cortribbon": set DoCortRibbonVolMask = 1; breaksw case "-nocortribbon": set DoCortRibbonVolMask = 0; breaksw case "-sphere": set DoSphere = 1; breaksw case "-nosphere": set DoSphere = 0; breaksw case "-surfreg": set DoSurfReg = 1; breaksw case "-nosurfreg": set DoSurfReg = 0; breaksw case "-contrasurfreg": set DoContraSurfReg = 1; breaksw case "-nocontrasurfreg": set DoContraSurfReg = 0; breaksw case "-avgcurv": set DoAvgCurv = 1; breaksw case "-noavgcurv": set DoAvgCurv = 0; breaksw case "-avglabels": set DoAvgLabels = 1; breaksw case "-noavglabels": set DoAvgLabels = 0; breaksw case "-morphrgb": set DoMorphRGB = 1; breaksw case "-nomorphrgb": set DoMorphRGB = 0; breaksw case "-finalsurfs": set DoFinalSurfs = 1; breaksw case "-nofinalsurfs": set DoFinalSurfs = 0; breaksw case "-cortparc": set DoCortParc = 1; breaksw case "-nocortparc": set DoCortParc = 0; breaksw case "-parcstats": set DoParcStats = 1; breaksw case "-noparcstats": set DoParcStats = 0; breaksw case "-stage1": set DoMotionCor = 1; set DoTalairach = 1; set DoNuIntensityCor = 1; set DoNormalization = 1; set DoSkullStrip = 1; set DoSegmentation = 1; set DoGCAReg = 1; set DoCANormalize = 1; set DoCAReg = 1; set DoCALabel = 1; set DoFill = 1; set DoTessellate = 1; set SvInitOrigSurf = 1; set DoSmooth1 = 1; set DoInflate1 = 1; set SvInitInflated = 1; breaksw case "-stage2": set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; breaksw case "-stage3": set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; set DoQSphere = 1; set DoFix = 1; set DoEuler = 1; set DoSmooth2 = 1; set DoInflate2 = 1; breaksw case "-stage4a": set DoFinalSurfs = 1; set DoCortRibbonVolMask = 1; breaksw case "-stage4b": set DoSphere = 1; set DoSurfReg = 1; set DoContraSurfReg = 1; set DoAvgCurv = 1; set DoAvgLabels = 0; set DoMorphRGB = 0; set DoCortParc = 1; set DoParcStats = 1; breaksw case "-segment_subject": set DoTalairach = 1; set DoNuIntensityCor = 1; set DoNormalization = 1; set DoSkullStrip = 1; set DoSegmentation = 1; set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; breaksw case "-inflate_subject": set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; breaksw case "-fix_subject": set DoQSphere = 1; set DoFix = 1; set DoSmooth2 = 1; set DoInflate2 = 1; breaksw case "-morph": set DoSphere = 1; set DoSurfReg = 1; set DoContraSurfReg = 1; set DoMorphRGB = 0; breaksw case "-make_final_surfaces": set DoFinalSurfs = 1; set DoCortParc = 1; set DoParcStats = 1; set DoCortRibbonVolMask = 1; breaksw case "-all": set DoMotionCor = 1; set DoTalairach = 1; set DoNuIntensityCor = 1; set DoNormalization = 1; set DoSkullStrip = 1; set DoGCAReg = 1; set DoCANormalize = 1; set DoCAReg = 1; set DoCALabel = 1; set DoSegmentation = 1; set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; set DoFill = 1; set DoQSphere = 1; set DoFix = 1; set DoEuler = 1; set DoSmooth2 = 1; set DoInflate2 = 1; set DoFinalSurfs = 1; set DoCortRibbonVolMask = 1; set DoSphere = 1; set DoSurfReg = 1; set DoContraSurfReg = 1; set DoAvgCurv = 1; set DoAvgLabels = 0; set DoMorphRGB = 0; set DoCortParc = 1; set DoParcStats = 1; breaksw case "-autorecon1": set DoMotionCor = 1; set DoTalairach = 1; set DoNuIntensityCor = 1; set DoNormalization = 1; set DoSkullStrip = 1; set UseNuIntensityCor = 1; breaksw case "-autorecon2": set UseNuIntensityCor = 1; set EditWMwithASeg = 1; set FillWithASeg = 1; set DoGCAReg = 1; set DoCANormalize = 1; set DoCAReg = 1; set DoCALabel = 1; set DoNormalization2 = 1; set DoSegmentation = 1; set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; set DoQSphere = 1; set DoFix = 1; set DoEuler = 1; set DoSmooth2 = 1; set DoInflate2 = 1; set DoFinalSurfs = 1; set DoCortRibbonVolMask = 1; breaksw case "-autorecon2-cp": set SegKeepWMEdits = 1; set UseControlPoints = 1; set UseNuIntensityCor = 1; set EditWMwithASeg = 1; set FillWithASeg = 1; set DoNormalization2 = 1; set DoSegmentation = 1; set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; set DoQSphere = 1; set DoFix = 1; set DoEuler = 1; set DoSmooth2 = 1; set DoInflate2 = 1; set DoFinalSurfs = 1; set DoCortRibbonVolMask = 1; breaksw case "-autorecon2-wm": set UseNuIntensityCor = 1; set EditWMwithASeg = 1; set FillWithASeg = 1; set DoFill = 1; set DoTessellate = 1; set DoSmooth1 = 1; set DoInflate1 = 1; set DoQSphere = 1; set DoFix = 1; set DoEuler = 1; set DoSmooth2 = 1; set DoInflate2 = 1; set DoFinalSurfs = 1; set DoCortRibbonVolMask = 1; breaksw case "-autorecon2-pial": set DoFinalSurfs = 1; set DoCortRibbonVolMask = 1; breaksw case "-autorecon3": set DoSphere = 1; set DoSurfReg = 1; set DoContraSurfReg = 1; set DoAvgCurv = 1; set DoCortParc = 1; set DoParcStats = 1; set DoAvgLabels = 0; set DoMorphRGB = 0; breaksw case "-enable-autoseg": setenv FS_ENABLE_AUTOSEG 1 breaksw case "-disable-autoseg": setenv FS_ENABLE_AUTOSEG 0 set DoGCAReg = 0; set DoCANormalize = 0; set DoCAReg = 0; set DoCALabel = 0; breaksw case "-waitfor": if ( $#argv < 1) goto arg1err; set WaitForFile = $argv[1]; shift; breaksw case "-notify": if ( $#argv < 1) goto arg1err; set NotifyFile = $argv[1]; shift; breaksw case "-status": if ( $#argv < 1) goto arg1err; set SF = $argv[1]; shift; breaksw case "-noappendlog": set AppendLog = 0; breaksw case "-noappendstatus": set AppendStatus = 0; breaksw case "-noappend": set AppendLog = 0; set AppendStatus = 0; breaksw case "-log": if ( $#argv < 1) goto arg1err; set LF = $argv[1]; shift; breaksw case "-csurfdir": if ( $#argv < 1) goto arg1err; setenv FREESURFER_HOME $argv[1]; shift; if(! -e $FREESURFER_HOME) then echo "ERROR: cannot find $FREESURFER_HOME" exit 1; endif pushd $FREESURFER_HOME > /dev/null setenv FREESURFER_HOME `pwd`; breaksw case "-dontrun": set RunIt = 0; breaksw case "-verbose": set verbose = 1; breaksw case "-echo": set echo = 1; breaksw case "-debug": set verbose = 1; set echo = 1; breaksw case "-umask": if ( $#argv < 1) goto arg1err; umask $1; shift; breaksw case "-grp": if ( $#argv < 1) goto arg1err; set grp = $argv[1]; set curgrp = `id -gn`; if($grp != $curgrp) then echo "ERROR: current group ($curgrp) does not equal specified group $grp" exit 1; endif breaksw case "-cm": set HiRes =('-cm') echo "INFO: all COR volumes are conformed to the min voxel size" breaksw default: echo ERROR: Flag $flag unrecognized. echo $cmdline exit 1 breaksw endsw end goto parse_args_return; ############--------------################## ############--------------################## arg1err: echo "ERROR: flag $flag requires one argument" exit 1 ############--------------################## ############--------------################## arg3err: echo "ERROR: flag $flag requires three arguments" exit 1 ############--------------################## ############--------------################## check_params: if($#subjid != 1) then echo "ERROR: must specify a subject id" exit 1; endif if(! $?SUBJECTS_DIR ) then echo "ERROR: environment variable SUBJECTS_DIR not set" echo " this can be done by setting it in the shell before" echo " executing recon-all or by using the -sd flag" exit 1; endif if(! -e $SUBJECTS_DIR ) then echo "ERROR: SUBJECTS_DIR $SUBJECTS_DIR does not exist." exit 1; endif # Get the full path # pushd $SUBJECTS_DIR > /dev/null setenv SUBJECTS_DIR `$PWD`; popd > /dev/null echo "INFO: SUBJECTS_DIR is $SUBJECTS_DIR" set subjdir = $SUBJECTS_DIR/$subjid if(! -e $subjdir) then echo "ERROR: cannot find $subjdir" exit 1; endif if(! -w $subjdir) then echo "ERROR: you do not have write permission to $subjdir" exit 1; endif if(! $?FREESURFER_HOME ) then echo "ERROR: environment variable FREESURFER_HOME not set." exit 1; endif if(! -e $FREESURFER_HOME ) then echo "ERROR: FREESURFER_HOME $FREESURFER_HOME does not exist." exit 1; endif if($DoGCAReg || $DoCALabel) then if(! -e $GCA ) then echo "ERROR: cannot find $GCA" |& tee -a $LF exit 1; endif endif if($EditWMwithASeg && ! $DoCALabel) then set asegdir = $SUBJECTS_DIR/$subjid/mri/aseg if(! -e $asegdir ) then echo "ERROR: cannot find $asegdir." echo "This is needed to perform the subcortical segmentation." echo "Try rerunning with -subcortpar." endif endif foreach hemi ($hemilist) if($DoSurfReg || $DoContraSurfReg || $DoAvgCurv) then set avgtif = $FREESURFER_HOME/average/$hemi.average.tif; if(! -e $avgtif) then echo "ERROR: cannot find $avgtif." echo "This is needed to do surface registration and avg curv." exit 1; endif endif if($DoCortParc) then set CPAtlas = $FREESURFER_HOME/average/$hemi.atlas2002_simple.gcs if(! -e $CPAtlas) then echo "ERROR: cannot find $CPAtlas." echo "This is needed to do cortical parcellation." exit 1; endif if(! -e $CPAnnotTable) then echo "ERROR: cannot find $CPAnnotTable" echo "This is needed to do cortical parcellation." exit 1; endif endif if($DoAvgLabels) then set average7 = $SUBJECTS_DIR/average7 if(! -e $average7) then echo "ERROR: cannot find 'average7' directory in SUBJECTS_DIR (needed to do average labels)." exit 1; endif foreach label (calcarine_sulcus central_sulcus superior_temporal_sulcus) set labelfile = $SUBJECTS_DIR/average7/label/$hemi-avg_$label.label if(! -e $labelfile ) then echo "ERROR: cannot find $labelfile" |& tee -a $LF goto error_exit; endif end endif end if($#NotifyFile != 0) then rm -f $NotifyFile; set tmpdir = `dirname $NotifyFile`; mkdir -p $tmpdir; pushd $tmpdir > /dev/null; set tmpdir = `$PWD`; set NotifyFile = $tmpdir/`basename $NotifyFile`; popd > /dev/null; endif if($#WaitForFile != 0) then set tmpdir = `dirname $WaitForFile`; mkdir -p $tmpdir; pushd $tmpdir > /dev/null; set tmpdir = `$PWD`; set WaitForFile = $tmpdir/`basename $WaitForFile`; popd > /dev/null; endif if(! $DoCortParc && ! $DoGCAReg ) then if(! $DoMotionCor && ! $DoTalairach && ! $DoNormalization && \ ! $DoNormalization2 && ! $DoParcStats && \ ! $DoSkullStrip && ! $DoSegmentation && ! $DoNuIntensityCor &&\ ! $DoFill && ! $DoTessellate && ! $DoEuler && \ ! $DoSmooth1 && ! $DoInflate1 && ! $DoQSphere && \ ! $DoFix && ! $DoSmooth2 && ! $DoInflate2 && ! $DoSphere && \ ! $DoSurfReg && ! $DoContraSurfReg && ! $DoAvgCurv && \ ! $DoMorphRGB && ! $DoFinalSurfs && ! $DoAvgLabels && ! $DoCortRibbonVolMask &&\ ! $DoCANormalize && ! $DoCAReg && ! $DoCALabel && ! $EditWMwithASeg) then echo "ERROR: nothing to do" exit 1; endif endif if($SvInitOrigSurf && ! $DoTessellate) then echo "ERROR: you have chosen to save the initial orig surface, however," echo "you have not chosen to perform the command that would create" echo "the orig surface (ie, tessellation)."; exit 1; endif if($SvInitInflated && ! $DoInflate1) then echo "ERROR: you have chosen to save the initial inflated surface, " echo "however, you have not chosen to perform the command that" echo "would create the inflated surface (ie, inflate1)"; exit 1; endif if($UseControlPoints) then set ControlPointsFile = $subjdir/tmp/control.dat if(! -e $ControlPointsFile) then echo "ERROR: you have specfied that control points should be used" echo " during the intensity normalization. However, the control" echo " points file ($ControlPointsFile) does not exist." exit 1; endif endif if($WSMore && $WSLess) then echo "ERROR: cannot specify both -wsmore and -wsless" exit 1; endif if( ($WSMore || $WSLess) && $WSPctPreFlood ) then echo "ERROR: cannot specify -wsmore or -wsless and -wsthresh" exit 1; endif if($DoNuIntensityCor) then which nu_correct > /dev/null if($status) then echo "ERROR: nu_correct does not exist" exit 1; endif endif goto check_params_return; ############--------------################## ############--------------################## usage_exit: echo "" echo "USAGE: $ProgName" echo "" echo " Required Arguments:"; echo " -subjid subjid" echo "" echo " Clustered Directives:" echo " -all : do everything" echo " -stage1 : pre-manual editing (mc, tal, norm, strip, seg, stage2)" echo " -stage2 : with manual editing (fill, tess, sm1, inf1)" echo " -stage3 : runs the topology fixer (and stage2)" echo " -stage4a : make final surfaces" echo " -stage4b : spherical morph" echo " -hemi ?h : just do lh or rh (default is to do both)" echo " -subcortseg : automatic subcortical segmentation (aseg)" echo "" echo " Legacy Clustered Directives:" echo " -segment_subject : (same as stage1 without motion cor)" echo " -inflate_subject : fill, tessellate, smooth1, inflate1" echo " -fix_subject : (qsphere, fix, smooth2, inflate2)" echo " -morph : (sphere, surfreg, contrasurfreg, avgcurv, avglabels)" echo " -make_final_surfaces : finalsurfs" echo "" echo "Step-wise Directives" echo " See -help" echo "" echo "Expert Preferences" echo " -usecontrolpoints : use control points when intensity normalizing" echo " -keepwmedits : keep edits to wm volume when segmenting" echo " -pons-xyz X Y Z : XYZ of seed point for pons, used in fill" echo " -cc-xyz X Y Z : XYZ of seed point for corpus callosum, used in fill" echo " -lh-xyz X Y Z : XYZ of seed point for left hemisphere, used in fill" echo " -rh-xyz X Y Z : XYZ of seed point for right hemisphere, used in fill" echo " -fill-with-aseg : use the automatic subcort seg to fill" echo " -watershed cmd : control skull stripping/watershed program" echo " -wsless : decrease watershed threshold (shrinks skull surface)" echo " -wsmore : increase watershed threshold (expands skull surface)" echo " -wsatlas : use atlas when skull stripping" echo " -wsthresh pct : explicity set watershed threshold" echo " -wsseed C R S : identify an index (C, R, S) point in the skull" echo " -nuiterations N : set number of iterations for nu intensity " echo " correction (default is $NuIterations)" echo " -norm3diters niters : number of 3d iterations for mri_normalize" echo " -cm : conform COR volumes to the min voxel size " echo " -edit_wm_with_aseg : use automatic segmentation to edit WM volume." echo " -no-fix-with-ga : do not use genetic algorithm when fixing topology" echo "" echo " Notification Files (Optional)" echo " -waitfor file : wait for file to appear before beginning" echo " -notify file : create this file after finishing" echo "" echo " Status and Log files (Optional)" echo " -log file : default is scripts/recon-all.log" echo " -status file : default is scripts/recon-all.status" echo " -noappend : start new log and status files instead of appending" echo "" echo " Other Arguments (Optional)" echo " -mgz : use compressed MGH format (see help)" echo " -COR : use compressed MGH format (see help)" echo " -disable-autoseg : disable automatic segmentation" echo " -sd subjectsdir : specify subjects dir (default env SUBJECTS_DIR)" echo " -gca gcafile : full path to gca file (def $GCA)" echo " -gca-tl gcatlfile : full path to gca temporal lobe file" echo " -mail username : mail user when done" echo " -umask umask : set unix file permission mask (default 002)" echo " -grp groupid : check that current group is alpha groupid " echo " -debug : print out lots of info" echo " -dontrun : do everthing but execute each command" echo " -version : print version of this script and exit" echo " -help : yea, like anybody's going to read this" echo "" if(! $PrintHelp) exit 1; echo $VERSION echo "" cat $0 | sed 's/dASEGd//g' | awk 'BEGIN{prt=0}{if(prt) print $0;if($1 == "BEGINHELP") prt=1}' exit 1; cat $0 | awk 'BEGIN{prt=0}{if(prt) print $0;if($1 == "BEGINHELP") prt=1}' exit 1; #---- Everything below here is printed out as part of help -----# BEGINHELP Performs all, or any part of, the FreeSurfer cortical reconstruction process. It is assumed that the subject directory has already been created using mksubjdirs and that the raw data already exists in subjid/mri/orig, either in COR format or mgz. The format is automatically detected. To explicitly use COR, then add -COR. To explicitly use mgz, then add -mgz. When automatically detecting, looks for a COR volume in orig/XXX in COR format (XXX is a three-digit, zero-padded number). If that is not found, then looks for orig/XXX.mgz. See USING COMPRESSED MGH FORMAT (MGZ) below. This help is not meant to be exhaustive documentation on FreeSurfer. For more information, see the references at the end or go to the FreeSurfer web site at http://surfer.nmr.mgh.harvard.edu. In particular, there is both a reconstruction guide and tutorial as well as manuals for tkmedit and tksurfer. The FreeSurfer mailing list can also be reached at freesurfer@nmr.mgh.harvard.edu. SUBJECT IDENTIFICATION STRING -subjid subjectid This is the FreeSurfer subject identification string which doubles as the name of the reconstruction root directory for this subject. This reconstruction should be referenced by this string for all FreeSurfer commands and in the register.dat matrix (for functional interfacing). SPECIFYING DIRECTIVES Directives instruct recon-all which part(s) of the reconstruction stream to run. While it is possible to do everything in one shot (using the -all flag), there can be some benefits to customizing the stream. These benefits include stopping to perform manual editing as well as parallelization. Directives are either clustered or step-wise. Clustered directives are sets of steps that can be performed by specifying a single flag. A step-wise directive refers to a single step. Directives accumulate. For example, specifying -stage1 and -stage3 will perform all the steps in both stage 1 and 2. A step can be removed from a cluster by adding -no after the cluster flag. For example, specifying -all followed by -notalairach will perform all the reconstruction steps except talairaching. However, note that if -notalairach *preceeded* -all, talairaching would still be performed. CLUSTERED DIRECTIVES -all Perform all reconstruction steps. -stage1 Perform all the stages prior to manually editing the wm volume. This includes motion correction and averaging, talairaching, non-uniform (nu) intensity correction, intensity normalization, skull stripping, and white matter segmentation. It also runs stage2 so that users can immediately start manual editing using the surface as a guide (stage2 usually only takes a few minutes). Runs the following steps: motioncor, talairach, normalization, skullstrip, fill, tessellate, smooth1, and inflate1. Approximate run time: 20 min. -stage2 Run this stage after each manual edit. Cuts hemispheres from each other and from the mid brain and fills each hemisphere in the volume with a constant value, tesslates the surface, smooths, and inflates. Runs the following steps: fill, tessellate, smooth1, and inflate1. This stage is also run with stage1 and stage3. Approximate run time: less than 5 min. -stage3 Runs qsphere and automatic topology fixing. This will regeneate the orig surface as well as the smoothwm surface, the inflated surface, and the area, curv, and sulc files. Runs the following steps: fill, tessellate, smooth1, inflate1, fix, euler, smooth2, inflate2. It is a good idea to check the orig surface at this stage. It also runs stage2 just in case the user did not run it after manual editing (stage2 usually only takes a few minutes). Approximate run time: 1 hour per hemisphere. -stage4a Creates the final surfaces (ie, white, pial, and thickness). Includes the following step: finalsurfs. Can be run in parallel with -stage4b. Approximate run time: 1.5 hour per hemisphere. Includes creating a mask of the cortical ribbon (see -cortribbon) as ?h.ribbon.mgz. -stage4b Run spherical morph, which includes the following steps: sphere, surfreg, contrasurfreg, avgcurv, avglabels. Can be run in parallel with -stage4a. Approximate run time: 6.5 hours per hemisphere. -hemi hemisphere Instruct recon-all to only operate on the specified hemisphere. Legal values are lh and rh. This can be used to run the surface-related steps in parallel. -autorecon1 Motion correction through skull strip -autorecon2 Subcortical segmentation through make final surfaces -autorecon2-cp Normalization2 through make final surfaces. Implies -usecontrolpoints and -keepwmedits. Used after adding control points after running -autorecon2. -autorecon2-wm Fill through make final surfaces. Used after editing wm volume after running -autorecon2. -autorecon2-pial Makes final surfaces. Used after editing brain volume after running -autorecon2. The brain volume may be edited to fix problems with the pial surface. -autorecon3 Spherical morph and automatic cortical parcellation. LEGACY CLUSTERED DIRECTIVES Legacy clustered directives implement sets of steps associated with scripts before the advent of recon-all. STEP-WISE DIRECTIVES Step-wise directives allow the user to implement a single step in the reconstruction process. See also STEP DESCRIPTION SUMMARIES below. They also allow users to include/exclude a step from a clustered DIRECTIVE. To include a step, use -step (eg, -skillstrip). To exclude a step, use -nostep (eg -noskullstrip). Run times are approximate for Pentium III (Coppermine) 1GHz processor. -motioncor < 5 min -talairach 2 min -nuintensitycor 12 min -usenuintensitycor N/A -normalization 5 min -skullstrip 1 min -normalization2 5 min -segmentation 4 min -gcareg 10 min -fill 1 min -tessellate 1 min per hemisphere -smooth1 1 min per hemisphere -inflate1 4 min per hemisphere -qsphere 40 min per hemisphere -fix 2 min per hemisphere -euler 1 min per hemisphere -smooth2 1 min per hemisphere -inflate2 4 min per hemisphere -finalsurfs 1.5 hours per hemisphere -cortribbon 1 min per hemisphere -sphere 3.0 hours per hemisphere -surfreg 1.5 hours per hemisphere -contrasurfreg 1.5 hours per hemisphere -avgcurv 1 min per hemisphere -avglabels 5 min per hemisphere -cortparc 5 min per hemisphere -parcstats 1 min per hemisphere -edit_wm_with_aseg EXPERT PREFERENCES -usecontrolpoints Use control points during intensity normalization. They are used when the inensity normalization fails because it cannot determine the proper intensity for white matter. A control point is a manually selected location in the volume that the user feels sure is inside white matter. Control points are created using tkmedit. Inside tkmedit, enable editing of control points with Tools->EditCtrlPts. Middle-clicking will create a control point; right-clicking will delete a control point. After creation, File->SaveControlPoints; this will create a file called subjid/tmp/control.dat. -keepwmedits Keep edits manually made edits to the wm volume when segmenting the brain volume (normally the segmentation step will just overwrite the wm volume). -pons-xyz X Y Z Specify a seed point for the pons during the fill operation. This is used to cut the brain stem from brain. By default, this point will be determined automatically. It should only be specified if there is a cut failure. To determine what this point should be, find the center of the pons in the T1 volume (in tkmedit) and record the Talairach XYZ values. If the talairach is not available, use the Volume RAS Coordinates. -cc-xyz X Y Z Specify a seed point for the corpus callosum during the fill operation. This is used to help separate the hemispheres. By default, this point will be determined automatically. It should only be specified if there is a cut failure. To determine what this point should be, find the center of the corpus callosum in the T1 volume (in tkmedit) and record the Talairach XYZ values. If the talairach is not available, use the Volume RAS Coordinates. -lh-xyz X Y Z Specify a seed point for the left hemisphere during the fill operation. This is used to help identify the left hemisphere. By default, this point will be determined automatically. It should only be specified if there is a cut failure. To determine what this point should be, find a point in the white matter mass of the left hemisphere in the T1 volume (in tkmedit) and record the Talairach XYZ values. If the talairach is not available, use the Volume RAS Coordinates. Remember that tkmedit displays the volume in radiological convention (ie, left is right). -rh-xyz X Y Z Same as -lh-xyz but for the right hemisphere. -fill-with-aseg Fill subcortical structures based on results from automatic subcortical. segmentation. -watershed cmd This controls how the skull stripping will be performed. Legal values are normal (the default), atlas, nowatershed, watershedonly, and watershedtemplate. -wsmore/-wsless Increase/decrease the preflooding height (threshold) when skull stripping. -wsmore will expand the skull surface; -wsless will shrink the skull surface. See also -wsthresh. -wsthresh pctheight Explicitly set the preflooding height when skull stripping. -wsseed R C S Supply a point in the volume that the user believes to be in the white matter. By default, this point will be determined automatically. It should only be specified if there is a strip failure. To determine what this point should be, find a point in the white matter using tkmedit and record the Volume Index values (NOT the XYZ coordinates). -gca gcafile dASEGd dASEGd Specify the full path to the gaussian classifier array (GCA) file dASEGd to be used with GCA registration and automatic subcortical dASEGd segmentation. Default is FREESURFER_HOME/average/talairach_mixed.gca. dASEGd This has no effect unless the GCA registration or subcortical dASEGd segmentation stages are to be performed. dASEGd dASEGd -nuiterations Number of iterations in the non-uniform intensity correction. Default is 4. -norm3diters niters Use niters 3d normalization iterations (passes as -n to mri_normalize). -edit_wm_with_aseg Uses the results of the automatic subcortical segmentation to edit the WM. Uses wm-init as the input volume. See also -subcortseg. -no-fix-with-ga Use genetic algorithm during automatic topology fixing (adds -ga -keep 0 to the mris_fix_topology command line). NOTIFICATION FILES Notification files allow the user to cascade invocations to recon-all, with one invocation waiting until another one terminates. This is done by specifying a file that must exist before an invocation can precede (-waitfor) and/or specifying a file that is created when an invocation terminates (-notify). This type of interprocess communication can allow users to parallelize the stream. If this is to be done, note that each hemisphere can be run separately by specifying the -hemi flag. LOG AND STATUS FILES By default, log and status files are created in subjid/scripts. The log file contains all the output from all the programs that have been run during the invocation to recon-all. The status file has a list of all the programs that have been run and the time at which each started. The log file is intended to be a record of what was done whereas the status file allows the user to easily see where in the stream a currently running process is. The log file should be sent with all bug reports. By default, these files are called recon-all.log and recon-all.status, but this can be changed with the -log and -status options. By default, the log and status are appended to. New log and status files can be forced with the -noappend flag. OTHER ARGUMENTS -sd subjectsdir This allows the user to specify the root of the FreeSufer subjects directory. If unspecified, the environment variable SUBJECTS_DIR is used. -mail username Send email to username when the process terminates. STEP DESCRIPTION SUMMARIES Motion Correction (-motioncor) When there are multiple source volumes, this step will correct for small motions between them and then average them together. The input are the COR volumes found in mri/orig/XXX (or mri/XXX.mgz with the -mgz option). The output will be the orig COR volune in mri/orig (or orig.mgz with the -mgz option). If no runs are found then it looks for a volume in mri/orig (or mri/orig.mgz). If that volume is there, then it is used in subsequent processes as if it was the motion corrected volume. If no volume is found, then the process exits with errors. It uses the MINC program minctracc (see Collins, et al, 1994) through a FreeSurfer script called mri_motion_correct. Users must have the MINC tools installed. Talairach (-talairach) This computes the affine transform from the orig volume to the MNI305 atlas using the MINC program mritotal (see Collins, et al, 1994) through a FreeSurfer script called talairach. Users must have the MINC tools installed. Several of the downstream programs use talairach coordinates as seed points. You can/should check how good the talairach registration is using "tkregister2 --s subjid --fstal". You must have a "talairach" subject in your SUBJECTS_DIR. tkregister2 allows you to compare the orig volume against the talairach volume resampled into the orig space. If you modify the registration, it will change the talairach.xfm file. Your edits will be overwritten if you run recon-all without specifying -notalairach. Run "tkregister2 --help" for more information. Normalization (-normalization) Performs intensity normalization of the orig volume and places the result in T1 (or T1.mgz). Attempts to correct for fluctuations in intensity that would otherwise make intensity-based segmentation much more difficult. Intensities for all voxels are scaled so that the mean intensity of the white matter is 110. If there are problems with the normalization, users can add control points. If -usenuintensitycor is specified, then the input comes from the nu directory intead of orig (to create this volume, run with -nuintensitycor). A file called mri/T1/input-source is created indicating which input was used for intensity normalization. See also Normalization2. Skull Strip (-skullstrip) Removes the skull from mri/T1 and stores the result in mri/brain (or mri/brain.mgz). Runs the mri_watershed program. If the strip fails, users can specify seed points (-wsseed) or change the threshold (-wsthresh, -wsmore, -wsless). Normalization2 (-normalization) Performs a second intensity using only the brain volume as the input (so that it has to be done after the skull strip). Intensity normalization works better when the skull has been removed. Creates a new T1 volume. It also creates a new brain volume by masking the T1 with the original brain mask. Currently, this is not automatically performed with Stage1 as this is experimental. Segmentation -segmentation Attempts to separate white matter from everything else. The input is mri/brain, and the output is mri/wm (or wm.mgz). Uses intensity, neighborhood, and smoothness constraints. This is the volume that is edited when manually fixing defects. Calls mri_segment. To keep previous edits, run with -keepwmedits. Cut/Fill -fill This creates the subcortical mass from which the orig surface is created. The mid brain is cut from the cerebrum, and the hemispheres are cut from each other. The left hemisphere is binarized to 255. The right hemisphere is binarized to 127. The input is mri/wm and the output is mri/filled (or filled.mgz). Calls mri_fill. If the cut fails, then seed points can be supplied (-cc-xyz, -pons-xyz, -lh-xyz, -rh-xyz). The actual points used for the cutting planes in the corpus callosum and pons can be found in scripts/ponscc.cut.log. Tessellation -tessellate This is the step where the orig surface (ie, surf/?h.orig) is created. The surface is created by covering the filled hemisphere with triangles. Runs mri_tessellate. The places where the points of the triangles meet are called vertices. Note: the topology fixer will over-write the orig surface. Orig Surface Smoothing (-smooth1, -smooth2) After tesselation, the orig surface is very jagged because each triangle is on the edge of a voxel face and so are at right angles to each other. The vertex positions are adjusted slightly here to reduce the angle. This is only necessary for the inflation processes. Creates surf/?h.smoothwm. Calls mris_smooth. Smooth1 is the step just after tessellation, and smooth2 is the step just after topology fixing. Inflation (-inflate1, -inflate2) Inflation of the surf/?h.smoothwm surface to create surf/?h.inflated. The inflation attempts to minimize metric distortion so that distances and areas are perserved (ie, the surface is not stretched). In this sense, it is like inflating a paper bag and not a balloon. Inflate1 is the step just after tessellation, and inflate2 is the step just after topology fixing. Calls mris_inflate. Creates ?h.inflated, ?h.sulc, ?h.curv, and ?h.area. QSphere (-qsphere) This is the initial step of automatic topology fixing. It is a "quick" spherical morph of the inflated surface designed to make the topological defects show up clearly to the automatic topology fixer. Calls mris_sphere. Creates surf/?h.qsphere. Automatic Topology Fixer (-fix) Findes topological defects (ie, holes in a filled hemisphere) using surf/?h.qsphere, and changes the orig surface (surf/?h.orig) to remove the defects. Changes the number of vertices. All the defects will be removed, but the user should check the orig surface in the volume to make sure that it looks appropriate. Calls mris_fix_topology. Overwrites surf/?h.orig. Euler Number (-euler) Computes the euler number of the orig surface. If there are no defects, the euler number will be 2 (0 holes). Creates surf/?h.orig.euler, which is just a text file with the output of mris_euler_number. Final Surfaces (-finalsurfs) Creates the ?h.white and ?h.pial surfaces as well as the thickness file (?h.thickness). The white surface is created by "nudging" the orig surface so that it closely follows the white-gray intensity gradient as found in the T1 volume. The pial surface is created by expanding the white surface so that it closely follows the gray-CSF intensity gradient as found in the T1 volume. Calls mris_make_surfaces. Cortical Ribbon Mask (-cortribbon) Creates binary volume masks of the cortical ribbon, ie, each voxel is either a 1 or 0 depending upon whether it falls in the ribbon or not. Saved as ?h.ribbon.mgz. Uses mgz regardless of whether the -mgz option is used. Spherical Inflation (-sphere) Inflates the orig surface into a sphere while minimizing metric distortion. This step is necessary in order registrer the surface to the spherical atlas. (also known as the spherical morph). Calls mris_sphere. Creates surf/?h.sphere. Ipsilateral Surface Registation (Spherical Morph) (-surfreg) Registers the orig surface to the spherical atlas through surf/?h.sphere. The surfaces are first coarsely registered by aligning the large scale folding patterns found in ?h.sulc and then fine tuned using the small-scale patterns as in ?h.curv. Calls mris_register. Creates surf/?h.sphere.reg. Contralateral Surface Registation (Spherical Morph) (-contasurfreg) Same as ipsilateral but registers to the contralateral atlas. Creates lh.rh.sphere.reg and rh.lh.sphere.reg. Average Curvature (-avgcurv) Resamples the average curvature from the atlas to that of the subject. Allows the user to display activity on the surface of an individual with the folding pattern (ie, anatomy) of a group. Calls mrisp_paint. Creates surf/?h.avg_curv. Average Labels (-avglabels) This is obsolete because full surface parcellation is now done automatically with -cortparc. This supplies all labels which can then be checked to make sure that they ended up in the right place. It is still possible to to use this flag, but it is turned off by default. If you turn it on, make sure that you have an average7 subject. Resamples several labels from the average7 subject onto the surface of the subject. The labels are for the calcarine central, and superior temporal sulci. The purpose of this is to help check how well the registration performed. The user can view these labels in tksurfer by loading them through the File->Label->Load. Creates ?h-calcarine_sulcus.label, ?h-central_sulcus.label, and ?h-superior_temporal_sulcus.label in the label directory. Parcellation Statistics (-parcstats) Runs mris_anatomical_stats to create a summary table of cortical parcellation statistics for each structure, including 1. structure name 2. number of vertices 3. total surface area (mm^2) 4. total gray matter volume (mm^3) 5. average cortical thickness (mm) 6. standard error of cortical thicknessr (mm) 7. integrated rectified mean curvature 8. integrated rectified Gaussian curvature 9. folding index 10. intrinsic curvature index. The file is saved in scripts/?h.aparc.stats. Automatic Subcortical Segmentation <-subcortseg> This is done in four stages. (1) CGA linear registration (-cgareg). This is an initial registration to a template. (2) Canonical Normalization (-canorm), (3) Cannonical Registration (-careg). (4) Subcortical labeling (-calabel). See also -edit_wm_with_aseg. MANUAL CHECKING AND EDITING OF SURFACES To manually edit segmenation, run the following command (make sure that your SUBJECTS_DIR environment variable is properly set). tkmedit subjid wm -aux T1 The surfaces can be loaded through the menu item File->LoadMainSurface. To enable editing, set Tools->EditVoxels. It may also be convenient to bring up the reconstruction toolbar with View->ToolBars->Reconstruction. Alt-C toggles between the main (wm) and auxiliary (T1) volumes. Middle clicking will set a voxel value to 255; left clicking will set a voxel value to 0. Only edit the wm volume. When finished, File-SaveMainVolume. To view the inflated surface simultaneosly with the volume, run the following command from a different shell: tksurfer subjid lh inflated To goto a point on the surface inside the volume, click on the point and hit SavePoint (icon looks like a floppy disk), then, in tkmedit, hit GotoSavedPoint (icon looks like an open file). USING COMPRESSED MGH FORMAT (MGZ) MGZ format can be used by specifying the -mgz flag. The MGH format is a single-file format in which both pixel and meta data are stored. Files in this format have a .mgh extension. This can be compressed with gzip to give a compressed MGH format for which the extension is .mgz. This can provide substantial savings on disk space, but it does change the way that the data are stored. When COR format is used, an entire directory must be dedicated to the volume, and the volume is identified by the directory name (eg, mri/brain contains the skull-stripped volume). When MGZ is used, the COR volume and directory are replaced by a single file named directory.mgz (eg, brain.mgz). When setting up the raw data in the subject directory, create MGZ files with the names RRR.mgz in the mri directory, where RRR is the 3-digit, 0-padded run number (eg, 004.mgz). Do not use numbers over 100. Note that the input runs do not have to be conformed (ie, 256^3, 1mm isotropic). The input runs will be motion corrected and averaged togther into rawavg.mgz which will then be conformed into orig.mgz. FLATTENING Flattening is not actually done in this script. This part just documents how one would go about performing the flattening. First, load the subject surface into tksurfer: tksurfer subjid lh inflated Load the curvature through the File->Curvature->Load menu (load lh.curv). This should show a green/red curvature pattern. Red = sulci. Right click before making a cut; this will clear previous points. This is needed because it will string together all the previous places you have clicked to make the cut. To make a line cut, left click on a line of points. Make the points fairly close together; if they are too far appart, the cut fails. After making your line of points, execute the cut by clicking on the Cut icon (scissors with an open triangle for a line cut or scissors with a closed triangle for a closed cut). To make a plane cut, left click on three points to define the plane, then left click on the side to keep. Then hit the CutPlane icon. Fill the patch. Left click in the part of the surface that you want to form your patch. Then hit the Fill Uncut Area button (icon = filled triangle). This will fill the patch with white. The non-patch area will be unaccessible through the interface. Save the patch through File->Patch->SaveAs. For whole cortex, save it to something like lh.cort.patch.3d. For occipital patches, save it to lh.occip.patch.3d. Cd into the subject surf directory and run mris_flatten -w N -distances Size Radius lh.patch.3d lh.patch.flat where N instructs mris_flatten to write out an intermediate surface every N interations. This is only useful for making movies; otherwise set N=0. Size is maximum number of neighbors; Radius radius (mm) in which to search for neighbors. In general, the more neighbors that are taken into account, the less the metric distortion but the more computationally intensive. Typical values are Size=12 for large patches, and Size=20 for small patches. Radius is typically 7. Note: flattening may take 12-24 hours to complete. The patch can be viewed at any time by loading the subjects inflated surface, then loading the patch through File->Patch->LoadPatch... GETTING HELP Send email to freesurfer@nmr.mgh.harvard.edu. Also see http://surfer.nmr.mgh.harvard.edu. In particular, there is both a reconstruction guide and tutorial as well as manuals for tkmedit and tksurfer. REFERENCES [1] Collins, DL, Neelin, P., Peters, TM, and Evans, AC. (1994) Automatic 3D Inter-Subject Registration of MR Volumetric Data in Standardized Talairach Space, Journal of Computer Assisted Tomography, 18(2) p192-205, 1994 PMID: 8126267; UI: 94172121 [2] Cortical Surface-Based Analysis I: Segmentation and Surface Reconstruction Dale, A.M., Fischl, Bruce, Sereno, M.I., (1999). Cortical Surface-Based Analysis I: Segmentation and Surface Reconstruction. NeuroImage 9(2):179-194 [3] Fischl, B.R., Sereno, M.I.,Dale, A. M. (1999) Cortical Surface-Based Analysis II: Inflation, Flattening, and Surface-Based Coordinate System. NeuroImage, 9, 195-207. [4] Fischl, Bruce, Sereno, M.I., Tootell, R.B.H., and Dale, A.M., (1999). High-resolution inter-subject averaging and a coordinate system for the cortical surface. Human Brain Mapping, 8(4): 272-284 [5] Fischl, Bruce, and Dale, A.M., (2000). Measuring the Thickness of the Human Cerebral Cortex from Magnetic Resonance Images. Proceedings of the National Academy of Sciences, 97:11044-11049. [6] Fischl, Bruce, Liu, Arthur, and Dale, A.M., (2001). Automated Manifold Surgery: Constructing Geometrically Accurate and Topologically Correct Models of the Human Cerebral Cortex. IEEE Transactions on Medical Imaging, 20(1):70-80 [7] Non-Uniform Intensity Correction. http://www.bic.mni.mcgill.ca/software/N3/node6.html [8] Fischl B, Salat DH, Busa E, Albert M, Dieterich M, Haselgrove C, van der Kouwe A, Killiany R, Kennedy D, Klaveness S, Montillo A, Makris N, Rosen B, Dale AM. Whole brain segmentation: automated labeling of neuroanatomical structures in the human brain. Neuron. 2002 Jan 31;33(3):341-55. [9] Bruce Fischl, Andre van der Kouwe, Christophe Destrieux, Eric Halgren, Florent Segonne, David H. Salat, Evelina Busa, Larry J. Seidman, Jill Goldstein, David Kennedy, Verne Caviness, Nikos Makris, Bruce Rosen, and Anders M. Dale. Automatically Parcellating the Human Cerebral Cortex. Cerebral Cortex January 2004; 14:11-22.