Generate XDS.INP: Difference between revisions

Jump to navigation Jump to search
m
(17 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.09 (9-NOV-2021)"
# 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.13 . KD variables for /usr/local/lib64/dectris-neggia.so and durin-plugin.so . Remove h5dump error messages.
REVISION="1.13 (04-Jun-2022)"


#                                                                                                             
#                                                                                                             
Line 137: Line 141:
# - 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)  
# - on Mac OS X, the Xcode command line tools (from https://developer.apple.com/download/more/) are needed.                             
# - on macOS, the "Command Line Tools for Xcode" (from https://developer.apple.com/download/more/) are needed.                             
#                                                                                                                 
#                                                                                                                 
# notes for debugging of the script:                                                                             
# notes for debugging of the script:                                                                             
# - add the -x option to the first line, to see where an error occurs                                             
# - 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=//`   
   DIRECTION_OF_DETECTOR_X_AXIS="-1 0 0"  
   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 612: Line 622:
     OSCILLATION_RANGE=`h5dump -d "/entry/sample/goniometer/omega_range_average" $FIRSTFRAME | awk '/\(0\): [0-9]/{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:  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}'`
     STARTING_ANGLE=`h5dump -d "/entry/sample/goniometer/omega_start" $FIRSTFRAME 2>/dev/null | awk '/\(0\): [\-0-9]/{print $2}'`
   # /entry/sample/goniometer/omega_start is missing in some eiger2 detectors (e.g. Eiger2 9M with fw version release-2020.2.1 and SIMPLON API 1.8) (Feng YU 2021-07-18)
   # /entry/sample/goniometer/omega_start is missing in some eiger2 detectors (e.g. Eiger2 9M with fw version release-2020.2.1 and SIMPLON API 1.8) (Feng YU 2021-07-18)
     if [ "$STARTING_ANGLE" == "" ]; then
     if [ "$STARTING_ANGLE" == "" ]; then
  echo "/entry/sample/goniometer/omega_start not found, try /entry/sample/goniometer/omega"
  echo "/entry/sample/goniometer/omega_start not found, trying /entry/sample/goniometer/omega"
  STARTING_ANGLE=`h5dump -d /entry/sample/goniometer/omega $FIRSTFRAME | grep "(0):" | head -n 1 | awk '{print $2}' | sed -e "s/,//g"`
  STARTING_ANGLE=`h5dump -d /entry/sample/goniometer/omega $FIRSTFRAME | grep "(0):" | head -n 1 | awk '{print $2}' | sed -e "s/,//g"`
     fi
     fi
     echo "STARTING_ANGLE=$STARTING_ANGLE"
     echo "STARTING_ANGLE=$STARTING_ANGLE"
   # If rotation vector set (NeXus)
   # 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
    SN=`h5dump -d "/entry/instrument/detector/detector_number" $FIRSTFRAME | awk '/\(0\): /{print $2}' | sed s/\"//g`
     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 2>/dev/null | 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))')
!  NY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(772);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)))')
   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)))')
   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))')
!  ORGY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(544);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))')
   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))')
!  QY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(780);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)))')
   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)))')
   X_RAY_WAVELENGTH=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(292);print("%.6f"%struct.unpack(">f",f.read(4)))')


