#! /bin/csh -f

#
# mc-sess - motion correction
#
# Original Author: Doug Greve
# CVS Revision Info:
#    $Author: greve $
#    $Date: 2008/01/18 06:17:42 $
#    $Revision: 1.16.2.1 $
#
# 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
#


set VERSION    = '$Id: mc-sess,v 1.16.2.1 2008/01/18 06:17:42 greve Exp $'
set cmdargs = ($argv);

set fsd = "bold";
set mcmethod   = "afni"
set targoff    = 0;
set targoffmid = 0;
set PerRun = 0;
set funcstem   = f;  # stem of functional volume
set funcmcstem = (); # stem of functional motion-corrected volume
set PWDCMD = `getpwdcmd`;
set targnthrun = 1;  # use nth run as target
set targrun = ();    # use explicit run as target
set RunListFile = ();
set targstem = ();
set DoInorm = 0;
set UpdateOnly = 0;
set mask = brain;

set nolog = 0;
set usenew = 1;

set infmt = ();
set outfmt = bhdr;
if($?FSF_OUTPUT_FORMAT) then
  set outfmt = $FSF_OUTPUT_FORMAT;
endif

if($#argv == 0) then
  goto usage_exit;
  exit 1;
endif

set n = `echo $argv | grep version | wc -l` 
if($n != 0) then
  echo $VERSION
  exit 0;
endif

set n = `echo $argv | grep citation | wc -l` 
if($n != 0) then
  echo "Those using the AFNI motion correction should cite:"
  echo "  RW Cox and A Jesmanowicz."
  echo "  Real-time 3D image registration for functional MRI."
  echo "  Magnetic Resonance in Medicine, 42: 1014-1018, 1999."
  exit 0;
endif

set SessList = `getsesspath $argv`;
if($status || $#SessList == 0) then
  echo $SessList
  exit 1;
endif

goto parse_args;
parse_args_return:

if($#funcmcstem == 0) set funcmcstem = fmc;

goto check_params;
check_params_return:

set ProjectDir = `pwd`;

## Check each session ##
foreach sess ($SessList)
  set sessid = `basename $sess`;
  if(! -d $sess) then
    echo "ERROR: $sess does not exist"  
    exit 1;
  endif
  if(! -d $sess/$fsd) then
    echo "ERROR: $sess/$fsd does not exist"  
    exit 1;
  endif
  if($DoInorm) then
    set maskpath = $sess/$fsd/masks/$mask
    set tmp = `getformat_from_stem $maskpath`;
    if($status) then
      echo "$tmp"
      echo "ERROR: cannot find $maskpath, needed for inorm"
      exit 1;
    endif
  endif
end

## Now analyze each session ##
foreach sess ($SessList)
  set sessid = `basename $sess`;

  # Create a log file #
  if(! $nolog ) then
    mkdir -p log
    set LF = $ProjectDir/log/mc-$sessid-$fsd.log
    rm -f $LF
    touch $LF
  else
    set LF = /dev/null
  endif
  echo Logfile is $LF

  echo "mc-sess" >> $LF
  echo $sessid      >> $LF
  echo $VERSION  >> $LF
  echo $LF       >> $LF
  uname -a       >> $LF
  date           >> $LF
  echo $cmdargs  >> $LF
  pwd            >> $LF
  echo "ProjectDir $ProjectDir" >> $LF

  echo "-------------------------------------------" |& tee -a $LF
  echo "$sess " |& tee -a $LF

  if(! -d $sess) then
    echo "ERROR: $sess does not exist"   |& tee -a $LF
    exit 1;
  endif

  pushd $sess/$fsd > /dev/null

  if(! $usenew) then
    ## get resolutions #
    set inplaneres  = `cat seq.info | awk '{if($1 == "rowpixelsize") print $2}'`;
    set betplaneres = `cat seq.info | awk '{if($1 == "slcpixelsize") print $2}'`;
    set TR = `cat seq.info | awk '{if($1 == "TR") print $2}'`;

    if($#inplaneres == 0) then
      echo "ERROR: seq.info file does not appear to be formated correctly"
      echo "       Try running fixseqinfo-sess."
      exit 1;
    endif
  endif # dont use new

  if($#RunListFile == 0) then
    set RunList = `getrunlist .`;
    if($status || $#RunList == 0) then
      echo "ERROR: $sess/$fsd has no runs"  |& tee -a $LF
      exit 1;
    endif
  else
    if(! -e $RunListFile) then
      echo "ERROR: cannot find runlistfile $RunListFile"
      exit 1;
    endif
    set RunList = `cat $RunListFile`;
  endif
  echo "RunList: $RunList" |& tee -a $LF

  if($#targrun == 0) then
    if($#RunList < $targnthrun) then
      echo "ERROR: $sessid target run ($targnthrun) exceeds "
      echo "   number of runs ($#RunList)."
      exit 1;
    endif
    if(! $PerRun) set targstem = $RunList[$targnthrun]/$funcstem
  else
    if(! $PerRun) set targstem = $targrun/$funcstem
  endif
  if($#targstem) echo "Targ Stem is $targstem"

  foreach run ($RunList)  
    set instem  = $run/$funcstem
    set infmtuse = `getformat_from_stem $instem $infmt`
    if($status) then
      echo "$infmtuse" 
      exit 1;
    endif
    set outstem = $run/$funcmcstem
    if($PerRun) set targstem = $instem
    if($targoffmid) then
      set nframes = `getnframes $instem`;
      set targoff = `echo $nframes/2 | bc`;
    endif
    if(! $usenew) then
      set cmd = (mc-$mcmethod -i $instem -o $outstem \
                 -t $targstem -toff $targoff);
      set cmd = ($cmd -ipr $inplaneres -bpr $betplaneres -TR $TR)
    else
      test $outstem.$outfmt -nt $instem.$infmtuse
      if($status || ! $UpdateOnly) then
        set cmd = (mc-afni2 --i $instem.$infmtuse --t $targstem.$infmtuse \
           --frame $targoff --o $outstem.$outfmt  --mcdat $outstem.mcdat)
      else
        set cmd = ();
      endif
    endif

    if($#cmd == 0 ) then
      echo "Update not needed " | tee -a $LF
      ls -lt $instem.$infmtuse $outstem.$outfmt | tee -a $LF
    else
      echo "  ------- ************************** -----------" |& tee -a $LF
      echo "  ------- Motion Correcting Run $run -----------" |& tee -a $LF
      echo "  ------- ************************** -----------" |& tee -a $LF
      echo "sess = $sessid" |& tee -a $LF
      date |& tee -a $LF
      echo $cmd |& tee -a $LF
      $cmd |& tee -a $LF
      if($status) exit 1;

      # Inorm = compute mean in mask (creates $outstem.meanval)
      if($DoInorm) then
        set maskpath = $sess/$fsd/masks/$mask
        set fmt = `getformat_from_stem $maskpath`;
        set cmd = (mri_segstats --seg $maskpath.$fmt --id 1 --sum /tmp/blah.$$ \
                     --in $outstem.$outfmt --sfavg $outstem.meanval )
        echo "cd `pwd`" |& tee -a $LF
        echo $cmd |& tee -a $LF
        $cmd |& tee -a $LF
        if($status) exit 1;
      endif
    
      # Create the external regresssor file -- this requires matlab
      echo "INFO: Making external regressor from mc params" |& tee -a $LF
      set cmd = (mcparams2extreg -mcfile $outstem.mcdat -northog 6)
      set cmd = ($cmd -extreg $run/mcextreg)
      echo $cmd |& tee -a $LF
      $cmd |& tee -a $LF
      if($status) exit 1;
    endif

  end # Loop over sessions 

  echo "" |& tee -a $LF
  echo "" |& tee -a $LF

  popd > /dev/null
end

date | tee -a $LF
echo "mc-sess completed SUCCESSFULLY" | tee -a $LF

exit 0;
###############################################


############--------------##################
parse_args:
set cmdline = "$argv";
while( $#argv != 0 )

  set flag = $argv[1]; shift;
  
  switch($flag)

    case "-ssd":
    case "-fsd":
      if ( $#argv == 0) goto arg1err;
      set fsd = $argv[1]; shift;
      breaksw

    case "-toff":
      if ( $#argv == 0) goto arg1err;
      set targoff = $argv[1]; shift;
      breaksw

    case "-fstem":
      if ( $#argv == 0) goto arg1err;
      set funcstem = $argv[1]; shift;
      breaksw

    case "-fmcstem":
      if ( $#argv == 0) goto arg1err;
      set funcmcstem = $argv[1]; shift;
      breaksw

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

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

    case "-runlistfile":
    case "-rlf":
      if ( $#argv == 0) goto arg1err;
      set RunListFile = $argv[1]; shift;
      breaksw

    case "-method":
      if ( $#argv == 0) goto arg1err;
      set mcmethod = $argv[1]; shift;
      if($mcmethod != "afni") then
        echo "ERROR: only afni supported"
        exit 1;
      endif
      breaksw

    case "-perrun":
      set PerRun = 1;
      set targoffmid = 1;
      breaksw

    case "-nolog":
      set nolog = 1;
      breaksw

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

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

    case "-new":
      set usenew = 1;
      breaksw

    case "-fmt":
      if ( $#argv == 0) goto arg1err;
      set fmt = $argv[1]; shift;
      set infmt = $fmt;
      set outfmt = $fmt;
      breaksw

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

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

    case "-inorm":
      set DoInorm = 1;
      breaksw

    case "-no-inorm":
      set DoInorm = 0;
      breaksw

    case "-update":
      set UpdateOnly = 1;
      breaksw

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

    case "-umask":
      if ( $#argv == 0) goto arg1err;
      set umaskarg = "-umask $argv[1]";
      umask $argv[1]; shift;
      breaksw

    case "-s":
    case "-sf":
    case "-d":
    case "-df":
    case "-g":
      shift;
      # ignore getsesspath arguments 
      breaksw

    case "-cwd":
      # ignore getsesspath arguments 
      breaksw

    default:
      echo ERROR: Flag $flag unrecognized. 
      echo $cmdline
      exit 1
      breaksw
  endsw

end

goto parse_args_return;
############--------------##################

############--------------##################
check_params:

  if ($#SessList == 0) then
     echo "ERROR: no sessions specified"
     exit 1
  endif

goto check_params_return;
############--------------##################

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

############--------------##################
usage_exit:
  echo ""
  echo "USAGE: mc-sess"
  echo ""
  echo "Optional Arguments:";
  echo "   -method  mcmethod  : afni"
  echo "   -targnthrun n      : use nth run as target (default=1)"
  echo "   -targrun RRR       : use run RRR as target"
  echo "   -toff m            : target image offset ($targoff)"
  echo "   -fstem stem        : stem of input volume <f>"
  echo "   -fmcstem stem      : stem of output motion-corrected volume (fmc)"
  echo "   -umask umask       : set unix file permission mask"
  echo "   -version           : print version and exit"
  echo "   -rlf  runlistfile  : only process those in the runlist file"
  echo "   -perrun            : MC each run separately (targ=mid)"
  echo "   -infmt  format     : <auto>, bhdr, mgh, mgz, nii, nii.gz"
  echo "   -outfmt format     : <bhdr>, mgh, mgz, nii, nii.gz"
  echo "   -inorm             : perform intensity normalization"
  echo "   -no-inorm          : do not intensity normalize (default)"
  echo "   -update            : only mc if input is newer than output"
  echo ""
  echo "Session Arguments (Required)"
  echo "   -sf sessidfile  "
  echo "   -df srchdirfile "
  echo "   -s  sessid      "
  echo "   -d  srchdir     "
  echo "   -fsd dir        (optional - default = bold)"
  echo ""
exit 1;
