------------------------------------------
 tkstrip -- interactively strip skull
------------------------------------------
Tkstrip reads a volume data set and attempts to
strip the skull off of it.  This can be started
from csurf for the currently selected volume data
set with shift-middle-click on the VOLUME button.

The basic usage is:

    tkstrip <subj> <somevol.mgz>

The primary output is another skull-stripped 3D
dataset, which can be a different data set than
the one used to find the skull.  The stripping
surface and tiffs of it can also be saved.

N.B.: on MacOS 10.11+, the environment variable 
DYLD_LIBRARY_PATH is not passed into a shell
script, which will prevent tkstrip from seeing
the csurf X11 tcl/tk libraries.  To use tkstrip 
in a MacOS 10.11+ shell script, include the
following line before the first call to tkstrip:

csh/tcsh:
  setenv DYLD_LIBRARY_PATH $CSURF_LIBRARY_PATH

sh/bash:
  export DYLD_LIBRARY_PATH=$CSURF_LIBRARY_PATH

-------------------------------------------
 Keyboard shortcuts -- for both image,tk windows
-------------------------------------------
  # rotate view of surf (interface win: add Mod)
  R/L arrow      -- rotate around vert axis
  up/down arrow  -- rotate around horiz axis
  Shift-R/L arrow      -- translate right/left
  Shift-up/down arrow  -- translate up/down
-------------------------------------------

Main parameters

 -fzero <0-255>  (40) norm MRIforce=0 this val (lo->plump)
 -fmax <0-255> (130)sm1:if MRI>fmax,inforce=0(hi->plump)
 -dfrac <0.1-2.0>  (0.7) start ellipsoid rel to avg MRI radius
 -istilt <mm>         (1.0) inside stilt
 -fsteepness <0.1-8>   (0.5) steepness MRI->force sigmoid
 -fstrength <~1>     (1.0) sm4 only: scale pnt-force tanh
 -flattenflag <0,1>  (0) smooth surface
 -momentumflag <0,1>   (1) add fraction of previous move 
 -update <frac>  (0.9) update:d{x,y,z} += update*d{x,y,z}
 -decay <frac>  (0.9) momentum:d{x,y,z} += decay*m{x,y,z}

Shrinkmodes (where to sample along vertex normal)

 -shrinkmode <1,3,4>  (def=1)
     1 = samp-in/out
     3 = samp-out
     4 = samp-pnt

Built-in scripts

---------------------------------------------------------------
action mode insurf     outsurf       outim         dat (cwd)
---------------------------------------------------------------
   0  ===> default=0: *don't* run a builtin script <====
   1     1     ic4.tri     brain.tri         brain        brain.dat
   2     4     ic4.tri  inner_skull.tri    [none]    inner_skull.dat
   3     3     ic4.tri  outer_skull.tri    [none]    outer_skull.dat
   4     4     ic4.tri   outer_skin.tri    [none]    outer_skin.dat
   5     4     ic4.tri   brainPD.tri          tmp           [none]
   6     4     ic4.tri   brainPD.tri          tmp           [none]
---------------------------------------------------------------
N.B.: for action=6, after shrink on inim, reads orig.mgz to strip it

Basic usage:

 tkstrip subj CORdir/mgzfile [-action <n>] [-tcl script] [-opt..]

Simple examples:

 tkstrip marty T1.mgz            (interactive)
 tkstrip marty T1.mgz -action 5  (strip to tmp.mgz)

How to strip noise in air from quantitative T1 image

Quantitative T1/PD images contain noise in the
air because, roughly, two extremely small noisy
signals are being divided by each other.  To
strip this noise from an quantitative T1 image
named orig.mgz, use one of the raw T1- or
PD-weighted input images with action-6, or
interactively as follows (pd.mgz in example
below):

  startup interface:

    tktrip marty pd.mpg

  [interactive commands follow]
  use finer insurf: -> ic5.tri, READ
  tick ACTION "outskin"
  reduce istilt: 3.0 -> 0.0
  click "SCALE SURF TO MRI"
  click "SHRINK"
  change inmri: ~/mri/pd.mgz => ~/mri/orig.mgz
  click "PEEL"
  
This will strip the noise off of the quantititive
T1 image, orig.mgz, overwriting the original
image (first save original aside if desired).

