#!/bin/tcsh -f

# make surface spec files from the surface files
#
# usage @SUMA_Make_Spec_FS [options]
#
# options:  -sid	subject_id	: specify subject ID
#	    -fspath	FreeSurfer_path : specify path to FreeSurfer files
#	    -neuro			: use neurological orientation
#           -debug      level		: display extra output
#

#----------------------------------------------------------------------
goto L_INIT_VARS
     L_INIT_VARS_DONE:

goto L_CHECK_USAGE
     L_CHECK_USAGE_DONE:

goto L_PARSE_COMMAND
     L_PARSE_COMMAND_DONE:

goto L_VERIFY_PROGRAMS
     L_VERIFY_PROGRAMS_DONE:

goto L_SET_SURF_DIRS
     L_SET_SURF_DIRS_DONE:

goto L_CHECK_FOR_OVERWRITE
     L_CHECK_FOR_OVERWRITE_DONE:

goto L_LOOK_FOR_SURF
     L_LOOK_FOR_SURF_DONE:

goto L_CONVERT_SURFACES
     L_CONVERT_SURFACES_DONE:

goto L_CREATE_SPEC
     L_CREATE_SPEC_DONE:

goto L_CREATE_BRICK
     L_CREATE_BRICK_DONE:

goto L_TEST_SURF_VOL
     L_TEST_SURF_VOL_DONE:

goto L_GOOD_END	# finished, woohooo!


####################################################################
# variable initialization

L_INIT_VARS:

    set prog_name = $0:t
    set endstr = "$prog_name ... finished"
    set debug     = 0

    set surf_attribs = (smoothwm		\
			pial			\
			inflated		\
			occip.patch.3d		\
			occip.patch.flat	\
			full.patch.3d		\
			full.patch.flat	\
			sphere			\
         white          \
         sphere.reg     \
			)

goto L_INIT_VARS_DONE


####################################################################
# check usage, and possibly print help

