#!/usr/bin/tcsh

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

## This script re-faces one input dataset, using a master shell dataset to
## write over the subject's 'face' region (which includes a bunch of skull).
## The single command line argument is the name of a T1-weighted dataset.

## This script relies on two datasets that are included with AFNI binaries:
##   MNI152_2009_template_SSW.nii.gz = MNI skull strip/warp template
##   afni_refacer_shell.nii.gz       = dataset to replace face region
## The latter dataset was made with the script @afni_refacer_make_master.

# ============================================================================
# 
#set version   = "2.0"; set rev_dat   = "Jan 23, 2020"
#   + [PT] put in real option parsing
#        + also allow user to input fname in truer AFNI-style as
#          "SOMETHING+orig" and not just SOMETHING+orig.HEAD
#        + new shell has been created+used here
#
#set version   = "2.1"; set rev_dat   = "Jan 26, 2020"
#   + [PT] choose modes of running differently
#        + also be able to output all versions of re/defacing at once
#
#set version   = "2.11"; set rev_dat   = "Jan 27, 2020"
#   + [PT] include QC images now
#
#set version   = "2.12"; set rev_dat   = "Jan 29, 2020"
#   + [PT] new opt: can choose cost func
#
#set version   = "2.2"; set rev_dat   = "Feb 3, 2020"
#   + [PT] new opt: -anonymize_output (pretty self-explanatory)
#
#set version   = "2.3"; set rev_dat   = "Aug 31, 2021"
#   + [PT] change default cost to 'lpa' (was 'ls'?)
#
#set version   = "2.31";   set rev_dat   = "Sep 27, 2021"
#     + [PT] chauffeur label_size 3 -> 4, bc imseq.c shifted all sizes
#       down one level
#
#set version   = "2.4";   set rev_dat   = "Apr 23, 2022"
#     + [PT] start optionizing template+shell to use
#       - also introduce new shell with larger face/neck removal
#
#set version   = "2.5";   set rev_dat   = "Aug 29, 2025"
#     + [PT] add cubeface functionality and opts
#
#set version   = "2.6";   set rev_dat   = "Sep 25, 2025"
#     + [PT] migrate from older @afni_refacer_run
#       - start using newer shells
#       - move default ref_shell to sym_2.1 (more anonymizing)
#
set version   = "2.7";   set rev_dat   = "July 1, 2026"
#     + [PT] update help and tweak option usage
#       - move less useful -mode_* opts to -mode2_*
#
# ============================================================================

set iset       = ""            # name of input dset
set impref     = ""            # need a prefix now
set odir       = '.'

set run_mode   = ( )           # also, "REFACE_FACE", "DEFACE"
set verb_allin = ""            # don't need this verbose, by def (can with opt)
set DO_CLEAN   = 1
set DO_CHAUFF  = 1             # of COURSE users want images
set owrite     = ""

set DO_ANON    = 0             # opt: anonymize the output dsets

set cost_allin = "lpa"          # cost function used; this was orig def

# for cubeface
set lcube = 10
set edge  = ( 0 0 0 )


### these dsets are now selectable/alterable at command line
# this is a newer shell than (now long ago) original: this one is
# symmetric, without gaps in the skull, and more tightly bounded by -1s.
set ref_shell = "afni_refacer_shell_sym_2.1.nii.gz"  
set ref_dset  = "MNI152_2009_template_SSW.nii.gz"

set all_ok_shell = ( "afni_refacer_shell_sym_1.0.nii.gz" \
                     "afni_refacer_shell_sym_2.0.nii.gz" \
                     "afni_refacer_shell_sym_1.1.nii.gz" \
                     "afni_refacer_shell_sym_2.1.nii.gz" )

# ------------------------ read in + interpret cmd line opts -----------------

