[current new release: 02 May 2026]

###################################################################
UPDATE:  @@ Dec 2026
###################################################################

-------------------------------------------------------------------
Summary:
  (1) calculate/display rawdata covariance
  (2) ...
-------------------------------------------------------------------


-------------------------------------------
(1) calculate/display rawdata covariance
-------------------------------------------

New (very) basic functionality to calculate and
display rawdata time series covariance has been
added.  There are 4 new C/tcl functions:

  calc_rawdata_covar
  write_rawdata_covar
  read_rawdata_covar
  copy_rowcovar_val

These functions can be accessed via the buttonbar
from a R-click on the "X" (cross-corr) button on
the "label:" line.

The first step is to set up a new functional
session with a scandir containing a raw time
series data BRIK and register that rawdata to a
subject in the standard way (makes register.dat).

Then read the rawdata BRIK into tksurfer using the
alternate 3D buttons on the "val:" line:

 (1) click "val:" to toggle it to "val3d:"
 (2) click "RD" to get rawdata popup
 (3) select rawdata BRIK from popup "val3d:" dropdown
 (4) click "READ RAWDATA and REGISTRATION"

Next, click "label:" to get NormSamp controls and
set the sampling method and sampling point, using
either mm or fraction of cortical thickness:

  if normdfracflag unticked (mm above orig surface),
  set normdsamp, normdmax equal (e.g., 1.0 [mm])

  if normdfracflag ticked (fraction of cort thickness above),
  set normdfracsamp, normdfracmax equal (e.g., 0.6 [=60%])

Next, R-click the "X" button on the "label:" line
to get a popup and click "Calculate RawData
Covariance" (there will be an error if you are not
sampling at a point along the surface normals).

This procedure first finds 'representative' or
'unique' vertices.  That is, for each sampled 3D
voxel, find the surface vertex closest to the 3D
positional average of all the vertices that
sampled that voxel (to avoid having duplicate
entries in the covariance matrix). N.B.: to see
the 'representative' vertices, click "UQ" on the
"val3d:" line after "Calculate RawData Covariance"
has run.

The C/tcl functions run by "Calculate RawData
Covariance" are:

  rawdatasubbrik_to_paintable 0   # extract first frame of rawdata
  paint_surface 0                 # 'paint' to surf to find sample voxels
  find_uniqsamp_vertices          # find voxel-unique 'representative' vtxs
  calc_rawdata_covar              # calculate covariance matrix

Each covariance matrix entry (for a pair of
vertices, v1 and v2) is computed in the usual way
as follows (sum is across t):

           Sum[(v1 - v1_avg) * (v2 - v2_avg)]
corr =   -------------------------------------
                       n - 1

which results in a symmetric matrix with variances
along the diagonal.

To view individual rows of the covariance matrix,
click "Display Correlation for CurrVertex" on the
Label "X" popup, after selecting a 'seed' vertex
(the actual seed will be the 'representative'
vertex closest to your selected vertex).  The
first time this runs, the colscale will be set to
sane values to display the correlations:

  set overlayflag 1
  set truncphaseflag 0
  set complexvalflag 0
  set statmaskampflag 0
  set colscale 11
  set fslope 0.1
  set fthresh 5.0
  set fmid 10.0

Since the (large) covariance matrix (about 13K by
13K) only contains 'representative' vertices, the
correlation data is first interpolated on the
surface with smooth_val_sparse (the "sp" option
for the SMOOTH button).  During this smoothing,
the values at 'representative' vertices are fixed
and only the undefined vertices in between are
interpolated (20 steps).

Finally, to export the covariance matrix to the
current scandir to analyze it with external tools,
use the "Write RawData Covariance" button on the
R-click "X" popup.  This will write out two files
in the current scandir with standard names.  The
first file:

  $hemi-CovarianceMatrix.float

is the covariance matrix, written as a string of
floats in standard freesurfer byte order (MSB).
Use AFNI 4swap to convert to Intel (LSB) byte
order to read the binary data into an external
program, for example:

  4swap rh-CovarianceMatrix.float

The indices of the rows and columns of this matrix
are sequentially numbered 'representative'
vertices, which are a subset of full vertex
subset.  So, in addition to the covariance matrix,
an ASCII file of the original full surface vertex
numbers of these 'representative' vertices is also
written to:

  $hemi-CovarianceMatrixVnums.txt

