Generate XDS.INP: Difference between revisions

m revision 1.23 . KD 28/2/2026 remove setting negative DETECTOR_DISTANCE for adsc-CMOS1 - found with SBGrid 383 (PDB 5HV4)
JanGeb (talk | contribs)
The script: Added support for Pilatus 4M CdTe @ ID30B/ESRF (rev. 1.24)
 
Line 15: Line 15:
<div class="mw-collapsible-content">
<div class="mw-collapsible-content">


<pre>
<pre>#!/bin/bash
 
#!/bin/bash
# purpose: generate XDS.INP
# purpose: generate XDS.INP
#
#
Line 153: Line 151:
# revision 1.22 . KD 28/5/2025 UNTRUSTED_RECTANGLEs for Pilatus3 1M, S/N 10-0159
# revision 1.22 . KD 28/5/2025 UNTRUSTED_RECTANGLEs for Pilatus3 1M, S/N 10-0159
# revision 1.23 . KD 28/2/2026 remove setting negative DETECTOR_DISTANCE for adsc-CMOS1 - found with SBGrid 383 (PDB 5HV4)
# revision 1.23 . KD 28/2/2026 remove setting negative DETECTOR_DISTANCE for adsc-CMOS1 - found with SBGrid 383 (PDB 5HV4)
REVISION="1.23 (28-Feb-2026)"
# revision 1.24 . Jan Gebauer 14/03/2026 Implementation for ID30B Pilatus CdTe detector. Introduction of calc_CdTe_Silicon () for 5-25kEV range.
REVISION="1.24 (14-Mar-2026)"


#
#
Line 180: Line 179:
# make sure the locale does not interfere with e.g. awk calculations:
# make sure the locale does not interfere with e.g. awk calculations:
export LC_ALL="C"
export LC_ALL="C"
# calc_CdTe_silicon() - Compute XDS SILICON parameter for CdTe (1mm sensor)
# Valid range: 5-25 keV (0.496-2.480 A)
# Fit: SILICON = 36548 * E_keV^(-2.661)  R2=0.9997 vs calcmu
#
# Usage:
#  calc_CdTe_silicon 12.4        -> keV input
#  calc_CdTe_silicon 1.0A        -> Angstrom input (A suffix, case-insensitive)
#
# Returns: SILICON value on stdout, or "XXX" if out of range
# In script usage e.g. SILICON="SILICON= $(calc_CdTe_silicon ${X_RAY_WAVELENGTH}A)"
calc_CdTe_silicon() {
    local input="$1"
    local kev
    # Parse input: Angstrom or keV
    if [[ "${input}" =~ ^([0-9]*\.?[0-9]+)[Aa]$ ]]; then
        kev=$(awk -v l="${BASH_REMATCH[1]}" 'BEGIN { printf "%.6f", 12.39842/l }')
    elif [[ "${input}" =~ ^[0-9]*\.?[0-9]+$ ]]; then
        kev="${input}"
    else
        echo "XXX"; return 1
    fi
    # Range check 5-25 keV, apply power law
    awk -v kev="$kev" '
    BEGIN {
        if (kev < 5.0 || kev > 25.0) { print "XXX"; exit }
        printf "%.4f\n", 36548.0 * (kev ^ -2.661)
    }'
}
#
#
# defaults:
# defaults:
Line 214: Line 247:
CLUSTER_RADIUS=3.5
CLUSTER_RADIUS=3.5
REFINE_CORRECT="CELL BEAM ORIENTATION AXIS POSITION ! Default is: refine everything"
REFINE_CORRECT="CELL BEAM ORIENTATION AXIS POSITION ! Default is: refine everything"
SILICON=""  # normally we don't need to set SILICON, but this is no correct for CdTe detector surfaces


dname=$(dirname "$1")
dname=$(dirname "$1")
Line 294: Line 328:
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
h5dump -d "/entry/instrument/detector/description" $FIRSTFRAME | grep -i "PILATUS4 CdTe 4M" > /dev/null && DET=eiger
fi
fi


