#!/bin/tcsh -e

# written by PA Taylor (NIMH, NIH, USA)
# started March, 2017

# --------------------- revision history -------------------------
#
#set version   = "1.0";    set rev_dat   = "March 29, 2017"
#   + inception
#
#set version   = "1.1";    set rev_dat   = "Apr 15, 2017"
#   + standardize I/O
#
#set version   = "1.2";    set rev_dat   = "Apr 15, 2017"
#   + run with helpfile correctly for no inputs
#
#set version   = "1.3";    set rev_dat   = "Apr 27, 2017"
#   + naming conventions corrected
#
#set version   = "1.4";    set rev_dat   = "Apr 28, 2017"
#   + path stuff corrected, for arbitrary locations
#
set version   = "1.5";    set rev_dat   = "Sep 04, 2017"
#   + update to use new @chauffeur* calling
#
# ---------------------------------------------------------------

set this_prog = "fat_proc_select_vols"
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 my_selector  = "$adir/@djunct_dwi_selector.bash"
set my_encoder   = "$adir/@djunct_select_str.py"
set my_viewer_4d = "$adir/@djunct_4d_imager"

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

set idwi       = ""              # required input
set iimg       = ""              # required input
set obads      = ""              # NOT required input

set odir       = ""
set opref      = ""
set DO_OUTVOL  = "0"               # don't apply to DWI by default

set DO_VIEWER  = "1"             # def: do viewing
set DO_CLEAN   = 1
set output_cmd = 1               # def: output copy of this command
set cmd_file   = ""              # def: same name as viewer
set qc_prefix  = ""              # def: autoname; user can enter
set postfix    = "_"             # stick into name

set movie      = ""
set wdir     = "__WORKING_$tpname"
set WDIR_EX  = "1"               # put opref on wdir (unless user names)

