#! /bin/csh -f
#
echo "Processer Elves 1.3  Automatic, MAD multi-processing 	James Holton 5-12-06"
echo ""
#
#
#	This script will run through all set-up wedges of data and run 
#	a Wedger command in each, first to process each wedge
#	individually, and then again to impose the average unit cell
#	on all wedges.  
#
#	Several copies of this script can be run side-by-side, or even
#	on separate computers.  They will avoid simultaneously processing
#	the same wedge, and "leapfrog" over each other until all the wedges
#	are done.
#
#
# set up awk
alias nawk /bin/awk
nawk 'BEGIN{print 1; exit}' >& /dev/null
if($status) alias nawk awk

# set up internal environment
if(-e `pwd`"/Elfsheim") setenv PATH `pwd`"/Elfsheim:$PATH"

if($#argv == 0) then
    cat << EOF-Help

usage: $0 stage hurry SGs */wedge*

where:
stage      - the stage of data analysis you want to perform.
		one of: 
    initialize - start over with */*/start files
    mosflm     - process data with mosflm [default]
    solve      - advance to heavy-atom finding
hurry	   - rush through processing [default: no hurry]
SGs	   - space groups you want to try [default: all]
*/wedge*   - wedge directories you want to process [default: */wedge*]

other options:
new	   - erase all records of previous/current runs 
		(careful! make sure no other Processers are running! )
local	   - only process frames on local file systems
no solve   - quit after scaling (don't run heavy-atom finding programs)
no ./dir   - do not run mosflm in the ./dir directory

EOF-Help
endif
################################################################################

# project-dependent variables
set wedge_dirs = ""		# wedges to process (if empty: scans command line and directory)
set image_dir = "."             # "backup" directory for missing frames
set timeout = 24                # max hours to wait for other instances to finish

# program flags
set REFIND_IMAGES = sometimes	# only look for images if directory is missing too
#set REFIND_IMAGES = always	# look for all missing images
#set LOCAL			# only process frames on local filesystems
set NICE			# nice all processing jobs
#set HURRY_UP			# fast, (reckless) route to stats and Pattersons
#set STAGE = indexing		# Wedger is figuring out the point group
#set STAGE = restarting		# reset parameters from "./start" files
set STAGE = testing		# quick check to make sure each wedge works
#set STAGE = refining		# using "long" Wedger runs on all wedges
#set STAGE = polishing		# reprocessing with fixed, average cell
#set STAGE = scaling		# localscale and merge whatever raw data are available
#set STAGE = solve		# done with measurment, running solve/shelx
#set STAGE = warp		# run ARP/wARP on the available MR/MAD results
set GLOBALS = ""		# stuff listed after "STAGE" in busyfile
#set ALONE			# act as though there are no other instances
set machine = `hostname -s`	# for printing
set myname  = `basename $0`	# for printing
set tempfile = ./deleteme_${machine}_$$	# name of temporary file (should be unique to process)
set sitefile
set busyfile = "busy"		# name of "busy signal" file (change if you have a conflict)
set donefile = "done"		# name of "done signal" file (change if you have a conflict)
# busyfile format: "$pwd  ($image)  $$ $machine $STAGE $GLOBALS"
#
set not_these = ""
set root_dir = `pwd`
set SGs    = ""			# default to all available
set USER_hires = ""		# force Wedger runs to use this
set sites  = ""			# if not already set up on disk
set SOLC   = ""			# list of solvent contents (eg: "40% 45%")
set CELL   = ""                 # set only if you're sure you know it
set MOSAIC = ""                 # same here
set search_models = ""		# molecular replacement search model(s)
#
#
goto Setup
# scan command line for changes to the above options
Return_From_Setup:

# make it easier to connect log files with processes
echo "this $myname running as pid=$$ on $machine"
echo -n "in $root_dir on "
date
#if("$wedge_dirs" == "") then
#    echo "nothing to do! "
#    goto cleanup
#endif

# clean house if we are the first job
if(($?ALONE)||($?CLEAN)) then
    # clear out crap from any other runs
    foreach wedge_dir ( $wedge_dirs )
	rm -f ${wedge_dir}/$busyfile ${wedge_dir}/$donefile >& /dev/null
	rm -f ${wedge_dir}/logs/Wedger.log >& /dev/null
    end
    rm -f ./$busyfile ./$donefile >& /dev/null
endif

# describe supposed other jobs now
find . -name $busyfile -print |& nawk 'NF==1' |\
nawk 'BEGIN{FS="/"} NF>2' |\
nawk '{file=$1; getline < file; print $0, file; close(file)}' |\
cat >! ${tempfile}busyfiles
find . -name $donefile -print |& nawk 'NF==1' |\
nawk 'BEGIN{FS="/"} NF>2' |\
nawk '{file=$1; getline < file; print $0, file; close(file)}' |\
cat >! ${tempfile}donefiles

# check veracity of these files
cat ${tempfile}busyfiles |\
nawk -v machine=$machine '$4==machine{print substr($3,match($3,"[0-9]")), $NF}' |\
nawk '{pid=$1; file=$2; cmd = "ps -p "pid" | tail -1"; cmd | getline; \
 if($1!=pid){print "rm -f", file}; close(cmd)}' |\
tee ${tempfile}bogus | nawk '{print "deleting", $3, "(that job is no longer running)"}'
# remove outdated signal files
source ${tempfile}bogus >& /dev/null

# check remote jobs too?

set temp = `cat ${tempfile}bogus | wc -l`
rm -f ${tempfile}bogus >& /dev/null
if($temp != 0) then
    # re-find signal files
    find . -name $busyfile -print |& nawk 'NF==1' |\
    nawk 'BEGIN{FS="/"} NF>2' |\
    nawk '{file=$1; getline < file; print $0, file; close(file)}' |\
    cat >! ${tempfile}busyfiles
    find . -name $donefile -print |& nawk 'NF==1' |\
    nawk 'BEGIN{FS="/"} NF>2' |\
    nawk '{file=$1; getline < file; print $0, file; close(file)}' |\
    cat >! ${tempfile}donefiles
endif

# report what we think other jobs are doing
cat ${tempfile}donefiles |\
nawk -v myname=$myname '$4!=""{print "another "myname": pid=" $3, "on", $4, "processed", $1, $2;}'
cat ${tempfile}busyfiles |\
nawk -v myname=$myname '$4!=""{print "another "myname": pid=" $3, "on", $4, "is processing", $1, $2;}'


# read (and adopt) the stage these other Processers are at
set temp = `cat ${tempfile}donefiles ${tempfile}busyfiles | wc -l`
if(($temp > 0)&&(! $?USER_STAGE)&&(! $?CLEAN)) then
    cat ${tempfile}donefiles ${tempfile}busyfiles |\
    nawk 'NF>=5{++count[$5]} END{for(state in count) print count[state], state}' |\
    sort -n | head -1 >! ${tempfile}stage
    set temp = `nawk '{print $NF}' ${tempfile}stage`
    rm -f ${tempfile}stage >& /dev/null
    if("$temp" != "") then
	if("$temp" == "indexing")   set STAGE = "$temp"
	if("$temp" == "restarting") set STAGE = "$temp"
	if("$temp" == "testing")    set STAGE = "$temp"
	if("$temp" == "refining")   set STAGE = "$temp"
	if("$temp" == "polishing")  set STAGE = "$temp"
	if("$temp" == "shelx")      set STAGE = "solve"
	if("$temp" == "solve")      set STAGE = "solve"
	if("$temp" == "phaser")     set STAGE = "phaser"
	if("$temp" == "Phaser")     set STAGE = "phaser"
	if("$temp" == "warp")       set STAGE = "warp"
	echo "proceeding to $STAGE stage."
    endif
endif
rm -f ${tempfile}donefiles >& /dev/null

if("$STAGE" == "indexing") then
    # we should wait for the other guy to finish
    set indexing
    set wedge_dir = `awk '/indexing/{print $1}' ${tempfile}busyfiles`
    rm -f ${tempfile}busyfiles >& /dev/null

    if(-e "${wedge_dir}/$busyfile") then
	# explain the wait
	cat "${wedge_dir}/$busyfile" |\
	nawk '{printf "waiting for %s on %s to finish %s %s\n", $3, $4, $5, $1}'
	
	# wait $timeout hours for signal that processing is done
	set waiting = `echo "$timeout" | nawk '{printf "%d", 360*$1}'`
	unset done
	while(($waiting)&&(! $?done))
	    # wait 10 seconds
	    sleep 10
	    
	    grep "$STAGE" ${wedge_dir}/$busyfile >& /dev/null
	    if($status) then
		# busy signal is now missing
		set done
		
		# will anyone miss this? 
		#rm -f ${wedge_dir}/$donefile >& /dev/null
	    endif

	    @ waiting = ( $waiting - 1 )
	end
	
	# check to see if we timed out
	if(! $?done) then
	    echo "waited $timeout hours! "
	    echo -n "giving up waiting for "
	    if(-e "${wedge_dir}/$busyfile") then
		nawk '{printf "%s on %s to finish ", $3, $4}' "${wedge_dir}/$busyfile"
	    endif
	    echo "$wedge_dir"
	    rm -f "${wedge_dir}/$busyfile" >& /dev/null
	endif
    endif
    # re-evaluate where we are
    set STAGE = testing
    goto Return_From_Setup
endif
rm -f ${tempfile}busyfiles >& /dev/null

if("$STAGE" == "polishing") then
    # we can't do polishing without a CELL and MOSAIC to fix
    if(("$CELL" == "")||("$MOSAIC" == "")) then
	# we need to obtain a CELL and MOSAIC in the usual way
	# pretend we just finished "refining"
	set STAGE = "refining"
	goto Branch
    endif
endif


# check for orientation solution(s)
set mats = `ls -1 $wedge_dirs | nawk '/.mat$/' | wc -l`
if(("$STAGE" == "scaling")||("$STAGE" == "solve")||("$STAGE" == "warp")||("$STAGE" == "phaser")) set mats = 1
#if("$STAGE" == "restarting") set mats = 0

if(! $mats) then
    # look for orientation in standard place
    set mats = `ls -1 ./index | nawk '/.mat$/' | wc -l`
    if(! $mats) then
	# no orientation solutions anywhere!
	echo "no crystal orientation information found! "
	test -t 1
	if($status) then
	    # we're screwed
	    echo "please index one of your wedges with Wedger Elves:"
	    which Wedger
	    goto cleanup
	else
	    # start Wedger
	    cd index
	    onintr Report
	    Wedger ./start -new index ../wedges.txt
	    cd ..
	endif
    endif
endif


Report:
onintr
cd $root_dir
################################################################################
echo "ready to process:"

if(("$STAGE" != "solve")&&("$STAGE" != "scaling")) then
    echo "$wedge_dirs" | nawk 'BEGIN{RS=" "; ORS="\n"} {print $1}' | nawk 'NF==1'
    echo ""
endif

if($?HURRY_UP) echo "(as quickly as possible)"

if("$STAGE" == "scaling")  echo "scaling of all data."

if($?NICE) then
    echo "using "\"nice\"" cpu priority"
endif

if($?LOCAL) echo "only local image files will be processed"
if("$STAGE" == "restarting") echo "re-starting from scratch (./start files)"

if(($?NO_SOLVE)||("$search_models" != "")) then
    echo "heavy-atom finding programs will not be run."
    #if("$STAGE" == "solve") goto cleanup
endif

if("$search_models" != "") then
    # doing molecular replacement
    echo "epmr will be run with $#search_models search models"
endif

# preview of short cuts
if("$STAGE" == "solve") then
    # user requested solve-only run

    ls ./SHELX/*.hkl >& /dev/null
    if(! $status) then
        # SHELX data is already set up
        echo "shelx will be run in each space group"
    endif

    ls ./SOLVE/*.fmt >& /dev/null
    if($status) then
	# need to do scaling
        echo "scaling will be done first"
    endif
endif



# checkpoint
checkpoint:



if($?NICE) then
    # be nice :)
    renice 40 $$ >& /dev/null
    if($status) renice -n 40 $$ >& /dev/null
endif

if("$STAGE" == "scaling") goto scale
if("$STAGE" == "phaser") goto setup_SGs

# short cut
if("$STAGE" == "solve") then
    # user requested solve-only run

    if((-e ./mtz/all.mtz)&&("$search_models" != "")) then
        # EPMR data is already set up
        goto setup_SGs
    endif

    ls ./SHELX/*.hkl >& /dev/null
    if(! $status) then
        # SHELX data is already set up
        goto setup_SGs
    endif

    ls ./SOLVE/*.fmt >& /dev/null
    if(! $status) then
	# SOLVE data is already set up
	goto setup_SGs 
    endif

    if(-e ./mtz/all.mtz) then
	# Phaser data is already set up
	goto setup_SGs
    endif

    # need to do scaling
    goto scale
endif

# need to do SG set-up before we can run wARP
if("$STAGE" == "warp") goto setup_SGs


again:
####################################################################################
# remove "busy" file if we get killed
onintr cleanup   
# assume we'll fix any problems that happened last time
unset PROBLEMS
# make sure this is a multiword variable
set GLOBALS = ( $GLOBALS )

# go through all wedges of data and measure spots
foreach wedge_dir ( $wedge_dirs )
    # $root_dir is where we were launched
    cd "$root_dir"
    
    # $wedge_dir is (usually) relative to $root_dir
    if(-e "$wedge_dir") then
	cd "$wedge_dir"
	set pwd = `pwd`
	set pwd = "./${wedge_dir}"

	set temp = `pwd`
        set wedge = `basename "$temp" | nawk '{print substr($1, 6)+0}'`
        set temp  = `dirname "$temp"`
        set wave  = `basename "$temp"`
	if((-e ../../wedges.txt) && ("$wedge" != "0")) then
	    set wedge_line = `nawk -v wave=$wave -v wedge=$wedge '$1==wave{--wedge} wedge==0{print;exit}' ../../wedges.txt`
	    if($#wedge_line < 9) unset wedge_line
	endif

	# check to see if processing is possible
	set mostrecent = `ls -1rt ./start ./mosflm.com ../../wedges.txt |& tail -1`
	if("$mostrecent" == "../../wedges.txt") then
	    # update from just-modified parent file
	    
	    # re-extract the wedge data
	    touch ./start
	    nawk -v wave=$wave '$1==wave' ../../wedges.txt |\
	    nawk -v wedge=$wedge 'NR==wedge' |\
	    nawk '$3 !~ /[\/]/{exit}\
	          {print "IMAGE", $3; n=split($3,w,"."); \
		         first=substr(w[n-1], length(w[n-1])-2)+0} \
		  first!=0 && $4+0>0 {\
		    printf "PROCESS %d TO %d ", first, first+$4-1; \
		    if($5!="-" && $6+0>0) printf "START %s ANGLE %s", $5, $6;\
		    print ""}\
	          $2+0>3000{print "WAVE", 12398.4245/$2} \
	          $7+0>0{print "DIST", $7} \
	          $8~/[0-9.]/ && $9~/[0-9.]/{print "BEAM", $8, $9} \
	          $10+0>0{print "TWOTHETA", $10}' |\
	    cat >> ./start
	    
	    # see if this did anything at all
	    set temp = `grep "IMAGE" ./start | wc -l`
	    if($temp) then
		echo "reading wedges.txt"
	    else
		rm -f ./start >& /dev/null
	    endif
	endif
	
	# check once again
	if((! -e ./start)&&(! -e ./mosflm.com)) then
	    # no processing information (don't let Wedger get creative! )
	    echo "skipping   $pwd  no wedge information! "
	    cd ..
	    continue
	endif
	
	# check to see if processing is appropriate
	
	# reconstruct image filename from mosflm keywords
	set mostrecent = `ls -1rt ./start ./mosflm.com |& tail -1`
	cat $mostrecent |&\
	nawk '/^DIRE/{dir=$2} /^IDENT/{ident=$2} /^EXTEN/{ext=$2}\
	      pattern=="" && dir!="" && ident!="" && ext!=""{pattern= ident "_%03d." ext; ident=ext=""}\
	      /TEMPLATE/{w=gsub("[\043]"," ",$2); n=split($2,a); pattern=a[1] "%0" w "d" a[2]}\
	      /IMAGE/ && $2~/[^0-9]/ && $2!~/^[\/]/{print dir "/" $2}\
	      /IMAGE/ && $2~/[^0-9]/ && $2~/^[\/]/{print $2}\
	      /IMAGE/ && $2!~/[^0-9]/{printf dir "/" pattern "\n", $2}\
	      /^PROCESS/ && $2!~/[^0-9]/ && pattern!=""{printf dir "/" pattern "\n", $2; pattern=""}' |\
	cat >! ${tempfile}
	set image = `tail -1 ${tempfile}`
	rm -f ${tempfile} >& /dev/null
	set frames = ""
	if(-e $mostrecent) then
	    # use initially set-up wedge lengths
	    set frames = `nawk '/^PROCESS/ && $4~/[0-9]/{print $4-$2+1}' $mostrecent | tail -1`
	endif
	if($?wedge_line) then
	    set frames = "$wedge_line[4]"
	endif

	if($?LOCAL) then
	    # only process frames on a local filesystem
	    set temp = `find $image -not -fstype nfs -print | wc -l`
	    if($temp == 0) then
		echo "skipping   $pwd  ($image on remote filesystem)"
		cd ..
		continue
	    endif
	endif
	
	# ignore "other-instance" signals if we are "alone"
	if($?ALONE) rm -f ./$busyfile ./$donefile >& /dev/null
	
	# check for another instance
	if(-e ./$busyfile) then
	    # see what STAGE the other process is at
	    set temp = `nawk '{print $5}' ./$busyfile`
	    if(("$temp" != "$STAGE")&&("$temp" != "")) then
		# other process does not match!
		cat ./$busyfile |\
		nawk '{printf "NOTICE: pid=%s on %s is at %s stage! \n", $3, $4, $5}'
		echo "we will switch to $temp stage too."
		set STAGE = "$temp"
	    endif
	    
	    if("$STAGE" == "polishing") then
		# check that GLOBALS are same too
		set temp = `nawk '{for(i=6;i<=NF;++i)print $i}' ./$busyfile`
		if(("$temp" != "$GLOBALS")&&($#temp == $#GLOBALS)) then
		    cat ./$busyfile |\
		    nawk '{printf "WARNING: pid=%s on %s is using ", $3, $4}'
		    echo "$temp"
		    echo "not $GLOBALS"
		    echo ""
		    echo "we will switch"
		    
		    # pretend we just finished "refining"
		    set STAGE = "refining"
		    goto Branch
		endif
	    endif

	    # display message that we are skipping
	    cat ./$busyfile |\
	    nawk '{printf "skipping   %s  %s claimed by pid=%s on %s\n", $1, $2, $3, $4}'
	    cd ..
	    continue
	endif
	
	ls ./temp/*.spotod >& /dev/null
	if((! $status)&&($?SENSITIVE)) then
	    # another instance of this script is PROBABLY busy here
	    echo "skipping   $pwd  ($image)  unknown job running here"
	    cd ..
	    continue
	endif
	
	if(-e ./$donefile) then
	    # see what STAGE the other process was at
	    set temp = `nawk '{print $5}' ./$donefile`
	    if(("$temp" != "$STAGE")&&("$temp" != "")) then
		# other process does not match! 
		cat ./$donefile |\
		nawk '{printf "NOTICE: pid=%s on %s was at %s stage \n", $3, $4, $5}'
		if("$temp" == "polishing") then
		    # check that GLOBALS are same as us
		    set temp = `nawk '{for(i=6;i<=NF;++i)print $i}' ./$donefile`
		    if(("$temp" != "$GLOBALS")&&($#temp == $#GLOBALS)) then
			# these guys must be ahead of us
			cat ./$donefile |\
			nawk '{printf "WARNING: pid=%s on %s is using ", $3, $4}'
			echo "$temp"
			echo "not $GLOBALS"
			echo ""
			echo "we will switch"
			
			# pretend we just finished "refining"
			set STAGE = "refining"
			goto Branch
		    endif
		endif
		echo "but we are at $STAGE stage..."
		rm -f ./$donefile
	    endif
	endif

	if(-e ./$donefile) then
	    # this directory has already been processed
	    cat ./$donefile |\
	    nawk '{printf "skipping   %s  %s  %s already done\n", $1, $2, $5}'
	    cd ..
	    continue
	endif
	
	# check that image exists
	if(! -e "$image") then
	    # extract file part of name
	    set img = `echo $image | nawk 'BEGIN{FS="/"} {print $NF}'`
	    
	    # try previously-found directory
	    if(-e "${image_dir}/${img}") then
		set image = "${image_dir}/${img}"
	    endif
	endif
	# re-find images (if requested)
	if((! -e "$image")&&($?REFIND_IMAGES)) then
	    # check to see if image directory exists
	    set dir = `dirname "$image"`
	    if((! -e "$dir")||("$REFIND_IMAGES" == "always")) then
		# either user requested re-finding all missing images
		# or filesystem structure appears to have changed
		set img = `echo $image | nawk 'BEGIN{FS="/"} {print $NF}'`
		echo "looking for $img in filesystem"
		set img = `find / -name $img -print |& nawk 'NF==1{print; exit}'`
		if(-e "$img") then
		    set image = "$img"
		    set image_dir = `dirname "$image"`
		    echo "found $image"
		endif
	    else
		# directory exists, but no image.  Probably just not collected yet
	    endif
	endif
	if(! -e "$image") then
	    echo "skipping   $pwd  (no $image found)"
	    echo "$pwd $image $$ $machine testing" >! ./$donefile
	    cd ..
	    continue
	endif
	
	# check one more time for another instance
	if(-e ./$busyfile) then
	    cat ./$busyfile |\
	    nawk '{printf "skipping   %s  %s claimed by pid=%s on %s\n", $1, $2, $3, $4}'
	    cd ..
	    continue
	endif
    
	####################################	
	# claim this directory as "busy"
	#     dir   what     who    where    how
	echo "$pwd  ($image) $$ $machine $STAGE $GLOBALS" >! $busyfile
	# now make sure noone else just did too!
	sleep 5
	set temp = "someone else"
	if(-e ./$busyfile) set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
	if("$temp" != "$$ on $machine") then
	    echo "WARNING: collided with ${temp} in ${pwd}! "
            cat ./$busyfile |\
            nawk '{printf "skipping   %s  %s claimed by pid=%s on %s\n", $1, $2, $3, $4}'
            cd ..
	    continue
	endif
	
	# set-up shop
	if(! -e logs) mkdir logs
	if(! -e ./logs/Wedger.log) touch ./logs/Wedger.log
	rm -f temp/* >& /dev/null
	
	# decide on best instructions for Wedger elves
	unset exitcode
	if((("$STAGE" == "restarting")&&(! $?exitcode))||(! -e ./mosflm.com)) then
	    # set up mosflm.com script
	    echo "setting up ${pwd}/mosflm.com with $pwd/start and $image"
	    #rm -f *.mat >& /dev/null
	    Wedger -norun ./start best.mat ${root_dir}/index/mosflm.com $image -nostrategy -nointeg $USER_hires $SGs >! ./logs/Wedger.log
	    if("$STAGE" == "restarting") set exitcode = $status
	endif
	if(("$STAGE" == "testing")&&(! $?HURRY_UP)&&(! $?exitcode)) then
	    # make sure this is going to work! single-run mode
	    echo "testing    ${pwd}/mosflm.com  ($image)"
	    Wedger -1 ./mosflm.com $image -nomerge -nostrategy -nointeg $frames frames $USER_hires $SGs >> ./logs/Wedger.log
	    set exitcode = $status
	endif
	if(! $?exitcode) echo "processing into ${pwd}/logs/Wedger.log  ($image)"
	if(($?HURRY_UP)&&(! $?exitcode)) then
	    # refine 2x and then integrate
	    Wedger -burst 2 ./mosflm.com $image -nomerge -nostrategy $frames frames $USER_hires $SGs >> ./logs/Wedger.log
	    set exitcode = $status
	endif
	if(("$STAGE" == "polishing")&&(! $?exitcode)) then
	    grep "polishing CELL" ${root_dir}/${donefile} >& /dev/null
	    if(! $status) then
		# our own "busyfile" should take care of this now
		rm -f ${root_dir}/${donefile} >& /dev/null
	    endif
	
	    # re-refine with cell fixed
	    echo "MOSAIC $MOSAIC" >> mosflm.com
	    Wedger ./mosflm.com $image -fixcell $CELL $frames frames $USER_hires $SGs >> ./logs/Wedger.log
	    # fix mosaicity as well?
	    #Wedger ./mosflm.com $image -fixcell $CELL -fixmosaicity $frames frames $USER_hires $SGs >> ./logs/Wedger.log
	    set exitcode = $status
	endif
	if(! $?exitcode) then
	    # "default" run
	    Wedger ./mosflm.com $image -nomerge -nostrategy $frames frames $USER_hires $SGs >> ./logs/Wedger.log
	    set exitcode = $status
	endif
	
	# respond to Wedger's exit code
	if($exitcode != 0) then
	    set PROBLEMS = $exitcode
	    cat << EOF-problem | tee -a mosflm.com
WARNING: processing did not go well!
     see ${pwd}/logs/Wedger.log and
         ${pwd}/logs/mosflm.log
         to find out what went wrong.
EOF-problem
	endif
	
	# clear our claim to this directory
	if(! -e ./$busyfile) then
	    echo "someone deleted ${pwd}/$busyfile ! "
	    echo "aborting run"
	    exit
	endif
	mv ./$busyfile ./$donefile
    endif
    
    cd $root_dir
end
# finished measuring all wedges
onintr
cd $root_dir

# print time when we are done
echo -n "finished $STAGE "
date

# see if we were the first to finish
if(! -e ./$donefile) then
    # declare ourselves the winner (of all instances)
    echo "$root_dir first $$ $machine $STAGE $GLOBALS" >! ./$donefile
endif

# skip waiting is user said we are alone
if($?ALONE) goto Branch

wait:
####################################################################################
# run back through wedges, and make sure they are all marked as "done".
# if not, wait up to $timeout hours before proceeding anyway
# NOTE: each instance should be processing wedges in the same order! 

# check every wedge for a "busy with this stage" signal
foreach wedge_dir ( $wedge_dirs )
    grep "$STAGE" ${wedge_dir}/$busyfile >& /dev/null
    if($status) then
	# busy signal is either missing, or for a different stage
	# wait a second, to make sure it's really not busy
	sleep 1
	grep "$STAGE" ${wedge_dir}/$busyfile >& /dev/null
	if($status) then
	    # this wedge is, officially, not busy
	    
	    # will anyone miss this? 
	    #rm -f ${wedge_dir}/$donefile >& /dev/null
	    continue
	endif
	# must have just missed it, wedge really is busy
    endif
    
    # reaching here means the wedge is marked as busy
    if(-e "${wedge_dir}/$busyfile") then
	# explain the wait
	cat "${wedge_dir}/$busyfile" |\
	nawk '{printf "waiting for %s on %s to finish %s %s\n", $3, $4, $5, $1}'
	
	# wait $timeout hours for signal that processing is done
	set waiting = `echo "$timeout" | nawk '{printf "%d", 360*$1}'`
	unset done
	while(($waiting)&&(! $?done))
	    # wait 10 seconds
	    sleep 10
	    
	    grep "$STAGE" ${wedge_dir}/$busyfile >& /dev/null
	    if($status) then
		# busy signal is now missing
		set done
		
		# will anyone miss this? 
		#rm -f ${wedge_dir}/$donefile >& /dev/null
	    endif

	    @ waiting = ( $waiting - 1 )
	end
	
	# check to see if we timed out
	if(! $?done) then
	    echo "waited $timeout hours! "
	    echo -n "giving up waiting for "
	    if(-e "${wedge_dir}/$busyfile") then
		nawk '{printf "%s on %s to finish ", $3, $4}' "${wedge_dir}/$busyfile"
	    endif
	    echo "$wedge_dir"
	    rm -f "${wedge_dir}/$busyfile" >& /dev/null
	endif
    endif
end
# reaching here should mean all wedges are marked as "done"

# make sure every instance notices this?
#if(-e ./$donefile) then
#    echo "waiting for other instances to synch up..."
#    sleep 15
#endif
echo ""

# clear "busy" and "done" flag files (if this hasn't been done already)
if(-e "./$donefile") then
    rm -f ./$donefile >& /dev/null
    foreach wedge_dir ( $wedge_dirs )
#	rm -f ${wedge_dir}/$busyfile >& /dev/null
	rm -f ${wedge_dir}/$donefile >& /dev/null
    end
endif



Branch:
####################################################################################
# all processing on all CPUs is finished for this round

if($?PROBLEMS) then
    echo "some wedges failed to process"
    echo "feel free to fix these problems while we work on other wedges"
endif

# if all we did was initialize, then we should just go back and process for real
if("$STAGE" == "restarting") then
    echo "initialization complete, running scripts this time..."
    set STAGE = "testing"
    goto again
endif

# "hurry up" means we should scale now
if($?HURRY_UP) then
    goto scale
endif
Branch_late:

# reaching here means wedges must have all been checked out
if(("$STAGE" == "testing")||("$STAGE" == "restarting")) then
    if(! $?PROBLEMS) then
	echo "all wedges checked out"
    endif
    set STAGE = "refining"
    goto again
endif

# reaching here means we are done "refining" or "polishing"



# get average cell, etc. and remeasure with it

if(("$CELL" == "")||("$MOSAIC" == "")) then
    # first, try to inherit parameters that are already in use
    
    echo -n "" >! ${tempfile}params
    foreach wedge_dir ( . $wedge_dirs . )
	# check for another instance that is already polishing
	set file = "${wedge_dir}/${donefile}"
	grep "polishing CELL" "$file" >&! ${tempfile}params
	if($status) then
	    set file = "${wedge_dir}/${busyfile}"
	    grep "polishing CELL" "$file" >&! ${tempfile}params
	    if($status) set file = ""
	endif
	
	if("$file" != "") then
	    # someone else is/was polishing, they must know what they are doing
	    cat ${tempfile}params |\
	    nawk '$5=="polishing"{\
	          for(i=6;i<=12;++i) printf "%s ", $i; print "";\
		  for(i=13;i<=NF;i+=2) print $i, $(i+1);}' |\
	    cat >! ${tempfile}
	    mv -f ${tempfile} ${tempfile}params >& /dev/null
	    
	    # see if this was useful
	    set temp = `nawk '/^CELL/ || /^MOSA/' ${tempfile}params | wc -l`
	    if($temp) then
		# this is all we need to know
		break	    
	    endif
	endif
    end
    
    # inherit average values from this other run
    # (if we didn't find one, these are harmless initializations)
    if("$CELL" == "") then
	set CELL = `nawk '/^CELL/ && NF==7{print $2, $3, $4, $5, $6, $7; exit}' ${tempfile}params `
    endif
    if("$MOSAIC" == "") then
	set MOSAIC = `nawk '/^MOSAIC/ && NF==2{print $2; exit}' ${tempfile}params `
    endif
    # anything else?
    rm -f ${tempfile}params >& /dev/null
endif

if(("$CELL" == "")||("$MOSAIC" == "")) then
    # constrained parameters have still not been set
    # perhaps we are the first to finish?
    
    # gather average project-wide values
    echo -n "" >! ${tempfile}params
    foreach wedge_dir ( $wedge_dirs )	
	# first, check to make sure processing finished okay
	set script = "${wedge_dir}/mosflm.com"
	grep "WARNING: processing did not go well" $script >& /dev/null
	if($status) then
	    # processing DID go well
	    set log = "${wedge_dir}/logs/mosflm.log"
	    cat $log |\
	    nawk '/Processing Image/{if(cell) print "CELL", cell; if(mosaic) print "MOSAIC", mosaic; cell=mosaic=""}\
	      /Mosaic spread/{getline; if($1 == "New"){mosaic = $NF}} \
   /^          Real cell parameters/{getline; cell = $0}' |\
	    cat >> ${tempfile}params
	endif
    end
    grep "polishing CELL" ./${donefile} >& /dev/null
    if($status) then
	# we do not appear to have collided with someone else here
	
	# average all the parameters
	# and claim we are the first to have determined the average
	# parameters, and wait to see if someone else collides with us
	cat ${tempfile}params |\
	nawk '/^CELL/ && NF==7{++cells; for(i=2;i<=NF;++i){c[i]+=$i}} \
	      /^MOSAIC/ && NF==2{++mosas; mos+=$NF}\
	END{if(cells){printf "CELL "; for(i=2;i<=7;++i) printf "%s ", c[i]/cells; print ""};\
	    if(mosas){print "MOSAIC", mos/mosas}}' |\
	nawk -v pid=$$ -v machine=$machine '/^MOSA/{MOSA = $0} /^CELL/{CELL = $0}\
	     END{print "./ (none)", pid, machine, "polishing", CELL, MOSA}' |\
	cat >! ./${donefile}
	rm -f ${tempfile}params >& /dev/null
	
	# wait and see if there's a collision
	sleep 5
	grep " $$ $machine polishing CELL" ./${donefile} >& /dev/null
	if($status) then
	    # collided...
	    cat ./${donefile} |\
	    nawk '{printf "collided with %s on %s averaging cell! \n", $3, $4}'
	    # just go ahead and use it
	endif
    else
	# collided, someone else already did averaging
	rm -f ${tempfile}params >& /dev/null
    endif
    
    
    # use whatever average values are in ./$donefile 
    if("$CELL" == "") then
	set CELL = `nawk '$6=="CELL" && NF>11 {print $7, $8, $9, $10, $11, $12}' ./${donefile} `
    endif
    if("$MOSAIC" == "") then
	set MOSAIC = `nawk '$13~/^MOSAIC/ && NF>13{print $14}' ./${donefile} `
    endif
    # anything else?
    
    # ./${donefile} will be deleted once the first wedge-wise "busy" file
    # is written
endif

if("$CELL" == "") then
    # uh oh...
    echo "ERROR: unable to obtain project-wide parameters for polishing stage."
    # just go on to scaling? 
endif

if(("$GLOBALS" == "")&&("$CELL" != "")) then
    # only do this once

    # signal repeating refinement
    echo "repeating refinement with cell fixed at $CELL"
    set STAGE = "polishing"
    set GLOBALS = ( CELL $CELL MOSAIC $MOSAIC )
    goto again
endif



# reaching here means we are done "polishing"
set STAGE = "polishing"

goto scale

scale:
####################################################################################
# make sure only one instance does scaling
if(-e ./$busyfile) then
    # check for a failed scaling job
    grep "failed" ./$busyfile >& /dev/null
    if(! $status) then
	# the last scaling job failed! 
	cat ./$busyfile |\
	nawk '{printf "%s on %s failed to complete scaling.\n", $2, $3}'
	# other scaling job must have died
	rm -f ./$busyfile >& /dev/null

	# try it again
	goto scale
    endif

    # verify scaling process? 
    set other_pid = `nawk '{print $3}' ./$busyfile`
    set other_machine = `nawk '{print $4}' ./$busyfile`
    if("$other_machine" == "$machine") then
	# make sure this process is actually running
	set temp = `ps -p "$other_pid" |& tail -1 | nawk '{print $1}'`
    else
	# try to check and see if this remote job is really running
	echo "checking for $other_pid on $other_machine..."
	set temp = `rsh $other_machine "echo "madeit" ; ps -p $other_pid |& tail -1"`
	if("$temp" !~ madeit* ) then
	    echo "can't tell."
	    # assume it is running
	    set temp = "$other_pid"
	else
	    # rsh worked! 
	    # check to see if process was there
	    set temp = `echo "$temp" | nawk -v other_pid=$other_pid '$2==other_pid{print $2}'`
	endif
    endif
    if("$temp" != "$other_pid") then
	echo "$other_pid on $other_machine is not running."
	
	# make sure noone else beat us to the punch
	set temp = ""
	if(-e ./$busyfile) set temp = `nawk '{print $3, $4}' ./$busyfile`
	if("$temp" == "$other_pid $other_machine") then
	    echo "deleting ./$busyfile"
	    rm -f ./$busyfile >& /dev/null
	endif

	# try that again
	goto scale
    endif
    
    # report what's going on
    nawk '{print "scaling already in progress by", $3, "on", $4}' ./$busyfile
    
    if((-e mtz/all.mtz)&&($?HURRY_UP)&&(! $?NO_SOLVE)) then
	# charge ahead?
	goto setup_SGs
    endif

    if("$STAGE" != "polishing") then
	# might as well do more mosflm processing while we wait
	echo "continuing with data processing..."
	#goto again
	# continue with "Branch" section (as usual)
	goto Branch_late
    endif
    
    # skip ahead, and wait for scaling to finish
    goto wait_for_scaling
endif
# claim scaling job
echo "$root_dir scaling $$ $machine scaling" >! ./$busyfile
# wait a bit, for synchronization
sleep 5
set temp = "someone else"
if(-e ./$busyfile) set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
if("$temp" != "$$ on $machine") then
    echo "WOOPS! $temp beat us to it! "
    # go back and do standard check again
    sleep 2
    goto scale
endif
# now we are for sure going to run scaling
set STAGE = "scaling"

# run Scaler Elves to scale and merge
set temp = ""
if($?HURRY_UP) set temp = "$temp hurry"
foreach wedge_dir ( $wedge_dirs )
    set temp = "$temp ${wedge_dir}/raw.mtz"
end
Scaler wedges.txt -new $temp | tee Scaler.log

# signal other instances that we are done scaling
rm -f ./$busyfile >& /dev/null

# check to see if scaling went okay
if(! -e ./mtz/all.mtz) then
    # let someone else try it?
    echo "$root_dir failed $$ $machine $STAGE" >! ./$busyfile
    goto wait_for_scaling
endif

# Pattersons?

# postrefine and repeat?



wait_for_scaling:
####################################################################################

# set timeout to $timeout hours
set waiting = `echo $timeout | nawk '{print $1*60}'`
# wait for scaling to finish
if(-e ./$busyfile) then
    cat ./$busyfile |\
    nawk '/ failed /{print "waiting for someone else to finish scaling."}\
        ! / failed /{print "waiting for", $3, "on", $4, "to finish scaling."}'
endif
while(($waiting)&&(-e ./$busyfile))
    # wait up to $waiting minutes (otherwise, something is probably just stuck)
    @ waiting = ( $waiting - 1 )
    sleep 60
end
if(! -e ./mtz/all.mtz) then
    # hmm... nothing to do but keep waiting
    sleep 60
    goto wait_for_scaling
endif

# give up waiting for scaling
if(-e ./$busyfile) then
    set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
    echo "tired of waiting for $temp to finish scaling..."
    rm -f ./$busyfile >& /dev/null
    goto setup_SGs
endif

# check and see if scaling needs to be updated
set temp = ""
if(-e scripts/sort_everything.com) then
    # see if new processing has been done since start of scaling run
    set temp = `find . -name raw.mtz -newer scripts/sort_everything.com -print |& nawk 'NF==1' |& head -1`
endif
if("$temp" != "") then
    # there are raw mtz files newer than the merged one
    # we need to do more scaling
    echo "$temp was updated since scaling began"
    echo "scaling needs to be updated..."
    if(! $?HURRY_UP) goto scale
    echo "...but we are in a hurry."
endif


echo -n "Finished scaling "
date



setup_SGs:
###############################################################################
# now that we know SG informaiton is available, we need to set up directories
# for parallelizing MR and heavy-atom finding in different space groups

cd $root_dir
set sitefile
set best_SG

# bail now if user requested no site-finding
if($?NO_SOLVE) then
    echo -n "finished with processing "
    date
    goto table1
endif

# check and see if phasing is even possible
set completeness = `echo "stats nbin 3" | mtzdump hklin mtz/all.mtz |& awk '$10 ~ /^F/ && ! /FreeR_flag/{print int($5)}' | sort -nr | head -1`
# check and see if there are any "new" images since the processing was done
set new_images = 0
foreach mosflm_script ( `ls -1rt */we*/mosflm.com` )
   set image_dirs = `nawk '/^DIRE/{print $2}' $mosflm_script`
   set image_pattern = `nawk '/IDEN/{print $2} /^TEMP/{print substr($2,1,index($2,"#")-1)}' $mosflm_script | tail -1`
   set new_images = `find $image_dirs -type f -name ${image_pattern}'*' -cnewer $mosflm_script | wc -l`
   if("$new_images" == "") set new_images = 0
   if($new_images) break
end
if(-e mtz/all.mtz && "$completeness" != "") then
    # see if the most complete dataset is > 75% complete
    if($completeness < 75 && $new_images) then
	# there are not enough data to even think about finding sites (and we have "new" frames)
	echo "data are only $completeness % complete."
	echo "we need to process more images..."
	goto again
    endif
endif


# make sure we have a "root" space group 
set SGnum = `echo "head" | mtzdump hklin mtz/all.mtz | nawk '/Space group/{print $NF+0}'`
set SG = ` nawk -v num=$SGnum '$1==num && NF>5{print $4}' ${CLIBD}/symop.lib `

if("$SG" == "") then
    # we are in trouble...
    echo "ERROR: mtz/all.mtz is corrupted! "
    goto wait_for_scaling
endif
if("$CELL" == "") then
    # get cell from mtz file too?
    set CELL = `echo "head" | mtzdump hklin mtz/all.mtz | nawk '/Cell Dimensions/{getline;getline;print}' | tail -1`
endif


# support trials in multiple space groups

# get point group, and lattice from $SG
set PG   = `nawk -v SG=$SG '$4==SG{print $5; exit}' $CLIBD/symop.lib`
set latt = `echo $SG | nawk '{print substr($1, 1, 1)}'`

# get all space groups in this point group
set SGs = `nawk -v PG=$PG -v latt=$latt '$5==PG && $4 ~ latt && ! /m/ && ! /bar/ && $1 < 500{print $4}' $CLIBD/symop.lib`

# special case of asymmetric orhorhombics
if("$PG" == "PG222") then
    if("$latt" == "P") set SGs = "P212121 P21212 P21221 P22121 P2221 P2212 P2122 P222"
#    if("$latt" == "C") set SGs = "C2221 C2212 C2122 C222"
endif

# prioritize them somehow? 
echo " $SGs " | nawk 'BEGIN{RS=" "} NF==1{print}' |\
nawk '{o=1} \
    # sort space-groups by popularity \
    $1=="P212121"{o=5} $1=="P21212"{o=4} $1=="C2221"{o=3} $1=="I222"{o=2} $1=="C222"{o=0} $1=="P222"{o=0} \
    $1=="P43212"{o=3} $1=="P41212"{o=2} \
    $1=="P3221"{o=5} $1=="P3121"{o=4} $1=="P6122"{o=3} $1=="P61"{o=2} \
    $1=="R3"{o=3} $1=="R32"{o=2} {print o, $1}' | sort -nr |\
cat >! ${tempfile}SGs
set defaultSGs = `nawk 'NF==2{print $NF}' ${tempfile}SGs`
set SGs = ( $defaultSGs )
rm -f ${tempfile}SGs >& /dev/null
if($?SG_order) then
    # enforce user-specified order
    set SGs = ( $SG_order )
endif

# make sure Phaser has a directory to work in
if(-e phaser) then
    test -d phaser
    if($status) then
	# regular file in the way
	echo "moving phaser to phaser.old"
	mv phaser phaser.old
    endif
endif
if(! -e phaser) mkdir phaser
# create the space-group directory tree
foreach SG ( $SGs )
    if(-e ${root_dir}/phaser/$SG) then
	test -d ${root_dir}/phaser/$SG
	if($status) then
	    # file in the way
	    echo "moving phaser/$SG to phaser/${SG}.old"
	    mv ${root_dir}/phaser/$SG ${root_dir}/phaser/${SG}.old
	endif
    endif
    if(! -e ${root_dir}/phaser/$SG) mkdir ${root_dir}/phaser/$SG
end
# same thing for EPMR
if(! -e epmr) mkdir epmr
if((! -e epmr/epmr.com)&&(-e scripts/epmr.com)) then
    cp scripts/epmr.com epmr/epmr.com >& /dev/null
endif
foreach SG ( $SGs )
    if(! -e ${root_dir}/epmr) continue
    set dir = ${root_dir}/epmr/$SG
    if(-e "$dir") then
	test -d "$dir"
	if($status) then
	    # file in the way
	    echo "moving $dir to ${dir}.old"
	    mv $dir ${dir}.old
	endif
    endif
    if(! -e $dir) mkdir $dir
end
# same thing for wARP
foreach SG ( $SGs )
    if(! -e ${root_dir}/wARP) continue
    set dir = ${root_dir}/wARP/$SG
    if(-e "$dir") then
	test -d "$dir"
	if($status) then
	    # file in the way
	    echo "moving $dir to ${dir}.old"
	    mv $dir ${dir}.old
	endif
    endif
    if(! -e $dir) mkdir $dir
    cd $dir
    # link critical files 
    ln -s ../setup_warp.com . >& /dev/null
    ln -s ../warp.runme . >& /dev/null
    ln -s ../seq.pir . >& /dev/null
    ln -s ../Rplot.com . >& /dev/null
#    ln -s ../Drift.com . >& /dev/null
end
cd $root_dir
if(-e refmac) then
    test -d refmac
    if($status) then
	# regular file in the way
	echo "moving refmac to refmac.old"
	mv refmac refmac.old
    endif
endif
if(! -e refmac) mkdir refmac



#make up some solvent contents?
echo ""
if(! $?MASS) then
    # add up the total protein mass from wedges.txt
    set MASS = `nawk '/Da chain:/{mass+=$1} END{print mass}' wedges.txt`
endif
if("$CELL" == "") then
    
endif
if(! $?NMOLs) set NMOLs = ""
if(("$SOLC" == "")&&("$MASS" != "")) then
    # let's make up some solvent contents
    set nmol = 1
    set minSOLC = 10
    set maxSOLC = 90
    if($?HURRY_UP) then
	set minSOLC = 30
	set maxSOLC = 70
    endif
    while ( $nmol < 15 )
	matthews_coef << EOF >! ${tempfile}solc
CELL $CELL
SYMM $SG
MOLW $MASS
NMOL $nmol
EOF
	# save the solvent content
	set solc = `nawk '/the solvent % is:/{printf "%.0f", $NF}' ${tempfile}solc`
	rm -f ${tempfile}solc >& /dev/null
	if("$solc" == "") set solc = 1
	
	if($solc > $minSOLC) then
	    # accumulate list of solvent contents and molecule counts
	    if("$solc" < $maxSOLC) then
		set SOLC = ( ${solc}% $SOLC )
		set NMOLs = "$NMOLs $nmol"
	    endif
	else
	    # exit loop if solc has dropped too low
	    break
	endif
	@ nmol = ( $nmol + 1 )
    end
    if("$NMOLs" == "") then
	# no solvent contents were possible?
	set NMOLs = 1
	if($solc > 10 && $solc < 90) set SOLC = ${solc}%
    endif
    # tell user what we are up to...
    echo "$NMOLs" |\
    nawk '$NF!=1{s="s"}\
	  NF>1{printf "There could be "}\
          NF==1{printf "There can be only "}\
	  NF>1{for(i=1;i<NF;++i) printf "%s ", $i; printf "or "}\
	  {print $NF, "monomer"s" in the assymmetric unit."}'
    
    # back off if we chose more solvent contents than Phaser will
    if($#SOLC > 10) set SOLC = ""
    echo ""
endif
if("$NMOLs" == "") set NMOLs = 1


##############################
# retrieve expected number of sites/asu? from Scaler's solve script? 
if(("$sites" == "")&&(-e "SOLVE/solve.com")) then
    set sites = `nawk '/nanomalous/ && $2+0>0{print $2+0}' SOLVE/solve.com | tail -1`
endif
# figure out reasonable number of sites (if we still don't know)
if("$sites" == "") then
    set sites = `nawk '/sites/ && $2+0>0{print $2+0}' wedges.txt | tail -1`
    if("$sites" == "") set sites = 1
    if("$NMOLs" != "") then
	# maximum conceivable number of sites
	set sites = `echo $sites $NMOLs[$#NMOLs] | nawk '{print $1 * $2}'`
    endif
endif
if("$sites" == "") set sites = 1


# now we can jump ahead to wARP if we want to
if("$STAGE" == warp) goto warp
if("$STAGE" == phaser) goto phaser






epmr:
###############################################################################
# use EPMR (if availabe) to do molecular replacement
if("$search_models" == "") goto shelx
set STAGE = epmr
set search_models = ( $search_models )

echo ""
# now run down the space group list
foreach SG ( $SGs ) 
    set model = 0
foreach search_model ( $search_models )
    @ model = ( $model + 1 )
    set dir = `dirname "$search_model"`
    set short_name = `basename "$search_model"`
    set search_model = `cd $root_dir ; cd $dir ; pwd`"/$short_name"
    
    # make a working directory
    set dir = ${root_dir}/epmr/$SG/model$model    
    if(! -e $dir ) mkdir $dir
    cd $dir
    
    # check to see if another instance is running EPMR here
    if(-e ./$donefile) then
	grep "best CC=" ./epmr.log
	continue
    endif
    if(-e ./$busyfile) then
	cat ./$busyfile |\
	nawk '{printf "skipping %s  %s being run by pid=%s on %s\n", $1, $5, $3, $4}'
	continue
    endif
    
    # indicate what we are doing in the "busy" file
    echo "epmr/$SG/model$model ${search_model} $$ $machine EPMR" >! ./$busyfile
    
    # check for collisions? 
    sleep 2
    set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
    if("$temp" != "$$ on $machine") then
	echo "collided with ${temp}! in epmr/$SG/model$model"
	echo "moving on..."
	continue
    endif
    
    # run EPMR
    echo "running EPMR on $short_name into epmr/$SG/model$model/epmr.log "
    set temp = "4-15A 3-15A 5-15A"
    if($?HURRY_UP) set temp = "4-15A"
    if(! $?NMOLs) set NMOLs = 1
    #ln -sf $search_model $short_name >& /dev/null
    ../../epmr.com  ../../../mtz/all.mtz $SG $search_model $temp $NMOLs >! ./epmr.log
    mv ./$busyfile ./$donefile
end
end
# return to launch directory again
cd $root_dir    

# check for still-running EPMR jobs
ls epmr/*/*/$busyfile >& /dev/null
if(! $status) then
    echo "other EPMR jobs will finish up latter..."
else
    # last one out should turn off the lights...
    rm -f epmr/*/*/$donefile >& /dev/null
endif

##########################
# sumarize epmr runs for the user

echo ""
echo "epmr summary:"

# locate the "best of the best" pdb files
find epmr -name '*.best.pdb' -print |\
nawk 'NF==1{file=$1;getline < file;R=$NF;CC=$(NF-2);SG=$5;close(file);\
      printf "R= %s CC= %s  in %-7s for %s\n", R,CC,SG,file}' |\
sort -n +1 | tee ${tempfile}best_Rs

# make a copy of the "best" pdb in the EPMR directory
set best_pdb = `cat ${tempfile}best_Rs | nawk '{print $NF; exit}'`
set best_R = `cat ${tempfile}best_Rs | nawk '{printf "%d", $2*100; exit}'`
set best_SG = `cat ${tempfile}best_Rs | nawk '{printf "%s", $6; exit}'`
# re-order SG list
set SGs    = `cat ${tempfile}best_Rs | nawk '! seen[$6]{print $6; seen[$6]=1}'`
if(! -e "$best_pdb") then
    echo "WARNING: all EPMR runs seem to have failed! "
    set best_pdb = ""
    set search_models = ""
    
    # what else is there to do?
    goto shelx
endif
cat ${tempfile}best_Rs >! epmr/Elves.summary.txt

# set these up to be dropped into wARP
foreach SG ( $SGs )
    if(! -e wARP/${SG}) continue

    # find the best EPMR hit for this space group
    set model = `nawk -v SG=$SG '$6==SG{print $NF; exit}' ${tempfile}best_Rs`
    set dir = `dirname "$model"`
    set fullname = `cd $dir ; pwd`/`basename "$model"`
    if(! -e "$fullname") continue
    
    if(! -e wARP/${SG}) continue
    
    # links might be misleading?
    echo "linking ${model} to wARP/${SG}/best.pdb"
    ln -sf ${fullname} wARP/${SG}/best.pdb >& /dev/null
    echo "reindexing mtz/all.mtz to mtz/all.${SG}.mtz"
    
    # hijack the epmr script?
    mkdir ${tempfile}reindex_temp
    cat epmr/epmr.com |\
    nawk '/^mtz2various /{\
	print "mv -f", $3, "reindexed.mtz" ;\
	print "exit";} {print}' |\
    cat >! ${tempfile}reindex_temp/reindex.com
    cd ${tempfile}reindex_temp
	/bin/csh -f reindex.com ${root_dir}/mtz/all.mtz $SG $fullname > /dev/null
	# ${tempfile}reindex_temp/reindexed.mtz should be it.
    cd $root_dir
    
    # watch out for collisions?
    mv ${tempfile}reindex_temp/reindexed.mtz mtz/all.${SG}.mtz >& /dev/null
    ln -sf ${root_dir}/mtz/all.${SG}.mtz wARP/${SG}/best.mtz >& /dev/null
    
    # clear out our temporary directory
    rm -rf ${tempfile}reindex_temp >& /dev/null
end
rm -f ${tempfile}best_Rs >& /dev/null

# skip over heavy-atom stuff if we found something
goto warp











shelx:
###############################################################################
cd $root_dir
set STAGE = "shelx"


if($?NO_SOLVE) goto table1

# run SHELX?
if(! -e ./SHELX) then
    goto solve
endif

ls ./SHELX/*.hkl >& /dev/null
if($status) then
    echo "ERROR: no data for shelx! "
    goto scale
endif

# get space groups (directories) to try
if("$SGs" == "") then
    set SGs = ( $defaultSGs )
endif
if($?SG_order) then
    # enforce user-specified order
    set SGs = ( $SG_order )
endif
    
foreach SG ( $SGs )
    set dir = "${root_dir}/SHELX/$SG"
    if(! -e $dir ) continue
    cd $dir
    
    # avoid interprocess collisions
    if((-e ./$busyfile)||(-e ./$donefile)) then
	echo "skipping $SG"
	continue
    endif
    

    # claim this directory first
    echo "SHELX/$SG $SG $$ $machine shelx" >! ./$busyfile
    # check for collision?
    sleep 1
    set temp = "someone else"
    if(-e ./$busyfile) set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
    if("$temp" != "$$ on $machine") then
	echo "WARNING! collision with ${temp} in SHELX/${SG}! "
	continue
    endif
    
    # move into the shelx space group directory
    set pwd = `pwd`
    echo "$SG" | nawk '{printf "running shelx in SHELX/%-7s ", $1, $1}'
	
    if(-e ano.hkl) ../shelxs ano >&! ano.log
    if(-e iso.hkl) ../shelxs iso >&! iso.log
    if(-e fh.hkl)  ../shelxs fh  >&! fh.log
    if(-e fm.hkl)  ../shelxs fm  >&! fm.log
    
    # sumarize shelx runs
    set CFOM = `nawk '/CFOM =/{print $NF}' *.lst |& sort -n +2 | head -1`
    if("$CFOM" != "") then
	echo "$pwd $CFOM $$ $machine $STAGE" >! ./$donefile
	set CFOM = "CFOM = $CFOM"
	set CAN_RUN_SHELX

	# set up the "best" shelx solution for Phaser
	set temp = `nawk '/CFOM =/{print FILENAME, $NF}' *.lst | sort -n +2 | nawk 'NR==1{split($1,w,"\."); print w[1]}'`
	if("$temp" != "") then
	    # just use a link to the "best" shelx solution
	    ln -sf ${temp}.res best.res
	endif
    else
	# can't seem to run shelx
	set CFOM = "bust."
    endif
	
#   # run the combinatorial shelx script? 
#   set mtz = ""
#   if(-e ../../mtz/all.mtz) set mtz = ../../mtz/FH.mtz
#   if(-e ../../mtz/FH.mtz)  set mtz = ../../mtz/FH.mtz
#   if((-e ../../scripts/shelx.com)&&(-e "$mtz")) then
#	# run the pre-packaged shelx script
#	../../scripts/shelx.com $SG $mtz $sites sites ../shelxs
#	if(-e "shelx.pdb") then
#	    # must have found something
#	    set sitefile = shelx.pdb
#	endif
#   endif
	
    # indicate positive or negative result
    echo "$CFOM"
    rm -f ./$busyfile >& /dev/null
end
cd ${root_dir}/SHELX

# wait for all SHELX runs to finish
foreach SG ( $SGs )
    # skip over completed SGs
    if(-e ./${SG}/$donefile) then
	#echo "skipping $SG (already done)"
	continue
    endif
    
    # not done, but not busy?
    if(! -e ./${SG}/$busyfile) then
	sleep 2
	if((! -e ./${SG}/$busyfile)&&($?CAN_RUN_SHELX)) then
	    # try again
	    unset CAN_RUN_SHELX
	    goto shelx
	endif
    endif
    
    # nothing more to do but wait
    if(-e ./${SG}/$busyfile) then
	# wait an ample amount of time for other process to finish
	sleep 60
    endif
    if(-e ./${SG}/$busyfile) sleep 60
    if(-e ./${SG}/$busyfile) sleep 60
    if(-e ./${SG}/$busyfile) sleep 60
    # give up
end
cd ${root_dir}/SHELX

# are we the last one out?
ls */$busyfile >& /dev/null
if($status) then
    # everyone is done...
    # reset the shelx directory tree for the next run.
    rm -f */$donefile >& /dev/null
endif

# order space groups by their CFOM scores (lower is better)
nawk '/CFOM =/{printf "%s %s ", FILENAME, $NF} \
      /Heavy-atom assignments/{n=0} $5+0==1{++n} /Peak list/{print n}' */*.lst |\
nawk 'NF==3 && $2+0>0{print ($3+1)/$2, $3, $2, $1}' |\
sort -nr  |\
nawk '{print $2, "sites CFOM =", $3, $4}' |\
nawk 'BEGIN{FS="."} {print $1 "." $2 ".res"}' |\
cat >! ${tempfile}summary.txt
# format # sites CFOM = #.#### SG/set.res

# set up a default "site" file (for Phaser)
set temp = `head -1 ${tempfile}summary.txt | nawk '{print "./SHELX/" $NF, substr($NF, 1, index($NF, "/")-1)}'`
if($#temp == 2) then
    set sitefile = "$temp[1]"
    set best_SG = "$temp[2]"
endif

# re-order space group list
nawk '{print $NF}' ${tempfile}summary.txt |\
nawk 'BEGIN{FS="/"} {print $1}' |\
cat >! ${tempfile}SGs
# make sure all SGs are represented
echo " $SGs " | nawk 'BEGIN{RS=" "} {print}' >> ${tempfile}SGs
# make sure each SG only shows up once
#set SGs = `nawk '! seen[$NF]{seen[$NF]=1; print $NF}' ${tempfile}SGs`
rm -f ${tempfile}SGs >& /dev/null

# $SGs $best_SG and $sitefile have all been set-up for SHELX

# display the results:
echo "SHELX results:"
set temp = `cat ${tempfile}summary.txt | wc -l`
if($temp) then
    cat ${tempfile}summary.txt |\
    nawk '{print $NF, $(NF-1), $1}' |\
    nawk 'BEGIN{FS="/"} {print $NF, $1}' |\
    nawk '! seen[$NF]{seen[$NF]=1; printf "%-8s %d sites CFOM = %s\n", $NF, $3, $2}'
    # format: SG  # sites CFOM = #.####
else
    echo "failed."
endif
echo ""
# watch for collisions?
mv -f ${tempfile}summary.txt Elves.summary.txt >& /dev/null


# back to main directory
cd $root_dir













solve:
###############################################################################
# run SOLVE (if possible)
set STAGE = "solve"


if($?NO_SOLVE) goto table1
if(! -e ./SOLVE) goto phaser

ls ./SOLVE/*.fmt >& /dev/null
if($status) then
    # how did we get here? 
    echo "ERROR: no data for SOLVE! "
    goto scale
endif

# set up space-group list to do
if("$SGs" == "") then
    set SGs = ( $defaultSGs )
endif
if($?SG_order) then
    # enforce user-specified order
    set SGs = ( $SG_order )
endif

echo ""
foreach SG ( $SGs ) 
    cd ${root_dir}/SOLVE/$SG
    
    # check to see if another instance is running SOLVE
    if(-e ./$donefile) then
	echo "skipping $SG  already done "
	continue
    endif
    if(-e ./$busyfile) then
	cat ./$busyfile |\
	nawk '{printf "skipping %s  being run by pid=%s on %s\n", $2, $3, $4}'
	continue
    endif
    echo "SOLVE/$SG $SG $$ $machine $STAGE" >! ./$busyfile
    # delay to prevent collisions?
    
    # try to run solve
    echo "running SOLVE in $SG at "`pwd`
    ./solve.com >! Elves.summary.txt
    
    # sumarize SOLVE results
    tail -300 solve.status |&\
    nawk -v SG=$SG '/TOP SOLUTION/{fom=$8+0; zscore=$11+0; sites=0} \
	    ( ! /[^0-9 .-]/) && NF==7{ ++sites} \
	    /TIME REQUIRED/{printf "%-12s %d sites, fom = %4.2f, Z-score = %.2f\n", SG,  sites, fom, zscore}' |\
    tail -1 >> Elves.summary.txt
	
    # check if this worked
    grep "Dang" Elves.summary.txt >& /dev/null
    if(! $status) then
        # maybe another instance will have better luck?
        rm -f ./$busyfile >& /dev/null
        echo "failed! "
        echo "see "`pwd`"/solve.status"
        echo "to find out why."
	continue
    endif
    # report # of sites found, FOM, etc.
    tail -1 Elves.summary.txt

    # run resolve too?
    set solc = `echo $SOLC | nawk '{for(i=1;i<=NF;++i)print sqrt(($i-50)^2),$i}' | sort -n | nawk '{print $2;exit}'`
    if ("$solc" == "") set solc = "50%"
    echo "running RESOLVE at $solc solvent"
    ./resolve.com solve.mtz $solc >&! resolve.log 
    if($status) then
	echo "failed! "
	echo "see `pwd`/resolve.log"
	echo "to find out why."
    endif

    # declare this space group considered
    mv ./$busyfile ./$donefile
end
# return to launch directory again
cd $root_dir    


# check for still-running SOLVE jobs
ls SOLVE/*/$busyfile >& /dev/null
if(! $status) then
    echo "other SOLVE jobs will finish up latter..."
else
    # last one out should turn off the lights...
    rm -f SOLVE/*/$donefile >& /dev/null
endif




# check if SOLVE actually worked
echo ""
grep "TOP SOLUTION FOUND BY SOLVE" ./SOLVE/*/solve.status >& /dev/null
if($status) then
    echo "unable to run SOLVE"
    goto phaser
endif

# print out summary
echo "SOLVE summary:"
echo -n "" >! ${tempfile}
foreach SG ( $SGs ) 
    tail -300 SOLVE/${SG}/solve.status |&\
    nawk -v SG=$SG '/TOP SOLUTION/{fom=$8+0; zscore=$11+0; sites=0} \
	    ( ! /[^0-9 .-]/) && NF==7{ ++sites} \
	    /TIME REQUIRED/{printf "%-9s %d sites, fom = %4.2f, Z-score = %.2f\n", SG, sites, fom, zscore}' |\
    tail -1 >> ${tempfile}
end
# sort by SOLVE score
#sort -nr +8 ${tempfile} | tee ${tempfile}summary.txt
# sort by figure of merit
sort -nr +5 ${tempfile} | tee ${tempfile}summary.txt
rm -f ${tempfile} >& /dev/null

# now pick best space group / sites
set best_SG = `head -1 ${tempfile}summary.txt | nawk '{print $1}'`
set SGs = `nawk '{print $1}' ${tempfile}summary.txt`
# make sure all SGs are represented?
set sitefile = "./SOLVE/$best_SG/solve.status"

# watch for collisions?
mv ${tempfile}summary.txt SOLVE/Elves.summary.txt
cd $root_dir















phaser:
###############################################################################
# use Phaser Elves to refine/find atoms and calculate solvent-flattened phases
set STAGE = "phaser"

cd $root_dir

if($?NO_SOLVE) goto table1

if(! -e mtz/all.mtz) then
    echo "ERROR: no data for running Phaser! "
    goto wait_for_scaling
endif


# organize space group information
if("$SGs" == "") then
    # no user-specified space group order
    set SGs = ( $defaultSGs )
endif
if($?SG_order) then
    # enforce user-specified order
    set SGs = ( $SG_order )
endif


# default to Phaser finding atoms themselves
set site_source = " $sites"

# sites from other sources?
if("$sitefile" =~ *SOLVE*) then
    # use sites found by SOLVE
    set site_source = SOLVE
    set sitefile   = solve.status
endif
if("$sitefile" =~ *SHELX*) then
    # use sites found by shelx
#   Phaser Elves can do this themselves...
#    set site_source = SHELX
#    set sitefile   = best.res
endif
# sNb?

echo ""

# now run down the space group list
foreach SG ( $SGs ) 
    if(! -e ${root_dir}/phaser/$SG) continue
    cd ${root_dir}/phaser/$SG
    if($status) continue
    
    # check to see if another instance is running Phaser here
    if(-e ./$donefile) then
	echo "skipping $SG  already done "
	continue
    endif
    if(-e ./$busyfile) then
	cat ./$busyfile |\
	nawk '{printf "skipping %s  %s being run by pid=%s on %s\n", $1, $5, $3, $4}'
	continue
    endif
    # see if we have sites already or if Phaser should find its own
    set source = "../../${site_source}/$SG/$sitefile"
    if(! -e "$source") then
	# no sites available
	set source = "$sites"
    endif
    
    # indicate what we are doing in the "busy" file
    echo "phaser/$SG ${source} $$ $machine Phaser" >! ./$busyfile
    
    # check for collisions? 
    sleep 2
    set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
    if("$temp" != "$$ on $machine") then
	echo "collided with ${temp}! in phaser/$SG"
	echo "moving on..."
	continue
    endif
    
    # run Phaser
    echo ""
    echo "running Phaser on $site_source sites in $SG "
    echo "into "`pwd`"/Phaser.log"
    set temp = ""
    if($?HURRY_UP) set temp = "hurry"
    if(! $?SOLC) set SOLC = ""
    Phaser new ${source} sites and add more  $SG and no flip sg  ../../mtz/all.mtz $temp $SOLC >! ./Phaser.log
    mv ./$busyfile ./$donefile
end
# return to launch directory again
cd $root_dir    

    
# check for still-running Phaser jobs
ls phaser/*/$busyfile >& /dev/null
if(! $status) then
    echo "other Phaser jobs will finish up latter..."
else
    # last one out should turn off the lights...
    rm -f phaser/*/$donefile >& /dev/null
endif


# create an o macro for viewing ALL of the Phaser maps
find phaser -name allmaps.omac'*' -print |\
nawk '{split($1,w,"/"); SG=w[2];\
       print "! space group", SG; system("cat "$1)}' |\
nawk '/^! space group/{SG=$NF}\
      /^message/{gsub("flip",SG,$0)} {print}' |\
cat >! ${tempfile}allmaps.omacro

# avoid collisions?
mv -f ${tempfile}allmaps.omacro allmaps.omacro >& /dev/null

################################################################################
# sumarize phasing runs for the user

# locate the "best of the best_phased.mtz" files
find phaser -name best_phased.mtz -print >! ${tempfile}best_mtzs
find SOLVE -name '*solve*.mtz' -print >> ${tempfile}best_mtzs
set mtzs = `cat ${tempfile}best_mtzs | wc -l`
echo -n >! ${tempfile}best_FOMs
set i = 0 
while( $i < $mtzs )
    @ i = ( $i + 1 )
    set mtz = `nawk -v mtz=$i 'NR==mtz' ${tempfile}best_mtzs`
    set SG = `echo $mtz | nawk -F "/" '$2~/^[PCIFR][1-6]/{print $2}'`
    set SGnum = `nawk -v SG=$SG '$4 == SG {print $1}' $CLIBD/symop.lib | head -1`
    
    # add it to the list
    echo -n "$mtz " >> ${tempfile}best_FOMs
    
    # retrieve the most-recent FOM in the file
    echo "go" | mtzdump hklin "$mtz" |&\
    head -5000 |\
    nawk '/OVERALL FILE STATISTICS/,/LIST OF REFLECTIONS/{print} \
          /Space group/{print}' | nawk 'NF>5' |\
    nawk '/Space group/{SGnum=$NF;next} \
       $(NF-1)=="W"{print $NF, $(NF-4), SGnum}' |\
    sort -nr +1 >! ${tempfile}FOM
    set FOM = `nawk '{print $1;exit}' ${tempfile}FOM`
    set value = `nawk '{print $2;exit}' ${tempfile}FOM`
    if("$SG" == "") then
	set SGnum = `nawk '{print $3;exit}' ${tempfile}FOM`
	set SG = `nawk -v num=$SGnum '$1==num && NF>5{print $4}' ${CLIBD}/symop.lib`
    endif
    rm -f ${tempfile}FOM

    echo "$FOM $value $SG" >> ${tempfile}best_FOMs
end
sort -nr +2 ${tempfile}best_FOMs >! ${tempfile}best_mtzs
rm -f ${tempfile}best_FOMs >& /dev/null
echo ""
echo "mtz summary:"
nawk 'NF>=3{printf "%7s %s for %s\n", $2 "=", $3, $1}' ${tempfile}best_mtzs

# only one per space group...
cat ${tempfile}best_mtzs |\
nawk '! seen[$4]{print; seen[$4]=1}' |\
cat >! ${tempfile}
mv -f ${tempfile} ${tempfile}best_mtzs
set SGs = `nawk 'NF>=3{print $4}' ${tempfile}best_mtzs`

# make a copy of the "best" mtz to the local "mtz" directory
set best_mtz = `nawk '{print $1; exit}' ${tempfile}best_mtzs`
if(! -e "$best_mtz") then
    echo "WARNING: all attempts at phasing seem to have failed! "
    set best_mtz = mtz/all.mtz
    
    # eventually, this will exit gracefully
    rm -f ${tempfile}best_mtzs >& /dev/null
    goto table1
endif
# direct copy, links might be misleading
echo "copying ${best_mtz} to mtz/best_phased.mtz"

# watch out for collisions?
cp -f ${best_mtz} ${tempfile}best_mtz >& /dev/null
mv -f ${tempfile}best_mtz mtz/best_phased.mtz >& /dev/null



# set these up to be dropped into wARP
foreach SG ( $SGs )
    if(! -e wARP/${SG}) continue

    # find the best phasing solution for this space group
    set mtz = `nawk -v SG=$SG '$4==SG{print $1; exit}' ${tempfile}best_mtzs`
    set dir = `dirname "$mtz"`
    set fullname = `cd $dir ; pwd`/`basename "$mtz"`
    
    # links might be misleading?
    echo "linking ${mtz} to wARP/${SG}/best.mtz"
    rm -f wARP/${SG}/best.mtz >& /dev/null
    ln -sf ${fullname} wARP/${SG}/best.mtz >& /dev/null
end
rm -f ${tempfile}best_mtzs >& /dev/null











warp:
#################################################################################
# run wARP

set STAGE = warp
cd $root_dir
    
# check that wARP was found
if(! -e ./wARP/warp.runme) then
    echo "ARP/wARP is not set up"
    echo "see ./wARP/README"
    goto refmacer
endif

# start setting it up
nawk '/setenv warpbin/' ./wARP/warp.runme >! ${tempfile}sourceme
source ${tempfile}sourceme
rm -f ${tempfile}sourceme
if(! $?warpbin) set warpbin = ""
if(! -e "${warpbin}/arp_warp.sh") then
    echo "ARP/wARP is not set up"
    echo "see ./wARP/README"
    goto refmacer
endif

# set up the path
if("$path" !~ *${warpbin}*) set path = ( $warpbin $path )


# organize space group information
if("$SGs" == "") then
    # no user-specified space group order
    set SGs = ( $defaultSGs )
endif
if($?SG_order) then
    # enforce user-specified order
    set SGs = ( $SG_order )
endif

echo ""
echo "proceeding to model building stage"

# run in multiple space groups? (why not! )
foreach SG ( $SGs )
    if(! -e ${root_dir}/wARP/$SG) continue
    cd ${root_dir}/wARP/$SG
    if($status) continue
    
    # check to see if another instance is running wARP here
    if(-e ./$donefile) then
	echo "skipping $SG  already done "
	continue
    endif
    if(-e ./$busyfile) then
	cat ./$busyfile |\
	nawk '{printf "skipping %s  %s being run by pid=%s on %s\n", $1, $5, $3, $4}'
	continue
    endif
    
    if(! -e ./best.mtz) then
	echo "skipping $SG  no data file "
	continue
    endif

    #################
    # see what the phasing programs have left us
    set best_mtz = `ls -l best.mtz | nawk '{print $NF}'`
    set best_mtz = `echo $root_dir $best_mtz | nawk '{print substr($2,length($1)+2)}'`
    set best_pdb = ""
    if(-e ./best.pdb) then
	# we are doing molecular replacement
	set best_pdb = `ls -l best.pdb | nawk '{print $NF}'`
	set best_pdb = `echo $root_dir $best_pdb | nawk '{print substr($2,length($1)+2)}'`
    endif
    
    # get contents of the mtz
    echo "go" | mtzdump hklin ./best.mtz >! ${tempfile}mtzdump
    
    set reso = `nawk '/Resolution Range/{getline;getline;print $6}' ${tempfile}mtzdump`
    set reso_test = `echo $reso | nawk '$1+0 != 0 && $1+0 < 3.0{print "okay"}'`
    rm -f ${tempfile}mtzdump >& /dev/null

    # indicate what we are doing in the "busy" file
    echo "wARP/$SG $SG $$ $machine $STAGE " >! ./$busyfile
    
    # check for collisions? 
    sleep 2
    set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
    if("$temp" != "$$ on $machine") then
	echo "collided with ${temp}! in wARP/$SG"
	echo "moving on..."
	continue
    endif

    
    # now build a warp.par file
    # run the packaged set-up script
    ./setup_warp.com ./best.mtz ./best.pdb
    if($status) then
	# maybe someone else will have better luck?
	rm -f ./$busyfile >& /dev/null
	continue
    endif

    # decisions about monomers and side-chain building?
    set monomers = 1
    set side = side
    grep "side" warp.runme >& /dev/null
    if(($status)||($monomers > 1)) set side = ""
    
    # decide on a log-file name
    set i = 1
    while(-e warp${i}.log)
	@ i = ( $i + 1 )
    end
    echo -n "" >! warp${i}.log
    
    # rigid-body refinement?
    if(0 && -e "./rigid.com" && -e "./best.pdb") then
	echo "doing rigid body refinement into wARP/${SG}/logs/rigid.log"
	set shift = ""
	echo "<html>" >! logs/rigid.log
	set moving = 1
	while ($moving)
	    ./rigid.com files/molrep.pdb >>& logs/rigid.log
	    if(! -e rigid_body.pdb) break
	    cat files/molrep.pdb |\
	    nawk '/^ATOM/{++n;print n,substr($0,31,8),substr($0,39,8),substr($0,47,8)}' |\
	    cat >! ${tempfile}before.xyz
	    cat rigid_body.pdb |\
	    nawk '/^ATOM/{++n;print n,substr($0,31,8),substr($0,39,8),substr($0,47,8)}' |\
	    cat >! ${tempfile}after.xyz
	    cat ${tempfile}before.xyz ${tempfile}after.xyz |\
	    nawk 'X[$1]==""{X[$1]=$2;Y[$1]=$3;Z[$1]=$4;next} \
	       {print (X[$1]-$2)^2+(Y[$1]-$3)^2+(Z[$1]-$4)^2}' |\
	    cat >! ${tempfile}ms_shifts.txt
	    set shift = `nawk '{++n;sum+=$1} END{if(n) printf "%.3f", sqrt(sum/n)}' ${tempfile}ms_shifts.txt`
	    rm -f ${tempfile}before.xyz ${tempfile}after.xyz ${tempfile}ms_shifts.txt >& /dev/null

	    echo "moved $shift A"
	    set moving = `echo $shift 0.001 | nawk '{print ($1>$2)}'`
	    mv rigid_body.pdb files/molrep.pdb
	end
    endif
    
    if("$reso_test" != "okay" && ! -e "./best.pdb") then
	echo "skipping free-atom refinement in $SG  not enough resolution "
	mv ./$busyfile ./$donefile
	continue
    endif

    # only print this if nothing was printed above
    if(! -e "./best.pdb") then
	echo "running ARP/wARP on $best_mtz into wARP/${SG}/warp${i}.log"
    else
	echo "running ARP/wARP on $best_pdb into wARP/${SG}/warp${i}.log"
    endif

    # run the pre-defined script
    ./warp.runme >>& warp${i}.log
    
    if(($status)||(! -e files/warpNtrace.pdb)) then
	# didn't work... oh well
	echo "wARP run failed..."
	rm -f ./$busyfile >& /dev/null
	echo "please have a look at:"
	cd $root_dir
	ls -1rt wARP/${SG}/logs/* | tail -1
	continue
    endif
    mv ./$busyfile ./$donefile
end
# return to launch directory again
cd $root_dir    


# check for still-running wARP jobs
ls wARP/*/$busyfile >& /dev/null
if(! $status) then
    echo "other wARP jobs will finish up latter..."
else
    # last one out should turn off the lights...
    rm -f wARP/*/$donefile >& /dev/null
endif

date
echo ""


#########################################################################
# sumarize ARP/wARP runs for the user

# locate the files that led to the lowest R-factor
find wARP \( -name '*.pdb' -o -name '*.brk' \) -print |\
grep -v warp_free >! ${tempfile}pdbs
set pdbs = `cat ${tempfile}pdbs | wc -l`
echo -n >! ${tempfile}best_Rs
set i = 0 
while( $i < $pdbs )
    @ i = ( $i + 1 )
    set pdb = `nawk -v line=$i 'NR==line' ${tempfile}pdbs`
    
    # find the log file that created this
    set dir = `dirname "$pdb"`
    set dir = `dirname "$dir"`
    set prefix = `basename "$pdb" .pdb`
    set log = `ls -1t ${dir}/logs |& egrep "^$prefix" | nawk '/.log$/{print;exit}'`
    if("$log" == "") continue
    set log = "${dir}/logs/$log"
    set R     = `tail -10000 $log | nawk '/all[_ ]R[_ ]factor/{print $NF}' | tail -1`
    set Rfree = `tail -10000 $log | nawk '/ree[_ ]R[_ ]factor/ && ! /DPI/{print $NF}' | tail -1`
    if ("$R" == "") then
	set R     = `cat $log | nawk '/all[_ ]R[_ ]factor/{print $NF}' | tail -1`
	set Rfree = `cat $log | nawk '/ree[_ ]R[_ ]factor/ && ! /DPI/{print $NF}' | tail -1`
    endif
    set SGnum = `nawk '/Space group/ && $NF+0>0{print $NF+0;exit}' $log`
    set SG = ` nawk -v num=$SGnum '$1==num && NF>5{print $4}' ${CLIBD}/symop.lib `
    
    if(("$R" == "")||("$Rfree" == "")||("$SG" == "")) continue
    # make a list
    echo "$pdb $SG $R $Rfree $log " >> ${tempfile}best_Rs
end
sort -n +2 ${tempfile}best_Rs | nawk 'NF>=3' |\
nawk 'BEGIN{FS="/"} ! seen[$2]{print; seen[$2]=1}' |\
cat >! ${tempfile}best_pdbs
# format: pdbfile SG R Rfree log

rm -f ${tempfile}best_Rs ${tempfile}pdbs >& /dev/null
echo ""
echo "wARP summary:"
nawk 'NF>=3{printf "R/Rfree = %s/%s for %s\n", $3, $4, $1}' ${tempfile}best_pdbs
set SGs = `nawk 'NF>=3{print $2}' ${tempfile}best_pdbs`

# make a copy of the "best" pdb to the local "pdb" directory
set best_SG  = `nawk '{print $2; exit}' ${tempfile}best_pdbs`
set best_log = `nawk '{print $5; exit}' ${tempfile}best_pdbs`
set best_pdb = `nawk '{print $1; exit}' ${tempfile}best_pdbs`
mv ${tempfile}best_pdbs wARP/Elves.summary.txt

if(! -e "$best_pdb") then
    echo "WARNING: all wARP runs seem to have failed! "
    set best_pdb = ""
    set best_mtz = ""
    
    # eventually, this will exit gracefully
    goto table1
endif
# direct copy, links might be misleading
echo "copying $best_pdb to pdb/best.pdb"

# watch out for collisions?
if(! -e ./pdb) mkdir pdb
cp -f $best_pdb ${tempfile}best >& /dev/null
mv -f ${tempfile}best pdb/best.pdb >& /dev/null


# check for the map
set best_mapdir = `dirname $best_pdb`
set prefix = `basename $best_pdb .pdb`
set prefix = `basename $prefix .brk`
set best_map = `ls -1rt $best_mapdir | grep $prefix | awk '/.map$/'`
if("${best_map}" != "" ) set best_map = ${best_mapdir}/${best_map}

# watch out for collisions?
echo "copying $best_map to maps/best.map"
if(! -e ./maps) mkdir maps
cp -f $best_map ${tempfile}best >& /dev/null
mv -f ${tempfile}best maps/best.map >& /dev/null


# check for the refined mtz
set best_mtzdir = `dirname $best_pdb`
set prefix = `basename $best_pdb .pdb`
set prefix = `basename $prefix .brk`
set best_mtz = `ls -1rt $best_mtzdir | grep $prefix | awk '/.mtz$/'`
if("${best_mtz}" != "" ) set best_mtz = ${best_mtzdir}/${best_mtz}

# watch out for collisions?
echo "copying $best_mtz to mtz/best.mtz"
if(! -e ./mtz) mkdir mtz
cp -f $best_mtz ${tempfile}best >& /dev/null
mv -f ${tempfile}best mtz/best.mtz >& /dev/null



refmacer:
#################################################################################
# run Refmacer to set things up?
set STAGE = refmac
cd $root_dir    

# safety catches
if(! $?best_mtz) set best_mtz 
if(! $?best_pdb) set best_pdb
if(! $?best_SG)  set best_SG 
if("$best_SG" == "") set best_SG = P1
if(! -e "$best_pdb") set best_pdb = pdb/best.pdb
if(! -e "$best_mtz") set best_mtz = mtz/best_phased.mtz
if(! -e "$best_mtz") set best_mtz = mtz/all.mtz
if(! -e "$best_mtz") then
    echo "ERROR: no data available! "
    goto scale
endif

foreach dir ( refmac )

    echo "cd $dir"
    cd $root_dir
    cd $dir

    if(-e ${dir}/$donefile) continue
    if(-e ./$busyfile) continue
    
    if((! -e "../$best_mtz")||(! -e "../$best_pdb")) then
	echo "skipping refmac setup, no data files "
	echo "run:"
	echo "./Elfsheim/Refmacer best.mtz best.pdb"
	echo "when you have a partially-built structure."
	echo ""
	continue
    endif

    # claim refmac set-up with a "busy" file
    echo "refmac $best_SG $$ $machine $STAGE" >! ./$busyfile
    
    # check for collisions? 
    sleep 2
    set temp = `nawk '{print $3, "on", $4}' ./$busyfile`
    if("$temp" != "$$ on $machine") then
	echo "collided with ${temp}! in refmac"
	echo "moving on..."
	continue
    endif

    # just run the set-up routine
    Refmacer ../$best_mtz ../$best_pdb
    
    # run the script too?
    # ./scripts/converge.com
    mv ./$busyfile ./$donefile
end
cd $root_dir

# remove busy signal to rest of instances
sleep 10
if(! -e refmac/$busyfile) rm -f refmac/$donefile >& /dev/null


table1:
#################################################################################
# display final statistics
cd $root_dir
if(! -e scripts/table1.com) then
    goto cleanup
endif

# run the "table 1" summarizer script
if(! $?best_mtz) set best_mtz = "mtz/all.mtz"
if(! $?best_pdb) set best_pdb = ""
if(! $?best_SG)  set best_SG  = P1
if(! $?best_log) set best_log = ./wARP/${best_SG}/logs/molrep.log
set mlpharelog = `dirname "$best_mtz"`
set mlpharelog = `dirname "$mlpharelog"`"/logs/mlphare.log"
scripts/table1.com $best_mtz $best_log $best_pdb $mlpharelog | tee table1.txt



if($?HURRY_UP) then
    # done with "hurried" processing,
    # so go back and do a more thorough job
    date
    echo '"Hurried" processing complete.'
    if($?ONLYHURRY) exit
    echo "Elves will now go back to the beginning,"
    echo "but, this time, every parameter will be"
    echo "carefully optimized."
endif
if($?PROBLEMS) then
    echo "since there were problems in processing,"
    echo "Elves will now go back to the beginning."
    echo "Hopefully, we will have better luck this time."
endif
if(($?HURRY_UP)||($?PROBLEMS)) then
    set STAGE = "refining"
    unset HURRY_UP
    unset PROBLEMS
    date
    goto again
endif


echo "Thank you, drive through! "
exit

cleanup:
# still in wedge directory?
rm -f ./$busyfile >& /dev/null
exit


Setup:
################################################################################
echo -n "" >! ${tempfile}wedges
echo -n "" >! ${tempfile}not_these

# set any default values of variables


# scan command line for options and directories
set i = 0
while ( $i < $#argv )
    @ i = ( $i + 1 )
    @ nexti = ( $i + 1 )
    @ lasti = ( $i - 1 )
    if($nexti > $#argv) set nexti = $#argv
    if($lasti < 1) set lasti = 1
    
    # cache different case combinations
    set Arg = `echo "$argv[$i]" | nawk '/^-/{print substr($0,2);exit} {print}'`
    set arg = `echo "$Arg" | nawk '{print tolower($1)}'`
    set ARG = `echo "$Arg" | nawk '{print toupper($1)}'`
    
    if(("$arg" == "no")||("$arg" == "not")||("$arg" =~ *"n't")) then
	set NO
	continue
    endif
    
    # recognize space groups
    if("$ARG" =~ [PCIFR][1-6]*) then
	set SG = `nawk -v SG=$ARG '$4==SG {print $4; exit}' ${CLIBD}/symop.lib`
	if("$SG" == "") then
	    # recognize non-standard SGs
	    set SG = `echo "$ARG" | nawk '$1=="P22121" || $1=="P21221" || /^[PC]2122$/ || /^[PC]2212$/ {print}'`
	endif
	if("$SG" != "") then
	    # user-specified space group
	    set SGs = ( $SGs $SG )
	endif
    endif
    
    # assume args begginning with numbers are numbers
    if("$arg" =~ [0-9]*) then
	# we have a number
	if(("$Arg" =~ *A)||("$argv[$nexti]" == "A")) then
	    # user-preferred resolution limits
	    set temp = `echo "$arg" | nawk 'BEGIN{FS="-"} $1+0 > 0.1{print $1+0} $2+0 > 0.1{print $2+0}'`
	    if($#temp != 1) then
		set temp = `echo $temp | nawk '$1>$2{print $1, $2} $2>$1{print $2, $1}'`
		if($#temp == 2) then
		    # a range 3-10A is a resolution
		    set USER_hires = `echo "$temp[2]" | nawk '{print $1+0 "A"}'`
		    continue
		endif
	    else
		# single 1.8A is just high resolution
		set USER_hires = `echo "$arg" | nawk '{print $1+0 "A"}'`
		continue
	    endif
	endif
    endif
    
    # "fix" options words
    if("$arg" == "fix") then
	set FIX
	continue
    endif
#    if("$arg" == "refine") then
#	set FIX
#	set NO
#	continue
#    endif
    
    if($?NO) then
	# user said "no" to this arg

        if("$arg" == alone) unset ALONE
        if(("$arg" == reset)||("$arg" =~ restart*)||("$arg" =~ reinit*)||("$arg" =~ init*)) then
	    if("$STAGE" == "restarting") then
		set STAGE = "testing"
		set USER_STAGE
	    endif
        endif
        if("$arg" =~ test*) then
	    set STAGE = "refining"
	    set USER_STAGE
        endif
	if("$arg" =~ hurry*) unset HURRY_UP
	if("$arg" == "nice") unset NICE
	if("$arg" == "local") unset LOCAL
	if("$arg" == "refind") set REFIND_IMAGES = no
	if(($?FIX)&&("$arg" == "cell")) then
	    set CELL = ""
	    if("$STAGE" == "polishing") then
		set STAGE = "refining"
		set USER_STAGE
	    endif
	endif
        if("$arg" == solve) then
	    set NO_SOLVE
	    if("$STAGE" == "solve") then
		set STAGE = "warp"
		set USER_STAGE
	    endif
	endif
	if("$arg" == "warp") then
	    set NO_WARP
	endif
    else
	# the "NO" state is not set
	
        if("$arg" == alone) set ALONE
        if("$arg" == clean) set CLEAN
	if("$arg" == new)   set CLEAN
	if("$arg" == new) then
	    set STAGE = "restarting"
	    set USER_STAGE
	endif
        if("$arg" == reset) then
	    set STAGE = "restarting"
	    set USER_STAGE
        endif
	if("$arg" =~ restart*) then
	    set STAGE = "restarting"
	    set USER_STAGE
	endif
	if("$arg" =~ reinit*) then
	    set STAGE = "restarting"
	    set USER_STAGE
	endif
	if("$arg" =~ init*) then
	    set STAGE = "restarting"
	    set USER_STAGE
        endif
	if("$arg" == refine) then
	    set STAGE = "refining"
	    set USER_STAGE
        endif
	if("$arg" == solve) then
	    set STAGE = "solve"
	    set USER_STAGE
	endif
	if("$arg" == warp) then
            set STAGE = "warp"
            set USER_STAGE
        endif
	if(($?FIX)&&("$arg" == "cell")) then
	    set STAGE = "polishing"
	    set USER_STAGE
	endif
	if("$arg" =~ hurry*) set HURRY_UP
	if("$arg" =~ hurry*) unset NICE
	if("$arg" == "nice")   set NICE
	if("$arg" == "local") set LOCAL
	if("$arg" == "refind") set REFIND_IMAGES = always
    endif
    
    # add directories to wedge list
    if(-e "$Arg") then
	# pure directory
	test -d "$Arg"
	if(! $status) then
	    if(! $?NO) then
		echo "$Arg" >> ${tempfile}wedges
	    else
		echo "$Arg" >> ${tempfile}not_these
	    endif
	    continue
	endif
	
	# molecular replacement targets
	if(("$arg" =~ *.pdb)||("$arg" =~ *.brk)) then
	    grep "ATOM" "$Arg" >& /dev/null
	    if(! $status) then
		set search_models = ( $search_models $Arg )
		continue
	    endif
	endif
	
	# directories of mosflm files
	grep "IMAGE" "$Arg" >& /dev/null
	if(! $status) then
	    if(! $?NO) then
		dirname "$Arg" >> ${tempfile}wedges
	    else
		dirname "$Arg" >> ${tempfile}not_these
	    endif
	    continue
	endif
    endif
    
    unset NO
end


# now organize any wedge directories the user may have indicated

set wedge_dirs = `nawk 'NF==1' ${tempfile}wedges | wc -l`
if(! $wedge_dirs) then
    # look in standard places for wedge directories
    ls */wedge*/mosflm.com */wedge*/start |&\
    nawk 'NF==1' | nawk 'BEGIN{FS="/"} \
        {for(i=1;i<NF;++i) printf "%s/", $i; print ""}' |\
    sort -u >! ${tempfile}wedges
endif


# default to Elves expected wedge directories
set wedge_dirs = `nawk 'NF==1' ${tempfile}wedges | wc -l`
if(! $wedge_dirs) then
    # scan for set-up wedge directories
    find . \( -name mosflm.com -o -name start \) -print |&\
    nawk 'NF==1' | nawk 'BEGIN{FS="/"} \
        {for(i=2;i<NF;++i) printf "%s/", $i; print ""}' |\
    sort -u >! ${tempfile}wedges
endif

# now remove any undesirables
set lines = `nawk 'NF==1' ${tempfile}not_these | wc -l`
set line = 1
while($line <= $lines)
    # retrieve name from file
    set baddie = `nawk -v line=$line 'NR==line' ${tempfile}not_these`
    # remove leading "./"
    set baddie = `echo $baddie | nawk '/^\.\//{$0=substr($0,3)} {print}'`

    egrep -v "^$baddie" ${tempfile}wedges |\
    egrep -v "^./$baddie" >! ${tempfile}filtered
    mv ${tempfile}filtered ${tempfile}wedges >& /dev/null

    @ line = ( $line + 1 )
end
rm -f ${tempfile}not_these >& /dev/null

# now promote the wedge list to a variable
set wedge_dirs = ""
set lines = `cat ${tempfile}wedges | wc -l`
set line = 1
while($line <= $lines)
    # get directory name
    set wedge = `nawk -v line=$line 'NR==line' ${tempfile}wedges`
    # remove leading "./" and trailing "/"
    set wedge = `echo $wedge | nawk '/^\.\//{$0=substr($0,3)} /\/$/{$0=substr($1, 1, length($1)-1)} {print}'`
    
    # add it to the master list
    set wedge_dirs = `echo "$wedge_dirs $wedge" | nawk '{L+=length($0)+1} L<1000{print}'`
    @ line = ( $line + 1 )
end 
rm -f ${tempfile}wedges


# remember that user specified space groups
if("$SGs" != "") then
    set SG_order = ( $SGs )
endif


goto Return_From_Setup

exit


#########################################
# Future plans:
- unify with Elves MCP
- run dm/fft/mapman after solve?
- run Spotter
- run moviefy?