if ( $#argv == 0 ) goto SHOW_HELP

set ac = 1
while ( $ac <= $#argv )

    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 iset = "$argv[$ac]"

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

    # need at least one mode (list of uniq-ized below)
    else if ( "$argv[$ac]" == "-mode_deface" ) then
        set run_mode = ( ${run_mode} "deface" )
    else if ( "$argv[$ac]" == "-mode_reface" ) then
        set run_mode = ( ${run_mode} "reface" )
    else if ( "$argv[$ac]" == "-mode_reface_plus" ) then
        set run_mode = ( ${run_mode} "reface_plus" )
    else if ( "$argv[$ac]" == "-mode_all" ) then
        set run_mode = ( ${run_mode} "deface" "reface" "reface_plus" )

    else if ( "$argv[$ac]" == "-mode2_cubeface" ) then
        set run_mode = ( ${run_mode} "cubeface" )
    else if ( "$argv[$ac]" == "-mode2_all" ) then
        set run_mode = ( ${run_mode} "cubeface" )

    # ------------------------------------------------------
    # opt

    # now checked below for valid choice
    else if ( "$argv[$ac]" == "-ref_shell" ) then
        if ( $ac >= $#argv ) goto FAIL_MISSING_ARG
        @ ac += 1
        set ref_shell = "$argv[$ac]"

    else if ( "$argv[$ac]" == "-anonymize_output" ) then
        set DO_ANON = 1

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

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

    else if ( "$argv[$ac]" == "-no_images" ) then
        set DO_CHAUFF = 0

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

    else if ( "$argv[$ac]" == "-verb_allin" ) then
        set verb_allin = "-verb"

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

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

    else
        echo "** unexpected option #$ac = '$argv[$ac]'"
        exit 2

    endif
    @ ac += 1
end

# ------------------ parse/verify inputs ---------------------------

echo "++ verify inputs and options"

# need a run_mode to have been entered
if ( ! ${#run_mode} ) then
    echo "** ERROR: need to specify at least one mode with '-mode_*'"
    goto BAD_EXIT
else
    # get uniq (and sorted) list of modes
    set run_mode = `echo ${run_mode} | tr ' ' '\n' | sort | uniq`
endif

# check main input
if ( "${iset}" == "" ) then
    echo "** ERROR: need to have an input anatomical, at least"
    goto BAD_EXIT
else
    set check = `3dinfo -prefix "${iset}"`
    if ( "${check}" == "NO-DSET" ) then
        echo "** ERROR: can't find input file:  ${iset}"
        goto BAD_EXIT
    else
        echo "++ Found input file:   ${iset}"
    endif
endif

# find MNI template (target for 3dAllineate)
set Basedset = `@FindAfniDsetPath -full_path -append_file "${ref_dset}"`
if ( "${Basedset}" == '' ) then
    echo "** ERROR: Failed to find template ${ref_dset} -- exiting :(" 
    goto BAD_EXIT
endif

# check that ref_shell is valid
set FOUND = 0
foreach shell ( ${all_ok_shell} )
    if ( "${ref_shell}" == "${shell}" ) then
        set FOUND = 1
    endif
end
if ( ! ${FOUND} ) then
    echo "** ERROR: not an allowed shell.  Must be one of:"
    foreach shell ( ${all_ok_shell} )
       echo "   ${shell}"
    end
    goto BAD_EXIT
endif

# Find AFNI refacer shell (to replace subject face); this is a newer
# shell than original: this one is symmetric, without gaps in the
# skull, and more tightly bounded by -1s.
set mset = `@FindAfniDsetPath -full_path -append_file "${ref_shell}"`
if ( "${mset}" == '' ) then
    echo "** ERROR: Failed to find refacer shell ${ref_shell} -- exiting :("
    goto BAD_EXIT
endif

# need prefix
if ( "${impref}" == "" ) then
    echo "** ERROR: user needs to enter '-prefix ..' for output filename :("
    goto BAD_EXIT
else
    ### get base of output prefix
    # get rid of +orig.{HEAD,BRIK}, +orig
    set opref = `@GetAfniPrefix ${impref}` 
    # get rid of any .nii.gz, .nii
    set opref = `basename ${opref} .gz`
    set opref = `basename ${opref} .nii`    # final output prefix base

    set opref_qc = ${opref}_QC              # for auto images

    # make output dir and working dir
    set wdir0 = __work_refacer.${opref}.`3dnewid -fun11`
    set wdir  = ${odir}/${wdir0}
    \mkdir -p ${wdir}
endif

# cube length for cubeface
if ( ${lcube} <= 0 ) then
    echo "** ERROR: cube length must be >=0, not ${lcube}; fix '-cube_len ..'"
    goto BAD_EXIT
endif

# if we got to here:  good to continue.  Brag a bit first.
echo ""
echo "++ AFNI refacer, version      = ${version}"
echo "++ AFNI template dataset      = $Basedset"
echo "++ AFNI refacer shell dataset = $mset"
echo "++ Mode for running           = $run_mode"
echo ""

# ============================================================================
# prepare: get header info, and copy input to wdir

# get useful info from header
set vvv    = `3dinfo -space -av_space -nv -datum $iset`
set ispace = ${vvv[1]}    # space (ORIG, MNI, etc.)
set iview  = ${vvv[2]}    # AFNI view (+orig, +tlrc, etc.)
set nnn    = ${vvv[3]}    # number of vols (1, 2, 743, etc.)
set idatum = ${vvv[4]}    # datum (short, float, etc.)

# make temp directory, copy input dataset there
set dset_orig = tmp.00.INPUT.nii

if ( "$nnn" == "1" ) then
    3dcopy $iset ${wdir}/${dset_orig}
else
    3dcalc -a $iset'[0]' -expr a -prefix ${wdir}/${dset_orig}
endif

cd ${wdir}

# -----------------------------------------------------------------------
# do alignment

# Unifize input to a standard T1 image intensity

3dUnifize                         \
    -GM                           \
    -prefix tmp.01.uni.nii        \
    -ssave  tmp.01.uscale.nii     \
    ${dset_orig}

# Align to the MNI template - save only the transform matrix

3dAllineate         ${verb_allin}                                            \
    -base           $Basedset'[1]'                                           \
    -weight         $Basedset'[2]'                                           \
    -source         tmp.01.uni.nii                                           \
    -prefix         NULL                                                     \
    -warp           shift_rotate_scale                                       \
    -cost           ${cost_allin}                                            \
    -cmass                                                                   \
    -conv           0.5 -source_automask+4                                   \
    -fineblur       3                                                        \
    -norefinal                                                               \
    -twobest        3                                                        \
    -num_rtb        33                                                       \
    -1Dmatrix_save  tmp.02.mat_a2t.1D

# compute the inverse matrix, to transform from MNI back to orig space

cat_matvec                      \
    -ONELINE                    \
    tmp.02.mat_a2t.1D -I        \
    > tmp.03.mat_t2a.1D

# transform the refacer shell from MNI back to subject original space
# and grid

# [PT: Jan 23, 2020] Using NN interp is good here-- less/no gap
# outside shell than using linear
3dAllineate                                                                  \
    -1Dmatrix_apply  tmp.03.mat_t2a.1D                                       \
    -source          $mset                                                   \
    -final           NN                                                      \
    -prefix          tmp.04.sh_t2a.nii                                       \
    -master          ${dset_orig}                                            \
    -float

# create final version of shell in subject space.
# NB: -isola option removes isolated stuff that might be left around
3dcalc                                                                       \
    -a       tmp.04.sh_t2a.nii                                               \
    -expr    'a*bool(a)'                                                     \
    -isola                                                                   \
    -prefix  tmp.05.sh_t2a_thr.nii

# make sure shell's space matches that of input vol
3drefit -space ${ispace} tmp.05.sh_t2a_thr.nii

# -----------------------------------------------------------------------
# go through modes

# reface and reface_plus share some parts; use this var to avoid repetition
set DID_REFACE = 0

foreach mode ( ${run_mode} )
  if ( "${mode}" == "reface" || "${mode}" == "reface_plus" ) then
    # REFACE      : replace face+ears
    # REFACE_PLUS : replace face+ears+skull

    # specify subbrick of ref_shell to use, as well as shell label str
    if ( "${mode}" == "reface" ) then
        set subbr = 1
        set shell = "face"
    else if ( "${mode}" == "reface_plus" ) then
        set subbr = 0
        set shell = "face_plus"
    else
        echo "** ERROR: mode '${mode}' not allowed here."
        exit 1
    endif

    echo "++++ Proc for ${mode} with subbrick ${subbr} ('${shell}')"

    if ( ! $DID_REFACE ) then
        # scale factor for refacer shell to be about the same intensity as
        # the input:
        #   ibar = mean of input over refacer shell
        #   mbar = mean of refacer shell
        #   ifac = scale factor for refacer shell to match input (sort of)
        # This method doesn't allow for duplicating shading artifacts in
        # the input dataset, but that would be somewhat more work.

        # NB1: not using 'step(a-99)' anymore;
        # NB2: don't use single quotes in double-quoted 3dcalc part
        set ibar = `3dBrickStat -non-zero -mean \
                       "3dcalc( -a     tmp.05.sh_t2a_thr.nii[0]    \
                                -b     $dset_orig                  \
                                -expr  step(a)*b )"`
        set mbar = `3dBrickStat -non-zero -mean \
                       "3dcalc( -a     tmp.05.sh_t2a_thr.nii[0]    \
                                -expr  step(a)*a )"`
        # NB: not scaling by 1.222 anymore
        set ifac = `ccalc "1.000*${ibar}/${mbar}"`
    endif

    #   plop the scaled refacer shell 'c' on top of the input 'a':
    #   -- where the shell is positive = step(c)*c
    #   -- zero out anything where the shell is negative = iszero(c)*a
    #   -- since the master shell is negative in the outer volume,
    #      is zero in the 'brain' region, and is positive in the
    #      parts of the volume to be replaced.

    3dcalc                                                                   \
        -a       ${dset_orig}                                                \
        -c       tmp.05.sh_t2a_thr.nii"[${subbr}]"                           \
        -expr    "step(c)*c*${ifac}+iszero(c)*a*step(a)"                     \
        -prefix  tmp.06.${mode}.orig_mskd.nii                                \
        -datum   float -ISOLA

    3dcalc                                                                   \
        -a       tmp.05.sh_t2a_thr.nii"[${subbr}]"                           \
        -expr    'step(a)'                                                   \
        -datum   byte                                                        \
        -nscale                                                              \
        -prefix  tmp.07.${mode}.sh_t2a_thr_mskd.nii

    # create final output
    3dBlurInMask                                                             \
        -input     tmp.06.${mode}.orig_mskd.nii                              \
        -mask      tmp.07.${mode}.sh_t2a_thr_mskd.nii                        \
        -FWHM      2.666                                                     \
        -preserve                                                            \
        -prefix    tmp.99.result.${mode}.nii
  
    set DID_REFACE = 1

  else if ( "${mode}" == "deface" ) then
    # DEFACE: just remove the 'face' rather than replace it

    set subbr = 1 
    set shell = "face"

    echo "++++ Proc for ${mode} with subbrick ${subbr} ('${shell}')"

    3dcalc                                                                   \
        -a       ${dset_orig}                                                \
        -c       tmp.05.sh_t2a_thr.nii"[${subbr}]"                           \
        -expr    "a*not(bool(c))"                                            \
        -prefix  tmp.99.result.${mode}.nii                                   \
        -datum   float 
        -isola

  else if ( "${mode}" == "cubeface" ) then
    # CUBEFACE: replace face with Cubist averages

    set subbr = 1 
    set shell = "face"

    echo "++++ Proc for ${mode} with subbrick ${subbr} ('${shell}')"

    # figure out edge lengths for making ROI map
    set dim = `3dinfo -n4 tmp.05.sh_t2a_thr.nii`
    foreach ii ( `seq 1 1 3` )
        # integer division
        set edge[$ii] = `ccalc -i -eval "int((${dim[$ii]} - 1) / ${lcube}) + 1"`
    end

    echo "++ CUBE: ${lcube}"
    echo "++ DIM : ${dim[1-3]}"
    echo "++ EDGE: ${edge}"

    # make the cubist ROI map
    3dcalc                                                                   \
        -overwrite                                                           \
        -a          tmp.05.sh_t2a_thr.nii"[1]"                               \
        -expr       "bool(a)*(int(i/${lcube}) + ${edge[1]}*int(j/${lcube}) \
                     + ${edge[1]}*${edge[2]}*int(k/${lcube}))"               \
        -prefix     tmp.11.cube.nii                                          \
        -datum      float                                                    \
        -nscale

    # make the text file of info for ROI_label -> ROI_value mapping
    # ... first as 2 rows:
    3dROIstats                                                               \
        -quiet                                                               \
        -mask          tmp.11.cube.nii                                       \
        -float_format  '%.0f'                                                \
        tmp.11.cube.nii                                                      \
        > tmp.12.mapping_row.1D
    3dROIstats                                                               \
        -quiet                                                               \
        -mask          tmp.11.cube.nii                                       \
        -float_format  '%f'                                                  \
        tmp.00.INPUT.nii                                                     \
        >> tmp.12.mapping_row.1D

    # ... and then as 2 cols:
    1dtranspose -overwrite tmp.12.mapping_row.1D tmp.13.mapping_col.1D 

    # map average values into place in cubes
    3dExchange                                                               \
        -overwrite                                                           \
        -input      tmp.11.cube.nii                                          \
        -map        tmp.13.mapping_col.1D                                    \
        -prefix     tmp.14.cube_mapped.nii

    # finally, put together the mapped cubes and original data 
    3dcalc                                                                   \
        -overwrite                                                           \
        -a          tmp.00.INPUT.nii                                         \
        -b          tmp.14.cube_mapped.nii                                   \
        -expr       'b + not(b)*a'                                           \
        -prefix     tmp.99.result.${mode}.nii                                \
        -datum      float

  else 
    echo "** ERROR: unknown mode '${mode}' in loop"
    exit -1
  endif

  # -------------------------- act on each result --------------------------

  # ----- short-ize result, if relevant and practicable

  if ( "${idatum}" == "short" ) then
    set rr  = tmp.99.result.${mode}.nii

    set mmm = `3dBrickStat -max ${rr}`
    @   mmm = `ccalc -int $mmm`

    if ( $mmm < 32000 ) then
        \mv ${rr} tmp.80.nonshort.${mode}.nii

        3dcalc                                                       \
            -a       tmp.80.nonshort.${mode}.nii                     \
            -expr    a                                               \
            -prefix  ${rr}                                           \
            -datum   short                                           \
            -nscale

        \rm tmp.80.nonshort.${mode}.nii
    endif
  endif

  # ----- make output copy

  if ( ${DO_ANON} ) then 
    @djunct_anonymize ${owrite}                        \
        -input     tmp.99.result.${mode}.nii           \
        -copy_to   ../${opref}.${mode}.nii.gz          \
        -add_note  "afni_refacer2 created this file"
  else
    3dcopy -echo_edu ${owrite}                         \
        tmp.99.result.${mode}.nii                      \
        ../${opref}.${mode}.nii.gz
  endif

  # ----- make purdy QC images: input as ulay, re/defaced vol as olay

  if ( ${DO_CHAUFF} ) then
    @chauffeur_afni                                                      \
        -ulay                ${dset_orig}                                \
        -ulay_range          "2%" "98%"                                  \
        -olay                ../${opref}.${mode}.nii.gz                  \
        -func_range_perc_nz  95                                          \
        -cbar                "Plasma"                                    \
        -pbar_posonly                                                    \
        -opacity             9                                           \
        -prefix              ../${opref_qc}/${opref}.${mode}             \
        -montx               5                                           \
        -monty               3                                           \
        -montgap             3                                           \
        -set_xhairs          OFF                                         \
        -label_mode          1                                           \
        -label_size          4
  endif

  # output face/face_plus dsets, as well as mask images of each
  if ( ! -f tmp.90.mask_shell_${shell}.nii ) then

    # output face/face_plus dset
    3dcalc         ${owrite}                                                 \
        -a         tmp.05.sh_t2a_thr.nii"[${subbr}]"                         \
        -expr      'a'                                                       \
        -prefix    ../${opref}.${shell}.nii.gz

    if ( ${DO_ANON} ) then
        @djunct_anonymize                                                    \
            -input     ../${opref}.${shell}.nii.gz                           \
            -add_note  "afni_refacer2 created this file"
    endif 

    # mask for QC images
    3dcalc                                                                   \
        -overwrite                                                           \
        -a         tmp.05.sh_t2a_thr.nii"[${subbr}]"                         \
        -expr      'bool(a)'                                                 \
        -prefix    tmp.90.mask_shell_${shell}.nii

    if ( ${DO_CHAUFF} ) then
        @chauffeur_afni                                                      \
            -ulay                ${dset_orig}                                \
            -ulay_range          "2%" "98%"                                  \
            -olay                tmp.90.mask_shell_${shell}.nii              \
            -pbar_posonly                                                    \
            -func_range_perc_nz  1                                           \
            -cbar                "Reds_and_Blues_Inv"                        \
            -opacity             4                                           \
            -prefix              ../${opref_qc}/${opref}.${shell}            \
            -montx               5                                           \
            -monty               3                                           \
            -montgap             3                                           \
            -set_xhairs          OFF                                         \
            -label_mode          1                                           \
            -label_size          4
    endif
  endif

end  ### end of loop over all modes

# --------------------------------------------------------------------------
# final steps

cd ..

# trash the junk, vamoose the ranch

if ( $DO_CLEAN ) then
    \rm -rf ${wdir0}
endif

echo "\n++ Done.\n"

exit 0


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

SHOW_VERSION:

    echo "$version"

    goto GOOD_EXIT

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

SHOW_HELP:

cat <<EOF

OVERVIEW ~1~

This script re-faces or defaces one input dataset, using a reference
shell dataset (which is mapped from template space) to write over the
subject's 'face' region. The main input is the name of a T1-weighted
dataset.

This can be an important step in anonymizing anatomical datasets.

For an independent comparison of methods that demonstrates the strong
performance of this defacing/refacing program, see:

  Multisite Comparison of MRI Defacing Software Across Multiple Cohorts
    by Theyers et al. (2021)
  https://pmc.ncbi.nlm.nih.gov/articles/PMC7943842/

ver = ${version}

Author   - The Face of Imperial Zhark, Who is Terrible to Behold!
Modifier - PA Taylor

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

USAGE ~1~

  afni_refacer2                                                  \
    -input  DSET                                                \
    -mode_{reface|reface_plus|deface|all}                       \
    -mode2_{cubeface|all}                                       \
    -prefix PPP                                                 \
    {-anonymize_output}                                         \
    {-cost CC}                                                  \
    {-overwrite}                                                \
    {-no_clean}                                                 \
    {-no_images}                                                \
    {-echo}                                                     \
    {-verb_allin}      

where:

 -input DSET  : (req) name of input dset; can contain path information.

 -prefix PPP  : (req) name of output dset (see NOTES for info about
                about file names, particularly when "-mode_all" is used).

     ... and at least one '-mode*' option MUST be chosen (any
     combination of these can be used; the union of modes will be
     output):

 -mode_deface : replace the computed face+ears voxels with all zeros
                instead of the artificial face (ears are also removed)
 -mode_reface : replace the subject's face+ears with a scaled set of
                artificial values
 -mode_reface_plus : replace the subject's face+ears+skull with a scaled
                set of artificial values (i.e., like 'refacing', but
                replacing a more complete shell around the subject's
                brain)
 -mode_all    : output three face-replaced volumes: one defaced, one 
                refaced, and one reface_plused

 -mode2_cubeface : replace the subject's face+ears with values averaged
                across large cubes (see -cube_len, for controlling cube 
                size)
                NB: this mode is NOT generally recommended; it exists
                primarily for testing/using within training a
                skullstripping program, simply because we saw it
                existed in The Wild.
 -mode2_all :   output all the other '-mode2_* cases, which are not 
                included in '-mode_all'
                NB: the '-mode2_*' cases are not recommended for general
                use, but instead exist for other special use cases

 -anonymize_output : (opt) use 3drefit and nifti_tool to anonymize the
                output dsets.  **But always verify anonymization
                yourself, Dear User.** This option will not be able to help
                you if you choose a non-anonymizing output file name,
                for example.

 -cost CC     : (opt) can specify any cost function that is allowed by 
                3dAllineate (def: ${cost_allin})
 
 -ref_shell RS : (opt) can specify which shell to use.  At present, the 
                available options for SH are:
                  afni_refacer_shell_sym_1.1.nii.gz  (earlier, shorter version)
                  afni_refacer_shell_sym_2.1.nii.gz  (remove more face/neck/ear)
                See NOTES about specific reference shell version numbers.
                (def: ${ref_shell})

 -ref_dset RD  : (opt) specify the reference template used, which must be
                consistent with the shell being used. 
                See NOTES about specific reference datasets and partnering
                with reference shells.
                (def: ${ref_dset})

 -cube_len CL : (opt) when using "cubeface"-style refacing, users can control
                the number voxels along a cubeface side with this number; must
                be greater than 0 (def: ${lcube})
                
 -no_clean    : (opt) don't delete temp working dir (def: remove working
                dir)

 -no_images   : (opt) don't make pretty images to automatically view the 
                results of re/defacing;  but why wouldn't you want those?
                This disables use of Xvfb.

 -overwrite   : (opt) final two file outputs will overwrite any existing
                files of the same name (def: don't do this).  NB: this 
                option does not apply to the working directory

 -echo        : (opt) run program very verbosely, echoing each command before
                executing it; likely only for debugging

 -verb_allin  : (opt) run the 3dAllineate part herein with '-verb' (for
                verbosity)

 -help        : see helpfile (here, in fact)
 -hview       : popup help

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

NOTES ~1~

Modes for running ~2~

There are different modes available for defacing/refacing.  Users can
pick and choose which one(s) they want from an available list. 

When running with '-mode_all', then 5 datasets will be output, all in
the same space as the input volume:

  + Three versions of the input anatomical with refacing/defacing, which 
    we consider a reasonable/mainstream way of hiding the original face:
    1) a "defaced" volume (face+ears replaced with zeros)
    2) a "refaced" volume (face+ears replaced with artificial values) 
    3) a "reface_plus"ed volume (face+ears+skull replaced with artificial
       values)

  + Two volumes of just the face-replacing datasets, for reference:
    4) the face+ears used to replace or remove subject data
    5) the face+ears+skull used to replace subject data

