#!/bin/bash

# (c) early 2000---2022/03/18: WGHTFIX (S. Parkin, University of Kentucky)
# A bash script to optimize the weighting scheme used in SHELXL20XX by iterating  
# runs of SHELXL with cut/paste editing of the .res/.ins files.  Based on an old 
# csh script from about the year 2000 for SHELXL97. It first copies the old .res 
# and .hkl files to temporary files, changes the L.S. instruction to perform two 
# cycles of least-squares refinement and changes the WGHT command to the new one
# that SHELXL puts near the end of the previously written res file. It then runs
# SHELXL using the temporary files for a number of iterations while updating the 
# WGHT instruction for each round.  Now properly deals with structures that have 
# been treated with Ton Spek's SQUEEZE process. The default number of iterations 
# is five but this can be changed on the command line as follows:
#
# wghtfix filename x
#
# Where 'x' is an (optional) integer.  After running the given number of rounds, 
# the script puts the optimized weighting scheme back into the original res file 
# and runs a SHELXL refinement job (using the original L.S. line of course). The 
# version here uses the regular SHELXL2019/2 for the optimization steps but uses 
# the 'shelxl-launcher' script to run the final rounds of refinement in order to 
# get RT, ciffix, and ciftab-automator to run.
#
echo
echo " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
echo " +  WGHTFIX  Optimization of SHELXL weighting scheme  OSX & Linux  +"
echo " +  (c) Sean Parkin ~2000---2022/03/18   Version for SHELXL2019/2  +"
echo " +  Recycles Sheldrick's SHELXL to optimize the weighting scheme.  +"
echo " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

# Check the input to ensure that a filename has been supplied. If it hasn't then 
# write a helpful message. If the number of iterations is not given then use the 
# default of 5.
#
if [ "$1" == "" ]; then
  echo
  echo " This script is run as follows (where 'x' is an optional integer): "
  echo
  echo "    wghtfix filename x"
  echo
  exit
fi
if [ "$2" == "" ]; then
  iterations=5
else
  iterations=$2
fi

# Change the IFS to prevent collapsing multiple spaces down to a single space.
#
IFS='#'

# For the sake of safety, the optimization is done using temporary copies of the 
# structure files. For the temporary .res file use two cycles of refinement. For 
# the WGHT optimization cycles, there is no need to write a .cif or .fcf file so 
# these are REM'd out. NOTE: It looks as though SHELXL20XY writes a .fcf file no 
# matter what.  Oh well, no big deal.
#
cp $1.hkl temp.hkl
old_ls=$(grep -iF L.S. $1.res)
sed "s/$old_ls/L.S. 2/;s/ACTA/REM ACTA/;s/LIST/REM LIST/" $1.res > temp.res
# If the structure used Ton Spek's SQUEEZE routine, then we also need to write a 
# temporary copy of the *.fab file.  NOTE: temp files are deleted at the end. 
if [ -f $1.fab ]; then
  cp $1.fab temp.fab
fi

# Get the initial weighting scheme and write it to the screen.  NOTE: grep needs 
# the caret (^) here so that it only looks for WGHT at the beginning of a line.
#
init_wght=$(grep -i -m1 ^WGHT temp.res)
echo
echo " The weighting scheme prior to optimization was: "
echo
echo "  "$init_wght
echo
echo " Iterative optimization of the weighting scheme follows: "
echo

# Run the specified number of iterations, each with two cycles of least squares, 
# and write the WGHT parameters out for each round. It should be easy to tell if 
# the weighting scheme optimization is converging as planned.  If not then run a 
# few more rounds. NOTE: In my set up, the executable for SHELXL-20XY/Z is named 
# 'shelxlXY.Z', where X, Y, and Z are integers.
#
for ((n=1; n <= "$iterations"; n++)); do
  old_wght=$(grep -i -m1 WGHT temp.res)
  new_wght=$(grep -i -m2 WGHT temp.res | tail -n1)
  old_wght_1=$(echo $old_wght | awk '{print $2}')
  old_wght_2=$(echo $old_wght | awk '{print $3}')
  new_wght_1=$(echo $new_wght | awk '{print $2}')
  new_wght_2=$(echo $new_wght | awk '{print $3}')
  if [ "$old_wght_2" == "" ]; then 
     old_wght_2="0.0000"
  fi
  if [ "$new_wght_2" == "" ]; then 
     new_wght_2="0.0000"
  fi
  new_wght="WGHT  $new_wght_1  $new_wght_2"
  sed "s/$old_wght/$new_wght/" temp.res > temp.ins

  shelxl19.2 temp > temp.out
echo "  Round $n:  WGHT  $new_wght_1  $new_wght_2"
done

# Put the optimized weighting scheme back into the original .res file, rename it 
# as a new .ins file and run a full refinement job using SHELXL. Then remove all 
# the temporary files. NOTE: In my set up, 'shelxl' is a launch script that does 
# a bunch of other things in addition to just running SHELXL.
#
sed "s/$init_wght/WGHT $new_wght_1 $new_wght_2/" $1.res > $1.ins

echo
echo " ... and now run SHELXL on structure $1 using the optimized weights."
shelxl $1

rm temp.*