Line 740: Line 775:
   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}'`


# revision 1.24: Settings for the Pilatus 4M CdTe ad ID30B / ESRF
  if [ "$DET_SN" == "D033638" ]; then
    echo "Pilatus 4M CdTe at ID30B / ESRF: setting SENSOR_THICKNESS and SILICON parameters for CdTe sensor"
    SENSOR_THICKNESS=1.0
    SILICON="SILICON= $(calc_CdTe_silicon ${X_RAY_WAVELENGTH}A)"
    OVERLOAD=1048500
    DETECTOR="PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= $OVERLOAD"
# manually overwriting the DIRECTION_OF_DETECTOR_X/Y-AXIS and ROTATION_AXIS since the NeXus header of this detector is wrong (DIRECTION_OF_DETECTOR_X/Y-AXIS are swapped, and ROTATION_AXIS is inverted)
    DIRECTION_OF_DETECTOR_X_AXIS="1.0 0.0 0.0"
    DIRECTION_OF_DETECTOR_Y_AXIS="0.0 1.0 0.0"
    ROTATION_AXIS="1.0 0.0 0.0"
  fi
 
   NX=`h5dump -d "/entry/instrument/detector/detectorSpecific/x_pixels_in_detector" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
   NX=`h5dump -d "/entry/instrument/detector/detectorSpecific/x_pixels_in_detector" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
   NY=`h5dump -d "/entry/instrument/detector/detectorSpecific/y_pixels_in_detector" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
   NY=`h5dump -d "/entry/instrument/detector/detectorSpecific/y_pixels_in_detector" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
Line 1,175: Line 1,223:
DETECTOR= $DETECTOR
DETECTOR= $DETECTOR
SENSOR_THICKNESS= $SENSOR_THICKNESS
SENSOR_THICKNESS= $SENSOR_THICKNESS
$SILICON
! attention CCD detectors: for very high resolution (better than 1A) make sure to specify SILICON
! attention CCD detectors: for very high resolution (better than 1A) make sure to specify SILICON
! as about 32* what CORRECT.LP suggests (absorption of phosphor is much higher than that of silicon).
! as about 32* what CORRECT.LP suggests (absorption of phosphor is much higher than that of silicon).
Line 1,375: Line 1,424:
eof
eof
     fi
     fi
  elif [ "$NX" == "2073" -a "$NY" == "2180" ]; then
# Pilatus 4M CdTe ; v1.24 numbers from Jan Gebauer
    cat >> XDS.INP << eof
!masking non sensitive area of Pilatus 4M CdTe
UNTRUSTED_RECTANGLE= 0 2074 255 276
UNTRUSTED_RECTANGLE= 0 2074 530 551
UNTRUSTED_RECTANGLE= 0 2074 805 826
UNTRUSTED_RECTANGLE= 0 2074 1080 1101
UNTRUSTED_RECTANGLE= 0 2074 1355 1376
UNTRUSTED_RECTANGLE= 0 2074 1630 1651
UNTRUSTED_RECTANGLE= 0 2074 1905 1926
UNTRUSTED_RECTANGLE= 513 521 0 2181
UNTRUSTED_RECTANGLE= 1033 1041 0 2181
UNTRUSTED_RECTANGLE= 1553 1561 0 2181
UNTRUSTED_RECTANGLE= 255 257 0 2181
UNTRUSTED_RECTANGLE= 775 777 0 2181
UNTRUSTED_RECTANGLE= 1295 1297 0 2181
UNTRUSTED_RECTANGLE= 1815 1817 0 2181
eof


# Pilatus 12M
# Pilatus 12M
Line 1,431: Line 1,499:
echo "spots in FRAME.cbf (or SHOW_HKL.cbf in versions since BUILT=20240723)!"
echo "spots in FRAME.cbf (or SHOW_HKL.cbf in versions since BUILT=20240723)!"
rm -f tmp1 tmp2
rm -f tmp1 tmp2
# end of generate_XDS.INP
# end of generate_XDS.INP</pre>
</pre>
</div>
</div>
</div>
</div>