#!/bin/tcsh

set version   = "0.0";  set rev_dat   = "May 30, 2024"
# + desphinxify datasets, particularly for nonhuman datasets
#
# ----------------------------------------------------------------

set this_prog = "desphinxify"
set prog_abbr = "desphinx"
#set tpname    = "${this_prog:gas///}"
set here      = $PWD

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

set input   = ""
set prefix  = ""

set ori_mid = ""            # the mid-proc orient that actually 
                            # rotates the dset. user **must** specify
                            # (likely should be RIP)

set odir    = $here
set opref   = ""
set wdir    = ""
set ow      = ""                        # overwrite? (off by def)

set DO_CLEAN  = 1                       # default: keep working dir

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

    if ( "$argv[$ac]" == '-echo' ) then
        set echo

    # --------- required

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

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

    # we recommend in help, but user MUST specify
    else if ( "$argv[$ac]" == "-orient_mid" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set ori_mid = "$argv[$ac]"

    # --------- opt

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

        set tf = `python -c "print('/' in '${wdir}')"`
        if ( "${tf}" == "True" ) then
            echo "** ERROR: '-workdir ..' is a name only, no '/' allowed\n"
            goto BAD_EXIT
        endif

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

    else if ( "$argv[$ac]" == "-overwrite" ) then
        set ow = "-overwrite"

    else
        echo "\n\n** ERROR: unexpected option #$ac = '$argv[$ac]'\n\n"
        goto BAD_EXIT
        
    endif
    @ ac += 1
end

# =======================================================================
# ======================== ** Verify + setup ** =========================
# =======================================================================

if ( "${prefix}" == "" ) then
    echo "** ERROR: need to provide output name with '-prefix ..'"
    goto BAD_EXIT
endif

if ( "${input}" == "" ) then
    echo "** ERROR: need to provide input dataset with '-input ..'"
    goto BAD_EXIT
endif

if ( "${ori_mid}" == "" ) then
    echo "** ERROR: need to provide an intermediate dset orientation"
    echo "   with '-orient_mid ..'"
    goto BAD_EXIT
endif

# make workdir name, if nec
if ( "${wdir}" == "" ) then
    set tmp_code = `3dnewid -fun11`  # should be essentially unique hash
    set wdir     = __workdir_${this_prog}_${tmp_code}
endif

# check output directory, use input one if nothing given
if ( ! -e "${odir}" ) then
    echo "++ Making new output directory: $odir"
    \mkdir -p "${odir}"
endif

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

# =======================================================================
# =========================== ** Main work ** ===========================
# =======================================================================

# intermediate/final values derived from input dset
set inori    = `3dinfo -orient       "${input}"`
set inpre    = `3dinfo -prefix_noext "${input}"`
set inobl    = `3dinfo -is_oblique   "${input}"`

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

set dset_00 = __tmp_00_copy.nii

# copy dset to wdir
3dcalc                                     \
    -a "${input}"                          \
    -expr "a"                              \
    -prefix "${odir}/${wdir}/${dset_00}"

# go to wdir
cd "${odir}/${wdir}"


# recenter around origin, if obliquity exists (3dresample would purge
# obliquity anyways)
if ( ${inobl} ) then
    echo "++ deoblique input around origin (no resampling)"
    adjunct_deob_around_origin                       \
        -input   "${dset_00}"                        \
        -prefix  __tmp_00_deob.nii

    set dset_00 = __tmp_00_deob.nii
endif

# resample input to have RAI orientation (will lose obliquity info)
3dresample -orient RAI -prefix __tmp_01.nii -input "${dset_00}"

# refit the tmp dset to effectively rotate.  
3drefit -orient ${ori_mid}  __tmp_01.nii

# resample tmp to have its original orientation in final output
3dresample -orient ${inori} -prefix __tmp_02_res.nii -input __tmp_01.nii

# copy to output
3dcopy ${ow} __tmp_02_res.nii "../${opref}"

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

# move out of wdir to the odir
cd ..
set whereout = $PWD

if ( $DO_CLEAN == 1 ) then
    echo "++ Clean working dir"
    # ***** clean
    \rm -rf "${wdir}"
endif

cat <<EOF

++ DONE. See the output:
   $whereout/${opref}"

EOF

goto GOOD_EXIT

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

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

Overview ~1~

This is a simple program that *might* be useful for desphinxifying
datasets. That is, when datasets are acquired in "sphinx" position,
this will try to reorient them to match with axial/coronal/sagittal
definitions standard to human neuroimaging. This may be useful
particularly when processing nonhuman datasets

Importantly, this program really only reliable **if** the user knows
the correct final dataset orientation, to verify. We can recommend a
useful intermediate orientation to reorient the data correctly, but
the user is in charge of being user.

ver  = ${version}
auth = PA Taylor (SSCC, NIMH, NIH)
-------------------------------------------------------------------------

Options ~1~

-input II         :(req) input dset name

-prefix PP        :(req) output dset name (can include path)

-orient_mid OM    :(req) intermediate orientation value, which determines
                   how the input dataset is effectively rotated (from
                   RAI orientation) in order to desphinxify it.  
                   **NB:** a commonly used value here is: RIP.  
                   However, users must verify this, particularly to get
                   left and right correct (other mistakes in orientation
                   tend to be more visually apparent). That is why there is
                   no default value: please check this with a pilot dataset
                   for your study.

-workdir WD      : working directory name (just name, no path;
                   will be subdirectory of the output location)

-overwrite       : when writing output, overwrite any preexisting
                   dataset (def: do not overwrite)

-no_clean        : when done, do not remove temporary working
                   directory (def: do remove woroking directory

-echo            : run very verbosely (with 'set echo' on)

-ver             : display program version

-help            : show help

-hview           : show help in text editor

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

Examples ~1~

1) Basic usage:
     desphinxify                                \
        -orient_mid  RPI                        \
        -input       sub-001_T1w.nii.gz         \
        -prefix      sub-001_T1w_DSPH.nii.gz

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
