Generate XDS.INP: Difference between revisions

No edit summary
m (→‎Dependencies: re-word h5dump version)
 
(180 intermediate revisions by 4 users not shown)
Line 1: Line 1:
This script generates XDS.INP based on a list of frame names supplied on the commandline. It currently works for MarCCD, ADSC, Pilatus, Eiger, some Rigaku and one Bruker detector(s); since this is just a bash script, extension to other detectors should be very easy.
This script generates XDS.INP based on a list of frame names supplied on the commandline. It currently works for MarCCD, ADSC, Pilatus, Eiger, some Rigaku and one Bruker detector(s); there is also some support for microED with SMV files which have a wavelength given as 0 (look for "experimental-ED" in the script). Since this is just a bash script, extension to other detectors should be very easy.


== Usage ==
== Usage ==
Line 5: Line 5:
Usage is just (don't forget the quotation marks!):
Usage is just (don't forget the quotation marks!):
  generate_XDS.INP "/home/myname/frms/mydata_1_???.img"
  generate_XDS.INP "/home/myname/frms/mydata_1_???.img"
XDS [http://strucbio.biologie.uni-konstanz.de/~dikay/XDS_html_doc/html_doc/xds_parameters.html#NAME_TEMPLATE_OF_DATA_FRAMES= supports] bzip2-ed frames. Thus, when specifying the frame name parameter of the script, you should leave out any .bz2 extension.
XDS [https://xds.mr.mpg.de/html_doc/xds_parameters.html#NAME_TEMPLATE_OF_DATA_FRAMES= supports] bzip2-ed frames. Thus, when specifying the frame name parameter of the script, you should leave out any .bz2 extension.


For improved interaction with [[XDSGUI]], it is advantageous to use an ''absolute'' filename - one that starts with a slash ("/").
For improved interaction with [[XDSGUI]], it is advantageous to provide an ''absolute'' filename for the data files - one that starts with a slash ("/").


== The script ==
== The script ==
<!-- leave a blank line after <pre>! KD 10/2023 -->
<div class="toccolours mw-collapsible mw-collapsed">
Expand code section below (i.e. click on blue <code>[Expand]</code> at the end of this line if there is no code visible)
<div class="mw-collapsible-content">


<pre>
<pre>
#!/bin/bash                                                                  
 
# purpose: generate XDS.INP                                                  
#!/bin/bash
#                                                                            
# purpose: generate XDS.INP
# tested with some datasets from ALS, SSRL, SLS, ESRF, BESSY, SPring-8 and PF; only MAR, ADSC/SMV, PILATUS, Eiger, RAXIS (in-house), Bruker (Photonics II) detectors;  
#
# for other detectors, values marked with XXX must be manually filled in.                                
# tested with some datasets from ALS, SSRL, SLS, ESRF, BESSY, SPring-8 and PF; only MAR, ADSC/SMV, PILATUS, Eiger, RAXIS (in-house), Bruker (PHOTON II) detectors;
#                                                                                                        
# for other detectors, values marked with XXX must be manually filled in.
# revision 0.03 . Kay Diederichs 2/2010                                                                  
#
# revision 0.04 . Kay Diederichs 4/2010 - include alternative ORGX, ORGY calculations for ADSC            
# revision 0.03 . Kay Diederichs 2/2010
# revision 0.05 . Kay Diederichs 5/2010 - grep for "Corrected" in addition to "marccd"; needed for BESSY  
# revision 0.04 . Kay Diederichs 4/2010 - include alternative ORGX, ORGY calculations for ADSC
# revision 0.06 . KD 6/2010 - add UNTRUSTED_RECTANGLE and UNTRUSTED_ELLIPSE; use `whereis catmar` and so on  
# revision 0.05 . Kay Diederichs 5/2010 - grep for "Corrected" in addition to "marccd"; needed for BESSY
# revision 0.07 . KD 6/2010 - decide about ORGX/Y info in MAR header being pixels or mm; other fixes      
# revision 0.06 . KD 6/2010 - add UNTRUSTED_RECTANGLE and UNTRUSTED_ELLIPSE; use `whereis catmar` and so on
# revision 0.08 . KD 6/2010 - fixes for Pilatus 6M                                                        
# revision 0.07 . KD 6/2010 - decide about ORGX/Y info in MAR header being pixels or mm; other fixes
# revision 0.09 . KD 6/2010 - get rid of requirement for mccd_xdsparams.pl and/or catmar; rather use "od"  
# revision 0.08 . KD 6/2010 - fixes for Pilatus 6M
# revision 0.10 . Tim Gruene 7/2010 - set link 'images' to image directory if path exceeds 72 characters  
# revision 0.09 . KD 6/2010 - get rid of requirement for mccd_xdsparams.pl and/or catmar; rather use "od"
# revision 0.11 . KD 7/2010 - for MarCCD: look for distance info at different byte position                
# revision 0.10 . Tim Gruene 7/2010 - set link 'images' to image directory if path exceeds 72 characters
# revision 0.12 . KD 7/2010 - fix for negative PHISTART                                                    
# revision 0.11 . KD 7/2010 - for MarCCD: look for distance info at different byte position
# revision 0.13 . KD 8/2010 - store correct NX NY QX QY in XDS.INP                                        
# revision 0.12 . KD 7/2010 - fix for negative PHISTART
# revision 0.14 . KD 1/2011 - SENSOR_THICKNESS for Pilatus; MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=3          
# revision 0.13 . KD 8/2010 - store correct NX NY QX QY in XDS.INP
# revision 0.14 . KD 1/2011 - SENSOR_THICKNESS for Pilatus; MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=3
# revision 0.15 . KD 2/2011 - add comment for -ive sign of APS 19-ID and Australian Synchrotron rotation axis
# revision 0.15 . KD 2/2011 - add comment for -ive sign of APS 19-ID and Australian Synchrotron rotation axis
# revision 0.16 . KD 3/2011 - SENSOR_THICKNESS=0.01 for ADSC and MarCCD. Add comment about SILICON=        
# revision 0.16 . KD 3/2011 - SENSOR_THICKNESS=0.01 for ADSC and MarCCD. Add comment about SILICON=
# revision 0.17 . KD 3/2011 - make it work for .bz2 frames; improve screen output                          
# revision 0.17 . KD 3/2011 - make it work for .bz2 frames; improve screen output
# revision 0.18 . KD 4/2011 - faster by doing "strings" only once; revert "images/${1##/*/}" "correction"  
# revision 0.18 . KD 4/2011 - faster by doing "strings" only once; revert "images/${1##/*/}" "correction"
# revision 0.19 . KD 6/2011 - bugfix for 0.18                                                              
# revision 0.19 . KD 6/2011 - bugfix for 0.18
# revision 0.20 . KD 7/2011 - redirect stderr of /bin/ls to /dev/null                                      
# revision 0.20 . KD 7/2011 - redirect stderr of /bin/ls to /dev/null
# revision 0.21 . KD 11/2011 - SEPMIN, CLUSTER_RADIUS hints; read NX NY from header (for Pilatus 2M)
# revision 0.21 . KD 11/2011 - SEPMIN, CLUSTER_RADIUS hints; read NX NY from header (for Pilatus 2M)
# revision 0.22 . KD 12/2011 - Pilatus 2M UNTRUSTED_RECTANGLE lines, SENSOR_THICKNESS from header
# revision 0.22 . KD 12/2011 - Pilatus 2M UNTRUSTED_RECTANGLE lines, SENSOR_THICKNESS from header
Line 52: Line 57:
# revision 0.35 . KD 6/2013 - reduce 7000 to 6000 for shadow detection; insert comment about *_RESOLUTION_RANGE lines
# revision 0.35 . KD 6/2013 - reduce 7000 to 6000 for shadow detection; insert comment about *_RESOLUTION_RANGE lines
# revision 0.36 . KD 6/2013 - insert NUMBER_OF_PROFILE_GRID* lines for Pilatus (suggested by C.Vonrhein)
# revision 0.36 . KD 6/2013 - insert NUMBER_OF_PROFILE_GRID* lines for Pilatus (suggested by C.Vonrhein)
# revision 0.37 . Keitaro 10/2013 - fix for MX225HS detector on SPring-8 BL32XU (Ignore case when matching marccd in header); but cannot decide reverse-phi because of missing detector S/N
# revision 0.37 . Keitaro 10/2013 - fix for MX225HS detector on SPring-8 BL32XU (Ignore case when matching marccd in header); see also rev-0.39
# revision 0.38 . KD 2/2014 - change defaults for REFINE(IDXREF) and REFINE(INTEGRATE) such that more stable results are obtained for difficult datasets
# revision 0.38 . KD 2/2014 - change defaults for REFINE(IDXREF) and REFINE(INTEGRATE) such that more stable results are obtained for difficult datasets
# revision 0.39 . Keitaro 4/2014 - automatically set ROTATION_AXIS=-1 0 0 for MX225HS at SPring-8 BL32XU.
# revision 0.39 . Keitaro 4/2014 - automatically set ROTATION_AXIS=-1 0 0 for MX225HS at SPring-8 BL32XU.
Line 63: Line 68:
# revision 0.46 . Keitaro 6/2014 automatically set ROTATION_AXIS=-1 0 0 for Mar225 at SPring-8 BL26B2.
# revision 0.46 . Keitaro 6/2014 automatically set ROTATION_AXIS=-1 0 0 for Mar225 at SPring-8 BL26B2.
# revision 0.47 . Keitaro 7/2014 more generic dTREK format support (Saturn and RAXIS)
# revision 0.47 . Keitaro 7/2014 more generic dTREK format support (Saturn and RAXIS)
# revision 0.48 . Kip Guja 11/2014 add detector serial number for ALS 5.0.2 to beam center convention 1  
# revision 0.48 . Kip Guja 11/2014 add detector serial number for ALS 5.0.2 to beam center convention 1
# revision 0.49 . Nobuhisa 2/2015 add  detector serial number for AichiSR BL2S1 to beam center convention 1
# revision 0.49 . Nobuhisa 2/2015 add  detector serial number for AichiSR BL2S1 to beam center convention 1
# revision 0.50 . KD 03/2015 workaround for Mar-1 change of parameter name "DISTANCE" to "POSITION" in REFINE(*) keywords
# revision 0.50 . KD 03/2015 workaround for Mar-1 change of parameter name "DISTANCE" to "POSITION" in REFINE(*) keywords
Line 74: Line 79:
# revision 0.57 . KD 12/2015 start to take care of vertical ROTATION_AXIS at Diamond I24 - for now only introduce comment
# revision 0.57 . KD 12/2015 start to take care of vertical ROTATION_AXIS at Diamond I24 - for now only introduce comment
# revision 0.58 . Keitaro 01/2016 fix for dTREK image: take 'rotation axis' information from header
# revision 0.58 . Keitaro 01/2016 fix for dTREK image: take 'rotation axis' information from header
# revision 0.59 . KD 04/04/2016 check for ADSC detector _after_ checking for dtrek detector, to correct wrong choice for https://zenodo.org/record/45756
# revision 0.59 . KD 04/04/2016 check for ADSC detector _after_ dtrek detector, to correct wrong choice for https://zenodo.org/record/45756
# revision 0.60 . KD 04/04/2016 ADSC detector SN=458 at APS 19-ID has reverse phi (https://zenodo.org/record/45756)
# revision 0.60 . KD 04/04/2016 ADSC detector SN=458 at APS 19-ID has reverse phi (https://zenodo.org/record/45756)
# revision 0.61 . Keitaro 10/04/2016 Add Eiger hdf5 support (may be incomplete; UNTRUSTED_RECTANGLE=s not set) NEED h5dump.
# revision 0.61 . Keitaro 10/04/2016 Add Eiger hdf5 support (may be incomplete; UNTRUSTED_RECTANGLE=s not set) NEED h5dump.
Line 81: Line 86:
# revision 0.64 . KD 16/06/2016 reverse phi @APS 19ID (reported by Wolfram Tempel)
# revision 0.64 . KD 16/06/2016 reverse phi @APS 19ID (reported by Wolfram Tempel)
# revision 0.65 . Keitaro 07/09/2016 Fix for "too many arguments" problem in ls
# revision 0.65 . Keitaro 07/09/2016 Fix for "too many arguments" problem in ls
# revision 0.65 . KD 15/09/2016 Add Bruker Photonics II with .cbf frames
# revision 0.66 . KD 15/09/2016 add Bruker PHOTON II with .cbf frames
REVISION="0.66 (15-Sep-2016)"
# revision 0.67 . KD 02/10/2016 add BM30A (ADSC SERIAL 924) reverse_phi
#                                                                                                          
# revision 0.68 . KD 24/10/2016 add -H option (follow symlinks) to "find" command (thanks to Jan Gebauer!)
# usage: e.g. generate_XDS.INP "/file/system/frms/mydata_1_???.img"                                                      
# revision 0.69 . KD 04/11/2016 add CMOS-1 MBC Detector at ALS 4.2.2
# make sure to have the two quotation marks !                                                              
# revision 0.70beta . KD 08/12/2016 ROTATION_AXIS=0 -1 0 at Diamond I24; depending on CBF header
# the ? are wildcards for the frame numbers.                                                                
# revision 0.70 . KD 12/01/2017 remove error message if h5dump does not find /entry/sample/transformations/omega/vector
#                                                                                                          
# revision 0.71 . KD 27/02/2017 implement rule for S/N 916 @ APS 24_ID_E
# known problems:                                                                                          
# revision 0.72 . KD 8/03/2017 fix nframes lookup in Eiger master file
# revision 0.73 . KD 18/05/2017 for Andrey Nascimento: add Pilatus 2M S/N 24-0109 with ROTATION_AXIS=-1 0 0
# revision 0.74 . Keitaro 02/08/2017 Add PILATUS3 6M, S/N 60-0127 at CHESS F1 with  ROTATION_AXIS=-1 0 0
# revision 0.75 . KD 30/08/2017 reversed ORGX and ORGY for marCCD @ BM14 (Indian beamline @ ESRF)
# revision 0.76 . KD 4/09/2017 include POSITION into REFINE(IDXREF) because latest XDS is more robust. Add comments to keywords.
# revision 0.77 . KD 19/12/2017 obtain QX QY from CBF header.
# revision 0.78 . KD 21/12/2017 if possible and sensible, provide LIB= line with hardcoded /usr/local/lib64/dectris-neggia.so .
# revision 0.79 . KD 16/01/2018 read OVERLOAD from Pilatus miniCBF header instead of fixing at 1048576
# revision 0.80 . KD 13/02/2018 remove DISTANCE keyword from REFINE() list; remove POSITION from REFINE(IDXREF)
# revision 0.81 . KD 21/02/2018 when encountering CBF files from Eiger (ESRF), treat as Pilatus detector
# revision 0.82 . KD 01/03/2018 STARTING_ANGLE for MarCCD/Pilatus/PHOTON, enabling to use dials.rs_mapper with spot2pdb.
# revision 0.83 . KD 25/06/2018 for ADSC detector #458 at APS BM19, revert the definition of ROTATION_AXIS=-1 0 0. See "Beamline notes" in this wiki.
# revision 0.84 . KD 10/10/2018 implement Pilatus detector with d*TREK header
# revision 0.85 . Jie Nan 09/01/2019 STARTING_ANGLE for Eiger
# revision 0.86 . Keitaro 03/05/2019 Add PILATUS3 6M, S/N 60-0123 at SSRF BL18U-1 with ROTATION_AXIS=-1 0 0
# revision 0.87 . KD 12/10/2019 Add PILATUS XXX, S/N XX-XXX at SSRF BL19U1 and MarCCD detector #43 at BL17B1 with ROTATION_AXIS=-1 0 0
# 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.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.96 . KD 03/10/2020 make script echo detector serial number if inverted ROTATION_AXIS is detected.
# revision 0.97 . KD 19/10/2020 add UNTRUSTED_RECTANGLEs for Eiger2 (which has a few pixels less than Eiger (thanks to Andreas Förster)
# revision 0.98 . Thomas Hauß (HZB) 06/11/2020 switch Python print syntax to Python3
# revision 0.99 . Aaron Finke (CHESS) 07/11/2020 add ROTATION_AXIS=-1 0 0 for EIGER2 16M detector at MX beamline ID7B2 (CHESS)
# revision 1.00 . Gleb Bourenkov 10/11/2020 add ROTATION_AXIS=0 -1 0 for beamline P14 (EMBL Hamburg) detectors Eiger 16M S/N E-32-0107; previously Eiger 4M S/N E-08-0107 and PILATUS 6M-F, S/N 60-0115-F
# revision 1.01 . KD 07/12/2020 ROTATION_AXIS=0 -1 0 for Pilatus3 2M, S/N 24-0118 at ID23-2 (http://www.globalphasing.com/autoproc/wiki/index.cgi?BeamlineSettings)
# revision 1.02 . KD 11/01/2021 recognize mar555 detector as mar345 (thanks to Thomas Hauß, HZB)
# revision 1.03 . Feng Yu 18/7/2021 fix/expand information about Shanghai Synchrotron Radiation Facility (SSRF)
# revision 1.04 . Zhipu Luo 13/08/2021 extract ORGX,ORGY for electron diffraction from SMV header if the wavelength value starts with 0.0
# revision 1.05 . KD specialcase extraction of number of images for BNL detectors E-32-0101 and E-18-0104
# revision 1.06 . KD fix URLs in output. Availability of Apple M1 processor dectris-neggia-Apple-arm64.so . LC_ALL=C .
# revision 1.07 . KD, Thomas Hauß, Gleb Bourenkov 25/10/2021. Detector moved from Petra P14 to P13
# 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.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.14 . Juno Krahn 16/03/2023 Modified initial string header extraction; added exit to awk token extractions
#                      Print help if multiple arguments (e.g. forgot quotes) or if neither '???' or master.h5
#                      Set full path for frames; needed by some tools (e.g. show frame with predicted spots)
#                      Comment out FRACTION_OF_POLARIZATION if wavelength is copper K-alpha
#                      2-theta offset, rotation axis, starting angle, and flipping updated for all dtrek detectors
#                      Untrusted rectangle for Saturn944
#                      Environment variables to define alternate paths for dectris-neggia.so and durin-plugin.so
#                      Append detector specific parameters from $HOME/.xds-site/${DET}_${DET_SN}
#                      Cleaned up section for creating XDS.INP
# revision 1.15 . KD 22/05/2023 fix bug with second argument leading to usage message. Updating links.
# revision 1.16 . KD 26/05/2023 fix bug on Mac for Pilatus CBF missing two lines
# revision 1.17 . JMK 31/05/2023 fix sed error for Mac, where \| is not supported
# revision 1.18 . JMK 19/08/2023 Pilatus 12M support, give help msg if $5 defined (i.e. unquoted frame pattern)
# revision 1.19 . KD 14/10/2023 Pilatus 12M at DLS I23 has reverse phi. Fix download commands.
# revision 1.20 . KD 13/7/2024 Comment out line STRONG_PIXEL=4 in preparation for mid-2024 version of XDS.
REVISION="1.20 (13-Jul-2024)"
 
#
# usage: e.g. generate_XDS.INP "/file/system/frms/mydata_1_???.img"
# make sure to have the two quotation marks !
# the ? are wildcards for the frame numbers.
#
# known problems:
# - 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, Xcode (from http://developer.apple.com/tools/xcode) might be needed - not sure about this                             
# - 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 -v 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
#                                                                                                              
#
# ====== Start of script ======                                                                                
# ====== Start of script ======
echo generate_XDS.INP version $REVISION . Obtain the latest version from                                        
echo generate_XDS.INP version $REVISION. Obtain the latest version from
echo http://strucbio.biologie.uni-konstanz.de/xdswiki/index.php/generate_XDS.INP                                
echo http://wiki.uni-konstanz.de/xds/index.php/generate_XDS.INP
if [ "$1" == "help" ] || [ "$1" == "-help" ] || [ "$1" == "-h" ]; then                                          
if [ "$1" == "help" ] || [ "$1" == "-help" ] || [ "$1" == "-h" ] || [ "$1" == "" ] || [ "$5" != "" ] || ! [[ "$1" =~ \?\?|_master\.h5 ]]; then
   echo usage: generate_XDS.INP \"/file/system/frms/mydata_1_???.img\"  \(_with_ the quotation marks!\)                      
   echo usage: generate_XDS.INP \"/file/system/frms/mydata_1_???.img\"  \(_with_ the quotation marks!\)
   echo if the frames are compressed with bzip2, leave out the .bz2 extension!                                  
   echo If the frames are compressed leave out the extension .bz2, .gz, or .xz!
   exit                                                                                                          
  echo for .h5 files: generate_XDS.INP /file/system/frms/mydata_1_master.h5
fi                                                                                                              
   exit
#                                                                                                              
fi
# defaults:                                                                                                    
# make sure the locale does not interfere with e.g. awk calculations:
#                                                                                                              
export LC_ALL="C"
DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX"                                                      
#
# defaults:
#
# conversion radian / degrees:
DEGTOR=57.2957795
 
DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX"
REVERSE_PHI="no"
REVERSE_PHI="no"
ORGX=XXX                                                                                                        
ORGX=XXX
ORGY=XXX                                                                                                        
ORGY=XXX
DETECTOR_DISTANCE=XXX                                                                                          
DETECTOR_DISTANCE=XXX
OSCILLATION_RANGE=XXX                                                                                          
OSCILLATION_RANGE=XXX
X_RAY_WAVELENGTH=XXX                                                                                            
X_RAY_WAVELENGTH=XXX
QX=XXX                                                                                                          
QX=XXX
QY=XXX                                                                                                          
QY=XXX
NX=XXX                                                                                                          
NX=XXX
NY=XXX                                                                                                          
NY=XXX
SENSOR_THICKNESS=0  
SENSOR_THICKNESS=0
TRUSTED_REGION="0.0 1.2 ! partially use corners of detector (0 1.4143: use all pixels)"                                                                                          
TRUSTED_REGION="0.0 1.2 ! partially use corners of detector (0 1.4143: use all pixels)"
# default MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT
# default MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT
MNOPIAS=3  
MNOPIAS=3
# 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
# default POLARIZATION_PLANE_NORMAL
POLARIZATION_PLANE_NORMAL="0 1 0"
STARTING_ANGLE=0
dtrek_det=""
SEPMIN=7.0
CLUSTER_RADIUS=3.5
REFINE_CORRECT="CELL BEAM ORIENTATION AXIS POSITION ! Default is: refine everything"


dname=`echo "$1" | xargs dirname`
dname=$(dirname "$1")
# Convert to full path (verify 'realpath' is available first)
command -v realpath &> /dev/null && dname=$(realpath $dname)
test "${dname}" == "" && dname="."
test "${dname}" == "" && dname="."
bname=`echo "$1" | xargs basename`
bname=$(basename "$1")
# see how we are called:                                                                                        
# see how we are called:
NAME_TEMPLATE_OF_DATA_FRAMES="${dname}/${bname}"
NAME_TEMPLATE_OF_DATA_FRAMES="${dname}/${bname}"
# list frames matching the wildcards in NAME_TEMPLATE_OF_DATA_FRAMES
# list frames matching the wildcards in NAME_TEMPLATE_OF_DATA_FRAMES
# don't accept the "direct beam" shot at SLS/Pilatus PX-I and PX-II  
# don't accept the "direct beam" shot at SLS/Pilatus PX-I and PX-II
# cope with blanks in directory / file name
# cope with blanks in directory / file name
IFS=$'\n'
IFS=$'\n'
find $dname -name "$bname" -or -name "${bname}.bz2" -or -name "${bname}.gz" -or -name "${bname}.xz" | egrep -v "_00000.cbf|_000.img" | sort > tmp1
find -H $dname -maxdepth 1 -name "$bname" -or -name "${bname}.bz2" -or -name "${bname}.gz" -or -name "${bname}.xz" | egrep -v "_00000.cbf|_000.img" | sort > tmp1
if [ ! -s tmp1 ]
if [ ! -s tmp1 ]
then
then
Line 152: Line 238:
  # Find the first '?' position and the number of '?' to determine DATA_RANGE=.
  # Find the first '?' position and the number of '?' to determine DATA_RANGE=.
  pos1=`echo "$NAME_TEMPLATE_OF_DATA_FRAMES" | awk '{print index($0, "?")}'`
  pos1=`echo "$NAME_TEMPLATE_OF_DATA_FRAMES" | awk '{print index($0, "?")}'`
  pos2=`echo "$NAME_TEMPLATE_OF_DATA_FRAMES" | sed -e "s/[^\?]//g" | awk '{print length+'$pos1' - 1'}`
  pos2=`echo "$NAME_TEMPLATE_OF_DATA_FRAMES" | sed -e "s/[^\?]//g" | awk '{print length+'$pos1' - 1}'`
  data_first=`cat tmp1 | cut -b $pos1-$pos2 | head -n1|bc`
  data_first=`cut -b $pos1-$pos2 tmp1 | head -n1 | bc`
  data_last=`cat tmp1 | cut -b $pos1-$pos2 | tail -n1|bc`
  data_last=`cut -b $pos1-$pos2 tmp1 | tail -n1 | bc`
  DATA_RANGE="$data_first $data_last"
  DATA_RANGE="$data_first $data_last"
   
  echo DATA_RANGE=$DATA_RANGE
 
  # set SPOT_RANGE to first half of DATA_RANGE
  # set SPOT_RANGE to first half of DATA_RANGE
  data_num=`wc -l tmp1 | awk '{print $1}'`
  data_num=`wc -l tmp1 | awk '{print $1}'`
  data_half=`echo "scale=0; $data_num/2" | bc -l`                      
  data_half=`echo "scale=0; $data_num/2" | bc -l`
  data_half=`echo "if ($data_half<=1) 1;if ($data_half>1) $data_half" | bc -l`
  data_half=`echo "if ($data_half<=1) 1;if ($data_half>1) $data_half" | bc -l`
  spot_last=`echo "scale=0; $data_first+$data_half-1" | bc -l`
  spot_last=`echo "scale=0; $data_first+$data_half-1" | bc -l`
Line 167: Line 254:
FIRSTFRAME=`head -1 tmp1`
FIRSTFRAME=`head -1 tmp1`
echo $FIRSTFRAME | grep "\.h5$" && is_h5=1 || is_h5=0
echo $FIRSTFRAME | grep "\.h5$" && is_h5=1 || is_h5=0
if [ "$is_h5" == 1 ]; then
nframes=`h5dump -A -g "/entry/data" $FIRSTFRAME | grep "DATASPACE  SIMPLE" | sed -e "s/,.*//" | awk '{a+=$5}END{print a}'`
DATA_RANGE="1 $nframes"
SPOT_RANGE="1 `echo "scale=0; ${nframes}/2"|bc -l`"
fi
echo DATA_RANGE=$DATA_RANGE


# find out detector type
# find out detector type
DET=XXX            
DET=XXX
IFS=$'\n'  
IFS=$'\n'
echo $FIRSTFRAME | grep -q '\.bz2$' && bzcat $FIRSTFRAME > tmp1 && FIRSTFRAME=tmp1
echo $FIRSTFRAME | grep -q '\.bz2$' && bzcat $FIRSTFRAME > tmp1 && FIRSTFRAME=tmp1
# for mac/linux compatibility. zcat foo.gz doesn't work on mac.
# for mac/linux compatibility. zcat foo.gz doesn't work on mac.
Line 186: Line 265:
unset IFS
unset IFS
if [ "$is_h5" == 0 ]; then
if [ "$is_h5" == 0 ]; then
  strings $FIRSTFRAME > tmp2  
# extract strings from binary file header, removing leading '#' (Pilatus) and trailing ';' (CBF)
  strings $FIRSTFRAME | head -400 | sed 's/^ *#//;s/; *$//;' >tmp2
  # TODO: whenever FIRSTFRAME is used below, it should be copied to tmp2 (using IFS as above), and tmp2 should be used instead
  # TODO: whenever FIRSTFRAME is used below, it should be copied to tmp2 (using IFS as above), and tmp2 should be used instead
  # this was done for "mccd", but still has to be done for the "raxis" detector types
  # this was done for "mccd", but still has to be done for the "raxis" detector types
  # the reason is that FIRSTFRAME may contain a blank, which makes some commands fail                                              
  # the reason is that FIRSTFRAME may contain a blank, which makes some commands fail
  egrep -qi 'marccd|Corrected' tmp2 && DET=mccd                                
  egrep -qi 'marccd|Corrected' tmp2 && DET=mccd
  grep -q PILATUS tmp2            && DET=pilatus                            
  grep -q PILATUS tmp2            && DET=pilatus
grep -iq Eiger tmp2              && DET=pilatus
  head -n1 tmp2 | grep -q "^RAXIS" && DET=raxis
  head -n1 tmp2 | grep -q "^RAXIS" && DET=raxis
  head -n1 tmp2 | grep -q "^R-AXIS" && DET=raxis
  head -n1 tmp2 | grep -q "^R-AXIS" && DET=raxis
  grep -q "^SOURCE_WAVELENGTH= *1" tmp2 && DET=dtrek
  grep -q "^SOURCE_WAVELENGTH= *1" tmp2 && DET=dtrek
  grep -q BEAM_CENTER_X tmp2      && DET=adsc                                
  grep -q BEAM_CENTER_X tmp2      && DET=adsc
  grep -q mar345 tmp2 && DET=MAR345    
  grep -q mar345 tmp2 && DET=MAR345
  grep -q BRUKER tmp2 && grep -q CBF tmp2  && DET=Bruker-cbf                  
# rev. 1.02: in one case, mar555 data could be processed pretending it is mar345, so:
grep -q mar555 tmp2 && DET=MAR345
  grep -q BRUKER tmp2 && grep -q CBF tmp2  && DET=Bruker-cbf
grep -q CMOS1 tmp2 && DET=adsc-CMOS1
grep -q MARCONTROL tmp2 && DET=OLDMAR
grep -q "WAVELENGTH=0.0" tmp2 && DET=experimental-ED
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
fi
fi


# identify other detector types in the same way  
# identify other detector types in the same way


# parse ASCII header of first frame
# parse ASCII header of first frame


if [ "$DET" == "XXX" ]; then
if [ "$DET" == "XXX" ]; then
   echo "this is not a MAR, ADSC/SMV or PILATUS detector - fill in XXX values manually!"
   echo "Detector type unknown -- fill in XXX values manually!"
   DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX"                          
   DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX"


# find parameters of first frame
# find parameters of first frame
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"
   SENSOR_THICKNESS=0.01                                          
   SENSOR_THICKNESS=0.01
   # use first frame of dataset to obtain parameters              
   # use first frame of dataset to obtain parameters


   # Check detector serial number and recognize beamline for reversed-phi setting.
   # Check detector serial number and recognize beamline for reversed-phi setting.
   # Known detectors for reversed-phi in SPring-8: 24: BL26B2 Mar225, 31: BL32XU MX225HE, 38: BL44XU MX225HE, 42: BL44XU MX300HE, 40: BL41XU MX225HE, 106: BL32XU MX225HS
   # Known detectors for reversed-phi in SPring-8: 24: BL26B2 Mar225, 31: BL32XU MX225HE, 38: BL44XU MX225HE, 42: BL44XU MX300HE, 40: BL41XU MX225HE, 106: BL32XU MX225HS
  # same for SSRF: BL17B1 rayonix MX300. As on 2019-10-13, this also needs doubling of ORGX and ORGY. But the beamline staff (Wenming) wants to fix the header.
   REVERSEPHI_SNs="
   REVERSEPHI_SNs="
24
24
Line 226: Line 314:
40
40
42
42
43
106
106
"
"
Line 232: Line 321:
   if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
   if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
     REVERSE_PHI="yes"
     REVERSE_PHI="yes"
    echo inverted ROTATION_AXIS since Detector Serial Number is "${DET_SN}"
   fi
   fi


Line 238: Line 328:
   cp $FIRSTFRAME tmp2
   cp $FIRSTFRAME tmp2
   unset IFS
   unset IFS
   let SKIP=1024+80                                                      
   let SKIP=1024+80
   NX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   NX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   let SKIP=$SKIP+4                                                                        
   let SKIP=$SKIP+4
   NY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   NY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')


   let SKIP=1720
   let SKIP=1720
   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`
                                                                                                         
 
   let SKIP=1024+256+128+256+4                                                                            
# Mar 12, 2020 KD
   ORGX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')            
  let SKIP=1724
   ORGX=`echo "scale=2; $ORGX/1000" | bc -l `                                                            
  TWOTHETA=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   let SKIP=$SKIP+4                                                                                      
  TWOTHETA=`echo "scale=3; $TWOTHETA/1000" | bc -l`
   ORGY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')            
  echo 2THETA= $TWOTHETA
   ORGY=`echo "scale=2; $ORGY/1000" | bc -l `                                                            
 
# FIXME 25.5.2015: reverse ORGX and ORGY for BM14 @ ESRF (no serial number in header)
  let SKIP=1024+256+128+256+44
  STARTING_ANGLE=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  STARTING_ANGLE=`echo "scale=2; $STARTING_ANGLE/1000" | bc -l `
 
   let SKIP=1024+256+128+256+4
   ORGX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   ORGX=`echo "scale=2; $ORGX/1000" | bc -l `
   let SKIP=$SKIP+4
   ORGY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   ORGY=`echo "scale=2; $ORGY/1000" | bc -l `
# fixed Aug 30, 2017 after IUCr2017 @ Hyderabad
  if [ "$DET_SN" == "4" ]; then
    TEMP=$ORGY
    ORGY=$ORGX
    ORGX=$TEMP
    echo reversed ORGX and ORGY for marCCD @ ESRF BM14
  fi


   let SKIP=1024+736
   let SKIP=1024+736
   OSCILLATION_RANGE=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')  
   OSCILLATION_RANGE=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   OSCILLATION_RANGE=`echo "scale=3; $OSCILLATION_RANGE/1000" | bc -l`  
   OSCILLATION_RANGE=`echo "scale=3; $OSCILLATION_RANGE/1000" | bc -l`
                                                                                               
 
   let SKIP=1024+256+128+256+128+4                                                              
   let SKIP=1024+256+128+256+128+4
   QX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')    
   QX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   QX=`echo "scale=10; $QX/1000000" |bc -l `                                                    
   QX=`echo "scale=10; $QX/1000000" |bc -l `
   let SKIP=$SKIP+4                                                                              
   let SKIP=$SKIP+4
   QY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')    
   QY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   QY=`echo "scale=10; $QY/1000000" |bc -l `                                                    
   QY=`echo "scale=10; $QY/1000000" |bc -l `


   let SKIP=1024+256+128+256+128+128+12
   let SKIP=1024+256+128+256+128+128+12
   X_RAY_WAVELENGTH=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   X_RAY_WAVELENGTH=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
   X_RAY_WAVELENGTH=`echo "scale=5; $X_RAY_WAVELENGTH/100000" | bc -l`                                  
   X_RAY_WAVELENGTH=`echo "scale=5; $X_RAY_WAVELENGTH/100000" | bc -l`


# at most BLs, ORGX and ORGY are in pixels, but sometimes in mm ... guess:
# at most BLs, ORGX and ORGY are in pixels, but sometimes in mm ... guess:
   NXBYFOUR=`echo "scale=0; $NX/4" | bc -l `                              
   NXBYFOUR=`echo "scale=0; $NX/4" | bc -l `
   ORGXINT=`echo "scale=0; $ORGX/1" | bc -l `                            
   ORGXINT=`echo "scale=0; $ORGX/1" | bc -l `
   if [ $ORGXINT -lt $NXBYFOUR ]; then                                    
   if [ $ORGXINT -lt $NXBYFOUR ]; then
     ORGX=`echo "scale=1; $ORGX/$QX" | bc -l`                            
     ORGX=`echo "scale=1; $ORGX/$QX" | bc -l`
     ORGY=`echo "scale=1; $ORGY/$QY" | bc -l`                            
     ORGY=`echo "scale=1; $ORGY/$QY" | bc -l`
     echo MARCCD detector: header ORGX, ORGY seem to be in mm ... converting to pixels
     echo MARCCD detector: header ORGX, ORGY seem to be in mm ... converting to pixels
   else                                                                              
   else
     echo MARCCD detector: header ORGX, ORGY seem to be in pixel units              
     echo MARCCD detector: header ORGX, ORGY seem to be in pixel units
   fi                                                                                
   fi


elif [ "$DET" == "adsc" ]; then
elif [ "$DET" == "adsc" ]; then
Line 285: Line 391:
   DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000"
   DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000"
   echo Data from ADSC detector. Obtaining ORGX, ORGY depends on beamline setup:
   echo Data from ADSC detector. Obtaining ORGX, ORGY depends on beamline setup:
   SENSOR_THICKNESS=0.01                                                      
   SENSOR_THICKNESS=0.01
  sed s/\;// tmp2 > tmp1                                                     
  mv tmp1 tmp2                                                               


       # find X_RAY_WAVELENGTH:
       # find X_RAY_WAVELENGTH:
Line 294: Line 398:
       # find NX, QX, ORGX and ORGY:
       # find NX, QX, ORGX and ORGY:
       NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
       NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
      NY=`grep SIZE2 tmp2 | tail -1 | sed s/SIZE2=//`
       QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//`
       QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//`
# FIXME - next 2 lines should be done properly, from header
       QY=$QX
      NY=$NX                                             
       QY=$QX                                              
       BEAM_CENTER_X=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//`
       BEAM_CENTER_X=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//`
       BEAM_CENTER_Y=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`
       BEAM_CENTER_Y=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`
# fix 2010-04-26 - tell user about possible ORGX, ORGY alternatives - 
 
       COMMENT_ORGXY="
       COMMENT_ORGXY="
! Following are possible beam center interpretations for ADSC detectors"
! Following are possible beam center interpretations for ADSC detectors"
# at ESRF, PF, ALS 5.0.2 and ... (pls fill in!) the following should be used:        
# at ESRF, PF, ALS 5.0.2, AS MX2 and ... (pls fill in!) the following should be used:
       ORGX1=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l`
       ORGX1=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l`
       ORGY1=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l`
       ORGY1=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l`
       echo - at ESRF, PF, APS Argonne BLs use: ORGX=$ORGX1 ORGY=$ORGY1                  
       echo - at ESRF, PF, ALS 8.2.1, APS Argonne BLs use: ORGX=$ORGX1 ORGY=$ORGY1
       COMMENT_ORGXY="${COMMENT_ORGXY}
       COMMENT_ORGXY="${COMMENT_ORGXY}
! ORGX= $ORGX1 ORGY= $ORGY1 ! For ESRF, PF, APS Argonne ..."
! ORGX= $ORGX1 ORGY= $ORGY1 ! For ESRF, PF, APS, AS MX2 ..."
# this 2nd alternative convention should be used at the following beamlines (pls complete the list): ALS 5.0.3, ...
# this 2nd alternative convention should be used at the following beamlines (pls complete the list): ALS 5.0.3, ...
       ORGX2=`echo "scale=1; $NX-$BEAM_CENTER_X/$QX" | bc -l `
       ORGX2=`echo "scale=1; $NX-$BEAM_CENTER_X/$QX" | bc -l `
       ORGY2=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l `
       ORGY2=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l `
       echo - at e.g. ALS 5.0.3 use: ORGX=$ORGX2 ORGY=$ORGY2                                                        
       echo - at e.g. ALS 5.0.3 use: ORGX=$ORGX2 ORGY=$ORGY2
       COMMENT_ORGXY="${COMMENT_ORGXY}
       COMMENT_ORGXY="${COMMENT_ORGXY}
! ORGX= $ORGX2 ORGY= $ORGY2 ! For ALS 5.0.3,.."
! ORGX= $ORGX2 ORGY= $ORGY2 ! For ALS 5.0.3,.."
# this 3rd alternative convention should be used at the following beamlines (pls complete the list): ALS 8.2.2, ...  
# this 3rd alternative convention should be used at the following beamlines (pls complete the list): ALS 8.2.2, ...
# this alternative is written into the generated XDS.INP ! You have to correct this manually in XDS.INP, or adjust this script.
# this alternative is written into the generated XDS.INP ! You have to correct this manually in XDS.INP, or adjust this script.
       ORGX3=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l `
       ORGX3=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l `
Line 325: Line 428:
       ORGX4=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l `
       ORGX4=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l `
       ORGY4=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l `
       ORGY4=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l `
       echo - at e.g. SPring-8 use: ORGX=$ORGX4 ORGY=$ORGY4  
       echo - at e.g. SPring-8 use: ORGX=$ORGX4 ORGY=$ORGY4
       COMMENT_ORGXY="${COMMENT_ORGXY}
       COMMENT_ORGXY="${COMMENT_ORGXY}
! ORGX= $ORGX4 ORGY= $ORGY4 ! For SPring-8,.."
! ORGX= $ORGX4 ORGY= $ORGY4 ! For SPring-8,.."
Line 331: Line 434:
       # Decision of beam center convention based on detector serial numbers.
       # Decision of beam center convention based on detector serial numbers.
       DET_SN=`grep DETECTOR_SN tmp2 | sed -e "s/DETECTOR_SN=//"`
       DET_SN=`grep DETECTOR_SN tmp2 | sed -e "s/DETECTOR_SN=//"`
       # For convention 1; Known PF detectors = 449: NW12A Q210, 472: NE3A Q270, 474: BL17A Q270, 912: BL5A Q315, 923: ALS BL5.0.2 Q315, 933: AichiSR BL2S1 Q315
      echo Detector serial number is $DET_SN
       # For convention 1; Known PF detectors = 449: NW12A Q210, 472: NE3A Q270, 474: BL17A Q270, 912: BL5A Q315, 923: ALS BL5.0.2 Q315, 933: AichiSR BL2S1 Q315, 916: APS 24 IDE, 928: AS MX2
       ORG1_SNs="
       ORG1_SNs="
449
449
Line 341: Line 445:
911
911
446
446
916
905
928
"
"
       ORG4_SNs="
       ORG4_SNs="
Line 348: Line 455:
       ORGX=$ORGX1
       ORGX=$ORGX1
       ORGY=$ORGY1
       ORGY=$ORGY1
      echo the following was chosen based on detector serial number:
       elif echo "${DET_SN}${ORG4_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
       elif echo "${DET_SN}${ORG4_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
       ORGX=$ORGX4
       ORGX=$ORGX4
       ORGY=$ORGY4
       ORGY=$ORGY4
      echo the following was chosen based on detector serial number:
       else
       else
       ORGX=$ORGX3
       ORGX=$ORGX3
       ORGY=$ORGY3
       ORGY=$ORGY3
      echo the following default was chosen because the detector serial number was not special-cased:
       fi
       fi


       # Check detector serial number and recognize beamline for reversed-phi setting.
       # Check detector serial number and recognize beamline for reversed-phi setting.
       # Known detectors for reversed-phi in SPring-8: 915: BL38B1 Q315; APS 19-ID: 458
       # Known detectors for reversed-phi in SPring-8: 915: BL38B1 Q315; APS 19-ID: 458; BM30A: 924
      # 928 is at Australian Beamline MX2
      # revision 0.83 of this script removes 458 from the list!
       REVERSEPHI_SNs="
       REVERSEPHI_SNs="
915
915
458
924
928
"
"
       if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
       if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
         REVERSE_PHI="yes"
         REVERSE_PHI="yes"
        echo inverted ROTATION_AXIS since detector serial number is ${DET_SN}
       fi
       fi


       # find DETECTOR_DISTANCE and OSCILLATION_RANGE:                                                                              
       # find DETECTOR_DISTANCE and OSCILLATION_RANGE:
       DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=//`                                                                    
       DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=//`
       OSCILLATION_RANGE=`grep OSC_RANGE tmp2 | sed s/OSC_RANGE=//`                                                                  
       OSCILLATION_RANGE=`grep OSC_RANGE tmp2 | sed s/OSC_RANGE=//`
 
elif [ "$DET" == "adsc-CMOS1" ]; then
  DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000"
  echo Data from CMOS1 MBC detector.
  SENSOR_THICKNESS=0.01
  X_RAY_WAVELENGTH=`grep WAVELENGTH tmp2 | head -1 | sed s/WAVELENGTH=//`
  NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
  QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//`
  NY=`grep SIZE2 tmp2 | tail -1 | sed s/SIZE2=//`
  QY=$QX
  ORGX=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//`
  ORGY=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`
  REVERSE_PHI="yes"
  DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=/-/`
  OSCILLATION_RANGE=`grep OMEGA_DELTA tmp2 | sed s/OMEGA_DELTA=//`
  DETECTOR_X_AXIS="-1 0 0"
 
elif [ "$DET" == "experimental-ED" ]; then
  DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000  ! OVERLOAD is really unknown "
  echo --- Electron diffraction data in SMV format!
  SENSOR_THICKNESS=0.01
  X_RAY_WAVELENGTH=`grep WAVELENGTH tmp2 | head -1 | sed s/WAVELENGTH=//`
  NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
  QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//`
  NY=`grep SIZE2 tmp2 | tail -1 | sed s/SIZE2=//`
  QY=$QX
  BEAM_CENTER_X=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//`
  BEAM_CENTER_Y=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`
  QXY=`echo "scale=1; $QX*($BEAM_CENTER_X+$BEAM_CENTER_Y)" | bc -l`
      if [ "$QXY" "<" "$BEAM_CENTER_X" ] ; then
      ORGX=`echo "scale=2; $BEAM_CENTER_Y/$QX" | bc -l`
      ORGY=`echo "scale=2; $BEAM_CENTER_X/$QX" | bc -l`
      else
      ORGX=`echo "scale=2; $BEAM_CENTER_X/1" | bc -l`
      ORGY=`echo "scale=2; $BEAM_CENTER_Y/1" | bc -l`
      fi
  DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=//`
  OSCILLATION_RANGE=`grep OSC_RANGE tmp2 | sed s/OSC_RANGE=//`
  STARTING_ANGLE=`grep OSC_START tmp2 | sed s/OSC_START=//`
  echo --- For TIMEPIX detector, please fix ROTATION_AXIS yourself!
  DIRECTION_OF_DETECTOR_X_AXIS="1 0 0"
  REFINE_CORRECT="ORIENTATION CELL AXIS BEAM ! for ED, no POSITION when CELL is refined"


elif [ "$DET" == "pilatus" ]; then
elif [ "$DET" == "pilatus" ]; then
   DETECTOR="PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= 1048576 !PILATUS"
  echo Data from a Pilatus detector
   QX=0.172 QY=0.172                                                        
  OVERLOAD=1048574
  echo Data from a Pilatus detector                                       
  SEPMIN=4
   sed s/#// tmp2 > tmp1                                                   
  CLUSTER_RADIUS=2
   mv tmp1 tmp2                                                            
  grep -q Count_cutoff tmp2 && OVERLOAD=`awk '/Count_cutoff/{print $2;exit}' tmp2`
   DETECTOR="PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= $OVERLOAD !PILATUS"
   QX=0.172 QY=0.172
# the default above guards against missing Pixel_size line in CBF header
   grep -q Pixel_size tmp2 && QX=`awk '/Pixel_size/{print 1000*$2;exit}' tmp2`
   grep -q Pixel_size tmp2 && QY=`awk '/Pixel_size/{print 1000*$5;exit}' tmp2`


       # find SENSOR_THICKNESS:
       # find SENSOR_THICKNESS:
       SENSOR_THICKNESS=`grep thickness tmp2 | sed -e s/'Silicon sensor, thickness'// | awk '{print $1*1000}'`
       SENSOR_THICKNESS=`grep thickness tmp2 | sed -e s/'Si.* sensor, thickness'// | awk '{print $1*1000}'`
       # find X_RAY_WAVELENGTH:                                                                              
       # find X_RAY_WAVELENGTH:
       X_RAY_WAVELENGTH=`grep Wavelength tmp2 | sed -e s/Wavelength// -e s/A// | awk '{print $1}'`          
       X_RAY_WAVELENGTH=`grep Wavelength tmp2 | sed -e s/Wavelength// -e s/A// | awk '{print $1}'`


       # find NX and NY; 2463/2527 is 6M, 1475/1679 is 2M
       # find NX and NY; 2463/2527 is 6M, 1475/1679 is 2M
       NX=`grep X-Binary-Size-Fastest-Dimension tmp2 | awk '{print $2}'`
       NX=`grep X-Binary-Size-Fastest-Dimension tmp2 | awk '{print $2}'`
       NY=`grep X-Binary-Size-Second-Dimension tmp2 | awk '{print $2}'`  
       NY=`grep X-Binary-Size-Second-Dimension tmp2 | awk '{print $2}'`


       # find ORGX and ORGY:
       # find ORGX and ORGY:
Line 390: Line 551:
       ORGY=`grep Beam_xy tmp2 | sed -e s/\(// -e s/\)// -e s/\,// | awk '{print $3}'`
       ORGY=`grep Beam_xy tmp2 | sed -e s/\(// -e s/\)// -e s/\,// | awk '{print $3}'`


       # find DETECTOR_DISTANCE and OSCILLATION_RANGE:
       # find DETECTOR_DISTANCE, OSCILLATION_RANGE, and STARTING_ANGLE:
       DETECTOR_DISTANCE=`awk '/distance/{print $2}' tmp2`
       DETECTOR_DISTANCE=`awk '/Detector_distance/{print $2;exit}' tmp2`
       DETECTOR_DISTANCE=`echo "$DETECTOR_DISTANCE*1000" | bc -l`
       DETECTOR_DISTANCE=`echo "$DETECTOR_DISTANCE*1000" | bc -l`


       OSCILLATION_RANGE=`awk '/Angle/{print $2}' tmp2`
       OSCILLATION_RANGE=`awk '/Angle_increment/{print $2;exit}' tmp2`
 
      STARTING_ANGLE=`awk '/Start_angle/{print $2;exit}' tmp2`


       # get detector serial number and check if it is included in the list
       # get detector serial number and check if it is included in the list
       # Known detectors for reversed-phi in SPring-8: BL41XU PILATUS3 6M 60-0125
       # Known detectors for reversed-phi in SPring-8: BL41XU PILATUS3 6M 60-0125
       # Known detectors for reversed-phi in APS: 19ID PILATUS3 6M 60-0132
       # Known detectors for reversed-phi in APS: 19ID PILATUS3 6M 60-0132
      # Known detectors for reversed-phi at MX2 beamline (Brazilian Synchrotron National Laboratory - LNLS)
      # Known detectors for reversed-phi at CHESS F1 PILATUS3 6M, S/N 60-0127
      # Known detectors for reversed-phi at SSRF BL18U1 (S/N 60-0123) and BL19U1 (S/N XX-XXX) (!; 2019-10-19: staff will fix this)
       DET_SN=`grep "Detector:" tmp2 | sed "s/^.*Detector: *//"`
       DET_SN=`grep "Detector:" tmp2 | sed "s/^.*Detector: *//"`
      echo detector serial number is $DET_SN
       REVERSEPHI_SNs="
       REVERSEPHI_SNs="
PILATUS3 6M, S/N 60-0125
PILATUS3 6M, S/N 60-0125
PILATUS3 6M, S/N 60-0132
PILATUS3 6M, S/N 60-0132
PILATUS 2M, S/N 24-0109
PILATUS3 6M, S/N 60-0127
PILATUS3 6M, S/N 60-0123
PILATUS 12M, S/N 120-0100
"
"
       if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
       if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
         REVERSE_PHI="yes"
         REVERSE_PHI="yes"
        echo inverted ROTATION_AXIS since detector serial number is ${DET_SN}
      fi
      if [ "$DET_SN" == "PILATUS XXX, S/N XX-XXX" ] ; then
        REVERSE_PHI="yes"
        echo inverted rotation axis at SSRF BL19U1
      fi
# Diamond I24:
      if [ "$DET_SN" == "PILATUS3 6M, S/N 60-0119" ] ; then
        if grep -q "Oscillation_axis X.CW +SLOW" tmp2 ; then
          ROTATION_AXIS="0 -1 0"
          echo ROTATION_AXIS="0 -1 0" at Diamond I24
        fi
      fi
# 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" \
                                        -o "$DET_SN" == "Dectris EIGER2 CdTe 16M, E-32-0129" ] ; then
        ROTATION_AXIS="0 -1 0"
        echo ROTATION_AXIS="0 -1 0" at PETRA P14
      fi
# similarly, Eiger 16M at PETRA P14 until May 22, 2021
      if [ "$DET_SN" == "Dectris Eiger 16M, E-32-0107" ] ; then
        egrep -q '^# 2020-|^# 2021-0[1-5]|^# 2021-06-[01]|^# 2021-06-2[01]' tmp2 || isatP13=1
        if [ "$isatP13" == 1 ] ; then
          echo using the default ROTATION_AXIS=1 0 0 at PETRA P13
        else
          ROTATION_AXIS="0 -1 0"
          echo ROTATION_AXIS="0 -1 0" at PETRA P14
        fi
      fi
# ESRF ID23-2:
      if [ "$DET_SN" == "PILATUS3 2M, S/N 24-0118, ESRF ID23" ] ; then
        ROTATION_AXIS="0 -1 0"
        echo ROTATION_AXIS="0 -1 0" at ESRF ID23-2
       fi
       fi


elif [ "$DET" == "eiger" ]; then
elif [ "$DET" == "eiger" ]; then
   OVERLOAD=`h5dump -d "/entry/instrument/detector/detectorSpecific/countrate_correction_count_cutoff" $FIRSTFRAME | awk '/\(0\):/{print $2}' `
nframes=`h5dump -d "/entry/instrument/detector/detectorSpecific/nimages" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
   DETECTOR="EIGER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= $OVERLOAD !EIGER"
DATA_RANGE="1 $nframes"
SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`"
DET_SN=`h5dump -d "/entry/instrument/detector/detector_number" $FIRSTFRAME | awk '/\(0\): /{print $2}' | sed s/\"//g`
echo detector serial number is $DET_SN
 
# 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
# unfortunately h5dump 1.10 is required to get this right for the DLS .h5 files. This version is available at DLS but maybe not elsewhere
    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
  # 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
    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 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)
    if [ "$STARTING_ANGLE" == "" ]; then
  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"`
    fi
  # 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"`
  # EIGER2 16M CHESS ID7B2 has S/N E-32-0123 (A. Finke 2020-11-07) v0.99
    if [ "$DET_SN" == "E-32-0123" ]; then
      ROTATION_AXIS="-1 0 0"
      echo CHESS ID7B2 with inverted rotation axis
    fi
  # SSRF BL17U1 and SSRF BL10U2 (Feng YU 2021-07-18)
  # Eiger X 16M (S/N E-32-0111) was installed at SSRF BL17U1 from Oct 2017 to Feb 2021. After Feb 2021, it was moved back to SSRF BL10U2.
# 2021-03-01 00:00:00 time stamp is 1614528000
    if [ "$DET_SN" == "E-32-0111" ]; then
      collection_time=`h5dump -d "/entry/instrument/detector/detectorSpecific/data_collection_date" $FIRSTFRAME | grep "(0):" | awk '{print $2}' | sed -e "s/\.\(.*\)//g; s/\"//g"`
      if [ `uname -s` == "Darwin" ]; then
        collection_timestamp=`date -j -f "%Y-%m-%dT%H:%M:%S" $collection_time +%s`
      elif [ `uname -s` == "Linux" ]; then
        collection_timestamp=`date -d $collection_time +%s`
      else
        collection_timestamp=0
      fi
      if [ $collection_timestamp -eq 0 ]; then
        is_ROTATION_AXIS_set=1
        ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME 2>/dev/null || is_ROTATION_AXIS_set=0`
        if [ "$is_ROTATION_AXIS_set" == "1" ]; then
          ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME | grep "(0):" | sed -e "s/^.*://; s/,//g"`
          echo "The rotation axis of SSRF BL10U2 (Eiger X 16M) is $ROTATION_AXIS"
        else
          ROTATION_AXIS="-1 0 0    ! Cannot determine rotation axis. SSRF BL17U1: -1 0 0; SSRF BL02U1: 0 -1 0"
        fi
      elif [ $collection_timestamp -ge 0 ] && [ $collection_timestamp -le 1614528000 ]; then
        # SSRF BL17U1
        ROTATION_AXIS="-1 0 0"
        echo "SSRF BL17U1 (Eiger X 16M) with inverted rotation axis"
      else
        # SSRF BL10U2
        is_ROTATION_AXIS_set=1
        ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME 2>/dev/null || is_ROTATION_AXIS_set=0`
        if [ "$is_ROTATION_AXIS_set" == "1" ]; then
          ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME | grep "(0):" | sed -e "s/^.*://; s/,//g"`
          echo "The rotation axis of SSRF BL10U2 (Eiger X 16M) is $ROTATION_AXIS"
        else
          ROTATION_AXIS="0 -1 0"
          echo "SSRF BL10U2 (Eiger X 16M) with vertical rotation axis"
        fi
      fi
    fi
  # SSRF BL02U1 (Feng YU 2021-07-18)
  # EIGER2 S 9M SSRF BL02U1 has S/N E-18-0121
    if [ "$DET_SN" == "E-18-0121" ]; then
      is_ROTATION_AXIS_set=1
      ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME 2>/dev/null || is_ROTATION_AXIS_set=0`
      if [ "$is_ROTATION_AXIS_set" == "1" ]; then
        ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME | grep "(0):" | sed -e "s/^.*://; s/,//g"`
        echo "The rotation axis of SSRF BL02U1 (Eiger2 S 9M) is $ROTATION_AXIS"
      else
        ROTATION_AXIS="1 0 0"
        echo "SSRF BL02U1 (Eiger2 S 9M) with horizontal rotation axis"
      fi
    fi
# revision 1.05 specialcase nframes for Eiger detectors at BNL
    if [ "$DET_SN" == "E-18-0104" -o "$DET_SN" == "E-32-0101" ]; then
      nframes=`h5dump -A -g "/entry/data" $FIRSTFRAME | grep "DATASPACE  SIMPLE" | sed -e "s/,.*//" | awk '{a+=$5}END{print a}'`
      DATA_RANGE="1 $nframes"
      SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`"
      echo Special case nframes for Eiger detectors at BNL: nframes=$nframes
    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
  echo DATA_RANGE=$DATA_RANGE
   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}'`


      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}'`


      # find ORGX and ORGY:
  # find ORGX and ORGY:
      ORGX=`h5dump -d "/entry/instrument/detector/beam_center_x" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
  ORGX=`h5dump -d "/entry/instrument/detector/beam_center_x" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
      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 :
  DETECTOR_DISTANCE=`h5dump -d "/entry/instrument/detector/detector_distance" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`


      # find DETECTOR_DISTANCE and OSCILLATION_RANGE:
  SEPMIN=4
      DETECTOR_DISTANCE=`h5dump -d "/entry/instrument/detector/detector_distance" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`
  CLUSTER_RADIUS=2
      OSCILLATION_RANGE=`h5dump -d "/entry/sample/goniometer/omega_range_average" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`


      # If rotation vector set (NeXus)
      rotation_axis=`h5dump -a "/entry/sample/transformations/omega/vector" $FIRSTFRAME | grep "(0):" | sed -e "s/^.*://; s/,//g"`
 
elif [ "$DET" == "raxis" ]; then
elif [ "$DET" == "raxis" ]; then
   echo Data from a RAXIS detector
   echo Data from an RAXIS detector


   DETECTOR="RAXIS MINIMUM_VALID_PIXEL_VALUE=0  OVERLOAD=2000000"
   DETECTOR="RAXIS MINIMUM_VALID_PIXEL_VALUE=0  OVERLOAD=2000000"
   #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)))')
 
   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))')
   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))')
   ORGY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(544);print "%.4f"%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)))')
   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)')
   X_RAY_WAVELENGTH=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(292);print("%.6f"%struct.unpack(">f",f.read(4)))')
 
  DIRECTION_OF_DETECTOR_Y_AXIS="0 -1 0"
   QX=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(776);print "%.6f"%struct.unpack(">f",f.read(4))')
  POLARIZATION_PLANE_NORMAL="1 0 0"
   QY=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(780);print "%.6f"%struct.unpack(">f",f.read(4))')
  ROTATION_AXIS="0 1 0"
 
   X_RAY_WAVELENGTH=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(292);print "%.6f"%struct.unpack(">f",f.read(4))')


