#! /bin/csh -f

#
# isxconcat-sess
#
# Original Author: Doug Greve
# CVS Revision Info:
#    $Author: greve $
#    $Date: 2008/05/20 15:55:44 $
#    $Revision: 1.25.2.5 $
#
# 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: isxconcat-sess,v 1.25.2.5 2008/05/20 15:55:44 greve Exp $'

set inputargs = ($argv);

set outtop = ();
set analysis = ();
set flac = ();
set fsd  = ();
set contrastlist = ();

set conmaplist = ();
set anamaplist = (meanfunc fsnr)
set regfile = register.dat 

set interp = trilin
set fwhm = ();
set paireddiff = 0;
set pairedavg  = 0;
set mean = 0;
set ToVol = 0;
set ToSurf = 0;
set DoPercent = 0;
set DoAllContrasts = 0;
set DoOSGM = 0;
set SplitMVC = 1; # Split multivariate contrasts

# for volume-based only
set talres = 2;
set talxfm = ();
set DoMorph = 0;

# for surface-based only
set hemilist = ();
set projfrac = ();
set DoProjFracAvg = 0;
set trgsubject = fsaverage; 
set fsgd = ();

set sessargs = ();
set tmpdir = ();
set cleanup = 1;
set PrintHelp = 0;

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

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

goto parse_args;
parse_args_return:

goto check_params;
check_params_return:

set outdir = $outtop/$analysis
mkdir -p $outdir/log

##### Create a log file ######
set LF = $outdir/log/isxconcat.log
if(-e $LF) mv $LF $LF.old
echo $LF

echo "isxconcat-sess log file" >> $LF
echo $VERSION >> $LF
date          >> $LF
uname -a      >> $LF
pwd           >> $LF
echo $0       >> $LF
echo $inputargs  >> $LF
id            >> $LF

set StartTime = `date`;

