diff options
Diffstat (limited to 'tests')
29 files changed, 1132 insertions, 591 deletions
diff --git a/tests/ev_enum1.geom b/tests/ev_enum1.geom index 9189727f..0afc500c 100644 --- a/tests/ev_enum1.geom +++ b/tests/ev_enum1.geom @@ -1,4 +1,5 @@ photon_energy = 10000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/dim0 = ss diff --git a/tests/ev_enum2.geom b/tests/ev_enum2.geom index ce0aeacc..c27fb49c 100644 --- a/tests/ev_enum2.geom +++ b/tests/ev_enum2.geom @@ -1,4 +1,5 @@ photon_energy = 10000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/dim0 = % diff --git a/tests/ev_enum3.geom b/tests/ev_enum3.geom index 3a83848e..2e08f383 100644 --- a/tests/ev_enum3.geom +++ b/tests/ev_enum3.geom @@ -1,4 +1,5 @@ photon_energy = 10000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/dim0 = ss diff --git a/tests/geom_roundtrip b/tests/geom_roundtrip new file mode 100755 index 00000000..6d205f06 --- /dev/null +++ b/tests/geom_roundtrip @@ -0,0 +1,645 @@ +#!/bin/sh + +ADJUST_DETECTOR=$1 + +cat > roundtrip.geom << EOF +photon_energy = /LCLS/photon_energy_eV eV +clen = /LCLS/detector_1/EncoderValue +bandwidth = 1.000000e-08 +coffset = 0.573224 +mask0_data = /entry_1/data_1/mask +mask0_goodbits = 0x0 +mask0_badbits = 0xffff +res = 9090.910000 +data = /entry_1/data_1/data +adu_per_eV = 0.003380 +dim0 = % +dim1 = ss +dim2 = fs + +q0a0/min_fs = 0 +q0a0/max_fs = 193 +q0a0/min_ss = 0 +q0a0/max_ss = 184 +q0a0/corner_x = 443.819000 +q0a0/corner_y = -49.871900 +q0a0/fs = 0.004806x +0.999989y +0.000000z +q0a0/ss = -0.999989x +0.004806y +0.000000z + +q0a1/min_fs = 194 +q0a1/max_fs = 387 +q0a1/min_ss = 0 +q0a1/max_ss = 184 +q0a1/corner_x = 444.766000 +q0a1/corner_y = 147.126000 +q0a1/fs = 0.004806x +0.999989y +0.000000z +q0a1/ss = -0.999989x +0.004806y +0.000000z + +q0a2/min_fs = 0 +q0a2/max_fs = 193 +q0a2/min_ss = 185 +q0a2/max_ss = 369 +q0a2/corner_x = 239.800000 +q0a2/corner_y = -49.350400 +q0a2/fs = 0.003265x +0.999995y +0.000000z +q0a2/ss = -0.999995x +0.003265y +0.000000z + +q0a3/min_fs = 194 +q0a3/max_fs = 387 +q0a3/min_ss = 185 +q0a3/max_ss = 369 +q0a3/corner_x = 240.444000 +q0a3/corner_y = 147.649000 +q0a3/fs = 0.003265x +0.999995y +0.000000z +q0a3/ss = -0.999995x +0.003265y +0.000000z + +q0a4/min_fs = 0 +q0a4/max_fs = 193 +q0a4/min_ss = 370 +q0a4/max_ss = 554 +q0a4/corner_x = 872.219000 +q0a4/corner_y = 342.054000 +q0a4/fs = -0.999997x +0.002424y +0.000000z +q0a4/ss = -0.002424x -0.999997y +0.000000z + +q0a5/min_fs = 194 +q0a5/max_fs = 387 +q0a5/min_ss = 370 +q0a5/max_ss = 554 +q0a5/corner_x = 675.220000 +q0a5/corner_y = 342.532000 +q0a5/fs = -0.999997x +0.002424y +0.000000z +q0a5/ss = -0.002424x -0.999997y +0.000000z + +q0a6/min_fs = 0 +q0a6/max_fs = 193 +q0a6/min_ss = 555 +q0a6/max_ss = 739 +q0a6/corner_x = 871.381000 +q0a6/corner_y = 135.836000 +q0a6/fs = -0.999997x +0.002685y +0.000000z +q0a6/ss = -0.002685x -0.999997y +0.000000z + +q0a7/min_fs = 194 +q0a7/max_fs = 387 +q0a7/min_ss = 555 +q0a7/max_ss = 739 +q0a7/corner_x = 674.382000 +q0a7/corner_y = 136.365000 +q0a7/fs = -0.999997x +0.002685y +0.000000z +q0a7/ss = -0.002685x -0.999997y +0.000000z + +q0a8/min_fs = 0 +q0a8/max_fs = 193 +q0a8/min_ss = 740 +q0a8/max_ss = 924 +q0a8/corner_x = 480.758000 +q0a8/corner_y = 769.640000 +q0a8/fs = -0.000078x -0.999999y +0.000000z +q0a8/ss = 0.999999x -0.000078y +0.000000z + +q0a9/min_fs = 194 +q0a9/max_fs = 387 +q0a9/min_ss = 740 +q0a9/max_ss = 924 +q0a9/corner_x = 480.743000 +q0a9/corner_y = 572.640000 +q0a9/fs = -0.000078x -0.999999y +0.000000z +q0a9/ss = 0.999999x -0.000078y +0.000000z + +q0a10/min_fs = 0 +q0a10/max_fs = 193 +q0a10/min_ss = 925 +q0a10/max_ss = 1109 +q0a10/corner_x = 689.447000 +q0a10/corner_y = 770.295000 +q0a10/fs = 0.001551x -0.999999y +0.000000z +q0a10/ss = 0.999999x +0.001551y +0.000000z + +q0a11/min_fs = 194 +q0a11/max_fs = 387 +q0a11/min_ss = 925 +q0a11/max_ss = 1109 +q0a11/corner_x = 689.752000 +q0a11/corner_y = 573.296000 +q0a11/fs = 0.001551x -0.999999y +0.000000z +q0a11/ss = 0.999999x +0.001551y +0.000000z + +q0a12/min_fs = 0 +q0a12/max_fs = 193 +q0a12/min_ss = 1110 +q0a12/max_ss = 1294 +q0a12/corner_x = 445.672000 +q0a12/corner_y = 751.701000 +q0a12/fs = -0.999998x -0.002161y +0.000000z +q0a12/ss = 0.002161x -0.999998y +0.000000z + +q0a13/min_fs = 194 +q0a13/max_fs = 387 +q0a13/min_ss = 1110 +q0a13/max_ss = 1294 +q0a13/corner_x = 248.672000 +q0a13/corner_y = 751.276000 +q0a13/fs = -0.999998x -0.002161y +0.000000z +q0a13/ss = 0.002161x -0.999998y +0.000000z + +q0a14/min_fs = 0 +q0a14/max_fs = 193 +q0a14/min_ss = 1295 +q0a14/max_ss = 1479 +q0a14/corner_x = 445.151000 +q0a14/corner_y = 541.081000 +q0a14/fs = -0.999999x -0.000074y +0.000000z +q0a14/ss = 0.000074x -0.999999y +0.000000z + +q0a15/min_fs = 194 +q0a15/max_fs = 387 +q0a15/min_ss = 1295 +q0a15/max_ss = 1479 +q0a15/corner_x = 248.151000 +q0a15/corner_y = 541.066000 +q0a15/fs = -0.999999x -0.000074y +0.000000z +q0a15/ss = 0.000074x -0.999999y +0.000000z + +q1a0/min_fs = 388 +q1a0/max_fs = 581 +q1a0/min_ss = 0 +q1a0/max_ss = 184 +q1a0/corner_x = 28.477600 +q1a0/corner_y = 436.830000 +q1a0/fs = -0.999990x -0.004167y +0.000000z +q1a0/ss = 0.004167x -0.999990y +0.000000z + +q1a1/min_fs = 582 +q1a1/max_fs = 775 +q1a1/min_ss = 0 +q1a1/max_ss = 184 +q1a1/corner_x = -168.520000 +q1a1/corner_y = 436.009000 +q1a1/fs = -0.999990x -0.004167y +0.000000z +q1a1/ss = 0.004167x -0.999990y +0.000000z + +q1a2/min_fs = 388 +q1a2/max_fs = 581 +q1a2/min_ss = 185 +q1a2/max_ss = 369 +q1a2/corner_x = 29.355900 +q1a2/corner_y = 226.978000 +q1a2/fs = -1.000001x +0.000385y +0.000000z +q1a2/ss = -0.000385x -1.000001y +0.000000z + +q1a3/min_fs = 582 +q1a3/max_fs = 775 +q1a3/min_ss = 185 +q1a3/max_ss = 369 +q1a3/corner_x = -167.644000 +q1a3/corner_y = 227.054000 +q1a3/fs = -1.000001x +0.000385y +0.000000z +q1a3/ss = -0.000385x -1.000001y +0.000000z + +q1a4/min_fs = 388 +q1a4/max_fs = 581 +q1a4/min_ss = 370 +q1a4/max_ss = 554 +q1a4/corner_x = -364.144000 +q1a4/corner_y = 859.163000 +q1a4/fs = 0.000539x -1.000000y +0.000000z +q1a4/ss = 1.000000x +0.000539y +0.000000z + +q1a5/min_fs = 582 +q1a5/max_fs = 775 +q1a5/min_ss = 370 +q1a5/max_ss = 554 +q1a5/corner_x = -364.038000 +q1a5/corner_y = 662.163000 +q1a5/fs = 0.000539x -1.000000y +0.000000z +q1a5/ss = 1.000000x +0.000539y +0.000000z + +q1a6/min_fs = 388 +q1a6/max_fs = 581 +q1a6/min_ss = 555 +q1a6/max_ss = 739 +q1a6/corner_x = -156.511000 +q1a6/corner_y = 857.902000 +q1a6/fs = -0.000337x -1.000000y +0.000000z +q1a6/ss = 1.000000x -0.000337y +0.000000z + +q1a7/min_fs = 582 +q1a7/max_fs = 775 +q1a7/min_ss = 555 +q1a7/max_ss = 739 +q1a7/corner_x = -156.577000 +q1a7/corner_y = 660.902000 +q1a7/fs = -0.000337x -1.000000y +0.000000z +q1a7/ss = 1.000000x -0.000337y +0.000000z + +q1a8/min_fs = 388 +q1a8/max_fs = 581 +q1a8/min_ss = 740 +q1a8/max_ss = 924 +q1a8/corner_x = -786.718000 +q1a8/corner_y = 463.506000 +q1a8/fs = 0.999996x +0.002303y +0.000000z +q1a8/ss = -0.002303x +0.999996y +0.000000z + +q1a9/min_fs = 582 +q1a9/max_fs = 775 +q1a9/min_ss = 740 +q1a9/max_ss = 924 +q1a9/corner_x = -589.719000 +q1a9/corner_y = 463.959000 +q1a9/fs = 0.999996x +0.002303y +0.000000z +q1a9/ss = -0.002303x +0.999996y +0.000000z + +q1a10/min_fs = 388 +q1a10/max_fs = 581 +q1a10/min_ss = 925 +q1a10/max_ss = 1109 +q1a10/corner_x = -787.022000 +q1a10/corner_y = 668.135000 +q1a10/fs = 0.999997x +0.001741y +0.000000z +q1a10/ss = -0.001741x +0.999997y +0.000000z + +q1a11/min_fs = 582 +q1a11/max_fs = 775 +q1a11/min_ss = 925 +q1a11/max_ss = 1109 +q1a11/corner_x = -590.022000 +q1a11/corner_y = 668.478000 +q1a11/fs = 0.999997x +0.001741y +0.000000z +q1a11/ss = -0.001741x +0.999997y +0.000000z + +q1a12/min_fs = 388 +q1a12/max_fs = 581 +q1a12/min_ss = 1110 +q1a12/max_ss = 1294 +q1a12/corner_x = -761.085000 +q1a12/corner_y = 428.541000 +q1a12/fs = -0.000201x -0.999999y +0.000000z +q1a12/ss = 0.999999x -0.000201y +0.000000z + +q1a13/min_fs = 582 +q1a13/max_fs = 775 +q1a13/min_ss = 1110 +q1a13/max_ss = 1294 +q1a13/corner_x = -761.125000 +q1a13/corner_y = 231.541000 +q1a13/fs = -0.000201x -0.999999y +0.000000z +q1a13/ss = 0.999999x -0.000201y +0.000000z + +q1a14/min_fs = 388 +q1a14/max_fs = 581 +q1a14/min_ss = 1295 +q1a14/max_ss = 1479 +q1a14/corner_x = -559.624000 +q1a14/corner_y = 428.347000 +q1a14/fs = 0.003097x -0.999995y +0.000000z +q1a14/ss = 0.999995x +0.003097y +0.000000z + +q1a15/min_fs = 582 +q1a15/max_fs = 775 +q1a15/min_ss = 1295 +q1a15/max_ss = 1479 +q1a15/corner_x = -559.014000 +q1a15/corner_y = 231.348000 +q1a15/fs = 0.003097x -0.999995y +0.000000z +q1a15/ss = 0.999995x +0.003097y +0.000000z + +q2a0/min_fs = 776 +q2a0/max_fs = 969 +q2a0/min_ss = 0 +q2a0/max_ss = 184 +q2a0/corner_x = -442.346000 +q2a0/corner_y = 20.338200 +q2a0/fs = -0.004086x -0.999991y +0.000000z +q2a0/ss = 0.999991x -0.004086y +0.000000z + +q2a1/min_fs = 970 +q2a1/max_fs = 1163 +q2a1/min_ss = 0 +q2a1/max_ss = 184 +q2a1/corner_x = -443.151000 +q2a1/corner_y = -176.660000 +q2a1/fs = -0.004086x -0.999991y +0.000000z +q2a1/ss = 0.999991x -0.004086y +0.000000z + +q2a2/min_fs = 776 +q2a2/max_fs = 969 +q2a2/min_ss = 185 +q2a2/max_ss = 369 +q2a2/corner_x = -235.519000 +q2a2/corner_y = 19.231200 +q2a2/fs = 0.000302x -1.000000y +0.000000z +q2a2/ss = 1.000000x +0.000302y +0.000000z + +q2a3/min_fs = 970 +q2a3/max_fs = 1163 +q2a3/min_ss = 185 +q2a3/max_ss = 369 +q2a3/corner_x = -235.459000 +q2a3/corner_y = -177.769000 +q2a3/fs = 0.000302x -1.000000y +0.000000z +q2a3/ss = 1.000000x +0.000302y +0.000000z + +q2a4/min_fs = 776 +q2a4/max_fs = 969 +q2a4/min_ss = 370 +q2a4/max_ss = 554 +q2a4/corner_x = -863.817000 +q2a4/corner_y = -370.344000 +q2a4/fs = 0.999997x -0.002037y +0.000000z +q2a4/ss = 0.002037x +0.999997y +0.000000z + +q2a5/min_fs = 970 +q2a5/max_fs = 1163 +q2a5/min_ss = 370 +q2a5/max_ss = 554 +q2a5/corner_x = -666.817000 +q2a5/corner_y = -370.746000 +q2a5/fs = 0.999997x -0.002037y +0.000000z +q2a5/ss = 0.002037x +0.999997y +0.000000z + +q2a6/min_fs = 776 +q2a6/max_fs = 969 +q2a6/min_ss = 555 +q2a6/max_ss = 739 +q2a6/corner_x = -863.549000 +q2a6/corner_y = -165.126000 +q2a6/fs = 1.000000x -0.001155y +0.000000z +q2a6/ss = 0.001155x +1.000000y +0.000000z + +q2a7/min_fs = 970 +q2a7/max_fs = 1163 +q2a7/min_ss = 555 +q2a7/max_ss = 739 +q2a7/corner_x = -666.549000 +q2a7/corner_y = -165.353000 +q2a7/fs = 1.000000x -0.001155y +0.000000z +q2a7/ss = 0.001155x +1.000000y +0.000000z + +q2a8/min_fs = 776 +q2a8/max_fs = 969 +q2a8/min_ss = 740 +q2a8/max_ss = 924 +q2a8/corner_x = -473.620000 +q2a8/corner_y = -793.473000 +q2a8/fs = 0.002076x +0.999998y +0.000000z +q2a8/ss = -0.999998x +0.002076y +0.000000z + +q2a9/min_fs = 970 +q2a9/max_fs = 1163 +q2a9/min_ss = 740 +q2a9/max_ss = 924 +q2a9/corner_x = -473.211000 +q2a9/corner_y = -596.474000 +q2a9/fs = 0.002076x +0.999998y +0.000000z +q2a9/ss = -0.999998x +0.002076y +0.000000z + +q2a10/min_fs = 776 +q2a10/max_fs = 969 +q2a10/min_ss = 925 +q2a10/max_ss = 1109 +q2a10/corner_x = -676.809000 +q2a10/corner_y = -792.653000 +q2a10/fs = 0.004134x +0.999991y +0.000000z +q2a10/ss = -0.999991x +0.004134y +0.000000z + +q2a11/min_fs = 970 +q2a11/max_fs = 1163 +q2a11/min_ss = 925 +q2a11/max_ss = 1109 +q2a11/corner_x = -675.995000 +q2a11/corner_y = -595.655000 +q2a11/fs = 0.004134x +0.999991y +0.000000z +q2a11/ss = -0.999991x +0.004134y +0.000000z + +q2a12/min_fs = 776 +q2a12/max_fs = 969 +q2a12/min_ss = 1110 +q2a12/max_ss = 1294 +q2a12/corner_x = -442.034000 +q2a12/corner_y = -769.447000 +q2a12/fs = 0.999981x -0.006417y +0.000000z +q2a12/ss = 0.006417x +0.999981y +0.000000z + +q2a13/min_fs = 970 +q2a13/max_fs = 1163 +q2a13/min_ss = 1110 +q2a13/max_ss = 1294 +q2a13/corner_x = -245.038000 +q2a13/corner_y = -770.711000 +q2a13/fs = 0.999981x -0.006417y +0.000000z +q2a13/ss = 0.006417x +0.999981y +0.000000z + +q2a14/min_fs = 776 +q2a14/max_fs = 969 +q2a14/min_ss = 1295 +q2a14/max_ss = 1479 +q2a14/corner_x = -441.283000 +q2a14/corner_y = -566.627000 +q2a14/fs = 0.999996x -0.002727y +0.000000z +q2a14/ss = 0.002727x +0.999996y +0.000000z + +q2a15/min_fs = 970 +q2a15/max_fs = 1163 +q2a15/min_ss = 1295 +q2a15/max_ss = 1479 +q2a15/corner_x = -244.283000 +q2a15/corner_y = -567.164000 +q2a15/fs = 0.999996x -0.002727y +0.000000z +q2a15/ss = 0.002727x +0.999996y +0.000000z + +q3a0/min_fs = 1164 +q3a0/max_fs = 1357 +q3a0/min_ss = 0 +q3a0/max_ss = 184 +q3a0/corner_x = -33.350700 +q3a0/corner_y = -458.693000 +q3a0/fs = 0.999988x -0.004965y +0.000000z +q3a0/ss = 0.004965x +0.999988y +0.000000z + +q3a1/min_fs = 1358 +q3a1/max_fs = 1551 +q3a1/min_ss = 0 +q3a1/max_ss = 184 +q3a1/corner_x = 163.647000 +q3a1/corner_y = -459.671000 +q3a1/fs = 0.999988x -0.004965y +0.000000z +q3a1/ss = 0.004965x +0.999988y +0.000000z + +q3a2/min_fs = 1164 +q3a2/max_fs = 1357 +q3a2/min_ss = 185 +q3a2/max_ss = 369 +q3a2/corner_x = -31.831600 +q3a2/corner_y = -254.931000 +q3a2/fs = 0.999998x -0.002316y +0.000000z +q3a2/ss = 0.002316x +0.999998y +0.000000z + +q3a3/min_fs = 1358 +q3a3/max_fs = 1551 +q3a3/min_ss = 185 +q3a3/max_ss = 369 +q3a3/corner_x = 165.168000 +q3a3/corner_y = -255.388000 +q3a3/fs = 0.999998x -0.002316y +0.000000z +q3a3/ss = 0.002316x +0.999998y +0.000000z + +q3a4/min_fs = 1164 +q3a4/max_fs = 1357 +q3a4/min_ss = 370 +q3a4/max_ss = 554 +q3a4/corner_x = 359.553000 +q3a4/corner_y = -886.512000 +q3a4/fs = 0.002474x +0.999997y +0.000000z +q3a4/ss = -0.999997x +0.002474y +0.000000z + +q3a5/min_fs = 1358 +q3a5/max_fs = 1551 +q3a5/min_ss = 370 +q3a5/max_ss = 554 +q3a5/corner_x = 360.040000 +q3a5/corner_y = -689.512000 +q3a5/fs = 0.002474x +0.999997y +0.000000z +q3a5/ss = -0.999997x +0.002474y +0.000000z + +q3a6/min_fs = 1164 +q3a6/max_fs = 1357 +q3a6/min_ss = 555 +q3a6/max_ss = 739 +q3a6/corner_x = 154.142000 +q3a6/corner_y = -884.763000 +q3a6/fs = 0.000059x +1.000000y +0.000000z +q3a6/ss = -1.000000x +0.000059y +0.000000z + +q3a7/min_fs = 1358 +q3a7/max_fs = 1551 +q3a7/min_ss = 555 +q3a7/max_ss = 739 +q3a7/corner_x = 154.154000 +q3a7/corner_y = -687.763000 +q3a7/fs = 0.000059x +1.000000y +0.000000z +q3a7/ss = -1.000000x +0.000059y +0.000000z + +q3a8/min_fs = 1164 +q3a8/max_fs = 1357 +q3a8/min_ss = 740 +q3a8/max_ss = 924 +q3a8/corner_x = 784.877000 +q3a8/corner_y = -492.935000 +q3a8/fs = -0.999993x +0.004040y +0.000000z +q3a8/ss = -0.004040x -0.999993y +0.000000z + +q3a9/min_fs = 1358 +q3a9/max_fs = 1551 +q3a9/min_ss = 740 +q3a9/max_ss = 924 +q3a9/corner_x = 587.878000 +q3a9/corner_y = -492.139000 +q3a9/fs = -0.999993x +0.004040y +0.000000z +q3a9/ss = -0.004040x -0.999993y +0.000000z + +q3a10/min_fs = 1164 +q3a10/max_fs = 1357 +q3a10/min_ss = 925 +q3a10/max_ss = 1109 +q3a10/corner_x = 784.254000 +q3a10/corner_y = -699.590000 +q3a10/fs = -0.999971x +0.007529y +0.000000z +q3a10/ss = -0.007529x -0.999971y +0.000000z + +q3a11/min_fs = 1358 +q3a11/max_fs = 1551 +q3a11/min_ss = 925 +q3a11/max_ss = 1109 +q3a11/corner_x = 587.260000 +q3a11/corner_y = -698.107000 +q3a11/fs = -0.999971x +0.007529y +0.000000z +q3a11/ss = -0.007529x -0.999971y +0.000000z + +q3a12/min_fs = 1164 +q3a12/max_fs = 1357 +q3a12/min_ss = 1110 +q3a12/max_ss = 1294 +q3a12/corner_x = 769.176000 +q3a12/corner_y = -460.510000 +q3a12/fs = 0.004516x +0.999990y +0.000000z +q3a12/ss = -0.999990x +0.004516y +0.000000z + +q3a13/min_fs = 1358 +q3a13/max_fs = 1551 +q3a13/min_ss = 1110 +q3a13/max_ss = 1294 +q3a13/corner_x = 770.066000 +q3a13/corner_y = -263.512000 +q3a13/fs = 0.004516x +0.999990y +0.000000z +q3a13/ss = -0.999990x +0.004516y +0.000000z + +q3a14/min_fs = 1164 +q3a14/max_fs = 1357 +q3a14/min_ss = 1295 +q3a14/max_ss = 1479 +q3a14/corner_x = 554.764000 +q3a14/corner_y = -460.250000 +q3a14/fs = 0.004918x +0.999989y +0.000000z +q3a14/ss = -0.999989x +0.004918y +0.000000z + +q3a15/min_fs = 1358 +q3a15/max_fs = 1551 +q3a15/min_ss = 1295 +q3a15/max_ss = 1479 +q3a15/corner_x = 555.732000 +q3a15/corner_y = -263.253000 +q3a15/fs = 0.004918x +0.999989y +0.000000z +q3a15/ss = -0.999989x +0.004918y +0.000000z + +group_a0 = q0a0,q0a1 +group_a1 = q0a2,q0a3 +group_a2 = q0a4,q0a5 +group_a3 = q0a6,q0a7 +group_a4 = q0a8,q0a9 +group_a5 = q0a10,q0a11 +group_a6 = q0a12,q0a13 +group_a7 = q0a14,q0a15 +group_a8 = q1a0,q1a1 +group_a9 = q1a2,q1a3 +group_a10 = q1a4,q1a5 +group_a11 = q1a6,q1a7 +group_a12 = q1a8,q1a9 +group_a13 = q1a10,q1a11 +group_a14 = q1a12,q1a13 +group_a15 = q1a14,q1a15 +group_a16 = q2a0,q2a1 +group_a17 = q2a2,q2a3 +group_a18 = q2a4,q2a5 +group_a19 = q2a6,q2a7 +group_a20 = q2a8,q2a9 +group_a21 = q2a10,q2a11 +group_a22 = q2a12,q2a13 +group_a23 = q2a14,q2a15 +group_a24 = q3a0,q3a1 +group_a25 = q3a2,q3a3 +group_a26 = q3a4,q3a5 +group_a27 = q3a6,q3a7 +group_a28 = q3a8,q3a9 +group_a29 = q3a10,q3a11 +group_a30 = q3a12,q3a13 +group_a31 = q3a14,q3a15 +group_q0 = a0,a1,a2,a3,a4,a5,a6,a7 +group_q1 = a8,a9,a10,a11,a12,a13,a14,a15 +group_q2 = a16,a17,a18,a19,a20,a21,a22,a23 +group_q3 = a24,a25,a26,a27,a28,a29,a30,a31 +group_all = q0,q1,q2,q3 +EOF + +$ADJUST_DETECTOR -i roundtrip.geom -o roundtrip-out.geom +if [ $? -ne 0 ]; then + exit 1; +fi + +diff roundtrip.geom roundtrip-out.geom +if [ $? -ne 0 ]; then + exit 1 +fi +#rm -f roundtrip.geom roundtrip-out.geom +exit 0 diff --git a/tests/gradient_check.c b/tests/gradient_check.c new file mode 100644 index 00000000..001bff7a --- /dev/null +++ b/tests/gradient_check.c @@ -0,0 +1,187 @@ +/* + * gradient_panel_x.c + * + * Check gradients for prediction refinement + * + * Copyright © 2012-2023 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2012-2023 Thomas White <taw@physics.org> + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <getopt.h> + +#include <image.h> +#include <geometry.h> +#include <predict-refine.h> + +#include "gradient_check_utils.h" + + +int main(int argc, char *argv[]) +{ + struct image image; + struct reflpeak *rps; + int n_refls; + double **before; + double **after; + int i; + int n_wrong_r = 0; + int n_wrong_fs = 0; + int n_wrong_ss = 0; + int n_wrong_obsr = 0; + int fail = 0; + double step; + gsl_matrix **panel_matrices; + int didsomething = 0; + const double cx = 0.03; /* Detector is a 7.5 cm side length square */ + const double cy = 0.02; + const double cz = 0.01; + + rps = make_test_image(&n_refls, &image); + panel_matrices = make_panel_minvs(image.detgeom); + + before = make_dev_list(rps, n_refls, image.detgeom); + + #ifdef TRANSLATE_PANEL + struct detgeom_panel *p = &image.detgeom->panels[0]; + step = 0.01e-3; /* metres */ + image.detgeom->panels[0].THING_TO_MOVE += step/p->pixel_pitch; + didsomething = 1; + #endif + + #ifdef ROTATE_PANEL_X + struct detgeom_panel *p = &image.detgeom->panels[0]; + step = deg2rad(0.01); + rotate2d(&p->cny, &p->cnz, cy/p->pixel_pitch, cz/p->pixel_pitch, step); + rotate2d(&p->fsy, &p->fsz, 0, 0, step); + rotate2d(&p->ssy, &p->ssz, 0, 0, step); + didsomething = 1; + #endif + + #ifdef ROTATE_PANEL_Y + struct detgeom_panel *p = &image.detgeom->panels[0]; + step = deg2rad(0.01); + rotate2d(&p->cnz, &p->cnx, cz/p->pixel_pitch, cx/p->pixel_pitch, step); + rotate2d(&p->fsz, &p->fsx, 0, 0, step); + rotate2d(&p->ssz, &p->ssx, 0, 0, step); + didsomething = 1; + #endif + + #ifdef ROTATE_PANEL_Z + struct detgeom_panel *p = &image.detgeom->panels[0]; + step = deg2rad(0.01); + rotate2d(&p->cnx, &p->cny, cx/p->pixel_pitch, cy/p->pixel_pitch, step); + rotate2d(&p->fsx, &p->fsy, 0, 0, step); + rotate2d(&p->ssx, &p->ssy, 0, 0, step); + didsomething = 1; + #endif + + #ifdef CHANGE_CELL + double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; + UnitCell *cell = crystal_get_cell(image.crystals[0]); + step = 0.5e5; + cell_get_reciprocal(cell, &asx, &asy, &asz, + &bsx, &bsy, &bsz, + &csx, &csy, &csz); + THING_TO_MOVE += step; + cell_set_reciprocal(cell, asx, asy, asz, + bsx, bsy, bsz, + csx, csy, csz); + didsomething = 1; + #endif + + if ( !didsomething ) { + fprintf(stderr, "Nothing changed. Check the build system.\n"); + return 1; + } + + update_predictions(image.crystals[0]); + after = make_dev_list(rps, n_refls, image.detgeom); + + for ( i=0; i<n_refls; i++ ) { + + float calc[3]; + double obs[3]; + + calc[0] = r_gradient(TEST_GPARAM, rps[i].refl, + crystal_get_cell(image.crystals[0]), + image.lambda); + + fs_ss_gradient(TEST_GPARAM, rps[i].refl, + crystal_get_cell(image.crystals[0]), + &image.detgeom->panels[rps[i].peak->pn], + panel_matrices[rps[i].peak->pn], cx, cy, cz, + &calc[1], &calc[2]); + + obs[0] = (after[0][i] - before[0][i]) / step; + obs[1] = (after[1][i] - before[1][i]) / step; + obs[2] = (after[2][i] - before[2][i]) / step; + + #ifdef TRANSLATE_PANEL + if ( fabs(calc[0]) > 1e-12 ) n_wrong_r++; /* Should be zero */ + if ( fabs(obs[0]) > 1e-12 ) n_wrong_obsr++; /* Should also be zero */ + if ( fabs(obs[1] - calc[1]) > 10.0 ) n_wrong_fs++; + if ( fabs(obs[2] - calc[2]) > 10.0 ) n_wrong_ss++; + #endif + + #if defined(ROTATE_PANEL_X) || defined(ROTATE_PANEL_Y) || defined(ROTATE_PANEL_Z) + if ( fabs(calc[0]) > 1e-12 ) n_wrong_r++; /* Should be zero */ + if ( fabs(obs[0]) > 1e-12 ) n_wrong_obsr++; /* Should also be zero */ + if ( fabs(obs[1] - calc[1]) > 1.0 ) n_wrong_fs++; /* Units are pixels/rad */ + if ( fabs(obs[2] - calc[2]) > 1.0 ) n_wrong_ss++; /* (numbers are big) */ + #endif + + #ifdef CHANGE_CELL + if ( fabs(obs[0] - calc[0]) > 1e-2 ) n_wrong_r++; + if ( fabs(obs[1] - calc[1]) > 1e-8 ) n_wrong_fs++; + if ( fabs(obs[2] - calc[2]) > 1e-8 ) n_wrong_ss++; + #endif + + } + + if ( n_wrong_r > 0 ) { + fprintf(stderr, "%i out of %i R gradients were wrong.\n", + n_wrong_r, n_refls); + fail = 1; + } + + if ( n_wrong_fs > 0 ) { + fprintf(stderr, "%i out of %i fs gradients were wrong.\n", + n_wrong_fs, n_refls); + fail = 1; + } + + if ( n_wrong_ss > 0 ) { + fprintf(stderr, "%i out of %i ss gradients were wrong.\n", + n_wrong_ss, n_refls); + fail = 1; + } + + if ( n_wrong_obsr > 0 ) { + fprintf(stderr, "%i out of %i observed R gradients were not zero as expected\n", + n_wrong_obsr, n_refls); + fail = 1; + } + + return fail; +} diff --git a/tests/gradient_check_utils.c b/tests/gradient_check_utils.c new file mode 100644 index 00000000..6b641b9d --- /dev/null +++ b/tests/gradient_check_utils.c @@ -0,0 +1,184 @@ +/* + * gradient_check_utils.c + * + * Check gradients for prediction refinement (common component) + * + * Copyright © 2012-2023 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2012-2023 Thomas White <taw@physics.org> + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <gsl/gsl_randist.h> +#include <getopt.h> + +#include <image.h> +#include <cell.h> +#include <cell-utils.h> +#include <geometry.h> +#include <reflist.h> + + +double **make_dev_list(struct reflpeak *rps, int n_refls, struct detgeom *det) +{ + int i; + double **vals; + + vals = malloc(3*sizeof(double *)); + vals[0] = malloc(n_refls*sizeof(double)); + vals[1] = malloc(n_refls*sizeof(double)); + vals[2] = malloc(n_refls*sizeof(double)); + + for ( i=0; i<n_refls; i++ ) { + vals[0][i] = get_exerr(rps[i].refl); + vals[1][i] = fs_dev(&rps[i], det); + vals[2][i] = ss_dev(&rps[i], det); + } + + return vals; +} + + +static UnitCell *random_rotated_cell(gsl_rng *rng) +{ + UnitCell *cell; + struct quaternion orientation; + + cell = cell_new_from_parameters(10.0e-9, 10.0e-9, 10.0e-9, + deg2rad(90.0), + deg2rad(90.0), + deg2rad(90.0)); + orientation = random_quaternion(rng); + return cell_rotate(cell, orientation); +} + + +static void rot(double *x, double *y, double ang) +{ + double nx, ny; + nx = (*x)*cos(ang) - (*y)*sin(ang); + ny = (*x)*sin(ang) + (*y)*cos(ang); + *x = nx; *y = ny; +} + + +struct reflpeak *make_test_image(int *pn_refls, struct image *image) +{ + Crystal *cr; + gsl_rng *rng; + RefList *refls; + Reflection *refl; + RefListIterator *iter; + int n_refls; + int i; + struct reflpeak *rps; + + image->detgeom = malloc(sizeof(struct detgeom)); + image->detgeom->n_panels = 1; + image->detgeom->panels = malloc(sizeof(struct detgeom_panel)); + image->detgeom->panels[0].name = "panel"; + image->detgeom->panels[0].adu_per_photon = 1.0; + image->detgeom->panels[0].max_adu = INFINITY; + image->detgeom->panels[0].fsx = 1.0; + image->detgeom->panels[0].fsy = 0.0; + image->detgeom->panels[0].fsz = 0.0; + image->detgeom->panels[0].ssx = 0.0; + image->detgeom->panels[0].ssy = 1.0; + image->detgeom->panels[0].ssz = 0.0; + rot(&image->detgeom->panels[0].fsx, + &image->detgeom->panels[0].fsy, + deg2rad(30)); + rot(&image->detgeom->panels[0].ssx, + &image->detgeom->panels[0].ssy, + deg2rad(30)); + rot(&image->detgeom->panels[0].fsx, + &image->detgeom->panels[0].fsz, + deg2rad(15)); + rot(&image->detgeom->panels[0].ssx, + &image->detgeom->panels[0].ssz, + deg2rad(15)); + image->detgeom->panels[0].cnx = -500.0; + image->detgeom->panels[0].cny = -500.0; + image->detgeom->panels[0].cnz = 1000.0; /* pixels */ + image->detgeom->panels[0].w = 1000; + image->detgeom->panels[0].h = 1000; + image->detgeom->panels[0].pixel_pitch = 75e-6; + + image->lambda = ph_en_to_lambda(eV_to_J(8000.0)); + image->div = 1e-3; + image->bw = 0.00001; + image->filename = malloc(256); + image->spectrum = spectrum_generate_gaussian(image->lambda, image->bw); + + image->crystals = NULL; + image->n_crystals = 0; + + rng = gsl_rng_alloc(gsl_rng_mt19937); + + cr = crystal_new(); + if ( cr == NULL ) { + ERROR("Failed to allocate crystal.\n"); + return NULL; + } + crystal_set_mosaicity(cr, 0.0); + crystal_set_profile_radius(cr, 0.005e9); + crystal_set_image(cr, image); + crystal_set_cell(cr, random_rotated_cell(rng)); + + refls = predict_to_res(cr, detgeom_max_resolution(image->detgeom, image->lambda)); + crystal_set_reflections(cr, refls); + n_refls = num_reflections(refls); + + /* Associate a peak with every reflection */ + rps = malloc(n_refls*sizeof(struct reflpeak)); + i = 0; + for ( refl = first_refl(refls, &iter); + refl != NULL; + refl = next_refl(refl, iter) ) + { + double fs, ss; + int pn; + struct imagefeature *pk; + + get_detector_pos(refl, &fs, &ss); + pn = get_panel_number(refl); + + pk = malloc(sizeof(struct imagefeature)); + + pk->fs = fs + gsl_ran_gaussian(rng, 5.0); + pk->ss = ss + gsl_ran_gaussian(rng, 5.0); + pk->pn = pn; + pk->intensity = 1.0; + + rps[i].peak = pk; + rps[i].refl = refl; + rps[i].Ih = 1.0; + i++; + } + + image_add_crystal(image, cr); + + gsl_rng_free(rng); + + *pn_refls = n_refls; + return rps; +} diff --git a/tests/gradient_check_utils.h b/tests/gradient_check_utils.h new file mode 100644 index 00000000..562081fe --- /dev/null +++ b/tests/gradient_check_utils.h @@ -0,0 +1,32 @@ +/* + * gradient_check_utils.h + * + * Check gradients for prediction refinement (common component) + * + * Copyright © 2012-2023 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2012-2023 Thomas White <taw@physics.org> + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <image.h> + +extern struct reflpeak *make_test_image(int *n_refls, struct image *image); +extern double **make_dev_list(struct reflpeak *rps, int n_refls, struct detgeom *det); diff --git a/tests/meson.build b/tests/meson.build index 917c59db..88a8d073 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -44,7 +44,6 @@ simple_tests = ['ambi_check', 'cell_check', 'centering_check', 'list_check', - 'prediction_gradient_check', 'ring_check', 'symmetry_check', 'transformation_check', @@ -96,6 +95,63 @@ exe = executable('prof2d_check', dependencies : [libcrystfeldep, mdep, gsldep]) test('prof2d_check', exe) + +# Refinement gradient checks, part 1: panel translations +panel_gradient_tests = [['gradient_panel_x', 'cnx', 'GPARAM_DET_TX'], + ['gradient_panel_y', 'cny', 'GPARAM_DET_TY'], + ['gradient_panel_z', 'cnz', 'GPARAM_DET_TZ']] + +foreach name : panel_gradient_tests + exe = executable(name[0], + ['gradient_check.c', + 'gradient_check_utils.c'], + c_args : ['-DTHING_TO_MOVE='+name[1], + '-DTEST_GPARAM='+name[2], + '-DTRANSLATE_PANEL=1'], + dependencies : [libcrystfeldep, mdep, gsldep]) + test(name[0], exe) +endforeach + + +# Refinement gradient checks, part 2: panel rotations +panel_gradient_tests = [['gradient_panel_rx', '-DROTATE_PANEL_X', 'GPARAM_DET_RX'], + ['gradient_panel_ry', '-DROTATE_PANEL_Y', 'GPARAM_DET_RY'], + ['gradient_panel_rz', '-DROTATE_PANEL_Z', 'GPARAM_DET_RZ']] + +foreach name : panel_gradient_tests + exe = executable(name[0], + ['gradient_check.c', + 'gradient_check_utils.c'], + c_args : [name[1], + '-DTEST_GPARAM='+name[2]], + dependencies : [libcrystfeldep, mdep, gsldep]) + test(name[0], exe) +endforeach + + +# Refinement gradient checks, part 3: diffraction physics +panel_gradient_tests = [['gradient_cell_asx', 'asx', 'GPARAM_ASX'], + ['gradient_cell_asy', 'asy', 'GPARAM_ASY'], + ['gradient_cell_asz', 'asz', 'GPARAM_ASZ'], + ['gradient_cell_bsx', 'bsx', 'GPARAM_BSX'], + ['gradient_cell_bsy', 'bsy', 'GPARAM_BSY'], + ['gradient_cell_bsz', 'bsz', 'GPARAM_BSZ'], + ['gradient_cell_csx', 'csx', 'GPARAM_CSX'], + ['gradient_cell_csy', 'csy', 'GPARAM_CSY'], + ['gradient_cell_csz', 'csz', 'GPARAM_CSZ']] + +foreach name : panel_gradient_tests + exe = executable(name[0], + ['gradient_check.c', + 'gradient_check_utils.c'], + c_args : ['-DTHING_TO_MOVE='+name[1], + '-DTEST_GPARAM='+name[2], + '-DCHANGE_CELL=1'], + dependencies : [libcrystfeldep, mdep, gsldep]) + test(name[0], exe) +endforeach + + # Event enumeration tests if hdf5dep.found() ev_enum_tests = ['ev_enum1', @@ -138,3 +194,8 @@ if hdf5dep.found() test(p[0], exe, args : [h5, geom, expected_wl]) endforeach endif + + +test('geom_roundtrip', + find_program('geom_roundtrip'), + args: [adjust_detector.full_path()]) diff --git a/tests/partialator_merge_check_1 b/tests/partialator_merge_check_1 index 4ed03785..221a9327 100755 --- a/tests/partialator_merge_check_1 +++ b/tests/partialator_merge_check_1 @@ -7,6 +7,7 @@ CrystFEL stream format 2.3 Command line: indexamajig -i dummy.lst -o dummy.stream --kraken=prawn ----- Begin geometry file ----- photon_energy = 9000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 0 panel/max_fs = 1023 @@ -15,7 +16,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/partialator_merge_check_2 b/tests/partialator_merge_check_2 index 2ebcd74e..e392b82e 100755 --- a/tests/partialator_merge_check_2 +++ b/tests/partialator_merge_check_2 @@ -7,6 +7,7 @@ CrystFEL stream format 2.3 Command line: indexamajig -i dummy.lst -o dummy.stream --kraken=prawn ----- Begin geometry file ----- photon_energy = 9000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 0 panel/max_fs = 1023 @@ -15,7 +16,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/partialator_merge_check_3 b/tests/partialator_merge_check_3 index 8c998258..9f5fa350 100755 --- a/tests/partialator_merge_check_3 +++ b/tests/partialator_merge_check_3 @@ -7,6 +7,7 @@ CrystFEL stream format 2.3 Command line: indexamajig -i dummy.lst -o dummy.stream --kraken=prawn ----- Begin geometry file ----- photon_energy = 9000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 0 panel/max_fs = 1023 @@ -15,7 +16,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/plot_gradients b/tests/plot_gradients deleted file mode 100755 index b5800d07..00000000 --- a/tests/plot_gradients +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -gnuplot -persist << EOF - -set key bottom right - -set xlabel "Calculated gradient" -set ylabel "Observed gradient" - - plot "gradient-test-x.dat" using 1:2 w p lc 1 pt 1 title "x" -replot "gradient-test-y.dat" using 1:2 w p lc 2 pt 1 title "y" -replot "gradient-test-z.dat" using 1:2 w p lc 3 pt 1 title "z" - -EOF - -gnuplot -persist << EOF -set key bottom right -set xlabel "Calculated gradient" -set ylabel "Observed gradient" -plot "gradient-test-R.dat" using 1:2 w p lc 1 pt 1 title "profile radius" -EOF - -gnuplot -persist << EOF -set key bottom right -set xlabel "Calculated gradient" -set ylabel "Observed gradient" -plot "gradient-test-div.dat" using 1:2 w p lc 1 pt 1 title "divergence" -EOF diff --git a/tests/prediction_gradient_check.c b/tests/prediction_gradient_check.c deleted file mode 100644 index 493da445..00000000 --- a/tests/prediction_gradient_check.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * prediction_gradient_check.c - * - * Check partiality gradients for prediction refinement - * - * Copyright © 2012-2020 Deutsches Elektronen-Synchrotron DESY, - * a research centre of the Helmholtz Association. - * - * Authors: - * 2012-2020 Thomas White <taw@physics.org> - * - * This file is part of CrystFEL. - * - * CrystFEL is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CrystFEL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <gsl/gsl_statistics.h> -#include <getopt.h> - -#include <image.h> -#include <cell.h> -#include <cell-utils.h> -#include <geometry.h> -#include <reflist.h> - - -int checkrxy; - - -static void twod_mapping(double fs, double ss, double *px, double *py, - struct detgeom_panel *p) -{ - double xs, ys; - - xs = fs*p->fsx + ss*p->ssx; - ys = fs*p->fsy + ss*p->ssy; - - *px = (xs + p->cnx) * p->pixel_pitch; - *py = (ys + p->cny) * p->pixel_pitch; -} - - -static void scan(RefList *reflections, RefList *compare, - int *valid, long double *vals[3], int idx, - struct detgeom *det) -{ - int i; - Reflection *refl; - RefListIterator *iter; - - i = 0; - for ( refl = first_refl(reflections, &iter); - refl != NULL; - refl = next_refl(refl, iter) ) - { - signed int h, k, l; - Reflection *refl2; - double fs, ss, xh, yh; - int pn; - - get_indices(refl, &h, &k, &l); - refl2 = find_refl(compare, h, k, l); - if ( refl2 == NULL ) { - valid[i] = 0; - i++; - continue; - } - - get_detector_pos(refl2, &fs, &ss); - pn = get_panel_number(refl2); - twod_mapping(fs, ss, &xh, &yh, &det->panels[pn]); - - switch ( checkrxy ) { - - case 0 : - vals[idx][i] = get_exerr(refl2); - break; - - case 1 : - vals[idx][i] = xh; - break; - - case 2 : - vals[idx][i] = yh; - break; - } - - i++; - } -} - - -static UnitCell *new_shifted_cell(UnitCell *input, int k, double shift) -{ - UnitCell *cell; - double asx, asy, asz; - double bsx, bsy, bsz; - double csx, csy, csz; - - cell = cell_new(); - cell_get_reciprocal(input, &asx, &asy, &asz, &bsx, &bsy, &bsz, - &csx, &csy, &csz); - switch ( k ) - { - case GPARAM_ASX : asx += shift; break; - case GPARAM_ASY : asy += shift; break; - case GPARAM_ASZ : asz += shift; break; - case GPARAM_BSX : bsx += shift; break; - case GPARAM_BSY : bsy += shift; break; - case GPARAM_BSZ : bsz += shift; break; - case GPARAM_CSX : csx += shift; break; - case GPARAM_CSY : csy += shift; break; - case GPARAM_CSZ : csz += shift; break; - } - cell_set_reciprocal(cell, asx, asy, asz, bsx, bsy, bsz, csx, csy, csz); - - return cell; -} - - -static Crystal *new_shifted_crystal(Crystal *cr, int refine, double incr_val) -{ - Crystal *cr_new; - UnitCell *cell; - - cr_new = crystal_copy(cr); - if ( cr_new == NULL ) { - ERROR("Failed to allocate crystal.\n"); - return NULL; - } - - crystal_set_image(cr_new, crystal_get_image(cr)); - - switch ( refine ) { - - case GPARAM_ASX : - case GPARAM_ASY : - case GPARAM_ASZ : - case GPARAM_BSX : - case GPARAM_BSY : - case GPARAM_BSZ : - case GPARAM_CSX : - case GPARAM_CSY : - case GPARAM_CSZ : - cell = new_shifted_cell(crystal_get_cell(cr), refine, - incr_val); - crystal_set_cell(cr_new, cell); - break; - - default: - ERROR("Can't shift %i\n", refine); - break; - - } - - return cr_new; -} - - -static void calc_either_side(Crystal *cr, double incr_val, - int *valid, long double *vals[3], - int refine, struct detgeom *det) -{ - RefList *compare; - struct image *image = crystal_get_image(cr); - Crystal *cr_new; - - cr_new = new_shifted_crystal(cr, refine, -incr_val); - compare = predict_to_res(cr_new, detgeom_max_resolution(image->detgeom, - image->lambda)); - scan(crystal_get_reflections(cr), compare, valid, vals, 0, det); - cell_free(crystal_get_cell(cr_new)); - crystal_free(cr_new); - reflist_free(compare); - - cr_new = new_shifted_crystal(cr, refine, +incr_val); - compare = predict_to_res(cr_new, detgeom_max_resolution(image->detgeom, - image->lambda)); - scan(crystal_get_reflections(cr), compare, valid, vals, 2, det); - cell_free(crystal_get_cell(cr_new)); - crystal_free(cr_new); - reflist_free(compare); -} - - -static double max_resolution(const struct image *image) -{ - return detgeom_max_resolution(image->detgeom, - image->lambda); -} - - -static double test_gradients(Crystal *cr, double incr_val, int refine, - const char *str, const char *file, - int quiet, int plot, struct detgeom *det) -{ - Reflection *refl; - RefListIterator *iter; - long double *vals[3]; - int i; - int *valid; - int nref; - int n_good, n_invalid, n_small, n_nan, n_bad; - RefList *reflections; - FILE *fh = NULL; - int ntot = 0; - char tmp[32]; - double *vec1; - double *vec2; - int n_line; - double cc; - - reflections = predict_to_res(cr, max_resolution(crystal_get_image(cr))); - crystal_set_reflections(cr, reflections); - - nref = num_reflections(reflections); - if ( nref < 10 ) { - ERROR("Too few reflections found. Failing test by default.\n"); - return 0.0; - } - - vals[0] = malloc(nref*sizeof(long double)); - vals[1] = malloc(nref*sizeof(long double)); - vals[2] = malloc(nref*sizeof(long double)); - if ( (vals[0] == NULL) || (vals[1] == NULL) || (vals[2] == NULL) ) { - ERROR("Couldn't allocate memory.\n"); - return 0.0; - } - - valid = malloc(nref*sizeof(int)); - if ( valid == NULL ) { - ERROR("Couldn't allocate memory.\n"); - return 0.0; - } - for ( i=0; i<nref; i++ ) valid[i] = 1; - - scan(reflections, reflections, valid, vals, 1, det); - - calc_either_side(cr, incr_val, valid, vals, refine, det); - - if ( plot ) { - snprintf(tmp, 32, "gradient-test-%s.dat", file); - fh = fopen(tmp, "w"); - } - - vec1 = malloc(nref*sizeof(double)); - vec2 = malloc(nref*sizeof(double)); - if ( (vec1 == NULL) || (vec2 == NULL) ) { - ERROR("Couldn't allocate memory.\n"); - return 0.0; - } - - n_invalid = 0; n_good = 0; - n_nan = 0; n_small = 0; n_bad = 0; n_line = 0; - i = 0; - for ( refl = first_refl(reflections, &iter); - refl != NULL; - refl = next_refl(refl, iter) ) - { - long double grad1, grad2, grad; - double cgrad; - signed int h, k, l; - - get_indices(refl, &h, &k, &l); - - if ( !valid[i] ) { - n_invalid++; - i++; - } else { - - grad1 = (vals[1][i] - vals[0][i]) / incr_val; - grad2 = (vals[2][i] - vals[1][i]) / incr_val; - grad = (grad1 + grad2) / 2.0; - i++; - - if ( checkrxy == 0 ) { - - cgrad = r_gradient(crystal_get_cell(cr), refine, - refl, crystal_get_image(cr)); - - } else { - - struct image *image; - - image = crystal_get_image(cr); - - if ( checkrxy == 1 ) { - cgrad = x_gradient(refine, refl, - crystal_get_cell(cr), - &image->detgeom->panels[0]); - } else { - cgrad = y_gradient(refine, refl, - crystal_get_cell(cr), - &image->detgeom->panels[0]); - } - } - - if ( isnan(cgrad) ) { - n_nan++; - continue; - } - - if ( plot ) { - fprintf(fh, "%e %Le\n", cgrad, grad); - } - - vec1[n_line] = cgrad; - vec2[n_line] = grad; - n_line++; - - if ( (fabsl(cgrad) < 5e-12) && (fabsl(grad) < 5e-12) ) { - n_small++; - continue; - } - - ntot++; - - if ( !within_tolerance(grad, cgrad, 5.0) - || !within_tolerance(cgrad, grad, 5.0) ) - { - - if ( !quiet ) { - STATUS("!- %s %3i %3i %3i " - "%10.2Le %10.2e " - "ratio = %5.2Lf\n", - str, h, k, l, grad, cgrad, - cgrad/grad); - } - n_bad++; - - } else { - - //STATUS("OK %s %3i %3i %3i" - // " %10.2Le %10.2e ratio = %5.2Lf" - // " %10.2e %10.2e\n", - // str, h, k, l, grad, cgrad, cgrad/grad, - // r1, r2); - - n_good++; - - } - - } - - } - - STATUS("%3s: %3i within 5%%, %3i outside, %3i nan, %3i invalid, " - "%3i small. ", str, n_good, n_bad, n_nan, n_invalid, n_small); - - if ( plot ) { - fclose(fh); - } - - cc = gsl_stats_correlation(vec1, 1, vec2, 1, n_line); - STATUS("CC = %+f\n", cc); - return cc; -} - - -int main(int argc, char *argv[]) -{ - struct image image; - const double incr_frac = 1.0/100000.0; - double incr_val; - double ax, ay, az; - double bx, by, bz; - double cx, cy, cz; - UnitCell *cell; - Crystal *cr; - struct quaternion orientation; - int fail = 0; - int quiet = 0; - int plot = 0; - int c; - gsl_rng *rng; - UnitCell *rot; - double val; - - const struct option longopts[] = { - {"quiet", 0, &quiet, 1}, - {"plot", 0, &plot, 1}, - {0, 0, NULL, 0} - }; - - while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) { - switch (c) { - - case 0 : - break; - - case '?' : - break; - - default : - ERROR("Unhandled option '%c'\n", c); - break; - - } - - } - - image.detgeom = malloc(sizeof(struct detgeom)); - image.detgeom->n_panels = 1; - image.detgeom->panels = malloc(sizeof(struct detgeom_panel)); - image.detgeom->panels[0].name = "panel"; - image.detgeom->panels[0].adu_per_photon = 1.0; - image.detgeom->panels[0].max_adu = INFINITY; - image.detgeom->panels[0].fsx = 1.0; - image.detgeom->panels[0].fsy = 0.0; - image.detgeom->panels[0].fsz = 0.0; - image.detgeom->panels[0].ssx = 0.0; - image.detgeom->panels[0].ssy = 1.0; - image.detgeom->panels[0].ssz = 0.0; - image.detgeom->panels[0].cnx = -500.0; - image.detgeom->panels[0].cny = -500.0; - image.detgeom->panels[0].cnz = 1000.0; /* pixels */ - image.detgeom->panels[0].w = 1000; - image.detgeom->panels[0].h = 1000; - image.detgeom->panels[0].pixel_pitch = 75e-6; - - image.lambda = ph_en_to_lambda(eV_to_J(8000.0)); - image.div = 1e-3; - image.bw = 0.00001; - image.filename = malloc(256); - image.spectrum = spectrum_generate_gaussian(image.lambda, image.bw); - - cr = crystal_new(); - if ( cr == NULL ) { - ERROR("Failed to allocate crystal.\n"); - return 1; - } - crystal_set_mosaicity(cr, 0.0); - crystal_set_profile_radius(cr, 0.005e9); - crystal_set_image(cr, &image); - - cell = cell_new_from_parameters(10.0e-9, 10.0e-9, 10.0e-9, - deg2rad(90.0), - deg2rad(90.0), - deg2rad(90.0)); - - rng = gsl_rng_alloc(gsl_rng_mt19937); - - for ( checkrxy=0; checkrxy<3; checkrxy++ ) { - - - switch ( checkrxy ) { - case 0 : - STATUS("Excitation error:\n"); - break; - case 1: - STATUS("x coordinate:\n"); - break; - default: - case 2: - STATUS("y coordinate:\n"); - break; - STATUS("WTF??\n"); - break; - } - - orientation = random_quaternion(rng); - rot = cell_rotate(cell, orientation); - crystal_set_cell(cr, rot); - - cell_get_reciprocal(rot, &ax, &ay, &az, - &bx, &by, &bz, &cx, &cy, &cz); - - if ( checkrxy != 2 ) { - - incr_val = incr_frac * ax; - val = test_gradients(cr, incr_val, GPARAM_ASX, - "ax*", "ax", quiet, plot, - image.detgeom); - if ( val < 0.99 ) fail = 1; - incr_val = incr_frac * bx; - val = test_gradients(cr, incr_val, GPARAM_BSX, - "bx*", "bx", quiet, plot, - image.detgeom); - if ( val < 0.99 ) fail = 1; - incr_val = incr_frac * cx; - val = test_gradients(cr, incr_val, GPARAM_CSX, - "cx*", "cx", quiet, plot, - image.detgeom); - if ( val < 0.99 ) fail = 1; - - } - - if ( checkrxy != 1 ) { - - incr_val = incr_frac * ay; - val = test_gradients(cr, incr_val, GPARAM_ASY, - "ay*", "ay", quiet, plot, - image.detgeom); - if ( val < 0.99 ) fail = 1; - incr_val = incr_frac * by; - val = test_gradients(cr, incr_val, GPARAM_BSY, - "by*", "by", quiet, plot, - image.detgeom); - if ( val < 0.99 ) fail = 1; - incr_val = incr_frac * cy; - val = test_gradients(cr, incr_val, GPARAM_CSY, - "cy*", "cy", quiet, plot, - image.detgeom); - if ( val < 0.99 ) fail = 1; - - } - - incr_val = incr_frac * az; - val = test_gradients(cr, incr_val, GPARAM_ASZ, "az*", "az", - quiet, plot, image.detgeom); - if ( val < 0.99 ) fail = 1; - incr_val = incr_frac * bz; - val = test_gradients(cr, incr_val, GPARAM_BSZ, "bz*", "bz", - quiet, plot, image.detgeom); - if ( val < 0.99 ) fail = 1; - incr_val = incr_frac * cz; - val = test_gradients(cr, incr_val, GPARAM_CSZ, "cz*", "cz", - quiet, plot, image.detgeom); - if ( val < 0.99 ) fail = 1; - - } - - gsl_rng_free(rng); - - return fail; -} diff --git a/tests/process_hkl_check_1 b/tests/process_hkl_check_1 index 7cd29335..464fd528 100755 --- a/tests/process_hkl_check_1 +++ b/tests/process_hkl_check_1 @@ -7,6 +7,7 @@ CrystFEL stream format 2.3 Command line: indexamajig -i dummy.lst -o dummy.stream --kraken=prawn ----- Begin geometry file ----- photon_energy = 9000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 0 panel/max_fs = 1023 @@ -15,7 +16,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/process_hkl_check_2 b/tests/process_hkl_check_2 index 1ce4bc3c..2a523d1b 100755 --- a/tests/process_hkl_check_2 +++ b/tests/process_hkl_check_2 @@ -7,6 +7,7 @@ CrystFEL stream format 2.3 Command line: indexamajig -i dummy.lst -o dummy.stream --kraken=prawn ----- Begin geometry file ----- photon_energy = 9000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 0 panel/max_fs = 1023 @@ -15,7 +16,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/process_hkl_check_3 b/tests/process_hkl_check_3 index 4e884ad2..2440ae79 100755 --- a/tests/process_hkl_check_3 +++ b/tests/process_hkl_check_3 @@ -7,6 +7,7 @@ CrystFEL stream format 2.3 Command line: indexamajig -i dummy.lst -o dummy.stream --kraken=prawn ----- Begin geometry file ----- photon_energy = 9000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 0 panel/max_fs = 1023 @@ -15,7 +16,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/process_hkl_check_4 b/tests/process_hkl_check_4 index bfca3b80..63048dd4 100755 --- a/tests/process_hkl_check_4 +++ b/tests/process_hkl_check_4 @@ -7,6 +7,7 @@ CrystFEL stream format 2.3 Command line: indexamajig -i dummy.lst -o dummy.stream --kraken=prawn ----- Begin geometry file ----- photon_energy = 9000 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 0 panel/max_fs = 1023 @@ -15,7 +16,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom1.geom b/tests/wavelength_geom1.geom index 280cc349..59567ecd 100644 --- a/tests/wavelength_geom1.geom +++ b/tests/wavelength_geom1.geom @@ -1,4 +1,5 @@ wavelength = /LCLS/wavelength m +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom10.geom b/tests/wavelength_geom10.geom index f0d7ca96..2ad31d19 100644 --- a/tests/wavelength_geom10.geom +++ b/tests/wavelength_geom10.geom @@ -1,4 +1,5 @@ photon_energy = 9e3 eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom11.geom b/tests/wavelength_geom11.geom index d0a49612..873ba099 100644 --- a/tests/wavelength_geom11.geom +++ b/tests/wavelength_geom11.geom @@ -1,4 +1,5 @@ wavelength = 1.125 A +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom12.geom b/tests/wavelength_geom12.geom index 81308932..832467c8 100644 --- a/tests/wavelength_geom12.geom +++ b/tests/wavelength_geom12.geom @@ -1,4 +1,5 @@ wavelength = 1.125e-10 m +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom2.geom b/tests/wavelength_geom2.geom index 68d77ff2..911b62fb 100644 --- a/tests/wavelength_geom2.geom +++ b/tests/wavelength_geom2.geom @@ -1,4 +1,5 @@ photon_energy = /LCLS/photon_energy +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom3.geom b/tests/wavelength_geom3.geom index 5d989d48..a3a540c6 100644 --- a/tests/wavelength_geom3.geom +++ b/tests/wavelength_geom3.geom @@ -1,4 +1,5 @@ photon_energy = /LCLS/photon_energyK keV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom4.geom b/tests/wavelength_geom4.geom index e3a70045..d3e8fce8 100644 --- a/tests/wavelength_geom4.geom +++ b/tests/wavelength_geom4.geom @@ -1,4 +1,5 @@ electron_voltage = /LCLS/electron_energy2 kV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom5.geom b/tests/wavelength_geom5.geom index bc5de6cf..13b02bef 100644 --- a/tests/wavelength_geom5.geom +++ b/tests/wavelength_geom5.geom @@ -1,4 +1,5 @@ electron_voltage = /LCLS/electron_energy V +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom6.geom b/tests/wavelength_geom6.geom index da09f6cc..59b342c5 100644 --- a/tests/wavelength_geom6.geom +++ b/tests/wavelength_geom6.geom @@ -1,4 +1,5 @@ photon_energy = /LCLS/photon_energy eV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom7.geom b/tests/wavelength_geom7.geom index c22f89e8..7756475f 100644 --- a/tests/wavelength_geom7.geom +++ b/tests/wavelength_geom7.geom @@ -1,4 +1,5 @@ photon_energy = 9000 +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom8.geom b/tests/wavelength_geom8.geom index 4bcf2c98..f8b3a413 100644 --- a/tests/wavelength_geom8.geom +++ b/tests/wavelength_geom8.geom @@ -1,4 +1,5 @@ electron_voltage = 300 kV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array diff --git a/tests/wavelength_geom9.geom b/tests/wavelength_geom9.geom index 992c10a3..94394163 100644 --- a/tests/wavelength_geom9.geom +++ b/tests/wavelength_geom9.geom @@ -1,4 +1,5 @@ photon_energy = 9 keV +clen = 50 mm panel/min_fs = 0 panel/min_ss = 1 panel/max_fs = 0 @@ -7,7 +8,6 @@ panel/fs = x panel/ss = y panel/corner_x = -100 panel/corner_y = -100 -panel/clen = 50 mm panel/res = 1000000 panel/adu_per_photon = 1 panel/data = /data/data_array |