Since it takes a minute to calculate the large
covariance matrix, you can read a previously
calculated matrix into tksurfer with "Read RawData
Covariance" on the R-click "X" buttonbar popup.

Finally, a new popup to select/query vertices by
vertex number and dispay time series is available
by R-clicking the REDRAW button and clicking the
bottom "Select Vertex By Number Popup" button
(mainly for debugging).  The buttons are:

  CURRENTLY SELECTED VTX   (from display window click)
  SELECT VERTEX BY NUMBER
  SHOW VERTEX TIMECOURSE 


-------------------------------------------
(2) ...
-------------------------------------------
...


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

UQ popup reports sampvtxcnt, uniqvtxcnt, vtxs per voxel

NormSamp popup: enable/disable relevant parms: normdfracflag, bokflag



##########################################################################
UPDATE: @@ Dec 2026
##########################################################################

[LATEST IN PROGRESS]

   [tmprelease 260521]
--lib/help/tksurfer/{label_corr,redraw}: update
--ksurfer.tcl: add "SHOW VERTEX TIMECOURSE" button to select-by-vtx-num popup
--tksurfer.c: functify show_timecourse and export to tcl
--tksurfer.tcl: R-click "REDRAW" button: add "Select Vertex By Number Popup"
--tksurfer.tcl: R-click "X" buttonbar: add "Read RawData Covariance"
--tksurfer.c: add/export read_rawdata_covar (a bit overkill)
--tksurfer.tcl: green selbgcol for hacked-in popup comboboxes (mkannot,rawdata)
--tksurfer.c: rawdatasubbrik_to_paintable now accepts short read by read_rawdata
--tksurfer.tcl: R-clk "X" buttonbar: add "Display Correlation for CurrVertex"
--tksurfer.tcl: R-clk "X" buttonbar: add "{Calc,Write} RawData Covariance"
--tksurfer.c: add/export copy_rowcovar_val() (find nearest uniqvtx to selected)
--tksurfer.c: add/export calc_rawdata_covar(), write_rawdata_covar()
--tksurfer.c: new tmp covar mat globals: covarmat{,_dim,_vnum,loaded}
--tksurfer.c: sampvtxcnt, uniqvtxcnt made global for tcl report
--tksurfer.tcl: R-clk menu "label:" line "X" refreshes corr over label/annot
--tksurfer.tcl: NormSamp popup: enable/disable parms: normdfracflag, bokflag
--tksurfer.tcl: UQ popup reports sampvtxcnt, uniqvtxcnt, vtxs per voxel
--tksurfer.c: sampvtxcnt, uniqvtxcnt made global for tcl report

##########################################################################
UPDATE: 02 May 2026
##########################################################################

   [newrelease 260502]
--lib/help/tksurfer/{save,goto}_pnt: update
--tksurfer.c: sensibly rename: *vindex -> *selectedptr (in 2 functs below)
--tksurfer.c: same fix as below for (script-only) select_talairach_point
   [tmprelease 260429]
--tksurfer.c: funct below passed &selected(def=-1) so deref rngchk brks 1stcall
--tksurfer.c: rm bad select_orig_vertex_coords err chk *vindex - broke 1st GOTO
--tksurfer.tcl: bind toggle nobicurvfadeoverfthresh mid-clk F3 panel "cv" radio
   [tmprelease 260426]
--tksurfer.tcl: cut_{line,vertices},uncut_connected_vertices: warn no selected
--lib/help/tksurfer/curv_tick: update
--tksurfer.tcl: bind toggle nobicurvfadeoverfthresh mid-clk "[ ] curv" tickbox
--tksurfer.c: add/exp nobicurvfadeoverfthresh:no diff fade to sulc/gyr > fthresh
   [tmprelease 260412]