Note that there are other methods of defacing/refacing.  While these
are not very common, they are available here (if for no other reason
than we have tested them and used them in other applications).  These
mode(s) can also be run individually or as a group.  These are not
included in the '-mode_all' output, but can be run with
'-mode_all_extras' or the individual names.  At present, these are:

    A) a "cubefaced" volume (face+ears replaced with average across
       big cubes)

In all cases, automatic images of the re/defaced volume(s) will be
created with @chauffeur_afni, so the user can quickly evaluate results
visually.

A temporary working directory is also created.  This will be cleaned
(=deleted) by default, but the user can choose to save it.

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

Output file names ~2~

If the user implements one of the individual modes for refacing,
reface_plusing or defacing, then the main output file of interest is
simply specified by their "-prefix .." choice.  Additionally, the
replacement volume in subject space will be output, with the same name
plus a suffix (either 'face' or 'face_plus').

If the user instead implements '-mode_all', then three output volumes
are created, each with the same prefix specified by their "-prefix .."
choice, with identifying suffixes and *.nii.gz extensions:
    PREFIX.deface.nii.gz 
    PREFIX.reface.nii.gz
    PREFIX.reface_plus.nii.gz
Additionally, both replacement volumes will be output, having the
same prefix and relevant suffix:
    PREFIX.face.nii.gz 
    PREFIX.face_plus.nii.gz 