L_CHECK_USAGE:

    if ( $#argv == 0 ) then
	echo "usage: $prog_name [options] -sid SUBJECT_ID"
	echo "usage: $prog_name -help"
	set endstr = ""
	goto L_GOOD_END
    endif

goto L_CHECK_USAGE_DONE


####################################################################
# parse the command line

L_PARSE_COMMAND:

    # init command line arg values

    set fs_dir		= "."
    set subj_id		= ""
    set neuro_ori	= 0

    set args     = $#argv
    set count    = 1

    while ( $count <= $args )
	switch ( "$argv[$count]" )

	    # ----------------------------------------------------------
	    # usage: -help
	    case "-h":
	    case "-help":

		goto L_HELP_END		# and don't ya' come back, neither

	    breaksw

	    # ----------------------------------------------------------
	    # usage: -sid SUBJECT_ID
	    case "-sid":

		if ( $count >= $args ) then
		    set endstr = "arg usage: -sid SUBJECT_ID"
		    goto L_BAD_END
		endif

		@ count ++
		set subj_id  = $argv[$count]

	    breaksw

	    # ----------------------------------------------------------
	    # usage: -fspath FREESURFER_PATH
	    case "-fspath":

		if ( $count >= $args ) then
		    set endstr = "arg usage: -fspath FREESURFER_PATH"
		    goto L_BAD_END
		endif

		@ count ++
		set fs_dir  = $argv[$count]

		if ( ! -d $fs_dir ) then
		    set endstr = "failure: directory not found - '$fs_dir'"
		    goto L_BAD_END
		endif

	    breaksw

	    # ----------------------------------------------------------
	    # usage : -neuro
	    case "-neuro":

		set neuro_ori = 1

	    breaksw

	    # ----------------------------------------------------------
	    # usage : -debug DEBUG_LEVEL
	    case "-debug":

		if ( $count >= $args ) then
		    set endstr = "arg usage: -debug DEBUG_LEVEL"
		    goto L_BAD_END
		endif

		@ count ++
		set debug = $argv[$count]

		if ( "$debug" > 2 ) set debug = 2
		if ( "$debug" < 0 ) set debug = 0

	    breaksw

	    # ----------------------------------------------------------
	    # bad argument
	    default:

		set endstr = "invalid option: '$argv[$count]'"
		goto L_BAD_END

	    breaksw
	endsw

	@ count ++
    end

    if ( $subj_id == "" ) then
	set endstr = "missing required option: -sid"
	goto L_BAD_END
    endif

    if ( $debug ) echo "-- usage okay"
    if ( $debug > 1 ) set echo

    set spec_files   = ({$subj_id}_lh.spec {$subj_id}_rh.spec )
    set afni_prefix  = ${subj_id}_SurfVol
    set afni_dataset = $afni_prefix+orig

    # set and go to the base directory
    cd $fs_dir
    set start_dir = $cwd

    if ( $debug ) echo "-- using start_dir '$start_dir'"

goto L_PARSE_COMMAND_DONE


####################################################################
# make sure programs exist

L_VERIFY_PROGRAMS:

    set failed_pgms = 0
    foreach test_command ( afni to3d suma mris_convert )

	(which $test_command) >& /dev/null

	if ( $status ) then
	    echo "program not found in path: $test_command"
	    @ failed_pgms ++
	endif
    end

    if ( $failed_pgms ) then
	set endstr = "$failed_pgms program(s) not found"
	goto L_BAD_END
    endif

    if ( $debug ) echo "-- all programs found"

goto L_VERIFY_PROGRAMS_DONE


####################################################################
# 1. set surf_dir and orig_dir - check cwd and parent
# 2. create SUMA directory at the same level as surf_dir and store the results there

L_SET_SURF_DIRS:

    # find surf directory

    if ( -d surf ) then
	set surf_dir = ./surf
    else if ( $cwd:t == surf ) then
	set surf_dir = .
    else if ( -d ../surf ) then
	set surf_dir = ../surf
    else
	# this is a general failure case, even if we find one
	set surf_dirs = ( `find . -maxdepth 4 -type d -name surf -print` )
	
	if ( $#surf_dirs == 0 ) then
	    echo "failure: cannot find directory 'surf' under '$fs_dir'"
	    echo "(subject to a maximum search depth of 4 subdirectories)"

	    set endstr = ""
	else if ( $#surf_dirs == 1 ) then
	    echo "surf directory found at '$surf_dirs[1]'"
	    set endstr = "consider running program from '$surf_dirs[1]:h'"
	else
	    echo "multiple surf directories found:"
	    set count = 1
	    while ( $count <= $#surf_dirs )
		echo "     $surf_dirs[$count]"
		@ count ++
	    end

	    set endstr = ( "consider running program from one of the" \
			   "surf directories" )
	endif

	goto L_BAD_END
    endif

    # verify surf dir permissions
    if ( ! -w $surf_dir ) then
	set endstr = "failure: no write permissions for directory '$surf_dir'"
	goto L_BAD_END
    endif

    if ( $debug ) echo "-- using surf directory '$surf_dir'..."

    # now check for orig dir

    set orig_dir = ""
    foreach test_dir (  $surf_dir/orig		\
			$surf_dir/mri/orig	\
			orig			\
			mri/orig		\
			../orig			\
			../mri/orig )
	if ( -d $test_dir ) then
	    set orig_dir = $test_dir
	    break
	endif
    end

    set orig_mgz = ""
    foreach test_mgz (  $surf_dir/orig.mgz		\
			$surf_dir/mri/orig.mgz	\
			orig.mgz			\
			mri/orig.mgz		\
			../orig.mgz			\
			../mri/orig.mgz )
	if ( -f $test_mgz ) then
	    set orig_mgz = $test_mgz
	    break
	endif
    end
    
    if ( $orig_dir == "" && $orig_mgz == "") then
	set endstr = "failure: cannot find directory 'orig' or file 'orig.mgz' under $fs_dir"
	goto L_BAD_END
    endif

    if ( $orig_dir == "" ) then
   set endstr = "failure: script expects an 'orig' directory even if it is empty."
   goto L_BAD_END 
    endif
    
    # verify orig dir permissions
    if ( ! -w $orig_dir ) then
	set endstr = "failure: no write permissions for directory '$orig_dir'"
	goto L_BAD_END
    endif

    if ( $debug ) echo "-- using orig directory '$orig_dir'..."

    # decide whether we need to make surf/SUMA directory

    set suma_dir = ./SUMA

    if ( -d $suma_dir ) then
	if ( $debug ) echo "-- $suma_dir already exists, continuing..."
    else
	echo "++ creating directory '$suma_dir' for results..."
	mkdir $suma_dir
	if ( $status ) then
	    set endstr = "failure: cannot create directory '$suma_dir'"
	    goto L_BAD_END
	endif
    endif

goto L_SET_SURF_DIRS_DONE


####################################################################
# verify non-existence of spec files and AFNI files

L_CHECK_FOR_OVERWRITE:

    set test_failures = 0

    foreach test_file (	$suma_dir/$spec_files[1]	\
			$suma_dir/$spec_files[2]	\
			$suma_dir/$afni_dataset.HEAD	\
			$suma_dir/$afni_dataset.BRIK	\
			$orig_dir/$afni_dataset.HEAD	\
			$orig_dir/$afni_dataset.BRIK		)
	if ( -f $test_file ) then
	    if ( $test_failures == 0 ) then
		echo "failure: will not overwrite files: "
		set test_failures = 1
	    endif

	    echo "        '$test_file'"
	endif
    end

    if ( $test_failures ) then
        set endstr = "please remove these files if you want to rerun the script."
	goto L_BAD_END
    endif

goto L_CHECK_FOR_OVERWRITE_DONE

####################################################################
# find surface files

L_LOOK_FOR_SURF:

    cd $surf_dir

    set list_lh = "X"	# init to something useless - allows nice empty check
    set list_rh = "X"

    foreach attrib ( $surf_attribs )
	if ( -f lh.$attrib ) set list_lh = ( $list_lh lh.$attrib )
	if ( -f rh.$attrib ) set list_rh = ( $list_rh rh.$attrib )
    end

    set list_lh = ( $list_lh[2-] )	# now remove the leading "X"
    set list_rh = ( $list_rh[2-] )

    if ( $#list_lh == 0 && $#list_rh == 0 ) then
	set endstr = "found no LH or RH surface files under '$surf_dir'"
	goto L_BAD_END
    endif

    if ( $#list_lh > 0 ) then
	echo "-- found $#list_lh LH surfaces"
	if ( $debug ) echo "    --" $list_lh
    endif

    if ( $#list_rh > 0 ) then
	echo "-- found $#list_rh RH surfaces"
	if ( $debug ) echo "    --" $list_rh
    endif

    cd $start_dir

goto L_LOOK_FOR_SURF_DONE


####################################################################
# convert to ascii via mris_convert (found earlier)

L_CONVERT_SURFACES:

    cd $surf_dir
    foreach surf ( $list_lh $list_rh )
	# run mris_convert and verify
	if ( $surf =~ *patch* ) then
	    echo  "-- running 'mris_convert -p $surf $surf.asc'"
	    mris_convert -p $surf $surf.asc
	else
	    echo "-- running 'mris_convert $surf $surf.asc'"
	    mris_convert $surf $surf.asc
	endif

	if ( ! -f $surf.asc ) then
	    echo "failure: could not create surface $surf.asc"

	    if ( ! -w . ) then
		set endstr = "--> no write permissions in this directory"
	    else
		set endstr = "--> is your FreeSurfer license installed?"
	    endif

	    goto L_BAD_END
	endif

	if ( $debug ) then
	    echo "++ $surf.asc created"
	    if ( -f $start_dir/$suma_dir/$surf.asc ) then
		echo "++ overwriting '$suma_dir/$surf.asc'"
	    endif
	endif

	\mv -f $surf.asc $start_dir/$suma_dir	# how barbaric!

	if ( $status ) then
	    set endstr = ( "failure: cannot write"	\
			   "'$suma_dir/$surf.asc'" )
	    goto L_BAD_END
	endif
    end

    cd $start_dir

goto L_CONVERT_SURFACES_DONE


####################################################################
# actually create the spec file

L_CREATE_SPEC:

    cd $suma_dir

    foreach hand ( lh rh )
 	if ( $hand == lh ) then
	    set list_cur = ( $list_lh )		# get a current list copy
	else
	    set list_cur = ( $list_rh )
	endif

	set spec_file = {$subj_id}_$hand.spec

	if ( $debug ) echo "++ creating spec file '$spec_file'..."

	(echo "# delimits comments" > $spec_file) >& /dev/null

	if ( $status ) then
	    set endstr = ( "failure: no permissions to create spec file" \
			 "'$suma_dir/$spec_file'" )
	    goto L_BAD_END
	endif

	# note user, date, machine, pwd, command line
	echo ""							>> $spec_file
	echo "# Creation information:"				>> $spec_file
	echo "#     user    : $user"				>> $spec_file
	echo "#     date    : `date`"				>> $spec_file
	echo "#     machine : `uname -n`"			>> $spec_file
	echo "#     pwd     : $cwd"				>> $spec_file
	echo "#     command : $prog_name $argv"			>> $spec_file
	echo ""							>> $spec_file
	
	# define the group
	echo "# define the group"				>> $spec_file
	echo "        Group = $subj_id"				>> $spec_file
	echo ""							>> $spec_file

	# define the states
	echo "# define various States"				>> $spec_file
	foreach attrib ( $surf_attribs )
	    echo "        StateDef = $attrib"			>> $spec_file
	end
	echo ""							>> $spec_file

	foreach surf ( $list_cur )
	    set s_head = `echo $surf | cut -d. -f1`	# up to first '.'
	    set s_state = `echo $surf | cut -d. -f2-`	# after first '.'

	    # check for SAME mapping ref
	    if ( "$surf.asc" == "$s_head.smoothwm.asc" ) then
		set map_ref = SAME
	    else
		set map_ref = $s_head.smoothwm.asc
	    endif

	    # EmbedDimension is 2 for .flat surfaces, else 3
	    if ( $surf =~ *.flat* ) then
		set embed_ref = 2
	    else
		set embed_ref = 3
	    endif

	    echo "NewSurface"					>> $spec_file
	    echo "        SurfaceFormat = ASCII"		>> $spec_file
	    echo "        SurfaceType = FreeSurfer"		>> $spec_file
	    echo "        FreeSurferSurface = $surf.asc"	>> $spec_file
	    echo "        LocalDomainParent = $map_ref"		>> $spec_file
	    echo "        SurfaceState = $s_state"		>> $spec_file
	    echo "        EmbedDimension = $embed_ref"		>> $spec_file
	    echo ""						>> $spec_file
	end

	echo "++ created spec file'$suma_dir/$spec_file'"
    end 	# foreach hand

    cd $start_dir

goto L_CREATE_SPEC_DONE


####################################################################
# actually create an AFNI dataset

L_CREATE_BRICK:

    cd $orig_dir
    # verify existence of 256 COR files, Checking for 256 is now obsolete ZSS Oct 14 04
    set cor_files = ( `echo COR-???` ) >& /dev/null 
    
    if ( $status) then
      if ($orig_mgz != "") then   
         #Try the orig.mgz business
         echo "No COR files, converting $orig_mgz ..."
         cd $start_dir
         mri_convert -ot cor $orig_mgz $orig_dir
         cd $orig_dir
      else 
         set endstr = "failure: No COR files and no $orig.mgz"
         goto L_BAD_END
      endif
    else
      if ($orig_mgz != "") then  
         echo ""
         echo "Warning: Found COR files and $orig_mgz"
         echo "******** Will use COR files."
         echo ""
      endif
    endif
   
   #check again
   set cor_files = ( `echo COR-???` ) >& /dev/null 
    if ( $status ) then
	set endstr = "failure: did not find COR files under '$orig_dir'"
	goto L_BAD_END
    #else if ( $#cor_files != 256 ) then
	#set endstr = "failure: 256 COR files required under '$orig_dir'"
	#goto L_BAD_END
    endif

    # create BRIK with to3d

    #SLAB changed by ZSS Mar 12 04. was 0.5 mm off. Bug pointed
    #out by A. Thomas. Good info found here:
    #www.wideman-one.com/gw/brain/fs/coords/fscoords.htm
    
      #New block added for reading COR images that are no longer 256x256x256 / 1mm cubic voxels ZSS Oct 20 04
      
      set Sr = `grep -w imnr0 COR-.info`
      set i0 = $Sr[$#Sr]
      set Sr = `grep -w imnr1 COR-.info`
      set i1 = $Sr[$#Sr]
      set Sr = `grep -w fov COR-.info`
      set FOV = `ccalc -eval $Sr[$#Sr] \* 1000`
      set Sr = `grep -w x COR-.info | grep -v xform`
      set nx = $Sr[$#Sr]
      set Sr = `grep -w y COR-.info`
      set ny = $Sr[$#Sr]
      set Sr = `grep -w thick COR-.info`
      set zthick = `ccalc -eval $Sr[$#Sr] \* 1000`
      set Sr = `grep -w psiz COR-.info`
      set psize = `ccalc -eval $Sr[$#Sr] \* 1000`

      set xSLAB0 = `ccalc -eval $nx \* $psize / 2`
      set xSLAB1 = `ccalc -eval $xSLAB0 - $psize`
      set ySLAB0 = `ccalc -eval $ny \* $psize / 2`
      set ySLAB1 = `ccalc -eval $ySLAB0 - $psize`
      set zSLAB0 = `ccalc -eval '('$i1 - $i0 + 1')' \* $zthick / 2`
      set zSLAB1 = `ccalc -eval $zSLAB0 - $zthick`

      if (0) then
         echo "COR-.info:"
         echo "i0,i1 = $i0, $i1, FOV = $FOV"
         echo "nx,ny = $nx, $ny"
         echo "pdim = $psize mm, thick = $zthick mm"
         echo "SLABS: $xSLAB0..$xSLAB1, $ySLAB0..$ySLAB1, $zSLAB0..$zSLAB1"
         if ( $neuro_ori == 1 ) then
            echo "to3d -xSLAB $xSLAB0'L'-$xSLAB1'R' -ySLAB $ySLAB0'S'-$ySLAB1'I' \
                     -zSLAB $zSLAB0'P'-$zSLAB1'A' '3Db:0:0:'$nx':'$ny':1:COR-???'"
         else 
            echo "to3d -xSLAB $xSLAB0'R'-$xSLAB1'L' -ySLAB $ySLAB0'S'-$ySLAB1'I' \
                     -zSLAB $zSLAB0'P'-$zSLAB1'A' '3Db:0:0:'$nx':'$ny':1:COR-???'"
         endif
      endif
    
    if ( $neuro_ori == 1 ) then
      to3d -prefix $afni_prefix -xSLAB $xSLAB0'L'-$xSLAB1'R' -ySLAB $ySLAB0'S'-$ySLAB1'I' -zSLAB $zSLAB0'P'-$zSLAB1'A' '3Db:0:0:'$nx':'$ny':1:COR-???'
	   #to3d -prefix $afni_prefix -xSLAB 127L-128R -ySLAB 128S-127I \
	   #  -zSLAB 128P-127A $cor_files
    else
	   to3d -prefix $afni_prefix -xSLAB $xSLAB0'R'-$xSLAB1'L' -ySLAB $ySLAB0'S'-$ySLAB1'I' -zSLAB $zSLAB0'P'-$zSLAB1'A' '3Db:0:0:'$nx':'$ny':1:COR-???'
      #to3d -prefix $afni_prefix -xSLAB 128R-127L -ySLAB 128S-127I \
	   #  -zSLAB 128P-127A $cor_files
    endif

    mv $afni_dataset.HEAD $afni_dataset.BRIK* $start_dir/$suma_dir

    echo "++ created AFNI file '$suma_dir/$afni_dataset.HEAD'"
    echo "++ created AFNI file '$suma_dir/$afni_dataset.BRIK'"

    cd $start_dir

goto L_CREATE_BRICK_DONE


####################################################################
# echo details for the user to launch suma and afni, in order to
# check the alignment

L_TEST_SURF_VOL:

    echo ""
    echo "------------------------------------------------------------------"
    echo "Please verify that the datasets are aligned properly in both"
    echo "afni and suma.  You may do this by running the following commands:"
    echo ""
    echo "    cd $suma_dir"
    echo "    afni -niml &"
    echo "    suma -spec $spec_file -sv $afni_dataset"

goto L_TEST_SURF_VOL_DONE


####################################################################
# display help and exit

L_HELP_END:

    echo ""
    echo "$prog_name - prepare for surface viewing in SUMA"
    echo ""
    echo "    This script goes through the following steps:"
    echo "      - verify existence of necessary programs "
    echo "        (afni, to3d, suma, mris_convert)"
    echo "      - determine the location of surface and COR files"
    echo "      - creation of ascii surface files via 'mris_convert'"
    echo "      - creation of left and right hemisphere SUMA spec files"
    echo "      - creation of an AFNI dataset from the COR files via 'to3d'"
    echo ""
    echo "      - all created files are stored in a new SUMA directory"
    echo ""
    echo "  Usage: $prog_name [options] -sid SUBJECT_ID"
    echo ""
    echo "  examples:"
    echo ""
    echo "    $prog_name -sid subject1"
    echo "    $prog_name -help"
    echo "    $prog_name -fspath subject1/surface_stuff -sid subject1"
    echo "    $prog_name -neuro -sid 3.14159265 -debug 1"
    echo ""
    echo "  options:"
    echo ""
    echo "    -help    : show this help information"
    echo ""
    echo "    -debug LEVEL    : print debug information along the way"
    echo "          e.g. -debug 1"
    echo "          the default level is 0, max is 2"
    echo ""
    echo "    -fspath PATH    : path to 'surf' and 'orig' directories"
    echo "          e.g. -fspath subject1/surface_info"
    echo "          the default PATH value is './', the current directory"
    echo ""
    echo "          This is generally the location of the 'surf' directory,"
    echo "          though having PATH end in surf is OK.  The mri/orig"
    echo "          directory should also be located here."
    echo ""
    echo "          Note: when this option is provided, all file/path"
    echo "          messages will be with respect to this directory."
    echo ""
    echo "    -neuro          : use neurological orientation"
    echo "          e.g. -neuro"
    echo "          the default is radiological orientation"
    echo ""
    echo "          In the default radiological orientation, the subject's"
    echo "          right is on the left side of the image.  In the"
    echo "          neurological orientation, left is really left."
    echo ""
    echo "    -sid SUBJECT_ID : required subject ID for file naming"
    echo ""
    echo ""
    echo "  notes:"
    echo ""
    echo "    0. More help may be found at http://afni.nimh.nih.gov/ssc/ziad/SUMA/SUMA_doc.htm"
    echo "    1. Surface file names should look like 'lh.smoothwm'."
    echo "    2. Patches of surfaces need the word patch in their name, in"
    echo "       order to use the correct option for 'mris_convert'."
    echo "    3. Flat surfaces must have .flat in their name."
    echo "    4. You can tailor the script to your needs. Just make sure you rename it or risk"
	 echo "       having your modifications overwritten with the next SUMA version you install."
	 echo ""
    echo "     R. Reynolds (rickr@codon.nih.gov), Z. Saad (ziad@nih.gov)"
    echo ""

    exit


####################################################################
# failure!

L_BAD_END:

    echo ""
    if ( "$endstr" != "" ) echo "$endstr"
    echo program failure: exiting...
    echo ""

    exit

####################################################################
# finished!

L_GOOD_END:

    if ( $debug > 1 ) unset echo

    echo ""
    if ( "$endstr" != "" ) then
	echo "$endstr"
	echo ""
    endif

    exit	# just to be consistent



syntax highlighted by Code2HTML, v. 0.9.1