################################################################### 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//image//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 ------------------------------------------- funct (shift-ctrl-left-click): write_val_annotedcols_vertices ------------------------------------------- New histogram options The histogram printing function has two new options: print_hist 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 ...