#!/bin/tcsh -f

# make surface spec files from the surface files
#
# usage @SUMA_Make_Spec_SF [options]
#
# options:  -sid	subject_id	: specify subject ID
#	    -sfpath	SureFit_path : specify path to SureFit files
#      -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_LOOK_FOR_TOPO
     L_LOOK_FOR_TOPO_DONE:

goto L_LOOK_FOR_VOLPARAMS
     L_LOOK_FOR_VOLPARAMS_DONE:

goto L_CREATE_SPEC
     L_CREATE_SPEC_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 = (fiducial		\
			ellipsoid			\
			inflated		\
			)

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"
	echo "See Also @SUMA_Make_Spec_Caret"
   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 sf_dir		= "."
    set subj_id		= ""

    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: -sfpath SUREFIT_PATH
	    case "-sfpath":

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

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

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

	    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 $sf_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 suma )

	(which $test_command) >& /dev/null

	if ( $status ) then
	    echo "Warning: program not found in path: $test_command"
	    #these programs are not necessary
		 #@ 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 surfaces_dir and vol_dir - check cwd and parent

L_SET_SURF_DIRS:

    # find SURFACES directory

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

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

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

	goto L_BAD_END
    endif

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

    if ( $debug ) echo "-- using SURFACES directory '$surfaces_dir'..."

    # vol_dir is the parent directory of SURFACES

    set vol_dir = $surfaces_dir/../
    
    # verify orig dir permissions
    if ( ! -w $vol_dir ) then
	set endstr = "failure: no write permissions for directory '$vol_dir'"
	goto L_BAD_END
    endif

    if ( $debug ) echo "-- using volume directory '$vol_dir'..."

	#set suma_dir to be surfaces_dir
    set suma_dir = $surfaces_dir

    

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]	\
			)
	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 $surfaces_dir

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

	 foreach Side ( 'L' 'R' )
		#get all the surfaces and ask user to identify one to use
		set CHOOSE_LIST = `ls -t *.$Side.*segment*fiducial*.coord`
				echo "Choose final fiducial surface (1st one is most likely since it was created last):"
				#vvvvvvvvvvvvvvvvvvvv   chooser block 
				#This cannot be used inside a loop with a goto statement.  	
					 set CHOOSE_LIST_cnt = 1
					 foreach CHOOSE_LIST_item ( $CHOOSE_LIST )
	 					echo "$CHOOSE_LIST_cnt- $CHOOSE_LIST_item"
						@ CHOOSE_LIST_cnt ++
					 end
					 set CHOOSE_LIST_select = 0
					 while ($CHOOSE_LIST_select > $#CHOOSE_LIST || $CHOOSE_LIST_select < 1)
	 					echo "Enter number of Choice:"
	 					set CHOOSE_LIST_select = $<
					 end
					set CHOSEN_ITEM = $CHOOSE_LIST[$CHOOSE_LIST_select]
					set CHOSEN_ITEM_INDEX = $CHOOSE_LIST_select
				#^^^^^^^^^^^^^^^^^^   chooser block 
				
		set NoExt = $CHOSEN_ITEM:r #remove the .coord extension
		set NodeNumb = $NoExt:e	#extract the number before .coord
		foreach attrib ( $surf_attribs )
			set candidate = `ls *.$Side.*segment*$attrib*$NodeNumb*.coord`
		
			if ($#candidate != 1) then
				echo 'candidate surfaces= '
				echo $candidate
				set endstr = "found 0 or more than one candidate surfaces matching '*."$Side'.*segment*'$attrib'*'$NodeNumb'*.coord'
				goto L_BAD_END
			else 
				if ($Side == 'L') then
					set list_lh = ( $list_lh $candidate )
				else
					set list_rh = ( $list_rh $candidate )
				endif
			endif
   	end
	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 '$surfaces_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

####################################################################
# choose an item from a list files
L_CHOOSE_LIST:

#pass a list in CHOOSE_LIST and a return label in CHOOSE_LIST_RET variables 
#expect CHOSEN_ITEM and CHOSEN_ITEM_INDEX (first item is 1)

	 set CHOOSE_LIST_cnt = 1
	 foreach CHOOSE_LIST_item ( $CHOOSE_LIST )
	 	echo "$CHOOSE_LIST_cnt- $CHOOSE_LIST_item"
		@ CHOOSE_LIST_cnt ++
	 end
	 set CHOOSE_LIST_select = 0
	 while ($CHOOSE_LIST_select > $#CHOOSE_LIST || $CHOOSE_LIST_select < 1)
	 	echo "Enter number of Choice:"
	 	set CHOOSE_LIST_select = $<
	 end

	set CHOSEN_ITEM = $CHOOSE_LIST[$CHOOSE_LIST_select]
	set CHOSEN_ITEM_INDEX = $CHOOSE_LIST_select

goto $CHOOSE_LIST_RET

####################################################################
# find topo files

L_LOOK_FOR_TOPO:
	 cd $surfaces_dir


	foreach Side (L R)
   	set list_topo = "X"	# init to something useless - allows nice empty check
		if ($Side == 'L') then
			set list = ( $list_lh )
		else 
			set list = ( $list_rh )
		endif
		#for each item in list, try to guess the appropriate .topo file
		foreach coord ( $list )
			#remove .coord
			set NoExt = $coord:r
			set NodeNumb = $NoExt:e
			
			set candidate = `ls *.$Side.*segment*$NodeNumb.topo`
			if ($#candidate == 0) then
				set endstr = "found no topo for $coord."
				goto L_BAD_END
    		else
				if ($#candidate > 1) then
					echo "Choose topo file to go with $list file:"
					set CHOOSE_LIST = ( $candidate )
						#vvvvvvvvvvvvvvvvvvvv   chooser block 
							 set CHOOSE_LIST_cnt = 1
							 foreach CHOOSE_LIST_item ( $CHOOSE_LIST )
	 							echo "$CHOOSE_LIST_cnt- $CHOOSE_LIST_item"
								@ CHOOSE_LIST_cnt ++
							 end
							 set CHOOSE_LIST_select = 0
							 while ($CHOOSE_LIST_select > $#CHOOSE_LIST || $CHOOSE_LIST_select < 1)
	 							echo "Enter number of Choice:"
	 							set CHOOSE_LIST_select = $<
							 end
							set CHOSEN_ITEM = $CHOOSE_LIST[$CHOOSE_LIST_select]
							set CHOSEN_ITEM_INDEX = $CHOOSE_LIST_select
						#^^^^^^^^^^^^^^^^^^   chooser block 
					set candidate = $CHOSEN_ITEM
				endif
			endif
			set list_topo = ( $list_topo $candidate )
		end

		if ($Side == 'L') then
			set list_topo_lh = ( $list_topo[2-] )		#Remove the X
			#echo "Topo List side $Side :"
			#echo "$list_topo_lh"
		else 
			set list_topo_rh = ( $list_topo[2-] )
			#echo "Topo List side $Side :"
			#echo "$list_topo_lh"
		endif
	end
   
	cd $start_dir

goto L_LOOK_FOR_TOPO_DONE

####################################################################
# Get the vol param file (and the afni brick used in creating surface)

L_LOOK_FOR_VOLPARAMS:
	cd $vol_dir
	
	foreach Side (L R)
		set candidate = `ls -t *.$Side.*.params`
		if ($#candidate == 0) then
				set endstr = "found no vol params found for $Side side"
				goto L_BAD_END
    	else
			if ($#candidate > 1) then
				echo "Choose .params file used in SureFit to create the surfaces:"
				set CHOOSE_LIST = ( $candidate )
					#vvvvvvvvvvvvvvvvvvvv   chooser block 
						 set CHOOSE_LIST_cnt = 1
						 foreach CHOOSE_LIST_item ( $CHOOSE_LIST )
	 						echo "$CHOOSE_LIST_cnt- $CHOOSE_LIST_item"
							@ CHOOSE_LIST_cnt ++
						 end
						 set CHOOSE_LIST_select = 0
						 while ($CHOOSE_LIST_select > $#CHOOSE_LIST || $CHOOSE_LIST_select < 1)
	 						echo "Enter number of Choice:"
	 						set CHOOSE_LIST_select = $<
						 end
						set CHOSEN_ITEM = $CHOOSE_LIST[$CHOOSE_LIST_select]
						set CHOSEN_ITEM_INDEX = $CHOOSE_LIST_select
					#^^^^^^^^^^^^^^^^^^   chooser block 
				set candidate = $CHOSEN_ITEM
			endif
		endif
		if ($Side == 'L') then
			set Vol_Param_lh = $candidate
		else
			set Vol_Param_rh = $candidate
		endif
	end
	
	# try for afni data set used in creating surface
	set candidate = `ls -t *.HEAD`
	echo $#candidate $candidate
	if ($#candidate == 0) then
				set endstr = "found no afni data sets used in creating surfaces"
				goto L_BAD_END
   else 
		if ($#candidate > 1) then
			echo "Choose AFNI data set used in SureFit to create the surfaces:"
			set CHOOSE_LIST = ( $candidate )
				#vvvvvvvvvvvvvvvvvvvv   chooser block 
					 set CHOOSE_LIST_cnt = 1
					 foreach CHOOSE_LIST_item ( $CHOOSE_LIST )
	 					echo "$CHOOSE_LIST_cnt- $CHOOSE_LIST_item"
						@ CHOOSE_LIST_cnt ++
					 end
					 set CHOOSE_LIST_select = 0
					 while ($CHOOSE_LIST_select > $#CHOOSE_LIST || $CHOOSE_LIST_select < 1)
	 					echo "Enter number of Choice:"
	 					set CHOOSE_LIST_select = $<
					 end
					set CHOSEN_ITEM = $CHOOSE_LIST[$CHOOSE_LIST_select]
					set CHOSEN_ITEM_INDEX = $CHOOSE_LIST_select
				#^^^^^^^^^^^^^^^^^^   chooser block 
			set candidate = $CHOSEN_ITEM
		endif
	endif	
		
		set afni_dataset = $candidate
		
	cd $start_dir

goto L_LOOK_FOR_VOLPARAMS_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
		 set list_topo_cur = ( $list_topo_lh )
		 set Vol_Param = $Vol_Param_lh
	else
	    set list_cur = ( $list_rh )
		 set list_topo_cur = ( $list_topo_rh )
		 set Vol_Param = $Vol_Param_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

	set cnt = 1
	foreach surf ( $list_cur )
	    set NoExt = $surf:r	#remove .coord
		 set NodeNumb = $NoExt:e	#store NodeNumb
		 set NoExt = $NoExt:r	#remove NodeNumb
		 set s_state = $NoExt:e	#store state
		 set s_head = $NoExt:r #store surface header, no state
		 
	    # check for SAME mapping ref
	    if ( "$s_state" == "fiducial" ) then
		set map_ref = SAME
	    else
		set map_ref = $s_head.fiducial.$NodeNumb.coord
	    endif

	    # EmbedDimension is 2 for .flat surfaces, else 3
	    #this is not set for SureFit yet. Must figure out nomenclature
		 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 = SureFit"		>> $spec_file
	    echo "        SureFitCoord = $surf"	>> $spec_file
	    echo "        SureFitTopo = $list_topo_cur[$cnt]" >> $spec_file
		 echo "        SureFitVolParam = ../$Vol_Param"	>> $spec_file
		 echo "        LocalDomainParent = $map_ref"		>> $spec_file
	    echo "        SurfaceState = $s_state"		>> $spec_file
	    echo "        EmbedDimension = $embed_ref"		>> $spec_file
	    echo ""						>> $spec_file
	@ cnt ++
	end

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

    cd $start_dir

goto L_CREATE_SPEC_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 "Use @SUMA_Make_Spec_Caret for caret surfaces"
    echo ""
    echo "    This script goes through the following steps:"
    echo "      - determine the location of surfaces and "
	 echo "        then AFNI volume data sets used to create them."
    echo "      - creation of left and right hemisphere SUMA spec files"
    echo ""
    echo "      - all created files are stored in SURFACES 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 -sfpath subject1/surface_stuff -sid subject1"
    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 "    -sfpath PATH    : path to directory containing 'SURFACES'"
	 echo "                      and AFNI volume used in creating the surfaces."
    echo "          e.g. -sfpath subject1/surface_models"
    echo "          the default PATH value is './', the current directory"
    echo ""
    echo "          This is generally the location of the 'SURFACES' directory,"
    echo "          though having PATH end in SURFACES is OK.  "
    echo ""
    echo "          Note: when this option is provided, all file/path"
    echo "          messages will be with respect to this directory."
    echo ""
    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 the standard names used by SureFit:"
	 echo "       rw_1mmLPI.L.full.segment_vent_corr.fiducial.58064.coord"
	 echo "       Otherwise the script cannot detect them. You will need to decide which"
	 echo "       surface is the most recent (the best) and the script helps you by listing"
	 echo "       the available surfaces with the most recent one first."
	 echo "       This sorting ususally works except when the time stamps on the surface files"
	 echo "       are messed up. In such a case you just need to know which one to use."
	 echo "       Once the fiducial surface is chosen, it's complimentary surfaces are selected"
	 echo "       using the node number in the file name."
    echo "    3. 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