---------------------------------------------------------------
C-code for actions
---------------------------------------------------------------
/** file,parm defaults for built-ins: before read data files */
if (action==1) {
  shrinkmode = 1;
  sprintf(dfname,"brain.dat");
  sprintf(gfname,"%s/lib/bem/ic4.tri",csurfdir);
  sprintf(ofname,"%s/%s/surf/brain.tri",
    lsubjectsdir,lpname);
  if (!outimoptflag)
    sprintf(bfname,"%s/%s/mri/brain",lsubjectsdir,lpname);
}
else if (action==2) {
  shrinkmode = 4;
  sprintf(dfname,"inner_skull.dat");
  sprintf(gfname,"%s/lib/bem/ic4.tri",csurfdir);
  sprintf(ofname,"%s/%s/surf/inner_skull.tri",
    lsubjectsdir,lpname);
  if (!outimoptflag)
    sprintf(bfname,"%s/%s/mri/tmp",lsubjectsdir,lpname);
}
else if (action==3) {
  shrinkmode = 3;
  sprintf(dfname,"outer_skull.dat");
  sprintf(gfname,"%s/%s/surf/inner_skull.tri",
    lsubjectsdir,lpname);
  sprintf(ofname,"%s/%s/surf/outer_skull.tri",
    lsubjectsdir,lpname);
  if (!outimoptflag)
    sprintf(bfname,"%s/%s/mri/tmp",lsubjectsdir,lpname);
}
else if (action==4) {
  shrinkmode = 4;
  sprintf(dfname,"outer_skin.dat");
  sprintf(gfname,"%s/lib/bem/ic4.tri",csurfdir);
  sprintf(ofname,"%s/%s/surf/outer_skin.tri",
    lsubjectsdir,lpname);
  if (!outimoptflag)
    sprintf(bfname,"%s/%s/mri/tmp",lsubjectsdir,lpname);
}
else if (action==5) {
  shrinkmode = 4;
  dfrac = 0.4;
  sprintf(gfname,"%s/lib/bem/ic4.tri",csurfdir);
  sprintf(ofname,"%s/%s/surf/brainPD.tri",lsubjectsdir,lpname);
  if (!outimoptflag)
    sprintf(bfname,"%s/%s/mri/tmp",lsubjectsdir,lpname);
}
else if (action==6) {
  shrinkmode = 4;
  dfrac = 1.2;
  sprintf(gfname,"%s/lib/bem/ic4.tri",csurfdir);
  sprintf(ofname,"%s/%s/surf/brainPD.tri",lsubjectsdir,lpname);
  if (!outimoptflag)
    sprintf(bfname,"%s/%s/mri/tmp",lsubjectsdir,lpname);
}

/** read data files */
check_infiles(mfname,gfname);
read_geometry(gfname);
read_images(mfname);
read_datfile(dfname);
init_surf_to_image();

/** run built-in, no-graphics scripts, maybe exiting */
if (action==1) {   /* skull stripping -- write surf and images */
  momentumflag = 1; MRIflag = 1; flattenflag = 0; shrink(100);
  momentumflag = 0; MRIflag = 0; flattenflag = 1; shrink(10);
  write_geometry(ofname);
  peel_brain();
  write_images(bfname);
  if (getenv("noexit")==NULL) exit(0);
}
else if (action==2) {    /* inner skull -- just write surf */
  momentumflag = 1; MRIflag = 1; flattenflag = 0; shrink(100);
  momentumflag = 1; MRIflag = 0; flattenflag = 0; shrink(50);
  momentumflag = 1; MRIflag = 1; flattenflag = 0; shrink(100);
  momentumflag = 0; MRIflag = 0; flattenflag = 1; shrink(10);
  write_geometry(ofname);
  if (getenv("noexit")==NULL) exit(0);
}
else if (action==3) { /* outer skull -- just write surf */
  move_vertices(istilt);
  write_geometry(ofname);
  if (getenv("noexit")==NULL) exit(0);
}
else if (action==4) { /* outer skin -- just write surf */
  momentumflag = 1; MRIflag = 1; flattenflag = 0; shrink(200);
  momentumflag = 0; MRIflag = 0; flattenflag = 1; shrink(10);
  write_geometry(ofname);
  if (getenv("noexit")==NULL) exit(0);
}
else if (action==5) { /* raw 1st echo PD -- write surf,imgs */
  fzero = 75.0; istilt = 0.0;
  fsteepness=50.0; momentumflag=1; update=0.1; decay=0.1;
  fstrength = 0.1; MRIflag = 1; flattenflag = 0; shrink(10000);
  fstrength = 0.5; MRIflag = 1; flattenflag = 1; shrink(100);
                   MRIflag = 0; flattenflag = 1; shrink(10);
  write_geometry(ofname);
  peel_brain();
  write_images(bfname);
  if (getenv("noexit")==NULL) exit(0);
}
else if (action==6) { /* raw 1st echo PD, strip orig to tmp */
  fzero = 75.0; istilt = 0.0;
  fsteepness=50.0; momentumflag=1; update=0.1; decay=0.1;
  fstrength = 0.1; MRIflag = 1; flattenflag = 0; shrink(10000);
  fstrength = 0.5; MRIflag = 1; flattenflag = 1; shrink(100);
                   MRIflag = 0; flattenflag = 1; shrink(10);
  write_geometry(ofname);
  sprintf(mfname,"%s/%s/mri/orig.mgz",lsubjectsdir,lpname);
  read_images(mfname);
  peel_brain();
  write_images(bfname);
  if (getenv("noexit")==NULL) exit(0);
}