elif [ "$DET" == "dtrek" ]; then
elif [ "$DET" == "dtrek" ]; then
  echo "Data from a RAXIS or Saturn detector with dTREK format"
  sed s/\;// tmp2 > tmp1
  mv tmp1 tmp2


   dname=`grep "DETECTOR_NAMES=" tmp2 | sed -e "s/.*=//"`
   dname=`grep "DETECTOR_NAMES=" tmp2 | sed -e "s/.*=//"`
   if [ "$dname" == "CCD_" ]; then
   if [ "$dname" == "CCD_" ]; then
     DETECTOR="SATURN MINIMUM_VALID_PIXEL_VALUE=1"
     DETECTOR="SATURN MINIMUM_VALID_PIXEL_VALUE=1"
     dtrek_det="saturn"
     dtrek_det="saturn"
 
  elif [ "$dname" == "PILT_" ]; then
     # Find rotation axis. Warning: currently not support flipping (det(tmpmat)<0)
    DETECTOR="PILATUS MINIMUM_VALID_PIXEL_VALUE=0"
     # I'm not sure this method is really valid - but at least mosflm seems to read this to determine rotation axis.
    dtrek_det="pilatus"
    tmpmat=(`grep ${dname}SPATIAL_DISTORTION_VECTORS= tmp2 | tail -1 | sed -e "s/.*=//"`)
     SEPMIN=3
    rotx=`echo "scale=6; -1.0*${tmpmat[0]}" | bc -l`
    CLUSTER_RADIUS=1.5
    roty=`echo "scale=6; -1.0*${tmpmat[1]}" | bc -l`
    SENSOR_THICKNESS=$(awk 'match($0,/SENSOR_THICKNESS= *(\S*)/,a){printf"%.3f",1000*a[1];exit}ENDFILE{print "0.45"}' tmp2)
    rotation_axis="$rotx $roty 0"
  elif [ "$dname" == "RX_" ]; then
  if [ `echo "(${tmpmat[0]}*${tmpmat[3]}-(${tmpmat[1]}*${tmpmat[2]}))/1"|bc` -lt 0 ]; then
    DETECTOR="RAXIS MINIMUM_VALID_PIXEL_VALUE=0"
    dtrek_det="raxis"
    POLARIZATION_PLANE_NORMAL="1 0 0"
    ROTATION_AXIS="0 1 0"
  else
    DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX"
    dtrek_det="unknown"
     echo "WARNING: Unsupported dTREK detector, check parameters"
  fi
  DET_SN=`awk '/_DETECTOR_IDENTIFICATION=/{print;exit}' tmp2 | sed 's/.*DETECTOR_IDENTIFICATION=//'`
  echo "Data from a $dtrek_det detector with dTREK format, ID=$DET_SN"
  # Find rotation axis and flipping
  # I'm not sure this method is really valid - but at least mosflm seems to read this to determine rotation axis.
  tmpmat=(`grep ${dname}SPATIAL_DISTORTION_VECTORS= tmp2 | tail -1 | sed -e "s/.*=//"`)
  flip=`echo "(${tmpmat[0]}*${tmpmat[3]}-(${tmpmat[1]}*${tmpmat[2]}))/1"|bc`
  if [ "$flip" -ne 1 -a "$flip" -ne -1 ]; then
     echo ""
     echo ""
     echo "WARNING!! not-supported SPATIAL_DISTORTION_VECTORS header detected."
     echo "WARNING!! not-supported SPATIAL_DISTORTION_VECTORS header."
     echo "Please report this to XDSwiki author."
     echo "Please report this to XDSwiki author."
     echo ""
     echo ""
  fi
   elif [ "$flip" -eq -1 ]; then
   else # should be RX_
     echo "Detector is flipped (from SPATIAL_DISTORTION_VECTORS header)"
    DETECTOR="RAXIS MINIMUM_VALID_PIXEL_VALUE=0"
     dtrek_det="raxis"
   fi
   fi
 
  rotx=`echo "scale=6; -1.0*$flip*${tmpmat[0]}" | bc -l`
  roty=`echo "scale=6; -1.0*$flip*${tmpmat[1]}" | bc -l`
  ROTATION_AXIS="$rotx $roty 0"