Finally, there is another set of less-common modes available, which
can be output with '-mode_all_extras'.  These might be primarily
useful for testing or other applications, and includes:
    PREFIX.cubeface.nii.gz

A directory of QC images will be made by default, called:
    PREFIX_QC/
This will contain images of each of the new anatomical volumes and the
replacement volumes over the original anatomical.

Requisite data sets ~2~

This script relies on having datasets that should already be included
with AFNI binaries:

    MNI152_2009_template_SSW.nii.gz  = MNI skull strip/warp template
    afni_refacer_shell_sym_*.nii.gz  = dataset to replace face region

The latter dataset(s) have been made by a combination of the
@afni_refacer_make_master and @afni_refacer_make_master_addendum2 
scripts.

If you are missing these datasets for some reason (e.g., you build
your own AFNI binaries on your computer), you can download these from
the current/atlases directory.  Or just ask for more info on the
Message Board.

Reference shells and template datasets ~2~

Different degrees of face-hiding have been preferred over time.
Typically, it is recommended to remove more face (and ears) nowadays.

The default masks here will do that.

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

EXAMPLES ~1~

1) deface (= replace face+ears with zeros)

    afni_refacer2                                           \
        -input        anat+orig.HEAD                        \
        -mode_deface                                        \
        -prefix       anat_deface.nii.gz

2) reface (= replace face+ears with generic face)

    afni_refacer2                                           \
        -input        anat.nii.gz                           \
        -mode_reface                                        \
        -prefix       anat_reface.nii.gz

3) reface plus (= reface a larger area, including skull region)

    afni_refacer2                                           \
        -input             anat.nii.gz                      \
        -mode_reface_plus                                   \
        -prefix            anat_reface_plus.nii.gz
    
4) ALL = output all versions of vol: refaced, reface_plused, defaced

    afni_refacer2                                           \
        -input     anat.nii.gz                              \
        -mode_all                                           \
        -prefix    anat

5) ... and using different shell for replacement:

    afni_refacer2                                           \
        -input     anat+orig.                               \
        -mode_all                                           \
        -ref_shell afni_refacer_shell_sym_1.1.nii.gz        \
        -prefix    anat

EOF

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

FAIL_MISSING_ARG:
   echo "** missing parameter for option $argv[$ac]"
   goto BAD_EXIT

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

BAD_EXIT:
    exit 1

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

GOOD_EXIT:
    exit 0
