#!/bin/tcsh -e

# --------------------- revision history -------------------------
# Jan, 2017
#   + rename
#
# Jan 27, 2017
#   + update opts
#   + 
#
#set version   = "2.0"; set rev_dat   = "Apr 11, 2017"
#   + majorly updating I/O
#   + wdir stuff
#
#set version   = "2.1"; set rev_dat   = "Apr 14, 2017"
#   + try to anonymize
#   + qc snapshotting
#set version = "2.8"; set rev_dat = "Apr 19, 2017"
#   + switch to dcm2niix from dcm2nii
#     -> motivated by Philips scaling requirements
#     -> prob better to stick with newer, anyways
#
#set version = "2.9"; set rev_dat = "Apr 21, 2017"
#   + no more automask in 3dCM
#
#set version = "3.0"; set rev_dat = "Apr 26, 2017"
#   + dcm2niix -> dcm2niix_afni
#
set version = "3.1"; set rev_dat = "May 24, 2017"
#   + dcm2niix_afni: in multiecho DCMs, the echo number
#     automatically gets put in *somehow*, whether asked for or not
#     ... so now this is controlled for
#
# ----------------------------------------------------------------

set this_prog = "fat_proc_convert_dcm_anat"
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 "** ERROR: 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"

# ----------------- find dcm2niix ---------------------

which dcm2niix_afni >& /dev/null
if ( $status ) then
    echo "** ERROR: Cannot find 'dcm2niix_afni'."
    goto BAD_EXIT
endif

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

set idir     = ""
set odir     = ""
set tpref    = "ttt"

set ori_new  = "RPI"
set ofile    = ""
set opref    = ""
set DO_REORI = 1

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 qc_prefix  = ""               # def: autoname; user can enter
set postfix    = "_"              # stick into name

set npref      = "nnn"

# ------------------- 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(s) ----------------
    if ( "$argv[$ac]" == "-indir" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set idir = "$argv[$ac]"

    # ------------- output(s) ----------------
    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]" == "-orient" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set ori_new = "$argv[$ac]"

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

    else if ( "$argv[$ac]" == "-reorig_reorient_off" ) then
        set DO_REORI = 0          # leave 'em alone!

    # -------------- qc stuff ----------------

    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_qc_view" ) then
        set DO_VIEWER = 0

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

echo "++ Start script version: $version"

# ============================= dicom dir ===============================

if ( "$idir" == "" ) then
    echo "** ERROR: need to input DICOM directory, after '-indir':"
    goto BAD_EXIT
endif

if ( ! -e "$idir" ) then
    echo "\n** ERROR: can't find input DICOM directory: $idir !"
    goto BAD_EXIT
endif

# check for old relics

cd $idir

echo "++ Checking $PWD for preexisting NIFTIs ... "

if ( (`find . -maxdepth 1 -type f -name "*nii" | wc -l` > 0 ) || \
     (`find . -maxdepth 1 -type f -name "*nii.gz" | wc -l` > 0 ) ) then
    echo "\n** ERROR: already some NIFTI files in $idir !"
    goto BAD_EXIT
endif

# get back home for running stuff
cd $here 

# ========================= 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
set ofile  = "${opref}.nii.gz"       # 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

# ======================== convert dicoms ===============================

# place output into wdir, using gzipped files. 
# [PT: May 24, 2017] Control for multiecho files now
dcm2niix_afni  \
        -z y              \
        -x n              \
        -p y              \
        -f ${npref}_%e    \
        -o "$wdir"        \
        $idir/

# ================ clean up possible extraneous files ===================

cd $wdir

set all_nii = `\ls ${npref}*.nii.gz`

# =========== put into proper orientation, simplify name =================