# 2theta
  TWOTHETA=`awk '/'${dname}'GONIO_VALUES=/{print $2;exit}' tmp2`
  R1=`echo "scale=7; $flip*-c($TWOTHETA/$DEGTOR)" | bc -l`
  R3=`echo "scale=7; $flip* s($TWOTHETA/$DEGTOR)" | bc -l`
  DIRECTION_OF_DETECTOR_X_AXIS="$R1 0 $R3"
  echo "Detector 2-theta = $TWOTHETA  "
  echo DIRECTION_OF_DETECTOR_X_AXIS="$R1 0 $R3"
   # find OVERLOAD
   # find OVERLOAD
   SATURATED_VALUE=`grep SATURATED_VALUE tmp2 | head -1 | sed s/SATURATED_VALUE=//`
   SATURATED_VALUE=`grep SATURATED_VALUE tmp2 | head -1 | sed s/SATURATED_VALUE=//`
Line 503: Line 830:
   ORGY=${SPATIAL_DISTORTION_INFO[1]}
   ORGY=${SPATIAL_DISTORTION_INFO[1]}


   # find DETECTOR_DISTANCE  
   # find DETECTOR_DISTANCE
   GONIO_NAMES=(`grep ${dname}GONIO_NAMES= tmp2 | tail -1 | sed s/.*_GONIO_NAMES=//`)
   GONIO_NAMES=(`grep ${dname}GONIO_NAMES= tmp2 | tail -1 | sed s/.*_GONIO_NAMES=//`)
   GONIO_VALUES=(`grep ${dname}GONIO_VALUES= tmp2 | tail -1 | sed s/.*_GONIO_VALUES=//`)
   GONIO_VALUES=(`grep ${dname}GONIO_VALUES= tmp2 | tail -1 | sed s/.*_GONIO_VALUES=//`)
  GONIO_UNITS=(`grep ${dname}GONIO_UNITS= tmp2 | tail -1 | sed s/.*_GONIO_UNITS=//`)
GONIO_UNITS=(`grep ${dname}GONIO_UNITS= tmp2 | tail -1 | sed s/.*_GONIO_UNITS=//`)
   for i in `seq 1 ${#GONIO_NAMES[*]}`
   for i in `seq 1 ${#GONIO_NAMES[*]}`
   do
   do
   idx=$((i-1))
   idx=$((i-1))
   if [ "${GONIO_NAMES[$idx]}" == "Distance" ]; then
   if [ "${GONIO_NAMES[$idx]}" == "Distance" ]; then
    DETECTOR_DISTANCE="-${GONIO_VALUES[$idx]}"
    if [ $flip -gt 0 ]; then
    # TODO: Check unit!! - ${GONIO_UNITS[$idx]}
      DETECTOR_DISTANCE="-${GONIO_VALUES[$idx]}"
      echo "Detector not flipped; using negative distance"
    else
      DETECTOR_DISTANCE="${GONIO_VALUES[$idx]}"
      echo "Detector flipped; using positive distance"
    fi
    break
   fi
   fi
   done
   done


   # find OSCILLATION_RANGE
   # find OSCILLATION start and range
   ROTATION=(`grep "^ROTATION=" tmp2 | tail -1 | sed s/ROTATION=//`)
   ROTATION=(`grep "^ROTATION=" tmp2 | tail -1 | sed s/ROTATION=//`)
  STARTING_ANGLE=${ROTATION[0]}
   OSCILLATION_RANGE=${ROTATION[2]}
   OSCILLATION_RANGE=${ROTATION[2]}


elif [ "$DET" == "MAR345" ]; then
elif [ "$DET" == "MAR345" ]; then
 
 
  echo  "Data from a Mar345 image plate detector"
  echo  "Data from a Mar345 image plate detector"
  DETECTOR="MAR345  MINIMUM_VALID_PIXEL_VALUE=0  OVERLOAD=130000"
  DETECTOR="MAR345  MINIMUM_VALID_PIXEL_VALUE=0  OVERLOAD=130000"
  NX=`awk '/FORMAT/{print $2}' tmp2`
  NX=`awk '/FORMAT/{print $2;exit}' tmp2`
  NY=$NX
# next line is rev 1.02 (previously NY= $NX):
  QX=`awk '/PIXEL/{print $3/1000.}' tmp2`
  NY=`awk -v NX=$NX '/FORMAT/{print $4/NX;exit}' tmp2`
  QY=`awk '/PIXEL/{print $5/1000.}' tmp2`
  QX=`awk '/PIXEL/{print $3/1000.;exit}' tmp2`
  QY=`awk '/PIXEL/{print $5/1000.;exit}' tmp2`
  if grep -q 'CENTER' tmp2; then
  if grep -q 'CENTER' tmp2; then
   echo Beam center found.
   echo Beam center found.
Line 537: Line 872:
   ORGY=`echo $NY / 2 | bc`
   ORGY=`echo $NY / 2 | bc`
  fi
  fi
  DETECTOR_DISTANCE=`grep 'DISTANCE' tmp2 | awk '{print $2}'`              
  DETECTOR_DISTANCE=`grep 'DISTANCE' tmp2 | awk '{print $2}'`
  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;exit}' tmp2`
