################################################################### UPDATE: 29 Jun 2020 ################################################################### ---------------------------------------------- MacOS 10.10+ interface slowdown fix ---------------------------------------------- On recent MacOS's (e.g., 10.15), the catastrophic tk interface slowdown that began with MacOS 10.10 can be fixed simply by the following sequence: boot login, start X11 logout login, start X11 The speedup will stick until the next reboot (start csurf with 'csurf -nohack' to skip the xterm cover/uncover hack). ---------------------------------------------- FreeSurfer.zsh ---------------------------------------------- FreeSurfer.sh has been fixed to be zsh-compatible for MacOS 10.15. I added a link so both 'source FreeSurfer.sh' and 'source FreeSurfer.zsh' will work in both zsh and bash. ---------------------------------------------- new tcl script - searchlightarea.tcl ---------------------------------------------- This script estimates local area differences by resampling individual subject vertexwise area data to fsaverage, and then running a surface-based searchlight operation on the resampled data using fsaverage sphere. First, create a Cross-Subject Session (for display subject, fsaverage) with: csurf -> File -> New SphereAvg (pseudo-subject "XS" for "cross-session") Then, open the just-created empty session and select searchlightarea.tcl from the "tcl:" dropdown in at the top left of the tksurfer interface. This generates a pop-up to select a subject and adjust parameters. Clicking "RUN SCRIPT" on the pop-up resamples the area data, and then runs the searchlight operation: 4 -> sum of data in searchlight writing the result of the operation as a vertexwise curvature-format file. The multithreaded operation takes about 10 min/hemisphere on an Intel i7. The size, ${num,sqmm,mm}, of the approximately geodesic surface searchlight circles can be specified by vertex count, area, radius, or by neighbor order (1=immediate neighbors, 2=also include neighbors of neighbors, etc): Searchlight size ($fillneartype): 0 -> num vertices 1 -> area (in mm^2) 2 -> radius (in mm) 3 -> neighbor order (1-6) The first three searchlight size specifications ($fillneartype) use the C/tcl function, searchlightop_val2stat (multi-threaded), while the fourth specification uses the C/tcl function, neighop_val2stat (similar result for similar vertex count, goes up to 6th-order neighbors, which is 127 vertices). Adjustable parameters can be hard-coded in this script (see commented-out example inside) in order to run it non-interactively from the command line as a tksurfer tcl script, for example: #! /bin/sh sublist="marty sean jill sue" hemlist="rh lh" cd $SUBJECTS_DIR/fsaverage/scripts cp $CSURF_DIR/lib/tcl/searchlightarea.tcl . for sub in $sublist; do for hem in $hemlist; do export sampsubj=$sub # tcl script reads env tksurfer fsaverage $hem sphere -tcl searchlightarea.tcl done done TODO: Gaussian instead of boxcar ---------------------------------------------- tksurfer reads/writes Wavefront *.obj surface files ---------------------------------------------- Surfaces in Wavefront/Alias *.obj (ASCII) format can now be autodetected and read by tksurfer. Any optional color appended to vertices is currently ignored and normals are recalculated (rather than read out of the *.obj file). Surfaces can be exported in Wavefront/Alias format using the "OBJ" button on the "outsurf:" line at the top right of the large F3 interface (C/tcl function: write_obj_surface). Output formats are: basic surface include vertexwise colors include normals include colors + normals ---------------------------------------------- tksurfer reads colors from Wavefront *.obj surface files ---------------------------------------------- If a Wavefront *.obj (ASCII) format surface contains vertexwise colors, these can now be read as if they were an annotation (a set of patches-of-interest). That is, the vertices in each unique color will be assigned to different brain region, and can then be used to extract surface data. Any *.obj file in the surf directory will be loaded in the "label:" line dropdown and can be read with the "D" button (which uses the C/tcl function, read_obj_to_annot). ---------------------------------------------- tksurfer reads Brain Voyager *.poi files ---------------------------------------------- Any *.poi file, a Brain Voyager "Patches of Interest" annotation file (ASCII, vers=2), in the current subject's label directory will be loaded into the "label:" line dropdown and can be read with the "D" button (which uses the C/tcl function, read_obj_to_annot). The expected file format looks like this: ------------------------------------------- FileVersion: 2 FromMeshFile: "" NrOfMeshVertices: 163842 NrOfPOIs: 8 NameOfPOI: "Te10" InfoTextFile: "" ColorOfPOI: 227 26 28 LabelVertex: 0 NrOfVertices: 468 52656 52657 ... [vtxnums for every vtx in this patch] NameOfPOI: "Te11" InfoTextFile: "" ColorOfPOI: 253 191 111 LabelVertex: 0 NrOfVertices: 855 43 166 ... [vtxnums for every vtx in this patch] ... [additional patches] ------------------------------------------- The result of reading a *.poi file is the same as when reading an MGH annotation file, and the displayed labels/patches can be used in the same way to extract surface data. ---------------------------------------------- tksurfer reads Brain Voyager *.srf surface files ---------------------------------------------- Brain Voyager *.srf binary surface files can now be read into tksurfer. Vertexwise color data is currently ignored, and surface normals and neighbor lists are recalculated. N.B.: when the left-handed PIL coordinates of native Brain Voyager surfaces are read into the right-handed RAS coordinate system of freesurfer, the surface will appear mirror-imaged (a right hemisphere will look like a left hemisphere and vice versa). The surface can be mirror-imaged (see next) and then written out as a native freesurfer surface. ---------------------------------------------- tksurfer can mirror-image a surface ---------------------------------------------- The new "FlipHemi" button at the upper far right of the larger F3 interface mirror-images the currently displayed surface. N.B.: this will misalign the surface with any 3D image data that it was derived from. N.B.: there is no permanent effect until the surface is saved (see below). This operation is occasionally needed for surfaces read in from other software packages. The C/tcl functions used are: really_flip_brain_x compute_normals_areas redraw After the x-coordinate has been flipped, the order of the vertices in the entry for each face is flipped so that lighting calculations work correctly. The resulting flipped surface can be saved by entering a name in the upper-left "outsurf:" entry in the F3 interface and clicking "W". To perform the same action with a tcl script, do something like: setfile outsurf ~/surf/lh.my_flipped_RH write_binary_surface ---------------------------------------------- tkmedit FILL can append, get volume, fill 3D annotation ---------------------------------------------- The FILL button now allows appending to an existing filled ROI, measuring the total volume of current ROIs, and filling 3D annotation regions (e.g., from rh.aparc.a2009s.annot). In order of precedence, the criteria for a connected FILL volume can be: 1) current clicked 3D annotation segid 2) stat mask above current $sfthresh 3) overlay data amplitude above curr $fthresh 4) struct between $white_lolim and $white_hilim Whichever of these four are in force can be logically AND'ed with a max radius as well as any temporary edits-to-black of the struct underlay image (to constrain the FILL). ########################################################################## UPDATE: 29 Jun 2020 ########################################################################## --csurf: fix bug in -nohack option --tksurfer.tcl: SAVE/GOTO add-suffix-to-viewmatrix popups show avail suffixes --csurf: add lights,blufact to all-help --mk0: combine lib/help/tksurfer/light{1,2,3,4} -> lights --tksurfer.tcl: better help for the lights --tksurfer.tcl: bold the "View" butt (curr saved matrix popup), report saved dir --lib/help/tksurfer/script_searchligharea: update --FreeSurfer.sh: fix zsh path parsing --tksurfer.tcl: force load example-res mgz file before FILL3d, write_fill_images --tksurfer.tcl: also load subjectdir *.mgh files into "val:" dropdown (areas) --tksurfer.tcl: 6th overload S/V with swap_origarea_val --tksurfer.c: add swap_origarea_val() -> .origarea loaded at start w/areafile --tksurfer.c: add copy_area_curv() (fix so-far-unused copy_area_val() bug) --tksurfer.c: export threadcnt (def=8), incl opt/env --tksurfer.tcl: blk reabbrev callbacks curv/area in sessdir (was just subjdir) --searchlightarea.tcl/mk0: new script --calcvert.c: 1D MGH outp opt for area (rename vars: vnum*->vcnt*, fnum*->fcnt*) --tksurfer.tcl: fix mid-clk SMOOTH logic (searchlightop_val2stat does neighfill) --tksurfer.c: searchlightop_val2stat calls neighop_val2stat if filltype=NEIFILL --tksurfer.c: add SLOPSUM searchlight operation to neighop_val2stat --tksurfer.c: add copy_area_val() --tkmedit.c: fill_roi, vol_rois put return in $genstrret_1k for tcl scripts --tkmedit.c: print 3D brainregion2 name to log (was only double-mid-click) --tkmedit.c: shift-middle-TRUNC voxel count now pops-up result --lib/help/tkmedit/roi_fill: update --tkmedit.tcl: shift-left-click overload FILL button: vol_rois --tkmedit.tcl: middle-click overload FILL button: clear_rois --tkmedit.c: vol_rois() to measure current total ROI volume (vox=64) --tkmedit.c: fill_roi() has option to append to existing region --tkmedit.c: fill_roi() now has option to fill annotation region --tkmedit.c: add clear_rois() (was roi_fill auto-cleared each time) --lib/help/csurf/rc-surfaces,lib/help/tksurfer/surf: FlipHemi update --csurf/tksurfer.tcl: chklefthandedsurf: change subj re-arms chk left-handed --csurf: warn read *.srf (but not *.obj), kill popup after 8sec, twice only --tksurfer.tcl: warn read *.srf possibly left-handed (but not *.obj) --tksurfer.c: back to not-flipping BV coords (force use F3 interface FlipHemi) --tksurfer.tcl: rm "surf:" dropdown dups (rh.surftmp match, strip, *.obj re-add) --tksurfer.c: bail on read BV cols (color indices + RGB, req's POI file anyway!) --tksurfer.c: make_filenames: *obj,*srf leave hemi on fpref for stdfmt curv etc --tksurfer.tcl: select_surf try pre-append *.obj/*.srf if non-preappend missing --csurf: tksurfercmd: special case for non-freesurfer-style *.obj,*.srf names --csurf: =>w/no surfext prefix, can't tell if intended file is ?h.*.obj, *.obj --csurf: =>parallel to tksurfer:make_filenames() -> not found, try no preappend --csurf: fixsurfaces: only strip hemi from globbed surf tail if present! --csurf: fixsurfaces (fix "surface:" dropdown if newsubj): load all *.obj,*.srf --tksurfer.c: make_filenames: *.obj/*.srf, also chk surffile no hemi preappend --lib/help/tksurfer/outsurfobj_write: new helpfile, add to mk0 --tksurfer.tcl: add OBJ to F3 panel for write_obj_surface --tksurfer.c: write_obj_surface(): basic, colors, normals, colors+normals --tksurfer.c: order_all_faces(): arr faces around vtxs: unordered->same winding --tksurfer.tcl: load all *.srf regardless of hemi to "surf:" dropdown --csurf: load all *.srf regardless of hemi to "surface:" dropdown, fixsurfaces --tksurfer.c: make_filenames accepts no-hemi-prefix *.srf --tksurfer.c: read_binary_surface(): tri BrainVoyager .srf surf fmt (flip x!) --tksurfer.c: fish out find_annot_borders() --csurf: add Flip (FlipHemi) to all help panel --lib/help/tksurfer/fliphemi: new help file, add to mk0{.csh} --tksurfer.tcl: add "FlipHemi" button to REDRAW row on F3 interface --tksurfer.c: flip_faces(): used by really_flip_brain functions --tksurfer.c: fix read_binary_surface reading of *.off surfaces (export was OK) --tksurfer.tcl: "D" button uses read_obj_to_annot if *.obj suffix --tksurfer.tcl: also load $subject/surf/*.obj file to "label:" dropdown --tksurfer.c: read_obj_to_annot(): read just colors out of *.obj surf to annot --tksurfer.tcl: "D" button uses read_poi_annot if *.poi suffix --tksurfer.tcl: also load $subject/label/*.poi file to "label:" dropdown --tksurfer.c: read_poi_annot(): load poi file into mghannot/brainregion --lib/help/csurf/csurf, lib/help/tksurfer/surf, add .obj format --tksurfer.c: flip_normals() --csurf: load all *.obj regardless of hemi to "surface:" dropdown, fixsurfaces --tksurfer.tcl: load all *LH/RH*.obj to "surf:" dropdown --tksurfer.c: make_filenames accept any *.obj surf, detect maybe fixes hemi --tksurfer.c: read_binary_surface() accepts tri Wavefront .obj surface format --tksurfer.c: rename vertex struct members: vnum->vcnt, num->fcnt --tksurfer.c: really_flip_brain --tksurfer.tcl: also look-for/dropdown-load oldstyle valfiles in $subject/surf --mkrandlut(.tcl): new lib/tcl script (add to mk0) --tksurfer.c: add SLOPPAT=3 to neighop_val2stat->color patches w/stat int id's --tksurfer.c: neighop_val2stat SLOPPAT=3: non-overlap colpatches w/stat intid's --tksurfer.tcl: jam unlabeled $insidesurffact entry next to offset on F3 panel --csurf: add insidesurffact to all help --lib/help/tksurfer/insidesurffact: new helpfile, add to mk0 --tksurfer.c: insidesurffact to control relative brightness inside surface --csurf: also load surface dropdown with $inflatedext? $pialext? --csurf: accepts subject or session dir as arg --csurf: change default startup volume to orig (was T1) ########################################################################## PREVIOUS 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 ...