#! /bin/tcsh -f # # make_average_surface # # Creates average surfaces and curvatures from a set of subjects. # # --help option will show usage # # Original Author: Doug Greve # CVS Revision Info: # $Author: zkaufman $ # $Date: 2016/02/16 17:17:20 $ # $Revision: 1.62 $ # # Copyright © 2011 The General Hospital Corporation (Boston, MA) "MGH" # # Terms and conditions for use, reproduction, distribution and contribution # are found in the 'FreeSurfer Software License Agreement' contained # in the file 'LICENSE' found in the FreeSurfer distribution, and here: # # https://surfer.nmr.mgh.harvard.edu/fswiki/FreeSurferSoftwareLicense # # Reporting: freesurfer@nmr.mgh.harvard.edu # # # uncomment this to increase number of allowable open files to maximum: #limit descriptors unlimited set VERSION = '$Id: make_average_surface,v 1.62 2016/02/16 17:17:20 zkaufman Exp $'; setenv FIX_VERTEX_AREA set PrintHelp = 0; set UseSymLink = 1; set sdout = (); set inputargs = ($argv); set surflist = (white pial orig) if ( $?SUBJECTS) then set SUBJECTS=($SUBJECTS) endif if ( $?SUBJECTS_DIR) then set SUBJECTS_DIR=($SUBJECTS_DIR) endif set average_subject=average set sphere_reg=sphere.reg set transform_fname="" set XFORM_FLAG="" set ico_no=7 set DoXHemi = 0; set topdir = (); set DoTemplateOnly = 0; set hemilist = (); set measlist = () set UseAnnot = 1; set annotlist = () set DoCortexLabel = 1; set NoSurf2Surf = ""; # these should match latest declarations in recon-all set DESIKAN_GCS = curvature.buckner40.filled.desikan_killiany.2010-03-25.gcs set DESTRIEUX_GCS = destrieux.simple.2009-07-29.gcs # note: SUBJECTS can be set by --subjects # SUBJECTS_DIR can be set by --sdir # average_subject can be set by --out # sphere_reg can be set by --surf-reg # transform_fname can be set by --xform (default is no file specified) # XFORM_FLAG appends -X to transform_fname if --xform is specified if($#argv == 0) then # zero args is allowed only if SUBJECTS env var is declared if ( ! $?SUBJECTS) then goto usage_exit; endif endif source $FREESURFER_HOME/sources.csh goto parse_args; parse_args_return: goto check_params; check_params_return: # This will put the data under $sdout (SUBJECTS_DIR by default) set ddir = ${sdout}/${average_subject} mkdir -p ${ddir} \ ${ddir}/surf \ ${ddir}/mri \ ${ddir}/mri/transforms \ ${ddir}/scripts \ ${ddir}/label \ ${ddir}/stats cd $sdout/${average_subject} set LF = ${ddir}/scripts/make_average_surface.log if(-e $LF) mv $LF $LF.bak echo "" | tee -a $LF echo "setenv SUBJECTS_DIR $SUBJECTS_DIR" | tee -a $LF echo $0 $inputargs | tee -a $LF echo "" | tee -a $LF echo $VERSION | tee -a $LF date | tee -a $LF pwd | tee -a $LF echo "output ddir is $sdout" | tee -a $LF id | tee -a $LF set tSecStart = `date '+%s'`; # # Begin script guts... # echo ==================== | tee -a $LF echo make_average_surface | tee -a $LF echo ==================== | tee -a $LF date | tee -a $LF pwd | tee -a $LF echo $0 | tee -a $LF echo $inputargs | tee -a $LF echo input subjects: ${SUBJECTS} | tee -a $LF echo output subject: ${average_subject} | tee -a $LF # Copy MNI 305 to output mri dir set mni305 = $FREESURFER_HOME/average/mni305.cor.mgz if(! -e $mni305) then echo "ERROR: cannot find $mni305" exit 1; endif cp $mni305 $sdout/${average_subject}/mri # Set the MNI305 xfm fname to 'auto' set mnivol = $sdout/${average_subject}/mri/mni305.cor.mgz set cmd = (mri_add_xform_to_header -c auto $mnivol $mnivol) echo $cmd | tee -a $LF $cmd | tee -a $LF if($status) exit 1; # Create a file with the list of subjects (will not include xhemi) set subjlistfile = /tmp/subjlistfile.$$ rm -f $subjlistfile foreach s ($SUBJECTS) echo $s >> $subjlistfile end cp $subjlistfile list.subjects.txt set subjlistfile = $sdout/$average_subject/list.subjects.txt # These are files that will exist when making surfaces from # subcortical structures with seg2surf (DNG) set fname = $SUBJECTS_DIR/$SUBJECTS[1]/rgb.dat if(-e $fname) then cp $fname $sdout/$average_subject endif set fname = $SUBJECTS_DIR/$SUBJECTS[1]/segname if(-e $fname) then cp $fname $sdout/$average_subject endif # Include cross-hemi registration if($DoXHemi) then set tmp = (); foreach s ($SUBJECTS) set tmp = ($tmp $s $s/xhemi) end set SUBJECTS = ($tmp); endif #------------------------------------------------------------ # Make the lh and rh template first so that other jobs can be started foreach hemi ($hemilist) echo "" | tee -a $LF # ------------------------------------------------------------------ echo "#@# Making $hemi registration template ---------" | tee -a $LF set atlas = $hemi.reg.template.tif set cmd = (mris_make_template -norot) if($UseAnnot) set cmd = ($cmd -annot aparc) set cmd = ($cmd $hemi $sphere_reg $SUBJECTS $atlas) pwd | tee -a $LF echo $cmd | tee -a $LF $cmd |& tee -a $LF if($status) exit(1); end #------------------------------------------------------------ # Now do everything else foreach hemi ($hemilist) if($DoTemplateOnly) continue; echo "" | tee -a $LF cd $sdout/$average_subject #-------------------------------------------------------------- foreach s ($surflist) echo "#@# Making average $hemi.$s surface ---------------------" | tee -a $LF date | tee -a $LF set cmd = (mris_make_average_surface $NoSurf2Surf $XFORM_FLAG \ -i $ico_no -o $s -sdir-out $sdout\ ${hemi} \ ${s} ${sphere_reg} \ ${average_subject} \ $SUBJECTS ) pwd | tee -a $LF echo $cmd | tee -a $LF $cmd |& tee -a $LF if($status) then echo "mris_average_surface failed" | tee -a $LF exit 1; endif echo "" | tee -a $LF echo "" | tee -a $LF end # loop over surfaces #-------------------------------------------------------------- # Create sphere and sphere.reg. mris_make_average_surface creates # its own sphere.reg (unless using the surf2surf option) so delete # it and copy ico rm -f surf/$hemi.$sphere_reg if($ico_no == 7) then # for historical reasons, use ?h.sphere.reg for ico7 set icoreg = ${FREESURFER_HOME}/average/surf/${hemi}.sphere.reg else set icoreg = ${FREESURFER_HOME}/average/surf/${hemi}.sphere.ico$ico_no.reg endif cp $icoreg surf/$hemi.sphere # Create a link to sphere.reg (want to do this? or reg to fsaverage?) if($UseSymLink) then cd surf ln -s $hemi.sphere $hemi.sphere.reg ln -s $hemi.sphere $hemi.$average_subject.sphere.reg cd .. else cp surf/$hemi.sphere surf/$hemi.sphere.reg cp surf/$hemi.sphere surf/$hemi.$average_subject.sphere.reg endif echo "---------------------------------------------------" | tee -a $LF echo "" | tee -a $LF #-------------------------------------------------------------- echo "#@# Smoothing, inflating, etc $hemi ----------------" | tee -a $LF cd $sdout/${average_subject}/surf pwd | tee -a $LF # Smooth white to get smoothwm (should average the indiv smoothwms?) set cmd = (mris_smooth -nw -n 5 ./${hemi}.white ./${hemi}.smoothwm) echo $cmd |& tee -a $LF $cmd | tee -a $LF if($status) exit 1; echo "" | tee -a $LF # Inflate the smoothwm set niters = "-n 15"; if($ico_no <= 5) set niters = "-n 2"; set cmd = (mris_inflate -dist .01 -f .001 -no-save-sulc $niters ./${hemi}.smoothwm ./${hemi}.inflated) echo $cmd |& tee -a $LF $cmd | tee -a $LF if($status) exit 1; echo "" | tee -a $LF cd $sdout/$average_subject # Create average annot if($UseAnnot) then foreach annot ($annotlist) set cmd = (annot2std --o label/$hemi.$annot.annot --$hemi \ --f $subjlistfile --t $average_subject --a $annot \ --srcsurfreg $sphere_reg --trgsurfreg sphere.reg) if($DoXHemi) set cmd = ($cmd --xhemi) echo $cmd | tee -a $LF $cmd |& tee -a $LF if($status) exit 1 end # Create cortex label from Christophe's medial wall if($DoCortexLabel) then set annot = $ddir/label/$hemi.aparc.a2009s.annot if(! -e $annot) then echo "ERROR: cannto find $annot" |& tee -a $LF exit 1; endif # Create tmpdir set tmpdir = $ddir/make_cortex_label.tmp.$$ rm -rf $tmpdir mkdir -p $tmpdir # Unload all of Christophe's labels into tmpdir set cmd = (mri_annotation2label --subject $average_subject \ --hemi $hemi --outdir $tmpdir --annotation aparc.a2009s) echo $cmd |& tee -a $LF $cmd |& tee -a $LF if($status) exit 1; # Create the medial wall label set unknown_label = $tmpdir/$hemi.Unknown.label set mw_label = $tmpdir/$hemi.Medial_wall.label if(! -e $unknown_label && ! -e $mw_label) then echo "ERROR: cannot find $hemi.Unknown.label or $hemi.Medial_wall.label" exit 1; else if(-e $unknown_label && -e $mw_label) then set cmd = (mri_mergelabels -i $unknown_label -i $mw_label -o $ddir/label/$hemi.Medial_wall.label) echo $cmd |& tee -a $LF $cmd |& tee -a $LF if($status) exit 1; rm -f $unknown_label $mw_label else if(-e $unknown_label) then mv $unknown_label $ddir/label/$hemi.Medial_wall.label else if(-e $mw_label) then mv $mw_label $ddir/label/$hemi.Medial_wall.label endif # Create the cortex label with all the remaining labels set ctxlabel = $ddir/label/$hemi.cortex.label set cmd = (mri_mergelabels -o $ctxlabel -d $tmpdir) echo $cmd |& tee -a $LF $cmd |& tee -a $LF if($status) exit 1; rm -rf $tmpdir; # Cleanup endif # DoCortexLabel endif # Create average surface measures foreach meas ($measlist) set measout = $ddir/surf/stack.$hemi.$meas.mgh set cmd = (mris_preproc --out $measout --f $subjlistfile \ --target $average_subject --hemi $hemi --meas $meas \ --srcsurfreg $sphere_reg --log $ddir/scripts/mris_preproc.$hemi.$meas.log) if($DoCortexLabel == 0) set cmd = ($cmd --no-cortex-only) if($DoXHemi) set cmd = ($cmd --xhemi) echo $cmd | tee -a $LF $cmd |& tee -a $LF if($status) exit 1 # Compute average across subject set avgmeas = $ddir/surf/$hemi.$meas.avg.mgh if($meas == area) set avgmeas = $ddir/surf/$hemi.white.avg.area.mgh; # backcompat set cmd = (mri_concat $measout --mean --o $avgmeas) echo $cmd | tee -a $LF $cmd |& tee -a $LF if($status) exit 1 # Compute std across subject set stdmeas = $ddir/surf/std.$hemi.$meas.mgh set cmd = (mri_concat $measout --std --o $stdmeas) echo $cmd | tee -a $LF $cmd |& tee -a $LF if($status) exit 1 # Convert avg to curv set tval = $ddir/surf/$hemi.$meas set cmd = (mri_surf2surf --sval $avgmeas --s $average_subject \ --tval $tval --trg_type curv --hemi $hemi) pwd | tee -a $LF echo $cmd | tee -a $LF $cmd |& tee -a $LF if($status) exit 1 # Delete temporary stuff if($meas != area) rm $avgmeas end # meas end # hemi echo "---------------------------------------------------" | tee -a $LF echo "" | tee -a $LF set tSecEnd = `date '+%s'`; @ tSecRun = $tSecEnd - $tSecStart; set tRunHours = `echo $tSecRun/3600|bc -l` set tRunHours = `printf %5.2f $tRunHours` echo "make_average_surface-Run-Time-Hours $tRunHours" |& tee -a $LF date | tee -a $LF echo "make_average_surface done" | tee -a $LF echo "" exit 0 ############################################### ############--------------################## parse_args: set cmdline = ($argv); set getting_subjects = 0; while( $#argv != 0 ) set flag = $argv[1]; if (! $getting_subjects) then shift; endif switch($flag) case "--help": set PrintHelp = 1; goto usage_exit; exit 0; case "--version": echo $VERSION exit 0; case "--s": case "--subjects": if ( $#argv == 0) goto arg1moreerr; set SUBJECTS = $argv[1]; shift; # loop on getting variable number of subject names set getting_subjects = 1; # see 'default:' case breaksw case "--fsgd": if ( $#argv == 0) goto arg1err; set fsgdf = $argv[1]; shift; if(! -e $fsgdf) then echo "ERROR: cannot find $fsgdf"; exit 1; endif set sl = `cat $fsgdf | awk '{if($1 == "Input") print $2}'`; set SUBJECTS = ($sl); breaksw case "--out": if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if ( $#argv == 0) goto arg1err; set average_subject = $argv[1]; shift; breaksw case "--surfreg": case "--surf-reg": case "--surf_reg": if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if ( $#argv == 0) goto arg1err; set sphere_reg = $argv[1]; shift; breaksw case "--surf": if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if( $#argv == 0) goto arg1err; set surflist = $argv[1]; shift; breaksw case "--topdir": case "--sd-out": if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if( $#argv < 1) goto arg1err; set sdout = $argv[1]; shift; breaksw case "--sd": case "--sdir": if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if ( $#argv == 0) goto arg1err; set SUBJECTS_DIR = $argv[1]; shift; setenv SUBJECTS_DIR $SUBJECTS_DIR breaksw case "--xform": if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if ( $#argv == 0) goto arg1err; set transform_fname = $argv[1]; shift; set XFORM_FLAG = "-X $transform_fname"; breaksw case "--ico": case "--i": if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if ( $#argv == 0) goto arg1err; set ico_no = $argv[1]; shift; breaksw case "--meas" if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if($#argv < 1) goto arg1err; set measlist = ($measlist $argv[1]); shift; breaksw case "--symlink": if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif set UseSymLink = 1; breaksw case "--annot" if ( $getting_subjects ) then # got em all, from --subjects variable arg loop set getting_subjects = 0; shift; endif if($#argv < 1) goto arg1err; set annotlist = ($annotlist $argv[1]); shift; breaksw case "--no-annot": if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif set UseAnnot = 0; breaksw case "--no-cortex-label": if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif set DoCortexLabel = 0; breaksw case "--no-symlink": case "--no-link": if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif set UseSymLink = 0; breaksw case "--nocleanup": # This has no effect, but needed for compat with make_average_volume set cleanup = 0; if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--no-surf2surf": # for mris_make_average_surface to use old method of parametric surface set NoSurf2Surf = "-no-surf2surf"; if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--debug": case "--echo": set echo = 1; set verbose = 1; if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--template-only": set DoTemplateOnly = 1; if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--no-template-only": set DoTemplateOnly = 0; if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--xhemi": set DoXHemi = 1; if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--lh": set hemilist = (lh) if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--rh": set hemilist = (rh) if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--lhrh": set hemilist = (lh rh) if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw case "--no-xhemi": set DoXHemi = 0; if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw # These are flags passed to make_average_subject, but dont apply here case "--no-surf": case "--no-vol": case "--force": case "--link": case "--keep-all-orig": case "--no-ribbon": if ( $getting_subjects ) then set getting_subjects = 0; # got em all, from --subjects variable arg loop endif breaksw default: if ( $getting_subjects ) then # loop on getting variable number of subjects, # until a new flag is found, or no more args set SUBJECTS = ( $SUBJECTS $argv[1] ); shift; set getting_subjects = 1; else echo ERROR: Flag $flag unrecognized. echo $cmdline exit 1 endif breaksw endsw end goto parse_args_return; ############--------------################## ############--------------################## check_params: if (! $?SUBJECTS) then echo "ERROR: no subjects declared!" echo "Either declare subjects in SUBJECTS variable," echo "or declare using --subjects argument." exit 1 endif if (! $?SUBJECTS_DIR) then echo "ERROR: SUBJECTS_DIR is not declared!" echo "Either set the SUBJECTS_DIR environment variable," echo "or declare using --sdir argument, the root directory" echo "for subject data files." exit 1 endif if(! -e $SUBJECTS_DIR ) then echo "ERROR: SUBJECTS_DIR $SUBJECTS_DIR does not exist." 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($#sdout == 0) set sdout = $SUBJECTS_DIR; if($#hemilist == 0) set hemilist = (lh rh) if($#annotlist == 0) set annotlist = (aparc aparc.a2009s) if($#measlist == 0) set measlist = (sulc curv thickness area volume inflated.H) goto check_params_return; ############--------------################## ############--------------################## arg1err: echo "ERROR: flag $flag requires one argument" exit 1 ############--------------################## ############--------------################## arg1moreerr: echo "ERROR: flag $flag requires one or more arguments" exit 1 ############--------------################## ############--------------################## usage_exit: echo "" echo "USAGE: make_average_surface" echo "" echo "Required Arguments" echo " --subjects ... " echo " : or declare subjects in SUBJECTS env var" echo " --fsgd fsgdfile : get subject list from fsgd" echo "" echo "Optional Arguments" echo " --out : default name is 'average'" echo " --sdir " echo " --sd : same as --sdir" echo " --sd-out topdir : put data here" echo " --xform : filename of transform file" echo " --ico : specify icosahedron number, default is 7 (ic7.tri)" echo " --surf-reg : alternative registration surface" echo " --lh : only do left hemi (default is to do both)" echo " --rh : only do right hemi (default is to do both)" echo " default: sphere.reg" echo " --force : overwrite existing average subject data" echo " --no-annot : do not use annotation when making template tif" echo " --template-only : useful when creating iterative atlases" echo " --no-template-only : turns off --template-only" echo " --no-cortex-label : do not create ?h.cortex.label" echo " --annot annotname <--annot annotname > : supply list of annots to use (default $annotlist)" echo " --meas measname <--meas measname > : supply list of meass to use (default $measlist)" echo " --no-surf2surf : use old parametric surface method (may give big faces at the poles)" echo "" echo " --help : short descriptive help" echo " --no-symlink : do not use symbolic links (just copy files)" echo " --no-lik : same as --no-symlink" echo " --version : script version info" echo " --echo : enable command echo, for debug" echo " --debug : same as --echo" echo "" echo "See also: recon-all, make_final_surfaces, morph_subject" echo "" if(! $PrintHelp) exit 1; echo Version: $VERSION 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 Creates average surfaces and curvatures from a set of subjects. Calls mris_average_curvature, mris_make_average_surface, mris_smooth, mris_inflate, and mris_curvature. EXAMPLE make_average_surface --out avgsubject --subjects subj1 subj2 subj3 subj4 will create $SUBJECTS_DIR/avgsubject with average surfaces for orig, white, pial, inflated for each hemi. SEE ALSO make_average_subject, make_average_volume GETTING HELP Run recon-all --help for extensive text on the reconstruction process. Or, send email to freesurfer@nmr.mgh.harvard.edu. Also see http://surfer.nmr.mgh.harvard.edu.