#!/bin/csh -f
# fcseed-sess
#
set VERSION    = '$Id: fcseed-sess,v 1.1.2.3 2010/07/26 21:08:58 greve Exp $';
set cmdargs = ($argv);

set segstem    = "aparc+aseg"; 
set segidlist  = ()
set outfile = ();
set rlf = ()
set fsd = bold
set RegDOF = 6;
set FillThresh = .5;
set DoMean = 1;
set DoSVD = 0;
set roicfg = ();
set maskfile = ();
set Overwrite = 0;
set DoWM = 0;

set nolog = 0;

set PrintHelp = 0;
if($#argv == 0)  goto usage_exit;
set n = `echo $argv | grep -e -help | wc -l` 
if($n != 0) then
  set PrintHelp = 1;
  goto usage_exit;
endif
set n = `echo $argv | grep version | wc -l` 
if($n != 0) then
  echo $VERSION
  exit 0;
endif

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

goto parse_args;
parse_args_return:

goto check_params;
check_params_return:

set ProjectDir = `pwd`;

# Create a log file #
if(! $nolog ) then
  mkdir -p log
  set LF = $ProjectDir/log/fcseed-sess.log
  # Below to help prevent collisions when parallel
  if($#SessList == 1) then
    set sessid = `basename $SessList`;
    set LF = $LF.$sessid
  endif
  rm -f $LF
else
  set LF = /dev/null
endif
echo Logfile is $LF

date | tee -a $LF
uname -a | tee -a $LF
echo "setenv SUBJECTS_DIR $SUBJECTS_DIR" | tee -a $LF
echo "cd `pwd`" | tee -a $LF
echo $0 | tee -a $LF
echo $cmdargs | tee -a $LF
cat $FREESURFER_HOME/build-stamp.txt | tee -a $LF

set outstem = `basename $outfile .dat`

## go through each session ##
foreach sess ($SessList)
  set sessid = `basename $sess`;
  set subject = `cat $sess/subjectname`
  set RunList = (`getrunlist $sess/$fsd $rlf`);
  foreach Run ($RunList)
    set rundir = $sess/$fsd/$Run

    set outpath = $rundir/$outfile
    if(-e $outpath && $Overwrite == 0) then
      echo "ERROR: output file $outpath already exists"
      echo "Choose a different name or run with -overwrite"
      exit 1;
    endif
    rm -f $outpath

    set tmpdir = $rundir/tmp.fcseed-sess.$$
    rm -rf $tmpdir
    mkdir -p $tmpdir

    set LLF = $rundir/$outstem.log
    rm -f $LLF
    date | tee -a $LLF
    uname -a | tee -a $LLF
    echo "setenv SUBJECTS_DIR $SUBJECTS_DIR" | tee -a $LLF
    echo "cd `pwd`" | tee -a $LLF
    echo $0 | tee -a $LLF
    echo $cmdargs | tee -a $LLF
    cat $FREESURFER_HOME/build-stamp.txt | tee -a $LLF
    echo "" | tee -a $LLF

    if($#segidlist) then
      # Segmentation
      set f   = $rundir/fmcpr.nii
      set template = $rundir/template.nii
      set reg = $rundir/register.dof$RegDOF.dat

      if($DoWM) then
        # treat white matter special
        set apas = $SUBJECTS_DIR/$subject/mri/aparc+aseg.mgz
        set seganat = $tmpdir/wm.seg.nii
        set cmd = (mri_binarize --i $apas --o $seganat \
          --match 2 --match 41 --erode 3)
        echo $cmd | tee -a $LLF
        $cmd | tee -a $LLF
        if($status) exit 1;
        set segidlist = (1);
      else 
        set seganat = $SUBJECTS_DIR/$subject/mri/$segstem.mgz
      endif

      # Convert segmentation to native functional space
      set seg = $rundir/masks/$segstem.nii
      set cmd = (mri_label2vol --seg $seganat \
         --reg $reg --temp $template --fillthresh $FillThresh \
         --o $seg);
      echo $cmd | tee -a $LLF
      $cmd | tee -a $LLF
      if($status) exit 1;

      # Create a binary mask of the union of all the segmentations IDs
      if($#maskfile) then
        set mask = $rundir/$maskfile.nii
      else
        set mask = $tmpdir/mask.nii
      endif
      set cmd = (mri_binarize --i $seg --o $mask )
      foreach id ($segidlist)
        set cmd = ($cmd --match $id)
      end
      echo $cmd | tee -a $LLF
      $cmd | tee -a $LLF
      if($status) exit 1;
    else
      # ROI configuration
      set mask = `stem2fname $sess/$ROIfsd/$ROIanalysis/$ROIname`
      if($status) then
        echo "$mask" | tee -a $LLF | tee -a $LF
        exit 1;
      endif
      set f = `stem2fname $rundir/$ROIfuncstem`
      if($status) then
        echo "$f" | tee -a $LLF | tee -a $LF
        exit 1;
      endif
    endif
 
    if($DoMean) then
      # Compute mean time course inside the mask
      set cmd = (mri_segstats --i $f --seg $mask --id 1 \
        --sum $tmpdir/junk.sum --avgwfvol $tmpdir/avgwf.mgh)
      echo $cmd | tee -a $LLF
      $cmd | tee -a $LLF
      if($status) exit 1;

      # Remove mean and 1st and 2nd order trends
      set cmd = (mri_glmfit --y $tmpdir/avgwf.mgh --qa \
         --glmdir $tmpdir/glm --save-eres --no-est-fwhm)
      echo $cmd | tee -a $LLF
      $cmd | tee -a $LLF
      if($status) exit 1;

      # Convert to ascii/text
      set cmd = (mri_convert $tmpdir/glm/eres.mgh \
        --ascii $rundir/$outfile)
      echo $cmd | tee -a $LLF
      $cmd | tee -a $LLF
      if($status) exit 1;

    endif

    if($DoSVD) then
      # Remove trends, take PCA only in mask
      set cmd = (mri_glmfit --y $f --mask $mask --qa \
         --glmdir $tmpdir/glm --pca --no-est-fwhm)
      echo $cmd | tee -a $LLF
      $cmd | tee -a $LLF
      if($status) exit 1;

      # Copy the temporal principal components
      cp $tmpdir/glm/pca-eres/u.mtx $rundir/$outfile

      # Copy pca stats
      set statsfile = $rundir/$outstem.pca-stats.dat
      cp $tmpdir/glm/pca-eres/stats.dat $statsfile
    endif

    rm -rf $tmpdir

  end
end # sess

date | tee -a $LF
echo "fcseed-sess done" | tee -a $LF

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


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

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

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

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

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

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

    case "-seg":
      if ( $#argv < 1) goto arg1err;
      set segstem = $argv[1]; shift;
      set segstem = `basename $segstem .mgz`
      breaksw

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

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

    case "-wm":
      set segidlist = ($segidlist 2 41);
      set FillThresh = .5;
      set DoMean = 0;
      set DoSVD  = 1;
      set DoWM = 1;
      breaksw

    case "-vcsf":
      set segidlist = ($segidlist 4 5 14 43 44 31 63) 
      set FillThresh = .75;
      set DoMean = 0;
      set DoSVD  = 1;
      #set segidlist = ($segidlist 4 5 14 43 44 72);
      breaksw

    case "-pca":
    case "-svd":
      set DoMean = 0;
      set DoSVD  = 1;
      breaksw

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

    case "-force":
    case "-overwrite":
      set Overwrite = 1;
      breaksw

    case "-debug":
      set verbose = 1;
      set echo = 1;
      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($#outfile == 0) then
    echo "ERROR: no output specified"
    exit 1
  endif
  if($#segidlist == 0 && $#roicfg == 0) then
    echo "ERROR: no segmentations or ROI specified"
    exit 1
  endif
  if($#segidlist != 0 && $#roicfg != 0) then
    echo "ERROR: cannot specify segmentation and ROI"
    exit 1
  endif
  if($#roicfg) then
    set ROIname     = `cat $roicfg | awk '{if($1 == "roiname") print $2}'`
    set ROIanalysis = `cat $roicfg | awk '{if($1 == "analysis") print $2}'`
    set ROIIsNative  = `getana -a $ROIanalysis -t IsNative`
    set ROIIsMNI305  = `getana -a $ROIanalysis -t IsMNI305`
    set ROIIsSurface = `getana -a $ROIanalysis -t IsSurface`
    set ROIhemi = ();
    if($ROIIsSurface) then
      set ROIhemi = `getana -a $ROIanalysis -t hemi`
    endif
    set ROIfsd = `getana -a $ROIanalysis -t fsd`
    set ROIfuncstem = `getana -a $ROIanalysis -t funcstem`
  endif

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

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

############--------------##################
usage_exit:
  echo ""
  echo "USAGE: fcseed-sess"
  echo ""
  echo "  -o outfile "
  echo ""
  echo "Segmentation-based options"
  echo "  -segid segid  <-segid segid2 ...>"
  echo "  -wm : white matter "
  echo "  -vcsf : ventricular CSF"
  echo "  -seg segmentation : default is aparc+aseg"
  echo "  -fillthresh thresh : value between 0 and 1 (default is .5)"
  echo "    only applies to analyses using segmentation-based"
  echo ""
  echo "Functional ROI-based options"
  echo "  -roi roiconfig : as created by funcroi-confg"
  echo ""
  echo "Session Arguments (Required)"
  echo "   -sf sessidfile  "
  echo "   -df srchdirfile "
  echo "   -s  sessid      "
  echo "   -d  srchdir     "
  echo "   -fsd FSD "
  echo ""
  echo "   -m maskfile : output mask for segmentation-based. Good for checking"
  echo "   -overwrite : delete and overwrite any existing files"
  echo "   -pca       : compute pca instead of a spatial mean"
  echo "   -help      : yea, as if"
  echo "   -version   : print version and exit"
  echo "   -debug"
  echo ""

  if(! $PrintHelp) exit 1;

  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

NOTE: this program is still experimental. Use at your own risk!

Computes seeds (regressors) that can be used for functional
connectivity analysis or for use as nuisance regressors. Seed regions
can be defined in two ways: (1) as an anatomical region in a
segmentation such as aparc+aseg, or (2) as an ROI created with
funcroi-config. The seed regions are always subject-specific.
The output is a text file in the same directory as the raw
data. This file will be named based on the -o flag.

======================================================
Segmentation-based Seed Regions

For segmentation-based, the segmentation must exist in
$SUBJECTS_DIR/$subject/mri. By default the segmentation is aparc+aseg.
This can be changed with -seg (eg, -seg aparc+aseg would be the same
as the default). You must specify a segmentation index with
-segid. Eg, if you are using aparc+aseg, then 17 would be left
hippocampus (this is defined in
$FREEESURFER_HOME/FreeSurferColorLUT.txt). You can specify any number
of segmentations; they will be combined into one seed region (eg,
(-segid 17 -segid 53 would produce one seed region from both
hippocampi).

The segmentation will be converted from the 1mm anatomical space into
the native functional space.  For this, you can specify a fill
threshold. This governs how much an anatomical segmentation must fill
a functional voxel must be in order for it to be considered part of
the seed region. This is a number between 0 (the smallest part of a
voxel) to 1 (all of the voxel). To avoid quatifification artifacts, it
is recommended that this not be set above .8. Default is .5.

There are two default segmentations: (1) white matter (-wm) and (2)
ventricular CSF (-vcsf). The white matter option first creates a mask
of the WM in the anatomical space by finding the voxels in the
aparc+aseg.mgz with indices 2 and 41. It then erodes the mask by 3
voxels. It then converts the mask to native functional space with
fillthresh=0.5 The CSF segmentation uses segmentation indices 4 5 14
43 44 31 and 63 with fillthresh=.75. Both use a PCA output. These are
good to use as nuisance regressors for functional connectivity
analysis.

======================================================
ROI-based Seed Regions

The ROI-based seed region is the result of a functional ROI analysis
(see funcroi-config). Note that the functional ROI may have a
different FSD than the functional connectivity analysis. This can be
helpful when creating an ROI from a task but applying it to rest data.



=====================================================
Examples

1. Create a seed waveform by spatially averaging the entire left
   hemisphere hippocampus:

     fcseed-sess -o lh.hippo.dat -segid 17 -s session -fsd rest

   This will create files called lh.hippo.dat in session/rest/RRR
   where RRR is the run directory.

2. Create white matter and ventricular CSF nuisance regressors
   
     fcseed-sess -o wm.dat   -wm   -s session -fsd rest
     fcseed-sess -o vcsf.dat -vcsf -s session -fsd rest

3. Analyze:
   
     mkanalysis-sess -a fc-lh.hippo.rhemi 
       -notask 
       -taskreg lh.hippo.dat 1 
       -nuisreg wm.dat 3 
       -nuisreg vcsf.dat 3 
       -surface fsaverage rh -fwhm 5 -fsd rest -TR 2 

   This analysis is called "fc-lh.hippo.rhemi". It uses the single
   waveform found in lh.hippo.dat as the "task regressor". It also
   adds 3 PCA waveforms from both the white matter and the CSF
   as nuisance regressors. Note that a contrast does not need to 
   be made because one is automatically created with an -taskreg.
   This data can be analyzed with selxavg3-sess and isxconcat-sess
   just as if it were any task-based analysis.


======================================================
Segmentation Ids for some common ROIs. See 
$FREEESURFER_HOME/FreeSurferColorLUT.txt for more.

Left-Hippocampus  17
Right-Hippocampus  53
Left-Amygdala  18
Right-Amygdala 54

