###################################################################
UPDATE: 20 Mar 2017
###################################################################

Convert fsaverage annotation to single-subject 3D ROIs

In order to take best advantage of surface-defined
ROIs (e.g., HCP annotation) in 3D-based processing
streams, the surface ROIs should be back-sampled
to individual subject surfaces so individual
subject, average-surface-defined, gray-matter-only
3D ROI masks can be defined.  There is a new
tksurfer tcl script, annot2roi.tcl, to automate
this.  The main steps are:

  1) fsaverage surf annotation -> indiv subject annotation
  2) annotation region -> 3D rawdata-aligned ROI

The voxel size and orientation of the output mask
ROI BRIK's is inherited from a functional BRIK, so
there must be at least one functional BRIK set in
the scandir.  The mapping from fsaverage surface
to 3D ROIs uses mri_surf2surf and the
auto-generated sphere.reg file, and then the
register.dat in the same scandir.

If a scan session has been analyzed in csurf,
these files will all be in place.  In that case,
simply display the surface with:

  File -> View Functional Data
  SURFACE-STATS

and then when tksurfer opens:

  select "annot2roi.tcl" from the "tcl:" dropdown
  GO
  [adjust surface-normal search parms in pop-up]
  RUN SCRIPT

The "orig" surface is near the gray/white matter
boundary, so ROI voxels can be selected at various
distance ranges (mm or fraction of cortical
thickness) along the surface normal.

The boundaries of the annotation regions can be
eroded one layers of vertices at a time before the
ROIs are determined ("erodesteps" parameter).

The annot2roi.tcl script will generate
individual-subject, rawdata-resolution ROI mask
BRIKs, and save them in the current scandir for
every annotation region (180 for the HCP
parcellation), as well an all-regions-in-one mask
ROI BRIK.  To view these immediately, use the AFNI
button on the View Functional Data panel.  The
mask BRIKs (datatype=short) contain the IDnum's of
each annotation region, else 0.  In the all-in-one
BRIK, the last annotation region 'wins' in case of
overlap.

If the data has been analyzed *outside* of csurf,
here are the minimal steps to set things up.  This
assumes you have already have a default surface
reconstruction for this subject (recon-all) in
SUBJECTS_DIR.

  File -> New Functional
    [cd into the image subdir of new functional]
    mkdir scan1
    cp SomeFunctionalDataset+orig.BRIK scan1
    cp SomeFunctionalDataset+orig.HEAD scan1
  SessionTools -> Setup Align/Funct Scans
  Funct Scan Dir (top left)
  READ HEADER (top right)
  FUNCT=>SUBJ
    this pops up tkregister
    align funct->struct using COMPARE, TRANSLATE, ROTATE
    SAVE REG
    QuitFUNCT=> (purple button)
  Save/Close

  File -> View Functional Data
  click Render Stats Dir (top left)
  SURFACE-STATS
    [now continue as w/native csurf functional]
  select annot2roi.tcl from the "tcl:" dropdown
  GO
  [adjust search parms in pop-up]
  RUN SCRIPT

Finally, the annot2roi.tcl script can be run from
the command line, which won't open any windows:

  [setup scandir as above]
  cd $FUNCTIONALS_DIR/<session>/image/<scandir>/scripts
  cp $CSURF_DIR/lib/tcl/annot2roi.tcl .
  [uncomment, adjust parameters at top of script]
  tksurfer marty rh orig -tcl annot2roi.tcl



3D ROI masks from annotation region(s) now have IDnum

Previously, if a 3D ROI was generated from one
region in an annotation by:

  [click one annotation region]
  shift-left-click-D  => make 3D ROI for one region

or for all regions in an annotation by:

  ctrl-shift-left-click-D  => 3D ROIs for all regions

each output mask BRIK would contain 0/1.  Now the
mask BRIKs are rewritten to contain the annotation
region IDnum(s).  An all-in-one ROI BRIK is also
generated (see above).



New label/annot erosion function

