#!/bin/tcsh

@global_parse `basename $0` "$*" ; if ($status) exit 0

# --------------------- 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 version = "3.2"; set rev_dat = "Sep 04, 2017"
#   + work with new @chauffeur*, '-prefix ...' only
#
#set version = "3.3"; set rev_dat = "Feb 20, 2018"
#   + output QC dir for images
#   + default orientation RAI
#
#set version = "3.4"; set rev_dat = "June 26, 2018"
#   + allow a NIFTI anatomical to be input, and then do rest of 
#     niceifying steps
#
#set version   = "3.5";   set rev_dat   = "Feb 12, 2019"
#     + [PT] change "checks" to use '3dinfo -prefix ...' as a better
#            methodology
#
set version   = "3.52";   set rev_dat   = "Sep 27, 2021"
#     + [PT] chauffeur label_size 3 -> 4, bc imseq.c shifted all sizes
#       down one level
#
# ----------------------------------------------------------------

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 inii     = ""
set odir     = ""
set tpref    = "ttt"

set ori_new  = "RAI"
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 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]"

    # [PT: June 26, 2018] Input nifti instead of just directory to be
    # converted
    else if ( "$argv[$ac]" == "-innii" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set inii = "$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" == "" && "$inii" == "" ) then
    echo "** ERROR: need to either"
    echo "          A) input DICOM directory, after '-indir'; or"
    echo "          B) input NIFTI file, after '-innii'"
    goto BAD_EXIT
else if ( "$idir" != "" && "$inii" != "" ) then
    echo "** ERROR: need to choose *either* '-indir' or  '-innii' input."
    goto BAD_EXIT
endif

# ---------- if input dir, check existence, and more
if ( "$idir" != "" ) then
    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"
endif

# ---------- if input nifti, check existence
if ( "$inii" != "" ) then
    set ff    = "$inii"
    set check = `3dinfo -prefix "$ff"`
    if ( "$check" == "NO-DSET" ) then
        echo "** ERROR: can't find input file:  $ff"
        goto BAD_EXIT
    else
        echo "++ Found input file:   $ff"
    endif
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

set odirqc = "$odir/QC"
if ( "$DO_VIEWER" == "1" ) then
    if ( ! -e "$odirqc" ) then
        mkdir "$odirqc"
    endif
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 -p "$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 ===============================

if ( "$idir" != "" ) then
    # 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`

    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 vols, just choosing first one (?)"
        echo ""
    endif
endif

# ======================== copy input vol to wdir =======================

if ( "$inii" != "" ) then
    # just copy the vol to the wdir
    set fout = "_init_vol.nii.gz"
    3dcalc                              \
        -overwrite                      \
        -a "$inii"                      \
        -expr 'a'                       \
        -prefix "$wdir/$fout"

    # ... and match with where things would be from "$idir" input
    cd "$wdir"
    set all_nii = "$fout" 
endif

# ======================== process! ==================================

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

# ---------- reorient + 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 -prefix "$odir/$ofile"`
if ( "$check" == "NO-DSET" ) then
    echo "Whoa, badness outputting: $odir/$ofile"
    goto BAD_EXIT
else
    echo "\nAll done!"
    cd $odir
    echo "\nYour output anatomical is:\n\t$PWD/$ofile\n"
    cd "$here"
endif 

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

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

    if ( $qc_prefix == "" ) then
        set vpref0 = ${opref}_qc_anat
    else
        set vpref0 = ${qc_prefix}_qc_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 "$odirqc/$vpref0"         \
        -montx 5 -monty 3                 \
        -set_xhairs OFF                   \
        -label_mode 1 -label_size 4       \
        -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  | -innii  NII_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  :input as dicom directory; DIR_IN should contain
                     only DICOM files; all will be selected.
    -innii  NII_IN  :input as NIFTI file (zipped or unzipped fine).
                     Alternative to '-indir ..'. The point of this option
                     is to have all other "niceifying" steps applied
                     to an already-converted volume.

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

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

  EXAMPLES:

    $this_prog  \
       -indir  "ANAT_DICOMS"                 \
       -prefix outdir/anat                   \
       -orient RAI
    
    $this_prog  \
       -innii  t1w.nii.gz                    \
       -prefix outdir/anat                   \
       -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
