#!/bin/tcsh

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

# Nomenclature note. We have multiple spaces, with the following abbrevs:
# + orig : original input dset space
# + osh  : shifted version of original dset (by @Align_Centers)
# + aff  : affine-aligned version of original dset (by align_epi_anat.py)
# + base : 'template' space, and/or NL warped version of original dset

# On a historical note, this script is derived from macaque_align.csh
# and NMT_subject_align.csh, scripts distributed with the D99 macaque
# and the NMT macaque template datasets and tools.

# affine alignment of individual dataset to a template
#  handcrafted for macaque alignment originally - D99 and NMT templates
# usage example:
#     @animal_warper  -input macaque1+orig \
#	      -base ../NMT.nii.gz 				\
#	      -atlas ${atlas_dir}/D99_atlas_1.2a_al2NMT.nii.gz
# see help section at end for options
# derived from macaque_align.csh and NMT_align.csh, scripts distributed
#  with the D99 macaque and the NMT macaque template datasets and tools

set progname = @animal_warper

# --------------------- version history with changes -----------------------
#
#set version = "1.00"
#
#set version = "1.02" ; set date = "Sep 3, 2019"
# [PT] Adding in @chauffeur_afni commands for visualization
#    + snapshots commented out
#    + cp -> \cp, etc.
#
#set version = "1.1" ; set date = "Sep 3, 2019"
# [PT] Make a "no skull" version of the orig dset
#    + another QC image: skull stripped area
#
#set version = "1.2" ; set date = "Sep 5, 2019"
# [PT] change smoothing of SUMA stuff, preserve ROIs more
#    + trivial stuff: change spacing / break lines for readability (sorry!)
#
#set version = "1.3" ; set date = "Sep 6, 2019"
# [PT] QC order rearranged a bit; change names; more useful focus (foci)
#    + QC to sep dir, called QC
#
#set version = "1.4" ; set date = "Sep 6, 2019"
# [PT] output dset that is wrpd2std, and skullstrip it with template
#      -> this is what would be useful to pass to AP
#
#set version = "1.5" ; set date = "Sep 10, 2019"
# [PT] unifize skullstripped template in standard template space
#    + describe QC images in help file, for reference
#    + remove __tmp* dset-- hadn't noticed COMPRESSOR was ON
#
#set version = "1.6" ; set date = "Sep 11, 2019"
# [DRG] remove temporary datasets with option to keep temporary datasets
#     + identify important output
#     + some help updates
#
#set version = "1.7" ; set date = "Sep 24, 2019"
# [DRG] fullpath for input datasets determined even if specified as ., .., ~
#
#set version = "1.71" ; set date = "Oct 3, 2019"
# [PT] Adjust 3dNotes to include @animal_warper name
#    + this goes with adjusting gen_ss_review_table.py so it recognizes
#      and reads in the template name
#    + make $animal_outs almost lined up?
#
#set version = "1.72" ; set date = "Oct 7, 2019"
# [PT] $animal_outs descriptors more consistent
#    + add in prog version numbers to animal_outs scripts
#    + goes with change in afni.c to have simpler AFNI version
#      number/package
#    + help now exits with 0
#
#set version = "1.73" ; set date = "Jan 14, 2020"
# [PT] update text output in @animal_outs a bit
#
#set version = "1.74" ; set date = "Feb 14, 2020"
# [DRG] dset_followers to allow for similar space datasets to follow 
#       into template space. Uses Align_Centers 1D dataset for initial
#       shifts 
#set version = "1.75" ; set date = "Feb 26, 2020"
# [DRG] roidset_followers to allow for similar space datasets to follow 
#       into template space with nearest neighbor interpolation 
#       +modal smoothing.
#set version = "1.76" ; set date = "Mar 22, 2020"
# [DRG] fixed stupid bug, space in feature_size option for aea.py
#set version = "1.77" ; set date = "Mar 26, 2020"
# [DRG] changed center shift defaults and help for dealing with shifts
#       concatenating shift with affine alignment by default option 
#
#set version = "1.78" ; set date = "Mar 29, 2020"
# [BTJ] added template mask-based brainmasking
# maxlev defaults to 9 for some increase in speed
#
#set version = "1.8" ; set date = "Apr 27, 2020"
# [PT] add help file example of integrating with afni_proc.py
#    + particularly important now to get correct aff12 mat
#
#set version = "1.81" ; set date = "May 14, 2020"
# [PT] change spacing and printing for ease of reading
#    + remove '-segmentation' opt, which didn't appear to do anything
#    + clean up comments
#    + introduce 'adjunct_simplify_cost.py' to get rid of +ZZ, +zz and +
#
#set version = "1.82" ; set date = "May 14, 2020"
# [PT] more readability changes
#
#set version = "1.83" ; set date = "May 14, 2020"
# [PT] more readability changes
#
#set version = "1.9" ; set date = "May 14, 2020"
# [PT] make '-atlas ..' accept a list of dsets
#    + new opt "-atlas_followers .." to have same behavior as '-atlas ..'
#
#set version = "1.91" ; set date = "May 15, 2020"
# [PT] continuing lots of updates, rearrangements, labelings
#
#set version = "1.92" ; set date = "May 15, 2020"
# [PT] shifts done more similarly
#    + surfacizing
#
#set version = "1.93" ; set date = "May 15, 2020"
# [PT] changing the way output atlas names and template abbrevs are done
#    + simplify help parsing for reporting missing params for opts
#
#set version = "1.94" ; set date = "May 16, 2020"
# [PT] simplify what to do with existing animal_outs.txt: 
#      + just make copy/backup
#
#set version = "1.95" ; set date = "May 16, 2020"
# [PT] base2osh, osh2base nomenclature
#    + backup notice of prior/backup animal_outs.txt
#    + reordered calcs, so animal_outs is more logically ordered, too
#    + for each follower, now there is an optional abbrev list
#    + update 3dUnifize to be more like @SSwarper's
#
#set version = "1.96" ; set date = "May 17, 2020"
# [PT] finally doing abbrevs
#    + abbrevs will be lists, and treated analogously for all
#      followers, to hopefully make code logic easier, by being
#      consistent and sorted out in a single place. HOPEFULLY.
#
#set version = "1.97" ; set date = "May 17, 2020"
# [PT] use more consistent naming, bc otherwise 'template' and 'dset' 
#      refer to many things-- both the required inputs, as well as 
#      follower types
#    + all '-base BASE' references  -> "${base_dset}"
#    + all '-input DSET' references -> "${src_dset0}" original/uncopied
#                                      "${src_dset}"  copied into outdir
#    + all shifted src references   -> "${srcsh_dset}"  
#    + as observable from above got rid of renaming of:
#           set dset = ${dset}_shft
#      - as part of this, don't need separate 'finalmaster' anymore
#
#set version = "1.97" ; set date = "May 17, 2020"
# [PT] do*.tcsh script to open surfaces in SUMA
#    + fix cleanup 'rm ..' commands
#
#set version = "1.98" ; set date = "May 17, 2020"
# [PT] completed testing with multiple inputs/etc.
#    + updated help file
#
#set version = "1.99" ; set date = "May 18, 2020"
# [PT] create skullstripped+unifized dset in orig space
#
#set version = "2.0" ; set date = "May 18, 2020"
# [PT] final adjustments
#
#set version = "2.01" ; set date = "May 19, 2020"
# [PT] use NSU in do_view_${surf_dir}.tcsh
#
#set version = "2.1" ; set date = "May 19, 2020"
# [PT] new adjunct* functionality: create table of ROI info
#    + done using: adjunct_aw_tableize_roi_info.py
#      - someday, might make this program more 'standalone' with real opts
#
#set version = "2.11" ; set date = "May 21, 2020"
# [PT] report mode_smooth_size in report*1D file
#
#set version = "2.2" ; set date = "May 30, 2020"
# [PT] 
#    + modal smoothing with replacement, now default; is new opt to turn off
#    + now, for multibrick ATL|SEG dsets, each subbrick will be snapshotted
#      for QC dir
#
#set version = "2.21" ; set date = "May 30, 2020"
# [PT] 
#    + change how input_abbrev gets applied-- will apply to copying
#      and earliest transformed input/src dsets now, for
#      simplicity/ease of reading if user is defining an inp abbr
#
#set version = "2.3" ; set date = "May 31, 2020"
# [PT] 2 bug fixes
#    + one in defining ${src_prefix} (reorder to not have error)
#    + one in passing along labels/atlases from SEG|atlas dsets
#
#set version = "2.4" ; set date = "Jul 10, 2020"
# [DRG]
#    + changed default mode_smooth_size to 1 voxel
#
#set version = "2.41" ; set date = "Aug 26, 2020"
# [PT] fix location of jump-to-help when no args are input
#    + was getting error message, because ${outdir} needed to be def
#
#set version = "2.5" ; set date = "Aug 26, 2020"
# [PT] add opts to turn @Align_Centers OFF or to use
#      "-cm", etc. 
#
#set version = "2.51" ; set date = "Aug 27, 2020"
# [PT] put specific space name for *base2osh* and *osh2base* dsets
#    
#set version = "2.6" ; set date = "Aug 27, 2020"
# [PT] put in 2nd shift-- well, it is a rearrangement: we combine the
#      @Align_Centers shift with the translation part of 3dAllineate
#    + and debugged a bit-- seems to run fine now
#    + NOTE: the shifts from @Align_Centers now go with the "*_pshft*"
#      files, and the "full" shift from combining the @Align_Center
#      work with the translation from align_epi_anat.py are the
#      "*_shft*" datasets, so there should be full continuity with the
#      help files and with the reported afni_proc.py usage.
#    
#set version = "2.7" ; set date = "Oct 16, 2020"
# [PT] instead of early 3dcalc of src_dset0 to start things off, use
# 3dresample there; with the concatenation of translations
# (pshft+shft), we want to have (x,y,z) ordering of coords for the src
# dset, and this ensures it.  Otherwise, get badness of something with
# orient RSP, AIL, etc. is entered.
#    
#set version = "2.8" ; set date = "Oct 16, 2020"
# [PT] add status checks around, to stop in case of intermediate
#      failure
#    
#set version = "2.9" ; set date = "Oct 16, 2020"
# [PT] Phase I of restructuring output and simplifying output dir
#    + reports*.1D   -> QC/ 
#    + surface_*     -> surfaces/
#    + do_view*.tcsh -> surfaces/
#    + animal_outs*txt is updated accordingly
#    ---> many thanks to B Jung for guidance+suggestions on this!
#    
#set version = "2.91" ; set date = "Oct 16, 2020"
# [PT] Phase II of restructuring output and simplifying output dir
#    + runs through "affine" part at the moment-- need to keep
#      adjusting files afterward to continue consistency
#    ---> many thanks to B Jung for guidance+suggestions on this!
#
#set version = "2.92" ; set date = "Oct 19, 2020"
# [PT] Phase III of restructuring output and simplifying output dir
#    ---> STILL many thanks to B Jung for guidance+suggestions on this!
#
#set version = "2.93" ; set date = "Oct 19, 2020"
# [PT] verifying/testing in Mac demos
#
#set version = "3.0" ; set date = "Oct 19, 2020"
# [PT] updating help file -- more useful?
#
#set version = "3.01" ; set date = "Oct 19, 2020"
# [PT] new "pre"-QC: check src-base overlap: @djunct_overlap_check
# 
#set version = "3.1" ; set date = "Dec 22, 2020"
# [PT] new feature size default: 0.5 (old default: empty)
# 
#set version = "3.2" ; set date = "Feb 3, 2021"
# [PT] add snapshot of aff, intermed qc
#    + pass along set echo to at least some subscript(s)
# 
#set version = "3.3" ; set date = "Feb 25, 2021"
# [PT] the rigid, rigid_equiv and affine align_types now go all the
#      way through the full processing, warping dsets, etc.  This
#      functionality changed for Adam Messinger.
#    + NL alignment is unchanged
#    + record align_type in animal_outs.txt
#    + fixed bug in 3drefitting a 'dset_follower' as if it were int-valued
# 
#set version = "3.31" ; set date = "Mar 1, 2021"
# [PT] fix location of affine align init*jpg
#
#set version = "3.32" ; set date = "Apr 6, 2021"
# [something lost in the mists of time. or github]
#
#set version = "3.33" ; set date = "May 17, 2021"
# [DRG] fix oneline output for rigid_equiv matrix
# 
#set version = "3.34" ; set date = "May 20, 2021"
# [PT] update help examples and citations
#    + add in more init_qc* images to track progress @djunct_overlap_check
#    + change dset used to mask warp2std_ns dset---thanks, A Messinger!
#    + dump out a log_cmd.txt file immediately, in case of crash
#
#set version = "3.35" ; set date = "May 21, 2021"
# [PT] new animal_ints file (guide to intermediate files, sep from main one)
#      - gets made in ${imed} dir
#    + myriad small description changes in animal_outs, to simplify or
#      clarify (ha, right!)
#
#set version = "3.36" ; set date = "May 21, 2021"
# [PT] update init_qc* filenames, simplify, and put help desc
#    + ... and fix output location
#    + use log to record time info of start/stop
#
#set version = "3.37" ; set date = "May 24, 2021"
# [PT] lower opacity in overlap check
#
#set version = "3.38" ; set date = "July 9, 2021"
# [PT] Couple useful things:
#    + new '-aff_move_opt ..' opt: control affine align behavior
#      - necessary if coords are good and there is a lot of non-brain 
#        in FOV
#      - NB: all aff output dsets will be on BASE grid, too.
#    + fix bug: if no followers used, no 'surfaces/' dir was created
#      for orig surface brain.  Now OK.
#
#set version   = "3.39";   set rev_dat   = "Sep 27, 2021"
#     + [PT] chauffeur label_size 3 -> 4, bc imseq.c shifted all sizes
#       down one level
#
#set version   = "3.40";   set rev_dat   = "Oct 21, 2021"
#     + [PT] help examples were missing "-outdir .." arg.  Now provided
#
#set version   = "3.41";   set rev_dat   = "Oct 23, 2021"
#     + [PT] make ROI_glasbey_2048 the colorbar for @chauffeur_afni
#            ROI images
#          + CHARM requires something >256, and other ones will, too
#
#set version   = "3.5";   set rev_dat   = "Oct 24, 2021"
#     + [PT] improve QC outputs
#          - use @djunct_edgy_olay to show alignment quality for qc_0{0,1}*
#          - improve/simplify/separate naming structure of QC images
#          - remove unnecessary pbar output for mask olay
#          - add src_abbrev to output QC names, if present, kind of like
#            having ${subj} (which we don't have available as input)
#          - make variable names for QC prefixes at top, so the help
#            automatically reflects them
#          - make glasbey_ROIs a bit more opaque (hard to see otherwise)
#
#set version   = "3.51";   set rev_dat   = "Oct 24, 2021"
#     + [PT] fix some chauffeur ranges
#          + change Urad in 3dUnifize to 14, from 30 (latter seems 
#            waaaay too large for most animal dsets?)
#   
#set version   = "3.52";   set rev_dat   = "Oct 27, 2021"
#     + [PT] fix desc of opt name "-qw_opts" in help to what it actually is:
#            "-extra_qw_opts".  Thanks, C Garin.
#   
#set version   = "3.6";   set rev_dat   = "Dec 1, 2022"
#     + [PT] new opt '-init_scale ..' for pre-scaling input anatomical if
#            it is much smaller/larger than the template (applied in AEA)
#   
#set version   = "3.61";   set rev_dat   = "Dec 2, 2022"
#     + [PT] add QC image when using '-init_scale ..'
#   
set version   = "4.00";   set rev_dat   = "Aug 6, 2024"
#     + [PT, DRG] fix application of shift shifting.
#   
# --------------------------------------------------------------------
# --------------------------------------------------------------------

setenv AFNI_COMPRESSOR GZIP

set here               = "${PWD}"

set src_dset0          = ""       # actual input 
set src_dset           = ""       # copied src in outdir; used in proc
set base_dset          = ""

set src_abbrev         = ""
set src_add            = ""
set base_abbrev        = ""
set USE_KNOWN_BASE_ABBREV = 0  # will use ${all_known_template_abbrev}

set outdir             = "aw_results"
set imed               = "intermediate"   # intermed files; ~purgeable
set center_out         = "native"

set brainmask          = ""

set cost               = ""
set maxlev             = "09"
set make_orig_surfaces = "1"
set align_type         = "all"
set ok_to_exist        = "0"
set extra_qw_opts      = ""
set aff_move           = "-giant_move"

# one-to-one correspondence between followers and abbrevs
set atlas_followers      = () ; set atlas_abbrevs    = ()
set template_followers   = () ; set template_abbrevs = ()
set seg_followers        = () ; set seg_abbrevs      = ()
set dset_followers       = () ; set dset_abbrevs     = ()
set roidset_followers    = () ; set roidset_abbrevs  = ()
# these start in base space
set USE_KNOWN_ATLAS_ABBREV = 0
set all_known_atlas_abbrev = ( "D99" "CHARM" )
set USE_KNOWN_TEMPLATE_ABBREV = 0
set all_known_template_abbrev = ( "NMT" )
set USE_KNOWN_SEG_ABBREV = 0
set all_known_seg_abbrev = ( )
# these start in input dset space
set USE_KNOWN_ROIDSET_ABBREV = 0
set all_known_roidset_abbrev = ( )
set USE_KNOWN_DSET_ABBREV = 0
set all_known_dset_abbrev = ( )