A new C/tcl function, annot_erode, can erode a
single layer of vertices from one or more distinct
colors in an annotation (e.g., the HCP
parcellation displayed with "D") by setting the
annotation of a vertex to zero if any of its
neighbors have a different annotation value.

This will also work on a single "D"-displayed
label.

Note that this does not do a FILL, so repeated
applications of annot_erode may result in
disconnected patches (probably what you want).

To access this function through the tksurfer
interface, type "annoterode" in the entry next to
the SMOOTH button for 'smoothing steps'.  Each
press of the SMOOTH button erodes another layer
of vertices from each annotation.

See the help for the "W" button for how to write
out ASCII label files containing currently
displayed vertex data under one or more currently
displayed annotation regions:

  -------------------------------------------
  funct (shift-left-click):
    write_val_annotedcol_vertices <r> <g> <b>
  -------------------------------------------
  funct (shift-ctrl-left-click):
    write_val_annotedcols_vertices
  -------------------------------------------


New histogram options

The histogram printing function has two new
options:

  print_hist <option:0-6> <histbins> <smoothteps>

    options:

      0: curv
      1: val
      2: complex amplitude
      3: complex angle
 ==>  4: complex angle w/complex amp > $fthresh
 ==>  5: complex angle w/stat > $sfthresh
      6: stat

It also respects ripflag, so re-cutting a label
(with "label:" line "C") will restrict histogram
report to that label.



Sparse ('representative-vertex') labels w/fixed count

The sparse/representative-vertex operation has
been generalized across several functions and a
new option has been added to the cross correlation
popup panel ("X" button on the "label:" line) and
searchlightop panel (middle-click on SMOOTH) to
generate and use sparse/representative-vertex
labels with a fixed number of vertices.

Ticking "xcorruseuniqflag" (now re-named to more
general "searchlightuniqflag") on the cross
correlation or searchlightop panels causes the
following operations to only use 'representative
vertices' (vertex nearest average of vertices that
sampled a 3D voxel):

  corr_over_label -- Pearson/circ searchlight corr
  fill_nearest_vertices  -- ROI by count/area/rad
  write_searchlights -- write ASCII searchlights
  searchlightop_val2stat -- other searchlight ops

Representative-vertex searchlights are created by
removing non-representative vertices from the
standard/dense searchlights defined by the
count/area/radius criteria.

A new tick in the cross-correlation and
searchlightop popup panels, "numafteruniqflag",
causes the criterion fillneartype=0 (count) to
generate searchlights with the full requested
count of vertices by extending the original area
of the label until the full count is reached.
This applies to all four functions above.

Ticking "numafteruniqflag" has no effect on
fillneartype=1,2 (area/radius) options, and is
ignored unless "searchlightuniqflag" is ticked.

Note that using "searchlightuniqflag" requires
that you have first read in 3D data, done a PAINT
operation using it (to define unique voxel IDs),
and then did a UQ operation (to find the
'representative vertex' for each voxel).  Here is
how to do that interactively:

  left-click "val:" to change it to "val3d:"
  left-click "R" to read 3D BRIK to def uniqvox
  left-click "PAINT" to sample 3D data to surf
    and record uniqvox ids during sampling, which
    uses curr sample depth in L-click-"label:" popup
  middle-click-"UQ" to calculate/write uniq vertices

or by using a tksurfer tcl script:

  ### read the 3D data
  setfile statpatt */scandir1/some3Ddata+orig.BRIK
  read_native_stat 0          ;# 0 means real
  ### set sampling parms
  set normdsampsearchflag 1   ;# turn on normal search
  set normdfracsamp 0.5       ;# begin search
  set normdfracmax 0.5        ;# endsearch
  ### sample 3D data to surface (get uniqvox)
  paint_surface 0
  ### calculate uniq vertices using live uniq id's
  find_uniqsamp_vertices
  ### select uniq vertices
  select_uniqsamp_vertices
  ### write label to scandir (name: rh-UniqSampVtxs.label)
  write_uniqsamp_vertices

-----------------------------------------------
Bug fixes, small changes
-----------------------------------------------

