###################################################################
UPDATE:  12 Nov 2024
###################################################################

Summary:
  (0) fix label header bug introduced in Linux interim releases 240619,240707
  (1) tksurfer can write Talairach coords (MNI 305 or 152) to label (10 functs)
  (2) tkmedit can use MNI 152 instead of MNI 305
  (3) read_label_to_nearest_annot_using_col: import label w/diff vtx numbering
  (4) fill_annot_holes_neigh: fill holes (e.g., in imported label)
  (5) option to select vertices inside surface (for complexly folded)

-------------------------------------------
fix write label header bug on two Linux interim releases
-------------------------------------------

I fixed a Linux-specific bug in writing any ASCII
*.label header that was just introduced ONLY in
the previous two interim releases (240619,
240707).  N.B.: no Mac release had this bug.

The two-line header, which has a first
info/comment line and a second line containing the
number of vertices was being omitted.  Thus, the
label file would look like:

  1263 49.014 -57.597 17.263 0.000000
  1692 43.572 -53.039 20.957 0.000000
  2350 47.215 -54.888 17.173 0.000000

instead of the correct:

  #!ascii , from subject fsaverage ...
  288
  1263 49.014 -57.597 17.263 0.000000
  1692 43.572 -53.039 20.957 0.000000
  2350 47.215 -54.888 17.173 0.000000
  ...

The resulting label, though containing all the
correct data lines, would be unreadable by csurf
without hand-editing.

The bug was introduced when I added some error
checking code that itself contained an error :-{

-------------------------------------------
tksurfer .orig/Talairach/currcoords/normsearch to label
-------------------------------------------

The machinery for dumping vertex x,y,z coordinates
to labels was overhauled and regularized.  Four
different kinds of coordinates can be written to a
label:

  1) .orig coords (gray/white boundary, default)
  2) .orig -> MNI 305 (default MGH freesurfer Talairach)
  3) .orig -> MNI 152
  4) current surface coords (e.g., for flat data analysis)

To control these options, there is a small button
bar at the far upper-left replacing the "c2lab"
(current to label) tickbox.  Ticking the "ta"
button results in Talairach to label, the "cu"
button selected current surface to label.  The
buttons act like radio buttons (ticking one
unticks the other), but they also both be unticked
(the default state), which results in .orig coords
to label.  When you tick "ta", you get a popup to
choose MNI 305 vs. MNI 152.  A R-click on a
ticked "ta" reports the current Talairach choice.

In addition, movement along the local vertex
normal can optionally be added so that final x,y,z
point is in the gray matter (or underneath that
border if desired), rather than at the gray/white
border.

To control this, left-click the bold "label" text
on the "label:" line to get a popup.  The first
tickbox, $normdsampsearchflag, turns normal
movement on (N.B.: the default!).  The second
tickbox, $normdfracflag, determines whether the
movement amount is in millimeters or in fraction
(0-1) of the local cortical thickness at that
vertex.

The selected point is halfway between $normdsamp
and $normdmax (if in mm), or halfway between
$normdfracsamp and $normdfracmax (if in fraction
of cortical thickness).

These parameters were originally introduced for
sampling fMRI data to the surface vertices using
the PAINT button.  They are also used for writing
out timecourses for multiple cortical depths.

The tcl functions affected are:

  write_val_visible_vertices  (was write_labeled_vertices, old OK)
  write_val_annoted_vertices
  write_val_annotedcol_vertices
  write_val_idnum_vertices
  write_val_unmasked_vertices
  write_annotedcol_autoname
  write_selected_list_to_label
  write_annotcols_timecourses_stats
  write_annotcol_timecourses_stats
  write_label_timecourses_stats

The 305 -> 152 transformation matrix is inverted,
so that an MNI 152  Talairach x,y,z can get back
to 305, and then back to access native freesurfer
.orig coordinates.  The 305 -> 152 transformation
matrix used is:

   0.9975  -0.0073   0.0176  -0.0429
   0.0146   1.0009  -0.0024   1.5496
  -0.0130  -0.0093   0.9971   1.1840
   0.0000   0.0000   0.0000   1.0000

-------------------------------------------
tkmedit can use MNI 152 coords
-------------------------------------------

By default, tkmedit uses and reports MNI 305
coordinates (calculated during default recon-all
cortical surface reconstruction).

