2,657
edits
(→See also: Known bugs: ROTATION_AXIS at X06SA) |
(→The script: KD 27.4.22 always print out detector serial number) |
||
(8 intermediate revisions by the same user not shown) | |||
Line 127: | Line 127: | ||
# revision 1.08 . KD, Thomas Hauß, Feng Yu 7/11/2021 fix TZ in timestamps for SSRF detectors | # revision 1.08 . KD, Thomas Hauß, Feng Yu 7/11/2021 fix TZ in timestamps for SSRF detectors | ||
# revision 1.09 . KD, Feng Yu 7/11/2021 fix detector number BNL E-18-0121 to be E-18-0104 | # revision 1.09 . KD, Feng Yu 7/11/2021 fix detector number BNL E-18-0121 to be E-18-0104 | ||
REVISION="1. | # revision 1.10 . KD NeXus header for Eiger | ||
# revision 1.11 . KD / Helena Taberman ROTATION_AXIS=-1 0 0 for Eiger .cbf data from Petra P14 | |||
# revision 1.12 . KD / Helena Taberman correct rev 1.11 to be 0 -1 0 | |||
REVISION="1.12 (25-MAR-2022)" | |||
# | # | ||
Line 135: | Line 138: | ||
# | # | ||
# known problems: | # known problems: | ||
# revision 1.10 . KD implement NeXus for Eiger | |||
# - for ADSC detectors, there are at least three ways to obtain ORGX and ORGY values from the header (see below); | # - for ADSC detectors, there are at least three ways to obtain ORGX and ORGY values from the header (see below); | ||
# - the same might be a problem for MAR headers, too (not sure about this) | # - the same might be a problem for MAR headers, too (not sure about this) | ||
Line 140: | Line 144: | ||
# | # | ||
# notes for debugging of the script: | # notes for debugging of the script: | ||
# - add the -x option to | # - add the -x option to #!/bin/bash in first line, to see where an error occurs | ||
# - comment out the removal of tmp1 and tmp2 in the last line | # - comment out the removal of tmp1 and tmp2 in the last line | ||
# | # | ||
Line 176: | Line 180: | ||
# default DIRECTION_OF_DETECTOR_X-AXIS | # default DIRECTION_OF_DETECTOR_X-AXIS | ||
DIRECTION_OF_DETECTOR_X_AXIS="1 0 0" | DIRECTION_OF_DETECTOR_X_AXIS="1 0 0" | ||
# default DIRECTION_OF_DETECTOR_Y-AXIS | |||
DIRECTION_OF_DETECTOR_Y_AXIS="0 1 0" | |||
# default FRACTION_OF_POLARIZATION | # default FRACTION_OF_POLARIZATION | ||
pol_frac=0.98 | pol_frac=0.98 | ||
Line 472: | Line 478: | ||
DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=/-/` | DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=/-/` | ||
OSCILLATION_RANGE=`grep OMEGA_DELTA tmp2 | sed s/OMEGA_DELTA=//` | OSCILLATION_RANGE=`grep OMEGA_DELTA tmp2 | sed s/OMEGA_DELTA=//` | ||
DETECTOR_X_AXIS="-1 0 0" | |||
elif [ "$DET" == "experimental-ED" ]; then | elif [ "$DET" == "experimental-ED" ]; then | ||
Line 569: | Line 575: | ||
fi | fi | ||
# PETRA P14: raw data from Eiger are stored as CBF files so this is treated as Pilatus | # PETRA P14: raw data from Eiger are stored as CBF files so this is treated as Pilatus | ||
if [ "$DET_SN" == "Dectris Eiger 4M, E-08-0107" -o "$DET_SN" == "PILATUS 6M-F, S/N 60-0115-F" ] ; then | if [ "$DET_SN" == "Dectris Eiger 4M, E-08-0107" -o "$DET_SN" == "PILATUS 6M-F, S/N 60-0115-F" \ | ||
-o "$DET_SN" == "Dectris EIGER2 CdTe 16M, E-32-0129" ] ; then | |||
rotation_axis="0 -1 0" | rotation_axis="0 -1 0" | ||
echo ROTATION_AXIS="0 -1 0" at PETRA P14 | echo ROTATION_AXIS="0 -1 0" at PETRA P14 | ||
Line 593: | Line 600: | ||
DATA_RANGE="1 $nframes" | DATA_RANGE="1 $nframes" | ||
SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`" | SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`" | ||
SN=`h5dump -d "/entry/instrument/detector/detector_number" $FIRSTFRAME | awk '/\(0\): /{print $2}' | sed s/\"//g` | |||
echo detector serial number is $SN | |||
# find out if HDF5 from Diamond (DLS=1) or Dectris (DLS=0) | # find out if HDF5 from Diamond (DLS=1) or Dectris (DLS=0) | ||
Line 607: | Line 616: | ||
# rotation_axis=`h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME 2>/dev/null | grep "(0):" | sed -e "s/^.*://; s/,//g"` | # 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 | # the above gives -1 0 0 for DLS data instead of the correct 1 0 0, so commented out for now | ||
# comment while implementing rev 1.10: this is because the DLS headers are NeXus, so DIRECTION_OF_DETECTOR_X/Y_AXIS must be adjusted. | |||
else | else | ||
echo Eiger HDF5 from Dectris | echo Eiger HDF5 from Dectris | ||
Line 619: | Line 629: | ||
fi | fi | ||
echo "STARTING_ANGLE=$STARTING_ANGLE" | echo "STARTING_ANGLE=$STARTING_ANGLE" | ||
# If rotation | # If rotation axis set (NeXus) | ||
rotation_axis=`h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME 2>/dev/null | grep "(0):" | sed -e "s/^.*://; s/,//g"` | rotation_axis=`h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME 2>/dev/null | grep "(0):" | sed -e "s/^.*://; s/,//g"` | ||
# EIGER2 16M CHESS ID7B2 has S/N E-32-0123 (A. Finke 2020-11-07) v0.99 | # EIGER2 16M CHESS ID7B2 has S/N E-32-0123 (A. Finke 2020-11-07) v0.99 | ||
if [ "$SN" == "E-32-0123" ]; then | if [ "$SN" == "E-32-0123" ]; then | ||
rotation_axis="-1 0 0" | rotation_axis="-1 0 0" | ||
Line 685: | Line 694: | ||
SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`" | SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`" | ||
fi | fi | ||
fi | |||
# rev 1.10: check for NeXus header. If found, its geometry will overwrite any rotation_axis set until here. | |||
NeXus=0 | |||
h5dump -d "/entry/definition" $FIRSTFRAME | grep -q NXmx && NeXus=1 | |||
if [ "$NeXus" == "1" ]; then | |||
echo NeXus header found. This defines DIRECTION_OF_DETECTOR_X/Y-AXIS and ROTATION_AXIS. | |||
DIRECTION_OF_DETECTOR_X_AXIS=$(h5dump -d "/entry/instrument/detector/module/fast_pixel_direction" $FIRSTFRAME 2>/dev/null | grep "(0):" | tail -1 | sed -e "s/^.*://; s/,//g") | |||
DIRECTION_OF_DETECTOR_Y_AXIS=$(h5dump -d "/entry/instrument/detector/module/slow_pixel_direction" $FIRSTFRAME 2>/dev/null | grep "(0):" | tail -1 | sed -e "s/^.*://; s/,//g") | |||
rotation_axis=$(h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME 2>/dev/null | grep "(0):" | sed -e "s/^.*://; s/,//g") | |||
else | |||
echo no NeXus header found. | |||
fi | fi | ||
echo DATA_RANGE=$DATA_RANGE | echo DATA_RANGE=$DATA_RANGE | ||
Line 714: | Line 734: | ||
#let SKIP=768 | #let SKIP=768 | ||
#NX=$(od -t x -j $SKIP -N 4 $FIRSTFRAME |awk 'NR==1{print toupper($2)}'|perl -nle '@array= $_ =~/.{2}/g; print "ibase=16;obase=A;".join("",reverse @array)'|bc) | #NX=$(od -t x -j $SKIP -N 4 $FIRSTFRAME |awk 'NR==1{print toupper($2)}'|perl -nle '@array= $_ =~/.{2}/g; print "ibase=16;obase=A;".join("",reverse @array)'|bc) | ||
NX=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(768);print("%.4d"%struct.unpack(">i",f.read(4)))') | NX=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(768);print("%.4d"%struct.unpack(">i",f.read(4)))') | ||
NY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(772);print("%.4d"%struct.unpack(">i",f.read(4)))') | NY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(772);print("%.4d"%struct.unpack(">i",f.read(4)))') | ||
DETECTOR_DISTANCE=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(344);print("-%.4f"%struct.unpack(">f",f.read(4)))') | DETECTOR_DISTANCE=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(344);print("-%.4f"%struct.unpack(">f",f.read(4)))') | ||
ORGX=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(540);print("%.4f"%struct.unpack(">f",f.read(4)))') | ORGX=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(540);print("%.4f"%struct.unpack(">f",f.read(4)))') | ||
ORGY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(544);print("%.4f"%struct.unpack(">f",f.read(4)))') | ORGY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(544);print("%.4f"%struct.unpack(">f",f.read(4)))') | ||
OSCILLATION_RANGE=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(524);phis,phie=struct.unpack(">ff",f.read(8));print("%.4f"%(phie-phis))') | OSCILLATION_RANGE=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(524);phis,phie=struct.unpack(">ff",f.read(8));print("%.4f"%(phie-phis))') | ||
QX=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(776);print("%.6f"%struct.unpack(">f",f.read(4)))') | QX=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(776);print("%.6f"%struct.unpack(">f",f.read(4)))') | ||
QY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(780);print("%.6f"%struct.unpack(">f",f.read(4)))') | QY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(780);print("%.6f"%struct.unpack(">f",f.read(4)))') | ||
X_RAY_WAVELENGTH=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(292);print("%.6f"%struct.unpack(">f",f.read(4)))') | X_RAY_WAVELENGTH=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(292);print("%.6f"%struct.unpack(">f",f.read(4)))') | ||
Line 1,042: | Line 1,048: | ||
cat >> XDS.INP << eof | cat >> XDS.INP << eof | ||
DIRECTION_OF_DETECTOR_X-AXIS=$DIRECTION_OF_DETECTOR_X_AXIS | DIRECTION_OF_DETECTOR_X-AXIS=$DIRECTION_OF_DETECTOR_X_AXIS | ||
DIRECTION_OF_DETECTOR_Y-AXIS= | DIRECTION_OF_DETECTOR_Y-AXIS=$DIRECTION_OF_DETECTOR_Y_AXIS | ||
eof | eof | ||
fi | fi | ||
Line 1,212: | Line 1,218: | ||
echo spots in FRAME.cbf! | echo spots in FRAME.cbf! | ||
rm -f tmp1 tmp2 | rm -f tmp1 tmp2 | ||
</pre> | </pre> | ||
Line 1,296: | Line 1,301: | ||
* 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. | ||
* there are apparently several flavours of HDF5 files produced at Diamond Light Source. They differ e.g. in the naming of the header items. This means that items like NX, NY, DETECTOR_DISTANCE and number of images cannot always be determined by the [[generate_XDS.INP]] script. Example: The data at /dls/i04-1/data/2021/mx28114-9/processing/Lenye_Diamini/ThiL/ThiL found during the CCP4 2021 online Cape Town workshop. A workaround is to use e.g. xia2 pipeline=3dii to process these files, and - if needed - extract those items from its output files, e.g. from DEFAULT/NATIVE/SWEEP1/index/XDS.INP . | * there are apparently several flavours of HDF5 files produced at Diamond Light Source. They differ e.g. in the naming of the header items. This means that items like NX, NY, DETECTOR_DISTANCE and number of images cannot always be determined by the [[generate_XDS.INP]] script. Example: The data at /dls/i04-1/data/2021/mx28114-9/processing/Lenye_Diamini/ThiL/ThiL found during the CCP4 2021 online Cape Town workshop. A workaround is to use e.g. xia2 pipeline=3dii to process these files, and - if needed - extract those items from its output files, e.g. from DEFAULT/NATIVE/SWEEP1/index/XDS.INP . | ||
== See also == | == See also == |