#! /bin/tcsh -f # echo "Elves v 1.3.6 Because you have better things to do.(TM) James Holton 7-15-16" echo "" # # go to: # http://bl831.als.lbl.gov/~jamesh/elves/session.html # to figure out what to do with this file # # if($#argv == 0) goto Help set temp = `find $0 -mtime +30 -print` if("$temp" == "") cat << EOF-lawyers Copyright ©1999. The Regents of the University of California (Regents). All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research, and not-for-profit purposes, without fee and without a signed licensing agreement, is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies, modifications, and distributions. Contact The Office of Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley, CA 94720-1620, (510) 643-7201, for commercial licensing opportunities. Created by James Holton, Department of Molecular and Cell Biology, University of California, Berkeley. IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. EOF-lawyers # goto Config Help: ################################################################################ # # ###### # ##### # # # # # # ###### ##### # # # # # # # ##### # # # # # # # ###### ###### # ################################################################################ # Help routine ################################################################################ cat << EOF usage: $0 [/your/frames/] [wedge.list] [my.seq] [PRTEINSEQENCE] [Space Group] where: /your/frames/ - is (one or more) directory containing x-ray images Space Group - your space group. i.e. P212121 PRTEINSEQENCE - your protein's sequence my.seq - your protein's sequence (in a file) OR wedge.list - is a text file formatted like this: directory Energy First_frame total phi0 osc dist 2theta x_beam y_beam fpp 12658.8 /data/frame_1_001.img 120 0.0 1.0 190.00 -20 92.20 88.70 etc ... or, at least: directory First frame fpp /data/se_1_001.img fpp /data/se_101_001.img fp /data/se_2_001.img etc... Just make sure your titles are vertically aligned with the table entries EOF exit 9 Config: ############################################################################### # # Evaluate unix system # ############################################################################### # make sure nawk works set program = "nawk" foreach name ( nawk awk gawk ) test -x "$program" if(! $status) break set possibilities = `which $name |& grep -v ' not in ' | tail -1` foreach file ( $possibilities ) test -x "$file" if(! $status) then # test for desired functionality (change this?) set temp = `echo "1.54" | $file '{printf("%3d", 3147.7 * ( $1 )^(-3.014))}' |& cat` if("$temp" == 856) then set program = "$file" break endif endif end unset possibilities end test -x "$program" if($status) then set program = "awk" foreach place ( /bin /usr/bin /usr/local/bin ) test -x "$program" if(($status)&&(-e $place)) then # keep looking set files = `ls -1L ${place} |& grep "$program" |& sort -k5nr |& head -20 ` foreach file ( $files ) # test for desired functionality set temp = `echo "1.54" | $file '{printf("%3d", 3147.7 * ( $1 )^(-3.014))}' |& cat` if("$temp" == 856) then set program = "$file" break endif end endif end endif # agressively search for nawk in likely places test -x "$program" if($status) then echo -n "Looking for $program " foreach place ( /bin /usr/bin /usr/local/bin /usr / ) test -x "$program" if(($status)&&(-e $place)) then if("$place" == "/") echo -n "uhh" # use find to get candidate files set files = `find $place -name '*'$program \( -type l -o \( -type f -size +10000c \) \) -perm -1 -print |& egrep -v "^find:" |& head -20` foreach file ( $files ) # test for desired functionality set temp = `echo "1.54" | $file '{printf("%3d", 3147.7 * ( $1 )^(-3.014))}' |& cat` if("$temp" == 856) then set program = "$file" break endif end endif # entertainment echo -n "." end endif # check that we found the right awk program set temp = `echo "1.54" | $program '{printf("%3d", 3147.7 * ( $1 )^(-3.014))}' |& cat` if("$temp" == 856) then # set up this awk program as nawk set nawk = "$program" alias nawk $nawk else echo "Dagnabbit! We can't find a suitable awk program. What kind of unix is this? " echo "Elves may not be able to work." set nawk = /bin/awk alias nawk awk endif # nice symbols, but may not be portable set ANG = `echo "" | nawk 'BEGIN{printf "\305"}'` set DEG = `echo "" | nawk 'BEGIN{printf "\260"}'` # I give up... set ANG = "A" set DEG = "deg" set PROMPT = "Elves-> " set BELL = `echo "" | awk 'BEGIN{printf "\07"}'` # fix OSF1 csh echo shortcomings set temp = `echo -n "test"` if(($#temp == 2)&&(-e /usr/bin/echo)) then alias echo /usr/bin/echo endif ############################################################################### if(! $?CCP4) then echo -n "Attempting to set up CCP4 ... " onintr Skip_CCP4_search set ccp4setup = "" foreach place ( /programs/xtal/ccp4_3.4/ /usr/xtal/CCP4_v3.4/ /programs/xtal /programs/ /usr/xtal /usr/local /usr/ ) if((! -e "$ccp4setup")&&(-e "$place")) then # look for setup scripts here set ccp4setup = `find ${place} -name ccp4.setup |& nawk '/ccp4.setup$/{print $NF}' | tail -1` endif if((-e "$ccp4setup")&&(! $?CCP4)) then source $ccp4setup setenv CCP4_SCR . setenv BINSORT_SCR . echo "using $ccp4setup" endif end endif Skip_CCP4_search: onintr if(! $?CCP4) then echo "failed." cat << EOF-getccp4 >! ./getccp4.com #! /bin/csh -f # # # Script for automatically retrieving ccp4 # from the MRC ftp site # # # # see what kind of system this is set uname = \`uname | awk '{print tolower(\$1)}'\` set pwd = \`pwd\` if("\$uname" == "IRIX") then set uname = \`uname | nawk '{print tolower(\$1)}'\` endif if("\$uname" == "irix") then # doesn't support mmcif set uname = "\$uname --disable-ccif" endif set gunzip = "gunzip" set fsplitURL = "http://src.doc.ic.ac.uk/computing/systems/unix/bsd-sources/usr.bin/fsplit" set ftpsite = "ccp4a.dl.ac.uk" set ftpdir = "pub/ccp4/ccp4/" set tarfile = "ccp4-4.1.1.tar.gz" set dirname = \`basename \$tarfile .tar.gz\` if(-e "\$1") then set tarfile = \`basename \$1\` echo "copying \$1 to \$tarfile" cp \$1 . echo "decompressing \$tarfile" goto decompress endif if(("\$1" =~ compile*)||("\$2" =~ compile*)) then goto compile endif retrieve: # now figure out how we're going to retrieve the file echo "retrieving \$tarfile from \${ftpsite}/\$ftpdir" rm -f \$tarfile >& /dev/null wget --passive-ftp ftp://\${ftpsite}/\${ftpdir}/\$tarfile >& /dev/null if((! \$status)&&(-e \$tarfile)) goto decompress # wget didn't work, try ncftpget ncftpget \${ftpsite} . \${ftpdir}/\$tarfile >& /dev/null if((! \$status)&&(-e \$tarfile)) goto decompress # dangerous! try using regular ftp: # confirm? if(-e ~/.netrc) then mv ~/.netrc ~/netrc.bak\$\$ set RESTORE_NETRC endif onintr restore_netrc echo "default login anonymous password user@site" >! ~/.netrc chmod go-rwx ~/.netrc ftp \$ftpsite << EOF get \${ftpdir}/\$tarfile \$tarfile close bye EOF restore_netrc: onintr if(\$?RESTORE_NETRC) then mv ~/netrc.bak\$\$ ~/.netrc else rm -f ~/.netrc >& /dev/null endif # check if transfer worked if(! -e "\$tarfile") then echo "transfer failed..." echo "perhaps the server is overloaded? " exit 9 endif decompress: ########################################################################## set uncompressed = \`basename \$tarfile .gz\` rm -f \$uncompressed >& /dev/null foreach unzip ( \$gunzip unzip "gzip -d" /bin/gunzip /usr/bin/gunzip uncompress ) \$unzip \$tarfile >& /dev/null if((! \$status)&&(-e "\$uncompressed")) break end untar: # un-tar the system tar xf \$uncompressed if(\$status) then echo "unable to decompress archive! " echo "is \$uncompressed corrupt?" exit 9 endif if(-e "\$dirname") then cd \$dirname set pwd = \`pwd\` endif setup: ########################################################################## # fix up the ccp4.setup file cat include/ccp4.setup-dist |\\ awk '\$1=="setenv" && \$2=="CCP4_MASTER"{print; \$3 = "'\`dirname \$pwd\`'"}\\ \$1=="setenv" && \$2=="CCP4" {print; \$3 = "\$CCP4_MASTER/'\`basename \$pwd\`'"}\\ \$1=="setenv" && \$2=="CCP4_SCR" {print; \$3 = "."}\\ \$1=="setenv" && \$2=="BINSORT_SCR"{print; \$3 = "."}\\ {print}' |\\ cat >! include/ccp4.setup # patches/fixes... # anything else? compile: ########################################################################## # configure the configurator echo "configuring CCP4...(logging to \${pwd}/compile.log)" source include/ccp4.setup # run the configurator echo "% ./configure \$uname --with-x" ./configure \$uname --with-x | tee \${pwd}/compile.log if(\$status) then cat compile.log cat << EOF Sorry, CCP4 build failed. Please follow the above instructions. Then type: cd \$pwd ./configure \$uname --with-x make -i make install EOF exit 9 endif # now try to build CCP4! echo "compiling CCP4...(logging to \${pwd}/compile.log)" echo "% make -i" make -i >>& compile.log if(\$status) then tail -200 compile.log echo "Sorry, CCP4 build failed. Please fix the above problem." echo "Then type:" echo "make -i" echo "make install" exit 9 endif echo "installing CCP4 under \${pwd}" echo "% make install" make install >>& compile.log if(\$status) set BAD_COMPILE # try to compile ancillary/optional programs echo "compiling ccp4mapwish" cd ./src/ccp4mapwish_ ./configure \$uname cd ../.. cp ./ccp4i/bin/mapslicer ./bin cp ./ccp4i/bin/loggraph ./bin # make SURE installation worked unset BAD #echo "" | bin/mapmask >& /dev/null #if(\$status > 3) set BAD if(\$?BAD) then echo "some programs failed to run properly." echo "you might want to examine compile.log carefully" goto done endif echo "SUCCESS! " goto done done: cat << EOF Before you do anyting else, please fill out the CCP4 license form: \${pwd}/license.txt or ftp://ccp4a.dl.ac.uk/pub/ccp4/licence.txt print it out, fill it in, and mail it to: Secretary to CCP4 Daresbury Laboratory Warrington WA4 4AD UK when you have done this, press "Enter" -> EOF set temp = ( \$< ) cat << EOF to use CCP4, type: % source \${pwd}/include/ccp4.setup or, put the above command in your .cshrc to rebuild CCP4: make whatever changes you want % cd \$pwd % source include/ccp4.setup % ./configure \$uname --with-x % make EOF exit EOF-getccp4 chmod a+x ./getccp4.com ###################################################### set temp = "Yes" if($?AUTO) set temp = "No" echo "shall we retrieve CCP4 from ccp4a.dl.ac.uk" echo "using anonymous FTP? [$temp]" if(! $?AUTO) then echo -n "$PROMPT" echo -n "$BELL" set temp = ( $< ) else set temp = "" endif if("$temp" !~ [Nn]*) then ./getccp4.com if(! $status) then source include/ccp4.setup setenv CCP4_SCR . setenv BINSORT_SCR . endif else echo "Okay, you can run the script called: ./getccp4.com" echo "to automatically retrieve the latest version of CCP4" echo "it's probably best if you do this as root, in a shared directory." endif endif if(! $?CCP4) then cat << EOF failed. Please ask your sysadmin how to set up CCP4, Or go to: netscape http://www.dl.ac.uk/CCP/CCP4/main.html about getting the CCP4 program suite. and run $0 again. If your system supports rpm, you can: rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-lib-3.5.1-5.i386.rpm rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-progs-3.5.1-5.i386.rpm rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-etc-3.5.1-5.i386.rpm rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-examples-3.5.1-5.i386.rpm rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-doc-3.5.1-5.i386.rpm rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-manual-3.5.1-5.i386.rpm rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-html-3.5.1-5.i386.rpm EOF exit 9 set CCP4_LIB endif setenv CCP4_OPEN UNKNOWN if(! $?CCP4_SCR) setenv CCP4_SCR . if(! $?BINSORT_SCR) setenv BINSORT_SCR . # make sure we can write to scratch directories touch ${CCP4_SCR}/this$$ >& /dev/null if($status) then # safest to do this setenv CCP4_SCR . else rm -f ${CCP4_SCR}/this$$ >& /dev/null endif touch ${BINSORT_SCR}/this$$ >& /dev/null if($status) then # safest to do this setenv BINSORT_SCR . else rm -f ${BINSORT_SCR}/this$$ >& /dev/null endif # check that current directory is writable touch ./this$$ >& /dev/null if($status) then # can't write to current directory! chmod u+w . >& /dev/null touch ./this$$ >& /dev/null if($status) then # can't chmod current directory either echo "ERROR! We can't write to this directory! " pwd echo "Please cd to the place you want to process your data, and" echo "then run $0 again." exit 9 else # warn user about what we did echo "Had to make current directory writable:" echo "chmod u+w ." endif rm -f ./this$$ >& /dev/null endif rm -f ./this$$ >& /dev/null # check/set system variables set machine = `hostname -s` set user = `whoami` # Linux if(-e /proc/cpuinfo) set CPUs = `grep processor /proc/cpuinfo |& wc -l` # OSF1 if(-e /usr/sbin/psrinfo) set CPUs = `/usr/sbin/psrinfo |& wc -l` # SGI if(-e /usr/sbin/mpadmin) set CPUs = `/usr/sbin/mpadmin -n |& wc -l` if(! $?CPUs) then # Sun uname -X >& /dev/null if(! $status) set CPUs = `uname -X | nawk '/CPU/{print $NF}'` endif if(! $?CPUs) set CPUs = 1 if($?ONLYHURRY) set CPUs = 1 # check free disk space set freespace = `df -k $CCP4_SCR |& nawk 'NR>=2&&NF>2{avl=NF-2;print $avl/1024}'` set test = `echo $freespace 100 | nawk '{print ($1<$2)}'` if($test) echo "WARNING: "'$'"CCP4_SCR is getting full! ${freespace}MB left. " set freespace = `df -k $BINSORT_SCR |& nawk 'NR>=2&&NF>2{avl=NF-2;print $avl/1024}'` set test = `echo $freespace 100 | nawk '{print ($1<$2)}'` if($test) echo "WARNING: "'$'"BINSORT_SCR is getting full! ${freespace}MB left." set freespace = `df -k . |& nawk 'NR>=2&&NF>2{avl=NF-2;print $avl/1024}'` set test = `echo $freespace 100 | nawk '{print ($1<$2)}'` if($test) echo "WARNING: disk space is getting low! ${freespace}MB left. " # no dumping! limit coredumpsize 0 # go automatic if user is ignoring us test -t 1 if($status) then echo "output is not a terminal." # Q&A would stop process cold echo "Elves will answer their own questions." echo "" echo "$0 $*" echo "on "`hostname -s`" at "`date +"%T %D"` echo "in "`pwd` set AUTO endif ############################################################################### # # Defaults # ############################################################################### # # crystal variables (stuff we can't find in frame headers) set SGs = "" set CELL = "unknown" set hiRES = "" set MolWT = "unknown" set METAL = "" set SITES = "" set search_models = "" # # Files generated by this script set wedgefile = wedges.txt #set tempfile = $CCP4_SCR/tempfile set tempfile = `pwd`"/tempfile." set busyfile = busy set donefile = done # where the Elves live set Elfsheim = `pwd`/Elfsheim set SCRIPT_dir = ./scripts/ # random internal settings set MAXLINE = 500 set FIRSTIME set HURRY = "" set temp set input set info set understood set in set bad_frames = "" set runlist = "" set ADSC_LOGFILE = "" # list of valid image filename extensions set IMAGE_pattern = '/[0-9][0-9][0-9].img$/ || /[0-9][0-9][0-9].osc$/ || /[0-9][0-9][0-9].image$/ || /[0-9][0-9][0-9].mar/ || /.[0-9][0-9][0-9][0-9]$/ || /[0-9][0-9][0-9].corr$/ || /[0-9][0-9][0-9].cbf$/' set IMAGE_pattern = 'BEGIN{FS="."} {n=NF-1;if(n<1)n=1} $n~/[0-9][0-9][0-9]$/ || $NF~/[0-9][0-9][0-9]$/{print}' # clear any old temporary files rm -f ${tempfile}* >& /dev/null goto Unwrap_Awk_Scripts # create ${tempfile}reformat.awk # create ${tempfile}labler.awk # create ${tempfile}sequence.awk # create ${tempfile}elements.awk RetrnUnwrap_Awk_Scripts: ############################################################################### # # Process command line # ############################################################################### set input = " $* " touch ${tempfile}wedges Gather: set understood = "" ############################################################################### #### ## ##### # # ###### ##### # # # # # # # # # # # # # # ###### ##### # # # ### ###### # # # # ##### # # # # # # # # # # #### # # # # # ###### # # ############################################################################### # # Gather info indicated in $input # ############################################################################### foreach arg ( $input ) # check for directories set framedir = `ls -lnLd $arg |& nawk '/^d/{print $NF}'` if(-e "$framedir") then # convert to absolute pathname set framedir = `cd $framedir; pwd` # neurotic set framedir = `echo "${framedir}/" |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1` endif if((-e "$framedir")&&(-e ${framedir}/LOGFILE)) then # see if this is a valid ADSC LOGFILE (describing run in progress) set temp = `cat ${framedir}/LOGFILE | nawk -f ${tempfile}reformat.awk | wc -l` if("$temp" >= 1) then # interpret this later set arg = ${framedir}/LOGFILE set framedir = "" set USEFUL endif endif endif if(-e "$framedir") then # add contents of this directory to our master list of frames: echo -n "Examining frames in $framedir ." ls -lnL $framedir |\ nawk '/^\-/ && $5+0 > 1000000 {print $NF}' |\ nawk "$IMAGE_pattern" |\ nawk -v dir=$framedir '{print dir $1}' |\ cat >! ${tempfile} set temp = `cat ${tempfile} | wc -l` if("$temp" == 0) then echo ".. none found. " rm -f ${tempfile} else mv ${tempfile} ${tempfile}frames set understood = "$understood $framedir" endif else # may be a partial filename if("$arg" =~ */*) then set framedir = `dirname $arg |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1` set prefix = `basename $arg` # add absolute pathname (if necessary) if($framedir !~ /*) set framedir = `cd $framedir ; pwd` # add this directory to our master list of frames: ls -lnL $framedir |&\ nawk '/^\-/ && $5+0 > 1000000 {print $NF}' |&\ nawk "$IMAGE_pattern" |&\ egrep "^$prefix" |&\ nawk -v dir=$framedir '{print dir "/" $1}' |&\ cat >! ${tempfile} set test = `cat ${tempfile} | wc -l` if("$test" == 1) then # exactly one file matched... set file = `cat ${tempfile}` set file = `basename $file` set test = `echo $file $prefix | nawk '{print ($1==$2)}'` if("$test" == 1) then # trim off part of the filename? set newprefix = `echo $prefix | awk '/001\.image$/{$0=substr($0,1,length($0)-9)} {print}'` set newprefix = `echo $newprefix | awk '/001\.corr$/{$0=substr($0,1,length($0)-8)} {print}'` set newprefix = `echo $newprefix | awk '/001$/{$0=substr($0,1,length($0)-4)} {print}'` set newprefix = `echo $newprefix | awk '/001\.img$/ || /001\.osc$/ || /001\.mar$/ || /001\.cbf$/{$0=substr($0,1,length($0)-7)} {while(gsub("[0-9]$",""));print}'` if("$newprefix" != "" && "$newprefix" != "$prefix") then set prefix = $newprefix ls -lnL $framedir |&\ nawk '/^\-/ && $5+0 > 1000000 {print $NF}' |&\ nawk "$IMAGE_pattern" |&\ egrep "^$prefix" |&\ nawk -v dir=$framedir '{print dir "/" $1}' |&\ cat >! ${tempfile} endif endif endif set test = `cat ${tempfile} | wc -l` if("$test" != "0") then echo -n "Examining frames named ${prefix}* in $framedir ." mv ${tempfile} ${tempfile}frames set understood = "$understood $framedir" else rm -f ${tempfile} set framedir = "" endif else # this was not a frame directory set framedir = "" endif endif if(! -e "$framedir") then # still havn't found a purpose for $arg # maybe its a runlist? if("$arg" =~ *runlist) then set framedir = `dirname $arg` # make a frame list with some extra info cat $arg |\ nawk -v dir=$framedir '{print dir "/" $1 ".img", $3, $5}' |\ cat >! ${tempfile} set temp = `cat ${tempfile} | wc -l` if($temp > 0) then echo -n "reading ADSC runlist file: $arg" mv ${tempfile} ${tempfile}frames else rm -f ${tempfile} set framedir = "" endif endif endif # now actually do wedge parsing of files in $framedir if((-e "$framedir")&&(-e ${tempfile}frames)) then ############################################################################### # # Parse out wedges # ############################################################################### # parse filenames into pattern/filenumber form nawk 'NF==1' ${tempfile}frames |\ nawk 'BEGIN{FS="."} {full=$0; ext="." $NF; prefix=num=w=""} \ $NF!~/^[a-z]/{ext=""}\ {prefix=substr(full,1,length(full)-length(ext));\ while(prefix~/[0-9]$/){++w;\ num=substr(prefix,length(prefix)) num;\ prefix=substr(prefix,1,length(prefix)-1)}\ gsub("%","%%",prefix)}\ {print prefix "%0" w "d" ext, num, full}' |\ cat >! ${tempfile}patterns # format: prefix%03d.ext number filename # now identify file types cat ${tempfile}patterns |\ nawk '{ format="UNK"} \ $1~/d.img$/{format="ADSC"}\ $1~/d.cbf$/{format="CBF"}\ $1~/%03d.osc$/{format="RAXIS"}\ $1~/%03d.stl$/{format="RAXIS"}\ $1~/%03d.mar/{format="MAR"}\ $1~/.%04d$/{format="MARCCD"}\ format=="UNK"{cmd = "od -b -N 100 " $NF;\ cmd | getline magic; close(cmd);n=split(magic, b);\ magic=b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] b[10];}\ magic~/^043043043103102106072040126/{format="CBF"}\ magic~/^322004000000/{format="MAR"}\ magic~/^111111052000/{format="MARCCD"}\ magic~/^115115000052/{format="MARCCD"}\ magic~/^122055101130111123/{format="RAXIS"}\ magic~/^122055101130111123062/{format="RAXIS2"}\ magic~/^122055101130111123064/{format="RAXIS4"}\ magic~/^122101130111123/{format="RAXIS4"}\ magic~/^122055101130111123065/{format="RAXIS5"}\ magic~/^173012110105101104105122/{format="SMV"}\ Format[$1]==""{Format[$1]=format}\ format=="UNK" {format=Format[$1]}\ {print format, magic, $0}' |&\ nawk 'NF==4' >! ${tempfile}formats # format: type prefix%03d.ext number filename # remove mistaken/unwanted file types # cat ${tempfile}formats |\ # nawk '/^ADSC/ && ! /\.img$/{next} {print}' |\ # cat >! ${tempfile} # mv ${tempfile} ${tempfile}formats >& /dev/null # get total number of frames set frames = `cat ${tempfile}formats | wc -l` rm -f ${tempfile}patterns >& /dev/null # entertainment rm -f ${tempfile}frames echo -n "." # get headers for all SMV types cat ${tempfile}formats |\ nawk ' /^SMV /{file = $NF; RS="\f"; status = getline header < file;\ if(status<0){header=""; \ if($5!="") print "WAVE", $5;\ if($6!="") print "OSC_START", $6;}\ gsub("=", " ", header);\ print header; print $0;\ close(file); RS="\n"}' |\ nawk 'BEGIN{type="SMV"}\ /^DETECTOR_SN/{type="ADSC"}\ /^RAXIS/{type="RAXIS_SMV"}\ /^APS1_/{type="SBC"}\ /^SMV /{print type,$2,$3,$4;type="SMV";next} {print}' |\ cat >! ${tempfile}smvheaders # get ADSC frame info cat ${tempfile}smvheaders |\ nawk 'BEGIN{dist=osc=wave=phi=xbeam=ybeam=mxbeam=mybeam=twotheta="-"} \ /^ADSC /{type=$1; dw=188; file = $4; num = $3; pattern=$2; \ if(sn~/^4[45]/)dw=210;if(sn~/^9/)dw=315;\ if(w+0==0 && size*pix != 0) w=size*pix; if(w+0==0) w=dw;\ if(sn==428||sn==444||sn==443||sn==415||sn==904){mxbeam=xbeam;mybeam=ybeam}\ if((mxbeam=="-")&&(ybeam!="-")){mxbeam=w-ybeam; mybeam=xbeam}\ print type, wave, dist, osc, pattern, num, phi, mxbeam, mybeam, twotheta, file;\ dist=osc=wave=phi=xbeam=ybeam=mxbeam=mybeam="-"}\ /^WAVE/{wave = $2+0}\ /^DIST/{dist = $2+0}\ /^TWOTHETA/{twotheta = -$2+0}\ /^OSC_START/{phi = $2+0}\ /^OSC_RANGE/{osc = $2+0}\ /^PIXEL/{pix = $2+0}\ /^SIZE/{size = $2+0}\ /^DETECTOR_SN/{sn=$2+0}\ /^DENZO_X_BEAM/{mxbeam = $2+0}\ /^DENZO_Y_BEAM/{mybeam = $2+0}\ /^BEAM_CENTER_X/{xbeam = $2+0}\ /^BEAM_CENTER_Y/{ybeam = $2+0}' |\ cat >! ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file # get headers for all CBF types cat ${tempfile}formats |\ nawk ' /^CBF /{file = $NF; RS="\f"; status = getline header < file;\ if(status<0){header=""} \ gsub("\r","", header);\ print header; print $0;\ close(file); RS="\n"}' |\ cat >! ${tempfile}cbfheaders # get CBF frame info cat ${tempfile}cbfheaders |\ nawk 'BEGIN{dist=osc=wave=phi=xbeam=ybeam=mxbeam=mybeam=twotheta="-"} \ /^CBF /{type=$1; dw=999; file = $4; num = $3; pattern=$2; \ if(w+0==0 && ysize*pix != 0) w=ysize*pix; if(w+0==0) w=dw;\ if((mxbeam=="-")&&(ybeampix!="-")){mxbeam=w-ybeampix*pix; mybeam=xbeampix*pix}\ print type, wave, dist, osc, pattern, num, phi, mxbeam, mybeam, twotheta, file;\ dist=osc=wave=phi=xbeam=ybeam=mxbeam=mybeam="-"}\ / Wavelength/{wave = $3+0}\ / Detector_dist/{dist = $3*1000}\ / Twotheta/{twotheta = -$3+0}\ / Start_angle/{phi = $3+0}\ / Angle_incr/{osc = $3+0}\ / Pixel_size/{pix = $3*1e3}\ /^X-Binary-Size-Fastest-Dimension/{xsize = $2+0}\ /^X-Binary-Size-Second-Dimension/{ysize = $2+0}\ / Beam_xy/{gsub("[()]"," ");xbeampix = $3+0;ybeampix = $4+0}' |\ cat >! ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file rm -f ${tempfile}cbfheaders >& /dev/null # entertainment echo -n "." # get SBC frame info cat ${tempfile}smvheaders |\ nawk 'BEGIN{dist=osc=end=pix=wave=phi=xbeam=ybeam=twotheta="-"} \ /^SBC /{type=$1; file = $4; num = $3; pattern=$2;\ if((phi!="-")&&(end!="-")){osc=end-phi}\ if((pix!="-")&&(xbeam!="-")){xbeam*=pix;ybeam*=pix}\ print type, wave, dist, osc, pattern, num, phi, xbeam, ybeam, twotheta, file;\ dist=osc=end=pix=wave=phi=xbeam=ybeam="-"}\ /SPATIAL_DISTORTION_INFO/{pix = $NF+0}\ /WAVE/{wave = $NF+0}\ /GONIO_VALUES/ && ! /CRYSTAL/{dist = $NF+0}\ /ROTATION_START/{phi = $NF+0}\ /ROTATION_END/{end = $NF+0}\ /BEAM_POSITION/{xbeam=$3+0;ybeam=$2+0}' |\ cat >> ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file # entertainment echo -n "." # get RAXIS SMV frame info cat ${tempfile}smvheaders |\ nawk 'BEGIN{dist=osc=end=pix=wave=phi=xbeam=ybeam=twotheta="-"} \ /^RAXIS_SMV /{type=$1; file = $4; num = $3; pattern=$2;\ if((phi!="-")&&(end!="-")){osc=end-phi}\ if((pix!="-")&&(xbeam!="-")){xbeam*=pix;ybeam*=pix}\ print type, wave, dist, osc, pattern, num, phi, xbeam, ybeam, twotheta, file;\ dist=osc=end=pix=wave=phi=xbeam=ybeam="-"}\ /SPATIAL_DISTORTION_INFO/ && $NF+0>0{pix = $NF+0}\ /WAVE/ && $NF+0>0{wave = $NF+0}\ /GONIO_NAMES/{for(i=1;i<=NF;++i){if(tolower($i)~/dist/)di=i;\ if(tolower($i)~/2theta/)ti=i}}\ /GONIO_VALUES/ && di+0>0 && $di+0>0{dist = $di+0;di=0}\ /GONIO_VALUES/ && ti+0>0 && $ti+0>0{twotheta = $ti+0;ti=0}\ /^ROTATION /{phi = $2+0;end = $3+0}\ /BEAM_POSITION/{xbeam=$3+0;ybeam=$2+0}' |\ cat >> ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file # entertainment echo -n "." # check for read failures set frames = `nawk '/^SMV /' ${tempfile}formats | wc -l` set temp = `nawk '/^ADSC |^SBC |^RAXIS/' ${tempfile}frameinfo | wc -l` if("$frames" != "$temp") then # assume nothing? echo -n "" cat ${tempfile}formats |\ nawk '/^SMV /{type=$1; file = $4; num = $3; pattern=$2;\ dist=osc=wave=phi=xbeam=ybeam=twotheta="-";\ print type, wave, dist, osc, pattern, num, phi, xbeam, ybeam, twotheta, file;}' |\ cat >! ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file endif rm -f ${tempfile}smvheaders >& /dev/null # get mar frame info cat ${tempfile}formats |\ nawk ' /^MAR /{type=$1; file = $4; num = $3; pattern=$2;\ line="";dist=osc=wave=phi=xbeam=ybeam=twotheta="-";\ while(line !~ /^END/){getline line < file;\ if(line ~ /^WAVE/){split(line,a); wave = a[2]+0};\ if(line ~ /^DIST/){split(line,a); dist = a[2]+0};\ if(line ~ /^PHI/){split(line,a); phi = a[3]+0; phiend = a[5]+0;\ osc=(((phiend+360000-phi)*1000)%360000)/1000};\ if(line ~ /^PIXEL/){split(line,a); px=a[3]; py=a[5]};\ if(line ~ /^CENTER/){split(line,a); bx=a[3]; by=a[5]};\ }close(file);\ if((px!=0)&&(py!=0)){xbeam=bx*px/1000;ybeam=by*py/1000};\ print type, wave, dist, osc, pattern, num, phi, xbeam, ybeam, twotheta, file}' |\ cat >> ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file # entertainment echo -n "." # MARCCD cat ${tempfile}formats |\ nawk '/^MARCCD /{line=$0; b=0; dump = "od -vb " $4; $0="";\ while((b<2000)&&( dump | getline )){for(i=2;i<=NF;++i){\ if(b%4==0){printf "\n%d ", b}\ printf "%d ", 64*substr($i,1,1)+8*substr($i,2,1)+substr($i,3,1);++b}}\ close(dump); print ""; print line}' |&\ nawk '/^1052 210 4 0 0/{little=1} /^1052 0 0 20 341/{big=1} \ /^MARCCD/{print; next}\ little{print $1, $2+256*($3+256*($4+256*$5))-(2^32)*($5>=128)} \ big{print $1, $5+256*($4+256*($3+256*$2))-(2^32)*($2>=128)}' |\ cat >! ${tempfile}marccdinfo cat ${tempfile}marccdinfo |\ nawk 'BEGIN{dist=osc=wave=phi=xbeam=ybeam=twotheta="-"}\ /^MARCCD /{type=$1; file = $4; num = $3; pattern=$2;\ if(omega != omegaend){phi=omega;phiend=omegaend}\ if(phiend!="-") osc=(((phiend+360000-phi)*1000)%360000)/1000; \ if(hbeam+0 > 0){ybeam=hbeam*hpix; xbeam=vbeam*vpix};\ if(xbeam<15 && ybeam<15){xbeam=hbeam; ybeam=vbeam};\ if((wave > 10)||(wave < 0.01)){\ dist=osc=wave=phi=phiend=xbeam=ybeam=twotheta="-"};\ print type, wave, dist, osc, pattern, num, phi, xbeam, ybeam, twotheta, file;\ dist=osc=wave=phi=phiend=xbeam=ybeam=xpix=ypix=twotheta="-"}\ $1==1708{phi=$2/1000} \ $1==1740{phiend=$2/1000} \ $1==1760 && $2+0>0{phiend=phi+$2/1000} \ $1==1696{omega=$2/1000} \ $1==1728{omegaend=$2/1000} \ $1==1720{dist=$2/1000} \ $1==1692{twotheta=$2/1000} \ $1==1668{hbeam=$2/1000} \ $1==1672{vbeam=$2/1000} \ $1==1796{hpix=$2/1000000} \ $1==1800{vpix=$2/1000000} \ $1==1932{wave=$2/100000}' |\ cat >> ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file rm -f ${tempfile}marccdinfo >& /dev/null # entertainment echo -n "." # RAXIS (II, IV or V) cat ${tempfile}formats |\ nawk '/^RAXIS/{line=$0; l=0; file=$4; dump = "od -vb " file; \ while(l<201){dump | getline; for(i=2;i<=NF;++i){++n;b[n]=64*substr($i,1,1)+8*substr($i,2,1)+substr($i,3,1);\ if(n==4){n=0;++l; odd=x=b[2]; if(b[1]+b[2]+b[3]+b[4]==0){--odd;++x};\ printf "%c%c%c%c", b[1],b[2],b[3],b[4] | "od -vf";\ printf "%c%c%c%c", b[4],b[3],b[2],b[1] | "od -vf";\ printf "%c%c%c%c", b[3],b[4],b[1],b[2] | "od -vf";\ printf "%c%c%c%c", odd,b[1],b[4],b[3] | "od -vf";\ printf "%c%c%c%c", b[3],b[4],b[1],x-1 | "od -vf";}}}\ close("od -vf");close(dump); print line}' |&\ nawk '/^RAXIS/{print ""; print; n=0;next} \ NF>2{for(i=2;i<=NF;++i){if(n%5==0) printf "\n%d ", n/5; printf "%s ", $i+0; ++n;}}' |\ nawk 'BEGIN{dist=osc=wave=phi=xbeam=ybeam=twotheta="-";swap=0}\ /^RAXIS/{type=$1; file = $4; num = $3; pattern=$2;\ if(phiend!="-") osc=(((phiend+360000-phi)*1000)%360000)/1000; \ if(hpix+0 < 1){xbeam=vbeam*vpix; ybeam=hbeam*hpix};\ if(swap==0){\ dist=osc=wave=phi=phiend=xbeam=ybeam=twotheta="-"};\ print type, wave, dist, osc, pattern, num, phi, xbeam, ybeam, twotheta, file;\ dist=osc=wave=phi=phiend=xbeam=ybeam=xpix=ypix=twotheta="-"}\ $1== 73{for(i=2;i<=NF;++i){if($i+0>0.1 && $i+0<5) swap=i}} \ $1== 73{wave=$swap} \ $1==131{phi=$swap} \ $1==132{phiend=$swap} \ $1== 86{dist=$swap} \ $1==139{twotheta=$swap} \ $1==135{hbeam=$swap} \ $1==136{vbeam=$swap} \ $1==194{hpix=$swap} \ $1==195{vpix=$swap}' |\ cat >> ${tempfile}frameinfo # format TYPE wave dist osc pattern num phi xbeam ybeam twotheta file # entertainment echo -n "." # update expanded frame-info list # mv ${tempfile}frameinfo ${tempfile}parse # filter out any header-value jitter cat ${tempfile}frameinfo |\ nawk 'BEGIN{last_energy=last_dist=last_twotheta=last_osc="-"} $2+0==0{$2=1.5459}\ {$2=12398.4245/$2}\ ($2-last_energy)^2<0.5{$2=last_energy}\ ($3-last_dist)^2<1 {$3=last_dist}\ ($10-last_twotheta)^2<0.3 {$10=last_twotheta}\ ($4-last_osc)^2<0.001{$4=last_osc}\ {last_energy=$2;last_dist=$3;last_osc=$4}\ {print}' |\ cat >! ${tempfile}filtered # format: TYPE wave dist osc pattern num phi xbeam ybeam twotheta file # now parse out wedges cat ${tempfile}filtered |\ sort -k1,2 -k2n,3 -k3n,4 -k4n,5 -k5,6 -k6n,7 |\ nawk 'BEGIN{phi="-";osc="-";dist=twotheta="-";}\ $1!=ext { ext=$1;++wedge } \ $2!=energy{energy=$2;++wedge; ++waves} \ $3!=dist{dist=$3;++wedge } \ $4!=osc { osc=$4;++wedge } \ $5!=pref{pref=$5;++wedge } \ $10!=twotheta{twotheta=$10;++wedge } \ $6!=num { num=$6;++wedge } \ { phi=$7 ; phi_miss=sqrt(((((phi-expect_phi)*1000+36180000)%360000)/1000-180)^2)}\ phi_miss>0.01 && $7!="-" && expect_phi != ""{ ++wedge } \ wedge { print frames; file=$NF; \ printf "%s %s %s %s %s %s %s %s ",\ energy, phi, osc, dist, $8, $9, $10, file;\ frames=0;wedge=0} \ $4!="-" {expect_phi=phi+osc} \ {++frames; num+=1} \ END{print frames}' |\ sort -k1rn,2 -k3n >! ${tempfile}wedged # format energy phi osc dist xbeam ybeam twotheta file # entertainment echo -n "." # stick a header on the wedge list echo "wave phi osc dist xbeam ybeam twotheta firstframe total" >! ${tempfile}parseme nawk '$NF+0>0' ${tempfile}wedged >> ${tempfile}parseme # reformat list into regularly-spaced form cat ${tempfile}parseme |\ nawk 'NF>4{printf "%10s %10s %10s %10s %10s %10s %10s %10s %10s \n",\ $1,$2,$3,$4,$5,$6,$7,$NF,$8}' |\ nawk -f ${tempfile}reformat.awk |\ nawk '{print substr($0, 10)}' >! ${tempfile}formatted set temp = `cat ${tempfile}formatted | wc -l` if("$temp" > 0) then # add this list to the (temporary) master list of wedges if(! -e ${tempfile}wedges) touch ${tempfile}wedges echo "" >> ${tempfile}wedges cat ${tempfile}formatted >> ${tempfile}wedges # finish up display echo "." else echo "no wedges." endif # clean up rm -f ${tempfile}frames >& /dev/null rm -f ${tempfile}frameinfo >& /dev/null rm -f ${tempfile}filtered >& /dev/null rm -f ${tempfile}wedged >& /dev/null rm -f ${tempfile}parseme >& /dev/null rm -f ${tempfile}formatted >& /dev/null endif ######################################################################### # # Examine Text files named on command line # ######################################################################### # check for a flat, text file containing something useful if((-e "$arg")&&("$framedir" == "")) then if(! -e ${tempfile}wedges) touch ${tempfile}wedges # may be a pdb file, see if it reads like one unset isaPDB cat $arg |\ nawk '/^ATOM/{X=substr($0, 31, 8)+0; occ=substr($0, 55, 6)+0;} \ X*X>10 && X*X<10000 && occ>0 && occ<2 {print}' |\ wc -l >! ${tempfile} set temp = `cat ${tempfile}` rm -f ${tempfile} if("$temp" > 10) then # This is a PDB file set isaPDB # remember this for latter... if($?FIRSTIME) echo "Recognized PDB file $arg" set search_models = ( $search_models $arg ) set USEFUL endif # look for space groups # GOTHERE: PDB can sometimes contain P2(1), etc... set pdbSG = `nawk '/^CRYST/{print substr($0,56,13)}' $arg` if("$pdbSG" != "") then set sg = `nawk -v pdbSG="$pdbSG" -F "[\047]" '$2==pdbSG{print $1;exit}' ${CLIBD}/symop.lib | nawk '{print $4}'` if("$sg" != "") then # this SG was listed in the CCP4 library! # ADD it to the list # set SGs = `echo " $SGs $sg " | nawk '{for(i=1;i<=NF;++i){if(! seen[$i]){print $i;++seen[$i]}}}'` set USEFUL endif endif # may be a wedge file, see if it reads like one cat $arg |\ nawk -f ${tempfile}reformat.awk |\ cat >! ${tempfile} set temp = `cat ${tempfile} | wc -l` if("$temp" > 1) then if($?FIRSTIME) echo "Getting image file layout from $arg" echo "" >> ${tempfile}wedges cat ${tempfile} >> ${tempfile}wedges echo "" >> ${tempfile}wedges set USEFUL set USER_WEDGE_FILE endif # may be a sequence file, see if it reads like one cat $arg |\ nawk -f ${tempfile}sequence.awk |\ cat >! ${tempfile} set temp = `cat ${tempfile} | wc -l` if("$temp" > 1 && (! $?isaPDB ) ) then # store sequences here too if($?FIRSTIME) echo "Getting protein sequence from $arg" echo "" >> ${tempfile}wedges cat ${tempfile} >> ${tempfile}wedges echo "" >> ${tempfile}wedges set GOT_SEQUENCE set USEFUL endif # may have something about the metal in it. cat $arg |\ nawk 'BEGIN{RS=" "} NF == 1' |\ nawk '$0 !~ /^[0-9]/' |\ nawk '$0 !~ "all"' |\ egrep -iv "^inf" |\ nawk -f ${tempfile}elements.awk |\ nawk '$1 > 16 && $1 < 100' |\ cat >! ${tempfile} set temp = `cat ${tempfile} | nawk 'NR==1{print $2, $3}'` if($#temp == 2) then set METAL = "$temp[2]" # see how many sites (number in front of element name) cat $arg |\ nawk '! /^ATOM/' |\ nawk 'BEGIN{RS=" "} NF == 1' |\ nawk 'NF==1' |\ egrep -iv "^inf" |\ nawk -v Ee=$temp[1] -v Name=$temp[2] \ '(tolower(Name) == tolower($1) || $1 == Ee || tolower($1) ~ /^site/) && v>0 && v<100{print v} {v=$1+0}' |\ cat >! ${tempfile} set temp = `nawk -v L=$MAXLINE '{l+=length($0)} l& /dev/null unset USEFUL endif end ############################################## # Finished first command-line pass # ############################################## # check to see if anything useful was found in files set temp = `cat ${tempfile}wedges | wc -l` if(($temp < 3)&&(! $?PICKUP)) then # couldn't have been anything too useful if(-e ${wedgefile}) then echo "found old ${wedgefile}" set input = " ${wedgefile} $input " set PICKUP goto Gather endif endif if(! $?AUTO) echo "Hang on ..." ############################################## # Word-wise command-line pass # ############################################## # go back through command line and allow user to override variables foreach arg ( $input ) # check for protein sequences on command line echo $arg | nawk -f ${tempfile}sequence.awk >&! ${tempfile} set temp = `cat ${tempfile} | wc -l` if(($temp != 0)&&("$input" !~ *remove*)&&("$input" !~ *delete*)) then # remove old sequences from ${tempfile}wedges if(-e ${tempfile}wedges) then # reprocess all wedge information into one list cat ${tempfile}wedges |\ nawk -f ${tempfile}reformat.awk |\ nawk '{print substr($0, 10)}' >> ${tempfile} endif # update master wedge list mv ${tempfile} ${tempfile}wedges set understood = "$understood new sequence" endif if(-e ${tempfile}) rm -f ${tempfile} # check for metal name/symbol (watch out for "I", user should say "iodine") echo $arg | nawk '! /[0-9]/ && $1 != "I"' |\ nawk -f ${tempfile}elements.awk >&! ${tempfile} set temp = `cat ${tempfile} | nawk 'NR==1{print $3}'` if("$temp" != "") then # must have given an element name! set METAL = "$temp" set understood = "$understood $METAL" endif # now find out number of sites (if metal was given, or "sites" is mentioned) if(("$temp" != "")||("$arg" =~ site*)) then set temp = `echo $METAL | nawk -f ${tempfile}elements.awk | nawk 'NR==1{print $2, tolower($3)}'` if("$temp" == "") set temp = "x" echo "$input" |\ nawk 'BEGIN{RS=" "} NF==1' |\ nawk 'NF==1' |\ nawk -v Ee=$temp[1] -v name=$temp[$#temp] \ '$1+0 != 0 && $1 == int($1) {v=$1;p=2} \ p>0 && ($1 == Ee || tolower($1) == name || tolower($1) ~ /^site/){print v}\ {--p}' >! ${tempfile} set temp = `head -1 ${tempfile}` rm -f ${tempfile} if("$temp" != "") then set SITES = "$temp" set understood = "$understood sites" endif endif # check for program-option flags if("$arg" =~ hurry*) set HURRY = "hurry" end if(! $?GOT_SEQUENCE) then # go back through command line again foreach arg ( $input ) # may be a sequence file, see if it reads like one cat $arg |&\ nawk -f ${tempfile}sequence.awk |\ cat >! ${tempfile} set temp = `cat ${tempfile} | wc -l` if("$temp" > 1 && ( ! $?GOT_SEQUENCE)) then # store sequences here too if($?FIRSTIME) echo "Getting protein sequence from $arg" echo "" >> ${tempfile}wedges cat ${tempfile} >> ${tempfile}wedges echo "" >> ${tempfile}wedges set GOT_SEQUENCE set USEFUL endif end endif ############################################################################### #### # # ###### #### #### # # # # # # # # # # ##### #### #### # ### # # # # # # # # # # # # # # #### #### ###### #### #### ############################################################################### # guess at metal type ############################################################################### if("$METAL" == "") then # see if we can figure out what the metal is from the wavelengths cat ${tempfile}wedges |\ nawk 'NF>8 && $1+0>3000{for(i=1;i<$3+0;++i) print $1}' |\ nawk -f ${tempfile}elements.awk |\ nawk '{++count[$3];eV[$3]=$4} END{for(Ee in count){print count[Ee], Ee, eV[Ee]}}' |\ sort -n | tail -1 >! ${tempfile} set temp = `nawk '{print $2,$3}' ${tempfile}` rm -f ${tempfile} if($#temp == 2) then # as good a site as any set METAL = "$temp[1]" set edge = "$temp[2]" endif endif # remember the photon energy of this edge if(! $?edge) set edge = `echo $METAL | ${tempfile}elements.awk | nawk '{print $4;exit}'` # guess at number of sites from sequence (if none given) if("$SITES" == "") then if(("$METAL" == "Selenium")||("$METAL" == "Platinum")) then # use methionine count as "sites" cat ${tempfile}wedges | nawk -f ${tempfile}sequence.awk >! ${tempfile} set temp = `cat ${tempfile} | nawk '/met$/{met += $0} END{print met+0}'` if("$temp" != "0") set SITES = "$temp" rm -f ${tempfile} endif if("$METAL" == "Mercury") then # use cystine count as "sites" cat ${tempfile}wedges | nawk -f ${tempfile}sequence.awk >! ${tempfile} set temp = `cat ${tempfile} | nawk '/cys$/{cys += $0} END{print cys+0}'` if("$temp" != "0") set SITES = "$temp" rm -f ${tempfile} endif if("$METAL" == "Gold") then # use histidine count as "sites" cat ${tempfile}wedges | nawk -f ${tempfile}sequence.awk >! ${tempfile} set temp = `cat ${tempfile} | nawk '/his$/{his += $0} END{print his+0}'` if("$temp" != "0") set SITES = "$temp" rm -f ${tempfile} endif endif if("$SITES" == "" && "$METAL" != "") then # suppose there is 1 site/10kD? set SITES = 2 endif ############################################################################# #### #### # # ##### # # # ###### # # # # ## ## # # # ## # # # # # # ## # ##### # # # # ##### # # # # # # # # # # # # # # # # # # # # # # ## # #### #### # # ##### # # # ###### ############################################################################# # # combine/process all collected information into: # ${tempfile}wedges # $SGs # $MolWT # $METAL # $SITES # ############################################################################# if(-e ${tempfile}wedges) then # reformat all this collected information into one list cat ${tempfile}wedges | nawk -f ${tempfile}sequence.awk >! ${tempfile}master # come up with better directory names if(($?FIRSTIME)&&(! $?USER_WEDGE_FILE)) then # invent directory names based on frame names cat ${tempfile}wedges |\ nawk -f ${tempfile}reformat.awk | tail -n +2 |\ nawk '$1 ~ /^wave[1-9]/{$1="----"} \ {n=split($3, f, "/"); $3=""; for(i=1;i<=n;++i){$3 = f[i] " " $3}} \ {print $1, $3, $2}' | sort -r |\ nawk '{Energy=$NF;\ for(i=1;i<=length($0);++i) {\ c=substr($0,i,1); if(c ~ /[^a-zA-Z0-9]/) c=" ";\ nameinfo[Energy] = nameinfo[Energy] c }} \ END{for(Energy in nameinfo) print nameinfo[Energy], Energy}' |\ nawk '{for(i=1;i1000) printf "%d ", $NF; print $NF}' |\ nawk -f ${tempfile}labler.awk |\ nawk '{print "NAME OF", $1, "is", $NF}' >! ${tempfile}nameinfo # invent directory names based on probable MAD wavelengths if ("$edge" != "") then set last = `awk '$1+0>2000{print $1}' ${tempfile}wedges | sort -un | head -1` cat ${tempfile}wedges |\ awk '$1+0>2000{print $1}' | sort -u |\ awk -v edge=$edge '{print sqrt(($1-edge)^2),$1-edge,$0}' |\ sort -nr -k2 |\ awk -v last=$last '\ $1<10 && ! peak{print $NF,"peak";peak=1;next}\ $1<10 && peak {print $NF,"inf"inf;if(! inf)inf=1;++inf;next}\ ! high && ! peak{print $NF,"high";high=1;next}\ ! low && peak && $NF==last {print $NF,"low";low=1;next}\ {++rem;print $NF,"rem"rem}' |\ awk '{print "NAME OF", $1, "is", $NF}' >! ${tempfile}nameinfo # having only "rem1" is stupid set test = `awk '$NF!="rem1"{print 1; exit}' ${tempfile}nameinfo` if("$test" != "1") then cat ${tempfile}nameinfo |\ awk '{print $1,$2,$3,$4,"native"}' >! ${tempfile} mv ${tempfile} ${tempfile}nameinfo endif endif # re-format all wedge lists together cat ${tempfile}wedges |\ nawk -f ${tempfile}reformat.awk >> ${tempfile}nameinfo # now re-name all wavelengths to the "best" names cat ${tempfile}nameinfo |\ nawk '/^NAME OF / && ! wedges {dir[$3]=$NF} \ wedges>0{printf "%-"wedges-2"s %s\n", dir[$2], substr($0, wedges)}\ /^directory/ && /First_Frame/{print; wedges=index($0, "Energy")-1;}' |\ cat >! ${tempfile}wedges cat ${tempfile}nameinfo |\ nawk 'BEGIN{max=9} /^NAME OF / && ! wedges {dir[$3]=$NF; if(length($NF)>max) max=length($NF)} \ /^directory/ && /First_Frame/{++wedges; dir[$2]=$1; len=index($0, "Energy")-1;}\ wedges>0{printf "%-"max"s %s\n", dir[$2], substr($0, len)}' |\ cat >! ${tempfile}wedges rm -f ${tempfile}nameinfo endif # make sure title bar is on top cat ${tempfile}wedges | nawk -f ${tempfile}reformat.awk |\ nawk '$2 !~ /[0-9]/' >> ${tempfile}master cat ${tempfile}wedges |\ nawk -f ${tempfile}reformat.awk |\ nawk '$2 ~ /[0-9]/' >! ${tempfile}unsorted if($?USER_WEDGE_FILE) then cat ${tempfile}unsorted >> ${tempfile}master else # organize by energy, phi, filename sort -k2rn,3 -k5n,6 -k3rn,4 ${tempfile}unsorted >> ${tempfile}master endif rm -f ${tempfile}unsorted >& /dev/null # update master wedge list mv ${tempfile}master ${tempfile}wedges # look for language indicating removal of something set temp = `echo $input | nawk 'BEGIN{RS=" "} {print}' | nawk 'tolower($0) ~ /^remove/ || tolower($0) ~ /^delete/'` # if(("$temp" != "")&&(! $?FIRSTIME)) then if("$temp" != "") then # see if undesired wedge was provided set temp = `echo $temp | nawk '{print $1}'` set temp = `echo $input | nawk -v key=$temp '{print substr($0,index($0,key))}' | nawk '{print $2}'` if("$temp" == "") set temp = "nothing" grep "$temp" ${tempfile}wedges >& /dev/null if($status && -e ${tempfile}wedges) then set temp = "none of it" # something needs to be removed, but we don't know what echo "Enter text of what you want to remove: [$temp]" set temp = "" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set temp = ( $in ) endif if("$temp" != "") then set remove = "$temp" set temp = `grep "$remove" ${tempfile}wedges | nawk 'NF==10 && $NF ~ /^[0-9-]/{print "wedge"}' | head -1` if("$temp" == "wedge") then grep -v "$remove" ${tempfile}wedges >! ${tempfile} mv ${tempfile} ${tempfile}wedges else cat ${tempfile}wedges |\ nawk -v rem=$remove '$0 !~ rem \ $0 ~ rem {printf "%s", substr($0,1,index($0,rem)-1);\ print substr($0,index($0,rem)+length(rem))}' |\ cat >! ${tempfile} mv ${tempfile} ${tempfile}wedges endif endif set understood = "remove" endif # retrieve the (total) molecular weight if(! $?KEEP_MW) then cat ${tempfile}wedges |\ nawk -f ${tempfile}sequence.awk |\ nawk '/ Da chain:/{mw += $1} END{print mw+0}' |\ cat >! ${tempfile} set temp = `cat ${tempfile}` if("$temp" != "0") set MolWT = "$temp" rm -f ${tempfile} endif endif ############################################## # At this point, ${tempfile}wedges is final # ############################################## ############################################################################# ###### ##### # ##### # # # # # ##### # # # # # # # # # # # # # # ###### ##### # # ############################################################################# # now look for global user-specified overrides ############################################################################# # SPACE GROUP(s) set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '/^space/ || /^[PpCcIiFfRrHh][1-6]/'` if("$temp" != "") then # see if space group was given set temp = `echo $input | nawk 'BEGIN{RS=" "} /^[PpCcIiFfRrHh][1-6]/'` if("$temp" !~ [PpCcIiFfRrHh][1-6]*) then set temp = "$SGs" # something is wrong with space group, but we don't know what echo "What is your space group? [$temp]" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set temp = ( $in ) endif set list = "" foreach possibility ( $temp ) set sg = `nawk -v SG=$possibility '$4 == toupper(SG) {print $4;exit}' ${CLIBD}/symop.lib` if("$sg" =~ [PCIFR][1-6]*) set list = "$list $sg " end set list = `echo " $list " | nawk 'BEGIN{RS=" "} /^[PCIFR][1-6]/ && ! seen[$1] {print; seen[$1]=1}'` # override current SG list if("$list" =~ [PCIFR][1-6]*) set SGs = ( $list ) if("$temp" =~ unk*) set SGs = unknown set understood = "SG" endif # unit CELL # resolution set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '/^reso/ || /^diffra/ || /[0-9]a$/'` if("$temp" != "") then # see if value was given set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '$0+0 > 0.1 && p>0 {printf "%g ", $0+0; --p} /^reso/{p=1} /^diffra/{p=1} /^measu/{p=4}'` if("$temp" !~ *[0-9]) set temp = `echo $input | nawk 'BEGIN{RS=" "} $1=="A" && val>0.1{print val} {val = $1+0} $1 ~ /[0-9]A$/ && $1+0>0.1 {print $1+0}'` if("$temp" !~ [0-9]*) then set temp = "$hiRES" # something is wrong with this parameter, but we don't know what echo "How far could this crystal possibly diffract? [$temp $ANG]" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set in = `echo $in | nawk '$1+0 > 0 {print $1+0}'` if("$in" != "") set temp = ( $in ) endif if("$temp" =~ [0-9]*) set hiRES = "$temp" set understood = "RESO" endif # Vm # molecular weight (override one in sequence) set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '/^molecu/ || /^weight/ || /^mass/'` if("$temp" == "") set temp = `echo $input | nawk 'BEGIN{RS=" "} {print}' | nawk '$1+0 > 0 {w=$1+0;getline; if($1 == "D"){print w} if($1 == "kD") print w*1000}'` if("$temp" != "") then # see if value was given set temp = `echo $input | nawk 'BEGIN{RS=" "} {print}' | nawk '$1+0 > 0 {w=$1+0;getline; if($1 == "D"){print w} if($1 == "kD") print w*1000}'` if("$temp" !~ [0-9]*) then set temp = "$MolWT" # something is wrong with this parameter, but we don't know what echo "What is the molecular weight of your protein? [$temp D]" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set in = `echo $in | nawk '$1+0 > 0 {print}'` if("$in" != "") set temp = ( $in ) endif if("$temp" =~ [1-9]*) then if("$temp" =~ *D) then # units given set temp = `echo $temp | nawk '/kD$/{print $0*1000} /D$/{print $0+0}' | head -1` else # units not given set temp = `echo $temp | nawk '$0+0<70{print $0*1000} {print $0+0}' | head -1` endif set MolWT = "$temp" set KEEP_MW endif set understood = "$understood $MolWT" endif # GLOBAL DISTANCE set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '/^dist/ || /^xt/ || /^crystal/ || /^detect/'` if("$temp" != "") then # see if value was given set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '$0+0 > 10 && $0+0 < 1000 && p>0 {printf "%g ", $0+0; --p} /^dist/{p=1} /^xtf/{p=1}'` if("$temp" !~ [0-9]*) then set temp = `nawk 'NF > 7 && $7 ~ /^[1-9]/{print $7}' ${tempfile}wedges | head -1` # something is wrong with this parameter, but we don't know what echo "Xtal-to-film Distance (all wedges)? [$temp mm]" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set in = `echo $in | nawk '$1+0 > 10 {print $1+0}'` if("$in" != "") set temp = ( $in ) endif if("$temp" =~ [0-9]*) then # global edit of the wedge file cat ${tempfile}wedges |\ nawk -v newval=$temp -v title=" distance" 'NF!=10 {print} \ $3 == "First_Frame"{start=index($0,title)-1; len=length(title); print; next} \ NF==10 && start!=0 {printf "%s", substr($0,1,start); \ printf "%"len".2f", newval;\ print substr($0,start+len+1)}' |\ cat >! ${tempfile} mv ${tempfile} ${tempfile}wedges endif set understood = "$understood dist" endif # GLOBAL TWOTHETA set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '/^detect/ || /^swing/ || /^swung/ || /^twoth/ || /^2theta/'` if("$temp" != "") then # see if value was given set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk 'p>0 && /[0-9]/ && ! /[a-z]/ {printf "%g ", $0+0; --p} /^2thet/{p=1} /^twoth/{p=1} /^swing/{p=1} /^swung/{p=1}'` if("$temp" !~ *[1-9]*) then set temp = `nawk 'NF == 10 && $10 !~ /[^0-9.]/{print $10}' ${tempfile}wedges | head -1` # something is wrong with this parameter, but we don't know what echo "2THETA angle (counterclockwise detector swing around phi axis)? [${temp}$DEG]" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set temp = `echo $in | nawk '{print $1+0}'` endif if("$temp" =~ *[0-9]*) then # edit # global edit of the wedge file cat ${tempfile}wedges |\ nawk -v newval=$temp -v title=" 2theta" 'NF!=10{print}\ $3=="First_Frame"{start=index($0,title)-1; len=length(title); print} \ NF==10 && $7 ~ /^[1-9]/ {printf "%s", substr($0,1,start); \ printf "%"len".1f", newval;\ print substr($0,start+len+1)}' |\ cat >! ${tempfile} mv ${tempfile} ${tempfile}wedges endif set understood = "$understood twotheta" endif # GLOBAL BEAM CENTER set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '/^direct/ || /^beam/ || /^center/'` if("$temp" != "") then # see if value was given set temp = `echo $input | nawk 'BEGIN{RS=" "} $0+0 > 10 && $0+0 < 1000 && p>0 {printf "%g ", $0+0; --p} tolower($0) ~ /^beam/{p=2}'` if($#temp != 2) then set temp = `nawk 'NF > 9 && $9 ~ /^[1-9]/ {print $8, $9}' ${tempfile}wedges | head -1` # something is wrong with this parameter, but we don't know what echo "What is the direct beam center (for all wedges)? [$temp]" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set temp = ( $in ) endif if($#temp == 2) then # something was entered by user set beam_center = `echo $temp` if(($temp[1] =~ [1-9]*)&&($temp[2] =~ [1-9]*)) then set temp = "mosflm" echo "$input" | grep mosflm >& /dev/null if(($status)||($?FIRSTIME)) then echo "Is this beam center from Mosflm, adxv, R-axis(horiz, vert), or denzo? [$temp]" echo -n "$PROMPT" echo -n "$BELL" if($?AUTO) then echo "$temp" else set in = ( $< ) endif if("$in" != "") set temp = `echo $in | nawk '{print tolower($0)($1)}'` endif if("$temp" =~ mos*) then # no change endif if("$temp" =~ den*) then # different origin for MAR set frame = `nawk 'NF==10 && $2 ~ /^[1-9]/{print $3}' ${tempfile}wedges | head -1` if("$frame" =~ *.mar*) then # this is a MAR frame, so we need to convert the center set temp = `head -30 $frame | nawk '/^FORMAT/{w=$2} /^PIXEL/{p=$3} END{print w*p/1000}'` if("$temp" == 0) then echo "What diameter MAR did you use?" endif if("$temp" != 0) then set beam_center = `echo "$beam_center $temp" | nawk '{print $2, $NF-$1}'` endif endif endif if("$temp" =~ ad*) then set temp = `echo $beam_center` # mosflm X is ( frame width) - (ADXV's Y), mosflm Y is ADXV's X set beam_center = `echo "188 - $temp[2]" | bc` set beam_center = `echo $beam_center $temp[1]` endif if("$temp" =~ r*) then # R-axis horizontal axis is Y, vertical axis is X set beam_center = `echo "$beam_center[2] $beam_center[1]"` endif if("$beam_center" =~ [0-9]*) then set temp = ( $beam_center ) # global edit of the wedge file # replace all the beam centers in the wedges file cat ${tempfile}wedges |\ nawk -v newval=$temp[1] -v title=" x_beam" 'NF!=10{print}\ $3 == "First_Frame"{start=index($0,title)-1; len=length(title); print; next} \ NF==10 && start != 0 {printf "%s", substr($0,1,start); \ printf "%"len".2f", newval;\ print substr($0,start+len+1)}' |\ cat >! ${tempfile} mv ${tempfile} ${tempfile}wedges cat ${tempfile}wedges |\ nawk -v newval=$temp[2] -v title=" y_beam" 'NF!=10{print}\ $3 == "First_Frame"{start=index($0,title)-1; len=length(title); print; next} \ NF==10 && start!=0 {printf "%s", substr($0,1,start); \ printf "%"len".2f", newval;\ print substr($0,start+len+1)}' |\ cat >! ${tempfile} mv ${tempfile} ${tempfile}wedges endif unset beam_center endif endif set understood = "$understood center" endif # look for unhappy signals set temp = `echo $input | nawk 'BEGIN{RS=" "} {print tolower($0)}' | nawk '/^exit$/ || /^quit$/ || /^edit$/ || /^change$/'` if("$temp" != "") then set temp = "Yes" cat ${wedgefile} echo "Do you want to exit and edit $wedgefile [$temp]" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else set in = ( $< ) if("$in" != "") set temp = ( $in ) endif if("$temp" =~ [Yy]*) then echo "Please edit ${wedgefile} with your favorite text editor." echo "(Remember to keep the wedge table nice and vertical)" echo "" echo "When you are done, type:" echo "$0 ${wedgefile}" goto Cleanup_Elves endif endif ############################################## # Finished second command-line pass # ############################################## ############################################################################### # # See if we have enough to go on # ############################################################################### # evaluate user input set temp = `nawk 'NF > 8' ${tempfile}wedges | wc -l` if($temp == 1) set ONE_WEDGE if($temp >= 1) goto Report if($?SEARCHED_FILESYSTEM) then goto Help endif # this will be re-generated rm -f ${tempfile}wedges >& /dev/null goto FrameSearch Report: ################################################################################ ##### ###### ##### #### ##### ##### # # # # # # # # # # # # ##### # # # # # # # ##### # ##### # # ##### # # # # # # # # # # # # ###### # #### # # # ################################################################################ # create the definitive wedge description file # from information contained in: # ${wedgefile} or ${tempfile}wedges # $SGs # $METAL # $SITES # ################################################################################ if(! -e ${tempfile}wedges) then if(! -e ${wedgefile}) goto Help echo "Using old ${wedgefile}" mv ${wedgefile} ${tempfile}wedges endif echo "" >! ${wedgefile} echo "single crystal of:" >> ${wedgefile} # sequence goes on top cat ${tempfile}wedges |\ nawk -f ${tempfile}sequence.awk |\ nawk '/Da chain:/,NF==0' >> ${tempfile} set temp = `cat ${tempfile} | wc -l` if("$temp" != 0) then # put the sequence in the file cat ${tempfile} >> ${wedgefile} rm -f ${tempfile} else echo "unknown protein sequence " >> ${wedgefile} endif echo "Total: $MolWT D" >> ${wedgefile} echo "" >> ${wedgefile} # put the wedge stuff next cat ${tempfile}wedges |\ nawk -f ${tempfile}reformat.awk >> ${wedgefile} echo "" >> ${wedgefile} # add space group echo -n "in " >> ${wedgefile} if("$SGs" != "") then echo "$SGs" |\ nawk '{for(i=1;i1{printf "or "}\ {print $NF}' >> ${wedgefile} else echo "unknown space group." >> ${wedgefile} endif if("$hiRES" != "") then echo "to ${hiRES}$ANG resolution. " >> ${wedgefile} endif if("$search_models" != "") then set SITES = 0 echo -n "using:" >> ${wedgefile} echo " $search_models " |\ nawk 'BEGIN{RS=" "} NF==1' | nawk '{print} \ END{if(NR==1) print "as a molecular-replacement search model.";\ if(NR>1) print "as molecular-replacement search models.";}' >> ${wedgefile} endif # announce number of sites if("$SITES" != "0") then set temp = `echo $MolWT | nawk '$1+0 != 0{printf "%6.1f kD", $1/1000}'` if("$temp" == "") set temp = "asymmetric unit" echo "with $SITES $METAL sites / ${temp}" >> ${wedgefile} endif # estimate Riso, Rano, Rdisp? if(("$MolWT" =~ [1-9]*)&&("$SITES" =~ [1-9]*)) then # Caclulate the expected R values for available wavelengths echo $METAL | nawk -f ${tempfile}elements.awk |\ nawk -v mass=$MolWT -v n=$SITES '{k=n/((7^2)*mass/14); \ print 100*k*($1+$5)^2, 100*k*$6*$6, 100*k*$5*$5, $4}' |\ nawk '{printf "Riso= %.1f%% Rano= %.1f%% Rdisp= %.1f%% at %7.1f eV\n", $1, $2, $3, $4}' |\ cat >> ${tempfile} # pick wavelength of greatest interest set temp = `nawk 'NF>9 && $2+0>2000{w+=$2;++n} END{if(n) print w/n}' ${wedgefile}` if("$temp" == "") set temp = "8000" echo -n "Expect: " >> ${wedgefile} cat ${tempfile} |\ nawk -v e=$temp '{dE[$0] = sqrt(($8-e)^2)} \ END{for(line in dE) printf "%10d %s\n", dE[line], line}' |\ sort -n | head -1 |\ nawk '{print substr($0,12)}' |\ cat >> ${wedgefile} endif echo "" >> ${wedgefile} rm -f ${tempfile}wedges echo "" echo "ready to set up processing directories for:" cat $wedgefile # everything from here on is an "edit" unset FIRSTIME set temp = "Yes" echo "Everything look okay? [$temp]" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else echo -n "$BELL" # wait for input (with timeout) #set in = `nawk 'BEGIN{system("(sleep 1800; echo "") &");} {print; exit}' | nawk 'NR==1{print; exit}'` set in = ( $< ) if("$in" != "") set temp = ( $in ) endif set temp = `echo $temp` # catch unexpected replies if(("$temp" !~ [Yy]*)||($#temp != 1)) then if(($#temp == 1)&&("$temp" =~ [Nn]*)) then # one word, began with "N" set temp = "nothing" echo "What's wrong? [$temp]?" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else set in = ( $< ) if("$in" != "") set temp = ( $in ) endif set quit = `echo " $temp " | egrep -i " quit | stop | exit "` if("$quit" != "") then set QUIT goto Cleanup_Elves endif if("$temp" != "nothing") then set input = " ${wedgefile} $temp " goto Gather endif else set input = " ${wedgefile} $temp " goto Gather endif endif # user said everyhting is okay! echo "Good." if(! $?AUTO) echo " Don't go away ..." # ${wedgefile} is now our unified information source # back it up cp ${wedgefile} ${tempfile}everything if(! $?DEPLOYED) goto Deploy_Elves goto SetUp_Wedges # # Unwrap/set-up Wedger, Scaler, Spotter, Processer, etc. # ReturnFrom_Deploy_Elves: cat << EOF ./scripts/sendhome will send your frames home, as they appear. ./scripts/guide.com is a step-by-step guide to the scripts Elves write. ./scripts/table1.com will summarize your project. ./Elfsheim/Wedger will index and process one wedge of data. ./Elfsheim/Scaler will localscale and merge multiwedge data. ./Elfsheim/Phaser will refine sites and calculate phases. ./Elfsheim/Refmacer will set up refmac for you. ./Elfsheim/Processer will process all your data. EOF SetUp_Wedges: ############################################################################# # # ###### ##### #### ###### #### # # # # # # # # # # # ##### # # # ##### #### # ## # # # # # ### # # ## ## # # # # # # # # # # ###### ##### #### ###### #### ############################################################################# # Here we actually set up the processing directories ############################################################################# set root_dir = `pwd` # get wedge information in simplefied form cat ${wedgefile} |\ nawk -f ${tempfile}reformat.awk |\ cat >! ${tempfile}wedges set wavedirs = "" set wedge = 1 # default parameter variables to blank # read title line (using same logic as ${tempfile}reformat.awk) set info = `nawk 'NR==1{print $0, "-"}' ${tempfile}wedges` set items = $#info set wavedir = $#info set energy = $#info set FirstImage = $#info set number_of_frames = $#info set phi0 = $#info set osc = $#info set distance = $#info set xbeam = $#info set ybeam = $#info set twotheta = $#info set add = $#info # establish position of parameter values from key line set temp = `echo $info | nawk -v key=dir '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set wavedir = "$temp" set temp = `echo $info | nawk -v key=first '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set FirstImage = "$temp" set temp = `echo $info | nawk -v key=energ '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set energy = "$temp" set temp = `echo $info | nawk -v key=total '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set number_of_frames = "$temp" set temp = `echo $info | nawk -v key=phi '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set phi0 = "$temp" set temp = `echo $info | nawk -v key=osc '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set osc = "$temp" set temp = `echo $info | nawk -v key=dist '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set distance = "$temp" set temp = `echo $info | nawk -v key1=beam -v key2=x '{for(i=1;i<=NF;++i){if((tolower($i) ~ key1)&&(tolower($i) ~ key2)) print i}}' | head -1` if("$temp" != "") set xbeam = "$temp" set temp = `echo $info | nawk -v key1=beam -v key2=y '{for(i=1;i<=NF;++i){if((tolower($i) ~ key1)&&(tolower($i) ~ key2)) print i}}' | head -1` if("$temp" != "") set ybeam = "$temp" set temp = `echo $info | nawk -v key=theta '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set twotheta = "$temp" set temp = `echo $info | nawk -v key=add '{for(i=1;i<=NF;++i){if(tolower($i) ~ key) print i}}' | head -1` if("$temp" != "") set add = "$temp" # remove the header line (for convenience) nawk 'NR>1' ${tempfile}wedges >! ${tempfile} mv ${tempfile} ${tempfile}wedges # see if this is a "trivial" measurement set number_of_wedges = `cat ${tempfile}wedges | wc -l` if("$number_of_wedges" == "1") then # this is not MAD, just run Wedger #goto OneWedge endif # set up first wedge as the indexing wedge set info = `nawk 'NR==1{print $0, "-"}' ${tempfile}wedges` set wave = `echo $info[$energy] | nawk '{if($1+0>0)print 12398.4245/$1}'` if(! -e index ) mkdir index cd index # initialize the "start" file echo "IMAGE $info[$FirstImage]" >! start if("$wave" != "") echo "WAVE $wave" >> start if("$info[$distance]" != "-") echo "DIST $info[$distance]" >> start if("$info[$xbeam]" != "-") echo "BEAM $info[$xbeam] $info[$ybeam]" >> start if("$info[$twotheta]" != "-") echo "TWOTHETA $info[$twotheta]" >> start # go down each line in the wedge definition file set line = 1 echo -n "" >! ${tempfile}wedge_dirs while($line <= $number_of_wedges) # create a new directory for each wavelength if("$wavedirs[$#wavedirs]" != "$info[$wavedir]") then # remember all wavelength directory names set wavedirs = `echo $wavedirs $info[$wavedir]` # cd back to root cd $root_dir # make the new wavelength directory if(! -e $info[$wavedir]) mkdir $info[$wavedir] cd $info[$wavedir] # reset the wedge counter set wedge = 1 endif # create a subdirectory for each wedge if(! -e wedge$wedge) mkdir wedge$wedge cd wedge$wedge # now do interesting stuff set wave = `echo $info[$energy] | nawk '{if($1+0>0)print 12398.4245/$1}'` set ext = `echo $info[$FirstImage] |& nawk 'BEGIN{FS="."} $NF~/^[a-z]/{print "."$NF}'` set pref = `basename $info[$FirstImage] $ext` set template = `echo $pref | nawk '{while($1~/[0-9]$/){patt=patt "\043"; $1=substr($1,1,length($1)-1)}} {print $1 patt}'` set num = `echo "$pref $template" | nawk '{print substr($1,index($2,"\043"))+0}'` if ("$info[$number_of_frames]" == "-") then # let Wedger figure it out set last = "-" else set last = `echo "$num $info[$number_of_frames]" | nawk '{print $1 + $2 - 1}'` endif # initialize "start" file with specified parameters echo "IMAGE $info[$FirstImage]" >! start if("$wave" != "") echo "WAVE $wave" >> start if("$info[$distance]" != "-") echo "DIST $info[$distance]" >> start if("$info[$xbeam]" != "-") echo "BEAM $info[$xbeam] $info[$ybeam]" >> start if("$info[$twotheta]" != "-") echo "TWOTHETA $info[$twotheta]" >> start echo -n "PROCESS $num to $last " >> start if("$info[$phi0]" != "-") echo -n " START $info[$phi0]" >> start if("$info[$osc]" != "-") echo -n " ANGLE $info[$osc]" >> start if("$info[$add]" != "-") echo -n " ADD $info[$add]" >> start echo "" >> start echo "./$info[$wavedir]/wedge$wedge is for $info[$FirstImage]" # make a simplefied file of all wedges echo "$info[$wavedir]/wedge$wedge $info[$FirstImage]" >> ${tempfile}wedge_dirs cd .. # now increment the counters @ wedge = ( $wedge + 1 ) @ line = ( $line + 1 ) set info = `nawk -v line=$line 'NR==line{print $0, "-"}' ${tempfile}wedges` end # processing directories have been set up cd $root_dir echo "" # now set up misc program directories, like ARP/wARP goto Setup_Progs Return_Setup_Progs: rm -f ${tempfile}wedges >& /dev/null rm -f ${tempfile}everything >& /dev/null set index = "" set STAGE = "indexing" Index: ############################################################################# # # # ##### ###### # # # ## # # # # # # # # # # # # ##### ## # # # # # # # ## # # ## # # # # # # # # ##### ###### # # ############################################################################# # launch Wedger for autoindexing ############################################################################# # check through existing wedge directories for indexable wedges set wedge = 0 echo -n "" >! ${tempfile}unindexed echo -n "" >! ${tempfile}indexable set wedges = `nawk 'NF>0' ${tempfile}wedge_dirs | wc -l` while($wedge < $wedges) @ wedge = ( $wedge + 1 ) # retrieve the name of the wedge directory set wedge_dir = `nawk -v wedge=$wedge 'NF>0{++n} n==wedge{print $1}' ${tempfile}wedge_dirs` set image = `nawk -v wedge=$wedge 'NF>0{++n} n==wedge{print $2}' ${tempfile}wedge_dirs` # keep track of indexed/unindexed directories set matrix = "" if(-e ${wedge_dir}/best.mat) then set matrix = ${wedge_dir}/best.mat endif if(-e ${wedge_dir}/auto.mat) then set matrix = ${wedge_dir}/auto.mat endif if(! -e "$matrix") then set matrix = "${wedge_dir}/best.mat" if(-e ${wedge_dir}/mosflm.com) then # perhaps the matrix is located elsewhere? set matrix = `nawk '/^MATRIX/{print $NF; exit}' ${wedge_dir}/mosflm.com` # get absolute path to the matrix file set temp = `dirname $matrix` set matrix = `cd ${wedge_dir}; cd $temp ; pwd`/`basename $matrix` endif endif if(-e "$matrix") then # at least one wedge has been indexed set INDEXED else # this wedge has not been indexed yet echo "$wedge_dir $image" >> ${tempfile}unindexed endif # check to see which of these are index-able now if(-e "$image") then # can, conceivably, index this wedge # see how many images there are set dir = `dirname $image` set ext = `echo $image |& nawk 'BEGIN{FS="."} $NF~/^[a-z]/{print "."$NF}'` set pref = `basename $image $ext` set template = `echo $pref $ext | nawk '{while($1~/[0-9]$/){patt=patt "\043"; $1=substr($1,1,length($1)-1)}} {print $1 patt $2}'` set noglob set framepattern = `echo "$template" | nawk '{gsub("[\044\050\051\052\053\054\056\077\133\134\135\136]","[&]",$0); gsub("\043","[0-9]",$0); print "^" $0 "$"}'` unset noglob set num = `echo "$image $template" | nawk '{n=split($1,a,"[\057]"); print substr(a[n],index($2,"\043"))+0}'` set last_frame = `ls -1 $dir |& egrep "${framepattern}" |& tail -1 ` set last = `echo "$last_frame $template" | nawk '{n=split($1,a,"[\057]"); print substr(a[n],index($2,"\043"))+0}'` if($last >= $num) then # there are some images here set frames = `echo "$num $last" | nawk '{print $2 - $1 + 1}'` echo "$frames $wedge_dir $image" >> ${tempfile}indexable endif endif end # sort, with biggest wedges first sort -nr ${tempfile}indexable |\ nawk 'NF>0' >! ${tempfile} mv ${tempfile} ${tempfile}indexable >& /dev/null # check to see if anything needs to be indexed set wedges = `nawk 'NF>0' ${tempfile}unindexed | wc -l` if(! $wedges) then # no more wedges need to be indexed set STAGE = "testing" goto Processer endif # display remaining, un-indexed wedges for user echo "" nawk '{print $1, "(" $2 ") is not indexed"}' ${tempfile}unindexed # choose a default wedge to index if(! -e "${index}") then # pick a wedge to index cat ${tempfile}unindexed ${tempfile}indexable |\ nawk 'NF==2{unindexed[$1]=1} \ NF==3 && unindexed[$2]{print}' |\ sort -nr >! ${tempfile}needs_index set index = `nawk 'NF>1{print $2; exit}' ${tempfile}needs_index` rm -f ${tempfile}needs_index >& /dev/null endif if(! -e "${index}") then # some wedges are still not indexed, but no frames are available in them rm -f ${tempfile}indexable >& /dev/null rm -f ${tempfile}unindexed >& /dev/null if($?INDEXED) then # there is at least one indexed wedge, even though the others aren't done echo "no new wedges can be indexed at the moment." goto Processer endif # perhaps frames have been moved? echo "waiting for frames to appear..." sleep 30 goto Index endif set temp = "Yes" echo "Shall we index ${index}? [$temp]" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else echo -n "$BELL" set in = ( $< ) if("$in" != "") set temp = ( $in ) endif set temp = ( $temp ) # catch unexpected replies if(("$temp" !~ [Yy]*)||($#temp != 1)) then if(($#temp == 1)&&("$temp" =~ [Nn]*)) then # one word, began with "N" # display user's choices cat ${tempfile}indexable |\ nawk '{printf "%16s has %3d frames available, starting with %s\n", $2, $1, $3}' set temp = "none" echo "Which wedge DO you want to index? [$temp]?" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else echo -n "$BELL" set in = ( $< ) if("$in" != "") set temp = ( $in ) endif set quit = `echo " $temp " | egrep -i " quit | stop | exit "` if("$quit" != "") then set QUIT goto Cleanup_Elves endif if("$temp" == "none") then set temp = "" if($?INDEXED) goto Processer endif endif # examine whatever the user said set index = "" foreach word ( $temp ) grep "$word" ${tempfile}indexable >& /dev/null if(! $status) then # something matched set index = `grep "$word" ${tempfile}indexable | nawk 'NF>1{print $2; exit}'` break endif grep "$word" ${tempfile}wedge_dirs >& /dev/null if(! $status) then # something matched, but it's not "indexable" set temp = `grep "$word" ${tempfile}wedge_dirs | nawk 'NF>1{print $1; exit}'` echo "$temp has not been collected yet." goto Index endif end # seem to have understood something if(-e "${index}") then goto Index endif # couldn't understand anything, back to Gather set input = " $temp " cd $root_dir cp ${wedgefile} ${tempfile}wedges goto Gather endif # user said everything is okay for indexing! echo "" echo "moving us into ${index}..." echo "cd ${index}" cd ${index} # any extra Wedger options? set extras = "$SGs" if("$hiRES" != "") set extras = "$extras ${hiRES}A" if("$HURRY" != "") then if("$SGs" != "") then set extras = "$extras -nomerge -norun" else # need to merge to settle point group set extras = "$extras -burst" endif endif # check for other instances? # claim indexing of this wedge echo "$index () $$ $machine $STAGE" >! $busyfile onintr After_Wedger set image = `nawk '/^IMAGE/{print $2}' ./start` ${Elfsheim}/Wedger ./start $extras $image index After_Wedger: onintr rm -f $busyfile >& /dev/null # see if indexing was successful set matrix = "" if(-e "mosflm.com") then # that's good, but we gotta have a matrix set matrix = `nawk '/^MATRIX/{print $NF; exit}' mosflm.com` set temp = `dirname $matrix` set matrix = `cd $temp ; pwd`/`basename $matrix` endif if(! -e "$matrix") then # uhh.... start over? cd ${root_dir} set index = "" goto Index # cp ${wedgefile} ${tempfile}wedges # goto Report endif # at least one wedge has been indexed set INDEXED # read parameters from the wedge we just indexed set mosflmSG = `nawk '/^SYMM/{print $NF; exit}' mosflm.com` set CELL = `nawk '/^CELL/{print $2, $3, $4, $5, $6, $7; exit}' mosflm.com` set hiRES = `nawk '/^RESO/{print $2}' mosflm.com | tail -1` set mosaicity = `nawk '/^MOSA/{print $NF; exit}' mosflm.com` set distance = `nawk '/^DIST/{print $NF; exit}' mosflm.com` set xbeam = `nawk '$1=="BEAM"{print $2; exit}' mosflm.com` set ybeam = `nawk '$1=="BEAM"{print $3; exit}' mosflm.com` set two_theta = `nawk '/^TWOTHETA/{print $NF; exit}' mosflm.com` #set matrix = "${index}/$matrix" # explicit extras cat mosflm.com |\ nawk '/not understood by Wedger/,/Detector parameters/' |\ nawk '! /^#/ && NF>0' |\ cat >! ${tempfile}extras set temp = `cat ${tempfile}extras | wc -l` if(! $temp) rm -f ${tempfile}extras >& /dev/null echo "" echo "moving back to root directory..." echo "cd ../.. " cd $root_dir ################ # We have just finished indexing a wedge # Now we see if this solution applies anywhere else ################ # remove the wedge directory we just indexed from the "unindexed" lists cat ${tempfile}unindexed |\ nawk -v wedge=$index '$1 != wedge' |\ cat >! ${tempfile} mv ${tempfile} ${tempfile}unindexed >& /dev/null cat ${tempfile}indexable |\ nawk -v wedge=$index '$2 != wedge' |\ cat >! ${tempfile} mv ${tempfile} ${tempfile}indexable >& /dev/null # look for other wedges that this parameter set could apply to set wedge = 0 echo -n "" >! ${tempfile}similar set wedges = `nawk 'NF>0' ${tempfile}wedge_dirs | wc -l` while($wedge < $wedges) @ wedge = ( $wedge + 1 ) # retrieve the name of the wedge directory set wedge_dir = `nawk -v wedge=$wedge 'NF>0{++n} n==wedge{print $1}' ${tempfile}wedge_dirs` set image = `nawk -v wedge=$wedge 'NF>0{++n} n==wedge{print $2}' ${tempfile}wedge_dirs` # check that critical parameters aren't too different echo "NEW $distance $xbeam $ybeam $two_theta" |\ cat - ${wedge_dir}/start |\ nawk -v cutoff=5.0 '/^NEW /{distance=$2;xbeam=$3;ybeam=$4;two_theta=$5}\ /^DIST/{delta=sqrt(($2-distance)^2)}\ /^BEAM/{delta=sqrt(($2-xbeam)^2 + ($3-ybeam)^2)}\ /^TWOTH/{delta=sqrt(($2-two_theta)^2)}\ delta+0>cutoff{print $1, delta; delta=0}' |\ cat >! ${tempfile}deltas set temp = `cat ${tempfile}deltas` rm -f ${tempfile}deltas >& /dev/null # only consider wedges with simmilar parameters if("$temp" == "") then # record wedges we believe to be "similar" to current refined parameters echo "$wedge_dir $image" >> ${tempfile}similar endif end set similar = `nawk 'NF>1' ${tempfile}similar | wc -l` if(! $similar) then # no wedges have nearly the same parameters as these echo -n >! ${tempfile}similar # this will do nothing goto Spread_params endif # some wedges have almost the same geometry as this one # ask if its okay to apply this wedge's parameters globally cat << EOF Space Group: $mosflmSG Unit Cell: $CELL Resolution: $hiRES Distance: $distance Beam Center: $xbeam $ybeam 2-Theta: $two_theta EOF if(-e ${tempfile}extras) then echo "" echo "mosflm opts:" cat ${tempfile}extras endif echo "" set temp = "Yes" echo "Do the above parameters apply to these wedges? [$temp]" nawk '{print $1, "(" $2 ")"}' ${tempfile}similar echo -n "$PROMPT" if($?AUTO) then echo "$temp" else echo -n "$BELL" # wait for input (with 30min timeout) set in = `nawk 'BEGIN{system("(sleep 1800; echo "") &");} {print; exit}' | nawk 'NR==1{print; exit}'` if("$in" != "") set temp = ( $in ) endif set temp = ( $temp ) if(($#temp == 1)&&("$temp" =~ [Yy]*)) then # apply ${index} to all these wedges goto Spread_params endif # unexpected reply if(($#temp == 1)&&("$temp" =~ [Nn]*)) then # one word, began with "N" # display user's options echo "" nawk '{print $1, "is for", $2}' ${tempfile}wedge_dirs set temp = "${index}" echo "Which wedges DO they apply to? [$temp]?" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else set in = ( $< ) if("$in" != "") set temp = ( $in ) endif endif # detect "none" statement set test = `echo " $temp " | egrep -i " none "` if("$test" != "") then # none match (except $index) echo -n >! ${tempfile}similar goto Spread_params endif # detect "quit" statement set quit = `echo " $temp " | egrep -i " quit | stop | exit "` if("$quit" != "") then set QUIT goto Cleanup_Elves endif # examine what the user said (allow them to define "similar" list) echo -n >! ${tempfile}similar foreach word ( $temp ) grep "$word" ${tempfile}wedge_dirs >> ${tempfile}similar end # count how many wedges were specified set wedges = `nawk 'NF>0' ${tempfile}similar | wc -l` if(! $wedges) then # user must have been saying something else? rm -f ${tempfile}similar >& /dev/null set input = "$temp" cp ${wedgefile} ${tempfile}wedges goto Gather endif # getting here means we have some wedges to apply refined parameters to! Spread_params: # reinitialize "similar" wedges with the current indexing solution set wedge = 0 set wedges = `nawk 'NF>0' ${tempfile}similar | wc -l` while($wedge <= $wedges) @ wedge = ( $wedge + 1 ) if($wedge <= $wedges) then # retrieve the name of the wedge directory set wedge_dir = `nawk -v wedge=$wedge 'NF>0{++n} n==wedge{print $1}' ${tempfile}similar` echo "applying $index to $wedge_dir" else # just for consistency, "apply" $index to itself set wedge_dir = "$index" endif cat << EOF >> ${wedge_dir}/start SYMM $mosflmSG CELL $CELL MOSAIC $mosaicity RESO $hiRES DIST $distance BEAM $xbeam $ybeam TWOTHETA $two_theta EOF if(-e "${tempfile}extras") then cat ${tempfile}extras >> ${wedge_dir}/start endif # initialize mosflm.com too? if(-e ${wedge_dir}/mosflm.com) then # might as well make sure it "takes" cat ${wedge_dir}/start >> ${wedge_dir}/mosflm.com endif end rm -f ${tempfile}extras >& /dev/null rm -f ${tempfile}similar >& /dev/null # allow user to review the predictions on all these wedges? Spread_matrix: # ask if its okay to apply this wedge's matrix globally cp ${tempfile}unindexed ${tempfile}also_indexed echo "" set temp = `cat ${tempfile}also_indexed | wc -l` if($temp == 0) then # no need to ask stupid questions rm -f ${tempfile}also_indexed >& /dev/null set index = "" goto Index endif set temp = "Yes" echo "Does this orientation (the one in $matrix)" echo "apply to all these wedges? [$temp]" cat ${tempfile}also_indexed echo -n "$PROMPT" if($?AUTO) then echo "$temp" else echo -n "$BELL" # wait for input (with 30min timeout) set in = `nawk 'BEGIN{system("(sleep 1800; echo "") &");} {print; exit}' | nawk 'NR==1{print; exit}'` if("$in" != "") set temp = ( $in ) endif set temp = ( $temp ) if(($#temp == 1)&&("$temp" =~ [Yy]*)) then # apply ${matrix} to all these wedges goto Copy_matrix endif # unexpected reply if(($#temp == 1)&&("$temp" =~ [Nn]*)) then # one word, began with "N" # display user's options echo "" nawk '{print $1, "(" $2 ") still not indexed"}' ${tempfile}also_indexed set temp = "${index}" echo "Which wedges DOES it apply to? [$temp]?" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else set in = ( $< ) if("$in" != "") set temp = ( $in ) endif endif # detect "quit" statement set quit = `echo " $temp " | egrep -i " quit | stop | exit "` if("$quit" != "") then set QUIT goto Cleanup_Elves endif # examine what the user said echo >! ${tempfile}also_indexed foreach word ( $temp ) grep "$word" ${tempfile}wedge_dirs >> ${tempfile}also_indexed end # count how many wedges were specified set wedges = `nawk 'NF>0' ${tempfile}also_indexed | wc -l` if(! $wedges) then # user must have been saying something else? rm -f ${tempfile}also_indexed >& /dev/null set input = "$temp" goto Gather endif # getting here means we have some wedges to apply the indexing solution to! Copy_matrix: # copy the matrix file around rm -f ${tempfile}.mat >& /dev/null if(-e ${matrix}) cp $matrix ${tempfile}.mat >& /dev/null if(-e ${index}/auto.mat) cp ${index}/auto.mat ${tempfile}.mat >& /dev/null if(-e ${index}/best.mat) cp ${index}/best.mat ${tempfile}.mat >& /dev/null if(! -e ${tempfile}.mat) then # didn't we do this before? set matrix = `nawk '/^MATRIX/{print $NF; exit}' ${index}/mosflm.com` set temp = `dirname $matrix` set matrix = `cd ${index}; cd $temp ; pwd`/`basename $matrix` endif if(! -e ${tempfile}.mat) then # this shouldn't be possible echo "ERROR: no orientation matrix available in ${index}! " goto Index endif # initialize "also_indexed" wedges with the current indexing solution set wedge = 0 set wedges = `nawk 'NF>0' ${tempfile}also_indexed | wc -l` while($wedge <= $wedges) @ wedge = ( $wedge + 1 ) if($wedge <= $wedges) then # retrieve the name of the wedge directory set wedge_dir = `nawk -v wedge=$wedge 'NF>0{++n} n==wedge{print $1}' ${tempfile}also_indexed` echo "copying $matrix to ${wedge_dir}/best.mat" else # just for consistency, "apply" $index to itself set wedge_dir = "$index" endif cp ${tempfile}.mat ${wedge_dir}/best.mat >& /dev/null # SG always belongs with matrix cat << EOF >> ${wedge_dir}/start SYMM $mosflmSG CELL $CELL EOF end rm -f ${tempfile}.mat >& /dev/null # allow user to review the predictions on all these wedges? rm -f ${tempfile}also_indexed >& /dev/null # go back and see if there are any un-indexed wedges left set index = "" goto Index Processer: ##################################### # prepare to launch background jobs cd $root_dir if("$STAGE" != "indexing") echo "all wedges are indexed! " # back to the root directory cd ${root_dir} set i = 1 set cpu = `w | nawk 'NR==1{printf "%.0f", $NF+1}'` if($cpu > $CPUs) set cpu = $CPUs # launch whatever CPUs we can (politely) use while( $cpu <= $CPUs ) # confirm each launched job with the user set data = "all of your data" if("$STAGE" == "indexing") set data = "the indexed wedges" echo "" if(! $?a) then set a = "a" else set a = "another" endif set temp = "Yes" if(($?AUTO)&&("$HURRY" == "")&&("$a" == "another")) set temp = "No" echo "Shall we launch $a Processer job" echo "to process ${data}? [$temp]" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else echo -n "$BELL" # wait for input (with 30min timeout) set in = `nawk 'BEGIN{system("(sleep 1800; echo "") &");} {print; exit}' | nawk 'NR==1{print; exit}'` if("$in" != "") set temp = ( $in ) endif set temp = `echo $temp` # catch unexpected replies if(("$temp" !~ [Yy]*)||($#temp != 1)) then if(($#temp == 1)&&("$temp" =~ [Nn]*)) then # one word, began with "N" set temp = "quit" if("$STAGE" == "indexing") set temp = "index" echo "What do you want to do? [$temp]?" echo -n "$PROMPT" if($?AUTO) then echo "$temp" else set in = ( $< ) if("$in" != "") set temp = ( $in ) endif set quit = `echo " $temp " | egrep -i " quit | stop | exit "` if("$quit" != "") then set QUIT goto Cleanup_Elves endif if("$temp" =~ index*) then set index = "" goto Index endif endif # multi-word response set input = "$temp" goto Gather endif # reaching here means 1-word, beginning with "Y" # user said everything is okay! set logfile = processing${i}.log # make up a unique logfile name while((-e "$logfile")&&( $i < 1000)) set logfile = "processing${i}.log" @ i = ( $i + 1 ) end set wedge_dirs = `nawk '{wedge_dirs = wedge_dirs " " $1} END{if(length(wedge_dirs)<=1000) print wedge_dirs}' ${tempfile}wedge_dirs` echo "launching ./Elfsheim/Processer $HURRY $SGs $wedge_dirs $search_models >&! $logfile &" ${Elfsheim}/Processer $HURRY $SGs $wedge_dirs $search_models >&! $logfile & sleep 2 @ cpu = ( $cpu + 1 ) @ i = ( $i + 1 ) # break out if we're not done indexing if("$STAGE" == "indexing") set cpu = 99999 echo "" echo "to see your Elves Processer jobs, type:" echo "ps -fu "`whoami`" | grep Processer" echo "" echo "to stop the Elves, type:" ps -ju `whoami` | nawk 'NR==1{for(i=1;i& /dev/null set FOLLOW = $logfile goto Cleanup_Elves ################################################################################ ################################################################################ ################################################################################ ################################################################################ ################################################################################ ################################################################################ ################################################################################ ################################################################################ exit Setup_Progs: ########## # now would be the time to set up # SOLVE, SHELX, wARP ########## # make required directories #foreach dir ( SOLVE SHELX wARP ) foreach dir ( epmr wARP ) # see if it's already done set temp = `ls -lnd $dir |& nawk '/^d/{print $NF}'` if((-e "$dir")&&(! -e "$temp")) then # a file is using this name echo "WARNING: we are moving your $dir to ${dir}.old" mv -f $dir ${dir}.old endif if(! -e "$dir") mkdir $dir end wARP: ##################################### # find where arp/warp is installed? set program = "arp_warp_setup.sh" set names = "arp_warp_setup.sh" set program_Version = "0" set GoodVersion = "5.1" set places = "/usr/local/arp_warp_6.1 /programs/xtal/arp_warp_6.1 /programs/arp_warp_6.1 /pxsoft/arp_warp_6.1 /usr/local/arp_warp_6.0 /programs/xtal/arp_warp_6.0 /programs/arp_warp_6.0 /pxsoft/arp_warp_6.0 /usr/local/arp_warp_5.1 /programs/xtal/arp_warp_5.1 /programs/arp_warp_5.1/programs/bin /programs /xtal /usr/local/bin /usr/local /usr/xtal /usr" if($?warpbin) then set program = "${warpbin}/${program}" endif # first, check to see if default will work test -x "$program" if(! $status) then # make sure it's a script set temp = `od -c $program | nawk '$2=="#" && $3~/[\041]/ {print "script"} {exit}'` if("$temp" != "") then # test for program signature (and version number) set temp = `nawk '/This is the setup procedure for ARP\/wARP version /{print $(NF-1); exit}' $program` if("$temp" != "") then # get most recent version (if possible) set temp = `echo $temp $program_Version | nawk '$1+0 > $2+0{print $1}'` if("$temp" != "") then set program_Version = "$temp" endif endif endif endif # check the directory where we plan to write warp.runme eventually if(-e wARP/warp.runme) then set temp = `nawk '$1=="setenv" && $2=="warpbin"{print $3; exit}' wARP/warp.runme` if("$temp" != "") then set file = "${temp}/arp_warp_setup.sh" set temp = "" # test for program signature (and version number) if(-e "$file") set temp = `nawk '/This is the setup procedure for ARP\/wARP version /{print $(NF-1); exit}' $file` if("$temp" != "") then # get most recent version (if possible) set temp = `echo $temp $program_Version | nawk '$1+0 > $2+0{print $1}'` if("$temp" != "") then set program = "$file" set program_Version = "$temp" endif endif endif endif # try using the "which" command foreach name ( $names ) # check for sufficiently high version number set temp = `echo "$program_Version $GoodVersion" | nawk '$1+0 >= $2+0{print $1}'` if("$temp" != "") goto End_WARP_search # "which" should handle processing of $path set possibilities = `which $name |& nawk 'NF==1{gsub(/[*?\042\047]/," "); print}' |& nawk -v L=$MAXLINE '{l+=length($0)} l $2+0{print $1}'` if("$temp" != "") then set program = "$file" set program_Version = "$temp" endif endif end end # check for sufficiently high version number set temp = `echo "$program_Version $GoodVersion" | nawk '$1+0 >= $2+0{print $1}'` if("$temp" != "") goto End_WARP_search # search for $program in likely places echo -n "Looking for ARP/wARP " set HARD_TO_FIND onintr End_WARP_search # simplefy program name set program = `echo $names | nawk '{print $1}'` foreach place ( $places ) if(! -e $place) continue if("$place" == "/") echo -n "hmm." # use find to get candidate files set files = `find $place -name $program -follow -perm -1 -print |& nawk '! /^find:/ && ! /src\/script/' |& nawk -v L=$MAXLINE '{l+=length($0)} lL{exit}'` foreach file ( $files ) # make sure it's executable test -x $file if($status) continue # make sure it's a script set temp = `od -c $file | nawk '$2=="#" && $3~/[\041]/ {print "script"} {exit}'` if("$temp" == "") continue # test for program signature (and version number) set temp = `nawk '/This is the setup procedure for ARP\/wARP version /{print $(NF-1); exit}' $file` if("$temp" != "") then # get most recent version (if possible) set temp = `echo $temp $program_Version | nawk '$1+0 > $2+0{print $1}'` if("$temp" != "") then set program = "$file" set program_Version = "$temp" endif endif # check for sufficiently high version number set temp = `echo "$program_Version $GoodVersion" | nawk '$1+0 >= $2+0{print $1}'` if("$temp" != "") goto End_WARP_search end # entertainment echo -n "." end End_WARP_search: onintr # check if we found any program set WARP_DIR = "" test -x "$program" if(! $status) then # got something, make sure it works set temp = `nawk '/This is the setup procedure for ARP\/wARP version /{print $(NF-1); exit}' $program` if("$temp" != "") then set WARP_DIR = `dirname $program` if($?HARD_TO_FIND) echo "found $WARP_DIR" endif endif if("$WARP_DIR" == "") then echo "Couldn't find ARP/wARP." echo "maybe you should look at: " echo "http://www.embl-hamburg.de/ARP/" # random default set WARP_DIR = /programs/arp_warp_6.1/bin/`uname` endif unset HARD_TO_FIND ##################################### # do a partial set-up of wARP # can't really finish set-up without a cell cd wARP # put the protein sequence in the wARP directory cat ../${wedgefile} |\ nawk -f ${tempfile}sequence.awk |\ nawk '/Da chain:/,NF==0' |\ nawk '/Da chain:/{print ">", $0;print ""; next} {print}' |\ cat >! seq.pir set temp = `cat seq.pir | wc -l` if($temp > 2) then set side = side # create a protin.custom file if(($?CLIBD)&&(! -e protin.custom)) then # retrieve three-letter code cat ${CLIBD}/protin.dic |\ nawk 'NF>3 && $3~/[A-Z][A-Z][A-Z]/{print $3, $4}' |\ cat >! ${tempfile}tlc # assign residue numbers to the sequence cat seq.pir |\ nawk '/^>/{next} {for(i=1;i<=length($0);++i) print substr($0,i,1)}' |\ nawk 'NF==1{++n; print n, $1} NF==0{n=0}' |\ cat ${tempfile}tlc - |\ nawk '/^[A-Z]/ && tlc[$2]==""{tlc[$2]=$1; next}\ /^[1-9]/{print $1, tlc[$2]}' |\ cat >! ${tempfile}sequence rm -f ${tempfile}tlc >& /dev/null # create protin chain types cat ${tempfile}sequence |\ nawk '$1==1{++typ; nter=$0;}\ {chntyp[typ]= "NTER " nter " 3 CTER " $0 " 2"} \ END{for(i=1;i<=typ;++i) print "CHNTYP",i, chntyp[i];\ print "CHNTYP", typ+1, "WAT"}' |\ cat >! ${tempfile}chntyp rm -f ${tempfile}sequence >& /dev/null # make up some chain names cat ${tempfile}chntyp |\ nawk '{ID=sprintf("%c",$2+64)} $3=="WAT"{ID="W"} {printf "CHNNAM ID %c CHNTYP %d\n", ID,$2}' |\ cat >! protin.custom cat ${tempfile}chntyp >> protin.custom rm -f ${tempfile}chntyp >& /dev/null endif else set side = "" echo "> example protein sequence" >! seq.pir echo "" >> seq.pir echo "YOURPROTEINSEQUENCE" >> seq.pir if(! -e protin.custom) then cat << EOF >! protin.custom CHNNAM ID A CHNTYP 1 CHNNAM ID W CHNTYP 2 CHNTYP 1 NTER 1 MET 3 CTER 7500 GLY 2 CHNTYP 2 WAT EOF endif endif # make a symbolic link to the "best" phased mtz #ln -sf ../mtz/best_phased.mtz . >& /dev/null cat << EOF-warp.runme >! warp.runme #! /bin/csh -f # # quick guide/example for running ARP/wARP # ###### if(! \$?warpbin) setenv warpbin /programs/arp_warp_6.1/bin/\`uname\` set path = ( \$warpbin \$path . ) set otheropts = "" # set-up wARP #1) distributed set-up script #arp_warp_setup.sh #2) Elven set-up of de-novo building from phased mtz #./setup_warp.com ./best.mtz #3) Elven set-up of molecular replacement #./setup_warp.com ../mtz/all.mtz best_MR_result.pdb #./rigid.com >! logs/rigid.log #arp_warp.sh mode molrep #cp files/molrep.brk files/warp_free.brk # set up synonyms if(-e files/warp_free.brk) cp files/warp_free.brk files/warp_free.pdb >& /dev/null if(-e files/warpNtrace.brk) cp files/warpNtrace.brk files/warpNtrace.pdb >& /dev/null if(-e files/molrep.brk) cp files/molrep.brk files/molrep.pdb >& /dev/null ln -sf warp_free.pdb files/warp_free.brk ln -sf warpNtrace.pdb files/warpNtrace.brk ln -sf molrep.pdb files/molrep.brk # check versions of refmac5 and arp_warp set refmacversion = \`echo "" | refmac5 |& grep -i version | awk '{print substr(\$0,index(\$0,"Refmac_")+7)+0}'\` set arpwarpversion = \`echo "" | arp_warp |& grep -i "arp ver" | awk '{print substr(\$0,index(toupper(\$0),"ARP VER. ")+8)+0}'\` set test = \`echo "\$refmacversion" | awk '{print (\$1>=5.1)}'\` if("\$test" == "1") then echo "using refmac5" set otheropts = "\$otheropts refmac5" endif # see what version of ARP/wARP this is set test = \`echo "\$arpwarpversion" | awk '{print (\$1>=6)}'\` if("\$test" == "1") then # apply a little "patch" cat \${warpbin}/arp_warp.sh |\\ awk '/^set tls/ || /^set extra/{\$0="if(! \$?"\$2") "\$0}\\ /Observations/ && /\\047\$/{\$0="#"\$0}\\ /All done/{++finishing}\\ /^ endif/ && finishing{\$0="#"\$0;finishing=0}\\ /MODE WILSON/{++wilson}\\ /WEIGHT/{next}\\ /goto exitlab/ && wilson{\$0="#"\$0;wilson=0}\\ {print}' |\\ cat >! arp_warp.sh chmod a+x arp_warp.sh set path = ( . \$path ) endif # make sure we use the model (if we have it) set model = "" if(-e files/warp_free.pdb) then set model = keepmodel set size = \`grep ATOM files/molrep.pdb |& wc -l\` if(\$size <= 10) set model = "" endif #if("\$model" != "") set initial_rigid try_rigid: if(\$?initial_rigid) then set minshift = 0.001 set tempfile = tempfile rm -f \${tempfile}shifts # rigid-body refinement? if(-e "./rigid.com" && -e "./files/molrep.pdb") then echo "doing rigid body refinement" set shift = "" if(-e logs/rigid.log) mv logs/rigid.log logs/rigid.log.old echo "" >! logs/rigid.log set moving = 1 set trials = 0 set last_trials = 10 while ("\$moving" == "1" && \$trials < 500) ./rigid.com files/molrep.pdb >>& logs/rigid.log if(! -e rigid_body.pdb) then echo "rigid body failed." break endif cat files/molrep.pdb |\\ awk '/^ATOM/{++n;print n,substr(\$0,31,8),substr(\$0,39,8),substr(\$0,47,8)}' |\\ cat >! \${tempfile}before.xyz cat rigid_body.pdb |\\ awk '/^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 |\\ awk '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 = \`awk '{++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" | tee -a \${tempfile}shifts tail -\$last_trials \${tempfile}shifts |\\ awk '{++n;v[n]=\$2;sum+=\$2;ssqr=\$2*\$2}\\ END{avg=sum/n;sum=0;for(i=1;i<=n;++i)sum+=(v[i]-avg)^2;\\ print sqrt(sum/n),sqrt(ssqr/n)}' |\\ cat >! \${tempfile}_rms_shift set rmsd_shift = \`awk '{print \$1}' \${tempfile}_rms_shift\` set rms_shift = \`awk '{print \$2}' \${tempfile}_rms_shift\` set trials = \`awk 'END{print NR}' \${tempfile}shifts\` if(\$trials > 20 && "\$rmsd_shift" != "") then echo "rmsd shift in last \$last_trials trials" set shift = "\$rmsd_shift" endif if(\$trials > 50) then set minshift = \`echo \$minshift | awk '{print \$1*1.1}'\` echo "waiting for shift < \$minshift" set last_trials = \`echo \$trials 5 | awk '{print int(\$1/\$2)}'\` endif set moving = \`echo \$shift \$minshift | awk '{print (\$1>\$2)}'\` mv rigid_body.pdb files/molrep.pdb end endif endif # run initial molrep job set size = \`grep ATOM files/molrep.pdb |& wc -l\` if(\$size > 10) then cp files/molrep.pdb files/starthere.pdb arp_warp.sh mode molrep \$otheropts Rplot.com logs/initial_molrep.log >! logs/initial_molrep.html #if(-e molrep/arp_out.pdb) cp molrep/arp_out.pdb files/molrep.pdb cp files/molrep.pdb files/initial_molrep.pdb cp files/molrep.pdb files/warp_free.pdb mv logs/molrep.log logs/initial_molrep.log # check to see if this blew up? set test = \`awk '\$1+0>0 && NF>6{print (\$2>50 || \$3>50)}' logs/initial_molrep.html | tail -1\` if(\$test) then echo "that was awful! " if ( ! \$?initial_rigid ) then set initial_rigid goto try_rigid endif echo "starting over with initial model..." cp files/starthere.pdb files/molrep.pdb cp files/starthere.pdb files/warp_free.pdb endif endif # run free-atom refinement (multi-model?) arp_warp.sh mode warp \$model \$otheropts #if(-e warp_free/arp_out.pdb) cp warp_free/arp_out.pdb files/warp_free.pdb cp files/warp_free.pdb files/warp_free1.pdb mv logs/warp_free.log logs/warp_free1.log Rplot.com logs/warp_free1.log >! logs/warp_free1.html # run auto-tracing refinement ( sometimes crashes without keepmodel ) arp_warp.sh mode warpNtrace \$otheropts keepmodel if(-e warpNtrace/arp_out.pdb) cp warpNtrace/arp_out.pdb files/warpNtrace.pdb cp files/warpNtrace.pdb files/warpNtrace1.pdb mv logs/warpNtrace_refine.log logs/warpNtrace1_refine.log Rplot.com logs/warpNtrace1_refine.log >! logs/warpNtrace1_refine.html # release the phase restraints echo "releasing phase restraints" echo "set phaseres = N" >> warp.par # start where last tracer left off cp files/warpNtrace.pdb files/warp_free.pdb # run autotracing again arp_warp.sh mode warpNtrace \$otheropts if(-e warpNtrace/arp_out.pdb) cp warpNtrace/arp_out.pdb files/warpNtrace.pdb cp files/warpNtrace.pdb files/warpNtrace2_nophase.pdb cp files/warpNtrace.pdb files/final_model_1.pdb mv logs/warpNtrace_refine.log logs/warpNtrace2_nophase_refine.log Rplot.com logs/warpNtrace2_nophase_refine.log >! logs/warpNtrace2_nophase_refine.html # now dock side chains if(-e seq.pir) then arp_warp.sh mode warpNtrace \$otheropts side if(-e warpNtrace/arp_out.pdb) cp warpNtrace/arp_out.pdb files/warpNtrace.pdb cp files/warpNtrace.pdb files/warpNtrace3_side.pdb cp files/warpNtrace.pdb files/final_model_1.pdb mv logs/warpNtrace_refine.log logs/warpNtrace3_side_refine.log Rplot.com logs/warpNtrace3_side_refine.log >! logs/warpNtrace3_side_refine.html endif # dock side chains? if(0) then set chains = \`awk '/ CA /{print substr(\$0, 22, 1)}' files/warpNtrace.pdb | sort -u\` awk '! /^ATOM/' files/warpNtrace.pdb >! side_dock.pdb # this may or may not be the best way foreach chain ( \$chains ) # try to dock whole sequence into this traced fragment side_dock.sh seq chains \$chain mv files/autobuild_chains_\${chain}.brk files/autobuild_chains_\${chain}.pdb >& /dev/null # concatenate all the docked chain traces cat files/autobuild_chains_\${chain}.pdb |\\ awk -v chain=\$chain '/^ATOM/ && substr(\$0, 22, 1)==chain {gsub("[*]"," "); print}' |\\ cat >> side_dock.pdb end # do all chains at once? if(\$?monomer) then side_dock.sh seq chains \$chains mv files/autobuild_chains_\${chains}.brk files/autobuild_chains_\${chains}.pdb >& /dev/null # new name for output file set chains = \`echo \$chains | awk 'BEGIN{RS=" "} {printf \$1}'\` # strip off "*" characters cat files/autobuild_chains_\${chains}.pdb |\\ awk '{gsub("[*]"," ")} substr(\$0, 23, 4)!=" "{print}' |\\ cat >! side_dock.pdb endif # update files for next run mv side_dock.pdb files/side_dock.pdb set size = \`grep ATOM files/side_dock.pdb |& wc -l\` if( \$size > 10 ) then cp files/side_dock.pdb files/molrep.pdb cp files/side_dock.pdb files/final_model_1.pdb endif endif # update/create the protin.custom file cp files/final_model_1.pdb files/molrep.pdb mv warp.par warp.par.save ./setup_warp.com best.mtz files/final_model_1.pdb mv warp.par.save warp.par # (re)build the free-atom structure arp_warp.sh mode molrep \$otheropts if(-e molrep/arp_out.pdb) cp molrep/arp_out.pdb files/molrep.pdb Rplot.com logs/molrep.log >! logs/molrep.html exit EOF-warp.runme chmod a+x warp.runme ######## # write the setup_warp.com script cat << EOF-setup_warp >! setup_warp.com #! /bin/csh -f # # Prototype Elves procedure for automatic warp setup 4-29-10 # # starting with only a phased mtz or pdb/mtz pair # alias nawk nawk set nawk = nawk nawk 'BEGIN{exit}' >& /dev/null if(\$status) then alias nawk awk set nawk = awk endif setenv CCP4_OPEN UNKNOWN set datafile = best_phased.mtz set pdbfile = "" set tempfile = tempfile set customlib = "" if(\$#argv == 0) then cat << EOF-help usage: setup_warp.com mtzfile.mtz [pdbfile.pdb] where: mtzfile.mtz - CCP4 "mtz" format data file. phases and Free-R flags recommended pdbfile.pdb - a "starting" structure description: A directory system and "warp.par" file for arp_warp will be produced. You will still need to "setenv warpbin" and edit your "\\\$path" to use arp_warp. use "uniqueify" or FreeRer.com to generate free-R flags. EOF-help exit 9 endif # support user-specified input files foreach arg ( \$* ) if("\$arg" =~ *.mtz) then set datafile = "\$arg" endif if(("\$arg" =~ *.pdb)||("\$arg" =~ *.brk)) then set pdbfile = "\$arg" endif end ##################################### # make sure datafile is set up globably set dir = \`dirname \$datafile\` set dir = \`cd \$dir ; pwd\` set datafile = "\${dir}/"\`basename \$datafile\` # get stats from the mtz file echo "go" | mtzdump hklin \$datafile >! \${tempfile}mtzdump if(\$status) then echo "ERROR: unable to read \$datafile" exit 9 endif # standard data stats set resol = \`nawk '/Resolution Range/{getline;getline;if(\$4>20)\$4=20; print \$4,\$6}' \${tempfile}mtzdump\` set sym = \`nawk '/Space group =/{print \$NF+0}' \${tempfile}mtzdump\` set cell = \`nawk '/Cell Dimensions/{getline;getline;print}' \${tempfile}mtzdump\` set wilsonb = \`echo "\$resol" | nawk '{printf "%.0f", 79*((\$2/3)^2)}'\` # same way arp_warp_setup.sh does it set wmat = \`echo \$resol | awk '{if (\$2>2.0) print 0.3} {if (\$2<2.001 && \$2>1.700) print 0.5} {if (\$2<1.701 && \$2>1.400) print 0.7} {if (\$2<1.401 && \$2>1.1) print 1.2} {if (\$2<1.101) print 2.5}'\` set freer = Y grep "FreeR_flag" \${tempfile}mtzdump >& /dev/null if(\$status) then # add some? echo "WARNING: no FreeR_flag in \$datafile" set freer = "N" endif # make the two directories if (! -e logs) mkdir logs if (! -e files) mkdir files # try using the Elven setup (if we need it) if (-e ./warp.runme && ! \$?warpbin) then nawk '/^setenv warpbin/' ./warp.runme >! \${tempfile}sourceme source \${tempfile}sourceme rm -f \${tempfile}sourceme if(! \$?warpbin) set warpbin = "" if(-e "\$warpbin") then set path = ( \$warpbin \$path ) else unset warpbin endif endif ############################# # get F with best resolution/completeness/F/SIG cat \${tempfile}mtzdump |\\ nawk '/OVERALL FILE STATISTICS/,/LIST OF REFLECTION/' | nawk 'NF>5' |\\ nawk '\$(NF-1) == "F"{F=\$NF; meanF=\$8; reso=\$(NF-2); comp=substr(\$0,32)+0; \\ getline; if(\$(NF-1)!="Q") next; S=\$NF; if(\$8) meanF /= \$8; print F, S, reso, comp, meanF;}' |\\ sort -k3n,4 -k4nr,5 -k5nr >! \${tempfile}F set F = \`head -1 \${tempfile}F\` if(\$#F > 2) then set sigfp = \$F[2] set fp = \$F[1] endif # get most recent phase set cat \${tempfile}mtzdump |\\ nawk 'NF>4{print \$(NF-1),\$(NF-4), \$NF, " "}' |\\ cat >! \${tempfile}cards set phibest = \`nawk '/^P/{phi=\$3} /^W/{print \$2,phi,\$3}' \${tempfile}cards | sort -nr | nawk '{print \$2;exit}'\` set fom = \`nawk '/^P/{phi=\$3} /^W/{print \$2,phi,\$3}' \${tempfile}cards | sort -nr | nawk '{print \$3;exit}'\` set phaseres = "F" if("\$phibest" == "") then set phaseres = "N" endif # make sure we get the right cell fft hklin \$datafile mapout \${tempfile}.map << EOF >&! \${tempfile}.fftlog LABIN F1=\$fp RESOL 1000 5 PATTERSON END EOF set test = \`awk '/Cell dimensions/{print \$4,\$5,\$6,\$7,\$8,\$9;exit}' \${tempfile}.fftlog\` rm -f \${tempfile}.map \${tempfile}.fftlog >& /dev/null if(\$#test == 6) set cell = ( \$test ) # find a working copy of refmac set refmac = \`which refmac5\` if(\$#refmac != 1) set refmac = refmac # skip PDB set-up if its not there if(! -e "\$pdbfile") goto sizeup ############################# # install user's PDB file (MR solution? ) cat \$pdbfile >! \${tempfile}input.pdb protin: # do a few transformations too cat \${tempfile}input.pdb |\\ nawk '/^ATOM/ || /^HETATM/' |\\ nawk '{atom=substr(\$0,13,5); Ee=substr(atom,1,2); \\ TYP=substr(\$0,18,3); NUM=substr(\$0,23,4);\\ Chain=substr(\$0,22,1)}\\ Chain==" "{Chain="A"}\\ # Ee !~ /[CONS]\$/ || Ee !~ /^ / {TYP="IUM";Chain="X"}\\ TYP=="HOH" || TYP=="WAT" {atom=" OW0 ";Chain="W";TYP="WAT"}\\ seen[atom TYP Chain NUM]{for(i=65;I<=90;++i){Chain=sprintf("%c",i); if(! seen[atom TYP Chain NUM]) break}}\\ {++n;++seen[atom TYP Chain NUM];\\ printf "ATOM %5d %5s%3s %1s%4d%s\\n", n,atom,TYP,Chain,NUM,substr(\$0,27,40)}' |\\ cat >! \${tempfile}.pdb # weigh it (roughly) set MASS = \`nawk '{Ee=substr(\$0,14,1)} Ee~/[CNOS]/{MASS+=14} END{print MASS}' \${tempfile}.pdb\` # make SURE cell is the same (or arp will crash) echo "CELL \$cell" |\\ pdbset xyzin \${tempfile}.pdb xyzout files/warp_free.pdb >& /dev/null rm -f \${tempfile}.pdb # in case we are doing molecular replacement run cp files/warp_free.pdb files/molrep.pdb # in case we are using version 5.x ln -sf warp_free.pdb files/warp_free.brk ln -sf molrep.pdb files/molrep.brk # in case we are using version 6.x ln -sf molrep.pdb files/molrep_start.pdb # create a protin.custom for this structure cat files/warp_free.pdb |\\ nawk '/^ATOM/ || /^HETATM/' |\\ nawk '{ID=substr(\$0, 22, 1); if(ID==" ")ID="_"; \\ atom=substr(\$0, 14, 2);\\ num = substr(\$0, 23, 4)+0;\\ res=substr(\$0, 18, 3)\\ print ID, atom, res, num} END{print "W O WAT 2"}' |\\ nawk 'CHNTYP[\$1]==""{CHNTYP[\$1]="WAT"}\\ CHNTYP[\$1]=="WAT" && \$2!~/^O/ {CHNTYP[\$1]="NON"}\\ \$2=="CA"{CHNTYP[\$1]="AA"}\\ nter[\$1]==""{nter[\$1]="1 MET"} \\ cter[\$1]+0<\$4{cter[\$1]=\$4 " " \$3} \\ \$4==1{nter[\$1]=\$4 " " \$3} \\ END{for(ID in CHNTYP) print CHNTYP[ID], ID, nter[ID], cter[ID]}' |\\ sort |\\ nawk '{++n; ID[n]=\$2; CHNTYP[n]="WAT";\\ print "CHNNAM ID", ID[n], "CHNTYP", n} \\ /^NON/{CHNTYP[n]="NON"}\\ /^AA/{CHNTYP[n]="NTER "\$3" "\$4" 3 CTERM "\$5" "\$6" 2"}\\ /^NON/{CHNTYP[n]="WAT"}\\ /^AA/{CHNTYP[n]="NTER 1 "\$4" 3 CTERM 7500 GLY 2"}\\ END{for(i=1;i<=n;++i) print "CHNTYP", i, CHNTYP[i]}' |\\ cat >! protin.custom # try this out? set protin = protin if(! \$?warpbin) set warpbin = "" if(-e "\$warpbin/arp_protin") then set protin = "\$warpbin/arp_protin DICT \$warpbin/arp_protin.dic" else if(! -e "\$protin") then which "\$protin" >& /dev/null if("\$status") then # no protin available echo "protin unavailable" set TRIED_PROTIN goto refmac5 endif endif endif # if we don't have refmac, protin is useless anyway which refmac >& /dev/null if(\$status) then echo "refmac unavailable" set TRIED_PROTIN goto refmac5 endif # try running protin echo "testing protin..." set TRIED_PROTIN \$protin XYZIN files/warp_free.pdb << EOF >&! \${tempfile}.log SYMM \$sym @protin.custom EOF rm -f PROTOUT PROTCOUNTS >& /dev/null # check to see it protin was happy grep "PROTIN: Normal termination" \${tempfile}.log >& /dev/null if(! \$status) then # great! goto rigid endif # there was a problem with the protin run... cat \${tempfile}.log |\\ nawk '/ERROR: Group Name/{print "NOTRES", \$4}\\ /Atom Name/{atom=\$3}\\ /ATOM OMITTED/{print "NOTATM", atom}\\ / atom / && /is absent in the library/{print "NOTATM", substr(\$4,2)}' |\\ sort -u >! \${tempfile}delete_these rm -f \${tempfile}.log >& /dev/null # report what we had to do... cat \${tempfile}delete_these |\\ nawk '{printf "\\042%s\\042\\047s ", \$2}' |\\ nawk '{print "WARNING: eliminating", \$0 "from files/molrep.pdb"}' nawk '/^ATOM/{print substr(\$0, 1, 66)}' files/warp_free.pdb |\\ cat >! \${tempfile}lastinput.pdb cat \${tempfile}delete_these \${tempfile}lastinput.pdb |\\ nawk '/^NOTRES/{bad[\$2]=1; next} /^NOTATM/{bad[\$2]=1; next}\\ {split(substr(\$0, 13, 4), a);\\ ATM=a[1]; NUM=substr(\$0, 23, 4);\\ TYP=substr(\$0, 18, 3)} \\ ! bad[TYP] && ! bad[ATM] {print}' |\\ cat >! \${tempfile}input.pdb set different = \`diff \${tempfile}input.pdb \${tempfile}lastinput.pdb | wc -l\` if(! \$different) then # no change, what to do next? echo "WARNING: unable to get \$protin to process \$pdbfile " goto refmac5 endif goto protin refmac5: which refmac5 >& /dev/null if(\$status) goto rigid echo "testing refmac5..." # protin is no more ... try getting refmac5 to swallow this PDB refmac5 HKLIN \${datafile} XYZIN files/warp_free.pdb XYZOUT \${tempfile}.pdb \\ HKLOUT \${tempfile}.mtz \$customlib << EOF >&! logs/refmac_test.log NCYC 2 SCALE TYPE BULK LABIN FP=\$fp SIGFP=\$sigfp END EOF set Rfactor = \`awk '/all[_ ]R[_ ]factor/{print \$NF}' logs/refmac_test.log | tail -1\` set newligand = \`awk '/A new ligand description has been added to/{print \$NF}' logs/refmac_test.log\` if("\$Rfactor" != "") then # great! echo "R = \$Rfactor" goto rigid endif if(-e "\$newligand" && "\$customlib" == "" ) then echo "making suggested custom.lib" mv \$newligand custom.lib set customlib = "LIBIN \`pwd\`/custom.lib" goto refmac5 endif # chuck all strage atoms? if("\$customlib" != "") then set customlib = "" awk '\$1 !~ /[_#]/{print "NOTRES",\$1}' custom.lib |\\ sort -u >! \${tempfile}delete_these cat \${tempfile}delete_these |\\ nawk '{printf "\\042%s\\042\\047s ", \$2}' |\\ nawk '{print "WARNING: eliminating", \$0 "from files/molrep.pdb"}' nawk '/^ATOM/{print substr(\$0, 1, 66)}' files/warp_free.pdb |\\ cat >! \${tempfile}lastinput.pdb cat \${tempfile}delete_these \${tempfile}lastinput.pdb |\\ nawk '/^NOTRES/{bad[\$2]=1; next} /^NOTATM/{bad[\$2]=1; next}\\ {split(substr(\$0, 13, 4), a);\\ ATM=a[1]; NUM=substr(\$0, 23, 4);\\ TYP=substr(\$0, 18, 3)} \\ ! bad[TYP] && ! bad[ATM] {print}' |\\ cat >! \${tempfile}input.pdb set different = \`diff \${tempfile}input.pdb \${tempfile}lastinput.pdb | wc -l\` if(! \$different) then # no change, what to do next? echo "WARNING: unable to get refmac5 to process \$pdbfile " if(! \$?TRIED_PROTIN) goto protin goto rigid endif goto protin endif # chuck all uninterpretable atoms? cat logs/refmac_test.log |\\ awk '/ atom / && /is absent in the library/{print "NOTATM", substr(\$4,2)}' |\\ sort -u >! \${tempfile}delete_these set test = \`cat \${tempfile}delete_these | wc -l\` if("\$test" != "0") then cat \${tempfile}delete_these |\\ nawk '{printf "\\042%s\\042\\047s ", \$2}' |\\ nawk '{print "WARNING: eliminating", \$0 "from files/molrep.pdb"}' nawk '/^ATOM/{print substr(\$0, 1, 66)}' files/warp_free.pdb |\\ cat >! \${tempfile}lastinput.pdb cat \${tempfile}delete_these \${tempfile}lastinput.pdb |\\ nawk '/^NOTRES/{bad[\$2]=1; next} /^NOTATM/{bad[\$2]=1; next}\\ {split(substr(\$0, 13, 4), a);\\ ATM=a[1]; NUM=substr(\$0, 23, 4);\\ TYP=substr(\$0, 18, 3)} \\ ! bad[TYP] && ! bad[ATM] {print}' |\\ cat >! \${tempfile}input.pdb set different = \`diff \${tempfile}input.pdb \${tempfile}lastinput.pdb | wc -l\` if(! \$different) then # no change, what to do next? echo "WARNING: unable to get refmac5 to process \$pdbfile " if(! \$?TRIED_PROTIN) goto protin goto rigid endif goto protin endif # how did we get here? echo "WARNING: unable to get refmac5 to swallow \$pdbfile" if(! \$?TRIED_PROTIN) goto protin rigid: ############################# # get F with best resolution/completeness/F/SIG rm -f \${tempfile}.log \${tempfile}delete_these \${tempfile}input.pdb \${tempfile}lastinput.pdb >& /dev/null #rm -f \${tempfile}.pdb \${tempfile}.mtz >& /dev/null set FREE if("\$freer" == "Y") set FREE = "FREE=FreeR_flag" cat << EOF-script >! rigid.com #! /bin/csh -f # # auto-generated rigid-body script # set pdbin = "\\\$1" if(! -e "\\\$pdbin") set pdbin = files/molrep.pdb \$refmac HKLIN \$datafile HKLOUT ./refmacout.mtz \\ XYZIN \\\$pdbin XYZOUT rigid_body.pdb << EOF-refmac LABIN FP=\$fp SIGFP=\$sigfp \$FREE LABO FC=FC PHIC=PHIC FWT=2FOFCWT PHWT=PH2FOFCWT - DELFWT=FOFCWT PHDELWT=PHFOFCWT REFI TYPE RIGID EOF-script # make individual chains the rigid-body parts cat protin.custom |\\ nawk '/^CHNNAM/{ID[\$NF]=\$3}\\ /NTER/{++n; print "RIGID GROUP",n,"from",\$4,ID[\$2],"to",\$8,ID[\$2]}' |\\ cat >> rigid.com cat << EOF-script >> rigid.com RIGID NCYC 10 #REFI RESIDUAL MLKF METHOD CDIR PHASED #REFI BREF OVERALL #REFI PHASE SIGMAcalc SCALE TYPE BULK #SCALE LSSC ANIS FIXBULK BBULK 200 EOF-refmac EOF-script chmod a+x rigid.com sizeup: ######################################## # size of protein (in atoms) # guess at Vm, if we don't know if(! \$?Vm) set Vm if("\$Vm" == "") set Vm = 2.4 # calculate unit cell volume echo \$cell |\\ nawk 'NF==6{s=3.1415926535897899419/180; A=cos(s*\$4); B=cos(s*\$5); G=cos(s*\$6); \\ skew = 1 + 2*A*B*G - A*A - B*B - G*G ; if(skew < 0) skew = -skew;\\ printf "%.3f\\n", \$1*\$2*\$3*sqrt(skew)}' |\\ cat >! \${tempfile}volume set CELLvolume = \`cat \${tempfile}volume\` rm -f \${tempfile}volume >& /dev/null # get number of ASUs in the unit cell set ASU_per_CELL = \`nawk -v sym=\$sym '\$1 == sym {print \$2;exit}' \$CLIBD/symop.lib\` # compute an ASU mass consistent with this Vm set ASU = \`echo "\$CELLvolume \$ASU_per_CELL \$Vm" | nawk '\$2+0>0 && \$3+0>0{print (\$1/\$2) / \$3}'\` # molecular weight of protein if(! \$?MASS) set MASS = 0 if(-e seq.pir) then # quick-and-stupid mass calculation set MASS = \`tail -n +2 seq.pir | wc -c | nawk '{printf "%d", \$1*120}'\` endif # any other way to get mass? set MASS = \`echo \$MASS \$ASU | nawk '\$1+0>0{print \$1} \$1+0<=0{print \$2}'\` # number of molecules in ASU set cgr = \`echo "\$ASU \$MASS" | nawk '\$2+0>0{cgr=\$1/\$2} {printf "%.0f", cgr}' | nawk '\$1<1{\$1=1} {print \$1}'\` if(\$cgr > 10) set cgr = 1 set ASU = \`echo "\$cgr \$MASS" | nawk '{print \$1 * \$2}'\` set nres = \`echo "\$ASU" | nawk '{print \$1/120}'\` # now \$ASU is in Da # do this the same way arp_warp_setup.sh does wilson hklin \${datafile} <&! \${tempfile}wilson.log NRESI \$nres LABIN FP=\$fp SIGFP=\$sigfp END EOF set protsize = \`nawk '\$1 ~ /^[CNO]\$/ {total += \$2} END {print total+0}' \${tempfile}wilson.log \` rm -f \${tempfile}wilson.log >& /dev/null if(\$protsize == 0) set protsize = \`echo "\$ASU" | nawk '{printf "%d", \$1/14}'\` # compute solvent content set solc = \`echo \$ASU \$CELLvolume \$ASU_per_CELL | nawk '{printf "%.2f", 1 - 1.2397*\$1/(\$2/\$3)}'\` set solc = \`echo \$solc | nawk '\$1+0<0.9 && \$1+0>0.2{print}'\` if("\$solc" == "") set solc = 0.5 ########################################## # use this to get arp's preferred ASU definition arp_warp << EOF >! \${tempfile}asu MODE MIRBUILD SYMM \$sym END EOF cat \${tempfile}asu |\\ nawk '/Asymmetric unit limits/{print 0, \$4/\$6; print 0, \$7/\$9; print 0, \$10/\$12}' |\\ nawk '/3\$/{\$0= \$0 4} /6\$/{\$0= \$0 7} {print}' |\\ cat >! \${tempfile}xyzlim set xyzlim = \`cat \${tempfile}xyzlim\` rm -f \${tempfile}xyzlim \${tempfile}asu >& /dev/null if( \$#xyzlim != 6) then which arp_warp echo "failed." echo "is this arp_warp version 5.0 or higher? " exit 9 endif set phaselabin = "" if("\$phibest" != "") then set phaselabin = "PHIB=\$phibest" if("\$fom" != "") then set phaselabin = "PHIB=\$phibest FOM=\$fom" endif endif set libin = ( \$customlib ) if("\$libin" =~ LIBIN*) set libin[1] = "" ################################################################################ # create the warp.par file cat << EOF >! warp.par set WORKDIR = \`pwd\` set PROJECT = PROJECT set remote = 0 set JOB_ID = 1 set arpwarpdir = \\\${JOB_ID}_arp_warp set CCP4I_DEFFILE = \`pwd\`/dummy.def #set modeccp4i = FREEATOMS #set modeccp4i = WARPNTRACEMODEL #set modeccp4i = WARPNTRACEPHASES #set modeccp4i = MOLREP #set modeccp4i = SOLVENT if(! \$?modeccp4i) set modeccp4i = FREEATOMS set seqin = \`pwd\`/seq.pir set modelin = '' set freebuild = 0 set libin = '\$libin' set extralib = '\$customlib' set datafile = \$datafile set fp = \$fp set sigfp = \$sigfp set fbest = \$fp set phibest = \$phibest set fom = \$fom set protsize = \$protsize set solventc = \$solc set wilsonb = \$wilsonb set whichtrace = 1 set restrcyc = 100 set restrref = 10 set cgr = \$cgr #set cgr = 1 set wmat = \$wmat set weightv = set wgrad = 1.0 set rc1 = 40 set rc2 = 40 set rc3 = 40 set models = 1 set procs = 1 set machine1 = \`hostname\` set machine2 = DUMMY set machine3 = DUMMY set machine4 = DUMMY set machine5 = DUMMY set machine6 = DUMMY set resol = ' \$resol ' set sym = \$sym set cell = ' \$cell ' set xyzlim = ' \$xyzlim ' set newrefmac = 1 set refmeth = "CGMAT" set newrefmac = 0 set refmeth = "CDIR" set refmax = MLKF set freer = \$freer set freerml = \$freer set freelabin = ' FREE=FreeR_flag ' set damp = ' 0.3 0.3 ' set rrcyc = 4 set scale = BULK set bulkls = 'SBULk -0.75 BBULk 150' set bulkml = 'SBULk -0.25 BBULk 80' set fixbulk = '\\#' set scaleopt = ' BULK LSSC ANIS ' set scalml = ' SCAL MLSC ' set scaleopt = set scanis = Y set phaseres = \$phaseres #set phaselabin = ' \$phaselabin ' #set phaseref = ' PHAS SCBL 1.0 ' set phasblur = 0.7 set solvent = 0 set flatten = 0 set eresol = set tlsonoff = 0 set tlsin = '' set tlsinfile = 'init.tls' set cycskip = 0 set skip = 0 set flagk = 1 set flagf = 0 set truncshifts = 1 set multit = 5 set upmore = 1 set side = 0 set fsig = 3.2 set rsig = 1.0 set bcut1 = 2.0 set bcut2 = 2.0 set bcut3 = 2.0 set randtimes = 0 set rand1 = 10 set rand2 = 20 set rand3 = 30 set randshift1 = 0.5 set randshift2 = 0.5 set randshift3 = 0.5 set keepdata = WORLD set logomega = logomega alias nawk \$nawk set boldoff = \\\`tput rmso\\\` #set boldon = "" #set boldoff = "" EOF echo "warp.par is ready." touch dummy.def # clean up rm -f \${tempfile}mtzdump \${tempfile}cards \${tempfile}F >& /dev/null EOF-setup_warp chmod a+x setup_warp.com ######## # write Rplot.com and Drift.com here? cat << EOF-script >! Rplot.com #! /bin/csh -f # # Plot R-factors from a REFMAC log in xloggraph format # # alias nawk /usr/bin/nawk if(\`uname\` == Linux) alias nawk awk if(! \$?CBIN) set CBIN = "/programs/ccp4/bin" set logs set sort = rt foreach arg ( \$* ) if(\$arg =~ paste*) then set sort = "" endif end echo "" ls -1\$sort \$* set i = 1 echo "" echo "
Stats"
echo 'For inline graphs use a Java browser'
echo "
" EOF-script chmod a+x Rplot.com ######## # write a README file cat << EOF-README >! README Elves have done an example set-up of ARP/wARP for you. To get ARP/wARP running, you may need to download a copy from the website: netscape http://www.embl-hamburg.de/ARP/ Once you have ARP/wARP installed, assuming it's in ${WARP_DIR}, you need to type this: setenv warpbin $WARP_DIR set path = ( \$warpbin \$path ) arp_warp_setup.sh and then answer the questions you see there. Alternately, Elves have written a shortcut around arp_warp_setup.sh called "setup_warp.com" in this directory. All you have to do is provide this script with a phased mtz file: setup_warp.com best_phased.mtz or setup_warp.com ../mtz/all.mtz model.pdb (i.e. model.pdb is a molecular replacement solution) ...and a basic warp.par file will be produced you should then be able to run: arp_warp.sh mode warpNtrace $side or any of the other ARP/wARP programs Elves will have included your protein sequence in seq.pir, which is needed for automated side-chain tracing in ARP/wARP Elves will, eventually, place what they believe to be the "best" phasing solution to your data in ./best.mtz, but you can use whatever mtz you want in arp_warp_setup.sh or setup_warp.com EOF-README ##################################### cd $root_dir goto Return_Setup_Progs FrameSearch: ############################################################################### ###### ##### ## # # ###### #### ###### ## ##### #### # # # # # # # ## ## # # # # # # # # # # # ##### # # # # # ## # ##### #### ##### # # # # # ###### # ##### ###### # # # # # ###### ##### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ###### #### ###### # # # # #### # # ############################################################################### # Go look for some data to process ############################################################################### set framedir = "" set frames set frames_found = 0 set enough_frames = 10 echo -n "Looking for frames " if(! $?AUTO) onintr End_of_FrameSearch if(! $?AUTO) echo -n "(Cntrl-C to stop)" # look in subdirectories of listed arguments foreach arg ( $input ) if(($frames_found < $enough_frames)&&(-e "$arg")) then # look for subdirectories ls -lnL $arg |&\ nawk '/^d/{print $NF}' |&\ nawk -v parent=$arg '{print parent "/" $1}' |&\ cat >&! ${tempfile}dirs # eliminate unwanted directories/frames foreach baddie ( $bad_frames ) grep -v $baddie ${tempfile}dirs >&! ${tempfile} mv ${tempfile} ${tempfile}dirs end set dirs = `cat ${tempfile}dirs |& nawk -v L=$MAXLINE '{l+=length($0)} l 1000000 {print $NF}' |& nawk "$IMAGE_pattern" |& wc -l` if($frames > 2) then set temp = `echo $dir | nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1` set framedir = "$framedir $temp" @ frames_found = ( $frames_found + $frames ) endif # for entertainment echo -n "." end endif end # look in PARENT directory of listed arguments foreach arg ( $input ) if(($frames_found < $enough_frames)&&(-e "$arg")) then # get parent directory set place = `dirname $arg |& nawk '$0 != "."' |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1` # eliminate unwanted directories foreach baddie ( $bad_frames ) set place = `echo $dirs | grep -v $baddie` end # see if there are frames here if(-e "$place") then set frames = `ls -lnL $place |& nawk '/^\-/ && $5+0 > 1000000 {print $NF}' |& nawk "$IMAGE_pattern" |& wc -l` if($frames > 2) then set framedir = "$framedir $place" @ frames_found = ( $frames_found + $frames ) endif # for entertainment echo -n "." endif endif end # More agressive search if still not enough frames found if($frames_found < $enough_frames) then # look in some likely places foreach root ( `pwd`/ /expdata/ /data/ /*/ ) if(-e "$root") then foreach subdir ( "" `whoami` `whoami`/frames frames ../frames data ../data ) # make sure this directory is for real if((-e "${root}/${subdir}")&&($frames_found < $enough_frames)) then # look in this directory for frames set place = `echo "${root}/${subdir}" |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1` # eliminate known bad directories foreach baddie ( $bad_frames ) set place = `echo $place | grep -v $baddie` end # look for frames in this directory if(($frames_found < $enough_frames)&&(-e "$place")) then # look for first file that matches the pattern set frames = `ls -lnL $place |& nawk '/^\-/ && $5+0 > 1000000 {print $NF}' |& nawk "$IMAGE_pattern" |& wc -l` if($frames > 2) then set framedir = "$framedir $place" @ frames_found = ( $frames_found + $frames ) endif # for entertainment echo -n "." endif endif end endif end endif # Really aggressive search if($frames_found < $enough_frames) then echo "" echo -n "Looking harder " # same starting points, different order foreach subdir ( `whoami`/frames `whoami` frames data "" ) foreach root ( ./ /expdata/ /data/ /*/ ) # look in these directories for frames if(($frames_found < $enough_frames)&&(-e "${root}${subdir}")) then set place = `echo "${root}${subdir}" |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1` # look for frames in this directory if(-e "$place") then # look for directories containing frames find $place -name '*[\-_][0-9][0-9][0-9].*' |&\ nawk "$IMAGE_pattern" | nawk 'NF==1' |& nawk ' ! /^find:/' |&\ nawk '{n=split($0,d,"/");for(i=1;i 1' |&\ cat >&! ${tempfile} # now check each of these new directories in the usual way set dirs = `sort -nr ${tempfile} |& nawk -v L=$MAXLINE '{l+=length($NF)} l 1000000 {print $NF}' |& nawk "$IMAGE_pattern" |& wc -l` if($frames > 2) then set framedir = "$framedir $dir" @ frames_found = ( $frames_found + $frames ) endif endif end # for entertainment echo -n "." endif endif end end endif End_of_FrameSearch: onintr set SEARCHED_FILESYSTEM # final report if("$framedir" != "") then echo "frames found in:$framedir" else echo "didn't find any." echo "" if(! $?AUTO) then set temp = "I don't know" echo "Where are the frames you want to process? [$temp] $BELL" echo -n "$PROMPT" echo -n "$BELL" set in = ( $< ) if("$in" != "") set temp = ( $in ) if("$temp" == "I don't know") then echo "Well ... We don't know either." echo "Bye! " set QUIT set end_status = 100 goto Cleanup_Elves endif # this might be worth something set framedir = "$temp" unset SEARCHED_FILESYSTEM else echo "Sorry, we can't find any x-ray image files." echo "Agressive image search will not be done in automatic mode." echo "" echo "please run: $0 /where/ever/your/frames/are/" echo "where /where/ever/your/frames/are/ is the location of your x-ray diffraction images." echo "Later! " set BAD goto Cleanup_Elves endif endif # go back and check these frames set input = " $framedir $input " goto Gather # save csh from end not found errors end end end exit Unwrap_Awk_Scripts: ################################################################################ # # # # # # ##### ## ##### # # ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## # ##### ###### ##### # # # ## ## ## # # # # # #### # # # # # # # # # ################################################################################ # Unwrap complex AWK programs used by Elves ################################################################################ cat << EOF-reformat >! ${tempfile}reformat.awk #! $nawk -f # # "Universal" wedge description file interpreter # # reformats a free-form table describing wedges to a # more standardized version # # that is, one that has all possible x-ray information tabulated, # and the same number of items per row # BEGIN{ max_dir_len = length("directory"); max_first_len = length("First_Frame"); wave_number = 0 } # only look at lines after the title title != "" { # extract the value of each field # first-image in the wedge if(substr(\$0,first,len[first]) !~ /[a-z,A-Z]/) { # take lack of image filename to be end of the list title = "" } else { # count wedges ++wedge # move start of feild for overhanging values temp = first while(substr(\$0,temp-1,1) ~ /[0-9,a-z,A-Z_\\/\\.]/ && temp>1){--temp;len[temp]=len[temp+1]+1}; split(substr(\$0,temp,len[temp]),a); FIRST[wedge]=a[1]; if(length(a[1]) > max_first_len) max_first_len = length(a[1]) # wavelength value (energy) WAVE[wedge] = " - "; if(wave) { # move start of feild for overhanging values temp = wave while(substr(\$0,temp-1,1) ~ /[0-9\\.]/ && temp>0){--temp;len[temp]=len[temp+1]+1}; if(substr(\$0,temp,len[temp])+0 > 0) { Wave=substr(\$0,temp,len[temp])+0; # convert to energy if(Wave < 5) Wave = 12398.4245/Wave WAVE[wedge] = sprintf("%7.1f ", Wave); } } # keep track of wavelengths (for directory names) if(wavenumber[WAVE[wedge]] == "") { ++wave_number; wavenumber[WAVE[wedge]] = wave_number; } # wavelength subdirectory name DIR[wedge]= "wave" wavenumber[WAVE[wedge]] if(dir) { # move start of feild for overhanging values temp = dir while(substr(\$0,temp-1,1) ~ /[a-z,A-Z0-9\\/\\.]/ && temp>1){--temp;len[temp]=len[temp+1]+1}; if(substr(\$0,temp,len[temp]) ~ /[a-z,A-Z.1-9]/) { split(substr(\$0,temp,len[temp]),a) DIR[wedge]=a[1]; if(length(DIR[wedge]) > max_dir_len) max_dir_len = length(DIR[wedge]) } } TOTAL[wedge] = " - "; if(total) { # move start of feild for overhanging values temp = total while(substr(\$0,temp-1,1) ~ /[0-9\\.]/ && temp>0){--temp;len[temp]=len[temp+1]+1}; if(int(substr(\$0,temp,len[temp])+0) > 0) { Total=int(substr(\$0,temp,len[temp])+0); TOTAL[wedge] = sprintf("%5d ", Total); } } PHI[wedge] = " - "; if(phi) { # compensate for overhanging numbers temp = phi while(substr(\$0,temp-1,1) ~ /[0-9\\-\\.-]/ && temp>0){--temp;len[temp]=len[temp+1]+1} if(substr(\$0,temp,len[temp]) ~ /[0-9]/) { Phi=substr(\$0,temp,len[temp])+0; PHI[wedge] = sprintf("%6.1f ", Phi); if(PHI[wedge]+0 != Phi+0) PHI[wedge] = sprintf("%6s ", Phi+0); } } OSC[wedge] = " - "; if(osc) { # compensate for overhanging numbers temp = osc while(substr(\$0,temp-1,1) ~ /[0-9\\.-]/ && temp>0){--temp;len[temp]=len[temp+1]+1} if(substr(\$0,temp,len[temp]) ~ /[0-9]/) { Osc=substr(\$0,temp,len[temp])+0; OSC[wedge] = sprintf("%6.1f ", Osc); if(OSC[wedge]+0 != Osc+0) OSC[wedge] = sprintf("%6s ", Osc+0); } } DIST[wedge] = " - "; if(dist) { temp = dist # compensate for overhanging numbers while(substr(\$0,temp-1,1) ~ /[0-9\\.]/ && temp>0){--temp;len[temp]=len[temp+1]+1} if(substr(\$0,temp,len[temp]) ~ /[0-9]/) { Dist=substr(\$0,temp,len[temp])+0; DIST[wedge] = sprintf("%8.2f ", Dist); } } XBEAM[wedge] = " - "; if(xbeam) { temp = xbeam # compensate for overhanging numbers while(substr(\$0,temp-1,1) ~ /[0-9\\.-]/ && temp>0){--temp;len[temp]=len[temp+1]+1} if(substr(\$0,temp,len[temp]) ~ /[0-9]/) { Xbeam=substr(\$0,temp,len[temp])+0; XBEAM[wedge] = sprintf("%7.2f ", Xbeam); } } YBEAM[wedge] = " - "; if(ybeam) { temp = ybeam # compensate for overhanging numbers while(substr(\$0,temp-1,1) ~ /[0-9\\.-]/ && temp>0){--temp;len[temp]=len[temp+1]+1} if(substr(\$0,temp,len[temp]) ~ /[0-9]/) { Ybeam=substr(\$0,temp,len[temp])+0; YBEAM[wedge] = sprintf("%7.2f ", Ybeam); } } TWOTHETA[wedge] = " 0 "; if(twotheta) { temp = twotheta # compensate for overhanging numbers while(substr(\$0,temp-1,1) ~ /[0-9\\.-]/ && temp>0){--temp;len[temp]=len[temp+1]+1} if(substr(\$0,temp,len[temp]) ~ /[0-9]/) { Twotheta=substr(\$0,temp,len[temp])+0; } TWOTHETA[wedge] = sprintf("%6.1f ", Twotheta); } ADD[wedge] = " - "; if(add) { temp = add # compensate for overhanging numbers while(substr(\$0,temp-1,1) ~ /[0-9]/ && temp>0){--temp;len[temp]=len[temp+1]+1} if(substr(\$0,temp,len[temp]) ~ /[0-9]/) { Add=substr(\$0,temp,len[temp])+0; ADD[wedge] = sprintf("%5d ", Add); } } } } # get keyword line tolower(\$0) ~ /file|frame|image/ && tolower(\$0) ~ /first|start/ && ! title { # title gives the register of each parameter \$0=tolower(\$0); title=tolower(\$0); # clear old definitions dir=first=total=wave=phi=osc=dist=xbeam=ybeam=twotheta=add=0 for(thing in mark) mark[thing]=0 # now browse title for the register of each value for(i=1;i<=NF;++i){ if((! dir )&&(\$i ~ /dir/)) { dir = index(title,\$i)+0; ++mark[dir]; } if((! first )&&(\$i ~ /first|frame|image|begin/)) { first = index(title,\$i)+4; ++mark[first]; } if((! total )&&(\$i ~ /total|num/)) { total = index(title,\$i)+2; ++mark[total]; } if((! wave )&&(\$i ~ /wave|energ/)) { wave = index(title,\$i)+2; ++mark[wave]; } if((! phi )&&(\$i ~ /phi|start/)) { phi = index(title,\$i)+2; ++mark[phi]; } if((! osc )&&(\$i ~ /osc|angle/)) { osc = index(title,\$i)+1; ++mark[osc]; } if((! dist )&&(\$i ~ /dist|xtf/)) { dist = index(title,\$i)+3; ++mark[dist]; } if((! xbeam )&&(\$i ~ /beam/ && \$i ~ /x/)) { xbeam = index(title,\$i)+2; ++mark[xbeam]; } if((! ybeam )&&(\$i ~ /beam/ && \$i ~ /y/)) { ybeam = index(title,\$i)+2; ++mark[ybeam]; } if((! twotheta )&&(\$i ~ /two|2/ && \$i ~ /theta/)) { twotheta = index(title,\$i)+1; ++mark[twotheta]; } if(\$i ~ /add/) { add = index(title,\$i); ++mark[add]; } } # mark last column too ++mark[length(\$0)+256] # find the "stop" of each parameter feild (now that we know all the starts) if(dir) { for(i=1;! mark[dir+i]; ++i); len[dir]=i } if(first) { for(i=1;! mark[first+i]; ++i); len[first]=i } if(wave) { for(i=1;! mark[wave+i]; ++i); len[wave]=i } if(total) { for(i=1;! mark[total+i]; ++i); len[total]=i } if(phi) { for(i=1;! mark[phi+i]; ++i); len[phi]=i } if(osc) { for(i=1;! mark[osc+i]; ++i); len[osc]=i } if(dist) { for(i=1;! mark[dist+i]; ++i); len[dist]=i } if(xbeam) { for(i=1;! mark[xbeam+i]; ++i); len[xbeam]=i } if(ybeam) { for(i=1;! mark[ybeam+i]; ++i); len[ybeam]=i } if(twotheta) { for(i=1;! mark[twotheta+i]; ++i); len[twotheta]=i } if(add) { for(i=1;! mark[add+i]; ++i); len[add]=i } } # support ADSC's LOGFILE format \$1 == "Directory:" { framedir = \$NF } \$2 == "Prefix:" { prefix = \$NF } \$2 == "Suffix:" { img = \$NF } \$1 == "Anomalous:" { ano = \$2 } \$2 == "Center:" { Xbeam = 188-\$4; Ybeam = \$3 } \$1 == "Wavelength:" { for(i=2;i<=NF;++i){ MADwave[i] = \$i}} /^Run# Start/{ # reconstruct the actual wedge list wedge_search_end = wedge getline; while(NF > 11) { # set the starting run number as indicated run_num = \$1 start_num = sprintf("%03d", \$2) # do this for each run entry for(i=2; MADwave[i]+0>0.1; ++i) { ++wedge RUN_NUMBER[wedge] = run_num FIRST[wedge]= framedir prefix "_" run_num "_" start_num "." img; if(length(FIRST[wedge]) > max_first_len) max_first_len = length(FIRST[wedge]) # look for re-run wedges for(j=wedge-1;j>1;--j) { if(FIRST[wedge]==FIRST[j]) FIRST[j]="" } WAVE[wedge] = sprintf("%7.1f ", 12398.4245/MADwave[i]); if(wavenumber[WAVE[wedge]] == "") { ++wave_number; wavenumber[WAVE[wedge]] = wave_number; } DIR[wedge]= "wave" wavenumber[WAVE[wedge]] TOTAL[wedge] = sprintf("%5d ", \$3); PHI[wedge] = sprintf("%6.1f ", \$6); if(PHI[wedge]+0 != \$6+0) PHI[wedge] = sprintf("%6s ", \$6+0); OSC[wedge] = sprintf("%6.1f ", \$10); if(OSC[wedge]+0 != \$10+0) OSC[wedge] = sprintf("%6s ", \$10+0); DIST[wedge] = sprintf("%8.2f ", \$4); XBEAM[wedge] = sprintf("%7.2f ", Xbeam); YBEAM[wedge] = sprintf("%7.2f ", Ybeam); TWOTHETA[wedge] = " 0 "; ADD[wedge] = " - "; run_num += 100; if(ano ~ /^Yes/) { # do inverse-beam wedge ++wedge RUN_NUMBER[wedge] = run_num FIRST[wedge]= framedir prefix "_" run_num "_" start_num "." img; if(length(FIRST[wedge]) > max_first_len) max_first_len = length(FIRST[wedge]) # look for re-run wedges for(j=wedge-1;j>1;--j) { if(FIRST[wedge]==FIRST[j]) FIRST[j]="" } WAVE[wedge] = sprintf("%7.1f ", 12398.4245/MADwave[i]); if(wavenumber[WAVE[wedge]] == "") { ++wave_number; wavenumber[WAVE[wedge]] = wave_number; } DIR[wedge]= "wave" wavenumber[WAVE[wedge]] TOTAL[wedge] = sprintf("%5d ", \$3); PHI[wedge] = sprintf("%6.1f ", \$6+180); if(PHI[wedge]+0 != \$6+180) PHI[wedge] = sprintf("%6s ", \$6+180); OSC[wedge] = sprintf("%6.1f ", \$10); if(OSC[wedge]+0 != \$10+0) OSC[wedge] = sprintf("%6s ", \$10+0); DIST[wedge] = sprintf("%8.2f ", \$4); XBEAM[wedge] = sprintf("%7.2f ", Xbeam); YBEAM[wedge] = sprintf("%7.2f ", Ybeam); TWOTHETA[wedge] = " 0 "; ADD[wedge] = " - "; } run_num += 100; } getline; } # clear all the variables for(i in MADwave) MADwave[i] = "" } /^STOP After/{ # roll back the wedge list, and truncate the last one n = split(\$NF, a, "_"); lastrun = a[n-1]; # "cancel" un-done wedges lastwedge = wedge; while((RUN_NUMBER[lastwedge] != lastrun)&&(lastwedge > wedge_search_end)) { --lastwedge; } if(wedge > wedge_search_end) { # erase all wedges "after" this one wedge = lastwedge; # update the actual size of the wedge TOTAL[wedge] = a[n] - substr(FIRST[wedge],length(FIRST[wedge])-6) +1; TOTAL[wedge] = sprintf("%5d ", TOTAL[wedge]); } } END{ wedges = wedge # decide on format strings Dir = "%-" max_dir_len "s " First = "%-" max_first_len "s " Wave = "Energy " Total = "total " Phi = " phi0 " Osc = " osc " Dist = "distance " Xbeam = " x_beam " Ybeam = " y_beam " Twotheta = "2theta " # Add = " add " # print out well-formatted versions of these lines if(wedges) { printf Dir Wave First Total Phi Osc Dist Xbeam Ybeam Twotheta"\\n", "directory", "First_Frame" } for(wedge=1;wedge<=wedges;++wedge) { if(FIRST[wedge]) printf Dir WAVE[wedge] First TOTAL[wedge] PHI[wedge] OSC[wedge] DIST[wedge] XBEAM[wedge] YBEAM[wedge] TWOTHETA[wedge] "\\n", DIR[wedge], FIRST[wedge] } } EOF-reformat chmod a+x ${tempfile}reformat.awk cat << EOF-labler >! ${tempfile}labler.awk #! $nawk -f # # Find a unique label for the set of items ending lines # among the words found on those lines # # { if(\$NF != Wave[w]) ++w Wave[w] = \$NF; wave[NR] = \$NF for(i=1;i 1)) { for(s=1;s<=waves;++s) { label[s] = substr(label[s], 2) } } else { done =1 } } ++catch if(catch > 1000) done =1 } for(w=1;w<=waves;++w) { # if(label[w] ~ /^f/) label[w] = "F" substr(label[w], 2) # if(label[w] !~ /^F/) label[w] = "F" label[w] print Wave[w], w, label[w] } } EOF-labler chmod a+x ${tempfile}labler.awk cat << EOF-sequence >! ${tempfile}sequence.awk #! $nawk -f # # Process/identify protein sequences in a text/pdb file # as > 20 consecutive, aa letters # # plus a few other goodies, such as monoisotopic mass, identifying # chemically unstable sequences, and common cleavage sites (using chop=yes) # # BEGIN { # one-letter amino-acid code OLC["ALA"] = "A" OLC["CYS"] = "C" OLC["ASP"] = "D" OLC["GLU"] = "E" OLC["PHE"] = "F" OLC["GLY"] = "G" OLC["HIS"] = "H" OLC["ILE"] = "I" OLC["LYS"] = "K" OLC["LEU"] = "L" OLC["MET"] = "M" OLC["MSE"] = "M" OLC["ASN"] = "N" OLC["PRO"] = "P" OLC["GLN"] = "Q" OLC["ARG"] = "R" OLC["SER"] = "S" OLC["THR"] = "T" OLC["VAL"] = "V" OLC["TRP"] = "W" OLC["TYR"] = "Y" # average mass H = 1.007947 C = 12.0111 N = 14.006747 O = 15.999943 P = 30.973762 S = 32.0666 Cl = 35.45279 Se = 78.963 # residue masses -NH-CH(R)-CO- aMass["G"] = 2*H+2*C+N+O+ H aMass["A"] = 2*H+2*C+N+O+ C+3*H aMass["V"] = 2*H+2*C+N+O+ C+H + 2*(C+3*H) aMass["I"] = 2*H+2*C+N+O+ C+H + C+2*H + 2*(C+3*H) aMass["L"] = 2*H+2*C+N+O+ C+2*H + C+H + 2*(C+3*H) aMass["D"] = 2*H+2*C+N+O+ C+2*H + C + 2*O +H aMass["N"] = 2*H+2*C+N+O+ C+2*H + C + O+N+2*H aMass["E"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C + 2*O +H aMass["Q"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C + O+N+2*H aMass["R"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + N + C + 2*(N+ 2*H) aMass["K"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + C+2*H + N+2*H aMass["M"] = 2*H+2*C+N+O+ C+2*H + C+2*H + S + C+3*H aMass["C"] = 2*H+2*C+N+O+ C+2*H + S+H aMass["S"] = 2*H+2*C+N+O+ C+2*H + O+H aMass["T"] = 2*H+2*C+N+O+ C+H + O+H + C+3*H aMass["H"] = 2*H+2*C+N+O+ C+2*H + C + C+H + N+H + C+H + N aMass["W"] = 2*H+2*C+N+O+ C+2*H + 3*C + 5*(C+H) + N+H aMass["F"] = 2*H+2*C+N+O+ C+2*H + C + 5*(C+H) aMass["Y"] = 2*H+2*C+N+O+ C+2*H + C + 5*(C+H) + O aMass["P"] = 1*H+2*C+N+O+ 3*(C+2*H) # monoisotopic mass (most abundant isotope) H = 1.007825 C = 12.00000 N = 14.003074 O = 15.994915 P = 30.973762 S = 31.972070 Cl = 34.968852 Se = 79.916520 # residue masses -NH-CH(R)-CO- iMass["G"] = 2*H+2*C+N+O+ H iMass["A"] = 2*H+2*C+N+O+ C+3*H iMass["V"] = 2*H+2*C+N+O+ C+H + 2*(C+3*H) iMass["I"] = 2*H+2*C+N+O+ C+H + C+2*H + 2*(C+3*H) iMass["L"] = 2*H+2*C+N+O+ C+2*H + C+H + 2*(C+3*H) iMass["D"] = 2*H+2*C+N+O+ C+2*H + C + 2*O +H iMass["N"] = 2*H+2*C+N+O+ C+2*H + C + O+N+2*H iMass["E"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C + 2*O +H iMass["Q"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C + O+N+2*H iMass["R"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + N + C + 2*(N+ 2*H) iMass["K"] = 2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + C+2*H + N+2*H iMass["M"] = 2*H+2*C+N+O+ C+2*H + C+2*H + S + C+3*H iMass["C"] = 2*H+2*C+N+O+ C+2*H + S+H iMass["S"] = 2*H+2*C+N+O+ C+2*H + O+H iMass["T"] = 2*H+2*C+N+O+ C+H + O+H + C+3*H iMass["H"] = 2*H+2*C+N+O+ C+2*H + C + C+H + N+H + C+H + N iMass["W"] = 2*H+2*C+N+O+ C+2*H + 3*C + 5*(C+H) + N+H iMass["F"] = 2*H+2*C+N+O+ C+2*H + C + 5*(C+H) iMass["Y"] = 2*H+2*C+N+O+ C+2*H + C + 5*(C+H) + O iMass["P"] = 1*H+2*C+N+O+ 3*(C+2*H) iMass["formyl"]= C + O iMass["p"] = P + 3*O } # read standard SEQRES cards from a PDB file /SEQRES/{ if(! seqres) seq = "" seqres = 1; for(i=4;i<=NF;++i) { seq = seq OLC[\$i] if(\$i !~ /^[A-Z][A-Z].\$/) continue if(OLC[\$i]=="") seq = seq "X" } } # don't do other kinds of search in a PDB file seqres {next} # read sequence of a PDB /^ATOM / && substr(\$0,12,5) == " CA " { if(! pdb) seq = "" pdb = 1 Restype = substr(\$0, 18, 3) Segid = substr(\$0, 22, 1) # O/Brookhaven-style segment ID Resnum = substr(\$0, 23, 4)+0 # check for breaks if((Segid != lastSegid)||(nextResnum != Resnum)) { # break in chain seq = seq " " lastSegid = Segid } nextResnum = Resnum +1 # translate three-letter code to one letter seq = seq OLC[Restype] if(OLC[Restype]=="") seq = seq "X" } # don't do other kinds of search in a PDB file pdb {next} # recognize ENTREZ files \$1~/[0-9]/ && \$1+0==\$1 && \$2 !~ /[^a-z]/ && \$NF !~ /[^a-z]/ && NF<10{ if(! entrez) seq="" entrez = 1 \$0=\$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 \$10 \$11 } (length(\$0) > 9 || seq != "") && ! /^>/ { #{ # remove leading spaces line = "" for(i=1;i= 20 || seqres) { # look for all the horrible things that can happen to the peptide acid = "" base = "" race = "" pyroQ = "" CNBr = "" factorXa = "" chymotrypsin = "" endoproteinaseDN = "" endoproteinaseKC = "" thrombin = "" trypsin = "" pepsin = "" V8 = "" # weigh this chain weight = Met = His = Cys = A280 = ""; weight = O + 3*H; mass = O + 3*H; for(i=1;i<=length(sequence[n]);++i) { c = substr(sequence[n], i, 1); # weigh this chain weight += aMass[c]; mass += aMass[c]; # count potentially derivitized residues if(c == "M") ++Met; if(c == "C") ++Cys; if(c == "H") ++His; # add up (denatured) extinction coefficient if(c == "W") A280 += 5600 if(c == "Y") A280 += 1400 if(c == "F") A280 += 197 # chemical instabilities (add up single-cleavage MWs) if(c == "M" ) CNBr = CNBr " " mass if(substr(sequence[n],i,2) == "DP") acid = acid " " mass if(substr(sequence[n],i,2) == "NG") base = base " " mass if(substr(sequence[n],i,2) == "NG") race = race ", " i if(substr(sequence[n],1,1) == "Q") pyroQ = 1 if((substr(sequence[n],1,1) == "M")&&(substr(sequence[n],2,1) == "Q")) pyroQ = 2 # proteolytic recognition sites (add up single-cleavage MWs)? if(substr(sequence[n],i-3,4) == "IEGR") factorXa = factorXa " " mass if(substr(sequence[n],i+1,1) == "D") endoDN = endoDN " " mass if(c ~ /[Y,F,W]/) chymotrypsin = chymotrypsin " " mass # if(c ~ /[L,M,A,N,E]/) chymotrypsin = chymotrypsin " " mass "*" if(c ~ /[K]/) endoKC = endoKC " " mass if(c ~ /[R]/) thrombin = thrombin " " mass if(c ~ /[R,K]/) trypsin = trypsin " " mass if(c ~ /[F,L]/) pepsin = pepsin " " mass # if(c ~ /[Y,W,I,M]/) pepsin = pepsin " " mass "*" if(c ~ /[E]/) V8 = V8 " " mass if(c ~ /[E]/) V82 = V82 " " mass if(c ~ /[D]/) V82 = V82 " " mass } # finish off cleavages acid = acid " " mass base = base " " mass CNBr = CNBr " " mass factorXa = factorXa " " mass chymotrypsin = chymotrypsin " " mass endoDN = endoDN " " mass endoKC = endoKC " " mass thrombin = thrombin " " mass trypsin = trypsin " " mass pepsin = pepsin " " mass V8 = V8 " " mass # we have found an acceptable protein sequence print mass " Da chain: " l=length(sequence[n]) while(length(sequence[n]) > 0) { # actually print out sequence here print substr(sequence[n], 1, 80) sequence[n] = substr(sequence[n], 81) } print "" print l "aa" print Met+0 "met" print Cys+0 "cys" print His+0 "his" print "" printf "denatured A(280nm) = %.4f*l*c (c in g/L)\\n", A280/weight printf " SeMET MAD Rano = %.3f%%\\n", 100*(Met*8^2)/(7^2 * (weight/14)) print "" f=split(acid base, Split) if((f>2) || pyroE != "") { print "Chemical Instabilities: " } f=split(acid, Split) if(f>1) { printf "acid (D*P): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(base, Split) if(f>1) { printf "base (N*G): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" print "racemization hazard at" substr(race,2) } if(pyroQ) { print "residue " pyroQ " could form an N-cyclized glutamine " } if(chop) { print "" f=split(CNBr, Split) if(f>1) { printf "CNBr (M*): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } print "" print "Common proteases: " f=split(factorXa, Split) if(f>1) { printf "factorXa (IEGR*): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(thrombin, Split) if(f>1) { printf "thrombin (R*): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(trypsin, Split) if(f>1) { printf "trypsin (R*, K*): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(endoKC, Split) if(f>1) { printf "endoproteinase Lys-C (K*): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(endoDN, Split) if(f>1) { printf "endoproteinase Asp-N (*D): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(chymotrypsin, Split) if(f>1) { printf "chymotrypsin (W*,Y*,F*, +others): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(pepsin, Split) if(f>1) { printf "pepsin (F*, L*, +others): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(V8, Split) if(f>1) { printf "V8 protease (E*): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } f=split(V82, Split) if(f>1) { printf "V8 protease (E*,D*): " for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " " print "" } } } } EOF-sequence chmod a+x ${tempfile}sequence.awk cat << EOF-elements >! ${tempfile}elements.awk #! $nawk -f # # General-purpose database for equating elements # with their x-ray absorption edges (and f', f" values) # # if the first word on the line is an element symbol or name, # an x-ray spectrum for that element will be displayed # # if the first thing on the line is a number (energy or wavelength) # the element with an edge closest to that energy will be displayed # # if the line is an element and a number (energy or wavelength) # the edge of the provided element closest to that energy will be given. # # nothing gets printed if no match is found # BEGIN{ # at no Sym Name element[1] = "H Hydrogen " element[2] = "He Helium " element[3] = "Li Lithium " element[4] = "Be Beryllium " element[5] = "B Boron " element[6] = "C Carbon " element[7] = "N Nitrogen " element[8] = "O Oxygen " element[9] = "F Fluorine " element[10] = "Ne Neon " element[11] = "Na Sodium " element[12] = "Mg Magnesium " element[13] = "Al Aluminum " element[14] = "Si Silicon " element[15] = "P Phosphorus " element[16] = "S Sulfur " element[17] = "Cl Chlorine " element[18] = "Ar Argon " element[19] = "K Potassium " element[20] = "Ca Calcium " element[21] = "Sc Scandium " element[22] = "Ti Titanium " element[23] = "V Vanadium " element[24] = "Cr Chromium " element[25] = "Mn Manganese " element[26] = "Fe Iron " element[27] = "Co Cobalt " element[28] = "Ni Nickel " element[29] = "Cu Copper " element[30] = "Zn Zinc " element[31] = "Ga Gallium " element[32] = "Ge Germanium " element[33] = "As Arsenic " element[34] = "Se Selenium " element[35] = "Br Bromine " element[36] = "Kr Krypton " element[37] = "Rb Rubidium " element[38] = "Sr Strontium " element[39] = "Y Yttrium " element[40] = "Zr Zirconium " element[41] = "Nb Niobium " element[42] = "Mo Molybdenum " element[43] = "Tc Technetium " element[44] = "Ru Ruthenium " element[45] = "Rh Rhodium " element[46] = "Pd Palladium " element[47] = "Ag Silver " element[48] = "Cd Cadmium " element[49] = "In Indium " element[50] = "Sn Tin " element[51] = "Sb Antimony " element[52] = "Te Tellurium " element[53] = "I Iodine " element[54] = "Xe Xenon " element[55] = "Cs Cesium " element[56] = "Ba Barium " element[57] = "La Lanthanum " element[58] = "Ce Cerium " element[59] = "Pr Praseodymium " element[60] = "Nd Neodymium " element[61] = "Pm Promethium " element[62] = "Sm Samarium " element[63] = "Eu Europium " element[64] = "Gd Gadolinium " element[65] = "Tb Terbium " element[66] = "Dy Dysprosium " element[67] = "Ho Holmium " element[68] = "Er Erbium " element[69] = "Tm Thulium " element[70] = "Yb Ytterbium " element[71] = "Lu Lutetium " element[72] = "Hf Hafnium " element[73] = "Ta Tantalum " element[74] = "W Tungsten " element[75] = "Re Rhenium " element[76] = "Os Osmium " element[77] = "Ir Iridium " element[78] = "Pt Platinum " element[79] = "Au Gold " element[80] = "Hg Mercury " element[81] = "Tl Thallium " element[82] = "Pb Lead " element[83] = "Bi Bismuth " element[84] = "Po Polonium " element[85] = "At Astatine " element[86] = "Rn Radon " element[87] = "Fr Francium " element[88] = "Ra Radium " element[89] = "Ac Actinium " element[90] = "Th Thorium " element[91] = "Pa Protactinium " element[92] = "U Uranium " element[93] = "Np Neptunium " element[94] = "Pu Plutonium " element[95] = "Am Americium " element[96] = "Cm Curium " element[97] = "Bk Berkelium " element[98] = "Cf Californium " element[99] = "Es Einsteinium " element[100] = "Fm Fermium " element[101] = "Md Mendelevium " element[102] = "No Nobelium " element[103] = "Lr Lawrencium " # x-ray edge information (condensed to "interesting" points) F["H " 1] = "1 H Hydrogen - - - " F["He " 1] = "2 He Helium - - - " F["Li " 1] = "3 Li Lithium - - - " F["Be " 1] = "4 Be Beryllium - - - " F["B " 1] = "5 B Boron - - - " F["C " 1] = "6 C Carbon - - - " F["N " 1] = "7 N Nitrogen - - - " F["O " 1] = "8 O Oxygen - - - " F["F " 1] = "9 F Fluorine - - - " F["Ne " 1] = "10 Ne Neon - - - " F["Na " 1] = "11 Na Sodium - - - " F["Mg " 1] = "12 Mg Magnesium - - - " F["Al " 1] = "13 Al Aluminum - - - " F["Si " 1] = "14 Si Silicon - - - " F["P " 3] = "15 P Phosphorus 2148 -7.423 4.112 edge" F["S " 3] = "16 S Sulfur 2475 -7.264 4.104 edge" F["Cl " 3] = "17 Cl Chlorine 2825 -7.487 4.091 edge" F["Ar " 4] = "18 Ar Argon 3205 -7.788 4.074 edge" F["K " 4] = "19 K Potassium 3610 -7.584 4.063 edge" F["Ca " 6] = "20 Ca Calcium 4041 -7.499 4.053 edge" F["Sc " 6] = "21 Sc Scandium 4495 -7.856 4.030 edge" F["Ti " 6] = "22 Ti Titanium 4969 -7.703 4.008 edge" F["V " 7] = "23 V Vanadium 5468 -7.623 3.995 edge" F["Cr " 7] = "24 Cr Chromium 5992 -7.701 3.973 edge" F["Mn " 8] = "25 Mn Manganese 6542 -7.670 3.962 edge" F["Fe " 9] = "26 Fe Iron 7115 -7.712 3.950 edge" F["Co " 9] = "27 Co Cobalt 7711 -8.149 3.939 edge" F["Ni " 10] = "28 Ni Nickel 8335 -8.132 3.920 edge" F["Cu " 10] = "29 Cu Copper 8981 -8.209 3.901 edge" F["Zn " 11] = "30 Zn Zinc 9661 -8.112 3.896 edge" F["Ga " 12] = "31 Ga Gallium 10370 -7.949 3.892 edge" F["Ge " 13] = "32 Ge Germanium 11106 -7.981 3.881 edge" F["As " 13] = "33 As Arsenic 11869 -8.255 3.865 edge" F["Se " 14] = "34 Se Selenium 12660 -8.320 3.846 edge" F["Br " 15] = "35 Br Bromine 13476 -8.289 3.826 edge" F["Kr " 16] = "36 Kr Krypton 14328 -8.256 3.806 edge" F["Rb " 17] = "37 Rb Rubidium 15200 -10.436 3.787 edge" F["Sr " 18] = "38 Sr Strontium 16107 -8.266 3.774 edge" F["Y " 19] = "39 Y Yttrium 17041 -8.191 3.754 edge" F["Zr " 19] = "40 Zr Zirconium 18000 -8.283 3.736 edge" F["Nb " 20] = "41 Nb Niobium 18988 -8.288 3.714 edge" F["Mo " 21] = "42 Mo Molybdenum 20000 -9.878 3.698 edge" F["Tc " 23] = "43 Tc Technetium 21046 -8.489 3.680 edge" F["Ru " 24] = "44 Ru Ruthenium 22120 -8.164 3.665 edge" F["Rh " 25] = "45 Rh Rhodium 23222 -8.459 3.650 edge" F["Pd " 26] = "46 Pd Palladium 24353 -8.219 3.633 edge" F["Ag " 4] = "47 Ag Silver 3354 -20.966 10.518 edge" F["Ag " 5] = "47 Ag Silver 3526 -16.055 13.800 edge" F["Ag " 6] = "47 Ag Silver 3808 -10.003 14.611 edge" F["Cd " 4] = "48 Cd Cadmium 3540 -21.398 10.767 edge" F["Cd " 5] = "48 Cd Cadmium 3730 -15.432 13.792 edge" F["Cd " 7] = "48 Cd Cadmium 4021 -9.699 14.245 edge" F["In " 4] = "49 In Indium 3733 -21.152 11.048 edge" F["In " 5] = "49 In Indium 3941 -15.141 13.784 edge" F["In " 7] = "49 In Indium 4240 -9.690 13.866 edge" F["Sn " 6] = "50 Sn Tin 4159 -14.958 13.683 edge" F["Sb " 6] = "51 Sb Antimony 4135 -21.027 11.070 edge" F["Sb " 8] = "51 Sb Antimony 4383 -14.902 13.571 edge" F["Te " 6] = "52 Te Tellurium 4344 -21.057 11.006 edge" F["Te " 8] = "52 Te Tellurium 4615 -14.559 13.442 edge" F["I " 6] = "53 I Iodine 4560 -20.634 10.936 edge" F["I " 8] = "53 I Iodine 4855 -14.434 13.310 edge" F["Xe " 6] = "54 Xe Xenon 4785 -20.563 10.874 edge" F["Xe " 9] = "54 Xe Xenon 5106 -14.540 13.185 edge" F["Cs " 7] = "55 Cs Cesium 5014 -21.106 10.876 edge" F["Cs " 9] = "55 Cs Cesium 5362 -14.233 13.120 edge" F["Ba " 7] = "56 Ba Barium 5250 -20.109 10.809 edge" F["Ba " 9] = "56 Ba Barium 5626 -14.171 12.992 edge" F["La " 7] = "57 La Lanthanum 5485 -20.405 10.570 edge" F["La " 9] = "57 La Lanthanum 5893 -14.030 12.840 edge" F["Ce " 7] = "58 Ce Cerium 5726 -20.237 10.734 edge" F["Ce " 10] = "58 Ce Cerium 6167 -13.634 12.698 edge" F["Pr " 7] = "59 Pr Praseodymium 5967 -20.069 10.711 edge" F["Pr " 10] = "59 Pr Praseodymium 6443 -13.610 12.615 edge" F["Nd " 8] = "60 Nd Neodymium 6210 -20.540 10.661 edge" F["Nd " 10] = "60 Nd Neodymium 6724 -13.655 12.624 edge" F["Pm " 8] = "61 Pm Promethium 6462 -19.898 10.625 edge" F["Pm " 11] = "61 Pm Promethium 7015 -13.710 12.558 edge" F["Sm " 8] = "62 Sm Samarium 6719 -19.794 10.651 edge" F["Sm " 11] = "62 Sm Samarium 7314 -13.591 12.442 edge" F["Eu " 8] = "63 Eu Europium 6979 -20.382 10.648 edge" F["Eu " 11] = "63 Eu Europium 7620 -13.183 12.345 edge" F["Gd " 9] = "64 Gd Gadolinium 7245 -20.213 10.609 edge" F["Gd " 11] = "64 Gd Gadolinium 7933 -13.095 12.185 edge" F["Tb " 9] = "65 Tb Terbium 7517 -19.488 10.612 edge" F["Tb " 12] = "65 Tb Terbium 8254 -13.276 12.233 edge" F["Dy " 9] = "66 Dy Dysprosium 7793 -19.495 10.588 edge" F["Dy " 12] = "66 Dy Dysprosium 8583 -13.206 12.196 edge" F["Ho " 10] = "67 Ho Holmium 8074 -19.458 10.591 edge" F["Ho " 12] = "67 Ho Holmium 8920 -13.268 12.188 edge" F["Er " 10] = "68 Er Erbium 8360 -20.135 10.578 edge" F["Er " 13] = "68 Er Erbium 9267 -12.986 12.157 edge" F["Tm " 10] = "69 Tm Thulium 8651 -19.330 10.573 edge" F["Tm " 13] = "69 Tm Thulium 9619 -13.222 12.154 edge" F["Yb " 10] = "70 Yb Ytterbium 8946 -19.795 10.547 edge" F["Yb " 13] = "70 Yb Ytterbium 9981 -12.747 11.816 edge" F["Lu " 11] = "71 Lu Lutetium 9247 -19.360 10.547 edge" F["Lu " 14] = "71 Lu Lutetium 10351 -12.855 11.722 edge" F["Hf " 11] = "72 Hf Hafnium 9563 -19.843 10.527 edge" F["Hf " 14] = "72 Hf Hafnium 10742 -12.733 11.655 edge" F["Ta " 11] = "73 Ta Tantalum 9884 -19.294 10.511 edge" F["Ta " 15] = "73 Ta Tantalum 11139 -12.418 11.449 edge" F["W " 12] = "74 W Tungsten 10209 -19.840 10.496 edge" F["W " 15] = "74 W Tungsten 11547 -12.327 11.384 edge" F["Re " 12] = "75 Re Rhenium 10538 -19.058 10.226 edge" F["Re " 15] = "75 Re Rhenium 11961 -12.563 11.463 edge" F["Os " 12] = "76 Os Osmium 10873 -19.529 10.214 edge" F["Os " 16] = "76 Os Osmium 12388 -12.224 11.392 edge" F["Ir " 13] = "77 Ir Iridium 11218 -18.898 10.201 edge" F["Ir " 16] = "77 Ir Iridium 12827 -12.200 11.311 edge" F["Pt " 13] = "78 Pt Platinum 11566 -19.273 10.202 edge" F["Pt " 17] = "78 Pt Platinum 13275 -12.348 11.248 edge" F["Au " 13] = "79 Au Gold 11921 -19.230 10.206 edge" F["Au " 17] = "79 Au Gold 13736 -12.285 11.152 edge" F["Hg " 14] = "80 Hg Mercury 12286 -19.370 10.191 edge" F["Hg " 18] = "80 Hg Mercury 14211 -12.270 11.078 edge" F["Tl " 14] = "81 Tl Thallium 12660 -18.943 10.157 edge" F["Tl " 18] = "81 Tl Thallium 14700 -12.289 11.003 edge" F["Pb " 15] = "82 Pb Lead 13038 -18.670 10.135 edge" F["Pb " 19] = "82 Pb Lead 15203 -11.882 10.933 edge" F["Bi " 15] = "83 Bi Bismuth 13421 -18.941 10.125 edge" F["Bi " 19] = "83 Bi Bismuth 15714 -11.873 10.838 edge" F["Po " 15] = "84 Po Polonium 13816 -19.063 10.103 edge" F["Po " 20] = "84 Po Polonium 16247 -11.883 10.757 edge" F["At " 16] = "85 At Astatine 14216 -18.784 10.081 edge" F["At " 20] = "85 At Astatine 16787 -12.007 10.679 edge" F["Rn " 16] = "86 Rn Radon 14622 -18.663 10.054 edge" F["Rn " 21] = "86 Rn Radon 17340 -11.749 10.609 edge" F["Fr " 17] = "87 Fr Francium 15034 -18.475 10.029 edge" F["Fr " 21] = "87 Fr Francium 17909 -11.846 10.524 edge" F["Ra " 17] = "88 Ra Radium 15447 -18.590 10.015 edge" F["Ra " 22] = "88 Ra Radium 18487 -11.732 10.428 edge" F["Ac " 17] = "89 Ac Actinium 15874 -18.287 9.988 edge" F["Ac " 23] = "89 Ac Actinium 19086 -11.670 10.341 edge" F["Th " 6] = "90 Th Thorium 4049 -23.021 31.611 edge" F["Th " 20] = "90 Th Thorium 16303 -18.447 9.968 edge" F["Th " 25] = "90 Th Thorium 19696 -11.637 10.266 edge" F["Pa " 6] = "91 Pa Protactinium 4176 -22.092 33.098 edge" F["Pa " 20] = "91 Pa Protactinium 16736 -18.320 9.964 edge" F["Pa " 26] = "91 Pa Protactinium 20316 -11.818 10.184 edge" F["U " 6] = "92 U Uranium 4306 -20.788 35.007 edge" F["U " 21] = "92 U Uranium 17169 -18.441 9.957 edge" F["U " 26] = "92 U Uranium 20950 -11.751 10.094 edge" F["Np " 1] = "93 Np Neptunium - - - " F["Pu " 1] = "94 Pu Plutonium - - - " F["Am " 1] = "95 Am Americium - - - " F["Cm " 1] = "96 Cm Curium - - - " F["Bk " 1] = "97 Bk Berkelium - - - " F["Cf " 1] = "98 Cf Californium - - - " F["Es " 1] = "99 Es Einsteinium - - - " F["Fm " 1] = "100 Fm Fermium - - - " F["Md " 1] = "101 Md Mendelevium - - - " F["No " 1] = "102 No Nobelium - - - " F["Lr " 1] = "103 Lr Lawrencium - - - " } Z = iselement(\$1) { # element symbol or name given Ee = substr(element[Z], 1, 3) if(energy = isenergy(\$2)) { # print edge f' and f'' closest to this energy bestdist = 9999999 for(i=1;i<40;++i) { split(F[Ee i], e) dist = sqrt((e[4] - energy)^2) if(dist < bestdist) { bestdist = dist entry=F[Ee i]; } } print entry; } else { # print out full "spectrum" for this element for(i=1;i<40;++i) { if(F[Ee i]) print F[Ee i] } } } # get element with edge closest to a given energy energy = isenergy(\$1) { mindist = 99999999 for(val in F) { n=split(F[val],e) # skip non-edge values here if(e[n] == "edge") { dist = sqrt((e[4] - energy)^2) if((dist < mindist)||((dist == mindist)&&(e[1] < bestelement+0))) { mindist = dist bestelement = F[val] } } } print bestelement } \$0 == "all elements" { for(Z=1;Z<104;++Z) { Ee = substr(element[Z], 1, 3) for(i=1;i<40;++i) { if(F[Ee i]) print F[Ee i]; } } } function isenergy(number) { energy = number if(number > 0) number += 0 if(number > 0 && number < 1000) { energy = 12398.4245/number } if((energy < 1000)||(energy > 25000)) energy = 0 return energy } function iselement(string) { reply = 0 for(z in element) { split(element[z], w) if((string == w[1])||(tolower(string) == tolower(w[2]))) { reply = z break; } } return reply } EOF-elements chmod a+x ${tempfile}elements.awk cat << EOF-x >! ${tempfile}x.awk EOF-x chmod a+x ${tempfile}x.awk rm -f ${tempfile}x.awk goto RetrnUnwrap_Awk_Scripts exit Cleanup_Elves: echo "Cleaning up ..." rm -f ${tempfile}* >& /dev/null if($?BAD) then echo "Dang! " exit 9 endif # see if we have jobs running set jobs = `jobs |& wc -l` set jobs = `setenv COLUMNS 1000 ; ps -lea | nawk -v us=$$ 'NR==1{for(i=1;i<=NF;++i)if($i~/PPID/)ppid=i} $ppid == us && $NF=="Processer"' | wc -l` if($jobs) then # inform user of other processing options cat << EOF You can also use Elves on other computers to help out with this data set. To do this, log into the remote computer system, cd to this same directory, and launch a copy or two of Processer Elves: ssh anothermachine cd `pwd` ./Elfsheim/Processer $HURRY >&! processing5.log & ./Elfsheim/Processer $HURRY >&! processing6.log & etc... to see your Elves Processer jobs, type: ps -fu `whoami` | grep Processer to stop your Elves Processer jobs, type: EOF ps -ju `whoami` | nawk 'NR==1{for(i=1;i! ${Elfsheim}/Wedger #! /bin/csh -f # echo "Wedger Elves 1.3.16 Because you have better things to do.(TM) James Holton 10-31-16" echo "" # # automatic X-ray data wedge processor # and mosflm script generator # # Wedger elves use a wide, flexible range of input information to build a # runnable MOSFLM script to process a single wedge of crystallographic # X-ray data, and then run it. If left on their own, the elves will go # to great lengths to find the informaion they need in the computer's # filesystem. In either case, the elves make a brief presentation for # your approval before processing your data. # Try it! Let me know what you think. # # JMHolton@lbl.gov # if(\$#argv == 0) cat << EOF-lawyers Copyright ©1999. The Regents of the University of California (Regents). All Rights Reserved. Permission to use, copy, modify, and distribute this software and its documentation for educational, research, and not-for-profit purposes, without fee and without a signed licensing agreement, is hereby granted, provided that the above copyright notice, this paragraph and the following two paragraphs appear in all copies, modifications, and distributions. Contact The Office of Technology Licensing, UC Berkeley, 2150 Shattuck Avenue, Suite 510, Berkeley, CA 94720-1620, (510) 643-7201, for commercial licensing opportunities. Created by James Holton, Department of Molecular and Cell Biology, University of California, Berkeley. IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. EOF-lawyers # # # For most variables, the precedence of information sources goes something like # this: # 1) Interactive User input (command-line, etc.) in order given # 2) Stuff found in files given by user (in order given) # 2) Info in files from last Mosflm run # 3) Stuff found in nearby computer files # 4) Image File Header # 5) Internal Defaults # # # EG: If an image file is specified on the command line, that file's name # will take precedence over any scripts when determining the # location and number of frames. # #################################################################################### # # Other programs that Wedger's elves need to work: # /bin/csh (tested on IRIX, OSF1, linux) # nawk # grep # egrep # ipmosflm (of course) tested with v 5.5x 6.x and 7.x # CCP4 (mtzdump, sortmtz, scala, truncate, combat) # # #################################################################################### #################################################################################### # Set up OS-specific fixes (not too many we hope) set OPERATING_SYSTEM = \`uname\` set prefered = gawk if("\$OPERATING_SYSTEM" =~ IRIX*) set prefered = nawk if("\$OPERATING_SYSTEM" == "linux") set prefered = awk # make sure nawk works set program = "nawk" foreach name ( \$prefered gawk nawk awk ) test -x "\$program" if(! \$status) break set possibilities = \`which \$name |& grep -v ' not in ' | tail -1\` foreach file ( \$possibilities ) test -x "\$file" if(! \$status) then # test for desired functionality (change this?) set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\` if("\$temp" == 856) then set program = "\$file" break endif endif end unset possibilities end test -x "\$program" if(\$status) then set program = "awk" foreach place ( /bin /usr/bin /usr/local/bin ) test -x "\$program" if((\$status)&&(-e \$place)) then # keep looking set files = \`ls -1L \${place} |& grep "\$program" |& sort -k5n |& head -20 \` foreach file ( \$files ) # test for desired functionality set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\` if("\$temp" == 856) then set program = "\$file" break endif end endif end endif # agressively search for nawk in likely places test -x "\$program" if(\$status) then echo -n "Looking for \$program " foreach place ( /bin /usr/bin /usr/local/bin /usr / ) test -x "\$program" if((\$status)&&(-e \$place)) then if("\$place" == "/") echo -n "uhh" # use find to get candidate files set files = \`find \$place -name '*'\$program \\( -type l -o \\( -type f -size +10000c \\) \\) -perm -1 -print |& egrep -v "^find:" |& head -20\` foreach file ( \$files ) # test for desired functionality set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\` if("\$temp" == 856) then set program = "\$file" break endif end endif # entertainment echo -n "." end endif # check that we found the right awk program set temp = \`echo "1.54" | \$program '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\` if("\$temp" == 856) then # set up this awk program as nawk set nawk = "\$program" alias nawk \$nawk else echo "Dagnabbit! We can't find a suitable awk program. What kind of unix is this? " echo "Elves may not be able to work." set nawk = /bin/awk alias nawk awk endif # nice symbols, but may not be portable set ANG = \`echo "" | nawk 'BEGIN{printf "\\305"}'\` set DEG = \`echo "" | nawk 'BEGIN{printf "\\260"}'\` if("\$OPERATING_SYSTEM" =~ IRIX*) then # this will work for sure set ANG = \`echo "\\0305"\` set DEG = \`echo "\\0260"\` endif # I give up... set ANG = "A" set DEG = " deg" # fix OSF1 csh echo shortcomings set temp = \`echo -n "test"\` if((\$#temp == 2)&&(-e /usr/bin/echo)) then alias echo /usr/bin/echo endif # CCP4 is handled later # check that current directory is writable touch ./this\$\$ >& /dev/null if(\$status) then # can't write to current directory! chmod u+w . >& /dev/null touch ./this\$\$ >& /dev/null if(\$status) then # can't chmod current directory either echo "ERROR! We can't write to this directory! " pwd echo "Please cd to the place you want to process your data, and" echo "then run \$0 again." exit 9 else # warn user about what we did echo "Had to make current directory writable:" echo "chmod u+w ." endif rm -f ./this\$\$ >& /dev/null endif rm -f ./this\$\$ >& /dev/null # fix old Irix od shortcomings alias ood od echo "test" >! ./this\$\$ set test = \`od -c -j 2 -N 4 this\$\$ |& nawk '{print \$2}'\` if("\$test" != "s") then # no -j option supported, compensate: # od -x -j offset ... --> od -x ... offset #alias ood /bin/od alias ood \`which od | tail -1 | awk '{print \$NF}'\` alias od 'od \\!:1 \\!:\$ \\!:3.' set WEAK_od endif rm -f ./this\$\$ >& /dev/null # character for ringing the terminal bell (alert user) set BELL = \`echo "" | nawk 'BEGIN{printf "\\07"}'\` set oldTTYerase = "^H" # go automatic if user is ignoring us test -t 1 if(\$status) then echo "output is not a terminal." # Q&A would stop Wedger process cold echo "Wedger elves will answer their own questions." echo "" echo "\$0 \$*" echo "on "\`hostname -s\`" at "\`date +"%T %D"\` echo "in "\`pwd\` set AUTO else # fix annoying TTY ^H characters (but save the current one so we don't mess up emacs) set oldTTYerase = \`stty -a | nawk '{for(i=1;i<=NF;++i){if(\$i == "erase"){print substr(\$(i+2),1,2)}}}'\` #stty erase ^H endif # prevent file overwrite errors? #unset noclobber # no core dumping! limit coredumpsize 0 # prevent never-ending mosflm jobs (5 hours)? #limit cputime 18000 # clean up if Wedger Elves are killed #onintr Cleanup onintr # # set Wedger prompt set PROMPT = "W. Elves-> " # # English input is command line set FIRSTIME #################################################################################### set mosflm_status = 0 set last_mosflm_status = 0 set last_mosflm_status = 0 set last_mosflm_failure = 0 set last_changed = "" set last_failure = "" set failure_count = 0 set chronic_failures = 0 set temp set input set Delta_orient = 99 set Delta_mosaic = 99 set Delta_distance = 99 set Delta_cell = 99 set shift_orient = 10 set shift_mosaic = 10 set shift_distance = 10 set shift_cell = 10 # program limits set MAX_Cycles = 50 set Cycle = 0 set Successes = 0 # reduce these if you are getting "word to long" errors set MAXLINE = 1000 set MAXWORDS = 10 # or if Wedger elves are looking at too many scripts set MAXSCRIPTS = 5 # list of known image filename patterns set IMAGE_pattern = 'BEGIN{FS="."} {n=NF-1;if(n<1)n=1} \$n~/[0-9][0-9][0-9]\$/ || \$NF~/[0-9][0-9][0-9]\$/{print}' set not_IMAGE_pattern = '! (/[0-9][0-9][0-9].img\$/ || /[0-9][0-9][0-9].osc\$/ || /[0-9][0-9][0-9].image\$/ || /[0-9][0-9][0-9].cbf\$/ || /[0-9][0-9][0-9].mar/ || /[0-9][0-9][0-9][0-9]\$/ && ! /^[PCIFHR][1-6]/ || /[0-9][0-9][0-9].corr\$/)' # predefine list of "potentially" useful mosflm cards set MOSFLM_CARDS = "SITE SCAN POLAR GAIN DIRE IDEN EXT IMAG \\ MATRIX NEWMAT WAVE DISP DIVE BEAM BACKSTOP DISTA \\ CELL SYMM LATT MOSAIC RESO DSTARMAX TWOT PROFILE \\ ADCO BACKG BIAS BSWA DISTO SYNC THICK SHIFT \\ FIDU SIZE LIMIT PIXEL NULLP OVERLOAD SEPA ADDP \\ MAXWIDTH POSTREF PROCESS REFI RAST REJECT PRINT SDMON \\ WAIT PLOT SPOTS" set MOSFLM_CARDS = \`echo \$MOSFLM_CARDS\` # list of mosflm cards used in file search set SEARCH_CARDS = "^SITE|^SCAN|^LIMIT|^POLAR|^GAIN|^DIRE|^IDEN|^EXT|^IMAG|^MATRIX|^NEWMAT|^WAVE|^DISP|^DIVE|^BEAM|^BACKSTOP|^DISTA|^CELL|^SYMM|^MOSAIC|^RESO|^RASTER" # list of relevant mosflm cards not handled by Wedger (yet) set PASSTHRU_CARDS = "^BACKSTOP|^FINDSP|^SPOTS |^LATTICE|^DSTARMAX|^PROFILE|^ADCO|^BACKG|^BIAS|^BSWA|^DISTO|^SYNC|^THICK|^SHIFT|^FIDU|^SIZE|^PIXEL|^NULLP|^NUSPOT OFF|^SEPA|^ADDP|^MAXWIDTH|^RAST|^REJECT|^PRINT|^SDMON|^WAIT|^CAMCON" # set PREAMBLE = "" set EXTRA_REFINE_CARDS = "" unsetenv MOSFLM_VERSION_NUMBERS # # check that directory is writable touch ./this\$\$ >& /dev/null if(\$status) then # can't write to current directory! chmod u+w . >& /dev/null touch ./this\$\$ >& /dev/null if(\$status) then # can't chmod current directory either echo "ERROR! We can't write to this directory! " pwd echo "Please cd to the place you want to process your data, and" echo "then run \$0 again." exit 9 else # warn user about what we did echo "Had to make current directory writable:" echo "chmod u+w ." endif endif rm -f ./this\$\$ >& /dev/null # make needed directories #if( -e temp) then # test -d temp >& /dev/null # if(\$status) then # echo "WARNING: moving temp to temp.bak" # mv temp temp.bak # endif #endif if( -e logs) then test -d logs >& /dev/null if(\$status) then echo "WARNING: moving logs to logs.bak" mv logs logs.bak endif endif #if(! -e temp) mkdir temp if(! -e logs) mkdir logs #################################################################################### #################################################################################### #################################################################################### # process "dash" options immediately set command_line_argv = \$0 set i = 1 while( \$i <= \$#argv ) set arg = \$argv[\$i] if("\$arg" =~ -norun) set NORUN if("\$arg" == -1) set ONCEONLY if("\$arg" == -1) set AUTO if("\$arg" == -auto) set AUTO if("\$arg" == -new) set NEW if("\$arg" == new) set NEW if("\$arg" =~ *index) set NEW if("\$arg" =~ *index) set autoindexing if("\$arg" =~ "-"nosear*) set NEW if("\$arg" =~ nosear*) set NEW if((("\$arg" == no)||("\$arg" == "-no"))&&(\$i < \$#argv)) then @ i = ( \$i + 1 ) if("\$argv[\$i]" =~ sear*) set NEW endif if(("\$arg" == "-burst")||("\$arg" == "hurry")) then set HURRY set BURSTMODE = 3 if(\$i < \$#argv) then # look for a user-specified burst count @ i = ( \$i + 1 ) set temp = \`echo \$argv[\$i] | nawk '{printf "%d", \$0+0}'\` if(\$temp != 0) then set BURSTMODE = \$temp # don't confuse this with image count set argv[\$i] = "" endif endif endif if("\$arg" =~ -h*) set help @ i = ( \$i + 1 ) end if((\$?help)||(\$#argv == 0)) then cat << EOF usage: \$0 [/dir/[image_001.img]] [script.com] [num] [SG] [[fix]cell a b c A B G] (items in braces [] are optional.) /dir : location of frames to process image_001.img : name of first image to process num : number of images to process SG : space group script.com : name of file containing beamline-specific mosflm cards (like an old script) refinement options: (no)refine : (don't) refine cell on a subset of frames (no)integrate : (don't) integrate spots on all frames (no)fixcell : (don't) fix the cell during refinement (no)fixyscale : (don't) fix the Y scale during refinement program options: -norun : create the mosflm script, but don't run it. -1 : single-shot (exit after one mosflm run) -semi : semi- automatic (default) prompts user for go-ahead. -burst [n] : n-round burst (default: 3 refinement runs, and integrate once) -auto : fully automatic (run a standard processing regimen) -new : ignore old files and start mosflm refinement fresh -nice : tell Wedger elves to nice their jobs -h : display this message EOF # (no)usebeam : (don't) use refined mosaicity, distance, etc. in integration (default) endif if(\$?help) exit #################################################################################### # Internal Defaults # # Easily overridden by pevious script, image file, or questionaire. #################################################################################### # # Input files set best_matrix = best.mat set inmatrix = "" set inframes = "" set oldscripts = "" set user_sources = "" set matrixfiles = "" set badmatrix = "" set bad_frames = "" # # Output files set scriptname = mosflm.com set outmatrix = postref.mat set missets = "0 0 0" set mtzout = raw.mtz set mergefile = merged.mtz set logfile = logs/ set lastlog = "" set mergescript = merge.com set rename_dataset = "#" # set tempfile = Wedger_temp # # program location set MOSFLM = ipmosflm set MosflmVersion = "" set Interactive = "#PLOT" # # crystal/protein parameters set xtal = \`whoami\` set SG = unknown set SG_number = 0 set wrongSGs = "" set wrongLPGs = "" set CELL = unknown set res_choice = auto set SG_choice = auto set hires = "" set merge_res = "" set VRSET = "#" set detector_res_limit = "" set mtz_res = "" #set MolWt = 4000 set mosaic = auto # filesystem/collection parameters set framedir = /data/\`whoami\`/\${xtal} set frameprefix = "" set ext = "img" set template = "" set FirstImage = "" set phi0 = 0.0 set osc = 1 set first = 1 set last = "" set add = 0 set ident = "frame" set swap = "" # Alignment/centering parameters set wavelength = "1.5418" set distance = "100" set beam_center = "" set two_theta = 0 # # default Detector/beam parameters (Quantum-4) set Site = "" set SCANNER = "SITE SSRL" set SCANNER = "SCANNER omega 90 ROTATION horiz ANTI FAST horiz ORIGIN UR RECTANG ADSC" set LIMITS = "LIMITS RMAX 188 YMAX 188 XMAX 188 xscan 188 yscan 188" set LIMITS = "" set GAIN = 1 # generally dominated by Nave disorder: ~0.5% set DISPERSION = 0.005 # or just use SI-111 set DISPERSION = 0.00014 set DIVERGENCE = "0 0" set POLARISATION = "SYNCHROTRON 0.9" set OVERLOAD = default set PIXEL = 0.1 set Width = "" # # default SDcorr card for scala set DEFAULT_SDCORR set SDCORR = "1.3 0 0.03" # # automatic postrefine parameters set mosflm_postref_segs = "auto" set frames_per_segment = "auto" set ESTIMATING = "" set SAVE_hires = "" # # fancy mosflm options set integrate = no set postref = yes set strategize = yes #set usebeam = no set fixmosaicity = no set fixcell = no set fixyscale = no set true_cell = unk set reinput_missets = no # set check_frames = yes set number_of_frames = "" set autoindexing_frames = 4 set autoindexing_cutoff = 0.2 set wedge_width = 0 #################################################################################### # # # Collect information about this project # # #################################################################################### # # Remember explicit command-line arguments that are existing files foreach arg ( \$* ) if(-e "\$arg") then set temp = \`ls -lnd \$arg |& nawk '! /^d/ {print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l1000000{print \$NF}' |& nawk "\$IMAGE_pattern" | wc -l\` if(\$test != 0) continue # check for command-line args that LOOK like scripts, but don't exist as a file if(! -e "\$arg") then if("\$arg" =~ */*) then # could be a template set dir = \`dirname \$arg\` set prefix = \`basename \$arg\` ls -1L \$dir |& egrep "^\$prefix" >& /dev/null if(\$status) echo "WARNING: the file \$arg does not exist." endif if(("\$arg" =~ *.com)||("\$arg" =~ *.sh)||("\$arg" =~ *.csh)) echo "WARNING: the file \$arg does not exist." continue endif # see if arg is a directory (containing files containing mosflm keywords) set dir = \`ls -lnLd \$arg |& nawk '/^d/{print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l1000{exit} END{print n+0}'\` head -\$safehead \$file | egrep -li "\$SEARCH_CARDS" >& /dev/null if(! \$status) then set scriptfiles = ( \$scriptfiles \$file ) endif end set files = ( \$scriptfiles ) # make sure this list doesn't get too long (csh can't handle long lines) if((-e "\$files[\$#files]")&&(\$#oldscripts < \$MAXSCRIPTS)) then set oldscripts = \`echo \$oldscripts \$files |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null if(! \$status) then # this is an executable binary! Don't try to read keywords from it continue endif # filter command-line-provided files for cards set safehead = \`ood -cv \$arg | nawk '{for(i=2;i<=NF;++i) print \$i}' | nawk '/\\\\n/{++n;c=0} {++c} c>1000{exit} END{print n+0}'\` head -\$safehead \$arg | egrep -li "\$SEARCH_CARDS" >& /dev/null if(! \$status) then set oldscripts = \`echo \$oldscripts \$arg \` else set size = \`ls -lnLd "\$arg" |& nawk '{print \$5+0; exit}'\` if((\$safehead > 0)&&("\$size" < 1000000)) then echo "WARNING: \$arg does not contain mosflm commands. ... ignoring it." endif endif end set oldscripts = \`echo \$oldscripts |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 1Mb # 4) must be a regular file (or link) # # Precedence: # 1) complete image filenames on command line # 2) incomplete image filenames on command line ("templates") # 3) images found in directories given on command line # 4) images indicated in scripts listed on command line # 5) images inspired by scripts listed on command line # 6) images found in directories indicated in scripts on command line # 7) images found in directories indicated in scripts found in filesystem # 8) images found in filesystem # #################################################################################### # foreach arg ( \$inframes ) # squash -dash options if("\$arg" =~ -*) continue # squash frames we know are unwanted foreach baddie ( \$bad_frames ) if("\$arg" =~ "\$baddie"*) set arg = "" end if("\$arg" == "") continue # filter arguments for proper image extension and file name pattern set img = \`echo "\$arg" |& nawk "\$IMAGE_pattern" \` if("\$img" != "") then # explicit image name was given set framedir = \`dirname \$arg\` set ext = \`basename \$arg |& nawk 'BEGIN{FS="."} {print \$NF}'\` # see if the file exists, and is the right size set img = \`ls -lnLd \$img |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}'\` test -r "\$img" if(! \$status) then # valid first image found! set ext = \`basename \$arg |& nawk 'BEGIN{FS="."} {print \$NF}'\` set temp = \`basename \$arg \$ext\` set FirstImage = "\$arg" break endif endif # no need to continue if we have an image if(-e "\$FirstImage") break # see if \$arg is a frame template ... # chop off file extension (if there is one) set test_framedir = \`dirname \$arg\` set test_frameprefix = \`basename \$arg |& nawk 'BEGIN{FS="."} {printf \$1; for(i=2;i 800000 {print \$NF}' |& grep "\$test_frameprefix" |& nawk "\$IMAGE_pattern" |& head -1\` set img = \`ls -lnLd \${test_framedir}/\$img |& nawk '! /^d/ {print \$NF}' |& head -1\` set img = \`echo \$img |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` # squash frames we know are unwanted foreach baddie ( \$bad_frames ) if("\$img" =~ "\$baddie"*) set img = "" end test -r "\$img" if(! \$status) then # good frame has been found! set FirstImage = "\$img" break # echo "Extrapolated \$FirstImage from \$arg" endif endif # at this point, warn about things that look like image filenames, but aren't set test = \`basename "\$arg" | nawk "\$not_IMAGE_pattern" \` if("\$test" == "") then # this word looked like an x-ray image if(-e "\$arg") then echo "WARNING: the file \$arg does not look like an x-ray image file... ignoring it." else echo "WARNING: image file \$arg doesn't exist." endif endif # see if \$arg is a directory containing frames if(-e "\$arg") then set dir = \`ls -lnd \$arg |& nawk '/^d/ {print \$NF}'\` # look for frames in this directory set img = \`ls -lnL \$dir |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& nawk "\$IMAGE_pattern" |& head -1\` set img = \`ls -lnLd \${dir}/\$img |& nawk '! /^d/ {print \$NF}' |& head -1\` set img = \`echo \$img |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` # squash frames we know are unwanted foreach baddie ( \$bad_frames ) if("\$img" =~ "\$baddie"*) set img = "" end test -r "\$img" if(! \$status) then # good frame has been found! set FirstImage = "\$img" break else set img = "" endif endif end if(-e "\$FirstImage") goto FirstImageFound if(\$?searched_scripts) then # this variable set means we have alerady done "GetFramesFromScripts", so skip ahead goto FrameSearch endif # no good images found, reset search list #set inframes = "" GetFramesFromScripts: ############################################################################### # # Look for image info provided in older mosflm script(s) # ############################################################################### # examine meaningful files only set temp = \`echo \$oldscripts\` if("\$temp" != "") then set temp = \`egrep -li "^EXT|^DIRE|^IDEN|^IMAGE|^RAW" \$temp\` endif # collect a precedence-sorted list in \$inframes (evaluate it later) foreach oldscript ( \$temp ) # preprocess script for stable nawk-ing (no blank lines, no comments, # no shell variables or unexpected characters ) cat \$oldscript |\\ nawk '(NF > 0) && (\$1 !~ /^#/){for(i=1;i<=NF;++i){if(\$i !~ /[\\\$,]/) printf "%s", \$i " "}; print ""}' |\\ nawk '{for(i=1;i<=length;++i){c=substr(\$0,i,1); \\ if(c ~ /[ ,\\t,\\",\\!,\\047,\\140]/){ c = " " }; \\ if((c ~ /[ ,a-z,A-Z,0-9,.,_,=\\/#]/)||(c == "-")){printf c }else{break}}print ""}' |\\ cat >! \$tempfile # extract frame name and location information set temp = \`egrep -i "^EXT" \$tempfile |& nawk 'NF>1 {print \$2}'\` if(\$#temp >= 1) set ext = "\$temp[\$#temp]" set temp = \`egrep -i "^DIRE" \$tempfile |& nawk 'NF>1 {print \$2}'\` if(\$#temp >= 1) set framedir = "\$temp[\$#temp]" set temp = \`egrep -i "^IDEN" \$tempfile |& nawk 'NF>1 {print \$2}'\` if(\$#temp >= 1) set frameprefix = "\$temp[\$#temp]" set temp = \`egrep -i "^TEMPLATE" \$tempfile |& nawk 'NF>1 {print \$2}'\` if(\$#temp >= 1) set template = "\$temp[\$#temp]" set temp = \`egrep -i "^IMAGE" \$tempfile |& nawk 'NF>1 {print \$2}'\` if(\$#temp >= 1) set inframes = \`echo \$inframes \$temp[\$#temp] |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l3 {print \$4}'\` if(\$#temp >= 1) set inframes = \`echo \$inframes \$temp[\$#temp] |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null # add this suggestion of first frame to master list if(-e "\$framedir") then set temp = \`echo "\$first" | nawk '{printf "%03d", \$1}'\` set file = "\$framedir/\${frameprefix}_\${temp}.\$ext" # support TEMPLATE keyword too if("\$template" != "") then set file = "\$framedir/"\`echo "\$template \$first" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` endif set inframes = \`echo \$inframes \$file |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 800000 {print \$NF}' |& nawk "\$IMAGE_pattern" |& head -1\` set img = \`ls -lnLd \${dir}/\$img |& nawk '! /^d/ {print \$NF}' |& head -1\` set img = \`echo \$img |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` # squash frames we know are unwanted foreach baddie ( \$bad_frames ) if("\$img" =~ "\$baddie"*) set img = "" end # check if valid image was found here test -r "\$img" if((! \$status)&&(! -e "\$FirstImage")) then # good image found! set FirstImage = "\$img" endif end endif endif end if(-e "\$FirstImage") goto FirstImageFound if(\$?AUTO) goto End_of_FrameSearch echo -n "Looking for frames " onintr End_of_FrameSearch # 2nd pass: look in PARENT directory of listed arguments foreach arg ( \$* \$inframes ) if((! -e "\$FirstImage")&&("\$arg" !~ -*)&&(! \$?FASTsearch)) then # still not assigned, try searching same directory set dir = \`dirname \$arg\` set img = \`ls -lnL \$dir |& nawk '(/^\\-/ || /^l/) && \$5+0 > 800000 {print \$NF}' |& nawk "\$IMAGE_pattern" |& head -1\` set img = \`ls -lnLd \${dir}/\$img |& nawk '! /^d/ {print \$NF}' |& head -1\` set img = \`echo \$img |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` # squash frames we know are unwanted foreach baddie ( \$bad_frames ) if("\$img" =~ "\$baddie"*) set img = "" end test -r "\$img" if(! \$status) then # good image found set FirstImage = "\$img" else set img = "" endif endif end # More agressive search if still no frames found if((! -e "\$FirstImage")&&(! \$?FASTsearch)) then # frame list is no good set inframes = "" set img = "" # look around for a frame foreach root ( ./ /expdata/ /data/ /*/ ) if(-e "\$root") then foreach subdir ( "" \`whoami\` \`whoami\`/frames frames ../frames data ../data ) if((-e "\${root}/\${subdir}")&&(! -e "\$img")) then # look in this directory for frames set place = \`echo "\${root}/\${subdir}" |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` if((! -e "\$FirstImage")&&(-e "\$place")) then # look for first file that matches the pattern set img = \`ls -lnL \$place |& nawk '(/^\\-/ || /^l/) && \$5+0 > 800000 {print \$NF}' |& nawk "\$IMAGE_pattern" |& head -1\` set img = \`ls -lnLd \${place}/\$img |& nawk '! /^d/ {print \$NF}' |& head -1\` set img = \`echo \$img |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` # squash frames we know are unwanted foreach baddie ( \$bad_frames ) if("\$img" =~ "\$baddie"*) set img = "" end test -r "\$img" if((! \$status)&&(! -e "\$FirstImage")) then set FirstImage = "\$img" endif # for entertainment echo -n "." endif endif end endif end # Really aggressive search if(! -e "\$img") then echo -n " looking harder " foreach subdir ( \`whoami\`/frames \`whoami\` frames data "" ) foreach root ( ./ /expdata/ /data/ /*/ ) # look in these directories for frames if(("\$img" == "")&&(-e "\${root}\${subdir}")) then # for entertainment echo -n "." set place = \`echo "\${root}\${subdir}" |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` # look for first file that matches the pattern set img = \`find \$place -name '*[\\-_][0-9][0-9][0-9].*' -print |& nawk 'NF==1' |& nawk ' ! /^find:/' |& nawk "\$IMAGE_pattern" |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 800000 {print \$NF}' |& head -1\` set img = \`echo \$img |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\` # squash frames we know are unwanted foreach baddie ( \$bad_frames ) if("\$img" =~ "\$baddie"*) set img = "" end test -r "\$img" if((! \$status)&&(! -e "\$FirstImage")) then set FirstImage = "\$img" endif endif end end endif # final report if( -e "\$FirstImage") then echo "found \$FirstImage" else echo "didn't find any." endif endif End_of_FrameSearch: onintr echo "" if(! -e "\$FirstImage") then if(! \$?AUTO) then set temp = "I don't know" echo "Where are the frames you want to process? [\$temp] \$BELL" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) set inframes = "\$temp" if("\$inframes" == "I don't know") then echo "Well ... We don't know either." echo "Bye! " set mosflm_status = 100 set NORUN goto Cleanup endif set FASTsearch goto PickFirstImage else echo "Sorry, we can't find any x-ray image files." echo "Agressive image search will not be done in automatic mode." echo "" echo "please run: \$0 directory/name_001.\$ext" echo "where directory/name_001.\$ext is your first x-ray image." echo "Later! " set mosflm_status = 100 goto Cleanup endif endif FirstImageFound: # reaching here means we have found a usable frame! # design an image template (in case we need it) set framedir = \`dirname \$FirstImage\` set ext = \`echo \$FirstImage |& nawk 'BEGIN{FS="."} \$NF~/^[a-z]/{print "."\$NF}'\` set FirstImage = \`basename \$FirstImage\` set frameprefix = \`basename \$FirstImage \$ext\` # make a template for recognizing filenames like this set template = \`echo \${frameprefix} \$ext | nawk '{while(\$1~/[0-9]\$/){patt=patt "\\043"; \$1=substr(\$1,1,length(\$1)-1)}} {print \$1 patt \$2}'\` # see if these filenames are back-compatible to old versions of mosflm set compatible = \`echo "\$template" | nawk '/[_-]\\043\\043\\043[.]/{print "yes"}'\` # scan for the last possible file in the wedge ls -lnL \${framedir} |&\\ nawk -v first=\$FirstImage '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # constrain template based on available filenames ls -1 \$framedir |\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print}' |\\ nawk -v first=\$FirstImage -v last=\$LastImage '\\ \$1==first{p=1} p{print} \$1==last{p=0}' |\\ nawk '{if(length(\$0)>maxlen) maxlen=length(\$0);\\ for(col=1;col<=maxlen;++col){c=substr(\$0,col,1);\\ if(tpl[col]!=c){tpl[col]=tpl[col] c}}} \\ END{for(col=maxlen;col>=1;--col){\\ if(tpl[col] ~ /[^0-9]/ || endnum){tpl[col]=substr(tpl[col],1,1);\\ if(num+0!=0) endnum=1};\\ if(length(tpl[col])!=1){tpl[col]="\\043";++num};\\ template=tpl[col] template}\\ print template}' |\\ cat >! \${tempfile} set temp = \`nawk 'BEGIN{FS="\\043"} {print NF}' \${tempfile}\` if("\$temp" > 3) then set template = \`cat \${tempfile}\` endif rm -f \${tempfile} # now we have template in "prefix###.img format" # make an RE pattern for recognizing new images set noglob set framepattern = \`echo "\$template" | nawk '{gsub("[\\044\\050\\051\\052\\053\\054\\056\\077\\133\\134\\135\\136]","[&]",\$0); gsub("\\043","[0-9]",\$0); print "^" \$0 "\$"}'\` unset noglob set first = \`echo "\$FirstImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` set FirstImage = \`echo "\$framedir/\$template \$first" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` set LastImage = \`echo "\$framedir/\$template \$last" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` # check for backward-compatibility if("\$compatible" != "") then # template has the form prefix[-_]###.ext # so, safe to use "old" image file breakdown set ext = \`echo \$FirstImage |& nawk 'BEGIN{FS="."} {print \$NF}'\` set frameprefix = \`basename \$FirstImage .\$ext | nawk '{print substr(\$1, 1, length(\$1)-4)}'\` set TEMPLATE = "" else # we will have to use the mosflm v5.4+ TEMPLATE keyword set TEMPLATE = "TEMPLATE \$template" set frameprefix = \`echo "\$template" | nawk 'BEGIN{FS="\\043"} {print \$1}'\` endif # remember rest of suggestion list (in case we come back) set inframes = \`echo \$inframes |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 300 && \$5+0 < 400 {print dir "/" \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l0 || NR==1)' |& head -1\` set matrixfiles = "\$matrixfiles \$mat" endif end endif endif end # now collect a list of potential matricies from script files found foreach file ( \$oldscripts ) if(-e "\$file") then # get matrix file name from script set temp = \`egrep "^MATR" \$file |& nawk '{print \$2}' |& tail -1\` if(\$#temp == 1) then if(-e "\$temp") set matrixfiles = "\$matrixfiles \$temp" endif # extract mosflm matrix from denzo files # (check determinant first) head -5 \$file |& nawk 'NR>1 && NF == 6{printf "%12.8f%12.8f%12.8f\\n", \$4, \$5, \$6}' |& \\ nawk 'NR < 4{i=NR; for(j=1;j<4;++j){mat[i,j]=\$j+0}} \\ END{det += mat[1,1]*((mat[2,2]*mat[3,3])-(mat[2,3]*mat[3,2])) \\ det -= mat[1,2]*((mat[2,1]*mat[3,3])-(mat[2,3]*mat[3,1])) \\ det += mat[1,3]*((mat[2,1]*mat[3,2])-(mat[2,2]*mat[3,1])) \\ printf "%.4f", det}' >&! \${tempfile}.determinant set temp = \`cat \${tempfile}.determinant\` rm -f \${tempfile}.determinant >& /dev/null # if determinant is unitary, then we almost certainly have an orientation matrix if( "\$temp" == "1.0000" ) then # store the .x file name in precedence list set set matrixfiles = "\$matrixfiles \$file" endif endif end # more agressive command-line search foreach arg ( \$* ) # see if arg contained a directory set dir = \`dirname \$arg |& nawk '\$0 != "."'\` # use directory name of the arg if((-e "\$dir")&&(! \$?NEW)) then # we have a directory to search! set temp = \`ls -lnLtp \$dir |& egrep '\\.mat\$' |& nawk -v dir=\$dir '/^\\-/ && \$5+0 > 300 && \$5+0 < 400 {print dir "/" \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l0 || NR==1)' |& head -1\` set matrixfiles = "\$matrixfiles \$mat" endif end endif end # add default to the list (if appropriate) if((-e "\$best_matrix")&&(! \$?NEW)) set matrixfiles = "\$matrixfiles \$best_matrix" CheckMATRIX: # now check the precedence-sorted list for REAL matricies foreach mat ( \$matrixfiles ) if(( -e "\$mat")&&(! -e "\$inmatrix")&&("\$mat" !~ *.mat)) then # must have been a script file set file = "\$mat" # redefine new matrix file name set temp = \`basename \$file .x\` set mat = "\${temp}.mat" if(-e "\$mat") mv \$mat \${mat}.old # extract the unitary matrix # head -5 \$file |& nawk 'NR>1 && NF == 6{printf "%12.8f%12.8f%12.8f\\n", \$4, \$5, \$6}' >! \${temp}.umat # convert denzo to york (if need be) cp \$file \${tempfile}.x grep HEADER \$file >& /dev/null if(\$status) then echo "HEADER 1" >! \${tempfile}.x head -10 \$file >> \${tempfile}.x endif # use combat logfile output to get mosflm matrix echo "" | nawk '{print "INPUT DENZO"; print "SYMM 1"; print "RESO 9"; print "END"}' |\\ combat HKLIN \${tempfile}.x HKLOUT /dev/null |&\\ nawk '/Mosflm umat matrix/{getline; getline; getline; getline;\\ getline; printf "%12.8f%12.8f%12.8f\\n", \$1, \$2, \$3; \\ getline; printf "%12.8f%12.8f%12.8f\\n", \$1, \$2, \$3; \\ getline; printf "%12.8f%12.8f%12.8f\\n", \$1, \$2, \$3}'|\\ cat >&! \${tempfile}.umat rm -f \${tempfile}.x >& /dev/null # quick check for validity set temp = \`cat \${tempfile}.umat | nawk '\$1+\$2+\$3 != 0' | wc -l\` if("\$temp" != 3) then echo "bad matrix in \$file" else # using the U matrix here doesn't seem to hurt preds cat \${tempfile}.umat >! \$mat # missetting angles are zero nawk 'BEGIN{printf "%12.3f%12.3f%12.3f\\n", 0, 0, 0}' >> \$mat # U matrix goes here cat \${tempfile}.umat >> \$mat # put the cell here... nawk 'toupper(\$0) ~ /CELL/{for(i=1;i<=NF;++i){if(\$i ~ /[0-9]/)\\ printf "%12.4f",\$i}} END{print ""}' \$file >> \$mat # missetting angles are zero nawk 'BEGIN{printf "%12.4f%12.4f%12.4f\\n", 0, 0, 0}' >> \$mat # inform user we created a new file echo "extracted \$mat from \$file " endif rm -f \${tempfile}.umat >& /dev/null # now go on and check this new matrix in the usual way ... endif if(( -e "\$mat")&&(! -e "\$inmatrix")) then # compute determinant of U matrix (mosflm is sensitive to this) cat "\$mat" |\\ nawk 'NR==5,NR==7{i=NR-4; for(j=1;j<4;++j){mat[i,j]=\$j+0}} \\ END{det += mat[1,1]*((mat[2,2]*mat[3,3])-(mat[2,3]*mat[3,2])) \\ det -= mat[1,2]*((mat[2,1]*mat[3,3])-(mat[2,3]*mat[3,1])) \\ det += mat[1,3]*((mat[2,1]*mat[3,2])-(mat[2,2]*mat[3,1])) \\ printf "%.4f", det}' >&! \$tempfile set det = \`cat \$tempfile\` rm -f \$tempfile >& /dev/null # make sure matrix has a unit cell set cell = \`nawk 'NF==6' \$mat\` if((\$#cell == 6)&&("\$det" == "1.0000")) then set inmatrix = "\$mat" else echo "WARNING: \$mat is not a valid matrix ... ignoring it." set badmatrix = \`echo \$badmatrix \$mat\` set inmatrix = "" endif endif end if(-e "\$inmatrix") then # stop screwing around, and skip ahead goto MatrixFound else # no luck with these set badmatrix = \`echo \$badmatrix \$matrixfiles\` set matrixfiles = "" endif if((\$?NEW)||(! \$?SEARCH_HARD)) goto Initialize # if we still don't have a "good" matrix, look around for one echo -n "Looking for an orientation matrix " if(! \$?AUTO) then echo -n "(Ctrl-C to skip) " onintr SkipMatrixSearch endif # look down a list of standard places for matricies set places = \`ls -1dt ../*/ ../../*/*/ \` foreach place ( ./ ../ ../../ \$places ) if((-e \$place)&&(! -e "\$inmatrix")) then # first, look for matrix files of predefined name set temp = \`ls -1t \${place}\$best_matrix |& nawk 'NF==1'\` # and then look for just any matrix file set temp = "\$temp "\`ls -1t \${place} |& nawk -v dir=\$place 'NF==1 && /.mat\$/ {print dir \$0}' |& grep -v \$best_matrix |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l&! \$tempfile set det = \`cat \$tempfile\` rm -f \$tempfile >& /dev/null # make sure matrix has a unit cell set cell = \`nawk 'NF==6' \$mat\` if((\$#cell == 6)&&("\$det" == "1.0000")) then set inmatrix = "\$mat" else set badmatrix = \`echo \$badmatrix \$mat\` endif endif end # keep user entertained echo -n "." endif end SkipMatrixSearch: onintr if(-e "\$inmatrix") then echo " found \$inmatrix" else echo " none found." set inmatrix = "\$best_matrix" endif MatrixFound: ################################################################################################################ # # First pass through filesystem complete. # # All data files should now be located, and we need to use # them to initialize program variables. # ################################################################################################################ Initialize: ########################################################################### # # # # ##### # ## # # ###### ###### # ## # # # # # # # # # # # # # # # # # # # # # # ##### # # # # # # # ###### # # # # # # ## # # # # # # # # # # # # # # # # # ###### # ###### ###### ########################################################################### # # Initialize variable values from old scripts. logs, frames, and the matrix, # in order of precedence/age # ########################################################################### # # # check oldscripts, just to be sure all files exist set oldscripts = \`echo \$oldscripts\` #if(("\$oldscripts" != "")&&(! \$?NEW)) then if("\$oldscripts" != "") then set temp = "" foreach file ( \$oldscripts ) head -1 \$file >> /dev/null if(! \$status) set temp = "\$temp \$file" # if(-e \$file) set temp = "\$temp \$file" end set oldscripts = \`echo "\$temp"\` # pick a representative oldscript from the bunch set oldscript = \`ls -1t \$oldscripts |& head -1\` else set oldscript = "" endif set sources = "" #check that all source files exist, and are readable foreach file ( \$FirstImage \$inmatrix \$oldscript \$lastlog ) head -1 \$file >& /dev/null if(! \$status) set sources = "\$sources \$file" end # sort source files by date set sources = \`echo \$sources\` if("\$sources" != "") then set sources = \`ls -1dt \$sources\` endif # now replace representative oldscript with entire list of oldscripts set temp = "" foreach file ( \$sources ) if("\$file" == "\$oldscript") then set temp = "\$temp \$oldscripts" else set temp = "\$temp \$file" endif end set sources = "\$temp" # if -new was specified, ignore the old scripts (above) #if(\$?NEW) then # set sources = "\$user_sources \$FirstImage \$inmatrix" #endif # now move command-line args to the "top" of the list echo "\$sources" | nawk 'BEGIN{RS=" "} {print}' >! \${tempfile}.sources echo "" >! \${tempfile}.args echo "" >! \${tempfile} foreach arg ( \$* ) egrep "^\$arg" \${tempfile}.sources >> \${tempfile}.args egrep -v "^\$arg" \${tempfile}.sources >> \${tempfile} mv \${tempfile} \${tempfile}.sources end set sources = \`cat \${tempfile}.args \${tempfile}.sources\` rm -f \${tempfile}.args \${tempfile}.sources >& /dev/null echo "" goto GetParamsFromSources # See end of this file for source code ReturnGetParamsFromSources: echo "" CommandLine: ############################################################################### # # Take other (refinement) options given on command line (highest precedence) # ############################################################################### # look for valid unit cell on command line set i = 1 set j = 1 set newCELL = "" while ( \$i <= \$#argv ) # look for any words containing "cell" if("\$argv[\$i]" =~ *[Cc][Ee][Ll][Ll]*) then # see if there is a valid cell after this word set k = 1 while(( \$k <= 6 )&&( \$j <= \$#argv)) @ j = ( \$i + \$k ) # safety catch if(\$j > \$#argv) break # check for number > 10 set temp = \`echo "\$argv[\$j]" | nawk '\$1+0 > 10{print \$1+0}'\` if("\$temp" == "") then # all bets are off set newCELL = "" set k = 10 else # add this parameter to the cell set newCELL = "\$newCELL \$temp" endif # increment offset from "cell" word @ k = ( \$k + 1 ) end # see if we got all six set newCELL = \`echo \$newCELL\` if(\$#newCELL == 6) then # this cell was valid set CELL = \`echo \$newCELL\` # erase the arguments (as not to confuse them with frame counts) set k = 1 while(( \$k <= 6 )&&( \$j <= \$#argv)) @ j = ( \$i + \$k ) set argv[\$j] = "" @ k = ( \$k + 1 ) end endif endif @ i = ( \$i + 1 ) end # now look for other (less complex) options 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 set arg = "\$argv[\$i]" set ARG = \`echo "\$arg" | nawk '{print toupper(\$1)}'\` if("\$ARG" =~ [PCIFHR][1-6]*) then set SG = "\$ARG" set SG_choice = user endif # if("\$arg" == "usebeam") set usebeam = yes # if("\$arg" == "nousebeam") set usebeam = no if("\$arg" =~ fixmo*) set fixmosaicity = yes if("\$arg" =~ nofixmo*) set fixmosaicity = no if("\$arg" =~ fixc*) set fixcell = yes if("\$arg" =~ nofixc*) set fixcell = no if("\$arg" =~ fixc*) set true_cell = yes if("\$arg" =~ nofixc*) set true_cell = no if("\$arg" =~ fixy*) set fixyscale = yes if("\$arg" =~ nofixy*) set fixyscale = no if("\$arg" =~ fixx*) set fixyscale = yes if("\$arg" =~ nofixx*) set fixyscale = no if("\$arg" =~ postre*) set postref = yes if("\$arg" =~ nopostre*) set postref = no if("\$arg" =~ refi*) set postref = yes if("\$arg" =~ norefi*) set postref = no if("\$arg" =~ integ*) set integrate = yes if("\$arg" =~ nointeg*) set integrate = no if("\$arg" =~ nostrat*) set strategize = no if("\$arg" =~ nomerge*) set NOSCALE if("\$arg" =~ nosear*) set NEW # if("\$arg" == "-usebeam") set usebeam = yes # if("\$arg" == "-nousebeam") set usebeam = no if("\$arg" =~ "-"fixmo*) set fixmosaicity = yes if("\$arg" =~ "-"nofixmo*) set fixmosaicity = no if("\$arg" =~ "-"fixc*) set fixcell = yes if("\$arg" =~ "-"nofixc*) set fixcell = no if("\$arg" =~ "-"fixc*) set true_cell = yes if("\$arg" =~ "-"nofixc*) set true_cell = no if("\$arg" =~ "-"fixy*) set fixyscale = yes if("\$arg" =~ "-"nofixy*) set fixyscale = no if("\$arg" =~ "-"fixx*) set fixyscale = yes if("\$arg" =~ "-"nofixx*) set fixyscale = no if("\$arg" =~ "-"postre*) set postref = yes if("\$arg" =~ "-"nopostre*) set postref = no if("\$arg" =~ "-"refi*) set postref = yes if("\$arg" =~ "-"norefi*) set postref = no if("\$arg" =~ "-"integ*) set integrate = yes if("\$arg" =~ "-"nointeg*) set integrate = no if("\$arg" =~ "-"nostrat*) set strategize = no if("\$arg" =~ "-"nomerge*) set NOSCALE if("\$arg" =~ "-"nosear*) set NEW if("\$arg" == "-nice") then renice 40 \$\$ >& /dev/null if(\$status) renice -n 40 \$\$ >& /dev/null continue endif if(("\$arg" == "-add")&&( \$i < \$#argv )) then set add = \$argv[\$nexti] @ i = (\$i + 1) continue endif # look for "no" preceding an option (opposite meaning) if(\$?NO) then # if("\$arg" == "usebeam") set usebeam = no if("\$arg" =~ fixmo*) set fixmosaicity = no if("\$arg" =~ fixc*) set fixcell = no if("\$arg" =~ fixc*) set true_cell = no if("\$arg" =~ fixy*) set fixyscale = no if("\$arg" =~ fixx*) set fixyscale = no if("\$arg" =~ postre*) set postref = no if("\$arg" =~ integ*) set integrate = no if("\$arg" =~ strat*) set strategize = no if("\$arg" =~ sear*) set NEW unset NO continue 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 hires = \`echo "\$temp[2]" | nawk '{print \$1+0}'\` set lores = \`echo "\$temp[1]" | nawk '{print \$1+0}'\` set res_choice = user continue endif else # single 1.8A is just high resolution set hires = \`echo "\$arg" | nawk '{print \$1+0}'\` set res_choice = user continue endif endif if(("\$arg" =~ [1-9][0-9]*aa)&&("\$arg" !~ *[b-z,A-Z]*)) then # this is probably a number of amino acids set Chain = \`echo \$arg | nawk '{print \$1+0}'\` endif # interpret free integers as number of frames? set int = \`echo "\$arg" | nawk '{printf "%d", \$1+0}'\` if(("\$arg" == "\$int")&&(("\$argv[\$nexti]" == "frame")||("\$argv[\$nexti]" == "frames"))) then set number_of_frames = "\$arg" set USER_WEDGE_SIZE = "\$arg" endif endif unset NO if("\$ARG" == NO) set NO if("\$ARG" == NOT) set NO end # if this is, indeed the first time through, we probably just # want to postrefine if(\$?NEW) set postref = yes # don't integrate in the first round of burstmode, or it will be the last! if((\$?BURSTMODE)&&(! \$?LAST_RUN)&&(! \$?Convergeing)) set integrate = no # process command-line through the Questionaire #set input = "\$*" #if("\$input" != "") goto Questionaire # Questionaire should return to ProcessInput ProcessInput: ############################################################################### #### # # ###### #### # # ## # # # # # # # # # # # # # # # # ###### ##### # #### # # # # # # # # # # # ###### # # # # # # # # # # # # # # # #### # # ###### #### # # # # ###### ###### ############################################################################### # # At this point, all variable values have been read in. # # Input Numbers are not, necesarrily valid or in the right form. Check each # one, and convert it to something useful to Wedger Elves. # ############################################################################### # if you're not integrating, you're postrefining if(\$?NEW) set integrate = no if(\$integrate == no) set postref = yes # see if we don't want postrefinement during integration set test = \`echo "\$PREAMBLE" | nawk 'BEGIN{RS="n"} {print}' | grep "POSTREF OFF"\` if("\$test" != "" && \$integrate == yes) then set postref = no endif # output script should be in local directory set scriptname = \`basename \$scriptname\` # oblige user-specified number of frames (check it later) if(\$number_of_frames != "") @ last = (\$first + \$number_of_frames - 1 ) # decide on a unique "add" value to differentiate this wedge from others if(\$add == "auto") then # reduce starting phi to range [0, 360] set temp = \`echo \$phi0 | nawk '{print (\$1 + 360*int(1+ sqrt(\$1*\$1)/360)) % 360}' | nawk '{print int(\$1)}'\` # assume phi values > 180 are inverse beam wedges if(\$temp >= 180) then # see if we can fit two wedges in three digits if((2 * (\$last + 1)) / 1000) then set add = 1000 else # can squeeze two I.B. wedges in same 3-digit space set add = 500 endif else # not inverse beam, so no offset set add = 0 endif # now add 1000 * ( run number - 1) # filter last whole number out of filename prefix set temp = \`echo \$frameprefix | nawk '{for(i=1;i<=length(\$1);++i){c=substr(\$1,i,1); if(c ~ /[0-9]/){printf c}else{printf " "}}}'\` set temp = \$temp[\$#temp] # if run number is given, use it as a guide if(\$temp != "") then # remove all but last digit (because batch numbers > 9999 interfere with scala) @ temp = ( \$temp % 10 ) # add "additional" offset to batch numbers @ add = ( \$add + ((\$temp - 1) * 1000)) endif endif # # convert beam center from foreign formats if(\$#beam_center != 2) then # beam center should ALWAYS be there! but just in case set beam_center = "97.2 97.2" echo "WARNING: Beam center is probably completely wrong." echo " Lets hope MOSFLM has better luck..." set UNRELIABLE_BEAM # mosflm X is ( frame width) - (ADXV's Y) # set beam_center = \`echo "188 - \$temp[2]" | bc\` # mosflm Y is ADXV's X # set beam_center = \`echo \$beam_center \$temp[1]\` endif # ############################################################################### # make sure CCP4, etc. is set up # ############################################################################### if((! \$?CLIBD)||(! \$?CCP4_SCR)||(! \$?CINCL)) then onintr Skip_CCP4_search echo -n "Trying to set up CCP4 ." set ccp4setup = "" foreach place ( /programs/xtal/ccp4_3.4/ /usr/xtal/CCP4_v3.4/ /programs/xtal /sw/ /programs/ /usr/xtal /usr/local /usr/ ) if((! -e "\$ccp4setup")&&(-e \$place)) then echo -n "." # look for setup scripts here set ccp4setup = \`find \${place} -name ccp4.setup -print |& nawk '/ccp4.setup\$/{print \$NF}' | tail -1\` endif if((-e "\$ccp4setup")&&((! \$?CLIBD)||(! \$?CCP4_SCR)||(! \$?CINCL))) then source \$ccp4setup setenv CCP4_SCR . setenv BINSORT_SCR . setenv CCP4_OPEN UNKNOWN echo "using \$ccp4setup" endif end endif Skip_CCP4_search: onintr if (! \$?BINSORT_SCR && \$?CCP4_SCR) setenv BINSORT_SCR \$CCP4_SCR echo "" if((! \$?CLIBD)||(! \$?CCP4_SCR)||(! \$?CINCL)) then set NO_CCP4 cat << EOF failed. Wedger Elves (and mosflm) need CCP4 to run properly. Please ask your sysadmin how to set up CCP4, or go to netscape ftp://ccp4a.dl.ac.uk/pub/ccp4/ to get yourself a copy. Unfortunately, you'll have to compile it. If, however, you have Red Hat linux, you can get an RPM from the O people at: netscape http://origo.imsb.au.dk/~mok/linux/dist/ In the meantime, Wedger Elves can limp along without CCP4, but they won't be able to scale and merge your data. EOF set NOSCALE # do half-assed setup setenv CCP4_SCR . setenv BINSORT_SCR . setenv CLIBD . setenv CINCL . # make some band-aid files goto DumpSymopLib # create \${CLIBD}/symop.lib # create \${CINCL}/environ.def # create \${CINCL}/default.def ReturnFrom_DumpSymopLib: endif setenv CCP4_OPEN UNKNOWN # chech that we can actually write to scratch directories touch \${CCP4_SCR}/.this\$\$ >& /dev/null if(\$status) then echo "WARNING: "'\$'"CCP4_SCR=\$CCP4_SCR is not accessible. using cwd instead." setenv CCP4_SCR . endif rm -f \${CCP4_SCR}/.this\$\$ >& /dev/null touch \${BINSORT_SCR}/.this\$\$ >& /dev/null if(\$status) then echo "WARNING: "'\$'"BINSORT_SCR=\$BINSORT_SCR is not accessible. using cwd instead." setenv BINSORT_SCR . endif rm -f \${BINSORT_SCR}/.this\$\$ >& /dev/null # check free disk space set freespace = \`df -k \$CCP4_SCR |& nawk 'NR>=2&&NF>2{avl=NF-2;print \$avl/1024}'\` set test = \`echo \$freespace 100 | nawk '{print (\$1<\$2)}'\` if(\$test) echo "WARNING: "'\$'"CCP4_SCR is getting full! \${freespace}MB left. " set freespace = \`df -k \$BINSORT_SCR |& nawk 'NR>=2&&NF>2{avl=NF-2;print \$avl/1024}'\` set test = \`echo \$freespace 100 | nawk '{print (\$1<\$2)}'\` if(\$test) echo "WARNING: "'\$'"BINSORT_SCR is getting full! \${freespace}MB left." set freespace = \`df -k . |& nawk 'NR>=2&&NF>2{avl=NF-2;print \$avl/1024}'\` set test = \`echo \$freespace 100 | nawk '{print (\$1<\$2)}'\` if(\$test) echo "WARNING: disk space is getting low! \${freespace}MB left. " ############################################################################### # now look for ipmosflm executable # ############################################################################### #if((! -e "\$MOSFLM")&&(! \$?NORUN)) then #if(! \$?NORUN) then #if(! -e "\$MOSFLM") then if("\$MosflmVersion" == "") then # set minor variable to see if executable comes back different set mosflm = \$MOSFLM goto FindMOSFLM endif ReturnFindMOSFLM: # a working executable should be in \$mosflm, or a blank if("\$MosflmVersion" =~ [1-9]*) then if((-e "\$mosflm")&&("\$mosflm" != "\$MOSFLM")) then echo "found \$mosflm" set MOSFLM = \$mosflm endif else # no mosflm found set NOMOSFLM set NORUN endif # # ############################################################################### # Check preamble cards # ############################################################################### # can't really check cards if there is no mosflm to chech them with if((! \$?NOMOSFLM)&&("\$PREAMBLE" != "")) then set safety = 0 echo "\$PREAMBLE" | nawk 'BEGIN{RS="n"} {print}' >! \${tempfile}.preamble CheckPREAMBLE: # safety catch, in case bad cards can't be removed @ safety = ( \$safety + 1 ) if(\$safety == 20) goto BAD_PREAMBLE # run mosflm with these cards cat \${tempfile}.preamble | \$MOSFLM SUMMARY /dev/null |& head -300 >&! \$tempfile tail -2 \$tempfile |& grep "END OF PROCESSING" >& /dev/null if(\$status) then # mosflm choked on a card set bad_card = \`tail -2 \$tempfile | nawk '/ ===> /{print substr(\$0,7)}'\` # remove this card from the preamble nawk -v bad="\$bad_card" 'bad != \$0' \${tempfile}.preamble >! \$tempfile # catch failure to remove a card set temp = \`diff \$tempfile \${tempfile}.preamble | wc -l\` if("\$temp" == 0) goto BAD_PREAMBLE # check again mv \${tempfile} \${tempfile}.preamble goto CheckPREAMBLE else rm -f \${tempfile} >& /dev/null goto GOOD_PREAMBLE endif BAD_PREAMBLE: # just comment everything out echo "WARNING: one or more of these keywords is making Mosflm unhappy:" cat \${tempfile}.preamble echo "They will all be commented out in \$scriptname \$BELL " nawk 'BEGIN{RS="n"} {print "#", \$0}' \${tempfile}.preamble >! \${tempfile} mv \${tempfile} \${tempfile}.preamble GOOD_PREAMBLE: # reimport preamble file into a variable (check it later) set PREAMBLE = \`nawk 'BEGIN{ORS="n"} NF != 0' \${tempfile}.preamble\` rm -f \${tempfile}.preamble endif ############################################################################### # forgot to update matrix file? # ############################################################################### #if((-e "\$outmatrix")&&(\$?AUTO || \$?Convergeing)&&(\$last_changed != failure)) then if((-e "\$outmatrix")&&(! \$?NEW)&&("\$inmatrix" != "")&&("\$last_changed" != "failure")) then # maybe forgot to do this earlier? set temp = "Yes" echo "\$outmatrix found. Move it to \${best_matrix}? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then # go ahead and update matrix mv \$best_matrix \${best_matrix}.old >& /dev/null mv \$outmatrix \$best_matrix set inmatrix = \$best_matrix endif if(-e "\$outmatrix") then # didn't move new matrix, get rid of it? set temp = "Yes" echo "remove \${outmatrix}? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then # don't ask next time rm -f \$outmatrix endif endif endif # have new frames appeared? #if((\$?Convergeing)&&(! \$?NO_EXTEND)) then if((! \$?NO_EXTEND)&&(-e "\$scriptname")) then # look for frames consecutive to the "last" frame of this run set offset = \`echo "\$template" | nawk '{print index(\$1,"\\043")}'\` ls -1Lrt \$framedir | egrep "^\${framepattern}" |\\ nawk -v last=\$last -v offset=\$offset '{num=substr(\$1,offset)+0} \\ num==last+1{++last; printf "%d %s\\n", last, \$1;}' |\\ tail -1 >! \${tempfile} set newframe = \`nawk '{print \$NF}' \${tempfile}\` set newlast = \`nawk '{print \$1}' \${tempfile}\` rm -f \${tempfile} if("\$newframe" != "" && \$?USER_WEDGE_SIZE) then @ test = (( \$newlast - \$first ) + 1 ) if(\$test < \$USER_WEDGE_SIZE) then # this is within the number of frames the user originally specified echo "extending wedge to \${framedir}/\$newframe" set last = \$newlast @ number_of_frames = (( \$last - \$first ) + 1 ) unset LAST_RUN unset SMOOTH_RUNS set mosflm_postref_segs = "auto" set frames_per_segment = "auto" # don't bother with asking set newframe = "" endif endif # see if there was a "new" frame if("\$newframe" != "") then # see if it is newer than the script we just ran set temp = \`ls -1Lrt \$scriptname \${framedir}/\$newframe | tail -1\` if("\$temp" != "\$scriptname") then # a new frame has appeared (potentially in this wedge) echo "\${framedir}/\$newframe has appeared." set temp = "Yes" #if(\$?USER_WEDGE_SIZE) set temp = "No" echo "Shall we extend the wedge to \${newframe}? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$temp" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then # update the wedge size set last = \$newlast @ number_of_frames = (( \$last - \$first ) + 1 ) unset LAST_RUN unset SMOOTH_RUNS set mosflm_postref_segs = "auto" set frames_per_segment = "auto" else # don't ask about this again set NO_EXTEND endif endif endif endif # speed things up a bit? if((\$?Convergeing)||("\$check_frames" == "no")) goto CheckSegments CheckWedge: ############################################################################### # check that all the frames are there, and have consecutive phis # if not, remove them from the processing list # ############################################################################### set number = \$last set savelast = \$last # This can take a while, tell user what we are doing echo -n "Checking frames " # Ctrl-C breaks out of frame check if(! \$?AUTO) then onintr SkipCheckWedge echo -n "(Ctrl-C to skip) " endif # check for existence of files while(\$number >= \$first) # generate the expected filename set img = \`echo "\$framedir/\$template \$number" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` # check that it is readable test -r \$img >& /dev/null if(\$status) then echo "" @ last = (\$number - 1) endif # check if it even exists if(! -e "\$img" ) then echo "" echo "WARNING: \$img does not exist" @ last = (\$number - 1) endif @ number = (\$number - 1) end #check phi, distance, etc. on images we can read set number = \$first set next_phi = \$phi0 set step = \$osc while(\$number <= \$last) # for entertainment purposes only echo -n "." # generate the expected filename set img = \`echo "\$framedir/\$template \$number" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` set phi = "" if("\$SCANNER" =~ *ADSC* || "\$SCANNER" =~ *SBC*) then set phi = \`nawk 'BEGIN{RS="\\f"} {print;exit}' \$img | egrep "OSC_START|PHI|ROTATION_START" | nawk -F "=" '{ print \$2+0}' | head -1\` endif if ("\$Site" =~ *PILATUS*) then set phi = \`nawk 'BEGIN{RS="\\f"} {print;exit}' \$img | egrep -i "Start_angle" | nawk '\$4~/^deg/{print \$3+0; exit}'\` endif if(\$?RAXIS_SMV) then set phi = \`nawk 'BEGIN{RS="\\f"} {print;exit}' \$img | egrep "^ROTATION=" | nawk -F "=" '{print \$2+0; exit}'\` endif if(("\$SCANNER" =~ *RAXIS*)&&("\$swap" != "")&&(! \$?RAXIS_SMV)) then # get phi value from header od -vb -j 524 -N 4 \$img |\\ nawk '{for(i=2;i<=5;++i){printf "%d ", 64*substr(\$i,1,1)+8*substr(\$i,2,1)+substr(\$i,3,1)};exit}' |\\ nawk '{w=x=\$2} \$1+\$2+\$3+\$4==0{--w;++x} {print \$0, w,x-1}' |\\ nawk '{printf "%c%c%c%c", '\$swap'}' | ood -f |\\ nawk '{print \$2+0;exit}' |\\ cat >! \${tempfile}phi set temp = \`nawk '\$1>-370 && \$1<800 {print \$1;exit}' \${tempfile}phi\` rm -f \${tempfile}phi >& /dev/null if("\$temp" != "") set phi = \$temp endif if("\$ext" =~ mar*) then set phi = \`head -56 \$img | nawk '/^PHI/{print}' | nawk 'BEGIN{RS=" "} /START/{getline; print \$0+0}'\` endif # check MARCCD header? if("\$SCANNER" =~ *MARCCD*) then od -bv -j 1024 -N 1024 \$img |\\ nawk '{for(i=2;i<=NF;++i){print 64*substr(\$i,1,1)+8*substr(\$i,2,1)+substr(\$i,3,1)}}' |\\ nawk 'NR%4==1{printf "\\n%d ", NR+1023} {printf "%d ", \$1}' |\\ nawk '/^1052 210 4 0 0/{little=1} /^1052 0 0 20 341/{big=1} \\ little{print \$1, (\$2+256*(\$3+256*(\$4+256*\$5)))-(2^32)*(\$5>=128)} \\ big{print \$1, (\$5+256*(\$4+256*(\$3+256*\$2)))-(2^32)*(\$2>=128)}' |\\ nawk '/^1708 / || /^1696 /{ print \$2/1000}' |\\ cat >! \${tempfile}phi set temp = \`nawk '\$1>-370 && \$1<800 {print \$1}' \${tempfile}phi\` rm -f \${tempfile}phi >& /dev/null if("\$temp" != "") set phi = \`echo \$temp | awk '{print \$NF}'\` if("\$temp" != "") set omega = \`echo \$temp | awk '{print \$1}'\` endif # defeat check if headers are just unreadable if("\$phi" == "") then set phi = \$phi0 set step = 0 endif # reset "phi0" value to that of first image (bug workaround) if(("\$img" == "\$FirstImage")&&("\$phi" != "\$phi0")) then echo "WARNING: resetting phi0 to \$phi (from first frame)" set phi0 = \$phi set next_phi = \$phi endif set temp = \`echo "\$phi \$next_phi" | nawk '{printf "%.2f", (((\$1 - \$2)*1000 + 36180000) % 360000)/1000}'\` if("\$temp" != "180.00" && \$?omega) then set phi = \$omega set temp = \`echo "\$phi \$next_phi" | nawk '{printf "%.2f", (((\$1 - \$2)*1000 + 36180000) % 360000)/1000}'\` endif if("\$temp" != "180.00") then echo "" echo "WARNING: \$img phi value: \$phi is out of sequence." @ last = (\$number - 1) echo " \$next_phi expected." # echo " will only process to frame \$last" endif set next_phi = \`echo "\$phi \$step" | nawk '{print \$1+\$2}'\` @ number = (\$number + 1) end echo "" # reset Ctrl-C catch to normal onintr @ temp = ((\$last - \$first) + 1 ) if((\$last < \$savelast)&&(\$temp > 1)) then echo "Only \$temp frames are available." endif #if((\$temp <= 1)&&(! \$?NORUN)&&(! \$?autoindexing)) then if(0) then echo "There are not enough frames for a processing run \$BELL" echo " (mosflm cannot postrefine just one frame) ... " # turn POSTREF off? set postref = "no" # maybe just want to index? set temp = "Yes" if(\$?AUTO) set temp = "No" echo "Do you just want to index \${FirstImage}? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp # Wedger has no business looking for more frames now echo "Agressive image searching will not be done in automatic mode." echo "" echo "please run: \$0 directory/name_001.\$ext" echo "where directory/name_001.\$ext is the first x-ray image" echo "in a multi-image wedge." echo "Later! " set mosflm_status = 100 goto Cleanup else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then # skip ahead to indexing set autoindexing set NORUN goto autoindex endif # user says this frame is useless set bad_frames = "\$bad_frames \${FirstImage}" # get the "next" image in this directory set img = \`basename \$FirstImage\` set img = \`ls -lnL \$framedir |& nawk '\$0 ~ /^\\-/ && \$5+0 > 800000 {print \$NF}' |& nawk "\$IMAGE_pattern" |& grep "\$ext" |& nawk -v key="\$img" '\$0 == key {getline; print}' \` if("\$img" != "") set img = "\${framedir}/\$img" echo "" if(-e "\$img") then # this could be a workable first image set temp = "Yes" echo "Is \$img the start of this wedge? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then # try this again set FirstImage = \$img # might need to reset some frame-specific variables goto FirstImageFound endif endif # no alternative images are available # ask for more frames set temp = "No" echo "Will there be more frames like \$FirstImage? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then # ask how many frames there will, evenutally, be @ temp = ((\$savelast - \$first) + 1) echo "How many? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [1-9]*) then set number_of_frames = \`echo \$temp | nawk '{print \$1+0}'\` set USER_WEDGE_SIZE = \$number_of_frames echo "" echo "\$scriptname will be created, but not run." echo "run \$scriptname when there are \$number_of_frames frames in this wedge." @ last = (\$first + \$number_of_frames) set savelast = \$last set NORUN endif else set newframe = "keep looking" echo "What is the first frame of the wedge you want to process? [\$newframe]" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$newframe" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set newframe = "\$in" endif # go back and check this set bad_frames = \`echo \$bad_frames \$FirstImage\` set FirstImage = "" # if user said so, frame is no longer bad set temp = "" foreach baddie ( \$bad_frames ) if(("\$baddie" !~ *"\$newframe"*)&&("\$newframe" !~ *\$baddie*)) set temp = "\$temp \$baddie" end set bad_frames = \`echo \$temp\` set inframes = \`echo \$newframe \$inframes |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 12) @ number = (\$number / 2 ) # mosflm can't handle more than 30 frames in postrefinement if(\$number > 30) set number = 30 # now 2 < number < 30 if(\$number < 4) then # small wedge, just do one segment set mosflm_postref_segs = 1 set frames_per_segment = \$number else if(\$number < 11) then # smallish wedge, two segments @ frames_per_segment = ( \$number / 2 ) else # do all subwedges as 4 frames each set frames_per_segment = 4 endif @ mosflm_postref_segs = ( \$number / \$frames_per_segment ) endif endif # absolute minimum for segment if(\$frames_per_segment < 2) set frames_per_segment = 2 @ number = ((\$last - \$first) + 1) # again, mosflm can't handle more than 30 frames in postrefinement #if(\$number > 30) set number = 29 # reduce frames per segment until number of frames is managable if(\$number < (\$frames_per_segment * \$mosflm_postref_segs)) then echo "Too many refinement frames, compensating ..." endif while((\$number < (\$frames_per_segment * \$mosflm_postref_segs))&&(\$frames_per_segment > 2)) @ frames_per_segment = ( \$frames_per_segment - 1 ) end # reduce number of segments, (if segment size is minimal and we still have too many frames) while(\$number < (\$frames_per_segment * \$mosflm_postref_segs)) @ mosflm_postref_segs = ( \$mosflm_postref_segs - 1 ) end # make sure there is at least one segment if(\$mosflm_postref_segs == 0) then set mosflm_postref_segs = 1 set frames_per_segment = \$number endif # absolute minimum for segment if(\$frames_per_segment < 2) set frames_per_segment = 2 ############################################################################### # check if space group has been set, if not, now is a good time to bug user # ############################################################################### Check_Space_Group: if("\$SG" != "unknown") then if("\$SG" =~ *-ish) then set SG_choice = "auto" set SG = \`echo \$SG | nawk -F "[-]" '{print \$1}'\` endif # make sure SG is in the space group library set SG = \`echo \$SG | nawk '{print toupper(\$1)}'\` cat \$CLIBD/symop.lib |&\\ nawk -v SG=\$SG '\$4==SG{type=substr(tolower(\$6),1,1); key=substr(\$6,4,1);\\ if((type=="t")&&(key=="G")) type="h"; if((type=="t")&&(key=="C")) type="a";\\ print \$1, \$5, type substr(\$4,1,1), \$6, substr(\$4,1,1)"_"substr(\$5,3);exit}' |\\ head -1 >! \${tempfile}sgdata set SG_number = \`nawk '{print \$1}' \${tempfile}sgdata\` set PG = \`nawk '{print \$2}' \${tempfile}sgdata\` set BRAV = \`nawk '{print \$3}' \${tempfile}sgdata\` set LATT = \`nawk '{print \$4}' \${tempfile}sgdata\` set LPG = \`nawk '{print \$7}' \${tempfile}sgdata\` rm -f \${tempfile}sgdata >& /dev/null if("\$SG_number" == "") then # this SG was not listed in the CCP4 library! echo "" echo "Woops! \$SG is not in space group library. \$BELL " echo "" set temp = "unknown" echo "What is your space group? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" =~ [PpCcIiFfRrHh][1-6]*) set temp = ( \$in ) endif set SG = "\$temp" # now go back and check this one goto Check_Space_Group endif # now decide between high-symmetry and low-symmetry refinement mode set test = \`echo "\$hires" | nawk '{printf "%.0f", \$1}'\` if(\$SG_number < 143 && \$test > 3) then # space group is < trigonal symmetry, cannot refine cell on small wedge if(\$wedge_width < 45 && \$wedge_width > 1) then # don't refine cell unless we have 45 degrees of data or more if(\$fixcell == no) then echo "" echo "WARNING: Cell refinement might be unstable with only \$wedge_width\$DEG of data! " if("\$true_cell" == "unk") then # user is undecided about this set temp = "No" echo "Shall we fix the cell? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$temp" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) set fixcell = yes # don't do this again set true_cell = no endif endif else # should have wide enough angle to refine cell, even with low symmetry endif else # can refine cell with only a few frames endif endif CheckCell: # Check that the cell is consistant with the space group if(("\$CELL" != "unknown")&&("\$SG" != "unknown")) then # get the lattice type set latt = \`nawk -v SG="\$SG" '\$4 == toupper(SG) {print \$6;exit}' \$CLIBD/symop.lib |& head -1\` # check Cell against lattice echo "\$CELL \$latt" |\\ nawk '{a=\$1+0; b=\$2+0; c=\$3+0; A=\$4+0; B=\$5+0; G=\$6+0}\\ \$NF == "MONOCLINIC" { A=90; ; G=90; if(\$4+0 > 5) B=\$4+0; if(\$5+0 > 5) B=\$5+0}\\ \$NF == "ORTHORHOMBIC" {A=90; B=90; G=90}\\ \$NF == "TETRAGONAL" || \$NF == "TRIGONAL" || \$NF == "HEXAGONAL" {\\ b=a; A=90; B=90; G=120;\\ if((c==0) && ((\$2-a)^2 > .0001)) {c = \$2+0}}\\ \$NF == "TETRAGONAL" {G=90}\\ \$NF == "CUBIC" {b=a; c=a; A=90; B=90; G=90}\\ END{if(a>5 && b>5 && c>5 && A>5 && B>5 &&G>5) print a, b, c, A, B, G}' |\\ cat >! \${tempfile} set temp = \`cat \${tempfile}\` rm -f \${tempfile} if("\$#temp" == 6) then # actual, corrected unit cell was given set CELL = \`echo "\$temp"\` endif endif # check the mosaicity, if it has not been set, pick a reasonable value if(("\$mosaic" == "auto")||("\$mosaic" == "")) then set mosaic = \`echo "\$osc" | nawk '\$1+0>0.05{print \$1/2}'\` if("\$mosaic" == "") set mosaic = 1 set temp = \`echo "\$MosflmVersion" | nawk '/[0-9]/{printf "%d", \$1*100}'\` if("\$temp" > 619) set mosaic = "estimate" endif # calculate resolution limit from detector geometry (unless user set it manually) if(("\$res_choice" == "auto")&&("\$Width" != "")&&(\$#beam_center == 2)) then # get resolution at all four corners and four midpoints echo "\$Width \$beam_center" |\\ nawk '{xmax=\$1; ymax=\$1; xc=\$2; yc=\$3; \\ print xc,yc,"C"; print xc,ymax-yc,"C"; print xmax-xc,yc,"C"; print xmax-xc,ymax-yc,"C";\\ print xc,0,"E"; print 0,yc,"E"; print xmax-xc,0,"E"; print ymax-yc,0,"E"}' |\\ nawk -v distance=\$distance -v two_theta=\$two_theta 'BEGIN{two_theta*=3.14159/180} \\ NF==3{x=\$1;y=\$2; L=distance-x*sin(two_theta); x=x*cos(two_theta);\\ print sin(atan2(sqrt(x^2 + y^2),L)/2),\$3}' |\\ nawk -v wavelength=\$wavelength '\$1+0>0{print wavelength/(2*\$1),\$2}' |\\ cat >! \${tempfile}res # disregard corners for circular detectors if(("\$Site" =~ MAR*)||(0)) then tail -4 \${tempfile}res >! \${tempfile} mv -f \${tempfile} \${tempfile}res >& /dev/null endif # set resolution limits set hires = \`sort -n \${tempfile}res | nawk '\$1+0>0{printf "%.1f", \$1; exit}'\` set edge_res = \`tail -4 \${tempfile}res | sort -n | nawk '\$1+0>0{printf "%.1f", \$1; exit}'\` rm -f \${tempfile}res >& /dev/null endif PrintIntentions: ############################################################################### ##### ###### ##### #### ##### ##### # # # # # # # # # # # # ##### # # # # # # # ##### # ##### # # ##### # # # # # # # # # # # # ###### # #### # # # ############################################################################### # # As a check, print out what Wedger Elves think they are supposed to do. # ############################################################################### if((\$?autoindexing)&&(! \$?NOMOSFLM)) goto autoindex unset FIRSTIME echo "" echo "" set temp = " that will run \$MOSFLM" if(\$?NORUN) set temp = " (but will not run it.)" set LastImage = \`echo "\$framedir/\$template \$last" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` echo "Wedger elves will create a script called \${scriptname}"\$temp echo " and process from \$FirstImage" echo -n " to \$LastImage" if(\$integrate == yes) then echo " into \$mtzout" else echo "" endif if((-e "\$inmatrix")&&(! \$?autoindexing)) then echo -n " using the orientation in \$inmatrix" if((\$add != 0)&&(\$integrate == yes)) then echo ", and adding \$add to each batch number." else echo "" endif else echo " after obtaining an orientation from autoindexing." endif if(("\$Interactive" == "PLOT")&&(! \$?AUTO)) then echo "" echo " The Mosflm interactive graphics window will be launched." endif #if(\$?NEW) then # echo "" # echo " First time processing these data." #endif if((\$?LAST_RUN)&&(! \$?NO_CCP4)) then echo "" echo " Then \$mtzout will be scaled and merged into \$mergefile." endif echo "" #set temp = \`echo "\${phi0} + (\$osc * (\$last - \$first + 1)) " | bc\` set temp = \`echo "\$phi0 \$osc \$last \$first" | nawk '{print \$1+(\$2*(\$3-\$4+1))}'\` echo " Data were collected from \${phi0}\$DEG to \${temp}\$DEG, in \${osc}\$DEG steps with the " echo " \$Site detector (gain = \$GAIN) at \$distance mm from the crystal and" set temp = \`echo \$two_theta | nawk '\$1+0 > 0{print \$1+0} \$1+0 < 0{print -(\$1+0)}'\` if("\$temp" != "") then echo -n " swung \${temp}" set temp = \`echo \$two_theta | nawk '\$1+0 > 0{print "counter-"}'\` echo "\$DEG \${temp}clockwise around the crystal rotation axis (2theta)" endif echo " the direct beam hit the detector at: \$beam_center" echo "" #set temp = \`echo "\$wavelength \$DISPERSION" | nawk '{if(\$1+0 == 0)\$1=1.54; printf "%.1f", 12398.4245/\$1 - (12398.4245/(\$1+ \$1*\$2))}'\` echo -n " X-rays were \${wavelength} \$ANG, " #set temp = \`echo "\$DISPERSION" | nawk '\$1+0 > 0{print 1/\$1}'\` #if("\$temp" != "") then # echo "with a spectral bandwidth of 1:\${temp}, and " #else # echo "with perfect bandwidth, and " #endif #echo -n " the beam was " #set temp = \`echo "\$DIVERGENCE" | nawk 'NF==1{print \$1} NF==2{print \$1 " x " \$2}'\` #echo -n "diverging by \${temp}\$DEG " set temp = \`echo "\$POLARISATION" | nawk '{print \$NF}'\` echo "with polarization \$temp" set temp = "" echo "" echo " Unit Cell is \$CELL" if(\$fixcell == yes) echo " and it will not be refined in this run." set sg_suffix = "" if("\$SG_choice" == "auto" && "\$SG" != "unknown") set sg_suffix = "-ish" set mosflmSG = \$SG echo " Spots will be measured out to \${hires} \$ANG with space group \$SG\${sg_suffix}" set temp = \`echo \$fixmosaicity \$mosaic | nawk '/no/{\$1="of"} /yes/{\$1="held at"} {printf "%s %.3f", \$1,\$2}'\` set temp = "\${temp}\$DEG" if("\$mosaic" == "estimate") set temp = "estimated from image \$first" echo " and a mosaic spread \${temp}" echo "" if(\$integrate == no) echo " Refinement will be in \${mosflm_postref_segs} blocks of \${frames_per_segment} frames. No integration." #if(\$usebeam == yes) echo " Parameters will be refined for each frame." if(\$fixyscale == no) echo " The detector X-to-Y scale will be refined." if((\$integrate == yes)&&(\$postref == no)) echo " Postrefinement will be turned OFF." echo "" if(("\$PREAMBLE" != "")||("\$EXTRA_REFINE_CARDS" != "")) then echo " additional keywords:" echo "\$PREAMBLE" | nawk 'BEGIN{RS="n"} {print " " \$0}' | nawk 'NF!=0' echo "\$EXTRA_REFINE_CARDS" | nawk 'BEGIN{RS="n"} {print " " \$0}' | nawk 'NF!=0' echo "" endif if(\$?NEW) then cat << EOF ^ ### #### # ### ##### # # # ### ^ /|\\ # # # # # # # # # # # # /|\\ | ### ### ##### # # # #### # ### | | # # # # # # # # # # # # | | # # #### # # ### # # # # #### | Make sure all the above numbers are correct. (Especially the beam center) EOF endif # # do Strategy? # #if(("\$strategize" == "yes")&&(-e "\$inmatrix")&&(\$#CELL == 6)&&(\$SG =~ [PpCcIiFfRrHh][1-6]*)&&(! \$?autoindexing)&&(! \$?Convergeing)) then if(("\$strategize" == "yes")&&(-e "\$inmatrix")&&(\$#CELL == 6)&&(\$SG =~ [PpCcIiFfRrHh][1-6]*)&&(! \$?autoindexing)) then set temp = "No" if(\$?NEW) set temp = "Yes" if("\$SG_choice" == "auto") set temp = "Yes" echo "Do you want our opinion on your collection strategy? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$temp" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then set strategize = "done" goto Strategy endif if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # weird answer, send it to interpreter set input = "\$temp" goto Questionaire endif # User has turned down the strategy offer set strategize = "done" endif ReturnFromStrategy: # # Warn user if matrix and SG are still not set up if((\$SG == unknown)||(! -e "\$inmatrix")) then echo -n "NOTE: \$scriptname will not run without " if(! -e "\$inmatrix") echo -n "a matrix file" if((\$SG == unknown)&&(! -e "\$inmatrix")) echo -n " and " if(\$SG == unknown) echo -n "a space group" echo "." if(! -e "\$inmatrix") echo " We can create a new matrix file by autoindexing." if(\$SG == unknown) then # echo " You can pick a space group by autoindexing interactively with mosflm," # echo " or let the elves pick one for you." endif echo "" # set autoindexing endif if(\$?NORUN) then # add BLU-ICE support here? set temp = "Yes" echo "Update \$scriptname and exit Wedger Elves? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$temp" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then # user specified updating the script, but not running it set NORUN goto ProcessData endif if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # non-standard user input set input = "\$temp" goto Questionaire endif # user seems to have changed mind about the -norun option unset NORUN endif # # Obligatory autoindexing # #if(((\$?autoindexing)||(\$SG == unknown)||(! -e "\$inmatrix"))&&(! \$?NORUN)) then if((\$?autoindexing)||(\$SG == unknown)||(! -e "\$inmatrix")) then set temp = "Yes" echo "Shall we autoindex now? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$temp" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) goto autoindex if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # non-standard user input set input = "\$temp" goto Questionaire endif # can't process, and can't autoindex, what do you want from me? set input = "" if(\$SG == unknown) set input = "wrong space group" if((! -e "\$inmatrix")&&(\$SG == unknown)) set input = "\${input} and" if(! -e "\$inmatrix") set input = "\${input} no matrix" # default to missing info set temp = "\$input" if("\$temp" == "") set temp = "nothing" echo "What's wrong? [\$temp]?" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" != "nothing") then set input = "\$temp" goto Questionaire endif endif # be a pest about the graphics window if(((! \$?AUTO)&&(! \$?NORUN)&&(\$?NEW))||("\$Interactive" == "PLOT")) then # graphics window will be displayed this run set temp = "No" if((! \$?AUTO)&&(! \$?NORUN)&&(\$?NEW)) set temp = "Yes" if(\$?Explicit_window) set temp = "Yes" unset Explicit_window echo "Do you want to monitor this run in the graphics window? (3x slower) [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then set Interactive = "PLOT" goto ProcessData endif if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # weird answer, send it to interpreter set input = "\$temp" goto Questionaire endif set Interactive = "#PLOT" endif # if this variable is set, we are converging if(\$?CATCH_USER) onintr Questionaire if((\$?AUTO)||(\$?ONCEONLY)||(\$?Convergeing)) goto ProcessData if((! \$?NORUN)&&(-e "\$inmatrix")&&(! \$?autoindexing)) then set temp = "Yes" echo "Shall we run \$scriptname now? [\$temp]? \$BELL" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" =~ [Yy]*) goto ProcessData if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # weird answer, send it to interpreter set input = "\$temp" goto Questionaire endif endif set temp = "" if(\$#CELL != 6) set temp = "bad cell" if(\$SG == "unknown") set temp = "wrong space group" if((\$#CELL != 6)&&(\$SG == "unknown")) set temp = "wrong space group and bad cell" if("\$temp" == "") set temp = "nothing" echo "What's wrong? [\$temp]?" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" != "nothing") then set input = "\$temp" goto Questionaire endif UpdateScript: set temp = "Yes" if("\$mosflm_status" != 0) set temp = "No" echo "Shall we update \${scriptname}? [\${temp}]?" echo -n "\$PROMPT" if(! \$?AUTO) then echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) else echo "\$temp" endif if("\$temp" =~ [Nn]*) then set NORUN goto Cleanup endif # user specified updating the script, but not running it set NORUN goto ProcessData Questionaire: ############################################################################### #### # # ###### #### ##### # #### # # ## # ##### ###### # # # # # # # # # # ## # # # # # # # # # # # ##### #### # # # # # # # # # # # # ##### # # # # # # # # # # # # # # ###### # ##### # # # # # # # # # # # # # ## # # # # # # ### # #### ###### #### # # #### # # # # # # # ###### ############################################################################### # # Question user about each variable, defaulting to previous value # ############################################################################### # forget recommendation, since user is explicitly telling us to do something unset recommendation # reset Ctrl-C catch onintr unset AUTO unset BURSTMODE unset LAST_RUN set understood = "" # # # Performs a keyworded search on user input to expedite proper initialization of variables # # # backup question, for calls without their own prompts if("\$input" == "") then set temp = "nothing" echo "What's wrong? [\$temp]?" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) # if("\$temp" != "nothing") then set input = "\$temp" # endif endif # Deploy Ginger, the English-to-Elvish translator # look for special characters set temp = \`echo "\$input" | nawk '/\\177/'\` if("\$temp" != "") then # keep this from happening again stty erase '^?' set input = \`echo "\$input" | nawk '{gsub("\\177","",\$0);print}'\` endif echo "\$input" | egrep '^\\\$' > /dev/null if(! \$status) then # execute an escaped shell command set input = \`echo "\$input" | nawk '{print substr(\$0,2)}'\` \$input goto ProcessInput endif # look for Wedger-specific commands # space group set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^space/ || /^sg\$/ || /^[PpCcIiFfRrHh][1-6]/'\` if("\$temp" != "") then # see if space group was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} /^[PpCcIiFfRrHh][1-6]/'\` if("\$temp" !~ [PpCcIiFfRrHh][1-6]*) then set temp = "\$SG" # something is wrong with space group, but we don't know what echo "What is your space group? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) then set SG = "\$temp[1]" set SG_choice = user endif if("\$temp" =~ unk*) set SG = unknown set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # new preamble cards set temp = \`echo \$input | nawk '{print toupper(\$0)}' | egrep "\$PASSTHRU_CARDS"\` if("\$temp" == "") set temp = \`echo \$input | egrep "^REFINE|^POSTREF|^LIMIT"\` if("\$temp" != "") then # add these to preamble (check it later) echo \$PREAMBLE | nawk 'BEGIN{RS="n"} {print}' >! \$tempfile echo \$temp |\\ nawk '! (/^LIMIT/ && \$2 !~ /^EXCLU/)' >> \$tempfile set PREAMBLE = \`nawk 'BEGIN{ORS="n"} NF != 0' \${tempfile} | nawk -v L=\$MAXLINE '{print substr(\$0,1,L)}'\` set understood = "\$understood \$temp" endif # clear PREAMBLE set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^clear/ || /^remove/ || /^addit/ || /^keyword/'\` if("\$temp" != "") then set temp = "Yes" echo "Do you want to clear the additional keywords? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" =~ [Yy]*) then set PREAMBLE = "" set EXTRA_REFINE_CARDS = "" endif set understood = "\$understood clear" endif # unit cell set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^cell/'\` if("\$temp" != "") then # see if unit cell was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '(\$0+0 > 5 || /^unk/) && p>0 {print \$0; --p} /^cell/{p=6}'\` set cell = \`echo \$temp |& nawk 'BEGIN{RS=" "} \$0+0 > 5 && p<6 {printf "%g ", \$0+0; ++p}'\` if((\$#cell != 6)&&("\$temp" !~ unk*)) then set temp = "\$CELL" # something is wrong with the cell, but we don't know what echo "What is your unit cell? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif set cell = \`echo \$temp |& nawk 'BEGIN{RS=" "} \$0+0 > 5 && p<6 {printf "%g ", \$0+0; ++p}'\` if(\$#cell == 6) set CELL = \`echo "\$cell"\` if("\$temp" =~ unk*) set CELL = unknown set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # resolution set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^reso/ || /^measu/ || /^diffra/ || /[\\305]/'\` if("\$temp" == "") set temp = \`echo \$input | nawk 'BEGIN{RS=" "} \$1=="A" && val>0.1{print val} {val = \$1+0} \$1 ~ /[0-9]A\$/ && \$1+0>0.1 {print \$1+0}'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0.1 && p>0 {printf "%g ", \$0+0; --p} /^reso/{p=1} /^diffra/{p=1} /^measu/{p=4}'\` if("\$temp" !~ *[0-9]) set temp = \`echo \$input | nawk 'BEGIN{RS=" "} \$1=="A" && val>0.1{print val} {val = \$1+0} \$1 ~ /[0-9]A\$/ && \$1+0>0.1 {print \$1+0}'\` # make sure diffraction limit is possible if("\$temp" =~ *[0-9]) then # diffraction limit cannot exceed x-ray wavelength if(\`echo \$temp \$wavelength | nawk '{print (\$1<\$2)}'\`) set temp = "" endif if("\$temp" !~ [0-9]*) then set temp = "\$hires" # something is wrong with this parameter, but we don't know what echo "How far could this crystal possibly diffract? [\$temp \$ANG]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set in = \`echo \$in | nawk '\$1+0 > 0 {print \$1+0}'\` if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [0-9]*) then set hires = "\$temp" set merge_res = "\$temp" set res_choice = user endif set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # mosaicity set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^mosaic/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0.01 && \$0+0 < 10 && p>0 {printf "%g ", \$0+0; --p} /^mosaic/{p=1}'\` if("\$temp" !~ [0-9]*) then set temp = "\$mosaic" # something is wrong with this parameter, but we don't know what echo "What is the mosaicity? [\$temp \$DEG]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set in = \`echo \$in | nawk '\$1+0 > 0.01 {print \$1+0}'\` if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [0-9]*) set mosaic = "\$temp" set understood = "\$understood \$temp" endif # wavelength set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^wave/ || /^x-ray/ || /^energy/ || /ev\$/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0 && p>0 {val=\$0+0; getline; if(\$0 == "kev") val *=1000; printf("%g ", val); --p} /^wave/{p=1} /^energy/{p=1}'\` if("\$temp" !~ *[0-9]) then set temp = "\$wavelength" # something is wrong with this parameter, but we don't know what echo "X-ray wavelength/energy? [\$temp \$ANG]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set in = \`echo \$in | nawk 'tolower(\$0) ~ /kev\$/{print \$1*1000} ! /kev\$/{print \$1+0}'\` if("\$in" != "") set temp = ( \$in ) endif set temp = \`echo \$temp | nawk '{w = \$1+0; if(w>0.2){ if(w<10){print w}else{print 12398.4245/w}}}' | tail -1\` if("\$temp" =~ *[0-9]) set wavelength = "\$temp" set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # detector gain set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^gain/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0.01 && \$0+0 < 20 && p>0 {printf "%g ", \$0+0; --p} /^gain/{p=1}'\` if("\$temp" !~ [0-9]*) then set temp = "\$GAIN" # something is wrong with this parameter, but we don't know what echo "What is the quantum gain of the detector? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set in = \`echo \$in | nawk '\$1+0 > 0 {print \$1+0}'\` if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [0-9]*) set GAIN = "\$temp" set understood = "\$understood \$temp" endif # beam polarization set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^polar/ || /^monoc/ || /^graphite/ || /^mirror/ || /^pinhole/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0 && \$0+0 < 1 && p>0 {printf "%g ", \$0+0; --p} /^polar/{p=1}'\` if("\$temp" !~ [0-9]*) set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print toupper(\$0)}' | nawk '/^MONOC/ || /^GRAPH/{print "MONOCHROMATOR"} /^MIRROR/ || /^PINHOLE/'\` set temp = \`echo "\$temp" | nawk '{print \$1}'\` if("\$temp" == "") then set temp = \`echo \$POLARISATION | nawk '{print \$NF}'\` # something is wrong with this parameter, but we don't know what echo "What is the beam polarization? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" !~ [0-9]*) set temp = \`echo \$temp | nawk 'BEGIN{RS=" "} {print toupper(\$0)}' | nawk '/^MONOC/ || /^GRAPH/{print "MONOCHROMATOR"} /^MIRROR/ || /^PINHOLE/'\` endif if("\$temp" != "") set POLARISATION = "\$temp" # make sure mosflm recognizes this if("\$POLARISATION" =~ [0-9]*) set POLARISATION = \`nawk -v p=\$POLARISATION 'BEGIN{print "SYNCHROTRON", p+0}'\` set understood = "\$understood \$temp" endif # # Initialize data collection strategy # # starting phi set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^phi/ || /^start/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk ' ! /[a-z,A-Z]/ && /[0-9]/ && p>0 {printf "%g ", \$0+0; --p} tolower(\$0) ~ /^phi/{p=1}'\` if("\$temp" !~ [0-9]*) then set temp = "\$phi0" # something is wrong with this parameter, but we don't know what echo "What is your starting phi? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = \`echo \$in | nawk '{print \$1+0}'\` endif if("\$temp" =~ *[0-9]*) set phi0 = "\$temp" set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # Oscillation angle set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^osc/ || /^step/ || /^delta/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0 && \$0+0 < 20 && p>0 {printf "%g ", \$0+0; --p} tolower(\$0) ~ /^osc/{p=1}'\` if("\$temp" !~ [0-9]*) then set temp = "\$osc" # something is wrong with this parameter, but we don't know what echo "Oscillation? (delta phi) [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set in = \`echo \$in | nawk '\$1+0 > 0 {print \$1+0}'\` if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [0-9]*) set osc = "\$temp" set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # # Processing mode # # Interactive? set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/inter/ || /graph/ || /watch/ || /window/ || /display/ || /predic/'\` if("\$temp" != "") then # see if we can figure out flag from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '{p="Y"} /nopost/{print "N"} /^no/{p="N"; getline} /^don/{p="N"; getline} /^stop/{p="N"; getline} /inter/{print p} /graph/{print p} /window/{print p} /predic/{print p} {p=""}'\` if("\$temp" == "") then # get current setting set temp = "No" # something is wrong with this parameter, but we don't know what echo "Do you want the graphics window? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then set Interactive = "PLOT" set Explicit_window if(\$?AUTO) unset AUTO endif if("\$temp" =~ [Nn]*) set Interactive = "#PLOT" set understood = "\$understood interactive" set strategize = no endif # automatic? set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$1 == "auto"'\` if("\$temp" == "auto") then set temp = "Yes" if("\$input" != "auto") then # might have meant something else echo "Shall we go fully automatic? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then set AUTO set CATCH_USER set understood = "\$understood go auto" endif endif # autoindex? set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/autoin/ || /index/'\` if("\$temp" == "") then set temp = \`echo \$input | nawk '{print tolower(\$0)}' | nawk '/matr/ && /bad/'\` if("\$temp" != "") then # remove mention of matrix, it will be handled here set input = \`echo \$input | nawk 'BEGIN{RS=" "} {print}' | grep -iv matr\` endif endif if("\$temp" != "") then # see if we can figure out flag from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '{p="Y"} /noauto/{print "N"} /^no/{p="N"; getline} /^don/{p="N"; getline} /^stop/{p="N"; getline} /autoin/{print p} /index/{print p} {p=""}'\` if("\$temp" == "") then # get current setting set temp = "No" if(\$?autoindexing) set temp = "Yes" # something is wrong with this parameter, but we don't know what echo "Auto-index? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) set autoindexing if("\$temp" =~ [Nn]*) unset autoindexing set understood = "\$understood index" if("\$strategize" == "done") set strategize = "yes" endif # integrate? set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/integ/'\` if("\$temp" != "") then # see if we can figure out flag from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '{p="Y"} /nointe/{print "N"} /^no/{p="N"; getline} /^don/{p="N"; getline} /^stop/{p="N"; getline} /^integ/{print p} {p=""}'\` if("\$temp" == "") then # get current setting set temp = \`echo "\$integrate" | nawk '{print substr(toupper(\$0),1,1)}'\` # something is wrong with this parameter, but we don't know what echo "Integrate? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) set integrate = yes if("\$temp" =~ [Nn]*) set integrate = no # have to do at least one of these if("\$integrate" == "no") set postref = yes if(("\$integrate" == "yes")&&(\$?NEW)) unset NEW set understood = "\$understood integ" endif # merge (or last run) set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^merge/ || /^scale/'\` if("\$temp" != "") then # asking for smooth scaling set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/smooth/'\` if("\$temp" != "") then echo "switching on smooth scales" set SMOOTH_RUNS = "scales rotation spacing 5 bfactor on" endif # see if we can figure out flag from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '{p="Y"} /nomerge/{print "N"} /^no/{p="N"; getline} /^don/{p="N"; getline} /^stop/{p="N"; getline} /^merge/{print p} {p=""}'\` if("\$temp" == "") then # get current setting set temp = "No" if(\$?LAST_RUN) set temp = "Yes" # something is wrong with this parameter, but we don't know what echo "Merge data now? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then set LAST_RUN # merge now, of we can if(-e \$mtzout) goto scale_and_merge echo "Sorry, \$mtzout does not exist." echo "We have to integrate before we can merge." set integrate = "yes" endif if("\$temp" =~ [Nn]*) unset LAST_RUN # no sense mergeing if we didn't integrate if("\$integrate" == "no") set integrate = yes if(("\$integrate" == "yes")&&(\$?NEW)) unset NEW set understood = "\$understood merge" endif # run Strategy? set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^strateg/'\` if("\$temp" != "") then # see if we can figure out flag from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '{p="Y"} /nostrat/{print "N"} /^no/{p="N"; getline} /^don/{p="N"; getline} /^stop/{p="N"; getline} /^strateg/{print p} {p=""}'\` if("\$temp" =~ [Yy]*) then set strategize = "yes" if((-e "\$inmatrix")&&("\$SG" != "unknown")) then goto Strategy else echo "Elves cannot strategize without a matrix and space group! " endif endif if("\$temp" =~ [Nn]*) set strategize = "no" set understood = "\$understood strategy" endif # postrefine? set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/postr/ || /refine/'\` if("\$temp" != "") then # see if we can figure out flag from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '{p="Y"} /nopost/{print "N"} /^no/{p="N"; getline} /^don/{p="N"; getline} /^stop/{p="N"; getline} /ref/{print p} {p=""}'\` if("\$temp" == "") then # get current setting set temp = \`echo "\$postref" | nawk '{print substr(toupper(\$0),1,1)}'\` # something is wrong with this parameter, but we don't know what echo "Refine parameters this run? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) set postref = yes if("\$temp" =~ [Nn]*) set postref = no set understood = "\$understood postref" endif # segmentation parameters set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^bloc/ || /^segment/'\` if(("\$temp" != "")&&(\$postref == yes)&&(\$integrate == no)) then # see if we can figure out number of segments from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '{num=""} \$0+0 > 0 {num=\$0+0; getline} /^bloc/{print num} /^segment/{print num}'\` if("\$temp" == "") then set temp = "\$mosflm_postref_segs" echo "number of frame blocks to postrefine? [\${temp}|auto]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" != "") set mosflm_postref_segs = "\$temp" # see if we can figure out block size from context set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 1 && \$0+0 < 30 && p>0 {printf "%g ", \$0+0; --p} /^block/{p=1} /^segment/{p=1}'\` if("\$temp" == "") then set temp = "\$frames_per_segment" echo "postrefinement block size (in frames)? [\${temp}|auto]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" != "") set frames_per_segment = "\$temp" set understood = "\$understood \$temp" # prevent embarassing double-hit set input = \`echo \$input | nawk 'BEGIN{RS=" "; ORS=" "} /frame/ && ! hit {getline; ++hit} {print}'\` endif # quit? if(("\$input" == "quit")||("\$input" == "exit")||("\$input" == "exit")) then # ask about the script first goto UpdateScript endif # fix CELL set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^no/{p= p "n"} /^un/{p= p "n"} /^don/{p = p "n"} /refine/{p= p "n_f"} /fix/{p= p "f"} /hold/{p= p "f"} /keep/{p= p "f"} /cell/{print p "c"; p=""} {p = p "_"}' | tail -1\` if("\$temp" =~ *f*) then # see if we can figure out flag from context set temp = \`echo \$temp | nawk '/f__c/ || /f_c/{if((\$0 ~ /n_f/)||(\$0 ~ /n__f/)){print "N"}else{print "Y"}}'\` if("\$temp" == "") then # get current setting set temp = \`echo "\$fixcell" | nawk '{print substr(toupper(\$0),1,1)}'\` # something is wrong with this parameter, but we don't know what echo "Fix the cell during refinement? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) set fixcell = yes if("\$temp" =~ [Nn]*) set fixcell = no if("\$temp" =~ [Nn]*) set true_cell = no set understood = "\$understood fixcell" # prevent embarassing double-hits set input = \`echo \$input | nawk 'BEGIN{RS=" "; ORS=" "} /cell/ && ! hit {getline; ++hit} {print}'\` endif # fix mosaicity set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^no/{p= p "n"} /^un/{p= p "n"} /^don/{p = p "n"} /refi/{p= p "nf"} /fix/{p= p "f"} /hold/{p= p "f"} /keep/{p= p "f"} /mosa/{print p "m"; p=""} {p = p "_"}' | tail -1\` if("\$temp" =~ *f*) then # see if we can figure out flag from context set temp = \`echo \$temp | nawk '/f__m/ || /f_m/{if((\$0 ~ /nf/)||(\$0 ~ /n_f/)||(\$0 ~ /n__f/)){print "N"}else{print "Y"}}'\` if("\$temp" == "") then # get current setting set temp = \`echo "\$fixmosaicity" | nawk '{print substr(toupper(\$0),1,1)}'\` # something is wrong with this parameter, but we don't know what echo "Keep the mosaicity at \$mosaic from now on? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) set fixmosaicity = yes if("\$temp" =~ [Nn]*) set fixmosaicity = no set understood = "\$understood fixcell" endif # fix YSCALE set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^no/{p= p "n"} /^un/{p= p "n"} /^don/{p = p "n"} /fix/{p= p "f"} /scale/{print p "s"; p=""} ! /^y/{p = p "_"}' | tail -1\` if("\$temp" =~ *f*) then # see if we can figure out flag from context set temp = \`echo \$temp | nawk '/f__s/ || /f_s/{if((\$0 ~ /n_f/)||(\$0 ~ /n__f/)){print "N"}else{print "Y"}}'\` if("\$temp" == "") then # get current setting set temp = \`echo "\$fixyscale" | nawk '{print substr(toupper(\$0),1,1)}'\` # something is wrong with this parameter, but we don't know what echo "Fix the X-to-Y scale during refinement? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) set fixyscale = yes if("\$temp" =~ [Nn]*) set fixyscale = no set understood = "\$understood fixcell" endif # # Finding files, etc. # # frame location set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^frame/ || /^image/ || /^directory/ || /^locat/ || /^start/'\` if(("\$temp" != "")&&(! \$?FIRSTIME)) then echo "Double-check: " # see if frame file name was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print}' | egrep "\${framepattern}" | head -1\` if(("\$temp" != "")&&(! -e "\$temp")) set temp = \${framedir}/\$temp if(! -e "\$temp") then set temp = "\$FirstImage" # something is wrong with this parameter, but we don't know what echo "What is the first image in this wedge? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if(! -e "\$temp") then # see if directory name was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} /\\//' | head -1\` if(! -e "\$temp") then #set temp = "\$framedir" set temp = "\$FirstImage" # something is wrong with this parameter, but we don't know what echo "Where are your frames? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif endif if(-e "\$temp") then set FirstImage = "\$temp" else echo "Sorry! the file \$temp does not exist! " set input = "" goto Questionaire endif # the following is essentially duplicated from FirstImageFound: # get file name info from the frame's name set framedir = \`dirname \$FirstImage\` set ext = \`echo \$FirstImage |& nawk 'BEGIN{FS="."} \$NF~/^[a-z]/{print "."\$NF}'\` set FirstImage = \`basename \$FirstImage\` set frameprefix = \`basename \$FirstImage \$ext\` # construct the template pattern from this filename set template = \`echo \${frameprefix} \$ext | nawk '{while(\$1~/[0-9]\$/){patt=patt "\\043"; \$1=substr(\$1,1,length(\$1)-1)}} {print \$1 patt \$2}'\` set compatible = \`echo "\$template" | nawk '/[_-]\\043\\043\\043[.]/{print "yes"}'\` # scan for the last possible file in the wedge ls -lnL \${framedir} |&\\ nawk -v first=\$FirstImage '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # constrain template based on available filenames ls -1 \$framedir |\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print}' |\\ nawk -v first=\$FirstImage -v last=\$LastImage '\\ \$1==first{p=1} p{print} \$1==last{p=0}' |\\ nawk '{if(length(\$0)>maxlen) maxlen=length(\$0);\\ for(col=1;col<=maxlen;++col){c=substr(\$0,col,1);\\ if(tpl[col]!=c){tpl[col]=tpl[col] c}}} \\ END{for(col=1;col<=maxlen;++col){\\ if(length(tpl[col])!=1) tpl[col]="\\043";\\ printf "%s", tpl[col]}; print ""}' |\\ cat >! \${tempfile} set temp = \`nawk 'BEGIN{FS="\\043"} {print NF}' \${tempfile}\` if("\$temp" > 2) then # set template = \`cat \${tempfile}\` endif rm -f \${tempfile} # now we have template in "prefix###.img format" # make a pattern for recognizing new images set noglob set framepattern = \`echo "\$template" | nawk '{gsub("[\\044\\050\\051\\052\\053\\054\\056\\077\\133\\134\\135\\136]","[&]",\$0); gsub("\\043","[0-9]",\$0); print "^" \$0 "\$"}'\` unset noglob set first = \`echo "\$FirstImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` set FirstImage = \`echo "\$framedir/\$template \$first" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` # check for backward-compatibility if("\$compatible" != "") then # template has the form prefix[-_]###.ext # so, safe to use "old" image file breakdown set ext = \`echo \$FirstImage |& nawk 'BEGIN{FS="."} {print \$NF}'\` set frameprefix = \`basename \$FirstImage .\$ext | nawk '{print substr(\$1, 1, length(\$1)-4)}'\` set TEMPLATE = "" else # we will have to use the mosflm v5.4+ TEMPLATE keyword set TEMPLATE = "TEMPLATE \$template" set frameprefix = \`echo "\$template" | nawk 'BEGIN{FS="\\043"} {print \$1}'\` endif # check for user-specified last image set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0 && \$0 !~ /\\./ && p>0 {printf "%d ", \$0+0; --p} /^last/{p=1}'\` if("\$temp" == "") set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 0 && \$0 !~ /\\./ {v = \$0+0; getline; if(\$0 == "frames") print v}'\` if("\$temp" != "") set last = "\$temp" echo "What is the ending frame number? [\${last}]" echo -n "\$PROMPT" set temp = "\$<" set temp = \`echo "\$temp" | nawk '{print \$1+0}'\` if(\$temp > 0) set last = "\$temp" @ number_of_frames = ( ( \$last - \$first ) + 1 ) set LastImage = \`echo "\$framedir/\$template \$last" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # output script set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/.sh\$/ || /.com\$/ || /^output/ || /^script/ || /^file/ || /^name/'\` set temp = "" if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print}' | nawk '/.sh\$/ || /.com\$/' | head -1\` if("\$temp" == "") then set temp = "\$scriptname" # something is wrong with this parameter, but we don't know what echo "What do you want the script to be called? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" != "") then set scriptname = "\$temp" set understood = "\$understood \$temp" endif endif # output mtz file set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/.mtz\$/ || /^output/ || /^file/ || /^name/'\` if(("\$temp" != "")&&("\$understood" !~ *file*)&&("\$understood" !~ *output*)&&("\$understood" !~ *name*)) then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} /.mtz\$/' | head -1\` if("\$temp" == "") then set temp = "\$mtzout" # something is wrong with this parameter, but we don't know what echo "What do you want the output mtz file to be called? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ *.mtz) then set mtzout = "\$temp" else echo "SORRY, unmerged output is (currently) only in MTZ format." echo " But, you can always use mtz2various.com to convert \${mtzout}." endif set understood = "\$understood \$temp" endif # mosflm executable file set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/mosflm/ || /execut/'\` if(("\$temp" != "")&&("\$understood" !~ *mosflm*)) then # see if real filename was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print}' | nawk '/mosflm/' | head -1\` if( -e "\$temp") set temp = \`ls -lnLd \$temp |& nawk '\$5>3000000{print \$NF}'\` if(! -e "\$temp") then set temp = "\$MOSFLM" # something is wrong with this parameter, but we don't know what echo "Which Mosflm executable shall we use? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if(-e "\$temp") then set mosflm = "\$temp" set temp = \`echo "GO" | \$mosflm SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$temp" !~ [1-9]*) then # no dice echo "\$mosflm does not appear to be a MOSFLM executable! " set mosflm = "" else unset NORUN set MOSFLM = \$mosflm set MosflmVersion = "\$temp" endif else echo "HEY! \$temp does not exist! " endif set understood = "\$understood \$temp" endif # "ADD" value for batch numbers set temp = \`echo \$input | nawk '/^ADD /'\` #set temp = "" if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > -0.1 && \$0+0 < 9000 && p>0 {printf "%d ", \$0+0; --p} /^add/{p=1}'\` if("\$temp" !~ [0-9]*) then set temp = "\$add" # something is wrong with this parameter, but we don't know what echo "What value should be added to frame numbers in \${mtzout}? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set in = \`echo \$in | nawk '\$1+0 >= 0 {printf "%d", \$1+0}'\` if("\$in" != "") set temp = ( \$in ) endif if((\$temp + \$last - \$first) < 9999) then set add = "\$temp" else echo "SORRY: batch numbers greater than 9999 are not allowed here. " endif set understood = "\$understood \$temp" endif # # Alignment # # XTF distance set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^dist/ || /^xt/ || /^crystal/ || /^detect/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '\$0+0 > 10 && \$0+0 < 1000 && p>0 {printf "%g ", \$0+0; --p} /^dist/{p=1} /^xtf/{p=1}'\` if("\$temp" !~ [0-9]*) then set temp = "\$distance" # something is wrong with this parameter, but we don't know what echo "Crystal-to-Film Distance? [\$temp mm]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set in = \`echo \$in | nawk '\$1+0 > 10 {print \$1+0}'\` if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [0-9]*) set distance = "\$temp" set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # 2THETA angle set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^detect/ || /^swing/ || /^swung/ || /^twoth/ || /theta/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk 'p>0 && /[0-9]/ && ! /[a-z]/ {printf "%g ", \$0+0; --p} /theta/{p=1} /^twoth/{p=1} /^swing/{p=1} /^swung/{p=1}'\` if("\$temp" !~ *[1-9]*) then set temp = "\$two_theta" # something is wrong with this parameter, but we don't know what echo "2THETA angle (counterclockwise detector swing around phi axis)? [\${temp}\$DEG]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = \`echo \$in | nawk '{print \$1+0}'\` endif if("\$temp" =~ *[0-9]*) set two_theta = "\$temp" set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # orientation matrix set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^matr/ || /^orien/ || /.mat\$/'\` if("\$temp" != "") then # see if matrix filename was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print}' | nawk '/.mat\$/' | head -1\` if(! -e "\$temp") then if(! -e "\$temp") set temp = "\$inmatrix" foreach word ( \$input ) # look for last word that is an existing file if(-e \$word) set temp = \$word end # something is wrong with this parameter, but we don't know what echo "Where is your orientation matrix? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if(-e "\$temp") then set inmatrix = "\$temp" unset autoindexing set input = "\$input scan \$inmatrix" else echo "HEY! \$temp does not exist! " endif set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif #Beam center set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print tolower(\$0)}' | nawk '/^direct/ || /^beam/ || /^center/'\` if("\$temp" != "") then # see if value was given set temp = \`echo \$input | nawk 'BEGIN{RS=" "} \$0+0 > 10 && \$0+0 < 1000 && p>0 {printf "%g ", \$0+0; --p} tolower(\$0) ~ /^beam/{p=2}'\` if(\$#temp != 2) then set temp = "\$beam_center" # something is wrong with this parameter, but we don't know what echo "What is the direct beam center? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if(\$#temp == 2) then # something was entered by user set beam_center = \`echo \$temp\` unset UNRELIABLE_BEAM if((\$temp[1] =~ [1-9]*)&&(\$temp[2] =~ [1-9]*)) then set temp = "mosflm" echo "Is this beam center from Mosflm, adxv, R-axis(horiz, vert), or denzo? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = \`echo \$in | nawk '{print tolower(\$0)(\$1)}'\` if("\$temp" =~ mos*) then # no change endif if(("\$temp" =~ den*)&&("\$Site" =~ *mar*)) then # different origin for MAR set beam_center = \`echo "\$beam_center \$Site" | nawk '{print \$2, \$NF-\$1}'\` endif if("\$temp" =~ ad*) then set temp = \`echo \$beam_center\` # mosflm X is ( frame width) - (ADXV's Y), mosflm Y is ADXV's X if(! \$?Width) set Width = 188 #set beam_center = \`echo "\$Width - \$temp[2]" | bc\` set beam_center = \`echo "\$Width \$temp[2]" | nawk '{print \$1-\$2}'\` set beam_center = \`echo \$beam_center \$temp[1]\` endif if("\$temp" =~ r*) then # R-axis horizontal axis is Y, vertical axis is X set beam_center = \`echo "\$beam_center[2] \$beam_center[1]"\` endif endif endif set understood = "\$understood \$temp" if("\$strategize" == "done") set strategize = "yes" endif # (re)scan a file? set temp = \`echo \$input | nawk 'BEGIN{RS=" "} {print}' | nawk 'tolower(\$0)~/^scan|^rescan|^read/{p=1} p==1{print}'\` if("\$temp" != "") then # see if we can figure out files from context set sources = "" foreach file ( \$temp ) if(-e "\$file") then # scan these in order specified by user set sources = "\$file \$sources" endif end if("\$sources" != "") goto GetParamsFromSources # must want to scan something, but we don't know what set temp = "\$oldscripts" echo "Scan an input file(s)? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" != "") then set sources = "\$temp" goto GetParamsFromSources endif set understood = "\$understood scan" endif if(("\$understood" == "")&&("\$input" != "nothing")) then # What matter of sanscrit is this?! # echo "\$input" | mail jamesh@ucxray6.berkeley.edu set temp = "nothing" echo "Um ... what, exactly, do you mean by "\\"\$input\\""? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) set input = "\$temp" goto Questionaire endif set input="" goto ProcessInput ProcessData: ############################################################################### # # ## # # ###### #### #### ##### # ##### ##### ## ## # # # # # # # # # # # # # # # ## # # # #### ##### #### # # # # # # # # # ###### # # # # # ##### # ##### # # # # # # # # # # # # # # # # # # # # # # # ###### #### #### # # # # # ############################################################################### # # # At this point, all relevant information about this processing run has been # gathered and checked for validity. # ############################################################################### # some numbers we will need set first_frame = \`echo "\$template \$first" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` if("\$TEMPLATE" != "") set first_frame = "\$first" set end_phi = \`echo \$phi0 \$osc | nawk '{printf "%d", \$1+\$2}'\` # must be no-run, so make up a matrix name if("\$inmatrix" == "") set inmatrix = "best.mat" ############################################################################### # create the README file, if necessary # ############################################################################### if(! -e README) then cat << EOF-readme >! README Wedger Elves guide to their scripts 1) In a rush? Just type this: \$scriptname integ >! logs/mosflm.log \$mergescript >! logs/merge.log That should do it. The logs from these runs: logs/mosflm.html and logs/merge.log can be viewed in CCP4's xloggraph program or netscape for a graphical view of your data reduction parameters. Your scaled and merged data will end up in \${mergefile}, (in CCP4 format) to convert it to other formats, read on... 2) Okay, how does it work? Wedger Elves do a lot of fancy footwork to get mosflm running properly and smoothly. It is HIGHLY recommended that you use Wedger Elves, and let them optimize your parameters as much as they can before you start messing around with these scripts yourself. They are more likely to run properly if you do. In this directory (\`pwd\`): ################################################################################ \$scriptname - mosflm script reads: x-ray images (\${framedir}/\${template}) \$inmatrix - the crystal's orientation matrix (mosflm format) makes: \$mtzout - integrated spot intensity data (CCP4 mtz format) \$outmatrix - the refined crystal orientation matrix usage: \$scriptname [integ] example: \$scriptname The \$scriptname script is meant to be a bare-bones script for running A.G.W. Leslie's ipmosflm program. If you don't have mosflm, you can download it for free from: netscape ftp://ftp.mrc-lmb.cam.ac.uk/pub/mosflm/ As long as the Wedger Elves could find the ipmosflm executable, and some x-ray data, they should have set up mosflm.com to at least run. Remember, a mosflm matrix must be obtained from autoindexing, (or from another wedge of data collected from the same data collection session) before mosflm.com will run. (see autoindex.inp below) NOTE: THIS SCRIPT HAS TWO MODES! 1) if this script has a "POSTREF SEGMENTS" line in it, then it is set up to only refine your crystal and camera parameters. It will produce the refined crystal orientation in \$outmatrix This file should be copied to \$inmatrix if you want to re-input this orientation into the next mosflm run. 2) if this script has no "POSTREF SEGMENTS" line, and only one "PROCESS" line, then it is set up to integrate. It will produce a list of measured spot intensities in \$mtzout To convert from a refining script to an integrating script, delete the "POSTREF SEG" line, and make sure there is only one "PROCESS" line indicating all of the data in your wedge. See the mosflm manual for more details on how to edit and run mosflm scripts. ################################################################################ \$mergescript - semi-intelligent mergeing script reads: \$mtzout - an mtz of integrated spot intensity data makes: \$mergefile - an mtz of averaged structure factor data usage: \$mergescript [SG] [raw.mtz] [1.8A] [120aa] where: SG is the space group to apply in mergeing (default: \$SG) raw.mtz contains the (unmerged) data to merge (default: \$mtzout) 1.8A is the desired outer resolution limit (default: \$hires) 120aa is the number of amino acids in the asymmetric unit (for truncate) Example: \$mergescript \$SG raw.mtz 3A 100aa will scale and merge the data in raw.mtz out to to 3.0 A with the symmetry operators from \$SG, and run truncate with an ASU of 100aa. This script is meant to get you started with scaling and mergeing your data. Wedger Elves will examine the results of this script to see if scale smoothing might be appropriate, and will try to apply it if it is. If a space group is provided, the CCP4 program reindex will be applied to the raw data before scaling and mergeing. The outer resolution limit can also be specified on the command-line, as well as the number of amino acids residues in the asymmetric unit. This latter value is used by truncate to try to put the final structure factors on an absolute scale (electron units). It is not critical, but a good habit to get into. Although merge.com was meant for the raw data produced from the Wedger Elves scripts, it should be applicable to almost any unmerged mtz data. ################################################################################ autoscala - optimizer for SDCORR card reads: a scala script makes: a better scala script usage: autoscala script.com where: script.com is the scala script to optimize example: autoscala merge.com Scala's SDCORRECTION card allows the assigned error (sigma) of the spot intensities to be edited. Most measurement programs cannot predict the effects of absorption and other systematic measurement errors, and therefore usually give unrealisticially low estimates of the error in the measured spot intensities. You should read the scala documentation to find out exactly how SDCORR works. Briefly, "correct" sigmas should be similar to the scatter of observed intensities. That is, if the 10 observations of hkl=(5,9,12) deviate from the average value of (5,9,12) by 100 units (rms), then the sigma of (5,9,12) should be 100. So, if the assigned sigma is 50, then the scatter/sigma will be 2. This analysis, grouped by intensity bins, is the last graph in the scala logfile. You want all the points on this graph to be as close to 1.0 as possible. If you see this, then your assigned sigmas are probably realistic. To save you from hours of diddling with the SDCORR numbers, autoscala uses a "Golded-Section" search (derived from Numerical Recipies), to optimize the three numbers for scala's SDCORRECTION card, using the deviation of the aforementioned graph from 1.0 as a target. In CCP4 3.3 and beyond, the first number on the SDCORR card is optimized internally (and might as well be "1"), but the remaining two can be tuned up by autoscala. ################################################################################ SGsearch.com - exhaustive space-group search reads: a scala script makes: a table of mergeing statistics usage: SGsearch.com [script.com] [raw.mtz] [rootSGs] where: script.com is the scala script to use (default: merge.com) raw.mtz is the raw, unscaled data (default: raw.mtz) rootSGs is/are the "starting" space group (default: SG from raw.mtz) example: SGsearch.com merge.com P212121 will run merge.com with every orthorhombic space group: P222, P2221, (P2122, P2212), P21212, (P21221, P22121), and P212121 Picking the wrong space group has been known to waste weeks to years of an investigators time. SGsearch.com uses the space group provided to get the general crystal system your crystal was indexed with, and will then try mergeing your data in EVERY space group belonging to that crystal system. The Rmerge, systematic absences, and asymmetric unit volume will be presented in a neat table for your review. The actual logs from the individual merge.com runs will be placed in the ./logs/ directory, named merge.SG.log. If SGsearch.com finds these logs aready exist, it will use the statistics in them to make the table, this usually saves you a lot of time re-generating the table, and you can always delete these logs, and run SGsearch.com again. SGsearch.com is desiged to work with the merge.com provided by Wedger Elves, but should work fine with any scala/truncate script that is capable of accepting and applying a space group provided on its command line. ################################################################################ Patt.com - basic Patterson script reads: merged.mtz makes: Patt.map usage: Patt.com merged.mtz [merged2.mtz] where: merged.mtz is the merged mtz file (containing DANO or F) merged2.mtz is another merged mtz file (containing F) examples: Patt.com merged.mtz - will calculate a Patterson of DANO in merged.mtz Patt.com merged.mtz ../wedge2/merged.mtz - will calculate a Patterson of F-F between the two mtzs description: Patt.com will have to be edited for most customizations. All it really is is a basic framework for calculationg Pattersons. Data sets are expected to be named "DANO" or "F", and changing the resolution or difference cutoffs must be done by editing the top of the script. Patt.com exists for your convenience in calculating preliminary Pattersons as your data are being processed. ################################################################################ mtz2various.com - basic format-converter script reads: merged.mtz makes: outfile.EXT EXT -> FORMAT cif -> CIF hkl -> shelx tnt -> TNT fin -> XtalView phs -> XtalView fobs-> XPLOR cv -> XPLOR cns -> CNS usage: mtz2various.com merged.mtz outfile.EXT [format] where: merged.mtz is the merged mtz file (containing Fs) outfile.EXT is the filename you want to use for the exported data format is the (optional) program you want outfile.EXT formatted for examples: mtz2various.com merged.mtz merged.cif - will convert merged.mtz to CIF format mtz2various.com all.mtz "F1" merged.fobs - will convert "F1" in all.mtz to XPLOR format mtz2various.com merged.mtz merged.hkl shelx - will convert merged.mtz to shelx format mtz2various.com merged.mtz merged.hkl tnt - will convert merged.mtz to TNT format description: mtz2various.com is a general-purpose "smart" script for converting "F" data from an mtz file (such as merged.mtz) to other file formats for other non-CCP4 programs. The format of the output file can either be implied by using a standard file extension in the output file name, or declared explicitly and separately on the command line. Free-R flags are exported automatically, if they are present. In the case of XtalView files, a suitable CRYSTAL file is also generated. ################################################################################ autoindex.com - mosflm autoindexing script usage: ./autoindex.com The autoindex.com file was created for your convenience if you want to resort to manually tinkering with autoindexing in mosflm. It can also be edited (and renamed) to work as a script for a full mosflm run to integrate your data, or refine cell parameters. ################################################################################ strategy.com - mosflm strategy script usage: ./strategy.com The strategy.com file was created for your convenience if you want to resort to manually tinkering with STRATEGY in mosflm. Changing things like mosaicity, distance, and 2theta can all affect the results of the strategy calculation. You can also run STRATEGY interactively by editing strategy.com file. Just un-comment the "IMAGE" and "GO" lines, and run the script. ################################################################################ 3) Data files ################################################################################ best.mat - mosflm's crystal orientation matrix This file contains the orientation information (and cell dimensions) of your crystal. It is periodically updated by Wedger Elves, as the crystal orientation is refined. As long as you are working with the same crystal setting, you can point Wedger Elves to a copy of best.mat from another wedge instead of autoindexing again. best.mat holds regardless of phi, distance, 2theta, and other camera parameters. ################################################################################ raw.mtz - raw, unmerged intensity data This is a multirecord (unmerged) mtz file produced by the last "integration" run of \$scriptname it should contain the raw intensity measurements for all the spots in the processed wedge. This file is meant to go into scala, or Scaler Elves ################################################################################ merged.mtz - scaled and merged data from the wedge This is a "standard" mtz file containing F, SIGF, DANO, SIGDANO for the data measured in the wedge just processed by Wedger Elves. It is produced from raw.mtz by merge.com ################################################################################ rejected_spots.txt - list of spot observations rejected during scaling "Outlier" observations that did not agree with other symmetry-equivalent observations are listed here (by merge.com). However, this list is given in the context of the "other" observations. It is usually a good idea for you to visually inspect these rejected spots and make sure there really was something wrong with them (i.e. behind the beamstop shadow) The quickest way to do this is with Spotter Elves: Spotter logs/merge.log \$FirstImage ################################################################################ Patt.map - anomalous difference Patterson By default, Wedger Elves create a "standard" anomalous-difference Patterson map in Patt.map by running Patt.com (above). If you do not have access to a graphics program for viewing the map, logs/patt.log should contain a peak- pick of this map that you can review. ################################################################################ 4) What if something goes wrong? The Wedger elves have been trained to handle a number of common problems encountered in using mosflm. However, if something happens that is beyond their experience, it's up to you to figure it out. :( But, please email jamesh@ucxray6.berkeley.edu about your problem. The mosflm manual is available from: netscape ftp://ftp.mrc-lmb.cam.ac.uk/pub/mosflm/ 5) tips and tricks: If you search for the words "Ding" and "Dang" in Wedger Elves output, you can instantly see the rate at which mosflm runs have been sucessful or crashing. --- use the following awk program to average a bunch of numbers: --- uncommenting the following lines: #IMAGE blah blah blah #GO in mosflm.com will turn it into a fully-interactive mosflm script. You run it, and the mosflm graphics pops up, giving you interactive control. --- EOF-readme endif ############################################################################### # create \$scriptname script # ############################################################################### if(-e "\${scriptname}.older") mv \${scriptname}.older \${scriptname}.oldest if(-e "\${scriptname}.old") mv \${scriptname}.old \${scriptname}.older if(-e "\$scriptname") cp \$scriptname \${scriptname}.old # set up missetting angle reinput logic if(\$#missets != 3) set missets = \`nawk 'NR==4 && NF==3' \$inmatrix\` set MISSET = "MISSETS \$missets RESET" if(\$reinput_missets != yes) then # keep command for user's reference set MISSET = "#\$MISSET" else # consider "average" missets for "last" run to be 0 0 0 set missets = ( 0 0 0 ) endif # # make printing decisions now set print_swing = "" set print_cell = "" set temp = \`echo "\$two_theta" | nawk '{printf "%d", \$1*100}'\` if("\$temp" != "0") set print_swing = "SWUNG_OUT " if(\$#CELL == 6) set print_cell = "CELL \$CELL" set integ = "END" if(\$integrate == yes) set integ = "" #set END = "" #if(\$integrate == no) set END = "END" set mosflmSG = \$SG if(! \$?PG) set PG = \`nawk -v SG=\$SG '\$4==SG{print \$5}' \$CLIBD/symop.lib\` if("\$PG" == "PG222" && "\$SG" =~ P*) set mosflmSG = P222 if("\$SG" =~ R* || "\$SG" =~ H*) set mosflmSG = \$SG_number set ESTIMATING = "" if("\$res_choice" == "auto") then # need a better estimate of resolution # should do this before or after estimating resolution? set ESTIMATING = resolution endif if("\$mosaic" == "estimate") then # just going to run mosaic estimation set ESTIMATING = "mosaic spread" endif set print_overload = "OVERLOAD CUTOFF \$OVERLOAD" set test = \`echo \$OVERLOAD | nawk '{print (\$1+0<1000)}'\` if(\$test) then set print_overload = "" endif set print_gain = "GAIN \$GAIN" set test = \`echo \$GAIN | nawk '{print (\$1+0<=0)}'\` if(\$test) then set print_gain = "" endif set EXTENSION if("\$ext" != "") set EXTENSION = "EXTENSION" set mosflm_temp = mosflm_temp if(\$?CCP4_SCR) then if(-e "\$CCP4_SCR") set mosflm_temp = '\${CCP4_SCR}/mosflm_temp\$\$' endif cat << eof-topscript >! \$scriptname #! /bin/csh -f # # Wedger Elves automatically generated mosflm script # # # option to integrate after refining set integ = "\$integ" if("\\\$1" =~ integ*) set integ = "" # # temporary file prefix set tempfile = \$mosflm_temp set outfile = \$mtzout # # \${MOSFLM} HKLOUT \\\${tempfile}.mtz \\ SPOTOD \\\${tempfile}.spotod \\ SUMMARY \${logfile}mosflm.xlog \\ COORDS \\\${tempfile}.coords << eof-ipmosflm # TITLE Raw data wedge from \${template} \$first to \$last at lambda= \$wavelength # GENFILE \\\${tempfile}.gen # # the following keywords were not understood by Wedger Elves, but passed on # because they resemble mosflm commands. # ---- \`echo "\$PREAMBLE" | nawk 'BEGIN{RS="n"} {print}'\` # ---- # Detector parameters (range, quantum gain, etc.) \$SCANNER \$print_overload \$print_gain \$LIMITS # Beam parameters (i.e. (delta-lambda)/lambda, H,V divervence in degrees) WAVELENGTH \$wavelength DISPERSION \$DISPERSION DIVERGENCE \$DIVERGENCE POLARISATION \$POLARISATION # Alignment parameters DISTANCE \$distance BEAM \${print_swing}\$beam_center TWOTHETA \$two_theta MATRIX \$inmatrix \$MISSET NEWMATRIX \${outmatrix} # Crystal parameters \${print_cell} SYMMETRY \$mosflmSG RESOLUTION \$hires MOSAIC \$mosaic # Frame filename breakdown DIRECTORY \$framedir IDENTIFIER \$frameprefix \$EXTENSION \$ext \$TEMPLATE # # To run mosflm interactively, # uncomment the following lines (and DON'T redirect output) #IMAGE \$first_frame PHI \$phi0 TO \$end_phi #GO #END \$Interactive # eof-topscript unset print_swing unset print_cell if("\$mosaic" == "estimate") then # must ALWAYS have a IMAGE to estimate resolution from cp \$scriptname \$tempfile echo "IMAGE \$first_frame" >> \$scriptname echo "go" >> \$scriptname echo "end" >> \$scriptname endif echo "\$EXTRA_REFINE_CARDS" | nawk 'BEGIN{RS="n"} {print}' | nawk 'NF!=0' >> \$scriptname echo "REFI RESID 100" >> \$scriptname ############################################################################### # prepare to integrate or postrefine # command cards will be placed in \$scriptname ############################################################################### if(\$fixcell == yes) echo "POSTREF FIX ALL" >> \$scriptname if(\$fixmosaicity == yes) echo "POSTREF BEAM 0" >> \$scriptname if(\$fixyscale == yes) echo "REFINE FIX YSCALE" >> \$scriptname #if(\$usebeam == yes) echo "POSTREF USEBEAM" >> \$scriptname echo "# Processing commands: " >> \$scriptname ############################################################################### # set up cards to refine and integrate # ############################################################################### if(\$postref == no) echo "POSTREF OFF" >> \$scriptname if("\$ESTIMATING" == "resolution") then # set up one-frame integration, but # don't do anything that might hang us up set integrate = yes cat << EOF-res_est >> \$scriptname POSTREF OFF # skip next line PROFILES NOOPTIMIZE PROCESS \$first to \$first START \${phi0} ANGLE \${osc} ADD \${add} go end EOF-res_est endif if(\$integrate == no) then ############################################################################### # create POSTREF segments commands # ############################################################################### echo "POSTREF SEGMENTS \$mosflm_postref_segs" >> \$scriptname set number = \$first set i = 1 @ frames_per_run = ( \$last - \$first ) while( \$i <= \$mosflm_postref_segs ) @ segend = ( \$number + \$frames_per_segment - 1 ) if(\$segend > \$last) set segend = \$last #set phi = \`echo "(( \$number - \$first ) * \$osc) + \$phi0" | bc\` set phi = \`echo "\$number \$first \$osc \$phi0" | nawk '{print (( \$1 - \$2 ) * \$3) + \$4}'\` echo "PROCESS \$number TO \$segend START \$phi ANGLE \$osc ADD \${add}" >> \$scriptname echo "go" >> \$scriptname @ temp = (\$mosflm_postref_segs - 1 ) if(\$temp == 0) set temp = 1 @ temp = ( (\$frames_per_run - \$frames_per_segment ) / \$temp ) @ number = ( \$number + \$temp ) @ i = (\$i + 1); # make sure last segment ends with last frame if(\$i == \$mosflm_postref_segs) then set segend = \$last @ number = ( \$segend - \$frames_per_segment - 1 ) endif end cat << EOF-option >> \$scriptname # to perform full integration, either put the word "integ" on the command line, # or remove the text on the next line: \\\$integ EOF-option endif # now put in full integration card (wether we intend to use it or not) if(! \$?BLOCK) set BLOCK = \`echo \$first \$last \$osc | awk '{print "BLOCK",int(45/\$3)}'\` cat << eof-endscript >> \$scriptname PROCESS \${first} to \${last} START \${phi0} ANGLE \${osc} ADD \${add} \$BLOCK GO END eof-ipmosflm set mosflm_status = \\\$status # update mtz only after run is finished if((! \\\$mosflm_status)&&(-e \\\${tempfile}.mtz)&&("\\\$integ" == "")) then mv \\\${tempfile}.mtz \\\${outfile} endif # Life's messy, clean it up. rm -f \\\${tempfile}.spotod >& /dev/null rm -f \\\${tempfile}.coord >& /dev/null rm -f \\\${tempfile}.gen >& /dev/null rm -f \\\${tempfile}.mtz >& /dev/null ls fort* >& /dev/null if(! \\\$status) rm -f fort* exit \\\$mosflm_status eof-endscript chmod a+x \$scriptname if(\$?NORUN) then echo "\$scriptname is ready..." if(! -e "\$inmatrix") then echo "Make sure you have a good \$inmatrix before you run \$scriptname " echo "" endif goto Cleanup endif RunMOSFLM: ############################################################################### ##### # # # # # # #### #### ###### # # # # # # # ## # ## ## # # # # # ## ## # # # # # # # # ## # # # #### ##### # # ## # ##### # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # # #### # # # # #### #### # ###### # # ############################################################################### # run MOSFLM # ############################################################################### if("\$ESTIMATING" != "") then echo "estimating \${ESTIMATING}..." else if(\$integrate == yes) then echo "Integrating..." else echo "Refining..." endif endif if("\$Interactive" == "PLOT") then set temp = "Yes" cat << EOF Mosflm's output will now be dumped onto your screen When the window comes up, you will probably want to: Turn Prompts "off" (lower left corner) Turn Timeout mode "on" (lower left corner) Hit "Continue" ( 5th button down ) Okay? [\$temp] EOF # make user confirm having read this echo -n "\$BELL" echo -n "\$PROMPT" set in = ( \$< ) if("\$in" != "") set temp = "\$in" if((\$#temp > 1)||("\$temp" !~ [Yy]*)) then set input = "\$temp" if("\$input" =~ [Nn][Oo]) set input = "" goto Questionaire endif else echo You can watch the full output in \`pwd\`/\${logfile}mosflm.log endif echo "" if(\$?DEBUG) then echo "DEBUGGING: STATUS? " set mosflm_status = "\$<" cp \$inmatrix \$outmatrix goto check endif # check, and backup old logfiles (if they have interesting stuff in them) if(-e "\${logfile}mosflm.log" ) then set temp = \`head -10000 \${logfile}mosflm.log | grep -c "Processing Image"\` if("\$temp" > 2) mv \${logfile}mosflm.log \${logfile}mosflm.log.old endif if(-e "\${logfile}mosflm.xlog" ) then set temp = \`grep -c "GRAPHS" \${logfile}mosflm.xlog\` if("\$temp" == 1) mv \${logfile}mosflm.xlog \${logfile}mosflm.xlog.old if("\$temp" > 1) mv \${logfile}mosflm.xlog \${logfile}mosflm.xlog.lastinteg endif if(-e "\${logfile}mosflm.html" ) then set temp = \`grep -c "GRAPHS" \${logfile}mosflm.html\` if("\$temp" == 1) mv \${logfile}mosflm.html \${logfile}mosflm.old.html if("\$temp" > 1) mv \${logfile}mosflm.html \${logfile}mosflm.lastinteg.html endif # keep track of how many times we have done this @ Cycle = ( \$Cycle + 1 ) # here is where we actually launch MOSFLM if("\$Interactive" == "PLOT") then ./\$scriptname \$integ set mosflm_status = \$status mv mosflm.lp \${logfile}mosflm.log else # unwrap the logfile sumarizer cat << EOF-logsum >! \${tempfile}logsum.awk #! \$nawk -f # # # Displays a (running) summary of a mosflm log file # # # BEGIN{ print " spot-prd |xtal slip around|" print "frame residual ovlap mosaic dist beam \\\\"Y\\\\" phi unit cell" } /Processing Image/{ if(overloads+0 > 0) { # printf " %4d overloads\\\\n", overloads # overloads = 0; } if(frame != "") { printf "%4d %5s mm %5s %5s %6s%21s %s\\\\n", frame, resid, overlaps, mos, dist, missets, cell; } frame = \\\$3; mos = " n/d"; dist = " n/d"; cell = " n/d"; misset = " ?? ?? ?? " # overloads = 0 overlaps = " ?" } /Final rms residual:/{ resid = sprintf("%5.2f", \\\$4+0); } / XTOFD /{ getline; dist = sprintf("%5.1f", \\\$4); } /Real cell parameters\\\$/{ getline; cell = \\\$1 " " \\\$2 " " \\\$3 " " \\\$4+0 " " \\\$5+0 " " \\\$6+0; } /Mosaic spread/{ getline; if(\\\$1=="New") mos = sprintf("%5.2f", \\\$NF); } /Refined Orientation Angles/{ getline; getline; missets = sprintf("%7.2f%7.2f%7.2f", \\\$1, \\\$2, \\\$3); } / are OVERLOADS/ && \\\$5 !~ /[^0-9]/{ overloads += \\\$5; } / Reflections generated/ && \\\$1 !~ /[^0-9]/{ total_spots = \\\$1+0; } / Overlapped reflections/ && \\\$1 !~ /[^0-9]/{ overlaps = sprintf("%4d", \\\$1); if(total_spots > 0) overlaps = sprintf("%3d%%", 100*overlaps/total_spots); } END{ if(frame != "") { printf "%4d %5s mm %5s %5s %6s%21s %s\\\\n", frame, resid, overlaps, mos, dist, missets, cell; printf " %4d overloads (total)\\\\n", overloads } } EOF-logsum # catch Ctrl-C set input = "" if(! \$?AUTO) onintr Questionaire ./\$scriptname \$integ | head -1000000 | tee \${logfile}mosflm.log | nawk -f \${tempfile}logsum.awk set mosflm_status = \$status rm -f \${tempfile}logsum.awk if(! \$?CATCH_USER) onintr endif # check: ############################################################################### #### # # ###### #### # # ##### ###### #### # # # ##### #### # # # # # # # # # # # # # # # # # # # ###### ##### # #### # # ##### #### # # # # #### # # # # # # # ##### # # # # # # # # # # # # # # # # # # # # # # # # # # # #### # # ###### #### # # # # ###### #### #### ###### # #### ############################################################################### # check, and sumarize mosflm results # ############################################################################### if(! \$mosflm_status) then # mosflm says everything is okay, but let's check anyway... # jump ahead if all we did was estimate mosaicity if("\$mosaic" == "estimate") then set lastlog = "\${logfile}mosflm.log" set sources = "\$lastlog" goto GetParamsFromSources endif # jump ahead if all we did was estimate resolution if("\$ESTIMATING" == "resolution") then set lastlog = "\${logfile}mosflm.log" set sources = "\$lastlog" set res_choice = "estimating" goto GetParamsFromSources endif ###################################### # Print out Refinement Residual info # ###################################### cat \${logfile}mosflm.log |\\ nawk '/Processing Image/{frame=\$3} \\ /Weighted residual/{resid[frame] = \$4+0 " " \$NF} \\ END{for(frame in resid) print resid[frame]}' |\\ nawk 'BEGIN{minR=9} NF==2{++n\\ if(\$1maxWR){maxWR=\$2} avgWR+=\$2;} \\ END{if(n) printf "%.2f %.2f %.2f %.3f", avgWR/n, maxWR, avgR/n, minR}' |\\ cat >! \$tempfile set resid = \`cat \$tempfile\` rm -f \$tempfile >& /dev/null if(\$#resid == 4) then # echo "Average Weighted Residual = \$resid[1] (should be ~ 1)" # echo "Maximum Weighted Residual = \$resid[2] (should be < 5)" # echo "RMSD of Spot Predictions = \$resid[3] mm (pixel = \$PIXEL mm)" # echo "Spots are \$resid[3] mm (rms) from their predictions." # echo "(pixel is \$PIXEL mm)" echo " (rms) \$resid[3] mm between spots and their predictions." set temp = \`echo \$PIXEL | nawk '{printf "%.2f", \$1}'\` echo " (with \$temp mm pixels)" # evaluate best positional residual (> 2.0 pixels is unacceptable) set temp = \`echo \$resid[4] \$PIXEL | nawk '{printf "%d", \$1/(2.0*\$2)}'\` if("\$temp" > 0) then # even the best frame is pretty far off set mosflm_status = "bad_preds" endif else echo "could not read spot residuals! " # something is probably wrong! set mosflm_status = "no_WR" endif # summarize rejected spots in moviefy format set filepattern = \`cd \$framedir ; pwd\`"/"\`echo "\$template" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}'\` cat \${logfile}mosflm.log |\\ nawk -v filepattern=\$filepattern '\\ # get image batch number, convert to full filename \\ /Integrating Image/{file=sprintf(filepattern, \$3);\\ nf=split(file,w,"/");base=w[nf];}\\ # detect "BADSPOTS" list \\ /H K L/{badspot=1} /Calculated detector/{badspot=0}\\ /Spots measured on this image/{badspot=0}\\ /SERIOUS ERROR/{serious=1} NF==0{serious=0}\\ # reformat "bad" spot entry \\ badspot && \$1 ~ /^[0-9-]/ && \$NF !~ /[0-9]/{\\ print file, "-center", substr(\$0, 34, 6), substr(\$0, 40, 6), \\ "-label", substr(\$0, 1, 13), "on", base, substr(\$0, 99)} \\ # reformat "serious" error entry \\ serious && /Pixel coordinates are/{X=\$5;Y=\$7} \\ serious && \$1 == "h,k,l"{HKL=substr(\$0,7,12); \\ print file, "-center", X, Y, "-label", HKL, "on", base, "SERIOUS ERROR"}' |\\ cat >! \${logfile}rejects.moviekey echo "" if(\$integrate == no) then ################################## # check Postref results # ################################## if(! -e "\${outmatrix}") then echo "Dang! \${outmatrix} was not generated." nawk '/ERROR/{print; getline; print; getline; print; getline; print}' \${logfile}mosflm.log echo " Mosflm died for some reason:" echo " To find out more: more \${logfile}mosflm.log" set mosflm_status = "no_matrix" endif else ################################## # check Integration results # ################################## if(-e "\${mtzout}") then if(\$?NO_CCP4) then echo "Unable to check \${mtzout} because CCP4 is not installed." else ############################## # check the output mtz file. # ############################## echo "go" | mtzdump hklin \${mtzout} >! \$tempfile.mtzdump set SGnum = \`nawk '/Space group/{print \$NF+0}' \$tempfile.mtzdump\` set temp = \`grep "Number of Batches" \$tempfile.mtzdump\` set temp = \$temp[\$#temp] if(\$temp == "") then echo "Dang! \${mtzout} seems to be corrupted." nawk '/ERROR/{print; getline; print; getline; print; getline; print}' \${logfile}mosflm.log grep "ERROR" \$tempfile.mtzdump echo " Integration didn't work: more \${logfile}mosflm.log" set mosflm_status = "bad_mtz" else # mtzout could be read... if(\$temp != ((\$last - \$first) + 1)) then echo "Dang! \${mtzout} does not contain all frames." nawk '/ERROR/{print; getline; print; getline; print; getline; print}' \${logfile}mosflm.log grep "ERROR" \$tempfile.mtzdump echo " Mosflm probably choked on one frame. more \${logfile}mosflm.log" set mosflm_status = "short_mtz" else # mtzout seems to be okay... set mtz_res = \`nawk '/Resolution Range/{getline;getline;print \$6}' \${tempfile}.mtzdump\` set mtz_res = \`echo \$mtz_res 1.05 | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\` endif endif rm -f \${tempfile}.mtzdump >& /dev/null endif else echo "Dang! \${mtzout} was not generated." grep ERROR \${logfile}mosflm.log echo " Mosflm must have died. Check \${logfile}mosflm.log" set mosflm_status = "no_mtz" endif # check out the mtz if(-e "\$mtzout" && "\$mosflm_status" == "0" && ! \$?NO_CCP4) then # check and see if high resolution limit is beyond detector edge set test = \`echo "\$mtz_res \$hires" | nawk 'NF==2{print (\$1 > \$2)}'\` if("\$test" == "1") then # we asked for a higher resolution than we got # must just be the edge of the detector is the limit echo "detector face only goes to \$mtz_res \${ANG}" set detector_res_limit = \$mtz_res set hires = \$mtz_res endif # measure completeness (now that we finally can) sortmtz hklin \$mtzout hklout \${tempfile}.sorted.mtz << EOF >& /dev/null \${VRSET}VRSET -9e+38 H K L M/ISYM BATCH EOF scala hklin \${tempfile}.sorted.mtz hklout \${tempfile}.merged.mtz << EOF-merge >& /dev/null nodump analyse noplot onlymerge EOF-merge if(! \$?SGnum) set SGnum = "\$SG_number" unique hklout \${tempfile}.unique.mtz << EOF-unique >& /dev/null SYMM \$SGnum CELL \$CELL RESOLUTION \$hires LABOUT F=IMEAN SIGF=SIGIMEAN EOF-unique mtzutils hklin1 \${tempfile}.merged.mtz \\ hklin2 \${tempfile}.unique.mtz \\ hklout \${tempfile}.complete.mtz << EOF-util >& /dev/null UNIQUE RUN EOF-util echo "stats nbin 100" |\\ mtzdump HKLIN \${tempfile}.complete.mtz |&\\ nawk '/PARTIAL FILE STATISTICS/,/No. of reflections/' |\\ nawk '\$1==4 && NF>3{res=\$(NF-2)+0; if(substr(\$0,28)+0!=0)miss+=substr(\$0,20)}\\ /partial statistics for resolution bin/{sum+=\$NF; \\ print res,100*(sum-miss)/sum}' |\\ sort -n |\\ nawk -v ANG="\$ANG" 'NR==1 || \$2>90{\\ printf " %.1f%% complete to %.2f %s\\n",\$2,\$1,ANG}\\ \$2>90{exit}' rm -f \${tempfile}.unique.mtz \${tempfile}.complete.mtz >& /dev/null rm -f \${tempfile}.merged.mtz \${tempfile}.sorted.mtz >& /dev/null rm -f \${tempfile}mtzstats >& /dev/null rm -f ANOMPLOT NORMPLOT ROGUES >& /dev/null echo "" endif # figure out effective outer resolution limit from mosflm log. cat \${logfile}mosflm.log |\\ nawk 'h==0 && /Analysis as a function of resolution./{h=1;getline;\\ print \$3, \$4, \$5, \$6, \$7, \$8, \$9, \$10} \\ /^ /{print \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9}' |\\ nawk 'NR==1{for(i=1;i<9;++i){res[i]=\$i};++n} \\ NR!=1{for(i=1;i<9;++i){signal[i]+=\$i;++count[i]}}\\ END{if(n) for(i=8;i>0;--i){print res[i], signal[i]/count[i]}}' |\\ sort -nr >! \${tempfile}res_limit set res_limit = \`nawk '\$NF > 0.0 {print \$1+0} \$NF<=0 {exit}' \${tempfile}res_limit | tail -1\` rm -f \${tempfile}res_limit >& /dev/null if("\$res_limit" == "") then # assume top bin still has spots? set res_limit = "\$hires" endif endif ################################################################################### # # Convergence Criteria: # missets average < 0.03 deg (rms) # mosaicity changes < 0.03 deg # distance changes < 0.1% # cell changes < 0.1% # # Convergence during integration (with maximally free cell) exits. # ################################################################################### if(\$postref == yes) then # read refined parameters here (to check convergence) # average missetting angles (should, eventually, tend toward zero) echo -n "orientation " # compute average misorientation angles (in degrees) cat \${logfile}mosflm.log |\\ nawk '/Processing Image/{f=\$3} \\ /Refined Orientation Angles/{getline; getline; Cx[f]=\$1; Cy[f]=\$2; Cz[f]=\$3} \\ END {n=0; for(f in Cx){++n;} \\ for(f in Cx){CX+=Cx[f]/n; CY+=Cy[f]/n; CZ+=Cz[f]/n; }; \\ printf "%12.6f %12.6f %12.6f", CX, CY, CZ }' >! \$tempfile set new_missets = \`cat \$tempfile\` rm -f \$tempfile >& /dev/null # retrieve missets for FIRST image in run #set new_missets = \`nawk '/Refined Orientation Angles/{getline; getline; missets=\$0} /Processing Image/ && missets!=""{print missets; exit}' \${logfile}mosflm.log\` if(\$#new_missets == 3) then # compute RMS shift from starting orientation # compute change in orientation from from previous values set Delta_orient = \`echo \$new_missets \$missets | nawk '{printf "%.3f", sqrt((((\$1-\$4)^2)+((\$2-\$5)^2)+((\$3-\$6)^2))/3)}'\` if("\$Delta_orient" != "0.000") then echo "changed \${Delta_orient}\$DEG" else echo "unchanged." endif # compute "shift" in missetting angles since last run set shift_orient = \`echo \$Delta_orient 0.03 | nawk '{printf "%d", \$1/\$2}'\` else echo "unreadable! " set mosflm_status = "no_missets" endif # these "new" missets will be "previous missets" for the next run set missets = ( \$new_missets ) # new mosaicity echo -n "mosaicity " # check mosaicity # flailing refinement will give REALLY small mosaicities cat \${logfile}mosflm.log |\\ nawk '/Mosaic spread/{getline;if(\$1 == "New"){\\ if(\$NF < 0.01){print \$NF}}}' | sort -n >! \$tempfile set temp = \`cat \$tempfile | head -1\` rm -f \$tempfile if("\$temp" != "") then echo "negative! \$temp" # set mosflm_status = "bad_mosaic" else # get mosaicity cat \${logfile}mosflm.log |\\ nawk '/Mosaic spread/{getline; if(\$1 == "New"){print \$NF}}' |\\ nawk '{avg += \$1; ++n;v[n]=\$1} \\ max+0<\$1 {sec=max; max = \$1}\\ END{if(n){avg/=n;\\ for(i=1;i<=n;++i){ms += (v[i]-=avg)^2};\\ print avg, sqrt(ms/n), max, sec}}' |\\ cat >! \$tempfile ######## # average ######## set new_mosaic = \`nawk '{print \$1}' \$tempfile\` # average + 1sd set new_mosaic = \`nawk '{print \$1+\$2}' \$tempfile\` ######## # largest (refined value) ######## set new_mosaic = \`nawk '{print \$3}' \$tempfile\` ######## # 2nd largest ######## set new_mosaic = \`nawk '{print \$NF}' \$tempfile\` if(\$#new_mosaic == 1) then # determine change in mosaicity set Delta_mosaic = \`echo \$new_mosaic \$mosaic | nawk '{printf "%.3f", sqrt((\$1-\$2)^2)}'\` if("\$Delta_mosaic" != "0.000") then echo "changed \${Delta_mosaic}\$DEG" else echo "unchanged." endif # now check for oscillating refinement if(! \$?mosaic_history) set mosaic_history = "" set mosaic_history = \`echo " \$mosaic \$mosaic_history " | nawk 'BEGIN{RS=" "} NF==1{++n} n<7'\` set Delta_mosaic = \`echo \$Delta_mosaic \$new_mosaic \$mosaic_history | nawk '{print \$1; for(i=5;i<=NF;++i) printf "%.3f\\n", sqrt((\$2-\$i)^2)}' | sort -n | head -1\` # compute "shift" in mosaicity (integer) set shift_mosaic = \`echo \$Delta_mosaic 0.03 | nawk '{printf "%d", \$1/\$2}'\` else echo "unreadable! " #if("\$fixmosaicity" != "yes") set mosflm_status = "no_mosaic" set shift_mosaic = 0 endif endif # average cell (if it were possible to refine it) echo -n "unit cell " if(\$fixcell == no) then # unit cell was refined, see how much it changed if(\$integrate == yes) then # cell is in the logfile cat \${logfile}mosflm.log |\\ nawk '/Processing Image/{print gather} \\ /^ Real cell parameters/{getline; gather = \$0} \\ END{print gather}' | \\ nawk 'NF==6{++n; a+=\$1; b+=\$2; c+=\$3; \\ al+=\$4; be+=\$5; ga+=\$6} \\ END{if(n) print a/n, b/n, c/n, al/n, be/n, ga/n}' >! \$tempfile set Delta_cell = \`head -1 \$tempfile\` rm -f \$tempfile >& /dev/null else # cell is in the new matrix set Delta_cell = \`nawk 'NF == 6' \$outmatrix |& nawk '{for(i=1;i<=NF;++i) if(\$i+0 > 10) printf \$i+0 " "}'\` endif # compute %RMS shift of cell parameters if((\$#Delta_cell == 6)&&(\$#CELL == 6)) then set temp = 0 foreach i ( 1 2 3 4 5 6 ) set temp = \`echo \$Delta_cell[\$i] \$CELL[\$i] \$temp | nawk '{print ((\$1-\$2)/\$2)^2 +\$3}'\` end set Delta_cell = \`echo \$temp | nawk '{printf "%.2f", sqrt(\$1)}'\` if("\$Delta_cell" != "0.00") then echo "changed \${Delta_cell}%" else echo "unchanged." endif # compute "shift" in cell set shift_cell = \`echo \$Delta_cell 0.1 | nawk '{printf "%d", \$1/\$2}'\` else echo "unreadable! " set mosflm_status = "no_cell" endif else # cell was not refined echo "n/d" set Delta_cell = 0.00 set shift_cell = 0 endif else # converge if we weren't even refining? set shift_orient = 0 set shift_mosaic = 0 set shift_cell = 0 endif # average distance echo -n "distance " cat \${logfile}mosflm.log |\\ nawk '/Processing Image/{print gather} \\ /XTOFD/{getline; gather = \$0} END{print gather}' |\\ nawk 'NF>6{++i; dist+=\$4} END{if(i) print dist/i}' >! \$tempfile set temp = \`cat \$tempfile\` rm -f \$tempfile >& /dev/null if("\$temp" =~ [1-9]*) then # compute "shift" in distance set Delta_distance = \`echo \$temp \$distance | nawk '{printf "%.2f", sqrt(((\$1-\$2)/\$2)^2)*100}'\` if("\$Delta_distance" != "0.00") then echo "changed \${Delta_distance}%" else echo "unchanged." endif # add shift in distance to total shift set shift_distance = \`echo \$Delta_distance 0.1 | nawk '{printf "%d", \$1/\$2}'\` else echo "unreadable! " set mosflm_status = "no_distance" endif echo "" # ignore change in mosaicity if it's supposed to be fixed if("\$fixmosaicity" == "yes") set shift_mosaic = 0 # sum of all shifts (to decide when it has settled) @ shift = ( \$shift_orient + \$shift_mosaic + \$shift_cell + \$shift_distance ) # ignore orientation drift if it is misbehaving if(\$?ignore_missets) then # orientation shift doesn't really matter anyway, as long as we # keep reinputing it. @ shift = ( \$shift_mosaic + \$shift_cell + \$shift_distance ) endif else # error condition directly from mosflm echo "ERROR from MOSFLM (" \$mosflm_status ")" # print error messages in file (discarding repeats) cat \${logfile}mosflm.log |\\ nawk '/ERROR/{print; getline; print; getline; print; getline; print}' |\\ nawk '{p=1;for(i in m){if(m[i]==\$0){p=0}}; if(p==1){++n;m[n]=\$0;print}}' endif ############################################################################### #### #### # # ##### # # # #### ###### # # #### # # # # ## # # # ## # # # # ## # # # # # # # # # # # # # # # ##### # # # # # # # # # # # # # # # # ### # # # # # # # # # # ## # # # ## # # # # ## # # #### #### # # # # # # #### ###### # # #### ############################################################################### # Various "contingency plans" for known problems ############################################################################### grep "QOPEN failed - no streams left" \${logfile}mosflm.log >& /dev/null if(! \$status) then # this always happens with buggy mosflm echo "detected bug in mosflm 6.2.3 ... compensating." # set input = "NUSPOT OFF" # goto Questionaire set PREAMBLE = "\${PREAMBLE}nNUSPOT OFF" set mosflm_status = "bugfix" set recommendation = "use keyword NUSPOT OFF" goto Suggest endif grep "DOES NOT EXIST" \${logfile}mosflm.log | grep "Image FILE " >& /dev/null if(! \$status) then # this happens when the specified number of images is wrong # set last = \`nawk '/Processing Image /{print \$3}' \${logfile}mosflm.log | tail -1\` # set LastImage = \`nawk '/Image FILE / && /DOES NOT EXIST/{print \$3}' \${logfile}mosflm.log | tail -1\` ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` if("\$last" =~ [0-9]*) then @ number_of_frames = (( \$last - \$first ) + 1 ) echo "you lied to me.." set recommendation = "use image \$last as the end of the wedge" goto Suggest endif endif # catch explicit kill if((("\$mosflm_status" == "1")||("\$mosflm_status" == "141"))&&(! \$?AUTO)) then # no need for darastic action if(\$?DISPLAY && "\$Interactive" == "PLOT") then set temp = "\$DISPLAY" else set temp = \`whoami\` endif echo "killed by \$temp..." set mosflm_status = "killed" set input = "" goto Questionaire endif if(\$mosflm_status =~ [a-z]*) then # Elves detected a problem (mosflm exited with a 0) endif # do some reading/interpretation of error messages? grep "BGSIG too large" \${logfile}mosflm.xlog >& /dev/null if(! \$status) then # this usually happens when the resolution is too ambitious echo "resolution is probably too ambitious." endif if("\$mosflm_status" != 0) then # unset LAST_RUN endif # ############################################################ # sumarize Refinement results (regardless of success) # ############################################################ if((-e \${logfile}mosflm.xlog)) then # replot refinement stuff echo ' \$TABLE: Elven plots:' >> \${logfile}mosflm.xlog echo ' \$GRAPHS:Unit Cell (deviation):A:1,2,3,4,5,6,7:' >> \${logfile}mosflm.xlog echo ':Crystal Orientation (deviation):A:1,8,9,10:' >> \${logfile}mosflm.xlog echo ':Detector Orientation (deviation):A:1,11,12,13:' >> \${logfile}mosflm.xlog echo ':Beam Center (deviation):A:1,14,15:' >> \${logfile}mosflm.xlog echo ':Distance:A:1,16:' >> \${logfile}mosflm.xlog echo ':X-Y Scale:A:1,17: \$\$' >> \${logfile}mosflm.xlog echo 'Frame A B C alpha beta gamma around_x-ray_beam around_axis_phi-X-beam around_phi_axis aournd_beam aournd_horiz aournd_vert x_beam y_beam distance x-y_scale \$\$' >> \${logfile}mosflm.xlog echo ' \$\$' >> \${logfile}mosflm.xlog cat \${logfile}mosflm.log |\\ nawk '/Processing Image/{f=\$3} \\ /^ Real cell parameters/{getline; a[f]=\$1; b[f]=\$2; c[f]=\$3; al[f]=\$4; be[f]=\$5; ga[f]=\$6 } \\ /Refined Orientation Angles/{getline; getline; Cx[f]=\$1; Cy[f]=\$2; Cz[f]=\$3} \\ /CCOM:/{Dx[f]=\$NF} \\ /XCEN YCEN/{getline; Bx[f]=\$1; By[f]=\$2; xtf[f]=\$4; Sy[f]=\$5; Dh[f]=\$6/100; Dv[f]=\$7/100} \\ END {n=0; for(f in a){++n;} \\ for(f in a){A+=a[f]/n; B+=b[f]/n; C+=c[f]/n; Al+=al[f]/n; Be+=be[f]/n; Ga+=ga[f]/n}; \\ for(f in a){CX+=Cx[f]/n; CY+=Cy[f]/n; CZ+=Cz[f]/n; DX+=Dx[f]/n; DH+=Dh[f]/n; DV+=Dv[f]/n; }; \\ for(f in a){BX+=Bx[f]/n; BY+=By[f]/n}; \\ for(f in a){printf "%3d %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f\\n",\\ f, a[f]-A, b[f]-B, c[f]-C, al[f]-Al, be[f]-Be, ga[f]-Ga,\\ Cx[f]-CX, Cy[f]-CY, Cz[f]-CZ, Dx[f]-DX, Dh[f]-DH, Dv[f]-DV, Bx[f]-BX, By[f]-BY, xtf[f], Sy[f]} }' |\\ sort -n >> \${logfile}mosflm.xlog echo ' \$\$' >> \${logfile}mosflm.xlog # extend to CCP4 4.x Java plot HTML format cat << EOF-javacise >! \${tempfile}javacize #! \$nawk -f # # convert "ordinary" xloggraph input to CCP4 4.x Java graphs # # BEGIN{ if(! CBIN) CBIN = ENVIRON["CBIN"] print "
"
}

//{already_html=1}
already_html==1{print; next}

\\\$1 ~ /^\\\\\\\$TABLE/{
    line=\\\$0; \\\$1= ""; print; \\\$0=line;
    print "For inline graphs use a Java browser";
}

END{print "
"} EOF-javacise # add the HTML tags in the appropriate places nawk -f \${tempfile}javacize \${logfile}mosflm.xlog >! \${logfile}mosflm.html # clean up rm -f \${tempfile}javacize >& /dev/null endif # # use bell to signal completion if(! \$?AUTO) echo -n "\$BELL" echo "" Auto_Step: ############################################################################### ## # # ## # # # ###### ###### # # ## # # # # # # # # # # # # # # # # # # ##### ###### # # # ###### # # # # # # # ## # # # # # # # # # # # # ###### # ###### ###### #### # # ##### ##### # # ##### # # # # # # # # # # # # # # # # # # # # # # # # # ##### # # # # # # # # # # # # #### #### # # #### # ############################################################################### # finally, decide what to do next # # The following procedure defines the "go auto" protocol of refinement # We have tried to make it as universal a procedure as possible, but # it still has a lot of shortcomings. # As always, the best advise is to know what you are doing and program # your own procedure in a batch file, like this: # Wedger -1 refine fixcell >! Wedger.log # Wedger -1 refine no fixcell >> Wedger.log # Wedger -1 integrate fixcell >> Wedger.log # etc. # # notes to self: # with: we get new: # integ nopostref nousebeam dist beam # integ nopostref usebeam dist beam # integ postref nousebeam dist beam mosaic GAIN # integ postref usebeam dist beam mosaic GAIN # nointeg postref nousebeam dist beam mosaic # nointeg postref usebeam dist beam mosaic # # ############################################################################### if(! \$?recommendation) set recommendation # never "finish" with an emergency-low resolution if("\$res_choice" == "backoff") unset LAST_RUN if("\$mosflm_status" == 0) then # Celebrate! echo -n "Ding! " if(\$integrate == yes) then else endif # no errors occured, increase the degrees of freedom set recommendation = "\$0" # run is no longer "new" if(\$?NEW) unset NEW @ Successes = ( \$Successes + 1 ) if(\$integrate == yes) then ####################################### # Successful Integration # ####################################### echo "Integration was successful! " echo "" echo "\$mtzout contains your spot intensities (ready for scaling)." if((\$?BURSTMODE)&&("\$res_choice" != "backoff")) then echo "Burst mode set. Further iterative mosflm runs will not be done." echo "" set LAST_RUN goto scale_and_merge endif if((\$?AUTO)&&(\$Cycle == \$MAX_Cycles)) then echo "Maximum number of automatic cycles exceeded. One last time..." echo "" set LAST_RUN goto Suggest endif if(\$?LAST_RUN) then echo -n "Last run complete. " if((! \$?BURSTMODE)&&(! \$?ONCEONLY)) echo "Measurements are as good as elves can make them." echo "" goto scale_and_merge endif # if Postrefinement was turned off, try returning to "pure" postrefinement if((\$postref == no)&&(\$number_of_frames > 1)) then echo "Might want to refine again." set postref = yes set integrate = no set recommendation = "\$recommendation nointeg postref" goto Suggest endif # # if USEBEAM was turned off, try turning it back on again. # if((\$usebeam == no)&&(\$shift_mosaic == 0)) then # echo "But, the "\\"usebeam\\"" option will allow parameters to be refined for each frame." # set usebeam = yes # set fixcell = yes # set fixyscale = yes # set last_changed = usebeam # set recommendation = "\$recommendation integ usebeam fixcell fixyscale" # goto Suggest # endif # see if resolution limit is dangerously optimistic set test = \`echo \$res_limit \$hires | nawk '{print (\$1^3 > 3 * \$2^3)}'\` if(\$test &&("\$res_choice" != "user")) then # current resolution covers more than 3x the useful reciprocal-space volume # pick an optimistic, but reasonable limit (1.5x the reciprocal-space volume of res_limit) set newRES = \`echo \$res_limit 1.5 | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\` echo "" echo "Resolution limit of \$hires \$ANG looks far too optimistic." echo "this can cause mosflm to hang." echo "Recomend you reduce the resolution limit to \$newRES \${ANG}." echo "" set hires = \$newRES set res_choice = mosflm set recommendation = "\$recommendation \$hires A" goto Suggest endif # Cell fixed, unfixed, or even refinable if((\$fixcell == no)||(\$SG_number < 134)||(\$true_cell == yes)) then # cell is either free, or unwise to refine while integrating # if(\$true_cell == yes) echo "-fixcell was specified on command line, cell will remain fixed." if(\$shift == 0) then # Convergence reached with cell as free as it's gonna get. echo "All refinable parameters are stable! " if("\$res_choice" == "backoff") then # restore resolution range set res_choice = \$SAVE_res_choice if(("\$res_choice" == "user" || "\$res_choice" == "script")&&("\$SAVE_hires" != "")) then set hires = \$SAVE_hires echo "now try returning to \$hires \$ANG" set recommendation = "\$recommendation \$hires A" else echo "now try optimizing resolution limit." # all bets are off, use integration logs to re-establish resolution limit set res_choice = mosflm set recommendation = "\$recommendation \$hires A" endif goto Suggest endif if(\$true_cell == yes) then # We are DONE! echo "Spots should now be ready for scaling and mergeing." set LAST_RUN set recommendation = "\$recommendation integ -fixcell" else echo "Now integrate again, with the cell constant over all frames." set integrate = yes set fixcell = yes set true_cell = yes set recommendation = "\$recommendation integ -fixcell" endif else # Orientation will not be properly propagated to next run if we continue # integrating, but everything else will if(("\$shift_orient" == 0)&&(\$postref == yes)) then # orientation is stable # might as well keep refining mosaicity, distance, and cell here echo "Integrate again, to keep refining against all frames." set integrate = yes set recommendation = "\$recommendation integ refine" else # mean orientation shifted significantly during the run echo "Mean crystal orientation differs from input." echo "Go back to refinement again, to update the orientation matrix." set integrate = no # leave cell refinement status where it is, absorb orientation only set fixcell = yes # danger of oscillation here? # # the average orientation for a subset (refinement) is not, necessarily # the same as for all frames, but we can only update a matrix in # refinement # #if(\$reinput_missets == yes) then if(1) then # tell refinement NOT to converge, just absorb orientation into matrix if(\$?REFINE_NO_CONVERGE) then if(\$REFINE_NO_CONVERGE > 0) then # try to maximize segment size set mosflm_postref_segs = 6 set frames_per_segment = 5 else echo "Never mind, we've done this too many times already." # don't go back to refinement, keep integrating set integrate = yes # orientation drift will be ignored (above) set ignore_missets # and missetting angles will NOT be reset (above) #set reset_missets = no endif else # count down, only do this a few times set REFINE_NO_CONVERGE = 3 endif endif set recommendation = "\$recommendation nointeg fixcell" endif endif else # Cell was fixed, but symmetry permits refining it while integrating echo "Consider allowing the cell to refine next time." set fixcell = no set last_changed = nofixcell set recommendation = "\$recommendation nofixcell " endif else ####################################### # Successful Refinement # ####################################### echo "Refinement was successful! " echo "" set recommendation = "mv \$outmatrix \$best_matrix ;\$recommendation" # try expanding wedges? @ temp = ( \$mosflm_postref_segs * \$frames_per_segment ) if(( \$temp < ((\$last - \$first) / 3 ) )&&(\$temp < 20)) then echo "You might want to refine more frames." if(\$mosflm_postref_segs < 2 ) then set mosflm_postref_segs = 2 else @ frames_per_segment = ( \$frames_per_segment + 1 ) endif else # do not exit postrefinement until things have converged if((\$?REFINE_NO_CONVERGE)) then # absorbed last integration's mean missetting angles into newmatrix echo "return to integration, with this new orientation matrix." # don't do this too many times, can oscillate @ REFINE_NO_CONVERGE = ( \$REFINE_NO_CONVERGE - 1 ) # don't put THESE missetting angles into the integration set reinput_missets = no set integrate = yes set recommendation = "\$recommendation integ" goto Suggest endif #if((\$reinput_missets == no)&&((\$shift_distance + \$shift_mosaic + \$shift_cell) == 0)&&(\$failure_count < 2)) then if(0) then # absorb new missetting angles into next matrix echo "absorb the missetting angles into the next run." set reinput_missets = yes set fixcell = yes set recommendation = "\$recommendation \${logfile}mosflm.log fixcell" goto Suggest endif if(\$shift == 0) then # Converged!! echo -n "Refinement seems stable, " # if("\$res_choice" == "backoff") then # # restore original resolution range # set res_choice = \$SAVE_res_choice # if(("\$res_choice" == "user" || "\$res_choice" == "script")&&("\$SAVE_hires" != "")) then # set hires = \$SAVE_hires # echo "now try refining to \$hires \$ANG" # set recommendation = "\$recommendation \$hires A" # else # echo "now try optimizing resolution limit." # set recommendation = "\$recommendation \$hires A" # endif # goto Suggest # endif if(\$fixcell == yes) then # refine cell if we have enough frames to do so if((1 || ((\$wedge_width >= 45)||(\$SG_number >= 143)))&&(\$true_cell != "yes")) then # refining the cell is technically reasonable, and user approves echo "consider unfixing the unit cell next time." set fixcell = no set recommendation = "\$recommendation nofixcell" else if(\$true_cell != "yes") echo "but there are not enough frames to refine the cell in \$SG." echo "Go ahead and integrate with this cell." set integrate = yes set recommendation = "\$recommendation integ fixcell" endif else # cell was not fixed, and matrix is good! echo "Try integrating next! " set integrate = yes set fixcell = yes set recommendation = "\$recommendation integ fixcell" endif else # not converged yet, keep doing whatever we were doing echo "Parameters are still drifting. Refine again." set recommendation = "\$recommendation refine nointeg" endif endif # count if we have done n-round burst if((\$?BURSTMODE)&&("\$res_choice" != "backoff")) then if(\$BURSTMODE == 1) then set integrate = yes # should fix the cell we just refined set fixcell = yes set LAST_RUN set recommendation = "\$recommendation integ" else @ BURSTMODE = ( \$BURSTMODE - 1 ) endif endif endif else echo -n "Dang! \$BELL " # echo "" ################################### # MOSFLM failed somehow, back off # ################################### # should probably look at preds next time set Interactive = "PLOT" unset LAST_RUN # decide how to best deal with this problem set recommendation = "\$0" # First, look for problems we know how to fix grep -i "try" \${logfile}mosflm.log |\\ egrep "NADD|WIDTH|more images|changed by more than 10" >! \${tempfile} set test = \`cat \$tempfile | wc -l\` rm -f \$tempfile if(\$test != 0) then # mosflm suggested "more images" # see if POSTREF WIDTH is already in use echo "\$EXTRA_REFINE_CARDS" |\\ nawk 'BEGIN{RS="n"} {print \$0}' |\\ nawk '/^POST/' |\\ egrep " WIDTH | ADD " >! \${tempfile} set test = \`cat \$tempfile | wc -l\` rm -f \${tempfile} if("\$test" == 0) then set addsize = \`echo "\$first \$last" | nawk '{n=30;if(\$2-\$1 < n){n=\$2-\$1}; print n}'\` # try the POSTEF WIDTH CARD echo "Try constraining the cell in groups of \$addsize frames." echo "\$EXTRA_REFINE_CARDS" | nawk 'BEGIN{RS="n"} {print}' |\\ nawk 'NF!=0' >! \${tempfile} echo "POSTREF ADD \$addsize" >> \$tempfile set EXTRA_REFINE_CARDS = \`nawk 'BEGIN{ORS="n"} NF != 0' \$tempfile\` rm -f \$tempfile set recommendation = "Put "\\""POSTREF ADD \$addsize"\\"" in \$scriptname" goto Suggest endif endif # bad image? grep "ERROR READING IMAGE FILE" \${logfile}mosflm.log >& /dev/null if(! \$status) then cat \${logfile}mosflm.log |\\ nawk '\$3 == "Filename:" {file = \$NF} /ERROR READING IMAGE FILE/{print file}' |\\ cat >! \${tempfile} set temp = \`cat \${tempfile}\` rm -f \${tempfile} # get the number of this file, and eliminate it from processing set newlast = \`basename \$temp .\$ext | nawk '{print substr(\$1,length(\$1)-2)-1}'\` if((\$newlast > 0)&&(\$newlast < \$last)) then echo "\$temp seems to be a bad frame. " echo "Please either repair it, or delete it. " echo "Try ending the wedge at frame \$newlast" set last = \$newlast @ number_of_frames = ( ( \$last - \$first ) + 1 ) set recommendation = "\$recommendation \$number_of_frames frames" goto Suggest endif endif # ridiculously high resolution can cause lots of problems # figure out pessimistic outer resolution limit from mosflm log. cat \${logfile}mosflm.log |\\ nawk 'h==0 && /Analysis as a function of resolution./{h=1;getline;\\ print \$3, \$4, \$5, \$6, \$7, \$8, \$9, \$10} \\ /^ /{print \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9}' |\\ nawk 'NR==1{for(i=1;i<9;++i){res[i]=\$i};++n} \\ NR!=1{for(i=1;i<9;++i){signal[i]+=\$i;++count[i]}}\\ END{if(n) for(i=8;i>0;--i){print res[i], signal[i]/count[i]}}' |\\ sort -nr >! \${tempfile}res_limit set res_limit = \`nawk '\$NF > 2.0 {print \$1+0} \$NF<=1 {exit}' \${tempfile}res_limit | tail -1\` rm -f \${tempfile}res_limit >& /dev/null if("\$res_limit" != "") then #echo "average I/sig drops below 2 at \$res_limit \${ANG}." endif # this seems to happen when refinement drifts a LOT grep "lies outside currently defined standard profile areas" \${logfile}mosflm.log >& /dev/null if(! \$status) then # this usually happens when the resolution is too ambitious if("\$res_limit" == "") then # must have been refining... if(\$?edge_res) then # is this a good idea? # set res_limit = \`echo \$edge_res \$hires | nawk 'NF==2 && \$1+0>\$2+0 && \$1<20{print \$1}'\` endif endif if("\$res_limit" == "") then # just reduce it a bit set res_limit = \`echo \$hires 0.9 | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\` endif # pick a resolution limit that covers 0.9x the reciprocal space volume of res_limit set newRES = \`echo \$res_limit 0.9 | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\` # suggest a more reasonable limit set test = \`echo \$hires \$newRES | nawk 'NF==2{print (\$1<\$2)}'\` if ("\$test" == 1) then echo "\$hires \${ANG} might be overly optimistic." echo "Try using \$newRES \${ANG} to be safe" set RES_TROUBLE if("\$res_choice" == "user") then if(\$?AUTO) echo "but, you insisted on \${hires}A ..." else set hires = \$newRES set res_choice = mosflm set recommendation = "\$recommendation \${hires}A" goto Suggest endif endif endif # excessive background rejection implies resolution too high grep "rerun with a larger value for BGSIG" \${logfile}mosflm.log >& /dev/null if(! \$status) then # this usually happens when the resolution is too ambitious # pick a resolution limit that covers 0.9x the reciprocal space volume of res_limit set newRES = \`echo \$res_limit 0.9 | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\` # suggest a more reasonable limit set test = \`echo \$hires \$newRES | nawk 'NF==2{print (\$1<\$2)}'\` if ("\$test" == 1) then echo "\$hires \${ANG} might be overly optimistic." echo "Try using \$newRES \${ANG} to be safe" if("\$res_choice" == "user") then if(\$?AUTO) echo "but, you insisted on \${hires}A ..." else set hires = \$newRES set res_choice = mosflm set recommendation = "\$recommendation \${hires}A" goto Suggest endif endif endif # could there be some other crashes resulting from too high a resolution limit? # pick a resolution limit that covers 1.0x the reciprocal space volume of res_limit set newRES = \`echo \$res_limit 1.0 | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\` set newRES = \`echo \$newRES \$detector_res_limit | nawk 'NF==2 && \$1<\$2{\$1=\$2} {print \$1}'\` set test = \`echo \$hires \$newRES | nawk '{print (\$1 < \$2)}'\` if(\$test) then # mosflm failed and # current resolution covers more than 1.0x the useful reciprocal-space volume # suggest a more reasonable limit echo "\$hires \${ANG} might be overly optimistic." echo "Try using \$newRES \${ANG} to be safe" if("\$res_choice" == "user") then if(\$?AUTO) echo "but, you insisted on \${hires}A ..." else set hires = \$newRES set res_choice = mosflm set recommendation = "\$recommendation \${hires}A" goto Suggest endif endif # keep track of failures @ failure_count = ( \$failure_count + 1 ) if("\$mosflm_status" == "\$last_mosflm_failure") @ chronic_failures = ( \$chronic_failures + 1 ) # have a look at predictions (indirectly) nawk '\$1 ~ /^[\\*\\-]/ && ! /[a-z,\\.]/ && /[0-9]/' \${logfile}mosflm.log >! \${tempfile} set temp = \`ls -ln \$tempfile | nawk '{print \$5}'\` rm -f \$tempfile >& /dev/null if("\$temp" < 10) then # the average peak-area pixel value is unusually low echo "Spot profiles were not even made." echo "" set temp = \`nawk -v wave=\$wavelength 'BEGIN{print 12398.4245/wave}'\` echo "crystal-to-film = \$distance mm" echo "x-ray wavelength = \$wavelength \$ANG / \$temp eV" echo "direct beam spot at \$beam_center (in mosflm window)" echo "detector 2theta = \$two_theta \$DEG" echo "unit cell = \$CELL" echo "matrix file = \$inmatrix" echo "" set temp = "Yes" echo "Are you sure these alignment parameters are correct? [\$temp] \$BELL" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$temp" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = \`echo "\$in"\` endif if(("\$temp" =~ [Nn]*)&&(\$#temp == 1)&&(! \$?AUTO)) then # duh... echo "Uhh, okay. What are the correct parameters? " echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) set input = "\$temp" goto Questionaire endif if("\$temp" !~ [Yy]*) then set input = "\$temp" if("\$input" =~ [Nn][Oo]) set input = "" goto Questionaire endif endif if("\$mosflm_status" == "bad_preds") then echo "Spots are too far off their predictions." echo " (best is \$resid[4] mm)" endif # if((\$Successes == 0)&&("\$SG_choice" == "auto")) then # # we may have just picked a bad space group # echo "maybe Bravais lattice is not really \${BRAV}? Autoindex again." # # set recommendation = "\$0 index" # goto Suggest # endif if(\$chronic_failures > 3) then echo "\${chronic_failures}th occurence of this problem." # try re-autoindexing if((\$SG_number < 75)&&(! \$?REINDEXED)) then echo "Try autoindexing again." set REINDEXED set KEEP_SG set recommendation = "\$recommendation -new index" endif # try indexing again? if("\$SG_choice" == "auto" && "\$SG" != "P1") then echo "Perhaps \$BRAV is not the Bravais lattice. Autoindex again." set recommendation = "\$recommendation index" goto Suggest endif # roll back into list of matricies if(\$number_of_frames > 5) then echo "Try reducing the size of the wedge." set temp = \`nawk '/Filename:/ {print \$NF}' \${logfile}mosflm.log | grep ".\$ext" | tail -1\` set newlast = \`basename \$temp .\$ext | nawk '{print substr(\$1,length(\$1)-2)-1}'\` if((-e "\$temp")&&(\$newlast > (\$first + 2))&&(\$newlast < \$last)) then # legitimate last frame loaded set last = \$newlast @ number_of_frames = ( ( \$last - \$first ) + 1 ) else # just try cutting it in half @ number_of_frames = ( \$number_of_frames / 2 ) endif set recommendation = "\$recommendation \$number_of_frames" goto Suggest else echo "The Wedger elves are confounded! " echo "" echo "Please check and make sure they have the right" echo "wavelength, distance, two-theta, cell, etc." echo "" echo "You should check that spots are actually being " echo "predicted in an interactive mosflm run, and give " echo "THAT matrix to a noninteractive Wedger run." echo "If you STILL have probelms, you need to know" echo "more than we do. Start reading manuals." goto Cleanup endif endif # remember last failure message set last_mosflm_failure = "\$mosflm_status" # set last_changed = failure # No-brainers: if(\$reinput_missets == yes) then # don't absorb mean missetting angles into next matrix, pretty dangerous echo "Don't use the misseting angles from \${logfile}mosflm.log this time." set reinput_missets = no set recommendation = "\$recommendation -new" # goto Suggest endif # if(usebeam == yes) then # # Definitely don't use beam if we are having problems # echo "Turn off the "\\"usebeam\\"" feature until refinement has converged." # set usebeam = no # set recommendation = "\$recommendation nousebeam" # goto Suggest # endif if(\$fixcell == no) then # don't mess around with cell if we are having problems echo "Try fixing the cell this time." set fixcell = yes set recommendation = "\$recommendation fixcell" # goto Suggest endif set temp = \`echo \$mosaic \$osc | nawk '{printf "%d", \$2/(\$1+0.001)}'\` if(\$temp > 5) then # reset mosaic spread if we are having problems echo "Use a wider mosaic spread." set temp = \`echo \$osc | nawk '{print 0.8*\$1}'\` set recommendation = "\$recommendation mosaic \$temp" if("\$fixmosaicity" != "yes") set mosaic = "\$temp" # goto Suggest endif if(\$integrate == yes) then # Died while trying to integrate echo "Full integration may have been premature, go back to refinement." set integrate = no set postref = yes set recommendation = "\$recommendation nointeg" else # Died during POSTREFINEMENT!, uh oh. if(("\$res_choice" != "backoff")&&("\$mosflm_status" != "fixed")) then # maybe we should reduce resolution to shure up refinement? set SAVE_hires = \$hires set SAVE_res_choice = \$res_choice set res_choice = backoff # pick a resolution avoiding ice rings set hires = \`echo \$hires | nawk '{printf "%.1f", (0.3*\$1^-3)^(-1/3)}' | nawk '\$1<3.9 && \$1>2.5{\$1 = 3.9} {print}'\` echo "Try refining low-resolution spots only." if("\$res_choice" == "user" || "\$res_choice" == "script") then # user-specified res choice should always be restored set res_choice = backoff endif set recommendation = "\$recommendation \$hires A" unset LAST_RUN goto Suggest endif # no adjustable cell (crystal slippage?) if(\$frames_per_segment > 3 ) then echo "Try reducing your refinement wedge size." @ frames_per_segment = (\$frames_per_segment / 2 ) else if(\$mosflm_postref_segs > 1) then echo "Try reducing your number of postref blocks." set mosflm_postref_segs = 1 else # If we get here, we were doing the most conservative # postref possible: # fixed cell # fixed yscale # no usebeam # 1 block of 2-3 frames # echo "Most basic postref run is not working." echo "" # see if there were other possibilities for a matrix foreach mat ( \$matrixfiles ) foreach bad ( \$badmatrix \$inmatrix \$outmatrix ) if("\$mat" == "\$bad") set mat = "" end if(-e "\$mat") then # might be worth a try set badmatrix = \`echo \$badmatrix \$inmatrix \$outmatrix\` echo "Try starting over again with \$mat" set badmatrix = \`echo \$badmatrix \$inmatrix \$outmatrix\` set recommendation = "mv \$inmatrix \${inmatrix}.bad;\$recommendation \$mat -new" goto Suggest endif end # no other matricies available. Make one? echo "Either some major parameter is wrong (distance?, wavelength?)" echo "or the orientation is too far off to converge." if((! \$?AUTO)||("\$SG_choice" == "auto")) then echo "Autoindex again." set set recommendation = "mv \$inmatrix \${inmatrix}.bad;\$recommendation \$FirstImage -new index" set lastlog = "" else # automatic refinement is no longer appropriate, user should look at graphics echo "" echo "You should check that spots are" echo "*** ACTUALLY BEING PREDICTED *** " echo "in an interactive mosflm run, and give " echo "THAT matrix to a noninteractive Wedger run." echo "If you STILL have probelms, then you need" echo "to know more than we do. Start reading manuals." goto Cleanup endif endif endif endif endif Suggest: ############################################################################### #### # # #### #### ###### #### ##### # #### # # # # # # # # # # # # # # # ## # #### # # # # ##### #### # # # # # # # # # # # ### # ### # # # # # # # # # # # # # # # # # # # # # # # # # ## #### #### #### #### ###### #### # # #### # # ################################################################################ # # Output recommendations to user # # # on CCD, this is probably always the case. if((\$fixyscale == no)&&(("\$ext" == "img")||("\$SCANNER" =~ *CCD*))) then echo "On the CCD, you should probably fix the X-Y scale." set recommendation = "\$recommendation fixyscale" set fixyscale = yes endif # suggest convergence run to user echo "" echo "Recommend:" echo "\$recommendation" | nawk 'BEGIN{RS=";"}{print \$0}' if(\$?ONCEONLY) then goto UpdateScript endif echo "" set temp = "Yes" echo "Do this now? [\${temp}/go auto]?" echo -n "\$PROMPT" if(\$?AUTO) then echo "\$temp" else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif echo "" if(("\$temp" =~ [Gg][Oo]*)||("\$temp" =~ [Aa][Uu][Tt][Oo]*)) then set AUTO set Interactive = "#PLOT" echo "Rock 'n Roll! " set CATCH_USER echo "(We will beep if something bad happens ...)" goto Converge endif if("\$temp" =~ [Yy]*) goto Converge if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then set input = "\$temp" goto Questionaire endif set temp = "quit" echo "What do you want to do? [\$temp]?" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" != "quit") then set input = "\$temp" goto Questionaire endif echo "" echo "Okay, bye! " goto Cleanup Converge: set Convergeing set last_mosflm_status = "\$mosflm_status" echo "\$recommendation" | grep \$outmatrix >& /dev/null if(! \$status) then # moving the matrix was suggested echo "moving \$outmatrix to \$best_matrix ..." if(-e "\$best_matrix") mv \$best_matrix \${best_matrix}.old mv \$outmatrix \$best_matrix # make this the input next time set inmatrix = \$best_matrix endif echo "\$recommendation" | grep index >& /dev/null if(! \$status) then # autoindexing was suggested set autoindexing # make a fresh start set lastlog = "" set chronic_failures = 0 set failure_count = 0 set last_mosflm_failure = indexing set argv = ( \$command_line_argv ) if(! \$?KEEP_SG) then # disqualify everything in this Bravais lattice set wrongSGs = ( \$wrongSGs \$BRAV ) set CELL = "unknown" set SG = "unknown" endif unset KEEP_SG # these sources shouldn't give us back an cell/sg. should they? set sources = "\$oldscripts" goto GetParamsFromSources endif echo "\$recommendation" | grep "mv \$inmatrix \${inmatrix}.bad" >& /dev/null if(! \$status) then # moving the matrix was suggested echo "moving \$inmatrix to \${inmatrix}.bad ..." mv \$inmatrix \$inmatrix.bad set temp = "old matrix" goto FindMATRIX endif # clear command-line args (they are now out of date) set argv = "" #set 0 = \$temp # Repeat the run, using last output as input set lastlog = "\${logfile}mosflm.log" set sources = "\${logfile}mosflm.log \$inmatrix" # don't read logfile if there were problems if("\$mosflm_status" != 0) set sources = "\$inmatrix" goto GetParamsFromSources # # # Cleanup: onintr # restore old TTY settings (for emacs sake) test -t 1 >& /dev/null if(! \$status) then stty erase \$oldTTYerase endif #restore resolution limit if we messed with it if(("\$SAVE_hires" != "")&&(-e \$scriptname)&&("\$mosflm_status" != "0")) then # restore resolution range set hires = \$SAVE_hires if(\$?SAVE_res_choice) then set res_choice = \$SAVE_res_choice endif echo "restoring \$hires \$ANG in \$scriptname" cat \$scriptname |\\ nawk -v hires=\$hires '! /^RESO/{print} /^RESO/{print "RESOLUTION", hires}' |\\ cat >! \${tempfile}oldhires mv -f \${tempfile}oldhires \$scriptname chmod a+x \$scriptname endif ############################################################################### # get rid of temp files that you will never look at anyway # ############################################################################### if((-e "\${logfile}mosflm.log")&&(! \$?NORUN)&&("\$mosflm_status" == 0)) then echo "For a detailed review of your measurement," echo " have a look at \${logfile}mosflm.log and \${logfile}mosflm.html" endif echo "Cleaning up..." rm -f \${tempfile}* >& /dev/null rm -f mosflm_temp >& /dev/null rm -f fort* >& /dev/null if((\$?NORUN)&&(\$number_of_frames < 2)) then echo "As soon as you have enough frames, " echo "you can edit and run \$scriptname, or run \$0 again." endif if((-e "\$outmatrix")&&("\$mosflm_status" == 0)&&(! \$?NORUN)) then echo "Don't forget to mv \$outmatrix \$inmatrix" echo "before you run \$0 again." endif if(\$?NO_CCP4) then # clean up band-aid files rm -f \${CLIBD}/symop.lib >& /dev/null rm -f \${CINCL}/environ.def >& /dev/null rm -f \${CINCL}/default.def >& /dev/null cat << EOF From here on out, you're going to need CCP4. Don't worry, it's free. Get yourself a copy at: netscape ftp://ccp4a.dl.ac.uk/pub/ccp4/ Unfortunately, you'll have to compile it. If, however, you have Red Hat linux, you can get an RPM from the O people at: netscape http://origo.imsb.au.dk/~mok/linux/dist/ Good Luck. In case this all seems like too much trouble, the raw data in \$mtzout are now being converted to a flat text file called raw.hkl so you can more easily import it into some other scaling and mergeing program. EOF # extract raw data to text? echo " H K L M/ISYM BATCH I SIGI IPR SIGIPR FRACTIONCALC XDET YDET ROT WIDTH LP MPART" >! raw.hkl ood -f \${mtzout} |\\ nawk '{for(i=2;i<=NF;++i){print \$i}}' |\\ nawk 'NR > 20{printf "%s ", \$1+0; ++i; if(i%16 == 0) print ""}' |\\ nawk '\$1 != int(\$1) || \$2 != int(\$2) || \$3 != int(\$3) || (\$1+\$2+\$3)==0 || (\$1+\$2+\$3)>1000000 || (\$1+\$2+\$3)<-1000000 {++done} ! done {print}' |\\ nawk '{printf "%4d %4d %4d %5d %6d %12f %12f %12f %12f %12.10f %12f %12f %12f %12f %12f %4d\\n", \$1, \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9, \$10, \$11, \$12, \$13, \$14, \$15, \$16}' |\\ cat >> raw.hkl echo "done! " echo "" endif if(\$?LAST_RUN) then if(\$?NOSCALE) then cat << EOF Now what? 1) review \${logfile}mosflm.log and \${logfile}mosflm.html 2) Edit and run \$mergescript, or: - Use sortmtz to combine \$mtzout with your other raw data files. - Use scala to scale and merge the sorted data into HKLs - Use truncate to convert scala's results into Fs, in mtz format. - Use mtz2various.com to export Fs to various other X-ray programs. OR Use Scaler Elves to do all the above automatially. :) EOF else cat << EOF Now what? - review \${logfile}mosflm.log and xloggraph \${logfile}mosflm.html - also, view and xloggraph \${logfile}merge.log - IF THIS IS THE ONLY WEDGE OF DATA FOR THIS CRYSTAL: Optimize \$mergescript for scaling and mergeing \$mtzout (see scala documentation) (Maybe use SGsearch.com to evaluate alternative space groups.) Use the CCP4 program scaleit to compare \$mergefile with data from other crystals Use mtz2various.com to export your Fs to various other X-ray programs. - IF THERE ARE OTHER WEDGES: Use sortmtz to combine \$mtzout with your other raw data files. Use scala to scale and merge the sorted data into HKLs Use truncate to convert scala's results into Fs, in mtz format. Use mtz2various.com to export your Fs to various other X-ray programs. OR Use Scaler Elves to do all the above automatially. :) EOF endif endif # make it a number set mosflm_status = \`echo \$mosflm_status | nawk '\$1~/[a-z]/{\$1+=100} {print \$1+0}'\` exit \$mosflm_status ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ####################### END OF MAIN SCRIPT ######################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### ############################################################################### # Below are a bunch of routines that were moved here to improve the readability # of this script. exit FindMOSFLM: ############################################################################### ###### # # # ##### # # #### #### ###### # # # # # ## # # # ## ## # # # # # ## ## ##### # # # # # # # ## # # # #### ##### # # ## # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # # # # # # ##### # # #### #### # ###### # # ############################################################################### # Hunt for ipmosflm executable # ############################################################################### # \$mosflm should be set to the expected location of the ipmosflm executable # if found, The fully-qualified pathname of a working mosflm executable will # be returned in \$mosflm. Otherwise, \$mosflm will be blank # (\$MOSFLM is used as a default name, set above, or in a script file) # # make sure this thing runs if( -e "\$mosflm") then set mosflm = \`ls -lnL \$mosflm |& nawk '\$5>1000000{print \$NF}'\` if(-e "\$mosflm") then set MosflmVersion = \`echo "GO" | \$mosflm SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" !~ [1-9]*) then # no dice set mosflm = "" set MosflmVersion = "" endif endif endif # check command-line first set i = 0 while(\$i < \$#argv) @ i = ( \$i + 1 ) set file = \`ls -lnLd \$argv[\$i] |& nawk '\$5>1000000{print \$NF}'\` if((-e "\$file")&&(! -e "\$mosflm")) then # try running it set mosflm = "\$file" set MosflmVersion = \`echo "GO" | \$mosflm SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" !~ [1-9]*) then # no dice set mosflm = "" set MosflmVersion = "" endif endif end # try the "which" command first if(! -e "\$mosflm") then foreach filename ( \$mosflm \$MOSFLM ipmosflm mosflm ) if(! -e "\$mosflm") then set temp = \`which \$filename |& grep -v ' not in ' |& tail -1 \` foreach file ( \$temp ) # see if file is big enough set file = \`ls -lnLd \$file |& nawk '\$5>1000000{print \$NF}'\` if((-e "\$file")&&(! -e "\$mosflm")) then # try running it set MosflmVersion = \`echo "GO" | \$file SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" =~ [1-9]*) then # got one set mosflm = "\$file" else # no dice set mosflm = "" endif endif end endif end endif if(! -e "\$mosflm") then # discard original suggestion, try this one set mosflm = "ipmosflm" echo -n "Looking for \$mosflm ... " onintr CantFindMosflm # look down a list of standard places for the executable foreach place ( ./ ../ ../../ ../../../ /programs/mosflm/bin/ /programs/mosflm/ /programs/ /pxsoft/mosflm /sw/ /usr/local/bin/ /usr/local/ /usr/local/mosflm/ ) # stop looking when we find it if((! -e "\$mosflm")&&(-e "\$place")) then # look for executable files with names containing "mosflm" in \$place set files = \`ls -lnLrt \${place} |& nawk '! /^d/ &&(\$1 ~ "x")&&(\$5+0 > 3000000)&&(\$NF ~ "mosflm"){print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l1000000{print \$NF}'\` if((-e "\$file")&&(! -e "\$mosflm")) then # try running it set MosflmVersion = \`echo "GO" | \$file SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" =~ [1-9]*) then # got one set mosflm = "\$file" else # no dice set mosflm = "" endif endif end endif end endif if(! -e "\$mosflm") then echo -n "looking harder ... " foreach place ( ../../../ ~/ /programs/ /usr/local/bin/ /usr/local/ /sw/ / ) # look for files of right type if((! -e "\$mosflm")&&(-e "\$place")) then # look for links, and big-enough files set temp = \`find \$place -name \\*mosflm\\* \\( -type l -o \\( -type f -size +100000c \\) \\) -perm -1 -print |& nawk '! /^find:/' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 3000000){print \$NF}'\` foreach file ( \$temp ) # see if file is big enough set file = \`ls -lnLd \$file |& nawk '\$5>1000000{print \$NF}'\` if((! -e "\$mosflm")&&(-e "\$file")) then # try running it set MosflmVersion = \`echo "GO" | \$file SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" =~ [1-9]*) then # got one set mosflm = "\$file" else # no dice set mosflm = "" endif endif end endif end endif # make sure this thing runs if(( -e "\$mosflm")&&("\$MosflmVersion" == "")) then # see if file is big enough set mosflm = \`ls -lnLd \$mosflm |& nawk '\$5>1000000{print \$NF}'\` set MosflmVersion = \`echo "GO" | \$mosflm SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" !~ [1-9]*) then # no dice set mosflm = "" endif endif CantFindMosflm: onintr if((! -e "\$mosflm")||(("\$MosflmVersion" !~ [678]*)&&(! -e "\$inmatrix"))) then echo "Hmm." if(-e "\$mosflm") then echo "we found \$mosflm, but " endif echo "you do not appear to have Mosflm 6.x ! " ###################################################### cat << EOF-getmosflm >! getmosflm.com #! /bin/csh -f # # # Script for automatically retrieving ipmosflm 6.23 # from the MRC ftp site # # # if("\\\$1" =~ compile*) set COMPILE # see what kind of system this is set uname = \\\`uname -a\\\` set ipmosflm = "" set gunzip = "gunzip" set ftpsite = "ftp.mrc-lmb.cam.ac.uk" set ftpdir = "pub/mosflm/ver623/" set guide = "pub/mosflm/ver623/mosflm_user_guide.html" # figure out which mosflm executable to get if(\\\$?COMPILE) then set ftpdir = "pub/mosflm/ver623/build-it-yourself" set ipmosflm = "mosflm623.tar.gz" goto retrieve endif if("\\\$uname" =~ IRIX*) then set ipmosflm = "mosflm_irix5.3.gz" set ftpdir = "pub/mosflm/ver623/pre-built/" if("\\\$uname" =~ IRIX6*) set ipmosflm = "mosflm_irix6.5_o32.gz" if("\\\$uname" =~ *" 6.2 "*) set ipmosflm = "mosflm_irix6.2.gz" endif if("\\\$uname" =~ OSF1*) then set ipmosflm = "mosflm_alpha.gz" set ftpdir = "pub/mosflm/ver623/pre-built/" # check for 4D60T graphics card? set ipmosflm = "mosflm_alpha4D60T.gz" set ipmosflm = "mosflm_alpha_noso.gz" endif if("\\\$uname" =~ Linux*) then set ipmosflm = "mosflm_redhat9.0.gz" set ftpdir = "pub/mosflm/ver623/pre-built/" if("\\\$uname" =~ *" "SUSE" "*) set ipmosflm = "mosflm_suse7.3.gz" if("\\\$uname" !~ *" "i?86" "*) set ipmosflm = "mosflm_ppc.gz" endif if("\\\$uname" =~ Darwin*) then set ipmosflm = "mosflm_macOSX.gz" set ftpdir = "pub/mosflm/ver623/pre-built/" endif # random, failsafe defaults if("\\\$ipmosflm" == "") set COMPILE if(\\\$?COMPILE) set ipmosflm = "mosflm623.tar.gz" if("\\\$ipmosflm" == "mosflm623.tar.gz") set ftpdir = "pub/mosflm/ver623/build-it-yourself/" retrieve: # now figure out how we're going to retrieve mosflm echo "retrieving ftp://\\\${ftpsite}/\\\${ftpdir}/\\\$ipmosflm " rm -f \\\$ipmosflm >& /dev/null wget -O \\\$ipmosflm ftp://\\\${ftpsite}/\\\${ftpdir}/\\\$ipmosflm >& /dev/null if((! \\\$status)&&(-e \\\$ipmosflm)) then wget -O \\\$guide ftp://\\\${ftpsite}/\\\$guide >& /dev/null goto decompress endif # wget didn't work, try ncftpget ncftpget \\\${ftpsite} . \\\${ftpdir}/\\\$ipmosflm \\\$guide >& /dev/null if((! \\\$status)&&(-e \\\$ipmosflm)) goto decompress # dangerous! try using regular ftp: # confirm? if(-e ~/.netrc) then mv ~/.netrc ~/netrc.bak\\\$\\\$ set RESTORE_NETRC endif onintr restore_netrc echo "default login anonymous password user@site" >! ~/.netrc chmod go-rwx ~/.netrc ftp \\\$ftpsite << EOF get \\\${ftpdir}/\\\$ipmosflm \\\$ipmosflm get \\\$guide mosflm_user_guide.html close bye EOF restore_netrc: onintr if(\\\$?RESTORE_NETRC) then mv ~/netrc.bak\\\$\\\$ ~/.netrc else rm -f ~/.netrc >& /dev/null endif # check if transfer worked if(! -e "\\\$ipmosflm") then echo "transfer failed..." echo "perhaps the server is overloaded? " exit 9 endif decompress: set uncompressed = \\\`basename \\\$ipmosflm .gz\\\` if ("\\\$uncompressed" != "\\\$ipmosflm") rm -f \\\$uncompressed >& /dev/null foreach unzip ( \\\$gunzip unzip "gzip -d" /bin/gunzip /usr/bin/gunzip ) \\\$unzip \\\$ipmosflm >& /dev/null if((! \\\$status)&&(-e "\\\$uncompressed")) break end # maybe wget decompressed it? if(! -e "\\\$uncompressed") then set uncompressed = \\\`basename \\\$ipmosflm .tgz\\\`".tar" endif compile: if(\\\$?COMPILE) then if(! \\\$?CCP4) then setenv CCP4 \\\`pwd\\\` setenv CCP4_LIB \\\`pwd\\\` setenv CLIB \\\$CCP4_LIB echo "mosflm needs the CCP4 libraries:" echo "libccp4.a libxdl_view.a" echo "in order to compile." exit 200 endif echo "compiling mosflm..." tar xf \\\$uncompressed if(\\\$status) then echo "unable to decompress archive! " echo "is \\\$uncompressed corrupt?" exit 9 endif # go into the build directory cd mosflm623 build >! compile.log if(\\\$status) then cat compile.log echo "unable to compile mosflm on this system! " echo "type:" echo "cd "\\\`pwd\\\` echo "make" echo "to see why." exit 9 else set uncompressed = \\\`pwd\\\`/bin/ipmosflm endif cd .. endif # re-name the executable mv \\\$uncompressed ipmosflm if(-e ipmosflm) then chmod a+x ipmosflm echo \\\`pwd\\\`"/ipmosflm is ready" endif done: exit EOF-getmosflm chmod a+x ./getmosflm.com ###################################################### set temp = "Yes" if(\$?AUTO) set temp = "No" echo "shall we retrieve ipmosflm 6.23 from ftp.mrc-lmb.cam.ac.uk" echo "using anonymous FTP? [\$temp]" if(! \$?AUTO) then echo -n "\$PROMPT" echo -n "\$BELL" set temp = "\$<" else set temp = "" endif if("\$temp" !~ [Nn]*) then ./getmosflm.com set mosflm = 'pwd'"/ipmosflm" else echo "Okay, you can run the script called: ./getmosflm.com" echo "to automatically retrieve the latest version of mosflm" endif endif if(! -e "\$mosflm") then echo "Darn! " echo "We can't find ipmosflm. Looked everywhere ... :( " echo "Where is ipmosflm [don't worry about it]?" if(! \$?AUTO) then echo -n "\$PROMPT" echo -n "\$BELL" set temp = "\$<" else set temp = "" endif if(("\$temp" =~ q*)||("\$temp" == "")) then echo "The Wedger elves could not find the executable file for MOSFLM." echo "We need this file to process your data. :)" echo "Ask your friendly neighborhood sysadmin where it is," echo "or go to: " echo "netscape ftp://ftp.mrc-lmb.cam.ac.uk/pub/mosflm/" echo "and get yourself the latest version." if("\$temp" =~ q*) then goto Cleanup else echo "" echo "Don't forget to edit \$scriptname before you run it! " set NORUN set mosflm = "" set MosflmVersion = "" goto ReturnFindMOSFLM endif endif # check the user-input executabe file set mosflm = \`ls -lnLd \$temp |& nawk '\$5>1000000{print \$NF}'\` if("\$mosflm" == "") echo "\$temp does not look like ipmosflm! " set MosflmVersion = \`echo "GO" | \$temp SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" !~ [1-9]*) then # no dice set mosflm = "" echo "Sorry, \$temp won't run." goto CantFindMosflm endif # update program location to user-input one set mosflm = "\$temp" # goto FindMOSFLM endif goto ReturnFindMOSFLM exit exit GetParamsFromSources: ############################################################################### #### #### ## # # ###### # # ###### #### # # # # # ## # # # # # # #### # # # # # # ##### # # ##### #### # # ###### # # # # # # # # # # # # # # # ## # # # # # # #### #### # # # # # # ###### ###### #### ############################################################################### # # Initialize program variables from an ordered listing of: # # \$img \$lastlog \$inmatrix \$scriptname and other files # # in the variable \$sources # ############################################################################### # create temporary files for script reading rm -f \${tempfile}* >& /dev/null touch \${tempfile}.preamble touch \${tempfile}.extra_refine_cards # reverse the order of the sources, so that "first" sources are scanned last (dominant) set temp = "" foreach source ( \$sources ) set temp = \`echo \$source \$temp |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null if (! \$status) then set format = SBC endif # new SMV format for RAXIS images nawk 'BEGIN{RS="\\f"} {print;exit}' \$source | grep "RAXIS_" >& /dev/null if (! \$status) then set format = RAXIS_SMV endif endif # # ## ##### ##### # # # ## ## # # # # # # # # # ## # # # # # # # ## # # ###### # ##### # ## # # # # # # # # # # # # # # # # # # # # if((\$source == "\$inmatrix")||(\$source =~ *.mat)) then echo -n "Scanning \$source ... " ####################################################################### # Read in CELL from the matrix file # ####################################################################### set temp = \`nawk 'NF == 6' \$source |& nawk '{for(i=1;i<=NF;++i) if(\$i+0 > 10) printf \$i+0 " "}'\` if(\$#temp == 6) then # don't update cell if we want it fixed if(("\$true_cell" != "yes")||(\$#CELL != 6)) then set CELL = \`echo \$temp\` endif echo -n "\$CELL" else # maybe this is a denzo .x file? set temp = \`basename \$source .x\` set temp = \`basename \$temp .y\` set mat = "\${temp}.mat" if(-e "\$mat") mv \$mat \${mat}.old # extract the (putative) unitary matrix head -5 \$source |& nawk 'NR>1 && NF == 6{printf "%12.8f%12.8f%12.8f\\n", \$4, \$5, \$6}' |\\ nawk '{i=NR; for(j=1;j<4;++j){mat[i,j]=\$j+0}} \\ END{det += mat[1,1]*((mat[2,2]*mat[3,3])-(mat[2,3]*mat[3,2])) \\ det -= mat[1,2]*((mat[2,1]*mat[3,3])-(mat[2,3]*mat[3,1])) \\ det += mat[1,3]*((mat[2,1]*mat[3,2])-(mat[2,2]*mat[3,1])) \\ printf "%.4f", det}' >&! \$tempfile set temp = \`cat \$tempfile\` if("\$temp" == "1.0000") then # get the cell out of this file set temp = \`grep -i cell \$source |& tail -1 |& nawk '{for(i=1;i<=NF;++i) if(\$i+0 > 10) printf \$i+0 " "}'\` if(\$#temp == 6) set CELL = \`echo \$temp\` # determinant indicates a valid matrix # convert denzo to york (if need be) cp \$source \${tempfile}.x grep HEADER \$source >& /dev/null if(\$status) then echo "HEADER 1" >! \${tempfile}.x head -10 \$file >> \${tempfile}.x endif # use combat logfile output to get mosflm matrix echo "" | nawk '{print "INPUT DENZO"; print "SYMM 1"; print "RESO 9"; print "END"}' |\\ combat HKLIN \${tempfile}.x HKLOUT /dev/null |&\\ nawk '/Mosflm umat matrix/{getline; getline; getline; getline;\\ getline; printf "%12.8f%12.8f%12.8f\\n", \$1, \$2, \$3; \\ getline; printf "%12.8f%12.8f%12.8f\\n", \$1, \$2, \$3; \\ getline; printf "%12.8f%12.8f%12.8f\\n", \$1, \$2, \$3}'|\\ cat >&! \${tempfile}.umat rm -f \${tempfile}.x >& /dev/null # quick check for validity set temp = \`cat \${tempfile}.umat | nawk '\$1+\$2+\$3 != 0' | wc -l\` if("\$temp" != 3) then echo "bad matrix in \$source" set inmatrix = "" set autoindexing continue endif # create a mosflm matrix file where A = U**-1 (doesn't seem to affect predictions) cat \${tempfile}.umat >! \$mat # missetting angles are zero nawk 'BEGIN{printf "%12.3f%12.3f%12.3f\\n", 0, 0, 0}' >> \$mat # U matrix goes here cat \${tempfile}.umat >> \$mat # put the cell here... echo "\$CELL" | nawk '{for(i=1;i<=NF;++i){if(\$i ~ /[0-9]/)\\ printf "%12.4f",\$i}} END{print ""}' >> \$mat # missetting angles are zero nawk 'BEGIN{printf "%12.4f%12.4f%12.4f\\n", 0, 0, 0}' >> \$mat rm -f \${tempfile}.umat >& /dev/null # inform user we created a new file echo -n "extracted \$mat " set inmatrix = \$mat else # not a valid matrix, or .x file echo -n "BAD MATRIX! " set inmatrix = "" set autoindexing endif endif echo "" # skip rest of scans continue endif ## ##### #### #### # # # ## #### ###### # # # # # # # # ## ## # # # # # # # # # #### # # # ## # # # # ##### ###### # # # # # # # ###### # ### # # # # # # # # # # # # # # # # # # # ##### #### #### # # # # # #### ###### # ADSC files begin with "{\\nHEADER_BYTES" if("\$format" == ADSC) then echo -n "Scanning \$source ... " # shorthand set img = \$source ############################################################################### # Read in parameters from an image file # ############################################################################### # \$img should be set to the location of the ADSC image file # following variables will be inilialized using this file's header: # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # phi - oscillation start (degrees) # osc - oscillation range (degrees) # wavelength - wavelength (according to the header) # overload - maximum pixel value # Site - the detector serial number (or text of site) # # framedir - directory where this file exists # frameprefix - image filename (minus batch number and underscore) # first - batch number of this frame # last - largest batch number with same prefix # # Width - detector width (mm) # PIXEL - pixel size (mm) # set GAIN = 0.3 set OVERLOAD = 65000 unset mosflm_beam # get ADSC CCD frame header nawk 'BEGIN{RS="\\f"} {print;exit}' \$img >! \${tempfile}header set Site = \`grep "DETECTOR_SN" \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` if("\$Site" == "") then set Site = \`grep "DETECTOR_DESCRIPTION" \${tempfile}header | nawk -F "=" '{ print \$2}'\` set test = \`echo \$Site | awk '{print ( /MBC CMOS/ )}'\` if(\$test) then set format = "SMV" set Site = "ALS 4.2.2" endif endif if("\$Site" == "411") then # prior knowledge of SSRL beamline 1-5 (could also be read from input script) set Site = "SSRL" set POLARISATION = "SYNCHROTRON 0.92" set DIVERGENCE = "0.250 0.030" # set DISPERSION = "0.0002" endif if(("\$Site" == "402")||("\$Site" == "401")) then # prior knowledge of ALS beamline 5.0.2 (could also be read from input script) set Site = "ALS" set POLARISATION = "SYNCHROTRON 0.9" set DIVERGENCE = "0.10 0.02" # set DISPERSION = "0.00025" endif if("\$Site" == "442" ) then # prior knowledge of ALS beamline 8.3.1 set Site = "ALS 8.3.1" set POLARISATION = "SYNCHROTRON 0.9" set DIVERGENCE = "0.10 0.02" # set DISPERSION = "0.00025" set PREAMBLE = "\${PREAMBLE}nBACKSTOP RADIUS 2" endif if("\$Site" == "926") then # prior knowledge of ALS beamline 8.3.1 set Site = "ALS 8.3.1" set POLARISATION = "SYNCHROTRON 0.9" set DIVERGENCE = "0.10 0.02" # set DISPERSION = "0.00025" set PREAMBLE = "\${PREAMBLE}nBACKSTOP RADIUS 2" set GAIN = 1.8 endif if("\$Site" == "907") then # prior knowledge of SIBYLS beamline set Site = "SIBYLS" set POLARISATION = "SYNCHROTRON 0.9" set DIVERGENCE = "0.10 0.02" # set DISPERSION = "0.00025" endif if("\$Site" == "428" || "\$Site" == "444") then # prior knowledge of ESRF beamline set Site = "ESRF" set mosflm_beam endif if("\$Site" == "443") then # prior knowledge of APS 17ID beamline set Site = "APS 17ID" set mosflm_beam endif if("\$Site" == "415") then # prior knowledge of APS 14 beamline set Site = "APS BIOCARS" set mosflm_beam endif if("\$Site" == "904") then # prior knowledge of APS NE-CAT 8BM beamline set Site = "APS NE-CAT 8BM" set mosflm_beam endif if("\$Site" == "914") then # prior knowledge of APS SBC-CAT 19ID beamline set Site = "APS SBC-CAT 19ID" set mosflm_beam set REVERSEPHI endif set Site = ( \$Site ADSC ) if(("\$Site" == "406 ADSC")||("\$Site" == "414 ADSC")) then # CHESS beamlines set REVERSEPHI endif if("\$Site" == "910 ADSC") then # BIOCARS set REVERSEPHI endif if("\$Site" == "457 ADSC") then # AS MX1 set REVERSEPHI endif if("\$Site" == "928 ADSC") then # AS MX2 set REVERSEPHI endif if("\$Site" == "441 ADSC") then # CHESS set REVERSEPHI endif if("\$Site" == "ALS 4.2.2") then # ALS 4.2.2 CMOS detector set REVERSEPHI set BEAM_IN_PIXELS endif # get the size of the detector face set PIXEL = \`grep "PIXEL_SIZE" \${tempfile}header | nawk -F "=" '\$2+0>0{ print \$2+0}' | tail -1\` set temp = \`grep "SIZE2" \${tempfile}header | nawk -F "=" '\$2+0>0{print \$2+0}' | tail -1\` set Width = 188 if(("\$Site" =~ 44*)&&("\$temp" == 2048)&&("\$PIXEL" == "0.0512")) then # fix brief bug in 8.3.1 history set PIXEL = 0.1024 echo "PIXEL \$PIXEL" >> \${tempfile}.preamble endif if(("\$temp" != "")&&("\$PIXEL" != "")) set Width = \`echo "\$temp \$PIXEL" | nawk '{print \$1*\$2}'\` # get beam center set test = \`nawk '/^DENZO_X_BEAM|^DENZO_XBEAM/' \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` if("\$test" != "") then set RELIABLE_BEAM set mosflm_beam set x_beam = \`nawk '/^DENZO_X_BEAM|^DENZO_XBEAM/' \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` set y_beam = \`nawk '/^DENZO_Y_BEAM|^DENZO_YBEAM/' \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` else # everybody seems to do these differently unset RELIABLE_BEAM set x_beam = \`nawk '/^BEAM_CENTER_X/' \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` set y_beam = \`nawk '/^BEAM_CENTER_Y/' \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` endif if(\$?BEAM_IN_PIXELS) then set x_beam = \`echo \$x_beam \$PIXEL | awk '{print \$1/\$2}'\` set y_beam = \`echo \$y_beam \$PIXEL | awk '{print \$1/\$2}'\` endif # convert beam center from ADXV convention set beam_center = \`echo "\$Width \$x_beam \$y_beam" | nawk '{print \$1-\$3, \$2}'\` # some beamlines put "denzo" beam center in headers if(\$?mosflm_beam) set beam_center = \`echo \$x_beam \$y_beam\` set distance = \`grep "DISTANCE" \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` set two_theta = \`grep "TWOTHETA" \${tempfile}header | nawk -F "=" '{ print -\$2+0}'\` set phi0 = \`egrep "PHI|OSC_START" \${tempfile}header | nawk -F "=" '{ print \$2+0}' | head -1\` set osc = \`grep "OSC_RANGE" \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` # predict twotheta from beam center? set temp = \`echo \$beam_center \$Width | nawk '{print \$NF/2-\$1}'\` set temp = \`echo "\$temp \$distance" | nawk '{printf "%.1f", 180*atan2(\$1,\$2)/3.1415927}'\` set temp = \`echo "\$temp" | nawk '{if(\$1*\$1 < 16){\$1=0}; print \$1}'\` if("\$temp" != "0") then # set two_theta = "\$temp" echo -n "2theta = \$two_theta " endif set two_theta = \`echo "\$two_theta" | nawk '{print \$1+0}'\` set temp = \`grep "CCD_IMAGE_SATURATION" \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` if("\$temp" != "") set OVERLOAD = "\$temp" set temp = \`grep "WAVELENGTH" \${tempfile}header | nawk -F "=" '/^WAVE/{ print \$2+0}' \${tempfile}header | tail -1\` if("\$temp" == "") then set temp = \`grep "WAVELENGTH" \${tempfile}header | nawk -F "=" '{ print \$2+0}' | tail -1\` endif if("\$temp" != "") set wavelength = "\$temp" echo -n "\$wavelength \$ANG " # set last frame to last file in frame directory ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # set LastImage = \`ls -lnL \${framedir} |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& egrep "\${framepattern}" |& tail -1\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` echo -n "\$first-\$last " # guess high resolution limit from detector geometry #set temp = \`echo "\$Width / 2 " | bc\` set temp = \`echo \$Width | nawk '{print \$1/2}'\` set edge_res = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set temp = \`echo "\$Width" | nawk '{print \$1/2}'\` # edge set temp = \`echo "\$Width" | nawk '{print \$1/1.4142}'\` # corner # set temp = \`echo "\$Width" | nawk '{print \$1/1.7}'\` # compromize set hires = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set up scanner dimensions set temp = \`echo \$Width | nawk '{printf "%.0f", \$1 / 1.4142}'\` set SCANNER = "SCANNER omega 90 ROTATION horiz ANTI FAST horiz ORIGIN UR RECTANG ADSC" if(\$?REVERSEPHI) then set SCANNER = "SCANNER omega 90 ROTATION horiz CLOCK FAST horiz ORIGIN UR RECTANG ADSC" endif # mosflm will read this header wrong if("\$Site" == "910 ADSC") set BAD_HEADER set LIMITS = "LIMITS RMAX 9999 YMAX \$Width XMAX \$Width xscan \$Width yscan \$Width" # X-Y scale does not vary on the CCD set fixyscale = yes # these variables are now out of scope unset x_beam unset y_beam unset img rm -f \${tempfile}header >& /dev/null rm -f \${tempfile}headertext >& /dev/null echo "" # skip rest of scans continue endif #### ##### ###### # # # ## #### ###### # # # # # # ## ## # # # # # # ##### ##### # # ## # # # # ##### # # # # # # # ###### # ### # # # # # # # # # # # # # # #### ##### # # # # # # #### ###### # CBF files begin with "###CBF: VERSION " if("\$format" == CBF) then echo -n "Scanning \$source ... " # shorthand set img = \$source ############################################################################### # Read in parameters from an image file # ############################################################################### # \$img should be set to the location of the CBF image file # following variables will be inilialized using this file's header: # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # phi - oscillation start (degrees) # osc - oscillation range (degrees) # wavelength - wavelength (according to the header) # overload - maximum pixel value # Site - the detector serial number (or text of site) # # framedir - directory where this file exists # frameprefix - image filename (minus batch number and underscore) # first - batch number of this frame # last - largest batch number with same prefix # # Width - detector width (mm) # PIXEL - pixel size (mm) # set GAIN = 1 unset mosflm_beam # get frame header nawk 'BEGIN{RS="\\f"} {gsub("\\r","\\n");print;exit}' \$img >! \${tempfile}header set Site = \`grep "# Detector:" \${tempfile}header | nawk '{ print \$NF,\$3}'\` if("\$Site" == "X06SA@SLS.PSI.CH PILATUS") then # prior knowledge? endif if("\$Site" == "60-0134 PILATUS3") then # prior knowledge? set Site = "ALS 8.3.1" set SCANNER = "DETECTOR PILATUS" endif set Site = ( \$Site ) # get the size of the detector face set PIXEL = \`egrep -i "pixel_size" \${tempfile}header | nawk '\$3+0>0{ print \$3*1e3}' | tail -1\` set xysize = \`grep "Binary-Size" \${tempfile}header | nawk '/imension/ && \$2+0>0{print \$2+0}' | tail -2\` set Width = 434 set xWidth = \`echo \$xysize \$PIXEL | awk '{print \$1*\$3}'\` set yWidth = \`echo \$xysize \$PIXEL | awk '{print \$2*\$3}'\` if(("\$xysize" != "")&&("\$PIXEL" != "")) set Width = \`echo "\$xysize \$PIXEL" | nawk '{print (\$2-1)*\$NF}'\` # get beam center set test = \`grep -i beam \${tempfile}header | nawk -F "[ (),]" '/pixels/{for(i=2;i<=NF;++i)if(\$i+0!=0) print \$i}'\` if(\$#test == 2) then # set UNRELIABLE_BEAM set x_beam = \`echo \$test \$PIXEL | awk '{print \$1*\$3}'\` set y_beam = \`echo \$test \$PIXEL | awk '{print \$2*\$3}'\` endif # convert beam center from CBF convention set beam_center = \`echo "\$Width \$x_beam \$y_beam" | nawk '{print \$3, \$2}'\` # some beamlines put "denzo" beam center in headers? if(\$?mosflm_beam) set beam_center = \`echo \$x_beam \$y_beam\` set distance = \`grep -i "distance" \${tempfile}header | nawk '\$4~/^m/{ print \$3*1000}'\` set two_theta = \`grep -i "twotheta" \${tempfile}header | nawk '\$4~/^deg/{ print \$3}'\` set phi0 = \`egrep -i "Start_angle" \${tempfile}header | nawk '\$4~/^deg/{ print \$3+0}' | head -1\` set osc = \`grep -i "Angle_incr" \${tempfile}header | nawk '\$4~/^deg/{ print \$3+0}'\` set two_theta = \`echo "\$two_theta" | nawk '{print \$1+0}'\` set temp = \`grep -i "wavelength" \${tempfile}header | nawk '\$4=="A" || \$4=="A."{print \$3+0}' | tail -1\` if("\$temp" != "") set wavelength = "\$temp" echo -n "\$wavelength \$ANG " # set last frame to last file in frame directory ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # set LastImage = \`ls -lnL \${framedir} |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& egrep "\${framepattern}" |& tail -1\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` echo -n "\$first-\$last " # guess high resolution limit from detector geometry #set temp = \`echo "\$Width / 2 " | bc\` set temp = \`echo \$Width | nawk '{print \$1/2}'\` set edge_res = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set temp = \`echo "\$Width" | nawk '{print \$1/2}'\` # edge set temp = \`echo "\$Width" | nawk '{print \$1/1.4142}'\` # corner # set temp = \`echo "\$Width" | nawk '{print \$1/1.7}'\` # compromize set hires = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # let MOSFLM figure it out?... set SCANNER = "" set LIMITS = "" set SCANNER = "DETECTOR PILATUS" # set LIMITS = "LIMITS RMAX 500 YMAX \$yWidth XMAX \$xWidth xscan \$xWidth yscan \$yWidth" # X-Y scale does not vary set fixyscale = yes # these variables are now out of scope unset x_beam unset y_beam unset img rm -f \${tempfile}header >& /dev/null rm -f \${tempfile}headertext >& /dev/null echo "" # skip rest of scans continue endif #### ##### #### # # # ## #### ###### # # # # # # ## ## # # # # # #### ##### # # # ## # # # # ##### # # # # # # # ###### # ### # # # # # # # # # # # # # # # #### ##### #### # # # # # #### ###### # SBC files are in SMV format, but all keywords are different from ADSC if("\$format" == SBC) then echo -n "Scanning \$source ... " # shorthand set img = \$source ############################################################################### # Read in parameters from an image file # ############################################################################### # \$img should be set to the location of the SMV image file # following variables will be inilialized using this file's header: # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # phi - oscillation start (degrees) # osc - oscillation range (degrees) # wavelength - wavelength (according to the header) # overload - maximum pixel value # Site - the detector serial number (or text of site) # # framedir - directory where this file exists # frameprefix - image filename (minus batch number and underscore) # first - batch number of this frame # last - largest batch number with same prefix # # Width - detector width (mm) # PIXEL - pixel size (mm) # set GAIN = 1 # get SMV frame header nawk 'BEGIN{RS="\\f"} {print;exit}' \$img >! \${tempfile}header set Site = "APS SBC" # get the size of the detector face set PIXEL = \`grep "SPATIAL_DISTORTION_INFO" \${tempfile}header | nawk '\$4+0>0{ print \$4+0}' | tail -1\` set pixels = \`grep "DETECTOR_DIMENSIONS" \${tempfile}header | nawk -F "=" '\$2+0>0{print \$2+0}' | tail -1\` set Width = \`grep "DETECTOR_SIZE" \${tempfile}header | nawk '\$2+0>0{print \$2+0}' | tail -1\` if("\$PIXEL" == "" && "\$Width" != "" && "\$pixels" != "") then set PIXEL = \`echo "\$Width \$pixels" | nawk '{print \$1/\$2}'\` endif if("\$Width" == "" && "\$PIXEL" != "" && "\$pixels" != "") then set Width = \`echo "\$pixels \$PIXEL" | nawk '{print \$1*\$2}'\` endif # get beam center set x_beam = \`grep "BEAM_POSITION" \${tempfile}header | nawk -v pix=\$PIXEL '{print \$3*pix}'\` set y_beam = \`grep "BEAM_POSITION" \${tempfile}header | nawk -v pix=\$PIXEL '{print \$2*pix}'\` # convert beam center to mosflm convention set beam_center = ( \$x_beam \$y_beam ) set distance = \`grep "GONIO_VALUES" \${tempfile}header | grep -v CRYSTAL | nawk '{ print \$NF+0}'\` set phi0 = \`grep "ROTATION_START" \${tempfile}header | nawk -F "=" '{ print \$2+0}'\` set osc = \`grep "ROTATION" \${tempfile}header | nawk -F "=" '/_START/{start=\$2+0} /_END/{end=\$2+0} END{print end-start}'\` set temp = \`grep "WAVELENGTH" \${tempfile}header | nawk -F "[= ]" '{ print \$NF+0}' | tail -1\` if("\$temp" != "") set wavelength = "\$temp" echo -n "\$wavelength \$ANG " # set last frame to last file in frame directory ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # set LastImage = \`ls -lnL \${framedir} |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& egrep "\${framepattern}" |& tail -1\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` echo -n "\$first-\$last " # guess high resolution limit from detector geometry #set temp = \`echo "\$Width / 2 " | bc\` set temp = \`echo \$Width | nawk '{print \$1/2}'\` set edge_res = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set temp = \`echo "\$Width" | nawk '{print \$1/2}'\` # edge set temp = \`echo "\$Width" | nawk '{print \$1/1.4142}'\` # corner # set temp = \`echo "\$Width" | nawk '{print \$1/1.7}'\` # compromize set hires = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set up scanner dimensions set temp = \`echo \$Width | nawk '{printf "%.0f", \$1 / 1.4142}'\` set SCANNER = "DETECTOR SBC1 REVERSEPHI" set LIMITS = "" set PREAMBLE = "\${PREAMBLE}nPIXEL \$PIXEL" # set SCANNER = "SCANNER omega 90 ROTATION horiz ANTI FAST horiz ORIGIN UR RECTANG TYPE ADSC" # set LIMITS = "LIMITS RMAX \$temp YMAX \$Width XMAX \$Width xscan \$Width yscan \$Width" # X-Y scale does not vary on the CCD set fixyscale = yes # these variables are now out of scope unset x_beam unset y_beam unset img rm -f \${tempfile}header >& /dev/null echo "" # skip rest of scans continue endif ##### ## # # # #### #### # # # # # # # # # # # # # ## ## # # # # # # ## # #### #### # ## # # # ##### ###### ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #### #### # # # # new Rigaku files are in SMV format, but all keywords are different from ADSC if("\$format" == RAXIS_SMV) then set RAXIS_SMV echo -n "Scanning \$source ... " # shorthand set img = \$source ############################################################################### # Read in parameters from an image file # ############################################################################### # \$img should be set to the location of the SMV image file # following variables will be inilialized using this file's header: # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # phi - oscillation start (degrees) # osc - oscillation range (degrees) # wavelength - wavelength (according to the header) # overload - maximum pixel value # Site - the detector serial number (or text of site) # # framedir - directory where this file exists # frameprefix - image filename (minus batch number and underscore) # first - batch number of this frame # last - largest batch number with same prefix # # Width - detector width (mm) # PIXEL - pixel size (mm) # set LIMITS = "" # set size = \`ls -lnL \$source |& nawk '{print \$5+0}'\` # default: R-axis 4 set Site = "RAXIS4" set SCANNER = "DETECTOR RAXIS4" set GAIN = 1 set PIXEL = 0.100 #set OVERLOAD = "262135" # get SMV frame header nawk 'BEGIN{RS="\\f"} {gsub("="," = ");print;exit}' \$img >! \${tempfile}header # check for explicit detector type set test = \`grep "DETECTOR_DESCRIPTION" \${tempfile}header | nawk -F "=" '{ print \$2}' | head -1 | awk '{print \$1}'\` if("\$test" =~ Saturn*) then set Site = "\$test" set SCANNER = "DETECTOR Saturn" endif if("\$test" =~ Jupiter*) then set Site = "\$test" set SCANNER = "DETECTOR Jupiter" endif # get the size of the detector face set PIXEL = \`grep "SPATIAL_DISTORTION_INFO" \${tempfile}header | nawk '\$4+0>0{ print \$4+0}' | tail -1\` set temp = \`grep "DETECTOR_DIMENSIONS" \${tempfile}header | nawk -F "=" '\$2+0>0{print \$2+0}' | tail -1\` set Width = \`grep "DETECTOR_SIZE" \${tempfile}header | nawk -F "=" '\$2+0>0{print \$2+0}' | tail -1\` # set Width = \`echo "\$temp \$PIXEL" | nawk '{print \$1*\$2}'\` set test = \`echo "\$temp \$Width" | nawk '\$2+0>0 && \$1+0>0{print \$2/\$1}'\` if("\$test" != "") set PIXEL = \$test # get beam center set x_beam = \`grep "BEAM_POSITION" \${tempfile}header | nawk -F "=" '{print \$2;exit}' | nawk -v pix=\$PIXEL '{print \$2*pix}'\` set y_beam = \`grep "BEAM_POSITION" \${tempfile}header | nawk -F "=" '{print \$2;exit}' | nawk -v pix=\$PIXEL '{print \$1*pix}'\` # convert beam center to mosflm convention set beam_center = ( \$x_beam \$y_beam ) set test = \`nawk '/GONIO_NAMES/{for(i=2;i<=NF;++i)if(tolower(\$i)~"distan")di=i} /GONIO_VALUES / && di && NF>=di{print \$di+0;exit}' \${tempfile}header \` if("\$test" != "") set distance = "\$test" set test = \`nawk '/GONIO_NAMES/{for(i=2;i<=NF;++i)if(tolower(\$i)~"2theta")ti=i} /GONIO_VALUES / && ti && NF>=ti{print \$ti+0;exit}' \${tempfile}header \` if("\$test" != "") set twotheta = "\$test" set phi0 = \`nawk -F "=" '/^ROTATION /{print \$2}' \${tempfile}header | nawk '{ print \$1+0}'\` set osc = \`nawk -F "=" '/^ROTATION /{print \$2}' \${tempfile}header | nawk '{print \$2-\$1}'\` set temp = \`grep "WAVELENGTH" \${tempfile}header | nawk -F "[= ]" '\$NF+0>0{ print \$NF+0}' | tail -1\` if("\$temp" != "") set wavelength = "\$temp" echo -n "\$wavelength \$ANG " # set last frame to last file in frame directory ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # set LastImage = \`ls -lnL \${framedir} |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& egrep "\${framepattern}" |& tail -1\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` echo -n "\$first-\$last " # guess high resolution limit from detector geometry #set temp = \`echo "\$Width / 2 " | bc\` set temp = \`echo \$Width | nawk '{print \$1/2}'\` set edge_res = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set temp = \`echo "\$Width" | nawk '{print \$1/2}'\` # edge set temp = \`echo "\$Width" | nawk '{print \$1/1.4142}'\` # corner # set temp = \`echo "\$Width" | nawk '{print \$1/1.7}'\` # compromize set hires = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set up scanner dimensions set temp = \`echo \$Width | nawk '{printf "%.0f", \$1 / 1.4142}'\` # set SCANNER = "DETECTOR RAXIS4" set LIMITS = "" # set PREAMBLE = "\${PREAMBLE}n" # X-Y scale does not vary? set test = \`nawk '/^CCD/{print 1;exit}' \${tempfile}header\` if("\$test" == "1") then # probably a CCD detector set fixyscale = yes else set fixyscale = no endif # these variables are now out of scope unset x_beam unset y_beam unset img rm -f \${tempfile}header >& /dev/null echo "" # skip rest of scans continue endif ##### ## # # # #### # # # ## #### ###### # # # # # # # # # ## ## # # # # # # # # # ## # #### # # ## # # # # ##### ##### ###### ## # # # # # ###### # ### # # # # # # # # # # # # # # # # # # # # # # # # # #### # # # # # #### ###### # if((\$source == "\$FirstImage")&&("\$ext" == "osc")) then # if(\$source =~ *.osc) then # all RAXIS formats begin with "R-AXIS" if("\$format" == RAXIS) then echo -n "Scanning \$source ... " ############################################################################### # Read in parameters from an raxisII image file # ############################################################################### # \$img should be set to the location of the raxis image file # following variables will be inilialized using this file's header: # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # phi - oscillation start (degrees) # osc - oscillation range (degrees) # wavelength - wavelength (according to the header) # overload - maximum pixel value # Site - the detector serial number (or text of site) # # framedir - directory where this file exists # frameprefix - image filename (minus batch number and underscore) # first - batch number of this frame # last - largest batch number with same prefix # # Width - detector size (mm) # PIXEL - pixel size in mm (0.105) # set LIMITS = "" set GAIN = 5 set size = \`ls -lnL \$source |& nawk '{print \$5+0}'\` set type = \`ood -cv \$source |& nawk '{print \$2 \$3 \$4 \$5 \$6 \$7 \$8; exit}'\` set fixyscale = no # default: R-axis 4 set Site = "RAXISIV" set SCANNER = "SCANNER RAXISIV" set GAIN = 1 set PIXEL = 0.100 #set OVERLOAD = "262135" if("\$type" == "R-AXIS2") then set Site = "RAXIS II" set SCANNER = "SCANNER RAXIS" set OVERLOAD = "262135" set PIXEL = "0.105" endif if(("\$type" == "R-AXIS5")||(\$size > 30000000)) then set Site = "RAXISV" # will this work with old version? # check if we have mosflm 6.10? set SCANNER = "SCANNER ROTATION vert anti FAST horiz ORIGIN lr RECT RAXISV" set GAIN = 1 # echo "PIXEL 0.1 0.1" >> \${tempfile}.preamble # echo "SIZE 4000 4000" >> \${tempfile}.preamble # header seems to be the same as RAXISII set PIXEL = 0.100 set OVERLOAD = "1100000" endif if("\$Site" =~ RAXIS*) then echo -n "\$Site " # use octal dump program to get header values set temp = \`od -c -j 76 -N 20 \$source | head -1 | nawk '{print substr(\$0, 1, 55)}'\` set temp = \`echo "\$temp" | nawk 'BEGIN{RS=" "} NR>1 && /[PpCcIiFfRrHh12346]/ {printf "%s", \$0}'\` if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) then set SG = \`echo "\$temp" | nawk '{print toupper(\$1)}'\` endif # get size of the detector face (maybe swap bytes latter) set h_size = \`od -d -j 788 -N 8 \$source | nawk '{print \$2+\$3; exit}'\` set v_size = \`od -d -j 768 -N 8 \$source | nawk '{print \$2+\$3; exit}'\` if(("\$h_size" > 10000)||("\$h_size" < 1000)) then # swap bytes for 2-byte values set h_size = \`echo \$h_size | nawk '{printf "%d", (\$1%256)*256 + \$1/256}'\` set v_size = \`echo \$v_size | nawk '{printf "%d", (\$1%256)*256 + \$1/256}'\` endif # now read monochromater info set temp = \`od -c -j 296 -N 20 \$source | head -1 | nawk 'BEGIN{RS=" "} /[a-z,A-Z]/ {printf "%s", \$0}'\` set temp = \`echo \$temp | nawk '{print toupper(\$1)}'\` if("\$temp" =~ GRAPH*) then # graphite set POLARISATION = "MONOCHROMATOR" else # unpolarized set POLARISATION = "MIRRORS" endif set phi = "" # convert header into every possible byte-swapping convention set best = "0.1 1234" set address = 780 foreach swap ( 1234 4321 3412 2143 5143 3416 ) set swap = \`echo "\$swap" | nawk '{print "\$"substr(\$1,1,1)",\$"substr(\$1,2,1)",\$"substr(\$1,3,1)",\$"substr(\$1,4,1)}'\` set bytes = \`od -vb -j \$address -N 4 \$source | nawk '{for(i=2;i<=5;++i){printf "%d ", 64*substr(\$i,1,1)+8*substr(\$i,2,1)+substr(\$i,3,1)};exit}'\` set bytes = \`echo \$bytes | nawk '{w=x=\$2} \$1+\$2+\$3+\$4==0{--w;++x} {print \$0, w,x-1}'\` set vpix = \`echo "\$bytes" | nawk '{printf "%c%c%c%c", '\$swap'}' | ood -f | nawk '{print \$2+0;exit}'\` set best = \`echo 0.1 \$vpix \$best \$swap | nawk '{diff=sqrt((\$1-\$2)^2); if(diff<\$3){print diff, \$5}else{print \$3, \$4}}'\` end # choose the convention that gave the closest-to-expected result set swap = \`echo \$best | nawk '\$2~/[,]/{print \$2}'\` # make sure its safe to try and read these if("\$swap" != "") then # extract floating-point variables echo -n "" >! \${tempfile}header_floats foreach address ( 524 528 344 556 776 780 540 544 292 52 56 60 64 68 72 88 ) od -vb -j \$address -N 4 \$source |\\ nawk '{for(i=2;i<=5;++i){printf "%d ", 64*substr(\$i,1,1)+8*substr(\$i,2,1)+substr(\$i,3,1)};exit}' |\\ nawk '{w=x=\$2} \$1+\$2+\$3+\$4==0{--w;++x} {print \$0, w, x-1}' |\\ nawk '{printf "%c%c%c%c", '\$swap'}' | ood -f |\\ nawk -v address=\$address '{print address, \$2+0;exit}' |\\ cat >> \${tempfile}header_floats end set phi = \`nawk '\$1==524{print \$2;exit}' \${tempfile}header_floats\` set phiend = \`nawk '\$1==528{print \$2;exit}' \${tempfile}header_floats\` set distance = \`nawk '\$1==344{print \$2;exit}' \${tempfile}header_floats\` set two_theta = \`nawk '\$1==556{print \$2;exit}' \${tempfile}header_floats\` # R-axis has Y= fast axis and X= slow axis (mosflm knows this) set h_pixel = \`nawk '\$1==776{print \$2;exit}' \${tempfile}header_floats\` set v_pixel = \`nawk '\$1==780{print \$2;exit}' \${tempfile}header_floats\` set h_beam = \`nawk '\$1==540{print \$2;exit}' \${tempfile}header_floats\` set v_beam = \`nawk '\$1==544{print \$2;exit}' \${tempfile}header_floats\` set wavelength = \`nawk '\$1==292{print \$2;exit}' \${tempfile}header_floats\` set a = \`nawk '\$1==52{print \$2;exit}' \${tempfile}header_floats\` set b = \`nawk '\$1==56{print \$2;exit}' \${tempfile}header_floats\` set c = \`nawk '\$1==60{print \$2;exit}' \${tempfile}header_floats\` set alpha = \`nawk '\$1==64{print \$2;exit}' \${tempfile}header_floats\` set beta = \`nawk '\$1==68{print \$2;exit}' \${tempfile}header_floats\` set gamma = \`nawk '\$1==72{print \$2;exit}' \${tempfile}header_floats\` if("\$fixmosaicity" != "yes") then set mosaic = \`nawk '\$1==88 && \$2+0>0.1{print \$2; exit}' \${tempfile}header_floats\` endif rm -f \${tempfile}header_floats >& /dev/null endif if("\$phi" == "") then echo -n "unable to read header. " else # calculate oscillation angle set phi0 = "\$phi" #set osc = \`echo "\$phiend - \$phi" | bc\` set osc = \`echo \$phiend \$phi | nawk '{print \$1-\$2}'\` # calculate beam center in mm set beam_center = \`echo \$v_beam \$v_pixel \$h_beam \$h_pixel | nawk '{print \$1*\$2, \$3*\$4}'\` # set yscale = \`echo "\$v_pixel \$h_pixel" | nawk '{print \$1 / \$2}'\` set PIXEL = "\$h_pixel" set Width = \`echo "\$h_pixel \$h_size" | nawk '{print \$1*\$2}'\` # set high resolution limit and detector geometry #set temp = \`echo "\$Width / 2 " | bc\` set temp = \`echo \$Width | nawk '{print \$1/2}'\` set edge_res = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` # set temp = \`echo "\$Width" | nawk '{print \$1/2}'\` # edge set temp = \`echo "\$Width" | nawk '{print \$1/1.4142}'\` # corner # set temp = \`echo "\$Width" | nawk '{print \$1/1.7}'\` # compromize set hires = \`echo "\$wavelength \$temp \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2, \$3)/2))}'\` set temp = \`echo \$a | nawk '{printf "%d", \$1}'\` if(\$temp > 10) then # don't read stupid cells set CELL = \`echo \$a \$b \$c \$alpha \$beta \$gamma\` endif endif # unset uneeded variables unset phi unset phiend unset h_beam unset v_beam unset h_pixel unset v_pixel unset a unset b unset c unset alpha unset beta unset gamma else set Site = "RAXISIV" set SCANNER = "SCANNER RAXISIV" echo -n "\$Site " # how do you read these? set PIXEL = 0.100 endif # set last frame to last file in frame directory ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # set LastImage = \`ls -lnL \${framedir} |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& egrep "\${framepattern}" |& tail -1\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` echo -n " \$first-\$last " rm -f \$tempfile >& /dev/null echo "" # skip rest of scans continue endif # # ## ##### # # # ## #### ###### ## ## # # # # # ## ## # # # # # # ## # # # # # # # ## # # # # ##### # # ###### ##### # # # ###### # ### # # # # # # # # # # # # # # # # # # # # # # # # # # #### ###### # if(\$source =~ *[0-9][0-9][0-9].mar*) then if("\$format" == MAR) then echo -n "Scanning \$source ... " # shorthand set img = "\$source" ############################################################################### # Read in parameters from an image file # ############################################################################### # \$img should be set to the location of the MAR image file # following variables will be inilialized using this file's header: # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # phi - oscillation start (degrees) # osc - oscillation range (degrees) # wavelength - wavelength (according to the header) # overload - maximum pixel value # Site - the detector serial number (or text of site) # # framedir - directory where this file exists # frameprefix - image filename (minus batch number and underscore) # first - batch number of this frame # last - largest batch number with same prefix # # Width - detector size (mm) # PIXEL - pixel size (mm) # # get variables from MAR frame header # get pixel size (in mm) set PIXEL = \`head -56 \$img | nawk '/^PIXEL/{ print \$3/1000, \$NF/1000}'\` if(\$#PIXEL != 2) then echo "bad MAR header! " continue endif set Site = \`head -56 \$img | nawk '/^PROGRAM/{ print \$2}'\` set Width = 345 set temp = \`head -56 \$img | nawk '/^FORMAT/ && \$2+0>0{ print \$2}'\` if("\$temp" != "") set Width = \`echo \$temp \$PIXEL | nawk '{print \$1*\$2}'\` set Site = \`echo \$Site \$Width | nawk '{printf "%s %dmm", \$1, \$2}'\` # convert beam center set temp = \`head -56 \$img | nawk -v pixx=\$PIXEL[1] -v pixy=\$PIXEL[2] '/^CENTER/{print \$3*pixx, \$5*pixy}'\` if(\$#temp == 2) then set beam_center = \`echo \$temp\` endif # get twotheta from image header set two_theta = \`head -56 \$img | nawk '/^TWOTHETA/{ print \$2+0}'\` set distance = \`head -56 \$img | nawk '/^DISTANCE/{ print \$2+0}'\` set phi0 = \`head -56 \$img | nawk '/^PHI/{print}' | nawk 'BEGIN{RS=" "} /START/{getline; print \$0+0}'\` set osc = \`head -56 \$img | nawk '/^PHI/{print}' | nawk 'BEGIN{RS=" "} /OSC/{getline; print \$0+0}'\` # set OVERLOAD = what? set wavelength = \`head -56 \$img | nawk '/^WAVELEN/{ print \$2+0}' | tail -1\` echo -n "\$wavelength \$ANG " # set last frame to last file in frame directory ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # set LastImage = \`ls -lnL \${framedir} |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& egrep "\${framepattern}" |& tail -1\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` echo -n "\$first-\$last " # get high resolution limit from frame header set temp = \`head -56 \$img | nawk '/^RESOL/&&\$2+0>0.1{print \$2+0}'\` if("\$temp" != "") set hires = "\$temp" # set up scanner dimensions set SCANNER = "SCANNER MAR" set LIMITS = "" set PIXEL = "\$PIXEL[1]" echo "" # skip rest of scans continue endif # # ## ##### #### #### ##### ## ## # # # # # # # # # # # ## # # # # # # # # # # # ###### ##### # # # # # # # # # # # # # # # # # # # # # # #### #### ##### if("\$format" == MARCCD) then echo -n "Scanning \$source ... " # shorthand set img = "\$source" ############################################################################### # Read in parameters from an image file # ############################################################################### # \$img should be set to the location of the MAR image file # following variables will be inilialized using this file's header: # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # phi - oscillation start (degrees) # osc - oscillation range (degrees) # wavelength - wavelength (according to the header) # overload - maximum pixel value # Site - the detector serial number (or text of site) # # framedir - directory where this file exists # frameprefix - image filename (minus batch number and underscore) # first - batch number of this frame # last - largest batch number with same prefix # # Width - detector size (mm) # PIXEL - pixel size (mm) # set Site = "MAR CCD" set fixyscale = yes # dump MARCCD header bytes (convert to decimal) od -bv -j 1024 -N 1024 \$source |\\ nawk '{for(i=2;i<=NF;++i){print 64*substr(\$i,1,1)+8*substr(\$i,2,1)+substr(\$i,3,1)}}' |\\ nawk 'NR%4==1{printf "\\n%d ", NR+1023} {printf "%d ", \$1}' |\\ nawk '/^1052 210 4 0 0/{little=1} /^1052 0 0 20 341/{big=1} \\ little{print \$1, (\$2+256*(\$3+256*(\$4+256*\$5)))-(2^32)*(\$5>=128)} \\ big{print \$1, (\$5+256*(\$4+256*(\$3+256*\$2)))-(2^32)*(\$2>=128)}' |\\ cat >! \${tempfile}header # dump header text too od -av -j 2048 -N 1024 \$source |\\ nawk '{for(i=2;i<=NF;++i){print \$i}}' |\\ nawk '\$1=="sp"{\$1=" "} length(\$1)>1{print "";next} {printf "%s",\$1}' |\\ nawk 'NF>0' |\\ cat >! \${tempfile}headertext set SN = \`nawk '/Detector Serial/{print \$NF}' \${tempfile}headertext\` set test = \`nawk '/Gain setting /{print \$NF}' \${tempfile}headertext\` if("\$test" != "") set GAIN = "\$test" # get pixel size (in mm) set PIXEL = \`nawk '/^1796 / || /^1800 /{ print \$2/1000000}' \${tempfile}header\` if(\$#PIXEL != 2) then echo "cannot read MARCCD header! " set PIXEL = "0.079108" rm -f \${tempfile}header >! /dev/null continue endif # detector size (fast axis) set Width = 162 set temp = \`nawk '/^1104 / && \$2+0>0{ print \$2}' \${tempfile}header\` if("\$temp" != "") then set Width = \`echo "\$temp \$PIXEL" | nawk '{print \$1*\$2}'\` endif # get beam center set temp = \`nawk '/^1668 / || /^1672 /{ print \$2/1000}' \${tempfile}header\` if((\$#temp == 2)&&("\$temp" != "0 0")) then set beam_center = \`echo \$PIXEL \$temp | nawk '{print \$1*\$3, \$2*\$4}'\` set beam_center = \`echo \$beam_center | nawk '{print \$2,\$1}'\` set test = \`echo \$beam_center \$Width | nawk '{print ((\$1*\$1 < 0.01*\$3*\$3) && (\$2*\$2 < 0.01*\$3*\$3))}'\` if(\$test) then # probably from ESRF, they use mm instead of pixels set beam_center = ( \$temp ) endif else echo -n "beam center missing! " set beam_center = \`echo "\$Width" | nawk '{print \$1/2, \$1/2}'\` endif # get twotheta from image header set two_theta = \`nawk '/^1692 /{ print \$2/1000}' \${tempfile}header\` set distance = \`nawk '/^1720 /{ print \$2/1000}' \${tempfile}header\` set phi0 = \`nawk '/^1708 /{ print \$2/1000}' \${tempfile}header\` set phi_end = \`nawk '/^1740 /{ print \$2/1000}' \${tempfile}header\` set osc = \`nawk '/^1760 /{ print \$2/1000}' \${tempfile}header\` set test = \`echo \$osc | nawk '{print (\$1<=0)}'\` if (\$test) then set osc = \`echo "\$phi0 \$phi_end" | nawk '{print \$2-\$1}'\` else set phi_end = \`echo "\$phi0 \$osc" | nawk '{print \$2+\$1}'\` endif set OVERLOAD = \`nawk '/^1128 /{ print \$2}' \${tempfile}header\` set wavelength = \`nawk '/^1932 /{ print \$2/100000}' \${tempfile}header\` echo -n "\$wavelength \$ANG " # set last frame to last file in frame directory ls -lnL \${framedir} |&\\ nawk -v first=\`basename \$FirstImage\` '\$NF==first{++p} /^\\-/ && \$5+0 > 800000 && p {print \$NF}' |&\\ nawk -v template=\$template 'BEGIN{gsub("[+]","\\\\+",template); n=split(template,w,"\\043")}\\ \$1 ~ "^"w[1] && \$1 ~ w[n]"\$" {print substr(\$1,length(w[1])+1)+0, \$1}' |\\ nawk 'NR>1 && \$1 != last+1{print lastfile} {last=\$1;lastfile=\$2} END{print lastfile}' |\\ cat >! \${tempfile} set LastImage = \`nawk '{print; exit}' \${tempfile}\` rm -f \${tempfile} >& /dev/null # set LastImage = \`ls -lnL \${framedir} |& nawk '/^\\-/ && \$5+0 > 800000 {print \$NF}' |& egrep "\${framepattern}" |& tail -1\` set last = \`echo "\$LastImage \$template" | nawk '{n=split(\$1,a,"[\\057]"); print int(substr(a[n],index(\$2,"\\043"))+0)}'\` echo -n "\$first-\$last " # calculate high resolution limit from frame size set edge_res = \`echo "\$wavelength \$Width \$distance" | nawk '{printf "%.1f\\n", \$1/(2*sin(atan2(\$2/2, \$3)/2))}'\` set hires = "\$edge_res" set extras = "" if("\$SN" == "15") set extras = "REVERSEPHI" # MOSFLM does not read BIOCARS headers properly if("\$SN" == "32") set BAD_HEADER # set up scanner dimensions set SCANNER = "DETECTOR MARCCD \$extras" set LIMITS = "" set PIXEL = "\$PIXEL[1]" echo "" # skip rest of scans continue endif # #### #### ###### # # ###### # # # # # # # # # # # # # ##### # # ##### # # # # ### # # # # # # # # # # # # # ###### #### #### # # ###### ###### if((\$source == "\$lastlog")||(\$source =~ *.log)) then echo -n "Scanning \$source ." ############################################################################### # compute average parameters from the last mosflm run # # Values for beam_center, distance, mosaicity, missetting angles, # and CELL (if informative) # # ############################################################################### # get beam center and distance nawk '/Processing Image/{print gather} \\ /XTOFD/{getline; gather = \$0} END{print gather}' \$lastlog >! \$tempfile # compute the average values # get beam center set temp = \`nawk 'NF>6{++i; x+=\$1; y+=\$2} END{if(i) print x/i, y/i}' \$tempfile\` if(\$#temp == 2) then # verify that both values are numbers if((\$temp[1] =~ [1-9]*)&&(\$temp[2] =~ [1-9]*)) then set beam_center = \`echo \$temp\` # guess this must be better than the one in the header? unset UNRELIABLE_BEAM endif endif echo -n "." # get distance set temp = \`nawk 'NF>6{++i; dist+=\$4} END{if(i) print dist/i}' \$tempfile\` if(\$#temp == 1) then if(\$temp[1] =~ [1-9]*) set distance = "\$temp" endif # update twotheta set tilt = \`nawk 'NF>6{++i; tilt+=\$6} END{if(i) print tilt/i/100}' \$tempfile\` if("\$tilt" != "") then # avoid huge shifts? set tilt = \`echo "\$tilt 0.1" | nawk '\$1*\$1>\$2*\$2{\$1=\$2*(\$1/sqrt(\$1*\$1))} {printf "%.2f", \$1}'\` set test = \`echo \$two_theta | nawk '{printf "%.0f", \$1}'\` if( "\$test" != 0 ) then # set two_theta = \`echo \$two_theta \$tilt | nawk '{print \$1+\$2}'\` endif endif rm -f \$tempfile # read an estimated mosaicity if("\$mosaic" !~ *[0-9]*) then set temp = \`nawk '/mosaicity has been estimated/ && \$8+0>0.1 && \$8+0<5{print \$8}' \$lastlog | head -1\` if("\$temp" != "") then set mosaic = "\$temp" else if("\$ESTIMATING" == "mosaic spread") then echo "mosaic spread estimation failed." set temp = 1 if(\$?osc) then set temp = \$osc endif set mosaic = \`echo \$temp | nawk '\$1+0<0.1{\$1=1} {print \$1/2}'\` set ESTIMATING = "" endif endif endif # get mosaicity cat \$lastlog |\\ nawk '/Mosaic spread/{getline; if(\$1 == "New"){print \$NF}}' |\\ nawk '{avg += \$1; ++n;v[n]=\$1} \\ max+0<\$1 {sec=max; max = \$1}\\ END{if(n) {avg/=n;\\ for(i=1;i<=n;++i){ms += (v[i]-=avg)^2};\\ print avg, sqrt(ms/n), max, sec}}' |\\ cat >! \$tempfile # average set temp = \`nawk '{print \$1}' \$tempfile\` # average + 1sd set temp = \`nawk '{print \$1+\$2}' \$tempfile\` ######### largest (refined value) ########set temp = \`nawk '{print \$3}' \$tempfile\` ######### 2nd largest ########set temp = \`nawk '{print \$NF}' \$tempfile\` if((\$#temp == 1)&&("\$fixmosaicity" != "yes")) then if(\$temp[1] =~ [0-5].[0-9]*) set mosaic = "\$temp" # echo -n "mosaicity = \$mosaic " endif rm -f \$tempfile echo -n "." # see if this was an integration run # if log was postref only, CELL will be in matrix grep "Integrating Image" \$lastlog >> /dev/null if(! \$status) then # get average cell parameters nawk '/Processing Image/{print gather} \\ /^ Real cell parameters/{getline; gather = \$0}' \$lastlog | \\ nawk 'NF==6{++n; a+=\$1; b+=\$2; c+=\$3; \\ al+=\$4; be+=\$5; ga+=\$6} \\ END{if(n) print a/n, b/n, c/n, al/n, be/n, ga/n}' >! \$tempfile # put averaged cell into variable set cell = \`head -1 \$tempfile\` rm -f \$tempfile >& /dev/null # check for valid CELL foreach X ( \$cell ) if(\$X !~ [1-9]*) set \$cell = "" end if((\$#cell == 6)&&("\$true_cell" != "yes")) then set CELL = \`echo "\$cell"\` endif endif echo -n "." # average the missetting angles (PSIX, PSIY, PSIZ) from the log. # Experience suggests this is appropriate cat \$source |\\ nawk '/Processing Image/{f=\$3} \\ /Refined Orientation Angles/{getline; getline; Cx[f]=\$1; Cy[f]=\$2; Cz[f]=\$3} \\ END { n=0; for(f in Cx){++n;} \\ for(f in Cx){CX+=Cx[f]/n; CY+=Cy[f]/n; CZ+=Cz[f]/n; }; \\ printf "%12.6f %12.6f %12.6f", CX, CY, CZ }' >! \$tempfile set missets = \`cat \$tempfile\` rm -f \$tempfile >& /dev/null # initial missetting angles (PSIX, PSIY, PSIZ) #set missets = \`nawk '/Refined Orientation Angles/{getline; getline; missets=\$0} /Processing Image/ && missets!=""{print missets; exit}' \$source\` if(\$reinput_missets == yes) echo -n " missets: \$missets " # get quantum GAIN of scanner set temp = \`grep GAIN \$lastlog | nawk '{if(\$NF+0 > 0) print \$NF+0}' | head -1\` if(\$#temp == 1) then if(\$temp[1] =~ [0-9]*) then set GAIN = "\$temp" # get BGRATIO (for correcting GAIN estimate) set temp = \`nawk '/^ BGRATIO/{ for(i=2;i<=NF;++i) {++n; sum+=\$i}} END{if(n) printf("%.3f", (sum/n)*(sum/n))}' \$lastlog\` set temp = \`echo \$temp | nawk '\$1+0 != 0'\` if(\$#temp == 1) then # gain correction must have been found set temp = \`echo \$temp 1.1 0.9 | nawk '\$1>=\$2{\$1=\$2} \$1<=\$3{\$1=\$3} {print}'\` set temp = \`echo "\$GAIN \$temp" | nawk '{printf "%0.3f", \$1*\$2}'\` echo -n "gain: \$GAIN -> \$temp " if(\$?REFINE_GAIN) set GAIN = "\$temp" endif endif endif # figure out effective outer resolution limit from mosflm log. cat \${logfile}mosflm.log |\\ nawk 'h==0 && /Analysis as a function of resolution./{h=1;getline;\\ print \$3, \$4, \$5, \$6, \$7, \$8, \$9, \$10} \\ /^ /{print \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9}' |\\ nawk 'NR==1{for(i=1;i<9;++i){res[i]=\$i};++n} \\ NR!=1{for(i=1;i<9;++i){signal[i]+=\$i;++count[i]}}\\ END{if(n) for(i=8;i>0;--i){print res[i], signal[i]/count[i]}}' |\\ sort -nr >! \${tempfile}res_limit set res_limit = \`nawk '\$NF > 0.1 {print \$1+0} \$NF<=0 {exit}' \${tempfile}res_limit | tail -1\` # pick an optimistic, but reasonable outer limit # (1.5x the reciprocal-space volume of res_limit) set inflation = 1.5 if(\$?RES_TROUBLE) set inflation = 1.0 set newRES = \`echo \$res_limit \$inflation | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\` if("\$newRES" != "") echo -n "RES: \$hires -> \$newRES " # clip resolution extention at detector limit (if we know it) set newRES = \`echo \$newRES \$detector_res_limit | nawk 'NF==2 && \$1<\$2{\$1=\$2} {print \$1}'\` # clip resolution extension to not more than a 20% change set test = \`echo \$newRES \$hires | nawk 'NF==2{print (sqrt((\$1^-3 - \$2^-3)^2)>0.2*(\$1^-3) )}'\` if("\$test" == "1") then # calculated change is > 20%, clip change off at 20% set newRES = \`echo \$newRES \$hires 1.2 | nawk '\$1<\$2{print (\$2^-3 * \$3)^(-1/3)} \$1>=\$2{print (\$2^-3 / \$3)^(-1/3)}'\` endif # see if it is appropriate to alter \$hires (> 10% change in rs volume) set test = \`echo \$newRES \$hires | nawk 'NF==2{print (sqrt((\$1^-3 - \$2^-3)^2)>0.1*(\$1^-3) )}'\` if("\$test" == "1") then if("\$res_choice" != "user" && "\$res_choice" != "estimating") then # Elves chose resolution, and it looks like it should be changed set hires = \$newRES set res_choice = mosflm echo "wait a minute... resolution needs updating." unset LAST_RUN endif endif # see if the whole purpose of this run was to estimate resolution if("\$res_choice" == "estimating") then # only do this once set res_choice = mosflm echo "" echo "" # we can afford to be a little more conservative at the beginning set res_limit = \`nawk '\$NF < 2.0 {print \$1+0}' \${tempfile}res_limit | head -1\` if("\$res_limit" != "") then echo "modest resolution estimate is: \$res_limit" set hires = \$res_limit else # what the hell? no information on resolution estimate? echo "resolution estimation failed: assuming detector face limits" endif endif rm -f \${tempfile}res_limit >& /dev/null echo "" # skip rest of scans continue endif #### # ##### #### #### ##### # ##### ##### # # # # # # # # # # # # # # # # # # # #### # # # # # # # # # # # # # # ##### # ##### # # # # # # # # # # # # # # # #### ###### ##### #### #### # # # # # # if we got here, source must be something? if(-e "\$source") then # if(\`echo \$oldscripts |& grep \$source |& wc -l\` != 0) then echo -n "Scanning \$source " ############################################################################### # Read in parameters from the last mosflm script # ############################################################################### # if present, values will be returned in the following variables: # MOSFLM - mosflm executable # SG - space group # CELL - cell dimensions (6) # hires - high resolution limit # mosaic - mosaicity # inmatrix - mosflm orientation matrix file # outmatrix - mosflm output matrix file # beam_center - center of x-ray beam on detector (in mosflm's convention) # distance - xtal-to-film distance (mm) # wavelength - wavelength (according to the header) # GAIN - GAIN used # POLARISATION - polarization parameters # OVERLOAD - overloaded pixel value used # # EXTRA_REFINE_CARDS - any extra refinement keywords (multiline, "n"-delimited shell variable) # PREAMBLE - any keywords not handled by Wedger (multiline, "n"-delimited shell variable) # # check that it's safe to read set safehead = \`ood -cv \$source | nawk '{for(i=2;i<=NF;++i) print \$i}' | nawk '/\\\\n/{++n;c=0} {++c} c>1000{exit} END{print n+0}'\` if(\$safehead == 0) then echo "not text." continue endif # preprocess script for convenient nawk-ing (no blank lines, no comments, # no shell variables or unexpected characters ) head -\$safehead \$source |\\ nawk '\$0=="# skip next line"{getline;next} {print}' |\\ nawk '(NF > 0) && (! /^#/){for(i=1;i<=NF;++i){if(\$i !~ /[\\\$,]/) printf "%s", \$i " "}; print ""}' |\\ nawk '{for(i=1;i<=length;++i){c=substr(\$0,i,1); \\ if(c ~ /[ ,\\t,\\",\\!,\\047,\\140]/){ c = " " }; \\ if((c ~ /[ ,\\t,a-z,A-Z,0-9,.,_,\\/]/)||(c == "-")){printf c }else{break}}print ""}' |\\ cat >! \$tempfile if(\$status) then # something bad happened during the read echo "unreadable! " rm -f \$tempfile continue endif echo -n "." ############################ # File Names ############################ # get mosflm executable name set mosflm = "" set temp = \`nawk '{for(i=1;i<=NF;++i){if(\$i ~ /mosflm/){print \$i}}}' \$tempfile\` foreach file ( \$temp ) set temp = \`ls -lnL \$file |& nawk ' /^-/ && \$1 ~ /x/ &&(\$5 > 3000000){print \$NF}'\` if(-e "\$temp") then # try running it set MosflmVersion = \`echo "GO" | \$temp SUMMARY /dev/null |& head -10 |& nawk '/ [Vv]ersion/{ver = substr(\$0,match(\$0," [Vv]ersion")+8)+0} / Leslie/{print ver}'\` rm -f mosflm.lp >& /dev/null if("\$MosflmVersion" =~ [1-9]*) then # new, viable ececutable found set MOSFLM = "\$temp" else # no dice set temp = "" set MosflmVersion = "" endif endif end # get last mtz file mentioned (in plain text) set temp = \`nawk '{for(i=1;i<=NF;++i){if(\$i ~/.mtz\$/){print \$i}}}' \$tempfile | tail -1\` if(\$#temp == 1) then if("\$temp" =~ *.mtz) set mtzout = "\$temp" endif # reset output matrix file name set temp = \`nawk 'substr(toupper(\$1), 0, 4) ~ "NEWMAT" {print \$2}' \$tempfile | tail -1\` if(\$#temp == 1) then if(-e "\$temp") set outmatrix = "\$temp" endif # image filename parameters were pre-read at the beginnning of Wedger # from now on, everything is upperase nawk '{print toupper(\$0)}' \$tempfile >! \$tempfile.upper mv \$tempfile.upper \$tempfile echo -n "." ############################ # Detector params ############################ # get SCANNER or SITE paramerers set temp = \`egrep "^SCAN|^SITE|^DETECTOR" \$tempfile |& tail -1\` if("\$temp" != "") set SCANNER = "\$temp" # get detector LIMIT paramerers # set temp = \`nawk '/^LIMIT/ && \$2 !~ /^EXCL/' \$tempfile | tail -1\` set temp = \`nawk '/^LIMIT/' \$tempfile | tail -1\` if(("\$temp" != "")&&("\$SCANNER" !~ "SITE*")) then set LIMITS = "\$temp" endif # get upper resolution limit # set temp = \`nawk '\$1 ~ /^RESO/{for(i=2;i<=NF;++i){print \$i}}' \$tempfile | nawk '\$1+0>0.3 && \$1+0 < 15' | sort -nr | tail -1\` set temp = \`nawk '\$1 ~ /^RESO/{for(i=2;i<=NF;++i){print \$i}}' \$tempfile | nawk '\$1+0>0.3 && \$1+0 < 15' | tail -1\` if(\$#temp == 1) then if("\$temp" =~ [0-9]*) then set hires = "\$temp" set res_choice = script endif endif # save unsuppoted resolution cards in preamble file nawk '\$1 ~ /^RESO/ && \$2 ~ /^EXCL|^CUT/' \$tempfile >> \${tempfile}.preamble # get XTF distance set temp = \`nawk '\$1 ~ /^DIST/ && \$2+0>10{print \$2}' \$tempfile |& tail -1\` if(\$#temp == 1) then if("\$temp" =~ [1-9]*) set distance = "\$temp" endif # get TWOTHETA angle set temp = \`nawk '\$1 ~ /^TWOTH/{print \$2}' \$tempfile |& tail -1\` if(\$#temp == 1) then if("\$temp" =~ *[0-9]) set two_theta = "\$temp" endif # get two-theta from denzo file (it's negative of cassette rotx) set temp = \`grep "CASSETTE" \$tempfile | nawk 'BEGIN{RS=" "} /^ROTX/{getline; if(\$1*\$1 > 0.25) print -(\$1+0)}' | head -1\` if(\$#temp == 1) then if("\$temp" =~ *[0-9]) set two_theta = "\$temp" # and correct denzo's distance set temp = \`nawk -v angle=\$two_theta '\$1 ~ /^DISTA/{print \$2*cos(angle*3.1415/180)}' \$tempfile\` if(\$#temp == 1) then if("\$temp" =~ [0-9]*) set distance = "\$temp" endif endif # get wavelength set temp = \`nawk '\$1 ~ /^WAVE/ && \$2>0.1 && \$2<3{print \$2}' \$tempfile |& tail -1\` if(\$#temp == 1) then if("\$temp" =~ [0-3]*) set wavelength = "\$temp" endif # get beam divergence set temp = \`nawk '\$1 ~ /^DIVERGE/{print \$2, \$3}' \$tempfile |& tail -1\` if(\$#temp > 0) then if("\$temp" =~ 0.*) set DIVERGENCE = "\$temp" endif # get spectral dispersion set temp = \`nawk '\$1 ~ /^DISPER/ && \$2+0>0{print \$2}' \$tempfile |& tail -1\` if(\$#temp == 1) then if("\$temp" =~ 0.0*[0-9]) set DISPERSION = "\$temp" endif # get beam center set temp = \`nawk '\$1 == "BEAM"' \$tempfile |& tail -1\` if(\$#temp > 3) then if("\$temp[2]" =~ SWUNG*) set SWING = "SWUNG_OUT" set temp = \`echo BEAM \$temp[3] \$temp[4]\` endif if(\$#temp == 3) then if(("\$temp[2]" =~ [1-9]*)&&("\$temp[3]" =~ [1-9]*)) then set beam_center = \`echo \$temp[2] \$temp[3]\` unset UNRELIABLE_BEAM endif endif # get beam center from denzo files (beam center is REALLY important to get right) set temp = \`nawk '/BEAM /{for(i=2;i! \${tempfile}.filtered mv \${tempfile}.filtered \$tempfile end endif # get GAIN used set temp = \`nawk '\$1 == "GAIN"{if(\$2+0 > 0) print \$2+0}' \$tempfile |& tail -1\` if(\$#temp == 1) then if("\$temp" =~ [0-9]*) set GAIN = "\$temp" endif # get polarization set temp = \`nawk '\$1 ~ /^POLAR/' \$tempfile |& tail -1\` if(\$#temp == 2) then if("\$temp[\$#temp]" =~ MONO*) then # graphite set POLARISATION = "MONOCHROMATOR" endif if(("\$temp[\$#temp]" =~ PIN*)||("\$temp[\$#temp]" =~ MIRR*)) then # no polarization set POLARISATION = "MIRRORS" endif endif if(("\$temp[\$#temp]" =~ *[0-9]*)&&("\$temp[\$#temp]" !~ *[A-Z]*)) then # probably "polarization synchrotron " set temp = \`echo \$temp[\$#temp] |& nawk '{print \$1+0}'\` set POLARISATION = "SYNCHROTRON \$temp" endif # get polarization from denzo file set temp = \`nawk '\$1 ~ /^MONOCHR/{print \$NF}' \$tempfile |& tail -1\` if("\$temp" =~ [0-9,.]*) then set POLARISATION = "SYNCHROTRON \$temp" set temp = \`echo \$temp | nawk '{print \$1+0}'\` if("\$temp" == 0) set POLARISATION = "MIRRORS" else if("\$temp" =~ FILT*) set POLARISATION = "MIRRORS" if("\$temp" =~ GRAPH*) set POLARISATION = "MONOCHROMATOR" endif # get OVERLOAD pixel value set temp = \`nawk '\$1 ~ /^OVER/{for(i=1;i 1000) set OVERLOAD = "\$temp" endif # get SDCORR for scala? set temp = \`nawk '\$1 ~ /^SDCORR/ && NF>3 && \$2>0.5 && \$NF+0<0.2 && \$NF+0>0' \$tempfile |& tail -1\` if("\$temp" != "") then set SDCORR = \`echo \$temp | nawk '{print \$2, \$3, \$4}'\` unset DEFAULT_SDCORR endif echo -n "." ############################ # Xtal params ############################ # get Space Group set temp = \`nawk '\$1 ~ /^SYMM/{print \$2}' \$tempfile |& tail -1\` if(\$#temp == 1) then # make sure variable has proper form if("\$temp" =~ [1-9]* && \$?CLIBD) then # recognize numerical SG set SGnum = "\$temp" set temp = \`nawk -v num=\$SGnum '\$1==num && NF>5{print \$4}' \${CLIBD}/symop.lib \` endif if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) set SG = "\$temp" else # look for alternative keywords set temp = \`nawk '/^SPACE GR/{print \$3}' \$tempfile\` if(\$#temp == 1) then if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) then set SG = "\$temp" set SG_choice = script endif endif endif # get CELL parameters (six numbers > 10) set temp = \`nawk '/CELL /{for(i=1;i<=NF;++i){if(\$i+0 > 10) printf \$i+0 " "} print ""}' \$tempfile |& tail -1\` if(\$#temp == 6) then foreach arg ( \$temp ) # make sure entries are numbers if(\$arg !~ [1-9]*) set temp = "" end if("\$temp" != "") set CELL = \`echo \$temp\` endif # get mosaicity set temp = \`nawk '\$1 ~ /^MOSA/ && NF>1{print \$2}' \$tempfile |& tail -1\` if(\$#temp == 1) then # change even if "fixmosaicity" set, since reading from script is like a manual set if("\$temp" =~ [0-5]*) set mosaic = "\$temp" endif ############################ # Refinement params ############################ # # # Postrefinement options set temp = \`grep "POST" \$tempfile | grep "SEGMENT" | nawk '{print \$3}'\` if(\$#temp == 1) then if("\$temp" =~ [1-9]*) then # this was a postrefinement script (in segments) set integrate = no set postref = yes set mosflm_postref_segs = "\$temp" # now look for width of segments set temp = \`nawk '\$1 ~ /^PROCESS/ && \$3 == "TO"{print \$4 - \$2 + 1}' \$tempfile | head -1\` if(\$#temp == 1) then if("\$temp" =~ [1-9]*) set frames_per_segment = "\$temp" endif endif else # this was an integration run set temp = \`grep "PROCESS" \$tempfile | nawk '\$2 !~ /^[0-9]/ && \$4 !~ /^[0-9]/{print \$4 - \$2 + 1}' \` if(\$#temp == 1) then set integrate = yes # import processing limits from this script if(\$temp > 0) set number_of_frames = \$temp endif endif # import total number of frames? set temp = \`nawk '/^PROCESS/{print \$2; print \$4}' \$tempfile | sort -n | nawk '/[0-9]/' | nawk 'NR==1{f=\$1} {l=\$1} END{if(NR==2) print l-f+1}'\` if(\$#temp == 1) then if(("\$number_of_frames" == "")&&(\$temp > 0)) set number_of_frames = \$temp endif # # ############################ # Fancy features ############################ # set temp = \`grep "POSTREF OFF" \$tempfile \` if(\$#temp) then set postref = no else set postref = yes endif # set temp = \`grep "POSTREF" \$tempfile | grep -i "USEBEAM" \` # if(\$#temp) then # set usebeam = yes # else # set usebeam = no # endif set temp = \`grep "POSTREF" \$tempfile | grep -i "FIX" \` if(\$#temp) then set fixcell = yes else set fixcell = no endif set temp = \`grep "POSTREF" \$tempfile | grep -i "BEAM 0" \` if(\$#temp) then set fixmosaicity = yes else set fixmosaicity = no endif grep "REFI" \$tempfile >& /dev/null if(! \$status) then set temp = \`grep "REFI" \$tempfile | grep -i "YSCALE" \` if(\$#temp) then set fixyscale = yes else set fixyscale = no endif endif # extract "ADD" oscillation and starting phi if frames are not different set temp = \`nawk '\$1 ~ /^IDEN/{print \$2}' \$source\` if(("\$temp" == "\$frameprefix")||("\$temp" == "")) then # probably reprocessing same frames # Look for "add" card in the script set temp = \`nawk '/ ADD / && /PROCES/{print substr(\$0, index(\$0, " ADD")+4)+0}' \$tempfile |& head -1\` if("\$temp" =~ [0-9]*) set add = "\$temp" set temp = \`nawk '/ ANGLE /{print substr(\$0, index(\$0, " ANGLE")+6)}' \$tempfile |& nawk '\$1 !~ /A-Z/{print \$1+0;exit}'\` if("\$temp" =~ [0-9]*) set osc = "\$temp" set temp = \`nawk '/ START /{print substr(\$0, index(\$0, " START")+6)}' \$tempfile |& nawk '\$1 !~ /A-Z/{print \$1+0;exit}'\` if("\$temp" =~ *[0-9]*) set phi0 = "\$temp" else # must not have processed these data yet set NEW endif echo -n "." ############################ # Accumulate PREAMBLE list of MOSFLM keywords not handled by Wedger Elves (capitalized) ############################ # set PREAMBLE = "\$PREAMBLE"\`egrep "\$PASSTHRU_CARDS" \$tempfile | nawk 'BEGIN{ORS="n"} {print}'\` egrep "\$PASSTHRU_CARDS" \$tempfile >> \${tempfile}.preamble # allow for new subkeywords too nawk '\$1 ~ /^LIMIT/ && \$2 ~ /^EXCLUDE/' \$tempfile >> \${tempfile}.preamble ############################ # Accumulate list of "extra" refinement options not handled by Wedger Elves (capitalized) ############################ # nawk '{\$0 = toupper(\$0)} /^POST/' \$source | grep -iv " SEGM" | grep -iv " ADD" |\\ nawk '{\$0 = toupper(\$0)} /^POST/' \$source | grep -iv " SEGM" |\\ grep -iv "FIX ALL" | grep -iv " OFF" >! \${tempfile}.extra_refine_cards nawk '{\$0 = toupper(\$0)} /^REFI/' \$source | grep -iv "FIX YSCALE" |\\ grep -iv "RESID 100" >> \${tempfile}.extra_refine_cards # accumulate this stuff into one variable # set EXTRA_REFINE_CARDS = "\$EXTRA_REFINE_CARDS"\`nawk 'BEGIN{ORS="n"} {print}' \$tempfile\` # clean up rm -f \${tempfile} >& /dev/null echo "." # skip rest of scans continue endif end # process preamble file into a variable ( temporary file might get deleted ) set temp = \`cat \${tempfile}.preamble |& wc -l\` if("\$temp" > 0) then echo "Hang on ... " # standardize cards and remove completely identical entries cat \${tempfile}.preamble |\\ nawk '{for(i=1;i<=NF;++i){s = s " " \$i} print substr(s,2); s=""}' |\\ nawk '{list[toupper(\$0)]==\$0} END{for(card in list){print card}}' >! \${tempfile} mv \${tempfile} \${tempfile}.preamble # watch out for huge files set temp = \`cat \${tempfile}.preamble | wc -c\` if(\$temp > \$MAXLINE) then echo "WARNING: too many passthru cards ... truncating list." nawk -v L=\$MAXLINE '{l+=length(\$0)} l! \${tempfile} mv \${tempfile} \${tempfile}.preamble endif # import preamble file into a variable (check it later) set PREAMBLE = \`nawk 'BEGIN{ORS="n"} NF != 0' \${tempfile}.preamble\` rm -f \${tempfile}.preamble endif # process extra refine cards into a variable too set temp = \`cat \${tempfile}.extra_refine_cards |& wc -l\` if("\$temp" > 0) then # remove completely identical entries cat \${tempfile}.extra_refine_cards |\\ nawk '{for(i=1;i<=NF;++i){printf "%s ", \$i} print ""}' |\\ nawk '{list[toupper(\$0)]==\$0} END{for(card in list){print card}}' >! \${tempfile} # watch out for huge files set temp = \`cat \${tempfile} | wc -c\` if(\$temp > \$MAXLINE) then echo "WARNING: too many postref cards ... truncating list." nawk -v L=\$MAXLINE '{l+=length(\$0)} l! \${tempfile}.extra_refine_cards mv \${tempfile}.extra_refine_cards \$tempfile endif # import refine cards file into a variable (get rid of blank lines) set EXTRA_REFINE_CARDS = \`nawk 'BEGIN{ORS="n"} NF != 0' \$tempfile\` endif # clean up rm -f \${tempfile}* >& /dev/null goto ReturnGetParamsFromSources exit autoindex: onintr ########################################################################## ## # # ##### #### # # # ##### ###### # # # # # # # # # # ## # # # # # # # # # # # # # # # # # # # ##### ## ###### # # # # # # # # # # # # ## # # # # # # # # # ## # # # # # # # #### # #### # # # ##### ###### # # ########################################################################## set autoindexing unset LAST_RUN # check the mosaicity, if it has not been set, pick a reasonable value if("\$mosaic" == "auto") then set mosaic = \`echo "\$osc" | nawk '\$1+0>0{print \$1/2}'\` if("\$mosaic" == "") set mosaic = 1 set temp = \`echo "\$MosflmVersion" | nawk '/[0-9]/{printf "%d", \$1*100}'\` if("\$temp" > 619) set mosaic = "estimate" endif set temp = "Yes" if(! \$?AUTO && ! \$?HURRY) then # Brief report on intentions (in case user didn't read the first one carefully) cat << EOF About to autoindex: \$framedir/\${template} using: \$MOSFLM v \$MosflmVersion beam center: \$beam_center distance: \$distance mm wavelength: \$wavelength \$ANG cell: \$CELL space group: \$SG Is this correct? [\$temp] EOF echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) else # autoindexing in fully-automatic mode is suspicious, user might be doing this for every wedge (WRONG!) echo "" echo "REMEMBER: You should only autoindex once per crystal." echo " Autoindexing two wedges from the same crystal might result in incompatible" echo " cell axis assignments, requiring reindexing of one wedge before mergeing." echo "" endif if("\$temp" !~ [Yy]*) then # ask user about parameters again set input = "" if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) set input = "\$temp" goto Questionaire endif if("\$number_of_frames" == "") set number_of_frames = \`echo "\$last \$first" | nawk '{print \$1-\$2+1}'\` # generate a mosflm "start" script ################################################################################################ echo "creating autoindex.com..." if(-e autoindex.inp) mv autoindex.inp autoindex.inp.old if("\$PREAMBLE" != "") then cat << EOF-preamble >! autoindex.inp # the following keywords were not understood by the Wedger elves, but passed on # because they resemble mosflm commands. # ---- \`echo "\$PREAMBLE" | nawk 'BEGIN{RS="n"} {print}'\` # ---- EOF-preamble else echo "" >! autoindex.inp endif # make other printing decisions now set print_mosaic = 1 set print_swing = "" set print_cell = "" set print_sg = "" set mosflmSG = \$SG if("\$SG" =~ P2*2*2* ) set mosflmSG = P222 if("\$SG" =~ R* || "\$SG" =~ H*) set mosflmSG = \$SG_number if("\$mosaic" =~ *[0-9]*) set print_mosaic = "\$mosaic" set temp = \`echo "\$two_theta" | nawk '{printf "%d", \$1+0}'\` if("\$temp" != "0") set print_swing = "SWUNG_OUT " #if(\$#CELL == 6) set print_cell = "CELL KEEP \$CELL" if(\$#CELL != 6) set print_cell = "#CELL KEEP 100 100 100 90 90 90" if(("\$SG" != "unknown")&&(\$#CELL == 6)) set print_sg = "SYMMETRY \$mosflmSG" if(("\$SG" != "unknown")&&(\$#CELL == 6)) set print_cell = "CELL KEEP \$CELL" if("\$SG" == "unknown") set print_sg = "#SYMMETRY P1" set test = \`echo \$MosflmVersion | awk '{print (\$1 >= 6.2)}'\` if("\$test" && ("\$SG" != "unknown")) then # this should not crash set print_sg = "SYMMETRY \$mosflmSG" endif set print_overload = "OVERLOAD CUTOFF \$OVERLOAD" set test = \`echo \$OVERLOAD | nawk '{print (\$1+0<1000)}'\` if(\$test) then set print_overload = "" endif set print_gain = "GAIN \$GAIN" set test = \`echo \$GAIN | nawk '{print (\$1+0<=0)}'\` if(\$test) then set print_gain = "" endif set EXTENSION if("\$ext" != "") set EXTENSION = "EXTENSION" set print_beam = "BEAM \${print_swing}\$beam_center" if(\$?UNRELIABLE_BEAM) set print_beam = "#\$print_beam" cat << EOF_auto >> autoindex.inp # Detector parameters (range, quantum gain, etc.) \$SCANNER \$print_overload \$print_gain \$LIMITS # Beam parameters (i.e. (delta-lambda)/lambda, H,V divervence in degrees) WAVELENGTH \$wavelength DISPERSION \$DISPERSION DIVERGENCE \$DIVERGENCE POLARISATION \$POLARISATION # Alignment parameters DISTANCE \$distance \$print_beam TWOTHETA \$two_theta # NEWMATRIX auto.mat # Crystal parameters \${print_cell} \${print_sg} RESOLUTION \$hires MOSAIC \$print_mosaic # frame filename breakdown DIRECTORY \$framedir IDENTIFIER \$frameprefix \$EXTENSION \$ext \$TEMPLATE # FINDSPOTS MINX 0.1 MINY 0.1 MAXX 5 MAXY 5 SPLIT 0.2 0.2 # EOF_auto unset print_swing unset print_cell unset print_sg if("\$Site" =~ "4*ADSC*") then # fix background stripe problem with ADSC frames cat << EOF-adsc >> autoindex.inp # make sure background stripe is above "window pane" FINDSPOTS YOFFSET 3 EOF-adsc endif if(! -e dps_index.com) then echo "creating dps_index.com" cat << EOF-script >! dps_index.com #! /bin/csh -f # # script for autoindexing mosflm spot output with dps_index # without the need for a GUI # ######## # # use the most recently-created .spt file by default set spotfile = \\\`ls -1rt *.spt | tail -1\\\` set outmatrix = dps.mat set tempfile = dps_temp # camera settings (not available in *.spt file) set wavelength = "" set distance = "" set two_theta = 0 set beam_center = "" # crystal parameters (overridden by keywords in script) set CELL = "" set SG = "" set max_cell = 300 set hiRES = 1 set loRES = 1000 goto Setup Help: ############################################################ cat << EOF usage: dps_index.com mosflm.spt 1.0A 100mm P212121 or usage: dps_index.com mosflm.spt mosflm.com P212121 where: mosflm.spt - the "spot" file (picked with mosflm) 1.0A - the x-ray wavelength 100mm - the xtf distance mosflm.com - a mosflm script containing CELL, DIST, WAVE, etc., P212121 - space group to select (optional) 3-20A - resolution range to use (optional) 50sig - I/sigma cutoff to use (default: 0) 300 - maximum cell edge (default: \\\$max_cell) EOF exit 9 Return_from_Setup: if("\\\$wavelength" == "") goto Help if("\\\$distance" == "") goto Help ############################################################ # retrieve useful parameters from the mosflm spot file echo "\\\$0 \\\$*" echo "using \\\${spotfile} (\\\$frames images)" set rotation = \\\`nawk 'NR==1{rot=\\\$5} NR==2{print (360-rot+180*\\\$1)%360;exit}' \\\$spotfile\\\` set ysign = \\\`nawk 'NR==2{print 1-(\\\$1*2);exit}' \\\$spotfile\\\` set raster = \\\`nawk '{print \\\$3;exit}' \\\$spotfile\\\` set yscale = \\\`nawk '{print \\\$4;exit}' \\\$spotfile\\\` set beam_center = \\\`nawk 'NR==3 && NF==2{print;exit}' \\\$spotfile\\\` set beamstop = \\\`echo \\\$beam_center \\\$raster \\\$yscale | nawk '{printf "r %d s %d", \\\$1/\\\$3,\\\$2*\\\$4/\\\$3}'\\\` set sscale = \\\`echo \\\$ysign \\\$yscale | nawk '{print \\\$1/\\\$2}'\\\` set mode = automatic # are these important? set phi0 = \\\`nawk 'NR==4{printf "%.1f", \\\$4-\\\$3}' \\\${spotfile}\\\` set phiend = \\\`nawk 'NR==4{printf "%.1f", \\\$4+\\\$3}' \\\${spotfile}\\\` # report values input into dps_index echo "wavelength: \\\$wavelength" echo "beam center: \\\$beamstop" echo "distance: \\\$distance" echo "2theta: \\\$two_theta" echo "sscale: \\\$sscale" echo "rotation: \\\$rotation" echo "resolution: \\\$loRES \\\$hiRES" echo "sigma cut: \\\$cutoff" if("\\\$CELL" != "") then echo "Cell: \\\$CELL" set CELL = "target_cell \\\$CELL" set mode = "target_cell" else echo "Cell: < \\\$max_cell" endif if("\\\$SG" != "") then echo "Space Group: \\\$SG" else if("\\\$wrongSGs" != "") echo "Space Group: anything but \\\$wrongSGs" endif echo "" # convert the mosflm spot file into a DPS peaks file cat \\\$spotfile |\\\\ nawk -v cutoff=\\\$cutoff 'BEGIN{PI=2*atan2(1,0); print "DPS-PF A2.0"}\\\\ NR==1{xwidth = \\\$3; ywidth = \\\$3/\\\$4;}\\\\ NF>5 && \\\$1!="-99.00" && \\\$1!="-999.00" && \\\$6+0>0{\\\\ if(\\\$5/\\\$6! peaks.file set temp = \\\`head -1 \\\$spotfile\\\` if("\\\$temp" =~ DPS-PF*) then cp \\\$spotfile peaks.file endif # now do DPS indexing foreach round ( 1 2 3 ) dps_index << EOF | tee \\\${tempfile}.log mode \\\$mode \\\$CELL \\\$target_sym resolution \\\$loRES \\\$hiRES cell \\\$max_cell wavelength \\\$wavelength rastersize \\\$raster distance \\\$distance twotheta \\\$two_theta beamstop \\\$beamstop film_rotation \\\$rotation sscale \\\$sscale PEAKS peaks.file \\\$phi0 \\\$phiend omfile auto.om EOF if(! -e PEAKS_WITH_PHIS) then exit 9 endif # keep re-cycling peak file mv PEAKS_WITH_PHIS peaks.file set RMS = \\\`nawk '/RMS/{printf "%d", \\\$NF}' \\\${tempfile}.log\\\` rm -f \\\${tempfile}.log if(\\\$RMS < 3) break end # score different lattice possibilities dps_bravais << EOF | tee \\\${tempfile}.log mode bravais omfile auto.om EOF # organize possibilities in terms of space groups cat \\\${tempfile}.log |\\\\ nawk -v library=\\\$CLIBD/symop.lib '/^Lattice:/{\\\\ solution=\\\$2; crys_sys=\\\$4; score=\\\$6; source="|";\\\\ sys = substr(\\\$4,1,1); lattice = substr(\\\$4,2); \\\\ getline;getline;getline;getline; cell=substr(\\\$0,10);\\\\ if(sys=="a") sys = "TRICL"; \\\\ if(sys=="m") sys = "MONOC"; \\\\ if(sys=="o") sys = "ORTHO"; \\\\ if(sys=="t") sys = "TETRA"; \\\\ if(sys=="h") sys = "TRIGO"; \\\\ if(sys=="c") sys = "CUBIC"; \\\\ while(getline < library){ \\\\ if(\\\$5 ~ /^PG/ && ! /m/ && ! /bar/ && \\\$1 < 500){\\\\ SYS=substr(\\\$6,1,5)\\\\ if(substr(\\\$4,1,1)==lattice && (SYS==sys || (SYS=="HEXAG" && sys=="TRIGO"))){\\\\ print \\\$1, substr(\\\$5,3), \\\$4, crys_sys, \\\$6, solution, score, cell, source;\\\\ }\\\\ }\\\\ }; close(library);}' |\\\\ sort -k1nr,2 -k7n,8 |\\\\ nawk '! seen[\\\$3]{print; seen[\\\$3]=1}' |\\\\ nawk '{a=\\\$8; b=\\\$9; c=\\\$10; A=\\\$11; B=\\\$12; G=\\\$13;latt=\\\$5}\\\\ \\\$5 == "MONOCLINIC" { A=90; ; G=90}\\\\ \\\$5 == "ORTHORHOMBIC" {A=90; B=90; G=90}\\\\ \\\$5 == "TETRAGONAL" || \\\$5 == "TRIGONAL" || \\\$5 == "HEXAGONAL" {\\\\ a=b=(a+b)/2; A=90; B=90; G=120;}\\\\ \\\$5 == "TETRAGONAL" {G=90}\\\\ \\\$5 == "CUBIC" {a=b=c=(a+b+c)/3; A=90; B=90; G=90}\\\\ {print \\\$0, a, b, c, A, B, G}' |\\\\ cat >! \\\${tempfile}.sg # format: SG_num PG SG crys_sys lattice solution penalty cell source newcell # clear undesirable SG choices from the list of possibilities echo " \\\$wrongSGs LIST " |\\\\ nawk 'BEGIN{RS=" "} NF==1' |\\\\ cat - \\\${tempfile}.sg |\\\\ nawk 'NF==1{bad[\\\$1]=1} \\\\ list && ! bad[\\\$3] && ! bad[\\\$4] && ! bad[\\\$5] {print}\\\\ /LIST/{list=1}' |\\\\ cat >! \\\${tempfile}filtered mv \\\${tempfile}filtered \\\${tempfile}.sg # format: SG_num PG SG crys_sys lattice solution penalty cell source newcell # automatically pick space group with good fit if("\\\$SG" == "") then # choose one... set solution = \\\`nawk '\\\$7<1{print \\\$6; exit}' \\\${tempfile}.sg\\\` if("\\\$solution" == "") then set solution = \\\`nawk '{print \\\$6}' \\\${tempfile}.sg | tail -1\\\` endif set SG = \\\`nawk -v solution=\\\$solution '\\\$6==solution{print \\\$3}' \\\${tempfile}.sg | tail -1\\\` echo "selected \\\$SG as a representative of the point group" endif set solution = \\\`nawk -v SG=\\\$SG '\\\$3==SG{print \\\$6;exit}' \\\${tempfile}.sg\\\` bravais_to_mosflm \\\$solution \\\${tempfile}.log /dev/null \\\${outmatrix} 0.0 \\\${wavelength} no_update condense_bravais \\\${tempfile}.log bravais.sum set CELL = \\\`nawk 'NF==6{print;exit}' \\\${outmatrix}\\\` if(\\\$#CELL != 6) then # do it ourselves... cat \\\${tempfile}.log |\\\\ nawk -v solution=\\\$solution '/Lattice/ && \\\$2==solution{\\\\ getline; mid=\\\$0; getline; last=\\\$0; getline; \\\\ print \\\$0; print mid; print last; \\\\ getline; print}' |\\\\ nawk -v wave=\\\$wavelength 'NF==3{printf "%12.8f%12.8f%12.8f\\\\n", \\\$1*wave, \\\$2*wave, \\\$3*wave}' |\\\\ cat >! \\\${outmatrix} cat \\\${tempfile}.sg |\\\\ nawk -v SG=\\\$SG '\\\$3==SG{\\\\ printf "%12.3f%12.3f%12.3f\\\\n", 0, 0, 0;\\\\ printf "%12.7f%12.7f%12.7f\\\\n", 1, 0, 0;\\\\ printf "%12.7f%12.7f%12.7f\\\\n", 0, 1, 0;\\\\ printf "%12.7f%12.7f%12.7f\\\\n", 0, 0, 1;\\\\ printf "%12.4f%12.4f%12.4f%12.4f%12.4f%12.4f\\\\n", \\\$15, \\\$16, \\\$17, \\\$18, \\\$19, \\\$20;\\\\ printf "%12.3f%12.3f%12.3f\\\\n", 0, 0, 0; exit}' |\\\\ cat >> \\\${outmatrix} set CELL = \\\`nawk 'NF==6{print;exit}' \\\${outmatrix}\\\` endif echo "SYMM \\\$SG" echo "CELL \\\$CELL" echo "MATRIX \\\${outmatrix}" # clean up exit rm -f peaks.file rm -f PEAKS_WITH_PHIS rm -f auto.om rm -f \\\${tempfile}.log rm -f \\\${tempfile}.sg rm -f bravais.sum rm -f b_to_m.in rm -f b_to_m.out rm -f analyse.out exit ############################################################ Setup: nawk 'BEGIN{exit}' >& /dev/null if(\\\$status) alias nawk awk set wrongSGs set userSG set cutoff = 0 # scan the command line for files 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 set arg = "\\\$argv[\\\$i]" set ARG = \\\`echo "\\\$arg" | nawk '{print toupper(\\\$1)}'\\\` if("\\\$arg" =~ *.spt) then if(! -e "\\\$arg") then echo "WARNING: \\\$arg does not exist! " continue endif set spotfile = "\\\$arg" continue endif if(-e "\\\$arg") then # assume this is the mosflm.com file set temp = \\\`nawk '/^WAVE/ && \\\$2+0>0.1 && \\\$2+0<10{print \\\$2}' \\\$arg\\\` if("\\\$temp" != "") set wavelength = "\\\$temp" set temp = \\\`nawk '/^DIST/ && \\\$2+0>10 && \\\$2+0<1000{print \\\$2}' \\\$arg\\\` if("\\\$temp" != "") set distance = "\\\$temp" set temp = \\\`nawk '/^TWOTHETA/ && \\\$2+0>-90 && \\\$2+0<90{print \\\$2}' \\\$arg\\\` if("\\\$temp" != "") set two_theta = "\\\$temp" # get (and check) space group set temp = \\\`nawk '/^SYMM/ && \\\$2 ~ /^[PpCcIiFfRrHh][1-6]/{print \\\$2}' \\\$arg\\\` set temp = \\\`nawk -v SG=\\\$temp '\\\$4==SG{print \\\$4;exit}' \\\${CLIBD}/symop.lib\\\` if("\\\$temp" != "") set SG = "\\\$temp" # get unit cell set temp = \\\`nawk '/CELL /{for(i=1;i<=NF;++i){if(\\\$i+0 > 10) printf \\\$i+0 " "} print ""}' \\\$arg |& tail -1\\\` if(\\\$#temp == 6) then foreach param ( \\\$temp ) # make sure entries are numbers if(\\\$param !~ [1-9]*) set temp = "" end if("\\\$temp" != "") set CELL = \\\`echo \\\$temp\\\` endif # get upper resolution limit set temp = \\\`nawk '\\\$1 ~ /^RESO/{for(i=2;i<=NF;++i){print \\\$i}}' \\\$arg | nawk '\\\$1+0>0.3 && \\\$1+0 < 15' | tail -1\\\` if(\\\$#temp == 1) then if("\\\$temp" =~ [0-9]*) set hiRES = "\\\$temp" endif continue endif # now read things that aren't files # check for space groups if("\\\$ARG" =~ [PCIFHR][1-6]*) then set temp = "\\\$ARG" if("\\\$arg" =~ [PCIFHR][1-6]*) set temp = "\\\$arg" set temp = \\\`nawk -v SG=\\\$temp '\\\$4 == SG {print \\\$4;exit}' \\\$CLIBD/symop.lib\\\` if("\\\$temp" == "") then # check for "pseudo-spacegroup" language #set temp = \\\`echo "\\\$ARG" | nawk 'toupper(\\\$1) ~ /[PC]2212|[PC]2122|P21221|P22121/'\\\` # these are okay too, reindexing engine will understand endif if("\\\$temp" != "") then if(\\\$?NO) then # user doesn't want this space group set wrongSGs = ( \\\$wrongSGs \\\$temp ) # check and see if \\\$SG is in \\\$wrongSGs foreach wrongSG ( \\\$wrongSGs ) if("\\\$SG" == "\\\$wrongSG") set SG = "" end continue endif # user prefers this space group set userSG = "\\\$temp" continue endif endif # allow disqualification of point groups if("\\\$ARG" =~ PG[1-6]*) then # see if this is really a point group set temp = \\\`nawk -v PG=\\\$ARG '\\\$5 == PG && ! /m/ && ! /bar/ {print \\\$4;exit}' \\\$CLIBD/symop.lib\\\` if("\\\$temp" != "") then if(\\\$?NO) then # user doesn't want this point group set wrongSGs = ( \\\$wrongSGs \\\$ARG ) # check and see if \\\$SG is in \\\$wrongSGs foreach wrongSG ( \\\$temp ) if("\\\$SG" == "\\\$temp") set SG = "" end continue endif # user prefers this point group? set SG = "\\\$temp[1]" continue endif endif # allow disqualification of lattice types if(("\\\$ARG" =~ *IC)||("\\\$ARG" =~ *ONAL)) then # see if this is really a crystal system set temp = \\\`nawk -v sys=\\\$ARG '\\\$6 == sys && ! /m/ && ! /bar/ {print \\\$4;exit}' \\\$CLIBD/symop.lib\\\` if("\\\$temp" != "") then if(\\\$?NO) then # user doesn't want these space groups set wrongSGs = ( \\\$wrongSGs \\\$ARG ) # check and see if \\\$SG is in \\\$wrongSGs foreach wrongSG ( \\\$temp ) if("\\\$SG" == "\\\$wrongSG") set SG = "" end continue endif # user prefers this crystal system? set SG = "\\\$temp[1]" continue endif endif # allow disqualification of a bravais lattice if(("\\\$arg" =~ [chotma][PICFR])) then # see if it's really a bravais lattice cat \\\${CLIBD}/symop.lib |\\\\ nawk -v brav=\\\$arg 'BEGIN{sys=substr(brav,1,1); type = substr(brav,2);\\\\ if(sys=="a") sys = "TRICL"; \\\\ if(sys=="m") sys = "MONOC"; \\\\ if(sys=="o") sys = "ORTHO"; \\\\ if(sys=="t") sys = "TETRA"; \\\\ if(sys=="h") sys = "TRIGO"; \\\\ if(sys=="c") sys = "CUBIC";}\\\\ \\\$5 ~ /^PG/ && ! /m/ && ! /bar/ {\\\\ SYS=substr(\\\$6,1,5); TYPE=substr(\\\$4,1,1);\\\\ if(TYPE==type && (SYS==sys || (SYS=="HEXAG" && sys=="TRIGO"))){\\\\ print \\\$4}}' |\\\\ cat >! \\\${tempfile}brav set temp = \\\`cat \\\${tempfile}brav\\\` rm -f \\\${tempfile}brav >& /dev/null if("\\\$temp" != "") then if(\\\$?NO) then # user doesn't want these space groups set wrongSGs = ( \\\$wrongSGs \\\$arg ) # check and see if \\\$SG is in \\\$wrongSGs foreach wrongSG ( \\\$temp ) if("\\\$SG" == "\\\$wrongSG") set SG = "" end continue endif # user prefers this crystal system? set SG = "\\\$temp[1]" continue endif endif 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 hiRES = \\\`echo "\\\$temp[2]" | nawk '{print \\\$1+0}'\\\` set loRES = \\\`echo "\\\$temp[1]" | nawk '{print \\\$1+0}'\\\` continue endif else # single 1.1A is a wavelength set wavelength = \\\`echo "\\\$arg" | nawk '{print \\\$1+0}'\\\` continue endif endif if(("\\\$arg" =~ *mm)||("\\\$argv[\\\$nexti]" == "mm")) then # distance is expressed in mm set distance = \\\`echo "\\\$arg" | nawk '{print \\\$1+0}'\\\` continue endif if(("\\\$arg" =~ *sig)||("\\\$argv[\\\$nexti]" == "sig")) then # sigma cutoff for spot use set cutoff = \\\`echo "\\\$arg" | nawk '{print \\\$1+0}'\\\` continue endif # interpret free integers as max cell edge? set int = \\\`echo "\\\$arg" | nawk '{printf "%d", \\\$1+0}'\\\` if("\\\$arg" == "\\\$int") then set max_cell = \\\$int endif endif # flags and switches if("\\\$ARG" == "CELL") then if(\\\$?NO) set CELL = "" continue endif if("\\\$ARG" == "SG") then if(\\\$?NO) set SG = "" continue endif unset NO if("\\\$ARG" == NO) set NO if("\\\$ARG" == NOT) set NO end # override any misc space-group settings with command-line space group if("\\\$userSG" != "") then set SG = "\\\$userSG" set wrongSGs = "" endif # get the number of images that were peak-picked into this spotfile set frames = \\\`nawk '\\\$NF=="-99.0" || \\\$NF=="-999.0"' \\\$spotfile | wc -l\\\` set spots = \\\`nawk 'NF>5 && \\\$1!="-99.00" && \\\$1!="-999.00"' \\\$spotfile | wc -l\\\` set target_sym if("\\\$SG" != "") then # set up target lattice/symm set target_sym = \\\`nawk -v SG=\\\$SG '\\\$4==SG{print "target_sym", substr(\\\$4,1,1), \\\$6;exit}' \\\${CLIBD}/symop.lib\\\` endif goto Return_from_Setup EOF-script chmod a+x dps_index.com endif PickIndexer: onintr # check for DPS-in-the-background version of Mosflm set temp = \`echo "\$MosflmVersion" | nawk '\$1+0>=6.11'\` if("\$temp" != "") then # a pity that v6.10 crashes with this... set background_DPS endif # check to see if dps_index is available set temp = \`which dps_index |& nawk 'NF==1 && /dps_index\$/'\` if(("\$temp" != "")&&(! \$?background_DPS)) then # this will do... set DPS_INDEX endif # background is preferable, if DPS indexing can be used if((\$?background_DPS)||(\$?DPS_INDEX)) then set temp = "No" echo "Do you want to use the graphics for indexing? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if(("\$temp" =~ [Nn]*)&&(\$#temp <= 1)) then # user is okay with background indexing goto Index_again endif # don't use these then... unset background_DPS unset DPS_INDEX if("\$temp" =~ [Yy]*) then # don't know why you'd want to do this... goto Manual_Index else # strange answer, send to interpreter set input = "\$temp" goto Questionaire endif endif # warn about bad indexing situation set test = \`echo \$MosflmVersion | awk '{print (\$1+0<6)}'\` if(("\$test" == "1")&&(\$number_of_frames < \$autoindexing_frames)) then set temp = "No" cat << EOF WARNING: MOSFLM Version \$MosflmVersion requires several images to index successfully. Recommend you download MOSFLM 6.x or higher, from: ftp://ftp.mrc-lmb.cam.ac.uk/pub/mosflm/ wait for some more, widely-separated frames, or (if you have it) try indexing with denzo. Do you have ipmosflm 6.x or higher ? [\$temp] EOF echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) then echo "Okay, starting over... " set input = "new executable" goto Questionaire else if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # strange answer, send to interpreter set input = "\$temp" goto Questionaire endif # user does not have mosflm 6 endif # if mosflm 6 isn't available, try for denzo if((-e /usr/local/lib/cr_info)||(-e ~/cr_info)||(-e ./cr_info)) then set temp = "Yes" echo "Do you want us to try using denzo (you need a \$Site licence)? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) goto denzo if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # strange answer, send to interpreter set input = "\$temp" goto Questionaire endif endif echo "Going ahead with indexing in Mosflm \$MosflmVersion ... " endif # decide if we need to do an interactive mosflm run if(("\$MosflmVersion" =~ 6*)||(\$#CELL != 6)||("\$SG" == "unknown")) then echo "" if("\$SG" == "unknown") then echo "WARNING: non-interactive indexing cannot determine your space group exactly." echo " (but, the elves can pick a close one, and reindex later.)" else echo "NOTE: non-interactive indexing without a cell is not recommended by AGWL." echo " (but it does seem to work eventually)." endif set Interactive = "PLOT" set temp = "No" endif if("\$MosflmVersion" =~ 6*) then echo "" echo "DPS indexing in MOSFLM Version 6.x is very cool," echo "but can only be done in the graphics window! " set Interactive = "PLOT" if(! \$?AUTO) set temp = "Yes" set message = "use the superior indexing algorithm" else set message = "autoindex INTERactively" endif if("\$Interactive" == "PLOT") then echo "Do you want to \$message (requires graphics)? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) goto Manual_Index if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # unexpected answer, send to interpreter set input = "\$temp" goto Questionaire endif # risky indexing without SG, go for broke... if("\$SG" == "unknown") set autoindexing_frames = 18 endif # pick frames for mosflm Index_again: ################################################################################################ if(! \$?AUTO) onintr Manual_Index echo "" echo "examining frames named \${framedir}/\${template} ..." # build a table of phi values for frames with this name touch \${tempfile}.phi_list # get any frames with the right name #set temp = \`ls -1 \$framedir |& egrep "\${framepattern}"\` # get frames from the wedge only set first_frame = \`echo "\$template \$first" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` #set frames = \`ls -1 \$framedir |& egrep "\$framepattern" |& nawk -v first_frame=\$first_frame '\$0==first_frame,NR<0' | head -\$number_of_frames\` set frames = \`ls -1 \$framedir |& egrep "\$framepattern" |& nawk -v first_frame=\$first_frame '\$0==first_frame,NR<0'\` foreach frame ( \$frames ) set number = \`echo \$frame \$template | nawk '{n=split(\$1,a,"[\\057]"); print substr(a[n],index(\$2,"\\043"))+0}'\` set phi = "" #save phi value set img = \$framedir/\$frame if("\$Site" =~ *ADSC* || "\$Site" =~ *SBC*) then set phi = \`nawk 'BEGIN{RS="\\f"} {print;exit}' \$img | egrep "PHI|OSC_START|ROTATION_START" | nawk -F "=" '{print \$NF+0; exit}'\` endif if("\$Site" =~ *PILATUS*) then set phi = \`nawk 'BEGIN{RS="\\f"} {print;exit}' \$img | egrep -i "Start_angle" | nawk '\$4~/^deg/{print \$3+0; exit}'\` endif if(\$?RAXIS_SMV) then set phi = \`nawk 'BEGIN{RS="\\f"} {print;exit}' \$img | egrep "^ROTATION=" | nawk -F "=" '{print \$2+0; exit}'\` endif if(("\$Site" =~ *RAXIS*)&&("\$swap" != "")&&(! \$?RAXIS_SMV)) then # get phi value from header od -vb -j 524 -N 4 \$img |\\ nawk '{for(i=2;i<=5;++i){printf "%d ", 64*substr(\$i,1,1)+8*substr(\$i,2,1)+substr(\$i,3,1)};exit}' |\\ nawk '{w=x=\$2} \$1+\$2+\$3+\$4==0{--w;++x} {print \$0, w,x-1}' |\\ nawk '{printf "%c%c%c%c", '\$swap'}' | ood -f |\\ nawk '{print \$2+0;exit}' |\\ cat >! \${tempfile}phi set temp = \`nawk '\$1>-370 && \$1<800 {print \$1;exit}' \${tempfile}phi\` rm -f \${tempfile}phi >& /dev/null if("\$temp" != "") set phi = \$temp endif if("\$SCANNER" =~ *MARCCD*) then od -bv -j 1024 -N 1024 \$img |\\ nawk '{for(i=2;i<=NF;++i){print 64*substr(\$i,1,1)+8*substr(\$i,2,1)+substr(\$i,3,1)}}' |\\ nawk 'NR%4==1{printf "\\n%d ", NR+1023} {printf "%d ", \$1}' |\\ nawk '/^1052 210 4 0 0/{little=1} /^1052 0 0 20 341/{big=1} \\ little{print \$1, (\$2+256*(\$3+256*(\$4+256*\$5)))-(2^32)*(\$5>=128)} \\ big{print \$1, (\$5+256*(\$4+256*(\$3+256*\$2)))-(2^32)*(\$2>=128)}' |\\ nawk '/^1708 /{ print \$2/1000}' |\\ cat >! \${tempfile}phi set temp = \`nawk '\$1>-370 && \$1<800 {print \$1;exit}' \${tempfile}phi\` rm -f \${tempfile}phi >& /dev/null if("\$temp" != "") set phi = \$temp endif if("\$phi" == "") then # guess #set phi = \`echo "(( \$number - \$first ) * \$osc) + \$phi0" | bc\` set phi = \`echo \$number \$first \$osc \$phi0 | nawk '{print ((\$1-\$2)*\$3)+\$4}'\` endif # nawk '{print (\$1 + (360*(1+int(\$1*\$1/360)))) % 360}' >> \${tempfile}.phi_list echo "\$number \$phi" >> \${tempfile}.phi_list end # sort in order of increasing phi #sort -n +1 \${tempfile}.phi_list >! \$tempfile #mv \$tempfile \${tempfile}.phi_list # make up a list of \$autoindexing_frames widely-separated images cat \${tempfile}.phi_list |\\ nawk -v n=\$autoindexing_frames '{phi[\$1] = (\$2+360000)%360} NR==1{selected[1]=\$1}\\ END{for(i=2;i<=n;++i){ best_score = 0; \\ for(image in phi) { score=1;\\ for( j in selected ){\\ dist = ((360000 + phi[image] - phi[selected[j]]) % 180);\\ if(dist>90)dist=180-dist;\\ score *= dist;\\ }\\ if(score > best_score){\\ best_score = score;\\ best = image;}}\\ selected[i] = best;}\\ for(i in selected){print selected[i]}\\ }' >! \$tempfile set index_images = \`sort -un \$tempfile\` rm -f \$tempfile >& /dev/null cat \${tempfile}.phi_list |\\ nawk -v n=2 '{phi[\$1] = (\$2+360000)%360} NR==1{selected[1]=\$1}\\ END{for(i=2;i<=n;++i){ best_score = 0; \\ for(image in phi) { score=1;\\ for( j in selected ){\\ dist = ((360000 + phi[image] - phi[selected[j]]) % 180);\\ if(dist>90)dist=180-dist;\\ score *= dist;\\ }\\ if(score > best_score){\\ best_score = score;\\ best = image;}}\\ selected[i] = best;}\\ for(i in selected){print selected[i]}\\ }' >! \$tempfile set best_two_index_images = \`sort -un \$tempfile\` rm -f \$tempfile >& /dev/null # run multiframe, MOSFLM autoindexing ################################################################################################ #echo "" echo -n "autoindexing on frames \$index_images " echo "" >! autoindex.frames set FLAGS = "" if(\$?background_DPS) then # anything fancier? set FLAGS = "DPS" if((\$#CELL == 6)&&("\$SG" != "unknown")) then #set FLAGS = "DPS PREREFINE" endif endif # will this usually work better? set FLAGS = "\$FLAGS THRESH 5" if("\$Site" =~ *RAXIS* || \$?BAD_HEADER) then foreach img ( \$index_images ) set temp = \`egrep "^\$img " \${tempfile}.phi_list |& nawk -v osc=\$osc '{print \$2, \$2+osc}'\` echo "AUTOINDEX \$FLAGS IMAGE \$img PHI \$temp" >> autoindex.frames end else echo "AUTOINDEX \$FLAGS IMAGE \$index_images" >> autoindex.frames endif if("\$fixcell" == "yes") then echo "AUTOINDEX \$FLAGS FIXCELL UNFIXDIST" >> autoindex.frames endif rm -f \${tempfile}.phi_list >& /dev/null if(((\$#CELL != 6)||("\$SG" == "unknown"))&&(! \$?background_DPS)) then # must need to pick these ourselves echo "CELL 10 10 10 10 10 10" >> \$tempfile echo "SYMM P1" >> \$tempfile cat autoindex.frames >> \$tempfile mv \$tempfile autoindex.frames endif # fix up long lines cat autoindex.frames |\\ nawk '{for(i=1;i<=NF;++i){l+=length(\$i)+1; if(l>79){l=0;print"-"} printf "%s ", \$i}; print ""}' |\\ cat >! \$tempfile mv \$tempfile autoindex.frames # write a short script for doing this cat << EOF-autoindex >! autoindex.com #! /bin/csh -fe # # Wedger Elves example background autoindexing script # \${MOSFLM} HKLOUT auto.mtz \\ SPOTOD auto.spotod \\ SUMMARY \${logfile}autoindex.xlog \\ COORDS auto.coords << eof-ipmosflm # GENFILE auto.gen # EOF-autoindex cat autoindex.inp >> autoindex.com if("\$mosaic" == "estimate") echo "MOSAIC \$mosaic" >> autoindex.com #echo "RESOLUTION 3.0" >> autoindex.com cat autoindex.frames >> autoindex.com cat << EOF-autoindex >> autoindex.com # go # eof-ipmosflm EOF-autoindex chmod a+x autoindex.com # try to run LABELIT set index_files = "" foreach num ( \$best_two_index_images ) set file = \`echo "\$template \$num" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` set index_files = ( \$index_files "\${framedir}/\$file" ) if(\$#index_files == 2) break end labelit.screen \$index_files |& tee \${logfile}labelit.log | nawk '/^:\\)/{printf "."}' set labelit_solution = \`nawk '/^:\\)/{print \$2}' \${logfile}labelit.log | tail -1\` if(\$?UNRELIABLE_BEAM && "\$labelit_solution" != "") then set labelit_mat = \`echo \$labelit_solution | nawk '{printf "index%02d.mat",\$1}'\` if(-e "\$labelit_mat") then echo "ran LABELIT on \$index_files" cp \$labelit_mat auto.mat set inmatrix = auto.mat set CELL = \`nawk 'NF == 6' auto.mat |& nawk '{for(i=1;i<=NF;++i) if(\$i+0 > 10) printf \$i+0 " "}'\` #set beam_center = \`nawk '/^:\\)/{print \$4,\$5}' \${logfile}labelit.log | tail -1\` set beam_center = \`nawk '/^Beam center/{print \$4+0,\$6+0}' \${logfile}labelit.log | tail -1\` #unset UNRELIABLE_BEAM set sg = \`nawk '/^:\\)/{print \$3}' \${logfile}labelit.log | tail -1\` if ("\$SG_choice" == "auto" || "\$SG" == "unknown") then set SG = \$sg endif echo " done! " unset autoindexing goto ProcessInput endif else # forget we ever tried this? #rm -f \${logfile}labelit.log endif if(-e \${logfile}autoindex.log) mv \${logfile}autoindex.log \${logfile}autoindex.log.old >& /dev/null # run it (do a timeout?) ./autoindex.com | tee \${logfile}autoindex.log | nawk '/Finding spots/{++frames; printf "."} frames>100{exit}' if(\$status) rm -f auto.mat >& /dev/null if(\$?DPS_INDEX) echo " peak-picking done." # now check and see if dps_index is available DPS_index: if(\$?DPS_INDEX) then # select most-recent spot file set spotfile = \`ls -1rt *.spt | tail -1\` # determine I/sig cutoff to get target number of spots cat \$spotfile |\\ nawk 'NF>5 && \$1!="-99.00" && \$1!="-999.00"{print \$5/\$6}' |\\ sort -nr | head -750 |\\ tail -1 >! \${tempfile}cutoff set cutoff = \`cat \${tempfile}cutoff\` rm -f \${tempfile}cutoff if(\$#CELL == 6) then # target_cell for dps_index #echo "CELL \$CELL" >! \${tempfile}.cell set max_cell = \`echo \$CELL | nawk '{print \$1;print \$2;print \$3}' | sort -nr | nawk '{printf "%d", \$1*1.2; exit}'\` else set max_cell = "" endif echo -n "running dps_index.com " rm -f dps.mat >& /dev/null ./dps_index.com \$spotfile \${wavelength}A \${distance}mm \${tempfile}.cell \${cutoff}sig \$SG \$max_cell no \$wrongSGs | tee -a \${logfile}autoindex.log | nawk '/Generating direct/{printf "."}' if((! \$status)&&(-e dps.mat)) then echo " done." cp dps.mat auto.mat # don't let the error detector below see this grep -v ERROR \${logfile}autoindex.log >! \${tempfile} mv \${tempfile} \${logfile}autoindex.log else echo " failed." rm -f auto.mat >& /dev/null grep -i error \${logfile}autoindex.log echo "see \${logfile}autoindex.log" endif rm -f \${tempfile}.cell >& /dev/null endif ########################################################################### # organize cell and SG data (from background) # convert the dps_index log (if its there) cat \${logfile}autoindex.log |\\ nawk '/^Lattice/{\\ solution=\$2; crys_sys=\$4; score=\$NF*1; \\ getline;getline;getline;getline; cell=substr(\$0,10);\\ print solution, crys_sys, score, cell, "DPS";}' |\\ cat >! \${tempfile}.bravlist # format: solution crys_sys score cell # also convert mosflm DPS log cat \${logfile}autoindex.log |\\ nawk '\$3 ~ /^[amothc][PCIFR]\$/{\\ crys_sys = \$3; solution=\$1; score=\$2/100;\\ sys = substr(crys_sys,1,1); lattice = substr(crys_sys,2); \\ cell = \$4 " " \$5 " " \$6 " " \$7 " " \$8 " " \$9; \\ print solution, crys_sys, score, cell, "DPS";}' |\\ cat >> \${tempfile}.bravlist # format: solution crys_sys score cell # now also convert the REFIX indexing log cat \${logfile}autoindex.log |\\ nawk '\$2 ~ /^[amothc][PCIFR]\$/{\\ crys_sys = \$2; solution=\$1; score=\$3/100;\\ sys = substr(crys_sys,1,1); lattice = substr(crys_sys,2); \\ cell = \$4 " " \$5 " " \$6 " " \$7 " " \$8 " " \$9; \\ if(\$4+0>0) print solution, crys_sys, score, cell, "REFIX";}' |\\ cat >> \${tempfile}.bravlist # format: solution crys_sys score cell # expand this information, using the space group library cat \${tempfile}.bravlist |\\ nawk '! seen[\$1]{print; seen[\$1]=1}' |\\ nawk -v library=\$CLIBD/symop.lib '{\\ solution=\$1; crys_sys=\$2; score=\$3; source=\$NF;\\ sys = substr(\$2,1,1); lattice = substr(\$2,2); \\ cell = \$4 " " \$5 " " \$6 " " \$7 " " \$8 " " \$9; \\ if(sys=="a") sys = "TRICL"; \\ if(sys=="m") sys = "MONOC"; \\ if(sys=="o") sys = "ORTHO"; \\ if(sys=="t") sys = "TETRA"; \\ if(sys=="h") sys = "TRIGO"; \\ if(sys=="c") sys = "CUBIC"; \\ while(getline < library){ \\ if(\$5 ~ /^PG/ && ! /m/ && ! /bar/ && \$1 < 500){\\ SYS=substr(\$6,1,5)\\ LAT=substr(\$4,1,1)\\ if((LAT==lattice || (LAT~/[HR]/ && lattice~/[HR]/)) && (SYS==sys || (SYS=="HEXAG" && sys=="TRIGO"))){\\ print \$1, substr(\$5,3), \$4, crys_sys, \$6, solution, score, cell, source;\\ }\\ }\\ }; close(library);}' |\\ sort -k1nr,2 -k7n,8 |\\ nawk '! seen[\$3]{print; seen[\$3]=1}' |\\ nawk '{a=\$8; b=\$9; c=\$10; A=\$11; B=\$12; G=\$13;latt=\$5}\\ \$5 == "MONOCLINIC" { A=90; ; G=90}\\ \$5 == "ORTHORHOMBIC" {A=90; B=90; G=90}\\ \$5 == "TETRAGONAL" || \$5 == "TRIGONAL" || \$5 == "HEXAGONAL" {\\ a=b=(a+b)/2; A=90; B=90; G=120;}\\ \$5 == "TETRAGONAL" {G=90}\\ \$5 == "CUBIC" {a=b=c=(a+b+c)/3; A=90; B=90; G=90}\\ {print \$0, a, b, c, A, B, G}' |\\ cat >! \${tempfile}.SG.full # format: SG_num PG SG crys_sys lattice solution penalty cell source newcell rm -f \${tempfile}.bravlist # SG.list now contains a list of all space groups # sorted by symmetry and indexing score # now clear unwanted SGs from the list of possibilities echo " \$wrongSGs \$wrongLPGs LIST " |\\ nawk 'BEGIN{RS=" "} NF==1' |\\ cat - \${tempfile}.SG.full |\\ nawk 'NF==1{bad[\$1]=1} {lpg=substr(\$3,1,1)"_"\$2}\\ list && ! bad[\$3] && ! bad[\$4] && ! bad[\$5] && ! bad[lpg] {print}\\ /LIST/{list=1}' |\\ cat >! \${tempfile}.SG.filtered # format: SG_num PG SG crys_sys lattice solution penalty cell source newcell # pick a default solution set solution = \`nawk -v cut=\$autoindexing_cutoff '\$7& /dev/null echo " failed." grep -i error \${logfile}autoindex.log # now what? endif onintr Ask_about_SG: #if(("\$SG" == "unknown")||(\$#CELL != 6)) then if("\$SG" == "unknown") then # user did not indicate a space group earlier # present options to user echo "" echo "" echo "example distortion" echo "space group of cell unit cell" nawk '\$7<3' \${tempfile}.SG.filtered |\\ sort -k1nr,2 -k6n,7 |\\ nawk '{line[\$4]=\$0} END{for(sys in line) print line[sys]}' |\\ sort -nr |\\ nawk '{printf "%-11s %5.3f %8.2f %8.2f %8.2f %5.1f %5.1f %5.1f\\n%20s%8.2f %8.2f %8.2f %5.1f %5.1f %5.1f\\n",\\ \$3, \$7, \$8, \$9, \$10, \$11, \$12, \$13, "", \$15, \$16, \$17, \$18, \$19, \$20}' set temp = "\$bestSG" echo "What is your space group? [\$temp]" echo -n "\$PROMPT" if(! \$?AUTO) then echo -n "\$BELL" set in = ( \$< ) if("\$in" == "") then # interactive user, but they just hit "Enter" set SG_choice = auto else set temp = ( \$in ) # user just typed something in set SG_choice = user endif else echo "\$temp" # auto mode, SG choice is automatic set SG_choice = auto endif if("\$temp" == "none of them") then # user didn't like any of the choices set SG = "unknown" set temp = "" endif if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) then set SG = \`nawk -v SG=\$temp '\$4==toupper(SG){print \$4;exit}' \${CLIBD}/symop.lib\` set SG_number = \`nawk -v SG=\$temp '\$4==toupper(SG){print \$1;exit}' \${CLIBD}/symop.lib\` else if((\$#temp > 1)&&(! \$?AUTO)) then # go to the open interpreter set input = ( \$temp ) rm -f \${tempfile}.SG.full \${tempfile}.SG.filtered >& /dev/null goto Questionaire endif endif if("\$SG" != "unknown") then # dont change cell (can affect indexing search) #set CELL = \`nawk -v SG=\$SG '\$3==SG{print \$15, \$16, \$17, \$18, \$19, \$20}' \${tempfile}.SG.full\` # now go back and use this cell and SG echo "indexing again, with \$SG" #echo " and cell: \$CELL" echo "SYMM \$SG_number" >> autoindex.inp if("\$CELL" != "unknown") echo "CELL \$CELL" >> autoindex.inp set SECOND_INDEXING_ROUND if(\$?DPS_INDEX) goto DPS_index goto Index_again endif # no space group was given if(("\$SG" == "unknown")&&("\$temp" != "")) then # no space group was given set SG = "unknown" echo 'Sorry, "'\$temp'" is not in the space group library.' goto Ask_about_SG endif # user said "none of them", so we go on to failure mode below. endif rm -f \${tempfile}.SG.full \${tempfile}.SG.filtered >& /dev/null # check to make sure indexing succeeded if(-e auto.mat) then # make sure this looks like a real matrix set cell = \`nawk 'NF == 6' auto.mat |& nawk '{for(i=1;i<=NF;++i) if(\$i+0 > 10) printf \$i+0 " "}'\` # and make sure mosflm was reasonably happy set mosflm_errors = 0 grep ERROR \${logfile}autoindex.log if(! \$status) set mosflm_errors = 1 if((\$mosflm_errors && ! \$?SECOND_INDEXING_ROUND)||(\$#cell != 6)) then # probably bad. mv auto.mat bad.mat >& /dev/null else set CELL = ( \$cell ) endif endif if(! -e auto.mat) then echo "\$BELL autoindexing failed. " # nawk '/ERROR/{print; getline; print; getline; print; getline; print}' \${logfile}autoindex.log # don't give up, try more images if((\$#index_images < 20)&&(\$#index_images < \$number_of_frames)) then @ autoindexing_frames = (\$autoindexing_frames + 2) # one of these might be better if("\$fixcell" == "yes") then set fixcell = "no" echo "trying again with free cell" else set fixcell = "yes" echo "trying again with cell fixed at \$CELL" endif goto Index_again else # this ain't hapening onintr # curse these spots rm -f *.spt >& /dev/null rm -f autoindex.frames >& /dev/null # ask about denzo if old-style indexing isn't working if(("\$MosflmVersion" !~ [678]*)&&((-e /usr/local/lib/cr_info)||(-e ~/cr_info)||(-e ./cr_info))) then echo "NOTICE:" echo "MOSFLM Version \$MosflmVersion does not index nearly as well as version 6.x, or above." echo "" set temp = "Yes" echo "Do you want us to try using denzo (you need a \$Site licence)? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" =~ [Yy]*) goto denzo if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # strange answer, send to interpreter set input = "\$temp" goto Questionaire endif endif goto Manual_Index endif endif # if auto.mat exists, it is good. if(! \$?DPS_INDEX) echo " done! " onintr unset autoindexing if("\$strategize" == "done") set strategize = yes unset Convergeing set NEW unset SECOND_INDEXING_ROUND echo "" # read an estimated mosaicity if("\$mosaic" !~ *[0-9]*) then set temp = \`nawk '/mosaicity has been estimated/ && \$8+0>0.1 && \$8+0<5{print \$8}' \${logfile}autoindex.log | head -1\` if("\$temp" != "") then set mosaic = "\$temp" echo "mosaicity estimated at: \$mosaic" endif endif # clean up rm -f autoindex.frames >& /dev/null rm -f auto.mtz >& /dev/null rm -f auto.spotod >& /dev/null rm -f auto.coords >& /dev/null rm -f auto.mtz >& /dev/null #rm -f *.spt >& /dev/null set inmatrix = "auto.mat" set integrate = "no" set postref = "yes" # probably should refine mosflm cell #set fixcell = "yes" set fixyscale = "yes" # alert user that we are ready if(! \$?AUTO) echo -n "\$BELL" goto ProcessInput exit Manual_Index: onintr ########################################################################### ##### ##### #### # # # ##### ###### # # # # # # # # ## # # # # # # # # # # #### # # # # # # ##### ## # # ##### # # # # # # # # ## # # # # # # # ## # # # # # ##### # #### # # # ##### ###### # # ########################################################################### # # Interactive MOSFLM indexing (much better in version 6! ) # ########################################################################### if("\$MosflmVersion" =~ [678]*) then cat << EOF #################################################################################### WHAT TO DO NEXT: 1) Say "Yes" to the question below. 2) the big Mosflm graphics window should come up. 3) Click on "Autoindex" and follow the directions you see. 4) If nothing too scary happens Click on "Predict" 5) If you see little boxes around your spots, You WIN! (auto.mat is your new matrix) You might also want to take this opportunity to define your backstop shadow using the "KEYWORDED INPUT" button and typing something like: "BACKSTOP CENTER \$beam_center RADIUS 3" 6) "Exit" Mosflm, and come back here. IF SOMETHING GOES WRONG: 1) Click on "Read Image" to read in another image far away (in PHI) from the current one. 2) Click on "Find Spots". The spots picked here will be added to a cumulative list. 3) repeat 1) and 2) for 2 or 3 (maybe more) images. 4) now click on "Autoindex" (using spots from several images can index almost anything) #################################################################################### EOF else cat << EOF #################################################################################### WHAT TO DO NEXT: 1) Say "Yes" to the question below. 2) the big Mosflm graphics window should come up. (if not, read the errors and make sure CCP4 is set up) 3) Click on "Find Spots" (and follow the instructions you see) 4) Click on "Read Image" and type in an image far from the last one. 5) Do 3) and 4) for 4 or so images, as widely separated in PHI as possible! 6) Click on "Autoindex" (make sure you FIX either the cell or the distance) 7) Cross your fingers. 8) If nothing too scary happens Click on "Predict" 9) If you see little boxes around your spots, You WIN! (auto.mat is your new matrix) 10) Exit Mosflm, and come back here. IF SOMETHING GOES WRONG: 1) download a more recent version of ipmosflm from: netscape ftp://ccp4a.dl.ac.uk/pub/ccp4/ the new DPS indexing is vastly superior to the one in this version. #################################################################################### EOF endif set temp = "Yes" if(\$?AUTO) set temp = "No" echo "launch mosflm and do some autoindexing now? [\$temp]" echo -n "\$PROMPT" if(! \$?AUTO) then echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) else echo "\$temp" endif if("\$temp" =~ [Yy]*) goto LAUNCH if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # strange answer, send to interpreter set input = "\$temp" goto Questionaire endif # see if denzo might run if((-e /usr/local/lib/cr_info)||(-e ~/cr_info)||(-e ./cr_info)) then set temp = "Yes" if(\$?AUTO) set temp = "No" echo "Try using denzo? [\$temp]" echo -n "\$PROMPT" if(! \$?AUTO) then echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) else echo "\$temp" endif if("\$temp" =~ [Yy]*) goto denzo if(("\$temp" !~ [Nn]*)||(\$#temp > 1)) then # strange answer, send to interpreter set input = "\$temp" goto Questionaire endif endif # Last chance set temp = "quit" echo "What do you want to do? [\$temp]" echo -n "\$PROMPT" if(\$?AUTO) then echo \$temp else echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) endif if("\$temp" !~ [Qq]*) then set input = "\$temp" goto Questionaire endif Noautoindex: # you never know... onintr # user doesn't seem to want to do anything cat << EOF #################################################################################### #################################################################################### #################################################################################### You can still use the file autoindex.inp as a guide for setting up autoindexing. #################################################################################### 1) start Mosflm by typing: \$MOSFLM 2) enter your crystal/beam/camera paramters by typing: MOSFLM> @autoindex.inp 3) Enter the name of an image you want to start with MOSFLM> image \$FirstImage 4) and then type: MOSFLM> go the big Mosflm graphics window should come up. (if not read the errors and make sure CCP4 is set up) 5) if you have Mosflm 6.xx, skip to step 10) (below). 6) Click on "Find Spots" (and follow on-screen instructions) 7) Click on "Read Image" and type in an image far from the last one. 8) Do 6) and 7) for 4 or so images, as widely separated in PHI as possible! 9) Click on "Autoindex" (make sure you FIX either the cell or the distance) 10) Click on "Predict" 11) If you see little boxes around your spots, You WIN! 12) Start postrefining or integrating, (or just exit and run \$0 again) Good luck. EOF goto Cleanup LAUNCH: if(! \$?DISPLAY) then # woops! this isn't going to work! if(\$?REMOTEHOST) setenv DISPLAY \${REMOTEHOST}:0 if(! \$?DISPLAY) setenv DISPLAY :0 endif set phiend = \`echo \$phi0 \$osc | nawk '{print \$1 + \$2}'\` set first_frame = \`basename \$FirstImage\` if("\$TEMPLATE" != "") set first_frame = "\$first" # sometimes it is better to let MOSFLM read the header set philist = "" if(\$?BAD_HEADER) set phillist = "PHI \$phi0 to \$phiend" # write the interactive autoindexing script cat << EOF-autoindex >! autoindex.com #! /bin/csh -fe # # Wedger Elves example interactive indexing script # \${MOSFLM} HKLOUT auto.mtz \\ SPOTOD auto.spotod \\ SUMMARY \${logfile}autoindex.xlog \\ COORDS auto.coords << eof-ipmosflm # GENFILE auto.gen # EOF-autoindex cat autoindex.inp >> autoindex.com cat << EOF-autoindex >> autoindex.com RESOLUTION 3 SYMM 0 # #IMAGE \$first_frame PHI \$phi0 to \$phiend IMAGE \$first_frame \$philist # go # eof-ipmosflm EOF-autoindex chmod a+x autoindex.com # run it (output to screen) ./autoindex.com if((\$status)||(! -e auto.mat)) then echo "" echo "AAAAACK! What happened? " echo "" echo "Let's try that again, shall we? ... " if("\$MosflmVersion" =~ [678]*) then echo "" echo "Try DPS indexing off of more than one frame this time. " echo "" endif goto Manual_Index endif echo "" echo "There, now wasn't that fun? :)" echo "" set sg = "\$SG" # if ".sav" file was selected, it should be newer than the matrix set savfile = \`ls -1rt *.sav *.mat |& tail -1\` if("\$savfile" !~ *.sav) set savfile = "" if(("\$sg" == "unknown")&&(-e "\$savfile")) then # get the chosen space group from the savfile set sg = \`nawk '/^SYMM/{print \$2}' \$savfile\` if("\$sg" != "") then # get SG name from CCP4 library set sg = \`nawk -v num=\$sg '\$1 == num {print \$4;exit}' \$CLIBD/symop.lib | head -1\` endif if("\$sg" == "") set sg = "\$SG" endif if("\$sg" == "unknown") then # grab a reasonable space group from the logfile set sg = \`nawk 'NF==10 && \$1+0>0 && \$2 < 25' mosflm.lp |& head -1 |& nawk '{print \$NF}' |& nawk 'BEGIN{FS=","} {print \$NF}'\` endif set temp = "\$sg" echo "What space group did you pick? [\$temp]" echo -n "\$PROMPT" echo -n "\$BELL" set in = ( \$< ) if("\$in" != "") set temp = ( \$in ) if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) then set SG = "\$temp[1]" set SG_choice = user endif unset autoindexing set NEW if("\$strategize" == "done") set strategize = yes mv mosflm.lp \${logfile}autoindex.log >& /dev/null mv *spot temp >& /dev/null # what to do with the ".sav" file. # too much or too little information? if(-e "\$savfile") then egrep -v "\$PASSTHRU_CARDS" \$savfile >! \${tempfile}sav grep "BACK" \$savfile >> \${tempfile}sav # OR egrep -v "DISTO|RAST|ADCOFF|MATRIX|RESO|GENF|PROFILE|SEPARATION" \$savfile >! \${tempfile}sav mv \$savfile \${savfile}.old mv \${tempfile}sav \$savfile endif set inmatrix = auto.mat set oldscripts = "\$savfile" set lastlog = \${logfile}autoindex.log set sources = "\$lastlog \$oldscripts \$inmatrix" goto GetParamsFromSources set inmatrix = auto.mat set lastlog = \${logfile}autoindex.log goto FindMATRIX exit denzo: ################################################################################################ ##### ###### # # ###### #### # # # ## # # # # # # ##### # # # # # # # # # # # # # # # # # # # ## # # # ##### ###### # # ###### #### ################################################################################################ # # Sometimes, you do need an expensive program # ################################################################################################ set denzo = denzo set xfile = auto.x # first of all, make sure there is a cr_info file in the right place if((! -e /usr/local/lib/cr_info)&&(! -e ~/cr_info)&&(! -e ./cr_info)) then echo "no cr_info files found." echo " Denzo will not run without a cr_info file, appropriate " echo " for your machine and detector, in: " echo " /usr/local/lib/" echo " ~/cr_info" echo " or ./cr_info" if(\$?AUTO) goto Cleanup goto Index_again endif # get most recent spot pick. set spotfile = \`ls -1rt *.spt |& grep "\$frameprefix" |& tail -1\` if(! -e "\$spotfile") then # no spots picked yet, force mosflm to pick some echo "picking spots in \$FirstImage ... " \${MOSFLM} HKLOUT pick.mtz \\ SPOTOD pick.spotod \\ SUMMARY pick.xlog \\ COORDS pick.coords << eof-ipmosflm >&! \${logfile}pick.log # GENFILE pick.gen # @autoindex.inp RESOLUTION 3 # # make up a cell so mosflm will run CELL KEEP 10 10 10 90 90 90 SYMM P1 AUTOINDEX IMAGE \$first PHI 0 1 FIXCELL # this will fail miserably, but it will pick spots go # eof-ipmosflm set spotfile = \`ls -1rt *.spt |& grep "\$frameprefix" |& tail -1\` if(! -e "\$spotfile") then echo "spot picking failed. Dagnabbit! " echo "look at \${logfile}pick.log to see why. " goto Cleanup endif else echo -n "using spots in \$spotfile ... " cat \$spotfile | wc -l endif # clean up after spot picking rm -f pick.* >& /dev/null rm -f auto.mat >& /dev/null rm -f \${logfile}pick.log >& /dev/null # convert the mosflm spots (mm) to denzo format (pixels) ################################################################################################ cat \$spotfile |\\ nawk '\\ NR==1{\\ pixelwidth = \$3; ratio = \$4;\\ printf " 7777%7.1f 0.0 1 1\\n", \$1;\\ }\\ NR==4,\$1=="-99.00"{\\ if(\$1 > 0) printf "%10d%7.1f%7.1f 1 1\\n", \$NF, \$1/pixelwidth, \$2/(pixelwidth/ratio);\\ }' >! \${tempfile} nawk '\$1 == "7777"' \${tempfile} >! peaks.file nawk '\$1 != "7777" && NF==5' \${tempfile} | sort -n -k2 >> peaks.file rm -f \${tempfile} if("\$Site" =~ *mar*) then # Denzo has a different origin for MAR cat peaks.file |\\ nawk 'NR == 1{edge = \$2} \\ edge != 0{printf "%10d%7.1f%7.1f 1 1\\n", \$1, edge-\$3, \$2}' |\\ cat >! \${tempfile} mv \${tempfile} peaks.file endif DENZOagain: # make denzo's autoindexing file ################################################################################################ echo "creating auto.dat for denzo" if("\$Site" =~ *ADSC*) then set denzostuff = "\$beam_center " cat << EOF-adsc >! auto.dat format ccd adsc unsupported-q4 [values good for ADSC Q4] error density 0.12 error positional 0.04 error systematic 5.0 partiality 0.1 film rotation 90.0 crossfire y .004 x -.004 xy -.019 cassette rotx \$two_theta roty -.07 rotz .00 EOF-adsc endif if("\$Site" == "RAXIS II") then set denzostuff = "\$beam_center " echo "format raxis" >! auto.dat endif if("\$Site" == "RAXIS IV") then set denzostuff = "\$beam_center " echo "format raxis4 100" >! auto.dat endif if("\$Site" =~ *mar*) then # make proper format card for denzo head -30 \$FirstImage |\\ nawk '/^PROGRAM/{type = \$2} \\ /^FORMAT/{w=\$2; if(\$0 ~ /PCK/) comp = "marpck"} \\ /^PIXEL/{pixel = \$3} \\ END{print "format", type, w*pixel/1000 "mm", pixel, comp}' |\\ cat >! auto.dat # need to (temporarily) change the beam center too set denzostuff = \`echo "\$beam_center \$Site" | nawk '{print \$NF-\$2, \$1}'\` endif # beam center defined above set temp = \`echo \$POLARISATION | nawk '/MONO/{print "graphite"} ! /MONO/{print \$NF+0}'\` set denzostuff = "\$denzostuff \$temp" set temp = \`nawk -v wl=\$wavelength 'BEGIN{print 3147.7 * ( wl )^(-3.014)}'\` set denzostuff = "\$denzostuff \$temp" set temp = \`echo \$distance | nawk -v angle=\$two_theta '{print \$1/cos(angle*3.1415/180)}'\` set denzostuff = \`echo \$denzostuff \$temp\` set print_sg = "" if("\$SG" != "unknown") set print_sg = "space group \$SG" cat << EOF >> auto.dat box print 2 2 spot radius 0.3 background radius 0.3 mosaicity 0.5 overlap spot wavelength \$wavelength monochromator \$denzostuff[3] air absorption length \$denzostuff[4] overload value \$OVERLOAD distance \$denzostuff[5] profile fitting radius 20.0 \${print_sg} resolution limits 25. \$hires x beam \$denzostuff[1] y beam \$denzostuff[2] cassette rotx \`echo \$two_theta | nawk '{print -\$1}'\` TITLE 'autoindex \$FirstImage' raw data file '\$FirstImage' oscillation start \$phi0 range \$osc film york output file 'auto.x' sector 1 longest vector 300 peak search file 'peaks.file' write predictions fix all go go fit cell fit x beam y beam fit crystal rotx roty rotz fit distance go go go go go go go go go go go go go go go go go go go go fit all go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go go calculate go exit EOF unset print_sg FindDENZO: if(! \$?AUTO) onintr NoDenzoSolutions # hunt for denzo that will give an acceptable autoindexing solution ################################################################################################ # don't risk reading an inappropriate auto.x if(-e "\$xfile") then # probably iterating here, back it up mv \$xfile \${xfile}.old endif set bad_denzo = 0 # look for aliases if(! -e "\$xfile") then if(! -e "\$denzo") then foreach filename ( \$denzo denzo ) if(! -e "\$denzo") then set temp = \`which \$filename |& grep -v ' not in ' |& tail -1\` foreach word ( \$temp ) if((-e "\$word")&&(! -e "\$denzo")) then set denzo = \`ls -ln \$word |& nawk '\$1 ~ /x/ && \$5 > 500000 && ! /^d/ {print \$NF}'\` endif end endif end endif if(-e "\$denzo") then # see if this denzo file will autoindex for us echo -n "trying \$denzo ... " mv \${logfile}denzo.log \${logfile}denzo.log.old >& /dev/null \$denzo < auto.dat >&! \${logfile}denzo.log # verify that preds were tolerably close set temp = \`nawk '/ chi/ && / x / && / y /{printf "%d\\n", substr(\$0,index(\$0," x ")+3)+ substr(\$0,index(\$0," y ")+3)}' \${logfile}denzo.log | tail -1\` if((-e "\$xfile")&&("\$temp" != "")) then if(\$temp < 6) then echo "indexed. " else echo "bad solution. chi^2 ~ \$temp" mv \$xfile not_so_good.\$temp.\$xfile @ bad_denzo = (\$bad_denzo + 1) endif else if(-e "\$xfile") rm -f \$xfile >& /dev/null echo "bust." endif endif else echo "found \${xfile}! Will use it to get orientation in denzo.mat ..." endif # look in directories if(! -e "\$xfile") then echo "Looking for denzo ... " # look down a list of standard places for the executable foreach place ( ./ ../ ../../ ../../../ /programs/HKL/newest/ /programs/HKL/1.9.1/ /usr/local/newest/ /programs/HKL/ /programs/denzo/ /programs/ /usr/local/bin/ /usr/local/ ) # stop looking once autoindexing has been done if((! -e "\$xfile")&&(-e "\$place")) then # look for executable files named "denzo" in \$place foreach file ( \`ls -lnL \${place} |& sort -k5n |& nawk ' /^-/ && \$1 ~ /x/ && (\$NF ~ "denzo"){print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l0 || NR==1)' |& head -1\` echo -n "trying \$denzo ... " mv \${logfile}denzo.log \${logfile}denzo.log.old >& /dev/null \$denzo < auto.dat >&! \${logfile}denzo.log # verify that preds were tolerably close set temp = \`nawk '/ chi/ && / x / && / y /{printf "%d\\n", substr(\$0,index(\$0," x ")+3)+ substr(\$0,index(\$0," y ")+3)}' \${logfile}denzo.log | tail -1\` if((-e "\$xfile")&&("\$temp" != "")) then if(\$temp < 6) then echo "indexed. " else echo "bad solution. chi^2 ~ \$temp" mv \$xfile not_so_good.\$temp.\$xfile @ bad_denzo = (\$bad_denzo + 1) endif else if(-e "\$xfile") rm -f \$xfile >& /dev/null echo "bust." endif endif end endif end endif # get agressive, use "find" if(! -e "\$xfile") then echo "looking harder ... " foreach place ( ../../../ /programs/ /usr/local/bin/ /usr/local/ ) # look for files of right type if((! -e "\$xfile")&&(-e "\$place")) then # look for links first set temp = \`find \$place -name denzo -type l -perm -1 -print |& nawk '! /^find:/' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 100000 && /denzo/ {print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null \$denzo < auto.dat >&! \${logfile}denzo.log # verify that preds were tolerably close set temp = \`nawk '/ chi/ && / x / && / y /{printf "%d\\n", substr(\$0,index(\$0," x ")+3)+ substr(\$0,index(\$0," y ")+3)}' \${logfile}denzo.log | tail -1\` if((-e "\$xfile")&&("\$temp" != "")) then if(\$temp < 6) then echo "indexed. " else echo "bad solution. chi^2 ~ \$temp" mv \$xfile not_so_good.\$temp.\$xfile @ bad_denzo = (\$bad_denzo + 1) endif else if(-e "\$xfile") rm -f \$xfile >& /dev/null echo "bust." endif endif end # then look at actual files foreach file ( \`find \$place -name \\*denzo\\* -type f -size +1000 -perm -1 -print |& nawk '! /^find:/' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null \$denzo < auto.dat >&! \${logfile}denzo.log # verify that preds were tolerably close set temp = \`nawk '/ chi/ && / x / && / y /{printf "%d\\n", substr(\$0,index(\$0," x ")+3)+ substr(\$0,index(\$0," y ")+3)}' \${logfile}denzo.log | tail -1\` if((-e "\$xfile")&&("\$temp" != "")) then if(\$temp < 6) then echo "indexed. " else echo "bad solution. chi^2 ~ \$temp" mv \$xfile not_so_good.\$temp.\$xfile @ bad_denzo = (\$bad_denzo + 1) endif else if(-e "\$xfile") rm -f \$xfile >& /dev/null echo "bust." endif endif end endif end endif NoDenzoSolutions: onintr if((! -e "\$xfile")&&(\$?AUTO)) then if("\$bad_denzo" > 0) then # might as well charge ahead set temp = \`ls -1 not_so_good* | nawk 'BEGIN{RS="."} /[0-9]/' | sort -n | head -1\` set xfile = \`ls -1 not_so_good* | egrep "\\.\$temp\\."\` if(-e "\$xfile") goto Done_With_Denzo else echo "" echo "We couldn't find any denzo's that would run. You probably don't have a license here." if(\$MosflmVersion !~ [678]*) then echo "Next time, try entering a CELL and Space Group, and you might be suprised at how" echo "well mosflm can index too! " else echo "Next time, try the new, interactive DPS indexing in Mosflm Version 6." echo "It is just as good as denzo. " endif echo "" echo "Out of options. Sorry! " goto Cleanup endif endif # whimper pitifully while(! -e "\$xfile") set temp = "" echo "" echo "WARNING: can't find a denzo that will autoindex." if(\$bad_denzo) then echo " Although \$bad_denzo gave poor solutions. \$BELL " echo "Are you sure the beam center/etc. was right? [No]" echo -n "\$PROMPT" set temp = "\$<" if("\$temp" !~ [Yy]*) goto Questionaire endif echo "Where is denzo [forget it]?" if(! \$?AUTO) then echo -n "\$PROMPT" set temp = "\$<" else set temp = "" endif if(("\$temp" == "")||("\$temp" =~ forget*)) then # prevent an infinite loop if(\$?AUTO) goto Noautoindex goto autoindex endif # something was entered if(\$#temp > 1) then # must mean something other than a filename set input = "\$temp" goto Questionaire endif # single word given set denzo = "\$temp" # set bad_denzo = 0 echo -n "trying \$denzo ... " mv \${logfile}denzo.log \${logfile}denzo.log.old >& /dev/null \$denzo < auto.dat >&! \${logfile}denzo.log if(-e "\$xfile") then # verify that preds were tolerably close set temp = \`nawk '/ chi/ && / x / && / y /{printf "%d\\n", substr(\$0,index(\$0," x ")+3)+ substr(\$0,index(\$0," y ")+3)}' \${logfile}denzo.log | tail -1\` if(("\$temp" != "")&&(\$temp < 6)) then echo "thanks! " else echo "sorry, bad solution. chi^2 ~ \$temp" mv \$xfile not_so_good.\$temp.\$xfile endif else echo -n "nope." if(! -e "\$denzo") then echo " \$denzo doesn't exits." else echo " didn't work." endif endif end ################################################################################################ # X file has been produced! ################################################################################################ # get refined parameters from .x file (SG should be same one we put in) set temp = \`nawk '/cell/{for(i=1;i<=NF;++i){if(\$i ~ /[0-9]/)printf "%12.4f",\$i}} END{print ""}' \$xfile\` if(\$#temp == 6) set CELL = \`echo \$temp\` #set SG = \`nawk '/space group/{print toupper( \$NF )}' \$xfile\` # get new beam center set temp = \`nawk '/beam /{for(i=2;i! \${tempfile}.spacegroups # pick highest symmetry space group with distortion < 1% set sg = \`nawk -v accept=1 '\$2 < accept && ! done {print \$1;done=1}' \${tempfile}.spacegroups\` if(("\$SG" != "\$sg")&&("\$sg" != "")) then # denzo seems to disagree with our space group if("\$SG_choice" == "auto") then # space group started out "unknown" so this one might be ever better set SG = "\$sg" endif echo -n "space group \${sg} looks best to me. " if("\$SG" != "unknown") echo -n "\$SG will be used." echo "" # if SG is "unknown", thes user had no idea what SG is if("\$SG" == "unknown") then # better than nuthn' set SG = "\$sg" set SG_choice = auto endif # go back and re-autoindex with this space group (and refined parameters) if("\$SG_choice" == "auto") then # maybe alter auto.dat? goto DENZOagain endif endif # if all else fails, just use P1 if(("\$SG" == "unknown")||("\$SG" == "")) set SG = P1 # clean up denzo files rm -f \$spotfile >& /dev/null #rm -f peaks.file >& /dev/null rm -f hklpredictions >& /dev/null rm -f fort* >& /dev/null rm -f \${tempfile}.spacegroups >& /dev/null #mv \${tempfile}.spacegroups denzo.spacegroups Done_With_Denzo: # convert orientation to a mosflm matrix ################################################################################################ # extract the unitary matrix head -24 \$xfile |& nawk 'NF == 6{printf "%12.8f%12.8f%12.8f\\n", \$4, \$5, \$6}' >! \${tempfile}.umat # make sure this new matrix is unitary cat \${tempfile}.umat |\\ nawk '{++i; for(j=1;j<4;++j){mat[i,j]=\$j+0}} \\ END{det += mat[1,1]*((mat[2,2]*mat[3,3])-(mat[2,3]*mat[3,2])) \\ det -= mat[1,2]*((mat[2,1]*mat[3,3])-(mat[2,3]*mat[3,1])) \\ det += mat[1,3]*((mat[2,1]*mat[3,2])-(mat[2,2]*mat[3,1])) \\ printf "%.4f", det}' >&! \$tempfile set det = \`cat \$tempfile\` rm -f \$tempfile >& /dev/null rm -f \${tempfile}.umat >& /dev/null if("\$det" == "1.0000") then # now go on and check this new matrix in the usual way ... set integrate = "no" set postref = "yes" set fixcell = "yes" set fixyscale = "yes" unset autoindexing set NEW if("\$strategize" == "done") set strategize = yes set inmatrix = auto.x set oldscripts = "\$xfile auto.dat" set sources = "\$inmatrix \$oldscripts" goto GetParamsFromSources else echo "WARNING: auto.x is not a valid matrix ... ignoring it." rm -f auto.mat if(\$?AUTO) goto Noautoindex goto autoindex endif exit Strategy: echo -n "strategizing ... " if(! \$?AUTO) then onintr SkipStrategy echo -n "(Ctrl-C to skip) " endif echo "" ########################################################################## #### ##### ##### ## ##### ###### #### # # # # # # # # # # # # # # #### # # # # # # ##### # # # # ##### ###### # # # ### # # # # # # # # # # # # # #### # # # # # # ###### #### # ########################################################################## # reset resolution limit to edge of detector (if possible) set strat_res = \$hires if(\$?edge_res) then set strat_res = \`echo "\$edge_res \$hires" | nawk '\$1+0>\$2+0{print \$1+0} \$1+0<=\$2+0{print \$2+0}'\` endif if("\$res_choice" != "auto") set strat_res = \$hires set phi_end = \`echo "\$phi0 \$osc \$last \$first" | nawk '{print \$1+\$2*(\$3-\$4+1)}'\` set strat_range = \`echo "\$phi0 \$phi_end" | nawk '{printf "start %d end %d", \$1-10, \$2+10}'\` #echo "creating strategy.com..." set print_swing = "" set print_cell = "" set print_sg = "" set mosflmSG = \$SG if("\$SG" =~ P2*2*2*) set mosflmSG = P222 if("\$SG" =~ R* || "\$SG" =~ H*) set mosflmSG = \$SG_number set temp = \`echo "\$two_theta" | nawk '{printf "%d", \$1+0}'\` if("\$temp" != "0") set print_swing = "SWUNG_OUT " if(\$#CELL == 6) set print_cell = "CELL \$CELL" if("\$SG" != "unknown") set print_sg = "SYMMETRY \$mosflmSG" # must have a valid SEPARATION for strategy set separation if("\$separation" == "") then # get separation from preamble? set separation = \`echo "\$PREAMBLE" | nawk 'BEGIN{RS="n"} {print}' | nawk '/^SEPA/ && \$2*\$3>0{print \$2+0, \$3+0}' |& tail -1 | nawk 'NF==2'\` endif set logfiles = \`ls -1rt \${logfile}/* |& awk 'NF==1'\` if("\$logfiles" == "") set logfiles = logs/strategy.log if("\$separation" == "") then # get a separation, from some old log set separation = \`nawk '/SEPARATION/ && /mm\$/ && \$NF+0>0{print \$(NF-1)+0, \$NF+0}' \$logfiles |& tail -1 | nawk 'NF==2'\` endif if("\$separation" == "") then # get a separation, any separation, from some old log set separation = \`nawk '/have been set to/ && /mm.\$/ && \$NF+0>0{print \$(NF-1)+0, \$NF+0}' \$logfiles |& tail -1 | nawk 'NF==2'\` endif if("\$separation" == "") set separation = "1 1" set first_frame = \`echo "\$template \$first" | nawk 'BEGIN{FS="\\043"} {print \$1 "%0" NF-1 "d" \$NF}' | nawk '{printf \$1,\$2}'\` if("\$TEMPLATE" != "") set first_frame = "\$first" set print_overload = "OVERLOAD CUTOFF \$OVERLOAD" set test = \`echo \$OVERLOAD | nawk '{print (\$1+0<1000)}'\` if(\$test) then set print_overload = "" endif set print_gain = "GAIN \$GAIN" set test = \`echo \$GAIN | nawk '{print (\$1+0<=0)}'\` if(\$test) then set print_gain = "" endif set print_beam = "BEAM \${print_swing}\$beam_center" if(\$?UNRELIABLE_BEAM) set print_beam = "#\$print_beam" set EXTENSION if("\$ext" != "") set EXTENSION = "EXTENSION" if("\$mosaic" == "estimate") then set mosaic = 0.4 endif set print_pixel = "" set print_LIMITS = "\$LIMITS" set max_osc if("\$SCANNER" =~ *PILATUS*) then set print_pixel = "PIXEL \$PIXEL" # heck with this if we have instant-retrigger? #set max_osc = \`echo \$mosaic | awk '{print "maxosc",\$1/4}'\` set print_LIMITS = "LIMITS RMAX 500 YMAX 434.644 XMAX 423.636 XSCAN 423.636 YSCAN 434.644" endif cat << EOF-stratstart >! strategy.com.start #! /bin/csh -fe # # Wedger Elves example STRATEGY session # \${MOSFLM} HKLOUT strategy.mtz \\ SPOTOD strategy.spotod \\ SUMMARY \${logfile}strategy.xlog \\ COORDS strategy.coords << eof-ipmosflm # GENFILE strategy.gen # # the following keywords were not understood by the Wedger elves, but passed on # because they resemble mosflm commands. # ---- \`echo "\$PREAMBLE" | nawk 'BEGIN{RS="n"} {print}'\` # ---- # Detector parameters (range, quantum gain, etc.) \$SCANNER \$print_overload \$print_gain \$print_LIMITS \$print_pixel # Beam parameters (i.e. (delta-lambda)/lambda, H,V divervence in degrees) WAVELENGTH \$wavelength DISPERSION \$DISPERSION DIVERGENCE \$DIVERGENCE POLARISATION \$POLARISATION # Alignment parameters DISTANCE \$distance \$print_beam TWOTHETA \$two_theta MATRIX \$inmatrix # # Crystal parameters \${print_cell} \${print_sg} RESOLUTION \$strat_res MOSAIC \$mosaic # Frame filename breakdown DIRECTORY \$framedir IDENTIFIER \$frameprefix \$EXTENSION \$ext \$TEMPLATE # # # un-comment the following lines to run strategy interactively #IMAGE \$first_frame #GO # EOF-stratstart unset print_swing unset print_cell unset print_sg if("\$mosaic" == "estimate") then echo "IMAGE \$first_frame" >> strategy.com.start echo "go" >> strategy.com.start endif cat << EOF-stratopts >! strategy.com.end # current strategy #strategy start \$phi0 end \$phi_end speedup 1 strategy start \$phi0 end \$phi_end go start \$phi0 end \$phi_end go stats end # calculate best oscillation widths SEPARATION \$separation testgen start \$phi0 end \$phi_end minosc \$osc overlap 3 \$max_osc go # best "next" strategy (given that "current" data are already collected) strategy start \$phi0 end \$phi_end PARTS 2 run strategy auto go stats end # best, overall strategy strategy auto go stats end # best, overall strategy for anomalous strategy auto anomalous go stats end # calculate best oscillation widths SEPARATION \$separation testgen start 0 end 180 minosc 0.01 overlap 3 \$max_osc go EOF-stratopts # now create an executable com file if(-e strategy.com) mv strategy.com strategy.com.old cat strategy.com.start >! strategy.com cat strategy.com.end |\\ nawk '/current strategy/,/already collected/' >> strategy.com echo "eof-ipmosflm" >> strategy.com chmod a+x strategy.com # run the strategy ./strategy.com >! \${logfile}strategy.log # print out reports of strategy run # read an estimated mosaicity if("\$mosaic" !~ *[0-9]*) then set temp = \`nawk '/mosaicity has been estimated/ && \$8+0>0.1 && \$8+0<5{print \$8}' \${logfile}strategy.log | head -1\` if("\$temp" != "") then set mosaic = "\$temp" echo "mosaicity estimated at: \$mosaic" endif endif # sumarize current wedge for user cat \${logfile}strategy.log |\\ nawk -v res=\$strat_res '/These segments contain / && /of the unique data/{complete = \$4+0} \\ /ANOMALOUS DATA/ {getline; getline; getline; anom = \$5+0} \\ END{printf "This wedge will be %.1f%% complete to %.1f A and contain %.1f%% of anomalous data.\\n", complete, res, anom}' cat \${logfile}strategy.log |\\ nawk '/TESTGEN OPTION/,/IMPORTANT/' |\\ nawk '/minimum percentage/ && /oscillation angle above/ && \$9+0>1{print \$9, \$3}' |\\ sort -n | tail -1 |\\ nawk -v osc="\${osc}\$DEG" '{printf "WARNING! with %s oscillations you will have %s overlaps when phi = %s\\n", osc,\$1,\$2+0}' ########################################################################## ########################################################################## # do best "complement wedge" if completeness is not already >99% #set temp = \`nawk '/These segments contain / && /unique/{printf "%d\\n", \$4+0}' \${logfile}strategy.log | head -1\` #if(\$temp < 99 ) then # now create an executable com file cat strategy.com.start >! strategy.com cat strategy.com.end |\\ nawk '/already collected/,/overall strategy/' >> strategy.com echo "eof-ipmosflm" >> strategy.com chmod a+x strategy.com # run the strategy ./strategy.com |& head -1000 >&! \${logfile}temp if(! \$status) then # completed okay cat \${logfile}temp |\\ nawk '/Run number 2/{getline; wedge = substr(\$0, 11, 15); getline; \\ print "Adding another wedge from " wedge " will give you " \$4 " completeness."}' # save for posterity cat \${logfile}temp >> \${logfile}strategy.log endif ########################################################################## ########################################################################## # best, overall strategy # now create an executable com file cat strategy.com.start >! strategy.com cat strategy.com.end |\\ nawk '/overall strategy/,/\\n/' >> strategy.com echo "eof-ipmosflm" >> strategy.com chmod a+x strategy.com # run the strategy ./strategy.com >! \${logfile}temp grep " cusp" \${logfile}temp >& /dev/null if(! \$status) then set temp = "" if("\$SG" == "P1") set temp = " in P1, using only phi axis" echo "WARNING! impossible to collect 100% complete data\${temp}! " set temp = \`nawk '/[abc]-axis/ && /cusp/{for(i=1;i<=NF;++i)if(\$i ~ /axis/) print \$i}' \${logfile}temp | tail -1\` if("\$temp" != "") echo "\$temp is too close to phi-axis" set temp = \`nawk '/axis/ && /cusp/ && \$(NF-1)+0>1{printf "%d\\n", \$(NF-1)+1}' \${logfile}temp | tail -1\` if("\$temp" != "") echo "try tilting the crystal at least \$temp degrees, and index again" endif cat \${logfile}temp |\\ nawk '/Optimum rotation gives / && /unique/{complete = \$4; getline; getline; \\ print "A wedge" tolower(\$0), "would be", complete, "complete."}' |\\ head -1 | tee \${tempfile} set best_strategy = \`nawk '{print \$4-5, \$6+5}' \${tempfile}\` if(\$#best_strategy < 2) set best_strategy = ( 0 0 ) rm -f \${tempfile} cat \${logfile}temp |\\ nawk '/Optimum rotation gives / && /anomalous/{complete = \$4; getline; getline; \\ print "A wedge" tolower(\$0), "would contain", complete, "of anomalous pairs."}' |\\ head -1 cat \${logfile}temp |\\ nawk '/TESTGEN OPTION/,/IMPORTANT/' |\\ nawk '/minimum percentage/ && /oscillation angle above/ && \$9+0>1{print \$9, \$3}' |\\ sort -n | tail -1 |\\ nawk -v osc="\${osc}\$DEG" '{printf "with %s oscillations you will have %s overlaps when phi = %s\\n", osc,\$1,\$2+0}' cat \${logfile}temp | \\ nawk '/TESTGEN OPTION/,/IMPORTANT/' |\\ nawk ' ! /[^0-9 .-]/ && NF>3{print \$1, \$4}' |\\ nawk 'BEGIN{minosc=99999} \$2maxosc{maxosc=\$2;maxphi=\$1} \\ END{maxphi2=maxphi+180; if(maxphi2>360) maxphi2=maxphi2%360\\ minphi2=minphi+180; if(minphi2>360) minphi2=minphi2%360\\ print "oscillation can be as much as", maxosc, "at phi =", maxphi, maxphi2;\\ print " but no more than", minosc, "at phi =", minphi, minphi2;}' cat \${logfile}temp >> \${logfile}strategy.log # back up last stragegy script if(-e strategy.com.old) mv strategy.com.old strategy.com.older mv strategy.com strategy.com.old ########################################################################## ########################################################################## # TESTGEN for best, overall strategy # now create an executable com file cat strategy.com.start >! strategy.com cat << EOF-testgen >> strategy.com SEPARATION \$separation testgen start \$best_strategy[1] end \$best_strategy[2] minosc 0.01 overlap 3 \$max_osc go eof-ipmosflm EOF-testgen chmod a+x strategy.com # run the strategy ./strategy.com >! \${logfile}temp # come up with a full data-collection strategy (with oscillation widths) echo "recommend: " echo " start osc frames wedge size" | tee strategy.txt cat \${logfile}temp |\\ nawk '/Suggested data collection strat/,/IMPORTANT/' |\\ nawk '! /[a-z]/ && NF>3{printf "%.0f %.0f %s\\n", \$1, \$2, \$4}' |\\ nawk '{for(phi=\$1;phi<\$2;++phi){print phi, \$3}}' |\\ nawk 'NR==1{last=\$1} \$11{\$2=1} {print}' |\\ nawk -v crit=1.8 'NR==1{lastosc=\$2} {phi=\$1;osc=\$2;ratio=osc/lastosc} ratio<1{ratio=1/ratio} \\ ratio2{print \$1, \$2, \$3, sprintf("%.0f", (\$3-\$2+\$1)/\$1)}' |\\ nawk 'NR==1{first=\$2}\\ {printf "%7.1f %5.1f %6d %5.1f %5.1f\\n", \$2, \$1, \$4, \$4*\$1, \$4*\$1+\$2-first}' |\\ cat > /dev/null cat \${logfile}temp |\\ nawk '/Suggested data collection strat/,/IMPORTANT/' |\\ nawk '! /[a-z]/ && NF>3{print \$4}' |\\ cat >! \${tempfile}minosc set minosc = \`sort -nr \${tempfile}minosc | tail -1\` rm -f \${tempfile}minosc >& /dev/null cat \${logfile}temp |\\ nawk '/Suggested data collection strat/,/IMPORTANT/' |\\ nawk -v minosc=\$minosc '! /[a-z]/ && NF>3{printf "%.0f %.0f %s\\n", \$1, \$2, minosc}' |\\ nawk '{for(phi=\$1;phi<\$2;++phi){print phi, \$3}}' |\\ nawk 'NR==1{last=\$1} \$11{\$2=1} {print}' |\\ nawk -v crit=1.8 'NR==1{lastosc=\$2} {phi=\$1;osc=\$2;ratio=osc/lastosc} ratio<1{ratio=1/ratio} \\ ratio2{print \$1, \$2, \$3, sprintf("%.0f", (\$3-\$2+\$1)/\$1)}' |\\ nawk 'NR==1{first=\$2}\\ {printf "%7.1f %5.2f %6d %5.1f %5.1f\\n", \$2, \$1, \$4, \$4*\$1, \$4*\$1+\$2-first}' |\\ cat | tee -a strategy.txt echo "" # make whole script for user's benifit cat strategy.com.start strategy.com.end >! strategy.com echo "eof-ipmosflm" >> strategy.com chmod a+x strategy.com # add some xloggraph plots to \${logfile}strategy.html echo "
" >! \${logfile}strategy.html

foreach strategy ( \`nawk '/ ===> strategy/{++line; print line}' \${logfile}strategy.log\` )

    set keyword = \`nawk -v strategy=\$strategy '/ ===> strategy/{++line} line==strategy{\$1="";print;exit}' \${logfile}strategy.log\`
    # make an xloggraph header for it
    cat << EOF >> \${logfile}strategy.html
 : \$keyword :
3{print;last=\$1}' |\\
    nawk '{printf "%6s %6s %6s %6s %6s \\n",\$1,\$2,\$3,\$4,\$5}' |\\
    cat >> \${logfile}strategy.html

    echo '\$\$' >> \${logfile}strategy.html
    echo '">For inline graphs use a Java browser' >> \${logfile}strategy.html
end

# show testgen data too
foreach strategy ( \`nawk '/ ===> testgen/{++line; print line}' \${logfile}strategy.log\` )

    set keyword = \`nawk -v strategy=\$strategy '/ ===> testgen/{++line} line==strategy{\$1="";print;exit}' \${logfile}strategy.log\`
    
    cat \${logfile}strategy.log |\\
    nawk -v strategy=\$strategy '/ ===> testgen/{++line} line==strategy{print}' |\\
    nawk '/Current values:/' >> \${logfile}strategy.html
    
    cat << EOF >> \${logfile}strategy.html
\$keyword :
3{printf "%.0f %.0f %s %s %s\\n", \$1, \$2, \$4, \$5, \$6}' |\\
    nawk '{for(phi=\$1;phi<=\$2;++phi){if(ovlap[phi]=="") ovlap[phi]=\$4;\\
	   if(\$NF != "OVLAP") print phi, \$3, ovlap[phi], \$5, ""}}' |\\
    nawk 'NR==1{last=\$1} \$13{print;last=\$1}' |\\
    nawk '{printf "%6s %6s %6s %6s \\n",\$1,\$2,\$3,\$4}' |\\
    cat >> \${logfile}strategy.html 

    echo '\$\$' >> \${logfile}strategy.html
    echo '">For inline graphs use a Java browser' >> \${logfile}strategy.html
end

#unset strat_res
unset phi_end
echo "for details, see \${logfile}strategy.log and \${logfile}strategy.html"


# Clean up a bit ...
rm -f strategy.com.start >& /dev/null
rm -f strategy.com.end >& /dev/null

rm -f strategy.mtz >& /dev/null
rm -f strategy.xlog >& /dev/null
rm -f \${logfile}temp >& /dev/null
rm -f \${tempfile}max_osc >& /dev/null

echo ""

SkipStrategy:
onintr

goto ReturnFromStrategy



























exit
scale_and_merge:
###############################################################################

  ####    ####     ##    #       ######
 #       #    #   #  #   #       #
  ####   #       #    #  #       #####
      #  #       ######  #       #
 #    #  #    #  #    #  #       #
  ####    ####   #    #  ######  ######

###############################################################################
# perform a complimentary scaling step here.  So user can see Rmerge, etc.
#
###############################################################################

# figure out asu
if(1 || ! \$?ASU) then
    # ASU is not set, so we need to calculate a "reasonable" one from Vm
    if(! \$?Vm) set Vm = 2.4
    set ASU_per_CELL = \`nawk -v SG=\$SG '\$4==SG{print \$2;exit}' \$CLIBD/symop.lib | head -1\`

    # calculate cell volume
    echo \$CELL |\\
    nawk 'NF==6{s=3.1415926535897899419/180; A=cos(s*\$4); B=cos(s*\$5); G=cos(s*\$6); \\
     skew = 1 + 2*A*B*G - A*A - B*B - G*G ; if(skew < 0) skew = -skew;\\
     printf "%.3f\\n", \$1*\$2*\$3*sqrt(skew)}' |\\
    cat >! \${tempfile}volume
    set CELLvolume = \`cat \${tempfile}volume\`
    rm -f \${tempfile}volume >> /dev/null
    
    # now set ASU to best number of AA, given the Vm
    set temp = \`echo "\$CELLvolume \$ASU_per_CELL " | nawk '{print \$1/\$2}'\`
    set ASU = \`echo "\$temp \$Vm" | nawk '{printf "%d", \$1 / \$2 / 120}'\` 
#    set ASU = \`echo "\$temp \$Vm" | nawk '{print \$1 / \$2 / 128}'\` 

    if(\$?Chain) then
	# protein size known, how many in ASU? 

	# decide to round up or down
	@ temp = ( \$ASU % \$Chain )
	if(\$temp >= (\$Chain / 2) ) then
	    set temp = 1
	else
	    set temp = 0
	endif
	
	@ Number_of_chains = ( ( \$ASU / \$Chain ) + \$temp  )
	if(\$?debug) echo "ASU will be \$Number_of_chains chains (\$Chain amino acids each)"
	@ ASU = ( \$Number_of_chains * \$Chain )
    endif
endif

# figure out outer resolution limit from mosflm log.
cat \${logfile}mosflm.log |\\
nawk 'h==0 && /Analysis as a function of resolution./{h=1;getline;\\
               print \$3, \$4, \$5, \$6, \$7, \$8, \$9, \$10} \\
      /^  /{print \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9}' |\\
nawk 'NR==1{for(i=1;i<9;++i){res[i]=\$i};++n} \\
      NR!=1{for(i=1;i<9;++i){signal[i]+=\$i;++count[i]}}\\
      END{if(n) for(i=8;i>0;--i){print res[i], signal[i]/count[i]}}' |\\
sort -nr >! \${tempfile}res_limit
set res_limit = \`nawk '\$NF > 0.5 {print \$1+0} \$NF<=0 {exit}' \${tempfile}res_limit | tail -1\`
rm -f \${tempfile}res_limit >& /dev/null


# reset high resolution limit to this 0.5-sigma cutoff
if("\$res_limit" =~ *[0-9].[0-9]* && "\$res_choice" != "user") then
    echo "Merging will be limited to \$res_limit \$ANG (I/sig drops to 0.5 there)."
    set merge_res = \$res_limit
endif
if(! \$?merge_res) set merge_res = \$hires
if("\$merge_res" == "") set merge_res = \$hires

# figure out how to use scale_partials, etc. from mosflm log
grep "Because the fraction of fully recorded reflections is less than" \${logfile}mosflm.log >& /dev/null
if(\$status) then
    # mosflm didn't feel the need to use partials, so neither will we
    set scale_partials = "#"
else
    # mosflm used partials in refinement, so we will use them in scaling
    set scale_partials = ""
endif
# see if we have way too many partials
set temp = \`echo "\$osc \$mosaic" | nawk '{printf "%d", 2*\$2/\$1}'\`
set extra_partials
if(\$temp > 4) then
    set extra_partials = "partials maxwidth \$temp"
endif

##############################################################################
#
# Go unwrap scaling scripts
#
echo "Unwrapping \${mergescript}, autoscala and SGsearch.com"
goto Unwrap_Scale_Scripts
Return_Unwrap_Scale_Scripts:
echo ""
#
##############################################################################
set temp2 = ""
set Rmerge = 100

# bail now if CCP4 is not set-up
if(\$?NO_CCP4) then
    echo "Wedger Elves can go no further without the help of CCP4"

    goto Cleanup
endif

# ask user if we should run merge.com
set temp = "Yes"
if(\$?NOSCALE) set temp = "No"
if(\$?SMOOTH_RUNS) set temp2 = " again"
echo "Scale and merge \${mtzout}\${temp2}? [\$temp]?"
echo -n "\$PROMPT"
if(\$?AUTO) then
    echo "\$temp"
else
    echo -n "\$BELL"
    set in = ( \$< )
    if("\$in" != "") set temp = ( \$in )
endif
if((\$#temp > 1)||("\$temp" !~ [NnYy]*)) then
    # complex answer, send it to the parser
    set input = "\$temp"
    goto Questionaire
endif
if("\$temp" =~ [Nn]*) goto AUTOscala


Run_mergescript:

if("\$SG_choice" == "auto") then
    # as long as we aren't sure about SG, don't pay attention to these
    unset SGsearched
    if(! \$?HURRY) unset SD_CORRECTED
endif

echo "running \$mergescript ... "
echo ""
echo You can watch the output in \`pwd\`/\${logfile}merge.log
if(-e \${logfile}merge.log) mv \${logfile}merge.log \${logfile}merge.log.old
if(! \$?AUTO) onintr AUTOscala
echo "Cycle shift"
./\$mergescript \$SG | tee \${logfile}merge.log |\\
   nawk '/Cycle/{printf "%s %s: ", \$2,\$3} /mum shift/{print \$7}'
#  nawk '/Cycle/{cycle=\$3} /mum shift/{shift[cycle]=\$7;\\
#	slope=0;for(i=cycle;(i>cycle-10 && i>0);--i){wrong+=(shift[i-1]>shift[i])}\\
#	print cycle,shift[cycle],shift[cycle]/shift[cycle-1],slope}'
onintr

# check the output
set lastcycle = \`nawk '/Cycle/ && int(\$3+0) == \$3{print \$3}' \${logfile}merge.log | tail -1\`
set maxcycle = \`nawk '/^cycles/ && int(\$2+0) == \$2{print \$2}' \$mergescript\`
if("\$maxcycle" == "") set maxcycle = 200
if("\$lastcycle" == "") set lastcycle = \$maxcycle
set test = \`grep 'TRUNCATE:  Normal termination' \${logfile}merge.log\`

if(("\$test" != "")&&(-e "\${mergefile}")&&(\$lastcycle < \$maxcycle)) then
    echo ""
    echo "\$mergefile contains your scaled and merged data."
    cat \${logfile}merge.log |\\
    nawk '\$3 == "Dmin(A)" {graph=1; title=\$0} \\
       graph==1 && \$1+0>0{if(title){print title; title=""}; print}\\
       \$1=="Overall:"{print; graph=0}' |\\
    nawk '/Dmin/{idx=index(\$0,"Mn");printf "%7s %5s %5s %5s %8s\\n", \$3, \$4, \$5, \$7, \$13} \\
          \$1+0!=0{printf "%7.2f %5.3f %5.3f %5.3f %8.1f\\n", \$3, \$4, \$5, \$7, substr(\$0,idx,7)} \\
        /Overall/{printf "Overall %5.3f %5.3f %5.3f %8.1f\\n", \$2, \$3, \$5, substr(\$0,idx,7)}' |\\
    tee \${tempfile}reslimit |\\
    nawk 'NR<3{print; next} /Overall/{if(cut!=outer) print cut; print outer; print} \$NF+0>2.8{cut=\$0} {outer=\$0}' 

    # store the I/sig of the current outer resolution bin
    set outer_sig = \`nawk '\$1+0>0{printf "%d\\n", 10*\$NF}' \${tempfile}reslimit | tail -1\`

    # interpolate a good resolution cutoff
    cat \${tempfile}reslimit |\\
    nawk -v goal=1.5 '\$1+0>0 && lastres+0>0 && \$NF+0>1.0 && \$NF+0<10 && (lastsig-\$NF)^2>0 {\\
	newres = \$1+(goal-\$NF)*(lastres-\$1)/(lastsig-\$NF);\\
	newrad = 1/sqrt(\$1)+(goal-\$NF)*(1/sqrt(lastres) - 1/sqrt(\$1))/(lastsig-\$NF); newrad=1/(newrad)^2\\
	print \$0, newres} {lastres=\$1;lastsig=\$NF}' |&\\
    cat >! \${tempfile}cutoff
    
    set best_res = \`nawk '\$NF+0>0.1{printf "%.2f\\n", \$NF}' \${tempfile}cutoff | tail -1\`
    rm -f \${tempfile}reslimit \${tempfile}cutoff
    

    # some kind of sanity check on best_res ?
    set test = \`echo \$best_res \$merge_res | nawk 'NF==2{print (\$1 > \$2)}'\`
    if("\$test" == "1" && \$outer_sig > 30) then
	# we are trying to decrease resolution with good outer signal.  WTF?
	# chose a best_res that is slightly beyond the current merge_res
	set best_res = \`echo \$merge_res | nawk '\$1+0>0.1{printf "%.2f\\n", (1.2*(\$1^-3))^-(1/3)}'\`
    endif

    # truncate any wild swings (more than doubling reciprocal space volume)
    set ridiculous_res = \`echo "\$merge_res" | nawk '\$1+0>0.1{printf "%.2f\\n", (2.0*(\$1^-3))^-(1/3)}'\`
    set test = \`echo \$best_res \$ridiculous_res | nawk 'NF==2{print (\$1 < \$2)}'\`
    if("\$test" == "1") then
	# this would be dangerous.  Instead, integrate at 2x volume and merge again...
	set best_res = \$ridiculous_res
    endif

    # pick an integration resolution that is slightly beyond best_res
    set dream_res = \`echo "\$best_res" | nawk '\$1+0>0.1{printf "%.2f\\n", (1.5*(\$1^-3))^-(1/3)}'\`

    # clip resolution extention at detector limit (if we know it) 
    set best_res = \`echo \$best_res \$detector_res_limit | nawk 'NF==2 && \$1<\$2{\$1=\$2} {print \$1}'\`
    set dream_res = \`echo \$dream_res \$detector_res_limit | nawk 'NF==2 && \$1<\$2{\$1=\$2} {print \$1}'\`

    # make sure we dont oscillate with a truncate failure
    if("\$res_choice" == "truncate") then
	# merge_res was chosen because truncate wouldn't run at anything higher
	set test = \`echo \$best_res \$merge_res | nawk '{print (\$1 < \$2)}'\`
	if(\$test) set best_res = \$merge_res
    endif

    
    # print out completeness (since this IS the real completeness)
    echo "stats nbin 100" |\\
     mtzdump HKLIN \$mergefile |&\\
    nawk '/PARTIAL FILE STATISTICS/,/No. of reflections/' |\\
    nawk '\$1==4 && NF>3{res=\$(NF-2)+0; if(substr(\$0,28)+0!=0)miss+=substr(\$0,20)}\\
      /partial statistics for resolution bin/{sum+=\$NF; \\
	print res,100*(sum-miss)/sum}' |\\
    sort -n |\\
    nawk -v ANG="\$ANG" 'NR==1 || \$2>90{\\
	printf "%.1f%% complete to %.2f %s\\n",\$2,\$1,ANG}\\
	\$2>90{exit}'


    if ("\$best_res" != "") then
        # is this "better" than before?

	echo ""
	set answer = "Yes"
	# don't bother if resolution change is small
	set test = \`echo \$best_res \$merge_res | nawk 'NF==2{print (sqrt((\$1^-3 - \$2^-3)^2)>0.1*(\$1^-3) )}'\`
	if("\$test" == "0") set answer = "No"
	# see if we are extending or retracting resolution limit
	set extending = \`echo \$hires \$best_res | nawk '{print (\$1>\$2)}'\`
        if ("\$res_choice" == "truncate" && \$extending) set answer = "No"
        if ("\$res_choice" == "user") set answer = "No"
        echo "\$best_res \$ANG looks like a good resolution cutoff."
        echo "shall we use it? [\$answer]"
	echo -n "\$PROMPT"
	if(\$?AUTO) then
	    echo \$answer
	else
	    echo -n "\$BELL"
	    set in = ( \$< )
	    if("\$in" != "") set answer = ( \$in )
        endif
	if("\$answer" =~ [Yy]*) then
	    # go ahead and update resolution cutoffs
            set hires = "\$dream_res"
	    set merge_res = "\$best_res"
	    set SAVE_hires = "\$best_res"
	    set res_choice = merge
	    if(! \$?AUTO) set res_choice = user
	    set test = \`echo \$mtz_res \$best_res | nawk '{print (\$1>\$2)}'\`
	    if(\$extending && \$test) then
		# need to run mosflm again
		goto PrintIntentions
	    endif
	    goto Unwrap_Scale_Scripts
	endif
    endif

    
    # average sdfac from fulls and partials (compromise)
    cat \${logfile}merge.log |\\
    nawk '/Final assessment of SDcorrection multipliers/{getline;getline;getline;getline;\\
          while(NF>2){if(\$2 != 1.0000){++n; print; sum+=(\$2+\$5)/2}; getline}; if(n) printf "%.2f\\n", sum/n}' |\\
    cat >! \${tempfile}
    set temp = \`tail -1 \${tempfile} | nawk '\$1+0 > 0.5{print \$1}'\`
    rm -f \${tempfile}
    
    # now update our SDCORR card
    if("\$temp" != "") then
	set SDCORR = \`echo "\$temp \$SDCORR" | nawk '{print \$1, \$3, \$4}'\`
	unset DEFAULT_SDCORR
    endif
    
    set Rmerge = \`nawk '/Overall:/{printf "%d", \$2*100}' \${logfile}merge.log\`

    if(! \$?SMOOTH_RUNS) then
	# only do this once
    
	# look for breaks in continuity of scales
	cat \${logfile}merge.log |\\
	nawk '/ Scales v rotation range/,/Total/' |\\
	nawk 'NF>2 && ! /[a-z]/' |\\
	nawk '{if(S+0!=0 && \$6+0!=0){jump=\$6/S; if(jump<1)jump=1/jump;\\
	       print \$4, jump}else{print \$4, 1}; S=\$6}' |\\
	nawk '\$2 > 1.2{print \$1-1; print \$1} NR==1{print \$1} {b=\$1} END{print b}' |\\
	nawk '{++n; printf "RUN " n " " \$1;getline; print " to " \$1}' |\\
	cat >! \${tempfile}.runs
    
	# see if it's safe to run smooth scaling
	set temp = \`cat \${tempfile}.runs | wc -l\`
	if(\$temp >= \$number_of_frames) set temp = 999
	if("\$temp" < 10) then
	    echo ""
	    if("\$temp" == 1) then
		echo "Recomend smooth scales next time."
	    else
		echo "Recomend smoothing scales in \$temp segments."
	    endif
	    echo "scales rotation spacing 5 bfactor on"  >> \${tempfile}.runs
	else
	    # too many runs
	    rm -f \${tempfile}.runs
	    echo "scaling was noisy. "
	    echo "you should xloggraph "\`pwd\`"/\${logfile}merge.log"

	    # is this a good idea?
	    echo "maybe try smoothing them out? "
	    set SMOOTH_RUNS = "scales rotation spacing 5 bfactor on"
	endif
    
	# regenerate merge.com with new scaling parameters
	if(-e \${tempfile}.runs) then
	    set SMOOTH_RUNS = \`nawk '{printf "%s%%", \$0}' \${tempfile}.runs\`
	    rm -f \${tempfile}.runs >& /dev/null
	endif
	if(\$?SMOOTH_RUNS) goto Unwrap_Scale_Scripts
    endif
else
    echo "FAILED! "
    echo ""
    # do something about this?

    # check for sorting bug
    grep "You must either scale down the data or change VRSET" \${logfile}merge.log
    if(! \$status) then
	if("\$VRSET" == "#") then
	    # we know how to handle this! 
	    set VRSET = ""
	    echo "try adding VRSET -9e+38 to \$mergescript"
	    goto Unwrap_Scale_Scripts
	else
	    # VRSET does not work...
	    # slight decrease in resolution cutoff
	    set res_choice = vrset
	    set hires = \`echo "\$merge_res" | nawk '{printf "%.2f", \$1 * 1.1}'\`
	    echo "try reducing the resolution to \$hires \$ANG"

	    # need to run mosflm again
	    goto PrintIntentions
	endif
    endif

    egrep "CCP4_QOPEN: can.t open H" \${logfile}merge.log
    if(! \$status && "\$VRSET" == "") then
	# VRSET does not work
	set VRSET = "##"
	
	# slight decrease in resolution cutoff
	set hires = \`echo "\$merge_res" | nawk '{printf "%.2f", \$1 * 1.05}'\`
	echo "try reducing the resolution to \$hires \$ANG"
    endif

    # check for bug in data harvesting
    grep "WIDTH OF BIN TOO LARGE" \${logfile}merge.log >& /dev/null
    if(! \$status && \$lastcycle < \$maxcycle && \$rename_dataset == "#") then
	echo "possible bug in data harvesting... turning it off."
	set rename_dataset = ""
	goto Unwrap_Scale_Scripts
    endif


    # check for overly ambitious resolution cutoff
    grep "Data beyond useful resolution limit" \${logfile}merge.log >& /dev/null 
    if(! \$status && \$lastcycle < \$maxcycle) then
	# we know how to handle this! 
	cat \${logfile}merge.log |\\
	nawk '/Wilson Plot/,/TRUNCATE/' |\\
	nawk 'NF==10 && ! /[a-z]/{print \$6}' |\\
	tail -1 >! \${tempfile}res
	set newRES = \`cat \${tempfile}res\`
	rm -f \${tempfile}res
	
	# now check against old high-res limit
	set test = \`echo "\$merge_res \$newRES" | nawk '{printf "%d", 100*(\$2-\$1)}'\`
	if("\$test" < 5) then
	    # slight decrease in resolution cutoff
	    set merge_res = \`echo "\$merge_res" | nawk '{printf "%.2f", \$1 * 1.05}'\`
	else
	    # use the reso from last good bin in truncate
	    set hires = "\$newRES"
	    set merge_res = "\$newRES"
	endif
	set res_choice = truncate
	echo "reducing resolution to \$merge_res \$ANG"
	goto Unwrap_Scale_Scripts
    endif

    if("\$merge_tie" == "#") then
        set merge_tie = ""
        echo "lets try forcing consistent scales..."

        # regenerate merge.com with new scaling parameters
        goto Unwrap_Scale_Scripts
    endif

    if("\$merge_damp" == "#") then
	set merge_damp = ""
	echo "lets try a damping function in scaling..."

	# regenerate merge.com with new scaling parameters
        goto Unwrap_Scale_Scripts
    endif

    if(! \$?SMOOTH_RUNS) then
        set SMOOTH_RUNS = "scales rotation spacing 5 bfactor on"
        # hope that this helps?
        echo "lets use smooth scales this time..."
	set merge_damp = "#"
	set merge_tie = "#"

        # regenerate merge.com with new scaling parameters
        goto Unwrap_Scale_Scripts
    endif

    if("\$SMOOTH_RUNS" =~ RUN*) then
        set SMOOTH_RUNS = "scales rotation spacing 5 bfactor on"
        # hope that this helps?
        echo "maybe all those subruns were a bad idea..."
	set merge_damp = "#"
	set merge_tie = "#"

        # regenerate merge.com with new scaling parameters
        goto Unwrap_Scale_Scripts
    endif

    if("\$SG_choice" == "auto") then
	# we kind of need this to work...

	# regenerate merge.com with new scaling parameters
#	goto Unwrap_Scale_Scripts
    endif

    echo "you should examine \$mergescript and the end of \${logfile}merge.log"

    set Rmerge = 100

    goto Cleanup
endif
echo ""
#
#
# go to Space Group Search if SDs have already been corrected, or if
# the Rmerge totally sucks (wrong space group)
if((\$?SD_CORRECTED)||(\$Rmerge > 35)) goto SG_search











AUTOscala:
########################################################################################

   ##    #    #   #####   ####    ####    ####     ##    #         ##
  #  #   #    #     #    #    #  #       #    #   #  #   #        #  #
 #    #  #    #     #    #    #   ####   #       #    #  #       #    #
 ######  #    #     #    #    #       #  #       ######  #       ######
 #    #  #    #     #    #    #  #    #  #    #  #    #  #       #    #
 #    #   ####      #     ####    ####    ####   #    #  ######  #    #

########################################################################################
#
#	Optimize the SDCORR parameters
#
########################################################################################
onintr
cat << EOF

Sigma corrections:

    Mosflm has calculated a standard deviation (sigma) for every observed 
    intensity in \${mtzout}, based on the counting statistics of the spot 
    measurement.  However, crystal absorption and other systematic errors 
    have not been accounted for.
    
    To make your final sigmas realistic (very important for modern phasing
    and refinement programs), you need to estimate the contribution of 
    systematic errors, and correct Mosflm's sigmas accordingly in scala:
    
    in \${mergescript}: SDCORR Sdfac SdB Sdadd
    
    where: newsigma = Sdfac * sqrt(oldsigma**2 + SdB*Ihl' + (Sdadd*Ihl)**2)
                      for each spot          (see your scala documentation)
    
    Wedger Elves can try a series of SDCORR parameters and then report 
    to you which set results in a "new sigma" which matches the average 
    scatter (disagreement) of symmetry-equivalent spots.
    
EOF
set temp = "Yes"
if(\$?NOSCALE) set temp = "No"
if(\$?SD_CORRECTED) set temp = "No"
if(\$?HURRY) set temp = "No"
echo "Optimize SDCORR in \${mergescript}? [\$temp]?"
echo -n "\$PROMPT"
if(\$?AUTO) then
    echo "\$temp"
else
    echo -n "\$BELL"
    set in = ( \$< )
    if("\$in" != "") set temp = ( \$in )
endif
if((\$#temp > 1)||("\$temp" !~ [NnYy]*)) then
    set input = "\$temp"
    goto Questionaire
endif
if("\$temp" =~ [Nn]*) goto SG_search


# get SDFAC from last scala run (if it's there)
if(-e "\${logfile}merge.log") then
    # average sdfac from fulls and partials (compromise)
    cat \${logfile}merge.log |\\
    nawk '/Final assessment of SDcorrection multipliers/{getline;getline;getline;getline;\\
          while(NF>2){if(\$2 != 1.0000){++n; print; sum+=(\$2+\$5)/2}; getline}; if(n) printf "%.2f\\n", sum/n}' |\\
    cat >! \${tempfile}
    set temp = \`tail -1 \${tempfile} | nawk '\$1+0>0.5 && \$1+0<3{print \$1}'\`
    rm -f \${tempfile}
    
    # now edit the mergeing script
    if("\$temp" != "") then
	cat \${mergescript} |\\
	nawk -v sdfac=\$temp 'toupper(\$0) ~ /^SDCORR/{print "SDCORR", sdfac, \$3, \$4} toupper(\$0) !~ /^SDCORR/' |\\
	cat >! \${tempfile}mergescript
	mv \${tempfile}mergescript \${mergescript}
	chmod a+x \${mergescript}
    endif
endif


#echo "while you wait, you might want to read the SCALA manual."
echo ""
echo "Optimizing \${mergescript}'s SDCORR parameters with autoscala: "
if(! \$?AUTO) onintr Skip_AUTOscala
./autoscala summary=no \${mergescript} | tee \${logfile}autoscala.log
Skip_AUTOscala:
onintr
rm -f \${mergescript}_test >& /dev/null

# retrieve SDCORR card from optimized script
set temp = ""
if(-e \${mergescript}_best) then
    set temp = \`nawk 'toupper(\$0) ~ /^SDCORR/ && NF==4 && \$2+0>0.5 {print \$2, \$3, \$4}' \${mergescript}_best | tail -1\`
endif
if("\$temp" != "") then
    mv \${mergescript}_best \${mergescript}
    chmod a+x \${mergescript}

    set SDCORR = "\$temp"
    unset DEFAULT_SDCORR
else
    # huh?
    echo "Woops! that didn't work! "
    echo "sticking with old SDCORR"
    rm -f \${mergescript}_best >& /dev/null
endif
set SD_CORRECTED
#
#
# now run it again, to update the log
echo "running the new \$mergescript with SDCORR \$SDCORR ... "
echo ""
echo You can watch the output in \`pwd\`/\${logfile}merge.log
if(-e \${logfile}merge.log) mv \${logfile}merge.log \${logfile}merge.log.old
if(! \$?AUTO) onintr SG_search
./\$mergescript | tee \${logfile}merge.log | nawk '/Cycle/{printf "%s %s: ", \$2,\$3} /mum shift/{print \$7}'
onintr

# check the output
set temp = \`grep 'TRUNCATE:  Normal termination' \${logfile}merge.log\`

if(("\$temp" != "")&&(-e "\${mergefile}")) then

    # get average sdfac from fulls and partials (again)
    cat \${logfile}merge.log |\\
    nawk '/Final assessment of SDcorrection multipliers/{getline;getline;getline;getline;\\
          while(NF>2){if(\$2 != 1.0000){++n; print; sum+=(\$2+\$5)/2}; getline}; if(n) printf "%.2f\\n", sum/n}' |\\
    cat >! \${tempfile}
    set temp = \`tail -1 \${tempfile} | nawk '\$1+0 > 0.5{print \$1}'\`
    rm -f \${tempfile}
    
    # now update the SDCORR card (again)
    if("\$temp" != "") then
	set SDCORR = \`echo "\$temp \$SDCORR" | nawk '{print \$1, \$3, \$4}'\`
    endif
    
    echo -n "final SDCORRections are: SDCORR \$SDCORR"
    echo ""
    set temp = \`echo \$SDCORR | nawk '\$1>2 || \$3>0.1 {print}'\`
    rm -f \${tempfile}
    
    # warn user of unreasonable SDcorrection
    if("\$temp" != "") then
	echo "WARNING: SDCORR \$SDCORR"
	echo "seems high."
	echo "X-ray data don't usually have this much systematic error. "
	echo "So, this could be due to a correctable mistake."
	echo "I.E. wrong space group, poor partials, incorrect quantum gain. etc."
	echo "look at the manuals for SCALA and MOSFLM to find out more."
	echo ""
    endif

    echo "\$mergefile contains your scaled and merged data."
    cat \${logfile}merge.log |\\
    nawk '\$3 == "Dmin(A)" {graph=1; title=\$0} \\
       graph==1 && \$1+0>0{if(title){print title; title=""}; print}\\
       \$1=="Overall:"{print; graph=0}' |\\
    nawk '/Dmin/{idx=index(\$0,"Mn");printf "%7s %5s %5s %5s %8s\\n", \$3, \$4, \$5, \$7, \$13} \\
          \$1+0!=0{printf "%7.2f %5.3f %5.3f %5.3f %8.1f\\n", \$3, \$4, \$5, \$7, substr(\$0,idx,7)} \\
        /Overall/{printf "Overall %5.3f %5.3f %5.3f %8.1f\\n", \$2, \$3, \$5, substr(\$0,idx,7)}' |\\
    nawk 'NR<3{print; next} /Overall/{if(cut!=outer) print cut; print outer; print} \$NF+0>2.8{cut=\$0} {outer=\$0}'
          
    echo ""
    echo " /sd now reflects the true signal/noise of your data."
    echo ""

else
    echo ""
    echo "FAILED! "
    echo ""
    echo "you should examine \$mergescript and the end of \${logfile}merge.log"

    # This should never happen
    
    if(! \$?AUTO) then
	set input = ""
	goto Questionaire
    endif
    goto Cleanup
endif









SG_search:
onintr
########################################################################################

  ####    ####            ####   ######    ##    #####    ####   #    #
 #       #    #          #       #        #  #   #    #  #    #  #    #
  ####   #                ####   #####   #    #  #    #  #       ######
      #  #  ###               #  #       ######  #####   #       #    #
 #    #  #    #          #    #  #       #    #  #   #   #    #  #    #
  ####    ####            ####   ######  #    #  #    #   ####   #    #

########################################################################################
#
#	If Space group was choses automatically, we should try other possibilities
#
########################################################################################

set temp = "No"
if("\$Rmerge" != 100) then
    # merge.com ran okay
    set temp = "Yes"
    # don't bother if we are in a hurry
    if(\$?AUTO && \$?HURRY) set temp = "No"
    # don't do this twice
    if(\$?SGsearched) set temp = "No"
    # ALWAYS do this if we are fiddling with the space group
    if("\$SG_choice" == "auto") set temp = "Yes"
    # unless, of course, there is only one possibility?
    if("\$SG" == "P1" || "\$SG" == "C2" || "\$SG" == "F23" || "\$SG" == "F222") then
    endif
endif
# never scale if we were asked not to
if(\$?NOSCALE) set temp = "No"
echo "Shall we try mergeing other possible space groups? [\$temp]?"
echo -n "\$PROMPT"
if(\$?AUTO) then
    echo "\$temp"
else
    echo -n "\$BELL"
    set in = ( \$< )
    if("\$in" != "") set temp = ( \$in )
endif
if((\$#temp > 1)||("\$temp" !~ [NnYy]*)) then
    set input = "\$temp"
    goto Questionaire
endif
if("\$temp" =~ [Nn]*) goto Patterson

# break out if we get bored
onintr Skip_SGsearch
./SGsearch.com \$mtzout ignore | tee \${logfile}SGsearch.log
#./SGsearch.com \$mtzout | tee \${logfile}SGsearch.log
onintr
# reminder that we have finished SG search at least once
set SGsearched

# pick up new space group from SGsearch    
set newSGs = \`nawk '/Possible/{for(i=5;i<=NF;++i){print \$i}}' \${logfile}SGsearch.log\`

# retrieve all mergeing groups (lattice + point group)
cat \${CLIBD}/symop.lib |\\
nawk '\$5~/^PG/ && \$1<500{print "LPG",\$4,substr(\$4,1,1)"_"substr(\$5,3)}' |\\
cat >! \${tempfile}SG_LPG

# get the mergeing groups for the SGs chosen by SGsearch
echo "GOOD \$newSGs" |\\
cat \${tempfile}SG_LPG - |\\
nawk '/^LPG/{lpg[\$2]=\$3;next}\\
   /^GOOD/{for(i=2;i<=NF;++i) print "GOOD",\$i,lpg[\$i]}' |\\
cat >! \${tempfile}goodSGs

# get list of space group that were considered by SGsearch
cat \${logfile}SGsearch.log |\\
nawk '/^[PCIFR][1-6]/{SG=\$1;print SG; }' |\\
sort -u |\\
cat \${tempfile}SG_LPG - |\\
nawk '/^LPG/{lpg[\$2]=\$3;next}\\
  NF==1{print \$1,lpg[\$1]}' |\\
cat >! \${tempfile}tried

# make list of all LPGs that were tried and did not pass
cat \${tempfile}goodSGs \${tempfile}tried |\\
nawk '/^GOOD/{++n;good[n]=\$3;next}\\
      NF==2{for(i in good) if(good[i]==\$2) next; print "BAD",\$1,\$2}' |\\
cat >! \${tempfile}badLPGs

# these badSGs are definitely out.  Add them to the wrongSGs list
echo "BAD \$wrongSGs" |\\
cat \${tempfile}SG_LPG - |\\
nawk '/^LPG/{lpg[\$2]=\$3;next}\\
   /^BAD/{for(i=2;i<=NF;++i) print "BAD",\$i,lpg[\$i]}' |\\
cat >> \${tempfile}badLPGs
set wrongSGs = \`sort -u \${tempfile}badLPGs | nawk '{print \$2}'\`
set wrongLPGs = \`sort -u \${tempfile}badLPGs | nawk '{print \$3}'\`

# clear out any taboo space group choices from the SGsearch list
cat \${tempfile}badLPGs \${tempfile}goodSGs |\\
nawk '/BAD/{++bad[\$3]} /GOOD/ && ! bad[\$3] {print}' |\\
cat >! \${tempfile}goodLPGs

# find all SGs that are both chosen by SGsearch and not in the bad list
set newSGs = \`nawk '{print \$2}' \${tempfile}goodLPGs\`

# see if the current space group is on the "good" list
set oldLPG = \`nawk -v SG=\$SG '\$2==SG{print \$3}' \${tempfile}SG_LPG\`
set oldLPGokay = \`nawk -v LPG=\$oldLPG '\$3==LPG{print 1;exit}' \${tempfile}goodLPGs\`

#cp \${tempfile}goodSGs  deleteme_goodSGs.txt >& /dev/null
#cp  \${tempfile}goodLPGs  deleteme_goodLPGs.txt >& /dev/null
#cp  \${tempfile}badLPGs deleteme_badLPGs.txt  >& /dev/null
#echo "\$wrongSGs" >! deleteme_wrongSGs.txt
#echo "\$wrongLPGs" >! deleteme_wrongLPGs.txt
#rm -f \${tempfile}goodSGs \${tempfile}goodLPGs \${tempfile}badLPGs \${tempfile}tried >& /dev/null

# pick "highest" symmetry SG as a representative
set newSG = "\$newSGs[\$#newSGs]"

# is this higher symmetry than we started with?
if("\$newSG" == "P1" && "\$SG" != "P1") then
    # P1 is the only one that merged well, but we didn't ask for it!
    # Make sure P1 only "counts" when it came up in autoindexing
    set newSG = ""
endif

# get the lattice and point group symmetry of the "best" SG choice
set newLPG = \`nawk -v SG=\$newSG '\$2==SG{print \$3}' \${tempfile}SG_LPG\`
rm -f \${tempfile}SG_LPG >& /dev/null


# check out the space groups that "worked"
if("\$newSG" != "") then
        
    # current LPG was bad, or a higher-symmetry option is available
    if(("\$oldLPGokay" != "1") || ("\$newSG" != "\$SG")) then
	# user might want to change SG choice
	set temp = "No"
	if("\$newLPG" != "\$oldLPG") set temp = "Yes"
#	if((! \$?AUTO)&&("\$newSG" != "\$SG")) set temp = "Yes"
	if("\$SG_choice" == "user") set temp = "No"
	echo "Do you want to remeasure in \${newSG}? [\$temp]"
	echo -n "\$PROMPT"
	if(\$?AUTO) then
	    echo \$temp
	else
	    echo -n "\$BELL"
	    set in = ( \$< )
	    if("\$in" != "") set temp = ( \$in )
	endif
	if((\$#temp > 1)||("\$temp" !~ [NnYy]*)) then
	    # unexpected answer
	    set input = "\$temp"
	    goto Questionaire
	endif
	if("\$temp" =~ [Yy]*) then
	    # user okayed new space group choice
	    
	    # don't consider old space group again (unless it is in the same mergeing group)
	    if ( \$newLPG != \$oldLPG ) then
	        set wrongSGs = ( \$wrongSGs \$SG )
		set wrongLPGs = ( \$wrongLPGs \$LPG )
	    endif
	    set SG = "\$newSG"
	    set strategize = yes
	    unset SMOOTH_RUNS

	    # no longer the last run
	    unset LAST_RUN
	    goto ProcessInput
	endif
	# user said they don't want \$newSG as a space group
	set wrongSGs = ( \$wrongSGs \$newSG )
#	if("\$temp" =~ [Nn]*) goto Cleanup
    endif	
else
    # No space groups survived the SGsearch (or they were already bad)
    set LPG = \`nawk -v SG=\$SG 'NF>4{lpg=substr(\$4,1,1)"_"substr(\$5,3)} \$4==SG{print lpg;exit}' \$CLIBD/symop.lib\`
    set new_wrong = \`nawk -v LPG=\$LPG '{lpg=substr(\$4,1,1)"_"substr(\$5,3)} lpg~"^"LPG{print \$4}' \$CLIBD/symop.lib\`
    set sys = \`nawk -v SG=\$SG '\$4==SG{print tolower(\$6);exit}' \$CLIBD/symop.lib\`
    set lattword = \`nawk -v SG=\$SG '\$4==SG{print substr(\$4,1,1)"-centered";exit}' \$CLIBD/symop.lib\`
    if("\$lattword" == "P-centered") set lattword = "primitive"
    if(("\$sys" == "trigonal")||("\$sys" == "hexagonal")) set sys = "trigonal or hexagonal"
    if(! \$?WRONG_SYSTEM) set WRONG_SYSTEM
    set WRONG_SYSTEM = ( \$lattword \$sys \$WRONG_SYSTEM )
    
    # all these SGs should have already been added to "wrongSGs" above
    
    echo "No \$WRONG_SYSTEM space groups merged acceptably. "
    echo "Chances are, this is not you crystal system. "
    echo ""
    echo "You should autoindex again, but, this time, pick a space group"
    echo "that is not \${WRONG_SYSTEM}."
    
    set temp = "Yes"
    if(\$?AUTO) set temp = "No"
    if("\$SG_choice" == "auto") set temp = "Yes"
    echo "Do you want to autoindex again? [\$temp]?"
    echo -n "\$PROMPT"
    if(\$?AUTO) then
	echo "\$temp"
    else
	echo -n "\$BELL"
	set in = ( \$< )
	if("\$in" != "") set temp = ( \$in )
    endif
    if((\$#temp > 1)||("\$temp" !~ [NnYy]*)) then
	set input = "\$temp"
	goto Questionaire
    endif
    if("\$temp" =~ [Yy]*) then
	set CELL = "unknown"
	set SG = "unknown"
	set wrongSGs = ( \$wrongSGs \$SG )
	set wrongLPGs = ( \$wrongLPGs \$LPG )
	
	goto autoindex
    endif
    
endif

goto Update_merge
Skip_SGsearch:
unset AUTO

Update_merge:
onintr

set temp = "Yes"
if(("\$Rmerge" != 100)&&("\$SG_choice" == "auto")) set temp = "Yes"
if(\$?AUTO) set temp = "Yes"
if(\$?NOSCALE) set temp = "No"
echo "Shall we update \$mergefile in \$SG? [\$temp]?"
echo -n "\$PROMPT"
if(\$?AUTO) then
    echo "\$temp"
else
    echo -n "\$BELL"
    set in = ( \$< )
    if("\$in" != "") set temp = ( \$in )
endif
if((\$#temp > 1)||("\$temp" !~ [NnYy]*)) then
    set input = "\$temp"
    goto Questionaire
endif
if("\$temp" =~ [Nn]*) goto Patterson

# reaching here means the SG found by SGsearch.com is the same
# as the one we started with, so we are now no longer concerned 
# about our automatically-chosen SG
set SG_choice = search

# jump back to script-runner
goto Run_mergescript


if(! \$?SD_CORRECTED) goto AUTOscala



Patterson:
########################################################################################
#
#	make the anomalous Patterson (because we can)
#
########################################################################################
if(! -e "\$mergefile") goto Cleanup

# reduce resolution a skosh...
set pattRES = \`echo "\$hires" |  nawk '\$1>0{printf "%.1f", 1/(0.5*((1/\$1)^3))^(1/3)}'\`
if("\$pattRES" == "") set pattRES = 4

# quick script
cat << EOF-script >! Patt.com
#! /bin/csh -f
#
#	basic Patterson script
#
set file1 = "\$mergefile"
set file2 = ""
set RESO = \$pattRES
set DIFF = ""
set SIG  = 0

if(-e "\\\$1") set file1 = "\\\$1"
if(-e "\\\$2") set file2 = "\\\$2"

set outfile  = Patt.map
set tempfile = "patt_temp"

if(-e "\\\$file2") goto iso

# apply an evelope-matching noise supression filter? 
set rolloff = \\\`echo \\\$RESO | awk '{print 8.8*\\\$1*\\\$1}'\\\`

######################
if("\\\$DIFF" == "") then
    # use scalit to get a good maximum-difference cutoff
    scaleit hklin \\\$file1 << EOF >&! \\\${tempfile}scale.log
    analyze
    labin FP=DANO SIGFP=SIGDANO FPH1=F SIGFPH1=SIGF
    scale FPH1 0.0000001
    END
EOF
    set DIFF = \\\`awk '/acceptable differences/{print \\\$NF}' \\\${tempfile}scale.log\\\`
    rm -f \\\${tempfile}scale.log >& /dev/null
endif

######################
# anomalous Patterson
fft hklin \\\$file1 mapout \\\${tempfile}.map << EOF-fft 
PATTERSON
RESOLUTION \\\$RESO
LABIN F1=DANO SIG1=SIGDANO F2=F SIG2=SIGF
SCALE F1 1 \\\$rolloff
SCALE F2 0.000001 0
EXCLUDE DIFF \\\$DIFF
EXCLUDE SIG1 \\\$SIG
EOF-fft
goto norm

iso:
######################
# isomorphous (dispersive) difference

# put both data sets into same file
cad hklin1 \\\$file1 hklin2 \\\$file2 \\\\
    hklout \\\${tempfile}.mtz << EOF-cad
LABIN file 1 E1=F  E2=SIGF
LABOU file 1 E1=F1 E2=SIGF1
LABIN file 2 E1=F  E2=SIGF
LABOU file 2 E1=F2 E2=SIGF2
EOF-cad

if(! \\\$?SCALED) then
    # need to scale input files together
    scaleit HKLIN \\\${tempfile}.mtz \\\\
           HKLOUT \\\${tempfile}scaled.mtz << EOF-scaleit | tee \\\${tempfile}log
LABIN FP=F1  SIGFP=SIGF1 FPH1=F2 SIGFPH1=SIGF2 
#RESO \\\$RESO 1000	# exclude lowest resolution data? 
#WEIGHT			# Sigmas should be reliable.
refine anisotropic	# use an anisotropic B-factor
#refine isotropic	# use an isotropic B-factor
#norefine		# don't change relative scale
END
EOF-scaleit
    # now this is the file we want to use for fft
    mv \\\${tempfile}scaled.mtz \\\${tempfile}.mtz

    if("\\\$DIFF" == "") then
	# auto-set DIFF from scaleit output
	set DIFF = \\\`awk '/acceptable differences/{print \\\$NF}' \\\${tempfile}log\\\`
    endif
    rm -f \\\${tempfile}log >& /dev/null
endif

######################
# do the Patterson
fft hklin \\\${tempfile}.mtz mapout \\\${tempfile}.map << EOF-fft 
PATTERSON
LABIN F1=F1 SIG1=SIGF1 F2=F2 SIG2=SIGF2
RESOLUTION \\\$RESO
SCALE F1 1 \\\$rolloff
SCALE F2 1 \\\$rolloff
EXCLUDE DIFF \\\$DIFF
EXCLUDE SIG1 \\\$SIG
EXCLUDE SIG2 \\\$SIG
EOF-fft
goto norm



norm:
# normalize the output map
echo "SCALE SIGMA" |\\\\
mapmask mapin \\\${tempfile}.map mapout \\\$outfile

# quick peak-pick (for the log)
peakmax mapin \\\$outfile PEAKS \\\${tempfile}.xyz TO \\\${tempfile}.xyz << eof-pick
THRESHOLD RMS 3
OUTPUT PEAKS
END
eof-pick

# clean up
rm -f \\\${tempfile}.map >& /dev/null
rm -f \\\${tempfile}.mtz >& /dev/null
rm -f \\\${tempfile}.xyz >& /dev/null

EOF-script
chmod a+x Patt.com


# now as the user if we should run it
set temp = "No"
if(("\$Rmerge" != 100)&&("\$SG_choice" == "auto")) set temp = "Yes"
if(\$?AUTO) set temp = "Yes"
echo "Shall we make an anomalous Patterson map? [\$temp]?"
echo -n "\$PROMPT"
if(\$?AUTO) then
    echo "\$temp"
else
    echo -n "\$BELL"
    set in = ( \$< )
    if("\$in" != "") set temp = ( \$in )
endif
if((\$#temp > 1)||("\$temp" !~ [NnYy]*)) then
    set input = "\$temp"
    goto Questionaire
endif
if("\$temp" =~ [Nn]*) goto Cleanup

# run it
rm -f Patt.map >& /dev/null
./Patt.com >! \${logfile}patt.log
if(-e "Patt.map") then
    echo "Patt.map is ready."
endif


# check and see if new frames have appeared? 



goto Cleanup












































exit

Unwrap_Scale_Scripts:
################################################################################

 #    #  #    #  #    #  #####     ##    #####
 #    #  ##   #  #    #  #    #   #  #   #    #
 #    #  # #  #  #    #  #    #  #    #  #    #
 #    #  #  # #  # ## #  #####   ######  #####
 #    #  #   ##  ##  ##  #   #   #    #  #
  ####   #    #  #    #  #    #  #    #  #

################################################################################
#	Unwrap scaling scripts: merge.com, autoscala, and SGsearch
################################################################################

if(-e \$mergescript) then
    # retrieve old SDCORR card?
    if(\$?DEFAULT_SDCORR) then
	set temp = \`nawk 'toupper(\$0) ~ /^SDCORR/ && NF>2 && \$2>0.1 {print \$2, \$3, \$4}' \${mergescript} | tail -1\`
#	if(\$#temp > 1) set SDCORR = "\$temp"
    endif
endif

set merge_temp = merge_temp
if(\$?CCP4_SCR) then
    if(-e "\$CCP4_SCR") set merge_temp = '\${CCP4_SCR}/merge_temp\$\$'
endif

# defaults
if(! \$?merge_tie) set merge_tie = "#"
if(! \$?merge_damp) set merge_damp = "#"
if(! \$?rename_dataset) set rename_dataset = "#"



cat << EOF-mergescript >! \$mergescript
#! /bin/csh -fe
#
#  Automatically generated scaling script for:
set title = "\$framedir/\${template} frames \$first to \$last"
#
# make sure netscape reads the graphs properly
echo "
"
Help:
if(("\\\$1" == "")||(\\\$?HELP)) then
    cat << EOF

usage: \\\$0 raw.mtz [\$SG] [\${merge_res}A] [aa]

where: \$SG 	- is the space group you want to "reindex" to.
       \${merge_res}A	- is the outer resolution cutoff
       aa	- is the number of amino acids in your asymmetric unit

EOF
    if(\\\$?HELP) exit
endif


# make sure awk works
alias nawk \$nawk
nawk 'BEGIN{exit}' >& /dev/null
if(\\\$status) alias nawk awk
##############################################################################
set rawfile = \$mtzout
set outfile = \$mergefile
set tempfile = \$merge_temp

##############################################################################
# this value was estimated for a Vm of \$Vm in \$SG
set ASU  = \$ASU
set SG   = ""
set CELL = ""
set RES  = \$merge_res

##############################################################################
goto Setup
# interpret command line
Return_From_Setup:
##############################################################################

echo "scaling, mergeing and truncating \\\$rawfile into \\\$outfile"
echo "to \\\${RES}A in \\\$SG with \\\${ASU}aa per ASU"



##############################################################################
# make sure the output is sorted
#
##############################################################################
sortmtz hklout \\\${tempfile}.sorted.mtz  << end_sort
\${VRSET}VRSET -9e+38
H K L M/ISYM BATCH I SIGI
\\\$rawfile
end_sort
#
##############################################################################
# now run SCALA 
#
##############################################################################
scala hklin \\\${tempfile}.sorted.mtz hklout \\\${tempfile}.scaled.mtz  \\
ROGUES rejected_spots.txt \\
ANOMPLOT \\\${tempfile}.anomplot \\
NORMPLOT \\\${tempfile}.normplot \\
SCALEPACK merged.sca \\
SCALES \\\${tempfile}.scales << EOF-scale
# save disk space?
#NODUMP
#ANALYSE NOPLOT

title "batch scaling of \\\$title"
\${rename_dataset}NAME PROJECT project CRYSTAL xtal DATASET dataset

resolution \\\$RES

EOF-mergescript
#if(-e \${tempfile}.runs) then
#    cat \${tempfile}.runs >> \$mergescript
#    rm -f \${tempfile}.runs
#else
if(\$?SMOOTH_RUNS) then
    echo "\$SMOOTH_RUNS" |\\
	 nawk 'BEGIN{RS="%"} {print}' >> \$mergescript
else
    echo "scales batch bfactor on" >> \$mergescript
endif
cat << EOF-mergescript >> \$mergescript

# straight frame-by-frame scales (for discontinuities in dose per frame)
#scales batch bfactor on
# frame-by-frame scales with smooth B-factor (discontinuous dose, but no xtal decay)
#scales batch bfactor on brotation spacing 5 
# smooth scales with smooth B-factor (if you have no discontinuities in dose per frame)
#scales rotation spacing 5 bfactor on
#
# restrain scales
\${merge_tie}tie rotation 0.1
\${merge_damp}DAMP 0.1 50
#
# extend nearly-full partials (this is important if you have no fulls)
#intensities scale_partials 0.8
# or use summed partials as fulls:
\${scale_partials}intensities partials
\$extra_partials
#
#########################################################
#  See SCALA documentation
SDCORR \$SDCORR
#########################################################
# 
# converge to within 0.3 sigmas of deviation (maximum of 200 cycles)
cycles 200 converge 0.3

anomalous on

output polish
EOF-scale
#
##############################################################################
# run truncate to finish the job
#
##############################################################################
truncate:
truncate hklin \\\${tempfile}.scaled.mtz hklout \\\${tempfile}.merged.mtz << EOF-trunc
title "anomalous truncate of \\\$title"
# resolution used to determine B factor
#rscale 4 2.8
#ranges 0.01

nresidue \\\$ASU
truncate yes
anomalous yes
LABOUT  F=F  SIGF=SIGF DANO=DANO SIGDANO=SIGDANO ISYM=ISYM
EOF-trunc

##############################################################################
# make sure completeness is correctly reported in mtz
#
##############################################################################
unique hklout \\\${tempfile}.unique.mtz << EOF-unique
SYMM \\\$SGnum
CELL \\\$CELL
RESOLUTION \\\$RES
LABOUT  F=F  SIGF=SIGF
EOF-unique
mtzutils hklin1 \\\${tempfile}.merged.mtz \\
         hklin2 \\\${tempfile}.unique.mtz \\
         hklout \\\$outfile << EOF-util
UNIQUE
RUN
EOF-util

# clean up
rm -f \\\${tempfile}.merged.mtz >& /dev/null
rm -f \\\${tempfile}.unique.mtz >& /dev/null
rm -f \\\${tempfile}.scaled.mtz >& /dev/null
rm -f \\\${tempfile}.sorted.mtz >& /dev/null
rm -f \\\${tempfile}.anomplot   >& /dev/null
rm -f \\\${tempfile}.normplot   >& /dev/null
rm -f \\\${tempfile}.scales     >& /dev/null
rm -f \\\${tempfile}.\\\${SG}.mtz  >& /dev/null
exit

##############################################################################
##############################################################################
##############################################################################
##############################################################################
Setup:
# command-line arguments
foreach arg ( \\\$* )
    if("\\\$arg" =~ *.mtz) set rawfile = "\\\$arg"
    if(("\\\$arg" =~ [0-9]*)&&("\\\$arg" =~ *A)) then
        # a number ending with "A" must mean resolution
        set RES = \\\`echo "\\\$arg" | nawk '{print \\\$1+0}'\\\`
	continue
    endif
    if(("\\\$arg" =~ [0-9]*)&&("\\\$arg" !~ [a-z,A-Z]*)) then
	# a pure number is on the command line
	if("\\\$arg" =~ *.*) then
	    # take it as resolution
	    set RES = \\\`echo "\\\$arg" | nawk '{print \\\$1+0}'\\\`
	else
	    # take it as ASU size
	    set ASU = \\\`echo "\\\$arg" | nawk '{print \\\$1+0}'\\\`
	endif
    endif
    
    # new space group
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	set temp = \\\`nawk -v SG=\\\$arg '\\\$4 == toupper(SG) && \\\$1<500 {print \\\$4;exit}' \\\$CLIBD/symop.lib | head -1\\\`
	if("\\\$temp" =~ [PpCcIiFfRrHh][1-6]*) then
	    # known space group
	    set new_SG = "\\\$temp"
	else
	    # check for "pseudo-spacegroup" language
	    if("\\\$arg" =~ [Pp]2212) then
		# P2221 with screw along current "b"
		set new_SG = "P2221"
		set REINDEX = "reindex l, h, k"
	    endif
	    if("\\\$arg" =~ [Pp]2122) then
		# P2221 with screw along current "a"
		set new_SG = "P2221"
		set REINDEX = "reindex k, l, h"
	    endif
	    if("\\\$arg" =~ [Pp]21221) then
		# P21212 with non-screw along current "b"
		set new_SG = "P21212"
		set REINDEX = "reindex l, h, k"
	    endif
	    if("\\\$arg" =~ [Pp]22121) then
		# P21212 with non-screw along current "a"
	    	set new_SG = "P21212"
		set REINDEX = "reindex k, l, h"
	    endif
	endif
    endif
end


##############################################################################
# check input MTZ file
if(! -e "\\\$rawfile") then
    set HELP
    goto Help
endif

##############################################################################
# update cell and SG variables from the raw MTZ header
#
##############################################################################
echo "HEADER" | mtzdump hklin \\\$rawfile >! \\\$tempfile
set SG =   \\\`nawk '/Space group/{gsub("\\\\047","");print \\\$5}' \\\$tempfile\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile} \\\`
set SG = \\\` nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile} \\\`
set SG = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set CELL = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\$tempfile\\\`
set mtzRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\$tempfile\\\`
rm -f \\\$tempfile

set temp = \\\`echo "\\\$RES \\\$mtzRES" | nawk '\\\$1>=\\\$2{print \\\$1} \\\$1<\\\$2{print \\\$2}'\\\`
if("\\\$temp" != "\\\$RES") then
    echo "\\\$rawfile resolution is only \\\${temp}A"
    set RES = "\\\$temp"
endif


##############################################################################
# change of space group? 
#
##############################################################################
if(("\\\$?new_SG")||(\\\$?REINDEX)) then
    # need a new space group
    if(! \\\$?REINDEX) set REINDEX = ""
    
    # change the space group
    echo "reindexing \\\$rawfile to \\\$new_SG \\\$REINDEX"
    if("\\\$new_SG" =~ R* || "\\\$new_SG" =~ H*) then
	set test = \\\` nawk -v SG=\\\$new_SG '\\\$4==SG{print \\\$1; exit}' \\\${CLIBD}/symop.lib \\\`
	if("\\\$test" != "") set new_SG = \\\$test
    endif
    reindex HKLIN \\\$rawfile HKLOUT \\\${tempfile}.\\\${new_SG}.mtz << end_reindex
SYMMETRY \\\$new_SG
\\\$REINDEX
END
end_reindex
    set SG = \\\$new_SG
    set rawfile = \\\${tempfile}.\\\${SG}.mtz
endif


goto Return_From_Setup

EOF-mergescript
chmod a+x \$mergescript



















































cat << EOF-autoscala >! autoscala
#! \$nawk -f
BEGIN {
#
#
#	Automatically adjusts SDCORR card in SCALA for "optimum" statistics
#	as given by agrovata.
#
#	The provided script MUST generate mergeing statistics (agrovata or scala).
#	The following scripts must be creatable.
#
#	test_script = "./" FILENAME "_test"
#	best_script = "./" FILENAME "_best"
#
#	The latter will continuously be updated to the best SDCORR line
#	found so far.
#
#
#
#
#
#
#
	# these are convergence criteria
	# specify the number of decimal places you want to refine
	# each variable to.
	sdfac_decimals = 2
	sdprime_decimals = 0
	sdadd_decimals = 2

	# defaults for Golden Section search
	# go ahead and modify these if you're 
	# SURE the best value is bracketed
	maximum_sdprime = 15
	maximum_sdadd   = 0.1

	minimum_sdprime = 0
	minimum_sdadd   = 0
	
	# alternately, you may specify "tune=factor"

	best_so_far = 1000000
	line = 0
	if(!debug) debug = 0
}
# finish up initialization (for linux awk)
NR==1{
    if((!test_script)&&(FILENAME)) test_script = "./" FILENAME "_test"
    if((!best_script)&&(FILENAME)) best_script = "./" FILENAME "_best"
    if((!test_log)&&(FILENAME))    test_log    = "./" FILENAME ".log"

    if(!test_script) test_script = "./scala.com_test"
    if(!best_script) best_script = "./scala.com_best"
    if(!test_log)    test_log    = "./scala.com.log"
}

########################################################################
#       Analyze the supplied script & copy it into memory              #
########################################################################

# copy the script into an array
{
    ++line;
    ++number_of_lines;
    script[line] = \\\$0;

    # now make everything easier to search
    \\\$0 = tolower(\\\$0);
}

# look for the "SDCORR" card in scala
/^sdcorr/ {
    # get the current sd correction parameters
    sdfac = \\\$2;
    if(NF == 4)
    {
	sdprime = \\\$3;
	sdadd = \\\$4;
    }
    else
    {
	# no sdprime specified
	sdprime = 0;
	sdadd = \\\$3;
    }	

    sdcorr_line = line;
}

END {
########################################################################
#	Now begins the "real" program                                  #
########################################################################


    # user may specify "tuning mode"
    if(tune > 1)
    {
	if(sdprime)
	{
	    maximum_sdprime = sdprime * tune;
	    minimum_sdprime = sdprime / tune;
	}

	if(sdadd)
	{
	    maximum_sdadd = sdadd * tune;
	    minimum_sdadd = sdadd / tune;
	}
    }

    # signal to optimize ...
    max_sdfac = max_sdprime = max_sdadd = "restart"
    done = 0;
    
    while(!done)
    {
	# write the script
	WriteScript(test_script);

	if(value[script[sdcorr_line]] != 0)
	{
	    # we have already caclulated this value
	    
	    RMSD_sigma = value[script[sdcorr_line]]
	    if(debug>1) print  "recall: " script[sdcorr_line] "\\\\t\\\\tRMSD(sigma): " RMSD_sigma*100 "\\\\tbest so far: " best_so_far*100;
	}
	else
	{
	    # we havn't run this pair before
	    
	    # run it, and filter output
	    printf  "trying: %s ", script[sdcorr_line] sdcorr_pad;
	    GetResults(test_script);
	
	    # remember all values obtained (to avoid repeats)
	    value[script[sdcorr_line]] = RMSD_sigma;

	    # print out rating of this run
	    printf "RMS(scatter/sigma -1): %8.5f    ", RMSD_sigma;

	    # update absolute best result
	    if(RMSD_sigma < best_so_far) 
	    {
		best_so_far = RMSD_sigma;
		best_sdcorr = script[sdcorr_line];

		# write out best scripts immediately
		WriteScript(best_script);

		# print out the values used, and their effect
		printf "best so far: %8.5f ", best_so_far;
	    }
	    # finish the line
	    print "";
	}

	# pick next values based on last run...
	if(NextSDadd()) 
	{
	    # ...has converged
	    
	    # "inner" loop done, so pick next sdprime value
	    if(NextSDprime()) 
	    {
		# ...has converged
		
		# both have converged, so we are done
		done = "true";
	    }
	    # reoptimize sdadd with new sdprime
	    max_sdadd = "restart";
	}
    }
    
    # Main loop has exited.
    # parameters have converged, so finish up


    # update scala's output files to best values
    #GetResults(best_script);

    
    # update variables for output
    split(best_sdcorr, best);
#    sdfac   = best[2];
    sdfac   = sprintf("%." sdfac_decimals "f", best_sdfac);
    sdprime = best[3];
    sdadd   = best[4];    
    
    # get rid of "test" script
    system("rm -f " test_script)
    # update the "best" script
    WriteScript(best_script);
    
    if(summary != "no")	    # option for cleaner output
    {
	print  "\\\\n\\\\nSUMMARY:\\\\n"
	printf("%s ==> RMSD = %.4f\\\\n", best_sdcorr, value[best_sdcorr]);
	print  "\\\\n"
	print  "****************************************"
	print  "**      BEST CARD FOUND               **"
	printf "**      %21s         **\\\\n", script[sdcorr_line];
	print  "****************************************"
	print  "\\\\n"

	# tell user what to do next
	print "***********************"
	print "***   ALL DONE!!!   ***"
	print "***********************"

	print "Your new " FILENAME " can be found at: " best_script

    }

}
########################################################################
#	Functions used in this script                                  #
########################################################################


#########################################################################
#	NextSDprime()							#
#									#
#	Updates optimizing parameters based on observed output from	#
#	the agrovata script.						#
#									#
#	uses:		RMSD_sigma					#
#									#
#	modifies:	sdprime						#
#									#
#	contains:	max_sdprime					#
#			min_sdprime					#
#			best_sdprime					#
#									#
#			value[]						#
#									#
#########################################################################
function NextSDprime()
{
    # offset SDprime to keep from interfering with sdfac in value[]
    sdprime += 100;
    best_sdprime += 100;

    # this should be known first
    value[sdprime] = RMSD_sigma;

    # pick some reasonable limits
    if (max_sdprime == "restart") 
    {
	min_sdprime = minimum_sdprime +100;
	value[max_sdprime] = 100000;

	best_sdprime = min_sdprime;
	value[best_sdprime] = 100000;

	max_sdprime = maximum_sdprime +100;
	value[max_sdprime] = 100000;
    }

    # use the Golden Section method to find minimum
    sdprime = GoldStep(min_sdprime, sdprime, best_sdprime, max_sdprime);
    min_sdprime = Gold_min;
    max_sdprime = Gold_max;
    best_sdprime = Gold_best;

        
    # just for monitoring...
    sdprime_step = sdprime - best_sdprime;
	
    # update move counter
    ++move;

    # now move sdprime back to true value
    sdprime -= 100;
    best_sdprime -= 100;

    # check for convergence
    if(max_sdprime - min_sdprime < 0.1^sdprime_decimals)
    {
	#convergence reached
	doneness = "true";
    }
    else
    {
	doneness = "";
    }
    
    # in case you're intetested...
    return doneness;
}

#########################################################################
#	NextSDadd()							#
#									#
#	Updates optimizing parameters based on observed output from	#
#	the agrovata script.						#
#									#
#	uses:		RMSD_sigma					#
#									#
#	modifies:	sdadd						#
#									#
#	contains:	max_sdadd					#
#			min_sdadd					#
#			best_sdadd					#
#									#
#			value[]						#
#									#
#########################################################################
function NextSDadd()
{
    # this should be known first
    value[sdadd] = RMSD_sigma;

    # pick some reasonable limits
    if (max_sdadd == "restart") 
    {
	min_sdadd = minimum_sdadd;
	value[max_sdadd] = 100000;

	best_sdadd = min_sdadd - min_sdadd_step/10;
	value[best_sdadd] = 100000;

	max_sdadd = maximum_sdadd;
	value[max_sdadd] = 100000;
    }

    # use the Golden Section method to find minimum
    sdadd = GoldStep(min_sdadd, sdadd, best_sdadd, max_sdadd);
    min_sdadd = Gold_min;
    max_sdadd = Gold_max;
    best_sdadd = Gold_best;

                
    # just for monitoring...
    sdadd_step = sdadd - best_sdadd;
	
    # update move counter
    ++move;

    # check for convergence
    if(max_sdadd - min_sdadd < 0.1^sdadd_decimals)
    {
	#convergence reached
	doneness = "true";
    }
    else
    {
	doneness = "";
    }

    # in case you're intetested...
    return doneness;
}





#########################################################################
#	WriteScript(filename)						#
#									#
#	Writes the script contained in the script[] array to the	#
#	file given in "filename."					#
#		The following cards, however, are rewriten with		#
#	the existing trial values:	WIDTH				#
#									#
#	uses:		script[]					#
#			bin_scale					#
#			width						#
#									#
#########################################################################
function WriteScript( filename )
{	
    for(line = 1; line <= number_of_lines; ++line)
    {
	if(line == sdcorr_line)
	{
	    script[line] = "SDCORR " sdfac \\\\
				 " " round(sdprime, sdprime_decimals) \\\\
				 " " round(sdadd, sdadd_decimals);
	    sdcorr_pad = "";
    	    for(i=0;i < 25 - length(script[line]); ++i) {sdcorr_pad = sdcorr_pad " "}
	}

	print script[line] > filename;
    }
    # close the file
    close(filename);

    #change it to an executable;
    system("chmod u+x " filename);
}


#########################################################################
#       GetResults(filename)                                            #
#                                                                       #
#       Runs the script given as "filename" and analyzes the output     #
#       for the agrovata Sigma(scatter/SD) graph.                       #
#               The RMS deviation from an even distribution of          #
#       observations per intensity bin is computed as RMSD_width.       #
#               The RMS deviation from 1.0 of the scatter/SD is         #
#       also computed and placed in RMSD_sigma.                         #
#                                                                       #
#       modifies:       RMSD_width                                      #
#                       RMSD_width_p                                    #
#                       RMSD_sigma                                      #
#                       RMSD_sigma_p                                    #
#                       RMSD_sigma_w                                    #
#                       best_sdfac                                      #
#                                                                       #
#########################################################################
function GetResults ( filename )
{
    # report what we're doing
#    print "running " filename "..."

    # analyze stdout from "agrovata" script
    command = filename
#    if(test_log) command = filename " | tee " test_log
    while(command | getline > 0)
    {
        # look for the graph entry
        if (\\\$0 ~ /^ \\\\\\\$GRAPHS: Sigma\\\\(scatter\\\\/SD\\\\)/)
	{
	    graph = 1
	    
	    # initialize cumulative variables
	    count_full["sum"]=count_part["sum"]=count["sum"]=0
	    bins = 0  
	}
	if (\\\$1 == "TOTALS:") graph = 0

        if(graph && \\\$0 ~ /Sigma/)
        {
            sig1_idx = index(\\\$0,"Sigma");
            sig2_idx = index(substr(\\\$0,sig1_idx+1),"Sigma")+1+sig1_idx;
        }

        if (graph && (\\\$0 !~ /[a-z]/) && NF>3)
        {
            # we are reading a line of graph data
	    ++bins
	    
	    # gather stats	    
#	    count_full[bins]  = \\\$5
#	    count_part[bins]  = \\\$9
            string = substr(\\\$0, 1,count1_idx);
            while(gsub("[^ ]\\\$","",string));
            idx = length(string);
            count_full[bins]  = substr(\\\$0, idx, 9)+0
            string = substr(\\\$0, 1,count2_idx);
            while(gsub("[^ ]\\\$","",string));
            idx = length(string);
            count_part[bins]  = substr(\\\$0, idx, 9)+0
	    count[bins]       = count_full[bins]+count_part[bins]

	    # sums
	    count_full["sum"] += count_full[bins]
	    count_part["sum"] += count_part[bins]
	         count["sum"] += count[bins]

#	    scatt_full[bins]  = \\\$7-1
#	    scatt_part[bins]  = \\\$NF-1
	    scatt_full[bins]  = substr(\\\$0, sig1_idx, 8)-1
	    scatt_part[bins]  = substr(\\\$0, sig2_idx, 8)-1
	    scatt[bins]       = (scatt_full[bins]+scatt_part[bins])/2
	}

        # look for refined SDfac
	if(\\\$0 ~ /Final assessment of SDcorrection multipliers/) { sdfac_list = 1 }
	if(\\\$0 ~ /Summary/) {sdfac_list = 0}

	if(sdfac_list)
	{
	    if((\\\$0 ~ /[0-9]/)&&(\\\$0 !~ /[a-z]/))
	    {
		if(NF>2)
		{
		    ++sdfacs
		    sdfac_sum+=(count_full["sum"]*\\\$2+count_part["sum"]*\\\$5)/(count["sum"])
		}
		else
		{
		    sdfac_list = 0
		}
	    }
	}
    }
    
    # close the pipe!
    close(filename);

    # calculate mean SDFAC
    if(sdfacs) best_sdfac = sdfac_sum/sdfacs
#    printf "%.2f %.2f %.2f %.2f \\\\n", best_sdfac, count_full["sum"], count_part["sum"], count["sum"]

    # the scatt and count arrays should now contain the LAST graph in the log
    if(bins)
    {
	# calculate average values
	count_full["avg"] = count_full["sum"]/bins
	count_part["avg"] = count_part["sum"]/bins
	count["avg"]      = count["sum"]     /bins

	# and now rmsds
	count_full["rms"]=count_part["rms"]=count["rms"]=0
	scatt_full["rms"]=scatt_part["rms"]=scatt["rms"]=scatt["wrms"]=0
	for(i=1; i<=bins; ++i)
	{
	    count_full["rms"] += (count_full[i]-count_full["avg"])*(count_full[i]-count_full["avg"])
	    count_part["rms"] += (count_part[i]-count_part["avg"])*(count_part[i]-count_part["avg"])
	    count["rms"]      += (count[i]     -count["avg"]     )*(count[i]     -count["avg"]     )

	    scatt_full["rms"] += scatt_full[i]*scatt_full[i]
	    scatt_part["rms"] += scatt_part[i]*scatt_part[i]
	    scatt["rms"]      += scatt[i]*scatt[i]
	    scatt["wrms"]     += count_full[i]*scatt_full[i]*scatt_full[i]
	    scatt["wrms"]     += count_part[i]*scatt_part[i]*scatt_part[i]
	}
	
	count_full["rms"] = sqrt(count_full["rms"]/bins)
	count_part["rms"] = sqrt(count_part["rms"]/bins)
	count["rms"]      = sqrt(count["rms"]/bins)
	
	scatt_full["rms"] = sqrt(scatt_full["rms"]/bins)
	scatt_part["rms"] = sqrt(scatt_part["rms"]/bins)
	scatt["rms"]      = sqrt(scatt["rms"]/bins)
	scatt["wrms"]     = sqrt(scatt["wrms"]/count["sum"])
    }
    else
    {
	print "ERROR: no stats generated by " filename
	print "please edit " FILENAME " and make sure it runs by itself."
	exit
    }

    # update global variables
    RMSD_width   = count_full["rms"]
    RMSD_width_p = count_part["rms"]
    RMSD_sigma   = scatt_full["rms"]
    RMSD_sigma_p = scatt_part["rms"]
    RMSD_sigma_w = scatt["wrms"]

    RMSD_sigma = RMSD_sigma_w

}

#########################################################################
#	GoldStep(min, last, best, max)					#
#									#
# Computes the Golden (next) step to minimize a variable		#
#									#
#	modifies:							#
#									#
#########################################################################

function GoldStep(min, last, best, max)
{
    # debugging...
    if(debug) printf "\\\\n" min " " best " " max " ==GoldStep==> "
    
    # eliminate sections that cannot contain the minimum
    if(last >= best)
    {
	# we tried a larger value last time
	if(value[last] <= value[best])
	{
	    # minimum must be somewhere between "best" and "max"
	    min = best;
	    best = last;
	}
	else
	{
	    # minimum must be somewhere between "min" and "last"
	    max = last;
	}
    }
    else
    {
	# we tried a smaller value last time
	if(value[last] <= value[best])
	{
	    # minimum must be somewhere between "min" and "best"
	    max = best;
	    best = last;
	}
	else
	{
	    # minimum must be somewhere between "last" and "max"
	    min = last;	    
	}
    }

    # now decide what width to try next
    if((max - best) > (best - min))
    {
	# next value should be larger
	Gold_next = best + 0.38*(max - best)
    }
    else
    {
	# next value should be smaller
	Gold_next = best - 0.38*(best - min)
    }
    
    # save the parameters as Globals ( this is awful!)
    Gold_min = min;
    Gold_max = max;
    Gold_next = Gold_next;
    Gold_best = best;
    
    # debugging...
    if (debug) printf min " " best " " max "\\\\t"
    
    return Gold_next;
}


function abs(number)
{
	return sqrt(number^2);
}

function round(number, sigdigs)
{
	return int(number*10^sigdigs)/10^sigdigs;
}

EOF-autoscala
chmod a+x autoscala



















































cat << EOF-search >! SGsearch.com
#! /bin/csh -f
#
#	SGsearch.com	4.2			-James Holton   12-1-09
#
#  Space group search script for scala scripts
#
set rawfile  = raw.mtz
set script   = merge.com
set logfile  = logs/merge
set tempfile = \\\${CCP4_SCR}/SGsearch_temp\\\$\\\$

set SG   = P1		# read from \\\$rawfile
set CELL		
set RES  = ""		# default to resolution in \\\$script or \\\$rawfile
set P1_scales_SG = ""

alias nawk \$nawk
nawk 'BEGIN{exit}' >& /dev/null
if(\\\$status) alias nawk awk

# command-line arguments (1 of 2)
foreach arg ( \\\$* )
    if(-e "\\\$arg") then
	if("\\\$arg" =~ *.mtz) set rawfile = "\\\$arg"
	if("\\\$arg" =~ *.com) set script  = "\\\$arg"
    endif
    if("\\\$arg" == ignore) set IGNORE
end

if((! -e "\\\$rawfile")||(! -e "\\\$script")) then
cat << EOF
usage: \\\$0 [\\\$script] [\\\$rawfile] \\\$SG 2.2A
where:
 \\\$script will scale and merge
 scaling, mergeing and truncating \\\$rawfile

 \\\$rawfile is the unmerged mtz file

 \\\$SG is the "root" space group i.e.
    P222 for P222, P2221, P21212, and P212121

 2.2A is the resolution for scaling and mergeing


EOF
    exit 1
endif

ls -1 \\\${logfile}.*.log >& /dev/null
if((! \\\$status)&&(! \\\$?IGNORE)) then
    echo ""
    echo "NOTICE: using stats from \\\${logfile}.*.log"
    echo ""
endif
if(! -e logs) mkdir logs

echo -n "evaluating alternative space groups for \\\$rawfile with \\\$script"

##############################################################################
# update cell and SG variables from the raw MTZ header
#
##############################################################################
echo "HEADER" | mtzdump hklin \\\$rawfile >! \\\$tempfile
set SG = \\\`nawk '/Space group/{print \\\$5}' \\\$tempfile\\\`
set SG = \\\`nawk '/Space group/{gsub("\\\\047","");print \\\$5}' \\\$tempfile\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile} \\\`
set SG = \\\` nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile} \\\`
set SG = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set CELL = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\$tempfile\\\`
set mtzRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\$tempfile\\\`

# calculate unit cell volume
echo \\\$CELL |\\\\
nawk 'NF==6{s=atan2(1,0)/90; A=cos(s*\\\$4); B=cos(s*\\\$5); G=cos(s*\\\$6); \\\\
 skew = 1 + 2*A*B*G - A*A - B*B - G*G ; if(skew < 0) skew = -skew;\\\\
 printf "%.3f\\\\n", \\\$1*\\\$2*\\\$3*sqrt(skew)}' |\\\\
cat >! \\\${tempfile}volume
set CELLvolume = \\\`cat \\\${tempfile}volume\\\`
rm -f \\\${tempfile}volume >> /dev/null

# command-line arguments (2 of 2)
foreach arg ( \\\$* )
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) set SG = \\\`echo \\\$arg | nawk '{print toupper(\\\$0)}'\\\`
    if(("\\\$arg" =~ [0-9]*)&&("\\\$arg" !~ [a-z,A-Z]*)) then
	# a pure number is on the command line
	if("\\\$arg" =~ *.*) then
	    # take it as resolution
	    set RES = \\\`echo \\\$arg | nawk '\\\$1+0>0.5 && \\\$1+0<10{print \\\$1+0}'\\\`
	else
	    # take it as ASU size
	    set ASU = \\\`echo \\\$arg | nawk '{printf "%d", \\\$1+0}'\\\`
	endif
    endif
    if("\\\$arg" =~ [0-9]*A) then
	# looks like a resolution
	set temp = \\\`echo \\\$arg | nawk '\\\$1+0>0.5 && \\\$1+0<10{print \\\$1+0}'\\\`
	if(\\\$#temp) set RES = "\\\$temp"
    endif
end


if("\\\$RES" != "") then
    echo " to \\\${RES}A"
else
    echo ""
    set RES = "\\\$mtzRES"
endif

# extract protein-compatible space groups from CCP4 in order of increasing symmetry
#nawk '\\\$5 ~ /^PG/ && ! /m/ && ! /bar/ && \\\$1 < 500' \\\$CLIBD/symop.lib >! \\\$tempfile
cat \\\${CLIBD}/symop.lib |\\\\
nawk '\\\$5 ~ /^PG/ && ! /m/ && ! /bar/ && \\\$1 < 500{\\\\
	printf "%s ", \\\$0; for(op=\\\$2;op>0;--op){getline;printf \\\$1 \\\$2};print ""}' |\\\\
nawk '{print length(\\\$NF), \\\$0}' |\\\\
sort -n |\\\\
nawk '{print \\\$2,\\\$3,\\\$4,\\\$5,\\\$6,\\\$7}' >! \\\$tempfile


# get crystal system of \\\$SG
set sys = \\\`nawk -v SG=\\\$SG '\\\$4==SG{print \\\$6}' \\\$tempfile\\\`
set latt = \\\`echo \\\$SG | nawk '{print substr(\\\$1,1,1)}'\\\`

# extract point group representatives
nawk 'substr(\\\$4,2)==substr(\\\$5,3)' \\\$tempfile >! \\\${tempfile}PGs
# extract point group representatives of the same lattice type
#nawk -v latt=\\\$latt 'substr(\\\$4,1,1)==latt && substr(\\\$4,2)==substr(\\\$5,3)' \\\$tempfile >! \\\${tempfile}PGs
nawk -v latt=\\\$latt 'substr(\\\$4,1,1)==latt && ! seen[substr(\\\$5,3)]{print;++seen[substr(\\\$5,3)]}' \\\$tempfile >! \\\${tempfile}PGs


# now get all point groups that co-index with \\\$SG
if(("\\\$sys" == "TRIGONAL") || ("\\\$sys" == "HEXAGONAL")) then
    set SGs =  \\\`nawk '\\\$6 ~ /TRIG/{print \\\$4} \\\$6 ~ /HEXA/{print \\\$4}' \\\${tempfile}PGs\\\`
else
    set SGs =  \\\`nawk -v S=\\\$sys '\\\$6==S{print \\\$4}' \\\${tempfile}PGs\\\`
endif
rm -f \\\$tempfile \\\${tempfile}PGs

echo "SG      ASU(A^3)  ASU(~kD) Rmerge(%)   Brightest systematic absence"

SGcheck:

# add any extra considerations
set SGs = ( \\\$SGs )
if("\\\$SGs " !~ "P1 "*) set SGs = "P1 \\\$SGs"

foreach SG ( \\\$SGs )

    # get size of ASU (in A^3)
    set tempV = \\\`nawk -v SG=\\\$SG '\\\$4==SG && \\\$1 < 500{print \\\$2}' \\\$CLIBD/symop.lib\\\`
    set tempV = \\\`echo "\\\$CELLvolume \\\$tempV" | nawk '\\\$2+0!=0{print \\\$1/\\\$2}'\\\`
    if("\\\$tempV" != "") set volume = "\\\$tempV"

    # indicate P1 merge after P1_scales_SG scaling
    set printSG = "\\\$SG"
    if("\\\$P1_scales_SG" != "" && "\\\$SG" == "P1" && "\\\$P1_scales_SG" != "P1") then
	set SG = \\\$P1_scales_SG
	set printSG = "\\\${SG}-P1"
    endif
    
    # print it out in A^3 and kD at Vm=2.5
    echo "\\\$printSG" | nawk '{printf "%-7s", \\\$0}'
    echo "\\\$volume" | nawk '{printf "%9d  %3d      ", \\\$0, \\\$0/2500}'   
    
    # remove bum log files
    if(-e \\\${logfile}.\\\${printSG}.log) then
	grep Overall: \\\${logfile}.\\\${printSG}.log >& /dev/null
	if((\\\$status)||(\\\$?IGNORE)) rm -f \\\${logfile}.\\\${printSG}.log
    endif
    
    # set up reindexing procedure
    set REINDEX = ""
    set new_SG  = "\\\$SG"
    # check for "pseudo-spacegroups"
    set temp = \\\`echo \\\$SG | nawk '{print toupper(\\\$1)}'\\\`
    if("\\\$temp" =~ [PC]2[12][12]*) then
	set axes = ""
	if("\\\$temp" == P2221) then
	    # P2221 with screw along longest axis
	    set axes  = "a b c"
	    set new_SG = "P2221"
	endif
	if("\\\$temp" == P2212) then
	    # P2221 with screw along mid-length axis
	    set axes  = "b c a"
	    set new_SG = "P2221"
	endif
	if("\\\$temp" == P2122) then
	    # P2221 with screw along shortest axis
	    set axes  = "c a b"
	    set new_SG = "P2221"
	endif
	
	if("\\\$temp" == P21212) then
	    # P21212 with non-screw along longest axis
	    set axes  = "a b c"
	    set new_SG = "P21212"
	endif
	if("\\\$temp" == P21221) then
	    # P21212 with non-screw along mid-length axis
	    set axes  = "b c a"
	    set new_SG = "P21212"
	endif
	if("\\\$temp" == P22121) then
	    # P21212 with non-screw along shotest axis
	    set axes  = "c a b"
	    set new_SG = "P21212"
	endif
	    
	# cannonize these
	if("\\\$new_SG" == "P222")    set axes = "a b c"
	if("\\\$new_SG" == "P212121") set axes = "a b c"
	
	# decide on new axis ordering (for asymmetric orthorhombics)
	if("\\\$axes" != "") then
	    # get current axis ordering
	    # find out what the cannonical one would be
	    # then decide how to go from current ordering to the desired one
	    echo "\\\$CELL" | nawk '{\\\\
		# print out current axis order \\\\
		print \\\$1, "h"; print \\\$2, "k"; print \\\$3, "l"}' |\\\\
	    sort -n |\\\\
	    nawk '\\\\
		# add cannonical axis names\\\\
		NR==1{print \\\$0, "a"} NR==2{print \\\$0, "b"} NR==3{print \\\$0, "c"}' |\\\\
	    nawk -v axes="\\\$axes" 'BEGIN{split(axes, abc)} {\\\\
		# write desired axis ordering in front of cannonical one \\\\
		print abc[NR], \\\$0}' |\\\\
	    sort |\\\\
	    cat >! \\\${tempfile}order    
	    set op = \\\`nawk '{printf "%s", \\\$3} NR~/[12]/{print ","}'  \\\${tempfile}order\\\`

            # check for inverted hand
            set test = \\\`echo " \\\${op}, \\\${op}, " | grep " h, k, l," | wc -l\\\`
            if(\\\$test == 0) then
                # flip the last sign
                set op = \\\`echo \\\$op | awk '{print \\\$1,\\\$2,"-" \\\$3}'\\\`
            endif

	    set REINDEX = "reindex \\\$op"
	    rm -f \\\${tempfile}order >& /dev/null
	
	    # this should give us a mapping between any two orthorhombics
	endif
    endif
    if("\\\$new_SG" =~ R*) set new_SG = \\\$SGnum
    if("\\\$new_SG" =~ H*) set new_SG = \\\$SGnum


    # only run mergeing step if we havn't already done so
    if((! -e \\\${logfile}.\\\${printSG}.log)||(\\\$?IGNORE)) then
	echo -n "" >! \\\${logfile}.\\\${printSG}.log

	# apply the resolution cutoff
	echo "RESOLUTION \\\$RES" |\\\\
	mtzutils hklin1 \\\$rawfile hklout \\\${tempfile}.cut.mtz >>& \\\${logfile}.\\\${printSG}.log
	
	# now re-index the input, raw mtz file
	reindex HKLIN \\\${tempfile}.cut.mtz \\\\
		HKLOUT \\\${tempfile}.reindexed.mtz << end_reindex >>& \\\${logfile}.\\\${printSG}.log
SYMMETRY \\\$new_SG
\\\$REINDEX
END
end_reindex
	rm -f \\\${tempfile}.cut.mtz >& /dev/null
	
	# make sure it's sorted
	sortmtz hklout \\\${tempfile}.\\\${SG}.mtz  << end_sort >>& \\\${logfile}.\\\${printSG}.log
	#VRSET -9e+38
	H K L M/ISYM BATCH I SIGI
	\\\${tempfile}.reindexed.mtz
end_sort
	rm -f \\\${tempfile}.reindexed.mtz >& /dev/null
 	
	# run the merge script
	if("\\\$printSG" !~ *-P1) then
	    ./\\\$script \\\${tempfile}.\\\${SG}.mtz >>& \\\${logfile}.\\\${printSG}.log
	else
	    # rewrite the script to scale with one SG and merge in P1
	    cat \\\$script |\\\\
	    nawk '{print} tolower(\\\$1)~/^cycle/{print "DUMP '\\\${tempfile}'_scales.txt"}' |\\\\
	    cat >! \\\${tempfile}_scale.com
            cat \\\$script |\\\\
            nawk '{print} tolower(\\\$1)~/^cycle/{print "RESTORE '\\\${tempfile}'_scales.txt";print "ONLYMERGE"}' |\\\\
            cat >! \\\${tempfile}_merge.com
	    chmod a+x \\\${tempfile}_scale.com \\\${tempfile}_merge.com
 	    \\\${tempfile}_scale.com \\\${tempfile}.\\\${SG}.mtz >>& \\\${logfile}.\\\${printSG}.log
	    # now merge in P1
	    echo "SYMM P1" |\\\\
	    reindex hklin \\\${tempfile}.\\\${SG}.mtz \\\\
		 hklout \\\${tempfile}.\\\${printSG}.mtz >>& \\\${logfile}.\\\${printSG}.log
	    \\\${tempfile}_merge.com \\\${tempfile}.\\\${printSG}.mtz >>& \\\${logfile}.\\\${printSG}.log

#	    rm -f \\\${tempfile}_scale.com \\\${tempfile}_merge.com >& /dev/null
#	    rm -f \\\${tempfile}.scales.txt >& /dev/null
#	    rm -f \\\${tempfile}.\\\${printSG}.mtz >& /dev/null
	endif
	
	# see if truncate was run
	grep "SUITE: TRUNCATE" \\\${logfile}.\\\${printSG}.log >& /dev/null
	if(\\\$status) then
	    # truncate was not run, so lets try to run it
	    set mergedmtz = \\\`nawk '/Filename:/{mtz=\\\$NF} /Scala/&&/termination/{print mtz}' \\\${logfile}.\\\${printSG}.log\\\`
	    set ASU = \\\`echo "\\\$volume" | nawk '{print \\\$0/2500}'\\\`
	    if((-e "\\\$mergedmtz")&&("\\\$ASU" != "")) then
		echo "nresidue \\\$ASU" |\\\\
		truncate hklin \\\$mergedmtz hklout \\\${tempfile}.mtz >>& \\\${logfile}.\\\${printSG}.log
	    	if(\\\$status) then
		    # truncate failed, try it again? 
		endif
	    endif
	endif
	
	# clean up
	rm -f \\\${tempfile}.\\\${SG}.mtz >& /dev/null
    endif
    
    # print out Rmerge
    set Rmerge = \\\`nawk '/ Overall /{line=\\\$0;getline;if(\\\$0~/Rmerge/){print substr(line,index(\\\$0,"Rmerge"),6)}}' logs/merge.\\\${printSG}.log | tail -1\\\`
    set test = \\\`echo "\\\$Rmerge" | awk '{print (\\\$1+0 == 0)}'\\\`
    if(\\\$test ) then
        set Rmerge = \\\`nawk '/ Overall: /{print \\\$2}' logs/merge.\\\${printSG}.log | tail -1\\\`
    endif
    set test = \\\`echo "\\\$Rmerge" | awk '{print (\\\$1+0 == 0)}'\\\`
    if(\\\$test) then
	# use "Ranom" instead?
	set Rmerge = \\\`nawk '/ Overall: /{print \\\$5}' logs/merge.\\\${printSG}.log | tail -1\\\`
    endif
    set test = \\\`echo "\\\$Rmerge" | awk '{print (\\\$1+0 == 0)}'\\\`
    if(\\\$test) then
	echo "-"
    else
	# print out Rmerge
	echo \\\$Rmerge | nawk '{printf "%5.1f        ", \\\$1*100}'
    
	# Look for Systematic absence intensities
	cat  logs/merge.\\\${printSG}.log |\\\\
	nawk '/Systematic absences are OMITTED/,/Distributions/' |\\\\
	nawk 'NF==5 && ! /[a-z]/ && \\\$5 != 0{printf "%-4d%-4d%-4d I/sig = %8.3f\\\\n", \\\$1, \\\$2, \\\$3, \\\$4/\\\$5}' |\\\\
	nawk '{print \\\$6"|"\\\$0}' |\\\\
	sort -n |\\\\
	nawk -F "|" '{print \\\$2}' >! \\\$tempfile
	set Absence = \\\`cat \\\$tempfile | tail -1\\\`
	if("\\\$Absence" != "") then
	    # print out the worst one
	    tail -1 \\\$tempfile | nawk '{printf "%s", \\\$0}'
	endif
	rm -f \\\$tempfile
    
	echo ""
    endif
end

# now, pick the best point/space group

# gather stats from last round of runs

if(\\\$?saved_SGs) then
    set SGs = ( \\\$saved_SGs )
    unset saved_SGs
endif
echo "" >! \\\$tempfile
foreach SG ( \\\$SGs )

    # get size of ASU (in A^3)
    set temp = \\\`nawk -v SG=\\\$SG '\\\$4==SG && \\\$1 < 500{print \\\$2}' \\\$CLIBD/symop.lib\\\`
    set temp = \\\`echo "\\\$CELLvolume \\\$temp" | nawk '\\\$2+0!=0{print \\\$1/\\\$2}'\\\`
    if("\\\$temp" != "") set volume = "\\\$temp"

    # indicates P1 merge after P1_scales_SG scaling
    set printSG = "\\\$SG"
    if("\\\$P1_scales_SG" != "" && "\\\$SG" == "P1" && "\\\$P1_scales_SG" != "P1") then
	set printSG = "\\\${P1_scales_SG}-P1"
    endif
    
    set Rmerge = \\\`nawk '/ Overall /{line=\\\$0;getline;if(\\\$0~/Rmerge/){print substr(line,index(\\\$0,"Rmerge"),6)}}' logs/merge.\\\${printSG}.log | tail -1\\\`
    set test = \\\`echo "\\\$Rmerge" | awk '{print (\\\$1+0 == 0)}'\\\`
    if(\\\$test ) then
        set Rmerge = \\\`nawk '/ Overall: /{print \\\$2}' logs/merge.\\\${printSG}.log | tail -1\\\`
    endif
    set test = \\\`echo "\\\$Rmerge" | awk '{print (\\\$1+0 == 0)}'\\\`
    if(\\\$test) then
        # use "Ranom" instead?
        set Rmerge = \\\`nawk '/ Overall: /{print \\\$5}' logs/merge.\\\${printSG}.log | tail -1\\\`
    endif
    set test = \\\`echo "\\\$Rmerge" | awk '{print (\\\$1+0 == 0)}'\\\`
    if(! \\\$test) then
	echo -n "\\\$SG " >> \\\$tempfile
	echo -n "\\\$Rmerge " >> \\\$tempfile
	cat  logs/merge.\\\${printSG}.log |\\\\
	nawk '/Systematic absences are OMITTED/,/Distributions/' |\\\\
	nawk 'NF==5 && ! /[a-z]/ && \\\$5 != 0{print \\\$4/\\\$5}' |\\\\
	sort -n | tail -1 >! \\\$tempfile.absent
	set Absence = \\\`tail -1 \\\$tempfile.absent\\\`
	echo "\\\$Absence" >> \\\$tempfile
    endif
end
rm -f \\\${tempfile}.absent >& /dev/null

# do some statistics
awk '{print \\\$2"|"\\\$0}' \\\$tempfile | sort -n |\\\\
nawk -F "|" '{print \\\$2}' >! \\\${tempfile}sorted
set best_SG     = \\\`nawk 'NF==2' \\\${tempfile}sorted | head -1 | nawk '\\\$2+0>0.0{print \\\$1}'\\\`
set P1_Rmerge   = \\\`nawk '\\\$1=="P1"{print \\\$2}' \\\$tempfile\\\`
set min_Rmerge  = \\\`nawk 'NF==2' \\\${tempfile}sorted | head -1 | nawk '\\\$2+0>0.0{print \\\$2}'\\\`
set max_Rmerge  = \\\`nawk 'NF==2' \\\${tempfile}sorted | tail -1 | nawk '\\\$2+0>0.0{print \\\$2}'\\\`
set mean_Rmerge = \\\`nawk '\\\$2+0>0{sum += \\\$2;++count} END{if(count) print sum/count}' \\\$tempfile\\\`
set rmsd_Rmerge = \\\`nawk -v avg=\\\$mean_Rmerge '\\\$2+0>0{sum+=(\\\$2-avg)^2;++count} END{if(count) print sqrt(sum/count)}' \\\$tempfile\\\`
rm -f \\\${tempfile}sorted >& /dev/null

# do we already have a "best" SG for obtaining the P1 baseline?
if("\\\$P1_scales_SG" == "" && "\\\$best_SG" != "P1" && "\\\$best_SG" != "") then
    # probably always a good idea to try and use P1_scales_SGs scales, but merge with P1
    set P1_scales_SG = "\\\$best_SG"
    set saved_SGs = ( \\\$SGs )
    set SGs = P1
    echo "scaling with \\\$P1_scales_SG to merge in P1"
    goto SGcheck
endif

set Rmerge_cutoff = ""

# see if P1 run worked
if("\\\$P1_Rmerge" != "") then
    # P1 run succeeded, so "no symmetry" hypothesis has been considered
    if("\\\$best_SG" == "P1") then
	# P1 had a lower Rmerge than anything else
	set Rmerge_cutoff = \\\`echo \\\$min_Rmerge 0.1 | nawk '{print \\\$1+1.0*\\\$2}'\\\`
    else
	# P1 worked, but it was not the best score
 	set Rmerge_cutoff = \\\`echo \\\$min_Rmerge 0.1 | nawk '{print \\\$1+1.0*\\\$2}'\\\`
    endif
else
    # P1 run failed, but we gotta have it
    # what do we do?
    set Rmerge_cutoff = 0.2
endif

set test = \\\`echo \\\$Rmerge_cutoff 0.5 | nawk 'NF==2{print (\\\$1 > \\\$2)}'\\\`
if("\\\$test" == "1") set Rmerge_cutoff = 0.5

# filter for SGs below the mergeing criteria
set SGs = \\\`nawk -v max=\\\$Rmerge_cutoff '\\\$2+0 < max && \\\$3+0 < 4 {print \\\$1}' \\\$tempfile\\\`

if("\\\$SGs" == "") then
    echo "WARNING: none of these space groups merged well."
    if("\\\$P1_Rmerge" == "") echo "not even P1"
    echo "         try to tune up \\\$script next time."
    exit 9
endif

# if \\\$?PG, we have been here before
if(\\\$?PG) then
    if(\\\$#SGs == 1) then
	echo "Possible space group is: \\\$SGs"
    else
	echo "Possible space groups are: \\\$SGs"
    endif
#    echo "\\\$SGs" >! SGs.txt
    rm -f \\\$tempfile
    exit
endif
    
# extract protein-compatible space groups from CCP4 in order of increasing symmetry
#nawk '\\\$5 ~ /^PG/ && ! /m/ && ! /bar/ && \\\$1 < 500' \\\$CLIBD/symop.lib >! \\\$tempfile
cat \\\${CLIBD}/symop.lib |\\\\
nawk '\\\$5 ~ /^PG/ && ! /m/ && ! /bar/ && \\\$1 < 500{\\\\
        printf "%s ", \\\$0; for(op=\\\$2;op>0;--op){getline;printf \\\$1 \\\$2};print ""}' |\\\\
nawk '{print length(\\\$NF), \\\$0}' |\\\\
sort -n |\\\\
nawk '{print \\\$2,\\\$3,\\\$4,\\\$5,\\\$6,\\\$7}' >! \\\$tempfile

# pursue all potential possibilites (but there should really only be one)
set temp = ""
echo "checking for screw axes in \\\$SGs"
foreach SG ( \\\$SGs )

    # get size of ASU (in A^3)
    set tempV = \\\`nawk -v SG=\\\$SG '\\\$4==SG && \\\$1 < 500{print \\\$2}' \\\$CLIBD/symop.lib\\\`
    set tempV = \\\`echo "\\\$CELLvolume \\\$tempV" | nawk '\\\$2+0!=0{print \\\$1/\\\$2}'\\\`
    if("\\\$temp" != "") set volume = "\\\$tempV"

    # get point group of \\\$SG
    set PG = \\\`nawk -v SG=\\\$SG '\\\$4==SG{print \\\$5}' \\\$tempfile\\\`
    set latt = \\\`echo \\\$SG | nawk '{print substr(\\\$1,1,1)}'\\\`
    
    # now get all space groups in \\\$PG on \\\$latt
    set temp =  "\\\$temp "\\\`nawk -v PG=\\\$PG -v latt=\\\$latt '\\\$5==PG && substr(\\\$4,1,1)==latt{print \\\$4}' \\\$tempfile\\\`

    # add pseudo-SGs for asymmetric orthorhombics
    if("\\\$PG" == "PG222") then
	set pseudoSGs = ""
	foreach sg ( \\\$temp )
	    set pseudoSGs = "\\\$pseudoSGs \\\$sg"
	    if("\\\$sg" == "P2221") set  set pseudoSGs = "\\\$pseudoSGs P2212 P2122"
	    if("\\\$sg" == "P21212") set  set pseudoSGs = "\\\$pseudoSGs P21221 P22121"
	end
	set temp = "\\\$pseudoSGs"
    endif
end
rm -f \\\$tempfile

set SGs = \\\`echo \\\$temp\\\`

# check each of these

goto SGcheck


exit

EOF-search
chmod a+x SGsearch.com 









# write out a convenient mtz2various script
cat << EOF-mtz2various >! mtz2various.com
#! /bin/csh -f
#
#	general script for converting mtz to another format
#
##############################################################################
# set up awk
alias nawk \$nawk
nawk 'BEGIN{print 1; exit}' >& /dev/null
if(\\\$status) alias nawk awk

# defaults
set mtzfile  = \$mergefile
set tempfile = mtz2various_temp

# output F, phase, etc. (automatic by default)
set hiRES    = ""
set F        = Fin
set SIGF     = SIGFin
set DANO     = ""
set SIGD     = ""
set PHI      = PHIDM
set FOM      = FOMDM
set FREE     = FreeR_flag

# output files
set outfile   = outfile.cif
# supported: xplor cns tnt cif shelx fin phs
set format    = "CIF"

if("\\\$1" == "") goto Help
goto Setup
#  Procedure (at bottom) to read command-line args
#  mtz, Fs, or resolution
Help:
cat << EOF

usage: \\\$0 mtzfile.mtz [F] [PHI] outfile.fmt

where:
mtzfile.mtz  - an mtz file you want to convert
[F] [PHI]    - are the dataset names in mtzfile.mtz you want to extract
outfile.fmt  - is the output file name
fmt          - implies format:
		cif -> CIF
		hkl -> shelx
		tnt -> TNT
		fin -> XtalView
		phs -> XtalView
		fobs-> XPLOR
		cv  -> XPLOR
		cns -> CNS

EOF
exit 9
ReturnFromSetup:

# construct a LABIN card for the dump
set label = ""
if("\\\$F" != "")    set label = "\\\$label FP=\\\$F"
if("\\\$SIGF" != "") set label = "\\\$label SIGFP=\\\$SIGF"
if("\\\$DANO" != "") set label = "\\\$label DP=\\\$DANO"
if("\\\$SIGD" != "") set label = "\\\$label SIGDP=\\\$SIGD"
if("\\\$PHI" != "")  set label = "\\\$label PHIB=\\\$PHI"
if("\\\$FOM" != "")  set label = "\\\$label FOM=\\\$FOM"
if("\\\$FREE" != "") set label = "\\\$label FREE=\\\$FREE"

################################################################################
# extract columns of interest
mtz2various HKLIN \\\$mtzfile HKLOUT \\\${tempfile}.hkl << EOF-dump 
#>> /dev/null
RESOLUTION 1000 \\\$hiRES
OUTPUT \\\$format
LABIN \\\$label
END
EOF-dump
if(\\\$status) exit

if("\\\$format" == "TNT") then
    if("\\\$FREE" != "") then
	# extract FREE-R set
	cat \\\${tempfile}.hkl |\\\\
	nawk '\\\$NF=="FREE"{print substr(\\\$0,1,index(\\\$0,"FREE")-1)}' |\\\\
	sort -k2n,3 -k3n,4 -k4n,5 |\\\\
	cat >! \\\${outfile}.free
    endif
    # make sure the output is properly sorted
    cat \\\${tempfile}.hkl |\\\\
    nawk '\\\$NF!="FREE"{print}' |\\\\
    sort -k2n,3 -k3n,4 -k4n,5 |\\\\
    cat >! \\\${outfile}

    echo "TNT version of \\\$F \\\$SIGF \\\$PHI \\\$FOM in \\\$mtzfile is now in:"
    echo "\\\$outfile"
    echo "\\\${outfile}.free contains the Free-R flagged HKLs"
    rm -f \\\${tempfile}.hkl >& /dev/null
    exit
endif

# check for supported/unsupported output
if("\\\$format" != 'USER *') then
    # use whatever mtz2various did
    mv \\\${tempfile}.hkl \\\$outfile

    echo "\\\$format version of \\\$F \\\$SIGF \\\$DANO \\\$SIGD \\\$PHI \\\$FOM from \\\$mtzfile is at:"
    echo "\\\$outfile"
    exit
endif

# must have been an unsupported format (fin, phs)
if(("\\\$ext" == "fin")||("\\\$ext" == "phs")) then
    echo "name" >! \\\${outfile}.CRYSTAL
    echo "cell \\\$CELL" >> \\\${outfile}.CRYSTAL
    cat \\\${CLIBD}/symop.lib |\\\\
    nawk -v SG=\\\$SG '\\\$4==SG{print "spgr", tolower(\\\$4), \\\$1, \\\$2, \\\$3, tolower(\\\$6);\\\\
	getline; getline; printf "symm x,y,z"; \\\\
	while(NF==1){printf "; %s", tolower(\\\$1); getline};\\\\
	print "."; exit}' |\\\\
    cat >> \\\${outfile}.CRYSTAL
endif

if("\\\$ext" == "phs") then
    # XtalView phs file
    # should have been output as H K L F PHI FOM
    cat \\\${tempfile}.hkl |\\\\
    nawk '{printf "%4d %4d %4d %12.4f %7.4f %7.2f\\\\n", \\\$1, \\\$2, \\\$3, \\\$4, \\\$6, \\\$5}' |\\\\
    cat >! \\\$outfile

    echo "XtalView version of \\\$F \\\$PHI \\\$FOM from \\\$mtzfile is at:"
    echo "\\\$outfile"
    echo "\\\${outfile}.CRYSTAL"
    rm -f \\\${tempfile}.hkl >& /dev/null
    exit
endif


if("\\\$ext" == "fin") then
    # XtalView fin file
    # should have been output as H K L F SIGF D SIGD
    cat \\\${tempfile}.hkl |\\\\
    nawk 'NF>=7{F1=\\\$4+(\\\$6/2); F2=\\\$4-(\\\$6/2); SIG1=SIG2=\\\$5*1.4142;}\\\\
	  NF<7 || \\\$NF+0==0{F1=\\\$4; SIG1=\\\$5; F2=0; SIG2=9999}\\\\
	  NF>3{printf "%4d %4d %4d %12.4f %12.4f %12.4f %12.4f\\\\n", \\\$1, \\\$2, \\\$3, F1, SIG1, F2, SIG2}' |\\\\
    cat >! \\\$outfile

    echo "XtalView version of \\\$F \\\$SIGF \\\$DANO \\\$SIGD from \\\$mtzfile is at:"
    echo "\\\$outfile"
    echo "\\\${outfile}.CRYSTAL"
    rm -f \\\${tempfile}.hkl >& /dev/null
    exit
endif


####################################################################
exit
####################################################################



Setup:
# scan the command line for files
foreach arg ( \\\$* )
    if( "\\\$arg" =~ *.mtz ) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set mtzfile  = "\\\$arg"
	continue
    endif
    if("\\\$arg" =~ *.cif) then
        set outfile  = "\\\$arg"
        set format   = "CIF data_\\\$arg"
        continue
    endif
    if("\\\$arg" =~ *.hkl) then
	set outfile  = "\\\$arg"
	set format   = "SHELX"
	continue
    endif
    if("\\\$arg" =~ *.tnt) then
        set outfile  = "\\\$arg"
        set format   = "TNT"
        continue
    endif
    if("\\\$arg" =~ *.cns) then
        set outfile  = "\\\$arg"
        set format   = "CNS"
        continue
    endif
    if(("\\\$arg" =~ *.fobs)||("\\\$arg" =~ *.cv)) then
	set outfile  = "\\\$arg"
	set format   = "XPLOR"
	continue
    endif
    if("\\\$arg" =~ *.fin) then
        set outfile  = "\\\$arg"
        set format   = 'FIN'
        continue
    endif
    if("\\\$arg" =~ *.phs) then
        set outfile  = "\\\$arg"
        set format   = 'PHS'
        continue
    endif
    if( "\\\$arg" =~ [0-9]* ) then
	set temp = \\\`echo "\\\$arg" | nawk '\\\$1+0>0.1{print \\\$1+0}'\\\`
	if("\\\$temp" != "") set hiRES = "\\\$temp"
    endif
end

#get variables from mtz file
echo "go" | mtzdump hklin \\\$mtzfile | tee \\\${tempfile}mtzhead |\\\\
nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\\\
nawk 'NF>10 && \\\$(NF-1) ~ /[FQPWADI]/' |\\\\
cat >! \\\${tempfile}mtzdmp

# set misc header values
set CELL = \\\`nawk '/Cell Dimensions/{getline; getline; print}' \\\${tempfile}mtzhead\\\`
set SG   = \\\`nawk '/Space group/{gsub("\\\\047","");print \\\$5}' \\\${tempfile}mtzhead\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzhead \\\`
set SG = \\\` nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile}mtzhead \\\`
set SG = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set mtzRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\${tempfile}mtzhead\\\`
rm -f \\\${tempfile}mtzhead >& /dev/null

# use completeness, or F/sigF to pick default F
cat \\\${tempfile}mtzdmp |\\\\
nawk '\\\$(NF-1) == "F"{F=\\\$NF; meanF=\\\$8; reso=\\\$(NF-2); comp=substr(\\\$0,32)+0; \\\\
      getline; S=\\\$NF; if(\\\$8) meanF /= \\\$8; print F, S, reso, comp, meanF;}' |\\\\
sort -k3n,4 -k4nr,5 -k5nr >! \\\${tempfile}F

# same for D/sigD for anomalous diffs
cat \\\${tempfile}mtzdmp |\\\\
nawk '\\\$(NF-1) == "D"{D=\\\$NF; meanD=\\\$8; reso=\\\$(NF-2); comp=substr(\\\$0,32)+0; \\\\
      getline; S=\\\$NF; if(\\\$8) meanD /= \\\$8; print D, S, reso, comp, meanD;}' |\\\\
sort -k3n,4 -k4nr,5 -k5nr >! \\\${tempfile}D


# and extract all dataset types/labels
cat \\\${tempfile}mtzdmp |\\\\
nawk 'NF>2{print \\\$(NF-1), \\\$NF, " "}' |\\\\
cat >! \\\${tempfile}cards

#clean up
rm -f \\\${tempfile}mtzdmp

# pick F with best resolution, or /
set F    = \\\`head -1 \\\${tempfile}F\\\`
if(\\\$#F > 2) then
    set SIGF = \\\$F[2]
    set F    = \\\$F[1]
endif

# see if default phase is available in this file
grep "P \\\$PHI" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # pick most recently-added phase
    set temp = \\\`nawk '/^P/{print \\\$2}' \\\${tempfile}cards  | tail -1\\\`
    if("\\\$temp" != "") set PHI = "\\\$temp"
endif
# see if default FOM is available in this file
grep "W \\\$FOM" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # pick most recently-added FOM
    set temp = \\\`nawk '/^W/{print \\\$2}' \\\${tempfile}cards | tail -1\\\`
    if("\\\$temp" != "") then
	set FOM = "\\\$temp"
    else
	# there are no FOMs in this mtz file
	set FOM = ""
    endif
endif

# see if user specified an F, Phase, or FOM
set last = "F"
foreach arg ( \\\$* )
    set temp = \\\`grep " \\\$arg " \\\${tempfile}cards\\\`
    if("\\\$temp" =~ F*) then
	set F = "\\\${arg}"
	set last = "F"
	# assign most likely sigma too
	set temp = \\\`nawk -v arg="\\\$arg" '\\\$1==arg{print \\\$2}' \\\${tempfile}F\\\`
	if(\\\$#temp == 1) set SIGF = "\\\$temp"
	continue
    endif
    if("\\\$temp" =~ D*) then
        set DANO = "\\\${arg}"
	set last = "D"
        # assign most likely sigma too
        set temp = \\\`nawk -v arg="\\\$arg" '\\\$1==arg{print \\\$2}' \\\${tempfile}D\\\`
        if(\\\$#temp == 1) set SIGD = "\\\$temp"
        continue
    endif
    if("\\\$temp" =~ Q*) then
	if("\\\$last" == "F") set SIGF = "\\\${arg}"
	if("\\\$last" == "D") set SIGD = "\\\${arg}"
    endif
    if("\\\$temp" =~ P*) set PHI  = "\\\${arg}"
    if("\\\$temp" =~ W*) set FOM  = "\\\${arg}"


    # detect particular out-of-context format specifiers
    set arg = \\\`echo "\\\$arg" | nawk '{print tolower(\\\$1)}'\\\`
    if("\\\$arg" == "shelx") set format = SHELX
    if("\\\$arg" == "tnt")   set format = TNT
    if("\\\$arg" == "cif")   set format = CIF
    if("\\\$arg" == "xplor") set format = XPLOR
    if("\\\$arg" == "cns")   set format = CNS
    if("\\\$arg" == "xtalview") then
        if("\\\$PHI" == "") then
            set format = "FIN"
        else
            set format = "PHS"
        endif
    endif
end

# check for DANO, if we might need one
if(("\\\$format" == "FIN")&&("\\\$DANO" == "")) then
    # grab pattern from name
    set temp = \\\`echo \\\$F | nawk '{print substr(\\\$1,2)}'\\\`
    set DANO = \\\`nawk -v patt=\\\$temp '\\\$1~ patt"\\\$" {print \\\$1; exit}' \\\${tempfile}D\\\`
    # get likely sigma too
    set SIGD = \\\`nawk -v arg="\\\$DANO" '\\\$1==arg{print \\\$2}' \\\${tempfile}D\\\`
endif

# now check and see if the sigma is really there
grep "Q \\\$SIGF" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no sigma availale
    set SIGF = ""
endif
grep "Q \\\$SIGD" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no sigma availale 
    set SIGD = ""
endif
grep "P \\\$PHI" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no phase availale
    set PHI = ""
endif
grep "W \\\$FOM" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no weight availale
    set FOM = ""
endif
grep " \\\$FREE" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no weight availale
    set FREE = ""
endif


rm -f \\\${tempfile}cards \\\${tempfile}F \\\${tempfile}D >& /dev/null

# set resolution (if none previously given)
if("\\\$hiRES" == "") set hiRES = "\\\$mtzRES"

# store filename extension/format
set ext = \\\`echo \\\$outfile | nawk 'BEGIN{FS="."} {print \\\$NF}'\\\`
if("\\\$format" == "CIF") then
    # needs an extra word
    set format = "CIF data_dump"
endif
if("\\\$format" == "FIN") then
    # not supported by mtz2various
    set format = 'USER *'
    set ext = fin
    set PHI = ""
    set FOM = ""
    set FREE = ""
endif
if("\\\$format" == "PHS") then
    # not supported by mtz2various
    set format = 'USER *'
    set ext = phs
    set SIGF = ""
    set DANO = ""
    set SIGD = ""
    set FREE = ""
endif

goto ReturnFromSetup

####################
# future:
better handling of shelx
multiple datasets/mtzs?

EOF-mtz2various
chmod a+x mtz2various.com










goto Return_Unwrap_Scale_Scripts





DumpSymopLib:
###########################################################################

  ####    #   #  #    #   ####   #####           #          #    #####
 #         # #   ##  ##  #    #  #    #          #          #    #    #
  ####      #    # ## #  #    #  #    #          #          #    #####
      #     #    #    #  #    #  #####    ###    #          #    #    #
 #    #     #    #    #  #    #  #        ###    #          #    #    #
  ####      #    #    #   ####   #        ###    ######     #    #####

###########################################################################
#
#   a copy of the CCP4 symop library (so mosflm can barely function)
#
###########################################################################
cat << EOF-symoplib >! \${CLIBD}/symop.lib
1 1 1 P1 PG1 TRICLINIC
 X,Y,Z
2 2 2 P-1 PG1bar TRICLINIC
 X,Y,Z
 -X,-Y,-Z
3 2 2 P2 PG2 MONOCLINIC
 X,Y,Z
 -X,Y,-Z
1003 2 2 P2 PG2 MONOCLINIC (dyad along z)
 X,Y,Z
 -X,-Y,Z
4 2 2 P21 PG2 MONOCLINIC
 X,Y,Z
 -X,Y+1/2,-Z
3004 2 1 I21 PG2
 X,Y,Z * -X,1/2+Y,-Z
 X+1/2,Y+1/2,Z+1/2 * -X+1/2,Y,1/2-Z
1004 1 1 P1121 PG2
 X,Y,Z * -X,-Y,1/2+Z
2005 2 1 A2 PG2 ! (Origin on screw along b)
 X, Y, Z *  -X,1/2+Y,-Z
 X,1/2+Y,1/2+Z * -X, Y,1/2-Z
5 4 2 C2 PG2 MONOCLINIC
 X,Y,Z 
 -X,Y,-Z 
 1/2+X,1/2+Y,Z 
 1/2-X,1/2+Y,-Z
1005 2 1 C21 PG2 ! (Origin on screw at 1/4X)
 X, Y, Z * -X,1/2+Y,-Z
 1/2+X,1/2+Y,Z *  1/2-X, Y,-Z
6 2 2 Pm PGm MONOCLINIC
 X,Y,Z 
 X,-Y,Z
7 2 2 Pc PGm MONOCLINIC
 X,Y,Z
 X,-Y,1/2+Z
8 4 2 Cm PGm MONOCLINIC
 X,Y,Z
 X,-Y,Z
 1/2+X,1/2+Y,Z
 1/2+X,1/2-Y,Z
9 4 2 Cc PGm MONOCLINIC
 X,Y,Z
 X,-Y,1/2+Z
 1/2+X,1/2+Y,Z
 1/2+X,1/2-Y,1/2+Z
10 4 4 P2/m PG2/m MONOCLINIC
 X,Y,Z
 X,-Y,Z
 -X,Y,-Z
 -X,-Y,-Z
11 4 4 P21/m PG2/m MONOCLINIC
 X,Y,Z
 -X,1/2+Y,-Z
 -X,-Y,-Z
 X,1/2-Y,Z
12 8 4 C2/m PG2/m MONOCLINIC
 X,Y,Z
 X,-Y,Z
 -X,Y,-Z
 -X,-Y,-Z
 1/2+X,1/2+Y,Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2-X,1/2-Y,-Z
13 4 4 P2/c PG2/m MONOCLINIC
 X,Y,Z
 -X,Y,1/2-Z
 -X,-Y,-Z
 X,-Y,1/2+Z
14 4 4 P21/c PG2/m MONOCLINIC
 X,Y,Z
 -X,-Y,-Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,1/2+Z
15 8 4 C2/c PG2/m MONOCLINIC
 X,Y,Z
 -X,Y,1/2-Z
 -X,-Y,-Z
 X,-Y,1/2+Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2+Y,1/2-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2-Y,1/2+Z
16 4 4 P222 PG222 ORTHORHOMBIC
 X,Y,Z 
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
17 4 4 P2221 PG222 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 -X,Y,1/2-Z
 X,-Y,-Z
18 4 4 P21212 PG222 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
1018 1 1 P21212a PG222 ! origin on 21 21 shift (1/4,1/4,0)
 X,Y,Z * 1/2-X,1/2-Y,Z * X+1/2,-Y,-Z * -X,Y+1/2,-Z
19 4 4 P212121 PG222 ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
20 8 4 C2221 PG222 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 -X,Y,1/2-Z
 X,-Y,-Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
1020 2 1 C2221a PG222 !  P212121 with C centring ! shift(1/4,0,0)
 X,Y,Z * 1/2-X,-Y,1/2+Z * 1/2+X,1/2-Y,-Z * -X,1/2+Y,1/2-Z
 1/2+X,1/2+Y,Z * -X,1/2-Y,1/2+Z * X,-Y,-Z * 1/2-X,Y,1/2-Z
21 8 4 C222 PG222 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
1021 2 1 C222a PG222 ! C21212a origin on 21 21
 X,Y,Z * 1/2-X,1/2-Y,Z * X+1/2,-Y,-Z * -X,Y+1/2,-Z
 1/2+ X,1/2+Y,Z * -X,-Y,Z * X,1/2-Y,-Z * 1/2-X,Y,-Z
22 16 4 F222 PG222 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,1/2-Z
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,-Y,1/2-Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
1022 4 1 F222a PG222 ! same as 1018 with face centring ! shift (1/4,0,0)
 X,Y,Z         * 1/2-X,1/2-Y,Z * X+1/2,-Y,-Z * -X,Y+1/2,-Z
 X,Y+1/2,Z+1/2 * 1/2-X,-Y,Z+1/2 * X+1/2,-Y+1/2,-Z+1/2 * -X,Y,-Z+1/2
 X+1/2,Y,Z+1/2 * -X,1/2-Y,Z+1/2 * X,-Y,-Z+1/2 * -X+1/2,Y+1/2,-Z+1/2
 X+1/2,Y+1/2,Z * -X,-Y,Z * X,-Y+1/2,-Z * -X+1/2,Y,-Z
23 8 4 I222 PG222 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,-Z
 -X,Y,-Z
 X+1/2,Y+1/2,Z+1/2
 -X+1/2,-Y+1/2,Z+1/2
 X+1/2,-Y+1/2,-Z+1/2
 -X+1/2,Y+1/2,-Z+1/2
1023 3 1 I222a PG222 ! same as 1018 with origin shift (1/4,1/4,1/4)
 X,Y,Z * 1/2-X,1/2-Y,Z * X+1/2,-Y,-Z * -X,Y+1/2,-Z
 1/2+X,1/2+Y,1/2+Z *  -X,-Y,1/2+Z
 1/2-X,Y,1/2-Z *  X,1/2-Y,1/2-Z
24 8 4 I212121 PG222 ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
 1/2+X,1/2+Y,1/2+Z
 -X,1/2-Y,Z
 1/2-X,Y,-Z
 X,-Y,1/2-Z
25 4 4 Pmm2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,Z
 -X,Y,Z
26 4 4 Pmc21 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 X,-Y,1/2+Z
 -X,Y,Z
27 4 4 Pcc2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
28 4 4 Pma2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2+X,-Y,Z
 1/2-X,Y,Z
29 4 4 Pca21 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 1/2+X,-Y,Z
 1/2-X,Y,1/2+Z
30 4 4 Pnc2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
31 4 4 Pmn21 PGmm2 ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 1/2+X,-Y,1/2+Z
 -X,Y,Z
32 4 4 Pba2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
33 4 4 Pna21 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,1/2+Z
34 4 4 Pnn2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
35 8 4 Cmm2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,Z
 -X,Y,Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
36 8 4 Cmc21 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 X,-Y,1/2+Z
 -X,Y,Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,1/2+Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,Z
37 8 4 Ccc2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
38 8 4 Amm2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,Z
 -X,Y,Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
39 8 4 Abm2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,1/2-Y,Z
 -X,1/2+Y,Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
40 8 4 Ama2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2+X,-Y,Z
 1/2-X,Y,Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
41 8 4 Aba2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 1/2+X,-Y,1/2+Z
 1/2-X,Y,1/2+Z
42 16 4 Fmm2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,Z
 -X,Y,Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2+X,-Y,1/2+Z
 1/2-X,Y,1/2+Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
43 16 4 Fdd2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/4+X,1/4-Y,1/4+Z
 1/4-X,1/4+Y,1/4+Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 1/4+X,3/4-Y,3/4+Z
 1/4-X,3/4+Y,3/4+Z
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 3/4+X,1/4-Y,3/4+Z
 3/4-X,1/4+Y,3/4+Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 3/4+X,3/4-Y,1/4+Z
 3/4-X,3/4+Y,1/4+Z
44 8 4 Imm2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 X,-Y,Z
 -X,Y,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
45 8 4 Iba2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
46 8 4 Ima2 PGmm2 ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2+X,-Y,Z
 1/2-X,Y,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
47 8 8 Pmmm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
48 8 8 Pnnn PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
49 8 8 Pccm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
50 8 8 Pban PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
51 8 8 Pmma PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,Z
 -X,Y,-Z
 1/2+X,-Y,-Z
 -X,-Y,-Z
 1/2+X,Y,-Z
 X,-Y,Z
 1/2-X,Y,Z
52 8 8 Pnna PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,Z
 1/2-X,1/2+Y,1/2-Z
 X,1/2-Y,1/2-Z
 -X,-Y,-Z
 1/2+X,Y,-Z
 1/2+X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
53 8 8 Pmna PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 X,-Y,-Z
 -X,-Y,-Z
 1/2+X,Y,1/2-Z
 1/2+X,-Y,1/2+Z
 -X,Y,Z
54 8 8 Pcca PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,Z
 -X,Y,1/2-Z
 1/2+X,-Y,1/2-Z
 -X,-Y,-Z
 1/2+X,Y,-Z
 X,-Y,1/2+Z
 1/2-X,Y,1/2+Z
55 8 8 Pbam PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 -X,-Y,-Z
 X,Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
56 8 8 Pccn PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,1/2-Y,Z
 -X,1/2+Y,1/2-Z
 1/2+X,-Y,1/2-Z
 -X,-Y,-Z
 1/2+X,1/2+Y,-Z
 X,1/2-Y,1/2+Z
 1/2-X,Y,1/2+Z
57 8 8 Pbcm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,-Z
 -X,-Y,-Z
 X,Y,1/2-Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,Z
58 8 8 Pnnm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
59 8 8 Pmmn PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2-X,Y+1/2,-Z
 X+1/2,1/2-Y,-Z
 1/2-X,1/2-Y,-Z
 X+1/2,Y+1/2,-Z
 X,-Y,Z
 -X,Y,Z
1059 8 8 Pmmn2 PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,1/2-Y,Z
 -X,1/2+Y,-Z
 1/2+X,-Y,-Z
 -X,-Y,-Z
 X+1/2,Y+1/2,-Z
 X,1/2-Y,Z
 1/2-X,Y,Z
60 8 8 Pbcn PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -X,Y,1/2-Z
 1/2+X,1/2-Y,-Z
 -X,-Y,-Z
 1/2+X,1/2+Y,1/2-Z
 X,-Y,1/2+Z
 1/2-X,1/2+Y,Z
61 8 8 Pbca PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
 -X,-Y,-Z
 1/2+X,Y,1/2-Z
 X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,Z
62 8 8 Pnma PGmmm ORTHORHOMBIC
 X,Y,Z
 -X+1/2,-Y,Z+1/2
 -X,Y+1/2,-Z
 X+1/2,-Y+1/2,-Z+1/2
 -X,-Y,-Z
 X+1/2,Y,-Z+1/2
 X,-Y+1/2,Z
 -X+1/2,Y+1/2,Z+1/2
63 16 8 Cmcm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,1/2+Z
 -X,Y,1/2-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,Y,1/2-Z
 X,-Y,1/2+Z
 -X,Y,Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,Z
64 16 8 Cmca PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,1/2+Y,1/2-Z
 X,1/2-Y,1/2+Z
 -X,Y,Z
 1/2+X,1/2+Y,Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,1/2-Y,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,Y,1/2-Z
 1/2+X,-Y,1/2+Z
 1/2-X,1/2+Y,Z
65 16 8 Cmmm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
66 16 8 Cccm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
67 16 8 Cmma PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,1/2-Y,Z
 -X,1/2+Y,-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,1/2+Y,-Z
 X,1/2-Y,Z
 -X,Y,Z
 1/2+X,1/2+Y,Z
 1/2-X,-Y,Z
 1/2-X,Y,-Z
 1/2+X,1/2-Y,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,Y,-Z
 1/2+X,-Y,Z
 1/2-X,1/2+Y,Z
68 16 8 Ccca PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,1/2-Y,Z
 -X,Y,-Z
 1/2+X,1/2-Y,-Z
 -X,1/2-Y,1/2-Z
 1/2+X,Y,1/2-Z
 X,1/2-Y,1/2+Z
 1/2-X,Y,1/2+Z
 1/2+X,1/2+Y,Z
 -X,-Y,Z
 1/2-X,1/2+Y,-Z
 X,-Y,-Z
 1/2-X,-Y,1/2-Z
 X,1/2+Y,1/2-Z
 1/2+X,-Y,1/2+Z
 -X,1/2+Y,1/2+Z
69 32 8 Fmmm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,1/2-Z
 -X,1/2-Y,1/2-Z
 X,1/2+Y,1/2-Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,-Y,1/2-Z
 1/2-X,-Y,1/2-Z
 1/2+X,Y,1/2-Z
 1/2+X,-Y,1/2+Z
 1/2-X,Y,1/2+Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
70 32 8 Fddd PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 1/4-X,1/4-Y,1/4-Z
 1/4+X,1/4+Y,1/4-Z
 1/4+X,1/4-Y,1/4+Z
 1/4-X,1/4+Y,1/4+Z
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,1/2-Z
 1/4-X,3/4-Y,3/4-Z
 1/4+X,3/4+Y,3/4-Z
 1/4+X,3/4-Y,3/4+Z
 1/4-X,3/4+Y,3/4+Z
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,-Y,1/2-Z
 3/4-X,1/4-Y,3/4-Z
 3/4+X,1/4+Y,3/4-Z
 3/4+X,1/4-Y,3/4+Z
 3/4-X,1/4+Y,3/4+Z
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 3/4-X,3/4-Y,1/4-Z
 3/4+X,3/4+Y,1/4-Z
 3/4+X,3/4-Y,1/4+Z
 3/4-X,3/4+Y,1/4+Z
71 16 8 Immm PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
72 16 8 Ibam PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 -X,-Y,-Z
 X,Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
73 16 8 Ibca PGmmm ORTHORHOMBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
 -X,-Y,-Z
 1/2+X,Y,1/2-Z
 X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,Z
 1/2+X,1/2+Y,1/2+Z
 -X,1/2-Y,Z
 1/2-X,Y,-Z
 X,-Y,1/2-Z
 1/2-X,1/2-Y,1/2-Z
 X,1/2+Y,-Z
 1/2+X,-Y,Z
 -X,Y,1/2+Z
74 16 8 Imma PGmmm ORTHORHOMBIC
 X,Y,Z
 -X,1/2-Y,Z
 -X,1/2+Y,-Z
 X,-Y,-Z
 -X,-Y,-Z
 X,1/2+Y,-Z
 X,1/2-Y,Z
 -X,Y,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,Y,1/2-Z
 1/2+X,-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
75 4 4 P4 PG4 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
76 4 4 P41 PG4 TETRAGONAL
 X,Y,Z
 -X,-Y,1/2+Z
 -Y,X,1/4+Z
 Y,-X,3/4+Z
77 4 4 P42 PG4 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
78 4 4 P43 PG4 TETRAGONAL
 X,Y,Z 
 -X,-Y,1/2+Z
 -Y,X,3/4+Z
 Y,-X,1/4+Z
79 8 4 I4 PG4 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
80 8 4 I41 PG4 TETRAGONAL
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -Y,1/2+X,1/4+Z
 1/2+Y,-X,3/4+Z
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-Y,X,3/4+Z
 Y,1/2-X,1/4+Z
81 4 4 P-4 PG4bar TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 Y,-X,-Z
 -Y,X,-Z
82 8 4 I-4 PG4bar TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 Y,-X,-Z
 -Y,X,-Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
83 8 8 P4/m PG4/m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
84 8 8 P42/m PG4/m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,1/2-Z
 -Y,X,1/2-Z
85 8 8 P4/n PG4/m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,Z
 1/2+Y,1/2-X,Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 Y,-X,-Z
 -Y,X,-Z
86 8 8 P42/n PG4/m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 Y,-X,-Z
 -Y,X,-Z
87 16 8 I4/m PG4/m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
88 16 8 I41/a PG4/m TETRAGONAL
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -Y,1/2+X,1/4+Z
 1/2+Y,-X,3/4+Z
 -X,1/2-Y,1/4-Z
 1/2+X,Y,3/4-Z
 Y,-X,-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-Y,X,3/4+Z
 Y,1/2-X,1/4+Z
 1/2-X,-Y,3/4-Z
 X,1/2+Y,1/4-Z
 1/2+Y,1/2-X,1/2-Z
 -Y,X,-Z
89 8 8 P422 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
90 8 8 P4212 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,Z
 1/2+Y,1/2-X,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
91 8 8 P4122 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,1/2+Z
 -Y,X,1/4+Z
 Y,-X,3/4+Z
 -X,Y,-Z
 X,-Y,1/2-Z
 Y,X,3/4-Z
 -Y,-X,1/4-Z
92 8 8 P41212 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,1/2+Z
 1/2-Y,1/2+X,1/4+Z
 1/2+Y,1/2-X,3/4+Z
 1/2-X,1/2+Y,1/4-Z
 1/2+X,1/2-Y,3/4-Z
 Y,X,-Z
 -Y,-X,1/2-Z
93 8 8 P4222 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
94 8 8 P42212 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 Y,X,-Z
 -Y,-X,-Z
1094 4 4 P42212a PG422 ! (as P21212a) origin on 21 21 ie Shift 1/4,1/4,1/4
 X,Y,Z                 *      1/2-X,1/2-Y,Z
 -Y,X+1/2,1/2+Z        *      Y+1/2,-X,1/2+Z
 -X,Y+1/2,-Z           *      X+1/2,-Y,-Z
 Y,X,1/2-Z             *  1/2-Y,1/2-X,1/2-Z
95 8 8 P4322 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,1/2+Z
 -Y,X,3/4+Z
 Y,-X,1/4+Z
 -X,Y,-Z
 X,-Y,1/2-Z
 Y,X,1/4-Z
 -Y,-X,3/4-Z
96 8 8 P43212 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,1/2+Z
 1/2-Y,1/2+X,3/4+Z
 1/2+Y,1/2-X,1/4+Z
 1/2-X,1/2+Y,3/4-Z
 1/2+X,1/2-Y,1/4-Z
 Y,X,-Z
 -Y,-X,1/2-Z
97 16 8 I422 PG422 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
98 16 8 I4122 PG422 TETRAGONAL
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -Y,1/2+X,1/4+Z
 1/2+Y,-X,3/4+Z
 1/2-X,Y,3/4-Z
 X,1/2-Y,1/4-Z
 1/2+Y,1/2+X,1/2-Z
 -Y,-X,-Z
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-Y,X,3/4+Z
 Y,1/2-X,1/4+Z
 -X,1/2+Y,1/4-Z
 1/2+X,-Y,3/4-Z
 Y,X,-Z
 1/2-Y,1/2-X,1/2-Z
99 8 8 P4mm PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 X,-Y,Z
 -X,Y,Z
 -Y,-X,Z
 Y,X,Z
100 8 8 P4bm PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
101 8 8 P42cm PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 -Y,-X,Z
 Y,X,Z
102 8 8 P42nm PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 -Y,-X,Z
 Y,X,Z
103 8 8 P4cc PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
104 8 8 P4nc PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
105 8 8 P42mc PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 X,-Y,Z
 -X,Y,Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
106 8 8 P42bc PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
107 16 8 I4mm PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 X,-Y,Z
 -X,Y,Z
 -Y,-X,Z
 Y,X,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
108 16 8 I4cm PG4mm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
109 16 8 I41md PG4mm TETRAGONAL
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -Y,1/2+X,1/4+Z
 1/2+Y,-X,3/4+Z
 X,-Y,Z
 1/2-X,1/2+Y,1/2+Z
 -Y,1/2-X,1/4+Z
 1/2+Y,X,3/4+Z
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-Y,X,3/4+Z
 Y,1/2-X,1/4+Z
 1/2+X,1/2-Y,1/2+Z
 -X,Y,Z
 1/2-Y,-X,3/4+Z
 Y,1/2+X,1/4+Z
110 16 8 I41cd PG4mm TETRAGONAL
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -Y,1/2+X,1/4+Z
 1/2+Y,-X,3/4+Z
 X,-Y,1/2+Z
 1/2-X,1/2+Y,Z
 -Y,1/2-X,3/4+Z
 1/2+Y,X,1/4+Z
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-Y,X,3/4+Z
 Y,1/2-X,1/4+Z
 1/2+X,1/2-Y,Z
 -X,Y,1/2+Z
 1/2-Y,-X,1/4+Z
 Y,1/2+X,3/4+Z
111 8 8 P-42m PG4bar2m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 -X,Y,-Z
 X,-Y,-Z
 -Y,-X,Z
 Y,X,Z
112 8 8 P-42c PG4bar2m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
113 8 8 P-421m PG4bar2m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
114 8 8 P-421c PG4bar2m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
115 8 8 P-4m2 PG4barm2 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,Z
 -X,Y,Z
 Y,X,-Z
 -Y,-X,-Z
116 8 8 P-4c2 PG4barm2 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
117 8 8 P-4b2 PG4barm2 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2+Y,1/2+X,-Z
 1/2-Y,1/2-X,-Z
118 8 8 P-4n2 PG4barm2 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
119 16 8 I-4m2 PG4barm2 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 X,-Y,Z
 -X,Y,Z
 Y,X,-Z
 -Y,-X,-Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
120 16 8 I-4c2 PG4barm2 TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2+Y,1/2+X,-Z
 1/2-Y,1/2-X,-Z
121 16 8 I-42m PG4bar2m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 -X,Y,-Z
 X,-Y,-Z
 -Y,-X,Z
 Y,X,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
122 16 8 I-42d PG4bar2m TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,-Z
 Y,-X,-Z
 1/2-X,Y,3/4-Z
 1/2+X,-Y,3/4-Z
 1/2-Y,-X,3/4+Z
 1/2+Y,X,3/4+Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 -X,1/2+Y,1/4-Z
 X,1/2-Y,1/4-Z
 -Y,1/2-X,1/4+Z
 Y,1/2+X,1/4+Z
123 16 16 P4/mmm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,Z
 -X,Y,Z
 -Y,-X,Z
 Y,X,Z
124 16 16 P4/mcc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
125 16 16 P4/nbm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+Y,1/2-X,-Z
 1/2-Y,1/2+X,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
126 16 16 P4/nnc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
127 16 16 P4/mbm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2+Y,1/2+X,-Z
 1/2-Y,1/2-X,-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
128 16 16 P4/mnc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
129 16 16 P4/nmm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,Z
 1/2+Y,1/2-X,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,Z
 -X,Y,Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
130 16 16 P4/ncc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,Z
 1/2+Y,1/2-X,Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
131 16 16 P42/mmc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,1/2-Z
 -Y,X,1/2-Z
 X,-Y,Z
 -X,Y,Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
132 16 16 P42/mcm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 Y,X,-Z
 -Y,-X,-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,1/2-Z
 -Y,X,1/2-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 -Y,-X,Z
 Y,X,Z
133 16 16 P42/nbc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 1/2+Y,1/2+X,-Z
 1/2-Y,1/2-X,-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 Y,-X,-Z
 -Y,X,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
134 16 16 P42/nnm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 -X,Y,-Z
 X,-Y,-Z
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 Y,-X,-Z
 -Y,X,-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 -Y,-X,Z
 Y,X,Z
135 16 16 P42/mbc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,1/2+Z
 Y,-X,1/2+Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,1/2-Z
 -Y,X,1/2-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
136 16 16 P42/mnm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,X+1/2,Z+1/2
 Y+1/2,1/2-X,Z+1/2
 1/2-X,Y+1/2,1/2-Z
 X+1/2,1/2-Y,1/2-Z
 Y,X,-Z
 -Y,-X,-Z
 -X,-Y,-Z
 X,Y,-Z
 Y+1/2,1/2-X,1/2-Z
 1/2-Y,X+1/2,1/2-Z
 X+1/2,1/2-Y,Z+1/2
 1/2-X,Y+1/2,Z+1/2
 -Y,-X,Z
 Y,X,Z
137 16 16 P42/nmc PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 Y,X,-Z
 -Y,-X,-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,Z
 -X,Y,Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
138 16 16 P42/ncm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
139 32 16 I4/mmm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,-Z
 X,-Y,-Z
 Y,X,-Z
 -Y,-X,-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,Z
 -X,Y,Z
 -Y,-X,Z
 Y,X,Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
140 32 16 I4/mcm PG4/mmm TETRAGONAL
 X,Y,Z
 -X,-Y,Z
 -Y,X,Z
 Y,-X,Z
 -X,Y,1/2-Z
 X,-Y,1/2-Z
 Y,X,1/2-Z
 -Y,-X,1/2-Z
 -X,-Y,-Z
 X,Y,-Z
 Y,-X,-Z
 -Y,X,-Z
 X,-Y,1/2+Z
 -X,Y,1/2+Z
 -Y,-X,1/2+Z
 Y,X,1/2+Z
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+Y,1/2-X,1/2+Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2+Y,1/2+X,-Z
 1/2-Y,1/2-X,-Z
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
141 32 16 I41/amd PG4/mmm TETRAGONAL
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -Y,1/2+X,1/4+Z
 1/2+Y,-X,3/4+Z
 1/2-X,Y,3/4-Z
 X,1/2-Y,1/4-Z
 1/2+Y,1/2+X,1/2-Z
 -Y,-X,-Z
 -X,1/2-Y,1/4-Z
 1/2+X,Y,3/4-Z
 Y,-X,-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 -X,Y,Z
 1/2-Y,-X,3/4+Z
 Y,1/2+X,1/4+Z
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-Y,X,3/4+Z
 Y,1/2-X,1/4+Z
 -X,1/2+Y,1/4-Z
 1/2+X,-Y,3/4-Z
 Y,X,-Z
 1/2-Y,1/2-X,1/2-Z
 1/2-X,-Y,3/4-Z
 X,1/2+Y,1/4-Z
 1/2+Y,1/2-X,1/2-Z
 -Y,X,-Z
 X,-Y,Z
 1/2-X,1/2+Y,1/2+Z
 -Y,1/2-X,1/4+Z
 1/2+Y,X,3/4+Z
142 32 16 I41/acd PG4/mmm TETRAGONAL
 X,Y,Z
 1/2-X,1/2-Y,1/2+Z
 -Y,1/2+X,1/4+Z
 1/2+Y,-X,3/4+Z
 1/2-X,Y,1/4-Z
 X,1/2-Y,3/4-Z
 1/2+Y,1/2+X,-Z
 -Y,-X,1/2-Z
 -X,1/2-Y,1/4-Z
 1/2+X,Y,3/4-Z
 Y,-X,-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2-Y,Z
 -X,Y,1/2+Z
 1/2-Y,-X,1/4+Z
 Y,1/2+X,3/4+Z
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-Y,X,3/4+Z
 Y,1/2-X,1/4+Z
 -X,1/2+Y,3/4-Z
 1/2+X,-Y,1/4-Z
 Y,X,1/2-Z
 1/2-Y,1/2-X,-Z
 1/2-X,-Y,3/4-Z
 X,1/2+Y,1/4-Z
 1/2+Y,1/2-X,1/2-Z
 -Y,X,-Z
 X,-Y,1/2+Z
 1/2-X,1/2+Y,Z
 -Y,1/2-X,3/4+Z
 1/2+Y,X,1/4+Z
143 3 3 P3 PG3 TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
144 3 3 P31 PG3 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z+1/3
 Y-X,-X,Z+2/3
145 3 3 P32 PG3 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z+2/3
 Y-X,-X,Z+1/3
146 9 3 R3 PG3 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z
 Y-X,-X,Z
 X+2/3,Y+1/3,Z+1/3
 -Y+2/3,X-Y+1/3,Z+1/3
 Y-X+2/3,-X+1/3,Z+1/3
 X+1/3,Y+2/3,Z+2/3
 -Y+1/3,X-Y+2/3,Z+2/3
 Y-X+1/3,-X+2/3,Z+2/3
147 6 6 P-3 PG3bar TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
148 18 6 R-3 PG3bar TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 2/3+X,1/3+Y,1/3+Z 
 2/3-Y,1/3+X-Y,1/3+Z 
 2/3+Y-X,1/3-X,1/3+Z
 2/3-X,1/3-Y,1/3-Z
 2/3+Y,1/3+Y-X,1/3-Z
 2/3+X-Y,1/3+X,1/3-Z
 1/3+X,2/3+Y,2/3+Z 
 1/3-Y,2/3+X-Y,2/3+Z 
 1/3+Y-X,2/3-X,2/3+Z
 1/3-X,2/3-Y,2/3-Z
 1/3+Y,2/3+Y-X,2/3-Z
 1/3+X-Y,2/3+X,2/3-Z
149 6 6 P312 PG312 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z
 Y-X,-X,Z
 -Y,-X,-Z
 Y-X,Y,-Z
 X,X-Y,-Z
150 6 6 P321 PG321 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z
 Y-X,-X,Z
 Y,X,-Z
 X-Y,-Y,-Z
 -X,Y-X,-Z
151 6 6 P3112 PG312 TRIGONAL
 X,Y,Z
 -Y,X-Y,1/3+Z
 Y-X,-X,2/3+Z
 -Y,-X,2/3-Z
 Y-X,Y,1/3-Z
 X,X-Y,-Z
152 6 6 P3121 PG321 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z+1/3
 Y-X,-X,Z+2/3
 Y,X,-Z
 X-Y,-Y,2/3-Z
 -X,Y-X,1/3-Z
153 6 6 P3212 PG312 TRIGONAL
 X,Y,Z
 -Y,X-Y,2/3+Z
 Y-X,-X,1/3+Z
 -Y,-X,1/3-Z
 Y-X,Y,2/3-Z
 X,X-Y,-Z
154 6 6 P3221 PG321 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z+2/3
 Y-X,-X,Z+1/3
 Y,X,-Z
 X-Y,-Y,1/3-Z
 -X,Y-X,2/3-Z
155 18 6 R32 PG32 TRIGONAL
 X,Y,Z
 -Y,X-Y,Z
 Y-X,-X,Z
 Y,X,-Z
 X-Y,-Y,-Z 
 -X,Y-X,-Z
 2/3+X,1/3+Y,1/3+Z
 2/3-Y,1/3+X-Y,1/3+Z
 2/3+Y-X,1/3-X,1/3+Z
 2/3+Y,1/3+X,1/3-Z
 2/3+X-Y,1/3-Y,1/3-Z 
 2/3-X,1/3+Y-X,1/3-Z
 1/3+X,2/3+Y,2/3+Z
 1/3-Y,2/3+X-Y,2/3+Z
 1/3+Y-X,2/3-X,2/3+Z
 1/3+Y,2/3+X,2/3-Z
 1/3+X-Y,2/3-Y,2/3-Z 
 1/3-X,2/3+Y-X,2/3-Z
156 6 6 P3m1 PG3m1 TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 -Y,-X,Z
 Y-X,Y,Z
 X,X-Y,Z
157 6 6 P31m PG31m TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 Y,X,Z
 X-Y,-Y,Z
 -X,Y-X,Z
158 6 6 P3c1 PG3m1 TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 -Y,-X,1/2+Z
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z
159 6 6 P31c PG31m TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 Y,X,1/2+Z
 X-Y,-Y,1/2+Z
 -X,Y-X,1/2+Z
160 18 6 R3m PG3m TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 -Y,-X,Z
 Y-X,Y,Z
 X,X-Y,Z
 2/3+X,1/3+Y,1/3+Z 
 2/3-Y,1/3+X-Y,1/3+Z 
 2/3+Y-X,1/3-X,1/3+Z
 2/3-Y,1/3-X,1/3+Z
 2/3+Y-X,1/3+Y,1/3+Z
 2/3+X,1/3+X-Y,1/3+Z
 1/3+X,2/3+Y,2/3+Z 
 1/3-Y,2/3+X-Y,2/3+Z 
 1/3+Y-X,2/3-X,2/3+Z
 1/3-Y,2/3-X,2/3+Z
 1/3+Y-X,2/3+Y,2/3+Z
 1/3+X,2/3+X-Y,2/3+Z
161 18 6 R3c PG3m TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 -Y,-X,1/2+Z
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z
 2/3+X,1/3+Y,1/3+Z 
 2/3-Y,1/3+X-Y,1/3+Z 
 2/3+Y-X,1/3-X,1/3+Z
 2/3-Y,1/3-X,5/6+Z
 2/3+Y-X,1/3+Y,5/6+Z
 2/3+X,1/3+X-Y,5/6+Z
 1/3+X,2/3+Y,2/3+Z 
 1/3-Y,2/3+X-Y,2/3+Z 
 1/3+Y-X,2/3-X,2/3+Z
 1/3-Y,2/3-X,1/6+Z
 1/3+Y-X,2/3+Y,1/6+Z
 1/3+X,2/3+X-Y,1/6+Z
162 12 12 P-31m PG3bar1m TRIGONAL
 X,Y,Z
 -Y,X-Y,Z
 Y-X,-X,Z
 -Y,-X,-Z
 Y-X,Y,-Z
 X,X-Y,-Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 Y,X,Z
 X-Y,-Y,Z
 -X,Y-X,Z
163 12 12 P-31c PG3bar1m TRIGONAL
 X,Y,Z
 -Y,X-Y,Z
 Y-X,-X,Z
 -Y,-X,1/2-Z
 Y-X,Y,1/2-Z
 X,X-Y,1/2-Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 Y,X,1/2+Z
 X-Y,-Y,1/2+Z
 -X,Y-X,1/2+Z
164 12 12 P-3m1 PG3barm1 TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 Y,X,-Z
 X-Y,-Y,-Z
 -X,Y-X,-Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 -Y,-X,Z
 Y-X,Y,Z
 X,X-Y,Z
165 12 12 P-3c1 PG3barm1 TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 Y,X,1/2-Z
 X-Y,-Y,1/2-Z
 -X,Y-X,1/2-Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 -Y,-X,1/2+Z
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z
166 36 12 R-3m PG3barm TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 Y,X,-Z
 X-Y,-Y,-Z
 -X,Y-X,-Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 -Y,-X,Z
 Y-X,Y,Z
 X,X-Y,Z
 2/3+X,1/3+Y,1/3+Z 
 2/3-Y,1/3+X-Y,1/3+Z 
 2/3+Y-X,1/3-X,1/3+Z
 2/3+Y,1/3+X,1/3-Z
 2/3+X-Y,1/3-Y,1/3-Z
 2/3-X,1/3+Y-X,1/3-Z
 2/3-X,1/3-Y,1/3-Z
 2/3+Y,1/3+Y-X,1/3-Z
 2/3+X-Y,1/3+X,1/3-Z
 2/3-Y,1/3-X,1/3+Z
 2/3+Y-X,1/3+Y,1/3+Z
 2/3+X,1/3+X-Y,1/3+Z
 1/3+X,2/3+Y,2/3+Z 
 1/3-Y,2/3+X-Y,2/3+Z 
 1/3+Y-X,2/3-X,2/3+Z
 1/3+Y,2/3+X,2/3-Z
 1/3+X-Y,2/3-Y,2/3-Z
 1/3-X,2/3+Y-X,2/3-Z
 1/3-X,2/3-Y,2/3-Z
 1/3+Y,2/3+Y-X,2/3-Z
 1/3+X-Y,2/3+X,2/3-Z
 1/3-Y,2/3-X,2/3+Z
 1/3+Y-X,2/3+Y,2/3+Z
 1/3+X,2/3+X-Y,2/3+Z
167 36 12 R-3c PG3barm TRIGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z
 Y,X,1/2-Z
 X-Y,-Y,1/2-Z
 -X,Y-X,1/2-Z
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 -Y,-X,1/2+Z
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z
 2/3+X,1/3+Y,1/3+Z 
 2/3-Y,1/3+X-Y,1/3+Z 
 2/3+Y-X,1/3-X,1/3+Z
 2/3+Y,1/3+X,5/6-Z
 2/3+X-Y,1/3-Y,5/6-Z
 2/3-X,1/3+Y-X,5/6-Z
 2/3-X,1/3-Y,1/3-Z
 2/3+Y,1/3+Y-X,1/3-Z
 2/3+X-Y,1/3+X,1/3-Z
 2/3-Y,1/3-X,5/6+Z
 2/3+Y-X,1/3+Y,5/6+Z
 2/3+X,1/3+X-Y,5/6+Z
 1/3+X,2/3+Y,2/3+Z 
 1/3-Y,2/3+X-Y,2/3+Z 
 1/3+Y-X,2/3-X,2/3+Z
 1/3+Y,2/3+X,1/6-Z
 1/3+X-Y,2/3-Y,1/6-Z
 1/3-X,2/3+Y-X,1/6-Z
 1/3-X,2/3-Y,2/3-Z
 1/3+Y,2/3+Y-X,2/3-Z
 1/3+X-Y,2/3+X,2/3-Z
 1/3-Y,2/3-X,1/6+Z
 1/3+Y-X,2/3+Y,1/6+Z
 1/3+X,2/3+X-Y,1/6+Z
168 6 6 P6 PG6 HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,Z 
 Y,Y-X,Z 
 X-Y,X,Z 
169 6 6 P61 PG6 HEXAGONAL
 X,Y,Z
 -Y,X-Y,Z+1/3
 Y-X,-X,Z+2/3
 -X,-Y,Z+1/2
 Y,Y-X,Z+5/6
 X-Y,X,Z+1/6
170 6 6 P65 PG6 HEXAGONAL
 X,Y,Z
 -Y,X-Y,Z+2/3
 Y-X,-X,Z+1/3
 -X,-Y,Z+1/2
 Y,Y-X,Z+1/6
 X-Y,X,Z+5/6
171 6 6 P62 PG6 HEXAGONAL
 X,Y,Z 
 -Y,X-Y,2/3+Z 
 Y-X,-X,1/3+Z 
 -X,-Y,Z 
 Y,Y-X,2/3+Z 
 X-Y,X,1/3+Z
172 6 6 P64 PG6 HEXAGONAL
 X,Y,Z 
 -Y,X-Y,1/3+Z 
 Y-X,-X,2/3+Z 
 -X,-Y,Z 
 Y,Y-X,1/3+Z 
 X-Y,X,2/3+Z
173 6 6 P63 PG6 HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,1/2+Z 
 Y,Y-X,1/2+Z 
 X-Y,X,1/2+Z 
174 6 6 P-6 PG6bar HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 X,Y,-Z
 -Y,X-Y,-Z
 Y-X,-X,-Z
175 12 12 P6/m PG6/m HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,Z 
 Y,Y-X,Z 
 X-Y,X,Z 
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 X,Y,-Z
 -Y,X-Y,-Z
 Y-X,-X,-Z
176 12 12 P63/m PG6/m HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,1/2+Z 
 Y,Y-X,1/2+Z 
 X-Y,X,1/2+Z 
 -X,-Y,-Z
 Y,Y-X,-Z
 X-Y,X,-Z
 X,Y,1/2-Z
 -Y,X-Y,1/2-Z
 Y-X,-X,1/2-Z
177 12 12 P622 PG622 HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 -X,-Y,Z
 Y,Y-X,Z
 X-Y,X,Z
 Y,X,-Z       
 X-Y,-Y,-Z
 -X,Y-X,-Z      
 -Y,-X,-Z     
 Y-X,Y,-Z
 X,X-Y,-Z      
178 12 12 P6122 PG622 HEXAGONAL
 X,Y,Z        
 -Y,X-Y,1/3+Z   
 Y-X,-X,2/3+Z
 -X,-Y,1/2+Z  
 Y,Y-X,5/6+Z   
 X-Y,X,1/6+Z
 Y,X,1/3-Z  
 X-Y,-Y,-Z
 -X,Y-X,2/3-Z
 -Y,-X,5/6-Z
 Y-X,Y,1/2-Z
 X,X-Y,1/6-Z
179 12 12 P6522 PG622 HEXAGONAL
 X,Y,Z       
 -Y,X-Y,2/3+Z   
 Y-X,-X,1/3+Z
 -X,-Y,1/2+Z  
 Y,Y-X,1/6+Z   
 X-Y,X,5/6+Z
 Y,X,2/3-Z  
 X-Y,-Y,-Z
 -X,Y-X,1/3-Z   
 -Y,-X,1/6-Z  
 Y-X,Y,1/2-Z
 X,X-Y,5/6-Z   
180 12 12 P6222 PG622 HEXAGONAL
 X,Y,Z        
 -Y,X-Y,2/3+Z       
 Y-X,-X,1/3+Z
 -X,-Y,Z
 Y,Y-X,2/3+Z
 X-Y,X,1/3+Z
 Y,X,2/3-Z       
 X-Y,-Y,-Z
 -X,Y-X,1/3-Z      
 -Y,-X,2/3-Z     
 Y-X,Y,-Z
 X,X-Y,1/3-Z      
181 12 12 P6422 PG622 HEXAGONAL
 X,Y,Z        
 -Y,X-Y,1/3+Z       
 Y-X,-X,2/3+Z
 -X,-Y,Z
 Y,Y-X,1/3+Z
 X-Y,X,2/3+Z
 Y,X,1/3-Z       
 X-Y,-Y,-Z
 -X,Y-X,2/3-Z      
 -Y,-X,1/3-Z     
 Y-X,Y,-Z
 X,X-Y,2/3-Z      
182 12 12 P6322 PG622 HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 -X,-Y,1/2+Z
 Y,Y-X,1/2+Z
 X-Y,X,1/2+Z
 Y,X,-Z       
 X-Y,-Y,-Z
 -X,Y-X,-Z      
 -Y,-X,1/2-Z     
 Y-X,Y,1/2-Z
 X,X-Y,1/2-Z      
183 12 12 P6mm PG6mm HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 -X,-Y,Z
 Y,Y-X,Z
 X-Y,X,Z
 -Y,-X,Z
 Y-X,Y,Z
 X,X-Y,Z
 Y,X,Z
 X-Y,-Y,Z
 -X,Y-X,Z
184 12 12 P6cc PG6mm HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 -X,-Y,Z
 Y,Y-X,Z
 X-Y,X,Z
 -Y,-X,1/2+Z
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z
 Y,X,1/2+Z
 X-Y,-Y,1/2+Z
 -X,Y-X,1/2+Z
185 12 12 P63cm PG6mm HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 -X,-Y,1/2+Z
 Y,Y-X,1/2+Z
 X-Y,X,1/2+Z
 -Y,-X,1/2+Z
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z
 Y,X,Z
 X-Y,-Y,Z
 -X,Y-X,Z
186 12 12 P63mc PG6mm HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 -X,-Y,1/2+Z
 Y,Y-X,1/2+Z
 X-Y,X,1/2+Z
 -Y,-X,Z
 Y-X,Y,Z
 X,X-Y,Z
 Y,X,1/2+Z
 X-Y,-Y,1/2+Z
 -X,Y-X,1/2+Z
187 12 12 P-6m2 PG6barm2 HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 X,Y,-Z
 -Y,X-Y,-Z
 Y-X,-X,-Z
 -Y,-X,Z
 Y-X,Y,Z
 X,X-Y,Z
 -Y,-X,-Z
 Y-X,Y,-Z
 X,X-Y,-Z
188 12 12 P-6c2 PG6barm2 HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 X,Y,1/2-Z
 -Y,X-Y,1/2-Z
 Y-X,-X,1/2-Z
 -Y,-X,1/2+Z
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z
 -Y,-X,-Z
 Y-X,Y,-Z
 X,X-Y,-Z
189 12 12 P-62m PG6bar2m HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 X,Y,-Z
 -Y,X-Y,-Z
 Y-X,-X,-Z
 Y,X,-Z
 X-Y,-Y,-Z
 -X,Y-X,-Z
 Y,X,Z
 X-Y,-Y,Z
 -X,Y-X,Z
190 12 12 P-62c PG6bar2m HEXAGONAL
 X,Y,Z        
 -Y,X-Y,Z       
 Y-X,-X,Z
 X,Y,1/2-Z
 -Y,X-Y,1/2-Z
 Y-X,-X,1/2-Z
 Y,X,-Z
 X-Y,-Y,-Z
 -X,Y-X,-Z
 Y,X,1/2+Z
 X-Y,-Y,1/2+Z
 -X,Y-X,1/2+Z
191 24 24 P6/mmm PG6/mmm HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,Z 
 Y,Y-X,Z 
 X-Y,X,Z 
 Y,X,-Z 
 X-Y,-Y,-Z
 -X,Y-X,-Z 
 -Y,-X,-Z 
 Y-X,Y,-Z
 X,X-Y,-Z 
 -X,-Y,-Z 
 Y,Y-X,-Z 
 X-Y,X,-Z 
 X,Y,-Z 
 Y-X,-X,-Z 
 -Y,X-Y,-Z 
 -Y,-X,Z 
 Y-X,Y,Z
 X,X-Y,Z 
 Y,X,Z 
 X-Y,-Y,Z
 -X,Y-X,Z 
192 24 24 P6/mcc PG6/mmm HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,Z 
 Y,Y-X,Z 
 X-Y,X,Z 
 Y,X,1/2-Z 
 X-Y,-Y,1/2-Z
 -X,Y-X,1/2-Z 
 -Y,-X,1/2-Z 
 Y-X,Y,1/2-Z
 X,X-Y,1/2-Z 
 -X,-Y,-Z 
 Y,Y-X,-Z 
 X-Y,X,-Z 
 X,Y,-Z 
 Y-X,-X,-Z 
 -Y,X-Y,-Z 
 -Y,-X,1/2+Z 
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z 
 Y,X,1/2+Z 
 X-Y,-Y,1/2+Z
 -X,Y-X,1/2+Z 
193 24 24 P63/mcm PG6/mmm HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,1/2+Z 
 Y,Y-X,1/2+Z 
 X-Y,X,1/2+Z 
 Y,X,1/2-Z 
 X-Y,-Y,1/2-Z
 -X,Y-X,1/2-Z 
 -Y,-X,-Z 
 Y-X,Y,-Z
 X,X-Y,-Z 
 -X,-Y,-Z 
 Y,Y-X,-Z 
 X-Y,X,-Z 
 X,Y,1/2-Z 
 Y-X,-X,1/2-Z 
 -Y,X-Y,1/2-Z 
 -Y,-X,1/2+Z 
 Y-X,Y,1/2+Z
 X,X-Y,1/2+Z 
 Y,X,Z 
 X-Y,-Y,Z
 -X,Y-X,Z 
194 24 24 P63/mmc PG6/mmm HEXAGONAL
 X,Y,Z 
 -Y,X-Y,Z 
 Y-X,-X,Z 
 -X,-Y,1/2+Z 
 Y,Y-X,1/2+Z 
 X-Y,X,1/2+Z 
 Y,X,-Z 
 X-Y,-Y,-Z
 -X,Y-X,-Z 
 -Y,-X,1/2-Z 
 Y-X,Y,1/2-Z
 X,X-Y,1/2-Z 
 -X,-Y,-Z 
 Y,Y-X,-Z 
 X-Y,X,-Z 
 X,Y,1/2-Z 
 Y-X,-X,1/2-Z 
 -Y,X-Y,1/2-Z 
 -Y,-X,Z 
 Y-X,Y,Z
 X,X-Y,Z 
 Y,X,1/2+Z 
 X-Y,-Y,1/2+Z
 -X,Y-X,1/2+Z 
195 12 12 P23 PG23 CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
196 48 12 F23 PG23 CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 X,1/2+Y,1/2+Z 
 -X,1/2-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 X,1/2-Y,1/2-Z 
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 1/2+X,Y,1/2+Z 
 1/2-X,-Y,1/2+Z 
 1/2-X,Y,1/2-Z 
 1/2+X,-Y,1/2-Z 
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/2+X,1/2+Y,Z 
 1/2-X,1/2-Y,Z 
 1/2-X,1/2+Y,-Z 
 1/2+X,1/2-Y,-Z 
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
197 24 12 I23 PG23 CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2+X,1/2+Y,1/2+Z 
 1/2-X,1/2-Y,1/2+Z 
 1/2-X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,1/2-Z 
 1/2+Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,1/2-Y
 1/2-Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,1/2-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,1/2-X
 1/2-Y,1/2-Z,1/2+X
1197 24 12 I23a PG23 CUBIC ! Expansion of 1023 which is an expansion of 1018
 X,Y,Z
 1/2-X,1/2-Y,Z
 X+1/2,-Y,-Z
 -X,Y+1/2,-Z
 Y,Z,X
 1/2-Y,1/2-Z,X
 Y+1/2,-Z,-X
 -Y,Z+1/2,-X
 Z,X,Y
 1/2-Z,1/2-X,Y
 Z+1/2,-X,-Y
 -Z,X+1/2,-Y
 1/2+X,1/2+Y,1/2+Z
 -X,-Y,1/2+Z
 X,1/2-Y,1/2-Z
 1/2-X,Y,1/2-Z
 1/2+Y,1/2+Z,1/2+X
 -Y,-Z,1/2+X
 Y,1/2-Z,1/2-X
 1/2-Y,Z,1/2-X
 1/2+Z,1/2+X,1/2+Y
 -Z,-X,1/2+Y
 Z,1/2-X,1/2-Y
 1/2-Z,X,1/2-Y
198 12 12 P213 PG23 CUBIC
 X,Y,Z 
 1/2-X,-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
199 24 12 I213 PG23 CUBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 1/2+X,1/2+Y,1/2+Z
 -X,1/2-Y,Z 
 1/2-X,Y,-Z 
 X,-Y,1/2-Z 
 1/2+Z,1/2+X,1/2+Y
 Z,-X,1/2-Y
 -Z,1/2-X,Y
 1/2-Z,X,-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,Z,-X
 Y,-Z,1/2-X
 -Y,1/2-Z,X
200 24 24 Pm-3 PGm3bar CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
201 24 24 Pn-3 PGm3bar CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Z,1/2-X,1/2-Y
 1/2-Z,1/2+X,1/2+Y
 1/2+Z,1/2+X,1/2-Y
 1/2+Z,1/2-X,1/2+Y
 1/2-Y,1/2-Z,1/2-X
 1/2+Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,1/2+X
 1/2+Y,1/2+Z,1/2-X
202 96 24 Fm-3 PGm3bar CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
 X,1/2+Y,1/2+Z 
 -X,1/2-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 X,1/2-Y,1/2-Z 
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 -X,1/2-Y,1/2-Z
 X,1/2+Y,1/2-Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
 -Z,1/2-X,1/2-Y
 -Z,1/2+X,1/2+Y
 Z,1/2+X,1/2-Y
 Z,1/2-X,1/2+Y
 -Y,1/2-Z,1/2-X
 Y,1/2-Z,1/2+X
 -Y,1/2+Z,1/2+X
 Y,1/2+Z,1/2-X
 1/2+X,Y,1/2+Z 
 1/2-X,-Y,1/2+Z 
 1/2-X,Y,1/2-Z 
 1/2+X,-Y,1/2-Z 
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/2-X,-Y,1/2-Z
 1/2+X,Y,1/2-Z
 1/2+X,-Y,1/2+Z
 1/2-X,Y,1/2+Z
 1/2-Z,-X,1/2-Y
 1/2-Z,X,1/2+Y
 1/2+Z,X,1/2-Y
 1/2+Z,-X,1/2+Y
 1/2-Y,-Z,1/2-X
 1/2+Y,-Z,1/2+X
 1/2-Y,Z,1/2+X
 1/2+Y,Z,1/2-X
 1/2+X,1/2+Y,Z 
 1/2-X,1/2-Y,Z 
 1/2-X,1/2+Y,-Z 
 1/2+X,1/2-Y,-Z 
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Z,1/2-X,-Y
 1/2-Z,1/2+X,Y
 1/2+Z,1/2+X,-Y
 1/2+Z,1/2-X,Y
 1/2-Y,1/2-Z,-X
 1/2+Y,1/2-Z,X
 1/2-Y,1/2+Z,X
 1/2+Y,1/2+Z,-X
203 96 24 Fd-3 PGm3bar CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/4-X,1/4-Y,1/4-Z
 1/4+X,1/4+Y,1/4-Z
 1/4+X,1/4-Y,1/4+Z
 1/4-X,1/4+Y,1/4+Z
 1/4-Z,1/4-X,1/4-Y
 1/4-Z,1/4+X,1/4+Y
 1/4+Z,1/4+X,1/4-Y
 1/4+Z,1/4-X,1/4+Y
 1/4-Y,1/4-Z,1/4-X 
 1/4+Y,1/4-Z,1/4+X
 1/4-Y,1/4+Z,1/4+X
 1/4+Y,1/4+Z,1/4-X
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,1/2-Z
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 1/4-X,3/4-Y,3/4-Z
 1/4+X,3/4+Y,3/4-Z
 1/4+X,3/4-Y,3/4+Z
 1/4-X,3/4+Y,3/4+Z
 1/4-Z,3/4-X,3/4-Y
 1/4-Z,3/4+X,3/4+Y
 1/4+Z,3/4+X,3/4-Y
 1/4+Z,3/4-X,3/4+Y
 1/4-Y,3/4-Z,3/4-X 
 1/4+Y,3/4-Z,3/4+X
 1/4-Y,3/4+Z,3/4+X
 1/4+Y,3/4+Z,3/4-X
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,-Y,1/2-Z
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 3/4-X,1/4-Y,3/4-Z
 3/4+X,1/4+Y,3/4-Z
 3/4+X,1/4-Y,3/4+Z
 3/4-X,1/4+Y,3/4+Z
 3/4-Z,1/4-X,3/4-Y
 3/4-Z,1/4+X,3/4+Y
 3/4+Z,1/4+X,3/4-Y
 3/4+Z,1/4-X,3/4+Y
 3/4-Y,1/4-Z,3/4-X 
 3/4+Y,1/4-Z,3/4+X
 3/4-Y,1/4+Z,3/4+X
 3/4+Y,1/4+Z,3/4-X
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
 3/4-X,3/4-Y,1/4-Z
 3/4+X,3/4+Y,1/4-Z
 3/4+X,3/4-Y,Z+1/4
 3/4-X,3/4+Y,Z+1/4
 3/4-Z,3/4-X,1/4-Y
 3/4-Z,3/4+X,1/4+Y
 3/4+Z,3/4+X,1/4-Y
 3/4+Z,3/4-X,1/4+Y
 3/4-Y,3/4-Z,1/4-X 
 3/4+Y,3/4-Z,1/4+X
 3/4-Y,3/4+Z,1/4+X
 3/4+Y,3/4+Z,1/4-X
204 48 24 Im-3 PGm3bar CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
 1/2+X,1/2+Y,1/2+Z 
 1/2-X,1/2-Y,1/2+Z 
 1/2-X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,1/2-Z 
 1/2+Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,1/2-Y
 1/2-Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,1/2-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,1/2-X
 1/2-Y,1/2-Z,1/2+X
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Z,1/2-X,1/2-Y
 1/2-Z,1/2+X,1/2+Y
 1/2+Z,1/2+X,1/2-Y
 1/2+Z,1/2-X,1/2+Y
 1/2-Y,1/2-Z,1/2-X
 1/2+Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,1/2+X
 1/2+Y,1/2+Z,1/2-X
205 24 24 Pa-3 PGm3bar CUBIC
 X,Y,Z 
 1/2-X,-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 -X,-Y,-Z
 1/2+X,Y,1/2-Z
 X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,Z
 -Z,-X,-Y
 1/2-Z,1/2+X,Y
 1/2+Z,X,1/2-Y
 Z,1/2-X,1/2+Y
 -Y,-Z,-X
 Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,X
 1/2+Y,Z,1/2-X
206 48 24 Ia-3 PGm3bar CUBIC
 X,Y,Z 
 1/2-X,-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 -X,-Y,-Z
 1/2+X,Y,1/2-Z
 X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,Z
 -Z,-X,-Y
 1/2-Z,1/2+X,Y
 1/2+Z,X,1/2-Y
 Z,1/2-X,1/2+Y
 -Y,-Z,-X
 Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,X
 1/2+Y,Z,1/2-X
 1/2+X,1/2+Y,1/2+Z 
 -X,1/2-Y,Z 
 1/2-X,+Y,-Z 
 X,-Y,1/2-Z 
 1/2+Z,1/2+X,1/2+Y
 Z,-X,1/2-Y
 -Z,1/2-X,Y
 1/2-Z,X,-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,Z,-X
 Y,-Z,1/2-X
 -Y,1/2-Z,X
 1/2-X,1/2-Y,1/2-Z
 X,1/2+Y,-Z
 1/2+X,-Y,Z
 -X,Y,1/2+Z
 1/2-Z,1/2-X,1/2-Y
 -Z,X,1/2+Y
 Z,1/2+X,-Y
 1/2+Z,-X,Y
 1/2-Y,1/2-Z,1/2-X
 1/2+Y,-Z,X
 -Y,Z,1/2+X
 Y,1/2+Z,-X
207 24 24 P432 PG432 CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,-Z
 -Y,-X,-Z
 Y,-X,Z
 -Y,X,Z
 X,Z,-Y
 -X,Z,Y
 -X,-Z,-Y
 X,-Z,Y
 Z,Y,-X
 Z,-Y,X
 -Z,Y,X
 -Z,-Y,-X
208 24 24 P4232 PG432 CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2+Y,1/2-X,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+X,1/2+Z,1/2-Y
 1/2-X,1/2+Z,1/2+Y
 1/2-X,1/2-Z,1/2-Y
 1/2+X,1/2-Z,1/2+Y
 1/2+Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2+X
 1/2-Z,1/2-Y,1/2-X
209 96 24 F432 PG432 CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,-Z
 -Y,-X,-Z
 Y,-X,Z
 -Y,X,Z
 X,Z,-Y
 -X,Z,Y
 -X,-Z,-Y
 X,-Z,Y
 Z,Y,-X
 Z,-Y,X
 -Z,Y,X
 -Z,-Y,-X
 X,1/2+Y,1/2+Z 
 -X,1/2-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 X,1/2-Y,1/2-Z 
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 Y,1/2+X,1/2-Z
 -Y,1/2-X,1/2-Z
 Y,1/2-X,1/2+Z
 -Y,1/2+X,1/2+Z
 X,1/2+Z,1/2-Y
 -X,1/2+Z,1/2+Y
 -X,1/2-Z,1/2-Y
 X,1/2-Z,1/2+Y
 Z,1/2+Y,1/2-X
 Z,1/2-Y,1/2+X
 -Z,1/2+Y,1/2+X
 -Z,1/2-Y,1/2-X
 1/2+X,Y,1/2+Z 
 1/2-X,-Y,1/2+Z 
 1/2-X,Y,1/2-Z 
 1/2+X,-Y,1/2-Z 
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/2+Y,X,1/2-Z
 1/2-Y,-X,1/2-Z
 1/2+Y,-X,1/2+Z
 1/2-Y,X,1/2+Z
 1/2+X,Z,1/2-Y
 1/2-X,Z,1/2+Y
 1/2-X,-Z,1/2-Y
 1/2+X,-Z,1/2+Y
 1/2+Z,Y,1/2-X
 1/2+Z,-Y,1/2+X
 1/2-Z,Y,1/2+X
 1/2-Z,-Y,1/2-X
 1/2+X,1/2+Y,Z 
 1/2-X,1/2-Y,Z 
 1/2-X,1/2+Y,-Z 
 1/2+X,1/2-Y,-Z 
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
 1/2+Y,1/2+X,-Z
 1/2-Y,1/2-X,-Z
 1/2+Y,1/2-X,Z
 1/2-Y,1/2+X,Z
 1/2+X,1/2+Z,-Y
 1/2-X,1/2+Z,Y
 1/2-X,1/2-Z,-Y
 1/2+X,1/2-Z,Y
 1/2+Z,1/2+Y,-X
 1/2+Z,1/2-Y,X
 1/2-Z,1/2+Y,X
 1/2-Z,1/2-Y,-X
210 96 24 F4132 PG432 CUBIC
 X,Y,Z 
 -X,1/2-Y,1/2+Z 
 1/2-X,1/2+Y,-Z 
 1/2+X,-Y,1/2-Z 
 Z,X,Y
 1/2+Z,-X,1/2-Y
 -Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,-Y
 Y,Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,-Z,1/2-X
 -Y,1/2-Z,1/2+X
 3/4+Y,1/4+X,3/4-Z
 1/4-Y,1/4-X,1/4-Z
 1/4+Y,3/4-X,3/4+Z
 3/4-Y,3/4+X,1/4+Z
 3/4+X,1/4+Z,3/4-Y
 3/4-X,3/4+Z,1/4+Y
 1/4-X,1/4-Z,1/4-Y
 1/4+X,3/4-Z,3/4+Y
 3/4+Z,1/4+Y,3/4-X
 1/4+Z,3/4-Y,3/4+X
 3/4-Z,3/4+Y,1/4+X
 1/4-Z,1/4-Y,1/4-X
 X,1/2+Y,1/2+Z 
 -X,-Y,Z 
 1/2-X,Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,-Y
 -Z,-X,Y
 1/2-Z,X,1/2-Y
 Y,1/2+Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,1/2-Z,-X
 -Y,-Z,X
 3/4+Y,3/4+X,1/4-Z
 1/4-Y,3/4-X,3/4-Z
 1/4+Y,1/4-X,1/4+Z
 3/4-Y,1/4+X,3/4+Z
 3/4+X,3/4+Z,1/4-Y
 3/4-X,1/4+Z,3/4+Y
 1/4-X,3/4-Z,3/4-Y
 1/4+X,1/4-Z,1/4+Y
 3/4+Z,3/4+Y,1/4-X
 1/4+Z,1/4-Y,1/4+X
 3/4-Z,1/4+Y,3/4+X
 1/4-Z,3/4-Y,3/4-X
 1/2+X,Y,1/2+Z 
 1/2-X,1/2-Y,Z 
 -X,1/2+Y,1/2-Z 
 X,-Y,-Z 
 1/2+Z,X,1/2+Y
 Z,-X,-Y
 1/2-Z,1/2-X,Y
 -Z,1/2+X,1/2-Y
 1/2+Y,Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,-Z,-X
 1/2-Y,1/2-Z,X
 1/4+Y,1/4+X,1/4-Z
 3/4-Y,1/4-X,3/4-Z
 3/4+Y,3/4-X,1/4+Z
 1/4-Y,3/4+X,3/4+Z
 1/4+X,1/4+Z,1/4-Y
 1/4-X,3/4+Z,3/4+Y
 3/4-X,1/4-Z,3/4-Y
 3/4+X,3/4-Z,1/4+Y
 1/4+Z,1/4+Y,1/4-X
 3/4+Z,3/4-Y,1/4+X
 1/4-Z,3/4+Y,3/4+X
 3/4-Z,1/4-Y,3/4-X
 1/2+X,1/2+Y,Z 
 1/2-X,-Y,1/2+Z 
 -X,Y,-Z 
 X,1/2-Y,1/2-Z 
 1/2+Z,1/2+X,Y
 Z,1/2-X,1/2-Y
 1/2-Z,-X,1/2+Y
 -Z,X,-Y
 1/2+Y,1/2+Z,X
 -Y,Z,-X
 Y,1/2-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/4+Y,3/4+X,3/4-Z
 3/4-Y,3/4-X,1/4-Z
 3/4+Y,1/4-X,3/4+Z
 1/4-Y,1/4+X,1/4+Z
 1/4+X,3/4+Z,3/4-Y
 1/4-X,1/4+Z,1/4+Y
 3/4-X,3/4-Z,1/4-Y
 3/4+X,1/4-Z,3/4+Y
 1/4+Z,3/4+Y,3/4-X
 3/4+Z,1/4-Y,3/4+X
 1/4-Z,1/4+Y,1/4+X
 3/4-Z,3/4-Y,1/4-X
211 48 24 I432 PG432 CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,-Z
 -Y,-X,-Z
 Y,-X,Z
 -Y,X,Z
 X,Z,-Y
 -X,Z,Y
 -X,-Z,-Y
 X,-Z,Y
 Z,Y,-X
 Z,-Y,X
 -Z,Y,X
 -Z,-Y,-X
 1/2+X,1/2+Y,1/2+Z 
 1/2-X,1/2-Y,1/2+Z 
 1/2-X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,1/2-Z 
 1/2+Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,1/2-Y
 1/2-Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,1/2-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,1/2-X
 1/2-Y,1/2-Z,1/2+X
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2+Y,1/2-X,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+X,1/2+Z,1/2-Y
 1/2-X,1/2+Z,1/2+Y
 1/2-X,1/2-Z,1/2-Y
 1/2+X,1/2-Z,1/2+Y
 1/2+Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2+X
 1/2-Z,1/2-Y,1/2-X
212 24 24 P4332 PG432 CUBIC
 X,Y,Z 
 1/2-X,-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 1/4+Y,3/4+X,3/4-Z
 1/4-Y,1/4-X,1/4-Z
 3/4+Y,3/4-X,1/4+Z
 3/4-Y,1/4+X,3/4+Z
 1/4+X,3/4+Z,3/4-Y
 3/4-X,1/4+Z,3/4+Y
 1/4-X,1/4-Z,1/4-Y
 3/4+X,3/4-Z,1/4+Y
 1/4+Z,3/4+Y,3/4-X
 3/4+Z,3/4-Y,1/4+X
 3/4-Z,1/4+Y,3/4+X
 1/4-Z,1/4-Y,1/4-X
213 24 24 P4132 PG432 CUBIC
 X,Y,Z 
 1/2-X,-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 3/4+Y,1/4+X,1/4-Z
 3/4-Y,3/4-X,3/4-Z
 1/4+Y,1/4-X,3/4+Z
 1/4-Y,3/4+X,1/4+Z
 3/4+X,1/4+Z,1/4-Y
 1/4-X,3/4+Z,1/4+Y
 3/4-X,3/4-Z,3/4-Y
 1/4+X,1/4-Z,3/4+Y
 3/4+Z,1/4+Y,1/4-X
 1/4+Z,1/4-Y,3/4+X
 1/4-Z,3/4+Y,1/4+X
 3/4-Z,3/4-Y,3/4-X
214 48 24 I4132 PG432 CUBIC
 X,Y,Z 
 1/2-X,-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,-Z 
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 3/4+Y,1/4+X,1/4-Z
 3/4-Y,3/4-X,3/4-Z
 1/4+Y,1/4-X,3/4+Z
 1/4-Y,3/4+X,1/4+Z
 3/4+X,1/4+Z,1/4-Y
 1/4-X,3/4+Z,1/4+Y
 3/4-X,3/4-Z,3/4-Y
 1/4+X,1/4-Z,3/4+Y
 3/4+Z,1/4+Y,1/4-X
 1/4+Z,1/4-Y,3/4+X
 1/4-Z,3/4+Y,1/4+X
 3/4-Z,3/4-Y,3/4-X
 1/2+X,1/2+Y,1/2+Z 
 -X,1/2-Y,Z 
 1/2-X,Y,-Z 
 X,-Y,1/2-Z 
 1/2+Z,1/2+X,1/2+Y
 Z,-X,1/2-Y
 -Z,1/2-X,Y
 1/2-Z,X,-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,Z,-X
 Y,-Z,1/2-X
 -Y,1/2-Z,X
 1/4+Y,3/4+X,3/4-Z
 1/4-Y,1/4-X,1/4-Z
 3/4+Y,3/4-X,1/4+Z
 3/4-Y,1/4+X,3/4+Z
 1/4+X,3/4+Z,3/4-Y
 3/4-X,1/4+Z,3/4+Y
 1/4-X,1/4-Z,1/4-Y
 3/4+X,3/4-Z,1/4+Y
 1/4+Z,3/4+Y,3/4-X
 3/4+Z,3/4-Y,1/4+X
 3/4-Z,1/4+Y,3/4+X
 1/4-Z,1/4-Y,1/4-X
215 24 24 P-43m PG4bar3m CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,Z
 -Y,-X,Z
 Y,-X,-Z
 -Y,X,-Z
 X,Z,Y
 -X,Z,-Y
 -X,-Z,Y
 X,-Z,-Y
 Z,Y,X
 Z,-Y,-X
 -Z,Y,-X
 -Z,-Y,X
216 96 24 F-43m PG4bar3m CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,Z
 -Y,-X,Z
 Y,-X,-Z
 -Y,X,-Z
 X,Z,Y
 -X,Z,-Y
 -X,-Z,Y
 X,-Z,-Y
 Z,Y,X
 Z,-Y,-X
 -Z,Y,-X
 -Z,-Y,X
 X,1/2+Y,1/2+Z 
 -X,1/2-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 X,1/2-Y,1/2-Z 
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 Y,1/2+X,1/2+Z
 -Y,1/2-X,1/2+Z
 Y,1/2-X,1/2-Z
 -Y,1/2+X,1/2-Z
 X,1/2+Z,1/2+Y
 -X,1/2+Z,1/2-Y
 -X,1/2-Z,1/2+Y
 X,1/2-Z,1/2-Y
 Z,1/2+Y,1/2+X
 Z,1/2-Y,1/2-X
 -Z,1/2+Y,1/2-X
 -Z,1/2-Y,1/2+X
 1/2+X,Y,1/2+Z 
 1/2-X,-Y,1/2+Z 
 1/2-X,Y,1/2-Z 
 1/2+X,-Y,1/2-Z 
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/2+Y,X,1/2+Z
 1/2-Y,-X,1/2+Z
 1/2+Y,-X,1/2-Z
 1/2-Y,X,1/2-Z
 1/2+X,Z,1/2+Y
 1/2-X,Z,1/2-Y
 1/2-X,-Z,1/2+Y
 1/2+X,-Z,1/2-Y
 1/2+Z,Y,1/2+X
 1/2+Z,-Y,1/2-X
 1/2-Z,Y,1/2-X
 1/2-Z,-Y,1/2+X
 1/2+X,1/2+Y,Z 
 1/2-X,1/2-Y,Z 
 1/2-X,1/2+Y,-Z 
 1/2+X,1/2-Y,-Z 
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
 1/2+Y,1/2+X,Z
 1/2-Y,1/2-X,Z
 1/2+Y,1/2-X,-Z
 1/2-Y,1/2+X,-Z
 1/2+X,1/2+Z,Y
 1/2-X,1/2+Z,-Y
 1/2-X,1/2-Z,Y
 1/2+X,1/2-Z,-Y
 1/2+Z,1/2+Y,X
 1/2+Z,1/2-Y,-X
 1/2-Z,1/2+Y,-X
 1/2-Z,1/2-Y,X
217 48 24 I-43m PG4bar3m CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,Z
 -Y,-X,Z
 Y,-X,-Z
 -Y,X,-Z
 X,Z,Y
 -X,Z,-Y
 -X,-Z,Y
 X,-Z,-Y
 Z,Y,X
 Z,-Y,-X
 -Z,Y,-X
 -Z,-Y,X
 1/2+X,1/2+Y,1/2+Z 
 1/2-X,1/2-Y,1/2+Z 
 1/2-X,1/2+Y,1/2-Z 
 1/2+X,1/2-Y,1/2-Z 
 1/2+Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,1/2-Y
 1/2-Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,1/2-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,1/2-X
 1/2-Y,1/2-Z,1/2+X
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2+Z,1/2+Y
 1/2-X,1/2+Z,1/2-Y
 1/2-X,1/2-Z,1/2+Y
 1/2+X,1/2-Z,1/2-Y
 1/2+Z,1/2+Y,1/2+X
 1/2+Z,1/2-Y,1/2-X
 1/2-Z,1/2+Y,1/2-X
 1/2-Z,1/2-Y,1/2+X
218 24 24 P-43n PG4bar3m CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2+Z,1/2+Y
 1/2-X,1/2+Z,1/2-Y
 1/2-X,1/2-Z,1/2+Y
 1/2+X,1/2-Z,1/2-Y
 1/2+Z,1/2+Y,1/2+X
 1/2+Z,1/2-Y,1/2-X
 1/2-Z,1/2+Y,1/2-X
 1/2-Z,1/2-Y,1/2+X
219 96 24 F-43c PG4bar3m CUBIC
 X,Y,Z 
 -X,-Y,Z 
 -X,Y,-Z 
 X,-Y,-Z 
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2-X,1/2-Z
 1/2-Y,1/2+X,1/2-Z
 1/2+X,1/2+Z,1/2+Y
 1/2-X,1/2+Z,1/2-Y
 1/2-X,1/2-Z,1/2+Y
 1/2+X,1/2-Z,1/2-Y
 1/2+Z,1/2+Y,1/2+X
 1/2+Z,1/2-Y,1/2-X
 1/2-Z,1/2+Y,1/2-X
 1/2-Z,1/2-Y,1/2+X
 X,1/2+Y,1/2+Z 
 -X,1/2-Y,1/2+Z 
 -X,1/2+Y,1/2-Z 
 X,1/2-Y,1/2-Z 
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 1/2+Y,X,Z
 1/2-Y,-X,Z
 1/2+Y,-X,-Z
 1/2-Y,X,-Z
 1/2+X,Z,Y
 1/2-X,Z,-Y
 1/2-X,-Z,Y
 1/2+X,-Z,-Y
 1/2+Z,Y,X
 1/2+Z,-Y,-X
 1/2-Z,Y,-X
 1/2-Z,-Y,X
 1/2+X,Y,1/2+Z 
 1/2-X,-Y,1/2+Z 
 1/2-X,Y,1/2-Z 
 1/2+X,-Y,1/2-Z 
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 Y,1/2+X,Z
 -Y,1/2-X,Z
 Y,1/2-X,-Z
 -Y,1/2+X,-Z
 X,1/2+Z,Y
 -X,1/2+Z,-Y
 -X,1/2-Z,Y
 X,1/2-Z,-Y
 Z,1/2+Y,X
 Z,1/2-Y,-X
 -Z,1/2+Y,-X
 -Z,1/2-Y,X
 1/2+X,1/2+Y,Z 
 1/2-X,1/2-Y,Z 
 1/2-X,1/2+Y,-Z 
 1/2+X,1/2-Y,-Z 
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
 Y,X,1/2+Z
 -Y,-X,1/2+Z
 Y,-X,1/2-Z
 -Y,X,1/2-Z
 X,Z,1/2+Y
 -X,Z,1/2-Y
 -X,-Z,1/2+Y
 X,-Z,1/2-Y
 Z,Y,1/2+X
 Z,-Y,1/2-X
 -Z,Y,1/2-X
 -Z,-Y,1/2+X
220 48 24 I-43d PG4bar3m CUBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 1/4+Y,1/4+X,1/4+Z
 1/4-Y,3/4-X,3/4+Z
 3/4+Y,1/4-X,3/4-Z
 3/4-Y,3/4+X,1/4-Z
 1/4+X,1/4+Z,1/4+Y
 3/4-X,3/4+Z,1/4-Y
 1/4-X,3/4-Z,3/4+Y
 3/4+X,1/4-Z,3/4-Y
 1/4+Z,1/4+Y,1/4+X
 3/4+Z,1/4-Y,3/4-X
 3/4-Z,3/4+Y,1/4-X
 1/4-Z,3/4-Y,3/4+X
 1/2+X,1/2+Y,1/2+Z
 -X,1/2-Y,Z
 1/2-X,Y,-Z
 X,-Y,1/2-Z
 1/2+Z,1/2+X,1/2+Y
 Z,-X,1/2-Y
 -Z,1/2-X,Y
 1/2-Z,X,-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,Z,-X
 Y,-Z,1/2-X
 -Y,1/2-Z,X
 3/4+Y,3/4+X,3/4+Z
 3/4-Y,1/4-X,1/4+Z
 1/4+Y,3/4-X,1/4-Z
 1/4-Y,1/4+X,3/4-Z
 3/4+X,3/4+Z,3/4+Y
 1/4-X,1/4+Z,3/4-Y
 3/4-X,1/4-Z,1/4+Y
 1/4+X,3/4-Z,1/4-Y
 3/4+Z,3/4+Y,3/4+X
 1/4+Z,3/4-Y,1/4-X
 1/4-Z,1/4+Y,3/4-X
 3/4-Z,1/4-Y,1/4+X
221 48 48 Pm-3m PGm3barm CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,-Z
 -Y,-X,-Z
 Y,-X,Z
 -Y,X,Z
 X,Z,-Y
 -X,Z,Y
 -X,-Z,-Y
 X,-Z,Y
 Z,Y,-X
 Z,-Y,X
 -Z,Y,X
 -Z,-Y,-X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
 -Y,-X,Z
 Y,X,Z
 -Y,X,-Z
 Y,-X,-Z
 -X,-Z,Y
 X,-Z,-Y
 X,Z,Y
 -X,Z,-Y
 -Z,-Y,X
 -Z,Y,-X
 Z,-Y,-X
 Z,Y,X
222 48 48 Pn-3n PGm3barm CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,-Z
 -Y,-X,-Z
 Y,-X,Z
 -Y,X,Z
 X,Z,-Y
 -X,Z,Y
 -X,-Z,-Y
 X,-Z,Y
 Z,Y,-X
 Z,-Y,X
 -Z,Y,X
 -Z,-Y,-X
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Z,1/2-X,1/2-Y
 1/2-Z,1/2+X,1/2+Y
 1/2+Z,1/2+X,1/2-Y
 1/2+Z,1/2-X,1/2+Y
 1/2-Y,1/2-Z,1/2-X
 1/2+Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,1/2+X
 1/2+Y,1/2+Z,1/2-X
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-X,1/2-Z,1/2+Y
 1/2+X,1/2-Z,1/2-Y
 1/2+X,1/2+Z,1/2+Y
 1/2-X,1/2+Z,1/2-Y
 1/2-Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2-X
 1/2+Z,1/2+Y,1/2+X
223 48 48 Pm-3n PGm3barm CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2+Y,1/2-X,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+X,1/2+Z,1/2-Y
 1/2-X,1/2+Z,1/2+Y
 1/2-X,1/2-Z,1/2-Y
 1/2+X,1/2-Z,1/2+Y
 1/2+Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2+X
 1/2-Z,1/2-Y,1/2-X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-X,1/2-Z,1/2+Y
 1/2+X,1/2-Z,1/2-Y
 1/2+X,1/2+Z,1/2+Y
 1/2-X,1/2+Z,1/2-Y
 1/2-Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2-X
 1/2+Z,1/2+Y,1/2+X
224 48 48 Pn-3m PGm3barm CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2+Y,1/2-X,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+X,1/2+Z,1/2-Y
 1/2-X,1/2+Z,1/2+Y
 1/2-X,1/2-Z,1/2-Y
 1/2+X,1/2-Z,1/2+Y
 1/2+Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2+X
 1/2-Z,1/2-Y,1/2-X
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Z,1/2-X,1/2-Y
 1/2-Z,1/2+X,1/2+Y
 1/2+Z,1/2+X,1/2-Y
 1/2+Z,1/2-X,1/2+Y
 1/2-Y,1/2-Z,1/2-X
 1/2+Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,1/2+X
 1/2+Y,1/2+Z,1/2-X
 -Y,-X,Z
 Y,X,Z
 -Y,X,-Z
 Y,-X,-Z
 -X,-Z,Y
 X,-Z,-Y
 X,Z,Y
 -X,Z,-Y
 -Z,-Y,X
 -Z,Y,-X
 Z,-Y,-X
 Z,Y,X
225 192 48 Fm-3m PGm3barm CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,-Z
 -Y,-X,-Z
 Y,-X,Z
 -Y,X,Z
 X,Z,-Y
 -X,Z,Y
 -X,-Z,-Y
 X,-Z,Y
 Z,Y,-X
 Z,-Y,X
 -Z,Y,X
 -Z,-Y,-X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
 -Y,-X,Z
 Y,X,Z
 -Y,X,-Z
 Y,-X,-Z
 -X,-Z,Y
 X,-Z,-Y
 X,Z,Y
 -X,Z,-Y
 -Z,-Y,X
 -Z,Y,-X
 Z,-Y,-X
 Z,Y,X
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,1/2-Z
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 Y,1/2+X,1/2-Z
 -Y,1/2-X,1/2-Z
 Y,1/2-X,1/2+Z
 -Y,1/2+X,1/2+Z
 X,1/2+Z,1/2-Y
 -X,1/2+Z,1/2+Y
 -X,1/2-Z,1/2-Y
 X,1/2-Z,1/2+Y
 Z,1/2+Y,1/2-X
 Z,1/2-Y,1/2+X
 -Z,1/2+Y,1/2+X
 -Z,1/2-Y,1/2-X
 -X,1/2-Y,1/2-Z
 X,1/2+Y,1/2-Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
 -Z,1/2-X,1/2-Y
 -Z,1/2+X,1/2+Y
 Z,1/2+X,1/2-Y
 Z,1/2-X,1/2+Y
 -Y,1/2-Z,1/2-X
 Y,1/2-Z,1/2+X
 -Y,1/2+Z,1/2+X
 Y,1/2+Z,1/2-X
 -Y,1/2-X,1/2+Z
 Y,1/2+X,1/2+Z
 -Y,1/2+X,1/2-Z
 Y,1/2-X,1/2-Z
 -X,1/2-Z,1/2+Y
 X,1/2-Z,1/2-Y
 X,1/2+Z,1/2+Y
 -X,1/2+Z,1/2-Y
 -Z,1/2-Y,1/2+X
 -Z,1/2+Y,1/2-X
 Z,1/2-Y,1/2-X
 Z,1/2+Y,1/2+X
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,-Y,1/2-Z
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/2+Y,X,1/2-Z
 1/2-Y,-X,1/2-Z
 1/2+Y,-X,1/2+Z
 1/2-Y,X,1/2+Z
 1/2+X,Z,1/2-Y
 1/2-X,Z,1/2+Y
 1/2-X,-Z,1/2-Y
 1/2+X,-Z,1/2+Y
 1/2+Z,Y,1/2-X
 1/2+Z,-Y,1/2+X
 1/2-Z,Y,1/2+X
 1/2-Z,-Y,1/2-X
 1/2-X,-Y,1/2-Z
 1/2+X,Y,1/2-Z
 1/2+X,-Y,1/2+Z
 1/2-X,Y,1/2+Z
 1/2-Z,-X,1/2-Y
 1/2-Z,X,1/2+Y
 1/2+Z,X,1/2-Y
 1/2+Z,-X,1/2+Y
 1/2-Y,-Z,1/2-X
 1/2+Y,-Z,1/2+X
 1/2-Y,Z,1/2+X
 1/2+Y,Z,1/2-X
 1/2-Y,-X,1/2+Z
 1/2+Y,X,1/2+Z
 1/2-Y,X,1/2-Z
 1/2+Y,-X,1/2-Z
 1/2-X,-Z,1/2+Y
 1/2+X,-Z,1/2-Y
 1/2+X,Z,1/2+Y
 1/2-X,Z,1/2-Y
 1/2-Z,-Y,1/2+X
 1/2-Z,Y,1/2-X
 1/2+Z,-Y,1/2-X
 1/2+Z,Y,1/2+X
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
 1/2+Y,1/2+X,-Z
 1/2-Y,1/2-X,-Z
 1/2+Y,1/2-X,Z
 1/2-Y,1/2+X,Z
 1/2+X,1/2+Z,-Y
 1/2-X,1/2+Z,Y
 1/2-X,1/2-Z,-Y
 1/2+X,1/2-Z,Y
 1/2+Z,1/2+Y,-X
 1/2+Z,1/2-Y,X
 1/2-Z,1/2+Y,X
 1/2-Z,1/2-Y,-X
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Z,1/2-X,-Y
 1/2-Z,1/2+X,Y
 1/2+Z,1/2+X,-Y
 1/2+Z,1/2-X,Y
 1/2-Y,1/2-Z,-X
 1/2+Y,1/2-Z,X
 1/2-Y,1/2+Z,X
 1/2+Y,1/2+Z,-X
 1/2-Y,1/2-X,Z
 1/2+Y,1/2+X,Z
 1/2-Y,1/2+X,-Z
 1/2+Y,1/2-X,-Z
 1/2-X,1/2-Z,Y
 1/2+X,1/2-Z,-Y
 1/2+X,1/2+Z,Y
 1/2-X,1/2+Z,-Y
 1/2-Z,1/2-Y,X
 1/2-Z,1/2+Y,-X
 1/2+Z,1/2-Y,-X
 1/2+Z,1/2+Y,X
226 192 48 Fm-3c PGm3barm CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2+Y,1/2-X,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+X,1/2+Z,1/2-Y
 1/2-X,1/2+Z,1/2+Y
 1/2-X,1/2-Z,1/2-Y
 1/2+X,1/2-Z,1/2+Y
 1/2+Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2+X
 1/2-Z,1/2-Y,1/2-X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-X,1/2-Z,1/2+Y
 1/2+X,1/2-Z,1/2-Y
 1/2+X,1/2+Z,1/2+Y
 1/2-X,1/2+Z,1/2-Y
 1/2-Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2-X
 1/2+Z,1/2+Y,1/2+X
 X,1/2+Y,1/2+Z
 -X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 X,1/2-Y,1/2-Z
 Z,1/2+X,1/2+Y
 Z,1/2-X,1/2-Y
 -Z,1/2-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,1/2+Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,1/2-Z,1/2-X
 -Y,1/2-Z,1/2+X
 1/2+Y,X,-Z
 1/2-Y,-X,-Z
 1/2+Y,-X,Z
 1/2-Y,X,Z
 1/2+X,Z,-Y
 1/2-X,Z,Y
 1/2-X,-Z,-Y
 1/2+X,-Z,Y
 1/2+Z,Y,-X
 1/2+Z,-Y,X
 1/2-Z,Y,X
 1/2-Z,-Y,-X
 -X,1/2-Y,1/2-Z
 X,1/2+Y,1/2-Z
 X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2+Z
 -Z,1/2-X,1/2-Y
 -Z,1/2+X,1/2+Y
 Z,1/2+X,1/2-Y
 Z,1/2-X,1/2+Y
 -Y,1/2-Z,1/2-X
 Y,1/2-Z,1/2+X
 -Y,1/2+Z,1/2+X
 Y,1/2+Z,1/2-X
 1/2-Y,-X,Z
 1/2+Y,X,Z
 1/2-Y,X,-Z
 1/2+Y,-X,-Z
 1/2-X,-Z,Y
 1/2+X,-Z,-Y
 1/2+X,Z,Y
 1/2-X,Z,-Y
 1/2-Z,-Y,X
 1/2-Z,Y,-X
 1/2+Z,-Y,-X
 1/2+Z,Y,X
 1/2+X,Y,1/2+Z
 1/2-X,-Y,1/2+Z
 1/2-X,Y,1/2-Z
 1/2+X,-Y,1/2-Z
 1/2+Z,X,1/2+Y
 1/2+Z,-X,1/2-Y
 1/2-Z,-X,1/2+Y
 1/2-Z,X,1/2-Y
 1/2+Y,Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,-Z,1/2-X
 1/2-Y,-Z,1/2+X
 Y,1/2+X,-Z
 -Y,1/2-X,-Z
 Y,1/2-X,Z
 -Y,1/2+X,Z
 X,1/2+Z,-Y
 -X,1/2+Z,Y
 -X,1/2-Z,-Y
 X,1/2-Z,Y
 Z,1/2+Y,-X
 Z,1/2-Y,X
 -Z,1/2+Y,X
 -Z,1/2-Y,-X
 1/2-X,-Y,1/2-Z
 1/2+X,Y,1/2-Z
 1/2+X,-Y,1/2+Z
 1/2-X,Y,1/2+Z
 1/2-Z,-X,1/2-Y
 1/2-Z,X,1/2+Y
 1/2+Z,X,1/2-Y
 1/2+Z,-X,1/2+Y
 1/2-Y,-Z,1/2-X
 1/2+Y,-Z,1/2+X
 1/2-Y,Z,1/2+X
 1/2+Y,Z,1/2-X
 -Y,1/2-X,Z
 Y,1/2+X,Z
 -Y,1/2+X,-Z
 Y,1/2-X,-Z
 -X,1/2-Z,Y
 X,1/2-Z,-Y
 X,1/2+Z,Y
 -X,1/2+Z,-Y
 -Z,1/2-Y,X
 -Z,1/2+Y,-X
 Z,1/2-Y,-X
 Z,1/2+Y,X
 1/2+X,1/2+Y,Z
 1/2-X,1/2-Y,Z
 1/2-X,1/2+Y,-Z
 1/2+X,1/2-Y,-Z
 1/2+Z,1/2+X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,1/2-X,Y
 1/2-Z,1/2+X,-Y
 1/2+Y,1/2+Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,1/2-Z,-X
 1/2-Y,1/2-Z,X
 Y,X,1/2-Z
 -Y,-X,1/2-Z
 Y,-X,1/2+Z
 -Y,X,1/2+Z
 X,Z,1/2-Y
 -X,Z,1/2+Y
 -X,-Z,1/2-Y
 X,-Z,1/2+Y
 Z,Y,1/2-X
 Z,-Y,1/2+X
 -Z,Y,1/2+X
 -Z,-Y,1/2-X
 1/2-X,1/2-Y,-Z
 1/2+X,1/2+Y,-Z
 1/2+X,1/2-Y,Z
 1/2-X,1/2+Y,Z
 1/2-Z,1/2-X,-Y
 1/2-Z,1/2+X,Y
 1/2+Z,1/2+X,-Y
 1/2+Z,1/2-X,Y
 1/2-Y,1/2-Z,-X
 1/2+Y,1/2-Z,X
 1/2-Y,1/2+Z,X
 1/2+Y,1/2+Z,-X
 -Y,-X,1/2+Z
 Y,X,1/2+Z
 -Y,X,1/2-Z
 Y,-X,1/2-Z
 -X,-Z,1/2+Y
 X,-Z,1/2-Y
 X,Z,1/2+Y
 -X,Z,1/2-Y
 -Z,-Y,1/2+X
 -Z,Y,1/2-X
 Z,-Y,1/2-X
 Z,Y,1/2+X
227 192 48 Fd-3m PGm3barm CUBIC
 X,Y,Z
 -X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,-Z
 1/2+X,-Y,1/2-Z
 Z,X,Y
 1/2+Z,-X,1/2-Y
 -Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,-Y
 Y,Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,-Z,1/2-X
 -Y,1/2-Z,1/2+X
 3/4+Y,1/4+X,3/4-Z
 1/4-Y,1/4-X,1/4-Z
 1/4+Y,3/4-X,3/4+Z
 3/4-Y,3/4+X,1/4+Z
 3/4+X,1/4+Z,3/4-Y
 3/4-X,3/4+Z,1/4+Y
 1/4-X,1/4-Z,1/4-Y
 1/4+X,3/4-Z,3/4+Y
 3/4+Z,1/4+Y,3/4-X
 1/4+Z,3/4-Y,3/4+X
 3/4-Z,3/4+Y,1/4+X
 1/4-Z,1/4-Y,1/4-X
 1/4-X,1/4-Y,1/4-Z
 1/4+X,3/4+Y,3/4-Z
 3/4+X,3/4-Y,1/4+Z
 3/4-X,1/4+Y,3/4+Z
 1/4-Z,1/4-X,1/4-Y
 3/4-Z,1/4+X,3/4+Y
 1/4+Z,3/4+X,3/4-Y
 3/4+Z,3/4-X,1/4+Y
 1/4-Y,1/4-Z,1/4-X
 3/4+Y,3/4-Z,1/4+X
 3/4-Y,1/4+Z,3/4+X
 1/4+Y,3/4+Z,3/4-X
 1/2-Y,-X,1/2+Z
 Y,X,Z
 -Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,-Z
 1/2-X,-Z,1/2+Y
 1/2+X,1/2-Z,-Y
 X,Z,Y
 -X,1/2+Z,1/2-Y
 1/2-Z,-Y,1/2+X
 -Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,-X
 Z,Y,X
 X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-X,Y,1/2-Z
 1/2+X,1/2-Y,-Z
 Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,-Y
 -Z,-X,Y
 1/2-Z,X,1/2-Y
 Y,1/2+Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,1/2-Z,-X
 -Y,-Z,X
 3/4+Y,3/4+X,1/4-Z
 1/4-Y,3/4-X,3/4-Z
 1/4+Y,1/4-X,1/4+Z
 3/4-Y,1/4+X,3/4+Z
 3/4+X,3/4+Z,1/4-Y
 3/4-X,1/4+Z,3/4+Y
 1/4-X,3/4-Z,3/4-Y
 1/4+X,1/4-Z,1/4+Y
 3/4+Z,3/4+Y,1/4-X
 1/4+Z,1/4-Y,1/4+X
 3/4-Z,1/4+Y,3/4+X
 1/4-Z,3/4-Y,3/4-X
 1/4-X,3/4-Y,3/4-Z
 1/4+X,1/4+Y,1/4-Z
 3/4+X,1/4-Y,3/4+Z
 3/4-X,3/4+Y,1/4+Z
 1/4-Z,3/4-X,3/4-Y
 3/4-Z,3/4+X,1/4+Y
 1/4+Z,1/4+X,1/4-Y
 3/4+Z,1/4-X,3/4+Y
 1/4-Y,3/4-Z,3/4-X
 3/4+Y,1/4-Z,3/4+X
 3/4-Y,3/4+Z,1/4+X
 1/4+Y,1/4+Z,1/4-X
 1/2-Y,1/2-X,Z
 Y,1/2+X,1/2+Z
 -Y,X,-Z
 1/2+Y,-X,1/2-Z
 1/2-X,1/2-Z,Y
 1/2+X,-Z,1/2-Y
 X,1/2+Z,1/2+Y
 -X,Z,-Y
 1/2-Z,1/2-Y,X
 -Z,Y,-X
 1/2+Z,-Y,1/2-X
 Z,1/2+Y,1/2+X
 1/2+X,Y,1/2+Z
 1/2-X,1/2-Y,Z
 -X,1/2+Y,1/2-Z
 X,-Y,-Z
 1/2+Z,X,1/2+Y
 Z,-X,-Y
 1/2-Z,1/2-X,Y
 -Z,1/2+X,1/2-Y
 1/2+Y,Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,-Z,-X
 1/2-Y,1/2-Z,X
 1/4+Y,1/4+X,1/4-Z
 3/4-Y,1/4-X,3/4-Z
 3/4+Y,3/4-X,1/4+Z
 1/4-Y,3/4+X,3/4+Z
 1/4+X,1/4+Z,1/4-Y
 1/4-X,3/4+Z,3/4+Y
 3/4-X,1/4-Z,3/4-Y
 3/4+X,3/4-Z,1/4+Y
 1/4+Z,1/4+Y,1/4-X
 3/4+Z,3/4-Y,1/4+X
 1/4-Z,3/4+Y,3/4+X
 3/4-Z,1/4-Y,3/4-X
 3/4-X,1/4-Y,3/4-Z
 3/4+X,3/4+Y,1/4-Z
 1/4+X,3/4-Y,3/4+Z
 1/4-X,1/4+Y,1/4+Z
 3/4-Z,1/4-X,3/4-Y
 1/4-Z,1/4+X,1/4+Y
 3/4+Z,3/4+X,1/4-Y
 1/4+Z,3/4-X,3/4+Y
 3/4-Y,1/4-Z,3/4-X
 1/4+Y,3/4-Z,3/4+X
 1/4-Y,1/4+Z,1/4+X
 3/4+Y,3/4+Z,1/4-X
 -Y,-X,Z
 1/2+Y,X,1/2+Z
 1/2-Y,1/2+X,-Z
 Y,1/2-X,1/2-Z
 -X,-Z,Y
 X,1/2-Z,1/2-Y
 1/2+X,Z,1/2+Y
 1/2-X,1/2+Z,-Y
 -Z,-Y,X
 1/2-Z,1/2+Y,-X
 Z,1/2-Y,1/2-X
 1/2+Z,Y,1/2+X
 1/2+X,1/2+Y,Z
 1/2-X,-Y,1/2+Z
 -X,Y,-Z
 X,1/2-Y,1/2-Z
 1/2+Z,1/2+X,Y
 Z,1/2-X,1/2-Y
 1/2-Z,-X,1/2+Y
 -Z,X,-Y
 1/2+Y,1/2+Z,X
 -Y,Z,-X
 Y,1/2-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/4+Y,3/4+X,3/4-Z
 3/4-Y,3/4-X,1/4-Z
 3/4+Y,1/4-X,3/4+Z
 1/4-Y,1/4+X,1/4+Z
 1/4+X,3/4+Z,3/4-Y
 1/4-X,1/4+Z,1/4+Y
 3/4-X,3/4-Z,1/4-Y
 3/4+X,1/4-Z,3/4+Y
 1/4+Z,3/4+Y,3/4-X
 3/4+Z,1/4-Y,3/4+X
 1/4-Z,1/4+Y,1/4+X
 3/4-Z,3/4-Y,1/4-X
 3/4-X,3/4-Y,1/4-Z
 3/4+X,1/4+Y,3/4-Z
 1/4+X,1/4-Y,1/4+Z
 1/4-X,3/4+Y,3/4+Z
 3/4-Z,3/4-X,1/4-Y
 1/4-Z,3/4+X,3/4+Y
 3/4+Z,1/4+X,3/4-Y
 1/4+Z,1/4-X,1/4+Y
 3/4-Y,3/4-Z,1/4-X
 1/4+Y,1/4-Z,1/4+X
 1/4-Y,3/4+Z,3/4+X
 3/4+Y,1/4+Z,3/4-X
 -Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,Z
 1/2-Y,X,1/2-Z
 Y,-X,-Z
 -X,1/2-Z,1/2+Y
 X,-Z,-Y
 1/2+X,1/2+Z,Y
 1/2-X,Z,1/2-Y
 -Z,1/2-Y,1/2+X
 1/2-Z,Y,1/2-X
 Z,-Y,-X
 1/2+Z,1/2+Y,X
228 192 48 Fd-3c PGm3barm CUBIC
 X,Y,Z
 -X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,-Z
 1/2+X,-Y,1/2-Z
 Z,X,Y
 1/2+Z,-X,1/2-Y
 -Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,-Y
 Y,Z,X
 1/2-Y,1/2+Z,-X
 1/2+Y,-Z,1/2-X
 -Y,1/2-Z,1/2+X
 3/4+Y,1/4+X,3/4-Z
 1/4-Y,1/4-X,1/4-Z
 1/4+Y,3/4-X,3/4+Z
 3/4-Y,3/4+X,1/4+Z
 3/4+X,1/4+Z,3/4-Y
 3/4-X,3/4+Z,1/4+Y
 1/4-X,1/4-Z,1/4-Y
 1/4+X,3/4-Z,3/4+Y
 3/4+Z,1/4+Y,3/4-X
 1/4+Z,3/4-Y,3/4+X
 3/4-Z,3/4+Y,1/4+X
 1/4-Z,1/4-Y,1/4-X
 3/4-X,3/4-Y,3/4-Z
 3/4+X,1/4+Y,1/4-Z
 1/4+X,1/4-Y,3/4+Z
 1/4-X,3/4+Y,1/4+Z
 3/4-Z,3/4-X,3/4-Y
 1/4-Z,3/4+X,1/4+Y
 3/4+Z,1/4+X,1/4-Y
 1/4+Z,1/4-X,3/4+Y
 3/4-Y,3/4-Z,3/4-X
 1/4+Y,1/4-Z,3/4+X
 1/4-Y,3/4+Z,1/4+X
 3/4+Y,1/4+Z,1/4-X
 -Y,1/2-X,Z
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,X,-Z
 Y,-X,1/2-Z
 -X,1/2-Z,Y
 X,-Z,1/2-Y
 1/2+X,1/2+Z,1/2+Y
 1/2-X,Z,-Y
 -Z,1/2-Y,X
 1/2-Z,Y,-X
 Z,-Y,1/2-X
 1/2+Z,1/2+Y,1/2+X
 X,1/2+Y,1/2+Z
 -X,-Y,Z
 1/2-X,Y,1/2-Z
 1/2+X,1/2-Y,-Z
 Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,-Y
 -Z,-X,Y
 1/2-Z,X,1/2-Y
 Y,1/2+Z,1/2+X
 1/2-Y,Z,1/2-X
 1/2+Y,1/2-Z,-X
 -Y,-Z,X
 3/4+Y,3/4+X,1/4-Z
 1/4-Y,3/4-X,3/4-Z
 1/4+Y,1/4-X,1/4+Z
 3/4-Y,1/4+X,3/4+Z
 3/4+X,3/4+Z,1/4-Y
 3/4-X,1/4+Z,3/4+Y
 1/4-X,3/4-Z,3/4-Y
 1/4+X,1/4-Z,1/4+Y
 3/4+Z,3/4+Y,1/4-X
 1/4+Z,1/4-Y,1/4+X
 3/4-Z,1/4+Y,3/4+X
 1/4-Z,3/4-Y,3/4-X
 3/4-X,1/4-Y,1/4-Z
 3/4+X,3/4+Y,3/4-Z
 1/4+X,3/4-Y,1/4+Z
 1/4-X,1/4+Y,3/4+Z
 3/4-Z,1/4-X,1/4-Y
 1/4-Z,1/4+X,3/4+Y
 3/4+Z,3/4+X,3/4-Y
 1/4+Z,3/4-X,1/4+Y
 3/4-Y,1/4-Z,1/4-X
 1/4+Y,3/4-Z,1/4+X
 1/4-Y,1/4+Z,3/4+X
 3/4+Y,3/4+Z,3/4-X
 -Y,-X,1/2+Z
 1/2+Y,X,Z
 1/2-Y,1/2+X,1/2-Z
 Y,1/2-X,-Z
 -X,-Z,1/2+Y
 X,1/2-Z,-Y
 1/2+X,Z,Y
 1/2-X,1/2+Z,1/2-Y
 -Z,-Y,1/2+X
 1/2-Z,1/2+Y,1/2-X
 Z,1/2-Y,-X
 1/2+Z,Y,X
 1/2+X,Y,1/2+Z
 1/2-X,1/2-Y,Z
 -X,1/2+Y,1/2-Z
 X,-Y,-Z
 1/2+Z,X,1/2+Y
 Z,-X,-Y
 1/2-Z,1/2-X,Y
 -Z,1/2+X,1/2-Y
 1/2+Y,Z,1/2+X
 -Y,1/2+Z,1/2-X
 Y,-Z,-X
 1/2-Y,1/2-Z,X
 1/4+Y,1/4+X,1/4-Z
 3/4-Y,1/4-X,3/4-Z
 3/4+Y,3/4-X,1/4+Z
 1/4-Y,3/4+X,3/4+Z
 1/4+X,1/4+Z,1/4-Y
 1/4-X,3/4+Z,3/4+Y
 3/4-X,1/4-Z,3/4-Y
 3/4+X,3/4-Z,1/4+Y
 1/4+Z,1/4+Y,1/4-X
 3/4+Z,3/4-Y,1/4+X
 1/4-Z,3/4+Y,3/4+X
 3/4-Z,1/4-Y,3/4-X
 1/4-X,3/4-Y,1/4-Z
 1/4+X,1/4+Y,3/4-Z
 3/4+X,1/4-Y,1/4+Z
 3/4-X,3/4+Y,3/4+Z
 1/4-Z,3/4-X,1/4-Y
 3/4-Z,3/4+X,3/4+Y
 1/4+Z,1/4+X,3/4-Y
 3/4+Z,1/4-X,1/4+Y
 1/4-Y,3/4-Z,1/4-X
 3/4+Y,1/4-Z,1/4+X
 3/4-Y,3/4+Z,3/4+X
 1/4+Y,1/4+Z,3/4-X
 1/2-Y,1/2-X,1/2+Z
 Y,1/2+X,Z
 -Y,X,1/2-Z
 1/2+Y,-X,-Z
 1/2-X,1/2-Z,1/2+Y
 1/2+X,-Z,-Y
 X,1/2+Z,Y
 -X,Z,1/2-Y
 1/2-Z,1/2-Y,1/2+X
 -Z,Y,1/2-X
 1/2+Z,-Y,-X
 Z,1/2+Y,X
 1/2+X,1/2+Y,Z
 1/2-X,-Y,1/2+Z
 -X,Y,-Z
 X,1/2-Y,1/2-Z
 1/2+Z,1/2+X,Y
 Z,1/2-X,1/2-Y
 1/2-Z,-X,1/2+Y
 -Z,X,-Y
 1/2+Y,1/2+Z,X
 -Y,Z,-X
 Y,1/2-Z,1/2-X
 1/2-Y,-Z,1/2+X
 1/4+Y,3/4+X,3/4-Z
 3/4-Y,3/4-X,1/4-Z
 3/4+Y,1/4-X,3/4+Z
 1/4-Y,1/4+X,1/4+Z
 1/4+X,3/4+Z,3/4-Y
 1/4-X,1/4+Z,1/4+Y
 3/4-X,3/4-Z,1/4-Y
 3/4+X,1/4-Z,3/4+Y
 1/4+Z,3/4+Y,3/4-X
 3/4+Z,1/4-Y,3/4+X
 1/4-Z,1/4+Y,1/4+X
 3/4-Z,3/4-Y,1/4-X
 1/4-X,1/4-Y,3/4-Z
 1/4+X,3/4+Y,1/4-Z
 3/4+X,3/4-Y,3/4+Z
 3/4-X,1/4+Y,1/4+Z
 1/4-Z,1/4-X,3/4-Y
 3/4-Z,1/4+X,1/4+Y
 1/4+Z,3/4+X,1/4-Y
 3/4+Z,3/4-X,3/4+Y
 1/4-Y,1/4-Z,3/4-X
 3/4+Y,3/4-Z,3/4+X
 3/4-Y,1/4+Z,1/4+X
 1/4+Y,3/4+Z,1/4-X
 1/2-Y,-X,Z
 Y,X,1/2+Z
 -Y,1/2+X,-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-X,-Z,Y
 1/2+X,1/2-Z,1/2-Y
 X,Z,1/2+Y
 -X,1/2+Z,-Y
 1/2-Z,-Y,X
 -Z,1/2+Y,-X
 1/2+Z,1/2-Y,1/2-X
 Z,Y,1/2+X
229 96 48 Im-3m PGm3barm CUBIC
 X,Y,Z
 -X,-Y,Z
 -X,Y,-Z
 X,-Y,-Z
 Z,X,Y
 Z,-X,-Y
 -Z,-X,Y
 -Z,X,-Y
 Y,Z,X
 -Y,Z,-X
 Y,-Z,-X
 -Y,-Z,X
 Y,X,-Z
 -Y,-X,-Z
 Y,-X,Z
 -Y,X,Z
 X,Z,-Y
 -X,Z,Y
 -X,-Z,-Y
 X,-Z,Y
 Z,Y,-X
 Z,-Y,X
 -Z,Y,X
 -Z,-Y,-X
 -X,-Y,-Z
 X,Y,-Z
 X,-Y,Z
 -X,Y,Z
 -Z,-X,-Y
 -Z,X,Y
 Z,X,-Y
 Z,-X,Y
 -Y,-Z,-X
 Y,-Z,X
 -Y,Z,X
 Y,Z,-X
 -Y,-X,Z
 Y,X,Z
 -Y,X,-Z
 Y,-X,-Z
 -X,-Z,Y
 X,-Z,-Y
 X,Z,Y
 -X,Z,-Y
 -Z,-Y,X
 -Z,Y,-X
 Z,-Y,-X
 Z,Y,X
 1/2+X,1/2+Y,1/2+Z
 1/2-X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2+Z,1/2+X,1/2+Y
 1/2+Z,1/2-X,1/2-Y
 1/2-Z,1/2-X,1/2+Y
 1/2-Z,1/2+X,1/2-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,1/2-X
 1/2-Y,1/2-Z,1/2+X
 1/2+Y,1/2+X,1/2-Z
 1/2-Y,1/2-X,1/2-Z
 1/2+Y,1/2-X,1/2+Z
 1/2-Y,1/2+X,1/2+Z
 1/2+X,1/2+Z,1/2-Y
 1/2-X,1/2+Z,1/2+Y
 1/2-X,1/2-Z,1/2-Y
 1/2+X,1/2-Z,1/2+Y
 1/2+Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2+X
 1/2-Z,1/2-Y,1/2-X
 1/2-X,1/2-Y,1/2-Z
 1/2+X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,1/2+Z
 1/2-Z,1/2-X,1/2-Y
 1/2-Z,1/2+X,1/2+Y
 1/2+Z,1/2+X,1/2-Y
 1/2+Z,1/2-X,1/2+Y
 1/2-Y,1/2-Z,1/2-X
 1/2+Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,1/2+X
 1/2+Y,1/2+Z,1/2-X
 1/2-Y,1/2-X,1/2+Z
 1/2+Y,1/2+X,1/2+Z
 1/2-Y,1/2+X,1/2-Z
 1/2+Y,1/2-X,1/2-Z
 1/2-X,1/2-Z,1/2+Y
 1/2+X,1/2-Z,1/2-Y
 1/2+X,1/2+Z,1/2+Y
 1/2-X,1/2+Z,1/2-Y
 1/2-Z,1/2-Y,1/2+X
 1/2-Z,1/2+Y,1/2-X
 1/2+Z,1/2-Y,1/2-X
 1/2+Z,1/2+Y,1/2+X
230 96 48 Ia-3d PGm3barm CUBIC
 X,Y,Z
 1/2-X,-Y,1/2+Z
 -X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,-Z
 Z,X,Y
 1/2+Z,1/2-X,-Y
 1/2-Z,-X,1/2+Y
 -Z,1/2+X,1/2-Y
 Y,Z,X
 -Y,1/2+Z,1/2-X
 1/2+Y,1/2-Z,-X
 1/2-Y,-Z,1/2+X
 3/4+Y,1/4+X,1/4-Z
 3/4-Y,3/4-X,3/4-Z
 1/4+Y,1/4-X,3/4+Z
 1/4-Y,3/4+X,1/4+Z
 3/4+X,1/4+Z,1/4-Y
 1/4-X,3/4+Z,1/4+Y
 3/4-X,3/4-Z,3/4-Y
 1/4+X,1/4-Z,3/4+Y
 3/4+Z,1/4+Y,1/4-X
 1/4+Z,1/4-Y,3/4+X
 1/4-Z,3/4+Y,1/4+X
 3/4-Z,3/4-Y,3/4-X
 -X,-Y,-Z
 1/2+X,Y,1/2-Z
 X,1/2-Y,1/2+Z
 1/2-X,1/2+Y,Z
 -Z,-X,-Y
 1/2-Z,1/2+X,Y
 1/2+Z,X,1/2-Y
 Z,1/2-X,1/2+Y
 -Y,-Z,-X
 Y,1/2-Z,1/2+X
 1/2-Y,1/2+Z,X
 1/2+Y,Z,1/2-X
 1/4-Y,3/4-X,3/4+Z
 1/4+Y,1/4+X,1/4+Z
 3/4-Y,3/4+X,1/4-Z
 3/4+Y,1/4-X,3/4-Z
 1/4-X,3/4-Z,3/4+Y
 3/4+X,1/4-Z,3/4-Y
 1/4+X,1/4+Z,1/4+Y
 3/4-X,3/4+Z,1/4-Y
 1/4-Z,3/4-Y,3/4+X
 3/4-Z,3/4+Y,1/4-X
 3/4+Z,1/4-Y,3/4-X
 1/4+Z,1/4+Y,1/4+X
 1/2+X,1/2+Y,1/2+Z
 -X,1/2-Y,Z
 1/2-X,Y,-Z
 X,-Y,1/2-Z
 1/2+Z,1/2+X,1/2+Y
 Z,-X,1/2-Y
 -Z,1/2-X,Y
 1/2-Z,X,-Y
 1/2+Y,1/2+Z,1/2+X
 1/2-Y,Z,-X
 Y,-Z,1/2-X
 -Y,1/2-Z,X
 1/4+Y,3/4+X,3/4-Z
 1/4-Y,1/4-X,1/4-Z
 3/4+Y,3/4-X,1/4+Z
 3/4-Y,1/4+X,3/4+Z
 1/4+X,3/4+Z,3/4-Y
 3/4-X,1/4+Z,3/4+Y
 1/4-X,1/4-Z,1/4-Y
 3/4+X,3/4-Z,1/4+Y
 1/4+Z,3/4+Y,3/4-X
 3/4+Z,3/4-Y,1/4+X
 3/4-Z,1/4+Y,3/4+X
 1/4-Z,1/4-Y,1/4-X
 1/2-X,1/2-Y,1/2-Z
 X,1/2+Y,-Z
 1/2+X,-Y,Z
 -X,Y,1/2+Z
 1/2-Z,1/2-X,1/2-Y
 -Z,X,1/2+Y
 Z,1/2+X,-Y
 1/2+Z,-X,Y
 1/2-Y,1/2-Z,1/2-X
 1/2+Y,-Z,X
 -Y,Z,1/2+X
 Y,1/2+Z,-X
 3/4-Y,1/4-X,1/4+Z
 3/4+Y,3/4+X,3/4+Z
 1/4-Y,1/4+X,3/4-Z
 1/4+Y,3/4-X,1/4-Z
 3/4-X,1/4-Z,1/4+Y
 1/4+X,3/4-Z,1/4-Y
 3/4+X,3/4+Z,3/4+Y
 1/4-X,1/4+Z,3/4-Y
 3/4-Z,1/4-Y,1/4+X
 1/4-Z,1/4+Y,3/4-X
 1/4+Z,3/4-Y,1/4-X
 3/4+Z,3/4+Y,3/4+X
EOF-symoplib


cat << EOF-environ >! \${CINCL}/environ.def
# minimized environ.def
#
ABCOEFFS=inout.coeff            # Optional Fourier terms (fft)
ABSIN=in.dat                    # absorption data (absurd)
BADSPOT=inout.spt               # mosflm
CROSSECDATA=in.lib              # crossec
GENFILE=inout.gen               # abscale, oscgen (mosflm distrib)
HKLIN=in.mtz                    # general reflexion i/p file
HKLOUT=out.mtz                  # general reflexion o/p file
PMOSFLMDAT=in.dat               # mosflm
PROFILE=inout.prf               # mosflm
SYMOP=in.lib                    # symlib
SPOTOD=inout.od                 # mosflm
SUMMARY=out.sum                 # mosflm

EOF-environ


cat << EOF-default >! \${CINCL}/default.def
# minimized default.def

ABCOEFFS=fftkw.abcoeffs         # fft
ATS=ATS.scr
BADSPOT=badspot.scr             # mosflm
CROSSECDATA=crossec.lib         # crossec
DISKIO1=IO1.scr
DISKIO2=IO2.scr
HISTLIB=hist.lib                # dm
FFTHKLSCR=IO4.scr               # fft, sfall
SD1=SD1.scr                     # ?
SD2=SD2.scr                     # ?
SYMOP=symop.lib                 # symlib
TEMP=temp.scr

EOF-default

goto ReturnFrom_DumpSymopLib


#########################################################################################
The Future:

TODO:
"alternative" beam center list?
de-novo beam centering
support external spot list
update merge.com reindexing
install ginger
don't "refine" two_theta angle from TILT?

MAYBE:
separate refine.com and integ.com scripts?
preemtive spot pick for autoindexing?
do "next wedge" question at end.
true postrefinement (after scaling)


EOF-Wedger
chmod a+x ${Elfsheim}/Wedger

echo -n "."





















































# Scaler
cat << EOF-Scaler >! ${Elfsheim}/Scaler
#! /bin/csh -f
#
echo "Scaler Elves v 1.3.6    Because you have better things to do.(TM)   James Holton 6-17-12"
echo ""
#
#   Intelligently scale data from several wavelengths/runs against each other, 
#   And then merge each wavelength separately.
#
#   Accepts input from mosflm (*.mtz) or denzo (*.x) and
#   Produces output files suitable for SHELX, SHARP, SOLVE, and X-PLOR.
#
# Try it!  Let me know what you think.
#
#   jamesh@ucxray.berkeley.edu
#
set temp = \`find \$0 -mtime +30 -print\`
if(("\$temp" == "")&&(\$#argv == 0)) cat << EOF-lawyers
Copyright 1999. The Regents of the University of California (Regents). All Rights Reserved. 

     Permission to use, copy, modify, and distribute this software and its 
     documentation for educational, research, and not-for-profit purposes, 
     without fee and without a signed licensing agreement, is hereby granted, 
     provided that the above copyright notice, this paragraph and the following 
     two paragraphs appear in all copies, modifications, and distributions. 
     Contact The Office of Technology Licensing, UC Berkeley, 2150 Shattuck 
     Avenue, Suite 510, Berkeley, CA 94720-1620, (510) 643-7201, for commercial 
     licensing opportunities. Created by James Holton, Department of Molecular 
     and Cell Biology, University of California, Berkeley. 
  
     IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 
     SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, 
     ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 
     REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  
     REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED 
     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
     PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 
     HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
     MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 

EOF-lawyers
#
#   upon its distribution, this file was:
#	lines: 15436
#	bytes: 434403
#   altered versions are not supported by JMH
#   
#   
############################################################################

###############################################################################
#
#   Evaluate unix system
#
###############################################################################
# make sure nawk works
set program = "nawk"
foreach name ( nawk awk gawk )
    test -x "\$program"
    if(! \$status) break
    
    set possibilities = \`which \$name |& grep -v ' not in ' | tail -1\`
    foreach file ( \$possibilities )
	test -x "\$file"
	if(! \$status) then
	    # test for desired functionality (change this?)
	    set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
	    if("\$temp" == 856) then
		set program = "\$file"
		break
	    endif
	endif
    end
    unset possibilities
end
test -x "\$program"
if(\$status) then
    set program = "awk"
    foreach place ( /bin /usr/bin /usr/local/bin  )
	test -x "\$program"
	if((\$status)&&(-e \$place)) then
	    # keep looking
	    set files = \`ls -1L \${place} |& grep "\$program" |& sort -k5n |& head -20 \`
	    foreach file ( \$files )
		# test for desired functionality
		set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
		if("\$temp" == 856) then
		    set program = "\$file"
		    break
		endif
	    end
	endif
    end
endif

# agressively search for nawk in likely places
test -x "\$program"
if(\$status) then
    echo -n "Looking for \$program "
    foreach place ( /bin /usr/bin /usr/local/bin /usr / )
	test -x "\$program"
	if((\$status)&&(-e \$place)) then
	    if("\$place" == "/") echo -n "uhh"
	    
	    # use find to get candidate files
	    set files = \`find \$place -name '*'\$program \\( -type l -o \\( -type f -size +10000c \\) \\) -perm -1 -print |& egrep -v "^find:" |& head -20\`
	    foreach file ( \$files )
		# test for desired functionality
		set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
		if("\$temp" == 856) then
		    set program = "\$file"
		    break
		endif
	    end
	endif
	
	# entertainment
	echo -n "."
    end
endif

# check that we found the right program
set temp = \`echo "1.54" | \$program '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
if("\$temp" == 856) then
    # set up this awk program as nawk
    set nawk = "\$program"
    alias nawk \$nawk
else
    echo "Dagnabbit!  We can't find a suitable awk program.  What kind of unix is this? "
    echo "Elves may not be able to work."
    set nawk = /bin/awk
    alias nawk awk
endif

# nice symbols, but may not be portable
set ANG = \`echo "" | nawk 'BEGIN{printf "\\305"}'\`
set DEG = \`echo "" | nawk 'BEGIN{printf "\\260"}'\`
set ANG = "A"
set DEG = "deg"

# fix OSF1 csh echo shortcomings
set temp = \`echo -n "test"\`
if((\$#temp == 2)&&(-e /usr/bin/echo)) then
    alias echo /usr/bin/echo
endif

if(! \$?CCP4) then
    echo -n "Attempting to set up CCP4 ... "

    set ccp4setup = ""
    foreach place ( /programs/xtal/ /usr/xtal/ /programs/xtal /programs/ /usr/xtal /usr/local /usr/ )
	if((! -e "\$ccp4setup")&&(-e "\$place")) then
	    # look for setup scripts here
	    set ccp4setup = \`find \${place} -name ccp4.setup |& nawk '/ccp4.setup\$/{print \$NF}' | tail -1\`
	endif
        if((-e "\$ccp4setup")&&(! \$?CCP4)) then
            source \$ccp4setup
            setenv CCP4_SCR    .
            setenv BINSORT_SCR .
            echo "using \$ccp4setup"
        endif
    end
endif
if(! \$?CCP4) then
    echo "failed."
    echo "Please ask your sysadmin how to set up CCP4, "
    echo "Or go to: netscape http://www.dl.ac.uk/CCP/CCP4/main.html"
    echo "about getting the CCP4 program suite."
    echo "and run \$0 again."
    
    echo "If you have Red Hat Linux, you can get ccp4 by typing:"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-lib-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-progs-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-etc-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-examples-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-doc-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-manual-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-html-3.5.1-5.i386.rpm"
    exit 9
    set CCP4_LIB
endif
setenv CCP4_OPEN       UNKNOWN
# make sure we can write to scratch directories
if(! \$?CCP4_SCR) setenv CCP4_SCR .
if(! \$?BINSORT_SCR) setenv BINSORT_SCR .
if(! \$?CDOC) setenv CDOC

touch \${CCP4_SCR}/this\$\$ >& /dev/null
if(\$status) then
    # safest to do this
    setenv CCP4_SCR .
endif
rm -f \${CCP4_SCR}/this\$\$ >& /dev/null

touch \${BINSORT_SCR}/this\$\$ >& /dev/null
if(\$status) then
    # safest to do this
    setenv BINSORT_SCR .
endif
rm -f \${BINSORT_SCR}/this\$\$ >& /dev/null


# check that current directory is writable
touch ./this\$\$ >& /dev/null
if(\$status) then
    # can't write to current directory!
    chmod u+w . >& /dev/null
    touch ./this\$\$ >& /dev/null
    if(\$status) then
	# can't chmod current directory either
	echo "ERROR! We can't write to this directory!"
	pwd
	echo "Please cd to the place you want to process your data, and"
	echo "then run \$0 again."
	exit 9
    else
	# warn user about what we did
	echo "Had to make current directory writable:"
	echo "chmod u+w ."
    endif
    rm -f ./this\$\$ >& /dev/null
endif
rm -f ./this\$\$ >& /dev/null

# no dumping! 
limit coredumpsize 0

# go automatic if user is ignoring us
test -t 1
if(\$status) then
    echo "output is not a terminal."
    # Q&A would stop process cold
    echo "Elves will answer their own questions."
    echo ""
    echo "\$0 \$*"
    echo "on "\`hostname -s\`" at "\`date +"%T %D"\`
    echo "in "\`pwd\`
    set AUTO
endif

###############################################################################

 #####   ######  ######    ##    #    #  #        #####   ####
 #    #  #       #        #  #   #    #  #          #    #
 #    #  #####   #####   #    #  #    #  #          #     ####
 #    #  #       #       ######  #    #  #          #         #
 #    #  #       #       #    #  #    #  #          #    #    #
 #####   ######  #       #    #   ####   ######     #     ####

###############################################################################
#
#   Default values for all parameters
#
###############################################################################
#
# crystal variables
set SG         = "unknown"
set CELL       = "unknown"
set MASS       = "unknown"
set CHAINS     = ""
set Vm         = "2.4"
set METAL      = ""
set Ee         = ""
set SITES      = ""
set hiRES      = ""
set loRES      = "1000"
#
# misc program settings
set TITLE         = "Scaler Elves"
set defaultSDCORR = "1.3 0 0.03"
set SPACING       = 10
set CYCLES        = 100
set EXTRA_ARGS    = ""
set USE_VRSET     = "#"
set SCALING       = batch
set BFACTOR       = batch
set ref_batch	  = 1
set wavenames
set wavelengths
set wave_reference
#
# Files generated by this script
set SCRIPT_dir = ./scripts
set LOG_dir    = ./logs
set TEMP_dir   = \$CCP4_SCR

set MTZ_dir    = ./mtz
set MAP_dir    = ./maps
set SHARP_dir  = ./mtz
set SOLVE_dir  = ./SOLVE
set SHELX_dir  = ./SHELX 
set XPLOR_dir  = ./XPLOR

# prefixes
set RUNFILE   = ./runlist.txt
set RULESFILE = ./rules.txt
set temp = \`basename \$0\`
set logfile   = \${LOG_dir}/
#set tempfile   = \$CCP4_SCR/tempfile
set tempfile   = "\${CCP4_SCR}/scaler_temp\$\$."

# customize file names? 
set rawMTZ     = \${MTZ_dir}/rawdata.mtz
set refMTZ     = \${MTZ_dir}/reference.mtz
set sortMTZ    = \${MTZ_dir}/sorted_ref.mtz
set rscaleMTZ  = \${MTZ_dir}/rough_scaled.mtz
set lscaleMTZ  = \${MTZ_dir}/localscaled.mtz
set finalMTZ   = \${MTZ_dir}/all.mtz

set sortLOG    = \${LOG_dir}/sorting.log
set refLOG     = \${LOG_dir}/make_reference_set.log
set rscaleLOG  = \${LOG_dir}/rough_scale.log
set lscaleLOG  = \${LOG_dir}/localscale.log
set finalLOG   = \${LOG_dir}/scaleit.log
set mergeLOG   = \${LOG_dir}/merge_
set extractLOG = \${LOG_dir}/extract_
set lastLOG    = \${rscaleLOG}

# might as well give these sensible values
set refMTZset  = "IMEAN SIGIMEAN"
set freeR_source = "5%"

# random internal settings
set MAXLINE    = 500
set PROMPT     = "S. Elves-> "
set BELL       = \`echo "" | awk 'BEGIN{printf "\\07"}'\`
set FIRSTIME
set NEW
set temp
set input
set info
set in
set baddirs
set otherSGs
set FRUGAL
set FIX_PROBLEMS

# clear any old temporary files
rm -f \${tempfile}* >& /dev/null
#rm -f \$RUNFILE
# accumulate rules?
rm -f \$RULESFILE

# sneaky: try to get SDCORR from Wedger runs
egrep -hi "^SDCORR" */*/merge.com |&\\
nawk 'toupper(\$0) ~ /^SDCORR/{print \$2, \$3, \$4}' |\\
nawk 'NF==2 || NF==3{sdfac+=\$1;sdadd+=\$NF; ++count} \\
      NF==3{sdB+=\$2;++countB} END{if(countB)sdB/=countB; \\
      if(count) printf "%.2f %.1f %.2f\\n", sdfac/count, sdB, sdadd/count}' |\\
cat >! \${tempfile}
set temp = \`nawk 'NF==3' \${tempfile}\`
if(\$#temp == 3) set defaultSDCORR = "\$temp"
rm -f \${tempfile} >& /dev/null


goto Unwrap_Awk_Scripts
# create \${tempfile}sequencer.awk
# create \${tempfile}elements.awk
# create \${tempfile}ginger.awk
# create \${tempfile}labler.awk
# create \${tempfile}parser.awk
Return_Unwrap_Awk_Scripts:



CommandLine:
###############################################################################
#
#   Process command line
#
###############################################################################
# create \${tempfile}input containing command-line args

if(\$#argv > 50) then
    # warn user about too many args slowing us down
    echo "Long command line... one moment."
endif

# dump command line into a temporary file (to avoid "word too long" errors)
echo -n "" >! \${tempfile}input
set i = 0
while(\$i < \$#argv)
    @ i = ( \$i + 1 )

    # make each word a line (for now)
    echo "\$argv[\$i]" >> \${tempfile}input
end
# now make lines as long as possible
cat \${tempfile}input |\\
nawk -v L=\$MAXLINE '{l+=length(\$0)+2; if(l>L){print ""; l=0}; printf " %s ", \$0}' |\\
cat >! \${tempfile}longlines
mv \${tempfile}longlines \${tempfile}input


# now check immediately important command-line options
if(\$#argv != 0) then
    # add final newline
    echo "" >> \${tempfile}input

    # check for cries for help
    grep " help " \${tempfile}input >& /dev/null
    if(! \$status) goto Help
    if("\$argv[\$#argv]" =~ *"\\?") goto Help
    
    # requests to pick up where we left off
    grep " pick up " \${tempfile}input >& /dev/null
    if(! \$status) unset NEW
    grep " -pickup " \${tempfile}input >& /dev/null
    if(! \$status) unset NEW
    
    # and requests to skip the pickup lines
    grep " new " \${tempfile}input >& /dev/null
    if(! \$status) set NEW
    grep " -new " \${tempfile}input >& /dev/null
    if(! \$status) set NEW
    
    if(! \$?NEW) goto Pickup
    goto Gather
endif
goto Help


Help:
################################################################################

 #    #  ######  #       #####
 #    #  #       #       #    #
 ######  #####   #       #    #
 #    #  #       #       #####
 #    #  #       #       #
 #    #  ######  ######  #

################################################################################
#	Online help routine
#
#	uses words contained in \${tempfile}input to determine what user wants
################################################################################
cat << EOF

usage: \$0 [sentence about your project]

where:
[sentence about your project]	is something like:
files called */raw.mtz are 2A data of a 22kD protein with six Se sites per chain

you can also keep all this information in a file, and give that file
to \$0 instead of a sentence

EOF

# insert online help code here

set input = ""
set temp = "no"
echo "Any other questions? [\$temp]"
echo -n "\$PROMPT"
echo -n "\$BELL"
if(\$?AUTO) then
    echo "\$temp"
else
    set in = "\$<"
    if("\$in" != "") set input = "\$in"    
endif
unset NEW
goto Pickup

Pickup:
if(\$?NEW) goto Gather
###############################################################################

 #####      #     ####   #    #  #    #  #####
 #    #     #    #    #  #   #   #    #  #    #
 #    #     #    #       ####    #    #  #    #
 #####      #    #       #  #    #    #  #####
 #          #    #    #  #   #   #    #  #
 #          #     ####   #    #   ####   #

###############################################################################
#
#   "Pick-up" info from last scala scripts
#
###############################################################################
# collect a list of likely "pickup" files
echo -n "looking for scala scripts ."
onintr SkipPickup
echo "" >! \${tempfile}sources
echo "" >! \${tempfile}pickuplines
unset USEFUL

foreach place ( ./ \${SCRIPT_dir}/  )
    test -d \$place
    if(! \$status) then
	# get small files in this directory
	ls -lnrt \${place} |& nawk -v dir=\$place '\$5 < 100000{print dir \$NF}' |&\\
	cat >> \${tempfile}sources
    endif

    # entertainment
    echo -n "."
end

# clean up filename list
mv \${tempfile}sources \${tempfile}
nawk 'NF==1' \${tempfile} >! \${tempfile}sources

# go through files, looking for scala cards
set files = \`cat \${tempfile}sources | wc -l\`
set i = 1
while( \$i <= \$files )
    # get ith filename from the bottom of the list
    set file = \`head -\$i \${tempfile}sources | tail -1\`

    if(-e "\$file") then
	# grab probable scala cards (except ones we handle internally)
	nawk '/^scala/,/^EOF/{print toupper(\$0)}' "\$file" |&\\
	egrep "^SDCORR|^INTENS|^PARTIALS|^REJECT|^SMOOTH|^DAMP|^FILTER|^BINS|^PRINT|^TIE|^ANALYZE" |\\
	grep -v "ANOM" |\\
	nawk '! /^#/{card[\$1]=\$0} END{for(x in card) print card[x]}' |\\
	cat >! \${tempfile}cards
    endif

    # see if we got anything
    test -s \${tempfile}cards
    if(! \$status) then
	echo " \$file"
	cat \${tempfile}cards >> \${tempfile}pickuplines
	
	set USEFUL
	set CHECK_SCALA_CARDS
    endif

    # entertainment
    echo -n "."

    @ i = ( \$i + 1 )
end

# simplefy, uniqueify and process the "pickup" lines
cat \${tempfile}pickuplines |\\
nawk 'NF>1{for(i=1;i<=NF && (\$i !~ /^#/);++i){printf "%s ", \$i}; print ""}' |\\
sort -u >! \${tempfile}lines

# update rules file
cat \${tempfile}lines >> \$RULESFILE

if(! \$?USEFUL) then
    echo -n "didn't find anything."
else
    set FOUND_SOMETHING
endif
echo ""

SkipPickup:
onintr

if(! \$?FOUND_SOMETHING) then
    # message if we skipped ahead
    echo "skipped."
    echo "use:"
    echo " \$0 \$* -new"
    echo " to prevent this search alltogether."
endif

#clean up temporary files
rm -f \${tempfile}lines       >& /dev/null
rm -f \${tempfile}cards       >& /dev/null
rm -f \${tempfile}pickuplines >& /dev/null
rm -f \${tempfile}sources     >& /dev/null


goto Gather
# appease onintr bugs
end
endif
end
endif



Gather:
onintr
###############################################################################

  ####     ##     #####  #    #  ######  #####
 #    #   #  #      #    #    #  #       #    #
 #       #    #     #    ######  #####   #    #
 #  ###  ######     #    #    #  #       #####
 #    #  #    #     #    #    #  #       #   #
  ####   #    #     #    #    #  ######  #    #

###############################################################################
#
#   Gather info indicated in \$input and/or \${tempfile}input
#
###############################################################################
rm -f \${tempfile}mtzs \${tempfile}elvish >& /dev/null
touch \${tempfile}mtzs
touch \${tempfile}xfiles
touch \${tempfile}batches
touch \${tempfile}elvish
touch \${tempfile}sequence
touch \${tempfile}input
touch \$RULESFILE
touch \$RUNFILE
set understood = ""



###############################################################################
# convert all inputs into a file
set input = ( \$input )
# input variable overrides the file
if(\$#input != 0) then
    echo " \$input " >! \${tempfile}input
endif

# Backup question: querry user about empty input
set temp = \`cat \${tempfile}input | wc -l\`
if(\$temp == 0) then
    # backup, default question
    set temp = "nothing"
    echo "What's wrong? [\$temp]"
    echo -n "\$PROMPT"
    echo -n "\$BELL"
    if(\$?AUTO) then
        echo "\$temp"
    else
        set in = "\$<"
        if("\$in" != "") set temp = "\$in"
    endif
    if("\$temp" == "nothing") goto RemoveStuff
    echo "\$temp" >! \${tempfile}input
endif



###############################################################################
#
#	look for "help me" phrases
#
###############################################################################
egrep -i "help|^ what |^ how |^ when |^ where |^ why|\\?" \${tempfile}input >& /dev/null
if(! \$status) then
    goto Help
endif




###############################################################################
#
#	look for Scaler-specific phrases (program variables, etc.)
#
###############################################################################

RemoveStuff:
##############################################
#   Remove mtzs or scala cards	 	     #
##############################################
# look for "remove" phrases
egrep -i " remove| except| exclud| leave out| don't use| do not use" \${tempfile}input >& /dev/null
if((! \$status)&&(! \$?FIRSTIME)) then

    # recover/add list of MTZs (for identification)
    touch \${tempfile}mtzs
    if(! \$?FIRSTIME) then
	cat \$RUNFILE |&\\
	nawk '\$3=="+"{print \$NF, (\$6-\$4)+1}' |&\\
	nawk '{count[\$1] += \$2} END{for(mtz in count) print mtz, count[mtz]}' |&\\
	sort -n -k2 >>& \${tempfile}mtzs
    endif
    
    # get user-specified things to remove
    set badmtzs = ""
    set removed = ""
    cat \${tempfile}input |\\
    nawk -v key=" remove| except| exclude| leave out|t use" '\$0 ~ key{\\
           pos=match(tolower(\$0), key); print substr(\$0, pos+RLENGTH)}' |\\
    cat >! \${tempfile}subinput
    
    set subinput = \`cat \${tempfile}subinput |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
    foreach word ( \$subinput )
	if(("\$word" != "and")&&("\$word" != '&')&&("\$word" != ',')) then
	    unset USEFUL
	    
	    # see if it's an mtz/file
	    nawk -v check=\$word '\$1 ~ check {print \$1}' \${tempfile}mtzs |&\\
	    cat >&! \${tempfile}remove
	    set temp = \`cat \${tempfile}remove\`
	    rm -f \${tempfile}remove
	    if("\$temp" != "") then
		# mtz was in our list of used mtzs
		set badmtzs = "\$badmtzs \$temp"

		set USEFUL
		set removed = "\$removed \$temp"
	    endif
	    
	    # see if word is a wavelength
	    foreach wave ( \$wavenames )
		if("\$word" == "\$wave") then
		    # get all mtzs from this wavelength
		    cat \$RUNFILE |\\
		    nawk -v wave=\$wave '\$2=="wavelength"{p=0} \\
		    \$2=="wavelength" && \$3==wave {p=1} \\
		    p==1 && \$3=="+"{print \$NF}' |\\
		    cat >! \${tempfile}remove
		    set temp = \`cat \${tempfile}remove\`
		    rm -f \${tempfile}remove
		    
		    set badmtzs = "\$badmtzs \$temp"
		    
		    set USEFUL
		    set removed = "\$removed \$wave"
		endif
	    end
	    
	    # see if word is a scala keyword
	    grep -i "\$word" \$RULESFILE >& /dev/null
	    if(! \$status) then
		# remove this keyword from the rules file
		echo "removing:"
		grep -i "\$word" \$RULESFILE 
		echo "from the keyword list."
		
		grep -iv "\$word" \$RULESFILE >! \${tempfile}rules
		mv \${tempfile}rules \$RULESFILE
		
		set USEFUL
		set removed = "\$removed \$word"
	    endif
	    
	    # break on first non-understood word
	    if(! \$?USEFUL) break
	endif
    end
    
    # see if we got any mtzs
    set badmtzs = \`echo "\$badmtzs"\`
    
    # default to removing mtz files
    if(("\$removed" == "")&&("\$badmtzs" == "")) set badmtzs = "none of them"

    if("\$badmtzs" != "") then
	# confirm before removing
	cat \${tempfile}mtzs |\\
	nawk '{print \$1, "has", \$2, "frames"}'

	set temp = "\$badmtzs"
	echo "Which files should we leave out? [\$temp]"
	echo -n "\$PROMPT"
	echo -n "\$BELL"
	if(\$?AUTO) then
	    echo "\$temp"
	else
	    set in = "\$<"
	    if("\$in" == "none") then
		set badmtzs = ""
		set in = ""
	    endif
	    if("\$in" != "") then
		echo "" >! \${tempfile}remove
		foreach temp ( \$in )
		    # remove each of these items
		    nawk '{print \$1}' \${tempfile}mtzs |\\
		      grep "\$temp" >> \${tempfile}remove
		end
		set badmtzs = \`cat \${tempfile}remove\`
		rm -f \${tempfile}remove
		
		if("\$badmtzs" == "") echo "Huh? "
	    endif
	endif
	
	# remove requested files from the list
	foreach file ( \$badmtzs )
	    mv \${tempfile}batches \${tempfile}
	    cat \${tempfile} |\\
	    nawk -v remove=\$file '\$2 != remove {print}' |\\
	    sort >! \${tempfile}batches

	    mv \${tempfile}mtzs \${tempfile}
	    cat \${tempfile} |\\
	    nawk -v remove=\$file '\$1 != remove {print \$1}' |\\
	    sort >! \${tempfile}mtzs

	    mv \${tempfile}input \${tempfile}
	    cat \${tempfile} |\\
	    nawk -v remove=\$file '{for(i=1;i<=NF;++i){if(\$i != remove) printf " %s ", \$i}; print ""}' |\\
	    cat >! \${tempfile}input
 	end
    
	# forget old batch list now
#	rm -f \${tempfile}batches >& /dev/null
    endif

    set understood = "\$understood remove"

    # probably don't mean anything else
#    goto Calculate
endif


EditWaves:
###############################################################################
#
#	Change wavelength labels
#
###############################################################################
egrep -i "change| label|name| wave" \${tempfile}input >& /dev/null
if(! \$status) then
    cat \${tempfile}input |\\
    nawk -v key="change| label|name| wave" '\$0 ~ key{\\
           pos=match(tolower(\$0), key); print substr(\$0, pos+RLENGTH)}' |\\
    cat >! \${tempfile}subinput
    
    set subinput = \`cat \${tempfile}subinput |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
    
    while("\$subinput" != "")
	set lambda = ""
	set newname = ""
	set oldname = ""
	
	# figure out wavelength to be renamed
	foreach word ( \$subinput )
	    foreach wave ( \$wavenames )
		if("\$word" == "\$wave") then
		    set lambda = \`echo \$wavenames \$wavelengths | nawk -v label="\$wave" '{for(i=1;i<=NF;++i){if(\$i==label) print \$(i+NF/2)}}'\`
		endif
	    end
	    foreach wl ( \$wavelengths )
		if("\$word" == "\$wl") then
		    set lambda = "\$wl"
		endif
	    end
	    if("\$lambda" != "") break
	end
	# "\$word" should be first word of input after "rename" directive
	
	# remember where we left off, cut off used portion of "\$subinput" string
	set subinput = \`echo \$subinput | nawk -v key="\$word" '{print substr(\$0, index(\$0, key))}'\`

	# get current name of this wavelenth
	set oldname = \`echo \$wavelengths \$wavenames | nawk -v label="\$lambda" '{for(i=1;i<=NF;++i){if(\$i==label) print \$(i+NF/2)}}'\`

	if("\$oldname" != "") then
	    # look for next word beginning in "F" after old name
	    set newname = \`cat \${tempfile}input | nawk -v key="\$word" '{print substr(\$0, index(\$0, key)+length(key))}'\`
	    set newname = \`echo \$newname | nawk -v key="F" '{print substr(\$0, index(\$0, key))}'\`
	    set newname = \`echo \$newname | nawk '{print \$1}'\`
	
	    # prevent duplicate wavelength labels
	    foreach wave ( \$wavenames )
		if("\$newname" == "\$wave") set newname = ""
	    end

	    if("\$newname" == "") then
		# no apparent user-specified new name
	
		# default to old label
		set temp = "\$oldname"
		echo "What name shall we use for data collected at \$lambda \$ANG ? [\$temp]"
		echo -n "\$PROMPT"
		echo -n "\$BELL"
		if(\$?AUTO) then
		    echo "\$temp"
		else
		    set in = "\$<"
		    if("\$in" != "") set temp = "\$in"
		endif
		set newname = "\$temp"
	    endif
	
	    # final check for appropriate label name
	    foreach wave ( \$wavenames )
		# prevent duplicate wavelength names
		if(("\$newname" == "\$wave")&&("\$newname" != "\$oldname")) then
		    set wl = \`echo \$wavenames \$wavelengths | nawk -v label="\$wave" '{for(i=1;i<=NF;++i){if(\$i==label) print \$(i+NF/2)}}'\`
		    echo "\$newname already refers to \$wl \$ANG."
		    set newname = ""
		endif
	    end
	
	    if("\$newname" == "") then
		echo "Sorry, but "\\"\$in\\"" is not a good lable. "
		echo "if you want to rename a wavelength, please say something like: "
		echo \\""label \$oldname as Fnew"\\"
		echo ""
		goto EditWaves
	    endif
	
	    # change the wavelength label
	    set temp = ""
	    set i = 1
	    while(\$i <= \$#wavelengths)
		if("\$lambda" == "\$wavelengths[\$i]") then
		    set temp = "\$temp \$newname"
		else
		    set temp = "\$temp \$wavenames[\$i]"
		endif
		@ i = ( \$i + 1 )
	    end
	    set wavenames = \`echo "\$temp"\`
	    # update reference set
	    if("\$wave_reference" == "\$oldname") set wave_reference = "\$newname"

	    set understood = "\$understood rename \$oldname"
	endif
	
	# now cut off leading text in input string
	set subinput = \`echo "\$subinput" | nawk -v key="change| label|name| wave" '\$0 ~ key{print substr(\$0, match(tolower(\$0), key))}'\`
	if("\$subinput" == "") then
	    break
	endif
    end
    
    unset newname
    unset oldname

    # user probably doesn't want anything else
#    goto Calculate
endif



ChangeReference:
###############################################################################
#
#	allow user to change reference wavelength
#
###############################################################################
egrep -i " reference" \${tempfile}input >& /dev/null
if((! \$status)&&("\$wavenames" != "")) then
#if((! \$status)&&(! \$?FIRSTIME)) then
    # user mentioned reference wavelength
    set name = ""

    # check for wavelength names mentioned
    foreach wave ( \$wavenames )
	grep " \$wave " \${tempfile}input >& /dev/null
	if(! \$status) then
	    # select this wavelength name?
	    set name = "\$wave"
	    
	    break
	endif
    end
    set understood = "\$understood ref \$name"

    if("\$name" == "") then
	# couldn't find a label
    
	set temp = "\$wave_reference"
	echo "Which of \$wavenames do you want to use as a reference set? [\$temp]"
	echo -n "\$PROMPT"
	echo -n "\$BELL"
	if(\$?AUTO) then
	    echo "\$temp"
	else
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	endif
	
	# update user-input reference
	set name = "\$temp"
    endif
    
    # final check before changeing reference
    set temp = ""
    foreach wave ( \$wavenames )
	if("\$name" == "\$wave") set temp = "\$wave"
    end
    
    if(("\$temp" == "")&&("\$name" == "all")) then
	# trick: use all data as a reference
	set temp = "\$name"
	set name = ""
	set wave_reference = "alldata"
    endif
    if("\$temp" == "") then
	echo "Sorry, but "\\"\$in\\"" doesn't tell us anything. "
	echo "\$wave_reference is still the reference wavelength. "
	echo "if you want to change the reference wavelength, please say something like: "
	echo \\""use \$wavenames[\$#wavenames] as the reference"\\"
	echo ""
	goto ChangeReference
    else
	# \$name is indeed, part of \$wavenames
	set wave_reference = "\$name"
    endif
    
    unset name
    
    # jump over wave editor
#    goto Calculate
endif




ScalaCards:
###############################################################################
#
#	identify user-specified scala cards
#
###############################################################################
cat \${tempfile}input |\\
nawk '{print substr(\$0, index(\$0, \$1))}' |\\
egrep -i "^SDCORR|^INTENS|^PARTIALS|^REJECT|^SMOOTH|^DAMP|^FILTER|^BINS|^PRINT|^TIE|^SKIP|^ANALYZE" |\\
cat >! \${tempfile}cards

set temp = \`cat \${tempfile}cards | wc -l\`
if(\$temp != 0) then
    nawk '{print toupper(\$0)}' \${tempfile}cards |\\
    cat >> \$RULESFILE
    
    set understood = "card"
    set CHECK_SCALA_CARDS
    
    # probably don't mean anything else
    rm -f \${tempfile}cards >& /dev/null
#    goto Calculate
endif
rm -f \${tempfile}cards >& /dev/null




GatherFiles:
###############################################################################
#
#	gather file info (mtzs and text)
#
###############################################################################
set words = \`cat \${tempfile}input | wc -w\`
set word = 0
while(\$word <= \$words)
    # here we want to examine input one word at a time
    @ word = ( \$word + 1 )
    set arg = \`nawk -v word=\$word '{for(i=1;i<=NF;++i){++w; if(w==word) print \$i}}' \${tempfile}input\`
    
    # reset flag for next pass
    unset USEFUL

    # see if this is an mtz file
    if("\$arg" =~ *.mtz) then
	if(-e "\$arg") then
	    # add it to the list (check later)
	    echo "\$arg" >> \${tempfile}mtzs
	    set USEFUL
	    
	    set understood = "\$understood \$arg"
	else
	    echo "WARNING: \$arg does not exist! "
	endif
    endif
    
    # see if this is a denzo file
    if((-e "\$arg")&&(! \$?USEFUL)) then
	# filter for denzo format
	head -10 "\$arg" | nawk -f \${tempfile}x2york.awk |\\
	cat >! \${tempfile}york
	
	grep HEADER \${tempfile}york >& /dev/null
	if(! \$status) then
	    # a bird in hand...
	    # look for more files like this? 
	    
	    # check for denzo vs york format
	    grep "WARNING" \${tempfile}york >& /dev/null
	    if(! \$status) then
		# this was not a york file
		set NOT_YORK
	    endif
	    
	    # add this denzo file to the list
	    echo "\$arg" >> \${tempfile}xfiles
	    set USEFUL
 	    
	    set understood = "\$understood \$arg"
	endif
	rm -f \${tempfile}york
    endif
    
    # check for directories
    if((-e "\$arg")&&(! \$?USEFUL)) then
	# make sure this is a directory
	set mtzdir = \`ls -lLd \$arg |& nawk '/^d/{print \$NF "/"}' |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\`

	# add contents of this directory to our master list of mtzs:
	if(-e "\$mtzdir") then
	    echo -n "Looking in \$mtzdir "
	
	    ls -lnL \$mtzdir |\\
	    nawk '/.mtz\$/ && /^\\-/ && \$5+0 > 1000 {print \$NF}' |\\
	    nawk -v dir=\$mtzdir '{print dir \$1}' |\\
	    cat >! \${tempfile}
	
	    set temp = \`cat \${tempfile} | wc -l\`
	    if("\$temp" > 0) then
		cat \${tempfile}  >> \${tempfile}mtzs
		set USEFUL	    

		set understood = "\$understood \$mtzdir"
	    else
		echo -n ".. no mtz files.."
		rm -f \${tempfile}
	    	
		# list directory again, this time filtering for denzo files
		ls -lnL \$mtzdir |\\
		nawk '\$NF ~ /[0-9][0-9][0-9]./ && /^\\-/ && \$5+0 > 1000 {print \$NF}' |\\
		nawk -v dir=\$mtzdir '{print dir \$1}' |\\
		nawk '! system("head -10 " \$1){print "sector", \$1}' |\\
		nawk -f \${tempfile}x2york.awk |\\
		cat >! \${tempfile}york
		
		echo -n "."
		
		set temp = \`grep -c sector \${tempfile}york\`
		if("\$temp" > 0) then
		    echo -n ".. found \$temp denzo files."
		    
		    # add these denzo files to the list
		    nawk '/^sector/{print \$2}' \${tempfile}york >> \${tempfile}xfiles
		    set USEFUL
	    
		    # check for denzo vs york format
		    grep "WARNING" \${tempfile}york >& /dev/null
		    if(! \$status) then
			# this was not a york file
			set NOT_YORK
		    endif
	    
		    set understood = "\$understood \$arg"
		else
		    echo -n ".. no denzo files either."
		endif
		rm -f \${tempfile}york
	    endif
	    echo ""
	endif
    endif
    
    # may be a partial filename
    if(("\$arg" =~ */*)&&(! \$?USEFUL)) then
	set mtzdir = \`dirname \$arg |& nawk 'BEGIN{RS="/";ORS="/"} (NF>0 || NR==1)' |& head -1\`
	set mtzdir = "\${mtzdir}/"
	set prefix = \`basename \$arg\`

	# look in this directory for mtzs:
	ls -lnL \$mtzdir |&\\
	nawk '/.mtz\$/ && /^\\-/ && \$5+0 > 1000 {print \$NF}' |\\
	egrep "^\$prefix" |&\\
	nawk -v dir=\$mtzdir '{print dir \$1}' |&\\
	cat >! \${tempfile}
	
	set number_of_mtzs = \`cat \${tempfile} | wc -l\`
	if("\$number_of_mtzs" > 0) then
	    echo "Looking at mtzs named \${prefix}* in \$mtzdir "
	    cat \${tempfile} >> \${tempfile}mtzs
	    
	    set understood = "\$understood \$mtzdir"
	    set USEFUL
	else
	    rm -f \${tempfile}
	    

	    # list directory again, this time filtering for denzo files
	    ls -lnL \$mtzdir |\\
	    nawk '\$NF ~ /[0-9][0-9][0-9]./ && /^\\-/ && \$5+0 > 1000 {print \$NF}' |\\
	    egrep "^\$prefix" |&\\
	    nawk -v dir=\$mtzdir '{print dir \$1}' |\\
	    nawk '! system("head -10 " \$1){print "sector", \$1}' |\\
	    nawk -f \${tempfile}x2york.awk |\\
	    cat >! \${tempfile}york
	    
	    set temp = \`grep -c sector \${tempfile}york\`
	    if("\$temp" > 0) then
		echo "Found \$temp denzo files named \${mtzdir}\${prefix}* "

		# filenames were printed after "sector"
		nawk '/^sector/{print \$2}' \${tempfile}york >> \${tempfile}xfiles
		set USEFUL
		
		# check for denzo vs york format
		grep "WARNING" \${tempfile}york >& /dev/null
		if(! \$status) then
		    # this was not a york file
		    set NOT_YORK
		endif

		set understood = "\$understood \$arg"
	    endif
	    rm -f \${tempfile}york
	endif
    endif


    #########################################################################
    #
    #	    Examine Text files named on command line
    #
    #########################################################################
    # check for a flat, text file containing something useful
    set file = \`ls -Lld \$arg |& nawk '/^\\-/ && (\$5+0 < 100000 || /.seq\$/ || /.pdb\$/) {print \$NF}'\`
    if((-e "\$file")&&(! \$?USEFUL)) then
	
	# check for re-edited \$RUNFILE
	set temp = \`nawk '\$2~/^wave/ && \$4==":" && \$6=="A" && \$NF=="eV"' \$file\`
	if("\$temp" != "") then
	    echo "using run definitions in \$file"
	    set wavenames   = \`nawk '\$2=="wavelength"{print \$3}' \$RUNFILE\`
	    set wavelengths = \`nawk '\$2=="wavelength"{print \$5}' \$RUNFILE\`
	    set USEFUL
	    set USER_RUNFILE = \$file
	    # don't re-define these runs
	    set FINAL_JUMPS
	endif
	
	# use Ginger to look for parameters interesting to Scaler
	cat \$file |\\
	nawk -f \${tempfile}ginger.awk |\\
	nawk '/^SYMM|^CELL|^RESO|^MASS|^ASU|^VM|^SITES/ && NF > 1' |\\
	cat >! \${tempfile}
	set temp = \`cat \$tempfile | wc -l\`
	if(\$temp > 0) then
	    if(\$?FIRSTIME) echo "Reading parameters in \$arg"
	    cat \${tempfile} >> \${tempfile}elvish
	    set USEFUL
	endif
	
	# gather up parameters interesting to scala
	cat \$file |\\
	nawk 'NF>1 && \$1 !~ /^#/{print toupper(\$0)}' |\\
	egrep "^SDCORR|^INTENS|^PARTIALS|^REJECT|^ANOM|^SMOOTH|^DAMP|^FILTER|^BINS|^TITLE|^PRINT|^TIE|^SKIP|^ANALYZE" |\\
	cat >! \${tempfile}
	set temp = \`cat \$tempfile | wc -l\`
	if(\$temp > 0) then
	    if(\$?FIRSTIME) echo "Reading cards in \$arg"
	    cat \${tempfile} >> \$RULESFILE
	    set USEFUL
	    set CHECK_SCALA_CARDS
	endif
	
	# get mtz files mentioned in this file
	cat \$file |\\
	nawk '{for(i=1;i<=length(\$0);++i){c=substr(\$0,i,1);\\
	     if(c ~ /[\\054\\044\\042\\047]/) c= " "; printf "%s", c}; print " "}' |\\
	nawk 'BEGIN{RS=" "} NF==1' |\\
	nawk '/.mtz\$/ {if(! system("test -r " \$1 )) print \$1}' |\\
	cat >! \${tempfile}
	
	set temp = \`cat \$tempfile | wc -l\`
	if(\$temp > 0) then
	    echo "\$temp mtzs from \$file"
	    cat \${tempfile} >> \${tempfile}mtzs
	    set USEFUL
	endif
	
	# get denzo files mentioned in this file
	cat \$file |\\
	nawk '{for(i=1;i<=length(\$0);++i){c=substr(\$0,i,1);\\
	     if(c ~ /[\\054\\044\\042\\047]/) c= " "; printf "%s", c}; print " "}' |&\\
	nawk 'BEGIN{RS=" "} NF==1' |\\
	nawk '/[0-9][0-9][0-9]./{if(! system("head -10 " \$1)) print "sector", \$1}' |&\\
	nawk -f \${tempfile}x2york.awk |&\\
	cat >&! \${tempfile}york
	
	set temp = \`grep -c sector \${tempfile}york\`
	if(\$temp > 0) then
	    echo "\$temp denzo files from \$file"
	    nawk '/^sector/{print \$2}' \${tempfile}york >> \${tempfile}xfiles
	    
	    # check for denzo vs york format
	    grep "WARNING" \${tempfile}york >& /dev/null
	    if(! \$status) then
		# this was not a york file
		set NOT_YORK
	    endif
	
	    set USEFUL	
	endif
	rm -f \${tempfile}york
	
	# may be a sequence file, see if it reads like one
	cat \$file |\\
	nawk -f \${tempfile}sequencer.awk |\\
	cat >! \${tempfile}
#	nawk '/chain/,NF==0' |\\
	set temp = \`cat \${tempfile} | wc -l\`
	if("\$temp" > 1) then
	    # store sequences here too
	    if(\$?FIRSTIME) echo "Getting protein sequence from \$arg"
	    echo ""         >> \${tempfile}sequence
	    cat \${tempfile} >> \${tempfile}sequence
	    echo ""         >> \${tempfile}sequence
	    set USEFUL
	endif
	
	# may have something about the metal in it.
	nawk '{print \$0 " "}' \$file |\\
	nawk 'BEGIN{RS=" "} NF == 1' |\\
	nawk '\$0+0 == 0' |\\
	nawk '\$0 !~ "all"' |\\
	nawk -f \${tempfile}elements.awk |\\
	nawk '\$1 > 16' |\\
	cat >! \${tempfile}
	set temp = \`cat \${tempfile} | nawk 'NR==1{print \$2, \$3}'\`
	if(\$#temp == 2) then
	    set METAL = "\$temp[2]"
	    set Ee = \`echo \$METAL | \${tempfile}elements.awk | nawk 'NR==1{print \$2}'\`

	    # look for number in front of element name (sites)
	    cat \$arg |\\
	    nawk '! /^ATOM/' |\\
	    nawk 'BEGIN{RS=" "} NF == 1' |\\
	    nawk 'NF==1' |\\
	    nawk -v Ee=\$temp[1] -v Name=\$temp[2] \\
	     '(tolower(Name) == tolower(\$1) || \$1 == Ee || tolower(\$1) ~ /^site/) && v>0 && v<100{print v} {v=\$1+0}' |\\
	    cat >! \${tempfile}
	    set temp = \`nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
    endif

    # keep this variable from getting too long
    set understood = \`echo \$understood | nawk '{print \$NF}'\`
end

##############################################
#   Finished first command-line pass (files) #
##############################################




GetMTZinfo:
###############################################################################
#
#	Dump MTZ batch info (quickly!)
#
###############################################################################
# now get batch data from any mtz files
touch \${tempfile}batches
touch \${tempfile}mtzs

# remove duplicate files
cat \${tempfile}batches \${tempfile}mtzs |\\
nawk 'NF > 5 {seen[\$2] = \$2} \\
      NF < 5 {if(seen[\$1] == "") print; seen[\$1] = \$1}' |\\
cat >! \${tempfile}
mv \${tempfile} \${tempfile}mtzs
set number_of_mtzs = \`cat \${tempfile}mtzs | wc -l\`
if(\$number_of_mtzs > 0) then

    echo ""
    echo -n "Organizing mtz data ... "
    if(! \$?AUTO) then
	echo -n "(Cntrl-C to end)"
	onintr SkipRestofMTZs
    endif
    echo ""

    # create temporary mtzdump input
    echo "HEAD" >! \${tempfile}inp
    echo "BATCH" >> \${tempfile}inp
    
    # run by each mtz in our list, collecting batch info
    set i = 0
    while(\$i < \$number_of_mtzs)
	@ i = ( \$i + 1 )
	# pick the i-th file in the list
	set mtz = \`head -\$i \${tempfile}mtzs | tail -1 | nawk '{print \$1}'\`
	unset USEFUL

	# dump out its batch contents
	cat \${tempfile}inp |&\\
	mtzdump hklin \$mtz |&\\
	nawk -v file=\$mtz '\\
	    /Space group =/{sg = \$NF+0}\\
	    /  Resolution Range /{getline;getline; hires = \$6; lores = \$4}\\
	    /Orientation data for batch/ {batch = \$5}\\
	    /  Cell dimensions /{cell = \$4 " " \$5 " " \$6 " " \$7 " " \$8 " " \$9}\\
	    /  Wavelength and dispersion/{wave = \$5}\\
	    /  Mosaicity /{mos = \$NF}\\
	    /  Start & stop Phi angles/{start = \$7; stop = \$8}\\
	    /Detector information/{print wave, file, batch, start, stop, mos, hires, lores, sg, cell}' |&\\
	nawk '\$1+0 > 0 && \$NF+0 > 10' |&\\
	cat >&! \${tempfile}
	
	set temp = \`nawk '\$1+0 > 0.1' \${tempfile} | wc -l\`
	if("\$temp" > 0) then
	    cat \${CLIBD}/symop.lib |\\
	    nawk 'NF>5{print "SYMM",\$1,\$4}' |\\
	    cat - \${tempfile} |\\
	    nawk '/^SYMM/{SG[\$2]=\$3;next} {\$9=SG[\$9];print}' |\\
	    cat >> \${tempfile}batches
	    echo "\$mtz (\$temp frames)"
	    continue
	endif

	if(! \$?SEARCHED_FOR_MTZS) then
	    # check to see if it could be merged data (a reference)
	    echo "HEAD" | mtzdump hklin \$mtz |\\
	    nawk '/Number of Reflections/ && \$NF==0{exit} \\
		   /Column Labels/{getline;getline;while(NF){j=0;for(i=1;i<=NF;++i){++j;label[i]=\$j;} getline}}\\
		   /Column Types/{getline;getline;while(NF){j=0;for(i=1;i<=NF;++i){++j;print \$j, label[i];} getline}}'|\\
	    cat >&! \${tempfile}labels
	    
	    # check for reference data
	    set temp = \`nawk '\$1=="F" || \$1=="J"' \${tempfile}labels | wc -l\`
	    if(\$temp > 0) then
		echo "\$mtz (merged reference)"
		set USER_REFERENCE
		set refMTZ = "\$mtz"
		set refMTZset = ""
		set USEFUL
	    endif
	    # check for free-R flags
            set temp = \`nawk 'tolower(\$NF) ~ /freer/ {print \$NF}' \${tempfile}labels\`
            if("\$temp" != "") then
                set freeR_source = "\$mtz"
		set USEFUL
            endif
	    
	    # this mtz must just not be anything useful...
	    if(! \$?USEFUL) then
		# warn about explicitly specified bad files (don't complain about ones we found)
		foreach file ( \$understood )
		    if("\$file" == "\$mtz") echo "WARNING: no batches in \$mtz"
	        end
	    endif
	    rm -f \${tempfile}labels >& /dev/null
	endif
	
#	@ i = ( \$i + 1 )
    end

    goto SkipRestofMTZs

    # avoid onintr nesting bug
    end
    end
    end
    endif
    endif
    endif

SkipRestofMTZs:
    onintr
    
    # clean up
    rm -f \${tempfile}labels >& /dev/null
    rm -f \${tempfile}mtzs
    rm -f \${tempfile}inp
endif

GetDenzoInfo:
###############################################################################
#
#	Denzo files will be represented in wildcard format for the
#	purposes of identifying "same" source batches:
#	frame_001.x -> frame_###.x, batch 1
#
#	the batch number from the filename will become the last word on the line
#
###############################################################################
# now get batch data from any mtz files
if(! -e \${tempfile}xfiles) touch \${tempfile}xfiles
set temp = \`nawk 'NF==1' \${tempfile}xfiles | wc -l\`
if("\$temp" > 0) then
    echo ""
    echo -n "Organizing denzo data .."
    
    set DENZO_FILES
    
    # parse filenames (into denzoish template and batch number)
    sort -u \${tempfile}xfiles |\\
    nawk 'NF==1{template="";batch=""; ext=""; width=pad=""; \\
	n=split(\$1,a,".");\\
	if(n>1){ext = "." a[n]};\\
	template = a[1];\\
	for(i=2;i! \${tempfile}parsed
    
    # entertainment
    echo -n ".this will take a while"
    
    # get same info from .x files that we would get from MTZs
    sort -u \${tempfile}parsed |\\
    nawk '{file=\$NF; template=\$1; batch=\$2;\\
	while("cat " file | getline){ print ;\\
	    if(\$1 ~ /^sector/){print "FILENAME", file, batch, template}};\\
	close("cat " file);}' |\\
    nawk -f \${tempfile}x2york.awk |\\
    nawk '/[a-z]/' >! \${tempfile}denzoinfo
    
    # entertainment
    echo -n "."
    
    # get the X-Y range for rotaprep (much later)
    set XYrange = \`tail -10 \${tempfile}denzoinfo | nawk '/X_range:/{print \$2, \$3, \$5, \$6}'\`
    
    # now extract batch info from this processed file
    cat \${tempfile}denzoinfo |\\
    nawk '/^sector/{sector = \$2+0;};\\
	  /^FILENAME/{file = \$2; batch=\$3; template=\$4};\\
	  /^oscillatio/{phi0 = \$3+0; phiend=\$NF+0};\\
	  /^wavelength/{wave = \$2+0};\\
	  /^mosaic/{mosaic = \$2+0};\\
	  /^resolution/{hires= \$NF+0; lores =\$3+0};\\
	  /^space/{sg = toupper(\$NF)};\\
	  /^unit cell/{cell = substr(\$0, 10)};\\
	  /^crossfire/{ \\
	osc=(((phiend-phi0)*1000)%360000)/1000; if(osc==0) osc=10000; \\
	print wave, template, sector, phi0, phiend, mosaic/osc, hires, lores, sg, cell, file, "DENZO";\\
	phi0=phiend=cell=wave=phi="-";}' |\\
    sort -k1n,2 -k2,3 -k3n,4 >! \${tempfile}denzobatches

# faster, but can't handle cat-ed xfiles or XY range
#    # get same info from .x files that we would get from MTZs
#    sort -u \${tempfile}parsed |\\
#    nawk '{file=\$NF; template=\$1; batch=\$2; phi0=phiend=cell=wave=phi="-";\\
#	while("tail -50 " file | getline){   ;\\
#	    if(\$1 ~ /^wavelength/){wave = \$2+0};\\
#	    if(\$1 ~ /^oscillatio/){phi0 = \$3+0; phiend=\$NF+0};\\
#	    if(\$1 ~ /^resolution/){hires= \$NF+0; lores =\$3+0};\\
#	    if(\$1 ~ /^mosaic/){  mosaic = \$2+0};\\
#	    if(\$1 ~ /^sector/){  sector = \$2+0};\\
#	    if(\$1 ~ /^space/){       sg = toupper(\$NF)};\\
#	    if(\$0 ~ /^unit cell/){ cell = substr(\$0, 10)};\\
#	}close("tail -50 " file); osc=(((phiend-phi0)*1000)%360000)/1000; if(osc==0) osc=10000; \\
#	print wave, template, sector, phi0, phiend, mosaic/osc, hires, lores, sg, cell, file}' |\\
#    sort +0n -1  +1 -2  +2n -3 >! \${tempfile}denzobatches


    # entertainment
    echo "."
    
    # add denzo files to master batch list
    cat \${tempfile}denzobatches >> \${tempfile}batches
    
    # no longer need this file
    rm -f \${tempfile}parsed
    rm -f \${tempfile}denzoinfo
    rm -f \${tempfile}denzobatches
endif
rm -f \${tempfile}xfiles >& /dev/null

#########################################
# \${tempfile}batches has format:
# wavelength file# batch# phi_start phi_stop  mosaicity hires lores SG cell
#########################################


##############################################
# gather statistics on all batches
##############################################
set temp = \`nawk '\$1+0 > 0.1' \${tempfile}batches | wc -l\`
if(\$temp > 0) then
    echo ""
    echo "Hang on..."
    
    # SG, wave, etc
    cat \${tempfile}batches |\\
    nawk 'BEGIN{hires = 10} \\
    {++n; ++wavecount[\$1]; ++SGcount[\$9]; if(\$6+0>0){mos += \$6/(\$5-\$4)}; \\
    if(hires > \$7){hires=\$7+0}; if(lores < \$8){lores=\$8+0};} \\
    END{if(n) mos /= n;\\
    for(w in wavecount) {if(wavecount[w] > wavecount[wave]){wave = w}} \\
    for(s in SGcount) {if(SGcount[s] > SGcount[SG]){SG = s} } \\
    for(s in SGcount) {if(s != SG){++extraSG[s]} } \\
    for(s in extraSG) {SG = SG "  " s}  \\
    print "WAVE", wave; \\
    print "RESO", hires, lores; \\
    print "SYMM", SG;   \\
    print "MOSAIC_NORM", mos;}' |\\
    cat >! \${tempfile}stats

    # analyze cell too
    cat \${tempfile}batches |\\
    nawk '{++n;\\
    a[n]=\$10;b[n]=\$11;c[n]=\$12;A[n]=\$13;B[n]=\$14;G[n]=\$15; \\
    asum+=\$10;bsum+=\$11;csum+=\$12;Asum+=\$13;Bsum+=\$14;Gsum+=\$15;} \\
    END{if(n==0) exit;\\
    asum/=n;bsum/=n;csum/=n;Asum/=n;Bsum/=n;Gsum/=n; \\
    for(x in a) {\\
      d=sqrt((a[x]-asum)*(a[x]-asum))/asum; if(d > dCELL) {dCELL = d};\\
      d=sqrt((b[x]-bsum)*(b[x]-bsum))/bsum; if(d > dCELL) {dCELL = d};\\
      d=sqrt((c[x]-csum)*(c[x]-csum))/csum; if(d > dCELL) {dCELL = d};\\
      d=sqrt((A[x]-Asum)*(A[x]-Asum))/Asum; if(d > dCELL) {dCELL = d};\\
      d=sqrt((B[x]-Bsum)*(B[x]-Bsum))/Bsum; if(d > dCELL) {dCELL = d};\\
      d=sqrt((G[x]-Gsum)*(G[x]-Gsum))/Gsum; if(d > dCELL) {dCELL = d};} \\
    print "CELL", asum, bsum, csum, Asum, Bsum, Gsum;\\
    printf "maxdCELL %f\\n", dCELL*1000;}' |\\
    cat >> \${tempfile}stats
    
    # use mtz values to set uninitialized variables
    set temp = \`nawk '/^SYMM/{print substr(\$0,5)}' \${tempfile}stats\`
    if("\$#temp" > 1) then
	echo "WARNING: \$temp found for space group! "
	echo "         \$temp[1] will be used."
	set temp = "\$temp[1]"
    endif
    if(\$#temp == 1) then
	# update SG, unless already set
	if("\$SG" == "unknown") then
	    set SG = "\$temp"
	endif
    else
	echo "ERROR! no space groups found in input files! "
	# this should never happen
	set SG = "P1"
#	goto Cleanup
    endif

    set temp = \`nawk '/^CELL/{print substr(\$0,5)}' \${tempfile}stats\`
    if(\$#temp == 6) then
	# define cell,  unless already set
	if(\$#CELL != 6) set CELL = \`echo "\$temp"\`
    else
	echo "WARNING: no unit cell in input files ! "
	echo "         What the hell is going on! "
	set CELL = \`echo 0 0 0 90 90 90\`
    endif

    set temp = \`nawk '/^maxdCELL/{printf "%d", \$NF}' \${tempfile}stats\`
    if(("\$temp" != "0")&&(\$?FIRSTIME)) then
	echo "WARNING: Unit cells differ in input files ! "
	echo "Average Cell: \$CELL"
	echo "CELL \$CELL" >! \${tempfile}cell
	
	cat \${tempfile}cell \${tempfile}batches |\\
	nawk '/^CELL/{a=\$2+0; b=\$3+0; c=\$4+0; A=\$5+0; B=\$6+0; G=\$7+0; D=\$NF} \\
	/^[0-9]/{if(((\$10-a)^2+(\$11-b)^2+(\$12-c)^2+(\$13-A)^2+(\$14-B)^2+(\$15-G)^2) > 0){\\
	print \$2 ": cell = ",  \$10, \$11, \$12, \$13, \$14, \$15} }' |\\
	nawk '{CELL[\$1]=\$0} END{for(mtz in CELL){print CELL[mtz]}}' |\\
	sort | nawk '{print} NR==11{print"etc..."; exit}'
	rm -f \${tempfile}cell >& /dev/null
	
	echo "         How are we supposed to know which one to use? "
	echo "         Unless you think your unit cell is really changing, "
	echo "         you should use the same cell for all your frames! "
	
	set NEED_TO_POSTREFINE
    endif

    # set up resolution range
    set temp = \`nawk '/^RESO/ && \$NF+0 > 0.1{print}' \${tempfile}stats\`
    if(("\$#temp" == "3")&&("\$hiRES" == "")) then
	set hiRES = "\$temp[2]"
	set loRES = "\$temp[3]"
    endif

    # pick most likely metal, based on wavelength data were collected at
    if("\$METAL" == "") then
	nawk '/^WAVE/{print \$NF}' \${tempfile}stats |\\
	nawk -f \${tempfile}elements.awk  >! \${tempfile}
	set temp = \`nawk 'NR == 1{print \$3}' \${tempfile}\`
	if("\$temp" != "") then
	    # most likely MAD metal
	    set METAL = "\$temp"
	    set Ee = \`echo \$METAL | \${tempfile}elements.awk | nawk 'NR==1{print \$2}'\`
	endif
    endif
    
    # evaluate mean normalized mosaicity (mosaicity/osc)
    set MOSAIC = \`nawk '/^MOSAIC/{print \$NF}' \${tempfile}stats\`
    echo \$MOSAIC |\\
    nawk '\$NF > 0.34{print \$NF, 0.577 - 0.226*log(\$NF-0.333)}' |\\
    nawk '\$NF < 0.99{printf "INTENSITIES SCALE_PARTIALS %.2f\\n", \$NF};\\
    \$NF < 0.7 {printf "INTENSITIES PARTIALS MAXWIDTH %d\\n", \$1+1.5;}' |\\
    nawk '/MAXWIDTH/{if(\$NF>6){print "INTENSITIES PARTIALS"}else{print}}  ! /MAXWIDTH/' |\\
    tail -1 >> \${tempfile}parts
    set temp = \`cat \${tempfile}parts | wc -l\`
    
    # create SCALA card for what to do with partials
    egrep "^INTEN" \$RULESFILE | grep "PART" >& /dev/null
    if((\$status)&&("\$temp" > 0)) then
	# no INTENS PART card yet, and Elves have picked one
	if(\$?FIRSTIME) then
	    # add our card to the list
	    cat \${tempfile}parts >> \$RULESFILE
	else
	    # ask this time
	    cat << EOF

Your crystal mosaicity is high compared to the oscillation angle: \${MOSAIC}:1  
This means you will have few fully-recorded spots in your data set, and the 
(default) fulls-only scaling procedure in scala might be unstable.
Therefore, the elves recommend using partials in scaling, specifically:
EOF
cat \${tempfile}parts
	    set temp = "Yes"
	    echo "Do this? [\$temp]"
	    echo -n "\$PROMPT"
	    echo -n "\$BELL"
	    if(\$?AUTO) then
		echo "\$temp"
	    else
		set in = "\$<"
		if("\$in" != "") set temp = "\$in"
	    endif
	    if("\$temp" !~ [Nn]*) then
		cat \${tempfile} >> \$RULESFILE
	    endif
	endif
    endif
    
    rm -f \${tempfile}parts
    
    # still merge denzo-derived partials
    if(\$?NOT_YORK) then
	# see if card is already there
	grep -i "NOTEST" \$RULESFILE >& /dev/null
	if(\$status) then
	    # don't defeat user's will, just bother them
	    if(\$?FIRSTIME) then
		echo "PARTIALS NOTEST" >> \$RULESFILE
	    else
		# explain ourselves?
		cat << EOF
WARNING: some denzo input files are not in york format, and, therefore have
         no record of the fraction-full of your partials.  You are strongly
	 advised to use "PARTIALS NOTEST" to keep scala from throwing out
	 all your partials.
EOF
	    endif
	endif

	set NEED_TO_POSTREFINE
    endif
else
    # no batches found anywhere
    if(! \$?SEARCHED_FOR_MTZS) then
	set temp = "I don't know"
	ls */*/raw.mtz >& /dev/null
	if(! \$status) set temp = '*/*/raw.mtz'
	echo "Where are the data you want to scale? [\$temp]"
	echo -n "\$PROMPT"
	echo -n "\$BELL"
	if(\$?AUTO) then
	    echo "\$temp"
	else
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	endif
	if("\$temp" == "I don't know") goto MTZsearch
	if("\$temp" != "") then
	    set input = "\$temp"
	    goto Gather
	endif
	
	goto MTZsearch
    endif
    
    # no mtzs, and can't find any
    echo "No mtz files!  Where are your data? "
    
    goto Problem
endif



##############################################
# now parse out runs, 
# and invent batch adding strategy
##############################################
sort -k1n,2 -k2,3 -k4n,5 \${tempfile}batches |\\
nawk -f \${tempfile}parser.awk |\\
cat >! \${tempfile}parsed

# use top part as user-viewable runfile
if(\$?USER_RUNFILE) then
    set wavenames   = \`nawk '\$2=="wavelength"{print \$3}' \$USER_RUNFILE\`
    set wavelengths = \`nawk '\$2=="wavelength"{print \$5}' \$USER_RUNFILE\`
    cat \$USER_RUNFILE |\\
    nawk '\$2 == "wavelength", /\\n/' |\\
    cat >! \${tempfile}
    cat \${tempfile} >! \$RUNFILE
    rm -f \${tempfile} >& /dev/null
else
    cat \${tempfile}parsed |\\
    nawk '\$2=="wavelength",NF==0' |\\
    cat >! \$RUNFILE
endif

# use bottom part to keep track of detailed batch adding strategy
cat \${tempfile}parsed |\\
nawk '/dump/,NF==0' |\\
sort -n >! \${tempfile}strategy

# check for overlap with "reference" batch
cat \${tempfile}strategy |\\
nawk -v ref_batch=\$ref_batch '{taken[\$3]=1} END{while(taken[ref_batch]) ++ref_batch;\\
   print ref_batch}' |\\
cat >! \${tempfile}ref_batch
set ref_batch = \`cat \${tempfile}ref_batch\`
rm -f \${tempfile}ref_batch >& /dev/null

# keep batch info around for later (might want to add/delete mtzs)
#rm -f \${tempfile}batches
rm -f \${tempfile}parsed




##############################################
# check for \$%&#@ing scala bug
##############################################
if(! \$?CPROG) then
    set CPROG = .
    set NO_SRC
endif
grep "lwidas(1,nlprgo" \${CPROG}/scala_/scala.f >& /dev/null
if((! \$status)&&(\$?FIRSTIME)) then
    # crap...
    set temp = "No"
    cat << EOF-message

Bad scala! 

Your version of scala appears to contain a known bug that
existed from CCP4 v 3.5.1 to 4.0.1.  This bug prevents Scaler
Elves from passing scales from one script to the next.  This
means that the localscaling procedure provided here will crash 
just before creating an output mtz file. ;(  There is no 
workaround, other than to forgo localscaling.

To fix your scala program you must edit:
\${CPROG}/scala_/scala.f

delete line 9805:
           nlprgo = ncolou
	   
and change line 9854:
          call lwidas(1,nlprgo,pname_out,dname_out,0)
to this:
          call lwidas(1,ncolou,pname_out,dname_out,0)
	  
and then recompile scala:
cd \${CPROG}/scala_
make
mv scala \${CBIN}

Until the above changes have been made, Scaler Elves will
not try to do localscaling for you.  Unfortunately, you 
probably have to be root to do this.

Has these changes already been made? [\$temp]
EOF-message
    echo -n "\$PROMPT"
    echo -n "\$BELL"
    if(\$?AUTO) then
	echo "\$temp"
    else
	set in = "\$<"
	if("\$in" != "") set temp = "\$in"    
    endif
    if("\$temp" !~ [Yy]*) then
	echo "disabling localscaling for this run.... sorry."
	set ROUGHSCALE_ONLY
    endif
endif




##############################################
# check for too many batches 
##############################################
set runs = \`nawk '/^run/' \$RUNFILE | wc -l\`
set batches = \`cat \${tempfile}batches | wc -l\`
@ batches = ( \$batches + 1 )
if((\$?FIRSTIME)&&((\$batches > 1000)||(\$runs > 40))) then
    set MBATCH
    set MAXRUNS
    # check to see if CCP4 might have been recompiled to handle this
    set MBATCH = \`grep -i mbatch \${CPROG}/*.f |& nawk 'BEGIN{FS="="} {for(i=1;i<=NF;++i)if(toupper(\$i) ~ "MBATCH") print \$(i+1)+0}' |& sort -n |& tail -1\`
    # assume default value if we can't tell
    if("\$MBATCH" !~ [1-9]*) then
	set MBATCH = 1000
	set NO_SRC
    endif
        
    set MAXRUNS = \`grep -i maxrun \${CPROG}/scala_/parameter.fh |& nawk 'BEGIN{FS="="} {for(i=1;i<=NF;++i)if(toupper(\$i) ~ "MAXRUN") print \$(i+1)+0}' |& sort -n |& tail -1\`
    # assume default value if we can't tell
    if("\$MAXRUNS" !~ [1-9]*) set MAXRUNS = 40;
       
    set are = "are"
    if(\$?NO_SRC) set are = "may be"
 
    if(\$MAXRUNS < \$runs) then
	# crap, too many runs.
	echo "There \$are too many runs for your copy of scala."
	echo ""
	echo "Either throw out some small wedges or edit:"
	echo "\${CPROG}/scala_/parameter.fh"
	echo "so that maxruns=\$runs (or more)"
	echo ""
    endif
    
    if(\$MBATCH < \$batches) then
	# crap, maybe we should recompile CCP4 with a bigger MBATCH?
	echo ""
	echo "There \$are too many frames! "
	set temp = \`echo "\$batches - \$MBATCH" | bc\`
	cat << EOF

As far as we can tell, your installation of CCP4 can't handle
more than \$MBATCH batches at once, and you have \${batches} batches.

You have three choices:
1)  throw out \$temp frames from this analysis.
2)  scale each wavelength separately, and combine them after mergeing 
    (that is, do several Scaler runs.)
3)  recompile CCP4 with the maximum allowed batches increased

Doing #3 seems like a real pain, (and it is).  However, it is still
the best option, and here's how you do it:
    
    for both \${CPROG} and \${CLIBS}
    - use 
      grep -i MBATCH \\\`find \${CPROG} -type f -print\\\` | grep 1000
      to find files containing MBATCH=1000.  You need to edit these
      files so MBATCH=\$batches (at least).  We use MBATCH=10000.
    - also, in: 
      \${CPROG}/scala_/parameter.fh
      you need to change maxbat=1000 and maxmat=1000 and, perhaps 
      maxpmr=2000 to values > \$batches as well.  maxrun should be > \$runs
      too.
    
    after that, you should be able to rebuild CCP4 with:
    cd \${CCP4}
    make
    make install
    
    but, you have to have write permissions to CCP4 to do this.

EOF
    endif
    if((\$MAXRUNS < \$runs)||(\$MBATCH < \$batches)) then
	
	# final warning
	echo ""
	echo "If, however you think your copies of scala and sortmtz can handle \$batches"
	echo "frames and \$runs runs, answer "none" to the question below."
	echo ""
    
	# don't do this twice
	unset FIRSTIME
	
	# pick shortest runs to throw out
	echo -n " remove " >! \${tempfile}input
	
	# name smallest mtzs that add up to the "batch excess"
	nawk '\$3 == "+"{print \$6-\$4+1, \$NF}' \$RUNFILE | sort -nr |\\
	 nawk -v limit=\$MBATCH '{batches+=\$1} batches > limit{print \$NF}' |\\
	 cat >! \${tempfile}badfiles
	# find smallest N-MAXRUN runs.
	nawk '\$3 == "+"{runcount += \$6-\$4+1; runfile = runfile " " \$NF} \\
	      /^run/ {print runcount, runfile; runcount = 0; runfile = ""}' \$RUNFILE | sort -nr |\\
	 nawk -v limit=\$MAXRUNS 'NR >= limit{print \$NF}' |\\
	 cat >> \${tempfile}badfiles
	
	# uniqueify, and send to mtz eliminator
	sort -u \${tempfile}badfiles | nawk '{printf " %s ", \$1}' >> \${tempfile}input
	rm -f \${tempfile}badfiles
	
	# don't override the \${tempfile}input file
	set input = ""
	echo " " >> \${tempfile}input
	
	if(\$?NO_SRC) then
	    echo "remove none" >! \${tempfile}input
	endif
	
	goto RemoveStuff
    endif

endif





##############################################
#   Word-wise command-line pass              #
##############################################

# go back through command line and allow user to override variables
grep " auto " \${tempfile}input >& /dev/null
if(! \$status) then
    # go automatic
    set AUTO
endif
grep " debug " \${tempfile}input
if(! \$status) then
    # me
    set
endif

grep " hurry " \${tempfile}input >& /dev/null
if(! \$status) then
    # select fast and reckless processing
    set HURRY_UP
endif

grep " keep " \${tempfile}input >& /dev/null
if(! \$status) then
    # bail instead of rejecting frames
    set KEEP_ALL_FRAMES
    set FINAL_JUMPS
endif

grep " smooth " \${tempfile}input >& /dev/null
if(! \$status) then
    # don't bother trying to find subwedges?
    set USER_SMOOTH
    set SCALING = smooth
    set BFACTOR = smooth
    #set INITIAL_JUMPS
endif

# select no reformatting of run list? 


###############################################################################
# check for protein sequences on command line
cat \${tempfile}input | nawk -f \${tempfile}sequencer.awk >&! \${tempfile}seq

set temp = \`cat \${tempfile}seq | wc -l\`
egrep "remove|delete" \${tempfile}input >& /dev/null
if((\$status)&&(\$temp != 0)) then

    # remove old sequences from \${tempfile}sequence
    mv \${tempfile}seq \${tempfile}sequence
    # redefine mass
    set MASS = "unknown"
    
    set understood = "\$understood new sequence"
endif
rm -f \${tempfile}seq >& /dev/null

# get mass from sequence
if("\$MASS" == "unknown") then
    set temp = \`nawk '/chain:/{mass += \$1} END{if(mass+0 > 1000) printf "%.1f", mass+0}' \${tempfile}sequence\`
    if("\$temp" != "") set MASS = "\$temp"
endif


###############################################################################
# check for metal name/symbol (watch out for single-letter elements, user should say "iodine" or "uranium")
cat \${tempfile}input |\\
nawk 'BEGIN{RS=" "} NF==1' |\\
nawk '! /[0-9]/ && length(\$1) != 1' |\\
nawk -f \${tempfile}elements.awk >&! \${tempfile}
set temp = \`cat \${tempfile} | nawk 'NR==1{print \$3}'\`
if("\$temp" != "") then
    # must have given an element name! 
    set METAL = "\$temp"
    set Ee = \`echo \$METAL | \${tempfile}elements.awk | nawk 'NR==1{print \$2}'\`

    set understood = "\$understood \$METAL"
endif


###############################################################################

# use Ginger to translate from English to Elvish
# (then append command-line translation to translations of files)
touch \${tempfile}elvish
cat  \${tempfile}elvish \${tempfile}input |\\
nawk -f \${tempfile}ginger.awk |\\
cat >! \${tempfile}
mv \${tempfile} \${tempfile}elvish


# now go through x-ray parameters germane to Scaler
# ONLY updating explicit values

grep "SYMM" \${tempfile}elvish >& /dev/null
if(! \$status) then
    set temp = \`nawk '/^SYMM/{print \$NF}' \${tempfile}elvish\`
    # check this word against the SG library (ginger can't really do this)
    if( -e \$CLIBD/symop.lib) then
	set temp = \`nawk -v SG=\$temp '\$4 == toupper(SG) {print \$4}' \$CLIBD/symop.lib | head -1\`
    endif
    if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) then
	set SG = "\$temp"
    endif
endif


# unit cell
grep "CELL" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # check against SG
    set temp = \`nawk -v SG="\$SG" '\$4 == toupper(SG) {print \$NF}' \$CLIBD/symop.lib |& head -1\`
    nawk -v latt="\$temp" '/^CELL/{print substr(\$0,5), latt}' \${tempfile}elvish |\\
    nawk '{a=\$1+0; b=\$2+0; c=\$3+0; A=\$4+0; B=\$5+0; G=\$6+0}\\
    \$NF == "MONOCLINIC" { A=90; ; G=90; if(\$4+0 > 5) B=\$4+0; if(\$5+0 > 5) B=\$5+0}\\
    \$NF == "ORTHORHOMBIC" {A=90; B=90; G=90}\\
    \$NF == "TETRAGONAL" || \$NF == "TRIGONAL" || \$NF == "HEXAGONAL" {\\
    b=a; A=90; B=90; G=120;\\
    if((c==0) && ((\$2-a)^2 > .0001)) {c = \$2+0}}\\
    \$NF == "TETRAGONAL" {G=90}\\
    \$NF == "CUBIC" {b=a; c=a; A=90; B=90; G=90}\\
    END{if(a>5 && b>5 && c>5 && A>5 && B>5 &&G>5) print a, b, c, A, B, G}' |\\
    cat >! \${tempfile}
    set temp = \`cat \${tempfile}\`
    if("\$#temp" == 6) then
	# actual unit cell was given
	set CELL = \`echo "\$temp"\`
	set understood = "\$understood \$temp"
    else
	# cell is bad, ask about it later
	grep -v "CELL" \${tempfile}elvish >! \${tempfile}
	echo "CELL" >> \${tempfile}
	mv \${tempfile} \${tempfile}elvish
    endif
endif


# resolution
grep "RESO" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # slower reader
    set temp = \`nawk '/^RESO/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" =~ [0-9]*) then
	# explicit value was given
	set hiRES = "\$temp"
	set USER_hiRES = "\$temp"
	set understood = "\$understood \$temp"
    endif
    set temp = \`nawk '/^loRESO/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" =~ [0-9]*) then
	# explicit value was given
	set loRES = "\$temp"
	set understood = "\$understood \$temp"
    endif
endif


# Matthews number/solvent content
grep "VM " \${tempfile}elvish >& /dev/null
if(! \$status) then
    # slower reader
    set temp = \`nawk '/^VM/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" =~ [0-9]*) then
	# explicit value was given
	set Vm = "\$temp"
	# forget the chain count, recalculate it later
	if("\$CHAINS" != "") then
	    if("\$SITES" != "") then
		# reset number of sites to monomer count
		set temp = \`echo "\$SITES \$CHAINS" | nawk '\$2+0 > 0 {printf "%d", \$1/\$2}'\`
		if("\$temp" > 0) set SITES = \$temp
	    endif
	    # reset mass if Vm was explicitly specified
	    if("\$CHAINS" == 1) set MASS = "unknown"
	    # redetermine chain count
	    set CHAINS = ""
	endif
	set understood = "\$understood \$temp"
    endif
endif


# Protein MASS size
grep "MASS" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # slower reader
    set temp = \`nawk '/^MASS/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" =~ [0-9]*) then
	# an actual mass value was given
	set MASS = "\$temp"
	set understood = "\$understood \$temp"
    endif
endif


# ASU size/chain number
grep "ASU" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # slower reader
    set temp = \`nawk '/^ASU/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" =~ [0-9]*) then
	# most likely need to update metal sites too
	if(("\$CHAINS" > 1)&&("\$SITES" != "")) then
	    set SITES = \`echo "\$SITES \$CHAINS \$temp" | nawk '\$2 > 0{printf "%d", (\$1/\$2) * \$3}'\`
	endif
	set CHAINS = "\$temp"
	set understood = "\$understood \$temp"
    endif
endif


# number of metal sites
grep "SITES" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # slower reader
    set temp = \`nawk '/^SITES/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" =~ [0-9]*) then
	# explicit value given
	set SITES = "\$temp"
	set understood = "\$understood \$temp"
    endif
endif


# wavelength names? 


Guess:
###############################################################################

  ####   #    #  ######   ####    ####
 #    #  #    #  #       #       #
 #       #    #  #####    ####    ####
 #  ###  #    #  #            #       #
 #    #  #    #  #       #    #  #    #
  ####    ####   ######   ####    ####

###############################################################################
#
#   Guess/calculate at values not provided by user
#
###############################################################################


##############################################
#   Decide on names for wavelengths
##############################################
# must check every time for new wavelengths
cat \$RUNFILE |\\
nawk '\$2=="wavelength"{++wave; wavelen = \$5; if(wavelen+0 == 0){wavelen=1.5470}}\\
 \$3=="+"{for(i=1;i<=length(\$NF);++i){c=substr(\$NF,i,1);if(c ~ /[_.\\-\\/]/){c=" "};printf "%s", c;};\\
          printf " %.0f %s \\n", 12398.4245/wavelen, wavelen}' | nawk -f \${tempfile}labler.awk |\\
cat >! \${tempfile}labels
set RUNFILE_waves = \`nawk '{print \$NF}' \${tempfile}labels\`

# default to FP for single-wavelength data
if(\$#RUNFILE_waves == 1) then
    cat \${tempfile}labels |\\
    nawk '{\$NF = "FP"; print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \${tempfile}labels
endif

set wavenames = ( \$wavenames )
if("\$#wavenames" != "\$#RUNFILE_waves") then

    # we need to update the wavelength names
    echo "\$wavelengths \$wavenames" |\\
    nawk '{for(i=1;i<=NF/2;++i){print \$i, \$(i+(NF/2))}}' |\\
    cat >! \${tempfile}oldlabels
    
    # filter out NEW lables
    cat \${tempfile}labels \${tempfile}oldlabels |\\
    nawk 'NF>2 || label[\$1] != ""{label[\$1] = \$NF}\\
	  END {for(wave in label) if(label[wave] != "") print wave, label[wave]}' |\\
    sort -n >! \${tempfile}
    mv \${tempfile} \${tempfile}labels
    rm -f \${tempfile}oldlabels
    
    set wavenames   = \`nawk '{print \$NF}' \${tempfile}labels\`
    set wavelengths = \`nawk '{print \$1}' \${tempfile}labels\`
endif 

# update reference wavelength (in case its been removed)
nawk -v ref="\$wave_reference" '\$NF == ref' \${tempfile}labels >! \${tempfile}
set temp = \`cat \${tempfile} | wc -l\`
rm -f \${tempfile} >& /dev/null
if(("\$temp" == 0)&&("\$wave_reference" != "alldata")) then
    # no reference?
    
    # (re)generate labels file
    echo "\$wavenames \$wavelengths" |\\
    nawk '{for(i=1;i<=NF/2;++i){print \$i, \$(i+(NF/2))}}' |\\
    cat >! \${tempfile}labels

    # pick new reference wavelength with the most frames
    cat \$RUNFILE |\\
    nawk '\$2=="wavelength"{lambda=\$5} \$3=="+"{count[lambda]+=1+\$6-\$4} \\
    END{for(lambda in count)print count[lambda], lambda}' |\\
    sort -n | tail -1 | \\
    nawk '{print \$NF}' >! \${tempfile}newref

    # now retrieve the label for this wavelength
    cat \${tempfile}labels \${tempfile}newref |\\
    nawk 'NF == 2{label[\$NF+0] = \$1} NF==1{print \$1, label[\$1+0]}' |\\
    cat >! \${tempfile}refname
    set wave_reference = \`nawk '{print \$NF}' \${tempfile}refname\`

    rm -f \${tempfile}refname >& /dev/null
    rm -f \${tempfile}newref >& /dev/null

    # should always find something, but...
    if("\$wave_reference" == "") set wave_reference = \`echo "\$wavenames" | nawk '{print \$1}'\`

endif

rm -f \${tempfile}labels









set ASU_per_CELL = \`nawk -v SG=\$SG '\$4 == toupper(SG) {print \$2}' \$CLIBD/symop.lib |& head -1\`
if("\$ASU_per_CELL" == "") set ASU_per_CELL = 1


# make unit cell consistent with space group (redundant here)
# check against SG
set temp = \`nawk -v SG="\$SG" '\$4 == toupper(SG) {print \$6}' \$CLIBD/symop.lib |& head -1\`
echo "\$CELL \$temp" |\\
nawk '{a=\$1+0; b=\$2+0; c=\$3+0; A=\$4+0; B=\$5+0; G=\$6+0}\\
    \$NF == "MONOCLINIC" { A=90; ; G=90; if(\$4+0 > 5) B=\$4+0; if(\$5+0 > 5) B=\$5+0}\\
    \$NF == "ORTHORHOMBIC" {A=90; B=90; G=90}\\
    \$NF == "TETRAGONAL" || \$NF == "TRIGONAL" || \$NF == "HEXAGONAL" {\\
    b=a; A=90; B=90; G=120;\\
    if((c==0) && ((\$2-a)^2 > .0001)) {c = \$2+0}}\\
    \$NF == "TETRAGONAL" {G=90}\\
    \$NF == "CUBIC" {b=a; c=a; A=90; B=90; G=90}\\
    END{if(a>5 && b>5 && c>5 && A>5 && B>5 &&G>5) print a, b, c, A, B, G}' |\\
cat >! \${tempfile}
set temp = \`cat \${tempfile}\`
rm -f \${tempfile}
if("\$#temp" == 6) then
    set CELL = \`echo \$temp\`
endif

# calculate unit cell volume
echo \$CELL |\\
nawk 'NF==6{s=3.1415926535897899419/180; A=cos(s*\$4); B=cos(s*\$5); G=cos(s*\$6); \\
 skew = 1 + 2*A*B*G - A*A - B*B - G*G ; if(skew < 0) skew = -skew;\\
 printf "%.3f\\n", \$1*\$2*\$3*sqrt(skew)}' |\\
cat >! \${tempfile}volume
set CELLvolume = \`cat \${tempfile}volume\`
rm -f \${tempfile}volume >> /dev/null


# guess at Vm, if we don't know
if("\$Vm" == "") set Vm = 2.4

# compute ASU mass consistent with this Vm
set ASU = \`echo "\$CELLvolume \$ASU_per_CELL \$Vm" | nawk '\$2+0>0 && \$3+0>0{print (\$1/\$2) / \$3}'\`
if("\$ASU" == "") set ASU = "30000"
set NRES = \`echo "\$ASU" | nawk '{printf "%d", (\$1/120)}'\`

if("\$MASS" == "unknown") then
    # set mass to be consistant with Vm
    set MASS = "\$ASU"
    set CHAINS = 1
endif

if("\$CHAINS" == "") then
    # we have a mass, but don't know how many chains
    
    # decide to round up or down
    set temp = \`echo "\$ASU \$MASS" | nawk '(\$1 % \$2) >= \$2/2{print 1}'\`

    # compute chain count most consistant with Vm
    set CHAINS = \`echo "\$ASU \$MASS \$temp" | nawk '{printf "%d", (\$1/\$2)+\$3}'\`
    
    # probably want to reset number of sites too
    if("\$SITES" != "") then
	set SITES = \`echo "\$SITES \$CHAINS" | nawk '{printf "%d", \$1 * \$2}'\`
    endif
endif

# recalculate Vm from protein mass
set ASU = \`echo "\$CHAINS \$MASS" | nawk '{print \$1 * \$2}'\`
set NRES = \`echo "\$ASU" | nawk '{printf "%d", (\$1/120)}'\`
matthews_coef << end_mat >&! \$tempfile
CELL \$CELL
SYMM \$SG
molweight \$ASU
END
end_mat
set Vm = \`grep "Matthews Coefficient is" \$tempfile | nawk '{print \$NF}' | tail -1\`
set SOLC = \`grep "protein density is" \$tempfile | nawk '{printf "%d", \$NF}' | tail -1\`
rm -f \$tempfile >> /dev/null


# estimate sites from sequence? 
set temp = \`cat \${tempfile}sequence | wc -l\`
if(("\$SITES" == "")&&("\$temp" > 0)) then
    if(("\$METAL" == "Selenium")||("\$METAL" == "Platinum")) then
	# use methionine count as "sites"
	set temp = \`cat \${tempfile}sequence | nawk '/met\$/{met += \$0} END{print met+0}'\`
	if("\$temp" != "0") set SITES = \`echo \$temp \$CHAINS | nawk '{print \$1*\$2}'\`
	rm -f \${tempfile}
    endif
    if("\$METAL" == "Mercury") then
	# use cystine count as "sites"
	set temp = \`cat \${tempfile}sequence | nawk '/cys\$/{cys += \$0} END{print cys+0}'\`
	if("\$temp" != "0") set SITES = \`echo \$temp \$CHAINS | nawk '{print \$1*\$2}'\`
	rm -f \${tempfile}
    endif
    if("\$METAL" == "Gold") then
	# use histidine count as "sites"
	set temp = \`cat \${tempfile}sequence | nawk '/his\$/{his += \$0} END{print his+0}'\`
	if("\$temp" != "0") set SITES = \`echo \$temp \$CHAINS | nawk '{print \$1*\$2}'\`
	rm -f \${tempfile}
    endif
endif

# guess at number of sites that would be "feasible"
if("\$SITES" == "") then
    # just one seems too trivial
    set SITES = \$CHAINS
    # estimate number of sites that would be "doable"
    
    # metal should always be set
    if("\$METAL" != "unknown") then
	# get wavelength of interest
	set temp = \`nawk '/^WAVE/ && \$NF+0 > 0 {print 12398.4245/\$NF}' \${tempfile}stats\`
	if("\$temp" == "") set temp = 8014
	
	# get number of electrons in this metal
	echo \$METAL \$temp | nawk -f \${tempfile}elements.awk |\\
	nawk -v mass=\$ASU '{k=1/((7^2)*mass/14); \\
	print 100*k*(\$1+\$5)^2, 100*k*\$6*\$6, 100*k*\$5*\$5, \$4}' |\\
	nawk '{if(\$1+0 == 0) \$1=99999; \\
	       if(\$2+0 == 0) \$1=99999; \\
	       if(\$3+0 == 0) \$1=99999; \\
	       printf "%d %d %d", 1/\$2, 1/\$3, 10/\$1 }' >! \${tempfile}
	# get sites for 1% Ranom, Rdisp, or 10% Riso
	set temp = \`cat \$tempfile\`
	rm -f \${tempfile}
	
	# update non-trivial numbers of sites
	foreach possibility ( \$temp )
	    if(("\$SITES" == "")&&("\$possibility" > \$CHAINS)&&("\$possibility" < 30)) then
		set SITES = "\$temp"
	    endif
	end
    endif
endif

# don't need this file anymore
rm -f \${tempfile}stats >& /dev/null

# skip questionaire first time through?
if(\$?FIRSTIME) then
    rm -f \${tempfile}elvish >& /dev/null
    goto Calculate
endif

Questionaire:
###############################################################################

  ####   #    #  ######   ####    #####     #     ####   #    #    ##       #   #####   ######
 #    #  #    #  #       #          #       #    #    #  ##   #   #  #      #   #    #  #
 #    #  #    #  #####    ####      #       #    #    #  # #  #  #    #     #   #    #  #####
 #  # #  #    #  #            #     #       #    #    #  #  # #  ######     #   #####   #
 #   #   #    #  #       #    #     #       #    #    #  #   ##  #    #     #   #   #   #
  ### #   ####   ######   ####      #       #     ####   #    #  #    #     #   #    #  ######

###############################################################################
#
#   Question user about parameters that were mentioned, but not explicitly
#   initialized by ginger
#
###############################################################################

grep "SYMM" \${tempfile}elvish >& /dev/null
if(! \$status) then
    set temp = \`nawk '/^SYMM/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" != "") then
	# check this word against the SG library
	if( -e \$CLIBD/symop.lib) then
	    set temp = \`nawk -v SG=\$temp '\$4 == toupper(SG) {print \$4}' \$CLIBD/symop.lib | head -1\`
	endif
	if("\$temp" !~ [PpCcIiFfRrHh][1-6]*) then
	    # must not have been initialized, 
	    # ask user about space group
	    set temp = "\$SG"
	    echo "What is your space group? [\$temp]"
	    echo -n "\$PROMPT"
	    if(! \$?AUTO) then
		echo -n "\$BELL"
		set in = "\$<"
		if("\$in" != "") set temp = "\$in"
	    else
		echo "\$temp"
	    endif

	    # check again
	    if( -e \$CLIBD/symop.lib) then
		set temp = \`nawk -v SG=\$temp '\$4 == toupper(SG) {print \$4}' \$CLIBD/symop.lib | head -1\`
	    endif
	    if("\$temp" =~ [PpCcIiFfRrHh][1-6]*) then
		set SG = "\$temp"
	    else
		# chance to undefine SG
		if("\$temp" =~ unk*) then
		    set SG = unknown
		else
		    echo "Sorry, but "\\"\$temp\\"" is not a space group. "
		    echo "P212121 is a space group. "
		    echo "(You could also say: "\\""unknown space group"\\"" ) "
		endif
	    endif
	endif
	set understood = "\$understood \$temp"
    endif
endif


# unit cell
grep "CELL" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # see if cell was given
    set temp = \`nawk '/^CELL/{print substr(\$0,5)}' \${tempfile}elvish\`
    if("\$temp" == "") then
	set temp = "\$CELL"
	# something is wrong with the cell, but we don't know what
	echo "What is your unit cell? [\$temp]"
	echo -n "\$PROMPT"
	if(! \$?AUTO) then
	    echo -n "\$BELL"
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	else
	    echo "\$temp"
	endif
	
	# now check/correct this (potential) cell against the space group
	set temp = "\$temp "\`nawk -v SG="\$SG" '\$4 == toupper(SG) {print \$6}' \$CLIBD/symop.lib |& head -1\`
	echo "\$temp" |\\
	nawk '{a=\$1+0; b=\$2+0; c=\$3+0; A=\$4+0; B=\$5+0; G=\$6+0}\\
	\$NF == "MONOCLINIC" { A=90; ; G=90; if(\$4+0 > 5) B=\$4+0; if(\$5+0 > 5) B=\$5+0}\\
	\$NF == "ORTHORHOMBIC" {A=90; B=90; G=90}\\
	\$NF == "TETRAGONAL" || \$NF == "TRIGONAL" || \$NF == "HEXAGONAL" {\\
	b=a; A=90; B=90; G=120;\\
	if((c==0) && ((\$2-a)^2 > .0001)) {c = \$2+0}}\\
	\$NF == "TETRAGONAL" {G=90}\\
	\$NF == "CUBIC" {b=a; c=a; A=90; B=90; G=90}\\
	END{if(a>5 && b>5 && c>5 && A>5 && B>5 &&G>5) print a, b, c, A, B, G}' |\\
	cat >! \${tempfile}
	set temp = \`cat \${tempfile}\`
	rm -f \${tempfile}
	if(\$#temp == 6) then
	    # enough info was available to get cell
	    set CELL = \`echo "\$temp"\`
	else
	    # chance to undefine cell
	    if("\$in" =~ unk*) then
		set CELL = "unknown"
	    else
		echo "Sorry, but "\\"\$in\\"" is not a unit cell. "
		echo "This is a unit cell: 89.1 89.1 47.5 90 90 120 "
		echo "(you could also have said "\\"unknown\\"")"
	    endif
	endif
	set understood = "\$understood \$temp"
    endif
endif


# resolution
grep "RESO" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # see if value was given
    set temp = \`nawk '/^RESO/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" !~ [0-9]*) then
	set temp = "\$hiRES"
	# something is wrong with this parameter, but we don't know what
	echo "How far could this crystal possibly diffract? [\$temp A]"
	echo -n "\$PROMPT"
	if(! \$?AUTO) then
	    echo -n "\$BELL"
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	else
	    echo "\$temp"
	endif
	set temp = \`echo "RESO \$temp" | nawk -f \${tempfile}ginger.awk | nawk '/^RESO/{print \$NF}'\`
	if("\$temp" =~ [0-9]*) then
	    set hiRES = "\$temp"
	    set USER_hiRES = "\$temp"
	else
	    echo "Sorry, but "\\"\$in\\"" doesn't tell us anything. "
	    echo "Resolution limit is probably 10 - 0.4 Angstroms. "
	endif
	set understood = "\$understood \$temp"
    endif
    # see if other value was given
    set temp = \`nawk '/^loRESO/{print \$NF}' \${tempfile}elvish\`
    if(("\$temp" !~ [0-9]*)&&("\$temp" != "")) then
	set temp = "\$loRES"
	# something is wrong with this parameter, but we don't know what
	echo "What is the lowest (smallest angle) resolution measured? [\$temp A]"
	echo -n "\$PROMPT"
	if(! \$?AUTO) then
	    echo -n "\$BELL"
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	else
	    echo "\$temp"
	endif
	set temp = \`echo "low RESO \$temp" | nawk -f \${tempfile}ginger.awk | nawk '/^loRESO/{print \$NF}'\`
	if("\$temp" =~ [0-9]*) then
	    set loRES = "\$temp"
	else
	    echo "Sorry, but "\\"\$in\\"" doesn't tell us anything. "
	    echo "Low-Resolution limit is probably > 10 Angstroms. "
	endif
	set understood = "\$understood \$temp"
    endif
endif


# Matthews number/solvent content
grep "VM " \${tempfile}elvish >& /dev/null
if(! \$status) then
    # see if value was given
    set temp = \`nawk '/^VM/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" !~ [0-9]*) then
	set temp = "\$Vm"
	# something is wrong with this parameter, but we don't know what
	echo "What is this crystal's Matthews number/solvent content? [\$temp]"
	echo -n "\$PROMPT"
	if(! \$?AUTO) then
	    echo -n "\$BELL"
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	else
	    echo "\$temp"
	endif
	
	# check user input with ginger
	set temp = \`echo "Vm \$temp" | nawk -f \${tempfile}ginger.awk | nawk '/^VM/{print \$NF}'\`
	if("\$temp" =~ [0-9]*) then
	    set Vm = "\$temp"
	    # forget the chain count, recalculate it later
	    if(("\$CHAINS" != "")&&("\$SITES" != "")) then
		if("\$SITES" != "") then
		    # reset number of sites to monomer count
		    set temp = \`echo "\$SITES \$CHAINS" | nawk '\$2+0 > 0 {printf "%d", \$1/\$2}'\`
		    if("\$temp" > 0) set SITES = \$temp
		endif
		# reset mass if Vm was explicitly specified
		if("\$CHAINS" == 1) set MASS = "unknown"
		# redetermine chain count
		set CHAINS = ""
	    endif
	    set understood = "\$understood \$temp"
	else
	    echo "Sorry, but "\\"\$in\\"" doesn't tell us anything. "
	    echo "Matthews numbers usually range from 1.2 to 5. "
	    echo "Solvent contents usually range from 45% to 80%. "
	endif
	set understood = "\$understood \$temp"
    endif
endif

# Protein MASS size
grep "MASS" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # see if an actual mass value was given
    set temp = \`nawk '/^MASS/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" !~ [0-9]*) then
	# something is wrong with this parameter, but we don't know what
	set temp = "\$MASS"
	echo "What is the molecular weight of your protein? [\$temp g/mol]"
	echo -n "\$PROMPT"
	if(! \$?AUTO) then
	    echo -n "\$BELL"
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	else
	    echo "\$temp"
	endif
	if("\$in" != "") set temp = "\$in"

	# now check user input with Ginger
	set temp = \`echo "MASS \$temp" | nawk -f \${tempfile}ginger.awk | nawk '/^MASS/{print \$NF}'\`
	if("\$temp" =~ [0-9]*) then
	    set MASS = "\$temp"
	else
	    echo "Sorry, but "\\"\$in\\"" doesn't tell us anything. "
	    echo "Protein is probably > 1000 g/mol. "
	endif
	set understood = "\$understood \$temp"
    endif
endif

# ASU size/chain number
grep "ASU " \${tempfile}elvish >& /dev/null
if(! \$status) then
    # see if value was given
    set temp = \`nawk '/^ASU/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" !~ [0-9]*) then
	set temp = "\$CHAINS"
	if("\$CHAINS" == "") set temp = "1"
	# something is wrong with this parameter, but we don't know what
	echo "How many chains do you expect in the asymmetric unit? [\$temp/pick for Vm=\$Vm]"
	echo -n "\$PROMPT"
	if(! \$?AUTO) then
	    echo -n "\$BELL"
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	else
	    echo "\$temp"
	endif
	set temp = \`echo "ASU \$temp" | nawk -f \${tempfile}ginger.awk | nawk '/^ASU/{print \$NF}'\`
	if("\$temp" =~ [0-9]*) then
	    # most likely need to update metal sites too
	    if(("\$CHAINS" > 1)&&("\$SITES" != "")) then
		set SITES = \`echo "\$SITES \$CHAINS \$temp" | nawk '\$2 > 0{printf "%d", (\$1/\$2) * \$3}'\`
	    endif
	    set CHAINS = "\$temp"
	else
	    # a few more possibilities
	    if(("\$in" =~ *pick*)||(" \$in " =~ " 0 ")) then
		# re-guess number of chains
		set CHAINS = ""
	    else
		echo "Sorry, but "\\"\$in\\"" doesn't tell us anything. "
		echo "Sometimes, crystals have two or more protein chains in the asymmetric unit. "
	    endif
	endif
	set understood = "\$understood \$temp"
    endif
endif

# number of metal sites
grep "SITES" \${tempfile}elvish >& /dev/null
if(! \$status) then
    # see if value was given
    set temp = \`nawk '/^SITES/{print \$NF}' \${tempfile}elvish\`
    if("\$temp" !~ [0-9]*) then
	set temp = "\$SITES"
	# something is wrong with this parameter, but we don't know what
	echo "How many metal sites do you expect per protein? [\$temp]"
	echo -n "\$PROMPT"
	if(! \$?AUTO) then
	    echo -n "\$BELL"
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	else
	    echo "\$temp"
	endif
	set temp = \`echo "SITES \$temp" | nawk -f \${tempfile}ginger.awk | nawk '/^SITES/{print \$NF}'\`
	if("\$temp" =~ [0-9]*) then
	    # see if user mentioned protein mass in the same breath
	    set SITES = "\$temp"
	    grep "MASS" \${tempfile}elvish >& /dev/null
	    if(! \$status) then
		# sites are probably per protein, not per ASU
		if("\$CHAINS" != "") then
		    set temp = \`echo "\$SITES \$CHAINS" | nawk '\$1*\$2 > 1 {printf "%d", \$1*\$2}'\`
		    if("\$temp" != "") set SITES = "\$temp"
		endif
	    endif
	else
	    echo "Sorry, but "\\"\$in\\"" doesn't tell us anything. "
	    echo "You probably have 1-50 metal sites. "
	endif
	set understood = "\$understood \$temp"
    endif
endif


rm -f \${tempfile}elvish >& /dev/null



# check for completely incomprehensible input
set input = \`head -1 \${tempfile}input\`
rm -f \${tempfile}input
if(("\$understood" == "")&&("\$input" != "")) then
    set temp = "nothing"
    echo "Um, what, exactly, do you mean by "\\"\$input\\"" [\$temp]? "
    echo -n "\$PROMPT"
    if(! \$?AUTO) then
	echo -n "\$BELL"
	set in = "\$<"
	if("\$in" != "") set temp = "\$in"
    else
	echo "\$temp"
    endif
    if("\$temp" != "nothing") then
	set input = "\$temp"
	goto Gather
    endif
endif




Calculate:
###############################################################################

  ####     ##    #        ####   #    #  #         ##     #####  ######
 #    #   #  #   #       #    #  #    #  #        #  #      #    #
 #       #    #  #       #       #    #  #       #    #     #    #####
 #       ######  #       #       #    #  #       ######     #    #
 #    #  #    #  #       #    #  #    #  #       #    #     #    #
  ####   #    #  ######   ####    ####   ######  #    #     #    ######

###############################################################################
#
#   (re)calculate interdependent parameters
#
###############################################################################
# first of all, check that we have data
set temp = \`nawk '/^run/' \$RUNFILE | wc -l\`
if(\$temp == 0) then
    echo "no data, we will look for some."
    goto MTZsearch
endif

set ASU_per_CELL = \`nawk -v SG=\$SG '\$4 == toupper(SG) {print \$2}' \$CLIBD/symop.lib |& head -1\`
if("\$ASU_per_CELL" == "") set ASU_per_CELL = 1

# make unit cell consistant with space group (redundant here)
# check against SG
set temp = \`nawk -v SG="\$SG" '\$4 == toupper(SG) {print \$6}' \$CLIBD/symop.lib |& head -1\`
echo "\$CELL \$temp" |\\
nawk '{a=\$1+0; b=\$2+0; c=\$3+0; A=\$4+0; B=\$5+0; G=\$6+0}\\
    \$NF == "MONOCLINIC" { A=90; ; G=90; if(\$4+0 > 5) B=\$4+0; if(\$5+0 > 5) B=\$5+0}\\
    \$NF == "ORTHORHOMBIC" {A=90; B=90; G=90}\\
    \$NF == "TETRAGONAL" || \$NF == "TRIGONAL" || \$NF == "HEXAGONAL" {\\
    b=a; A=90; B=90; G=120;\\
    if((c==0) && ((\$2-a)^2 > .0001)) {c = \$2+0}}\\
    \$NF == "TETRAGONAL" {G=90}\\
    \$NF == "CUBIC" {b=a; c=a; A=90; B=90; G=90}\\
    END{if(a>5 && b>5 && c>5 && A>5 && B>5 &&G>5) print a, b, c, A, B, G}' |\\
cat >! \${tempfile}
set temp = \`cat \${tempfile}\`
rm -f \${tempfile}
if("\$#temp" == 6) then
    set CELL = \`echo \$temp\`
endif

# calculate unit cell volume
echo \$CELL |\\
nawk 'NF==6{s=3.1415926535897899419/180; A=cos(s*\$4); B=cos(s*\$5); G=cos(s*\$6); \\
 skew = 1 + 2*A*B*G - A*A - B*B - G*G ; if(skew < 0) skew = -skew;\\
 printf "%.3f\\n", \$1*\$2*\$3*sqrt(skew)}' |\\
cat >! \${tempfile}volume
set CELLvolume = \`cat \${tempfile}volume\`
rm -f \${tempfile}volume >> /dev/null


# guess at Vm, if we don't know
if("\$Vm" == "") set Vm = 2.4

# compute ASU mass consistent with this Vm
set ASU = \`echo "\$CELLvolume \$ASU_per_CELL \$Vm" | nawk '\$2+0>0 && \$3+0>0{print (\$1/\$2) / \$3}'\`
if("\$ASU" == "") set ASU = "30000"
set NRES = \`echo "\$ASU" | nawk '{printf "%d", (\$1/120)}'\`

if("\$MASS" == "unknown") then
    # set mass to be consistant with Vm
    set MASS = "\$ASU"
    set CHAINS = 1
endif

if("\$CHAINS" == "") then
    # we have a mass, but don't know how many chains
    
    # decide to round up or down
    set temp = \`echo "\$ASU \$MASS" | nawk '(\$1 % \$2) >= \$2/2{print 1}'\`

    # compute chain count most consistant with Vm
    set CHAINS = \`echo "\$ASU \$MASS \$temp" | nawk '{printf "%d", (\$1/\$2)+\$3}'\`
    echo "\$CHAINS chains fit best with Vm = \$Vm"
    
    # probably want to reset number of sites too
    if("\$SITES" != "") then
	set SITES = \`echo "\$SITES \$CHAINS" | nawk '{printf "%d", \$1 * \$2}'\`
    endif
endif


CheckAll:
###############################################################################

  ####   #    #  ######   ####   #    #            ##    #       #
 #    #  #    #  #       #    #  #   #            #  #   #       #
 #       ######  #####   #       ####            #    #  #       #
 #       #    #  #       #       #  #            ######  #       #
 #    #  #    #  #       #    #  #   #           #    #  #       #
  ####   #    #  ######   ####   #    #          #    #  ######  ######

###############################################################################
#
#	Last-minute checks on sensitive parameters
#
###############################################################################

# (re)calculate final Vm
set ASU = \`echo "\$CHAINS \$MASS" | nawk '{print \$1 * \$2}'\`
set NRES = \`echo "\$ASU" | nawk '{printf "%d", (\$1/120)}'\`
matthews_coef << end_mat >&! \$tempfile
CELL \$CELL
SYMM \$SG
molweight \$ASU
END
end_mat
set Vm = \`grep "Matthews Coefficient is" \$tempfile | nawk '{print \$NF}' | tail -1\`
set SOLC = \`grep "protein density is" \$tempfile | nawk '{printf "%d", \$NF}' | tail -1\`
rm -f \$tempfile >> /dev/null




# load "ADD" values into awk program, for back-calculating frame numbers later
echo "#! \$nawk -f" >! \${tempfile}unadd.awk
echo "# \$TITLE awk program for retrieving original frame number/file" >> \${tempfile}unadd.awk
echo "# from Scaler-created mtzs" >> \${tempfile}unadd.awk
cat \$RUNFILE |\\
nawk '\$3=="+"{add=\$2;for(b=\$4;b<=\$6;++b){printf "\$1 == %d {print \\"%d in %s\\"}\\n", b+add, b, \$NF}}' |\\
cat >> \${tempfile}unadd.awk
chmod a+x \${tempfile}unadd.awk



###############################################################################
# check the rules file for bad cards (by running it by scala)
###############################################################################

# insert SDCORR into rules file
grep "SDCORR" \$RULESFILE | tail -1 >! \${tempfile}rules
if(\$status) then
    # no SDCORR card!
    echo "SDCORR \$defaultSDCORR"  >! \${tempfile}rules
endif
cat \$RULESFILE |\\
nawk 'NF>1{for(i=1;i<=NF && (\$i !~ /^#/);++i){printf "%s ", \$i}; print ""}' |\\
sort -u  | grep -iv "SDCORR" >> \${tempfile}rules
mv \${tempfile}rules \$RULESFILE


# make a meaningless hkl file
echo "   1   1   1  1  1 " >! \${tempfile}.hkl

# create an mtz from it
f2mtz hklin \${tempfile}.hkl hklout \${tempfile}prepme.mtz << EOF >& /dev/null
TITLE dummy mtz for testing scala
SYMM 1
CELL 100 100 100 90.00 90.00 90
LABOUT H K L I SIGI
CTYPOUT H H H R R
SKIP 0
END
EOF

# make it a multirecord MTZ
combat hklin \${tempfile}prepme.mtz  hklout \${tempfile}sortme.mtz << EOF >& /dev/null
input mtzi
batch 1
labin I=I SIGI=SIGI
EOF
if(\$status) then
echo "combat sucks ... trying rotaprep"
rotaprep  hklin \${tempfile}prepme.mtz  hklout \${tempfile}sortme.mtz << EOF >& /dev/null
input mtzi
batch 1
labin I=I SIGI=SIGI
EOF
endif

# sort it
sortmtz hklin \${tempfile}sortme.mtz hklout \${tempfile}dummy.mtz << EOF >& /dev/null
\${USE_VRSET}VRSET -9E+38
H K L M/ISYM BATCH I SIGI
EOF

rm -f \${tempfile}.hkl
rm -f \${tempfile}prepme.mtz
rm -f \${tempfile}sortme.mtz
#
set badcards = 1
# don't bother checking cards again (if we already checked)
if(! \$?CHECK_SCALA_CARDS) set badcards = 0
set catchloop = 20
while((\$badcards > 0)&&(\$catchloop > 0))
    # make temporary, do-nothing input file
    cat \$RULESFILE >! \${tempfile}in
    echo "INIT NONE" >> \${tempfile}in
    echo "OUTPUT NONE" >> \${tempfile}in
    echo "NOSCALE" >> \${tempfile}in
    
    # feed this file into scala
    cat \${tempfile}in |\\
    scala hklin \${tempfile}dummy.mtz  hklout /dev/null rogues /dev/null >&! \${tempfile}log
#    if(\$status) set catchloop = 0

    # look for rejected keywords
    cat \${tempfile}log |\\
    nawk '/^ Data line/,/ Run number/' |\\
    nawk '\$1 ~ /[\\052]/{print "BADCARD " last} /^ Data line/{last = substr(\$0,15)}' |\\
    cat >! \${tempfile}badcards
    # support html logfile
    cat \${tempfile}log |\\
    nawk '/Input keyworded commands/,/Contents/' |\\
    nawk '\$1 ~ /[\\052]/{print "BADCARD " last} {last = \$0}' |\\
    nawk 'NF > 1' >> \${tempfile}badcards

    set badcards = \`cat \${tempfile}badcards | wc -l\`

    if(\$badcards) then
	echo "eliminating: "
	nawk '{print substr(\$0, 9)}' \${tempfile}badcards | sort -u
	echo "scala did not accept these keywords"
    endif

    # remove the rejected keywords (based on word-wise comparison)
    cat \${tempfile}badcards \$RULESFILE |\\
    nawk '/^BADCARD/{++N;badcard[N]=substr(\$0,8);}\\
     ! /^BADCARD/{okay=1; for(n in badcard){split(badcard[n],badword);\\
       isbad=1; for(i=1;i<=NF;++i){if(badword[i] != \$i){isbad=0}}; if(isbad) okay=0} \\
                  if(okay) print}' |\\
    cat >! \${tempfile}newcards
    mv \${tempfile}newcards \$RULESFILE 
    
    # try again if there was a problem
    @ catchloop = ( \$catchloop - 1 )
end


if(\$catchloop < 1) then
    # check to see if scala simply won't run
    echo "INIT NONE" >! \${tempfile}in
    echo "OUTPUT NONE" >> \${tempfile}in
    echo "NOSCALE" >> \${tempfile}in

    # feed this file into scala
    cat \${tempfile}in |\\
    scala hklin \${tempfile}dummy.mtz  hklout /dev/null rogues /dev/null >&! \${tempfile}log
    if(\$status) then
	# cards weren't the problem. Scala just can't run
	cat << EOF
WARNING: unable to run scala on \`hostname -s\`
	this could be due to insufficient memory, write-protected disks, 
	or just absence of the scala program.  The elves will go ahead and
	set up scala scripts, but they aren't going to run until scala is
	fixed (as your SysAdmin (root) if you don't know how to do this).
EOF
	set NORUN
    else
	# couldn't remove some kind of bad card
	echo "WARNING: one of the following SCALA commands is bad, but we "
	echo "         can't tell which.  They will all be commented out."
	cat \$RULESFILE
	mv \$RULESFILE \${tempfile}
	nawk '{print "#" \$0}' \${tempfile} >! \$RULESFILE
    endif
endif

# clean up
rm -f \${tempfile}dummy.mtz
rm -f \${tempfile}badcards
rm -f \${tempfile}log
rm -f \${tempfile}in
unset CHECK_SCALA_CARDS

# (re)insert SDCORR into rules file
grep "SDCORR" \$RULESFILE >& /dev/null
if(\$status) then
    # no SDCORR card!
    mv \$RULESFILE \${tempfile}rules
    echo "SDCORR \$defaultSDCORR"  >! \$RULESFILE
    grep -v "SDCORR" \${tempfile}rules >> \$RULESFILE
    rm -f \${tempfile}rules
endif





#########################################
# now update labels in the run file     #
#########################################
echo "\$wavelengths \$wavenames" |\\
nawk '{for(i=1;i<=NF/2;++i){print \$i, \$(i+(NF/2))}}' |\\
cat >! \${tempfile}labels

cat \${tempfile}labels \$RUNFILE |\\
nawk 'NF==2{label[\$1+0]=\$2} \$2=="wavelength"{\$3 = label[\$5+0]}\\
 NF != 2{print}' >! \${tempfile}runs
mv \${tempfile}runs \$RUNFILE

rm -f \${tempfile}labels





# get alternative space groups (Patterson and index equivalent)
if(-e \$CLIBD/symop.lib) then
    cat \$CLIBD/symop.lib |\\
    nawk -v SG=\$SG '\$5 ~ /^PG/ && ! /m/ && ! /bar/ && \$1 < 500 {sys = substr(\$4, 1, 1); \\
    PG[\$4]=sys \$5; SGs[sys \$5] = SGs[sys \$5] " " \$4} \\
    END{print SGs[PG[SG]]}' >! \${tempfile}

    set otherSGs = \`cat \${tempfile}\`
    
    # add on (potentially) unsupported orthorhombics
    if("\$otherSGs" =~ *P222*) then
	set otherSGs = \`echo "\$otherSGs P2212 P2122 P21221 P22121"\`
    endif
    if("\$otherSGs" =~ *C222*) then
	#set otherSGs = \`echo "\$otherSGs C2122 C2212"\`
    endif
    
    
    rm -f \${tempfile}
endif






Report:
###############################################################################

 #####   ######  #####    ####   #####    #####
 #    #  #       #    #  #    #  #    #     #
 #    #  #####   #    #  #    #  #    #     #
 #####   #       #####   #    #  #####      #
 #   #   #       #       #    #  #   #      #
 #    #  ######  #        ####   #    #     #

###############################################################################
#
#   Create presentation for user's approval
#
###############################################################################

echo ""
echo "Scaler elves will localscale and merge your data with"
echo ""
if(\$#wavenames != 1) echo "\$#wavenames wavelengths:"
if(\$#wavenames == 1) echo "\$#wavenames wavelength:"
if(\$?USER_REFERENCE) then
    cat \$RUNFILE |\\
    nawk  '\$2=="wavelength"{printf "%.5f \\305  \\"%s\\"\\n", \$5, \$3;}'
    echo "reference set is \$refMTZ"
else
    if("\$wave_reference" == "alldata") echo "reference set will be all data"
    cat \$RUNFILE |\\
    nawk  -v ref=\$wave_reference '\$2=="wavelength"{\\
      printf "%.5f \\305  \\"%s\\"", \$5, \$3; \\
      if(\$3==ref){print "    <- reference"}else{print ""}}'
endif
echo ""
# format mtz info for user approval
cat \$RUNFILE | \\
nawk '\$2=="wavelength"{name = \$3} \\
\$3=="+"{++n; mtz[n]=\$NF; label[n]=name; first[n]=\$4; last[n]=\$6; \\
       if(w1 < length(first[n]))  w1=length(first[n]); \\
       if(w2 < length(last[n]))  w2=length(last[n]); \\
       if(w3 < length(mtz[n]))  w3=length(mtz[n]);}\\
    END {printf "%"w1"s%"w2"s   %-"w3"s  as wavelength\\n", "", "frames", "from file";\\
    for(i=1;i<=n;++i){ \\
    printf "%"w1"d to %"w2"d  %-"w3"s  %s\\n", first[i], last[i], mtz[i], label[i];}}'

if(\$?KEEP_ALL_FRAMES) echo "Elves will not reject any of these frames"
echo ""
echo "The following SCALA cards will be used:"
cat \$RULESFILE
#echo "(see \$CCP4/doc/scala.doc about what they mean.)"

echo ""
echo "Resolution : \$hiRES \$ANG - \$loRES \$ANG"
echo "Space group: \$SG"
echo "Unit Cell  : \$CELL"
echo "        Vm : \$Vm (\${SOLC}% solvent)"
echo "Asymmetric unit contains:"
echo "1/\$ASU_per_CELL of unit cell, "
echo -n "\$ASU Da of protein, "
if("\$CHAINS" > 1) echo -n "( \$CHAINS \$MASS Da chains )"
echo ""
echo "\$SITES \$METAL sites. (expected)"
echo ""







# master checkpoint
unset FIRSTIME
set temp = "Yes"
echo "Everything look okay? [\$temp]"
echo -n "\$PROMPT"
if(\$?AUTO) then
    echo "\$temp"
else
    echo -n "\$BELL"
    set in = "\$<"
    if("\$in" != "") set temp = "\$in"
endif
set temp = \`echo \$temp\`

# catch unexpected replies
if(("\$temp" !~ [Yy]*)||(\$#temp != 1)) then
    if((\$#temp == 1)&&("\$temp" =~ [Nn]*)) then
	# one word, began with "N"
	set temp = "nothing"
	echo "What's wrong? [\$temp]?"
	if(\$?AUTO) then
	    echo "\$temp"
	else
	    set in = "\$<"
	    if("\$in" != "") set temp = "\$in"
	endif
	set quit = \`echo " \$temp " | egrep -i " quit | stop | exit "\`
	if("\$quit" != "") then
	    goto Cleanup
	endif
	if("\$temp" != "nothing") then
	    set input = "\$temp"
	    goto Gather
	endif
    else
	set input = "\$temp"
	goto Gather
    endif
endif

# user said everything is okay!

echo "Good. Don't go away."


set FIRSTIME

# re-update wavelength info from the report file (in case it was changed)
set wavenames   = \`nawk '\$2=="wavelength"{print \$3}' \$RUNFILE\`
set wavelengths = \`nawk '\$2=="wavelength"{print \$5}' \$RUNFILE\`

MakeDirs:
###############################################################################
#
# create/verify required subdirectories
#
###############################################################################

foreach dir ( \$LOG_dir \$MTZ_dir \$MAP_dir \$SCRIPT_dir \$SHARP_dir \$SHELX_dir \$SOLVE_dir \$XPLOR_dir )
    # see if it's already done
    set temp = \`ls -ld \$dir |& nawk '/^d/{print \$NF}'\`
    if((-e "\$dir")&&(! -e "\$temp")) then
	# a file is using this name
	echo "WARNING: we are moving your \$dir to \${dir}.old"
	mv -f \$dir \${dir}.old
    endif
    if(! -e "\$dir") mkdir \$dir
end


# now print out scripts consistent with the above values
echo "setting up scripts in \${SCRIPT_dir}/..."
if(-e \${tempfile}unadd.awk) then
    cp \${tempfile}unadd.awk \${SCRIPT_dir}/unadd.awk >& /dev/null
endif

if(\$?DENZO_FILES) then
    # need this to prepare denzo files
    mv \${tempfile}x2york.awk \${SCRIPT_dir}/x2york.awk
    chmod a+x \${SCRIPT_dir}/x2york.awk
#    mv \${tempfile}strategy denzo.strategy
else
    # aren't going to need this
    rm -f \${tempfile}x2york.awk >& /dev/null
endif

# remove unneded files
if(! \$?DEBUG) then
    rm -f \${tempfile}input         >& /dev/null
    rm -f \${tempfile}batches       >& /dev/null
#    rm -f \${tempfile}elements.awk  >& /dev/null
    rm -f \${tempfile}ginger.awk    >& /dev/null
    rm -f \${tempfile}labler.awk    >& /dev/null
    rm -f \${tempfile}parser.awk    >& /dev/null
    rm -f \${tempfile}unadd.awk     >& /dev/null
    rm -f \${tempfile}sequencer.awk >& /dev/null
    rm -f \${tempfile}sequence     >& /dev/null
#    rm -f \${tempfile}runlist      >& /dev/null
#    rm -f \${tempfile}x2york.awk   >& /dev/null
#    rm -f \${tempfile}xfiles       >& /dev/null
endif

goto Generate
# Uses:
\$RUNFILE
\$RULESFILE

# Info files
#\${SCRIPT_dir}/runlist.txt
#\${SCRIPT_dir}/rules.txt

# actual scaling scripts
#\${SCRIPT_dir}/sort_everything.com
#\${SCRIPT_dir}/make_reference_set.com
#\${SCRIPT_dir}/import_reference.com
#\${SCRIPT_dir}/rough_scale.com
#\${SCRIPT_dir}/localscale.com
#\${SCRIPT_dir}/merge.com
#\${SCRIPT_dir}/extract.com
#\${SCRIPT_dir}/scaleit.com

# utilities
#\$SCRIPT_dir/FreeRer.com
#\$SCRIPT_dir/mtz2various.com
#\$SCRIPT_dir/SGsearch.com
#\$SCRIPT_dir/reindex.com
#\$SCRIPT_dir/bestFH.com
#\$SCRIPT_dir/revise.com
#\$SCRIPT_dir/mtz_sum.com
#\$SCRIPT_dir/scala_summary.com
#\$SCRIPT_dir/autoscala

Return_from_Generate:



# Set up SOLVE, (if we havn't already)
if((! \$?SOLVE_SET_UP)&&(! \$?NO_SOLVE)) then
    echo "setting up solve in \${SOLVE_dir}"
    goto Setup_SOLVE
endif
# \${SOLVE_dir}/spacegroup/solve.com
# \${SOLVE_dir}/mtz2SOLVE.com

Return_from_Setup_SOLVE:





# set up SHELX (if we havn't already)
if(! \$?SHELX_SET_UP) then
    echo "setting up shelx in \${SHELX_dir}"
    goto Setup_SHELX
endif
#\${SHELX_dir}/spacegroup/shelxs.ins, etc.
#\${SHELX_dir}/SHELX2pdb.com
#\${SHELX_dir}/mtz2SHELX.com
#\${SHELX_dir}/SHELX.com

Return_from_Setup_SHELX:






# x-plor setup (just converter script right now)
if(! \$?XPLOR_SET_UP) then
    echo "setting up X-PLOR in \${XPLOR_dir}"
    goto Setup_XPLOR
endif
#\${XPLOR_dir}/mtz2XPLOR.com
Return_from_Setup_XPLOR:





# checkpoint??
CheckPoint:
if(\$?FIRSTIME) then
    # don't need this anymore
    if(! \$?DEBUG) rm -f \${tempfile}elements.awk  >& /dev/null

    cat << EOF >! \${tempfile}message
    
    Scaler Elves are now ready to start scaling your data.  Scripts
to run "solve" and "shelx" have been set up, but have no data
files yet.  Your raw data must be scaled and merged first.
    However, since scaling can take longer that you will probably 
want to hang around, there are a few questions we would like you
to answer now:

Would you like to:
1)  Have the Elves give you some merged data to look at ASAP.
2)  Use these scripts to process your data yourself, thankyouverymuch.
3)  Let the Elves edit the scripts, and improve parameters automatically.
EOF
    cat \${tempfile}message
    set temp = "3"
    if(\$?HURRY_UP) set temp = "1"
    echo "Choose a strategy [\$temp]"
    echo -n "\$PROMPT"
    if(\$?AUTO) then
	echo "\$temp"
    else
	echo -n "\$BELL"
	set in = "\$<"
	if("\$in" != "") set temp = "\$in"
    endif

    # check the actual message for clues
    nawk -v pick="\$temp" '\$0 ~ pick' \${tempfile}message |\\
    nawk '/^[1-3]/{print substr(\$1, 1, 1)}' | head -1 >! \${tempfile}
    set in = \`cat \${tempfile}\`
    rm -f \${tempfile}        >& /dev/null
    rm -f \${tempfile}message >& /dev/null

    if("\$in" == "") then
	# what the hell? 
    
    else
	# something was chosen
	if(("\$in" == "1")||(\$?HURRY_UP)) then
	    # ASAP
	    echo "Hurrying up..."
	    set SDCORR_OPTIMIZED
	    set BREAKS_SET_UP
	    set RESOLUTION_OK
	    set HURRY_UP
	endif

	if("\$in" == "2") then
	    # quit
	    echo "It's all yours! "
	    echo "Don't forget to read the README files. "
	
	    goto Cleanup
	endif

	if("\$in" == "3") then
	    # what we planned to do anyway
	    echo "Okay, we'll take it from here."
	    unset HURRY_UP
	endif
    endif
endif
unset FIRSTIME


# fastest possible route to numbers
if(\$?HURRY_UP) then

    # just use the make file
    make | tee -a \${LOG_dir}/make.log
    if((\$status)||(! -e "\${finalMTZ}")) then
	# something went wrong

	if((-e "\${rscaleMTZ}")&&(! -e \${lscaleMTZ})&&(! \$?ROUGHSCALE_ONLY)) then
	    # localscaling seems to have failed

	    # user wants numbers now, so just bypass local scaling
	    echo "reverting to one-batch-per-frame scaling in \${rscaleMTZ}."
	    mv \${LOG_dir}/localscale.log \${LOG_dir}/localscale.log.bad
	    set ROUGHSCALE_ONLY
	    #cp \${rscaleMTZ} \${lscaleMTZ}
	    
	    # let's try that again
	    goto Scaling_Scripts
	endif
	goto FixProblem
    endif

    # done with first numbers, exit
    echo "Elves will make no further modifications to improve your scripts."
    echo "Enjoy your data! "
    echo ""
    goto Cleanup
endif

# first, we need the combined raw-data file
make -q \${rawMTZ}
if(\$status) then
    # make the file
    make \${rawMTZ} | tee -a \${LOG_dir}/make.log
    if(\$status) goto FixProblem
endif

# preemtively re-parse runs with scala's initial scales
if((! \$?FINAL_JUMPS)&&(! \$?INITIAL_JUMPS)) then
    set INITIAL_JUMPS
    # speical, short scala run to just get initial intensities
    set lastLOG = "\${LOG_dir}/initial_scales.log"
    echo "determining gross, initial scales (see \${lastLOG})"
    scala hklin \${rawMTZ} << EOF-initscale >! \${lastLOG}
# same resolution range
RESOLUTION \$hiRES \$loRES
# scales only, no B-factor
INTENSities partials
SCALES batch bfactor off
# only calculate initial scales for all batches
INITIAL mean
cycles 0
noscale
output none
final none
EOF-initscale
    if(\$status) then
	echo "ERROR determining initial scales."
	# too many parameters? 
	# if so, there's no way we can get initial scales
	goto FixProblem
    endif

    # make an xloggraph table in the log file
    cat \${lastLOG} |\\
    nawk 'BEGIN{print "\$TABLE : Initial Scales :"; print "\$GRAPHS:scale vs batch:N:1, 3: \$\$";\\
                print "batch batch_number scale \$\$ \$\$"} \\
	/Run number/ && /consists of batches/{run=\$3; rot=1;\\
		while (NF){ getline; for(i=1;i<=NF;++i){ \\
		batch[run "." rot] = \$i; ++rot; }}}     \\
	/Initial scales for run/{ run = \$NF; rot=1; \\
		while (NF){ getline; for(i=1;i<=NF;++i){ \\
		printf "%5d %6d %s\\n", rot, batch[run "." rot], \$i; ++rot}}}\\
	END{print "\$\$"}' |\\
    cat >! \${tempfile}init_scales
    cat \${tempfile}init_scales >> \${lastLOG}
    rm -f \${tempfile}init_scales >& /dev/null

    
    # use this log as input to the usual discontinuity detector
    set lastLOG = "\${LOG_dir}/initial_scales.log"
    goto Discontinuities
endif





ProcessData:

# bring processing up to first all-frame scaling round
make -q \${rscaleMTZ}
if(\$status) then
    # rscaleMTZ is not up-to-date
    date >> \${LOG_dir}/make.log
    make \${rscaleMTZ} | tee -a \${LOG_dir}/make.log
    if(\$status) goto FixProblem
    set lastLOG = \${rscaleLOG}

    # check for problems
    grep "no overlaps" \${lastLOG} >& /dev/null
    if(! \$status) then
	set GAPS
	goto Overlaps
    endif

    grep "Error in refscl/dsyev" \${lastLOG} >& /dev/null
    if(! \$status) then
	set REFSCL_BUG
	goto FixProblem
    endif

    grep "Negative scale" \${lastLOG} >& /dev/null
    if(! \$status) then
	goto FixProblem
    endif

    grep "not converged" \${lastLOG} >& /dev/null
    if(! \$status) then
	goto FixProblem
    endif

    if(! -e "\${rscaleMTZ}") goto FixProblem
endif




###############################################################################
#
#	Improvements
#
###############################################################################
#   This section uses the results of the first scaling run to
#   improve upon scala's input.  The appropriate changes will
#   be made, and the scripts updated.
###############################################################################

# make sure files are there!
unset GAPS
if(-e "\${lastLOG}") then
    grep "no overlaps" \${lastLOG} >& /dev/null
    if(! \$status) then
	set GAPS
    endif
endif

Overlaps:
###############################
# fill in gaps
###############################
if(\$?GAPS) then
    # there were gaps
    echo "Some frames had no spots in common with any other frames, "
    echo "and, therefore, undefined scale."
    
    # check to see if partials can be used
    set temp = \`nawk '\$1 ~ /^INTEN/ && \$2 ~ /^PART/ && NF==2' \$RULESFILE\`
    if("\$temp" == "") then
	# increase effective mean-normalized mosaicity
	set MOSAIC = \`echo \$MOSAIC | nawk '{while(\$1 < 0.27){\$1 *= 1.5}; print \$1 * 1.5}'\`
	
	# evaluate (as in stats setup)
	echo \$MOSAIC |\\
	nawk '\$NF > 0.34{print \$NF, 0.577 - 0.226*log(\$NF-0.333)}' |\\
	nawk '\$NF < 0.99{printf "INTENSITIES SCALE_PARTIALS %.2f\\n", \$NF};\\
	\$NF < 0.7 {printf "INTENSITIES PARTIALS MAXWIDTH %d\\n", \$1+1.5;}' |\\
	nawk '/MAXWIDTH/{if(\$NF>6){print "INTENSITIES PARTIALS"}else{print}}  ! /MAXWIDTH/' |\\
	tail -1 >! \${tempfile}parts
	
	# update RULES file
	nawk '! (/^INTEN/ && /PART/)' \$RULESFILE >! \${tempfile}rules
	cat \${tempfile}parts >> \${tempfile}rules
	mv \${tempfile}rules \$RULESFILE
	
	echo "changeing INTENS card to:"
	nawk '/^INTENS/' \$RULESFILE
	
	# need to re-create scaling scripts
	rm -f \${tempfile}parts >& /dev/null
	goto Scaling_Scripts
    endif

    # no more partials can be added to scaling
    
    # try using the smoothing function? 
    if(("\$SCALING" == "batch")&&(! \$?TRIED_EARLY_SMOOTH)) then
	# havn't tried smooth scaling yet.
	set TRIED_EARLY_SMOOTH
	
	echo "imposing smooth scales..."
	set SCALING = smooth
	set BFACTOR = smooth
		
	goto Scaling_Scripts
    endif 

    if((\$SPACING < 30)&&(! \$?TRIED_MORE_SMOOTH)) then
	# did smooth scaling, just not enough?
	set TRIED_MORE_SMOOTH
	
	set temp = \`echo \$SPACING | nawk '{printf "%d", 2*\$1}'\`
	if(\$temp != "") then
	    set SPACING = "\$temp"
	    
	    echo "increasing smoothing requirement to \${SPACING}\$DEG window"
	    goto Scaling_Scripts
	endif
    endif
    
#    # evidently, smoothing didn't work
#    if("\$SCALING" != "batch") then
#	echo "switching back to frame-by-frame scales."
#	set SCALING = "batch"
#	set BFACTOR = "batch"
#	set SPACING = 10
#    endif
    
    # Look for "hopeless" batches (no scalable spots)
    cat \${lastLOG} |\\
    nawk '/ERROR: no overlaps with batch/{print \$NF}' |\\
    nawk 'BEGIN{FS="."} NF!=0{print "hopeless", \$1, \$2}' |\\
    cat >! \${tempfile}hopeless
    
    # get input batch number from run definitions file
    cat \${tempfile}hopeless \$RUNFILE |\\
    nawk '/^hopeless /{badrun[\$2]=badrun[\$2] " " \$3-1} \\
	  /^run/{if(badrun[\$2] != ""){n=split(badrun[\$2],bad); \\
	         for(i=1;i<=n;++i){print \$3+bad[i]}}}' |\\
    cat >! \${tempfile}badframes
    rm -f \${tempfile}hopeless
	
    # see if we got anything
    set temp = \`nawk 'NF>0' \${tempfile}badframes | wc -l\`
    if((\$temp > 0)&&(! \$?KEEP_ALL_FRAMES)) then
	# we got some "hopeless" frames
	
	# jump ahead to the bad-frame eliminator
	goto BadFrames
    else
	# Can't do anything more with the gaps
	set CANT_FIX_GAPS
	rm -f \${tempfile}badframes
	goto FixProblem
    endif    
endif







FindBadFrames:
###############################
# find bad/outlier frames (based on R factor)
###############################
if(! -e \${lastLOG}) then
    # no logfile? what the hell? 
    goto FixProblem
else
    grep "SIGM0 Imean" \${lastLOG} >& /dev/null
    if(\$status) then
	# table is not here
	goto FixProblem
    endif
    
    # look for frames with Rfactor > 3x mean
    cat \${lastLOG} |\\
    nawk '/SIGM0 Imean/,NF==0' |\\
    nawk '/Rfactor /{ofst=index(\$0, "Rfactor")} \\
       \$1 ~ /^[0-9]/{badness[\$2]=substr(\$0, ofst)+0;\\
       mean+=badness[\$2]; ++n}\\
    END{if(n){mean/=n; for(frame in badness){if(badness[frame]+0>3*mean)print frame}}}' |\\
    sort -n -k2 >! \${tempfile}badframes
    
    # check to see if any frames were singled out
    set badframes = \`cat \${tempfile}badframes | wc -l\`
    if(\$badframes > 50) then
	# too many bad frames
	echo "intra-frame statistics are very bad."
	echo "you might have the wrong space group! "
	echo "Elves suggest inspecting your frames, and"
	echo "maybe trying a lower-symmetry space group."
	set badframes = 0
    endif
    if(\$badframes == 0) then
	# no bad frames, so get rid of this file
	rm -f \${tempfile}badframes >& /dev/null
    endif
endif

BadFrames:
###############################
# exclude bad frames? 
###############################
if(-e "\${tempfile}badframes") then

    # allow other procedures to eliminate frames via \${tempfile}badframes
    set badframes = \`cat \${tempfile}badframes | wc -l\`

    if(\$badframes != 0) then
	if(\$badframes == 1) then
	    echo "1 frame appears especially bad:"
	else
	    echo "\$badframes frames appear especially bad:"
	endif
	
	# report baddies to user (in familiar context)
	cat \${tempfile}badframes | nawk -f \${SCRIPT_dir}/unadd.awk
	

	# bad frames will be CUMULATIVELY eliminated
	cat \${tempfile}badframes \$RUNFILE |\\
	nawk 'NF==1 && \$1+0==\$1{Bad[\$1]=1} ! /^run / && NF!=1{print} \\
 	    /^run /{start=\$3; end=\$5; \\
	      while(Bad[start]){++start}; while(Bad[end]){--end}; \\
	      if(start <= end){++run;\\
		printf "run %5d %5d to ", run, start;\\
		for(b=start;b<=end;++b){\\
		    if(Bad[b]){printf "%5d\\n", b-1; ++run;\\
		    while(Bad[b]){++b};\\
		    printf "run %5d %5d to ", run, b;}};\\
		printf "%5d\\n", end;}}' |\\
	cat >! \${tempfile}newruns
	rm -f \${tempfile}badframes >& /dev/null
	
	# update new run list
	if((! \$?KEEP_ALL_FRAMES)&&(! \$?FINAL_JUMPS)) then
#	if(! \$?KEEP_ALL_FRAMES) then
	    echo "updating run definitions in \$RUNFILE ... "
	    mv \${tempfile}newruns \$RUNFILE
	    
	    # since there WERE bad frames, \$RUNFILE has changed, so we need to
	    # remake \${rscaleMTZ}
	    goto Scaling_Scripts
	else
	    rm -f \${tempfile}newruns >& /dev/null
	    echo "Please review the original images, and data reduction runs"
	    echo "for these frames.  IF there is nothing wrong with them..."
	    goto UnFixable
	endif
    endif
    
    rm -f \${tempfile}badframes >& /dev/null
endif






Discontinuities:
###############################
# look for discontinuities of scale
###############################
if(! -e \${lastLOG}) then
    goto FixProblem
else
    # get scale table from the log
    cat \${lastLOG} |\\
    nawk '/ Scales v rotation range/,/Total/' |\\
    nawk 'NF>2 && ! /[a-z]/{print \$4, \$6}' |\\
    cat >! \${tempfile}scales
    
    set temp = \`cat \${tempfile}scales | wc -l\`
#    if((\$temp == 0)&&("\$SCALING" == "batch")) then
    if(\$temp == 0) then
	# try initial scales?
	cat \${lastLOG} |\\
	nawk '/Run number/ && /consists of batches/{run=\$3; rot=1;\\
		while (NF){ getline; for(i=1;i<=NF;++i){ \\
       		  batch[run "." rot] = \$i; ++rot; }}}     \\
		/Initial scales for run/{ run = \$NF; rot=1; \\
		while (NF){ getline; for(i=1;i<=NF;++i){ \\
       		  print batch[run "." rot], \$i; ++rot}}}' |\\
   	cat >! \${tempfile}scales
    endif
    
    # convert scales to "jumps"
    cat \${tempfile}scales |\\
    nawk '{if(S+0!=0 && \$2+0!=0){jump=\$2/S; if(jump<1)jump=1/jump;\\
           print \$1, jump}else{print \$1, 1}; S=\$2}' |\\
    cat >! \${tempfile}jumps
    rm -f \${tempfile}scales >& /dev/null
    
    # compute sigma of all scale jumps
    set sigma = \`cat \${tempfile}jumps | nawk '{++n; sum += (\$2-1)^2} END{if(n*sum > 0) print sqrt(sum/n)}'\`
   
    # check to see if this worked
    if("\$sigma" == "") then
	# no scale information
	goto FixProblem
    endif
 
    # re-seal old breaks, but don't ressurrect rejected frames
    cat \${tempfile}jumps \$RUNFILE |\\
    nawk ' ! /^run /{print}  NF==2 && \$1+0==\$1 {Used[\$1]=1} \\
      \$3=="+"{add=\$2; start=\$4+add; end=\$6+add; \\
          while((! Used[start])&&(start < \$6+add)){++start};\\
          while((!   Used[end])&&(end   > \$4+add)){--end};  \\
	  if(start <= end){++run; \\
	  printf "run %5d %5d to ", run, start;\\
	  for(b=start;b<=end;++b){\\
		    if(! Used[b]){printf "%5d\\n", b-1; ++run;\\
		    while(! Used[b]){++b};\\
		    printf "run %5d %5d to ", run, b;}};\\
	  printf "%5d\\n", end};}' |\\
    cat >! \${tempfile}sealedruns
    
    # now break-up new runs at scale jumps > 3 sigma 
    cat \${tempfile}sealedruns |\\
    nawk -v sigma=\$sigma 'NF==2 && \$2 > 1+3*sigma{Break[\$1]=1} ! /^run/ && NF != 2{print} \\
      /^run /{++run; printf "run %5d %5d to ", run, \$3; \\
	   for(b=\$3;b<\$5;++b){if(Break[b+1]){++run;\\
	       printf "%5d\\nrun %5d %5d to ", b, run, b+1;}};\\
	printf "%5d\\n", \$5;}' |\\
    cat >! \${tempfile}newruns
	
    
    # clean up a bit
    rm -f \${tempfile}sealedruns >& /dev/null
    rm -f \${tempfile}jumps >& /dev/null
    
    # make sure we havn't thrown out entire wavelengths
    set newruns = \`nawk '/^run/' \${tempfile}newruns | wc -l\`
    set oldruns = \`nawk '/^run/' \$RUNFILE | wc -l\`
    set temp = \`nawk '\$2=="wavelength"' \${tempfile}newruns | wc -l\`
    if(\$temp < \$#wavelengths) then
	# no runs found
	echo "unable to interpret scales from \${lastLOG}."
	rm -f \${tempfile}newruns >& /dev/null

	# don't change anything
	echo "\$RUNFILE will remain unchanged."
	set newruns = \$oldruns
	#goto FixProblem
    endif

    # and not too many runs
    if(\$newruns > 25) then
	echo "too many scale discontinuities."
	echo "\$RUNFILE will be unchanged."
	
	rm -f \${tempfile}newruns >& /dev/null
	set newruns = \$oldruns
    endif
    

    # only adjust run file if run definition has actually changed
    if("\$oldruns" < "\$newruns") then
	# better way to avoid oscillation?
	#set FINAL_JUMPS
	
	# rebuild run list
	echo "Found \$newruns contiguous groups of scales."
	echo "updating run definitions to:"
	
	# display new run definitions for the user
	cat \${tempfile}newruns | \\
	nawk '\$2=="wavelength"{label = \$3} \\
	\$3=="+"{file=\$NF; add=\$2;} /^run /{print \$3-add, \$5-add, file, label}' |\\
	nawk '{++n; first[n]=\$1; last[n]=\$2; file[n]=\$3; label[n]=\$4; \\
	       if(w1 < length(first[n]))  w1=length(first[n]); \\
	       if(w2 < length(last[n]))  w2=length(last[n]); \\
	       if(w3 < length(file[n]))  w3=length(file[n]);}\\
	    END {printf "%"w1"s%"w2"s   %-"w3"s  as wavelength\\n", "", "frames", "from file";\\
	    for(i=1;i<=n;++i){ \\
	    printf "%"w1"d to %"w2"d  %-"w3"s  %s\\n", first[i], last[i], file[i], label[i];}}'

	if(\$?FINAL_JUMPS) then
	    echo "However, \$RUNFILE will remain unchanged."
	    rm -f \${tempfile}newruns >& /dev/null
	    goto LocalScaling
	endif
	
	mv \${tempfile}newruns \$RUNFILE
	
	# make sure we're NOT doing smooth scales next
	if("\$SCALING" == "smooth") echo "switching back to framewise scales."
	set SCALING = "batch"
	set BFACTOR = "smooth"
	
	# need to edit scaling scripts again
	goto RoughScale
    endif
    
    # no mid-run discontinuities, so do all-smooth scaling next
    if("\$SCALING" == "batch") then
	echo "switching to smooth scales."
	rm -f \${tempfile}newruns >& /dev/null
	set SCALING = "smooth"
	set BFACTOR = "smooth"
	
	# need to edit scaling scripts again
	goto RoughScale
    endif
    
    # didn't need this
    rm -f \${tempfile}newruns >& /dev/null
endif




LocalScaling:
# finish up all scaling (but don't do mergeing yet)
if(\$?ROUGHSCALE_ONLY) then
    # mimic localscaling
    echo "skipping localscaling"
    if("\${rscaleMTZ}" != "\${lscaleMTZ}") ln -sf \`basename \${rscaleMTZ}\` \${lscaleMTZ}
    goto OptimizeSDCORR
endif
set lastLOG = \${lscaleLOG}
make \${lscaleMTZ} | tee -a \${LOG_dir}/make.log
if((\$status)||(! -e "\${lscaleMTZ}")) goto FixProblem

# check for problems
grep "no overlaps" \${lastLOG} >& /dev/null
if(! \$status) then
    set GAPS
    goto Overlaps
endif

grep "Negative scale" \${lastLOG} >& /dev/null
if(! \$status) then
    goto FixProblem
endif

grep "not converged" \${lastLOG} >& /dev/null
if(! \$status) then
    goto FixProblem
endif





OptimizeSDCORR:
###############################
# optimize SDCORRections
###############################
if(! \$?SDCORR_OPTIMIZED) then
    
    set sdfac = \`nawk '/^SDCORR/{print \$2}' \$RULESFILE\`
    # get scala-refined sdfac value
    if(-e "\$lastLOG") then
	cat \${lastLOG} |\\
	nawk '/Final assessment of SDcorrection multipliers/{getline;getline;getline;getline;\\
	      while(NF>2){if(\$2 != 1.0000){++n; print; sum+=(\$2+\$5)/2}; getline}; if(n) printf "%.2f\\n", sum/n}' |\\
	cat >! \${tempfile}
	set temp = \`tail -1 \${tempfile} | nawk '\$1 > 0.8 && \$1 < 5{print \$1}'\`
	rm -f \${tempfile}
	if("\$temp" != "") set sdfac = "\$temp"
    endif

    # blurb about what autoscala is:
    echo "Optimizing SDCORR command in scala... (see \${SCRIPT_dir}/README for details)"
    
    # run autoscala on modified scala script (mergeing reference set)
    cat \${SCRIPT_dir}/merge.com |\\
    nawk -v wave=\$wave_reference '/^set wave/{\$NF = wave} {print}' |\\
    nawk -v sdfac=\$sdfac 'toupper(\$0) ~ /^SDCORR/{print "SDCORR", sdfac, \$3, \$4} toupper(\$0) !~ /^SDCORR/' |\\
    nawk '/^truncate hkl/{print "rm -f " \$3 " >& /dev/null"; print "exit"} {print}' |\\
    cat >! \${SCRIPT_dir}/test.com
    
#    # run autoscala on modified scala script (mergeing everything)
#    cat \${SCRIPT_dir}/merge.com |\\
#    nawk -v wave="all" '/^set wave/{\$NF = wave} {print}' |\\
#    nawk -v sdfac=\$sdfac 'toupper(\$0) ~ /^SDCORR/{print "SDCORR", sdfac, \$3, \$4} toupper(\$0) !~ /^SDCORR/' |\\
#    nawk '/^truncate hkl/{print "rm -f " \$3 " >& /dev/null"; print "exit"} {print}' |\\
#    cat >! \${SCRIPT_dir}/test.com
    
    \${SCRIPT_dir}/autoscala summary=no \${SCRIPT_dir}/test.com | tee \${LOG_dir}/autoscala.log
    rm -f \${SCRIPT_dir}/test.com_test >& /dev/null
    rm -f \${SCRIPT_dir}/test.com >& /dev/null
    
    grep SDCORR \${SCRIPT_dir}/test.com_best >& /dev/null
    if(! \$status) then
	# retrieve our new SDCORR value
	cat \${SCRIPT_dir}/test.com_best |\\
	nawk 'toupper(\$0) ~ /^SDCORR/{print toupper(\$0)}' >! \${tempfile}
	
	# inform user of what we are doing
	echo "Updating error corrections to:"
	cat \${tempfile}
	
	# update "rules" file
	nawk '! /^SDCORR/' \$RULESFILE >> \${tempfile}
	mv \${tempfile} \$RULESFILE
    else
	# what the hell?
	echo "Unable to determine new SDCORRections! "
	echo "will still use:"
	grep "SDCORR" \$RULESFILE
    endif
    
    rm -f \${SCRIPT_dir}/test.com_best >& /dev/null
    
    # only do this once
    set SDCORR_OPTIMIZED
    goto RoughScale
endif


CutResolution:
###############################
# evaluate outer resolution limit (once SDCORR has been optimized)
###############################
if((! \$?RESOLUTION_OK)&&(-e "\${lastLOG}")) then
    cat \${lastLOG} |\\
    nawk '\$3 == "Dmin(A)"{skip=12;idx=index(\$0,"Mn");}\\
     {--skip; if(skip == 0){print substr(\$0,idx,7)}}' |\\
     sort -n >! \${tempfile}signal
    set signal = \`head -1 \${tempfile}signal\`
    rm -f \${tempfile}signal
    
    # should have been detected earlier, but
    if("\$signal" == "") then
	goto FixProblem
    endif
    
    echo "Your outer resolution bin has I/sigma = \$signal"
    set signal = \`echo "\$signal" | nawk '{printf "%d", \$1*10}'\`
    if("\$signal" > 40) then
	echo "You could probably measure to higher resolution! "
	echo ""
	# extend resolution upward? (risk oscillation?)
    endif
    if("\$signal" < 15) then
	cat \${lastLOG} |\\
	nawk '\$3 == "Dmin(A)",/Overall/' |\\
	nawk '! /[^0-9. -]/{print} /Dmin/{print "idx",index(\$0,"Mn")}' | \\
	nawk '/^idx/{idx=\$2;next} NF>3 && (substr(\$0,idx,7)+0 > 2) {print \$3}' |\\
	sort -n >! \${tempfile}reso
	set newRES = \`head -1 \${tempfile}reso\`
	rm -f \${tempfile}reso
	set newRES = \`echo "\$newRES \$hiRES" | nawk 'NF==2 && \$1+0>\$2+0{print \$1}'\`
	
	if("\$newRES" == "") then
	    # bad log file?
	    set newRES = \`echo \$hiRES | nawk '{print \$1 * 1.1}'\`
	endif
	
	echo "This means there are no real spots at \$hiRES A."
	echo "Elves suggest \$newRES A as a cutoff."
	
	# ask permission?
	#echo "What resolution cutoff do you want? [\$temp]"
	
	if(! \$?USER_hiRES) then
	    # reset high resolution limit
	    set hiRES = "\$newRES"
	    unset SDCORR_OPTIMIZED
	
	    # update scaling scripts
	    goto RoughScale
	endif
    endif
    set RESOLUTION_OK
endif




# check convergence?
if(! -e "\${lastLOG}") goto FixProblem
set badLOG = \`grep -l "not converged" \${lastLOG} |& nawk 'NF==1' | head -1\`
if(-e "\$badLOG") goto FixProblem




# what else is there to fiddle with? 




# finish building all targets
# now that we can be confident truncate won't quit
make -i | tee -a \${LOG_dir}/make.log
if((\$status)||(! -e "\${finalMTZ}")) then
    goto FixProblem
endif



# edit SOLVE files?


#goto RunSOLVE


#goto RunwARP


goto Cleanup












exit
FixProblem:
#
#	Fix Known Problems with Scaler Elves scripts
#
if(\$?FIX_PROBLEMS) then
    # CRAP!

    # figure out where we went wrong
    set temp = \`ls -1 \${mergeLOG}* \${extractLOG}* |& nawk 'NF==1'\`
    ls -1t \$sortLOG \$refLOG \$rscaleLOG \$lscaleLOG \$finalLOG \$temp |&\\
    nawk 'NF==1' >! \${tempfile}allLOG

    set allLOGs = \`cat \${tempfile}allLOG |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
    
    if("\$lastLOG" == "") then
	# some kind of problem on this system?
	set lastLOG = "\${LOG_dir}/"\`ls -1t \${LOG_dir} | head -1\`
    endif
    set badLOG = "\$lastLOG"
    
    echo "Procedure failed in: \$lastLOG"
    set badSCRIPT = \`grep "\$lastLOG" Makefile | grep "\${SCRIPT_dir}" | nawk '{print \$2}'\`
    
    # detect un-fixable problems
    if("\$lastLOG" == "") then
	# some kind of problem on this system?
	goto UnFixable
    endif
    
    if("\$lastLOG" =~ \${extractLOG}*) then
	# no fixes for these! (that we know of)
	goto UnFixable
    endif
    if("\$lastLOG" =~ \${finalLOG}*) then
	# no fixes for this! (that we know of)
	goto UnFixable
    endif
    
    
    
    # look for problems we know how to solve
   
    # new mosflm, old sortmtz
    set badLOG = \`grep -l "You must either scale down the data or change VRSET" \${allLOGs} |& nawk 'NF==1' | head -1\`
    if(-e "\$badLOG" && "\$USE_VRSET" != "") then

        echo "new mosflm and old sortmtz ... trying to use VRSET"
        set USE_VRSET = ""

        unset cycles
        goto SortScript
    endif

    
    # rare bug in scala 4.x
    set badLOG = \`grep -l "Error in refscl/dsyev" \${allLOGs} |& nawk 'NF==1' | head -1\`
    if(-e "\$badLOG" && ! \$?NO_REFERENCE) then

	echo "trouble scaling to reference set ... throwing it out"
	set NO_REFERENCE

	unset cycles
	goto Scaling_Scripts	
	
    endif


    # new "feature" in 5.0.x
    set badLOG = \`grep -l "batches are not assigned to datasets" \${allLOGs} |& nawk 'NF==1' | head -1\`
    if(-e "\$badLOG" && ! \$?RENAME_DATASETS) then

        echo "scala is complaining about dataset info in headers ... rewriting it"
        set RENAME_DATASETS

        unset cycles
        goto SortScript

    endif

    if("\$lastLOG" == "\$sortLOG") then
        # no fixes for sorting (that we know of)
       goto UnFixable
    endif
 
    # convergence (oscillating? )
    set badLOG = \`grep -l "not converged" \${lastLOG} |& nawk 'NF==1' | head -1\`
    if(-e "\$badLOG") then

	echo -n "scaling didn't reach convergence, "
	
	# look through EXTRA_ARGS exacly as scaling scripts did
	set FILTER = "#"
	set cycles = \$CYCLES
	set temp = ""
	foreach arg ( \$EXTRA_ARGS )
	    # may override default filtering
	    if("\$arg" == "filter") then
		set FILTER = ""
	    endif
	    
	    # raw numbers become cycle counts
	    if(("\$arg" =~ [1-9]*)&&("\$arg" =~ *[0-9])) then
		set cycles = "\$arg"
		set arg = ""
	    endif
	    
	    # rebuild list without cycle count
	    set temp = "\$temp \$arg"
	end
	
	# increase number of cycles given before
	@ cycles = ( \$cycles + 50 )
	echo "will try \$cycles scaling rounds this time."
	set EXTRA_ARGS = "\$temp \$cycles"
	
	if(("\$cycles" > 110)&&("\$FILTER" == "#")) then
	    # maybe try damping?
	    set EXTRA_ARGS = "\$EXTRA_ARGS filter"
	    set FILTER = ""
	endif
	
	# report what's going on
	if("\$FILTER" == "") echo "eigenvalue filter is active."
    
	unset cycles
	goto Scaling_Scripts
    endif


    # lack-of-overlap problems
    set badLOG = \`grep -l "no overlaps" "\${lastLOG}" | head -1\`
    if(("\$badLOG" != "")&&(! \$?CANT_FIX_GAPS)) then
	# back up this "problem" run
	cp \$badLOG \${badLOG}.bad >& /dev/null
	set badLOG = "\${badLOG}.bad"
	set GAPS
	goto Overlaps
    endif
    
    # truncate crash
    set badLOG = \`grep -l "Data beyond useful resolution limit" "\$lastLOG" | head -1\`
    if("\$badLOG" != "") then
	echo "\$hiRES A bin has no real spots in it."
    
        # back it up, for user examination
	cp \$badLOG \${badLOG}.bad >& /dev/null
        set badLOG = "\${badLOG}.bad"

	cat \${badLOG} |\\
	nawk '/Wilson Plot/,/TRUNCATE/' |\\
	nawk 'NF==10 && ! /[a-z]/{print \$6}' |\\
	tail -1 >! \${tempfile}res
	set newRES = \`cat \${tempfile}res\`
	rm -f \${tempfile}res
	
	# update high-res limit
	set temp = \`echo "\$hiRES \$newRES" | nawk '{printf "%d", 100*(\$2-\$1)}'\`
	if("\$temp" < 5) then
	    # slight decrease in resolution cutoff
	    set hiRES = \`echo "\$hiRES" | nawk '{printf "%.2f", \$1 * 1.05}'\`
	else
	    # use the reso from last good bin in truncate
	    set hiRES = "\$newRES"
	endif
	
	# use ordinary resolution cutoff adjuster?
	#unset RESOLUTION_OK
	#goto CutResolution

	echo "Elves suggest \$hiRES A as a cutoff."
	
	if(\$?RESOLUTION_OK) goto Merger
	goto RoughScale
    endif
    
    # check for any further mergeing problems (like what? )
    if("\$lastLOG" =~ \${mergeLOG}*) then
	# no fixes for these! (that weren't considered above)
	goto UnFixable
    endif
    
    
    # now we know the problem is with a scaling script
    
    # negative scale?
    set badLOG = \`grep -l "Negative scale" \${allLOGs} | head -1\`
    if("\$badLOG" != "") then
   
	echo "Scale went negative in \$badLOG"
	
	# back it up, for user review
        cp \$badLOG \${badLOG}.bad >& /dev/null
        #set badLOG = "\${badLOG}.bad"
	
	# smooth B-factors?
	if(("\$BFACTOR" == "batch")&&("\$SCALING" == "batch")&&("\$badLOG" != "\$lscaleLOG")) then
	    # try smoothing B-factor only
	    set SCALING = batch
	    set BFACTOR = smooth
	    
	    echo "constraining B-factors to vary smoothly."
	    goto RoughScale
	endif
	
	# dampen shifts?
	egrep -i "^FILT|^DAMP" \$RULESFILE \$badSCRIPT >& /dev/null
	if(\$status) then
	    # no damping yet, let's do it! 
	    echo "Enabling damping function."
	    echo "Scaling will be slower, but more stable."
	    echo "\$CYCLES" | nawk '{printf "DAMP 0.1 %d\\n", \$1/2}' |\\
	    cat >> \$RULESFILE
	    
	    # re-generate all scaling scripts
	    if("\$badLOG" == "\$refLOG") goto Scaling_Scripts
	    goto RoughScale
	else
	    # check if scaling failed once damping was released?
	    set lastcycle = \`grep "Cycle" \$badLOG | wc -l\`
	    set lastDAMPcycle = \`nawk '\$3=="DAMP"{damp=\$NF} END{print damp+0}' \$badLOG\`
	    if((\$lastcycle > \$lastDAMPcycle)&& (\$CYCLES < 201)) then
		# just do more cycles of damping
		@ lastDAMPcycle = ( \$lastcycle + 50 )
		@ CYCLES = ( \$lastDAMPcycle + 50 )
		
		# add this to the rules file
		echo "DAMP 0.1 \$lastDAMPcycle" >> \$RULESFILE
		
		echo "Damping for \$lastDAMPcycle cycles this time..."
		if("\$badLOG" == "\$refLOG") goto Scaling_Scripts
		goto RoughScale
	    endif
	endif
	
	# increase smoothing window? (if we are using smooth scales)
	if(( ("\$badLOG" == "\$lscaleLOG")||("\$SCALING" == "smooth") )&&(\$SPACING < 30)&&(! \$?TRIED_MORE_SMOOTH)) then
	    # try doubling the spacing
	    set temp = \`echo \$SPACING | nawk '{printf "%d", 2*\$1}'\`
	    if(\$temp > 1) then
		set SPACING = "\$temp"
		set TRIED_MORE_SMOOTH
		
		echo "increasing the smooth scaling requirement to a \${SPACING}\$DEG window."
		goto RoughScale
	    endif
	endif
	
	# add "tie" cards
	egrep -i "^TIE" \$RULESFILE \$badSCRIPT >& /dev/null
	if(\$status) then
	    # no "ties" between scales, might as well try it.
	    echo "forcing neighboring scales to be within 0.1 sigmas."
	    echo "TIE ROTATION 0.1" >> \$RULESFILE
	    if("\$badLOG" == "\$lscaleLOG") echo "TIE DETECTOR 0.1" >> \$RULESFILE
	    
	    # re-generate all scaling scripts
	    if("\$badLOG" == "\$refLOG") goto Scaling_Scripts
	    goto RoughScale
	endif
	
	
	# last resort: throw out suspect frames
	cat \${badLOG} |\\
	nawk '/Negative scale factor/{print \$(NF-2)}' |\\
	cat >! \${tempfile}badframes
	
	# if we got some, go to bad-frame eliminator
	set badframes = \`nawk 'NF>0' \${tempfile}badframes | wc -l\`
	if((\$badframes > 0)&&(! \$?KEEP_ALL_FRAMES)) then
	    unset NO_BAD_FRAMES
	    goto BadFrames
	endif
	
    endif
    
    
    
    # too many parameters?
    set badLOG = \`grep -l "Too many parameters" \${allLOGs} | head -1\`
    if("\$badLOG" != "") then
   	echo ""
	echo "Too many free parameters for this version of scala! "
	if("\$BFACTOR" == "batch") then
	    echo "trying smooth B factors to reduce free parameters."
	    echo ""
	    set BFACTOR = "smooth"
	    goto Scaling_Scripts
	endif
	set temp = \`echo \$SPACING | nawk '{printf "%d", 2*\$1}'\`
	if((\$temp > 1)&&(\$temp < 30)) then
	    set SPACING = "\$temp"
	    set TRIED_MORE_SMOOTH
		
	    echo "increasing the smoothing window to \${SPACING}\$DEG."
	    echo ""
	    goto Scaling_Scripts
	endif
	if("\$SCALING" == "batch") then
	    echo "trying smooth scale factors to reduce free parameters."
	    echo ""
	    set SCALING = "smooth"
	    goto Scaling_Scripts
	endif
	echo ""
	echo "Elves cannot compensate for this problem."
	echo "You must either reduce the amount of data (frames) in this run, "
	echo "or ask your sysadmin to recompile scala with increased limits."
	echo ""
	goto UnFixable
    endif


    
    



    # BLIND fixes:
    
    # increase spacing?
    if((\$SPACING < 30)&&(! \$?TRIED_MORE_SMOOTH)) then
	# try doubling the spacing
	set temp = \`echo \$SPACING | nawk '{printf "%d", 2*\$1}'\`
	if(\$temp != "") then
	    set SPACING = "\$temp"
	    set SCALING = smooth
	    set BFACTOR = smooth
	    set TRIED_MORE_SMOOTH
		
	    echo "increasing the smooth scaling requirement to a \${SPACING}\$DEG window."
	    goto RoughScale
	endif
    endif
    
    # reduce spacing?
    if((\$SPACING > 3)) then
	# try cutting it by 2/3
	set temp = \`echo \$SPACING | nawk '{printf "%d", 2*\$1/3}'\`
	if(\$temp > 1) then
	    set SPACING = "\$temp"
	    set SCALING = smooth
	    set BFACTOR = smooth
	    echo "relaxing the smooth scaling requirement to a \${SPACING}\$DEG window."
	    goto RoughScale
	endif
    endif

    
    
    # give up on localscaling
    if(("\$badLOG" == "\$lscaleLOG")&&(! \$?ROUGHSCALE_ONLY)) then
	# localscaling has been failing, and we don't see why
	set ROUGHSCALE_ONLY
	
	echo "giving up on localscaling."
	#echo "copying \${rscaleMTZ} to \${lscaleMTZ}"

        # "fake" localscaling routine
	set lscaleMTZ = \$rscaleMTZ
        #cp \${rscaleMTZ} \${lscaleMTZ}
	
	goto RoughScale
    endif
endif

    
# place some magic code here? 
    
    
UnFixable:
# display error messages from the log
tail -300 \$lastLOG |\\
nawk 'NF>1 && \$2 != ":"' |\\
nawk 'tolower(\$0) ~ /error/{for(i=1;i<3;++i){print; getline}}'

# get the name of the offending script
set badSCRIPT = \`grep "\$lastLOG" Makefile | grep "\${SCRIPT_dir}" | nawk '{print \$2}'\`

echo ""
echo "Elves are not yet trained for this! "
echo "You had better start reading the scala manual: "
if(\$?CDOC) then
    echo "\${CDOC}/scala.doc"
endif
if(\$?CHTML) then
    echo "\${CHTML}/scala.html"
endif
echo ""
echo "Please examine \$lastLOG and see if you can figure out what to do."
echo "Then edit \$badSCRIPT"
echo "then type: make"
echo ""
exit 9

goto Generate













exit
Generate:
################################################################################
#
#	First, deploy useful utilities for Elves and Humans
#
################################################################################




FreeRer:
################################################################################

#######                                 ######
#        #####   ######  ######         #     #
#        #    #  #       #              #     #
#####    #    #  #####   #####   #####  ######
#        #####   #       #              #   #
#        #   #   #       #              #    #
#        #    #  ######  ######         #     #

################################################################################
#
#	create Elves version of uniqueify (with inheritance)
#
################################################################################
set SCRIPT = \$SCRIPT_dir/FreeRer.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#  Automatically generated script for setting up consistent FREE R flags
#
#   FreeRer.com
#
#  Unlike "uniqueify", FreeRer.com can "inherit" free R flags from another file 
#  (mtz or X-plor)
#
#
# set this to wherever your awk program is
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set tempfile = \\\$CCP4_SCR/FreeRer\\\$\\\$

# defaults
set unfree = ""
set flagfile = ""
set outfile = FreeRed.mtz
set XPLORfile = XPLOR.cv
set FRAC = 0.05


# process command-line input
foreach arg ( \\\$* )
    # user may specify free-R fraction
    if("\\\$arg" =~ [1-9]*%) set FRAC = \\\`echo "\\\$arg" | nawk '{print (\\\$1 + 0)/100}'\\\`
    if("\\\$arg" =~ 0.*) set FRAC = \\\`echo "\\\$arg" | nawk 'if((\\\$1+0)>0) {print \\\$1 + 0}'\\\`

    # look for MTZ files
    if(("\\\$arg" =~ *.mtz)&&(-e "\\\$arg")) then
	if(! -e "\\\$unfree") then
	    # file to recieve free-R flags is first MTZ encountered
	    set unfree = "\\\$arg"	    
	else
	    # make sure that potential free-R source contains free-R flags
	    mtzdump HKLIN "\\\$arg" << EOF-dump >! \\\${tempfile}
HEAD
go
EOF-dump
	    grep "FreeR_flag" \\\${tempfile} >& /dev/null
	    if(! \\\$status) set flagfile = "\\\$arg"
	endif
	rm -f \\\${tempfile} >& /dev/null
    else
	# free-R source can also be an X-plor hkl file
	if(-e "\\\$arg") then
	    grep "TEST" "\\\$arg" >& /dev/null
	    if(! \\\$status) set flagfile = "\\\$arg"
	endif
    endif
end

if(! -e "\\\$unfree") then
    cat << EOF
usage: \\\$0 mtzfile.mtz [free-R source] [fraction[%]]

Free R flags can be inherited from "free-R source" (mtz or X-plor)
or a new set can be defined as "fraction" of the data in mtzfile.mtz
and the resulting file will be "polished" to fill in missing flags.

EOF
    exit 1
endif

# print out what we are going to do
if(-e "\\\$flagfile") then
    set temp = "\\\${flagfile}'s"
else
    set temp = \\\`echo \\\$FRAC | nawk '{print 100*\\\$1"%"}'\\\`
endif
echo "\\\\n\\\\nadding \\\$temp FreeR_flag to \\\$unfree in output files: \\\$outfile and \\\$XPLORfile"
echo ""
echo ""
# get variables from the input MTZ
mtzdump HKLIN \\\$unfree << EOF-dump >! \\\${tempfile}
HEAD
go
EOF-dump
if(\\\$status) goto bad
set hires = \\\` nawk '/Resolution Range/{getline; getline; print \\\$6}' \\\${tempfile} \\\`
set CELL = \\\` nawk '/Cell Dimensions/ {getline; getline; print}' \\\${tempfile} \\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile} \\\`
set SG = \\\` nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile} \\\`
set SG = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`

grep FreeR_flag \\\${tempfile} >& /dev/null
if(\\\$status) goto flags_removed
################################################################################
#
# if input file has pre-existing FreeR_flag, I assume you don't want it anymore
# otherwise, you should just use the COMPLETE option in a run of "freerflags"
# or use the same file as the freer source
#
remove_flags:
# purge old Free R flags from \\\$unfree file
mtzutils hklin \\\$unfree hklout \\\${tempfile}.unfree.mtz << eof-purge
EXCLUDE FreeR_flag
eof-purge
if(\\\$status) goto bad
set unfree = \\\${tempfile}.unfree.mtz
echo "FreeR_flag removed from \\\$1"
flags_removed:

# if flag file has already been given, use it instead
if(-e "\\\$flagfile") then
    mtzdump hklin \\\$flagfile << EOF >&! \\\${tempfile}.dump2
    HEAD
    go
EOF
    grep FreeR_flag \\\${tempfile}.dump2  >& /dev/null
    if(! \\\$status) then
	# suggested file is a good mtz, so just use it
	goto add_flags
    else
	grep INDE \\\$flagfile >& /dev/null
	if(! \\\$status) then
#	    echo not done yet...
	    # this is an X-plor file.  We need to import it
	    cat  \\\$flagfile |\\\\
	    nawk '{print toupper(\\\$0)}' |\\\\
	    nawk '{for(i=1;i! \\\${tempfile}.import
	    
	    # import the flags into an MTZ
	    f2mtz HKLIN \\\${tempfile}.import HKLOUT \\\${tempfile}.mtz << EOF-import
TITLE FREE-R flags Imported from \\\$flagfile
CELL \\\$CELL
SYMM \\\$SG
LABOUT H K L FreeR_flag
CTYPOUT H H H I
EOF-import
	    if(\\\$status) goto bad
	    if(! \\\$?debug) rm -f \\\${tempfile}.import
	    sortmtz HKLOUT \\\${tempfile}.sorted.mtz << EOF-sort
H K L
\\\${tempfile}.mtz
EOF-sort
	    if(\\\$status) goto bad
	    if(! \\\$?debug) rm -f \\\${tempfile}.mtz
	    # reduce to CCP4 asymmetric unit
	    reindex HKLIN \\\${tempfile}.sorted.mtz HKLOUT \\\${tempfile}.imported.mtz << EOF-reindex
EOF-reindex
	    if(\\\$status) goto bad
	    set flagfile = \\\${tempfile}.imported.mtz
	    goto add_flags
	else
	    # can't use this file
	    echo "ERROR: \\\$flagfile is no good!!! "
	endif
    endif
endif


make_flags:
################################################################################
# use unique to generate all possible HKLs
# if you are ever so fortunate to extend your data to 1.5A
# this FREE-R set will still be appropriate! 
#
# if you want your free-R to be a different %-age, change FREERFAC
#
unique HKLOUT \\\${tempfile}.unique.mtz << EOF-unique
TITLE  Unique data for \\\$SG
LABOUT  F=FP SIGF=SIGFP
# get RESOL, SYMM and CELL
RESO 1.5
SYMM \\\$SGnum
CELL \\\$CELL
EOF-unique
if(\\\$status) goto bad
#
freerflag HKLIN \\\${tempfile}.unique.mtz HKLOUT freeR_flag.mtz << EOF-FreeR
FREERFAC \\\$FRAC
END
EOF-FreeR
if(\\\$status) goto bad
set flagfile = freeR_flag.mtz

# the file freeRflags.mtz now contains the Free-R flags


add_flags:
################################################################################
#
#	Combine these FREE R flags with the merged data
mtzutils        \\\\
HKLIN1 \\\$unfree \\\\
HKLIN2 \\\$flagfile \\\\
HKLOUT \\\${tempfile}.freed.mtz \\\\
<< EOF-lastcad

RESOLUTION 1000 \\\$hires

INCLUDE 1 ALL
INCLUDE 2 FreeR_flag

END
EOF-lastcad
if(\\\$status) goto bad
if(\\\$status) exit 9

# polish flags here (that is, fill in holes)
freerflag HKLIN \\\${tempfile}.freed.mtz HKLOUT \\\$outfile << EOF-polish
COMPLETE FREE=FreeR_flag
END
EOF-polish
if(\\\$status) goto bad
echo ""
echo ""
echo "\\\$outfile is now identical to \\\$1 with Free-R flags added" \\\`if(-e \\\$flagfile) echo "from \\\$flagfile"\\\`

################################################################################
#
#	list them in X-PLOR format as well
#

# output new (polished) flags from output file
sortmtz HKLOUT \\\${tempfile}.sorted.mtz << EOF-sort
L K H
\\\$outfile
EOF-sort
if(\\\$status) goto bad
mtz2various hklin \\\${tempfile}.sorted.mtz hklout \\\${tempfile}.cv << EOF
OUTPUT XPLOR
MISS 0.0
LABIN FP=FreeR_flag SIGFP=FreeR_flag FREE=FreeR_flag
END
EOF
if(\\\$status) goto bad
nawk '/TEST= 1/{print substr(\\\$0, 6, 13)}' \\\${tempfile}.cv >! \\\${tempfile}_1.cv

# transform X-plor output into something X-plor will read without problems
set NREF = \\\`wc \\\${tempfile}.cv | nawk '{print \\\$1 +1}'\\\`

echo " NREFlections= \\\$NREF"                                         >! \\\$XPLORfile
echo " ANOMalous=FALSE"                                             >> \\\$XPLORfile
echo " DECLare NAME=TEST   DOMAin=RECIprocal   TYPE=INTE END"       >> \\\$XPLORfile
nawk '{print substr(\\\$0, 1, 18) substr(\\\$0, 47) }' \\\${tempfile}.cv     >> \\\$XPLORfile
if(\\\$status) goto bad



#########################################
# output flags from original flag file
sortmtz HKLOUT \\\${tempfile}.sorted.mtz << EOF-sort
L K H
\\\$flagfile
EOF-sort
if(\\\$status) goto bad
mtz2various hklin \\\${tempfile}.sorted.mtz hklout \\\${tempfile}.cv << EOF
OUTPUT XPLOR
MISS 0.0
LABIN FP=FreeR_flag SIGFP=FreeR_flag FREE=FreeR_flag
END
EOF
if(\\\$status) goto bad
nawk '/TEST= 1/{print substr(\\\$0, 6, 13)}' \\\${tempfile}.cv >! \\\${tempfile}_0.cv

# find differences between new and old free R flags
diff \\\${tempfile}_0.cv \\\${tempfile}_1.cv | grep '> ' >! \\\${tempfile}.diff


echo ""
echo ""
echo \\\`cat \\\${tempfile}.diff | wc -l\\\`" new Free HKLs assigned during polishing:"
if(\\\$temp == 0) then
    echo none
else
    cat \\\${tempfile}.diff
endif
echo "above "\\\`cat \\\${tempfile}.diff | wc -l\\\`" new Free HKLs assigned during polishing."
echo ""
echo ""


set temp = \\\`echo \\\$FRAC | nawk '{print 100*\\\$0}'\\\`
if(-e "\\\${tempfile}.unique.mtz") echo "\\\$flagfile was created with \\\${temp}% free-R flags."
if("\\\$flagfile" == "\\\${tempfile}.imported.mtz") set flagfile = \\\$2
echo "\\\$outfile is now identical to \\\$1 with Free-R flags added from the file \\\$flagfile"
echo "\\\$XPLORfile contains these Free-R flags in X-PLOR format"


if(\\\$?debug) exit
rm -f \\\${tempfile}* >& /dev/null


exit


bad:
echo "ACK! \\07"
exit 9

EOF-script
chmod a+x \$SCRIPT











set SCRIPT = \$SCRIPT_dir/mtz2various.com
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#	general script for converting mtz to another format
#
##############################################################################
# set up awk
alias nawk \$nawk
nawk 'BEGIN{print 1; exit}' >& /dev/null
if(\\\$status) alias nawk awk

# defaults
set mtzfile  = \${finalMTZ}
set tempfile = \\\${CCP4_SCR}/mtz2various_temp\\\$\\\$

# output F, phase, etc. (automatic by default)
set hiRES    = ""
set F        = Fin
set SIGF     = SIGFin
set DANO     = ""
set SIGD     = ""
set PHI      = PHIDM
set FOM      = FOMDM
set FREE     = FreeR_flag

# output files
set outfile   = outfile.cif
# supported: xplor cns tnt cif shelx fin phs
set format    = "CIF"

if("\\\$1" == "") goto Help
goto Setup
#  Procedure (at bottom) to read command-line args
#  mtz, Fs, or resolution
Help:
cat << EOF

usage: \\\$0 mtzfile.mtz [F] [PHI] outfile.fmt

where:
mtzfile.mtz  - an mtz file you want to convert
[F] [PHI]    - are the dataset names in mtzfile.mtz you want to extract
outfile.fmt  - is the output file name
fmt          - implies format:
		cif -> CIF
		hkl -> shelx
		tnt -> TNT
		fin -> XtalView
		phs -> XtalView
		fobs-> XPLOR
		cv  -> XPLOR
		cns -> CNS

EOF
exit 9
ReturnFromSetup:

# construct a LABIN card for the dump
set label = ""
if("\\\$F" != "")    set label = "\\\$label FP=\\\$F"
if("\\\$SIGF" != "") set label = "\\\$label SIGFP=\\\$SIGF"
if("\\\$DANO" != "") set label = "\\\$label DP=\\\$DANO"
if("\\\$SIGD" != "") set label = "\\\$label SIGDP=\\\$SIGD"
if("\\\$PHI" != "")  set label = "\\\$label PHIB=\\\$PHI"
if("\\\$FOM" != "")  set label = "\\\$label FOM=\\\$FOM"
if("\\\$FREE" != "") set label = "\\\$label FREE=\\\$FREE"

################################################################################
# extract columns of interest
mtz2various HKLIN \\\$mtzfile HKLOUT \\\${tempfile}.hkl << EOF-dump 
#>> /dev/null
RESOLUTION 1000 \\\$hiRES
OUTPUT \\\$format
LABIN \\\$label
END
EOF-dump
if(\\\$status) exit

if("\\\$format" == "TNT") then
    if("\\\$FREE" != "") then
	# extract FREE-R set
	cat \\\${tempfile}.hkl |\\\\
	nawk '\\\$NF=="FREE"{print substr(\\\$0,1,index(\\\$0,"FREE")-1)}' |\\\\
	sort -k2n,3 -k3n,4 -k4n,5 |\\\\
	cat >! \\\${outfile}.free
    endif
    # make sure the output is properly sorted
    cat \\\${tempfile}.hkl |\\\\
    nawk '\\\$NF!="FREE"{print}' |\\\\
    sort -k2n,3 -k3n,4 -k4n,5 |\\\\
    cat >! \\\${outfile}

    echo "TNT version of \\\$F \\\$SIGF \\\$PHI \\\$FOM in \\\$mtzfile is now in:"
    echo "\\\$outfile"
    echo "\\\${outfile}.free contains the Free-R flagged HKLs"
    rm -f \\\${tempfile}.hkl >& /dev/null
    exit
endif

# check for supported/unsupported output
if("\\\$format" != 'USER *') then
    # use whatever mtz2various did
    mv \\\${tempfile}.hkl \\\$outfile

    echo "\\\$format version of \\\$F \\\$SIGF \\\$DANO \\\$SIGD \\\$PHI \\\$FOM from \\\$mtzfile is at:"
    echo "\\\$outfile"
    exit
endif

# must have been an unsupported format (fin, phs)
if(("\\\$ext" == "fin")||("\\\$ext" == "phs")) then
    echo "name" >! \\\${outfile}.CRYSTAL
    echo "cell \\\$CELL" >> \\\${outfile}.CRYSTAL
    cat \\\${CLIBD}/symop.lib |\\\\
    nawk -v SG=\\\$SG '\\\$4==SG{print "spgr", tolower(\\\$4), \\\$1, \\\$2, \\\$3, tolower(\\\$6);\\\\
	getline; getline; printf "symm x,y,z"; \\\\
	while(NF==1){printf "; %s", tolower(\\\$1); getline};\\\\
	print "."; exit}' |\\\\
    cat >> \\\${outfile}.CRYSTAL
endif

if("\\\$ext" == "phs") then
    # XtalView phs file
    # should have been output as H K L F PHI FOM
    cat \\\${tempfile}.hkl |\\\\
    nawk '{printf "%4d %4d %4d %12.4f %7.4f %7.2f\\\\n", \\\$1, \\\$2, \\\$3, \\\$4, \\\$6, \\\$5}' |\\\\
    cat >! \\\$outfile

    echo "XtalView version of \\\$F \\\$PHI \\\$FOM from \\\$mtzfile is at:"
    echo "\\\$outfile"
    echo "\\\${outfile}.CRYSTAL"
    rm -f \\\${tempfile}.hkl >& /dev/null
    exit
endif


if("\\\$ext" == "fin") then
    # XtalView fin file
    # should have been output as H K L F SIGF D SIGD
    cat \\\${tempfile}.hkl |\\\\
    nawk 'NF>=7{F1=\\\$4+(\\\$6/2); F2=\\\$4-(\\\$6/2); SIG1=SIG2=\\\$5*1.4142;}\\\\
	  NF<7 || \\\$NF+0==0{F1=\\\$4; SIG1=\\\$5; F2=0; SIG2=9999}\\\\
	  NF>3{printf "%4d %4d %4d %12.4f %12.4f %12.4f %12.4f\\\\n", \\\$1, \\\$2, \\\$3, F1, SIG1, F2, SIG2}' |\\\\
    cat >! \\\$outfile

    echo "XtalView version of \\\$F \\\$SIGF \\\$DANO \\\$SIGD from \\\$mtzfile is at:"
    echo "\\\$outfile"
    echo "\\\${outfile}.CRYSTAL"
    rm -f \\\${tempfile}.hkl >& /dev/null
    exit
endif


####################################################################
exit
####################################################################



Setup:
# scan the command line for files
foreach arg ( \\\$* )
    if( "\\\$arg" =~ *.mtz ) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set mtzfile  = "\\\$arg"
	continue
    endif
    if("\\\$arg" =~ *.cif) then
        set outfile  = "\\\$arg"
        set format   = "CIF data_\\\$arg"
        continue
    endif
    if("\\\$arg" =~ *.hkl) then
	set outfile  = "\\\$arg"
	set format   = "SHELX"
	continue
    endif
    if("\\\$arg" =~ *.tnt) then
        set outfile  = "\\\$arg"
        set format   = "TNT"
        continue
    endif
    if("\\\$arg" =~ *.cns) then
        set outfile  = "\\\$arg"
        set format   = "CNS"
        continue
    endif
    if(("\\\$arg" =~ *.fobs)||("\\\$arg" =~ *.cv)) then
	set outfile  = "\\\$arg"
	set format   = "XPLOR"
	continue
    endif
    if("\\\$arg" =~ *.fin) then
        set outfile  = "\\\$arg"
        set format   = 'FIN'
        continue
    endif
    if("\\\$arg" =~ *.phs) then
        set outfile  = "\\\$arg"
        set format   = 'PHS'
        continue
    endif
    if( "\\\$arg" =~ [0-9]* ) then
	set temp = \\\`echo "\\\$arg" | nawk '\\\$1+0>0.1{print \\\$1+0}'\\\`
	if("\\\$temp" != "") set hiRES = "\\\$temp"
    endif
end

#get variables from mtz file
echo "go" | mtzdump hklin \\\$mtzfile | tee \\\${tempfile}mtzhead |\\\\
nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\\\
nawk 'NF>10 && \\\$(NF-1) ~ /[FQPWADI]/' |\\\\
cat >! \\\${tempfile}mtzdmp

# set misc header values
set CELL = \\\`nawk '/Cell Dimensions/{getline; getline; print}' \\\${tempfile}mtzhead\\\`
set SG   = \\\`nawk '/Space group/{print \\\$5}' \\\${tempfile}mtzhead\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzhead \\\`
set SG = \\\` nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile}mtzhead \\\`
set SG = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set mtzRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\${tempfile}mtzhead\\\`
rm -f \\\${tempfile}mtzhead >& /dev/null

# use completeness, or F/sigF to pick default F
cat \\\${tempfile}mtzdmp |\\\\
nawk '\\\$(NF-1) == "F"{F=\\\$NF; meanF=\\\$8; reso=\\\$(NF-2); comp=substr(\\\$0,32)+0; \\\\
      getline; S=\\\$NF; if(\\\$8) meanF /= \\\$8; print F, S, reso, comp, meanF;}' |\\\\
sort -k3n,4 -k4nr,5 -k5nr >! \\\${tempfile}F

# same for D/sigD for anomalous diffs
cat \\\${tempfile}mtzdmp |\\\\
nawk '\\\$(NF-1) == "D"{D=\\\$NF; meanD=\\\$8; reso=\\\$(NF-2); comp=substr(\\\$0,32)+0; \\\\
      getline; S=\\\$NF; if(\\\$8) meanD /= \\\$8; print D, S, reso, comp, meanD;}' |\\\\
sort -k3n,4 -k4nr,5 -k5nr >! \\\${tempfile}D


# and extract all dataset types/labels
cat \\\${tempfile}mtzdmp |\\\\
nawk 'NF>2{print \\\$(NF-1), \\\$NF, " "}' |\\\\
cat >! \\\${tempfile}cards

#clean up
rm -f \\\${tempfile}mtzdmp

# pick F with best resolution, or /
set F    = \\\`head -1 \\\${tempfile}F\\\`
if(\\\$#F > 2) then
    set SIGF = \\\$F[2]
    set F    = \\\$F[1]
endif

# see if default phase is available in this file
grep "P \\\$PHI" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # pick most recently-added phase
    set temp = \\\`nawk '/^P/{print \\\$2}' \\\${tempfile}cards  | tail -1\\\`
    if("\\\$temp" != "") set PHI = "\\\$temp"
endif
# see if default FOM is available in this file
grep "W \\\$FOM" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # pick most recently-added FOM
    set temp = \\\`nawk '/^W/{print \\\$2}' \\\${tempfile}cards | tail -1\\\`
    if("\\\$temp" != "") then
	set FOM = "\\\$temp"
    else
	# there are no FOMs in this mtz file
	set FOM = ""
    endif
endif

# see if user specified an F, Phase, or FOM
set last = "F"
foreach arg ( \\\$* )
    set temp = \\\`grep " \\\$arg " \\\${tempfile}cards\\\`
    if("\\\$temp" =~ F*) then
	set F = "\\\${arg}"
	set last = "F"
	# assign most likely sigma too
	set temp = \\\`nawk -v arg="\\\$arg" '\\\$1==arg{print \\\$2}' \\\${tempfile}F\\\`
	if(\\\$#temp == 1) set SIGF = "\\\$temp"
	continue
    endif
    if("\\\$temp" =~ D*) then
        set DANO = "\\\${arg}"
	set last = "D"
        # assign most likely sigma too
        set temp = \\\`nawk -v arg="\\\$arg" '\\\$1==arg{print \\\$2}' \\\${tempfile}D\\\`
        if(\\\$#temp == 1) set SIGD = "\\\$temp"
        continue
    endif
    if("\\\$temp" =~ Q*) then
	if("\\\$last" == "F") set SIGF = "\\\${arg}"
	if("\\\$last" == "D") set SIGD = "\\\${arg}"
    endif
    if("\\\$temp" =~ P*) set PHI  = "\\\${arg}"
    if("\\\$temp" =~ W*) set FOM  = "\\\${arg}"


    # detect particular out-of-context format specifiers
    set arg = \\\`echo "\\\$arg" | nawk '{print tolower(\\\$1)}'\\\`
    if("\\\$arg" == "shelx") set format = SHELX
    if("\\\$arg" == "tnt")   set format = TNT
    if("\\\$arg" == "cif")   set format = CIF
    if("\\\$arg" == "xplor") set format = XPLOR
    if("\\\$arg" == "cns")   set format = CNS
    if("\\\$arg" == "xtalview") then
        if("\\\$PHI" == "") then
            set format = "FIN"
        else
            set format = "PHS"
        endif
    endif
end

# check for DANO, if we might need one
if(("\\\$format" == "FIN")&&("\\\$DANO" == "")) then
    # grab pattern from name
    set temp = \\\`echo \\\$F | nawk '{print substr(\\\$1,2)}'\\\`
    set DANO = \\\`nawk -v patt=\\\$temp '\\\$1~ patt"\\\$" {print \\\$1; exit}' \\\${tempfile}D\\\`
    # get likely sigma too
    set SIGD = \\\`nawk -v arg="\\\$DANO" '\\\$1==arg{print \\\$2}' \\\${tempfile}D\\\`
endif

# now check and see if the sigma is really there
grep "Q \\\$SIGF" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no sigma availale
    set SIGF = ""
endif
grep "Q \\\$SIGD" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no sigma availale 
    set SIGD = ""
endif
grep "P \\\$PHI" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no phase availale
    set PHI = ""
endif
grep "W \\\$FOM" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no weight availale
    set FOM = ""
endif
grep " \\\$FREE" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no weight availale
    set FREE = ""
endif


rm -f \\\${tempfile}cards \\\${tempfile}F \\\${tempfile}D >& /dev/null

# set resolution (if none previously given)
if("\\\$hiRES" == "") set hiRES = "\\\$mtzRES"

# store filename extension/format
set ext = \\\`echo \\\$outfile | nawk 'BEGIN{FS="."} {print \\\$NF}'\\\`
if("\\\$format" == "CIF") then
    # needs an extra word
    set format = "CIF data_dump"
endif
if("\\\$format" == "FIN") then
    # not supported by mtz2various
    set format = 'USER *'
    set ext = fin
    set PHI = ""
    set FOM = ""
    set FREE = ""
endif
if("\\\$format" == "PHS") then
    # not supported by mtz2various
    set format = 'USER *'
    set ext = phs
    set SIGF = ""
    set DANO = ""
    set SIGD = ""
    set FREE = ""
endif

goto ReturnFromSetup

####################
# future:
better handling of shelx
multiple datasets/mtzs?

EOF-script
chmod a+x \$SCRIPT
















###############################################################################
#
#	best FH calculator
#
###############################################################################
set SCRIPT = \$SCRIPT_dir/bestFH.com
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#
#	bestFH.com 				-James Holton 8-2-04
#
#	calculate a "best" estimate of F for the heavy atoms
#	alone (a la B. W. Matthews 1966 Acta Cryst 20, 230-239)
#	by combining ALL anomalous and isomorphous differences.  
#	(as many as you want)
#
#	FH should give cleaner Pattersons, difference Fouriers,
#	and direct methods.
#
#	Do NOT combine differences from data sets expected to have
#	different heavy atom locations.  That would be silly.
#
#
# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set mtzfile   = "\${finalMTZ}"		# MAD data set
set outfile   = "./FH.mtz"		# contains FH, SIGFH
set shelxfile = "./fh.hkl"		# same thing, shelx format
set fourfile  = "./FH_Four.map"		# Phased Fourier of FH (if phase is available)
set pattfile  = "./FH_Patt.map"		# Combined Patterson map
set wpattfile = "./wFH_Patt.map"	# Combined, weighted Patterson map
set logfile   = "./bestFH.log"		# all the CCP4 logs

set tempfile = \\\${CCP4_SCR}/bestFH_temp\\\$\\\$


# initialize internal variables
set loRES = 1000
set hiRES = ""
set order = ""		# "order" of increasing dispersive signal data sets

set DATA_cutoff = 1	# sigma cutoff      (not used)
set MAX_dano 		# upper Dano cutoff (not used)
set MAX_diso		# upper Diso cutoff (not used)
set scaling = scale	# apply one scale to each difference data set
#set scaling = isotropic # use a B-factor too (wise? )

if(\\\$#argv == 0) goto Help

# this procedure (re)sets most of the above variables
# from either the provided files, or the command line
goto Setup

Help:
cat << EOF

usage: \\\$0 alldata.mtz

where:
alldata.mtz	- contains all the Fs and DANOs you want to combine

\\\`basename \\\$0\\\` will calculate an (unscaled) estimate of FH, the scattering factor
of the heavy metal alone, by combining any and all anomalous and isomorphous
(dispersive) differences made available to it.  The procedure is derived
from Matthews et. al. 1966 Acta Cryst 20, 230.

FH is better than Dano or Diso alone, both because the averaging tends
to give better signal/noise, and because considering BOTH isomorphous
and anomalous simultaneously reduced the systematic errors arising
from cross-terms in difference intensity data.  FH usually gives 
cleaner Pattersons and difference Fouriers, as well as improved 
performace of direct methods programs.

Procedure:
The isomorphous difference data sets are computed from the provided Fs,
(assigned a sign), scaled together, and a sigma-weighed mean isomorphous 
difference is computed.  A similar procedure is applied to the anomalous 
differences.

The average Diso and Dano data sets are then scaled to each other, and
combined for the final estimate of FH = sqrt(Diso^2 + k * Dano^2).

REMEMBER: Do NOT combine differences from data sets expected to have
different heavy atom locations.  That would be silly.  If you don't
know why, you should read Matthews et. al. 1966 Acta Cryst 20, 230.

EOF

rm -f \\\${tempfile}Fs >& /dev/null
rm -f \\\${tempfile}Ds >& /dev/null
rm -f \\\${tempfile}Ps >& /dev/null
rm -f \\\${tempfile}Fpairs >& /dev/null
exit 2
#
#   This procedure (at the bottom of the script) does the following
#   1) scan the command line for the mtz file
#   2) set the CELL, SG, and other variables
#   3) generate dataset name lists: \\\${tempfile}Fs and \\\${tempfile}Ds
Return_from_Setup:






################################################################
#   initial report on intended program flow
################################################################
# start the logfile
echo "" >! \\\$logfile
echo "\\\$0 \\\$*" >> \\\$logfile

if(-e "\\\$mtzfile") then
    echo "calculating FH from data in \\\$mtzfile" | tee -a \\\$logfile
endif

echo "" | tee -a \\\$logfile
echo "resolution \\\$loRES \\\$hiRES" | tee -a \\\$logfile
# get a "better" resolution limit for scaling?
set scaleRES = "\\\$loRES \\\$hiRES"

# count how many datasets we have
set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`
set Ds = \\\`cat \\\${tempfile}Ds | wc -l\\\`

# trivial assignments of dispersive difference order
# (2 datasets -> doesn't matter)
# (1 dataset  -> unusable)
if(\\\$Fs < 3) set order = \\\`nawk '{print \\\$1}' \\\${tempfile}Fs\\\`
if(\\\$Fs < 2) set order = ""

# if user doesn't care, pick Diso ordering automatically
if(("\\\$order" == "")&&(\\\$Fs > 2)) then
    
    echo -n "Evaluating difference data "
    echo -n "" >! \\\${tempfile}diso_dano
    
    # make a list of essential pairs
    cat \\\${tempfile}Fs |\\\\
    nawk '{++n; F[n]=\\\$1} \\\\
          END{for(i=1;i<=n;++i){for(j=i;j<=n;++j){if(i!=j){\\\\
              print F[i] " - " F[j];}}}}' |\\\\
    cat >! \\\${tempfile}Fpairs
    
    foreach pair ( \\\`nawk '{print NR}' \\\${tempfile}Fpairs\\\` )
	# retrieve the pair  
	set F1 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$1}' \\\${tempfile}Fpairs\\\`
	set F2 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$3}' \\\${tempfile}Fpairs\\\`
	
	# and get the sigmas too
	set SIGF1 = \\\`nawk -v F=\\\$F1 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
	set SIGF2 = \\\`nawk -v F=\\\$F2 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
	
	# also, get magnitudes of anomalous diffs
	if(\\\$Ds != 0) then
	    @ i = ( ( \\\$pair  % \\\$Ds ) + 1 )
	    set DANO    = \\\`nawk -v n=\\\$i 'NR==n{print \\\$1}' \\\${tempfile}Ds\\\`
	    set SIGDANO = \\\`nawk -v n=\\\$i 'NR==n{print \\\$2}' \\\${tempfile}Ds\\\`

	    set DANOcards = "DPH1=\\\$DANO SIGDPH1=\\\$SIGDANO"
	else
	    set DANOcards = ""
	endif
    
	# make some ordinary scaleit cards
	cat << EOF-scaleitin >! \\\${tempfile}scaleit.in
RESOLUTION \\\$scaleRES
refine \\\$scaling
weight
LABIN FP=\\\$F1 SIGFP=\\\$SIGF1 -
      FPH1=\\\$F2 SIGFPH1=\\\$SIGF2 \\\$DANOcards
END
EOF-scaleitin
	
	# entertainment
	echo -n "."
	
	# put the labels in the log file
	echo -n "\\\$F1 \\\$F2 \\\$DANO " >> \\\${tempfile}diso_dano
	
	# run scaleit to get Diso and Dano
	cat \\\${tempfile}scaleit.in |\\\\
	scaleit HKLIN \\\$mtzfile HKLOUT /dev/null |\\\\
	nawk '/Sc_kraut SCALE/{iso=index(\\\$0,"diso")-4; ano=index(\\\$0,"")+3}\\\\
	/THE TOTALS/{print substr(\\\$0,iso)+0, substr(\\\$0,ano)+0}' |\\\\
	cat >> \\\${tempfile}diso_dano
	
	# \\\${tempfile}diso_dano has format: F1 F2 DANOF3   
    end
    rm -f \\\${tempfile}Fpairs >& /dev/null
    rm -f \\\${tempfile}scaleit.in >& /dev/null

    # get the single largest isomorphous difference
    set order = \\\`sort -n -k4 \\\${tempfile}diso_dano | tail -1 | nawk '{print \\\$2}'\\\`
    if("\\\$order" == "") then
	echo ""
	echo "no isomorphous differences"
	echo "estimating FH requires isomorphous/dispersive and anomalous differences! "
	echo "Therefore: \\\$mtzfile needs to contain at least two columns of Fs"
	echo "sorry"
	goto Clean_up
    endif

    # now order the remaining datasets with increasing distance from this "native"
    cat \\\${tempfile}diso_dano |\\\\
    nawk -v ref=\\\$order 'BEGIN{print ref, 0, "order"} \\\\
       \\\$1==ref{print \\\$2, \\\$4} \\\$2==ref{print \\\$1, \\\$4}' |\\\\
    sort -n -k2 >! \\\${tempfile}order
    # \\\${tempfile}order has format: F diso(from Fref)
    
    # store the new order in a variable
    set order = \\\`nawk '{print \\\$1}' \\\${tempfile}order\\\`

    # make sure nothing bad happened (this isn't exactly ergodic! )
    set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`
    if(\\\$#order != \\\$Fs) then
	# something has gone horribly wrong
	echo "ERROR: unable to determine the best order of"
	echo "       isomorphous/dispersive differences"
	echo "sorry! "
	echo ""
	goto Help
    endif
    
    # reorder the Dano list too (doesn't really matter)
    cat \\\${tempfile}diso_dano \\\${tempfile}Ds |\\\\
    nawk 'NF>2{dano[\\\$3]=\\\$5} \\\\
          NF==2{print \\\$0, dano[\\\$1]}' |\\\\
    sort -nru -k3 |\\\\
    nawk '{print \\\$1, \\\$2}' >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}Ds >& /dev/null

    # clean up
    rm -f \\\${tempfile}scaleit.in >& /dev/null
    rm -f \\\${tempfile}diso_dano >& /dev/null
endif

# whatever its source, put the f' order in a file
echo "\\\$order" |\\\\
nawk 'BEGIN{RS=" "} NF==1{++i; print \\\$1, "order"}' |\\\\
cat >! \\\${tempfile}order

# re-order the Fs list
cat \\\${tempfile}Fs \\\${tempfile}order |\\\\
nawk '\\\$NF!="order"{sig[\\\$1]=\\\$2} \\\\
      \\\$NF=="order"{print \\\$1, sig[\\\$1]}' |\\\\
cat >! \\\${tempfile}
mv \\\${tempfile} \\\${tempfile}Fs >& /dev/null
set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`



# print out final ordering results:
echo ""
echo -n " f' order: "
cat \\\${tempfile}Fs | nawk '{printf "%s ", \\\$1} END{print ""}'

echo -n " f"\\\\"" order: "
cat \\\${tempfile}Ds | nawk '{printf "%s ", \\\$1} END{print ""}'

# clean up
rm -f \\\${tempfile}order >& /dev/null


# jump ahead if there are no anomalous datasets (why bother?)
if("\\\$Ds" == 0) then
    # make sure this doesn't exist (this is a signal later on)
    rm -f \\\${tempfile}dano.mtz >& /dev/null
    goto calculate_iso
endif

# no need to weigh anomalous datasets if there is only one of them
if("\\\$Ds" == 1) then
    # all we need to do is rename the dataset
    set temp = \\\`cat \\\${tempfile}Ds\\\`
    # better than crashing, (I guess)
    if(\\\$#temp != 2) set temp = ( \\\$temp \\\$temp )

    echo "extracting \\\$temp[1] as Dano"
    cad hklin1 \\\$mtzfile hklout \\\${tempfile}dano.mtz << EOF-cad >> \\\$logfile
    LABIN FILE 1 E1=\\\$temp[1] E2=\\\$temp[2]
    CTYPO FILE 1 E1=F        E2=Q
    LABOU FILE 1 E1=Dano     E2=SIGDano
EOF-cad

    # go on to calculate isomorphous differences
    goto calculate_iso
endif

weigh_ano:
echo ""
echo "weighting anomalous differences"

# extract the anomalous differences, and treat them as Fs
cat \\\${tempfile}Ds |\\\\
nawk '{printf "%s %s ", \\\$1, \\\$2} END{print ""}' |\\\\
nawk 'BEGIN{printf "LABIN FILE 1 ";} \\\\
{for(i=1;i<=NF;++i){printf "E%d=%s ", i, \\\$i}; printf "\\\\nCTYPIN FILE 1 "; \\\\
 for(i=1;i<=NF;i+=2){printf "E%d=F E%d=Q ", i, i+1}; print ""}' |\\\\
cad HKLIN1 \\\$mtzfile HKLOUT \\\${tempfile}danos.mtz >> \\\$logfile

# put anomalous diffs on the same scale
set i = 1
echo -n "" >! \\\${tempfile}scaleit.log
while( \\\$i <= \\\$Ds )
    cat << EOF-scaleitin >! \\\${tempfile}scaleit.in
RESOLUTION \\\$scaleRES
#refine scale
refine \\\$scaling
weight
EOF-scaleitin

    # make the LABIN card (not too many FPHs! )
    head -1 \\\${tempfile}Ds |\\\\
    nawk '{printf "LABIN FP=%s SIGFP=%s ", \\\$1, \\\$2}' |\\\\
    cat >> \\\${tempfile}scaleit.in
    
    # no more than 6 at a time
    cat \\\${tempfile}Ds |\\\\
    nawk -v first=\\\$i '{++n} n>=first && n<(first+6){++i;\\\\
	printf "-\\\\nFPH%d=%s SIGFPH%d=%s ", i, \\\$1, i, \\\$2} \\\\
    END {print "\\\\nEND"}' |\\\\
    cat >> \\\${tempfile}scaleit.in
    
    # now actually run scaleit
    cat \\\${tempfile}scaleit.in |\\\\
    scaleit HKLIN \\\${tempfile}danos.mtz \\\\
            HKLOUT \\\${tempfile}danoscaled.mtz |\\\\
     tee -a \\\${tempfile}scaleit.log >> \\\$logfile
    
    # accumulate scaled datasets
    mv \\\${tempfile}danoscaled.mtz \\\${tempfile}danos.mtz >& /dev/null
    @ i = ( \\\$i + 6 )
end
mv \\\${tempfile}danos.mtz \\\${tempfile}danoscaled.mtz >& /dev/null

# print out "weights" (effective weighting is 1/scale^2)
cat \\\${tempfile}scaleit.log |\\\\
nawk '/APPLICATION OF SCALES/,/--------------------------/' |\\\\
nawk '\\\$1 == "Derivative"{++i; print \\\$1, i, \\\$3}' >! \\\${tempfile}scales

cat \\\${tempfile}Ds \\\${tempfile}scales |\\\\
nawk 'NF==2{++n; label[n]=\\\$1; if(length(\\\$1)>maxlen) maxlen=length(\\\$1)}\\\\
    \\\$1 == "Derivative"{w=0; if(\\\$3+0!=0) w=1/(\\\$3*\\\$3)\\\\
    printf "%-" maxlen "s : %.3f\\\\n", label[\\\$2], w}' |\\\\
sort -nr -k3


rm -f \\\${tempfile}scaleit.log >& /dev/null
rm -f \\\${tempfile}scales      >& /dev/null


combine_ano:
echo "combining anomalous differences into Dano"

# now do a sigma-weighted average of all anomalous diffs
set Ds = \\\`cat \\\${tempfile}Ds | wc -l\\\`
echo \\\$Ds | nawk '{print "NREF -1"; print "FORMAT \\\\047(3i5,"\\\$1*2"f15.7)\\\\047"}' |\\\\
mtzdump HKLIN \\\${tempfile}danoscaled.mtz |\\\\
nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
nawk '! /[A-Z]/ && NF>3{HKL=substr(\\\$0,1,15); sum=norm=n="";\\\\
    # run down list of D, sigD \\\\
    for(i=4;i0){w=1/(sigD*sigD); sum+=w*D; norm+=w;}}\\\\
    # do not print anything for "all-missing" HKLs \\\\
    # print zero for all-zero hkls \\\\
    if(norm==0) print HKL, 0, 0; \\\\
    # print sigma-weighted average (abs value? ) \\\\
    if(norm+0 > 0) print HKL, sum/norm, 1/sqrt(norm)}' |\\\\
cat >! \\\${tempfile}dano.hkl
rm -f \\\${tempfile}danoscaled.mtz >& /dev/null


f2mtz HKLIN \\\${tempfile}dano.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
CELL \\\$CELL
SYMM \\\$SGnum
LABOUT H K L Dano SIGDano
CTYPO  H H H F Q
EOF-f2mtz
rm -f \\\${tempfile}dano.hkl >& /dev/null

echo "H K L" |\\\\
sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\${tempfile}dano.mtz >> \\\$logfile
rm -f \\\${tempfile}sortme.mtz

# indicate finish
echo ""

# summed anomalous diffs should now be loaded into:
# \\\${tempfile}dano.mtz, labeled as Dano SIGDano



calculate_iso:
###########################################################
# now we need to calculate isomorphous diffs 
# before we can treat them as we did the anomalous diffs


# jump ahead if there are no isomorphous datasets (why bother?)
if("\\\$Fs" < 2) then
    # make sure this doesn't exist (this is a signal later on)
    rm -f \\\${tempfile}diso.mtz >& /dev/null
    goto compute_k
endif

if(\\\$Fs == 2) then
    echo "calculating isomorphous (dispersive) difference as Diso"
else
    echo "subtracting isomorphous (dispersive) differences"
    echo "note: f' differences should all have the same sign! "
endif

# make sure this doesn't already exist
rm -f \\\${tempfile}disos.mtz >& /dev/null

# make list with largest difference first
cat \\\${tempfile}Fs |\\\\
nawk '{++n; F[n]=\\\$1} \\\\
    END{for(i=1;i<=n;++i){for(j=n;j>i;--j){if(i!=j){\\\\
    print F[i] " - " F[j];}}}}' |\\\\
cat >! \\\${tempfile}Fpairs
set Fpairs = \\\`cat \\\${tempfile}Fpairs | wc -l\\\`
set pair = 0

while ( \\\$pair < \\\$Fpairs )
    @ pair = ( \\\$pair + 1 )
    # retrieve the pair  
    set F1 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$1}' \\\${tempfile}Fpairs\\\`
    set F2 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$3}' \\\${tempfile}Fpairs\\\`
    
    # and get the sigmas too
    set SIGF1 = \\\`nawk -v F=\\\$F1 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
    set SIGF2 = \\\`nawk -v F=\\\$F2 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
    
    echo "\\\${F1}-\\\${F2}"
    
    # extract these columns from the file
    echo "LABIN FILE 1 E1=\\\$F1 E2=\\\$SIGF1 E3=\\\$F2 E4=\\\$SIGF2" |\\\\
    cad HKLIN1 \\\$mtzfile HKLOUT \\\${tempfile}dump.mtz >> \\\$logfile
    
    # dump the Fs as text, calculate F1-F2 sqrt(SIG1^2+SIG2^2)
    echo "NREF -1" |\\\\
    mtzdump HKLIN \\\${tempfile}dump.mtz |\\\\
    nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
    nawk '! /[A-Z?]/ && NF>1{HKL=substr(\\\$0,1,13);\\\\
        F1=substr(\\\$0,14,12); F2=substr(\\\$0,36,10);\\\\
	SIGF1=substr(\\\$0,26,10); SIGF2=substr(\\\$0,46,10); \\\\
     print HKL, F1-F2, sqrt(SIGF1*SIGF1 + SIGF2*SIGF2)}' |\\\\
    cat >! \\\${tempfile}diso.hkl
    rm -f \\\${tempfile}dump.mtz >& /dev/null
    
    # special case: only one difference set
    if(\\\$Fs == 2) set pair = ""

    # read back into mtz format
    f2mtz HKLIN \\\${tempfile}diso.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
    CELL \\\$CELL
    SYMM \\\$SGnum
    LABOUT H K L Diso\\\${pair} SIGDiso\\\${pair}
    CTYPO  H H H F Q
EOF-f2mtz
    rm -f \\\${tempfile}diso.hkl >& /dev/null
    
    if("\\\$pair" == "") set pair = 999    
    
    # sort it (just in case)
    echo "H K L" |\\\\
    sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\${tempfile}diso.mtz >> \\\$logfile
    rm -f \\\${tempfile}sortme.mtz
    
    # add columns into an mtz
    if(-e \\\${tempfile}disos.mtz) then
	cad HKLIN1 \\\${tempfile}disos.mtz HKLIN2 \\\${tempfile}diso.mtz \\\\
	    HKLOUT \\\${tempfile}cadded.mtz << EOF-cadadd >> \\\$logfile
	LABIN FILE 1 ALL
	LABIN FILE 2 ALL
EOF-cadadd
	# update the cumulative mtz
	mv \\\${tempfile}cadded.mtz \\\${tempfile}disos.mtz
    else
	# create the cumulative mtz
	mv \\\${tempfile}diso.mtz \\\${tempfile}disos.mtz
    endif
end


# check for trivial case: one difference dataset
if(\\\$Fs <= 2) then
    # no need to calculate relative weights for one dataset
    mv \\\${tempfile}disos.mtz \\\${tempfile}diso.mtz
    
    goto compute_k
endif


weigh_iso:
echo "weighting isomorphous differences"

# now put all these differences on the same scale
set pair = 1
set Fpairs = \\\`cat \\\${tempfile}Fpairs | wc -l\\\`
echo -n "" >! \\\${tempfile}scaleit.log 
while ( \\\$pair <= \\\$Fpairs )
    cat << EOF-scaleitin >! \\\${tempfile}scaleit.in
RESOLUTION \\\$scaleRES
#refine scale
refine \\\$scaling
weight
EOF-scaleitin
    # first one is the reference
    echo -n "LABIN FP=Diso1 SIGFP=SIGDiso1 " >> \\\${tempfile}scaleit.in
    
    # scale 6 at a time
    cat \\\${tempfile}Fpairs |\\\\
    nawk -v first=\\\$pair '{++n} n>=first && n<(first+6){++i;\\\\
	printf "-\\\\nFPH%d=Diso%d SIGFPH%d=SIGDiso%d ", i, n, i, n;}\\\\
	END{print "\\\\nEND"}' |\\\\
    cat >> \\\${tempfile}scaleit.in
    
    # run scaleit
    cat \\\${tempfile}scaleit.in |\\\\
    scaleit HKLIN \\\${tempfile}disos.mtz \\\\
            HKLOUT \\\${tempfile}disoscaled.mtz  |\\\\
     tee -a \\\${tempfile}scaleit.log >> \\\$logfile
    rm -f \\\${tempfile}scaleit.in >& /dev/null

    @ pair = ( \\\$pair + 6 )
    
    # output is input for next round of scaling
    mv \\\${tempfile}disoscaled.mtz \\\${tempfile}disos.mtz >& /dev/null
end
mv \\\${tempfile}disos.mtz \\\${tempfile}disoscaled.mtz >& /dev/null


# print out "weights" (effective weighting is 1/scale^2)
cat \\\${tempfile}scaleit.log |\\\\
nawk '/APPLICATION OF SCALES/,/--------------------------/' |\\\\
nawk '\\\$1 == "Derivative"{++n; print \\\$1, n, \\\$3}' >! \\\${tempfile}scales

cat \\\${tempfile}Fpairs \\\${tempfile}scales |\\\\
nawk '\\\$2 == "-"{++n; label[n]=\\\$1 \\\$2 \\\$3; if(length(label[n])>maxlen) maxlen=length(label[n])}\\\\
    \\\$1 == "Derivative"{w=0; if(\\\$3+0!=0) w=1/(\\\$3*\\\$3)\\\\
    printf "%-" maxlen "s : %.3f\\\\n", label[\\\$2], w}' |\\\\
sort -nr -k3

rm -f \\\${tempfile}scaleit.log >& /dev/null
rm -f \\\${tempfile}scales      >& /dev/null



combine_iso:
echo "combining isomorphous differences into Diso"

# add these scaled data sets together (sigma-weighted again)
# (hopefully, our "ordering" procedure has made sure all
#  these differences have the same sign)
set Fpairs = \\\`cat \\\${tempfile}Fpairs | wc -l\\\`
rm -f \\\${tempfile}Fpairs >& /dev/null

echo \\\$Fpairs | nawk '{print "NREF -1"; print "FORMAT \\\\047(3i5,"\\\$1*2"f15.7)\\\\047"}' |\\\\
mtzdump HKLIN \\\${tempfile}disoscaled.mtz |\\\\
nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
nawk '! /[A-Z]/ && NF>3{HKL=substr(\\\$0,1,15); sum=norm=n="";\\\\
    # run down list of D, sigD \\\\
    for(i=4;i0){w=1/(sigD*sigD); sum+=w*D; norm+=w;}}\\\\
    # do not print anything for "all-missing" HKLs \\\\
    # print zero for all-zero hkls \\\\
    if(norm==0) print HKL, 0, 0; \\\\
    # print sigma-weighted average (abs value?) \\\\
    if(norm+0 > 0) print HKL, sum/norm, 1/sqrt(norm)}' |\\\\
cat >! \\\${tempfile}diso.hkl
rm -f \\\${tempfile}disoscaled.mtz >& /dev/null

# read the averaged isomorphous differences back into an mtz
f2mtz HKLIN \\\${tempfile}diso.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
CELL \\\$CELL
SYMM \\\$SGnum
LABOUT H K L Diso SIGDiso
CTYPO  H H H F Q
EOF-f2mtz
rm -f \\\${tempfile}diso.hkl >& /dev/null

echo "H K L" |\\\\
sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\${tempfile}diso.mtz >> \\\$logfile
rm -f \\\${tempfile}sortme.mtz

# indicate finish



compute_k:
##############################################################
# now we need the "k" that will put Diso and Dano on the same
# scale: k/2 = <|Diso|>/<|Dano|>

##############################################################
echo ""

# handle special cases
if((\\\$Ds == 0)&&(\\\$Fs <= 1)) then
    # this should never happen, but...
    echo "ERROR: no difference data in \\\${mtzfile}! "
    goto Help
endif
if(\\\$Ds == 0) then
    # anomalous difference data is totally missing
    # just rename the isomorphous differences
    echo "WARNING: treating Diso data as FH (FH is better with Dano and Diso)"
    cad hklin1 \\\${tempfile}diso.mtz hklout \\\${tempfile}sortme.mtz << EOF >> \\\$logfile
    labin file 1 E1=Diso E2=SIGDiso
    labou file 1 E1=FH   E2=SIGFH
EOF
    rm -f \\\${tempfile}diso.mtz >& /dev/null
    rm -f \\\${tempfile}dano.mtz >& /dev/null
    set wpattfile = ""

    goto sort_final
endif
if(\\\$Fs <= 1) then
    # isomorphous difference data is totally missing
    # just re-name the anomalous differences
    echo "WARNING: treating Dano data as FH (FH is better with Dano and Diso)"
    cad hklin1 \\\${tempfile}dano.mtz hklout \\\${tempfile}sortme.mtz << EOF >> \\\$logfile
    labin file 1 E1=Dano E2=SIGDano
    labou file 1 E1=FH   E2=SIGFH
EOF
    rm -f \\\${tempfile}diso.mtz >& /dev/null
    rm -f \\\${tempfile}dano.mtz >& /dev/null
    set wpattfile = ""

    goto sort_final
endif

##############################################################
echo -n "scaling Diso to Dano  "

# use scaleit to put Diso and Dano on the same scale
cad HKLIN1 \\\${tempfile}diso.mtz HKLIN2 \\\${tempfile}dano.mtz \\\\
HKLOUT \\\${tempfile}diso_dano.mtz << EOF-cad >> \\\$logfile
LABIN FILE 1 ALL
LABIN FILE 2 ALL
EOF-cad
rm -f \\\${tempfile}diso.mtz >& /dev/null
rm -f \\\${tempfile}dano.mtz >& /dev/null


scaleit HKLIN \\\${tempfile}diso_dano.mtz \\\\
 HKLOUT \\\${tempfile}scaled.mtz << EOF-scaleit | tee \\\${tempfile}scaleit.log >> \\\$logfile
RESOLUTION \\\$scaleRES
#refine scale
refine \\\$scaling
weight
LABIN FP=Diso SIGFP=SIGDiso FPH1=Dano SIGFPH1=SIGDano
end
EOF-scaleit
rm -f \\\${tempfile}diso_dano.mtz >& /dev/null
rm -f \\\${tempfile}scaleit.in >& /dev/null


# print out "k" value from scaling
cat \\\${tempfile}scaleit.log |\\\\
nawk '/APPLICATION OF SCALES/,/--------------------------/' |\\\\
nawk '\\\$1 == "Derivative"{printf "k= %.3f\\\\n", 2*\\\$3}'

rm -f \\\${tempfile}scaleit.log >& /dev/null


combine_diso_dano:
##############################################################
# now combine Diso and Dano as the "best" estimate of total FH

echo "calculating FH = sqrt( Diso^2 + (k/2)^2 * Dano^2 )"

# also do a "Patterson weight" of 1/(sigma(FH^2))^2
echo "NREF -1" |\\\\
mtzdump HKLIN \\\${tempfile}scaled.mtz |\\\\
nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
nawk '! /[A-Z]/ && NF>1{ HKL=substr(\\\$0,1,13); \\\\
    Diso=substr(\\\$0,14,12); SIGDiso=substr(\\\$0,26,10); \\\\
    Dano=substr(\\\$0,36,10); SIGDano=substr(\\\$0,46,10); \\\\
    FH=fh=sqrt(Diso*Diso + Dano*Dano); if(fh==0) fh=1;\\\\
    varFH  = (Diso*SIGDiso/fh)^2 + (Dano*SIGDano/fh)^2;\\\\
    varFH2 = 4 * FH^2 * varFH; \\\\
    W=0; if(varFH) W = 1/sqrt(varFH); if(W>maxW) maxW=W;\\\\
    print HKL, FH, sqrt(varFH), W} \\\\
    END{if(maxW) print 1/maxW > "'\\\${tempfile}'norm"}' |\\\\
cat >! \\\${tempfile}FH.hkl

set norm = \\\`tail -1 \\\${tempfile}norm\\\`
rm -f \\\${tempfile}norm >& /dev/null
if(\\\$#norm != 1) set norm = 1

# read FH back into mtz (finally)
f2mtz HKLIN \\\${tempfile}FH.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
CELL \\\$CELL
SYMM \\\$SGnum
LABOUT H K L FH SIGFH W
CTYPO  H H H F Q W
SCALE  1 1 1 1 1 \\\$norm
EOF-f2mtz
rm -f \\\${tempfile}FH.hkl >& /dev/null


sort_final:
# sort it (for good measure)
echo "H K L" |\\\\
sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\$outfile >> \\\$logfile
if((! \\\$status)&&(-e "\\\$outfile")) then
    echo "\\\$outfile is ready."
else
    echo "ERROR! see \\\$logfile for what happened..."
    exit 9
endif

rm -f \\\${tempfile}sortme.mtz
##############################################################


# use scaleit to get the recommended DIFF
scaleit hklin \\\$outfile << EOF >! \\\${tempfile}scaleit
analyze
labin FP=FH SIGFP=SIGFH FPH1=FH SIGFPH1=SIGFH
SCALE FPH1 0.000001
END
EOF
if("\\\$DIFF" == "") set DIFF = \\\`nawk '/acceptable differences/{print \\\$NF}' \\\${tempfile}scaleit\\\`
rm -f \\\${tempfile}scaleit >& /dev/null
if("\\\$DIFF" == "") set DIFF = 1000




Shelx_format:
if("\\\$shelxfile" == "") goto Fourier

# dump FH out in shelx format too.
mtz2various HKLIN \\\$outfile HKLOUT \\\$shelxfile << EOF-shelx >> \\\$logfile
OUTPUT SHELX
FSQUARED
LABIN FP=FH SIGFP=SIGFH
END
EOF-shelx

if((! \\\$status)&&(-e "\\\$shelxfile")) echo "\\\$shelxfile is the SHELX version of \\\$outfile."


Fourier:
###########################################
if(("\\\$PHASE" == "")||("\\\$fourfile" == "")) goto Patterson
# calculate a phased Fourier of FH
# first, we need to retrieve the phase columns
set FOM_cad = ""
if("\\\$FOM" != "") set FOM_cad = "E2=\\\$FOM"
# set up FOM weight
set W = ""
if("\\\$FOM" != "") set W = "W=\\\$FOM"

# special case of Diso or Dano only
if((\\\$Ds == 0)||(\\\$Fs <= 1)) then
    # no double-difference data
    set E1 = "E1=F"
    set fftF1="F1=FH"
    if(\\\$Fs <= 1) then
	# anomalous data only
	set E1="E1=D"
	set fftF1="DANO=FH"
    endif
    
    # but still want phased FH map
    cad hklin1 \\\$outfile hklin2 \\\$mtzfile \\\\
	hklout \\\${tempfile}phased.mtz << EOF-cad >> \\\$logfile
    LABIN FILE 1 E1=FH E2=SIGFH
    LABIN FILE 2 E1=\\\$PHASE \\\$FOM_cad
    CTYPO FILE 1 \\\$E1 E2=Q
EOF-cad

    # ordinary, boring difference Fourier
    fft HKLIN \\\${tempfile}phased.mtz MAPOUT \\\${tempfile}FH.map << EOF-fft >> \\\$logfile
    TITLE \\\${hiRES}A map of FH @ \\\$PHASE \\\$FOM
    RESOLUTION \\\$scaleRES
    LABIN \\\$fftF1 SIG1=SIGFH PHI=\\\$PHASE \\\$W
    EXCLUDE SIG1 0
EOF-fft
    
    goto norm_Four
endif

# calculate a combined, phased difference Fourier
cad hklin1 \\\${tempfile}scaled.mtz hklin2 \\\$mtzfile \\\\
    hklout \\\${tempfile}phased.mtz << EOF-cad >> \\\$logfile
LABIN FILE 1 E1=Diso E2=SIGDiso E3=Dano E4=SIGDano
LABIN FILE 2 E1=\\\$PHASE \\\$FOM_cad
CTYPO FILE 1 E1=F E2=Q E3=D E4=Q
EOF-cad

# now we make the isomorphous difference Fourier
fft HKLIN \\\${tempfile}phased.mtz MAPOUT \\\${tempfile}Diso.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A map of Diso @ \\\$PHASE \\\$FOM
RESOLUTION \\\$scaleRES
LABIN F1=Diso SIG1=SIGDiso PHI=\\\$PHASE \\\$W
EXCLUDE SIG1 0
EOF-fft

# then make the anomalous difference Fourier (phases rotated 90 degrees)
fft HKLIN \\\${tempfile}phased.mtz MAPOUT \\\${tempfile}Dano.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A map of Dano @ \\\$PHASE \\\$FOM
RESOLUTION \\\$scaleRES
LABIN DANO=Dano SIG1=SIGDiso PHI=\\\$PHASE \\\$W
EXCLUDE SIG1 0
EOF-fft

# try to make sure we get the right sign
# assume map has at least one large peak (which should be positive)
echo "go" | mapdump mapin \\\${tempfile}Diso.map |\\\\
nawk '/Minimum density/{print -\\\$NF, -1} /Maximum density/{print \\\$NF, 1}' |\\\\
sort -nr |\\\\
nawk 'NR==1{print \\\$NF}' >! \\\${tempfile}sign
set diso_sign = \\\`cat \\\${tempfile}sign\\\`
rm -f \\\${tempfile}sign >& /dev/null

# invert the Diso map if it seems to be upside-down
#if(("\\\$diso_sign" == "-1")) then
if(("\\\$diso_sign" == "-1")&&(! \\\$?USER_ORDER)) then
    echo "inverting sequence of Diso for difference Fourier"
    echo "SCALE FACTOR -1 0" |\\\\
    mapmask mapin1 \\\${tempfile}Diso.map mapout \\\${tempfile}temp.map >> \\\$logfile
    mv \\\${tempfile}temp.map \\\${tempfile}Diso.map >& /dev/null
endif

# add these two maps together (equivalent to vector sum to FH)
echo "MAPS ADD" |\\\\
mapmask mapin1 \\\${tempfile}Diso.map mapin2 \\\${tempfile}Dano.map \\\\
mapout \\\${tempfile}FH.map >> \\\$logfile

norm_Four:
# normalize it for output
echo "SCALE SIGMA" |\\\\
mapmask mapin \\\${tempfile}FH.map mapout \\\$fourfile >> \\\$logfile

if((! \\\$status)&&(-e "\\\$fourfile")) echo "\\\$fourfile is the map of \\\$PHASE applied to FH"

rm -f \\\${tempfile}phased.mtz >& /dev/null
rm -f \\\${tempfile}Diso.map >& /dev/null
rm -f \\\${tempfile}Dano.map >& /dev/null
rm -f \\\${tempfile}FH.map >& /dev/null


Patterson:
###########################################
if("\\\$pattfile" == "") goto Clean_up

# calculate the unweighted Patterson map (if desired)
fft HKLIN \\\$outfile MAPOUT \\\${tempfile}FH.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A Patterson of FH
RESOLUTION \\\$scaleRES
PATTERSON
LABIN F1=FH SIG1=SIGFH F2=FH SIG2=SIGFH
SCALE F2 0.000001 0
EXCLUDE DIFF \\\$DIFF
EXCLUDE SIG1 0
EOF-fft
peakmax MAPIN \\\${tempfile}FH.map XYZOUT \\\${tempfile}.pdb << EOF-pick >> \\\$logfile
THRESHOLD RMS 3
NUMPEAKS 50
EOF-pick
# extend it to whole unit cell?
mapmask mapin \\\${tempfile}FH.map mapout "\\\$pattfile" << EOF >> \\\$logfile
scale sigma
#xyzlim 0 1 0 1 0 1
EOF
if((! \\\$status)&&(-e "\\\$pattfile")) echo "\\\$pattfile is the Patterson of FH."
rm -f \\\${tempfile}FH.map >& /dev/null


if("\\\$wpattfile" == "") goto Clean_up
# calculate the weighted Patterson map (if desired)
fft HKLIN \\\$outfile MAPOUT \\\${tempfile}FH.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A Patterson of FH/SIGFH
RESOLUTION \\\$scaleRES
PATTERSON
LABIN F1=FH SIG1=SIGFH W=W F2=FH SIG2=SIGFH
SCALE F2 0.000001 0
#EXCLUDE DIFF \\\$DIFF
EXCLUDE SIG1 0
EOF-fft
peakmax MAPIN \\\${tempfile}FH.map XYZOUT \\\${tempfile}.pdb << EOF-pick >> \\\$logfile
THRESHOLD RMS 3
NUMPEAKS 50
EOF-pick
# extend it to whole unit cell?
mapmask mapin \\\${tempfile}FH.map mapout "\\\$wpattfile" << EOF >> \\\$logfile
scale sigma
#xyzlim 0 1 0 1 0 1
EOF
if((! \\\$status)&&(-e "\\\$wpattfile")) echo "\\\$wpattfile is the Patterson of FH / sig(FH)^2"
rm -f \\\${tempfile}FH.map >& /dev/null


# clean up
Clean_up:

rm -f \\\${tempfile}scaled.mtz >& /dev/null
rm -f \\\${tempfile}Fs     >& /dev/null
rm -f \\\${tempfile}Ds     >& /dev/null
rm -f \\\${tempfile}Fpairs >& /dev/null
rm -f \\\${tempfile}.pdb   >& /dev/null


exit






Setup:
#################################################

  ####   ######   #####  #    #  #####
 #       #          #    #    #  #    #
  ####   #####      #    #    #  #    #
      #  #          #    #    #  #####
 #    #  #          #    #    #  #
  ####   ######     #     ####   #

#################################################
#
#   gather information on:
#    mtz file
#    data sets
#    resolution limits
#    sigma cuttoff (for map generation)
#    difference cutoff
#
##################################################
if(! \\\$?DIFF) set DIFF = ""

# scan the command line for files
foreach arg ( \\\$* )
    # warn about probable mispellings
    if("\\\$arg" =~ *.mtz) then
	if(-e "\\\$arg") then
	    set mtzfile = "\\\$arg"
	else
	    if(! \\\$?useroutfile) then
		set useroutfile = "\\\$arg"
		set outfile = "\\\$arg"
	    endif
	endif
    endif
end


# now all filenames have been initialized

if(! -e "\\\$mtzfile") goto Help

##################################################
# get crystal and dataset information from the mtz file
echo "go" | mtzdump HKLIN \\\$mtzfile >! \\\${tempfile}mtzdump
set CELL  = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\${tempfile}mtzdump\\\`
set SGnum = \\\`nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzdump\\\`
set SG    = \\\`nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set hiRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\${tempfile}mtzdump\\\`

# get column label names from the mtz file
nawk 'NF>3' \\\${tempfile}mtzdump |\\\\
nawk '\\\$(NF-1)=="F"{print "F", \\\$NF}\\\\
      \\\$(NF-1)=="D"{print "D", \\\$NF}\\\\
      \\\$(NF-1)=="Q"{print "S", \\\$NF}\\\\
      \\\$(NF-1)=="P"{print "P", \\\$NF}\\\\
      \\\$(NF-1)=="W"{print "W", \\\$NF}' |\\\\
nawk '/^F/{++n} /^D/{++n} /^P/{++n} {printf "%s", \\\$1; \\\\
       if(\\\$1=="S") printf "%s", last;\\\\
printf " %d %s \\\\n",n, \\\$2; last=\\\$1}' |\\\\
cat >! \\\${tempfile}datasets
rm -f \\\${tempfile}mtzdump >& /dev/null

# check extent of available data
set temp = \\\`nawk '/^F/ || /^D/' \\\${tempfile}datasets |& wc -l\\\`
if(\\\$temp < 1) then
    # this is useless, bail out now
    rm -f \\\${tempfile}datasets >& /dev/null
    echo "ERROR: no usable data in \\\${mtzfile}! "
    set mtzfile = ""
    goto Help
endif

# get complete, unique lists of DANO/SIGDANOs
cat \\\${tempfile}datasets |\\\\
nawk '\\\$1=="D"{D[\\\$2]=\\\$NF} \\\$1=="SD"{S[\\\$2]=\\\$NF} \\\\
      END{for(i in D) print i, D[i], S[i];}' |\\\\
sort -un |\\\\
nawk 'NF==3{print \\\$2,\\\$3}' |\\\\
cat >! \\\${tempfile}Ds

# get complete, unique lists of F/SIGFs
cat \\\${tempfile}datasets |\\\\
nawk '\\\$1=="F"{F[\\\$2]=\\\$NF} \\\$1=="SF"{S[\\\$2]=\\\$NF} \\\\
      END{for(i in F) print i, F[i], S[i];}' |\\\\
sort -un |\\\\
nawk 'NF==3{print \\\$2,\\\$3}' |\\\\
cat >! \\\${tempfile}Fs

# get complete, unique lists of Phases/FOMs
cat \\\${tempfile}datasets |\\\\
nawk '\\\$1=="P"{P[\\\$2]=\\\$NF} \\\$1=="W"{W[\\\$2]=\\\$NF} \\\\
      END{for(i in P) print i, P[i], W[i];}' |\\\\
sort -un |\\\\
nawk 'NF>=2{print \\\$2,\\\$3, " "}' |\\\\
cat >! \\\${tempfile}Ps


# one last pass through command line
# allow user overrides of all internal variables
set i = 0
echo -n "" >! \\\${tempfile}userlabels
while( \\\$i < \\\$#argv )
    @ i = ( \\\$i + 1 )
    @ nexti = ( \\\$i + 1 )
    @ lasti = ( \\\$i - 1 )
    if(\\\$nexti > \\\$#argv) set nexti = \\\$#argv
    if(\\\$lasti < 1) set lasti = 1
    set arg = "\\\$argv[\\\$i]"
    
    # see if a dataset label was given
    egrep " \\\$arg " \\\${tempfile}datasets >& /dev/null
    if(! \\\$status) then
	if(\\\$?NO) then
	    # user doesn't want this label
	    # filter it out of the input files
	    egrep -v "^\\\$arg " \\\${tempfile}Fs >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}Fs
	    egrep -v "^\\\$arg " \\\${tempfile}Ds >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}Ds
	    egrep -v "^\\\$arg " \\\${tempfile}Ps >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}Ps
	else
	    # must want only this label?
	    cat \\\${tempfile}datasets |\\\\
	    nawk -v label=\\\$arg 'NF>2 && \\\$NF==label{print \\\$NF}' |\\\\
	    cat >> \\\${tempfile}userlabels
	endif
	# "NO" stays set for next word
	continue
    endif
    
    # only look at non-file words
    if(-e "\\\$arg") then
	unset NO
	continue
    endif
    
    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
		    set loRES = "\\\$temp[1]"
		    set hiRES = "\\\$temp[2]"
		endif
	    else
		if("\\\$temp" != "") set hiRES = "\\\$temp"
	    endif
	endif
	    
	if(("\\\$arg" =~ *[Ss]igma)||("\\\$argv[\\\$nexti]" =~ [Ss]igma)) then
	    set DATA_cutoff = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
	
	if(("\\\$arg" =~ *[Dd]iff)||("\\\$argv[\\\$lasti]" =~ [Dd]iff)) then
	    set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
	if(("\\\$arg" =~ *[Dd]iso)||("\\\$argv[\\\$lasti]" =~ [Dd]iso)) then
	    set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
	if(("\\\$arg" =~ *[Dd]ano)||("\\\$argv[\\\$lasti]" =~ [Dd]ano)) then
	    set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
    endif
    
    # allow "NO" logic to carry through to next word(s)
    unset NO
    if(("\\\$arg" == "no")||("\\\$arg" == "not")) set NO
    if(("\\\$arg" == "don't")||("\\\$arg" == "ignore")) set NO
    if("\\\$arg" == "except") set NO
end

rm -f \\\${tempfile}datasets >& /dev/null

# turn the "user" labels into real label files
cat \\\${tempfile}Ds \\\${tempfile}userlabels |\\\\
nawk 'NF==2{set[\\\$1]=\\\$0}\\\\
      NF==1{print set[\\\$1]}' |\\\\
nawk 'NF==2' >! \\\${tempfile}
set Ds = \\\`cat \\\${tempfile} | wc -l\\\`
if(\\\$Ds > 0) then
    # user mentioned which Ds to use
    mv \\\${tempfile} \\\${tempfile}Ds
endif
set Ds = \\\`cat \\\${tempfile}Ds | wc -l\\\`

# same for Fs
cat \\\${tempfile}Fs \\\${tempfile}userlabels |\\\\
nawk 'NF==2{set[\\\$1]=\\\$0}\\\\
      NF==1{print set[\\\$1]}' |\\\\
nawk 'NF==2' >! \\\${tempfile}
set Fs = \\\`cat \\\${tempfile} | wc -l\\\`
if(\\\$Fs > 1) then
    # user mentioned which Fs to use
    mv \\\${tempfile} \\\${tempfile}Fs
    
    # get user-specified F dataset order 
    set order = \\\`nawk 'NF==2{print \\\$1}' \\\${tempfile}Fs\\\`
    set USER_ORDER
endif
set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`

# same for Phases
cat \\\${tempfile}Ps \\\${tempfile}userlabels |\\\\
nawk 'NF==1{print set[\\\$1]}\\\\
           {set[\\\$1]=\\\$0}' |\\\\
nawk 'NF!=0' >! \\\${tempfile}
set Ps = \\\`cat \\\${tempfile} | wc -l\\\`
if(\\\$Ps > 0) then
    # user mentioned which Phase to use
    tail -1 \\\${tempfile} >! \\\${tempfile}Ps
endif
# only use one phase
tail -1 \\\${tempfile}Ps >! \\\${tempfile}
set PHASE = \\\`nawk '{print \\\$1}' \\\${tempfile}\\\`
set FOM   = \\\`nawk '{print \\\$2}' \\\${tempfile}\\\`


# clean up
rm -f \\\${tempfile} >& /dev/null
rm -f \\\${tempfile}Ps >& /dev/null
rm -f \\\${tempfile}userlabels >& /dev/null

goto Return_from_Setup


####################################################

The Future:
re-order Diso if scales come out screwy?
make the interface a little slicker, less wordy?
use correlation instead of scale as a weight?
implement use of max_DANO, DATA_cutoff, etc. ?

EOF-script
chmod a+x \$SCRIPT

















###############################################################################
#
#	revise.com
#
###############################################################################
set SCRIPT = \$SCRIPT_dir/revise.com
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#
#	revise.com 
#
#	calculate an estimate of FM for the heavy atoms alone
#	using CCP4's "revise" program
#
#	FM should give cleaner Pattersons, difference Fouriers,
#	and direct methods.
#
#	Do NOT combine differences from data sets expected to have
#	different heavy atom locations.  That would be silly.
#
#
# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

# defaults (can be overriden by command-line input)
set mtzfile     = "\${finalMTZ}" 	# MAD data set
set fp          = ""			# set these if you know what they are
set fpp         = ""			# set these if you know what they are
set Fs		= "\$wavenames"	# overriden by contents of mtz
set wavelengths = "\$wavelengths"	# only important if fp/fpp are unassiged
set Ee		= "\$Ee"			# only important if fp/fpp are unassiged

set outfile     = "./FM.mtz"		# contains FH, SIGFH
set shelxfile   = "./fm.hkl"		# same thing, shelx format
set pattfile    = "./FM_Patt.map"	# Combined Patterson map

set tempfile = ./revise_temp\\\$\\\$


# initialize internal variables
set loRES = 1000
set hiRES = ""

set DATA_cutoff = 0	# sigma cutoff      
set MAX_dano 	= 0.5	# upper Dano cutoff 
set MAX_diso	= 0.1	# upper Diso cutoff 

if(\\\$#argv == 0) goto Help

# this procedure (re)sets most of the above variables
# from either the provided files, or the command line
goto Setup

Help:
cat << EOF

usage: \\\$0 \\\$mtzfile \\\$Fs

where:
\\\$mtzfile	- contains at least two sets of F and DANO 
		  you want to combine


EOF

exit 2
#
#   This procedure (at the bottom of the script) does the following
#   1) scan the command line for the mtz file
#   2) set the CELL, SG, and other variables
#   3) generate dataset name list:
#      \\\${tempfile}LABIN and \\\${tempfile}waves
Return_from_Setup:


################################################################
#   initial report on intended program flow
################################################################
echo "running revise on \\\$mtzfile"
echo "with:"

Crossec:
################################################################
if("\\\$fp" != "") goto Revise

# make a lookup table for recognizing sorted wavelengths
echo "\\\$wavelengths" | nawk '{for(i=1;i<=NF;++i) print i, \\\$i, "order"}' |\\\\
sort -n -k2 |\\\\
cat >! \\\${tempfile}waveorder

# calculate f' and f" of \\\$Ee at the provided wavelengths
crossec << EOF >! \\\${tempfile}crossec.log
ATOM \\\$Ee
NWAVE \\\$#wavelengths \\\$wavelengths
END
EOF
# log will be printed out and deleted later

# condense crossec output to vital info only
cat \\\${tempfile}crossec.log |\\\\
nawk 'NF==4 && \\\$NF !~ /[^0-9\\\\.]/' |\\\\
sort -n -k2 |\\\\
cat >! \\\${tempfile}sortedwaves

# now put the wavelengths back in the order we originally had them
cat \\\${tempfile}waveorder \\\${tempfile}sortedwaves |\\\\
nawk '\\\$NF=="order"{++i; order[i]=\\\$1} \\\\
      \\\$NF!="order"{++n; print order[n], \\\$2, \\\$3, \\\$4}' |\\\\
sort -n >! \\\${tempfile}fp_fdp

# load f' and f" into variables (in dataset order)
set fp  = \\\`nawk '{print \\\$3}' \\\${tempfile}fp_fdp\\\`
set fpp = \\\`nawk '{print \\\$4}' \\\${tempfile}fp_fdp\\\`

# clean up
rm -f \\\${tempfile}fp_fdp >& /dev/null
rm -f \\\${tempfile}waveorder >& /dev/null
rm -f \\\${tempfile}sortedwaves >& /dev/null




Revise:
################################################################
# make a table of f' f" values (vs dataset number)
echo "\\\$fp" | nawk '{for(i=1;i<=NF;++i) print i, \\\$i, "fp"}' |\\\\
cat >! \\\${tempfile}fp
echo "\\\$fpp" | nawk '{for(i=1;i<=NF;++i) print i, \\\$i, "fpp"}' |\\\\
cat >! \\\${tempfile}fpp

# same thing for wavelengths (vs dataset number)
echo "\\\$wavelengths" | nawk '{for(i=1;i<=NF;++i) printf "%d %.4f wave\\\\n", i, \\\$i}' |\\\\
cat >! \\\${tempfile}waves

# make a table of datasets (vs dataset number)
cat \\\${tempfile}LABIN |\\\\
nawk '/^FPH/{split(\\\$1,w,"="); i=substr(\\\$1,4)+0; print i, w[2], "set"}' |\\\\
cat >! \\\${tempfile}datasets

# combine all this information into revise "WAVE" keywords
cat \\\${tempfile}datasets \\\${tempfile}waves \\\${tempfile}fp \\\${tempfile}fpp |\\\\
nawk '\\\$NF=="fp"{fp[\\\$1]=\\\$2} \\\$NF=="fpp"{fpp[\\\$1]=\\\$2} \\\\
      \\\$NF=="set"{set[\\\$1]=\\\$2} \\\$NF=="wave"{wave[\\\$1]=\\\$2} \\\\
      END{for(i in set) \\\\
      print "WAVE", i, "LAM", wave[i], "FPR", fp[i], "FDP", fpp[i]}' |\\\\
sort -n -k2 >! \\\${tempfile}WAVE

# clean up 
rm -f \\\${tempfile}datasets >& /dev/null
rm -f \\\${tempfile}waves    >& /dev/null
rm -f \\\${tempfile}fp       >& /dev/null
rm -f \\\${tempfile}fpp      >& /dev/null

# display f' f" stuff for user:
echo 'dataset wavelength  f'"'"'     f"   '
cat \\\${tempfile}LABIN \\\${tempfile}WAVE |\\\\
nawk '/^FPH/{split(\\\$1,w,"="); i=substr(\\\$1,4)+0; F[i]=w[2]} \\\\
/^WAVE/{printf "%7s  %7.5fA  %s %s\\\\n",F[\\\$2],\\\$4,\\\$6,\\\$8}'
echo ""
echo ""
test -t 1
if(! \\\$status) then
    echo "is this okay? [Yes]"
    echo -n "-> "
    set temp = "\\\$<"
    if("\\\$temp" =~ [Nn]*) then
	echo "please either change the order of your data sets (on the command line)"
	echo "or edit \\\$0 to enter in the proper f' and f"\\\\"" values."
	rm -f \\\${tempfile}LABIN \\\${tempfile}WAVE >& /dev/null
	exit 3
    endif
endif

# print this out for user's benifit
if(-e \\\${tempfile}crossec.log) then
    cat \\\${tempfile}crossec.log
    rm -f \\\${tempfile}crossec.log >& /dev/null
endif

################################################################
# now actually run revise! 
################################################################
revise hklin \\\$mtzfile hklout \\\${tempfile}revised.mtz << eof
TITLE  revised \\\$mtzfile

# read in Fs:
@\\\${tempfile}LABIN

LABO FM=FM SIGFM=SIGFM


# read in WAVE cards
@\\\${tempfile}WAVE

EXCL RISO \\\$MAX_diso RANO \\\$MAX_dano SIGM \\\$DATA_cutoff

END
eof

# strip off everything but FM
rm -f \\\$outfile >& /dev/null
cad hklin1 \\\${tempfile}revised.mtz hklout \\\$outfile << EOF
LABIN FILE 1 E1=FM E2=SIGFM
#LABOUT ALLIN
EOF
if((! \\\$status)&&(-e \\\$outfile)) then
    echo "\\\$outfile is ready."
    echo "calculated from \\\$mtzfile using:"
    echo 'dataset wavelength  f'"'"'     f"   '
    cat \\\${tempfile}LABIN \\\${tempfile}WAVE |\\\\
    nawk '/^FPH/{split(\\\$1,w,"="); i=substr(\\\$1,4)+0; F[i]=w[2]} \\\\
    /^WAVE/{printf "%7s  %7.4fA  %s %s\\\\n",F[\\\$2],\\\$4,\\\$6,\\\$8}'
endif

# clean up a bit
rm -f \\\${tempfile}WAVE >& /dev/null
rm -f \\\${tempfile}LABIN >& /dev/null
rm -f \\\${tempfile}revised.mtz >& /dev/null

Shelx_format:
################################################################
if("\\\$shelxfile" == "") goto Patterson

# dump FM out in shelx format too.
mtz2various HKLIN \\\$outfile HKLOUT \\\$shelxfile << EOF-shelx
OUTPUT SHELX
FSQUARED
LABIN FP=FM SIGFP=SIGFM
END
EOF-shelx

if((! \\\$status)&&(-e "\\\$shelxfile")) echo "\\\$shelxfile is ready."


Patterson:
################################################################
if("\\\$pattfile" == "") goto Clean_up

# use scaleit to get the recommended DIFF
scaleit hklin \\\$outfile << EOF >! \\\${tempfile}scaleit
analyze
labin FP=FM SIGFP=SIGFM FPH1=FM SIGFPH1=SIGFM
SCALE FPH1 0.000001
END
EOF
if(! \\\$?DIFF) set DIFF
set DIFF = \\\`nawk '/acceptable differences/{print \\\$NF}' \\\${tempfile}scaleit\\\`
rm -f \\\${tempfile}scaleit >& /dev/null
if("\\\$DIFF" == "") set DIFF = 1000

# calculate the Patterson map (if desired)
fft HKLIN \\\$outfile MAPOUT \\\${tempfile}FM.map << EOF-fft
PATTERSON
RESO \\\$loRES \\\$hiRES
LABIN F1=FM SIG1=SIGFM F2=FM SIG2=SIGFM
SCALE F2 0.000001 0
EXCLUDE DIFF \\\$DIFF
EXCLUDE SIG1 0
EOF-fft
peakmax MAPIN \\\${tempfile}FM.map XYZOUT \\\${tempfile}.pdb << EOF-pick
THRESHOLD RMS 3
NUMPEAKS 50
EOF-pick
# extend it to whole unit cell?
mapmask mapin \\\${tempfile}FM.map mapout "\\\$pattfile" << EOF
scale sigma
#xyzlim 0 1 0 1 0 1
EOF
if((! \\\$status)&&(-e "\\\$pattfile")) echo "\\\$pattfile is ready."
rm -f \\\${tempfile}FM.map >& /dev/null


Clean_up:
################################################################
# clean up


rm -f \\\${tempfile}.pdb   >& /dev/null


exit






Setup:
#################################################

  ####   ######   #####  #    #  #####
 #       #          #    #    #  #    #
  ####   #####      #    #    #  #    #
      #  #          #    #    #  #####
 #    #  #          #    #    #  #
  ####   ######     #     ####   #

#################################################
#
#   gather information on:
#    mtz file
#    data sets
#    resolution limits
#    sigma cuttoff (for map generation)
#    difference cutoff
#
##################################################
# make multiword variables out of these
set Fs		= ( \\\$Fs )
set wavelengths = ( \\\$wavelengths )
set fp          = ( \\\$fp )
set fpp         = ( \\\$fpp )

# scan the command line for files
foreach arg ( \\\$* )
    # warn about probable mispellings
    if("\\\$arg" =~ *.mtz) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set mtzfile = "\\\$arg"
    endif
    
    if("\\\$arg" =~ [A-Z][a-y]) then
	# might as well consider this an element
	set temp = "\\\$arg"
	if(\\\$?CLIBD) then
	    # check the CCP4 atom database
	    set temp = \\\`nawk -v arg=\\\$arg 'NF==1 && toupper(\\\$1)==toupper(arg){print; exit}' \\\$CLIBD/atomsf.lib\\\`
	endif
	if("\\\$temp" != "") set Ee = "\\\$arg"
	continue
    endif
end


# now all filenames have been initialized

if(! -e "\\\$mtzfile") goto Help

##################################################
# get crystal and dataset information from the mtz file
echo "go" | mtzdump HKLIN \\\$mtzfile >! \\\${tempfile}mtzdump
set CELL  = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\${tempfile}mtzdump\\\`
set SG    = \\\`nawk '/Space group/{print \\\$5}' \\\${tempfile}mtzdump\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzdump \\\`
set SG = \\\` nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile}mtzdump \\\`
set SG = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set hiRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\${tempfile}mtzdump\\\`

# get column label names from the mtz file
nawk 'NF>3' \\\${tempfile}mtzdump |\\\\
nawk '\\\$(NF-1)=="F"{print "F", \\\$NF}\\\\
      \\\$(NF-1)=="D"{print "D", \\\$NF}\\\\
      \\\$(NF-1)=="Q"{print "S", \\\$NF}' |\\\\
nawk '/^F/{++n} {printf "%s", \\\$1; \\\\
       if(\\\$1=="S") printf "%s", last;\\\\
printf " %d %s\\\\n",n, \\\$2; last=\\\$1}' |\\\\
nawk '\\\$1=="F"{F[\\\$2]=\\\$NF} \\\$1=="SF"{SF[\\\$2]=\\\$NF} \\\\
      \\\$1=="D"{D[\\\$2]=\\\$NF} \\\$1=="SD"{SD[\\\$2]=\\\$NF} \\\\
      END{for(i in F){\\\\
	print i, F[i], SF[i], D[i],SD[i];}}' |\\\\
sort -n >! \\\${tempfile}datasets


# check extent of available data
set temp = \\\`cat \\\${tempfile}datasets |& wc -l\\\`
if(\\\$temp < 2) then
    # this is useless, revise won't run. bail out now
    rm -f \\\${tempfile}datasets >& /dev/null
    echo "ERROR: no usable data in \\\${mtzfile}! "
    set mtzfile = ""
    goto Help
endif


# one last pass through command line
# allow user overrides of all internal variables
set i = 0
echo -n "" >! \\\${tempfile}userlabels
while( \\\$i < \\\$#argv )
    @ i = ( \\\$i + 1 )
    @ nexti = ( \\\$i + 1 )
    @ lasti = ( \\\$i - 1 )
    if(\\\$nexti > \\\$#argv) set nexti = \\\$#argv
    if(\\\$lasti < 1) set lasti = 1
    set arg = "\\\$argv[\\\$i]"
    
    # see if a dataset label was given
    grep " \\\$arg " \\\${tempfile}datasets >& /dev/null
    if(! \\\$status) then
	if(\\\$?NO) then
	    # user doesn't want this label
	    # filter it out of the input files
	    egrep -v " \\\$arg " \\\${tempfile}datasets >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}datasets
	    continue
	else
	    # must want only this label?
	    cat \\\${tempfile}mtzdump |\\\\
	    nawk -v label=\\\$arg 'NF>2 && \\\$NF==label{print \\\$NF}' |\\\\
	    cat >> \\\${tempfile}userlabels
	endif
    endif
    
    # only look at non-file words
    if(! -e "\\\$arg") then
	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
			set loRES = "\\\$temp[1]"
			set hiRES = "\\\$temp[2]"
		    endif
		else
		    if("\\\$temp" != "") set hiRES = "\\\$temp"
		endif
	    endif
	    
	    if(("\\\$arg" =~ *[Ss]igma)||("\\\$argv[\\\$nexti]" =~ [Ss]igma)) then
		set DATA_cutoff = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    
	    if(("\\\$arg" =~ *[Dd]iff)||("\\\$argv[\\\$lasti]" =~ [Dd]iff)) then
		set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
		set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    if(("\\\$arg" =~ *[Dd]iso)||("\\\$argv[\\\$lasti]" =~ [Dd]iso)) then
		set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    if(("\\\$arg" =~ *[Dd]ano)||("\\\$argv[\\\$lasti]" =~ [Dd]ano)) then
		set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	endif
	
	# allow "NO" logic to carry through
	unset NO
	if(("\\\$arg" == "no")||("\\\$arg" == "not")) set NO
	if(("\\\$arg" == "don't")||("\\\$arg" == "ignore")) set NO
	if("\\\$arg" == "except") set NO
    endif
end

rm -f \\\${tempfile}mtzdump >& /dev/null

#######################################################
# see if user specified particular labels
set temp = \\\`cat \\\${tempfile}userlabels | wc -l\\\`
if(\\\$temp != 0) then
    # turn the "user" labels into real label files
    cat \\\${tempfile}userlabels \\\${tempfile}datasets |\\\\
    nawk 'NF==1{++n; label[n]=\\\$NF}\\\\
          NF>1 {for(i in label) for(j=2;j<=NF;++j){\\\\
		if(label[i]==\\\$j) print i, \\\$2,\\\$3,\\\$4,\\\$5;break}}' |\\\\
    sort -n >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}datasets >& /dev/null
endif
if((\\\$temp == 0)&&(\\\$#Fs != 0)) then
    # apply the labels from the top of the script?
    echo "\\\$Fs" | nawk '{for(i=1;i<=NF;++i) print \\\$i}' >! \\\${tempfile}userlabels
    cat \\\${tempfile}userlabels \\\${tempfile}datasets |\\\\
    nawk 'NF==1{++n; label[n]=\\\$NF}\\\\
          NF>1 {for(i in label) for(j=2;j<=NF;++j){\\\\
		if(label[i]==\\\$j) print i, \\\$2,\\\$3,\\\$4,\\\$5;break}}' |\\\\
    sort -n >! \\\${tempfile}
    set temp = \\\`cat \\\${tempfile} | wc -l\\\`
    if(\\\$temp != 0) mv \\\${tempfile} \\\${tempfile}datasets >& /dev/null    
endif


###############################################################
# create "LABIN" cards for revise for each dataset
cat \\\${tempfile}datasets |\\\\
nawk '{print "FPH" \\\$1 "=" \\\$2, "SIGFPH" \\\$1 "=" \\\$3,\\\\
             "DPH" \\\$1 "=" \\\$4, "SIGDPH" \\\$1 "=" \\\$5;}' |\\\\
sort -n |\\\\
nawk 'BEGIN{printf "%s", "LABIN"} {printf " -\\\\n%s", \\\$0} END{print ""}' |\\\\
cat >! \\\${tempfile}LABIN


# convert the labin cards into an "Fs" variable
cat \\\${tempfile}LABIN |\\\\
nawk '/^FPH/{i=substr(\\\$1,4)+0; split(\\\$1,w,"="); print i, w[2]}' |\\\\
sort -n | nawk '{print \\\$NF}' |\\\\
cat >! \\\${tempfile}Fs
set Fs = \\\`cat \\\${tempfile}Fs\\\`
if(\\\$#Fs < 2) then
    echo "Sorry, revise needs at least two wavelengths."
    goto Help
endif

# make a table connecting Fs to wavelengths
echo "\\\$wavelengths" |\\\\
 nawk '{for(i=1;i<=NF;++i) print i,\\\$i,"lambda"}' |\\\\
cat >! \\\${tempfile}waves


# clean up
rm -f \\\${tempfile}Fs >& /dev/null
rm -f \\\${tempfile}datasets >& /dev/null
rm -f \\\${tempfile}userlabels >& /dev/null

goto Return_from_Setup


exit
####################################################

EOF-script
chmod a+x \$SCRIPT



















###############################################################################
#
#	MTZ file re-indexer
#
###############################################################################
set SCRIPT = \$SCRIPT_dir/reindex.com
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#	reindex.com
#
#	simple interface to reindexing of merged or unmerged mtz data
#
#
# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set mtzfile    = ""
set logfile    = "reindex.log"
set newmtzfile = "reindexed.mtz"
set tempfile   = ./reindex_temp\\\$\\\$

set message    = ""
set newSG      = ""

goto Setup
#
#	scan command line for mtz files, space groups, and preferences
#
Help:
cat << EOF-Help
usage: \\\$0 mtzfile.mtz [SG] [flip] [newmtz.mtz]

where:

mtzfile.mtz	- the mtz data you want to re-index. (merged or unmerged)
SG		- the new space group (P43 for example)
flip		- flip ambiguous axes of P4x P3x and P6x cells
newmtz.mtz	- name you want for the reindexed mtz (default: reindexed.mtz)

Example:    \\\$0 Fpp.mtz P43212 Fpp.P43212.mtz
Example:    \\\$0 Fpp.mtz flip

Note: to put the screw axis of P2221 on the shortest cell axis, say P2122
The space group in the new file will be P2221 again, but the cell
will be flipped around appropriately.  Same goes for P2212, or
P21221 and P22121 with P21212

EOF-Help
exit
#
Return_from_Setup:

if(! -e "\\\$mtzfile") goto Help

# okay to proceed
if("\\\$message" != "") set message = " \\\$message"
echo "reindexing \\\$mtzfile to \\\$newmtzfile (in \\\${newSG}\\\${message})" | tee \\\$logfile

if(\\\$?MERGED) then
    # apply any "flip" directives with "reindex"
    echo "\\\$REINDEX" |\\\\
    reindex HKLIN \\\$mtzfile HKLOUT \\\${tempfile}reindexed.mtz >> \\\$logfile
    if(\\\$status) set BAD
    
    # just use mtzutils to change SG record in header
    echo "SYMM \\\$newSGnum" |\\\\
    mtzutils HKLIN \\\${tempfile}reindexed.mtz HKLOUT \\\${tempfile}newSG.mtz >> \\\$logfile
    if(\\\$status) set BAD
    
    rm -f \\\${tempfile}reindexed.mtz >& /dev/null
    
    # sort it again, just to be safe
    echo "H K L" |\\\\
    sortmtz HKLIN \\\${tempfile}newSG.mtz HKLOUT \\\$newmtzfile >> \\\$logfile
    if(\\\$status) set BAD
    
    rm -f \\\${tempfile}newSG.mtz >& /dev/null
endif
    
if(\\\$?UNMERGED) then
    reindex HKLIN \\\$mtzfile HKLOUT \\\${tempfile}reindexed.mtz << EOF-reindex >> \\\$logfile
    SYMM \\\$newSG
    \\\$REINDEX
EOF-reindex
    if(\\\$status) set BAD

    # sort again
    sortmtz HKLIN \\\${tempfile}reindexed.mtz HKLOUT \\\$newmtzfile << EOF-sort >> \\\$logfile
\${USE_VRSET}VRSET -9E+38
H K L M/ISYM BATCH I SIGI
EOF-sort
    if(\\\$status) set BAD
    
endif
# remove intermediate file
rm -f \\\${tempfile}reindexed.mtz >& /dev/null


if((-e "\\\$newmtzfile")&&(! \\\$?BAD)) then
    echo "\\\$newmtzfile is \\\$mtzfile in \\\${newSG}\\\${message}"
    if("\\\$axes" != "") then
	echo "head" | mtzdump hklin "\\\$newmtzfile" |\\\\
	nawk '/Cell Dimensions/{getline;getline;\\\\
	print "new cell:", \\\$1, \\\$2, \\\$3, \\\$4, \\\$5, \\\$6}'
    endif
else
    # something went wrong
    echo "FAILED!  examine \\\$logfile to see what went wrong."
endif

exit







Setup:
#############################################################
# check up on essentials
if(! \\\$?CLIBD) then
    echo "Please set up CCP4, and then run \\\$0 again"
    goto Help
endif
if(! -e \\\$CLIBD/symop.lib) then
    echo "ERROR: no \\\$CLIBD/symop.lib"
    echo "Please set up CCP4, and then run \\\$0 again"
    goto Help
endif

set REINDEX
set axes
set FLIP = 0

#first, get filenames from the command line
foreach arg ( \\\$* )
    if("\\\$arg" =~ *.mtz) then
	if("\\\$mtzfile" == "") then
	    # havn't initialized this yet
	    if(-e "\\\$arg") then
		# check to make sure it is readable
		echo "HEAD" | mtzdump HKLIN \\\$arg >&! \\\${tempfile}mtzdump
		grep "Space group" \\\${tempfile}mtzdump >& /dev/null
		if(\\\$status) then
		    echo "WARNING: \\\$arg is not an MTZ file! "
		    continue
		endif
		set mtzfile = "\\\$arg"
	    else
		echo "WARNING: \\\$arg does not exist! "
		continue
	    endif
	else
	    # already have an input mtz, so assume this is output
	    set newmtzfile = "\\\$arg"
	    
	    # look for "hidden" space group in name? 
	    echo \\\$newmtzfile |\\\\
	     nawk '{for(i=1;i<=length(\\\$0);++i){c=substr(\\\$0,i,1);\\\\
	       if(c ~ /[PpCcIiFfRrHh1-6]/){printf c}else{print ""}}}' |\\\\
	     nawk '\\\$1~/^[PpCcIiFfRrHh][1-6]/' >! \\\${tempfile}SGs
	    foreach sg ( \\\`tail -10 \\\${tempfile}SGs\\\` )
		set temp = \\\`nawk -v SG=\\\$sg '\\\$4 == SG && \\\$1 < 500 {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
		if("\\\$temp" != "") then
		    set newSG = "\\\$temp"
		endif
	    end
	    rm -f \\\${tempfile}SGs >& /dev/null
	endif
    endif

    # check for new space group
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	# check for SGs listed in library (but not the screwy ones)
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	if(\\\$?CLIBD) then
	    set temp = \\\`nawk -v SG=\\\$temp '\\\$4 == SG && \\\$1 < 500 {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
	endif
	if("\\\$temp" != "") then
	    set newSG = "\\\$temp"
	endif
	
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	# check for orthorhombic "pseudo-spacegroup" language
	if("\\\$temp" == P2221) then
	    # P2221 with screw along longest axis
	    set axes  = "a b c"
	    set newSG = "P2221"
	    continue
	endif
	if("\\\$temp" == P2212) then
	    # P2221 with screw along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P2221"
	    continue
	endif
	if("\\\$temp" == P2122) then
	    # P2221 with screw along shortest axis
	    set axes  = "c a b"
	    set newSG = "P2221"
	    continue
	endif
	
	if("\\\$temp" == P21212) then
	    # P21212 with non-screw along longest axis
	    set axes  = "a b c"
	    set newSG = "P21212"
	    continue
	endif
	if("\\\$temp" == P21221) then
	    # P21212 with non-screw along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P21212"
	    continue
	endif
	if("\\\$temp" == P22121) then
	    # P21212 with non-screw along shotest axis
	    set axes  = "c a b"
	    set newSG = "P21212"
	    continue
	endif
	    
	if("\\\$temp" == P112) then
	    # P2 with twofold along longest axis
	    #set axes  = "a b c"
	    set newSG = "P2"
	    continue
	endif
	if("\\\$temp" == P121) then
	    # P2 with twofold along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P2"
	    continue
	endif
	if("\\\$temp" == P211) then
	    # P2 with twofold along shortest axis
	    set axes  = "c a b"
	    set newSG = "P2"
	    continue
	endif
	    
	if("\\\$temp" == P1121) then
	    # P21 with twofold along longest axis
	    #set axes  = "a b c"
	    set newSG = "P21"
	    continue
	endif
	if("\\\$temp" == P1211) then
	    # P21 with twofold along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P21"
	    continue
	endif
	if("\\\$temp" == P2111) then
	    # P21 with twofold along shortest axis
	    set axes  = "c a b"
	    set newSG = "P21"
	    continue
	endif
    endif
	
    # check for flipping of ambiguous axes
    if("\\\$arg" == "flip") then
	# user requested "flip" of axes
	@ FLIP = ( \\\$FLIP + 1 )
    endif
    
    # what about cubic? 
end

if(! -e "\\\$mtzfile") then
    goto Help
endif

# get info from the MTZ (should be left over from command-line check)
set CELL  = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\${tempfile}mtzdump\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzdump \\\`
cat \\\$CLIBD/symop.lib |\\\\
nawk -v SGnum=\\\$SGnum '\\\$1==SGnum{type=substr(tolower(\\\$6),1,1); key=substr(\\\$6,4,1);\\\\
    if((type=="t")&&(key=="G")) type="h"; if((type=="t")&&(key=="C")) type="a";\\\\
    print \\\$1, \\\$5, type substr(\\\$4,1,1), \\\$6, \\\$4;}' |\\\\
head -1 >! \\\${tempfile}sgdata
set SGnum = \\\`nawk '{print \\\$1}' \\\${tempfile}sgdata\\\`
set SG    = \\\`nawk '{print \\\$5}' \\\${tempfile}sgdata\\\`
set PG    = \\\`nawk '{print \\\$2}' \\\${tempfile}sgdata\\\`
set BRAV  = \\\`nawk '{print \\\$3}' \\\${tempfile}sgdata\\\`
set LATT  = \\\`nawk '{print \\\$4}' \\\${tempfile}sgdata\\\`

if("\\\$newSG" == "") set newSG = "\\\$SG"
cat \\\$CLIBD/symop.lib |\\\\
nawk -v SG=\\\$newSG '\\\$4==SG{type=substr(tolower(\\\$6),1,1); key=substr(\\\$6,4,1);\\\\
    if((type=="t")&&(key=="G")) type="h"; if((type=="t")&&(key=="C")) type="a";\\\\
    print \\\$1, \\\$5, type substr(\\\$4,1,1), \\\$6;}' |\\\\
head -1 >! \\\${tempfile}sgdata
set newSGnum = \\\`nawk '{print \\\$1}' \\\${tempfile}sgdata\\\`
set newPG    = \\\`nawk '{print \\\$2}' \\\${tempfile}sgdata\\\`
set newBRAV  = \\\`nawk '{print \\\$3}' \\\${tempfile}sgdata\\\`
set newLATT  = \\\`nawk '{print \\\$4}' \\\${tempfile}sgdata\\\`
rm -f \\\${tempfile}sgdata >& /dev/null

# decide how/if to flip
if(\\\$FLIP) then
    if(("\\\$SG" =~ [IP][46]*)||("\\\$SG" =~ P3*12)||("\\\$SG" =~ [PIF]2*3)) then
	set REINDEX = "reindex k, h, -l"
	set message = "with a and b axes flipped"
    endif
    if(("\\\$SG" == R32)||("\\\$SG" =~ P3*21)) then
	set REINDEX = "reindex -h, -k, l"
	set message = "with a and b axes inverted"
    endif
    if(("\\\$SG" =~ [PR]3)||("\\\$SG" =~ P3[12])) then
	# four possibilities here...
	if(\\\$FLIP == 1) then
	    set REINDEX = "reindex k, h, -l"
	    set message = "with a and b axes flipped"
	endif
	if(\\\$FLIP == 2) then
	    set REINDEX = "reindex -h, -k, l"
	    set message = "with a and b axes inverted"
	endif
	if(\\\$FLIP >  2) then
	    set REINDEX = "reindex -k, -h, -l"
	    set message = "with a and b axes flipped and inverted"
	endif
    endif
    if("\\\$SG" == P1) then
	# permute the axes (from their cannonical order)
	if(\\\$FLIP == 1) set axes = "a b c"
	if(\\\$FLIP == 2) set axes = "b c a"
	if(\\\$FLIP == 3) set axes = "c a b"
    endif
    if("\\\$PG" == PG2) then
	# flip the a and c axes?
	set REINDEX = "reindex l, -k, h"
	set message = "with a and c axes flipped"
    endif
    # for other space groups, "flip" is simply ignored
endif

if(("\\\$newSG" == "")&&(! \\\$FLIP)) then
    # WTF?
    echo "nothing to do! "
    rm -f \\\${tempfile}mtzdump >& /dev/null
    goto Help
endif

# now that whole command-line has been read, make some holistic decisions


# check to see if it's merged or unmerged
grep "Number of Batches" \\\${tempfile}mtzdump >& /dev/null
if(\\\$status) then
    set MERGED
else
    set UNMERGED
endif
rm -f \\\${tempfile}mtzdump


# decide on new axis ordering (for asymmetric orthorhombics)
if("\\\$newSG" == "P222")    set axes = "a b c"
if("\\\$newSG" == "P212121") set axes = "a b c"
if("\\\$axes" != "") then
    # get current axis ordering
    # find out what the cannonical one would be
    # then decide how to go from current ordering to the desired one
    echo "\\\$CELL" | nawk '{\\\\
	# print out current axis order \\\\
	print \\\$1, "h"; print \\\$2, "k"; print \\\$3, "l"}' |\\\\
    sort -n |\\\\
    nawk '\\\\
	# add cannonical axis names\\\\
	NR==1{print \\\$0, "a"} NR==2{print \\\$0, "b"} NR==3{print \\\$0, "c"}' |\\\\
    nawk -v axes="\\\$axes" 'BEGIN{split(axes, abc)} {\\\\
	# write desired axis ordering in front of cannonical one \\\\
	print abc[NR], \\\$0}' |\\\\
    sort |\\\\
    nawk '# print out new hkl order \\\\
          {printf "%s ", \\\$3} END{print ""}' |\\\\
    nawk '\\\$1 \\\$2 \\\$3 \\\$1 \\\$2 \\\$3 !~ /hkl/{\\\$3 = "-" \\\$3} {print \\\$1, \\\$2, \\\$3}' |\\\\
    cat >! \\\${tempfile}order    
    set REINDEX = "reindex "\\\`nawk '{print \\\$1 ",", \\\$2 ",", \\\$3}'  \\\${tempfile}order\\\`

    # this should give us a mapping between any two orthorhombics
    
    set temp = \\\`nawk '{print \\\$NF}' \\\${tempfile}order\\\`
    rm -f \\\${tempfile}order
    if("\\\$newSG" == "P2221") then
	set message = "with screw along \\\$temp axis"
    endif
    if("\\\$newSG" == "P21212") then
	set message = "with non-screw along \\\$temp axis"
    endif
    if("\\\$newSG" == "P2") then
	set message = "with twofold along \\\$temp axis"
    endif
    if("\\\$newSG" == "P21") then
	set message = "with twofold screw along \\\$temp axis"
    endif
    if("\\\$newSG" == "P1") then
	set message = "with axes in \\\$axes order."
    endif
endif


# known ways to convert between bravais lattices
if(("\\\$newBRAV" == "oC")&&("\\\$BRAV" =~ h[PR])) then
    # this lattice happens to fit, even if it's merged
    set REINDEX = "reindex h+k, k-h, l"
    set message = "with old hkl -> h+k,k-h,l"
    set OKAY
endif
set change_type = \\\`echo \\\$SG \\\$newSG | nawk 'substr(\\\$1,1,1) != substr(\\\$2,1,1)'\\\`
# cubic to just about anything should be okay
if(("\\\$change_type" == "")&&("\\\$BRAV" =~ c*)&&("\\\$newBRAV" !~ h*)) set OKAY
# tetratonal to anything below it should be okay
if(("\\\$change_type" == "")&&("\\\$BRAV" =~ t*)&&("\\\$newBRAV" !~ h*)&&("\\\$newBRAV" !~ c*)) set OKAY
# orthorhombic to anything below it is okay

# anything can be converted to P1
if("\\\$newBRAV" == aP) set OKAY

# now check for unhandlable situations


if((\\\$?MERGED)&&("\\\$newPG" != "\\\$PG")&&("\\\$PG" != "")&&(! \\\$?OKAY)) then
    # can't do this
    echo "WARNING: You Shouldn't reindex \\\$SG to \\\$newSG for a merged mtz! "
    echo ""
    if(\\\$SGnum < \\\$newSGnum) then
	cat << EOF
Since \\\$newSG has higher symmetry than \\\$SG, we would have
to merge some "unique" spots in \\\$mtzfile together.  Although
this is technically possible, it is definitely not advisable.
If your space group really is \\\$newSG, you will probably get
much better scaling and mergeing performance with the new
symmetry imposed during data processing, and probably in
data reduction as well.

EOF
    else
	cat << EOF
Since \\\$SG has higher symmetry than \\\$newSG, we would have
to "unmerge" the unique HKLs in \\\$mtzfile to form multiple, 
yet completely identical Fs.  So, all this will do is
make your mtz bigger, so we will just change the spacegroup
name.

If you think you "overmerged" your data in \\\$SG, then you
should go back to your mergeing step, and change \\\$SG to
\\\$newSG there.

EOF
    endif
#    exit
endif

if(\\\$?MERGED) goto Return_from_Setup
# now we are dealing with unmerged data

# what do we do about THIS! 
set temp = \\\`echo "\\\$newSG \\\$SG" | nawk 'substr(\\\$1,1,1) != substr(\\\$2,1,1)'\\\`
if("\\\$temp" != "") then
    # crystal system has changed!
    if(\\\$newSGnum < \\\$SGnum) then
	# we are going to loose some data
	
    else
	
    endif
    echo "WARNING: changing the lattice symmetry "
endif

goto Return_from_Setup
EOF-script
chmod a+x \$SCRIPT



















###############################################################################
#
#	MTZ file summarizer
#
###############################################################################
set SCRIPT = \$SCRIPT_dir/mtz_sum.com
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#	Utility script for quick, tabular summary of a merged MTZ file
#
#
###############################################################################
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set reso = ""
set mtzfile = ""
foreach arg ( \\\$* )
    if("\\\$arg" =~ [0-8].[0-9]*) set reso = "reso 100 \\\$arg"
    if(("\\\$arg" =~ *.mtz)&&(-e "\\\$arg")) set mtzfile = "\\\$arg"
end
if("\\\$mtzfile" == "") then
    echo "usage \\\$0 mtzfile.mtz [resolution]"
endif
#
echo "STATS NBIN 1 \\\$reso" | mtzdump hklin \\\$mtzfile |\\\\
 nawk '\\\$11 == "F"{printf \\\$NF ":\\\\t%6.2f%% complete,",\\\$6; F=\\\$7; lab=\\\$NF}\\\\
  \\\$12 == "SIG"lab {if((\\\$7+0)){printf "     / = %6.2f\\\\n", F/\\\$7}else{print ""}}'

EOF-script
chmod a+x \$SCRIPT

###############################################################################
#
#	scaleit logfile summarizer
#
###############################################################################
set SCRIPT = \$SCRIPT_dir/scaleit_sum.com
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#	Utility script for quick, tabular summary of Diso and Dano
#
#
###############################################################################
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk

echo " \\\\044TABLE : Diso and Dano:"
echo " \\\\044GRAPHS:Diso and Dano vs energy:A:1, 2, 3:"
echo " :Diso vs energy:A:1, 2:"
echo " :Dano vs energy:A:1, 3:"
echo "\\\\044\\\\044"
echo "energy  Diso  Dano   \\\\044\\\\044"
echo "\\\\044\\\\044"

cat  \\\$1 |\\\\
    nawk 'BEGIN{\\
EOF-script

# hard-code wavelengths with their names
echo "\$wavenames \$wavelengths" |\\
nawk '{for(i=1;i<=NF/2;++i){E=12398.4245/\$(i+NF/2); \\
       print "    E[\\042" \$i "\\042] = " E " ; \\134"}}' >> \$SCRIPT

cat << EOF-script >> \$SCRIPT
    }\\\\
    \\\$3 == "FPH="{++i;name[i] = \\\$4;}\\\\
    /TOTALS/{++j; diso[j]=substr(\\\$0,70,8)+0; dano[j]=substr(\\\$0,100,8)+0;\\\\
    printf "%.1f %5.1f %5.1f\\\\n", E[name[j]], diso[j], dano[j]}'

echo "\\\\044\\\\044"



echo " \\\\044TABLE : Risos:"
echo " \\\\044GRAPHS:Risos vs energy:A:1, 2, 3, 4:"
echo " :RFAC vs energy:A:1, 2:"
echo " :RF_I vs energy:A:1, 3:"
echo " :Wted_R vs energy:A:1, 4:"
echo "\\\\044\\\\044"
echo "energy  RFAC RF_I Wted_R   \\\\044\\\\044"
echo "\\\\044\\\\044"

cat  \\\$1 |\\\\
    nawk 'BEGIN{\\\\
EOF-script
echo "\$wavenames \$wavelengths" |\\
nawk '{for(i=1;i<=NF/2;++i){E=12398.4245/\$(i+NF/2); \\
       print "    E[\\042" \$i "\\042] = " E " ; \\134"}}' >> \$SCRIPT
cat << EOF-script >> \$SCRIPT
    }\\\\
    \\\$3 == "FPH="{++i;name[i] = \\\$4;}\\\\
    /TOTALS/{++j; RFAC[j]=substr(\\\$0,63,7)*100;\\\\
                  RF_I[j]=substr(\\\$0,56,7)*100;\\\\
                  Wted_R[j]=substr(\\\$0,49,7)*100;\\\\
    printf "%.1f %5.1f %5.1f %5.1f\\\\n", E[name[j]], RFAC[j], RF_I[j], Wted_R[j]}'

echo "\\\\044\\\\044"



EOF-script
chmod a+x \$SCRIPT

###############################################################################
#
#	Scala logfile summarizer
#
###############################################################################
set SCRIPT = \$SCRIPT_dir/scala_summary.com
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Automatically generated script for sumarizing scala logs
#  in nice, tabular format
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk

echo "wavelength Rmerge  Ranom I/sigma Complete Mult Wilson B"
foreach log ( \\\$* )
    basename \\\$log .log | nawk 'BEGIN{RS="_"}{print}' |\\
     nawk 'BEGIN{RS="."}{print}' | nawk 'BEGIN{RS="-"}{print}' |\\
     nawk 'NF != 0' | tail -1 |\\
     nawk '{printf "%10s ", \\\$NF}'
    nawk '/Dmin/{idx=index(\\\$0,"Mn")}\\
	/Overall:/{printf "%6.3f %6.3f %7.3f\\n", \\\$2, \\\$5, substr(\\\$0,idx)+0}' \\
    \\\$log | tail -1 | nawk '{printf "%s", \\\$0}'
    nawk '/Completeness v Resolution/,/Overall/{print}' \\\$log |\\
    tail -1 | nawk '{printf " %7.1f%% %4.1f", \\\$5, \\\$7}'
    nawk '/squares straight/{printf " %8.3f\\n", \\\$8}' \\
    \\\$log | tail -1 | nawk '{printf "%s", \\\$0}'
    echo ""
end
EOF-script
chmod a+x \$SCRIPT





###############################################################################
#
#	AutoScala   - optimizes SDCORR card in a SCALA mergeing script
#
###############################################################################
set SCRIPT = \$SCRIPT_dir/autoscala
cat << EOF-script >! \$SCRIPT
#! \$nawk -f
BEGIN {
#
#
#	Automatically adjusts SDCORR card in SCALA for "optimum" statistics
#	as given by agrovata.
#
#	The provided script MUST generate mergeing statistics (agrovata or scala).
#	The following scripts must be creatable.
#
#	test_script = "./" FILENAME "_test"
#	best_script = "./" FILENAME "_best"
#
#	The latter will continuously be updated to the best SDCORR line
#	found so far.
#
#
#
#
#
#
#
	# these are convergence criteria
	# specify the number of decimal places you want to refine
	# each variable to.
	sdfac_decimals = 2
	sdprime_decimals = 0
	sdadd_decimals = 2

	# defaults for Golden Section search
	# go ahead and modify these if you're 
	# SURE the best value is bracketed
	maximum_sdprime = 15
	maximum_sdadd   = 0.1

	minimum_sdprime = 0
	minimum_sdadd   = 0
	
	# alternately, you may specify "tune=factor"

	best_so_far = 1000000
	line = 0
	if(!debug) debug = 0
}
# finish up initialization (for linux awk)
NR==1{
    if((!test_script)&&(FILENAME)) test_script = "./" FILENAME "_test"
    if((!best_script)&&(FILENAME)) best_script = "./" FILENAME "_best"
    if((!test_log)&&(FILENAME))    test_log    = "./" FILENAME ".log"

    if(!test_script) test_script = "./scala.com_test"
    if(!best_script) best_script = "./scala.com_best"
    if(!test_log)    test_log    = "./scala.com.log"
}

########################################################################
#       Analyze the supplied script & copy it into memory              #
########################################################################

# copy the script into an array
{
    ++line;
    ++number_of_lines;
    script[line] = \\\$0;

    # now make everything easier to search
    \\\$0 = tolower(\\\$0);
}

# look for the "SDCORR" card in scala
/^sdcorr/ {
    # get the current sd correction parameters
    sdfac = \\\$2;
    if(NF == 4)
    {
	sdprime = \\\$3;
	sdadd = \\\$4;
    }
    else
    {
	# no sdprime specified
	sdprime = 0;
	sdadd = \\\$3;
    }	

    sdcorr_line = line;
}

END {
########################################################################
#	Now begins the "real" program                                  #
########################################################################


    # user may specify "tuning mode"
    if(tune > 1)
    {
	if(sdprime)
	{
	    maximum_sdprime = sdprime * tune;
	    minimum_sdprime = sdprime / tune;
	}

	if(sdadd)
	{
	    maximum_sdadd = sdadd * tune;
	    minimum_sdadd = sdadd / tune;
	}
    }

    # signal to optimize ...
    max_sdfac = max_sdprime = max_sdadd = "restart"
    done = 0;
    
    while(!done)
    {
	# write the script
	WriteScript(test_script);

	if(value[script[sdcorr_line]] != 0)
	{
	    # we have already caclulated this value
	    
	    RMSD_sigma = value[script[sdcorr_line]]
	    if(debug>1) print  "recall: " script[sdcorr_line] "\\\\t\\\\tRMSD(sigma): " RMSD_sigma*100 "\\\\tbest so far: " best_so_far*100;
	}
	else
	{
	    # we havn't run this pair before
	    
	    # run it, and filter output
	    printf  "trying: %s ", script[sdcorr_line] sdcorr_pad;
	    GetResults(test_script);
	
	    # remember all values obtained (to avoid repeats)
	    value[script[sdcorr_line]] = RMSD_sigma;

	    # print out rating of this run
	    printf "RMS(scatter/sigma -1): %8.5f    ", RMSD_sigma;

	    # update absolute best result
	    if(RMSD_sigma < best_so_far) 
	    {
		best_so_far = RMSD_sigma;
		best_sdcorr = script[sdcorr_line];

		# write out best scripts immediately
		WriteScript(best_script);

		# print out the values used, and their effect
		printf "best so far: %8.5f ", best_so_far;
	    }
	    # finish the line
	    print "";
	}

	# pick next values based on last run...
	if(NextSDadd()) 
	{
	    # ...has converged
	    
	    # "inner" loop done, so pick next sdprime value
	    if(NextSDprime()) 
	    {
		# ...has converged
		
		# both have converged, so we are done
		done = "true";
	    }
	    # reoptimize sdadd with new sdprime
	    max_sdadd = "restart";
	}
    }
    
    # Main loop has exited.
    # parameters have converged, so finish up


    # update scala's output files to best values
    #GetResults(best_script);

    
    # update variables for output
    split(best_sdcorr, best);
#    sdfac   = best[2];
    sdfac   = sprintf("%." sdfac_decimals "f", best_sdfac);
    sdprime = best[3];
    sdadd   = best[4];    
    
    # get rid of "test" script
    system("rm -f " test_script)
    # update the "best" script
    WriteScript(best_script);
    
    if(summary != "no")	    # option for cleaner output
    {
	print  "\\\\n\\\\nSUMMARY:\\\\n"
	printf("%s ==> RMSD = %.4f\\\\n", best_sdcorr, value[best_sdcorr]);
	print  "\\\\n"
	print  "****************************************"
	print  "**      BEST CARD FOUND               **"
	printf "**      %21s         **\\\\n", script[sdcorr_line];
	print  "****************************************"
	print  "\\\\n"

	# tell user what to do next
	print "***********************"
	print "***   ALL DONE!!!   ***"
	print "***********************"

	print "Your new " FILENAME " can be found at: " best_script

    }

}
########################################################################
#	Functions used in this script                                  #
########################################################################


#########################################################################
#	NextSDprime()							#
#									#
#	Updates optimizing parameters based on observed output from	#
#	the agrovata script.						#
#									#
#	uses:		RMSD_sigma					#
#									#
#	modifies:	sdprime						#
#									#
#	contains:	max_sdprime					#
#			min_sdprime					#
#			best_sdprime					#
#									#
#			value[]						#
#									#
#########################################################################
function NextSDprime()
{
    # offset SDprime to keep from interfering with sdfac in value[]
    sdprime += 100;
    best_sdprime += 100;

    # this should be known first
    value[sdprime] = RMSD_sigma;

    # pick some reasonable limits
    if (max_sdprime == "restart") 
    {
	min_sdprime = minimum_sdprime +100;
	value[max_sdprime] = 100000;

	best_sdprime = min_sdprime;
	value[best_sdprime] = 100000;

	max_sdprime = maximum_sdprime +100;
	value[max_sdprime] = 100000;
    }

    # use the Golden Section method to find minimum
    sdprime = GoldStep(min_sdprime, sdprime, best_sdprime, max_sdprime);
    min_sdprime = Gold_min;
    max_sdprime = Gold_max;
    best_sdprime = Gold_best;

        
    # just for monitoring...
    sdprime_step = sdprime - best_sdprime;
	
    # update move counter
    ++move;

    # now move sdprime back to true value
    sdprime -= 100;
    best_sdprime -= 100;

    # check for convergence
    if(max_sdprime - min_sdprime < 0.1^sdprime_decimals)
    {
	#convergence reached
	doneness = "true";
    }
    else
    {
	doneness = "";
    }
    
    # in case you're intetested...
    return doneness;
}

#########################################################################
#	NextSDadd()							#
#									#
#	Updates optimizing parameters based on observed output from	#
#	the agrovata script.						#
#									#
#	uses:		RMSD_sigma					#
#									#
#	modifies:	sdadd						#
#									#
#	contains:	max_sdadd					#
#			min_sdadd					#
#			best_sdadd					#
#									#
#			value[]						#
#									#
#########################################################################
function NextSDadd()
{
    # this should be known first
    value[sdadd] = RMSD_sigma;

    # pick some reasonable limits
    if (max_sdadd == "restart") 
    {
	min_sdadd = minimum_sdadd;
	value[max_sdadd] = 100000;

	best_sdadd = min_sdadd - min_sdadd_step/10;
	value[best_sdadd] = 100000;

	max_sdadd = maximum_sdadd;
	value[max_sdadd] = 100000;
    }

    # use the Golden Section method to find minimum
    sdadd = GoldStep(min_sdadd, sdadd, best_sdadd, max_sdadd);
    min_sdadd = Gold_min;
    max_sdadd = Gold_max;
    best_sdadd = Gold_best;

                
    # just for monitoring...
    sdadd_step = sdadd - best_sdadd;
	
    # update move counter
    ++move;

    # check for convergence
    if(max_sdadd - min_sdadd < 0.1^sdadd_decimals)
    {
	#convergence reached
	doneness = "true";
    }
    else
    {
	doneness = "";
    }

    # in case you're intetested...
    return doneness;
}





#########################################################################
#	WriteScript(filename)						#
#									#
#	Writes the script contained in the script[] array to the	#
#	file given in "filename."					#
#		The following cards, however, are rewriten with		#
#	the existing trial values:	WIDTH				#
#									#
#	uses:		script[]					#
#			bin_scale					#
#			width						#
#									#
#########################################################################
function WriteScript( filename )
{	
    for(line = 1; line <= number_of_lines; ++line)
    {
	if(line == sdcorr_line)
	{
	    script[line] = "SDCORR " sdfac \\\\
				 " " round(sdprime, sdprime_decimals) \\\\
				 " " round(sdadd, sdadd_decimals);
	    sdcorr_pad = "";
    	    for(i=0;i < 25 - length(script[line]); ++i) {sdcorr_pad = sdcorr_pad " "}
	}

	print script[line] > filename;
    }
    # close the file
    close(filename);

    #change it to an executable;
    system("chmod u+x " filename);
}


#########################################################################
#       GetResults(filename)                                            #
#                                                                       #
#       Runs the script given as "filename" and analyzes the output     #
#       for the agrovata Sigma(scatter/SD) graph.                       #
#               The RMS deviation from an even distribution of          #
#       observations per intensity bin is computed as RMSD_width.       #
#               The RMS deviation from 1.0 of the scatter/SD is         #
#       also computed and placed in RMSD_sigma.                         #
#                                                                       #
#       modifies:       RMSD_width                                      #
#                       RMSD_width_p                                    #
#                       RMSD_sigma                                      #
#                       RMSD_sigma_p                                    #
#                       RMSD_sigma_w                                    #
#                       best_sdfac                                      #
#                                                                       #
#########################################################################
function GetResults ( filename )
{
    # report what we're doing
#    print "running " filename "..."

    # analyze stdout from "agrovata" script
    command = filename
#    if(test_log) command = filename " | tee " test_log
    while(command | getline > 0)
    {
        # look for the graph entry
        if (\\\$0 ~ /^ \\\\\\\$GRAPHS: Sigma\\\\(scatter\\\\/SD\\\\)/)
	{
	    graph = 1
	    
	    # initialize cumulative variables
	    count_full["sum"]=count_part["sum"]=count["sum"]=0
	    bins = 0  
	}
	if (\\\$1 == "TOTALS:") graph = 0

        if(graph && \\\$0 ~ /Sigma/)
        {
            sig1_idx = index(\\\$0,"Sigma");
            sig2_idx = index(substr(\\\$0,sig1_idx+1),"Sigma")+1+sig1_idx;
        }

        if (graph && (\\\$0 !~ /[a-z]/) && NF>3)
        {
            # we are reading a line of graph data
	    ++bins
	    
	    # gather stats	    
#	    count_full[bins]  = \\\$5
#	    count_part[bins]  = \\\$9
            string = substr(\\\$0, 1,count1_idx);
            while(gsub("[^ ]\\\$","",string));
            idx = length(string);
            count_full[bins]  = substr(\\\$0, idx, 9)+0
            string = substr(\\\$0, 1,count2_idx);
            while(gsub("[^ ]\\\$","",string));
            idx = length(string);
            count_part[bins]  = substr(\\\$0, idx, 9)+0
	    count[bins]       = count_full[bins]+count_part[bins]

	    # sums
	    count_full["sum"] += count_full[bins]
	    count_part["sum"] += count_part[bins]
	         count["sum"] += count[bins]

#	    scatt_full[bins]  = \\\$7-1
#	    scatt_part[bins]  = \\\$NF-1
	    scatt_full[bins]  = substr(\\\$0, sig1_idx, 8)-1
	    scatt_part[bins]  = substr(\\\$0, sig2_idx, 8)-1
	    scatt[bins]       = (scatt_full[bins]+scatt_part[bins])/2
	}

        # look for refined SDfac
	if(\\\$0 ~ /Final assessment of SDcorrection multipliers/) { sdfac_list = 1 }
	if(\\\$0 ~ /Summary/) {sdfac_list = 0}

	if(sdfac_list)
	{
	    if((\\\$0 ~ /[0-9]/)&&(\\\$0 !~ /[a-z]/))
	    {
		if(NF>2)
		{
		    ++sdfacs
		    sdfac_sum+=(count_full["sum"]*\\\$2+count_part["sum"]*\\\$5)/(count["sum"])
		}
		else
		{
		    sdfac_list = 0
		}
	    }
	}
    }
    
    # close the pipe!
    close(filename);

    # calculate mean SDFAC
    if(sdfacs) best_sdfac = sdfac_sum/sdfacs
#    printf "%.2f %.2f %.2f %.2f \\\\n", best_sdfac, count_full["sum"], count_part["sum"], count["sum"]

    # the scatt and count arrays should now contain the LAST graph in the log
    if(bins)
    {
	# calculate average values
	count_full["avg"] = count_full["sum"]/bins
	count_part["avg"] = count_part["sum"]/bins
	count["avg"]      = count["sum"]     /bins

	# and now rmsds
	count_full["rms"]=count_part["rms"]=count["rms"]=0
	scatt_full["rms"]=scatt_part["rms"]=scatt["rms"]=scatt["wrms"]=0
	for(i=1; i<=bins; ++i)
	{
	    count_full["rms"] += (count_full[i]-count_full["avg"])*(count_full[i]-count_full["avg"])
	    count_part["rms"] += (count_part[i]-count_part["avg"])*(count_part[i]-count_part["avg"])
	    count["rms"]      += (count[i]     -count["avg"]     )*(count[i]     -count["avg"]     )

	    scatt_full["rms"] += scatt_full[i]*scatt_full[i]
	    scatt_part["rms"] += scatt_part[i]*scatt_part[i]
	    scatt["rms"]      += scatt[i]*scatt[i]
	    scatt["wrms"]     += count_full[i]*scatt_full[i]*scatt_full[i]
	    scatt["wrms"]     += count_part[i]*scatt_part[i]*scatt_part[i]
	}
	
	count_full["rms"] = sqrt(count_full["rms"]/bins)
	count_part["rms"] = sqrt(count_part["rms"]/bins)
	count["rms"]      = sqrt(count["rms"]/bins)
	
	scatt_full["rms"] = sqrt(scatt_full["rms"]/bins)
	scatt_part["rms"] = sqrt(scatt_part["rms"]/bins)
	scatt["rms"]      = sqrt(scatt["rms"]/bins)
	scatt["wrms"]     = sqrt(scatt["wrms"]/count["sum"])
    }
    else
    {
	print "ERROR: no stats generated by " filename
	print "please edit " FILENAME " and make sure it runs by itself."
	exit
    }

    # update global variables
    RMSD_width   = count_full["rms"]
    RMSD_width_p = count_part["rms"]
    RMSD_sigma   = scatt_full["rms"]
    RMSD_sigma_p = scatt_part["rms"]
    RMSD_sigma_w = scatt["wrms"]

    RMSD_sigma = RMSD_sigma_w

}

#########################################################################
#	GoldStep(min, last, best, max)					#
#									#
# Computes the Golden (next) step to minimize a variable		#
#									#
#	modifies:							#
#									#
#########################################################################

function GoldStep(min, last, best, max)
{
    # debugging...
    if(debug) printf "\\\\n" min " " best " " max " ==GoldStep==> "
    
    # eliminate sections that cannot contain the minimum
    if(last >= best)
    {
	# we tried a larger value last time
	if(value[last] <= value[best])
	{
	    # minimum must be somewhere between "best" and "max"
	    min = best;
	    best = last;
	}
	else
	{
	    # minimum must be somewhere between "min" and "last"
	    max = last;
	}
    }
    else
    {
	# we tried a smaller value last time
	if(value[last] <= value[best])
	{
	    # minimum must be somewhere between "min" and "best"
	    max = best;
	    best = last;
	}
	else
	{
	    # minimum must be somewhere between "last" and "max"
	    min = last;	    
	}
    }

    # now decide what width to try next
    if((max - best) > (best - min))
    {
	# next value should be larger
	Gold_next = best + 0.38*(max - best)
    }
    else
    {
	# next value should be smaller
	Gold_next = best - 0.38*(best - min)
    }
    
    # save the parameters as Globals ( this is awful!)
    Gold_min = min;
    Gold_max = max;
    Gold_next = Gold_next;
    Gold_best = best;
    
    # debugging...
    if (debug) printf min " " best " " max "\\\\t"
    
    return Gold_next;
}


function abs(number)
{
	return sqrt(number^2);
}

function round(number, sigdigs)
{
	return int(number*10^sigdigs)/10^sigdigs;
}

EOF-script
chmod a+x \$SCRIPT






























SortScript:
###############################################################################

  ####    ####   #####    #####
 #       #    #  #    #     #
  ####   #    #  #    #     #
      #  #    #  #####      #
 #    #  #    #  #   #      #
  ####    ####   #    #     #

###############################################################################
#
#	Rindex, rebatch, and sort all the data into one, big-ass file
#
###############################################################################
set SCRIPT = \${SCRIPT_dir}/sort_everything.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#   Sorting script made by Scaler Elves
#
# Defaults
set SG       = \$SG
set outfile  = "\${rawMTZ}"
set tempfile = "\\\${CCP4_SCR}/sort_temp\\\$\\\$"
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
goto Setup
############################
#
# usage: \$SCRIPT [sg]
# where: [sg] is the new space group
#    eg: \$SCRIPT \$SG
#        means reindex all data to \$SG (and sort it)
#
############################
ReturnFromSetup:
#####################################################
EOF-script

set cmt = "#"
if(\$?RENAME_DATASETS) set cmt = ""


# create rebatch entries for mtzs
foreach n ( \`nawk '\$3 == "+" && /.mtz\$/{++n;print n}' \$RUNFILE\` )

    set line = \`nawk -v n=\$n '\$2=="wavelength"{wave=\$3} \$3=="+" && /.mtz\$/{++i} i==n{print \$NF,\$4,\$6,\$2,wave}' \$RUNFILE\`
    set mtz   = "\$line[1]"
    set first = "\$line[2]"
    set last  = "\$line[3]"
    set add   = "\$line[4]"
    set wave  = "\$line[5]"

    cat << EOF-script >> \$SCRIPT
# add \$add to \$first through \$last in \$mtz
rebatch HKLIN \$mtz HKLOUT \\\${tempfile}run\${n}.mtz << EOF-rebatch
BATCH \$first TO \$last INCLUDE
BATCH \$first TO \$last ADD \$add
\${cmt}BATCH \$first TO \$last pname data xname xtal dname \$wave
EOF-rebatch

EOF-script

    # make some reindexing decisions here?

    cat << EOF-script >> \$SCRIPT
# uncomment/change this if the above mtz is flipped relative to the others
#set REINDEX = "h, k, l"

set sgnum = \\\`echo HEAD | mtzdump hklin \\\${tempfile}run\${n}.mtz | nawk '/Space group =/{print \\\$NF+0}'\\\`
if("\\\$sgnum" != "\\\$SGnum" || "\\\$REINDEX" != "h, k, l") then
    mv \\\${tempfile}run\${n}.mtz \\\${tempfile}.mtz
    reindex HKLIN \\\${tempfile}.mtz HKLOUT \\\${tempfile}run\${n}.mtz << EOF-reindex
SYMM \\\$SG
REINDEX \\\$REINDEX
EOF-reindex
    rm -f \\\${tempfile}.mtz
endif

EOF-script

end


# create rotaprep entries for denzo files
if(\$?DENZO_FILES) then
    cat << EOF-scriptbit >> \$SCRIPT

# prepare denzo files
echo "preparing denzo files"

rm -f \\\${tempfile}run*.york >& /dev/null

EOF-scriptbit
    
    # prepare denzo files
    if(-e \${tempfile}x2york.awk) mv \${tempfile}x2york.awk \${SCRIPT_dir}/x2york.awk
    chmod a+x \${SCRIPT_dir}/x2york.awk
    
    # create instructions to cat denzo runs together
    cat \${tempfile}strategy |\\
    nawk -v cvt=\${SCRIPT_dir}/x2york.awk '\$NF=="DENZO" {\\
    printf "%s %s >> \${tempfile}run%d.york\\n", cvt, \$(NF-1), \$2;}' |\\
    sort -n | sort -u |\\
    nawk '{if(lastrun != \$NF) printf "\\necho \\"\\" >! %s\\n", \$NF; print; lastrun=\$NF}' |\\
    nawk '{print "echo " \$2; print}' |\\
    cat >> \$SCRIPT

    # now give instructions to rotaprep each run
    foreach denzorun ( \`nawk '/DENZO/{print \$2}' \${tempfile}strategy | sort -u -n\` )
	# retrieve batch add value
	set ADD = \`nawk -v run=\$denzorun 'run==\$2{print \$3-\$6; exit}' \${tempfile}strategy\`
	
	cat << EOF-denzopreprun >> \$SCRIPT
	
combat HKLIN \\\${tempfile}run\${denzorun}.york HKLOUT \\\${tempfile}run\${denzorun}.mtz << eof-rotaprep
INPUT DENZO
SYMMETRY \\\$SG
DETECTOR \$XYrange
ADDBATCH \$ADD
END
eof-rotaprep
if(\$status) then
    echo "combat sux ... trying rotaprep"
rotaprep HKLIN \\\${tempfile}run\${denzorun}.york HKLOUT \\\${tempfile}run\${denzorun}.mtz << eof-rotaprep
INPUT DENZO
SYMMETRY \\\$SG
DETECTOR \$XYrange
ADDBATCH \$ADD
END
eof-rotaprep
endif

# done with this file
rm -f \\\${tempfile}run\${denzorun}.york

EOF-denzopreprun
    end
    
endif

# don't need this file anymore
rm -f \${tempfile}strategy


cat << EOF-script >> \$SCRIPT
#####################################################

# sort all runs together into one, big MTZ
sortmtz HKLOUT \\\$outfile << EOF-sort
\${USE_VRSET}VRSET -9E+38
H K L M/ISYM BATCH I SIGI
EOF-script
nawk '\$3 == "+"{++n; print "\${tempfile}run" n ".mtz"}' \$RUNFILE >> \$SCRIPT
cat << EOF-script >> \$SCRIPT
EOF-sort
if(! \\\$status) then
    echo "data from all runs and all wavelengths are now in: \\\$outfile"
else
    echo "sorting failed!  Check for overlapping batch numbers."
    set BAD
    exit 9
endif


#####################################################

# clean up
EOF-script
nawk '\$3 == "+"{++n; print "rm -f \${tempfile}run" n ".mtz"}' \$RUNFILE >> \$SCRIPT

cat << EOF-script >> \$SCRIPT
exit

#####################################################
Setup:
set REINDEX = "h, k, l"
foreach arg ( \\\$* )
    # new space group? 
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	set temp = \\\`nawk -v SG=\\\$arg '\\\$4 == toupper(SG) && \\\$1 < 500 {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
	if("\\\$temp" =~ [PpCcIiFfRrHh][1-6]*) then
	    set SG = "\\\$temp"
	else
	    # check for "pseudo-spacegroup" language
	    if("\\\$arg" =~ [Pp]2212) then
		# P2221 with screw along current "b"
		set SG = "P2221"
		set REINDEX = "l, h, k"
	    endif
	    if("\\\$arg" =~ [Pp]2122) then
		# P2221 with screw along current "a"
		set SG = "P2221"
		set REINDEX = "k, l, h"
	    endif
	    if("\\\$arg" =~ [Pp]21221) then
		# P21212 with non-screw along current "b"
		set SG = "P21212"
		set REINDEX = "l, h, k"
	    endif
	    if("\\\$arg" =~ [Pp]22121) then
		# P21212 with non-screw along current "a"
		set SG = "P21212"
		set REINDEX = "k, l, h"
	    endif
	endif
    endif
end

set SGnum = \\\`nawk -v SG=\\\$SG '\\\$4 == SG{print \\\$1; exit}' \\\$CLIBD/symop.lib\\\`

goto ReturnFromSetup

EOF-script
chmod a+x \$SCRIPT












ImportRefScript:
###############################################################################

  ####   ######   #####          #####   ######  ######
 #    #  #          #            #    #  #       #
 #       #####      #            #    #  #####   #####
 #  ###  #          #            #####   #       #
 #    #  #          #            #   #   #       #
  ####   ######     #            #    #  ######  #

###############################################################################
#
#	import an arbitrary reference set
#
###############################################################################
set SCRIPT = \${SCRIPT_dir}/import_reference.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#   Reference set import script by Scaler Elves
#
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set infile    = \${rawMTZ}
set reffile   = \${refMTZ}
set refdata   = ""
set ref_batch = \$ref_batch
set outfile   = \${sortMTZ}
#
set tempfile  = \${tempfile}get_ref
#
############################################################################
goto Setup
#
# scan command line for user options
#
Return_from_Setup:

##########################################################################
# Remove free-R flagged HKLs from the reference MTZ
#
##########################################################################
if(\\\$?ref_free) then
    # need to convert to text in order to exclude freeR
    mtz2various hklin \\\$reffile hklout \\\${tempfile}.hkl << EOF-various | tee \\\${tempfile}log
    labin FP=\\\$ref_set SIGFP=\\\$ref_sig FREE=\\\$ref_free
    OUTPUT XPLOR
    EXCLUDE FREER 0
EOF-various
    if(\\\$status) set BAD

    # prepare to read back in
    set CELL  = \\\`nawk '/Cell Dimensions/{getline; getline; print}' \\\${tempfile}log\\\`
    set SG    = \\\`nawk '/Space group/{print \\\$5}' \\\${tempfile}log\\\`
    set SGnum = \\\`nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}log\\\`
    set SG    = \\\`nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile}log\\\`
    set SG    = \\\`nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib\\\`
    rm -f \\\${tempfile}log >& /dev/null
    set temp = "F"
    if("\\\$input" == mtzi) set temp = J
   
    # simplefy file
    cat \\\${tempfile}.hkl |\\\\
    nawk '\\\$1 ~ /^INDE/{split(\\\$0,w,"="); print \\\$2, \\\$3, \\\$4, w[2]+0,w[3]+0}' |\\\\
    cat >! \\\${tempfile}no_freeR.hkl
    
    # now read it back in...
    f2mtz hklin \\\${tempfile}no_freeR.hkl hklout \\\${tempfile}reference.mtz << EOF-f2mtz
    CELL \\\$CELL
    SYMM \\\$SG
    SKIP
    LABOUT H K L \\\$ref_set \\\$ref_sig
    CTYPO  H H H \\\$temp Q
EOF-f2mtz
    if(\\\$status) set BAD
    
    # clean up
    rm -f \\\${tempfile}.hkl >& /dev/null
    rm -f \\\${tempfile}no_freeR.hkl >& /dev/null
else
    # symmetry with above
    cp \\\$reffile \\\${tempfile}reference.mtz
endif

##########################################################################
# Reformat reference set for reinput 
#
##########################################################################
combat hklin \\\${tempfile}reference.mtz  hklout \\\${tempfile}prep.mtz << eof-reprep
input \\\$input
batch \\\$ref_batch
labin \\\$labin
DNAME ref
PNAME ref
eof-reprep
if(\\\$status) then
echo "combat sux ... trying rotaprep"
rotaprep hklin \\\${tempfile}reference.mtz  hklout \\\${tempfile}prep.mtz << eof-reprep
input \\\$input
batch \\\$ref_batch
labin \\\$labin
DNAME ref
PNAME ref
eof-reprep
if(\\\$status) set BAD
endif

# Put reference dataset together with raw data: \\\$outfile
mtzutils hklin1 \\\$infile hklin2 \\\${tempfile}prep.mtz  hklout \\\$outfile << eof-utils
merge
eof-utils
if(\\\$status) set BAD

# clean up
rm -f \\\${tempfile}prep.mtz
rm -f \\\${tempfile}reference.mtz >& /dev/null


##########################################################################
if((-e \\\$outfile)&&(! \\\$?BAD)) then
    echo "\\\$outfile now contains all raw data, plus "
    echo " \\\${ref_set}/\\\${ref_sig} from \\\${reffile}, as a reference "
    if(\\\$?ref_free) then
        echo "excluding HKLs where \\\$ref_free == 0"
    endif
else
    echo "import failed!  See above for why."
    exit 9
endif
##########################################################################
exit

Setup:
# now scan command line
foreach arg ( \\\$* )
    # specific input file
    if(\\\$arg =~ *.mtz) then
        echo "HEAD" | mtzdump hklin \\\$arg |\\\\
        nawk '/Column Labels/{getline;getline;while(NF){printf "%s ", \\\$0; getline};print ""}\\\\
              /Column Types/ {getline;getline;while(NF){printf "%s ", \\\$0; getline};print ""}' |\\\\
	cat >! \\\${tempfile}.mtzdump
	grep "H K L" \\\${tempfile}.mtzdump >& /dev/null
        if(\\\$status) then
	    echo "WARNING: \\\$arg is not an mtz file! "
	    rm -f \\\${tempfile}.mtzdump >& /dev/null
	    continue
        endif

	# check for multirecord mtz
	grep " BATCH I " \\\${tempfile}.mtzdump >& /dev/null
	if(! \\\$status) then
	    # this must be the multirecord, raw-data file
	    set infile = \\\$arg
	    rm -f \\\${tempfile}.mtzdump >& /dev/null
	    continue
	endif
	
	# this must be a single-record mtz (merged)
	set reffile = \\\$arg
	cat \\\${tempfile}.mtzdump |\\\\
	nawk 'NR==1{split(\\\$0,name)} NR==2{for(i=1;i<=NF;++i){print \\\$i,name[i]}}' |\\\\
	cat >! \\\${tempfile}.labels
	rm -f \\\${tempfile}.mtzdump >& /dev/null
	continue
    endif
end

if(! -e "\\\$reffile") then
    echo "ERROR: reference mtz file does not exist! "
    rm -f \\\${tempfile}.labels >& /dev/null
    set BAD
    exit 9
endif


# see if user specified labels in the reference mtz
foreach arg ( \\\$refdata \\\$* )
    set temp = \\\`nawk -v arg=\\\$arg '\\\$NF==arg' \\\${tempfile}.labels\\\`
    if("\\\$temp" =~ J*) then
    	set input = mtzi
    	set ref_set = "\\\$temp[2]" 
    endif
    if("\\\$temp" =~ F*) then
    	set input = mtzf
    	set ref_set = "\\\$temp[2]" 
    endif
    if("\\\$temp" =~ *FreeR_flag) then
    	set ref_free = "\\\$temp[2]" 
    endif
    if("\\\$temp" =~ Q*) then
    	set ref_sig = "\\\$temp[2]" 
    endif
end
if(! \\\$?ref_set) then
    set temp = \\\`nawk '\\\$1=="J" || \\\$1=="F"{printf "%s ", \\\$0;getline;print \\\$NF}' \\\${tempfile}.labels | tail -1\\\`
    if("\\\$temp" =~ J*) then
    	set input = mtzi
    	set ref_set = "\\\$temp[2]" 
    endif
    if("\\\$temp" =~ F*) then
    	set input = mtzf
    	set ref_set = "\\\$temp[2]" 
    endif
    if(! \\\$?ref_set) then
	echo "ERROR: no data in \\\$reffile"
	rm -f \\\${tempfile}labels >& /dev/null
	exit 9
    endif
endif
# set up the sigma (if not aready done)
if(! \\\$?ref_sig) then
    set ref_sig = \\\`nawk -v set=\\\$ref_set '\\\$1=="Q"{Q=\\\$NF; if(nextq) exit} \\\$NF==set{nextq=1} END{print Q}' \\\${tempfile}.labels\\\`
endif
# use the FreeR flag (if it's there)
if(! \\\$?ref_free) then
    set temp = \\\`nawk 'tolower(\\\$NF) ~ /^freer/{print \\\$NF}' \\\${tempfile}.labels\\\`
    if("\\\$temp" != "") set ref_free = \\\$temp
endif
# set up rotaprep variables
if("\\\$input" == "mtzi") then
    set labin = "I=\\\$ref_set SIGI=\\\$ref_sig"
endif
if("\\\$input" == "mtzf") then
    set labin = "F=\\\$ref_set SIGF=\\\$ref_sig"
endif

echo "using \\\$ref_set \\\$ref_sig as the reference dataset"
if(\\\$?ref_free) then
    echo "(excluding free-R flagged hkls)"
endif

rm -f \\\${tempfile}.labels >& /dev/null

goto Return_from_Setup

EOF-script


chmod a+x \$SCRIPT






















# landing point to regenerate scaling scripts
Scaling_Scripts:


RefScaleScript:
###############################################################################

 #####   ######  ######           ####   ######   #####
 #    #  #       #               #       #          #
 #    #  #####   #####            ####   #####      #
 #####   #       #                    #  #          #
 #   #   #       #               #    #  #          #
 #    #  ######  #                ####   ######     #

###############################################################################
#
#	scale and merge reference set
#
###############################################################################
set SCRIPT = \${SCRIPT_dir}/make_reference_set.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

# set up the scaling card
set scale_card = "batch"
if("\$SCALING" == "smooth") set scale_card = "rotation spacing \$SPACING"
if("\$BFACTOR" == "smooth") then
    set scale_card = "\$scale_card brotation spacing \$SPACING"
else
    set scale_card = "\$scale_card bfactor on"
endif
set outputfile = \${refMTZ}
# don't overwrite a user-specified mtz file!
if(\$?USER_REFERENCE) set outputfile = mtz/reference.mtz

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#   Reference set (\$wave_reference) scaling, sorting, remergeing script by Scaler Elves
#
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set infile   = \${rawMTZ}
set outfile  = \${outputfile}
#
set tempfile = \${tempfile}make_ref
#
############################################################################
# now scan command line
foreach arg ( \\\$* )
    # specific input file
    if((\\\$arg =~ *.mtz)&&(-e \\\$arg)) then
	if(\\\$arg =~ *.mtz) set infile = "\\\$arg"
    endif
end
#
############################################################################
# first, pre-scale reference wavelength data
#
##########################################################################
scala hklin \\\$infile  hklout \\\$outfile \\
  scales   \\\${tempfile}scales \\
  rogues   \\\${tempfile}rogues \\
  normplot \\\${tempfile}norm   \\
  anomplot \\\${tempfile}anom << eof_scaleref
# save disk space
#NODUMP
#ANALYSE NOPLOT
# make sure scala doesnt do anyhting stupid like change the output filename
DNAME ref
PNAME ref

# resolution range
RESOLUTION \$hiRES \$loRES

EOF-script

# add runs for the reference set
cat \$RUNFILE |\\
 nawk -v wave=\$wave_reference '\$2=="wavelength"{p=0} \\
         \$0 ~ " " wave " " || wave=="all"{p=1} p{print}' |\\
cat >> \$SCRIPT

# plus the "universal" rules
echo "# global SCALA cards" >> \$SCRIPT
cat \$RULESFILE >> \$SCRIPT

cat << EOF-script >> \$SCRIPT

# one scale and one B-factor per frame
#scales batch bfactor on
# Elves choice
scales \$scale_card
# 30 scaling iterations, or convergence, whichever comes first
cycles 30 converge 0.1
# eigenvalue filter, if convergence is oscillating
#filter 1.0e-6 0.01

# no need for anomalous diffs in reference set
anomalous off

eof_scaleref
if(\\\$status) set BAD

# clean up
rm -f \\\${tempfile}scales
rm -f \\\${tempfile}norm
rm -f \\\${tempfile}anom
rm -f \\\${tempfile}rogues

rm -f \\\${tempfile}prep.mtz
rm -f \\\${tempfile}ref.mtz


##########################################################################
if((-e \\\$outfile)&&(! \\\$?BAD)) then
    echo "\\\$outfile now contains a merged data set of \${wave_reference} "
else
    echo "scaling failed!  See above for why."
    exit 9
endif
##########################################################################

EOF-script


chmod a+x \$SCRIPT
























RoughScale:
###############################################################################

 #####    ####   #    #   ####   #    #           ####    ####     ##    #       ######
 #    #  #    #  #    #  #    #  #    #          #       #    #   #  #   #       #
 #    #  #    #  #    #  #       ######           ####   #       #    #  #       #####
 #####   #    #  #    #  #  ###  #    #               #  #       ######  #       #
 #   #   #    #  #    #  #    #  #    #          #    #  #    #  #    #  #       #
 #    #   ####    ####    ####   #    #           ####    ####   #    #  ######  ######

###############################################################################
#
#	unified script scaling of ALL data (in both rough and smooth mode)
#
###############################################################################
set SCRIPT = \${SCRIPT_dir}/rough_scale.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

# set up the scaling card
set scale_card = "batch"
if("\$SCALING" == "smooth") set scale_card = "rotation spacing \$SPACING"
if("\$BFACTOR" == "smooth") then
    set scale_card = "\$scale_card brotation spacing \$SPACING"
else
    set scale_card = "\$scale_card bfactor on"
endif
set useref = ""
if(\$?NO_REFERENCE) set useref = "#"

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Automatically generated multiwavelength SCALA script 
#  for rough (frame-wise) scaling of \$wavenames together
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set infile   = \${sortMTZ}
set outfile  = \${rscaleMTZ}
set runfile  = \$RUNFILE
#
set tempfile = \${tempfile}rough
#
# Defaults
set SPACING = \$SPACING
set CYCLES  = \$CYCLES
set FILTER  = "#"
#
# read command-line arguments
goto Setup
############################
#
# usage: \$SCRIPT [cycles] spacing [spacing] filter
#    eg: \$SCRIPT 50 spacing \$SPACING filter
#         means 50 cycles, \${SPACING}-degree smoothing window and use the filter
#
############################
ReturnFromSetup:
######################################################################
#
# Now run SCALA
#
######################################################################
rm -f \\\${tempfile}temp.mtz >& /dev/null
scala hklin \\\$infile  hklout \\\${tempfile}temp.mtz \\
  scales   \\\${tempfile}scales \\
  rogues   badspots.txt       \\
  normplot \\\${tempfile}norm   \\
  anomplot \\\${tempfile}anom  << EOF-scale
# save disk space
#NODUMP
#ANALYSE NOPLOT

title "\$TITLE"

# resolution range
RESOLUTION \$hiRES \$loRES

# reference data set (\$wave_reference) is NOT merged
\${useref}run 999 batch \$ref_batch reference

@\\\$runfile

# global SCALA cards
\`cat \$RULESFILE\`

#### treatment of partials ###### default, scale fulls only
#intensities partials		# use summed partials as fulls in scaling
#intensities scale_partials 0.8	# use extrapolated partials (by their fraction recorded) as fulls in scaling

#### type of scaling to be done ##########
#intensities anomalous                                    # scale I+ and I- as separate data sets
#scales batch bfactor off                                # one scale per frame
#scales batch bfactor on                                 # one scale and one B-factor per frame
#scales batch brotation spacing 10 bfactor on            # same, but B-factor smoothed over 10-degree window
#scales batch brotation spacing 10 bfactor anisotropic   # same, but anisotropic B-factor
#scales rotation spacing 10 bfactor on                   # scales smoothed over 10-degree window, B-factors follow SAME rule
#scales rotation spacing 10 detector 3 3                 # no B-factors, 9, smooth detector scales instead
#scales rotation spacing 10 secondary                    # spherical harmonics instead of B-factors
scales \$scale_card	 # Scaler Elves's opinion

# perhaps tie these down to prevent wild swings in scaling? 
#tie rotation 0.2
#tie detector 0.2

cycles \\\$CYCLES converge 0.1	# need not converge completely
\\\${FILTER}filter 1.0e-4 0.01	# if convergence is oscillating

#reject byrun			# don't reject spots on comparison between wavelengths

# print out statistics for I+/I- instead of Imean
anomalous

# do not merge (yet)
output separate reference

EOF-scale
######################################################################
if(\\\$status) then
    echo "SCALA has crashed."
    
    # check to see if, perhaps, the mtz was produced anyway
    echo "go" | mtzdump hklin \\\${tempfile}temp.mtz >& /dev/null
    if(\\\$status) then
	# file was no good
	rm -f \\\${tempfile}temp.mtz >& /dev/null
    endif
    if(-e \\\${tempfile}temp.mtz) then
	echo "but seems to have produced the output file with its last breath..."
	echo "YOU SHOULD MAKE SURE IT'S STILL OKAY! "
    endif
endif
if(! -e \\\${tempfile}temp.mtz) then
    echo "This usually happens when you have bad frames, or too many degrees "
    echo "of freedom in your run."
    echo "Try eliminating bad frames, (look at them! ), or increasing the "
    echo "spacing of B factor smoothing, or turning off Bs and, especially, "
    echo "getting rid of things like anisotropic Bs"
    echo "Good luck! "
    echo ""
    # premature exit, allow user to see intermediate files
    exit 9
else
    # move file upon successful completion
    sortmtz hklout \\\$outfile << EOF
\${USE_VRSET}VRSET -9E+38
H K L M/ISYM BATCH I SIGI
\\\${tempfile}temp.mtz
EOF
    rm -f \\\${tempfile}temp.mtz  >& /dev/null
endif

# clean up after scala
rm -f \\\${tempfile}scales        >& /dev/null
rm -f \\\${tempfile}norm	        >& /dev/null
rm -f \\\${tempfile}anom	        >& /dev/null

exit

##############################################################################
Setup:
# process command-line arguments
set i = 1
while ( \\\$i <= \\\$#argv )
    # define the input file
    if(("\\\$argv[\\\$i]" =~ *.mtz)&&(-e "\\\$argv[\\\$i]")) then
	set infile = "\\\$argv[\\\$i]"
    else
    
	# may override default spacing
	if("\\\$argv[\\\$i]" =~ spac*) then
	    @ i = ( \\\$i + 1)
	    if("\\\$argv[\\\$i]" =~ [1-9]*) set SPACING = "\\\$argv[\\\$i]"
	endif
    
	# may override default filtering
	if("\\\$argv[\\\$i]" == "filter") then
	    set FILTER = ""
	endif
    
	# raw numbers become cycle counts
	if(("\\\$argv[\\\$i]" =~ [1-9]*)&&("\\\$argv[\\\$i]" =~ *[0-9])) then
	    set CYCLES = "\\\$argv[\\\$i]"
	endif
    endif
    
    @ i = ( \\\$i + 1)
end
#
# Run List passed down from Scaler Elves
if(! -e "\\\$runfile" ) then
    # generate file containing list of scala runs
    cat << EOF-runs >! \\\$runfile
EOF-script
cat \$RUNFILE >> \$SCRIPT
cat << EOF-script >> \$SCRIPT
EOF-runs
endif

goto ReturnFromSetup

EOF-script
chmod a+x \$SCRIPT



























LocalScale:
###############################################################################

 #        ####    ####     ##    #        ####    ####     ##    #       ######
 #       #    #  #    #   #  #   #       #       #    #   #  #   #       #
 #       #    #  #       #    #  #        ####   #       #    #  #       #####
 #       #    #  #       ######  #            #  #       ######  #       #
 #       #    #  #    #  #    #  #       #    #  #    #  #    #  #       #
 ######   ####    ####   #    #  ######   ####    ####   #    #  ######  ######

###############################################################################
#
#	script for local-scaling of MAD data
#
###############################################################################
set SCRIPT = \${SCRIPT_dir}/localscale.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

# the scaling card doesn't change here

set useref = ""
if(\$?NO_REFERENCE) set useref = "#"

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Automatically generated multiwavelength SCALA script 
#  for local-scaling of \$wavenames together
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set infile   = \${rscaleMTZ}
set outfile  = \${lscaleMTZ}
set runfile  = \$RUNFILE
#
set tempfile = \${tempfile}lscale
#
# Defaults
set SPACING = \$SPACING
set CYCLES  = \$CYCLES
set FILTER  = "#"
#
# read command-line arguments
goto Setup
############################
#
# usage: \$SCRIPT [cycles] spacing [spacing] filter
#    eg: \$SCRIPT 50 spacing \$SPACING filter
#         means 50 cycles, \${SPACING}-degree smoothing window and use the filter
#
############################
ReturnFromSetup:
######################################################################
#
# make SURE the mtz is sorted
#
######################################################################
rm -f \\\${tempfile}temp.mtz >& /dev/null
sortmtz HKLOUT \\\${tempfile}in.mtz << EOF
\${USE_VRSET}VRSET -9E+38
H K L M/ISYM BATCH I SIGI
\\\$infile
EOF

######################################################################
#
# Now run SCALA
#
######################################################################
rm -f \\\${tempfile}temp.mtz >& /dev/null
scala hklin \\\${tempfile}in.mtz  hklout \\\${tempfile}temp.mtz \\
  scales   \\\${tempfile}scales \\
  rogues   badspots.txt       \\
  normplot \\\${tempfile}norm   \\
  anomplot \\\${tempfile}anom  << EOF-scale
# save disk space
#NODUMP
#ANALYSE NOPLOT

title "\$TITLE"

# resolution range
RESOLUTION \$hiRES \$loRES

# reference data set (\$wave_reference) is NOT merged
\${useref}run 999 batch \$ref_batch reference

@\\\$runfile

# global SCALA cards
\`cat \$RULESFILE\`

#### treatment of partials ###### default, scale fulls only
#intensities partials		# use summed partials as fulls in scaling
#intensities scale_partials 0.8	# use extrapolated partials (by their fraction recorded) as fulls in scaling

#### type of scaling to be done ##########
#intensities anomalous                                    # scale I+ and I- as separate data sets
#scales batch bfactor off                                # one scale per frame
#scales batch bfactor on                                 # one scale and one B-factor per frame
#scales batch brotation spacing 10 bfactor on            # same, but B-factor smoothed over 10-degree window
#scales batch brotation spacing 10 bfactor anisotropic   # same, but anisotropic B-factor
#scales rotation spacing 10 bfactor on                   # scales smoothed over 10-degree window, B-factors follow SAME rule
#scales rotation spacing 10 detector 3 3                 # no B-factors, 9, smooth detector scales instead
#scales rotation spacing 10 secondary                    # spherical harmonics instead of detector scales and B-factors
scales rotation spacing \\\$SPACING secondary               # Scaler Elves's opinion

# perhaps tie these down to prevent wild swings in scaling? 
#tie rotation 0.1
#tie detector 0.1
tie surface 0.001

cycles \\\$CYCLES converge 0.01	# need to converge completely
\\\${FILTER}filter 1.0e-4 0.01	# if convergence is oscillating

#reject byrun			# don't reject spots on comparison between runs

# print out statistics for I+/I- instead of Imean
anomalous

# do not merge (yet), but get rid of reference dataset
output separate


EOF-scale
######################################################################
if(\\\$status) then
    echo "SCALA has crashed."
    
    # check to see if, perhaps, the mtz was produced anyway
    echo "go" | mtzdump hklin \\\${tempfile}temp.mtz >& /dev/null
    if(\\\$status) then
	# file was no good
	rm -f \\\${tempfile}temp.mtz >& /dev/null
    endif
    if(-e \\\${tempfile}temp.mtz) then
	echo "but seems to have produced the output file with its last breath..."
	echo "YOU SHOULD MAKE SURE IT'S STILL OKAY! "
    endif
endif
if(! -e \\\${tempfile}temp.mtz) then
    echo "This usually happens when you have too many degrees of freedom in your run."
    echo "Try increasing the spacing of the smooth scales."
    echo "or decreasing the values in the tie cards."
    echo "Good luck! "
    echo ""
    # premature exit, allow user to see intermediate files
    exit 9
else
    # move file upon successful completion
    sortmtz hklout \\\$outfile << EOF
\${USE_VRSET}VRSET -9E+38
H K L M/ISYM BATCH I SIGI
\\\${tempfile}temp.mtz
EOF
    rm -f \\\${tempfile}temp.mtz  >& /dev/null
endif

# clean up after scala
rm -f \\\${tempfile}in.mtz        >& /dev/null
rm -f \\\${tempfile}scales        >& /dev/null
rm -f \\\${tempfile}norm	        >& /dev/null
rm -f \\\${tempfile}anom	        >& /dev/null

exit

##############################################################################
Setup:
# process command-line arguments
set i = 1
while ( \\\$i <= \\\$#argv )
    # define the input file
    if(("\\\$argv[\\\$i]" =~ *.mtz)&&(-e "\\\$argv[\\\$i]")) then
	set infile = "\\\$argv[\\\$i]"
    else
    
	# may override default spacing
	if("\\\$argv[\\\$i]" =~ spac*) then
	    @ i = ( \\\$i + 1)
	    if("\\\$argv[\\\$i]" =~ [1-9]*) set SPACING = "\\\$argv[\\\$i]"
	endif
    
	# may override default filtering
	if("\\\$argv[\\\$i]" == "filter") then
	    set FILTER = ""
	endif
    
	# raw numbers become cycle counts
	if(("\\\$argv[\\\$i]" =~ [1-9]*)&&("\\\$argv[\\\$i]" =~ *[0-9])) then
	    set CYCLES = "\\\$argv[\\\$i]"
	endif
    endif
    
    @ i = ( \\\$i + 1)
end
#
# Run List passed down from Scaler Elves
if(! -e "\\\$runfile" ) then
    # generate file containing list of scala runs
    cat << EOF-runs >! \\\$runfile
EOF-script
cat \$RUNFILE >> \$SCRIPT
cat << EOF-script >> \$SCRIPT
EOF-runs
endif

goto ReturnFromSetup

EOF-script
chmod a+x \$SCRIPT

















###############################################################################

 #####    ####    ####    #####  #####   ######  ######
 #    #  #    #  #          #    #    #  #       #
 #    #  #    #   ####      #    #    #  #####   #####
 #####   #    #       #     #    #####   #       #
 #       #    #  #    #     #    #   #   #       #
 #        ####    ####      #    #    #  ######  #

###############################################################################
#
#	script for postrefinement (unsupported)
#
###############################################################################
set SCRIPT = \${SCRIPT_dir}/postref.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#   Prototype postref script
#
#
#	Takes standard unmerged SCALA output (using OUTPUT SEPARATE), 
#	reformats it for POSTREF, and postrefines each frame against
#	the overall, merged data set.
#	the results are output as a file suitable for reinput into
#	scala for mergeing (NOT scaling).
#
#	Caveats:
#	- The SDCORR option given below should match that used in the
#	  SCALA run.
#
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
############################################################################
#
set infile   = ./mtz/localscaled.mtz
set outfile  = ./mtz/postrefined.mtz
#
set tempfile = \${tempfile}postref_temp.
#
############################################################################
# now scan command line
foreach arg ( \\\$* )
    # specific input file
    if(-e "\\\$arg") then
	if(\\\$arg =~ *.mtz) then
	    set infile = "\\\$arg"
	endif
    endif
end
#
set MOSAICITY


Reformat:
############################################################################
# use scala to reformat data for postref
#
############################################################################
scala hklin \\\$infile  hklout \\\${tempfile}reformatted.mtz \\\\
  scales   \\\${tempfile}scales \\\\
  rogues   badspots.txt       \\\\
  normplot \\\${tempfile}norm   \\\\
  anomplot \\\${tempfile}anom  << EOF-reformat
# global SCALA cards
\`cat \$RULESFILE\`

anomalous
initial none
noscale
cycles 0
output postref
#final none
EOF-reformat
rm -f \\\${tempfile}scales >& /dev/null
rm -f \\\${tempfile}anom >& /dev/null
rm -f \\\${tempfile}norm >& /dev/null

PreSort:
############################################################################
# re-sort scaled data for postref
#
############################################################################
sortmtz HKLOUT \\\${tempfile}sorted.mtz << EOF-sort
\${USE_VRSET}VRSET -9E+38
BATCH H K L M/ISYM
\\\${tempfile}reformatted.mtz 
EOF-sort
rm -f \\\${tempfile}reformatted.mtz >& /dev/null

Rename:
# rename data to protect them from postref
# and use the sigma-corrected intensities
mtzutils hklin \\\${tempfile}sorted.mtz hklout \\\${tempfile}postrefme.mtz << EOF-utils
# postref changes ROT to range -180 to 180, which SCALA will not accept
#COLUMN_LABELS oldROT=ROT
# use SCALA's corrected sigmas
COLUMN_LABELS oldSIGI=SIGI oldSIGIPR=SIGIPR
COLUMN_LABELS SIGI=SIGIC   SIGIPR=SIGIPRC
EOF-utils
# bypass this? use SDFAC below? 
#mv \\\${tempfile}sorted.mtz \\\${tempfile}postrefme.mtz 
rm -f \\\${tempfile}sorted.mtz >& /dev/null


############################################################################
# examine file for lack of mosaicity (denzo data)
############################################################################
echo "BATCH" | mtzdump HKLIN \\\${tempfile}postrefme.mtz |\\\\
nawk '\\\$1 == "Mosaicity" {print \\\$NF; if(\\\$NF+0 == 0) badmos=1} \\\\
 badmos && /Phi angles/ {print \\\$NF - \\\$(NF-1)}' |\\\\
nawk '{sum += \\\$1;++n} END{if(n && badmos) print "MOSAICITY" sum/n}' |\\\\
cat >! \\\${tempfile}mos
# set mosaicity to osc/2 if no mosaicity given
set MOSAICITY = \\\`cat \\\${tempfile}mos\\\`
rm -f \\\${tempfile}mos

Postref:
############################################################################
# now do postrefining
#
############################################################################
postref SUMMARY \\\${tempfile}summary \\\\
          HKLIN \\\${tempfile}postrefme.mtz \\\\
          HKLOUT \\\${tempfile}postrefed.mtz  << eof_postref

TITLE postreffing \\\${infile}

# no need for SDFAC if we use SIGIC
#\`nawk '/SDCORR/{print \\\$1,\\\$2,\\\$NF}' \$RULESFILE\`
#BEAM 0 0  0.0001 0
\\\$MOSAICITY

# make sure this converges
REFINE NCYC 100 CONVRG 0.02
# default values for "REJECT" card:
REJECT 1000  -3 -3  0.5 3 0.0 0.0 10 

# refine all batches, individually, against the merged data
BATCH ALL
#CRYSTAL 1 to 77

OUTPUT ALL

END
eof_postref
rm -f \\\${tempfile}postrefme.mtz

# reformat output MTZ for input into SCALA again
mtzutils hklin \\\${tempfile}postrefed.mtz hklout \\\${tempfile}sortme.mtz << EOF-utils
# strip off incomplete line (will crash next postref run)
#EXCLUDE SIGSCALE SIGFRACTIONCALC IMEAN SIGIMEAN ISUM SIGISUM
# scala will crash if ROT is changed
#COLUMN_LABELS ROT=oldROT
# rename sigmas back to original values
COLUMN_LABELS SIGIC=SIGI   SIGIPRC=SIGIPR
COLUMN_LABELS SIGI=oldSIGI SIGIPR=oldSIGIPR
EOF-utils
#mv \\\${tempfile}postrefed.mtz \\\${tempfile}sortme.mtz >& /dev/null
rm -f \\\${tempfile}postrefed.mtz >& /dev/null

# re-sort for scala
sortmtz HKLOUT \\\${outfile} << EOF-sort
\${USE_VRSET}VRSET -9e+38
H K L M/ISYM BATCH I SIGI
\\\${tempfile}sortme.mtz
EOF-sort
# clean up
rm -f \\\${tempfile}sortme.mtz




# do xloggraph version of summary
cat << EOF-export >! \\\${tempfile}awkscript
#! /bin/nawk -f
#
#	Sumarize postref summary file in xloggraph format
#
#

# only read number-only lines
! /[a-z]/ && NF>1 {
    ++n; 
    
    # remember actual batch number
    batch[n] = \\\\\\\$1;
    
    # get cell parameters
    a[n]=\\\\\\\$2; a["avg"]+=a[n];
    b[n]=\\\\\\\$3; b["avg"]+=b[n]; 
    c[n]=\\\\\\\$4; c["avg"]+=c[n];
    A[n]=\\\\\\\$5; A["avg"]+=A[n];
    B[n]=\\\\\\\$6; B["avg"]+=B[n];
    G[n]=\\\\\\\$7; G["avg"]+=G[n];

    # get crystal orientation shifts
    phiX[n]= \\\\\\\$9; phiX["avg"] += phiX[n];
    phiY[n]=\\\\\\\$10; phiY["avg"] += phiY[n];
    phiZ[n]=\\\\\\\$11; phiZ["avg"] += phiZ[n];

    DphiX[n] = \\\\\\\$9-\\\\\\\$12;
    DphiY[n] = \\\\\\\$10-\\\\\\\$13;
    DphiZ[n] = \\\\\\\$11-\\\\\\\$14;
    
    # get mosaicity
    mos[n] = \\\\\\\$15; mos["avg"]+=mos[n];
    if(mos["max"] < mos[n]) mos["max"] = mos[n]
}

END{
    compute average values
    if(n)
    {
	a["avg"]=a["avg"]/n;
	b["avg"]=b["avg"]/n; 
	c["avg"]=c["avg"]/n;
	A["avg"]=A["avg"]/n;
	B["avg"]=B["avg"]/n;
	G["avg"]=G["avg"]/n;
    
	mos["avg"]=mos["avg"]/n;
    
	# print xloggraph plot header
	print " \\\\\\\$TABLE : - Elven Postref Plots:"
	print " \\\\\\\$GRAPHS:Unit Cell (deviations from mean):A:1, 3, 4, 5, 6, 7, 8:"
	print "        :Crystal Orientation (change during refinement):A:1, 9, 10, 11:"
	print "        :Crystal Slippage (orientation change during exposure):A:1, 12, 13, 14:"
	printf "        :Crystal Mosaicity (mean=%.3f max=%.3f):A:1, 15:\\\\\\\\n", mos["avg"], mos["max"]
	print " \\\\\\\$\\\\\\\$"
	print " frame batch A B C alpha beta gamma phiX phiY phiZ delta_phiX delta_phiY delta_phiZ mosaicity \\\\\\\$\\\\\\\$"
	print " \\\\\\\$\\\\\\\$"
    
	# compute deviates of the cell
	for(i=1;i<=n;++i)
	{
	    # compute deviates of the cell
	    a[i]-=a["avg"];
	    b[i]-=b["avg"]; 
	    c[i]-=c["avg"];
	    A[i]-=A["avg"];
	    B[i]-=B["avg"];
	    G[i]-=G["avg"];
	    
	    # print out interesting numbers as graphs
	    printf("%4d %6d %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f   %7.2f %7.2f %7.2f   %7.2f %7.2f %7.2f   %7.3f\\\\\\\\n", \\\\\\\\
	    i, batch[i], a[i], b[i], c[i], A[i], B[i], G[i], \\\\\\\\
	    phiX[i], phiY[i], phiZ[i], DphiX[i], DphiY[i], DphiZ[i], mos[i]);
	}

	print "\\\\\\\$\\\\\\\$"
	
	printf "Average cell is  : %.2f %.2f %.2f %.2f %.2f %.2f\\\\\\\\n", a["avg"],  b["avg"],  c["avg"],  A["avg"],  B["avg"],  G["avg"];
	printf "Average mosaicity: %.3f\\\\\\\\n", mos["avg"];
	printf "Maximum mosaicity: %.3f\\\\\\\\n", mos["max"];
    }    
}
EOF-export

# dump results to stdout
nawk -f \\\${tempfile}awkscript  \\\${tempfile}summary

# finish cleaning up
rm -f \\\${tempfile}awkscript 
rm -f \\\${tempfile}summary

##########################################################################
if(-e \\\$outfile) then
    echo "\\\$outfile now contains a postrefined version of \\\$infile "
endif
##########################################################################

exit

EOF-script
chmod a+x \$SCRIPT


















Merger:
############################################################################

 #    #  ######  #####    ####   ######  #####
 ##  ##  #       #    #  #    #  #       #    #
 # ## #  #####   #    #  #       #####   #    #
 #    #  #       #####   #  ###  #       #####
 #    #  #       #   #   #    #  #       #   #
 #    #  ######  #    #   ####   ######  #    #

############################################################################
#
# Generate script for mergeing each wavelength from final scaling file
#
############################################################################
set SCRIPT = \${SCRIPT_dir}/merge.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Automatically generated script 
#  for mergeing one or all of \$wavenames
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set infile   = \${lscaleMTZ}
set outfile  = merged.mtz
set runfile  = \$RUNFILE
#
set tempfile = \${tempfile}merge
#
# Default to mergeing ALL data together (useful? )
if(! \\\$?wave) set wave     = "all"
set hires    = \$hiRES
#
# read command-line arguments
goto Setup
############################
#
# usage: \$SCRIPT [wavename] [high_RES] [SG]
#    eg: \$SCRIPT \$wave_reference \$hiRES \$SG
#        means merge frames from \$wave_reference to \$hiRES A, in \$SG
#
############################
ReturnFromSetup:
######################################################################
#
# Now run SCALA (to merge, not scale data)
#
######################################################################
rm -f \\\${tempfile}merged.mtz >& /dev/null
scala hklin \\\$infile  hklout \\\${tempfile}merged.mtz \\
  scales   \\\${tempfile}scales \\
  rogues   badspots.\\\$wave.txt     \\
  normplot \\\${tempfile}norm \\
  anomplot \\\${tempfile}anom  << EOF-scale
# save disk space
#NODUMP
#ANALYSE NOPLOT
# make sure scala doesnt do anyhting stupid like change the output filename
DNAME \\\$wave
PNAME \\\$wave

title "merged \\\$wave from \$TITLE"

# resolution range
RESOLUTION \\\$hires \$loRES

@\\\${tempfile}runlist

# global SCALA cards
\`cat \$RULESFILE\`

# treatment of partials	    # default, sum partials, and use result in analysis
#final fulls		    # use fulls only in analysis
#final scale_partials 0.5   # treat partials with fraction recorded > 0.5 as fulls in mergeing

onlymerge
noscale			    # should apply old scales!
#scales batch bfactor off

# print out statistics for I+/I- instead of Imean
# changing this to "off" will NOT affect output Imean
anomalous on

EOF-scale
##############################################################################
if(\\\$status) then
    echo "SCALA crashed! "
    # check to see if file was produced anyway
    echo "go" | mtzdump hklin \\\${tempfile}merged.mtz >& /dev/null
    if(\\\$status) then
	# file was no good
	rm -f \\\${tempfile}merged.mtz >& /dev/null
	set BAD
    else
	echo "...but seems to have produced the output data file before it did."
	echo "YOU SHOULD CHECK AND SEE IF THIS IS OKAY!!! "
    endif
endif

# clean up after scala
rm -f \\\${tempfile}runlist       >& /dev/null
rm -f \\\${tempfile}scales        >& /dev/null
rm -f \\\${tempfile}norm	        >& /dev/null
rm -f \\\${tempfile}anom	        >& /dev/null

truncate:
##############################################################################
# run truncate to make "F"s from "I"s
#
##############################################################################
truncate hklin \\\${tempfile}merged.mtz \\
        hklout \\\${outfile} << EOF-trunc | tee \\\${tempfile}temp.log

title "merged \\\$wave from \$TITLE"

# overall resolution range 
RESOLUTION \\\$hires \$loRES
# resolution used to determine B factor
#rscale 4 2.8
#ranges 0.01

# needed to determine absolute scale
nresidue \$NRES

# roll-off negative intensities with French-Wilson procedure
truncate yes
# changing this to "no" will NOT affect output Fs
anomalous yes
LABOUT  F=F  SIGF=SIGF DANO=DANO SIGDANO=SIGDANO ISYM=ISYM
EOF-trunc
##############################################################################
if(\\\$status) then
    # see if this is a fixable problem
    grep "Data beyond useful resolution limit" \\\${tempfile}temp.log >& /dev/null
    if(\\\$status) then
	# nope
	set BAD
    else
	# we know how to fix this (and there is no reason not to)
	cat \\\${tempfile}temp.log | nawk '/Wilson Plot/,/TRUNCATE/' |\\\\
        nawk 'NF==10 && ! /[a-z]/{print \\\$6}' |\\\\
        tail -1 >! \\\${tempfile}res
        set hires = \\\`cat \\\${tempfile}res\\\`
        rm -f \\\${tempfile}res
	
        if("\\\$hires" == "") then
            set hires = \\\`awk '/Negative or zero mean I/ && \\\$NF+0>0.1{print \\\$NF+0}' \\\${tempfile}temp.log | tail -1\\\`
        endif

	# go back, and try this again
	if("\\\$hires" != "") then
	    set newRES = "\\\$hires"
	    # prevent infinite loops if truncate is messed up
	    if(! \\\$?retries) set retries = 0
	    @ retries = ( \\\$retries + 1 )
	    if(\\\$retries <= 5) then
	        goto truncate
	    endif
	    set BAD
	endif
	set BAD
    endif
endif

# delete intermediate files
rm -f \\\${tempfile}merged.mtz	>& /dev/null
rm -f \\\${tempfile}temp.log	>& /dev/null
rm -f \\\${tempfile}reindexed.mtz >& /dev/null

##############################################################################
if(! \\\$?BAD) then
    if(\\\$?newRES) echo "WARNING: output resolution reduced to \\\$hires A"
    echo "merged \\\$wave data is in \\\${outfile}"
else
    echo "mergeing failed!  See above for why."
    exit 9
endif

exit

##############################################################################
Setup:
#
# Run List passed down from Scaler Elves
if(! -e "\\\$runfile" ) then
    # generate file containing list of scala runs
    cat << EOF-runs >! \\\$runfile
EOF-script
cat \$RUNFILE >> \$SCRIPT
cat << EOF-script >> \$SCRIPT
EOF-runs
endif
#
# process command-line arguments
set newSG = ""
set axes  = ""
foreach arg ( \\\$* )
    # define the input file
    if(("\\\$arg" =~ *.mtz)&&(-e "\\\$arg")) then
	set infile = "\\\$arg"
    else
    
	# look for wavelength name
	set temp = \\\`grep "wavelength" \\\$runfile | grep " \\\$arg " \\\`
	if("\\\$temp" != "") then
	    # must be the wavelength user wants
	    set wave = "\\\$arg"
	else
	
	    # look for new resolution limit
	    set temp = \\\`echo "\\\$arg" | nawk '\\\$1+0<10 && \\\$1+0>0.4 {print \\\$1+0}'\\\`
	    if("\\\$temp" != "") then
		# must be the resolution user wants
		set hires = "\\\$temp"
	    endif
	
	endif
    endif
    
    # check for new space group
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	# check for SGs listed in library (but not the screwy ones)
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	if(\\\$?CLIBD) then
	    set temp = \\\`nawk -v SG=\\\$temp '\\\$4 == SG && \\\$1 < 500 {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
	endif
	if("\\\$temp" != "") then
	    set newSG = "\\\$temp"
	endif
	
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	# check for orthorhombic "pseudo-spacegroup" language
	if("\\\$temp" == P2221) then
	    # P2221 with screw along longest axis
	    set axes  = "a b c"
	    set newSG = "P2221"
	    continue
	endif
	if("\\\$temp" == P2212) then
	    # P2221 with screw along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P2221"
	    continue
	endif
	if("\\\$temp" == P2122) then
	    # P2221 with screw along shortest axis
	    set axes  = "c a b"
	    set newSG = "P2221"
	    continue
	endif
	
	if("\\\$temp" == P21212) then
	    # P21212 with non-screw along longest axis
	    set axes  = "a b c"
	    set newSG = "P21212"
	    continue
	endif
	if("\\\$temp" == P21221) then
	    # P21212 with non-screw along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P21212"
	    continue
	endif
	if("\\\$temp" == P22121) then
	    # P21212 with non-screw along shotest axis
	    set axes  = "c a b"
	    set newSG = "P21212"
	    continue
	endif
	    
	if("\\\$temp" == C2221) then
	    # C2221 with screw along longest axis
	    set axes  = "a b c"
	    set newSG = "C2221"
	    continue
	endif
	# are these legal? 
	if("\\\$temp" == C2212) then
	    # C2221 with screw along mid-length axis
	    set axes  = "b c a"
	    set newSG = "C2221"
	    continue
	endif
	if("\\\$temp" == C2122) then
	    # C2221 with screw along shortest axis
	    set axes  = "c a b"
	    set newSG = "C2221"
	    continue
	endif
    endif
	
    # check for flipping of ambiguous axes
    if("\\\$arg" == "flip") then
	# user requested "flip" of axes
	set FLIP
	# this should work for all P4x, P3x, P6x
	set REINDEX = "reindex k, h, -l"
	set message = "with a and b axes flipped"
	
	# are there any others?
    endif
    
    # what about cubic? 
end
#
# decide on new axis ordering (for asymmetric orthorhombics)
#if("\\\$newSG" == "P222")    set axes = "a b c"
#if("\\\$newSG" == "P212121") set axes = "a b c"
if("\\\$axes" != "") then
    # get current axis ordering
    set CELL = \\\`echo "head" | mtzdump hklin \\\$infile | nawk '/Cell Dimensions/{getline;getline;print}'\\\`
    # find out what the cannonical one would be
    # then decide how to go from current ordering to the desired one
    echo "\\\$CELL" | nawk '{\\\\
	# print out current axis order \\\\
	print \\\$1, "h"; print \\\$2, "k"; print \\\$3, "l"}' |\\\\
    sort -n |\\\\
    nawk '\\\\
	# add cannonical axis names\\\\
	NR==1{print \\\$0, "a"} NR==2{print \\\$0, "b"} NR==3{print \\\$0, "c"}' |\\\\
    nawk -v axes="\\\$axes" 'BEGIN{split(axes, abc)} {\\\\
	# write desired axis ordering in front of cannonical one \\\\
	print abc[NR], \\\$0}' |\\\\
    sort |\\\\
    cat >! \\\${tempfile}order    
    set REINDEX = "reindex "\\\`nawk '{printf "%s", \\\$3} NR~/[12]/{print ","}'  \\\${tempfile}order\\\`

    # this should give us a mapping between any two orthorhombics
    
    set temp = \\\`tail -1 \\\${tempfile}order | nawk '{print \\\$NF}'\\\`
    rm -f \\\${tempfile}order
    if(("\\\$newSG" == "P2221")||("\\\$newSG" == "C2221")) then
	set message = " with screw along \\\$temp axis"
    endif
    if("\\\$newSG" == "P21212") then
	set message = " with non-screw along \\\$temp axis"
    endif
endif

if((! \\\$?REINDEX) && ("\\\$newSG" != "")) set REINDEX

if(\\\$?REINDEX) then
    if("\\\$newSG" != "") set newSG = "SYMM \\\$newSG"

    # reindex the input file to the new space group
    reindex HKLIN \\\$infile HKLOUT \\\${tempfile}sortme.mtz << EOF-reindex
\\\$newSG
\\\$REINDEX
EOF-reindex
    
    # sort it too, for good measure
    sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\${tempfile}reindexed.mtz << EOF
\${USE_VRSET}VRSET -9e+38
H K L M/ISYM BATCH I SIGI
EOF
    
    rm -f  \\\${tempfile}sortme.mtz
    # scale and merge this file
    set infile = \\\${tempfile}reindexed.mtz
endif
#
# Extract runs for the desired wavelength
cat \\\$runfile |\\
nawk -v wave="\\\$wave" '\\\$2=="wavelength"{p=0} \\\$0 ~ " " wave " "{p=1} p{print}' |\\
cat >! \\\${tempfile}runlist
#
set temp = \\\`cat \\\${tempfile}runlist | wc -l\\\`
if(\\\$temp == 0) then
    # default to all runs
    cat \\\$runfile >! \\\${tempfile}runlist
endif

goto ReturnFromSetup

EOF-script
chmod a+x \$SCRIPT


























Extractor:
############################################################################

 ######  #    #   #####  #####     ##     ####    #####   ####   #####
 #        #  #      #    #    #   #  #   #    #     #    #    #  #    #
 #####     ##       #    #    #  #    #  #          #    #    #  #    #
 #         ##       #    #####   ######  #          #    #    #  #####
 #        #  #      #    #   #   #    #  #    #     #    #    #  #   #
 ######  #    #     #    #    #  #    #   ####      #     ####   #    #

############################################################################
#
# Generate script for extracting an unmerged wavelength from final scaling file
#
############################################################################
set SCRIPT = \${SCRIPT_dir}/extract.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Automatically generated script 
#  for extracting one of \$wavenames from an MTZ
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set infile   = \${lscaleMTZ}
set outfile  = unmerged.mtz
set runfile  = \$RUNFILE
#
set tempfile = \${tempfile}extract
#
# Default to all data (useful? )
if(! \\\$?wave) set wave     = "all"
set hires    = \$hiRES
#
# read command-line arguments
goto Setup
############################
#
# usage: \$SCRIPT [wavename] [high_RES]
#    eg: \$SCRIPT \$wave_reference \$hiRES
#        means extract frames from \$wave_reference to \$hiRES A
#
############################
ReturnFromSetup:
######################################################################
#
# Now run SCALA (to add partials, not scale data)
#
######################################################################
rm -f \\\${tempfile}unmerged.mtz >& /dev/null
scala hklin \\\$infile  hklout \\\${tempfile}unmerged.mtz \\
  scales   \\\${tempfile}scales \\
  rogues   \\\${tempfile}rogues \\
  normplot \\\${tempfile}norm   \\
  anomplot \\\${tempfile}anom  << EOF-scale
# save disk space
#NODUMP
#ANALYSE NOPLOT
DNAME \\\$wave
PNAME \\\$wave

title "unmerged \\\$wave from \$TITLE"

# resolution range
RESOLUTION \\\$hires \$loRES

@\\\${tempfile}runlist

# global SCALA cards
\`cat \$RULESFILE\`

# treatment of partials	    # default, sum partials, and use result in analysis
#final fulls		    # use fulls only in analysis
#final scale_partials 0.5   # treat partials with fraction recorded > 0.5 as fulls in mergeing

output unmerged original    # don't merge to ASU, but add partials
noscale			    # should apply old scales!
onlymerge
#scales batch

# changing this to "off" will NOT affect output Is
anomalous on

EOF-scale
##############################################################################
if(\\\$status) then
    echo "SCALA crashed! "
    # check to see if file was produced anyway
    echo "go" | mtzdump hklin \\\${tempfile}unmerged.mtz >& /dev/null
    if(\\\$status) then
	# file was no good
	rm -f \\\${tempfile}unmerged.mtz >& /dev/null
    else
	echo "...but seems to have produced the output data file before it did."
	echo "YOU SHOULD CHECK AND SEE IF THIS IS OKAY! "
    endif
endif

##############################################################################
# take existence of output file as signal of a sucessful run
if(-e \\\${tempfile}unmerged.mtz) then
    mv \\\${tempfile}unmerged.mtz \\\${outfile}
    echo "unmerged \\\$wave data is in \\\${outfile}"
else
    echo "extraction failed!  See above for why."
    exit 9
endif

# clean up after scala
rm -f \\\${tempfile}rogues        >& /dev/null
rm -f \\\${tempfile}runlist       >& /dev/null
rm -f \\\${tempfile}scales        >& /dev/null
rm -f \\\${tempfile}norm	        >& /dev/null
rm -f \\\${tempfile}anom	        >& /dev/null

exit

##############################################################################
Setup:
#
# Run List passed down from Scaler Elves
if(! -e "\\\$runfile" ) then
    # generate file containing list of scala runs
    cat << EOF-runs >! \\\$runfile
EOF-script
cat \$RUNFILE >> \$SCRIPT
cat << EOF-script >> \$SCRIPT
EOF-runs
endif
#
# process command-line arguments
foreach arg ( \\\$* )
    # define the input file
    if(("\\\$arg" =~ *.mtz)&&(-e "\\\$arg")) then
	set infile = "\\\$arg"
    else
    
	# look for wavelength name
	set temp = \\\`grep "wavelength" \\\$runfile | grep " \\\$arg " \\\`
	if("\\\$temp" != "") then
	    # must be the wavelength user wants
	    set wave = "\\\$arg"
	else
	
	    # look for new resolution limit
	    set temp = \\\`echo "\\\$arg" | nawk '\\\$1+0<10 && \\\$1+0>0.4 {print \\\$1+0}'\\\`
	    if("\\\$temp" != "") then
		# must be the resolution user wants
		set hires = "\\\$temp"
	    endif
	
	endif
    endif
end
#
# Extract runs for desired wavelength
cat \\\$runfile |\\
nawk -v wave="\\\$wave" '\\\$2=="wavelength"{p=0} \\\$0 ~ " " wave " "{p=1} p{print}' |\\
cat >! \\\${tempfile}runlist
#
set temp = \\\`cat \\\${tempfile}runlist | wc -l\\\`
if(\\\$temp == 0) then
    echo "WARNING: no wavelength specified for extraction. "
    echo "extracting all data"
    echo "usage: \\\$0 [\$wavenames] [2A]"
    echo ""
    echo "where:"
    echo "\$wavenames[1], etc.  is a wavelength name"
    echo "2A is the (optional) resolution cutoff"
    echo ""

    # default to all runs
    cat \\\$runfile >! \\\${tempfile}runlist
endif

goto ReturnFromSetup

EOF-script
chmod a+x \$SCRIPT


























ScaleitScript:
############################################################################

  ####    ####     ##    #       ######     #     #####
 #       #    #   #  #   #       #          #       #
  ####   #       #    #  #       #####      #       #
      #  #       ######  #       #          #       #
 #    #  #    #  #    #  #       #          #       #
  ####    ####   #    #  ######  ######     #       #

############################################################################
#
# Generate script for combining merged Fs into a single file
#
############################################################################
set SCRIPT = \${SCRIPT_dir}/scaleit.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Automatically generated scaleit script 
#  for combining \$wavenames into a single MTZ
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set outfile     = cadded.mtz
set scaledfile  = scaleited.mtz
#
set tempfile = \${tempfile}scaleit
#
#################################################
# use CAD to put all wavelengths side-by-side
EOF-script

cat << EOF-awk >! \${tempfile}.awk
#! \$nawk -f
#
#  make a com file for CADing an arbitrary number of items together
#  using the CCP4 program CAD
#
#
BEGIN{
    if(! dir) dir = "./mtz/"
}

{
    print "cad \\\\\\\\";

    for(word=1; word<=NF; ++word)
    {
	++n;
	printf "   HKLIN%d %s.mtz \\\\\\\\\\\\n", n, dir \\\$word;
	
	labin[n] = "LABIN  FILE " n " E1=F       E2=SIGF       E3=DANO        E4=SIGDANO        E5=ISYM\\\\n";
	labin[n] = labin[n] "CTYP   FILE " n " E1=F       E2=Q          E3=D           E4=Q              E5=Y\\\\n";
	labin[n] = labin[n] sprintf("LABOUT FILE %d E1=%-7s E2=SIG%-7s E3=DANO%-7s E4=SIGDANO%-7s E5=ISYM%s\\\\n", n, \\\$word, \\\$word, \\\$word, \\\$word, \\\$word);
	
	if((n == 9)||(word == NF))
	{
	    print "HKLOUT \\\${tempfile}cad.mtz << EOF-cad";
	    print ""
	    print "\\\\043 rename data after their original wavelength";
	    
	    for(i=1;i<=n;++i)
	    {
		print labin[i];
	    }
	    
	    print "END"
	    print ""
	    print "EOF-cad"
	    print "if(\\\$status) exit 1"
	    print ""
	    
	    if(word < NF)
	    {
		# not done yet, so set up reinput
		print ""
		print "mv \\\${tempfile}cad.mtz \\\${tempfile}cadin.mtz"
		print ""
		print "cad \\\\\\\\"
		
		n = 1;
		print "   HKLIN1 \\\${tempfile}cadin.mtz \\\\\\\\";
		
		labin[n] = "LABIN  FILE 1 ALL\\\\nCTYP   FILE 1 ALL\\\\nLABOUT FILE 1 ALL\\\\n"
	    }
	}
    }
}
EOF-awk

echo "\$wavenames" |\\
nawk -f \${tempfile}.awk >> \$SCRIPT
rm -f \${tempfile}.awk

cat << EOF-script >> \$SCRIPT


#################################################
# shouldn't need any more scaling, 
mv \\\${tempfile}cad.mtz \\\${outfile}

# but, Phil's example said to do scaleit.
EOF-script
foreach wave ( \$wavenames )
    echo 'if("\$1" == "'\$wave'") goto '\$wave  >> \$SCRIPT
end
cat << EOF-scriptbit >> \$SCRIPT
if("\\\$1" == "all") set DOALL

# default to scaling reference
if(! \\\$?DOALL) goto \$wave_reference

EOF-scriptbit

# make a scaleit run for each wave as a reference
foreach ref ( \$wavenames )

    cat << EOF-wave >> \$SCRIPT

\${ref}:
#################################################
# \$ref as reference
scaleit HKLIN \\\${outfile}  HKLOUT \\\$scaledfile << EOF-scaleit

TITLE Scale \$ref to rest.
RESO \$hiRES \$loRES		# Usually better to exclude lowest resolution data
WEIGHT			#   Sigmas should be reliable.
refine anisotropic	# use an anisotropic B-factor
#norefine		# don't change relative scale

EOF-wave

#    # scale ref against everything but ref
#    echo "\$wavenames" |\\
#    nawk '{for(i=1;i<=NF;++i){print \$i}}' |\\
#    nawk -v wave=\$ref 'wave == \$NF{print "LABIN FP=" \$NF "    SIGFP=SIG" \$NF " -"} \\
#	wave != \$NF {++n; F[n] = \$NF} END{for(i=1;i<=n;++i){\\
#	printf "    FPH%d=%s SIGFPH%d=SIG%s DPH%d=DANO%s SIGDPH%d=SIGDANO%s ", i, F[i], i, F[i], i, F[i], i, F[i]; \\
#	if(i != n) printf "-";\\
#	print "";}}' >> \$SCRIPT 

    # scale ref against everything (including ref)
    echo "\$wavenames" |\\
    nawk '{for(i=1;i<=NF;++i){print \$i}}' |\\
    nawk -v wave=\$ref 'wave == \$NF{print "LABIN FP=" \$NF "    SIGFP=SIG" \$NF " -"} \\
	{++n; F[n] = \$NF} END{for(i=1;i<=n;++i){\\
	printf "    FPH%d=%s SIGFPH%d=SIG%s DPH%d=DANO%s SIGDPH%d=SIGDANO%s ", i, F[i], i, F[i], i, F[i], i, F[i]; \\
	if(i != n) printf "-";\\
	print "";}}' >> \$SCRIPT 

    cat << EOF-wave >> \$SCRIPT
CONV ABS 0.0001 TOLR 0.000000001 NCYC 4
END
EOF-scaleit
if(\\\$status) set BAD

if(! \\\$?DOALL) goto cleanup

EOF-wave

end

cat << EOF-script >> \$SCRIPT
cleanup:
# clean up?


if(! \\\$?BAD) then
    echo "\$wavenames are now all in \\\$outfile"
else
    echo "scaleit failed."
    exit 9
endif

EOF-script
chmod a+x \$SCRIPT



































Makefile:
###############################################################################

#     #
##   ##    ##    #    #  ######  ######     #    #       ######
# # # #   #  #   #   #   #       #          #    #       #
#  #  #  #    #  ####    #####   #####      #    #       #####
#     #  ######  #  #    #       #          #    #       #
#     #  #    #  #   #   #       #          #    #       #
#     #  #    #  #    #  ######  #          #    ######  ######

###############################################################################
#
#	Create a Makefile for restarting Scaler procedures after a crash
#
###############################################################################

# cache filenames for use as dependencies
set MERGEfiles = \`echo \$wavenames \$MTZ_dir | nawk '{for(i=1;i! \${tempfile}SOLVEfiles 
set SOLVEfiles = \`nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
set SHELXafiles = \`echo \$wavenames \$SHELX_dir | nawk '{for(i=1;i! Makefile
#SHELL = /bin/csh

# aliases for common targets

all: SHARP SOLVE SHELX XPLOR Pattersons

frugal:
	@ echo "clearing out large intermediate files"
	rm -f \${rawMTZ} \${sortMTZ} \${rscaleMTZ} \${lscaleMTZ} \${LOG_dir}/*.old*

SHARP: \${finalMTZ}
	@ echo "\${finalMTZ} is ready for input into SHARP or mlphare."

SOLVE: \$SOLVEfiles
	@ echo "\${SOLVE_dir}/*.fmt are ready for input into SOLVE"

SHELX: \${SHELX_dir}/ano.hkl \${SHELX_dir}/iso.hkl \${SHELX_dir}/fh.hkl \$REVISE_hkl
	@ echo "\${SHELX_dir}/*.hkl are ready for input into SHELX"

XPLOR: \$XPLORfiles
	@ echo "\${XPLOR_dir}/*.fobs are ready for input into XPLOR's mad_merge.inp"

Pattersons: \${MAP_dir}/FH_Patt.map \$REVISE_Patt
	@ echo "Pattersons are ready in \${MAP_dir}"

##############################################################################
# Actual file targets for sorting, scaling, and localscaling

# sort all raw wavelength data together (and scale reference set)
\${rawMTZ}: \${SCRIPT_dir}/sort_everything.com \$RAWfiles
	@ if test -f \$sortLOG; then mv \$sortLOG \${sortLOG}.old ; fi
	@ echo "sorting raw data ..."
	@ \${SCRIPT_dir}/sort_everything.com > \$sortLOG

EOF

if(! \$?USER_REFERENCE) then
    cat << EOF >> Makefile
# scale and merge the reference set
\${refMTZ}: \${rawMTZ} \${SCRIPT_dir}/make_reference_set.com 
	@ if test -f \$refLOG; then mv \$refLOG \${refLOG}.old ; fi
	@ echo "prescaling reference set (\${wave_reference}) ... (see \$refLOG)"
	@ \${SCRIPT_dir}/make_reference_set.com \${rawMTZ} \${EXTRA_ARGS} > \$refLOG

EOF
endif

cat << EOF >> Makefile
# import the reference set into the raw data file
\${sortMTZ}: \${refMTZ} \${rawMTZ} \${SCRIPT_dir}/import_reference.com 
	@ if test ! -f \$refLOG; then echo "" > \$refLOG ; fi
	@ echo "importing the reference set ... (see \$refLOG)"
	@ \${SCRIPT_dir}/import_reference.com \${refMTZ} \$refMTZset FreeR_flags \${rawMTZ} \${EXTRA_ARGS} >> \$refLOG

# rough scaling
\${rscaleMTZ}: \${sortMTZ} \${SCRIPT_dir}/rough_scale.com \$RUNFILE
	@ if test -f \$rscaleLOG; then mv \$rscaleLOG \${rscaleLOG}.old ; fi
	@ echo "\$SCALING scaling everything to \${refMTZ}.  (see \$rscaleLOG)"
	@ \${SCRIPT_dir}/rough_scale.com \${sortMTZ} \${EXTRA_ARGS} | tee \${rscaleLOG} | egrep "Cycle|shift"

# smooth localscaling
\${lscaleMTZ}: \${rscaleMTZ} \${SCRIPT_dir}/localscale.com \$RUNFILE
EOF
if(\$?ROUGHSCALE_ONLY) then
    cat << EOF >> Makefile
	@ echo "localscaling disabled"
	@ ln -sf \`basename \${rscaleMTZ}\` \${lscaleMTZ}
EOF
else
    cat << EOF >> Makefile
	@ if test -f \$lscaleLOG; then mv \$lscaleLOG \${lscaleLOG}.old ; fi
	@ echo "localscaling: this can take a long time.  (see \$lscaleLOG)"
	@ \${SCRIPT_dir}/localscale.com \${rscaleMTZ} \${EXTRA_ARGS} | tee \${lscaleLOG} | egrep "Cycle|shift"
EOF
endif
cat << EOF >> Makefile
	@ echo ""

###############################################################################

# merge individual wavelengths from final scaled file
EOF
foreach wave ( \$wavenames )
cat << EOF >> Makefile
\${MTZ_dir}/\${wave}.mtz: \${lscaleMTZ} \${SCRIPT_dir}/merge.com
	@ if test -f \${mergeLOG}\${wave}.log; then mv \${mergeLOG}\${wave}.log \${mergeLOG}\${wave}.log.old ; fi
	@ echo "mergeing \$wave as \${MTZ_dir}/\${wave}.mtz ...  (see \${mergeLOG}\${wave}.log)"
	@ \${SCRIPT_dir}/merge.com \${wave} \${lscaleMTZ} > \${mergeLOG}\${wave}.log
	@ mv merged.mtz \${MTZ_dir}/\${wave}.mtz

EOF
end
# figure out where Free-R flags should come from
if("\$freeR_source" == "") set freeR_source = "5%"
if(("\$freeR_source" !~ *"%")&&(! -e "\$freeR_source")) set freeR_source = "5%"

cat << EOF >> Makefile
###############################################################################
# collate scaled and merged wavelengths together (and make free-R flags)
\${finalMTZ}: \$MERGEfiles \${SCRIPT_dir}/scaleit.com
	@ if test -f \$finalLOG; then mv \$finalLOG \${finalLOG}.old ; fi
	@ echo ""
	@ echo "combining \$wavenames into \${finalMTZ} ... (see \${finalLOG})"
	@ \${SCRIPT_dir}/scala_summary.com \${mergeLOG}*.log
	@ \${SCRIPT_dir}/scaleit.com > \${finalLOG}
	@ mv scaleited.mtz \${finalMTZ}
	@ rm -f cadded.mtz
	@ echo "adding \$freeR_source Free-R flags ..."
	@ \${SCRIPT_dir}/FreeRer.com \${finalMTZ} \$freeR_source >> \${finalLOG}
	@ mv FreeRed.mtz \${finalMTZ}
	@ mv freeR_flag.mtz \${MTZ_dir}
	@ mv XPLOR.cv \${XPLOR_dir}/freeR.cv
	@ echo ""
	@ echo "True completeness to \$hiRES A:"
	@ \${SCRIPT_dir}/mtz_sum.com \$hiRES \${finalMTZ}
	@ echo ""
	@ \${SCRIPT_dir}/scaleit_sum.com \${finalLOG} >> \${finalLOG}
	@ echo "look at end of \${finalLOG} for Dano and Diso vs \$wave_reference"

###############################################################################
# creation of Patterson maps

# calculate "best" FH Patterson (and update shelx data)
\${MAP_dir}/FH_Patt.map: \${finalMTZ} \${SCRIPT_dir}/bestFH.com
	@ \${SCRIPT_dir}/bestFH.com \${finalMTZ} > \${LOG_dir}/bestFH.log
	@ cat bestFH.log >> \${LOG_dir}/bestFH.log 
	@ rm -f bestFH.log 2> /dev/null
	@ mv fh.hkl \${SHELX_dir}/fh.hkl 2> /dev/null
	@ mv FH.mtz \${MTZ_dir}/bestFH.mtz 2> /dev/null
	@ mv FH_Patt.map \${MAP_dir}/FH_Patt.map 2> /dev/null
#	@ mv wFH_Patt.map \${MAP_dir}/ 2> /dev/null

EOF

# don't run revise for single-wavelength data
if("\$REVISE_Patt" != "") then
    cat << EOF >> Makefile
# calculate "revised" FM Patterson (and update shelx data)
\${MAP_dir}/FM_Patt.map: \${finalMTZ} \${SCRIPT_dir}/revise.com
	@ \${SCRIPT_dir}/revise.com \${finalMTZ} > \${LOG_dir}/revise.log
	@ mv fm.hkl \${SHELX_dir}/fm.hkl 2> /dev/null
	@ mv FM.mtz \${MTZ_dir}/revisedFM.mtz 2> /dev/null
	@ mv FM_Patt.map \${MAP_dir}/FM_Patt.map 2> /dev/null

EOF
endif
cat << EOF >> Makefile
###############################################################################
# conversion to other programs formats

# SOLVE
EOF

foreach wave ( \$wavenames )
cat << EOF >> Makefile
\${SOLVE_dir}/\${wave}.fmt: \${MTZ_dir}/\${wave}.mtz \${SOLVE_dir}/mtz2SOLVE.com
	@ \${SOLVE_dir}/mtz2SOLVE.com \${MTZ_dir}/\${wave}.mtz > \${extractLOG}SOLVE_\${wave}.log
	@ mv SOLVE.fmt \${SOLVE_dir}/\${wave}.fmt

\${SOLVE_dir}/\${wave}.unmerged.fmt: \${lscaleMTZ}  \${SCRIPT_dir}/extract.com  \${SOLVE_dir}/mtz2SOLVE.com
	@ \${SCRIPT_dir}/extract.com \${wave} \${lscaleMTZ} > \${extractLOG}unmerged_SOLVE_\${wave}.log
	@ \${SOLVE_dir}/mtz2SOLVE.com unmerged.mtz >> \${extractLOG}unmerged_SOLVE_\${wave}.log
	@ rm -f unmerged.mtz > /dev/null
	@ mv SOLVE.fmt \${SOLVE_dir}/\${wave}.unmerged.fmt

EOF
end

echo "###############################################################################" >> Makefile
echo "# SHELX" >> Makefile

cat << EOF >> Makefile

# these will be made when the Pattersons are made
\${SHELX_dir}/fh.hkl: \${MAP_dir}/FH_Patt.map
\${SHELX_dir}/fm.hkl: \${MAP_dir}/FM_Patt.map

# pick best SHELX data files
\${SHELX_dir}/ano.hkl: \$SHELXafiles
	@ \${SHELX_dir}/best_signal.com \${SHELX_dir}/*_ano.hkl
	@ mv best.hkl \${SHELX_dir}/ano.hkl

\${SHELX_dir}/iso.hkl: \$SHELXifiles
EOF

if("\$SHELXifiles" != "") then
cat << EOF >> Makefile
	@ \${SHELX_dir}/best_signal.com \${SHELX_dir}/*-*.hkl
	@ mv best.hkl \${SHELX_dir}/iso.hkl
EOF
endif

foreach file ( \$SHELXafiles )
set wave = \`basename \$file _ano.hkl\`
cat << EOF >> Makefile
\${file}: \${MTZ_dir}/\${wave}.mtz \${SHELX_dir}/mtz2SHELX.com
	@ \${SHELX_dir}/mtz2SHELX.com \${MTZ_dir}/\${wave}.mtz > \${extractLOG}SHELX-\${wave}_ano.log
	@ mv SHELX_ano.hkl \$file
	@ echo \$file >> \${extractLOG}SHELX-\${wave}_ano.log
	
EOF
end

# SHELXifiles can blow up line size with high # of wavelengths, so use nawk here
echo \$wavenames \$SHELX_dir |\\
 nawk -v xlog=\$extractLOG -v mtz=\$MTZ_dir '{for(i=1;i ", \$NF, mtz, \$i, mtz, \$j;\\
	printf "%sSHELX-%s-%s.log\\n", xlog, \$i, \$j;\\
	printf "\\t@ mv ./SHELX_iso.hkl %s \\n", file;\\
	printf "\\t@ echo %s >> %sSHELX-%s.log\\n\\n", file, xlog, \$i, \$j;\\
       }}}' >> Makefile


echo "###############################################################################" >> Makefile
echo "# X-plor" >> Makefile

foreach wave ( \$wavenames )
cat << EOF >> Makefile
\${XPLOR_dir}/\${wave}_anom.fobs: \${MTZ_dir}/\${wave}.mtz
	@ \${XPLOR_dir}/mtz2XPLOR.com \${MTZ_dir}/\${wave}.mtz > \${extractLOG}XPLOR-\${wave}.log
	@ mv XPLOR.fobs \${XPLOR_dir}/\${wave}_anom.fobs

EOF
end



#
# Make a README file
set SCRIPT = ./README.Scaler
cat << EOF-README >! \$SCRIPT

Scaler Elves guide to their scripts

1) In a rush?  Just type this:

make 

That's it.  

Your scaled and merged data will end up in \${finalMTZ}, in CCP4/SHARP format, 
and will also be converted into SOLVE, SHELX, and X-PLOR formats.



2) Okay, how does it work?

    All the really important stuff is in \${SCRIPT_dir}, and that directory
has its own README file.

In this directory (\`pwd\`):

################################################################################
Makefile		- "make" file for your project

    usage: make [target]
    where: [target] is the thing (file) you want to create or update
    
    example: make SOLVE

    will create data files for input into Tom Terwilliger's "solve" program

    The unix program "make" is a wonderful tool for maintaining a complex, 
    interdependent system of files (like source code, or x-ray data processing).
    The Makefile contains a list of instructions and rules, like this:
    
somefile.mtz: someotherfile.mtz script.com
	script.com >! logfile.log

    Translated: 
    To create somefile.mtz, you need someotherfile.mtz and script.com.  If
    somefile.mtz is missing, or if someotherfile.mtz or script.com are newer 
    (by file date stamp) than somefile.mtz, then execute the command:
    "script.com >! logfile.log".  

    This way, if you edit script.com or change someotherfile.mtz, "make" knows 
    that somefile.mtz needs to be updated.  The really neat part of it all is 
    that the Makefile can also contain a similar entry for how to make 
    someotherfile.mtz, using a different script, and "make" will then know 
    it needs to update somefile.mtz after it has updated someotherfile.mtz.
    The list can go on and on.
    Simply put, typing "make" will update your project, making use of any
    changes you have made to the scripts, and frees you from keeping track
    of which scripts to run in which order.
    
    To "defeat" make, and keep it from doing processing you don't want it to, 
    use "touch".  If you type: "touch \${rscaleMTZ}", then, as far
    as make is concerned, you just ran \${SCRIPT_dir}/rough_scale.com
    etc...

################################################################################
\$RUNFILE		- customizable run list 

    Your data are divided into "runs" of contiguous frames
    Run-specific scala commands can be put in here, i.e.
    RESOLUTION run 1 5.0 
    for a 5A cuttoff on run 1

################################################################################
\$RULESFILE		- custom SCALA commands used in all Scaler Elves scripts

    Note: unlike \${RUNFILE}, \$RULESFILE is not dynamically loaded by the
    scripts in \${SCRIPT_dir}.  However, you can present this file to Scaler
    Elves the next time you invoke them, and they will include any scala cards
    they find there into their scala scripts.
    
################################################################################



3) What if something goes wrong?

    The Scaler elves have been trained to handle a number of common problems 
encountered in their localscaling procedure.  However, if something happens that
is beyond their experience, it's up to you to figure it out.  :(  But, please
email jamesh@ucxray6.berkeley.edu about your problem.

    The scripts you will need to look at are all in \${SCRIPT_dir},  and are run
(pretty much) in the following order:
\${SCRIPT_dir}/sort_everything.com    - sorts all raw data together
\${SCRIPT_dir}/make_reference_set.com - creates a small, reference dataset from a selected wavelength
\${SCRIPT_dir}/import_reference.com   - imports the reference dataset into the raw, unscaled mtz
\${SCRIPT_dir}/rough_scale.com        - does one-scale-per-frame scaling
\${SCRIPT_dir}/localscale.com         - performs 3D localscaling
\${SCRIPT_dir}/merge.com wave         - merges "wave", do this for each of: \$wavenames
\${SCRIPT_dir}/merge.com ...etc.
\${SCRIPT_dir}/scaleit.com            - combines all wavelengths into one file

the file \${SCRIPT_dir}/README explains all this in more detail

    Wether you have problems or not, When you're ready to start tinkering around, 
(edit the scripts, trying other space groups, etc.), have a look in \${SCRIPT_dir}, 
\${SHELX_dir}, \${SOLVE_dir}, and \${XPLOR_dir}.  There are README files there too.


EOF-README


set SCRIPT = "\${SCRIPT_dir}/README"
grep "Scaler Elves" \$SCRIPT >& /dev/null
if(! \$status) set SCRIPT = \${SCRIPT_dir}/README.Scaler
cat << EOF-README >! \$SCRIPT

Scaler Elves guide to their scripts



What am I supposed to do with all these scripts!?


################################################################################
sort_everything.com	- script for combining and sorting all raw data into one file
    reads: \$RAWfiles	    
    makes: \${rawMTZ}
    usage: \${SCRIPT_dir}/sort_everything.com [SG]
    where: [SG] is the (optional) new space group

    example: \${SCRIPT_dir}/sort_everything.com \$SG >! \$sortLOG
	
	Will sort all raw data and reindex it to \$SG
    (Note: the reindexing done here is at the mercy of the CCP4 program "reindex", 
    it is always safer to change your indicies in the integration program)
    For asymmetric orthorhombic space groups (P2221, P21212 and C2221) you can
    also specify "pseudo" space groups like "P2212" to indicate P2221 with the 
    screw axis along "b" etc.
    
################################################################################
make_reference_set.com	- scale and merge the reference data set.
    reads: \${rawMTZ}
    makes: \${refMTZ}
    usage: \${SCRIPT_dir}/make_reference_set.com [infile.mtz]

    example: \${SCRIPT_dir}/make_reference_set.com >! \$refLOG

    This script creates a "pre-merged" reference data set out of one of 
    your wavelengths.  This reference set will be used by SCALA as a guide 
    for scaling all raw data.  It exists solely to stabilize the scaling run, 
    and is not included in the final mergeing step.  Mergeing of wavelength used
    to make this reference set will follow the same procedure as the rest of 
    the wavelengths.
    
    Note: this is not, necessarily the reference set you will be using in
     mlphare, etc.

################################################################################
import_reference.com  - combine the reference data set with \${rawMTZ}.
    reads: \${rawMTZ} \${refMTZ}
    makes: \${sortMTZ}
    usage: \${SCRIPT_dir}/import_reference.com reference.mtz [infile.mtz]

    example: \${SCRIPT_dir}/import_reference.com \${refMTZ} >> \$refLOG

    This script imports an arbitrary reference data set into your scaling
    run.  This can be almost any set of unique data.  By default, Scaler
    Elves will make a reference dataset one from your most complete wavelength
    using the script above.
    You could also use a calculated dataset from your final, refined structure
    as \${refMTZ} here.  This would have the effect of traditional FC-directed 
    absorption corrections in localscaling (below).  By default, the Free-R 
    Free-R flagged HKLs will be excluded, as not to bias scaling of Fobs to your
    final Fc.  This allows you to use the free R to see if this absorption 
    correction did you any good.

################################################################################
rough_scale.com		- first round of all-data scaling
    reads: \${sortMTZ} \$RUNFILE
    makes: \${rscaleMTZ}
    usage: \${SCRIPT_dir}/rough_scale.com [cycles] spacing [spacing] filter [infile]

    where: [cycles] is the number of scaling cycles you want (default: 50)
	   [spacing] is the Bfactor smoothing window, in degrees (default: 10)
	   [infile] is the input mtz file (default: \${sortMTZ})
	   filter turns on the "eigenvalue filter"
    
    example: \${SCRIPT_dir}/rough_scale.com 5   spacing 10   filter

    This script scales all data (guided by the "pre-merged" reference) using
    one scale factor per frame, but requiring that the B-factor vary smoothly
    over all frames.  This script mainly serves to remove large discontinuities
    in scale that would crash localscale.com.  If your runs have no discontinuities
    (no fills, inverse beam, etc.),  then you can skip rough_scale.com	   

    If \$RUNFILE is missing, it will be regenerated by rough_scale.com
    
################################################################################
localscale.com		- second round of all-data scaling (3D scales)
    reads: \${rscaleMTZ} \$RUNFILE
    makes: \${lscaleMTZ}
    usage: \${SCRIPT_dir}/localscale.com [cycles] spacing [spacing] filter [infile]

    where: [cycles] is the number of scaling cycles you want (default: 50)
	   [spacing] is the scale smoothing window, in degrees (default: 10)
	   [infile] is the input mtz file (default: \${rscaleMTZ})
	   filter turns on the "eigenvalue filter"

    example: \${SCRIPT_dir}/localscale.com 50    \${sortMTZ}

    This script scales all data, guided by the "pre-merged" reference, and 
    building on the scales obtained by rough_scale.com in a "3D" localscaling
    procedure.  Scale factors are required to vary smoothly within each "run".
    B-factors are not refined, but instead, the scale is allowd to vary (smoothly) 
    across the detector face.  Combined with the smooth scaling over frames, this
    has the effect of assigning a smoothly-varying scale to every point in the
    observed reciprocal space, and, hence, localscaling.  This is the MAD scaling
    procedure recommended by Phil Evans in the SCALA documentation, and JMH has
    found it to improve Rmerge significantly.
    
    If \$RUNFILE is missing, it will be regenerated by localscale.com

################################################################################
merge.com		- mergeing utility
    reads: \${lscaleMTZ} \$RUNFILE
    makes: merged.mtz
    usage: \${SCRIPT_dir}/merge.com [wave] [RESO] [SG]

    where: [wave] is is the wavelength name to merge (default: all of them)
           [RESO] is the high-resolution cutoff (default: \$hiRES)
	   [SG] is the space group, reindexed using "reindex" (default: \$SG)
    
    example: \${SCRIPT_dir}/merge.com \$wave_reference \$hiRES \$otherSGs[\$#otherSGs]

    This script merges all data from the provided wavelength.  No scaling is done, 
    so you should use a scaled MTZ.  merge.com "knows" which wavelength is which
    from the information in \$RUNFILE
 		    
    If \$RUNFILE is missing, it will be regenerated by merge.com

################################################################################
extract.com		- non-mergeing wavelength extractor
    reads: \${lscaleMTZ} \$RUNFILE
    makes: unmerged.mtz
    usage: \${SCRIPT_dir}/extract.com wave [RESO] [SG]

    where: wave is is the wavelength name to merge (required)
           [RESO] is the high-resolution cutoff (default: \$hiRES)
	   [SG] is the space group, reindexed using "reindex" (default: \$SG)
    
    example: \${SCRIPT_dir}/extract.com \$wave_reference \$hiRES

    This script works pretty much the same as merge.com, except it does
    not merge equivalent reflection data.  HOWEVER, it does add partials.
    extract.com serves mainly to migrate scaled, but unmerged reflection
    data to another scaling program (such as SOLVE's localscaling procedure).

    If \$RUNFILE is missing, it will be regenerated by extract.com

################################################################################
scaleit.com		- place merged data in a multicolumn MTZ file
    reads: \${lscaleMTZ} \$RUNFILE
    makes: \${finalMTZ}
    usage: \${SCRIPT_dir}/scaleit.com [\$wave_reference]
			    
    where:  [\$wave_reference] is the wavelength name to use as a reference
	    (one of: \$wavelengths)

	This script combines each of the files produced by merge.com into
    a single, multi-column mtz file.  This is the file you should use for
    SHARP and mlphare.
	If you type "\${SCRIPT_dir}/scaleit.com all", scaleit.com will do a 
    scaleit run on each of \$wavenames in turn.
    
    

Utilities:

################################################################################
scaleit_sum.com		- sumarize Diso and Dano
    reads: scaleit logs
    makes: an xloggraph plot (to screen)
    usage: \${SCRIPT_dir}/scaleit_sum.com \${LOG_dir}scaleit.log

	This little jiffy serves primarily in edge walking.  It gives you
    a quick plot of Dano and Diso (relative to the reference) vs. x-ray energy.

################################################################################
mtz_sum.com		- sumarize an MTZ file
    reads: merged MTZ files
    makes: a nice table of completeness and /
    usage: \${SCRIPT_dir}/mtz_sum.com mtzfile.mtz [RESO]
    
    example: \${SCRIPT_dir}/mtz_sum.com \$hiRES ./mtz/all.mtz

	Prints out completeness and F/sigF for every F in the mtz file provided.
    
################################################################################
scala_summary.com	- sumarize mergeing results from one or more scala logs
    reads: scala/truncate log files
    makes: a nice table of Rmerge Ranom I/sigma Completeness Multplicity and Wilson B
    usage: \${SCRIPT_dir}/scala_summary.com scala.log [otherscala.log ... ]

    example: \${SCRIPT_dir}/scala_summary.com ./logs/merge_*

	Prints out 

################################################################################
FreeRer.com		- add/inherit Free-R flags
    reads: one or two mtzs (or one mtz and an x-plor file)
    makes: FreeRed.mtz, FreeR_flag.mtz and XPLOR.cv
    usage: \${SCRIPT_dir}/FreeRer.com mtzfile.mtz [free-R source] [fraction[%]]
    where: mtzfile.mtz is the file you want to ADD Free-R flags to
           [free-R source] is the file you want to get the flags from (mtz or X-plor)
	   [fraction[%]] is the fraction of spots to put in the free-R set (default: 10%)

    example: \${SCRIPT_dir}/FreeRer \${finalMTZ} /some/random/place/xplor/olddata.cv
    
    FreeRed.mtz, FreeR_flag.mtz and XPLOR.cv will always be made, and they contain equivalent 
    representations of the Free-R set.  FreeR_flag.mtz, however will contain Free-R assignments 
    extending out to 1.5A.  That way, FreeR_flag.mtz can be used to assign the Free-R set from 
    future crystals (which might diffract better).
    If no [free-R source] is given, the Free-R flags will be made up (as in uniqueify).  However, 
    if a second file is given (mtz or X-PLOR format) The Free-R flags will be taken from it.  
    Any "holes" in an externally-obtained set (I.E. missing HKLs) will be filled in as described
    in the CCP4 documentation.  
    The given example will produce a file called FreeRed.mtz that contains the Free-R flags used 
    in /some/random/place/xplor/olddata.cv.  
    
################################################################################
bestFH.com	- Matthews "best" FH estimator

    input:  all.mtz	- a cad-ed mtz file with multiple data sets
    output: FH.mtz	- an mtz containing only the estimate of FH
            fh.hkl	- shelx version of FH.mtz
	    FH_Patt.map - a Patterson map of FH
	    FH_Four.map - phased map of FH (if a phase is in all.mtz)
	   
    usage: \${SCRIPT_dir}bestFH.com all.mtz [Fset] [Dset] [1.8A]
    where: 
    all.mtz    contains same-site reflection data      (default: mtz/all.mtz)
    Fset       are the sets of Fs you want to use      (default: all of them)
    Dset       are the sets of Danos you want to use   (default: all of them)
    1.8A       is the desired outer resolution limit   (default: all data)
    PHI        is the phase set you want to use	       (default: most recent phase)
    
    FH_Patt.map is calculated with a 4*rms(FH) cutoff, as calculated by scaleit.
    
    example1: \${SCRIPT_dir}bestFH.com mtz/all.mtz
	will calculate an estimate of FH from all the difference data in 
	mtz/all.mtz.
	
    example2: \${SCRIPT_dir}bestFH.com dmed.mtz
	will calculate an estimate of FH from all the difference data in 
	mtz/all.mtz. (same as above), but will also calculate a phased map 
	of FH, using the most recently-added phase in dmed.mtz (PHIDM).  
	This is usually superior to ordinary difference Fouriers for finding 
	new heavy-atom sites.
    
    example3: \${SCRIPT_dir}bestFH.com mtz/all.mtz no DANOFlo Flo
	same thing, but leave the "DANOFlo difference data-set and "Flo" data
	set out of the calculation.
    
    description:
	This script offers the "new" functionality of computing a "Matthews FH" 
	estimate.  This analysis not only "averages" information from all your 
	diference data into a single data set, but reduces the systematic error
	produced by cross-terms in the substraction of anomalous and 
	isomorphous difference data: |FH| == |FPH-FP| != |FPH|-|FP|
    
	In bestFH.com, all anomalous difference data are scaled together, 
	and then added (sigma-weighted) together.  Then, all the possible
	isomorphous differences between "F"s in the mtz are subtracted, 
	scaled, and also added together.  Finally, Dano is scaled against
	Diso, and FH is calculated by the Pythagorean theorem.
	
	Care must be taken in the ordering of the "F" datasets.  For example, 
	in a 3-wavelength MAD experiment: Finf Fpeak Fhi should be the order
	used.  Fhi Fpeak Finf is okay too, but not Finf Fhi Fpeak.  The latter
	would result in Finf-Fhi and Fhi-Fpeak "canceling" each other, because
	the f' differences will have opposite signs.  bestFH.com will try to
	get this ordering right, but you should check the difference dataset
	list to make sure none of them are opposing each other.

	Note also that all the data in mtz/all.mtz should be from 
	crystals with metal sites at the same positions, otherwise, FH will 
	be a mix of the two site constellations.  
    
    
################################################################################
reindex.com	- general-purpose re-indexing script

    input:  data.mtz	    - mtz file to re-index (merged or unmerged)
    output: reindexed.mtz   - mtz file with the new space group
    
    examples: 
	\${SCRIPT_dir}reindex.com data.P41212.mtz P43212
	  - will change the space group of "data.P41212.mtz" to P43212 
	    (assuming that is possible), and write the results to 
	    "reindexed.mtz"
	\${SCRIPT_dir}reindex.com data.P2221.mtz P2122
	  - will change the space group of "data.P2221.mtz" to the "pseudo" 
	    space group "P2122", which is P2221, but with "a" as the screw 
	    axis.  This is done by leaving the mtz file in P2221, but 
	    permuting the cell (and the data) so that the shortest cell edge 
	    (normally "a"), is moved to the third cell parameter (the one 
	    with screw symmetry).
	
    description:
	This is a general utility for changing the assigned space group of 
	mtz data using the CCP4 program "reindex".  It works on merged and 
	unmerged data.  Re-assignment of the screw/rotation axes of 
	anisotropic orthorhombic space groups is supported (see example 2).
	
	"Flipping" between alternative axis assignments is also easily done.
	Just include the word "flip" on the reindex.com command line to switch
	to the "other" axis assignment.  This may be neccessary for any space
	group having two or more cell edges exactly the same length.  The only 
	tricky ones are R3 and P3x, which have four possible axis assignments.  
	To specify the remaining two, use the word "flip" two or three times 
	(respectively).  see \${CDOC}/reindexing.doc for details.
	
	Changing between space groups with different point group, or even
	lattice symmetry is allowed, but unadvisable!  These transformations
	involve mergeing or "un-mergeing" spots, which reindex can't do.
    
	Note: moving/removing screw axes will result in the "loss" of 
	some systematic absence reflections, so be careful.  It is probably
	advisable to always merge in P222, and reindex later.
    
################################################################################
SGsearch.com		- exhaustive space-group search
    reads: a scala script
    makes: a table of mergeing statistics
    usage: SGsearch.com [script.com] [raw.mtz] [rootSGs]
    where: 
	script.com is the scala script to use        (default: merge.com)
	raw.mtz    is the raw, unscaled data         (default: raw.mtz)
	rootSGs    is/are the "starting" space group (default: SG from raw.mtz)

    example: SGsearch.com merge.com P212121

	will run merge.com with every orthorhombic space group:
	    P222, P2221, (P2122, P2212), P21212, (P21221, P22121), and P212121

    Picking the wrong space group has been known to waste weeks to years of an 
    investigators time.  SGsearch.com uses the space group provided to get the
    general crystal system your crystal was indexed with, and will then try 
    mergeing your data in EVERY space group belonging to that crystal system.
    The Rmerge, systematic absences, and asymmetric unit volume will be presented
    in a neat table for your review.  
    
    The actual logs from the individual merge.com runs will be placed in the ./logs/
    directory, named merge.SG.log.  If SGsearch.com finds these logs aready exist, 
    it will use the statistics in them to make the table, this usually saves you a 
    lot of time re-generating the table, and you can always delete these logs, and 
    run SGsearch.com again.
    
    SGsearch.com is desiged to work with the merge.com provided by Wedger Elves, 
    but should work fine with any scala/truncate script that is capable of 
    accepting and applying a space group provided on its command line.

################################################################################
autoscala		- optimizer for SDCORR card
    reads: a scala script
    makes: a better scala script
    usage: \${SCRIPT_dir}/autoscala script.com
    where: script.com is the \\scala script to optimize

    example: \${SCRIPT_dir}/autoscala \${SCRIPT_dir}/merge.com

    Scala's SDCORRECTION card allows the assigned error (sigma) of the spot 
    intensities to be edited.  Most measurement programs cannot predict the
    effects of absorption and other systematic measurement errors, and therefore
    usually give unrealisticially low estimates of the error in the measured
    spot intensities.  You should read the scala documentation to find out 
    exactly how SDCORR works.
    Briefly, "correct" sigmas should be similar to the scatter of observed intensities.
    That is, if the 10 observations of hkl=(5,9,12) deviate from the average value
    of (5,9,12) by 100 units (rms), then the sigma of (5,9,12) should be 100.  So, 
    if the assigned sigma is 50, then the scatter/sigma will be 2.  This analysis, 
    grouped by intensity bins, is the last graph in the scala logfile.  You want 
    all the points on this graph to be as close to 1.0 as possible.  If you see this, 
    then your assigned sigmas are probably realistic.
    To save you from hours of diddling with the SDCORR numbers, autoscala uses a 
    "Golded-Section" search (derived from Numerical Recipies), to optimize the three 
    numbers for scala's SDCORRECTION card, using the deviation of the aforementioned
    graph from 1.0 as a target.  In CCP4 3.3 and beyond, the first number on the SDCORR 
    card is optimized internally (and might as well be "1"), but the remaining two can 
    be tuned up by autoscala.

################################################################################
mtz2various.com		- basic format-converter script
    reads: merged.mtz
    makes: outfile.EXT
	EXT -> FORMAT
	cif -> CIF
	hkl -> shelx
	tnt -> TNT
	fin -> XtalView
	phs -> XtalView
	fobs-> XPLOR
	cv  -> XPLOR
	cns -> CNS
    usage: mtz2various.com merged.mtz outfile.EXT [format]
    where: 
	merged.mtz   is the merged mtz file (containing Fs)
	outfile.EXT  is the filename you want to use for the exported data
	format	     is the (optional) program you want outfile.EXT formatted for

    examples:
	mtz2various.com merged.mtz merged.cif
	  - will convert merged.mtz to CIF format
	mtz2various.com all.mtz "F1" merged.fobs
	  - will convert "F1" in all.mtz to XPLOR format
	mtz2various.com merged.mtz merged.hkl shelx
	  - will convert merged.mtz to shelx format
	mtz2various.com merged.mtz merged.hkl tnt
	  - will convert merged.mtz to TNT format

    description:
	mtz2various.com is a general-purpose "smart" script for converting
	"F" data from an mtz file (such as \${finalMTZ}) to other file formats
	for other non-CCP4 programs.  The format of the output file can either
	be implied by using a standard file extension in the output file name,
	or declared explicitly and separately on the command line.  Free-R 
	flags are exported automatically, if they are present.  In the case of 
	XtalView files, a suitable CRYSTAL file is also generated.

################################################################################
autoscala		- optimizer for SDCORR card
    reads: a scala script
    makes: a better scala script
    usage: \${SCRIPT_dir}/autoscala script.com
    where: script.com is the \\scala script to optimize

    example: \${SCRIPT_dir}/autoscala \${SCRIPT_dir}/merge.com

    Scala's SDCORRECTION card allows the assigned error (sigma) of the spot 
    intensities to be edited.  Most measurement programs cannot predict the
    effects of absorption and other systematic measurement errors, and therefore
    usually give unrealisticially low estimates of the error in the measured
    spot intensities.  You should read the scala documentation to find out 
    exactly how SDCORR works.
    Briefly, "correct" sigmas should be similar to the scatter of observed intensities.
    That is, if the 10 observations of hkl=(5,9,12) deviate from the average value
    of (5,9,12) by 100 units (rms), then the sigma of (5,9,12) should be 100.  So, 
    if the assigned sigma is 50, then the scatter/sigma will be 2.  This analysis, 
    grouped by intensity bins, is the last graph in the scala logfile.  You want 
    all the points on this graph to be as close to 1.0 as possible.  If you see this, 
    then your assigned sigmas are probably realistic.
    To save you from hours of diddling with the SDCORR numbers, autoscala uses a 
    "Golded-Section" search (derived from Numerical Recipies), to optimize the three 
    numbers for scala's SDCORRECTION card, using the deviation of the aforementioned
    graph from 1.0 as a target.  In CCP4 3.3 and beyond, the first number on the SDCORR 
    card is optimized internally (and might as well be "1"), but the remaining two can 
    be tuned up by autoscala.

################################################################################
For more detailed information, see your CCP4 documentation in:
\${CCP4}/doc

or go to the CCP4 homepage at:
netscape http://www.dl.ac.uk/CCP/CCP4/main.html

EOF-README


goto Return_from_Generate























































exit
Setup_SOLVE:
###############################################################################

  ####    ####   #       #    #  ######
 #       #    #  #       #    #  #
  ####   #    #  #       #    #  #####
      #  #    #  #       #    #  #
 #    #  #    #  #        #  #   #
  ####    ####   ######    ##    ######
     
###############################################################################
#
#   Create a SOLVE input file
#
###############################################################################

# safeties/defaults for undeclared names
if(! \$?CELL) set CELL = \`echo 100 100 100 90 90 90\`
if(! \$?SG) set SG = "P1"
if(! \$?otherSGs) set otherSGs = "\$SG"
if(! \$?hiRES) set hiRES = 3
if(! \$?loRES) set loRES = 1000
if(! \$?wavenames) set wavenames = "FP"
if(! \$?wavelengths) set wavelengths = "1.5471"
if(! \$?ASU) set ASU = 30000
set NRES = \`echo "\$ASU" | nawk '{printf "%d", (\$1/120)}'\`
if(! \$?SITES) set SITES = 2

# program variables
if(! \$?SOLVE_dir) set SOLVE_dir = "."
set SCRIPT = \${SOLVE_dir}/solve.com
set SOLVE_program = "solve"
set RESOLVE_program = "resolve"
set SOLVE_home = "."
set RESOLVE_home = ""
set SOLVE_sg_file = \`echo "\$SG" | nawk '{print tolower(\$0) ".sym"}'\`
set SOLVE_sg_dir = "\${SOLVE_home}"
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

# script variables
if(! \$?TITLE) set TITLE = "Example SOLVE input file"
if(! \$?tempfile) set tempfile = "./tempfile."
if(! \$?MAXLINE) set MAXLINE = 500


# need two-letter element code for SOLVE
if(! \$?Ee) then
    # use "\$METAL" variable from common Elves programs
    if(! \$?METAL) set METAL = "Se"
    if("\$METAL" == "unknown") set METAL = "Se"
    
    # convert long element name
    if(-e \${tempfile}elements.awk) then
	# need \${tempfile}elements.awk
	set Ee = \`echo \$METAL | \${tempfile}elements.awk | nawk 'NR==1{print \$2}'\`
    else
	# direct conversion?
	if(\$METAL =~ [A-Z][a-z]) then
	    set Ee = "\$METAL"
	else
	    # default to selenium
	    set Ee = "Se"
	endif
    endif
endif

# fill-in missing wavelength values (not too critical)
if(\$#wavelengths < \$#wavenames) then
    while(\$#wavelengths < \$#wavenames) 
	set wavelengths = \`echo "\$wavelengths 1.00000"\`
    end
endif


# create a temporary file of (potentially) unsupported symops
cat << EOF-screwies >! \${tempfile}screwies
17 4 4 P2122 PG222 ORTHORHOMBIC
 X,Y,Z 
 -X,Y,-Z 
 1/2+X,-Y,-Z 
 1/2-X,-Y,Z
17 4 4 P2212 PG222 ORTHORHOMBIC
  X,Y,Z 
  X,1/2-Y,-Z 
 -X,1/2+Y,-Z 
 -X,-Y,Z
18 4 4 P21221 PG222 ORTHORHOMBIC
 X,Y,Z 
 -X,Y,-Z 
 1/2+X,-Y,1/2-Z 
 1/2-X,-Y,1/2+Z
18 4 4 P22121 PG222 ORTHORHOMBIC
 X,Y,Z 
  X,-Y,-Z 
 -X,1/2+Y,1/2-Z 
 -X,1/2-Y,1/2+Z
EOF-screwies


#######################################

# check environment for SOLVE's location
if(\$?SOLVEDIR) then
    # solve must already be set up!
    set SOLVE_program = \${SOLVEDIR}/solve
    set RESOLVE_program = \${SOLVEDIR}/resolve
    set SOLVE_home = \${SOLVEDIR}
    set SOLVE_sg_dir = "\${SOLVE_home}"
endif

onintr Skip_Solve_Search

# look/check for solve access file in a few likely places
if((! -e /usr/local/lib/solve.access)&&(! -e /usr/local/lib/solve/solve.access)&&(! -e /usr/local/lib/solve2.access)&&(! -e /usr/local/lib/solve/solve2.access)) then
    # default locations of access file are not available
    # need to set SOLVEDIR variable 

    test -r \${SOLVE_home}/solve*.access >& /dev/null
    if(\$status) then
	# solve won't run without this file, look for it
	set files = \`which solve |& nawk 'BEGIN{RS=" "} ! system("test -x " \$0) {print}'\`
	foreach word ( \$files )
	    if((-e "\$word")&&(! (-e "\${SOLVE_home}/solve.access")||(-e "\${SOLVE_home}/solve2.access"))) then
		set temp = \`ls -lnLd \$word/solve*.access |& nawk '! /^d/ && \$5 > 10 {print \$NF}'\`
		if("\$#temp" != 1) then
		    set word = \`dirname \$word\`
		    set temp = \`ls -lnLd \$word/solve*.access |& nawk '! /^d/ && \$5 > 10 {print \$NF}'\`
		endif
		if("\$#temp" == 1) then
		    set SOLVE_home = "\$word"
		    set SOLVE_sg_dir = "\$SOLVE_home"
		endif
	    endif
	end
    endif
    test -r \${SOLVE_home}/solve.access
    if(\$status) then    
	# get serious, if we still havn't found it
#       foreach place ( /programs/solve /programs /usr/local /home /usr /* / )
	foreach place ( /usr/local /programs/solve /programs /home /usr/bin /usr/share )
	    if((-e "\$place")&&(! (-e "\${SOLVE_home}/solve.access")||(-e "\${SOLVE_home}/solve2.access"))) then
		# FIND files of right name
		set place = \`cd \$place ; pwd\`
		set temp = \`find \$place -name 'solve*.access' -print |& nawk 'NF==1' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 1000000 {print \$NF}'\`
	    if("\$#temp" == 1) then
		set SOLVE_program = "\$word"
		set temp = \`dirname \$SOLVE_program\`
		if(-e "\${temp}/\${SOLVE_sg_file}") then
		    set SOLVE_sg_dir = "\$temp"
		endif
		continue
	    endif
	    if("\$#temp" != 1) then
		# maybe this was a directory in the path? 
		set word = \`dirname \$word\`
		set temp = \`ls -ln \$word/solve |& nawk '! /^d/ && \$5 > 10 {print \$NF}'\`
	    endif
	endif
    end
endif


# get serious, if we still havn't found it
test -x "\$SOLVE_program"
if(\$status) then
#    foreach place ( /programs/solve /programs /usr/local /usr/* /* / )
    foreach place ( /programs/solve /programs /usr/local /xtal/ /usr/bin /usr/share )
	test -x "\$SOLVE_program"
	if((\$status)&&(-e "\$place")) then
	    # FIND files of right name
	    set temp = \`find \$place -name solve -print |& nawk 'NF==1' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
if(\$status) then
    # just set it to the one in the subdirectory
    #set SOLVE_sg_dir = \${SOLVE_dir}/\${SG}/\${SOLVE_sg_file}
    set SOLVE_sg_dir = ./\${SG}
endif

# actually try to run SOLVE and warn if it didn't work
echo "END" |& "\$SOLVE_program" |& grep "Terwilliger" >& /dev/null
if(\$status) then
    echo "WARNING: we can't run "\\"solve\\"" on this system."
    echo "find out where "\\"solve\\"" is, and edit \${SCRIPT}"
    set SOLVE_home = "/programs/solve"
endif
rm -f solve.status >& /dev/null
if (! -e "\$RESOLVE_home") set RESOLVE_home = "\$SOLVE_home"

# use CCP4 structure-factor program to get f' and f''
crossec << EOF >! \${tempfile}crossec.log
ATOM \$Ee
NWAVE \$#wavelengths \$wavelengths
END
EOF

cat \${tempfile}crossec.log |\\
nawk -v Ee=\$Ee '\$1 == toupper(Ee) {print \$2, \$3, \$4}' |\\
sort -nr >! \${tempfile}wl_fpfpp
# format: lambda f' f" 
rm -f \${tempfile}crossec.log >& /dev/null

# make sure f" maximum is really the maximum possible value of f"
if(-e \${tempfile}elements.awk) then
    # avoid making peak f" wavelength the minimum f" becasue
    # of slight undercutting of the metal's theoretical edge
    echo \$METAL | \${tempfile}elements.awk |\\
    nawk '\$NF=="edge"{print "EDGE", 12398.4245/\$4, \$6}' |\\
    cat - \${tempfile}wl_fpfpp |\\
    nawk '/EDGE/{edge=\$2;fpp=\$3}\\
        ! /EDGE/{print \$0, sqrt((\$1-edge)^2), fpp}' |\\
    sort -n -k4 |\\
    nawk '# only increase fpp if close to edge \\
	  NR==1 && \$4<0.001 && \$3<\$NF{\$3=\$NF}\\
          {print \$1, \$2, \$3}' |\\
    sort -nr >! \${tempfile}
    set temp = \`cat \${tempfile} | wc -l\`
    if(\$temp == \$#wavelengths) then
	mv \${tempfile} \${tempfile}wl_fpfpp >& /dev/null
    endif
    rm -f \${tempfile} >& /dev/null
endif


# generate wavelength entries in a temporary file
set i = 0
echo "" >! \${tempfile}solvewaves
foreach wave ( \$wavenames )
    @ i = ( \$i + 1 )
    
    # make sure it is valid
    set wl_fpfpp = \`head -\$i \${tempfile}wl_fpfpp | tail -1\`
    if(\$#wl_fpfpp != 3) then
	# bad metal, or wavelength
	set wl_fpfpp = \`echo "\$wavelengths[\$i] -?.???   ?.???"\`
    endif
    rm -f \${tempfile}
    
    # get energy for printing's sake
    set energy = \`echo "\$wavelengths[\$i]" | nawk '\$1+0>0{printf "%.1f", 12398.4245/\$1}'\`

    cat << EOF-wave >> \${tempfile}solvewaves
lambda \$i			! info on wavelength #\$i follows
label \$wave			! a label for this wavelength
rawmadfile \${wave}.unmerged.fmt	! datafile with h k l I+ sigma+ I- sigma-
wavelength \$wl_fpfpp[1]		! wavelength value (\$energy eV)
fprimv_mad \$wl_fpfpp[2]		! f' value of \$Ee at \$energy eV   (IMPORTANT!)
fprprv_mad \$wl_fpfpp[3]		! f" value of \$Ee at \$energy eV   (IMPORTANT!)

EOF-wave
end
rm -f \${tempfile}wl_fpfpp
unset wl_fpfpp

# generate space-group definition list
#set SOLVE_sg_file = \`echo "\$SOLVE_sg_dir \$SG" | nawk '{print "symfile", \$1 "/" tolower(\$2) ".sym"}'\`

# almost always a bad idea to go to full resolution
# select half the reciprocal-space volume
set solveRES = \`echo \$hiRES 0.5 | nawk 'NF==2{printf "%.2f", (\$2*(\$1^-3))^(-1/3)}'\`

###############################################################################
# now create a SOLVE input file
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \$SCRIPT \${SCRIPT}.bak
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Prototype SOLVE script from \$TITLE
#
############################
#
#  You can run SOLVE interactively by typing:
#   setenv SOLVEDIR \$SOLVE_home
#   \${SOLVE_program}
#
#   ... and then feeding it lines starting with "title" below
#
#  The f' and f'' values here were taken from the CCP4 crossec program
#  The SOLVE homepage/manual is at:
#  netscape http://www.solve.lanl.gov/
#
############################
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk

setenv SOLVEDIR \$SOLVE_home

echo "Output will be put in solve.log and mad.log"
echo "watch solve.status for the sites."
echo ""
echo "enter Cntrl-Z and bg to background this SOLVE job."
echo ""
echo ""

\$SOLVE_program << EOF-solve >! solve.log
title \$TITLE

CELL \$CELL
symfile \${SOLVE_sg_dir}/\$SOLVE_sg_file

resolution \$hiRES \$loRES
res_phase \$solveRES     ! sometimes works better without noisy hi-res data

logfile mad.log                 ! write out most information to this file.
				! summary info will be written to "solve.prt"

mad_atomname \$Ee               ! anomalously scattering atom

!fixscattfactors                 ! do not refine scattering factors
refscattfactors                 ! refine scattering factors
thorough

EOF-script
cat \${tempfile}solvewaves >> \$SCRIPT
set SAD = ""
set notmad = ""
if (\$#wavelengths == 1) then
    set SAD = SAD
    set notmad = "! "
endif
cat << EOF-script >> \$SCRIPT

!premerged
unmerged
readformatted
nres \$NRES			! approx # of residues in ASU         (IMPORTANT!)
nanomalous \$SITES			! approx # of anomalously scattering atoms in ASU (IMPORTANT!)

\$SAD
\${notmad}SCALE_MAD                       ! read in and localscale the data
\${notmad}ANALYZE_MAD                     ! run MADMRG and MADBST and analyze all the Pattersons
\${notmad}SOLVE                           ! Solve the structure

EOF-solve
############################
if(\\\$status) goto bad

grep "TOP SOLUTION FOUND BY SOLVE" solve.status >& /dev/null
if(\\\$status) goto bad

touch solve.log
echo "A message from the Elves: "                                         >> solve.log
nawk '/STATUS:   DONE  /,/EOF/' solve.status                              >> solve.log
echo "You might get better results with more accurate f' and f'' in \\\$0."  >> solve.log
echo "the refined values used this time were:"                            >> solve.log
nawk '/NEWATOMTYPE/{print \\\$NF} \\
      /FPRIMV/{print "fprimv_mad", \\\$NF} \\
      /FPRPRV/{print "fprprv_mad ", \\\$NF}' solve*.script                  >> solve.log
cat << EOF                                                                >> solve.log
a phased MTZ file using this solution should be available in solve.mtz
but, solvent-flattening is highly recommended before you look at maps.
Elves also suggest you put the above sites into SHARP, since it is a
very good phasing program.
EOF

# display message, for those who are listening
tail -500 solve.log | nawk '/A message from the Elves/,/\\n/'

exit

bad:
echo "Dang!  SOLVE failed. "
echo "You might need to edit \\\$0 "
echo "to see what went wrong type:  more solve.log"
exit 9

EOF-script
chmod a+x \$SCRIPT


cat << EOF-resolve >! \${SOLVE_dir}/resolve.com
#! /bin/csh -f
#
#	Scaler Elves: Automatic RESOLVE Solvent flattening script
#
#
####################################################################
set mtzfile  = "solve.mtz"
set pdbfile  = "mr_solution.pdb"
set outfile  = "resolved.mtz"
set tempfile = "./resolve_temp"

defaults:
set steps   = "auto"
set Solvent = "50%"

# these are all reset from the command line
set F       = "FP"
set SIGF    = "SIGFP"
set PHI     = PHIB
set FOM     = FOM
set HL      = "HLA=HLA HLB=HLB HLC=HLC HLD=HLD"

setenv SYMOP \\\${CLIBD}/symop.lib
setenv CCP4_OPEN UNKNOWN

# different systems have different nawks
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

if("\\\$1" == "") goto Help
goto Setup
# scan the command line
Help:
cat << EOF

usage: \\\$0 [mlphare.mtz] [50%] [Flo]

where:
    mlphare.mtz - output MTZ from MLPHARE
    50%		- solvent content (must end with %)
    Flo		- F you want to flatten with (default to best F in mtz)

EOF
exit 9
ReturnFromSetup:
if(("\\\$F" == "")||(! -e \\\$mtzfile)) goto Help

# make solvent content fractional
set Solvent = \\\`echo \\\$Solvent | nawk '{print \\\$1/100}' \\\`

####################################################################
setenv SOLVEDIR \$SOLVE_home
\$RESOLVE_program << eof-resolve
HKLIN \\\$mtzfile \\\\
HKLOUT \\\$outfile \\\\
!TITLE phase resolution in resolve by \\\$Solvent solvent
!
! number of flattening cycles to execute
!MASK_CYCLE \\\$steps
! change last two values for buffer between solvent and protein
!SOLC 0.628 MASK 0.60 0.37
SOLVENT_CONTENT \\\$Solvent
!
! use a pdb file as the starting phases
!NOPRIOR
!MODEL \\\$pdbfile
\\\$model
LABIN FP=\\\$F PHIB=\\\$PHI FOM=\\\$FOM \\\$HL
!LABOU FP=FP PHIM=PHIM FOMM=FOMM
!
eof-resolve
if(! \\\$status) then
    echo "\\\$outfile is ready."
else
    exit 2
endif
exit
####################################################################


Setup:
####################################################################
# scan the command line
foreach arg ( \\\$* )
    if( "\\\$arg" =~ *.mtz ) set mtzfile  = "\\\$arg"
    if( "\\\$arg" =~ *.pdb ) set pdbfile  = "\\\$arg"
    if( "\\\$arg" =~ *.brk ) set pdbfile  = "\\\$arg"
    if( "\\\$arg" =~ *% ) set Solvent     = "\\\$arg"
    if(( "\\\$arg" =~ *[0-9] )&&( "\\\$arg" =~ [1-9]* )) set steps = "\\\$arg"
end

#let DM choose scheme for known # of steps
#if("\\\$steps" != "auto") set SCHEME = AUTO

#get variables from mtz file
echo "go" | mtzdump hklin \\\$mtzfile |\\\\
nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\\\
nawk 'NF>10 && \\\$(NF-1) ~ /[FQPWADI]/' |\\\\
cat >! \\\${tempfile}mtzdmp

# use completeness, or F/sigF to pick default F
cat \\\${tempfile}mtzdmp |\\\\
nawk '\\\$(NF-1) == "F"{F=\\\$NF; meanF=\\\$8; reso=\\\$(NF-2); comp=substr(\\\$0,32)+0; \\\\
      getline; if(\\\$(NF-1)!="Q") next; S=\\\$NF; if(\\\$8) meanF /= \\\$8; \\\\
	print F, S, reso, comp, meanF;}' |\\\\
sort -k3n,4 -k4nr,5 -k5nr >! \\\${tempfile}F

# and extract all dataset types/labels
cat \\\${tempfile}mtzdmp |\\\\
nawk 'NF>2{print \\\$(NF-1), \\\$NF, " "}' |\\\\
cat >! \\\${tempfile}cards

#clean up
rm -f \\\${tempfile}mtzdmp

# pick F with best resolution, or F/sigma
set F    = \\\`head -1 \\\${tempfile}F\\\`
if(\\\$#F > 2) then
    set SIGF = \\\$F[2]
    set F    = \\\$F[1]
endif

# pick most recent phase/FOM
grep "P \\\$PHI " \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    set temp = \\\`nawk '/^P/{print \\\$2}' \\\${tempfile}cards  | tail -1\\\`
    if("\\\$temp" != "") set PHI = "\\\$temp"
endif
grep "W \\\$FOM " \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    set temp = \\\`nawk '/^W/{print \\\$2}' \\\${tempfile}cards | tail -1\\\`
    if("\\\$temp" != "") set FOM = "\\\$temp"
endif

# pick most recent HL coefficients
cat \\\${tempfile}cards |\\\\
nawk '\\\$1=="A"{++n;HL[n]=\\\$NF} END{for(i=1;i<=n;i+=4) \\\\
      print "HLA="HL[i],"HLB="HL[i+1],"HLC="HL[i+2],"HLD="HL[i+3]}' |\\\\
cat >! \\\${tempfile}HL
set HL = \\\`tail -1 \\\${tempfile}HL\\\`

# see if user specified an F, Phase, FOM, or HL set
foreach arg ( \\\$* )
    set temp = \\\`grep " \\\$arg " \\\${tempfile}cards\\\`
    if("\\\$temp" =~ F*) then
	set F = "\\\${arg}"
	set temp = \\\`nawk -v arg="\\\$arg" '\\\$1==arg{print \\\$2}' \\\${tempfile}F\\\`
	if(\\\$#temp == 1) set SIGF = "\\\$temp"
	continue
    endif
    if("\\\$temp" =~ P*) set PHI = "\\\${arg}"
    if("\\\$temp" =~ W*) set FOM = "\\\${arg}"
    if("\\\$temp" =~ A*) set HL = \\\`grep "=\\\${arg} " \\\${tempfile}HL | tail -1\\\`
end

if(-e "\\\$pdbfile") then
    set model = "pdb_in \\\$pdbfile"
else
    set model = "!"
endif

rm -f \\\${tempfile}cards \\\${tempfile}F \\\${tempfile}HL >& /dev/null

goto ReturnFromSetup
EOF-resolve
chmod a+x \${SOLVE_dir}/resolve.com

# now create a SOLVE input file for each possible space group
set ORIGINAL = "\$SCRIPT"
foreach sg ( \`echo \$otherSGs | nawk '{print toupper(\$0)}'\` )
    
    # make sure directory exists
    if(-e "\${SOLVE_dir}/\${sg}") then
	test -d "\${SOLVE_dir}/\${sg}"
	if(\$status) then
	    # move the offending file
	    mv \${SOLVE_dir}/\${sg} \${SOLVE_dir}/\${sg}.bak
	endif
    else
	mkdir \${SOLVE_dir}/\${sg}
    endif
    
    # create a different script for each space group
    set SCRIPT = \${SOLVE_dir}/\${sg}/solve.com
    if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak
    
    # edit the existing SOVLE script
    cat "\$ORIGINAL" |\\
    nawk -v SG=\$sg '! /^symfile/ && ! /^rawmadfile/ {print} \\
	/^rawmadfile/ {print "rawmadfile ../" substr(\$0, 12)}  \\
	/^symfile/    {print "symfile",  "./" tolower(SG) ".sym"}' |\\
    cat >! \$SCRIPT
    
    chmod a+x \$SCRIPT

    # give em a copy of the resolve script
    cp \${SOLVE_dir}/resolve.com \${SOLVE_dir}/\${sg}


    # copy each space group file
    set symfile = \`echo \$sg | nawk '{print tolower(\$0) ".sym"}'\`
    
    # check if solve directory already has one
    grep "X, Y, Z" \${SOLVE_sg_dir}/\$symfile >& /dev/null
    if(! \$status) then
	# use solve's sym file
	cp \${SOLVE_sg_dir}/\$symfile \${SOLVE_dir}/\${sg}/\$symfile >& /dev/null
    else
	# try to create symop files from CCP4
	set temp = ""
	if(\$?CLIBD) then
	    if(-e "\$CLIBD/symop.lib") then
		set temp = "\$CLIBD/symop.lib"
	    endif
	endif
	
	# convert sym file from CCP4
	cat \$CLIBD/symop.lib \${tempfile}screwies |\\
	nawk -v SG=\$sg 'ops{print \$1;--ops} \\
	\$4 == SG && \$1 < 999 {printf "%3d Equiv positions, %-10s SG # %3d\\n", \$2, \$4, \$1; ops=\$2}' |\\
	nawk 'BEGIN{FS=","} NR>1{print \$1 ", " \$2 ", " \$3 " "} NR==1' |\\
	cat >! \${SOLVE_dir}/\${sg}/\$symfile
    endif
    
    # warning in case the unthinkable happens
    grep "X, Y, Z" \${SOLVE_dir}/\${sg}/\$symfile >& /dev/null
    if(\$status) then
	echo "WARNING: unable to determine symmetry operators for \$sg ! "
    endif
end
unset ORIGINAL
unset energy

rm -f \${tempfile}solvewaves
rm -f \${tempfile}symfiles
rm -f \${tempfile}screwies













##############################################################
# create SOLVE hkl converter script
##############################################################
set SCRIPT = \${SOLVE_dir}/mtz2SOLVE.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Conversion script to output I+ and I- in SOLVE format
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set infile   = ""
set outfile  = "SOLVE.fmt"
set tempfile = "\${tempfile}mtz2solve"
#
goto Setup
#
# usage: \$SCRIPT blah.mtz
#
#   if blah.mtz is a merged mtz, then H, K, L, I(+), SIGI(+), I(-), SIGI(-) 
#	will be written to \\\$outfile
#   if blah.mtz is an unmerged mtz, then  H, K, L, I, SIGI
#	will be written to \\\$outfile
#
ReturnFromSetup:

##############################################################
if("\\\$type" == "un") then
# this is the mtz2various format to use, you need 
mtz2various hklin \\\$infile hklout \\\$outfile << EOF-solve
OUTPUT USER '(\\\$format)'
LABIN \\\$LABIN
END
EOF-solve
else

# mtz2various doesn't work for this, use mtzutils/mtzdump instead
mtzutils hklin1 \\\$infile hklout \\\${tempfile}dumpme.mtz << EOF-label
INCLUDE \\\$LABELS
EOF-label

mtzdump hklin \\\${tempfile}dumpme.mtz << EOF-dump |\\\\
  nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' | nawk 'NF>3 && ! /[A-Z]/' >! \\\$outfile
FORMAT '(\\\$format)'
NREF -1
EOF-dump

endif

############################
if(! \\\$status) then
    echo ""
    echo "\\\$outfile now contains \\\$I from \\\$infile in SOLVE format."
    echo "use readformatted and \\\${type}merged in SOLVE"
    echo ""
endif

exit

Setup:
foreach arg ( \\\$* )
    if((! -e "\\\$infile")&&(-e "\\\$arg")) then
	if(\\\$arg =~ *.mtz) set infile = \\\$arg
    endif
end

if(! -e "\\\$infile") then
    echo "usage: \\\$0 blah.mtz "
    echo "where: blah.mtz is the mtz file you want to convert to SOLVE format."
    exit 9
endif

# see if this is a merged, or unmerged file
echo "HEADER" | mtzdump hklin \\\$infile |\\
nawk '/^ H K L /{while(NF>1){printf "%s", \\\$0; getline}; print ""} \\
/^ H H H /{while(NF>1){printf "%s", \\\$0; getline}; print ""}' |\\
nawk '/^ H K L /{for(i=1;i<=NF;++i){++n;label[n]=\\\$i}} \\
      /^ H H H /{for(i=1;i<=NF;++i){if(\\\$i ~ /[JGK]/) print label[i], label[i+1]}}' |\\
cat >! \\\${tempfile}labels

set I = \\\`cat \\\${tempfile}labels\\\`
if(\\\$#I > 3) then
    # this was a merged file
    set type = "pre"
    set I = "I(+) SIGI(+) I(-) SIGI(-)"
    set LABELS = "\\\$I"
    set format = "3I5, 4F12.3"
    # Resolve version incompatibility here
    set temp = \\\`echo "" | mtz2various | & nawk '/VERSION/{print \\\$7*10}'\\\`
    if("\\\$temp" < 34) then
	set LABIN = "DUM1=I(+) DUM2=SIGI(+) DUM3=I(-) DUM4=SIGI(-)"
    else
	# make sure we get these labels right
	set LABIN = "I(+)=I(+) SIGI(+)=SIGI(+) I(-)=I(-) SIGI(-)=SIGI(-)"
    endif
else
    # unmerged file
    set type = "un"
    set format = "3I5, 2F12.3"
    set LABIN = "FP=\\\$I[1] SIGFP=\\\$I[2]"
    set LABELS = "\\\$I[1] \\\$I[2]"
endif
rm -f \\\${tempfile}labels

goto ReturnFromSetup

EOF-script
chmod a+x \$SCRIPT



#
# Make a README file
set SCRIPT = "\${SOLVE_dir}/README"
cat << EOF-README >! \$SCRIPT

So, how do I run SOLVE?

1)  Make sure you have *.unmerged.fmt in this directory

    If you don't, type this:
    cd \`pwd\`
    make SOLVE

2)  Then type this:
    cd \`pwd\`/\${SOLVE_dir}
    solve.com

That's it.

------------------
For your convenience, \$otherSGs have been set up to
run SOLVE in other possible space groups for your crystal.
To try one of these space groups, say \${SG}, do this:

cd \${SG}
./solve.com

To run solve in all these space groups, do this:

cd \`pwd\`/\${SOLVE_dir}
foreach SG ( \$otherSGs )
cd \$SG
./solve.com
cd ..
end

What if it doesn't work?
1)  Try reducing your outer resolution limit
2)  Try getting better values for f' and f'' from your EXAFS
3)  Try commenting out the "refscattfactors" (could be unstable)
4)  Try changeing the "nanomalous" (expected number of sites)
5)  Try eliminating radiation damaged-spots (re-run \$0 with less frames)

For more detailed information, go to the SOLVE homepage at:
netscape http://www.solve.lanl.gov/

EOF-README


set SOLVE_SET_UP

goto Return_from_Setup_SOLVE


























exit
Setup_SHELX:
###############################################################################

  ####   #    #  ######  #       #    #
 #       #    #  #       #        #  #
  ####   ######  #####   #         ##
      #  #    #  #       #         ##
 #    #  #    #  #       #        #  #
  ####   #    #  ######  ######  #    #
     
###############################################################################
#
#   Create SHELX input files
#
###############################################################################
#
# see if shelx is in the path
set possibilities = \`which shelxs |& nawk 'NF==1 && ! /[\\052]/' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l0.3{print \$1+0}'\`
    if("\$temp" != "") set wave = "\$temp"
endif

# this is the only one that works, in my experience
set LATT = "-1"
if("\$SG" =~ [Ii]*) set LATT = -2
if("\$SG" =~ [Rr]*) set LATT = -3
if("\$SG" =~ [Ff]*) set LATT = -4

# create a temporary file of (potentially) unsupported symops
cat << EOF-screwies >! \${tempfile}screwies
17 4 4 P2122 PG222 ORTHORHOMBIC
 X,Y,Z 
 -X,Y,-Z 
 1/2+X,-Y,-Z 
 1/2-X,-Y,Z
17 4 4 P2212 PG222 ORTHORHOMBIC
  X,Y,Z 
  X,1/2-Y,-Z 
 -X,1/2+Y,-Z 
 -X,-Y,Z
18 4 4 P21221 PG222 ORTHORHOMBIC
 X,Y,Z 
 -X,Y,-Z 
 1/2+X,-Y,1/2-Z 
 1/2-X,-Y,1/2+Z
18 4 4 P22121 PG222 ORTHORHOMBIC
 X,Y,Z 
  X,-Y,-Z 
 -X,1/2+Y,1/2-Z 
 -X,1/2-Y,1/2+Z
20 8 4 C2212 PG222 ORTHORHOMBIC
 X,Y,Z 
 -X,1/2+Y,-Z
 X,1/2-Y,-Z
 -X,-Y,Z
 1/2+X,Y,1/2+Z
 1/2-X,1/2+Y,1/2-Z
 1/2+X,1/2-Y,1/2-Z
 1/2-X,-Y,1/2+Z
20 8 4 C2122 PG222 ORTHORHOMBIC
 X,Y,Z 
 1/2+X,-Y,-Z
 1/2-X,-Y,Z
 -X,Y,-Z
 X,1/2+Y,1/2+Z
 1/2+X,1/2-Y,1/2-Z
 1/2-X,1/2-Y,1/2+Z
 -X,1/2+Y,1/2-Z
EOF-screwies


set SCRIPT = "\${SHELX_dir}/shelxs.ins"
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak
cat << EOF-shelin >! \$SCRIPT
 !
 !  Example SHELX input file
 !
TITLE \$TITLE
 ! CELL wavelength A B C a b g
CELL \$wave \$CELL
 ! ZERR sites/cell  SDs of cell
ZERR \$sites   0.001   0.001   0.001   0.00   0.00   0.00

 ! LATT is supposed to be -1 for P, -2 for I, -3 for R, -4 for F
 ! \$SG
LATT \$LATT
 ! symmetry taken from \$CLIBD/symop.lib
EOF-shelin

# try to use MTZ2VARIOUS to get symops
echo "1 1 1 1 1" >! \${tempfile}.hkl
f2mtz hklin \${tempfile}.hkl hklout \${tempfile}.mtz << EOF >& /dev/null
CELL \$CELL
SYMM \$SG
LABOUT H K L F SIGF
CTYPO  H H H F Q
EOF
rm -f \${tempfile}.hkl >& /dev/null
mtz2various hklin \${tempfile}.mtz hklout \${tempfile}.hkl << EOF >& /dev/null
OUTPUT SHELX
LABIN FP=F SIGFP=SIGF
END
EOF
rm -f \${tempfile}.mtz >& /dev/null

grep SYMM \${tempfile}.hkl >&! \${tempfile}.symm
if(\$status) then
    # try to nab symops (sans identity op)
    cat \$CLIBD/symop.lib \${tempfile}screwies |\\
    nawk -v SG=\$SG 'ops{print "SYMM", \$0; --ops}\\
     \$4 == SG  && \$1 < 999 { ops=\$3-1; getline}' |\\
    cat >! \${tempfile}.symm
endif
cat \${tempfile}.symm >> \$SCRIPT
rm -f \${tempfile}.symm
rm -f \${tempfile}.hkl

cat << EOF-shelin >> \$SCRIPT

 ! SFAC Doesn't seem all that important (atom types)
SFAC N \$Ee
 ! sqrt(#atoms) and #sites in CELL
UNIT \$unit \$sites

 ! F/sig>1 and 2theta<180 cutoff
 ! OMIT 1 180

 ! tell SHELX to solve by direct methods
TREF
 ! tell SHELX to solve by Patterson methods
 !PATT
 ! tell SHELX to expand a partial solution
 !TEXP
 !\${Ee}1  2  0.000 0.000 0.000 1 0.05

 ! tell SHELXD to solve by dual-space methods
 !PATS
 !FIND \$SITES
 !MIND -1

 ! giving SHELX delta-intensity data
HKLF 4
 ! giving SHELX delta-F data
 !HKLF 3
END
EOF-shelin

cp \$SCRIPT \${SHELX_dir}/iso.ins
cp \$SCRIPT \${SHELX_dir}/ano.ins
cp \$SCRIPT \${SHELX_dir}/fh.ins
cp \$SCRIPT \${SHELX_dir}/fm.ins
cat \$SCRIPT |\\
nawk -v sites=\$SITES '/SFAC/{print \$1,\$NF} /UNIT/{print \$1,sites*4}\\
     /TREF/{print " ! resolution cutoff"; print " ! SHEL 99 4";\\
      print "PATS";print "FIND",sites; print "MIND -1"; print "NTRY 20";next} {print}' |\\
cat >! \${SHELX_dir}/shelxd.ins

# set up directories for alternative space groups
set ORIGINAL = "\$SCRIPT"

foreach sg ( \$otherSGs )
    set SCRIPT = \${SHELX_dir}/\${sg}/ano.ins
    
    if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak
    if(-e "\${SHELX_dir}/\${sg}") then
	test -d "\${SHELX_dir}/\${sg}"
	if(\$status) then
	    # move the offending file
	    mv \${SHELX_dir}/\${sg} \${SHELX_dir}/\${sg}.file
	endif
    else
	mkdir \${SHELX_dir}/\${sg}
    endif
    
    cat \$CLIBD/symop.lib \${tempfile}screwies |\\
    nawk -v SG=\$sg 'ops{print "newSYMM", \$0; --ops}\\
     \$4 == SG  && \$1 < 999 { ops=\$2-1; getline}' >! \${tempfile}symops

    # replace SG with new one (sg)
    cat \${tempfile}symops "\$ORIGINAL" |\\
    nawk '/^newSYM/{++ops; op[ops]=substr(\$0, 4)} \\
    /^SYMM/{for(i=1;i<=ops;++i){print op[i]}; while(\$0 ~ /^SYMM/){getline}}  ! /SYMM/' |\\
    nawk -v SG=\$SG -v sg=\$sg '\$2==SG{print " ! " sg} \$2 != SG' |\\
    cat >! \$SCRIPT
    
    rm -f \${tempfile}symops
    
    # update other files
    cp \${SCRIPT} \${SHELX_dir}/\${sg}/iso.ins
    cp \${SCRIPT} \${SHELX_dir}/\${sg}/fh.ins
    cat \$SCRIPT |\\
    nawk -v sites=\$SITES '/SFAC/{print \$1,\$NF} /UNIT/{print \$1,sites*4}\\
         /TREF/{print " ! resolution cutoff"; print " ! SHEL 99 4";\\
          print "PATS";print "FIND",sites; print "MIND -1"; print "NTRY 20";next} {print}' |\\
    cat >! \${SHELX_dir}/\${sg}/shelxd.ins
    set temp = \`pwd\`
    cd \${SHELX_dir}/\${sg}
    ln -sf ../ano.hkl ano.hkl
    ln -sf ../iso.hkl iso.hkl
    ln -sf ../fh.hkl fh.hkl >& /dev/null
    cd \$temp
    
end

rm -f \${tempfile}screwies >& /dev/null





##############################################################
# create jiffy for getting I/sigma of SHELX file(s)
##############################################################
set SCRIPT = "\${SHELX_dir}/best_signal.com"
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak
cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#       get best signal of (one or more) shelx hkl files
#       and copy it to best.hkl
#
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set tempfile = \${tempfile}sig.
#
echo -n "" >! \\\${tempfile}signal

# run through all input files
set i = 0
while(\\\$i < \\\$#argv)
    @ i = ( \\\$i + 1 )

    echo -n "\\\$argv[\\\$i] " >> \\\${tempfile}signal
    
    # get mean I/sigma of this shelx file
    cat \\\$argv[\\\$i] |\\\\
    nawk '\\\$5+0 != 0 {++n; sum+=\\\$4/\\\$5} END{print sum/n}' |\\\\
    cat >> \\\${tempfile}signal
end

# get best, overall signal file
set best = \\\`sort -nr -k2 \\\${tempfile}signal | nawk 'NR==1{print \\\$1}'\\\`
# copy it to new location
cp \\\$best best.hkl

rm -f \\\${tempfile}signal >& /dev/null

exit

EOF-script
chmod a+x \$SCRIPT







##############################################################
# create SHELX hkl converter script
##############################################################
set SCRIPT = \${SHELX_dir}/mtz2SHELX.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Conversion script to output I+ - I- from  an mtz  in SHELX format
#              OR output IMEAN - IMEAN from two mtzs in SHELX format
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set ano_outfile = "SHELX_ano.hkl"
set iso_outfile = "SHELX_iso.hkl"
#
set tempfile = \${tempfile}mtz2shelx
#
goto Setup
#######################################
#
#   usage: \$SCRIPT [native.mtz] derivative.mtz
#
#######################################
ReturnFromSetup:

Dano:
echo "outputting anomalous differences from \\\$infiles in SHELX format as \\\$ano_outfile"

# SHELX anomalous
mtz2various hklin \\\$infiles \\
            hklout \\\${tempfile}hkl << EOF-shelx1
OUTPUT SHELX
#LABIN FP=I(-) SIGFP=SIGI(-) FPH=I(+) SIGFPH=SIGI(+)
FSQUARED
LABIN DP=DANO SIGDP=SIGDANO
END
EOF-shelx1
if(\\\$status) exit 3

# strip off non-SHELX lines
cat \\\${tempfile}hkl | nawk '\\\$1 !~ /[A-Z]/ && \\\$5 != 0' >! \\\$ano_outfile

# print out mean DI/sigma
nawk '(NF == 6)&&(\\\$5 != 0){sum += \\\$4/\\\$5; ++n} END{if(n) print "Dano/sig =", sum/n}' \\\$ano_outfile

goto cleanup

Diso:
# SHELX can also use isomorphous differences

echo "outputting isomorphous difference between \\\$infiles in SHELX format as \\\$iso_outfile"
echo "\\\$infiles had better be on the same scale! "

# do difference HKLs
cad HKLIN1 \\\$infiles[1]                     \\
    HKLIN2 \\\$infiles[2]                     \\
    HKLOUT \\\${tempfile}shelx.mtz  << eof-cad-shelx
LABI FILE 1 E1=IMEAN E2=SIGIMEAN
CTYP FILE 1 E1=J     E2=Q
LABO FILE 1 E1=I1    E2=SIGI1
        
LABI FILE 2 E1=IMEAN E2=SIGIMEAN
CTYP FILE 2 E1=J     E2=Q
LABO FILE 2 E1=I2    E2=SIGI2
eof-cad-shelx
if(\\\$status) exit 2

# Dump difference in SHELX format
mtz2various hklin \\\${tempfile}shelx.mtz     \\
            hklout \\\${tempfile}hkl  << EOF-shelx2
OUTPUT SHELX
LABIN FP=I2 SIGFP=SIGI2 FPH=I1 SIGFPH=SIGI1
END
EOF-shelx2
if(\\\$status) exit 3

# strip off non-SHELX lines
cat \\\${tempfile}hkl | nawk '\\\$1 !~ /[A-Z]/ && \\\$5 != 0' >! \\\$iso_outfile

# print out mean DI/sigma
nawk '(NF == 6)&&(\\\$5 != 0){sum += \\\$4/\\\$5; ++n} END{if(n) print "Diso/sig =", sum/n}' \\\$iso_outfile


cleanup:
rm -f \\\${tempfile}shelx.mtz >& /dev/null
rm -f \\\${tempfile}hkl       >& /dev/null

exit

#####################################################################

Setup:
set infiles
foreach arg ( \\\$* )
    if((\\\$arg =~ *.mtz)&&(-e \\\$arg)) then
	if(\\\$arg =~ *.mtz) set infiles = \\\`echo \\\$arg \\\$infiles\\\`
    endif
end

if (\\\$#infiles == 1) then
    # do something to identify Is?
    goto Dano
endif

if (\\\$#infiles == 2) then
    # do something to identify Is?
    goto Diso
endif

# no files, exit
cat << EOF
usage: \\\$0 native.mtz derivative.mtz	(output DISO in \\\$iso_outfile)
       OR
       \\\$0 derivative.mtz		(output DANO in \\\$ano_outfile)
       
NOTE: NO scaling will be done.  
      Make sure your MTZs are on the same scale.

EOF
exit 9

goto ReturnFromSetup


EOF-script
chmod a+x \$SCRIPT










##############################################################
# create SHELX atom converter script
##############################################################
set SCRIPT = \$SHELX_dir/SHELX2pdb.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
# converts SHELXL output into PDB format
#
#  B = 79*U^2
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#

if(! -e "\\\$1") then
    echo "usage: \\\$0 shelx.res [outfile.pdb]"
    exit
endif
if(\\\$2 !~ *.pdb) then
    set outfile = \\\$1
    set outfile = \\\`basename \\\$outfile .ins\\\`
    set outfile = \\\`basename \\\$outfile .res\\\`
    set outfile = \\\`basename \\\$outfile .lst\\\`".pdb"
else
    set outfile = \\\$2
endif



set CELL = \\\`nawk '\\\$1=="CELL"{print \\\$3, \\\$4, \\\$5, \\\$6, \\\$7, \\\$8}' \\\$1\\\`

cat \\\$1 |\\
nawk '/[Ss][Ff][Aa][Cc]/{Ee=toupper(\\\$NF)} (NF==7 && \\\$6 ~ /0000/){++i; \\
printf("%5d%10.5f%10.5f%10.5f%10.5f%5.2f   35%10d%2s   MTL M\\n",\\
i, \\\$3,\\\$4,\\\$5, 79*\\\$7*\\\$7, \\\$6-10, i, Ee)}' |\\
cat >! temp\\\$\\\$.frac

coordconv xyzin temp\\\$\\\$.frac xyzout \\\$outfile << EOF >> temp\\\$\\\$.log
CELL \\\$CELL
INPUT FRAC
OUTPUT PDB ORTH 1
END
EOF
if(! \\\$status) then
    echo "PDB version of SHELX sites in \\\$1 is: \\\$outfile"
else
    cat temp\\\$\\\$.*
    
    echo "problem converting \\\$1 to \\\$outfile (see above for explanation)"
endif
rm -f temp\\\$\\\$.*

EOF-script
chmod a+x \$SCRIPT


















###############################################################################
#
#	auto-run SHELX ?
#
###############################################################################
set SCRIPT = \$SHELX_dir/shelx.com
if(! -e \$SCRIPT) cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
echo "not done, sorry"
EOF-script
chmod a+x \$SCRIPT










#
# Create the README file
set SCRIPT = "\${SHELX_dir}/README"
cat << EOF-README >! \$SCRIPT

So, how do you use SHELX?

If you are in a hurry, type this:
\$SHELXS ano
and
\$SHELXS iso

to locate heavy atom sites using your best anomalous differences, or 
your best dispersive differences (respectively).

------------------
Key concepts:
1)  Shelx needs an input file (ALWAYS *.ins) and an HKL file (ALWAYS *.hkl)
2)  The prefixes of these files MUST be the same
3)  Shelx produces two output files: prefix.res and prefix.lst
	prefix.res contains the atom sites
	prefix.lst is the "log" file
4)  the UNIT and ZERR lines in prefix.ins should indicate the expected number
	of metal sites in the CELL, not the ASU
	UNIT is for metal:protein scaling and
	ZERR controls site picking
5)  in prefix.lst, lower CFOMs are BETTER


------------------
How do I know if it worked?
1)  That's a good question, it can be hard to tell.
2)  a CFOM below 0.1 is really good.
3)  make sure your sites are not on special positions (s.o.f.==1)
4)  Calculate Patterson vectors from SHELX's sites, and 
    see if they are consistent with your Patterson peaks.


For more detailed information, go to the SHELX homepage at:

netscape http://shelx.uni-ac.gwdg.de/SHELX/

EOF-README

set SHELX_SET_UP

goto Return_from_Setup_SHELX

























exit
Setup_XPLOR:
##############################################################

 #    #  #####   #        ####   #####
  #  #   #    #  #       #    #  #    #
   ##    #    #  #       #    #  #    #
   ##    #####   #       #    #  #####
  #  #   #       #       #    #  #   #
 #    #  #       ######   ####   #    #

##############################################################
# create XPLOR/CNS hkl converter script
##############################################################
set SCRIPT = \${XPLOR_dir}/mtz2XPLOR.com
if((-e "\$SCRIPT")&&(! \$?FRUGAL)) mv \${SCRIPT} \${SCRIPT}.bak

cat << EOF-script >! \$SCRIPT
#! /bin/csh -f
#
#  Conversion script to output F+ and F- in XPLOR format for one wavelength
#
#
set nawk = \$nawk
\\\$nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) set nawk = awk
alias nawk \\\$nawk
#
set outfile = XPLOR.fobs
set tempfile = \${tempfile}mtz2xplor
#
#
foreach arg ( \\\$* )
    if((! \\\$?infile)&&(-e \\\$arg)) then
    if(\\\$arg =~ *.mtz) set infile = \\\$arg
    endif
end
if(! \\\$?infile) exit 9
################################
#
#   usage: \$SCRIPT blah.mtz
#	only works on merged MTZs
#
################################
# this is the mtz2various format to use, you need 
mtz2various hklin \\\$infile hklout \\\${tempfile}fobs << EOF
OUTPUT XPLOR
LABIN FP=F SIGFP=SIGF DP=DANO SIGDP=SIGDANO ISYM=ISYM
END
EOF
if(\\\$status) exit 9

set NREF = \\\`wc \\\${tempfile}fobs | nawk '{print \\\$1 +1}'\\\`

echo " NREFlections= \\\$NREF"                                         >! \\\$outfile
echo " ANOMalous=TRUE"                                              >> \\\$outfile
echo " DECLare NAME=FOBS    DOMAin=RECIprocal   TYPE=COMP END"      >> \\\$outfile
echo " DECLare NAME=SIGMA   DOMAin=RECIprocal   TYPE=REAL END"      >> \\\$outfile
cat \\\${tempfile}fobs                                                 >> \\\$outfile

rm -f \\\${tempfile}fobs >& /dev/null
rm -f MTZ2VSCR >& /dev/null

EOF-script
chmod a+x \$SCRIPT




#
# Make a README file
set SCRIPT = "\${XPLOR_dir}/README"
cat << EOF-README >! \$SCRIPT

So, what's all this then?

    The files matching *.fobs are your merged F+ and F- data in 
X-PLOR/CNS format.  Don't see any files matching *.fobs?  Type 
"make XPLOR" and the Elves will do whatever it takes to create 
them.
    These files have been formatted to feed directly into X-PLOR 3.1's 
"mad_merge.inp" procedure, which should be located in the 
\\\${XPLOR}/tutorial/mad/ directory (where \\\${XPLOR} is wherever your 
system has X-PLOR installed.)

------------------
Briefly, mad_merge.inp uses the actual anomalous and dispersive
differences of a MAD data set to refine a protein structure.  
In this case, phase calculation is circumvented by refining 
calculated anomalous and dispersive differences directly against
F+ and F- of each wavelength.  JMH has not gotten this to work, 
but when he does, it will be implemented here.

For more detailed information, go to the X-PLOR homepage at:
netscape http://xplor.csb.yale.edu/


EOF-README

set XPLOR_SET_UP
goto Return_from_Setup_XPLOR















































exit
MTZsearch:
###############################################################################

 #    #   #####  ######           ####   ######    ##    #####    ####   #    #
 ##  ##     #        #           #       #        #  #   #    #  #    #  #    #
 # ## #     #       #             ####   #####   #    #  #    #  #       ######
 #    #     #      #                  #  #       ######  #####   #       #    #
 #    #     #     #              #    #  #       #    #  #   #   #    #  #    #
 #    #     #    ######           ####   ######  #    #  #    #   ####   #    #

###############################################################################
#
#   actively search for measured x-ray data
#
###############################################################################

set number_of_mtzs = 0
#unset FIRSTIME

# start looking for MTZs
echo "Looking for raw data ..."
#foreach place ( \$* . ~/ )
foreach place ( \$* . )
    # make sure it's a directory
    set place = \`ls -lnd \$place |& nawk '/^d/{print \$NF}'\`
    
    # squash known bad paths
    foreach baddie ( \$baddirs )
	if("\$place" =~ \$baddie*) place = ""
    end
    
    if((-e "\$place")&&(\$number_of_mtzs == 0)) then
	# search this tree for some mtzs
	find \$place -name '*.mtz' -print |&\\
	nawk 'NF==1 && /.mtz\$/' >&! \${tempfile}
	
	# see if we got anything
	set temp = \`cat \${tempfile} | wc -l\`
	if("\$temp" > 0) then
	    # prepare to analyze these mtzs
	    mv \${tempfile} \${tempfile}mtzs
	    
	    # stop search after successful find
	    set number_of_mtzs = "\$temp"
	endif
    endif
end

# remember that we have done this
set SEARCHED_FOR_MTZS

goto GetMTZinfo












































exit
Unwrap_Awk_Scripts:
################################################################################

 #    #  #    #  #    #  #####     ##    #####
 #    #  ##   #  #    #  #    #   #  #   #    #
 #    #  # #  #  #    #  #    #  #    #  #    #
 #    #  #  # #  # ## #  #####   ######  #####
 #    #  #   ##  ##  ##  #   #   #    #  #
  ####   #    #  #    #  #    #  #    #  #

################################################################################
#   Unwrap complex AWK programs used by Elves
################################################################################

cat << EOF-sequence >! \${tempfile}sequencer.awk
#! \$nawk -f
#
#   Process/identify protein sequences in a text/pdb file
#   as > 20 consecutive, aa letters
#
#   plus a few other goodies, such as monoisotopic mass, identifying 
#   chemically unstable sequences, and common cleavage sites (using chop=yes)
#
#
BEGIN {


    # average mass
    H  =  1.007947
    C  = 12.0111  
    N  = 14.006747
    O  = 15.999943
    P  = 30.973762
    S  = 32.0666  
    Cl = 35.45279 
    Se = 78.963   

    # residue masses -NH-CH(R)-CO-
    aMass["G"] =  2*H+2*C+N+O+ H
    aMass["A"] =  2*H+2*C+N+O+ C+3*H
    aMass["V"] =  2*H+2*C+N+O+ C+H + 2*(C+3*H)
    aMass["I"] =  2*H+2*C+N+O+ C+H + C+2*H + 2*(C+3*H)
    aMass["L"] =  2*H+2*C+N+O+ C+2*H + C+H + 2*(C+3*H)
    aMass["D"] =  2*H+2*C+N+O+ C+2*H + C + 2*O  +H
    aMass["N"] =  2*H+2*C+N+O+ C+2*H + C + O+N+2*H
    aMass["E"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C + 2*O  +H
    aMass["Q"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C + O+N+2*H
    aMass["R"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + N + C + 2*(N+ 2*H)
    aMass["K"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + C+2*H + N+2*H
    aMass["M"] =  2*H+2*C+N+O+ C+2*H + C+2*H + S     + C+3*H
    aMass["C"] =  2*H+2*C+N+O+ C+2*H + S+H
    aMass["S"] =  2*H+2*C+N+O+ C+2*H + O+H
    aMass["T"] =  2*H+2*C+N+O+ C+H   + O+H   + C+3*H
    aMass["H"] =  2*H+2*C+N+O+ C+2*H + C     + C+H + N+H + C+H + N 
    aMass["W"] =  2*H+2*C+N+O+ C+2*H + 3*C + 5*(C+H) + N+H
    aMass["F"] =  2*H+2*C+N+O+ C+2*H + C +   5*(C+H)
    aMass["Y"] =  2*H+2*C+N+O+ C+2*H + C +   5*(C+H) + O
    aMass["P"] =  1*H+2*C+N+O+ 3*(C+2*H)

    # monoisotopic mass (most abundant isotope)
    H  = 1.007825 
    C  = 12.00000 
    N  = 14.003074
    O  = 15.994915
    P  = 30.973762
    S  = 31.972070
    Cl = 34.968852
    Se = 79.916520

    # residue masses -NH-CH(R)-CO-
    iMass["G"] =  2*H+2*C+N+O+ H
    iMass["A"] =  2*H+2*C+N+O+ C+3*H
    iMass["V"] =  2*H+2*C+N+O+ C+H + 2*(C+3*H)
    iMass["I"] =  2*H+2*C+N+O+ C+H + C+2*H + 2*(C+3*H)
    iMass["L"] =  2*H+2*C+N+O+ C+2*H + C+H + 2*(C+3*H)
    iMass["D"] =  2*H+2*C+N+O+ C+2*H + C + 2*O  +H
    iMass["N"] =  2*H+2*C+N+O+ C+2*H + C + O+N+2*H
    iMass["E"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C + 2*O  +H
    iMass["Q"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C + O+N+2*H
    iMass["R"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + N + C + 2*(N+ 2*H)
    iMass["K"] =  2*H+2*C+N+O+ C+2*H + C+2*H + C+2*H + C+2*H + N+2*H
    iMass["M"] =  2*H+2*C+N+O+ C+2*H + C+2*H + S     + C+3*H
    iMass["C"] =  2*H+2*C+N+O+ C+2*H + S+H
    iMass["S"] =  2*H+2*C+N+O+ C+2*H + O+H
    iMass["T"] =  2*H+2*C+N+O+ C+H   + O+H   + C+3*H
    iMass["H"] =  2*H+2*C+N+O+ C+2*H + C     + C+H + N+H + C+H + N 
    iMass["W"] =  2*H+2*C+N+O+ C+2*H + 3*C + 5*(C+H) + N+H
    iMass["F"] =  2*H+2*C+N+O+ C+2*H + C +   5*(C+H)
    iMass["Y"] =  2*H+2*C+N+O+ C+2*H + C +   5*(C+H) + O
    iMass["P"] =  1*H+2*C+N+O+ 3*(C+2*H)
    iMass["formyl"]=  C + O
    iMass["p"] =  P + 3*O
}

# read sequence of a PDB
/^ATOM / {pdb = 1}
pdb && substr(\\\$0,12,5) == "  CA " {

    Restype = substr(\\\$0, 18, 3)
    Segid   = substr(\\\$0, 22, 1)    	# O/Brookhaven-style segment ID
    Resnum  = substr(\\\$0, 23, 4)+0
    
    # check for breaks
    if((Segid != lastSegid)||(nextResnum != Resnum)) {
	# break in chain
	seq = seq " "
	lastSegid = Segid
    }
    nextResnum = Resnum +1

    # translate three-letter code to one letter
    if(Restype == "ALA") seq = seq "A"
    if(Restype == "CYS") seq = seq "C"
    if(Restype == "ASP") seq = seq "D"
    if(Restype == "GLU") seq = seq "E"
    if(Restype == "PHE") seq = seq "F"
    if(Restype == "GLY") seq = seq "G"
    if(Restype == "HIS") seq = seq "H"
    if(Restype == "ILE") seq = seq "I"
    if(Restype == "LYS") seq = seq "K"
    if(Restype == "LEU") seq = seq "L"
    if(Restype == "MET") seq = seq "M"
    if(Restype == "MSE") seq = seq "M"
    if(Restype == "ASN") seq = seq "N"
    if(Restype == "PRO") seq = seq "P"
    if(Restype == "GLN") seq = seq "Q"
    if(Restype == "ARG") seq = seq "R"
    if(Restype == "SER") seq = seq "S"
    if(Restype == "THR") seq = seq "T"
    if(Restype == "VAL") seq = seq "V"
    if(Restype == "TRP") seq = seq "W"
    if(Restype == "TYR") seq = seq "Y"    
}

# don't do other kinds of search in a PDB file
pdb {next}

(length(\\\$0) > 9 || seq != "") && ! /^>/ {
#{
    # remove leading spaces
    line = ""
    for(i=1;i= 20)
    {
	# look for all the horrible things that can happen to the peptide
	acid = ""
	base = ""
	race = ""
	pyroQ = ""
	CNBr = ""

	factorXa = ""
	chymotrypsin = ""
	endoproteinaseDN = ""
	endoproteinaseKC = ""
	thrombin = ""
	trypsin = ""
	pepsin = ""
	V8 = ""

	# weigh this chain
	weight = Met = His = Cys = A280 = "";
	weight = O + 3*H;
	mass   = O + 3*H;
	for(i=1;i<=length(sequence[n]);++i)
	{
	    c = substr(sequence[n], i, 1);
	    
	    # weigh this chain
	    weight += aMass[c];
	    mass   += aMass[c];
	
	    # count potentially derivitized residues
	    if(c == "M") ++Met;
	    if(c == "C") ++Cys;
	    if(c == "H") ++His;
	    
	    # add up (denatured) extinction coefficient
	    if(c == "W") A280 += 5600
	    if(c == "Y") A280 += 1400
	    if(c == "F") A280 += 197
	    
	    # chemical instabilities  (add up single-cleavage MWs)
	    if(c == "M" )                       CNBr = CNBr " " mass
	    if(substr(sequence[n],i,2) == "DP") acid = acid " " mass
	    if(substr(sequence[n],i,2) == "NG") base = base " " mass
	    if(substr(sequence[n],i,2) == "NG") race = race ", " i
	    if(substr(sequence[n],1,1) == "Q") pyroQ = 1
	    if((substr(sequence[n],1,1) == "M")&&(substr(sequence[n],2,1) == "Q")) pyroQ = 2

	    # proteolytic recognition sites (add up single-cleavage MWs)?
	    if(substr(sequence[n],i-3,4) == "IEGR") factorXa = factorXa  " " mass
	    if(substr(sequence[n],i+1,1) == "D") endoDN = endoDN " " mass
	    if(c ~ /[Y,F,W]/)     chymotrypsin = chymotrypsin    " " mass
#	    if(c ~ /[L,M,A,N,E]/) chymotrypsin = chymotrypsin    " " mass "*"
	    if(c ~ /[K]/)               endoKC = endoKC          " " mass
	    if(c ~ /[R]/)             thrombin = thrombin        " " mass
	    if(c ~ /[R,K]/)            trypsin = trypsin         " " mass
	    if(c ~ /[F,L]/)             pepsin = pepsin          " " mass
#	    if(c ~ /[Y,W,I,M]/)         pepsin = pepsin          " " mass "*"
	    if(c ~ /[E]/)                   V8 = V8              " " mass
	    if(c ~ /[E]/)                  V82 = V82             " " mass
	    if(c ~ /[D]/)                  V82 = V82             " " mass
	}
	
	# finish off cleavages
	acid = acid " " mass
	base = base " " mass
	CNBr = CNBr " " mass

	factorXa = factorXa         " " mass
	chymotrypsin = chymotrypsin " " mass
	endoDN = endoDN             " " mass
	endoKC = endoKC             " " mass
	thrombin = thrombin         " " mass
	trypsin = trypsin           " " mass
	pepsin = pepsin             " " mass
	V8 = V8                     " " mass
	
	
	# we have found an acceptable protein sequence
	print mass " Da chain: "
	l=length(sequence[n])
	while(length(sequence[n]) > 0)
	{
	    # actually print out sequence here
	    print substr(sequence[n], 1, 80)
	    sequence[n] = substr(sequence[n], 81)
	}
	print ""
	print l "aa"
	print Met+0 "met"
	print Cys+0 "cys"
	print His+0 "his"
	print ""
	printf "denatured A(280nm) = %.4f*l*c (c in g/L)\\\\n", A280/weight
	printf "    SeMET MAD Rano = %.1f%%\\\\n", 100*(M*8^2)/(7^2 * (weight/14))
	print ""
	
	f=split(acid base, Split)
	if((f>2) || pyroE != "")
	{
	    print "Chemical Instabilities: "
	}
	f=split(acid, Split)
	if(f>1)
	{
	    printf "acid (D*P):                       "
	    for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	    print ""
	}
	f=split(base, Split)
	if(f>1)
	{
	    printf "base (N*G):                       "
	    for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	    print ""
	    print "racemization hazard at" substr(race,2)
	}
	if(pyroQ)
	{
	    print "residue " pyroQ " could form an N-cyclized glutamine "
	}

	if(chop)
	{
	    print ""
	    
	    f=split(CNBr, Split)
	    if(f>1)
	    {
		printf "CNBr (M*):                        "
		for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
		print ""
	    }
	    print ""
	    print "Common proteases: "
	    f=split(factorXa, Split)
	    if(f>1)
	    {
	        printf "factorXa (IEGR*):                 "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(thrombin, Split)
	    if(f>1)
	    {
	        printf "thrombin (R*):                    "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(trypsin, Split)
	    if(f>1)
	    {
	        printf "trypsin (R*, K*):                 "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(endoKC, Split)
	    if(f>1)
	    {
	        printf "endoproteinase Lys-C (K*):        "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(endoDN, Split)
	    if(f>1)
	    {
	        printf "endoproteinase Asp-N (*D):        "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(chymotrypsin, Split)
	    if(f>1)
	    {
	        printf "chymotrypsin (W*,Y*,F*, +others): "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(pepsin, Split)
	    if(f>1)
	    {
	        printf "pepsin (F*, L*, +others):         "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(V8, Split)
	    if(f>1)
	    {
	        printf "V8 protease (E*):                 "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	    f=split(V82, Split)
	    if(f>1)
	    {
	        printf "V8 protease (E*,D*):              "
	        for(i=1;i<=f;++i) printf Split[i] - Split[i-1] " "
	        print ""
	    }
	}
    }
}

EOF-sequence
chmod a+x \${tempfile}sequencer.awk

















cat << EOF-elements >! \${tempfile}elements.awk
#! \$nawk -f
#
#	General-purpose database for equating elements
#	with their x-ray absorption edges (and f', f" values)
#
#	if the first word on the line is an element symbol or name,
#	    an x-ray spectrum for that element will be displayed
#
#	if the first thing on the line is a number (energy or wavelength)
#	    the element with an edge closest to that energy will be displayed
#
#	if the line is an element and a number (energy or wavelength)
#	    the edge of the provided element closest to that energy will be given.
#
#	nothing gets printed if no match is found
#
BEGIN{
#   at no      Sym Name
element[1]   = "H  Hydrogen     "
element[2]   = "He Helium       "
element[3]   = "Li Lithium      "
element[4]   = "Be Beryllium    "
element[5]   = "B  Boron        "
element[6]   = "C  Carbon       "
element[7]   = "N  Nitrogen     "
element[8]   = "O  Oxygen       "
element[9]   = "F  Fluorine     "
element[10]  = "Ne Neon         "
element[11]  = "Na Sodium       "
element[12]  = "Mg Magnesium    "
element[13]  = "Al Aluminum     "
element[14]  = "Si Silicon      "
element[15]  = "P  Phosphorus   "
element[16]  = "S  Sulfur       "
element[17]  = "Cl Chlorine     "
element[18]  = "Ar Argon        "
element[19]  = "K  Potassium    "
element[20]  = "Ca Calcium      "
element[21]  = "Sc Scandium     "
element[22]  = "Ti Titanium     "
element[23]  = "V  Vanadium     "
element[24]  = "Cr Chromium     "
element[25]  = "Mn Manganese    "
element[26]  = "Fe Iron         "
element[27]  = "Co Cobalt       "
element[28]  = "Ni Nickel       "
element[29]  = "Cu Copper       "
element[30]  = "Zn Zinc         "
element[31]  = "Ga Gallium      "
element[32]  = "Ge Germanium    "
element[33]  = "As Arsenic      "
element[34]  = "Se Selenium     "
element[35]  = "Br Bromine      "
element[36]  = "Kr Krypton      "
element[37]  = "Rb Rubidium     "
element[38]  = "Sr Strontium    "
element[39]  = "Y  Yttrium      "
element[40]  = "Zr Zirconium    "
element[41]  = "Nb Niobium      "
element[42]  = "Mo Molybdenum   "
element[43]  = "Tc Technetium   "
element[44]  = "Ru Ruthenium    "
element[45]  = "Rh Rhodium      "
element[46]  = "Pd Palladium    "
element[47]  = "Ag Silver       "
element[48]  = "Cd Cadmium      "
element[49]  = "In Indium       "
element[50]  = "Sn Tin          "
element[51]  = "Sb Antimony     "
element[52]  = "Te Tellurium    "
element[53]  = "I  Iodine       "
element[54]  = "Xe Xenon        "
element[55]  = "Cs Cesium       "
element[56]  = "Ba Barium       "
element[57]  = "La Lanthanum    "
element[58]  = "Ce Cerium       "
element[59]  = "Pr Praseodymium "
element[60]  = "Nd Neodymium    "
element[61]  = "Pm Promethium   "
element[62]  = "Sm Samarium     "
element[63]  = "Eu Europium     "
element[64]  = "Gd Gadolinium   "
element[65]  = "Tb Terbium      "
element[66]  = "Dy Dysprosium   "
element[67]  = "Ho Holmium      "
element[68]  = "Er Erbium       "
element[69]  = "Tm Thulium      "
element[70]  = "Yb Ytterbium    "
element[71]  = "Lu Lutetium     "
element[72]  = "Hf Hafnium      "
element[73]  = "Ta Tantalum     "
element[74]  = "W  Tungsten     "
element[75]  = "Re Rhenium      "
element[76]  = "Os Osmium       "
element[77]  = "Ir Iridium      "
element[78]  = "Pt Platinum     "
element[79]  = "Au Gold         "
element[80]  = "Hg Mercury      "
element[81]  = "Tl Thallium     "
element[82]  = "Pb Lead         "
element[83]  = "Bi Bismuth      "
element[84]  = "Po Polonium     "
element[85]  = "At Astatine     "
element[86]  = "Rn Radon        "
element[87]  = "Fr Francium     "
element[88]  = "Ra Radium       "
element[89]  = "Ac Actinium     "
element[90]  = "Th Thorium      "
element[91]  = "Pa Protactinium "
element[92]  = "U  Uranium      "
element[93]  = "Np Neptunium    "
element[94]  = "Pu Plutonium    "
element[95]  = "Am Americium    "
element[96]  = "Cm Curium       "
element[97]  = "Bk Berkelium    "
element[98]  = "Cf Californium  "
element[99]  = "Es Einsteinium  "
element[100] = "Fm Fermium      "
element[101] = "Md Mendelevium  "
element[102] = "No Nobelium     "
element[103] = "Lr Lawrencium   "

# x-ray edge information (condensed to "interesting" points)
F["H  "  1] = "1   H  Hydrogen         -     -       -    "
F["He "  1] = "2   He Helium           -     -       -    "
F["Li "  1] = "3   Li Lithium          -     -       -    "
F["Be "  1] = "4   Be Beryllium        -     -       -    "
F["B  "  1] = "5   B  Boron            -     -       -    "
F["C  "  1] = "6   C  Carbon           -     -       -    "
F["N  "  1] = "7   N  Nitrogen         -     -       -    "
F["O  "  1] = "8   O  Oxygen           -     -       -    "
F["F  "  1] = "9   F  Fluorine         -     -       -    "
F["Ne "  1] = "10  Ne Neon             -     -       -    "
F["Na "  1] = "11  Na Sodium           -     -       -    "
F["Mg "  1] = "12  Mg Magnesium        -     -       -    "
F["Al "  1] = "13  Al Aluminum         -     -       -    "
F["Si "  1] = "14  Si Silicon          -     -       -    "
F["P  "  3] = "15  P  Phosphorus    2148   -7.423   4.112 edge"
F["S  "  3] = "16  S  Sulfur        2475   -7.264   4.104 edge"
F["Cl "  3] = "17  Cl Chlorine      2825   -7.487   4.091 edge"
F["Ar "  4] = "18  Ar Argon         3205   -7.788   4.074 edge"
F["K  "  4] = "19  K  Potassium     3610   -7.584   4.063 edge"
F["Ca "  6] = "20  Ca Calcium       4041   -7.499   4.053 edge"
F["Sc "  6] = "21  Sc Scandium      4495   -7.856   4.030 edge"
F["Ti "  6] = "22  Ti Titanium      4969   -7.703   4.008 edge"
F["V  "  7] = "23  V  Vanadium      5468   -7.623   3.995 edge"
F["Cr "  7] = "24  Cr Chromium      5992   -7.701   3.973 edge"
F["Mn "  8] = "25  Mn Manganese     6542   -7.670   3.962 edge"
F["Fe "  9] = "26  Fe Iron          7115   -7.712   3.950 edge"
F["Co "  9] = "27  Co Cobalt        7711   -8.149   3.939 edge"
F["Ni " 10] = "28  Ni Nickel        8335   -8.132   3.920 edge"
F["Cu " 10] = "29  Cu Copper        8981   -8.209   3.901 edge"
F["Zn " 11] = "30  Zn Zinc          9661   -8.112   3.896 edge"
F["Ga " 12] = "31  Ga Gallium      10370   -7.949   3.892 edge"
F["Ge " 13] = "32  Ge Germanium    11106   -7.981   3.881 edge"
F["As " 13] = "33  As Arsenic      11869   -8.255   3.865 edge"
F["Se " 14] = "34  Se Selenium     12660   -8.320   3.846 edge"
F["Br " 15] = "35  Br Bromine      13476   -8.289   3.826 edge"
F["Kr " 16] = "36  Kr Krypton      14328   -8.256   3.806 edge"
F["Rb " 17] = "37  Rb Rubidium     15200  -10.436   3.787 edge"
F["Sr " 18] = "38  Sr Strontium    16107   -8.266   3.774 edge"
F["Y  " 19] = "39  Y  Yttrium      17041   -8.191   3.754 edge"
F["Zr " 19] = "40  Zr Zirconium    18000   -8.283   3.736 edge"
F["Nb " 20] = "41  Nb Niobium      18988   -8.288   3.714 edge"
F["Mo " 21] = "42  Mo Molybdenum   20000   -9.878   3.698 edge"
F["Tc " 23] = "43  Tc Technetium   21046   -8.489   3.680 edge"
F["Ru " 24] = "44  Ru Ruthenium    22120   -8.164   3.665 edge"
F["Rh " 25] = "45  Rh Rhodium      23222   -8.459   3.650 edge"
F["Pd " 26] = "46  Pd Palladium    24353   -8.219   3.633 edge"
F["Ag "  4] = "47  Ag Silver        3354  -20.966  10.518 edge"
F["Ag "  5] = "47  Ag Silver        3526  -16.055  13.800 edge"
F["Ag "  6] = "47  Ag Silver        3808  -10.003  14.611 edge"
F["Cd "  4] = "48  Cd Cadmium       3540  -21.398  10.767 edge"
F["Cd "  5] = "48  Cd Cadmium       3730  -15.432  13.792 edge"
F["Cd "  7] = "48  Cd Cadmium       4021   -9.699  14.245 edge"
F["In "  4] = "49  In Indium        3733  -21.152  11.048 edge"
F["In "  5] = "49  In Indium        3941  -15.141  13.784 edge"
F["In "  7] = "49  In Indium        4240   -9.690  13.866 edge"
F["Sn "  6] = "50  Sn Tin           4159  -14.958  13.683 edge"
F["Sb "  6] = "51  Sb Antimony      4135  -21.027  11.070 edge"
F["Sb "  8] = "51  Sb Antimony      4383  -14.902  13.571 edge"
F["Te "  6] = "52  Te Tellurium     4344  -21.057  11.006 edge"
F["Te "  8] = "52  Te Tellurium     4615  -14.559  13.442 edge"
F["I  "  6] = "53  I  Iodine        4560  -20.634  10.936 edge"
F["I  "  8] = "53  I  Iodine        4855  -14.434  13.310 edge"
F["Xe "  6] = "54  Xe Xenon         4785  -20.563  10.874 edge"
F["Xe "  9] = "54  Xe Xenon         5106  -14.540  13.185 edge"
F["Cs "  7] = "55  Cs Cesium        5014  -21.106  10.876 edge"
F["Cs "  9] = "55  Cs Cesium        5362  -14.233  13.120 edge"
F["Ba "  7] = "56  Ba Barium        5250  -20.109  10.809 edge"
F["Ba "  9] = "56  Ba Barium        5626  -14.171  12.992 edge"
F["La "  7] = "57  La Lanthanum     5485  -20.405  10.570 edge"
F["La "  9] = "57  La Lanthanum     5893  -14.030  12.840 edge"
F["Ce "  7] = "58  Ce Cerium        5726  -20.237  10.734 edge"
F["Ce " 10] = "58  Ce Cerium        6167  -13.634  12.698 edge"
F["Pr "  7] = "59  Pr Praseodymium  5967  -20.069  10.711 edge"
F["Pr " 10] = "59  Pr Praseodymium  6443  -13.610  12.615 edge"
F["Nd "  8] = "60  Nd Neodymium     6210  -20.540  10.661 edge"
F["Nd " 10] = "60  Nd Neodymium     6724  -13.655  12.624 edge"
F["Pm "  8] = "61  Pm Promethium    6462  -19.898  10.625 edge"
F["Pm " 11] = "61  Pm Promethium    7015  -13.710  12.558 edge"
F["Sm "  8] = "62  Sm Samarium      6719  -19.794  10.651 edge"
F["Sm " 11] = "62  Sm Samarium      7314  -13.591  12.442 edge"
F["Eu "  8] = "63  Eu Europium      6979  -20.382  10.648 edge"
F["Eu " 11] = "63  Eu Europium      7620  -13.183  12.345 edge"
F["Gd "  9] = "64  Gd Gadolinium    7245  -20.213  10.609 edge"
F["Gd " 11] = "64  Gd Gadolinium    7933  -13.095  12.185 edge"
F["Tb "  9] = "65  Tb Terbium       7517  -19.488  10.612 edge"
F["Tb " 12] = "65  Tb Terbium       8254  -13.276  12.233 edge"
F["Dy "  9] = "66  Dy Dysprosium    7793  -19.495  10.588 edge"
F["Dy " 12] = "66  Dy Dysprosium    8583  -13.206  12.196 edge"
F["Ho " 10] = "67  Ho Holmium       8074  -19.458  10.591 edge"
F["Ho " 12] = "67  Ho Holmium       8920  -13.268  12.188 edge"
F["Er " 10] = "68  Er Erbium        8360  -20.135  10.578 edge"
F["Er " 13] = "68  Er Erbium        9267  -12.986  12.157 edge"
F["Tm " 10] = "69  Tm Thulium       8651  -19.330  10.573 edge"
F["Tm " 13] = "69  Tm Thulium       9619  -13.222  12.154 edge"
F["Yb " 10] = "70  Yb Ytterbium     8946  -19.795  10.547 edge"
F["Yb " 13] = "70  Yb Ytterbium     9981  -12.747  11.816 edge"
F["Lu " 11] = "71  Lu Lutetium      9247  -19.360  10.547 edge"
F["Lu " 14] = "71  Lu Lutetium     10351  -12.855  11.722 edge"
F["Hf " 11] = "72  Hf Hafnium       9563  -19.843  10.527 edge"
F["Hf " 14] = "72  Hf Hafnium      10742  -12.733  11.655 edge"
F["Ta " 11] = "73  Ta Tantalum      9884  -19.294  10.511 edge"
F["Ta " 15] = "73  Ta Tantalum     11139  -12.418  11.449 edge"
F["W  " 12] = "74  W  Tungsten     10209  -19.840  10.496 edge"
F["W  " 15] = "74  W  Tungsten     11547  -12.327  11.384 edge"
F["Re " 12] = "75  Re Rhenium      10538  -19.058  10.226 edge"
F["Re " 15] = "75  Re Rhenium      11961  -12.563  11.463 edge"
F["Os " 12] = "76  Os Osmium       10873  -19.529  10.214 edge"
F["Os " 16] = "76  Os Osmium       12388  -12.224  11.392 edge"
F["Ir " 13] = "77  Ir Iridium      11218  -18.898  10.201 edge"
F["Ir " 16] = "77  Ir Iridium      12827  -12.200  11.311 edge"
F["Pt " 13] = "78  Pt Platinum     11566  -19.273  10.202 edge"
F["Pt " 17] = "78  Pt Platinum     13275  -12.348  11.248 edge"
F["Au " 13] = "79  Au Gold         11921  -19.230  10.206 edge"
F["Au " 17] = "79  Au Gold         13736  -12.285  11.152 edge"
F["Hg " 14] = "80  Hg Mercury      12286  -19.370  10.191 edge"
F["Hg " 18] = "80  Hg Mercury      14211  -12.270  11.078 edge"
F["Tl " 14] = "81  Tl Thallium     12660  -18.943  10.157 edge"
F["Tl " 18] = "81  Tl Thallium     14700  -12.289  11.003 edge"
F["Pb " 15] = "82  Pb Lead         13038  -18.670  10.135 edge"
F["Pb " 19] = "82  Pb Lead         15203  -11.882  10.933 edge"
F["Bi " 15] = "83  Bi Bismuth      13421  -18.941  10.125 edge"
F["Bi " 19] = "83  Bi Bismuth      15714  -11.873  10.838 edge"
F["Po " 15] = "84  Po Polonium     13816  -19.063  10.103 edge"
F["Po " 20] = "84  Po Polonium     16247  -11.883  10.757 edge"
F["At " 16] = "85  At Astatine     14216  -18.784  10.081 edge"
F["At " 20] = "85  At Astatine     16787  -12.007  10.679 edge"
F["Rn " 16] = "86  Rn Radon        14622  -18.663  10.054 edge"
F["Rn " 21] = "86  Rn Radon        17340  -11.749  10.609 edge"
F["Fr " 17] = "87  Fr Francium     15034  -18.475  10.029 edge"
F["Fr " 21] = "87  Fr Francium     17909  -11.846  10.524 edge"
F["Ra " 17] = "88  Ra Radium       15447  -18.590  10.015 edge"
F["Ra " 22] = "88  Ra Radium       18487  -11.732  10.428 edge"
F["Ac " 17] = "89  Ac Actinium     15874  -18.287   9.988 edge"
F["Ac " 23] = "89  Ac Actinium     19086  -11.670  10.341 edge"
F["Th "  6] = "90  Th Thorium       4049  -23.021  31.611 edge"
F["Th " 20] = "90  Th Thorium      16303  -18.447   9.968 edge"
F["Th " 25] = "90  Th Thorium      19696  -11.637  10.266 edge"
F["Pa "  6] = "91  Pa Protactinium  4176  -22.092  33.098 edge"
F["Pa " 20] = "91  Pa Protactinium 16736  -18.320   9.964 edge"
F["Pa " 26] = "91  Pa Protactinium 20316  -11.818  10.184 edge"
F["U  "  6] = "92  U  Uranium       4306  -20.788  35.007 edge"
F["U  " 21] = "92  U  Uranium      17169  -18.441   9.957 edge"
F["U  " 26] = "92  U  Uranium      20950  -11.751  10.094 edge"
F["Np "  1] = "93  Np Neptunium        -     -       -    "
F["Pu "  1] = "94  Pu Plutonium        -     -       -    "
F["Am "  1] = "95  Am Americium        -     -       -    "
F["Cm "  1] = "96  Cm Curium           -     -       -    "
F["Bk "  1] = "97  Bk Berkelium        -     -       -    "
F["Cf "  1] = "98  Cf Californium      -     -       -    "
F["Es "  1] = "99  Es Einsteinium      -     -       -    "
F["Fm "  1] = "100 Fm Fermium          -     -       -    "
F["Md "  1] = "101 Md Mendelevium      -     -       -    "
F["No "  1] = "102 No Nobelium         -     -       -    "
F["Lr "  1] = "103 Lr Lawrencium       -     -       -    "

}

Z = iselement(\\\$1) {
    # element symbol or name given
    Ee = substr(element[Z], 1, 3)
    
    if(energy = isenergy(\\\$2))
    {
	# print edge f' and f'' closest to this energy
    
	bestdist = 9999999
	for(i=1;i<40;++i)
	{
	    split(F[Ee i], e)
	    dist = sqrt((e[4] - energy)^2)

 	    if(dist < bestdist)
	    {
		bestdist = dist
		entry=F[Ee i];
	    }
	}
	print entry;
    }
    else
    {
	# print out full "spectrum" for this element
	for(i=1;i<40;++i)
	{
	    if(F[Ee i]) print F[Ee i]
	}
    }
}


# get element with edge closest to a given energy
energy = isenergy(\\\$1) {

    mindist = 99999999
    for(val in F)
    {
	n=split(F[val],e)
	
	# skip non-edge values here
	if(e[n] == "edge")
	{
	    dist = sqrt((e[4] - energy)^2)
	    
	    if((dist < mindist)||((dist == mindist)&&(e[1] < bestelement+0)))
	    {
		mindist = dist
		bestelement = F[val]
	    }
	}
    }
    print bestelement
}

\\\$0 == "all elements" {
    for(Z=1;Z<104;++Z)
    {
	Ee = substr(element[Z], 1, 3)
	for(i=1;i<40;++i)
	{
	    if(F[Ee i]) print F[Ee i];
	}
    }
}

function isenergy(number)
{
    energy = number
    if(number > 0 && number < 1000)
    {
	if(number+0>0) energy = 12398.4245/number
    }
    if((energy < 1000)||(energy > 25000)) energy = 0

    return energy
}

function iselement(string)
{
    reply = 0
    for(z in element)
    {
	split(element[z], w)
	if((string == w[1])||(tolower(string) == tolower(w[2])))
	{
	    reply = z
	    break;
	}
    }

    return reply
}
EOF-elements
chmod a+x \${tempfile}elements.awk









cat << EOF-ginger >! \${tempfile}ginger.awk
#! \$nawk -f
#
#   Ginger:  an English to Elvish(TM) translator
#
#   Process/identify crystallographic parameters from
#	free-form (english) input, 
#   and print them out in MOSFLMish format
#
#   The parameter keyword will always be printed if a parameter is mentioned, 
#   but the value may or may not be given.  The parent program is expected
#   to ask the user for these values explicitly
#
BEGIN{
    line = ""
}

# preprocess
{
    line = ""
    # remove weird characters
    for(i=1;i<=length(\\\$0);++i)
    {
	c = substr(\\\$0,i,1);
	
	# separate stuff from puctuation
	if(c !~ /[a-zA-Z0-9.\\\\-]/) c = " " c " "
	# periods (not decimals)
	if((c == ".") && (substr(\\\$0,i+1,1) !~ /[a-zA-Z0-9.\\\\-]/)) c = ""
	# commas in numbers
	if((c == ",") && (substr(\\\$0,i-1,1) ~ /[0-9]/) && (substr(\\\$0,i+1,3) ~ /[0-9][0-9][0-9]/)) c = ""
	# other punctuation
	if(c ~ /[\\\\"\\\\'\\\\\\\`=,;:~]/) c = " " c " "
#	if(c ~ /[,;:]/) c = " " c " "
	
	# separate numbers from letters/labels
	if((c ~ /[0-9.]/)&&(substr(\\\$0,i+1,1) !~ /[0-9.]/)) c = c " "
#	if((c ~ /[0-9.\\\\-]/)&&(substr(\\\$0,i-1,1) !~ /[0-9.\\\\-PpCcIiFfRrHh]/)) c = " " c

	# separate beginning of negative numbers
#	if((c == "-") && (substr(\\\$0,i+1,1) ~ /[0-9.]/)) c = " " c

	line = line c
    }
    
    if(debug) print "1: " line

    
    # now re-parse the line
    nf = split(tolower(line), w)
    line = ""
    

    ###########################################################
    #
    # resolve all numbers,  converting to standard units
    #
    ###########################################################
    for(i=1;i<=nf;++i)
    {
	word = w[i]
	num = ""
	
	# wordy people
	last = 0
	do{
	    oldnum = num
	    if(last != 1)
	    {
		if(w[i] == "one")       {num += 1 ; last = 1}
		if(w[i] == "two")       {num += 2 ; last = 1}
		if(w[i] == "three")     {num += 3 ; last = 1}
		if(w[i] == "four")      {num += 4 ; last = 1}
		if(w[i] == "five")      {num += 5 ; last = 1}
		if(w[i] == "six")       {num += 6 ; last = 1}
		if(w[i] == "seven")     {num += 7 ; last = 1}
		if(w[i] == "eight")     {num += 8 ; last = 1}
		if(w[i] == "nine")      {num += 9 ; last = 1}
	    }
	    if((last != 10)&&(last != 1))
	    {
		if(w[i] == "ten")       {num += 10; last = 1}
		if(w[i] == "eleven")    {num += 11; last = 1}
		if(w[i] == "twelve")    {num += 12; last = 1}
		if(w[i] == "thirteen")  {num += 13; last = 1}
		if(w[i] == "fourteen")  {num += 14; last = 1}
		if(w[i] == "fifteen")   {num += 15; last = 1}
		if(w[i] == "fifthteen") {num += 15; last = 1}
		if(w[i] == "sixteen")   {num += 16; last = 1}
		if(w[i] == "seventeen") {num += 17; last = 1}
		if(w[i] == "eighteen")  {num += 18; last = 1}
		if(w[i] == "eightteen") {num += 18; last = 1}
		if(w[i] == "ninteen")   {num += 19; last = 1}
		if(w[i] == "nineteen")  {num += 19; last = 1}

		if(w[i] == "twenty")    {num += 20; last=10}
		if(w[i] == "thirty")    {num += 30; last=10}
		if(w[i] == "fourty")    {num += 40; last=10}
		if(w[i] == "fifty")     {num += 50; last=10}
		if(w[i] == "sixty")     {num += 60; last=10}
		if(w[i] == "seventy")   {num += 70; last=10}
		if(w[i] == "eighty")    {num += 80; last=10}
		if(w[i] == "ninty")     {num += 90; last=10}
		if(w[i] == "ninety")    {num += 90; last=10}
	    }
	    
	    # orders of magnitude
	    if(last != 10)
	    {
		if(w[i] == "hundred")  {last=0; if(num == "") num = 1; num = (num - (num%100)) + 100*(num%100)}
		if(w[i] == "thousand") {last=0; if(num == "") num = 1; num = (num - (num%1000)) + 1000*(num%1000)}
		if(w[i] == "million")  {last=0; if(num == "") num = 1; num = (num - (num%1000000)) + 1000000*(num%1000000)}
	    }
	    ++i
	
	} while ((num != oldnum)||((num+0 != 0)&&(w[i-1] == "and")))
	--i
	if(num != "") --i
	
	# actual, real numbers
	if((w[i] ~ /[0-9]/)&&(w[i] !~ /[a-z]/)) num = w[i]+0
	
	if(num != "")
	{
	    # convert numbers
	    ++i
	    oldnum = num
	    
	    if((w[i] ~ /^million/)) num *= 1000
	    if((w[i] ~ /^thousa/)) num *= 1000
	    if((w[i] ~ /^hundred/)) num *= 100
	
	    # percent
	    if((w[i] == "%")||(w[i] ~ /^per[c\\\\-]/))
	    {
		num /= 100
		# could be a solvent content
#		num = num " SOLVENT"
	    }
	    # cm to mm
	    if(w[i] == "cm") num *= 10
	    # um to mm
	    if((w[i] == "um")||(w[i] ~ /^micro/)) num /= 1000
	
	    # some units have unambiguous meaning
	
	    # molecular weights
	    if((w[i] == "kd")||(w[i] == "d")||(w[i] == "amu")||(w[i] ~ /^dalton/))
	    {
		if(w[i] ~ /^k/) num *= 1000
		num = "MASS " num
	    }
	    if((w[i] == "g")&&(w[i+1] == "/")&&(w[i+2] ~ /^mol/))
	    {
		if(num > 1000) num = "MASS " num
	    }
	    if((w[i] == "aa")||(w[i] ~ /^amino/))
	    {
		num *= 120
		num = "MASS " num
	    }
	    
	    # x-ray energies
	    if((w[i] == "ev")||(w[i] == "kev")||(w[i] == "electronvolt"))
	    {
		if(w[i] == "kev") num *= 1000
		num = "ENERGY " num
	    }
	    
	    # angstrom units (imortant without explicit label)
	    if((w[i] == "a")||(w[i] == "\\\\305")||(w[i] ~ /^angsr/))
	    {
		# if wavelength is mentioned, then the show is off
		if((\\\$0 !~ /wave/)&&(\\\$0 !~ /x-ray/)&&(num+0 <= 10)) num = "RESO " num
	    }

	    # this word might mean something else
	    if(num == oldnum) --i
	    
	    word = num
	    
	    # end of number interpreter
	}

	line = line " " word
    }
    
    if(debug) print "2: " line
    
    # now re-parse the line (again)
    nf = split(tolower(line), w)
    line = ""
    
    ###########################################################
    #
    #	reduce all words to a simplified vocabulary
    #	    (and detect "mentioning" of variables)
    #
    ###########################################################
    for(i=1;i<=nf;++i)
    {
#	word = "blah"
	word = ""
	# always interested in numbers
	if((w[i] ~ /[0-9]/)&&(w[i] !~ /[a-z]/))
	{
	    word = w[i]+0
	}
	
	# Crystal/sample properties
	
	# Space group
	if((w[i] == "sg")||(w[i] ~ /^space/))
	{
	    word = "SG"
	    SG = " "
	}
	if(w[i] ~ /^[pcifr][1-6]/)
	{
	    word = toupper(w[i])
	    SG = " "
	}
	# unit cell
	if(w[i] == "cell")
	{
	    word = "CELL"
	}
	# molecular weight
	if((w[i] ~ /molec/)||(w[i] == "mass")||(w[i] ~ /^weigh/)||(w[i] ~ /^protein/)||(w[i] ~ /^peptide/)||(w[i] ~ /^chain/))
	{
	    word = "MASS"
	    if((w[i] !~ /^protein/)&&(w[i] !~ /^peptide/)&&(w[i] !~ /^chain/))
	    {
		MASS = " "
	    }
	}
	# asu could be given in "monomers"
	if((w[i] == "asu")||(w[i] ~ /^asymmetric/)||(w[i] ~ /^chain/)||(w[i] ~ /mer\\\$/))
	{
	    word = "ASU"
	    if(w[i] !~ /mer\\\$/)
	    {
		word = "ASU"
		ASU = " "
	    }
	    if(w[i] == "monomer")  word = "1 ASU"
	    if(w[i] == "dimer")    word = "2 ASU"
	    if(w[i] == "trimer")   word = "3 ASU"
	    if(w[i] == "tetramer") word = "4 ASU"
	    if(w[i] == "pentamer") word = "5 ASU"
	    if(w[i] == "hexamer")  word = "6 ASU"
	    if(w[i] == "heptamer") word = "7 ASU"
	    if(w[i] == "octamer")  word = "8 ASU"
	    if(w[i] == "nonamer")  word = "9 ASU"
	    if(w[i] == "decamer")  word = "10 ASU"
	}
	# solvent content
	if((w[i] ~ /solven/)||(w[i] == "content"))
	{
	    word = "SOLVENT"
	    SOLVENT = " "
	}
	if((w[i] ~ /matthew/)||(w[i] == "vm"))
	{
	    word = "VM"
	    VM = " "
	}
	# metal sites?
	if((w[i] == "site")||(w[i] == "sites")||(w[i] ~ /^metal/)||(w[i] ~ /^deriva/))
	{
	    word = "SITES"
	    if(w[i] !~ /^deriva/) SITES = " "
	}
	# resolution
	if((w[i] ~ /^reso/)||(w[i] ~ /^diffra/)||(w[i] == "res"))
	{
	    word = "RESO"
	    if(w[i] ~ /^reso/)
	    {
		RESO = " "
	    }
	    if(w[i-1] ~ /^low/)
	    {
		RESO = ""
#		word = "low " RESO
	    }
	}
	# mosaicity
	if(w[i] ~ /^mosaic/)
	{
	    word = "MOSAIC"
	}


	# X-ray properties

	# wavelength/energy
	if((w[i] ~ /^wave/)||(w[i] ~ /^x-ray/)||(w[i] ~ /^lambda/)||(w[i] ~ /^lamda/))
	{
	    word = "WAVE"
	    if(w[i] ~ /^wave/) WAVE = " "
	}
	if(w[i] ~ /^energ/)
	{
	    word = "ENERGY"
	    WAVE = " "
	}
	if((w[i] ~ /^disper/)||(w[i] ~ /^spectr/)||(w[i] ~ /^bandwidth/))
	{
	    word = "DISPERSION"
	    DISPER = " "
	}
	if((w[i] ~ /^diverge/)||(w[i] ~ /^crossfire/)||(w[i] ~ /^crossection/))
	{
	    word = "DIVERGENCE"
	    DIVER = " "
	}
	if((w[i] ~ /^polar/)||(w[i] ~ /^monochro/)||(w[i] ~ /^graphi/)||(w[i] ~ /^mirror/)||(w[i] ~ /^pinhole/))
	{
	    # hadle word-based arguments here
	    temp = ""
	    if(w[i] ~ /^monochro/) temp = "MONOCHROMATOR"
	    if(w[i] ~ /^graphi/)   temp = "MONOCHROMATOR"
	    if(w[i] ~ /^mirror/)   temp = "MIRRORS"
	    if(w[i] ~ /^pinhole/)  temp = "MIRRORS"

	    POLAR = POLAR " " temp
	    if(temp == "") word = "POLAR"
	}

	
	# Detector proterties
	
	# mentioning detector
	if((w[i] ~ /^detect/))
	{
	    word = "DETECTOR"
	    DETECTOR = " "
	}
	# distance
	if((w[i] ~ /^dist/)||(w[i] ~ /^xtf/))
	{
	    word = "DISTANCE"
	}
	# beam center
	if((w[i] == "direct")||(w[i] == "beam")||(w[i] == "center"))
	{
	    word = "CENTER"
	    if(w[i] != "beam") CENTER = " "
	}
	# 2theta
	if((w[i] ~ /^sw[iu]ng/)||(w[i] ~ /^twothe/)||(w[i] ~ /theta/))
	{
	    word = "TWOTHETA"
	    TWOTHETA = " "
	}
	# quantum gain
	if((w[i] ~ /^gain/)||(w[i] ~ /^quantum/)||(w[i] ~ /^yeild/))
	{
	    word = "GAIN"
	}
	# starting phi
	if((w[i] ~ /^phi/)||(w[i] ~ /^start/))
	{
	    word = "PHI"
	    if(w[i] ~ /^phi/) PHI = " "
	}
	# oscillation
	if((w[i] ~ /^osc/)||(w[i] ~ /^step/)||(w[i] ~ /^delta/)||(w[i] == "angle"))
	{
	    word = "OSC"
	    if((w[i] ~ /^osc/)) OSC = " "
	}
	
	
	# hard-to-determine program options
	if((w[i] ~ /^sdcorr/))
	{
	    # scala's SDCORRECTION card
	    word = "SDCORR"
	    SDCORR = " "
	}
	
	# (potentially) complex logic flags
	if(w[i] == "fix")
	{
	    word = "FIX"
	}
	if((w[i] == "fit")||(w[i] == "unfix")||(w[i] == "free"))
	{
	    word = "NEG FIX"
	}
	if((w[i] == "not")||(w[i] == "no")||(w[i] == "stop")||(w[i] == "wrong")||(w[i] == "cease"))
	{
	    word = "NEG"
	}
	# handle apostraphe in don't can't shouldn't, etc.
	if((w[i-1] ~ /n\\\$/)&&(w[i] == "'")&&(w[i+1] == "t"))
	{
	    word = "NEG"
	}
	if((w[i] == "off")||(w[i] == "wrong"))
	{
	    word = "NEG-"
	}

	line = line " " word
    }

    nf = split(line, w)
    line = ""
    

    ###########################################################
    #
    #	assign values to variables (cell and SG)
    #
    ###########################################################
    # look for unit cells (six, consecutive numbers)
    for(i=1;i<=nf;++i)
    {
	# look for space groups
	if((w[i] ~ /^[PpCcIiFfRrHh][1-6]/)&&(w[i-1] != "NEG"))
	{
	    SG = SG " " toupper(substr(w[i],1,1)) substr(w[i],2)+0
	    # don't confuse this with a number
	    w[i] = ""
	}	

	# look for pattern of six, consecutive numbers (could only be a unit cell)
	if((w[i]+0 > 5)&&(w[i+1]+0 > 5)&&(w[i+2]+0 > 5)&&(w[i+3]+0 > 5)&&(w[i+4]+0 > 5)&&(w[i+5]+0 > 5))
	{
	    if((w[i]+0 < 1000)&&(w[i+1]+0 < 1000)&&(w[i+2]+0 < 1000)&&(w[i+3]+0 < 175)&&(w[i+4]+0 < 175)&&(w[i+5]+0 < 175))
	    {
		CELL = w[i]+0 " " w[i+1]+0 " " w[i+2]+0 " " w[i+3]+0 " " w[i+4]+0 " " w[i+5]+0
	 
		# these numbers don't mean anything else
		i += 5
	    }
	}
	else
	{
	    # reassemble non-cell words
	    line = line " " w[i]
	}
    }
    
    
    if(debug) print "3: " line

    nf = split(line, w)
    line = ""
    
    ###########################################################
    #
    #	assign likely values to keyworded variables
    #
    ###########################################################
    # now go through each KEY word, and see if we can find a value for it
    for(i=1;i<=nf;++i)
    {
	# fix/unfix parameters
	if((w[i] == "FIX"))
	{
	    # fix/unfix logic
	    FIX = FIX " " w[i+1]
	
	    # next keyword/value gets cancelled
#	    w[i+1] = ""
	}
    
	# negation cancels next word,  wether it be a number or a word
	if((w[i-1] == "NEG")||(w[i+1] == "NEG-"))
	{
	    # fix/unfix logic
	    if(w[i] == "FIX")
	    {
		FIX = "NOT " FIX
	    }
	
	    # keyword/value gets cancelled
	    w[i] = ""
	}
    
	# size of the asymmetric unit
	if(w[i] == "ASU")
	{
	    num = ""
	    # check for valid numbers next to this keyword
	    if((w[i-1] ~ /^[0-9]/)&&(w[i-1]+0 >= 1))
	    {
		num = w[i-1]+0
		
		# convert/interpret range
		if((num+0 < 100)&&(num+0 == int(num)))
		{
		    ASU = num
		    # numbers are used only once
		    w[i-1] = ""
		    w[i] = ""
		}
		# could be a straightforward mass
		if(num+0 > 1000)
		{
		    MASS = MASS " " num
#		    ASU = 1
		    
		    # numbers are used only once
		    w[i-1] = ""
		    w[i] = ""
		}
	    }
	}
	
	if(w[i] == "SOLVENT")
	{
	    num = ""
	    # check for valid numbers next to this keyword
	    if((w[i-1]+0 > 0.05)&&(w[i-1]+0 < 0.95))
	    {
		num = w[i-1]+0
		w[i-1] = ""
		w[i] = ""
	    }
	    else
	    {
		if((w[i+1]+0 > 0.05)&&(w[i+1]+0 < 0.95))
		{
		    num = w[i+1]+0
		    w[i+1] = ""
		    w[i] = ""
		}
	    }
	    if((num > 0.05)&&(num < 0.95))
	    {
		# compute Vm from solvent content
		VM = VM " " 1.24/(1 - num)
	    }
	}
	
	# metal sites
	if(w[i] == "SITES")
	{
	    num = w[i-1]+0
	    # check for valid numbers before this keyword
	    if((num > 0)&&(num < 200)&&(num == int(num))||w[i-1]=="0")
	    {
		SITES = SITES " " num
		w[i-1] = ""
		w[i] = ""
	    }
	    else
	    {
		num = w[i+1]+0
		if((num > 0)&&(num < 200)&&(num == int(num))||w[i+1]=="0")
		{
		    SITES = SITES " " num
		    w[i+1] = ""
		    w[i] = ""
		}
	    }
	}
	
	# Oscillation angle
	if(w[i] == "OSC")
	{
	    # check for valid numbers before this keyword
	    if((w[i-1]+0 > 0)&&(w[i-1]+0 < 30))
	    {
		OSC = OSC " " w[i-1]+0
		w[i-1] = ""
		w[i] = ""
	    }
	    else
	    {
		# maybe after
		if((w[i+1]+0 > 0)&&(w[i+1]+0 < 30))
		{
		    OSC = OSC " " w[i+1]+0
		    w[i+1] = ""
		    w[i] = ""
		}
	    }
	}
	
    }
    
    if(debug) printf "%s",  "4: "

    # prefix keywords
    for(i=1;i<=nf;++i)
    {
    if(debug) printf " %s", w[i]
    
	########################
	# crystal properties
	
	# unit cell mentioned
	if((w[i] == "CELL")&&(CELL == ""))
	{
	    CELL = CELL " "

	    # check for partial cell?
	    for(j=0; j<=6; ++j)
	    {
		if((w[i+j]+0 >5)&&(w[i+j]+0 < 1000))
		{
		    if((w[i+j]+0 < 175)||(j < 3))
		    {
			# assemble numbers that might be incomplete cell dimensions
			CELL = CELL " " w[i+j]+0
			w[i+j] = ""
		    }
		}
	    }
	}
	
#	# outer resolution limit
#	if(w[i] == "RESO")
#	{
#	    # check for valid numbers next to this keyword
#	    if((w[i+1]+0 > 0.1)&&(w[i+1]+0 <= 10))
#	    {
#		RESO = RESO " " w[i+1]+0
#		w[i+1] = ""
#	    }
#	}
	
	# resolution limits
	if(w[i] == "RESO")
	{
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 0.1)&&(w[i+1]+0 <= 10))
	    {
		RESO = RESO " " w[i+1]+0
		w[i+1] = ""
		
		# perhaps a lo-res limit?
		if((w[i+2]+0 > 10)&&(w[i+2]+0 <= 1000))
		{
		    loRESO = loRESO " " w[i+2]+0
		    w[i+2] = ""
		    # cancel mentioning hi-res
		    if(RESO+0 == 0) RESO = ""
		}
	    }
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 10)&&(w[i+1]+0 <= 1000))
	    {
		loRESO = loRESO " " w[i+1]+0
		w[i+1] = ""
		# cancel mentioning hi-res
		if(RESO+0 == 0) RESO = ""
	    }
	}
	
	# mosaic spread
	if(w[i] == "MOSAIC")
	{
	    MOSAIC = MOSAIC " " 
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 0.01)&&(w[i+1]+0 <= 10))
	    {
		MOSAIC = MOSAIC w[i+1]+0
		w[i+1] = ""
	    }
	}
	
	# size of the asymmetric unit
	if(w[i] == "ASU")
	{
	    num = ""
	    # check for valid numbers next to this keyword
	    if((w[i+1] ~ /^[0-9]/)&&(w[i+1]+0 >= 1))
	    {
		# look AFTER keyword
		num = w[i+1]+0

		# convert/interpret range
		if((num+0 >= 1)&&(num+0 < 100)&&(num+0 == int(num)))
		{
		    ASU = num
		    
		    # numbers are used only once
		    w[i+1] = ""
		}
		# could be a straightforward mass
		if(num+0 > 1000)
		{
		    MASS = MASS " " num
		    ASU = 1
		    
		    # numbers are used only once
		    w[i-1] = ""
		}
	    }
	}
	
	# molecular weight of the protein
	if(w[i] == "MASS")
	{
	    num = ""
	    # check for valid numbers next to this keyword
	    if((w[i+1] ~ /^[0-9]/)&&(w[i+1]+0 > 1))
	    {
		num = w[i+1]+0
		
		# convert/interpret range
		if(num < 1) num = 0
		
		# assume < 1000 means kD
		if(num < 1000) num *= 1000
		
		if(num+0 > 1000) 
		{
		    MASS = MASS " " num
		    
		    # numbers are used only once
		    w[i+1] = ""
		}
	    }
	}
	
	# solvent content
	if(w[i] == "VM")
	{
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 1)&&(w[i+1]+0 <= 10))
	    {
		VM = VM " " w[i+1]
		w[i+1] = ""
	    }
	}
	
	########################
	# X-ray properties
	
	# Wavelength
	if(w[i] == "WAVE")
	{
	    num = ""
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 0.1)&&(w[i+1]+0 < 30000))
	    {
		num = w[i+1]+0
		
		# assume > 10 just means energy
		if(num > 10)
		{
		    # assume < 1000 means keV
		    if(num < 1000) num *= 1000
		    num = 12398.4245 / num
		}
		    
		if((num > 0.1)&&(num < 10))
		{
		    WAVE = WAVE " " num
		    
		    # numbers are used only once
		    w[i+1] = ""
		}
	    }
	}
	if(w[i] == "ENERGY")
	{
	    num = ""
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 3)&&(w[i+1]+0 < 30000))
	    {
		num = w[i+1]+0
		
		# assume < 1000 means keV
		if(num < 1000) num *= 1000
		num = 12398.4245 / num
		
		if((num > 0.1)&&(num < 10))
		{
		    WAVE = WAVE " " num
		    
		    # numbers are used only once
		    w[i+1] = ""
		}
	    }
	}
	
	# Scanner gain
	if(w[i] == "GAIN")
	{
	    GAIN = GAIN " "
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 0.0001)&&(w[i+1]+0 < 1000000))
	    {
		GAIN = GAIN w[i+1]+0
		w[i+1] = ""
	    }
	}
	
	# beam polarization
	if(w[i] == "POLAR")
	{
	    # check for actual numbers next to this keyword (word arguments hanlded above)
	    if((w[i+1] ~ /[0-9]/)&&(w[i+1]+0 > -1)&&(w[i+1]+0 < 1))
	    {
		POLAR = POLAR " " w[i+1]+0
		w[i+1] = ""
	    }
	}
	
	# spectral dispersion (bandwidth)
	if(w[i] == "DISPERSION")
	{
	    # check for valid numbers next to this keyword
	    if(((w[i+1]>0)&&(w[i+1]+0 < 0.01))||(w[i+1]+0 > 100))
	    {
		num = w[i+1]+0
		
		# assume > 1 means bandwidth
		if(num > 1) num = 1/num
		
		if((num > 0)&&(num < 0.01))
		{
		    DISPER = DISPER " " w[i+1]+0
		    w[i+1] = ""
		}
	    }
	}
	
	# beam divergence (degrees)
	if(w[i] == "DIVERGENCE")
	{
	    # check for valid numbers next to this keyword
	    if((w[i+1] ~ /[0-9]/)&&(w[i+1]+0 >= 0)&&(w[i+1]+0 < 2))
	    {
		DIVER = DIVER " " w[i+1]+0
		w[i+1] = ""
		
		# possible vertical divergence too?
		if((w[i+2] ~ /[0-9]/)&&(w[i+2]+0 >= 0)&&(w[i+2]+0 < 2))
		{
		    DIVER = DIVER " " w[i+2]+0
		    w[i+2] = ""
		}
	    }
	}
	
	
	
	########################
	# Collection strategy
	
	# Starting phi angle
	if(w[i] == "PHI")
	{
	    # check for valid numbers next to this keyword
	    if((w[i+1] ~ /[0-9]/)&&(w[i+1]+0 > -360)&&(w[i+1]+0 < 720))
	    {
		PHI = PHI " " w[i+1]+0
		w[i+1] = ""
	    }
	}
	
	# XTF distance
	if(w[i] == "DISTANCE")
	{
	    DIST = DIST " " 
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 5)&&(w[i+1]+0 < 10000))
	    {
		DIST = DIST w[i+1]+0
		w[i+1] = ""
	    }
	}
	
	# beam center on detector face
	if(w[i] == "CENTER")
	{
	    # check for TWO valid numbers next to this keyword
	    if((w[i+1] ~ /[0-9]/)&&(w[i+1]+0 > -200))
	    {
		if((w[i+2] ~ /[0-9]/)&&(w[i+2]+0 > -200))
		{
		    CENTER = " " w[i+1]+0 " " w[i+2]+0
		    w[i+1] = ""
		    w[i+2] = ""
		}
	    }
	}
	
	# twotheta (detector swing) angle
	if(w[i] == "TWOTHETA")
	{
	    # check for actual numbers next to this keyword (word arguments hanlded above)
	    if((w[i+1] ~ /[0-9]/)&&(w[i+1]+0 > -120)&&(w[i+1]+0 < 120))
	    {
		TWOTHETA = TWOTHETA " " w[i+1]+0
		w[i+1] = ""
	    }
	}
	
	
	
	# scala's SDCORRection card
	if(w[i] == "SDCORR")
	{
	    # check for valid numbers next to this keyword
	    if((w[i+1]+0 > 0.9)&&(w[i+1]+0 < 5))
	    {
		# must be at least two numbers
		if((w[i+2] ~ /[0-9]/)&&(w[i+2]+0 >= 0)&&(w[i+2]+0 < 10))
		{
		    if((w[i+2]+0 < 0.5)&&((w[i+3] !~ /[0-9]/)||(w[i+3]+0 > 0.5)))
		    {
			# just these two
			SDCORR = w[i+1]+0 " " w[i+2]+0
			w[i+1] = ""
			w[i+2] = ""
		    }
		    if((w[i+3] ~ /[0-9]/)&&(w[i+3]+0 >= 0)&&(w[i+3]+0 < 0.5))
		    {
			# all three
			SDCORR = w[i+1]+0 " " w[i+2]+0 " " w[i+3]+0
			w[i+1] = ""
			w[i+2] = ""
			w[i+3] = ""
		    }
		}
	    }
	}
    }

    if(debug) print ""
    ###########################################################
    #
    #	assign UNlikely values to keyworded variables
    #	    ("wrong" side of uninitialized keyword)
    #
    ###########################################################
    # not done



#    ###########################################################
#    #
#    #	Look for outright filenames
#    #
#    ###########################################################
#    line = ""
#    # remove punctuation
#    for(i=1;i<=length(\\\$0);++i)
#    {
#	c = substr(\\\$0,i,1);
#	
#	# separate stuff from puctuation
#	if(c !~ /[a-zA-Z0-9._\\\\/\\\\-]/) c = " "
#	if(c ~ /[\\\\"\\\\'\\\\\\\`,;:]/) c = " "
#	if((c ~ /./) && (substr(\\\$0,i+1,1) !~ /[0-9]/)) c = " " c
#	if(c ~ /[,;:]/) c = " " c " "
#	
#	line = line c
#    }
#
#    nf = split(line, w)
#    line = ""
#
#    for(i=1;i<=nf;++i)
#    {
#	if((w[i-1] !~ /^[Nn][Oo]/)&&(w[i-2] !~ /^[Nn][Oo]/))
#	{
#	    if(! system("test -d " w[i] ))
#	    {
#		DIR = DIR " " w[i]
#	    }
#	    else
#	    {
#		if(! system("test -r " w[i] ))
#		{
#		    FILE = FILE " " w[i]
#		    
#		    if(! system("test -x " w[i] ))
#		    {
#			PROG = PROG " " w[i]
#		    }
#		}
#	    }
#	}
#    }
}


END{
    # give ASU in Daltons (once we know mass)
#    if((MASS)&&(! ASU)) ASU = " "
#    {
#	temp = ASU
#	if(ASU+0 == 0) temp = 1
#	if((MASS+0 > 1000)&&(ASU+0 < 100)) ASU = temp * MASS
#	if(ASU < MASS) ASU = MASS
#    }

    # input range: the usual
    if(SG)       print "SYMM   ", SG
    # input range: six, CONSECUTIVE numbers > 5
    if(CELL)     print "CELL     ", CELL
    # input range: 1->
    if(MASS)     print "MASS   ", MASS
    # input range: 1 - 5
    if(ASU)      print "ASU    ", ASU
    # input range: 1 - 5
    if(VM)       print "VM     ", VM
    # input range: integers
    if(SITES)    print "SITES  ", SITES
    # input range: 0.1 - 10
    if(RESO)     print "RESO   ", RESO
    # input range: 0.1 - 10
    if(loRESO)   print "loRESO ", loRESO
    # input range: 0.01 < mosaic < 10
    if(MOSAIC)   print "MOSAIC ", MOSAIC
    # input range: 0.1 -> 30000 (ang, eV, keV)
    if(WAVE)     print "WAVE   ", WAVE
    # input range: 0 < gain 
    if(GAIN)     print "GAIN   ", GAIN
    # input range: -1 < polar < 1
    if(POLAR)    print "POLAR  ", POLAR
    # input range: 0< disper < 0.01 or > 100
    if(DISPER)   print "DISPER  ", DISPER
    # input range: 0 < 2 (1-2 values)
    if(DIVER)    print "DIVER   ", DIVER
    # input range: anything
    if(PHI)      print "PHI     ", PHI
    # input range: osc > 0
    if(OSC)      print "OSC     ", OSC
    # input range: dist > 0
    if(DIST)     print "DIST    ", DIST
    # input range: two numbers
    if(CENTER)   print "CENTER  ", CENTER
    # input range: -180 -> 180
    if(TWOTHETA) print "TWOTHETA ", TWOTHETA
    # input range: word logic
    if(SDCORR)   print "SDCORR  ", SDCORR
    # input range: word logic
    if(FIX)      print "FIX     ", FIX
    # input range: word logic
    if(FILE)     print "FILE    ", FILE
    # input range: word logic
    if(TEMPLATE) print "TEMPLATE ", TEMPLATE
    # input range: word logic
    if(DIR)      print "DIR     ", DIR
    # input range: word logic
    if(PROG)     print "PROG    ", PROG

    # whatever is left
    if(REST)     print "REST    ", REST}
    
EOF-ginger
chmod a+x \${tempfile}ginger.awk




cat << EOF-labler >! \${tempfile}labler.awk
#! \$nawk -f
#
#   Find a unique label for the set of items ending lines
#   among the words found on those lines
#
#
{
    if(\\\$NF != Wave[w]) ++w
    Wave[w] = \\\$NF;
    wave[NR] = \\\$NF

    for(i=1;i 1))
	    {
		for(s=1;s<=waves;++s)
		{
		    label[s] = substr(label[s], 2)
		}
	    }
	    else
	    {
		done =1
	    }
	}
	++catch
	if(catch > 1000) done =1
    }
    for(w=1;w<=waves;++w)
    {
	if(label[w] ~ /^f/) label[w] = "F" substr(label[w], 2)
	if(label[w] !~ /^F/) label[w] = "F" label[w]
	print Wave[w], w, label[w]
    }
}
EOF-labler
chmod a+x \${tempfile}labler.awk






cat << EOF-x2york >! \${tempfile}x2york.awk
#! \$nawk -f
#
#	Tries to convert standard denzo .x files to "york" format, so
#	programs other than scalepack can read them.
#
#	Files already in york format pass through unharmed.
#
#	Non-denzo files (no unitary matrix in header) are blocked
#
#	.x files are missing:
#	- a "HEADER" record, which provides rotaprep with a batch number
#	- fractional partiality and phi value of spot center
#	- they also split the 5th york line into two parts
#
BEGIN{
    minX = 9999999
    minY = 9999999
    
    if(! add) add = 0;
    
    reading = 1
}

# read in ALL lines to an array
{
    ++n
    line[n] = \\\$0
    
    # recognize format of camera info line
    if(substr(\\\$0,1,48) == sprintf("%12.5f%12.5f%12.5f%12.5f", \\\$1, \\\$2, \\\$3, \\\$4))
    {
	start = \\\$1
	end   = \\\$2
    }
    
    # reformat long lines (5th line)
    if((length(\\\$0) > 80)&&(! york)&&(! /[^0-9 \\.-]/))
    {
	line[n] = substr(\\\$0, 1, 48)
	++n
	line[n] = substr(\\\$0, 49)
    }
    
    # reformat spot entries
    if((n >5) && (length(\\\$0) >= 77) && (substr(\\\$0, 12, 3) ~ /[0-9] [01]/))
    {
	if((length == 77)&&(! york))
	{
	    # make-up missing data
	    if(substr(\\\$0, 13, 2) == " 0")
	    {
		fractioncalc = 1
	    }
	    else
	    {
		# do something creative here? 
		fractioncalc = 0.001
	    }
	    phispot = (start + end)/2
	    warn = "yes"
	    
	    # append these values to the line
	    line[n] = line[n] sprintf(" %5.3f%6.1f", fractioncalc, phispot)
	}

	# eliminate negative sigmas (rotaprep will remove them anyway)
	if(clean)
	{
	    sigma = substr(\\\$0, 38)+0
	    I = substr(\\\$0, 15, 8)+0
	    if((sigma <= 0)||(I > 999999)||(I < 3*sigma))
	    {
		# next line will overwrite this one
		--n
	    }
	}
	
	# collect stats on spots
	X = substr(\\\$0,50,7)+0
	Y = substr(\\\$0,57,7)+0
	
	if(X < minX) minX=X
	if(Y < minY) minY=Y
	if(X > maxX) maxX=X
	if(Y > maxY) maxY=Y
    }
    
    # get batch number from here
    if(\\\$0 ~ /^sector / )
    {
	if(! batch[page]) batch[page] = \\\$NF + batch_add

	# look for batch overlaps?
    }
}

# telltale signs of end-of-xfile (avoid random junk)
/^crossfire/ {
    # back up over this header line
    if(lastline < 10) lastline = n
}

/^HEADER/ {
    if((lastline < 10)&&(n > 10)) lastline = n-1
    york = "yes"
    
    # back up over this header line
    --n
}

FILENAME != oldFILENAME {
    if(lastline < 10) lastline = n-1

    oldFILENAME = FILENAME
}

# look for orientation matrix entry
\\\$0 == sprintf("%15.8f%15.8f%15.8f%10.6f%10.6f%10.6f", \\\$1, \\\$2, \\\$3, \\\$4, \\\$5, \\\$6) {
    # matrix entry shall mark new denzo batch
    if(determinant == "1.0000")
    {
	# then one file has already been read
    
	# print out the header line
	printf "HEADER %5d\\\\n", batch[page]+add
	
	# don't print out title (can screw up batch numbers)
#	line[1]=""	
    
	# dump lines for previous x file
	if(lastline < 10) lastline = n-2
	for(i=1;i<=lastline;++i)
	{
	    print line[i]
	}
	# update lines for current file
	line[1] = line[n-1]
	line[2] = \\\$0
	lastline = 0

	determinant = "undefined"
	++page
	n=2
    }

    # keep track of matrix row count
    ++matrix_rows
    
    # run down columns, initializing matrix
    for(j=1;j<=3;++j)
    {
	mat[matrix_rows,j]=\\\$(j+3)+0
    }
    
    # calculate determinant of (putative) unitary matrix, when we have it all
    if(matrix_rows == 3)
    {
	determinant = 0
	determinant += mat[1,1]*((mat[2,2]*mat[3,3])-(mat[2,3]*mat[3,2]));
	determinant -= mat[1,2]*((mat[2,1]*mat[3,3])-(mat[2,3]*mat[3,1]));
	determinant += mat[1,3]*((mat[2,1]*mat[3,2])-(mat[2,2]*mat[3,1]));
	determinant = sprintf("%.4f", determinant)
	matrix_rows = 0
    }
}



END {
    # last one
    
    if(determinant == "1.0000") 
    {
	# add header line
	printf "HEADER %5d\\\\n", batch[page]+add

	# don't print out title (can screw up batch numbers)
#	line[1]=""	
    
	# dump all lines
	for(i=1;i<=n;++i)
	{
	    print line[i]
	}
    }
    print ""
    if(warn)
    {
	print "WARNING: some "fraction" numbers had to be filled-in"
    }
    minX=int(minX-1)
    minY=int(minY-1)
    maxX=int(maxX+1)
    maxY=int(maxY+1)
    printf "X_range: %d %d Y_range: %d %d\\\\n", minX, maxX, minY, maxY
}

EOF-x2york
chmod a+x \${tempfile}x2york.awk







cat << EOF-parser >! \${tempfile}parser.awk
#! \$nawk -f
#
#   Create a list of unique an non-overlapping batch numbers from a list
#   of:
#   wave, file, batch, phi, ending phi
#
#   like this:
#   1.54 raw.mtz 1  0 1.5 ...
#
#   step 1: identify runs of batches
#   step 2: link runs contiguous in phi & batch from separate input files (same wavelength)
#   step 3: renumber frames to avoid run collisions
#   
#	We will try to make the wave identifier in the ten-thousandth's place, and the
#	run identifier in the thousandths place, like this:
#	| second lowest wavelength
#	23022 <- batch 22
#	 | third run (in this wavelength)
#
#	Since we cannot exceed 99999 as a batch number, if there are more than
#	9 wavelengths, the thousandths place will simply count the runs
#	if you have > 99 runs, batches will be renumbered sequentially
#
#   parsing is fastest with input sorted on wavelength, sourcefile and then on batch :
#   sort +0n -1 +1 -2 +2n -3 
#   output is a list of runs and batch-adding procedures
#
#
#   printout look like this:
#   # wavelength 1 : 1 A = 12398.4 eV
#   # 11000 +     1 to    15 in filea
#   # 11000 +    16 to    30 in fileb
#   run     1 11001 to 11030
#   # 12000 +    32 to    46 in filec
#   run     2 12032 to 12046
#
#
# read in "batches file"
NF >= 5 {
    ++i
    
    # line should consist of: wave file batch phistart phiend etc...
    Line[i]	= \\\$0
    Wave[i]     = \\\$1+0
    File[i]     = \\\$2
    Batch[i]    = \\\$3+0
    Phi[i]      = \\\$4+0
    Endphi[i]   = \\\$5+0
    Rest[i]     = substr(\\\$0, index(\\\$0, \\\$4));  

    # Wave must be non-zero (to avoid dividing by zero)
    if(Wave[i] == 0)
    {
	Wave[i] = 1;
	if(Wave[i-1]+0 != 0) Wave[i] = Wave[i-1]
    }

    # keep track of wavelengths that have passed by
    if(! taken["wave " Wave[i]])
    {
	# this is the beginning of a new wavelength
	taken["wave " Wave[i]] = 1;
	++waves;
	Lambda[waves] = Wave[i];
    }
    
}

END{
    N = i;
    
    # sort wavelengths (stupid, n^2 sort, but n is small)
    for(wave=1; wave<=waves; ++wave)
    {
	for(other=1; other<=waves; ++other)
	{
	    if(Lambda[wave] <= Lambda[other]) ++wavenumber[Lambda[wave]];
	}
    }
    # reassign wave numbers
    for(lambda in wavenumber)
    {
	Lambda[wavenumber[lambda]] = lambda;
    }
    
    
    
        
    # phase 1: identify adjacent frames (restricted to same source file)
    
    # assign a wedge to each and every frame
    for(i=1;i<=N;++i)
    {
	# now run through all other frames, looking for the adjacent frame to i
	for(k=1; k<=N; ++k)
	{
	    # wraparound index (for speed)
	    j = (i+k-1)%N +1;
	    
	    # adjacent frames have same wavelength, adjacent batch and phi, and same source file.
	    if((Batch[i]+1 == Batch[j])&&\\\\
	       (Endphi[i]==Phi[j])&&\\\\
	       (File[i] == File[j])&&\\\\
	       (Wave[i] == Wave[j])&&\\\\
	       (before[j] == ""))
	    {
		# assign frame "j" to be after frame "i"
		 after[i] = j;
		before[j] = i;
		
		# we're done with frame i
		break;
	    }
	}
    }
    
    


    # phase 2: connect same-wl wedges that are consecutive in phi and batch number
    #          (regardless of source file)
    for(i=1;i<=N;++i)
    {
	if(after[i] == "")
	{
	    for(k=1; k<=N; ++k)
	    {
		# wraparound index (for speed)
		j = (i+k-1)%N +1;
	    
		# just look at dangling ends this time
		if((after[i]=="")&&(before[j]=="")&&\\\\
		    (Batch[i]+1 == Batch[j])&&\\\\
		    (Endphi[i]==Phi[j])&&\\\\
		    (Wave[i] == Wave[j]))
		{
		    after[i] = j;
		    before[j] = i;
		    
		    break;
		}
	    }
	}
    }
    
    
    
    # phase 3: define runs
    for(i=1;i<=N;++i)
    {
	# look for unassigned frames
	if(Run_number[i]=="")
	{
	    # count how many runs
	    ++run;
	    
	    # trace back to "beginning" of this run (ergodicity? yikes!)
	    start[run]=i;
	    while((before[start[run]]!="")&&\\\\
	          (before[start[run]] != i)&&\\\\
		  (Run_number[start[run]]==""))
	    {
		start[run] = before[start[run]];
	    }
	    before[start[run]]="";
	    
	    # now trace to the "end" of this run (again, ergodicity?)
	    end[run] = start[run];
	    while((after[end[run]] != "")&&\\\\
	          (after[end[run]] != start[run])&&\\\\
		  (Run_number[after[end[run]]]==""))
	    {
		# claim this frame for this run
		Run_number[end[run]] = run;
		
		end[run] = after[end[run]];
	    }
	    after[end[run]]="";
	    Run_number[end[run]] = run;
	    
	    
	    # now that we've gotten this far (I hope)
	    # figure out which files are involved in this run
	    
#	    printf "run %4d  %4d in %4s to %4d in %s\\\\n", run, Batch[start[run]], File[start[run]], Batch[end[run]], File[end[run]]
	}
    }
    runs = run;
    
    
    ##########################################################################
    
    # phase 4: renumber batches in the prettiest way possible
    
    # gather information on batch layout, to see which renumbering scheme will work
    # each run should contain consecutive batches from start[] to end[]
    for(wave=1; wave <= waves; ++wave)
    {
	for(run=1; run <= runs; ++run)
	{
	    if(wave == wavenumber[Wave[start[run]]])
	    {
		# compute intra-wave run counter
		++Runs[wave];
		waverun[run] = Runs[wave];
		
		# make unique output run numbers (for scala)
		++outrun;
		Outrun[run] = outrun;
		
		# statistics on runs
		size[run] = Batch[end[run]] - Batch[start[run]] +1;
	    
		wave_size[wave] += size[run];	
		if(size[run] > maxsize[wave]) maxsize[wave] = size[run];
		if(Batch[end[run]] > maxBatch[wave]) maxBatch[wave] = Batch[end[run]];
	    }
	}
    }
    
    # do not exceed batch no. 99999
    plan = "A";
    if(waves > 9) plan = "B";
    for(wave=1; wave <= waves; ++wave)
    {
	if(Runs[wave] > 9)
	{
	    plan = "B"
	}
    }
    
    if(runs > 99) plan = C;
    
    # plan A	- nice, single digit indicators of wave and wedge
    if(plan == "A")
    {
	# nice, two-digit wave/wedge identifier
	for(run=1; run <= runs; ++run)
	{
	    wave = wavenumber[Wave[start[run]]]   
	    add[run] = 10000*wave + 1000*waverun[run] - 1000*int(Batch[start[run]]/1000);
	    
	    # index by scala run? 
#	    if(runs < 10) add[run] = 10000*wave + 1000*Outrun[run];
	}
	for(i=1; i <= N; ++i)
	{
	    newbatch[i] = Batch[i] + add[Run_number[i]];

	    # register batch number, to gaurentee no conflicts
	    if(taken[newbatch[i]]) {plan = "C"; break;};
	    taken[newbatch[i]] = 1;
	}
    }
    
    # plan B	- run-wise identifiers
    if(plan == "B")
    {
	# run counter in two-digit identifier
	outrun=0;
	for(wave=1; wave<=waves; ++wave)
	{
	    for(run=1; run <= runs; ++run)
	    {
		if(Wave[start[run]] == wave) 
		{
		    ++outrun;
		    add[run] = 1000*outrun - 1000*int(Batch[start[run]]/1000);
		}
	    }
	}
	for(i=1; i <= N; ++i)
	{
	    newbatch[i] = Batch[i] + add[Run_number[i]];

	    # register batch number, to gaurentee no conflicts
	    if(taken[newbatch[i]]) {plan = "C"; break;};
	    taken[newbatch[i]] = 1;
	}
    }
    
    # plan C	- last attempt to preserve batch numbers
    if(plan == "C")
    {
	# things are looking pretty bad
	# either there are > 99 runs, or batch numbers > 999.
	# or two batches are inexplicably overlapping	

	# clear the "taken" registry
	for(thing in taken) taken[thing] = "";
	# first batch is always "taken"
	taken[1]=1;
	
	# Ideas?

	# closest 100+x packing?
	for(wave=1; wave<=waves; ++wave)
	{
	    for(run=1; run <= runs; ++run)
	    {
		if(wavenumber[Wave[start[run]]] == wave) 
		{
		    # search for a clear block of batch numbers
		    clear = 0
		    while(! clear)
		    {
		    	clear = 1;
		    	for(i=start[run];i!="";i=after[i])
		    	{
		    		if(taken[Batch[i]%1000+add[run]]) clear = 0;
		    	}
		    	if(! clear) add[run] += 100;
		    	
		    	# emergency exit
		    	if(add[run]>10000) break;
		    }
			# fix up "add" value to avoid 1000s place
		    add[run] = Batch[start[run]]%1000+add[run] - Batch[start[run]];

		    # register batch numbers, to gaurentee no conflicts
		    for(i=start[run];i!="";i=after[i])
		    {
			    taken[Batch[i]%1000+add[run]] = 1;
		    }
		}
	    }
	}
	# now double-check this batch-adding strategy
	for(thing in taken) taken[thing] = "";
	for(i=1; i <= N; ++i)
	{
	    newbatch[i] = Batch[i]%1000 + add[Run_number[i]];

	    # register batch number, to gaurentee no conflicts
	    if(taken[newbatch[i]]) {plan = "D"; break;};
	    taken[newbatch[i]] = 1;
	}
    }
    
    # plan D	- un-pretty ordinal batch assignments
    if(plan == "D")
    {
	# forget it, just remap this stuff to ordinal numbers
	lastbatch = 1;
	for(wave=1; wave<=waves; ++wave)
	{
	    for(run=1; run <= runs; ++run)
	    {
		if(wavenumber[Wave[start[run]]] == wave) 
		{
		    add[run] = lastbatch - Batch[start[run]] +1;
		    lastbatch = Batch[end[run]]+add[run];
		}
	    }
	}
	
	for(i=1; i <= N; ++i)
	{
	    # can't possibly need "taken" registry here
	    newbatch[i] = Batch[i] + add[Run_number[i]];
	}
    }
    
    
    ######################################
    
    # phase 5: expound on batch adding strategy
    
    subrun = 1;
    for(wave=1; wave<=waves; ++wave)
    {
	print "";
	printf "# wavelength %d : %s A = %.1f eV\\\\n", wave, Lambda[wave], 12398.4245/Lambda[wave];
	for(run=1; run <= runs; ++run)
	{
	    if(wave == wavenumber[Wave[start[run]]])
	    {
		# run through wedge
		begin = start[run];
		lastfile = File[start[run]]
		for(i=start[run];i!="";i=after[i])
		{
		    if(File[i] != lastfile)
		    {
#			printf "# add %5d to %5d - %5d in %s\\\\n", add[run], Batch[begin], Batch[before[i]], lastfile
			printf "# %5d + %5d to %5d in %s\\\\n", add[run], Batch[begin], Batch[before[i]], lastfile
			begin = i;
			++subrun;
		    }
		    lastfile = File[i];
		    Subrun[i] = subrun;
		}
		++subrun;
#		printf "# add %5d to %5d - %5d in %s\\\\n", add[run], Batch[begin], Batch[end[run]], lastfile
		printf "# %5d + %5d to %5d in %s\\\\n", add[run], Batch[begin], Batch[end[run]], lastfile
#		printf "#       %5d to %5d in %s +%d\\\\n", Batch[begin], Batch[end[run]], lastfile, add[run]

		printf "run %5d %5d to %5d\\\\n", Outrun[run], newbatch[start[run]], newbatch[end[run]];
	    }
	}
    }
    
    print ""
    
    # now dump the whole business
    
    print "# dump of all new batch numbers"
    for(i=1;i<=N;++i)
    {
	print Subrun[i], Run_number[i], newbatch[i], Line[i];
    }
}

EOF-parser
chmod a+x \${tempfile}parser.awk







cat << EOF-x >! \${tempfile}x.awk
EOF-x
chmod a+x \${tempfile}x.awk
rm -f \${tempfile}x.awk

goto Return_Unwrap_Awk_Scripts

exit











Problem:
################################################################################

 #####   #####    ####   #####   #       ######  #    #
 #    #  #    #  #    #  #    #  #       #       ##  ##
 #    #  #    #  #    #  #####   #       #####   # ## #
 #####   #####   #    #  #    #  #       #       #    #
 #       #   #   #    #  #    #  #       #       #    #
 #       #    #   ####   #####   ######  ######  #    #

################################################################################
#	Help routine
################################################################################
cat << EOF

usage: \$0 [sentence about your project]

where:
[sentence about your project]	is something like:
files called */raw.mtz are 2A data of a 22kD protein with six metal sites per chain
OR
*/*/raw.mtz is from a crystal of peptide RMKQLEDKVEELLSKNYHLENEVARLKKLVG

We can figure it out from there.

you can also keep all this information in a file, and give that file
to \$0

EOF













Cleanup:
if(! \$?DEBUG) rm -f \${tempfile}* >& /dev/null

echo "Thank you, drive through! "

exit


# the Future

# TODO

- keep track of reindexing before run, and for each input file
- update solve.com at end?
- review failure modes
- new ginger
- intelligent scaleit.com
- merge all data in one column?
- export optimizations to script?
- allow command-line choice of reference
- review flow-of-control
- check remove/rename/reference input
- Online Help
- simplify if only one wavelength (no diso data)
- read x-plor files?


# WISH LIST

- fix reindexing bug in sort_everything.com
- postrefine
- improve auto-metal thing
- better indication of "bad frames" ("local" deviation for discontinuities?)
- keep track of Rmerge (or something) when making decisions
- assign wavelength names from edge??
- set up wARP
- figure out what the metal's peak f'' is for value in SOLVE

EOF-Scaler
chmod a+x ${Elfsheim}/Scaler

echo -n "."















































# Spotter
cat << EOF-Spotter >! ${Elfsheim}/Spotter
#! /bin/csh -f
#
#	Spotter Elves 0.5 - easy access to important spots
#	
#	Given a scala/truncate log:
#	orgamizes observations of systematic absences and
#	rejected observations in a simple list, and generages
#	a textual represention of these spots from the frames
#
#
# set this to wherever your awk program is
alias nawk $nawk
nawk 'BEGIN{print}' >& /dev/null
if(\$status) alias nawk awk


set logfile     = "logs/smartflm.merge.log"
set xfile       = \`ls -1 xfiles |& head -1 |& nawk 'NF==1{print "xfiles/" \$1}'\`
set rejectfile  = temp/smartflm.temp.rejects
set rawmtzfile  = raw.mtz
set tempfile    = tempfile
set framedir    = "./frames"
set frameprefix = ""
set ext         = ""

set IMG2SGI     = "GetBox.com"
set spotfile    = spots
set ROCK

################################################################################
echo "Spotter Elves: v1.0b      Because you'd never do it yourself.(TM)   James Holton 8-25-99"
echo ""


foreach arg ( \$* )
    if("\$arg" =~ *.log) then
	if(-e "\$arg") then
	    set logfile = "\$arg"
	else
	    echo "WARNING: \$arg does not exist."
	endif
    endif
    
    if(("\$arg" =~ *.img)||("\$arg" =~ *.osc)) then
	if(-e "\$arg") then
	    set framedir    = \`dirname \$arg\`
	    set ext         = \`basename \$arg |& nawk 'BEGIN{FS="."} {print \$NF}'\`
	    set frameprefix = \`basename \$arg .\$ext |& nawk '{print substr(\$0,1,length(\$0)-3)}'\`
	else
	    echo "WARNING: \$arg does not exist."
	endif
    endif
end

if(! -e "\$logfile") then
    echo "usage: \$0 scala_truncate.log [/your/frames/xtal_001.ext]"
    echo "       OR"
    echo "       \$0 scalepack.log"
    echo ""
    echo "where: "
    echo "    /your/frames/xtal_001.ext  - one of the original images"
    echo "    scala_truncate.log         - log file containing scala/truncate output"
    echo "    scalepack.log              - log file from scalepack"
    echo ""
   exit
endif

grep "Zbyszek Otwinowski" \$logfile >& /dev/null
if(! \$status) goto denzo

################################################################################
Absences:
# get other filenames from the scala log
set temp = \`nawk '/ROGUES, Full name:/{print \$NF}' \$logfile\`
if(-e "\$temp") set rejectfile = "\$temp"
set temp = \`nawk '/Status: READONLY   Filename:/{print \$NF}' \$logfile | head -1\`
if(-e "\$temp") set rawmtzfile = "\$temp"

# coordinates are in \$rawmtzfile (can't proceed without them)
if(! -e "\$rawmtzfile") then
    echo "there is no \${rawmtzfile}, (I need it to get detector coordinates.) "
    echo "systematic absences will not be plotted."
    goto Rejects
endif

# get the systematic absences (printed by truncate)
cat \$logfile |\\
nawk '/Systematic absences are OMITTED/,/Distributions/' |\\
nawk 'NF==5 && ! /[a-z]/ && \$5 != 0{printf "%-4d%-4d%-4d I/sig = %8.3f\\n", \$1, \$2, \$3, \$4/\$5}' |\\
sort -k6n >! \${tempfile}.txt

set test = \`cat \${tempfile}.txt | wc -l\`
if("\$test" == 0) then
    echo "no systematic absences listed in \$logfile "
    goto Rejects
endif

# create an awk script to print symm mates of an HKL in this SG
cat \$logfile |\\
nawk '/SCALA - continuous/,/Data line/' |\\
nawk '/Original indices for/,/Data line/' |\\
nawk '/^  ISYM/' |\\
nawk 'BEGIN{RS=" "} /[hkl]/' |\\
nawk 'NF!=0 {for(i=1;i<=length(\$0);++i){\\
             c=substr(\$0,i,1); \\
             if(c=="h") c="\$1" \\
             if(c=="k") c="\$2" \\
             if(c=="l") c="\$3" \\
             printf "%s", c}; print ""}' |\\
nawk 'BEGIN{print "{" } {print "printf \\"%4d%4d%4d\\\\n\\", " \$0 ";"} END {print "}"}' |\\
cat >! \${tempfile}.awk


# expand unique HKLs to all possible indicies
nawk -f \${tempfile}.awk \${tempfile}.txt |\\
nawk '{list[\$0]=\$0} END{for(entry in list){print entry}}' |\\
sort -n |\\
nawk '{print "/^ " \$0 "/{printf \\"%4d%4d%4d on frame %4d, at: \\", \$1, \$2, \$3, \$5; getline; printf \\"%6.1f %6.1f absence\\\\n\\", \$2, \$3 }"}' |\\
cat >! \${tempfile}
rm -f \${tempfile}.txt            >& /dev/null
mv \${tempfile} \${tempfile}.awk   >& /dev/null


# get observations of these absences from raw mtz file
set test = \`cat \${spotfile}.txt |& wc -l\`
if("\$test" < 2) then
    set temp = \`cat \${tempfile}.awk |& wc -l\`
    echo "getting \$temp systematic absence coordinates from \${rawmtzfile}..."
    echo "NREF -1" |\\
    mtzdump hklin \${rawmtzfile} |\\
    nawk -f \${tempfile}.awk |\\
    sort -k1n,2 -k2n,3 -k3n,4 -k6n,7 >! \${spotfile}.txt
else
    echo "getting systematic absences from \${spotfile}.txt"
    cat \${spotfile}.txt |\\
    nawk '\$NF=="absence"' |\\
    sort -n >! \${tempfile}
    mv \${tempfile} \${spotfile}.txt
endif
# Clean up
rm -f \${tempfile}.awk

Rejects:
##############################################################################

if(! -e "\$rejectfile") then
    echo "no rejection file found: \$rejectfile."
    echo "rejections will not be listed."
    goto SGImovie
endif

# get statistically rejected spots
echo "reading \$rejectfile ..."
cat \$rejectfile |\\
nawk '/ \\*I/{printf "%4d%4d%4d on frame %4d, at: %6.1f %6.1f\\n",\$1,\$2,\$3,\$7,\$16,\$17}' |\\
cat >> \${spotfile}.txt

# \${spotfile}.txt now contains a list of all spots the user really should look at
echo ""
echo "\${spotfile}.txt now contains a list of absent and rejected spots."

echo ""

goto SGImovie




denzo:

echo "denzo files..."

denzoInfo:
#####################################
cat \$logfile |\\
nawk '/Intensities of systematic absences/,/asdf/' |\\
tail -n +4 |\\
nawk '{printf "%4d%4d%4d\\n%4d%4d%4d\\n", \$1, \$2, \$3, -\$1, -\$2, -\$3}' |\\
nawk '{print "/^" \$0 "/{printf \\"%4d%4d%4d %s %6.1f %6.1f\\\\n\\", \$1, \$2, \$3, FILENAME, substr(\$0,50,7), substr(\$0,57,7), \\"absence\\"}"}' |\\
cat >! \${tempfile}.awk

# get all xfile names
set xfiles = \`nawk '/reading from a file:/ {print \$NF}' \$logfile\`

# get Xfile breakdown from frist filename
cat \$logfile |\\
nawk '/reading from a file:/ {print \$NF}' |\\
head -1 |\\
nawk '{print; N=split(\$1,a,".");\\
for(i=1;i! \${tempfile}

set xfile = \`cat \${tempfile}\`
if(\$#xfile != 3) then
    echo "error getting xfile name."
    echo "Sorry! "
    exit
endif

rm -f \${tempfile}
set xpref = "\$xfile[2]"
set xsuff = "\$xfile[3]"
set xfile = "\$xfile[1]"

denzoFrames:
#####################################
cat \$xfile |\\
nawk '/raw data file/{print \$NF}' |\\
nawk '{for(i=1;i<=length(\$0);++i){c=substr(\$0,i,1);\\
       if(c == "\\047") c=" "; \\
       if(c == "#") c=" "; \\
       printf c}}' |\\
cat >! \${tempfile}
set temp = \`cat \$tempfile\`
rm -f \${tempfile}

if((\$#temp == 2)&&("\$frameprefix" == "")) then
    set framedir    = \`dirname  \$temp[1]\`
    set frameprefix = \`basename \$temp[1]\`
    set ext         = \`echo \$temp[2] | nawk '{print substr(\$0,2)}'\`
else
    echo "could not get frame information from \$xfile "
    exit
endif

if(-e \${spotfile}.txt) goto SGImovie

denzoAbsences:
#####################################

echo "getting systematic absences    from \${xpref}???\${xsuff} ..."
nawk -f \${tempfile}.awk \$xfiles |\\
sort -nr -k1,2 -k2,3 -k3,4 |\\
nawk '{N=split(\$4,a,"."); printf "%4d%4d%4d on frame %4d, at: %6.1f %6.1f absence\\n", \\
 \$1,\$2,\$3, substr(a[N-1],length(a[N-1])-2),\$5,\$6}' |\\
cat >! \${spotfile}.txt
if(! \$?debug) rm -f \${tempfile}.awk


denzoRejects:
#####################################
# get frame information from first .x file

if(-e reject) then
    echo "#! /bin/csh -f " >! \${tempfile}.com
    tail -n +2 reject |\\
    nawk -v xpref=\$xpref -v xsuff=\$xsuff \\
    '{printf "nawk \\047/^%4d%4d%4d/{print \$0, " \$5 "}\\047 %s%03d%s \\n", \$1, \$2, \$3, xpref, \$5, xsuff}' |\\
    cat >> \${tempfile}.com
    chmod a+x \${tempfile}.com
    
    echo "getting rejections in ./reject from \${xpref}???\${xsuff} ..."
    \${tempfile}.com |\\
    nawk '{printf "%4d%4d%4d on frame %4d, at: %6.1f %6.1f\\n", \$1, \$2, \$3, \$NF, substr(\$0,50,7), substr(\$0,57,7)}' |\\
    cat >> \${spotfile}.txt

    if(! \$?debug) rm -f \${tempfile}.com
    
else
    echo "WARNING: no reject file found."
endif

goto SGImovie


SGImovie:
##############################################################################

# enable rocking curve
if(\$?ROCK) then
    echo "frame pixels before and after each spot will be included."

    # add +/- one frame for each spot
    cat \${spotfile}.txt |\\
    nawk 'BEGIN{min=9999} {++n; hkl[n]=substr(\$0,1,21); xy[n]=substr(\$0,28); \\
          b[n]=\$6+0; if(b[n]max)max=b[n]} \\
    END{for(i=1;i<=n;++i){ \\
	if(b[i]-1>min) printf "%s%5d, %s -1\\n", hkl[i], b[i]-1, xy[i];\\
	               printf "%s%5d, %s\\n", hkl[i], b[i],   xy[i];\\
	if(b[i]+1! \${tempfile}rocked

    # find some way to get rid of +/- jitter?

    # convert back to original sorting
    grep "absence"    \${tempfile}rocked >! \${spotfile}.txt
    grep -v "absence" \${tempfile}rocked >> \${spotfile}.txt
    rm -f \${tempfile}rocked
endif

if("\$ext" == "osc") then
    set IMG2SGI = ./osc2sgi
endif
if("\$ext" == "img") then
    set IMG2SGI = ./adsc2sgi
endif

goto Decode
# extract adsc2sgi - precompiled SGI ELF binary
# extract osc2sgi  - precompiled SGI ELF binary
ReturnFrom_Decode:

# make sure frames are available
if(("\$framedir" == "")||("\$frameprefix" == "")) then
    echo "no frames"
    echo "use: \$0 \$logfile /your/frames/firstimage_001.ext"
    echo "     to extract and view your systematic absences"
    exit
endif
set test = \`ls -1 \${framedir} |& egrep "^\${frameprefix}"|& egrep "\\.\$ext"'\$' |& head -1\`
if("\$test" == "") then
    echo "could not find \${framedir}/\${frameprefix}???.\$ext"
    echo "edit and run \${tempfile}.com to plot spots in these frames"
    exit
endif

set test = \`\$IMG2SGI |& grep Holton | wc -l\`
if("\$test" == "") then
    echo "no \$IMG2SGI available for movie-making."
    goto TEXTspots
endif

# now prepare an \$IMG2SGI script for viewing them
cat \${spotfile}.txt |\\
nawk '{printf "%03d.rgb is %s\\n",n,\$0;++n}' |\\
cat >! \${spotfile}.list

echo "#! /bin/csh -f " >! \${tempfile}.com
cat \${spotfile}.list |\\
nawk -v pref="\${framedir}/\${frameprefix}" -v suf=\$ext -v prog=\$IMG2SGI \\
'{printf "%s %s%03d.%s -box %4d %4d  %4d %4d -zoom 4 %s\\n",\\
 prog, pref, \$8%1000, suf, \$11-10,\$10-10, \$11+10,\$10+10, \$1}' |\\
cat >> \${tempfile}.com
chmod a+x \${tempfile}.com

#set scale = \`\${tempfile}.com | grep scale | nawk '{++n;sum+=\$NF} END{if(n) print sum/n}'\`
set end   = \`tail -1 \${tempfile}.com | nawk '{print \$NF+0}'\`

set temp = \`cat spots.txt | wc -l\`
echo "extracting \$temp spots from \${framedir}/\${frameprefix}###.\${ext}..."
\${tempfile}.com | grep "converting" >> /dev/null
rm -f \${tempfile}.com

cat << EOF >! makemovie.com
#! /bin/csh -f
#
#	make an sgi movie of 000.rgb to \$end.rgb
#
dmconvert -f sgimv -n \\#\\#\\#.rgb,start=0,end=\$end -p video \\#\\#\\#.rgb \${spotfile}.movie
if(-e \${spotfile}.movie) echo "type: movieplayer \${spotfile}.movie"
EOF
chmod a+x makemovie.com
./makemovie.com >> /dev/null
if((! \$status)&&(-e \${spotfile}.movie)) then

    echo "frame is   h   k   l on image at:    X      Y  " >! \${spotfile}.moviekey
    cat \${spotfile}.list |\\
    nawk '{printf "%4d    %4d%4d%4d    %5d    %6.1f %6.1f %s %s\\n",\\
     \$1+0, \$3, \$4, \$5, \$8%1000, \$10, \$11, \$12, \$13}' |\\
    cat >> \${spotfile}.moviekey
    cat \${spotfile}.moviekey
    
    echo "to view the above spots"
    echo "use: movieplayer \${spotfile}.movie"
    
    if(! \$?debug) then
	rm -f ???.rgb
	rm -f makemovie.com
	rm -f \${spotfile}.list
    endif
    
    # stop here? 
else
    echo "file  is   h   k   l on image at:    X      Y  "
    cat \${spotfile}.list |\\
    nawk '{printf "%7s %4d%4d%4d    %5d    %6.1f %6.1f %s\\n",\\
     \$1, \$3, \$4, \$5, \$8%1000, \$10, \$11, \$12}'
    echo "unable to make SGI movie, "
    echo "but you can still view the ???.rgb files with imgview"
    echo ""
    echo "make sure dmconvert is installed and that your SGI"
    echo "has the right graphics capabilities."
    echo "then run: makemovie.com"
endif
echo ""

TEXTspots:
##############################################################################

goto Unwrap_GetBox
Return_Unwrap_GetBox:

# extract pixel information to text
echo "#! /bin/csh -f " >! getspots.com
cat \${spotfile}.txt |\\
nawk -v pref="\${framedir}/\${frameprefix}" -v suf=\$ext \\
'{printf "echo \\"\\"\\necho \\"%4d%4d%4d on %s%03d.%s ",\\
                 \$1,\$2,\$3, pref, \$6, suf}\\
\$NF == "absence" {print "should be absent\\""}\\
\$NF != "absence" {print "was rejected\\""}\\
 {printf "./GetBox.com %s%03d.%s %4d %4d\\n",\\
 pref, \$6%1000, suf, \$8,\$9}' |\\
cat >> getspots.com
chmod a+x getspots.com


echo "extracting spots as text images into \${spotfile}.plot"
cat << EOF >! \${spotfile}.plot
The following spots have been extracted from your frames.
The pixel values are normalized so that the rms pixel value
in the displayed square is 10.

They are all in "Portable Graymap Format" (pgm) which can be read
by the SGI dmconvert program (and other image conversion programs)
and converted to a format more convenient for you.  Each PGM image
begins with the "P2" line, which should be at the top of the PGM file.

EOF
./getspots.com >> \${spotfile}.plot

echo "look at the spot plots with: more \${spotfile}.plot"

##############################################################################
#
#   End of Main Script
#
##############################################################################

exit


















































Unwrap_GetBox:

cat << EOF >! GetBox.com
#! /bin/csh -f
#
#	GetBox.com -
#
#	Retrieve an nxn square surrounding the given X-Y pixel coordinate
#       and print it out as a nxn grid of numbers, normalized to 0-256
#
# NOTE: mosflm/denzo X,Y is frame Y,X for raxis
#
#
alias nawk $nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set tempfile = tempfile
set img      = ""
set ext      = "osc"
set X        = ""
set Y        = ""
set edge     = 20

foreach arg ( \\\$* )
    if(-e "\\\$arg") then
    	set img = "\\\$arg"
	set ext = \\\`echo \\\$img | nawk 'BEGIN{FS="."} {print \\\$NF}'\\\`
    endif
    if(("\\\$arg" !~ *[a-z,A-Z]*)&&("\\\$arg" =~ [1-9]*)) then
	# a number has been entered
    	if("\\\$X" == "") then
	    set X = "\\\$arg"
	else
	    if("\\\$Y" == "") then
		set Y = "\\\$arg"
	    else
		set temp = \\\`echo \\\$arg | nawk '{printf "%d", \\\$1+0}'\\\`
		if(("\\\$temp" > 5)&&("\\\$temp" < 100)) set edge = \\\$temp
	    endif
	endif
    endif
end

if((! -e "\\\$img")||("\\\$X" == "")||("\\\$Y" == "")) then
    echo "usage: \\\$0 xrayimage.ext X Y [boxedge]"
    echo ""
    exit
endif

###############################################################################

set X1 = \\\`echo \\\$Y | nawk -v e=\\\$edge '{printf "%d", \\\$1-(e/2)}'\\\`
set Y1 = \\\`echo \\\$X | nawk -v e=\\\$edge '{printf "%d", \\\$1-(e/2)}'\\\`
set X2 = \\\`echo \\\$Y | nawk -v e=\\\$edge '{printf "%d", \\\$1+(e/2)}'\\\`
set Y2 = \\\`echo \\\$X | nawk -v e=\\\$edge '{printf "%d", \\\$1+(e/2)}'\\\`

if(\\\$?debug) echo "retreiveing box: (\\\${X1},\\\${Y1})-(\\\${X2},\\\${Y2})"

if("\\\$ext" == "osc") then
    set header   = 4096
    set record   = 4096

    set test  = \\\`od -f \\\$img 780. | head -1 | nawk '{print \\\$2+0}'\\\`
    if("\\\$test" != "0.105") set SWAP
endif

if("\\\$ext" == "img") then
    set header   = 512
    set record   = 4608

    set test  = \\\`head -14 \\\$img | grep "BYTE_ORDER"\\\`
    if("\\\$test" =~ "little_endian") set SWAP
endif

# calculate number of lines we will need from od -d (8 words/line)
@ dumplines = ( ( (\\\$X2 - \\\$X1) / 8 ) + 1 )
@ xpixels   = ( \\\$X2 - \\\$X1 )

# loop through the scan lines
set Y = \\\$Y1
echo "" >! \\\${tempfile}.dump
while(\\\$Y < \\\$Y2)

    # calculate starting byte for this scan line
    @ offset = ( \\\$header + (\\\$record * \\\$Y) + (\\\$X1 * 2))

    # dump word values to scratch file
    od -dv \\\$img \\\${offset}. | head -\\\$dumplines |\\\\
    nawk '{for(i=2;i<=NF;++i){printf "%d ", \\\$i}}' |\\\\
    nawk -v xpixels=\\\$xpixels '{for(i=1;i<=xpixels;++i)\\\\
    {print \\\$i}}' >> \\\${tempfile}.dump

    # signal end-of-scanline
    echo "n" >> \\\${tempfile}.dump

    @ Y = ( \\\$Y + 1 )
end

# remove any blank lines
nawk 'NF!=0' \\\${tempfile}.dump >! \\\${tempfile}
mv \\\${tempfile} \\\${tempfile}.dump


# now we have a file that contains the word values from the frame
if(\\\$?SWAP) then
    if(\\\$?debug) echo "swaping bytes"
    # swap bytes in each word
    cat \\\${tempfile}.dump |\\\\
    nawk '! /n/ {printf "%d\\\\n", (\\\$1%256)*256 + \\\$1/256} /n/' |\\\\
    cat >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}.dump
endif

# now convert the word values to x-ray counts
if("\\\$ext" == "osc") then
    cat \\\${tempfile}.dump |\\\\
    nawk '! /n/{if(\\\$1+0 <= 32768) printf "%d\\\\n", \\\$1+0;\\\\
                  if(\\\$1+0  > 32768) printf "%d\\\\n", \\\$1*4;\\\\
        } /n/' |\\\\
    cat >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}.dump
endif


# now plot these pixels in Portable Graymap Format (PGM)
set sigma = \\\`nawk '! /n/ {++n;sum+=\\\$1*\\\$1} END{if(n) print sqrt(sum/n)}' \\\${tempfile}.dump\\\`
cat \\\${tempfile}.dump |\\\\
nawk -v sigma=\\\$sigma '/n/{print}  ! /n/{pix=10*\\\$1/sigma; if(pix>255)pix=255;\\\\
 print pix}' |\\\\
nawk -v edge=\\\$edge 'BEGIN{printf "P2\\\\n%d %d\\\\n255\\\\n",edge,edge; \\\\
print "# values are 10*pixel/sigma"} \\\\
  /n/{print ""}  ! /n/{printf "%3d ", \\\$1}'


rm -f \\\${tempfile}.dump


EOF
chmod a+x GetBox.com

goto Return_Unwrap_GetBox





Decode:

set temp = \`uname\`
if("\$temp" !~ IRIX*) then
    # not that protable, dammit
    echo "Sorry, can't make SGI images on \$temp computers"
    echo ""
    
    goto ReturnFrom_Decode
endif

# uudecode compiled spot-extractor binaries

cat << EOF | uudecode
begin 755 adsc2sgi
M?T5,1@\\\$"\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`@\\\`\\\`\\\`\\\`!\\\`\\\$\\\`,H\\\`\\\`\\\`\\\`#0\\\`\\\`\\\$08\\\`\\\`\\\`\\\`!\\\`\\\`T\\\`"\\\`\\\`
M!P\\\`H\\\`!0\\\`\\\$@\\\`\\\`\\\`\\\`8\\\`\\\`\\\`\\\`T\\\`\\\$\\\`\\\`-\\\`!\\\`\\\`#0\\\`\\\`\\\`#@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`P\\\`\\\`
M\\\`2\\\`\\\`0\\\`\\\$@\\\`\\\$\\\`!(\\\`\\\`\\\`\\\`!,\\\`\\\`\\\`\\\`3\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`1P\\\`\\\`\\\`\\\`\\\`\\\`\\\`!0\\\`!\\\`\\\`4\\\`\\\`0\\\`%\\\`\\\`\\\`\\\`\\\`
M&\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`(\\\`\\\`\\\`&\\\`\\\`\\\$\\\`!@\\\`!\\\`\\\`8\\\`\\\`\\\`\\\`G\\\`\\\`\\\`\\\`)P\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`0
M<\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`
M0\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`\\\`\\\`%\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`"\\\`\\\`\\\$\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`
M\\\`\\\`8\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+W5SD*4\\\`\\\`\\\`\\\`!!LHVE0\\\`\\\`\\\`\\\`\\\$\\\`!ZUR\\\`\\\`\\\`\\\`\\\`0=LF6(\\\`\\\`\\\`\\\`!!ZN)A\\\`\\\`\\\`\\\`\\\`\\\$\\\`!L\\\\\\\$
M\\\`\\\`\\\`\\\`\\\`0WC+B4\\\`\\\`\\\`\\\`!"KE*,\\\`\\\`\\\`\\\`\\\`\\\$\\\`;6:^\\\`\\\`\\\`\\\`\\\`0=Y!:8\\\`\\\`\\\`\\\`!!ZN2O@\\\`\\\`\\\`\\\`\\\$*
MN4H)\\\`\\\`\\\`\\\`\\\`0>KB?(\\\`\\\`\\\`\\\`!!ZN:L@\\\`\\\`\\\`\\\`\\\$\\\`;8MT\\\`\\\`\\\`\\\`\\\`0\\\`&BU8\\\`\\\`\\\`\\\`!!I@S4P\\\`\\\`
M\\\`\\\`\\\$'JXIY\\\`\\\`\\\`\\\`\\\`0!MF[L\\\`\\\`\\\`\\\`!\\\`\\\`:+7\\\`\\\`\\\`\\\`\\\`\\\$\\\`!S?^\\\`\\\`\\\`\\\`\\\`0R-A.4\\\`\\\`\\\`\\\`!!@JN
MQ\\\`\\\`\\\`\\\`\\\`\\\$&7Z=#\\\`\\\`\\\`\\\`\\\`093B-,\\\`\\\`\\\`\\\`!!E.(Y@\\\`\\\`\\\`\\\`\\\$.9;;P\\\`\\\`\\\`\\\`\\\`0!L:6)M+G-O
M\\\`'-G:3\\\$N,\\\`!L:6)C+G-O+C\\\$\\\`'0\\\`7V5T
M97AT\\\`%]F9&%T80!E9&%T80!?961A=&\\\$\\\`7V9B\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$P/_\\\`@\\\`\\\`\\\`(4\\\`0\\\`\\\`T\\\`\\\`\\\`\\\`
M\\\`!,#_P(\\\`\\\`\\\`"<\\\`\\\$\\\`,H\\\`\\\`\\\`\\\`\\\`\\\`2\\\`/\\\\!\\\`\\\`\\\`\\\`I\\\`!\\\`"T\\\`\\\`\\\`\\\`\\\`\\\`\\\$@#_\\\`0\\\`\\\`\\\`*L\\\`0\\\`VH
M\\\`\\\`\\\`\\\`\\\`!(\\\`_P\\\$\\\`\\\`\\\`"S\\\`\\\$\\\`?0\\\`\\\`\\\`\\\`\\\`\\\`2\\\`/\\\\!\\\`\\\`\\\`\\\`N0!\\\`'T\\\`\\\`\\\`\\\`\\\`\\\`\\\$@#_\\\`0\\\`\\\`\\\`,\\\`0
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!,\\\`_P(\\\`\\\`\\\`#'\\\$\\\`\\\`%D\\\`\\\`\\\`\\\`\\\`\\\`3\\\`/\\\\"\\\`\\\`\\\`\\\`S1\\\`\\\`!9\\\`\\\`\\\`\\\`\\\`\\\`\\\$P#_\\\`@\\\`\\\`
M\\\`-00\\\`\\\`60\\\`\\\`\\\`\\\`\\\`!,\\\`_P(\\\`\\\`\\\`#:\\\$\\\`\\\`%F\\\`\\\`\\\`\\\`\\\`01\\\`/\\\\\\\`\\\`\\\`\\\`\\\`Z1\\\`\\\`!:\\\`\\\`\\\`\\\`\\\`\\\`\\\$P#_
M\\\`@\\\`\\\`\\\`.T\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`#V\\\`\\\$\\\`+4\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`^P!\\\`"V\\\`\\\`\\\`\\\`\\\`\\\`
M\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`0(\\\`0\\\`MP\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$)\\\`\\\$\\\`+@\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`!#@!\\\`"Y\\\`\\\`
M\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`14\\\`0\\\`N@\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$<\\\`\\\$\\\`+L\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(0!\\\`
M"\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`3(\\\`0\\\`O0\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$Z\\\`\\\$\\\`+X\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`!
M0\\\`!\\\`"_\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`4<\\\`0\\\`P\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`%.\\\`\\\$\\\`,\\\$\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`!5@!\\\`#"\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`5T\\\`0\\\`PP\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`%D\\\`\\\$\\\`,0\\\`\\\`\\\`\\\`\\\`\\\`2
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`!:@!\\\`#%\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`6\\\\\\\`0\\\`Q@\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`%V\\\`\\\$\\\`,<\\\`\\\`\\\`
M\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`!?0!\\\`#(\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`8,\\\`0\\\`R0\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`&(\\\`\\\$\\\`-
MP\\\`\\\`\\\`\\\`\\\`\\\`2\\\`/\\\\!\\\`\\\`\\\`!C0!\\\`'=\\\`\\\`\\\`\\\`\\\`\\\`\\\$@#_\\\`0\\\`\\\`\\\`98\\\`0!\\\\L\\\`\\\`\\\`\\\`\\\`!(\\\`_P\\\$\\\`\\\`\\\`&?
M\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`1\\\`/\\\\"\\\`\\\`\\\`!JA\\\`\\\`!9\\\`\\\`\\\`\\\`\\\`\\\$\\\$0#_\\\`\\\`\\\`\\\`\\\`;\\\$0\\\`\\\`64\\\`\\\`\\\`\\\`!!\\\$\\\`_P\\\`\\\`
M\\\`\\\`&X\\\$\\\`"\\\$X\\\`\\\`\\\`\\\`\\\`\\\`3\\\`/_Q\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`#8\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`P\\\`\\\`\\\`\\\`R\\\`\\\`\\\`\\\`"@\\\`\\\`
M\\\`\\\`T\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`F\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!D\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`*P\\\`\\\`\\\`!H\\\`\\\`\\\`\\\`<\\\`\\\`\\\`\\\`*@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+
M\\\`\\\`\\\`\\\`+@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`3\\\`\\\`\\\`\\\`'@\\\`\\\`\\\`!8\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`&P\\\`\\\`\\\`"0\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`B\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`!T\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`#@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"T\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`",\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`/\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`!\\\$\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`%P\\\`\\\`\\\`!0\\\`
M\\\`\\\`\\\`5\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`I\\\`\\\`\\\`\\\`'P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`G\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`"\\\`\\\`\\\`\\\`\\\`Q\\\`\\\`\\\`\\\`,\\\`\\\`\\\`\\\`#4\\\`\\\`\\\`\\\`E\\\`\\\`\\\`\\\`-\\\`\\\`\\\`\\\`"\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`#,\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`^\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(^9@!\\\`#X'@A\\\`R#X"308\\\`!J/F8\\\`0\\\`^!X(0,@^\\\`DT
M&\\\`\\\`;CYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`'(^9@!\\\`#X'@A\\\`R#X"308\\\`!V/F8\\\`0\\\`^!X(0,@
M^\\\`DT&\\\`\\\`>CYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`'X^9@!\\\`#X'@A\\\`R#X"308\\\`""/F8\\\`0\\\`^!X
M(0,@^\\\`DT&\\\`\\\`ACYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`(H^9@!\\\`#X'@A\\\`R#X"308\\\`"./F8\\\`0
M\\\`^!X(0,@^\\\`DT&\\\`\\\`DCYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`)8^9@!\\\`#X'@A\\\`R#X"308\\\`":/
MF8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`GCYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`*(^9@!\\\`#X'@A\\\`R#X"308
M\\\`"F/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`JCYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`*X^9@!\\\`#X'@A\\\`R#X
M"308\\\`"R/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`MCYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`+@/@0"4\\\$\\\$0\\\`!
M\\\`\\\`\\\`\\\`\\\`#P<#\\\\\\\`GG'@T\\\`Y_@(0\\\$\\\`^"6/I\\\`\\\`\\\`/\\\`\\\$\\\`\\\`">E\\\`\\\`0\\\`/\\\`@AC"&\\\`."2F\\\`\\\`0\\\`
M!!"\\\`\\\`,(P(:PF\\\`\\\`\\\`\\\\\\\`0\\\`\\\`\\\`#P((8PA@*\\\`\\\\&0\\\`\\\`K"0\\\`\\\`#P!\\\`\\\`\\\`\\\`/\\\`@AC"&\\\`I\\\`,\\\\
MR"&/.8"8)[W_Z*^\\\\\\\`!"OH\\\`\\\`4\\\`\\\`#P)0,@^\\\`FL)0\\\`\\\`C[P\\\`\\\$#P9\\\`\\\`\\\`#/,@ACSF\\\`
M6\\\`\\\`\\\`\\\`\\\`\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`!\\\`\\\\!\\\`\\\`\\\`/\\\`4\\\`\\\`#P&\\\`\\\`\\\`\\\\&0\\\`\\\`\\\`)P@(0"\\\\*"\\\$\\\`W#\\\`A
MC(2\\\`H(RE@*2,QH\\\`X\\\`SS((8\\\\Y@)",A\\\`\\\`\\\`C*4\\\`\\\`(S&\\\`\\\`\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`!\\\`\\\\
M&0\\\`\\\`\\\`SS((8\\\\Y@%0\\\`0"\\\`E\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`0\\\`\\\`\\\`\\\`#2>]__@GO0\\\`0\\\`^\\\`\\\`"\\\`\\\`@
M^"4\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`#P<#\\\\\\\`GG'<@\\\`YG@(2>]_\\\$B/F(\\\`4/\\\`\\\$_\\\\\\\$2\\\`*\\\`!\\\$@"\\\`\\\`1(\\\`X
M\\\`\\\$2\\\`,\\\`!\\\$@\\\$@\\\`1(!\\\`\\\`\\\$2!6\\\`!\\\$@%\\\`\\\`-\\\`[__R<8\\\`!"OOP\\\`DK[P\\\`(*^D\\\`[BOI0.\\\\
MK[\\\`\\\`'*^@\\\`[2OH\\\`.HKZ\\\`#@*^@\\\`WROK@-XKZ\\\`#5*^@\\\`U"OH\\\`-,KZ\\\`#2*^@\\\`T2O
MH\\\`\\\$P)PD\\\`_">O\\\`##GI0-PYZ0#=.>G\\\`VCGI@-LYZD#8.>H\\\`V3GJP-8YZH#7(\\\\!
M\\\`\\\`\\\`G&\\\`\\\`,K>\\\$\\\`\\\`(\\\\!__@E[P\\\`,K>'_^(\\\\!__P7"?_XK>'__(\\\\!\\\`\\\`"/A(\\\`4K>\\\$\\\`
M\\\`(^9@&0DA\\\`\\\$0\\\`R#X"0\\\`\\\`\\\`\\\`"/JP.XC[P\\\`("0*\\\`\\\`\\\$I80\\\`"%"\\\`!!:^J\\\`["/K0.P
MCZP#O\\\`\\\`-<("/A8\\\`4CYF\\\`=\\\`&.0"&-!\\\`\\\`\\\`\\\`R#X"22E\\\`3R/O\\\`\\\`@\\\$\\\$\\\`\\\`/@\\\`\\\`\\\`\\\`"/
MN0.H\\\`\\\`\\\`\\\`\\\`!<@\\\`#H\\\`\\\`\\\`\\\`\\\`C[@#L(^I\\\`[P\\\`&'B\\\`\\\`2]0(8U+\\\`\\\`"/F8!P)\\\`4\\\`+Z^K
M\\\`ZP#(/@)\\\`6\\\`@)8^\\\\\\\`"\\\`00\\\`\\\`/\\\`\\\`\\\`\\\`\\\`(^9@'"/I\\\`.L\\\`R#X"20%\\\`"^/O\\\`\\\`@)\\\$T\\\`
M\\\`8^9@'"OK0.LCZ0#K\\\`,@^\\\`DD!0\\\`OC[P\\\`(!1\\\`__,\\\`\\\`\\\`\\\`\\\`CYF\\\`:(^D\\\`ZP#(/@)
M\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`"\\\`\\\`0(\\\`ECYF\\\`;(^E\\\`ZPF!O_\\\\\\\`R#X"2>D\\\`#"/O\\\`\\\`@)Z0\\\`,(^%@!2/
MF8!0)*4!1\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`CZX#L(^L\\\`[P\\\`#D"\\\`\\\`8C((8^\\\\\\\`""/.\\\`\\\`\\\`CYF\\\`E*^X
M\\\`ZP#(/@)\\\`P\\\`@)8^\\\\\\\`""OH@.HCZ\\\\#L(^I\\\`[P\\\`#U"\\\`CX6\\\`%(^9@'0!*E@AC60\\\`
M\\\`\\\`,@^\\\`DDI0%,C[P\\\`(!1\\\`\\\`\\\`T\\\`\\\`\\\`\\\`\\\`CZX#L(^M\\\`[P\\\`#F"\\\`CX6\\\`%(^9@'0!K\\\$\\\`A
MC00\\\`\\\`\\\`,@^\\\`DDI0%4C[P\\\`(!!\\\`\\\`\\\`L\\\`\\\`\\\`\\\`\\\`C[@#L(^Y\\\`[P\\\`&'B\\\`\\\`R]((8^9@(2-
M)0\\\`\\\`\\\`R#X"2>D\\\`#"/O\\\`\\\`@\\\`\\\`\\\`\\\`\\\`(^K\\\`["/J@.\\\\\\\`\\\`MP@\\\`%.:"&-K\\\`\\\`\\\`)\\\`\\\$\\\`+9&(
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`%0\\\$\\\`B@\\\`\\\`\\\`\\\`"/A8\\\`4CYF\\\`=\\\`&\\\`("4#(/@))*4!7(^\\\\\\\`"\\\`00\\\`\\\`#\\\`\\\`\\\`\\\`
M\\\`"08\\\`\\\`&ON\\\`-4CZ\\\\#L(^Y\\\`[P\\\`#TB\\\`\\\`RE8(8^9@'2/A8\\\`4C60\\\`\\\`\\\`,@^\\\`DDI0%D
MC[P\\\`(!!\\\`\\\`\\\`,\\\`\\\`\\\`\\\`\\\`)\\\`H\\\`\\\`:^J\\\`U2/K0.PCZX#O\\\`\\\`-0("/A8\\\`4CYF\\\`=\\\`'(8"&-
MA\\\`\\\`\\\`\\\`R#X"22E\\\`6R/O\\\`\\\`@\\\$\\\$\\\`\\\`\\\$0\\\`\\\`\\\`\\\`"/N\\\`.XCZ\\\\#L\\\`\\\`\\\`\\\`\\\`\\\`!^\\\`@J\\\$"\\\`\\\`"P\\\`\\\`
M\\\`\\\`"/N0.\\\\\\\`\\\`](@\\\`,I6"&/F8!\\\\C60\\\`!\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`(.>A\\\`V#GH\\\`-DCZT#
ML(^J\\\`[P\\\`#7"\\\`CX6\\\`%(^9@'0!3D\\\`AC00\\\`\\\`\\\`,@^\\\`DDI0%TC[P\\\`(!!\\\`\\\`!\\\$\\\`\\\`\\\`\\\`\\\`
MCZP#N(^X\\\`[\\\`\\\`\\\`\\\`\\\`\\\`\\\`PP(*A\\\`@\\\`\\\`L\\\`\\\`\\\`\\\`\\\`CZ\\\\#O\\\`\\\`8R(\\\`!^4@ACYF\\\`?(TD\\\`\\\`0#
M(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`"#GH0-8YZ\\\`#7(^M\\\`["/JP.\\\\\\\`\\\`U0@(^%@!2/F8!T\\\`6IP(8W\\\$
M\\\`\\\`\\\`#(/@))*4!?(^\\\\\\\`"\\\`00\\\`\\\`N\\\`\\\`\\\`\\\`\\\`(^L\\\`["/J\\\`.X)9@\\\`!\\\`\\\$8""H4(\\\`\\\`H\\\`\\\`\\\`\\\`
M\\\`(^O\\\`[P\\\`#,B\\\`\\\`?E((8^9@(R-)\\\`\\\`\\\$\\\`R#X"0\\\`\\\`\\\`\\\`"/JP.PC[P\\\`((^M\\\`[P\\\`"U"\\\`
MCYF\\\`C*^B\\\`U\\\`!JG\\\`AC<0\\\`"\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[@#L(^\\\\\\\`""/J\\\`.\\\\\\\`!A@@(^9@(RO
MH@-,\\\`0QX(8WD\\\`\\\`P#(/@)\\\`\\\`\\\`\\\`\\\`(^I\\\`["/N0.\\\\C[P\\\`(\\\`\\\`)6(\\\`#*V@ACYF\\\`C*^B
M\\\`TB-I\\\`\\\`0\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@KZ(#1(^J\\\`["/N\\\`.X)4X\\\`\\\`0'8""H4(/[]KZX#
ML(^H\\\`Z@\\\`\\\`\\\`\\\`\\\`\\\$0\\\`"=P\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`9(^E\\\`ZPGI@\\\`P\\\`R#X"22\\\$\\\`82/O\\\`\\\`@
MCZ8#6(^\\\$@!2/F8!DCZ<#7\\\`,@^\\\`DDA\\\`&P\\\`V1\\\$@)@\\\`1("0\\\`(^\\\\\\\`"!&
M,H\\\`R\\\`\\\`\\\`\\\`\\\`\\\$4\\\`\\\`\\\`D\\\`\\\`\\\`\\\`\\\`CX2\\\`%(^9@&0DA\\\`&P\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@\\\$\\\`\\\`\\\`"0\\\`\\\`
M\\\`\\\`"/A(\\\`4CYF\\\`9(^F\\\`V"/IP-D\\\`R#X"22\\\$\\\`@#(/@)\\\`\\\`\\\`\\\`\\\`(^Y\\\`TB/O\\\`\\\`@
M)\\\`P2\\\`"0/"0\\\`D"0D\\\`KZP#H*^O\\\`YP3(\\\`\\\`\\\$KZD#F"LA"0\\\$4(\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`(^K\\\`Y@\\\`
M\\\`\\\`\\\`\\\`KZL#2(^M\\\`T0\\\`\\\`\\\`\\\`\\\`\\\$:\\\`\\\`!@\\\`\\\`\\\`\\\`"/J@.<\\\`\\\`\\\`\\\`\\\`\\\`%-""H0(\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`(^N
M\\\`YP\\\`\\\`\\\`\\\`\\\`KZX#1(^X\\\`TB/J\\\`-0\\\`\\\`\\\`\\\`\\\`\\\`,(""H0(\\\`\\\`%\\\`\\\`\\\`\\\`\\\`*^H\\\`["/K\\\`.PK[@#
M4*^L\\\`TB/KP-\\\$CZD#3\\\`\\\`\\\`\\\`\\\`\\\`!Z0@J\\\$"\\\`\\\`!0\\\`\\\`\\\`\\\`"OJ0.PC[D#L*^O\\\`TRON0-\\\$
MCZL#2(^M\\\`U"/K@-\\\$CZ@#3(^\\\$@!2/F8!D\\\`6U0(P'(P".OJ@.4K[@#D\\\`%@."4!
MH"@EKZX\\\`\\\$\\\`\\\$\\\`,"4#(/@))(0!](^\\\\\\\`""/I0.0CYF\\\`@"0\\\$\\\`\\\`0#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\
M\\\`"\\\`D\\\`0\\\`!CXR\\\`G*^B\\\`Z2-C\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!6!\\\`!\\\`\\\`\\\`\\\`\\\`\\\`CZ4#E(^9@(\\\`\\\`!4A\\\`\\\`2\\\`H
M)0,@^\\\`DD!\\\`\\\`!C[P\\\`(*^B\\\`SR/A(\\\`4CYF\\\`9"2\\\$\\\`A0#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`"\\\`\\\`\\\`\\\`\\\`\\\`
MCZ\\\\#D*^@\\\`X09X\\\`!N\\\`\\\`\\\`\\\`\\\`(^9@("/I0.4\\\`R#X"20\\\$\\\`\\\`*/N0.\\\$CZH#3(^M\\\`Z\\\`#
M*L\\\`A\\\`PT\\\`&8^\\\\\\\`""/JP-0CYF\\\`B\\\`\\\`+<\\\$"/I\\\`.HKZ(#0\\\`\\\`\\\`,"4\\\`\\\`\\\$\\\`2\\\`0XH(0,@
M^\\\`DDI0(\\\`C[P\\\`((^D\\\`T"/F8!XCZ8#E(^G\\\`Z@#(/@))\\\`4\\\`\\\`H^\\\\\\\`"\\\`D\\\`0\\\`!CXR\\\`
MG\\\`\\\`\\\`\\\`\\\`"-C\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!6!\\\`\\\`\\\\\\\`\\\`\\\`\\\`\\\`CZD#0(^F\\\`Y2/F8!(CZ4#/\\\`\\\`&>\\\$\\\`!X#\\\`E
MKZD#.\\\`,@^\\\`D!("\\\`EC[D#/(^J\\\`SB/O\\\`\\\`@K[D#0*^J\\\`SR/JP.\\\$CZT#I(^X\\\`T\\\`\\\`
M"T"\\\`\\\`:AP(:W8\\\`\\\`"/K\\\`.4KZ\\\`#B!F\\\`\\\`"T\\\`\\\`\\\`\\\`\\\`CZ\\\\#B(^I\\\`T\\\`\\\`#\\\\A\\\`\\\`3E0(95+
M\\\`\\\`\\\`T\\\`?__%6\\\$\\\`!@\\\`\\\`\\\`\\\`"/K0.\\\`\\\`\\\`\\\`\\\`\\\`"6H\\\`\\\`\\\$0\\\`\\\`\\\`:KZ@#@(^N\\\`X2/N\\\`.D\\\`\\\`Y@
M@(^Y\\\`X@##'@AC>D\\\`\\\`\\\`\\\`94\\\$\\\`!*E@AE6T\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\$C2\\\`\\\`!:\\\$\\\`!D:\\\`(:\\\$\\\\\\\`4'P
M1(%(\\\`\\\$2\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\`1B@Q@\\\$8F,H+'L0-HQ[\\\`#;\\\`\\\`\\\`\\\`\\\`!&*H2\\\`Y[(#;.>S\\\`VB/
MJ\\\`.(C[@#E"4.\\\`\\\`\\\$!V\\\`@J%"#_U:^N\\\`XB/K\\\`.\\\$C[D#D"6/\\\`\\\`\\\$!^0@J%"#_E*^O
M\\\`X2/F8!\\\$CZ0#J\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`CZD#E(^J\\\`Y#'IP-H\\\`2H\\\`&<>F\\\`VR/O\\\`\\\`@\\\`\\\`\\\`\\\`
M\\\`(^9@#P\\\`\\\`%@21(L@\\\`\\\`\\\`\\\`\\\`\\\`!&@"(A\\\`\\\`\\\`\\\`\\\`\\\$8H-\\\`/GL\\\`-LY[\\\$#:\\\`,@^\\\`E&((,&
MQZL#8,>J\\\`V1\\\$@)@\\\`1("0\\\`(^\\\\\\\`"!&,E\\\`RYZ\\\$#:\\\$4\\\`\\\`!7GH\\\`-L/\\\`%\\\`%\\\$2!*\\\`!\\\$
M@"\\\`\\\`QZ<#:,>F\\\`VP\\\\\\\`4!P1B8B\\\`D2!B\\\`!\\\$@(\\\`\\\`CX2\\\`%(^9@&1&*(*#)(0"*\\\$0'
M4\\\`!\\\$!E@\\\`YZH#9\\\`,@^\\\`GGJP-@C[P\\\`(\\\`\\\`\\\`\\\`\\\`"/N\\\`.4QZ<#6\\\$28D\\\`#'I@-<1H"1
M(20/\\\`\\\`\\\$D#0':1B8D\\\`B0(\\\`\\\`\\\$D#@\\\`"IZT!.*.@\\\`3I\\\$3/@\\\`1,_X\\\`*.H\\\`3M&(((D
MIZX!/\\\$1/^\\\`\\\`\\\`\\\`\\\`\\\`\\\`,>\\\$\\\`!#'O\\\`'@1X\\\`\\\`4/\\\`%!X\\\$2!2\\\`!\\\$@\\\$\\\`\\\`)\\\`\\\\\\\`\\\`48H@@%\\\$
MS_@\\\`\\\`\\\`\\\`\\\`\\\`\\\$8@0B1\\\$3_@\\\`\\\`\\\`\\\`\\\`\\\`#'A\\\`\\\`0Q[P!X%>\\\`\\\`!0\\\`\\\`\\\`\\\`!\\\$#T\\\`\\\`/\\\`&\\\`\\\`!\\\`\\\`
M\\\`\\\`!\\\$@8@\\\`1("\\\`\\\`"0*\\\`\\\`%&,"0!1,KX\\\`\\\`\\\`\\\`\\\`\\\`!&((0D1\\\$KX\\\`\\\`\\\`\\\`\\\`\\\`\\\`Q
M00\\\`\\\$,4H\\\`>!5\\\`\\\`\\\`4\\\`\\\`\\\`\\\`\\\`1\\\`J\\\`\\\`#P!@\\\`\\\`0\\\`\\\`\\\`'\\\`4%0)1\\\`\\\`\\\`\\\`4D"O__1\\\`J\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`%0/_[\\\`\\\`\\\`\\\`\\\`#'M__\\\\Q2/__\\\`:@\\\`&8^9@(!\\\$R?@\\\`)\\\`L\\\`\\\`:>J\\\`4"GJP%")\\\`4\\\`
M\\\`0\\\`\\\`(!(#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`""OH@\\\$TCYF\\\`;(^E\\\`30GI\\\`\\\$X)(0\\\`%\\\`,@^\\\`DD!@\\\`\\\$
MC[P\\\`(">D\\\`3B/F8!LCZ4!-"2\\\$\\\`&P#(/@))\\\`8!E(^\\\\\\\`"\\\`D#@#_CX6\\\`%(^9@(0G
MI\\\`\\\$XKZ\\\`!1*^N\\\`4@DA\\\`\\\`8\\\`R#X"22E\\\`D2/O\\\`\\\`@KZ\\\`!H(^\\\$@!2/F8!D)(0"3\\\`,@
M^\\\`D\\\`\\\`\\\`\\\`\\\`E[@!0(^\\\\\\\`"\\\`;\\\`\\\`"(KZ\\\`#A)>L\\\`3ZOH\\\`.(&8\\\`\\\`?@\\\`\\\`\\\`\\\`"/N0.\\\$Q[,#
M6\\\$290\\\`#'L@-<1H!"H8^N\\\`XB/J@.D1C)1@T2.@\\\`!\\\$2?@\\\`\\\`\\\`\\\`\\\`\\\`#4A\\\`\\\`,X(0\\\`"
M1,'X\\\`\\\`\\\`\\\`\\\`\\\`!&(#\\\$D1,GX\\\`\\\$0+(\\\`!&@((A\\\`\\\`MX@\\\`%/:"%&,D*#C:@\\\`\\\`\\\$18^\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`-P\\\$\\\`\\\`S@A\\\`\\\`)\\\$P?@\\\`\\\`\\\`\\\`\\\`\\\`\\\$8@4:1\\\$##\\\`\\\`1-CX\\\`\\\`\\\`,R\\\$\\\`!&4@AE2L\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`!\\\$BR\\\`\\\`!6\\\$\\\`!D:\\\`)"\\\$\\\\\\\`4'P1(%(\\\`\\\$2\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\`1BB\\\$\\\`,>S\\\`V#'L@-DCX&\\\`
M%\\\$8R@H+\\\$)P38Q"8\\\$W\\\`\\\`\\\`\\\`\\\`!&*C\\\`\\\\YZH#=\\\$4\\\`\\\`\\\`?GJP-PCX&\\\`%\\\`\\\`\\\`\\\`\\\`#\\\$)03@
MQ"0\\\$Y.>E\\\`W#GI\\\`-TCZH#5\\\`\\\`\\\`\\\`\\\`\\\`10\\\`\\\`)CX&\\\`%,>Q\\\`W#'L\\\`-TQ"D\\\$Z,0H!.P\\\`
M\\\`\\\`\\\`\\\`1C!\\\$@>>R\\\`W3GLP-P1\\\$_X\\\`"0-\\\`\\\`%\\\$S?@\\\`QZL#<,>J\\\`W0\\\`\\\`\\\`\\\`\\\`1B!1I\\\$1-
M^\\\`\\\`\\\`\\\`\\\`\\\`\\\`,:\\\$\\\`!#&M\\\`'@1H\\\`\\\`4/\\\`%!X\\\$2!.\\\`!\\\$@#\\\`\\\`)\\\`T\\\`\\\`48F48%\\\$S?@\\\`\\\`\\\`\\\`\\\`
M\\\`\\\$8@,:1\\\$3?@\\\`\\\`\\\`\\\`\\\`\\\`#&A\\\`\\\`0QK0!X%:\\\`\\\`!0\\\`\\\`\\\`\\\`!\\\$#3\\\`\\\`/\\\`&\\\`\\\`!\\\`\\\`\\\`\\\`X\\\`3Z/J\\\`.(\\\`=@\\\`&8^I\\\`31\\\$
MS_@\\\`\\\`\\\`!@\\\$@&(R"\\\$!.5@AH6T\\\`\\\`(^J\\\`XB7K@\\\$^)4\\\\\\\`\\\`0'N""H4(/^\\\$KZ\\\\#B(^X
M\\\`X27J\\\`%\\\`)PP\\\`\\\`0&(""H4(/]ZKZP#A(^%@!2/F8!@)Z0\\\`,\\\`,@^\\\`DDI0)DKZ(!
M,(^I\\\`3"/O\\\`\\\`@\\\$2\\\`\\\`)@\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`9">E\\\`#\\\`#(/@))(0":(^\\\\\\\`""/IP\\\$P
MCYF\\\`0">D\\\`3@D!0(\\\`\\\`R#X"20&\\\`\\\`&7N0\\\$^EZT!0)>J\\\`4(#+0\\\`9C[P\\\`((^D\\\`32/
MF8!\\\`DZ4!.X^G\\\`3\\\`\\\`\\\`%@2\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!:@\\\`9\\\`\\\`\\\`P\\\$@,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`((^D
M\\\`3"/F8!\\\$\\\`\\\`\\\`\\\`\\\`\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`(!\\\`\\\`\\\`\\\$H\\\`\\\`\\\`\\\`\\\`CX2\\\`%(^9@&0GI0\\\`P\\\`R#X
M"22\\\$\\\`G2/O\\\`\\\`@\\\$\\\`\\\`\\\`0@\\\`\\\`\\\`\\\`"/KP.\\\\CX2\\\`%(^9@&2-Y0\\\`\\\`\\\`R#X"22\\\$\\\`I"/O\\\`\\\`@
M\\\`\\\`\\\`\\\`\\\`(^\\\$@!2/F8!D)(0"Y\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`(\\\`\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`9"2\\\$\\\`R0#
M(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`"\\\`\\\`\\\`\\\`\\\`\\\`CX2\\\`%(^9@&0DA\\\`-4\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@\\\`\\\`\\\`\\\`\\\`(^\\\$
M@!2/F8!D)(0#@\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`(\\\`\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`9"2\\\$\\\`]0#(/@)\\\`\\\`\\\`\\\`
M\\\`(^\\\\\\\`"\\\`\\\`\\\`\\\`\\\`\\\`CX2\\\`%(^9@&0DA\\\`0(\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@\\\`\\\`\\\`\\\`\\\`(^\\\$@!2/F8!D
M)(0\\\$#\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`(\\\`\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`9"2\\\$!\\\$P#(/@)\\\`\\\`\\\`\\\`\\\`"0.\\\`\\\`&/
MO\\\`\\\`@KZX#M(^_\\\`"2/H@.TC[\\\`\\\`'\\\`/@\\\`\\\`@GO0.X/!P/P"><9Q\\\`#F>\\\`A)[W]V(^%
M@!2/F8!@KZ0"**^_\\\`!R/I\\\`(HK[P\\\`&\\\`,@^\\\`DDI010KZ(")(^N\\\`B2/O\\\`\\\`8\\\$<\\\`\\\`
M.\\\`\\\`\\\`\\\`\\\`"/F8!X)Z0\\\`)"0%\\\`\\\`\\\$D!@(\\\`\\\`R#X"0'\\\`."6/O\\\`\\\`8)Z\\\\\\\`)(^%@!2/F8!<
MKZ\\\\\\\`(\\\`'@("4D!@\\\`H\\\`R#X"22E!%2/O\\\`\\\`8\\\$\\\$\\\`\\\`#P\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`9(^E\\\`B@#
M(/@))(0\\\$@(^\\\\\\\`!B/I\\\`(DCYF\\\`1\\\`\\\`\\\`\\\`\\\`\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`!@0\\\`\\\`\\\`?KZ\\\`")(^%
M@!2/F8!T)Z0\\\`)\\\`,@^\\\`DDI02PC[P\\\`&"18\\\`\\\`N/A8\\\`4CYF\\\`7*^X\\\`""/I\\\`\\\`@)\\\`8\\\`
M"@,@^\\\`DDI02\\\\C[P\\\`&!1\\\`\\\`\\\`./@8"<\\\$\\\`\\\`\\\`#*P@\\\`\\\`"/@8"<)!D\\\`\\\`1\\\`\\\`\\\`\\\`BL.0\\\`\\\`
MCX2\\\`%(^9@\\\$PDA\\\`3(\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`8\\\`\\\`\\\`\\\`\\\`(^_\\\`!R/H@(D\\\`^\\\`\\\`"">]\\\`B@\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`/@\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`;F5W+G)G8@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\$%\\\$4T,R4T=)(#\\\$N,"XQ"0EB>2!*86UEF]O;0\\\`\\\`\\\`"UB;W@\\\`\\\`\\\`\\\`\\\`8V]N=F5R=&EN9R\\\`E"!F#\\\$@
M>3\\\$@('@R('DR72!;+6YE9V%T95T*\\\`\\\`H)(&9R86UE9FEL92YI;6<@+2!T:&4@
M04130R!#0T0@:6UA9V4@9FEL92!Y;W4@=V%N="!T;R!C;VYV97)T"@\\\`)("\\\`@
M;W5T9FEL92YR9V(@+2!N86UE(&]F(&]U='!U="!31TD@4D="(&9I;&4N"@\\\`)
M("\\\`@("\\\`@("!F86-T;W(@+2!Z;V]M(&EN(&)Y('1H:7,@9F%C=&]R+@H\\\`\\\`\\\`D@
M('@Q('DQ("!X,B!Y,B\\\`M(&-O&5L(&-O;W)D:6YA=&5S*2X*\\\`\\\`\\\`\\\`\\\`\\\`D@("\\\`@("\\\`@
M+6YE9V%T92\\\`M(&)L86-K('-P;W1S(&]N('=H:71E(&)A8VMGPI(14%\\\$15)?0EE415,]
M("\\\`U,3(["D1)33TR.PI"651%7T]21\\\$52/0\\\`\\\`\\\`\\\`!%4E)/4CH@)7,@9&]EX#ZX"!\\\`^P1JP\\\`
M0\\\`W,\\\`\\\$\\\`=W\\\`!\\\`'RP0\\\`\\\`\\\`\\\`\\\$\\\`\\\`%D!\\\`\\\`!900\\\`(3@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`<\\\`D#\\\$P\\\`\\\`!)T\\\`\\\`\\\`%S\\\`\\\`!'.\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`,&\\\`\\\`\\\`\\\`\\\`C\\\`\\\`\\\`Q,\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`,M0\\\`\\\`\\\`%@\\\`\\\`\\\`S]\\\`\\\`\\\`\\\`:\\\`\\\`\\\`#54\\\`\\\`\\\`\\\`"P\\\`\\\`-O0\\\`\\\`\\\`\\\`_\\\`\\\`\\\`Z
M#\\\`\\\`\\\`\\\`#4\\\`\\\`#L(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`#_____\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`8
M\\\`!T\\\`\\\`\\\`\\\`\\\`\\\`%D\\\`\\\`\\\`"(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0@\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`0@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`_____P\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`=\\\`!\\\\\\\`\\\`\\\`"9\\\`\\\`\\\`\\\`I\\\`\\\`\\\`\\\`"L\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`"0\\\`0\\\`\\\`___\\\\;/__
M__\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`[@\\\`'0\\\`?\\\`\\\`\\\`\\\`(@\\\`\\\`\\\`38\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\$\\\`\\\`\\\`\\\`\\\`,\\\`\\\`\\\`0\\\$D\\\`\\\`\\\`
M\\\`/___?3_____\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(H\\\`!T\\\`'P\\\`\\\`\\\`3L\\\`\\\`\\\`%G\\\`\\\`\\\`!*P\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`
M+"\\\`\\\`"P\\\`\\\`\\\`\\\`P\\\`\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`"(\\\`
M\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`"@\\\`0\\\`R@&"\\\`\\\`\\\`@\\\`\\\`\\\`#\\\`\\\`0\\\`RL%"___P\\\`\\\`\\\`"@\\\`\\\`\\\`\\\$(("\\\`\\\`!0\\\`\\\`
M\\\`#X\\\`0\\\`VH&"\\\`\\\`!@\\\`\\\`\\\`#X\\\`\\\`\\\`\\\`0("\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`
M\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`
M+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`
M\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`!@\\\`\\\`\\\`\\\`P\\\`0\\\`W\\\`&"\\\`\\\`#P\\\`\\\`
M\\\`\\\`P\\\`\\\`!\\\`0("\\\`\\\`\\\`0\\\`\\\`\\\`!\\\$\\\`0!W0&"\\\`\\\`\\\$0\\\`\\\`\\\`!\\\$\\\`\\\`\\\`%,("\\\`\\\`\\\`P\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`
M("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`
M\\\`\\\`\\\`\\\`("\\\`\\\`\\\`/____\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`#_____\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`H\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`,\\\`
M\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`8\\\`\\\`\\\`\\\`'\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`(0\\\`\\\`\\\`\\\`H\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`"P\\\`\\\`
M\\\`!H\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`P8\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`%!@\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`
M!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#
M\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`L\\\`
M\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`(\\\`\\\`\\\`
M\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!C'0\\\`7V9D871A\\\`%]F8G-S\\\`\\\`!\\\`#*\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$8\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!&\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"1F\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+P!\\\`#*\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`1@\\\`\\\`\\\`"@\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#*\\\`\\\`\\\`\\\`\\\`!
M\\\`\\\`\\\`\\\`;@\\\`\\\`\\\`"D\\\`\\\`\\\`\\\`-\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`2\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#*\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`EP\\\`\\\`\\\`"X\\\`\\\`\\\`\\\`/\\\`\\\`\\\`\\\`\\\`@\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`;\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`!\\\`#*\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`Q0\\\`\\\`\\\`"4\\\`\\\`\\\`\\\`1\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`
M\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#*\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`Z@\\\`\\\`\\\`\\\`T\\\`
M\\\`\\\`\\\`3\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`M\\\`\\\`\\\`\\\`\\\`1V\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#<\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`]P\\\`\\\`\\\`!H\\\`\\\`\\\`\\\`5\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`\\\$8\\\`\\\`\\\`17\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`"\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`!,\\\`\\\`\\\`\\\`N\\\`\\\`\\\`\\\`!\\\`&\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`O\\\`\\\`\\\`!1\\\`!\\\`#<\\\`\\\`\\\`\\\`\\\`!
M\\\`\\\`\\\`!\\\$0\\\`\\\`\\\`!8\\\`\\\`\\\`\\\`;\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`&P\\\`\\\`\\\`\\\`\\\\\\\`
M\\\`\\\`\\\`R\\\`\\\`\\\`\\\`!\\\`6\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#<\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!)P\\\`\\\`\\\`!<\\\`\\\`\\\`\\\`=\\\`\\\`\\\`\\\`\\\`@\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`*@\\\`\\\`\\\`\\\`\\\\\\\`\\\`\\\`\\\`V\\\`\\\`\\\`\\\`!\\\`6\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`!\\\`#<\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!/@\\\`\\\`\\\`!4\\\`\\\`\\\`\\\`?\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`
M\\\`\\\`\\\`\\\`.0\\\`\\\`\\\`\\\`\\\\\\\`\\\`\\\`\\\`Z\\\`\\\`\\\`\\\`!\\\`6\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`'<\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!4P\\\`\\\`\\\`\\\`P\\\`
M\\\`\\\`\\\`A\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`^\\\`\\\`\\\`\\\`\\\`1V\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`
M\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!
M\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`
M\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`
M\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`\\\`<\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`
M"0\\\`\\\`\\\`\\\`8\\\`\\\`\\\`\\\`'\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`"@\\\`\\\`__\\\\\\\`\\\`\\\`\\\`\\\`
M\\\`\\\$\\\`+0!\\\`O__\\\\\\\`\\\`/__\\\`\\\`\\\`\\\`!@!\\\`'R\\\`2S___\\\`\\\`#__P\\\`\\\`\\\`\\\`P\\\`0!]\\\`\\\$T___P\\\`\\\`__\\\\\\\`
M\\\`\\\`\\\`2\\\$\\\`\\\`\\\`\\\`!!/__\\\\\\\`\\\`/__\\\`\\\`\\\`\\\`'Q\\\`\\\`\\\`!\\\`1[___\\\`\\\`#__P\\\`\\\`\\\`!@0\\\`\\\`3P\\\$:___P\\\`\\\`
M__\\\\\\\`\\\`\\\`\\\`L\\\$\\\`\\\`%D!!O__\\\\\\\`\\\`/__\\\`\\\`\\\`\\\`)A\\\`\\\`!9\\\`1S___\\\`\\\`#__P\\\`\\\`\\\`58\\\`\\\`\\\`\\\`\\\`%\\\$__
M_P\\\`\\\`__\\\\\\\`\\\`\\\`%W\\\$\\\`\\\`%H!1O__\\\\\\\`\\\`/__\\\`\\\`\\\`\\\`,0\\\`\\\`\\\`\\\`\\\$4K___\\\`\\\`#__P\\\`\\\`\\\`3(\\\`0\\\`\\\`\\\`
M%\\\$___P\\\`\\\`__\\\\\\\`\\\`\\\`\\\$_\\\`\\\$\\\`\\\`-!1/__\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`80!\\\`#*\\\`8(\\\`\\\`%\\\`\\\`#__P\\\`\\\`\\\`8P\\\`
M0\\\`M\\\`%"___P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"1\\\`\\\$\\\`-J!@@\\\`\\\`@\\\`\\\`/__\\\`\\\`\\\`!?\\\`!\\\`'T\\\`4+___\\\`\\\`#__P\\\`\\\`
M\\\`6D\\\`0!]\\\`%"___P\\\`\\\`__\\\\\\\`\\\`\\\`&3\\\$\\\`\\\`\\\`\\\`!1/__\\\\\\\`\\\`/__\\\`\\\`\\\`!@A\\\`\\\`!9\\\`5K___\\\`\\\`#_
M_P\\\`\\\`\\\`7\\\`0\\\`\\\`60%:___P\\\`\\\`__\\\\\\\`\\\`\\\`&:\\\$\\\`\\\`%D!7/__\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`31\\\`\\\`!9@\\\$;___
M\\\`\\\`#__P\\\`\\\`\\\`8@0\\\`\\\`6@%&___P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!I\\\`\\\`\\\`\\\`\\\`\\\`3/__\\\\\\\`\\\`\\\`\\\`)\\\`\\\`\\\`!\\\$0!\\\`"U\\\`8
MS___\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`1P\\\`0\\\`M@&,___P\\\`\\\`\\\`\\\`<\\\`\\\`\\\`\\\$*\\\`\\\$\\\`+'0\\\`
M7V9D871A\\\`%]F8G-S\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`!\\\`\\\$\\\`+0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`!P!\\\`'R\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"@\\\`\\\`\\\`\\\`T\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`3\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`(!\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!D\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`M\\\$\\\`\\\`%D\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`.\\\`\\\`\\\`\\\`)P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`5<\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`!,#\\\`\\\`L\\\`\\\`\\\`%X\\\$\\\`\\\`%H\\\`\\\`\\\`\\\`\\\`\\\`3\\\`\\\`\\\`.\\\`\\\`\\\`\\\`,@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`\\\$P#_\\\\0\\\`\\\`\\\`3,\\\`
M0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!,#\\\`\\\`L\\\`\\\`\\\`%\\\`\\\`\\\$\\\`\\\`-\\\`\\\`\\\`\\\`\\\`\\\`3\\\`P\\\`+\\\`\\\`\\\`\\\`8@!\\\`#*\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`"0\\\`\\\`
M\\\`8T\\\`0\\\`M\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`D\\\`\\\`\\\`"2\\\`\\\$\\\`-J\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`)\\\`\\\`\\\`!?0!\\\`'T\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`
M"0\\\`\\\`\\\`6H\\\`0!]\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`D\\\`\\\`\\\`&4\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`3\\\`\\\`\\\`+\\\`\\\`\\\`!@P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\$P\\\`\\\`\\\`\\\`\\\`\\\`\\\`7\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!,\\\`\\\`\\\`\\\`\\\`\\\`\\\`&;\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`3\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`3A\\\`\\\`!9@\\\`
M\\\`\\\`\\\`\\\$\\\$0#_\\\`\\\`\\\`\\\`\\\`8D0\\\`\\\`6@\\\`\\\`\\\`\\\`\\\`!,\\\`\\\`\\\`X\\\`\\\`\\\`!J\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`1\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\$@\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`1T\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$+\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`!
M!@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`2P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`#2\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`70\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`'P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$D\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`!%P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`*X\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`#+\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`PP\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`+P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`"U\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`.D\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`\\\`\\\`#S
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`X@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`/H\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`#N\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`C0!\\\`#<\\\`\\\`\\\`\\\`\\\`\\\`\\\$@\\\`\\\`"0\\\`\\\`\\\`-D\\\`0!W0\\\`\\\`\\\`\\\`\\\`!(\\\`
M\\\`\\\`D\\\`\\\`\\\`!S\\\`\\\$\\\`?+\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`*\\\`\\\`\\\`\\\`HQ\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$0\\\`\\\`"P\\\`\\\`\\\`\\\$\\\`0\\\`\\\`60\\\`\\\`\\\`\\\`
M!!\\\$\\\`_P\\\`\\\`\\\`\\\`!'\\\$\\\`\\\`%E\\\`\\\`\\\`\\\`\\\`01\\\`/\\\\\\\`\\\`\\\`\\\`\\\`FA\\\`\\\`A.\\\`\\\`\\\`\\\`\\\`\\\`\\\$P#_\\\\0\\\`N:6YT97)P
M\\\`"YR96=I;F9O\\\`"YD>6YA;6EC\\\`"YL:6)L:7-T\\\`"YM6YS='(\\\`+F1Y
M;G-Y;0\\\`N:&%S:\\\`\\\`N=&5X=\\\`\\\`N:6YI=\\\`\\\`N9&%T80\\\`N\\\`\\\`\\\`\\\`),\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`?\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2;\\\`\\\`\\\`\\\`\\\`T\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`"9\\\`4,!!T!\\\`0\\\$!)PD!)AL!\\\`0\\\$""@8(8\\\`\\\$D\\\`0\\\$!#0\\\$!#@\\\$!\\\`1T!\\\`0
M\\\$B+P\\\$A!0\\\$\\\$\\\`0\\\`X\\\`\\\`+8#_[]\\\$1\\\$1'\\\`@\\\`\\\`5A/_3(%"\\\`\\\`\\\`TP\\\$%\\\`0\\\$!\\\`0@\\\`\\\`+\\\$8'_
M[!\\\$1\\\$8@\\\`\\\$0\\\`PT#,PT#,H\\\`C,T\\\$?\\\`4.\\\`0X\\\`A4CX"\\\`0\\\\!,X"\\\`4H\\\`"@\\\`.\\\`\\\`8!!@(
M*\\\`\\\`H""@\\\`*\\\`@F\\\$/\\\`2\\\\!,0\\\\!+P\\\$Q'P\\\$O\\\`4A?_4@P\\\`Q-A43\\\\!,G1R4U8*\\\`@\\\$!#@
M\\\$##@)1@"&\\\`\\\`8\\\`!\\\$1(=\\\`0\\\\!\\\`F-3'0,R<60S,TT#/0-38V,#30,1\\\`PP!\\\`P13-'
M)\\\$@(!H7_]H7_XX,\\\`,C300?<1,]\\\`PT##06!'P\\\$O\\\`0\\\\!&%\\\`\\\`S\\\`0.\\\`0T!\\\`QX"#P
M&\\\`@(\\\`1#P\\\$O\\\`8"\\\`@&(^\\\`0\\\\!\\\`5%A8@\\\$N\\\`0\\\$Q\\\`T\\\$/\\\`1(W@("\\\`@(\\\`!#P\\\$_\\\`0\\\\!48
M\\\`B@("\\\`@(\\\`(7_]>6%\\\`!(0\\\\!\\\$E%1/P&\\\`(71V8F%A86%A86%3#0,#0#4;%0L%(@
MX"\\\$F,"'@)E4E(481\\\\!8A0W8S\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`,\\\`\\\`\\\`\\\`"\\\`\\\`!)R\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`X\\\`@\\\`\\\`\\\`_\\\`>#0\\\`0\\\`RL
08\\\`@\\\`10_\\\`=R!@"\\\`0\\\$#\\\\!G\\\$\\\`,\\\`
\\\`
end
EOF


# and the RaxisIIc converter
cat << EOF | uudecode
begin 755 osc2sgi
M?T5,1@\\\$"\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`@\\\`\\\`\\\`\\\`!\\\`\\\$\\\`.,\\\`\\\`\\\`\\\`#0\\\`\\\`%J\\\`\\\`\\\`\\\`\\\`!\\\`\\\`T\\\`"\\\`\\\`
M!P\\\`H\\\`!0\\\`\\\$@\\\`\\\`\\\`\\\`8\\\`\\\`\\\`\\\`T\\\`\\\$\\\`\\\`-\\\`!\\\`\\\`#0\\\`\\\`\\\`#@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`P\\\`\\\`
M\\\`2\\\`\\\`0\\\`\\\$@\\\`\\\$\\\`!(\\\`\\\`\\\`\\\`!,\\\`\\\`\\\`\\\`3\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`1P\\\`\\\`\\\`\\\`\\\`\\\`\\\`!0\\\`!\\\`\\\`4\\\`\\\`0\\\`%\\\`\\\`\\\`\\\`\\\`
M&\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`(\\\`\\\`\\\`&\\\`\\\`\\\$\\\`!@\\\`!\\\`\\\`8\\\`\\\`\\\`\\\`M\\\`\\\`\\\`\\\`+0\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`0
M<\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`
M0\\\`\\\`\\\`\\\`\\\`\\\`P\\\`\\\`\\\`\\\`,\\\`\\\`\\\`\\\`\\\`\\\`%\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`#\\\`\\\`\\\$\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`5L\\\`\\\`\\\`
M\\\`\\\`8\\\`\\\`!\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+W5S0\\\`\\\`\\\`\\\`\\\$'
MJXI\\\`\\\`\\\`\\\`\\\`\\\`0>KFK(\\\`\\\`\\\`\\\`!\\\`\\\`:+5@\\\`\\\`\\\`\\\`\\\$'JXIY\\\`\\\`\\\`\\\`\\\`0>KB80\\\`\\\`\\\`\\\`!!ZN2O@\\\`\\\`
M\\\`\\\`\\\$*N4H)\\\`\\\`\\\`\\\`\\\`0>KB?(\\\`\\\`\\\`\\\`!\\\`\\\`>M<@\\\`\\\`\\\`\\\`\\\$\\\`;8MT\\\`\\\`\\\`\\\`\\\`0:8,U,\\\`\\\`\\\`\\\`!\\\`&V;
MNP\\\`\\\`\\\`\\\`\\\$\\\`!S?^\\\`\\\`\\\`\\\`\\\`0R-A.4\\\`\\\`\\\`\\\`!":O#AP\\\`\\\`\\\`\\\`\\\$,C3%4\\\`\\\`\\\`\\\`\\\`03L(\\\`
M\\\`\\\`\\\`!!E.(TP\\\`\\\`\\\`\\\`\\\$&4XCF\\\`\\\`\\\`\\\`\\\`0YEMO\\\`\\\`\\\`\\\`\\\`!\\\`&QI8FTN'0\\\`+FEN:70\\\`+F9I;FD\\\`+F1A=&\\\$\\\`+G)D871A
M\\\`"YS9&%T80\\\`N0!S=')C;7\\\`\\\`0!S=')C:'(\\\`\\\`\\\`\\\`\\\`
M*\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`(@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`5
M\\\`\\\`\\\`\\\`'0\\\`\\\`\\\`!@\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`'\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`_\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"<\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`#@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`E\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`#\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`&@\\\`\\\`\\\`!\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`/\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`/
M\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`!,\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`9\\\`\\\`\\\`\\\`%@\\\`\\\`\\\`!<\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"\\\\\\\`
M\\\`\\\`\\\`C\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"L\\\`\\\`\\\`\\\`U\\\`\\\`\\\`\\\`/@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`J\\\`\\\`\\\`\\\`,P\\\`\\\`
M\\\`"D\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`.\\\`\\\`\\\`\\\`#(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`W\\\`\\\`\\\`\\\`
M.0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`.P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`Z\\\`\\\`\\\`\\\`/0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`^\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(^9@!\\\`#
MX'@A\\\`R#X"308\\\`!R/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`=CYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`'H^9
M@!\\\`#X'@A\\\`R#X"308\\\`!^/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`@CYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`
M(8^9@!\\\`#X'@A\\\`R#X"308\\\`"*/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`CCYF\\\`\\\$\\\`/@>"\\\$#(/@)
M-!@\\\`)(^9@!\\\`#X'@A\\\`R#X"308\\\`"6/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`FCYF\\\`\\\$\\\`/@>"\\\$#
M(/@)-!@\\\`)X^9@!\\\`#X'@A\\\`R#X"308\\\`"B/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`ICYF\\\`\\\$\\\`/@
M>"\\\$#(/@)-!@\\\`*H^9@!\\\`#X'@A\\\`R#X"308\\\`"N/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`LCYF\\\`
M\\\$\\\`/@>"\\\$#(/@)-!@\\\`+8^9@!\\\`#X'@A\\\`R#X"308\\\`"Z/F8\\\`0\\\`^!X(0,@^\\\`DT&\\\`\\\`O
MCYF\\\`\\\$\\\`/@>"\\\$#(/@)-!@\\\`,(^9@!\\\`#X'@A\\\`R#X"308\\\`#\\\$#X\\\$\\\`E!!\\\$\\\`\\\`0\\\`\\\`\\\`\\\`\\\`\\\\
M'\\\`_\\\`)YQVE\\\`.?X"\\\$!\\\`/@ECZ0\\\`\\\`#P!\\\`\\\`\\\`GI0\\\`\\\$\\\`#P((8PA@#@DI@\\\`\\\$\\\`\\\`00@\\\`#"
M,"&L)@\\\`\\\`/\\\`\\\$\\\`\\\`\\\`\\\`\\\\""&,(8#\\\`/!D\\\`\\\`*PD\\\`\\\`\\\`\\\\\\\`0\\\`\\\`\\\`#P((8PA@,0#/,@ACSF\\\`
MM">]_^BOO\\\`\\\`0KZ\\\`\\\`%\\\`\\\`\\\`\\\\"4#(/@)K"4\\\`\\\`(^\\\\\\\`!\\\`\\\\&0\\\`\\\`\\\`SS((8\\\\Y@%P\\\`\\\`\\\`\\\`\\\`
M\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`0/\\\`0\\\`\\\`#P%\\\`\\\`\\\`\\\\!@\\\`\\\`/!D\\\`\\\`\\\`"<("\\\$\\\`O"@A\\\`-PP(8R\\\$@,",
MI8#\\\$C,:\\\`.\\\`,\\\\R"&/.8"4C(0\\\`\\\`(RE\\\`\\\`",Q@\\\`\\\`\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`0/!D\\\`\\\`\\\`,\\\\
MR"&/.8!8\\\`\\\$\\\`@)0,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`\\\$\\\`\\\`\\\`\\\`\\\`TGO?_X)[T\\\`\\\$\\\`/@\\\`\\\`@\\\`(/@E\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\\'\\\`_\\\`)YQU@\\\`.9X"\\\$GO?Q0CYB\\\`%#P!/_!\\\$@"@\\\`1(\\\`@\\\`\\\$2\\\`.\\\`!\\\$@#\\\`\\\`
M1(!(\\\`\\\$2\\\`0\\\`!\\\$@5@\\\`1(!0\\\`#0.__\\\\G&\\\`\\\`0K[\\\\\\\`)*^\\\\\\\`""OI\\\`.PKZ4#M*^P\\\`!RO
MH\\\`.LKZ\\\`#H*^@\\\`X"OH\\\`-\\\\KZX#>*^@\\\`U2OH\\\`-0KZ\\\`#3*^@\\\`TBOH\\\`-\\\$KZ\\\`!,"<)
M\\\`/PGKP\\\`PYZ4#<.>D\\\`W3GIP-HYZ8#;.>I\\\`V#GJ\\\`-DYZL#6.>J\\\`UR/\\\`0\\\`\\\`)Q@\\\`
M#*WA\\\`\\\`"/\\\`?_X)>\\\\\\\`#*WA__B/\\\`?_\\\\%PG_^*WA__R/\\\`0\\\`\\\`CX2\\\`%*WA\\\`\\\`"/F8!0
M)(0!\\\$\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`CZL#L(^\\\\\\\`"\\\`D"@\\\`!*6\\\$\\\`\\\`A0@\\\`06OJ@.HCZT#J(^L\\\`[0\\\`
M#7"\\\`CX6\\\`%(^9@&@!CD\\\`AC00\\\`\\\`\\\`,@^\\\`DDI0\\\$XC[P\\\`(!!\\\`\\\`#X\\\`\\\`\\\`\\\`\\\`C[D#H\\\`\\\`\\\`
M\\\`\\\`\\\`7(\\\`\\\`Z\\\`\\\`\\\`\\\`\\\`(^X\\\`ZB/J0.T\\\`!AX@\\\`\\\$O4"&-2P\\\`\\\`CYF\\\`@"0%\\\`"^OJP.D\\\`R#X
M"0%@("6/O\\\`\\\`@\\\$\\\$\\\`\\\`#P\\\`\\\`\\\`\\\`"/F8"\\\`CZ0#I\\\`,@^\\\`DD!0\\\`OC[P\\\`("1-\\\`\\\`&/F8"\\\`
MKZT#I(^D\\\`Z0#(/@))\\\`4\\\`+X^\\\\\\\`"\\\`40/_S\\\`\\\`\\\`\\\`\\\`(^9@'B/I\\\`.D\\\`R#X"0\\\`\\\`\\\`\\\`"/
MO\\\`\\\`@\\\`\\\$"\\\`)8^9@'R/I0.D)@;__\\\`,@^\\\`DGI\\\`\\\`PC[P\\\`(">D\\\`#"/A8\\\`4CYF\\\`="2E
M\\\`4\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^N\\\`ZB/K\\\`.T\\\`\\\`Y\\\`@\\\`&(R"&/O\\\`\\\`@CS@\\\`\\\`(^9@)BON\\\`.D\\\`R#X
M"0,\\\`("6/O\\\`\\\`@KZ(#H(^O\\\`ZB/J0.T\\\`\\\`]0@(^%@!2/F8!H\\\`2I8(8UD\\\`\\\`\\\`#(/@)
M)*4!2(^\\\\\\\`"\\\`40\\\`\\\`-\\\`\\\`\\\`\\\`\\\`(^N\\\`ZB/K0.T\\\`\\\`Y@@(^%@!2/F8!H\\\`:Q\\\`(8T\\\$\\\`\\\`\\\`#
M(/@))*4!4(^\\\\\\\`"\\\`00\\\`\\\`+\\\`\\\`\\\`\\\`\\\`(^X\\\`ZB/N0.T\\\`!AX@\\\`,O2"&/F8!PC24\\\`\\\`\\\`,@
M^\\\`DGI\\\`\\\`PC[P\\\`(\\\`\\\`\\\`\\\`\\\`"/JP.HCZH#M\\\`\\\`+<(\\\`!3F@AC:P\\\`\\\`"0!\\\`"V1B\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`!4!\\\`(H\\\`\\\`\\\`\\\`\\\`CX6\\\`%(^9@&@!@"\\\`E\\\`R#X"22E\\\`5B/O\\\`\\\`@\\\$\\\$\\\`\\\`\\\`P\\\`\\\`\\\`\\\`\\\`D&\\\`\\\`!
MK[@#5(^O\\\`ZB/N0.T\\\`\\\`](@\\\`,I6"&/F8!HCX6\\\`%(UD\\\`\\\`\\\`#(/@))*4!8(^\\\\\\\`"\\\`0
M0\\\`\\\`#\\\`\\\`\\\`\\\`\\\`"0*\\\`\\\`&OJ@-4CZT#J(^N\\\`[0\\\`#4"\\\`CX6\\\`%(^9@&@!R&\\\`AC80\\\`\\\`\\\`,@
M^\\\`DDI0%HC[P\\\`(!!\\\`\\\`!\\\$\\\`\\\`\\\`\\\`\\\`C[@#L(^O\\\`Z@\\\`\\\`\\\`\\\`\\\`\\\`?@(*A\\\`@\\\`\\\`L\\\`\\\`\\\`\\\`\\\`C[D#
MM\\\`\\\`/2(\\\`#*5@ACYF\\\`;(UD\\\`\\\`0#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`"#GH0-@YZ\\\`#9(^M\\\`ZB/J@.T
M\\\`\\\`UP@(^%@!2/F8!H\\\`4Y\\\`(8T\\\$\\\`\\\`\\\`#(/@))*4!<(^\\\\\\\`"\\\`00\\\`\\\`1\\\`\\\`\\\`\\\`\\\`(^L\\\`["/
MN\\\`.H\\\`\\\`\\\`\\\`\\\`\\\`,,""H0(\\\`\\\`+\\\`\\\`\\\`\\\`\\\`(^O\\\`[0\\\`&,B\\\`\\\`?E((8^9@&R-)\\\`\\\`\\\$\\\`R#X"0\\\`\\\`
M\\\`\\\`"/O\\\`\\\`@YZ\\\$#6.>@\\\`UR/K0.HCZL#M\\\`\\\`-4("/A8\\\`4CYF\\\`:\\\`%J<"&-Q\\\`\\\`\\\`\\\`R#X
M"22E\\\`7B/O\\\`\\\`@\\\$\\\$\\\`\\\`+@\\\`\\\`\\\`\\\`"/K\\\`.HCZ@#L"68\\\`\\\`0!&\\\`@J%"\\\`\\\`*\\\`\\\`\\\`\\\`\\\`"/KP.T
M\\\`\\\`S(@\\\`'Y2"&/F8!4C20\\\`!\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`CZL#J(^\\\\\\\`""/K0.T\\\`\\\`M0@(^9@%2O
MH@-0\\\`:IP(8W\\\$\\\`\\\`@#(/@)\\\`\\\`\\\`\\\`\\\`(^X\\\`ZB/O\\\`\\\`@CZ@#M\\\`\\\`88("/F8!4KZ(#3\\\`\\\$,
M>"&-Y\\\`\\\`,\\\`R#X"0\\\`\\\`\\\`\\\`"/J0.HC[D#M(^\\\\\\\`"\\\`\\\`"5B\\\`\\\`RMH(8^9@%2OH@-(C:0\\\`
M\\\$\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`(*^B\\\`T2/J@.HC[@#L"5.\\\`\\\`\\\$!V\\\`@J%"#^_:^N\\\`ZB/B("X
M)\\\`\\\$\\\`\\\`HT(\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$0\\\$"^P\\\`\\\`\\\`\\\`"/K\\\`.@\\\`\\\`\\\`\\\`\\\`!&\\\`\\\`O<\\\`\\\`\\\`\\\`\\\`CX2\\\`%(^9@%"/
MI0.D)Z8\\\`,\\\`,@^\\\`DDA\\\`&\\\`C[P\\\`((^F\\\`UB/A(\\\`4CYF\\\`4(^G\\\`UP#(/@))(0!F,>Q
M\\\`V#'L\\\`-D1("8\\\`\\\$2\\\`D\\\`"/O\\\`\\\`@1C*\\\`,@\\\`\\\`\\\`\\\`!%\\\`\\\`\\\`)\\\`\\\`\\\`\\\`\\\`(^\\\$@!2/F8!0)(0!
MK\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`(!\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`\\\`CX2\\\`%(^9@%"/I@-@CZ<#9\\\`,@^\\\`DDA\\\`'\\\$
MC[P\\\`(\\\`\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`4"2\\\$\\\`>\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`""/I0.DCX2\\\`%(^9@%\\\`D
MA\\\`'D\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@)\\\`0#\\\$(^9@*0\\\`\\\`\\\`\\\`\\\`\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@KZ(#F(^9
M@*0D!\\\`,4\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@KZ(#E(^9@*0D!\\\`,\\\`\\\`R#X"0\\\`\\\`\\\`\\\`"/O\\\`\\\`@KZ(#
MD(^9@*\\\`D!\\\`,@\\\`R#X"0\\\`\\\`\\\`\\\`"/KP-(C[P\\\`(!7@\\\`\\\`3GH\\\`.,CZD#D\\\`\\\`\\\`\\\`\\\`"OJ0-(
MC[D#1\\\`\\\`\\\`\\\`\\\`\\\`7(\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`(^K\\\`Y0\\\`\\\`\\\`\\\`\\\`KZL#1(^M\\\`TB/J@-0\\\`\\\`\\\`\\\`\\\`\\\`&J""H0
M(\\\`\\\`%\\\`\\\`\\\`\\\`\\\`*^J\\\`ZB/K@.HKZT#4*^N\\\`TB/N\\\`-\\\$CZ@#3\\\`\\\`\\\`\\\`\\\`\\\`#"\\\`@J\\\$"\\\`\\\`!0\\\`\\\`
M\\\`\\\`"OJ\\\`.HCZP#J*^X\\\`TROK\\\`-\\\$CX2\\\`%(^O\\\`T2/F8!0CZ4#4(^F\\\`TR/IP-()(0!
M\\\\\\\`,@^\\\`FOKP\\\`0C[P\\\`((^E\\\`YB/F8",)\\\`0\\\`\\\`0,@^\\\`D\\\`\\\`\\\`\\\`\\\`CZD#1(^Y\\\`TR/O\\\`\\\`@
M\\\`3DH(X^9@(ROH@-\\\`\\\`R#X"20\\\$\\\`\\\`2/O\\\`\\\`@)\\\`\\\$\\\`\\\`8^+@+BOH@.("/O\\\`\\\`@\\\`P]((:TB\\\`\\\`"/JP-0C[D#2*^@\\\`X@#*U\\\`C&4\\\`\\\`E\\\`\\\`\\\`\\\`\\\`"/K0-0
MCZX#B(^X\\\`T\\\`!KD\\\`A\\\`\\\`A@0*^H\\\`Z@##'@AA>D\\\`\\\`"0!__\\\\5(0\\\`-\\\`\\\`\\\`\\\`\\\`(^Y\\\`X"/
MJ\\\`.\\\$CZT#G"E\\\`VC'I\\\`-L)G\\\`VB/
MKP.\\\$CZL#1(^M\\\`TPEZ\\\`\\\`!\\\`6W\\\`(P\\\$8""H4(/\\\\MKZ@#A(^9@\\\$2/I\\\`.@\\\`R#X"0\\\`\\\`
M\\\`\\\`"/K@-(CZH#4(^I\\\`T2/K\\\`-,\\\`",#+P\\\`9QZL#:,>J\\\`VR/O\\\`\\\`@\\\`\\\`\\\`\\\`
M\\\`(^9@\\\$P\\\`\\\`%@21(M\\\`\\\`\\\`\\\`\\\`\\\`\\\`!&@\\\$0A\\\`\\\`\\\`\\\`\\\`\\\$8P40/GI\\\`-LYZ4#:\\\`,@^\\\`E&(",&
MQ[,#8,>R\\\`V1\\\$@#@\\\`1(\\\`P\\\`(^\\\\\\\`"!&)I\\\`RYZ\\\$#:\\\$4\\\`\\\`!7GH\\\`-L/\\\`%\\\`%\\\$2!2\\\`!\\\$
M@\\\$\\\`\\\`QZL#:,>J\\\`VP\\\\\\\`4!P1BI\\\$\\\`D2!*\\\`!\\\$@"\\\`\\\`CX2\\\`%(^9@%!&,"2#)(0"2\\\$0'
MD\\\`!\\\$!I@\\\`Y[(#9\\\`,@^\\\`GGLP-@C[P\\\`(\\\`\\\`\\\`\\\`\\\`"/K@-(CZH#4,>K\\\`U@!RD@C1(DP
M\\\`,>J\\\`UQ&@#(A)!D\\\`\\\`20-\\\`=I&*D\\\$")\\\`@\\\`\\\`208\\\`\\\`*GK0\\\$XHZ\\\`!.D1,^\\\`!\\\$V?@\\\`
MHZ@!.T8@)"2GN\\\`\\\$\\\\1%GX\\\`\\\`\\\`\\\`\\\`\\\`\\\`S(0\\\`\\\$,SD\\\`>!,@\\\`!0\\\\\\\`4'@1(&(\\\`\\\$2\\\`@\\\`\\\`D
M&0\\\`!1C\\\`D\\\`439^\\\`\\\`\\\`\\\`\\\`\\\`\\\`1B"\\\$)\\\$19^\\\`\\\`\\\`\\\`\\\`\\\`\\\`,R\\\$\\\`!#,Y\\\`'@7(\\\`\\\`%\\\`\\\`\\\`\\\`\\\`\\\$09
M@\\\`\\\`\\\\\\\`8\\\`\\\`\\\$\\\`\\\`\\\`!P,AR"40\\\`\\\`\\\`%)!G__T09@\\\`\\\`\\\`\\\`\\\`\\\`\\\`!R#_^P\\\`\\\`\\\`\\\`"/KP-\\\$CZL#
M3\\\$3,^\\\`\\\`!ZV@C1(V0\\\`"08\\\`\\\`%&@)&AI[D!/D8J,@)\\\$2/@\\\`1-CX\\\`\\\`\\\`\\\`\\\`\\\`!&(\\\$\\\$D
M1%CX\\\`\\\`\\\`\\\`\\\`\\\`\\\`S\\\`0\\\`\\\$,Q@\\\`>!,\\\`\\\`!0\\\\\\\`4'@1(\\\$H\\\`\\\$2\\\`(\\\`\\\`D&\\\`\\\`!1B1!\\\`438^\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`1B\\\`A)\\\$18^\\\`\\\`\\\`\\\`\\\`\\\`\\\`,P\\\$\\\`!#,8\\\`'@7\\\`\\\`\\\`%\\\`\\\`\\\`\\\`\\\`\\\$08(\\\`\\\`\\\\\\\`8\\\`\\\`\\\$\\\`\\\`\\\`!P,!
MP"40\\\`\\\`\\\`%)!C__T08(\\\`\\\`\\\`\\\`\\\`\\\`\\\`!P#_^P\\\`\\\`\\\`\\\`"GN\\\`%\\\`EZH!0#,I__\\\\!*@\\\`9)\\\`X\\\`
M\\\`:>N\\\`4*7KP%"CYF\\\`C\\\$3(^\\\`\\\`D!0\\\`!\\\`\\\`!@\\\$@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`8\\\\\\\`&0\\\`\\\`(!(#(/@)
M\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`""OH@\\\$TCYF\\\`?(^E\\\`30GI\\\`\\\$X)(0\\\`%\\\`,@^\\\`DD!@\\\`\\\$C[P\\\`(">D\\\`3B/
MF8!\\\\CZ4!-"2\\\$\\\`&P#(/@))\\\`8!E(^\\\\\\\`"\\\`D"P#_CX6\\\`%(^9@'\\\`GI\\\`\\\$XKZ\\\`!1*^K
M\\\`4@DA\\\`\\\`8\\\`R#X"22E\\\`F2/O\\\`\\\`@KZ\\\`!H(^\\\$@!2/F8!0)(0";\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`EZT!
M0(^\\\\\\\`"\\\`9H\\\`"(KZ\\\`#A)>H\\\`3ZOH\\\`.(&0\\\`\\\`?@\\\`\\\`\\\`\\\`"/N\\\`.\\\$QZ<#6\\\$28@\\\`#'I@-<
M1H"\\\$H8^K\\\`XB/J@.<1B:2@T2+(\\\`!\\\$3O@\\\`\\\`\\\`\\\`\\\`\\\`#7!\\\`\\\`,X(0\\\`"1,'X\\\`\\\`\\\`\\\`\\\`\\\`!&
M(%(D1,[X\\\`\\\$090\\\`!&@"0A\\\`!E(@\\\`%)8"%&)H2#C8\\\\\\\`\\\`\\\$1-^\\\`\\\`\\\`\\\`\\\`\\\`\\\`-:\\\$\\\`\\\`S@A
M\\\`\\\`)\\\$P?@\\\`\\\`\\\`\\\`\\\`\\\`\\\$8@DJ1\\\$"%\\\`\\\`1,WX\\\`\\\`\\\`(P(\\\`!^'\\\`AC=D\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\$F4\\\`\\\`!R\\\$\\\`
M!D:\\\`02\\\$\\\\\\\`4'P1(&(\\\`\\\$2\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`1C\\\`A\\\`,>G\\\`V#'I@-DCX&\\\`%\\\$8F)(+\\\$*P3\\\`
MQ"H\\\$Q\\\`\\\`\\\`\\\`\\\`!&,E\\\`\\\\Y[(#=\\\$4\\\`\\\`\\\`?GLP-PCX&\\\`%\\\`\\\`\\\`\\\`\\\`#\\\$*03(Q"@\\\$S.>I\\\`W#G
MJ\\\`-TCZH#5\\\`\\\`\\\`\\\`\\\`\\\`10\\\`\\\`)CX&\\\`%,>E\\\`W#'I\\\`-TQ#\\\$\\\$T,0P!-0\\\`\\\`\\\`\\\`\\\`1B2!@>>F
M\\\`W3GIP-P1\\\$GX\\\`"0,\\\`\\\`%\\\$S/@\\\`Q[,#<,>R\\\`W0\\\`\\\`\\\`\\\`\\\`1B"2I\\\$1,^\\\`\\\`\\\`\\\`\\\`\\\`\\\`,8\\\$\\\`
M!#&,\\\`'@1@\\\`\\\`4/\\\`%!X\\\$2!6\\\`!\\\$@%\\\`\\\`)\\\`P\\\`\\\`48JDH%\\\$S/@\\\`\\\`\\\`\\\`\\\`\\\`\\\$8@4J1\\\$3/@\\\`
M\\\`\\\`\\\`\\\`\\\`#&!\\\`\\\`0QC\\\`!X%8\\\`\\\`!0\\\`\\\`\\\`\\\`!\\\$#%\\\`\\\`/\\\`&\\\`\\\`!\\\`\\\`\\\`\\\`M\\\`3Z/KP.(\\\`6T\\\`&8^N\\\`31\\\$R?@\\\`\\\`\\\`!\\\`\\\$@\\\$/
MP"\\\$!V,@AHRP\\\`\\\`(^J\\\`XB7JP\\\$^)4D\\\`\\\`0\\\$K""H4(/^\\\$KZD#B(^M\\\`X27KP%\\\`):@\\\`
M\\\`0\\\$/""H4(/]ZKZ@#A(^%@!2/F8!()Z0\\\`,\\\`,@^\\\`DDI0*\\\$KZ(!,(^N\\\`3"/O\\\`\\\`@
M\\\$<\\\`\\\`)@\\\`\\\`\\\`\\\`"/A(\\\`4CYF\\\`4">E\\\`#\\\`#(/@))(0"B(^\\\\\\\`""/IP\\\$PCYF\\\`/">D\\\`3@D
M!0(\\\`\\\`R#X"20&\\\`\\\`&7N\\\`\\\$^EZP!0)>J\\\`4(##\\\`\\\`9C[P\\\`((^D\\\`323I0\\\$[CZ<8TP#F>\\\`A)[W[
MV(^%@!2/F8!(KZ0\\\$**^_\\\`!R/I\\\`0HK[P\\\`&\\\`,@^\\\`DDI01TKZ(\\\$)(^N!"2/O\\\`\\\`8
M\\\$<\\\`\\\`/\\\`\\\`\\\`\\\`\\\`"/F8"(CX2\\\`O"0%\\\`\\\`\\\$D!@@\\\`\\\`R#X"0'\\\`."6/O\\\`\\\`8)Z0\\\`)(^9@)P\\\`
M\\\`"@E\\\`R#X"20&\\\`\\\`:/O\\\`\\\`8)Z0\\\`)(^%@!2/F8!D)*4\\\$>\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`&!!\\\`
M\\\`!&/@8"XCX2\\\`%(^9@%\\\`D#P\\\`"CZ4\\\$**PO\\\`\\\`\\\`#(/@))(0\\\$@(^\\\\\\\`!B/I\\\`0DCYF\\\`
M1\\\`\\\`\\\`\\\`\\\`\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`!@0\\\`\\\`\\\`@KZ\\\`\\\$)(^9@)PGI\\\`\\\`D)\\\`4#+\\\`,@^\\\`DD!@\\\`\\\$
MC[P\\\`&">D\\\`"2/A8\\\`4CYF\\\`9"2E!+\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^\\\\\\\`!@40\\\`\\\`#CX&\\\`N!\\\`\\\`\\\`\\\`^L
M(\\\`\\\`\\\`CX&\\\`N"08\\\`\\\`\\\$0\\\`\\\`\\\`+K#@\\\`\\\`(^\\\$@!2/F8!\\\`)(0\\\$N\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`&"09
M\\\`\\\`*/@8"X\\\`\\\`\\\`\\\`\\\`*PY\\\`\\\`"/OP\\\`<8>0#F>\\\`A)[W_
MX*^E\\\`"2/K@\\\`DCX^\\\`O(^9@&"OI\\\`\\\`@KZ8\\\`**^_\\\`!R/I@\\\`HCZ0\\\`(*^\\\\\\\`!@#(/@)
M\\\`<\\\\H(8^X\\\`""/N0\\\`HC[P\\\`&\\\`,90"&A\\\`\\\`\\\`\\\`CYF\\\`L(^D\\\`"\\\`#(/@)\\\`\\\`\\\`\\\`\\\`(^_\\\`!R/
MO\\\`\\\`8CZ(\\\`(\\\`/@\\\`\\\`@GO0\\\`@/!P/P"><86P#F>\\\`A)[W_V*^D\\\`"B/K@\\\`HCX^\\\`O(^9
M@&"OOP\\\`D\\\`"0D!@\\\`\\\$\\\`R#X"0'/*"&/O\\\`\\\`8)\\\`\\\$\\\`\\\`8^8@+@\\\`\\\`\\\`\\\`\\\`CQ@\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`7\\\`0\\\`+\\\`\\\`\\\`\\\`\\\`">Y\\\`"2/(0\\\`\\\`\\\`R\\\`@)8^9@*ROH0\\\`\\\$CZ4\\\`!\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`
MC[P\\\`&\\\`\\\`\\\`\\\`\\\`"/OP\\\`<8-P#F>\\\`A)[W_V*^D\\\`"B/
MK@\\\`HCX^\\\`O(^9@&"OOP\\\`D\\\`"0D!@\\\`\\\$\\\`R#X"0'/*"&/O\\\`\\\`8)\\\`\\\$\\\`\\\`8^8
M@+@\\\`\\\`\\\`\\\`\\\`CQ@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`7\\\`0\\\`+\\\`\\\`\\\`\\\`\\\`">Y\\\`"2/(0\\\`\\\`\\\`R\\\`@)8^9@*BOH0\\\`\\\$CZ4\\\`
M!\\\`,@^\\\`D\\\`\\\`\\\`\\\`\\\`C[P\\\`&\\\`\\\`\\\`\\\`\\\`"/OP\\\`<8\\\$\\\`#F>\\\`A)[W_^*^E\\\`\\\`PGK@\\\`,D<\\\\\\\`\\\`R>X\\\`\\\`0GN0\\\`,HP\\\\\\\`\\\`),H\\\`\\\`(G
MJ0\\\`\\\$)ZH\\\`#*\\\$H\\\`\\\`&12P\\\`!)ZP\\\`!">M\\\`\\\`RABP\\\`"D:X\\\`\\\`">O\\\`\\\`0GN\\\`\\\`\\\$H>X\\\`\\\`X\\\\!
M\\\`\\\`\\\`GO0\\\`(\\\`(\\\`0)0/@\\\`\\\`BL@0\\\`\\\`/!P/P"><7]0#F>\\\`A)[W_^*^E\\\`\\\`PGK@\\\`,D<\\\\\\\`
M\\\`2>X\\\`\\\`0GN0\\\`,HP\\\\\\\`\\\`),H\\\`\\\`\\\`GJ0\\\`\\\$)ZH\\\`#*\\\$H\\\`\\\`&12P\\\`#)ZP\\\`!">M\\\`\\\`RABP\\\`"
MD:X\\\`\\\`B>O\\\`\\\`0GN\\\`\\\`\\\$H>X\\\`\\\`Y,9\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$R\\\`\\\`\\\`P\\\`\\\`\\\`\\\`\\\`G*/__HP@\\\`\\\`">I\\\`\\\`2-
M(0\\\`\\\`)[T\\\`"\\\`"\\\`\\\$"4#X\\\`\\\`(K(\\\$\\\`\\\`#P<#\\\\\\\`GG%],\\\`YG@(2>]_]BOI0\\\`LCZX\\\`+*^_
M\\\`!ROO\\\`\\\`8KZ0\\\`*!G\\\`\\\`!*OH\\\`\\\`DC[@\\\`)(^O\\\`"@\\\`&,B\\\`\\\`?E\\\`(8T!\\\`\\\`"/F8"HKZ\\\$\\\`
M!(^E\\\`\\\`0#(/@)\\\`0\\\`@)8^K\\\`"2/K0\\\`L)6P\\\`\\\`8^\\\\\\\`!@!C0@J%"#_\\\\*^L\\\`"2/OP\\\`<
M)[T\\\`*\\\`/@\\\`\\\`@\\\`\\\`\\\`\\\`\\\`/!P/P"><7LP#F>\\\`A)[W_V*^E\\\`"R/K@\\\`LK[\\\\\\\`'*^\\\\\\\`!BO
MI\\\`\\\`H&<\\\`\\\`\\\$J^@\\\`"2/N\\\`\\\`DCZ\\\\\\\`*\\\`\\\`8R(\\\`!^4\\\`AC0\\\$\\\`\\\`(^9@*ROH0\\\`\\\$CZ4\\\`!\\\`,@
M^\\\`D!\\\`"\\\`ECZL\\\`)(^M\\\`"PE;\\\`\\\`!C[P\\\`&\\\`&-""H4(/_PKZP\\\`)(^_\\\`!PGO0\\\`H\\\`^\\\`\\\`
M"\\\`\\\`\\\`\\\`\\\`\\\`\\\\'\\\`_\\\`)YQ>3\\\`.9X"\\\$GO?_8CYF\\\`>*^D\\\`"BOOP\\\`2!*86UEF]O;0\\\`\\\`\\\`"UB;W@\\\`\\\`\\\`\\\`\\\`8V]N=F5R=&EN9R\\\`E"!F&5L(3H@*"4T9"P@)31D*2\\\`]("4T9\\\`H\\\`
M\\\`\\\`!I;G1E;G-I='D@#\\\$@>3\\\$@('@R('DR72!;
M+6YE9V%T95T*\\\`\\\`H)(&9R86UE9FEL92YO6]U('=A;G0@=&\\\\@8V]N=F5R=\\\`H\\\`\\\`\\\`D@("!O=71F:6QE+G)G8B\\\`M(&YA
M;64@;V8@;W5T<'5T(%-'22!21T(@9FEL92X*\\\`\\\`D@("\\\`@("\\\`@(&9A8W1O#\\\$@>3\\\$@('@R('DR("T@
M8V]R;F5R0\\\`\\\`\\\`5,\\\`\\\`!.<\\\`\\\`\\\`\\\`
M!0\\\`\\\`!.>0\\\`\\\`\\\`\\\`_____/____\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`'0\\\`?\\\`\\\`\\\`!?@\\\`\\\`\\\`8,\\\`\\\`\\\`%M
M\\\`\\\`\\\`4%\\\`\\\`\\\`\\\`\\\`<\\\`\\\`\\\`4%D\\\`\\\`\\\`\\\`/____3_____\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`H\\\`!T\\\`'P\\\`\\\`\\\`8<\\\`
M\\\`\\\`&-\\\`\\\`\\\`!>@\\\`\\\`%*0\\\`\\\`\\\`\\\`)\\\`\\\`\\\`%*9\\\`\\\`\\\`\\\`#____T_____P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`*\\\`\\\`=
M\\\`!\\\\\\\`\\\`\\\`&1\\\`\\\`\\\`!EP\\\`\\\`\\\`8\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`/____\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`@\\\`'0\\\`?\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`!\\\$\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`;\\\`\\\`\\\`\\\`\\\`,\\\`\\\`\\\`\\\`;\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`#_____
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(\\\`!T\\\`'P\\\`\\\`\\\`!4\\\`\\\`\\\`\\\`?\\\`\\\`\\\`\\\`#@\\\`\\\`\\\`/0\\\`\\\`\\\`\\\`%\\\`\\\`\\\`\\\`/9\\\`\\\`\\\`\\\`#_
M___T_____P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`*\\\`\\\`=\\\`!\\\\\\\`\\\`\\\`\\\`C\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`!T\\\`\\\`\\\`%T\\\`\\\`\\\`\\\`!P\\\`\\\`
M\\\`%V0\\\`\\\`\\\`\\\`____]/____\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"@\\\`'0\\\`?\\\`\\\`\\\`\\\`,\\\`\\\`\\\`\\\`#D\\\`\\\`\\\`\\\`G\\\`\\\`\\\`!
M]\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`!]D\\\`\\\`\\\`\\\`/____3_____\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`H\\\`!T\\\`'P\\\`\\\`\\\`#T\\\`\\\`\\\`!)
M\\\`\\\`\\\`\\\`,0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`"P\\\`\\\`\\\`\\\`P\\\`\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`!P\\\`
M\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`"(\\\`\\\`\\\`\\\`\\\`"*___P\\\`\\\`\\\`"@\\\`0\\\`XP&"\\\`\\\`\\\`@\\\`\\\`\\\`#\\\`\\\`0\\\`X\\\\%"___P\\\`\\\`
M\\\`"@\\\`\\\`\\\`\\\$(("\\\`\\\`!0\\\`\\\`\\\`#X\\\`0\\\`\\\\X&"\\\`\\\`!@\\\`\\\`\\\`#X\\\`\\\`\\\`\\\`0("\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`
M("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`
M\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`#\\\`\\\`\\\`
M\\\`\\\`L\\\`0\\\`]0&"\\\`\\\`#P\\\`\\\`\\\`\\\`L\\\`\\\`!(T("\\\`\\\`\\\`0\\\`\\\`\\\`!\\\`\\\`0"&\\\$&"\\\`\\\`\\\$0\\\`\\\`\\\`!\\\`\\\`\\\`\\\`%H("\\\`\\\`
M\\\`P\\\`\\\`\\\`!D\\\`0"+L&"\\\`\\\`\\\$P\\\`\\\`\\\`!D\\\`\\\`\\\`!X("\\\`\\\`!0\\\`\\\`\\\`",\\\`0"-D&"\\\`\\\`%0\\\`\\\`\\\`",\\\`\\\`\\\`"0
M("\\\`\\\`!P\\\`\\\`\\\`"P\\\`0"/T&"\\\`\\\`%P\\\`\\\`\\\`"P\\\`\\\`\\\`"0("\\\`\\\`"0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`
M\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`#\\\`\\\`\\\`\\\`\\\`L\\\`0"20&"\\\`\\\`#P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`!L("\\\`\\\`\\\`0\\\`\\\`\\\`!,\\\`0"3\\\\
M&"\\\`\\\`\\\$0\\\`\\\`\\\`!,\\\`\\\`\\\`"(("\\\`\\\`\\\`P\\\`\\\`\\\`!T\\\`0"6\\\$&"\\\`\\\`\\\$P\\\`\\\`\\\`!T\\\`\\\`\\\`"\\\`("\\\`\\\`!0\\\`\\\`\\\`"H\\\`
M0"8\\\$&"\\\`\\\`%0\\\`\\\`\\\`"H\\\`\\\`\\\`"\\\`("\\\`\\\`!P\\\`\\\`\\\`#D\\\`0":\\\$&"\\\`\\\`%P\\\`\\\`\\\`#D\\\`\\\`\\\`"@("\\\`\\\`"0\\\`\\\`
M\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`+"\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`("\\\`\\\`\\\`/____\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M"\\\`\\\`\\\`\\\`\\\`#_____\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`H\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`,\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`8\\\`\\\`\\\`\\\`'\\\`\\\`\\\`\\\`
M"\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`(0\\\`\\\`\\\`\\\`H\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`!H\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`P8\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`%!@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`<&\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"08\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+!@\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`
M\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`
M"P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)
M\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`
M\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"\\\$\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`
M"P\\\`\\\`\\\`\\\`L\\\`\\\`\\\`\\\`:\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`,&\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!08\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`'!@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`D&
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"P8\\\`\\\`\\\`\\\`\\\`8W)T,71E>'0N%]F;&]A=%]L:7-T\\\`&YO%]F;&]A=\\\`!F:7A?:6YT\\\`&9I>%]I;G1?;&ES=\\\`!F:7A?
M9FQO871?;&ES=\\\`!?7V5L9E]H96%D97(\\\`7U]P'0\\\`7V9D871A\\\`%]F8G-S\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#C\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\$8\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!&\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`"1F\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`+P!\\\`#C\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`1@\\\`\\\`\\\`"@\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`
M#C\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`;@\\\`\\\`\\\`"D\\\`\\\`\\\`\\\`-\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`
M"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`2\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#C\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`EP\\\`\\\`\\\`"X\\\`\\\`\\\`\\\`/
M\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`;\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#C\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`Q0\\\`\\\`\\\`"4\\\`\\\`\\\`\\\`1\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`"1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#C\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`
MZ@\\\`\\\`\\\`\\\`T\\\`\\\`\\\`\\\`3\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`M
M\\\`\\\`\\\`\\\`\\\`1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#U\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`]P\\\`\\\`\\\`#,\\\`\\\`\\\`\\\`5\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\$8\\\`
M\\\`\\\`5-\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`@\\\`%\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`!D\\\`\\\`\\\`\\\`N\\\`\\\`\\\`\\\`!0&\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`O\\\`\\\`\\\`!B\\\`!\\\`
M#U\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!*@\\\`\\\`\\\`!8\\\`\\\`\\\`\\\`A\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`\\\`\\\`
M(0\\\`\\\`\\\`\\\`\\\\\\\`\\\`\\\`\\\`S\\\`\\\`\\\`\\\`!06\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#U\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`!<\\\`\\\`\\\`\\\`C
M\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`\\\`\\\`,\\\`\\\`\\\`\\\`\\\`\\\\\\\`\\\`\\\`\\\`X\\\`\\\`\\\`\\\`!06\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#U\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!5P\\\`\\\`\\\`!4\\\`\\\`\\\`\\\`E\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`\\\`\\\`/P\\\`\\\`\\\`\\\`\\\\\\\`\\\`\\\`\\\`]\\\`\\\`\\\`\\\`!06\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#U\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!
M;\\\`\\\`\\\`\\\`\\\`T\\\`\\\`\\\`\\\`G\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!0\\\`\\\`\\\`\\\`\\\`\\\`3@\\\`\\\`\\\`\\\`\\\\\\\`\\\`\\\`!"
M\\\`\\\`\\\`\\\`!06\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`))\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!>0\\\`\\\`\\\`\\\$(\\\`\\\`\\\`\\\`I\\\`\\\`\\\`\\\`#\\\`\\\`\\\`!9,\\\`
M\\\`\\\`"E\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!P\\\`%\\\`\\\`\\\`\\\`70\\\`\\\`\\\`!D\\\`\\\`\\\`!'\\\`\\\`\\\`\\\`\\\`0&\\\`\\\`\\\`\\\`\\\`\\\`\\\`&W\\\`\\\`\\\`\\\`/@!\\\`
M)<\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`!NP\\\`\\\`\\\`\\\`P\\\`\\\`\\\`\\\`U\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!(\\\`\\\`\\\`\\\`\\\`1V\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#
M\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`
M\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!\\\`\\\`\\\`\\\`
M\\\`0\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`#\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`0\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`4\\\`\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)
M\\\`\\\`\\\`\\\`"@\\\`\\\`\\\`\\\`8\\\`\\\`\\\`\\\`'\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`\\\`<\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`"0\\\`\\\`\\\`\\\`H\\\`
M\\\`\\\`\\\`&\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\`)\\\`\\\`\\\`\\\`"@\\\`\\\`\\\`\\\`8\\\`\\\`\\\`\\\`'\\\`\\\`\\\`\\\`"\\\`\\\`\\\`\\\`\\\`D\\\`\\\`\\\`\\\`*\\\`\\\`\\\`\\\`"P\\\`\\\`
M\\\`\\\`P\\\`\\\`/__\\\`\\\`\\\`\\\`\\\`\\\`!\\\`#,\\\`0+___\\\`\\\`#__P\\\`\\\`\\\`\\\`8\\\`0"___P\\\`\\\`__\\\\\\\`\\\`\\\`\\\`8
M\\\$\\\`\\\`\\\$X!&O__\\\\\\\`\\\`/__\\\`\\\`\\\`\\\`)A\\\`\\\`!:\\\`1S___\\\`\\\`#__P\\\`\\\`\\\`"P0\\\`\\\`6@\\\$&___P\\\`\\\`__\\\\\\\`
M\\\`\\\`'4\\\$\\\`\\\`5L!1O__\\\\\\\`\\\`/__\\\`\\\`\\\`!LP\\\`\\\`\\\`\\\`\\\`43___\\\`\\\`#__P\\\`\\\`\\\`#\\\$\\\`\\\`\\\`\\\`!%*___P\\\`\\\`
M__\\\\\\\`\\\`\\\`&/\\\`\\\$\\\`\\\`\\\`!1/__\\\\\\\`\\\`/__\\\`\\\`\\\`!G\\\`!\\\`\\\`#043___\\\`\\\`#__P\\\`\\\`\\\`>D\\\`0\\\`S\\\`%"__
M_P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!A\\\`\\\$\\\`.,!@@\\\`\\\`4\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`D0!\\\`#S@8(\\\`\\\`(\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`7,\\\`0"6\\\$
M&"\\\`\\\`!0\\\`\\\`\\\`\\\`L\\\`\\\`\\\`&\\\`\\\`\\\$\\\`F!!@@\\\`\\\`<\\\`\\\`/__\\\`\\\`\\\`!Q@!\\\`)U\\\`4+___\\\`\\\`#__P\\\`\\\`\\\`=D\\\`
M0"=0%"___P\\\`\\\`__\\\\\\\`\\\`\\\`'P\\\$\\\`\\\`\\\`\\\`!1/__\\\\\\\`\\\`/__\\\`\\\`\\\`!S1\\\`\\\`!:\\\`5K___\\\`\\\`#__P\\\`\\\`
M\\\`=\\\\0\\\`\\\`6@%:___P\\\`\\\`__\\\\\\\`\\\`\\\`'W\\\$\\\`\\\`%H!7/__\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`31\\\`\\\`%:@\\\$;___\\\`\\\`#_
M_P\\\`\\\`\\\`>40\\\`!6P%&___P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`!I\\\`\\\`\\\`\\\`\\\`\\\`3/__\\\\\\\`\\\`\\\`\\\`'\\\`\\\`\\\`!,@!\\\`#-\\\`8S___
M\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`4H\\\`0\\\`S@&,___P\\\`\\\`\\\`\\\`<\\\`\\\`\\\`\\\$@\\\`\\\$\\\`,\\\\!C/__\\\\\\\`\\\`\\\`\\\`'\\\`\\\`\\\`!+\\\`!\\\`#0\\\`8
MS___\\\`\\\`\\\`\\\`"0\\\`\\\`\\\`2<\\\`0\\\`T0&,___P\\\`\\\`\\\`\\\`<\\\`\\\`\\\`"S\\\`\\\$\\\`-(!C/__\\\\\\\`\\\`\\\`\\\`(\\\`\\\`\\\`\\\`\\\\P!\\\`
M#3\\\`8S___\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`%P\\\`0\\\`U\\\`&,___P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`![\\\`\\\$\\\`-4!C/__\\\\\\\`\\\`\\\`\\\`&\\\`\\\`\\\`!
M40!\\\`#6\\\`8S___\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`4,\\\`0\\\`UP&,___P\\\`\\\`\\\`\\\`8\\\`\\\`\\\`"Z\\\`\\\$\\\`-@!C/__\\\\\\\`\\\`\\\`\\\`(
M\\\`\\\`\\\`\\\`[@!\\\`#9\\\`8S___\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`.<\\\`0\\\`V@&,___P\\\`\\\`\\\`\\\`8\\\`\\\`\\\`#7\\\`\\\$\\\`-L!C/__\\\\\\\`
M\\\`\\\`\\\`&\\\`\\\`\\\`\\\`T\\\`!\\\`#<\\\`8S___\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`,@\\\`0\\\`W0&,___P\\\`\\\`\\\`\\\`8\\\`\\\`\\\`#!\\\`\\\$\\\`-X!C/
M__\\\\\\\`\\\`\\\`\\\`(\\\`\\\`\\\`!&P!\\\`#?\\\`8S___\\\`\\\`\\\`\\\`!P\\\`\\\`\\\`14\\\`0\\\`X\\\`&,___P\\\`\\\`\\\`\\\`@\\\`\\\`\\\`\\\$(\\\`\\\$\\\`.
M\\\$!C/__\\\\\\\`\\\`\\\`\\\`'\\\`\\\`\\\`!#P!\\\`#B\\\`8S___\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`(P\\\`0\\\`]0&"\\\`\\\`\\\`0\\\`\\\`\\\`\\\`8\\\`\\\`\\\`#>
M\\\`\\\$\\\`AA!@@\\\`\\\`,\\\`\\\`\\\`\\\`&\\\`\\\`\\\`!.0!\\\`(NP8(\\\`\\\`%\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`/\\\\\\\`0"-D&"\\\`\\\`!P\\\`\\\`\\\`\\\`8\\\`
M\\\`\\\`#X\\\`\\\$\\\`C]!@@\\\`\\\`D\\\`\\\`\\\`\\\`+\\\`\\\`\\\`!:P!\\\`))\\\`8(\\\`\\\`!\\\`\\\`\\\`\\\`"P\\\`\\\`\\\`6\\\$\\\`0"3\\\\&"\\\`\\\`\\\`P\\\`\\\`
M\\\`\\\`L\\\`\\\`\\\`%8\\\`\\\$\\\`FA!@@\\\`\\\`D\\\`\\\`\\\`\\\`%\\\`\\\`\\\`\\\`<@!\\\`)SP6S___\\\`\\\`\\\`\\\`!@\\\`\\\`\\\`*(0\\\`\\\`\\\`\\\`!\\\$__
M_P\\\`\\\`\\\`\\\`8\\\`\\\`\\\`"L\\\$\\\`\\\`%H\\\`1O__\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`/Q\\\`\\\`%:\\\`\\\$;___\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$80\\\`!6D
M!&___P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"9\\\$\\\`"\\\$T!2O__\\\\\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`"YT97AT\\\`"YI
M;FET\\\`"YF:6YI\\\`"YD871A\\\`"YS9&%T80\\\`N0!S=')L96X\\\`0!A=&]F\\\`&%T;VP\\\`1V5T26YT\\\`\\\$=E=\\\$9L;V%T\\\`&-A;&QO8P!F%]I
M;G0\\\`9FEX7VEN=%]L:7-T\\\`&9I>%]F;&]A=%]L:7-T\\\`%]?96QF7VAE861E<@!?
M7W!R;V=R86U?:&5A9&5R7W1A8FQE\\\`%]?9'-O7V1I'0\\\`7V5D871A\\\`%]E;F0\\\`971E>'0\\\`961A=&\\\$\\\`96YD\\\`%]F=&5X=\\\`!?9F1A=&\\\$\\\`
M7V9B6YA;6EC\\\`"YL:6)L
M:7-T\\\`"YM6YS='(\\\`+F1Y;G-Y;0\\\`N:&%S:\\\`\\\`N=&5X=\\\`\\\`N:6YI=\\\`\\\`N
M9&%T80\\\`N\\\`@\\\\!@("\\\`\\\$1\\\\!/P&\\\`@(!R+Q\\\$>\\\`H\\\`!86(!+@\\\$!,0-!#P
M\\\$2-X"\\\`@("\\\`\\\`0\\\\!/P\\\$/\\\`5&\\\`(H"\\\`@("\\\`"%__7EA0\\\`2\\\$/\\\`1)143\\\\!@"%T=6)A86
M%A86%A8Q\\\$?!4\\\`T'!0,!"(.\\\`A)C4H8=\\\`PT#(E(448,5-U(S,\\\$\\\$O(1\\\\!\\\$1\\\\!\\\$3
M(.\\\`B!#+1-!@'(P0RT308!R,\\\$0A#P\\\$1#P\\\$1#P\\\$2#@)\\\`0R\\\$/\\\`1\\\$/\\\`1\\\$/\\\`1(.\\\`E
M)00PTC\\\$X\\\`-(PTF,\\\$,-(Q.\\\`#2,-)C\\\`R#A(>\\\`A,=\\\`T*\\\`\\\$T(P\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`
M\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\$\\\`\\\`\\\`\\\`+\\\`\\\`\\\`\\\`\\\`@\\\`\\\`
M8+@\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`\\\`.\\\`(\\\`\\\`\\\`/P':4\\\`\\\$\\\`./&\\\`(\\\`\\\$4/P'6\\\`8\\\`@\\\$C0_\\\`8TQ@"\\\`!:#\\\\!A
MY&\\\`(\\\`!X/P&%L8\\\`@\\\`)\\\`_\\\`8-Q@"\\\`\\\`G#\\\\!@0&\\\`(\\\`!L/P%_48\\\`@\\\`(@_\\\`7TQ@"\\\`\\\`@
,#\\\\!>S&\\\`(\\\`"\\\`/P%Y,
\\\`
end
EOF

goto ReturnFrom_Decode


EOF-Spotter
chmod a+x  ${Elfsheim}/Spotter

echo -n "."






















# Processer
cat << EOF-Processer >! ${Elfsheim}/Processer
#! /bin/csh -f
#
echo "Processer Elves 1.3.6  Automatic, MAD multi-processing 	James Holton 10-2-10"
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
if("\$machine" == "") set machine = \`hostname\`
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}'\`
	        set testdirs = \`dirname \$image\`
		while ( "\$testdirs[\$#testdirs]" != "/" )
		    set testdirs = ( \$testdirs \`dirname \$testdirs[\$#testdirs]\` )
		end
		foreach testdir ( \$testdirs )
		    echo "looking for \$img in \$testdir"
		    set img = \`find \$testdir -name \$img -print |& nawk 'NF==1{print; exit}'\`
		    if(-e "\$img") then
		        set image = "\$img"
		        set image_dir = \`dirname "\$image"\`
		        echo "found \$image"
			break
		    endif
		end
	    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\`
    if("\$search_models" != "") then
	set firstmodel = \`echo \$search_models | nawk '{print \$1}'\`
	set MASS = \`nawk '/^ATOM/{mass+=14} END{print mass}' \$firstmodel\`
    endif
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 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"
    set temp = "4-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 -k2 | 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! "
    if(! -e mtz/all.mtz) then
        goto scale
    endif
    # maybe it is just broken?
    goto solve
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 -k3 | 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 -k3 | 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 -k6 \${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 -k2 >! \${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 -k3 \${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"
set best_phase_mtz = \$best_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 "" >! 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 -k3 \${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_warplog = \`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_phase_mtz) set best_phase_mtz = "mtz/all.mtz"
if(! \$?best_pdb) set best_pdb = ""
if(! \$?best_SG)  set best_SG  = P1
if(! \$?best_warplog) set best_warplog = ./wARP/\${best_SG}/logs/molrep.log
if(! \$?best_pharelog) set best_pharelog = ./phaser/\${best_SG}/logs/mlphare.log
set test = \`echo \${best_SG}/ \$best_warplog | nawk -F "/" '{for(i=2;i& /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 || "\$arg" == refining) 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! \${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! \${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<2000{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?




EOF-Processer
chmod a+x  ${Elfsheim}/Processer

echo -n "."






















# Phaser
cat << EOF-Phaser >! ${Elfsheim}/Phaser
#! /bin/csh -f
#
#	Phaser Elves		Automatic heavy-atom phase determination
#
#
echo "Phaser Elves v 1.3.6     Because trying everything isn't so hard.(TM)   James Holton 6-24-10"
echo ""
#
########################################################################################################
# Legal stuff
set temp = \`find \$0 -mtime +30 -print\`
if(("\$temp" == "")&&(\$#argv == 0)) cat << EOF-lawyers
Copyright 1999. The Regents of the University of California (Regents). All Rights Reserved. 

     Permission to use, copy, modify, and distribute this software and its 
     documentation for educational, research, and not-for-profit purposes, 
     without fee and without a signed licensing agreement, is hereby granted, 
     provided that the above copyright notice, this paragraph and the following 
     two paragraphs appear in all copies, modifications, and distributions. 
     Contact The Office of Technology Licensing, UC Berkeley, 2150 Shattuck 
     Avenue, Suite 510, Berkeley, CA 94720-1620, (510) 643-7201, for commercial 
     licensing opportunities. Created by James Holton, Department of Molecular 
     and Cell Biology, University of California, Berkeley. 
  
     IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 
     SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, 
     ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 
     REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  
     REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED 
     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
     PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 
     HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
     MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 

EOF-lawyers


###############################################################################

 #    #  ######  #       #####
 #    #  #       #       #    #
 ######  #####   #       #    #
 #    #  #       #       #####
 #    #  #       #       #
 #    #  ######  ######  #

###############################################################################
#
#   Help screen and program defaults
#
###############################################################################
if(("\$argv" =~ "-h")||(\$#argv == 0)) goto Help
goto Config

Help:
cat << EOF

usage: \$0 mtzfile.mtz sitefile Fnat n params Res_A

where:
    mtzfile.mtz  - CCP4 mtz file containing all your Fs

    sitefile
    mlphare.com  - previous mlphare input script
    mlphare.log  - previous mlphare output log
    sites.pdb    - Brookhaven-style PDB file containing your metal sites
    sites.res    - SHELX output file (.lst works too)
    solve.status - SOLVE status file (containing sites)
    sites.txt    - just any random list of sites
    
    Fnat         - F in mtzfile.mtz to use as native
    n		 - params/atom. 3=(XYZ) 6=(XYZ occ aocc B)
    Res_A	 - a resolution limit

all of these items are optional

examples:
Start refining sites from SOLVE
    \$0 mtz/all.mtz solve.status
Pick up where you left off
    \$0 scripts/mlphare.com
Run SHELX on anomalous differences and refine those sites
    \$0 mtz/all.mtz

EOF
exit





Config:
###############################################################################
#
#   Evaluate unix system
#
###############################################################################
# make sure nawk works
set program = "nawk"
foreach name ( nawk awk gawk )
    test -x "\$program"
    if(! \$status) break
    
    set possibilities = \`which \$name |& grep -v ' not in ' | tail -1\`
    foreach file ( \$possibilities )
	test -x "\$file"
	if(! \$status) then
	    # test for desired functionality (change this?)
	    set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
	    if("\$temp" == 856) then
		set program = "\$file"
		break
	    endif
	endif
    end
    unset possibilities
end
test -x "\$program"
if(\$status) then
    set program = "awk"
    foreach place ( /bin /usr/bin /usr/local/bin  )
	test -x "\$program"
	if((\$status)&&(-e \$place)) then
	    # keep looking
	    set files = \`ls -1L \${place} |& grep "\$program" |& sort -nr -k5 |& head -20 \`
	    foreach file ( \$files )
		# test for desired functionality
		set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
		if("\$temp" == 856) then
		    set program = "\$file"
		    break
		endif
	    end
	endif
    end
endif

# agressively search for nawk in likely places
test -x "\$program"
if(\$status) then
    echo -n "Looking for \$program "
    foreach place ( /bin /usr/bin /usr/local/bin /usr / )
	test -x "\$program"
	if((\$status)&&(-e \$place)) then
	    if("\$place" == "/") echo -n "uhh"
	    
	    # use find to get candidate files
	    set files = \`find \$place -name '*'\$program \\( -type l -o \\( -type f -size +10000c \\) \\) -perm -1 -print |& egrep -v "^find:" |& head -20\`
	    foreach file ( \$files )
		# test for desired functionality
		set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
		if("\$temp" == 856) then
		    set program = "\$file"
		    break
		endif
	    end
	endif
	
	# entertainment
	echo -n "."
    end
endif

# check that we found the right awk program
set temp = \`echo "1.54" | \$program '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
if("\$temp" == 856) then
    # set up this awk program as nawk
    set nawk = "\$program"
    alias nawk \$nawk
else
    echo "Dagnabbit!  We can't find a suitable awk program.  What kind of unix is this? "
    echo "Elves may not be able to work."
    set nawk = /bin/awk
    alias nawk awk
endif

# nice symbols, but may not be portable
set ANG = \`echo "" | nawk 'BEGIN{printf "\\305"}'\`
set DEG = \`echo "" | nawk 'BEGIN{printf "\\260"}'\`
#set ANG = "A"
#set DEG = "deg"

# fix OSF1 csh echo shortcomings
set temp = \`echo -n "test"\`
if((\$#temp == 2)&&(-e /usr/bin/echo)) then
    alias echo /usr/bin/echo
endif

if(! \$?CDOC) set CDOC
if(! \$?CCP4) then
    echo -n "Attempting to set up CCP4 ... "

    set ccp4setup = ""
    foreach place ( /programs/xtal/ccp4_3.4/ /usr/xtal/CCP4_v3.4/ /programs/xtal /programs/ /usr/xtal /usr/local /usr/ )
	if((! -e "\$ccp4setup")&&(-e "\$place")) then
	    # look for setup scripts here
	    set ccp4setup = \`find \${place} -name ccp4.setup |& nawk '/ccp4.setup\$/{print \$NF}' | tail -1\`
	endif
        if((-e "\$ccp4setup")&&(! \$?CCP4)) then
            source \$ccp4setup
            setenv CCP4_SCR    \`pwd\`
            setenv BINSORT_SCR \`pwd\`
            echo "using \$ccp4setup"
        endif
    end
endif
if(! \$?CCP4) then
    echo "failed."
    echo "Please ask your sysadmin how to set up CCP4, "
    echo "Or go to: netscape http://www.dl.ac.uk/CCP/CCP4/main.html"
    echo "about getting the CCP4 program suite."
    echo "and run \$0 again."
    
    echo "If you have Red Hat Linux, you can get ccp4 by typing:"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-lib-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-progs-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-etc-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-examples-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-doc-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-manual-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-html-3.5.1-5.i386.rpm"
    exit 9
    set CCP4_LIB
endif
setenv CCP4_OPEN       UNKNOWN
# make sure we can write to scratch directories
if(! \$?CCP4_SCR) setenv CCP4_SCR .
if(! \$?BINSORT_SCR) setenv BINSORT_SCR .

touch \${CCP4_SCR}/this\$\$ >& /dev/null
if(\$status) then
    # safest to do this
    setenv CCP4_SCR .
endif
rm -f \${CCP4_SCR}/this\$\$ >& /dev/null

touch \${BINSORT_SCR}/this\$\$ >& /dev/null
if(\$status) then
    # safest to do this
    setenv BINSORT_SCR .
endif
rm -f \${BINSORT_SCR}/this\$\$ >& /dev/null


# check that current directory is writable
touch ./this\$\$ >& /dev/null
if(\$status) then
    # can't write to current directory!
    chmod u+w . >& /dev/null
    touch ./this\$\$ >& /dev/null
    if(\$status) then
	# can't chmod current directory either
	echo "ERROR! We can't write to this directory!"
	pwd
	echo "Please cd to the place you want to process your data, and"
	echo "then run \$0 again."
	exit 9
    else
	# warn user about what we did
	echo "Had to make current directory writable:"
	echo "chmod u+w ."
    endif
    rm -f ./this\$\$ >& /dev/null
endif
rm -f ./this\$\$ >& /dev/null

# check free disk space
set freespace = \`df -k \$CCP4_SCR |& nawk 'NR>=2&&NF>2{avl=NF-2;print \$avl/1024}'\`
set test = \`echo \$freespace 100 | nawk '{print (NF==2 && \$1<\$2)}'\`
if(\$test) echo "WARNING: "'\$'"CCP4_SCR is getting full!  \${freespace}MB left. "
set freespace = \`df -k \$BINSORT_SCR |& nawk 'NR>=2&&NF>2{avl=NF-2;print \$avl/1024}'\`
set test = \`echo \$freespace 100 | nawk '{print (NF==2 && \$1<\$2)}'\`
if(\$test) echo "WARNING: "'\$'"BINSORT_SCR is getting full!  \${freespace}MB left."
set freespace = \`df -k . |& nawk 'NR>=2&&NF>2{avl=NF-2;print \$avl/1024}'\`
set test = \`echo \$freespace 100 | nawk '{print (NF==2 && \$1<\$2)}'\`
if(\$test) echo "WARNING: disk space is getting low! \${freespace}MB left. "


# fix old Irix od shortcomings
alias ood od
echo "test" >! ./this\$\$
set test = \`od -c -j 2 -N 4 this\$\$ |& nawk '{print \$2}'\`
if("\$test" != "s") then
    # no -j option supported, compensate:
    # od -x -j offset ... --> od -x ... offset
    alias od 'od \\!:1 \\!:\$ \\!:3.'
    alias ood /bin/od
    set WEAK_od
endif
rm -f ./this\$\$ >& /dev/null

# set Elves prompt
set PROMPT = "P. Elves-> "

# character for ringing the terminal bell (alert user)
set BELL = \`echo "" | awk 'BEGIN{printf "\\07"}'\`
set oldTTYerase = "^H"


# no dumping! 
limit coredumpsize 0

# go automatic if user is ignoring us
test -t 1
if(\$status) then
    echo "output is not a terminal."
    # Q&A would stop process cold
    echo "Elves will answer their own questions."
    echo ""
    echo "\$0 \$*"
    echo "as pid=\$\$ on "\`hostname -s\`" at "\`date +"%T %D"\`
    echo "in "\`pwd\`
    echo ""
    set AUTO
endif

# random script-control settings and utility variables
set MAXLINE    = 500
set FIRSTIME
set temp
set input
set info
set understood
set in



########################################################################################################
# Defaults
#
# required directories
set scriptDIR  = scripts/
set logDIR     = logs/
set mtzDIR     = mtz/
set mapDIR     = maps/
set oDIR       = o/

# default data file names
set mtzfile    = \${mtzDIR}all.mtz
set bestmtz    = \${mtzDIR}best_phased.mtz

# names of generated mlphare script
set scriptfile = \${scriptDIR}mlphare.com

set logfile    = \${logDIR}mlphare.log
set coordfile  = ./phaser_tempcoordfile
set tempfile   = ./phaser_temp

# potential input files
set shelxfile  = ""
set solvefile  = ""
set pdbfile    = ""
set sitefile   = ""
set inscript   = ""
set inlogfile  = ""

# preliminary program locations
set DM	    = dm
set SHELX   = /programs/shelx/sgi/shelxs
set MAPMAN  = /programs/o/rave/rave_irix6/6d_mapman
set BRIX    = /usr/bin/brix
set BONES   = /usr/bin/bones

# crystal parameters
set SG      = ""
set CELL    = ""
set hiRES   = ""

# refinement settings
set native  = ""
set fix     = "W"
set params  = 3
set mlphareCYCLES = 30

# mlphare convergence criteria
set converge_crit = 2
set Memory  = 0

# atom rejection parameters
set FILTER_ATOMS
set baddies = 0
set Bcap    = 500
set wilsonB = ""
set sites   = 0

# solvent-flattening settings
set SOLVENT = ""
set default_trials = "25 30 35 40 45 50 55 60 65 70"

# option to add difference-Fourier sites to the script
set MORE_SITES
set newSIG = 3

# sign/hand flipping variables
set FLIP_OCC
set FLIP_HAND
set FLIP_SG
set Cycle   = 0
set FOM	    = ""
set bestFOM = ""
set bestDMtrial
set biggest_bone = 0
set FLIP_state   = 1
set FLIP_label   = ""
set FLIP_labels  = ""

# for memory of original state
set firstmtz = ""
set firstSG  = ""
set otherSG  = ""

# random, empty initializations
set RESCARD   = ""
set newSG     = ""
set futureSG  = ""
set site_cell = ""
set site_sg   = ""
set mapmtz    = ""
set ofmt      = "dsn6"

# delete old garbage files
rm -f \${tempfile}* \${coordfile} >& /dev/null



















# begin program with input from command line (hopefully, not too long)
set input =  ( \$argv )

Gather:
###############################################################################

  ####     ##     #####  #    #  ######  #####
 #    #   #  #      #    #    #  #       #    #
 #       #    #     #    ######  #####   #    #
 #  ###  ######     #    #    #  #       #####
 #    #  #    #     #    #    #  #       #   #
  ####   #    #     #    #    #  ######  #    #

###############################################################################
#
#   Interpret the command line
#
###############################################################################

# reset user-input variables
set SOLVENT = ""

# un-pack complex awk procedures
goto Unwrap_Awk_Scripts
# \${tempfile}sitereader.awk
# \${tempfile}mtzstuff.awk
Return_Unwrap_Awk_Scripts:

# make sure input is a multiword variable
set input = ( \$input )
if("\$input" == "") then
    # replace empty input with command line?
    set input = ( \$argv )
endif

# Pass 1: find site files, program settings (and third-party binaries)
set i = 0
while ( \$i < \$#input )
    @ i = ( \$i + 1 )
    set arg = "\$input[\$i]"
    
    # negative logic
    if(! -e "\$arg") then
	# \$arg is not a file
	# simplefy interpretation of settings
	set arg = \`echo "\$arg" | nawk '{print toupper(\$0)}'\`
	if(("\$arg" == "NO")||("\$arg" == "NOT")) then
	    # this will remain set until we know what it means
	    set NO
	    continue
	endif
	
	# program options (not initializable anywhere else)
	if("\$arg" == "NEW") set NEW
	if("\$arg" == "-NEW") set NEW
	if("\$arg" == "NEGATIVE") then
	    if(\$?NO) then
		# must just not want to flip occupancies
		unset FLIP_OCC
		unset NO
		continue
	    endif
	    # user-option to override default of positive real occs
	    set NEGATIVE_OCC
	endif
	
	# regognize general (unitless) numbers
	if(("\$arg" =~ [0-9]*)&&("\$arg" =~ *[0-9])&&("\$arg" !~ *[a-zA-Z]*)) then
	    if("\$arg" !~ *.*) then
		# some non-negative integer, what does it mean? 
		set integer = \$arg
		continue
	    endif
	endif
	
	# interpret "NO"s
	if(\$?NO) then
	    # preemtive, will be re-set if nothing is recognized
	    unset NO
	    if(("\$arg" == "DM")||("\$arg" =~ FLAT*)) then
		set NO_DM
		continue
	    endif
	    if("\$arg" == "MAPMAN") then
		set NO_MAPMAN
		continue
	    endif
	    if("\$arg" == "SHELX") then
		set NO_SHELX
		continue
	    endif
	    if(("\$arg" == "ADD")||("\$arg" == "MORE")) then
		unset MORE_SITES
		continue
	    endif
	    if(("\$arg" == "FILTER")||("\$arg" == "REJECT")) then
		unset FILTER_ATOMS
		continue
	    endif
	    if(("\$arg" == "FLIP")||("\$arg" =~ ALTERNAT*)||("\$arg" =~ EXPLOR*)) then
		# there's a little more to this
		if(\$i < \$#input) then
		    @ i = ( \$i + 1 )
		    set narg = \`echo "\$input[\$i]" | nawk '{print toupper(\$1)}'\`
		    if(("\$narg" =~ OCC*)||("\$narg" == SIGN)) then
			unset FLIP_OCC
			continue
		    endif
		    if("\$narg" == "HAND") then
			unset FLIP_HAND
			continue
		    endif
		    if(("\$narg" == "SG")||("\$narg" == "SPACE")) then
			unset FLIP_SG
			continue
		    endif
		    @ i = ( \$i - 1 )
		endif
		# no qualifier, so just turn 'em all off
		unset FLIP_OCC
		unset FLIP_HAND
		unset FLIP_SG
		continue
	    endif
	    if("\$arg" == "HURRY") then
		unset HURRY_UP
		continue
	    endif
	    # look to next word for meaningful "no x"
	    set NO
	endif
	
	# optinally turn on some options
	if("\$arg" == "HURRY") set HURRY_UP
	if(("\$arg" == "ADD")||("\$arg" == "MORE")) then
	    set MORE_SITES
	    continue
	endif
	if(("\$arg" == "FILTER")||("\$arg" == "REJECT")) then
	    set FILTER_ATOMS
	    continue
	endif
	if(("\$arg" == "FLIP")||("\$arg" =~ ALTERNAT*)||("\$arg" =~ EXPLOR*)) then
	    # there's a little more to this...
	    if(\$i < \$#input) then
		@ i = ( \$i + 1 )
		set narg = \`echo "\$input[\$i]" | nawk '{print toupper(\$1)}'\`
		if(("\$narg" =~ OCC*)||("\$narg" == SIGN)) then
		    set FLIP_OCC
		    continue
		endif
		if("\$narg" == "HAND") then
		    set FLIP_HAND
		    continue
		endif
		if(("\$narg" == "SG")||("\$narg" == "SPACE")) then
		    set FLIP_SG
		    continue
		endif
		@ i = ( \$i - 1 )
	    endif
	    # no qualifier, so just turn 'em all on
	    set FLIP_OCC
	    set FLIP_HAND
	    set FLIP_SG
	    continue
	endif
	
	
	# recognize post-number "unit" words
	if(\$?integer) then
	    # units must come right after
	    if(("\$arg" =~ PARAM*)&&("\$integer" =~ [0-6])) then
		set user_params = \$integer
		continue
	    endif
	    if(("\$arg" =~ SITE*)&&("\$integer" =~ [1-9]*)) then
		set user_sites = \$integer
		# user must be happy with given number of sites? 
		unset MORE_SITES
	    endif
	    unset integer
	endif
	
	# recognize numbers with units attached
	if("\$arg" =~ [1-9]*%) then
	    # this must be a solvent content
	    set temp = \`echo \$arg | nawk '\$1+0>0 && \$1+0 < 100{printf "%02d", \$1+0}'\`
	    if("\$temp" != "") then
		set SOLVENT = "\$SOLVENT \$temp"
	    else
		echo "bad solvent content: \$arg ?"
	    endif
	endif
	
	# resolution is read below (along with scripts)
	
	# might as well read space group now
	if("\$arg" =~ [PCIFR][1-6]*) then
	    if(\$?NO) then
		unset NO
		# must just not want to flip SG
		unset FLIP_SG
		continue
	    endif
	    
	    set temp = ""
	    if(\$?CLIBD) then
		set temp = \`nawk -v SG=\$arg '\$4 == SG && \$1 < 500 {print \$4}' \$CLIBD/symop.lib | head -1\`
	    endif
	    if("\$temp" != "") then
		# valid space group, prepare to reindex to it
		set newSG = "\$temp"
		set USER_SG = "\$temp"
		unset FLIP_SG
		continue
	    endif
	    # check for "pseudo-spacegroup" language
	    set temp = \`echo "\$arg" | nawk '/[PC]2212|[PC]2122|P21221|P22121/'\`
	    if("\$temp" != "") then
		# these are okay too, \${scriptDIR}reindex.com will understand
		set newSG = "\$temp"
		set USER_SG = "\$temp"
		unset FLIP_SG
		
		continue
	    endif
	endif
	
	# unrecognized non-file word
	continue
    endif
    
    # arg is a file that exists
	
    # make sure it's an ordinary file
    set temp = \`ls -lnLd \$arg | nawk '/^-/{print \$NF}'\`
    if(! -e "\$temp") then
	# what the...
	echo "What is \$arg for? "
	continue
    endif
    
    # \$arg is an ordinary, readable file
    switch("\$arg")
	case *.sh:
	    set inscript = "\$arg"
	breaksw
	case *.com:
	    set inscript = "\$arg"
	breaksw
	case *.log:
	    set inlogfile = "\$arg"
	breaksw
	case *.log.old*
	    set inlogfile = "\$arg"
	breaksw
	case *.res:
	    set shelxfile = "\$arg"
	breaksw
	case *.ins:
	    set shelxfile = "\$arg"
	breaksw
	case *.lst:
	    set shelxfile = "\$arg"
	breaksw
	case *.pdb:
	    set pdbfile = "\$arg"
	breaksw
	case *.brk:
	    set pdbfile = "\$arg"
	breaksw
	case *solve.status:
	    set solvefile = "\$arg"
	breaksw
	case *mlphare*:
	    if("\$arg" !~ *.log*) then
		grep "mlphare " \$arg >& /dev/null
		if(! \$status) then
		    set inscript = "\$arg"
		    breaksw
		endif
	    endif
	
	default:
	    # just a random "site" file?
	    # look for three, consecutive high-precision numbers between -1.1 and 1.1
	    cat \$arg |\\
	    nawk -f \${tempfile}sitereader.awk |&\\
	    nawk '/ATOM/' >! \${tempfile}.sites
	    set temp = \`cat \${tempfile}.sites | wc -l\`
	    rm -f \${tempfile}.sites
	    if(\$temp > 0) then
		# re-find the sites later
		set sitefile = \$arg
	    endif
	breaksw
    endsw

    # check for program binaries
    test -x "\$arg"
    if(\$status) then
	# maybe a data file, handle this later...
	continue
    endif

    set file = "\$arg"

    # is it dm?
    if("\$file" =~ *dm*) then
	echo "testing \$arg"
	    set temp = \`setenv DISPLAY; echo "" | \$file |& nawk '/K. Cowtan/{print ver} /dm [1-4].[0-9]/{for(i=1;i 0) then
		set inlogfile = "\$logfile"
	    else
		# maybe an aborted run?
		if(-e "\${logfile}.old") then
		    # check it
		    set temp = \`nawk '\$1 ~ /^ATOM/' \${logfile}.old | wc -l\`
		    if(\$temp > 0) then
			set inlogfile = "\${logfile}.old"
		    endif
		endif
	    endif
	endif
	if(-e "\$inlogfile") then
	    echo "found \$inlogfile"
	endif
    endif
    if(-e "\$inscript") then
	echo "found \$inscript"
    endif
else
    # remember that user supplied sites
    set USER_SITES
endif

# decide on list of solvent contents to try
set trials = "\$default_trials"

# user preference overrides default trials
if("\$SOLVENT" != "") then
    set trials = "\$SOLVENT"
endif
set default_trials = ( \$trials )
set trials = ( \$trials )

# for impatient people
if(\$?HURRY_UP) then
    # only do a few cycles each round
    set mlphareCYCLES = 5
    # declare convergence when 1st decimal place is the same
    set converge_crit = 100
    # only look for reasonably high difference-fourier peaks 
    set newSIG = 4
endif
if(\$?MAD) then
    # don't let parameters diverge too much between runs
    set mlphareCYCLES = 5    
endif


FindData:
################################################################################

 ######     #    #    #  #####           #    #   #####  ######
 #          #    ##   #  #    #          ##  ##     #        #
 #####      #    # #  #  #    #          # ## #     #       #
 #          #    #  # #  #    #          #    #     #      #
 #          #    #   ##  #    #          #    #     #     #
 #          #    #    #  #####           #    #     #    ######

################################################################################
#   decide on/find an input mtz file
################################################################################

# first thing first: find the data

# get mtz filename from command line (highest priority)
foreach arg ( \$input )
    if("\$arg" =~ *.mtz) then
	if(-e "\$arg") then
	    set mtzfile = "\$arg"
	    set USERmtz
	    unset DEFAULT_PARAMS
	else
	    echo "WARNING: \$arg does not exist! "
	endif
    endif
end

# retrieve MTZ filename from logfile
if((! \$?USERmtz)&&(-e "\$inlogfile")) then
    # get MTZ filename from the log
    set temp = \`nawk '/Filename:/{print \$NF}' \$inlogfile | head -1\`
    
    if("\$temp" != "") then
	if(-e "\$temp") then
	    set mtzfile = "\$temp"
	    unset DEFAULT_PARAMS
	else
	    echo "WARNING: \$temp from \$inlogfile does not exist! "
	endif
    endif
endif

	

# retrieve MTZ filename form old script (higher priority than logfile)
if((! \$?USERmtz)&&(-e "\$inscript")) then

    # get first MTZ filename in this script
    cat \$inscript |&\\
    nawk 'BEGIN{RS=" "} {print}' |&\\
    nawk '/mtz\$/ && ! /\\\$/' |&\\
    cat >! \${tempfile}
    set temp = \`cat \${tempfile}\`
    rm -f \${tempfile} >& /dev/null
    
    if("\$temp" != "") then
	set temp = \$temp[1];
	if(-e "\$temp") then
	    set mtzfile = "\$temp"
	    unset DEFAULT_PARAMS
	else
	    echo "WARNING: \$temp from \$inscript does not exist! "
	endif
    endif
endif










read_mtz:
################################################################################

 #####   ######    ##    #####           #    #   #####  ######
 #    #  #        #  #   #    #          ##  ##     #        #
 #    #  #####   #    #  #    #          # ## #     #       #
 #####   #       ######  #    #          #    #     #      #
 #   #   #       #    #  #    #          #    #     #     #
 #    #  ######  #    #  #####           #    #     #    ######

################################################################################
#   Read in label assignments from mtz file
################################################################################

set firstmtz = "\$mtzfile"

# read info from MTZ file
echo "go" | mtzdump HKLIN \$mtzfile |\\
nawk -f \${tempfile}mtzstuff.awk >&! \${tempfile}mtzdmp
# format: [FQDP..]: Fname SIGFname /

# don't need this anymore
#rm -f \${tempfile}mtzstuff.awk >& /dev/null


# get the paired-up Fs and SIGFs
nawk '/^F: / && NF>2' \${tempfile}mtzdmp |\\
cat >! \${tempfile}Fpairs
# format: [FQDP..]: Fname SIGFname /

# count them
set Fs = \`cat \${tempfile}Fpairs | wc -l\`
if("\$Fs" == 0) then
    # back-up plan
    echo "go" | mtzdump HKLIN \$mtzfile |\\
    nawk '/OVERALL FILE STATISTICS/,/LIST OF REFLECTIONS/' |\\
    nawk 'NF>8' |\\
    nawk '\$(NF-1)=="F"{print "F:", \$NF}\\
          \$(NF-1)=="Q"{print "Q:", \$NF}' |\\
    cat >! \${tempfile}
    
    egrep "^F" \${tempfile} >& /dev/null
    if(! \$status) echo "WARNING: main mtz reader failed! "
    cat \${tempfile} |\\
    nawk '/^F:/{F=\$2} /^Q:/{if(F)print"F:", F, \$NF, 1; F=""}' |\\
    cat >! \${tempfile}Fpairs
    rm -f \${tempfile} >& /dev/null
endif
if("\$Fs" == 0) then
    echo "no Fs in \$mtzfile ... sorry "
    
    if(! \$?debug) rm -f \${tempfile}* >& /dev/null
    exit 9
endif
if("\$Fs" < 2) then
    echo -n "only \$Fs F in \$mtzfile "

    # see if there's anomalous
    set Ds = \`nawk '/^D: / && NF>2' \${tempfile}mtzdmp | wc -l\`
    if("\$Ds" > 0) then
	# no-brainer picking native
	set native = \`nawk '{print \$2, \$3}' \${tempfile}Fpairs\`
    else
	echo "you need DIFFERENCE data to get phases! "
	rm -f \${tempfile}* >& /dev/null
	exit 8
    endif
endif

################################################################################
# initialize misc variables from MTZ
set CELL    = \`nawk '/^CELL/{print \$2+0, \$3+0, \$4+0, \$5+0, \$6+0, \$7+0}' \${tempfile}mtzdmp\`
set SGnum   = \`nawk '/^SYMM/{print \$NF}' \${tempfile}mtzdmp\`
set mtzSG   = \`nawk -v SGnum=\$SGnum '\$1==SGnum{print \$4}' \${CLIBD}/symop.lib\`
# "current" SG is the one in the mtz file
set SG      = "\$mtzSG"
if("\$newSG" == "") then
    # there was no user-specified space group
    set newSG    = "\$mtzSG"
endif

# use resolution from mtz file
set hiRES   = \`nawk '/^RESO/{print \$NF+0}' \${tempfile}mtzdmp\`
set RESCARD = \`nawk '/^RESO/' \${tempfile}mtzdmp\`

# base B-factor limits on resolution range
set wilsonB = \`echo "\$hiRES" | nawk '{print 79*(\$1/3)^2}'\`
#set Bcap    = \`echo "\$RESCARD" | nawk '{print 79*(\$2/4)^2}'\`



################################################################################################################
#   initialize resolution limit
################################################################################################################
if(-e "\$inlogfile") then
    # get resolution from the last output log
    set temp = \`nawk '\$3~/^RESO/ && \$NF+0 >0.1 && \$NF+0 < 6 {print \$NF;exit}' \$inlogfile\`
    if("\$temp" != "") then
	set hiRES = "\$temp"
	set RESCARD = \`nawk '\$3~/^RESO/ && \$NF+0 >0.1 && \$NF+0 < 6 {print \$3, \$4, \$5}' \$inlogfile\`
    endif
endif	

if(-e "\$inscript") then
    # get resolution from an input script
    set temp = \`nawk '/^RESO/ && \$NF+0 >0.1 && \$NF+0 < 6 {print \$NF}' \$inscript\`
    if("\$temp" != "") then
	set hiRES = "\$temp"
	set RESCARD = \`nawk '/^RESO/ && \$NF+0 >0.1 && \$NF+0 < 6 {print}' \$inscript\`
    endif
endif	

# pass through command line, for right resolution limit
foreach arg ( \$input )
    if(! -e "\$arg") then
	if("\$arg" =~ [1-6]*A) then
	    set hiRES = \`echo \$arg | nawk '{print \$1+0}'\`
	endif
    endif
end
# update the RESolution keycard
set RESCARD = \`echo "\$RESCARD \$hiRES" | nawk '{print "RESOLUTION", \$2, \$NF}'\`






PickRef:
################################################################################

 #####      #     ####   #    #          #####   ######  ######
 #    #     #    #    #  #   #           #    #  #       #
 #    #     #    #       ####            #    #  #####   #####
 #####      #    #       #  #            #####   #       #
 #          #    #    #  #   #           #   #   #       #
 #          #     ####   #    #          #    #  ######  #

################################################################################
#   look to all sources for indications of "best" native set
################################################################################

# see if user specified native (now that we know the contents of the mtz)

echo -n "" >! \${tempfile}filelabels

# get reference from input logfile?
if(("\$native" == "")&&(-e "\$inlogfile")) then
    # retrieve reference wavelength used in \$inlogfile
    cat \$inlogfile |\\
    nawk '/LABIN/{for(i=1;i<=NF;++i)if(\$i == "LABIN") print \$(i+1), \$(i+2)}' |\\
    head -1 |\\
    nawk '{print \$1; print \$2}' |\\
    nawk 'BEGIN{FS="="} {print \$2}' |\\
    cat >> \${tempfile}filelabels
endif
# get reference from input script?
if(("\$native" == "")&&(-e "\$inscript")) then
    # retrieve reference wavelength used here
    cat \$inscript |\\
    nawk '/LABIN/{for(i=1;i<=NF;++i)if(\$i == "LABIN") print \$(i+1), \$(i+2)}' |\\
    head -1 |\\
    nawk '{print \$1; print \$2}' |\\
    nawk 'BEGIN{FS="="} {print \$2}' |\\
    cat >> \${tempfile}filelabels
endif
set filelabels = \`cat \${tempfile}filelabels\`
rm -f \${tempfile}filelabels >& /dev/null

# check command line (and file contents) for labels
foreach arg ( \$filelabels \$input )
    set temp = \`nawk -v arg=\$arg '/^COL/ && \$3=="F" && \$2==arg' \${tempfile}mtzdmp\`
    if("\$temp" != "") then
	set USER_NATIVE
#        echo "found \$arg in \$mtzfile"
	
	# assign F to our favorite SIGF
        set native = \`nawk -v arg=\$arg '\$2==arg{print \$2, \$3}' \${tempfile}Fpairs\`
	if("\$native" == "") then
	    # resort to no sigma
	    set native = "\$arg"
	endif
    endif
    set temp = \`nawk -v arg=\$arg '/^COL/ && \$3=="Q" && \$2==arg' \${tempfile}mtzdmp\`
    if("\$temp" != "") then
#        echo "found \$arg in \$mtzfile"
	
	# assign Sigma to our favorite SIGF (if we can)
	set SIGnative = \`nawk -v arg=\$arg '\$3==arg{print \$2, \$3}' \${tempfile}Fpairs\`
	if("\$SIGnative" == "") set SIGnative = "\$arg"
    endif
end

# inform user that we understood the native assignment
if(\$?USER_NATIVE) then
    echo "reference data set is \$native"
    unset USER_NATIVE
endif


# if user doesn't seem to care, pick F with best Diso from all other Fs
if("\$native" == "") then
    set i = 0
    echo -n "Evaluating \$Fs Fs in \$mtzfile "

    echo -n "" >! \${tempfile}diso_dano
    while (\$i < \$Fs)
	@ i = ( \$i + 1 )
	
	echo -n "."
	
	# retrieve name of this "reference" F and SIGF
	set F    = \`nawk -v line=\$i 'NR==line {print \$2}' \${tempfile}Fpairs\`
	set SIGF = \`nawk -v line=\$i 'NR==line {print \$3}' \${tempfile}Fpairs\`
	
	set dataset = 1
	set datasets = \`nawk '/^F: /' \${tempfile}mtzdmp | wc -l\`
	while ( \$dataset <= \$datasets )
	    # make some ordinary scaleit cards
	    echo "refine anisotropic" >! \${tempfile}scaleit.in
	    echo "\$RESCARD" >> \${tempfile}scaleit.in

	    # make a LABIN card for scaleit
	    echo -n "LABIN FP=\$F SIGFP=\$SIGF " >> \${tempfile}scaleit.in
	    
	    # scaleit might only do 6 datasets at a time
	    cat \${tempfile}mtzdmp |\\
	    nawk -v first=\$dataset '\\
	       /^F: /{++f; F[f]=\$2; QF[f]=\$3; } \\
	       /^D: /{++d; D[d]=\$2; QD[d]=\$3; } \\
		  END{for(i=1;i<=6;++i){set=i+first-1;\\
	      if(F[set] != "")printf "-\\nFPH%d=%s SIGFPH%d=%s ", i, F[set], i, QF[set];\\
	      if(D[set] != "")printf "DPH%d=%s SIGDPH%d=%s ",    i, D[set], i, QD[set]};\\
	      print ""; print "END"}' |\\
	    cat >> \${tempfile}scaleit.in
	    
	    # run scaleit
	    cat \${tempfile}scaleit.in |\\
	    scaleit HKLIN \$mtzfile HKLOUT /dev/null |\\
	    nawk '/TABLE:Analysis /{for(i=1;i")+3}\\
	    /THE TOTALS/{print FP, FPH, substr(\$0,iso)+0, substr(\$0,ano)+0}' |\\
	    cat >> \${tempfile}diso_dano
	    
	    # advance to next batch of 6 datasets
	    @ dataset = ( \$dataset + 6 )
	end
    end
    #  \${tempfile}diso_dano has format:
    # Fnat Fderiv diso dano

    # compute a "native score" for each F (sum of all diso+dano) (maybe use product? )
    cat \${tempfile}diso_dano |\\
    nawk '{if(\$3+0==0) score[\$1]+=\$4; score[\$1] += \$3} \\
        END{for(ref in score) print ref, score[ref]}' |\\
    sort -n -k2 >! \${tempfile}Fscores
    
    # now pick the best native F (and SIGF)
    set native = \`tail -1 \${tempfile}Fscores | nawk '{print \$1}'\`
    set native = \`nawk -v F=\$native '\$2==F{print \$2, \$3}' \${tempfile}Fpairs\`
    
    if("\$native" != "") then
	echo "picked \$native[1] as the best reference."
    else
	echo "WARNING: could not read scaleit logs "
    endif
 
    # clean up
    rm -f \${tempfile}Fscores
    rm -f \${tempfile}scaleit.in
    rm -f \${tempfile}diso_dano
endif



# failing that, just pick F with best F/sigma
if("\$native" == "") then
    set native = \`sort -n -k4 \${tempfile}Fpairs | tail -1 | nawk '{print \$2, \$3}'\`
endif

# last safety catch, if all else fails
if("\$native" == "") then
    set native = \`nawk '/^COL/ && \$3=="F"{print \$2}' \${tempfile}mtzdmp | head -1\`
endif

# finally, tack user-specified SIG to end of native
if(\$?SIGnative) then
    set native = \`echo "\$native \$SIGnative" | nawk '{print \$1, \$NF}'\`
endif






# make sure we have SOME kind of sigma for native
set native = ( \$native )
if(\$#native < 2) then
    # pick first sigma in file
    set temp = \`nawk '/^COL/ && \$3=="Q"{print \$2}' \${tempfile}mtzdmp | head -1\`
    set native = \`echo "\$native \$temp" | nawk '{print \$1, \$NF}'\`
endif

# fail if mtz is just a bunch of crap
if(\$#native < 2) then
    echo "ERROR: no sigmas in \$mtzfile"
    echo ""
    echo "Maximum Likelihood cannot be done without sigmas! "
    echo ""
    
    if(! \$?debug) rm -f \${tempfile}* >& /dev/null
    
    set BAD
    goto done
endif

# make F/SIG pair into two variables
set SIGnative = \`echo \$native | nawk '{print \$NF}'\`
set native = \`echo \$native | nawk '{print \$1}'\`


# don't need this anymore
rm -f \${tempfile} >& /dev/null
rm -f \${tempfile}Fpairs >& /dev/null
#rm -f \${tempfile}mtzdmp >& /dev/null















################################################################################
# decide on atoms to fix or not to fix in this space/point group
################################################################################
set PG = \`nawk -v SG=\$SG '\$4==SG{print substr(\$5,3)}' \$CLIBD/symop.lib | head -1\`
set temp = \`echo \$PG | nawk '{print length(\$1)}'\`
if("\$temp" == 1) set fix = "Z"
if("\$PG"   == 1) set fix = "X|Y|Z"
if("\$PG"   == 2) set fix = "Y"


# do we need to change space groups? (that is, do we have a chiral screw axis)
set otherSG = ""
if(("\$newSG" =~ P[346]*)&&(0)) then
    # construct inverted-hand spacegroup symbol
    set otherSG = \`echo \$newSG | nawk '{print substr(\$1,1,2) substr(\$1,2,1)-substr(\$1,3,1) substr(\$1,4) }'\`
    # make sure it's a real spacegroup
    set otherSG = \`nawk -v SG=\$otherSG '\$4 == SG && \$1 < 500 {print \$4}' \$CLIBD/symop.lib | head -1\`
    if(("\$otherSG" != "")&&("\$otherSG" != "\$newSG")) then
	# we've got another SG to try!
	set otherSG = "\$otherSG"
	# remember the initial SG too
	set firstSG = "\$newSG"
    else
	# no reindexing needed
	set otherSG = ""
    endif
endif

# no need to FLIP_SG if there's nothing to flip to
#if("\$otherSG" == "") unset FLIP_SG
if(! \$?FLIP_SG) set otherSG = ""









Make_LABIN:
################################################################################

 #         ##    #####      #    #    #
 #        #  #   #    #     #    ##   #
 #       #    #  #####      #    # #  #
 #       ######  #    #     #    #  # #
 #       #    #  #    #     #    #   ##
 ######  #    #  #####      #    #    #

################################################################################
# build, borrow or modify the LABIN card
################################################################################

# make the "maximum" labin card from the MTZ
echo -n "LABIN FP=\$native SIGFP=\$SIGnative " >! \${tempfile}labin.mtz
cat \${tempfile}mtzdmp |\\
nawk '/^F: /{++f; F[f]=\$2; QF[f]=\$3; } \\
      /^D: /{++d; D[d]=\$2; QD[d]=\$3; } \\
      END{for(i=1;i<=f;++i){\\
  if(F[i] != "")printf "-\\nFPH%d=%s SIGFPH%d=%s ", i, F[i], i, QF[i];\\
  if(D[i] != "")printf "DPH%d=%s SIGDPH%d=%s ",    i, D[i], i, QD[i]};\\
  print ""}' |\\
cat >> \${tempfile}labin.mtz


if(-e "\$inscript") then
    # now get LABIN card from the script (verbatim)
    cat \$inscript |\\
    nawk '\$1 ~ /^LABIN/{print; while(\$NF == "-"){getline; print}}' |\\
    nawk 'BEGIN{RS=" "} NF != 0 && \$1 != "-"' |\\
    nawk 'NF!=0' |\\
    nawk '/^FPH/{printf " -\\n"} {printf "%s ", \$0} END{print ""}' |\\
    cat >! \${tempfile}labin.input
else
    if(-e "\$inlogfile") then
	# reconstruct LABIN card from the log
	cat \$inlogfile |\\
	nawk '/LABIN/{printf "%s", substr(\$0, 15); while(getline){if(\$1 != "Data"){printf "%s", substr(\$0, 2)}else{break}}}' |\\
	nawk 'BEGIN{RS=" "; ORS=" "} NF != 0' |\\
	nawk 'BEGIN{RS=" "} /^FPH/{printf "-\\n"} {printf "%s ", \$0} END{print ""}' |\\
	cat >! \${tempfile}labin.input
    endif
endif    

if(-e \${tempfile}labin.input) then
    # don't bother using if there aren't any real labels
    set temp = \`cat \${tempfile}labin.input | nawk 'BEGIN{RS=" "} /[=]/{print \$0}' | wc -l\`
    if(\$temp < 2) rm -f \${tempfile}labin.input
endif

if(-e \${tempfile}labin.input) then
    # reconcile this with possible cards (from MTZ)
    echo "=----=" >! \${tempfile}
    cat \${tempfile}labin.mtz \${tempfile} \${tempfile}labin.input |\\
    nawk 'BEGIN{RS="=";ORS="="} {++count[\$1]} \$0=="----"{p=1} \\
     p==1{if(count[\$1]>=2) print \$0}' |\\
    cat >! \${tempfile}labin.okay
    
    # now \${tempfile}labin.okay contains the intersection of labels from
    # the mtz file and the previous script/log's labin card
else
    # use the one we generated from the mtz file
    cp \${tempfile}labin.mtz \${tempfile}labin.okay
endif

# reformat, so it looks pretty
cat \${tempfile}labin.okay |\\
nawk '/^LABI/{printf "LABIN %-10s %s -\\n", \$2, \$3} \\
 \$1~/^FPH/{printf "      %-10s %-15s %-15s %s %s\\n", \$1, \$2, \$3, \$4, \$5}' |\\
cat >! \${tempfile}.LABELS

# don't need these anymore
rm -f \${tempfile} >& /dev/null
rm -f \${tempfile}labin.okay >& /dev/null
rm -f \${tempfile}labin.mtz >& /dev/null
rm -f \${tempfile}labin.input >& /dev/null
rm -f \${tempfile}Fpairs >& /dev/null
#rm -f \${tempfile}mtzdmp >& /dev/null


# \${tempfile}.LABELS now contains the desired data labels
# check for SAD?
set Fs = \`nawk 'BEGIN{RS=" "} {print}' \${tempfile}.LABELS | nawk '/^FPH/' | wc -l\`
if(\$Fs < 2) then
    set Ds = \`nawk 'BEGIN{RS=" "} {print}' \${tempfile}.LABELS | nawk '/^DPH/' | wc -l\`
    if(\$Ds == 1) then
	echo "You must be SAD :)"
	set SAD
	unset FLIP_OCC
    endif
endif

# skip over mtz check on repeat passes by here
if(\$?DEFAULT_PARAMS) goto GetSites


###############################################################################
# analyze mtzfile
###############################################################################
# run SCALEIT with the same LABIN we will be using for MLPHARE
echo "checking \$mtzfile"
cp -f \$mtzfile \${tempfile}scaleme.mtz >& /dev/null

# extract the datasets (again)
nawk '\$1 ~ /^FPH/' \${tempfile}.LABELS |\\
nawk 'BEGIN{FS="="} {print \$2, \$3, \$4, \$5}' |\\
nawk '{print \$1, \$3, \$5, \$7}' |\\
cat >! \${tempfile}datasets

echo -n "" >! \${tempfile}scaleit.log
set i = 1
set datasets = \`cat \${tempfile}datasets | wc -l\`
while (\$i <= \$datasets)
    head -1 \${tempfile}.LABELS >! \${tempfile}scaleit.in
    cat \${tempfile}datasets |\\
    nawk -v first=\$i '{++n} n>=first && n<(first+6){++i;\\
	printf "-\\nFPH%d=%s SIGFPH%d=%s ", i, \$1, i, \$2;\\
	if(\$3!="")\\
	printf "DPH%d=%s SIGDPH%d=%s ", i, \$3, i, \$4;}\\
	END{print ""}' |\\
    cat >> \${tempfile}scaleit.in
    echo "refine anisotropic" >> \${tempfile}scaleit.in
    echo "\$RESCARD"           >> \${tempfile}scaleit.in
    echo "END"		      >> \${tempfile}scaleit.in
    cat \${tempfile}scaleit.in |\\
    scaleit HKLIN \${tempfile}scaleme.mtz HKLOUT \${tempfile}scaled.mtz |\\
    cat >> \${tempfile}scaleit.log
    if(\$status) then
	# why would this happen?
	echo "WARNING: \$mtzfile failed to scale! "
    endif
    # get ready to continue scaling
    mv -f \${tempfile}scaled.mtz \${tempfile}scaleme.mtz >& /dev/null
    @ i = ( \$i + 6 )
end
mv -f \${tempfile}scaleme.mtz \${tempfile}scaled.mtz >& /dev/null
rm -f \${tempfile}scaleit.in >& /dev/null
rm -f \${tempfile}datasets >& /dev/null







#####################################
# see if scales varied wildly, if so, use the scaled version
cat \${tempfile}scaleit.log |\\
nawk '/APPLICATION OF SCALES/,/--------------------------/' |\\
nawk '\$1 == "Derivative"{++n; scale[n]=\$3+0; avg+=\$3}\\
END{if(n==0) exit; avg/=n; for(i=1;i<=n;++i){\\
      rmsd+=(scale[i]-avg)^2};\\
    rmsd = sqrt(rmsd/n); print rmsd}' |\\
cat >! \${tempfile}scales

set temp = \`nawk '{printf "%d", \$1*100}' \${tempfile}scales\`
if(\$temp > 5) then
    # make up a new name
    set newmtzfile = \`echo "\$firstmtz" | nawk 'BEGIN{FS="/"} {print \$NF}' | nawk 'BEGIN{FS="."} {for(i=1;i& /dev/null
endif
rm -f \${tempfile}scales >& /dev/null


#####################################
# define default EXCLUDE flags for each derivative
cat \${tempfile}scaleit.log |\\
nawk '/Derivative title:/{F=\$6} \\
      /Anomalous Differences/{KEY="DANO"} /Isomorphous Differences/{KEY="DISO"} \\
      /acceptable differences are less than/{print F, KEY, \$NF}' |\\
cat >! \${tempfile}EXCLUDE

# quick-reference file for LABIN
cat \${tempfile}.LABELS |\\
nawk 'BEGIN{RS=" "} /[=]/{print \$0}' |\\
nawk 'BEGIN{FS="="} {print substr(\$1,1,1), substr(\$1,length(\$1))+0, \$2}' |\\
sort -n -k2,3 >! \${tempfile}derivs

# re-name labels to derivative numbers
cat \${tempfile}derivs \${tempfile}EXCLUDE |\\
nawk '\$1=="F"{num[\$3]=\$2} \$2~/O\$/{print num[\$1], \$2, \$3}' |\\
cat >! \${tempfile}
mv \${tempfile} \${tempfile}EXCLUDE
rm -f \${tempfile}derivs

# just in case files get lost
set max_dano = \`nawk '\$2=="DANO"{print 1.5*\$3}' \${tempfile}EXCLUDE | sort -n | tail -1\`
set max_diso = \`nawk '\$2=="DISO"{print 1.5*\$3}' \${tempfile}EXCLUDE | sort -n | tail -1\`

# since mlphare looses the EXCLUDE cards in each iteration,
# we will have to continuously re-generate them





#####################################
# now load these "default occupancies" from the scaleit log into a variable
# (this will eliminate the need to keep this log around forever)
cat \${tempfile}scaleit.log |\\
nawk -v wilsonB=\$wilsonB '/THE TOTALS/{++n; print n, \$10, \$14, wilsonB}' |\\
cat >! \${tempfile}occs
# format: deriv_num Diso Dano WilsonB

set temp = \`nawk 'NF==4' \${tempfile}occs | wc -l\`
if(\$temp == 0) then
    # perhaps scaling failed?
    cat \${tempfile}.LABELS |\\
    nawk -v wilsonB=\$wilsonB '\$1 ~ /^FPH/{++i; print i, 1, 1, wilsonB}' |\\
    cat >! \${tempfile}occs
endif

# load this file into a variable
set DEFAULT_PARAMS = \`nawk '{printf "%s n", \$0}' \${tempfile}occs\`



# don't need this anymore
rm -f \${tempfile}scaleit.log >& /dev/null
rm -f \${tempfile}occs >& /dev/null






GetSites:
########################################################################################################

  ####   ######   #####           ####      #     #####  ######   ####
 #    #  #          #            #          #       #    #       #
 #       #####      #             ####      #       #    #####    ####
 #  ###  #          #                 #     #       #    #            #
 #    #  #          #            #    #     #       #    #       #    #
  ####   ######     #             ####      #       #    ######   ####

########################################################################################################
# make decision about where to go get sites
########################################################################################################

# skip this if we already have sites
if(\$sites) goto GotSites

# these kinds of files take precedence over the logfile and old scripts

if(-e "\$pdbfile") then
    set sitefile = "\$pdbfile"
    goto read_pdb
endif
if(-e "\$solvefile") then
    set sitefile = "\$solvefile"
    goto read_solve
endif
if(-e "\$shelxfile") then
    set sitefile = "\$shelxfile"
    goto read_shelx
endif
if(-e "\$sitefile") then
    # random, text site file
    goto read_general
endif


if(-e "\$inscript") then
    set sitefile = "\$inscript"
    goto read_inscript
endif
if(-e "\$inlogfile") then
    set sitefile = "\$inlogfile"
    goto read_inlog
endif

# handle this later
#if(\$?FIRSTIME) echo "no sites? "
set FIND_SITES

# all the above routines return HERE (upon success, otherwise GetSites) 
GotSites:
set inscript = ""
set inlogfile = ""





################################################################################

 ######  #    #  #####     ##    #    #  #####
 #        #  #   #    #   #  #   ##   #  #    #
 #####     ##    #    #  #    #  # #  #  #    #
 #         ##    #####   ######  #  # #  #    #
 #        #  #   #       #    #  #   ##  #    #
 ######  #    #  #       #    #  #    #  #####

################################################################################
#
#   "expand" any sets of sites to cover all derivatives
#
#   Also, zero-out occupancies that are undefined   
#
################################################################################
grep ATOM \$coordfile >& /dev/null
if(! \$status) then
    # we have read in some sites
    
    # count the original number of sites
    if(\$sites == 0) set sites = \`grep ATOM \$coordfile | wc -l\`
    
    # get names of "derivative" data sets we will be refining agaist
    cat \${tempfile}.LABELS |\\
    nawk 'BEGIN{RS=" "} /[=]/{print \$0}' |\\
    nawk 'BEGIN{FS="="} {print substr(\$1,1,1), substr(\$1,length(\$1))+0, \$2}' |\\
    sort -n -k2,3 >! \${tempfile}derivs
    set FPHs = \`nawk '\$1=="F" && \$2!=0 {print \$NF}' \${tempfile}derivs\`
    
    # now make sure we actually have proper "DERIV" cards
    grep "DERIV" \$coordfile >& /dev/null
    if(\$status) then
	# assume this is just a single bunch of atoms
	# so make a copy for each wavelength
	
	echo "" >! \${tempfile}refine
	foreach F ( \$FPHs )
	
	    # bare minimum header here
	    echo "DERIV \${F}-\$native, and \$F anomalous"     >> \${tempfile}refine
	    echo "DCYCLE PHASE ALL REFCYC ALL KBOV ALL"     >> \${tempfile}refine
	    
	    cat \$coordfile                                  >> \${tempfile}refine
	    
	    echo ""                                         >> \${tempfile}refine
	end
	mv \${tempfile}refine \$coordfile
    endif
    
    # now reconcile # of atom groups vs # of data sets being refined
    set sets = \`grep "DERIV" \${coordfile} | wc -l\`
    if(\$sets > \$#FPHs) then
	# there are more DERIV cards that there are Fs! 
	
	# lop off last ones?
	cat \$coordfile |\\
	nawk -v FPHs=\$#FPHs '/DERIV/{++deriv;p=1} deriv>FPHs{p=0} \\
	    p==1{print}' |\\
	cat >! \${tempfile}
	mv \${tempfile} \$coordfile
    endif
    if(\$sets < \$#FPHs) then
	# there are more Fs than DERIV cards!
	
	# duplicate last one? 
	cat \$coordfile |\\
	nawk -v needed=\$#FPHs '/DERIV/{++derivs;lines=0} {++lines; line[lines]=\$0} \\
	    {print} END{deriv=derivs; while(deriv < needed){ \\
	     for(i=1;i<=lines;++i) print line[i]; ++deriv}}' |\\
	cat >! \${tempfile}
	mv \${tempfile} \$coordfile
    endif

    # see if one of these FPHs is the reference 
    set temp = \`nawk '/^F /' \${tempfile}derivs | nawk '\$3==ref{print \$2} \$2==0{ref=\$3}'\`
    if("\$temp" != "") then
	# make sure the real occupancy is zero for this one
	cat \$coordfile |\\
	nawk -v ref=\$temp '/DERIV/{++deriv;p=0} deriv==ref{p=1} \\
	    /ATOM/ && p==1 {\$6="0.000"}  {print}' |\\
	cat >! \${tempfile}
	mv \${tempfile} \$coordfile
    endif
    
    # set anomalous occupancy to 0 for derivatives with no anomalous diffs
    nawk '\$2!=0' \${tempfile}derivs |\\
    nawk '\$1=="F"{F[\$2]=\$3} \$1=="D"{D[\$2]=\$3} \\
	END{for(num in F)if(D[num]=="") printf "|" num; print ""}' |\\
    nawk '{print substr(\$0,2)}' >! \${tempfile}worry
    set noanom = \`cat \${tempfile}worry\`
    rm -f \${tempfile}worry >& /dev/null
    
    if("\$noanom" != "") then
	# some anomalous occupancies need to be zeroed
	cat \$coordfile |\\
	nawk -v noanom="\$noanom" '/DERIV/{++deriv;noano=0} deriv~noanom{noano=1} \\
	    /ATOM/ && noano {if(\$7+0 != 0) \$7="0.000"}  {print}' |\\
	cat >! \${tempfile}
	mv \${tempfile} \$coordfile
    endif
    
    
    # don't need these anymore
    rm -f \${tempfile}derivs >& /dev/null

    # reset out-of-bounds input B factors and occupancies (avoid rejecting them later)
    cat \$coordfile |\\
    nawk -v Bcap=\$Bcap -v wilsonB=\$wilsonB '\$1 ~/^ATOM/ && \\
        ( \$NF < wilsonB/4 || \$NF > Bcap ){\$NF="?.???"} \\
        ( \$6*\$6 < 0.0025 && \$6+0!=0){\$6="?.???"} \\
        ( \$7 < 0.05 && \$7+0!=0){\$7="?.???"} \\
        {print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile
endif


Fill-in:
################################################################################

 ######     #    #       #                  #    #    #
 #          #    #       #                  #    ##   #
 #####      #    #       #       #####      #    # #  #
 #          #    #       #                  #    #  # #
 #          #    #       #                  #    #   ##
 #          #    ######  ######             #    #    #

################################################################################
#
#   fill-in missing occupancy/Bfactor data
#
################################################################################
grep '?.???' \$coordfile >& /dev/null
if(! \$status) then
    # there are some undefined values in the atom list
    
    #set params = 2
    
    # retrieve average parameters from currently available sites
    cat \$coordfile |\\
    nawk '/DERIV/{++derivs} \\
        \$1~/^ATOM/ && \$6 !~ /[?]/{ occ[derivs]+=\$6; ++nocc[derivs];} \\
        \$1~/^ATOM/ && \$7 !~ /[?]/{aocc[derivs]+=\$7; ++naocc[derivs];} \\
        \$1~/^ATOM/ && \$NF!~ /[?]/{Bfac[derivs]+=\$NF;++nBfac[derivs];} \\
     END{for(i=1;i<=derivs;++i){\\
        if( nocc[i]){ occ[i]= occ[i]/ nocc[i]}else{ occ[i]="?.???"};\\
        if(naocc[i]){aocc[i]=aocc[i]/naocc[i]}else{aocc[i]="?.???"};\\
        if(nBfac[i]){Bfac[i]=Bfac[i]/nBfac[i]}else{Bfac[i]="?.???"};\\
	print i, occ[i], aocc[i], Bfac[i]}}' |\\
    cat >! \${tempfile}occs
    
    # substitute missing values in the coordfile
    cat \${tempfile}occs \$coordfile |\\
    nawk '/DERIV/{++deriv} \\
          /^[1-9]/{occ[\$1]=\$2; aocc[\$1]=\$3; Bfac[\$1]=\$4 } \\
	  \$1~/^ATOM/&&\$6~/[?]/{\$6= occ[deriv]} \\
	  \$1~/^ATOM/&&\$7~/[?]/{\$7=aocc[deriv]} \\
	  \$1~/^ATOM/&&\$NF~/[?]/{\$NF=Bfac[deriv]} \\
	   ! /^[0-9]/{print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile
    
    
    
    
    # use scaleit results to estimate remaining parameters
    echo "\$DEFAULT_PARAMS" |\\
    nawk 'BEGIN{RS="n"} {print}' |\\
    cat >! \${tempfile}occs
    # format: deriv_num Diso Dano WilsonB
    
    # honor request for negative default occupancies
    if(\$?NEGATIVE_OCC) then
echo "GOTHERE NEGATIVE_OCC"
	nawk '{\$2=-\$2; print}' \${tempfile}occs >! \${tempfile}
	mv \${tempfile} \${tempfile}occs >& /dev/null
        cat \$coordfile |\\
        nawk '/DERIV/{++deriv} \\
          \$1~/^ATOM/&&\$6!~/[?]/{\$6=-\$6} \\
          {print}' |\\
        cat >! \${tempfile}
        mv \${tempfile} \$coordfile
    endif
    
    # substitute missing values in the coordfile
    cat \${tempfile}occs \$coordfile |\\
    nawk '/DERIV/{++deriv} \\
          \$1~/^[1-9]/{occ[\$1]=\$2; aocc[\$1]=\$3; Bfac[\$1]=\$4 } \\
	  \$1~/^ATOM/&&\$6~/[?]/{\$6= occ[deriv]} \\
	  \$1~/^ATOM/&&\$7~/[?]/{\$7=aocc[deriv]} \\
	  \$1~/^ATOM/&&\$NF~/[?]/{\$NF=Bfac[deriv]} \\
	  \$1!~/^[0-9]/{print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile
    
    # check for anything that survived?
    set temp = \`nawk '\$1~/^ATOM/ && /[?]/' \$coordfile | wc -l\`
    if("\$temp") then
	echo "ERROR: unable to determine starting occupancies! "
	set BAD
	goto done
    endif
    
    # don't need this anymore
    rm -f \${tempfile}occs >& /dev/null
endif


# don't need these anymore
rm -f \${tempfile}mtzdmp       >& /dev/null
rm -f \${tempfile}scaleit.log  >& /dev/null
rm -f \${tempfile}mtzstuff.awk >& /dev/null
rm -f \${tempfile}sitereader.awk >& /dev/null




# check for atoms again
grep ATOM \$coordfile >& /dev/null
if(\$status) then
    # see if we can find a few sites ourselves
    if(\$?FIRSTIME) echo "no heavy atom sites were provided..."
    set FIND_SITES
else
    # we definitely don't need to do this
    unset FIND_SITES
endif







permute:
################################################################################

 #####   ######  #####   #    #  #    #   #####  ######
 #    #  #       #    #  ##  ##  #    #     #    #
 #    #  #####   #    #  # ## #  #    #     #    #####
 #####   #       #####   #    #  #    #     #    #
 #       #       #   #   #    #  #    #     #    #
 #       ######  #    #  #    #   ####      #    ######

################################################################################
#
# figure out whether or not to permute axes (based on cell edges)
#
################################################################################
# first, we need to know what the mtz unit cell WILL be
# (not, necessarily what it is)
set axes = ""
if("\$newSG" == P2212)  set axes = "b c a"
if("\$newSG" == P2122)  set axes = "c a b"
if("\$newSG" == P21221) set axes = "b c a"
if("\$newSG" == P22121) set axes = "c a b"
#if("\$newSG" == C2212)  set axes = "b c a"
#if("\$newSG" == C2122)  set axes = "c a b"
if("\$axes" != "") then
    # planning to change orthorhombic cell axis ordering...
    # predict new unit cell (after reindex.com in \$newSG)
    echo "\$CELL" | nawk '{print \$1; print \$2; print \$3}' |\\
    sort -n |\\
    nawk -v axes="\$axes" 'BEGIN{split(axes, abc)} {\\
	# write desired axis ordering in front of cannonical one \\
	print abc[NR], \$0}' |\\
    sort |\\
    nawk '{print \$2}' >! \${tempfile}newcell
    echo "90 90 90"   >> \${tempfile}newcell
    set CELL = \`cat \${tempfile}newcell\`
    set CELL = \`echo "\$CELL" | nawk '{print \$1+0, \$2+0, \$3+0, \$4+0, \$5+0, \$6+0}'\`

    rm -f \${tempfile}newcell >& /dev/null
    if(\$#CELL != 6) then
	# this should never happen...
	echo "ERROR! no unit cell is available! "	
	set BAD
	goto done
    endif
    
endif

# the "future" space group (for the report) will be \$futureSG
set futureSG = \`echo "\$newSG" | nawk '/^[PC]2212\$/||/^[PC]2122\$/{print substr(\$1,1,1) "2221"} /^P21221\$/||/^P22121\$/{print "P21212"}'\`
if("\$futureSG" == "") set futureSG = "\$newSG"


# can we change space groups? (that is, do we have a chiral screw axis)
set otherSG = ""
if("\$newSG" =~ P[346]*) then
    # construct inverted-hand spacegroup symbol
    set otherSG = \`echo \$newSG | nawk '{print substr(\$1,1,2) substr(\$1,2,1)-substr(\$1,3,1) substr(\$1,4) }'\`
    # make sure it's a real spacegroup
    set otherSG = \`nawk -v SG=\$otherSG '\$4 == SG && \$1 < 500 {print \$4}' \$CLIBD/symop.lib | head -1\`
    if(("\$otherSG" != "")&&("\$otherSG" != "\$newSG")) then
        # we've got another SG to try!
        set otherSG = "\$otherSG"
        # remember the initial SG too
        set firstSG = "\$newSG"
    else
        # no reindexing needed
        set otherSG = ""
    endif
endif
# no way to FLIP_SG if there's nothing to flip to
if("\$otherSG" == "") unset FLIP_SG
# enforce user-specified no flip SG option
if(! \$?FLIP_SG) set otherSG = ""


# define list of all space groups we intend to try
set allSGs = ( \$futureSG \$otherSG )
if((\$?FIND_SITES)&&(\$?FLIP_SG)) then
    # we have even more space groups to consider
    
    # get point-group of \$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 allSGs = \`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 allSGs = "P212121 P21212 P21221 P22121 P2221 P2212 P2122 P222"
#	if("\$latt" == "C") set allSGs = "C222 C2221 C2212 C2122"
    endif
endif
if(\$#allSGs == 1) unset FLIP_SG

# now decide on how to permute the input coorinates
set permutaion = ""
if(\$?site_cell) then
    echo "\$CELL \$site_cell" |\\
    nawk '{A=\$1;B=\$2;C=\$3; x=\$7;y=\$8;z=\$9;\\
          print (A-x)^2+(B-y)^2+(C-z)^2, "XYZ";\\
          print (A-y)^2+(B-z)^2+(C-x)^2, "YZX";\\
          print (A-z)^2+(B-x)^2+(C-y)^2, "ZXY";}' |\\
    sort -n | head -1 >! \${tempfile}permutation
    set permutation = \`nawk '{print \$NF}' \${tempfile}permutation\`
    rm -f \${tempfile}permutation >& /dev/null
endif

if("\$permutation" == "") then
    # must have been unable to get the cell?
    # now we have to "guess" as to what cell the input
    # atoms were found in!  
    # Assume that it was the standard cell, with symops redefined
    if(("\$newSG" =~ [PpCc]2[12][12]*)&&(\$?USER_SITES)) then
	# we are reindexing to an orthorhombic space group,
	# so we need to re-do the sites too! 
	set temp = \`echo "\$newSG" | nawk '{print substr(\$1,2)}'\`
	if(("\$temp" == 21221)||("\$temp" == 2212)) then
	    # the current "Y" axis needs to become "Z"
	    set permutation = "ZXY"
	endif
	if(("\$temp" == 22121)||("\$temp" == 2122)) then
	    # the current "X" axis needs to become "Z"
	    set permutation = "YZX"
	endif
	
	if(\$permutation") then
	    # next message may reflect a dubious choice
	    echo -n "WARNING!  "
	endif
    endif
endif

if("\$permutation" == "YZX") then
    # apply this to sites
    echo "permuting sites in \$sitefile"
    echo "by new XYZ = old \$permutation (because unit cells were different)"
    cat \$coordfile |\\
    nawk '\$1 ~ /^ATOM/{x=\$4; y=\$5; z=\$3; \$3=x; \$4=y; \$5=z} {print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile
endif
if("\$permutation" == "ZXY") then
    # apply this to sites
    echo "permuting sites in \$sitefile"
    echo "by new XYZ = old \$permutation (because unit cells were different)"
    cat \$coordfile |\\
    nawk '\$1 ~ /^ATOM/{x=\$5; y=\$3; z=\$4; \$3=x; \$4=y; \$5=z} {print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile
endif

# sites should now be in the right cell
set site_cell = "\$CELL"



# only look for programs once
if(! \$?FOUND_PROGS) then
    # find location of needed/wanted third-party programs
    goto FindProgs
    # dm 2.x or higher
    # mapman (or brix & bones)
    # shelx (if \$?FIND_SITES)
endif
Return_FindProgs:
set FOUND_PROGS




# report here?
Report:
if(\$?FIRSTIME) set REPORT
if(\$?REPORT) then
    unset FIRSTIME
    echo ""
    echo -n "    Phaser Elves are ready to "
    if(\$?FIND_SITES) then
	echo -n "find "
	if(\$?user_sites) then
	    echo -n "\$user_sites "
	endif

	if(-e "\$SHELX") then
	    set temp = "shelx"
	else
	    set temp = "rantan"
	endif
	echo "heavy atoms using \${temp},"
	echo -n "    and then refine them "
    else
	set temp = ""
	if(\$sites > 1) set temp = "s"
	echo "refine the \$sites heavy-atom position\${temp} from \$sitefile"
	echo -n "    "
    endif
    echo "against the data in \$mtzfile with mlphare,"
    echo "    using a script called \$scriptfile"
    echo ""
    if(! \$?NO_DM) then
	echo "    Solvent-flattening by \${scriptDIR}dm.com will be done at:"
	set temp = \`echo "\$trials" | nawk '{for(i=1;i1{print "and"} {print \$NF"%"}'\`
	echo "    \$temp solvent."
    else
	echo "    No solvent-flattening will be attempted."
    endif
    if(\$?HURRY_UP) then
	echo "    Refinement will be rushed."
    endif
    set temp = ""
    if(\$?FLIP_OCC)  set temp = "\$temp sign"
    if((\$?FLIP_OCC)&&(\$?FLIP_HAND)&&(\$?FLIP_SG)) set temp = "\${temp},"
    if(\$?FLIP_HAND) set temp = "\$temp hand"
    if(\$?FLIP_SG)   set temp = "\$temp space_group"
    if("\$temp" != "") then
	set temp = \`echo \$temp | nawk '{for(i=1;i1{print "and"} {print \$NF}'\`
	set temp = \`echo \$temp | nawk '{gsub("_", " ", \$0); print}'\`
	echo "    Alternative \$temp choices will be explored."
    endif
    if(\$?FILTER_ATOMS) then
	echo "    Atoms with unrealistic parameters will be rejected."
    endif
    if(\$?MORE_SITES) then
	echo "    Peaks found in difference-Fouriers will be added to refinement."
    endif
    echo ""
    echo "    Unit Cell:   \$CELL"
    echo "    Space Group: \$allSGs"
    echo ""
    
    set temp = "Yes"
    echo "Everything look okay? [\$temp]"
    echo -n "\$PROMPT"
    if(\$?AUTO) then
	echo "\$temp"
    else
	echo -n "\$BELL"
	set in = ( \$< )
	if("\$in" != "") set temp = "\$in"
    endif
    set temp = ( \$temp )
    
    # catch unexpected replies
    if(("\$temp" !~ [Yy]*)||(\$#temp != 1)) then
	if((\$#temp == 1)&&("\$temp" =~ [Nn]*)) then
	    # one word, began with "N"
	    set temp = "nothing"
	    echo "What's wrong? [\$temp]?"
	    echo -n "\$PROMPT"
	    if(\$?AUTO) then
		echo "\$temp"
	    else
		set in = ( \$< )
		if("\$in" != "") set temp = ( \$in )
	    endif
	    if(("\$temp" == "quit")||("\$temp" == "exit")||("\$temp" == "stop")) then
		set QUIT
		goto done
	    endif
	    if("\$temp" != "nothing") then
		set input = "\$temp"
		goto Gather
	    endif
	else
	    set input = "\$temp"
	    goto Gather
	endif
    endif

    # user said everyhting is okay!
    echo "Good."
    unset REPORT
endif




# only do this once
if(! \$?MADE_DIRS) then
    # make required directories
    foreach dir ( \$logDIR \$mtzDIR \$scriptDIR \$mapDIR \$oDIR )
	# see if it's already done
	set temp = \`ls -lnd \$dir |& nawk '/^d/{print \$NF}'\`
	if((-e "\$dir")&&(! -e "\$temp")) then
	    # a file is using this name
	    echo "WARNING: we are moving your \$dir to \${dir}.old"
	    mv -f \$dir \${dir}.old
	endif
	if(! -e "\$dir") mkdir \$dir
    end
    
    # generate the auxillary scripts
    goto Setup_scripts
    # generate: (if they're not already there)
    #\${scriptDIR}reindex.com
    #\${scriptDIR}rrsps.com
    #\${scriptDIR}bestFH.com
    #\${scriptDIR}dm.com
    #\${scriptDIR}fft.com
    #\${scriptDIR}pick.com
    set MADE_DIRS
endif
Return_Setup_scripts:

















reindex:
################################################################################

 #####   ######     #    #    #  #####   ######  #    #
 #    #  #          #    ##   #  #    #  #        #  #
 #    #  #####      #    # #  #  #    #  #####     ##
 #####   #          #    #  # #  #    #  #         ##
 #   #   #          #    #   ##  #    #  #        #  #
 #    #  ######     #    #    #  #####   ######  #    #

################################################################################
# check to see if it's time for another space group.
################################################################################
if((("\$newSG" != "\$SG")&&("\$newSG" != ""))||(\$?REINDEX_SG)) then
    # maybe use this variable to communicate extra parameters someday? 
    if(! \$?REINDEX_SG) set REINDEX_SG

    # make up a "new" input mtz name
    set newmtzfile = \`echo "\$firstmtz" | nawk 'BEGIN{FS="/"} {print \$NF}' | nawk 'BEGIN{FS="."} {for(i=1;i& /dev/null
    
    
    # check for success
    if(-e "\$newmtzfile") then    
	# reset variables
	set mtzfile = \$newmtzfile
	set SG = "\$newSG"
	if(! \$?site_cell) set site_cell = "\$CELL"
	set CELL = \`echo "head" | mtzdump hklin \$mtzfile | nawk '/Cell Dimensions/{getline;getline;print}'\`
	set CELL = \`echo "\$CELL" | nawk '{print \$1+0, \$2+0, \$3+0, \$4+0, \$5+0, \$6+0}'\`
    else
	# something went wrong
	echo "FAILED!  sticking with \$mtzfile in \$SG ..."
	set newSG = \$SG
    endif
    unset REINDEX_SG
endif











# jump to site locator at this point 
# (if we don't have any starting atoms)
if(\$?FIND_SITES) goto FindSites

# no need to FLIP_SG anymore if there is no otherSG
if("\$otherSG" == "") unset FLIP_SG

# allow user-override of degrees-of-freedom
if(\$?user_params) then
    #if(\$user_params > \$params) set params = \$user_params
    set params = \$user_params
endif
# only display when refinement type changes (beginning)
if(\$params == 1) echo "refining B-factors only"
if(\$params == 2) echo "refining occupancies only"
if(\$params == 3) echo "refining XYZ only"
if(\$params == 4) echo "refining XYZ and B-factors"
if(\$params == 5) echo "refining XYZ and occupancy"
if(\$params == 6) echo "refining XYZ, occupancy and B-factors"


Write_Script:
###############################################################################

  ####    ####   #####      #    #####    #####
 #       #    #  #    #     #    #    #     #
  ####   #       #    #     #    #    #     #
      #  #       #####      #    #####      #
 #    #  #    #  #   #      #    #          #
  ####    ####   #    #     #    #          #

###############################################################################
#
#	get ready to run mlphare
#
########################################################################################################



# impose Phaser's options on the atom list
# needs: 
# \$coordfile 
# \${tempfile}.LABELS (or \$scriptfile)
# can use:
# \${tempfile}EXCLUDE 
# \${tempfile}badatoms


if(! \$?AUTO) then
    # ask for approval?
endif

# regenerate the LABELS file, if it is missing somehow
if((! -e \${tempfile}.LABELS)&&(-e \$scriptfile)) then
    # this shouldn't happen, but it might
    cat \$scriptfile |\\
    nawk '\$1 ~ /^LABIN/{print; while(\$NF == "-"){getline; print}}' |\\
    nawk 'BEGIN{RS=" "} NF != 0 && \$1 != "-"' |\\
    nawk 'NF!=0' |\\
    nawk '/^FPH/{printf " -\\n"} {printf "%s ", \$0} END{print ""}' |\\
    nawk '/^LABI/{printf "LABIN %-10s %s -\\n", \$2, \$3} \\
     \$1~/^FPH/{printf "      %-10s %-15s %-15s %s %s\\n", \$1, \$2, \$3, \$4, \$5}' |\\
    cat >! \${tempfile}.LABELS
endif


# regenerate sites (if they are missing somehow)
grep ATOM "\$coordfile" >& /dev/null
if(\$status) then
    echo "WARNING: all atoms are gone! "

    # no worries if we were just flipping...
    if(\$?TENTATIVE) then
	# loss of atoms occurred because of something
	# Phaser did, so go undo it
	echo "...guess that was a bad idea."
	goto Flip
    endif

    # only do this once
    if(\$?RESTORED_ATOMS) then
	set BAD
	goto done
    endif
    
    rm -f \$coordfile >& /dev/null
    grep ATOM "\${scriptfile}.best" >& /dev/null
    if((! \$status)&&(! -e "\$coordfile")) then
	echo "restoring atoms from \${scriptfile}.best"
	cat \${scriptfile}.best |\\
	nawk '\$1~/^DERIV/,/END/' |\\
	nawk '\$1~/^ATOM/ && /BFAC/{\$NF=99} {print}' |\\
	cat >! \$coordfile
    endif
    grep ATOM "\$scriptfile" >& /dev/null
    if((! \$status)&&(! -e "\$coordfile")) then
	echo "restoring atoms from \$scriptfile"
	cat \$scriptfile |\\
	nawk '\$1~/^DERIV/,/END/' |\\
	nawk '\$1~/^ATOM/ && /BFAC/{\$NF=99} {print}' |\\
	cat >! \$coordfile
    endif

    if(! -e "\$coordfile") then
	echo "ERROR: we seem to have lost all the atoms! "
	set BAD
	goto done
    endif
    set RESTORED_ATOMS
endif


# maintain list of known-to-be-bad atoms
if((\$Cycle > 0)&&(! \$?FLIP_BEGIN)) then
    # don't mistake a Phaser-written script for input one on first round

    # check for old,bad atoms already listed in the last script
    egrep "BADATOM|OLDATOM" \$scriptfile >& /dev/null
    if(! \$status) then
	# the last script has "bad" atoms in it
	cat \$scriptfile |\\
	nawk '\$1~/^BADATOM/ || \$1~/^OLDATOM/' >! \${tempfile}
	
	# propagate these old/bad atoms to the next script
	if(-e \${tempfile}badatoms) then
	    # add "new bad" sites after these
	    cat \${tempfile}badatoms >> \${tempfile}
	endif
	mv \${tempfile} \${tempfile}badatoms
    endif
endif
unset FLIP_BEGIN

# insert the EXCLUDE cards (if they are missing)
grep -i EXCLUDE \$coordfile >& /dev/null
if((\$status)&&(-e \${tempfile}EXCLUDE)) then
    # there are no EXLCUDE cards, so we should use ours
    cat \${tempfile}EXCLUDE \$coordfile |\\
    nawk '! /^[0-9]/{print} \\
            /^[1-9]/{card[\$1] = card[\$1] \$2 " " \$3 " " } \\
	    /DERIV/{++deriv; print " EXCLUDE", card[deriv]}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile
endif
# done with this file now
rm -f \${tempfile}EXCLUDE >& /dev/null


# decide to refine against real or anomalous diffs
cat \$coordfile |\\
nawk '\$1!~/^ATREF/{print} \\
      \$1~/^ATOM/{\\
        if(\$6*\$6 > \$7*\$7){\\
	  # isomorphous diffs are stronger \\
	  print " ATREF X ALL Y ALL Z ALL OCC ALL AOCC ALL B ALL"}\\
	else{\\
	# anomalous diffs are stronger \\
	print " ATREF AX ALL AY ALL AZ ALL OCC ALL AOCC ALL AB ALL"}}' |\\
cat >! \${tempfile}refine
mv \${tempfile}refine \$coordfile


# disable occupancy refinement for occupancies == 0;
cat \$coordfile |\\
nawk '\$1!~/^ATREF/{print} \\
      \$1~/^ATOM/{occ = \$6+0; aocc = \$7+0; getline; \\
    printf " ATREF "; for(i=2;i <= NF; i+=2){\\
    # only print refinement flag if occupancy != 0 \\
    if(! (((\$i == "OCC")&&(occ == 0)) || ((\$i == "AOCC")&&(aocc <= 0)))) printf "%s ALL ", \$i}; \\
    print ""}' |\\
cat >! \${tempfile}refine
mv \${tempfile}refine \$coordfile

# check for anomalous-only data
set temp = \`nawk '\$1~/^ATOM/ && \$6*\$6 > 0.000025' \$coordfile | wc -l\`
if("\$temp" == "0") then
    # no atoms have real occupancies
    unset FLIP_OCC
endif

if(\$params == 1) then
    # params=1 means B-only refinement

    # disable all XYZ refinement, and do occupancy only
    cat \$coordfile |\\
    nawk '\$1!~/^ATREF/{print} \$1~/^ATREF/{ \\
	printf " ATREF "; for(i=2;i <= NF; i+=2){\\
	# remove all but B refinement flags for this atom \\
	if(\$i ~ "B") printf "%s ALL ", \$i}; \\
	print ""}' |\\
    cat >! \${tempfile}refine
endif

if(\$params == 2) then
    # params=2 means occupancy-only refinement
#    set Memory = 0
    
    # disable all XYZ refinement, and do occupancy only
    cat \$coordfile |\\
    nawk '\$1!~/^ATREF/{print} \$1~/^ATREF/{ \\
	printf " ATREF "; for(i=2;i <= NF; i+=2){\\
	# remove XYZ refinement flags for this atom \\
	if(\$i !~ "X|Y|Z|B") printf "%s ALL ", \$i}; \\
	print ""}' |\\
    cat >! \${tempfile}refine
endif

if(\$params >= 3) then
    # create ATREF line for desired degrees of freedom
    set mask = \`echo "X Y Z O AO B \$params" | nawk '{printf "W"; for(i=6;i>\$NF;--i){printf "|%s", \$i}}'\`
#    if(\$params == 3) set mask = "O|AO|B"
    if(\$params == 4) set mask = "O|AO"
#    if(\$params == 5) set mask = "B"
#    if(\$params == 6) set mask = "W"
    cat \$coordfile |\\
    nawk -v mask=\$mask '\$1!~/^ATREF/{print} \$1~/^ATREF/{\\
	printf " ATREF "; for(i=2;i <= NF; i+=2){\\
	# remove desired refinement keys \\
	if(\$i !~ mask) printf "%s ALL ", \$i}; print ""}' |\\
    cat >! \${tempfile}refine
    
endif
mv \${tempfile}refine \$coordfile

# disable refinement of indeterminant axes (for first atom only)
cat \$coordfile |\\
nawk -v fix=\$fix '\$1!="ATOM1"{print} \$1=="ATOM1"{print; getline; \\
    printf " ATREF "; for(i=2;i <= NF; i+=2){\\
    # remove refinement card for this atom \\
    if(\$i !~ fix) printf "%s ALL ", \$i}; print ""}' |\\
cat >! \${tempfile}refine
mv \${tempfile}refine \$coordfile


# reformat atom list, so it's pretty
cat \$coordfile |\\
nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
nawk '\$1!~/^ATOM/{print} \$1~/^ATOM/{\\
    printf " ATOM%-3d ANO  %6.3f %6.3f %6.3f %6.3f %6.3f BFAC %8.3f\\n",\\
    substr(\$1,5)+0, \$3, \$4, \$5, \$6, \$7, \$9}' >! \${tempfile}refine
mv \${tempfile}refine \$coordfile



# \$coordfile has now been completely filtered




# speed up when we know we're close?
#if(\$?TENTATIVE) set mlphareCYCLES = 5




# maintain decaying list of old scripts
if(-e \${scriptfile}.older) mv \${scriptfile}.older \${scriptfile}.oldest
if(-e \${scriptfile}.old) mv \${scriptfile}.old \${scriptfile}.older
if(-e \${scriptfile}) mv \${scriptfile} \${scriptfile}.old

cat << END-script >! \$scriptfile
#! /bin/csh -f
#
#   \$scriptfile  - Automatically generated mlphare script
#
#   (courtesy of the Phaser Elves)
#
# intended for \$SG
#         cell \$CELL
#
set mtzfile = \$mtzfile
set outfile = mlphared.mtz

if(("\\\$1" =~ *.mtz)&&(-e "\\\$1")) set mtzfile = "\\\$1"

mlphare \\
        HKLIN \\\$mtzfile \\
	HKLOUT \\\$outfile   \\
 << eof-phare
TITLE Phaser Elves's mlphare script
HLOUT

\$RESCARD
SCALE SIGFP 1.0
CYCLE \$mlphareCYCLES
ANGLE 10
PRINT AVE AVF
END-script
cat \${tempfile}.LABELS >> \$scriptfile
rm -f \${tempfile}.LABELS >& /dev/null
cat << END-script >> \$scriptfile
LABOUT ALLIN
RUN

# note that occupancies here should be in "electron" units
# relative to the absolute scale of your data
END-script
cat \$coordfile >> \$scriptfile
rm -f \$coordfile >& /dev/null
cat << END-script >> \$scriptfile

END
eof-phare
if(! \\\$status) then
    echo \\\$mtzfile phased to \\\$outfile
endif

exit

END-script
if(-e \${tempfile}badatoms) then
    echo "Sites we have already tried (history list):" >> \$scriptfile
    cat \${tempfile}badatoms >> \$scriptfile
    
    rm -f \${tempfile}badatoms >& /dev/null
endif
chmod a+x \$scriptfile


make_pdb:
#######################################################
# convert the mlphare sites to other file formats
#######################################################
cat \$scriptfile |\\
nawk '\$1 ~ /^ATOM/{print}' |\\
cat >! \${tempfile}sites

# first, symmetry-expand all these sites out to a full unit cell
cat << EOF >! \${tempfile}gensym.in
SYMM \$SGnum
CELL \$CELL
XYZLIM -0.1 1.1 -0.1 1.1 -0.1 1.1 
EOF
# label by ordinal number in mlphare script
cat \${tempfile}sites |\\
nawk '{++n; print "RESIDUE",n; print "ATOM X", \$3, \$4, \$5}' |\\
cat >> \${tempfile}gensym.in
cat \${tempfile}gensym.in | gensym |&\\
nawk '/List of sites/,/Normal termination/' |\\
nawk '\$2 ~ /[01].[0-9][0-9][0-9]/{print \$2, \$3, \$4, \$5, \$6, \$7, \$(NF-1), "sym"}' |\\
cat >! \${tempfile}symsites
rm -f \${tempfile}gensym.in >& /dev/null

# set cutoff for sites being "close enough"
set CLOSE_peaks = \`echo "\$hiRES" | nawk '{printf "%.2f", \$1/3}'\`

# now filter the symmetry-expanded list of all sites to 
# assign a unique list of independent sites
cat \${tempfile}symsites |\\
nawk -v cut=\$CLOSE_peaks '\\
    \$NF=="sym"{++n; X[n]=\$4; Y[n]=\$5; Z[n]=\$6; group[n]=\$(NF-1); \\
	for(i=1;i<=n;++i){\\
	    dist=sqrt((\$4-X[i])^2 +(\$5-Y[i])^2 +(\$6-Z[i])^2);\\
	    # see if this site has already been printed \\
	    if(dist < cut){ label = group[i]; break}}; \\
	print \$(NF-1), "same as", label}' |\\
sort -un >! \${tempfile}sites_unique
rm -f \${tempfile}symsites >& /dev/null

# now reduce equivalent sites to a common label
cat \${tempfile}sites_unique \${tempfile}sites |\\
nawk '/same as/{g[\$1]=\$NF}\\
    ! /same as/{++n; ++count[g[n]]; if(g[n]==n) ATOM[g[n]]=\$1; \\
      X[g[n]]+=\$3; Y[g[n]]+=\$4; Z[g[n]]+=\$5; \\
      if(\$6+0!=0)++ocount[g[n]]; if(\$7+0!=0)++acount[g[n]];\\
      occ[g[n]]+=\$6; aocc[g[n]]+=\$7; B[g[n]]+=\$9 }\\
      END{for(i in ATOM){if(count[i]==0) count[i]=999999;\\
      if(ocount[i]==0) ocount[i]=999999;if(acount[i]==0) acount[i]=999999;\\
      print i, ATOM[i], X[i]/count[i], Y[i]/count[i], Z[i]/count[i],\\
        occ[i]/ocount[i], aocc[i]/acount[i], B[i]/count[i];}}' |\\
sort -n |\\
nawk '{printf " %-7s ANO  %6.3f %6.3f %6.3f %6.3f %6.3f BFAC %8.3f\\n",\\
       \$2, \$3, \$4, \$5, \$6, \$7, \$8}' |\\
cat >! \${scriptDIR}sites.mlphare
rm -f \${tempfile}sites >& /dev/null
rm -f \${tempfile}sites_unique >& /dev/null


# make a PDB too
cat \${scriptDIR}sites.mlphare |\\
nawk 'BEGIN{deriv="0"} \$1~/^ATOM/{print substr(\$1,5), \$3, \$4, \$5, sqrt(\$6*\$6),\$7, \$NF}' |\\
nawk '{B=\$NF; norm=2; if((\$5+0==0)||(\$6+0==0)) norm=1; occ=(\$5+\$6)/norm;\\
       printf "%5d%10.5f%10.5f%10.5f%10.5f%5.2f%5d%10d%2s%-3s%3s %1s\\n", \\
       \$1, \$2, \$3, \$4, B, occ, "38", \$1, "HA", "", "IUM", " "}' |\\
cat >! \${tempfile}sites.frac

# use coordconv to convert fractional MLphare coordinates to Angstroms
coordconv XYZIN \${tempfile}sites.frac \\
         XYZOUT \${tempfile}sites.pdb << EOF-conv >& /dev/null
CELL \$CELL
INPUT FRAC
OUTPUT PDB ORTH 1
END
EOF-conv

# explain what this is in the header
echo "REMARK symmetry-reduced sites from \$scriptfile" |\\
cat - \${tempfile}sites.pdb |\\
cat >! \${oDIR}/sites.pdb

rm -f \${tempfile}sites.frac >& /dev/null
rm -f \${tempfile}sites.pdb  >& /dev/null

##################
# \${scriptDIR}sites.mlphare has the (reduced) sites in MLPHARE format
# \${oDIR}/sites.pdb has the (reduced) sites in PDB format
# these will be renamed by the "Flip" procedure anyway
##################


###############################################################################

# clean up ALL temporary files (everything can be reconstructed from the logfile)



# back up old logs
tail -100 \${logfile}.older |& grep "Normal termination" >& /dev/null
if(! \$status) mv \${logfile}.older \${logfile}.oldest
tail -100 \${logfile}.old   |& grep "Normal termination" >& /dev/null
if(! \$status) mv \${logfile}.old \${logfile}.older
tail -100 \${logfile}       |& grep "Normal termination" >& /dev/null
if(! \$status) mv \${logfile} \${logfile}.old

########################################################

 #####   #    #  #    #
 #    #  #    #  ##   #
 #    #  #    #  # #  #
 #####   #    #  #  # #
 #   #   #    #  #   ##
 #    #   ####   #    #

########################################################
#  Actual MLPHARE run
########################################################
echo -n "running \$scriptfile into \$logfile "
./\$scriptfile \$mtzfile | nawk '{print} NR>100000{exit}' | tee \$logfile | nawk '\$1=="Cycle:"&&\$2%3==0 || \$2=="CYCLE"&&\$3%3==0{printf "."}'
########################################################
set temp = \$status
if(! \$temp) then
    # make sure mlphare reported sucessful finish
    grep "Normal termination" \$logfile >& /dev/null
    set temp = \$status
endif
if(! \$temp) then
    if(-e mlphared.mtz) then
	# move the output file to where Phaser wants it
	mv mlphared.mtz \${mtzDIR}mlphare.mtz
	set temp = \$status
    else
	# output file does not exist! 
	set temp = 1
    endif
endif
if(! \$temp) then    
    # this run was good, so reset any tentative things
    if(\$?SHORT_RUN) then
	# this run was shortened, and that fixed the problem
	# so, reset to the previous run length
	set mlphareCYCLES = \$SHORT_RUN
	# forget that we tried this? 
	unset SHORT_RUN
    endif
else
    echo "mlphare crashed! "

    # maybe we let it run too long?
    if(! \$?SHORT_RUN) then
        # we have not tried a short run
        set temp = \`nawk '/Cycle:/{cyc = \$NF} /inconsistent phase/{exit} END{print cyc+0}' \${logfile}\`
        if(\$temp > 2) then
            # allow this run to get as far as it did, and then try to eliminate sites
	    # store "old" cycle count in this variable
	    set SHORT_RUN = \$mlphareCYCLES
	    # set new cycle count to one less that old one
            @ mlphareCYCLES = ( \$temp - 1 )
	    echo "woops!  let's try just \$mlphareCYCLES cycles."
	    # "read" scriptfile like an input script
	    nawk '\$1 ~ /DERIV/,/END/{print}' \$scriptfile |\\
	    nawk '! /END/{print}' >! \${coordfile}

	    goto Write_Script
        endif
    else
	# we just tried a short run (and it failed), so undo the limited number of cycles
	set mlphareCYCLES = \$SHORT_RUN
	unset SHORT_RUN
    endif


    # see if there's anything we can do...
    if(\$?TENTATIVE) then
	# this crash occurred because of something
	# Phaser did, so go undo it
	echo "...guess that was a bad idea."
	goto Flip
    endif
    
    
    echo "examine \${logfile} to find out what went wrong. "
    echo "once you have made any changes to \${scriptfile}, you"
    echo "can continue automated refinement by typing:"
    echo "\$0 \$scriptfile "
    echo ""
    echo "Good Luck! "
    rm -f \${tempfile}* >& /dev/null
    exit 9
endif

# keep track of how many mlphare runs we have done
@ Cycle = ( \$Cycle + 1 )
@ Memory = ( \$Memory + 1 )

##############################
#if(\$params == 2) then
#    # eliminate stupid atoms
#    set FILTER_ATOMS
#endif





Analyze_Results:
################################################################################################################

 #####   ######   ####   #    #  #        #####   ####
 #    #  #       #       #    #  #          #    #
 #    #  #####    ####   #    #  #          #     ####
 #####   #            #  #    #  #          #         #
 #   #   #       #    #  #    #  #          #    #    #
 #    #  ######   ####    ####   ######     #     ####

################################################################################################################
#   Analyze results of the MLphare run
################################################################################################################

if(! -e "\$logfile") then
    echo "ERROR: no log produced! "
    set BAD
    goto done
endif
    
# print out mean FOM
cat \$logfile |\\
nawk '/phased -ALL/ || /phased -ACENTRIC/{getline; getline; getline; min = 1; max=0; print; \\
  for(i=1;i max) max=\$i; if((\$i < min)&&(\$i+0!=0)) min = \$i};\\
  print " FOM = " \$NF " ("min" - "max")"}' |\\
tail -1 >! \${tempfile}FOM
set FOM = \`nawk '{print \$3}' \${tempfile}FOM\`
nawk '{printf "%s", \$0}' \${tempfile}FOM
rm -f \${tempfile}FOM

# print out phasing powers
#echo "  best Phasing Power = " | nawk '{printf "%s", \$0}'
#nawk '/PhP_a/{getline;print \$6;getline;print \$6;getline;print \$6;getline;print \$6;\\
# getline;print \$6;getline;print \$6;getline;print \$6;getline;print \$6}'\\
#\$logfile | sort -n | tail -1 | nawk '{printf "%s (a), ", \$1}'
#nawk '/PhP_a/{getline;print \$11;getline;print \$11;getline;print \$11;getline;print \$11;\\
# getline;print \$11;getline;print \$11;getline;print \$11;getline;print \$11}'\\
#\$logfile | sort -n | tail -1 | nawk '{printf "%s (c)", \$1}'

echo ""

####################################################################
# reconstruct LABIN card from the log
cat \$logfile |\\
nawk '/LABIN/{printf "%s", substr(\$0, 15); while(getline){if(\$1 != "Data"){printf "%s", substr(\$0, 2)}else{break}}}' |\\
nawk 'BEGIN{RS=" "; ORS=" "} NF != 0' |\\
nawk 'BEGIN{RS=" "} /^FPH/{printf "-\\n"} {printf "%s ", \$0} END{print ""}' |\\
nawk '/^LABI/{printf "LABIN %-10s %s -\\n", \$2, \$3} \\
 \$1~/^FPH/{printf "      %-10s %-15s %-15s %s %s\\n", \$1, \$2, \$3, \$4, \$5}' |\\
cat >! \${tempfile}.LABELS

# reconstruct EXCLUDE cards from the log
cat \$logfile |\\
nawk '\$1=="Compound"{deriv=\$2} \\
      \$5=="Compound"{deriv=\$6} \\
      \$1=="EXCLUDE" && /FPH -FP/ && />/{print deriv+0, "DISO", \$NF}   \\
      \$1=="EXCLUDE" && /-FPH/ && />/{print deriv+0, "DANO", \$NF}' |\\
cat >! \${tempfile}EXCLUDE

# extract atom entries from the MLphare log 
# (with full refinement cards)
cat \$logfile |\\
nawk '\$1~/^DERIV/,\$1~/^MLPHARE/{print}' |\\
nawk '\$1 ~ /^ATOM/ {while(/\\.[0-9][0-9][0-9][0-9-]/ && safe < 20){\\
      # insert spaces between numbers that are stuck together \\
      stuck=match(\$0,/\\.[0-9][0-9][0-9][0-9-]/)+3; \\
      \$0 = substr(\$0,1,stuck) " " substr(\$0, stuck+1);++safe}}\\
      {print}' |\\
nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
nawk '! /MLPHARE/ && ! /SUMMARY/{print}' >! \${coordfile}

# apply MAD constraints here? 
if(\$?MAD) then
    nawk -f \${scriptDIR}mad.awk -v same_occ=1 -v same_B=1 \${coordfile} |\\
    nawk '\$0=="Summary:"{exit} {print}' >! \${tempfile}
    mv \${tempfile} \${coordfile}
endif

# check for valid atoms
grep ATOM \${coordfile} >& /dev/null
if(\$status) then
    echo "ERROR: no atoms found in \$logfile ... "
    set FIND_SITES
    goto Report
endif

####################################################################
# see if these parameters have converged

# extract list of parameters from \$coordfile (the "next" script)
cat \$coordfile |\\
nawk '\$1~/^ATOM/ {++n; print n,"x",\$3; print n,"y",\$4; print n,"z",\$5;\\
                       print n,"o",\$6; print n,"a",\$7; print n,"b",\$NF}' |\\
cat >! \${tempfile}params
# format: atomnum [xyzoab] value

# get input coordinates from the "current" script
cat \$scriptfile |\\
nawk '\$1~/^ATOM/ {++n; print n,"x",\$3; print n,"y",\$4; print n,"z",\$5;\\
                       print n,"o",\$6; print n,"a",\$7; print n,"b",\$NF}' |\\
cat >! \${tempfile}oldparams
# format: atomnum [xyzoab] value

# get coordinates from one or more old scripts
if((-e "\${scriptfile}.old")&&(\$Memory > 2)) then
    # (re)extract atoms from the "previous" script
    cat \${scriptfile}.old |\\
    nawk '\$1~/^DERIV/,\$1~/^MLPHARE/{print}' |\\
    nawk '\$1 ~ /^ATOM/ {while(/\\.[0-9][0-9][0-9][0-9-]/ && safe < 20){\\
          # insert spaces between numbers that are stuck together \\
          stuck=match(\$0,/\\.[0-9][0-9][0-9][0-9-]/)+3; \\
          \$0 = substr(\$0,1,stuck) " " substr(\$0, stuck+1);++safe}}\\
        {print}' |\\
    nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
    nawk '\$1~/^ATOM/ {++n; print n,"x",\$3; print n,"y",\$4; print n,"z",\$5;\\
			   print n,"o",\$6; print n,"a",\$7; print n,"b",\$NF}' |\\
    cat >! \${tempfile}olderparams
    # format: atomnum [xyzoab] value
endif

if((-e "\${scriptfile}.older")&&(\$Memory > 3)) then
    # (re)extract atoms from 2 runs ago
    cat \${scriptfile}.older |\\
    nawk '\$1~/^DERIV/,\$1~/^MLPHARE/{print}' |\\
    nawk '\$1 ~ /^ATOM/ {while(/\\.[0-9][0-9][0-9][0-9-]/ && safe < 20){\\
	  # insert spaces between numbers that are stuck together \\
	  stuck=match(\$0,/\\.[0-9][0-9][0-9][0-9-]/)+3; \\
	  \$0 = substr(\$0,1,stuck) " " substr(\$0, stuck+1);++safe}}\\
	  {print}' |\\
    nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
    nawk '\$1~/^ATOM/ {++n; print n,"x",\$3; print n,"y",\$4; print n,"z",\$5;\\
			   print n,"o",\$6; print n,"a",\$7; print n,"b",\$NF}' |\\
    cat >! \${tempfile}oldestparams
    # format: atomnum [xyzoab] value
endif

if((-e "\${scriptfile}.oldest")&&(\$Memory > 4)) then
    # (re)extract atoms from 3 runs ago
    cat \${scriptfile}.oldest |\\
    nawk '\$1~/^DERIV/,\$1~/^MLPHARE/{print}' |\\
    nawk '\$1 ~ /^ATOM/ {while(/\\.[0-9][0-9][0-9][0-9-]/ && safe < 20){\\
	  # insert spaces between numbers that are stuck together \\
	  stuck=match(\$0,/\\.[0-9][0-9][0-9][0-9-]/)+3; \\
	  \$0 = substr(\$0,1,stuck) " " substr(\$0, stuck+1);++safe}}\\
	  {print}' |\\
    nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
    nawk '\$1~/^ATOM/ {++n; print n,"x",\$3; print n,"y",\$4; print n,"z",\$5;\\
			   print n,"o",\$6; print n,"a",\$7; print n,"b",\$NF}' |\\
    cat >! \${tempfile}oldestparams
    # format: atomnum [xyzoab] value
endif

# make sure we have at least two parameter sets to compare
set sets = \`ls -1 \${tempfile}*params |& wc -l\`
if(\$sets > 1) then
    # calculate the shifts between each parameter set
    cat \${tempfile}*params |\\
    nawk '{p=\$1 " " \$2; param[p]=param[p] " " \$3} \\
	  END{for(p in param) print p, param[p]}' | sort -n |\\
    nawk '{printf "%s %s ",\$1, \$2; \\
	   for(i=3;i<=NF;++i){for(j=i+1;j<=NF;++j){printf "%s ", sqrt((\$i-\$j)^2);}} print ""}' |\\
    cat >! \${tempfile}shifts
    # format: atomnum [xyzoab] shift shift shift ...    	

    # find the largest, overall "minimum" shift
    cat \${tempfile}shifts |\\
    nawk '{min=99999; for(i=3;i<=NF;++i){if(min>\$i)min=\$i} print \$1, \$2, min}' |\\
    nawk '\$NF>max{max=\$NF} END{printf "%d\\n", max*1000}' |\\
    cat >! \${tempfile}max_of_mins
    
    # load convergence number into a variable
    set maxdrift = \`cat \${tempfile}max_of_mins\`
    rm -f \${tempfile}max_of_mins >& /dev/null
    
    # see if biggest intra-parameter drift meets convergence criteria
    if((\$maxdrift <= \$converge_crit)&&(1)) then
	# this round of MLpharing has converged
	set Converged
	# forget about runs leading up to this
	set Memory = 0
    endif
endif

# clean up
rm -f \${tempfile}*params >& /dev/null
# still need \${tempfile}shifts (below)

####################################################################
# filter out atoms that don't meet cutoffs

# first, find atoms with completely bad occ or Bfactor
#       |occ| > 0.05  OR aocc > 0.05 
#   and \$Bcap > Bfac > \$wilsonB/4
# (negative aocc will be handled below)
nawk '\$1~/^ATOM/' \$coordfile |\\
nawk -v Bcap=\$Bcap -v wilsonB=\$wilsonB '{++n}\\
    \$7 < 0.05 && \$6*\$6 < 0.0025{print "BADATOM", n, "occ too low"}\\
                    \$NF > Bcap {print "BADATOM", n, "B too high"}\\
    \$NF < wilsonB/4 || \$NF < 1 {print "BADATOM", n, "B too low";}' |\\
cat >! \${tempfile}badatom_numbers

# extract and mark atoms that had unreasonable occ and/or B values
cat \${tempfile}badatom_numbers \$coordfile |\\
nawk '\$1=="BADATOM" && NF==5 {bad[\$2]=\$3 " " \$4 " " \$5}\\
      \$1~/^ATOM/{++n; if(bad[n]) \\
      print "BADATOM" substr(\$0, index(\$0, "ATOM")+4), "(" bad[n] ")";}' |\\
cat >! \${tempfile}badatoms



# check for too-big-XYZ-shift atoms (from above):
if(! -e \${tempfile}shifts) then
    echo -n "" >! \${tempfile}shifts
endif
# find any XYZ shifts larger than 0.2 cells
cat \${tempfile}shifts |\\
nawk '\$NF+0 > 0.2 && \$2 ~ /[xyz]/ {print "BADATOM", \$1, \$2, "moved", \$NF}' |\\
sort -nu >! \${tempfile}bigshift_numbers

# extract and mark atoms that LED TO large XYZ shifts
cat \${tempfile}bigshift_numbers \$scriptfile |\\
nawk '\$1=="BADATOM" && NF==5 {bad[\$2]=\$3 " " \$4 " " \$5}\\
      \$1~/^ATOM/{++n; if(bad[n]) \\
      print "BADATOM" substr(\$0, index(\$0, "ATOM")+4), "(", bad[n] ")";}' |\\
cat >> \${tempfile}badatoms


if(\$?MAD) then
    # only eliminate sites with all-bad atoms? 
    unset FILTER_ATOMS
endif


# now actually elimiate the "bad" atoms from \$coordfile
cat \${tempfile}badatom_numbers \${tempfile}bigshift_numbers \$coordfile |\\
nawk '\$1=="BADATOM" && NF==5 {bad[\$2]=1; next}\\
      \$1~/^ATOM/{++n; if(! bad[n]) print} \\
      \$1!~/^ATOM/{print}' |\\
cat >! \${tempfile}filtered

# eliminate atoms in the vicinity of baddies?

# don't need these anymore
rm -f \${tempfile}badatom_numbers \${tempfile}bigshift_numbers >& /dev/null
rm -f \${tempfile}shifts >& /dev/null

# convert negative anomalous occupancies to zero
# (could just be a derivative with no anomalous signal)
set neganoms = \`nawk '\$1~/^ATOM/ && \$7+0<0' \${tempfile}filtered | wc -l\`
if("\$neganoms" != "0") then
    # some anomalous occupancies were negative
    # set them to zero (mlphare set-up engine will not refine these)
    cat \${tempfile}filtered |\\
    nawk '\$1~/^ATOM/ && \$7+0<0 {\$7=0} {print}' |\\
    cat >! \${tempfile}zeroed
    mv \${tempfile}zeroed \${tempfile}filtered
endif

# count how many "bad" atoms there were
set oldatoms = \`nawk '\$1~/^ATOM/{print}' \$coordfile | wc -l\`
set newatoms = \`nawk '\$1~/^ATOM/{print}' \${tempfile}filtered | wc -l\`
set baddies = \`echo "\$oldatoms \$newatoms" | nawk '{print \$1 - \$2}'\`


if(\$?FILTER_ATOMS) then
    #unset FILTER_ATOMS
    
    # use filtered atom list
    mv \${tempfile}filtered \$coordfile
    
    if(("\$baddies" != "0")||("\$neganoms" != "0")) then
	unset Converged
	set Memory = 0
    endif
    
    # report on modifications of atoms
    if("\$baddies" != "0") echo "eliminated \$baddies bad atoms from \$scriptfile"
    if("\$neganoms" != "0") echo "\$neganoms negative anomalous occupancies have been fixed to zero"    
else
    if("\$baddies" != "0") echo "WARNING: \$baddies atoms from \$scriptfile look pretty bad! "
    if("\$neganoms" != "0") echo "WARNING: \$neganoms anomalous occupancies are negative! "    
    rm -f \${tempfile}filtered >& /dev/null
endif


####################################################################
# decide to increase degrees of freedom or not
if(\$?Converged) then
    unset Converged
    if((\$params >= 6)||(\$?user_params)) then
	echo "refinement has converged! "
	
	# clean up
	rm -f \${tempfile}EXCLUDE  >& /dev/null
	rm -f \${tempfile}.LABELS  >& /dev/null
	rm -f \$coordfile          >& /dev/null
	rm -f \${tempfile}badatoms >& /dev/null
	goto flatten
    endif
    # implement a careful parameter refinement schedule
    if(\$params == 5) then
	# we've been refining xyz, occ & aocc
	echo "enabling B factor refinement"
	set params = 6
    endif
    if(\$params == 4) then
	# we've been refining xyz & B
	echo "enabling occupancy refinement"
	set params = 6
    endif
    if((\$params == 5)&&(\$?NO_B)) then
	# we've been refining xyz, occ & aocc
	echo "switching to XYZ & B refinement"
	set params = 4
    endif
    if(\$params == 3) then
	# we've been refining xyzB
	echo "enabling occupancy refinement"
	set params = 5
    endif
    if(\$params == 2) then
	# we've been refining occ & aocc only
	echo "switching to XYZ refinement"
	set params = 3
	set Memory = 0
    endif
    if(\$params == 1) then
	# we've been refining B only
	echo "switching to XYZ refinement"
	set params = 3
	set Memory = 0
    endif
endif

####################################################################	


# we are now ready to go back to refinement


goto Write_Script


















FindProgs:
########################################################################################################

 ######     #    #    #  #####           #####   #####    ####    ####    ####
 #          #    ##   #  #    #          #    #  #    #  #    #  #    #  #
 #####      #    # #  #  #    #          #    #  #    #  #    #  #        ####
 #          #    #  # #  #    #          #####   #####   #    #  #  ###       #
 #          #    #   ##  #    #          #       #   #   #    #  #    #  #    #
 #          #    #    #  #####           #       #    #   ####    ####    ####

########################################################################################################
#	find needed third-party programs
########################################################################################################




set DM = dm
set DM_method = "PERT"





find_mapman:
########################################################################################################
#	find the O/RAVE MAPMAN executable
########################################################################################################
if(\$?NO_MAPMAN) then
    # user doesn't want o-format files
    set MAPMAN = mapman
    set BRIX   = brix
    set BONES  = bones
    goto find_shelx
endif
# no mapman for Linux
#if(\`uname\` == Linux) then
#    set MAPMAN = "mapman"
#    goto find_brix
#endif

set program  = "\$MAPMAN"
set names    = "mapman MAPMAN 6d_mapman 4d_mapman lx_mapman"
set badname  = "xdlmapman"
set places = "~/bin /programs/o/bin /programs/bin /programs /xtal /usr/local/bin /usr/local /usr/xtal /usr"

set size        = 100000
set program_Version = "0"
set GoodVersion     = "4"

# make sure no xwindows program pop up
if(\$?DISPLAY) then
    set noDISPLAY = \$DISPLAY
endif
setenv DISPLAY

# first, check to see if default will work
test -x "\$program"
if(! \$status) then
    set file = \`ls -lnL \$program |& nawk -v size=\$size '\$5>size{print \$NF}'\`
    # test for program signature (author and version number)
    set temp = \`echo "" | \$file |& nawk '/Kleywegt/ && name{print ver, 1;exit} /MAPMAN/{name=1} /Version/{split(\$NF,w,"/"); ver=w[2]}'\`
    if("\$temp" != "") then
	# get most recent version (if possible)
	set temp = \`echo \$temp \$program_Version | nawk '\$1+0 > \$2+0{print \$1}'\`
	if("\$temp" != "") then
	    set program = "\$file"
	    set program_Version = "\$temp"
	endif
    endif
endif


# try using the "which" command
foreach name ( \$names )
    # check for sufficiently high version number
    set temp = \`echo "\$program_Version \$GoodVersion" | nawk '\$1+0 >= \$2+0{print \$1}'\`
    if("\$temp" != "") break
    
    # "which" should handle processing of \$path
    set possibilities = \`which \$name |& nawk 'NF==1{gsub(/[*?\\042\\047]/," "); print}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l \$2+0{print \$1}'\`
		if("\$temp" != "") then
		    set program = "\$file"
		    set program_Version = "\$temp"
		endif
	    endif
	endif
    end
end


# check again for sufficiently high version number
set temp = \`echo "\$program_Version \$GoodVersion" | nawk '\$1+0 >= \$2+0{print \$1}'\`
if("\$temp" == "") then    

    # simplefy program name
    set program = \`echo \$names | nawk '{print \$1}'\`
    
    # search for \$program in likely places
    echo -n "Looking for \$program "
    set HARD_TO_FIND
    onintr Skip_MAPMAN_search
    foreach place ( \$places )
	if(-e \$place) then
	    # keep looking
	    set files = \`ls -lnL \${place} |& grep "\$program" |& sort -nr -k5 |& nawk -v size=\$size ' /^-/ && \$1 ~ /x/ && \$5 > size {print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l \$2+0{print \$1}'\`
		    if("\$temp" != "") then
			set program = "\$file"
			set program_Version = "\$temp"
		    endif
		endif
	    end
	endif
		
	# entertainment
	echo -n "."

	# check for sufficiently high version number
	set temp = \`echo "\$program_Version \$GoodVersion" | nawk '\$1+0 >= \$2+0{print \$1}'\`
	if("\$temp" != "") break
    end
endif


# check again for sufficiently high version number
set temp = \`echo "\$program_Version \$GoodVersion" | nawk '\$1+0 >= \$2+0{print \$1}'\`
if("\$temp" == "") then

    # get absolute time (seconds since 1/1/1)
    set THEN = \`date "+%S %M %H %j %Y" |& nawk '{\$5-=1; printf "%50.0f\\n", \$1+ 60*(\$2+ 60*(\$3+ 24*(\$4 + 365 *\$5 + int(\$5/4) -int(\$5/100) +int(\$5/400) )))}'\`

    echo -n " looking harder "
    
    foreach place ( \$places )
	# check for sufficiently high version number
	set temp = \`echo "\$program_Version \$GoodVersion" | nawk '\$1+0 >= \$2+0{print \$1}'\`
	if("\$temp" != "") break
	
	if(-e \$place) then
	    if("\$place" == "/") echo -n "hmm."
	
	    # use find to get candidate files
	    set files = \`find \$place -name '*'\$program'*' -follow -size +\${size}c -perm -1 -print |& nawk '! /^find:/' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} lL{exit}'\`
	    foreach file ( \$files )
		# skip filenames we know are wrong
		if("\$file" =~ *\$badname) continue

		# test for program signature (author and version number)
		set temp = \`echo "" | \$file |& nawk '/Kleywegt/ && name{print ver, 1;exit} /MAPMAN/{name=1} /Version/{split(\$NF,w,"/"); ver=w[2]}'\`
		if("\$temp" != "") then
		    # get most recent version (if possible)
		    set temp = \`echo \$temp \$program_Version | nawk '\$1+0 > \$2+0{print \$1}'\`
		    if("\$temp" != "") then
			set program = "\$file"
			set program_Version = "\$temp"
		    endif
		endif
	    end
	endif
	
	# entertainment
	echo -n "."

	# give up if this is taking too long (10 minutes)
	set NOW = \`date "+%S %M %H %j %Y" |& nawk '{\$5-=1; printf "%50.0f\\n", \$1+ 60*(\$2+ 60*(\$3+ 24*(\$4 + 365 *\$5 + int(\$5/4) -int(\$5/100) +int(\$5/400) )))}'\`
	set temp = \`echo "\$NOW \$THEN" | nawk '{printf "%d", \$1 - \$2}'\`
	if(\$temp > 600) then
	    echo " this is taking too long."
	    break;
	endif	
    end
endif

Skip_MAPMAN_search:
onintr

# check if we found any program
test -x "\$program"
if(! \$status) then
    # got something, make sure it works
    set file = \$program
    set temp = \`echo "" | \$file |& nawk '/Kleywegt/ && name{print ver, 1;exit} /MAPMAN/{name=1} /Version/{split(\$NF,w,"/"); ver=w[2]}'\`
    if("\$temp" != "") then
	set MAPMAN = \$program
	set MAPMAN_Version = "\$temp"
	set ofmt = "dsn6"
    else
	# this shouldn't happen, but...
#	set MAPMAN = ""
    endif
else
#    set MAPMAN = ""
endif

# turn display back on
if(\$?noDISPLAY) then
    setenv DISPLAY \$noDISPLAY
endif
unset noDISPLAY


# out of ideas, help?
test -x "\$MAPMAN"
if(! \$status) then
    echo ""
    if(\$?HARD_TO_FIND) echo "found \$MAPMAN"
else
    echo ""
    echo "Couldn't find \${program}, looked everywhere."
    set MAPMAN_Version = "0"
    set NO_MAPMAN
endif
unset HARD_TO_FIND



find_brix:
# no need for brix if we have mapman
if(-e "\$MAPMAN") goto find_shelx

# don't have mapman, resort to brix and bones...
set program  = "\$BRIX"
set names    = "brix BRIX 6d_brix 4d_brix"
set badname  = "bones2pdb"
set places = "~/bin /programs/o/bin /programs/bin /programs/o /programs /xtal /usr/local/o/bin /usr/local/o /usr/local/bin /usr/local /usr/xtal /usr"
set places = "/usr/bin ~/bin /programs/o/bin /programs /xtal /usr/local /usr/xtal /usr"


# make a test map
echo "1 1 1 1 1" >! \${tempfile}.hkl
f2mtz hklin \${tempfile}.hkl hklout \${tempfile}.mtz << EOF >& /dev/null
CELL 20 20 20 90 90 90
SYMM P1
LABOU H K L F PHI
CTYPI H H H F P
EOF
fft hklin \${tempfile}.mtz mapout \${tempfile}.map << EOF >& /dev/null
RESO 10
LABIN F1=F PHI=PHI
EOF
rm -f \${tempfile}.hkl \${tempfile}.mtz >& /dev/null
set testmap = \${tempfile}.map
set newmap = \${tempfile}.omap
rm -f "\$newmap" >& /dev/null
if(! -e "\$testmap") then
    # this is not going to work
    echo "test-map generation failed! "
    goto End_BRIX_search
endif


# first, check to see if default will work
test -x "\$program"
if(! \$status) then    
    set file = "\$program"
    
    # test for program function
    rm -f "\$newmap" >& /dev/null
    echo "" | \$file \$testmap \$newmap >& /dev/null
    if(! -e "\$newmap") continue
    
    # check output file
    grep -l ":-)" "\$newmap" >& /dev/null
    if(\$status) continue
    
    # made it this far, \$file must work...
    set program = "\$file"
    goto End_BRIX_search
endif


# try using the "which" command
foreach name ( \$names )
    # "which" should handle processing of \$path
    set possibilities = \`which \$name |& nawk 'NF==1{gsub(/[*?\\042\\047]/," "); print}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
	echo "" | \$file \$testmap \$newmap >& /dev/null
	if(! -e "\$newmap") continue
	
	# check output file
	grep -l ":-)" "\$newmap" >& /dev/null
	if(\$status) continue
	
	# made it this far, \$file must work...
	set program = "\$file"
	goto End_BRIX_search
    end
end


# simplefy program name
set program = \`echo \$names | nawk '{print \$1}'\`

# search for \$program in likely places
echo -n "Looking for \$program program "
set HARD_TO_FIND
# get absolute time (seconds since 1/1/1)
set THEN = \`date "+%S %M %H %j %Y" |& nawk '{\$5-=1; printf "%50.0f\\n", \$1+ 60*(\$2+ 60*(\$3+ 24*(\$4 + 365 *\$5 + int(\$5/4) -int(\$5/100) +int(\$5/400) )))}'\`
onintr End_BRIX_search

foreach place ( \$places )
    if(! -e \$place) continue
    
    # keep looking
    set files = \`ls -lnL \${place} |& grep "\$program" |& sort -nr -k5 |& nawk ' /^-/ && \$1 ~ /x/ {print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
	echo "" | \$file \$testmap \$newmap >& /dev/null
	if(! -e "\$newmap") continue
	
	# check output file
	grep -l ":-)" "\$newmap" >& /dev/null
	if(\$status) continue
	
	# made it this far, \$file must work...
	set program = "\$file"
	goto End_BRIX_search
    end

    # entertainment
    echo -n "."
end


echo -n " looking harder "
    
foreach place ( \$places )
    if(! -e \$place) continue

    if("\$place" == "/") echo -n "hmm."
	
    # use find to get candidate files
    set files = \`find \$place -name '*'\$program'*' -follow -perm -1 -print |& nawk '! /^find:/' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} lL{exit}'\`
    foreach file ( \$files )
	# skip filenames we know are wrong
	if("\$file" =~ *\$badname) continue
	
	# make sure it's executable
	test -x \$file
	if(\$status) continue

	# test for program function
	rm -f "\$newmap" >& /dev/null
	echo "" | \$file \$testmap \$newmap >& /dev/null
	if(! -e "\$newmap") continue
	
	# check output file
	grep -l ":-)" "\$newmap" >& /dev/null
	if(\$status) continue
	
	# made it this far, \$file must work...
	set program = "\$file"
	goto End_BRIX_search
    end
    
    # entertainment
    echo -n "."
    
    # give up if this is taking too long (10 minutes)
    set NOW = \`date "+%S %M %H %j %Y" |& nawk '{\$5-=1; printf "%50.0f\\n", \$1+ 60*(\$2+ 60*(\$3+ 24*(\$4 + 365 *\$5 + int(\$5/4) -int(\$5/100) +int(\$5/400) )))}'\`
    set temp = \`echo "\$NOW \$THEN" | nawk '{printf "%d", \$1 - \$2}'\`
    if(\$temp > 600) then
	echo " this is taking too long."
	goto End_BRIX_search
    endif	
end

End_BRIX_search:
onintr

# check if we found any program
test -x "\$program"
if(! \$status) then
    # got something, make sure it works
    set file = \$program
    rm -f \$newmap >& /dev/null
    echo "" | \$file \$testmap \$newmap >& /dev/null
    if(-e "\$newmap") then
	# check output file
	grep -l ":-)" "\$newmap" >& /dev/null
	if(! \$status) then
	    set BRIX = "\$file"
	    set ofmt = "brix"
	endif
    endif
endif
# clean up
rm -f \${tempfile}.map >& /dev/null
rm -f \${tempfile}.omap >& /dev/null



# out of ideas, help?
test -x "\$BRIX"
if(! \$status) then
    echo ""
    if(\$?HARD_TO_FIND) echo "found \$BRIX"
else
    echo ""
    echo "Couldn't find \${program}, looked everywhere."
    set NO_BRIX
endif
unset HARD_TO_FIND



find_bones:
# no need for "bones" if we have mapman
if(-e "\$MAPMAN") goto find_shelx

set program  = "\$BONES"
set names    = "bones BONES 6d_bones 4d_bones"
set badname  = "bones2pdb"
set places = "/usr/bin ~/bin /programs/o/bin /programs/bin /programs /xtal /usr/local/o/bin /usr/local/o /usr/local/bin /usr/local /usr/xtal /usr"

# make a test map
echo "1 1 1 1 1" >! \${tempfile}.hkl
f2mtz hklin \${tempfile}.hkl hklout \${tempfile}.mtz << EOF >& /dev/null
CELL 10 10 10 90 90 90
SYMM P1
LABOU H K L F PHI
CTYPI H H H F P
EOF
fft hklin \${tempfile}.mtz mapout \${tempfile}.map << EOF >& /dev/null
LABIN F1=F PHI=PHI
EOF
rm -f \${tempfile}.hkl \${tempfile}.mtz >& /dev/null
set testmap = \${tempfile}.map
if(! -e "\$testmap") set testmap = ""

# make a test input file
cat << EOF >! \${tempfile}.inp
\$testmap
1000 1000
1000
\${tempfile}.o
skel
EOF

# first, check to see if default will work
test -x "\$program"
if(! \$status) then
    set file = "\$program"
    
    # test for program function
    rm -f \${tempfile}.o >& /dev/null
    cat \${tempfile}.inp | \$file >& /dev/null
    if(! -e "\${tempfile}.o") continue
    
    # check output file
    grep -l "SKEL_ATOM_XYZ" \${tempfile}.o >& /dev/null
    if(\$status) set program = ""
    
    # made it this far, \$file must work...
    set program = "\$file"
    goto End_BONES_search
endif


# try using the "which" command
foreach name ( \$names )
    # "which" should handle processing of \$path
    set possibilities = \`which \$name |& nawk 'NF==1{gsub(/[*?\\042\\047]/," "); print}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
	cat \${tempfile}.inp | \$file >& /dev/null
	if(! -e "\${tempfile}.o") continue
    
	# check output file
	grep -l "SKEL_ATOM_XYZ" \${tempfile}.o >& /dev/null
	if(\$status) continue
	
	# made it this far, \$file must work...
	set program = "\$file"
	goto End_BONES_search
    end
end


# simplefy program name
set program = \`echo \$names | nawk '{print \$1}'\`

# search for \$program in likely places
echo -n "Looking for \$program program "
set HARD_TO_FIND
# get absolute time (seconds since 1/1/1)
set THEN = \`date "+%S %M %H %j %Y" |& nawk '{\$5-=1; printf "%50.0f\\n", \$1+ 60*(\$2+ 60*(\$3+ 24*(\$4 + 365 *\$5 + int(\$5/4) -int(\$5/100) +int(\$5/400) )))}'\`
onintr End_BONES_search

foreach place ( \$places )
    if(! -e \$place) continue
    
    # keep looking
    set files = \`ls -lnL \${place} |& grep "\$program" |& sort -nr -k5 |& nawk ' /^-/ && \$1 ~ /x/ {print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l& /dev/null
	cat \${tempfile}.inp | \$file >& /dev/null
	if(! -e "\${tempfile}.o") continue
    
	# check output file
	grep -l "SKEL_ATOM_XYZ" \${tempfile}.o >& /dev/null
	if(\$status) continue
	
	# made it this far, \$file must work...
	set program = "\$file"
	goto End_BONES_search
    end

    # entertainment
    echo -n "."
end


echo -n " looking harder "
    
foreach place ( \$places )
    if(! -e \$place) continue

    if("\$place" == "/") echo -n "hmm."
	
    # use find to get candidate files
    set files = \`find \$place -name '*'\$program'*' -follow -perm -1 -print |& nawk '! /^find:/' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} lL{exit}'\`
    foreach file ( \$files )
	# skip filenames we know are wrong
	if("\$file" =~ *\$badname) continue
	
	# make sure it's executable
	test -x \$file
	if(\$status) continue

	# test for program function
	rm -f \${tempfile}.o >& /dev/null
	cat \${tempfile}.inp | \$file >& /dev/null
	if(! -e "\${tempfile}.o") continue
    
	# check output file
	grep -l "SKEL_ATOM_XYZ" \${tempfile}.o >& /dev/null
	if(\$status) continue
	
	# made it this far, \$file must work...
	set program = "\$file"
	goto End_BONES_search
    end
    
    # entertainment
    echo -n "."
    
    # give up if this is taking too long (10 minutes)
    set NOW = \`date "+%S %M %H %j %Y" |& nawk '{\$5-=1; printf "%50.0f\\n", \$1+ 60*(\$2+ 60*(\$3+ 24*(\$4 + 365 *\$5 + int(\$5/4) -int(\$5/100) +int(\$5/400) )))}'\`
    set temp = \`echo "\$NOW \$THEN" | nawk '{printf "%d", \$1 - \$2}'\`
    if(\$temp > 600) then
	echo " this is taking too long."
	goto End_BONES_search
    endif	
end

End_BONES_search:
onintr

# check if we found any program
test -x "\$program"
if(! \$status) then
    # got something, make sure it works
    set file = \$program
    rm -f \${tempfile}.o >& /dev/null
    cat \${tempfile}.inp | \$file >& /dev/null
    if(-e "\${tempfile}.o") then
	# check output file
	grep -l "SKEL_ATOM_XYZ" \${tempfile}.o >& /dev/null
	if(! \$status) then
	    set BONES = "\$file"
	endif
    endif
endif
# clean up (regardless)
rm -f \${tempfile}.map >& /dev/null
rm -f \${tempfile}.inp >& /dev/null
rm -f \${tempfile}.o >& /dev/null



# out of ideas, help?
test -x "\$BONES"
if(! \$status) then
    echo ""
    if(\$?HARD_TO_FIND) echo "found \$BONES"
else
    echo ""
    echo "Couldn't find \${program}, looked everywhere."
    set BONES = "bones"
endif
unset HARD_TO_FIND





















find_shelx:
# first, do we HAVE to find shelx?
if((! \$?FIND_SITES)||(\$?NO_SHELX)) then
    set SHELX = shelxs
    goto Return_FindProgs
endif

set program = "\$SHELX"
set names = "shelxs shelx"
set places = "/programs/shelx /programs/bin /programs /usr/local/shelx /usr/local/bin /usr/local /usr/xtal"
set size    = 100000

# first, check to see if default will work
test -x \$program
if(! \$status) then
    set file = \`ls -lnL \$program |& nawk -v size=\$size '\$5>size{print \$NF}'\`
    # test for program signature (author and version number)
    set temp = \`\$file \$\$ |& nawk '/CANNOT OPEN FILE/{print \$NF}' | grep "\$\$.ins" | tail -1\`
    if("\$temp" != "") then
	set program = "\$file"
    endif
endif


# try using the "which" command
foreach name ( \$names )
    # check for success
    test -x \$program
    if(! \$status) break
    
    # which should handle processing of \$path
    set possibilities = \`which \$name |& nawk 'NF==1' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l size {print \$NF}' |& nawk -v L=\$MAXLINE '{l+=length(\$0)} l 600) then
	    echo " this is taking too long."
	    break;
	endif	
    end
endif

Skip_SHELX_search:
onintr

# check if we found any program
test -x "\$program"
if(! \$status) then
    # got something, make sure it works
    set file = \$program
    set temp = \`\$file \$\$ |& nawk '/CANNOT OPEN FILE/{print \$NF}' | grep "\$\$.ins" | tail -1\`
    if("\$temp" != "") then
	set SHELX = \$program
    else
	# this shouldn't happen, but...
#	set SHELX = ""
    endif
else
#    set SHELX = ""
endif

#set SHELX = "shelxs"

# out of ideas, help?
test -x "\$SHELX"
if(! \$status) then
    echo "found \$SHELX"
else
    echo ""
    echo "Couldn't find shelxs, looked everywhere."
endif


goto Return_FindProgs






















FindSites:
################################################################################

 ######     #    #    #  #####            ####      #     #####  ######   ####
 #          #    ##   #  #    #          #          #       #    #       #
 #####      #    # #  #  #    #           ####      #       #    #####    ####
 #          #    #  # #  #    #               #     #       #    #            #
 #          #    #   ##  #    #          #    #     #       #    #       #    #
 #          #    #    #  #####            ####      #       #    ######   ####

################################################################################
#   Run various site-finding programs
#
#   needs \${tempfile}mtzdmp
################################################################################

# don't loop forever
if(\$?LOOKED_FOR_SITES) then
    echo "Guess those sites we found were no good... ;("
    echo ""
    echo "We suggest solve as a good third-party program for doing this:"
    echo "http://www.solve.lanl.gov/"
    echo "Good luck! "
    set BAD
    goto done
endif
set LOOKED_FOR_SITES
unset FIND_SITES

# check for info on mtz file
if(! -e \${tempfile}mtzdmp) then
    # uhh, do a half-assed regeneration of this file
    echo "go" | mtzdump HKLIN \$mtzfile |&\\
    nawk 'NF>6{if(\$(NF-1)=="D"){\\
       D=\$NF; m=\$(NF-4); getline; s=\$(NF-4); if(s+0==0) s=1; \\
       print "D:", D, \$NF, m/s;}}' >&! \${tempfile}mtzdmp
endif

# make the best Patterson we can:
if(-e \${tempfile}EXCLUDE) then
    set temp = \`nawk '\$2=="DANO"{print 1.5*\$3}' \${tempfile}EXCLUDE | sort -n | tail -1\`
    if("\$temp" != "") set max_dano = "\$temp"
    set max_diso = \`nawk '\$2=="DISO"{print 1.5*\$3}' \${tempfile}EXCLUDE | sort -n | tail -1\`
    if("\$temp" != "") set max_diso = "\$temp"
endif
if(! \$?max_diso) set max_diso
if(! \$?max_dano) set max_dano

# reduce resolution a little? (80% volume)
set pattRES = \`echo "\$hiRES" | nawk '\$1+0>0.1{printf "%.2f", (0.8*1/(\$1^3))^(-1/3)}'\`

if(! -e "\${scriptDIR}bestFH.com") then
    # this should NEVER happen! 
    echo "ERROR! our \${scriptDIR}bestFH.com is missing! "
    echo "       what have you done with it? "
    goto Setup_scripts
endif
# run the packaged Matthews Patterson script
\${scriptDIR}bestFH.com \$mtzfile \${pattRES}A dano \$max_dano diso \$max_diso |\\
nawk '\$1=="./FH.mtz"{\$0="mtz" substr(\$0,2)} \$1=="./FH_Patt.map"{\$0="maps" substr(\$0,2)}  {print}'
rm -f wFH_Patt.map >& /dev/null
mv FH_Patt.map \${mapDIR} >& /dev/null
mv FH.mtz \${mtzDIR}      >& /dev/null
mv fh.hkl \${mtzDIR}      >& /dev/null
mv bestFH.log \${logDIR} >& /dev/null
echo ""


# try SHELX first, it's fastest, if it works

goto run_shelx

exit











run_shelx:
################################################################################

 #####   #    #  #    #           ####   #    #  ######  #       #    #
 #    #  #    #  ##   #          #       #    #  #       #        #  #
 #    #  #    #  # #  #           ####   ######  #####   #         ##
 #####   #    #  #  # #               #  #    #  #       #         ##
 #   #   #    #  #   ##          #    #  #    #  #       #        #  #
 #    #   ####   #    #           ####   #    #  ######  ######  #    #

################################################################################
#   Run SHELX
################################################################################


# first, we have to FIND shelx! 
test -x "\$SHELX"
if(\$status) then
    echo "shelxs is unavailable."
    echo ""
    
    # go to Plan B:
    goto run_rantan
endif




# try a range of sites if we don't know how many
set target_sites = "1 sites 3 sites 5 sites 10 sites 15 sites 20 site"
if(\$?user_sites) then
    set target_sites = "\$user_sites sites"
endif
# try a range of resolutions too
#   highest  frac_last   steps
set shells = \`echo "\$pattRES 0.1 5" | nawk '\$1+0>0{for(r=\$2;r<=1;r+=(1-\$2)/\$3){printf "%.2fA ", (r*1/(\$1^3))^(-1/3)}}'\`

# take steps to speed things up
if(\$?HURRY_UP) then
    set shells = \`echo "\$pattRES 0.1 2" | nawk '\$1+0>0{for(r=\$2;r<=1;r+=(1-\$2)/\$3){printf "%.2fA ", (r*1/(\$1^3))^(-1/3)}}'\`
endif

set FHmtz = \${mtzDIR}FH.mtz
if(! -e "\$FHmtz") then
    # this should always exist
    set FHmtz = \$mtzfile
endif

if(! -e "\${scriptDIR}shelx.com") then
    # this should NEVER happen! 
    echo "ERROR! our \${scriptDIR}shelx.com is missing! "
    echo "       what have you done with it? "
    goto Setup_scripts
endif
# run the combinatorial shelx script
echo ""
echo "running \${scriptDIR}shelx.com \${FHmtz} \$allSGs \$shells \$target_sites"
onintr After_shelx
\${scriptDIR}shelx.com \${FHmtz} \$allSGs \$shells \$target_sites
After_shelx:
onintr
mv shelx.log \${logDIR} >& /dev/null
# clear out any temporary files?
rm -f shelx_temp* >& /dev/null
rm -f shelx.inp shelx.lst >& /dev/null

# filter the result for shelx-approved atoms
cat ./shelx.pdb |\\
nawk '/^ATOM/ && \$5 == "D" && substr(\$0, 55, 6)+0>0 {print}  ! /^ATOM/{print}' |\\
cat >! \${tempfile}.pdb

# check that we got something? 
set sites = \`nawk '/^ATOM/' \${tempfile}.pdb | wc -l\`
if("\$sites" == "0") then
    # huh...
    rm -f \${tempfile}.pdb >& /dev/null
    echo "shelx failed..."
    goto run_rantan
endif

# we got some sites
set site_cell = \`nawk '\$1 ~ /^CRYST/{printf "%.3f %.3f %.3f %.3f %.3f %.3f\\n", \$2,\$3,\$4,\$5,\$6,\$7;exit}' ./shelx.pdb\`
coordconv XYZIN \${tempfile}.pdb XYZOUT \${tempfile}.xyz << eof-pdb >& /dev/null
INPUT PDB
CELL \$site_cell
OUTPUT FRAC
END
eof-pdb
# make sure we don't use occ or B-factor (they are sigma heights)
cat \${tempfile}.xyz |\\
nawk '{++i; printf " ATOM%-3d ANO  %6.3f %6.3f %6.3f ?.??? ?.??? BFAC ?.???\\n",\\
i, \$2, \$3, \$4}' >! \$coordfile
set params = 2

# make sure we use the same SG that was used to run SHELX
set newSG = \`nawk '/results here are from/{getline; print \$NF}' ./shelx.pdb\`
# re-define otherSG latter?


# clean up
rm -f \${tempfile}.xyz >& /dev/null
rm -f \${tempfile}.pdb >& /dev/null

# now return to site handler
set sitefile = ./shelx.pdb
echo "using \$sites sites in \$sitefile"
goto GotSites
exit



run_rantan:
################################################################################

 #####   #    #  #    #          #####     ##    #    #   #####    ##    #    #
 #    #  #    #  ##   #          #    #   #  #   ##   #     #     #  #   ##   #
 #    #  #    #  # #  #          #    #  #    #  # #  #     #    #    #  # #  #
 #####   #    #  #  # #          #####   ######  #  # #     #    ######  #  # #
 #   #   #    #  #   ##          #   #   #    #  #   ##     #    #    #  #   ##
 #    #   ####   #    #          #    #  #    #  #    #     #    #    #  #    #

################################################################################
#   Run RANTAN,  CCP4's direct-methods program
################################################################################

# try a range of sites if we don't know how many
set target_sites = ""
if(\$?user_sites) then
    set target_sites = "\$user_sites sites"
endif
# try a range of resolutions too
set shells = \`echo "\$pattRES 0.1 5" | nawk '\$1+0>0{for(r=\$2;r<=1;r+=(1-\$2)/\$3){printf "%.3fA ", (r*1/(\$1^3))^(-1/3)}}'\`

set FHmtz = \${mtzDIR}FH.mtz
if(! -e "\$FHmtz") then
    # this should always exist
    set FHmtz = \$mtzfile
endif

if(! -e "\${scriptDIR}rantan.com") then
    # this should NEVER happen! 
    echo "ERROR! our \${scriptDIR}rantan.com is missing! "
    echo "       what have you done with it? "
    goto Setup_scripts
endif
# run the combinatorial rantan script
echo ""
echo "running \${scriptDIR}rantan.com \${FHmtz} \$allSGs \$shells \$target_sites"
onintr After_rantan
\${scriptDIR}rantan.com \${FHmtz} \$allSGs \$shells \$target_sites
After_rantan:
onintr
mv rantan.log \${logDIR} >& /dev/null
rm -f rantan_temp* >& /dev/null

# filter for non-zero occupancies
cat ./rantan.pdb |\\
nawk '/^ATOM/ && \$5 != "X" && substr(\$0, 55, 6)+0>0 {print}  ! /^ATOM/{print}' |\\
cat >! \${tempfile}.pdb

# check that we got something?
set sites = \`nawk '/^ATOM/' \${tempfile}.pdb | wc -l\`
if("\$sites" == "0") then
    echo "rantan failed..."
    rm -f \${tempfile}.pdb >& /dev/null
    goto run_rsps
endif


# we got some sites
set site_cell = \`nawk '\$1 ~ /^CRYST/{printf "%.3f %.3f %.3f %.3f %.3f %.3f\\n", \$2,\$3,\$4,\$5,\$6,\$7;exit}' ./rantan.pdb\`
coordconv XYZIN \${tempfile}.pdb XYZOUT \${tempfile}.xyz << eof-pdb >& /dev/null
INPUT PDB
CELL \$site_cell
OUTPUT FRAC
END
eof-pdb
# make sure we don't use occ or B-factor (they are sigma heights)
cat \${tempfile}.xyz |\\
nawk '{++i; printf " ATOM%-3d ANO  %6.3f %6.3f %6.3f ?.??? ?.??? BFAC ?.???\\n",\\
i, \$2, \$3, \$4}' >! \$coordfile
set params = 2

# clean up
rm -f \${tempfile}.xyz >& /dev/null
rm -f \${tempfile}.pdb >& /dev/null

# now return to site handler
set sitefile = ./rantan.pdb
echo "using \$sites sites in \$sitefile"
goto GotSites
exit



run_rsps:
################################################################################

 #####   #    #  #    #          #####    ####   #####    ####
 #    #  #    #  ##   #          #    #  #       #    #  #
 #    #  #    #  # #  #          #    #   ####   #    #   ####
 #####   #    #  #  # #          #####        #  #####        #
 #   #   #    #  #   ##          #   #   #    #  #       #    #
 #    #   ####   #    #          #    #   ####   #        ####

################################################################################
#   Run Real-Space Patterson Search
################################################################################

if(! -e "./\${scriptDIR}rrsps.com") then
    # this should NEVER happen! 
    echo "ERROR! our \${scriptDIR}rrsps.com is missing! "
    echo "       what have you done with it? "
    goto Setup_scripts
endif

echo ""
echo "running a recursive Real-Space Patterson Search. "

# do this in more than one SG? 

# use the old Patterson map
\${scriptDIR}rrsps.com \${mapDIR}FH_Patt.map \$allSGs

# now convert the output file to something Phaser can read
nawk 'NF==1,/roduct/' rrsps.sites_\$SG |\\
nawk '\$2 ~ /[01].[0-9][0-9]/{++i; \\
  printf(" ATOM%-3d ANO  %6.3f %6.3f %6.3f   ?.???  ?.??? BFAC   ?.???\\n",\\
  i, \$2,\$3,\$4)}' >! \$coordfile

set sitefile = rrsps.sites_\$SG

# incorperate these sites into the script
echo "using \$sites sites in \$sitefile"
goto GotSites
exit






















read_inscript:
################################################################################################################

 #####   ######    ##    #####          ####    ####   #####      #    #####    #####
 #    #  #        #  #   #    #        #       #    #  #    #     #    #    #     #
 #    #  #####   #    #  #    #         ####   #       #    #     #    #    #     #
 #####   #       ######  #    #             #  #       #####      #    #####      #
 #   #   #       #    #  #    #        #    #  #    #  #   #      #    #          #
 #    #  ######  #    #  #####          ####    ####   #    #     #    #          #

################################################################################################################
#   initialize variables from a pre-written mlphare script
################################################################################################################
grep "ATOM" "\$inscript" >& /dev/null
if(\$status) then
    echo "WARNING: no atoms in \$inscript"
    set inscript = ""
    goto GetSites
endif
echo "imitating script: \$inscript " 


# transform atoms into rereadable file
nawk '\$1 ~ /DERIV/,/END/{print}' \$inscript >! \${tempfile}atoms
set temp = \`cat \${tempfile}atoms | wc -l\`
if(\$temp == 0) then
    # maybe just no DERIV cards? 
    nawk '\$1 ~ /^ATOM/' \$inscript >! \${tempfile}atoms
endif
cat \${tempfile}atoms |\\
nawk '\$1 ~ /^ATOM/ {while(/[0-9]-/ && safe < 20){\\
      # insert spaces between numbers that are obviously stuck together \\
      stuck=match(\$0,/[0-9]-/); \\
      \$0 = substr(\$0,1,stuck) " " substr(\$0, stuck+1);++safe}}\\
      {print}' |\\
nawk '\$1 ~ /^ATOM/ {for(i=1;i<=NF;++i){test=\$i;\\
      if(gsub("[\\.]", ".", test)>1){\\
      # more than one decimal in a number, assume 3 decimal places \\
      stuck=match(\$i,/[\\.]/)+3; \\
      \$i = substr(\$i,1,stuck) " " substr(\$i, stuck+1);++safe}}}\\
      {print}' |\\
nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
nawk '! /END/{print}' >! \${coordfile}
rm -f \${tempfile}atoms >& /dev/null
    
# \$coordfile now contains a filtered version of these sites
# so this script will be imitated
    
# retrieve "BAD" atom list (to ignore in atom finding)
nawk '\$1 ~ /^BADATOM/ || \$1 ~ /^OLDATOM/' \$inscript >! \${tempfile}badatoms
set temp = \`cat \${tempfile}badatoms | wc -l\`
if(\$temp == 0) then
    rm -f \${tempfile}badatoms >& /dev/null
else
    echo "found \$temp previously-tried atom records in \$inscript"
    if(\$?MORE_SITES) echo "these sites will be avoided in atom-finding."
endif
    
# check for valid atoms
grep ATOM \${coordfile} >& /dev/null
if(\$status) then
    echo "WARNING: no mlphare atoms found in \$inscript ... "
    set inscript = ""
    rm -f \${coordfile} >& /dev/null
    goto GetSites
endif
goto GotSites
exit
















read_inlog:
################################################################################################################

 #####   ######    ##    #####           #        ####    ####
 #    #  #        #  #   #    #          #       #    #  #    #
 #    #  #####   #    #  #    #          #       #    #  #
 #####   #       ######  #    #          #       #    #  #  ###
 #   #   #       #    #  #    #          #       #    #  #    #
 #    #  ######  #    #  #####           ######   ####    ####

################################################################################################################
#   Read in a user-specified MLphare logfile
################################################################################################################

grep "ATOM" "\$inlogfile" >& /dev/null
if(\$status) then
    echo "WARNING: no atoms in \$inlogfile"
    set inlogfile = ""
    goto GetSites
endif

echo "imitating run that produced \$inlogfile"

# transform log-file output into appropriate atom entries 
# (with full refinement cards)
cat \$inlogfile |\\
nawk '\$1~/^DERIV/,\$1~/^MLPHARE/{print}'|\\
nawk '\$1 ~ /^ATOM/ {while(/\\.[0-9][0-9][0-9][0-9-]/ && safe < 20){\\
      # insert spaces between numbers that are stuck together \\
      stuck=match(\$0,/\\.[0-9][0-9][0-9][0-9-]/)+3; \\
      \$0 = substr(\$0,1,stuck) " " substr(\$0, stuck+1);++safe}}\\
      {print}' |\\
nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
nawk '! /MLPHARE/ && ! /SUMMARY/{print}' >! \${coordfile}

# check for valid atoms
grep ATOM \${coordfile} >& /dev/null
if(\$status) then
    echo "WARNING: no atoms found in \${inlogfile} ."
    rm -f \${coordfile}
    set inlogfile = ""
    goto GetSites
endif

# make sure coordfile goes atom ano x y z o ao BFAC b
cat \${coordfile} |\\
nawk '\$1~/^ATOM/ && \$7=="BFAC"{\$7="0.000 BFAC"} {print}' |\\
cat >! \${tempfile}
mv \$tempfile \$coordfile

goto GotSites
exit














read_shelx:
################################################################################

 #####   ######    ##    #####            ####   #    #  ######  #       #    #
 #    #  #        #  #   #    #          #       #    #  #       #        #  #
 #    #  #####   #    #  #    #           ####   ######  #####   #         ##
 #####   #       ######  #    #               #  #    #  #       #         ##
 #   #   #       #    #  #    #          #    #  #    #  #       #        #  #
 #    #  ######  #    #  #####            ####   #    #  ######  ######  #    #

################################################################################
#   Read in a SHELX atom file
################################################################################

if(! -e "\$shelxfile") then
    echo "ERROR: \$shelxfile does not exist! "
    set shelxfile = ""
    goto GetSites
endif

#echo "getting atoms from \$shelxfile ..."

# now write out these coordinates in an MLphare-readable format
cat \$shelxfile |\\
nawk 'p && NF>=5 && \$2 ~ /[0-9]\$/ {print} \\
      /^PLAN/ || \$2=="Atom"{p=1} /Reflections read/{p=0}' |\\
nawk 'substr(\$0,1,8)=="        "{\$0 = "1" \$0} {print}' |\\
nawk '\$1 !~ /^Q/ && \$2 !~ /^Q/' |\\
nawk '{\\
# "jiggle" special positions \\
if(\$6 !~ /\\.0/){\$3+=0.001; \$4+=0.001; \$5+=0.001}\\
++i; printf(" ATOM%-3d ANO  %6.3f %6.3f %6.3f   ?.???  ?.??? BFAC   ?.???\\n",\\
i, \$3,\$4,\$5) }' |\\
cat >! \$coordfile

set sites = \`cat \$coordfile | wc -l\`
if("\$sites" == 0) then
    echo "ERROR: no atoms found in \${shelxfile}! "
    
    rm -f \$coordfile >& /dev/null
    set shelxfile = ""
    goto GetSites
endif

# definitely want to refine these occupancies first! 
set params = 2

# get unit cell (so we can tell if sites are permuted)
set site_cell = \`nawk '\$1 == "CELL"{printf "%.3f %.3f %.3f %.3f %.3f %.3f\\n", \$3,\$4,\$5,\$6,\$7,\$8;exit}' \${shelxfile}\`
if(\$#site_cell == 6) then
    if("\$SG" =~ [pPcC][21][21][21]*) then
	echo "SHELX Cell: \$site_cell"
    endif
else
    echo ""
    echo "WARNING: no unit cell in \$shelxfile. "
    echo "we will use \$CELL"
    echo ""
    set site_cell = "\$CELL"
endif

# \$coordfile now contains the SHELX sites in mlphare format

echo "got \$sites atoms from \$shelxfile"
goto GotSites
exit






read_pdb:
################################################################################

 #####   ######    ##    #####           #####   #####   #####
 #    #  #        #  #   #    #          #    #  #    #  #    #
 #    #  #####   #    #  #    #          #    #  #    #  #####
 #####   #       ######  #    #          #####   #    #  #    #
 #   #   #       #    #  #    #          #       #    #  #    #
 #    #  ######  #    #  #####           #       #####   #####

################################################################################
#   Read in metal atoms given in standard PDB format
################################################################################
#echo "getting atom coordinates from \$pdbfile"

# get unit cell (so we can tell if sites are permuted)
set site_cell = \`nawk '\$1 ~ /^CRYST/{printf "%.3f %.3f %.3f %.3f %.3f %.3f\\n", \$2,\$3,\$4,\$5,\$6,\$7;exit}' \$pdbfile\`
if(\$#site_cell == 6) then
    if("\$SG" =~ [pPcC][21][21][21]*) echo "pdb cell: \$site_cell"
else
    echo ""
    echo "WARNING: no unit cell in \$pdbfile. "
    echo "we will use \$CELL"
    echo ""
    set site_cell = "\$CELL"
endif

# try converting file
echo "CELL \$site_cell" | pdbset XYZIN \$pdbfile XYZOUT \${tempfile}.pdb >&! \${tempfile}.log
egrep "^CRYS|^SCALE" \${tempfile}.pdb >! \${tempfile}cannon.pdb
egrep "^ATOM|^HETATM" \$pdbfile >> \${tempfile}cannon.pdb
echo "END" >> \${tempfile}cannon.pdb
echo "CELL \$site_cell" | pdbset XYZIN \${tempfile}cannon.pdb XYZOUT \${tempfile}.pdb >&! \${tempfile}.log
rm -f \${tempfile}cannon.pdb >& /dev/null
coordconv XYZIN \${tempfile}.pdb XYZOUT \${tempfile}.xyz << eof-pdb >&! \${tempfile}.log
INPUT PDB ORTH 1
CELL \$site_cell
OUTPUT FRAC
END
eof-pdb
if(\$status) then
    rm -f \${tempfile}.xyz >& /dev/null
endif
rm -f \${tempfile}.pdb >& /dev/null
if(! -e \${tempfile}.xyz) then
    echo ""
    echo "error from coordconv"
    mv \${tempfile}.log Phaser.coordconv.log >& /dev/null
    nawk 'toupper(\$0) ~ /ERROR/{print;getline;print;getline;print}' Phaser.coordconv.log
    echo ""
    echo "please examine Phaser.coordconv.log"
    echo "to see what went wrong, and"
    echo "check \$pdbfile for errors."
    echo ""
    rm -f \$coordfile >& /dev/null
    set pdbfile = ""
    goto GetSites
endif

# now convert the coordinates to MLphare format
cat \${tempfile}.xyz |\\
nawk '{print \$2,\$3,\$4,substr(\$0,46)+0,substr(\$0,36)+0}' |\\
nawk '\$4+0>0{++i; printf " ATOM%-3d ANO  %6.3f %6.3f %6.3f %6.3f %6.3f BFAC %8.3f\\n",\\
i, \$1, \$2, \$3, \$4, \$4, \$5}' >! \$coordfile

if(\$?NEGATIVE_OCC) then
    nawk '{\$6=-\$6; print}' \$coordfile >! \${tempfile}
    mv \${tempfile} \$coordfile >& /dev/null
endif


set sites = \`cat \$coordfile | wc -l\`
if("\$sites" == 0) then
    echo "ERROR: no atoms found in \${pdbfile}! "
    rm -f \$coordfile >& /dev/null
    set pdbfile = ""
    goto GetSites
endif
if("\$sites" > 100) then
    echo "ERROR: way too many atoms found in \${pdbfile}! "
    echo "MLphare is for refining METAL sites! "
    rm -f \$coordfile >& /dev/null
    set pdbfile = ""
    goto GetSites
endif

# clean up
rm -f \${tempfile}.xyz >& /dev/null
rm -f \${tempfile}.log >& /dev/null

# probaby best to refine these occupancies first
set params = 2

# \$coordfile now contains the PDB sites in mlphare format

echo "got \$sites atoms from \$pdbfile"

set sitefile = "\$pdbfile"
goto GotSites

exit


read_solve:
################################################################################

 #####   ######    ##    #####            ####    ####   #       #    #  ######
 #    #  #        #  #   #    #          #       #    #  #       #    #  #
 #    #  #####   #    #  #    #           ####   #    #  #       #    #  #####
 #####   #       ######  #    #               #  #    #  #       #    #  #
 #   #   #       #    #  #    #          #    #  #    #  #        #  #   #
 #    #  ######  #    #  #####            ####    ####   ######    ##    ######

################################################################################
#   Read in metal atoms given in solve.status file
################################################################################
#echo "getting atom coordinates from \$solvefile"

# solve occupancies are not on electron scale
set params = 2

# convert LAST set of coordinates to MLphare format
cat \$solvefile |\\
nawk '/TOP SOLUTION FOUND BY SOLVE/{\\
while(\$1 != "TIME")\\
{status=getline; if((NF!=0)&&(\$1 != "TIME")) print; if(! status) break}}' |\\
nawk '/OCC/{for(i in site){site[i]=""}; n=0}\\
    /[0-9]/{++n; site[n]= \$0}\\
        END{for(i=1;i<=n;++i){print site[i]}}' |\\
nawk '{++i; printf " ATOM%-3d ANO  %6.3f %6.3f %6.3f %6.3f %6.3f BFAC %8.3f\\n",\\
i, \$(NF-5), \$(NF-4), \$(NF-3), \$(NF-2), \$(NF-2), \$(NF-1)}' >! \$coordfile

set sites = \`cat \$coordfile | wc -l\`
if("\$sites" == 0) then
    echo "ERROR: no atoms found in \${solvefile}! "
    rm -f \$coordfile >& /dev/null
    set solvefile = ""
    goto GetSites
endif

# try to get unit cell (so we can tell if sites are permuted)
set dir = \`dirname \$solvefile\`
foreach file ( \`ls -ln \$dir | sort -n -k5 | nawk '/^-/ && /solve/ && mass<5000000 && len<900{print \$NF; mass+=\$5; len +=length(\$NF)+1}'\` )
    grep -l CELL \${dir}/\$file >& /dev/null
    if(! \$status) then
	set site_cell = \`nawk '\$1 == "CELL"{printf "%.3f %.3f %.3f %.3f %.3f %.3f\\n", \$2,\$3,\$4,\$5,\$6,\$7;exit}' \${dir}/\$file | nawk '! /[^0-9 \\.]/ && NF'\`
	
	# make sure we got it
	if(\$#site_cell == 6) then
	    echo "retrieved SOLVE cell: \$site_cell"
	    echo "from: \${dir}/\$file"
	    break
	endif
	# keep looking
    endif
end
if(\$#site_cell != 6) then
    echo ""
    echo "WARNING: unable to obtain unit cell for \$solvefile. "
    echo "we will assume \$CELL"
    echo ""
    set site_cell = "\$CELL"
endif


# \$coordfile now contains the SOLVE sites in mlphare format

echo "got \$sites atoms from \$solvefile"
goto GotSites
exit







read_general:
################################################################################

 #####   ######    ##    #####            ####   ######  #    #  ######  #####
 #    #  #        #  #   #    #          #    #  #       ##   #  #       #    #
 #    #  #####   #    #  #    #          #       #####   # #  #  #####   #    #
 #####   #       ######  #    #          #  ###  #       #  # #  #       #####
 #   #   #       #    #  #    #          #    #  #       #   ##  #       #   #
 #    #  ######  #    #  #####            ####   ######  #    #  ######  #    #

################################################################################
#   Read in metal atoms given in solve.status file
################################################################################
if(! -e "\$sitefile") then
    echo "ERROR: \$sitefile does not exits! "
    set sitefile = ""
    goto GetSites
endif
    
if(! -e "\${tempfile}sitereader.awk") then
    echo "ERROR: \${tempfile}sitereader.awk is missing! "
    echo "       unable to read \$sitefile"
    set sitefile = ""
    goto GetSites
endif

# search for consecutive triplets of 3-decimal numbers between -1.1 and 1.1
nawk -f \${tempfile}sitereader.awk "\$sitefile" >! \${tempfile}sites

set sites = \`cat \${tempfile}sites | wc -l\`
if("\$sites" == 0) then
    echo "ERROR: no atoms found in \${sitefile}! "
    rm -f \${tempfile}sites >& /dev/null
    set sitefile = ""
    goto GetSites
endif

echo "found \$sites sites in \$sitefile"
mv \${tempfile}sites \$coordfile

# best refine occupancies first
set params = 2
	
# see if we can get a cell too
cat "\$sitefile" |\\
nawk 'toupper(\$1) == "CELL" && NF>=7{n=0\\
    for(i=1;i<=NF;++i){\\
      if(\$i+0>5 && \$i+0==\$i){cell = cell " " \$i;++n};\\
      if(n==6){print cell; exit}}}' |\\
cat >! \${tempfile}cell
set site_cell = \`cat \${tempfile}cell\`
rm -f \${tempfile}cell >& /dev/null

if((\$#site_cell != 6)&&("\$SG" =~ [pPcC]2[21][21]*)) then
    echo ""
    echo "WARNING: no unit cell in \$sitefile. "
    echo "we will use \$CELL"
    echo ""
    set site_cell = "\$CELL"
endif
goto GotSites
exit

















flatten:
################################################################################################################

######  #     #
#     # ##   ##
#     # # # # #
#     # #  #  #
#     # #     #
#     # #     #
######  #     #

################################################################################################################
#	Solvent flatten with DM
################################################################################################################
# clear "best yet" flag (we are about to find out)
unset BEST_YET

set flatten_this = \${mtzDIR}mlphare.mtz

# run OASIS here?
#if(\$?SAD) then
if(0) then
    echo "running \${scriptDIR}oasis.com on mlphare sites"
    \${scriptDIR}oasis.com \$scriptfile >! \${logDIR}oasis.log
    if(! \$status) then
	mv oasised.mtz \${mtzDIR} >& /dev/null
	set flatten_this = \${mtzDIR}oasised.mtz
    else
	echo "failed! "
	echo "we will use \${flatten_this} instead"
    endif
endif

if(! -e "\${scriptDIR}dm.com") then
    echo "dm is not available."
    set NO_DM
endif
if(\$?NO_DM) then
    # see if this FOM is better than the best so far
    set temp = \`echo "\$FOM \$bestFOM" | nawk '\$1+0>\$2+0{print \$1} \$1+0<\$2+0{print \$2}'\`
    if("\$temp" != "\$bestFOM") then
	# new winner
	set bestFOM = "\$FOM"

	# remember all the conditions used to make this MTZ
	set bestDMtrial = "0% \$Cycle \$SG \$FOM \${mtzDIR}mlphare\${FLIP_label}.mtz"
	set BEST_YET	
    else
#	echo "\$scriptfile seems inferior to \${scriptfile}.best"
    endif
    
    # skip over DM
    set mapmtz = \${mtzDIR}mlphare.mtz
    goto FFT
endif

################################################
if(! \$?bestrial) then
    # initialize global scorekeepers
    set bestrial = "0"
    set bestDMscore = "999999"
endif
# "local" scorekeeper
set bestMAPscore = 999999

# make up a list of solvent contents to try
set trials = "\$default_trials"

# user preference overrides default trials
if("\$SOLVENT" != "") then
    set trials = "\$SOLVENT"
endif

set trials = \`echo "\$trials"\`
set temp = \`echo "\$trials" | nawk '{for(i=1;i1{print "and"} {print \$NF"%"}'\`
echo "running \${scriptDIR}dm.com with \$temp solvent for auto cycles each"

foreach trial ( \$trials )
    
    # should all be 2-characters wide
    echo -n "\${trial}% : "
    
    # here is where we actually run the dm script
    \${scriptDIR}dm.com \${trial}% \${flatten_this} >! \${logDIR}dm_\${trial}.log
    if((\$status)||(! -e dmed.mtz)) then
	echo "DM crashed! "
	# keep going...
	continue
    endif
    
    # save the MTZ
    mv dmed.mtz \${mtzDIR}dm_\${trial}.mtz
    rm -f solvent.map >& /dev/null
    
    # print out the free residual
    cat \${logDIR}dm_\${trial}.log |\\
    nawk '/Cycle_number  Free_R_factor/{getline; getline; \\
	  while(NF==3){print; getline}}'  |\\
    nawk 'BEGIN{min=10} \\
	  \$3 0 {min = \$3; bstep=NR} \\
	  \$2 0 {min = \$2; bstep=NR} \\
	  END{if(bstep+0!=0){print min, bstep, NR}}'  |\\
    cat >! \${tempfile}R_dm
    
    # get FOMDM too
    echo "go" | mtzdump hklin \${mtzDIR}dm_\${trial}.mtz | nawk 'NF>5' |\\
     nawk '\$NF=="FOMDM" && \$(NF-1)=="W" {FOM=\$(NF-4)} END{print FOM+0}' |\\
    cat >! \${tempfile}FOMDM

    # now retrieve the "DM residual"
    set R_dm = \`nawk '\$1+0>0{printf "%d", \$1*1000}' \${tempfile}R_dm\`
    set FOMDM = \`cat \${tempfile}FOMDM\`
    rm -f \${tempfile}FOMDM >& /dev/null
    
    # decide on how to score these?
    set DMscore = ""
    # use real-space residual as a "score"
    #set DMscore = "R_dm"
    
    if("\$DMscore" == "") then
	# user edited the script?
	
	# print it out for user to see
	echo "\$FOMDM" | nawk '{printf "FOMDM = %5.3f\\n", \$1}'
	
	set DMscore = \`echo "\$FOMDM" | nawk '\$1+0>0{printf "%d", 1000/\$1}'\`
	if("\$DMscore" == "") then
	    # must have just crashed
	    set DMscore = \`echo \$trial | nawk '{printf "%d", sqrt((\$1-50)^2)*1000}'\`
	endif	
    else
	# print it out for user to see
	nawk 'NF==3{printf "R_dm = %5.3f ( %d/%d )\\n", \$1, \$2, \$3}' \${tempfile}R_dm
    endif
    rm -f \${tempfile}R_dm >& /dev/null
    
    if(\$DMscore < \$bestDMscore) then
	# we have a new, overall winner!
	set bestDMscore = "\$DMscore"
	
	# remember all the conditions used to make this MTZ
	set bestDMtrial = "\${trial}% \$Cycle \$SG \$FOM \${mtzDIR}dm_\${trial}.mtz"
	set BEST_YET
    endif
    # check for "local" winner
    if(\$DMscore < \$bestMAPscore) then
	# update mtz file to use for the map this round
	set bestMAPscore = \$DMscore
	set mapmtz = \${mtzDIR}dm_\${trial}.mtz
    endif
end

goto FFT


FFT:
# make a map
\${scriptDIR}fft.com \$mapmtz >! \${logDIR}fftphase.log
if(\$status) then
    echo "WARNING: map generation failed! "
    rm -f ffted.map >& /dev/null
    goto Best_not_Best
endif

# look at largest fragment from bones trace (pretty good indicator of correctness)
set big_bone = \`nawk '/Maximum fragment/{print \$NF}' \${logDIR}fftphase.log\`
if("\$big_bone" != "") then
    if("\$big_bone" > "\$biggest_bone") then
	# call this the best mtz?
	set biggest_bone = "\$big_bone"
#	set BEST_YET
    else
	# cancel DM score
#	if("\$biggest_bone" > 0) unset BEST_YET
    endif
endif

# move all the files produced by fft.com to unique names (probably temporary)
if(-e fftpick.pdb) mv fftpick.pdb \${oDIR}pick.pdb
if(-e bones.o)     mv bones.o     \${oDIR}bones.o
if(-e ffted.map)   mv ffted.map   \${mapDIR}phased.map
if(-e ffted.omap)  mv ffted.omap  \${oDIR}phased.omap
rm -f ffted.omacro

# \${oDIR}sites.pdb and \${scriptDIR}sites.mlphare
# were made at the "make_pdb:" label


# now make an O macro for looking at this?


Best_not_Best:
################################################################################################################
                                 
 #####   ######   ####    #####   ##### 
 #    #  #       #          #    #     #
 #####   #####    ####      #        ##
 #    #  #            #     #       #
 #    #  #       #    #     #
 #####   ######   ####      #       #

################################################################################################################
# see if this round of flattening produced a superior map
################################################################################################################
if(\$?BEST_YET) then
    # map was judged to be the best one yet
    # regardless of "flip" state or atom finding
    
    # back up the script
    echo "best-looking solution yet! "
    echo "copying \$scriptfile to \${scriptfile}.best"
    cp \$scriptfile \${scriptfile}.best
    cp \${scriptDIR}sites.mlphare \${scriptDIR}best_sites.mlphare >& /dev/null
    
    # copy the MTZ from this new "best" run to a safe location
    set temp = \`echo \$bestDMtrial | nawk '{print \$NF}'\`
    echo "copying \$temp to \$bestmtz"
    cp \$temp \$bestmtz

    # change SG in the o macros
    cat \${oDIR}best.omacro |\\
    awk -v SG=\$SG '/^sym_set/{\$NF=SG} {print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \${oDIR}best.omacro
    cat \${oDIR}latest.omacro |\\
    awk -v SG=\$SG '/^sym_set/{\$NF=SG} {print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \${oDIR}latest.omacro

    echo ""
    
    # report on files produced by last FFT
    if(-e \${mapDIR}phased.map) then
	echo "\${mapDIR}best_phased.map is a normalized ccp4 map from \$bestmtz"
	if(-e \${oDIR}phased.omap) then
	    echo "\${oDIR}best_phased.omap is an o version (\${ofmt}) of \${mapDIR}best_phased.map"
	    if(-e \${oDIR}best.omacro) echo "you can view it now in o using \${oDIR}best.omacro"
	endif
    endif

    # back-up "best" files in o directory
    cp -f \${mapDIR}phased.map \${mapDIR}best_phased.map >& /dev/null
    cp -f \${oDIR}phased.omap \${oDIR}best_phased.omap >& /dev/null
    cp -f \${oDIR}bones.o     \${oDIR}best_bones.o     >& /dev/null
    cp -f \${oDIR}pick.pdb    \${oDIR}best_pick.pdb    >& /dev/null
    cp -f \${oDIR}sites.pdb   \${oDIR}best_sites.pdb   >& /dev/null

else
    echo "none of these were better than \$bestmtz"
    echo "\${scriptfile}.best is still the best mlphare script."
    echo ""
    
    # no improvement this round, so maybe we should
    # chuck the changes from last time?
    
    # register new atoms as bad?
endif

# now decide where to go next
if(("\$FLIP_state" < 999)&&((\$?FLIP_OCC)||(\$?FLIP_HAND)||(\$?FLIP_SG))) then
    # flipping is either in progress, or needs to be done
    goto Flip
endif

# we are either done with flipping,
# or user requested to forgo this rigamarol
    
# report on files produced by last FFT
if((-e \${mapDIR}phased.map)&&(! \$?BEST_YET)) then
    # only display this message if we havn't already 
    # blabered about "best" maps above, and aren't going
    # to be moving these files to new "FLIP_label" names
    echo "\${mapDIR}phased.map is a normalized ccp4 map from \$mapmtz"
    if(-e \${oDIR}phased.omap) then
	echo "\${oDIR}phased.omap is an o version (\${ofmt}) of \${mapDIR}phased.map"
	if(-e \${oDIR}latest.omacro) echo "you can view it now in o using \${oDIR}latest.omacro"
    endif
endif
    
# go find more sites
goto more_atoms























Flip:
################################################################################################################

 ######  #          #    #####
 #       #          #    #    #
 #####   #          #    #    #
 #       #          #    #####
 #       #          #    #
 #       ######     #    #

################################################################################################################
#	Flip over axes, space group, etc.
################################################################################################################


# prepare to flip out
if(\$#FLIP_labels < 2) then
    # flipping is not set up yet

    # set up flipping of variable values
    set FLIP_state = 1
    
    # this flag indicates that Phaser is now screwing around
    # so, if anything bad happens, we should come back here
    # and try something else!
    set TENTATIVE
    
    echo ""
    echo "now we will try other sign/hand conventions."
    
    # start "flips" from best script we have
    if(-e "\${scriptfile}.best") then
	echo "copying \${scriptfile}.best to \${scriptfile}.unflipped"
	cp \${scriptfile}.best \${scriptfile}.unflipped >& /dev/null
    else
	# what the hell?
	echo "ERROR: we have no sites! "
	set BAD
	goto done
    endif
    
    
    # create list of things to try (in the form of filename labels)
    set FLIP_labels = "flip"
    if((\$?FLIP_SG)&&("\$otherSG" != "")) then
	set FLIP_labels = "\$SG \$otherSG"
    endif
    if(\$?FLIP_HAND) then
	set temp = ""
	foreach label ( \$FLIP_labels )
	    set temp = "\$temp \${label}_+hand \${label}_-hand"
	end
	set FLIP_labels = "\$temp"
    endif
    if(\$?FLIP_OCC) then
	set temp = ""
	foreach label ( \$FLIP_labels )
	    set temp = "\$temp \${label}_+occ \${label}_-occ"
	end
	set FLIP_labels = "\$temp"
    endif
    
    # origin shift? 
    
    # make this a multiword variable (count number of flip-states)
    set FLIP_labels = ( \$FLIP_labels )
    if(\$#FLIP_labels == 1) then
	# how did this happen?
	unset FLIP_SG
	set otherSG = ""
	set FLIP_state = 999
	goto more_atoms
    endif
    
    # now create an O macro for viewing all these maps!
    set odir = \`cd \${oDIR}; pwd\`
    set center = \`echo \$CELL | nawk '{print \$1/2, \$2/2, \$3/2}'\`
    
    # start the "master" o macro
    echo "! root working directory" >! \${oDIR}allmaps.omacro
    echo "symbol root \$odir"        >> \${oDIR}allmaps.omacro
    echo ""                         >> \${oDIR}allmaps.omacro
    foreach FLIP_label ( \$FLIP_labels )
	# create a directory under o directory for all this crap
	test -d \${oDIR}\${FLIP_label}
	if(\$status) then
	    rm -f \${oDIR}\${FLIP_label} >& /dev/null
	    mkdir \${oDIR}\${FLIP_label}
	endif
	
	# make up a shorter label (for o objects)
	echo "\$FLIP_label" | nawk 'BEGIN{FS="_"} \\
	    \$2 ~ /^[Pp]/{if(substr(\$2,3)! \${tempfile}shortlabel
	set short_label = \`cat \${tempfile}shortlabel\`
	rm -f \${tempfile}shortlabel >& /dev/null
	
	# make up a color code
	echo "\$FLIP_label" | nawk 'BEGIN{FS="_";R=0;G=0;B=1} \\
	    \$2 ~ /^[Pp]/{if(substr(\$2,3)! \${tempfile}rgb
	set RGB = \`cat \${tempfile}rgb\`
	rm -f \${tempfile}rgb >& /dev/null
	
	# cancel the above two (for now)
	set RGB = white
	set short_label = map
	set msg = \`echo "\$FLIP_label" | nawk 'BEGIN{FS="_"} {print \$1, \$2, \$3, \$4}'\`
	
	# space group to put in macros
	set sg = "\$SG"
	if("\${FLIP_label}" =~ P*) set sg = \`echo \${FLIP_label} | nawk 'BEGIN{FS="_"} {print \$1}'\`

	# make an "individual" macro for each flip state
	cat << EOF-omacro >! \${oDIR}\${FLIP_label}/load.omacro
! current working directory
symbol cwd \${odir}/\${FLIP_label}
symbol cwd .

! read in a peak-pick of phased.omap (for grabbing onto)
sam_atom_in \\\${cwd}/pick.pdb pick
mol pick
obj pick
zone ;
end

sym_set ; ; \$sg
sym_cell
! cen_xyz \$center

! read in pdb version of the metal sites
sam_atom_in \\\${cwd}/sites.pdb sites
mol sites
obj sites
zone ;
end
sym_set ; ; \$sg
sym_cell

! display them as big spheres
sketch_cpk sites
sym_sphere sites sym 30
sketch_cpk sym1
clear_flags
sketch_cpk sym2
clear_flags
sketch_cpk sym3
clear_flags
sketch_cpk sym4
clear_flags
sketch_cpk sym5
clear_flags
sketch_cpk sym6
clear_flags
sketch_cpk sym7
clear_flags
sketch_cpk sym8
clear_flags
sketch_cpk sym9
clear_flags
sketch_cpk sym10
clear_flags

! read in and display the bones trace
read \\\${cwd}/bones.o
bone_setup skel bones 30 1 2 3 4 5
bone_draw

! use newer fastmap feature
fm_file \\\${cwd}/../maps/phased.map \$short_label \$sg
!          radius style n sig color
fm_set \$short_label 25     solid 1 1.0 \$RGB 


! use "old reliable" map commands
map_cache
map_active_center
map_file \\\${cwd}/phased.omap
map_object \$short_label
!         dx dy dz sig color linestyle
map_param 25 25 25 1   \$RGB  0.5 0 1
map_draw

! convenient @map macro
menu @map on

EOF-omacro

	# make an "individual" map macro for each flip state
	cat << EOF-omacro >! \${oDIR}\${FLIP_label}/map
! use newer fastmap feature
fm_file \\\${cwd}/../maps/phased.map \$short_label \$sg
!          radius style n sig color
fm_set \$short_label 25     solid 1 1.0 white 


! use "old reliable" map commands
map_cache
map_active_center
map_file \\\${cwd}/phased.omap
map_object \$short_label
!         dx dy dz sig color linestyle
map_param 25 25 25 1 \$RGB 0.5 0 1
map_draw

EOF-omacro

	# make a "master" o macro for viewing all maps in succession
	cat << EOF-omacro >> \${oDIR}allmaps.omacro
! --------------------------------------------
message "click on an atom to view \$msg"
wait_id

! change the effective "working directory"
symbol cwd \\\${root}/\${FLIP_label}
! --------------------------------------------
EOF-omacro
	# copy over the "individual" macro into this one
	tail -n +3 \${oDIR}\${FLIP_label}/load.omacro |\\
	cat >> \${oDIR}allmaps.omacro
    end
    
#    cat << EOF-omacro >> \${oDIR}allmaps.omacro
#message "click on an atom to view 'best' map"
#wait_id
#
#@\${odir}/map
#EOF-omacro
    
    ###############################
    # now, preemtively set FLIP_label for "first" flipping round
    # output files are already generated, 
    # but we need the new label name
    set FLIP_label = \`echo "\$FLIP_labels \$FLIP_state" | nawk '{print \$(\$NF)}'\`
endif

# flipping is now set up.




##########################
#  now begins the actual handling of flip-states
##########################

# clear convergence history
set Memory = 0
# proceed with caution? 
#set params = 3


###################
# back up all the files from the "last" flip run to this label

# first, do the script and logs
cp \${scriptfile}         \${scriptfile}.\${FLIP_label}
cp \${logfile}            \${logfile}.\${FLIP_label} 
if(-e \${logDIR}fftphase.log) mv \${logDIR}fftphase.log \${logDIR}fftphase.log.\${FLIP_label}


# rename each of the flattened mtzs 
set files = \`ls -1 \${mtzDIR} | nawk '/^dm_[0-9][0-9]\\.mtz\$/'\`
if(\$?NO_DM) set files = ""
foreach dm_mtz ( \$files )
    set trial = \`echo \$dm_mtz | nawk '{print substr(\$1,4,2)}'\`
    set dm_mtz = \${mtzDIR}\$dm_mtz
    mv \$dm_mtz \${mtzDIR}dm_\${trial}_\${FLIP_label}.mtz
    mv \${logDIR}dm_\${trial}.log \${logDIR}dm_\${trial}_\${FLIP_label}.log
    
    # update this for printing's sake
    if("\$mapmtz" == "\$dm_mtz") set mapmtz = "\${mtzDIR}dm_\${trial}_\${FLIP_label}.mtz"
end

# rename the mlphare output file to this flip state
cp \${mtzDIR}mlphare.mtz \${mtzDIR}mlphare_\${FLIP_label}.mtz
# update this for printing's sake
if("\$mapmtz" == "\${mtzDIR}mlphare.mtz") set mapmtz = "\${mtzDIR}mlphare_\${FLIP_label}.mtz"


# rename the O/rave stuff
if(-e \${mapDIR}phased.map)  cp \${mapDIR}phased.map  \${mapDIR}\${FLIP_label}_phased.map
if(-e \${oDIR}phased.omap)   cp \${oDIR}phased.omap   \${oDIR}\${FLIP_label}/phased.omap
if(-e \${oDIR}bones.o)       cp \${oDIR}bones.o       \${oDIR}\${FLIP_label}/bones.o
if(-e \${oDIR}pick.pdb)      cp \${oDIR}pick.pdb      \${oDIR}\${FLIP_label}/pick.pdb 
if(-e \${oDIR}sites.pdb)     cp \${oDIR}sites.pdb     \${oDIR}\${FLIP_label}/sites.pdb 
if(-e \${scriptDIR}sites.mlphare) cp \${scriptDIR}sites.mlphare \${scriptDIR}sites_\${FLIP_label}.mlphare


# report on files produced by last FFT
if((-e \${mapDIR}phased.map)&&(! \$?BEST_YET)) then
    # only display this message if we havn't already blabered about "best" maps above
    echo "\${mapDIR}\${FLIP_label}_phased.map is a normalized ccp4 map from \$mapmtz"
    if(-e \${oDIR}phased.omap) then
	echo "\${oDIR}\${FLIP_label}/phased.omap is an o version (\${ofmt}) of \${mapDIR}\${FLIP_label}_phased.map"
	if(-e \${oDIR}latest.omacro) echo "you can view it now in o using \${oDIR}latest.omacro"
    endif
endif


# need to change \$bestDMtrial variable?
if(\$?BEST_YET) then
    # remember this for the end
    set best_FLIP = "\$FLIP_label"
endif




############################
# move to the next flip state
@ FLIP_state = ( \$FLIP_state + 1 )
# retrieve the appropriate filename label
set FLIP_label = \`echo "\$FLIP_labels \$FLIP_state" | nawk '{print \$(\$NF)}'\`




############################
# if this was the last run, we need to close up shop
if( \$FLIP_state > \$#FLIP_labels ) then
    # we just finished the last "flip cycle"
    set FLIP_label = ""
    
    echo ""
    echo "finished flipping signs and axes."
    
    # we've tried everything, so go get the new winner
    if(-e "\${scriptfile}.best") then
	echo "copying \${scriptfile}.best back to \$scriptfile"
	cp \${scriptfile}.best \$scriptfile >& /dev/null

	cp \${scriptDIR}best_sites.mlphare \${scriptDIR}sites.mlphare >& /dev/null
	cp \${mtzDIR}mlphare_\${best_FLIP}.mtz \${mtzDIR}mlphare.mtz 
	if(-e "\${scriptfile}.unflipped") mv \${scriptfile}.unflipped \${scriptfile}.old

	# restore "best" files in o directory as well
	cp -f \${mapDIR}best_phased.map \${mapDIR}phased.map >& /dev/null
	cp -f \${oDIR}best_phased.omap  \${oDIR}phased.omap  >& /dev/null
	cp -f \${oDIR}best_bones.o      \${oDIR}bones.o      >& /dev/null
	cp -f \${oDIR}best_pick.pdb     \${oDIR}pick.pdb     >& /dev/null
	cp -f \${oDIR}best_sites.pdb    \${oDIR}sites.pdb    >& /dev/null
	
	# recover the space group name that ended up being the "best"
	set newSG = \`echo "\$bestDMtrial" | nawk '{print \$3}'\`
	if("\$?FLIP_SG") then
	    # we tried 2 space groups
	    set bestSG = "\$newSG"
	    echo "\$bestSG was the best space group."
	endif
    endif
    
    # no longer experimenting
    unset TENTATIVE
    # signal that filpping is done
    set FLIP_state = 999
    goto more_atoms
endif

#############################
# "ordinary" flip run

# start with the same script each "flip" cycle
cat \${scriptfile}.unflipped |\\
nawk '\$1 ~ /^DERIV/,/END/{print}' |\\
cat >! \$coordfile
# get rid of last script (and the "bad" atom list with it)
cp -f \${scriptfile}.unflipped \${scriptfile} >& /dev/null

# for separation
echo ""


# invert real occupancies every other FLIP state
if( "\$FLIP_label" =~ *-occ* ) then
    echo "negating real occupancies "
    
    # invert real occupancies (they can get stuck on the wrong side of 0)
    cat \$coordfile |\\
    nawk '\$1~/^ATOM/{\$6 = -\$6} {print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile >& /dev/null
    
endif
if(( "\$FLIP_label" =~ *-occ*)&&("\$FLIP_label" =~ *-hand*)) echo -n "and "


# invert atom coordinates 
if( "\$FLIP_label" =~ *-hand* ) then
    echo "flipping all atoms through the origin "
    
    # mirror-flip, sometimes this can be wrong too
    cat \$coordfile |\\
    nawk '\$1~/^ATOM/{\$3= -\$3; \$4= -\$4; \$5= -\$5;} {print}' |\\
    cat >! \${tempfile}
    mv \${tempfile} \$coordfile >& /dev/null
endif
#if( "\$FLIP_label" =~ "\$otherSG"* ) echo -n "and "



# invert spacegroup hand when requested
if( "\$FLIP_label" =~ P[1-6]* ) then
    # only need to reindex at beginning and end of the "Flip block"
    set newSG = \`echo \$FLIP_label | nawk -F "_" '{print \$1}'\`

    # print message every time SG is changed
    if("\$SG" != "\$newSG") then
	if(("\$FLIP_label" =~ *-occ*)||("\$FLIP_label" =~ *-hand*)) echo -n "and "
	echo "switching to \$newSG "
    endif
else
    # switch "back" to firstSG
    #if("\$firstSG" != "") set newSG = "\$firstSG"
endif

    

# anything else?  

# put this new \$coordfile and \$newSG into refinement
if("\$newSG" != "\$SG") goto reindex

goto Write_Script


















MinusOne:
########################################################################################################

 #    #     #    #    #  #    #   ####            ####   #    #  ######
 ##  ##     #    ##   #  #    #  #               #    #  ##   #  #
 # ## #     #    # #  #  #    #   ####   #####   #    #  # #  #  #####
 #    #     #    #  # #  #    #       #          #    #  #  # #  #
 #    #     #    #   ##  #    #  #    #          #    #  #   ##  #
 #    #     #    #    #   ####    ####            ####   #    #  ######

########################################################################################################
#
#	Manage "minus-one" analysis
#
#	that is, throw out a site, and see if it comes back in a difference Fourier
#
########################################################################################################

echo "not implemented "


# always eliminate atom #1

# obliterate anything withing 1A of this site ?

# remember where it was? 
set MINUS_ONE = "X Y Z"




goto GotSites






















more_atoms:
################################################################################################################

 #    #   ####   #####   ######            ##     #####   ####   #    #   ####
 ##  ##  #    #  #    #  #                #  #      #    #    #  ##  ##  #
 # ## #  #    #  #    #  #####           #    #     #    #    #  # ## #   ####
 #    #  #    #  #####   #               ######     #    #    #  #    #       #
 #    #  #    #  #   #   #               #    #     #    #    #  #    #  #    #
 #    #   ####   #    #  ######          #    #     #     ####   #    #   ####

################################################################################################################
#   look for new sites using a difference Fourier
################################################################################################################


# get the best ordering of the Fs, based on refined occupancies
cat \$scriptfile |\\
nawk '\$1~/^DERIV/{++deriv}\\
      \$1~/^ATOM/{++count[deriv]; \\
	 fp[deriv]=fp[deriv]+\$6; fpp[deriv]=fpp[deriv]+\$7}\\
      END{for(deriv in count) if(count[deriv]){\\
	  print deriv, "F", fp[deriv];\\
	  print deriv, "D", fpp[deriv]}}' |\\
cat >! \${tempfile}fp_fpp

# get the dataset label names
cat \$scriptfile |\\
nawk '\$1 ~ /^LABIN/{print; while(\$NF == "-"){getline; print}}' |\\
nawk 'BEGIN{RS=" "} NF != 0 && \$1 != "-"' |\\
nawk 'NF!=0' |\\
nawk '/^FPH/{print "F", substr(\$0,4)+0, substr(\$0,index(\$0,"=")+1)}\\
      /^DPH/{print "D", substr(\$0,4)+0, substr(\$0,index(\$0,"=")+1)}' |\\
cat >> \${tempfile}fp_fpp

# combine labels with occupancies
cat \${tempfile}fp_fpp |\\
nawk '\$2=="F"{fp[\$2 \$1]=\$3} \$2=="D"{fpp[\$2 \$1]=\$3}\\
      \$1=="F"{print "F", \$NF, fp[\$1 \$2]} \$1=="D"{print "D", \$NF, fpp[\$1 \$2]}' |\\
cat >! \${tempfile}Forder

# sort them so that biggest magnitudes come first
set Forder = \`sort -nr -k3 \${tempfile}Forder | nawk '\$1=="F"{print \$2}'\`
set Dorder = \`sort -nr -k3 \${tempfile}Forder | nawk '\$1=="D"{print \$2}'\`
rm -f \${tempfile}Forder >& /dev/null

# check for missing data sets
if("\$Forder" == "") then
    # no isomorphous differences?
    set temp = \`nawk '\$1=="F"' \${tempfile}fp_fpp | wc -l\`
    if(\$temp) then
	# there WERE datasets, they just don't have any signal
	# so let's just leave them out of the analysis
	set Forder = "no "\`nawk '\$1=="F"{print \$NF}' \${tempfile}fp_fpp\`
    endif
endif
if("\$Dorder" == "") then
    # no anomalous differences?
    set temp = \`nawk '\$1=="D"' \${tempfile}fp_fpp | wc -l\`
    if(\$temp) then
	# there WERE datasets, they just don't have any signal
	# so let's just leave them out of the analysis
	set Dorder = "no "\`nawk '\$1=="D"{print \$NF}' \${tempfile}fp_fpp\`
    endif
endif
rm -f \${tempfile}fp_fpp >& /dev/null

# check for intentionally missing data sets
if(("\$Forder" == "")||("\$Dorder" == "")) then
    # there really are no (desired) differences of one kind or the other
    # make sure we don't accidentally include any from the mtz
    echo "go" | mtzdump hklin \$bestmtz |\\
    nawk '/OVERALL FILE/,/LIST OF REF/' |\\
    nawk 'NF>3 && \$1~/^[0-9]/' |\\
    nawk '\$(NF-1) ~ /^[FD]\$/{print \$NF}' |\\
    cat >! \${tempfile}
    set temp = \`nawk '\$1=="F"{print \$2}' \${tempfile}\`
    if(("\$Forder" == "")&&("\$temp" != "")) then
	# make sure these are not included (without dangling "no"s)
	set Forder = "no \$temp"
    endif
    set temp = \`nawk '\$1=="D"{print \$2}' \${tempfile}\`
    if(("\$Dorder" == "")&&("\$temp" != "")) then
	# make sure these are not included
	set Dorder = "no \$temp"
    endif
    rm -f \${tempfile} >& /dev/null
endif

# get a good "exclude" value
cat \$scriptfile |\\
nawk '\$1~/^EXCLUDE/{for(i=1;i<=NF;++i){\\
      if(\$i~/^DI/)print "DISO", \$(i+1);\\
      if(\$i~/^DA/)print "DANO", \$(i+1);}}' |\\
nawk '/^DI/{if(\$2>max_diso) max_diso=\$2} \\
      /^DA/{if(\$2>max_dano) max_dano=\$2} \\
END{print max_diso, max_dano}' |\\
cat >! \${tempfile}
# use a little wider spread
set max_diso = \`nawk '\$1+0>1{print 1.5*\$1}' \${tempfile}\`
set max_dano = \`nawk '\$2+0>1{print 1.5*\$2}' \${tempfile}\`
rm -f \${tempfile}

# calculate the average, overall B-factor of these sites
cat \$scriptfile |\\
nawk '\$1~/^ATOM/{weight = sqrt(\$6*\$6)+\$7; wsum += weight;\\
    B += \$NF*weight;}\\
    END{if(wsum+0==0)wsum=1; print B/wsum}' |\\
cat >! \${tempfile}
set avgB = \`nawk '\$1+0>1' \${tempfile}\`
if("\$avgB" == "") set avgB = \$wilsonB
rm -f \${tempfile}



########
# calculate a phase-combined difference Fourier
# back-up "old" copies?
mv \${mtzDIR}FH.mtz \${tempfile}FH.mtz  >& /dev/null
mv \${mtzDIR}FH.hkl \${tempfile}FH.hkl  >& /dev/null

# run the packaged difference-Fourier script:
\${scriptDIR}bestFH.com \$bestmtz \${hiRES}-1000A \$Forder  \$Dorder |\\
egrep -v "FH.hkl|FH.mtz|FH_" 
rm -f FH.hkl FH.mtz wFH_Patt.map >& /dev/null
if(-e FH_Patt.map) then
    echo "\${mapDIR}FH_Patt.map is ready."
    mv FH_Patt.map \${mapDIR}FH_Patt.map  >& /dev/null
    mv wFH_Patt.map \${mapDIR}wFH_Patt.map  >& /dev/null
endif
if(-e FH_Four.map) then
    echo "\${mapDIR}FH_Four.map is ready."
    mv FH_Four.map \${mapDIR}FH_Four.map  >& /dev/null
endif
mv bestFH.log \${logDIR} >& /dev/null

# restore "old" copies?
mv \${tempfile}FH.mtz \${mtzDIR}FH.mtz  >& /dev/null
mv \${tempfile}FH.hkl \${mtzDIR}FH.hkl  >& /dev/null

# now we should have \${mapDIR}FH_Four.map and \${mapDIR}FH_Patt.map to look at.


########
# pick only peaks that we havn't already seen (listed in \$scriptfile)
echo ""
echo "looking for new \${newSIG}-sigma peaks in \${mapDIR}FH_Four.map"
echo "that are not already in \$scriptfile"
\${scriptDIR}pick.com \${mapDIR}FH_Four.map \$scriptfile \$newSIG sigma >! \${tempfile}.log
mv pick.log \${logDIR} >& /dev/null
echo ""
set peaks = \`nawk '/^ATOM/' pick.pdb | wc -l\`
mv pick.pdb \${oDIR}/FH_Fourier.pdb >& /dev/null
if(! \$peaks) then
    # no difference features?
    echo "no new sites found."
    rm -f \${tempfile}.log >& /dev/null
    goto no_new_atoms
endif

# vecref can't handle more than 50 sites
set max_new_sites = \`cat \${scriptDIR}sites.mlphare | wc -l | nawk '\$1+0<50{print 50-\$1}'\`
if("\$max_new_sites" == "") then
    # uhh... hmm.  no what?
    set max_new_sites = 50
endif

# extract fractional coordinates from the pick.com screen output
cat \${tempfile}.log |\\
nawk 'NF>5 && \$1~/[01]\\.[0-9][0-9][0-9]/{print}' |\\
head -\$max_new_sites >! \${tempfile}peaks
rm -f \${tempfile}.log >& /dev/null
# format: xf yf zf mult height/sig  dist  neighbor...



# check these against the Patterson map
set peaks = \`cat \${tempfile}peaks | wc -l\`
set lowsigma = \`tail -1 \${tempfile}peaks | nawk '{print \$5+0}'\`
echo "checking \$peaks new peaks > \${lowsigma}*sigma against \${mapDIR}FH_Patt.map"

# get "reference" sites from \${scriptDIR}sites.mlphare 
# these will serve to check for cross-vectors with new peaks
cat \${scriptDIR}sites.mlphare |\\
nawk '\$1~/^ATOM/{print "ATOM H 0", sqrt(\$6*\$6)+\$7, \$3, \$4, \$5, \$NF}' |\\
cat >! \${tempfile}atoms.out
# vecref format: ATOM Ee atom# occ xf yf zf Bfac 
# we are using hydrogen because these occupancies should be in "electrons"

if("\$max_new_sites" == "50") then
    # discard original sites if there are > 50 of them?
    echo -n "" >! \${tempfile}atoms.out
endif

# convert fractional coordinates to vecref format
cat \${tempfile}peaks |\\
nawk -v avgB=\$avgB '{++n;\\
    print "ATOM H", n, \$4,\$1,\$2,\$3,avgB}' |\\
cat >> \${tempfile}atoms.out
# vecref format: ATOM Ee atom# occ xf yf zf Bfac 



# use vecref to check against the Patterson
set rcycles = "3,0,0 3,0,0 3,10,0 3,10,0 3,0,10 3,0,10"
set rcycles = "3,0,0 3,0,0 3,0,0 3,0,0"

# reduce resolution a bit so vecref won't crash
set refRES = \`echo \$hiRES | nawk '{print (0.8*1/(\$1^3))^(-1/3)}'\`
set refLOG = \${logDIR}/pick.log


# "dribble" peaks into refinement?

# do several cycles of rejection
foreach rcycle ( \$rcycles )
    set rcycle = \`echo "\$rcycle" | nawk 'BEGIN{FS=","} {print \$1, \$2, \$3}'\`
    
    # vecref can't handle more than 50 sites
    sort -n -k3,4 \${tempfile}atoms.out |\\
    head -50 |\\
    cat >! \${tempfile}atoms.in
    
    # refine "occupancies" against the Patterson
    rm -f \${tempfile}atoms.out >& /dev/null
    set vecrefSG = \$SG
    if("\$vecrefSG" == "H3") set vecrefSG = R3
    if("\$vecrefSG" == "H32") set vecrefSG = R32
    vecref mapin \${mapDIR}FH_Patt.map \\
           ATOUT \${tempfile}atoms.out << EOF-vecref >>& \$refLOG
    SPACEGROUP \$vecrefSG
    RESOLUTION \${refRES}
    CYCLES \$rcycle
    BREF
    @\${tempfile}atoms.in
EOF-vecref
    if((\$status)||(! -e \${tempfile}atoms.out)) then
	# all atoms rejected
	echo -n "" >! \${tempfile}atoms.out
	break
    endif
end
# delete the vecref input file
rm -f \${tempfile}atoms.in >& /dev/null

# combine the peak heights with the vecref occupancies
cat \${tempfile}atoms.out \${tempfile}peaks |\\
nawk '/^ATOM/{occ[\$3]=\$4; next} NF>5{++n;\\
    printf "%12.4f %s\\n", occ[n]*5/\$4, \$0}' |\\
sort -nr | nawk '\$1+0>0' |\\
cat >! \${tempfile}survivors
rm -f \${tempfile}atoms.out >& /dev/null
rm -f \${tempfile}peaks >& /dev/null
# \${tempfile}survivors contains a "combined" score for each peak
# format:  height*vecref_occ/mult xf yf zf mult height dist neighbor...

echo ""
set survivors = \`cat \${tempfile}survivors | wc -l\`
echo -n "\$survivors survived, "

# only show a handful:
set sigCUT = 0
while( \$survivors > 8 )
    # increase the sigma cutoff
    set sigCUT = \`echo \$sigCUT | nawk '{print \$1+1}'\`
    set survivors = \`nawk -v sigCUT=\$sigCUT '\$1+0>sigCUT' \${tempfile}survivors | wc -l\`
    # safety catch?
end

if(\$survivors) then
    # print sites out for user to review
    echo "top \${survivors}:"
    echo "  x        y        z        mult  height/sigma   dist  from nearest neighbor"
    head -\${survivors} \${tempfile}survivors |\\
    nawk '{print substr(\$0,14)}'

    # check for special positions
    set specials = \`head -\${survivors} \${tempfile}survivors | nawk '\$5+0>1' | wc -l\`
    if(\$specials) then
	# ignore these?  jiggle them? 
	echo "peaks with mult > 1 are on special positions."
	echo ""
    endif
else
    # no suitable sites were found.
    echo "what a shame..."
    rm -f \${tempfile}survivors >& /dev/null
    goto no_new_atoms
endif
echo ""



# now we need to decide which of these to add to the refinement
set NEW_SITES_FOUND

# don't add more sites than we already have
cat \$scriptfile |\\
nawk '\$1~/^DERIV/{++deriv} \$1~/^ATOM/{++atom[deriv]}\\
    END{for(deriv in atom) printf "%d\\n", atom[deriv]*0.7}' |\\
sort -n >! \${tempfile}
set max_new_sites = \`head -1 \${tempfile}\`
rm -f \${tempfile} >& /dev/null
if(("\$max_new_sites" == "")||("\$max_new_sites" == "0")) set max_new_sites = 1

# if we're not in a hurry, don't add more than 2 sites at a time
if(("\$max_new_sites" > 2)&&(! \$?HURRY_UP)) set max_new_sites = 2

# don't look stupid
if(\$max_new_sites > \$survivors) set max_new_sites = \$survivors












# retrieve maximum atom number used so far
set atom = \`nawk '\$1~/^ATOM/{print substr(\$1,5)}' \$scriptfile | sort -n | tail -1\`

head -\$max_new_sites \${tempfile}survivors |\\
nawk -v atom=\$atom '{++atom; \\
    printf " ATOM%-3d ANO  %6.3f %6.3f %6.3f  ?.???  ?.??? BFAC    ?.???\\n",\\
       atom, \$2, \$3, \$4;}' |\\
cat >! \${tempfile}newATOMs
rm -f \${tempfile}survivors
# \${tempfile}newATOMs has the new mlphare atoms, mlphare format


# retrive full coordinate list from the script
cat \$scriptfile |\\
nawk '\$1 ~ /DERIV/,/END/{print}' | nawk '! /END/{print}' |\\
cat >! \${coordfile}

# as well as the LABIN cards
cat \$scriptfile |\\
nawk '\$1 ~ /^LABIN/{print; while(\$NF == "-"){getline; print}}' |\\
cat >! \${tempfile}.LABELS

# append the new atoms to the end of each derivative
cat \${tempfile}newATOMs \${coordfile} |\\
nawk '/[?]/{++n; ATOM[n]=\$0} \\
      /DERIV/{deriv=1} \\
      NF==0 && deriv!=""{\\
        for(i=1;i<=n;++i){print ATOM[i]; print "ATREF"};\\
	deriv=""}  ! /[?]/{print}' |\\
cat >! \${tempfile}
mv \${tempfile} \${coordfile}

# add the new sites to the "previously tried" list (as OLDATOMs)
cat \${tempfile}newATOMs |\\
nawk '{print "OLD" substr(\$0,2)}' |\\
cat >! \${tempfile}badatoms
rm -f \${tempfile}newATOMs >& /dev/null
    
# go back and clean up these new sites for further refinement
if(\$?MORE_SITES) then
    echo ""
    echo "adding top \$max_new_sites sites to \$scriptfile"
	
    # occupancies will probably be okay, but not xyz! 
    set params = 3

    # this procedure will use \${coordfile} and \${tempfile}badatoms
    set sites = \`cat \${coordfile} | wc -l\`
    goto GotSites
endif

# user asked us to stop now
mv \${coordfile} newATOMS.mlphare
rm -f \${tempfile}badatoms  >& /dev/null
echo ""
echo "new mlphare atoms written to newATOMS.mlphare"

no_new_atoms:

# flip again?
if((\$FLIP_state == 999)&&(\$?MORE_SITES)&&(\$?NEW_SITES_FOUND)&&(! \$?FINAL_FLIP)) then
    # flipping was done before, and we have found new sites
    unset NEW_SITES_FOUND
    set FLIP_labels = ""
    #set FINAL_FLIP

    # combine bad,old atom lists in the "best" script
    egrep -v "^OLDATOM|^BADATOM" \${scriptfile}.best >! \${scriptfile}.unflipped
    cat \${scriptfile}.best \${scriptfile} |\\
    egrep "^OLDATOM|^BADATOM" |\\
    nawk '! seen[\$0]{print \$0; seen[\$0]=\$0}' |\\
    cat >> \${scriptfile}.unflipped
    cp \${scriptfile}.unflipped \${scriptfile}.best >& /dev/null

    # make maps again?
    #goto FFT
    touch \${logDIR}fftphase.log
    goto Flip
endif

# jump to minus-one procedure now?
#goto MinusOne

# that's all she wrote...
goto done

exit

done:
################################################################################

 #####    ####   #    #  ######
 #    #  #    #  ##   #  #
 #    #  #    #  # #  #  #####
 #    #  #    #  #  # #  #
 #    #  #    #  #   ##  #
 #####    ####   #    #  ######

################################################################################
#   Clean up
################################################################################

# clean up
#rm -f \${tempfile}* >& /dev/null
rm -f \${tempfile}EXCLUDE >& /dev/null
rm -f \${tempfile}.LABELS >& /dev/null
rm -f \$coordfile         >& /dev/null

# user-requested exit
if(\$?QUIT) then
    echo "Okay, Bye! "
    exit
endif

# unhappy ending
if((! -e "\$scriptfile")||(! -e "\$bestmtz")||(\$?BAD)) then
    echo "Dang! "
    exit 9
endif

# copy the "best" script back over to the new one
if(-e \${scriptfile}.older) mv \${scriptfile}.older \${scriptfile}.oldest
if(-e \${scriptfile}.old) mv \${scriptfile}.old \${scriptfile}.older
if(-e \${scriptfile}) mv \${scriptfile} \${scriptfile}.old
cp \${scriptfile}.best \${scriptfile}

echo ""
echo ""
echo "average values for sites used in this Phaser run: "
cat \${scriptDIR}sites.mlphare
if(-e \${oDIR}sites.pdb) echo "a PDB version of these sites is in: \${oDIR}sites.pdb"

echo ""
echo -n "phased version of \$firstmtz is \${mtzDIR}mlphare.mtz"
if("\$?bestSG") then
    echo -n "(in \$bestSG)"
endif
echo ""
set temp = \`echo \$bestDMtrial | nawk '\$1+0>0{print \$1}'\`
if("\$temp" != "") then
    echo "\${temp} solvent flattened \${mtzDIR}mlphare.mtz is \$bestmtz"
else
    echo "and it has been backed up as \$bestmtz"
endif

# explain the maps
if(-e \${mapDIR}best_phased.map) echo "\${mapDIR}best_phased.map is a normalized ccp4 map from \$bestmtz"
if(-e \${oDIR}best_phased.omap) then
    echo "\${oDIR}best_phased.omap is an o version (\${ofmt}) of \${mapDIR}best_phased.map"
    if(-e \${oDIR}best.omacro) echo "you can view it now in o using \${oDIR}best.omacro"
    if(-e \${oDIR}allmaps.omacro) echo "you can view all maps in o using \${oDIR}allmaps.omacro"
endif

echo ""
echo "Phaser Elves are done."
date +"%T %D"

exit






























































exit
Setup_scripts:
########################################################################################################

  ####    ####   #####      #    #####    #####   ####
 #       #    #  #    #     #    #    #     #    #
  ####   #       #    #     #    #    #     #     ####
      #  #       #####      #    #####      #         #
 #    #  #    #  #   #      #    #          #    #    #
  ####    ####   #    #     #    #          #     ####

########################################################################################################
#
#	Set up all auxillary scripts before we run mlphare
#
########################################################################################################
echo ""
echo "setting up scripts in \$scriptDIR"








########################################################################################################
# write the README file first
cat << EOF >! README.Phaser

Phaser Elves guide to their scripts

1) In a rush?  Just type this:

\$scriptfile >! logs/mlphare.log
\${scriptDIR}dm.com 50% mlphared.mtz >! logs/dm_50.log
\${scriptDIR}fft.com dmed.mtz >! logs/fft.log

# if you have "o" installed:
ono
  O > @ffted.omacro

That should give you something to look at in "o".

Phases calculated from the metal sites in \$scriptfile will be placed in a file
called ./mlphared.mtz by the first command.  

The second command runs dm on these phases, using 50% as the solvent content.  
The solvent-flattening results are placed in ./dmed.mtz.

The fft.com script will calculate a phased electron density map from the 
solvent-flattening results.  If an appropriate conversion program is available 
(mapman, brix), an "o version" of this map will also be generated by fft.com, 
as well as a bones trace, and an o macro (called ffted.omacro) for viewing it.



2) Okay, how does it work?

    The details of how each script behaves are described below.  

    Phaser Elves do a lot of exploratory work to find the correct parameters.
for your phasing run.  It is HIGHLY recommended that you alow Phaser Elves to
explore alternative sign/hand/spacegroup/solvent-content parameters before you
look at any maps.  Particularly for MAD data, you can get exactly the same
phasing statistics for a number of choices of sign/hand/spacegroup, but
only one combination of these will give you an interpretable map.  

    However, once you are certain you have the correct sign and hand choice,
run Phaser with the words "no flip" on the command line, to keep them from 
re-exploring all these alternatives.

    Phaser Elves will also calculate a phased difference Fourier, using all
your difference data, once they are done doing all of the above.  By default,
peaks in this difference Fourier are added to the mlphare script (one at a
time), and then the refinement continues.  This process repeats until all the
significant peaks in the difference Fourier have been tried.  To turn this off,
put the words "no add" on the command line.
	

In the \${scriptDIR} directory:

################################################################################
\$scriptfile	- mlphare script
    reads: \$mtzfile	- cad-ed data sets
    makes: mlphared.mtz	- phases calculated from sites, ready for dm
    usage: \$scriptfile [other.mtz]
    
    example: \$scriptfile

    description:
	The \$scriptfile script has been carefully written to have the best 
	chance of generating a sucessful mlphare run.  Phaser Elves are 
	careful not set up \$scriptfile to refine indeterminant parameters, 
	such as anomalous occupancy when there are no anomalous diffs, and 
	things like one "y" position in P2.  For derivatives where the 
	anomalous differences seem stronger than the isomorphous ones 
	(typical for MAD), the atom refinement flags are set up to take 
	advantage of this.  
	
	Also, since Phaser Elves don't always refine all the atomic parameters, 
	\$scriptfile might only be set up to refine a few.  So, don't believe
	a nice, high FOM if you havn't refined your occupancies yet! 
	
	\$scriptfile also contains all the information Phaser Elves need to
	continue refining your atom sites.  So, once you have got it running, 
	you can run Phaser Elves with \$scriptfile on their command line, and 
	let them tune things up for you.
	
	Note: if an occupancy is set to exactly zero, Phaser Elves will 
	interpret this as a "true" missing parameter and will never refine 
	it.  If you want to start refining from zero, try using "0.001" instead.
	
	See the mlphare manual for more details on how to edit and run mlphare 
	scripts.


################################################################################
\${scriptDIR}dm.com	- "smart" dm script

    reads: mlphared.mtz	- an mtz with some kind of phase information in it
    makes: dmed.mtz	- the solvent-flattened results
    
    usage: \${scriptDIR}dm.com phased.mtz [Fset] [1.8A] [solc%]
    where: 
    phased.mtz contains the (phased) data to flatten   (default: \${mtzDIR}mlphare.mtz)
    Fset       is the set of Fs you want to flatten    (default: most complete F)
    1.8A       is the desired outer resolution limit   (default: \${hiRES}A)
    solc%      is the solvent content of your crystal  (default: 50%)
    
    examples: 
	\${scriptDIR}dm.com \${mtzDIR}mlphare.mtz
	  - will flatten an automatically-chosen dataset in 
	    \${mtzDIR}mlphare.mtz at 50% solvent.  
	\${scriptDIR}dm.com \${mtzDIR}mlphare.mtz \$native 40%
	  - will flatten the \$native dataset in \${mtzDIR}mlphare.mtz using 
	  a solvent content of 40%.  
    
    description:
	This script is meant to do a standard, highly-automatic dm run.  Most 
	of the "automatic" stuff it does it finding a suitable F and phase to 
	use in flattening.  There are a lot of things you can do to tweak dm 
	and make it give you better phases, not the least of which is averaging.
	For this reason, dm.com is designed to be easily edited by end-users to
	suit these needs.
	
	Although dm.com was meant for the phased data produced by the Phaser 
	Elves scripts, it should be applicable to almost any phased mtz data, 
	including the "solve.mtz" output from Terwilliger's SOLVE program.

    advanced:
	If you edit or replace this script, Phaser Elves will not overwrite
	your new version of it next time it is run.  You can, therefore, easily
	apply NCS operators just by adding them to dm.com

################################################################################
\${scriptDIR}fft.com	- "smart" fft script

    reads: phased.mtz	- an mtz with some kind of phase information in it
           cover.pdb	- a PDB file to "cover" with the map
           phased.map   - (optional) an already-calculated CCP4 map you want to
			  convert to "o format"
    makes: ffted.map	- a CCP4 map of phased.mtz (one ASU only)
           ffted.omap	- a DSN6 or BRIX version of ffted.map 
			  (extended to cover either cover.pdb or 120% of the cell)
	   bones.o	- a "bones" trace of ffted.omap
	   fftpick.pdb  - a peak-pick of ffted.omap (unless cover.pdb is available)
	   ffted.omacro - an o macro for viewing all these files
	   
    usage: \${scriptDIR}fft.com phased.mtz [Fset] [PHI] [FOM] [1.8A]
    where: 
    phased.mtz contains the (phased) data to transform (default: \$bestmtz)
    Fset       is the set of Fs you want to use        (default: most complete F)
    PHI        is the phase set you want to use	       (default: most recent phase)
    FOM        is the FOM weight to use		       (default: most recent FOM)
    1.8A       is the desired outer resolution limit   (default: \${hiRES}A)
    
    examples: 
	\${scriptDIR}fft.com dmed.mtz \$native FOM
	  - will transform the \$native dataset in dmed.mtz using the most-
	    recently added phase in dmed.mtz (PHIDM), but weighted by 
	    mlphare's FOM (FOM in dmed.mtz).  
	\${scriptDIR}fft.com maps/2fofc.map pdb/refmac123.pdb
	  - will calculate the ffted.omap and ffted.omacro to cover 
	    pdb/refmac123.pdb with maps/2fofc.map, (no actual fft will 
	    be done).  
    
    description:
	This script is meant to do a quick, "most reasonable" fft of the 
	"best" data in the mtz file provided to it, and make sure its easy for 
	you to see in o as quickly as possible.  Most of the "automatic" stuff
	it does it finding a suitable F and phase to use (in exactly the same 
	way dm.com does).
	
	For your convenience, a pdb file included on the command line, 
	ffted.omap will be extended to "cover" everything within 10A of the 
	atoms in this file.  This comes in very handy if your building takes 
	you significantly out of the unit cell.
	Also for your convenience, the above o-map calculation can be done on 
	a pre-calculated CCP4 map (like one you obtained from refmac).
	
	If no pdb file is provided, fft.com produced fftpeak.pdb, which is 
	just a simple peak-pick on the region covered by the "o" map.  
	fftpeak.pdb is handy when exploring a new map in "o", giving you atoms 
	to "cen_id" on as you move around the map.
	The ffted.omacro also contains a section for reading in the "sites.pdb"
	file (produced by Phaser Elves) to allow you to see the heavy-atom 
	positions used to calculate the map you are looking at.  However, 
	fft.com does not generate this sites.pdb file itself.
	
	Although fft.com was meant for the phased data produced by the Phaser 
	Elves scripts, it should be applicable to almost any phased mtz data, 
	including the "solve.mtz" output from Terwilliger's SOLVE program.

################################################################################
\${scriptDIR}bestFH.com	- Matthews "best" FH estimator

    input:  all.mtz	- a cad-ed mtz file with multiple data sets
    output: FH.mtz	- an mtz containing only the estimate of FH
            fh.hkl	- shelx version of FH.mtz
	    FH_Patt.map - a Patterson map of FH
	    FH_Four.map - phased map of FH (if a phase is in all.mtz)
	   
    usage: \${scriptDIR}bestFH.com all.mtz [Fset] [Dset] [1.8A]
    where: 
    all.mtz    contains same-site reflection data      (default: mtz/all.mtz)
    Fset       are the sets of Fs you want to use      (default: all of them)
    Dset       are the sets of Danos you want to use   (default: all of them)
    1.8A       is the desired outer resolution limit   (default: all data)
    PHI        is the phase set you want to use	       (default: most recent phase)
    
    FH_Patt.map is calculated with a 4*rms(FH) cutoff, as calculated by scaleit.
    
    example1: \${scriptDIR}bestFH.com mtz/all.mtz
	will calculate an estimate of FH from all the difference data in 
	mtz/all.mtz.
	
    example2: \${scriptDIR}bestFH.com dmed.mtz
	will calculate an estimate of FH from all the difference data in 
	mtz/all.mtz. (same as above), but will also calculate a phased map 
	of FH, using the most recently-added phase in dmed.mtz (PHIDM).  
	This is usually superior to ordinary difference Fouriers for finding 
	new heavy-atom sites.
    
    example3: \${scriptDIR}bestFH.com mtz/all.mtz no DANOFlo Flo
	same thing, but leave the "DANOFlo difference data-set and "Flo" data
	set out of the calculation.
    
    description:
	This script offers the "new" functionality of computing a "Matthews FH" 
	estimate.  This analysis not only "averages" information from all your 
	diference data into a single data set, but reduces the systematic error
	produced by cross-terms in the substraction of anomalous and 
	isomorphous difference data: |FH| == |FPH-FP| != |FPH|-|FP|
    
	In bestFH.com, all anomalous difference data are scaled together, 
	and then added (sigma-weighted) together.  Then, all the possible
	isomorphous differences between "F"s in the mtz are subtracted, 
	scaled, and also added together.  Finally, Dano is scaled against
	Diso, and FH is calculated by the Pythagorean theorem.
	
	Care must be taken in the ordering of the "F" datasets.  For example, 
	in a 3-wavelength MAD experiment: Finf Fpeak Fhi should be the order
	used.  Fhi Fpeak Finf is okay too, but not Finf Fhi Fpeak.  The latter
	would result in Finf-Fhi and Fhi-Fpeak "canceling" each other, because
	the f' differences will have opposite signs.  bestFH.com will try to
	get this ordering right, but you should check the difference dataset
	list to make sure none of them are opposing each other.

	Note also that all the data in mtz/all.mtz should be from 
	crystals with metal sites at the same positions, otherwise, FH will 
	be a mix of the two site constellations.  
    
################################################################################
\${scriptDIR}reindex.com	- general-purpose re-indexing script

    input:  data.mtz	    - mtz file to re-index (merged or unmerged)
    output: reindexed.mtz   - mtz file with the new space group
    
    examples: 
	\${scriptDIR}reindex.com data.P41212.mtz P43212
	  - will change the space group of "data.P41212.mtz" to P43212 
	    (assuming that is possible), and write the results to 
	    "reindexed.mtz"
	\${scriptDIR}reindex.com data.P2221.mtz P2122
	  - will change the space group of "data.P2221.mtz" to the "pseudo" 
	    space group "P2122", which is P2221, but with "a" as the screw 
	    axis.  This is done by leaving the mtz file in P2221, but 
	    permuting the cell (and the data) so that the shortest cell edge 
	    (normally "a"), is moved to the third cell parameter (the one 
	    with screw symmetry).
	
    description:
	This is a general utility for changing the assigned space group of 
	mtz data using the CCP4 program "reindex".  It works on merged and 
	unmerged data.  Re-assignment of the screw/rotation axes of 
	anisotropic orthorhombic space groups is supported (see example 2).
	
	"Flipping" between alternative axis assignments is also easily done.
	Just include the word "flip" on the reindex.com command line to switch
	to the "other" axis assignment.  This may be neccessary for any space
	group having two or more cell edges exactly the same length.  The only 
	tricky ones are R3 and P3x, which have four possible axis assignments.  
	To specify the remaining two, use the word "flip" two or three times 
	(respectively).  see \${CDOC}/reindexing.doc for details.
	
	Changing between space groups with different point group, or even
	lattice symmetry is allowed, but unadvisable!  These transformations
	involve mergeing or "un-mergeing" spots, which reindex can't do.
    
	Note: moving/removing screw axes will result in the "loss" of 
	some systematic absence reflections, so be careful.  It is probably
	advisable to always merge in P222, and reindex later.
    
################################################################################
\${scriptDIR}shelx.com	- automatic, combinatorial shelx script

    input: data.mtz	- mtz file containing one or more data sets
    output: shelx.pdb	- PDB file containing shelx sites and peaks
    
    usage: \${scriptDIR}shelx.com data.mtz P212121 Fname 1s 4A 3 sites diff 200  no Fbad
    where:
	Fname - dataset or dataset pair you specifically want to use
	1s    - sigma cutoff
	4A    - resolution cutoff
	diff #- maximum difference cutoff (default: auto)
	sites - specify number of expected sites (3 above)
	Fbad  - dataset or dataset pair you do not want to use

    examples:
	shelx.com mtz/Fpp.mtz 
	  - use DANO from mtz/Fpp.mtz as the shelx data set
	shelx.com mtz/Fp.mtz mtz/Flo.mtz
	  - use both DANO data sets, as well as F-F between the two mtzs.
	shelx.com mtz/FH.mtz 
	  - use FH in mtz/FH.mtz (no DANO present)
	shelx.com mtz/FH.mtz 0s 1s 2s 4A 3A 2A 5 sites
	  - use sigma cutoffs of 0.0, 1.0, 2.0, and resolution cutoffs of
	    4, 3, and 2A in all possible combinations.  Looking for 5 sites.
	shelx.com mtz/all.mtz no DANOFlo Flo-Fhi
	  - use all difference data in mtz/all.mtz, except for DANOFlo and
	    the difference between Flo and Fhi
	shelx.com mtz/all.mtz P222 P212121 P21212 P21221 P22121 P21212
	  - try all the listed space groups, permuting axes appropriately
	shelx.com mtz/all.mtz /programs/bin/shelxs
	  - different location of shelxs executable
	
    description:
	shelx.com is designed to be an exhaustive, combinatorial interface
	to direct-methods heavy-atom finding with shelx.  Multiple space
	groups, sigma cutoffs, resolution cutoffs, maximum difference
	cutoffs, data files and target numbers of sites can all be specified, 
	and every combination of the specified parameters will be tried, 
	in turn.  This can, of course, take some time.  The terminal output
	from shelx.com is formatted so that you can cut-and-paste it as
	command-line arguments to a second run of shelx.com, if you want
	to re-run a particular combination.
	  The atoms positions reported by shelx are filtered for non-special
	positions, and then checked against a Patterson map generated with
	the same data that was provided to shelx.  The CCP4 program "vecref"
	is used to reject atoms that do not agree with the Patterson.
	  The output shelx.pdb file contains the shelx peak-heights/10 as
	the B-factor column, and the "occupancy" (refined by vecref) in the
	occupancy column.  Atoms on special positions are listed, but with
	zero occupancy.  
	  shelx.pdb is written whenever the sum of the products of the shelx 
	peak-heights and the Patterson "occupancies" exceeds the "last" 
	shelx.pdb written.  It is not clear if this is the "best" scoring 
	function, but you can always re-run a single-pass shelx.com run to 
	reproduce any combinations that you are curious about.

################################################################################
\${scriptDIR}rantan.com	- automatic, combinatorial rantan script

    input: data.mtz	- mtz file containing one or more data sets
    output: rantan.pdb	- PDB file containing possible heavy-atom sites
    
    usage: \${scriptDIR}rantan.com data.mtz P212121 Fname 1s 4A 3 sites diff 200  no Fbad
    where:
	Fname - dataset or dataset pair you specifically want to use
	1s    - sigma cutoff
	4A    - resolution cutoff
	diff #- maximum difference cutoff (default: auto)
	sites - specify number of expected sites (3 above)
	Fbad  - dataset or dataset pair you do not want to use

    examples:
	see shelx.com (above)
	
    description:
	rantan.com is essentially identical to shelx.com (above), except
	that it uses the CCP4 program "rantan" instead of shelx to calculate
	direct phases.  In this case peaks are picked from an E-Fourier of
	the deduced phases, and then subjected to the "Patterson filter"
	in vecref.  The output file: rantan.pdb contains the height/sigma
	peak heights in the E-Fourier as the B-factor column and the 
	"vecref occupancy" in the occupancy column. 
    
################################################################################
\${scriptDIR}rrsps.com	- Recursive Real-Space Patterson Search

    input: Patt.map	- Patterson map file to be deconvoluted
	   boring.pdb	- PDB file containing "uninteresting" sites (to be ignored)
    output: pick.pdb	- PDB file containing picked peaks
    
    usage: \${scriptDIR}rrsps.com FH_Patt.map P212121 P222
    where:
    FH_Patt.map	- is a CCP4 Patterson map 
    P212121	- is the space group you want to try
    
    examples:
	rrsps.com FH_Patt.map P212121 P222
	  - will run a recursive rsps procedure on FH_Patt.map in P212121 and
	    in P222

    description:
	rrsps.com is a recursive shell script.  It actuall calls itself.
    
################################################################################
\${scriptDIR}pick.com	- sophisticated peak-picker

    input: pickme.map	- map file to be picked (must cover at least one asu)
	   boring.pdb	- PDB file containing "uninteresting" sites (to be ignored)
    output: pick.pdb	- PDB file containing picked peaks
    
    examples: 
	\${scriptDIR}pick.com FH_Four.map o/sites.pdb
	  - will pick peaks in FH_Four.map that aren't already within a grid
	    unit or so of atoms in o/sites.pdb
	\${scriptDIR}pick.com FH_Four.map
	  - just pick peaks in the map
	\${scriptDIR}pick.com FH_Patt.map
	  - pick unique peaks in the Patterson map, displaying multiplicities
    
    description:
	pick.com does more than a simple "peakmax" run.  The actual pick is
	performed on a map of one asu, plus a 10% "buffer zone" padding the
	outside of the asu.  After the peakmax run, peaks picked outside the
	asu are thrown out.  After that, the remaining peaks are symmeytry-
	expanded and checked against each other to make sure none of their
	symmetry mates overlap. 
	
	This procedure prevents false, "map-edge" peaks from being picked near 
	the edges of the asymmetric unit, and it also gaurentees that none of 
	the output peaks are symmetry mates of each other.  
	
	Peaks on special positions are printed out with occupancies < 1.  The
	B-factor column of pick.pdb contains the height/sigma of the peak.
	
	Including the "boring.pdb" on the command line allows you to specify 
	atom locations that you aren't interested in seeing in the pick.pdb 
	output file (including all their symmetry mates).  This is useful in 
	picking difference Fouriers, which will already have large peaks for 
	the sites used to obtain the phases.
    
################################################################################
\${scriptDIR}oasis.com	- experimental OASIS script

    input: sad.mtz	- mtz file containing anomalous differences
	   mlphare.com	- mlphare script containing refined sites
    output: oasised.mtz	- same as sad.mtz, but with improved phases
    
    examples: 
	\${scriptDIR}oasis.com mtz/Fpp.mtz scripts/mlphare.com
	  - will convert the sites refined by scripts/mlphare.com and put
	    them into oasis.
	\${scriptDIR}oasis.com mtz/Fpp.mtz scripts/mlphare.com 8.76e
	  - same thing, but use an f'' value of 8.76 (otherwise, use
	    the refine occupancy from mlphare)
    
    description:
	oasis is new in CCP4 4.0.  It uses a direct-phasing equation to try
	and resolve the bimodal phase distributions you get with Single-
	Anomalous Difference (SAD) data or SIR data.  oasis has demonstrated
	the ability to substantially improve SAD phases, but Phaser Elves do
	not have enough experience with it to make it the default for SAD
	data.  The results in oasised.mtz can then be solvent-flattened with
	dm.com (above).
    
################################################################################

3)  What about all these data files?

    Phaser Elves do produce a lot of different kinds of output.  This is mainly
    for your convenience, to make reviewing Phaser's exploratoins easy.  Once
    you have seen a map you can interpret, you can go ahead and delete most of
    these files.  Here is a quick review of what all the files are for:
    
    Heavy-atom positions:
	\${scriptfile}
	- contains heavy-atom positions, as well as a record of all positons that
	  were added or removed from the starting script by Phaser Elves.  These
	  "BADATOM" and "OLDATOM" positions are avoided when picking the difference
	  Fourier.
	\${scriptDIR}sites.mlphare
	- contains a symmetry-reduced version of the "good" sites in mlphare.com.
	  Atoms that are close enough to be indistinguishable (separation < d/3)
	  are "merged", giving you an "average" site constellation across all
	  derivatives.  This is useful for re-inputting a unique list of sites
	  back into Phaser.
	\${oDIR}sites.pdb
	- same as \${scriptDIR}sites.mlphare, but in PDB format.

    Phased data:
	\${mtzDIR}mlphare.mtz
	- the output file from the most recent mlphare run.
	\${mtzDIR}dm_##.mtz	    
	- results from a ##%-solvent dm run on mlphare.mtz.
	\${mtzDIR}best_phased.mtz
	- a copy of what Phaser Elves consider the "best" solution
    
    Maps:
	\${mapDIR}best_phased.map
	- a copy of what Phaser Elves consider the "best" map (CCP4 format).
	\${mapDIR}phased.map
	- the most-recently calculated map (usually from one of the dm_##.mtz files)
    
    O stuff:
	\${oDIR}phased.omap
	- an "o version" of \${mapDIR}phased.map, (dsn6 or brix format) extended
	  to cover 1.7 unit cells (one cell, plus 10% in every direction). 
	\${oDIR}bones.o
	- a simple bones trace of \${oDIR}phased.omap (molecule name: SKEL)
	\${oDIR}pick.pdb
	- a peak-pick of the area covered by \${oDIR}phased.omap.  Useful for
	  providing atoms to cen_id on while you review the map in o.
	\${oDIR}sites.pdb
	- a simple PDB file of where the mlphare-refined sites ended up.
	\${oDIR}latest.omacro
	- an o macro for loading and displaying all of the above files.
	\${oDIR}latest
	- sub-macro for just loading \${oDIR}phased.omap
	\${oDIR}best_*
	copies of the above files ultimately calculated from \${mtzDIR}best_phased.mtz
	\${oDIR}best.omacro
	- an o macro for loading and displaying the best_* files.
	\${oDIR}allmaps.omacro
	- an o "super-macro" for displaying all of the alternative "flip"
	  combinations (one at a time) with a single command.
    
    
    Sign/hand flipping results:
	Files like:
	mlphare.com.flip_-hand_+occ or flip_-hand_+occ_phased.map
	- are copies of mlphare.com or phased.map (respectively) that were 
	  calculated for a particular combination of hand, sign and/or space
	  group conventions.  All indications are relative to the initial site
	  constellation provided to/found by Phaser Elves (+hand_+occ).  If you
	  have a chiral space group (i.e. P41/P43), then the space group name
	  is used in place of "flip".
	  
	- under the \${oDIR} directory, however, files are not renamed, but moved
	  into a subdirectory called \${oDIR}flip_+hand_+occ/.  This makes it
	  easy to change "flip states" by just "cd"-ing to the various directories
	  
    
    Deleting files:
	  Once you are satisfied that you have found an interpretable map 
	  (let's say its in flip_+hand_-occ/, at 45% solvent), 
	  then you can type this:
	  
	  # save the script
	cp \${scriptfile}.flip_+hand_-occ \${scriptfile}
	cp \${scriptDIR}sites_flip_+hand_-occ.mlphare \${scriptDIR}sites.mlphare 
	rm \${scriptfile}.*
	rm \${scriptDIR}sites_*
	
	  # save the data (this file contains the mlphare and dm results)
	cp \${mtzDIR}dm_45_flip_+hand_-occ.mtz \${mtzDIR}best_phased.mtz
	rm \${mtzDIR}dm_* \${mtzDIR}mlphare* 
	
	  # maybe save the CCP4 map
	cp \${mapDIR}flip_+hand_-occ_phased.map \${mapDIR}best_phased.map
	rm \${mapDIR}flip*
	
	  # then take care of the \${oDIR} directory
	cd \${oDIR}
	cp flip_+hand_-occ/* .
	rm -r flip*
	rm best*
	cd ..
	
	  this is easier than re-naming all the proper files by hand.
	  After all that, you should have reduced your disk consumption quite
	  a bit, and running \${oDIR}latest.omacro will display the results
	  of the flip_+hand_-occ run.
	  
################################################################################


4) What if something goes wrong?

    The Phaser elves have been trained to handle a number of common problems 
encountered in using mlphare.  However, if something happens that
is beyond their experience, they will quit, and display the error message they
couldn't understand.  It's up to you to edit \$scriptfile, and get it working
again.  However, once you do, you can feed the (runnable) \$scriptfile back to
Phaser Elves, and let them tune it up.


5) tips and tricks:

If you start Phaser Elves with "hurry" they will relax their convergence
criteria for mlphare, and finish the refinement earlier.

If you start Phaser Elves with "no flip" they won't try exploring all the
alternative possibilities of sign, hand and space group.

If you start Phaser Elves with "no add" they will exit after picking peaks
in the first difference Fourier they calculate.

If you start Phaser Elves with "6 params" on their command line, they will
begin by refining x, y, z, occ, aocc, and Bfac for all atoms, instead of 
starting with x, y, z only, and working their way up.

---
EOF












write_moreatoms:
########################################################################################################

# don't overwrite user-modified script
if(-e \${scriptDIR}moreatoms.com) goto write_reindex

#echo "writing \${scriptDIR}shelx.com "
cat << EOF-shelxscript >! \${scriptDIR}shelx.com
#! /bin/csh -f
#
#
#	shelx.com	- combinatorial shelx-based heavy-atom finder
#
#   will try all possible combinations of an arbitrary number of:
#   1) space groups
#   2) data sets (multiple mtz files are okay)
#   3) resolution cutoffs
#   4) F/sigma cutoffs
#   5) maximum delta-F cutoffs (default to a reasonable value)
#   6) expected site counts
#
#   the results of each shelx run are also passed through the CCP4 "vecref"
#   program, using a Patterson calculated with the same data presented to
#   shelx.  Sites that don't agree with the Patterson are rejected by vecref.
#
#   a pdb file ("outfile" below) is produced for each combinatorial run
#
#   "good" shelx sites are in chain:   D
#   "maybe" shelx sites are in chain:  Q
#   sites on special positons are in:  X
#
#   however, this pdb file will be overwritten if the peak heights look
#   "better" than the last "best" soluton.
#
#   the output lines that this script prints to the terminal can each be
#   used as command-line input to re-run the same procedure, updating the
#   output file.
#
# location of shelxs executable
set SHELX = \$SHELX
set prefix = "shelx"

# location of awk
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set mtzfile  = ./mtz/all.mtz
set outfile  = shelx.pdb
set logfile  = \${logDIR}shelx.log
set tempfile = ./shelx_temp

# crystal variables
set hiRES = ""
set loRES = 1000
set CELL  = ""
set SG    = ""
set Ee    = "Se"

# trials
set SGs           = ""
set RESOs         = ""
set target_sites  = "1 3 5 10 15 20"
set sigma_cutoffs = "0 1 2 3"
set max_diffs     = "auto"

# no args? need help
if(\\\$#argv == 0) goto Help

# this procedure (re)sets most of the above variables
# from either the provided files, or the command line
goto Setup

Help:
cat << EOF

usage: \\\$0 data.hkl 6 sites P212121

where:
data.mtz	- contains the F, Fs, or Dano you want to run shelx on
6 sites		- your expected number of sites
2A		- your desired resolution cutoff
1sig		- your desired F/sigma cutoff
diff 50		- your desired maximum-difference cutoff
P212121		- space group (optional)

\\\$0 will run shelxs (direct phasing) on the data provided in the
space group(s) given.

EOF

exit
#
#   This procedure (at the bottom of the script) does the following
#   1) scan the command line for the mtz file(s)
#   2) set the CELL, SG, and other variables
#   3) generate dataset list file: \\\${tempfile}datasets
Return_from_Setup:

################################################################################
# back-up values (shouldn't be empty)
if("\\\$SGs" == "")           set SGs           = "\\\$SG"
if("\\\$RESOs" == "")         set RESOs         = \\\`echo "\\\$hiRES 0.1 4" | nawk '\\\$3-1>0{v=1;vstep=(1-\\\$2)/(\\\$3-1); for(i=1;i<=\\\$3;++i){printf "%.1f ", (v*1/(\\\$1^3))^(-1/3);v-=vstep;}}'\\\`
if("\\\$RESOs" == "")         set RESOs         = "\\\$hiRES"
if("\\\$sigma_cutoffs" == "") set sigma_cotoffs = "1"
if("\\\$target_sites" == "")  set target_sites  = "1"
if("\\\$max_diffs" == "")     set max_diffs     = "auto"

# print intended combinatorial
cat << EOF | tee \\\$logfile
          SGs: \\\$SGs
  reso limits: \\\$RESOs
sigma cutoffs: \\\$sigma_cutoffs
 target sites: \\\$target_sites
    max diffs: \\\$max_diffs
EOF
echo -n "    data sets: " | tee -a \\\$logfile
cat \\\${tempfile}datasets |\\\\
nawk 'NF==4{print \\\$2,"from",\\\$4} NF>4{print \\\$2 "-" \\\$5,"from",\\\$4,\\\$7} {printf "               "} END{print ""}' |\\\\
tee -a \\\$logfile

echo "running SHELX:            ---- cutoffs ------           shelx results   Patterson-check"
echo "spacegroup data set       reso  sigma maximum    expect found    CFOM  survivors  avg  max  mtz file(s)"


################################################################################
# explore all indicated possibilities
foreach SG ( \\\$SGs )
    # retrieve ASU count in this space group
    set ASU_per_CELL = \\\`nawk -v SG=\\\$SG '\\\$4==SG{print \\\$2}' \\\$CLIBD/symop.lib | head -1\\\`
    
    
foreach dataset ( \\\`nawk '{print NR}' \\\${tempfile}datasets\\\` )

    # extract labels from the "dataset" file
    set F1    = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$2}' \\\${tempfile}datasets\\\`
    set SIGF1 = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$3}' \\\${tempfile}datasets\\\`
    set mtz1  = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$4}' \\\${tempfile}datasets\\\`
    
    set F2    = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$5}' \\\${tempfile}datasets\\\`
    set SIGF2 = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$6}' \\\${tempfile}datasets\\\`
    set mtz2  = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$7}' \\\${tempfile}datasets\\\`
        
    # (F or D)
    set type  = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$1}' \\\${tempfile}datasets\\\`
    
    if("\\\$F2" == "") then
	set F2 = "\\\$F1"
	set SIGF2 = "\\\$SIGF1"
	set mtz2  = "\\\$mtz1"
	unset SUBTRACT
    else
	# need to do the subtraction
	set SUBTRACT
    endif
    
    # check for orthorhombic "pseudo-spacegroups"
    set axes = ""
    set realSG = "\\\$SG"
    if("\\\$SG" == P222)    set axes = "a b c"
    if("\\\$SG" == P212121) set axes = "a b c"
    if("\\\$SG" == P2221) then
	# P2221 with screw along longest axis
	set axes  = "a b c"
	set realSG = "P2221"
    endif
    if("\\\$SG" == P2212) then
	# P2221 with screw along mid-length axis
	set axes  = "b c a"
	set realSG = "P2221"
    endif
    if("\\\$SG" == P2122) then
	# P2221 with screw along shortest axis
	set axes  = "c a b"
	set realSG = "P2221"
    endif
    
    if("\\\$SG" == P21212) then
	# P21212 with non-screw along longest axis
	set axes  = "a b c"
	set realSG = "P21212"
    endif
    if("\\\$SG" == P21221) then
	# P21212 with non-screw along mid-length axis
	set axes  = "b c a"
	set realSG = "P21212"
    endif
    if("\\\$SG" == P22121) then
	# P21212 with non-screw along shotest axis
	set axes  = "c a b"
	set realSG = "P21212"
    endif
    set realSGnum = \\\`nawk -v SG=\\\$realSG '\\\$4==SG{print \\\$1;exit}' \\\${CLIBD}/symop.lib\\\`
    
    if("\\\$axes" != "") then
	# we have an asymmetric orthorhombic space group 
	set i = 0
	foreach mtz ( \\\$mtz1 \\\$mtz2 )
	    @ i = ( \\\$i + 1 )
	    # get current axis ordering, then
	    # find out what the cannonical one would be
	    # then decide how to go from current ordering to the desired one
	    echo "head" |\\\\
	    mtzdump hklin \\\$mtz |\\\\
	    nawk '/Cell Dimensions/{getline;getline;print}' |\\\\
	    nawk '{\\\\
		# print out current axis order \\\\
		print \\\$1, "h"; print \\\$2, "k"; print \\\$3, "l"}' |\\\\
	    sort -n |\\\\
	    nawk '\\\\
		# add cannonical axis names\\\\
		NR==1{print \\\$0, "a"} NR==2{print \\\$0, "b"} NR==3{print \\\$0, "c"}' |\\\\
	    nawk -v axes="\\\$axes" 'BEGIN{split(axes, abc)} {\\\\
		# write desired axis ordering in front of cannonical one \\\\
		print abc[NR], \\\$0}' |\\\\
	    sort |\\\\
	    nawk '# print out new hkl order \\\\
	          {printf "%s ", \\\$3} END{print ""}' |\\\\
	    nawk '\\\$1 \\\$2 \\\$3 \\\$1 \\\$2 \\\$3 !~ /hkl/{\\\$3 = "-" \\\$3} {print "reindex", \\\$1",",\\\$2",",\\\$3}' |\\\\
	    reindex HKLIN \\\$mtz HKLOUT \\\${tempfile}.mtz >> \\\$logfile

	    # this should give us a mapping between any two orthorhombics

	    # now simply re-name the space group in the header
	    echo "SYMM \\\$realSGnum" |\\\\
	    mtzutils HKLIN \\\${tempfile}.mtz HKLOUT \\\${tempfile}mtz\\\${i}.mtz >> \\\$logfile
	    if(\\\$status) then
		set BAD
		goto Clean_up
	    endif
	    rm -f \\\${tempfile}.mtz >& /dev/null
	end
    else
	# just re-name the space group in each mtz header
	echo "SYMM \\\$realSGnum" |\\\\
	mtzutils HKLIN \\\$mtz1 HKLOUT \\\${tempfile}mtz1.mtz >> \\\$logfile
	if(\\\$status) then
	    set BAD
	    goto Clean_up
	endif
	echo "SYMM \\\$realSGnum" |\\\\
	mtzutils HKLIN \\\$mtz2 HKLOUT \\\${tempfile}mtz2.mtz >> \\\$logfile
	if(\\\$status) then
	    set BAD
	    goto Clean_up
	endif
    endif
    

    # extract the two datasets into a single file
    cad hklin1 \\\${tempfile}mtz1.mtz hklin2 \\\${tempfile}mtz2.mtz \\\\
        hklout \\\${tempfile}cadded.mtz << EOF-cad >> \\\$logfile
    LABIN FILE 1 E1=\\\$F1  E2=\\\$SIGF1
    CTYPI FILE 1 E1=F    E2=Q
    LABOU FILE 1 E1=F1   E2=SIGF1
    LABIN FILE 2 E1=\\\$F2  E2=\\\$SIGF2
    CTYPI FILE 2 E1=F    E2=Q
    LABOU FILE 2 E1=F2   E2=SIGF2
EOF-cad
    
    # make sure we have the proper cell
    set CELL  = \\\`echo "head" | mtzdump hklin \\\${tempfile}cadded.mtz | nawk '/Cell Dimensions/{getline;getline;print}'\\\`
    
    # come up with a reasonable protein size (assume Vm=2.5)
    echo \\\$CELL |\\\\
    nawk 'NF==6{s=3.1415926535897899419/180; A=cos(s*\\\$4); B=cos(s*\\\$5); G=cos(s*\\\$6); \\\\
     skew = 1 + 2*A*B*G - A*A - B*B - G*G ; if(skew < 0) skew = -skew;\\\\
     printf "%.3f\\\\n", \\\$1*\\\$2*\\\$3*sqrt(skew)}' |\\\\
    cat >! \\\${tempfile}volume
    set CELLvolume = \\\`cat \\\${tempfile}volume\\\`
    rm -f \\\${tempfile}volume >> /dev/null
        
    # estimate no of protein atoms in cell assume Vm=2.5 and protein atom = 14 amu
    set protein = \\\`echo "\\\$CELLvolume \\\$ASU_per_CELL" | nawk '\\\$2+0>0{printf "%d", (((\\\$1+1)/2.5)/14)/\\\$2}'\\\`
    if("\\\$protein" == "") set protein = 2000
    #echo "we estimate \\\$protein protein atoms in ASU."


    # iterate over resolution cutoffs
    foreach cutRES ( \\\$RESOs )
    
    # apply scaleit (to scale isomorphous differences, and check DIFF recommendation)
    if(\\\$?SUBTRACT) then
	set refine = "refine anisotropic"
	set scale  = ""
    else
	# either Dano or FH data (squash F2)
	set refine = "analyze"
	set scale  = "SCALE FPH1 0.000001"
    endif
    scaleit hklin \\\${tempfile}cadded.mtz \\\\
            hklout \\\${tempfile}scaled.mtz << EOF-scale | tee \\\${tempfile}scaleit.log >> \\\$logfile
    RESOLUTION 1000 \\\$cutRES
    \\\$refine
    \\\$scale
    LABIN FP=F1 SIGFP=SIGF1 FPH1=F2 SIGFPH1=SIGF2
EOF-scale
    
    # iterate over sigma- and maximum-difference cutoffs
    foreach cutSIG ( \\\$sigma_cutoffs )
    foreach diff ( \\\$max_diffs )
    
    # use scaleit's recommendation by default
    if("\\\$diff" == "auto") set diff = \\\`nawk '/acceptable differences/{print \\\$NF}' \\\${tempfile}scaleit.log\\\`
    if("\\\$diff" == "") set diff = 99999999
    
    # make a Patterson map
    set labin = "F1=F1 SIG1=SIGF1 F2=F2 SIG2=SIGF2"
    if(\\\$?SUBTRACT) then
	set scale = 1
	set fftmtz = \\\${tempfile}scaled.mtz
    else
	# F2 is zero (for calculating DIFF)
	set scale = 0.0000001
	set fftmtz = "\\\${tempfile}cadded.mtz"
    endif
    fft HKLIN \\\$fftmtz MAPOUT \\\${tempfile}patt.map << EOF-fft >> \\\$logfile
    TITLE \\\${cutRES}A Patterson of \\\$F1-\\\${scale}\\\$F2 excluding diff>\\\$diff
    RESOLUTION \\\$cutRES
    PATTERSON
    LABIN \\\$labin
    SCALE F2 \\\$scale 0
    EXCLUDE DIFF \\\$diff
    EXCLUDE SIG1 \\\$cutSIG
EOF-fft
    # normalize the Patterson
    echo "scale sigma" |\\\\
    mapmask mapin  \\\${tempfile}patt.map \\\\
           mapout \\\${tempfile}.map >> \\\$logfile
    mv \\\${tempfile}.map \\\${tempfile}patt.map
    if(\\\$?user_patt) then
	# option to use an outside Patterson?
	cp \\\$user_patt \\\${tempfile}patt.map
    endif
    
    # extract the dataset in shelx format
    set exportmtz = "\\\$fftmtz"
    set labin = "FP=F1 SIGFP=SIGF1"
    if(\\\$?SUBTRACT) set labin = "\\\$labin FPH=F2 SIGFPH=SIGF2"
    if("\\\$type" == "D") then
	# make sure we treat Danos properly
	set labin = "DP=\\\$F1 SIGDP=\\\$SIGF1"
	set exportmtz = \\\${tempfile}mtz1.mtz
    endif

    
    mtz2various hklin \\\$exportmtz hklout \\\${tempfile}.hkl << EOF >> \\\$logfile
    OUTPUT SHELX
    FSQUARED
    RESOLUTION \\\$cutRES
    #EXCLUDE SIGP \\\$cutSIG
    #EXCLUDE SIGH \\\$cutSIG
    EXCLUDE DIFF \\\$diff
    LABIN \\\$labin
EOF
    # strip off the text header
    nawk '! /[A-Z]/' \\\${tempfile}.hkl >! \\\${prefix}.hkl

    # use the output to make a shelx .ins file as well
    nawk '! /[A-Z]/{exit} {print}' \\\${tempfile}.hkl |\\\\
    grep -v HKLF >! \\\${prefix}.ins
    rm -f \\\${tempfile}.hkl >& /dev/null
    
    # finish it up
    echo "SFAC N \\\$Ee"    >> \\\${prefix}.ins
    echo "\\\$protein \\\$ASU_per_CELL" | nawk '{print "UNIT", sqrt(\\\$1),\\\$2}' >> \\\${prefix}.ins
    echo "OMIT \\\$cutSIG" >> \\\${prefix}.ins
    echo "TREF"         >> \\\${prefix}.ins
    echo "HKLF 4"       >> \\\${prefix}.ins
    echo "END"          >> \\\${prefix}.ins
    
    foreach expect ( \\\$target_sites )
    
    # print mini-report (suitable for re-input on command line)
    if(\\\$?SUBTRACT) then
	set dataset = "\\\${F1}-\\\${F2}"
    else
	set dataset = "\\\$F1"
    endif
    echo "\\\$SG \\\$dataset \\\$cutRES \\\$cutSIG \\\$diff \\\$expect" |\\\\
	 nawk '{printf "%-10s %-13s %4.1fA %4.1fs  diff %-5.1f %3d sites ", \\\$1, \\\$2, \\\$3, \\\$4, \\\$5, \\\$6}'
    
    # shelx wants sites in CELL not ASU
    set sites_in_cell = \\\`echo "\\\$expect \\\$ASU_per_CELL" | nawk '{print \\\$1 * \\\$2}'\\\`
    
    # edit the shelx input file
    cat \\\${prefix}.ins |\\\\
    nawk -v sites=\\\$sites_in_cell '/^UNIT/{\\\$3=sites} {print}' |\\\\
    cat >! \\\${tempfile}.ins
    mv \\\${tempfile}.ins \\\${prefix}.ins >& /dev/null
    
    #######################################
    # run shelx
    \\\${SHELX} \\\${prefix} >> \\\$logfile
    #######################################
    
    # check the results
    cat \\\${prefix}.lst |\\\\
    nawk '/Heavy-atom assignments:/{slist=1} /optimization/{slist=0}\\\\
	  /Peak  Atom     x/{plist=1}\\\\
          slist && \\\$5~/[0-9]/{++s;ssum+=\\\$6;mins=\\\$6}\\\\
	  plist && \\\$2~/^Q/{++q;qsum+=\\\$1;if(maxq+0==0)maxq=\\\$1}\\\\
          END{print "SITES", s+0; \\\\
	      if(s+0==0) s=1; savg=ssum/s;\\\\
	      if(q+0==0) q=1; qavg=qsum/q;\\\\
	      if(qavg==0) qavg=100; if(maxq+0==0)maxq=100;\\\\
	      print "HEIGHT", ssum/s, mins;\\\\
	      print "QAVG", qsum/q, maxq;\\\\
	      print "RATIO", savg/qavg;\\\\
	      print "DISCR", mins/maxq}' |\\\\
    cat >! \\\${tempfile}.results
    cat \\\${prefix}.lst |\\\\
    nawk '/with CFOM/{print "CFOM", \\\$NF+0; exit}' |\\\\
    cat >> \\\${tempfile}.results
    cat \\\${prefix}.lst |\\\\
    nawk '/Try    Ralpha Nqual/,/CFOM Range/' |\\\\
    nawk 'NF>=6 && ! /[A-Z]/{++n;sum+=\\\$6} \\\\
          END{if(n) print "meanCFOM", sum/n}' |\\\\
    cat >> \\\${tempfile}.results
    
    set found  = \\\`nawk '/^SITES/{print \\\$2}' \\\${tempfile}.results\\\`
    set DISCR  = \\\`nawk '/^DISCR/{print \\\$2}' \\\${tempfile}.results\\\`
    set RATIO  = \\\`nawk '/^RATIO/{print \\\$2}' \\\${tempfile}.results\\\`
    set bCFOM  = \\\`nawk '/^CFOM/{print \\\$2}' \\\${tempfile}.results\\\`
    set mCFOM  = \\\`nawk '/^meanCFOM/{print \\\$2}' \\\${tempfile}.results\\\`
    rm -f \\\${tempfile}.results >& /dev/null
    
    # display for user
    echo "\\\$found \\\$bCFOM " | nawk '{printf "%-4d  %4.2f  ", \\\$1, \\\$2, \\\$3 " " \\\$4 " " \\\$5}'
    
    # retrieve shelx's atoms in a more managable format
    cat \\\${prefix}.lst |\\\\
    nawk '/Heavy-atom assignments:/{list=1} /optimization/{list=0}\\\\
	  /Peak  Atom     x/{plist=1}\\\\
          list {print \\\$NF, \\\$0}\\\\
	  plist && \\\$2 ~ /^Q/{print \\\$0, \\\$1}' |\\\\
    nawk 'NF==7{n=substr(\\\$2,match(\\\$2,"[1-9]"));\\\\
                Ee=substr(\\\$2,1,match(\\\$2,"[1-9]")-1);\\\\
		x=\\\$3;y=\\\$4;z=\\\$5;occ=\\\$6;height=\\\$NF;\\\\
		chain="D"; if(Ee=="Q")chain=Ee; if(occ<1)chain="X";\\\\
    print x, y, z, occ, height/10, Ee, n, chain;}' |\\\\
    cat >! \\\${tempfile}allatoms
    # format: xf yf zf 1/mult height Ee atmno chain
    
    # use vecref to check against the Patterson
    cat \\\${tempfile}allatoms |\\\\
    nawk -v cutRES=\\\$cutRES '{++n} \\\$4 !~ /\\\\.0/{next;\\\$1+=0.001; \\\$2+=0.001; \\\$3+=0.001}\\\\
    NF>6{print "ATOM H", n, 1, \\\$1, \\\$2, \\\$3, 79*(cutRES/3)^2}' |\\\\
    cat >! \\\${tempfile}atoms.out
    set orig = \\\`cat \\\${tempfile}atoms.out | wc -l\\\`
    
    # do some cycles of atom rejection
    set rcycles = "3,0,0 3,0,0 3,10,0 3,10,0 3,0,10 3,0,10"
    set rcycles = "3,0,0 3,0,0 3,0,0"
    if(\\\$?NO_PATT) set rcycles = ""
    foreach rcycle ( \\\$rcycles )
	set rcycle = \\\`echo "\\\$rcycle" | nawk 'BEGIN{FS=","} {print \\\$1, \\\$2, \\\$3}'\\\`
	
	# reduce resolution a bit so vecref won't crash
	set refRES = \\\`echo \\\$cutRES | nawk '{print (0.8*1/(\\\$1^3))^(-1/3)}'\\\`
	
	# make sure there aren't >50 sites
	sort -n -k3 \\\${tempfile}atoms.out |\\\\
	head -50 >! \\\${tempfile}atoms.in
	
	# refine "occupancies" against the Patterson
	rm -f \\\${tempfile}atoms.out >& /dev/null
	set vecrefSG = \\\$realSG
	if("\\\$vecrefSG" == "H3") set vecrefSG = R3
	if("\\\$vecrefSG" == "H32") set vecrefSG = R32
	vecref mapin \\\${tempfile}patt.map ATOUT \\\${tempfile}atoms.out << EOF-vecref >>& \\\$logfile
	SPACEGROUP \\\$vecrefSG
	RESOLUTION \\\${refRES}
	CYCLES \\\$rcycle
	BLIMIT 0 1000
	BREF
	@\\\${tempfile}atoms.in
EOF-vecref
	if((\\\$status)||(! -e \\\${tempfile}atoms.out)) then
	    # all atoms rejected
	    echo -n "" >! \\\${tempfile}atoms.out
	    break
	endif
    end
    rm -f \\\${tempfile}atoms.in >& /dev/null
    if(\\\$?NO_PATT) then
	# no data available from Patterson
	echo -n "" >! \\\${tempfile}atoms.out
    endif
    
    # label the peaks file with the vecref occupancies
    cat \\\${tempfile}atoms.out \\\${tempfile}allatoms |\\\\
    nawk '/^ATOM/{occ[\\\$3]=\\\$4; next} {++n; print \\\$0, occ[n]+0}' |\\\\
    cat >! \\\${tempfile}atoms.pocc
    # format xf yf zf 1/mult height Ee atmno chain pocc

    rm -f \\\${tempfile}atoms.out >& /dev/null
    rm -f \\\${tempfile}allatoms >& /dev/null
    
    # print out stats
    cat \\\${tempfile}atoms.pocc |\\\\
    nawk '\\\$6~/^Q/{next} \\\$NF+0>0{++patt}\\\\
	  {++n; sum+=\\\$NF} \\\$NF>max{max=\\\$NF}\\\\
          END{printf "%d ", patt; if(n==0)n=1; print sum/n, max+0}' |\\\\
    cat >! \\\${tempfile}.results
    if(\\\$?NO_PATT) then
	# fake it, but let user know nothing happened
	echo "? 0 0" >! \\\${tempfile}.results
    endif
    set patt = \\\`nawk '{print \\\$1}' \\\${tempfile}.results\\\`
    set avg  = \\\`nawk '{print \\\$2}' \\\${tempfile}.results\\\`
    set max  = \\\`nawk '{print \\\$3}' \\\${tempfile}.results\\\`
    rm -f \\\${tempfile}.results >& /dev/null

    # print out for user
    echo "\\\$patt \\\$orig \\\$avg \\\$max" | nawk '{printf "%9s %4.1f %4.1f ", \\\$1"/"\\\$2, \\\$3, \\\$4}'
    
    # print out data files used
    set mtzfiles = "\\\$mtz1"
    if("\\\$mtz2" != "\\\$mtz1") set mtzfiles = "\\\$mtz1 \\\$mtz2"
    echo -n " \\\$mtzfiles "
    
    
    # come up with some kind of holistic "score"?     
    echo "\\\$expect \\\$found \\\$bCFOM \\\$patt \\\$avg \\\$max" |\\\\
    nawk '{expect=\\\$1; found=\\\$2; CFOM=\\\$3; patt=\\\$4+0; avg=\\\$5; max=\\\$6;\\\\
    sites=found; if(sites<1) sites=0.5; if(patt<1) patt=0.5;\\\\
    if(\\\$4 ~ /^\\\\?/) avg=1/CFOM;\\\\
    printf "%s %s %s ",  1/CFOM, avg*sites*sites/patt, sites*max}' |\\\\
    cat >! \\\${tempfile}.score

    # sum-of-sums score
    # format xf yf zf 1/mult height Ee atmno chain pocc
    cat \\\${tempfile}atoms.pocc |\\\\
    nawk -v expect=\\\$expect '\\\$6~/^Q/ || n>=expect{next} {++n}\\\\
	  \\\$NF*\\\$5>0{sum+=\\\$NF+\\\$5; sum_s+=\\\$5}\\\\
          END{if(n==0)n=1; print sum/n, sum_s}' |\\\\
    cat >! \\\${tempfile}.score

    set score = \\\`nawk '{printf "%d", 1000*\\\$1}' \\\${tempfile}.score\\\`
    set sum_s = \\\`nawk '{print \\\$2}' \\\${tempfile}.score\\\`
    rm -f \\\${tempfile}.score >& /dev/null

    # create the output pdb
    cat \\\${tempfile}atoms.pocc |\\\\
    nawk '{x=\\\$1;y=\\\$2;z=\\\$3;occ=\\\$9;B=\\\$5;\\\\
	   Ee=\\\$6;n=\\\$7;chain=\\\$8;\\\\
        printf("%5d%10.5f%10.5f%10.5f%10.5f%5.2f   35%10d%2s   SLX %1s\\\\n",\\\\
    n, x,y,z, B, occ, n, Ee, chain)}' |\\\\
    cat >! \\\${tempfile}.frac

    # make sure we've got the right cell
    set CELL  = \\\`nawk '\\\$1 == "CELL"{print \\\$3, \\\$4, \\\$5, \\\$6, \\\$7, \\\$8; exit}' \\\${prefix}.lst\\\`
    coordconv xyzin \\\${tempfile}.frac xyzout \\\${tempfile}.pdb << EOF >> \\\$logfile
    CELL \\\$CELL
    INPUT FRAC
    OUTPUT PDB ORTH 1
    END
EOF
    

    # write a descriptive header to the PDB file
    cat << EOF | nawk '{print "REMARK", \\\$0}' >! \\\${tempfile}full.pdb
results here are from:
\\\$dataset in \\\$mtzfiles at \\\${cutRES}A in \\\$SG
reflections were excluded if F/sigF < \\\$cutSIG or |delta-F| > \\\$diff
internal score: \\\$score

the B-factor column here contains the "peak height", as reported
by shelx.

the occupancy column contains the result of vector-space refinement of all
the shelx peaks against a Patterson calculated with the same data
provided to shelx.  The CCP4 program vecref will have rejected most of
the atoms, leaving non-zero "occupancy" only for sites that are consistent 
with the Patterson.

ATOMs in the "D" chain are the highest peaks in shelx's direct-phased
Fourier, and represent sites that shelx was "sure" about.

ATOMs in the "Q" chain represent peaks in shelx's direct-phased Fourier
map that may or may not be "real" atoms, but shelx printed them out anyway.

ATOMs in the "X" chain were on special positions.

the symmetry of these positions is \\\$realSG
                           X       Y       Z      occ height
EOF
    # copy over the atoms
    cat \\\${tempfile}.pdb >> \\\${tempfile}full.pdb
    rm -f \\\${tempfile}.pdb >& /dev/null
    rm -f \\\${tempfile}.frac >& /dev/null
    rm -f \\\${tempfile}.atoms >& /dev/null


    if(\\\$?debug) then
	if(! -e scores.log) touch scores.log
	cat \\\${tempfile}full.pdb |\\\\
	nawk '/^ATOM/{\\\$0=substr(\\\$0, 1, 60) " 20.00"} {print}' |\\\\
	cat >! \\\${tempfile}test.pdb
	/max/jamesh/Develop/patteq.com \\\$SG o/best_sites.pdb \\\${tempfile}test.pdb |\\\\
	nawk 'NF==1{printf " %s ", \\\$0; exit}' |\\\\
	cat >> scores.log

	echo "\\\$expect \\\$found \\\$bCFOM \\\$patt \\\$avg \\\$max \\\$sum_s" >> scores.log	
    endif
    

    if(\\\$score > \\\$best_score) then
	set best_score = \\\$score
	if(-e \\\${outfile}.older) mv \\\${outfile}.older \\\${outfile}.oldest
	if(-e \\\${outfile}.old) mv \\\${outfile}.old \\\${outfile}.older
	if(-e \\\${outfile}) mv \\\${outfile} \\\${outfile}.old
	mv \\\${tempfile}full.pdb \\\$outfile >& /dev/null
	if(! \\\$status) echo -n " (saved as \\\$outfile)"
    endif
    
    
    
    # end the line
    echo ""
    
    end	# sites
    end	# diff
    end	# cutSIG
    end	# cutRES
    
end	# dataset
end	# SG

# clean up
Clean_up:
if(\\\$?debug) exit
rm -f \\\${prefix}.hkl >& /dev/null
rm -f \\\${prefix}.ins >& /dev/null
rm -f \\\${prefix}.res >& /dev/null
rm -f \\\${prefix}.lst >& /dev/null
rm -f \\\${tempfile}atoms.pocc >& /dev/null

rm -f \\\${tempfile}patt.map >& /dev/null
rm -f \\\${tempfile}datasets >& /dev/null
rm -f \\\${tempfile}mtz1.mtz >& /dev/null
rm -f \\\${tempfile}mtz2.mtz >& /dev/null
rm -f \\\${tempfile}cadded.mtz >& /dev/null
rm -f \\\${tempfile}scaled.mtz >& /dev/null
rm -f \\\${tempfile}scaleit.log >& /dev/null
rm -f \\\${tempfile}full.pdb >& /dev/null


exit






Setup:
#################################################

  ####   ######   #####  #    #  #####
 #       #          #    #    #  #    #
  ####   #####      #    #    #  #    #
      #  #          #    #    #  #####
 #    #  #          #    #    #  #
  ####   ######     #     ####   #

#################################################
#
#   gather information on:
#    mtz file
#    data sets
#    resolution limits
#    sigma cuttoff (for map generation)
#    difference cutoff
#
##################################################
# scan the command line for files
set user_SGs   = ""
set user_sigs  = ""
set user_resos = ""
set user_diffs = ""
set user_sites = ""
set mtzfiles   = ""
set best_score = -1

foreach arg ( \\\$* )
    # warn about probable mispellings
    if("\\\$arg" =~ *.mtz) then
	if(-e "\\\$arg") then
	    set mtzfiles = "\\\$mtzfiles \\\$arg"
	else
	    echo "WARNING: \\\$arg does not exist! "
	endif
    endif
    if(("\\\$arg" =~ *shelxs)&&(-e "\\\$arg")) then
	# user-specified shelx executable
	set SHELX = "\\\$arg"
    endif
end

# use default if nothing specified
if("\\\$mtzfiles" == "") set mtzfiles = "\\\$mtzfile"

# gather data set labels, etc from the mtzs
set i = 0
echo "" >! \\\${tempfile}labels
foreach mtz ( \\\$mtzfiles )
    @ i = ( \\\$i + 1 )
    
    # dump and characterize contents
    echo "go" | mtzdump HKLIN \\\$mtz >! \\\${tempfile}mtzdump

    cat \\\${tempfile}mtzdump |\\\\
    nawk '/Cell Dimensions/{getline;getline;print "CELL", \\\$0}\\\\
	  /Space group/{print "SYMM", \\\$NF+0}\\\\
	  /Resolution Range/{getline;getline;print "RESO", \\\$4, \\\$6}' |\\\\
    cat >! \\\${tempfile}info
    
    # read in dataset info
    cat \\\${tempfile}mtzdump |\\\\
    nawk 'NF>6' |\\\\
    nawk '\\\$(NF-1)=="F"{print "F", \\\$NF, \\\$(NF-4)}\\\\
          \\\$(NF-1)=="D"{print "D", \\\$NF, \\\$(NF-4)}\\\\
          \\\$(NF-1)=="Q"{print "S", \\\$NF, \\\$(NF-4)}' |\\\\
    nawk '/^F/{++n} /^D/{++n} {printf "%s", \\\$1; \\\\
           if(\\\$1=="S") printf "%s", last;\\\\
    printf " %d %s %s\\\\n",n, \\\$2, \\\$3; last=\\\$1}' |\\\\
    cat >> \\\${tempfile}info
    
    # check for empty mtzs
    set temp = \\\`nawk '/^[FD]/' \\\${tempfile}info | wc -l\\\`
    if(\\\$temp > 0) then
	# add it to the pile
	cat \\\${tempfile}info |\\\\
	nawk -v mtz=\\\$mtz '{print \\\$0, mtz}' |\\\\
	cat >> \\\${tempfile}labels
    else
	echo "WARNING: \\\$mtz contains no useful data!"
    endif
    if(! \\\$?debug) rm -f \\\${tempfile}mtzdump >& /dev/null
    if(! \\\$?debug) rm -f \\\${tempfile}info >& /dev/null
end

# get complete, unique lists of DANOs
cat \\\${tempfile}labels |\\\\
nawk '{l= \\\$2 " " \\\$NF}\\\\
      \\\$1=="D"{D[l]=\\\$3; signal[l]=\\\$4} \\\\
      \\\$1=="SD"{S[l]=\\\$3; noise[l]=\\\$4} \\\\
      END{for(l in S){if(noise[l]+0==0) noise[i]=1; \\\\
	print "D", D[l], S[l], signal[l]/noise[l], l}}' |\\\\
nawk 'NF==6' |\\\\
sort -nr -k3 >! \\\${tempfile}mtzlabels

# get complete, unique lists of Fs
cat \\\${tempfile}labels |\\\\
nawk '{l= \\\$2 " " \\\$NF}\\\\
      \\\$1=="F"{F[l]=\\\$3; signal[l]=\\\$4} \\\\
      \\\$1=="SF"{S[l]=\\\$3; noise[l]=\\\$4} \\\\
      END{for(l in S){if(noise[l]+0==0) noise[l]=1; \\\\
	print "F", F[l], S[l], signal[l]/noise[l], l}}' |\\\\
nawk 'NF==6' |\\\\
sort -nr -k3 >> \\\${tempfile}mtzlabels

# reconcile different cells? SGs?
set CELL  = \\\`nawk '/^CELL/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7; exit}' \\\${tempfile}labels\\\`
set SG    = \\\`nawk '/^SYMM/{print \\\$2; exit}' \\\${tempfile}labels\\\`
set SGnum = \\\`nawk '/^SYMM/{print \\\$2; exit}' \\\${tempfile}labels\\\`
set SG    = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set hiRES = \\\`nawk '/^RESO/{print \\\$3}' \\\${tempfile}labels | sort -n | head -1\\\`

if(! \\\$?debug) rm -f \\\${tempfile}labels >& /dev/null


set mtzlabels = \\\`cat \\\${tempfile}mtzlabels | wc -l\\\`
if("\\\$mtzlabels" == 0) then
    echo "no usefult data in \\\$mtzfiles "
    goto Help
endif

##################################################
# get crystal and dataset information from the final mtz file


# make a two-way difference-dataset list (for recognition)
cat \\\${tempfile}mtzlabels |\\\\
nawk '\\\$1=="F"{++n; set[n]= \\\$2 " " \\\$3 " " \\\$NF;\\\\
      for(i=1;i! \\\${tempfile}Fpairs


# one last pass through command line
# allow user overrides of all internal variables
set i = 0
echo -n "" >! \\\${tempfile}userlabels
echo -n "" >! \\\${tempfile}userpairs
echo -n "" >! \\\${tempfile}not_pairs
while( \\\$i < \\\$#argv )
    @ i = ( \\\$i + 1 )
    @ nexti = ( \\\$i + 1 )
    @ lasti = ( \\\$i - 1 )
    if(\\\$nexti > \\\$#argv) set nexti = \\\$#argv
    if(\\\$lasti < 1) set lasti = 1
    set arg = "\\\$argv[\\\$i]"
    
    # check for space groups
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	set temp = \\\`nawk -v SG=\\\$temp '\\\$4 == SG {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
	if("\\\$temp" == "") then
	    # check for "pseudo-spacegroup" language
	    set temp = \\\`echo "\\\$arg" | nawk 'toupper(\\\$1) ~ /[PC]2212|[PC]2122|P21221|P22121/'\\\`
	    # these are okay too, reindexing engine will understand
	endif
	if("\\\$temp" != "") then
	    # add this SG to the space group list
	    set user_SGs = "\\\$user_SGs \\\$temp"
	    continue
	endif
    endif
    
    # only look at non-file words
    if(! -e "\\\$arg") then
	# see if a dataset label was given
	set temp = \\\`nawk -v arg=\\\$arg '\\\$2==arg' \\\${tempfile}mtzlabels | wc -l\\\`
	if(\\\$temp) then
	    # a dataset label was mentioned
	    if(\\\$?NO) then
		# user doesn't want this label
		# filter it out of the input files
		nawk -v arg=\\\$arg '\\\$2!=arg' \\\${tempfile}mtzlabels >! \\\${tempfile}
		mv \\\${tempfile} \\\${tempfile}mtzlabels
	    else
		# must want only this label?
		nawk -v arg=\\\$arg '\\\$2==arg' \\\${tempfile}mtzlabels |\\\\
		cat >> \\\${tempfile}userlabels
	    endif
	    continue
	endif
    	
	# see if a difference-dataset label was given
	set temp = \\\`nawk -v arg=\\\$arg '\\\$2 "-" \\\$5 == arg{print \\\$2, \\\$5; exit}' \\\${tempfile}Fpairs\\\`
	if(\\\$#temp == 2) then
	    # a specific difference dataset was mentioned
	    if(\\\$?NO) then
		# user doesn't want this label pair
		# filter it out of the input files
		echo "NOT_A_PAIR \\\$temp" >> \\\${tempfile}not_pairs
	    else
		# must want only this pair (in this order)?
		cat \\\${tempfile}Fpairs |\\\\
		nawk -v F1=\\\$temp[1] -v F2=\\\$temp[2] '\\\$2==F1 && \\\$5==F2' |\\\\
		cat >> \\\${tempfile}userpairs
	    endif
	    continue	    
	endif
	
	# program options
	if("\\\$arg" =~ [Pp]att*) then
	    if(\\\$?NO) then
		set NO_PATT
	    else
		unset NO_PATT
	    endif
	endif
	
	# check for 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
				set loRES = "\\\$temp[1]"
				set user_resos = "\\\$user_resos \\\$temp[2]"
				continue
		    endif
		else
		    if("\\\$temp" != "") set user_resos = "\\\$user_resos \\\$temp"
		    continue
		endif
	    endif
	    
	    if(("\\\$arg" =~ *[0-9][Ss]*)||("\\\$argv[\\\$nexti]" =~ [Ss]igma)) then
		set user_sigs = "\\\$user_sigs "\\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    
	    if(("\\\$argv[\\\$nexti]" =~ [Ss]ite)||("\\\$argv[\\\$nexti]" =~ [Ss]ites)) then
		set user_sites = "\\\$user_sites "\\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    
	    if(("\\\$arg" =~ *[Dd]iff)||("\\\$argv[\\\$lasti]" =~ [Dd]iff)) then
		set user_diffs = "\\\$user_diffs "\\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    if(("\\\$arg" =~ *[Dd]iso)||("\\\$argv[\\\$lasti]" =~ [Dd]iso)) then
		set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    if(("\\\$arg" =~ *[Dd]ano)||("\\\$argv[\\\$lasti]" =~ [Dd]ano)) then
		set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	endif
	
	# allow "NO" logic to carry through
	unset NO
	if(("\\\$arg" == "no")||("\\\$arg" == "not")) set NO
	if(("\\\$arg" == "don't")||("\\\$arg" == "ignore")) set NO
	if("\\\$arg" == "except") set NO
    endif
end

# honor user requests (when mentioned)
if("\\\$user_SGs"   != "") set SGs           = "\\\$user_SGs"
if("\\\$user_resos" != "") set RESOs         = "\\\$user_resos"
if("\\\$user_sigs"  != "") set sigma_cutoffs = "\\\$user_sigs"
if("\\\$user_diffs" != "") set max_diffs     = "\\\$user_diffs"
if("\\\$user_sites" != "") set target_sites  = "\\\$user_sites"


# check the "user" labels
sort -u -k6 \\\${tempfile}userlabels >! \\\${tempfile}mtzs
sort -u -k6 \\\${tempfile}mtzlabels >> \\\${tempfile}mtzs
cat \\\${tempfile}mtzs |\\\\
nawk '{++seen[\\\$6]} END{for(mtz in seen) if(seen[mtz]==1) print mtz}' |\\\\
cat >! \\\${tempfile}orphans

foreach mtz ( \\\`cat \\\${tempfile}orphans\\\` )
    # some mtzs were mentioned, but aren't in \\\${tempfile}userlabels
    # so, we'll just assume everything in them was wanted
    cat \\\${tempfile}mtzlabels |\\\\
    nawk -v mtz=\\\$mtz '\\\$6==mtz' |\\\\
    cat >> \\\${tempfile}userlabels
end
if(! \\\$?debug) rm -f \\\${tempfile}orphans   >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}mtzlabels >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}mtzs      >& /dev/null

# make sure no label is mentioned twice
cat \\\${tempfile}userlabels |\\\\
nawk '! seen[\\\$2 " " \\\$NF]{print} {++seen[\\\$2 " " \\\$NF]}' |\\\\
cat >! \\\${tempfile}
mv \\\${tempfile} \\\${tempfile}userlabels

# organize user's desired labels into difference-data sets
cat \\\${tempfile}userlabels |\\\\
nawk '\\\$1=="F"{++n; set[n]= \\\$2 " " \\\$3 " " \\\$NF;\\\\
      for(i=1;i! \\\${tempfile}Fpairs

# see if user had particular pairing in mind
set temp = \\\`cat \\\${tempfile}userpairs | wc -l\\\`
if(\\\$temp) then
    # this overrides the Fpairs we just generated
    cat \\\${tempfile}userpairs >! \\\${tempfile}Fpairs
    
    # also any user-specified individual labels must be lone Fs? 
    cat \\\${tempfile}userlabels |\\\\
    nawk '\\\$1=="F"{print "F", \\\$2, \\\$3, \\\$NF}' |\\\\
    cat >> \\\${tempfile}Fpairs
endif
if(! \\\$?debug) rm -f \\\${tempfile}userpairs >& /dev/null

set Fpairs = \\\`nawk '\\\$1=="F"' \\\${tempfile}Fpairs | wc -l\\\`
if(! \\\$Fpairs) then
    # maybe there's just one, lone F?
    cat \\\${tempfile}userlabels |\\\\
    nawk '\\\$1=="F"{print "F", \\\$2, \\\$3, \\\$NF}' |\\\\
    cat >> \\\${tempfile}Fpairs
endif


# now filter out user-unwanted pairings
set temp = \\\`cat \\\${tempfile}not_pairs | wc -l\\\`
if(\\\$temp) then
    # user didn't want particular pairings
    cat \\\${tempfile}not_pairs \\\${tempfile}Fpairs |\\\\
    nawk '/^NOT_A_PAIR/{not_a_pair[\\\$2 " " \\\$3]=1; not_a_pair[\\\$3 " " \\\$2]=1;}\\\\
        ! /^NOT_A_PAIR/{if(! not_a_pair[\\\$2 " " \\\$5]) print}' |\\\\
    cat >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}Fpairs
endif

# assemble Diso and Dano data into the same "dataset" file
cat \\\${tempfile}userlabels |\\\\
nawk '\\\$1=="D"{print "D", \\\$2, \\\$3, \\\$NF}' |\\\\
cat >! \\\${tempfile}datasets
cat \\\${tempfile}Fpairs >> \\\${tempfile}datasets

if(! \\\$?debug) rm -f \\\${tempfile}Fpairs     >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}userlabels >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}userpairs  >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}not_pairs  >& /dev/null

goto Return_from_Setup

####################################################

The Future:
mtz or hkl input
support intensity data
EOF-shelxscript
chmod a+x \${scriptDIR}shelx.com









#echo "writing \${scriptDIR}rantan.com "
cat << EOF-rantanscript >! \${scriptDIR}rantan.com
#! /bin/csh -f
#
#
#	rantan.com	- combinatorial rantan-based heavy-atom finder
#
#	"Because it was there."
#
#   will try all possible combinations of an arbitrary number of:
#   1) space groups
#   2) data sets (multiple mtz files are okay)
#   3) resolution cutoffs
#   4) F/sigma cutoffs
#   5) maximum delta-F cutoffs (default to a reasonable value)
#   6) expected site counts
#
#   the results of each rantan run are also passed through the CCP4 "vecref"
#   program, using a Patterson calculated with the same data presented to
#   rantan.  Sites that don't agree with the Patterson are rejected by vecref.
#
#   a pdb file ("outfile" below) is produced for each combinatorial run
#
#   the B-factor column is the height/sigma of each peak in rantan's direct-
#   phased difference Fourier.  The occupancy column is the refined atomic
#   occupancy from vecref (no particular scale).
#
#   however, this pdb file will be overwritten when each combination finishes, 
#   leaving only the results of the last combination when this script exits.
#
#   the output lines that this script prints to the terminal can each be
#   used as command-line input to re-run the same procedure, updating the
#   output file.
#

# location of awk
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set mtzfile  = ./mtz/all.mtz
set outfile  = rantan.pdb
set logfile  = \${logDIR}rantan.log
set tempfile = ./rantan_temp

# crystal variables
set hiRES = ""
set loRES = 1000
set CELL  = ""
set SG    = ""

# trials
set SGs           = ""
set RESOs         = ""
set target_sites  = "2 4 6 8 10 20"
set sigma_cutoffs = "0 0.5 1 2 3"
set max_diffs     = "auto"

# no args? need help
if(\\\$#argv == 0) goto Help

# this procedure (re)sets most of the above variables
# from either the provided files, or the command line
goto Setup

Help:
cat << EOF

usage: \\\$0 data.hkl 6 sites P212121

where:
data.mtz	- contains the F, Fs, or Dano you want to run rantan on
6 sites		- your expected number of sites
2A		- your desired resolution cutoff
1sig		- your desired F/sigma cutoff
diff 50		- your desired maximum-difference cutoff
P212121		- space group (optional)

\\\$0 will run rantan (direct phasing) on the data provided in the
space group(s) given.

EOF

exit
#
#   This procedure (at the bottom of the script) does the following
#   1) scan the command line for the mtz file(s)
#   2) set the CELL, SG, and other variables
#   3) generate dataset list file: \\\${tempfile}datasets
Return_from_Setup:

################################################################################
# back-up values (shouldn't be empty)
if("\\\$SGs" == "")           set SGs           = "\\\$SG"
if("\\\$RESOs" == "")         set RESOs         = \\\`echo "\\\$hiRES 0.1 4" | nawk '\\\$3-1>0{v=1;vstep=(1-\\\$2)/(\\\$3-1); for(i=1;i<=\\\$3;++i){printf "%.1f ", (v*1/(\\\$1^3))^(-1/3);v-=vstep;}}'\\\`
if("\\\$RESOs" == "")         set RESOs         = "\\\$hiRES"
if("\\\$sigma_cutoffs" == "") set sigma_cotoffs = "1"
if("\\\$target_sites" == "")  set target_sites  = "1"
if("\\\$max_diffs" == "")     set max_diffs     = "auto"

# print intended combinatorial
cat << EOF | tee \\\$logfile
          SGs: \\\$SGs
  reso limits: \\\$RESOs
sigma cutoffs: \\\$sigma_cutoffs
 target sites: \\\$target_sites
    max diffs: \\\$max_diffs
EOF
echo -n "    data sets: " | tee -a \\\$logfile
cat \\\${tempfile}datasets |\\\\
nawk 'NF==4{print \\\$2,"from",\\\$4} NF>4{print \\\$2 "-" \\\$5,"from",\\\$4,\\\$7} {printf "               "} END{print ""}' |\\\\
tee -a \\\$logfile

echo "running rantan:           ------ cutoffs ------  rantan results -- height -  Patterson  check"
echo "spacegroup data set       reso  sigma   maximum  WFOM   peaks    mean   max  good  mean   max mtz file(s)"


################################################################################
# explore all indicated possibilities
foreach SG ( \\\$SGs )
    # retrieve ASU count in this space group
    set ASU_per_CELL = \\\`nawk -v SG=\\\$SG '\\\$4==SG{print \\\$2}' \\\$CLIBD/symop.lib | head -1\\\`
    
    
foreach dataset ( \\\`nawk '{print NR}' \\\${tempfile}datasets\\\` )

    # extract labels from the "dataset" file
    set F1    = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$2}' \\\${tempfile}datasets\\\`
    set SIGF1 = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$3}' \\\${tempfile}datasets\\\`
    set mtz1  = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$4}' \\\${tempfile}datasets\\\`
    
    set F2    = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$5}' \\\${tempfile}datasets\\\`
    set SIGF2 = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$6}' \\\${tempfile}datasets\\\`
    set mtz2  = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$7}' \\\${tempfile}datasets\\\`
        
    # (F or D)
    set type  = \\\`nawk -v dataset=\\\$dataset 'NR==dataset{print \\\$1}' \\\${tempfile}datasets\\\`
    
    if("\\\$F2" == "") then
	set F2 = "\\\$F1"
	set SIGF2 = "\\\$SIGF1"
	set mtz2  = "\\\$mtz1"
	unset SUBTRACT
    else
	# need to do the subtraction
	set SUBTRACT
    endif
    
    # check for orthorhombic "pseudo-spacegroups"
    set axes = ""
    set realSG = "\\\$SG"
    if("\\\$SG" == P222)    set axes = "a b c"
    if("\\\$SG" == P212121) set axes = "a b c"
    if("\\\$SG" == P2221) then
	# P2221 with screw along longest axis
	set axes  = "a b c"
	set realSG = "P2221"
    endif
    if("\\\$SG" == P2212) then
	# P2221 with screw along mid-length axis
	set axes  = "b c a"
	set realSG = "P2221"
    endif
    if("\\\$SG" == P2122) then
	# P2221 with screw along shortest axis
	set axes  = "c a b"
	set realSG = "P2221"
    endif
    
    if("\\\$SG" == P21212) then
	# P21212 with non-screw along longest axis
	set axes  = "a b c"
	set realSG = "P21212"
    endif
    if("\\\$SG" == P21221) then
	# P21212 with non-screw along mid-length axis
	set axes  = "b c a"
	set realSG = "P21212"
    endif
    if("\\\$SG" == P22121) then
	# P21212 with non-screw along shotest axis
	set axes  = "c a b"
	set realSG = "P21212"
    endif
    set realSGnum = \\\`nawk -v SG=\\\$realSG '\\\$4==SG{print \\\$1;exit}' \\\${CLIBD}/symop.lib\\\`
    
    if("\\\$axes" != "") then
	# we have an asymmetric orthorhombic space group 
	set i = 0
	foreach mtz ( \\\$mtz1 \\\$mtz2 )
	    @ i = ( \\\$i + 1 )
	    # get current axis ordering, then
	    # find out what the cannonical one would be
	    # then decide how to go from current ordering to the desired one
	    echo "head" |\\\\
	    mtzdump hklin \\\$mtz |\\\\
	    nawk '/Cell Dimensions/{getline;getline;print}' |\\\\
	    nawk '{\\\\
		# print out current axis order \\\\
		print \\\$1, "h"; print \\\$2, "k"; print \\\$3, "l"}' |\\\\
	    sort -n |\\\\
	    nawk '\\\\
		# add cannonical axis names\\\\
		NR==1{print \\\$0, "a"} NR==2{print \\\$0, "b"} NR==3{print \\\$0, "c"}' |\\\\
	    nawk -v axes="\\\$axes" 'BEGIN{split(axes, abc)} {\\\\
		# write desired axis ordering in front of cannonical one \\\\
		print abc[NR], \\\$0}' |\\\\
	    sort |\\\\
	    nawk '# print out new hkl order \\\\
	          {printf "%s ", \\\$3} END{print ""}' |\\\\
	    nawk '\\\$1 \\\$2 \\\$3 \\\$1 \\\$2 \\\$3 !~ /hkl/{\\\$3 = "-" \\\$3} {print "reindex", \\\$1",",\\\$2",",\\\$3}' |\\\\
	    reindex HKLIN \\\$mtz HKLOUT \\\${tempfile}.mtz >> \\\$logfile

	    # this should give us a mapping between any two orthorhombics

	    # now simply re-name the space group in the header
	    echo "SYMM \\\$realSGnum" |\\\\
	    mtzutils HKLIN \\\${tempfile}.mtz HKLOUT \\\${tempfile}mtz\\\${i}.mtz >> \\\$logfile
	    if(\\\$status) then
		set BAD
		goto Clean_up
	    endif
	    rm -f \\\${tempfile}.mtz >& /dev/null
	end
    else
	# just re-name the space group in each mtz header
	echo "SYMM \\\$realSGnum" |\\\\
	mtzutils HKLIN \\\$mtz1 HKLOUT \\\${tempfile}mtz1.mtz >> \\\$logfile
	if(\\\$status) then
	    set BAD
	    goto Clean_up
	endif
	echo "SYMM \\\$realSGnum" |\\\\
	mtzutils HKLIN \\\$mtz2 HKLOUT \\\${tempfile}mtz2.mtz >> \\\$logfile
	if(\\\$status) then
	    set BAD
	    goto Clean_up
	endif
    endif
    

    # extract the two datasets into a single file
    cad hklin1 \\\${tempfile}mtz1.mtz hklin2 \\\${tempfile}mtz2.mtz \\\\
        hklout \\\${tempfile}cadded.mtz << EOF-cad >> \\\$logfile
    LABIN FILE 1 E1=\\\$F1  E2=\\\$SIGF1
    CTYPI FILE 1 E1=F    E2=Q
    LABOU FILE 1 E1=F1   E2=SIGF1
    LABIN FILE 2 E1=\\\$F2  E2=\\\$SIGF2
    CTYPI FILE 2 E1=F    E2=Q
    LABOU FILE 2 E1=F2   E2=SIGF2
EOF-cad
    
    # make sure we have the actual cell now
    set CELL  = \\\`echo "head" | mtzdump hklin \\\${tempfile}cadded.mtz | nawk '/Cell Dimensions/{getline;getline;print}'\\\`
    
    # iterate over resolution cutoffs
    foreach cutRES ( \\\$RESOs )
    
    # apply scaleit (to scale isomorphous differences, and check DIFF recommendation)
    if(\\\$?SUBTRACT) then
	set dataset = "\\\${F1}-\\\${F2}"
	set scale  = ""
    else
	set dataset = "\\\$F1"
	# either Dano or FH data (squash F2)
	set scale  = "SCALE FPH1 0.0000001"
    endif

    scaleit hklin \\\${tempfile}cadded.mtz \\\\
            hklout \\\${tempfile}scaled.mtz << EOF-scale | tee \\\${tempfile}scaleit.log >> \\\$logfile
    RESOLUTION 1000 \\\$cutRES
    refine anisotropic
    \\\$scale
    LABIN FP=F1 SIGFP=SIGF1 FPH1=F2 SIGFPH1=SIGF2
EOF-scale
    
    # iterate over sigma- and maximum-difference cutoffs
    foreach cutSIG ( \\\$sigma_cutoffs )
    foreach diff ( \\\$max_diffs )
    
    # use scaleit's recommendation by default
    if("\\\$diff" == "auto") set diff = \\\`nawk '/acceptable differences/{print \\\$NF}' \\\${tempfile}scaleit.log\\\`
    if("\\\$diff" == "") set diff = 99999999
    
    # print mini-report (suitable for re-input on command line)
    # display for user
    echo "\\\$SG \\\$dataset \\\$cutRES \\\$cutSIG \\\$diff" |\\\\
	 nawk '{printf "%-10s %-13s %4.1fA %4.1fs  diff %-5.1f ", \\\$1, \\\$2, \\\$3, \\\$4, \\\$5}'
    



    # make a Patterson map
    fft HKLIN \\\${tempfile}scaled.mtz MAPOUT \\\${tempfile}patt.map << EOF-fft >> \\\$logfile
    TITLE \\\${cutRES}A Patterson of \\\$dataset excluding diff>\\\$diff
    RESOLUTION \\\$cutRES
    PATTERSON
    LABIN F1=F1 SIG1=SIGF1 F2=F2 SIG2=SIGF2
    EXCLUDE DIFF \\\$diff
    EXCLUDE SIG1 \\\$cutSIG
EOF-fft
    # normalize the Patterson
    echo "scale sigma" |\\\\
    mapmask mapin  \\\${tempfile}patt.map \\\\
           mapout \\\${tempfile}.map >> \\\$logfile
    mv \\\${tempfile}.map \\\${tempfile}patt.map
    if(\\\$?user_patt) then
	# option to use an outside Patterson?
	cp \\\$user_patt \\\${tempfile}patt.map
    endif
    
    # calculate Es on exactly the same data
    ecalc hklin \\\${tempfile}scaled.mtz  hklout \\\${tempfile}E.mtz << EOF-ecalc >> \\\$logfile
    RESOLUTION \\\$cutRES
    EXCLUDE DIFF \\\$diff
    EXCLUDE SIGP \\\$cutSIG
    LABIN FP=F1 SIGFP=SIGF1 FPH=F2 SIGFPH=SIGF2
EOF-ecalc
    
    #######################################
    # run rantan
    rm -f \\\${tempfile}rantaned.mtz >& /dev/null
    echo "LABI EVAL=E " |\\\\
    rantan hklin \\\${tempfile}E.mtz \\\\
          hklout \\\${tempfile}rantaned.mtz |& tee \\\${tempfile}rantan.log >>& \\\$logfile

    #######################################
    if(\\\$status) then
	echo "crashed"
	rm -f \\\${tempfile}E.mtz \\\${tempfile}rantan.log >& /dev/null
	continue
    endif
    
    # get the mean FOM of the best data set
    set WFOM = \\\`nawk '/COMBINED FOM/{getline; print \\\$NF}' \\\${tempfile}rantan.log | tail -1\\\`
    rm -f \\\${tempfile}rantan.log >& /dev/null
    rm -f \\\${tempfile}E.mtz >& /dev/null

    # fourier and peak-pick
    rm -f \\\${tempfile}rantan.map
    fft HKLIN \\\${tempfile}rantaned.mtz MAPOUT \\\${tempfile}rantan.map << EOF-fft >> \\\$logfile
    resolution \\\$cutRES
    LABIN F1=E   PHI=PHI1 W=WT1 
EOF-fft
    # normalize it
    echo "SCALE SIGMA" |\\\\
    mapmask MAPIN \\\${tempfile}rantan.map \\\\
           MAPOUT \\\${tempfile}norm.map | tee \\\${tempfile}map.log >> \\\$logfile
    mv \\\${tempfile}norm.map \\\${tempfile}rantan.map
    set GRID = \\\`nawk '/Grid sampling on x, y, z/{print \\\$(NF-2), \\\$(NF-1), \\\$NF;exit}' \\\${tempfile}map.log\\\`
    set ASU = \\\`nawk '/Start and stop points on x, y, z/{print \\\$(NF-5)+0, \\\$(NF-4)+0, \\\$(NF-3)+0, \\\$(NF-2)+0, \\\$(NF-1)+0, \\\$NF+0; exit}' \\\${tempfile}map.log\\\`
    set CRS = \\\`nawk '/Start and stop points on cols/{print \\\$(NF-5)-1, \\\$(NF-4)+1, \\\$(NF-3)-1, \\\$(NF-2)+1, \\\$(NF-1)-1, \\\$NF+1; exit}' \\\${tempfile}map.log\\\`
    rm -f \\\${tempfile}map.log >& /dev/null

    # now extend the map to a little more than one ASU
    echo "\\\$ASU" |\\\\
     nawk '{print "XYZLIM", \\\$1-10, \\\$2+10, \\\$3-10, \\\$4+10, \\\$5-10, \\\$6+10}' |\\\\
    mapmask MAPIN \\\${tempfile}rantan.map \\\\
           MAPOUT \\\${tempfile}xtend.map >> \\\$logfile
    mv \\\${tempfile}xtend.map \\\${tempfile}rantan.map
    

    
    foreach expect ( \\\$target_sites )
    
    # re-print initial tag for multiple-target-site runs
    set temp = \\\`echo "\\\$target_sites" | nawk '{print \\\$1}'\\\`
    if("\\\$expect" != "\\\$temp") then
	# only do this 2nd time and beyond
	echo "\\\$SG \\\$dataset \\\$cutRES \\\$cutSIG \\\$diff" |\\\\
	     nawk '{printf "%-10s %-13s %4.1fA %4.1fs  diff %-5.1f ", \\\$1, \\\$2, \\\$3, \\\$4, \\\$5}'
    endif
    
    # pick peaks in the direct-phased map
    peakmax MAPIN \\\${tempfile}rantan.map \\\\
            XYZOUT \\\${tempfile}.pdb << EOF | tee \\\${tempfile}.log >> \\\$logfile
    xyzlimit \\\$CRS
    threshold 3
EOF
    # get only symmetry-unique peaks
    cat \\\${tempfile}.log |\\\\
    nawk '/Count Site Height/,/threshold/' |\\\\
    nawk 'NF>3 && ! /[^0-9 -\\\\.]/{print substr(\\\$0,9)+0, substr(\\\$0,length(\\\$0)-47,25), substr(\\\$0,5)+0}' |\\\\
    sort -nr |\\\\
    nawk '! seen[\\\$NF] {print \\\$2, \\\$3, \\\$4, \\\$1} {seen[\\\$NF]=1}' |\\\\
    head -\\\$expect >! \\\${tempfile}peaks.pick
    # format: xf yf zf height/sigma
    rm -f \\\${tempfile}.pdb >& /dev/null
    rm -f \\\${tempfile}.log >& /dev/null
    
    ##########################################
    # filter out special positions
    cat \\\${tempfile}peaks.pick |\\\\
    nawk '{++n; print "RES", n; print "ATOM X", \\\$1, \\\$2, \\\$3}' |\\\\
    cat >! \\\${tempfile}atoms
    # for gensym
    
    # get symmetry mates for (nearly) a whole cell
    gensym << EOF >! \\\${tempfile}sym.log
    SYMM \\\$realSG
    CELL \\\$CELL
    XYZLIM 0 0.999999 0 0.999999 0 0.999999
    @\\\${tempfile}atoms
EOF
    rm -f \\\${tempfile}atoms >& /dev/null
    
    # count the number of times each xyz position is "seen"
    # more than once implies a special position
    cat \\\${tempfile}sym.log |\\\\
    nawk '/List of sites/,/Normal termination/' |\\\\
    nawk '\\\$2 ~ /[01].[0-9][0-9][0-9]/{print \\\$2, \\\$3, \\\$4, \\\$(NF-1), \\\$NF}' |\\\\
    nawk '{++seen[\\\$1 " " \\\$2 " " \\\$3 " " \\\$4]}\\\\
       END{for(site in seen) print site, seen[site]}' |\\\\
    sort -un -k4 |\\\\
    nawk '\\\$5+0>0{print \\\$4, \\\$5}' >! \\\${tempfile}mults
    rm -f \\\${tempfile}sym.log >& /dev/null
    
    # add "multiplicity" to peaks file
    cat \\\${tempfile}mults \\\${tempfile}peaks.pick |\\\\
    nawk 'NF==2{mult[\\\$1]=\\\$2} \\\\
           NF>2{++n; print \\\$0, mult[n]}' |\\\\
    cat >! \\\${tempfile}peaks.mult
    # format: xf yf zf height/sigma mult
    rm -f \\\${tempfile}mults \\\${tempfile}peaks.pick >& /dev/null
        
    #############################################
    # count number of peaks
    set peaks = \\\`cat \\\${tempfile}peaks.mult | wc -l\\\`
    
    # another partial print-out (before vecref run)
    echo "\\\$WFOM \\\$peaks" | nawk '{printf "%4.2f %3d sites ", \\\$1, \\\$2}'

    
    # use vecref to check against the Patterson
    set rcycles = "3,0,0 3,0,0 3,10,0 3,10,0 3,0,10 3,0,10"
    set rcycles = "3,0,0 3,0,0 3,0,0 3,0,0"
    if(\\\$?NO_PATT) set rcycles = ""
    # reduce resolution a bit so vecref won't crash
    set refRES = \\\`echo \\\$cutRES | nawk '{print (0.8*1/(\\\$1^3))^(-1/3)}'\\\`
    set Bstart = \\\`echo \\\$cutRES | nawk '{print 79*(\\\$1/3)^2}'\\\`
    
    cat \\\${tempfile}peaks.mult |\\\\
    nawk -v Bstart=\\\$Bstart 'NF>3{++n}\\\\
      \\\$5+0==1{print "ATOM H", n, \\\$4, \\\$1, \\\$2, \\\$3, Bstart}' |\\\\
    cat >! \\\${tempfile}atoms.out

    # run a few rounds of vecref
    foreach rcycle ( \\\$rcycles )
	set rcycle = \\\`echo "\\\$rcycle" | nawk 'BEGIN{FS=","} {print \\\$1, \\\$2, \\\$3}'\\\`
	
	# vecref can't handle more than 50 sites
	sort -nr -k4 \\\${tempfile}atoms.out |\\\\
	head -50 >! \\\${tempfile}atoms.in
	
	# refine "occupancies" against the Patterson
	rm -f \\\${tempfile}atoms.out >& /dev/null
        set vecrefSG = \\\$realSG
        if("\\\$vecrefSG" == "H3") set vecrefSG = R3
        if("\\\$vecrefSG" == "H32") set vecrefSG = R32
	vecref mapin \\\${tempfile}patt.map ATOUT \\\${tempfile}atoms.out << EOF-vecref >>& \\\$logfile
	SPACEGROUP \\\$vecrefSG
	RESOLUTION \\\${refRES}
	CYCLES \\\$rcycle
	BLIM 0 1000
	@\\\${tempfile}atoms.in
EOF-vecref
	if((\\\$status)||(! -e \\\${tempfile}atoms.out)) then
	    # all atoms rejected
	    echo -n "" >! \\\${tempfile}atoms.out
	    break
	endif
    end
    rm -f \\\${tempfile}atoms.in >& /dev/null
    if(\\\$?NO_PATT) then
	# no data available from Patterson
	echo -n "" >! \\\${tempfile}atoms.out
    endif
    
    # label the peaks file with the vecref occupancies
    cat \\\${tempfile}atoms.out \\\${tempfile}peaks.mult |\\\\
    nawk '/^ATOM/{occ[\\\$3]=\\\$4; next} {++n; print \\\$0, occ[n]+0}' |\\\\
    cat >! \\\${tempfile}peaks.pocc
    # format: xf yf zf height/sigma mult pocc
    rm -f \\\${tempfile}atoms.out >& /dev/null
    rm -f \\\${tempfile}peaks.mult >& /dev/null

    
    # calculate scores
    echo "WFOM \\\$WFOM" >! \\\${tempfile}.results
    cat \\\${tempfile}peaks.pocc |\\\\
    nawk '\\\$5+0!=1{next} {++n; sig+=\\\$4} \\\$6+0>0{++p;pat+=\\\$6}\\\\
	  \\\$4*\\\$6>0{mix+=\\\$4+\\\$6}\\\\
	  \\\$4>max{max=\\\$4} \\\$6>pmax{pmax=\\\$6}\\\\
          END{print "PEAKS", n; if(n==0)n=1;\\\\
	      print "MEAN", sig/n;\\\\
	      print "MAX", max+0;\\\\
	      print "SURV", p; if(p==0)p=1;\\\\
	      print "PMEAN", pat/p;\\\\
	      print "PMAX", pmax+0;\\\\
	      print "COMB", (mix* 1/n)/10}' |\\\\
    cat >> \\\${tempfile}.results
    if(\\\$?NO_PATT) then
	# fake it, but let user know nothing happened
	echo "SURV  ?" >> \\\${tempfile}.results
	echo "PMEAN ?" >> \\\${tempfile}.results
	echo "PMAX  ?" >> \\\${tempfile}.results
	echo "COMB  ?" >> \\\${tempfile}.results
    endif

    # print out for user
    cat \\\${tempfile}.results |\\\\
     nawk 'NR>2{printf "%s ", \\\$NF} END{print ""}' |\\\\
     nawk '{printf "%5.2f %5.2f %5d %5.2f %5.2f", \\\$1, \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7}'
    
    # print out data files used
    set mtzfiles = "\\\$mtz1"
    if("\\\$mtz2" != "\\\$mtz1") set mtzfiles = "\\\$mtz1 \\\$mtz2"
    echo -n " \\\$mtzfiles "
    
    # come up with some kind of holistic "score"?     
    cat \\\${tempfile}.results |\\\\
    nawk '/^WFOM/{WFOM=\\\$NF}\\\\
          /^MAX/ {MAX=\\\$NF}\\\\
          /^PEAK/{PEAKS=\\\$NF}\\\\
          /^SURV/{PATT=\\\$NF}\\\\
          /^COMB/{COMB=\\\$NF}\\\\
          END{if(COMB != "?"){print COMB}else{print MAX}}' |\\\\
    cat >! \\\${tempfile}.score
    set score = \\\`cat \\\${tempfile}.score | nawk '{printf "%d", \\\$1*1000}'\\\`
    rm -f \\\${tempfile}.score >& /dev/null
    

    # create the output pdb
    cat \\\${tempfile}peaks.pocc |\\\\
    nawk -v Bstart=\\\$Bstart 'NF>=3{++n;\\\\
                Ee="HA";\\\\
		x=\\\$1;y=\\\$2;z=\\\$3;occ=\\\$6;B=\\\$4;\\\\
		chain="D"; if(\\\$5+0>1) chain="X";\\\\
    printf("%5d%10.5f%10.5f%10.5f%10.5f%5.2f   35%10d%2s   RAN %1s\\\\n",\\\\
    n, x,y,z, B, occ, n, Ee, chain)}' |\\\\
    cat >! \\\${tempfile}.frac

    # make sure we've got the right cell
    coordconv xyzin \\\${tempfile}.frac xyzout \\\${tempfile}.pdb << EOF >> \\\$logfile
    CELL \\\$CELL
    INPUT FRAC
    OUTPUT PDB ORTH 1
    END
EOF
    
    # write a descriptive header to the PDB file
    cat << EOF | nawk '{print "REMARK", \\\$0}' >! \\\${tempfile}full.pdb
results here are from:
\\\$dataset in \\\$mtzfiles at \\\${cutRES}A in \\\$SG
reflections were excluded if F/sigF < \\\$cutSIG or |delta-F| > \\\$diff
internal score: \\\$score

the B-factor column here contains the peak height of each atom in 
a difference Fourier calculated using the "best" set of directly-
obtained phases from rantan.

the occupancy column contains the result of vector-space refinement of all
the located peaks against a Patterson calculated with the same data
provided to rantan.  The CCP4 program vecref will have rejected most of
the atoms, leaving non-zero occupancy only for sites that are consistent 
with the Patterson.

ATOMs in the "X" chain were on special positions.

the symmetry of these positions is \\\$realSG
                           X       Y       Z      occ height
EOF
    # copy over the atoms
    cat \\\${tempfile}.pdb >> \\\${tempfile}full.pdb
    rm -f \\\${tempfile}.pdb >& /dev/null
    rm -f \\\${tempfile}.frac >& /dev/null
    rm -f \\\${tempfile}.atoms >& /dev/null
    rm -f \\\${tempfile}peaks.pocc >& /dev/null

    if(\\\$?debug) echo "\\\$CELL" | nawk '{printf "%d %d %d ", \\\$1, \\\$2, \\\$3}'

    
    if(\\\$score > \\\$best_score) then
	set best_score = \\\$score
	if(-e \\\${outfile}.older) mv \\\${outfile}.older \\\${outfile}.oldest
	if(-e \\\${outfile}.old) mv \\\${outfile}.old \\\${outfile}.older
	if(-e \\\${outfile}) mv \\\${outfile} \\\${outfile}.old
	cp \\\${tempfile}full.pdb \\\$outfile >& /dev/null
	if(! \\\$status) echo -n " (saved as \\\$outfile)"
#	if(! \\\$status) echo -n " (saved)"
    endif
    
    
    # diagnostics
    if(\\\$?debug) then
	/max/jamesh/Develop/origins.com \\\$realSG right_sites.pdb \\\${tempfile}full.pdb |\\\\
	nawk 'NF==5{right=\\\$4} END{printf "%d", right}'
	
	nawk '\\\$10+0>0 || ! /^ATOM/' \\\${tempfile}full.pdb >! \\\${tempfile}.pdb 
	/max/jamesh/Develop/origins.com \\\$realSG right_sites.pdb \\\${tempfile}.pdb |\\\\
	nawk 'NF==5{right=\\\$4;fit=\\\$5} END{printf "%s", "/" right " correct " fit}'
    endif

    # end the line
    echo ""
    
    end	# sites
    end	# diff
    end	# cutSIG
    end	# cutRES
    
end	# dataset
end	# SG

# clean up
Clean_up:
if(\\\$?debug) exit
rm -f \\\${tempfile}rantaned.mtz >& /dev/null
rm -f \\\${tempfile}rantan.map >& /dev/null
rm -f \\\${tempfile}.results >& /dev/null
rm -f \\\${tempfile}full.pdb >& /dev/null

rm -f \\\${tempfile}patt.map >& /dev/null
rm -f \\\${tempfile}datasets >& /dev/null
rm -f \\\${tempfile}mtz1.mtz >& /dev/null
rm -f \\\${tempfile}mtz2.mtz >& /dev/null
rm -f \\\${tempfile}cadded.mtz >& /dev/null
rm -f \\\${tempfile}scaled.mtz >& /dev/null
rm -f \\\${tempfile}scaleit.log >& /dev/null


exit






Setup:
#################################################

  ####   ######   #####  #    #  #####
 #       #          #    #    #  #    #
  ####   #####      #    #    #  #    #
      #  #          #    #    #  #####
 #    #  #          #    #    #  #
  ####   ######     #     ####   #

#################################################
#
#   gather information on:
#    mtz file
#    data sets
#    resolution limits
#    sigma cuttoff (for map generation)
#    difference cutoff
#
##################################################
# scan the command line for files
set user_SGs   = ""
set user_sigs  = ""
set user_resos = ""
set user_diffs = ""
set user_sites = ""
set mtzfiles   = ""
set best_score = -1

foreach arg ( \\\$* )
    # warn about probable mispellings
    if("\\\$arg" =~ *.mtz) then
	if(-e "\\\$arg") then
	    set mtzfiles = "\\\$mtzfiles \\\$arg"
	else
	    echo "WARNING: \\\$arg does not exist! "
	endif
    endif
end

# use default if nothing specified
if("\\\$mtzfiles" == "") set mtzfiles = "\\\$mtzfile"

# gather data set labels, etc from the mtzs
set i = 0
echo "" >! \\\${tempfile}labels
foreach mtz ( \\\$mtzfiles )
    @ i = ( \\\$i + 1 )
    
    # dump and characterize contents
    echo "go" | mtzdump HKLIN \\\$mtz >! \\\${tempfile}mtzdump

    cat \\\${tempfile}mtzdump |\\\\
    nawk '/Cell Dimensions/{getline;getline;print "CELL", \\\$0}\\\\
	  /Space group/{print "SYMM", \\\$NF+0}\\\\
	  /Resolution Range/{getline;getline;print "RESO", \\\$4, \\\$6}' |\\\\
    cat >! \\\${tempfile}info
    
    # read in dataset info
    cat \\\${tempfile}mtzdump |\\\\
    nawk 'NF>6' |\\\\
    nawk '\\\$(NF-1)=="F"{print "F", \\\$NF, \\\$(NF-4)}\\\\
          \\\$(NF-1)=="D"{print "D", \\\$NF, \\\$(NF-4)}\\\\
          \\\$(NF-1)=="Q"{print "S", \\\$NF, \\\$(NF-4)}' |\\\\
    nawk '/^F/{++n} /^D/{++n} {printf "%s", \\\$1; \\\\
           if(\\\$1=="S") printf "%s", last;\\\\
    printf " %d %s %s\\\\n",n, \\\$2, \\\$3; last=\\\$1}' |\\\\
    cat >> \\\${tempfile}info
    
    # check for empty mtzs
    set temp = \\\`nawk '/^[FD]/' \\\${tempfile}info | wc -l\\\`
    if(\\\$temp > 0) then
	# add it to the pile
	cat \\\${tempfile}info |\\\\
	nawk -v mtz=\\\$mtz '{print \\\$0, mtz}' |\\\\
	cat >> \\\${tempfile}labels
    else
	echo "WARNING: \\\$mtz contains no useful data!"
    endif
    if(! \\\$?debug) rm -f \\\${tempfile}mtzdump >& /dev/null
    if(! \\\$?debug) rm -f \\\${tempfile}info >& /dev/null
end

# get complete, unique lists of DANOs
cat \\\${tempfile}labels |\\\\
nawk '{l= \\\$2 " " \\\$NF}\\\\
      \\\$1=="D"{D[l]=\\\$3; signal[l]=\\\$4} \\\\
      \\\$1=="SD"{S[l]=\\\$3; noise[l]=\\\$4} \\\\
      END{for(l in S){if(noise[l]+0==0) noise[i]=1; \\\\
	print "D", D[l], S[l], signal[l]/noise[l], l}}' |\\\\
nawk 'NF==6' |\\\\
sort -nr -k3 >! \\\${tempfile}mtzlabels

# get complete, unique lists of Fs
cat \\\${tempfile}labels |\\\\
nawk '{l= \\\$2 " " \\\$NF}\\\\
      \\\$1=="F"{F[l]=\\\$3; signal[l]=\\\$4} \\\\
      \\\$1=="SF"{S[l]=\\\$3; noise[l]=\\\$4} \\\\
      END{for(l in S){if(noise[l]+0==0) noise[l]=1; \\\\
	print "F", F[l], S[l], signal[l]/noise[l], l}}' |\\\\
nawk 'NF==6' |\\\\
sort -nr -k3 >> \\\${tempfile}mtzlabels

# reconcile different cells? SGs?
set CELL  = \\\`nawk '/^CELL/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7; exit}' \\\${tempfile}labels\\\`
set SG    = \\\`nawk '/^SYMM/{print \\\$2; exit}' \\\${tempfile}labels\\\`
set SGnum = \\\`nawk '/^SYMM/{print \\\$2; exit}' \\\${tempfile}labels\\\`
set SG    = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set hiRES = \\\`nawk '/^RESO/{print \\\$3}' \\\${tempfile}labels | sort -n | head -1\\\`

if(! \\\$?debug) rm -f \\\${tempfile}labels >& /dev/null


set mtzlabels = \\\`cat \\\${tempfile}mtzlabels | wc -l\\\`
if("\\\$mtzlabels" == 0) then
    echo "no usefult data in \\\$mtzfiles "
    goto Help
endif

##################################################
# get crystal and dataset information from the final mtz file


# make a two-way difference-dataset list (for recognition)
cat \\\${tempfile}mtzlabels |\\\\
nawk '\\\$1=="F"{++n; set[n]= \\\$2 " " \\\$3 " " \\\$NF;\\\\
      for(i=1;i! \\\${tempfile}Fpairs


# one last pass through command line
# allow user overrides of all internal variables
set i = 0
echo -n "" >! \\\${tempfile}userlabels
echo -n "" >! \\\${tempfile}userpairs
echo -n "" >! \\\${tempfile}not_pairs
while( \\\$i < \\\$#argv )
    @ i = ( \\\$i + 1 )
    @ nexti = ( \\\$i + 1 )
    @ lasti = ( \\\$i - 1 )
    if(\\\$nexti > \\\$#argv) set nexti = \\\$#argv
    if(\\\$lasti < 1) set lasti = 1
    set arg = "\\\$argv[\\\$i]"
    
    # check for space groups
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	set temp = \\\`nawk -v SG=\\\$temp '\\\$4 == SG {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
	if("\\\$temp" == "") then
	    # check for "pseudo-spacegroup" language
	    set temp = \\\`echo "\\\$arg" | nawk 'toupper(\\\$1) ~ /[PC]2212|[PC]2122|P21221|P22121/'\\\`
	    # these are okay too, reindexing engine will understand
	endif
	if("\\\$temp" != "") then
	    # add this SG to the space group list
	    set user_SGs = "\\\$user_SGs \\\$temp"
	    continue
	endif
    endif
    
    # only look at non-file words
    if(! -e "\\\$arg") then
	# see if a dataset label was given
	set temp = \\\`nawk -v arg=\\\$arg '\\\$2==arg' \\\${tempfile}mtzlabels | wc -l\\\`
	if(\\\$temp) then
	    # a dataset label was mentioned
	    if(\\\$?NO) then
		# user doesn't want this label
		# filter it out of the input files
		nawk -v arg=\\\$arg '\\\$2!=arg' \\\${tempfile}mtzlabels >! \\\${tempfile}
		mv \\\${tempfile} \\\${tempfile}mtzlabels
	    else
		# must want only this label?
		nawk -v arg=\\\$arg '\\\$2==arg' \\\${tempfile}mtzlabels |\\\\
		cat >> \\\${tempfile}userlabels
	    endif
	    continue
	endif
    	
	# see if a difference-dataset label was given
	set temp = \\\`nawk -v arg=\\\$arg '\\\$2 "-" \\\$5 == arg{print \\\$2, \\\$5; exit}' \\\${tempfile}Fpairs\\\`
	if(\\\$#temp == 2) then
	    # a specific difference dataset was mentioned
	    if(\\\$?NO) then
		# user doesn't want this label pair
		# filter it out of the input files
		echo "NOT_A_PAIR \\\$temp" >> \\\${tempfile}not_pairs
	    else
		# must want only this pair (in this order)?
		cat \\\${tempfile}Fpairs |\\\\
		nawk -v F1=\\\$temp[1] -v F2=\\\$temp[2] '\\\$2==F1 && \\\$5==F2' |\\\\
		cat >> \\\${tempfile}userpairs
	    endif
	    continue	    
	endif
	
	# program options
	if("\\\$arg" =~ [Pp]att*) then
	    if(\\\$?NO) then
		set NO_PATT
	    else
		unset NO_PATT
	    endif
	endif
	
	# check for 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
				set loRES = "\\\$temp[1]"
				set user_resos = "\\\$user_resos \\\$temp[2]"
				continue
		    endif
		else
		    if("\\\$temp" != "") set user_resos = "\\\$user_resos \\\$temp"
		    continue
		endif
	    endif
	    
	    if(("\\\$arg" =~ *[0-9][Ss]*)||("\\\$argv[\\\$nexti]" =~ [Ss]igma)) then
		set user_sigs = "\\\$user_sigs "\\\`echo "\\\$arg" | nawk '\\\$1~/^[0-9\\\\.]/{print \\\$1+0}'\\\`
	    endif
	    
	    if(("\\\$argv[\\\$nexti]" =~ [Ss]ite)||("\\\$argv[\\\$nexti]" =~ [Ss]ites)) then
		set user_sites = "\\\$user_sites "\\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    
	    if(("\\\$arg" =~ *[Dd]iff)||("\\\$argv[\\\$lasti]" =~ [Dd]iff)) then
		set user_diffs = "\\\$user_diffs "\\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    if(("\\\$arg" =~ *[Dd]iso)||("\\\$argv[\\\$lasti]" =~ [Dd]iso)) then
		set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	    if(("\\\$arg" =~ *[Dd]ano)||("\\\$argv[\\\$lasti]" =~ [Dd]ano)) then
		set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    endif
	endif
	
	# allow "NO" logic to carry through
	unset NO
	if(("\\\$arg" == "no")||("\\\$arg" == "not")) set NO
	if(("\\\$arg" == "don't")||("\\\$arg" == "ignore")) set NO
	if("\\\$arg" == "except") set NO
    endif
end

# honor user requests (when mentioned)
if("\\\$user_SGs"   != "") set SGs           = "\\\$user_SGs"
if("\\\$user_resos" != "") set RESOs         = "\\\$user_resos"
if("\\\$user_sigs"  != "") set sigma_cutoffs = "\\\$user_sigs"
if("\\\$user_diffs" != "") set max_diffs     = "\\\$user_diffs"
if("\\\$user_sites" != "") set target_sites  = "\\\$user_sites"


# check the "user" labels
sort -u -k6 \\\${tempfile}userlabels >! \\\${tempfile}mtzs
sort -u -k6 \\\${tempfile}mtzlabels >> \\\${tempfile}mtzs
cat \\\${tempfile}mtzs |\\\\
nawk '{++seen[\\\$6]} END{for(mtz in seen) if(seen[mtz]==1) print mtz}' |\\\\
cat >! \\\${tempfile}orphans

foreach mtz ( \\\`cat \\\${tempfile}orphans\\\` )
    # some mtzs were mentioned, but aren't in \\\${tempfile}userlabels
    # so, we'll just assume everything in them was wanted
    cat \\\${tempfile}mtzlabels |\\\\
    nawk -v mtz=\\\$mtz '\\\$6==mtz' |\\\\
    cat >> \\\${tempfile}userlabels
end
if(! \\\$?debug) rm -f \\\${tempfile}orphans   >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}mtzlabels >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}mtzs      >& /dev/null

# make sure no label is mentioned twice
cat \\\${tempfile}userlabels |\\\\
nawk '! seen[\\\$2 " " \\\$NF]{print} {++seen[\\\$2 " " \\\$NF]}' |\\\\
cat >! \\\${tempfile}
mv \\\${tempfile} \\\${tempfile}userlabels

# organize user's desired labels into difference-data sets
cat \\\${tempfile}userlabels |\\\\
nawk '\\\$1=="F"{++n; set[n]= \\\$2 " " \\\$3 " " \\\$NF;\\\\
      for(i=1;i! \\\${tempfile}Fpairs

# see if user had particular pairing in mind
set temp = \\\`cat \\\${tempfile}userpairs | wc -l\\\`
if(\\\$temp) then
    # this overrides the Fpairs we just generated
    cat \\\${tempfile}userpairs >! \\\${tempfile}Fpairs
    
    # also any user-specified individual labels must be lone Fs? 
    cat \\\${tempfile}userlabels |\\\\
    nawk '\\\$1=="F"{print "F", \\\$2, \\\$3, \\\$NF}' |\\\\
    cat >> \\\${tempfile}Fpairs
endif
if(! \\\$?debug) rm -f \\\${tempfile}userpairs >& /dev/null

set Fpairs = \\\`nawk '\\\$1=="F"' \\\${tempfile}Fpairs | wc -l\\\`
if(! \\\$Fpairs) then
    # maybe there's just one, lone F?
    cat \\\${tempfile}userlabels |\\\\
    nawk '\\\$1=="F"{print "F", \\\$2, \\\$3, \\\$NF}' |\\\\
    cat >> \\\${tempfile}Fpairs
endif


# now filter out user-unwanted pairings
set temp = \\\`cat \\\${tempfile}not_pairs | wc -l\\\`
if(\\\$temp) then
    # user didn't want particular pairings
    cat \\\${tempfile}not_pairs \\\${tempfile}Fpairs |\\\\
    nawk '/^NOT_A_PAIR/{not_a_pair[\\\$2 " " \\\$3]=1; not_a_pair[\\\$3 " " \\\$2]=1;}\\\\
        ! /^NOT_A_PAIR/{if(! not_a_pair[\\\$2 " " \\\$5]) print}' |\\\\
    cat >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}Fpairs
endif

# assemble Diso and Dano data into the same "dataset" file
cat \\\${tempfile}userlabels |\\\\
nawk '\\\$1=="D"{print "D", \\\$2, \\\$3, \\\$NF}' |\\\\
cat >! \\\${tempfile}datasets
cat \\\${tempfile}Fpairs >> \\\${tempfile}datasets

if(! \\\$?debug) rm -f \\\${tempfile}Fpairs     >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}userlabels >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}userpairs  >& /dev/null
if(! \\\$?debug) rm -f \\\${tempfile}not_pairs  >& /dev/null

goto Return_from_Setup

####################################################

The Future:
EOF-rantanscript
chmod a+x \${scriptDIR}rantan.com



























write_reindex:

# don't overwrite user-modified script
if(-e \${scriptDIR}reindex.com) goto write_rrsps

#echo "writing \${scriptDIR}reindex.com"
cat << EOF-reindexscript >! \${scriptDIR}reindex.com
#! /bin/csh -f
#
#	\${scriptDIR}reindex.com
#
#	simple interface to reindexing of merged or unmerged mtz data
#
#
# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set mtzfile    = ""
set logfile    = "\${logDIR}reindex.log"
set newmtzfile = "reindexed.mtz"
set tempfile   = ./reindex_temp

set message    = ""
set newSG      = ""

goto Setup
#
#	scan command line for mtz files, space groups, and preferences
#
Help:
cat << EOF-Help
usage: \\\$0 mtzfile.mtz [SG] [flip] [newmtz.mtz]

where:

mtzfile.mtz	- the mtz data you want to re-index. (merged or unmerged)
SG		- the new space group (P43 for example)
flip		- flip ambiguous axes of P4x P3x and P6x cells
newmtz.mtz	- name you want for the reindexed mtz (default: reindexed.mtz)

Example:    \\\$0 Fpp.mtz P43212 Fpp.P43212.mtz
Example:    \\\$0 Fpp.mtz flip

Note: to put the screw axis of P2221 on the shortest cell axis, say P2122
The space group in the new file will be P2221 again, but the cell
will be flipped around appropriately.  Same goes for P2212, or
P21221 and P22121 with P21212

EOF-Help
exit
#
Return_from_Setup:

if(! -e "\\\$mtzfile") goto Help

# okay to proceed
if("\\\$message" != "") set message = " \\\$message"
echo "reindexing \\\$mtzfile to \\\$newmtzfile (in \\\${newSG}\\\${message})" | tee \\\$logfile

if(\\\$?MERGED) then
    # apply any "flip" directives with "reindex"
    echo "\\\$REINDEX" |\\\\
    reindex HKLIN \\\$mtzfile HKLOUT \\\${tempfile}reindexed.mtz >> \\\$logfile
    if(\\\$status) set BAD
    
    # just use mtzutils to change SG record in header
    echo "SYMM \\\$newSG" |\\\\
    mtzutils HKLIN \\\${tempfile}reindexed.mtz HKLOUT \\\${tempfile}newSG.mtz >> \\\$logfile
    if(\\\$status) set BAD
    
    rm -f \\\${tempfile}reindexed.mtz >& /dev/null
    
    # sort it again, just to be safe
    echo "H K L" |\\\\
    sortmtz HKLIN \\\${tempfile}newSG.mtz HKLOUT \\\$newmtzfile >> \\\$logfile
    if(\\\$status) set BAD
    
    rm -f \\\${tempfile}newSG.mtz >& /dev/null
endif
    
if(\\\$?UNMERGED) then
    reindex HKLIN \\\$mtzfile HKLOUT \\\${tempfile}reindexed.mtz << EOF-reindex >> \\\$logfile
    SYMM \\\$newSG
    \\\$REINDEX
EOF-reindex
    if(\\\$status) set BAD

    # sort again
    sortmtz HKLIN \\\${tempfile}reindexed.mtz HKLOUT \\\$newmtzfile << EOF-sort >> \\\$logfile
#VRSET -9E+38
H K L M/ISYM BATCH I SIGI
EOF-sort
    if(\\\$status) set BAD
    
endif
# remove intermediate file
rm -f \\\${tempfile}reindexed.mtz >& /dev/null


if((-e "\\\$newmtzfile")&&(! \\\$?BAD)) then
    echo "\\\$newmtzfile is \\\$mtzfile in \\\${newSG}\\\${message}"
    if("\\\$axes" != "") then
	echo "head" | mtzdump hklin "\\\$newmtzfile" |\\\\
	nawk '/Cell Dimensions/{getline;getline;\\\\
	print "new cell:", \\\$1, \\\$2, \\\$3, \\\$4, \\\$5, \\\$6}'
    endif
else
    # something went wrong
    echo "FAILED!  examine \\\$logfile to see what went wrong."
endif

exit







Setup:
#############################################################
# check up on essentials
if(! \\\$?CLIBD) then
    echo "Please set up CCP4, and then run \\\$0 again"
    goto Help
endif
if(! -e \\\$CLIBD/symop.lib) then
    echo "ERROR: no \\\$CLIBD/symop.lib"
    echo "Please set up CCP4, and then run \\\$0 again"
    goto Help
endif

set REINDEX
set axes
set FLIP = 0

#first, get filenames from the command line
foreach arg ( \\\$* )
    if("\\\$arg" =~ *.mtz) then
	if("\\\$mtzfile" == "") then
	    # havn't initialized this yet
	    if(-e "\\\$arg") then
		# check to make sure it is readable
		echo "HEAD" | mtzdump HKLIN \\\$arg >&! \\\${tempfile}mtzdump
		grep "Space group" \\\${tempfile}mtzdump >& /dev/null
		if(\\\$status) then
		    echo "WARNING: \\\$arg is not an MTZ file! "
		    continue
		endif
		set mtzfile = "\\\$arg"
	    else
		echo "WARNING: \\\$arg does not exist! "
		continue
	    endif
	else
	    # already have an input mtz, so assume this is output
	    set newmtzfile = "\\\$arg"
	    
	    # look for "hidden" space group in name? 
	    echo \\\$newmtzfile |\\\\
	     nawk '{for(i=1;i<=length(\\\$0);++i){c=substr(\\\$0,i,1);\\\\
	       if(c ~ /[PpCcIiFfRrHh1-6]/){printf "%s", c}else{print ""}}}' |\\\\
	     nawk '\\\$1~/^[PpCcIiFfRrHh][1-6]/' >! \\\${tempfile}SGs
	    foreach sg ( \\\`tail -10 \\\${tempfile}SGs\\\` )
		set temp = \\\`nawk -v SG=\\\$sg '\\\$4 == SG && \\\$1 < 500 {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
		if("\\\$temp" != "") then
		    set newSG = "\\\$temp"
		endif
	    end
	    rm -f \\\${tempfile}SGs >& /dev/null
	endif
    endif

    # check for new space group
    if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	# check for SGs listed in library (but not the screwy ones)
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	if(\\\$?CLIBD) then
	    set temp = \\\`nawk -v SG=\\\$temp '\\\$4 == SG && \\\$1 < 500 {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
	endif
	if("\\\$temp" != "") then
	    set newSG = "\\\$temp"
	endif
	
	set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	# check for orthorhombic "pseudo-spacegroup" language
	if("\\\$temp" == P2221) then
	    # P2221 with screw along longest axis
	    set axes  = "a b c"
	    set newSG = "P2221"
	    continue
	endif
	if("\\\$temp" == P2212) then
	    # P2221 with screw along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P2221"
	    continue
	endif
	if("\\\$temp" == P2122) then
	    # P2221 with screw along shortest axis
	    set axes  = "c a b"
	    set newSG = "P2221"
	    continue
	endif
	
	if("\\\$temp" == P21212) then
	    # P21212 with non-screw along longest axis
	    set axes  = "a b c"
	    set newSG = "P21212"
	    continue
	endif
	if("\\\$temp" == P21221) then
	    # P21212 with non-screw along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P21212"
	    continue
	endif
	if("\\\$temp" == P22121) then
	    # P21212 with non-screw along shotest axis
	    set axes  = "c a b"
	    set newSG = "P21212"
	    continue
	endif
	    
	if("\\\$temp" == P112) then
	    # P2 with twofold along longest axis
	    #set axes  = "a b c"
	    set newSG = "P2"
	    continue
	endif
	if("\\\$temp" == P121) then
	    # P2 with twofold along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P2"
	    continue
	endif
	if("\\\$temp" == P211) then
	    # P2 with twofold along shortest axis
	    set axes  = "c a b"
	    set newSG = "P2"
	    continue
	endif
	    
	if("\\\$temp" == P1121) then
	    # P21 with twofold along longest axis
	    #set axes  = "a b c"
	    set newSG = "P21"
	    continue
	endif
	if("\\\$temp" == P1211) then
	    # P21 with twofold along mid-length axis
	    set axes  = "b c a"
	    set newSG = "P21"
	    continue
	endif
	if("\\\$temp" == P2111) then
	    # P21 with twofold along shortest axis
	    set axes  = "c a b"
	    set newSG = "P21"
	    continue
	endif
    endif
	
    # check for flipping of ambiguous axes
    if("\\\$arg" == "flip") then
	# user requested "flip" of axes
	@ FLIP = ( \\\$FLIP + 1 )
    endif
    
    # what about cubic? 
end

if(! -e "\\\$mtzfile") then
    goto Help
endif

# get info from the MTZ (should be left over from command-line check)
set CELL  = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\${tempfile}mtzdump\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzdump \\\`
cat \\\$CLIBD/symop.lib |\\\\
nawk -v SGnum=\\\$SGnum '\\\$1==SGnum{type=substr(tolower(\\\$6),1,1); key=substr(\\\$6,4,1);\\\\
    if((type=="t")&&(key=="G")) type="h"; if((type=="t")&&(key=="C")) type="a";\\\\
    print \\\$1, \\\$5, type substr(\\\$4,1,1), \\\$6,\\\$4;}' |\\\\
head -1 >! \\\${tempfile}sgdata
set SGnum = \\\`nawk '{print \\\$1}' \\\${tempfile}sgdata\\\`
set SG    = \\\`nawk '{print \\\$5}' \\\${tempfile}sgdata\\\`
set PG    = \\\`nawk '{print \\\$2}' \\\${tempfile}sgdata\\\`
set BRAV  = \\\`nawk '{print \\\$3}' \\\${tempfile}sgdata\\\`
set LATT  = \\\`nawk '{print \\\$4}' \\\${tempfile}sgdata\\\`

if("\\\$newSG" == "") set newSG = "\\\$SG"
cat \\\$CLIBD/symop.lib |\\\\
nawk -v SG=\\\$newSG '\\\$4==SG{type=substr(tolower(\\\$6),1,1); key=substr(\\\$6,4,1);\\\\
    if((type=="t")&&(key=="G")) type="h"; if((type=="t")&&(key=="C")) type="a";\\\\
    print \\\$1, \\\$5, type substr(\\\$4,1,1), \\\$6;}' |\\\\
head -1 >! \\\${tempfile}sgdata
set newSGnum = \\\`nawk '{print \\\$1}' \\\${tempfile}sgdata\\\`
set newPG    = \\\`nawk '{print \\\$2}' \\\${tempfile}sgdata\\\`
set newBRAV  = \\\`nawk '{print \\\$3}' \\\${tempfile}sgdata\\\`
set newLATT  = \\\`nawk '{print \\\$4}' \\\${tempfile}sgdata\\\`
rm -f \\\${tempfile}sgdata >& /dev/null

# decide how/if to flip
if(\\\$FLIP) then
    if(("\\\$SG" =~ [IP][46]*)||("\\\$SG" =~ P3*12)||("\\\$SG" =~ [PIF]2*3)) then
	set REINDEX = "reindex k, h, -l"
	set message = "with a and b axes flipped"
    endif
    if(("\\\$SG" == R32)||("\\\$SG" =~ P3*21)) then
	set REINDEX = "reindex -h, -k, l"
	set message = "with a and b axes inverted"
    endif
    if(("\\\$SG" =~ [PR]3)||("\\\$SG" =~ P3[12])) then
	# four possibilities here...
	if(\\\$FLIP == 1) then
	    set REINDEX = "reindex k, h, -l"
	    set message = "with a and b axes flipped"
	endif
	if(\\\$FLIP == 2) then
	    set REINDEX = "reindex -h, -k, l"
	    set message = "with a and b axes inverted"
	endif
	if(\\\$FLIP >  2) then
	    set REINDEX = "reindex -k, -h, -l"
	    set message = "with a and b axes flipped and inverted"
	endif
    endif
    if("\\\$SG" == P1) then
	# permute the axes (from their cannonical order)
	if(\\\$FLIP == 1) set axes = "a b c"
	if(\\\$FLIP == 2) set axes = "b c a"
	if(\\\$FLIP == 3) set axes = "c a b"
    endif
    if("\\\$PG" == PG2) then
	# flip the a and c axes?
	set REINDEX = "reindex l, -k, h"
	set message = "with a and c axes flipped"
    endif
    # for other space groups, "flip" is simply ignored
endif

if(("\\\$newSG" == "")&&(! \\\$FLIP)) then
    # WTF?
    echo "nothing to do! "
    rm -f \\\${tempfile}mtzdump >& /dev/null
    goto Help
endif

# now that whole command-line has been read, make some holistic decisions


# check to see if it's merged or unmerged
grep "Number of Batches" \\\${tempfile}mtzdump >& /dev/null
if(\\\$status) then
    set MERGED
else
    set UNMERGED
endif
rm -f \\\${tempfile}mtzdump


# decide on new axis ordering (for asymmetric orthorhombics)
if("\\\$newSG" == "P222")    set axes = "a b c"
if("\\\$newSG" == "P212121") set axes = "a b c"
if("\\\$axes" != "") then
    # get current axis ordering
    # find out what the cannonical one would be
    # then decide how to go from current ordering to the desired one
    echo "\\\$CELL" | nawk '{\\\\
	# print out current axis order \\\\
	print \\\$1, "h"; print \\\$2, "k"; print \\\$3, "l"}' |\\\\
    sort -n |\\\\
    nawk '\\\\
	# add cannonical axis names\\\\
	NR==1{print \\\$0, "a"} NR==2{print \\\$0, "b"} NR==3{print \\\$0, "c"}' |\\\\
    nawk -v axes="\\\$axes" 'BEGIN{split(axes, abc)} {\\\\
	# write desired axis ordering in front of cannonical one \\\\
	print abc[NR], \\\$0}' |\\\\
    sort |\\\\
    nawk '# print out new hkl order \\\\
          {printf "%s ", \\\$3} END{print ""}' |\\\\
    nawk '\\\$1 \\\$2 \\\$3 \\\$1 \\\$2 \\\$3 !~ /hkl/{\\\$3 = "-" \\\$3} {print \\\$1, \\\$2, \\\$3}' |\\\\
    cat >! \\\${tempfile}order    
    set REINDEX = "reindex "\\\`nawk '{print \\\$1 ",", \\\$2 ",", \\\$3}'  \\\${tempfile}order\\\`

    # this should give us a mapping between any two orthorhombics
    
    set temp = \\\`nawk '{print \\\$NF}' \\\${tempfile}order\\\`
    rm -f \\\${tempfile}order
    if("\\\$newSG" == "P2221") then
	set message = "with screw along \\\$temp axis"
    endif
    if("\\\$newSG" == "P21212") then
	set message = "with non-screw along \\\$temp axis"
    endif
    if("\\\$newSG" == "P2") then
	set message = "with twofold along \\\$temp axis"
    endif
    if("\\\$newSG" == "P21") then
	set message = "with twofold screw along \\\$temp axis"
    endif
    if("\\\$newSG" == "P1") then
	set message = "with axes in \\\$axes order."
    endif
endif


# known ways to convert between bravais lattices
if(("\\\$newBRAV" == "oC")&&("\\\$BRAV" =~ h[PR])) then
    # this lattice happens to fit, even if it's merged
    set REINDEX = "reindex h+k, k-h, l"
    set message = "with old hkl -> h+k,k-h,l"
    set OKAY
endif
set change_type = \\\`echo \\\$SG \\\$newSG | nawk 'substr(\\\$1,1,1) != substr(\\\$2,1,1)'\\\`
# cubic to just about anything should be okay
if(("\\\$change_type" == "")&&("\\\$BRAV" =~ c*)&&("\\\$newBRAV" !~ h*)) set OKAY
# tetratonal to anything below it should be okay
if(("\\\$change_type" == "")&&("\\\$BRAV" =~ t*)&&("\\\$newBRAV" !~ h*)&&("\\\$newBRAV" !~ c*)) set OKAY
# orthorhombic to anything below it is okay

# anything can be converted to P1
if("\\\$newBRAV" == aP) set OKAY

# now check for unhandlable situations


if((\\\$?MERGED)&&("\\\$newPG" != "\\\$PG")&&("\\\$PG" != "")&&(! \\\$?OKAY)) then
    # can't do this
    echo "WARNING: You Shouldn't reindex \\\$SG to \\\$newSG for a merged mtz! "
    echo ""
    if(\\\$SGnum < \\\$newSGnum) then
	cat << EOF
Since \\\$newSG has higher symmetry than \\\$SG, we would have
to merge some "unique" spots in \\\$mtzfile together.  Although
this is technically possible, it is definitely not advisable.
If your space group really is \\\$newSG, you will probably get
much better scaling and mergeing performance with the new
symmetry imposed during data processing, and probably in
data reduction as well.

EOF
    else
	cat << EOF
Since \\\$SG has higher symmetry than \\\$newSG, we would have
to "unmerge" the unique HKLs in \\\$mtzfile to form multiple, 
yet completely identical Fs.  So, all this will do is
make your mtz bigger, so we will just change the spacegroup
name.

If you think you "overmerged" your data in \\\$SG, then you
should go back to your mergeing step, and change \\\$SG to
\\\$newSG there.

EOF
    endif
#    exit
endif

if(\\\$?MERGED) goto Return_from_Setup
# now we are dealing with unmerged data

# what do we do about THIS! 
set temp = \\\`echo "\\\$newSG \\\$SG" | nawk 'substr(\\\$1,1,1) != substr(\\\$2,1,1)'\\\`
if("\\\$temp" != "") then
    # crystal system has changed!
    if(\\\$newSGnum < \\\$SGnum) then
	# we are going to loose some data
	
    else
	
    endif
    echo "WARNING: changing the lattice symmetry "
endif

goto Return_from_Setup
EOF-reindexscript
chmod a+x \${scriptDIR}reindex.com









write_rrsps:

# don't overwrite user-modified script
if(-e \${scriptDIR}rrsps.com) goto write_bestFH


#echo "writing \${scriptDIR}rrsps.com"
cat << EOF-rrspsscript >! \${scriptDIR}rrsps.com
#! /bin/csh -f
#
#	\${scriptDIR}rrsps.com   - Recursive RSPS
#
#	For completely brute-force heavy atom searching :)
#
#   courtesy of the Phaser Elves
#
# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set SIGMA_CUTOFF = 3
set CLOSE_peaks  = 0.5
set MAX_SITES    = 30
set MAXPEAKS     = 300
set outfile      = "./rrsps.sites"

set mapfiles     = ""
set SGs          = ""
set mapfile      = ""
set SG           = ""
set fixxyzfile   = ""
set tempfile     = ./rrsps_tempfile
set bestscore    = 0

set SYMOP
goto Setup
#############################################################
#
#   scan command line for map filename, space group(s)
#   and "fixed" site list file
#
Help:
cat << EOF-Help
usage: \\\$0 patt.map P212121 3 sigma 30 sites

where:

patt.map    - is the Patterson map you want to solve (CCP4 format)
P212121	    - is the space group you want to try
3 sigma	    - only consider harker peaks > 3*sigma
30 sites    - maximum number of sites you expect to find

Note: you CAN specify more than one space group, 
      and/or more than one map file.  Each will be
      considered in turn.

EOF-Help

goto Cleanup_RSPS
#############################################################
ReturnFrom_Setup:

# this is the tricky one, this file MUST NOT be
# overwritten by the child processes! 
if(! \\\$?RRSPS_DEPTH) then
    # this must be the first instance
    setenv RRSPS_DEPTH 0

    # do multi-spacegroup run
    foreach mapfile ( \\\$mapfiles )
	echo "using \\\$mapfile"
	foreach SG ( \\\$SGs )
	    # recurse
	    #echo "trying \\\$SG"
	    
	    # initialize the cumulative files
	    echo -n "" >! \\\${tempfile}_\\\${SG}_biglist
	    echo -n "" >! \\\${outfile}_\\\${SG}
	    
	    # recurse
	    \\\$0 \\\$SG \\\$mapfile \\\$PASSALONG
	end
    end
    # we are done
    goto Cleanup_RSPS
endif


# if we reach this point 
# there is only one SG and one map
set mapfile = "\\\$mapfiles"
set SG      = "\\\$SGs"


# this variable keeps rrsps child runs from overwriting
# their parent job's files
@ temp = ( \\\$RRSPS_DEPTH + 1 )
setenv RRSPS_DEPTH \\\$temp
set unique = "\\\${tempfile}_\\\$RRSPS_DEPTH"


# skip over harker procedure on all but first instance
if(-e "\\\$fixxyzfile") goto cross_scan


harker_scan:
#############################################################
# kick-start heavy atom search with a harker scan
echo -n "\\\$SG harker scan... "
rsps \\\$SYMOP << EOF-harker >! \\\${tempfile}.log
spacegroup \\\$SG
patfile \\\$mapfile
scorfile \\\${tempfile}rsps.map

mode harker
reject 0
scan au
pick scoremap \\\$MAXPEAKS
EOF-harker
grep ERROR \\\${tempfile}.log
if(! \\\$status) then
    echo "RSPS failed! see rsps.error.log to find out why."
    mv \\\${tempfile}.log rsps.error.log
    goto Cleanup_RSPS
endif

# convert any peaks > sigma cutoff to new, potential sites
cat \\\${tempfile}.log |\\\\
nawk 'BEGIN{rms=999999} \\\\
    /Rms deviation from mean/ && \\\$NF+0 != 0{rms=\\\$NF+0}\\\\
    /ANGSTROM COORDINATES/{table=1} \\\\
    NF>7 && ! /[A-Za-z]/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7, \\\$8/rms}' |\\\\
nawk -v cutoff=\\\$SIGMA_CUTOFF '\\\$NF > cutoff' |\\\\
sort -nr -k7 >! \\\${unique}_newsites
#cat >! \\\${unique}_newsites

rm -f \\\${tempfile}.log     >& /dev/null
rm -f \\\${tempfile}rsps.map >& /dev/null

set hits = \\\`cat \\\${unique}_newsites | wc -l\\\`
set temp = \\\`tail -1 \\\${unique}_newsites | nawk '{printf "%.2f", \\\$NF}'\\\`
echo "\\\$hits hits > \\\$temp sigma"
if((\\\$hits == 0)||("\\\$SG" == "P1")) then
    # woops! no harker vectors!
    echo "0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 \\\$SIGMA_CUTOFF" >! \\\${unique}_newsites
endif


# now act like we just found this in a "regular" (cross) scan
set fixxyzfile = \\\${tempfile}.empty
touch \\\$fixxyzfile

goto Recurse





cross_scan:
#############################################################
# look for new sites, given that we already have 
# the sites listed in \\\$fixxyzfile

# tell RSPS to scan ASU for sites with cross-vectors to \\\$fixxyzfile
cat << EOF-cross >! \\\${tempfile}rsps.in
spacegroup \\\$SG
patfile \\\$mapfile
scorfile \\\${tempfile}rsps.map

mode cross
#reject 0
EOF-cross
cat \\\$fixxyzfile |\\\\
nawk '{print "fixxyz", \\\$1, \\\$2, \\\$3}' >> \\\${tempfile}rsps.in

# also get the "harker score", and avoid crossvector search peaks
# that don't have Harker peaks
cat << EOF-cross2 >> \\\${tempfile}rsps.in
scan au
pick scoremap \\\$MAXPEAKS
mode harker
vlist site 1 \\\$MAXPEAKS
EOF-cross2

# run rsps and convert any peaks > sigma cutoff to new, potential sites
cat \\\${tempfile}rsps.in | rsps |\\\\
nawk 'BEGIN{rms=999999} \\\\
    /Rms deviation from mean/ && \\\$NF+0 != 0{rms=\\\$NF+0}\\\\
    /ANGSTROM COORDINATES/{table=1} \\\\
    \\\$1=="SCORE"{++n; print n, \\\$3} \\\\
    NF>7 && ! /[A-Za-z]/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7}' |\\\\
nawk -v cutoff=\\\$SIGMA_CUTOFF '\\\\
      NF!=2{++n;line[n]=\\\$0}\\\\
      NF==2 && \\\$2+0>cutoff{print line[\\\$1], \\\$2}' |\\\\
sort -nr -k7 >! \\\${unique}_newsites
#cat >! \\\${unique}_newsites

rm -f \\\${tempfile}rsps.in  >& /dev/null
rm -f \\\${tempfile}rsps.map >& /dev/null

# filter out the fixxyz sites, and their symm mates

# generate all symmetry mates of fixed sites
cat \\\$fixxyzfile |\\\\
nawk -v SG=\\\$SG -v CELL="\\\$CELL" '\\\\
    BEGIN{print "SYMM", SG; print "CELL", CELL;\\\\
          print "XYZLIM -0.1 1.1 -0.1 1.1 -0.1 1.1"} \\\\
    {print "ATOM X", \\\$1, \\\$2, \\\$3}' |\\\\
gensym |\\\\
nawk '/List of sites/,/Normal termination/' |\\\\
nawk '\\\$2 ~ /[01].[0-9][0-9][0-9]/ {print \\\$5, \\\$6, \\\$7, "fixed"}' |\\\\
cat >! \\\${tempfile}fixxyz


cat \\\${tempfile}fixxyz \\\${unique}_newsites |\\\\
nawk -v cut=\\\$CLOSE_peaks ' \\\\
      \\\$NF=="fixed"{++n; X[n]=\\\$1; Y[n]=\\\$2; Z[n]=\\\$3} \\\\
      \\\$NF!="fixed"{minD=999999; \\\\
         # find nearest "old" site \\\\
         for(i=1;i<=n;++i){\\\\
	     dist=sqrt((\\\$4-X[i])^2 +(\\\$5-Y[i])^2 +(\\\$6-Z[i])^2);\\\\
	     if(dist < minD){\\\\
	     minD=dist;}}\\\\
	 # now see if it is too close \\\\
	 if(minD > cut) {print}}' |\\\\
cat >! \\\${tempfile}
mv \\\${tempfile} \\\${unique}_newsites





# now represent each "new site" as it's true, full constellation
# of cross-vector related peaks

# label the "fixxyz" sites, and their scores
cat \\\$fixxyzfile |\\\\
nawk '{print \\\$1, \\\$2, \\\$3, \\\$NF, "fixed"}' >! \\\${tempfile}fixxyz

# explode the list
nawk 'NF>3' \\\${tempfile}fixxyz \\\${unique}_newsites |\\\\
nawk -v SG=\\\$SG -v file=\\\$mapfile 'BEGIN{ bigscore=1;} \\\\
      \\\$NF=="fixed"{# collect list of fixed sites \\\\
          ++n; X[n]=\\\$1; Y[n]=\\\$2; Z[n]=\\\$3; score[n]=\\\$(NF-1); bigscore*=\\\$(NF-1)} \\\\
      \\\$NF!="fixed"{ printf "%11.1f ", bigscore*\\\$NF \\\\
          # print out all fixed sites first \\\\
          for(i=1;i<=n;++i){printf "%s %s %s ", X[i], Y[i], Z[i];}\\\\
	  # each new site goes in the middle \\\\
          printf "%s %s %s | %s %s ", \\\$1, \\\$2, \\\$3, SG, file; \\\\
          # sigma scores follow in the same order \\\\
	  for(i=1;i<=n;++i){printf "%s ", score[i]}; \\\\
	  print \\\$NF }' |\\\\
cat >> \\\${tempfile}_\\\${SG}_biglist



# update "best" group of sites yet
set bestscore = \\\`tail -1 \\\${outfile}_\\\$SG |& nawk '{print \\\$NF+0}'\\\`
sort -n \\\${tempfile}_\\\${SG}_biglist | tail -1 |\\\\
nawk 'BEGIN{FS="|"} {print \\\$1; print \\\$2}' |\\\\
nawk 'NR==1{n=0; bigscore=\\\$1; for(i=2;i<=NF;i+=3){++n; \\\\
	X[n]=\\\$i; Y[n]=\\\$(i+1); Z[n]=\\\$(i+2);}} \\\\
      NR==2{print \\\$1, "in", \\\$2; for(i=1;i<=n;++i){\\\\
        printf "%4d %8.5f %8.5f %8.5f %8.1f*sigma\\\\n", i, X[i], Y[i], Z[i], \\\$(i+2);}\\\\
	printf "product: %31.1f\\\\n", bigscore}' |\\\\
cat >! \\\${outfile}_\\\$SG

set temp = \\\`tail -1 \\\${outfile}_\\\$SG | nawk '{print \\\$NF+0}'\\\`
if("\\\$bestscore" != "\\\$temp") then
    echo ""
    cat \\\${outfile}_\\\$SG
    set bestscore = "\\\$temp"
endif


# don't need this anymore
rm -f \\\${tempfile}fixxyz >& /dev/null

Recurse:
#############################################################
# run down the list of all peaks we found, and launch
# a new instance of \\\$0 to look for more cross peaks

set site = 0
set sites = \\\`cat \\\${unique}_newsites | wc -l\\\`
while (( \\\$site < \\\$sites )&&(\\\$RRSPS_DEPTH < \\\$MAX_SITES))
    @ site = ( \\\$site + 1 )
    
    # use all the "fixxyz" sites we just used
    cat \\\$fixxyzfile >! \\\${unique}_fixxyz
    
    # and add the one site we are interested in
    cat \\\${unique}_newsites |\\\\
    nawk -v site=\\\$site 'NR==site' |\\\\
    cat >> \\\${unique}_fixxyz
    
    # here we go!
    if(\\\$RRSPS_DEPTH == 1) then
	# progress meter
	echo "\\\$site \\\$sites" | nawk '\\\$2+0>0 && \\\$1+0>1{printf "%d%%", 100*\\\$1/\\\$2}'
    endif
    echo -n "."
    \\\$0 \\\$SG \\\$mapfile \\\$PASSALONG \\\${unique}_fixxyz

    # each child will report it's own findings in \\\${tempfile}_\\\${SG}_biglist
end

# done with this file
rm -f \\\${unique}_fixxyz \\\${unique}_newsites >& /dev/null

goto Cleanup_RSPS


exit







Setup:

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
    set arg = "\\\$argv[\\\$i]"
    
    if(! -e "\\\$arg") then
	# space group
	if("\\\$arg" =~ [PpCcIiFfRrHh][1-6]*) then
	    set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
	    if(\\\$?CLIBD) then
		set temp = \\\`nawk -v SG=\\\$temp '\\\$4 == SG {print \\\$4}' \\\$CLIBD/symop.lib | head -1\\\`
	    endif
	    if("\\\$temp" != "") then
		# add this SG to the space group list
		set SGs = "\\\$SGs \\\$temp"
		continue
	    else
		# check for "pseudo-spacegroup" language
		set temp = \\\`echo \\\$arg | nawk '{print toupper(\\\$1)}'\\\`
		set temp = \\\`echo \\\$temp | nawk '/P2212|P2122|P21221|P22121/'\\\`
		if("\\\$temp" != "") then
		    # PG222 with screw along non-standard axis
		    set SGs = "\\\$SGs \\\$temp"
		    # create new spacegroup library for RSPS
		    if(! -e "\\\${tempfile}rsps_spacegroups") mkdir \\\${tempfile}rsps_spacegroups
                    if(! -e "\\\${tempfile}rsps_spacegroups/data") mkdir \\\${tempfile}rsps_spacegroups
		    cat \\\$CLIBD/symop.lib >! \\\${tempfile}rsps_spacegroups/symop.lib
		    set SYMOP = "SYMOP \\\${tempfile}rsps_spacegroups/symop.lib"
		endif
	    endif
	endif
	
	if("\\\$arg" =~ [0-9]*) then
	    # we have a number
	    set temp = \\\`echo "\\\$arg \\\$argv[\\\$nexti]" | nawk 'tolower(\\\$0)~/sigma\\\$/ || tolower(\\\$1)~/sigma\\\$/{if(\\\$1+0>0) print \\\$1+0}'\\\`
	    if("\\\$temp" != "") then
		set SIGMA_CUTOFF = "\\\$temp"
		@ i = ( \\\$i + 1 )
		continue
	    endif
	    
	    # maximum number of sites to find (recursion depth)
	    set temp = \\\`echo "\\\$arg \\\$argv[\\\$nexti]" | nawk 'tolower(\\\$0)~/sites\\\$/ || tolower(\\\$1)~/sites\\\$/{if((\\\$1+0>1)&&(int(\\\$1+0)==\\\$1+0)) print \\\$1+1}'\\\`
	    if("\\\$temp" != "") then
		set MAX_SITES = "\\\$temp"
		@ i = ( \\\$i + 1 )
		continue
	    endif
	endif
    endif
    
    # files
    if(-e "\\\$arg") then
	if("\\\$arg" =~ *.map) then
	    # check to see if it's a ccp4 map
	    set temp = \\\`echo "" | mapdump MAPIN \\\$arg |& nawk '/Cell dimensions/{print \\\$4, \\\$5, \\\$6, \\\$7, \\\$8, \\\$9}'\\\`
	    if("\\\$temp" != "") then
		set mapfiles = "\\\$mapfiles \\\$arg"
		set CELL = "\\\$temp"
	    else
		echo "WARNING: \\\$arg is not a CCP4 map! "
	    endif
	else
	    # see if this is a "site" file
	    egrep "[01].[0-9][0-9][0-9]" \\\$arg >& /dev/null
	    if(! \\\$status) then
		set temp = \\\`nawk '\\\$1~/^[0-1].[0-9][0-9][0-9]/ || \\\$1~/^-[0-1].[0-9][0-9][0-9]/ ' \\\$arg | wc -l\\\`
		if(\\\$temp > 0) then
		    # use as the "sites" file
		    set fixxyzfile = "\\\$arg"
		endif
	    endif
	endif
    endif
end

set SGs = \\\`echo "\\\$SGs"\\\`
set mapfiles = \\\`echo "\\\$mapfiles"\\\`
if((\\\$#mapfiles == 0) || (\\\$#SGs == 0)) goto Help
set PASSALONG = "\\\$MAX_SITES sites \\\$SIGMA_CUTOFF sigma"


# extend spacegroup library
if("\\\$CLIBD" == "\\\${tempfile}rsps_spacegroups") then
    # add pseudo-spacegroups
    cat << EOF-new_sg_lib >> \\\${CLIBD}/symop.lib
1017 4 4 P2122 PG222 ORTHORHOMBIC 'P 21 2 2' !(unique axis a)
 X,Y,Z 
 -X,Y,-Z 
 1/2+X,-Y,-Z 
 1/2-X,-Y,Z
2017 4 4 P2212 PG222 ORTHORHOMBIC 'P 2 21 2' !(unique axis b)
 X,Y,Z 
 X,1/2-Y,-Z 
 -X,1/2+Y,-Z 
 -X,-Y,Z
1018 4 4 P21212a PG222 ORTHORHOMBIC 'P 21 21 2 (a)' ! origin on 21 21, shift (1/4,1/4,0)
 X,Y,Z 
 1/2-X,1/2-Y,Z 
 X+1/2,-Y,-Z 
 -X,Y+1/2,-Z
2018 4 4 P21221 PG222 ORTHORHOMBIC 'P 21 2 21'  !(unique axis b)
 X,Y,Z 
 -X,Y,-Z 
 1/2+X,-Y,1/2-Z 
 1/2-X,-Y,1/2+Z
3018 4 4 P22121 PG222 ORTHORHOMBIC 'P 2 21 21'  !(unique axis a)
 X,Y,Z 
 X,-Y,-Z 
 -X,1/2+Y,1/2-Z 
 -X,1/2-Y,1/2+Z
1020 2 1 C2221a PG222 ORTHORHOMBIC 'C 2 2 21a)' ! P212121 with C centring, shift(1/4,0,0)
 X,Y,Z 
 1/2-X,-Y,1/2+Z 
 1/2+X,1/2-Y,-Z 
 -X,1/2+Y,1/2-Z
 1/2+X,1/2+Y,Z 
 -X,1/2-Y,1/2+Z 
 X,-Y,-Z 
 1/2-X,Y,1/2-Z
1021 2 1 C222a PG222 ORTHORHOMBIC 'C 2 2 2a'  ! C21212a origin on 21 21
 X,Y,Z 
 1/2-X,1/2-Y,Z 
 X+1/2,-Y,-Z 
 -X,Y+1/2,-Z
 1/2+ X,1/2+Y,Z 
 -X,-Y,Z 
 X,1/2-Y,-Z 
 1/2-X,Y,-Z
1022 4 1 F222a PG222 ORTHORHOMBIC 'F 2 2 2a' ! same as 1018 with face centring ! shift (1/4,0,0)
 X,Y,Z         
 1/2-X,1/2-Y,Z 
 X+1/2,-Y,-Z 
 -X,Y+1/2,-Z
 X,Y+1/2,Z+1/2 
 1/2-X,-Y,Z+1/2 
 X+1/2,-Y+1/2,-Z+1/2 
 -X,Y,-Z+1/2
 X+1/2,Y,Z+1/2 
 -X,1/2-Y,Z+1/2 
 X,-Y,-Z+1/2 
 -X+1/2,Y+1/2,-Z+1/2
 X+1/2,Y+1/2,Z 
 -X,-Y,Z 
 X,-Y+1/2,-Z 
 -X+1/2,Y,-Z
EOF-new_sg_lib
endif


goto ReturnFrom_Setup


Cleanup_RSPS:


if(! \\\$?RRSPS_DEPTH) set RRSPS_DEPTH = -1

if(\\\$RRSPS_DEPTH == 0) then
    # the "real" finish
    echo ""
    echo "done! "
    
    foreach SG ( \\\$SGs )
	echo ""
	echo -n "best solution for "
	cat \\\${outfile}_\\\$SG

	sort -nr \\\${tempfile}_\\\${SG}_biglist |\\\\
	nawk 'BEGIN{FS="|"} NF==2{print \\\$1; print \\\$2}' |\\\\
	nawk 'NR%2==1{n=0; bigscore=\\\$1; for(i=2;i<=NF;i+=3){++n; \\\\
		X[n]=\\\$i; Y[n]=\\\$(i+1); Z[n]=\\\$(i+2);}} \\\\
	      NR%2==0{print ""; print \\\$1, "in", \\\$2; for(i=1;i<=n;++i){\\\\
	        printf "%4d %8.5f %8.5f %8.5f %8.1f*sigma\\\\n", i, X[i], Y[i], Z[i], \\\$(i+2);}\\\\
		printf "product: %31.1f\\\\n", bigscore}' |\\\\
	cat >! \\\${outfile}_\\\$SG
	echo "full listing for \\\$SG is in \\\${outfile}_\\\$SG"
	
	rm -f \\\${tempfile}_\\\${SG}_biglist >& /dev/null
    end
    
    rm -f \\\${tempfile}.empty >& /dev/null
endif

rm -rf \\\${tempfile}rsps_spacegroups/ >& /dev/null


exit

########################
# Future plans

- fix the non-standard orthorhombic implementation

EOF-rrspsscript
chmod a+x \${scriptDIR}rrsps.com




















write_bestFH:
#################################################################################

# don't overwrite user-modified script
if(-e \${scriptDIR}bestFH.com) goto write_dm

cat << EOF-bestFH_script >! \${scriptDIR}bestFH.com
#! /bin/csh -f
#
#
#	bestFH.com 				-James Holton 8-25-00
#
#	calculate a "best" estimate of F for the heavy atoms
#	alone (a la B. W. Matthews 1966 Acta Cryst 20, 230-239)
#	by combining ALL anomalous and isomorphous differences.  
#	(as many as you want)
#
#	FH should give cleaner Pattersons, difference Fouriers,
#	and direct methods.
#
#	Do NOT combine differences from data sets expected to have
#	different heavy atom locations.  That would be silly.
#
#
# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

set mtzfile   = "\$mtzfile"		# data sets
set outfile   = "./FH.mtz"		# contains FH, SIGFH
set shelxfile = "./fh.hkl"		# same thing, shelx format
set fourfile  = "./FH_Four.map"		# Phased Fourier of FH (if phase is available)
set pattfile  = "./FH_Patt.map"		# Combined Patterson map
set wpattfile = "./wFH_Patt.map"	# Combined, weighted Patterson map
set logfile   = "./bestFH.log"		# all the CCP4 logs

set tempfile = ./bestFH_temp


# initialize internal variables
set loRES = 1000
set hiRES = ""
set order = ""		# "order" of increasing dispersive signal data sets

set DATA_cutoff = 1	# sigma cutoff      (not used)
set MAX_dano 		# upper Dano cutoff (not used)
set MAX_diso		# upper Diso cutoff (not used)
set scaling = scale	# apply one scale to each difference data set
#set scaling = isotropic # use a B-factor too (wise? )

if(\\\$#argv == 0) goto Help

# this procedure (re)sets most of the above variables
# from either the provided files, or the command line
goto Setup

Help:
cat << EOF

usage: \\\$0 alldata.mtz

where:
alldata.mtz	- contains all the Fs and DANOs you want to combine

\\\`basename \\\$0\\\` will calculate an (unscaled) estimate of FH, the scattering factor
of the heavy metal alone, by combining any and all anomalous and isomorphous
(dispersive) differences made available to it.  The procedure is derived
from Matthews et. al. 1966 Acta Cryst 20, 230.

FH is better than Dano or Diso alone, both because the averaging tends
to give better signal/noise, and because considering BOTH isomorphous
and anomalous simultaneously reduced the systematic errors arising
from cross-terms in difference intensity data.  FH usually gives 
cleaner Pattersons and difference Fouriers, as well as improved 
performace of direct methods programs.

Procedure:
The isomorphous difference data sets are computed from the provided Fs,
(assigned a sign), scaled together, and a sigma-weighed mean isomorphous 
difference is computed.  A similar procedure is applied to the anomalous 
differences.

The average Diso and Dano data sets are then scaled to each other, and
combined for the final estimate of FH = sqrt(Diso^2 + k * Dano^2).

REMEMBER: Do NOT combine differences from data sets expected to have
different heavy atom locations.  That would be silly.  If you don't
know why, you should read Matthews et. al. 1966 Acta Cryst 20, 230.

EOF

rm -f \\\${tempfile}Fs >& /dev/null
rm -f \\\${tempfile}Ds >& /dev/null
rm -f \\\${tempfile}Ps >& /dev/null
rm -f \\\${tempfile}Fpairs >& /dev/null
exit 2
#
#   This procedure (at the bottom of the script) does the following
#   1) scan the command line for the mtz file
#   2) set the CELL, SG, and other variables
#   3) generate dataset name lists: \\\${tempfile}Fs and \\\${tempfile}Ds
Return_from_Setup:






################################################################
#   initial report on intended program flow
################################################################
# start the logfile
echo "" >! \\\$logfile
echo "\\\$0 \\\$*" >> \\\$logfile

if(-e "\\\$mtzfile") then
    echo "calculating FH from data in \\\$mtzfile" | tee -a \\\$logfile
endif

echo "" | tee -a \\\$logfile
echo "resolution \\\$loRES \\\$hiRES" | tee -a \\\$logfile
# get a "better" resolution limit for scaling?
set scaleRES = "\\\$loRES \\\$hiRES"

# count how many datasets we have
set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`
set Ds = \\\`cat \\\${tempfile}Ds | wc -l\\\`

# trivial assignments of dispersive difference order
# (2 datasets -> doesn't matter)
# (1 dataset  -> unusable)
if(\\\$Fs < 3) set order = \\\`nawk '{print \\\$1}' \\\${tempfile}Fs\\\`
if(\\\$Fs < 2) set order = ""

# if user doesn't care, pick Diso ordering automatically
if(("\\\$order" == "")&&(\\\$Fs > 2)) then
    
    echo -n "Evaluating difference data "
    echo -n "" >! \\\${tempfile}diso_dano
    
    # make a list of essential pairs
    cat \\\${tempfile}Fs |\\\\
    nawk '{++n; F[n]=\\\$1} \\\\
          END{for(i=1;i<=n;++i){for(j=i;j<=n;++j){if(i!=j){\\\\
              print F[i] " - " F[j];}}}}' |\\\\
    cat >! \\\${tempfile}Fpairs
    
    foreach pair ( \\\`nawk '{print NR}' \\\${tempfile}Fpairs\\\` )
	# retrieve the pair  
	set F1 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$1}' \\\${tempfile}Fpairs\\\`
	set F2 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$3}' \\\${tempfile}Fpairs\\\`
	
	# and get the sigmas too
	set SIGF1 = \\\`nawk -v F=\\\$F1 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
	set SIGF2 = \\\`nawk -v F=\\\$F2 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
	
	# also, get magnitudes of anomalous diffs
	if(\\\$Ds != 0) then
	    @ i = ( ( \\\$pair  % \\\$Ds ) + 1 )
	    set DANO    = \\\`nawk -v n=\\\$i 'NR==n{print \\\$1}' \\\${tempfile}Ds\\\`
	    set SIGDANO = \\\`nawk -v n=\\\$i 'NR==n{print \\\$2}' \\\${tempfile}Ds\\\`

	    set DANOcards = "DPH1=\\\$DANO SIGDPH1=\\\$SIGDANO"
	else
	    set DANOcards = ""
	endif
    
	# make some ordinary scaleit cards
	cat << EOF-scaleitin >! \\\${tempfile}scaleit.in
RESOLUTION \\\$scaleRES
refine \\\$scaling
weight
LABIN FP=\\\$F1 SIGFP=\\\$SIGF1 -
      FPH1=\\\$F2 SIGFPH1=\\\$SIGF2 \\\$DANOcards
END
EOF-scaleitin
	
	# entertainment
	echo -n "."
	
	# put the labels in the log file
	echo -n "\\\$F1 \\\$F2 \\\$DANO " >> \\\${tempfile}diso_dano
	
	# run scaleit to get Diso and Dano
	cat \\\${tempfile}scaleit.in |\\\\
	scaleit HKLIN \\\$mtzfile HKLOUT /dev/null |\\\\
	nawk '/Sc_kraut SCALE/{iso=index(\\\$0,"diso")-4; ano=index(\\\$0,"")+3}\\\\
	/THE TOTALS/{print substr(\\\$0,iso)+0, substr(\\\$0,ano)+0}' |\\\\
	cat >> \\\${tempfile}diso_dano
	
	# \\\${tempfile}diso_dano has format: F1 F2 DANOF3   
    end
    rm -f \\\${tempfile}Fpairs >& /dev/null
    rm -f \\\${tempfile}scaleit.in >& /dev/null

    # get the single largest isomorphous difference
    set order = \\\`sort -n -k4 \\\${tempfile}diso_dano | tail -1 | nawk '{print \\\$2}'\\\`
    if("\\\$order" == "") then
	echo ""
	echo "no isomorphous differences"
	echo "estimating FH requires isomorphous/dispersive and anomalous differences! "
	echo "Therefore: \\\$mtzfile needs to contain at least two columns of Fs"
	echo "sorry"
	goto Clean_up
    endif

    # now order the remaining datasets with increasing distance from this "native"
    cat \\\${tempfile}diso_dano |\\\\
    nawk -v ref=\\\$order 'BEGIN{print ref, 0, "order"} \\\\
       \\\$1==ref{print \\\$2, \\\$4} \\\$2==ref{print \\\$1, \\\$4}' |\\\\
    sort -n -k2 >! \\\${tempfile}order
    # \\\${tempfile}order has format: F diso(from Fref)
    
    # store the new order in a variable
    set order = \\\`nawk '{print \\\$1}' \\\${tempfile}order\\\`

    # make sure nothing bad happened (this isn't exactly ergodic! )
    set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`
    if(\\\$#order != \\\$Fs) then
	# something has gone horribly wrong
	echo "ERROR: unable to determine the best order of"
	echo "       isomorphous/dispersive differences"
	echo "sorry! "
	echo ""
	goto Help
    endif
    
    # reorder the Dano list too (doesn't really matter)
    cat \\\${tempfile}diso_dano \\\${tempfile}Ds |\\\\
    nawk 'NF>2{dano[\\\$3]=\\\$5} \\\\
          NF==2{print \\\$0, dano[\\\$1]}' |\\\\
    sort -nru -k3 |\\\\
    nawk '{print \\\$1, \\\$2}' >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}Ds >& /dev/null

    # clean up
    rm -f \\\${tempfile}scaleit.in >& /dev/null
    rm -f \\\${tempfile}diso_dano >& /dev/null
endif

# whatever its source, put the f' order in a file
echo "\\\$order" |\\\\
nawk 'BEGIN{RS=" "} NF==1{++i; print \\\$1, "order"}' |\\\\
cat >! \\\${tempfile}order

# re-order the Fs list
cat \\\${tempfile}Fs \\\${tempfile}order |\\\\
nawk '\\\$NF!="order"{sig[\\\$1]=\\\$2} \\\\
      \\\$NF=="order"{print \\\$1, sig[\\\$1]}' |\\\\
cat >! \\\${tempfile}
mv \\\${tempfile} \\\${tempfile}Fs >& /dev/null
set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`



# print out final ordering results:
echo ""
echo -n " f' order: "
cat \\\${tempfile}Fs | nawk '{printf "%s ", \\\$1} END{print ""}'

echo -n " f"\\\\"" order: "
cat \\\${tempfile}Ds | nawk '{printf "%s ", \\\$1} END{print ""}'

# clean up
rm -f \\\${tempfile}order >& /dev/null


# jump ahead if there are no anomalous datasets (why bother?)
if("\\\$Ds" == 0) then
    # make sure this doesn't exist (this is a signal later on)
    rm -f \\\${tempfile}dano.mtz >& /dev/null
    goto calculate_iso
endif

# no need to weigh anomalous datasets if there is only one of them
if("\\\$Ds" == 1) then
    # all we need to do is rename the dataset
    set temp = \\\`cat \\\${tempfile}Ds\\\`
    # better than crashing, (I guess)
    if(\\\$#temp != 2) set temp = ( \\\$temp \\\$temp )

    echo "extracting \\\$temp[1] as Dano"
    cad hklin1 \\\$mtzfile hklout \\\${tempfile}dano.mtz << EOF-cad >> \\\$logfile
    LABIN FILE 1 E1=\\\$temp[1] E2=\\\$temp[2]
    CTYPO FILE 1 E1=F        E2=Q
    LABOU FILE 1 E1=Dano     E2=SIGDano
EOF-cad

    # go on to calculate isomorphous differences
    goto calculate_iso
endif

weigh_ano:
echo ""
echo "weighting anomalous differences"

# extract the anomalous differences, and treat them as Fs
cat \\\${tempfile}Ds |\\\\
nawk '{printf "%s %s ", \\\$1, \\\$2} END{print ""}' |\\\\
nawk 'BEGIN{printf "LABIN FILE 1 ";} \\\\
{for(i=1;i<=NF;++i){printf "E%d=%s ", i, \\\$i}; printf "\\\\nCTYPIN FILE 1 "; \\\\
 for(i=1;i<=NF;i+=2){printf "E%d=F E%d=Q ", i, i+1}; print ""}' |\\\\
cad HKLIN1 \\\$mtzfile HKLOUT \\\${tempfile}danos.mtz >> \\\$logfile

# put anomalous diffs on the same scale
set i = 1
echo -n "" >! \\\${tempfile}scaleit.log
while( \\\$i <= \\\$Ds )
    cat << EOF-scaleitin >! \\\${tempfile}scaleit.in
RESOLUTION \\\$scaleRES
#refine scale
refine \\\$scaling
weight
EOF-scaleitin

    # make the LABIN card (not too many FPHs! )
    head -1 \\\${tempfile}Ds |\\\\
    nawk '{printf "LABIN FP=%s SIGFP=%s ", \\\$1, \\\$2}' |\\\\
    cat >> \\\${tempfile}scaleit.in
    
    # no more than 6 at a time
    cat \\\${tempfile}Ds |\\\\
    nawk -v first=\\\$i '{++n} n>=first && n<(first+6){++i;\\\\
	printf "-\\\\nFPH%d=%s SIGFPH%d=%s ", i, \\\$1, i, \\\$2} \\\\
    END {print "\\\\nEND"}' |\\\\
    cat >> \\\${tempfile}scaleit.in
    
    # now actually run scaleit
    cat \\\${tempfile}scaleit.in |\\\\
    scaleit HKLIN \\\${tempfile}danos.mtz \\\\
            HKLOUT \\\${tempfile}danoscaled.mtz |\\\\
     tee -a \\\${tempfile}scaleit.log >> \\\$logfile
    
    # accumulate scaled datasets
    mv \\\${tempfile}danoscaled.mtz \\\${tempfile}danos.mtz >& /dev/null
    @ i = ( \\\$i + 6 )
end
mv \\\${tempfile}danos.mtz \\\${tempfile}danoscaled.mtz >& /dev/null

# print out "weights" (effective weighting is 1/scale^2)
cat \\\${tempfile}scaleit.log |\\\\
nawk '/APPLICATION OF SCALES/,/--------------------------/' |\\\\
nawk '\\\$1 == "Derivative"{++i; print \\\$1, i, \\\$3}' >! \\\${tempfile}scales

cat \\\${tempfile}Ds \\\${tempfile}scales |\\\\
nawk 'NF==2{++n; label[n]=\\\$1; if(length(\\\$1)>maxlen) maxlen=length(\\\$1)}\\\\
    \\\$1 == "Derivative"{w=0; if(\\\$3+0!=0) w=1/(\\\$3*\\\$3)\\\\
    printf "%-" maxlen "s : %.3f\\\\n", label[\\\$2], w}' |\\\\
sort -nr -k3


rm -f \\\${tempfile}scaleit.log >& /dev/null
rm -f \\\${tempfile}scales      >& /dev/null


combine_ano:
echo "combining anomalous differences into Dano"

# now do a sigma-weighted average of all anomalous diffs
set Ds = \\\`cat \\\${tempfile}Ds | wc -l\\\`
echo \\\$Ds | nawk '{print "NREF -1"; print "FORMAT \\\\047(3i5,"\\\$1*2"f15.7)\\\\047"}' |\\\\
mtzdump HKLIN \\\${tempfile}danoscaled.mtz |\\\\
nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
nawk '! /[A-Z]/ && NF>3{HKL=substr(\\\$0,1,15); sum=norm=n="";\\\\
    # run down list of D, sigD \\\\
    for(i=4;i0){w=1/(sigD*sigD); sum+=w*D; norm+=w;}}\\\\
    # do not print anything for "all-missing" HKLs \\\\
    # print zero for all-zero hkls \\\\
    if(norm==0) print HKL, 0, 0; \\\\
    # print sigma-weighted average (abs value? ) \\\\
    if(norm+0 > 0) print HKL, sum/norm, 1/sqrt(norm)}' |\\\\
cat >! \\\${tempfile}dano.hkl
rm -f \\\${tempfile}danoscaled.mtz >& /dev/null


f2mtz HKLIN \\\${tempfile}dano.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
CELL \\\$CELL
SYMM \\\$SGnum
LABOUT H K L Dano SIGDano
CTYPO  H H H F Q
EOF-f2mtz
rm -f \\\${tempfile}dano.hkl >& /dev/null

echo "H K L" |\\\\
sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\${tempfile}dano.mtz >> \\\$logfile
rm -f \\\${tempfile}sortme.mtz

# indicate finish
echo ""

# summed anomalous diffs should now be loaded into:
# \\\${tempfile}dano.mtz, labeled as Dano SIGDano



calculate_iso:
###########################################################
# now we need to calculate isomorphous diffs 
# before we can treat them as we did the anomalous diffs


# jump ahead if there are no isomorphous datasets (why bother?)
if("\\\$Fs" < 2) then
    # make sure this doesn't exist (this is a signal later on)
    rm -f \\\${tempfile}diso.mtz >& /dev/null
    goto compute_k
endif

if(\\\$Fs == 2) then
    echo "calculating isomorphous (dispersive) difference as Diso"
else
    echo "subtracting isomorphous (dispersive) differences"
    echo "note: f' differences should all have the same sign! "
endif

# make sure this doesn't already exist
rm -f \\\${tempfile}disos.mtz >& /dev/null

# make list with largest difference first
cat \\\${tempfile}Fs |\\\\
nawk '{++n; F[n]=\\\$1} \\\\
    END{for(i=1;i<=n;++i){for(j=n;j>i;--j){if(i!=j){\\\\
    print F[i] " - " F[j];}}}}' |\\\\
cat >! \\\${tempfile}Fpairs
set Fpairs = \\\`cat \\\${tempfile}Fpairs | wc -l\\\`
set pair = 0

while ( \\\$pair < \\\$Fpairs )
    @ pair = ( \\\$pair + 1 )
    # retrieve the pair  
    set F1 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$1}' \\\${tempfile}Fpairs\\\`
    set F2 = \\\`nawk -v pair=\\\$pair 'NR==pair{print \\\$3}' \\\${tempfile}Fpairs\\\`
    
    # and get the sigmas too
    set SIGF1 = \\\`nawk -v F=\\\$F1 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
    set SIGF2 = \\\`nawk -v F=\\\$F2 '\\\$1==F{print \\\$2}' \\\${tempfile}Fs\\\`
    
    echo "\\\${F1}-\\\${F2}"
    
    # extract these columns from the file
    echo "LABIN FILE 1 E1=\\\$F1 E2=\\\$SIGF1 E3=\\\$F2 E4=\\\$SIGF2" |\\\\
    cad HKLIN1 \\\$mtzfile HKLOUT \\\${tempfile}dump.mtz >> \\\$logfile
    
    # dump the Fs as text, calculate F1-F2 sqrt(SIG1^2+SIG2^2)
    echo "NREF -1" |\\\\
    mtzdump HKLIN \\\${tempfile}dump.mtz |\\\\
    nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
    nawk '! /[A-Z?]/ && NF>1{HKL=substr(\\\$0,1,13);\\\\
        F1=substr(\\\$0,14,12); F2=substr(\\\$0,36,10);\\\\
	SIGF1=substr(\\\$0,26,10); SIGF2=substr(\\\$0,46,10); \\\\
     print HKL, F1-F2, sqrt(SIGF1*SIGF1 + SIGF2*SIGF2)}' |\\\\
    cat >! \\\${tempfile}diso.hkl
    rm -f \\\${tempfile}dump.mtz >& /dev/null
    
    # special case: only one difference set
    if(\\\$Fs == 2) set pair = ""

    # read back into mtz format
    f2mtz HKLIN \\\${tempfile}diso.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
    CELL \\\$CELL
    SYMM \\\$SGnum
    LABOUT H K L Diso\\\${pair} SIGDiso\\\${pair}
    CTYPO  H H H F Q
EOF-f2mtz
    rm -f \\\${tempfile}diso.hkl >& /dev/null
    
    if("\\\$pair" == "") set pair = 999    
    
    # sort it (just in case)
    echo "H K L" |\\\\
    sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\${tempfile}diso.mtz >> \\\$logfile
    rm -f \\\${tempfile}sortme.mtz
    
    # add columns into an mtz
    if(-e \\\${tempfile}disos.mtz) then
	cad HKLIN1 \\\${tempfile}disos.mtz HKLIN2 \\\${tempfile}diso.mtz \\\\
	    HKLOUT \\\${tempfile}cadded.mtz << EOF-cadadd >> \\\$logfile
	LABIN FILE 1 ALL
	LABIN FILE 2 ALL
EOF-cadadd
	# update the cumulative mtz
	mv \\\${tempfile}cadded.mtz \\\${tempfile}disos.mtz
    else
	# create the cumulative mtz
	mv \\\${tempfile}diso.mtz \\\${tempfile}disos.mtz
    endif
end


# check for trivial case: one difference dataset
if(\\\$Fs <= 2) then
    # no need to calculate relative weights for one dataset
    mv \\\${tempfile}disos.mtz \\\${tempfile}diso.mtz
    
    goto compute_k
endif


weigh_iso:
echo "weighting isomorphous differences"

# now put all these differences on the same scale
set pair = 1
set Fpairs = \\\`cat \\\${tempfile}Fpairs | wc -l\\\`
echo -n "" >! \\\${tempfile}scaleit.log 
while ( \\\$pair <= \\\$Fpairs )
    cat << EOF-scaleitin >! \\\${tempfile}scaleit.in
RESOLUTION \\\$scaleRES
#refine scale
refine \\\$scaling
weight
EOF-scaleitin
    # first one is the reference
    echo -n "LABIN FP=Diso1 SIGFP=SIGDiso1 " >> \\\${tempfile}scaleit.in
    
    # scale 6 at a time
    cat \\\${tempfile}Fpairs |\\\\
    nawk -v first=\\\$pair '{++n} n>=first && n<(first+6){++i;\\\\
	printf "-\\\\nFPH%d=Diso%d SIGFPH%d=SIGDiso%d ", i, n, i, n;}\\\\
	END{print "\\\\nEND"}' |\\\\
    cat >> \\\${tempfile}scaleit.in
    
    # run scaleit
    cat \\\${tempfile}scaleit.in |\\\\
    scaleit HKLIN \\\${tempfile}disos.mtz \\\\
            HKLOUT \\\${tempfile}disoscaled.mtz  |\\\\
     tee -a \\\${tempfile}scaleit.log >> \\\$logfile
    rm -f \\\${tempfile}scaleit.in >& /dev/null

    @ pair = ( \\\$pair + 6 )
    
    # output is input for next round of scaling
    mv \\\${tempfile}disoscaled.mtz \\\${tempfile}disos.mtz >& /dev/null
end
mv \\\${tempfile}disos.mtz \\\${tempfile}disoscaled.mtz >& /dev/null


# print out "weights" (effective weighting is 1/scale^2)
cat \\\${tempfile}scaleit.log |\\\\
nawk '/APPLICATION OF SCALES/,/--------------------------/' |\\\\
nawk '\\\$1 == "Derivative"{++n; print \\\$1, n, \\\$3}' >! \\\${tempfile}scales

cat \\\${tempfile}Fpairs \\\${tempfile}scales |\\\\
nawk '\\\$2 == "-"{++n; label[n]=\\\$1 \\\$2 \\\$3; if(length(label[n])>maxlen) maxlen=length(label[n])}\\\\
    \\\$1 == "Derivative"{w=0; if(\\\$3+0!=0) w=1/(\\\$3*\\\$3)\\\\
    printf "%-" maxlen "s : %.3f\\\\n", label[\\\$2], w}' |\\\\
sort -nr -k3

rm -f \\\${tempfile}scaleit.log >& /dev/null
rm -f \\\${tempfile}scales      >& /dev/null



combine_iso:
echo "combining isomorphous differences into Diso"

# add these scaled data sets together (sigma-weighted again)
# (hopefully, our "ordering" procedure has made sure all
#  these differences have the same sign)
set Fpairs = \\\`cat \\\${tempfile}Fpairs | wc -l\\\`
rm -f \\\${tempfile}Fpairs >& /dev/null

echo \\\$Fpairs | nawk '{print "NREF -1"; print "FORMAT \\\\047(3i5,"\\\$1*2"f15.7)\\\\047"}' |\\\\
mtzdump HKLIN \\\${tempfile}disoscaled.mtz |\\\\
nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
nawk '! /[A-Z]/ && NF>3{HKL=substr(\\\$0,1,15); sum=norm=n="";\\\\
    # run down list of D, sigD \\\\
    for(i=4;i0){w=1/(sigD*sigD); sum+=w*D; norm+=w;}}\\\\
    # do not print anything for "all-missing" HKLs \\\\
    # print zero for all-zero hkls \\\\
    if(norm==0) print HKL, 0, 0; \\\\
    # print sigma-weighted average (abs value?) \\\\
    if(norm+0 > 0) print HKL, sum/norm, 1/sqrt(norm)}' |\\\\
cat >! \\\${tempfile}diso.hkl
rm -f \\\${tempfile}disoscaled.mtz >& /dev/null

# read the averaged isomorphous differences back into an mtz
f2mtz HKLIN \\\${tempfile}diso.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
CELL \\\$CELL
SYMM \\\$SGnum
LABOUT H K L Diso SIGDiso
CTYPO  H H H F Q
EOF-f2mtz
rm -f \\\${tempfile}diso.hkl >& /dev/null

echo "H K L" |\\\\
sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\${tempfile}diso.mtz >> \\\$logfile
rm -f \\\${tempfile}sortme.mtz

# indicate finish



compute_k:
##############################################################
# now we need the "k" that will put Diso and Dano on the same
# scale: k/2 = <|Diso|>/<|Dano|>

##############################################################
echo ""

# handle special cases
if((\\\$Ds == 0)&&(\\\$Fs <= 1)) then
    # this should never happen, but...
    echo "ERROR: no difference data in \\\${mtzfile}! "
    goto Help
endif
if(\\\$Ds == 0) then
    # anomalous difference data is totally missing
    # just rename the isomorphous differences
    echo "WARNING: treating Diso data as FH (FH is better with Dano and Diso)"
    cad hklin1 \\\${tempfile}diso.mtz hklout \\\${tempfile}sortme.mtz << EOF >> \\\$logfile
    labin file 1 E1=Diso E2=SIGDiso
    labou file 1 E1=FH   E2=SIGFH
EOF
    rm -f \\\${tempfile}diso.mtz >& /dev/null
    rm -f \\\${tempfile}dano.mtz >& /dev/null
    set wpattfile = ""

    goto sort_final
endif
if(\\\$Fs <= 1) then
    # isomorphous difference data is totally missing
    # just re-name the anomalous differences
    echo "WARNING: treating Dano data as FH (FH is better with Dano and Diso)"
    cad hklin1 \\\${tempfile}dano.mtz hklout \\\${tempfile}sortme.mtz << EOF >> \\\$logfile
    labin file 1 E1=Dano E2=SIGDano
    labou file 1 E1=FH   E2=SIGFH
EOF
    rm -f \\\${tempfile}diso.mtz >& /dev/null
    rm -f \\\${tempfile}dano.mtz >& /dev/null
    set wpattfile = ""

    goto sort_final
endif

##############################################################
echo -n "scaling Diso to Dano  "

# use scaleit to put Diso and Dano on the same scale
cad HKLIN1 \\\${tempfile}diso.mtz HKLIN2 \\\${tempfile}dano.mtz \\\\
HKLOUT \\\${tempfile}diso_dano.mtz << EOF-cad >> \\\$logfile
LABIN FILE 1 ALL
LABIN FILE 2 ALL
EOF-cad
rm -f \\\${tempfile}diso.mtz >& /dev/null
rm -f \\\${tempfile}dano.mtz >& /dev/null


scaleit HKLIN \\\${tempfile}diso_dano.mtz \\\\
 HKLOUT \\\${tempfile}scaled.mtz << EOF-scaleit | tee \\\${tempfile}scaleit.log >> \\\$logfile
RESOLUTION \\\$scaleRES
#refine scale
refine \\\$scaling
weight
LABIN FP=Diso SIGFP=SIGDiso FPH1=Dano SIGFPH1=SIGDano
end
EOF-scaleit
rm -f \\\${tempfile}diso_dano.mtz >& /dev/null
rm -f \\\${tempfile}scaleit.in >& /dev/null


# print out "k" value from scaling
cat \\\${tempfile}scaleit.log |\\\\
nawk '/APPLICATION OF SCALES/,/--------------------------/' |\\\\
nawk '\\\$1 == "Derivative"{printf "k= %.3f\\\\n", 2*\\\$3}'

rm -f \\\${tempfile}scaleit.log >& /dev/null


combine_diso_dano:
##############################################################
# now combine Diso and Dano as the "best" estimate of total FH

echo "calculating FH = sqrt( Diso^2 + (k/2)^2 * Dano^2 )"

# also do a "Patterson weight" of 1/(sigma(FH^2))^2
echo "NREF -1" |\\\\
mtzdump HKLIN \\\${tempfile}scaled.mtz |\\\\
nawk '/LIST OF REFLECTIONS/,/MTZDUMP/' |\\\\
nawk '! /[A-Z]/ && NF>1{ HKL=substr(\\\$0,1,13); \\\\
    Diso=substr(\\\$0,14,12); SIGDiso=substr(\\\$0,26,10); \\\\
    Dano=substr(\\\$0,36,10); SIGDano=substr(\\\$0,46,10); \\\\
    FH=fh=sqrt(Diso*Diso + Dano*Dano); if(fh==0) fh=1;\\\\
    varFH  = (Diso*SIGDiso/fh)^2 + (Dano*SIGDano/fh)^2;\\\\
    varFH2 = 4 * FH^2 * varFH; \\\\
    W=0; if(varFH) W = 1/sqrt(varFH); if(W>maxW) maxW=W;\\\\
    print HKL, FH, sqrt(varFH), W} \\\\
    END{if(maxW) print 1/maxW > "'\\\${tempfile}'norm"}' |\\\\
cat >! \\\${tempfile}FH.hkl

set norm = \\\`tail -1 \\\${tempfile}norm\\\`
rm -f \\\${tempfile}norm >& /dev/null
if(\\\$#norm != 1) set norm = 1

# read FH back into mtz (finally)
f2mtz HKLIN \\\${tempfile}FH.hkl HKLOUT \\\${tempfile}sortme.mtz << EOF-f2mtz >> \\\$logfile
CELL \\\$CELL
SYMM \\\$SGnum
LABOUT H K L FH SIGFH W
CTYPO  H H H F Q W
SCALE  1 1 1 1 1 \\\$norm
EOF-f2mtz
rm -f \\\${tempfile}FH.hkl >& /dev/null


sort_final:
# sort it (for good measure)
echo "H K L" |\\\\
sortmtz HKLIN \\\${tempfile}sortme.mtz HKLOUT \\\$outfile >> \\\$logfile
if((! \\\$status)&&(-e "\\\$outfile")) then
    echo "\\\$outfile is ready."
else
    echo "ERROR! see \\\$logfile for what happened..."
    exit 9
endif

rm -f \\\${tempfile}sortme.mtz
##############################################################


# use scaleit to get the recommended DIFF
scaleit hklin \\\$outfile << EOF >! \\\${tempfile}scaleit
analyze
labin FP=FH SIGFP=SIGFH FPH1=FH SIGFPH1=SIGFH
SCALE FPH1 0.000001
END
EOF
if("\\\$DIFF" == "") set DIFF = \\\`nawk '/acceptable differences/{print \\\$NF}' \\\${tempfile}scaleit\\\`
rm -f \\\${tempfile}scaleit >& /dev/null
if("\\\$DIFF" == "") set DIFF = 1000




Shelx_format:
if("\\\$shelxfile" == "") goto Fourier

# dump FH out in shelx format too.
mtz2various HKLIN \\\$outfile HKLOUT \\\$shelxfile << EOF-shelx >> \\\$logfile
OUTPUT SHELX
FSQUARED
LABIN FP=FH SIGFP=SIGFH
END
EOF-shelx

if((! \\\$status)&&(-e "\\\$shelxfile")) echo "\\\$shelxfile is the SHELX version of \\\$outfile."


Fourier:
###########################################
if(("\\\$PHASE" == "")||("\\\$fourfile" == "")) goto Patterson
# calculate a phased Fourier of FH
# first, we need to retrieve the phase columns
set FOM_cad = ""
if("\\\$FOM" != "") set FOM_cad = "E2=\\\$FOM"
# set up FOM weight
set W = ""
if("\\\$FOM" != "") set W = "W=\\\$FOM"

# special case of Diso or Dano only
if((\\\$Ds == 0)||(\\\$Fs <= 1)) then
    # no double-difference data
    set E1 = "E1=F"
    set fftF1="F1=FH"
    if(\\\$Fs <= 1) then
	# anomalous data only
	set E1="E1=D"
	set fftF1="DANO=FH"
    endif
    
    # but still want phased FH map
    cad hklin1 \\\$outfile hklin2 \\\$mtzfile \\\\
	hklout \\\${tempfile}phased.mtz << EOF-cad >> \\\$logfile
    LABIN FILE 1 E1=FH E2=SIGFH
    LABIN FILE 2 E1=\\\$PHASE \\\$FOM_cad
    CTYPO FILE 1 \\\$E1 E2=Q
EOF-cad

    # ordinary, boring difference Fourier
    fft HKLIN \\\${tempfile}phased.mtz MAPOUT \\\${tempfile}FH.map << EOF-fft >> \\\$logfile
    TITLE \\\${hiRES}A map of FH @ \\\$PHASE \\\$FOM
    RESOLUTION \\\$scaleRES
    LABIN \\\$fftF1 SIG1=SIGFH PHI=\\\$PHASE \\\$W
    EXCLUDE SIG1 0
EOF-fft
    
    goto norm_Four
endif

# calculate a combined, phased difference Fourier
cad hklin1 \\\${tempfile}scaled.mtz hklin2 \\\$mtzfile \\\\
    hklout \\\${tempfile}phased.mtz << EOF-cad >> \\\$logfile
LABIN FILE 1 E1=Diso E2=SIGDiso E3=Dano E4=SIGDano
LABIN FILE 2 E1=\\\$PHASE \\\$FOM_cad
CTYPO FILE 1 E1=F E2=Q E3=D E4=Q
EOF-cad

# now we make the isomorphous difference Fourier
fft HKLIN \\\${tempfile}phased.mtz MAPOUT \\\${tempfile}Diso.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A map of Diso @ \\\$PHASE \\\$FOM
RESOLUTION \\\$scaleRES
LABIN F1=Diso SIG1=SIGDiso PHI=\\\$PHASE \\\$W
EXCLUDE SIG1 0
EOF-fft

# then make the anomalous difference Fourier (phases rotated 90 degrees)
fft HKLIN \\\${tempfile}phased.mtz MAPOUT \\\${tempfile}Dano.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A map of Dano @ \\\$PHASE \\\$FOM
RESOLUTION \\\$scaleRES
LABIN DANO=Dano SIG1=SIGDiso PHI=\\\$PHASE \\\$W
EXCLUDE SIG1 0
EOF-fft

# try to make sure we get the right sign
# assume map has at least one large peak (which should be positive)
echo "go" | mapdump mapin \\\${tempfile}Diso.map |\\\\
nawk '/Minimum density/{print -\\\$NF, -1} /Maximum density/{print \\\$NF, 1}' |\\\\
sort -nr |\\\\
nawk 'NR==1{print \\\$NF}' >! \\\${tempfile}sign
set diso_sign = \\\`cat \\\${tempfile}sign\\\`
rm -f \\\${tempfile}sign >& /dev/null

# invert the Diso map if it seems to be upside-down
#if(("\\\$diso_sign" == "-1")) then
if(("\\\$diso_sign" == "-1")&&(! \\\$?USER_ORDER)) then
    echo "inverting sequence of Diso for difference Fourier"
    echo "SCALE FACTOR -1 0" |\\\\
    mapmask mapin1 \\\${tempfile}Diso.map mapout \\\${tempfile}temp.map >> \\\$logfile
    mv \\\${tempfile}temp.map \\\${tempfile}Diso.map >& /dev/null
endif

# add these two maps together (equivalent to vector sum to FH)
echo "MAPS ADD" |\\\\
mapmask mapin1 \\\${tempfile}Diso.map mapin2 \\\${tempfile}Dano.map \\\\
mapout \\\${tempfile}FH.map >> \\\$logfile

norm_Four:
# normalize it for output
echo "SCALE SIGMA" |\\\\
mapmask mapin \\\${tempfile}FH.map mapout \\\$fourfile >> \\\$logfile

if((! \\\$status)&&(-e "\\\$fourfile")) echo "\\\$fourfile is the map of \\\$PHASE applied to FH"

rm -f \\\${tempfile}phased.mtz >& /dev/null
rm -f \\\${tempfile}Diso.map >& /dev/null
rm -f \\\${tempfile}Dano.map >& /dev/null
rm -f \\\${tempfile}FH.map >& /dev/null


Patterson:
###########################################
if("\\\$pattfile" == "") goto Clean_up

# calculate the unweighted Patterson map (if desired)
fft HKLIN \\\$outfile MAPOUT \\\${tempfile}FH.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A Patterson of FH
RESOLUTION \\\$scaleRES
PATTERSON
LABIN F1=FH SIG1=SIGFH F2=FH SIG2=SIGFH
SCALE F2 0.000001 0
EXCLUDE DIFF \\\$DIFF
EXCLUDE SIG1 0
EOF-fft
peakmax MAPIN \\\${tempfile}FH.map XYZOUT \\\${tempfile}.pdb << EOF-pick >> \\\$logfile
THRESHOLD RMS 3
NUMPEAKS 50
EOF-pick
# extend it to whole unit cell?
mapmask mapin \\\${tempfile}FH.map mapout "\\\$pattfile" << EOF >> \\\$logfile
scale sigma
#xyzlim 0 1 0 1 0 1
EOF
if((! \\\$status)&&(-e "\\\$pattfile")) echo "\\\$pattfile is the Patterson of FH."
rm -f \\\${tempfile}FH.map >& /dev/null


if("\\\$wpattfile" == "") goto Clean_up
# calculate the weighted Patterson map (if desired)
fft HKLIN \\\$outfile MAPOUT \\\${tempfile}FH.map << EOF-fft >> \\\$logfile
TITLE \\\${hiRES}A Patterson of FH/SIGFH
RESOLUTION \\\$scaleRES
PATTERSON
LABIN F1=FH SIG1=SIGFH W=W F2=FH SIG2=SIGFH
SCALE F2 0.000001 0
#EXCLUDE DIFF \\\$DIFF
EXCLUDE SIG1 0
EOF-fft
peakmax MAPIN \\\${tempfile}FH.map XYZOUT \\\${tempfile}.pdb << EOF-pick >> \\\$logfile
THRESHOLD RMS 3
NUMPEAKS 50
EOF-pick
# extend it to whole unit cell?
mapmask mapin \\\${tempfile}FH.map mapout "\\\$wpattfile" << EOF >> \\\$logfile
scale sigma
#xyzlim 0 1 0 1 0 1
EOF
if((! \\\$status)&&(-e "\\\$wpattfile")) echo "\\\$wpattfile is the Patterson of FH / sig(FH)^2"
rm -f \\\${tempfile}FH.map >& /dev/null


# clean up
Clean_up:

rm -f \\\${tempfile}scaled.mtz >& /dev/null
rm -f \\\${tempfile}Fs     >& /dev/null
rm -f \\\${tempfile}Ds     >& /dev/null
rm -f \\\${tempfile}Fpairs >& /dev/null
rm -f \\\${tempfile}.pdb   >& /dev/null


exit






Setup:
#################################################

  ####   ######   #####  #    #  #####
 #       #          #    #    #  #    #
  ####   #####      #    #    #  #    #
      #  #          #    #    #  #####
 #    #  #          #    #    #  #
  ####   ######     #     ####   #

#################################################
#
#   gather information on:
#    mtz file
#    data sets
#    resolution limits
#    sigma cuttoff (for map generation)
#    difference cutoff
#
##################################################
if(! \\\$?DIFF) set DIFF = ""

# scan the command line for files
foreach arg ( \\\$* )
    # warn about probable mispellings
    if("\\\$arg" =~ *.mtz) then
	if(-e "\\\$arg") then
	    set mtzfile = "\\\$arg"
	else
	    if(! \\\$?useroutfile) then
		set useroutfile = "\\\$arg"
		set outfile = "\\\$arg"
	    endif
	endif
    endif
end


# now all filenames have been initialized

if(! -e "\\\$mtzfile") goto Help

##################################################
# get crystal and dataset information from the mtz file
echo "go" | mtzdump HKLIN \\\$mtzfile >! \\\${tempfile}mtzdump
set CELL  = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\${tempfile}mtzdump\\\`
set SGnum = \\\`nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzdump\\\`
set SG    = \\\`nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set hiRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\${tempfile}mtzdump\\\`

# get column label names from the mtz file
nawk 'NF>3' \\\${tempfile}mtzdump |\\\\
nawk '\\\$(NF-1)=="F"{print "F", \\\$NF}\\\\
      \\\$(NF-1)=="D"{print "D", \\\$NF}\\\\
      \\\$(NF-1)=="Q"{print "S", \\\$NF}\\\\
      \\\$(NF-1)=="P"{print "P", \\\$NF}\\\\
      \\\$(NF-1)=="W"{print "W", \\\$NF}' |\\\\
nawk '/^F/{++n} /^D/{++n} /^P/{++n} {printf "%s", \\\$1; \\\\
       if(\\\$1=="S") printf "%s", last;\\\\
printf " %d %s \\\\n",n, \\\$2; last=\\\$1}' |\\\\
cat >! \\\${tempfile}datasets
rm -f \\\${tempfile}mtzdump >& /dev/null

# check extent of available data
set temp = \\\`nawk '/^F/ || /^D/' \\\${tempfile}datasets |& wc -l\\\`
if(\\\$temp < 1) then
    # this is useless, bail out now
    rm -f \\\${tempfile}datasets >& /dev/null
    echo "ERROR: no usable data in \\\${mtzfile}! "
    set mtzfile = ""
    goto Help
endif

# get complete, unique lists of DANO/SIGDANOs
cat \\\${tempfile}datasets |\\\\
nawk '\\\$1=="D"{D[\\\$2]=\\\$NF} \\\$1=="SD"{S[\\\$2]=\\\$NF} \\\\
      END{for(i in D) print i, D[i], S[i];}' |\\\\
sort -un |\\\\
nawk 'NF==3{print \\\$2,\\\$3}' |\\\\
cat >! \\\${tempfile}Ds

# get complete, unique lists of F/SIGFs
cat \\\${tempfile}datasets |\\\\
nawk '\\\$1=="F"{F[\\\$2]=\\\$NF} \\\$1=="SF"{S[\\\$2]=\\\$NF} \\\\
      END{for(i in F) print i, F[i], S[i];}' |\\\\
sort -un |\\\\
nawk 'NF==3{print \\\$2,\\\$3}' |\\\\
cat >! \\\${tempfile}Fs

# get complete, unique lists of Phases/FOMs
cat \\\${tempfile}datasets |\\\\
nawk '\\\$1=="P"{P[\\\$2]=\\\$NF} \\\$1=="W"{W[\\\$2]=\\\$NF} \\\\
      END{for(i in P) print i, P[i], W[i];}' |\\\\
sort -un |\\\\
nawk 'NF>=2{print \\\$2,\\\$3, " "}' |\\\\
cat >! \\\${tempfile}Ps


# one last pass through command line
# allow user overrides of all internal variables
set i = 0
echo -n "" >! \\\${tempfile}userlabels
while( \\\$i < \\\$#argv )
    @ i = ( \\\$i + 1 )
    @ nexti = ( \\\$i + 1 )
    @ lasti = ( \\\$i - 1 )
    if(\\\$nexti > \\\$#argv) set nexti = \\\$#argv
    if(\\\$lasti < 1) set lasti = 1
    set arg = "\\\$argv[\\\$i]"
    
    # see if a dataset label was given
    egrep " \\\$arg " \\\${tempfile}datasets >& /dev/null
    if(! \\\$status) then
	if(\\\$?NO) then
	    # user doesn't want this label
	    # filter it out of the input files
	    egrep -v "^\\\$arg " \\\${tempfile}Fs >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}Fs
	    egrep -v "^\\\$arg " \\\${tempfile}Ds >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}Ds
	    egrep -v "^\\\$arg " \\\${tempfile}Ps >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}Ps
	else
	    # must want only this label?
	    cat \\\${tempfile}datasets |\\\\
	    nawk -v label=\\\$arg 'NF>2 && \\\$NF==label{print \\\$NF}' |\\\\
	    cat >> \\\${tempfile}userlabels
	endif
	# "NO" stays set for next word
	continue
    endif
    
    # only look at non-file words
    if(-e "\\\$arg") then
	unset NO
	continue
    endif
    
    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
		    set loRES = "\\\$temp[1]"
		    set hiRES = "\\\$temp[2]"
		endif
	    else
		if("\\\$temp" != "") set hiRES = "\\\$temp"
	    endif
	endif
	    
	if(("\\\$arg" =~ *[Ss]igma)||("\\\$argv[\\\$nexti]" =~ [Ss]igma)) then
	    set DATA_cutoff = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
	
	if(("\\\$arg" =~ *[Dd]iff)||("\\\$argv[\\\$lasti]" =~ [Dd]iff)) then
	    set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	    set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
	if(("\\\$arg" =~ *[Dd]iso)||("\\\$argv[\\\$lasti]" =~ [Dd]iso)) then
	    set MAX_diso = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
	if(("\\\$arg" =~ *[Dd]ano)||("\\\$argv[\\\$lasti]" =~ [Dd]ano)) then
	    set MAX_dano = \\\`echo "\\\$arg" | nawk '\\\$1+0 > 0{print \\\$1+0}'\\\`
	endif
    endif
    
    # allow "NO" logic to carry through to next word(s)
    unset NO
    if(("\\\$arg" == "no")||("\\\$arg" == "not")) set NO
    if(("\\\$arg" == "don't")||("\\\$arg" == "ignore")) set NO
    if("\\\$arg" == "except") set NO
end

rm -f \\\${tempfile}datasets >& /dev/null

# turn the "user" labels into real label files
cat \\\${tempfile}Ds \\\${tempfile}userlabels |\\\\
nawk 'NF==2{set[\\\$1]=\\\$0}\\\\
      NF==1{print set[\\\$1]}' |\\\\
nawk 'NF==2' >! \\\${tempfile}
set Ds = \\\`cat \\\${tempfile} | wc -l\\\`
if(\\\$Ds > 0) then
    # user mentioned which Ds to use
    mv \\\${tempfile} \\\${tempfile}Ds
endif
set Ds = \\\`cat \\\${tempfile}Ds | wc -l\\\`

# same for Fs
cat \\\${tempfile}Fs \\\${tempfile}userlabels |\\\\
nawk 'NF==2{set[\\\$1]=\\\$0}\\\\
      NF==1{print set[\\\$1]}' |\\\\
nawk 'NF==2' >! \\\${tempfile}
set Fs = \\\`cat \\\${tempfile} | wc -l\\\`
if(\\\$Fs > 1) then
    # user mentioned which Fs to use
    mv \\\${tempfile} \\\${tempfile}Fs
    
    # get user-specified F dataset order 
    set order = \\\`nawk 'NF==2{print \\\$1}' \\\${tempfile}Fs\\\`
    set USER_ORDER
endif
set Fs = \\\`cat \\\${tempfile}Fs | wc -l\\\`

# same for Phases
cat \\\${tempfile}Ps \\\${tempfile}userlabels |\\\\
nawk 'NF==1{print set[\\\$1]}\\\\
           {set[\\\$1]=\\\$0}' |\\\\
nawk 'NF!=0' >! \\\${tempfile}
set Ps = \\\`cat \\\${tempfile} | wc -l\\\`
if(\\\$Ps > 0) then
    # user mentioned which Phase to use
    tail -1 \\\${tempfile} >! \\\${tempfile}Ps
endif
# only use one phase
tail -1 \\\${tempfile}Ps >! \\\${tempfile}
set PHASE = \\\`nawk '{print \\\$1}' \\\${tempfile}\\\`
set FOM   = \\\`nawk '{print \\\$2}' \\\${tempfile}\\\`


# clean up
rm -f \\\${tempfile} >& /dev/null
rm -f \\\${tempfile}Ps >& /dev/null
rm -f \\\${tempfile}userlabels >& /dev/null

goto Return_from_Setup


####################################################

The Future:
re-order Diso if scales come out screwy?
make the interface a little slicker, less wordy?
use correlation instead of scale as a weight?
implement use of max_DANO, DATA_cutoff, etc. ?

EOF-bestFH_script
chmod a+x \${scriptDIR}bestFH.com
























write_dm:
####################################################################
#
#	generate adaptive DM script
#
####################################################################

# don't overwrite user-modified script
if(-e \${scriptDIR}dm.com) goto write_fft

#echo "writing \${scriptDIR}dm.com"
cat << EOF-DMscript >! \${scriptDIR}dm.com
#! /bin/csh -f
#
#	Phaser Elves: Automatic DM Solvent flattening script
#
#
####################################################################
set mtzfile  = "\${mtzDIR}mlphare.mtz"
set outfile  = "dmed.mtz"
set tempfile = "./dm_temp"

defaults:
set SCHEME  = "AUTO"
set method  = "\$DM_method"
set steps   = "auto"
set Solvent = "50%"

# these are all reset from the command line
set F       = "FP"
set SIGF    = "SIGFP"
set PHI     = PHIB
set FOM     = FOM
set HL      = "HLA=HLA HLB=HLB HLC=HLC HLD=HLD"

# different systems have different nawks
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

if("\\\$1" == "") goto Help
goto Setup
# scan the command line
Help:
####################################################################
cat << EOF

usage: \\\$0 [mlphare.mtz] [50%] [FP]

where:
    mlphare.mtz - output MTZ from MLPHARE
    50%		- solvent content (must end with %)
    FP		- F you want to flatten with (default to best F in mtz)

EOF
exit 9
ReturnFromSetup:
if(("\\\$F" == "")||(! -e \\\$mtzfile)) goto Help

# make solvent content fractional
set Solvent = \\\`echo \\\$Solvent | nawk '{print \\\$1/100}' \\\`

####################################################################

\$DM \\\\
HKLIN \\\$mtzfile \\\\
HKLOUT \\\$outfile \\\\
 << eof-dm | nawk '{print} /Cycle  500/{exit}'
TITLE flattening in dm by \\\$Solvent solvent
# do flattening, histogram matching, and "multi-resolution" modification
MODE SOLV HIST MULT
# method of detecting bias in the flattened map
COMBINE \\\$method
# number of flattening cycles to execute
NCYCLE \\\$steps
# change last two values for buffer between solvent and protein
#SOLC 0.628 MASK 0.60 0.37
SOLC \\\$Solvent

# "SCHEME ALL" is all spots at once (could also be AUTO, RES, FOM, MAG, etc.)
SCHEME \\\$SCHEME
# print out realspace residuals
REALFREE

# defaults =-1.0 =2 =0.32 =2.0 e/A^3
#WANG -1.0 2 LIMITS 0.32 2.0
LABI FP=\\\$F SIGFP=\\\$SIGF PHIO=\\\$PHI FOMO=\\\$FOM \\\$HL
LABO PHIDM=PHIDM FOMDM=FOMDM HLADM=HLADM HLBDM=HLBDM HLCDM=HLCDM HLDDM=HLDDM
END

eof-dm
if(! \\\$status) then
    echo "\\\$outfile is ready."
else
    exit 2
endif

exit
####################################################################

Setup:
####################################################################
# scan the command line
foreach arg ( \\\$* )
    if( "\\\$arg" =~ *.mtz ) set mtzfile  = "\\\$arg"
    if( "\\\$arg" =~ *% ) set Solvent     = "\\\$arg"
    if(( "\\\$arg" =~ *[0-9] )&&( "\\\$arg" =~ [1-9]* )) set steps = "\\\$arg"
    if( "\\\$arg" == omit ) set method    = "OMIT"
end

#let DM choose scheme for known # of steps
#if("\\\$steps" != "auto") set SCHEME = AUTO

#get variables from mtz file
echo "go" | mtzdump hklin \\\$mtzfile |\\\\
nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\\\
nawk 'NF>10 && \\\$(NF-1) ~ /[FQPWADI]/' |\\\\
cat >! \\\${tempfile}mtzdmp

# use completeness, or F/sigF to pick default F
cat \\\${tempfile}mtzdmp |\\\\
nawk '\\\$(NF-1) == "F"{F=\\\$NF; meanF=\\\$8; reso=\\\$(NF-2); comp=substr(\\\$0,32)+0; \\\\
      getline; S=\\\$NF; if(\\\$8) meanF /= \\\$8; print F, S, reso, comp, meanF;}' |\\\\
sort -k3n,4 -k4nr,5 -k5nr >! \\\${tempfile}F

# and extract all dataset types/labels
cat \\\${tempfile}mtzdmp |\\\\
nawk 'NF>2{print \\\$(NF-1), \\\$NF, " "}' |\\\\
cat >! \\\${tempfile}cards

#clean up
rm -f \\\${tempfile}mtzdmp

# pick F with best resolution, or F/sigma
set F    = \\\`head -1 \\\${tempfile}F\\\`
if(\\\$#F > 2) then
    set SIGF = \\\$F[2]
    set F    = \\\$F[1]
endif

# pick most recent phase/FOM
grep "P \\\$PHI " \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    set temp = \\\`nawk '/^P/{print \\\$2}' \\\${tempfile}cards  | tail -1\\\`
    if("\\\$temp" != "") set PHI = "\\\$temp"
endif
grep "W \\\$FOM " \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    set temp = \\\`nawk '/^W/{print \\\$2}' \\\${tempfile}cards | tail -1\\\`
    if("\\\$temp" != "") set FOM = "\\\$temp"
endif

# pick most recent HL coefficients
cat \\\${tempfile}cards |\\\\
nawk '\\\$1=="A"{++n;HL[n]=\\\$NF} END{for(i=1;i<=n;i+=4) \\\\
      print "HLA="HL[i],"HLB="HL[i+1],"HLC="HL[i+2],"HLD="HL[i+3]}' |\\\\
cat >! \\\${tempfile}HL
set HL = \\\`tail -1 \\\${tempfile}HL\\\`

# see if user specified an F, Phase, FOM, or HL set
foreach arg ( \\\$* )
    set temp = \\\`grep " \\\$arg " \\\${tempfile}cards\\\`
    if("\\\$temp" =~ F*) then
	set F = "\\\${arg}"
	set temp = \\\`nawk -v arg="\\\$arg" '\\\$1==arg{print \\\$2}' \\\${tempfile}F\\\`
	if(\\\$#temp == 1) set SIGF = "\\\$temp"
	continue
    endif
    if("\\\$temp" =~ P*) set PHI = "\\\${arg}"
    if("\\\$temp" =~ W*) set FOM = "\\\${arg}"
    if("\\\$temp" =~ A*) set HL = \\\`grep "=\\\${arg} " \\\${tempfile}HL | tail -1\\\`
end

rm -f \\\${tempfile}cards \\\${tempfile}F \\\${tempfile}HL >& /dev/null

goto ReturnFromSetup

EOF-DMscript
chmod a+x \${scriptDIR}dm.com






































write_fft:
####################################################################
#
#	generate fft script
#
####################################################################

# don't overwrite user-modified script
if(-e \${scriptDIR}fft.com) goto write_macros

#echo "writing \${scriptDIR}fft.com"

# presume type of phasing
set tempPHI = "PHIDM"
set tempFOM = "FOMDM"
if(\$?NO_DM) then
    set tempPHI = "PHIB"
    set tempFOM = "FOM"
endif
cat << EOF-fftscript >! \${scriptDIR}fft.com
#! /bin/csh -f
#
#	Phaser's fft script for making the phased map
#
#
##############################################################################
# set up awk
alias nawk \$nawk
nawk 'BEGIN{print 1; exit}' >& /dev/null
if(\\\$status) alias nawk awk

# defaults
set MAPMAN   = \$MAPMAN
set BRIX     = \$BRIX
set BONES    = \$BONES
set pdbfile  = ""
set mtzfile  = \$bestmtz
set tempfile = fft_temp

# oversampling makes maps look prettier
set hiRES    = ""
set F        = \$native
set SIGF     = \$SIGnative
set PHI      = \$tempPHI
set FOM      = \$tempFOM

# output files
set ccp4map  = ffted.map
set omap     = ffted.omap
set pickpdb  = fftpick.pdb
set omacro   = ffted.omacro
set bonefile = bones.o

set pick = pick

if("\\\$1" == "") goto Help
goto Setup
#  Procedure (at bottom) to read command-line args
#  mtz, Fs, or resolution
Help:
cat << EOF

usage: \\\$0 mtzfile.mtz [F] [PHI] [coverme.pdb]
   or: \\\$0 mapfile.map [coverme.pdb]

where:
mtzfile.mtz  - a (phased) mtz file you want a map from
mapfile.map  - a pre-calculated map you want to convert to o format
coverme.pdb  - a pdb file you want the output map to cover

EOF
exit 9
ReturnFromSetup:

if(\\\$?user_mapfile) then
    # jump ahead if user specified a map
    cp \\\$user_mapfile \\\${tempfile}.map
    goto normalize
endif


################################################################################
fft HKLIN \\\$mtzfile MAPOUT \\\${tempfile}.map << EOF-fft
RESOLUTION 1000 \\\$hiRES
#EXCLUDE SIG1 1
title  \\\$hiRES A map of \\\$FOM * \\\$F @ \\\$PHI
LABIN F1=\\\$F \\\$SIG1 PHI=\\\$PHI \\\$WFOM
END
EOF-fft
if(\\\$status) exit

normalize:
# normalize the map
echo "SCALE SIGMA" |\\\\
mapmask mapin \\\${tempfile}.map mapout \\\$ccp4map
rm -f \\\${tempfile}.map >& /dev/null

extend:
# extend the map

# quit if user wasn't interested in an O map
if("\\\$omap" == "") exit

# get space group/CELL from map header
set CELL = \\\`echo "go" | mapdump mapin \\\$ccp4map | nawk '/Cell dimensions/{print \\\$(NF-5), \\\$(NF-4), \\\$(NF-3), \\\$(NF-2), \\\$(NF-1), \\\$NF; exit}'\\\`
set SGnum = \\\`echo "go" | mapdump mapin \\\$ccp4map | nawk '/Space-group/{print \\\$NF}'\\\`
set SG = \\\`nawk -v SGnum=\\\$SGnum '\\\$1 == SGnum {print \\\$4;exit}' \\\$CLIBD/symop.lib\\\`

# decide on how to extend the map (cover or fill cell)
if(-e "\\\$pdbfile") then
    set pickpdb = "\\\$pdbfile"
    set pick = "build"
    set center = \\\`echo "COM" | pdbset xyzin \\\$pdbfile XYZOUT \\\${tempfile}.pdb | nawk '\\\$1=="Center" && \\\$3=="Mass:"{print \\\$4, \\\$5, \\\$6}'\\\`
    rm -f \\\${tempfile}.pdb >& /dev/null
else
    set center  = \\\`echo \\\$CELL | nawk '{print \\\$1/2, \\\$2/2, \\\$3/2}'\\\`
endif


# make an O macro for looking at the results
set temp = \\\`dirname \\\$pickpdb\\\`
set temp = \\\`cd \\\$temp ; pwd\\\`
#set pickpdb = \\\${temp}/\\\`basename \\\$pickpdb\\\`
cat << EOF >! \\\$omacro

! read in a pdb file
sam_atom_in \\\$pickpdb \\\$pick
mol \\\$pick
obj \\\$pick
zone ;
end

sym_set ; ; \\\$SG
sym_cell
! cen_xyz \\\$center

! read in the sites
sam_atom_in sites.pdb sites
mol sites
obj sites
zone ;
end
sym_set ; ; \\\$SG
sym_cell

! display them as big spheres
sketch_cpk sites
sym_sphere sites sym 30
sketch_cpk sym1
clear_flags
sketch_cpk sym2
clear_flags
sketch_cpk sym3
clear_flags
sketch_cpk sym4
clear_flags
sketch_cpk sym5
clear_flags
sketch_cpk sym6
clear_flags
sketch_cpk sym7
clear_flags
sketch_cpk sym8
clear_flags

! do bones
read \\\$bonefile
bone_setup skel bones 30 1 2 3 4 5
bone_draw

! use newer fastmap feature
fm_file \\\${ccp4map} map \\\$SG
!          radius style n sig color
fm_set map 25     solid 1 1.0 white 


! use "old reliable" map commands
map_cache
map_active_center
map_file \\\$omap
map_object map
!         dx dy dz sig color linestyle
map_param 25 25 25 1   white 0.5 0 1
map_draw

menu @\\\$omacro on

EOF

# now actually do the map extension
if("\\\$pick" == "build") then
    echo "border 10" |\\\\
    mapmask mapin \\\$ccp4map xyzin \\\$pdbfile mapout \\\${tempfile}.map
else
    # just extend to unit cell (and then some)
    echo "XYZLIM -0.1 1.1   -0.1 1.1   -0.1 1.1 " |\\\\
    mapmask mapin \\\$ccp4map mapout \\\${tempfile}.map

    # pick peaks in it (just to have something to grab onto)
    peakmax MAPIN \\\${tempfile}.map XYZOUT \\\$pickpdb << eof-pick
    THRESHOLD RMS 2
    OUTPUT BROOKHAVEN
    END
eof-pick
endif


mapman:
# convert to O format (and do a bones trace)
setenv MAPSIZE \\\`ls -ln \\\${tempfile}.map | nawk '{printf "%d", \\\$5/3.9}'\\\`
\\\$MAPMAN << end-mapman |& grep -v Toodle
read map1 \\\${tempfile}.map CCP4
mappage map1 \\\$omap
bone skel map1 1.5 0.5 100
bone conn \\\$bonefile skel 5
quit
y
end-mapman
if(! \\\$status) then
    # no need to do further conversions
    set BONES = ""
    set BRIX  = ""
endif

if(-e "\\\$BRIX") then
    # use the brix program to make an o-readable file
    \\\$BRIX \\\${tempfile}.map \\\$omap
endif

if((-e "\\\$BONES")&&(! -e "\\\$pdbfile")) then
    \\\$BONES \\\${tempfile}.map << EOF
    1.5 0.5
    5
\\\$bonefile
skel
EOF
endif

rm -f \\\${tempfile}.map >& /dev/null



####################################################################
exit
####################################################################



Setup:
# scan the command line for files
foreach arg ( \\\$* )
    if( "\\\$arg" =~ *.mtz ) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set mtzfile  = "\\\$arg"
	continue
    endif
    if(("\\\$arg" =~ *.map)||("\\\$arg" =~ *.ext)) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set user_mapfile  = "\\\$arg"
	continue
    endif
    if(("\\\$arg" =~ *.pdb)||("\\\$arg" =~ *.brk)) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set pdbfile  = "\\\$arg"
	continue
    endif
    if( "\\\$arg" =~ [0-9]* ) then
	set temp = \\\`echo "\\\$arg" | nawk '\\\$1+0>0.1{print \\\$1+0}'\\\`
	if("\\\$temp" != "") set hiRES = "\\\$temp"
    endif
end

# return early if a map was specified (not actually going to do an fft! )
if(\\\$?user_mapfile) goto ReturnFromSetup

#get variables from mtz file
echo "go" | mtzdump hklin \\\$mtzfile |\\\\
nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\\\
nawk 'NF>10 && \\\$(NF-1) ~ /[FQPWADI]/' |\\\\
cat >! \\\${tempfile}mtzdmp

# use completeness, or F/sigF to pick default F
cat \\\${tempfile}mtzdmp |\\\\
nawk '\\\$(NF-1) == "F"{F=\\\$NF; meanF=\\\$8; reso=\\\$(NF-2); comp=substr(\\\$0,32)+0; \\\\
      getline; S=\\\$NF; if(\\\$8) meanF /= \\\$8; print F, S, reso, comp, meanF;}' |\\\\
sort -k3n,4 -k4nr,5 -k5nr >! \\\${tempfile}F

# and extract all dataset types/labels
cat \\\${tempfile}mtzdmp |\\\\
nawk 'NF>2{print \\\$(NF-1), \\\$NF, " "}' |\\\\
cat >! \\\${tempfile}cards

#clean up
rm -f \\\${tempfile}mtzdmp

# pick F with best resolution, or /
set F    = \\\`head -1 \\\${tempfile}F\\\`
if(\\\$#F > 2) then
    set SIGF = \\\$F[2]
    set F    = \\\$F[1]
endif

# pick most recent phase/FOM
grep "P \\\$PHI" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    set temp = \\\`nawk '/^P/{print \\\$2}' \\\${tempfile}cards  | tail -1\\\`
    if("\\\$temp" != "") set PHI = "\\\$temp"
endif
grep "W \\\$FOM" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    set temp = \\\`nawk '/^W/{print \\\$2}' \\\${tempfile}cards | tail -1\\\`
    if("\\\$temp" != "") then
	set FOM = "\\\$temp"
    else
	# there are no FOMs in this mtz file
	set FOM = ""
    endif
endif

# see if user specified an F, Phase, or FOM
foreach arg ( \\\$* )
    set temp = \\\`grep " \\\$arg " \\\${tempfile}cards\\\`
    if("\\\$temp" =~ F*) then
	set F = "\\\${arg}"
	set temp = \\\`nawk -v arg="\\\$arg" '\\\$1==arg{print \\\$2}' \\\${tempfile}F\\\`
	if(\\\$#temp == 1) set SIGF = "\\\$temp"
	continue
    endif
    if("\\\$temp" =~ Q*) set SIGF = "\\\${arg}"
    if("\\\$temp" =~ P*) set PHI  = "\\\${arg}"
    if("\\\$temp" =~ W*) set FOM  = "\\\${arg}"
    
    if(\\\$?NO && ("\\\$arg" == FOM)) set FOM = ""
    
    unset NO
    if("\\\$arg" == "no") set NO
end

# now check and see if the sigma is really there
grep "Q \\\$SIGF" \\\${tempfile}cards >& /dev/null
if(\\\$status) then
    # no sigma availale (doesn't really matter anyway)
    set SIGF = ""
endif

rm -f \\\${tempfile}cards \\\${tempfile}F >& /dev/null


# assign the actual fft cards here (and blank them if they don't exist)
set SIG1 = "SIG1=\\\$SIGF"
set WFOM = "W=\\\$FOM"

if("\\\$SIGF" == "") set SIG1 = ""
if("\\\$FOM"  == "") then
    set FOM  = 1
    set WFOM = ""
endif

if(("\\\$hiRES" == "")&&(-e "\\\$mtzfile")&&(! \\\$?user_mapfile)) then
    set hiRES = \\\`echo "head" | mtzdump hklin \\\$mtzfile | nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\`
    # zero-fill for better-looking map
    set hiRES = \\\`echo \\\$hiRES |  nawk '\\\$1>0{print 1/(2.0*((1/\\\$1)^3))^(1/3)}'\\\`
endif

goto ReturnFromSetup


EOF-fftscript

chmod a+x \${scriptDIR}fft.com



















write_macros:

set sg = "\$SG"
if ("\$sg" == "") set sg = "\$newSG"

# make an o macro for loading and viewing "best" map
set pwd = \`cd \$oDIR ; pwd \`
if(! -e \${oDIR}map) then
    cat << EOF-omac >! \${oDIR}map
! render what Phaser Elves consider the best map
map_cache
map_active_center
map_file \\\${cwd}/best_phased.omap
map_object map
!         dx dy dz sig color linestyle
map_param 25 25 25 1   white 0.5 0 1
map_draw

! use newer fastmap feature
fm_file ../maps/best_phased.map map \$sg
!          radius style n sig color
fm_set map 35     solid 1 1.0 white 


EOF-omac
endif
# make an o macro for loading and viewing best stuff
if(! -e \${oDIR}best.omacro) then
    set center = \`echo \$CELL | nawk '{print \$1/2, \$2/2, \$3/2}'\`
    cat << EOF-omac >! \${oDIR}best.omacro
! current working directory
symbol cwd \${pwd}
symbol cwd .

! read in a peak-pick of best_phased.omap (for grabbing onto)
sam_atom_in \\\${cwd}/best_pick.pdb pick
mol pick
obj pick
zone ;
end

sym_set ; ; \$sg
sym_cell
! cen_xyz \$center

! read in pdb version of the metal sites
sam_atom_in \\\${cwd}/best_sites.pdb sites
mol sites
obj sites
zone ;
end
sym_set ; ; \$sg
sym_cell

! display them as big spheres
sketch_cpk sites
sym_sphere sites sym 30
sketch_cpk sym1
clear_flags
sketch_cpk sym2
clear_flags
sketch_cpk sym3
clear_flags
sketch_cpk sym4
clear_flags
sketch_cpk sym5
clear_flags
sketch_cpk sym6
clear_flags
sketch_cpk sym7
clear_flags
sketch_cpk sym8
clear_flags

! read in and display the bones trace
read \\\${cwd}/best_bones.o
bone_setup skel bones 30 1 2 3 4 5
bone_draw

! render what Phaser Elves consider the best map
@\\\${cwd}/map
menu @map on
EOF-omac
endif



if(! -e \${oDIR}latest) then
    cat << EOF-omac >! \${oDIR}latest
! render the latest Phaser Elves map
map_cache
map_active_center
map_file \\\${cwd}/phased.omap
map_object map
!         dx dy dz sig color linestyle
map_param 25 25 25 1   white 0.5 0 1
map_draw

EOF-omac
endif
# make an o macro for loading and viewing latest stuff
if(! -e \${oDIR}latest.omacro) then
    set center = \`echo \$CELL | nawk '{print \$1/2, \$2/2, \$3/2}'\`
    cat << EOF-omac >! \${oDIR}latest.omacro
! current working directory
symbol cwd \${pwd}
symbol cwd .

! read in a peak-pick of phased.omap (for grabbing onto)
sam_atom_in \\\${cwd}/pick.pdb pick
mol pick
obj pick
zone ;
end

sym_set ; ; \$sg
sym_cell
! cen_xyz \$center

! read in pdb version of the metal sites
sam_atom_in \\\${cwd}/sites.pdb sites
mol sites
obj sites
zone ;
end
sym_set ; ; \$sg
sym_cell

! display them as big spheres
sketch_cpk sites
sym_sphere sites sym 30
sketch_cpk sym1
clear_flags
sketch_cpk sym2
clear_flags
sketch_cpk sym3
clear_flags
sketch_cpk sym4
clear_flags
sketch_cpk sym5
clear_flags
sketch_cpk sym6
clear_flags
sketch_cpk sym7
clear_flags
sketch_cpk sym8
clear_flags

! read in and display the bones trace
read \\\${cwd}/bones.o
bone_setup skel bones 30 1 2 3 4 5
bone_draw

! render what Phaser Elves consider the best map
@latest
menu @latest on
EOF-omac
endif












write_pick:
#################################################################
# don't overwrite user-modified script
if(-e \${scriptDIR}pick.com) goto write_oasis

# create a general-purpose peak-pick script
#echo "writing \${scriptDIR}pick.com"

cat << EOF-pickscript >! \${scriptDIR}pick.com
#! /bin/csh -f
#
#	Pick unique peaks in a map, 
#	avoiding "map-edge" false peaks
#	optionally avoiding a list of "boring" positions
#	in a "symmetry-aware" fashion
#
# defaults
set mapfile = "maps/FH_Four.map"
set pdbfile = ""
set logfile = "pick.log"
set outfile = "pick.pdb"

set sigma   = 6

set tempfile = pick_temp

# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk

if("\\\$1" == "") goto Help
echo -n "" >! \\\$logfile
################################################################################
goto Setup
# set/reset \\\$mapfile \\\$pdbfile \\\$sigma from command-line
Help:
cat << EOF

usage: \\\$0 \\\$mapfile [\\\$sigma] [boring.pdb]

where: \\\$mapfile is the map you want to pick
       \\\$sigma (optional) is the minimum peak height (sigma units)
       boring.pdb (optional) sites to avoid in peak-picking

EOF
exit 9
Return_from_Setup:
################################################################################

if(! -e "\\\$mapfile") goto Help

set sign = \\\`echo "\\\$sigma" | nawk '\\\$1+0<0{print "+/-" 0-\\\$1} \\\$1+0>0{print \\\$1}'\\\`
echo -n "looking for \\\${sign}*sigma peaks in \\\$mapfile "
if(-e "\\\$sitefile") then
    echo "not already withing \\\${CLOSE_peaks}A"
    echo -n "of the \\\$boring_sites atoms listed in \\\$sitefile"
endif
echo ""

# extract a single ASU from the input map
mapmask mapin \\\$mapfile mapout \\\${tempfile}asu.map << EOF-xtend | tee \\\${tempfile}xtend >> \\\$logfile
scale sigma
xyzlim ASU
# re-axis to X,Y,Z
AXIS X Y Z
# fill blank spaces with zero
pad 0
EOF-xtend

# get size of the ASU
cat \\\${tempfile}xtend |\\\\
nawk '/Grid sampling on x, y, z/{print \\\$(NF-2), \\\$(NF-1), \\\$NF;} \\\\
      /Start and stop points on x, y, z/{print \\\$(NF-5), \\\$(NF-4), \\\$(NF-3), \\\$(NF-2), \\\$(NF-1), \\\$NF}' |\\\\
nawk 'NF==3{gx=\\\$1;gy=\\\$2;gz=\\\$3}\\\\
      NF==6{print "ASU", \\\$1/gx, \\\$2/gx, \\\$3/gy, \\\$4/gy, \\\$5/gz, \\\$6/gz}' |\\\\
cat >! \\\${tempfile}asu
rm -f \\\${tempfile}xtend >& /dev/null

# calculate a 10% "edge pad"
set xyzlim = \\\`nawk '/^ASU/{print \\\$2-0.1, \\\$3+0.1, \\\$4-0.1, \\\$5+0.1, \\\$6-0.1, \\\$7+0.1}' \\\${tempfile}asu\\\`
set asu = \\\`nawk '/^ASU/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7}' \\\${tempfile}asu\\\`

# re-extend the map by a 10% pad in every direction
echo "xyzlim \\\$xyzlim" |\\\\
mapmask mapin \\\${tempfile}asu.map mapout \\\${tempfile}pick.map >> \\\$logfile
rm -f \\\${tempfile}asu.map >& /dev/null


repeat:
# reformat to peakmax vernacular
set sigma = \\\`echo \\\$sigma | awk '\\\$1+0>0{print \\\$1} \\\$1+0<0{print -\\\$1,"NEGATIVES"}'\\\`

# do the actual peak-pick
peakmax MAPIN \\\${tempfile}pick.map PEAKS \\\${tempfile}.xyz TO \\\${tempfile}.xyz << eof-pick >> \\\$logfile
THRESHOLD \\\$sigma
OUTPUT PEAKS
END
eof-pick
if(\\\$status) then
    grep "Threshold too high" \\\$logfile >& /dev/null
    if(! \\\$status) then
	set sigma = \\\`echo "\\\$sigma" | nawk '\\\$1+0>0.5{print  \\\$1*2/3}'\\\`
	if("\\\$sigma" == "") then
	    echo "no peaks."
	    set BAD
	    goto cleanup
	endif
	echo "reducing sigma to \\\$sigma"
	goto repeat
    endif
endif
rm -f \\\${tempfile}pick.map >& /dev/null

# re-format the peaks list (with no stuck-together numbers)
cat \\\${tempfile}.xyz |\\\\
nawk 'NF>6 && /[^1-9.-]/{ \\\\
print substr(\\\$0,23,8), substr(\\\$0,31,8), substr(\\\$0,39,8),\\\\
      substr(\\\$0,49,8), substr(\\\$0,57,8), substr(\\\$0,65,8), substr(\\\$0,6,8)}' |\\\\
cat >! \\\${tempfile}peaks.pick
rm -f \\\${tempfile}.xyz >& /dev/null

# now filter out out-of-bounds (map-edge) peaks
################################################################
# trim off peaks outside the CCP4 ASU limits
# (they should either be redundant, or map-edge peaks)
cat \\\${tempfile}asu \\\${tempfile}peaks.pick |\\\\
nawk '/^ASU/{xmin=\\\$2-0;ymin=\\\$4-0;zmin=\\\$6-0;\\\\
	     xmax=\\\$3+0;ymax=\\\$5+0;zmax=\\\$7+0;next;} \\\\
      {x=\\\$1+0;y=\\\$2+0;z=\\\$3+0}\\\\
      x>=xmin && x<=xmax && y>=ymin && y<=ymax && z>=zmin && z<=zmax {print}' |\\\\
sort -nr -k7 >! \\\${tempfile}peaks.trimmed

# add another 5% pad (just in case we lost a few)
cat \\\${tempfile}asu \\\${tempfile}peaks.pick |\\\\
nawk -v pad=0.05 '/^ASU/{xmino=\\\$2-pad;ymino=\\\$4-pad;zmino=\\\$6-pad;\\\\
			 xmaxo=\\\$3+pad;ymaxo=\\\$5+pad;zmaxo=\\\$7+pad;\\\\
                         xmini=\\\$2-0;ymini=\\\$4-0;zmini=\\\$6-0;\\\\
			 xmaxi=\\\$3+0;ymaxi=\\\$5+0;zmaxi=\\\$7+0;\\\\
                         next;} \\\\
      {x=\\\$1+0;y=\\\$2+0;z=\\\$3+0}\\\\
      x>=xmini && x<=xmaxi && y>=ymini && y<=ymaxi && z>=zmini && z<=zmaxi {next}\\\\
      x>xmino && xymino && yzmino && z> \\\${tempfile}peaks.trimmed
rm -f \\\${tempfile}peaks.pick \\\${tempfile}asu >& /dev/null

# these peaks are sorted by "priority" of their ASU convention
# \\\${tempfile}peaks.trimmed had
# format: xf yf zy X Y Z height

################################################################
# near-edge peaks have probably been counted twice, so we need
# to filter them out

# generate ALL symmetry-equivalent positions for the trimmed peaks
cat << EOF >! \\\${tempfile}gensym.in
SYMM \\\$SG
CELL \\\$CELL
XYZLIM \\\$xyzlim
EOF
cat \\\${tempfile}peaks.trimmed |\\\\
nawk '{++n; print "RESIDUE",n; print "ATOM X", \\\$1, \\\$2, \\\$3}' |\\\\
cat >> \\\${tempfile}gensym.in
cat \\\${tempfile}gensym.in | gensym |&\\\\
nawk '/List of sites/,/Normal termination/' |\\\\
nawk '\\\$2 ~ /[01].[0-9][0-9][0-9]/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7, \\\$(NF-1), "sym"}' |\\\\
cat >! \\\${tempfile}peaks.symm
rm -f \\\${tempfile}gensym.in >& /dev/null

#  \\\${tempfile}peaks.symm is now an indexed list of all 
# symmetry-related peak positions within \\\$xyzlim
#format: xf yf zf X Y Z peak# "sym" 

# to preserve the ASU coordinates:
# sort the trimmed coordinates into the list so 
# they will be the "first" symmetry mate considered 
# for each "site"
cat \\\${tempfile}peaks.trimmed |\\\\
nawk '{++n; print \\\$1, \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, n, \\\$NF*\\\$NF, \\\$NF}' |\\\\
cat - \\\${tempfile}peaks.symm |\\\\
sort -k7n,8 -k8nr,9 >! \\\${tempfile}peaks.xpanded
rm -f \\\${tempfile}peaks.trimmed >& /dev/null
rm -f \\\${tempfile}peaks.symm >& /dev/null


# now filter the symmetry-expanded list for the
# unique list of non-symmetry related peaks
cat \\\${tempfile}peaks.xpanded |\\\\
nawk '! seen[\\\$1 " " \\\$2 " " \\\$3] {print} {seen[\\\$1 " " \\\$2 " " \\\$3]=1}' |\\\\
nawk -v cut=\\\$CLOSE_peaks '\\\$NF!="sym"{height[\\\$7]=\\\$NF}\\\\
        NF>3{++n; X[n]=\\\$4; Y[n]=\\\$5; Z[n]=\\\$6; site[n]=\\\$7;\\\\
        # compare this peak to all sites seen so far \\\\
	for(i=1;i! \\\${tempfile}peaks.reduced
rm -f \\\${tempfile}peaks.xpanded >& /dev/null

# \\\${tempfile}peaks.reduced should now contain only unique peaks from \\\$mapin
# format: xf yf zf X Y Z height


################################################################
# now look for special positions
cat \\\${tempfile}peaks.reduced |\\\\
nawk 'NF>0{++n; print "RESIDUE",n; print "ATOM X", \\\$1, \\\$2, \\\$3}' |\\\\
cat >! \\\${tempfile}gensym.in
gensym << EOF >! \\\${tempfile}.log
SYMM \\\$SG
CELL \\\$CELL
XYZLIM 0 0.999999 0 0.999999 0 0.999999
@\\\${tempfile}gensym.in
EOF
# count the number of times each site is "seen"
# more than once implies a special position
cat \\\${tempfile}.log |\\\\
nawk '/List of sites/,/Normal termination/' |\\\\
nawk '\\\$2 ~ /[01].[0-9][0-9][0-9]/{print \\\$2, \\\$3, \\\$4, \\\$(NF-1), \\\$NF}' |\\\\
nawk '{++seen[\\\$1 " " \\\$2 " " \\\$3 " " \\\$4]}\\\\
   END{for(site in seen) print site, seen[site]}' |\\\\
sort -un -k4 |\\\\
nawk '\\\$5+0>0{print \\\$4, 1/\\\$5}' >! \\\${tempfile}occs
rm -f  \\\${tempfile}.log >& /dev/null


# now add these "occupancies" to the master list
cat \\\${tempfile}occs \\\${tempfile}peaks.reduced |\\\\
nawk 'NF==2{occ[\\\$1]=\\\$2} \\\\
       NF>2{++n;print \\\$1,\\\$2,\\\$3,\\\$4,\\\$5,\\\$6,occ[n],\\\$7}' |\\\\
cat >! \\\${tempfile}peaks.final
rm -f \\\${tempfile}peaks.reduced >& /dev/null
# \\\${tempfile}peaks.final now contains the "final" list of output peaks
# and should faithfully represent the unique peaks in the map
# format: xf yf zf X Y Z 1/mult height

set peaks = \\\`cat \\\${tempfile}peaks.final | wc -l\\\`
echo -n "\\\$peaks found "
rm -f  \\\${tempfile}occs >& /dev/null

################################################################
# filter out "boring" sites
if(! -e \\\${tempfile}boring_sites) touch \\\${tempfile}boring_sites
# format: xf yf zf

# count number of "boring" sites
set boring_sites = \\\`cat \\\${tempfile}boring_sites | wc -l\\\`

# symmetry-expand the "boring" sites
cat << EOF >! \\\${tempfile}gensym.in
SYMM \\\$SG
CELL \\\$CELL
XYZLIM \\\$xyzlim
EOF
cat \\\${tempfile}boring_sites |\\\\
nawk 'NF>2{print "ATOM X", \\\$1, \\\$2, \\\$3}' |\\\\
cat >> \\\${tempfile}gensym.in

cat \\\${tempfile}gensym.in | gensym |&\\\\
nawk '/List of sites/,/Normal termination/' |\\\\
nawk '\\\$2 ~ /[01].[0-9][0-9][0-9]/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7, "boring"}' |\\\\
cat >! \\\${tempfile}boring_sites.symm
rm -f \\\${tempfile}gensym.in >& /dev/null

# \\\${tempfile}all_boring_sites now contains ALL symmetry-equivalent
# positions to the sites the user entered on the command-line
# format: xf yf zf X Y Z "boring"

# now remove peaks that were too close to "boring" sites
cat \\\${tempfile}boring_sites.symm \\\${tempfile}peaks.final |\\\\
nawk -v cut=\\\$CLOSE_peaks ' \\\\
      \\\$NF=="boring"{++n; X[n]=\\\$4; Y[n]=\\\$5; Z[n]=\\\$6} \\\\
      \\\$NF!="boring"{minD=999999; \\\\
         # find nearest "boring" site \\\\
         for(i=1;i<=n;++i){\\\\
	     dist=sqrt((\\\$4-X[i])^2 +(\\\$5-Y[i])^2 +(\\\$6-Z[i])^2);\\\\
	     if(dist < minD){\\\\
	     minD=dist;}}\\\\
	 # now see if it is too close \\\\
	 if(minD > cut) {print}}' |\\\\
cat >! \\\${tempfile}peaks.interesting
rm -f  \\\${tempfile}boring_sites.symm >& /dev/null
rm -f  \\\${tempfile}peaks.final >& /dev/null

# sort the picked peaks by height
sort -nr -k8 \\\${tempfile}peaks.interesting >! \\\${tempfile}
mv \\\${tempfile} \\\${tempfile}peaks.interesting

# \\\${tempfile}peaks.interesting now contains only "interesting" peaks
# format: xf yf zf X Y Z 1/mult height

# see how many are left
set interesting = \\\`cat \\\${tempfile}peaks.interesting | wc -l\\\`
if(\\\$boring_sites) echo -n "(\\\$interesting) new"
echo ""

################################################################
# make a pdb output file

echo "REMARK B-factors are peak heights in \\\$mapfile" >! \\\$outfile
echo "REMARK Occs are 1/multiplicity (for special positions)" >> \\\$outfile
echo "\\\$CELL" | nawk '{printf "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f\\\\n",\\\\
      \\\$1, \\\$2, \\\$3, \\\$4, \\\$5, \\\$6}' >> \\\$outfile
cat \\\${tempfile}peaks.interesting |\\\\
nawk '{++i; printf "ATOM   %4d  OW  WAT X%4d    %8.3f%8.3f%8.3f%6.2f%6.2f\\\\n",\\\\
         i, i, \\\$4, \\\$5, \\\$6, \\\$7, \\\$8}' |\\\\
cat >> \\\$outfile

################################################################
# calculate distance to nearest "old" site

# by default, use the "boring" list as "old" sites
cat \\\${tempfile}boring_sites >! \\\${tempfile}old_sites
if(! -e "\\\$sitefile") then
    # no sites input, so just get inter-peak distances
    cat \\\${tempfile}peaks.interesting >! \\\${tempfile}old_sites
endif
if(\\\$?scriptfile) then
    # input file was an mlphare script, so only interested in real atoms
    cat "\\\$scriptfile" |\\\\
    nawk '\\\$1~/^ATOM/{print \\\$3, \\\$4, \\\$5}' |\\\\
    cat >! \\\${tempfile}old_sites
endif
# count number of "old" sites
set old_sites = \\\`cat \\\${tempfile}old_sites | wc -l\\\`

# calculate the largest expected inter-atom distance (cell center to origin)
echo "0.5 0.5 0.5" |\\\\
nawk 'NF>2{++n; printf "%5d%10.5f%10.5f%10.5f%10.5f%5.2f%5d%10d%2s%3s%3s %1s\\\\n", \\\\
       n, \\\$1, \\\$2, \\\$3, 80, 1, "38", n, "H", "", "IUM", " "}' |\\\\
cat >! \\\${tempfile}.frac
coordconv XYZIN \\\${tempfile}.frac \\\\
         XYZOUT \\\${tempfile}.pdb << EOF-conv >& /dev/null
CELL \\\$CELL
INPUT FRAC
OUTPUT PDB ORTH 1
END
EOF-conv
cat \\\${tempfile}.pdb |\\\\
nawk '/^ATOM/{print substr(\\\$0, 31, 8), substr(\\\$0, 39, 8), substr(\\\$0, 47, 8)}' |\\\\
cat >! \\\${tempfile}center
set max_dist = \\\`nawk '{print sqrt(\\\$1*\\\$1 + \\\$2*\\\$2 + \\\$3*\\\$3)+3}' \\\${tempfile}center\\\`
rm -f \\\${tempfile}.frac >& /dev/null
rm -f \\\${tempfile}.pdb >& /dev/null
rm -f \\\${tempfile}center >& /dev/null


# convert "old" sites to a pdb
cat \\\${tempfile}old_sites |\\\\
nawk 'NF>2{++n; printf "%5d%10.5f%10.5f%10.5f%10.5f%5.2f%5d%10d%2s%3s%3s %1s\\\\n", \\\\
       n, \\\$1, \\\$2, \\\$3, 80, 1, "38", n, "C", "", "IUM", "A"}' |\\\\
cat >! \\\${tempfile}old.frac
coordconv XYZIN \\\${tempfile}old.frac \\\\
         XYZOUT \\\${tempfile}old.pdb << EOF-conv >& /dev/null
CELL \\\$CELL
INPUT FRAC
OUTPUT PDB ORTH 1
END
EOF-conv
rm -f \\\${tempfile}old.frac >& /dev/null

# strip off unneeded cards
nawk '/^ATOM/ || /^CRYS/ || /^SCALE/' \\\${tempfile}old.pdb |\\\\
cat >! \\\${tempfile}both.pdb
rm -f \\\${tempfile}old.pdb >& /dev/null

# append peak list to the combined PDB file
nawk '/^ATOM/{print}' \\\$outfile >> \\\${tempfile}both.pdb
@ start_peaks = ( \\\$old_sites + 1 )

# renumber the atoms so that distang won't get confused
cat \\\${tempfile}both.pdb |\\\\
nawk '/^ATOM/{++n; \\\$0 = sprintf("ATOM  %5d%s",n,substr(\\\$0,12))} {print \\\$0}' |\\\\
cat >! \\\${tempfile}.pdb
mv \\\${tempfile}.pdb \\\${tempfile}both.pdb >& /dev/null

# use distang to calculate all inter-atom distances (and then sort them)
distang xyzin \\\${tempfile}both.pdb << EOF |\\\\
    nawk '\\\$1=="Z"{print "dist", \\\$6, \\\$2, \\\$9}' | sort -n -k4 |\\\\
    nawk '! seen[\\\$2]{seen[\\\$2]=1;print}' | sort -n -k2 >! \\\${tempfile}dists
SYMM \\\$SG
DIST ALL
RADII C 1
RADII OW \\\$max_dist
DMIN \\\$CLOSE_peaks
FROM ATOM 1 to \\\$old_sites
TO   ATOM \\\$start_peaks to 99999
END
EOF
rm -f \\\${tempfile}both.pdb >& /dev/null
#\\\${tempfile}dists now contains the minimum 
# format: peak# old# min_dist


# gaurentee a label file for the "old" sites
cat \\\${tempfile}old_sites |\\\\
nawk 'NF>2{++n; printf "label %5d atom %d\\\\n", n, n}' |\\\\
cat >! \\\${tempfile}labels

# get a descriptive label from the "old site" source file
if(-e "\\\$pdbfile") then
    # input file was a PDB file
    cat \\\$sitefile |\\\\
    nawk '/^ATOM/ || /^HETATM/{++n; printf "label %5d %s\\\\n", n, substr(\\\$0,12,15)}' |\\\\
    cat >! \\\${tempfile}labels
endif
if(\\\$?scriptfile) then
    # input file was an mlphare script
    cat \\\$sitefile |\\\\
    nawk '\\\$1~/^DERIV/{deriv=\\\$0}\\\\
          \\\$1~/^ATOM/{++n; printf "label %5d %6s in %s\\\\n", n, \\\$1, deriv}' |\\\\
    cat >! \\\${tempfile}labels
endif
if(! -e "\\\$sitefile") then
    # peaks list was used for distnace self-caclulation
    cat \\\${tempfile}peaks.interesting |\\\\
    nawk 'NF>2{++n;printf "label %5d peak %d\\\\n", n, n}' |\\\\
    cat >! \\\${tempfile}labels
endif

# add these descriptive labels to the peaks list
cat \\\${tempfile}dists \\\${tempfile}labels \\\${tempfile}peaks.interesting |\\\\
nawk '/^dist/{dist[\\\$2]=\\\$4; neighbor[\\\$2]=\\\$3; next}\\\\
      /^label/{label[\\\$2]=substr(\\\$0,13); next}\\\\
      {++n; print \\\$0, dist[n], "label:", label[neighbor[n]]}' |\\\\
cat >! \\\${tempfile}peaks.distlabel
#
# format: xf yf zf X Y Z 1/mult height   dist neighbor name ...


################################################################

# print surviving peaks out to screen
echo ""
echo "unique peaks:"
set xyz = "x        y        z"
if(\\\$?PATT) set xyz = "u        v        w"
echo "  \\\$xyz        mult  height/sigma   dist  from nearest neighbor"
cat \\\${tempfile}peaks.distlabel |\\\\
nawk '{printf "%8.5f %8.5f %8.5f   %4d %8.2f %10.1fA  %s\\\\n", \\\$1, \\\$2, \\\$3, 1/\\\$7, \\\$8,\\\\
       \\\$9, substr(\\\$0, index(\\\$0,"label:")+7)}'


echo "written to \\\$outfile"

cleanup:
# clean up 
rm -f  \\\${tempfile}labels >& /dev/null
rm -f  \\\${tempfile}dists >& /dev/null
rm -f  \\\${tempfile}peaks.distlabel >& /dev/null
rm -f  \\\${tempfile}peaks.interesting >& /dev/null
rm -f  \\\${tempfile}boring_sites >& /dev/null
rm -f  \\\${tempfile}old_sites >& /dev/null

if(\\\$?BAD) exit 9
exit


################################################################
################################################################
################################################################
Setup:
set siteCELL
set sitefile

# scan command line
foreach arg ( \\\$* )
    # recognize map files
    if(("\\\$arg" =~ *.map)||("\\\$arg" =~ *.ext)) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set mapfile = "\\\$arg"

	continue
    endif
    
    # recognize pdb files
    if(("\\\$arg" =~ *.pdb)||("\\\$arg" =~ *.brk)) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set pdbfile = "\\\$arg"
	set siteCELL = \\\`nawk '/^CRYST/{print \\\$2, \\\$3, \\\$4, \\\$5, \\\$6, \\\$7}' \\\$pdbfile | tail -1\\\`
	
	continue
    endif
    
    # recognize mlphare scripts? 
    if(-e "\\\$arg") then
	cat "\\\$arg" |\\\\
	nawk '\\\$1~/^ATOM/ || \\\$1~/^BADATOM/ || \\\$1~/^OLDATOM/{print \\\$3, \\\$4, \\\$5}' |\\\\
	cat >! \\\${tempfile}boring_sites
	# format: xf yf zf
	set sitefile = "\\\$arg"
	set scriptfile = "\\\$arg"
    endif
    
    # recognize sigma-cutoff
    set temp = \\\`echo "\\\$arg" | awk '\\\$1+0 != 0{print \\\$1+0}'\\\`
    if("\\\$temp" != "") then
	set sigma = "\\\$temp"
	continue
    endif
end

# get map parameters
echo "go" | mapdump mapin \\\$mapfile >! \\\${tempfile}.mapdump
if(\\\$status) goto Help

set CELL = \\\`nawk '/Cell dimensions/{print \\\$4, \\\$5, \\\$6, \\\$7, \\\$8, \\\$9; exit}' \\\${tempfile}.mapdump\\\`
set SG   = \\\`nawk '/Space-group/{print \\\$3; exit}' \\\${tempfile}.mapdump\\\`
set GRID = \\\`nawk '/Grid sampling on x, y, z/{print \\\$(NF-2), \\\$(NF-1), \\\$NF; exit}' \\\${tempfile}.mapdump\\\`
rm -f \\\${tempfile}.mapdump >& /dev/null

# see if this is a Patterson map
set temp = \\\`nawk -v SG="\\\$SG" '\\\$1==SG{print \\\$4}' \\\$CLIBD/symop.lib | nawk '/[abcdmn-]/{print "PATT"}'\\\`
if("\\\$temp" != "") set PATT


# convert input coordinate file formats to fractional
if(\\\$#siteCELL != 6) set siteCELL = ( \\\$CELL )

if(-e "\\\$pdbfile") then
    # convert orthogonal PDB coordinates to fractional
    coordconv xyzin \\\$pdbfile xyzout \\\${tempfile}.xyz << EOF >> \\\$logfile
CELL \\\$siteCELL 
INPUT PDB
OUTPUT FRAC
END
EOF
    # all we need are fractional coordinates
    cat \\\${tempfile}.xyz |\\\\
    nawk '{print \\\$2, \\\$3, \\\$4}' |\\\\
    cat >! \\\${tempfile}boring_sites
    rm -f \\\${tempfile}.xyz >& /dev/null
    set sitefile = "\\\$pdbfile"
endif
if(! -e "\\\${tempfile}boring_sites") touch \\\${tempfile}boring_sites
set boring_sites = \\\`cat \\\${tempfile}boring_sites | wc -l\\\`
# format: xf yf zf 

# decide on a "closeness" cutoff for two peaks being the same
if(! \\\$?CLOSE_peaks) set CLOSE_peaks
if("\\\$CLOSE_peaks" == "") then
    # set the "close" criteria to be one grid unit
    echo "\\\$GRID \\\$CELL" |\\\\
    nawk '\\\$1+0>0{print \\\$4/\\\$1}\\\\
          \\\$2+0>0{print \\\$5/\\\$2}\\\\
          \\\$3+0>0{print \\\$6/\\\$3}' |\\\\
sort -n >! \\\${tempfile}close
    set CLOSE_peaks = \\\`nawk 'NR==1{printf "%.2f", \\\$1}' \\\${tempfile}close\\\`
    rm -f \\\${tempfile}close >& /dev/null
endif
# guess? 
if("\\\$CLOSE_peaks" == "") set CLOSE_peaks = 0.5


goto Return_from_Setup

exit
#################################
# the future? 
- support other coordinate file formats
EOF-pickscript
chmod a+x \${scriptDIR}pick.com



















write_oasis:
#################################################################
# don't overwrite user-modified script
if(-e \${scriptDIR}oasis.com) goto write_mad

# create a quick-and-dirty oasis script
#echo "writing \${scriptDIR}oasis.com"

cat << EOF-oasisscript >! \${scriptDIR}oasis.com
#! /bin/csh -f
#
#	Experimental OASIS script
#
#
# set this to wherever your awk program is
alias nawk \$nawk
nawk 'BEGIN{print}' >& /dev/null
if(\\\$status) alias nawk awk


set script  = ./scripts/mlphare.com
set mtzfile = ./mtz/all.mtz
set F1      = ""		# these can be assigned on the command line
set SIGF1   = ""		# but are normally just read in from the mtz
set F2      = ""
set SIGF2   = ""
set PHI     = ""

# these might be important
set Ee      = Se
set sites   = ""		# use the default
set fpp     = ""
set lambda  = "0.9794"		# only needed if fpp is unknown
set outfile = ./oasised.mtz

set tempfile = oasis_temp

if(\\\$#argv == 0) goto Help
goto Setup
# scan command line for:
# mlphare script (and read in atom coordinates)
# new element name
Help:
cat << EOF

usage: \\\$0 mlphare.com FP DANO sad.mtz \\\$Ee 6.32e

where:
mlphare.com	- is an mlphare script, containing the refined sites
sad.mtz		- is an MTZ containing FP and DANO for your SAD data
FP		- the full protein F data set
DANO		- the anomalous difference data set
\\\$Ee		- is the anomalous scatterer
6.32e		- is the expected f" value (in electron equivalents)

defaults:
FP      will default to the first F found in sad.mtz
DANO    will default to the first D found in sad.mtz
f"      will default to the highest anomalous occupancy in mlphare.com
sad.mtz will default to the mtz file used in mlphare.com

note: all mlphare.com really need be is a list of:
ATOM ANO x y z 0 occ
where x,y,z are fractional coordinates, and occ is a "relative" occupancy
EOF

exit 2
ReturnFromSetup:

if(! -e "\\\$mtzfile") then
    echo "ERROR: \\\$mtzfile does not exist! "
    goto Help
endif

#####################################################################################
#####################################################################################
#####################################################################################
cat << EOF >! \\\${tempfile}oasis.in
CEL \\\$CELL
HCO \\\$EE \\\$cell_sites
ANO \\\$EE \\\$fpp
LCE 7
FIT
OAS
\\\$usePHI
LABIN  F1=\\\$F1 SIGF1=\\\$SIGF1 F2=\\\$F2 SIGF2=\\\$SIGF2 \\\$TPHI
LABOUT F1=\\\$F1 SIGF1=\\\$SIGF1 PHI=PHIOAS W=FOMOAS
EOF
# append the site list
cat \\\${tempfile}sites >> \\\${tempfile}oasis.in
echo "END"           >> \\\${tempfile}oasis.in

# display this, so user can actually see it! 
cat << EOF
Running "oasis" with \\\$sites \\\$Ee sites from \\\$script on
\\\$F1 and \\\$F2 from \\\$mtzfile
Assuming f" of \\\$Ee is \\\$fpp at the wavelength used for \\\$F1
EOF
if("\\\$PHI" != "") echo "\\\$PHI will be used for comparison only"
echo "-------------------------------------------------------"
echo "OASIS input:"
cat \\\${tempfile}oasis.in
echo "-------------------------------------------------------"

# now, actually run oasis:
cat \\\${tempfile}oasis.in |\\\\
oasis hklin \\\$mtzfile hklout \\\$outfile 
if(\\\$status) then
    echo "Woops! See above for what went wrong."
    exit 9
endif

echo "\\\$outfile is ready. "

# clean up
rm -f \\\${tempfile}sites >& /dev/null
rm -f \\\${tempfile}oasis.in >& /dev/null

exit


Setup:
#####################################################################################
#####################################################################################
#####################################################################################
set TPHI   = ""
set usePHI = ""
set EE

# scan command line for args
foreach arg ( \\\$* )
    # warn about probable mispellings
    if("\\\$arg" =~ *.mtz) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	set mtzfile = "\\\$arg"
	continue
    endif
    
    if("\\\$arg" =~ *phare*) then
	if(! -e "\\\$arg") then
	    echo "WARNING: \\\$arg does not exist! "
	    continue
	endif
	grep "ATOM" "\\\$arg" >& /dev/null
	if(\\\$status) then
	    echo "WARNING: no atoms in \\\$arg"
	    continue
	endif 
	set script = "\\\$arg"
	continue
    endif
    
    if(("\\\$arg" =~ [A-Z][a-y])||("\\\$arg" =~ [HBCNOFPSKVYIWU])) then
	# might as well consider this an element
	set temp = "\\\$arg"
	if(\\\$?CLIBD) then
	    # check the CCP4 atom database
	    set temp = \\\`nawk -v arg=\\\$arg 'NF==1 && toupper(\\\$1)==toupper(arg){print; exit}' \\\$CLIBD/atomsf.lib\\\`
	endif
	if("\\\$temp" != "") then
	    set Ee = "\\\$arg"
	    continue
	endif
    endif
end

grep "ATOM" \\\$script >& /dev/null
if(\\\$status) then
    echo "ERROR! no atoms in \\\$script"
    goto Help
endif

if(! -e "\\\$mtzfile") then
    # see if we can retrieve the script's mtz
    set mtzfiles = \\\`nawk 'BEGIN{RS=" "} {gsub("[\\\\042\\\\047]"," ",\\\$0); print}' \\\$script | nawk '/\\\\.mtz\\\$/{print}'\\\`
    
    foreach mtz ( \\\$mtzfile \\\$mtzfiles )
	echo "head" | mtzdump hklin \\\$mtz >& /dev/null
	if(! \\\$status) then
	    echo "reading \\\$mtz"
	    set mtzfile = \\\$mtz
	    break
	endif
    end
endif

if(! -e "\\\$mtzfile") then
    echo "ERROR: \\\$mtzfile does not exist! "
    goto Help
endif

# read important constants from the mtz header
echo "go" | mtzdump HKLIN \\\$mtzfile >! \\\${tempfile}mtzdump
set CELL  = \\\`nawk '/Cell Dimensions/{getline;getline;print}' \\\${tempfile}mtzdump\\\`
set SG    = \\\`nawk '/Space group/{print \\\$5}' \\\${tempfile}mtzdump\\\`
set SGnum = \\\` nawk '/Space group/{print \\\$NF+0}' \\\${tempfile}mtzdump \\\`
set SG = \\\` nawk -F "[\\\\047]" '/Space group/{print \\\$2}' \\\${tempfile}mtzdump \\\`
set SG = \\\` nawk -v num=\\\$SGnum '\\\$1==num && NF>5{print \\\$4}' \\\${CLIBD}/symop.lib \\\`
set hiRES = \\\`nawk '/Resolution Range/{getline;getline;print \\\$6}' \\\${tempfile}mtzdump\\\`

if(\\\$#CELL != 6) then
    echo "ERROR: unable to read \\\$mtzfile"
    goto Help
endif

# get data column label names from the mtz file
nawk 'NF>3' \\\${tempfile}mtzdump |\\\\
nawk '\\\$(NF-1)=="F"{print "F", \\\$NF}\\\\
      \\\$(NF-1)=="D"{print "D", \\\$NF}\\\\
      \\\$(NF-1)=="P"{print "P", \\\$NF}\\\\
      \\\$(NF-1)=="Q"{print "S", \\\$NF}' |\\\\
nawk '/^F/{++n} {printf "%s", \\\$1; \\\\
       if(\\\$1=="S") printf "%s", last;\\\\
printf " %d %s\\\\n",n, \\\$2; last=\\\$1}' |\\\\
nawk '\\\$1=="F"{F[\\\$2]=\\\$NF} \\\$1=="SF"{SF[\\\$2]=\\\$NF} \\\\
      \\\$1=="D"{D[\\\$2]=\\\$NF} \\\$1=="SD"{SD[\\\$2]=\\\$NF} \\\\
      \\\$1=="P"{P=P \\\$NF} \\\\
      END{for(i in F){\\\\
	print i, F[i], SF[i], D[i],SD[i], P, " ";}}' |\\\\
sort -n >! \\\${tempfile}datasets


# one last pass through command line
# allow user overrides of all internal variables
set i = 0
echo -n "" >! \\\${tempfile}userlabels
while( \\\$i < \\\$#argv )
    @ i = ( \\\$i + 1 )
    @ nexti = ( \\\$i + 1 )
    @ lasti = ( \\\$i - 1 )
    if(\\\$nexti > \\\$#argv) set nexti = \\\$#argv
    if(\\\$lasti < 1) set lasti = 1
    set arg = "\\\$argv[\\\$i]"
    
    # see if a dataset label was given
    grep " \\\$arg " \\\${tempfile}datasets >& /dev/null
    if(! \\\$status) then
	if(\\\$?NO) then
	    # user doesn't want this label
	    # filter it out of the input files
	    egrep -v " \\\$arg " \\\${tempfile}datasets >! \\\${tempfile}
	    mv \\\${tempfile} \\\${tempfile}datasets
	    unset NO
	else
	    # must want only this label?
	    cat \\\${tempfile}mtzdump |\\\\
	    nawk -v label=\\\$arg 'NF>2 && \\\$NF==label{print \\\$NF}' |\\\\
	    cat >> \\\${tempfile}userlabels
	endif
	continue
    endif
    
    # only look at non-file words now
    if(! -e "\\\$arg") then
	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
			set loRES = "\\\$temp[1]"
			set hiRES = "\\\$temp[2]"
		    endif
		else
		    # this isn't used, but...
		    if("\\\$temp" != "") set hiRES = "\\\$temp"
		endif
		unset NO
		continue
	    endif
	    
	    # maybe setting f" value?
	    if(("\\\$arg" =~ *e)||("\\\$argv[\\\$nexti]" == "e")) then
		set temp = \\\`echo "\\\$arg" | nawk '\\\$1+0>0.1 && \\\$1+0<100{print \\\$1+0}'\\\`
		if(\\\$#temp == 1) then
		    set fpp = "\\\$temp"
		    unset NO
		    continue
		endif
	    endif
	endif
	
	# allow "NO" logic to carry through
	unset NO
	if(("\\\$arg" == "no")||("\\\$arg" == "not")) set NO
	if(("\\\$arg" == "don't")||("\\\$arg" == "ignore")) set NO
	if("\\\$arg" == "except") set NO
    endif
end

rm -f \\\${tempfile}mtzdump >& /dev/null

#######################################################
# see if user specified particular labels
set temp = \\\`cat \\\${tempfile}userlabels | wc -l\\\`
if(\\\$temp != 0) then
    # turn the "user" labels into real label files
    cat \\\${tempfile}userlabels \\\${tempfile}datasets |\\\\
    nawk 'NF==1{++n; label[n]=\\\$NF}\\\\
          NF>1 {for(i in label) for(j=2;j<=NF;++j){\\\\
		if(label[i]==\\\$j) print i, \\\$2,\\\$3,\\\$4,\\\$5;break}}' |\\\\
    sort -n >! \\\${tempfile}
    mv \\\${tempfile} \\\${tempfile}datasets >& /dev/null
endif
if((\\\$temp == 0)&&("\\\$F1" != "")) then
    # apply the labels from the top of this script?
    echo "\\\$F1 \\\$F2 \\\$SIGF1 \\\$SIGF2 \\\$PHI" | nawk '{for(i=1;i<=NF;++i) print \\\$i}' >! \\\${tempfile}userlabels
    cat \\\${tempfile}userlabels \\\${tempfile}datasets |\\\\
    nawk 'NF==1{++n; label[n]=\\\$NF}\\\\
          NF>1 {for(i in label) for(j=2;j<=NF;++j){\\\\
		if(label[i]==\\\$j) print i, \\\$2,\\\$3,\\\$4,\\\$5;break}}' |\\\\
    sort -n >! \\\${tempfile}
    set temp = \\\`cat \\\${tempfile} | wc -l\\\`
    if(\\\$temp != 0) mv \\\${tempfile} \\\${tempfile}datasets >& /dev/null    
endif
rm -f \\\${tempfile}userlabels >& /dev/null

###############################################################
# assign actual "LABIN" cards for oasis for each dataset
if("\\\$F1" == "")    set F1 = \\\`head -1 \\\${tempfile}datasets | nawk '{print \\\$2}'\\\`
if("\\\$F2" == "")    set F2 = \\\`head -1 \\\${tempfile}datasets | nawk '{print \\\$4}'\\\`
if("\\\$SIGF1" == "") set SIGF1 = \\\`head -1 \\\${tempfile}datasets | nawk '{print \\\$3}'\\\`
if("\\\$SIGF2" == "") set SIGF2 = \\\`head -1 \\\${tempfile}datasets | nawk '{print \\\$5}'\\\`
grep " \\\$PHI " \\\${tempfile}datasets >& /dev/null
if(\\\$status) set PHI = ""
if("\\\$PHI" == "") set PHI = \\\`head -1 \\\${tempfile}datasets | nawk '{print \\\$6}'\\\`
if("\\\$PHI" != "") then
    set TPHI = "TPHI=\\\$PHI"
    set usePHI = "PHI"
endif

rm -f \\\${tempfile}datasets >& /dev/null

# oasis needs this to be uppercase
set EE = \\\`echo "\\\$Ee" | nawk '{print toupper(\\\$1)}'\\\`

###############################################################
# convert MLphare sites to OASIS sites
set maxocc = \\\`nawk '\\\$1 ~ /^ATOM/{print \\\$7}' \\\$script | sort -n | tail -1\\\`
cat \\\$script |\\\\
nawk -v Ee=\\\$EE -v norm=\\\$maxocc 'BEGIN{pos = "POS"}\\\\
 \\\$1 ~ /^ATOM/{++i; printf "%-4s %2s %7s %7s %7s %3d %7.5f\\\\n", pos, toupper(Ee), \\\$3, \\\$4, \\\$5, i, \\\$7/norm; pos=""}' |\\\\
cat >! \\\${tempfile}sites
set sites = \\\`cat \\\${tempfile}sites | wc -l\\\`

# need number in cell
set ASU_per_CELL = \\\`nawk -v SG=\\\$SG '\\\$4==SG{print \\\$3}' \\\$CLIBD/symop.lib | head -1\\\`
set cell_sites = \\\`echo "\\\$sites \\\$ASU_per_CELL" | nawk '{print \\\$1 * \\\$2}'\\\`

# this is probably the best indicator of f" anyway
if("\\\$fpp" == "") set fpp = "\\\$maxocc"

if("\\\$fpp" == "") then
    # use crossec to calculate this from the wavelength?
    set fpp = 1
endif


goto ReturnFromSetup


exit
#############################################
# the future?

read solve.status (where do we get \\\$Ee?)
EOF-oasisscript
chmod a+x \${scriptDIR}oasis.com













write_mad:
#################################################################
# don't overwrite user-modified script
if(-e \${scriptDIR}mad.awk) goto write_next

# write the MAD-constraint averaging awk program
#echo "writing \${scriptDIR}mad.awk"

cat << EOF-madscript >! \${scriptDIR}mad.awk
#! \$nawk -f
#
#   Constrain an mlphare script to have sites with
#   the same B-factor and overall occupancy,
#   regardless of wavelength
#
#   That is, impose the constraint that atoms with the same "ATOM#"
#   card should correspond to the same "site", and have the same xyz 
#   coordinate, B-factor, and "true" occupancy, regardless of wavelength.
#   The mlphare occupancies, however are modified by an fp and fpp 
#   value that is the same for every atom in a particular DERIV block (wavelength).
#
#   occ  = fp*tocc(site)
#   aocc = fpp*tocc(site)
#   Bfac = Bfac(site)
#
#   This script assumes a single value for fp and fpp for each wavelength, 
#   and, therefore, should not be used for double-edge MAD experiments! 
#
BEGIN{
    #  same_occ==1 means force all sites to have same (effective) occupancy
    if(same_occ=="") same_occ = 0
    #  same_B==1 means force all sites to have same B-factor
    if(same_B=="")   same_B   = 0
}

\\\$1 ~ /^LABIN/ || labinline{
    labinline= ( \\\$NF == "-" )
    for(i=1;i<=NF;++i){
	if(\\\$i ~ /^FP=/)
	{
	    FP = substr(\\\$i,index(\\\$i,"=")+1)
	}
	if(\\\$i ~ /^FPH/)
	{
	    wave = substr(\\\$i,4)+0
	    FPH[wave] = substr(\\\$i,index(\\\$i,"=")+1)
	}
	if(\\\$i ~ /^DPH/)
	{
	    wave = substr(\\\$i,4)+0
	    DPH[wave] = substr(\\\$i,index(\\\$i,"=")+1)
	}
    }
}

\\\$1 ~ /^DERIV/{
    ++waves
}

\\\$1 ~ /^ATOM/{
    # use atom number as "site" identifier
    atomnum = substr(\\\$1, 5)+0
    Bfac[atomnum] += \\\$NF;
    X[atomnum] += \\\$3; Y[atomnum] += \\\$4; Z[atomnum] += \\\$5;
    ++count[atomnum];
    
     fp[waves] += \\\$6;
    fpp[waves] += \\\$7;
    ++atoms[waves];
    
    # remember each atom's occupancy
     Occ[waves " " atomnum] = \\\$6;
    aOcc[waves " " atomnum] = \\\$7;
    ++occs[num];

    ++tatoms;
    B += \\\$NF
}

{line[NR] = \\\$0}

END{
    if(! waves) exit
    if(! tatoms) exit
    # overall, average B-factor
    B /= tatoms

    # compute mean f' and f" for each wavelength
    for(wave in fp)
    {
	# normalize anomalous and dispersive differences
	if(atoms[wave]) fp[wave]  =  fp[wave]/atoms[wave];
	if(atoms[wave]) fpp[wave] = fpp[wave]/atoms[wave];
    }
    
    # add up combined occupancy for each atom (averaged over all wavelengths)
    for(atomnum in Bfac)
    {
	# compute mean B-factor for each site
	if(count[atomnum]) Bfac[atomnum] = Bfac[atomnum]/count[atomnum];
	
	# compute mean XYZ position for each site
	if(count[atomnum])
	{
	    X[atomnum] = X[atomnum] / count[atomnum];
	    Y[atomnum] = Y[atomnum] / count[atomnum];
	    Z[atomnum] = Z[atomnum] / count[atomnum];
	}
	
	# compute mean occ,aocc for each wavelength
	occ_count = 0
	for(wave in fp)
	{
	    if( fp[wave])
	    {
		tOcc[atomnum] += Occ[wave " " atomnum]/fp[wave]
		++occ_count
	    }
	    if( fpp[wave])
	    {
		tOcc[atomnum] += aOcc[wave " " atomnum]/fpp[wave]
		++occ_count
	    }
	}
	# divide by total number of occupancies contributing to this "total"
	if(occ_count) tOcc[atomnum] = tOcc[atomnum]/occ_count
	
	# optionally set all occs to same value
	if(same_occ) tOcc[atomnum] = 1;
	if(same_B)   Bfac[atomnum] = B;
    }
    
    
    # now re-write the lines in the script
    wave = 0
    for(i=1;i<=NR;++i)
    {
	split(line[i],w);
	if(w[1] ~ /^DERIV/) ++wave
	
	if(w[1] ~ /^ATOM/)
	{
	    atomnum = substr(w[1], 5)+0
	    
	    line[i] = sprintf(" ATOM%-3d %3s  %6.3f %6.3f %6.3f %6.3f %6.3f BFAC %8.3f",\\\\
	    atomnum, w[2], X[atomnum], Y[atomnum], Z[atomnum], \\\\
	    fp[wave]*tOcc[atomnum], fpp[wave]*tOcc[atomnum], Bfac[atomnum])
	}
	
	print line[i];
    }
    
    print "Summary:"
    for(wave=1;wave<=waves;++wave)
    {
	printf "%s - %s = %6.3f \\\\n", FPH[wave], FP, fp[wave];
    }
    for(wave=1;wave<=waves;++wave)
    {
	printf "%s = %6.3f \\\\n", DPH[wave], fpp[wave];
    }
    for(wave=1;wave<=waves;++wave)
    {
#	printf "DERIV %d %6.3f %6.3f\\\\n", wave, fp[wave], fpp[wave];
    }
}

EOF-madscript
chmod a+x \${scriptDIR}mad.awk








write_next:

goto Return_Setup_scripts


















Unwrap_Awk_Scripts:
################################################################################

 #    #  #    #  #    #  #####     ##    #####
 #    #  ##   #  #    #  #    #   #  #   #    #
 #    #  # #  #  #    #  #    #  #    #  #    #
 #    #  #  # #  # ## #  #####   ######  #####
 #    #  #   ##  ##  ##  #   #   #    #  #
  ####   #    #  #    #  #    #  #    #  #

################################################################################
#   unwrap some utility scripts
################################################################################
cat << EOF-mtzstuff >! \${tempfile}mtzstuff.awk
#! \$nawk -f
#
#
#	Organize info from an mtzdump in more accessible format
#
#
#
# resolution limits
/Resolution Range/ {
    getline; getline;
    hires = \\\$6;
    lores = \\\$4;
}

# cell
/Cell Dimensions/ {
    getline; getline;
    cell = \\\$0
}

# space group
/Space group/{
    SG = \\\$NF+0
}

/Column Labels/{
    getline; getline;
    while(NF>0)
    {
	for(i=1;i<=NF;++i)
	{
	    ++labels;
	    label[labels] = \\\$i
	}
	getline
    }
}

/Column Types/{
    getline; getline;
    while(NF>0)
    {
	for(i=1;i<=NF;++i)
	{
	    ++t;
	    type[t] = \\\$i
	}
	getline
    }
}

/OVERALL FILE STATISTICS/,/LIST OF REFLECTIONS/{
    for(l in label)
    {
	if(\\\$NF == label[l])
	{
	    # retrieve interesting numbers from the summary list
	    mean[l] = \\\$(NF-4)+0
	    completeness[l] = substr(\\\$0, 32)+0
	}
    }
}



END {
    # now print everything out
    print "CELL", cell
    print "SYMM", SG
    print "RESO", lores, hires
    for(l=1;l<=labels;++l)
    {
	printf "COL %-15s %s %6.2f %6.2f%%\\\\n", label[l], type[l], mean[l], completeness[l]
    }
    
    # now try to equate Fs and DANOs with their sigmas
    for(l=1;l<=labels;++l)
    {
	# structure factors
	if(type[l]=="F")
	{
	    ++fs; 
	    F[fs]=label[l];
	    meanF[F[fs]]=mean[l];

	    last = F[fs];
	}
	
	# anomalous differences (in F units)
	if(type[l]=="D")
	{
	    ++ds; 
	    D[ds]=label[l];
	    meanD[D[ds]]=mean[l];

	    last = D[ds];
	}
	
	# sigmas (of anything)
	if(type[l]=="Q")
	{
	    ++ss;
	    Q[ss]=label[l];
	    meanQ[Q[ss]]=mean[l]; 
	    
	    # putatively assign sigmas to most recent F (almost always right)
	    sigma[last]=Q[ss];
	}
    }

    # now go see if any sigmas have nearly identical names with an F or DANO
    for(s=1;s<=ss;++s)
    {
	# run down all Fs
	for(f=1;f<=fs;++f)
	{   
	    # look for SIG(name) to match name
	    if(Q[s] == "SIG" F[f])
	    {
		sigma[F[f]]=Q[s];
	    }
	}
	
	# same for DANOs
	for(d=1;d<=ds;++d)
	{
	    if(Q[s] == "SIG" D[d])
	    {
		sigma[D[d]]=Q[s];
	    }
	}
    }
    
    # now print out putative pairs
    for(f=1;f<=fs;++f)
    {
	if(meanQ[sigma[F[f]]]!=0)
	{
	    meanF[F[f]] = meanF[F[f]] / meanQ[sigma[F[f]]];
	}
	else
	{
	    meanF[F[f]]="";
	}
      
	printf "F: %-10s %-10s %-10s\\\\n", F[f], sigma[F[f]], meanF[F[f]];
    }
    for(d=1;d<=ds;++d)
    {
	if(meanQ[sigma[D[d]]]!=0)
	{
	    meanD[D[d]] = meanD[D[d]] / meanQ[sigma[D[d]]];
	}
	else
	{
	    meanD[D[d]]="";
	}
      
	printf "D: %-10s %-10s %-10s\\\\n", D[d], sigma[D[d]], meanD[D[d]];
    }
}
EOF-mtzstuff
chmod a+x \${tempfile}mtzstuff.awk













cat << EOF-sitereader >! \${tempfile}sitereader.awk
#! \$nawk -f
#
#
#	Retrieve arbitrarily formatted heavy-metal sites
#
#	looks for contiguous blocks of lines 
#	all of them containing three consecutive numbers written
#	to 3 or more decimal places and betwen -1.1 and +1.1
#
BEGIN{
    # estimate of B, to aid in finding real B-factors
    if(! B) B = 50
    if(! wilsonB) wilsonB = B
    if(! expectB) expectB = wilsonB
    
    if(! OCC) OCC = 1
    if(! expectOCC) expectOCC = OCC
}

# line must have at least 3 words

NF>=3{
    coords=0;
    # recognize mlphare format
    if(\\\$1 ~ /^ATOM/ && \\\$2 == "ANO" && \\\$8 == "BFAC")
    {
	OCC_col=4; AOCC_col=5; BFAC_col=6;
    }
    
    for(i=1;i<=NF;++i)
    {
	# pattern to recognize fractional coordinates
	if(((\\\$i ~ /^[01].[0-9][0-9][0-9]/)||(\\\$i ~ /^-[01].[0-9][0-9][0-9]/))&&
	    (\\\$i+0>=-1.1)&&(\\\$i+0<=1.1))
	{
	    ++coords
	}
	else
	{
	    coords=0
	}
      
	# check for 3 consecutive hits \\\\
	if(coords==3)
	{
	    # this line is a site
	    ++site;
	    ++sites;
	    
	    XYZ[site] = ""
	    for(i=i-2;i<=NF;++i)
	    {
		# remember this line
		if(\\\$i !~ /[^0-9.-]/)
		{
		    XYZ[site] = XYZ[site] " " \\\$i;
		}
	    }

	    # reset site list with each new block
	    if(sites>site) sites = site;
	}
    }
    
    if(coords != 3)
    {
	# this was not a site, so reset the site counter for the
	# next block of sites
	site = 0;
    }
}

END {
    # bail if we found no sites
    if(! sites) exit

    # see if we can assign the rest of the numbers
    maxnums = 10
    for(site=1;site<=sites;++site)
    {
	nums=split(XYZ[site], num)
	
	# remember length of shortest list
	if(numsmean[max_value]) max_value = i;
    }
    	
    # biggest B-factor dominates
    if(sqrt((mean[max_value]-expectB)^2)/expectB < 0.5)
    {
	BFAC_col=max_value;
    }
    
    # start on right side searching for B factor
    for(i=maxnums;i>3;--i)
    {
	# check each column against the expected B value
	if(sqrt((mean[i]-expectB)^2)/expectB < 0.5)
	{
	    # this column is within 50% of expected B factor
	    if(! BFAC_col) BFAC_col=i;
	}
    }
    
    # start at 4th position for occupancy
    for(i=4;i<=maxnums;++i)
    {
	# real occupancy could be positive or negative
	if((sqrt((sqrt(mean[i]^2)-expectOCC)^2)/expectOCC < 0.8)&&(i != BFAC_col))
	{
	    # this column is within 50% of expected occupancy value 
	    # (ignoring sign)
	    if(! OCC_col) OCC_col=i;
	}
	
	# anomalous occupancy is always positive, and usually after OCC
	if((sqrt((mean[i]-sqrt(expectOCC^2))^2)/expectOCC < 0.8) && (i != OCC_col) && (i != BFAC_col))
	{
	    # this column is within 50% of expected occupancy value
	    if(! AOCC_col) AOCC_col=i;
	}	
    }
    
    # now print out the last, contiguous block of sites
    for(site=1;site<=sites;++site)
    {
	# preliminary assignment of variables
	nums=split(XYZ[site], num)
	X   = num[1];
	Y   = num[2];
	Z   = num[3];
	OCC ="?.???";
	AOCC="?.???";
	BFAC="?.???";
	
	# assign values (if they are known)
	if( OCC_col)  OCC = sprintf("%6.3f", num[OCC_col]);
	if(AOCC_col) AOCC = sprintf("%6.3f", num[AOCC_col]);
	if(BFAC_col) BFAC = sprintf("%8.3f", num[BFAC_col]);

	if((AOCC=="?.???")&&(OCC!="?.???"))
	{
	    # might as well...
	    AOCC = sprintf("%6.3f", sqrt(OCC^2));
	}
	
	# now print out the site
	printf " ATOM%-3d ANO  %6.3f %6.3f %6.3f %6s %6s BFAC %8s\\\\n", 
	  site, X, Y, Z, OCC, AOCC, BFAC;
    }
}
EOF-sitereader
chmod a+x \${tempfile}sitereader.awk


goto Return_Unwrap_Awk_Scripts




exit
############################################

todo:
change atom-find cutoff for HURRY mode
update README file
test site permutation logic
test CUI
don't reject atoms with OCC==AOCC==0 in MAD mode


# needed?
"NO_B" refinement?
use oasis.com
More agressive atom eliminator?
automatic heavy-atom cutoff in DM



# wish list
implement minus-one feature
skeletonize in DM?
anisotropic Bs
Run SOLVE?
read in scalepack files?
optionally impose MAD restraints on sites

EOF-Phaser
chmod a+x ${Elfsheim}/Phaser

echo -n "."














































# Fourier
#cat << EOF-Fourier >! ${Elfsheim}/Fourier
#EOF-Fourier
#chmod a+x  ${Elfsheim}/Fourier

#echo "."



















# Refmacer
cat << EOF-Refmacer >! ${Elfsheim}/Refmacer
#! /bin/tcsh -f
#
echo "Refmacer Elves v 1.3.6     Just getting started.   James Holton 4-25-10"
echo ""
#
#
#   Universal (more-or-less) setup of REFMAC
#
#	This script auto-detects chain IDs and chain end information in the
#	PDB file, and sets up refmac/protin/arpp appropriately
#
#	As long as your PDB is formatted properly for refmac: 
#	- Chain ID at column 22
#	- acetyl group is: 
#ATOM      1  CT2 ARG A   1      71.507  24.225  20.829  1.00 51.12   6       C  
#ATOM      2  CT1 ARG A   1      70.031  24.413  20.903  1.00 49.18   6       C  
#ATOM      3  OT  ARG A   1      69.217  23.895  20.123  1.00 50.52   8       O  
#ATOM      4  N   ARG A   1      69.934  25.196  21.953  1.00 47.52   7       N  
#	- multiple conformers are:
#ATOM     31  N   SER A   3      69.379  26.088  17.587  1.00 36.99   7       N  
#ATOM     32  CA  SER A   3      68.368  25.330  16.881  1.00 38.70   6       C  
#ATOM     33  C   SER A   3      66.970  25.474  17.504  1.00 38.53   6       C  
#ATOM     34  O   SER A   3      65.969  25.505  16.775  1.00 38.11   8       O  
#ATOM     35  CB  SER A   3      68.741  23.848  16.842  1.00 39.47   6       C  
#ATOM     36  OG ASER A   3      67.636  22.917  16.373  0.50 39.89   6       C  
#ATOM     37  OG BSER A   3      67.980  23.119  15.733  0.50 41.31   6       C  
#	this script should be able to tell REFMAC what it means
#
#
#
#
#	Things you will need:
#	the programs listed below
#
################################################################################
#
# non-ccp4 acessory programs used
#
set MAPMAN =  /programs/rave/lx_mapman

goto Find_awk
Return_Find_awk:

# nice symbols, but may not be portable
set ANG = \`echo "" | nawk 'BEGIN{printf "\\305"}'\`
set DEG = \`echo "" | nawk 'BEGIN{printf "\\260"}'\`
#set ANG = "A"
#set DEG = "deg"

if(! \$?CCP4) then
    echo -n "Attempting to set up CCP4 ... "

    set ccp4setup = ""
    foreach place ( /programs/xtal/ccp4_3.4/ /usr/xtal/CCP4_v3.4/ /programs/xtal /programs/ /usr/xtal /usr/local /usr/ )
	if((! -e "\$ccp4setup")&&(-e "\$place")) then
	    # look for setup scripts here
	    set ccp4setup = \`find \${place} -name ccp4.setup |& nawk '/ccp4.setup\$/{print \$NF}' | tail -1\`
	endif
        if((-e "\$ccp4setup")&&(! \$?CCP4)) then
            source \$ccp4setup
            setenv CCP4_SCR    \`pwd\`/temp
            setenv BINSORT_SCR \`pwd\`/temp
            echo "using \$ccp4setup"
        endif
    end
endif
if(! \$?CCP4) then
    echo "failed."
    echo "Please ask your sysadmin how to set up CCP4, "
    echo "Or go to: netscape http://www.dl.ac.uk/CCP/CCP4/main.html"
    echo "about getting the CCP4 program suite."
    echo "and run \$0 again."
    
    echo "If you have Red Hat Linux, you can get ccp4 by typing:"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-lib-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-progs-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-etc-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-examples-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-doc-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-manual-3.5.1-5.i386.rpm"
    echo "rpm -i http://imsb.au.dk/~mok/linux/dist/rpms/ccp4-html-3.5.1-5.i386.rpm"
    exit 9
    set CCP4_LIB
endif
# CCP4 v4.x renamed arpp
set arpp = arpp
which \$arpp >& /dev/null
if(\$status) then
    set arpp = arp_warp
endif

# CCP4 v5.x renamed refmac
set refmac = refmac
which \$refmac >& /dev/null
if(\$status) then
    set refmac = refmac5
endif


setenv CCP4_OPEN       UNKNOWN
# make sure we can write to scratch directories
if(! \$?CCP4_SCR) setenv CCP4_SCR .
if(! \$?BINSORT_SCR) setenv BINSORT_SCR .

touch \${CCP4_SCR}/this\$\$ >& /dev/null
if(\$status) then
    # safest to do this
    setenv CCP4_SCR .
endif
rm -f \${CCP4_SCR}/this\$\$ >& /dev/null

touch \${BINSORT_SCR}/this\$\$ >& /dev/null
if(\$status) then
    # safest to do this
    setenv BINSORT_SCR .
endif
rm -f \${BINSORT_SCR}/this\$\$ >& /dev/null


# check that current directory is writable
touch ./this\$\$ >& /dev/null
if(\$status) then
    # can't write to current directory!
    chmod u+w . >& /dev/null
    touch ./this\$\$ >& /dev/null
    if(\$status) then
	# can't chmod current directory either
	echo "ERROR! We can't write to this directory!"
	pwd
	echo "Please cd to the place you want to process your data, and"
	echo "then run \$0 again."
	exit 9
    else
	# warn user about what we did
	echo "Had to make current directory writable:"
	echo "chmod u+w ."
    endif
    rm -f ./this\$\$ >& /dev/null
endif
rm -f ./this\$\$ >& /dev/null

# no dumping! 
limit coredumpsize 0

if(! -e scripts) mkdir scripts
if(! -e temp)    mkdir temp
if(! -e maps)    mkdir maps
if(! -e logs)    mkdir logs
if(! -e pdb)     mkdir pdb
if(! -e o)       mkdir o

#
################################################################################
#
#  Set default parameters

set scriptname     = ./scripts/refmac.com
set convergescript = ./scripts/converge.com
set arpscriptname  = ./scripts/arp.com
set fftscriptname  = ./scripts/maps.com
set RMSD           = ./scripts/rmsd

set newpdbname = ./pdb/starthere.pdb
set mtzfile    = ./refine.mtz

set F	       = ""
set SIGF       = ""
set hires      = ""
set lores      = ""
set HL	       = ""
set dicfile    = "../protin.SeMET.dic"
set dicfile    = ""

set xyzlim   = ""


# Cycle Numbers for running arp, or quitting 
# converge will do "refcycle" rounds of refmac refinement per arp cycle
set SUPERCYCLE = 10
# ARP will run every "arpcycle" refmac cycles (regardless of convergence)
set arpcycle  = 1000
# this script will quit after "maxcycle" total refmac cycles
set maxcycle  = 1000
set cycle     = ""

# chain to which ARP will add water atoms (default, water chain in your PDB)
set ARPCHAIN  = "S"

###############################################################################
###############################################################################
###############################################################################
###############################################################################
###############################################################################
###############################################################################
###############################################################################
###############################################################################
###############################################################################

set tempfile = \$CCP4_SCR/refmactemp
set SG       = ""
set pdbin    = ""

# scan command line
foreach arg ( \$* )
    if(\$arg =~ *.mtz) set mtzfile = \$arg
    if(\$arg =~ *.pdb) set pdbin = \$arg
    if(\$arg =~ *.brk) set pdbin = \$arg
    if((\$arg =~ [1-9]*)&&(\$arg =~ *[0-9])) set cycle = \$arg
    if(\$arg == nice)  renice -n 40 \$\$
    if(\$arg =~ *.dic) set dicfile = \$arg
end

if(! -e "\$pdbin") then
    echo "ERROR: \$pdbin does not exist! "
endif

if(! -e "\$mtzfile") then
    echo "ERROR: \$mtzfile does not exist! "
endif

if((! -e "\$pdbin")||(! -e "\$mtzfile")) then
cat << EOF

usage: \$0 input.pdb [./refine.mtz] [converge] [nice]

where:
	input.pdb 	- the PDB file you want to refine
	refine.mtz	- the file containing Fs and phases you want to refine against

	converge	- wait for refmac to converge, then run arp, (and repeat)
	nice		- run refmac/arp as "nice" processes

--------

logs/refmac*.log	- will be the REFMAC logs
 pdb/refmac*.pdb	- will be the refined PDB files
   o/*.omap		- will be the sigmaa maps (O format)

EOF
    exit 1
endif

#######################################################################################
#   check for dictionary file
#
if(! -e "\$dicfile") then
    if("\$dicfile" != "") then
	echo "WARNING: \$dicfile does not exist! "
	echo "         using \$CLIBD/protin.dic "
    endif
    set dicfile = "\$CLIBD/protin.dic"
endif

#######################################################################################
#   Unwrap utility scripts
#
goto Unwrap_awk_Scripts
# \${tempfile}mtzstuff.awk
# \${tempfile}reformatpdb.awk
RetrnUnwrap_awk_Scripts:


#######################################################################################
#   Info from MTZ file
#
# get Cell and SG from MTZ file
echo "go" | mtzdump HKLIN \$mtzfile >! \${tempfile}mtzdump
if(\$status) then
    echo "unable to read \$mtzfile"
    echo "make sure \$mtzfile exists, and is not corruped, and then run"
    echo "\$0 again."
    exit 255
endif
# do this now
set HKLs = \`nawk '/Number of Reflections/{print \$NF}' \${tempfile}mtzdump\`

# now turn the dump into something more readable
cat \${tempfile}mtzdump |\\
nawk -f \${tempfile}mtzstuff.awk >! \${tempfile}
mv \${tempfile} \${tempfile}mtzdump

set SG = \`nawk '/^SYMM/{print \$NF}' \${tempfile}mtzdump\`
set CELL = \`nawk '/^CELL/{print substr(\$0, 5)}' \${tempfile}mtzdump\`
#
# get high and low resolution limits
if("\$hires" == "") set hires = \`nawk '/^RESO/{print \$NF}' \${tempfile}mtzdump\`
if("\$lores" == "") set lores = \`nawk '/^RESO/{print \$2}' \${tempfile}mtzdump\`
#
# get "best" F and SIGF in \$mtzfile
cat \${tempfile}mtzdump |\\
nawk '/^COL/ && \$3=="F"{comp[\$2]=\$NF} /^F:/{print \$0, \$NF*comp[\$2]}' |\\
sort -n -k5 | tail -1 |\\
cat >! \${tempfile}
set    F = \`nawk '{print \$2}' \${tempfile}\`
set SIGF = \`nawk '{print \$3}' \${tempfile}\`
rm -f \${tempfile} >& /dev/null
#
# get last four HL coefficients
if("\$HL" == "") then
#    nawk '/^COL/ && \$3=="A"{print \$2}' \${tempfile}mtzdump |\\
#    tail -4 |\\
#    nawk '/HLA/{tag="HLA"} /HLB/{tag="HLB"} \\
#         /HLC/{tag="HLC"} /HLD/{tag="HLD"} \\
#	  {print tag "=" \$1}' |\\
#    cat >! \${tempfile}
    nawk '/^COL/ && \$3=="A"{print \$2}' \${tempfile}mtzdump |\\
    tail -4 |\\
    nawk 'NR==1{tag="HLA"} NR==2{tag="HLB"} \\
          NR==3{tag="HLC"} NR==4{tag="HLD"} \\
	  {print tag "=" \$1}' |\\
    cat >! \${tempfile}
    
    set HL = \`cat \${tempfile}\`
    if(\$#HL != 4) then
	echo "WARNING: could not find HL coefficients in \$mtzfile! "
	set HL = ""
    endif
    rm -f \${tempfile} >& /dev/null
endif
#
# check for free-R flags
set temp = \`nawk '/^COL/ && \$3=="I" && \$2=="FreeR_flag" {print \$2}' \${tempfile}mtzdump\`
if("\$temp" == "") then
    # more dangerous, but probably okay
    set temp = \`nawk '/^COL/ && \$3=="I" {print \$2}' \${tempfile}mtzdump\`
endif
if("\$temp" == "") then
    echo "WARNING: could not find FreeR_flag in \$mtzfile "
    echo "         Rfree will not be used! "
    echo "         please use "\\"FreeR_flag\\"" as a label for them. "
    echo "         believe me, you'll be glad you did."
    set FREE = ""
else
    set FREE = "FREE=\$temp"
endif
#
rm -f \${tempfile}mtzdump >& /dev/null
rm -f \${tempfile}mtzstuff.awk >& /dev/null
#
#
#
#######################################################################################
#
#   Examine the PDB
#
# first, run the PDB through a cannonizing filter
cat \$pdbin |\\
 nawk -f \${tempfile}reformatpdb.awk |\\
 nawk '! /^ATOM/ || /^ATOM/ && substr(\$0,14,1) !~ /[1-9H]/' |\\
 cat >! \${tempfile}fixcell.pdb

pdbset XYZIN \${tempfile}fixcell.pdb XYZOUT \$newpdbname << EOF-fixcell >& /dev/null
CELL \$CELL
EOF-fixcell

rm -f \${tempfile}fixcell.pdb

# decide if we can refine individual Bs
set B_REFINE = "ISOTROPIC"
set ATOMs = \`nawk '/^ATOM/' \$pdbin | wc -l\`
if( \$HKLs < ( 4 * \$ATOMs ) ) set B_REFINE = "OVERALL"
#
# check the unit cell too
echo "MTZ \$CELL" |\\
nawk '{printf "MTZ %8.3f %8.3f %6.1f %6.1f %6.1f %6.1f\\n", \$2, \$3, \$4, \$5, \$6, \$7}' |\\
cat >! \${tempfile}cell
nawk '/^CRYST/' \$pdbin |\\
nawk '{printf "PDB %8.3f %8.3f %6.1f %6.1f %6.1f %6.1f\\n", \$2, \$3, \$4, \$5, \$6, \$7}' |\\
cat >> \${tempfile}cell

cat \${tempfile}cell |\\
nawk 'NR==1{for(i=2;i<=NF;++i){c[i]=\$i;}}\\
  NR==2{for(i=2;i<=NF;++i){d=sqrt((\$i-c[i])^2); if(maxd! \${tempfile}
set temp = \`head -1 \${tempfile}\`
if("\$temp" == "") set temp = 0
rm -f \${tempfile}
    
if(\$temp > 3) then
    echo "WARNING: unit cells"
    cat \${tempfile}cell
    echo "are kind of different! "
endif
rm -f \${tempfile}cell

#
# get chains from PDB
cat \$newpdbname |\\
nawk '/^ATOM/{c=substr(\$0, 22, 1); if(c==" ")c="_"; print c}' |\\
nawk '\$1 != c{++n; print "CHNNAM ID", \$1, "CHNTYP", n; c=\$1}' |\\
cat >! \${tempfile}chnnam
set chains = \`nawk '{print \$3}' \${tempfile}chnnam\`

# determine chain ends
echo -n "" >! \${tempfile}chntyp
foreach chain ( \$chains )

    # get the exact chain number we're going to tell protin
    set i = \`nawk -v chain="\$chain" '\$3==chain{print \$NF}' \${tempfile}chnnam | head -1\`
    
    # "_" represents no chain ID
    if("\$chain" == "_") set chain = " "
    
    # extract the chain, for ease of use
    cat \$newpdbname |\\
    nawk -v chain="\$chain" '/^ATOM/ && substr(\$0, 22, 1)==chain' |\\
    cat >! \${tempfile}chain_\$chain
    
    # detect non-protein chains
    set temp = \`nawk 'substr(\$0, 13, 3) == " CA"' \${tempfile}chain_\$chain | head -1\`
    if("\$temp" == "") then
	# no alpha carbons, so must be a non-protein chain
	set CHNTYP = "NON"
	
	# see if this is a water chain
	set temp = \`nawk 'substr(\$0, 13, 2) != " O"' \${tempfile}chain_\$chain | head -1\`
	if("\$temp" == "") then
	    set CHNTYP = "WAT"
	    # use last water chain as the ARP chain
	    set ARPCHAIN = \$chain
	endif
	
	echo "CHNTYP \$i \$CHNTYP" >> \${tempfile}chntyp
	
	# skip to next chain
	rm -f \${tempfile}chain_\$chain
	continue
    endif
    
    # get terminal residues
    cat \${tempfile}chain_\$chain |\\
    nawk '{print substr(\$0, 23, 5), substr(\$0, 18, 3)}'  |\\
    cat >! \${tempfile}
    set Nter = \`head -1 \${tempfile}\`
    set Cter = \`tail -1 \${tempfile}\`
    
    # get capping groups: 5=acetyl, 4=formyl, 3=amino, 2=carboxyl
    cat \${tempfile}chain_\$chain |\\
    nawk '{Atom=substr(\$0, 13, 4);\\
    if(Atom == " CT1"){print "5"};\\
    if(Atom == " CT "){print "4"};\\
    if(Atom == " N  "){print "3"};\\
    }' >! \${tempfile}
    set Ncap = \`head -1 \${tempfile}\`
    rm -f \${tempfile}
    # default to amino terminus
    if("\$Ncap" == "") set Ncap = "3"
    
    # COOH will never hurt
    set Ccap = "2"
    
    # send this keycard to the file
    echo "CHNTYP \$i NTERM \$Nter \$Ncap CTERM \$Cter \$Ccap" >> \${tempfile}chntyp
    
    
    
    
    ############################################
    # detect secondary structure
    cat \${tempfile}chain_\$chain |\\
    nawk -f \${tempfile}phipsi.awk |\\
    cat >! \${tempfile}phipsi
    
    
    # initialize temp file
    echo -n "" >! \${tempfile}seco
    
    # alpha helix
    cat \${tempfile}phipsi |\\
    nawk -v phi=-64 -v psi=-40 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 15-degree error cutoff
    nawk '\$NF < 15' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco
    
    
    
    # parallel beta sheet
    cat \${tempfile}phipsi |\\
    nawk -v phi=-119 -v psi=113 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco

    
    
    
    # antiparallel beta sheet
    cat \${tempfile}phipsi |\\
    nawk -v phi=-139 -v psi=135.0 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # 3-10 HELIX (3.0/10)
    cat \${tempfile}phipsi |\\
    nawk -v phi=-75.5 -v psi=-4.5 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # PI HELIX (4.4/16)
    cat \${tempfile}phipsi |\\
    nawk -v phi=-57.1 -v psi=-69.7 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # COLLAGEN-TYPE HELIX
    cat \${tempfile}phipsi |\\
    nawk -v phi=-64.0 -v psi=145.0 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # CLASSIC BETA-BULGE 1
    cat \${tempfile}phipsi |\\
    nawk -v phi=-95.0 -v psi=-65.0 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # CLASSIC BETA-BULGE 2
    cat \${tempfile}phipsi |\\
    nawk -v phi=-130.0 -v psi=150.0 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # BETA-BEND I (1-4)  2
    cat \${tempfile}phipsi |\\
    nawk -v phi=-70.0 -v psi=-30.0 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    #BETA-BEND I (1-4)  3
    cat \${tempfile}phipsi |\\
    nawk -v phi=-90 -v psi=10 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # BETA-BEND II (1-4) 2
    cat \${tempfile}phipsi |\\
    nawk -v phi=-60 -v psi=130 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # BETA-BEND II (1-4) 3
    cat \${tempfile}phipsi |\\
    nawk -v phi=80 -v psi=0 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # GAMMA-TURN (1-3) 1
    cat \${tempfile}phipsi |\\
    nawk -v phi=172.0 -v psi=128.0 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # GAMMA-TURN (1-3) 2
    cat \${tempfile}phipsi |\\
    nawk -v phi=68.0 -v psi=-61 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco




    # GAMMA-TURN (1-3) 3
    cat \${tempfile}phipsi |\\
    nawk -v phi=-131 -v psi=162 'NF>6{++n; num[n]=\$3; \\
      dev[n]=sqrt(((\$5-phi+3780)%360-180)^2) + sqrt(((\$7-psi+3780)%360-180)^2)}\\
      END{dev[0]=dev[-1]=dev[-2]=dev[1];dev[n+3]=dev[n+2]=dev[n+1]=dev[n];\\
    for(i=1;i<=n;++i){smooth[i]=(dev[i-2]+dev[i-1]+dev[i]+dev[i+1]+dev[i+2])/5};\\
    for(i=1;i<=n;++i){print num[i], dev[i], smooth[i]}}' |\\
    cat >! \${tempfile}scores
    
    # choose 30-degree error cutoff
    nawk '\$NF < 30' \${tempfile}scores |\\
    nawk '\$1 != nextN{if(nextN!="")printf "%d ", nextN-1; printf "%d ", \$1} \\
       {nextN=\$1+1} END{print nextN-1}' |\\
    nawk -v chnum=\$i '{for(i=1;i 1' >> \${tempfile}seco

    
    
    # only do top 50 secondary structure constraints
    cat \${tempfile}seco |\\
    nawk '{printf "%4d %s\\n", \$5-\$4, \$0}' |\\
    sort -n -k1,2 |\\
    head -50 |\\
    nawk '{print substr(\$0, 6)}' |\\
    sort -k2n,3 -k4n,5 >! \${tempfile}
    mv \${tempfile} \${tempfile}seco
    
    # cis-peptide bonds
    cat \${tempfile}phipsi |\\
    nawk -v pep=180.0 'NF>6{++n; num[n]=\$3; \\
      dev=sqrt(((\$9-pep+3780)%360-180)^2);\\
      print \$3, \$9, dev}' |\\
    cat >! \${tempfile}scores
    
    # choose 120-degree error cutoff
    nawk '\$NF > 120{print \$1}' \${tempfile}scores |\\
    sort -un |\\
    nawk '{printf "%d ", \$1}' |\\
    nawk -v chnum=\$i '{\\
    print "CHNTYP",chnum, "CISPEP", NF,"   " \$0, "    # cis-peptide bonds"}' |\\
    cat >> \${tempfile}seco
    
    
    
    # intrachain disulphides?
    cat \${tempfile}chain_\$chain |\\
    nawk 'substr(\$0, 13, 3)==" SG" && substr(\$0, 18, 3)=="CYS"{\\
    print substr(\$0, 23, 4), substr(\$0, 31, 8), substr(\$0, 39, 8), substr(\$0, 47, 8)}' |\\
    nawk '{++n; res[n]=\$1; X[n]=\$2; Y[n]=\$3; Z[n]=\$4; for(i=1;i=2{\\
    printf "CHNTYP %d DISU %2d %s    # disulphide bridges\\n", chnum, NF/2, \$0}' |\\
    cat >> \${tempfile}seco
    
    # now reorganize all this stuff and put it in the chntyp list
    sort -k2n,3 -k4n,5 \${tempfile}seco |\\
    awk '{print "#" \$0}' |\\
    cat >> \${tempfile}chntyp

    # clean up
    rm -f \${tempfile}chain_\$chain >& /dev/null
    rm -f \${tempfile}seco         >& /dev/null
    rm -f \${tempfile}scores       >& /dev/null
    rm -f \${tempfile}phipsi       >& /dev/null
end
#
# organize secondary-structure cards
#
# look for inerchain disulphides
cat \$newpdbname |\\
nawk 'substr(\$0, 13, 3)==" SG" && substr(\$0, 18, 3)=="CYS"{\\
c=substr(\$0, 22, 1); if(c==" ")c="_";\\
print c, substr(\$0, 23, 4), substr(\$0, 31, 8), substr(\$0, 39, 8), substr(\$0, 47, 8)}' |\\
nawk '{++n; c[n]=\$1; res[n]=\$2; X[n]=\$3; Y[n]=\$4; Z[n]=\$5; for(i=1;i> \${tempfile}chntyp


# make sure there's at least one water chain
grep "WAT" \${tempfile}chntyp >& /dev/null
if(\$status) then
    @ i = ( \$i + 1 )
    echo "CHNNAM ID \$ARPCHAIN CHNTYP \$i" >> \${tempfile}chnnam
    echo "CHNTYP \$i WAT" >> \${tempfile}chntyp
endif
#

# Rule-of-Thumb formula given in ARP manual
set ADDATOMS = \`grep ATOM \$newpdbname | wc -l | nawk -v hires=\$hires '{printf "%d", 0.08*\$1/(3*hires)}'\`
# other rule-of-thumb in ARP manual (remove half as much as you add)
set REMATOMS = \`echo "\$ADDATOMS" | nawk '{printf "%d", \$1/2}'\`


set temp = "with one, overall B factor "
if("\$B_REFINE" == "ISOTROPIC") set temp = "with individual B factors"
echo "refining \$ATOMs atoms in \$pdbin \$temp "
echo "against \$HKLs values of \${F}/\${SIGF} \$HL in \$mtzfile"
echo "protein layout:"
cat \${tempfile}chnnam


# clean up
rm -f \${tempfile}phipsi.awk >& /dev/null
rm -f \${tempfile}reformatpdb.awk >& /dev/null

goto Deploy_scripts
################################################################################
################################################################################
# END OF SETUP ROUTINES
################################################################################
################################################################################

Find_awk:
# make sure nawk works
set program = "nawk"
foreach name ( nawk awk gawk )
    test -x "\$program"
    if(! \$status) break
    
    set possibilities = \`which \$name |& grep -v ' not in ' | tail -1\`
    foreach file ( \$possibilities )
	test -x "\$file"
	if(! \$status) then
	    # test for desired functionality (change this?)
	    set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
	    if("\$temp" == 856) then
		set program = "\$file"
		break
	    endif
	endif
    end
    unset possibilities
end
test -x "\$program"
if(\$status) then
    set program = "awk"
    foreach place ( /bin /usr/bin /usr/local/bin  )
	test -x "\$program"
	if((\$status)&&(-e \$place)) then
	    # keep looking
	    set files = \`ls -1L \${place} |& grep "\$program" |& sort -k5nr |& head -20 \`
	    foreach file ( \$files )
		# test for desired functionality
		set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
		if("\$temp" == 856) then
		    set program = "\$file"
		    break
		endif
	    end
	endif
    end
endif

# agressively search for nawk in likely places
test -x "\$program"
if(\$status) then
    echo -n "Looking for \$program "
    foreach place ( /bin /usr/bin /usr/local/bin /usr / )
	test -x "\$program"
	if((\$status)&&(-e \$place)) then
	    if("\$place" == "/") echo -n "uhh"
	    
	    # use find to get candidate files
	    set files = \`find \$place -name '*'\$program \\( -type l -o \\( -type f -size +10000c \\) \\) -perm -1 -print |& egrep -v "^find:" |& head -20\`
	    foreach file ( \$files )
		# test for desired functionality
		set temp = \`echo "1.54" | \$file '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
		if("\$temp" == 856) then
		    set program = "\$file"
		    break
		endif
	    end
	endif
	
	# entertainment
	echo -n "."
    end
endif

# check that we found the right awk program
set temp = \`echo "1.54" | \$program '{printf("%3d", 3147.7 * ( \$1 )^(-3.014))}' |& cat\`
if("\$temp" == 856) then
    # set up this awk program as nawk
    set nawk = "\$program"
    alias nawk \$nawk
else
    echo "Dagnabbit!  We can't find a suitable awk program.  What kind of unix is this? "
    echo "Elves may not be able to work."
    set nawk = /bin/awk
    alias nawk awk
endif

goto Return_Find_awk

































Deploy_scripts:
# Create the REFMAC script
cat << EOF-refmacscript >! \$scriptname
#! /bin/csh -f
#
#	Automatically generated REFMAC script for:
#	 \$pdbin and \$mtzfile
#
###############################################################################
#   Set-up stuff
#
alias nawk \$nawk
#
set pdbin      = \$newpdbname
set pdbout     = ./pdb/refmac.pdb
set mtzfile    = \$mtzfile
set tempfile   = \\\${CCP4_SCR}/refmactemp
#
#
# scan command line
foreach arg ( \\\$* )
    if(\\\$arg =~ *.mtz) set mtzfile = \\\$arg
    if(\\\$arg =~ *.pdb) set pdbin = \\\$arg
    if(\\\$arg =~ *.brk) set pdbin = \\\$arg
    if(\\\$arg == nice)  renice -n 40 \\\$\\\$
end
#
# need these directories
if(! -e logs)    mkdir logs
if(! -e pdb)     mkdir pdb
if(! -e temp)    mkdir temp

# refmac version-spanning options
if("\$refmac" == "refmac5") then
    goto refmac
endif

protin:
###############################################################################
#
#   Run protin  to set up geometric restraints
#
\\\${CCP4_BIN}/protin \\
XYZIN      \\\$pdbin \\
DICTPROTN  \$dicfile 		\\
PROTOUT    \\\${tempfile}protout.dat		\\
PROTCOUNTS \\\${tempfile}counts.dat		\\
<< eof
# automatically determined chains
\`cat \${tempfile}chnnam\`
#capping groups: 5=acetyl, 4=formyl, 3=amino, 2=carboxyl
\`cat \${tempfile}chntyp\`

# NCS chains A,B,and C from residues 2-33, 40-77 code 2
# code 1 2 3 4 5 6 
# main t t t m m l
# side t m l m l l
#NONX 3 CHNID A B C NSPANS 2    2 33    2    40 77     2

# of atoms in peptide bond 5 -> Ca to Ca (default)
PEPP 5
SYMM \$SG
#VDWRadii 1 CA 7 3.8
# VDW cuttoff distance (5 default)
VDWCUT 5
END
eof
if(\\\$status) then
    exit 2
endif

refmac:
###############################################################################
#
# Refmac step. Refine
#
\$refmac \\
HKLIN      \\\$mtzfile \\
HKLOUT     ./refmacout.mtz \\
PROTOUT    \\\${tempfile}protout.dat \\
PROTCOUNTS \\\${tempfile}counts.dat \\
PROTSCR    \\\${tempfile}counts.scr \\
XYZIN      \\\$pdbin \\
XYZOUT     \\\${tempfile}refmacout.pdb \\
<< END-OF-REFMAC 
LABIN FP=\$F SIGFP=\$SIGF  \$FREE  \$HL
LABO FC=FC PHIC=PHIC    FWT=2FOFCWT PHWT=PH2FOFCWT -
                     DELFWT=FOFCWT  PHDELWT=PHFOFCWT
# RESTRAINED, RIGID, or IDEAL (geometry only)
REFI TYPE RESTrained 
# default: refine agains full resolution range
#REFI RESOLUTION  \$lores \$hires
# use maximum-likelihood, conjugate-direction refinement (with phases)
REFI RESIDUAL MLKF METHOD CGMAT PHASED
# One, overall B (OVERALL) or individual Bs (ISOTROPIC)
REFI BREF \$B_REFINE

#weight of X-ray over geometry (default: WEIG EXPE MATR 0.5)
#WEIG EXPE MATR 0.5
# No torsional restraints (combine with low WEIG ? )
#TORSION 0.0
# Bfactor restraints weight
#BFAC 1.0
# NCS restraints weight
#NCSR 1.0

#Blur the phases?
#PHASE SCBL 1 BBLUR 0
# combine experimental phases with calculated ones in output maps
REFI PHASE SIGMAcalc

# Fo-Fc SCALING 
#Scale Fc to Fo with 2-Gaussian fit (TYPE SIMPLE is 1-Gaussian)
SCALE TYPE BULK 
# use an anisotropic, overall B factor (for anisotropic diffraction)
SCALE LSSC ANIS 
# low-res cutoff for scaling (intended for SCALE TYPE SIMPLE)
#SCALE RESO 4.5 \$hires

# fix water/protein density ratio to 1/1.35 and water B=80 in scaling
#SCALE LSSC FIXBULK SCBULK -0.74 BBULK 80
# same for SigmaA estimation (NOT recommended)
#SCALE MLSC FIXBULK SCBULK -0.5  BBULK 100

# use free-R hkls in scaling (ignored by default)
#SCALE LSSC FREE
# use experimental sigmas in scaling (ignored by default)
#SCALE LSSC EXPE


# Actual number of REFMAC refinement steps per cycle (5 default)
NCYC 5


# verboseness
MONI FEW
#MONI MEDI HBOND
#MONI MEDI CHIRAL 0.5
#MONI MANY
# 20 display bins by default
#BINS 20
end
END-OF-REFMAC
#
# update the output file
mv \\\${tempfile}refmacout.pdb \\\$pdbout
#
# Clean up
rm -f \\\${tempfile}protout.dat
rm -f \\\${tempfile}counts.dat
rm -f \\\${tempfile}counts.scr
#
exit


EOF-refmacscript
chmod a+x \$scriptname

rm -f \${tempfile}chnnam >& /dev/null
rm -f \${tempfile}chntyp >& /dev/null















# now unwrap the arp script
cat << EOF-arpscript >! \$arpscriptname
#! /bin/csh -f
#
#	\$arpscriptname 	- intelligent arp script
#
#
#	this script adapts to most of arp's quirks
#	
#
alias nawk \$nawk

set map_2fofc  = maps/2fofc_free.map
set map_fofc   = maps/fofc.map
set pdbin      = \$newpdbname	# to add water to
set pdbout     = ./pdb/arp.pdb		# new file with water added

set tempfile   = \\\${CCP4_SCR}arptemp

# user can override defaults
foreach arg ( \\\$* )
    if("\\\$arg" =~ *.mtz) set refmacmtz = "\\\$arg"
    if("\\\$arg" =~ *.pdb) set pdbin     = "\\\$arg"
    if("\\\$arg" =~ *.map) then
	if("\\\$arg" =~ *2*) then
	    set map_2fofc = "\\\$arg"
	else
	    set map_fofc  = "\\\$arg"
	endif
    endif
end

# need these directories
if(! -e logs)    mkdir logs
if(! -e pdb)     mkdir pdb

if((! -e "\\\$map_2fofc")||(! -e "\\\$map_fofc")) then
    echo "ERROR!  no maps: \\\$map_2fofc AND \\\$map_fofc needed to run arp."
    exit 9
endif

ARP:
###############################################################################
#
# get ARP's variable names from map file
#
echo "" | mapdump MAPIN \\\$map_2fofc |\\\\
grep "Cell dimensions ..." | tail -1 |\\\\
     nawk '{printf("%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f\\\\n", \\\\
              \\\$(NF-5), \\\$(NF-4), \\\$(NF-3), \\\$(NF-2), \\\$(NF-1), \\\$NF)}' |\\\\
cat >! \\\${tempfile}cell.txt
set CELL = \\\`cat \\\${tempfile}cell.txt\\\`
#rm -f \\\${tempfile}dump.txt
rm -f \\\${tempfile}cell.txt

# change the cell in the PDB so ARP won't freak out.
pdbset XYZIN \\\$pdbin XYZOUT \\\${tempfile}arpin.pdb << EOF-fixcell >& /dev/null
CELL \\\$CELL
EOF-fixcell


# change all occupancies to be < 1 (or ARP will die)
cat \\\${tempfile}arpin.pdb |\\\\
nawk '{if(substr(\\\$0,55,6)+0>1)\\\\
          {print substr(\\\$0,1,56) "1.00" substr(\\\$0,61)}\\\\
     else {print}}' |\\\\
cat >! \\\${tempfile}arptemp.pdb
mv \\\${tempfile}arptemp.pdb \\\${tempfile}arpin.pdb


arpagain:
# Now try to run ARP
\$arpp XYZIN \\\${tempfile}arpin.pdb \\\\
 MAPIN1 \\\$map_2fofc \\\\
 MAPIN2 \\\$map_fofc  \\\\
 XYZOUT \\\$pdbout << eof-arpp | tee \\\${tempfile}arp.log
MODE UPDATE WATERS
CELL \\\$CELL
SYMM \$SG
RESOLUTION \$lores \$hires
! Removal based on 2mFo-DFc map
# remove about 10 waters that are below 1sigma, and merge ones closer that 2.2 A
REMOVE     ATOMS \$REMATOMS CUTSIGMA 1.0 MERGE 2.2

! Addition based on mFo-DFc map
# add up to \$ADDATOMS atoms to chain \$ARPCHAIN, with automatic sigma cuttoff
FIND       ATOMS \$ADDATOMS CHAIN \$ARPCHAIN CUTSIGMA AUTO
# new atoms should be within 2.3 to 3.3 A of existing atoms, 
# but not closer than 2.3 A to another new atom (default).
#FDISTANCE  NEWOLD 2.3 3.3 NEWNEW 2.3

# do real-space refinement of waters
REFINE     WATERS
END
eof-arpp
if(\\\$status) goto ARPerror

# clean up after ARP
rm -f \\\${tempfile}arpin.pdb
rm -f \\\${tempfile}arpp_2fofc.map >& /dev/null
rm -f \\\${tempfile}arpp_fofc.map >& /dev/null

# get rid of bad water
mv \\\$pdbout \\\${tempfile}.pdb
nawk '{if(! ((substr(\\\$0,55,6)=="  0.00")&&(\\\$4=="WAT"))){print} }'\\\\
\\\${tempfile}.pdb >! \\\$pdbout
rm -f \\\${tempfile}.pdb


# sumarize for user
cat \\\${tempfile}arp.log |\\\\
nawk '/New atoms found/{print "arp found  ", \\\$2, "new waters"}'
cat \\\${tempfile}arp.log |\\\\
nawk '/Number of atoms will be removed/{print "and removed", \\\$NF, " waters"}'

echo "new pdb is in \\\$pdbout"
rm -f \\\${tempfile}arp.log
exit


ARPerror:

echo "ARP died! \\\\07 "
tail -10 \\\${tempfile}arp.log

# most common problem: ARPP won't swallow map 
if(! \\\$?FIXED) then
    set FIXED
    # fix this, and go again
    set xyzlim = \\\`nawk 'BEGIN{print "xyzlim"} /Map limits/{print \\\$(NF-1), \\\$NF}' \\\${tempfile}arp.log\\\`
    
    if(\\\$#xyzlim == 7) then
	echo "fixed error: \\\$xyzlim"
	echo "please edit \$fftscriptname and change:"
	grep xyzlim \$fftscriptname | head -1
	echo "to"
	echo "set xyzlim = "\\"\\\$xyzlim\\"
	echo "to make this script run a bit faster"
	echo "extending the maps."
	goto extend
    endif
    
    echo "don't know why that happened! "
endif

echo "Stopping. "
echo ""
rm -f \\\${tempfile}arp.log

exit 8

extend:
mapmask MAPIN \\\$map_2fofc MAPOUT \\\${tempfile}arpp_2fofc.map << EOF
\\\$xyzlim
END
EOF
set map_2fofc = \\\${tempfile}arpp_2fofc.map
mapmask MAPIN \\\$map_fofc MAPOUT \\\${tempfile}arpp_fofc.map << EOF 
\\\$xyzlim
END
EOF
set map_fofc = \\\${tempfile}arpp_fofc.map

goto arpagain

EOF-arpscript
chmod a+x \$arpscriptname

























# now unwrap fft script
cat << EOF-fftscript >! \$fftscriptname
#! /bin/csh -f
#
#	\$fftscriptname 	- make refmac's maps
#
#
#	use this script to get the "current" map out of
#	refmacout.mtz, even if refmac is still running
#
alias nawk \$nawk

set refmacmtz  = ./refmacout.mtz
set pdbin      = \$newpdbname	# PDB to "cover"
set xyzlim     = "\$xyzlim"			# important for ARP maps

# need this to make O maps
set MAPMAN = \$MAPMAN

set tempfile   = \\\${CCP4_SCR}ffttemp

# user override defaults
foreach arg ( \\\$* )
    if("\\\$arg" =~ *.mtz) set refmacmtz = "\\\$arg"
    if("\\\$arg" =~ *.pdb) set pdbin     = "\\\$arg"
    if("\\\$arg" =~ *mapman*) set MAPMAN     = "\\\$arg"
end

if(! -e "\\\$refmacmtz") then
    echo "ERROR: no \\\$refmacmtz ! "
    exit 9
endif

FFT:
###############################################################################
#
# make maps.
#
#  Sigmaa style 2mfo-dfc map with FREE R removed (for ARP)
#
echo "making arp's maps/2fofc_free.map"
fft hklin ./refmacout.mtz mapout \\\${tempfile}.map <& /dev/null
mapmask MAPIN \\\${tempfile}.map MAPOUT maps/2fofc_free.map << EOF
\\\$xyzlim
END
EOF
#
#
#  Sigmaa style 2mfo-dfc map _without_ FREE R removed (for O)
#
echo "making maps/2fofc.map"
fft hklin \\\$refmacmtz mapout maps/2fofc.map <& /dev/null
###############################################################################
pick_peaks:
# list difference peaks
echo "picking peaks in maps/fofc.map"
peakmax MAPIN maps/fofc.map XYZOUT \\\${tempfile}pick.pdb << eof-pick 
THRESHOLD RMS 4 NEGATIVES
OUTPUT BROOKHAVEN
END
eof-pick

# convert to an O macro
cat \\\${tempfile}pick.pdb |\\\\
nawk '/^ATOM/{print substr(\\\$0, 61, 6)+0, substr(\\\$0, 31, 8), substr(\\\$0, 39, 8), substr(\\\$0, 47, 8)}' |\\\\
sort -nr |\\\\
nawk '{print "! ", \\\$1, "sigma peak"; print "centre_xyz", \\\$2,\\\$3,\\\$4; \\\\
print "sym_sphere ; ; ;";print "@map";}' |\\\\
cat >! \\\${tempfile}peaklist
rm -f \\\${tempfile}pick.pdb >& /dev/null

if(\\\$?NO_MACROS) goto done
# make some nice O macros for visiting large difference features
echo "generating o macros in ./o/"
cat \\\${tempfile}peaklist >! ./o/visit_peaks.omac

set temp = \\\`awk '/^ATOM/{++n;X+=substr(\\\$0, 31, 8);Y+=substr(\\\$0, 39, 8);Z+=substr(\\\$0, 47, 8)} END{if(n) print "cen_x", X/n, Y/n, Z/n}' \\\$pdbin\\\`
cat << EOF-latest >! ./o/latest.omac
sam_atom_in \\\`pwd\\\`/\\\$pdbin latest
mol latest
obj latest
zone ;
end
\\\$temp

paint_ramp atom_b ; blue red
obj Bfac
zone ;
end

sym_set ; ; \$SG ; 
sym_cell

menu @visit_peaks.omac on
menu @map on
EOF-latest

if(! -e ./o/map) then
    cat << EOF-map >! ./o/map
map_cache
map_active_centre
map_file \\\`pwd\\\`/o/2fofc.omap
map_object sigmaa
map_parameter 15 15 15 1 tan 0.5 0 1
map_draw

map_cache
map_active_centre
map_file \\\`pwd\\\`/o/fofc.omap
map_object good
map_parameter 15 15 15 3 green 0.5 0 1
map_draw

map_cache
map_active_centre
map_file \\\`pwd\\\`/o/fofc.omap
map_object bad
map_parameter 15 15 15 -3 red 0.5 0 1
map_draw

EOF-map
endif

done:
# list the difference peaks
cat \\\${tempfile}peaklist |\\\\
nawk '/sigma/{printf "%s | ", \\\$0} /cen/{print}'
rm -f \\\${tempfile}peaklist >& /dev/null
echo "maps ready."
exit

EOF-fftscript
chmod a+x \$fftscriptname













# unwrap the auto-converge script
cat << EOF-arpscript >! \$convergescript
#! /bin/csh -f
#
#	Auto-convergeing refmac/arp engine
#
alias nawk \$nawk

set pdbin      = \$newpdbname
set mtzfile    = \$mtzfile

setenv CCP4_SCR   ./temp
set tempfile   = \\\${CCP4_SCR}/refmactemp
#
set refmacscript = ./scripts/refmac.com
set arpscript    = ./scripts/arp.com
set fftscript    = \$fftscriptname
set rmsdscript   = ./scripts/rmsd
#
# scan command line
foreach arg ( \\\$* )
    if(\\\$arg =~ *.mtz) set mtzfile = \\\$arg
    if(\\\$arg =~ *.pdb) set pdbin = \\\$arg
    if(\\\$arg =~ *.brk) set pdbin = \\\$arg
    if((\\\$arg =~ [1-9]*)&&(\\\$arg =~ *[0-9])) set cycle = \\\$arg
    if(\\\$arg == "noarp") set NO_ARP
    if(\\\$arg == nice)  renice -n 40 \\\$\\\$
end
#
# Cycle Numbers for running arp, or quitting 
set cycle     = 0
# number of refmac cycles to run between saving pdb
set savecycle = 10
# FFT will run every "fftcycle" refmac cycles (regardless of convergence)
set fftcycle  = 10
# ARP will run every "arpcycle" refmac cycles (regardless of convergence)
set arpcycle  = 1000
# this script will quit after "maxcycle" \$refmac cycles
set maxcycle  = 1000

# get cycle number from input PDB filename
set temp = \\\`echo \\\$pdbin | nawk '{for(i=1;i! logs/refmac\\\${cycle}.log
if(\\\$status) goto done
set pad_cycle = \\\`echo "\\\$cycle \\\$maxcycle" | nawk '{printf "%0"length(\\\$2)"d", \\\$1}'\\\`
mv pdb/refmac.pdb pdb/refmacin.pdb
if((\\\$cycle % \\\$savecycle) == 0) cp pdb/refmacin.pdb pdb/refmac\\\${pad_cycle}.pdb
#
# evaluate change in the model (rmsCA, rmsXYZ, rmsB, maxXYZ, maxB)
set temp = \\\`./\\\$rmsdscript xlog=on \\\$pdbin pdb/refmac\\\${pad_cycle}.pdb \\\`
if(\\\$#temp > 4) then
    set RMSxyz = "\\\$temp[2]"
    set RMSDB  = "\\\$temp[3]"
else
    echo "\\\$0: unable to determine model shifts! "
endif

# prepare for next cycle
set pdbin = pdb/refmacin.pdb

# check for maximum cycle reached
if(\\\$cycle > \\\$maxcycle) goto done

# if refinement is getting nowhere, go to ARP
if("\\\$RMSxyz" =~ 0.000*) set RUN_ARP
#if("\\\$RMSDB" =~ 0.0*) set RUN_ARP
#if(("\\\$RMSDB" =~ 0.0*)&&("\\\$RMSxyz" =~ 0.000*)) set RUN_ARP

if(\\\$?RUN_ARP) then
    echo "refmac converged! "
endif

# check cycle counts
if((\\\$cycle % \\\$arpcycle) == 0) set RUN_ARP
if((\\\$cycle % \\\$fftcycle) == 0) goto FFT

if(\\\$?RUN_ARP) then
    goto FFT
endif

# repeat cycles of refinement
@ cycle = ( \\\$cycle + 1 )

goto REFMAC




FFT:
###############################################################################
#
# make maps.
#
# defaults to ./maps/2fofc.map ./maps/fofc.map and ./maps/2fofc_free.map 
# plus ./o/2fofc.omap and ./o/fofc.omap 
#
echo "calculating maps"
./\\\$fftscript \\\$pdbin >! ./logs/fft.log
if(\\\$status) goto done

if(\\\$?RUN_ARP) then
    unset RUN_ARP
    goto ARP
endif

# if we get here, this was just an fft cycle

# repeat cycles of refinement
@ cycle = ( \\\$cycle + 1 )

goto REFMAC



ARP:
if(\\\$?NO_ARP) goto done
###############################################################################
#
#   use ARP to add and remove waters
#
echo "running arp"
./\\\$arpscript ./maps/2fofc_free.map ./maps/fofc.map \\\$pdbin >! logs/arpp\\\${cycle}.log
if(\\\$status) goto done
mv ./pdb/arp.pdb pdb/arpp\\\${cycle}.pdb

tail -3 logs/arpp\\\${cycle}.log | head -2

# handle convergence loop
set pdbin = pdb/arpp\\\${cycle}.pdb

@ cycle = ( \\\$cycle + 1 )

# edit maps.com if arp complains?

goto REFMAC


done:
###############################################################################
#
#   exiting message
#

echo "REFMAC/ARP stopped!  \\\\07 "
echo ""

exit

EOF-arpscript
chmod a+x \$convergescript




















# now unwrap rmsd awk script
cat << EOF-RMSDSCRIPT >! \$RMSD
#! \$nawk -f
#
#   Calculate RMSD of atoms with the same name in two PDB files
#
#	The PDB feild:
#           |<--- here -->|
#ATOM      1  N   ALA A 327      40.574  34.523  43.012  1.00 34.04
#
#	is used to determine if two atoms are a "pair"
#
BEGIN {
if(! atom) atom = "CA"
maxXYZ = maxdB = 0
max_atom_XYZ = max_atom_dB = 0
maxXYZ_ID = maxdB_ID = "-"
max_atom_XYZ_ID = max_atom_dB_ID = "-"
}

/^ATOM/{
    # read in values (watching for duplications)
    ID = substr(\\\$0,12,15)
    ++count[ID]

    if(count[ID] == 1)
    {
	# not initialized yet
	X[ID] = substr(\\\$0, 31, 8)+0
	Y[ID] = substr(\\\$0, 39, 8)+0
	Z[ID] = substr(\\\$0, 47, 8)+0
	B[ID] = substr(\\\$0, 61, 6)+0
    }
    
    if(count[ID] == 2)
    {
	++pairs
    
	# seen this before, subtract values
	dX     = X[ID] - substr(\\\$0, 31, 8)
	dY     = Y[ID] - substr(\\\$0, 39, 8)
	dZ     = Z[ID] - substr(\\\$0, 47, 8)
	dB[ID] = B[ID] - substr(\\\$0, 61, 6)
	
	# get drift (and add up squares of drifts)
	sqrD   = dX*dX + dY*dY + dZ*dZ
	dXYZ[ID] = sqrt(sqrD)

	# remember maximum shifts
	if(dXYZ[ID] > maxXYZ) {maxXYZ  = dXYZ[ID]; maxXYZ_ID = ID }
	if(dB[ID]*dB[ID] > maxdB*maxdB) {maxdB = dB[ID]; maxdB_ID = ID }

	# maintain mean-square sums	
	sumXYZ += sqrD
	sumB   += dB[ID]*dB[ID]

	# separate stats for special atom type
	if(ID ~ atom)
	{
	    ++atom_pairs

	    # maintain separate mean-square sums
	    sum_atom_XYZ += sqrD
	    sum_atom_B   += dB[ID]*dB[ID]
	    
	    # remember maximum drifts too
	    if(dXYZ[ID] > max_atom_XYZ) {max_atom_XYZ  = dXYZ[ID]; max_atom_XYZ_ID = ID }
	    if(dB[ID]*dB[ID] > max_atom_dB*max_atom_dB) {max_atom_dB = dB[ID]; max_atom_dB_ID = ID }	    
	}
	# debug output
	if(debug)
	{
	    printf("%s moved %8.4f (XYZ) %6.2f (B)\\\\n", ID, dXYZ[ID], dB[ID])
	}	
    }

    if(count[ID] > 2)
    {
	print "WARNING: " ID " appeared more than twice! "
    }
}


END{
    
    if((pairs+0 == 0)&&(! xlog)) 
    {
	print "no atom pairs found"
	exit
    }
    rmsXYZ = sqrt(sumXYZ/pairs)
    rmsB = sqrt(sumB/pairs)
    if(atom_pairs+0 != 0)
    {
	rms_atom_XYZ = sqrt(sum_atom_XYZ/atom_pairs)
	rms_atom_B = sqrt(sum_atom_B/atom_pairs)
    }
    

    if(! xlog) 
    {
	print pairs " atom pairs found"
	print "RMSD("atom" )= " rms_atom_XYZ " ("atom_pairs, atom " pairs)"
	print "RMSD(all)= " rmsXYZ " ("pairs" atom pairs)"
	print "RMSD(Bfac)= " rmsB

	print "MAXD(all)= " maxXYZ "\\\\tfor " maxXYZ_ID
	print "MAXD(Bfac)= " maxdB "\\\\tfor " maxdB_ID
	
	# final check for orphan atoms 
	for(id in count)
	{
	    if(count[id]<2) print "WARNING: " id " only found once"
	}
    }
    else
    {
	printf "%10.8f %10.8f %10.5f %10.8f %8.2f \\\\n", rms_atom_XYZ, rmsXYZ, rmsB, maxXYZ, maxdB
    }
}

EOF-RMSDSCRIPT
chmod a+x \$RMSD

















# unwrap analysis scripts
cat << EOF-Rplot >! ./scripts/Rplot.com
#! /bin/csh -f
#
#   Plot R-factors from a REFMAC log in xloggraph format
#
#
alias nawk $nawk
if(\\\`uname\\\` == Linux) alias nawk awk
if(! \\\$?CBIN) set CBIN = "/programs/ccp4/bin"

set logs
set sort = rt
foreach arg ( \\\$* )
    if(\\\$arg =~ paste*) then
	set sort = ""
    endif
end
echo ""
ls -1\\\$sort \\\$*
set i = 1
echo ""
echo "
Stats"
echo 'For inline graphs use a Java browser'
echo "
" EOF-Rplot chmod a+x ./scripts/Rplot.com cat << EOF-Drift >! ./scripts/Drift.com #! /bin/csh -f # # Plot "drift" of a series of PDB files, relative to each other # #goto skip set nawk = \$nawk \\\$nawk 'BEGIN{exit}' >& /dev/null if(\\\$status) set nawk = \\\`which awk\\\` alias nawk \\\$nawk if(! \\\$?CBIN) set CBIN = "/programs/ccp4/bin" set refcycles = 10 set rmsd = ./scripts/rmsd if(\\\$#argv == 1) then endif plot: echo "
Steps"
echo 'For inline graphs use a Java browser'

skip:
# differences from first file in list
set ref = \\\`ls -1rt \\\$* | head -1\\\`

echo 'Diffs from '\\\$ref':'
echo 'For inline graphs use a Java browser'


# diffs from LAST pdb in the list

set ref = \\\`ls -1rt \\\$* | tail -1\\\`

echo 'Diffs from '\\\$ref':'
echo 'For inline graphs use a Java browser'

if(-e ./rmsd\\\$\\\$) rm -f ./rmsd\\\$\\\$
echo "
" exit EOF-Drift chmod a+x ./scripts/Drift.com echo "created suitable refmac script as \$scriptname" echo "created suitable fft script as \$fftscriptname" echo "created suitable arp script as \$arpscriptname" echo "\$RMSD can be used to get the rmsd between two pdbs" echo "./scripts/Drift.com will plot the drift of a series of pdbs" echo "./scripts/Rplot.com will plot the R-factors of refmac logs" echo "\$convergescript will iteratively run all the above scripts" exit Unwrap_awk_Scripts: cat << EOF-mtzstuff >! \${tempfile}mtzstuff.awk #! \$nawk -f # # # Organize info from an mtzdump in more accessible format # # # # resolution limits /Resolution Range/ { getline; getline; hires = \\\$6; lores = \\\$4; } # cell /Cell Dimensions/ { getline; getline; cell = \\\$0 } # space group /Space group/{ gsub("\\\\047",""); SG = \\\$5 } /Column Labels/{ getline; getline; while(NF>0) { for(i=1;i<=NF;++i) { ++labels; label[labels] = \\\$i } getline } } /Column Types/{ getline; getline; while(NF>0) { for(i=1;i<=NF;++i) { ++t; type[t] = \\\$i } getline } } /OVERALL FILE STATISTICS/,/LIST OF REFLECTIONS/{ for(l in label) { if(\\\$NF == label[l]) { # retrieve interesting numbers from the summary list mean[l] = \\\$(NF-4)+0 completeness[l] = substr(\\\$0, 32)+0 } } } END { # now print everything out print "CELL", cell print "SYMM", SG print "RESO", lores, hires for(l=1;l<=labels;++l) { printf "COL %-15s %s %6.2f %6.2f%%\\\\n", label[l], type[l], mean[l], completeness[l] } # now try to equate Fs and DANOs with their sigmas for(l=1;l<=labels;++l) { # structure factors if(type[l]=="F") { ++fs; F[fs]=label[l]; meanF[F[fs]]=mean[l]; last = F[fs]; } # anomalous differences (in F units) if(type[l]=="D") { ++ds; D[ds]=label[l]; meanD[D[ds]]=mean[l]; last = D[ds]; } # sigmas (of anything) if(type[l]=="Q") { ++ss; Q[ss]=label[l]; meanQ[Q[ss]]=mean[l]; # putatively assign sigmas to most recent F (almost always right) sigma[last]=Q[ss]; } } # now go see if any sigmas have nearly identical names with an F or DANO for(s=1;s<=ss;++s) { # run down all Fs for(f=1;f<=fs;++f) { # look for SIG(name) to match name if(Q[s] == "SIG" F[f]) { sigma[F[f]]=Q[s]; } } # same for DANOs for(d=1;d<=ds;++d) { if(Q[s] == "SIG" D[d]) { sigma[D[d]]=Q[s]; } } } # now print out putative pairs for(f=1;f<=fs;++f) { if(meanQ[sigma[F[f]]]!=0) { meanF[F[f]]=meanF[F[f]]/meanQ[sigma[F[f]]]; } else { meanF[F[f]]=""; } printf "F: %-10s %-10s %-10s\\\\n", F[f], sigma[F[f]], meanF[F[f]]; } for(d=1;d<=ds;++d) { if(meanQ[sigma[D[d]]]!=0) { meanD[D[d]]=meanD[D[d]]/meanQ[sigma[D[d]]]; } else { meanD[D[d]]=""; } printf "D: %-10s %-10s %-10s\\\\n", D[d], sigma[D[d]], meanD[D[d]]; } } EOF-mtzstuff chmod a+x \${tempfile}mtzstuff.awk cat << EOF-reformatpdb >! \${tempfile}reformatpdb.awk #! \$nawk -f # # # Re-writes PDB into something more canonnical # BEGIN { # memorize ordering of the alphabet alphabet[1]="A"; alphabet[2]="B"; alphabet[3]="C"; alphabet[4]="D"; alphabet[5]="E"; alphabet[6]="F"; alphabet[7]="G"; alphabet[8]="H"; alphabet[9]="I"; alphabet[10]="J"; alphabet[11]="K"; alphabet[12]="L"; alphabet[13]="M"; alphabet[14]="N"; alphabet[15]="O"; alphabet[16]="P"; alphabet[17]="Q"; alphabet[18]="R"; alphabet[19]="S"; alphabet[20]="T"; alphabet[21]="U"; alphabet[22]="V"; alphabet[23]="W"; alphabet[24]="X"; alphabet[25]="Y"; alphabet[26]="Z" alphabet["A"]=1; alphabet["B"]=2; alphabet["C"]=3; alphabet["D"]=4; alphabet["E"]=5; alphabet["F"]=6; alphabet["G"]=7; alphabet["H"]=8; alphabet["I"]=9; alphabet["J"]=10; alphabet["K"]=11; alphabet["L"]=12; alphabet["M"]=13; alphabet["N"]=14; alphabet["O"]=15; alphabet["P"]=16; alphabet["Q"]=17; alphabet["R"]=18; alphabet["S"]=19; alphabet["T"]=20; alphabet["U"]=21; alphabet["V"]=22; alphabet["W"]=23; alphabet["X"]=24; alphabet["Y"]=25; alphabet["Z"]=26 alphabet[0]=" "; alphabet[" "]=0; # canonical ordering of atom types in PDB align[1] = "N" ; align[2] = "A " ; align[3] = "C" ; align[4] = "O" ; align[5] = "B " ; align[6] = "G " ; align[7] = "G1" ; align[8] = "G2" ; align[9] = "G3" ; align[10] = "D " ; align[11] = "D1" ; align[12] = "D2" ; align[13] = "D3" ; align[14] = "E " ; align[15] = "E1" ; align[16] = "E2" ; align[17] = "E3" ; align[18] = "Z " ; align[19] = "Z1" ; align[20] = "Z2" ; align[21] = "Z3" ; align[22] = "H " ; align[23] = "H1" ; align[24] = "H2" ; align[25] = "H3" ; } /^ATOM/ || /^HETATM/ { if(debug) print tolower(\\\$0) ####################################################################################### electrons = substr(\\\$0, 67,6) # number of electrons in this atom (not always there) XPLORSegid = substr(\\\$0, 73, 4) # XPLOR-style segment ID split(XPLORSegid, a) # (remove spaces) XPLORSegid = a[1]; Element = substr(\\\$0, 67) # sometimes element is given here Atomnum= substr(\\\$0, 7, 5)+0 # atom number Element= substr(\\\$0, 13, 2); # actual element number Greek= substr(\\\$0, 15, 2); # "remoteness" number of this atom (i.e. "A" for C-alpha) split(Element Greek, a) # (remove spaces) Atom = a[1]; # store whole atom name Conf = substr(\\\$0, 17, 1) # conformer letter Restyp = substr(\\\$0, 18, 3) # residue name Segid = substr(\\\$0, 22, 1) # O/Brookhaven-style segment ID Resnum = substr(\\\$0, 23, 4) # residue number X = substr(\\\$0, 31, 8)+0 # coordinates Y = substr(\\\$0, 39, 8)+0 Z = substr(\\\$0, 47, 8)+0 Occ = substr(\\\$0, 55, 6)+0 # occupancy Bfac = substr(\\\$0, 61, 6)+0 # B-factor # rest = substr(\\\$0, 67) # rest of the line after B-factor? ATOM = toupper(substr(\\\$0, 1, 6)) # store given atom name ID = substr(\\\$0,12,15) ####################################################################################### # correct for alternate formatting if((Segid == " ") && (substr(XPLORSegid,1,1) ~ /[A-Z]/)) { Segid = substr(XPLORSegid,1,1) } if(Resnum ~ /[A-Z]/) { # incorrect residue numbers: A14, etc. Segid = substr(Resnum,match(Resnum,"[A-Z]"),1); Resnum = substr(Resnum,match(Resnum,"[A-Z]")+1); } Resnum+=0; # fix X-plor's non-standard MET if(Restyp == "MSE") { # Restyp = "MET" if((Greek == "E ")&&(Element == " S")) { Element = "SE" Greek = "D " } } if(electrons+0 == 0) { if(Element == " C") electrons = 6 if(Element == " O") electrons = 8 if(Element == " N") electrons = 7 if(Element == " H") electrons = 1 if(Element == " S") electrons = 16 if(Element == "SE") electrons = 34 } ####################################################################################### # user-directed globlal changes if(BFAC != "") { if(BFAC !~ /^[+-]/) Bfac = 0 Bfac += BFAC } if(OCC != "") { if(OCC !~ /^[+-]/) Occ = 0 Occ += OCC } if(CHAIN != "") Segid = CHAIN if(renumber) { ++ATOMNUM Atomnum = ATOMNUM } # increment/decrement Segids? if(map[Segid]=="") map[Segid]=Segid ID = substr(ID,1,10) map[Segid] substr(ID,12) seen[ID]=seen[ID]+1 while((seen[ID]>1)&&(Segid != "Z")&&(1)) { map[Segid] = alphabet[alphabet[map[Segid]]+1] ID = substr(ID,1,10) map[Segid] substr(ID,12) seen[ID]=seen[ID]+1 } Segid=map[Segid] ####################################################################################### if(Resnum != lastResnum) { for(i=1;i<30;++i) { if((residue[align[i]] != "")&&(reorder)) { print residue[align[i]] } } # clear for next time for(x in residue) residue[x] = "" } lastResnum = Resnum order = Greek if(order == " ") order = Atom residue[order] = sprintf("%6s%5d %2s%-2s%1s%3s %1s%4d %7.3f %7.3f %7.3f %5.2f%6.2f%4d %-4s%2s",\\\\ ATOM, Atomnum,Element,Greek,Conf,Restyp,Segid,Resnum,X,Y,Z,Occ,Bfac,electrons,XPLORSegid,Element); ####################################################################################### # default, non-reordering mode if(!reorder) { printf("%6s%5d %2s%-2s%1s%3s %1s%4d %7.3f %7.3f %7.3f %5.2f%6.2f%4d %-4s%2s\\\\n",ATOM, Atomnum,Element,Greek,Conf,Restyp,Segid,Resnum,X,Y,Z,Occ,Bfac,electrons,XPLORSegid,Element); } } ! /^ATOM/ && ! /^HETATM/ END{ for(i=1;i<30;++i) { if((residue[align[i]] != "")&&(reorder)) { print residue[align[i]] } } } EOF-reformatpdb chmod a+x \${tempfile}reformatpdb.awk cat << EOF-phipsi >! \${tempfile}phipsi.awk #! \$nawk -f # # Calculate phi-psi angles for a pdb file # # # BEGIN{ # put "0th" CA in outer space CA["X"]=999999999; CA["Y"]=999999999; CA["Z"]=999999999; } /^ATOM/{ Element= substr(\\\$0, 13, 2); Greek= substr(\\\$0, 15, 2); split(Element Greek, a) Atom = a[1]; Restyp = substr(\\\$0, 18, 3) Segid = substr(\\\$0, 22, 1) # O/Brookhaven-style segment ID Resnum = substr(\\\$0, 23, 4)+0 X = substr(\\\$0, 31, 8)+0 Y = substr(\\\$0, 39, 8)+0 Z = substr(\\\$0, 47, 8)+0 if(Segid == " ") Segid = "_" if((Atom == "CA")||(Atom == "CT2")) { # store XYZ of last 2 Ca atoms lastCA["X"] = CA["X"]; lastCA["Y"] = CA["Y"]; lastCA["Z"] = CA["Z"]; CA["X"] = X; CA["Y"] = Y; CA["Z"] = Z; # flag to know when we're in "real" protein one_CA_read = 1 } if((Atom == "C")||(Atom == "CT1")) { # store XYZ of last 2 carbonyl carbons lastC["X"] = C["X"]; lastC["Y"] = C["Y"]; lastC["Z"] = C["Z"]; C["X"] = X; C["Y"] = Y; C["Z"] = Z; } if((Atom == "N" )||(Atom == "OT")) { # store XYZ of last 2 amino nitrogens N["X"] = nextN["X"]; N["Y"] = nextN["Y"]; N["Z"] = nextN["Z"]; nextN["X"] = X; nextN["Y"] = Y; nextN["Z"] = Z; } # print phi-psi when we reach the N of the NEXT residue if((Atom == "N") && (one_CA_read)) { # don't print out unrealistic CA-CA distances CA_CA = sqrt((lastCA["X"]-CA["X"])^2 + (lastCA["Y"]-CA["Y"])^2 + (lastCA["Z"]-CA["Z"])^2) # don't print out unrealistic psi distances either CA_nN = sqrt((CA["X"]-nextN["X"])^2 + (CA["Y"]-nextN["Y"])^2 + (CA["Z"]-nextN["Z"])^2) phi=psi=0; if(CA_CA < 10) { phi = dihedral(lastC, N, CA, C); } if(CA_nN < 10) { psi = dihedral(N, CA, C, nextN); } pep = dihedral(lastCA, lastC, N, CA); # print residue phi and psi: if((CA_CA < 10)||(CA_nN < 10)) { printf "%3s %s %-4d phi= %7.2f psi= %7.2f pep= %7.2f\\n",\\ lastRestyp, lastSegid, lastResnum,phi,psi,pep; } } lastResnum = Resnum lastRestyp = Restyp lastSegid = Segid lastX = X lastY = Y lastZ = Z } END{print ""} function dihedral(atom1,atom2,atom3,atom4) { # # O -atom1 O - atom4 # \\\\ / # \\\\ / # \\\\ / # \\\\ / # \\\\ chi = 0 / # atom2- O -------------- O -atom3 # # atom1, atom2, atom3, atom4, are 3-membered arrays ["X","Y","Z"] # return value is chi # # we need to construct a basis for converting them to "global" coordinates # get vector of first dihedral bond bond1["X"] = atom1["X"]-atom2["X"] bond1["Y"] = atom1["Y"]-atom2["Y"] bond1["Z"] = atom1["Z"]-atom2["Z"] # get vector of "second" (rotating axis) bond axis["X"] = atom3["X"]-atom2["X"] axis["Y"] = atom3["Y"]-atom2["Y"] axis["Z"] = atom3["Z"]-atom2["Z"] # get vector of "third" dihedral bond bond3["X"] = atom4["X"]-atom3["X"] bond3["Y"] = atom4["Y"]-atom3["Y"] bond3["Z"] = atom4["Z"]-atom3["Z"] # normalize the "axis" to unit length norm = sqrt(axis["X"]^2 + axis["Y"]^2 + axis["Z"]^2) if(norm == 0) return "axis error" axis["X"] = axis["X"]/norm axis["Y"] = axis["Y"]/norm axis["Z"] = axis["Z"]/norm # reduce "bond" to their components perpendicular to the "axis" component = bond1["X"]*axis["X"] + bond1["Y"]*axis["Y"] + bond1["Z"]*axis["Z"] bond1["X"] = bond1["X"]-component*axis["X"] bond1["Y"] = bond1["Y"]-component*axis["Y"] bond1["Z"] = bond1["Z"]-component*axis["Z"] component = bond3["X"]*axis["X"] + bond3["Y"]*axis["Y"] + bond3["Z"]*axis["Z"] bond3["X"] = bond3["X"]-component*axis["X"] bond3["Y"] = bond3["Y"]-component*axis["Y"] bond3["Z"] = bond3["Z"]-component*axis["Z"] # now the angle between bond1 and bond3 is the dihedral angle # normalize the first and last bond vectors norm = sqrt(bond1["X"]^2 + bond1["Y"]^2 + bond1["Z"]^2) if(norm == 0) return "bond1 error" bond1["X"] = bond1["X"]/norm bond1["Y"] = bond1["Y"]/norm bond1["Z"] = bond1["Z"]/norm norm = sqrt(bond3["X"]^2 + bond3["Y"]^2 + bond3["Z"]^2) if(norm == 0) return "bond3 error" bond3["X"] = bond3["X"]/norm bond3["Y"] = bond3["Y"]/norm bond3["Z"] = bond3["Z"]/norm # construct a vector perpendicular to both the axis and bond1 # (this differentiates "sides" of the dihedral) chi90["X"] = axis["Y"] * bond1["Z"] - axis["Z"] * bond1["Y"]; chi90["Y"] = axis["Z"] * bond1["X"] - axis["X"] * bond1["Z"]; chi90["Z"] = axis["X"] * bond1["Y"] - axis["Y"] * bond1["X"]; # get the component of bond3 along bond1 adjacent = bond1["X"]*bond3["X"] + bond1["Y"]*bond3["Y"] + bond1["Z"]*bond3["Z"] # get the component of bond3 along bond1 opposite = chi90["X"]*bond3["X"] + chi90["Y"]*bond3["Y"] + chi90["Z"]*bond3["Z"] # use ArcTan to get the angle angle = atan2(opposite, adjacent)*180/3.1415927; return angle } EOF-phipsi chmod a+x \${tempfile}phipsi.awk goto RetrnUnwrap_awk_Scripts ######################## The Future: recognize metals as IUM recognize NCS by least-squares alignment? edit dictionary for SeMET jam.com and traj.com Canned omit-map procedure: omit.com EOF-Refmacer chmod a+x ${Elfsheim}/Refmacer echo "." # might as well do some other scripts too # sendhome cat << EOF-sendhome >! ${SCRIPT_dir}/sendhome #! /bin/csh -f # # sendhome.com v0.95 # # Send your x-ray frames to a remote machine (home) # continuously, AS they are collected! # # -James Holton 12-12-1901 :) # ################################################################################ echo "\$0 - a safe, secure, and backgroundable way to send files home James Holton 12-12-1901" echo "" goto Setup # # Routine (at bottom) to read command-line args # Help: cat << EOF-help usage: \$0 /data/\${user}/frames/first_001.img \${user}@remotehost.college.edu:/bigdisk/\${user}/frames/ [no compress] where: /data/\${user}/frames/ - the local directory containing frames first_001.img - the first (oldest) frame to send home any frames newer than [first_001.img] will also be sent \${user}@remotehost.college.edu - your login at home /bigdisk/\${user}/frames/ - the disk (at home) you want to put your frames on (remote directory will be created if it doesn't exist) Other options: no compress - (optional) do not compress the files during transfer (usually 3x slower) timeout 50 - set the connection time-out to 50 minutes no timeout - disable connection time-out (careful! might interfere with last file ) ----------- a log of files that were sent home will be kept in \$sentlog NOTE: things will probably go a lot faster if: /bigdisk is pysically attached to remotehost.college.edu /data is pysically attached to the computer running sendhome EOF-help # exit is "Help" was not just displayed for fun... #if(\$?BAD) exit 9 Return_from_Setup: if("\$rhost" == "") goto Help ############################################################################### # preamble ############################################################################### echo "logging sent files in \$sentlog" echo "sending \${minsize}-byte files" echo -n "from \${framedir} " if("\$firstfile" != "") echo -n "(starting with "\\"\$firstfile\\"") " if("\$lastfile" != "") echo -n "(finishing with "\\"\$lastfile\\"") " echo "" echo "to \$rdir on \${ruser}@\${rhost}" if(\$?CLEAR) echo "local copy will be deleted once file has been sent." onintr User_Interrupt unset FINISHED touch \$sentlog if(\$?BUNCHWISE) goto Bunchwise ############################################################################### # start sending frames home ############################################################################### echo "\$framedir ext \$minsize \$timeout \$lastfile \$firstfile \$sentlog" |\\ nawk '{framedir=\$1;minsize=\$3;timeout=\$4*60;lastfile=\$5;firstfile=\$6;\\ if(firstfile == "") sending=1;\\ cmd="ls -lLrt "framedir; while(1){new=0;\\ # keep listing the directory every 10 seconds \\ while(cmd | getline){\\ # ignore entries before the first file \\ if(\$NF == firstfile){sending=1};\\ # pretend earlier entries were already sent \\ if(! sending) sent[\$NF]=1;\\ if((sending)&&(\$5>=minsize)&&(! sent[\$NF])){\\ print \$NF; fflush(); ++new; idle=0; \\ # keep an internal record of files we have sent \\ sent[\$NF]=1;};\\ # exit when we see a file called "exit" \\ if(\$NF == lastfile){exit};\\ };\\ # idle timeout so last file send finishes \\ close(cmd); if(! new){system(" sleep 10 "); idle+=10};\\ if(idle > timeout) exit;}}' |\\ (cd \$framedir; tar c\${B}\${T}f - - ) | \$compresser |\\ ssh -x -k \${ruser}@\${rhost} "if(! -e \$rdir) mkdir -p \$rdir; \$decompress | (cd \$rdir ; tar xv\${B}f - )" |\\ nawk -v clear=\$?CLEAR -v framedir=\$framedir -v sentlog=\$sentlog '\\ {filename=""; for(i=1;i<=NF;++i){ word=\$i; \\ if(! system("test -s " framedir "/" word)) filename=word; \\ word=substr(\$i,1,length(\$i)-1);\\ if(! system("test -s " framedir "/" word)) filename=word; \\ } if(filename=="") {print; next}}\\ clear!=0 && sentfile!=""{if(! system("rm -f " framedir "/" sentfile)) printf "deleted %s ", sentfile} \\ {print ""} \\ {printf "sending %s ", filename; print filename > sentlog} \\ {sentfile=filename} \\ END{if(clear !=0 && sentfile!="") if(! system("rm -f " framedir "/" sentfile)) printf "deleted %s ", sentfile; \\ print ""}' # user will only have to enter their remote password once if(-e "\${framedir}/\$lastfile") then # the "exit" file was produced set FINISHED goto done endif # reaching here means the file-finder program timed out goto Timed_out Bunchwise: ############################################################################### # make a list of at least \$bunch_size files before initiating a send # mainly for OSF1 users echo "unimplemented! sorry." exit 9 goto done # user will have to enter their remote password once per bunch Timed_out: ############################################################################### echo "timeout: \$timeout minutes" set FINISHED User_Interrupt: ############################################################################### onintr done echo "connection lost...." # don't ask user questions if output is not a terminal test -t 1 if(\$status) set DONT_ASK echo "reconnect to \${rhost}? [Yes]" echo -n "->" if(! \$?DONT_ASK) then set temp = "\$<" else set temp = "No" echo "" endif if("\$temp" =~ [Nn]*) then goto done endif # re-discover first filename set firstfile = "" goto reconnect ############################################################################### done: ############################################################################### onintr # don't ask user questions if output is not a terminal test -t 1 if(\$status) set DONT_ASK if(! \$?FINISHED) then # extract last file sent from TAR log cat \$sentlog |&\\ nawk 'BEGIN{RS=" "} {print}' |\\ nawk '/,\$/{print substr(\$0,1,length(\$0)-1)} ! /,\$/{print}' |\\ nawk 'NF==1' |\\ tail -1 >! \${tempfile}\$\$ set firstfile = \`tail -1 \${tempfile}\$\$\` rm -f \${tempfile}\$\$ >& /dev/null if(-e "\${framedir}/\$firstfile") then echo "" echo "WARNING! remote \$firstfile is incomplete! " echo "" echo "send it now? [Yes]" echo -n "->" if(! \$?DONT_ASK) then set temp = "\$<" else echo "" endif if("\$temp" =~ [Nn]*) then goto cleanup endif # do the standard send for one file echo "\$firstfile" |\\ (cd \$framedir; tar c\${B}\${T}f - - ) | \$compresser |\\ ssh \${ruser}@\${rhost} "\$decompress | (cd \$rdir ; tar xv\${B}f - )" |&\\ nawk -v clear=\$?CLEAR -v framedir=\$framedir -v sentlog=\$sentlog '\\ NF==1{filename= \$1} NF>1{filename = substr(\$2,1,length(\$2)-1)} \\ {printf "sending %s", filename; print filename > sentlog} \\ END{if(clear !=0){if(! system("rm -f " framedir "/" filename)) printf " deleted %s\\n", filename;}}' if(! \$status) set FINISHED endif endif cleanup: if(\$?FINISHED) then echo "done" endif exit ############################################################################### # set-up routine (moved to bottom for clarity) Setup: if(! \$?user) set user = \`whoami\` # defaults (can be reset interdependently) set timeout = "60" # max time since last new file appeared (minutes) set framedir = "" # directory to send files from set firstfile = "" # first file (chronologically) to send set lastfile = "exit" # last file (chronologically) to send set minsize = 10617344 # file must reach this size before being sent set ruser = "" # remote username set rhost = "" # remote computer name set rdir = "" # send-to directory on remote computer if(\$?CLEAR) unset CLEAR #set CLEAR # uncomment to delete files after they are sent set tempfile = ./tempfile set sentlog = ./sent_home.log touch \$sentlog >& /dev/null if(\$status) then set sentlog = ~/sent_home.log set tempfile = ~/tempfile endif touch \$sentlog >& /dev/null if(\$status) then echo "ERROR! unable to create sent-file log" echo "please make sure either "\`pwd\`" or ~\$user is writable! " sleep 2 set BAD goto Help endif # default: use compress (gzip is too slow) # default: use gzip (compress has a stream size limit) set compresser = "gzip --fast -c" set decompress = "gunzip -c" # machine-specific configurations set machine = \`uname\` set T = "" #set B = "B" set B = "" if("\$machine" =~ IRIX*) then set T="L" endif if("\$machine" == "Linux") then set T="hT" alias nawk awk endif if("\$machine" == "OSF1") then echo "ERROR: realtime file transmission is not possible on Digital Unix" echo " this is because the OSF1 tar program is incapable of streaming" echo " archives. A workaround is being implemented, but is not yet" echo " available. " echo "" echo " You will probably have better luck on an SGI or Linux box." echo "" set BUNCHWISE set bunch_size = 50 endif # scan the command line if(\$#argv == 0) goto Help set i = 0 while ( \$i < \$#argv ) @ i = ( \$i + 1 ) set arg = "\$argv[\$i]" # check for local directory specifier if(("\$arg" =~ */*)&&("\$arg" !~ *[@:]*)||(-e "\$arg")) then if(-e "\$arg") then test -d \$arg if(! \$status) then # just a directory set framedir = "\$arg" continue endif test -c \$arg if(! \$status) then # support tapes one day? continue endif # must just be a regular file (or link) if("\$firstfile" == "") then set framedir = \`dirname \$arg\` set firstfile = \`basename \$arg\` else # use last local filename given as a "last" file set lastfile = \`basename \$arg\` endif continue else if("\$framedir" == "") then # no files specified yet set framedir = \`dirname \$arg\` set prefix = \`basename \$arg\` set firstfile = \`ls -lL \$framedir | nawk '\$5>1000000 && ! /dkc\$/ {print \$NF}' | egrep "^\$prefix" | head -1\` if(-e "\${framedir}/\$firstfile") then continue endif # guess that wasn't anything set framedir = "" set firstfile = "" echo "WARNING: \$arg does not exist! " else # maybe this is a preemtive last file? if("\$arg" =~ *.\$ext) set lastfile = \`basename \$arg\` endif endif endif # check for remote file specifier if("\$arg" =~ *[@:/]*) then # retrieve remote username set ruser = \`echo \$arg | nawk 'BEGIN{FS="@"} NF>1{print \$1}'\` if("\$ruser" == "") set ruser = \`whoami\` # get the remote computer name set rhost = \`echo \$arg | nawk 'BEGIN{FS="@"} {print \$NF}' | nawk 'BEGIN{FS="[:/]"} {print \$1}'\` if("\$rhost" != "") then # get remote directory name if("\$arg" =~ *:*) then # everything after first colon is directory set rdir = \`echo \$arg | nawk 'BEGIN{FS="@"} {print \$2}' | nawk '{print substr(\$0,index(\$0,":")+1)}'\` set rdir = \`echo \$arg | nawk 'BEGIN{FS="@"} {print \$2}' | nawk 'BEGIN{FS=":"} {print \$2}'\` else # everything after first "/" is directory set rdir = \`echo \$arg | nawk '/[\\/]/{print substr(\$0,index(\$0,"/"))}'\` endif else echo "WARNING: did not understand \$arg" echo " please use: user@host:directory" endif continue endif # optional compression stuff if(("\$arg" == "compress")||("\$arg" == "-compress")) then set compresser = "compress -c" set decompress = "uncompress -c" if(\$?NO) then # disable compression set compresser = "cat" set decompress = "cat" endif continue endif if(("\$arg" == "gzip")||("\$arg" == "-gzip")) then set compresser = "gzip --fast -c" set decompress = "gunzip -c" continue endif # ignore last sentlog if(("\$arg" == "new")||("\$arg" == "-new")) then echo "clearing \$sentlog ..." echo -n "" >! \$sentlog endif # delete files after sending them #if(("\$arg" == "clear")||("\$arg" == "delete")||("\$arg" == "remove")) then if(("\$arg" == "delete")) then if(\$?NO) then unset CLEAR else set CLEAR endif endif # negative logic (for next word) unset NO if(("\$arg" == "no")||("\$arg" == "-no")||("\$arg" == "not")) then set NO continue endif end # default timeouts (relative speed of detectors) if("\$firstfile" =~ *.mar*) set timeout = 120 if("\$firstfile" =~ *.img) set timeout = 60 if("\$firstfile" =~ *.osc) set timeout = 200 # second pass # scan the command line set i = 0 while ( \$i < \$#argv ) @ i = ( \$i + 1 ) set arg = "\$argv[\$i]" # manual setting of timeout if(("\$arg" == "timeout")||("\$arg" == "-timeout")) then if(\$?NO) then # set timeout to 24 hours set timeout = 1440 else @ j = ( \$i + 1 ) if(\$j <= \$#argv) then if("\$argv[\$j]" =~ [0-9]*) then # user-specified timeout set timeout = \`echo \$rgv[\$j] | nawk '{print \$1+0}'\` endif endif endif endif # negative logic (for next word) unset NO if(("\$arg" == "no")||("\$arg" == "-no")||("\$arg" == "not")) then set NO continue endif end # defaults for bad or missing inputs if(! -e "\$framedir") then # default to current directory set framedir = "." set firstfile = "" endif if("\$rhost" == "") then set temp = "" echo "where shall we send \$firstfile ... etc. to? [\${user}@home.college.edu:/bigdisk/\${user}/frames]" echo "" echo -n "-> " if(! \$?DONT_ASK) set temp = "\$<" if(("\$temp" =~ *[@:]*)) then set argv = ( \$temp ) goto Setup endif goto Help endif if("\$rdir" == "") then echo "WARNING: files will be sent to \${ruser}@\${rhost}'s HOME directory! " set rdir = "." endif # jump here to re-establish send where we left off reconnect: # check to see if we don't have a first filename yet if(("\${firstfile}" == "")||(! -e "\${framedir}/\$firstfile")) then # check for an old, aborted run if(-e "\$sentlog") then # extract last file sent from TAR log cat \$sentlog |&\\ nawk 'BEGIN{RS=" "} {print}' |\\ nawk '/,\$/{print substr(\$0,1,length(\$0)-1)} ! /,\$/{print}' |\\ tail -1 >! \${tempfile}\$\$ set temp = \`head -1 \${tempfile}\$\$\` rm -f \${tempfile}\$\$ >& /dev/null if(-e "\${framedir}/\$temp") then echo "reading \$sentlog" set firstfile = "\$temp" endif endif endif # default to the first file in the directory if(("\${firstfile}" == "")||(! -e "\${framedir}/\$firstfile")) then set firstfile = \`ls -lLrt \$framedir | nawk -v size=\$minsize '\$5>=size{print \$NF}' | head -1\` endif # still nothing? if(("\${firstfile}" == "")||(! -e "\${framedir}/\$firstfile")) then # wait for something to appear set firstfile = "" # maybe just send the directory? endif # set the target frame size if(("\$firstfile" != "")&&(-e "\${framedir}/\$firstfile")) then set minsize = \`ls -lL \${framedir}/\${firstfile} | nawk '\$5+0>0{print \$5}'\` # get filename extension too set ext = \`echo \$firstfile | nawk 'BEGIN{FS="."} {print \$NF}'\` endif goto Return_from_Setup ################################## # Future plans # # use cpio instead of tar? # implement bunch-wise send # # checksum remote files after transfer (retransmit?) # send directories? # # EOF-sendhome chmod a+x ${SCRIPT_dir}/sendhome echo -n "." ######################################## # create a combinatorial EPMR script if(! -e epmr) mkdir epmr cat << EOF-epmr.com >! epmr/epmr.com #! /bin/csh # # Combinatorial EPMR Molecular-Replacement script James Holton 9-8-10 # # EPMR is available from Agouron Pharmaceuticals, Inc. # ftp://ftp.agouron.com/pub/epmr/ # alias nawk nawk nawk 'BEGIN{exit}' >& /dev/null if(\$status) alias nawk awk #################################### # defaults for EPMR program set nmols = "" set RESOs = "" set SGs = "" set pdbfiles = "" set mtzfile = mtz/all.mtz set F = FP set tempfile = epmr_temp if("\$1" == "") goto Help goto Setup #################################### Help: cat << EOF usage: epmr.com pdbfile.pdb [file1.pdb ...] mtzfile.mtz P212121 4-15A 1 where: pdbfile.pdb - anything with Brookhaven "ATOM" or "HETATM" entries in it file1.pdb - one or more other models you want to try mtzfile.mtz - CCP4 "mtz" format data file P212121 - space group to search 4-15A - resolution range (4A to 15A) 1 - number of molecules to place (integer) note: you can specify more than one space group, more than one model, and more than one resolution range, they will be run combinatorially. EOF exit 9 #################################### Return_from_Setup: echo "data: \$F in \$mtzfile" echo "models: \$pdbfiles" echo "resolution: \$RESOs" echo "chains: \$nmols" echo "space group: \$SGs" echo "" echo "model SG n reso" | nawk -v format="\$format" '{printf format, \$1, \$2, \$3, \$4}' echo "" # try each model, in turn foreach pdbfile ( \$pdbfiles ) # prefix for output log/file set prefix = \`basename \$pdbfile .pdb\` set prefix = \`basename \$prefix .brk\` foreach RESO ( \$RESOs ) # update resolution limits set temp = \`echo "\$RESO" | nawk 'BEGIN{FS="-"} \$1+0 > 0.1{print \$1+0} \$2+0 > 0.1{print \$2+0}'\` if(\$#temp != 1) then # setting both resolution limits set temp = \`echo \$temp | nawk '\$1>\$2{print \$1, \$2} \$2>\$1{print \$2, \$1}'\` if(\$#temp == 2) then set loRES = "\$temp[1]" set hiRES = "\$temp[2]" endif else # only setting high-resolution limit if("\$temp" != "") set hiRES = "\$temp" endif foreach nmol ( \$nmols ) foreach SG ( \$SGs ) # check for orthorhombic "pseudo-spacegroups" set axes = "" set realSG = "\$SG" if("\$SG" == P222) set axes = "a b c" if("\$SG" == P212121) set axes = "a b c" if("\$SG" == P2221) then # P2221 with screw along longest axis set axes = "a b c" set realSG = "P2221" endif if("\$SG" == P2212) then # P2221 with screw along mid-length axis set axes = "b c a" set realSG = "P2221" endif if("\$SG" == P2122) then # P2221 with screw along shortest axis set axes = "c a b" set realSG = "P2221" endif if("\$SG" == P21212) then # P21212 with non-screw along longest axis set axes = "a b c" set realSG = "P21212" endif if("\$SG" == P21221) then # P21212 with non-screw along mid-length axis set axes = "b c a" set realSG = "P21212" endif if("\$SG" == P22121) then # P21212 with non-screw along shotest axis set axes = "c a b" set realSG = "P21212" endif set realSGnum = \`nawk -v SG=\$realSG '\$4==SG{print \$1;exit}' \${CLIBD}/symop.lib\` if("\$axes" != "") then # we have an asymmetric orthorhombic space group # get current axis ordering, then # find out what the cannonical one would be # then decide how to go from current ordering to the desired one echo "head" |\\ mtzdump hklin \$mtzfile |\\ nawk '/Cell Dimensions/{getline;getline;print}' |\\ nawk '{\\ # print out current axis order \\ print \$1, "h"; print \$2, "k"; print \$3, "l"}' |\\ sort -n |\\ nawk '\\ # add cannonical axis names\\ NR==1{print \$0, "a"} NR==2{print \$0, "b"} NR==3{print \$0, "c"}' |\\ nawk -v axes="\$axes" 'BEGIN{split(axes, abc)} {\\ # write desired axis ordering in front of cannonical one \\ print abc[NR], \$0}' |\\ sort |\\ nawk '# print out new hkl order \\ {printf "%s ", \$3} END{print ""}' |\\ nawk '\$1 \$2 \$3 \$1 \$2 \$3 !~ /hkl/{\$3 = "-" \$3} {print "reindex", \$1",",\$2",",\$3}' |\\ reindex HKLIN \$mtzfile HKLOUT \${tempfile}.mtz >> /dev/null # this should give us a mapping between any two orthorhombics # now simply re-name the space group in the header echo "SYMM \$realSGnum" |\\ mtzutils HKLIN \${tempfile}.mtz HKLOUT \${tempfile}newSG.mtz >> /dev/null if(\$status) then set BAD echo "failed! ?" continue endif mv \${tempfile}newSG.mtz \${tempfile}.mtz >& /dev/null else # just re-name the space group in the mtz header echo "SYMM \$realSGnum" |\\ mtzutils HKLIN \$mtzfile HKLOUT \${tempfile}.mtz >> /dev/null if(\$status) then set BAD echo "failed! ?" continue endif endif ########################################## # convert mtz data to EPMR-readable format (only needs F, not SIGF) rm -f \${tempfile}.hkl >& /dev/null mtz2various hklin \${tempfile}.mtz hklout \${tempfile}.hkl << EOF >! \${tempfile}.log OUTPUT USER '(3I5, 1F12.3)' LABIN FP=\$F EOF echo "head" | mtzdump hklin \${tempfile}.mtz >! \${tempfile}.log rm -f \${tempfile}.mtz # create "cell" file set CELL = \`nawk '/Cell Dimensions/{getline;getline;print}' \${tempfile}.log\` set SGnum = \`nawk -v SG=\$realSG '\$4 == SG {print \$1}' \$CLIBD/symop.lib | head -1\` echo "\$CELL \$SGnum" >! \${tempfile}.cel rm -f \${tempfile}.log echo "\$pdbfile \$SG \$nmol \$hiRES \$loRES" |\\ nawk -v format="\$format" '{printf format, \$1, \$2, \$3, \$4+0 "-" \$5+0 "A"}' ########################################## # run epmr epmr -m\$nmol -h\$hiRES -l\$loRES -e1 \${tempfile}.cel \$pdbfile \${tempfile}.hkl >! \${prefix}_\${nmol}_\${SG}_{\$RESO}.log # other epmr options: # -p300 population size # -g50 generations # -n10 total runs # -t0.45 acceptable correlation coefficient (threshold) # -b0.0 minimum "bump" distance (penalize overlapping molecules) # -w1 print out top "1" solutions # -s file.pdb input a "static" structure as a partial solution # -e0 seed random number generator (0 means seed with clock) ########################################## # finish off summary line cat \${prefix}_\${nmol}_\${SG}_\${RESO}.log |\\ nawk '/^Soln/{print " best CC=", \$(NF-2), "R=", \$NF}' |\\ sort -n -k3 | tail -1 | tee \${tempfile}stats set R = \`nawk '{print \$5}' \${tempfile}stats\` set CC = \`nawk '{print \$3}' \${tempfile}stats\` rm -f \${tempfile}stats >& /dev/null # record what the stats were in the PDB file echo "REMARK EPMR result: \$pdbfile \$SG \$nmol \${hiRES}-\${loRES}A best CC= \$CC R= \$R" |\\ cat >! \${prefix}_\${nmol}_\${SG}_{\$RESO}.best.pdb # add a header to the PDB file echo "" >! \${tempfile}.pdb echo "CELL \$CELL" |\\ pdbset XYZIN \${tempfile}.pdb XYZOUT \${tempfile}cell.pdb > /dev/null head -4 \${tempfile}cell.pdb >> \${prefix}_\${nmol}_\${SG}_{\$RESO}.best.pdb rm -f \${tempfile}.pdb \${tempfile}cell.pdb >& /dev/null set i = 0 while( \$i < \$nmol ) @ i = ( \$i + 1 ) # re-name output files if((! -e epmr.\${i}.best.pdb) && (-e epmr.\${i}.pdb)) mv epmr.\${i}.pdb epmr.\${i}.best.pdb cat epmr.\${i}.best.pdb >> \${prefix}_\${nmol}_\${SG}_{\$RESO}.best.pdb rm -f epmr.\${i}.best.pdb >& /dev/null end end end end end #clean up rm -f \${tempfile}.hkl \${tempfile}.cel >& /dev/null exit ########################################## ########################################## ########################################## ########################################## Setup: # read some command-line options set hiRES = 4 set loRES = 15 # scan the command line for files 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 set arg = "\$argv[\$i]" # check for mtz file if( "\$arg" =~ *.mtz ) then if(! -e "\$arg") then echo "WARNING: \$arg does not exist! " continue endif set mtzfile = "\$arg" continue endif if(("\$arg" =~ *.pdb)||("\$arg" =~ *.brk)) then if(! -e "\$arg") then echo "WARNING: \$arg does not exist! " continue endif set pdbfiles = ( \$pdbfiles \$arg ) continue endif # check for space groups if("\$arg" =~ [PpCcIiFfRr][1-6]*) then set temp = \`echo \$arg | nawk '{print toupper(\$1)}'\` set temp = \`nawk -v SG=\$temp '\$4 == SG {print \$4}' \$CLIBD/symop.lib | head -1\` if("\$temp" == "") then # check for "pseudo-spacegroup" language set temp = \`echo "\$arg" | nawk 'toupper(\$1) ~ /[PC]2212|[PC]2122|P21221|P22121/'\` # these are okay too, reindexing engine will understand endif if("\$temp" != "") then # add this SG to the space group list set SGs = ( \$SGs \$temp ) continue endif endif 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 set RESOs = "\$RESOs \$arg" endif else if("\$temp" != "") set RESOs = "\$RESOs \$arg" endif endif # interpret free integers as number of molecules? set int = \`echo "\$arg" | nawk '{printf "%d", \$1+0}'\` if("\$arg" == "\$int") then set nmols = ( \$nmols \$int ) endif endif end # go no further if there is no mtz file if(! -e "\$mtzfile") goto Help ##################################### #get dataset names from mtz file echo "go" | mtzdump hklin \$mtzfile |\\ cat >! \${tempfile}mtzdump # get info from the MTZ set SG = \`nawk '/Space group/{print \$5}' \${tempfile}mtzdump\` set SGnum = \`nawk '/Space group/{print \$NF+0}' \${tempfile}mtzdump \` set SG = \`nawk -F "[\\047]" '/Space group/{print \$2}' \${tempfile}mtzdump \` set SG = \`nawk -v num=\$SGnum '\$1==num && NF>5{print \$4}' \${CLIBD}/symop.lib \` set PG = \`nawk -v num=\$SGnum '\$1==num && NF>5{print \$5}' \$CLIBD/symop.lib | head -1\` set latt = \`echo \$SG | nawk '{print substr(\$1, 1, 1)}'\` set allSGs = \`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 allSGs = "P212121 P21212 P21221 P22121 P2221 P2212 P2122 P222" endif if("\$SGs" == "") set SGs = "\$allSGs" # epmr default: if("\$RESOs" == "") set RESOs = "4-15A" if("\$nmols" == "") set nmols = "1" # use completeness, or F/sigF to pick default F cat \${tempfile}mtzdump |\\ nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\ nawk 'NF>10 && \$(NF-1) ~ /[FQPWADI]/' |\\ nawk '\$(NF-1) == "F"{F=\$NF; meanF=\$8; reso=\$(NF-2); comp=substr(\$0,32)+0; \\ getline; S=\$NF; if(\$8) meanF /= \$8; print F, S, reso, comp, meanF;}' |\\ sort -k3n,4 -k4nr,5 -k5nr >! \${tempfile}F # and extract all dataset types/labels cat \${tempfile}mtzdump |\\ nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\ nawk 'NF>10 && \$(NF-1) ~ /[FQPWADI]/' |\\ nawk 'NF>2{print \$(NF-1), \$NF, " "}' |\\ cat >! \${tempfile}cards #clean up a bit rm -f \${tempfile}mtzdump ##################################### # pick F with best resolution, or / set F = \`head -1 \${tempfile}F\` if(\$#F > 2) then set SIGF = \$F[2] set F = \$F[1] endif # see if user specified an F foreach arg ( \$* ) set temp = \`grep " \$arg " \${tempfile}cards\` if("\$temp" =~ F*) then set F = "\${arg}" set temp = \`nawk -v arg="\$arg" '\$1==arg{print \$2}' \${tempfile}F\` if(\$#temp == 1) set SIGF = "\$temp" continue endif end rm -f \${tempfile}cards \${tempfile}F >& /dev/null if("\$F" == "") goto Help # devise a clean printing-out format set w1 = \`echo "\$pdbfiles" | nawk '{for(i=1;i<=NF;++i) print length(\$i)}' | sort -n | tail -1\` set w2 = \`echo "\$SGs" | nawk '{for(i=1;i<=NF;++i) print length(\$i)}' | sort -n | tail -1\` set w3 = \`echo "\$RESOs" | nawk '{for(i=1;i<=NF;++i) print length(\$i)}' | sort -n | tail -1\` set format = "%-\${w1}s %\${w2}s %s %\${w3}s" goto Return_from_Setup exit #################### # the future combinatorial B-factor, mtz EOF-epmr.com chmod a+x epmr/epmr.com ######################################## # create a "guide" script for processing everything cat << EOF-guide.com >! ${SCRIPT_dir}guide.com #! /bin/csh -f # # Non-automatic shell script for executing all the steps in the # Elves data-processing chain without actually using Elves. # Instead, you use the scripts that Elves have written for you. # # Although this script should run okay, it is not actually used by # Elves. It is here as a guide to what the Elves are doing, and # as a jumping-off point for creating your own processing procedure. # # jump ahead to the domain of a particular Elves group goto Wedger #goto Scaler #goto solve #goto shelx #goto Phaser #goto wARP #goto Refmacer sendhome: # if you are at synchrotron, or otherwise collecting data far from home, # you will probably want a way to send your data frames back to your "home" # computer system while you work on other tasks. # If you type the following command: scripts/sendhome /data/user/first_1_001.img user@home.college.edu:/remote/dir # then you will be prompted for your password once, and an ssh login will # be initiated to your home computer. Every frame in /data/user that # is as new or newer than first_1_001.img will be sent to /remote/dir on # your home computer system. As new frames are collected, they will be sent # too. Once the file transfer is underway, you can type: # #bg #(that is hold down the "Ctrl" key, and press "z", then type "bg" on the # unix command line). This will "background" the sendhome job, so it will # keep running when you log off. # with ADSC Q4 frames, data-transfer rates of up to 5 sec/frame can be # acheived with sendhome, which means it can actually send files home # as fast as they are collected off the Q4 detector. # to send your processing directory home too, use this: cd /your/processing/directory tar cBf - . | compress | ssh user@home.college.edu "cd /remote/dir ; uncompress | tar xvBf -" # this works with ssh 1.x and 2.x. # HOWEVER: sendhome will not work on DEC unix! This is because the DEC tar # program does not support a stream of filenames. You must run sendhome on # either an SGI or Linux box. Wedger: ############################################################################### # now we get into actual data processing... # "foreach" loop to run through all the wedges (Wedger Elves scripts) foreach wedge ( */wedge* ) # change to the "wedge" processing directory cd \$wedge # maybe do a quick "pre-postrefinement" of the wedge ./mosflm.com >! logs/mosflm.log # integrate the image data ./mosflm.com integ >> logs/mosflm.log # this produces "raw.mtz" # scale and merge the wedge ./merge.com raw.mtz >! logs/merge.log # this produces "merged.mtz" # back to the root directory cd ../.. end Spotter: # it may be helpful to run Spotter Elves in each of your processed # wedges. They will present you with an SGI movie of the image pixels # corresponding to the "observation" of your systematic absences, as # well as any "outliers" that were rejected during scaling foreach wedge ( */wedge* ) # change to the "wedge" processing directory cd \$wedge # retrieve the name of the first frame in the wedge set image = \`awk '/^IMAGE/{print \$2}' ./start\` # run Spotter Elves to create the SGI movie Spotter logs/merge.log \$image cd ../.. end # at the moment, there is no "script" for what Spotter Elves do, but there # will be soon. Scaler: ############################################################################### # now we need to do some scaling (Scaler Elves scripts) # first, data from all the wedges must be rebatched and sorted into # a single, large mtz scripts/sort_everything.com >! logs/sorting.log # this makes: mtz/rawdata.mtz # now scala needs a "reference" data set # this script will scale and merge one of your wavelengths, and # prepare it for use as a reference scripts/make_reference_set.com mtz/rawdata.mtz >! logs/make_reference_set.log # this makes: mtz/reference.mtz # now we need to import this reference data set as a "reference batch" # in the raw data file scripts/import_reference.com mtz/reference.mtz mtz/rawdata.mtz >> logs/make_reference_set.log # this makes: mtz/sorted_ref.mtz # you can also use the above script to import just about any merged data set # and use it as a reference ############################################################################### # now we are ready to do some actual multiwavelength scaling # this script applies simple batch scaling (scalepack-style) scripts/rough_scale.com mtz/sorted_ref.mtz >! logs/rough_scale.log # this makes: mtz/rough_scaled.mtz # Now that the frame scales have all converged, we are ready to # apply a smoothing function to them. # this script requires the scale to vary slowly over diffraction space # (specifically, over phi, and across the detector face) # this has the effect of minimizing systematic errors like absorption scripts/localscale.com mtz/rough_scaled.mtz >! logs/localscale.log # this makes: mtz/localscaled.mtz ############################################################################### # now that all the data are scaled, we need to merge them, but we only # want to merge data from the same wavelength! The file: # ./runlist.txt # describes the relationship between scala "run"s and "wavelengths" and it # is read by the following mergeing script scripts/merge.com Fpp mtz/localscaled.mtz >! ./logs/merge_Fpp.log # this makes: merged.mtz # now merged.mtz contains all the runs in the wavelength called "Fpp" in # runlist.txt mv merged.mtz ./mtz/FP.mtz # you should do this for each of the rest of your wavelengths # i.e. foreach wave ( \\\`awk '\\\$2=="wavelength"{print \\\$3}' runlist.txt\\\` ) scripts/merge.com \\\$wave mtz/localscaled.mtz >! ./logs/merge_\\\${wave}.log mv merged.mtz ./mtz/\\\${wave}.mtz end # it is usually much more convenient to have all your datasets in one file # the following cad/scaleit script will do this for you: scripts/scaleit.com >! ./logs/scaleit.log # this makes: scaleited.mtz and cadded.mtz rm cadded.mtz mv scaleited.mtz mtz/all.mtz freeR_flags: ############################################################################### # now would be a good time to add free-R flags to your data set # the following script works pretty much like "uniqueify" scripts/FreeRer.com ./mtz/all.mtz 5% >> ./logs/scaleit.log # this makes: Freered.mtz mv FreeRed.mtz mtz/all.mtz # however, if you already have Free-R flags from a previous crystal, you # can put them into your new data file like this: scripts/FreeRer.com ./mtz/all.mtz ~/old_data/mtz/all.mtz >> ./logs/scaleit.log # or, if your old data are in X-PLOR/CNS format: scripts/FreeRer.com ./mtz/all.mtz ~/cns/refine/old_data.fobs >> ./logs/scaleit.log # FreeRer.com also creates: # freeR_flag.mtz - full free-R set, extending to 1.5A # XPLOR.cv - same thing, x-plor format # you can also use the "utility scripts": # to sumarize a scala/truncate run scripts/scala_summary.com ./logs/merge_*.log # to sumarize your new mtz file scripts/mtz_sum.com 2.24 mtz/all.mtz # to sumarize the results from scaleit scripts/scaleit_sum.com ./logs/scaleit.log Pattersons: ############################################################################### # at this point, you will probably want to look at Pattersons # # an intelligent script has been included for doing just that: # calculate "best" FH estimate from all difference data scripts/bestFH.com ./mtz/all.mtz # will produce: # FH.mtz - an MTZ containing FH and SIGFH # fh.hkl - same data, in shelx format # FH_Patt.map - basic Patterson map of FH # # use this with shelx... mv fh.hkl ./SHELX/ # if, however, you are only interested in a particular dataset, # you can do something like this: scripts/bestFH.com ./mtz/all.mtz DANOFpp no Fpp Fhi Flo # this will ignore Fpp Fhi Flo and only use DANOFpp # a similar program, now available in CCP4, is revise: scripts/revise.com ./mtz/all.mtz # you might have to edit revise.com to get it working properly, # since it is sensitive to the values of f' and f" shelx: ############################################################################### # getting SHELX data # the fh.hkl and fm.hkl data above should work well with shelx, but you # can also extract particular datasets from the un-truncated intensity # data like this: SHELX/mtz2SHELX.com mtz/FP.mtz >! logs/extract_SHELX-FP_ano.log # will make: SHELX_ano.hkl # - which is the anomalous difference data from mtz/FP.mtz # use this in the SHELX directory mv SHELX_ano.hkl SHELX/ano.hkl # for isomorphous data, do this: SHELX/mtz2SHELX.com mtz/F1.mtz mtz/F2.mtz >! logs/extract_SHELX-F1-F2.log # will make: SHELX_iso.hkl # - which contains the isomorphous difference between the two mtzs IMEAN values run_shelx: ############################################################################### # shelx is an extremely fast, direct-phasing program that, when used on # difference data, can be used to locate the positions of your heavy atoms cd SHELX # shelx is always run like this: shelxs fh # this implies to use fh.ins as shelx input, and to read fh.hkl as the data # it will create fh.res, which will contain the heavy-atom sites, and # fh.lst, which is a more detailed log # if you want to run shelx on ano.hkl, using ano.ins, do this: shelxs ano # in my experience, varying sigma-cutoffs and resolution limits seems to # be the best way to get results from shelx. # an easy way to do this is to use the packaged shelx.com script: shelx.com # Phaser Elves know how to read the *.res files, and import them into mlphare # back to the root directory cd .. solve: ############################################################################### # although recent versions of solve can use mtz data, you might still # want to explicitly extract and format unmerged data for input into solve # merged data for SOLVE SOLVE/mtz2SOLVE.com ./mtz/FP.mtz >! logs/extract_SOLVE_FP.log mv SOLVE.fmt ./SOLVE/FP.fmt # to get unmerged data for SOLVE, you use the extract.com script: scripts/extract.com FP ./mtz/localscaled.mtz >! ./logs/extract_unmerged_SOLVE_FP.log # this makes: unmerged.mtz SOLVE/mtz2SOLVE.com unmerged.mtz >> logs/extract_unmerged_SOLVE_FP.log # the solve data are in SOLVE.fmt mv SOLVE.fmt SOLVE/FP.unmerged.fmt # don't need this anymore rm unmerged.mtz # you can do this for all your wavelengths like this foreach wave ( \\\`awk '\\\$2=="wavelength"{print \\\$3}' runlist.txt\\\` ) scripts/extract.com \${wave} ./mtz/localscaled.mtz >! ./logs/extract_unmerged_SOLVE_\${wave}.log SOLVE/mtz2SOLVE.com unmerged.mtz >> logs/extract_unmerged_SOLVE_\${wave}.log mv SOLVE.fmt SOLVE/\${wave}.unmerged.fmt rm unmerged.mtz end run_solve: ############################################################################### # running SOLVE cd ./SOLVE/ # your ./SOLVE/ directory should be equipped with a "solve.runme" script # this should be a pretty good set-up for running solve on your data. # you might want to tinker with the resolution and/or the f'/f" values, # but, otherwise... solve.runme # to try out different space groups, you can use the pre-build direcotires # named for them. There is a solve.runme file in each. foreach SG ( [PCFIR][1-6]* ) cd \$SG solve.runme cd .. end # back to the root directory cd .. Xplor: ############################################################################### # moving into X-plor/CNS # a script is also available for converting your merged mtz data into # X-plor/CNS format: XPLOR/mtz2XPLOR.com mtz/FP.mtz > ./logs/extract_XPLOR-FP.log mv XPLOR.fobs XPLOR/FP_anom.fobs # these data will be formatted for input into the mad_merge.inp procedure # for finding and refining heavy atom positions Phaser: ############################################################################### # Phaser Elves can either take the site constellation found by one of the # above programs, or come up with one on their own, using shelx, rantan, or rsps # The following is a description on how to run the Phaser Elves scripts # # assuming you had run: # Elfsheim/Phaser mtz/all.mtz SOLVE/solve.status # you would want to run these scripts: # the mlphare script with the sites from SOLVE/solve.status in it scripts/mlphare.com >! logs/mlphare.com # this makes: mlphared.mtz mv mlphared.mtz mtz/mlphare.mtz # now you want to do some solvent-flattening/histogram matching in dm # do do a 45%-solvent run on the results of the above mlphare script, # do this: scripts/dm.com mtz/mlphare.mtz 45% >! logs/dm_50.log # this makes: dmed.mtz mv dmed.mtz mtz/dm_45.mtz # you can do other solvent contents by re-running dm.com with 50%, 30%, etc. # also, if you want to flatten a particular data set, just # mention its name on the dm.com command line: dm.com Fpp 45% ... # it shouldn't be hard to edit dm.com and add NCS operators # to view the electron density map, you need to do an fft: scripts/fft.com mtz/dm_50.mtz >! logs/fft.log # this makes: # ffted.map - CCP4 asymmetric unit of phased electron density # ffted.omap - o version, extended over 1.7 unit cells # bones.o - "bones" trace of ffted.omap # fftpick.pdb - peak-pick of ffted.omap (something to cen_id on in o) # ffted.omac - o macro for loading and viewing all of the above # also, if you want to do a phased difference Fourier, for picking up # new sites, the bestFH.com script will do this for you as well: scripts/bestFH.com mtz/dm_45.mtz # will produce the usual FH.mtz, etc. but will also use PHIDM and FOMDM to # make: FH_Four.map mv FH_Four.map maps/FH_Four.map # this should be the "best" estimate of a phased difference map of FH, # as opposed to Dano or Diso from a particular data set. If you want to # use FOM instead of FOMDM, or PHIB instead of PHIDM, just mention their # names on the bestFH.com command line # you can view maps/FH_Four.map in o by doing this: scripts/fft.com maps/FH_Four.map >! logs/fft.log # now ffted.omap will be an o map of FH, phased with PHIDM # to pick out "new" peaks from FH_Four.map (that is, peaks that are not # already explained by refined sites in mlphare.com), do this: scripts/pick.com maps/FH_Four.map 4 sigma scripts/mlphare.com # this makes: pick.pdb # pick.pdb contains unique peaks with height > 4*sigma that are not already # symmetry mates of the atoms in scripts/mlphare.com. map-edge peaks are # automatically avoided by pick.com, and special positions will be flagged # by a occupancy < 1 in pick.pdb # if you run Phaser Elves, they will automatically add these difference peaks # to scripts/mlphare.com, and keep refining. # NB: Processer Elves create a directory called "./phaser/" in which, you # will find subdirectories named for different space groups. Processer then # performs a separate Phaser run in each of these space groups, and there # will be a complete set of Phaser scripts in each of these directories wARP: ############################################################################### # Elves currently only do a partial set-up of ARP/wARP cd wARP # run this if you havn't already set-up ARP/wARP #arp_warp_setup.sh # Answer the questionaire # Suggestions: # for "data file" use ../mtz/best_phased.mtz # for "total cycles of arp/warp" use 100 # for "cycles between rebuilding" use 10 # for "multiple free atom models" say "Y" if you have .rhosts set up # for "REFMAC protocols" use "R" (or P if you have good phases) # alternately, you can use the Elven set-up script. Just provide your # phased mtz file on the command line setup_warp.com best_phased.mtz # or, you can provide an unphased mtz and a "starting" pdb file (such as # a molecular replacement solution) #setup_warp.com ../mtz/all.mtz ../EPMR/best.pdb # run this if you have multi-model stuff set-up in warp.par #arp_warp.sh mode warp >! warp1.log # remember, you must not log off of the terminal you launch the above # command from! A deluge of refmac jobs will result if you do. # this is really cool, if you have the resolution for it... if(-e seq.pir) then # if you gave Elves a sequence at the beginning, you can run: arp_warp.sh mode warpNtrace side >! warpNtrace1.log else # no side-chain building/tracing arp_warp.sh mode warpNtrace >! warpNtrace1.log endif cd .. Refmacer: ############################################################################### # Elves can also do a partial set-up of protin/refmac/arp if you give them # a pdb and mtz to start with mkdir refmac cd refmac # this "elf" will set-up refmac from the results of wARP ../Elfsheim/Refmacer ../wARP/files/warpNtrace.brk ../mtz/best_phased.mtz # this makes: # scripts/refmac.com - protin/refmac script # scripts/maps.com - fft script for making maps for arp_warp and o # scripts/arp.com - arp_warp water-building script # scripts/converge.com - run the above three scripts with convergence criteria # scripts/rmsd - jiffy for getting rmsd shift between two pdbs # scripts/Rplot.com - jiffy for watching R-factors in xloggraph # scripts/Drift.com - jiffy for watching pdb shifts in xloggraph # the directories: # pdb - will contain the refmac/arp results # logs - will contain the log files # maps - will contain the sigmaa maps from refmac # the converge.com script is smart enough to pick up where it left off. # in normal running you will get things like pdb/refmac123.pdb # running scripts/converge.com pdb/refmac123.pdb will start numbering # new pdbs at 124, etc... scripts/converge.com pdb/starthere.pdb >! converge1.log cd .. # this is as far as Elves 0.x will get you. # automated building and rebuilding are in the works for Elves 1.x # to help you in getting your paper written, Elves have also provided you with: scripts/table1.com # this will generate a basic table of data-reduction and model refinement # stats (which usually appears as "Table 1" in crystallographic papers) # to specify which log files you want to use for the statistics, just list # them on the table1.com command line: # i.e. scripts/table1.com phaser/P212121/logs/mlphare.log refmac/logs/refmac534.log EOF-guide.com chmod a+x ${SCRIPT_dir}/guide.com ######################################## # create the "Table 1" sumarizing script cat << EOF-table1.com >! ${SCRIPT_dir}/table1.com #! /bin/csh -f # # Script for quickly assembling vital crystallographic data # from an Elves data-processing directory tree. # # dataset wavelength resolution # set nawk = /usr/bin/nawk \$nawk 'BEGIN{exit}' >& /dev/null if(\$status) set nawk = awk alias nawk \$nawk set outfile = table1.txt set runlist = ./runlist.txt set mlpharelog = logs/mlphare.log set refmaclog = logs/refmac.log set best_phased = mtz/best_phased.mtz set completemtzfile = mtz/all.mtz set tempfile = /tmp/table1_temp if(\$#argv != 0) goto Setup Help: ############################################################################### cat << EOF usage: table1.com runlist.txt mlphare.log refmac.log best_phased.mtz runlist.txt - scala "run" file written by Scaler Elves mlphare.log - final mlphare log output refmac.log - final refmac log best_phased.mtz - final, phased mtz from solvent-flattening EOF goto Setup ############################################################################### Return_from_Setup: echo -n "" >! \${tempfile}dummy # start with the runlist.txt file, it contains all the dataset names if(-e \$runlist) then set wavenames = \`nawk '\$2=="wavelength"{print \$3}' \$runlist \` set wavelengths = \`nawk '\$2=="wavelength"{print \$5}' \$runlist \` else # assume this is a wedger run? echo "single-wedge run." set wavenames = "" set wavelengths = "" endif set i = 0 echo "" >! \${tempfile}info while ( \$i < \$#wavenames ) @ i = ( \$i + 1 ) # get a name for this dataset set name = "\$wavenames[\$i]" set mergelog = "logs/merge_\${name}.log" if("\$name" == "") set mergelog = "logs/merge.log" if(! -e "\$mergelog") then # look for any scala output set files = \`find . -name '*.log' -type f -exec grep -q "SCALA - continuous scaling program" \\{\\} \\; -print\` set mergelog = \`ls -1rt \$files | grep merge | tail -1\` if(! -e "\$mergelog") set mergelog = \`ls -1rt \$files | tail -1\` endif if(! -e "\$mergelog") set mergelog = "logs/merge.log" echo "reading \$mergelog" # try to find wavelengths if we don't know them if("\$wavelengths" == "" && -e "mosflm.com") set wavelengths = \`awk '/WAVE/{print \$2}' mosflm.com | tail -1\` if("\$wavelengths" == "" && -e "raw.mtz") set wavelengths = \`echo "BATCH" | mtzdump HKLIN raw.mtz |& awk '/Wavelength/{print \$5}' | tail -1\` if("\$wavelengths" == "") set wavelengths = "unknown" # put this name into the general "info" file echo "NAME \$name" >> \${tempfile}info echo "WAVE \$wavelengths[\$i]" >> \${tempfile}info # signal info from the final, mergeing step cat \$mergelog |\\ nawk '\$3 == "Dmin(A)" {graph=1; title=\$0} \\ graph==1 && \$1+0>0{if(title){print title; title=""}; print}\\ \$1=="Overall:"{print; graph=0}' |\\ nawk 'NR<2{print} \$1+0>0{store=\$0} /Overall/{print store; print}' |\\ nawk '\$1+0!=0{print "RMERGE", \$3, \$4;\\ print "RANOM", \$3, \$7;\\ print "SIGNAL", \$3, substr(\$0,81,7)} \\ /Overall/{print "RMERGE all", \$2;\\ print "RANOM all", \$5;\\ print "SIGNAL all", substr(\$0,81,7)}' |\\ cat >> \${tempfile}info # get resolution limits cat \$mergelog |\\ nawk '/Overall resolution limits:/{print "RESO", \$5+0, \$4+0}' |\\ cat >> \${tempfile}info # data completeness, and multiplicity cat \$mergelog |\\ nawk '/Completeness v Resolution/,/Overall/{print}' |\\ nawk '\$1+0>1 && ! /\\*\\*\\*\\*\\*/{print "COMPL", \$7; print "MULT", \$9} \\ /Overall/ && ! /\\*\\*\\*\\*\\*/{print "COMPL all", \$5; print "MULT all", \$7;} \\ \$1+0>1 && /\\*\\*\\*\\*\\*\\*\\*/{print "MULT", \$7} \\ /Overall/ && /\\*\\*\\*\\*\\*\\*/{print "MULT all", \$5;}' |\\ cat >> \${tempfile}info # Wilson B cat \$mergelog |\\ nawk '/squares straight/{print "WILSON", \$8}' |\\ cat >> \${tempfile}info # better indication of completeness if(! -e "\$completemtzfile") set completemtzfile = mtz/all.mtz if(! -e "\$completemtzfile") set completemtzfile = merged.mtz echo "go" | mtzdump hklin \$completemtzfile |\\ nawk '/OVERALL FILE STATISTICS/,/No. of reflections used/' |\\ nawk -v name=\$name '\$NF==name{COMPL = substr(\$0,32)+0} \\ \$NF=="F"{print "COMPL F", substr(\$0,32)+0}\\ \$NF=="FreeR_flag"{unique=1}\\ END{if(unique) print "COMPL all", COMPL}' |\\ cat >> \${tempfile}info end ############################################# # get phasing stats from an mlphare run that finished egrep "^ ATOM" "\$mlpharelog" >& /dev/null if(\$status) then egrep "^ ATOM" "\${mlpharelog}.old" >& /dev/null if(! \$status) set mlpharelog = \${mlpharelog}.old endif egrep "^ ATOM" "\$mlpharelog" >& /dev/null if(\$status) then # maybe its somewhere else? echo "looking for an mlphare log" set possibilities = \`find . -name mlphare.log'*' | head -20\` if("\$possibilities" == "") set possibilities = \`ls logs/*\` ls -ldt \$possibilities |\\ nawk '/^-/{if(! system("egrep -l \\"^ ATOM\\" " \$NF)){exit}}' |\\ cat >! \${tempfile}.log set mlpharelog = \`head -1 \${tempfile}.log\` if("\$mlpharelog" == "") then echo "none found." set mlpharelog = \${tempfile}dummy else echo "\$mlpharelog" endif rm -f \${tempfile}.log >& /dev/null endif # deal with what we got cat \$mlpharelog |\\ nawk '/LABIN/{printf substr(\$0, 15); while(getline){\\ if(\$1 != "Data"){printf substr(\$0, 2)}else{break}}}' |\\ nawk 'BEGIN{RS=" "; ORS=" "} NF != 0' |\\ nawk 'BEGIN{RS=" "} /^FPH/{\\ print "DERIVATIVE", substr(\$1, 4)+0, substr(\$1, 6)}' |\\ cat >! \${tempfile}names # get number of sites in each derivative # now get phasing power for each derivative cat \$mlpharelog |\\ nawk '/Analysis of Derivative/{deriv=substr(\$0,match(\$0,"[0-9]"))+0;print}\\ /FH_a_rl FH_a_imag/{fh=1;print} \\ /LOC_a PhP_a /{p_r=1;print} \\ /calc LOC_ano/{p_i=1;print} \\ /TOTAL/ && p_r {ppow_r[deriv]=\$5;p_r=0;print}\\ /TOTAL/ && fh {fh_a=\$6;fh=0;print}\\ /TOTAL/ && p_i {if(\$5+0==0) \$5=999999; print;\\ ppow_i[deriv]=sprintf("%.2f",fh_a/\$5);p_i=0}\\ END{for(deriv in ppow_r) print deriv, ppow_r[deriv]+0, ppow_i[deriv]+0}' |\\ nawk 'NF==3' |\\ sort -n >! \${tempfile}powers cat \${tempfile}names \${tempfile}powers |\\ nawk '/^DERIV/{name[\$2]=\$3} ! /^DERIV/{print "PPOWER", name[\$1], \$2, \$3}' |\\ cat >> \${tempfile}info rm -f \${tempfile}powers \${tempfile}names >& /dev/null # might as well get FOM too cat \$mlpharelog |\\ nawk '/phased -ALL/{getline; getline; getline; \\ print "FOM", \$NF;}' |\\ tail -1 >> \${tempfile}info # and phasing resolution range cat \$mlpharelog |\\ nawk '/Resolution Range/{getline; getline; \\ print "FOM_RESO", \$4, \$6;}' |\\ tail -1 >> \${tempfile}info ###################################### # get solvent-flattened FOM from the phased MTZ file if(-e "\$best_phased") then echo "FOM from \$best_phased" echo "go" | mtzdump hklin \$best_phased |\\ nawk '/OVERALL FILE STATISTICS/,/LIST OF REFLECTIONS/' |\\ nawk '\$NF=="FOMDM" && NF>9{print "FOM_RESO",\$(NF-2),\$(NF-3);print "FOMDM", \$(NF-4)}\\ \$NF=="FOM" && NF>9{print "FOM_RESO",\$(NF-2),\$(NF-3);print "FOM", \$(NF-4)}' |\\ cat >> \${tempfile}info endif ####################################### # get R/Rfree delta-bonds, and delta-angles from refmac log? egrep -l "all[_ ]R[_ ]factor" "\$refmaclog" >& /dev/null if(\$status) then # maybe its somewhere else? echo "looking for a refmac log" set possibilities = \`find . -name refmac'*'.log | head -20\` if(("\$possibilities" == "")&&(-e wARP/logs)) set possibilities = \`ls -1t wARP/logs/*\` if("\$possibilities" == "") set possibilities = \`ls -1t logs/*\` ls -ldt \$possibilities |\\ nawk '/^-/{if(! system("egrep -l \\"all[_ ]R[_ ]factor\\" " \$NF)){exit}}' |\\ cat >! \${tempfile}.log set refmaclog = \`head -1 \${tempfile}.log\` if("\$refmaclog" == "") then echo "none found." set refmaclog = \${tempfile}dummy else echo "\$refmaclog" endif rm -f \${tempfile}.log >& /dev/null endif echo "R factors from \$refmaclog" cat "\$refmaclog" |\\ nawk '/all[_ ]R[_ ]factor/{print "RCRYST", \$NF}\\ /ee[_ ]R[_ ]factor/ && ! /DPI/{print "RFREE", \$NF}\\ /Estimated bond angle/{print "RMSD_angles", angles, \$NF}\\ /Estimated bond angle/{print "RMSD_angles", angles, \$NF}\\ /NUMBER DIST DELTA/{getline; print "RMSD_bonds", \$5}\\ /Bond distances: refined atoms/{print "RMSD_bonds",\$6} \\ /Bond angles : refined atoms/{print "RMSD_angles",\$7} \\ /Resolution Range/{getline; getline; \\ print "R_RESO", \$4, \$6;}' |\\ cat >> \${tempfile}info # get R/Rfree delta-bonds, and delta-angles from pdb file? # average B-factor? ############################################################################ # export formatting awk program cat << EOF >! \${tempfile}table1.awk #! \$nawk -f # # awk program for formatting "table-1" statistics # # BEGIN{ FOM=FOMDM=Rcryst=Rfree=RMSD_bonds=RMSD_angles="?"; ANG="\\\\305"; DEG="\\\\260"; ANG="A"; DEG="deg"; } /^NAME/{ ++sets; dataset=\\\$2; Set[sets]=\\\$2; Ppow_r[\\\$2]="n"; Ppow_i[\\\$2]="a"; } /^WAVE/{wave[dataset]=sprintf("%.4f",\\\$2)} /^RMERGE/ && \\\$2=="all"{Rmerge[dataset]=\\\$3} /^RMERGE/ && \\\$2+0>0 {Rmerge_hires[dataset]=sprintf("%.2f", \\\$3)} /^RANOM/ && \\\$2=="all"{Ranom[dataset]=\\\$3} /^RANOM/ && \\\$2+0>0 {Ranom_hires[dataset]=\\\$3} /^SIGNAL/ && \\\$2=="all"{signal[dataset]=\\\$3} /^SIGNAL/ && \\\$2+0>0 {signal_hires[dataset]=\\\$3} /^COMP/ && \\\$2=="all" {comp[dataset]=sprintf("%.1f", \\\$3)} /^COMP/ && \\\$2=="F" {comp[dataset]=sprintf("%.1f", \\\$3)} /^COMP/ && \\\$2+0>0 {comp_hires[dataset]=sprintf("%.1f", \\\$2)} /^MULT/ && \\\$2=="all" {mult[dataset]=\\\$3} /^MULT/ && \\\$2+0>0 {mult_hires[dataset]=\\\$2} /^RESO/ {reso[dataset]=\\\$2} /^RESO/ {lores[dataset]=\\\$3} /^WILS/ {wilson[dataset]=\\\$2} /^FOM / {FOM=\\\$2} /^FOMDM/{FOMDM=\\\$2} /^FOM_RES/ {FOM_loRES=\\\$2; FOM_hiRES=\\\$3} /^PPOWER/{Ppow_r[\\\$2]=\\\$3; Ppow_i[\\\$2]=\\\$4} /^RCRYST/{Rcryst=sprintf("%.3f",\\\$2)} /^RFREE/{Rfree=sprintf("%.3f",\\\$2)} /^R_RESO/{Rfac_loRES = \\\$2; Rfac_hiRES = \\\$3} /^RMSD_bond/{RMSD_bonds = \\\$2} /^RMSD_ang/{RMSD_angles = \\\$2} END{ printf "%-17s", "Data Set:"; for(i=1;i<=sets;++i){printf "%13s ", Set[i];} print ""; printf "%-17s", "Wavelength, " ANG; for(i=1;i<=sets;++i){printf "%13s ", wave[Set[i]]}; print ""; printf "%-17s", "Resolution, " ANG; for(i=1;i<=sets;++i){printf "%13s ", reso[Set[i]]}; print ""; printf "%-17s", "Rsym"; for(i=1;i<=sets;++i){printf "%13s ", Rmerge[Set[i]] "(" Rmerge_hires[Set[i]] ")"}; print ""; printf "%-17s", "Completeness, %"; for(i=1;i<=sets;++i){printf "%13s ", comp[Set[i]] "(" comp_hires[Set[i]] ")"}; print ""; printf "%-17s", "Multiplicity"; for(i=1;i<=sets;++i){printf "%13s ", mult[Set[i]] "(" mult_hires[Set[i]] ")"}; print ""; printf "%-17s", "I/SD"; for(i=1;i<=sets;++i){printf "%13s ", signal[Set[i]] "(" signal_hires[Set[i]] ")"}; print ""; printf "%-17s", "Phasing Power"; for(i=1;i<=sets;++i){printf "%13s ", Ppow_r[Set[i]] "/" Ppow_i[Set[i]]}; print ""; printf "Mean figure of merit (%.1f-%.1f "ANG" resolution): %s (%s after solvent flattening)\\\\n", FOM_loRES, FOM_hiRES, FOM, FOMDM; printf "Rcryst/Rfree (%.0f-%s "ANG"): %s/%s.\\\\n", Rfac_loRES, Rfac_hiRES+0, Rcryst, Rfree; printf "rms delta-bonds, rms delta-angles: %s "ANG", %s"DEG".\\\\n", RMSD_bonds, RMSD_angles; } EOF cat << EOF Table 1: Data collection, phasing, and refinement statistics EOF # print out a nice table cat \${tempfile}info |\\ nawk -f \${tempfile}table1.awk # obligatory footer cat << EOF Rsym = sum(|I-|)/sum(I); I, intensity. I, intensity; SD, standard deviation. Parentheses denote I/SD for highest resolution bin. Phasing power, (dis/ano) = [sum(|FH|^2)/sum(|E|^2)]^(1/2); FH, calculated heavy-atom scattering factor; E, lack-of-closure error. Mean figure of merit = <|| sum(P(alpha)e^i*alpha)/sum(P(alpha)) ||>; alpha, phase; P(alpha), phase probability distribution. Rcryst = sum(|Fobs - Fcalc|)/sum(Fobs); Fobs, observed structure-factor amplitude; Fcalc, calculated structure-factor amplitude. rms deviations from ideal values. EOF rm -f \${tempfile}table1.awk \${tempfile}info \${tempfile}dummy >& /dev/null exit Setup: ################################################################################ foreach arg ( \$* ) if(! -e "\$arg") then echo "WARNING: \$arg does not exist." continue endif # see if its an mtz file if("\$arg" =~ *.mtz) then set best_phased = "\$arg" set completemtzfile = "\$arg" continue endif # see if its an mlphare log egrep -l "FH_a_rl FH_a_imag" \$arg >& /dev/null if(! \$status) then set mlpharelog = "\$arg" continue endif # see if its a refmac log egrep -l "ee[_ ]R[_ ]factor" \$arg >& /dev/null if(! \$status) then set refmaclog = "\$arg" continue endif # see if its a runlist.txt set temp = \`nawk '\$2=="wavelength" && \$NF=="eV"' \$arg\` if("\$temp" != "") then set runlist = "\$arg" continue endif echo "WARNING: unable to identify \$arg" end goto Return_from_Setup EOF-table1.com chmod a+x ${SCRIPT_dir}/table1.com # dummy, for terminating list cat << EOF-nothing >> /dev/null EOF-nothing ######################################## # create the README file for the root directory cat << EOF-README.Elves >! README.Elves The Elves' quick guide to their scripts 1) In a rush? Just type this: ./Elfsheim/Processer hurry >&! process1.log & That's it. If you're in a BIG hurry, and you have several CPUs at your disposal, you can use all your CPUs in parallel: ./Elfsheim/Processer hurry >&! process1.log & ssh anothermachine cd `pwd` ./Elfsheim/Processer hurry >&! process2.log & ./Elfsheim/Processer hurry >&! process3.log & ./Elfsheim/Processer hurry >&! process4.log & etc.. each "Processer" will take full advantage of one CPU. As long as the Processers are all launched in the same directory, no matter what computer system they are on, they will cooperate with each other, and, eventually, process all your data. 2) Okay, how does it work? The Processer Elves will run: 1) Wedger Elves for each of your data wedges 2) Scaler Elves on all the raw intensity data 3) SHELX and/or SOLVE on the datasets output from Scaler 4) Phaser Elves on the resulting heavy-atom positions 5) ARP/wARP on the "best" phased mtz from Phaser (resolution permitting) in the ./Elfsheim directory... ################################################################################ sendhome reads: x-ray images, as they appear writes: senthome.log runs: ssh, tar, compress, uncompress output: x-ray images (on a remote filesystem) example: sendhome /data/se1_1_001.img user@remote.college.edu:/bigdisk/user - will send /data/se1_1_001.img (and any other frames in /data that are newer than se1_1_001.img) to /bigdisk/user using "user"'s account on remote.college.edu. description: sendhome is designed specifically for crystallographers collecting x-ray image data that they want to send to another computer (home). The file transfer is done via an ssh (version 1 or 2) login session, so broadcasting your password is no longer a concern. The frames are compressed in transit, so sendhome is ~3X faster than FTP, and sendhome continuously monitors the disk for newly-collected images, and sends them as soon as they appear, allowing you to concentrate on data collection, instead of backups. Also, once sendhome is running, you can and "bg" the job, and then log out and go home yourself. sendhome will timeout and exit if no new frames have appeared after 2 hours. If the transfer is ever interrupted, you can usually re-start sendhome with just a directory name, it will read the senthome.log file, and pick up where it left off. WARNING: if you kill sendhome your last file may not be completely transferred. Because of a quirk in unix pipes, the last kilobyte or so of your last frame will not be sent until sendhome exits normally. If running interactively, sendhome will warn you about this, and offer to transfer the last file explicitly before exiting from a . note: to send home a processing directory, type something like this: cd /local/processing tar cBf - . | compress | ssh user@home.college.edu "cd /home/processing ; uncompress | tar xvBf -" ################################################################################ Wedger Elves - single-wedge x-ray image data processer reads: x-ray images (ADSC Q4, MAR, R-axis II & IV, and others) mosflm scripts and script fragments mosflm orientation matrix files denzo *.x and input files writes: mosflm.com - a simple script for running ipmosflm on your data merge.com - a simple scala/truncate mergeing script SGsearch.com - routine for running merge.com in alternative space groups autoscala - routine for optimizing SDCORR in merge.com autoindex.inp - script fragment for setting up autoindexing manually patt.com - simple difference-Patterson script runs: ipmosflm (merge.com needs CCP4) output: raw.mtz - raw intensity data in multirecord mtz format merged.mtz - scaled and merged reflection examples: Wedger /data/frames/Se1_1_001.img - set-up mosflm.com for wedge beginning with Se1_1_001.img Wedger /data/frames/Se1_ - set-up mosflm.com for files matching /data/frames/Se1_* Wedger ./start -new - read the ./start script fragment, and don't look for other files Wedger mosflm.com - pick up processing where mosflm.com left off Wedger auto.x - start processing from a denzo indexing solution description: Wedger Elves are capable of everything from autoindexing to scaling and mergeing of single-wedge x-ray diffraction image data. If you have multiple wedges, you should process each of them with Wedger, and then combine the output files with Scaler Elves (below). Wedger Elves run mosflm to index and process x-ray images, and are designed to teach you how to use mosflm as you are processing your data. If you do not have mosflm 6.x, then Wedger Elves can go get it for you. ################################################################################ Spotter Elves - easy access to important spots reads: x-ray images (ADSC Q4, R-axis II & IV only) scala logs denzo *.x files and scalepack logs writes: moviefy - movie-maker engine absences.moviekey - textual index of the extracted spot images rejects.moviekey - textual index of the extracted spot images runs: adsc2pgm, osc2pgm (or embedded backup) ImageMagick (convert, mogrify, animate) dmconvert (SGI only) output: absences.movie - SGI movie of systematic absence observations absences.gif - animated GIF equivalent of the above (ImageMagick required) rejects.movie - SGI movie of rejected observations from scaling rejects.gif - animated GIF equivalent of the above (ImageMagick required) examples: Spotter logs/merge.log /data/frames/Se1_1_001.img - display rejected outliers and systematic absence observations from the original images, beginning with Se1_1_001.img Spotter scalepack.log - display rejected outliers and systematic absence observations from the original images listed in the *.x files description: The version of Spotter Elves that ships with Elves 0.9 will only work on SGIs, and can only use R-axis and ADSC Q4 type images. ################################################################################ Scaler Elves - multi-wedge, multi-wavelength localscaling reads: */*/raw.mtz (unmerged, multibatch mtz files) scala scripts and script fragments denzo *.x files writes: sort_everything.com - script for combining all input data into a single, multirecord mtz file (regardless of batch numbers) make_reference_set.com - scale and merge a reference data set. import_reference.com - combine a merged reference with the raw data. rough_scale.com - batch-wise, initial scaling pass localscale.com - smooth, continuous scaling procedure merge.com - merge one of the wavelengths after scaling extract.com - extract a wavelength without mergeing it scaleit.com - combine merged wavelengths into one mtz file FreeRer.com - like "uniqueify", but can "inherit" a Free-R set from another file autoscala - routine for optimizing SDCORR in a scala script runlist.txt - scala script fragment, defining "runs" and "wavelengths" (runs merged together) Makefile - a "make" file for using "make" to rebuild your scaling project with the above scripts runs: scala, truncate, scaleit, cad, mtzutils, etc... setup: solve, shelx, x-plor output: mtz/all.mtz - multi-column mtz file (for mlphare or SHARP) SOLVE/*.fmt - data formatted for input into solve SHELX/*.hkl - data formatted for input into shelx XPLOR/*.fobs - data formatted for input into x-plor/cns examples: Scaler */*/raw.mtz - set-up mosflm.com for wedge beginning with Se1_1_001.img Scaler */*/raw.mtz with 8 Se sites in ~/protein.seq - same thing, but use site and protein sequence data for solve and truncate Scaler *.x - use the denzo data in *.x files (york or default format okay) Scaler runlist.txt cards.txt - pick up processing after editing the "run" definitions in runlist.txt, and using the scala commands in cards.txt description: Scaler Elves are an adaptive implementation of the "MAD scaling" procedure outlined in the scala manual. They easily handle multiple input files, and they make sure none of the batch numbers overlap. Scaler Elves can carry out the scaling for you (they know how to fix the most common problems), or you can take over scaling yourself by editing and running the above scripts. Scaler Elves write a relatively large number of scripts, and so, a Makefile is included to run them all intelligently. All you have to do is type "make" and any changes you made to the scripts will be applied. ################################################################################ Phaser Elves - general heavy-atom phasing/solvent flattening reads: merged, multi-column mtz data solve.status file shelx.res files sites.pdb files (heavy atom sites) random.txt (fractional coordinates in "0.000 0.000 0.000" format) writes: mlphare.com - simple mlphare script for refining sites against data dm.com - basic dm script for solvent-flattening fft.com - "smart" fft script for calculating/converting maps bestFH.com - procedure for combining all difference data to estimate FH reindex.com - general mtz re-indexing procedure (includes P2212, etc.) shelx.com - combinatorial shelx-running script (try different combinations of space group, resolution, cutoffs) rantan.com - same thing, but uses rantan instead of shelx pick.com - sophisticated map-peak-picker (allows "taboo" sites to be specified) runs: mlphare, dm, rantan, shelx, rsps, vecref, fft, peakmax output: mlphare.mtz - result of mlphare run dm_??.mtz - result of solvent flattening at ??% solvent phased.map - examples: Phaser mtz/all.mtz SOLVE/P2212/solve.status P2212 - run mlphare on all.mtz, using the sites found by solve in P2212 Phaser mtz/all.mtz SHELX/ano.res - refine sites found by shelx in ano.res Phaser mtz/all.mtz - find some heavy-atom sites with shelx or rantan, then start refining them against all.mtz data Phaser mtz/all.mtz -new - start over, don't try to restart with an old mlphare.com, etc. Phaser scripts/mlphare.com no flip sg - pick up where we left off in scripts/mlphare.com, but don't flip between alternative space groups. (you can also say: "no flip hand", "no flip occ", or just "no flip") Phaser scripts/mlphare.com no add 40% 45% 50% - same thing, but don't add difference-Fourier peaks back into mlphare.com. Also solvent contents of 0.4 0.45 and 0.5 will be tried in dm. description: Phaser Elves obtain heavy-atom sites either by running shelx, rantan or rsps, or by get them from a solve.status file, pdb file, res file, or just a plain text file with three decimal numbers on each line. Sites are refined against mtz data with mlphare, and the results are solvent-flattened with dm. Multiple solvent contents can be tried if you're not sure of your crystal density. Alternative choices of occupancy sign, site hand and space group are also explored by Phaser Elves. Atoms that refine to unrealistic parameter values (occ near 0, B>500) are automatically rejected from the mlphare script. (This behavior can be overriden by stating "no reject", but it is not recommended) Once everything is refined, Phaser Elves will calculate a phased difference Fourier (combining all your difference data) and look for potential new sites. By default, these new sites are added to the mlphare script, and refinement continues until no novel peaks appear in the difference Fouriers. ################################################################################ Processer Elves reads: contents of wedge directories writes: "busy" and "done" signals for other Processer jobs runs: Wedger, Scaler, shelx, solve, Phaser, wARP examples: Processer >&! processing.log & - launch Processer in the background. Any existing wedge directories will be processed automatically. All space-groups that have been set-up in SOLVE or SHELX will also be processed. Processer hurry >&! processing.log & - tell Processer (and all the Elves it runs) to "hurry", skiping most optimization steps, and getting to a rough solution as quickly as possible. Processer fpp/wedge* lo/wedge* >&! processing.log & - tell Processer to only work on the specified directories (useful if you think one of your wavelengths is badly decayed) Processer no solve - tell Processer to quit after scaling and mergeing the data. Processer solve only - tell Processer to jump immediately to the SOLVE and SHELX stage. description: Processer Elves will eventuall be incorperated into the Elves main program. But, for now, you should use them to automate everything but the initial set-up and indexing stages of your project. Once you have a directory structure of */wedge*, SOLVE/*/ SHELX/*, etc. Processer Elves are designed to move through these directories, processing data as they go. If you launch more than one Processer job in the same, root working directory, the jobs will cooperate with each other, each working on a different part of your project at the same time, and completing the whole data-processing task in proportionately less time. If you have access to your processing directory tree from another computer, you can run Processers on remote CPUs too. Processer Elves can still coordinate their efforts from an arbitrary number of different computers. ################################################################################ ################################################################################ 3) What if something goes wrong? The Elves main program is desiged to handle a number of common problems encountered in processing x-ray data. However, they are certainly not capable of handling EVERY situation that might crop up. If you have problems with the Elves main program, there are a series of fallback positions you can take: A. Problems with integration 1. Go through all your data wedge directories yourself. Use Wedger interactively until you see accurate spot predictions for each wedge. 2. Then go back to the root directory, and run Processer to tune everything up. B. Problems with how Processer processes your data 1. If you don't like the way Processer does things, you can always run the Elves manually: Wedger, Scaler and Phaser are all a lot more user-friendly and customizable that Processer Elves. Wedger should br run in the wedge directories themselves. Scaler and Phaser Elves can be run from just about anywhere. C. Problems with how Elves process your data 2. The script: ${SCRIPT_dir}guide.com is intended to guide you through the entire data-processing chain, but by running the scripts Elves wrote directly (no automation). All of these scripts have been desiged to be easily read, edited, and re-run by end-users. README files have also been written to guide you. EOF-README.Elves goto ReturnFrom_Deploy_Elves exit ###################### TODO: shelx/rantan scripts? migrate SOLVE/SHELX set-up to here? mtz2sNb.com? The Future: single-frame strategy option use ginger better CUI more testing port filesystem framesearch ############################################################## # go to: # http://ucxray.berkeley.edu/~jamesh/elves/session.html # to figure out what to do with this file ##############################################################