NY=$NX
QX=`awk 'NR==2 {print $15;exit}' tmp2`
QY=$QX
ORGX=`awk 'NR==2 {print $19;exit}' tmp2`
ORGY=`awk 'NR==2 {print $20;exit}' tmp2`
DETECTOR_DISTANCE=`awk 'NR==2 {print $22;exit}' tmp2`
X_RAY_WAVELENGTH=`awk 'NR==2 {print $21;exit}' tmp2`
OSCILLATION_RANGE=`awk 'NR==2 {print $24-$23;exit}' 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
 
 
  echo  "Data from a Bruker-cbf detector"
  echo  "Data from a Bruker-cbf detector"
# conversion radian / degrees:
DEGTOR=57.2957795
# MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT:
# MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT:
  MNOPIAS=6  
  MNOPIAS=6
# use complete detector including corners:
# use complete detector including corners:
  TRUSTED_REGION="0 1.42"      
  TRUSTED_REGION="0 1.42"
# polarization
# polarization
  pol_frac=`awk '/polarizn_source_ratio/{print $2}' tmp2`
  pol_frac=`awk '/polarizn_source_ratio/{print $2;exit}' tmp2`
  pol_frac=`echo "${pol_frac}+0.5" | bc -l`
  pol_frac=`echo "${pol_frac}+0.5" | bc -l`
  OVERLOAD=`awk '/_array_intensities.overload/{print $2}' tmp2`
  OVERLOAD=`awk '/_array_intensities.overload/{print $2;exit}' tmp2`
  DETECTOR="BRUKER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD=${OVERLOAD}"
  DETECTOR="BRUKER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD=${OVERLOAD}"
  NX=`awk '/X-Binary-Size-Fastest-Dimension/{print $2}' tmp2`
  NX=`awk '/X-Binary-Size-Fastest-Dimension/{print $2;exit}' tmp2`
  NY=`awk '/X-Binary-Size-Second-Dimension/{print $2}' tmp2`
  NY=`awk '/X-Binary-Size-Second-Dimension/{print $2;exit}' tmp2`
 
  QX=`awk '/ELEMENT_X ELEMENT_X/{print $4}' tmp2`
  QX=`awk '/ELEMENT_X ELEMENT_X/{print $4;exit}' tmp2`
  QY=`awk '/ELEMENT_Y ELEMENT_Y/{print $4}' tmp2`
  QY=`awk '/ELEMENT_Y ELEMENT_Y/{print $4;exit}' tmp2`


# ORGX/Y-offsets relative to center of detector:
# ORGX/Y-offsets relative to center of detector:
Line 568: Line 919:
  ORGY=`echo "scale=2; ${NY}/2-($ORGY/$QY)" | bc -l`
  ORGY=`echo "scale=2; ${NY}/2-($ORGY/$QY)" | bc -l`


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


X_RAY_WAVELENGTH=`awk '/diffrn_radiation_wavelength.wavelength/{print $2}' tmp2`
OMEGA=`awk '/OMEGA \? \? \?/{print $5}' tmp2`
DELTAOMEGA=`awk '/OMEGA \? \? \?/{print $6}' tmp2`
PHI=`awk '/PHI \? \? \?/{print $5}' tmp2`
DELTAPHI=`awk '/PHI \? \? \?/{print $6}' tmp2`
KAPPA=`awk '/CHI \? \? \?/{print $5}' tmp2`
echo OMEGA DELTAOMEGA PHI DELTAPHI KAPPA= $OMEGA $DELTAOMEGA $PHI $DELTAPHI $KAPPA
# test whether the absolute value of deltaphi is > absolute value of deltaomega
# test whether the absolute value of deltaphi is > absolute value of deltaomega
  if (( $(echo "${DELTAPHI}^2 > ${DELTAOMEGA}^2"|bc -l) )); then
  if (( $(echo "${DELTAPHI}^2 > ${DELTAOMEGA}^2"|bc -l) )); then
Line 583: Line 936:
     R1=`echo "scale=7; s($KAPPA/$DEGTOR)*c($OMEGA/$DEGTOR)" | bc -l`
     R1=`echo "scale=7; s($KAPPA/$DEGTOR)*c($OMEGA/$DEGTOR)" | bc -l`
     R2=`echo "scale=7; c($KAPPA/$DEGTOR)          " | bc -l`
     R2=`echo "scale=7; c($KAPPA/$DEGTOR)          " | bc -l`
     rotation_axis="$R1 $R2 $R3"
     ROTATION_AXIS="$R1 $R2 $R3"
     OSCILLATION_RANGE=${DELTAPHI}
     OSCILLATION_RANGE=${DELTAPHI}
# here we could check if DELTAPHI is <0, and if so, negate it and rotation_axis
    STARTING_ANGLE=${PHI}
# here we could check if DELTAPHI is <0, and if so, negate it and ROTATION_AXIS
  else
  else
     echo OMEGA scan
     echo OMEGA scan
     rotation_axis="0 -1 0"
     ROTATION_AXIS="0 -1 0"
     OSCILLATION_RANGE=${DELTAOMEGA}
     OSCILLATION_RANGE=${DELTAOMEGA}
# here we could check if DELTAOMEGA is <0, and if so, negate it and rotation_axis
    STARTING_ANGLE=${OMEGA}
# here we could check if DELTAOMEGA is <0, and if so, negate it and ROTATION_AXIS
  fi
  fi
# 2theta
# 2theta
   TWOTHETA=`awk '/TWOTHETA \? \? \?/{print $5}' tmp2`
   TWOTHETA=`awk '/TWOTHETA \? \? \?/{print $5;exit}' tmp2`
   echo TWOTHETA=$TWOTHETA
   echo TWOTHETA=$TWOTHETA
   R1=`echo "scale=7; c($TWOTHETA/$DEGTOR)" | bc -l`
   R1=`echo "scale=7; c($TWOTHETA/$DEGTOR)" | bc -l`
Line 601: Line 957:
else
else
   echo should never come here
   echo should never come here
   exit 1                    
   exit 1
fi                          
fi


echo ORGX= $ORGX ORGY= $ORGY - check these values with adxv !
echo ORGX= $ORGX ORGY= $ORGY - check these values with adxv or xdsgui !
echo DETECTOR_DISTANCE= $DETECTOR_DISTANCE                  
echo DETECTOR_DISTANCE= $DETECTOR_DISTANCE ! only read by XYCORR, IDXREF
echo OSCILLATION_RANGE= $OSCILLATION_RANGE                  
echo STARTING_ANGLE= $STARTING_ANGLE        ! only read by IDXREF
echo X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH                    
echo OSCILLATION_RANGE= $OSCILLATION_RANGE ! only read by IDXREF
echo X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH   ! only read by IDXREF
if (( $(echo "$X_RAY_WAVELENGTH > 1.54 && $X_RAY_WAVELENGTH < 1.55" |bc -l) )); then
  echo "Copper K-alpha source, FRACTION_OF_POLARIZATION commented out"
  not_synchrotron='!'
fi


# now we know everything that is required to generate XDS.INP
if [ "$DET" == "eiger" ] && [ "$is_h5" == 1 ]; then
  if [ "$DLS" == 0 ] ; then
    neggia_path=${NEGGIA_PATH-/usr/local/lib64/dectris-neggia.so}
    if [ -e $neggia_path ]; then
      LIB="LIB=$neggia_path"
      echo "LIB= <dectris-neggia> was written to XDS.INP . Check the path! For Apple M1 processors, modify the name or set \$NEGGIA_PATH."
    else
      LIB="!LIB=/usr/local/lib64/dectris-neggia.so"
      echo "dectris-neggia.so not found. Specify LIB=<path-to-dectris-neggia> in XDS.INP -- set \$NEGGIA_PATH to specify the path!"
    fi
  else
    durin_path=${DURIN_PATH-/usr/local/lib64/durin-plugin.so}
    if [ -e $durin_path ]; then
      LIB="LIB=$durin_path"
      echo "LIB= <durin-plugin> was written to XDS.INP . Check the path! For Apple M1 processors, modify the name or set \$DURIN_PATH."
    else
      LIB="!LIB=/usr/local/lib64/durin-plugin.so"
      echo "durin-plugin.so not found. Specify LIB=<path-to-durin-plugin> in XDS.INP -- set \$DURIN_PATH to specify the path!"
    fi
  fi
fi
if [ "$ROTATION_AXIS" != "" ]; then
  ROTATION_AXIS="$ROTATION_AXIS  ! only read by IDXREF"
elif [ "$REVERSE_PHI" == "no" ]; then
  ROTATION_AXIS='1 0 0  ! Australian Synchrotron, SERCAT ID-22 (?), APS 19-ID (?), ESRF BM30A, SPring-8, SSRF need -1 0 0. Diamond ID24 needs 0 -1 0'
else
  ROTATION_AXIS='-1 0 0  ! Default; if this is wrong, please contact author.'
fi


# Append 2-theta comment if defined
if (( $(echo "${TWOTHETA}0 != 0"|bc -l) )); then
  COMMENT_ORGXY="$COMMENT_ORGXY
! TWOTHETA=$TWOTHETA -- information only, do not uncomment. If indexing fails, check DIRECTION_OF_DETECTOR_X-AXIS"
fi
if [ "$DET" == "pilatus" -a "$NX" == "2463" -a "$NY" == "5071" ]; then
  SEGMENTED=1
fi
# now we know almost everything that is required to generate XDS.INP
# --------- Generate XDS.INP containing all defined parameters ----------
cat > XDS.INP << eof
cat > XDS.INP << eof
!=============================================================================
! written by generate_XDS.INP version $REVISION
! written by generate_XDS.INP version $REVISION
! For more details on XDS parameters, please check the online documentation at
!  http://xds.mr.mpg.de/html_doc/xds_parameters.html
!
! Full documentation, including complete detector templates, at xds.mr.mpg.de .
! More documentation in wiki.uni-konstanz.de/xds/index.php .
! After running xds, inspect at least the agreement of predicted and observed
! spots in FRAME.cbf (or SHOW_HKL.cbf in versions since BUILT=20240723)!
!=============================================================================
JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT
JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT
ORGX= $ORGX ORGY= $ORGY  ! check these values with adxv !\
ORGX= $ORGX ORGY= $ORGY  ! values from frame header; only read by XYCORR, IDXREF
$COMMENT_ORGXY
$COMMENT_ORGXY
DETECTOR_DISTANCE= $DETECTOR_DISTANCE                  
DETECTOR_DISTANCE= $DETECTOR_DISTANCE !read by XYCORR, IDXREF. Negative if detector normal points to crystal.
OSCILLATION_RANGE= $OSCILLATION_RANGE                  
OSCILLATION_RANGE= $OSCILLATION_RANGE
X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH                    
STARTING_ANGLE= $STARTING_ANGLE
X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH
NAME_TEMPLATE_OF_DATA_FRAMES=$NAME_TEMPLATE_OF_DATA_FRAMES
NAME_TEMPLATE_OF_DATA_FRAMES=$NAME_TEMPLATE_OF_DATA_FRAMES
! REFERENCE_DATA_SET=xxx/XDS_ASCII.HKL ! e.g. to ensure consistent indexing
! REFERENCE_DATA_SET=xxx/XDS_ASCII.HKL ! e.g. to ensure consistent indexing
DATA_RANGE=$DATA_RANGE                                                    
DATA_RANGE=$DATA_RANGE
SPOT_RANGE=$SPOT_RANGE                                                    
SPOT_RANGE=$SPOT_RANGE
! BACKGROUND_RANGE=1 10 ! rather use defaults (first 5 degree of rotation)  
! BACKGROUND_RANGE=1 10 ! rather use defaults (first 5 degree of rotation)


SPACE_GROUP_NUMBER=0                  ! 0 if unknown
SPACE_GROUP_NUMBER=0                  ! 0 if unknown
Line 647: Line 1,057:
TRUSTED_REGION=$TRUSTED_REGION
TRUSTED_REGION=$TRUSTED_REGION
VALUE_RANGE_FOR_TRUSTED_DETECTOR_PIXELS=6000. 30000. ! often 7000 or 8000 is ok
VALUE_RANGE_FOR_TRUSTED_DETECTOR_PIXELS=6000. 30000. ! often 7000 or 8000 is ok
STRONG_PIXEL=4           ! COLSPOT: only use strong reflections (default is 3)
!STRONG_PIXEL=4 ! COLSPOT: only use strong reflections (default is 3). For XDS versions before mid-2024.
MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=$MNOPIAS ! default of 6 is sometimes too high
MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=$MNOPIAS ! default of 6 is sometimes too high
! close spots/long cell axis: reduce SEPMIN and CLUSTER_RADIUS from their defaults of 6 and 3
! close spots/long cell axis: reduce SEPMIN and CLUSTER_RADIUS from their defaults of 7 and 3.5
! SEPMIN=4 CLUSTER_RADIUS=2 ! should be default for Pilatus and other detectors with low PSF
SEPMIN=$SEPMIN CLUSTER_RADIUS=$CLUSTER_RADIUS ! 4 and 2 for Pixel Array Detectors
! since XDS 01-MAR-2015, POSITION supersedes DISTANCE. DISTANCE only for compatibility w/ old XDS.
! since XDS 01-MAR-2015, POSITION supersedes DISTANCE.
! nowadays headers are usually correct so refine DISTANCE/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 ! POSITION
! however, if the spots from COLSPOT extend to 2A then POSITION could, and if 1.5A POSITION should be refined
REFINE(INTEGRATE)= DISTANCE POSITION BEAM ORIENTATION ! AXIS CELL
REFINE(IDXREF)=CELL BEAM ORIENTATION AXIS ! add POSITION if high resolution, or DETECTOR_DISTANCE inaccurate
! REFINE(CORRECT)=CELL BEAM ORIENTATION AXIS DISTANCE POSITION ! Default is: refine everything
REFINE(INTEGRATE)= POSITION BEAM ORIENTATION ! AXIS CELL . If 1.5A or higher it is ok to refine CELL (unless electron diffraction)
 
REFINE(CORRECT)= $REFINE_CORRECT
! parameters specifically for this detector and beamline:
! parameters specifically for this detector and beamline:
DETECTOR= $DETECTOR
DETECTOR= $DETECTOR
Line 662: Line 1,072:
! 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).
! Better: read the article http://strucbio.biologie.uni-konstanz.de/xdswiki/index.php/SILICON .
! Better: read the article http://wiki.uni-konstanz.de/xds/index.php/SILICON .
NX= $NX NY= $NY  QX= $QX  QY= $QY ! to make CORRECT happy if frames are unavailable
NX= $NX NY= $NY  QX= $QX  QY= $QY ! to make CORRECT happy if frames are unavailable
 
$LIB
eof
ROTATION_AXIS=$ROTATION_AXIS
if [ "$DET" == "raxis" -o "$dtrek_det" == "raxis" ]; then
cat >> XDS.INP << eof
DIRECTION_OF_DETECTOR_X-AXIS=1 0 0
DIRECTION_OF_DETECTOR_Y-AXIS=0 -1 0
INCIDENT_BEAM_DIRECTION=0 0 1
ROTATION_AXIS=0 1 0
!FRACTION_OF_POLARIZATION=0.98  ! uncomment if synchrotron
POLARIZATION_PLANE_NORMAL=1 0 0
eof
else
if [ "$rotation_axis" != "" ]; then
  echo "ROTATION_AXIS= $rotation_axis" >> XDS.INP
elif [ "$REVERSE_PHI" == "no" ]; then
  echo 'ROTATION_AXIS=1 0 0  ! Australian Synchrotron, SERCAT ID-22 (?), APS 19-ID (?), ESRF BM30A, SPring-8, SSRF BL17U need -1 0 0. Diamond ID24 needs 0 -1 0' >> XDS.INP
else
  echo 'ROTATION_AXIS=-1 0 0  ! if this is wrong, please contact author.' >> XDS.INP
fi
if [ "$dtrek_det" == "saturn" ]; then
cat >> XDS.INP << eof
DIRECTION_OF_DETECTOR_X-AXIS=-1 0 0
DIRECTION_OF_DETECTOR_Y-AXIS= 0 1 0
eof
else
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
INCIDENT_BEAM_DIRECTION=0 0 1   ! only read by IDXREF
${not_synchrotron}FRACTION_OF_POLARIZATION=${pol_frac}  ! comment out if not synchrotron; only use by CORRECT
                                      ! better value is provided by beamline staff!
POLARIZATION_PLANE_NORMAL=$POLARIZATION_PLANE_NORMAL        ! only used by CORRECT
eof
eof
fi
 
cat >> XDS.INP << eof
# --------- Append known detector untrusted regions -----------
INCIDENT_BEAM_DIRECTION=0 0 1
FRACTION_OF_POLARIZATION=${pol_frac}  ! better value is provided by beamline staff!
POLARIZATION_PLANE_NORMAL=0 1 0
eof
fi
cat >> XDS.INP << eof
cat >> XDS.INP << eof
!used by DEFPIX and CORRECT to exclude ice-reflections / ice rings - uncomment if necessary
!used by DEFPIX and CORRECT to exclude ice-reflections / ice rings - uncomment if necessary
!fine-grained list is in Thorn et al http://journals.iucr.org/d/issues/2017/09/00/hi5647/index.html
!EXCLUDE_RESOLUTION_RANGE= 3.93 3.87 !ice-ring at 3.897 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 3.93 3.87 !ice-ring at 3.897 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 3.70 3.64 !ice-ring at 3.669 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 3.70 3.64 !ice-ring at 3.669 Angstrom
Line 712: Line 1,098:
!EXCLUDE_RESOLUTION_RANGE= 1.913 1.853 !ice-ring at 1.883 Angstrom - weak
!EXCLUDE_RESOLUTION_RANGE= 1.913 1.853 !ice-ring at 1.883 Angstrom - weak
!EXCLUDE_RESOLUTION_RANGE= 1.751 1.691 !ice-ring at 1.721 Angstrom - weak
!EXCLUDE_RESOLUTION_RANGE= 1.751 1.691 !ice-ring at 1.721 Angstrom - weak
! additional ice-ring resolution ranges: 1.524 1.519, 1.473 1.470, 1.444 1.440, 1.372 1.368, 1.367 1.363,
! 1.299 1.296, 1.275 1.274, 1.261 1.259, 1.224 1.222, 1.171 1.168, 1.124 1.122 (compiled by GlobalPhasing)
eof
eof
# --------- Append additional detector-specific parameters ----------
if [ "$DET" == "Bruker-cbf" ]; then
if [ "$DET" == "Bruker-cbf" ]; then
   echo "DELPHI=15 ! refine less often than the default of 5" >> XDS.INP
   echo "DELPHI=15 ! refine less often than the default of 5" >> XDS.INP
elif [ "$DET" == "adsc-CMOS1" ]; then
  echo UNTRUSTED_RECTANGLE= 0 1468  2451 2631  >> XDS.INP
elif [ "$dtrek_det" == "pilatus" -a "$NX" == 487 -a "$NY" = "407" ]; then
  echo UNTRUSTED_RECTANGLE= 1 487 196 212 >> XDS.INP # Dectris Pilatus 200K
elif [ "$DET" == "pilatus" -o "$DET" == "eiger" ]; then
elif [ "$DET" == "pilatus" -o "$DET" == "eiger" ]; then
cat >> XDS.INP << eof
cat >> XDS.INP << eof
SEPMIN=4 CLUSTER_RADIUS=2
NUMBER_OF_PROFILE_GRID_POINTS_ALONG_ALPHA/BETA=13 ! Default is 9 - Increasing may improve data
NUMBER_OF_PROFILE_GRID_POINTS_ALONG_ALPHA/BETA=13 ! Default is 9 - Increasing may improve data  
NUMBER_OF_PROFILE_GRID_POINTS_ALONG_GAMMA=13      ! accuracy, particularly if finely-sliced on phi,
NUMBER_OF_PROFILE_GRID_POINTS_ALONG_GAMMA=13      ! accuracy, particularly if finely-sliced on phi,  
!                                                  and does not seem to have any downsides.
!                                                  and does not seem to have any downsides.  
eof
# -------- Append known detector untrusted regions ------------------
  if [ "$NX" == "1028"  -a "$NY" == "1062" ]; then
# Eiger2 1M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
UNTRUSTED_RECTANGLE=    0 1029    512  551
eof
eof
   if [ $NX == "1475" ]; then
   elif [ "$NX" == "1475" ]; then
     if ! grep -q Flat_field tmp2 ; then
     if ! grep -q Flat_field tmp2 ; then
     cat >> XDS.INP << eof
     cat >> XDS.INP << eof
! the following specifications are for a detector _without_ proper
! the following specifications are for a detector _without_ proper
! flat_field correction; they cut away one additional pixel adjacent  
! flat_field correction; they mask one additional pixel adjacent
! to each UNTRUSTED_RECTANGLE
! to each UNTRUSTED_RECTANGLE
!EXCLUSION OF VERTICAL DEAD AREAS OF THE PILATUS 2M DETECTOR
!EXCLUSION OF VERTICAL DEAD AREAS OF THE PILATUS 2M DETECTOR
Line 755: Line 1,154:
eof
eof
     fi
     fi
   elif [ $NX == "2463" ]; then
   elif [ "$NX" == "2068"  -a "$NY" == "2162" ]; then
# Eiger2 4M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER2 4M DETECTOR
UNTRUSTED_RECTANGLE= 1028 1041      0 2163
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER 4M DETECTOR
UNTRUSTED_RECTANGLE=    0 2069    512  551
UNTRUSTED_RECTANGLE=    0 2069  1062 1101
UNTRUSTED_RECTANGLE=    0 2069  1612 1651
eof
  elif [ "$NX" == "2463" -a "$NY" == "2527" ]; then
# Pilatus 6M
# Pilatus 6M
# FIXME: here we could test if a Flat_field correction was applied like we do for 2M
# FIXME: here we could test if a Flat_field correction was applied like we do for 2M
Line 775: Line 1,184:
UNTRUSTED_RECTANGLE=  0 2464  2315 2333
UNTRUSTED_RECTANGLE=  0 2464  2315 2333
eof
eof
   elif [ $NX == "3110"  -a $NY == "3269" ]; then
   elif [ "$NX" == "3110"  -a "$NY" == "3269" ]; then
# Eiger 9M
# Eiger 9M
     cat >> XDS.INP << eof
     cat >> XDS.INP << eof
Line 788: Line 1,197:
UNTRUSTED_RECTANGLE= 0 3110 2717 2757
UNTRUSTED_RECTANGLE= 0 3110 2717 2757
eof
eof
   elif [ $NX == "4150" -a $NY == "4371" ]; then
   elif [ "$NX" == "3108"  -a "$NY" == "3262" ]; then
# Eiger2 9M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER2 9M DETECTOR
UNTRUSTED_RECTANGLE= 1028 1041      0 3262
UNTRUSTED_RECTANGLE= 2068 2081      0 3263
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER2 9M DETECTOR
UNTRUSTED_RECTANGLE=    0 3109    512  551
UNTRUSTED_RECTANGLE=    0 3109  1062 1101
UNTRUSTED_RECTANGLE=    0 3109  1612 1651
UNTRUSTED_RECTANGLE=    0 3109  2162 2201
UNTRUSTED_RECTANGLE=    0 3109  2712 2751
eof
  elif [ "$NX" == "4150" -a "$NY" == "4371" ]; then
# Eiger 16M
# Eiger 16M
     cat >> XDS.INP << eof
     cat >> XDS.INP << eof
Line 801: Line 1,223:
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER 16M DETECTOR + ONE PIXEL ON EACH SIDE
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER 16M DETECTOR + ONE PIXEL ON EACH SIDE
  UNTRUSTED_RECTANGLE= 1029 1042      0 4371
  UNTRUSTED_RECTANGLE= 1029 1042      0 4371
  UNTRUSTED_RECTANGLE= 2069 2082      0 4371  
  UNTRUSTED_RECTANGLE= 2069 2082      0 4371
  UNTRUSTED_RECTANGLE= 3109 3122      0 4371
  UNTRUSTED_RECTANGLE= 3109 3122      0 4371
eof
eof
  elif [ "$NX" == "4148" -a "$NY" == "4362" ]; then
# Eiger2 16M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER2 16M DETECTOR
UNTRUSTED_RECTANGLE= 1028 1041      0 4363
UNTRUSTED_RECTANGLE= 2068 2081      0 4363
UNTRUSTED_RECTANGLE= 3108 3121      0 4363
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER2 16M DETECTOR
UNTRUSTED_RECTANGLE=    0 4149    512  551
UNTRUSTED_RECTANGLE=    0 4149  1062 1101
UNTRUSTED_RECTANGLE=    0 4149  1612 1651
UNTRUSTED_RECTANGLE=    0 4149  2162 2201
UNTRUSTED_RECTANGLE=    0 4149  2712 2751
UNTRUSTED_RECTANGLE=    0 4149  3262 3301
UNTRUSTED_RECTANGLE=    0 4149  3812 3851
eof
  elif [ "$NX" == "2463" -a "$NY" == "5071" ]; then
    : # handled above, before writing XDS.INP, untrusted regions come from site file
  else
    echo "**** WARNING ****"
    echo "Unknown Pilatus or Eiger detector, add UNTRUSTED regions and SEGMENT information manually"
   fi
   fi
fi
# Mechanism to append detector-specific parameters without editing this file:
# NOTE: some detectors don't set DET_SN so this is not always unique
# If the detector name is present in $DET_SN, then use only $DET_SN
if [ "$DET_SN" != "" ]; then
  echo "$DET_SN" | grep -qi "$DET" && DET="$DET_SN" || DET="${DET}_$DET_SN"
fi
DET=$(echo $DET | sed 's/ /_/g;s/[^-_A-Za-z0-9]//g;')
site_file="$HOME/.xds-site/$DET"
if [ -f $site_file ]; then
  echo Appending site parameters from: $site_file
  echo "! Parameters from $site_file" >> XDS.INP
  echo "Site parameters:"
  cat $site_file | head -20
  [ $(wc -l $site_file | awk '{print $1}') -gt 20 ] && echo "... (truncated)"
  echo
  # Only FRACTION_POLARIZATION and ROTATION_AXIS are commented out automatically because they
  # are the most likely to not match defaults.
  # For segmented detectors, also allow origin and distance to be replaced
  # Also likely adjustments are UNTRUSTED regions and maybe SILICON, but those don't replace existing parameters
  # Create a pattern like "XX\|YY" to search overriden parameters.
  REDEF_TOKENS="POLARIZATION\|ROTATION_AXIS\|TRUSTED_REGION"
  [ "$SEGMENTED" != "" ] && REDEF_TOKENS=$REDEF_TOKENS"\|ORGX\|ORGY\|DETECTOR_DISTANCE\|"
  pattern=$(grep "$REDEF_TOKENS" $site_file | grep -v SEGMENT | uniq | awk 'match($0,/^ *(\w+) *=/,a){x=x"\\|"a[1];}END{print substr(x,3);}')
  if [ "$pattern" != "" -a $(grep "^!! *\($pattern\)" XDS.INP) != ""]; then
      sed 's/\(^ *\('$pattern'\) *=\)/!!!\1/;' XDS.INP >tmp1
      echo "Overridden parameters:"
      grep "^ *\($pattern\)" XDS.INP
      echo
      mv tmp1 XDS.INP
  fi
  cat $site_file >> XDS.INP
else
  if [ "$SEGMENTED" != "" ]; then
    echo "**** Multi-SEGMENTed detector, site file is mandatory ****"
  fi
  echo "Detector specific parameters can be placed in: $site_file"
  echo "! Detector specific parameters can be placed in:" >> XDS.INP
  echo "!    $site_file" >> XDS.INP
  echo "! FRACTION_OF_POLARIZATION, ROTATION_AXIS and TRUSTED_REGION will auto-comment the replaced parameters" >> XDS.INP
  echo "! If the site file defines SEGMENTs then ORGX, ORGY, and DISTANCE may be overridden" >> XDS.INP
fi
fi
echo XDS.INP is ready for use. The file has only the most important keywords.
echo XDS.INP is ready for use. The file has only the most important keywords.
echo Full documentation, including complete detector templates, is at
echo Full documentation, including complete detector templates, at xds.mr.mpg.de .
echo http://www.mpimf-heidelberg.mpg.de/~kabsch/xds . More documentation in XDSwiki
echo More documentation in wiki.uni-konstanz.de/xds/index.php .
echo After running xds, inspect, using XDS-Viewer, at least the beamstop mask in
echo After running xds, inspect at least the agreement of predicted and observed
echo BKGPIX.cbf, and the agreement of predicted and observed spots in FRAME.cbf!
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>


== System-wide or personal installation ==
== System-wide or personal installation ==


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 specify the environment variables NEGGIA_PATH or DURIN_PATH, to point to the correct path on your system of the Dectris' Neggia library, or the Durin plugin, respectively. This relieves users from having to change the LIB= line of XDS.INP 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 (or better, into your ~/bin directory if that is in your $PATH); the filename should be generate_XDS.INP. After creating the file, make it executable - e.g. if it's in your $HOME, use:
  chmod +x ~/generate_XDS.INP
  chmod +x ~/generate_XDS.INP
After that, you can just run it in a similar way as if it were installed in your $PATH:
After that, you can just run it in a similar way as if it were installed in your $PATH:
Line 825: Line 1,312:
By using your own file, you can easily update to the latest revision, or even change the script, without having to bother the system administrator.
By using your own file, you can easily update to the latest revision, or even change the script, without having to bother the system administrator.


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 for the first time.
See also [[Generate_XDS.INP#Dependencies]] below, and the [[Installation]] article.
 
== Copying generate_XDS.INP from XDSwiki webserver ==
On Linux:
wget https://wiki.uni-konstanz.de/pub/linux_bin/generate_XDS.INP
chmod a+x generate_XDS.INP
On Mac:
curl -o generate_XDS.INP https://wiki.uni-konstanz.de/pub/linux_bin/generate_XDS.INP
chmod a+x generate_XDS.INP
See also [[Installation]].


== Generating generate_XDS.INP from this webpage ==
== Obtaining generate_XDS.INP from this webpage ==


Instead of cutting-and-pasting the lines of the script, you (or the system administrator) could just cut-and-paste the following four lines
Instead of cutting-and-pasting the lines of the script, you (or the system administrator) could just cut-and-paste the following four lines
<pre>
<pre>
  wget http://strucbio.biologie.uni-konstanz.de/xdswiki/index.php/generate_XDS.INP -O - | \
  wget http://wiki.uni-konstanz.de/xds/index.php/generate_XDS.INP -O - | \
   sed -e s/\&nbsp\;/\ /g -e s/\&gt\;/\>/g -e s/\&lt\;/\</g -e s/amp\;//g -e s/\&quot\;/\"/g -e s/\&\#\1\6\0\;/\ /g | \
   sed -e s/\&nbsp\;/\ /g -e s/\&gt\;/\>/g -e s/\&lt\;/\</g -e s/amp\;//g -e s/\&quot\;/\"/g -e s/\&\#\1\6\0\;/\ /g | \
   sed '/# end of generate_XDS.INP/,$d' | awk '/^#/,/rm -f tmp1 tmp2/' > generate_XDS.INP
   sed '/# end of generate_XDS.INP/,$d' | sed -n '/#!\/bin\/bash/,/# end of generate_XDS.INP/p' > generate_XDS.INP
  chmod +x generate_XDS.INP
  chmod +x generate_XDS.INP
</pre>
</pre>
to copy the script from this website into an executable file generate_XDS.INP in your current directory. On a Mac (which does not seem to have wget), one could try
to copy the script from this website into an executable file generate_XDS.INP in your current directory. On a Mac (which does not seem to have wget), one could try
<pre>
<pre>
  curl -L -o - http://strucbio.biologie.uni-konstanz.de/xdswiki/index.php/generate_XDS.INP | \
  curl -L -o - http://wiki.uni-konstanz.de/xds/index.php/generate_XDS.INP | \
   sed -e s/\&nbsp\;/\ /g -e s/\&gt\;/\>/g -e s/\&lt\;/\</g -e s/amp\;//g -e s/\&quot\;/\"/g -e s/\&\#\1\6\0\;/\ /g | \
   sed -e s/\&nbsp\;/\ /g -e s/\&gt\;/\>/g -e s/\&lt\;/\</g -e s/amp\;//g -e s/\&quot\;/\"/g -e s/\&\#\1\6\0\;/\ /g | \
   sed '/# end of generate_XDS.INP/,$d' | awk '/^#/,/rm -f tmp1 tmp2/' > generate_XDS.INP
   sed '/# end of generate_XDS.INP/,$d' | sed -n '/#!\/bin\/bash/,/# end of generate_XDS.INP/p' > generate_XDS.INP
  chmod +x generate_XDS.INP
  chmod +x generate_XDS.INP
</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 use TextEdit on a Mac to cut-and-paste from this webpage, be aware of the following problem report: After loading frames, by clicking “generate XDS.INP”, the program shows 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.''


== Calling generate_XDS.INP from a Python script ==
== Calling generate_XDS.INP from a Python script ==
Line 859: Line 1,355:


== Dependencies ==
== Dependencies ==
The script makes use of many GNU commands, like ls, grep and egrep, awk, cut, cat, echo, wc, bc, head, sed, tail, cp, od, python. Some of them (like od and python) are only used in case of specific detectors.  
The script makes use of many GNU commands, like <code>ls, grep, egrep, awk, cut, cat, echo, wc, bc, head, sed, tail, cp, od, python</code>. Some of them (like <code>od</code> and <code>python</code>) are only used in case of specific detectors (MarCCD and RAXIS, respectively).  
The script will only work if all the required commands are available. They reside in either the coreutils RPM, or specific RPMs (sed, bc, grep, python ...). Please note that to get the <code>strings</code> command on some Linux distributions (e.g. FC23) you need to install the <code>binutils</code> RPM package.
The script will only work if all the required commands are available. They reside in either the <code>coreutils</code> package, or specific packages (<code>gawk, sed, bc, grep, python</code> ...). Please note that to get the <code>strings</code> command on some Linux distributions, you need to install the <code>binutils</code> package.
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). The .h5 files collected at Diamond Light Source require at least version 1.10 of h5dump to extract the OVERLOAD parameter from the .h5 file; this version is available in newer Linux distributions but not in RHEL/CentOS 7.
 
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.
 
One way to check for missing programs is
#!/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)
yum -y install coreutils binutils gawk sed bc grep python hdf5
and for Ubuntu this would be (untested!)
sudo apt-get install coreutils binutils gawk sed bc grep python hdf5-tools
 
See also [[Installation]].
 
== Site Files ==
 
Site files may be used to add or modify parameters for specific hardware configurations. The primary use is for SEGMENT definitions of multi-segment detectors, and may also override FRACTION_OF_POLARIZATION, ROTATION_AXIS, TRUSTED_REGION, or UNTRUSTED_* specific to a site configuration. The site file is named ~/.xds-site/<NAME>_<SN>. The exact name will be printed by generate_XDS.INP when it is executed.
 
[https://wiki.uni-konstanz.de/pub/linux_bin/PILATUS_12M_SN_120-0100 Site file for PILATUS 12M-DLS detector for the I23 beamline at Diamond Light Source]:
<div class="toccolours mw-collapsible mw-collapsed">
Expand code section below (i.e. click on blue <code>[Expand]</code> at the end of this line if there is no code visible)
<div class="mw-collapsible-content">
<pre>
!--------------------------------------------------------------
! XDS Site file for Pilatus12M
! Save as: ~/.xds-site/PILATUS_12M_SN_120-0100
! SEGMENT definitions translated to align frame header beam
! and distance, from segments refined against 20141016/germ8979
!
! generated by Juno Krahn
! National Institute of Environmental Health Sciences, NIH
!--------------------------------------------------------------
! SEGMENT 1
SEGMENT= 1 487 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00106  0.00008
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00023 -0.14270  0.98977
SEGMENT_ORGX=    4.83
SEGMENT_ORGY=  473.86
SEGMENT_DISTANCE=  -190.77
! SEGMENT 2
SEGMENT= 495 981 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00094  0.00014
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00027 -0.14289  0.98974
SEGMENT_ORGX=    4.81
SEGMENT_ORGY=  474.08
SEGMENT_DISTANCE=  -190.72
! SEGMENT 3
SEGMENT= 989 1475 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00011  0.00035
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00033 -0.14157  0.98993
SEGMENT_ORGX=    3.52
SEGMENT_ORGY=  472.75
SEGMENT_DISTANCE=  -190.67
! SEGMENT 4
SEGMENT= 1483 1969 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00027
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00030 -0.14316  0.98970
SEGMENT_ORGX=    3.49
SEGMENT_ORGY=  473.57
SEGMENT_DISTANCE=  -190.50
! SEGMENT 5
SEGMENT= 1977 2463 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00017 -0.00024
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00026 -0.14305  0.98972
SEGMENT_ORGX=    3.83
SEGMENT_ORGY=  473.58
SEGMENT_DISTANCE=  -190.59
! SEGMENT 6
SEGMENT= 1 487 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00051  0.00011
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00011  0.00238  1.00000
SEGMENT_ORGX=    3.82
SEGMENT_ORGY=  309.94
SEGMENT_DISTANCE=  -195.53
! SEGMENT 7
SEGMENT= 495 981 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00090 -0.00018
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00018  0.00238  1.00000
SEGMENT_ORGX=    4.48
SEGMENT_ORGY=  309.68
SEGMENT_DISTANCE=  -195.51
! SEGMENT 8
SEGMENT= 989 1475 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00046
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00046  0.00229  1.00000
SEGMENT_ORGX=    3.28
SEGMENT_ORGY=  309.29
SEGMENT_DISTANCE=  -195.33
! SEGMENT 9
SEGMENT= 1483 1969 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00020 -0.00009
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00009  0.00194  1.00000
SEGMENT_ORGX=    3.31
SEGMENT_ORGY=  310.20
SEGMENT_DISTANCE=  -195.29
! SEGMENT 10
SEGMENT= 1977 2463 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00028 -0.00048
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00048  0.00221  1.00000
SEGMENT_ORGX=    4.20
SEGMENT_ORGY=  309.13
SEGMENT_DISTANCE=  -195.44
! SEGMENT 11
SEGMENT= 1 487 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00021 -0.00034
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00036  0.14700  0.98914
SEGMENT_ORGX=    3.79
SEGMENT_ORGY=  146.46
SEGMENT_DISTANCE=  -190.86
! SEGMENT 12
SEGMENT= 495 981 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00098  0.00012
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00002  0.14705  0.98913
SEGMENT_ORGX=    5.09
SEGMENT_ORGY=  146.20
SEGMENT_DISTANCE=  -190.83
! SEGMENT 13
SEGMENT= 989 1475 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00034 -0.00060
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00065  0.14764  0.98904
SEGMENT_ORGX=    4.25
SEGMENT_ORGY=  144.79
SEGMENT_DISTANCE=  -190.74
! SEGMENT 14
SEGMENT= 1483 1969 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00016 -0.00074
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00076  0.14716  0.98911
SEGMENT_ORGX=    4.12
SEGMENT_ORGY=  145.21
SEGMENT_DISTANCE=  -190.69
! SEGMENT 15
SEGMENT= 1977 2463 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00055
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00051  0.14723  0.98910
SEGMENT_ORGX=    3.95
SEGMENT_ORGY=  145.25
SEGMENT_DISTANCE=  -190.55
! SEGMENT 16
SEGMENT= 1 487 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007  0.00022
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00019  0.28893  0.95735
SEGMENT_ORGX=    3.45
SEGMENT_ORGY=    -9.50
SEGMENT_DISTANCE=  -176.83
! SEGMENT 17
SEGMENT= 495 981 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00070 -0.00020
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00039  0.28888  0.95736
SEGMENT_ORGX=    4.70
SEGMENT_ORGY=    -9.69
SEGMENT_DISTANCE=  -176.81
! SEGMENT 18
SEGMENT= 989 1475 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00084 -0.00061
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00083  0.28961  0.95715
SEGMENT_ORGX=    5.18
SEGMENT_ORGY=  -11.24
SEGMENT_DISTANCE=  -176.77
! SEGMENT 19
SEGMENT= 1483 1969 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00004 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00055  0.28951  0.95718
SEGMENT_ORGX=    4.22
SEGMENT_ORGY=  -10.88
SEGMENT_DISTANCE=  -176.50
! SEGMENT 20
SEGMENT= 1977 2463 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00004 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00058  0.28889  0.95736
SEGMENT_ORGX=    4.18
SEGMENT_ORGY=  -10.47
SEGMENT_DISTANCE=  -176.63
! SEGMENT 21
SEGMENT= 1 487 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00014  0.00006
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00001  0.42489  0.90524
SEGMENT_ORGX=    3.87
SEGMENT_ORGY=  -149.76
SEGMENT_DISTANCE=  -153.74
! SEGMENT 22
SEGMENT= 495 981 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00076  0.00043
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00007  0.42509  0.90515
SEGMENT_ORGX=    5.02
SEGMENT_ORGY=  -149.85
SEGMENT_DISTANCE=  -153.68
! SEGMENT 23
SEGMENT= 989 1475 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00042 -0.00107
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00115  0.42569  0.90487
SEGMENT_ORGX=    5.25
SEGMENT_ORGY=  -152.03
SEGMENT_DISTANCE=  -153.46
! SEGMENT 24
SEGMENT= 1483 1969 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00011 -0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00041  0.42530  0.90505
SEGMENT_ORGX=    4.09
SEGMENT_ORGY=  -150.92
SEGMENT_DISTANCE=  -153.42
! SEGMENT 25
SEGMENT= 1977 2463 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00061 -0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00019  0.42520  0.90510
SEGMENT_ORGX=    3.67
SEGMENT_ORGY=  -150.36
SEGMENT_DISTANCE=  -153.14
! SEGMENT 26
SEGMENT= 1 487 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00024 -0.00062
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00065  0.55176  0.83400
SEGMENT_ORGX=    4.50
SEGMENT_ORGY=  -267.14
SEGMENT_DISTANCE=  -122.15
! SEGMENT 27
SEGMENT= 495 981 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00104  0.00037
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00026  0.55182  0.83396
SEGMENT_ORGX=    5.05
SEGMENT_ORGY=  -267.36
SEGMENT_DISTANCE=  -122.12
! SEGMENT 28
SEGMENT= 989 1475 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00016 -0.00047
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00048  0.55207  0.83380
SEGMENT_ORGX=    4.55
SEGMENT_ORGY=  -267.71
SEGMENT_DISTANCE=  -121.94
! SEGMENT 29
SEGMENT= 1483 1969 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00003 -0.00099
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00084  0.55221  0.83371
SEGMENT_ORGX=    5.02
SEGMENT_ORGY=  -268.34
SEGMENT_DISTANCE=  -121.73
! SEGMENT 30
SEGMENT= 1977 2463 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00022 -0.00053
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00032  0.55182  0.83396
SEGMENT_ORGX=    3.99
SEGMENT_ORGY=  -267.40
SEGMENT_DISTANCE=  -121.75
! SEGMENT 31
SEGMENT= 1 487 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00015  0.00013
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00001  0.66732  0.74477
SEGMENT_ORGX=    4.14
SEGMENT_ORGY=  -354.22
SEGMENT_DISTANCE=  -82.50
! SEGMENT 32
SEGMENT= 495 981 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00063  0.00076
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00015  0.66760  0.74452
SEGMENT_ORGX=    4.31
SEGMENT_ORGY=  -354.30
SEGMENT_DISTANCE=  -82.42
! SEGMENT 33
SEGMENT= 989 1475 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00011 -0.00026
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00027  0.66758  0.74454
SEGMENT_ORGX=    4.54
SEGMENT_ORGY=  -354.50
SEGMENT_DISTANCE=  -82.31
! SEGMENT 34
SEGMENT= 1483 1969 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00046 -0.00045
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00003  0.66738  0.74472
SEGMENT_ORGX=    3.67
SEGMENT_ORGY=  -353.83
SEGMENT_DISTANCE=  -82.19
! SEGMENT 35
SEGMENT= 1977 2463 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00007 -0.00091
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00063  0.66809  0.74408
SEGMENT_ORGX=    4.46
SEGMENT_ORGY=  -355.74
SEGMENT_DISTANCE=  -81.76
! SEGMENT 36
SEGMENT= 1 487 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00016  0.00111
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00083  0.76825  0.64015
SEGMENT_ORGX=    2.59
SEGMENT_ORGY=  -404.52
SEGMENT_DISTANCE=  -35.97
! SEGMENT 37
SEGMENT= 495 981 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00094  0.00104
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00005  0.76800  0.64045
SEGMENT_ORGX=    4.62
SEGMENT_ORGY=  -404.40
SEGMENT_DISTANCE=  -36.21
! SEGMENT 38
SEGMENT= 989 1475 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049 -0.00114
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00111  0.76871  0.63959
SEGMENT_ORGX=    6.17
SEGMENT_ORGY=  -405.99
SEGMENT_DISTANCE=  -35.56
! SEGMENT 39
SEGMENT= 1483 1969 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00030 -0.00083
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00076  0.76828  0.64012
SEGMENT_ORGX=    5.36
SEGMENT_ORGY=  -405.83
SEGMENT_DISTANCE=  -35.75
! SEGMENT 40
SEGMENT= 1977 2463 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00033 -0.00084
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00028  0.76806  0.64038
SEGMENT_ORGX=    4.15
SEGMENT_ORGY=  -404.69
SEGMENT_DISTANCE=  -35.60
! SEGMENT 41
SEGMENT= 1 487 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00012  0.00028
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00004  0.85314  0.52169
SEGMENT_ORGX=    3.87
SEGMENT_ORGY=  -412.52
SEGMENT_DISTANCE=    16.72
! SEGMENT 42
SEGMENT= 495 981 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00052  0.00053
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.85309  0.52176
SEGMENT_ORGX=    4.44
SEGMENT_ORGY=  -412.64
SEGMENT_DISTANCE=    16.63
! SEGMENT 43
SEGMENT= 989 1475 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00025 -0.00126
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00045  0.85311  0.52173
SEGMENT_ORGX=    5.35
SEGMENT_ORGY=  -413.24
SEGMENT_DISTANCE=    16.97
! SEGMENT 44
SEGMENT= 1483 1969 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00092 -0.00086
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00033  0.85325  0.52150
SEGMENT_ORGX=    3.55
SEGMENT_ORGY=  -411.91
SEGMENT_DISTANCE=    17.21
! SEGMENT 45
SEGMENT= 1977 2463 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00008 -0.00113
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00052  0.85326  0.52149
SEGMENT_ORGX=    5.13
SEGMENT_ORGY=  -413.28
SEGMENT_DISTANCE=    17.35
! SEGMENT 46
SEGMENT= 1 487 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00028 -0.00004
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00028  0.92003  0.39185
SEGMENT_ORGX=    4.58
SEGMENT_ORGY=  -374.02
SEGMENT_DISTANCE=    74.51
! SEGMENT 47
SEGMENT= 495 981 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049  0.00109
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00002  0.91985  0.39227
SEGMENT_ORGX=    3.78
SEGMENT_ORGY=  -374.06
SEGMENT_DISTANCE=    74.25
! SEGMENT 48
SEGMENT= 989 1475 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00073 -0.00102
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00107  0.92009  0.39172
SEGMENT_ORGX=    6.81
SEGMENT_ORGY=  -374.77
SEGMENT_DISTANCE=    74.74
! SEGMENT 49
SEGMENT= 1483 1969 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00050 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00023  0.91986  0.39226
SEGMENT_ORGX=    3.55
SEGMENT_ORGY=  -373.25
SEGMENT_DISTANCE=    74.64
! SEGMENT 50
SEGMENT= 1977 2463 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00023 -0.00070
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00049  0.92007  0.39176
SEGMENT_ORGX=    5.78
SEGMENT_ORGY=  -374.22
SEGMENT_DISTANCE=    74.74
! SEGMENT 51
SEGMENT= 1 487 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00035  0.00033
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00025  0.96695  0.25495
SEGMENT_ORGX=    4.41
SEGMENT_ORGY=  -285.55
SEGMENT_DISTANCE=  135.47
! SEGMENT 52
SEGMENT= 495 981 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00057  0.00085
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00033  0.96701  0.25473
SEGMENT_ORGX=    4.25
SEGMENT_ORGY=  -285.70
SEGMENT_DISTANCE=  135.50
! SEGMENT 53
SEGMENT= 989 1475 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00024 -0.00056
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00038  0.96692  0.25510
SEGMENT_ORGX=    5.50
SEGMENT_ORGY=  -286.05
SEGMENT_DISTANCE=  135.50
! SEGMENT 54
SEGMENT= 1483 1969 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00038 -0.00100
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00062  0.96709  0.25444
SEGMENT_ORGX=    6.40
SEGMENT_ORGY=  -285.85
SEGMENT_DISTANCE=  135.99
! SEGMENT 55
SEGMENT= 1977 2463 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00036 -0.00067
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00052  0.96712  0.25433
SEGMENT_ORGX=    5.98
SEGMENT_ORGY=  -285.86
SEGMENT_DISTANCE=  135.96
! SEGMENT 56
SEGMENT= 1 487 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00051 -0.00020
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00053  0.99369  0.11217
SEGMENT_ORGX=    5.92
SEGMENT_ORGY=  -144.32
SEGMENT_DISTANCE=  199.07
! SEGMENT 57
SEGMENT= 495 981 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00033  0.00099
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00021  0.99374  0.11172
SEGMENT_ORGX=    3.79
SEGMENT_ORGY=  -143.69
SEGMENT_DISTANCE=  199.15
! SEGMENT 58
SEGMENT= 989 1475 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00067 -0.00123
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00080  0.99372  0.11190
SEGMENT_ORGX=    7.88
SEGMENT_ORGY=  -144.66
SEGMENT_DISTANCE=  199.42
! SEGMENT 59
SEGMENT= 1483 1969 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007 -0.00038
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00011  0.99374  0.11170
SEGMENT_ORGX=    5.18
SEGMENT_ORGY=  -143.35
SEGMENT_DISTANCE=  199.36
! SEGMENT 60
SEGMENT= 1977 2463 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00080 -0.00014
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00081  0.99380  0.11117
SEGMENT_ORGX=    6.82
SEGMENT_ORGY=  -144.43
SEGMENT_DISTANCE=  199.40
! SEGMENT 61
SEGMENT= 1 487 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00000  0.00000
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00000  0.99944 -0.03352
SEGMENT_ORGX=    4.09
SEGMENT_ORGY=    52.67
SEGMENT_DISTANCE=  263.82
! SEGMENT 62
SEGMENT= 495 981 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00015  0.00057
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.99942 -0.03399
SEGMENT_ORGX=    3.77
SEGMENT_ORGY=    53.04
SEGMENT_DISTANCE=  264.14
! SEGMENT 63
SEGMENT= 989 1475 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00005  0.00096
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00001  0.99941 -0.03430
SEGMENT_ORGX=    2.71
SEGMENT_ORGY=    53.88
SEGMENT_DISTANCE=  264.03
! SEGMENT 64
SEGMENT= 1483 1969 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00000  0.00000
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00000  0.99944 -0.03352
SEGMENT_ORGX=    4.09
SEGMENT_ORGY=    52.67
SEGMENT_DISTANCE=  263.82
! SEGMENT 65
SEGMENT= 1977 2463 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00000  0.00000
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00000  0.99944 -0.03352
SEGMENT_ORGX=    4.09
SEGMENT_ORGY=    52.67
SEGMENT_DISTANCE=  263.82
! SEGMENT 66
SEGMENT= 1 487 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049  0.00114
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00068  0.98402 -0.17805
SEGMENT_ORGX=    4.00
SEGMENT_ORGY=  303.18
SEGMENT_DISTANCE=  328.29
! SEGMENT 67
SEGMENT= 495 981 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00038  0.00066
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00049  0.98400 -0.17816
SEGMENT_ORGX=    4.55
SEGMENT_ORGY=  303.20
SEGMENT_DISTANCE=  328.34
! SEGMENT 68
SEGMENT= 989 1475 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00032 -0.00068
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00019  0.98391 -0.17866
SEGMENT_ORGX=    6.24
SEGMENT_ORGY=  304.40
SEGMENT_DISTANCE=  328.74
! SEGMENT 69
SEGMENT= 1483 1969 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00037 -0.00113
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00016  0.98397 -0.17834
SEGMENT_ORGX=    7.48
SEGMENT_ORGY=  303.70
SEGMENT_DISTANCE=  328.88
! SEGMENT 70
SEGMENT= 1977 2463 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00016 -0.00027
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00011  0.98399 -0.17824
SEGMENT_ORGX=    5.61
SEGMENT_ORGY=  303.71
SEGMENT_DISTANCE=  328.44
! SEGMENT 71
SEGMENT= 1 487 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00030 -0.00024
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00021  0.94770 -0.31916
SEGMENT_ORGX=    5.64
SEGMENT_ORGY=  608.83
SEGMENT_DISTANCE=  391.30
! SEGMENT 72
SEGMENT= 495 981 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00012  0.00040
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00024  0.94756 -0.31957
SEGMENT_ORGX=    4.12
SEGMENT_ORGY=  609.89
SEGMENT_DISTANCE=  391.43
! SEGMENT 73
SEGMENT= 989 1475 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00058 -0.00069
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00033  0.94764 -0.31935
SEGMENT_ORGX=    7.12
SEGMENT_ORGY=  609.07
SEGMENT_DISTANCE=  391.50
! SEGMENT 74
SEGMENT= 1483 1969 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00048 -0.00088
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.94769 -0.31918
SEGMENT_ORGX=    7.06
SEGMENT_ORGY=  608.83
SEGMENT_DISTANCE=  391.56
! SEGMENT 75
SEGMENT= 1977 2463 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00165 -0.00010
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00153  0.94753 -0.31967
SEGMENT_ORGX=    8.87
SEGMENT_ORGY=  606.87
SEGMENT_DISTANCE=  391.76
! SEGMENT 76
SEGMENT= 1 487 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00041 -0.00026
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00025  0.89152 -0.45299
SEGMENT_ORGX=    5.40
SEGMENT_ORGY=  964.61
SEGMENT_DISTANCE=  450.92
! SEGMENT 77
SEGMENT= 495 981 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00004  0.00066
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00026  0.89140 -0.45322
SEGMENT_ORGX=    3.47
SEGMENT_ORGY=  965.43
SEGMENT_DISTANCE=  450.97
! SEGMENT 78
SEGMENT= 989 1475 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007 -0.00097
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00038  0.89142 -0.45318
SEGMENT_ORGX=    5.83
SEGMENT_ORGY=  965.97
SEGMENT_DISTANCE=  451.19
! SEGMENT 79
SEGMENT= 1483 1969 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00042 -0.00120
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00017  0.89131 -0.45339
SEGMENT_ORGX=    7.27
SEGMENT_ORGY=  966.72
SEGMENT_DISTANCE=  451.51
! SEGMENT 80
SEGMENT= 1977 2463 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00012  0.00005
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00013  0.89154 -0.45293
SEGMENT_ORGX=    4.23
SEGMENT_ORGY=  964.23
SEGMENT_DISTANCE=  450.89
! SEGMENT 81
SEGMENT= 1 487 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00041  0.00034
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00053  0.81635 -0.57756
SEGMENT_ORGX=    4.73
SEGMENT_ORGY=  1370.46
SEGMENT_DISTANCE=  506.46
! SEGMENT 82
SEGMENT= 495 981 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00031 -0.00018
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00015  0.81619 -0.57779
SEGMENT_ORGX=    5.45
SEGMENT_ORGY=  1371.41
SEGMENT_DISTANCE=  506.67
! SEGMENT 83
SEGMENT= 989 1475 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00062 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.81642 -0.57746
SEGMENT_ORGX=    7.02
SEGMENT_ORGY=  1370.21
SEGMENT_DISTANCE=  506.58
! SEGMENT 84
SEGMENT= 1483 1969 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00070 -0.00071
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00016  0.81619 -0.57778
SEGMENT_ORGX=    7.44
SEGMENT_ORGY=  1371.37
SEGMENT_DISTANCE=  506.88
! SEGMENT 85
SEGMENT= 1977 2463 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00098 -0.00041
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00056  0.81610 -0.57791
SEGMENT_ORGX=    7.74
SEGMENT_ORGY=  1370.96
SEGMENT_DISTANCE=  507.00
! SEGMENT 86
SEGMENT= 1 487 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00117  0.00085
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00026  0.72365 -0.69017
SEGMENT_ORGX=    -0.95
SEGMENT_ORGY=  1822.59
SEGMENT_DISTANCE=  556.73
! SEGMENT 87
SEGMENT= 495 981 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00032  0.00058
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.72347 -0.69035
SEGMENT_ORGX=    1.93
SEGMENT_ORGY=  1823.31
SEGMENT_DISTANCE=  556.80
! SEGMENT 88
SEGMENT= 989 1475 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00037 -0.00043
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00003  0.72375 -0.69006
SEGMENT_ORGX=    5.71
SEGMENT_ORGY=  1822.09
SEGMENT_DISTANCE=  556.81
! SEGMENT 89
SEGMENT= 1483 1969 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00077 -0.00057
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.72366 -0.69016
SEGMENT_ORGX=    7.82
SEGMENT_ORGY=  1822.42
SEGMENT_DISTANCE=  557.04
! SEGMENT 90
SEGMENT= 1977 2463 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00064 -0.00079
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00008  0.72355 -0.69027
SEGMENT_ORGX=    7.16
SEGMENT_ORGY=  1823.19
SEGMENT_DISTANCE=  557.18
! SEGMENT 91
SEGMENT= 1 487 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00020  0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00052  0.61513 -0.78843
SEGMENT_ORGX=    4.08
SEGMENT_ORGY=  2316.53
SEGMENT_DISTANCE=  600.68
! SEGMENT 92
SEGMENT= 495 981 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00045  0.00073
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00030  0.61597 -0.78777
SEGMENT_ORGX=    1.75
SEGMENT_ORGY=  2312.82
SEGMENT_DISTANCE=  600.29
! SEGMENT 93
SEGMENT= 989 1475 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007 -0.00044
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00030  0.61591 -0.78782
SEGMENT_ORGX=    4.50
SEGMENT_ORGY=  2313.65
SEGMENT_DISTANCE=  600.46
! SEGMENT 94
SEGMENT= 1483 1969 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00096  0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00099  0.61532 -0.78828
SEGMENT_ORGX=    7.42
SEGMENT_ORGY=  2314.13
SEGMENT_DISTANCE=  600.64
! SEGMENT 95
SEGMENT= 1977 2463 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00022 -0.00030
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00010  0.61556 -0.78809
SEGMENT_ORGX=    5.16
SEGMENT_ORGY=  2315.08
SEGMENT_DISTANCE=  600.62
! SEGMENT 96
SEGMENT= 1 487 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00053  0.00024
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00047  0.49448 -0.86919
SEGMENT_ORGX=    5.67
SEGMENT_ORGY=  2840.04
SEGMENT_DISTANCE=  636.75
! SEGMENT 97
SEGMENT= 495 981 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00022  0.00073
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00074  0.49423 -0.86933
SEGMENT_ORGX=    4.46
SEGMENT_ORGY=  2840.73
SEGMENT_DISTANCE=  636.83
! SEGMENT 98
SEGMENT= 989 1475 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00092 -0.00030
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00020  0.49510 -0.86884
SEGMENT_ORGX=    8.05
SEGMENT_ORGY=  2837.31
SEGMENT_DISTANCE=  636.77
! SEGMENT 99
SEGMENT= 1483 1969 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00018  0.00027
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00032  0.49433 -0.86928
SEGMENT_ORGX=    4.71
SEGMENT_ORGY=  2840.07
SEGMENT_DISTANCE=  636.77
! SEGMENT 100
SEGMENT= 1977 2463 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00091 -0.00047
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00004  0.49460 -0.86912
SEGMENT_ORGX=    8.26
SEGMENT_ORGY=  2839.42
SEGMENT_DISTANCE=  637.08
! SEGMENT 101
SEGMENT= 1 487 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00032  0.00022
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00032  0.36345 -0.93161
SEGMENT_ORGX=    5.33
SEGMENT_ORGY=  3390.42
SEGMENT_DISTANCE=  664.77
! SEGMENT 102
SEGMENT= 495 981 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00027  0.00044
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00031  0.36324 -0.93169
SEGMENT_ORGX=    2.96
SEGMENT_ORGY=  3391.32
SEGMENT_DISTANCE=  664.69
! SEGMENT 103
SEGMENT= 989 1475 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00101  0.00002
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00038  0.36357 -0.93157
SEGMENT_ORGX=    8.16
SEGMENT_ORGY=  3389.42
SEGMENT_DISTANCE=  664.85
! SEGMENT 104
SEGMENT= 1483 1969 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00059 -0.00019
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00003  0.36334 -0.93166
SEGMENT_ORGX=    6.56
SEGMENT_ORGY=  3390.71
SEGMENT_DISTANCE=  664.86
! SEGMENT 105
SEGMENT= 1977 2463 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00173 -0.00028
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00036  0.36352 -0.93159
SEGMENT_ORGX=    11.50
SEGMENT_ORGY=  3389.42
SEGMENT_DISTANCE=  665.23
! SEGMENT 106
SEGMENT= 1 487 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00058  0.00007
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00020  0.22382 -0.97463
SEGMENT_ORGX=    6.33
SEGMENT_ORGY=  3964.77
SEGMENT_DISTANCE=  684.01
! SEGMENT 107
SEGMENT= 495 981 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00071 -0.00041
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00055  0.22448 -0.97448
SEGMENT_ORGX=    1.76
SEGMENT_ORGY=  3962.92
SEGMENT_DISTANCE=  683.89
! SEGMENT 108
SEGMENT= 989 1475 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00065  0.00001
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00015  0.22437 -0.97450
SEGMENT_ORGX=    6.92
SEGMENT_ORGY=  3962.37
SEGMENT_DISTANCE=  684.06
! SEGMENT 109
SEGMENT= 1483 1969 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00073 -0.00120
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00101  0.22429 -0.97452
SEGMENT_ORGX=    7.71
SEGMENT_ORGY=  3964.48
SEGMENT_DISTANCE=  684.23
! SEGMENT 110
SEGMENT= 1977 2463 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00052 -0.00035
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00022  0.22472 -0.97442
SEGMENT_ORGX=    6.51
SEGMENT_ORGY=  3961.51
SEGMENT_DISTANCE=  684.03
! SEGMENT 111
SEGMENT= 1 487 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00029  0.00012
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00010  0.08035 -0.99677
SEGMENT_ORGX=    2.86
SEGMENT_ORGY=  4547.50
SEGMENT_DISTANCE=  693.99
! SEGMENT 112
SEGMENT= 495 981 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00088 -0.00026
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00033  0.08081 -0.99673
SEGMENT_ORGX=    0.34
SEGMENT_ORGY=  4546.02
SEGMENT_DISTANCE=  693.92
! SEGMENT 113
SEGMENT= 989 1475 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00118 -0.00039
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00029  0.07994 -0.99680
SEGMENT_ORGX=    8.96
SEGMENT_ORGY=  4549.58
SEGMENT_DISTANCE=  694.25
! SEGMENT 114
SEGMENT= 1483 1969 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00068  0.00041
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00047  0.07984 -0.99681
SEGMENT_ORGX=    6.59
SEGMENT_ORGY=  4548.65
SEGMENT_DISTANCE=  694.25
! SEGMENT 115
SEGMENT= 1977 2463 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00057 -0.00031
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00026  0.08104 -0.99671
SEGMENT_ORGX=    6.47
SEGMENT_ORGY=  4545.15
SEGMENT_DISTANCE=  694.14
! SEGMENT 116
SEGMENT= 1 487 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00100  0.00013
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00007 -0.06472 -0.99790
SEGMENT_ORGX=    7.84
SEGMENT_ORGY=  5134.69
SEGMENT_DISTANCE=  694.61
! SEGMENT 117
SEGMENT= 495 981 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00039
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00038 -0.06512 -0.99788
SEGMENT_ORGX=    2.94
SEGMENT_ORGY=  5136.66
SEGMENT_DISTANCE=  694.59
! SEGMENT 118
SEGMENT= 989 1475 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00054  0.00036
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00033 -0.06446 -0.99792
SEGMENT_ORGX=    6.18
SEGMENT_ORGY=  5133.17
SEGMENT_DISTANCE=  694.74
! SEGMENT 119
SEGMENT= 1483 1969 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00061 -0.00046
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00041 -0.06543 -0.99786
SEGMENT_ORGX=    1.83
SEGMENT_ORGY=  5138.36
SEGMENT_DISTANCE=  694.32
! SEGMENT 120
SEGMENT= 1977 2463 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049  0.00007
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00004 -0.06464 -0.99791
SEGMENT_ORGX=    6.44
SEGMENT_ORGY=  5134.23
SEGMENT_DISTANCE=  694.72
</pre>
</div>
</div>


== Limitations ==
== Limitations ==


* The script tries to interpret the header of the frames, so is currently limited to Dectris (Pilatus), ADSC (Quantum), Rigaku (several types) and MAR (CCD and image plate) detectors. 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 oscillation range, wavelength, distance, and direct beam position (or rather: point of detector that is closest to the crystal). 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 needs to 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. The frame headers do not have this information, but for some beamlines the correct value has been implemented in the script. For other beamlines, the default chosen by [[generate_XDS.INP]] may be wrong and need manual correction of XDS.INP. The correct choice can be enforced by you with a [[Generate_XDS.INP#Site_Files|site file]]. Pls also see the article [[Beamline notes]].
* 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. A beamline that is also known to have reversed X and Y is BM14 (ESRF; Mar CCD, as of April 2014) but the script does not currently implement the reversal.
* 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 certain 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 .


== See also ==
== See also ==
Line 873: Line 2,250:
* GlobalPhasing's list of beamlines and their settings is at http://www.globalphasing.com/autoproc/wiki/index.cgi?BeamlineSettings .
* GlobalPhasing's list of beamlines and their settings is at http://www.globalphasing.com/autoproc/wiki/index.cgi?BeamlineSettings .
* [[Beamline notes]] to collect information about specific settings
* [[Beamline notes]] to collect information about specific settings
* [[spot2pdb]] for visualizing reciprocal space

Latest revision as of 10:16, 28 August 2024

This script generates XDS.INP based on a list of frame names supplied on the commandline. It currently works for MarCCD, ADSC, Pilatus, Eiger, some Rigaku and one Bruker detector(s); there is also some support for microED with SMV files which have a wavelength given as 0 (look for "experimental-ED" in the script). Since this is just a bash script, extension to other detectors should be very easy.

Usage

Usage is just (don't forget the quotation marks!):

generate_XDS.INP "/home/myname/frms/mydata_1_???.img"

XDS supports bzip2-ed frames. Thus, when specifying the frame name parameter of the script, you should leave out any .bz2 extension.

For improved interaction with XDSGUI, it is advantageous to provide an absolute filename for the data files - one that starts with a slash ("/").

The script

Expand code section below (i.e. click on blue [Expand] at the end of this line if there is no code visible)


#!/bin/bash
# purpose: generate XDS.INP
#
# tested with some datasets from ALS, SSRL, SLS, ESRF, BESSY, SPring-8 and PF; only MAR, ADSC/SMV, PILATUS, Eiger, RAXIS (in-house), Bruker (PHOTON II) detectors;
# for other detectors, values marked with XXX must be manually filled in.
#
# revision 0.03 . Kay Diederichs 2/2010
# revision 0.04 . Kay Diederichs 4/2010 - include alternative ORGX, ORGY calculations for ADSC
# revision 0.05 . Kay Diederichs 5/2010 - grep for "Corrected" in addition to "marccd"; needed for BESSY
# revision 0.06 . KD 6/2010 - add UNTRUSTED_RECTANGLE and UNTRUSTED_ELLIPSE; use `whereis catmar` and so on
# revision 0.07 . KD 6/2010 - decide about ORGX/Y info in MAR header being pixels or mm; other fixes
# revision 0.08 . KD 6/2010 - fixes for Pilatus 6M
# revision 0.09 . KD 6/2010 - get rid of requirement for mccd_xdsparams.pl and/or catmar; rather use "od"
# revision 0.10 . Tim Gruene 7/2010 - set link 'images' to image directory if path exceeds 72 characters
# revision 0.11 . KD 7/2010 - for MarCCD: look for distance info at different byte position
# revision 0.12 . KD 7/2010 - fix for negative PHISTART
# revision 0.13 . KD 8/2010 - store correct NX NY QX QY in XDS.INP
# revision 0.14 . KD 1/2011 - SENSOR_THICKNESS for Pilatus; MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=3
# revision 0.15 . KD 2/2011 - add comment for -ive sign of APS 19-ID and Australian Synchrotron rotation axis
# revision 0.16 . KD 3/2011 - SENSOR_THICKNESS=0.01 for ADSC and MarCCD. Add comment about SILICON=
# revision 0.17 . KD 3/2011 - make it work for .bz2 frames; improve screen output
# revision 0.18 . KD 4/2011 - faster by doing "strings" only once; revert "images/${1##/*/}" "correction"
# revision 0.19 . KD 6/2011 - bugfix for 0.18
# revision 0.20 . KD 7/2011 - redirect stderr of /bin/ls to /dev/null
# revision 0.21 . KD 11/2011 - SEPMIN, CLUSTER_RADIUS hints; read NX NY from header (for Pilatus 2M)
# revision 0.22 . KD 12/2011 - Pilatus 2M UNTRUSTED_RECTANGLE lines, SENSOR_THICKNESS from header
# revision 0.23 . KD 1/2012 - add UNTRUSTED_QUADRILATERAL, remove MINIMUM_ZETA (0.05 is default now)
# revision 0.24 . KD 3/2012 - remove revision 0.10 since XDS now takes much longer paths
# revision 0.25 . KD 3/2012 - remove revision 0.22 for PSI Pilatus 2M; see http://www.globalphasing.com/autoproc/wiki/index.cgi?TroubleShootingKnownIssues
# revision 0.26 . KD 7/2012 - Mac-compatibility: replace od flags --skip-bytes= and --read-bytes= with -j and -N (thanks to Oliver Clarke for working this out!)
# revision 0.27 . KD 11/2012 - EXCLUDE_RESOLUTION_RANGE lines and generic Pilatus Flat_field test
# revision 0.28 . Keitaro 11/2012 - for MarCCD: read oscillation range from the position 1024+736 (fix for omega rotation)
# revision 0.29 . KD 1/2013 - include UNTRUSTED_RECTANGLEs for Pilatus 6M; never hurts but needed if the beamline software does not mark them with -2 or such
# revision 0.30 . Keitaro 3/2013 - for ADSC: write all possible beam center conventions in XDS.INP as comments
# revision 0.31 . Keitaro 3/2013 - add comment for reversed phi for SPring-8
# revision 0.32 . Keitaro 3/2013 - add RAXIS support. only tested with RAXIS IV++ and VII.
# revision 0.33 . Keitaro 5/2013 - automatically set ROTATION_AXIS=-1 0 0 for SPring-8 BL32XU/41XU/44XU beamlines based on detector serial numbers.
# revision 0.34 . Keitaro 5/2013 - recognize ADSC detectors in Photon Factory and choose correct beam center convention based on detector serial numbers.
# revision 0.35 . KD 6/2013 - reduce 7000 to 6000 for shadow detection; insert comment about *_RESOLUTION_RANGE lines
# revision 0.36 . KD 6/2013 - insert NUMBER_OF_PROFILE_GRID* lines for Pilatus (suggested by C.Vonrhein)
# revision 0.37 . Keitaro 10/2013 - fix for MX225HS detector on SPring-8 BL32XU (Ignore case when matching marccd in header); see also rev-0.39
# revision 0.38 . KD 2/2014 - change defaults for REFINE(IDXREF) and REFINE(INTEGRATE) such that more stable results are obtained for difficult datasets
# revision 0.39 . Keitaro 4/2014 - automatically set ROTATION_AXIS=-1 0 0 for MX225HS at SPring-8 BL32XU.
# revision 0.40 . Jan Gebauer /KD 4/2014 - simple implementation of MAR345 detector
# revision 0.41 . recognize header starting with R-AXIS instead of RAXIS
# revision 0.42 . Keitaro 5/2014 automatically set ROTATION_AXIS=-1 0 0 for Q315 at SPring-8 BL38B1.
# revision 0.43 . Keitaro 5/2014 add experimental support of dTREK format (raxis_smv)
# revision 0.44 . Keitaro 5/2014 automatically set ROTATION_AXIS=-1 0 0 for PILATUS3 at SPring-8 BL41XU.
# revision 0.45 . KD cope with blanks in filenames
# revision 0.46 . Keitaro 6/2014 automatically set ROTATION_AXIS=-1 0 0 for Mar225 at SPring-8 BL26B2.
# revision 0.47 . Keitaro 7/2014 more generic dTREK format support (Saturn and RAXIS)
# revision 0.48 . Kip Guja 11/2014 add detector serial number for ALS 5.0.2 to beam center convention 1
# revision 0.49 . Nobuhisa 2/2015 add  detector serial number for AichiSR BL2S1 to beam center convention 1
# revision 0.50 . KD 03/2015 workaround for Mar-1 change of parameter name "DISTANCE" to "POSITION" in REFINE(*) keywords
# revision 0.51 . Keitaro 03/2015 add .gz and .xz support and remove limitation - frame numbers can start with any.
# revision 0.52 . Keitaro 05/2015 fix ADSC beam center convention for SPring-8 and DET_SN acquisition for PILATUS (didn't work on Mac)
# revision 0.53 . KD add ADSC beam center convention for APS Argonne but only as commented line in XDS.INP (not detector serial no)
# revision 0.54 . KD add ADSC S/N 911 for APS Argonne, and fix spurious output arising from THETADISTANCE (?!)
# revision 0.55 . KD add ADSC S/N 446 for APS, and check w/ 12 datasets from data.sbgrid.org. No rule found: S/N 916 @ APS 24_ID_E !
# revision 0.56 . Keitaro 12/2015 show error message when user's input didn't match any files
# revision 0.57 . KD 12/2015 start to take care of vertical ROTATION_AXIS at Diamond I24 - for now only introduce comment
# revision 0.58 . Keitaro 01/2016 fix for dTREK image: take 'rotation axis' information from header
# revision 0.59 . KD 04/04/2016 check for ADSC detector _after_ dtrek detector, to correct wrong choice for https://zenodo.org/record/45756
# revision 0.60 . KD 04/04/2016 ADSC detector SN=458 at APS 19-ID has reverse phi (https://zenodo.org/record/45756)
# revision 0.61 . Keitaro 10/04/2016 Add Eiger hdf5 support (may be incomplete; UNTRUSTED_RECTANGLE=s not set) NEED h5dump.
# revision 0.62 . Keitaro 11/04/2016 Can give foo_master.h5 instead of foo_??????.h5.
# revision 0.63 . Keitaro 13/04/2016 Set UNTRUSTED_RECTANGLE=s for EIGER 9M and 16M (KD).
# revision 0.64 . KD 16/06/2016 reverse phi @APS 19ID (reported by Wolfram Tempel)
# revision 0.65 . Keitaro 07/09/2016 Fix for "too many arguments" problem in ls
# revision 0.66 . KD 15/09/2016 add Bruker PHOTON II with .cbf frames
# revision 0.67 . KD 02/10/2016 add BM30A (ADSC SERIAL 924) reverse_phi
# revision 0.68 . KD 24/10/2016 add -H option (follow symlinks) to "find" command (thanks to Jan Gebauer!)
# revision 0.69 . KD 04/11/2016 add CMOS-1 MBC Detector at ALS 4.2.2
# revision 0.70beta . KD 08/12/2016 ROTATION_AXIS=0 -1 0 at Diamond I24; depending on CBF header
# revision 0.70 . KD 12/01/2017 remove error message if h5dump does not find /entry/sample/transformations/omega/vector
# revision 0.71 . KD 27/02/2017 implement rule for S/N 916 @ APS 24_ID_E
# revision 0.72 . KD 8/03/2017 fix nframes lookup in Eiger master file
# revision 0.73 . KD 18/05/2017 for Andrey Nascimento: add Pilatus 2M S/N 24-0109 with ROTATION_AXIS=-1 0 0
# revision 0.74 . Keitaro 02/08/2017 Add PILATUS3 6M, S/N 60-0127 at CHESS F1 with  ROTATION_AXIS=-1 0 0
# revision 0.75 . KD 30/08/2017 reversed ORGX and ORGY for marCCD @ BM14 (Indian beamline @ ESRF)
# revision 0.76 . KD 4/09/2017 include POSITION into REFINE(IDXREF) because latest XDS is more robust. Add comments to keywords.
# revision 0.77 . KD 19/12/2017 obtain QX QY from CBF header.
# revision 0.78 . KD 21/12/2017 if possible and sensible, provide LIB= line with hardcoded /usr/local/lib64/dectris-neggia.so .
# revision 0.79 . KD 16/01/2018 read OVERLOAD from Pilatus miniCBF header instead of fixing at 1048576
# revision 0.80 . KD 13/02/2018 remove DISTANCE keyword from REFINE() list; remove POSITION from REFINE(IDXREF)
# revision 0.81 . KD 21/02/2018 when encountering CBF files from Eiger (ESRF), treat as Pilatus detector
# revision 0.82 . KD 01/03/2018 STARTING_ANGLE for MarCCD/Pilatus/PHOTON, enabling to use dials.rs_mapper with spot2pdb.
# revision 0.83 . KD 25/06/2018 for ADSC detector #458 at APS BM19, revert the definition of ROTATION_AXIS=-1 0 0. See "Beamline notes" in this wiki.
# revision 0.84 . KD 10/10/2018 implement Pilatus detector with d*TREK header
# revision 0.85 . Jie Nan 09/01/2019 STARTING_ANGLE for Eiger
# revision 0.86 . Keitaro 03/05/2019 Add PILATUS3 6M, S/N 60-0123 at SSRF BL18U-1 with ROTATION_AXIS=-1 0 0
# revision 0.87 . KD 12/10/2019 Add PILATUS XXX, S/N XX-XXX at SSRF BL19U1 and MarCCD detector #43 at BL17B1 with ROTATION_AXIS=-1 0 0
# 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.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.96 . KD 03/10/2020 make script echo detector serial number if inverted ROTATION_AXIS is detected.
# revision 0.97 . KD 19/10/2020 add UNTRUSTED_RECTANGLEs for Eiger2 (which has a few pixels less than Eiger (thanks to Andreas Förster)
# revision 0.98 . Thomas Hauß (HZB) 06/11/2020 switch Python print syntax to Python3
# revision 0.99 . Aaron Finke (CHESS) 07/11/2020 add ROTATION_AXIS=-1 0 0 for EIGER2 16M detector at MX beamline ID7B2 (CHESS)
# revision 1.00 . Gleb Bourenkov 10/11/2020 add ROTATION_AXIS=0 -1 0 for beamline P14 (EMBL Hamburg) detectors Eiger 16M S/N E-32-0107; previously Eiger 4M S/N E-08-0107 and PILATUS 6M-F, S/N 60-0115-F
# revision 1.01 . KD 07/12/2020 ROTATION_AXIS=0 -1 0 for Pilatus3 2M, S/N 24-0118 at ID23-2 (http://www.globalphasing.com/autoproc/wiki/index.cgi?BeamlineSettings)
# revision 1.02 . KD 11/01/2021 recognize mar555 detector as mar345 (thanks to Thomas Hauß, HZB)
# revision 1.03 . Feng Yu 18/7/2021 fix/expand information about Shanghai Synchrotron Radiation Facility (SSRF)
# revision 1.04 . Zhipu Luo 13/08/2021 extract ORGX,ORGY for electron diffraction from SMV header if the wavelength value starts with 0.0
# revision 1.05 . KD specialcase extraction of number of images for BNL detectors E-32-0101 and E-18-0104
# revision 1.06 . KD fix URLs in output. Availability of Apple M1 processor dectris-neggia-Apple-arm64.so . LC_ALL=C .
# revision 1.07 . KD, Thomas Hauß, Gleb Bourenkov 25/10/2021. Detector moved from Petra P14 to P13
# 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.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.14 . Juno Krahn 16/03/2023 Modified initial string header extraction; added exit to awk token extractions
#                       Print help if multiple arguments (e.g. forgot quotes) or if neither '???' or master.h5
#                       Set full path for frames; needed by some tools (e.g. show frame with predicted spots)
#                       Comment out FRACTION_OF_POLARIZATION if wavelength is copper K-alpha
#                       2-theta offset, rotation axis, starting angle, and flipping updated for all dtrek detectors
#                       Untrusted rectangle for Saturn944
#                       Environment variables to define alternate paths for dectris-neggia.so and durin-plugin.so
#                       Append detector specific parameters from $HOME/.xds-site/${DET}_${DET_SN}
#                       Cleaned up section for creating XDS.INP
# revision 1.15 . KD 22/05/2023 fix bug with second argument leading to usage message. Updating links.
# revision 1.16 . KD 26/05/2023 fix bug on Mac for Pilatus CBF missing two lines
# revision 1.17 . JMK 31/05/2023 fix sed error for Mac, where \| is not supported
# revision 1.18 . JMK 19/08/2023 Pilatus 12M support, give help msg if $5 defined (i.e. unquoted frame pattern)
# revision 1.19 . KD 14/10/2023 Pilatus 12M at DLS I23 has reverse phi. Fix download commands.
# revision 1.20 . KD 13/7/2024 Comment out line STRONG_PIXEL=4 in preparation for mid-2024 version of XDS.
REVISION="1.20 (13-Jul-2024)"

#
# usage: e.g. generate_XDS.INP "/file/system/frms/mydata_1_???.img"
# make sure to have the two quotation marks !
# the ? are wildcards for the frame numbers.
#
# known problems:
# - 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)
# - on macOS, the "Command Line Tools for Xcode" (from https://developer.apple.com/download/more/) are needed.
#
# notes for debugging of the script:
# - 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
#
# ====== Start of script ======
echo generate_XDS.INP version $REVISION. Obtain the latest version from
echo http://wiki.uni-konstanz.de/xds/index.php/generate_XDS.INP
if [ "$1" == "help" ] || [ "$1" == "-help" ] || [ "$1" == "-h" ] || [ "$1" == "" ] || [ "$5" != "" ] || ! [[ "$1" =~ \?\?|_master\.h5 ]]; then
  echo usage: generate_XDS.INP \"/file/system/frms/mydata_1_???.img\"   \(_with_ the quotation marks!\)
  echo If the frames are compressed leave out the extension .bz2, .gz, or .xz!
  echo for .h5 files: generate_XDS.INP /file/system/frms/mydata_1_master.h5
  exit
fi
# make sure the locale does not interfere with e.g. awk calculations:
export LC_ALL="C"
#
# defaults:
#
# conversion radian / degrees:
DEGTOR=57.2957795

DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX"
REVERSE_PHI="no"
ORGX=XXX
ORGY=XXX
DETECTOR_DISTANCE=XXX
OSCILLATION_RANGE=XXX
X_RAY_WAVELENGTH=XXX
QX=XXX
QY=XXX
NX=XXX
NY=XXX
SENSOR_THICKNESS=0
TRUSTED_REGION="0.0 1.2 ! partially use corners of detector (0 1.4143: use all pixels)"
# default MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT
MNOPIAS=3
# default DIRECTION_OF_DETECTOR_X-AXIS
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
pol_frac=0.98
# default POLARIZATION_PLANE_NORMAL
POLARIZATION_PLANE_NORMAL="0 1 0"
STARTING_ANGLE=0
dtrek_det=""
SEPMIN=7.0
CLUSTER_RADIUS=3.5
REFINE_CORRECT="CELL BEAM ORIENTATION AXIS POSITION ! Default is: refine everything"

dname=$(dirname "$1")
# Convert to full path (verify 'realpath' is available first)
command -v realpath &> /dev/null && dname=$(realpath $dname)
test "${dname}" == "" && dname="."
bname=$(basename "$1")
# see how we are called:
NAME_TEMPLATE_OF_DATA_FRAMES="${dname}/${bname}"
# list frames matching the wildcards in NAME_TEMPLATE_OF_DATA_FRAMES
# don't accept the "direct beam" shot at SLS/Pilatus PX-I and PX-II
# cope with blanks in directory / file name
IFS=$'\n'
find -H $dname -maxdepth 1 -name "$bname" -or -name "${bname}.bz2" -or -name "${bname}.gz" -or -name "${bname}.xz" | egrep -v "_00000.cbf|_000.img" | sort > tmp1
if [ ! -s tmp1 ]
then
 echo "Error! No files matched: $1"
 rm -f tmp1
 exit 1
fi
unset IFS
# we can continue - the frames are found

if echo $NAME_TEMPLATE_OF_DATA_FRAMES | grep '_master.h5$' > /dev/null; then
 NAME_TEMPLATE_OF_DATA_FRAMES=`echo "$NAME_TEMPLATE_OF_DATA_FRAMES" | sed -e 's/_master.h5$/_??????.h5/'`
else
 # Find the first '?' position and the number of '?' to determine DATA_RANGE=.
 pos1=`echo "$NAME_TEMPLATE_OF_DATA_FRAMES" | awk '{print index($0, "?")}'`
 pos2=`echo "$NAME_TEMPLATE_OF_DATA_FRAMES" | sed -e "s/[^\?]//g" | awk '{print length+'$pos1' - 1}'`
 data_first=`cut -b $pos1-$pos2 tmp1 | head -n1 | bc`
 data_last=`cut -b $pos1-$pos2 tmp1 | tail -n1 | bc`
 DATA_RANGE="$data_first $data_last"
 echo DATA_RANGE=$DATA_RANGE

 # set SPOT_RANGE to first half of DATA_RANGE
 data_num=`wc -l tmp1 | awk '{print $1}'`
 data_half=`echo "scale=0; $data_num/2" | bc -l`
 data_half=`echo "if ($data_half<=1) 1;if ($data_half>1) $data_half" | bc -l`
 spot_last=`echo "scale=0; $data_first+$data_half-1" | bc -l`
 SPOT_RANGE="$data_first $spot_last"
fi

FIRSTFRAME=`head -1 tmp1`
echo $FIRSTFRAME | grep "\.h5$" && is_h5=1 || is_h5=0

# find out detector type
DET=XXX
IFS=$'\n'
echo $FIRSTFRAME | grep -q '\.bz2$' && bzcat $FIRSTFRAME > tmp1 && FIRSTFRAME=tmp1
# for mac/linux compatibility. zcat foo.gz doesn't work on mac.
echo $FIRSTFRAME | grep -q '\.gz$' && zcat < $FIRSTFRAME > tmp1 && FIRSTFRAME=tmp1
echo $FIRSTFRAME | grep -q '\.xz$' && xzcat $FIRSTFRAME > tmp1 && FIRSTFRAME=tmp1

unset IFS
if [ "$is_h5" == 0 ]; then
 # extract strings from binary file header, removing leading '#' (Pilatus) and trailing ';' (CBF)
 strings $FIRSTFRAME | head -400 | sed 's/^ *#//;s/; *$//;' >tmp2
 # TODO: whenever FIRSTFRAME is used below, it should be copied to tmp2 (using IFS as above), and tmp2 should be used instead
 # this was done for "mccd", but still has to be done for the "raxis" detector types
 # the reason is that FIRSTFRAME may contain a blank, which makes some commands fail
 egrep -qi 'marccd|Corrected' tmp2 && DET=mccd
 grep -q PILATUS tmp2             && DET=pilatus
 grep -iq Eiger tmp2              && DET=pilatus
 head -n1 tmp2 | grep -q "^RAXIS" && DET=raxis
 head -n1 tmp2 | grep -q "^R-AXIS" && DET=raxis
 grep -q "^SOURCE_WAVELENGTH= *1" tmp2 && DET=dtrek
 grep -q BEAM_CENTER_X tmp2       && DET=adsc
 grep -q mar345 tmp2		 && DET=MAR345
 # rev. 1.02: in one case, mar555 data could be processed pretending it is mar345, so:
 grep -q mar555 tmp2		 && DET=MAR345
 grep -q BRUKER tmp2 && grep -q CBF tmp2  && DET=Bruker-cbf
 grep -q CMOS1 tmp2 && DET=adsc-CMOS1
 grep -q MARCONTROL tmp2 && DET=OLDMAR
 grep -q "WAVELENGTH=0.0" tmp2 && DET=experimental-ED
else
 h5dump -d "/entry/instrument/detector/description" $FIRSTFRAME | grep -i Eiger > /dev/null && DET=eiger
fi

# identify other detector types in the same way

# parse ASCII header of first frame

if [ "$DET" == "XXX" ]; then
  echo "Detector type unknown -- fill in XXX values manually!"
  DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX OVERLOAD=XXX"

# find parameters of first frame
elif [ "$DET" == "mccd" ]; then
  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"
  SENSOR_THICKNESS=0.01
  # use first frame of dataset to obtain parameters

  # Check detector serial number and recognize beamline for reversed-phi setting.
  # Known detectors for reversed-phi in SPring-8: 24: BL26B2 Mar225, 31: BL32XU MX225HE, 38: BL44XU MX225HE, 42: BL44XU MX300HE, 40: BL41XU MX225HE, 106: BL32XU MX225HS
  # same for SSRF: BL17B1 rayonix MX300. As on 2019-10-13, this also needs doubling of ORGX and ORGY. But the beamline staff (Wenming) wants to fix the header.
  REVERSEPHI_SNs="
24
31
38
40
42
43
106
"
  # get detector serial number and check if it is included in the list
  DET_SN=`grep "Detector Serial Number =" tmp2 | sed "s/Detector Serial Number = //"`
  if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
    REVERSE_PHI="yes"
    echo inverted ROTATION_AXIS since Detector Serial Number is "${DET_SN}"
  fi

  # offsets are documented; values can be found in mccd_xdsparams.pl script
  IFS=$'\n'
  cp $FIRSTFRAME tmp2
  unset IFS
  let SKIP=1024+80
  NX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  let SKIP=$SKIP+4
  NY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')

  let SKIP=1720
  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`

