Generate XDS.INP: Difference between revisions

Jump to navigation Jump to search
→‎The script: v0.95 fix DLS Eiger HDF5 variant OSCILLATION_RANGE, STARTING_ANGLE. Attention: DLS Eiger variant needs h5dump 1.10 for OVERLOAD!
m (→‎The script: update v.89 notes)
(→‎The script: v0.95 fix DLS Eiger HDF5 variant OSCILLATION_RANGE, STARTING_ANGLE. Attention: DLS Eiger variant needs h5dump 1.10 for OVERLOAD!)
(10 intermediate revisions by the same user not shown)
Line 106: Line 106:
# revision 0.88 . KD 16/10/2019 fixes for SSRF, add "-maxdepth 1" to "find -H ..."
# revision 0.88 . KD 16/10/2019 fixes for SSRF, add "-maxdepth 1" to "find -H ..."
# revision 0.89 . KD 21/10/2019 add ADSC S/N 905 at ALS 8.2.1, S/N 928 at Australian Synchrotron MX2 beamline; final SSRF fixes
# revision 0.89 . KD 21/10/2019 add ADSC S/N 905 at ALS 8.2.1, S/N 928 at Australian Synchrotron MX2 beamline; final SSRF fixes
REVISION="0.89 (23-Oct-2019)"
# revision 0.90 . KD 25/10/2019 add OLDMAR detector type. Tested w/ SBGrid data set 6. Anomalous signal may have wrong hand!
# revision 0.91 . KD 16/01/2020 Allow negative starting angle for Eiger (found -33 at SLS !).
# revision 0.92 . KD 27/02/2020 read *_master.h5 from Diamond Light Source
# revision 0.93 . KD 13/03/2020 print out 2theta for MarCCD (DETECTOR_*_AXIS can be derived from this)
# revision 0.94 . KD 16/03/2020 bugfix for Bruker-cbf to make bc accept e.g. 3.1e-005 by using awk printf "%.5f" instead of awk print
# revision 0.95 . KD 29/07/2020 fix DLS Eiger HDF5 variant OSCILLATION_RANGE, STARTING_ANGLE. Attention: DLS Eiger variant needs h5dump 1.10 for OVERLOAD!
REVISION="0.95 (29-Jul-2020)"


#                                                                                                             
#                                                                                                             
Line 232: Line 238:
  grep -q mar345 tmp2 && DET=MAR345     
  grep -q mar345 tmp2 && DET=MAR345     
  grep -q BRUKER tmp2 && grep -q CBF tmp2  && DET=Bruker-cbf   
  grep -q BRUKER tmp2 && grep -q CBF tmp2  && DET=Bruker-cbf   
  grep -q CMOS1 tmp2 && DET=adsc-CMOS1                  
  grep -q CMOS1 tmp2 && DET=adsc-CMOS1  
grep -q MARCONTROL tmp2 && DET=OLDMAR                   
else
else
  h5dump -d "/entry/instrument/detector/description" $FIRSTFRAME | grep -i Eiger > /dev/null && DET=eiger
  h5dump -d "/entry/instrument/detector/description" $FIRSTFRAME | grep -i Eiger > /dev/null && DET=eiger
Line 248: Line 255:
elif [ "$DET" == "mccd" ]; then  
elif [ "$DET" == "mccd" ]; then  
   echo Data from a MarCCD detector
   echo Data from a MarCCD detector
# http://www.sb.fsu.edu/~xray/Manuals/marCCD165header.html has header information
                                    
                                    
   DETECTOR="CCDCHESS MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65500"
   DETECTOR="CCDCHESS MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65500"
Line 283: Line 291:
   DETECTOR_DISTANCE=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   DETECTOR_DISTANCE=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   DETECTOR_DISTANCE=`echo "scale=3; $DETECTOR_DISTANCE/1000" | bc -l`                                     
   DETECTOR_DISTANCE=`echo "scale=3; $DETECTOR_DISTANCE/1000" | bc -l`                                     
# Mar 12, 2020 KD
  let SKIP=1724
  TWOTHETA=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  TWOTHETA=`echo "scale=3; $TWOTHETA/1000" | bc -l`
  echo 2THETA= $TWOTHETA


   let SKIP=1024+256+128+256+44
   let SKIP=1024+256+128+256+44
Line 510: Line 524:
       fi
       fi
