#! /bin/tcsh -f

#
# make_average_subject
#
# Creates average surfaces, curvatures, and volumes from a set of subjects.
#
# --help option will show usage
#
# Original Author: Doug Greve
# CVS Revision Info:
#    $Author: fischl $
#    $Date: 2009/12/03 22:33:03 $
#    $Revision: 1.19 $
#
# Copyright (C) 2002-2007,
# The General Hospital Corporation (Boston, MA).
# All rights reserved.
#
# Distribution, usage and copying of this software is covered under the
# terms found in the License Agreement file named 'COPYING' found in the
# FreeSurfer source code root directory, and duplicated here:
# https://surfer.nmr.mgh.harvard.edu/fswiki/FreeSurferOpenSourceLicense
#
# General inquiries: freesurfer@nmr.mgh.harvard.edu
# Bug reports: analysis-bugs@nmr.mgh.harvard.edu
#

# uncomment this to increase number of allowable open files:
#limit descriptors unlimited

set VERSION = '$Id: make_average_subject,v 1.19 2009/12/03 22:33:03 fischl Exp $'
set PrintHelp = 0;
set sdout = ();
set average_subject = average;
set DoLink = 0;
set DoSurfaces = 1;
set DoVolumes  = 1;
set Force = 0;
set KeepAllOrig = 0;

set cmdargs = ($argv);