# 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
  STARTING_ANGLE=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  STARTING_ANGLE=`echo "scale=2; $STARTING_ANGLE/1000" | bc -l `

  let SKIP=1024+256+128+256+4
  ORGX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  ORGX=`echo "scale=2; $ORGX/1000" | bc -l `
  let SKIP=$SKIP+4
  ORGY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  ORGY=`echo "scale=2; $ORGY/1000" | bc -l `
# fixed Aug 30, 2017 after IUCr2017 @ Hyderabad
  if [ "$DET_SN" == "4" ]; then
     TEMP=$ORGY
     ORGY=$ORGX
     ORGX=$TEMP
     echo reversed ORGX and ORGY for marCCD @ ESRF BM14
  fi

  let SKIP=1024+736
  OSCILLATION_RANGE=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  OSCILLATION_RANGE=`echo "scale=3; $OSCILLATION_RANGE/1000" | bc -l`

  let SKIP=1024+256+128+256+128+4
  QX=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  QX=`echo "scale=10; $QX/1000000" |bc -l `
  let SKIP=$SKIP+4
  QY=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  QY=`echo "scale=10; $QY/1000000" |bc -l `

  let SKIP=1024+256+128+256+128+128+12
  X_RAY_WAVELENGTH=$(od -t dI -j $SKIP -N 4 tmp2 | head -1 | awk '{print $2}')
  X_RAY_WAVELENGTH=`echo "scale=5; $X_RAY_WAVELENGTH/100000" | bc -l`