To change to using MNI 152 coordinates, tick the
"152" tickbox (at the lower right of the
"SAGITTAL" button and slider).

N.B.: using MNI 152 vs. MNI 305 coordinates does
not affect the operation of SEND'ing and GOTO'ing
points between tkmedit and tksurfer, since that
process always uses native .orig coordinates
(possibly modified by normal movement along the
local vertex normal).

-------------------------------------------
Import label with different vtx numbering
-------------------------------------------

Import a label file (for the same subject), but 
which has a different vertex numbering scheme
(e.g., a surface made from a previous edit).

This works like read_label_to_annot_using_col in
that the requested color is defined in the r,g,b
fields to the right of "MESH"),

However, instead of reading the label file vertex
indices (first entry on each label line) to 
determine which surface vertices to color, each
label file line will be used to color the current
surface vertex that has its .orig x,y,z
coordinates closest to the x,y,z coordinates in
that label file line.  N.B.: the label file
coordinates are are assumed to be from the .orig
surface, which is the default for label-writing
(i.e., not from the new Talairach coordinate
option above, for from inflated surface
coordinates, etc).

This makes it possible to display a label file 
written out from an earlier version of a surface,
which will have a different vertex numbering
scheme, and which would otherwise be incompatible
with the newer surface.

N.B.: this will give non-sensical results if the
label file comes from a different subject or if
the label file contains x.y,z vertex coordinates 
that are not from the .orig surface.

N.B.: to save new label:

  (1) re-cut current labeled (ctrl-L-clk "C" on "label:" line
         or tcl funct:  labeled_cut_clearvals 0)
  (2) change name in "label:" line entry to avoid overwrite!
  (3) save label with \"W\" on \"label:\" line"

This works well when edits are localized and no
global refinements have been applied (e.g.,
slightly different target target image value
criterion).  If not, there will be aliasing
between the older label x,y,z vertex positions
and the newer surface x,y,z vertex positions,
resulting in many small linear-shaped holes in 
the transferred label where a new surface vertex
just missed being assigned an annotation from a
label vertex.

To fix this, see the next function below.
However, even without filling the holes, the
converted label can be used as a template to
re-cut a new native label.

This function is quick on a standard sized
freesurfer brain (130K vertices), but it will be
slow with a very large surface (e.g., over 30 min
for a 5M vertex cerebellum).  In that case, it
can be sped up by cutting away irrelevant parts
of the surface (if these are known), for example,
using the "PLANE" button.

-------------------------------------------
New funct to fill holes in imported label/annotations
-------------------------------------------

A more general, controllable label hole-filler
(than the basic one-vertex-hole-fixing
"annotholes").

This function, fill_annot_holes_neigh is accessed
by typing "annotholes-neigh" into the unlabeled
"steps" entry immediately to the right of the
"SMOOTH" button plus <Ret> or click "SMOOTH", which
generates a popup window.  From the popup window,
you can control the size of the smoothing neighborhood,
"neighord" (1-5, where 1 means just consider
nearest vertex neighbors, 2 means includ neighbors
of neighbors, and so on), and the criterion for
filling a hole, "annotedfrac" (% of surrounding
non-hole vertices required to cause
label/annotation hole to be filled with the
surrounding color).

Larger neighborhoods (3-5) are successively
slower with a large surface (e.g., 5M vertex
cerebellum), but can be sped up by cutting away
irrelevant parts of the surface, for example, by
using the "PLANE" button.

-------------------------------------------
Option to select vertices inside surface
-------------------------------------------

Normally, the inside of a surface is invisible,
not lighted, and you cannot select vertices from
the inside.  However, when editing and cutting a
complexly folded surface (e.g., the anterior lobe
vermis of the cerbellum), it is sometimes helpful
to be able to select points from the inside of
the surface.

An alternate middle-click on the "clo" tickbox
(middle bottom) toggles $selectinsideflag.  When
this flag is ON, vertices can be selected from
the inside/back surface.

N.B.: this will disable the normal selecting of
vertices on the outside of the surface!
(middle=click again to go back to normal).

To make the surface and the selected vertices
visible, two additional variables are adjusted:

  set lighttwosidedflag 1   ;# show inside surface
  set light1 1.0            ;# also light inside/back surface

Selections on the inside surface are also marked
when viewing the surface from the outside.

