SANS2D: I(Q) for sample and background
Contents
SANS2D: I(Q) for sample and background#
In this notebook, we will be reducing a sample and a background measurements to a one-dimensional \(I(Q)\).
It assumes the detector data has been recorded in event mode, while the monitor data has been histogrammed.
The data used in this notebook has been published in Manasi et al. (2021), and we kindly thank the authors for allowing us to use their data.
Outline:
We will begin by loading the data files containing the sample, direct, and background measurements.
We will then apply some corrections to beamline components specific to the SANS2D beamline.
This will be followed by some masking of some saturated or defect detector pixels
Finally, the sample and background measurement will be converted to the \(Q\) dimension
[1]:
import matplotlib.pyplot as plt
import scipp as sc
from ess import loki, sans
from ess.logging import configure_workflow
import scippneutron as scn
import scippnexus.v2 as snx
from scippnexus.v2.application_definitions import nxcansas
[2]:
logger = configure_workflow('sans2d_reduction', filename='sans2d.log')
Define reduction workflow parameters#
We define here whether to include the effects of gravity, as well as common wavelength and \(Q\) bins for all the measurements.
[3]:
# Include effects of gravity?
gravity = True
# Wavelength binning
wavelength_bins = sc.linspace(
dim='wavelength', start=2.0, stop=16.0, num=141, unit='angstrom'
)
# Q binning
q_bins = sc.linspace(dim='Q', start=0.01, stop=0.5, num=141, unit='1/angstrom')
Loading data files#
We load the following files:
The direct beam function for the main detector (gives detector efficiency as a function of wavelength)
The sample measurement
The direct measurement: this is the run with the empty sample holder/cuvette
The background measurement: this is the run with only the solvent which the sample is placed in
[4]:
direct_beam = sc.io.load_hdf5(
loki.data.get_path('DIRECT_SANS2D_REAR_34327_4m_8mm_16Feb16.hdf5')
)
sample = loki.io.load_sans2d(filename=loki.data.get_path('SANS2D00063114.hdf5'))
direct = loki.io.load_sans2d(filename=loki.data.get_path('SANS2D00063091.hdf5'))
background = loki.io.load_sans2d(filename=loki.data.get_path('SANS2D00063159.hdf5'))
dg = {'sample': sample, 'direct': direct, 'background': background}
Downloading file 'DIRECT_SANS2D_REAR_34327_4m_8mm_16Feb16.hdf5' from 'https://public.esss.dk/groups/scipp/ess/loki/1/DIRECT_SANS2D_REAR_34327_4m_8mm_16Feb16.hdf5' to '/home/runner/.cache/ess/loki/1'.
Downloading file 'SANS2D00063114.hdf5' from 'https://public.esss.dk/groups/scipp/ess/loki/1/SANS2D00063114.hdf5' to '/home/runner/.cache/ess/loki/1'.
Downloading file 'SANS2D00063091.hdf5' from 'https://public.esss.dk/groups/scipp/ess/loki/1/SANS2D00063091.hdf5' to '/home/runner/.cache/ess/loki/1'.
Downloading file 'SANS2D00063159.hdf5' from 'https://public.esss.dk/groups/scipp/ess/loki/1/SANS2D00063159.hdf5' to '/home/runner/.cache/ess/loki/1'.
Pre-process monitor data#
We convert the monitor data from time-of-flight to wavelength, remove background noise, and rebin to the requested wavelength binning using the preprocess_monitor_data
helper function from the i_of_q
submodule:
[5]:
monitors = {}
for key, da in dg.items():
monitors[f'{key}-incident'] = da.attrs["monitor2"].value
monitors[f'{key}-transmission'] = da.attrs["monitor4"].value
# Define range outside of which monitor data is considered to be background
non_background_range = sc.array(
dims=['wavelength'], values=[0.7, 17.1], unit='angstrom'
)
# Run preprocessing
monitors = sans.i_of_q.preprocess_monitor_data(
monitors, non_background_range=non_background_range, wavelength_bins=wavelength_bins
)
# Unpack monitors to make steps below easier
sample_monitors = {
'incident': monitors['sample-incident'],
'transmission': monitors['sample-transmission'],
}
direct_monitors = {
'incident': monitors['direct-incident'],
'transmission': monitors['direct-transmission'],
}
background_monitors = {
'incident': monitors['background-incident'],
'transmission': monitors['background-transmission'],
}
Masking bad detector pixels#
Note: We use programmatic masks here and not those stored in xml files.
Now that the monitor data is cleaned and binned to the correct wavelength range, we turn to the detector data. The first step is to mask noisy and saturated pixels. We mask the edges of the square-shaped detector panel with a simple distance relation. We also mask the region close to the beam center, where the sample holder is visible as a dark patch with an arm extending to the north-east.
[6]:
mask_edges = (
sc.abs(sample.coords['position'].fields.x) > sc.scalar(0.48, unit='m')
) | (sc.abs(sample.coords['position'].fields.y) > sc.scalar(0.45, unit='m'))
summed = sample.sum('tof')
holder_mask = (
(summed.data < sc.scalar(100, unit='counts'))
& (sample.coords['position'].fields.x > sc.scalar(0, unit='m'))
& (sample.coords['position'].fields.x < sc.scalar(0.42, unit='m'))
& (sample.coords['position'].fields.y < sc.scalar(0.05, unit='m'))
& (sample.coords['position'].fields.y > sc.scalar(-0.15, unit='m'))
)
for da in dg.values():
da.masks['edges'] = mask_edges
da.masks['holder_mask'] = holder_mask
A good sanity check is to view the masks on the instrument view:
[7]:
scn.instrument_view(sample.hist(), pixel_size=0.0075)
[7]:
Beam center finder#
The beam is not guaranteed to travel through the center of the detector panel, and we thus have to apply a horizontal and vertical offset to our pixel positions so that the beam centre is at x = y = 0
. This is necessary for subsequent azimuthal averaging of the data counts into \(Q\) bins.
The beam_center
utility in the sans
module is designed for this. It requires us to define a \(Q\) range over which convergence will be checked.
[8]:
q_range = sc.linspace('Q', 0.02, 0.3, 71, unit='1/angstrom')
center = sans.beam_center(
data=dg['sample'],
data_monitors=sample_monitors,
direct_monitors=direct_monitors,
wavelength_bins=wavelength_bins,
q_bins=q_range,
gravity=gravity,
)
print(center)
# Now shift pixels positions to get the correct beam center
for da in dg.values():
da.coords['position'] -= center
<scipp.Variable> () vector3 [m] (0.0945643, -0.082074, 0)
Mask Bragg peaks in wavelength#
We will now take out the time regions with Bragg peaks from the beam stop and detector window, although in reality the peaks appear only close to the beam stop, and will make little difference to \(I(Q)\).
This could be implemented as masking specific time bins for a specific region in space, but for now we keep it simple.
[9]:
wavelength_mask = sc.DataArray(
data=sc.array(dims=['wavelength'], values=[True]),
coords={
'wavelength': sc.array(
dims=['wavelength'], values=[2.21, 2.59], unit='angstrom'
)
},
)
Use to_I_of_Q workflow#
We now reduce the sample and the background measurements to Q
using the sans.to_I_of_Q
workflow.
In that process, the intensity as a function of Q
is normalized using the direct measurement and direct beam function.
We call the workflow on both the sample and background runs:
[10]:
sample_q = sans.to_I_of_Q(
data=dg['sample'],
data_monitors=sample_monitors,
direct_monitors=direct_monitors,
direct_beam=direct_beam,
wavelength_bins=wavelength_bins,
q_bins=q_bins,
gravity=gravity,
wavelength_mask=wavelength_mask,
)
sample_q.hist().plot()
[2024-04-03T11:19:15+0000] WARNING <scipp.ess.sans> :
An interpolation was performed on the direct_beam function. The variances in the direct_beam function have been dropped.
[10]:
[11]:
background_q = sans.to_I_of_Q(
data=dg['background'],
data_monitors=background_monitors,
direct_monitors=direct_monitors,
direct_beam=direct_beam,
wavelength_bins=wavelength_bins,
q_bins=q_bins,
gravity=gravity,
wavelength_mask=wavelength_mask,
)
background_q.hist().plot()
[2024-04-03T11:19:16+0000] WARNING <scipp.ess.sans> :
An interpolation was performed on the direct_beam function. The variances in the direct_beam function have been dropped.
[11]:
We are now in a position to subtract the background from the sample measurement:
[12]:
result = sample_q.bins.sum() - background_q.bins.sum()
result
[12]:
- Q: 140
- L1()float64m19.334
Values:
array(19.334) - Q(Q [bin-edge])float641/Å0.01, 0.013, ..., 0.496, 0.5
Values:
array([0.01 , 0.0135, 0.017 , 0.0205, 0.024 , 0.0275, 0.031 , 0.0345, 0.038 , 0.0415, 0.045 , 0.0485, 0.052 , 0.0555, 0.059 , 0.0625, 0.066 , 0.0695, 0.073 , 0.0765, 0.08 , 0.0835, 0.087 , 0.0905, 0.094 , 0.0975, 0.101 , 0.1045, 0.108 , 0.1115, 0.115 , 0.1185, 0.122 , 0.1255, 0.129 , 0.1325, 0.136 , 0.1395, 0.143 , 0.1465, 0.15 , 0.1535, 0.157 , 0.1605, 0.164 , 0.1675, 0.171 , 0.1745, 0.178 , 0.1815, 0.185 , 0.1885, 0.192 , 0.1955, 0.199 , 0.2025, 0.206 , 0.2095, 0.213 , 0.2165, 0.22 , 0.2235, 0.227 , 0.2305, 0.234 , 0.2375, 0.241 , 0.2445, 0.248 , 0.2515, 0.255 , 0.2585, 0.262 , 0.2655, 0.269 , 0.2725, 0.276 , 0.2795, 0.283 , 0.2865, 0.29 , 0.2935, 0.297 , 0.3005, 0.304 , 0.3075, 0.311 , 0.3145, 0.318 , 0.3215, 0.325 , 0.3285, 0.332 , 0.3355, 0.339 , 0.3425, 0.346 , 0.3495, 0.353 , 0.3565, 0.36 , 0.3635, 0.367 , 0.3705, 0.374 , 0.3775, 0.381 , 0.3845, 0.388 , 0.3915, 0.395 , 0.3985, 0.402 , 0.4055, 0.409 , 0.4125, 0.416 , 0.4195, 0.423 , 0.4265, 0.43 , 0.4335, 0.437 , 0.4405, 0.444 , 0.4475, 0.451 , 0.4545, 0.458 , 0.4615, 0.465 , 0.4685, 0.472 , 0.4755, 0.479 , 0.4825, 0.486 , 0.4895, 0.493 , 0.4965, 0.5 ]) - gravity()vector3m/s^2[ 0. -9.80665 0. ]
Values:
array([ 0. , -9.80665, 0. ]) - incident_beam()vector3m[ 0. 0. 19.334]
Values:
array([ 0. , 0. , 19.334]) - pixel_height()float64m0.002033984375
Values:
array(0.00203398) - pixel_width()float64m0.0035
Values:
array(0.0035) - sample_position()vector3m[ 0. 0. 19.334]
Values:
array([ 0. , 0. , 19.334]) - source_position()vector3m[0. 0. 0.]
Values:
array([0., 0., 0.]) - wavelength(wavelength)float64Å2.0, 16.0
Values:
array([ 2., 16.])
- (Q)float32𝟙161.78444, 165.29965, ..., 13.476799, 15.517735σ = 1.3260165, 1.042895, ..., 1.7960951, 1.967876
Values:
array([161.78444 , 165.29965 , 171.25478 , 175.2563 , 183.40327 , 193.42014 , 201.35278 , 210.56567 , 224.33945 , 238.68176 , 258.84473 , 280.33835 , 305.01505 , 333.4955 , 364.42712 , 395.85257 , 422.90314 , 444.27954 , 450.4084 , 437.84937 , 408.74414 , 363.2295 , 311.37177 , 259.4588 , 211.42996 , 171.83272 , 139.6375 , 113.08425 , 92.71926 , 76.140686 , 63.164036 , 53.819695 , 45.84127 , 39.518814 , 34.46906 , 30.297415 , 27.540356 , 24.990686 , 22.95015 , 21.41086 , 20.077946 , 19.107616 , 18.784996 , 18.306068 , 17.741531 , 17.434677 , 17.040321 , 17.305439 , 16.861364 , 17.095934 , 16.935135 , 16.988256 , 16.779318 , 16.45695 , 16.720547 , 16.50543 , 16.669086 , 16.250322 , 15.979316 , 15.868567 , 16.228926 , 15.8302765, 15.760885 , 15.847942 , 16.119442 , 15.979694 , 15.376701 , 15.274389 , 15.412689 , 15.579598 , 15.159598 , 15.252158 , 15.422558 , 14.860669 , 14.897312 , 14.890955 , 15.219356 , 14.922459 , 15.021738 , 14.841351 , 14.342807 , 15.210317 , 14.133667 , 14.853384 , 14.653447 , 14.537657 , 15.254662 , 15.20522 , 15.434814 , 14.29929 , 15.423164 , 14.142195 , 14.816057 , 14.703209 , 14.68547 , 15.237367 , 15.839544 , 14.801003 , 14.4092865, 14.763835 , 15.466315 , 14.936306 , 15.2029705, 14.175878 , 15.652899 , 14.543182 , 14.137838 , 14.459902 , 15.416008 , 14.654943 , 14.505656 , 15.005402 , 14.195094 , 14.022969 , 14.150953 , 14.497314 , 13.856966 , 14.14429 , 14.861629 , 14.229111 , 13.331196 , 14.930405 , 14.17462 , 15.687802 , 13.055973 , 15.397145 , 14.307382 , 15.312213 , 14.023117 , 14.753797 , 14.785855 , 12.179808 , 13.155926 , 12.271888 , 10.933204 , 14.237772 , 13.778609 , 11.915322 , 13.476799 , 15.517735 ], dtype=float32)
Variances (σ²):
array([1.7583197 , 1.0876298 , 0.8152003 , 0.67626584, 0.60469294, 0.55829257, 0.5168169 , 0.48769057, 0.47252294, 0.46340716, 0.46652868, 0.4735413 , 0.48509178, 0.502195 , 0.52430487, 0.54558456, 0.5605339 , 0.5708923 , 0.5611004 , 0.5319528 , 0.485764 , 0.42330873, 0.35715216, 0.29282087, 0.23640609, 0.1906748 , 0.15405802, 0.12467595, 0.10203931, 0.08396456, 0.07004694, 0.06011045, 0.051602 , 0.04508053, 0.03968527, 0.03563153, 0.03287712, 0.03022594, 0.02822677, 0.02693907, 0.02573748, 0.02510064, 0.02502436, 0.02478819, 0.02459623, 0.02467373, 0.02469771, 0.02540914, 0.02544596, 0.02625924, 0.02677828, 0.02764825, 0.02789999, 0.02838071, 0.02963788, 0.03025249, 0.03121522, 0.03171728, 0.0322886 , 0.03318183, 0.03476194, 0.03566809, 0.03654954, 0.03792671, 0.04019926, 0.04164233, 0.04139678, 0.04311093, 0.04495625, 0.0473176 , 0.04678401, 0.04951651, 0.0517948 , 0.05379223, 0.05454113, 0.05685369, 0.06056976, 0.06246104, 0.06576307, 0.06767666, 0.0691793 , 0.07796361, 0.07639227, 0.08372991, 0.0880893 , 0.09333858, 0.10204349, 0.1066614 , 0.11879715, 0.12010423, 0.13256356, 0.13131465, 0.14859737, 0.15892981, 0.16893926, 0.18539147, 0.2147794 , 0.20608588, 0.22680768, 0.24627978, 0.26227814, 0.28425866, 0.29928806, 0.30683067, 0.36096698, 0.34571573, 0.37534234, 0.37558445, 0.4531969 , 0.45728898, 0.48383632, 0.5232283 , 0.5289032 , 0.54186743, 0.61048144, 0.6574644 , 0.6260512 , 0.68812996, 0.7724814 , 0.813479 , 0.82270044, 0.9434157 , 0.97440815, 1.1310067 , 1.0624584 , 1.3480734 , 1.3999326 , 1.522354 , 1.6545621 , 1.7093427 , 1.9869848 , 1.7573869 , 1.906035 , 2.291194 , 1.7023892 , 2.6989024 , 2.7843099 , 2.5185847 , 3.2259579 , 3.872536 ], dtype=float32)
- current_period()int64𝟙1
Values:
array(1) - experiment_identifier()string𝟙1920676
Values:
'1920676' - instrument_name()stringSANS2D
Values:
'SANS2D' - measurement_id()string𝟙
Values:
'' - measurement_label()string𝟙
Values:
'' - measurement_subid()string𝟙
Values:
'' - measurement_type()string𝟙
Values:
'' - nperiods()int64𝟙1
Values:
array(1) - placeholder monitor_5()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 5 - placeholder monitor_6()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 6 - placeholder monitor_7()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 7 - placeholder monitor_8()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 8
[13]:
fig1, ax1 = plt.subplots(1, 2, figsize=(10, 4))
sc.plot(result, ax=ax1[0])
sc.plot(result, norm='log', ax=ax1[1])
[13]:
Note
Instead of .bins.sum()
, one could use sc.histogram()
above to define different Q
bins compared to the ones defined at the top of the notebook. This can be done in event mode, see here.
There may be performance advantages to first use a coarse Q
binning when the computing I(Q)
numerator, and use finer binning for the final results.
Wavelength bands#
It is often useful to process the data in a small number (~10) of separate wavelength bands.
This can be achieved by requesting 10 bands from the to_I_of_Q
workflow via the wavelength_bands
argument.
[14]:
wavelength_bands = sc.linspace(
dim='wavelength', start=2.0, stop=16.0, num=11, unit='angstrom'
)
sample_slices = sans.to_I_of_Q(
data=dg['sample'],
data_monitors=sample_monitors,
direct_monitors=direct_monitors,
direct_beam=direct_beam,
wavelength_bins=wavelength_bins,
q_bins=q_bins,
gravity=gravity,
wavelength_bands=wavelength_bands,
wavelength_mask=wavelength_mask,
)
background_slices = sans.to_I_of_Q(
data=dg['background'],
data_monitors=background_monitors,
direct_monitors=direct_monitors,
direct_beam=direct_beam,
wavelength_bins=wavelength_bins,
q_bins=q_bins,
gravity=gravity,
wavelength_bands=wavelength_bands,
wavelength_mask=wavelength_mask,
)
result_slices = sample_slices.bins.sum() - background_slices.bins.sum()
result_slices
[2024-04-03T11:19:18+0000] WARNING <scipp.ess.sans> :
An interpolation was performed on the direct_beam function. The variances in the direct_beam function have been dropped.
[2024-04-03T11:19:19+0000] WARNING <scipp.ess.sans> :
An interpolation was performed on the direct_beam function. The variances in the direct_beam function have been dropped.
[14]:
- Q: 140
- wavelength: 10
- L1()float64m19.334
Values:
array(19.334) - Q(Q [bin-edge])float641/Å0.01, 0.013, ..., 0.496, 0.5
Values:
array([0.01 , 0.0135, 0.017 , 0.0205, 0.024 , 0.0275, 0.031 , 0.0345, 0.038 , 0.0415, 0.045 , 0.0485, 0.052 , 0.0555, 0.059 , 0.0625, 0.066 , 0.0695, 0.073 , 0.0765, 0.08 , 0.0835, 0.087 , 0.0905, 0.094 , 0.0975, 0.101 , 0.1045, 0.108 , 0.1115, 0.115 , 0.1185, 0.122 , 0.1255, 0.129 , 0.1325, 0.136 , 0.1395, 0.143 , 0.1465, 0.15 , 0.1535, 0.157 , 0.1605, 0.164 , 0.1675, 0.171 , 0.1745, 0.178 , 0.1815, 0.185 , 0.1885, 0.192 , 0.1955, 0.199 , 0.2025, 0.206 , 0.2095, 0.213 , 0.2165, 0.22 , 0.2235, 0.227 , 0.2305, 0.234 , 0.2375, 0.241 , 0.2445, 0.248 , 0.2515, 0.255 , 0.2585, 0.262 , 0.2655, 0.269 , 0.2725, 0.276 , 0.2795, 0.283 , 0.2865, 0.29 , 0.2935, 0.297 , 0.3005, 0.304 , 0.3075, 0.311 , 0.3145, 0.318 , 0.3215, 0.325 , 0.3285, 0.332 , 0.3355, 0.339 , 0.3425, 0.346 , 0.3495, 0.353 , 0.3565, 0.36 , 0.3635, 0.367 , 0.3705, 0.374 , 0.3775, 0.381 , 0.3845, 0.388 , 0.3915, 0.395 , 0.3985, 0.402 , 0.4055, 0.409 , 0.4125, 0.416 , 0.4195, 0.423 , 0.4265, 0.43 , 0.4335, 0.437 , 0.4405, 0.444 , 0.4475, 0.451 , 0.4545, 0.458 , 0.4615, 0.465 , 0.4685, 0.472 , 0.4755, 0.479 , 0.4825, 0.486 , 0.4895, 0.493 , 0.4965, 0.5 ]) - gravity()vector3m/s^2[ 0. -9.80665 0. ]
Values:
array([ 0. , -9.80665, 0. ]) - incident_beam()vector3m[ 0. 0. 19.334]
Values:
array([ 0. , 0. , 19.334]) - pixel_height()float64m0.002033984375
Values:
array(0.00203398) - pixel_width()float64m0.0035
Values:
array(0.0035) - sample_position()vector3m[ 0. 0. 19.334]
Values:
array([ 0. , 0. , 19.334]) - source_position()vector3m[0. 0. 0.]
Values:
array([0., 0., 0.]) - wavelength(wavelength [bin-edge])float64Å2.0, 3.4, ..., 14.6, 16.0
Values:
array([ 2. , 3.4, 4.8, 6.2, 7.6, 9. , 10.4, 11.8, 13.2, 14.6, 16. ])
- (Q, wavelength)float32𝟙95.59793, 129.73592, ..., 0.0, 0.0σ = 16.669903, 3.2071216, ..., 0.0, 0.0
Values:
array([[ 95.59793 , 129.73592 , 152.61768 , ..., 187.0749 , 181.9613 , 196.12837 ], [114.29981 , 153.99359 , 167.6352 , ..., 178.72124 , 186.442 , 191.61877 ], [141.40605 , 168.64348 , 171.59222 , ..., 181.55257 , 202.8205 , 200.87894 ], ..., [ 11.915322, 0. , 0. , ..., 0. , 0. , 0. ], [ 13.476799, 0. , 0. , ..., 0. , 0. , 0. ], [ 15.517735, 0. , 0. , ..., 0. , 0. , 0. ]], dtype=float32)
Variances (σ²):
array([[277.88568 , 10.285629 , 5.9534698, ..., 45.006645 , 64.12296 , 97.744064 ], [ 16.891293 , 4.0625243, 4.577567 , ..., 33.06983 , 49.57422 , 73.468575 ], [ 6.2256346, 3.128347 , 3.7712398, ..., 27.112074 , 43.547905 , 62.603054 ], ..., [ 2.5185847, 0. , 0. , ..., 0. , 0. , 0. ], [ 3.2259579, 0. , 0. , ..., 0. , 0. , 0. ], [ 3.872536 , 0. , 0. , ..., 0. , 0. , 0. ]], dtype=float32)
- current_period()int64𝟙1
Values:
array(1) - experiment_identifier()string𝟙1920676
Values:
'1920676' - instrument_name()stringSANS2D
Values:
'SANS2D' - measurement_id()string𝟙
Values:
'' - measurement_label()string𝟙
Values:
'' - measurement_subid()string𝟙
Values:
'' - measurement_type()string𝟙
Values:
'' - nperiods()int64𝟙1
Values:
array(1) - placeholder monitor_5()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 5 - placeholder monitor_6()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 6 - placeholder monitor_7()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 7 - placeholder monitor_8()DataArray{dims=[tof: 481], unit=counts, coords=[tof, position, source_position]}
Values:
<scipp.DataArray> Dimensions: Sizes[tof:481, ] Coordinates: * position vector3 [m] () (0, 0, 0) * source_position vector3 [m] () (0, 0, 0) * tof float64 [µs] (tof [bin-edge]) [5.5, 50, ..., 99750, 100005] Data: float64 [counts] (tof) [0, 0, ..., 0, 0] [0, 0, ..., 0, 0] Attributes: instrument_name string <no unit> () "SANS2D" sample_position vector3 [m] () (0, 0, 19.281) spectrum int32 <no unit> () 8
[15]:
collapsed = sc.collapse(result_slices, keep='Q')
fig2, ax2 = plt.subplots(1, 2, figsize=(10, 4))
sc.plot(collapsed, ax=ax2[0])
sc.plot(collapsed, norm='log', ax=ax2[1])
/home/runner/micromamba/envs/ess-developer/lib/python3.8/site-packages/matplotlib/axes/_axes.py:3642: RuntimeWarning: invalid value encountered in add
low, high = dep + np.row_stack([-(1 - lolims), 1 - uplims]) * err
[15]:
Saving reduced data to file#
Finally, we can save reduced data to the file. Below there is an example of saving data for full range into NXcanSAS format (NeXus compatible)
[16]:
result.coords['Q'] = sc.midpoints(result.coords['Q'])
with snx.File('test.nxs', 'w') as f:
f['sasentry'] = nxcansas.SASentry(title='hd-DES_10_h-C16EO8', run=63114)
f['sasentry']['sasdata'] = nxcansas.SASdata(result, Q_variances='resolutions')
References#
Manasi I., Andalibi M. R., Atri R. S., Hooton J., King S. M., Edler K. J., 2021, Self-assembly of ionic and non-ionic surfactants in type IV cerium nitrate and urea based deep eutectic solvent, J. Chem. Phys. 155, 084902