# insert similar code for Petra P14 here
# insert similar code for Petra P14 here
elif [ "$DET" == "eiger" ]; then
elif [ "$DET" == "eiger" ]; then
   OVERLOAD=`h5dump -d "/entry/instrument/detector/detectorSpecific/countrate_correction_count_cutoff" $FIRSTFRAME | awk '/\(0\):/{print $2}' `
# find out if HDF5 from Diamond (DLS=1) or Dectris (DLS=0)
  DLS=0
   OVERLOAD=`h5dump -d "/entry/instrument/detector/detectorSpecific/countrate_correction_count_cutoff" $FIRSTFRAME 2>/dev/null` || DLS=1
  if [ "$DLS" == 1 ]; then
    echo Eiger HDF5 from Diamond
    OVERLOAD=`h5dump -d "/entry/instrument/detector/saturation_value" $FIRSTFRAME | awk '/\(0\):/{print $2}'`
  # v0.95: fix the next 2 lines by taking care of negative values with the \- , and stop after first "(0)"
    OSCILLATION_RANGE=`h5dump -d "/entry/data/omega" $FIRSTFRAME | awk '/\(0\): [\-0-9]/{print $3-$2;exit}'`
    STARTING_ANGLE=`h5dump    -d "/entry/data/omega" $FIRSTFRAME | awk '/\(0\): [\-0-9]/{print $2;exit}' | sed -e "s/,//"`
    echo OSCILLATION_RANGE=$OSCILLATION_RANGE STARTING_ANGLE=$STARTING_ANGLE
  # rotation_axis=`h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME 2>/dev/null | grep "(0):" | sed -e "s/^.*://; s/,//g"`
  # the above gives -1 0 0 for DLS data instead of the correct 1 0 0, so commented out for now
  else
    echo Eiger HDF5 from Dectris
    OVERLOAD=`h5dump -d "/entry/instrument/detector/detectorSpecific/countrate_correction_count_cutoff" $FIRSTFRAME | awk '/\(0\):/{print $2}'`   
    OSCILLATION_RANGE=`h5dump -d "/entry/sample/goniometer/omega_range_average" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
  # STARTING_ANGLE:  the \- was introduced in version 0.91 to allow negative values :
    STARTING_ANGLE=`h5dump -d "/entry/sample/goniometer/omega_start" $FIRSTFRAME | awk '/\(0\): [\-0-9]/{print $2}'`
  # If rotation vector set (NeXus)
    rotation_axis=`h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME 2>/dev/null | grep "(0):" | sed -e "s/^.*://; s/,//g"`
  # Eiger 16M SSRF BL17U1
    SN=`h5dump -d "/entry/instrument/detector/detector_number" $FIRSTFRAME | awk '/\(0\): /{print $2}' | sed s/\"//g`
    if [ "$SN" == "E-32-0111" ]; then
      rotation_axis="-1 0 0"
      echo SSRF BL17U1 with inverted rotation axis
    fi
  fi
   DETECTOR="EIGER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= $OVERLOAD"
   DETECTOR="EIGER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= $OVERLOAD"
   QX=`h5dump -d "/entry/instrument/detector/x_pixel_size" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
   QX=`h5dump -d "/entry/instrument/detector/x_pixel_size" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
   QY=`h5dump -d "/entry/instrument/detector/y_pixel_size" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
   QY=`h5dump -d "/entry/instrument/detector/y_pixel_size" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`


   echo Data from a Eiger hdf5
   echo OVERLOAD=$OVERLOAD
   SENSOR_THICKNESS=`h5dump -d "/entry/instrument/detector/sensor_thickness" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
   SENSOR_THICKNESS=`h5dump -d "/entry/instrument/detector/sensor_thickness" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
   X_RAY_WAVELENGTH=`h5dump -d "/entry/instrument/beam/incident_wavelength" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
   X_RAY_WAVELENGTH=`h5dump -d "/entry/instrument/beam/incident_wavelength" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
Line 527: Line 568:
   ORGY=`h5dump -d "/entry/instrument/detector/beam_center_y" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
   ORGY=`h5dump -d "/entry/instrument/detector/beam_center_y" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`


   # find DETECTOR_DISTANCE and OSCILLATION_RANGE:
   # find DETECTOR_DISTANCE :
   DETECTOR_DISTANCE=`h5dump -d "/entry/instrument/detector/detector_distance" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
   DETECTOR_DISTANCE=`h5dump -d "/entry/instrument/detector/detector_distance" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
  OSCILLATION_RANGE=`h5dump -d "/entry/sample/goniometer/omega_range_average" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
 
  #STARTING_ANGLE:
  STARTING_ANGLE=`h5dump -d "/entry/sample/goniometer/omega_start" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
 
  # If rotation vector set (NeXus)
  rotation_axis=`h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME 2>/dev/null | grep "(0):" | sed -e "s/^.*://; s/,//g"`
  # Eiger 16M SSRF BL17U1
  SN=`h5dump -d "/entry/instrument/detector/detector_number" $FIRSTFRAME | awk '/\(0\): /{print $2}' | sed s/\"//g`
  if [ "$SN" == "E-32-0111" ]; then
    rotation_axis="-1 0 0"
    echo SSRF BL17U1 with inverted rotation axis
  fi


   SEPMIN=4
   SEPMIN=4
   CLUSTER_RADIUS=2
   CLUSTER_RADIUS=2
 
 