set DO_ALIGN_CENTERS   = 1
set align_centers_meth = "-grid" 

set DO_INIT_SCALE      = 0           # [PT: Dec 1, 2022] overcome size mismatch
set init_scale         = 1.0
set opt_init_scale     = ""

set feature_size       = "0.5"       # [PT: Dec 22, 2020] new default
set feature_option     = "-feature_size $feature_size"
set modesmooth         = "1"   # 1 voxel modal smoothing
set DO_MODE_SMOO_W_REP = 1     # use modal smoothing with rep (def)
set supersize          = ""
set keep_temp          = ""

set animal_outs        = "animal_outs.txt"         # recreated, even with exist
set animal_ints        = "${imed}/guide_to_ints.txt"  # guide to intermediate 
set backup_ao          = ""

set DO_ECHO            = ""

# put all QC/ image prefixes here, so we refer more easily to them in help
set iqc00  = init_qc_00.input+base
set iqc01  = init_qc_01.input_sh+base
set iqc01b = init_qc_01.input_sh_scale+base      # if init scaling is used
set iqc02  = init_qc_02.input_aff+base
set iqc03  = init_qc_03.input_NL+base

set qc00  = qc_00.wrpd_input+base
set qc01  = qc_01.input+wrpd_base
set qc02  = qc_02.input+mask
set qc03  = qc_03.input+wrpd

# ------------------------ process user options --------------------------

# [PT: Oct 7, 2019] changed condition from ("$#" < "2"), so that args
# get parsed and we can still get at script version number
# [PT: Aug 26, 2020] moved this here, because it needs to be after
# ${outdir} is defined, or an error is caused when trying to show help
if ("$#" <  "1") then
   goto HELP
endif

