#!/bin/tcsh -e

# --------------------- revision history -------------------------
# Sept, 2016
#   + added pre-lr-symm (as def), 
#   + added option for post-lr-symm
#   + added '-wdir'
#   + added cmass->(0,0,0) as def for output
#
# Jan, 2017
#   + rename
#
# Jan, 2017b
#   + visualization output
#
#set version   = "2.8"; set rev_dat   = "Feb 21, 2017"
#   + more QC output (sca and unwt+thr)
#   + sca and thr opts in
#
#set version   = "2.9"; set rev_dat   = "Apr 11, 2017"
#   + printf fix
#   + working dir better
#   + output command
#
set version   = "3.0"; set rev_dat   = "Apr 26, 2017"
#   + wdir naming
#
# ----------------------------------------------------------------

set this_prog = "fat_proc_decmap"
set tpname    = "${this_prog:gas/fat_proc_//}"
set here      = $PWD

# ----------------- find AFNI and set viewer ---------------------

# find AFNI binaries directory and viewer location
set adir      = ""
set my_viewer = ""
which afni >& /dev/null
if ( $status ) then
    echo "** Cannot find 'afni' (?!)."
    goto BAD_EXIT
else
    set aa   = `which afni`
    set adir = $aa:h
endif

# default location of viewer: user could modify!
set my_viewer = "$adir/@chauffeur_afni"

# ----------------------- set defaults --------------------------

set ifa     = ""
set iv1     = ""
set imask   = ""

set odir      = ""
set opref     = "DEC"
set qc_prefix = ""
set tpref     = "tdwi"
set copy_fa   = "${tpref}_FA.nii"

set wdir       = "__WORKING_$tpname"
set WDIR_EX  = "1"                # put opref on wdir (unless user names)
set output_cmd = 1                # def: output copy of this command
set cmd_file   = ""               # def: same name as viewer
set DO_CLEAN    = "1"             # def: do delete temp files
set DO_VIEWER  = 1                # def: do QC image visualization

set sca_fa    = "0.7"            # optional user scaling for a brighter img

set postfix   = "_"               
set postfix0  = "_dec"            # stick into name
set postfix1  = "_dec_unwt_thr"   # stick into name: unwtd, but thresholded
set postfix2  = "_dec_sca"        # stick into name: unwtd, but thresholded
set thr_fa    = "0.2"             # for unweighted but thresholded image

# ------------------- process options, a la rr ----------------------