if($#argv == 0) then
  # zero args is allowed only if SUBJECTS env var is declared
  if ( ! $?SUBJECTS) then
    goto usage_exit;
  endif
endif

goto parse_args;
parse_args_return:

goto check_params;
check_params_return:

if($DoLink) then
  echo "Creating link"
  pushd $sdout > /dev/null
  set sdoutfulldir = `pwd`;
  pushd $SUBJECTS_DIR > /dev/null
  set cmd = (ln -s $sdoutfulldir/$average_subject $average_subject)
  echo $cmd
  $cmd
  if($status) then
    echo "ERROR: make_average_subject"
    exit 1;
  endif
  popd > /dev/null
  popd > /dev/null
endif

if($DoSurfaces) then
  set cmd = (make_average_surface $cmdargs)
  echo $cmd
  $cmd
  if($status) then
    echo "ERROR: make_average_surface"
    exit 1;
  endif
endif

if($DoVolumes) then
  set cmd = (make_average_volume $cmdargs)
  if($KeepAllOrig) set cmd = ($cmd --keep-all-orig)
  echo $cmd
  $cmd
  if($status) then
    echo "ERROR: make_average_volume"
    exit 1;
  endif
endif

exit 0
#----------------------------------------------------------#
############--------------##################
parse_args:
set cmdline = ($argv);

while( $#argv != 0 )

  set flag = $argv[1]; shift;

  switch($flag)

    case "--help":
      set PrintHelp = 1;
      goto usage_exit;
      exit 0;
      breaksw

    case "--version":
      echo $VERSION
      exit 0;
      breaksw

    case "--sd":
    case "--sdir":
      if ( $#argv == 0) goto arg1err;
      setenv SUBJECTS_DIR $argv[1]; shift;
      breaksw

    case "--out":
      if($#argv < 1) goto arg1err;
      set average_subject = $argv[1]; shift;
      breaksw

    case "--ico":
      if($#argv < 1) goto arg1err;
      set IcoOrder = $argv[1]; shift;
      breaksw

    case "--sd-out":
      if ( $#argv == 0) goto arg1err;
      set sdout = $argv[1]; shift;
      set DoLink = 1;
      breaksw

    case "--surf_reg":
    case "--surf-reg":
      if($#argv < 1) goto arg1err;
      set SurfReg = $argv[1]; shift;
      breaksw

    case "--no-link":
      set DoLink = 0;
      breaksw

    case "--link":
      set DoLink = 1;
      breaksw

    case "--no-surf":
      set DoSurfaces = 0;
      breaksw

    case "--no-vol":
      set DoVolumes = 0;
      breaksw

    case "--force":
      set Force = 1;
      set DoLink = 0;
      breaksw

    case "--keep-all-orig":
      set KeepAllOrig = 1;
      breaksw

   case "--debug":
   case "--echo":
      set echo = 1;
      set verbose = 1
      breaksw

    default:
      breaksw
  endsw

end
goto parse_args_return;

############--------------##################
arg1err:
  echo "ERROR: flag $flag requires one argument"
  exit 1
############--------------##################

############--------------##################
check_params:
  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
  set outdir = $sdout/$average_subject
  if(-e $outdir && ! $Force) then
    echo "ERROR: $outdir already exists, select a new average subject name"
    echo "       or delete and rerun"
    exit 1;
  endif
  if($sdout == $SUBJECTS_DIR) set DoLink = 0;
  if($DoLink && -e $SUBJECTS_DIR/$average_subject) then
    echo "ERROR: subject $average_subject already exists in $SUBJECTS_DIR."
    echo "       Cannot create link. Select a different average subject name"
    echo "       or delete and re-run."
    exit 1;
  endif
  if(! $DoSurfaces && ! $DoVolumes) then
    echo "ERROR: you have turned off computing both surfaces and volumes"
    echo " Nothing to do!"
    exit 1;
  endif
goto check_params_return;
############--------------##################

############--------------##################
usage_exit:
  echo ""
  echo "USAGE: make_average_subject"
  echo ""
  echo "Required Arguments"
  echo "   --subjects <subj1> <subj2> ... <subjN>"
  echo "             : or declare subjects in SUBJECTS env var"
  echo "   --fsgd fsgdfile : get subject list from fsgd"
  echo ""
  echo "Optional Arguments"
  echo "   --out <average subject name>    : default name is 'average'"
  echo "   --sd-out sdout : put output under sdout instead of SUBJECTS_DIR"
  echo "   --no-link : do not link back to the original SUBJECTS_DIR with --sd-out"
  echo "   --sdir <SUBJECTS_DIR to use instead of the one in the env>"
  echo "   --sd      : same as --sdir"
  echo "   --ico <ico order> : change order of icosahedron (default=7)"
  echo "   --xform <transform_fname>   : filename of transform file"
  echo "   --surf-reg <surface name>   : alternative registration surface"
  echo "                                 default: sphere.reg"
  echo "   --no-surf : do not make average surfaces"
  echo "   --no-vol  : do not make average volumes"
  echo "   --force   : overwrite existing average subject data"
  echo "   --keep-all-orig : concatenate all orig vols into mri/orig.all.mgz"
  echo "   --no-symlink : do not use symbolic links with surfs (just copy files)"
  echo ""
  echo "   --help    : short descriptive help"
  echo "   --version : script version info"
  echo "   --echo    : enable command echo, for debug"
  echo "   --debug   : same as --echo"
  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 subject by averaging surfaces, curvatures, and volumes
from a set of subjects. The surface is a 7th order icosahedron
tesselation.  For surfaces, the XYZ coordinate of a vertex is computed
as the average talairach coordinate of that vertex in each subject. The
talairach coordinate is based on talairach.xfm (unless changed with
--xform), so the individual talairachs must be accurate for the final
coordinate to be meaningful. Note that even though talairach coordinates
are used for surfaces, all surface-based averaging is done using the
surface atlas (NOT talairach averaging!).

Calls make_average_surface and make_average_volume. See these programs
for specific help.

The subject list can be specified in one of three ways:
  (1) on the command-line with --subjects
  (2) through the SUBJECTS environment variable
  (3) specifying a FreeSurfer Group Descriptor (FSGD) file. The FSGD is
      used by freesurfer to specify designs for statistical analysis.
      See surfer.nmr.mgh.harvard.edu/docs/fsgdf.txt.

The output will be created in SUBJECTS_DIR/averagesubjectname unless
--topdir is specified. In this case, the data are stored in
topdir/averagesubjectname, and a link is created to
SUBJECTS_DIR/averagesubjectname. This can convenient when your
the disk that hosts your SUBJECTS_DIR starts to get full.

EXAMPLES

Example 1:

  make_average_subject --out avgsubject --subjects subj1 subj2 subj3 subj4

will create $SUBJECTS_DIR/avgsubject with average surfaces for orig,
white, pial, inflated for each hemi. It will also create average volumes
for orig, brain, and T1.  Notice that the '--out avgsubject' is merely
overriding the default output name 'average'.

Example 2:

  setenv SUBJECTS = (subj1 subj2 subj3 subj4)
  make_average_subject --out avgsubject

will do the same as Example 1.

Example 3: check that the average subject volume aligns with the
talairach subject:

  tkregister2 --fstal --s avgsubject --mgz

Example 4: check that the average subject surfaces align with the
volume:

  tkmedit avgsubject orig.mgz lh.white

You should see that the surfaces more-or-less align with the folds.
Remember this is talairach, so the volume will be blurry.

SEE ALSO

make_average_volume, make_average_surface, recon-all, make_final_surfaces,
morph_subject

GETTING HELP

Run recon-all --help for extensive text on the reconstruction process.
Or, send email to freesurfer@nmr.mgh.harvard.edu
See also https://surfer.nmr.mgh.harvard.edu