write_uniqsamp_vertices now respects ripflag (sparse in re-cut label)

annot region IDnum (was just name) printed to log on click one

movie360.tcl can use ffmpeg to make mp4 directly (if ffmpeg on $path)

##########################################################################
UPDATE: 20 Mar 2017
##########################################################################
--lib/tcl/movie360.tcl: can use ffmpeg to make mp4 directly (if on $path)
--lib/tcl/tksurfer/scripts: doc annot2roi.tcl
--lib/tcl/annot2roi.tcl: new script: samp fsavg annot to sing sub, get 3D ROIs
--tksurfer.c: single quote rm,>> args in system() calls (sure wildcard block)
--lib/tcl/tksurfer/label_read: doc all-in-one ROI BRIK
--tksurfer.c: insert_idnum() can accumulate merged all-in-one ROI BRIK
--tksurfer.c: write_annotcols_timecourses_stats() makes all-in-one ROI BRIK
--bin/noarch/fsavgannot2subj: sh one-liner to samp fsaverage annot to sing sub
--lib/help/csurf/setupfield, lib/tcl/borders.tcl: better doc
--tksurfer.c: write_annotcol{s}_timecourses_stats puts idnums into mask BRIKs
--tksurfer.c: print annot region IDnum (not just annot name) to log on select
--lib/help/tksurfer/label: update because couldn't find label->3DROI ("D")
--lib/help/tksurfer/{smooth,smooth_steps}: update
--tksurfer.tcl: SMOOTH steps field also takes "annoterode" -> run erode_annot()
--tksurfer.c: add/export erode_annot() HCP parcellation or single disp label
--lib/help/tksurfer/{label_corr,label_write,fill2num,smooth}: update docs
--tksurfer.tcl: searchlightop panel: add searchlighuniqflag, numafteruniqflag
--tksurfer.{c,tcl}: searchlight outfile: Spotlights.txt -> Searchlight.txt
--tksurfer.tcl; "N" butt reports std/dense vs. uniq-by-rm vs. uniq-expand-to-N
--tksurfer.c: searchlightuniqflag/numafteruniqflag: searchlightop_val2stat_th
--tksurfer.c: searchlightuniqflag/numafteruniqflag: fill_nearest_vertices
--tksurfer.c: searchlightuniqflag/numafteruniqflag: write_searchlights
--tksurfer.c: searchlightuniqflag/numafteruniqflag: corr_over_label
--tksurfer.tcl: xcorr: xcorruseuniq->searchlightuniqflag, add numafteruniqflag
--tksurfer.c: xcorruseuniqflag -> searchlightuniqflag, export numafteruniqflag
--tksurfer.c: write_uniqsamp_vertices now respects ripflag (for re-cut label)
--lib/help/tksurfer/val3d_read: HEAD -> BRIK in example
--csurf: add $hemi.surftmp* to surfaces dropdown (like tksurfer, tkmedit)
--lib/help/tksurfer/comp_grad: doc dilate, 3D arrow heads
--lib/help/tksurfer/hbutt: doc new options
--tksurfer.tcl: histctrls: two new options on popup sensitive to (s)fthresh
--tksurfer.c: new print_hist ops: (4)ang if amp>fthresh (5)ang if stat>sfthresh
--tksurfer.c: print_hist respects ripflag
--tksurfer.tcl: histctrls: preset complex ang option=3 if complexvalflag

##########################################################################
UPDATE: 17 Dec 2016
##########################################################################
--lib/help/tksurfer/smooth: explain mid-clk-SMOOTH for searchlightop_val2stat
--tksurfer.tcl: middle-click SMOOTH to get pop-up to run searchlightop_val2stat
--csurf: add hist button help panel to all-help index
--lib/help/tksurfer/hbutt,mk0{.csh}: new helpfile for "h" help button...
--tksurfer.tcl: mid-clk upper-right "h" makes run print_hist (histogram) pop-up
--tksurfer.c: print_hist(): adjustable smoothing, nbins 
--tksurfer.c: print_hist(): convert x-axis bin number to data value 
...




