#! /bin/csh -f

#
# rawfunc2surf-sess
#
# Original Author: Doug Greve
# CVS Revision Info:
#    $Author: greve $
#    $Date: 2010/06/29 21:59:08 $
#    $Revision: 1.15.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: rawfunc2surf-sess,v 1.15.2.1 2010/06/29 21:59:08 greve Exp $';

set inputargs = ($argv);

set fsd        = bold;
set instem     = ()
set outstem    = ();
set regfile    = ();
set RegDOF     = 6;
set trgsubject = fsaverage
set hemilist = ()
set ProjFrac = 0.5;
set interp = trilin
set PerRun = 1;
set maskname = brain
set maskdir = masks
set maskstem = ();
set RunListFile = ();
set fwhm = ();
set UpdateOnly = 0;
set nolog = 0;
set debug = 0;
set DoSelf = 0;
set PrintHelp = 0;
set SurfReg = sphere.reg
set ExpKey = ();
set ExpKeyNeeded = 0;
set SliceOrder = ();

set outfmt = nii
if($?FSF_OUTPUT_FORMAT) then
  set outfmt = $FSF_OUTPUT_FORMAT
endif

## If there are no options, just print the usage ##
if($#argv == 0) goto usage_exit;
set n = `echo $argv | grep -e  -version | wc -l` 
if($n != 0) then
  echo $VERSION
  exit 0;
endif
set n = `echo $argv | grep -e -help | wc -l` 
if($n != 0) then
  set PrintHelp = 1;  
  goto usage_exit;
endif

goto parse_args;
parse_args_return:

set SessList = `getsesspath $inputargs`;
if($status || $#SessList == 0) then
  getsesspath $inputargs 
  echo "ERROR: cannot find any sessions"
  exit 1;
endif

goto check_params;
check_params_return:

# Create a string like lhrh
set hemistr = ();
foreach hemi ($hemilist)
  set hemistr = $hemistr$hemi
end

set ProjectDir = `pwd`;

## Loop through each session ##
@ nthsess = 0;
foreach sess ($SessList)
  set sessid = `basename $sess`
  @ nthsess = $nthsess + 1;

  ##### Create a log file ######
  set LF = /dev/null
  if(! $nolog) then
    set logdir = $ProjectDir/log;
    mkdir -p $logdir
    set LF = $logdir/rawfunc2surf-sess.$sessid.$fsd.$outstem.$hemistr$ExpKey.log
    if(-e $LF) mv $LF $LF.old
  endif
  echo "rawfunc2surf-sess log file" >> $LF
  echo $VERSION >> $LF
  uname -a >> $LF
  date >> $LF
  pwd >> $LF
  echo $0 $inputargs  >> $LF 
  echo UpdateOnly $UpdateOnly >> $LF 

  echo "------------------------------ " |& tee -a $LF
  echo "$nthsess/$#SessList $sessid" |& tee -a $LF

  set subject = `cat $sess/subjectname`;
  if($DoSelf) set trgsubject = $subject

  foreach hemi ($hemilist)

  if(! $PerRun) then
    set reg = $sess/$fsd/$regfile
    if(! -e $reg) then
      echo "ERROR: cannot find $reg" | tee -a $LF
      echo "Try running register-sess" | tee -a $LF
      exit 1;
    endif
    set maskstempath = $sess/$fsd/$maskdir/$maskname
    set mask = `stem2fname $maskstempath`
    if($status) then
      echo "$mask" | tee -a $LF
      echo "Try running mkbrainmask-sess" | tee -a $LF
      exit 1;
    endif
    set outmask = $sess/$fsd/$maskdir/$maskstem.$hemi.$outfmt
  endif

  set RunList = `getrunlist $sess/$fsd $RunListFile`;
  if($status) then
    echo "$RunList" |& tee -a $LF
    exit 1;
  endif

  foreach Run ($RunList)
    echo "  $nthsess/$#SessList $sessid $Run $hemi ---------" |& tee -a $LF
    echo "    `date`"  |& tee -a $LF
    set funcdir = $sess/$fsd/$Run

    set invol = `stem2fname $funcdir/$instem`
    if($status) then
      echo "$invol" |& tee -a $LF
      exit 1;
    endif

    if($PerRun) then
      set reg = $sess/$fsd/$Run/$regfile
      if(! -e $reg) then
        echo "ERROR: cannot find $reg" | tee -a $LF
        echo "Try running register-sess with -per-run" | tee -a $LF
        exit 1;
      endif
      set maskstempath = $sess/$fsd/$maskdir/$maskname
      set mask = `stem2fname $maskstempath`
      if($status) then
        echo "$mask" | tee -a $LF
        echo "Try running mkbrainmask-sess with -per-run" | tee -a $LF
        exit 1;
      endif
      set outmask = $sess/$fsd/$Run/$maskdir/$maskstem.$hemi$ExpKey.$outfmt
    endif

    set outvol = $funcdir/$outstem.$hemi$ExpKey.$outfmt
    set UpdateNeeded = 0;
    if(! $UpdateOnly) set UpdateNeeded = 1;
    if(! -e $outvol || ! -e $mask) set UpdateNeeded = 1;
    if($UpdateNeeded == 0) then    
      if($debug) ls -lt $invol $reg $mask $outvol
      test $invol -nt $outvol
      if(! $status) set UpdateNeeded = 1;
      test $reg -nt $outvol
      if(! $status) set UpdateNeeded = 1;
      test $mask -nt $outvol
      if(! $status) set UpdateNeeded = 1;
    endif

    if($UpdateNeeded == 0) then
      echo "    $sessid $Run Update not needed" | tee -a $LF
      continue
    endif

    # Mask
    set cmd = (mri_vol2surf --mov $mask --reg $reg \
      --trgsubject $trgsubject --interp nearest --projfrac $ProjFrac\
      --hemi $hemi --o $outmask --noreshape --cortex)
    if($trgsubject != $subject) set cmd = ($cmd --surfreg $SurfReg)
    echo $cmd | tee -a $LF
    $cmd | tee -a $LF
    if($status) exit 1;
    set cmd = (mri_binarize --i $outmask --min .00001 --o $outmask)
    echo $cmd | tee -a $LF
    $cmd | tee -a $LF

    # Raw data
    set cmd = (mri_vol2surf --mov $invol --reg $reg \
      --trgsubject $trgsubject --interp $interp --projfrac $ProjFrac\
      --hemi $hemi --o $outvol --noreshape --cortex)
    if($trgsubject != $subject) set cmd = ($cmd --surfreg $SurfReg)
    echo $cmd | tee -a $LF
    $cmd | tee -a $LF
    if($status) exit 1;

    # Smooth raw data within mask
    if($fwhm != 0) then
      set cmd = (mris_fwhm --s $trgsubject --hemi $hemi --smooth-only \
        --i $outvol --fwhm $fwhm --o $outvol --mask $outmask )
      echo $cmd | tee -a $LF
      $cmd | tee -a $LF
      if($status) exit 1;
    endif

  end  # Loop over runs
end # Loop over hemis

end  # foreach sess ($SessList)

echo "" |& tee -a $LF
date |& tee -a $LF
echo "rawfunc2surf-sess completed " |& tee -a $LF

exit 0;

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

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

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

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

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

    case "-per-run":
    case "-perrun":
      set PerRun = 1;
      breaksw

    case "-per-session":
    case "-no-per-run":
    case "-no-perrun":
      set PerRun = 0;
      set ExpKeyNeeded = 1;
      breaksw

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

    case "-expkey":
      if($#argv < 1) goto arg1err;
      set ExpKey = $argv[1]; shift;
      set ExpKey = (.$ExpKey); # prepend a dot
      breaksw

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

    case "-force":
      set UpdateOnly = 0;
      breaksw

    case "-nearest":
      set interp = "nearest"e
      set ExpKeyNeeded = 1;
      breaksw

    case "-trilin":
      set interp = "trilin"
      breaksw

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

    case "-stc":
    case "-sliceorder":
    case "-so":
      if ( $#argv == 0) goto arg1err;
      set SliceOrder = $argv[1]; shift;
      if($SliceOrder != siemens && $SliceOrder != up && $SliceOrder != down && \
         $SliceOrder != odd && $SliceOrder != even && $SliceOrder != none) then
         echo "ERROR: -stc is $SliceOrder, must be siemens, up, down, odd, even, or none"
         exit 1;
      endif
      breaksw

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

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

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

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

    case "-lh":
      set hemilist = ($hemilist lh);
      breaksw

    case "-rh":
      set hemilist = ($hemilist rh);
      breaksw

    case "-self":
      set DoSelf = 1;
      breaksw

    # should not use either of these
    case "-o":
    case "-outstem":
      if ( $#argv == 0) goto arg1err;
      set outstem = $argv[1]; shift;
      breaksw
    case "-mask":
      # output mask stem
      if ( $#argv == 0) goto arg1err;
      set maskstem = $argv[1]; shift;
      breaksw

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

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

    case "-cwd":
      breaksw

    case "-s":
    case "-sf":
    case "-df":
    case "-d":
    case "-g":
      shift;
      breaksw

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

end

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

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

if($#fwhm == 0) then
  echo "ERROR: you must enter a FWHM. Use 0 for no smoothing."
  exit 1;
endif
if($ExpKeyNeeded && $#ExpKey == 0) then
  echo "ERROR: experts key needed (-expkey)"
  exit 1;
endif

if($#SliceOrder == 0) set SliceOrder = "none";

if($#instem == 0) then
  if($PerRun)   set instem = fmcpr
  if(! $PerRun) set instem = fmc
  if($SliceOrder != none) set instem = $instem.$SliceOrder
endif

if($DoSelf) then
  set subjstr = self
else
  set subjstr = $trgsubject
endif

if($#outstem == 0) set outstem = $instem
set outstem = $outstem.sm$fwhm.$subjstr; # hemi appended later

if($#maskstem == 0) set maskstem = $maskname
set maskstem = $maskstem.$subjstr # hemi appended later

if($#hemilist == 0) set hemilist = (lh rh);
echo "instem $instem"
echo "outstem $outstem.hemi"

if($#regfile == 0) set regfile  = register.dof$RegDOF.dat

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

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

############--------------##################
usage_exit:
  echo "rawfunc2surf-sess"
  echo ""
  echo " Session Arguments (some required)"
  echo "  -sf sessidfile  ..."
  echo "  -df srchdirfile ..."
  echo "  -s  sessid      ..."
  echo "  -d  srchdir     ..."
  echo ""
  echo "  -fwhm FWHMmm : smooth by FWHM mm (enter 0 for no smoothing)"
  echo ""
  echo "Optional Arguments"
  echo "  -i instem    :  fmcpr (default is fmcpr)"
  echo "  -fsd dir     : functional subdirectory ($fsd)"
  echo "  -self : map to native subject surface instead of fsaverage"
  echo ""
  echo "Expert Options"
  echo "  -reg regfile : default is register.dof$RegDOF.dat"
  echo "  -nearest     : use nearest neighbor interp (default is trilin)"
  echo "  -surfreg SurfReg : change from $SurfReg"
  echo "  -per-session : use session-level registration and mask instead of -per-run"
  echo ""
  echo "Other options"
  echo "  -update : only run if update is needed"
  echo "  -force : force an update (default)"
  echo "  -version       : print version and exit"
  echo "  -debug"
  echo ""
  if(! $PrintHelp ) exit 1;

  echo " "
  echo "$VERSION "
  echo " "

  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

Resamples raw functional data onto the cortical surface.