if ( ${#all_nii} < "1" ) then
    echo "\n** ERROR: no anatomical found"
    echo "\t(at least not with expected filename '2*')\n"
    goto BAD_EXIT
else if ( ${#all_nii} >= "2" ) then
    echo ""
    echo "+* Warning: multiple possible volumes, just choosing first one (?)"
    echo ""
endif

# ---------- try to anonymize -------------
echo "++ Using nifti_tool to remove ID info, if possible."

set fin  = $all_nii[1]
set fout = ${tpref}_empty.nii
nifti_tool                          \
    -strip_extras                   \
    -prefix  $fout                  \
    -infiles $fin

# ---------- center nicely, if desired -------------

if ( $DO_REORI ) then

    3dresample                                        \
        -orient $ori_new                              \
        -inset  $fout                                 \
        -prefix ../$ofile                             \
        -overwrite

    # put (0, 0, 0) at center of mass.  (Aug, 2016)
    3dCM -set 0 0 0 ../$ofile

else
    # chicken...
    3dcalc                                 \
        -a $fout                           \
        -expr 'a'                          \
        -prefix ../$ofile                  \
        -overwrite
endif

cd $here 

set check = `3dinfo "$odir/$ofile"`
#echo "$#check"
if ( "$#check" >= "0" ) then
    echo "\nAll done!"
    cd $odir
    echo "\nYour output anatomical is:\n\t$PWD/$ofile\n"
    cd $here
else 
    echo "Whoa, badness outputting: $odir/$ofile"
    goto BAD_EXIT
endif

# ---------------- imager -------------------

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

    if( $qc_prefix == "" ) then
        set vpref0 = ${opref}${postfix}_qc00_anat
    else
        set vpref0 = ${qc_prefix}${postfix}_qc00_anat
    endif

    echo "\n\n"
    echo "++ QC image 00 ($odir/$ofile): $vpref0"
    echo "\n\n"
    # need to put '[0]' on $iref?
    $my_viewer                            \
        -ulay "$odir/$ofile"              \
        -ulay_range "2%" "98%"            \
        -olay_off                         \
        -prefix $vpref0                   \
        -outdir "$odir"                   \
        -montx 5 -monty 3                 \
        -set_xhairs OFF                   \
        -label_mode 1 -label_size 3       \
        -do_clean 

endif

# --------------- clean --------------------

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

goto GOOD_EXIT

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

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

    The purpose of this function is to help convert an anatomical data
    set from DICOM files into a volume.  Ummm, yep, that's about it.

    (But it will be done in a way to fit in line with other
    processing, particularly with DTI analysis, so it might not be
    *totally* useless; more options while converting might be added
    over time, as well.)

    REQUIRES: AFNI (which should now contain dcm2niix_afni, the
    version of dcm2niix [by C. Rorden] distributed in AFNI).

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

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

  RUNNING:

  $this_prog  \
        -indir    DIR_IN                       \
        -prefix  PPP                           \
        {-workdir WWW}                         \
        {-orient  ORIENT}                      \
        {-no_clean}                            \
        {-reorig_reorient_off}                 \
        {-qc_prefix    QCPREF}                 \
        {-no_cmd_out}                          \
        {-no_qc_view} 

  where:
    -indir  DIR_IN  :required input directory; DIR_IN should contain
                     only DICOM files; all will be selected.

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

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

    -orient  ORIENT :optional chance to reset orientation of the volume
                     files (default is currently '$ori_new').
  -reorig_reorient_off
                    :switch to turn of the nicety of putting (0, 0, 0)
                     at brain's center of mass (-> 'reorigin' calc) and to
                     not reorient data (-> 'reorient' calc).  Could lead
                     to weirdness later on down the road, depending on the
                     data and headers (ergo, not recommended.)

  -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: a single anatomical volume in the DIR_OUT.  
           In some cases of anatomical volume acquisition, the DICOMS
           get converted to more than one format of volumetric output
           (one total acquired volume, one centered around the head,
           etc.); these usually have different formats of file name,
           starting with '2*', 'co*' and 'o*'.  Basically, the '2*' is
           chosen for outputting, and the others are stored in a
           subdirectory called DIR_OUT/WWW/.

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

  EXAMPLE:

    $this_prog  \
       -indir  "ANAT_DICOMS"                 \
       -orient RAI
    
-------------------------------------------------------------------------

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