--tksurfer.tcl: disp-annot,chng-annotbordflag reselect_selected_list:select->top
--tksurfer.c: finally fix undo logic! select_vertex w/select=-1 restarts baklist
--tksurfer.c: back out: draw_curs 3x for all b/c weird offset select problem?
--tksurfer.c: reselect_selected_list: draw last-in-list curs 2x extra fix fail?
--lib/help/tksurfe/clks: update, undo
--tksurfer.c: glxwin 'cmd-z' restores prev selected list & redisplays
--tksurfer.c; add restore_selected_list()
--tksurfer.c: clear_vertex_marks_list saves prev (if not already clr:2Rclk help)
--tksurfer.c: glxwin 'd' key does reselect_selected_list to see over annot
--tksurfer.c: add/export reselect_selected_list()
   [tmprelease 260108]
--csurf: warn {SUBJECTS,FUNCTIONALS}_DIR autoset to inside csurf (by FS Env)
--update-csurf: non-verbose untar if "ggo" to not clog csurf.log
--csurf: updatecsurfcmd: find moved-aside name before run update-csurf
--csurf: check csurf install/update dir writable
--csurf: add un-quarantine commands to final updatecsurfcmd popup
    [tmprelease 260104]
--update-csurf: echo pwd/install dir!
--update-csurf: Mac warns run xattr (new tar), don't autodo b/c req's passwd
--csurf: Preferences->Update Csurf:setupupdatecsurf,updatecsurfcmd: update-csurf
--update-csurf: add "ggo" for don't-ask install
    [tmprelease 260101]
--8 file/label lightweight 'annots' (8M) added to fsaverage/fsaverage-ADDITIONS
 {rh,lh}-CsurfMaps1_MNI152.label
 {rh,lh}-CsurfMaps1_MNI305.label
 CsurfMaps1_newcurv-{rh,lh}.w
 CsurfMaps1_old3byte-{rh,lh}.w
--tksurfer.c: write_label_hdr() includes Talairach 152 vs. 305, normd{frac}samp
--lib/help/tksurfer/val_{lab,write}: update
--tksurfer.tcl: mid-click "val;" makes allverticesflag,val2newcurfflag popup
--tksurfer.tcl: left-click "label:" auto-pops up label_label help
--lib/help/tksurfer/swapstatval: update
--tksurfer.tcl: add copy_idnum_val to S/V (swap stat val) button bar
--tksurfer.c: add/export copy_idnum_val (for writing annot-like wfile/label)
--lib/help/tksurfer/comp_grad: doc hidden compute_laplacian <0,1,2> funct
--tksurfer.c: scale_brain() updates tcl-exported glxzoomfact (not yet used)
--tksurfer.c: trunc pval dots w/fthresh (not fully general for all mod flags)
--tksurfer.tcl: rm 3 Calc Laplacian (includelaplacian=0),leave procs,tksurfer.c
--tksurfer.tcl add 3 Calc Laplacian buttons, comp_disp_laplace proc
--tksurfer.c: add/export compute_laplacian (curv,val,phase) -> valbak
--wrappers.tcl: allow "whitespace" (use proc null), added into GR gradient menu
--tksurfer.tcl: findgradrevctrls help: non-existent findgradrev -> comp_grad
    [tmprelease 251126]
--lib/help/tksurfer/{gradfsarrows,comp_grad}: updates
--tksurfer.tcl: add flipRHpolararrowsflag to FIELDSIGN and GRADIENT ARR
--tksurfer.tcl: do_gradrev: find_grad..,write pval wfile, borddots/val display
--tksurfer.c: add/export pvalborddotflag/dthresh to view .pval above thr as dots
--tksurfer.c: find_gradient_reversals: get same ang from 2D/3D grads dot prod
--lib/help/tksurfer/gradfsarrows: update stale hotkeys, regularize
--tksurfer.tcl: don't trunc lg early-area curv gradients (curv avg flatter/OK)
--tksurfer.c: find_gradient_reversals: replace w/new neighbors-only version
--tksurfer.c: add/export find_gradient_reversals (similar to find_retin_borders)
--tksurfer.tcl: findgradrevctrls popup to run find_gradient_reversals
--tksurfer.tcl: calc gradient reversals make-popup-button to GR button R-click
--lib/help/csurf/setupfield: respect reordered parms
--csurf: Setup Calculate Fieldsign, Borders: dividers, better var description
--lib/help/tksurfer/comp_grad: fix avggradvecbak{3d}flag->reggradvecbak{3d}flag