elif [ "$DET" == "raxis" ]; then
elif [ "$DET" == "raxis" ]; then
   echo Data from a RAXIS detector
   echo Data from a RAXIS detector
Line 675: Line 703:
  X_RAY_WAVELENGTH=`grep 'WAVELENGTH' tmp2 | awk '{print $2}'`  
  X_RAY_WAVELENGTH=`grep 'WAVELENGTH' tmp2 | awk '{print $2}'`  
  OSCILLATION_RANGE=`grep 'PHI' tmp2 | awk '{print $5-$3}'`     
  OSCILLATION_RANGE=`grep 'PHI' tmp2 | awk '{print $5-$3}'`     
  TRUSTED_REGION="0 0.99"         
  TRUSTED_REGION="0 0.99"  
 
elif [ "$DET" == "OLDMAR" ]; then
 
echo  "Data from old type MAR image plate detector"
DETECTOR="MAR  MINIMUM_VALID_PIXEL_VALUE=0  OVERLOAD=130000"
NX=`awk 'NR==2 {print $2}' tmp2`
NY=$NX
QX=`awk 'NR==2 {print $15}' tmp2`
QY=$QX
ORGX=`awk 'NR==2 {print $19}' tmp2`
ORGY=`awk 'NR==2 {print $20}' tmp2`
DETECTOR_DISTANCE=`awk 'NR==2 {print $22}' tmp2`             
X_RAY_WAVELENGTH=`awk 'NR==2 {print $21}' tmp2`
OSCILLATION_RANGE=`awk 'NR==2 {print $24-$23}' tmp2`   
TRUSTED_REGION="0 0.99" 
rotation_axis="0 1 0" 
echo unsure if sign of anomalous signal is correct - please verify or try both hands!
        
elif [ "$DET" == "Bruker-cbf" ]; then
elif [ "$DET" == "Bruker-cbf" ]; then
    
    
Line 704: Line 750:


  X_RAY_WAVELENGTH=`awk '/diffrn_radiation_wavelength.wavelength/{print $2}' tmp2`  
  X_RAY_WAVELENGTH=`awk '/diffrn_radiation_wavelength.wavelength/{print $2}' tmp2`  
  OMEGA=`awk '/OMEGA \? \? \?/{print $5}' tmp2`
# fix 16.3.20: instead of print, use printf "%.5f", because bc does not accept e.g. 3.1e-005
  DELTAOMEGA=`awk '/OMEGA \? \? \?/{print $6}' tmp2`
  OMEGA=`awk '/OMEGA \? \? \?/{printf "%.5f",$5}' tmp2`
  PHI=`awk '/PHI \? \? \?/{print $5}' tmp2`
  DELTAOMEGA=`awk '/OMEGA \? \? \?/{printf "%.5f",$6}' tmp2`
  DELTAPHI=`awk '/PHI \? \? \?/{printf "%5.4f",$6}' tmp2`
  PHI=`awk '/PHI \? \? \?/{printf "%.5f",$5}' tmp2`
  KAPPA=`awk '/CHI \? \? \?/{print $5}' tmp2`
  DELTAPHI=`awk '/PHI \? \? \?/{printf "%.5f",$6}' tmp2`
  KAPPA=`awk '/CHI \? \? \?/{printf "%.5f",$5}' tmp2`
# echo OMEGA DELTAOMEGA PHI DELTAPHI KAPPA= $OMEGA $DELTAOMEGA $PHI $DELTAPHI $KAPPA
# echo OMEGA DELTAOMEGA PHI DELTAPHI KAPPA= $OMEGA $DELTAOMEGA $PHI $DELTAPHI $KAPPA


