#!/usr/bin/env python

from afnipy import afni_util          as UTIL
from afnipy import lib_format_cmd_str as lfcs
import copy

# ----------------------------------------------------------------------
# This is a library for storing basic information regarding options and
# examples for afni_proc.py.
#
#    - examples are stored as individual dictionaries
#    - examples from afni_proc.py -help are created by:
#       - set noglob
#       - add '-optlist_show_argv_array dict' to command
#
#    - for a given example, want:
#       - name (e.g. Example 11) - want case insensitive checking
#       - source (from help, from AFNI_data6, etc.)
#       - description
#       - header  (before the example in verbose -help output)
#       - trailer (after  the example in verbose -help output)
#       - keywords = []; e.g. 'obsolete', 'complete', 'registration'. 'ME',
#                             'surface', 'rest', 'task', 'physio'
#                             ('noshow' : default to not showing with help)
#
# --------------------------
# preferred option ordering: 
#
#   - id and script specs
#   - EPI data and specs, including blip
#   - anat data and specs (followers)
#   - non-block data inputs
#   - block order (-blocks)
#   - general block options (e.g. -radial_correlate_blocks)
#   - block ordered options (e.g. -blur_size)
#      -surf dests go in surf block section
#      -blip dsets do not go in blip block section (as not user specified)
#   -regress order:
#       ROI (regs of interest), opts_3dD, polort, bandpass,
#       motion, AICOR/RONI (regs of no interest), censoring,
#       non-reg opts (3dD_stop, reml_exec, then post-reg options)

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


# ----------------------------------------------------------------------
# main array of APExample instances
# (will rename later to _old and examples)
ap_examples = []
ap_examples_new = []

# ----------------------------------------------------------------------
# class definition for instances in ap_examples array
class APExample:
   def __init__(self, name, olist, source='', descrip='', moddate='UNKNOWN',
                header='', trailer='', keywords=[]):
      self.name     = name          # used to reference example
      self.source   = source        # from AP help, AD6, etc.
      self.descrip  = descrip       # very short description
      self.moddate  = moddate       # most recent modification date
      self.header   = header        # shown before example (in -help)
      self.trailer  = trailer       # shown after example (in -help)
      self.keywords = keywords      # list:

      self.keys     = []            # convenience: olist[][0] entries
      self.olist    = olist         # list of options [opt, [params]]
      self.aphelp   = (source == 'afni_proc.py -help')

      if not self.valid_olist():
         return None

      self.keys = [o[0] for o in olist]

   def valid_olist(self):
      valid = 1
      for oind, opt in enumerate(self.olist):
         if len(opt) != 2:
            print("** APExample '%s' olist #%d needs opt and list, have:\n" \
                  "   %s" % (self.name, oind, opt))
            valid = 0
            continue
         if type(opt[0]) != str:
            print("** APExample '%s' olist #%d should start with string:\n" \
                  "   %s" % (self.name, oind, opt))
            valid = 0
         if type(opt[1]) != list:
            print("** APExample '%s' olist #%d should have a list:\n" \
                  "   %s" % (self.name, oind, opt))
            valid = 0
      return valid

   def copy(self, quotize=0):
      """return a deep copy
            quotize - if set, quotize any needed option parameters
      """
      cc = copy.deepcopy(self)

      if quotize:
         for entry in cc.olist:
            entry[1] = UTIL.quotize_list(entry[1])

      return cc

   def compare(self, target, eskip=[], verb=1):
      """compare against some target, which can be a 'name' string
         or another APExample instance

         for any key in eskip, do not print all details of element differences
      """
      itarg = self.find_instance(target, verb=verb)
      if itarg is None:
         return

      return self.compare_v_instance(itarg, eskip=eskip, verb=verb)

   def find_instance(self, target, verb):
      """target might already be an instance, but allow for a string,
         possibly with spaces, to be found as an example name

         on error, return None
      """
      if isinstance(target, APExample):
         return target

      # target must be either an instance or a string
      if type(target) != str:
         print("** find_instance: target not instance or string, %s" % target)
         return None

      # otherwise, try to find an instance in the ap_examples list
      eg = find_eg(target)
      # if not found, try replacing any '_' with ' '
      if eg is None and target.find('_') >= 0:
          eg = find_eg(target.replace('_', ' '))

      # success
      if eg is not None:
         if verb > 2:
            print("-- found instance for target string '%s'" % target)
         return eg

      # failure
      print("** find_instance : failed for target '%s'" % target)
      return None

   def compare_v_instance(self, target, eskip=[], verb=1):
      """compare against another APExample instance

            -show missing, extra and different categories

            target  can be name (string) or APExample instance
            eskip list of keys for which elements should not be compared
            verb    0 - use short list notation
                    1 - show missing, extra and diffs
                    2 - show diffs, but after trying to remove paths
                    3 - include all parameter lists
      """
      print("="*75)
      print("==== comparing (current) '%s' vs (target) '%s'" \
            % (self.name, target.name))
      if verb == 1:
         print('     (for more detail, consider "-verb 2")')
      print("")

      # use more generic name
      source = self

      # get global max key len
      maxs = max([len(key) for key in source.keys])
      maxt = max([len(key) for key in target.keys])
      maxk = max(maxs, maxt)

      # first look for missing and extra
      emiss =  [e for e in target.olist if e[0] not in source.keys]
      eextra = [e for e in source.olist if e[0] not in target.keys]

      # common keys, might be fewer, more, and/or have diffs
      efewer = []   # fewer of keys than target
      emore = []    # more than keys than target
      pdiff = []    # index pairs, where keys are the same but lists differ
      ncommon = 0

      # loop over unique keys, counting number in both key lists
      uniq_target_keys = UTIL.get_unique_sublist(target.keys)

      # rcr - right now, options of the same name need to be in the same order
      #       to be equal, we could try to remove the requirement...

      for key in uniq_target_keys:

         if key not in source.keys: continue

         ksource = [ind for ind, e in enumerate(source.olist) if e[0]==key]
         ktarget = [ind for ind, e in enumerate(target.olist) if e[0]==key]

         # how many of each?  both must be positive
         nsource = len(ksource)
         ntarget = len(ktarget)

         # get any efewer or emore entries
         if nsource < ntarget:
            efewer.extend([target.olist[ktarget[ind]] \
                          for ind in range(nsource,ntarget)])
         elif ntarget < nsource:
            emore.extend([source.olist[ksource[ind]] \
                         for ind in range(ntarget,nsource)])

         # get matching e[0]'s where e[1]'s differ
         ncomp = min(nsource, ntarget)
         ncommon += ncomp
         for ind in range(ncomp):
            # rcr - should we separate path diffs from true diffs here?
            if source.olist[ksource[ind]] != target.olist[ktarget[ind]]:
               # just store source and target indices here
               pdiff.append([ksource[ind], ktarget[ind]])

      nindent = 3
      ind1 = ' '*nindent
      ind2 = ' '*(2*nindent)

      # possibly print compact output
      if verb == 0:
         print("== missing (%d): %s\n" % (len(emiss),  [e[0] for e in emiss ]))
         print("== extra   (%d): %s\n" % (len(eextra), [e[0] for e in eextra]))
         print("== fewer   (%d): %s\n" % (len(efewer), [e[0] for e in efewer]))
         print("== more    (%d): %s\n" % (len(emore),  [e[0] for e in emore ]))
         print("== common  (%d - with %d differing)\n" % (ncommon, len(pdiff)))
         print("== diffs   (%d): %s\n" % (len(pdiff),
                                       [source.olist[p[0]][0] for p in pdiff ]))
         return

      # more verbose output allows for full printing
      if verb > 1: lmax = 0
      else:        lmax = 45

      print("==========  missing option(s) : %d" % len(emiss))
      if len(emiss) > 0:
         for e in emiss:
             estr = ' '.join(e[1])
             self._print_opt_lin(ind1, e[0], maxk, estr, lmax=lmax)
      print("")

      print("==========  extra option(s) : %d" % len(eextra))
      if len(eextra) > 0:
         for e in eextra:
             estr = ' '.join(e[1])
             self._print_opt_lin(ind1, e[0], maxk, estr, lmax=lmax)
      print("")

      print("==========  differing option(s) : %d" % len(pdiff))
      if len(pdiff) > 0:
         samestr = '  : SAME, but path diff (skipping details)'
         skips = []
         for pair in pdiff:
             oname = source.olist[pair[0]][0]
             if oname in eskip and verb < 2:
                # only show skipping details once
                if oname in skips:
                   continue
                skips.append(oname)

                # if only path diff, say so
                if self.depath_lists_equal(source.olist[pair[0]][1],
                                           target.olist[pair[1]][1]):
                   print("%s%-*s%s" % (ind1, maxk, oname, samestr))
                else:
                   print("%s%-*s  (verb=1; skipping details)" \
                         % (ind1, maxk, oname))

             elif verb <= 2:
                # try to remove any paths
                kslist = self.depath_list(source.olist[pair[0]][1])
                ktlist = self.depath_list(target.olist[pair[1]][1])
                ksstr = ' '.join(kslist)
                ktstr = ' '.join(ktlist)
                # if removing paths makes them the same, say so
                if ksstr == ktstr:
                    print("%s%-*s%s" % (ind1, maxk, oname, samestr))
                else:
                    print("%s%-*s" % (ind1, maxk, oname))
                    self._print_diff_line(ind2, 'current', ksstr, lmax=lmax)
                    self._print_diff_line(ind2, 'target',  ktstr, lmax=lmax)
             else:
                # full details
                print("%s%-*s" % (ind1, maxk, oname))

                ksstr = ' '.join(source.olist[pair[0]][1])
                ktstr = ' '.join(target.olist[pair[1]][1])
                self._print_diff_line(ind2, 'current', ksstr, lmax=lmax)
                self._print_diff_line(ind2, 'target',  ktstr, lmax=lmax)
             print("")

      print("==========  fewer applied option(s) : %d" % len(efewer))
      if len(efewer) > 0:
         for e in efewer:
             estr = ' '.join(e[1])
             self._print_opt_lin(ind1, e[0], maxk, estr, lmax=lmax)
      print("")

      print("==========  more applied option(s) : %d" % len(emore))
      if len(emore) > 0:
         for e in emore:
             estr = ' '.join(e[1])
             self._print_opt_lin(ind1, e[0], maxk, estr, lmax=lmax)
      print("")

      print("")

   def merge_w_instance(self, target, eskip=[], verb=1):
      """merge with another APExample instance

         Expand the current instance with options in the target.

         For each option in the target:

            if it exists in current
              ignore (for repeated options, do we require all?)
            else
              add (if in eskip, prepend -CHECK)

         Do not need much verb, since we can compare opts afterwards.

         return 0 on success
      """

      # use more generic name
      source = self

      if verb > 2: print("-- merge_w_instance() ..., target %s" % target)

      # be sure we have an instance, and not a string
      target = self.find_instance(target, verb=verb)
      if target is None:
         return 1

      # loop over unique keys, counting number in both key lists
      uniq_target_keys = UTIL.get_unique_sublist(target.keys)

      for key in uniq_target_keys:

         # ignore if already in current (ponder repeated options?)
         if key in source.keys:
            if verb > 2:
               print("-- skip already applied, %s" % key)
            continue

         # key is missing in source, so add all such target options to source

         # make note of all target options
         # ksource = [ind for ind, e in enumerate(source.olist) if e[0]==key]
         ktarget = [ind for ind, e in enumerate(target.olist) if e[0]==key]
         ntarget = len(ktarget)

         # if the key is in eskip, modify the option name with prefix -CHECK
         prefix = ''
         if key in eskip:
            if verb > 2:
               print("-- add with prefix, %s" % key)
            prefix = '-CHECK'
         else:
            if verb > 2:
               print("-- add directly, %s" % key)

         # for each such option, duplicate, possibly modify, and insert
         for ind in range(ntarget):
            newopt = copy.deepcopy(target.olist[ktarget[ind]])
            if prefix:
               newopt[0] = prefix+newopt[0]
            source.olist.append(newopt)

         # and add the new key, without prefix
         source.keys.append(key)

      return 0

   def depath_lists_equal(self, list0, list1):
       """if we depath_list() both lists, are they equal"""
       kslist = self.depath_list(list0)
       ktlist = self.depath_list(list1)
       ksstr = ' '.join(kslist)
       ktstr = ' '.join(ktlist)

       return (ksstr == ktstr)

   def depath_list(self, arglist):
       """return a copy of arglist, removing anything up to each final '/'
       """
       # rfind returns the highest index of '/', else -1
       # --> so always start at the return index+1
       newlist = [s[s.rfind('/')+1:] for s in arglist]

       return newlist

   def _print_opt_lin(self, indent, oname, maxlen, parstr, lmax=50):
       """if lmax > 0: restrict parstr to given length, plus ellipsis
       """
       estr = ''
       kprint = parstr
       if lmax > 0:
          if len(parstr) > lmax:
             kprint = parstr[0:lmax]
             estr = ' ...'

       print("%s%-*s  %s%s" % (indent, maxlen, oname, kprint, estr))

   def _print_diff_line(self, indent, tstr, parstr, lmax=50):
       """if lmax > 0: restrict parstr to given length, plus ellipsis
       """
       estr = ''
       kprint = parstr
       if lmax > 0:
          if len(parstr) > lmax:
             kprint = parstr[0:lmax]
             estr = ' ...'

       print("%s%-8s : %s%s" % (indent, tstr, kprint, estr))

   def command_string(self, wrap=0, windent=8):
      """return a string that is an afni_proc.py command
            if wrap: - return indented command
                     - indent by windent
      """

      # minor format conversion to a list of lists per line
      newolist = [['afni_proc.py']] + [([o[0]] + o[1]) for o in self.olist]

      # set default left-padding and line length
      if wrap:
         leftstr = ' '*windent
         linewid = 78
         is_diff, str_nice = lfcs.afni_niceify_cmd_str('',
                                                       comment_start=leftstr,
                                                       max_lw=linewid,
                                                       big_list=newolist)
      else:
         # join nested list into single string
         str_nice = ' '.join([' '.join(entry) for entry in newolist])

      return str_nice

   def display(self, verb=0, sphinx=1):
      """display a single example - use a copy for quoting
         verb: verbosity level
           0: only show example, with no wrap or formatting
           1: include name, source, descrip
           2: full verbosity: as ap -help: include descrip, header, trailer
              - terminate descrip with ~2~, for sphinxificaiton

         ponder indentation
      """
      cc = self.copy(quotize=1)

      # handle verb 0 right away, as the command string will differ
      if verb == 0:
         print("%s" % cc.command_string())
         return

      cmd = cc.command_string(wrap=1)

      indent = ' '*8

      if sphinx: sstr = ' ~2~'
      else:      sstr = ''

      # possibly show the name/description line,
      # (with trailing ~2~ for sphinx help)
      if verb > 0:
         print("%s%s. %s%s" % (indent, cc.name, cc.descrip, sstr))

      # header
      if verb > 1:
         print("%s" % cc.header)
         print("%s--------------------------" % indent)
         print("%slast mod date : %s" % (indent, cc.moddate))
         print("%skeywords      : %s" % (indent, ', '.join(cc.keywords)))
         print("%s--------------------------" % indent)

      print("")

      # print the actual example
      print("%s" % cmd)

      # any trailer
      if verb > 1 and cc.trailer != '':
         print("%s" % cc.trailer)

      print("")

      del(cc)


def get_all_examples():
   """return all known examples"""

   examples = []

   examples.extend(egs_example())
   examples.extend(egs_class())
   examples.extend(egs_demo())
   examples.extend(egs_short())
   examples.extend(egs_publish())

   return examples


def populate_examples(keys_keep=[], keys_rm=[], verb=1):
   """only populate the examples array if someone wants it

        keys_keep : if not empty, keep only entries with any of these keywords
        keys_rm   : if not empty, remove entries with any of these keywords
                    - default to 'noshow', those examples not shown by default
                      with the -help output

      populate the global ap_examples array from some of the egs_* functions
   """

   global ap_examples

   if len(ap_examples) > 0:
      return

   # use a local name to populate the global list
   examples = get_all_examples()

   # keys_keep = ['task', 'surface']
   # keys_rm   = ['obsolete', 'surface']

   if verb > 2:
      show_example_keywords(examples, mesg='initial examples')

   # --------------------------------------------------
   # keep only those entries with at least one of the given keep keys
   if len(keys_keep) > 0:
      newex = []
      for key in keys_keep:
         for ex in examples:
            if key in ex.keywords:
               if ex not in newex:
                  newex.append(ex)

      examples = newex

      if verb > 2:
         show_example_keywords(examples, mesg='post-keep examples')

   # --------------------------------------------------
   # remove any entry with any given rm key
   poplist = []
      # counting from the end, pop unwanted indices
   for eind, eg in enumerate(examples):
      # if there is any bad key, add to poplist and break
      for key in keys_rm:
         if key in eg.keywords:
            poplist.append(eg)
            break
   # remove everything in poplist
   if len(poplist) > 0:
      examples = [e for e in examples if e not in poplist]

   ap_examples = examples