# ------------------- 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

    # --------------- input dset(s) ----------------
    # input dwi set
    if ( "$argv[$ac]" == "-in_dwi" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set idwi = "$argv[$ac]"

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

    # can edit a pre-existing text file
    else if ( "$argv[$ac]" == "-in_bads" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set obads = "$argv[$ac]"

    # ----------------- outputs ---------------------

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

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

    # ? make a flag to chop the input DWI if necessary?

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

    # --------------- apply to DWI and image ---------

    else if ( "$argv[$ac]" == "-apply_to_vols" ) then
        set DO_OUTVOL = "1"

    else if ( "$argv[$ac]" == "-do_movie" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set movie = "$argv[$ac]"
        if ( ( $movie == "MPEG" ) || ( $movie == "AGIF" ) ) then
            echo "++ OK, will make a movie of type $movie."
        else
            echo "** ERROR: '$movie' is NOT an allowed movie format!"
            echo "      -> must be either 'MPEG' or 'AGIF'"
            goto BAD_EXIT
        endif
        # replace with both here for calling @dj*
        set movie = "-do_movie $movie"   

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

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

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

    endif
    @ ac += 1
end

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

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

echo "++ Start script version: $version"

# NEED this input
if ( "$idwi" == "" ) then
    echo "** ERROR: no t1w file input?!"
    goto BAD_EXIT
endif

# make sure we can read volumes OK
foreach ff ( "$idwi" )
    set check = `3dinfo "$ff"`
    if ( "$#check" == "0" ) then
        echo "** ERROR: can't find input file:  $ff !"
        goto BAD_EXIT
    else
        echo "++ Found input file:   $ff"
    endif
end

# ========================= output dir ==========================

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

# check output directory, use input one if nothing given

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

# ----> here, only need wdir if outputting imgs but no vol; see below

# ========================= output fnames ==========================

set ocmd   = "${opref}_cmd.txt"            # name for output command
set ogoods = "$odir/${opref}_goods.txt"    # name 
set ovol   = "${opref}.nii.gz"             # name 

if ( "$obads" == "" ) then

    # then need to glue on the odir in this case
    set obads  = "$odir/${opref}_bads.txt"

    if ( -e "$obads" ) then
        echo ""
        echo "** ERROR! File for listing 'bads' exists already: $odir/$obads"
        echo "   ---> If you want to add to a list you started previously,"
        echo "        you must use the '-in_bads ...' option."
        echo "        (Sorry, but hopefully this prevents mistakenly"
        echo "        appending to preexisting lists.)\n"
        goto BAD_EXIT
    else
        echo "++ Setting up file for output: $obads"
    endif
else
    # in input by the user, then $obads shd be a full path, as needed, 
    if ( -e "$obads" ) then
        echo ""
        echo "+* WARNING! Just so you know the file: $obads"
        echo "   exists already!  I assume you know that you will append to"
        echo "   it, and that you want to do so (because I assume all users"
        echo "   read help files as much as *I* do!)"
        echo "   Ooook, carrying on, then.\n"
    endif
endif

# =======================================================================
# =========================== ** 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

# --------------------- start proc ---------------------------

echo "++ Call selector:"
echo "   $my_selector $idwi $iimg $obads\n"

$my_selector "$idwi" "$iimg" "$obads"

set Nvols = `3dinfo -nv "$idwi"`

$my_encoder  "$obads" $Nvols "$ogoods"

if ( "$DO_OUTVOL" == "1" ) then

    set selstr = `cat $ogoods`
    3dcalc                    \
        -overwrite            \
        -a "$idwi""[$selstr]" \
        -expr 'a'             \
        -prefix $odir/$ovol

    if ( "$DO_VIEWER" == "1" ) then

        set img_pref = `basename $ovol     .gz`
        set img_pref = `basename $img_pref .nii`

        $my_viewer_4d \
            -inset  $odir/$ovol               \
            -prefix "$odir/$img_pref"   

        if ( "$movie" != "" ) then
            $my_viewer_4d \
                -inset  $odir/$ovol          \
                -prefix "$odir/$img_pref"    \
                $movie
        endif
    endif
else
    if ( "$DO_VIEWER" == "1" ) then
        
        # ---------- wdir ---------------------
        # 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 selstr = `cat $ogoods`
        set fout   = $wdir/$ovol
        3dcalc                    \
            -overwrite            \
            -a "$idwi""[$selstr]" \
            -expr 'a'             \
            -prefix $fout

        set img_pref = `basename $fout     .gz`
        set img_pref = `basename $img_pref .nii`

#        $my_viewer_4d \
#            -inset  "$fout"        \
#            -outdir "$odir"                   \
#            -prefix "$img_pref"   
        $my_viewer_4d \
            -inset  "$fout"              \
            -prefix "$odir/$img_pref"   

        if ( "$movie" != "" ) then
#            $my_viewer_4d \
#                -inset  "$fout"        \
#                -outdir "$odir"                   \
#                -prefix "$img_pref"         \
#                $movie
            $my_viewer_4d \
                -inset  "$fout"              \
                -prefix "$odir/$img_pref"    \
                $movie
        endif

        if ( "$DO_CLEAN" == "1" ) then
            echo "\n++ Cleaning working directory!\n"
            cd $here
            \rm -rf $wdir
        else
            echo "\n++ NOT removing working directory '$wdir'.\n"
        endif

    endif
endif

# ---------------------------------------------------------------------
goto GOOD_EXIT

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

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

 This program is for building a selector string for AFNI subbricks
 and/or 1D text files.  It makes use of J. Rajendra's
 '@djunct_dwi_selector.sh' script to make a list of 'bad' volume
 indices by clicking on individual volumes in a montage image.  Pretty
 cool.

 In the end, a selector string of volumes *to keep* (i.e., the
 complement of the set of indices chosen with clicks) is output to
 screen as well as stored in a text file.

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

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

  OUTPUT:

    + PPP_bads.txt: text file with AFNI-usable selector string, which
                    can be put into either square brackets [] or curly
                    brackets {}, whichever is appropriate for a given
                    application.

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

  RUNNING:

    $this_prog  \
        -in_dwi   DDD                  \
        -in_img   IM2D                 \
        {-in_bads TTT}                 \
        -prefix  PPP                   \
        {-apply_to_vols}               \
        {-do_movie AGIF|MPEG}          \
        {-workdir WWW}                 \
        {-no_cmd_out} 

  where:

   -in_dwi  DDD   :input DWI set (required).
   -in_img  IM2D  :2d image of DDD, such as made by a fat_proc* 
                   script, or @djunct_*imager directly (required).
   -in_bads TTT   :(optional) a single column file of integers,
                   such as made by a previous run of $this_prog.
                   For example, if one has dual phase-encoded
                   DWI data, then one might make a list of bads
                   from the AP-acquired set and then add to it any
                   bad indices from the PA-acquired set.

   -prefix  PPP   :output prefix for files. Required.

   -apply_to_vols :switch to apply the created selection of good 
                   volumes to the DWI dset.  NB: if you are using 
                   this function to select out bad volumes from 
                   a dual phase encode set, then you *wouldn't* want 
                   to use this option, because you want to apply
                   the complete removal to *both* volumes.  Note also,
                   that once you apply this selection to the volumes,
                   you also need to apply it to any bval, bvec, bmatrix,
                   etc. text files!

    -do_movie AGIF | MPEG:
                   when "-apply_to_vols" is used, static images are 
                   output by default;  one can use this option with 
                   either of the given arguments to output a movie of the
                   newly created dset.  Only those arguments can be used
                   at present.

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

   -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/).                     

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

  EXAMPLE

    $this_prog    \
        -in_dwi DWI.nii.gz               \
        -in_img DWI_sepscl.sag.png       \
        -prefix DWI_trim


    $this_prog    \
        -in_dwi DWI_ap.nii.gz            \
        -in_img DWI_ap_sepscl.sag.png    \
        -in_bads DWI_trim_bads.txt       \
        -prefix DWI_trim_both 

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

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

# send everyone here, in case there is any cleanup to do
GOOD_EXIT:
    exit 0
