##############################################################################
# searchlightarea.tcl (tksurfer): searchlight local area
##############################################################################
### run in Cross-Subject Session w/subject fsaverage (pick indiv subj in popup)
# output file goes to Cross-Subject Session scandir "searchlight-area":
# $FUNCTIONALS_DIR/YYMMDDXS-<cohort>/image/searchlight-area/$hemi-area-<subj>-$size.label

### def tcl-only on 1st entry (don't biff set-by-popup on interactive reenter)
# don't change these here: for custom script, uncomment/adjust copies below 
if ![info exists userok]              { set userok 0 }
if ![info exists sampsubject]         { set sampsubject __nobody__ }
if ![info exists fillneartype]        { set fillneartype 0 }
if ![info exists num,sqmm,mm]         { set num,sqmm,mm 250 }
set crv,mgh,label  crv             ;# non-editable for now
set area_scandir searchlight-area  ;# non-editable
set searchlightop 4                ;# non-editable, shown on pop-up
set rtmptcl /tmp/TmpTclResamp.[pid]
#TODO: save var state on entry

### HOWTO: run interactively from tksurfer
#  select searchlightarea.tcl from "tcl:" dropdown (under DEFAULT LIB SCRIPTS)
#  GO
#  adjust parms in pop-up
#  RUN SCRIPT
#
### HOWTO: run interactively from tksurfer with saved non-default parms
#  copy this lib script into subject/session scripts dir
#  uncomment/edit parameters below (N.B.: uncommented vars override popup vals!)
#  open inflated surface using csurf SURFACE button (or tksurfer cmdline)
#  find edited script in "tcl:" dropdown (under LOCAL SUBJECT/FUNCT SCRIPTS)
#  GO
#  verify non-default parms in pop-up (N.B.: changes made in pop-up ignored!)
#  RUN SCRIPT
#
### HOWTO: run from shell/cmdline:
#  copy this default lib script into a subject/session scripts dir
#  uncomment/adjust parameters below
#  example (subject=marser-qT1):
#    cd $SUBJECTS_DIR/marser-qT1/scripts
#    tksurfer marser-qT1 rh inflated -tcl searchlightarea.tcl
#

##############################################################################
# for cmdline or subj-specific tksurfer tcl script: uncomment/adj these parms
##############################################################################
### N.B.: any vars uncommented here override interactively entered popup values

### tcl-only parameters (not linked to tksurfer C-variables)
#set sampsubject  __nobody__    ;# subj to sample to fsaverage
#set crv,mgh,label crv        ;# output format
### tcl-variables linked to C-variables in tksurfer.c
# for complete list, see: tksurfer -help
#set searchlightop  4           ;# 0=avg, 1=count, 2=variance, 3=paint, 4=sum
#set fillneartype   0           ;# fill-to criterion: 0=num, 1=area, 2=radius
#set num,sqmm,mm  250           ;# num vtxs (cnt), area (mm^2), or radius (mm)

##############################################################################
#TODO: check/warn here if above uncommented have overriden popup-edited val