def show_example_keywords(elist, mesg='', verb=1):
   """
   """
   if mesg: mstr = '(%s) ' % mesg
   else:    mstr = ''

   if len(elist) == 0:
      print("-- %d examples %s:" % (len(elist), mstr))
      print()
      return

   # special cases, get all keywords, and show a unique list
   if 'ALL' in elist:
      elist = get_all_examples()

   # if being quiet just show a compact key list
   if verb <= 1:
      # now python has a strange left to right reading to nest 2 lists
      klist = [e for ex in elist for e in ex.keywords]
      klist = UTIL.get_unique_sublist(klist)
      klist.sort()
      print('   ' + '\n   '.join(klist))
      return

   # else verbose, so show all examples and their keys
   print("-- %d examples %s:" % (len(elist), mstr))
   # align ':' using max name length
   nlen = max([len(ex.name) for ex in elist])
   for ex in elist:
      print("    %-*s : %s" % (nlen, ex.name, ', '.join(ex.keywords)))
   print()

def egs_ap_run(keys_keep=[], keys_rm=[]):
   """
            ***** this is probably garbage *****

      only populate the examples array if someone wants it

      return an array of APExample objects

       # sample example generation
       sample = APExample( 'my help example name',
         source='place to find this example in use',
         descrip='short description w/name in help output',
         moddate='1946.02.30',
         header='''
                  (recommended?  no, not intended for a complete analysis)
                  (              merely shows how simple a command can be)

               Purpose of this command, shown before example command.
               ''',
         trailer='''Any parts to show after the example command.''',
         olist = [
            ['-dsets',                 ['epiRT*.HEAD']],
            ['-regress_stim_files',    ['stims.1D']],
            # any other needed options
           ],
         )

   """

   examples = []

   examples.append( APExample( 'run_ap FT',
     source='ap_run_simple_rest.tcsh on class subject FT',
     descrip='Basic example to generate APQC for quick review.',
     moddate='2023.12.18',
     keywords=['rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (            * might be done immediately after acquisition)

           This example was generated by running ap_run_simple_rest.tcsh,
           providing a single subject anat and (3 runs of) EPI.  It could
           be generated (and run) using the following:

              cd AFNI_data6/FT_analysis/FT
              ap_run_simple_rest.tcsh -subjid FT -run_proc \\
                -anat FT_anat+orig -epi FT_epi_r*.HEAD
           """,
     trailer="""
           This quick processing will generate results in a new FT.results
           directory, which contains the APQC HTML report under QC_FT (where
           FT is the subject ID).  The report can be viewed using:

              afni_open -b FT.results/QC_FT/index.html

           or using interactive afni and niivue:

              open_apqc.py -infiles FT.results/QC_FT/index.html

           """,
     olist = [
        ['-subj_id',                 ['FT.run_ap']],
        ['-script',                  ['proc.FT.run_ap']],
        ['-out_dir',                 [ 'FT.1.results']],
        ['-blocks',                  [ 'tshift', 'align', 'tlrc', 'volreg',
                                       'mask', 'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', [ 'tcat volreg']],
        ['-copy_anat',               [ 'FT_anat+orig']],
        ['-dsets',                   [ 'FT_epi_r1+orig.HEAD',
                'FT_epi_r2+orig.HEAD', 'FT_epi_r3+orig.HEAD']],
        ['-tcat_remove_first_trs',   [ '2']],
        ['-align_unifize_epi',       [ 'local']],
        ['-align_opts_aea',          [ '-cost lpc+ZZ -giant_move -check_flip']],
        ['-tlrc_base',               [ 'MNI152_2009_template_SSW.nii.gz']],
        ['-volreg_align_to',         [ 'MIN_OUTLIER']],
        ['-volreg_align_e2a',        []],
        ['-volreg_tlrc_warp',        []],
        ['-volreg_compute_tsnr',     [ 'yes']],
        ['-mask_epi_anat',           [ 'yes']],
        ['-blur_size',               [ '6']],
        ['-regress_apply_mot_types', [ 'demean deriv']],
        ['-regress_motion_per_run',  []],
        ['-regress_censor_motion',   [ '0.25']],
        ['-regress_censor_outliers', [ '0.05']],
        ['-regress_est_blur_epits',  []],
        ['-regress_est_blur_errts',  []],
        ['-regress_make_ideal_sum',  [ 'sum_ideal.1D']],
        ['-html_review_style',       [ 'pythonic']],
       ],
     ))

   examples.append( APExample('simple align orig EPI',
     source='basic example',
     descrip='Perform orig space alignment to EPI base.',
     moddate='2023.12.18',
     keywords=['registration'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (            - only to do basic registration to EPI base)

           Align the anat and EPI time series to the EPI MIN_OUTLIER volume.
           The regress block is included merely to provide extra QC.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',                 ['FT.align.orig']],
        ['-blocks',                  [ 'align', 'volreg', 'regress']],
        ['-dsets',                   [ 'FT_epi_r1+orig.HEAD',
                'FT_epi_r2+orig.HEAD', 'FT_epi_r3+orig.HEAD']],
        ['-tcat_remove_first_trs',   ['2']],
        ['-align_unifize_epi',       [ 'local']],
        ['-align_opts_aea',          [ '-cost lpc+ZZ -giant_move -check_flip']],
        ['-volreg_align_to',         [ 'MIN_OUTLIER']],
        ['-html_review_style',       [ 'pythonic']],
       ],
     ))

   return examples

def egs_example():
   """general "Example" list, corresponding to the 2023 list"""

   examples = []

   examples.append( APExample( 'Example 1',
     source='afni_proc.py -help',
     descrip='Minimum use.',
     moddate='2008.12.10',
     keywords=['obsolete', 'task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              merely shows how simple a command can be)

           Provide datasets and stim files (or stim_times files).  Note that a
           dataset suffix (e.g. HEAD) must be used with wildcards, so that
           datasets are not applied twice.  In this case, a stim_file with many
           columns is given, where the script to changes it to stim_times files.
           """,
     trailer=""" """,
     olist = [
        ['-dsets',                 ['epiRT*.HEAD']],
        ['-regress_stim_files',    ['stims.1D']],
       ],
     ))

   examples.append( APExample('Example 2',
     source='afni_proc.py -help',
     descrip='Very simple.',
     moddate='2009.05.28',
     keywords=['obsolete', 'task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              many missing preferences, e.g. @SSwarper)

           Use all defaults, except remove 3 TRs and use basis
           function BLOCK(30,1).  The default basis function is GAM.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['sb23.e2.simple']],
        ['-dsets',                 ['sb23/epi_r??+orig.HEAD']],
        ['-tcat_remove_first_trs', ['3']],
        ['-regress_stim_times',    ['sb23/stim_files/blk_times.*.1D']],
        ['-regress_basis',         ['BLOCK(30,1)']],
       ],
     ))

   examples.append( APExample('Example 3',
     source='afni_proc.py -help',
     descrip='Formerly a simple class example.',
     moddate='2009.05.28',
     keywords=['obsolete', 'task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              many missing preferences, e.g. @SSwarper)

           Copy the anatomy into the results directory, register EPI data to
           the last TR, specify stimulus labels, compute blur estimates, and
           provide GLT options directly to 3dDeconvolve.  The GLTs will be
           ignored after this, as they take up too many lines.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['sb23.blk']],
        ['-dsets',                 ['sb23/epi_r??+orig.HEAD']],
        ['-copy_anat',             ['sb23/sb23_mpra+orig']],
        ['-tcat_remove_first_trs', ['3']],
        ['-volreg_align_to',       ['last']],
        ['-regress_stim_times',    ['sb23/stim_files/blk_times.*.1D']],
        ['-regress_stim_labels',   ['tneg', 'tpos', 'tneu', 'eneg', 'epos',
                                    'eneu', 'fneg', 'fpos', 'fneu']],
        ['-regress_basis',         ['BLOCK(30,1)']],
        ['-regress_opts_3dD',      ['-gltsym', 'SYM: +eneg -fneg',
                '-glt_label', '1', 'eneg_vs_fneg', '-gltsym',
                'SYM: 0.5*fneg 0.5*fpos -1.0*fneu', '-glt_label', '2',
                'face_contrast', '-gltsym',
                'SYM: tpos epos fpos -tneg -eneg -fneg',
                '-glt_label', '3', 'pos_vs_neg']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample( 'Example 4',
     source='afni_proc.py -help',
     descrip='Similar to 3, but specify the processing blocks.',
     moddate='2009.05.28',
     keywords=['obsolete', 'task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              many missing preferences, e.g. @SSwarper)

           Adding despike and tlrc, and removing tshift.  Note that
           the tlrc block is to run @auto_tlrc on the anat.  Ignore the GLTs.
           """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['sb23.e4.blocks']],
        ['-dsets',                 ['sb23/epi_r??+orig.HEAD']],
        ['-blocks',                ['despike', 'volreg', 'blur', 'mask',
                                    'scale', 'regress', 'tlrc']],
        ['-copy_anat',             ['sb23/sb23_mpra+orig']],
        ['-tcat_remove_first_trs', ['3']],
        ['-regress_stim_times',    ['sb23/stim_files/blk_times.*.1D']],
        ['-regress_stim_labels',   ['tneg', 'tpos', 'tneu', 'eneg', 'epos',
                                    'eneu', 'fneg', 'fpos', 'fneu']],
        ['-regress_basis',         ['BLOCK(30,1)']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample( 'Example 5a',
     source='afni_proc.py -help',
     descrip='RETROICOR, resting state data.',
     moddate='2009.05.28',
     keywords=['obsolete', 'physio', 'rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              just a terribly simple example using ricor)

           Assuming the class data is for resting-state and that we have the
           appropriate slice-based regressors from RetroTS.py, apply the
           despike and ricor processing blocks.  Note that '-do_block' is used
           to add non-default blocks into their default positions.  Here the
           'despike' and 'ricor' processing blocks would come before 'tshift'.

           Remove 3 TRs from the ricor regressors to match the EPI data.  Also,
           since degrees of freedom are not such a worry, regress the motion
           parameters per-run (each run gets a separate set of 6 regressors).

           The regression will use 81 basic regressors (all of "no interest"),
           with 13 retroicor regressors being removed during preprocessing:

                 27 baseline  regressors ( 3 per run * 9 runs)
                 54 motion    regressors ( 6 per run * 9 runs)

           To example #3, add -do_block, -ricor_* and -regress_motion_per_run.
           """,
     trailer="""
           If tshift, blurring and masking are not desired, consider replacing
           the -do_block option with an explicit list of blocks:

                -blocks despike ricor volreg regress
           """,
     olist = [
        ['-subj_id',               ['sb23.e5a.ricor']],
        ['-dsets',                 ['sb23/epi_r??+orig.HEAD']],
        ['-do_block',              ['despike', 'ricor']],
        ['-tcat_remove_first_trs', ['3']],
        ['-ricor_regs_nfirst',     ['3']],
        ['-ricor_regs',            ['sb23/RICOR/r*.slibase.1D']],
        ['-regress_motion_per_run', []],
       ],
     ))

   examples.append( APExample( 'Example 5b',
     source='afni_proc.py -help',
     descrip='RETROICOR, while running a normal regression.',
     moddate='2009.05.28',
     keywords=['obsolete', 'physio', 'rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              another overly simple example using ricor)

           Add the ricor regressors to a normal regression-based processing
           stream.  Apply the RETROICOR regressors across runs (so using 13
           concatenated regressors, not 13*9).  Note that concatenation is
           normally done with the motion regressors too.

           To example #3, add -do_block and three -ricor options.
           """,
     trailer="""
           Also consider adding -regress_bandpass.
           """,
     olist = [
        ['-subj_id',               ['sb23.e5b.ricor']],
        ['-dsets',                 ['sb23/epi_r??+orig.HEAD']],
        ['-do_block',              ['despike', 'ricor']],
        ['-copy_anat',             ['sb23/sb23_mpra+orig']],
        ['-tcat_remove_first_trs', ['3']],
        ['-ricor_regs_nfirst',     ['3']],
        ['-ricor_regs',            ['sb23/RICOR/r*.slibase.1D']],
        ['-ricor_regress_method',  ['across-runs']],
        ['-volreg_align_to',       ['last']],
        ['-regress_stim_times',    ['sb23/stim_files/blk_times.*.1D']],
        ['-regress_stim_labels',   ['tneg', 'tpos', 'tneu', 'eneg', 'epos',
                                    'eneu', 'fneg', 'fpos', 'fneu']],
        ['-regress_basis',         ['BLOCK(30,1)']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample( 'Example 5c',
     source='afni_proc.py -help',
     descrip='RETROICOR: censor and band pass.',
     moddate='2016.05.03',
     keywords=['obsolete', 'physio', 'task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              many missing preferences, e.g. @SSwarper, no BP)

           This is an example of how we might currently suggest analyzing
           resting state data.  If no RICOR regressors exist, see example 9
           (or just remove any ricor options).

           Censoring due to motion has long been considered appropriate in
           BOLD FMRI analysis, but is less common for those doing bandpass
           filtering in RS FMRI because the FFT requires one to either break
           the time axis (evil) or to replace the censored data with something
           probably inappropriate.

           Instead, it is slow (no FFT, but maybe SFT :) but effective to
           regress frequencies within the regression model, where censoring
           is simple.

           Note: band passing in the face of RETROICOR is questionable.  It may
                 be questionable in general.  To skip bandpassing, remove the
                 -regress_bandpass option line.

           Also, align EPI to anat and warp to standard space.
           """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['sb23.e5a.ricor']],
        ['-dsets',                 ['sb23/epi_r??+orig.HEAD']],
        ['-blocks',                ['despike', 'ricor', 'tshift', 'align',
                            'tlrc', 'volreg', 'blur', 'mask', 'regress']],
        ['-copy_anat',             ['sb23/sb23_mpra+orig']],
        ['-tcat_remove_first_trs', ['3']],
        ['-ricor_regs_nfirst',     ['3']],
        ['-ricor_regs',            ['sb23/RICOR/r*.slibase.1D']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-blur_size',             ['6']],
        ['-regress_bandpass',      ['0.01', '0.1']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_run_clustsim',  ['no']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample( 'Example 6',
     source='afni_proc.py -help',
     descrip='A simple task example, based on AFNI_data6.',
     moddate='2020.02.15',
     keywords=['task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              meant to be fast, but not complete, e.g. NL warp)
              (              prefer: see Example 6b)

           This example has changed to more closely correspond with the
           the class analysis example, AFNI_data6/FT_analysis/s05.ap.uber.

           The tshift block will interpolate each voxel time series to adjust
           for differing slice times, where the result is more as if each
           entire volume were acquired at the beginning of the TR.

           The 'align' block implies using align_epi_anat.py to align the
           anatomy with the EPI.  Here, the EPI base is first unifized locally.
           Additional epi/anat alignment options specify using lpc+ZZ for the
           cost function (more robust than simply lpc), -giant_move (in case
           the anat and EPI start a bit far apart), and -check_flip, to try to
           verify whether EPI left and right agree with the anatomy.
           This block computes the anat to EPI transformation matrix, which
           will be inverted in the volreg block, based on -volreg_align_e2a.

           Also, compute the transformation of the anatomy to MNI space, using
           affine registration (for speed in this simple example) to align to
           the 2009c template.

           In the volreg block, align the EPI to the MIN_OUTLIER volume (a
           low-motion volume, determined based on the data).  Then concatenate
           all EPI transformations, warping the EPI to standard space in one
           step (without multiple resampling operations), combining:

              EPI  ->  EPI base  ->  anat  ->  MNI 2009c template

           The standard space transformation is included by specifying option
           -volreg_tlrc_warp.

           A 4 mm blur is applied, to keep it very light (about 1.5 times the
           voxel size).

           The regression model is based on 2 conditions, each lasting 20 s
           per event, modeled by convolving a 20 s boxcar function with the
           BLOCK basis function, specified as BLOCK(20,1) to make the regressor
           unit height (height 1).

           One extra general linear test (GLT) is included, contrasting the
           visual reliable condition (vis) with auditory reliable (aud).

           Motion regression will be per run (using one set of 6 regressors for
           each run, i.e. 18 regressors in this example).

           The regression includes censoring of large motion (>= 0.3 ~mm
           between successive time points, based on the motion parameters),
           as well as censoring of outlier time points, where at least 5% of
           the brain voxels are computed as outliers.

           The regression model starts as a full time series, for time
           continuity, before censored time points are removed.  The output
           errts will be zero at censored time points (no error there), and so
           the output fit times series (fitts) will match the original data.

           The model fit time series (fitts) will be computed AFTER the linear
           regression, to save RAM on class laptops.

           Create sum_ideal.1D, as the sum of all non-baseline regressors, for
           quality control.

           Estimate the blur in the residual time series.  The resulting 3 ACF
           parameters can be averaged across subjects for cluster correction at
           the group level.

           Skip running the Monte Carlo cluster simulation example (which would
           specify minimum cluster sizes for cluster significance, based on the
           ACF parameters and mask), for speed.

           Once the proc script is created, execute it.
           """,
     trailer="""
         * One could also use ANATICOR with task (e.g. -regress_anaticor_fast)
           in the case of -regress_reml_exec.  3dREMLfit supports voxelwise
           regression, but 3dDeconvolve does not.
             """,
     olist = [
        ['-subj_id',               ['FT.e6']],
        ['-copy_anat',             ['FT/FT_anat+orig']],
        ['-dsets',                 ['FT/FT_epi_r?+orig.HEAD']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-volreg_compute_tsnr',   ['yes']],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['4.0']],
        ['-regress_stim_times',    ['FT/AV1_vis.txt', 'FT/AV2_aud.txt']],
        ['-regress_stim_labels',   ['vis', 'aud']],
        ['-regress_basis',         ['BLOCK(20,1)']],
        ['-regress_opts_3dD',      ['-jobs', '2', '-gltsym', 'SYM: vis -aud',
                                    '-glt_label', '1', 'V-A']],
        ['-regress_motion_per_run',[]],
        ['-regress_censor_motion', ['0.3']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_compute_fitts', []],
        ['-regress_make_ideal_sum',['sum_ideal.1D']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-regress_run_clustsim',  ['no']],
        ['-html_review_style',     ['pythonic']],
        ['-execute',               []],
       ],
     ))

   examples.append( APExample( 'Example 6b',
     source='afni_proc.py -help',
     descrip='A modern task example, with preferable options.',
     moddate='2020.02.15',
     keywords=['complete', 'task'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)

           GOOD TO CONSIDER

           This is based on Example 6, but is more complete.
           Example 6 is meant to run quickly, as in an AFNI bootcamp setting.
           Example 6b is meant to process more as we might suggest.

              - apply -check_flip in align_epi_anat.py, to monitor consistency
              - apply non-linear registration to MNI template, using output
                from @SSwarper:
                  o apply skull-stripped anat in -copy_anat
                  o apply original anat as -anat_follower (QC, for comparison)
                  o pass warped anat and transforms via -tlrc_NL_warped_dsets,
                    to apply those already computed transformations
              - use -mask_epi_anat to tighten the EPI mask (for QC),
                intersecting it (full_mask) with the anat mask (mask_anat)
              - use 3dREMLfit for the regression, to account for temporal
                autocorrelation in the noise
                (-regress_3dD_stop, -regress_reml_exec)
              - generate the HTML QC report using the nicer pythonic functions
                (requires matplotlib)
           """,
     trailer="""
           To compare one's own command against this one, consider adding
                -compare_opts 'example 6b'
           to the end of (or anywhere in) the current command, as in:

                afni_proc.py ... my options ...   -compare_opts 'example 6b'
           """,
     olist = [
        ['-subj_id',               ['FT.e6b']],
        ['-copy_anat',             ['Qwarp/anat_warped/anatSS.FT.nii']],
        ['-anat_has_skull',        ['no']],
        ['-anat_follower',         ['anat_w_skull', 'anat', 'FT/FT_anat+orig']],
        ['-dsets',                 ['FT/FT_epi_r?+orig.HEAD']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template_SSW.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-tlrc_NL_warped_dsets',  ['Qwarp/anat_warped/anatQQ.FT.nii',
                                    'Qwarp/anat_warped/anatQQ.FT.aff12.1D',
                                    'Qwarp/anat_warped/anatQQ.FT_WARP.nii']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-volreg_compute_tsnr',   ['yes']],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['4.0']],
        ['-regress_stim_times',    ['FT/AV1_vis.txt', 'FT/AV2_aud.txt']],
        ['-regress_stim_labels',   ['vis', 'aud']],
        ['-regress_basis',         ['BLOCK(20,1)']],
        ['-regress_opts_3dD',      ['-jobs', '2', '-gltsym', 'SYM: vis -aud',
                                    '-glt_label', '1', 'V-A']],
        ['-regress_motion_per_run',[]],
        ['-regress_censor_motion', ['0.3']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_3dD_stop',      []],
        ['-regress_reml_exec',     []],
        ['-regress_compute_fitts', []],
        ['-regress_make_ideal_sum',['sum_ideal.1D']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-regress_run_clustsim',  ['no']],
        ['-html_review_style',     ['pythonic']],
        ['-execute',               []],
       ],
     ))

   examples.append( APExample( 'Example 7',
     source='afni_proc.py -help',
     descrip='Apply some esoteric options.',
     moddate='2020.01.08',
     keywords=['task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              e.g. NL warp without @SSwarper)
              (              prefer: see Example 6b)

           a. Blur only within the brain, as far as an automask can tell.  So
              add -blur_in_automask to blur only within an automatic mask
              created internally by 3dBlurInMask (akin to 3dAutomask).

           b. Let the basis functions vary.  For some reason, we expect the
              BOLD responses to the telephone classes to vary across the brain.
              So we have decided to use TENT functions there.  Since the TR is
              3.0s and we might expect up to a 45 second BOLD response curve,
              use 'TENT(0,45,16)' for those first 3 out of 9 basis functions.

              This means using -regress_basis_multi instead of -regress_basis,
              and specifying all 9 basis functions appropriately.

           c. Use amplitude modulation.

              We expect responses to email stimuli to vary proportionally with
              the number of punctuation characters used in the message (in
              certain brain regions).  So we will use those values as auxiliary
              parameters 3dDeconvolve by marrying the parameters to the stim
              times (using 1dMarry).

              Use -regress_stim_types to specify that the epos/eneg/eneu stim
              classes should be passed to 3dDeconvolve using -stim_times_AM2.

           d. Not only censor motion, but censor TRs when more than 10% of the
              automasked brain are outliers.  So add -regress_censor_outliers.

           e. Include both de-meaned and derivatives of motion parameters in
              the regression.  So add '-regress_apply_mot_types demean deriv'.

           f. Output baseline parameters so we can see the effect of motion.
              So add -bout under option -regress_opts_3dD.

           g. Save on RAM by computing the fitts only after 3dDeconvolve.
              So add -regress_compute_fitts.

           h. Speed things up.  Have 3dDeconvolve use 4 CPUs and skip the
              single subject 3dClustSim execution.  So add '-jobs 4' to the
              -regress_opts_3dD option and add '-regress_run_clustsim no'.
           """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['sb23.e7.esoteric']],
        ['-dsets',                 ['sb23/epi_r??+orig.HEAD']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'blur', 'mask', 'scale', 'regress']],
        ['-copy_anat',             ['sb23/sb23_mpra+orig']],
        ['-tcat_remove_first_trs', ['3']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['4']],
        ['-blur_in_automask',      []],
        ['-regress_stim_times',    ['sb23/stim_files/blk_times.*.1D']],
        ['-regress_stim_types',    ['times', 'times', 'times',
                                    'AM2', 'AM2', 'AM2',
                                    'times', 'times', 'times']],
        ['-regress_stim_labels',   ['tneg', 'tpos', 'tneu',
                                    'eneg', 'epos', 'eneu',
                                    'fneg', 'fpos', 'fneu']],
        ['-regress_basis_multi',['BLOCK(30,1)', 'TENT(0,45,16)','BLOCK(30,1)',
                                 'BLOCK(30,1)', 'TENT(0,45,16)','BLOCK(30,1)',
                                 'BLOCK(30,1)', 'TENT(0,45,16)','BLOCK(30,1)']],
        ['-regress_opts_3dD',      ['-bout', '-gltsym', 'SYM: +eneg -fneg',
                            '-glt_label', '1', 'eneg_vs_fneg', '-jobs', '4']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.3']],
        ['-regress_censor_outliers', ['0.1']],
        ['-regress_compute_fitts', []],
        ['-regress_run_clustsim',  ['no']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample('Example 8',
     source='afni_proc.py -help',
     descrip='Surface-based analysis.',
     moddate='2017.09.12',
     keywords=['complete', 'surface', 'task'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)

           This example is intended to be run from AFNI_data6/FT_analysis.
           It is provided with the class data in file s03.ap.surface.

           Add -surf_spec and -surf_anat to provide the required spec and
           surface volume datasets.  The surface volume will be aligned to
           the current anatomy in the processing script.  Two spec files
           (lh and rh) are provided, one for each hemisphere (via wildcard).

           Also, specify a (resulting) 6 mm FWHM blur via -blur_size.  This
           does not add a blur, but specifies a resulting blur level.  So
           6 mm can be given directly for correction for multiple comparisons
           on the surface.

           Censor per-TR motion above 0.3 mm.

           Note that no -regress_est_blur_errts option is given, since that
           applies to the volume only (and since the 6 mm blur is a resulting
           blur level, so the estimates are not needed).

           The -blocks option is provided, but it is the same as the default
           for surface-based analysis, so is not really needed here.  Note that
           the 'surf' block is added and the 'mask' block is removed from the
           volume-based defaults.

           important options:

                -blocks         : includes surf, but no mask
                                  (default blocks for surf, so not needed)
                -surf_anat      : volume aligned with surface
                -surf_spec      : spec file(s) for surface

           Note: one would probably want to use standard mesh surfaces here.
                 This example will be updated with them in the future.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT.surf']],
        ['-blocks',                ['tshift', 'align', 'volreg', 'surf',
                                    'blur', 'scale', 'regress']],
        ['-copy_anat',             ['FT/FT_anat+orig']],
        ['-dsets',                 ['FT/FT_epi_r?+orig.HEAD']],
        ['-surf_anat',             ['FT/SUMA/FTmb_SurfVol+orig']],
        ['-surf_spec',             ['FT/SUMA/FTmb_?h.spec']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-blur_size',             ['6']],
        ['-regress_stim_times',    ['FT/AV1_vis.txt', 'FT/AV2_aud.txt']],
        ['-regress_stim_labels',   ['vis', 'aud']],
        ['-regress_basis',         ['BLOCK(20,1)']],
        ['-regress_opts_3dD',      ['-jobs', '2', '-gltsym', 'SYM: vis -aud',
                                    '-glt_label', '1', 'V-A']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.3']],
       ],
     ))

   examples.append( APExample('Example 9',
     source='afni_proc.py -help',
     descrip='Resting state analysis with censoring and band passing.',
     moddate='2019.02.26',
     keywords=['rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              e.g. has band pass, no @SSwarper)
              (              prefer: see Example 11)

           With censoring and bandpass filtering.

           This is our suggested way to do preprocessing for resting state
           analysis, under the assumption that no cardio/physio recordings
           were made (see example 5 for cardio files).

           Censoring due to motion has long been considered appropriate in
           BOLD FMRI analysis, but is less common for those doing bandpass
           filtering in RS FMRI because the FFT requires one to either break
           the time axis (evil) or to replace the censored data with something
           probably inappropriate.

           Instead, it is slow (no FFT, but maybe SFT :) but effective to
           regress frequencies within the regression model, where censoring
           is simple.

           inputs: anat, EPI
           output: errts dataset (to be used for correlation)

           special processing:
              - despike, as another way to reduce motion effect
                 (see block despike)
              - censor motion TRs at the same time as bandpassing data
                 (see -regress_censor_motion, -regress_bandpass)
              - regress motion parameters AND derivatives
                 (see -regress_apply_mot_types)

           Note: for resting state data, a more strict threshold may be a good
                 idea, since motion artifacts should play a bigger role than in
                 a task-based analysis.

                 So the typical suggestion of motion censoring at 0.3 for task
                 based analysis has been changed to 0.2 for this resting state
                 example, and censoring of outliers has also been added, at a
                 value of 5% of the brain mask.

                 Outliers are typically due to motion, and may capture motion
                 in some cases where the motion parameters do not, because
                 motion is not generally a whole-brain-between-TRs event.

           Note: if regressing out regions of interest, either create the ROI
                 time series before the blur step, or remove blur from the list
                 of blocks (and apply any desired blur after the regression).

           Note: it might be reasonable to estimate the blur using epits rather
                 than errts in the case of bandpassing.  Both options are
                 included here.

           Note: scaling is optional here.  While scaling has no direct effect
                 on voxel correlations, it does have an effect on ROI averages
                 used for correlations.

           Other options to consider: -tlrc_NL_warp, -anat_uniform_method
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['subj123']],
        ['-dsets',                 ['epi_run1+orig.HEAD']],
        ['-copy_anat',             ['anat+orig']],
        ['-blocks',                ['despike', 'tshift', 'align', 'tlrc',
                          'volreg', 'blur', 'mask', 'scale', 'regress']],
        ['-tcat_remove_first_trs', ['3']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['4']],
        ['-regress_bandpass',      ['0.01', '0.1']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample('Example 9b',
     source='afni_proc.py -help',
     descrip='Resting state analysis with ANATICOR.',
     moddate='2020.01.08',
     keywords=['rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              e.g. has band pass, no @SSwarper)
              (              prefer: see Example 11)

           Like example #9, but also regress out the signal from locally
           averaged white matter.  The only change is adding the option
           -regress_anaticor.

           Note that -regress_anaticor implies options -mask_segment_anat and
           -mask_segment_erode.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['subj123']],
        ['-dsets',                 ['epi_run1+orig.HEAD']],
        ['-copy_anat',             ['anat+orig']],
        ['-blocks',                ['despike', 'tshift', 'align', 'tlrc',
                          'volreg', 'blur', 'mask', 'scale', 'regress']],
        ['-tcat_remove_first_trs', ['3']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['4']],
        ['-regress_bandpass',      ['0.01', '0.1']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_anaticor',      []],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample('Example 10',
     source='afni_proc.py -help',
     descrip='Resting state analysis, with tissue-based regressors.',
     moddate='2020.01.08',
     keywords=['rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              e.g. missing @SSwarper)
              (              prefer: see Example 11)

           Like example #9, but also regress the eroded white matter averages.
           The WMe mask come from the Classes dataset, created by 3dSeg via the
           -mask_segment_anat and -mask_segment_erode options.

        ** While -mask_segment_anat also creates a CSF mask, that mask is ALL
           CSF, not just restricted to the ventricles, for example.  So it is
           probably not appropriate for use in tissue-based regression.

           CSFe was previously used as an example of what one could do, but as
           it is not advised, it has been removed.

           Also, align to minimum outlier volume, and align to the anatomy
           using cost function lpc+ZZ.

           Note: it might be reasonable to estimate the blur using epits rather
                 than errts in the case of bandpassing.  Both options are
                 included here.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['subj123']],
        ['-dsets',                 ['epi_run1+orig.HEAD']],
        ['-copy_anat',             ['anat+orig']],
        ['-blocks',                ['despike', 'tshift', 'align', 'tlrc',
                                'volreg', 'blur', 'mask', 'scale', 'regress']],
        ['-tcat_remove_first_trs', ['3']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-blur_size',             ['4']],
        ['-mask_epi_anat',         ['yes']],
        ['-mask_segment_anat',     ['yes']],
        ['-mask_segment_erode',    ['yes']],
        ['-regress_bandpass',      ['0.01', '0.1']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_ROI',           ['WMe']],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample('Example 10b',
     source='afni_proc.py -help',
     descrip='Resting state analysis, as 10a with 3dRSFC.',
     moddate='2019.02.13',
     keywords=['rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              prefer: see Example 11)
              (         ***        : use censoring and 3dLombScargle)

            This is for band passing and computation of ALFF, etc.

          * This will soon use a modified 3dRSFC.

            Like example #10, but add -regress_RSFC to bandpass via 3dRSFC.
            Skip censoring and regression band passing because of the bandpass
            operation in 3dRSFC.

            To correspond to common tractography, this example stays in orig
            space (no 'tlrc' block, no -volreg_tlrc_warp option).  Of course,
            going to standard space is an option.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['subj123']],
        ['-dsets',                 ['epi_run1+orig.HEAD']],
        ['-copy_anat',             ['anat+orig']],
        ['-blocks',                ['despike', 'tshift', 'align', 'volreg',
                                    'blur', 'mask', 'scale', 'regress']],
        ['-tcat_remove_first_trs', ['3']],
        ['-volreg_align_e2a',      []],
        ['-blur_size',             ['6.0']],
        ['-mask_apply',            ['epi']],
        ['-mask_segment_anat',     ['yes']],
        ['-mask_segment_erode',    ['yes']],
        ['-regress_bandpass',      ['0.01', '0.1']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_ROI',           ['WMe']],
        ['-regress_RSFC',          []],
        ['-regress_run_clustsim',  ['no']],
        ['-regress_est_blur_errts', []],
       ],
     ))

   examples.append( APExample( 'Example 11',
     source='afni_proc.py -help',
     descrip='Resting state analysis (now even more modern :).',
     moddate='2022.10.06',
     keywords=['complete', 'rest'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)

         o Yes, censor (outliers and motion) and despike.
         o Align the anatomy and EPI using the lpc+ZZ cost function, rather
           than the default lpc one.  Apply -giant_move, in case the datasets
           do not start off well-aligned.  Include -check_flip for good measure.
           A locally unifized EPI base is used for anatomical registration.
         o Register EPI volumes to the one which has the minimum outlier
              fraction (so hopefully the least motion).
         o Use non-linear registration to MNI template (non-linear 2009c).
           * This adds a lot of processing time.
           * Let @SSwarper align to template MNI152_2009_template_SSW.nii.gz.
             Then use the resulting datasets in the afni_proc.py command below
             via -tlrc_NL_warped_dsets.
                  @SSwarper -input FT_anat+orig        \\
                            -subid FT                  \\
                            -odir  FT_anat_warped      \\
                            -base  MNI152_2009_template_SSW.nii.gz

            - The SS (skull-stripped) can be given via -copy_anat, and the
              with-skull unifized anatU can be given as a follower.
         o No bandpassing.
         o Use fast ANATICOR method (slightly different from default ANATICOR).
         o Use FreeSurfer segmentation for:
             - regression of first 3 principal components of lateral ventricles
             - ANATICOR white matter mask (for local white matter regression)
           * For details on how these masks were created, see "FREESURFER NOTE"
             in the help, as it refers to this "Example 11".
         o Erode FS white matter and ventricle masks before application.
         o Bring along FreeSurfer parcellation datasets:
             - aaseg : NN interpolated onto the anatomical grid
             - aeseg : NN interpolated onto the EPI        grid
           * These 'aseg' follower datasets are just for visualization,
             they are not actually required for the analysis.
         o Compute average correlation volumes of the errts against the
           the gray matter (aeseg) and ventricle (FSVent) masks.
         o Run @radial_correlate at the ends of the tcat, volreg and regress
           blocks.  If ANATICOR is being used to remove a scanner artifact,
           the errts radcor images might show the effect of this.

           Note: it might be reasonable to use either set of blur estimates
                 here (from epits or errts).  The epits (uncleaned) dataset
                 has all of the noise (though what should be considered noise
                 in this context is not clear), while the errts is motion
                 censored.  For consistency in resting state, it would be
                 reasonable to stick with epits.  They will likely be almost
                 identical.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT.11.rest']],
        ['-blocks',                ['despike', 'tshift', 'align', 'tlrc',
                          'volreg', 'blur', 'mask', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
        ['-copy_anat',             ['anatSS.FT.nii']],
        ['-anat_has_skull',        ['no']],
        ['-anat_follower',         ['anat_w_skull', 'anat', 'anatU.FT.nii']],
        ['-anat_follower_ROI',     ['aaseg', 'anat', 'aparc.a2009s+aseg_REN_all.nii.gz']],
        ['-anat_follower_ROI',     ['aeseg', 'epi', 'aparc.a2009s+aseg_REN_all.nii.gz']],
        ['-anat_follower_ROI',     ['FSvent', 'epi', 'fs_ap_latvent.nii.gz']],
        ['-anat_follower_ROI',     ['FSWe', 'epi', 'fs_ap_wm.nii.gz']],
        ['-anat_follower_erode',   ['FSvent', 'FSWe']],
        ['-dsets',                 ['FT_epi_r?+orig.HEAD']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template_SSW.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-tlrc_NL_warped_dsets',  ['anatQQ.FT.nii', 'anatQQ.FT.aff12.1D',
                                    'anatQQ.FT_WARP.nii']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['4']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_anaticor_fast', []],
        ['-regress_anaticor_label', ['FSWe']],
        ['-regress_ROI_PC',        ['FSvent', '3']],
        ['-regress_ROI_PC_per_run', ['FSvent']],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_make_corr_vols', ['aeseg', 'FSvent']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-html_review_style',     ['pythonic']],
       ],
     ))

   examples.append( APExample('Example 11b',
     source='afni_proc.py -help',
     descrip='Similar to 11, but without FreeSurfer.',
     moddate='2020.01.17',
     keywords=['complete', 'rest'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)
              (              if this ventricle extraction method seems okay)

         AFNI currently does not have a good program to extract ventricles.
         But it can make a CSF mask that includes them.  So without FreeSurfer,
         one could import a ventricle mask from the template (e.g. for TT space,
         using TT_desai_dd_mpm+tlrc).  For example, assuming Talairach space
         (and a 2.5 mm^3 final voxel grid) for the analysis, one could create a
         ventricle mask as follows:

                3dcalc -a ~/abin/TT_desai_dd_mpm+tlrc                       \\
                       -expr 'amongst(a,152,170)' -prefix template_ventricle
                3dresample -dxyz 2.5 2.5 2.5 -inset template_ventricle+tlrc \\
                       -prefix template_ventricle_2.5mm

         o Be explicit with 2.5mm, using '-volreg_warp_dxyz 2.5'.
         o Use template TT_N27+tlrc, to be aligned with the desai atlas.
         o No -anat_follower options, but use -mask_import to import the
           template_ventricle_2.5mm dataset (and call it Tvent).
         o Use -mask_intersect to intersect ventricle mask with the subject's
           CSFe mask, making a more reliable subject ventricle mask (Svent).
         o Ventricle principle components are created as per-run regressors.
         o Make WMe and Svent correlation volumes, which are just for
           entertainment purposes anyway.
         o Run the cluster simulation.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT.11b.rest']],
        ['-blocks',                ['despike', 'tshift', 'align', 'tlrc',
                          'volreg', 'blur', 'mask', 'scale', 'regress']],
        ['-copy_anat',             ['FT_anat+orig']],
        ['-dsets',                 ['FT_epi_r?+orig.HEAD']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['TT_N27+tlrc']],
        ['-tlrc_NL_warp',          []],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-volreg_warp_dxyz',      ['2.5']],
        ['-blur_size',             ['4']],
        ['-mask_segment_anat',     ['yes']],
        ['-mask_segment_erode',    ['yes']],
        ['-mask_import',           ['Tvent', 'template_ventricle_2.5mm+tlrc']],
        ['-mask_intersect',        ['Svent', 'CSFe', 'Tvent']],
        ['-mask_epi_anat',         ['yes']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_anaticor_fast', []],
        ['-regress_ROI_PC',        ['Svent', '3']],
        ['-regress_ROI_PC_per_run', ['Svent']],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_make_corr_vols', ['WMe', 'Svent']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-regress_run_clustsim',  ['yes']],
       ],
     ))

   examples.append( APExample('Example 12',
     source='afni_proc.py -help',
     descrip='background: Multi-echo data processing.',
     moddate='2018.02.27',
     keywords=['ME', 'rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              incomplete - just shows basic ME options)
              (              prefer: see Example 13)

         Processing multi-echo data should be similar to single echo data,
         except for perhaps:

            combine         : the addition of a 'combine' block
            -dsets_me_echo  : specify ME data, per echo
            -dsets_me_run   : specify ME data, per run (alternative to _echo)
            -echo_times     : specify echo times (if needed)
            -combine_method : specify method to combine echoes (if any)

         An afni_proc.py command might be updated to include something like:
            """,
     trailer=""" """,
     olist = [
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                            'mask', 'combine', 'blur', 'scale', 'regress']],
        ['-dsets_me_echo',         ['epi_run*_echo_01.nii']],
        ['-dsets_me_echo',         ['epi_run*_echo_02.nii']],
        ['-dsets_me_echo',         ['epi_run*_echo_03.nii']],
        ['-echo_times',            ['15', '30.5', '41']],
        ['-mask_epi_anat',         ['yes']],
        ['-combine_method',        ['OC']],
       ],
     ))

   examples.append( APExample('Example 12a',
     source='afni_proc.py -help',
     descrip='Multi-echo data processing - very simple.',
     moddate='2018.02.27',
     keywords=['ME', 'rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              many missing preferences, e.g. @SSwarper)
              (              prefer: see Example 13)

         Keep it simple and just focus on the basic ME options, plus a few
         for controlling registration.

         o This example uses 3 echoes of data across just 1 run.
            - so use a single -dsets_me_run option to input EPI datasets
         o Echo 2 is used to drive registration for all echoes.
            - That is the default, but it is good to be explicit.
         o The echo times are not needed, as the echoes are never combined.
         o The echo are never combined (in this example), so that there
           are always 3 echoes, even until the end.
            - Note that the 'regress' block is not valid for multiple echoes.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT.12a.ME']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'blur']],
        ['-copy_anat',             ['FT_anat+orig']],
        ['-dsets_me_run',          ['epi_run1_echo*.nii']],
        ['-reg_echo',              ['2']],
        ['-tcat_remove_first_trs', ['2']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
       ],
     ))

   examples.append( APExample('Example 12b',
     source='afni_proc.py -help',
     descrip='Multi-echo data processing - OC resting state.',
     moddate='2020.01.08',
     keywords=['ME', 'rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              many missing preferences, e.g. @SSwarper)
              (              prefer: see Example 13)

         Still keep this simple, mostly focusing on ME options, plus standard
         ones for resting state.

         o This example uses 3 echoes of data across just 1 run.
            - so use a single -dsets_me_run option to input EPI datasets
         o Echo 2 is used to drive registration for all echoes.
            - That is the default, but it is good to be explicit.
         o The echoes are combined via the 'combine' block.
         o So -echo_times is used to provided them.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT.12a.ME']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                            'mask', 'combine', 'blur', 'scale', 'regress']],
        ['-copy_anat',             ['FT_anat+orig']],
        ['-dsets_me_run',          ['epi_run1_echo*.nii']],
        ['-echo_times',            ['15', '30.5', '41']],
        ['-reg_echo',              ['2']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-combine_method',        ['OC']],
        ['-blur_size',             ['4']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits', []],
       ]
     ))

   examples.append( APExample('Example 12c',
     source='afni_proc.py -help',
     descrip='Multi-echo data processing - ME-ICA resting state.',
     moddate='2020.01.08',
     keywords=['ME', 'rest'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              many missing preferences, e.g. @SSwarper)
              (              prefer: see Example 13)

         As above, but run tedana.py for MEICA denoising.

         o Since tedana.py will mask the data, it may be preferable to
           blur only within that mask (-blur_in_mask yes).
         o A task analysis using tedana might look much the same,
           but with the extra -regress options for the tasks.
            """,
     trailer="""
         Consider an alternative combine method, 'tedana_OC_tedort'.
           """,
     olist = [
        ['-subj_id',               ['FT.12a.ME']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                            'mask', 'combine', 'blur', 'scale', 'regress']],
        ['-copy_anat',             ['FT_anat+orig']],
        ['-dsets_me_run',          ['epi_run1_echo*.nii']],
        ['-echo_times',            ['15', '30.5', '41']],
        ['-reg_echo',              ['2']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-combine_method',        ['tedana']],
        ['-blur_size',             ['4']],
        ['-blur_in_mask',          ['yes']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run',[]],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits',[]],
       ],
     ))

   examples.append( APExample( 'Example 13',
     source='afni_proc.py -help',
     descrip='Complicated ME, surface-based resting state example.',
     moddate='2019.09.06',
     keywords=['complete', 'ME', 'physio', 'rest', 'surface'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)

         Example 'publish 3d' might be preferable.

         Key aspects of this example:

            - multi-echo data, using "optimally combined" echoes
            - resting state analysis (without band passing)
            - surface analysis
            - blip up/blip down distortion correction
            - slice-wise regression of physiological parameters (RETROICOR)
            - ventricle principal component regression (3 PCs)
            - EPI volreg to per-run MIN_OUTLIER, with across-runs allineate
            - QC: @radial_correlate on tcat and volreg block results
            - QC: pythonic html report

            * since this is a surface-based example, the are no tlrc options

         Minor aspects:

            - a FWHM=6mm blur is applied, since blur on surface is TO is size

         Note: lacking good sample data for this example, it is simply faked
               for demonstration (echoes are identical, fake ricor parameters
               are not part of this data tree).
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT.complicated']],
        ['-dsets_me_echo',         ['FT/FT_epi_r?+orig.HEAD']],
        ['-dsets_me_echo',         ['FT/FT_epi_r?+orig.HEAD']],
        ['-dsets_me_echo',         ['FT/FT_epi_r?+orig.HEAD']],
        ['-echo_times',            ['11', '22.72', '34.44']],
        ['-blip_forward_dset',     ['FT/FT_epi_r1+orig.HEAD[0]']],
        ['-blip_reverse_dset',     ['FT/FT_epi_r1+orig.HEAD[0]']],
        ['-copy_anat',             ['FT/FT_anat+orig']],
        ['-anat_follower_ROI',     ['FSvent', 'epi', 'FT/SUMA/FT_vent.nii']],
        ['-anat_follower_erode',   ['FSvent']],
        ['-blocks',                ['despike', 'ricor', 'tshift', 'align',
                                    'volreg', 'mask', 'combine', 'surf',
                                    'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg']],
        ['-tcat_remove_first_trs', ['2']],
        ['-ricor_regs_nfirst',     ['2']],
        ['-ricor_regs',            ['FT/fake.slibase.FT.r?.1D']],
        ['-ricor_regress_method',  ['per-run']],
        ['-tshift_interp',         ['-wsinc9']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_post_vr_allin',  ['yes']],
        ['-volreg_pvra_base_index', ['MIN_OUTLIER']],
        ['-volreg_warp_final_interp', ['wsinc5']],
        ['-mask_epi_anat',         ['yes']],
        ['-combine_method',        ['OC']],
        ['-surf_anat',             ['FT/SUMA/FT_SurfVol.nii']],
        ['-surf_spec',             ['FT/SUMA/std.141.FT_?h.spec']],
        ['-blur_size',             ['6']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_ROI_PC',        ['FSvent', '3']],
        ['-regress_ROI_PC_per_run', ['FSvent']],
        ['-regress_make_corr_vols', ['FSvent']],
        ['-regress_censor_motion', ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-html_review_style',     ['pythonic']],
       ]
     ))

   return examples

def egs_class():
   """AP class examples
   """

   examples =  []

   examples.append( APExample('AP class 3',
     source='FT_analysis',
     descrip='s03.ap.surface - basic surface analysis',
     moddate='2025.03.11',
     keywords=['complete', 'surface', 'task'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)
                             (though it is a very simple example)

           This is the surface analysis run during an AFNI bootcamp.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT.surf']],
        ['-dsets',                 ['FT/FT_epi_r?+orig.HEAD']],
        ['-copy_anat',             ['FT/FT_anat+orig']],
        ['-blocks',                ['tshift', 'align', 'volreg', 'surf',
                                    'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_compute_tsnr',   ['yes']],
        ['-surf_anat',             ['FT/SUMA/FT_SurfVol.nii']],
        ['-surf_spec',             ['FT/SUMA/std.60.FT_?h.spec']],
        ['-blur_size',             ['6']],
        ['-regress_stim_times',    ['FT/AV1_vis.txt', 'FT/AV2_aud.txt']],
        ['-regress_stim_labels',   ['vis', 'aud']],
        ['-regress_basis',         ['BLOCK(20,1)']],
        ['-regress_opts_3dD',      ['-jobs', '2', '-gltsym', 'SYM: vis -aud',
                                    '-glt_label', '1', 'V-A']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.3']],
        ['-regress_censor_outliers', ['0.05']],
       ]
     ))

   examples.append( APExample('AP class 5',
     source='FT_analysis',
     descrip='s05.ap.uber - basic task analysis',
     moddate='2025.03.11',
     keywords=['task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              prefer: see Example publish 3b for NL warp)

           A basic task analysis with a pair of visual and auditory tasks.

           notable options include :
                - affine registration to MNI152_2009_template.nii.gz template
                - censoring based on both motion params and outliers
                - '-regress_compute_fitts' to reduce RAM needs in 3dD
                - mask_epi_anat - intersect full_mask (epi) with mask_anat
                - QC: computing radial correlation volumes at the end
                      of the tcat, volreg and regress processing blocks
                - QC: include -check_flip left/right consistency check
                - QC: compute sum of ideals, for evaluation
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT']],
        ['-dsets',                 ['FT/FT_epi_r1+orig.HEAD',
                                    'FT/FT_epi_r2+orig.HEAD',
                                    'FT/FT_epi_r3+orig.HEAD']],
        ['-copy_anat',             ['FT/FT_anat+orig']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template.nii.gz']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-volreg_compute_tsnr',   ['yes']],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['4.0']],
        ['-regress_stim_times',    ['FT/AV1_vis.txt', 'FT/AV2_aud.txt']],
        ['-regress_stim_labels',   ['vis', 'aud']],
        ['-regress_basis',         ['BLOCK(20,1)']],
        ['-regress_opts_3dD',      ['-jobs', '2', '-gltsym', 'SYM: vis -aud',
                                    '-glt_label', '1', 'V-A',
                                    '-gltsym', 'SYM: 0.5*vis +0.5*aud',
                                    '-glt_label', '2', 'mean.VA']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.3']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_compute_fitts', []],
        ['-regress_make_ideal_sum', ['sum_ideal.1D']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-regress_run_clustsim',  ['no']],
        ['-html_review_style',     ['pythonic']],
        ['-execute',               []],
       ]
     ))

   examples.append( APExample('AP class do_21',
     source='task_demo_ap',
     descrip='do_21_ap_affine.tcsh - basic task analysis',
     moddate='2025.09.22',
     keywords=['task'],
     header="""
              (recommended?  no, not intended for a complete analysis)
              (              prefer: see Example publish 3b for NL warp)

           A basic task analysis with a pair of visual and auditory tasks.

           notable options include :
                - affine registration to MNI152_2009_template.nii.gz template
                - censoring based on both motion params and outliers
                - '-regress_compute_fitts' to reduce RAM needs in 3dD
                - mask_epi_anat - intersect full_mask (epi) with mask_anat
                - QC: computing radial correlation volumes at the end
                      of the tcat, volreg and regress processing blocks
                - QC: include -check_flip left/right consistency check
                - QC: compute sum of ideals, for evaluation
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',                 ['sub-000.affine']],
        ['-dsets',                   ['sub-000_task-av_run-01_bold.nii.gz',
                                      'sub-000_task-av_run-02_bold.nii.gz',
                                      'sub-000_task-av_run-03_bold.nii.gz']],
        ['-copy_anat',               ['anatSS.sub-000.nii']],
        ['-anat_has_skull',          ['no']],
        ['-anat_follower',           ['anat_w_skull', 'anat',
                                      'anatU.sub-000.nii']],
        ['-blocks',                  ['tshift', 'align', 'tlrc', 'volreg',
                                      'mask', 'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
        ['-tcat_remove_first_trs',   ['2']],
        ['-align_unifize_epi',       ['local']],
        ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                      '-check_flip']],
        ['-tlrc_base',               ['MNI152_2009_template.nii.gz']],
        ['-volreg_align_to',         ['MIN_OUTLIER']],
        ['-volreg_align_e2a',        []],
        ['-volreg_tlrc_warp',        []],
        ['-volreg_compute_tsnr',     ['yes']],
        ['-mask_epi_anat',           ['yes']],
        ['-blur_size',               ['4.0']],
        ['-regress_stim_times',      ['times.vis.txt', 'times.aud.txt']],
        ['-regress_stim_labels',     ['vis', 'aud']],
        ['-regress_basis',           ['BLOCK(20,1)']],
        ['-regress_opts_3dD',        ['-jobs', '2', '-gltsym', 'SYM: vis -aud',
                                      '-glt_label', '1', 'V-A',
                                      '-gltsym', 'SYM: 0.5*vis +0.5*aud',
                                      '-glt_label', '2', 'mean.VA']],
        ['-regress_motion_per_run',  []],
        ['-regress_censor_motion',   ['0.3']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_compute_fitts',   []],
        ['-regress_make_ideal_sum',  ['sum_ideal.1D']],
        ['-regress_est_blur_epits',  []],
        ['-regress_est_blur_errts',  []],
        ['-regress_run_clustsim',    ['no']],
        ['-html_review_style',       ['pythonic']],
        ['-execute',                 []],
       ]
     ))

   return examples

def egs_publish():
   """AP publish examples
   """

   examples =  []

   examples.append( APExample('AP publish 1',
     source='AFNI_demos',
     descrip='pamenc, ds000030.v16 parametric encoding task analysis.',
     moddate='2024.08.26',
     keywords=['complete', 'publish', 'task'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)

           While this example is reasonable, 'publish 3b' has more QC options,
           as well as updates for anat/EPI alignment and grid size.

           Events are modeled using duration modulation, so AM1 is applied.

           original analysis was from:
               Gorgolewski KJ, Durnez J and Poldrack RA.
               Preprocessed Consortium for Neuropsychiatric Phenomics dataset.
               F1000Research 2017, 6:1262
               https://doi.org/10.12688/f1000research.11964.2

           downloadable from https://legacy.openfmri.org/dataset/ds000030
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['SID']],
        ['-script',                ['proc.SID']],
        ['-scr_overwrite',         []],
        ['-dsets',                 ['func/SID_task-pamenc_bold.nii.gz']],
        ['-copy_anat',             ['anatSS.SID.nii']],
        ['-anat_has_skull',        ['no']],
        ['-anat_follower',         ['anat_w_skull', 'anat', 'anatU.SID.nii']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'blur', 'scale', 'regress']],
        ['-radial_correlate',      ['yes']],
        ['-tcat_remove_first_trs', ['0']],
        ['-tshift_opts_ts',        ['-tpattern', 'alt+z2']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template_SSW.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-tlrc_NL_warped_dsets',  ['anatQQ.SID.nii', 'anatQQ.SID.aff12.1D',
                                    'anatQQ.SID_WARP.nii']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['6']],
        ['-blur_in_mask',          ['yes']],
        ['-regress_stim_times',    ['timing/times.CONTROL.txt',
                                    'timing/times.TASK.txt']],
        ['-regress_stim_labels',   ['CONTROL', 'TASK']],
        ['-regress_stim_types',    ['AM1']],
        ['-regress_basis_multi',   ['dmBLOCK']],
        ['-regress_opts_3dD',      ['-jobs', '8']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.3']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_compute_fitts', []],
        ['-regress_fout',          ['no']],
        ['-regress_3dD_stop',      []],
        ['-regress_reml_exec',     []],
        ['-regress_make_ideal_sum', ['sum_ideal.1D']],
        ['-regress_est_blur_errts', []],
        ['-regress_run_clustsim',  ['no']],
        ['-html_review_style',     ['pythonic']],
       ],
     ))

   examples.append( APExample('AP publish 2',
     source='eventually mention paper reference?',
     descrip='NARPS analysis from AFNI.',
     moddate='2020.02.10',
     keywords=['complete', 'publish', 'task'],
     header="""
              (recommended?  yes, reasonable for a complete analysis)

           An amplitude modulation task analysis.  AM1 is used for NoResp
           merely to consistently apply duration modulation.
            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['sid']],
        ['-script',                ['proc.sid']],
        ['-scr_overwrite',         []],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'blur', 'scale', 'regress']],
        ['-copy_anat',             ['anatSS.sid.nii']],
        ['-anat_has_skull',        ['no']],
        ['-anat_follower',         ['anat_w_skull', 'anat', 'anatU.sid.nii']],
        ['-anat_follower_ROI',     ['FS_wm_e', 'epi',
                                    'SUMA/mask.aseg.wm.e1.nii.gz']],
        ['-anat_follower_ROI',     ['FS_REN_epi', 'epi',
                                    'SUMA/aparc+aseg_REN_all.nii.gz']],
        ['-anat_follower_ROI',     ['FS_REN_anat', 'anat',
                                    'SUMA/aparc+aseg_REN_all.nii.gz']],
        ['-anat_follower_erode',   ['FS_wm_e']],
        ['-dsets',                 ['func/sid_task-MGT_run-01_bold.nii.gz',
                                    'func/sid_task-MGT_run-02_bold.nii.gz',
                                    'func/sid_task-MGT_run-03_bold.nii.gz',
                                    'func/sid_task-MGT_run-04_bold.nii.gz']],
        ['-tcat_remove_first_trs', ['0']],
        ['-tshift_opts_ts',        ['-tpattern', 'alt+z2']],
        ['-radial_correlate',      ['yes']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template_SSW.nii.gz']],
        ['-tlrc_NL_warp',          []],
        ['-tlrc_NL_warped_dsets',  ['anatQQ.sid.nii', 'anatQQ.sid.aff12.1D',
                                    'anatQQ.sid_WARP.nii']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['5']],
        ['-test_stim_files',       ['no']],
        ['-regress_stim_times',    ['timing/times.Resp.txt',
                                    'timing/times.NoResp.txt']],
        ['-regress_stim_labels',   ['Resp', 'NoResp']],
        ['-regress_stim_types',    ['AM2', 'AM1']],
        ['-regress_basis_multi',   ['dmBLOCK']],
        ['-regress_anaticor_fast', []],
        ['-regress_anaticor_fwhm', ['20']],
        ['-regress_anaticor_label', ['FS_wm_e']],
        ['-regress_censor_motion', ['0.3']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_motion_per_run', []],
        ['-regress_compute_fitts', []],
        ['-regress_opts_3dD',      ['-jobs', '8',
                        '-gltsym', 'SYM: Resp[1] -Resp[2]',
                        '-glt_label', '1', 'gain-loss', '-GOFORIT', '10']],
        ['-regress_opts_reml',     ['-GOFORIT']],
        ['-regress_3dD_stop',      []],
        ['-regress_reml_exec',     []],
        ['-regress_make_ideal_sum', ['sum_ideal.1D']],
        ['-regress_make_corr_vols', ['FS_wm_e']],
        ['-regress_est_blur_errts', []],
        ['-regress_run_clustsim',  ['no']],
        ['-html_review_style',     ['pythonic']],
       ],
     ))

   examples.append( APExample('AP publish 3a',
     source='AP_paper/scripts_rest/do_21_ap_ex1_align.tcsh',
     descrip='do_21_ap_ex1_align.tcsh - only perform alignment steps.',
     moddate='2024.01.26',
     keywords=['partial', 'publish', 'align'],
     header="""
              (recommended?  somewhat, for alignment only)

         This example is based on the APMULTI_Demo1_rest tree, but will come
         with a new demo package.  Probably.  Maybe.

         This is a full analysis, including:

            - reverse phase encoding (blip) distortion correction
              (-blip_forward_dset, -blip_reverse_dset)
            - EPI motion registration (to MIN_OUTLIER)
            - EPI to anatomical registration
            - non-linear anatomical to MNI template registration
              (precomputed affine+non-linear warp is provided)
            * the regress block is included only for QC

            - QC options:
                -anat_follower (with skull), (-align_opts_aea) -check_flip

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',                 ['sub-005.ex1']],
        ['-dsets',                   ['func/sub-005_rest_echo-2_bold.nii.gz']],
        ['-blip_forward_dset',       ['func/sub-005_blip-match.nii.gz[0]']],
        ['-blip_reverse_dset',       ['func/sub-005_blip-opp.nii.gz[0]']],
        ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
        ['-anat_has_skull',          ['no']],
        ['-anat_follower',           ['anat_w_skull', 'anat',
                                      'ssw/anatU.sub-005.nii']],
        ['-blocks',                  ['align', 'tlrc', 'volreg', 'regress']],
        ['-tcat_remove_first_trs',   ['4']],
        ['-align_unifize_epi',       ['local']],
        ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                      '-check_flip']],
        ['-tlrc_base',               ['MNI152_2009_template_SSW.nii.gz']],
        ['-tlrc_NL_warp',            []],
        ['-tlrc_NL_warped_dsets',    ['ssw/anatQQ.sub-005.nii',
                                      'ssw/anatQQ.sub-005.aff12.1D',
                                      'ssw/anatQQ.sub-005_WARP.nii']],
        ['-volreg_align_to',         ['MIN_OUTLIER']],
        ['-volreg_align_e2a',        []],
        ['-volreg_tlrc_warp',        []],
        ['-volreg_warp_dxyz',        ['3']],
       ],
     ))

   examples.append( APExample('AP publish 3b',
     source='AP_paper/scripts_task/do_22_ap_ex2_task.tcsh',
     descrip='do_22_ap_ex2_task.tcsh - pamenc task analysis.',
     moddate='2024.02.20',
     keywords=['complete', 'publish', 'task'],
     header="""
              (recommended?  yes, for a volumetric task analysis)

         This example is based on the AFNI_demos/AFNI_pamenc data.

         This is a full analysis, including:
            - slice time correction (alt+z2 timing pattern)
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - NL warp to MNI152_2009 template, as computed by @SSwarper
            - all registration transformations are concatenated
            - computing an EPI mask intersected with the anatomical mask
              for blurring and QC (-mask_epi_anat)
            - applying a 6 mm FWHM Gaussian blur, restricted to the EPI mask
            - voxelwise scaling to percent signal change
            - linear regression of task events using duration modulation with
              the BLOCK basis function (dmUBLOCK(-1)), where the ideal response
              height is unit for a 1 s event; stim_type AM1 is required here
            - censoring time points where motion exceeds 0.3 mm or the outlier
              fraction exceeds 5%
            - regression is performed by 3dREMLfit, accounting for voxelwise
              temporal autocorrelation in the noise
            - estimate data blur from the regression residuals using
              the mixed-model ACF function

            - QC options:
                -anat_follower (with skull), (-align_opts_aea) -check_flip,
                -radial_correlate_blocks, -volreg_compute_tsnr,
                -regress_make_ideal_sum, -html_review_style

         * input dataset names have been shortened

            """,
     trailer=""" """,
     olist = [
      ['-subj_id',                      ['sub-10506.ex2']],
      ['-dsets',                        ['func/sub-10506_pamenc_bold.nii.gz']],
      ['-copy_anat',                    ['ssw/anatSS.sub-10506.nii']],
      ['-anat_has_skull',               ['no']],
      ['-anat_follower',                ['anat_w_skull', 'anat',
                                         'ssw/anatU.sub-10506.nii']],
      ['-blocks',                       ['tshift', 'align', 'tlrc', 'volreg',
                                         'mask', 'blur', 'scale', 'regress']],
      ['-radial_correlate_blocks',      ['tcat', 'volreg', 'regress']],
      ['-tcat_remove_first_trs',        ['0']],
      ['-tshift_opts_ts',               ['-tpattern', 'alt+z2']],
      ['-align_unifize_epi',            ['local']],
      ['-align_opts_aea',               ['-giant_move', '-cost', 'lpc+ZZ',
                                         '-check_flip']],
      ['-tlrc_base',                    ['MNI152_2009_template_SSW.nii.gz']],
      ['-tlrc_NL_warp',                 []],
      ['-tlrc_NL_warped_dsets',         ['ssw/anatQQ.sub-10506.nii',
                                         'ssw/anatQQ.sub-10506.aff12.1D',
                                         'ssw/anatQQ.sub-10506_WARP.nii']],
      ['-volreg_align_to',              ['MIN_OUTLIER']],
      ['-volreg_align_e2a',             []],
      ['-volreg_tlrc_warp',             []],
      ['-volreg_warp_dxyz',             ['3.0']],
      ['-volreg_compute_tsnr',          ['yes']],
      ['-mask_epi_anat',                ['yes']],
      ['-blur_size',                    ['6']],
      ['-blur_in_mask',                 ['yes']],
      ['-regress_stim_times',           ['timing/times.CONTROL.txt',
                                         'timing/times.TASK.txt']],
      ['-regress_stim_labels',          ['CONTROL', 'TASK']],
      ['-regress_stim_types',           ['AM1']],
      ['-regress_basis_multi',          ['dmUBLOCK(-1)']],
      ['-regress_opts_3dD',             ['-jobs', '8',
                                         '-gltsym', 'SYM: TASK -CONTROL',
                                         '-glt_label', '1', 'T-C',
                                         '-gltsym',
                                         'SYM: 0.5*TASK +0.5*CONTROL',
                                         '-glt_label', '2', 'meanTC']],
      ['-regress_motion_per_run',       []],
      ['-regress_censor_motion',        ['0.3']],
      ['-regress_censor_outliers',      ['0.05']],
      ['-regress_compute_fitts',        []],
      ['-regress_fout',                 ['no']],
      ['-regress_3dD_stop',             []],
      ['-regress_reml_exec',            []],
      ['-regress_make_ideal_sum',       ['sum_ideal.1D']],
      ['-regress_est_blur_errts',       []],
      ['-regress_run_clustsim',         ['no']],
      ['-html_review_style',            ['pythonic']],
       ],
     ))

   examples.append( APExample('AP publish 3c',
     source='AP_paper/scripts_rest/do_23_ap_ex3_vol.tcsh',
     descrip='do_23_ap_ex3_vol.tcsh - rest analysis.',
     moddate='2024.08.09',
     keywords=['complete', 'physio', 'publish', 'rest'],
     header="""
              (recommended?  yes, an example of resting state analysis)

         This example is based on the APMULTI_Demo1_rest tree, to perform a
         resting state analysis with a single echo time series.

         This is a resting state processing command, including:
            - physio regression, slicewise, before any temporal or volumetric
              alterations (and per-run, though there is only 1 run here)
            - slice timing correction (notably after physio regression)
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - NL warp to MNI152_2009 template, as computed by @SSwarper
            - apply 5 mm FWHM Gaussian blur, approx 1.5*voxel size
            - all registration transformations are concatenated
            - voxelwise scaling to percent signal change
            - regression (projection) of:
                - per run motion and first differences
                - censor motion exceeding 0.2 ~mm from enorm time series,
                  or outliers exceeding 5% of brain 
            - estimate data blur from the regression residuals and the
              regression input (separately) using the mixed-model ACF function

            - QC options:
                -anat_follower (with skull), -anat_follower_ROI (FS GM mask),
                -radial_correlate_blocks, (-align_opts_aea) -check_flip,
                -volreg_compute_tsnr, -regress_make_corr_vols,
                -html_review_style

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
      ['-subj_id',                 ['sub-005.ex3']],
      ['-dsets',                   ['func/sub-005_rest_echo-2_bold.nii.gz']],
      ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
      ['-anat_has_skull',          ['no']],
      ['-anat_follower',           ['anat_w_skull', 'anat',
                                   'ssw/anatU.sub-005.nii']],
      ['-anat_follower_ROI',       ['aagm09', 'anat',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-anat_follower_ROI',       ['aegm09', 'epi',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-ROI_import',              ['BrodPijn', 'Brodmann_pijn_afni.nii.gz']],
      ['-ROI_import',              ['SchYeo7N', 'Schaefer_7N_400.nii.gz']],
      ['-blocks',                  ['ricor', 'tshift', 'align', 'tlrc',
                                    'volreg', 'mask', 'blur', 'scale',
                                    'regress']],
      ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
      ['-tcat_remove_first_trs',   ['4']],
      ['-ricor_regs',              ['physio/sub-005_rest_physio.slibase.1D']],
      ['-ricor_regs_nfirst',       ['4']],
      ['-ricor_regress_method',    ['per-run']],
      ['-align_unifize_epi',       ['local']],
      ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
      ['-tlrc_base',               ['MNI152_2009_template_SSW.nii.gz']],
      ['-tlrc_NL_warp',            []],
      ['-tlrc_NL_warped_dsets',    ['ssw/anatQQ.sub-005.nii',
                                    'ssw/anatQQ.sub-005.aff12.1D',
                                    'ssw/anatQQ.sub-005_WARP.nii']],
      ['-volreg_align_to',         ['MIN_OUTLIER']],
      ['-volreg_align_e2a',        []],
      ['-volreg_tlrc_warp',        []],
      ['-volreg_warp_dxyz',        ['3']],
      ['-volreg_compute_tsnr',     ['yes']],
      ['-mask_epi_anat',           ['yes']],
      ['-blur_size',               ['5']],
      ['-regress_apply_mot_types', ['demean', 'deriv']],
      ['-regress_motion_per_run',  []],
      ['-regress_censor_motion',   ['0.2']],
      ['-regress_censor_outliers', ['0.05']],
      ['-regress_make_corr_vols',  ['aegm09']],
      ['-regress_est_blur_epits',  []],
      ['-regress_est_blur_errts',  []],
      ['-regress_compute_tsnr_stats', ['BrodPijn', '7', '10', '12', '39',
                                       '107', '110', '112', '139']],
      ['-regress_compute_tsnr_stats', ['SchYeo7N', '161', '149', '7', '364',
                                       '367', '207']],
      ['-html_review_style',       ['pythonic']],
       ],
     ))

   examples.append( APExample('AP publish 3d',
     source='AP_paper/scripts_rest/do_24_ap_ex4_mesurf.tcsh',
     descrip='do_24_ap_ex4_mesurf.tcsh - multi-echo surface-based analysis.',
     moddate='2024.05.30',
     keywords=['complete', 'blip', 'ME', 'publish', 'rest',
               'surface', 'tedana'],
     header="""
              (recommended?  yes)

         This example is based on the APMULTI_Demo1_rest tree, to perform a
         resting state analysis on the surface with multi-echo data.

         This is a surface-based resting state processing command, including:
            - slice timing correction (using wsinc9 interpolation)
            - distortion correction using reverse blip phase encoding
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - all registration transformations are concatenated, and
              based on echo 2 (as we did not specify), but applied to all
              echoes, and resampled using a wsinc9 interpolant
            - compute a mask dataset to give to tedana (-mask_epi_anat)
              (having tedana do the projection results in masked EPI data)
            - echos are combined and then "cleaned" by tedana
            - the EPI time series are then  projected onto the surface
              (a previously computed set of surfaces, registered to the
              current anat, making a new SurfVol_Alnd_Exp anat dset)
                - might have surf data gaps, due to coverage or tedana masking
            - (light) blurring _to_ of FWHM of 4 mm is applied on the surface
            - nodewise scaling to percent signal change
            - (light, since tedana) regression (projection) of:
                - per run motion and first differences
                - censor motion exceeding 0.2 ~mm from enorm time series,
                  or outliers exceeding 5% of brain 

            - QC options:
                -anat_follower (with skull), -radial_correlate_blocks,
                (-align_opts_aea) -check_flip, -volreg_compute_tsnr,
                -html_review_style

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',                  ['sub-005.ex4']],
        ['-dsets_me_run',             ['func/sub-005_rest_echo-1_bold.nii.gz',
                                       'func/sub-005_rest_echo-2_bold.nii.gz',
                                       'func/sub-005_rest_echo-3_bold.nii.gz']],
        ['-echo_times',               ['12.5', '27.6', '42.7']],
        ['-blip_forward_dset',        ['func/sub-005_blip-match.nii.gz[0]']],
        ['-blip_reverse_dset',        ['func/sub-005_blip-opp.nii.gz[0]']],
        ['-copy_anat',                ['ssw/anatSS.sub-005.nii']],
        ['-anat_has_skull',           ['no']],
        ['-anat_follower',            ['anat_w_skull', 'anat',
                                       'ssw/anatU.sub-005.nii']],
        ['-blocks',                   ['tshift', 'align', 'volreg', 'mask',
                                       'combine', 'surf', 'blur', 'scale',
                                       'regress']],
        ['-radial_correlate_blocks',  ['tcat', 'volreg']],
        ['-tcat_remove_first_trs',    ['4']],
        ['-tshift_interp',            ['-wsinc9']],
        ['-align_unifize_epi',        ['local']],
        ['-align_opts_aea',           ['-cost', 'lpc+ZZ', '-giant_move',
                                       '-check_flip']],
        ['-volreg_align_to',          ['MIN_OUTLIER']],
        ['-volreg_align_e2a',         []],
        ['-volreg_warp_final_interp', ['wsinc5']],
        ['-volreg_compute_tsnr',      ['yes']],
        ['-mask_epi_anat',            ['yes']],
        ['-combine_method',           ['m_tedana']],
        ['-surf_anat',                ['SUMA/sub-005_SurfVol.nii']],
        ['-surf_spec',                ['SUMA/std.141.sub-005_lh.spec',
                                       'SUMA/std.141.sub-005_rh.spec']],
        ['-blur_size',                ['4']],
        ['-regress_apply_mot_types',  ['demean', 'deriv']],
        ['-regress_motion_per_run',   []],
        ['-regress_censor_motion',    ['0.2']],
        ['-regress_censor_outliers',  ['0.05']],
        ['-html_review_style',        ['pythonic']],

       ],
     ))

   examples.append( APExample('AP publish 3e',
     source='AP_paper/scripts_rest/do_35_ap_ex5_vol.tcsh',
     descrip='do_35_ap_ex5_vol.tcsh - rest analysis, with bandpassing.',
     moddate='2024.08.27',
     keywords=['complete', 'noshow', 'physio', 'publish', 'rest'],
     header="""
              (recommended?  almost, bandpassing is not preferred)

         This example is based on the APMULTI_Demo1_rest tree, to perform a
         resting state analysis with a single echo time series.

         This is the same as AP publish 3c, but with bandpassing added.

         This is a resting state processing command, including:
            - physio regression, slicewise, before any temporal or volumetric
              alterations (and per-run, though there is only 1 run here)
            - slice timing correction (notably after physio regression)
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - NL warp to MNI152_2009 template, as computed by @SSwarper
            - apply 5 mm FWHM Gaussian blur, approx 1.5*voxel size
            - all registration transformations are concatenated
            - voxelwise scaling to percent signal change
            - regression (projection) of:
                - per run motion and first differences
                - bandpassing to include frequencies in [0.01, 0.1]
                - censor motion exceeding 0.2 ~mm from enorm time series,
                  or outliers exceeding 5% of brain 
            - estimate data blur from the regression residuals and the
              regression input (separately) using the mixed-model ACF function

            - QC options:
                -anat_follower (with skull), -anat_follower_ROI (FS GM mask),
                -radial_correlate_blocks, (-align_opts_aea) -check_flip,
                -volreg_compute_tsnr, -regress_make_corr_vols,
                -html_review_style

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
      ['-subj_id',                 ['sub-005.ex5']],
      ['-dsets',                   ['func/sub-005_rest_echo-2_bold.nii.gz']],
      ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
      ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
      ['-anat_has_skull',          ['no']],
      ['-anat_follower',           ['anat_w_skull', 'anat',
                                   'ssw/anatU.sub-005.nii']],
      ['-anat_follower_ROI',       ['aagm09', 'anat',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-anat_follower_ROI',       ['aegm09', 'epi',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-ROI_import',              ['BrodPijn', 'Brodmann_pijn_afni.nii.gz']],
      ['-ROI_import',              ['SchYeo7N', 'Schaefer_7N_400.nii.gz']],
      ['-blocks',                  ['ricor', 'tshift', 'align', 'tlrc',
                                    'volreg', 'mask', 'blur', 'scale',
                                    'regress']],
      ['-tcat_remove_first_trs',   ['4']],
      ['-ricor_regs',              ['physio/sub-005_rest_physio.slibase.1D']],
      ['-ricor_regs_nfirst',       ['4']],
      ['-ricor_regress_method',    ['per-run']],
      ['-align_unifize_epi',       ['local']],
      ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
      ['-tlrc_base',               ['MNI152_2009_template_SSW.nii.gz']],
      ['-tlrc_NL_warp',            []],
      ['-tlrc_NL_warped_dsets',    ['ssw/anatQQ.sub-005.nii',
                                    'ssw/anatQQ.sub-005.aff12.1D',
                                    'ssw/anatQQ.sub-005_WARP.nii']],
      ['-volreg_align_to',         ['MIN_OUTLIER']],
      ['-volreg_align_e2a',        []],
      ['-volreg_tlrc_warp',        []],
      ['-volreg_warp_dxyz',        ['3']],
      ['-volreg_compute_tsnr',     ['yes']],
      ['-mask_epi_anat',           ['yes']],
      ['-blur_size',               ['5']],
      ['-regress_bandpass',        ['0.01', '0.1']],
      ['-regress_apply_mot_types', ['demean', 'deriv']],
      ['-regress_motion_per_run',  []],
      ['-regress_censor_motion',   ['0.2']],
      ['-regress_censor_outliers', ['0.05']],
      ['-regress_make_corr_vols',  ['aegm09']],
      ['-regress_est_blur_epits',  []],
      ['-regress_est_blur_errts',  []],
      ['-regress_compute_tsnr_stats', ['BrodPijn', '7', '10', '12', '39',
                                       '107', '110', '112', '139']],
      ['-regress_compute_tsnr_stats', ['SchYeo7N', '161', '149', '7', '364',
                                       '367', '207']],
      ['-html_review_style',       ['pythonic']],
       ],
     ))

   examples.append( APExample('AP publish 3f',
     source='AP_paper/scripts_rest/do_36_ap_ex6_vol.tcsh',
     descrip='do_36_ap_ex6_vol.tcsh - rest analysis.',
     moddate='2024.08.30',
     keywords=['complete', 'noshow', 'physio', 'publish', 'rest'],
     header="""
              (recommended?  almost, this has extra regressors)

         This example is based on the APMULTI_Demo1_rest tree, to perform a
         resting state analysis with a single echo time series.

         This is the same as AP publish 3c, but with:
            - anat_follower_erode, ROI_PC, ANATICOR, extra followers

         This is a resting state processing command, including:
            - physio regression, slicewise, before any temporal or volumetric
              alterations (and per-run, though there is only 1 run here)
            - slice timing correction (notably after physio regression)
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - NL warp to MNI152_2009 template, as computed by @SSwarper
            - apply 8 mm FWHM Gaussian blur using -blur_to_fwhm to account
              for data from multiple sites
              * this results in the EPI being masked
            - all registration transformations are concatenated
            - voxelwise scaling to percent signal change
            - regression (projection) of:
                - per run motion and first differences
                - first 3 principle components from volreg ventricles
                  (per run, though only 1 run here)
                - fast ANATICOR: weighted local white matter (voxelwise regs)
                - censor motion exceeding 0.2 ~mm from enorm time series,
                  or outliers exceeding 5% of brain 
            - estimate data blur from the regression residuals and the
              regression input (separately) using the mixed-model ACF function

            - QC options:
                -anat_follower (with skull), -anat_follower_ROI (FS GM mask),
                -radial_correlate_blocks, (-align_opts_aea) -check_flip,
                -volreg_compute_tsnr, -regress_make_corr_vols,
                -html_review_style

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
      ['-subj_id',                 ['sub-005.ex6']],
      ['-dsets',                   ['func/sub-005_rest_echo-2_bold.nii.gz']],
      ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
      ['-anat_has_skull',          ['no']],
      ['-anat_follower',           ['anat_w_skull', 'anat',
                                   'ssw/anatU.sub-005.nii']],
      ['-anat_follower_ROI',       ['aaseg', 'anat',
                                    'SUMA/aparc.a2009s+aseg_REN_all.nii.gz']],
      ['-anat_follower_ROI',       ['aeseg', 'epi',
                                    'SUMA/aparc.a2009s+aseg_REN_all.nii.gz']],
      ['-anat_follower_ROI',       ['aagm09', 'anat',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-anat_follower_ROI',       ['aegm09', 'epi',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-anat_follower_ROI',       ['aagm00', 'anat',
                                   'SUMA/aparc+aseg_REN_gmrois.nii.gz']],
      ['-anat_follower_ROI',       ['aegm00', 'epi',
                                   'SUMA/aparc+aseg_REN_gmrois.nii.gz']],
      ['-anat_follower_ROI',       ['FSvent', 'epi',
                                    'SUMA/fs_ap_latvent.nii.gz']],
      ['-anat_follower_ROI',       ['FSWe', 'epi', 'SUMA/fs_ap_wm.nii.gz']],
      ['-anat_follower_erode',     ['FSvent', 'FSWe']],
      ['-ROI_import',              ['BrodPijn', 'Brodmann_pijn_afni.nii.gz']],
      ['-ROI_import',              ['SchYeo7N', 'Schaefer_7N_400.nii.gz']],
      ['-blocks',                  ['ricor', 'tshift', 'align', 'tlrc',
                                    'volreg', 'mask', 'blur', 'scale',
                                    'regress']],
      ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
      ['-tcat_remove_first_trs',   ['4']],
      ['-ricor_regs',              ['physio/sub-005_rest_physio.slibase.1D']],
      ['-ricor_regs_nfirst',       ['4']],
      ['-ricor_regress_method',    ['per-run']],
      ['-align_unifize_epi',       ['local']],
      ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
      ['-tlrc_base',               ['MNI152_2009_template_SSW.nii.gz']],
      ['-tlrc_NL_warp',            []],
      ['-tlrc_NL_warped_dsets',    ['ssw/anatQQ.sub-005.nii',
                                    'ssw/anatQQ.sub-005.aff12.1D',
                                    'ssw/anatQQ.sub-005_WARP.nii']],
      ['-volreg_align_to',         ['MIN_OUTLIER']],
      ['-volreg_align_e2a',        []],
      ['-volreg_tlrc_warp',        []],
      ['-volreg_warp_dxyz',        ['3']],
      ['-volreg_compute_tsnr',     ['yes']],
      ['-mask_epi_anat',           ['yes']],
      ['-blur_size',               ['8']],
      ['-blur_to_fwhm',            []],
      ['-regress_apply_mot_types', ['demean', 'deriv']],
      ['-regress_motion_per_run',  []],
      ['-regress_anaticor_fast',   []],
      ['-regress_anaticor_label',  ['FSWe']],
      ['-regress_ROI_PC',          ['FSvent', '3']],
      ['-regress_ROI_PC_per_run',  ['FSvent']],
      ['-regress_censor_motion',   ['0.2']],
      ['-regress_censor_outliers', ['0.05']],
      ['-regress_make_corr_vols',  ['aeseg', 'FSvent']],
      ['-regress_est_blur_epits',  []],
      ['-regress_est_blur_errts',  []],
      ['-regress_compute_tsnr_stats', ['BrodPijn', '7', '10', '12', '39',
                                       '107', '110', '112', '139']],
      ['-regress_compute_tsnr_stats', ['SchYeo7N', '161', '149', '7', '364',
                                       '367', '207']],
      ['-html_review_style',       ['pythonic']],
       ],
     ))

   examples.append( APExample('AP publish 3g',
     source='AP_paper/scripts_rest/do_37_ap_ex7_roi.tcsh',
     descrip='do_37_ap_ex7_roi.tcsh - rest analysis.',
     moddate='2024.08.29',
     keywords=['complete', 'noshow', 'physio', 'publish', 'rest'],
     header="""
              (recommended?  yes, an example of resting state analysis)

         This example is based on the APMULTI_Demo1_rest tree, to perform a
         resting state analysis with a single echo time series.

         This is the same as AP publish 3c, but it is for an ROI analysis,
         and so does not have any 'blur' block or blur_size.

         This is a resting state processing command, including:
            - physio regression, slicewise, before any temporal or volumetric
              alterations (and per-run, though there is only 1 run here)
            - slice timing correction (notably after physio regression)
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - NL warp to MNI152_2009 template, as computed by @SSwarper
            - do not apply any blur, to avoid corrupting regions of interest
            - all registration transformations are concatenated
            - voxelwise scaling to percent signal change
            - regression (projection) of:
                - per run motion and first differences
                - censor motion exceeding 0.2 ~mm from enorm time series,
                  or outliers exceeding 5% of brain 
            - estimate data blur from the regression residuals and the
              regression input (separately) using the mixed-model ACF function

            - QC options:
                -anat_follower (with skull), -anat_follower_ROI (FS GM mask),
                -radial_correlate_blocks, (-align_opts_aea) -check_flip,
                -volreg_compute_tsnr, -regress_make_corr_vols,
                -html_review_style

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
      ['-subj_id',                 ['sub-005.ex7']],
      ['-dsets',                   ['func/sub-005_rest_echo-2_bold.nii.gz']],
      ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
      ['-anat_has_skull',          ['no']],
      ['-anat_follower',           ['anat_w_skull', 'anat',
                                   'ssw/anatU.sub-005.nii']],
      ['-anat_follower_ROI',       ['aagm09', 'anat',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-anat_follower_ROI',       ['aegm09', 'epi',
                                   'SUMA/aparc.a2009s+aseg_REN_gmrois.nii']],
      ['-ROI_import',              ['BrodPijn', 'Brodmann_pijn_afni.nii.gz']],
      ['-ROI_import',              ['SchYeo7N', 'Schaefer_7N_400.nii.gz']],
      ['-blocks',                  ['ricor', 'tshift', 'align', 'tlrc',
                                    'volreg', 'mask', 'scale', 'regress']],
      ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
      ['-tcat_remove_first_trs',   ['4']],
      ['-ricor_regs',              ['physio/sub-005_rest_physio.slibase.1D']],
      ['-ricor_regs_nfirst',       ['4']],
      ['-ricor_regress_method',    ['per-run']],
      ['-align_unifize_epi',       ['local']],
      ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
      ['-tlrc_base',               ['MNI152_2009_template_SSW.nii.gz']],
      ['-tlrc_NL_warp',            []],
      ['-tlrc_NL_warped_dsets',    ['ssw/anatQQ.sub-005.nii',
                                    'ssw/anatQQ.sub-005.aff12.1D',
                                    'ssw/anatQQ.sub-005_WARP.nii']],
      ['-volreg_align_to',         ['MIN_OUTLIER']],
      ['-volreg_align_e2a',        []],
      ['-volreg_tlrc_warp',        []],
      ['-volreg_warp_dxyz',        ['3']],
      ['-volreg_compute_tsnr',     ['yes']],
      ['-mask_epi_anat',           ['yes']],
      ['-regress_apply_mot_types', ['demean', 'deriv']],
      ['-regress_motion_per_run',  []],
      ['-regress_censor_motion',   ['0.2']],
      ['-regress_censor_outliers', ['0.05']],
      ['-regress_make_corr_vols',  ['aegm09']],
      ['-regress_est_blur_epits',  []],
      ['-regress_est_blur_errts',  []],
      ['-regress_compute_tsnr_stats', ['BrodPijn', '7', '10', '12', '39',
                                       '107', '110', '112', '139']],
      ['-regress_compute_tsnr_stats', ['SchYeo7N', '161', '149', '7', '364',
                                       '367', '207']],
      ['-html_review_style',       ['pythonic']],
       ],
     ))

   examples.append( APExample('AP publish 3h',
     source='AP_paper/scripts_rest/do_38_ap_ex8_mesurf_oc.tcsh',
     descrip='do_38_ap_ex8_mesurf_oc.tcsh - multi-echo surface analysis.',
     moddate='2024.09.04',
     keywords=['complete', 'blip', 'ME', 'noshow', 'publish',
               'rest', 'surface'],
     header="""
              (recommended?  yes)

         This example is based on the APMULTI_Demo1_rest tree, to perform a
         resting state analysis on the surface with multi-echo data.

         This is the same as AP publish 3d, but it uses AFNI's OC echo combine
         method rather than tedana (-combine_method).  Because a mask is not
         required, the mask block and option have also been removed (though it
         is certainly fine to keep them).

         This is a surface-based resting state processing command, including:
            - slice timing correction (using wsinc9 interpolation)
            - distortion correction using reverse blip phase encoding
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - all registration transformations are concatenated, and
              based on echo 2 (as we did not specify), but applied to all
              echoes, and resampled using a wsinc9 interpolant
            - echos are combined and then "cleaned" by tedana
            - the EPI time series are then  projected onto the surface
              (a previously computed set of surfaces, registered to the
              current anat, making a new SurfVol_Alnd_Exp anat dset)
                - might have surf data gaps, due to coverage
            - (light) blurring _to_ of FWHM of 4 mm is applied on the surface
            - nodewise scaling to percent signal change
            - (light, since tedana) regression (projection) of:
                - per run motion and first differences
                - censor motion exceeding 0.2 ~mm from enorm time series,
                  or outliers exceeding 5% of brain 

            - QC options:
                -anat_follower (with skull), -radial_correlate_blocks,
                (-align_opts_aea) -check_flip, -volreg_compute_tsnr,
                -html_review_style

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',                  ['sub-005.ex8']],
        ['-dsets_me_run',             ['func/sub-005_rest_echo-1_bold.nii.gz',
                                       'func/sub-005_rest_echo-2_bold.nii.gz',
                                       'func/sub-005_rest_echo-3_bold.nii.gz']],
        ['-echo_times',               ['12.5', '27.6', '42.7']],
        ['-blip_forward_dset',        ['func/sub-005_blip-match.nii.gz[0]']],
        ['-blip_reverse_dset',        ['func/sub-005_blip-opp.nii.gz[0]']],
        ['-copy_anat',                ['ssw/anatSS.sub-005.nii']],
        ['-anat_has_skull',           ['no']],
        ['-anat_follower',            ['anat_w_skull', 'anat',
                                       'ssw/anatU.sub-005.nii']],
        ['-blocks',                   ['tshift', 'align', 'volreg',
                                       'combine', 'surf', 'blur', 'scale',
                                       'regress']],
        ['-radial_correlate_blocks',  ['tcat', 'volreg']],
        ['-tcat_remove_first_trs',    ['4']],
        ['-tshift_interp',            ['-wsinc9']],
        ['-align_unifize_epi',        ['local']],
        ['-align_opts_aea',           ['-cost', 'lpc+ZZ', '-giant_move',
                                       '-check_flip']],
        ['-volreg_align_to',          ['MIN_OUTLIER']],
        ['-volreg_align_e2a',         []],
        ['-volreg_warp_final_interp', ['wsinc5']],
        ['-volreg_compute_tsnr',      ['yes']],
        ['-combine_method',           ['OC']],
        ['-surf_anat',                ['SUMA/sub-005_SurfVol.nii']],
        ['-surf_spec',                ['SUMA/std.141.sub-005_lh.spec',
                                       'SUMA/std.141.sub-005_rh.spec']],
        ['-blur_size',                ['4']],
        ['-regress_apply_mot_types',  ['demean', 'deriv']],
        ['-regress_motion_per_run',   []],
        ['-regress_censor_motion',    ['0.2']],
        ['-regress_censor_outliers',  ['0.05']],
        ['-html_review_style',        ['pythonic']],

       ],
     ))

   examples.append( APExample('AP publish 3i',
     source='AP_paper/scripts_rest/do_39_ap_ex9_mevol_oc.tcsh',
     descrip='do_39_ap_ex9_mevol_oc.tcsh - ME volume rest analysis.',
     moddate='2024.08.27',
     keywords=['blip', 'complete', 'ME', 'publish', 'rest'],
     header="""
              (recommended?  yes, an example of resting state analysis)

         This example is based on the APMULTI_Demo1_rest tree, to perform a
         resting state analysis with a multi-echo time series.

         This is a multi-echo resting state processing command, including:
            - 1 run with 3 echoes of EPI time series data
            - reverse phase encoding distortion correction
            - slice timing correction
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - NL warp to MNI152_2009 template, as computed by sswarper2
            - apply 4 mm FWHM Gaussian blur, approx 1.5*voxel size,
              but lower because of multi-echo noise cancellation
            - all registration transformations are concatenated
            - combine echoes using the base OC (optimally combined) method
            - voxelwise scaling to percent signal change
            - regression (projection) of:
                - per run motion and first differences
                - censor motion exceeding 0.2 ~mm from enorm time series,
                  or outliers exceeding 5% of brain 
            - estimate data blur from the regression residuals and the
              regression input (separately) using the mixed-model ACF function

            - QC options:
                -anat_follower (with skull), -anat_follower_ROI (Brodmann
                 and Schaefer ROIs) for TSNR statistics
                -radial_correlate_blocks, (-align_opts_aea) -check_flip,
                -volreg_compute_tsnr, -html_review_style

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
      ['-subj_id',                 ['sub-005.ex9']],
      ['-dsets_me_run',            ['func/sub-005_rest_r1_e1_bold.nii.gz',
                                    'func/sub-005_rest_r1_e2_bold.nii.gz',
                                    'func/sub-005_rest_r1_e3_bold.nii.gz']],
      ['-echo_times',              ['12.5', '27.6', '42.7']],
      ['-blip_forward_dset',       ['func/sub-005_blip-match.nii.gz[0]']],
      ['-blip_reverse_dset',       ['func/sub-005_blip-opp.nii.gz[0]']],
      ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
      ['-anat_has_skull',          ['no']],
      ['-anat_follower',           ['anat_w_skull', 'anat',
                                   'ssw/anatU.sub-005.nii']],
      ['-ROI_import',              ['BrodPijn', 'Brodmann_pijn_afni.nii.gz']],
      ['-ROI_import',              ['SchYeo7N', 'Schaefer_7N_400.nii.gz']],
      ['-blocks',                  ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'combine', 'blur', 'scale',
                                    'regress']],
      ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
      ['-tcat_remove_first_trs',   ['4']],
      ['-align_unifize_epi',       ['local']],
      ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
      ['-tlrc_base',               ['MNI152_2009_template_SSW.nii.gz']],
      ['-tlrc_NL_warp',            []],
      ['-tlrc_NL_warped_dsets',    ['ssw/anatQQ.sub-005.nii',
                                    'ssw/anatQQ.sub-005.aff12.1D',
                                    'ssw/anatQQ.sub-005_WARP.nii']],
      ['-volreg_align_to',         ['MIN_OUTLIER']],
      ['-volreg_align_e2a',        []],
      ['-volreg_tlrc_warp',        []],
      ['-volreg_warp_dxyz',        ['3']],
      ['-volreg_compute_tsnr',     ['yes']],
      ['-mask_epi_anat',           ['yes']],
      ['-combine_method',          ['OC']],
      ['-blur_size',               ['4']],
      ['-regress_censor_motion',   ['0.2']],
      ['-regress_censor_outliers', ['0.05']],
      ['-regress_apply_mot_types', ['demean', 'deriv']],
      ['-regress_motion_per_run',  []],
      ['-regress_est_blur_epits',  []],
      ['-regress_est_blur_errts',  []],
      ['-regress_compute_tsnr_stats', ['BrodPijn', '7', '10', '12', '39',
                                       '107', '110', '112', '139']],
      ['-regress_compute_tsnr_stats', ['SchYeo7N', '161', '149', '7', '364',
                                       '367', '207']],
      ['-html_review_style',       ['pythonic']],
     ],
     ))

   examples.append( APExample('AP publish 3j',
     source='AP_paper/scripts_task/do_40_ap_ex10_task_bder.tcsh',
     descrip='do_40_ap_ex10_task_bder.tcsh - pamenc task analysis.',
     moddate='2024.02.20',
     keywords=['complete', 'noshow', 'publish', 'task'],
     header="""
              (recommended?  yes, for a volumetric task analysis)

         This example is based on the AFNI_demos/AFNI_pamenc data.

         This is the same as AP publish 3b, but it sets taskname as a uvar
         and outputs an extra bids derivative tree.

         This is a full analysis, including:
            - slice time correction (alt+z2 timing pattern)
            - EPI registration to MIN_OUTLIER vr_base volume
            - EPI/anat alignment, with -align_unifize_epi local
            - NL warp to MNI152_2009 template, as computed by @SSwarper
            - all registration transformations are concatenated
            - computing an EPI mask intersected with the anatomical mask
              for blurring and QC (-mask_epi_anat)
            - applying a 6 mm FWHM Gaussian blur, restricted to the EPI mask
            - voxelwise scaling to percent signal change
            - linear regression of task events using duration modulation with
              the BLOCK basis function (dmUBLOCK(-1)), where the ideal response
              height is unit for a 1 s event; stim_type AM1 is required here
            - censoring time points where motion exceeds 0.3 mm or the outlier
              fraction exceeds 5%
            - regression is performed by 3dREMLfit, accounting for voxelwise
              temporal autocorrelation in the noise
            - estimate data blur from the regression residuals using
              the mixed-model ACF function

            - QC options:
                -anat_follower (with skull), (-align_opts_aea) -check_flip,
                -radial_correlate_blocks, -volreg_compute_tsnr,
                -regress_make_ideal_sum, -html_review_style

         * input dataset names have been shortened

            """,
     trailer=""" """,
     olist = [
      ['-subj_id',                      ['sub-10506.ex10']],
      ['-uvar',                         ['taskname', 'pamenc']],
      ['-dsets',                        ['func/sub-10506_pamenc_bold.nii.gz']],
      ['-copy_anat',                    ['ssw/anatSS.sub-10506.nii']],
      ['-anat_has_skull',               ['no']],
      ['-anat_follower',                ['anat_w_skull', 'anat',
                                         'ssw/anatU.sub-10506.nii']],
      ['-blocks',                       ['tshift', 'align', 'tlrc', 'volreg',
                                         'mask', 'blur', 'scale', 'regress']],
      ['-radial_correlate_blocks',      ['tcat', 'volreg', 'regress']],
      ['-tcat_remove_first_trs',        ['0']],
      ['-tshift_opts_ts',               ['-tpattern', 'alt+z2']],
      ['-align_unifize_epi',            ['local']],
      ['-align_opts_aea',               ['-giant_move', '-cost', 'lpc+ZZ',
                                         '-check_flip']],
      ['-tlrc_base',                    ['MNI152_2009_template_SSW.nii.gz']],
      ['-tlrc_NL_warp',                 []],
      ['-tlrc_NL_warped_dsets',         ['ssw/anatQQ.sub-10506.nii',
                                         'ssw/anatQQ.sub-10506.aff12.1D',
                                         'ssw/anatQQ.sub-10506_WARP.nii']],
      ['-volreg_align_to',              ['MIN_OUTLIER']],
      ['-volreg_align_e2a',             []],
      ['-volreg_tlrc_warp',             []],
      ['-volreg_warp_dxyz',             ['3.0']],
      ['-volreg_compute_tsnr',          ['yes']],
      ['-mask_epi_anat',                ['yes']],
      ['-blur_size',                    ['6']],
      ['-blur_in_mask',                 ['yes']],
      ['-regress_stim_times',           ['timing/times.CONTROL.txt',
                                         'timing/times.TASK.txt']],
      ['-regress_stim_labels',          ['CONTROL', 'TASK']],
      ['-regress_stim_types',           ['AM1']],
      ['-regress_basis_multi',          ['dmUBLOCK(-1)']],
      ['-regress_opts_3dD',             ['-jobs', '8',
                                         '-gltsym', 'SYM: TASK -CONTROL',
                                         '-glt_label', '1', 'T-C',
                                         '-gltsym',
                                         'SYM: 0.5*TASK +0.5*CONTROL',
                                         '-glt_label', '2', 'meanTC']],
      ['-regress_motion_per_run',       []],
      ['-regress_censor_motion',        ['0.3']],
      ['-regress_censor_outliers',      ['0.05']],
      ['-regress_compute_fitts',        []],
      ['-regress_fout',                 ['no']],
      ['-regress_3dD_stop',             []],
      ['-regress_reml_exec',            []],
      ['-regress_make_ideal_sum',       ['sum_ideal.1D']],
      ['-regress_est_blur_errts',       []],
      ['-regress_run_clustsim',         ['no']],
      ['-html_review_style',            ['pythonic']],
      ['-bids_deriv',                   ['yes']],
       ],
     ))

   return examples

def egs_demo():
   """AP demo examples
   """

   examples =  []

   examples.append( APExample('AP demo 1a',
     source='ap_run_simple_rest.tcsh',
     descrip='for QC, ap_run_simple_rest.tcsh with EPI and anat',
     moddate='2024.02.20',
     keywords=['rest'],
     header="""
              (recommended?  yes, for quick quality control)

         This example was generated by running ap_run_simple_rest.tcsh,
         providing a single subject anat and (3 runs of) EPI.  It could
         be generated (and run) using the following:

            cd AFNI_data6/FT_analysis/FT
            ap_run_simple_rest.tcsh -subjid FT -run_proc \\
              -anat FT_anat+orig -epi FT_epi_r*.HEAD

         This is highly recommended as a tool for quick quality control to be
         run on all EPI data right out of the scanner.  It is fine to run on
         task data, but without worrying about the actual task regression.

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT']],
        ['-dsets',                 ['FT/FT_epi_r1+orig.HEAD',
                                    'FT/FT_epi_r2+orig.HEAD',
                                    'FT/FT_epi_r3+orig.HEAD']],
        ['-copy_anat',             ['FT_anat+orig']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
        ['-tcat_remove_first_trs', ['2']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template_SSW.nii.gz']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-volreg_compute_tsnr',   ['yes']],
        ['-mask_epi_anat',         ['yes']],
        ['-blur_size',             ['6']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.25']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-regress_make_ideal_sum',  ['sum_ideal.1D']],
        ['-html_review_style',     ['pythonic']],
       ],
     ))

   examples.append( APExample('AP demo 1b',
     source='ap_run_simple_rest.tcsh',
     descrip='for QC, ap_run_simple_rest.tcsh with no anat',
     moddate='2022.11.23',
     keywords=['rest'],
     header="""
              (recommended?  yes, for quick quality control of EPI)

         This example was generated by running ap_run_simple_rest.tcsh,
         providing only 3 runs of EPI data.  It could be generated (and run)
         using the following:

            cd AFNI_data6/FT_analysis/FT
            ap_run_simple_rest.tcsh -subjid FT -run_proc -epi FT_epi_r*.HEAD

         No anatomical volume is included, excluding many options from
         example simple_rest_QC.

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['FT']],
        ['-script',                ['proc.FT']],
        ['-out_dir',               ['FT.results']],
        ['-dsets',                 ['FT/FT_epi_r1+orig.HEAD',
                                    'FT/FT_epi_r2+orig.HEAD',
                                    'FT/FT_epi_r3+orig.HEAD']],
        ['-blocks',                ['tshift', 'volreg', 'mask',
                                    'blur', 'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg']],
        ['-tcat_remove_first_trs', ['2']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_compute_tsnr',   ['yes']],
        ['-blur_size',             ['6']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.25']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-regress_make_ideal_sum',  ['sum_ideal.1D']],
        ['-html_review_style',     ['pythonic']],
       ],
     ))

   examples.append( APExample('AP demo 1c',
     source='ap_run_simple_rest_me.tcsh',
     descrip='for QC, ap_run_simple_rest_me.tcsh with ME EPI and anat',
     moddate='2024.08.09',
     keywords=['rest', 'ME'],
     header="""
              (recommended?  yes, for quick quality control)

         This example was generated by running ap_run_simple_rest_me.tcsh,
         providing a single subject anat, EPI (1 run of 3 echoes), and
         the 3 echo times.

         It could be generated using the following, where the dataset names
         have been slightly truncated to save screen space:

            cd data_00_basic/sub-005/ses-01
            ap_run_simple_rest_me.tcsh                                  \\
                -run_ap                                                 \\
                -subjid      sub-005                                    \\
                -nt_rm       4                                          \\
                -anat        anat/sub-005*mprage_run-1_T1w.nii.gz       \\
                -epi_me_run  func/sub-005*rest*bold.nii.gz              \\
                -echo_times  12.5 27.6 42.7                             \\
                -template    MNI152_2009_template_SSW.nii.gz

         This is highly recommended as a tool for quick quality control to be
         run on all EPI data right out of the scanner.

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',               ['sub-005']],
        ['-dsets_me_run',          ['func/sub-005_rest_r1_e1_bold.nii.gz',
                                    'func/sub-005_rest_r1_e2_bold.nii.gz',
                                    'func/sub-005_rest_r1_e3_bold.nii.gz']],
        ['-echo_times',            ['12.5', '27.6', '42.7']],
        ['-reg_echo',              ['2']],
        ['-copy_anat',             ['anat/sub-005_mprage_run-1_T1w.nii.gz']],
        ['-blocks',                ['tshift', 'align', 'tlrc', 'volreg',
                                    'mask', 'combine', 'blur', 'scale',
                                    'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg', 'regress']],
        ['-tcat_remove_first_trs', ['4']],
        ['-tshift_interp',         ['-wsinc9']],
        ['-align_unifize_epi',     ['local']],
        ['-align_opts_aea',        ['-cost', 'lpc+ZZ', '-giant_move',
                                    '-check_flip']],
        ['-tlrc_base',             ['MNI152_2009_template_SSW.nii.gz']],
        ['-volreg_align_to',       ['MIN_OUTLIER']],
        ['-volreg_align_e2a',      []],
        ['-volreg_tlrc_warp',      []],
        ['-volreg_warp_final_interp', ['wsinc5']],
        ['-volreg_compute_tsnr',   ['yes']],
        ['-mask_epi_anat',         ['yes']],
        ['-combine_method',        ['OC']],
        ['-blur_size',             ['4']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run', []],
        ['-regress_censor_motion', ['0.25']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_est_blur_epits', []],
        ['-regress_est_blur_errts', []],
        ['-regress_make_ideal_sum',  ['sum_ideal.1D']],
        ['-html_review_style',     ['pythonic']],
       ],
     ))

   examples.append( APExample('AP demo 2a',
     source='APMULTI_Demo1_rest/scripts_desktop/do_20_ap_se.tcsh',
     descrip='do_20_ap_se.tcsh - one way to process rest data',
     moddate='2023.04.19',
     keywords=['complete', 'rest'],
     header="""
              (recommended?  somewhat, includes tissue-based regression)

         This example is part of the APMULTI_Demo1_rest tree, installable by
         running :

            @Install_APMULTI_Demo1_rest

         This is a sample rest processing command, including:

            - despike block for high motion subjects

            - QC options:
                -radial_correlate_blocks, (-align_opts_aea) -check_flip
                -volreg_compute_tsnr, -regress_make_corr_vols,
                -html_review_style, -anat_follower_ROI (some are for QC)

            - non-linear template alignment (precomputed warp is provided)

            - noise removal of:
                - motion and derivatives, per run
                - ventricle principal components (top 3 per run)
                - fast ANATICOR
                - censoring for both motion and outliers

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',                 ['sub-005']],
        ['-dsets',                   ['func/sub-005_rest_echo-2_bold.nii.gz']],
        ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
        ['-anat_has_skull',          ['no']],
        ['-anat_follower',           ['anat_w_skull', 'anat',
                                      'ssw/anatU.sub-005.nii']],
        ['-anat_follower_ROI',       ['aaseg', 'anat',
                                      'SUMA/aparc.a2009s+aseg_REN_all.nii.gz']],
        ['-anat_follower_ROI',       ['aeseg', 'epi',
                                      'SUMA/aparc.a2009s+aseg_REN_all.nii.gz']],
        ['-anat_follower_ROI',       ['FSvent', 'epi',
                                      'SUMA/fs_ap_latvent.nii.gz']],
        ['-anat_follower_ROI',       ['FSWe', 'epi', 'SUMA/fs_ap_wm.nii.gz']],
        ['-anat_follower_erode',     ['FSvent', 'FSWe']],
        ['-blocks',                  ['despike', 'tshift', 'align', 'tlrc',
                                      'volreg', 'mask', 'blur', 'scale',
                                      'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg']],
        ['-tcat_remove_first_trs',   ['4']],
        ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                      '-check_flip']],
        ['-tlrc_base',               ['MNI152_2009_template_SSW.nii.gz']],
        ['-tlrc_NL_warp',            []],
        ['-tlrc_NL_warped_dsets',    ['ssw/anatQQ.sub-005.nii',
                                      'ssw/anatQQ.sub-005.aff12.1D',
                                      'ssw/anatQQ.sub-005_WARP.nii']],
        ['-volreg_align_to',         ['MIN_OUTLIER']],
        ['-volreg_align_e2a',        []],
        ['-volreg_tlrc_warp',        []],
        ['-volreg_warp_dxyz',        ['3']],
        ['-volreg_compute_tsnr',     ['yes']],
        ['-mask_epi_anat',           ['yes']],
        ['-blur_size',               ['5']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run',  []],
        ['-regress_anaticor_fast',   []],
        ['-regress_anaticor_label',  ['FSWe']],
        ['-regress_ROI_PC',          ['FSvent', '3']],
        ['-regress_ROI_PC_per_run',  ['FSvent']],
        ['-regress_censor_motion',   ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_make_corr_vols',  ['aeseg', 'FSvent']],
        ['-regress_est_blur_epits',  []],
        ['-regress_est_blur_errts',  []],
        ['-html_review_style',       ['pythonic']],
       ],
     ))

   examples.append( APExample('AP demo 2b',
     source='APMULTI_Demo1_rest/scripts_desktop/do_44_ap_me_bTs.tcsh',
     descrip='do_44_ap_me_bTs.tcsh - ME surface rest with tedana',
     moddate='2024.01.04',
     keywords=['complete', 'blip', 'ME', 'rest', 'surface', 'tedana'],
     header="""
              (recommended?  yes)

         This example is based on the APMULTI_Demo1_rest tree, installable by
         running :

            @Install_APMULTI_Demo1_rest

         This is a sample rest processing command, including:

            - reverse phase encoding (blip) distortion correction
              (-blip_forward_dset, -blip_reverse_dset)
            - multi-echo EPI (-dsets_me_run, -echo_times)
            - MEICA-group tedana usage
              (-combine_method m_tedana, -volreg_warp_final_interp wsinc5)

            - surface-based analysis (-surf_anat, -surf_spec)

            - despike block for high motion subjects

            - QC options:
                -radial_correlate_blocks, -align_opts_aea -check_flip,
                -volreg_compute_tsnr, -regress_make_corr_vols,
                -anat_follower anat_w_skull, -anat_follower_ROI (some for QC),
                -html_review_style

            - noise removal of:
                - tedana
                - motion and derivatives, per run
                - censoring for both motion and outliers

         * input dataset names have been shortened to protect the margins

            """,
     trailer=""" """,
     olist = [
        ['-subj_id',                 ['sub-005']],
        ['-dsets_me_run',            ['func/sub-005_rest_echo-1_bold.nii.gz',
                                      'func/sub-005_rest_echo-2_bold.nii.gz',
                                      'func/sub-005_rest_echo-3_bold.nii.gz']],
        ['-echo_times',              ['12.5', '27.6', '42.7']],
        ['-blip_forward_dset',       ['func/sub-005_blip-match.nii.gz[0]']],
        ['-blip_reverse_dset',       ['func/sub-005_blip-opp.nii.gz[0]']],
        ['-copy_anat',               ['ssw/anatSS.sub-005.nii']],
        ['-anat_has_skull',          ['no']],
        ['-anat_follower',           ['anat_w_skull', 'anat',
                                      'ssw/anatU.sub-005.nii']],
        ['-anat_follower_ROI',       ['aaseg', 'anat',
                                      'SUMA/aparc.a2009s+aseg_REN_all.nii.gz']],
        ['-anat_follower_ROI',       ['aeseg', 'epi',
                                      'SUMA/aparc.a2009s+aseg_REN_all.nii.gz']],
        ['-anat_follower_ROI',       ['FSvent', 'epi',
                                      'SUMA/fs_ap_latvent.nii.gz']],
        ['-anat_follower_ROI',       ['FSWe', 'epi', 'SUMA/fs_ap_wm.nii.gz']],
        ['-anat_follower_erode',     ['FSvent', 'FSWe']],
        ['-blocks',                  ['despike', 'tshift', 'align', 'volreg',
                                      'mask', 'combine', 'surf', 'blur',
                                      'scale', 'regress']],
        ['-radial_correlate_blocks', ['tcat', 'volreg']],
        ['-tcat_remove_first_trs',   ['4']],
        ['-tshift_interp',           ['-wsinc9']],
        ['-align_unifize_epi',       ['local']],
        ['-align_opts_aea',          ['-cost', 'lpc+ZZ', '-giant_move',
                                      '-check_flip']],
        ['-volreg_align_to',         ['MIN_OUTLIER']],
        ['-volreg_align_e2a',        []],
        ['-volreg_warp_final_interp',['wsinc5']],
        ['-volreg_compute_tsnr',     ['yes']],
        ['-mask_epi_anat',           ['yes']],
        ['-combine_method',          ['m_tedana']],
        ['-surf_anat',               ['SUMA/sub-005_SurfVol.nii']],
        ['-surf_spec',               ['SUMA/std.141.sub-005_lh.spec',
                                      'SUMA/std.141.sub-005_rh.spec']],
        ['-blur_size',               ['4']],
        ['-regress_apply_mot_types', ['demean', 'deriv']],
        ['-regress_motion_per_run',  []],
        ['-regress_censor_motion',   ['0.2']],
        ['-regress_censor_outliers', ['0.05']],
        ['-regress_make_corr_vols',  ['aeseg', 'FSvent']],
        ['-html_review_style',       ['pythonic']],
       ],
     ))

   return examples

def egs_short():
   """AP short examples (examples of only partial processing)
   """

   examples =  []

   return examples

def find_eg(name):
   """try to find a matching ap_examples instance

      consider things like:
        if failure, and if 'name' is substring of only 1 example, return it

      return None on failure
   """
   global ap_examples
   populate_examples()

   if len(name) < 1: return None

   # use lower case for searching names
   nlist = [eg.name.lower() for eg in ap_examples]
   lname = name.lower()

   # if lname is exactly (no case) in nlist, return the respective example
   if lname in nlist:
      return ap_examples[nlist.index(lname)]

   # otherwise, try harder

   # If number (possibly with trailing a,b,c,...) search after 'example'.
   if lname[0].isdigit():
      tname = 'example ' + lname
      if tname in nlist:
         return ap_examples[nlist.index(tname)]

   # otherwise, just see if there is a unique substring match
   ind = unique_substr_name_index(lname, nlist)
   if ind >= 0:
      return ap_examples[ind]

   return None

def unique_substr_name_index(nsub, nlist, endswith=0):
   """search for nsub in nlist, where nsub can be a substring
      if endswith, use name.endswith(), rather than name.find()
      return : index >= 0 on success
             : -1, if no match is found
             : -2, if the match is not uniq
   """
   findex = -1
   for ind, name in enumerate(nlist):
      # first, check to see if nsub matches name
      found = 0
      if endswith:
         if name.endswith(nsub):
            found = 1
      elif name.find(nsub) >= 0:
         found = 1

      # if not, just move along
      if not found:
         continue

      # if so, fail on non-unique
      if findex >= 0:
         # not unique
         return -2

      # we have a match, keep looking for non-uniqueness
      findex = ind

   # we have either failed to find a match, or have a unique one
   # - either way, return findex
   return findex

def show_enames(verb=1):
   """list all ap_example names
   """
   global ap_examples
   populate_examples()

   if len(ap_examples) == 0:
      return

   nlist = [eg.name for eg in ap_examples]

   # basic: show list
   if verb == 0:
      print("%s" % nlist)
      return

   # nicer: show pretty list
   if verb == 1:
      istr = ' '*2
      jstr = '\n%s' % istr
      print("%s%s\n" % (istr, jstr.join(nlist)))
      return

   # so verb > 1
   maxn = max([len(name) for name in nlist])
   indent = ' '*2
   for eg in ap_examples:
      if verb <= 2: dstr = ''
      else:         dstr = '%s : ' % eg.moddate
      print("%s%-*s : %s%s" % (indent, maxn, eg.name, dstr, eg.descrip))

def compare_eg_pair(eg1, eg2, eskip=[], verb=1):
   """similar to compare(), above, but compare 2 known examples"""

   # set names and get an instance for the first entry, eg1
   if isinstance(eg1, APExample):
      n1 = eg1.name
      eg = eg1
   else:
      n1 = eg1
      eg = find_eg(eg1)
      if not isinstance(eg, APExample):
         print("** compare_eg_pair: failed to find example named '%s'" % n1)
         return

   # so eg is the instance of eg1, just use it
   return eg.compare(eg2, eskip=eskip, verb=verb)

def display_eg_all(aphelp=1, source='', verb=0):
   """display the examples array if someone wants it
         aphelp :  1   show only AP help examples
                   0   show only others
                  -1   show all (leaving higher numbers for other cases)
         source : if set, restrict to matching
         verb   : verbosity level, pass on to eg.display
   """
   global ap_examples

   for eg in ap_examples:
      # skip what we do not want to show
      if aphelp >= 0 and aphelp != eg.aphelp:
         continue
      if source != '' and source != eg.source:
         continue
      eg.display(verb=verb)

if __name__ == '__main__':
   print('** this is not a main module')
   sys.exit(1)

