Analyzing HRIXS data¶
HRIXS spectra are, at the base, one dimensional spectra. They are recorded on a 2 D camera. The complication is that due to abberations, the spectra do not show up as straight lines on the camera, but are curved. These abberations need to be corrected for data analyis.
We start with importing all necessary:
[1]:
import numpy as np
import xarray as xa
import matplotlib.pyplot as plt
%matplotlib inline
%load_ext autoreload
%autoreload 2
from toolbox_scs.detectors.hrixs import hRIXS
Setting the stage¶
we start by creating an hRIXS object. It contains all the gory details about the experiment, but no data.
All those parameters need to be carefully calibrated whenever the spectrometer is moved, usually at the beginning of a beamtime.
[2]:
h = hRIXS()
h.PROPOSAL = 3154 # the current proposal number
h.Y_RANGE = slice(700, 900) # the range of the camera the data is in. Y is the "energy" axis
h.CURVE_B = -3.695346575286939e-07 # the curvature as determined elsewhere (see later)
h.CURVE_A = 0.024084479232443695
h.ENERGY_SLOPE = 0.018387 # the energy calibration
h.ENERGY_INTERCEPT = 498.27
h.STD_THRESHOLD = 3.5 # threshold above which a peak is considered a peak, in standard deviations above noise level
reading the data¶
now we can read the data. There are two different ways to analyze the data: for low intensities, we can do single photon counting, for high intensities as simple integration is better. No matter which method, all data is read into an xarray DataSet, and further treated therein.
Centroiding¶
The centroiding algorithm then finds single photons, creates as spectrum and adds that to the DataSet. The parameters for the centroiding only need to be set once.
[3]:
data = h.from_run(2) # just load run No 2
h.BINS = 500 # number of bins to centroid into
h.centroid(data)
[3]:
<xarray.Dataset> Dimensions: (energy: 500, trainId: 6, x: 2048, y: 2048) Coordinates: * trainId (trainId) uint64 1531618246 1531618389 ... 1531618962 * energy (energy) float64 511.1 511.1 511.2 511.2 ... 514.8 514.8 514.8 Dimensions without coordinates: x, y Data variables: hRIXS_det (trainId, x, y) uint16 595 561 595 588 603 ... 625 645 630 635 hRIXS_index (trainId) int32 6 6 6 6 6 6 hRIXS_delay (trainId) float32 0.15 0.15 0.15 0.15 0.15 0.15 hRIXS_norm (trainId) float32 7.0124035 7.4794917 ... 5.220501 4.259891 spectrum (trainId, energy) float64 0.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0 Attributes: runFolder: /gpfs/exfel/exp/SCS/202202/p003154/raw/r0002
- energy: 500
- trainId: 6
- x: 2048
- y: 2048
- trainId(trainId)uint641531618246 ... 1531618962
array([1531618246, 1531618389, 1531618533, 1531618676, 1531618819, 1531618962], dtype=uint64)
- energy(energy)float64511.1 511.1 511.2 ... 514.8 514.8
array([511.1409 , 511.14827 , 511.155639, ..., 514.803561, 514.81093 , 514.8183 ])
- hRIXS_det(trainId, x, y)uint16595 561 595 588 ... 625 645 630 635
array([[[595, 561, 595, ..., 728, 710, 706], [686, 623, 704, ..., 665, 654, 639], [616, 584, 622, ..., 646, 639, 638], ..., [597, 549, 602, ..., 644, 633, 630], [623, 556, 585, ..., 610, 628, 630], [616, 540, 586, ..., 646, 615, 650]], [[601, 542, 595, ..., 713, 742, 687], [682, 646, 691, ..., 633, 653, 652], [620, 583, 629, ..., 624, 650, 641], ..., [613, 567, 592, ..., 622, 629, 625], [615, 556, 589, ..., 637, 619, 632], [599, 558, 605, ..., 633, 650, 625]], [[597, 552, 577, ..., 720, 724, 708], [716, 627, 693, ..., 618, 640, 647], [624, 589, 606, ..., 635, 646, 642], ..., ... ..., [607, 545, 582, ..., 614, 633, 636], [627, 568, 577, ..., 631, 645, 640], [608, 558, 591, ..., 646, 633, 641]], [[617, 548, 594, ..., 725, 732, 700], [720, 647, 685, ..., 649, 629, 653], [633, 592, 606, ..., 648, 633, 650], ..., [614, 562, 561, ..., 632, 637, 625], [620, 563, 597, ..., 637, 637, 631], [595, 539, 586, ..., 639, 645, 619]], [[628, 549, 604, ..., 735, 715, 722], [712, 634, 676, ..., 649, 655, 668], [604, 586, 600, ..., 622, 645, 630], ..., [615, 554, 597, ..., 625, 637, 636], [608, 556, 577, ..., 644, 624, 619], [607, 567, 575, ..., 645, 630, 635]]], dtype=uint16)
- hRIXS_index(trainId)int326 6 6 6 6 6
array([6, 6, 6, 6, 6, 6], dtype=int32)
- hRIXS_delay(trainId)float320.15 0.15 0.15 0.15 0.15 0.15
array([0.15, 0.15, 0.15, 0.15, 0.15, 0.15], dtype=float32)
- hRIXS_norm(trainId)float327.0124035 7.4794917 ... 4.259891
array([7.0124035, 7.4794917, 6.268197 , 7.865573 , 5.220501 , 4.259891 ], dtype=float32)
- spectrum(trainId, energy)float640.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0
array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]])
- runFolder :
- /gpfs/exfel/exp/SCS/202202/p003154/raw/r0002
Integration¶
for higher intensities, when single photons are not visible anymore, we just integrate over pixels with the same energy.
[4]:
data = h.from_run(2) # just load run No 2
h.integrate(data)
[4]:
<xarray.Dataset> Dimensions: (energy: 180, trainId: 6, x: 2048, y: 2048) Coordinates: * trainId (trainId) uint64 1531618246 1531618389 ... 1531618962 * energy (energy) float64 511.3 511.3 511.4 511.4 ... 514.6 514.6 514.6 Dimensions without coordinates: x, y Data variables: hRIXS_det (trainId, x, y) uint16 595 561 595 588 603 ... 625 645 630 635 hRIXS_index (trainId) int32 6 6 6 6 6 6 hRIXS_delay (trainId) float32 0.15 0.15 0.15 0.15 0.15 0.15 hRIXS_norm (trainId) float32 7.0124035 7.4794917 ... 5.220501 4.259891 spectrum (trainId, energy) float64 637.9 638.8 638.6 ... 640.0 639.3 Attributes: runFolder: /gpfs/exfel/exp/SCS/202202/p003154/raw/r0002
- energy: 180
- trainId: 6
- x: 2048
- y: 2048
- trainId(trainId)uint641531618246 ... 1531618962
array([1531618246, 1531618389, 1531618533, 1531618676, 1531618819, 1531618962], dtype=uint64)
- energy(energy)float64511.3 511.3 511.4 ... 514.6 514.6
array([511.32477 , 511.343157, 511.361544, 511.379931, 511.398318, 511.416705, 511.435092, 511.453479, 511.471866, 511.490253, 511.50864 , 511.527027, 511.545414, 511.563801, 511.582188, 511.600575, 511.618962, 511.637349, 511.655736, 511.674123, 511.69251 , 511.710897, 511.729284, 511.747671, 511.766058, 511.784445, 511.802832, 511.821219, 511.839606, 511.857993, 511.87638 , 511.894767, 511.913154, 511.931541, 511.949928, 511.968315, 511.986702, 512.005089, 512.023476, 512.041863, 512.06025 , 512.078637, 512.097024, 512.115411, 512.133798, 512.152185, 512.170572, 512.188959, 512.207346, 512.225733, 512.24412 , 512.262507, 512.280894, 512.299281, 512.317668, 512.336055, 512.354442, 512.372829, 512.391216, 512.409603, 512.42799 , 512.446377, 512.464764, 512.483151, 512.501538, 512.519925, 512.538312, 512.556699, 512.575086, 512.593473, 512.61186 , 512.630247, 512.648634, 512.667021, 512.685408, 512.703795, 512.722182, 512.740569, 512.758956, 512.777343, 512.79573 , 512.814117, 512.832504, 512.850891, 512.869278, 512.887665, 512.906052, 512.924439, 512.942826, 512.961213, 512.9796 , 512.997987, 513.016374, 513.034761, 513.053148, 513.071535, 513.089922, 513.108309, 513.126696, 513.145083, 513.16347 , 513.181857, 513.200244, 513.218631, 513.237018, 513.255405, 513.273792, 513.292179, 513.310566, 513.328953, 513.34734 , 513.365727, 513.384114, 513.402501, 513.420888, 513.439275, 513.457662, 513.476049, 513.494436, 513.512823, 513.53121 , 513.549597, 513.567984, 513.586371, 513.604758, 513.623145, 513.641532, 513.659919, 513.678306, 513.696693, 513.71508 , 513.733467, 513.751854, 513.770241, 513.788628, 513.807015, 513.825402, 513.843789, 513.862176, 513.880563, 513.89895 , 513.917337, 513.935724, 513.954111, 513.972498, 513.990885, 514.009272, 514.027659, 514.046046, 514.064433, 514.08282 , 514.101207, 514.119594, 514.137981, 514.156368, 514.174755, 514.193142, 514.211529, 514.229916, 514.248303, 514.26669 , 514.285077, 514.303464, 514.321851, 514.340238, 514.358625, 514.377012, 514.395399, 514.413786, 514.432173, 514.45056 , 514.468947, 514.487334, 514.505721, 514.524108, 514.542495, 514.560882, 514.579269, 514.597656, 514.616043])
- hRIXS_det(trainId, x, y)uint16595 561 595 588 ... 625 645 630 635
array([[[595, 561, 595, ..., 728, 710, 706], [686, 623, 704, ..., 665, 654, 639], [616, 584, 622, ..., 646, 639, 638], ..., [597, 549, 602, ..., 644, 633, 630], [623, 556, 585, ..., 610, 628, 630], [616, 540, 586, ..., 646, 615, 650]], [[601, 542, 595, ..., 713, 742, 687], [682, 646, 691, ..., 633, 653, 652], [620, 583, 629, ..., 624, 650, 641], ..., [613, 567, 592, ..., 622, 629, 625], [615, 556, 589, ..., 637, 619, 632], [599, 558, 605, ..., 633, 650, 625]], [[597, 552, 577, ..., 720, 724, 708], [716, 627, 693, ..., 618, 640, 647], [624, 589, 606, ..., 635, 646, 642], ..., ... ..., [607, 545, 582, ..., 614, 633, 636], [627, 568, 577, ..., 631, 645, 640], [608, 558, 591, ..., 646, 633, 641]], [[617, 548, 594, ..., 725, 732, 700], [720, 647, 685, ..., 649, 629, 653], [633, 592, 606, ..., 648, 633, 650], ..., [614, 562, 561, ..., 632, 637, 625], [620, 563, 597, ..., 637, 637, 631], [595, 539, 586, ..., 639, 645, 619]], [[628, 549, 604, ..., 735, 715, 722], [712, 634, 676, ..., 649, 655, 668], [604, 586, 600, ..., 622, 645, 630], ..., [615, 554, 597, ..., 625, 637, 636], [608, 556, 577, ..., 644, 624, 619], [607, 567, 575, ..., 645, 630, 635]]], dtype=uint16)
- hRIXS_index(trainId)int326 6 6 6 6 6
array([6, 6, 6, 6, 6, 6], dtype=int32)
- hRIXS_delay(trainId)float320.15 0.15 0.15 0.15 0.15 0.15
array([0.15, 0.15, 0.15, 0.15, 0.15, 0.15], dtype=float32)
- hRIXS_norm(trainId)float327.0124035 7.4794917 ... 4.259891
array([7.0124035, 7.4794917, 6.268197 , 7.865573 , 5.220501 , 4.259891 ], dtype=float32)
- spectrum(trainId, energy)float64637.9 638.8 638.6 ... 640.0 639.3
array([[637.94752893, 638.79049542, 638.58968001, ..., 638.04656365, 638.42933004, 638.79161647], [638.62429325, 638.57901241, 638.42418185, ..., 637.79115906, 638.74806385, 639.28137786], [638.29826953, 638.42261666, 638.272642 , ..., 638.53740214, 638.37720303, 639.02509478], [638.99940487, 638.91825579, 638.84920975, ..., 639.00820865, 639.11737212, 638.81298841], [638.37130646, 638.27148812, 638.3679324 , ..., 638.65410763, 638.87997339, 638.91133286], [639.39048973, 639.2276897 , 639.12638728, ..., 639.76092019, 639.95871205, 639.25183164]])
- runFolder :
- /gpfs/exfel/exp/SCS/202202/p003154/raw/r0002
Plotting¶
we employ xarray also for plotting. As a first example, we just integrate over all trains in a run, thus ignoring any possible delay or energy scan.
[5]:
agg = h.aggregate(data) # sum spectra for all trains
agg.spectrum.plot()
[5]:
[<matplotlib.lines.Line2D at 0x2af499cc1390>]
Delay scans¶
we make full use of xarray to select for parameters we scan over, in this example a pump-probe dela. “hRIXS_index” is an index into the table of delays, as it is an integer it makes it easier to group the data. Ideally, this index should also be used for all other types of scans, like energy scans, this is why the nameOne may then reduce the data, summing all corresponding images.
[6]:
gr = data.groupby('hRIXS_index', squeeze=True)
delays = gr.map(h.aggregate)
delays
[6]:
<xarray.Dataset> Dimensions: (energy: 180, hRIXS_index: 1, x: 2048, y: 2048) Coordinates: * energy (energy) float64 511.3 511.3 511.4 511.4 ... 514.6 514.6 514.6 * hRIXS_index (hRIXS_index) int64 6 Dimensions without coordinates: x, y Data variables: hRIXS_det (hRIXS_index, x, y) uint64 3623 3320 3557 ... 3844 3816 3800 hRIXS_delay (hRIXS_index) float32 0.14999999 hRIXS_norm (hRIXS_index) float32 38.10606 spectrum (hRIXS_index, energy) float64 3.832e+03 3.832e+03 ... 3.834e+03
- energy: 180
- hRIXS_index: 1
- x: 2048
- y: 2048
- energy(energy)float64511.3 511.3 511.4 ... 514.6 514.6
array([511.32477 , 511.343157, 511.361544, 511.379931, 511.398318, 511.416705, 511.435092, 511.453479, 511.471866, 511.490253, 511.50864 , 511.527027, 511.545414, 511.563801, 511.582188, 511.600575, 511.618962, 511.637349, 511.655736, 511.674123, 511.69251 , 511.710897, 511.729284, 511.747671, 511.766058, 511.784445, 511.802832, 511.821219, 511.839606, 511.857993, 511.87638 , 511.894767, 511.913154, 511.931541, 511.949928, 511.968315, 511.986702, 512.005089, 512.023476, 512.041863, 512.06025 , 512.078637, 512.097024, 512.115411, 512.133798, 512.152185, 512.170572, 512.188959, 512.207346, 512.225733, 512.24412 , 512.262507, 512.280894, 512.299281, 512.317668, 512.336055, 512.354442, 512.372829, 512.391216, 512.409603, 512.42799 , 512.446377, 512.464764, 512.483151, 512.501538, 512.519925, 512.538312, 512.556699, 512.575086, 512.593473, 512.61186 , 512.630247, 512.648634, 512.667021, 512.685408, 512.703795, 512.722182, 512.740569, 512.758956, 512.777343, 512.79573 , 512.814117, 512.832504, 512.850891, 512.869278, 512.887665, 512.906052, 512.924439, 512.942826, 512.961213, 512.9796 , 512.997987, 513.016374, 513.034761, 513.053148, 513.071535, 513.089922, 513.108309, 513.126696, 513.145083, 513.16347 , 513.181857, 513.200244, 513.218631, 513.237018, 513.255405, 513.273792, 513.292179, 513.310566, 513.328953, 513.34734 , 513.365727, 513.384114, 513.402501, 513.420888, 513.439275, 513.457662, 513.476049, 513.494436, 513.512823, 513.53121 , 513.549597, 513.567984, 513.586371, 513.604758, 513.623145, 513.641532, 513.659919, 513.678306, 513.696693, 513.71508 , 513.733467, 513.751854, 513.770241, 513.788628, 513.807015, 513.825402, 513.843789, 513.862176, 513.880563, 513.89895 , 513.917337, 513.935724, 513.954111, 513.972498, 513.990885, 514.009272, 514.027659, 514.046046, 514.064433, 514.08282 , 514.101207, 514.119594, 514.137981, 514.156368, 514.174755, 514.193142, 514.211529, 514.229916, 514.248303, 514.26669 , 514.285077, 514.303464, 514.321851, 514.340238, 514.358625, 514.377012, 514.395399, 514.413786, 514.432173, 514.45056 , 514.468947, 514.487334, 514.505721, 514.524108, 514.542495, 514.560882, 514.579269, 514.597656, 514.616043])
- hRIXS_index(hRIXS_index)int646
array([6])
- hRIXS_det(hRIXS_index, x, y)uint643623 3320 3557 ... 3844 3816 3800
array([[[3623, 3320, 3557, ..., 4380, 4378, 4272], [4201, 3823, 4131, ..., 3876, 3913, 3905], [3749, 3543, 3685, ..., 3819, 3856, 3835], ..., [3641, 3348, 3509, ..., 3745, 3798, 3774], [3689, 3361, 3520, ..., 3797, 3787, 3785], [3625, 3301, 3528, ..., 3844, 3816, 3800]]], dtype=uint64)
- hRIXS_delay(hRIXS_index)float320.14999999
array([0.14999999], dtype=float32)
- hRIXS_norm(hRIXS_index)float3238.10606
array([38.10606], dtype=float32)
- spectrum(hRIXS_index, energy)float643.832e+03 3.832e+03 ... 3.834e+03
array([[3831.63129277, 3832.20955811, 3831.63003328, 3831.41054038, 3831.63949212, 3831.30579896, 3831.75793828, 3831.33787609, 3831.09818232, 3831.4891032 , 3831.04815842, 3830.72278012, 3831.75151058, 3831.71726072, 3831.61928781, 3831.24111986, 3830.42367417, 3831.47385247, 3831.76710872, 3831.66167668, 3831.65765351, 3831.21159335, 3831.24785015, 3831.48870923, 3830.98819101, 3831.11392219, 3832.06032167, 3831.42643266, 3831.12159709, 3830.8658899 , 3830.96343873, 3830.56700391, 3831.43024542, 3831.18107421, 3831.90898244, 3832.07559448, 3830.86788831, 3831.04780914, 3832.01239699, 3831.85352729, 3831.66611276, 3831.89966526, 3831.04070421, 3830.72679013, 3831.68876152, 3831.43229215, 3831.21574105, 3831.45706845, 3831.61677892, 3831.81540078, 3831.7531723 , 3830.69690167, 3831.19219516, 3830.80647697, 3830.80187255, 3831.83375806, 3831.04763525, 3830.44470301, 3831.45178376, 3830.20997858, 3830.9671061 , 3831.38661976, 3831.06514235, 3831.27816574, 3831.6367184 , 3831.15371548, 3831.61457093, 3830.83581547, 3830.31876994, 3831.09705016, 3831.07020335, 3831.7513016 , 3831.00632598, 3830.70006033, 3830.937109 , 3830.59763462, 3830.90613262, 3830.62793334, 3830.88599805, 3830.38978147, ... 3831.13174074, 3831.02271075, 3830.04052127, 3830.45349948, 3831.06060205, 3831.1063046 , 3831.00449962, 3830.91165041, 3831.01348142, 3831.27409823, 3830.36255967, 3829.99870354, 3831.1991301 , 3830.96925429, 3830.46297555, 3831.23982503, 3830.2495295 , 3830.00289385, 3831.02884274, 3830.45012192, 3830.82182053, 3831.46062972, 3830.93945168, 3830.81381629, 3831.01357697, 3829.64352725, 3830.29712006, 3831.38656781, 3830.48477985, 3830.68720545, 3830.22338528, 3830.70110065, 3831.54148904, 3831.13732486, 3831.4286333 , 3831.63809527, 3831.61185818, 3830.81552656, 3831.69046809, 3830.9980216 , 3830.27712997, 3830.27265272, 3830.71904377, 3832.06694195, 3832.16034521, 3831.56515548, 3832.20846743, 3832.59327813, 3833.01108178, 3833.87667662, 3833.54012543, 3834.11568055, 3834.40318046, 3834.78819934, 3834.71665809, 3833.86690128, 3835.08039973, 3834.96172145, 3834.67983078, 3834.10781392, 3832.53901142, 3832.06430421, 3832.16951563, 3830.92469426, 3831.58052226, 3831.40091498, 3829.88547013, 3830.15941306, 3830.01320729, 3830.2633882 , 3831.70675429, 3830.87512839, 3832.25028773, 3831.27545121, 3831.83342082, 3833.44117205, 3831.16106349, 3831.79836132, 3833.51065449, 3834.07424202]])
Instead of reducing all data at once, one can also just look at one delay. The first axis (the 0 in the example) is the index in the delay scan table, so the 0 means: take the data for the 0th delay in the list of delays.
[7]:
delays.spectrum[0, :].plot()
[7]:
[<matplotlib.lines.Line2D at 0x2af49a02fc18>]
adding up several runs¶
Data of different runs can be concatenated
[8]:
data2 = h.from_run(3)
data2 = h.centroid(data2)
datas = xa.concat((data, data2), 'trainId')
finding the curvature¶
there is an automatic procedure to find the curvature for an HRIXS operation point. The method find_curvature
takes a run, integrates the images and fits the curvature parameters to it. During the fit, it will use the current curvature as starting values. It outputs the new curvature parameters, together with a plot of the curvature overlayed on top of the data, where the starting values are shown in blue, while the fitted curve is in orange.
[9]:
h.Y_RANGE = slice(700, 900) # tell the algorithm where the data actually is
h.find_curvature(1, 3485) # use run 1 of proposal 3485 to fit the curvature
[9]:
(0.01934392725990066, -3.2404000959549933e-07)