### two interactive ways to override defaults (popup or current env)
if ![info exists searchlightactrls] { set searchlightactrls "" }
if [winfo viewable .] {  ;# make popup -- N.B.: re-enters this script on OK
  set noexit 1
  if {!$userok} {
    if [winfo exists $searchlightactrls] { raise $searchlightactrls; return }
    set searchlightactrls [controls "SEARCHLIGHT AREA\
                              \noutput: vtxwise searchlight sum\
                              \nof individual subject orig area\
                              \n\nFill nearest (fillneartype)\
                                \n(N.B.: on fsaverage!): \
                                \n 0:  num vertices\
                                \n 1:  area (mm^2)\
                                \n2:  radius (mm)\
                                \n        3:  neighbor ord (1-6)\
                              \n\nSearchlightOp: sum (4)" {
      sampsubject
      whitespace
      searchlightop
      fillneartype
      num,sqmm,mm
      crv,mgh,label
      whitespace
      whitespace
    } "RUN SCRIPT" "set userok 1; source [info script]" 14]
    ### hack: repl controls-made entry w/filled tix dropdown w/subjects
    pack forget $searchlightactrls.sampsubject
    tixComboBox $searchlightactrls.cbx -label "subject:" -dropdown true \
      -editable true -variable sampsubject -listwidth 243
    $searchlightactrls.cbx subwidget label config -font $ffont -bg $bgcol
    $searchlightactrls.cbx subwidget entry config -font $hfont \
      -selectbackground $selbgcol -highlightbackground $bgcol -width 21
    $searchlightactrls.cbx subwidget listbox config -font $hfont
    pack $searchlightactrls.cbx -after $searchlightactrls.la -side top
    set globfullsampsubjects [glob -nocomplain $env(SUBJECTS_DIR)/*]
    foreach fullsampsubject $globfullsampsubjects {
      $searchlightactrls.cbx insert end [file tail $fullsampsubject]
    }
    bind $searchlightactrls <ButtonRelease-3> { helpwin script_searchlightarea }
    ### hack: disable searchlight operation, output format entries
    $searchlightactrls.searchlightop.e config -state disabled
    "$searchlightactrls.crv,mgh,label.e" config -state disabled
    ### end controls proc hacks
    unset globfullsampsubjects fullsampsubject
    return
  }
} else {                 ;# batch scripts; re-read env to override defaults
  source $env(CSURF_DIR)/lib/tcl/readenv.tcl
}

### force subject to be fsaverage
if ![string match "fsaverage*" $subject] {
  confirmalert "[file tail $script]: startup subject (csurf \"subject:\")\
            \n\n    $subject\
            \n\nmust always be \"fsaverage\"\
            \n\n1) First, create Cross-Subject Session (subj=fsaverage) with:\
            \n\n      csurf -> File -> New SphereAvg\
              \n      (use pseudo-subject \"XS\" for \"cross-session\")\
            \n\n2) Then, pick individual subject to operate on from\
              \n      SEARCHLIGHT AREA pop-up"
  return
}

### force surface to be sphere (or sphere.reg)
if {"$surfext" != "sphere" && "$surfext" != "sphere.reg"} {
  confirmalert "[file tail $script]: startup surface (csurf \"surface:\")\
            \n\n    $surfext\
            \n\nmust always be \"sphere\" (or \"sphere.reg\")\
            \n\nThis is surface used for distance-based searchlights"
  return
}

### catch session dup's subject from open fsaverage surface with SURFACE button
if [string match $isession "$env(SUBJECTS_DIR)/fsaverage"] {
  confirmalert "[file tail $script]: must run from Cross-Subject Session:\
            \n\n1) First, create Cross-Subject Session (subj=fsaverage) with:\
            \n\n      csurf -> File -> New SphereAvg\
              \n      (use pseudo-subject \"XS\" for \"cross-session\")\
            \n\n2) Then, pick individual subject to operate on from\
              \n      SEARCHLIGHT AREA pop-up"
  return
}

### force cross-subject session ending in *XS*/image
if ![string match "*XS*/image" $isession] {
  if ![okreplace "" \
               "[file tail $script]: can't use non-standard session:\
            \n\n    $isession\
            \n\n1) First, create Cross-Subject Session (subj=fsaverage) with:\
            \n\n      csurf -> File -> New SphereAvg\
              \n      (use pseudo-subject \"XS\" for \"cross-session\")\
            \n\n2) Then, pick individual subject to operate on from\
              \n      SEARCHLIGHT AREA pop-up"
        "Use NonStd Session"] {
    return
  }
}

### check input subject exists (maybe typed incorrectly)
if ![file exists $env(SUBJECTS_DIR)/$sampsubject] {
  confirmalert "[file tail $script]: subject:\
            \n\n    $sampsubject\
            \n\nnot found"
  return
}

### check fillneartype
if {$fillneartype < 0 || $fillneartype > 3} {
  puts \
   "tksurfer: [file tail $script]: ### bad fillneartype: $fillneartype (OK:0-3)"
  if [winfo viewable .] {  ;# tcl tools window
    confirmalert "Bad fillneartype:\n\n    $fillneartype\
  \n\nOK:\n\n    0 -> num\n    1 -> area\n    2 -> rad\n    3 -> neighbor order"
    return
  } else { exit }  ;# cmdline script
}
if {$fillneartype == 3} {
  if {${num,sqmm,mm} < 1 || ${num,sqmm,mm} > 6} {
    puts "tksurfer: [file tail $script]: ### bad num,sqmm,mm (neighbor order): ${num,sqmm,mm} (OK:1-6)"
    if [winfo viewable .] {  ;# tcl tools window
      confirmalert \
        "Bad num,sqmm,mm (neighbor order):  ${num,sqmm,mm}\n\nOK: 1-6"
      return
    } else { exit }  ;# cmdline script
  }
}

### check output format
if {"${crv,mgh,label}" != "crv" &&
    "${crv,mgh,label}" != "mgh" &&
    "${crv,mgh,label}" != "lab"} {
  puts "tksurfer: [file tail $script]: ### bad output fmt (OK:crv,mgh,lab))"
  if [winfo viewable .] {  ;# tcl tools window
    confirmalert "Bad output format:\n\n    ${crv,mgh,label}\
      \n\nOK:\n\n    val -> *.w\n    mgh -> *.mgh\n    lab -> *.label (ASCII)"
    return
  } else { exit }  ;# cmdline script
}
#TODO: respect output fmt (curr resample/output hard-coded crv)

### create searchight-area scandir if not already there
if ![file exists $isession/$area_scandir] {
  exec mkdir $isession/$area_scandir
  if ![file exists $isession/$area_scandir] {
    confirmalert "[file tail $script]: can't create scandir for output:\
              \n\n    $isession/$areas_candir"
    return
  }
}

### setup output files (always overwrites), last-chance cancel
if {$fillneartype == 0} { set inf num }
if {$fillneartype == 1} { set inf area }
if {$fillneartype == 2} { set inf rad }
# N.B.: mri_surf2surf inserts $hemi prefix into tail of $outfile1 abspath!
set d $isession/$area_scandir
set tval_arg $d/area-$sampsubject.${crv,mgh,label}       ;# surf2surf arg
set outfile1 $d/$hemi.area-$sampsubject.${crv,mgh,label} ;# actual output
set outfile2 $d/sumover-$inf=${num,sqmm,mm}-$sampsubject-$hemi.${crv,mgh,label}
### last chance (interactive-only) cancel
if [winfo viewable .] {  ;# tcl tools window
  if ![okreplace "" "Interface will be unresponsive during searchlight calc\
                \n\n(1) resample subject ($sampsubject) area to fsaverage\
                  \n(2) vertexwise sum searchlight area (indiv) on fsaverage\
                  \n(3) final output file (~10 min on 8-thread i7):\
                \n\n$outfile2\
                \n\nOK to start?" "Start Searchlight Area"] {
    return
  }
}

### go: resamp area to fsaverage, run searchlights on fsavg

### resample sampsubject's area to fsaverage
puts "tksurfer: [file tail $script]: resample $sampsubject area to fsaverage"
# assume mri_surf2surf on path (since tksurfer is)
set cmd "mri_surf2surf \
  --srcsubject $sampsubject \
  --trgsubject fsaverage \
  --hemi $hemi \
  --mapmethod nnf \
  --sval-area orig \
  --tfmt curv \
  --tval $tval_arg"
catch { puts [eval exec $cmd] } ret
if {$ret != ""} { puts "tksurfer: [file tail $script]: ### scripterr: $ret" }
logcmd "eval exec $cmd"
puts "tksurfer: [file tail $script]: resampled $sampsubject area written to:"
puts "tksurfer: [file tail $script]:  $outfile1"
### don't require second OK
#if [winfo viewable .] {
#  confirmalert "[file tail $script]: $sampsubject area resampled to\
#              \nfsaverage and written to:\
#            \n\n    $outfile1\
#            \n\nclick \"OK\" to start searchlight operation (~10 min)\
#              \n(csurf log for progress)"
#}
puts "tksurfer: [file tail $script]: mri_surf2surf cmd:"
puts "tksurfer:  $cmd"

### load/display resampled indiv subj area data onto fsaverage
if {!$openglwindowflag} {
  open_window
  logcmd "open_window"
  make_lateral_view
  logcmd "make_lateral_view"
}
set complexvalflag 0
logcmd "set complexvalflag 0"
set overlayflag 1
logcmd "set overlayflag 1"
set colscale 6
logcmd "set colscale 6"
clear_values
logcmd "clear_values"
clear_stats
logcmd "clear_stats"
setfile val $outfile1     ;# updates/reabbreviates "val:" line
read_binary_values
logcmd "read_binary_values"
redraw
logcmd "redraw"

### run searchlights, save vertexwise sums as curv file
searchlightop_val2stat $fillneartype ${num,sqmm,mm} $searchlightop
logcmd "searchlightop_val2stat $fillneartype ${num,sqmm,mm} $searchlightop"
swap_stat_val              ;# see searchlights result saved in .stat
logcmd "swap_stat_val"
if { "${crv,mgh,label}" == "crv" } {
  swap_curv_val            ;# so we can write .curv file
  logcmd "swap_curv_val"
  setfile curv $outfile2   ;# touches curvabbrev -> select_curv -> noexist popup
  #set curv $outfile2      ;# safer
  write_binary_curv
  swap_curv_val            ;# restore to .val for visibility
  logcmd "swap_curv_val"
}
if { "${crv,mgh,label}" == "mgh" } {
  # TODO: write_mgh_values => 1D *.mgh
}
if { "${crv,mgh,label}" == "lab" } {
  # TODO: write_val_visible_vertices => ASCII *.label
}

### display vertexwise sums
set colscale 6
logcmd "set colscale 6"
set fmid 0.0
logcmd "set fmid 0.0"
set fslope 0.5
logcmd "set fslope 0.5"
redraw
logcmd "redraw"

### explain outputs
puts "tksurfer: [file tail $script]: vtxwise searchlight sum for $sampsubject:"
puts "tksurfer: [file tail $script]:   [file tail $curv]"
puts "tksurfer: [file tail $script]: output file directory:"
puts "tksurfer: [file tail $script]:   [file dirname $curv]"
if [winfo viewable .] {
  confirmalert "Vertexwise searchlight sum for $sampsubject:\
            \n\n    [file tail $curv]\
            \n\nOutput directory:\
            \n\n    [file dirname $curv]"
}

### cleanup
exec rm -f $rtmptcl
if ![info exists noexit] { exit }  ;# cmdline script
set userok 0
#if [info exists searchlightactrls] {destroy $searchlightactrls}
unset inf tval_arg outfile1 outfile2          ;# cleanup tmp script vars
return   ;# else catch in tksurfer.tcl returns err (=last return of last cmd)