A shift-R-click on the "REDRAW" button makes a
popup with full control over the 4 lights
(brightness, x/y/z position, $insidesurffact
(brightness inside relative to outside),
and $lighttwosidedflag.

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

off-edge access causing occas. startup crash fixed in set_{real,complex}_col

R-click help buttonbars for remaining overloaded buttons tksurfer/tkmedit

better popups for using 2-D color space for truncation

isocontour controls popup

catch tkmedit crash in FILL struct 3D ROI if (irrelevant) im2i not loaded



##########################################################################
UPDATE: 12 Nov 2024 -- details
##########################################################################

--lib/help/tksurfer/{smooth_steps,label_read,selectdmax}: update
--tksurfer.c: read_label_to_nearest_annot_using_col: ignore ripflag vtxs
--tksurfer.c: fill_annot_holes_neigh: ignore ripflag vtxs to speed high neiorder
--tksurfer.c: fill_annot_holes_neigh: add neiorder=5 for smaller surfaces
--tksurfer.c: fix fill_annot_holes bugs (fill val sometimes 0, then paren bug)
--tksurfer.tcl: rm "annotholes-more" b/c fill_annot_holes_neigh is more general
--tksurfer.c: rm fill_annot_holes_more (redundant w/fill_annot_holes_neigh)
--tksurfer.tcl: "annotholes-neigh" uses funct: C/tcl fill_annot_holes_neigh
--tksurfer.tcl: overload smooth steps: add "{annot,label}holes-neigh popup
--tksurfer.c: add fill_annot_holes_neigh(neiorder,annotedfrac) general funct
--tksurfer.tcl: smoothsteps: "{annot,label}holes-more" -> fill_annot_holes_more
--tksurfer.c: add fill_annot_holes_more(): (filled nei minus 3 (vs. minus 2)
--tksurfer.tcl: add no-hotkey "D" button: read_label_to_nearest_annot_using_col
--tksurfer.c: read_label_to_nearest_annot_using_col(): for updated surfaces
    [tmprelease 241028]
--tksurfer.c: fix write_label_hdr check-fp-writable-code on Linux (& O_ACCMODE)
--tksurfer.tcl: disp annot prints totarea all regions (except Unknown) for csurf
--tksurfer.c: tot area annot regions (except Unknown) to genstrret_1k/csurflog
--tksurfer.tcl: add $lighttwosidedflag to lights popup from R-click help buttbar
--tksurfer.tcl: fix R-click report popups for current ta/cu button state
    [tmprelease 240709]
--csurf: hack^2: slow mac10.15 csurf log hangs tkwait/GLwin if appnaphack so blk
    [tmprelease 240707]
--mk0: comment out version-name tksurfer (leave update-tksurfer for later)
--tksurfer.c: set_{real,complex}_color: blk annotmask,adjphase off edge if k=-1
--mk0: add update-tksurfer sh script to dist
--update-tksurfer: toggles tksurfer symlink between 10.6/10.15
--mk0: version-name 10.6 tksurfer compile, incl 10.15 compile, tksurfer->symlink
    [tmprelease 240619]
--tksurfer.tcl: fix buttonbar REDRAW (forgot to make def cmd bind for event gen)
--tksurfer.tcl: add $insidesurffact to brightness/position lights ctrls
--lib/help/tksurfer/{redraw,lights,blufact,selectdmax}: update
--tksurfer.c: draw prev selected inside surface vertices w/points
--tksurfer.tcl: lights bright/pos ctrls: shift-R-clk-REDRAW, REDRAW buttonbar
    [tmprelease 240611]
--tkmedit.c: do 305->152 xform if $xform_mni_305to152_flag (6 fwd's, 1 inv)
--lib/help/tkmedit/xfm305to152,mk0: new helpfile
--tkmedit.tcl: "152" tickbox for $xform_mni_305to152_flag under SAGITTAL
--tkmedit.c: load_invert_305to152_xform() at startup, $xform_mni_305to152_flag
    [tmprelease 240609]
--tksurfer.c: write_annotcol{s}_timecourse.. warns usecurrcoords cancels norm mv
--tksurfer.c:xform_mni_305to152_flag picks find_orig_vertex_coordinates edit.dat
--tksurfer.c: find_orig_vertex_coordinates always reports both MNI 305 and 152
--lib/help/tksurfer/: update multiple help (6 renames, 305 vs 152, 15 files)
--tksurfer.c: export selected (curr vtx, starts -1)
--tksurfer.c: rm xform_mni_305to152(), subst. mni_transform_point(): 5fwd/2inv
--tksurfer.c: add load_305to152_xform() to startup seq: always load, invert
--tksurfer.c: new global Transform's: {inverse_}mni_305to152_transform
--tksurfer.tcl: R-click-"ta" reports MNI 305 vs. MNI 152
--tksurfer.tcl: select Talaiarch "ta" sets up choose MNI 305 vs. MNI 152
--tksurfer.c: test/add xform_mni_305to152(), add/export $xform_mni_305to152_flag
--tksurfer.tcl: C:write_selected_list_to_label->write_val_selected_list_to_label
--tksurfer.tcl: copy-C:write_annotedcol_autoname-> write_val_annotedcol_autoname
--tksurfer.c: rename:write_annotedcol_autoname ->  write_val_annotedcol_autoname
--tksurfer.c:write_selected_list_to_label->write_val_selected_list_to_label(syn)
--tksurfer.tcl: rename: extract_unmasked_flag -> unmasked_to_label_flag
--tksurfer.tcl: rename: extract_overlays_flag -> unmasked_to_labels_flag
--tksurfer.c: fix write_selected_list_to_label header update bug if bigcursorflg
--tksurfer.c: fix all synonyms to use an extra Tcl_CreateCommand
--tksurfer.c: rename write_labeled_vertices->write_val_visible_vertices (bakcmp)
--searchlight{area,diff}.tcl: write_labeled_vertices->write_val_visible_vertices
--tksurfer.tcl: copy-C: write_labeled_vertices->write_val_visible_vertices
--tksurfer.c: write_selected_list_to_label uses new functs, but dup'd for neigh
--tksurfer.c: write_annotedcol_autoname uses 2 new funct
--tksurfer.c: write_{annotcols,annotcol}_timecourses_stats DON'T (do separately)
--tksurfer.c: write_val_{annoted,annotedcol,unmasked}_vertices use 2 new functs
--tksurfer.tcl: usecurrcoordsflag/usetalcoordsflag ticks to "|ta|cu|" tixSelect
--tksurfer.c: extract new funct: write_label_vtxline,write_labeled_vertices uses
--tksurfer.c: extract new funct: write_label_hdr, write_labeled_vertices uses
--lib/help/tksurfer/nsamp_{search,dfrac,max,min,fracmax,fracmin}: update
--tksurfer.tcl: fix R-click help on "label:" label popup
--lib/help/tksurfer/label_write: update
--tksurfer.c: find_orig_vertex_coordinates, write_labeled_vertices use it
--tksurfer.c: extract new function: move_along_normal(k,vb,x,y,z,&x2,&y2,&z2)
--tksurfer.tcl: overload "c2lab" button with usetalcoordsflag
--tksurfer.c: separator: '=' to '_' for write_val_{annotedcols,idnum}_vertices
--tksurfer.tcl: event generate buttonbars for R-clk help for REDRAW, RESTORE
--lib/help/tksurfer/selectdmax: update
--tksurfer.tcl: overload "clo" button with $selectinsideflag
--tksurfer.c: if $selectinsideflag, draw cursor underneath surface (instead)
--tksurfer.c: add/export $selectinsideflag (N.B.: cancels outside select!)
--tksurfer.tcl: display label (labelD_display) opens label control popup (duh!)
--lib/help/tksurfer/isocont: update
--tksurfer.tcl: add isocontour controls pop-up for R-click "isocont"
--lib/help/tksurfer/{label_read,label_toggle}: update
--tksurfer.tcl: padlabelvtxsflag in label tickbox popup, hotkey, warn label read
--tksurfer.c: add padlabelvtxsflag to read_label_to_annot_using_col (also neigh)
--tkmedit.tcl: "im2:" label popup: better description (test vs. apply)
--lib/help/tkmedit/im2label: clarify transpar overlay test vs apply to editable
--tkmedit.c: COMPARE/TRUNC: event generate -> call proc, fix TRUNC cmd-. bind
--tkmedit.tcl: COMPARE: event generate -> call proc, cleanup TRUNC/PF/PFGAU
    [tmprelease 240519]
--tksurfer.tcl: fix def bind for Return in label: entry (invoke fail w/no-cmd)
--tksurfer.tcl: fix def bind for Return in val: entry (invoke fail w/no-cmd)
--tksurfer.c/tcl: check " invoke" of "buttons $f SOMEBUTTON { }"
--tkmedit.c: WMTRUNC,CORONAL invoke -> event generate (b/c empty cmd/only bind)
--tkmedit.tcl: change invoke to event generate: SMOOTHGAUSS,TRUNC,CORONAL,TEST
--tkmedit.c: COMPARE Xkeys: add alt/cmd-C for COMPARE
--tkmedit.c: COMPARE Xkeys: invoke->event generate (b/c empty cmd/only bind)
--tkmedit.tcl: COMPARE hotkeys: add alt/cmd-C for COMPARE
--tkmedit.tcl: COMPARE hotkeys: invoke->event generate (b/c empty cmd/only bind)
--tkmedit.c,tcl: search " invoke" of "buttons $f SOMEBUTTON { }" -> event gen
--tkmedit.tcl: mv up imim2 ctrls un-overlap TRUNC buttbar (not if from OP butt)
--lib/help/tkmedit/wmtrunc: add imim2op help (overlap w/imim2op OP help)
--tkmedit.tcl: add imim2op colspace ellipse to TRUNC buttbar, ctrls to OP
--tkmedit.tcl: rm do_imim2op arg
--tkmedit.tcl: add buttbar for SMOOTH{STRUCT/STATS} button, incl calc grad x/y/z
--tkmedit.tcl: add buttonbar for PF,PFGAU butts (event gen hack for compact)
    [tmprelease 240503]
--tkmedit.c: catch crash in FILL struct 3D ROI if (irrelevant) im2(i) not loaded
--tkmedit.tcl: add buttonbar for FILL button (event gen hack for compactness
--tkmedit.tcl: COMPARE/TRUNC: 'after 1' fix butt state race after bind->proc
--tksurfer.tcl: put neighbor order info on paintball popup into
    [tmprelease 240501]
--tkmedit.tcl: add toggle linearflag button to COMPARE buttonbar
--tkmedit.tcl: add buttonbar for COMPARE button, change bind's to proc's
--tkmedit.tcl: buttonbar for F3 TEST butt (event gen hack keep binds like APPLY)
--tkmedit.tcl: buttonbar for CORONAL (event gen hack to keep binds like SAG/HOR)
--tkmedit.tcl: convert TRUNC butt bind's to procs (rm event generate hacks)
--tkmedit.tcl: section dividers for readability

##########################################################################
UPDATE: 26 Apr 2024
##########################################################################

--tksurfer.tcl: new buttonbar for areal-line "D" button
--tksurfer.tcl: new buttonbar for "SMOOTH" button 
--tksurfer.tcl: conv val-line "W" butt bind's to procs (rm event generate hacks)
--tksurfer.tcl: new buttonbar for val line "CLR" button (just 2: val, all)
--tksurfer.tcl: new buttonbar for val-line "CS" button (just 2: cluster, FDR)
--tksurfer.tcl: conv val-line "S/V" butt bind's to procs (rm event gen hacks)
--tksurfer.tcl: new buttonbar for val-line "R" button (bind's -> proc's)
--tksurfer.tcl: new button bar for label-line "X" butt (bind's -> proc's)
--tksurfer.tcl: new button bar for label-line "S" butt (bind's -> proc's)
--tksurfer.tcl: new button bar for label-line "T" butt (bind's -> proc's)
--tksurfer.tcl: conv fs-line GR butt bind's to procs (rm event generate hacks)
--tksurfer.tcl: conv label-line W butt bind's to procs (rm event generate hack)
--tksurfer.tcl: conv label-line R butt bind's to procs (rm event generate hack)
--tksurfer.tcl: conv label-line CLR butt bind's to procs (rm eventgenerate hack)
--tksurfer.tcl: conv label-line C butt bind's to procs (rm event generate hack)
--tksurfer.tcl: conv label-line D butt bind's to procs (rm event generate hack)
--tksurfer.tcl: fix stale funct name: read_poi_annot -> read_poi_to_annot
    [tmprelease 240418]
--lib/help/tksurfer/label_write: update write_sorted_by_pathdist_label
--tksurfer.tcl: R-clk label W for C pathsort: write_sorted_by_pathdist_label

...

