################################################################### UPDATE: 16 Dec 2019 ################################################################### ---------------------------------------------- tksurfer 'direct paint' ---------------------------------------------- The operation of sampling data onto the surface (PAINT) usually passes through a transformation matrix, and the sampled data often has a different voxel size than the native scans used to reconstruct the surface. A new tksurfer 'direct paint' operation (C/tcl function direct_paint) was added to sample native conforming COR data (e.g., orig.mgz) directly onto the surface without a transform. Run direct_paint with the new "P" button, visible at the top left of the larger, [fn-]F3 interface (use "i" at upper left of default interface to get larger interface). This requires first loading a 3D data set using "R" button on the "im:" line. This function uses the following parameters to sample the 3D data to the current surface: normdfracflag 0=mm, 1=fraction (def=0) normdsamp dist along normal in mm (def=1.0) normdfracsamp fraction cortical thickness (def=0.4) wmgmext sampling surface (def=orig) To adjust these parameters interactively, click "label:" to get a popup. All other parameters on that pop-up besides the four above are ignored. ---------------------------------------------- sphere_morph ("REG") can use 2nd complex dataset ---------------------------------------------- The tksurfer C/tcl function, sphere_morph, can now use two complex-valued data sets in order to align retinotopic data. See the R-click help for the "REG" button (sphere_morph) and the "W" button on the "val:" line (surf2sphim). The overall procedure is: (1) open a sphere.reg surface (2) load target curvature (e.g., sulc), and/or real-valued target data and stat, and/or complex-valued data, and possibly a second complex-valued data set to surface. (3) sample target surface data to target volumes ("reverse paint" function, surf2sphim, using alternate clicks on the "val:" line "W" button) so moveable data can be loaded (click the bold "im:" label to get pop-up controls) (4) load corresponding moveable surface data (data to be morphed) onto the surface (5) run sphere_morph ("REG" button on F3 interface) ---------------------------------------------- csurf "Surface for Sampling 3D Data" orig -> white ---------------------------------------------- The FreeSurfer 5.3 "orig" and "white" (and "smoothwm") surfaces are very similar across virtually the entire brain. However, in the foot area in S-I (which I just happened to be recently mapping :-} ), the "orig" surface can billow out toward the pial surface, when compared to "white" and "smoothwm". Therefore, the default "Surface for Sampling 3D Data" in the "Calculate 3D Fourier Stats" panel and the "Import 3D Stats" panel was changed from "orig" to "white". This results in extremely subtle differences in data sampled to the surface (even in the foot area of S-I), esp. if normal search is engaged. ---------------------------------------------- tksurfer display gray-matter diffusion vecs from AFNI BRIK ---------------------------------------------- After clicking "val:" to toggle it to "val3d:", there is a new "RD" button (read rawdata and register.dat), and a new "V" (vectors) button (tcl/C function, read_vecs2surf), which allows reading 3D vectors out of an AFNI DTi eigenvector BRIK in order to sample gray-matter diffusion vectors to the surface and display them as ball-and-sticks. A new tcl/C funct, rotate_dti, rotates the diffusion vectors using the inverse of register.dat (ignores translation and scale). Here is how to perform the read_vecs2surf actions in a tcl script: if {$rawdataloaded && $registerdatloaded} { ### rawdata -> vector (dipole) display set xvectbrik 9 set scalebrik 5 set normdsampsearchflag 1 set normdfracflag 1 set normdfracsamp 0.5 set normdfracmax 0.5 swap_val_valbak ;# save overlay for {set i 0} {$i < 3} {incr i} { rawdatasubbrik_to_paintable [expr $xvectbrik + $i] paint_surface 0 push_val_dip $i ;# 0=dipx,1=dipy,2=dipz } ### optional scale length by 4th vol dataset if {$scalebrik >= 0} { rawdatasubbrik_to_paintable $scalebrik paint_surface 0 swap_stat_val scale_dipxyz_by_stat } rotate_dti swap_val_valbak ;# restore ovelay set dipolesflag 1 redrawbutton } This is equivalent to calling the combined function directly: if {$rawdataloaded && $registerdatloaded} { ### rawdata -> vector (dipole) display set xvectbrik 9 set scalebrik 5 set normdsampsearchflag 1 set normdfracflag 1 set normdfracsamp 0.5 set normdfracmax 0.5 read_vecs2surf $xvectbrik $scalebrik ;# all-in-one set dipolesflag 1 redrawbutton } ---------------------------------------------- tksurfer display vectors (e.g., GM DTi) from 3-frame .mgh ---------------------------------------------- Alternatively, if diffusion eigenvectors (or any other vectors) have already been sampled to the surface in the form of a 3-frame *.mgh file, they can be displayed directly with a shift-right-click on the "V" button on the "val:" line, using the C/tcl function, read_mgh_dipoles. First select the *.mgh file to read from the "val:" entry dropdown (the file must be in the current scandir to be loaded into the dropdown). The vector length and thickness can be controlled with the left-middle (unlabeled) unlabled entry in the "phc" box. Use Return to set vector length to the value of the entry, and Shift-Return to set both length (in mm), and line thickness (in pixels). ---------------------------------------------- Calc % overlap between annotation regions and non-zero .val ---------------------------------------------- Calculate vertex-wise percent overlap between each region in the currently loaded MGH annotation file and vertices containing non-zero .val data. Annotation regions overlapping only zero .val's are not reported. To use this, if necessary, first clear any .val data from the surface using: "CLR" on the "val:" line The load the .val field using either: select valfile (*.w or *.mgh) file "label:" dropdown click "R" (=read) on the "val:" line *or* select data-containing label from "label:" dropdown click "R" (=read) on the "label:" line Then, load an MGH annotation using: select .annot file from "label:" dropdown click "D" (=display) on the "val:" line Finally, ctrl-shift-right-click the "D" button on the "val:" line. The result is written to a pop-up, to the csurf log, and to a text file ($hemi.overlap.txt) in the subject's "scripts" directory with the following format: #calc_annots_nzval_overlap (non-zero .val's) #annot=/usr0/subjects/fsaverage/label/lh.HCP-MMP1.annot #val=/tmp/191101BC-ICA_mgh/ICA20_medial_sensorimotor_rh.mgh #IDnum Percent (Overlap/Vtxs) Structure #----------------------------------------------------------- 8 27.7% (1111/4015) L_4_ROI 9 29.9% (852/2845) L_3b_ROI 10 5.2% (43/832) L_FEF_ROI 11 6.1% (23/375) L_PEF_ROI 12 39.8% (261/656) L_55b_ROI ... ----------------------------------------------- Bug fixes, small changes ---------------------------------------------- Sample to sphim pop-up, optional conv byte mgz for debugging surf2sphim now fills small number of remaining holes Immediately update orig area after "really_" transformations Fixed tksurfer double redraw on change surface Fixed tksurfer Dijk button Save/Goto View can add suffix to surfer.mat, list currently there middle-click upper-left "i" in tkmedit to invert contrast fix tksurfer printvtxdata off-edge im crasher if MRIloaded fix extra callbacks controls pop-up panels purple/unpurple buttons to indicate running ########################################################################## UPDATE: 16 Dec 2019 ########################################################################## --mk0{.csh}: add -viewerlin,-viewermac to make self-contained quickstart inst --tksurfer.c: rm redundant diploadedflag --tksurfer.c: add/export read_mgh_dipoles(): from $val (must be 3-frame .mgh) --tksurfer.tcl: lib/help/tksurfer/arrownorm: update --tksurfer.tcl: shift-right-clk on unlabeled arrowstick toggles dipolesflag --tksurfer.tcl: read .mgh val: check embedded *.rh/lh.* (vs. *-rh/lh.w), warn --tksurfer.tcl: wider "RD" dropdown list for rawdata BRIKs --{wrappers,tksurfer}.tcl: -selectforeground black for linux dti,regraw popups --tksurfer.c: paint_surface: if stat dims=0, subst rawdata dims, fail if both=0 --tksurfer.c: init xx0=xx1=yy0=yy1=zz0=zz1=0.0 (enable test unset, not yet done) --tksurfer.c: rename: push_val_dip() to copy_val_dip() [no history yet] --lib/tcl/zz-examples/renderoffscreen.tcl: respect previous rename --lib/tcl/{borders,eccen-,fs-make,phasemovie,polar-,twocond-*}.tcl: respect prev --tksurfer.c: rename: push_val_val2() to copy_val_val2(), push_ another synonym --tksurfer.c: if diploadedflag, printvtx reports it --tksurfer.c: calc avg len dip (for scale) --tksurfer.tcl: do_dtivec: force sample single cortical depth, update NormSamp --tksurfer.tcl: dtivecctrls: add parms for sampling surface, cortical depth --tksurfer.c: replaced accidentally deleted normals display --lib/help/tksurfer/val3d_{raw,vecs}: update --tksurfer.c: add/export scale_dipxyz_by_stat(), optional use in read_vecs2surf --tksurfer.c: rotate_dti uses normalized (rot-only) inv regdat xform --tksurfer.c: invert_regdat also makes normed upper 3x3 inv regdat for rot-only --tksurfer.c: read_rawdata: set flag from HEAD to short, not just float! --lib/help/tksurfer/val3d_raw: update --tksurfer.tcl: finish "RD" (read rawdata and regdat) popup for val3d: line --csurf: help/tksurfer/val3d_raw: add to all help --wrappers.tcl: okreplace debug msg if absfilename is dir, parent doesn't exist --wrappers.tcl: okreplace w/o altmsg checks if file exists, adjusts message --csurf: allow multiple cmdline flags --tk{surfer,medit}.tcl: macappnaphackflag can force/unforce hack --tk{surfer,medit}.c: macappnaphackflag passed thru to tk --csurf: -[no]hack opt pass -macappnaphackflag (-1,1,0) to tk{surfer,medit}cmd --csurf: -[no]hack opt pass -macappnaphackflag (-1,1,0) to {surf,med}testrender --lib/help/tksurfer/label: update for overlap calc --csurf: MacOS 10.15/kern=19 fast tk after logout/in w/o hack: add -[no]hack --FreeSurferEnv.sh: works on MacOS 10.15 zsh --tksurfer.tcl: warn overwrite $hemi.overlap.txt --tksurfer.c: also count overlap w/idnum=0,col=maxUint,name=??? --tksurfer.tcl: warn about FILL even w/visible label (was block invisible label) --tksurfer.c: lastvalfromlabelflag: to tell fname (vfname/val vs. lfname/label) --tksurfer.c: write calc_annots_nzval_overlap output to subject scripts dir --tksurfer.tcl: 8th overload "D" butt w/calc_annots_nzval_overlap (ctrl-shift-R) --tksurfer.c: calc_annots_nzval_overlap: vtxwise overlap MGH annots, non-0 .val --tksurfer.c: add RD button to val3d to read regdat/rawdata (space: PAINT=>PA) --tksurfer.tcl: fix tcl: GO button double exec (block callback from setfile) --tksurfer.tcl: fix misleading error message on NormSamp parm mismatch --csurf: "Update Subjects/Sessions" warns when subj changed to match curr sess --csurf: add selecthemi to fieldsigncmd to allow doing fieldsign for one hemi --tksurfer.tcl: do_dtivec purple/unpurple mv'd more gen wrappers.tcl controls --wrappers.tcl: add purple/unpurple main button hack to controls proc --tksurfer.tcl: fix val/val3d both visible after chng interface size w/val3d --tksurfer.tcl: do_dtivec purples/disables/renames butt, unpurples when done --tksurfer.tcl: R-clk help also pops up panel for too-much-overloaded labeltick --tksurfer.tcl: dtivecctrls pop-up to allow choose subbrik --tksurfer.c: export registerdatloaded, dtirotatedflag, diploadedflag --tksurfer.c: rotate_dti() to rotate eig in place using inverse of register.dat --tksurfer.c: invert_regdat() using MNI inverse (read_regdat always does) --tksurfer.c: rename vtx2rawdata() => xformvec() --tksurfer.c: draw_surf: flip dip vec if neg projection onto vtx normal --lib/help/tksurfer/val3d_vecs: add helpfile, add to mk0{.csh}, csurf --tksurfer.tcl: add "V" butt to "val3d:" entry to run all-in-one read_vecs2surf --tksurfer.c: read_vecs2surf() to read/paint/xyz/to-dip --tksurfer.c: swap_val_valbak() to save/restore current overlay --tksurfer.c: rawdatasubbrik_to_paintable(): copy 1 subbrik to paintable fim_2r --tksurfer.c: export dipolesflag (draw_surf()) --ima2brik: add -listboth --ima2brik: add -listprot: just list num files, protocol names for each scan --csurf: "Surface for Sampling 3D Data" orig->white: orig has bad S-I foot! --tksurfer.tcl: write sphim to mgz now optional on sphimctrls --csurf: SUBJECTSS_DIR crasher! --csurf: don't complain about xterm if not Mac! --csurf: use recon-all6.0b w/-all-skipstep1 option for fs6.0 (was just fs5.3) --csurf: add all-help: nonintecc/exptrans/direct_paint/read_im{2,3,_label}, --tksurfer.c: surf2sphim now clamps in case non-spherical surf search off edge --csurf: add im,im2,im3,im-label to all-help panel --lib/help/tksurfer/read_im_label: new helpfile for bold "im:" label --tksurfer.tcl: "im:" F3 interface makes surfdata->sphim->mgz popup: sphimctrls --tksurfer.c: change default volumes (inim{2,3} to *.mgz (was CORdir) --tksurfer.c: surf2sphim fills (the few) remaining holes, thicker rim --tksurfer.c: add/export: write_sphim2byte hack/debug/check morph tractor beams --lib/help/tksurfer/(morph,val_write,shrink_wbn}: update for wcpx2 --tksurfer.tcl: 8th overload "val:" W butt: samp valbak,val2bak: surf2sphim 4,5 --tksurfer.tcl: replace "wbn:" entry (boundary normal) with "wcpx2:" --csurf: add morph_wcpx2 to all-help --lib/help/tksurfer/morph_wcpx2: new helpfile (add to mk0{.csh}) --tksurfer.c: exported: {real,imag}im2loadedflag, surf2sphim accepts 4,5 --tksurfer.c: add second complex-valued drive to sphere_morph, sphims --lib/help/tksurfer/exptrans: new helpfile (tksurfer.tcl, mk0{.csh}) --tksurfer.c: fix printvtxdata off-edge im crasher w/MRIloaded --lib/help/tksurfer/read_{im,im2,im3}: new helpfiles, add to mk0{.csh} --tksurfer.tcl: undo prev, update help to load using std S/V "push imaginary" --tksurfer.tcl: mid-clk overload "P" button to paint to .val2 (direct_paint 1) --tksurfer.c: direct_paint stattype arg so im[][][] can go to .val or .val2 --tksurfer.c: export non-std flags: MRIloaded, MRI2loaded, MRI3loaded --lib/help/tksurfer/{nonintecc,direct_paint} new helpfiles; also mk0{.csh} --tksurfer.tcl: add "P" button (direct_paint) to "im:" entry --tksurfer.c: add/export: scale_val --tksurfer.c: add/export: direct_paint() from im[][][] using normd parms --lib/help/tkmedit/interface: update --tkmedit.tcl: middle-click "i" to toggle invert contrast ($midpt => -$midpt) --tksurfer.tcl: rm 2x reread F3 "insurf:" (touch surfext does tix callback) --tksurfer.tcl: select_surfext blocks redraw if same as last (callback overlap!) --lib/help/tksurfer/saveview: update --tksurfer.tcl: mid-clk Save/Goto view to add suff to default name, surfer.mat --tksurfer.c: {read,write}_view_matrix use exported vmfname/$viewmatrix --tksurfer.tcl: fix Dijk button (normal ret to stderr, too? when did I break?) --lib/help/csurf/flattensurface: re-flatten, better save/view steps instruction --lib/tcl/{phasemovie,offsetmovie,searchightdiff}.tcl: re-use already there --tksurfer.tcl: listbox select pops up standard tclscript controls panels w/o GO --csurf: re-flatten sets subprocessredo: avoid second confusing overwrite query --{flatten,inflate}movie.tcl: change irritating $skip to $every, raise if there --tksurfer.c: write_{view,really}_matrix: add subj/surf/date comment --tksurfer.c: read_{view,really}_matrix: allow comments, bare CR's --tksurfer.tcl: write surfer.mat into log on "Save"/"Goto" --tksurfer.c: really_scale_brain->compute_normals_areas (so immed FILL area OK) --tksurfer.tcl; strip *.3d and *.flat in case patch infix matches surflooklist --lib/help/tksurfer/{surf,patch,brainpose}: update --wrappers.tcl confirmalert opt fix height for wrap lines (already linecnt-sens) --block AFNI,AFNI-ALL buttons from cd'ing, e.g., if 3dvolreg/2swap running in bg --csurf: VOLUME butt: if vol not found, suggest found *.mgz's from volllooklist --lib/help/tksurfer/{min,max}stat: add also controls phase rect limits --csurf: AFNI_PATH_SPACES_OK=YES: avgstruct,reconall,stripinit,3dvolreg,fourier --brik2cor.c: backslash-quote system arg for abs outpath w/spaces --lib/help/csurf/csurf: update spaces-in-path advice ########################################################################## PREVIOUS UPDATE: 22 Jul 2019 ########################################################################## --[### end spaces-in-{CSURF,SUBJECTS,FUNCTIONALS}_DIR nightmare ###] --tkmedit.tcl: pathspaces: listcmd_{surf,ims}: set "$list $m" =>lappend list $m --csurf: refactor dyld/path spaces runafni proc for afni{cmd,allcmd,structcmd} --csurf: afnicmd: omit empty dyld for namespace fix: env cmd uses as arg not env --csurf: use AFNI_PATH_SPACES_OK=YES if detect FUNCTIONALS_DIR space (multiple) --csurf: {l}backslashspaces runacmd args/listargs that could have spaces (~135) --FreeSurfer.sh: fix lss,lsf,cds,cdf functions to accept spaces --FreeSurfer.csh: fix lss,lsf,cds,cdf aliases to accept spaces --mk0: unwind allow spaces edits to "tcltktix" (spaces break tcl configure's) --mk0: (sh) allows space in srcdir path only for option "dist" --mk0.csh: block all options if spaces in srcdir path, suggest mk0 (sh) --N.B.: 10.12 tk{surfer/medit/strip} compiles coredump on 10.6 (converse OK) --backslash-quote cat/gunzip/system args for paths w/spaces in following: => calcimg.c/fill.c/rawaverage.c/regcor.c/tkregister.c/wmfilter.c/tkstrip.c ...