Generate XDS.INP
This script should be in your $PATH as "generate_XDS.INP"
#!/bin/bash # purpose: generate XDS.INP # revision 0.03 . Kay Diederichs 2/2010 # revision 0.04 . Kay Diederichs 26/4/2010 # tested with own and some JCSG datasets; only MARCCD, ADSC/SMV, PILATUS detectors; for other detectors, values must be manually filled in. # # usage: e.g. generate_XDS.INP.rc "frms/mydata_1_???.img" # make sure to have the two " ! # the ? are wildcards for the frame numbers. # # requirement for external programs(s): # - for MARCCD detectors the "catmar" binary (which can be downloaded from http://www.marresearch.com/download.html) must be in $PATH # - alternatively, the mccd_xdsparams.pl script (see http://strucbio.biologie.uni-konstanz.de/xdswiki/index.php/Mccd_xdsparams.pl ) will be used, courtesy of Ana Gonzalez. # # limitations: # - frame numbers are assumed to start with 1 and run consecutively # # known problems: # - for ADSC detectors, the ORGX and ORGY values are inaccurate; the "imgheader" program that I have delivers better values, but I don't know how and why. # # notes for debugging of the script: # - add the -v option to the first line, to see where an error occurs # - comment out the removal of tmp1 and tmp2 in the last line # # ====== Start of script ====== # # defaults: # DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX" ORGX=XXX ORGY=XXX DETECTOR_DISTANCE=XXX OSCILLATION_RANGE=XXX X_RAY_WAVELENGTH=XXX # see how we are called: NAME_TEMPLATE_OF_DATA_FRAMES="$1" # list frames matching the wildcards in NAME_TEMPLATE_OF_DATA_FRAMES ls -C1 $1 > tmp1 # set upper limit of DATA_RANGE to number of frames (see "limitations" above) DATA_RANGE=`wc -l tmp1 | awk '{print $1}'` # set upper limit of SPOT_RANGE to half of DATA_RANGE, but not less than 1 SPOT_RANGE=`echo "scale=0; $DATA_RANGE/2" | bc -l` SPOT_RANGE=`echo "if ($SPOT_RANGE<1) 1;if ($SPOT_RANGE>1) $SPOT_RANGE" | bc -l` echo DATA_RANGE=1 $DATA_RANGE # find out detector type DET=XXX strings `head -1 tmp1` | grep -q marccd && DET=mccd strings `head -1 tmp1` | grep -q PILATUS && DET=pilatus strings `head -1 tmp1` | grep -q BEAM_CENTER_X && DET=adsc # identify other detector types in the same way (MAR IP would be straightforward) # parse ASCII header of first frame (except for MARCCD, which therefore requires catmar) if [ "$DET" == "XXX" ]; then echo "this is not a MAR, ADSC/SMV or PILATUS detector - fill in XXX values manually!" DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX" # find parameters of first frame elif [ "$DET" == "mccd" ]; then DETECTOR="CCDCHESS MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000" echo this a a MARCCD detector if [ -e /usr/local/bin/catmar ]; then # inspect frame header and get rid of blanks in imgheader output: catmar `head -1 tmp1` | sed s/\ //g > tmp2 # find X_RAY_WAVELENGTH: X_RAY_WAVELENGTH=`grep Wavelength tmp2 | sed s/Wavelength.Ang]=//` # find QX, ORGX and ORGY: QX=`grep Pixelsizex tmp2 | sed s/Pixelsizex=//` NX=`grep pixelsin1line tmp2 | sed s/#pixelsin1line=//` ORGX=`grep Centerx tmp2 | sed s/Centerx=//` ORGX=`echo "scale=1; ($ORGX+50)/1000" | bc -l ` ORGY=`grep Centery tmp2 | sed s/Centery=//` ORGY=`echo "scale=1; ($ORGY+50)/1000" | bc -l ` # find DETECTOR_DISTANCE and OSCILLATION_RANGE: DETECTOR_DISTANCE=`grep Distance tmp2 | sed s/Distance.mm]=//` STARTING_PHI=`grep StartingPHI tmp2 | sed s/StartingPHI=//` ENDING_PHI=`grep EndingPHI tmp2 | sed s/EndingPHI=//` OSCILLATION_RANGE=`echo "scale=3; ($ENDING_PHI-$STARTING_PHI)/1000" | bc -l` else if [ -e /usr/local/bin/mccd_xdsparams.pl ]; then mccd_xdsparams.pl -v `head -1 tmp1` > tmp2 X_RAY_WAVELENGTH=`awk '/X-RAY_WAVELENGTH/{print $2}' tmp2` DETECTOR_DISTANCE=`awk '/DETECTOR_DISTANCE/{print $2}' tmp2` ORGX=`awk '/ORGX/{print $2}' tmp2` ORGY=`awk '/ORGY/{print $4}' tmp2` OSCILLATION_RANGE=`awk '/OSCILLATION_RANGE/{print $2}' tmp2` else echo "could not find /usr/local/bin/catmar - fill XXX values manually!" fi fi elif [ "$DET" == "adsc" ]; then DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000" echo this is an ADSC detector. there are at least two conventions strings `head -1 tmp1` | sed s/\;// > tmp2 # find X_RAY_WAVELENGTH: X_RAY_WAVELENGTH=`grep WAVELENGTH tmp2 | sed s/WAVELENGTH=//` # find NX, QX, ORGX and ORGY: NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//` QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//` ORGX=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//` ORGY=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`
- fix 2010-04-26 - tell user about possible alternatives
- according to Ingo Korndörfer, e.g. at ESRF ID29 the following should be used:
ORGX=`echo "scale=1; $ORGY/$QX" | bc -l ` ORGY=`echo "scale=1; $ORGX/$QX" | bc -l ` echo ATTENTION: at ESRF ID29 and other BLs use: ORGX=$ORGX ORGY=$ORGY (try these in XDS.INP !)
- whereas this alternative convention should be used at the following beamlines (pls complete the list): XXXXX
ORGX=`echo "scale=1; $ORGX/$QX" | bc -l ` ORGY=`echo "scale=1; $NX-$ORGY/$QX" | bc -l `
- the latter alternative is written into the generated XDS.INP
# find DETECTOR_DISTANCE and OSCILLATION_RANGE: DETECTOR_DISTANCE=`grep DISTANCE tmp2 | sed s/DISTANCE=//` OSCILLATION_RANGE=`grep OSC_RANGE tmp2 | sed s/OSC_RANGE=//` elif [ "$DET" == "pilatus" ]; then DETECTOR="DETECTOR=PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= 1048576" echo this is a Pilatus detector head -50 `head -1 tmp1` | sed s/#//> tmp2 # find X_RAY_WAVELENGTH: X_RAY_WAVELENGTH=`grep Wavelength tmp2 | sed -e s/Wavelength// -e s/A// | awk '{print $1}'` # find ORGX and ORGY: ORGX=`grep Beam_xy tmp2 | sed -e s/\(// -e s/\)// -e s/\,// | awk '{print $2}'` ORGY=`grep Beam_xy tmp2 | sed -e s/\(// -e s/\)// -e s/\,// | awk '{print $3}'` # find DETECTOR_DISTANCE and OSCILLATION_RANGE: DETECTOR_DISTANCE=`awk '/distance/{print $2}' tmp2` DETECTOR_DISTANCE=`echo "$DETECTOR_DISTANCE*1000" | bc -l` OSCILLATION_RANGE=`awk '/Angle/{print $2}' tmp2` else echo should never come here exit 1 fi echo ORGX= $ORGX ORGY= $ORGY - check these values with adxv ! echo DETECTOR_DISTANCE= $DETECTOR_DISTANCE echo OSCILLATION_RANGE= $OSCILLATION_RANGE echo X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH # now we know everything that is required to write XDS.INP cat >XDS.INP<<eof JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT ORGX= $ORGX ORGY= $ORGY ! check these values with adxv ! DETECTOR_DISTANCE= $DETECTOR_DISTANCE OSCILLATION_RANGE= $OSCILLATION_RANGE X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH NAME_TEMPLATE_OF_DATA_FRAMES=$NAME_TEMPLATE_OF_DATA_FRAMES DATA_RANGE=1 $DATA_RANGE SPOT_RANGE=1 $SPOT_RANGE # BACKGROUND_RANGE=1 10 ! rather use defaults (first 5 degree of rotation) SPACE_GROUP_NUMBER=0 ! 0 if unknown UNIT_CELL_CONSTANTS= 70 80 90 90 90 90 ! put correct values if known INCLUDE_RESOLUTION_RANGE=50 0 ! after CORRECT, insert high resol limit; re-run CORRECT FRIEDEL'S_LAW=FALSE ! This acts only on the CORRECT step ! If the anom signal turns out to be, or is known to be, very low or absent, ! use FRIEDEL'S_LAW=TRUE instead (or comment out the line); re-run CORRECT ! remove the "!" in the following line: ! STRICT_ABSORPTION_CORRECTION=TRUE ! if the anomalous signal is strong: in that case, in CORRECT.LP the three ! "CHI^2-VALUE OF FIT OF CORRECTION FACTORS" values are significantly> 1, e.g. 1.5 ! parameters with changes wrt default values: TRUSTED_REGION=0.00 1.2 ! partially use corners of detectors; 1.41421=full use VALUE_RANGE_FOR_TRUSTED_DETECTOR_PIXELS=7000. 30000. ! often 8000 is ok MINIMUM_ZETA=0.05 ! integrate close to the Lorentz zone; 0.15 is default STRONG_PIXEL=6 ! COLSPOT: don't find weak reflections; default is 3 REFINE(INTEGRATE)=CELL BEAM ORIENTATION ! parameters specifically for this detector and beamline: DETECTOR= $DETECTOR !NX= 3072 NY= 3072 QX= 0.10260 QY= 0.10260 ! XDS finds this out by itself DIRECTION_OF_DETECTOR_X-AXIS=1 0 0 DIRECTION_OF_DETECTOR_Y-AXIS=0 1 0 INCIDENT_BEAM_DIRECTION=0 0 1 ROTATION_AXIS=1 0 0 ! at e.g. SERCAT ID-22 this needs to be -1 0 0 FRACTION_OF_POLARIZATION=0.98 ! better value is provided by beamline staff! POLARIZATION_PLANE_NORMAL=0 1 0 eof echo "XDS.INP is ready for use." echo "After running xds, inspect BKGPIX.cbf and FRAME.cbf with XDS-Viewer!" rm tmp1 tmp2