if ( $#argv == 0 ) goto SHOW_HELP

set ac = 1
while ( $ac <= $#argv )
    # terminal options
    if ( ("$argv[$ac]" == "-h" ) || ("$argv[$ac]" == "-help" )) then
        goto SHOW_HELP
    endif
    if ( "$argv[$ac]" == "-ver" ) then
        goto SHOW_VERSION
    endif

    # required
    if ( "$argv[$ac]" == "-in_fa" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set ifa = "$argv[$ac]"
        
    else if ( "$argv[$ac]" == "-in_v1" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set iv1 = "$argv[$ac]"

    else if ( "$argv[$ac]" == "-mask" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set imask = "$argv[$ac]"

    else if ( "$argv[$ac]" == "-prefix" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set opref = "$argv[$ac]"

    else if ( "$argv[$ac]" == "-workdir" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set wdir = "$argv[$ac]"
        set WDIR_EX  = "0"

    # --------------- other opts -------------------

    else if ( "$argv[$ac]" == "-fa_thr" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set thr_fa = "$argv[$ac]"

    else if ( "$argv[$ac]" == "-fa_sca" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set sca_fa = "$argv[$ac]"

    else if ( "$argv[$ac]" == "-no_clean" ) then
        set DO_CLEAN = "0"

    else if ( "$argv[$ac]" == "-no_qc_view" ) then
        set DO_VIEWER = 0

    else if ( "$argv[$ac]" == "-qc_prefix" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set qc_prefix = "$argv[$ac]"

    else if ( "$argv[$ac]" == "-no_cmd_out" ) then
        set output_cmd = 0

    else
        echo "** unexpected option #$ac = '$argv[$ac]'"
        goto BAD_EXIT

    endif
    @ ac += 1
end

# =======================================================================
# ============================ ** SETUP ** ==============================
# =======================================================================

# ============================ input files ==============================

echo "++ Start script version: $version"

set check = `3dinfo "$ifa"`
if ( "$#check" == "0" ) then
    echo "** ERROR: can't find inset file $ifa !"
    goto BAD_EXIT
endif

set check = `3dinfo "$iv1"`
if ( "$#check" == "0" ) then
    echo "** ERROR: can't find inset file $iv1 !"
    goto BAD_EXIT
endif

# ========================= output/working dir ==========================

# check output directory, use input one if nothing given

if ( "$opref" == "" ) then
    echo "** ERROR: need '-prefix ...' option provided!"
    echo "   See the helpfile for more information."
    goto BAD_EXIT
else
    set odir = `dirname $opref`
    set opref = `basename $opref`
    echo ""
    echo "++ Based on prefix, the output directory will be:"
    echo "     $odir"
    echo "++ Based on prefix, the output prefix will be:"
    echo "     $opref"
    echo ""
endif

# default output dir, if nothing input.
if ( ! -e "$odir" ) then
    echo "+* Output directory didn't exist.  Trying to make it now."
    mkdir "$odir"
endif

# and put working directory as subdirectory.
if ( "$WDIR_EX" == "1" ) then
    set wdir = $odir/${wdir}_$opref
else
    set wdir = $odir/$wdir
endif

# make the working directory
if ( ! -e $wdir ) then
    echo "++ Making working directory: $wdir"
    mkdir $wdir
else
    echo "+* WARNING: Somehow found a premade working directory (?):"
    echo "     $wdir"

    # don't clean preexisting directories-- could be user mistake.
    echo "   NB: will *not* clean it afterwards."
    set DO_CLEAN = "0"
endif

set ocmd   = "${opref}_cmd.txt"      # name for output command

# =======================================================================
# =========================== ** PROCESS ** =============================
# =======================================================================

echo "\n-----> STARTING $this_prog ---->"

# ---------------------------- CMD ---------------------------------

echo "\n\nThis command:"
echo "$this_prog $argv\n\n"

if ( "$cmd_file" == "" ) then
    set cmd_file = "$odir/$ocmd"
endif

# copy original command:
# dump copy of command into workdir/..
if ( $output_cmd == 1 ) then
    echo "++ Echoing the command to: $cmd_file"

    set rec_afni_ver = `afni -ver`
    echo "### AFNI version:"  > $cmd_file
    echo "# $rec_afni_ver\n"            >> $cmd_file

    echo "### Executed from the directory location:"  >> $cmd_file
    echo "# $here\n"            >> $cmd_file
    echo "### The command was:" >> $cmd_file
    echo "# $this_prog $argv"   >> $cmd_file
    echo "\n"                   >> $cmd_file
endif

# ----------- init: cp data + move to wdir ----------------

if ( $imask =="" ) then
    echo "+* No mask input, so ~making one of regions where FA>0."
    set imask = "${tpref}_mskd.nii"

    3dcalc -echo_edu                     \
        -overwrite                       \
        -a $ifa                          \
        -expr 'step(a)'                  \
        -prefix $wdir/$imask             \
        -datum byte

else
    echo "++ User input mask, so checking for it..."
    set check = `3dinfo "$imask"`
    if ( "$#check" == "0" ) then
        echo "** ERROR: can't find inset file $imask !"
        goto BAD_EXIT
    endif 
    echo "++ ... OK, got $imask"
    
    # copy it, rename and reassign name
    set newmask = "dwi_mask.nii.gz"
    # copy it to wdir
    3dcalc                              \
        -overwrite                      \
        -a $imask                       \
        -expr 'a'                       \
        -prefix $wdir/$newmask

    set imask = "$newmask"
endif

# =======================================================================
# =========================== ** PROCESS ** =============================
# =======================================================================

echo "\n-----> STARTING RGB calcs with FA and V1 <----\n"

3dcalc                                   \
    -echo_edu                            \
    -overwrite                           \
    -a $ifa                              \
    -b "$wdir/$imask"                    \
    -expr 'a*step(b)'                    \
    -prefix "$wdir/$copy_fa"             \
    -datum float

# weighted, but not thresholded, by FA
set fout_wtd = "${tpref}_wtd.nii"
3dcalc                                   \
    -echo_edu                            \
    -overwrite                           \
    -a $ifa                              \
    -b $iv1                              \
    -expr 'a*abs(b)'                     \
    -prefix "$wdir/$fout_wtd"            \
    -datum float

# unweighted, but thresholded, by FA
set fout_uwtd = "${tpref}_uwtd.nii"
3dcalc                                   \
    -echo_edu                            \
    -overwrite                           \
    -a $ifa                              \
    -b $iv1                              \
    -expr "step(a-${thr_fa})*abs(b)"     \
    -prefix "$wdir/$fout_uwtd"           \
    -datum float

if ( $sca_fa != "" ) then
    # weighted, but not thresholded, by FA PLUS scaled by userval
    set fout_sca = "${tpref}_sca.nii"
    3dcalc                                   \
        -echo_edu                            \
        -overwrite                           \
        -a $ifa                              \
        -b $iv1                              \
        -expr "a*abs(b)/${sca_fa}"           \
        -prefix "$wdir/$fout_sca"            \
        -datum float
endif

# change to working directory
cd $wdir

# "classical" dec map
set fin0  = "$fout_wtd"
set fout0 = "${opref}${postfix0}.nii"
3dThreetoRGB                             \
    -echo_edu                            \
    -overwrite                           \
    -scale 255                           \
    -prefix ../$fout0                    \
    -mask   $imask                       \
    $fin0

# "other" dec map
set fin1  = "$fout_uwtd"
set fout1 = "${opref}${postfix1}.nii"
3dThreetoRGB                             \
    -echo_edu                            \
    -overwrite                           \
    -scale 255                           \
    -prefix ../$fout1                    \
    -mask   $imask                       \
    $fin1

if ( $sca_fa != "" ) then
    # "other" dec map
    set fin2  = "$fout_sca"
    set fout2 = "${opref}${postfix2}.nii"
    3dThreetoRGB                             \
        -echo_edu                            \
        -overwrite                           \
        -scale 255                           \
        -prefix ../$fout2                    \
        -mask   $imask                       \
        $fin2
endif

if ( $DO_VIEWER ) then

    echo "++ Making QC images."
    if( $qc_prefix == "" ) then
        set vpref0 = ${opref}${postfix}_qc0${postfix0}
        set vpref1 = ${opref}${postfix}_qc1${postfix1}_"$thr_fa"
        set vpref2 = ${opref}${postfix}_qc2${postfix2}_"$sca_fa"
    else
        set vpref0 = ${qc_prefix}${postfix}_qc0${postfix0}
        set vpref1 = ${qc_prefix}${postfix}_qc1${postfix1}_"$thr_fa"
        set vpref2 = ${qc_prefix}${postfix}_qc2${postfix2}_"$sca_fa"
    endif

    echo "++ QC image #0 (weighted+unthresholded dec): $vpref0"
    $my_viewer      -ulay ../$fout0                 \
                    -prefix $vpref0                 \
                    -outdir ".."                    \
                    -montx 5 -monty 3               \
                    -set_xhairs OFF                 \
                    -label_mode 1 -label_size 3     \
                    -globalrange ""                 \
                    -do_clean

    echo "++ QC image #1 (ulay FA, olay unweighted+thresholded dec): $vpref1"
    $my_viewer      -ulay ../$fout1                 \
                    -prefix $vpref1                 \
                    -outdir ".."                    \
                    -montx 5 -monty 3               \
                    -set_xhairs OFF                 \
                    -label_mode 1 -label_size 3     \
                    -globalrange ""                 \
                    -do_clean

    if ( $sca_fa != "" ) then
        echo "++ QC image #2 (weighted+unthresholded+scaled dec): $vpref2"
        echo "     --> scaling value = $sca_fa"
        $my_viewer      -ulay ../$fout2                 \
                        -prefix $vpref2                 \
                        -outdir ".."                    \
                        -montx 5 -monty 3               \
                        -set_xhairs OFF                 \
                        -label_mode 1 -label_size 3     \
                        -globalrange ""                 \
                        -do_clean
    endif
endif

# --------------------------------------------------------

# leave working dir
cd $here

if ( "$DO_CLEAN" == "1" ) then
    echo "\n Removing temporary file(s) in working dir: $wdir"
   \rm -rf $wdir
else
    echo "\n NOT Removing working director: $wdir\n"
endif

# --------------------------------------------------------

echo ""
echo "++ -----------------------------------------------"
echo "++ DONE! View the finished, DEC (whee, yay!) products:"
echo "    $odir/$fout0"
echo "    $odir/$fout1\n\n"

# ---------------------------------------------------------------------

goto GOOD_EXIT

# ========================================================================
# ========================================================================

SHOW_HELP:
cat << EOF
-------------------------------------------------------------------------

  This program makes a "directionally encoded color" (DEC) map for DTI
  results.  Basically, the directionality of the tensor's major axis
  provides the color information, and the FA value weights the
  brightness (higher FA is brighter).

    red   :     left <-> right
    blue  : inferior <-> superior
    green : anterior <-> posterior

  This program uses the first eigenvector ("V1" file, from 3dDWItoDT),
  takes its absolute value and multiplies each component by the
  voxel's FA value.  That makes a 3-vector of numbers between [0,1],
  which is turned into RGB coloration.

  This is basically a simple wrapper script for 3dcalc and
  3dThreetoRGB.

  REQUIRES: AFNI.

  Ver. $version (PA Taylor, ${rev_dat})

-------------------------------------------------------------------------

  RUNNING:

  This script has two *required* arguments ('-in_fa ...' and '-in_v1 ...'),
  and the rest are optional:

    $this_prog  \
        -in_fa    IFA                            \
        -in_v1    IV1                            \
        {-mask    MASK}                          \
        -prefix   PREFIX                         \
        {-fa_thr  FFF}                           \
        {-fa_sca  SSS}                           \
        {-workdir WWW}                           \
        {-no_clean}                              \
        {-qc_prefix    QCPREF}                   \
        {-no_cmd_out}                            \
        {-no_qc_view} 

   where:
   -in_fa   IFA    :input FA (scalar) map.   
   -in_v1   IV1    :input first eigenvector (3-vector) map.
   -mask    MASK   :optional mask for pickout out a region;
                    otherwise, only places with FA>0 are 
                    given coloration (which just makese sense,
                    anyways, since FA>=0?).

   -prefix   PPP   :set prefix (and path) for output DWI data; required.

   -fa_thr  FFF    :for QC1 type of DEC images, use FFF to threshold
                    where DEC values are calculated (def: FFF = ${thr_fa}).
   -fa_sca  SSS    :for QC2 type of DEC images, use SSS to scale the 
                    FA weighting of what would otherwise be a 'classical'
                    DEC map (where |V1|*FA);  this is added because 
                    sometimes the DEC map can be kind of dim when 
                    weighting by FA only; instead, in this map, RGB values
                    are given by '|V1|*FA/SSS' (def:  SSS = ${sca_fa}).

   -no_qc_view     :by default, a set of QC snapshots are made and
                    output.  To turn these off (why?), use this
                    switch
   -qc_prefix QCP  :by default, the QC snapshots carry the same output
                    name as the final output: PREFIX_*. You
                    can change this to be QCP_*, if you want.

   -workdir WWW    :specify a working directory, which can be removed;
                    (default name = '$wdir').

   -no_clean       :a couple temporary files are created whilst
                    making the DEC map.  This switch tells the 
                    program to *not* delete them when finishing
                    (default is to do so).  The default prefix of 
                    working dir is '$wdir'.

 -qc_prefix QCPREF :can set the prefix of the QC image files separately
                    (default is '$opref').
   -no_qc_view     :can turn off generating QC image files (why?)
   -no_cmd_out     :don't save the command line call of this program
                    and the location where it was run (otherwise, it is
                    saved by default in the ODIR/).

 ------------------------------------------------------------------------

  OUTPUTS:

    PREFIX${postfix0}.nii.gz 
        a single file of type 'rgb' that AFNI knows how to 
        display with RGB coloration when viewed as underlay: 
        made by using V1 as RGB and weighting by FA values

    PREFIX${postfix1}.nii.gz 
        a single file of type 'rgb' that AFNI knows how to 
        display with RGB coloration when viewed as underlay: 
        made by using V1 as RGB, *not* weighting by FA, but using FA
        to threshold where DEC values are calculated (def: FA>0.2).

    PREFIX${postfix2}*.nii.gz 
        A similar file to PREFIX${postfix0}.nii.gz, but additionally
        scaled by a value (such as 0.7; see "-sca_fa SSS" option
        above); this can 'brighten' the DEC map for clarity.

    PREFIX${postfix0}_qc0*.png
        a set cor, axi and sag images (each a 5x3 montage) of the 
        PREFIX${postfix0}.nii.gz data set.

    PREFIX${postfix1}_qc1*.png
        a set cor, axi and sag images (each a 5x3 montage) of the 
        PREFIX${postfix1}.nii.gz data set.

    PREFIX${postfix2}*_qc2*.png
        a set cor, axi and sag images (each a 5x3 montage) of the 
        PREFIX${postfix2}.nii.gz data set.

    (working directory of temp files: these can be deleted, as desired.)

-------------------------------------------------------------------------

  EXAMPLE:
    
    $this_prog  \
        -in_fa DTI/DT_FA+orig.                    \
        -in_v1 DTI/DT_V1+orig.                    \
        -mask  mask_DWI+orig                      \
        -prefix DEC

-------------------------------------------------------------------------
EOF

    goto GOOD_EXIT

SHOW_VERSION:
   echo "version  $version (${rev_dat})"
   goto GOOD_EXIT

FAIL_MISSING_ARG:
    echo "** ERROR! Missing an argument after option flag: '$argv[$ac]'"
    goto BAD_EXIT

BAD_EXIT:
    exit 1

GOOD_EXIT:
    exit 0