set ac = 1
while ($ac <= $#argv)
    if ("$argv[$ac]" == "-help" || "$argv[$ac]" == "-h") then
        goto HELP

    else if ("$argv[$ac]" == "-ver") then
        echo $version
        exit 0

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

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

    else if ("$argv[$ac]" == "-input") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set src_dset0 =  $argv[$ac]

    # User can specify simpler name for this dset for output fnames
    else if ("$argv[$ac]" == "-input_abbrev") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set src_abbrev = $argv[$ac] 

    else if ("$argv[$ac]" == "-base") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set base_dset =  $argv[$ac]

    # User can specify simpler name for this dset for output fnames
    else if ("$argv[$ac]" == "-base_abbrev") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set base_abbrev = $argv[$ac]

    else if ("$argv[$ac]" == "-outdir") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set outdir =  $argv[$ac]

    else if ("$argv[$ac]" == "-cost") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set cost =  $argv[$ac]

    #### [PT: May 17, 2020] remove for '-abbrev_base'-- matches other
    #### input names/opts better
    #else if ("$argv[$ac]" == "-template_prefix") then
    #    set this_opt = "$argv[$ac]"
    #    @ ac ++
    #    if ( $ac > $#argv ) then
    #        echo "** missing parameter for option '${this_opt}'"
    #        exit 1
    #    endif
    #    set templatename =  $argv[$ac]

    else if ("$argv[$ac]" == "-use_known_abbrev_base") then
        set USE_KNOWN_BASE_ABBREV = 1

    else if ("$argv[$ac]" == "-use_known_abbrev_atlas") then
        set USE_KNOWN_ATLAS_ABBREV = 1

    else if ("$argv[$ac]" == "-use_known_abbrev_template") then
        set USE_KNOWN_TEMPLATE_ABBREV = 1

    else if ("$argv[$ac]" == "-use_known_abbrev_seg") then
        set USE_KNOWN_SEG_ABBREV = 1

    else if ("$argv[$ac]" == "-use_known_abbrev_dset") then
        set USE_KNOWN_DSET_ABBREV = 1

    else if ("$argv[$ac]" == "-use_known_abbrev_roidset") then
        set USE_KNOWN_ROIDSET_ABBREV = 1

    else if ("$argv[$ac]" == "-use_known_abbrev_ALL") then
        set USE_KNOWN_BASE_ABBREV     = 1
        set USE_KNOWN_ATLAS_ABBREV    = 1
        set USE_KNOWN_TEMPLATE_ABBREV = 1
        set USE_KNOWN_SEG_ABBREV      = 1
        set USE_KNOWN_DSET_ABBREV     = 1
        set USE_KNOWN_ROIDSET_ABBREV  = 1

    else if ("$argv[$ac]" == "-align_centers_meth") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif

        set ac_opt = "$argv[$ac]"

        if ( "${ac_opt}" == "OFF" ) then
            set DO_ALIGN_CENTERS = 0
        else
            set align_centers_meth = "-${ac_opt}"
            
            if ( "${ac_opt}" == "shift_xform" || \
                 "${ac_opt}" == "shift_xform_inv" ) then
                @ ac ++
                if ( $ac > $#argv ) then
                    echo "** missing parameter for option '${this_opt}'"
                    echo "   because you need another arg after '${ac_opt}'"
                    exit 1
                endif

                set align_centers_meth = "${align_centers_meth} $argv[$ac]" 
            endif
        endif

    # [PT: July 8, 2021] be able to control main affine opts for move
    else if ("$argv[$ac]" == "-aff_move_opt") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif

        set aaa = "$argv[$ac]"

        if ( "${aaa}" == "OFF" ) then
            set aff_move = ""
        else
            set aff_move = "-${aaa}"
        endif

    else if ("$argv[$ac]" == "-skullstrip") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set brainmask =  $argv[$ac]

    else if ("$argv[$ac]" == "-maxlev") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set maxlev =  $argv[$ac]

    else if ("$argv[$ac]" == "-init_scale") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set init_scale    = $argv[$ac]
        set DO_INIT_SCALE = 1

    else if ("$argv[$ac]" == "-align_type") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set align_type =  $argv[$ac]
        if (( "$align_type" == "all" )         || \
            ( "$align_type" == "rigid" )       || \
            ( "$align_type" == "rigid_equiv" ) || \
            ( "$align_type" == "affine" )) then
           echo "align_type set to $align_type"
        else
           echo "align_type $align_type is not a valid choice"
           exit 1
        endif

    else if ("$argv[$ac]" == "-extra_qw_opts") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set extra_qw_opts =  ($extra_qw_opts $argv[$ac] )
        echo "extra_qw_opts is set to "$extra_qw_opts

    else if ("$argv[$ac]" == "-center_out") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set center_out =  "$argv[$ac]"
        if (( "${center_out}" == "native") ||     \
            ( "${center_out}" == "center_shift")) then
           echo "++ The center_out is set to: $center_out"
        else
           echo "** ERROR: center_out '$center_out' is not a valid choice"
           echo "          please choose native or center_shift"
           exit 1
        endif    
         
    else if ("$argv[$ac]" == "-ok_to_exist") then
        set ok_to_exist = "1"

    else if ("$argv[$ac]" == "-no_surfaces") then
        set make_orig_surfaces = "0"

    # [PT: May 14, 2020]
    else if ( ("$argv[$ac]" == "-atlas") ||   \
              ("$argv[$ac]" == "-atlas_followers") ) then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            # go until an option starting with a hyphen appears
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            # if hyphenated, grep returns same arg -> are at new opt
            if ("$argv[$ac]" == "$poss_dset") then
               break
            # not a hyphen leading option, should be dataset
            else
               set atlfollow = $argv[$ac]
               # is the dataset somewhere else or current directory
                set atlfollow = `@FindAfniDsetPath -append_file \
                                    -full_path $atlfollow`
               # add the dataset to the segmentation follower list
               set atlas_followers = ($atlas_followers $atlfollow)
            endif
            @ ac ++
        end
        if ( $#atlas_followers == 0 ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --        

    
    else if ( ("$argv[$ac]" == "-atlas_abbrevs") ) then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            if ("$argv[$ac]" == "$poss_dset") then
               break
            else
               set atlas_abbrevs = ( $atlas_abbrevs "$argv[$ac]" )
            endif
            @ ac ++
        end
        if ( $#atlas_abbrevs == 0 ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --        

    else if ("$argv[$ac]" == "-template_followers") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            # go until an option starting with a hyphen appears
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            # if hyphenated, grep returns same arg -> are at new opt
            if ("$argv[$ac]" == "$poss_dset") then
               break
            # not a hyphen leading option, should be dataset 
            else
               set tempfollow = $argv[$ac]
               # is the dataset somewhere else or current directory
               set tempfollow = `@FindAfniDsetPath -append_file \
                                    -full_path $tempfollow`
               # add the dataset to the template follower list
               set template_followers = ($template_followers $tempfollow)
            endif
            @ ac ++
        end
        if ( "$#template_followers" == "0" ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --

    else if ( ("$argv[$ac]" == "-template_abbrevs") ) then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            if ("$argv[$ac]" == "$poss_dset") then
               break
            else
               set template_abbrevs = ( $template_abbrevs "$argv[$ac]" )
            endif
            @ ac ++
        end
        if ( $#template_abbrevs == 0 ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --        

    else if ("$argv[$ac]" == "-seg_followers") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            # go until an option starting with a hyphen appears
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            # if hyphenated, grep returns same arg -> are at new opt
            if ("$argv[$ac]" == "$poss_dset") then
               break
            # not a hyphen leading option, should be dataset
            else
               set segfollow = $argv[$ac]
               # is the dataset somewhere else or current directory
                set segfollow = `@FindAfniDsetPath -append_file \
                                    -full_path $segfollow`
               # add the dataset to the segmentation follower list
               set seg_followers = ($seg_followers $segfollow)
            endif
            @ ac ++
        end
        if ( $#seg_followers == 0 ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --        

    else if ( ("$argv[$ac]" == "-seg_abbrevs") ) then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            if ("$argv[$ac]" == "$poss_dset") then
               break
            else
               set seg_abbrevs = ( $seg_abbrevs "$argv[$ac]" )
            endif
            @ ac ++
        end
        if ( $#seg_abbrevs == 0 ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --        

    else if ("$argv[$ac]" == "-dset_followers") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            # go until an option starting with a hyphen appears
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            # if hyphenated, grep returns same arg -> are at new opt
            if ("$argv[$ac]" == "$poss_dset") then
               break
            # not a hyphen leading option, should be dataset 
            else
               set dsetfollow = $argv[$ac] 
               # is the dataset somewhere else or current directory
               set dsetfollow = `@FindAfniDsetPath -append_file \
                                    -full_path $dsetfollow`
               # add the dataset to the template follower list
               set dset_followers = ($dset_followers $dsetfollow)
            endif
            @ ac ++ 
        end
        if ( "$#dset_followers" == "0" ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --

    else if ( ("$argv[$ac]" == "-dset_abbrevs") ) then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            if ("$argv[$ac]" == "$poss_dset") then
               break
            else
               set dset_abbrevs = ( $dset_abbrevs "$argv[$ac]" )
            endif
            @ ac ++
        end
        if ( $#dset_abbrevs == 0 ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --        

    else if ("$argv[$ac]" == "-roidset_followers") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            # go until an option starting with a hyphen appears
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            # if hyphenated, grep returns same arg -> are at new opt
            if ("$argv[$ac]" == "$poss_dset") then
               break
            # not a hyphen leading option, should be dataset 
            else
               set dsetfollow = $argv[$ac] 
               # is the dataset somewhere else or current directory
               set dsetfollow = `@FindAfniDsetPath -append_file \
                                    -full_path $dsetfollow`
               # add the dataset to the template follower list
               set roidset_followers = ($roidset_followers $dsetfollow)
            endif
            @ ac ++ 
        end
        if ( "$#roidset_followers" == "0" ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --

    else if ( ("$argv[$ac]" == "-roidset_abbrevs") ) then
        set this_opt = "$argv[$ac]"
        @ ac ++
        while ($ac <= $#argv)
            set poss_dset = `echo $argv[$ac] | grep -- "^-"`
            if ("$argv[$ac]" == "$poss_dset") then
               break
            else
               set roidset_abbrevs = ( $roidset_abbrevs "$argv[$ac]" )
            endif
            @ ac ++
        end
        if ( $#roidset_abbrevs == 0 ) then
            echo "** missing dataset for option '${this_opt}'"
            exit 1
        endif
        @ ac --        

    else if ("$argv[$ac]" == "-feature_size") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set feature_size = $argv[$ac]
        set feature_option =  "-feature_size $feature_size"

    else if ("$argv[$ac]" == "-mode_smooth_size") then
        set this_opt = "$argv[$ac]"
        @ ac ++
        if ( $ac > $#argv ) then
            echo "** missing parameter for option '${this_opt}'"
            exit 1
        endif
        set modesmooth = $argv[$ac]
        set modesmooth = `ccalc -int -expr "$modesmooth"`
        if ("$status" != "0") then
          echo "mode_smooth_size set to $argv[$ac] is not valid"
          echo "Please use a number to specify how many voxels"
          exit 1
        endif

    # [PT: May 30, 2020] turn off replacement of lost ROIs in modal smooth
    else if ("$argv[$ac]" == "-mode_smooth_replacement_off") then
        set DO_MODE_SMOO_W_REP = 0

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

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

    # ---------- fin ------------------

    else
        echo "** unknown option $argv[$ac]"
        exit 1
    endif
    @ ac ++
end

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

echo "++ Start @animal_warper, ver = ${version}"

set thedate   = `date +%Y_%m_%d_%H_%M_%S`
set start_d   = `date +%Y-%m-%d`
set start_H   = `date +%H`
set start_M   = `date +%M`
set start_S   = `date +%S`
set start_VAL = "${start_d} ${start_H}:${start_M}:${start_S}"

# ------------------------- check for required inputs
if ("${src_dset0}" == "") then
    echo "No input dataset provided"
    exit 1
endif

if ("${base_dset}" == "") then
    echo "No base template dataset provided"
    exit 1
endif

# [PT: Oct 24, 2021] if a src abbrev is used, add it to the QC image
# names, so we can tell who is who more easily when looking at a lot
# of them.
if ( "${src_abbrev}" != "" ) then
    set src_add = ".${src_abbrev}"
endif

# ------------------------ define final 'orig' space
# is it *really* the orig, or the osh (orig-shifted)?

if ( "${center_out}" == "native" ) then
    set orig_fin = "orig"
else if ( "${center_out}" == "center_shift" ) then
    set orig_fin = "orig-shft"
else
    echo "** ERROR: Unrecognized center_out value: ${center_out}"
    exit 1
endif

# ------------------------- make OUTDIR + QC dir

# We don't allow output directory to be $PWD -- must be a subdir; too
# complicated with copying fnames

\mkdir -p "${outdir}"
cd "${outdir}"
if ( "${PWD}" == "${here}" ) then
    echo "** ERROR: Output directory cannot be same current working dir."
    echo "          Please specify new output directory"
    exit 1
endif
cd -

\mkdir -p ${outdir}/QC
\mkdir -p ${outdir}/${imed}

# ----------------------- INFO for animal_outs

set afni_pack = `afni -package`
set afni_vnum = `afni -vnum`
set aw_ver    = `@animal_warper -ver`

# so that if there is a crash, there is a record of what was run
echo "# AFNI pack : ${afni_pack}"   >    ${outdir}/log_cmd.txt
echo "# AFNI ver  : ${afni_vnum}"   >>   ${outdir}/log_cmd.txt
echo "# AW ver    : ${aw_ver}"      >>   ${outdir}/log_cmd.txt
echo "# Command   :"                >>   ${outdir}/log_cmd.txt
echo "@animal_warper $argv"         >>   ${outdir}/log_cmd.txt
echo ""                             >>   ${outdir}/log_cmd.txt
echo "# start     : ${start_VAL}"   >>   ${outdir}/log_cmd.txt

# -------------------------- set alignment COSTS

if ($cost == "") then
   set cost = "lpa+ZZ"
   set nlcost = ""
else
   # NL warps do not support +ZZ costs, so just use similar cost
   set nlcost = `adjunct_simplify_cost.py ${cost}`
endif

# user set cost function
if ( "${nlcost}" != "" ) then
    set nlcostoption = "-$nlcost"
else
    # using default cost in 3dQwarp
    set nlcostoption = ""
endif

# ------------------------- earliest QC: check overlap

set opref = QC/${iqc00}${src_add}

@djunct_overlap_check                             \
    -ulay   "${src_dset0}"                        \
    -olay   "${base_dset}"                        \
    -opacity 3                                    \
    -prefix ${outdir}/${opref}

# ------------------------- setup input SRC dset

# input datasets may not be +orig
# so match input view equivalent even for NIFTI
set origview       = `3dinfo -av_space     "${src_dset0}" |tr -d +` # unused
set origspace      = `3dinfo -space        "${src_dset0}"`
set src_prefix     = `3dinfo -prefix_noext "${src_dset0}"`
if ( "${src_abbrev}" == "" ) then
    set src_abbrev = "${src_prefix}"
endif
set src_dset       = ${src_abbrev}.nii.gz   # cp of orig inp, used to proc

# all the *p*reliminary shifted forms
set srcsh_prefix    = ${src_abbrev}_pshft         # NOTE this name change
set srcsh_dset      = ${srcsh_prefix}.nii.gz      # ... redefine $dset
set srcsh_shft      = ${srcsh_prefix}.1D          # for convenience
set srcsh_shft_inv  = ${srcsh_prefix}_inv.1D

# [PT: Aug 27, 2020] this will be the combined @Align_Centers shift
# with the translation part of 3dAllineate 
set srcsh2_prefix    = ${src_abbrev}_shft           # NOTE this name change
set srcsh2_dset      = ${srcsh2_prefix}.nii.gz      # ... redefine $dset
set srcsh2_shft      = ${srcsh2_prefix}.1D          # for convenience
set srcsh2_shft_inv  = ${srcsh2_prefix}_inv.1D

if (($ok_to_exist == 1) && \
    (-f "${outdir}/${src_dset}" )) then
   echo "++ Reusing input copy: ${outdir}/${src_dset}"
else
   # in case use uses subbrick selection on $dset, copy this way
   ### [PT: Oct 16, 2020] this 3dresample replaces a previous 3dcalc
   ### to copy src_dset: with the pshft and concatenation of
   ### translations, we want to have the the src dataset have good
   ### (x,y,z) ordering of coords.
   3dresample -overwrite                             \
     -input    "${src_dset0}"                        \
     -orient   RAI                                   \
     -prefix   "${outdir}/${src_dset}"

   if ( ${status} ) then
       echo "** ERROR: program failed (cp src)"
       exit 1
   endif
endif

# -------------------- setup BASE dset

# is the dataset somewhere else or current directory
set base_dset  = `@FindAfniDsetPath -full_path -append_file "${base_dset}"`
set base_space = `3dinfo -space "${base_dset}"`
set base_view  = `3dinfo -av_space "${base_dset}"`
set tbase      = `basename ${base_dset}` # can also refer to base in OUTDIR

# Figure out short name for base to insert into output files
if ( "${base_abbrev}" != "" ) then
    echo "++ Using user's base abbrev: ${base_abbrev}"
else 
    # default will be `3dinfo -space ..` of base_dset
    set base_abbrev = ${base_space}
    echo "++ Making 'base' abbrev:"
    echo "   ... ${base_abbrev}"

    if ( ${USE_KNOWN_BASE_ABBREV} ) then
        # go through our list of known *template* abbrevs
        foreach aa ( ${all_known_template_abbrev} )
            set gcount = `echo "${base_abbrev}" | grep -c "${aa}"`
            if ( "${gcount}" != "0" ) then
                set base_abbrev = "${aa}"
                break
            endif
        end
    endif

    # special case, if base_dset is in orig space; clarify *whose*
    # ORIG space; probably a rare occurrence
    if ( "${base_abbrev}" == "ORIG" ) then
        set base_abbrev = "BASEORIG"
    endif
    printf " --> ${base_abbrev}\n"
endif

if (($ok_to_exist == 1) && \
    (-f ${outdir}/`basename "${base_dset}"`)) then
   echo "++ Reusing ${outdir}/${base_dset}"
else
   # NB: in code below, instances of ${base_dset} still refer to the
   # original, uncopied dset (bc it has full path); this is just for
   # checking alignments; probably better to still have code refer to
   # original ${base_dset}, for gen_ss_review.py to get info via
   # afni_proc.py-generated script
   3dcopy "${base_dset}" ${outdir}/

   if ( ${status} ) then
       echo "** ERROR: program failed (copy base)"
       exit 1
   endif
endif

# ------------------ copy atlas followers

if ( ${#atlas_followers} != 0 ) then
   foreach ff ( ${atlas_followers} )
      if ( ($ok_to_exist == 1) && \
           (-f ${outdir}/`basename "${ff}"`) ) then
          echo "++ Reusing ${outdir}/${ff}"
      else
          # Use 3dcopy here to tables/atlas_points/subbrick labels wd
          # copy over
          3dcopy "${ff}" ${outdir}/

          if ( ${status} ) then
             echo "** ERROR: program failed (copy atlas foll)"
             exit 1
          endif
      endif
    end
endif

# ----- SHOULD ALL FOLLOWERS BE COPIED HERE AS WELL ??? 

# ------------------------- setup BRAINMASK 

# [BTJ: Mar 29, 2020] template mask-based brainmasking code
if ("${brainmask}" != "") then
   # is the dataset somewhere else or current directory
   set brainmask = `@FindAfniDsetPath -full_path -append_file "${brainmask}"`

   if ( ($ok_to_exist == 1) && \
        (-f ${outdir}/`basename "$brainmask"`) ) then
      echo "++ Reusing ${outdir}/$brainmask"
   else
      3dcopy "${brainmask}" ${outdir}/
   endif

   # Need to specify a mask to use for 'base' dset for reports
   set base_mask_for_reps = "${brainmask}"
else
   # If no brainmask is input, then the base dset itself is applied as
   # the mask
   set base_mask_for_reps = "${base_dset}"
endif


# ------------------ check/make abbrevs (for all followers)

# Here, we check that the number of user-entered abbrevs is
# appropriate (either 0 or same nonzero number of atlas followers).
# The we also see if we recognize an atlas, based on file name, and if
# so take that shorter piece as an abbreviation;

# We now treat all followers in a similar manner, so have some generic
# variables defined that are sent to/returned from a 'function' with
# goto.  Each chunk here is created by replacing "atlas" with the
# follower type.  (In emacs, case is matched with this manner of
# find/replace.)

# ATLAS
if ( ${#atlas_followers} ) then
    set generic_followers        = ( ${atlas_followers} )
    set generic_abbrevs          = ( ${atlas_abbrevs} )
    set all_known_generic_abbrev = ( ${all_known_atlas_abbrev} )
    set foll_type                = "atlas"
    set USE_KNOWN_GENERIC_ABBREV = ${USE_KNOWN_ATLAS_ABBREV}
    goto ABBREV_CREATION_START
    ABBREV_CREATION_END_ATLAS:
    set atlas_abbrevs = ( ${generic_abbrevs} ) 
endif

# TEMPLATE
if ( ${#template_followers} ) then
    set generic_followers        = ( ${template_followers} )
    set generic_abbrevs          = ( ${template_abbrevs} )
    set all_known_generic_abbrev = ( ${all_known_template_abbrev} )
    set foll_type                = "template"
    set USE_KNOWN_GENERIC_ABBREV = ${USE_KNOWN_TEMPLATE_ABBREV}
    goto ABBREV_CREATION_START
    ABBREV_CREATION_END_TEMPLATE:
    set template_abbrevs = ( ${generic_abbrevs} ) 
endif

# SEG
if ( ${#seg_followers} ) then
    set generic_followers        = ( ${seg_followers} )
    set generic_abbrevs          = ( ${seg_abbrevs} )
    set all_known_generic_abbrev = ( ${all_known_seg_abbrev} )
    set foll_type                = "seg"
    set USE_KNOWN_GENERIC_ABBREV = ${USE_KNOWN_SEG_ABBREV}
    goto ABBREV_CREATION_START
    ABBREV_CREATION_END_SEG:
    set seg_abbrevs = ( ${generic_abbrevs} ) 
endif

# DSET
if ( ${#dset_followers} ) then
    set generic_followers        = ( ${dset_followers} )
    set generic_abbrevs          = ( ${dset_abbrevs} )
    set all_known_generic_abbrev = ( ${all_known_dset_abbrev} )
    set foll_type                = "dset"
    set USE_KNOWN_GENERIC_ABBREV = ${USE_KNOWN_DSET_ABBREV}
    goto ABBREV_CREATION_START
    ABBREV_CREATION_END_DSET:
    set dset_abbrevs = ( ${generic_abbrevs} ) 
endif

# ROIDSET
if ( ${#roidset_followers} ) then
    set generic_followers        = ( ${roidset_followers} )
    set generic_abbrevs          = ( ${roidset_abbrevs} )
    set all_known_generic_abbrev = ( ${all_known_roidset_abbrev} )
    set foll_type                = "roidset"
    set USE_KNOWN_GENERIC_ABBREV = ${USE_KNOWN_ROIDSET_ABBREV}
    goto ABBREV_CREATION_START
    ABBREV_CREATION_END_ROIDSET:
    set roidset_abbrevs = ( ${generic_abbrevs} ) 
endif

# --------- END of abbrev name generation for all followers

# ----------------------- setup autowarp dir

set awpy_dir = awpy_${srcsh_prefix}

# ------------------------------------------------------------------------
# --------------------- move to odir, then start proc --------------------

cd ${outdir}

# ----------------------- MAKE animal_outs -------------------------------

# If animal_outs text file already exists, mv it (for backup) and then
# make a new one
if ( ($ok_to_exist == 1) && \
     (-f ${animal_outs}) ) then
    set backup_ao = ${animal_outs:gas/.txt//}_mvd_${thedate}.txt
    \mv ${animal_outs} ${backup_ao}

    if ( ${status} ) then
        echo "** ERROR: program failed (cp backup rep)"
        exit 1
    endif

    echo "++ Moved old ${animal_outs} to: ${backup_ao}"
endif


if ( ($ok_to_exist == 1) && \
     (-f ${animal_ints}) ) then
    set backup_ao2 = ${animal_ints:gas/.txt//}_mvd_${thedate}.txt
    \mv ${animal_ints} ${backup_ao2}
    echo "++ Moved old ${animal_ints} to: ${backup_ao2}"
endif

# Set up main and intermediate output text file with file descriptions 
echo "# List of inputs and outputs from @animal_warper" > ${animal_outs}
echo "" >> ${animal_outs}

echo "# List of @animal_warper files in ${imed} directory" > ${animal_ints}
echo "" >> ${animal_ints}

printf "%-37s : %s\n"                \
        "AFNI package"               \
        "${afni_pack}"               \
       >> ${animal_outs}

printf "%-37s : %s\n"                \
        "AFNI version number"        \
        "${afni_vnum}"               \
       >> ${animal_outs}

printf "%-37s : %s\n"                \
        "@animal_warper ver"         \
        "${version}"                 \
       >> ${animal_outs}

printf "%-37s : %s\n"                 \
        "List of main outputs (this file)" \
        "${animal_outs}"              \
       >> ${animal_outs}

printf "%-37s : %s\n"                   \
        "List of intermediate files"    \
        "${animal_ints}"                \
    >> ${animal_outs}

if ( "${backup_ao}" != "" ) then
    printf "%-37s : %s\n"               \
        "Rerun notice, see backup info" \
        "${backup_ao}"                  \
       >> ${animal_outs}
endif

echo "" >> ${animal_outs}

printf "%-37s : %s\n"                \
        "Input dset (orig)"          \
        "${src_dset}"                \
       >> ${animal_outs}

printf "%-37s : %s\n"                \
        "Base dset (templ)"          \
        "${tbase}"                   \
       >> ${animal_outs}

printf "%-37s : %s\n"                \
        "Base space"                 \
        "${base_space}"              \
       >> ${animal_outs}

set dlist = ""
foreach ff ( ${atlas_followers} )
    # use basename of each atlas, bc full path can be long; full
    # command is echoed at bottom of animal_outs, anyways
    set bb = `basename "${ff}"`
    if ( "${dlist}" == "" ) then
        set dlist = "${bb}"
    else
        set dlist = "${dlist}, ${bb}"
    endif
end

printf "%-37s : %s\n"       \
        "Atlas dsets"       \
        "${dlist}"          \
       >> ${animal_outs}

# Record the final 'orig' space (shifted or original)
printf "%-37s : %s\n"                   \
        "Input dset center_out"         \
        "${center_out}"                 \
       >> ${animal_outs}

if ( "$align_type" == "all" ) then
    set al_meth = "all (= nonlinear)"
else
    set al_meth = "$align_type"
endif

# Record the type of alignment
printf "%-37s : %s\n"                   \
        "Alignment type"                \
        "${al_meth}"                    \
    >> ${animal_outs}

echo "" >> ${animal_outs}

# -----------------------------------------------------------------------
# -------------------- estimate center-align shift ----------------------

# put the center of the dataset on top of the center of the template
if ( ($ok_to_exist == "1") && \
     (-f  ${srcsh_dset}) ) then
   echo "++ Reusing center aligned  ${srcsh_dset}"
else

    if ( ${DO_ALIGN_CENTERS} ) then
        @Align_Centers -overwrite            \
            ${align_centers_meth}            \
            -prefix "${imed}/${srcsh_dset}"  \
            -base   "${base_dset}"           \
            -dset   "${src_dset}"

        if ( ${status} ) then
            echo "** ERROR: program failed (align centers)"
            exit 1
        endif

        # Do this because @Align Centers doesn't put *_shft.1D in same
        # place as its "-prefix .." path tells it to.
        \mv ${srcsh_shft} \
            ${imed}/${srcsh_shft}

    else
        echo "++ Well, actually just COPYING dset as the center-alignment..."
        3dcopy -overwrite                  \
            "${src_dset}"                  \
            "${imed}/${srcsh_dset}"

        if ( ${status} ) then
            echo "** ERROR: program failed (align centers, cp)"
            exit 1
        endif

        echo "   ... and making an identity 'shift'"
        echo "1 0 0 0 0 1 0 0 0 0 1 0" > ${imed}/${srcsh_shft}
    endif
endif

# *** After this point, the following files exist: 
#          ${srcsh_dset} = src dset that has been shifted
#          ${srcsh_shft} = text file of the shift itself

# Inverse translation (should just be negation of translation column).
if ( ($ok_to_exist == "1") && \
     (-f  ${imed}/${srcsh_shft_inv}) ) then
   echo "++ Reusing center aligned  ${srcsh_shft_inv}"
else
    cat_matvec                                     \
          ${imed}/${srcsh_shft} -I                 \
        > ${imed}/${srcsh_shft_inv}

    if ( ${status} ) then
        echo "** ERROR: program failed (al cent inv)"
        exit 1
    endif
endif

printf "%-37s : %s\n"                             \
        "Dset, pre-shifted to base"               \
        "${srcsh_dset}"                   \
       >> ${animal_ints}

# [PT] newer check about overlap, and show some progress
set opref = QC/${iqc01}${src_add}

@djunct_overlap_check                             \
    -ulay    "${imed}/${srcsh_dset}"              \
    -olay    "${base_dset}"                       \
    -opacity 3                                    \
    -prefix  ${opref}

# ------------------------- estimate aff mat -------------------------

# Using input/src dset as dset2 and the base as dset1 (the base and
# source are treated differently by align_epi_anats resampling and by
# 3dAllineate)

if ( "$align_type" == "rigid" ) then
   set rigidopt = "-rigid_body"
else
   set rigidopt = ""
endif

if ( ( $ok_to_exist == "1" ) && \
     (-f  ${imed}/${srcsh_prefix}_al2std_mat.aff12.1D) ) then
   echo "++ Reusing affine transformation matrix"
else

   #set aaa = ( -giant_move )

   if ( $DO_INIT_SCALE ) then
      echo "++ Make pre_matrix for initial scale: ${init_scale}"

      set premat_fname   = "${imed}/aea_pre_matrix.1D"
      set opt_init_scale = "-pre_matrix ${premat_fname}"
cat <<EOF > "${premat_fname}"
${init_scale} 0.0 0.0 0.0
0.0 ${init_scale} 0.0 0.0
0.0 0.0 ${init_scale} 0.0
EOF
      # just for QC image-generating purposes
      3dAllineate                                                  \
         -overwrite                                                \
         -1Dmatrix_apply "${premat_fname}"                         \
         -input          "${imed}/${srcsh_dset}"                   \
         -prefix         "${imed}/__tmp_INIT_SCALE.nii.gz"

      set opref = QC/${iqc01b}${src_add}
      @djunct_overlap_check                             \
          -ulay    "${imed}/__tmp_INIT_SCALE.nii.gz"    \
          -olay    "${base_dset}"                       \
          -opacity 3                                    \
          -prefix  ${opref}

      if ( "${keep_temp}" != "1") then
         \rm -rf "${imed}/__tmp_INIT_SCALE.nii.gz"
      endif
   endif

   # outputs a BRIK/HEAD file
   # [PT: July 8, 2021] allow '-giant_move' to be switched to other opts
   # [PT: July 9, 2021] ... and adding "-master_dset2 BASE" for stability
   # across now-larger range of $aff_move options.
   align_epi_anat.py -overwrite                                     \
    -output_dir   "${imed}"                                         \
    -dset2        "${imed}/${srcsh_dset}"                           \
    -dset1        "${base_dset}"                                    \
    -dset2to1                                                       \
    -suffix       _al2std                                           \
    -dset1_strip  None                                              \
    -dset2_strip  None                                              \
    -cost $cost $rigidopt $feature_option $supersize ${aff_move}    \
    -master_dset2  BASE   ${opt_init_scale}

   if ( ${status} ) then
       echo "** ERROR: program failed (AEA)"
       exit 1
   endif

   # convert the affine aligned output to NIFTI
   3dAFNItoNIFTI                                                    \
        -prefix ${imed}/${srcsh_prefix}_al2std.nii.gz               \
        ${imed}/${srcsh_prefix}_al2std${base_view}

   if ( ${status} ) then
       echo "** ERROR: program failed (afni2nii)"
       exit 1
   endif

   \rm ${imed}/${srcsh_prefix}_al2std${base_view}.*
endif

# re-partition the translation part of aff alignment with the shift
# from @Align_Centers

if ( ( $ok_to_exist == "1" ) && \
     (-f  ${imed}/${srcsh2_dset} ) ) then
   echo "++ Reusing re-partitioned shift"
else

    # extract the translation part and output it
    set mat0 = `cat_matvec -ONELINE         \
                    "${imed}/${srcsh_prefix}_al2std_mat.aff12.1D"`
    echo "1 0 0 ${mat0[4]} 0 1 0 ${mat0[8]} 0 0 1 ${mat0[12]}" > \
        "${imed}/${srcsh_prefix}_al2std_mat_TR.aff12.1D"

    # ... and calc its inverse
    cat_matvec -ONELINE                                          \
        "${imed}/${srcsh_prefix}_al2std_mat_TR.aff12.1D" -I      \
        > "${imed}/${srcsh_prefix}_al2std_mat_TR_INV.aff12.1D"

    # this is needed for shifting the origin, below
    set inv_transl = `cat "${imed}/${srcsh_prefix}_al2std_mat_TR_INV.aff12.1D"`

    # create the new full shift
    cat_matvec -ONELINE                          \
        ${imed}/${srcsh_shft}                            \
        "${imed}/${srcsh_prefix}_al2std_mat_TR.aff12.1D" \
        > ${imed}/${srcsh2_shft}

    # ... and inverse shift
    cat_matvec -ONELINE                          \
        ${imed}/${srcsh2_shft} -I                        \
        > ${imed}/${srcsh2_shft_inv}

    if ( ${status} ) then
        echo "** ERROR: program failed (cat_matvec inv)"
        exit 1
    endif

    # THIS is the aff matrix that goes from shft2 to template space,
    # and what we should use later; it should have NO translation
    # component
    # [PT, DRG: Aug 5, 2024] fix how this is done, so that 
    # after this is applied, the *_pshft_al2std.nii.gz will
    # be essentially the same as *_shft_aff.nii.gz (just in
    # ORIG and TLRC views, and on diff grids)
    cat_matvec -ONELINE                              \
        "${imed}/${srcsh_prefix}_al2std_mat.aff12.1D"        \
        "${imed}/${srcsh_prefix}_al2std_mat_TR_INV.aff12.1D" \
        >  "${imed}/${srcsh2_prefix}_al2std_mat.aff12.1D"

    # Finally, make the new shifted dset; that should overlap
    # well with base_dset
    3dcopy                                       \
        -overwrite                               \
        ${imed}/${srcsh_dset}                    \
        ${imed}/${srcsh2_dset}
    3drefit \
        -dxorigin ${inv_transl[4]}               \
        -dyorigin ${inv_transl[8]}               \
        -dzorigin ${inv_transl[12]}              \
        ${imed}/${srcsh2_dset}

    if ( ${status} ) then
        echo "** ERROR: program failed (combine shifts)"
        exit 1
    endif

    # *** From this point onward, the shft2 space is the more important
    # jumping point between the original native space and the
    # base/template space***
endif


printf "%-37s : %s\n"                                               \
        "Dset, 2nd-shifted to base"                                 \
        "${srcsh2_dset}"                                    \
       >> ${animal_ints}

echo "" >> ${animal_ints}

printf "%-37s : %s\n"                                               \
        "Input, aff-xformed to base (orig res)"                     \
        "${srcsh_prefix}_al2std.nii.gz"                     \
       >> ${animal_ints}

printf "%-37s : %s\n"                                               \
        "Matrix, aff xform (shft2 to base)"                         \
        "${srcsh2_prefix}_al2std_mat.aff12.1D"              \
       >> ${animal_ints}

if ( "$align_type" == "rigid_equiv" ) then
    set affmat = ${srcsh2_prefix}_al2std_mat_rigid.aff12.1D
    cat_matvec -ONELINE                                             \
        ${imed}/${srcsh2_prefix}_al2std_mat.aff12.1D -P             \
        > ${imed}/${affmat}

    if ( ${status} ) then
        echo "** ERROR: program failed (cat_matvec, affmat)"
        exit 1
    endif

    printf "%-37s : %s\n"                                           \
            "Matrix, rigid equiv xform"                             \
            "${affmat}"                                     \
        >> ${animal_ints}
else
    set affmat = ${srcsh2_prefix}_al2std_mat.aff12.1D
endif

## put affine aligned data on template grid
# similar to al2std dataset but with exactly same grid as the template
if (($ok_to_exist == "1") && \
    (-f ${imed}/${srcsh2_prefix}_aff.nii.gz)) then
    echo "++ Reusing affine transformed dataset"
else
    3dAllineate -overwrite                                       \
         -1Dmatrix_apply ${imed}/${affmat}                       \
         -prefix ${imed}/${srcsh2_prefix}_aff.nii.gz             \
         -base   "${base_dset}"                                  \
         -master BASE                                            \
         -source "${imed}/${srcsh2_dset}"

    if ( ${status} ) then
        echo "** ERROR: program failed (3dAllineate)"
        exit 1
    endif

    set opref = QC/${iqc02}${src_add}
    @djunct_overlap_check                             \
        -ulay   "${imed}/${srcsh2_prefix}_aff.nii.gz" \
        -olay   "${base_dset}"                        \
        -opacity 3                                    \
        -prefix  ${opref}
endif


printf "%-37s : %s\n"                                      \
        "Input, aff-xformed to base"                       \
        "${srcsh2_prefix}_aff.nii.gz"              \
       >> ${animal_ints}

echo "" >> ${animal_ints}

# ---------------------- make inv and composite aff mats ----------------

# Note on combining shft2 and affine 1D files for composite linear
# transformation to template space: combining shift is dangerous! The
# transformation distance can be very large, and 3dNwarpApply will
# create a high resolution space that will likely eat up large amounts
# of memory.  Proceed with caution (well, the user needs dsets that
# aren't *too* far apart).

# Compute the inverse of the affine alignment transformation - all 12
# numbers; creates 'template -> shifted input space' aff xform
cat_matvec                                               \
    -ONELINE                                             \
    ${imed}/${srcsh2_prefix}_al2std_mat.aff12.1D -I      \
    >! ${imed}/${srcsh2_prefix}_inv_al2std_mat.aff12.1D

# full affine part, template to unshifted org space: don't want this
# to be large (see note above); creates 'original input -> template
# space' aff xform
cat_matvec                                                \
    -ONELINE                                              \
    ${imed}/${srcsh2_prefix}_al2std_mat.aff12.1D          \
    ${imed}/${srcsh2_shft}                                \
    > ${src_abbrev}_composite_linear_to_template.1D

#Now create the inverse composite warp from template to subject space;
# creates 'template spac -> original input' aff xform
cat_matvec -ONELINE                                       \
    ${imed}/${srcsh2_shft_inv}                            \
    ${imed}/${srcsh2_prefix}_inv_al2std_mat.aff12.1D      \
    > ${src_abbrev}_composite_linear_to_template_inv.1D

if ( ${status} ) then
    echo "** ERROR: program failed (inv comp)"
    exit 1
endif

printf "%-37s : %s\n"                                       \
        "Matrix, full aff xform (for AP)"                   \
        "${src_abbrev}_composite_linear_to_template.1D"     \
       >> ${animal_outs}

printf "%-37s : %s\n"                                       \
        "Matrix, full aff xform, inv"                       \
        "${src_abbrev}_composite_linear_to_template_inv.1D" \
       >> ${animal_outs}

# ---------------------- end aff; can go to NL ----------------------------

#### no longer the case!
#
## if nonlinear alignment is not requested, then exit
#if ( "$align_type" != "all" ) then
#    echo ""
#    echo "++ Finished aligning with only ${align_type} alignment"
#    echo ""
#    if ( "$align_type" == "rigid" ) then
#        echo "++ This 'rigid' alignment method requires restarting"
#        echo "   the alignment for other types of alignment"
#    else
#        echo "++ You may restart for other types of alignment with"
#        echo "   a different align_type and -ok_to_exist"
#    endif
#    goto FINISH_OUTS
#endif

if ( "$align_type" != "all" ) then
    echo "++ With align_type = '$align_type', we jump ahead."
    goto JUMP_RIGID
endif


# ------------------------ MAKE_WARP aff2base, base2aff --------------------

# --------------------------------------------------------------------------
# Note about the warping here:
#
# affinely align to template (could let auto_warp.py hande this, but
#  AUTO_CENTER option might be needed)
# @auto_tlrc -base $base -input $dset -no_ss -init_xform AUTO_CENTER
#
# NB: Now skipping cheap skullstripping:
#   It didn't work for macaques with very different size brains. V1
#   got cut off probably could work with dilated mask "cheap"
#   skullstripping with affine registered dataset the macaque brains
#   are similar enough that the affine seems to be sufficient here for
#   skullstripping
# 3dcalc -a ${src_prefix}_aff+tlrc. -b $base -expr 'a*step(b)'   \
#    -prefix ${src_prefix}_aff_ns -overwrite
#
# nonlinear alignment of affine skullstripped dataset to template
#  by default,the warp and the warped dataset are computed
#  by using "-qw_opts ", one could save the inverse warp and do extra padding
#  with -qw_opts '-iwarp -expad 30'
# change qw_opts to remove max_lev 2 for final   
# --------------------------------------------------------------------------

# No $ok_to_exist on this dir: the outputs that are extracted from it
# are checked, instead.  Gets purged, below, at end of running.
\rm -rf ${awpy_dir}

if ( ($ok_to_exist == "1") && \
     (-f ${srcsh2_prefix}_WARP.nii.gz) ) then
   echo "++ Reusing nonlinear WARP dataset"
else
   # nonlinear warping via auto_warp script
   auto_warp.py  -overwrite                                      \
      -base "${base_dset}"                                       \
      -affine_input_xmat ID                                      \
      -qworkhard 0 2                                             \
      -input ${imed}/${srcsh2_prefix}_aff.nii.gz                 \
      -output_dir ${awpy_dir}                                    \
      -qw_opts -iwarp -maxlev ${maxlev} ${nlcostoption}          \
      $extra_qw_opts

   if ( ${status} ) then
       echo "** ERROR: program failed (autowarp)"
       exit 1
   endif

   # the awpy has the result dataset, copy the warped data, the warp,
   # inverse warp don't copy the warped dataset - combine the
   # transformations instead below

   # THIS is a major output
   # from orig+shft2+aff -> base
   3dcopy -overwrite                                \
        ${awpy_dir}/anat.*.qw_WARP.nii*             \
        ${srcsh2_prefix}_WARP.nii.gz

   # from base -> orig+shft2+aff
   3dcopy -overwrite                                \
        ${awpy_dir}/anat.*.qw_WARPINV.nii*          \
        ${srcsh2_prefix}_WARPINV.nii.gz

   if ( ${status} ) then
       echo "** ERROR: program failed (autowarp cp)"
       exit 1
   endif
endif

# THIS is what should be given to afni_proc.py
printf "%-37s : %s\n"                                           \
        "NL warp, aff2base (for AP)"                            \
        "${srcsh2_prefix}_WARP.nii.gz"                          \
       >> ${animal_outs}

printf "%-37s : %s\n"                                           \
        "NL warp, base2aff"                                     \
        "${srcsh2_prefix}_WARPINV.nii.gz"                       \
       >> ${animal_outs}

# -----------------------------------------------------------------------
# ------------------------ MAKE_WARP osh2base  --------------------------

# This is the aff+WARP dset used within @animal_warper, so we don't
# have to keep recalculate it below.  THIS IS NOT what is applied to
# afni_proc.py.

if ( ($ok_to_exist == "1") &&                  \
     (-f "${imed}/${srcsh2_prefix}_osh2base_WARP.nii.gz" ) ) then
    echo "++ Reusing osh2base_WARP dataset"
else
    # warp from orig+shft2 -> base
    3dNwarpCat  -echo_edu                                          \
        -warp1  "${srcsh2_prefix}_WARP.nii.gz"                     \
        -warp2  "${imed}/${srcsh2_prefix}_al2std_mat.aff12.1D"     \
        -prefix "${imed}/${srcsh2_prefix}_osh2base_WARP.nii.gz"

    if ( ${status} ) then
        echo "** ERROR: program failed (3dNwarpCat, osh2base)"
        exit 1
    endif
endif

printf "%-37s : %s\n"                                             \
        "NL warp, osh2base (internal use)"                        \
        "${srcsh2_prefix}_osh2base_WARP.nii.gz"           \
       >> ${animal_ints}

# ------------------------- MAKE_WARP base2osh ------------------------

# Since this warp will get applied at least once (and probably more
# often, create it and then apply it.  Thus, THIS is the warp to apply
# for all template -> original/native space transforms

if ( ($ok_to_exist == "1") &&                  \
     (-f "${imed}/${srcsh2_prefix}_base2osh_WARP.nii.gz" ) ) then
    echo "++ Reusing base2osh_WARP dataset"
else
    # warp from base -> orig+shft2

    # [PT: Aug 27, 2020] get name of specific space (otherwise will
    # just be generic "TLRC)"
    set space = `3dinfo -space "${srcsh2_prefix}_WARPINV.nii.gz"`

    3dNwarpCat  -echo_edu                                          \
        -warp1  "${imed}/${srcsh2_prefix}_inv_al2std_mat.aff12.1D" \
        -warp2  "${srcsh2_prefix}_WARPINV.nii.gz"                  \
        -space  "${space}"                                         \
        -prefix "${imed}/${srcsh2_prefix}_base2osh_WARP.nii.gz"

    if ( ${status} ) then
        echo "** ERROR: program failed (3dNwarpCat, base2osh)"
        exit 1
    endif
endif

printf "%-37s : %s\n"                                             \
        "NL warp, base2osh (internal use)"                        \
        "${srcsh2_prefix}_base2osh_WARP.nii.gz"           \
       >> ${animal_ints}


JUMP_RIGID:

# -----------------------------------------------------------------------
# --------------------- APPLY_WARP osh2base: input dset -----------------

# NB: when *applying* warps to bring data into standard space, in this
# case the input template is in the shifted location: that is why the
# warp is only aff+WARP, and not oshft2+aff+WARP.

if ( ($ok_to_exist == "1") &&                  \
     (-f ${src_abbrev}_warp2std.nii.gz) && \
     (-f ${src_abbrev}_warp2std_nsu.nii.gz) ) then
    echo "++ Reusing warped input dataset and its unifized version"
else
    if ( "$align_type" == "all" ) then
        # [DRG: 07 Nov 2016] combine nonlinear and affine warps for dataset
        # warped to standard template space 
        3dNwarpApply -overwrite                                      \
            -prefix "${src_abbrev}_warp2std.nii.gz"                  \
            -nwarp  "${imed}/${srcsh2_prefix}_osh2base_WARP.nii.gz"  \
            -source "${imed}/${srcsh2_dset}"                         \
            -master "${base_dset}"

        if ( ${status} ) then
            echo "** ERROR: program failed (3dNwarpApply, osh2base)"
            exit 1
        endif
    else 
        3dAllineate -overwrite                                       \
            -prefix "${src_abbrev}_warp2std.nii.gz"                  \
            -1Dmatrix_apply "${imed}/${srcsh2_prefix}_al2std_mat.aff12.1D" \
            -source "${imed}/${srcsh2_dset}"                         \
            -master "${base_dset}"

        if ( ${status} ) then
            echo "** ERROR: program failed ($align_type 3dAllineate, osh2base)"
            exit 1
        endif
    endif

    set opref = QC/${iqc03}${src_add}
    @djunct_overlap_check                             \
        -ulay   "${src_abbrev}_warp2std.nii.gz"       \
        -olay   "${base_dset}"                        \
        -opacity 3                                    \
        -prefix  ${opref}

   # make masked version of orig dset in template space, using the
   # template itself.
   # [PT: Feb 25, 2021] not sure how much sense this makes with rigid aligns,
   # but will leave it in for user to decide about utility
   # [PT: May 20, 2021] switch what dset is used to mask the data that
   # has now been warped to standard space: should be either input
   # mask, or masking of template dset---thanks to A Messinger for pointing
   # this out
   3dcalc -overwrite                                    \
      -a      "${src_abbrev}_warp2std.nii.gz"           \
      #-b      "${base_dset}"                            \
      -b      "${base_mask_for_reps}"                   \
      -expr   'a*step(b)'                               \
      -prefix "${src_abbrev}_warp2std_ns.nii.gz"

   if ( ${status} ) then
       echo "** ERROR: program failed (3dcalc, osh2base)"
       exit 1
   endif

    # nicer version for viewing in template space: this will be passed
   # along to AP to be ulay at times
   echo "++ Unifizing input dset in template space"
   3dUnifize -overwrite                             \
      -GM                                           \
      -clfrac 0.4                                   \
      -Urad   14                                    \
      -input  ${src_abbrev}_warp2std_ns.nii.gz      \
      -prefix ${src_abbrev}_warp2std_nsu.nii.gz

   if ( ${status} ) then
       echo "** ERROR: program failed (3dUnifize, osh2base)"
       exit 1
   endif

   # ... and put a note in its history, so that
   # gen_ss_review_scripts.py knows the name of the template
   3dNotes \
   -h "@animal_warper aligned this dset to standard space: -base ${base_dset}" \
      ${src_abbrev}_warp2std_nsu.nii.gz


   # Image : [ulay] orig dset, warped to template
   #         [olay] edges of template
   # This is in template space, so use the template (which has no
   # skull) as a refbox
   set olay  = "${base_dset}"
   set ulay  = "${src_abbrev}_warp2std.nii.gz"
   set opref = QC/${qc00}${src_add}

    @djunct_edgy_align_check                  \
        -olay              ${olay}            \
        -box_focus_slices  ${olay}            \
        -ulay              ${ulay}            \
        -prefix            ${opref}           \
        -save_ftype        PNG                \
        -montx 5 -monty 3                     \
        -montgap 1                            \
        -montcolor 'black'

endif

# maybe change names? these sound like warp dsets, but they are
# actually dsets that *have* been warped
echo "" >> ${animal_outs}

printf "%-37s : %s\n"                              \
        "Input in templ"                           \
        "${src_abbrev}_warp2std.nii.gz"            \
       >> ${animal_outs}

printf "%-37s : %s\n"                              \
        "Input in templ, no skull"                 \
        "${src_abbrev}_warp2std_ns.nii.gz"         \
       >> ${animal_outs}

printf "%-37s : %s\n"                              \
        "Input in templ, no skull, unifized"       \
        "${src_abbrev}_warp2std_nsu.nii.gz"        \
       >> ${animal_outs}

# ------------ APPLY_WARP osh2base: DSET, ROIDSET followers -----------

# Use just one loop through all float- and int-valued dsets that are
# in the orig space, so the code isn't duplicated.  Use a matched list
# of interp values to tell which is which, when we need differences.

# Note: the followers will first be shifted here with @Align_centers,
# and then the aff+WARP matrix will be applied to them; this is yet
# again different than applying shft+aff+WARP.  The reason for this is
# the potential for giant memory usage if the shift part is large, as
# the final NL warp dset might be ginormous.

set all_follow = ( )
set all_abbrev = ( ) 
set all_interp = ( )

foreach ii ( `seq 1 1 ${#dset_followers}` ) 
    set all_follow = ( ${all_follow} "${dset_followers[$ii]}" )
    set all_abbrev = ( ${all_abbrev} "${dset_abbrevs[$ii]}"   )
    set all_interp = ( ${all_interp} wsinc5  )
end
foreach ii ( `seq 1 1 ${#roidset_followers}` )
    set all_follow = ( ${all_follow} "${roidset_followers[$ii]}" )
    set all_abbrev = ( ${all_abbrev} "${roidset_abbrevs[$ii]}"   )
    set all_interp = ( ${all_interp} NN      )
end

# applying warps to followers - other datasets that start in same
# space, ~grid.  move each the same way as the data - align centers,
# apply affine, nonlinear warp.
foreach ii ( `seq 1 1 ${#all_follow}` )

   set followset     = "${all_follow[$ii]}"
   set follow_abbrev = "${all_abbrev[$ii]}"
   set follow_interp = "${all_interp[$ii]}"

   # the main output
   set follow_in_std     = ${follow_abbrev}_warp2std.nii.gz
   # ... but if followset is int value AND is modally smoothed, then
   # save the pre-modally smoothed version under this name:
   set follow_in_std_pre = ${follow_abbrev}_w2s_PRE.nii.gz


   #  first check if output exists
   if ( ($ok_to_exist == "1") && \
        (-f ${follow_in_std}) ) then
      echo "++ Reusing nonlinear transformed follower dataset:"
      echo "   ${follow_in_std}"
   else 
      # copy dataset to temporary one - reused by multiple dset followers
      \rm -f tempfollow.nii.gz
      3dcopy "${followset}" tempfollow.nii.gz

      # Move center of follower with same 1D shift as original dataset.
      # Funny that the opt has '_inv', but that appears to be correct!
      @Align_Centers -overwrite                       \
          -no_cp                                      \
          -base "${base_dset}"                        \
          -dset tempfollow.nii.gz                     \
          -shift_xform_inv ${imed}/${srcsh2_shft}

      if ( "$align_type" == "all" ) then
          # apply NL warp
          3dNwarpApply  -overwrite                                       \
              -ainterp ${follow_interp}                                  \
              -prefix  ${follow_in_std}                                  \
              -nwarp  "${imed}/${srcsh2_prefix}_osh2base_WARP.nii.gz"    \
              -source  tempfollow.nii.gz                                 \
              -master  "${base_dset}"

          if ( ${status} ) then
             echo "** ERROR: program failed (follower data, 1)"
             exit 1
          endif
      else 
          3dAllineate -overwrite                                         \
              -final   ${follow_interp}                                  \
              -prefix  ${follow_in_std}                                  \
              -1Dmatrix_apply "${imed}/${srcsh2_prefix}_al2std_mat.aff12.1D" \
              -source  tempfollow.nii.gz                                 \
              -master "${base_dset}"

          if ( ${status} ) then
             echo "** ERROR: program failed ($align_type follower data, 1)"
             exit 1
          endif
      endif
 
      if ( "${follow_interp}" == "NN" ) then
         # keep propagating labels/atlases
         3drefit -copytables "${followset}" ${follow_in_std}
         3drefit -cmap INT_CMAP             ${follow_in_std}

         echo "++ Created follower ROI dset: ${follow_in_std}"

         if ( "${modesmooth}" != "0") then
            # save the unsmoothed version as a backup
            3dcopy -overwrite         \
                ${follow_in_std}      \
                ${imed}/${follow_in_std_pre}

            if ( ${DO_MODE_SMOO_W_REP} ) then
               # Modal smoothing *with* replacement; output has
               # INT_CMAP and tables copied
               @djunct_modal_smoothing_with_rep                            \
                    -overwrite  ${DO_ECHO}                                 \
                    -input      ${imed}/${follow_in_std_pre}               \
                    -prefix     ${follow_in_std}                           \
                    -modesmooth $modesmooth 
            else
               # Standard modal smoothing (*no* replacement)
               3dLocalstat -overwrite                                      \
                    -stat   mode                                           \
                    -nbhd   "SPHERE(-${modesmooth})"                       \
                    -prefix ${follow_in_std}                               \
                    ${imed}/${follow_in_std_pre}

               # make these show up in AFNI as labeled ROI or atlas datasets 
               3drefit -copytables ${followset} ${follow_in_std}
               3drefit -cmap INT_CMAP ${follow_in_std}

               if ( ${status} ) then
                  echo "** ERROR: program failed (foll data, 2: ${followset})"
                  exit 1
               endif

            endif
         endif

         echo "   ... and finished processing it"
         
      else if ( "${follow_interp}" == "wsinc5" ) then
         echo "++ Created follower dset: ${follow_in_std}"
      else 
         echo "** ERROR: how is the interp value: ${follow_interp}?"
         exit 1
      endif
   endif

   # final part, for text file info
   if ( "${follow_interp}" == "NN" ) then
      printf "%-37s : %s\n"                                \
               "Follower ROI dset, warped to base"         \
               "${follow_in_std}"                          \
             >> ${animal_outs}
   else if ( "${follow_interp}" == "wsinc5" ) then
      printf "%-37s : %s\n"                         \
               "Follower dset, warped to base"      \
               "${follow_in_std}"                   \
            >> ${animal_outs}
   else 
      echo "** ERROR: how is the interp value: ${follow_interp}?"
      exit 1
   endif
end

# -------------------------------------------------------------------------
# ------------------ pre-APPLY_WARP base2orig|base2osh --------------------

# Now handle the inverse transformed data - template and atlases to
# native space.

# ---------------------------- useful vars --------------------------------

set t_in_o_prefix   = ${base_abbrev}_in_${src_abbrev}
set templ_in_orig   = ${t_in_o_prefix}.nii.gz
set templ_in_origA  = ${t_in_o_prefix}_aniso.nii.gz
set templ_in_origAC = ${t_in_o_prefix}_aniso_clust.nii.gz
set templ_in_origG  = ${t_in_o_prefix}.gii

# ---------------- APPLY_WARP base2orig|base2osh: BASE dset ----------------

# apply base2osh warp (and osh2orig shft vec, by default)

if ( ($ok_to_exist == "1") && \
     (-f  ${templ_in_orig} ) ) then
   echo "++ Reusing template transformed to native space dataset"
else 
   if ( "$align_type" == "all" ) then
       # warp to orig+shft space
       3dNwarpApply -overwrite                                   \
         -ainterp wsinc5                                         \
         -nwarp  "${imed}/${srcsh2_prefix}_base2osh_WARP.nii.gz" \
         -source "${base_dset}"                                  \
         -master ${imed}/${srcsh2_dset}                          \
         -prefix ${templ_in_orig}

       if ( ${status} ) then
          echo "** ERROR: program failed (3dNwarpApply, base2osh, 1)"
          exit 1
       endif
   else 
       3dAllineate -overwrite                                              \
           -final   wsinc5                                                 \
           -1Dmatrix_apply "${imed}/${srcsh2_prefix}_inv_al2std_mat.aff12.1D" \
           -source "${base_dset}"                                          \
           -master ${imed}/${srcsh2_dset}                                  \
           -prefix ${templ_in_orig}

       if ( ${status} ) then
          echo "** ERROR: program failed ($align_type 3dAllineate, base2osh, 1)"
          exit 1
       endif
   endif

   # put back in non-shifted version (really native space); default
   if (${center_out} == "native") then
      # Move center of dset with the INV of the original shift.  Funny
      # that the opt has '_inv', but this appears to be correct!
      @Align_Centers -overwrite                       \
          -no_cp                                      \
          -base ${src_dset}                           \
          -dset ${templ_in_orig}                      \
          -shift_xform_inv ${imed}/${srcsh2_shft_inv}

      if ( ${status} ) then
         echo "** ERROR: program failed (base2osh 2)"
         exit 1
      endif

   endif 

   # Return original dataset view (to view in AFNI)
   3drefit -space ${origspace}  ${templ_in_orig}

   # Note: image made below, after skull-stripping applied to make
   # focus mask.
endif

# --------------- APPLY_WARP base2orig|base2osh: BRAINMASK ---------------

# apply base2osh warp (and osh2orig shft vec, by default); or, created
# a brain mask

if ( ($ok_to_exist == "1") &&              \
     (-f  ${src_abbrev}_ns.nii.gz) &&  \
     (-f  ${src_abbrev}_mask.nii.gz) ) then
   echo "++ Reusing masked original/input dset"
else
   # [BTJ: Mar 29, 2020] template mask-based brainmasking code
   if (${brainmask} != "") then
      if ( ($ok_to_exist == "1") && \
           (-f  ${src_abbrev}_mask.nii.gz) ) then
         echo "++ Reusing template transformed to native space dataset"
      else
         if ( "$align_type" == "all" ) then
             # warp to orig+shft space
             3dNwarpApply -overwrite                                  \
               -ainterp NN                                            \
               -short                                                 \
               -nwarp "${imed}/${srcsh2_prefix}_base2osh_WARP.nii.gz" \
               -source ${brainmask}                                   \
               -master ${imed}/${srcsh2_dset}                         \
               -prefix ${src_abbrev}_mask.nii.gz

             if ( ${status} ) then
                echo "** ERROR: program failed (base2osh, brainmask)"
                exit 1
             endif
         else 
             set amat = "${imed}/${srcsh2_prefix}_inv_al2std_mat.aff12.1D"
             3dAllineate -overwrite                                          \
                 -final   NN                                                 \
                 -1Dmatrix_apply "${amat}"                                   \
                 -source ${brainmask}                                        \
                 -master ${imed}/${srcsh2_dset}                              \
                 -prefix ${src_abbrev}_mask.nii.gz

             if ( ${status} ) then
                echo "** ERROR: program failed ($align_type 3dAllineate base2osh, brainmask)"
                exit 1
             endif
         endif

         # put back in non-shifted version (really native space);
         # default
         if (${center_out} == "native") then
            # put back in non-shifted version (really native space)
            @Align_Centers                                  \
                -no_cp                                      \
                -base ${src_dset}                           \
                -dset ${src_abbrev}_mask.nii.gz             \
                -shift_xform_inv ${imed}/${srcsh2_shft_inv}

            if ( ${status} ) then
               echo "** ERROR: program failed (base2osh, brainmask 2)"
               exit 1
            endif

         endif

         # Return original dataset view (to view in AFNI)
         3drefit -space ${origspace} ${src_abbrev}_mask.nii.gz
      endif
   else
      3dcalc \
         -a      ${templ_in_orig}                         \
         -b      ${src_abbrev}.nii.gz                     \
         -expr   'step(a)*b'                              \
         -prefix ${imed}/__tmp_orig_mskd.nii.gz           \
         -overwrite

      if ( ${status} ) then
         echo "** ERROR: program failed (base2osh, brainmask, B1)"
         exit 1
      endif

      # smoothify mask with in/out dilations; slightly pad: this is our
      # new anat mask.
      3dmask_tool                                \
         -dilate_inputs -2 3                     \
         -inputs ${imed}/__tmp_orig_mskd.nii.gz  \
         -prefix ${src_abbrev}_mask.nii.gz       \
         -overwrite

      if ( ${status} ) then
         echo "** ERROR: program failed (base2osh, brainmask, B2)"
         exit 1
      endif

   endif

   3dcalc \
      -a       ${src_abbrev}.nii.gz             \
      -b       ${src_abbrev}_mask.nii.gz        \
      -expr    'a*step(b)'                      \
      -prefix  ${src_abbrev}_ns.nii.gz          \
      -overwrite

   if ( ${status} ) then
      echo "** ERROR: program failed (base2osh brainmask 4)"
      exit 1
   endif

   # Image   : [ulay] orig dset; [olay] edges of warped template
   set olay  = "${templ_in_orig}"
   set ulay  = "${src_abbrev}.nii.gz"
   set focus = "${src_abbrev}_mask.nii.gz"
   set opref = QC/${qc01}${src_add}

    @djunct_edgy_align_check                  \
        -olay              ${olay}            \
        -box_focus_slices  ${focus}           \
        -ulay              ${ulay}            \
        -prefix            ${opref}           \
        -save_ftype        PNG                \
        -montx 5 -monty 3                     \
        -montgap 1                            \
        -montcolor 'black'

   # Image   : [ulay] orig dset [olay] mask of orig dset
   set ulay  = ${src_abbrev}.nii.gz
   set olay  = ${src_abbrev}_mask.nii.gz
   set focus = ${olay}
   set opref = QC/${qc02}${src_add}

   @chauffeur_afni                            \
       -ulay "${ulay}"                        \
       -ulay_range_nz 0% 98%                  \
       -set_subbricks 0 0 0                   \
       -olay "${olay}"                        \
       -box_focus_slices "${focus}"           \
       -cbar RedBlueGreen                     \
       -montgap 1                             \
       -montcolor 'black'                     \
       -pbar_posonly                          \
       #-pbar_saveim ${opref}                  \
       -prefix      ${opref}                  \
       -opacity 3                             \
       -montx 5 -monty 3                      \
       -set_xhairs OFF                        \
       -label_mode 1 -label_size 4

   # clean up a bit
   \rm -f ${imed}/__tmp_orig_mskd.nii.gz

endif

# [PT: Jan 14, 2020] add these to the output text
printf "%-37s : %s\n"                        \
        "Mask of input"                      \
        "${src_abbrev}_mask.nii.gz"          \
       >> ${animal_outs}

printf "%-37s : %s\n"                        \
        "Input (orig), no skull"             \
        "${src_abbrev}_ns.nii.gz"            \
       >> ${animal_outs}

# Make unifized form of original (skullstripped) dset
if ( ($ok_to_exist == "1") &&              \
     (-f  ${src_abbrev}_nsu.nii.gz) ) then
   echo "++ Reusing skullstripped+unifized original/input dset"
else

   echo "++ Unifizing input dset in input/source space"
   3dUnifize -overwrite                   \
      -GM                                 \
      -clfrac 0.4                         \
      -Urad   14                          \
      -input  ${src_abbrev}_ns.nii.gz     \
      -prefix ${src_abbrev}_nsu.nii.gz

   if ( ${status} ) then
      echo "** ERROR: program failed (nsu)"
      exit 1
   endif
endif

printf "%-37s : %s\n"                      \
        "Input (orig), no skull, unifized" \
        "${src_abbrev}_nsu.nii.gz"         \
       >> ${animal_outs}

echo "" >> ${animal_outs}

# -------- APPLY_WARP base2orig|base2osh: TEMPLATE followers (floats) ------

# apply base2osh warp (and osh2orig shft vec, by default)

foreach ii ( `seq 1 1 ${#template_followers}` )

   set template_dset   = "${template_followers[$ii]}"
   set template_prefix = "${template_abbrevs[$ii]}"

   set template_in_orig = ${template_prefix}_in_${src_abbrev}.nii.gz

   if ( ($ok_to_exist == "1") && \
        (-f  ${template_in_orig} ) ) then
      echo "++ Reusing template transformed to native space dataset:"
      echo "   ${template_in_orig}"
   else
      if ( "$align_type" == "all" ) then
          # warp to orig+shft space
          3dNwarpApply -overwrite                                  \
            -short                                                 \
            -ainterp wsinc5                                        \
            -nwarp "${imed}/${srcsh2_prefix}_base2osh_WARP.nii.gz" \
            -source ${template_dset}                               \
            -master ${imed}/${srcsh2_dset}                         \
            -prefix ${template_in_orig}

          if ( ${status} ) then
             echo "** ERROR: program failed (base2osh templ foll, ${template_dset})"
             exit 1
          endif
      else 
          set amat = "${imed}/${srcsh2_prefix}_inv_al2std_mat.aff12.1D"
          3dAllineate -overwrite                                     \
              -final   wsinc5                                        \
              -1Dmatrix_apply "${amat}"                              \
              -source ${template_dset}                               \
              -master ${imed}/${srcsh2_dset}                         \
              -prefix ${template_in_orig}

          if ( ${status} ) then
             echo "** ERROR: program failed ($align_type base2osh templ foll, ${template_dset})"
             exit 1
          endif
      endif

      # put back in non-shifted version (really native space) 
      if (${center_out} == "native") then
        @Align_Centers                                         \
            -no_cp                                             \
            -base ${src_dset}                                  \
            -dset ${template_in_orig}                          \
            -shift_xform_inv ${imed}/${srcsh2_shft_inv}
      endif

      # Return original dataset view (to view in AFNI)
      3drefit -space ${origspace} ${template_in_orig}
   endif

   printf "%-37s : %s\n"                          \
            "Template follower in ${orig_fin}"    \
            "${template_in_orig}"                 \
        >> ${animal_outs}
end

 # ----------------------------------------------------------------------
 # Old Note (var names may be out of date):
 # 
 # this only warps back to the affine warped space (~ in template space)
 #    3dNwarpApply -ainterp NN -short -overwrite -nwarp \
 #       ${src_prefix}_WARPINV.nii.gz  -overwrite \
 #       -source $segset -master ${src_prefix}_aff.nii.gz \
 #       -prefix ${segname}_in_${src_abbrev}.nii.gz
 # moves data to orig space - but introduces second interpolation
 # on nearest neighbor ROI data, this can make for odd artifacts
 #    3dAllineate -source ${segname}_in_${src_abbrev}.nii.gz \
 #       -base ${src_abbrev}.nii.gz \
 #    	-final NN \
 #    -1Dmatrix_apply ${src_abbrev}_composite_linear_to_template_inv.1D \
 #        -prefix ${segname}_in_${src_abbrev}.nii.gz
 # deletes the segmentation in affine warped space
 # ----------------------------------------------------------------------


# -------- APPLY_WARP base2orig|base2osh: ATL, SEG followers (int) ------

# apply base2osh warp (and osh2orig shft vec, by default)

# Loop over all atl and seg dsets that were entered; most of what
# happens is similar; only difference is that the ATL dsets will get
# isosurfaces generated

set all_tfollow  = ( )  
set all_tabbrev  = ( )
set all_ttypes   = ( )  

foreach ii ( `seq 1 1 ${#atlas_followers}` )
    set all_tfollow = ( ${all_tfollow} "${atlas_followers[$ii]}" )
    set all_tabbrev = ( ${all_tabbrev} "${atlas_abbrevs[$ii]}"   )
    set all_ttypes  = ( ${all_ttypes}  "ATL"   )
end
foreach ii ( `seq 1 1 ${#seg_followers}` )
    set all_tfollow = ( ${all_tfollow} "${seg_followers[$ii]}" )
    set all_tabbrev = ( ${all_tabbrev} "${seg_abbrevs[$ii]}"   )
    set all_ttypes  = ( ${all_ttypes}  "SEG"   )
end

foreach ii ( `seq 1 1 ${#all_tfollow}` )
   set iii = `printf "%02d" $ii`

   set segm_dset   = "${all_tfollow[$ii]}"
   set segm_prefix = "${all_tabbrev[$ii]}"
   set segm_type   = "${all_ttypes[$ii]}"

   # the main output
   set segm_in_orig = "${segm_prefix}_in_${src_abbrev}.nii.gz"
   # ... but if followset is int value AND is modally smoothed, then
   # save the pre-modally smoothed version under this name:
   set segm_in_orig_pre = "${segm_prefix}_in_${src_abbrev}_PRE.nii.gz"


   if ( ( $ok_to_exist == "1" ) && \
        ( -f  ${segm_in_orig} ) ) then
       echo "++ Reusing ${segm_type} in native space: ${segm_in_orig}"
   else
       if ( "$align_type" == "all" ) then
           # warp to orig+shft space
           3dNwarpApply -overwrite                                   \
              -ainterp NN                                            \
              -short                                                 \
              -nwarp "${imed}/${srcsh2_prefix}_base2osh_WARP.nii.gz" \
              -source ${segm_dset}                                   \
              -master ${imed}/${srcsh2_dset}                         \
              -prefix ${segm_in_orig}

           if ( ${status} ) then
              echo "** ERROR: program failed (base2osh atl/seg foll)"
              echo "   ... for dset: ${segm_dset}"
              exit 1
           endif
       else 
           set amat = "${imed}/${srcsh2_prefix}_inv_al2std_mat.aff12.1D"
           3dAllineate -overwrite                                     \
               -final   NN                                            \
               -1Dmatrix_apply "${amat}"                              \
               -source ${segm_dset}                                   \
               -master ${imed}/${srcsh2_dset}                         \
               -prefix ${segm_in_orig}

           if ( ${status} ) then
              echo "** ERROR: program failed ($align_type base2osh atl/seg foll)"
              echo "   ... for dset: ${segm_dset}"
              exit 1
           endif
       endif

       # put back in non-shifted version (really native space) 
       if ($center_out == "native") then
          @Align_Centers                                          \
            -no_cp                                                \
            -base ${src_dset}                                     \
            -dset ${segm_in_orig}                                 \
            -shift_xform_inv ${imed}/${srcsh2_shft_inv}
       endif

       # change the datum type to byte to save space if values
       # range from 0 to 255 this step also gets removes the shift
       # transform information in the header overwriting original
       # dataset just created
       set segminmax = `3dBrickStat         \
                            -min -max -slow \
                            ${segm_in_orig}`

       if ( (${segminmax[2]} <= 255) && \
            (${segminmax[1]} >= 0) ) then
          3dcalc -overwrite                                       \
            -a      ${segm_in_orig}                               \
            -expr   a                                             \
            -datum  byte                                          \
            -nscale                                               \
            -prefix ${segm_in_orig}

          if ( ${status} ) then
             echo "** ERROR: program failed (base2osh atl/seg foll, calc)"
             echo "   ... for dset: ${segm_dset}"
             exit 1
          endif

       endif

      # keep propagating labels/atlases
      3drefit -copytables "${segm_dset}" ${segm_in_orig}
      3drefit -cmap INT_CMAP             ${segm_in_orig}

       # modal smoothing
       if ( "${modesmooth}" != "0") then
          # save the unsmoothed version as a backup
          3dcopy -overwrite         \
              ${segm_in_orig}       \
              ${imed}/${segm_in_orig_pre}

          if ( ${status} ) then
             echo "** ERROR: program failed (base2osh atl/seg foll, cp)"
             echo "   ... for dset: ${segm_dset}"
             exit 1
          endif

          \rm ${segm_in_orig}

          # this extra step done here to make sure the space is
          # correct (should be, from 3dNwarp*?)
          3drefit                      \
              -space ${origspace}      \
              ${imed}/${segm_in_orig_pre}

          if ( ${DO_MODE_SMOO_W_REP} ) then
             # Modal smoothing *with* replacement; output has
             # INT_CMAP and tables copied
             @djunct_modal_smoothing_with_rep                            \
                  -overwrite  ${DO_ECHO}                                 \
                  -input      ${imed}/${segm_in_orig_pre}                \
                  -prefix     ${segm_in_orig}                            \
                  -modesmooth ${modesmooth} 

             if ( ${status} ) then
                echo "** ERROR: program failed (base2osh atl/seg foll, @dj)"
                echo "   ... for dset: ${segm_dset}"
                exit 1
             endif

          else
             # Standard modal smoothing (*no* replacement)
             3dLocalstat -overwrite                                      \
                  -stat   mode                                           \
                  -nbhd   "SPHERE(-${modesmooth})"                       \
                  -prefix ${segm_in_orig}                                \
                  ${imed}/${segm_in_orig_pre}

             if ( ${status} ) then
                echo "** ERROR: program failed (base2osh atl/seg foll, loc)"
                echo "   ... for dset: ${segm_dset}"
                exit 1
             endif

             # make these show up in AFNI as labeled ROI or atlas datasets 
             3drefit                      \
                 -cmap  INT_CMAP          \
                 ${segm_in_orig}
             3drefit                      \
                 -copytables ${segm_dset} \
                 ${segm_in_orig}

             if ( ${status} ) then
                echo "** ERROR: program failed (base2osh atl/seg foll, refit)"
                echo "   ... for dset: ${segm_dset}"
                exit 1
             endif
          endif
       endif

       # Image : [ulay] edge enhanced orig dset;
       #         [olay] atlas warped to orig space
       set ulay  = "${src_abbrev}.nii.gz"
       set olay  = "${segm_in_orig}"
       set focus = ${src_abbrev}_mask.nii.gz

       set nvi = `3dinfo -nvi "${olay}"`

       if ( "${nvi}" == "0" ) then
           set opref = QC/${qc03}_${segm_type}_${segm_prefix}${src_add}

           @chauffeur_afni                             \
                -ulay "${ulay}"                        \
                -edge_enhance_ulay 0.5                 \
                -set_subbricks 0 0 0                   \
                -olay "${olay}"                        \
                -box_focus_slices "${focus}"           \
                -montgap 1                             \
                -montcolor 'black'                     \
                -XXXnpane 2048                         \
                -func_range 2048                       \
                -cbar ROI_glasbey_2048                 \
                -pbar_posonly                          \
                -pbar_saveim "${opref}"                \
                -prefix      "${opref}"                \
                -opacity 5                             \
                -montx 5 -monty 3                      \
                -set_xhairs OFF                        \
                -label_mode 1 -label_size 4
       else
          foreach nn ( `seq 0 1 ${nvi}` )
             set nnn   = `printf %02d ${nn}`
             set opref = QC/${qc03}_${segm_type}_${segm_prefix}_${nnn}
             set opref = ${opref}${src_add}

             @chauffeur_afni                             \
                  -ulay "${ulay}"                        \
                  -edge_enhance_ulay 0.5                 \
                  -set_subbricks 0 ${nn} ${nn}           \
                  -olay "${olay}"                        \
                  -box_focus_slices "${focus}"           \
                  -montgap 1                             \
                  -montcolor 'black'                     \
                  -XXXnpane 2048                         \
                  -func_range 2048                       \
                  -cbar ROI_glasbey_2048                 \
                  -pbar_posonly                          \
                  -pbar_saveim "${opref}"                \
                  -prefix      "${opref}"                \
                  -opacity 5                             \
                  -montx 5 -monty 3                      \
                  -set_xhairs OFF                        \
                -label_mode 1 -label_size 4
          end
       endif
   endif

   if ( "${segm_type}" == "SEG" ) then
        printf "%-37s : %s\n"                                  \
                "Seg follower in ${orig_fin}"                  \
                "${segm_in_orig}"                              \
            >> ${animal_outs}
   else if ( "${segm_type}" == "ATL" ) then
        printf "%-37s : %s\n"                                  \
                "Atlas follower in ${orig_fin}"                \
                "${segm_in_orig}"                              \
            >> ${animal_outs}
   endif

   # ---------------- report info on atl/seg vols --------------------

   if ( -f ${segm_in_orig} ) then
      # each atl dset could have multiple subbricks, like the
      # CHARM atlas for macaques
      set nvi = `3dinfo    \
                     -nvi  \
                     ${segm_in_orig}`

      foreach nn ( `seq 0 1 ${nvi}` ) 

           set report    = QC/report_${segm_prefix}.1D
           set surf_dir  = surfaces_${segm_prefix}
           if ( ${nvi} > 0 ) then
               set nnn      = `printf %02d ${nn}`
               set surf_dir = ${surf_dir}_${nnn}
               set report   = QC/report_${segm_prefix}_${nnn}.1D
           endif
           set surf_path = surfaces/${surf_dir}

           # reports on sizes of ROIs *after* warping, relative to
           # those values *before* warping
           adjunct_aw_tableize_roi_info.py   \
                "${report}"                  \
                "${segm_in_orig}[${nn}]"     \
                "${src_abbrev}_mask.nii.gz"  \
                "${segm_dset}[${nn}]"        \
                "${base_mask_for_reps}"      \
                "${modesmooth}"

           # ------- isosurfs in native space: only for ATLAS followers

           if ( ${status} ) then
              echo "** ERROR: program failed (base2osh atl/seg foll, table)"
              echo "   ... for dset: ${segm_in_orig}"
              exit 1
           endif

           if ( ( $make_orig_surfaces == "1" ) && \
                ( -f ${segm_in_orig} ) ) then

              \rm -rf   ${surf_path}
              \mkdir -p ${surf_path}

              cd ${surf_path}

              IsoSurface                               \
                  -isorois+dsets                       \
                  -o native.gii                        \
                  -input ../../${segm_in_orig}"[$nn]"  \
                  -noxform                             \
                  -Tsmooth 0.01 6

              cd -

              # [PT: Oct 16, 2020] put in SEG/ATL separately
              if ( "${segm_type}" == "SEG" ) then
                 printf "%-37s : %s\n"                     \
                     "Seg follower surfs in ${orig_fin}"   \
                     "${surf_path}"                        \
                     >> ${animal_outs}
              else if ( "${segm_type}" == "ATL" ) then
                 printf "%-37s : %s\n"                     \
                     "Atlas follower surfs in ${orig_fin}"   \
                     "${surf_path}"                        \
                     >> ${animal_outs}
              endif

# a script to view all surfs together
set oscript = surfaces/do_view_${surf_dir}.tcsh
printf "" >  ${oscript}
cat <<EOF >> ${oscript}
#!/bin/tcsh

# All files are defined here relative to the "surfaces/" directory
# that originally contained this script.  This can be adapted to other
# cases, by adjusting the two variables defined at the top of the
# script.

set bkgd_vol = "../${src_abbrev}_nsu.nii.gz"
set surf_dir = ${surf_dir}

suma                               \
    -onestate                      \
    -i    \${surf_dir}/native*.gii  \
    -vol "\${bkgd_vol}" &

EOF
chmod 755 ${oscript}
           endif
      end
   endif
end


# --------------- TEMPLATE SURFACE: in native space -------------------

if ( $make_orig_surfaces == "1" ) then

   # [PT: July 9, 2021] this needed in case no followers above used
   \mkdir -p surfaces

   # "carve" out template surface in native space instead to use
   #  as representative surface using anisotropic smoothing could
   #  use skullstripped original instead
   if ( ($ok_to_exist == "1") && \
        (-f  ${imed}/${templ_in_origA} ) ) then
      echo "++ Reusing anisotropically smoothed template"
      echo "   in native space dataset"
   else
      3danisosmooth -overwrite                                    \
        -prefix ${imed}/${templ_in_origA}                         \
        -automask                                                 \
        -3D                                                       \
        -iters 6                                                  \
        -matchorig                                                \
        ${templ_in_orig}

      if ( ${status} ) then
         echo "** WARNING: program failed (templ surf, anisosmoo)"
      endif
   endif

   # also remove any  small clusters for surface generation
   #  (threshold here is specific so may need tweaking)
   set baseperc   = 15
   set basestats  = `3dBrickStat                                 \
                        -percentile $baseperc 1 $baseperc        \
                        -non-zero                                \
                        ${imed}/${templ_in_origA}`
   if ( ${status} ) then
      echo "** WARNING: program failed (templ surf, brickstat)"
   endif

   set basethresh = $basestats[2]

   # non-zero count not right with percentile, so doing it
   # separately here
   set basestats2      = `3dBrickStat                  \
                                 -max -count -non-zero \
                                 ${imed}/${templ_in_origA}`
   set basemax         = $basestats2[1]
   set minbrainvolume  = `ccalc -int "${basestats2[2]}*0.5"`

   if ( ($ok_to_exist == "1") && \
        (-f  ${imed}/${templ_in_origAC} )) then
      echo "++ Reusing anisotropically smoothed and clustered template"
      echo "   in native space dataset"
   else
      3dClusterize                                              \
        -idat 0 -ithr 0                                         \
        -1sided RIGHT_TAIL ${basethresh}                        \
        -pref_dat ${imed}/${templ_in_origAC}                    \
        -inset    ${imed}/${templ_in_origA}                     \
        -NN 2                                                   \
        -clust_nvox  ${minbrainvolume}

      if ( ${status} ) then
         echo "** WARNING: program failed (templ surf, clust)"
      endif
   endif

   if ( ($ok_to_exist == "1") && \
        (-f  surfaces/${templ_in_origG} ) ) then
      echo "++ Reusing template in native space surface dataset"
   else
      IsoSurface -overwrite                                  \
        -isorange ${basethresh} ${basemax}                   \
        -input    ${imed}/${templ_in_origAC}                 \
        -o        surfaces/${templ_in_origG}                 \
        -noxform                                             \
        -Tsmooth 0.01 6

      if ( ${status} ) then
         echo "** WARNING: program failed (templ surf, isosurf)"
      endif
   endif

   printf "%-37s : %s\n"                                     \
            "Templ surf in ${orig_fin}"                      \
            "surfaces/${templ_in_origG}"                     \
        >> ${animal_outs}


   # move in to surfaces/ subdir for this step!
   cd surfaces

# a script to view all surfs together
set oscript = do_view_isosurf_${t_in_o_prefix}.tcsh
printf "" >  ${oscript}
cat <<EOF >> ${oscript}
#!/bin/tcsh
    
    set bkgd_vol = "../${src_dset}"
    set dset_gii = "${templ_in_origG}"

    suma                        \
        -onestate               \
        -i   \${dset_gii}        \
        -vol \${bkgd_vol} &

EOF
chmod 755 ${oscript}

   cd -

endif

# ------------------------------ Clean up ----------------------------

# get rid of temporary warped datasets
if ( "${keep_temp}" != "1") then
   \rm -rf "${awpy_dir}/"
   \rm -f `\ls __tmp*`
   \rm -f tempfollow.nii*
   echo "++ Done cleaning up."
endif

# --------------------------- Finish and exit ----------------------------

# finish outputs and exit gracefully: normal exit for default proc
goto FINISH_OUTS

# -------------------------------------------------------------------------
# Old Note (out of date variables....)
#
# zeropad the warp if segmentation doesn't cover the brain, and
# reapply the warp:
# 3dZeropad -S 50 -prefix ${src_prefix}_zp_WARP.nii.gz \
#   ${src_prefix}_WARP.nii.gz
# 3dNwarpApply -interp NN \
#   -nwarp "${src_prefix}_inv.aff12.1D INV(${src_prefix}_zp_WARP.nii.gz)" \
#   -source $segset -master $dset -prefix ${src_prefix}_seg_zp
# 3drefit -cmap INT_CMAP ${src_prefix}_seg_zp${origview}
# 3drefit -copytables $segset ${src_prefix}_seg_zp${origview}
# ---------------------------------------------------------------------------

HELP:

cat << SCRIPT_HELP_STRING

Overview ~1~

This is a script to:
+ align a subject structural dataset to a template
+ save the warp + inverse warps, for any future mapping
+ apply the warps to "follower" datasets in either space (e.g.,
  atlases, segmentations, masks, or other anatomicals) to map those
  dsets to the other space
  - one common use: send a template atlas to native space
+ estimate surfaces of ROIs (with scripts also made to simplify viewing)
+ make automatic QC images to show the outputs, for quick evaluation

This @animal_warper (AW) program uses basic AFNI commands to compute
affine and nonlinear alignments. The program works by first aligning
centers of the subject to that of the template. Affine and nonlinear
alignment follow. The inverse warp is computed to bring the template
and atlas segmentation into the center-shifted grid. Skullstripping is
provided by masking with the template. Finally, the grids are adjusted
back to the original center. Surfaces are made for all the atlas
regions and for a transformed copy of the template dataset.

Throughout this help file and output text files, note that the
following terminology applies:

    AP    =  afni_proc.py
    AW    =  @animal_warper

    xform =  transform
    NL    =  nonlinear
    aff   =  affine

    orig  =  'original' (or native) subject data and/or space
    base  =  template and/or template space
    osh   =  original subject data/space shifted to base
    pshft =  pre-shift (simple center of mass shift) to base
    shft  =  'full' shift (includes aff align) to base
    warp2std = a dset now warped to standard/template space (from original)


Usage Example ~1~

  animal_warper                                          \
      -input  macaque1+orig                              \
      -base   ../NMT.nii.gz                              \
      -atlas  atlas_dir/D99_atlas_1.2a_al2NMT.nii.gz     \
      -outdir aligned_data

   Note only the input dset and template_dset are *required*. If no
   "-atlas .." dset is given, then only the alignment steps are
   performed.

   Note also that you might want to include the "-ok_to_exist" flag,
   in case you need to restart the command at some point, and want to
   make use of previously created datasets (to save time).


Options ~1~

  -input input_dset   :required input dataset to align to base template
                       (what is called the 'source' in other AFNI
                       alignment programs).

  -base base_dset     :required dataset. Can be given with a normal
                       path-specification, or by just being somewhere
                       that @FindAfniDsetPath can find it.  Note,
                       this volume will also be used to try to
                       skullstrip in the input dset (unless an
                       explicit '-brainmask ..' dset is input; see
                       that option below).

  -template_prefix TP :*no longer an option*.  See/use '-base_abbrev',
                       below.

  -outdir outputdir   :create new directory and do all processing there.
                       Minor note: '.' is not allowed;  that is, you must 
                       choose a new directory.  NB: the input, base and 
                       any atlas followers get copied into that directory
                       (def = '${outdir}')

  -skullstrip brainmask
                      :one can provide a brainmask that is in the
                       base template space. This brainmask will be
                       warped back to native space and used to
                       skullstrip the original volume. This dataset
                       should share exactly the same grid as the
                       base template dataset.  (If this opt isn't
                       used to provide a brainmask, then the '-base
                       ..' volume itself will be used to do so.)

  -atlas ATL1 ATL2 ATL3 ...
  -atlas_followers ATL1 ATL2 ATL3 ...
                      :either of these option flags does the exact
                       same thing-- one or more atlas (int-valued)
                       dsets in the *base* volume space can be
                       provided, and each will be mapped to the
                       input dset's native space.  Atlas labeling
                       will be preserved. Additionally, isosurfaces
                       of each that can be viewed in SUMA will be
                       created.  Atlas locations can be given with a
                       normal path-specification, or by just being
                       somewhere that @FindAfniDsetPath can find it.

  -seg_followers S1 S2 S3 ...
                      :one or more (int-valued) dsets in the *base*
                       volume space can be provided, and each will
                       be mapped to the input dset's native space.
                       Must share the same grid of the base
                       dataset. Atlas labeling will be preserved.
                       different than the atlas_followers above (no
                       surfaces generated for these).

  -template_followers T1 T2 T3 ...
                      :one or more dsets in the *base* volume space
                       can be provided, and each will be mapped to
                       the input dset's native space.  Not required
                       to be int-valued here.

  -dset_followers D1 D2 D3 ...
                      :one or more dsets in the *input* volume space
                       can be provided, and each will be mapped to
                       the base dset's template space.  Not required
                       to be int-valued here.

  -roidset_followers dset1 dset2 ...
                      :one or more (int-valued) dsets in the *input*
                       volume space can be provided, and each will
                       be mapped to the base dset's template space.

  -input_abbrev INP_ABBR
                      :when a dset DSET is warped to a space, it
                       will like DSET_in_SOMETHING.nii.gz.  If that
                       SOMETHING is the input dset space, then you
                       can specify that label/abbreviation here.
                       The INP_ABBR is also used for some files as 
                       SOMETHING_*.
                       Default naming will be to use the prefix of
                       the input dset, such as would come from:
                         3dinfo -prefix_noext INPUT_DSET
                       Created file names can be quite long due to this,
                       so an INP_ABBR might be useful.

  -base_abbrev BASE_ABBR
                      :used just like the '-input_abbrev ..' value 
                       above, but for the base dset.
                       Default here is to use the space information
                       from a dset, namely:
                          3dinfo -space BASE_DSET
                       See also the '-use_known_abbrev_*' options
                       for being able to let this program try to
                       recognize a commonly known dset from its name.

  -atlas_abbrevs AA1 AA2 AA3 ...
                      :used just like the '-input_abbrev ..' value
                       above, but for the atlas follower dsets.  NB:
                       you either need to have the same number of
                       atlas abbreviations as input atlas followers,
                       or none.
                       Default abbreviation is:  
                         3dinfo -prefix_noext ATLAS_DSET
                       See also the '-use_known_abbrev_*' options
                       for being able to let this program try to
                       recognize a commonly known dset from its name.

  -template_abbrevs TA1 TA2 TA3 ...
                      :used just like the '-atlas_abbrevs ..' opt
                       above, but for the template follower dsets.  
                       Default abbreviation is:  
                         3dinfo -prefix_noext TEMPLATE_DSET
                       Has the same 'known' list as the base abbrevs, 
                       so make sure you don't run into having two files
                       share the same abbrev!

  -seg_abbrevs SA1 SA2 SA3 ...
                      :used just like the '-atlas_abbrevs ..' opt
                       above, but for the seg follower dsets.  
                       Default abbreviation is:  
                         3dinfo -prefix_noext SEG_DSET
                       Has no 'known' abbrevs.

  -dset_abbrevs DA1 DA2 DA3 ...
                      :used just like the '-atlas_abbrevs ..' opt
                       above, but for the dset follower dsets.  
                       Default abbreviation is:  
                         3dinfo -prefix_noext DSET_DSET
                       Has no 'known' abbrevs.

  -roidset_abbrevs RA1 RA2 RA3 ...
                      :used just like the '-atlas_abbrevs ..' opt
                       above, but for the dset follower dsets.  
                       Default abbreviation is:  
                         3dinfo -prefix_noext ROIDSET_DSET
                       Has no 'known' abbrevs.

  -use_known_abbrev_base
                      :try to 'guess' an appropriate abbreviation
                       for a base dset as processing proceeds, for
                       naming created dsets.  Shares same list of
                       knowns as the 'template' followers.

  -use_known_abbrev_atlas
                      :try to 'guess' an appropriate abbreviation
                       for an atlas dset as processing proceeds, for
                       naming created dsets.  

  -use_known_abbrev_template
                      :try to 'guess' an appropriate abbreviation
                       for a template follower dset as processing
                       proceeds, for naming created dsets.  Shares
                       same list of knowns as the 'base'.

  -use_known_abbrev_ALL
                      :like using all the other '-use_known_abbrev*' 
                       opts.

  -align_centers_meth ACM
                      :By default, an early step here is to use
                       "Align_Centers -grid .." to start the
                       alignment (align centers of grids).  If you
                       want to, you can enter any of the "Center
                       options" that @Align_Centers permits by using
                       the given option in place of "ACM" *without*
                       the preceding minus (e.g. a useful one might
                       be: cm).  
                       You can also provide the keyword "OFF" as an
                       argument, and then @Align_Centers won't be
                       run at all (the dset is just copied at that
                       step), which is useful if you have already
                       centered your dataset nicely.

  -aff_move_opt AMO   :by default, '-giant_move' is used in the affine
                       alignment step (via align_epi_anat.py). With this
                       option, you can change the movement type to be
                       any of the values allowed by align_epi_anat.py---
                       note that you should *not* include the hyphen from
                       the align_epi_anat.py option name, and if the option
                       takes two terms, then you should put it in quotes, 
                       such as: "cmass cmass"  (default: "giant_move").
                       A special value of "OFF" means that none of these
                       extra movement options is included (e.g., your
                       input dset overlaps the base VERY well already).

  -cost xxx           :choose a cost function for affine and nonlinear
                       alignment. The same or similar cost function
                       will be used for both alignments. The cost
                       functions are listed in the help for
                       3dAllineate and 3dQwarp.  Cost functions,
                       like lpa+ZZ for 3dAllineate, are not
                       available in 3dQwarp, so the "+ZZ" part would
                       removed from the NL part of warping (i.e.,
                       lpa would then be used for 3dQwarp's NL
                       warping cost function). The default cost
                       function is lpa+ZZ for affine warping (via
                       align_epi_anat.py and 3dAllineate) and a
                       clipped Pearson correlation for nonlinear
                       warping (via auto_warp.py and 3dQwarp)

  -maxlev nn          :maximum level for nonlinear warping. Determines 
                       final neighborhood 'patch' size that is
                       matched+refined. Allowed values are:
                           0 <= nn <= 11
                       See 3dQwarp help for information on maxlev. 
                       Use smaller values for faster performance and
                       testing. Increase up to 11 for finer warping.
                       (def = ${maxlev})

  -no_surfaces        :do not make surfaces for atlas regions in native
                       space. Default is to create a surface directory
                       with surfaces of each region in native space.

  -feature_size mm    :set size in mm for affine alignment. Use about 0.1
                       for mouse, 0.5 for macaque or rat. (def: 0.5)

  -supersize          :allow for up to 50% size difference between subject
                       and template

  -init_scale  IS     :useful if the input dset is much larger or smaller
                       than the reference template.  'IS' is the approximate
                       length ratio of the input to the template.  So, if 
                       you align a baby shark (doo doo, doo doo doo doo) 
                       brain to an adult shark template brain, you might 
                       use this option with a value of 0.75, for example.

  -mode_smooth_size n :modal smoothing kernel size in voxels (not mm)
                       This determines the size of a spatial regularization
                       neighborhood for both ROI followers and segmentation
                       datasets. Voxel values are replaced with the mode
                       (most common value) in the spherical neighborhood.
                       The default uses a 1 voxel radius. Use higher values
                       depending on the irregularities of the edges of the
                       regions and ROI 
                       Turn off by setting this to 0

  -mode_smooth_replacement_off
                      :the current default behavior for modal
                       smoothing is to do both 1) modal smoothing
                       (with 3dLocalstat) and then 2) check if any
                       ROIs got lost in that process, and 3) if ROIs
                       got lost, put them back in (those specific
                       ones won't be smoothed, just re-placed).
                       Using this opt will mean that steps #2 and #3
                       do NOT happen -- you just get plain modal
                       smoothing without replacement.

  -center_out CO      :center native-space output to native original 
                       space or to center-shifted space over the center
                       of template.  Allowed values of CO are 'native' 
                       (def, leaves center at original location)
                       and 'center_shift' (shift the input toward base,
                       and calculate all other warps and outputs to/from
                       there).
                       ****Note using the center_out native data
                       transformations might require extra care.
                       3dNmatrix_apply may require vast amounts of memory
                       if the center of the original dataset is far from
                       the center of the template dataset, usually around
                       an xyz coordinate of 0,0,0. 
                       If datasets are far from a center around 0,0,0,
                       then consider using 
                         3drefit -oblique_recenter
                         3drefit -oblique_recenter_raw
                       or a preprocessing center alignment for all the
                       native space datasets
                         @Align_Centers -base template -dset mydset \
                          -child dset2 dset3 ...

  -align_type   AT    :provide alignment only to specified level, of which  
                       your choices are:
                         rigid       - align using rotation and translation
                         rigid_equiv - compute alignment with full
                                       affine but apply only the rigid
                                       parameters.  This is usually
                                       preferred over the rigid body
                                       alignment because it handles
                                       different sizes better. The
                                       purpose here is to put data
                                       into approximately the same
                                       position as the template
                                       (AC-PC, axialized, ...)
                         affine      - full affine, 12 parameters
                                       rotation, translation, shearing and 
                                       scaling
                         all         - go through affine and nonlinear warps
                                       (default)
                       In each case the full script runs.  However, note that
                       the detail of alignment (and quality of masking) from
                       less-than-nonlinear warps will necessarily be more 
                       approximate.

 -extra_qw_opts "EQO" :specify other options to add on to the
                       existing options for 3dQwarp either as a group
                       of options in quotes as in "-nopenalty
                       -workhard 0:3" or by repeated use of this
                       option. 3dQwarp is called indirectly using
                       auto_warp.py.

  -keep_temp          :keep temporary files including awpy directory (from
                       auto_warp.py) and other intermediate datasets

  -ver                :display program version

  -ok_to_exist        :reuse and do not overwrite existing datasets.
                       This option is used for faster restarts or with
                       limited alignment options

  -echo               :copy all commands being run into the terminal 
                       (like running 'tcsh -x ...')


Outputs (we got plenty of 'em!) ~1~

  @animal_warper provides multiple outputs to assist in registering
  your anatomicals and associated MRI data to the template.  Below,
  INP refers to the abbreviation used to refer to the "-input .."
  subject dset, and TEM to that of the "-base .." template
  (typically in some standard space).

  Main datasets ~2~

    The following are all contained in the main output directory
    ("-outdir ..")

    + Text file "dictionary" reference of outputs
      o animal_outs.txt         - guide to data in main dir and subdirs;
                                  contains version number and history of 
                                  command run

    + Subject scans in native space of input
      o INP.nii.gz              - copy of original input
      o INP_ns.nii.gz           - same as above, but "no skull" (ns) version
      o INP_nsu.nii.gz          - same as above, but also unifized (brightness)
      o INP_mask.nii.gz         - mask of input (should match "ns" version)
      o DSET_FOLL               - copy(s) of "-dset_followers .." (not abbrev)
      o ROIDSET_FOLL            - copy(s) of "-roidset_followers .." (not 
                                  abbrev)

    + Template scans in native space of input 
      o TEM_in_INP.nii.gz       - template aligned to input

    + Template followers (e.g., atlas ATL, segmentation SEG) in native
      space of input; could be several of each, each with own abbreviation
      o ATL_in_INP.nii.gz       - "-atlas_followers .." aligned to input
      o SEG_in_INP.nii.gz       - "-seg_followers .." aligned to input


    + Template dsets and followers in template space
      o TEMPLATE                - copy of "-template .." (not abbrev)
      o TEMPLATE_MASK           - copy of "-skullstrip .." mask (not abbrev)
      o ATL_FOLL                - copy(s) of "-atlas_followers .." (not abbrev)
      o SEG_FOLL                - copy(s) of "-seg_followers .." (not abbrev)
      o TEMPLATE_FOLL           - copy of "-template_followers .." (not abbrev)

    + Subject scans mapped to the template
      o INP_warp2std.nii.gz     - input dset nonlinearly warped to TEM
      o INP_warp2std_ns.nii.gz  - same as above, but "no skull" version
      o INP_warp2std_nsu.nii.gz - same as above, but also unifized (brightness)

    + Alignment data (INP->TEM)
      o INP_composite_linear_to_template.1D - matrix, full affine part
      o INP_shft_WARP.nii.gz    - NL warp part (TEM grid)

    + Alignment data (TEM->INP)
      o INP_composite_linear_to_template_inv.1D - matrix, full affine part
      o INP_shft_WARPINV.nii.gz - NL part of warp (TEM grid)

  QC info ~2~

    The following are all contained in the "QC/" subdirectory.

    The following quality control (QC) images are automatically
    generated during processing, to help with speedy checking of
    processing.  In each case, there are three sets of PNG montages
    (one for sag, cor and axi views) and a copy of the colorbar used
    (same prefix as file name, *.jpg).  Additionally, there is also a
    *.txt file of ranges of values related to the ulay and olay, which
    might be useful for QC or figure-generation.

    + ${iqc00}*.jpg, [init_qc_00_*_DEOB*]
      [ulay] input source dset, original location
      [olay] base dset
      o single image montage to check initial overlap of source and base,
        ignoring any obliquity that might be present (i.e., the way AFNI 
        GUI does by default, and also how alignment starts)
      o if initial overlap is not strong, alignment can fail or
        produce weirdness
      o *if* either dset has obliquity, then an image of both after 
        deobliquing with 3dWarp is created (*DEOB.jpg), and a text file
        about obliquity is also created (*DEOB.txt).

    + ${iqc01}*.jpg
      [ulay] input source dset, center-shifted location
      [olay] base dset

    + ${iqc01b}*.jpg   (only created if using '-init_scale ..')
      [ulay] same as previous ulay, but with init_scale value applied
      [olay] base dset

    + ${iqc02}*.jpg
      [ulay] input source dset, affine-aligned to base
      [olay] base dset

    + ${iqc03}*.jpg
      [ulay] input source dset, NL-aligned to base
      [olay] base dset

    + ${qc00}* (in base space)
      [ulay] edges of the base dset
      [olay] warped input dset

    + ${qc01}* (in input space)
      [ulay] edges of the (warped) base dset
      [olay] original input dset

    + ${qc02}* (in input space)
      [ulay] input dset 
      [olay] estimated (or input) mask, showing skullstripping

    + ${qc03}_{ATL,SEG}* (in input space)
      [ulay] 'edge enhanced' original input dset
      [olay] warped atlas or seg dset 
      o NB: if the olay dset has >1 subbrick, each will be snapshotted
            separately, because I heard the baying of the crowds for
            such.

    Additionally, if follower datasets are used (e.g., mapping atlases
    from template to subject space), then report*1D text files are
    also output, detailing information about ROIs before and after
    mapping.

    + report_{ATL,SEG}*.1D 
      o this text file includes both absolute and relative volumes, as
        well as ratios of volumes.  Additionally, one can see if any
        ROIs got lost in the mapping process (e.g., were too small or
        narrow, got squeezed too much or fell outside the mask).
      o this text file can be viewed in a regular text editor and also
        used for calculations with AFNI programs
      o each report calculated separately for each subbrick of an
        input ATL or SEG

  Surfaces generated ~2~

    (Unless you turn off surface estimate) there will be a "surfaces/"
    directory with full sets of ROI surfaces calculated from the
    '-atlas_follower ..' and '-seg_follower ..' dsets.

    + surfaces_{ATL,SEG}*/
      o full set of surfaces of each region in the respective dset
      o if the atlas has >1 subbrick (e.g., the CHARM), then each 
        subbrick will have its own subdir

    + do_view_surfaces_{ATL,SEG}*.tcsh
      o automatically generated script to view the contents of each 
        surfaces_{ATL,SEG}*/ directory in SUMA

    + TEM_in_INP.gii
      o slightly polished surface of the warped template in input
        space

    + do_view_isosurf_TEM_in_INP.tcsh
      o automatically generated script to view TEM_in_INP.gii in SUMA


  Intermediate results directory ~2~

    There is an "intermediate/" directory with lots of intermediate
    warps, affine transforms and datasets.  

    *If* you are supremely confident about your outputs, you can
    remove this directory to save space.  **But** you should probably
    only do so if you really need to, because invariably once you
    delete it you will need to check something from it.  That's just
    life.

    This directory is useful to keep around for asking questions,
    checking alignment (esp. checking if something went wrong),
    potentially debugging (not my fault!), etc.

    Comments ~2~

    All atlas_points and labeltables on all input dsets should be
    passed along to their warped versions, preserving those useful
    functionalities and information.


Integrating AW with afni_proc.py (AP) ~1~

  Let's say that you plan to run AW as a prelude to processing FMRI
  data with AP (a good idea, by the way!).  

  This might be an example AW command (written with variables in ye
  olde 'tcsh' style):

    set anat_subj = sub-001_anat.nii.gz                   # input anat
    set refvol    = NMT_*_SS.nii.gz                       # ref: template
    set refatl    = CHARM*.nii.gz                         # ref: atlas
    set odir_aw   = dir_aw/sub-001                        # output dir

    @animal_warper                           \
        -input  \${anat_subj}                \
        -base   \${refvol}                   \
        -atlas  \${refatl}                   \
        -outdir \${odir_aw}                  \
        -ok_to_exist

  If you are mapping your FMRI data to standard space and using the
  "tlrc" block in your AP command, then there are probably 4 main
  outputs from there that you would then put into every successive AP
  command, as well as using the same "refvol" and noting that your
  anatomical dset has already been skullstripped.  We highlight these
  in the following AP skeleton command (where the '...' means some
  other entries/options would likely be included; order doesn't matter
  for the AP command, but we are following the style in which most
  afni_proc.py help examples are written):

  |  # root of AW output dsets
  |  set anat_base = \`3dinfo -prefix_noext \${anat_subj}\`  
  |
  |  afni_proc.py                                                       \
  |      ...                                                            \
  |      -blocks  ... align tlrc volreg ...                             \
  |      ...                                                            \
  |      -copy_anat               \${odir_aw}/\${anat_base}_ns.nii.gz     \
  |      -anat_has_skull          no                                    \
  |      ...                                                            \
  |      -tlrc_base               \${refvol}                             \
  |      -tlrc_NL_warp                                                  \
  |      -tlrc_NL_warped_dsets                                          \
  |          \${odir_aw}/\${anat_base}_warp2std_nsu.nii.gz                \
  |          \${odir_aw}/\${anat_base}_composite_linear_to_template.1D  \
  |          \${odir_aw}/\${anat_base}_shft_WARP.nii.gz                 \
  |      ...

  In the preceding, please note the naming conventions in the *.1D
  affine matrix and *WARP.nii.gz nonlinear warp dset which are
  provided to the '-tlrc_NL_warped_dsets ..' option.


Examples ~1~

  1) Align a subject anatomical to the NMT template.  Use some
  'follower' datasets that are defined in the template space, so that
  they will be warped to subject space (there are other followers that
  can start in the native space and be warped to the standard space,
  too).  Use abbreviations with the followers to simplify life:

    @animal_warper                                                \
        -input             \${dir_anat}/anat-sub-000.nii.gz       \
        -input_abbrev      \${subj}_anat                          \
        -base              \${dir_ref}/NMT_*_SS.nii.gz            \
        -base_abbrev       NMT2                                   \
        -atlas_followers   \${dir_ref}/CHARM_*.nii.gz             \
        -atlas_abbrevs     CHARM                                  \
        -seg_followers     \${dir_ref}/NMT_*_segmentation.nii.gz  \
        -seg_abbrevs       SEG                                    \
        -skullstrip        \${dir_ref}/NMT_*_brainmask.nii.gz     \
        -outdir            odir_aw                                \
        -ok_to_exist 

  2) Just like the previous example, but include more followers and
  abbrevs:

    @animal_warper                                                \
        -input             \${dir_anat}/anat-sub-000.nii.gz       \
        -input_abbrev      \${subj}_anat                          \
        -base              \${dir_ref}/NMT_*_SS.nii.gz            \
        -base_abbrev       NMT2                                   \
        -atlas_followers   \${dir_ref}/CHARM_*.nii.gz             \
                           \${dir_ref}/D99_*.nii.gz               \
        -atlas_abbrevs     CHARM  D99                             \
        -seg_followers     \${dir_ref}/NMT_*_segmentation.nii.gz  \
        -seg_abbrevs       SEG                                    \
        -skullstrip        \${dir_ref}/NMT_*_brainmask.nii.gz     \
        -outdir            odir_aw                                \
        -ok_to_exist 

  3) Just like the previous example, but include followers (dset and
  roidset) from subject space:

    @animal_warper                                                \
        -input             \${dir_anat}/anat-sub-000.nii.gz       \
        -input_abbrev      \${subj}_anat                          \
        -base              \${dir_ref}/NMT_*_SS.nii.gz            \
        -base_abbrev       NMT2                                   \
        -atlas_followers   \${dir_ref}/CHARM_*.nii.gz             \
                           \${dir_ref}/D99_*.nii.gz               \
        -atlas_abbrevs     CHARM  D99                             \
        -seg_followers     \${dir_ref}/NMT_*_segmentation.nii.gz  \
        -seg_abbrevs       SEG                                    \
        -skullstrip        \${dir_ref}/NMT_*_brainmask.nii.gz     \
        -dset_followers    \${dir_anat}/anat-t2w-sub-000.nii.gz   \
        -dset_abbrevs      T2W                                    \
        -roidset_followers \${dir_anat}/parcels-sub-000.nii.gz    \
        -roidset_abbrevs   ROIS                                   \
        -outdir            odir_aw                                \
        -ok_to_exist 

Demos, Tutorials and Online Docs ~1~

  + See the MACAQUE_DEMO_* demos for examples in using the program, as
    well as integrating its outputs with afni_proc.py.  To download
    the demos for task-based FMRI and resting state FMRI analysis,
    respectively:

      @Install_MACAQUE_DEMO

      @Install_MACAQUE_DEMO_REST

    ... with accompanying webpages here:

      https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/nonhuman/macaque_demos/main_toc.html

  + For (growing) documentation on non-human dataset processing in
    AFNI, see:

      https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/nonhuman/main_toc.html

  + For information on accompanying templates and atlases in the
    animal kingdon (such as NMT, CHARM and SARM), as well as how to
    download them, please see here:

      https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/nonhuman/macaque_tempatl/main_toc.html


References ~1~

  If you use this program and/or the NMTv2, CHARM or ARM in your work,
  please cite the following:

  + Jung B, Taylor PA, Seidlitz PA, Sponheim C, Perkins P, 
    Ungerleider LG, Glen DR, Messinger A (2021). 
    A Comprehensive Macaque FMRI Pipeline and Hierarchical Atlas.
    NeuroImage 235:117997.
    https://doi.org/10.1016/j.neuroimage.2021.117997
    https://www.biorxiv.org/content/10.1101/2020.08.05.237818v1

  + Saad ZS, Glen DR, Chen G, Beauchamp MS, Desai R, Cox RW (2009). A
    new method for improving functional-to-structural MRI alignment
    using local Pearson correlation. Neuroimage 44 839–848. doi:
    10.1016/j.neuroimage.2008.09.037
    https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2649831/

  If you use the SARM or ARM atlas, please cite the following:

    R. Hartig, D. Glen, B. Jung, N.K. Logothetis, G. Paxinos,
    E.A. Garza-Villarreal, A. Messinger, H. Evrard (2021). The
    Subcortical Atlas of the Rhesus Macaque (SARM) for
    Neuroimaging. NeuroImage 235:117996.
    https://doi.org/10.1016/j.neuroimage.2021.117996.
    

  If you use the D99 atlas (warped to the NMT v2 in this
  repository), please cite the following:

    C. Reveley, A. Gruslys, F.Q. Ye, D. Glen, J. Samaha, B.E. Russ,
    Z. Saad, A.K.  Seth, D.A. Leopold, K.S. Saleem (2017).
    Three-Dimensional Digital Template Atlas of the Macaque
    Brain. Cereb. Cortex 27:4463-4477.
    https://doi.org/10.1093/cercor/bhw248.

This program has been written (and rewritten!) by D Glen and PA Taylor
(SSCC, NIMH, NIH, USA), with many helpful contributions and
suggestions from B Jung and A Messinger.

SCRIPT_HELP_STRING

   exit 0

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

FINISH_OUTS:

set stop_d   = `date +%Y-%m-%d`
set stop_H   = `date +%H`
set stop_M   = `date +%M`
set stop_S   = `date +%S`
set stop_VAL = "${stop_d} ${stop_H}:${stop_M}:${stop_S}"

echo "# finish    : ${stop_VAL}"   >>   log_cmd.txt


echo ""                                              >> ${animal_outs}
printf "%-37s : %s\n"                 \
        "QC directory of images"      \
        "QC/"                         \
       >> ${animal_outs}

printf "%-37s : %s\n"                 \
        "Info on atl/seg followers"   \
        "QC/report_*.1D"              \
       >> ${animal_outs}

printf "%-37s : %s\n"                 \
        "Scripts to view surfaces"    \
        "surfaces/do*.tcsh"           \
       >> ${animal_outs}

echo ""                                              >> ${animal_outs}
echo "Command : @animal_warper $argv"                >> ${animal_outs}

echo ""
echo "Highlights of the output"
echo "------------------------"
# show list of outputs
cat ${animal_outs}
echo ""
echo "-------------------------"
echo ""
echo "++ To check the output, go to:"
echo "  cd ${outdir}"
echo ""

exit 0





# -------------------------------------------------------------------------
# "functions"

ABBREV_CREATION_START:

if ( ${#generic_followers} ) then
    # user enters ALL abbrevs or NONE.
    if ( ${#generic_abbrevs} == ${#generic_followers} ) then
        echo "++ Using user-entered list of ${foll_type}_follower abbrevs"
    else if ( ${#generic_abbrevs} == 0 ) then
        echo "++ Making list of '${foll_type}_follower' abbrevs:"
        foreach ff ( ${generic_followers} ) 
            set ff_name = `3dinfo -prefix_noext "${ff}"` 
            printf "   ... ${ff_name}"
            if ( ${USE_KNOWN_GENERIC_ABBREV} ) then
                # go through our list of knowns
                foreach aa ( ${all_known_generic_abbrev} )
                    set gcount = `echo "${ff_name}" | grep -c "${aa}"`
                    if ( "${gcount}" != "0" ) then
                        set ff_name = "${aa}"
                        break
                    endif
                end
            endif
            printf " --> ${ff_name}\n"
            set generic_abbrevs = ( ${generic_abbrevs} "${ff_name}" )
        end
    else
        echo "** ERROR:"
        echo "   The number of ${foll_type}_follower"
        echo "   abbrevs (${#generic_abbrevs}) must be 0 or match the"
        echo "   number of ${foll_type}_followers (${#generic_followers})"
        exit 1
    endif
endif

if ( "${foll_type}" == "atlas" ) then
    goto ABBREV_CREATION_END_ATLAS
else if ( "${foll_type}" == "template" ) then
    goto ABBREV_CREATION_END_TEMPLATE
else if ( "${foll_type}" == "seg" ) then
    goto ABBREV_CREATION_END_SEG
else if ( "${foll_type}" == "dset" ) then
    goto ABBREV_CREATION_END_DSET
else if ( "${foll_type}" == "roidset" ) then
    goto ABBREV_CREATION_END_ROIDSET
else
    echo "** Someone forgot to code a new type here"
    exit 1
endif





