#!/bin/tcsh

# help?

if( $#argv < 2 )then
  echo
  echo '-----------------------------------------------------------------'
  echo
  echo 'This script will make a JPEG image showing the edges of an'
  echo 'EPI dataset overlay-ed on an anatomical dataset.  The purpose is'
  echo 'to let the user (you) judge the quality of the 3D registration.'
  echo
  echo 'Three images from each of the coronal, axial, and sagittal'
  echo 'AFNI image viewers are used, laid out in a 3x3 grid.'
  echo
  echo '@snapshot_volreg works by running the AFNI GUI inside a "virtual"'
  echo 'X11 display server program named "Xvfb", and saving images from'
  echo 'that copy of AFNI.  The script also uses programs from the netpbm11'
  echo 'software library to put the saved images together into a pleasing'
  echo 'layout.  If the script cannot find the netpbm11 software, it will'
  echo 'not run :('
  echo
  echo '-----------------------------------------------------------------'
  echo 'Usage: @snapshot_volreg ANATdataset EPIdataset [jname] [xdisplay]'
  echo
  echo 'Sample (from an afni_proc.py results directory):'
  echo
  echo '  @snapshot_volreg anat_final.sub-10506+tlrc      \'
  echo '                   pb02.sub-10506.r01.volreg+tlrc sub-10506'
  echo
  echo 'The output file from this example is "sub-10506.jpg".'
  echo '-----------------------------------------------------------------'
  echo
  echo 'Do NOT put a sub-brick index (such as "[0]") on the EPIdataset'
  echo 'name -- the script will automatically only use the "[0]" volume.'
  echo
  echo '(( Although the original use was for visualizing how well EPI ))'
  echo '(( and anatomical datasets were aligned by align_epi_anat.py, ))'
  echo '(( it is also useful to see how well 3dQwarp aligned an       ))'
  echo '(( anatomical dataset to a template dataset.                  ))'
  echo
  echo 'The optional third argument is the name of the output JPEG'
  echo 'file -- if it does not end in ".jpg", that suffix will be added.'
  echo 'If you do NOT supply a 3rd argument, the script will invent a name:'
  echo 'it is probably better for you to supply a 3rd argument.'
  echo
  echo 'The fourth (and very optional) argument is the display number'
  echo 'of an ALREADY RUNNING copy of Xvfb, as in'
  echo '  Xvfb :88 -screen 0 1024x768x24 &'
  echo 'If you do NOT supply this number (88 in the example), then'
  echo 'the script will start its own Xvfb (on a display of its choosing),'
  echo 'use it once, and then stop it. If you are going to run this script'
  echo 'many times in a row, starting and stopping your own Xvfb'
  echo 'instance will speed things up a little. Normally, you do not'
  echo 'need to use this 4th argument.'
  echo
  echo '-----------------------------------------------------------------'
  echo
  echo 'The edges from a typical EPI dataset are usually broken up and'
  echo 'do not completely outline sulci, ventricles, etc.  In judging'
  echo 'the quality of alignment, I usually start by looking at the'
  echo 'outlines of the large lateral ventricles -- if those are very'
  echo 'wrong, the alignment is not good.  After that, I look at the'
  echo 'sulci in the superior part of the brain -- if the EPI edges'
  echo 'there seem to be mostly aligned with the sulci, then I am'
  echo 'usually happy.  The base of the brain, where lots of EPI'
  echo 'dropout happens, often does not not show good edge alignment'
  echo 'even when the rest of the brain alignment looks good.'
  echo
  echo '-----------------------------------------------------------------'
  echo
  echo 'If this script crashes, then it might leave behind files with'
  echo 'names that start with "zzerm".  Delete these files.'
  echo 'It is also possible that the Xvfb program will still be running'
  echo 'if this script crashes.  A command such as that below can'
  echo 'be used to see if you have any stray Xvfb programs running:'
  echo
  echo '  ps X | grep Xvfb | grep -v grep'
  echo
  echo 'If there are any such programs, the command below can be used'
  echo 'to kill all of them:'
  echo
  echo '  killall Xvfb'
  echo
  echo '-------------- Author: The Madd Allineator ----------------------'
  echo
  exit 0
endif

# control variables

setenv AFNI_DONT_LOGFILE YES
unset noclobber

# check if all the needed auxiliary programs exist

set nerr = 0
set errm = "** ERROR:"

set plist = ( Xvfb djpeg cjpeg pnmcat pbmtext pnmscale pbmtopgm )
foreach pppp ( $plist )
  set wwww = `which $pppp`
  if( $status != 0 )then
    @ nerr++
    set errm = "$errm $pppp"
  endif
end

# we can use either pamcomp or pnmcomp, so only need to
# find one of the twain

set pcprog = pamcomp
set wwww = `which $pcprog`
if( $status != 0 )then
  set pcprog = pnmcomp
  set wwww = `which $pcprog`
  if( $status != 0 )then
    @ nerr++
    set errm = "$errm (pnmcomp OR pamcomp)"
  endif
endif

if( $nerr > 0 )then
  echo "$errm -- not found in path -- @snapshot_volreg fails"
  echo "** WARNING: this script cannot run without installing package netpbm11"
  exit 1
endif

# set the prefix for the anat and epi datasets

set adset = $argv[1]
set abase = $adset:t
set anat  = `basename $abase .gz`
set anat  = `basename $anat  .nii`
set anat  = `basename $anat  .HEAD`
set anat  = `basename $anat  .BRIK`
set anat  = `basename $anat  +tlrc`
set anat  = `basename $anat  +orig`
set anat  = `basename $anat  +acpc`
set anat  = `basename $anat  +tlrc.`
set anat  = `basename $anat  +orig.`
set anat  = `basename $anat  +acpc.`
if( $abase == $anat.nii.gz )then
  set asuff = .nii.gz
else if( $abase == $anat.nii )then
  set asuff = .nii
else
  set asuff = ""
endif

set edset = $argv[2]
set epi   = `basename $edset .gz`
set epi   = `basename $epi   .nii`
set epi   = `basename $epi   .HEAD`
set epi   = `basename $epi   .BRIK`
set epi   = `basename $epi   +orig`
set epi   = `basename $epi   +acpc`
set epi   = `basename $epi   +tlrc`
set epi   = `basename $epi   +tlrc.`
set anat  = `basename $anat  +tlrc.`
set anat  = `basename $anat  +tlrc`
set anat  = `basename $anat  +orig.`
set anat  = `basename $anat  +acpc.`

# set output image prefix

if( $#argv > 2 )then
  set jnam = $argv[3]
  set jnam = `basename "$jnam" .jpg`
  set jnam = `basename "$jnam" .JPG`
  set jnam = `basename "$jnam" .jpeg`
  set jnam = `basename "$jnam" .JPEG`
else
  set jnam = $anat.$epi
endif

# Are we re-using Xvfb?

unset xdisplay
unset killX
if( $#argv > 3 )then
  set xdisplay = $argv[4]
  if( ! -e /tmp/.X${xdisplay}-lock )then
    echo "** ERROR: it doesn't look like Xvfb is running with display $xdisplay"
    exit 1
  endif
endif

set exad = `3dinfo -exists $adset`
set exep = `3dinfo -exists $edset`

if( $exad == 0 || $exep == 0 )then
  if( $exad == 0 ) echo "** ERROR: @snapshot_volreg can't find $adset"
  if( $exep == 0 ) echo "** ERROR: @snapshot_volreg can't find $edset"
  exit 1
endif

# set some AFNI GUI things

setenv AFNI_NOSPLASH          YES
setenv AFNI_SPLASH_MELT       NO
setenv AFNI_LEFT_IS_LEFT      YES
setenv AFNI_IMAGE_LABEL_MODE  5
setenv AFNI_IMAGE_LABEL_SIZE  2
setenv AFNI_ENVIRON_WARNINGS  NO
setenv AFNI_COMPRESSOR        NONE

# start the X virtual frame buffer on display #xdisplay

set ranval = `count -dig 1 1 999999 R1`

if( $?xdisplay == 0 )then
  set killX     = 1
  set ntry      = 1
  set Xnotfound = 1
  while( $Xnotfound )
    set xdisplay = `count -dig 1 3 999 R1`
    if( -e /tmp/.X${xdisplay}-lock ) continue
    echo " -- trying to start Xvfb :${xdisplay}"
    Xvfb :${xdisplay} -screen 0 1024x768x24 >& /dev/null &
    sleep 1
    jobs > zzerm.$ranval.txt
    grep -q Xvfb zzerm.$ranval.txt
    set Xnotfound = $status
    \rm -f zzerm.$ranval.txt
    if( $Xnotfound == 0 )break ;
    @ ntry++
    if( $ntry > 99 )then
      echo "** ERROR: can't start Xvfb -- exiting"
      exit 1
    endif
  end
endif

setenv DISPLAY :${xdisplay}

# quasi-random temp filename prefix

set zpref = zzerm.X${xdisplay}-${ranval}

# crop the input anat to a standard size

set cdset = ${zpref}.acrop.nii

3dAutobox -npad 17 -prefix $cdset $adset

# resample the EPI to the anat grid

3dAllineate -input  ${edset}'[0]'     \
            -master ${cdset}          \
            -prefix ${zpref}.epiR.nii \
            -1Dparam_apply IDENTITY   \
            -final cubic

# find edges in the EPI

3dedge3 -input ${zpref}.epiR.nii -prefix ${zpref}.epiE.nii

# get the EPI automask and apply it to the edgized EPI

3dAutomask -q -prefix ${zpref}.epiM.nii -clfrac 0.333 -dilate 5 ${zpref}.epiR.nii
3dcalc -a ${zpref}.epiE.nii -b ${zpref}.epiM.nii -expr 'a*b' -prefix ${zpref}.epiEM.nii

# get the lower and upper thresholds for the edgized EPI

set epp = `3dBrickStat -non-zero -percentile 20 60 80 ${zpref}.epiEM.nii`
set eth = $epp[2]
set emx = $epp[4]

# run AFNI to make the 3 overlay images

set anatCM = ( `3dCM $cdset` )

set anatNN = `3dinfo -nijk $cdset`

set astep = `ccalc -int "cbrt($anatNN)/6.111"`

if( $astep < 2 ) set astep = 2

afni -noplugins -no_detach                                       \
     -com "SWITCH_UNDERLAY ${cdset}"                             \
     -com "SWITCH_OVERLAY ${zpref}.epiEM.nii"                    \
     -com "SET_DICOM_XYZ $anatCM"                                \
     -com "SET_PBAR_ALL +99 1 Plasma"                            \
     -com "SET_FUNC_RANGE $emx"                                  \
     -com "SET_THRESHNEW $eth *"                                 \
     -com "SEE_OVERLAY +"                                        \
     -com "SET_XHAIRS OFF"                                       \
     -com "OPEN_WINDOW sagittalimage opacity=6 mont=3x1:$astep"  \
     -com "OPEN_WINDOW axialimage opacity=6 mont=3x1:$astep"     \
     -com "OPEN_WINDOW coronalimage opacity=6 mont=3x1:$astep"   \
     -com "SAVE_JPEG sagittalimage ${zpref}.sag.jpg blowup=2"    \
     -com "SAVE_JPEG coronalimage  ${zpref}.cor.jpg blowup=2"    \
     -com "SAVE_JPEG axialimage    ${zpref}.axi.jpg blowup=2"    \
     -com "QUITT"                                                \
     ${cdset} ${zpref}.epiEM.nii

# convert the output JPEGs to PNMs for manipulation

djpeg ${zpref}.sag.jpg > ${zpref}.sag.pnm
djpeg ${zpref}.cor.jpg > ${zpref}.cor.pnm
djpeg ${zpref}.axi.jpg > ${zpref}.axi.pnm

# cat them together, make a text label, overlay it, make output JPEG

pnmcat -tb -jcenter -black ${zpref}.sag.pnm ${zpref}.axi.pnm ${zpref}.cor.pnm           > ${zpref}.pnm
pbmtext -builtin fixed "$jnam"   | pnmcrop | pbmtopgm 1 1 | pnmscale 2                  > ${zpref}.t1.pgm
pbmtext -builtin fixed "<- Left"           | pbmtopgm 1 1                               > ${zpref}.t2.pgm
$pcprog -align=right -valign=bottom ${zpref}.t1.pgm ${zpref}.pnm                        > ${zpref}.t3.pnm
$pcprog -align=right -valign=top    ${zpref}.t2.pgm ${zpref}.t3.pnm | cjpeg -quality 95 > "$jnam.jpg"

# delete the trash data

\rm -f ${zpref}.*

echo "@snapshot_volreg output image = $jnam.jpg"

# stop Xvfb if we started it ourselves

if( $?killX ) kill %1

exit 0