# at most BLs, ORGX and ORGY are in pixels, but sometimes in mm ... guess:
  NXBYFOUR=`echo "scale=0; $NX/4" | bc -l `
  ORGXINT=`echo "scale=0; $ORGX/1" | bc -l `
  if [ $ORGXINT -lt $NXBYFOUR ]; then
     ORGX=`echo "scale=1; $ORGX/$QX" | bc -l`
     ORGY=`echo "scale=1; $ORGY/$QY" | bc -l`
     echo MARCCD detector: header ORGX, ORGY seem to be in mm ... converting to pixels
  else
     echo MARCCD detector: header ORGX, ORGY seem to be in pixel units
  fi

elif [ "$DET" == "adsc" ]; then

  DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000"
  echo Data from ADSC detector. Obtaining ORGX, ORGY depends on beamline setup:
  SENSOR_THICKNESS=0.01

      # find X_RAY_WAVELENGTH:
      X_RAY_WAVELENGTH=`grep WAVELENGTH tmp2 | head -1 | sed s/WAVELENGTH=//`

      # find NX, QX, ORGX and ORGY:
      NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
      NY=`grep SIZE2 tmp2 | tail -1 | sed s/SIZE2=//`
      QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//`
      QY=$QX
      BEAM_CENTER_X=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//`
      BEAM_CENTER_Y=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`

      COMMENT_ORGXY="
! Following are possible beam center interpretations for ADSC detectors"
# at ESRF, PF, ALS 5.0.2, AS MX2 and ... (pls fill in!) the following should be used:
      ORGX1=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l`
      ORGY1=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l`
      echo - at ESRF, PF, ALS 8.2.1, APS Argonne BLs use: ORGX=$ORGX1 ORGY=$ORGY1
      COMMENT_ORGXY="${COMMENT_ORGXY}
! ORGX= $ORGX1 ORGY= $ORGY1 ! For ESRF, PF, APS, AS MX2 ..."
# this 2nd alternative convention should be used at the following beamlines (pls complete the list): ALS 5.0.3, ...
      ORGX2=`echo "scale=1; $NX-$BEAM_CENTER_X/$QX" | bc -l `
      ORGY2=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l `
      echo - at e.g. ALS 5.0.3 use: ORGX=$ORGX2 ORGY=$ORGY2
      COMMENT_ORGXY="${COMMENT_ORGXY}
! ORGX= $ORGX2 ORGY= $ORGY2 ! For ALS 5.0.3,.."
# this 3rd alternative convention should be used at the following beamlines (pls complete the list): ALS 8.2.2, ...
# this alternative is written into the generated XDS.INP ! You have to correct this manually in XDS.INP, or adjust this script.
      ORGX3=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l `
      ORGY3=`echo "scale=1; $NX-$BEAM_CENTER_Y/$QX" | bc -l `
      echo - at e.g. ALS 8.2.2 use: ORGX=$ORGX3 ORGY=$ORGY3 - this is written to XDS.INP if beamline is not detected
      COMMENT_ORGXY="${COMMENT_ORGXY}
! ORGX= $ORGX3 ORGY= $ORGY3 ! For ALS 8.2.2,.."
# this 4th alternative convention should be used at the following beamlines (pls complete the list): SPring-8, ...
      ORGX4=`echo "scale=1; $BEAM_CENTER_X/$QX" | bc -l `
      ORGY4=`echo "scale=1; $BEAM_CENTER_Y/$QX" | bc -l `
      echo - at e.g. SPring-8 use: ORGX=$ORGX4 ORGY=$ORGY4
      COMMENT_ORGXY="${COMMENT_ORGXY}
! ORGX= $ORGX4 ORGY= $ORGY4 ! For SPring-8,.."

      # Decision of beam center convention based on detector serial numbers.
      DET_SN=`grep DETECTOR_SN tmp2 | sed -e "s/DETECTOR_SN=//"`
      echo Detector serial number is $DET_SN
      # For convention 1; Known PF detectors = 449: NW12A Q210, 472: NE3A Q270, 474: BL17A Q270, 912: BL5A Q315, 923: ALS BL5.0.2 Q315, 933: AichiSR BL2S1 Q315, 916: APS 24 IDE, 928: AS MX2
      ORG1_SNs="
449
472
474
912
923
933
911
446
916
905
928
"
      ORG4_SNs="
915
"
      if echo "${DET_SN}${ORG1_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
       ORGX=$ORGX1
       ORGY=$ORGY1
       echo the following was chosen based on detector serial number:
      elif echo "${DET_SN}${ORG4_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
       ORGX=$ORGX4
       ORGY=$ORGY4
       echo the following was chosen based on detector serial number:
      else
       ORGX=$ORGX3
       ORGY=$ORGY3
       echo the following default was chosen because the detector serial number was not special-cased:
      fi

      # Check detector serial number and recognize beamline for reversed-phi setting.
      # Known detectors for reversed-phi in SPring-8: 915: BL38B1 Q315; APS 19-ID: 458; BM30A: 924
      # 928 is at Australian Beamline MX2
      # revision 0.83 of this script removes 458 from the list!
      REVERSEPHI_SNs="
915
924
928
"
      if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
        REVERSE_PHI="yes"
        echo inverted ROTATION_AXIS since detector serial number is ${DET_SN}
      fi

      # 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" == "adsc-CMOS1" ]; then
  DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000"
  echo Data from CMOS1 MBC detector.
  SENSOR_THICKNESS=0.01
  X_RAY_WAVELENGTH=`grep WAVELENGTH tmp2 | head -1 | sed s/WAVELENGTH=//`
  NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
  QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//`
  NY=`grep SIZE2 tmp2 | tail -1 | sed s/SIZE2=//`
  QY=$QX
  ORGX=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//`
  ORGY=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`
  REVERSE_PHI="yes"
  DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=/-/`
  OSCILLATION_RANGE=`grep OMEGA_DELTA tmp2 | sed s/OMEGA_DELTA=//`
  DETECTOR_X_AXIS="-1 0 0"

elif [ "$DET" == "experimental-ED" ]; then
  DETECTOR="ADSC MINIMUM_VALID_PIXEL_VALUE= 1 OVERLOAD= 65000  ! OVERLOAD is really unknown "
  echo --- Electron diffraction data in SMV format!
  SENSOR_THICKNESS=0.01
  X_RAY_WAVELENGTH=`grep WAVELENGTH tmp2 | head -1 | sed s/WAVELENGTH=//`
  NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
  QX=`grep PIXEL_SIZE tmp2 | sed s/PIXEL_SIZE=//`
  NY=`grep SIZE2 tmp2 | tail -1 | sed s/SIZE2=//`
  QY=$QX
  BEAM_CENTER_X=`grep BEAM_CENTER_X tmp2 | sed s/BEAM_CENTER_X=//`
  BEAM_CENTER_Y=`grep BEAM_CENTER_Y tmp2 | sed s/BEAM_CENTER_Y=//`
  QXY=`echo "scale=1; $QX*($BEAM_CENTER_X+$BEAM_CENTER_Y)" | bc -l`
      if [ "$QXY" "<" "$BEAM_CENTER_X" ] ; then
       ORGX=`echo "scale=2; $BEAM_CENTER_Y/$QX" | bc -l`
       ORGY=`echo "scale=2; $BEAM_CENTER_X/$QX" | bc -l`
      else
       ORGX=`echo "scale=2; $BEAM_CENTER_X/1" | bc -l`
       ORGY=`echo "scale=2; $BEAM_CENTER_Y/1" | bc -l`
      fi
  DETECTOR_DISTANCE=`grep ^DISTANCE tmp2 | sed s/DISTANCE=//`
  OSCILLATION_RANGE=`grep OSC_RANGE tmp2 | sed s/OSC_RANGE=//`
  STARTING_ANGLE=`grep OSC_START tmp2 | sed s/OSC_START=//`
  echo --- For TIMEPIX detector, please fix ROTATION_AXIS yourself!
  DIRECTION_OF_DETECTOR_X_AXIS="1 0 0"
  REFINE_CORRECT="ORIENTATION CELL AXIS BEAM ! for ED, no POSITION when CELL is refined"

elif [ "$DET" == "pilatus" ]; then
  echo Data from a Pilatus detector
  OVERLOAD=1048574
  SEPMIN=4
  CLUSTER_RADIUS=2
  grep -q Count_cutoff tmp2 && OVERLOAD=`awk '/Count_cutoff/{print $2;exit}' tmp2`
  DETECTOR="PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD= $OVERLOAD  !PILATUS"
  QX=0.172 QY=0.172
# the default above guards against missing Pixel_size line in CBF header
  grep -q Pixel_size tmp2 && QX=`awk '/Pixel_size/{print 1000*$2;exit}' tmp2`
  grep -q Pixel_size tmp2 && QY=`awk '/Pixel_size/{print 1000*$5;exit}' tmp2`

      # find SENSOR_THICKNESS:
      SENSOR_THICKNESS=`grep thickness tmp2 | sed -e s/'Si.* sensor, thickness'// | awk '{print $1*1000}'`
      # find X_RAY_WAVELENGTH:
      X_RAY_WAVELENGTH=`grep Wavelength tmp2 | sed -e s/Wavelength// -e s/A// | awk '{print $1}'`

      # find NX and NY; 2463/2527 is 6M, 1475/1679 is 2M
      NX=`grep X-Binary-Size-Fastest-Dimension tmp2 | awk '{print $2}'`
      NY=`grep X-Binary-Size-Second-Dimension tmp2 | awk '{print $2}'`

      # 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, OSCILLATION_RANGE, and STARTING_ANGLE:
      DETECTOR_DISTANCE=`awk '/Detector_distance/{print $2;exit}' tmp2`
      DETECTOR_DISTANCE=`echo "$DETECTOR_DISTANCE*1000" | bc -l`

      OSCILLATION_RANGE=`awk '/Angle_increment/{print $2;exit}' tmp2`

      STARTING_ANGLE=`awk '/Start_angle/{print $2;exit}' tmp2`

      # get detector serial number and check if it is included in the list
      # Known detectors for reversed-phi in SPring-8: BL41XU PILATUS3 6M 60-0125
      # Known detectors for reversed-phi in APS: 19ID PILATUS3 6M 60-0132
      # Known detectors for reversed-phi at MX2 beamline (Brazilian Synchrotron National Laboratory - LNLS)
      # Known detectors for reversed-phi at CHESS F1 PILATUS3 6M, S/N 60-0127
      # Known detectors for reversed-phi at SSRF BL18U1 (S/N 60-0123) and BL19U1 (S/N XX-XXX) (!; 2019-10-19: staff will fix this)
      DET_SN=`grep "Detector:" tmp2 | sed "s/^.*Detector: *//"`
      echo detector serial number is $DET_SN
      REVERSEPHI_SNs="
PILATUS3 6M, S/N 60-0125
PILATUS3 6M, S/N 60-0132
PILATUS 2M, S/N 24-0109
PILATUS3 6M, S/N 60-0127
PILATUS3 6M, S/N 60-0123
PILATUS 12M, S/N 120-0100
"
      if echo "${DET_SN}${REVERSEPHI_SNs}" | sort | uniq -d | grep [0-9] > /dev/null; then
        REVERSE_PHI="yes"
        echo inverted ROTATION_AXIS since detector serial number is ${DET_SN}
      fi
      if [ "$DET_SN" == "PILATUS XXX, S/N XX-XXX" ] ; then
        REVERSE_PHI="yes"
        echo inverted rotation axis at SSRF BL19U1
      fi

# Diamond I24:
      if [ "$DET_SN" == "PILATUS3 6M, S/N 60-0119" ] ; then
        if grep -q "Oscillation_axis X.CW +SLOW" tmp2 ; then
          ROTATION_AXIS="0 -1 0"
          echo ROTATION_AXIS="0 -1 0" at Diamond I24
        fi
      fi
# 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" \
                                        -o "$DET_SN" == "Dectris EIGER2 CdTe 16M, E-32-0129" ] ; then
        ROTATION_AXIS="0 -1 0"
        echo ROTATION_AXIS="0 -1 0" at PETRA P14
      fi
# similarly, Eiger 16M at PETRA P14 until May 22, 2021
      if [ "$DET_SN" == "Dectris Eiger 16M, E-32-0107" ] ; then
        egrep -q '^# 2020-|^# 2021-0[1-5]|^# 2021-06-[01]|^# 2021-06-2[01]' tmp2 || isatP13=1
        if [ "$isatP13" == 1 ] ; then
          echo using the default ROTATION_AXIS=1 0 0 at PETRA P13
        else
          ROTATION_AXIS="0 -1 0"
          echo ROTATION_AXIS="0 -1 0" at PETRA P14
        fi
      fi
# ESRF ID23-2:
      if [ "$DET_SN" == "PILATUS3 2M, S/N 24-0118, ESRF ID23" ] ; then
        ROTATION_AXIS="0 -1 0"
        echo ROTATION_AXIS="0 -1 0" at ESRF ID23-2
      fi

elif [ "$DET" == "eiger" ]; then
 nframes=`h5dump -d "/entry/instrument/detector/detectorSpecific/nimages" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2}'`
 DATA_RANGE="1 $nframes"
 SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`"
 DET_SN=`h5dump -d "/entry/instrument/detector/detector_number" $FIRSTFRAME | awk '/\(0\): /{print $2}' | sed s/\"//g`
 echo detector serial number is $DET_SN

# 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
# unfortunately h5dump 1.10 is required to get this right for the DLS .h5 files. This version is available at DLS but maybe not elsewhere
    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
  # 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
    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 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)
    if [ "$STARTING_ANGLE" == "" ]; then
		  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"`
    fi
  # 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"`
  # EIGER2 16M CHESS ID7B2 has S/N E-32-0123 (A. Finke 2020-11-07) v0.99
    if [ "$DET_SN" == "E-32-0123" ]; then
      ROTATION_AXIS="-1 0 0"
      echo CHESS ID7B2 with inverted rotation axis
    fi
  # SSRF BL17U1 and SSRF BL10U2 (Feng YU 2021-07-18)
  # Eiger X 16M (S/N E-32-0111) was installed at SSRF BL17U1 from Oct 2017 to Feb 2021. After Feb 2021, it was moved back to SSRF BL10U2.
	# 2021-03-01 00:00:00 time stamp is 1614528000
    if [ "$DET_SN" == "E-32-0111" ]; then
      collection_time=`h5dump -d "/entry/instrument/detector/detectorSpecific/data_collection_date" $FIRSTFRAME | grep "(0):" | awk '{print $2}' | sed -e "s/\.\(.*\)//g; s/\"//g"`
      if [ `uname -s` == "Darwin" ]; then
        collection_timestamp=`date -j -f "%Y-%m-%dT%H:%M:%S" $collection_time +%s`
      elif [ `uname -s` == "Linux" ]; then
        collection_timestamp=`date -d $collection_time +%s`
      else
        collection_timestamp=0
      fi
      if [ $collection_timestamp -eq 0 ]; then
        is_ROTATION_AXIS_set=1
        ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME 2>/dev/null || is_ROTATION_AXIS_set=0`
        if [ "$is_ROTATION_AXIS_set" == "1" ]; then
          ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME | grep "(0):" | sed -e "s/^.*://; s/,//g"`
          echo "The rotation axis of SSRF BL10U2 (Eiger X 16M) is $ROTATION_AXIS"
        else
          ROTATION_AXIS="-1 0 0    ! Cannot determine rotation axis. SSRF BL17U1: -1 0 0; SSRF BL02U1: 0 -1 0"
        fi
      elif [ $collection_timestamp -ge 0 ] && [ $collection_timestamp -le 1614528000 ]; then
        # SSRF BL17U1
        ROTATION_AXIS="-1 0 0"
        echo "SSRF BL17U1 (Eiger X 16M) with inverted rotation axis"
      else
        # SSRF BL10U2
        is_ROTATION_AXIS_set=1
        ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME 2>/dev/null || is_ROTATION_AXIS_set=0`
        if [ "$is_ROTATION_AXIS_set" == "1" ]; then
          ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME | grep "(0):" | sed -e "s/^.*://; s/,//g"`
          echo "The rotation axis of SSRF BL10U2 (Eiger X 16M) is $ROTATION_AXIS"
        else
          ROTATION_AXIS="0 -1 0"
          echo "SSRF BL10U2 (Eiger X 16M) with vertical rotation axis"
        fi
      fi
    fi
  # SSRF BL02U1 (Feng YU 2021-07-18)
  # EIGER2 S 9M SSRF BL02U1 has S/N E-18-0121
    if [ "$DET_SN" == "E-18-0121" ]; then
      is_ROTATION_AXIS_set=1
      ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME 2>/dev/null || is_ROTATION_AXIS_set=0`
      if [ "$is_ROTATION_AXIS_set" == "1" ]; then
        ROTATION_AXIS=`h5dump -d "/SSRF/RotationAxis" $FIRSTFRAME | grep "(0):" | sed -e "s/^.*://; s/,//g"`
        echo "The rotation axis of SSRF BL02U1 (Eiger2 S 9M) is $ROTATION_AXIS"
      else
        ROTATION_AXIS="1 0 0"
        echo "SSRF BL02U1 (Eiger2 S 9M) with horizontal rotation axis"
      fi
    fi
# revision 1.05 specialcase nframes for Eiger detectors at BNL
    if [ "$DET_SN" == "E-18-0104" -o "$DET_SN" == "E-32-0101" ]; then
      nframes=`h5dump -A -g "/entry/data" $FIRSTFRAME | grep "DATASPACE  SIMPLE" | sed -e "s/,.*//" | awk '{a+=$5}END{print a}'`
      DATA_RANGE="1 $nframes"
      SPOT_RANGE="1 `echo "scale=0; if (${nframes}<2) 1; if (${nframes}>1) ${nframes}/2"|bc -l`"
      echo Special case nframes for Eiger detectors at BNL: nframes=$nframes
    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
  echo DATA_RANGE=$DATA_RANGE
  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}'`
  QY=`h5dump -d "/entry/instrument/detector/y_pixel_size" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`

  echo OVERLOAD=$OVERLOAD
  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}'`

  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}'`

  # find ORGX and ORGY:
  ORGX=`h5dump -d "/entry/instrument/detector/beam_center_x" $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 :
  DETECTOR_DISTANCE=`h5dump -d "/entry/instrument/detector/detector_distance" $FIRSTFRAME | awk '/\(0\): [0-9]/{print $2*1000}'`

  SEPMIN=4
  CLUSTER_RADIUS=2

elif [ "$DET" == "raxis" ]; then
  echo Data from an RAXIS detector

  DETECTOR="RAXIS MINIMUM_VALID_PIXEL_VALUE=0  OVERLOAD=2000000"
  #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=$(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)))')
  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)))')
  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)))')
  X_RAY_WAVELENGTH=$(python -c 'import struct; f=open("'$FIRSTFRAME'","rb");f.seek(292);print("%.6f"%struct.unpack(">f",f.read(4)))')
  DIRECTION_OF_DETECTOR_Y_AXIS="0 -1 0"
  POLARIZATION_PLANE_NORMAL="1 0 0"
  ROTATION_AXIS="0 1 0"

elif [ "$DET" == "dtrek" ]; then

  dname=`grep "DETECTOR_NAMES=" tmp2 | sed -e "s/.*=//"`
  if [ "$dname" == "CCD_" ]; then
    DETECTOR="SATURN MINIMUM_VALID_PIXEL_VALUE=1"
    dtrek_det="saturn"
  elif [ "$dname" == "PILT_" ]; then
    DETECTOR="PILATUS MINIMUM_VALID_PIXEL_VALUE=0"
    dtrek_det="pilatus"
    SEPMIN=3
    CLUSTER_RADIUS=1.5
    SENSOR_THICKNESS=$(awk 'match($0,/SENSOR_THICKNESS= *(\S*)/,a){printf"%.3f",1000*a[1];exit}ENDFILE{print "0.45"}' tmp2)
  elif [ "$dname" == "RX_" ]; then
    DETECTOR="RAXIS MINIMUM_VALID_PIXEL_VALUE=0"
    dtrek_det="raxis"
    POLARIZATION_PLANE_NORMAL="1 0 0"
    ROTATION_AXIS="0 1 0"
  else
    DETECTOR="XXX MINIMUM_VALID_PIXEL_VALUE=XXX"
    dtrek_det="unknown"
    echo "WARNING: Unsupported dTREK detector, check parameters"
  fi
  DET_SN=`awk '/_DETECTOR_IDENTIFICATION=/{print;exit}' tmp2 | sed 's/.*DETECTOR_IDENTIFICATION=//'`
  echo "Data from a $dtrek_det detector with dTREK format, ID=$DET_SN"
  # Find rotation axis and flipping
  # I'm not sure this method is really valid - but at least mosflm seems to read this to determine rotation axis.
  tmpmat=(`grep ${dname}SPATIAL_DISTORTION_VECTORS= tmp2 | tail -1 | sed -e "s/.*=//"`)
  flip=`echo "(${tmpmat[0]}*${tmpmat[3]}-(${tmpmat[1]}*${tmpmat[2]}))/1"|bc`
  if [ "$flip" -ne 1 -a "$flip" -ne -1 ]; then
    echo ""
    echo "WARNING!! not-supported SPATIAL_DISTORTION_VECTORS header."
    echo "Please report this to XDSwiki author."
    echo ""
  elif [ "$flip" -eq -1 ]; then
    echo "Detector is flipped (from SPATIAL_DISTORTION_VECTORS header)"
  fi
  rotx=`echo "scale=6; -1.0*$flip*${tmpmat[0]}" | bc -l`
  roty=`echo "scale=6; -1.0*$flip*${tmpmat[1]}" | bc -l`
  ROTATION_AXIS="$rotx $roty 0"
# 2theta
  TWOTHETA=`awk '/'${dname}'GONIO_VALUES=/{print $2;exit}' tmp2`
  R1=`echo "scale=7; $flip*-c($TWOTHETA/$DEGTOR)" | bc -l`
  R3=`echo "scale=7; $flip* s($TWOTHETA/$DEGTOR)" | bc -l`
  DIRECTION_OF_DETECTOR_X_AXIS="$R1 0 $R3"
  echo "Detector 2-theta = $TWOTHETA  "
  echo DIRECTION_OF_DETECTOR_X_AXIS="$R1 0 $R3"
  # find OVERLOAD
  SATURATED_VALUE=`grep SATURATED_VALUE tmp2 | head -1 | sed s/SATURATED_VALUE=//`
  DETECTOR="${DETECTOR}  OVERLOAD=${SATURATED_VALUE}"

  # find X_RAY_WAVELENGTH:
  X_RAY_WAVELENGTH=(`grep SOURCE_WAVELENGTH tmp2 | head -1 | sed s/SOURCE_WAVELENGTH=//`)
  X_RAY_WAVELENGTH=${X_RAY_WAVELENGTH[1]}

  # find NX,NY,QX,QY
  # NX,NY should be read from *_DETECTOR_DIMENSIONS?
  NX=`grep SIZE1 tmp2 | tail -1 | sed s/SIZE1=//`
  NY=`grep SIZE2 tmp2 | tail -1 | sed s/SIZE2=//`
  DET_SIZE=(`grep ${dname}DETECTOR_SIZE tmp2 | tail -1 | sed s/.*_DETECTOR_SIZE=//`)
  QX=`echo "scale=6; ${DET_SIZE[0]} / $NX" | bc -l`
  QY=`echo "scale=6; ${DET_SIZE[1]} / $NY" | bc -l`

  # find ORGX, ORGY
  SPATIAL_DISTORTION_INFO=(`grep ${dname}SPATIAL_DISTORTION_INFO tmp2 | tail -1 | sed s/.*_SPATIAL_DISTORTION_INFO=//`)
  ORGX=${SPATIAL_DISTORTION_INFO[0]}
  ORGY=${SPATIAL_DISTORTION_INFO[1]}

  # find DETECTOR_DISTANCE
  GONIO_NAMES=(`grep ${dname}GONIO_NAMES= tmp2 | tail -1 | sed s/.*_GONIO_NAMES=//`)
  GONIO_VALUES=(`grep ${dname}GONIO_VALUES= tmp2 | tail -1 | sed s/.*_GONIO_VALUES=//`)
#  GONIO_UNITS=(`grep ${dname}GONIO_UNITS= tmp2 | tail -1 | sed s/.*_GONIO_UNITS=//`)
  for i in `seq 1 ${#GONIO_NAMES[*]}`
  do
   idx=$((i-1))
   if [ "${GONIO_NAMES[$idx]}" == "Distance" ]; then
     if [ $flip -gt 0 ]; then
       DETECTOR_DISTANCE="-${GONIO_VALUES[$idx]}"
       echo "Detector not flipped; using negative distance"
     else
       DETECTOR_DISTANCE="${GONIO_VALUES[$idx]}"
       echo "Detector flipped; using positive distance"
     fi
     break
   fi
  done

  # find OSCILLATION start and range
  ROTATION=(`grep "^ROTATION=" tmp2 | tail -1 | sed s/ROTATION=//`)
  STARTING_ANGLE=${ROTATION[0]}
  OSCILLATION_RANGE=${ROTATION[2]}