Line 791: Line 838:
SEPMIN=$SEPMIN  CLUSTER_RADIUS=$CLUSTER_RADIUS ! 4 and 2 for Pixel Array Detectors
SEPMIN=$SEPMIN  CLUSTER_RADIUS=$CLUSTER_RADIUS ! 4 and 2 for Pixel Array Detectors
! since XDS 01-MAR-2015, POSITION supersedes DISTANCE.
! since XDS 01-MAR-2015, POSITION supersedes DISTANCE.
! nowadays headers are usually correct so refine POSITION in INTEGRATE but not IDXREF
! nowadays headers are usually correct so refine POSITION in INTEGRATE but not IDXREF if low to medium resolution
REFINE(IDXREF)=CELL BEAM ORIENTATION AXIS  ! refine POSITION only if known that header distance inaccurate
! however, if the spots from COLSPOT extend to 2A then POSITION could, and if 1.5A POSITION should be refined
REFINE(INTEGRATE)= POSITION BEAM ORIENTATION ! AXIS CELL
REFINE(IDXREF)=CELL BEAM ORIENTATION AXIS  ! add POSITION if high resolution, or DETECTOR_DISTANCE inaccurate
REFINE(INTEGRATE)= POSITION BEAM ORIENTATION ! AXIS CELL . If 1.5A or higher it is ok to refine CELL
! REFINE(CORRECT)=CELL BEAM ORIENTATION AXIS POSITION ! Default is: refine everything
! REFINE(CORRECT)=CELL BEAM ORIENTATION AXIS POSITION ! Default is: refine everything


Line 807: Line 855:


if [ "$DET" == "eiger" ] && [ "$is_h5" == 1 ]; then
if [ "$DET" == "eiger" ] && [ "$is_h5" == 1 ]; then
   if [ -e /usr/local/lib64/dectris-neggia.so ]; then
   if [ "$DLS" == 0 ] ; then
    echo LIB=/usr/local/lib64/dectris-neggia.so >> XDS.INP
    if [ -e /usr/local/lib64/dectris-neggia.so ]; then
    echo LIB= line was written to XDS.INP
      echo LIB=/usr/local/lib64/dectris-neggia.so >> XDS.INP
      echo LIB= line was written to XDS.INP
    else
      echo !LIB=/usr/local/lib64/dectris-neggia.so >> XDS.INP
      echo /usr/local/lib64/dectris-neggia.so was not found - specify location manually!
    fi
   else
   else
     echo !LIB=/usr/local/lib64/dectris-neggia.so >> XDS.INP
     if [ -e /usr/local/lib64/durin-plugin.so ]; then
    echo /usr/local/lib64/dectris-neggia.so was not found - specify location manually!
      echo LIB=/usr/local/lib64/durin-plugin.so >> XDS.INP
   fi
      echo LIB= line was written to XDS.INP
    else
      echo !LIB=/usr/local/lib64/durin-plugin.so >> XDS.INP
      echo /usr/local/lib64/durin-plugin.so was not found - specify location manually!
    fi
   fi  
fi  
fi  


Line 1,017: Line 1,075:
For Eiger data processing, the <code>h5dump</code> program must be installed. This is part of <code>hdf5-tools</code> (Ubuntu) or <code>hdf5</code> (RHEL).
For Eiger data processing, the <code>h5dump</code> program must be installed. This is part of <code>hdf5-tools</code> (Ubuntu) or <code>hdf5</code> (RHEL).