if($#flac == 0) cp $analysis/analysis.* $outdir

# Go thru each session, get DOF, etc
set sesslistfile = $outdir/sessid.txt
rm -f $sesslistfile
@ DOF = 0;
foreach sess ($SessList)
  set sessid = `basename $sess`;
  set sessinfo = $sess/session.info
  if(-e $sessinfo) then
    set IsGroup = `grep GroupAverage $sessinfo | wc -l`;
  else
    set IsGroup = 0;
  endif
  if($IsGroup) then
    echo "ERROR: session `basename $sess` is a group analysis."|& tee -a $LF
    echo "This is not allowed with isxconcat-sess."|& tee -a $LF
    exit 1;
  endif

  set reg = $sess/$fsd/$regfile
  if(! -e $reg) then
    echo "ERROR: cannot find $reg"|& tee -a $LF
    exit 1;
  endif

  set doffile = $sess/$fsd/$analysis/dof
  if(! -e $doffile) then
    echo "ERROR: cannot find $doffile" |& tee -a $LF
    exit 1;
  endif
  @ dofsess = `cat $doffile`;
  @ DOF = $DOF + $dofsess;

  set srcsubject = `cat $reg | head -n 1`
  echo "$sessid $srcsubject $dofsess" >> $sesslistfile
end
set ffxdofdat = $outdir/ffxdof.dat
echo $DOF > $ffxdofdat

#-------------------------------------------------
foreach hemi ($hemilist)

  # Concat the masks
  set masksvol = $outdir/$hemi.masks.$FSF_OUTPUT_FORMAT
  set cmd = (isxconcat0-sess)
  if($#flac == 0) set cmd = ($cmd -a $analysis)
  if($#flac)      set cmd = ($cmd -flac $flac)
  set cmd = ($cmd -m mask -o $masksvol -interp nearest -fsd $fsd)
  if($#tmpdir) set cmd = ($cmd -tmp $tmpdir);
  if($hemi == tal) then
    if(! $DoMorph) set cmd = ($cmd -talres $talres)
    if($DoMorph)   set cmd = ($cmd -morph)
    if($#talxfm)   set cmd = ($cmd -talxfm $talxfm)
  else
    set cmd = ($cmd -subject $trgsubject)
    set cmd = ($cmd -hemi $hemi)
    if($#projfrac)     set cmd = ($cmd -projfrac $projfrac)
    if($DoProjFracAvg) set cmd = ($cmd -projfrac-avg)
  endif
  if($#fsgd) set cmd = ($cmd -fsgd $fsgd) # only need to do this once
  set cmd = ($cmd $sessargs);
  echo "cd `pwd`" |& tee -a $LF
  echo $cmd       |& tee -a $LF
  $cmd            |& tee -a $LF
  if($status) exit 1;

  # Make a single mask = 0 unless all input masks are != 0
  set maskvol = $outdir/$hemi.mask.$FSF_OUTPUT_FORMAT
  set cmd = (mri_concat $masksvol --o $maskvol --mean)
  echo $cmd       |& tee -a $LF
  $cmd            |& tee -a $LF
  if($status) exit 1;
  # Binarize
  set thresh = `echo \($#SessList-.5\)/$#SessList | bc -l`
  echo $thresh
  set cmd = (mri_binarize --i $maskvol --min $thresh --o $maskvol)
  echo $cmd       |& tee -a $LF
  $cmd            |& tee -a $LF
  if($status) exit 1;

  # Go thru the maps in the contrasts
  foreach contrast ($contrastlist)
    set outcondir = $outdir/$contrast
    mkdir -p $outcondir

    # copy the contrast.mat file for reference
    if($#flac == 0) then
      # Might not exist for some reason
      set cmat = $analysis/$contrast.mat
      if(-e $cmat)  cp $cmat $outcondir/$contrast.lowerlevel.mat
    endif

    foreach mapname ($conmaplist)

      set outvol = $outcondir/$hemi.$mapname.$FSF_OUTPUT_FORMAT
      set cmd = (isxconcat0-sess)
      if($#flac == 0) set cmd = ($cmd -a $analysis)
      if($#flac)      set cmd = ($cmd -flac $flac)
      set cmd = ($cmd -m $mapname -o $outvol -interp $interp);
      set cmd = ($cmd -fsd $fsd -c $contrast)
      if($SplitMVC) set cmd = ($cmd -split $tmpdir);
      if($#tmpdir)  set cmd = ($cmd -tmp $tmpdir);
      if($#fwhm)    set cmd = ($cmd -fwhm $fwhm);
      if($paireddiff) then
        if($mapname == cesvar || $mapname == cesvarpct) then
          set cmd = ($cmd -paired-sum)
        else
          set cmd = ($cmd -paired-diff)
        endif
      endif
      if($pairedavg)  set cmd = ($cmd -paired-avg) # Prob not right for var
      if($hemi == tal) then
        if(! $DoMorph) set cmd = ($cmd -talres $talres)
        if($DoMorph)   set cmd = ($cmd --morph)
        if($#talxfm)   set cmd = ($cmd -talxfm $talxfm)
      else
        set cmd = ($cmd -hemi $hemi)
        set cmd = ($cmd -subject $trgsubject)
        if($#projfrac)      set cmd = ($cmd -projfrac $projfrac)
        if($DoProjFracAvg) set cmd = ($cmd -projfrac-avg)
      endif
      set cmd = ($cmd $sessargs);
      echo "cd `pwd`" |& tee -a $LF
      echo $cmd       |& tee -a $LF
      $cmd            |& tee -a $LF
      if($status) exit 1;

     end # Loop over maps

     if($DoOSGM) then
       set y       = $outcondir/$hemi.ces.$FSF_OUTPUT_FORMAT
       set yffxvar = $outcondir/$hemi.cesvar.$FSF_OUTPUT_FORMAT

       set glmdir = $outcondir/osgm.rfx.$hemi.ces
       set cmd = (mri_glmfit --osgm --y $y --glmdir $glmdir)
       set cmd = ($cmd --mask $maskvol)
       if($ToSurf) set cmd = ($cmd --surf $trgsubject $hemi)
       if($ToVol)  set cmd = ($cmd --nii);
       echo $cmd |& tee -a $LF
       $cmd |& tee -a $LF
       if($status) exit 1;

       set glmdir = $outcondir/osgm.wrfx.$hemi.ces
       set cmd = (mri_glmfit --osgm --y $y --glmdir $glmdir)
       set cmd = ($cmd --mask $maskvol --wls $yffxvar)
       if($ToSurf) set cmd = ($cmd --surf $trgsubject $hemi)
       if($ToVol)  set cmd = ($cmd --nii);
       echo $cmd |& tee -a $LF
       $cmd |& tee -a $LF
       if($status) exit 1;

       set glmdir = $outcondir/osgm.ffx.$hemi.ces
       set cmd = (mri_glmfit --osgm --y $y --glmdir $glmdir)
       set cmd = ($cmd --mask $maskvol --yffxvar $yffxvar)
       set cmd = ($cmd --ffxdofdat $ffxdofdat)
       if($ToSurf) set cmd = ($cmd --surf $trgsubject $hemi)
       if($ToVol)  set cmd = ($cmd --nii);
       echo $cmd |& tee -a $LF
       $cmd |& tee -a $LF
       if($status) exit 1;
      endif # OSGM

   end # Loop over contrasts

  # Analysis-level maps
  foreach mapname ($anamaplist)
    set outvol = $outdir/$hemi.$mapname.$FSF_OUTPUT_FORMAT
    set cmd = (isxconcat0-sess)
    if($#flac == 0) set cmd = ($cmd -a $analysis)
    if($#flac)      set cmd = ($cmd -flac $flac)
    set cmd = ($cmd -m $mapname -o $outvol -interp $interp -fsd $fsd)
    if($#tmpdir) set cmd = ($cmd -tmp $tmpdir);
    if($#fwhm) set cmd = ($cmd -fwhm $fwhm);
    # What about paired diff for these?
    if($paireddiff) then
      if($mapname == rvar) then
        set cmd = ($cmd -paired-sum)
      else
        set cmd = ($cmd -paired-diff)
      endif
    endif
    if($hemi == tal) then
      if(! $DoMorph) set cmd = ($cmd -talres $talres)
      if($DoMorph)   set cmd = ($cmd --morph)
      if($#talxfm)   set cmd = ($cmd -talxfm $talxfm)
    else
      set cmd = ($cmd -hemi $hemi)
      set cmd = ($cmd -subject $trgsubject)
      if($#projfrac)      set cmd = ($cmd -projfrac $projfrac)
      if($DoProjFracAvg) set cmd = ($cmd -projfrac-avg)
    endif
    set cmd = ($cmd $sessargs);
    echo "cd `pwd`" |& tee -a $LF
    echo $cmd       |& tee -a $LF
    $cmd            |& tee -a $LF
    if($status) exit 1;
  end

end # Loop over hemi

echo "" | tee -a $LF
echo "" | tee -a $LF
echo "Started at $StartTime" | tee -a $LF
echo "Ended   at `date`"     | tee -a $LF
echo "isxconcat-sess completed" | tee -a $LF
echo " "
echo " "

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

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

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

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

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

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

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

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

    case "-all-contrasts":
      set DoAllContrasts = 1;
      breaksw

    case "-pct"
    case "-percent"
      set DoPercent = 1;
      breaksw

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

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

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

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

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

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

    case "-morph":
      set DoMorph = 1;
      set ToVol = 1;
      breaksw

    case "-hemis":
      set hemilist = (lh rh); 
      set ToSurf = 1;
      breaksw

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

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

    case "-projfrac-avg":
      set DoProjFracAvg = 1;
      set ToSurf = 1;
      breaksw

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

    case "-fsgd":
      if($#argv == 0) goto arg1err;
      set fsgd = $argv[1]; shift;
      if(! -e $fsgd) then
        echo "ERROR: cannot find $fsgd"
        exit 0;
      endif
      breaksw

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

    case "-paired-diff"
      set paireddiff = 1;
      breaksw

    case "-paired-avg"
      set pairedavg = 1;
      breaksw

    case "-mean"
      set mean = 1;
      breaksw

    case "-no-anamaps"
      set anamaplist = ();
      breaksw

    case "-osgm"
      set DoOSGM = 1;
      breaksw

    case "-split-mvc"
      set SplitMVC = 1;
      breaksw

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

    case "-cwd":
      breaksw

    case "-g":
    case "-s":
    case "-sf":
    case "-df":
    case "-d":
      set sessargs = ($sessargs $flag $argv[1]); shift;
      breaksw

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

end

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

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

  if($#analysis == 0 && $#flac == 0) then
    echo "ERROR: no analysis specified"
    exit 1;
  endif

  if($#analysis != 0 && $#flac != 0) then
    echo "ERROR: cannot specify flac and analysis"
    exit 1;
  endif

  if($#flac) set analysis = `basename $flac .flac`

  ## Get functional subdirectory from the info file ##
  if($#fsd == 0) then
    set infofile = $analysis/analysis.info
    if(! -e $infofile) then
      echo "ERROR: cannot find $infofile, needed for fsd" 
      exit 1;
    endif
    set fsd = `cat $infofile | awk '{if($1 == "fsd") print $2}'`;
  endif

  if($DoAllContrasts) then
    # Wont include merged (ie, conjunction) contrasts
    set matlist = ($analysis/*.mat)
    if($#matlist == 0) then
      echo "ERROR: not contrasts found in $analysis"
      exit 1;
    endif
    set contrastlist = ();
    foreach m ($matlist)
      set b = `basename $m | sed 's/.mat//'`
      set contrastlist = ($contrastlist $b);
    end
  endif

  if($#contrastlist == 0) then
    echo "ERROR: no contrast specified"
    exit 1;
  endif

  if($#outtop == 0) then
    echo "ERROR: no output directory specified"
    exit 1;
  endif

  if($ToSurf == 0 && $ToVol == 0) set ToVol = 1;
  if($ToSurf && $ToVol) then
    echo "ERROR: cannot convert to surface and volume"
    exit 1;
  endif

  if("$interp" != "trilin" && "$interp" != "nearest") then
    echo "ERROR: interp is $interp, must be trilinear or nearest"
    exit 1;
  endif

  if($talres != 1 && $talres != 2) then
    echo "ERROR: talres = $talres, must be 1 or 2"
    exit 1;
  endif

  if($#hemilist) then
    foreach hemi ($hemilist)
      if($hemi != lh && $hemi != rh) then
        echo "ERROR: hemi = $hemi, must be rh or lh"
        exit 1;
      endif
    end
  else
    set hemilist = tal;
  endif

  mkdir -p $outtop
  if($status) then
    echo "ERROR: making $outtop";
    exit 1;
  endif

  if($paireddiff && $pairedavg) then
    echo "ERROR: cannot --paired-diff and --paired-avg";
    exit 1;
  endif

  if($#conmaplist == 0) then
    if(! $DoPercent ) then
      set conmaplist = (ces cesvar)
    else
      set conmaplist = (cespct cesvarpct)
    endif
  endif

  if($?FSF_OUTPUT_FORMAT == 0) setenv FSF_OUTPUT_FORMAT mgh

  if($#projfrac && $DoProjFracAvg) then
    echo "ERROR: cannot --projfrac and --projfrac-avg"
    exit 1
  endif

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

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

############--------------##################
usage_exit:
  echo " "
  echo "USAGE: isxconcat-sess"
  echo ""
  echo "   -o outdir       : top group output directory"
  echo ""
  echo "   -a analysisname : session-level functional analysis name"
  echo "   -c contrast     : contrast "
  echo "   -all-contrasts  : contrast "
  echo "   -percent        : use voxel-wise percent signal change"
  echo "   -m mapname      : contrast-level maps stem (def is ces and cesvar)"
  echo ""
  echo "   -reg regfile    : instead of register.dat"
  echo "   -interp method  : trilinear (def) or nearest"
  echo "   -fwhm fwhm      : smooth by fwhm"
  echo "   -paired-diff    : compute 1-2, 3-4, etc"
  echo "   -paired-avg     : compute avg 1+2, 3+4, etc"
  echo "   -mean           : mean over all frames"
  echo "   -no-anamaps     : do not compute analysis level maps"
  echo "   -split-mvc      : split multi-variate contrasts"
  echo ""
  echo "  Volume-based options:"
  echo "   -talres res     : 1 or 2 mm (def is 2)"
  echo "   -talxfm xfmfile : use xfmfile instead of talairach.xfm"
  echo ""
  echo "  Surface-based options:"
  echo "   -hemis           : surface-based, both lh and rh";
  echo "   -hemi hemisphere : for surface-based analysis (lh or rh)";
  echo "   -projfrac frac   : sample frac into surface bet white and gray"
  echo "   -projfrac-avg    : average across cortical depth"
  echo "   -trgsubject subject : sample to subject's surface (def fsaverage)"
  echo ""
  echo "   -sf sessidfile  ..."
  echo "   -df srchdirfile ..."
  echo "   -s  sessid      ..."
  echo "   -d  srchdir     ..."
  echo ""
  echo "   -fsgd fsgdfile : for comparing subject order"
  echo ""
  echo "   -help"
  echo "   -debug"
  echo "   -tmpdir dir : use dir for temporary storage (implies -nocleanup)"
  echo "   -nocleanup  : do not delete tmpdir"
  echo "   -version    : print version and exit"
  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 a group of FS-FAST first-level analyses into a common space,
either volume- or surface-based, and concatenates all the sessions
together into one multi-frame file suitable for use with
mri_glmfit. This script is partially redundant with mris_preproc.