elif [ "$DET" == "MAR345" ]; then

 echo  "Data from a Mar345 image plate detector"
 DETECTOR="MAR345  MINIMUM_VALID_PIXEL_VALUE=0  OVERLOAD=130000"
 NX=`awk '/FORMAT/{print $2;exit}' tmp2`
# next line is rev 1.02 (previously NY= $NX):
 NY=`awk -v NX=$NX '/FORMAT/{print $4/NX;exit}' tmp2`
 QX=`awk '/PIXEL/{print $3/1000.;exit}' tmp2`
 QY=`awk '/PIXEL/{print $5/1000.;exit}' tmp2`
 if grep -q 'CENTER' tmp2; then
   echo Beam center found.
   ORGX=`grep 'CENTER' tmp2 | awk '{print $3}'`
   ORGY=`grep 'CENTER' tmp2 | awk '{print $5}'`
 else
   echo No beam center was found. Setting beam center to the middle of the detector.
   ORGX=`echo $NX / 2 | bc`
   ORGY=`echo $NY / 2 | bc`
 fi
 DETECTOR_DISTANCE=`grep 'DISTANCE' tmp2 | awk '{print $2}'`
 X_RAY_WAVELENGTH=`grep 'WAVELENGTH' tmp2 | awk '{print $2}'`
 OSCILLATION_RANGE=`grep 'PHI' tmp2 | awk '{print $5-$3}'`
 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;exit}' tmp2`
 NY=$NX
 QX=`awk 'NR==2 {print $15;exit}' tmp2`
 QY=$QX
 ORGX=`awk 'NR==2 {print $19;exit}' tmp2`
 ORGY=`awk 'NR==2 {print $20;exit}' tmp2`
 DETECTOR_DISTANCE=`awk 'NR==2 {print $22;exit}' tmp2`
 X_RAY_WAVELENGTH=`awk 'NR==2 {print $21;exit}' tmp2`
 OSCILLATION_RANGE=`awk 'NR==2 {print $24-$23;exit}' 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

 echo  "Data from a Bruker-cbf detector"
# MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT:
 MNOPIAS=6
# use complete detector including corners:
 TRUSTED_REGION="0 1.42"
# polarization
 pol_frac=`awk '/polarizn_source_ratio/{print $2;exit}' tmp2`
 pol_frac=`echo "${pol_frac}+0.5" | bc -l`
 OVERLOAD=`awk '/_array_intensities.overload/{print $2;exit}' tmp2`
 DETECTOR="BRUKER MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD=${OVERLOAD}"
 NX=`awk '/X-Binary-Size-Fastest-Dimension/{print $2;exit}' tmp2`
 NY=`awk '/X-Binary-Size-Second-Dimension/{print $2;exit}' tmp2`

 QX=`awk '/ELEMENT_X ELEMENT_X/{print $4;exit}' tmp2`
 QY=`awk '/ELEMENT_Y ELEMENT_Y/{print $4;exit}' tmp2`

# ORGX/Y-offsets relative to center of detector:
 ORGX=`grep " 0 0 ? ? ?" tmp2 | awk '/ H /{print $2}'`
 ORGY=`grep " 0 0 ? ? ?" tmp2 | awk '/ V /{print $2}'`
# total ORGX/Y
 ORGX=`echo "scale=2; ${NX}/2+($ORGX/$QX)" | bc -l`
 ORGY=`echo "scale=2; ${NY}/2-($ORGY/$QY)" | bc -l`

 DETECTOR_DISTANCE=`grep "0 0 ? ? ?" tmp2 | awk '/DX /{print $2}'`

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

# test whether the absolute value of deltaphi is > absolute value of deltaomega
 if (( $(echo "${DELTAPHI}^2 > ${DELTAOMEGA}^2"|bc -l) )); then
    echo PHI scan
    R3=`echo "scale=7; s($KAPPA/$DEGTOR)*s($OMEGA/$DEGTOR)" | bc -l`
    R1=`echo "scale=7; s($KAPPA/$DEGTOR)*c($OMEGA/$DEGTOR)" | bc -l`
    R2=`echo "scale=7; c($KAPPA/$DEGTOR)         	  " | bc -l`
    ROTATION_AXIS="$R1 $R2 $R3"
    OSCILLATION_RANGE=${DELTAPHI}
    STARTING_ANGLE=${PHI}
# here we could check if DELTAPHI is <0, and if so, negate it and ROTATION_AXIS
 else
    echo OMEGA scan
    ROTATION_AXIS="0 -1 0"
    OSCILLATION_RANGE=${DELTAOMEGA}
    STARTING_ANGLE=${OMEGA}
# here we could check if DELTAOMEGA is <0, and if so, negate it and ROTATION_AXIS
 fi

# 2theta
  TWOTHETA=`awk '/TWOTHETA \? \? \?/{print $5;exit}' tmp2`
  echo TWOTHETA=$TWOTHETA
  R1=`echo "scale=7; c($TWOTHETA/$DEGTOR)" | bc -l`
  R3=`echo "scale=7; s($TWOTHETA/$DEGTOR)" | bc -l`
  DIRECTION_OF_DETECTOR_X_AXIS="$R1 0 $R3"
# end of Bruker-cbf section
else
  echo should never come here
  exit 1
fi

echo ORGX= $ORGX ORGY= $ORGY - check these values with adxv or xdsgui !
echo DETECTOR_DISTANCE= $DETECTOR_DISTANCE  ! only read by XYCORR, IDXREF
echo STARTING_ANGLE= $STARTING_ANGLE        ! only read by IDXREF
echo OSCILLATION_RANGE= $OSCILLATION_RANGE  ! only read by IDXREF
echo X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH    ! only read by IDXREF
if (( $(echo "$X_RAY_WAVELENGTH > 1.54 && $X_RAY_WAVELENGTH < 1.55" |bc -l) )); then
  echo "Copper K-alpha source, FRACTION_OF_POLARIZATION commented out"
  not_synchrotron='!'
fi

if [ "$DET" == "eiger" ] && [ "$is_h5" == 1 ]; then
  if [ "$DLS" == 0 ] ; then
    neggia_path=${NEGGIA_PATH-/usr/local/lib64/dectris-neggia.so}
    if [ -e $neggia_path ]; then
      LIB="LIB=$neggia_path"
      echo "LIB= <dectris-neggia> was written to XDS.INP . Check the path! For Apple M1 processors, modify the name or set \$NEGGIA_PATH."
    else
      LIB="!LIB=/usr/local/lib64/dectris-neggia.so"
      echo "dectris-neggia.so not found. Specify LIB=<path-to-dectris-neggia> in XDS.INP -- set \$NEGGIA_PATH to specify the path!"
    fi
  else
    durin_path=${DURIN_PATH-/usr/local/lib64/durin-plugin.so}
    if [ -e $durin_path ]; then
      LIB="LIB=$durin_path"
      echo "LIB= <durin-plugin> was written to XDS.INP . Check the path! For Apple M1 processors, modify the name or set \$DURIN_PATH."
    else
      LIB="!LIB=/usr/local/lib64/durin-plugin.so"
      echo "durin-plugin.so not found. Specify LIB=<path-to-durin-plugin> in XDS.INP -- set \$DURIN_PATH to specify the path!"
    fi
  fi
fi
if [ "$ROTATION_AXIS" != "" ]; then
  ROTATION_AXIS="$ROTATION_AXIS  ! only read by IDXREF"
elif [ "$REVERSE_PHI" == "no" ]; then
  ROTATION_AXIS='1 0 0  ! Australian Synchrotron, SERCAT ID-22 (?), APS 19-ID (?), ESRF BM30A, SPring-8, SSRF need -1 0 0. Diamond ID24 needs 0 -1 0'
else
  ROTATION_AXIS='-1 0 0  ! Default; if this is wrong, please contact author.'
fi

# Append 2-theta comment if defined
if (( $(echo "${TWOTHETA}0 != 0"|bc -l) )); then
  COMMENT_ORGXY="$COMMENT_ORGXY
! TWOTHETA=$TWOTHETA -- information only, do not uncomment. If indexing fails, check DIRECTION_OF_DETECTOR_X-AXIS"
fi

if [ "$DET" == "pilatus" -a "$NX" == "2463" -a "$NY" == "5071" ]; then
  SEGMENTED=1
fi

# now we know almost everything that is required to generate XDS.INP
# --------- Generate XDS.INP containing all defined parameters ----------
cat > XDS.INP << eof
!=============================================================================
! written by generate_XDS.INP version $REVISION
! For more details on XDS parameters, please check the online documentation at
!   http://xds.mr.mpg.de/html_doc/xds_parameters.html
!
! Full documentation, including complete detector templates, at xds.mr.mpg.de .
! More documentation in wiki.uni-konstanz.de/xds/index.php .
! After running xds, inspect at least the agreement of predicted and observed
! spots in FRAME.cbf (or SHOW_HKL.cbf in versions since BUILT=20240723)!
!=============================================================================
JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT
ORGX= $ORGX ORGY= $ORGY  ! values from frame header; only read by XYCORR, IDXREF
$COMMENT_ORGXY
DETECTOR_DISTANCE= $DETECTOR_DISTANCE !read by XYCORR, IDXREF. Negative if detector normal points to crystal.
OSCILLATION_RANGE= $OSCILLATION_RANGE
STARTING_ANGLE= $STARTING_ANGLE
X-RAY_WAVELENGTH= $X_RAY_WAVELENGTH
NAME_TEMPLATE_OF_DATA_FRAMES=$NAME_TEMPLATE_OF_DATA_FRAMES
! REFERENCE_DATA_SET=xxx/XDS_ASCII.HKL ! e.g. to ensure consistent indexing
DATA_RANGE=$DATA_RANGE
SPOT_RANGE=$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
! IDXREF now obeys INCLUDE_RESOLUTION_RANGE and EXCLUDE_RESOLUTION_RANGE to exclude ice-rings

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
!
! exclude (mask) untrusted areas of detector, e.g. beamstop shadow :
! UNTRUSTED_RECTANGLE= 1800 1950 2100 2150 ! x-min x-max y-min y-max ! repeat
! UNTRUSTED_ELLIPSE= 2034 2070 1850 2240 ! x-min x-max y-min y-max ! if needed
! UNTRUSTED_QUADRILATERAL= x1 y1 x2 y2 x3 y3 x4 y4 ! see documentation
!
! parameters with changes wrt default values:
TRUSTED_REGION=$TRUSTED_REGION
VALUE_RANGE_FOR_TRUSTED_DETECTOR_PIXELS=6000. 30000. ! often 7000 or 8000 is ok
!STRONG_PIXEL=4  ! COLSPOT: only use strong reflections (default is 3). For XDS versions before mid-2024.
MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=$MNOPIAS ! default of 6 is sometimes too high
! close spots/long cell axis: reduce SEPMIN and CLUSTER_RADIUS from their defaults of 7 and 3.5
SEPMIN=$SEPMIN  CLUSTER_RADIUS=$CLUSTER_RADIUS ! 4 and 2 for Pixel Array Detectors
! since XDS 01-MAR-2015, POSITION supersedes DISTANCE.
! nowadays headers are usually correct so refine POSITION in INTEGRATE but not IDXREF if low to medium resolution
! however, if the spots from COLSPOT extend to 2A then POSITION could, and if 1.5A POSITION should be refined
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 (unless electron diffraction)
REFINE(CORRECT)= $REFINE_CORRECT
! parameters specifically for this detector and beamline:
DETECTOR= $DETECTOR
SENSOR_THICKNESS= $SENSOR_THICKNESS
! 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).
! Better: read the article http://wiki.uni-konstanz.de/xds/index.php/SILICON .
NX= $NX NY= $NY  QX= $QX  QY= $QY ! to make CORRECT happy if frames are unavailable
$LIB
ROTATION_AXIS=$ROTATION_AXIS
DIRECTION_OF_DETECTOR_X-AXIS=$DIRECTION_OF_DETECTOR_X_AXIS
DIRECTION_OF_DETECTOR_Y-AXIS=$DIRECTION_OF_DETECTOR_Y_AXIS
INCIDENT_BEAM_DIRECTION=0 0 1   ! only read by IDXREF
${not_synchrotron}FRACTION_OF_POLARIZATION=${pol_frac}   ! comment out if not synchrotron; only use by CORRECT
                                       ! better value is provided by beamline staff!
POLARIZATION_PLANE_NORMAL=$POLARIZATION_PLANE_NORMAL        ! only used by CORRECT
eof

# --------- Append known detector untrusted regions -----------
cat >> XDS.INP << eof
!used by DEFPIX and CORRECT to exclude ice-reflections / ice rings - uncomment if necessary
!fine-grained list is in Thorn et al http://journals.iucr.org/d/issues/2017/09/00/hi5647/index.html
!EXCLUDE_RESOLUTION_RANGE= 3.93 3.87 !ice-ring at 3.897 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 3.70 3.64 !ice-ring at 3.669 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 3.47 3.41 !ice-ring at 3.441 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 2.70 2.64 !ice-ring at 2.671 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 2.28 2.22 !ice-ring at 2.249 Angstrom
!EXCLUDE_RESOLUTION_RANGE= 2.102 2.042 !ice-ring at 2.072 Angstrom - strong
!EXCLUDE_RESOLUTION_RANGE= 1.978 1.918 !ice-ring at 1.948 Angstrom - weak
!EXCLUDE_RESOLUTION_RANGE= 1.948 1.888 !ice-ring at 1.918 Angstrom - strong
!EXCLUDE_RESOLUTION_RANGE= 1.913 1.853 !ice-ring at 1.883 Angstrom - weak
!EXCLUDE_RESOLUTION_RANGE= 1.751 1.691 !ice-ring at 1.721 Angstrom - weak
! additional ice-ring resolution ranges: 1.524 1.519, 1.473 1.470, 1.444 1.440, 1.372 1.368, 1.367 1.363,
! 1.299 1.296, 1.275 1.274, 1.261 1.259, 1.224 1.222, 1.171 1.168, 1.124 1.122 (compiled by GlobalPhasing)

eof
# --------- Append additional detector-specific parameters ----------
if [ "$DET" == "Bruker-cbf" ]; then
  echo "DELPHI=15 ! refine less often than the default of 5" >> XDS.INP
elif [ "$DET" == "adsc-CMOS1" ]; then
  echo UNTRUSTED_RECTANGLE= 0 1468  2451 2631  >> XDS.INP
elif [ "$dtrek_det" == "pilatus" -a "$NX" == 487 -a "$NY" = "407" ]; then
  echo UNTRUSTED_RECTANGLE= 1 487 196 212 >> XDS.INP # Dectris Pilatus 200K
elif [ "$DET" == "pilatus" -o "$DET" == "eiger" ]; then
cat >> XDS.INP << eof
NUMBER_OF_PROFILE_GRID_POINTS_ALONG_ALPHA/BETA=13 ! Default is 9 - Increasing may improve data
NUMBER_OF_PROFILE_GRID_POINTS_ALONG_GAMMA=13      ! accuracy, particularly if finely-sliced on phi,
!                                                   and does not seem to have any downsides.
eof
# -------- Append known detector untrusted regions ------------------
  if [ "$NX" == "1028"  -a "$NY" == "1062" ]; then
# Eiger2 1M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
UNTRUSTED_RECTANGLE=    0 1029    512  551
eof
  elif [ "$NX" == "1475" ]; then
    if ! grep -q Flat_field tmp2 ; then
    cat >> XDS.INP << eof
! the following specifications are for a detector _without_ proper
! flat_field correction; they mask one additional pixel adjacent
! to each UNTRUSTED_RECTANGLE
!EXCLUSION OF VERTICAL DEAD AREAS OF THE PILATUS 2M DETECTOR
UNTRUSTED_RECTANGLE= 486  496     0 1680
UNTRUSTED_RECTANGLE= 980  990     0 1680
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE PILATUS 2M DETECTOR
UNTRUSTED_RECTANGLE=   0 1476   194  214
UNTRUSTED_RECTANGLE=   0 1476   406  426
UNTRUSTED_RECTANGLE=   0 1476   618  638
UNTRUSTED_RECTANGLE=   0 1476   830  850
UNTRUSTED_RECTANGLE=   0 1476  1042 1062
UNTRUSTED_RECTANGLE=   0 1476  1254 1274
UNTRUSTED_RECTANGLE=   0 1476  1466 1486
eof
    else
    cat >> XDS.INP << eof
!EXCLUSION OF VERTICAL DEAD AREAS OF THE PILATUS 2M DETECTOR
UNTRUSTED_RECTANGLE= 487  495     0 1680
UNTRUSTED_RECTANGLE= 981  989     0 1680
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE PILATUS 2M DETECTOR
UNTRUSTED_RECTANGLE=   0 1476   195  213
UNTRUSTED_RECTANGLE=   0 1476   407  425
UNTRUSTED_RECTANGLE=   0 1476   619  637
UNTRUSTED_RECTANGLE=   0 1476   831  849
UNTRUSTED_RECTANGLE=   0 1476  1043 1061
UNTRUSTED_RECTANGLE=   0 1476  1255 1273
UNTRUSTED_RECTANGLE=   0 1476  1467 1485
eof
    fi
  elif [ "$NX" == "2068"  -a "$NY" == "2162" ]; then
# Eiger2 4M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER2 4M DETECTOR
 UNTRUSTED_RECTANGLE= 1028 1041      0 2163
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER 4M DETECTOR
 UNTRUSTED_RECTANGLE=    0 2069    512  551
 UNTRUSTED_RECTANGLE=    0 2069   1062 1101
 UNTRUSTED_RECTANGLE=    0 2069   1612 1651
eof
  elif [ "$NX" == "2463" -a "$NY" == "2527" ]; then
# Pilatus 6M
# FIXME: here we could test if a Flat_field correction was applied like we do for 2M
    cat >> XDS.INP << eof
UNTRUSTED_RECTANGLE= 487  495     0 2528
UNTRUSTED_RECTANGLE= 981  989     0 2528
UNTRUSTED_RECTANGLE=1475 1483     0 2528
UNTRUSTED_RECTANGLE=1969 1977     0 2528
UNTRUSTED_RECTANGLE=   0 2464   195  213
UNTRUSTED_RECTANGLE=   0 2464   407  425
UNTRUSTED_RECTANGLE=   0 2464   619  637
UNTRUSTED_RECTANGLE=   0 2464   831  849
UNTRUSTED_RECTANGLE=   0 2464  1043 1061
UNTRUSTED_RECTANGLE=   0 2464  1255 1273
UNTRUSTED_RECTANGLE=   0 2464  1467 1485
UNTRUSTED_RECTANGLE=   0 2464  1679 1697
UNTRUSTED_RECTANGLE=   0 2464  1891 1909
UNTRUSTED_RECTANGLE=   0 2464  2103 2121
UNTRUSTED_RECTANGLE=   0 2464  2315 2333
eof
  elif [ "$NX" == "3110"  -a "$NY" == "3269" ]; then
# Eiger 9M
    cat >> XDS.INP << eof
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER 9M DETECTOR
UNTRUSTED_RECTANGLE= 1029 1042 0 3269
UNTRUSTED_RECTANGLE= 2069 2082 0 3269
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER 9M DETECTOR
UNTRUSTED_RECTANGLE= 0 3110  513  553
UNTRUSTED_RECTANGLE= 0 3110 1064 1104
UNTRUSTED_RECTANGLE= 0 3110 1615 1655
UNTRUSTED_RECTANGLE= 0 3110 2166 2206
UNTRUSTED_RECTANGLE= 0 3110 2717 2757
eof
  elif [ "$NX" == "3108"  -a "$NY" == "3262" ]; then
# Eiger2 9M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER2 9M DETECTOR
UNTRUSTED_RECTANGLE= 1028 1041      0 3262
UNTRUSTED_RECTANGLE= 2068 2081      0 3263
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER2 9M DETECTOR
UNTRUSTED_RECTANGLE=    0 3109    512  551
UNTRUSTED_RECTANGLE=    0 3109   1062 1101
UNTRUSTED_RECTANGLE=    0 3109   1612 1651
UNTRUSTED_RECTANGLE=    0 3109   2162 2201
UNTRUSTED_RECTANGLE=    0 3109   2712 2751
eof
  elif [ "$NX" == "4150" -a "$NY" == "4371" ]; then
# Eiger 16M
    cat >> XDS.INP << eof
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER 16M DETECTOR + ONE PIXEL ON EACH SIDE
 UNTRUSTED_RECTANGLE=    0 4150    513  553
 UNTRUSTED_RECTANGLE=    0 4150   1064 1104
 UNTRUSTED_RECTANGLE=    0 4150   1615 1655
 UNTRUSTED_RECTANGLE=    0 4150   2166 2206
 UNTRUSTED_RECTANGLE=    0 4150   2717 2757
 UNTRUSTED_RECTANGLE=    0 4150   3268 3308
 UNTRUSTED_RECTANGLE=    0 4150   3819 3859
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER 16M DETECTOR + ONE PIXEL ON EACH SIDE
 UNTRUSTED_RECTANGLE= 1029 1042      0 4371
 UNTRUSTED_RECTANGLE= 2069 2082      0 4371
 UNTRUSTED_RECTANGLE= 3109 3122      0 4371
eof
  elif [ "$NX" == "4148" -a "$NY" == "4362" ]; then
# Eiger2 16M ; v0.97 numbers from Andreas Förster
    cat >> XDS.INP << eof
!EXCLUSION OF HORIZONTAL DEAD AREAS OF THE EIGER2 16M DETECTOR
 UNTRUSTED_RECTANGLE= 1028 1041      0 4363
 UNTRUSTED_RECTANGLE= 2068 2081      0 4363
 UNTRUSTED_RECTANGLE= 3108 3121      0 4363
!EXCLUSION OF VERTICAL DEAD AREAS OF THE EIGER2 16M DETECTOR
 UNTRUSTED_RECTANGLE=    0 4149    512  551
 UNTRUSTED_RECTANGLE=    0 4149   1062 1101
 UNTRUSTED_RECTANGLE=    0 4149   1612 1651
 UNTRUSTED_RECTANGLE=    0 4149   2162 2201
 UNTRUSTED_RECTANGLE=    0 4149   2712 2751
 UNTRUSTED_RECTANGLE=    0 4149   3262 3301
 UNTRUSTED_RECTANGLE=    0 4149   3812 3851
eof
  elif [ "$NX" == "2463" -a "$NY" == "5071" ]; then
    : # handled above, before writing XDS.INP, untrusted regions come from site file
  else
    echo "**** WARNING ****"
    echo "Unknown Pilatus or Eiger detector, add UNTRUSTED regions and SEGMENT information manually"
  fi
fi
# Mechanism to append detector-specific parameters without editing this file:
# NOTE: some detectors don't set DET_SN so this is not always unique
# If the detector name is present in $DET_SN, then use only $DET_SN
if [ "$DET_SN" != "" ]; then
  echo "$DET_SN" | grep -qi "$DET" && DET="$DET_SN" || DET="${DET}_$DET_SN"
fi
DET=$(echo $DET | sed 's/ /_/g;s/[^-_A-Za-z0-9]//g;')
site_file="$HOME/.xds-site/$DET"
if [ -f $site_file ]; then
  echo Appending site parameters from: $site_file
  echo "! Parameters from $site_file" >> XDS.INP
  echo "Site parameters:"
  cat $site_file | head -20
  [ $(wc -l $site_file | awk '{print $1}') -gt 20 ] && echo "... (truncated)"
  echo
  # Only FRACTION_POLARIZATION and ROTATION_AXIS are commented out automatically because they
  # are the most likely to not match defaults.
  # For segmented detectors, also allow origin and distance to be replaced
  # Also likely adjustments are UNTRUSTED regions and maybe SILICON, but those don't replace existing parameters
  # Create a pattern like "XX\|YY" to search overriden parameters.
  REDEF_TOKENS="POLARIZATION\|ROTATION_AXIS\|TRUSTED_REGION"
  [ "$SEGMENTED" != "" ] && REDEF_TOKENS=$REDEF_TOKENS"\|ORGX\|ORGY\|DETECTOR_DISTANCE\|"
  pattern=$(grep "$REDEF_TOKENS" $site_file | grep -v SEGMENT | uniq | awk 'match($0,/^ *(\w+) *=/,a){x=x"\\|"a[1];}END{print substr(x,3);}')
  if [ "$pattern" != "" -a $(grep "^!! *\($pattern\)" XDS.INP) != ""]; then
      sed 's/\(^ *\('$pattern'\) *=\)/!!!\1/;' XDS.INP >tmp1
      echo "Overridden parameters:"
      grep "^ *\($pattern\)" XDS.INP
      echo
      mv tmp1 XDS.INP
  fi
  cat $site_file >> XDS.INP
else
  if [ "$SEGMENTED" != "" ]; then
    echo "**** Multi-SEGMENTed detector, site file is mandatory ****"
  fi
  echo "Detector specific parameters can be placed in: $site_file"
  echo "! Detector specific parameters can be placed in:" >> XDS.INP
  echo "!     $site_file" >> XDS.INP
  echo "! FRACTION_OF_POLARIZATION, ROTATION_AXIS and TRUSTED_REGION will auto-comment the replaced parameters" >> XDS.INP
  echo "! If the site file defines SEGMENTs then ORGX, ORGY, and DISTANCE may be overridden" >> XDS.INP
fi
echo XDS.INP is ready for use. The file has only the most important keywords.
echo Full documentation, including complete detector templates, at xds.mr.mpg.de .
echo More documentation in wiki.uni-konstanz.de/xds/index.php .
echo After running xds, inspect at least the agreement of predicted and observed
echo "spots in FRAME.cbf (or SHOW_HKL.cbf in versions since BUILT=20240723)!"
rm -f tmp1 tmp2
# end of generate_XDS.INP

System-wide or personal installation

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 specify the environment variables NEGGIA_PATH or DURIN_PATH, to point to the correct path on your system of the Dectris' Neggia library, or the Durin plugin, respectively. This relieves users from having to change the LIB= line of XDS.INP 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 (or better, into your ~/bin directory if that is in your $PATH); the filename should be generate_XDS.INP. After creating the file, make it executable - e.g. if it's in your $HOME, use:

chmod +x ~/generate_XDS.INP

After that, you can just run it in a similar way as if it were installed in your $PATH:

~/generate_XDS.INP "frms/mydata_1_???.img"

By using your own file, you can easily update to the latest revision, or even change the script, without having to bother the system administrator.

See also Generate_XDS.INP#Dependencies below, and the Installation article.

Copying generate_XDS.INP from XDSwiki webserver

On Linux:

wget https://wiki.uni-konstanz.de/pub/linux_bin/generate_XDS.INP
chmod a+x generate_XDS.INP

On Mac:

curl -o generate_XDS.INP https://wiki.uni-konstanz.de/pub/linux_bin/generate_XDS.INP
chmod a+x generate_XDS.INP

See also Installation.

Obtaining generate_XDS.INP from this webpage

Instead of cutting-and-pasting the lines of the script, you (or the system administrator) could just cut-and-paste the following four lines

 wget http://wiki.uni-konstanz.de/xds/index.php/generate_XDS.INP -O - | \
   sed -e s/\&nbsp\;/\ /g -e s/\&gt\;/\>/g -e s/\&lt\;/\</g -e s/amp\;//g -e s/\&quot\;/\"/g -e s/\&\#\1\6\0\;/\ /g | \
   sed '/# end of generate_XDS.INP/,$d' | sed -n '/#!\/bin\/bash/,/# end of generate_XDS.INP/p' > generate_XDS.INP
 chmod +x generate_XDS.INP

to copy the script from this website into an executable file generate_XDS.INP in your current directory. On a Mac (which does not seem to have wget), one could try

 curl -L -o - http://wiki.uni-konstanz.de/xds/index.php/generate_XDS.INP | \
   sed -e s/\&nbsp\;/\ /g -e s/\&gt\;/\>/g -e s/\&lt\;/\</g -e s/amp\;//g -e s/\&quot\;/\"/g -e s/\&\#\1\6\0\;/\ /g | \
   sed '/# end of generate_XDS.INP/,$d' | sed -n '/#!\/bin\/bash/,/# end of generate_XDS.INP/p' > generate_XDS.INP
 chmod +x generate_XDS.INP

If you use TextEdit on a Mac to cut-and-paste from this webpage, be aware of the following problem report: After loading frames, by clicking “generate XDS.INP”, the program shows some strange symbol “” in XDS.INP. And the more you click “save” button, the more “” appear. This looks like e.g.
SPACE_GROUP_NUMBER=0  ! 0 if unknown
UNIT_CELL_CONSTANTS= 70 80 90 90 90 90 Â
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.

Calling generate_XDS.INP from a Python script

It is recommended to use the subprocess.Popen() module instead of os.system():

 subprocess.Popen(["generate_XDS.INP",imagepath],stdout=outputfile)

where imagepath is a string containing the path to an image and outputfile is either a chosen variable for an output file or subprocess.PIPE if you're not interested in the output of the script.

The module os.system() internally uses /bin/sh to execute the command and overrides #!/bin/bash at the beginning of the script. While this is not a problem on most operating systems, /bin/sh points to dash instead of bash on Ubuntu, which leads to a program crash with the error message

 sh: 1: Syntax error: Bad fd number

Dependencies

The script makes use of many GNU commands, like ls, grep, egrep, awk, cut, cat, echo, wc, bc, head, sed, tail, cp, od, python. Some of them (like od and python) are only used in case of specific detectors (MarCCD and RAXIS, respectively). The script will only work if all the required commands are available. They reside in either the coreutils package, or specific packages (gawk, sed, bc, grep, python ...). Please note that to get the strings command on some Linux distributions, you need to install the binutils package. For Eiger data processing, the h5dump program must be installed. This is part of hdf5-tools (Ubuntu) or hdf5 (RHEL). The .h5 files collected at Diamond Light Source require at least version 1.10 of h5dump to extract the OVERLOAD parameter from the .h5 file; this version is available in newer Linux distributions but not in RHEL/CentOS 7.

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 xcode-select --install). These are also part of the (larger, but also free) Xcode package. This package comes with a license that has to be accepted by the user when running a Command Line Tool (e.g. strings) for the first time.

One way to check for missing programs is

#!/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)

yum -y install coreutils binutils gawk sed bc grep python hdf5

and for Ubuntu this would be (untested!)

sudo apt-get install coreutils binutils gawk sed bc grep python hdf5-tools

See also Installation.

Site Files

Site files may be used to add or modify parameters for specific hardware configurations. The primary use is for SEGMENT definitions of multi-segment detectors, and may also override FRACTION_OF_POLARIZATION, ROTATION_AXIS, TRUSTED_REGION, or UNTRUSTED_* specific to a site configuration. The site file is named ~/.xds-site/<NAME>_<SN>. The exact name will be printed by generate_XDS.INP when it is executed.

Site file for PILATUS 12M-DLS detector for the I23 beamline at Diamond Light Source:

Expand code section below (i.e. click on blue [Expand] at the end of this line if there is no code visible)

!--------------------------------------------------------------
! XDS Site file for Pilatus12M
! Save as: ~/.xds-site/PILATUS_12M_SN_120-0100
! SEGMENT definitions translated to align frame header beam
! and distance, from segments refined against 20141016/germ8979
!
! generated by Juno Krahn
! National Institute of Environmental Health Sciences, NIH
!--------------------------------------------------------------
! SEGMENT 1
SEGMENT= 1 487 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00106  0.00008
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00023 -0.14270  0.98977
SEGMENT_ORGX=     4.83
SEGMENT_ORGY=   473.86
SEGMENT_DISTANCE=  -190.77
! SEGMENT 2
SEGMENT= 495 981 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00094  0.00014
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00027 -0.14289  0.98974
SEGMENT_ORGX=     4.81
SEGMENT_ORGY=   474.08
SEGMENT_DISTANCE=  -190.72
! SEGMENT 3
SEGMENT= 989 1475 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00011  0.00035
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00033 -0.14157  0.98993
SEGMENT_ORGX=     3.52
SEGMENT_ORGY=   472.75
SEGMENT_DISTANCE=  -190.67
! SEGMENT 4
SEGMENT= 1483 1969 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00027
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00030 -0.14316  0.98970
SEGMENT_ORGX=     3.49
SEGMENT_ORGY=   473.57
SEGMENT_DISTANCE=  -190.50
! SEGMENT 5
SEGMENT= 1977 2463 1 195
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00017 -0.00024
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00026 -0.14305  0.98972
SEGMENT_ORGX=     3.83
SEGMENT_ORGY=   473.58
SEGMENT_DISTANCE=  -190.59
! SEGMENT 6
SEGMENT= 1 487 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00051  0.00011
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00011  0.00238  1.00000
SEGMENT_ORGX=     3.82
SEGMENT_ORGY=   309.94
SEGMENT_DISTANCE=  -195.53
! SEGMENT 7
SEGMENT= 495 981 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00090 -0.00018
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00018  0.00238  1.00000
SEGMENT_ORGX=     4.48
SEGMENT_ORGY=   309.68
SEGMENT_DISTANCE=  -195.51
! SEGMENT 8
SEGMENT= 989 1475 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00046
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00046  0.00229  1.00000
SEGMENT_ORGX=     3.28
SEGMENT_ORGY=   309.29
SEGMENT_DISTANCE=  -195.33
! SEGMENT 9
SEGMENT= 1483 1969 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00020 -0.00009
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00009  0.00194  1.00000
SEGMENT_ORGX=     3.31
SEGMENT_ORGY=   310.20
SEGMENT_DISTANCE=  -195.29
! SEGMENT 10
SEGMENT= 1977 2463 213 407
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00028 -0.00048
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00048  0.00221  1.00000
SEGMENT_ORGX=     4.20
SEGMENT_ORGY=   309.13
SEGMENT_DISTANCE=  -195.44
! SEGMENT 11
SEGMENT= 1 487 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00021 -0.00034
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00036  0.14700  0.98914
SEGMENT_ORGX=     3.79
SEGMENT_ORGY=   146.46
SEGMENT_DISTANCE=  -190.86
! SEGMENT 12
SEGMENT= 495 981 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00098  0.00012
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00002  0.14705  0.98913
SEGMENT_ORGX=     5.09
SEGMENT_ORGY=   146.20
SEGMENT_DISTANCE=  -190.83
! SEGMENT 13
SEGMENT= 989 1475 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00034 -0.00060
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00065  0.14764  0.98904
SEGMENT_ORGX=     4.25
SEGMENT_ORGY=   144.79
SEGMENT_DISTANCE=  -190.74
! SEGMENT 14
SEGMENT= 1483 1969 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00016 -0.00074
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00076  0.14716  0.98911
SEGMENT_ORGX=     4.12
SEGMENT_ORGY=   145.21
SEGMENT_DISTANCE=  -190.69
! SEGMENT 15
SEGMENT= 1977 2463 425 619
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00055
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00051  0.14723  0.98910
SEGMENT_ORGX=     3.95
SEGMENT_ORGY=   145.25
SEGMENT_DISTANCE=  -190.55
! SEGMENT 16
SEGMENT= 1 487 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007  0.00022
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00019  0.28893  0.95735
SEGMENT_ORGX=     3.45
SEGMENT_ORGY=    -9.50
SEGMENT_DISTANCE=  -176.83
! SEGMENT 17
SEGMENT= 495 981 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00070 -0.00020
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00039  0.28888  0.95736
SEGMENT_ORGX=     4.70
SEGMENT_ORGY=    -9.69
SEGMENT_DISTANCE=  -176.81
! SEGMENT 18
SEGMENT= 989 1475 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00084 -0.00061
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00083  0.28961  0.95715
SEGMENT_ORGX=     5.18
SEGMENT_ORGY=   -11.24
SEGMENT_DISTANCE=  -176.77
! SEGMENT 19
SEGMENT= 1483 1969 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00004 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00055  0.28951  0.95718
SEGMENT_ORGX=     4.22
SEGMENT_ORGY=   -10.88
SEGMENT_DISTANCE=  -176.50
! SEGMENT 20
SEGMENT= 1977 2463 637 831
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00004 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00058  0.28889  0.95736
SEGMENT_ORGX=     4.18
SEGMENT_ORGY=   -10.47
SEGMENT_DISTANCE=  -176.63
! SEGMENT 21
SEGMENT= 1 487 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00014  0.00006
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00001  0.42489  0.90524
SEGMENT_ORGX=     3.87
SEGMENT_ORGY=  -149.76
SEGMENT_DISTANCE=  -153.74
! SEGMENT 22
SEGMENT= 495 981 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00076  0.00043
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00007  0.42509  0.90515
SEGMENT_ORGX=     5.02
SEGMENT_ORGY=  -149.85
SEGMENT_DISTANCE=  -153.68
! SEGMENT 23
SEGMENT= 989 1475 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00042 -0.00107
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00115  0.42569  0.90487
SEGMENT_ORGX=     5.25
SEGMENT_ORGY=  -152.03
SEGMENT_DISTANCE=  -153.46
! SEGMENT 24
SEGMENT= 1483 1969 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00011 -0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00041  0.42530  0.90505
SEGMENT_ORGX=     4.09
SEGMENT_ORGY=  -150.92
SEGMENT_DISTANCE=  -153.42
! SEGMENT 25
SEGMENT= 1977 2463 849 1043
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00061 -0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00019  0.42520  0.90510
SEGMENT_ORGX=     3.67
SEGMENT_ORGY=  -150.36
SEGMENT_DISTANCE=  -153.14
! SEGMENT 26
SEGMENT= 1 487 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00024 -0.00062
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00065  0.55176  0.83400
SEGMENT_ORGX=     4.50
SEGMENT_ORGY=  -267.14
SEGMENT_DISTANCE=  -122.15
! SEGMENT 27
SEGMENT= 495 981 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00104  0.00037
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00026  0.55182  0.83396
SEGMENT_ORGX=     5.05
SEGMENT_ORGY=  -267.36
SEGMENT_DISTANCE=  -122.12
! SEGMENT 28
SEGMENT= 989 1475 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00016 -0.00047
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00048  0.55207  0.83380
SEGMENT_ORGX=     4.55
SEGMENT_ORGY=  -267.71
SEGMENT_DISTANCE=  -121.94
! SEGMENT 29
SEGMENT= 1483 1969 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00003 -0.00099
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00084  0.55221  0.83371
SEGMENT_ORGX=     5.02
SEGMENT_ORGY=  -268.34
SEGMENT_DISTANCE=  -121.73
! SEGMENT 30
SEGMENT= 1977 2463 1061 1255
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00022 -0.00053
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00032  0.55182  0.83396
SEGMENT_ORGX=     3.99
SEGMENT_ORGY=  -267.40
SEGMENT_DISTANCE=  -121.75
! SEGMENT 31
SEGMENT= 1 487 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00015  0.00013
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00001  0.66732  0.74477
SEGMENT_ORGX=     4.14
SEGMENT_ORGY=  -354.22
SEGMENT_DISTANCE=   -82.50
! SEGMENT 32
SEGMENT= 495 981 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00063  0.00076
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00015  0.66760  0.74452
SEGMENT_ORGX=     4.31
SEGMENT_ORGY=  -354.30
SEGMENT_DISTANCE=   -82.42
! SEGMENT 33
SEGMENT= 989 1475 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00011 -0.00026
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00027  0.66758  0.74454
SEGMENT_ORGX=     4.54
SEGMENT_ORGY=  -354.50
SEGMENT_DISTANCE=   -82.31
! SEGMENT 34
SEGMENT= 1483 1969 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00046 -0.00045
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00003  0.66738  0.74472
SEGMENT_ORGX=     3.67
SEGMENT_ORGY=  -353.83
SEGMENT_DISTANCE=   -82.19
! SEGMENT 35
SEGMENT= 1977 2463 1273 1467
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00007 -0.00091
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00063  0.66809  0.74408
SEGMENT_ORGX=     4.46
SEGMENT_ORGY=  -355.74
SEGMENT_DISTANCE=   -81.76
! SEGMENT 36
SEGMENT= 1 487 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00016  0.00111
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00083  0.76825  0.64015
SEGMENT_ORGX=     2.59
SEGMENT_ORGY=  -404.52
SEGMENT_DISTANCE=   -35.97
! SEGMENT 37
SEGMENT= 495 981 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00094  0.00104
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00005  0.76800  0.64045
SEGMENT_ORGX=     4.62
SEGMENT_ORGY=  -404.40
SEGMENT_DISTANCE=   -36.21
! SEGMENT 38
SEGMENT= 989 1475 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049 -0.00114
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00111  0.76871  0.63959
SEGMENT_ORGX=     6.17
SEGMENT_ORGY=  -405.99
SEGMENT_DISTANCE=   -35.56
! SEGMENT 39
SEGMENT= 1483 1969 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00030 -0.00083
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00076  0.76828  0.64012
SEGMENT_ORGX=     5.36
SEGMENT_ORGY=  -405.83
SEGMENT_DISTANCE=   -35.75
! SEGMENT 40
SEGMENT= 1977 2463 1485 1679
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00033 -0.00084
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00028  0.76806  0.64038
SEGMENT_ORGX=     4.15
SEGMENT_ORGY=  -404.69
SEGMENT_DISTANCE=   -35.60
! SEGMENT 41
SEGMENT= 1 487 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00012  0.00028
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00004  0.85314  0.52169
SEGMENT_ORGX=     3.87
SEGMENT_ORGY=  -412.52
SEGMENT_DISTANCE=    16.72
! SEGMENT 42
SEGMENT= 495 981 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00052  0.00053
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.85309  0.52176
SEGMENT_ORGX=     4.44
SEGMENT_ORGY=  -412.64
SEGMENT_DISTANCE=    16.63
! SEGMENT 43
SEGMENT= 989 1475 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00025 -0.00126
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00045  0.85311  0.52173
SEGMENT_ORGX=     5.35
SEGMENT_ORGY=  -413.24
SEGMENT_DISTANCE=    16.97
! SEGMENT 44
SEGMENT= 1483 1969 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00092 -0.00086
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00033  0.85325  0.52150
SEGMENT_ORGX=     3.55
SEGMENT_ORGY=  -411.91
SEGMENT_DISTANCE=    17.21
! SEGMENT 45
SEGMENT= 1977 2463 1697 1891
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00008 -0.00113
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00052  0.85326  0.52149
SEGMENT_ORGX=     5.13
SEGMENT_ORGY=  -413.28
SEGMENT_DISTANCE=    17.35
! SEGMENT 46
SEGMENT= 1 487 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00028 -0.00004
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00028  0.92003  0.39185
SEGMENT_ORGX=     4.58
SEGMENT_ORGY=  -374.02
SEGMENT_DISTANCE=    74.51
! SEGMENT 47
SEGMENT= 495 981 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049  0.00109
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00002  0.91985  0.39227
SEGMENT_ORGX=     3.78
SEGMENT_ORGY=  -374.06
SEGMENT_DISTANCE=    74.25
! SEGMENT 48
SEGMENT= 989 1475 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00073 -0.00102
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00107  0.92009  0.39172
SEGMENT_ORGX=     6.81
SEGMENT_ORGY=  -374.77
SEGMENT_DISTANCE=    74.74
! SEGMENT 49
SEGMENT= 1483 1969 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00050 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00023  0.91986  0.39226
SEGMENT_ORGX=     3.55
SEGMENT_ORGY=  -373.25
SEGMENT_DISTANCE=    74.64
! SEGMENT 50
SEGMENT= 1977 2463 1909 2103
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00023 -0.00070
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00049  0.92007  0.39176
SEGMENT_ORGX=     5.78
SEGMENT_ORGY=  -374.22
SEGMENT_DISTANCE=    74.74
! SEGMENT 51
SEGMENT= 1 487 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00035  0.00033
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00025  0.96695  0.25495
SEGMENT_ORGX=     4.41
SEGMENT_ORGY=  -285.55
SEGMENT_DISTANCE=   135.47
! SEGMENT 52
SEGMENT= 495 981 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00057  0.00085
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00033  0.96701  0.25473
SEGMENT_ORGX=     4.25
SEGMENT_ORGY=  -285.70
SEGMENT_DISTANCE=   135.50
! SEGMENT 53
SEGMENT= 989 1475 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00024 -0.00056
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00038  0.96692  0.25510
SEGMENT_ORGX=     5.50
SEGMENT_ORGY=  -286.05
SEGMENT_DISTANCE=   135.50
! SEGMENT 54
SEGMENT= 1483 1969 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00038 -0.00100
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00062  0.96709  0.25444
SEGMENT_ORGX=     6.40
SEGMENT_ORGY=  -285.85
SEGMENT_DISTANCE=   135.99
! SEGMENT 55
SEGMENT= 1977 2463 2121 2315
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00036 -0.00067
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00052  0.96712  0.25433
SEGMENT_ORGX=     5.98
SEGMENT_ORGY=  -285.86
SEGMENT_DISTANCE=   135.96
! SEGMENT 56
SEGMENT= 1 487 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00051 -0.00020
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00053  0.99369  0.11217
SEGMENT_ORGX=     5.92
SEGMENT_ORGY=  -144.32
SEGMENT_DISTANCE=   199.07
! SEGMENT 57
SEGMENT= 495 981 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00033  0.00099
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00021  0.99374  0.11172
SEGMENT_ORGX=     3.79
SEGMENT_ORGY=  -143.69
SEGMENT_DISTANCE=   199.15
! SEGMENT 58
SEGMENT= 989 1475 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00067 -0.00123
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00080  0.99372  0.11190
SEGMENT_ORGX=     7.88
SEGMENT_ORGY=  -144.66
SEGMENT_DISTANCE=   199.42
! SEGMENT 59
SEGMENT= 1483 1969 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007 -0.00038
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00011  0.99374  0.11170
SEGMENT_ORGX=     5.18
SEGMENT_ORGY=  -143.35
SEGMENT_DISTANCE=   199.36
! SEGMENT 60
SEGMENT= 1977 2463 2333 2527
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00080 -0.00014
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00081  0.99380  0.11117
SEGMENT_ORGX=     6.82
SEGMENT_ORGY=  -144.43
SEGMENT_DISTANCE=   199.40
! SEGMENT 61
SEGMENT= 1 487 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00000  0.00000
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00000  0.99944 -0.03352
SEGMENT_ORGX=     4.09
SEGMENT_ORGY=    52.67
SEGMENT_DISTANCE=   263.82
! SEGMENT 62
SEGMENT= 495 981 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00015  0.00057
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.99942 -0.03399
SEGMENT_ORGX=     3.77
SEGMENT_ORGY=    53.04
SEGMENT_DISTANCE=   264.14
! SEGMENT 63
SEGMENT= 989 1475 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00005  0.00096
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00001  0.99941 -0.03430
SEGMENT_ORGX=     2.71
SEGMENT_ORGY=    53.88
SEGMENT_DISTANCE=   264.03
! SEGMENT 64
SEGMENT= 1483 1969 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00000  0.00000
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00000  0.99944 -0.03352
SEGMENT_ORGX=     4.09
SEGMENT_ORGY=    52.67
SEGMENT_DISTANCE=   263.82
! SEGMENT 65
SEGMENT= 1977 2463 2545 2739
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00000  0.00000
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00000  0.99944 -0.03352
SEGMENT_ORGX=     4.09
SEGMENT_ORGY=    52.67
SEGMENT_DISTANCE=   263.82
! SEGMENT 66
SEGMENT= 1 487 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049  0.00114
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00068  0.98402 -0.17805
SEGMENT_ORGX=     4.00
SEGMENT_ORGY=   303.18
SEGMENT_DISTANCE=   328.29
! SEGMENT 67
SEGMENT= 495 981 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00038  0.00066
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00049  0.98400 -0.17816
SEGMENT_ORGX=     4.55
SEGMENT_ORGY=   303.20
SEGMENT_DISTANCE=   328.34
! SEGMENT 68
SEGMENT= 989 1475 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00032 -0.00068
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00019  0.98391 -0.17866
SEGMENT_ORGX=     6.24
SEGMENT_ORGY=   304.40
SEGMENT_DISTANCE=   328.74
! SEGMENT 69
SEGMENT= 1483 1969 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00037 -0.00113
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00016  0.98397 -0.17834
SEGMENT_ORGX=     7.48
SEGMENT_ORGY=   303.70
SEGMENT_DISTANCE=   328.88
! SEGMENT 70
SEGMENT= 1977 2463 2757 2951
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00016 -0.00027
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00011  0.98399 -0.17824
SEGMENT_ORGX=     5.61
SEGMENT_ORGY=   303.71
SEGMENT_DISTANCE=   328.44
! SEGMENT 71
SEGMENT= 1 487 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00030 -0.00024
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00021  0.94770 -0.31916
SEGMENT_ORGX=     5.64
SEGMENT_ORGY=   608.83
SEGMENT_DISTANCE=   391.30
! SEGMENT 72
SEGMENT= 495 981 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00012  0.00040
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00024  0.94756 -0.31957
SEGMENT_ORGX=     4.12
SEGMENT_ORGY=   609.89
SEGMENT_DISTANCE=   391.43
! SEGMENT 73
SEGMENT= 989 1475 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00058 -0.00069
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00033  0.94764 -0.31935
SEGMENT_ORGX=     7.12
SEGMENT_ORGY=   609.07
SEGMENT_DISTANCE=   391.50
! SEGMENT 74
SEGMENT= 1483 1969 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00048 -0.00088
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.94769 -0.31918
SEGMENT_ORGX=     7.06
SEGMENT_ORGY=   608.83
SEGMENT_DISTANCE=   391.56
! SEGMENT 75
SEGMENT= 1977 2463 2969 3163
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00165 -0.00010
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00153  0.94753 -0.31967
SEGMENT_ORGX=     8.87
SEGMENT_ORGY=   606.87
SEGMENT_DISTANCE=   391.76
! SEGMENT 76
SEGMENT= 1 487 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00041 -0.00026
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00025  0.89152 -0.45299
SEGMENT_ORGX=     5.40
SEGMENT_ORGY=   964.61
SEGMENT_DISTANCE=   450.92
! SEGMENT 77
SEGMENT= 495 981 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00004  0.00066
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00026  0.89140 -0.45322
SEGMENT_ORGX=     3.47
SEGMENT_ORGY=   965.43
SEGMENT_DISTANCE=   450.97
! SEGMENT 78
SEGMENT= 989 1475 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007 -0.00097
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00038  0.89142 -0.45318
SEGMENT_ORGX=     5.83
SEGMENT_ORGY=   965.97
SEGMENT_DISTANCE=   451.19
! SEGMENT 79
SEGMENT= 1483 1969 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00042 -0.00120
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00017  0.89131 -0.45339
SEGMENT_ORGX=     7.27
SEGMENT_ORGY=   966.72
SEGMENT_DISTANCE=   451.51
! SEGMENT 80
SEGMENT= 1977 2463 3181 3375
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00012  0.00005
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00013  0.89154 -0.45293
SEGMENT_ORGX=     4.23
SEGMENT_ORGY=   964.23
SEGMENT_DISTANCE=   450.89
! SEGMENT 81
SEGMENT= 1 487 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00041  0.00034
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00053  0.81635 -0.57756
SEGMENT_ORGX=     4.73
SEGMENT_ORGY=  1370.46
SEGMENT_DISTANCE=   506.46
! SEGMENT 82
SEGMENT= 495 981 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00031 -0.00018
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00015  0.81619 -0.57779
SEGMENT_ORGX=     5.45
SEGMENT_ORGY=  1371.41
SEGMENT_DISTANCE=   506.67
! SEGMENT 83
SEGMENT= 989 1475 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00062 -0.00059
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.81642 -0.57746
SEGMENT_ORGX=     7.02
SEGMENT_ORGY=  1370.21
SEGMENT_DISTANCE=   506.58
! SEGMENT 84
SEGMENT= 1483 1969 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00070 -0.00071
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00016  0.81619 -0.57778
SEGMENT_ORGX=     7.44
SEGMENT_ORGY=  1371.37
SEGMENT_DISTANCE=   506.88
! SEGMENT 85
SEGMENT= 1977 2463 3393 3587
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00098 -0.00041
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00056  0.81610 -0.57791
SEGMENT_ORGX=     7.74
SEGMENT_ORGY=  1370.96
SEGMENT_DISTANCE=   507.00
! SEGMENT 86
SEGMENT= 1 487 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00117  0.00085
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00026  0.72365 -0.69017
SEGMENT_ORGX=    -0.95
SEGMENT_ORGY=  1822.59
SEGMENT_DISTANCE=   556.73
! SEGMENT 87
SEGMENT= 495 981 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00032  0.00058
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.72347 -0.69035
SEGMENT_ORGX=     1.93
SEGMENT_ORGY=  1823.31
SEGMENT_DISTANCE=   556.80
! SEGMENT 88
SEGMENT= 989 1475 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00037 -0.00043
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00003  0.72375 -0.69006
SEGMENT_ORGX=     5.71
SEGMENT_ORGY=  1822.09
SEGMENT_DISTANCE=   556.81
! SEGMENT 89
SEGMENT= 1483 1969 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00077 -0.00057
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00017  0.72366 -0.69016
SEGMENT_ORGX=     7.82
SEGMENT_ORGY=  1822.42
SEGMENT_DISTANCE=   557.04
! SEGMENT 90
SEGMENT= 1977 2463 3605 3799
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00064 -0.00079
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00008  0.72355 -0.69027
SEGMENT_ORGX=     7.16
SEGMENT_ORGY=  1823.19
SEGMENT_DISTANCE=   557.18
! SEGMENT 91
SEGMENT= 1 487 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00020  0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00052  0.61513 -0.78843
SEGMENT_ORGX=     4.08
SEGMENT_ORGY=  2316.53
SEGMENT_DISTANCE=   600.68
! SEGMENT 92
SEGMENT= 495 981 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00045  0.00073
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00030  0.61597 -0.78777
SEGMENT_ORGX=     1.75
SEGMENT_ORGY=  2312.82
SEGMENT_DISTANCE=   600.29
! SEGMENT 93
SEGMENT= 989 1475 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00007 -0.00044
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00030  0.61591 -0.78782
SEGMENT_ORGX=     4.50
SEGMENT_ORGY=  2313.65
SEGMENT_DISTANCE=   600.46
! SEGMENT 94
SEGMENT= 1483 1969 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00096  0.00050
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00099  0.61532 -0.78828
SEGMENT_ORGX=     7.42
SEGMENT_ORGY=  2314.13
SEGMENT_DISTANCE=   600.64
! SEGMENT 95
SEGMENT= 1977 2463 3817 4011
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00022 -0.00030
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00010  0.61556 -0.78809
SEGMENT_ORGX=     5.16
SEGMENT_ORGY=  2315.08
SEGMENT_DISTANCE=   600.62
! SEGMENT 96
SEGMENT= 1 487 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00053  0.00024
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00047  0.49448 -0.86919
SEGMENT_ORGX=     5.67
SEGMENT_ORGY=  2840.04
SEGMENT_DISTANCE=   636.75
! SEGMENT 97
SEGMENT= 495 981 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00022  0.00073
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00074  0.49423 -0.86933
SEGMENT_ORGX=     4.46
SEGMENT_ORGY=  2840.73
SEGMENT_DISTANCE=   636.83
! SEGMENT 98
SEGMENT= 989 1475 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00092 -0.00030
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00020  0.49510 -0.86884
SEGMENT_ORGX=     8.05
SEGMENT_ORGY=  2837.31
SEGMENT_DISTANCE=   636.77
! SEGMENT 99
SEGMENT= 1483 1969 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00018  0.00027
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00032  0.49433 -0.86928
SEGMENT_ORGX=     4.71
SEGMENT_ORGY=  2840.07
SEGMENT_DISTANCE=   636.77
! SEGMENT 100
SEGMENT= 1977 2463 4029 4223
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00091 -0.00047
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00004  0.49460 -0.86912
SEGMENT_ORGX=     8.26
SEGMENT_ORGY=  2839.42
SEGMENT_DISTANCE=   637.08
! SEGMENT 101
SEGMENT= 1 487 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00032  0.00022
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00032  0.36345 -0.93161
SEGMENT_ORGX=     5.33
SEGMENT_ORGY=  3390.42
SEGMENT_DISTANCE=   664.77
! SEGMENT 102
SEGMENT= 495 981 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00027  0.00044
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00031  0.36324 -0.93169
SEGMENT_ORGX=     2.96
SEGMENT_ORGY=  3391.32
SEGMENT_DISTANCE=   664.69
! SEGMENT 103
SEGMENT= 989 1475 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00101  0.00002
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00038  0.36357 -0.93157
SEGMENT_ORGX=     8.16
SEGMENT_ORGY=  3389.42
SEGMENT_DISTANCE=   664.85
! SEGMENT 104
SEGMENT= 1483 1969 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00059 -0.00019
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00003  0.36334 -0.93166
SEGMENT_ORGX=     6.56
SEGMENT_ORGY=  3390.71
SEGMENT_DISTANCE=   664.86
! SEGMENT 105
SEGMENT= 1977 2463 4241 4435
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00173 -0.00028
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00036  0.36352 -0.93159
SEGMENT_ORGX=    11.50
SEGMENT_ORGY=  3389.42
SEGMENT_DISTANCE=   665.23
! SEGMENT 106
SEGMENT= 1 487 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00058  0.00007
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00020  0.22382 -0.97463
SEGMENT_ORGX=     6.33
SEGMENT_ORGY=  3964.77
SEGMENT_DISTANCE=   684.01
! SEGMENT 107
SEGMENT= 495 981 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00071 -0.00041
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00055  0.22448 -0.97448
SEGMENT_ORGX=     1.76
SEGMENT_ORGY=  3962.92
SEGMENT_DISTANCE=   683.89
! SEGMENT 108
SEGMENT= 989 1475 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00065  0.00001
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00015  0.22437 -0.97450
SEGMENT_ORGX=     6.92
SEGMENT_ORGY=  3962.37
SEGMENT_DISTANCE=   684.06
! SEGMENT 109
SEGMENT= 1483 1969 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00073 -0.00120
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00101  0.22429 -0.97452
SEGMENT_ORGX=     7.71
SEGMENT_ORGY=  3964.48
SEGMENT_DISTANCE=   684.23
! SEGMENT 110
SEGMENT= 1977 2463 4453 4647
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00052 -0.00035
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00022  0.22472 -0.97442
SEGMENT_ORGX=     6.51
SEGMENT_ORGY=  3961.51
SEGMENT_DISTANCE=   684.03
! SEGMENT 111
SEGMENT= 1 487 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00029  0.00012
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00010  0.08035 -0.99677
SEGMENT_ORGX=     2.86
SEGMENT_ORGY=  4547.50
SEGMENT_DISTANCE=   693.99
! SEGMENT 112
SEGMENT= 495 981 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00088 -0.00026
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00033  0.08081 -0.99673
SEGMENT_ORGX=     0.34
SEGMENT_ORGY=  4546.02
SEGMENT_DISTANCE=   693.92
! SEGMENT 113
SEGMENT= 989 1475 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00118 -0.00039
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00029  0.07994 -0.99680
SEGMENT_ORGX=     8.96
SEGMENT_ORGY=  4549.58
SEGMENT_DISTANCE=   694.25
! SEGMENT 114
SEGMENT= 1483 1969 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00068  0.00041
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00047  0.07984 -0.99681
SEGMENT_ORGX=     6.59
SEGMENT_ORGY=  4548.65
SEGMENT_DISTANCE=   694.25
! SEGMENT 115
SEGMENT= 1977 2463 4665 4859
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00057 -0.00031
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00026  0.08104 -0.99671
SEGMENT_ORGX=     6.47
SEGMENT_ORGY=  4545.15
SEGMENT_DISTANCE=   694.14
! SEGMENT 116
SEGMENT= 1 487 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00100  0.00013
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00007 -0.06472 -0.99790
SEGMENT_ORGX=     7.84
SEGMENT_ORGY=  5134.69
SEGMENT_DISTANCE=   694.61
! SEGMENT 117
SEGMENT= 495 981 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00023 -0.00039
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00038 -0.06512 -0.99788
SEGMENT_ORGX=     2.94
SEGMENT_ORGY=  5136.66
SEGMENT_DISTANCE=   694.59
! SEGMENT 118
SEGMENT= 989 1475 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00054  0.00036
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00033 -0.06446 -0.99792
SEGMENT_ORGX=     6.18
SEGMENT_ORGY=  5133.17
SEGMENT_DISTANCE=   694.74
! SEGMENT 119
SEGMENT= 1483 1969 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000  0.00061 -0.00046
DIRECTION_OF_SEGMENT_Y-AXIS= -0.00041 -0.06543 -0.99786
SEGMENT_ORGX=     1.83
SEGMENT_ORGY=  5138.36
SEGMENT_DISTANCE=   694.32
! SEGMENT 120
SEGMENT= 1977 2463 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS=  1.00000 -0.00049  0.00007
DIRECTION_OF_SEGMENT_Y-AXIS=  0.00004 -0.06464 -0.99791
SEGMENT_ORGX=     6.44
SEGMENT_ORGY=  5134.23
SEGMENT_DISTANCE=   694.72

Limitations

  • 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 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 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 needs to 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. The frame headers do not have this information, but for some beamlines the correct value has been implemented in the script. For other beamlines, the default chosen by generate_XDS.INP may be wrong and need manual correction of XDS.INP. The correct choice can be enforced by you with a site file. Pls also see the article Beamline notes.
  • 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 certain 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 .

See also