#! /bin/csh -f

#
# acfseg-sess
#
# Original Author: Doug Greve
# CVS Revision Info:
#    $Author: nicks $
#    $Date: 2007/01/09 22:41:16 $
#    $Revision: 1.8 $
#
# 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: acfseg-sess,v 1.8 2007/01/09 22:41:16 nicks Exp $';

set cmdargs = ($argv);

set funcstem  = f; 
set fsd       = "bold";
set nthrun    = ();
set perrun    = 0;
set maskstem  = brain;
set nbins     = 10;
set RunListFile = ();
set acfsegstem = acfseg
set fmt       = ();
set fmtext    = ();
set monly     = 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;
  exit 1;
endif

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

goto parse_args;
parse_args_return:

goto check_params;
check_params_return:

if(! $nolog) then
  set LF = log/acfseg-sess.log
  if(-e $LF) mv $LF $LF.bak
else
  set LF = /dev/null
endif

date | tee -a $LF
pwd  | tee -a $LF
echo $0  | tee -a $LF
echo $cmdargs | tee -a $LF
echo $VERSION | tee -a $LF
hostname  | tee -a $LF

if(! $monly) set MLF = /tmp/acfseg-sess.$$.m
rm -f $MLF

#------------------------------------------------------------------#
set StartTime = `date`;
foreach sess ($SessList)
  set sessid = `basename $sess`;

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

  ### Check that the target directory is there ###
  if(! -d $sess/$fsd) then
    echo "ERROR: $sess/$fsd does not exist"   | tee -a $LF
    exit 1;
  endif

  ### Check that the target directory is writable ###
  if(! -w $sess/$fsd) then
    echo "ERROR: $sess/$fsd is not writable"   | tee -a $LF
    exit 1;
  endif

  set RunList = `getrunlist $sess/$fsd $RunListFile`;
  if($status || $#RunList == 0) then
    echo "ERROR: $sess/$fsd has no runs"  | tee -a $LF
    exit 1;
  endif
  echo "nthrun $nthrun $#nthrun"
  if($#nthrun != 0) then
    set RunList = $RunList[$nthrun];
  endif
  echo "RunList $RunList" | tee -a $LF

  foreach run ($RunList)

    set funcpath   = $sess/$fsd/$run/$funcstem
    if(! $perrun) then
      set maskpath   = $sess/$fsd/masks/$maskstem
      set acfsegpath = $sess/$fsd/masks/$acfsegstem
    else
      set maskpath   = $sess/$fsd/$run/masks/$maskstem
      set acfsegpath = $sess/$fsd/$run/masks/$acfsegstem
    endif

#--------------------------#
tee -a $MLF > /dev/null <<EOF
tic;
funcstem   = '$funcpath$fmtext';
maskstem   = '$maskpath$fmtext';
acfsegstem = '$acfsegpath.mgh';
nbins = $nbins;
monly = $monly;

%------- Load the mask -------------%
if(~isempty(maskstem))
  mask = MRIread(maskstem);
  if(isempty(mask))
    if(~monly) quit; end
    return;
  end
  indmask = find(mask.vol);
  indmaskout = find(~mask.vol);
else
  mask.vol = [];
  indmask = [1:nv];  
  indmaskout = [];
end
nmask = length(indmask);

% ------- Load the functional -------- %
fprintf('Loading the functional t=%g\n',toc);
%[y mri] = fast_ldbslice(funcstem);
y = MRIread(funcstem);
if(isempty(y)) 
  if(~monly) quit; end
  return;
end
ymn = mean(y.vol,4);
ystd = std(y.vol,[],4);
volsz = size(ymn);

% The purpose of the Rayleigh-Gaussian (RG) Mixture Model
% is to robustly determine the maximum over which the
% segmentation binning should be done to assure a good 
% dynamic range.  Not sure how robust it will really be.
fprintf('Searching for optimal RG parameters\n');
t0 = toc;
rgpar0  = fast_raygausinit(ymn(indmask));
[rgpar rgcost exitflag] = fminsearch('fast_raygauscost',rgpar0,[],ymn(indmask));
if(exitflag ~= 1)
  fprintf('ERROR: RG optimization, exit=%d\n',exitflag);
  if(~monly) 
    quit; 
  end
  return;
end
fprintf('  done searching (%g min)\n',(toc-t0)/60);
RGalpha = rgpar(1);
Rmu  = rgpar(2);
Gmu  = rgpar(3);
Gstd = rgpar(4);

if(0)
  ythresh = fast_raygausthresh(rgpar);
  [h0 x0] = hist(ymn(indmask),100);
  pdf0 = h0/trapz(x0,h0);
  rgpdf = fast_raygaus(x0,rgpar);
  plot(x0,pdf0,x0,rgpdf);
end

ymax = Gmu + 3*Gstd;
indsupmax = find(ymn > ymax);
nsup = length(indsupmax);
fprintf('RG: alpha=%g, Rmu=%g, Gmu=%g, Gstd=%g, ymax=%g, nsup=%d\n',...
    RGalpha,Rmu,Gmu,Gstd,ymax,nsup);
ymn(indsupmax) = ymax;

% ------- Get the bins of the intensity ----------
fprintf('Computing bins t=%g\n',toc);
[hbin xbin] = hist(ymn(indmask),nbins);
dxbin = xbin(2)-xbin(1);
binmap = y;
binmap.vol = zeros(size(ymn));
nperbin = zeros(nbins,1);
for nthbin = 1:nbins
  yminbin = xbin(nthbin)-dxbin/2;
  ymaxbin = xbin(nthbin)+dxbin/2;
  if(nthbin == 1)     yminbin = -inf; end
  if(nthbin == nbins) ymaxbin = +inf; end
  indbin = find(yminbin < ymn(indmask) & ymn(indmask) < ymaxbin);
  nperbin(nthbin) = length(indbin);
  binmap.vol(indmask(indbin)) = nthbin;
  fprintf('bin %2d  %3d  %8.3f %8.3f\n',nthbin,nperbin(nthbin),yminbin,ymaxbin);
end

%yak2('init',vol2mos(ymn),'-A',vol2mos(binmap.vol),'-pmin',1,'-pmax',nbins);

%fast_svbslice(binmap,acfsegstem,[],'bshort',mri);
MRIwrite(binmap,acfsegstem);
if(~monly) clear all; end

EOF
#--------------------------#
  end # Loop over runs

end # Loop over sessions #

if(! $monly) then
  cat $MLF | matlab -display iconic
  rm -f $MLF
endif


echo "Started at $StartTime" | tee -a $LF
echo "Ended   at `date`"     | tee -a $LF
echo "acfseg-sess Done"    | tee -a $LF

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    case "-cwd":
      # ignore getsesspath arguments 
      breaksw

    case "-umask":
      if ( $#argv == 0) goto arg1err;
      setenv MRI_UMASK $1; shift;
      breaksw

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

end

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

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

if($#nthrun && $perrun) then
  echo "ERROR: cannot -nthrun and -perrun"
  exit 1;
endif
if(! $perrun && $#nthrun == 0) set nthrun = 1;

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

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

############--------------##################
usage_exit:
  echo ""
  echo "USAGE: acfseg-sess"
  echo ""
  echo "Opttional Arguments"
  echo "   -f funcstem      : input  functional volume stem <f>"
  echo "   -nthrun nthrun   : nthrun to use (default: 1st) "
  echo "   -perrun          : acfseg per-run (not with -nthrun)" 
  echo "   -rlf runlistfile : explicit run to use "
  echo "   -mask mask       : set out of mask to 0 (def brain)"
  echo "   -nbins nbins     : number of segmentations (10)"
  echo "   -acfseg stem     : output stem"
  echo ""
  echo "Session Arguments (Required)"
  echo "   -sf sessidfile  "
  echo "   -df srchdirfile "
  echo "   -s  sessid      "
  echo "   -d  srchdir     "
  echo "   -fsd fsdir      (optional)"
  echo ""
  echo "Other Arguments"
  echo "   -umask umask    : set unix file permission mask"
  echo "   -version        : print version and exit"
  echo "   -help           : print help and exit"
  echo ""

  if(! $PrintHelp) exit 1;

  echo $VERSION

  echo "------------------------------------------------------------"
  cat $0 | awk 'BEGIN{prt=0}{if(prt) print $0; if($1 == "BEGINHELP") prt = 1 }'

  echo "------------------------------------------------------------"

exit 1;

#---- Everything below here is printed out as part of help -----#
BEGINHELP

Segments a functional volume into nbins segments based on intensity.
This is done in preparation for modeling the temporal autocorrelation 
function (acf) separately in each segment.