Line 999: Line 1,005:
if [ "$DET" == "eiger" ] && [ "$is_h5" == 1 ]; then
if [ "$DET" == "eiger" ] && [ "$is_h5" == 1 ]; then
   if [ "$DLS" == 0 ] ; then
   if [ "$DLS" == 0 ] ; then
     if [ -e /usr/local/lib64/dectris-neggia.so ]; then
     neggia_path=/usr/local/lib64/dectris-neggia.so
       echo LIB=/usr/local/lib64/dectris-neggia.so >> XDS.INP
    if [ -e $neggia_path ]; then
       echo LIB= line was written to XDS.INP . For Apple ARM64 processors, you must modify the name.
       echo LIB=$neggia_path >> XDS.INP
       echo "LIB= <dectris-neggia> was written to XDS.INP . Check the path! For Apple M1 processors, modify the name."
     else
     else
       echo !LIB=/usr/local/lib64/dectris-neggia.so >> XDS.INP
       echo !LIB=/usr/local/lib64/dectris-neggia.so >> XDS.INP
       echo /usr/local/lib64/dectris-neggia.so was not found - specify location manually!
       echo "dectris-neggia.so not found. Specify LIB=<path-to-dectris-neggia> in XDS.INP & fix your generate_XDS.INP !"
     fi
     fi
   else
   else
     if [ -e /usr/local/lib64/durin-plugin.so ]; then
     durin_path=/usr/local/lib64/durin-plugin.so
       echo LIB=/usr/local/lib64/durin-plugin.so >> XDS.INP
    if [ -e $durin_path ]; then
       echo LIB= line was written to XDS.INP
       echo LIB=$durin_path >> XDS.INP
       echo "LIB= <durin-plugin> was written to XDS.INP . Check the path! For Apple M1 processors, modify the name."
     else
     else
       echo !LIB=/usr/local/lib64/durin-plugin.so >> XDS.INP
       echo !LIB=/usr/local/lib64/durin-plugin.so >> XDS.INP
       echo /usr/local/lib64/durin-plugin.so was not found - specify location manually!
       echo "durin-plugin.so not found. Specify LIB=<path-to-durin-plugin> in XDS.INP & fix your generate_XDS.INP !"
     fi
     fi
   fi  
   fi  
Line 1,042: Line 1,050:
  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=0 1 0
DIRECTION_OF_DETECTOR_Y-AXIS=$DIRECTION_OF_DETECTOR_Y_AXIS
eof
eof
  fi
  fi
Line 1,212: Line 1,220:
echo spots in FRAME.cbf!
echo spots in FRAME.cbf!
rm -f tmp1 tmp2
rm -f tmp1 tmp2
</pre>
</pre>


Line 1,218: Line 1,225:


Ask your system adminstrator to cut-and-paste the script into e.g. /usr/local/bin/generate_XDS.INP, and to make it "executable".
Ask your system adminstrator to cut-and-paste the script into e.g. /usr/local/bin/generate_XDS.INP, and to make it "executable".
If you work with Eiger data, you may want to make a one-line change to the script after downloading, in order to point to the correct path on your system of the Dectris' Neggia library, or the Durin plugin, respectively. Just open the script with an editor and adjust neggia_path or durin_path ! This relieves users from having to change the LIB= line for every data set. You should also insert that path into the Menu / Settings / "generic library" in [[XDSGUI]] .


But you may also cut-and-paste the script from this webpage into a file in e.g. your home directory; the filename should be generate_XDS.INP. After creating the file, make it executable - e.g. if it's in your $HOME, use:
But you may also cut-and-paste the script from this webpage into a file in e.g. your home directory; the filename should be generate_XDS.INP. After creating the file, make it executable - e.g. if it's in your $HOME, use:
Line 1,253: Line 1,262:
</pre>
</pre>
If you do use cut-and-paste from the webpage, be aware of the following problem report: On the Mac, after loading frames, by clicking “generate XDS.INP”, the program gives some strange symbol “” in XDS.INP. And the more you click “save” button, the more “” appear. This looks like e.g. <br>SPACE_GROUP_NUMBER=0  ! 0 if unknown <br>UNIT_CELL_CONSTANTS= 70 80 90 90 90 90  <br> ''The problem is due to the “Rich text” format in TextEdit when saving "generate_XDS.INP". It is solved by re-downloading the script, and changing format to Plain - everything should work then.''
If you do use cut-and-paste from the webpage, be aware of the following problem report: On the Mac, after loading frames, by clicking “generate XDS.INP”, the program gives some strange symbol “” in XDS.INP. And the more you click “save” button, the more “” appear. This looks like e.g. <br>SPACE_GROUP_NUMBER=0  ! 0 if unknown <br>UNIT_CELL_CONSTANTS= 70 80 90 90 90 90  <br> ''The problem is due to the “Rich text” format in TextEdit when saving "generate_XDS.INP". It is solved by re-downloading the script, and changing format to Plain - everything should work then.''
Attention beamline staff: it would be great if you could make a one-line change to the script after downloading, in order to point to the correct path to Dectris' Neggia library, or the Durin plugin, respectively. Just open the script with an editor and adjust neggia_path or durin_path ! This relieves users from having to change the LIB= line for every data set.


== Calling generate_XDS.INP from a Python script ==
== Calling generate_XDS.INP from a Python script ==
2,652

edits

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

Navigation menu