On Mac OS X, installation of the "Command Line Tools" (from http://developer.apple.com/downloads; requires Apple ID) is required. These are also part of the (larger, but also free) [http://developer.apple.com/tools/xcode Xcode] package. This package comes with a license that has to be accepted by the user when running a Command Line Tool (e.g. <code>strings</code>) for the first time.
On Mac OS X, installation of the "Command Line Tools" (from http://developer.apple.com/downloads; requires Apple ID) is required (open a terminal and type <code>xcode-select --install</code>). These are also part of the (larger, but also free) [http://developer.apple.com/tools/xcode Xcode] package. This package comes with a license that has to be accepted by the user when running a Command Line Tool (e.g. <code>strings</code>) for the first time.


An easy way to check for missing programs is
One way to check for missing programs is
  which ls grep egrep awk cut cat echo wc bc head sed tail cp od python strings h5dump
  #!/bin/bash
for i in  ls grep egrep awk cut cat echo wc bc head sed tail cp od python strings h5dump ; do
    if [ ! -x /bin/$i ] && [ ! -x /usr/bin/$i ]; then
      echo $i not found
    fi
done


A command that should go a long way in providing all these tools for RedHat-derived distros is (as root)
A command that should go a long way in providing all these tools for RedHat-derived distros is (as root)
Line 1,032: Line 1,095:


* The script tries to interpret the header of the frames, so is currently limited to Dectris (Pilatus, Eiger), ADSC (Quantum), Rigaku (several types), MAR (CCD and image plate) detectors, and one Bruker detector. Other detectors need some values to be manually filled into XDS.INP - the relevant places are marked with XXX. These are detector properties (type, pixel size and number, min and max counts in a pixel), and experimental parameters like ROTATION_AXIS, OSCILLATION_RANGE, X-RAY_WAVELENGTH, DETECTOR_DISTANCE, and XORG, YORG. For fine-tuning of detector parameters, see the [http://xds.mpimf-heidelberg.mpg.de/html_doc/xds_prepare.html detector-specific templates].
* The script tries to interpret the header of the frames, so is currently limited to Dectris (Pilatus, Eiger), ADSC (Quantum), Rigaku (several types), MAR (CCD and image plate) detectors, and one Bruker detector. Other detectors need some values to be manually filled into XDS.INP - the relevant places are marked with XXX. These are detector properties (type, pixel size and number, min and max counts in a pixel), and experimental parameters like ROTATION_AXIS, OSCILLATION_RANGE, X-RAY_WAVELENGTH, DETECTOR_DISTANCE, and XORG, YORG. For fine-tuning of detector parameters, see the [http://xds.mpimf-heidelberg.mpg.de/html_doc/xds_prepare.html detector-specific templates].
* The authors have made a "best effort" to provide a XDS.INP that results in the correct sign of the anomalous signal. In the case of one detector type (internally called Rigaku SMV) this requires reversal of one detector axis, and a negative DETECTOR_DISTANCE, as is found in some of the [http://xds.mpimf-heidelberg.mpg.de/html_doc/xds_prepare.html detector-specific templates]. '''For an unusual or unknown detector setup, the correct sign of the anomalous signal needs to be established and verified e.g. with a good dataset from a test crystal that has a anomalous signal.''' The authors do not take any responsibility for problems arising from incorrect sign of the anomalous signal, nor - obviously! - for any other mischief arising in or from data processing.
* The authors have made a "best effort" to provide a XDS.INP that results in the correct sign of the anomalous signal. In the case of one detector type (internally called Rigaku SMV) this requires reversal of one detector axis, and a negative DETECTOR_DISTANCE, as is found in some of the [http://xds.mpimf-heidelberg.mpg.de/html_doc/xds_prepare.html detector-specific templates]. '''For an unusual or unknown detector setup, the correct sign of the anomalous signal needs to be established and verified e.g. with a good dataset from a test crystal that has an anomalous signal.''' The authors do not take any responsibility for problems arising from incorrect sign of the anomalous signal, nor - obviously! - for any other mischief arising in or from data processing.
* At some beamlines, the ROTATION_AXIS should be -1 0 0 ("backwards") instead of the usual 1 0 0 ("horizontal"), or even 0 1 0 ("vertical") like at one of the PETRA Hamburg BLs. We have only just started the article [[Beamline notes]], and the frame headers do not have this information, so the default chosen by [[generate_XDS.INP]] may be wrong and need manual correction.
* At some beamlines, the ROTATION_AXIS should be -1 0 0 ("backwards") instead of the usual 1 0 0 ("horizontal"), or even 0 1 0 ("vertical") like at one of the PETRA Hamburg BLs. We have only just started the article [[Beamline notes]], and the frame headers do not have this information, so the default chosen by [[generate_XDS.INP]] may be wrong and need manual correction.
* Sometimes, the x- and y- values of the primary beam position recorded in the header should be used for ORGY and ORGX (i.e reversed) instead of as ORGX and ORGY. For ADSC, this has been implemented in the script for a number of beamlines.
* Sometimes, the x- and y- values of the primary beam position recorded in the header should be used for ORGY and ORGX (i.e reversed) instead of as ORGX and ORGY. For ADSC, this has been implemented in the script for a number of beamlines.
2,652

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu