Quasi Elastic Neutron Scattering model library

. This paper reports on the development of a collection of dynamical models of one-dimensional peak proﬁle functions used to ﬁt dynamic structure factors S ( Q , (cid:126) ω ) of Quasi Elastic Neutron Scattering (QENS) data. The objective of this development is to create a maintainable and interoperable Python library with models reusable in other projects related to the analysis of data from Quasi Elastic Neutron Scattering experiments. The ambition is that the library also will serve as a platform where scientists can make their models available for others. We illustrate how the library can be used by newcomers to the ﬁeld as well as by experts via di ﬀ erent examples. These examples, provided as Jupyter notebooks, show how the QENS models can be integrated in the whole QENS data processing pipeline.


Motivation and significance
Quasi elastic Neutron Scattering (QENS) is a neutron scattering technique to probe displacements in temporal and spatial scales, typically from pico-to tens of nanoseconds and from Ångströms to nanometres, respectively.In this technique one measures the dynamic structure factor S (Q, ω) around the elastic line with ω = 0.Here Q is the momentum exchange between the neutron and the investigated sample and ω is the energy transfer.The broadening of the elastic peak can be related to diffusive stochastic motions taking place in the sample, including translational diffusion (both unconstrained long-range translations and confined translation), molecular reorientations, localised motions (e.g., methyl rotations), etc. 1  Correspondingly, QENS finds applications in various scientific domains, such as biology (e.g., to explore the dynamics of proteins) [5,6], soft-matter (e.g., to investigate different relaxation modes in polymers) [7,8] or materials science (e.g., to probe H-diffusion in hydrogen storage materials) [9], among others.Each type of motion is characterised by a specific Q-dependence of the intensity and line-width of the quasi elastic signal for a given Q, which can be represented by an analytical model.Therefore, a large series of analytical models corresponding to the different types of motions mentioned above exist and can be used to fit the experimental data in order to extract the relevant physical parameters (e.g., self-diffusion constants, residence times, jump lengths, etc.) from the QENS spectra [1].
The QENS library makes a range of these mathematical models freely available to practitioners of QENS and developers of QENS analysis software in a format that makes them inter-operable and reusable.As an opensource library, the implementations can be scrutinised and validated by peers, and scientists are encouraged to add their own models to make them available for the QENS community at large.
The QENS library at its core provides Python models of mainly one-dimensional (1D) line profiles to fit experimental or simulated S (Q, ω ≈ 0) data.This work was part of SINE2020 Work Package 10 on Data Treatment [10] to develop a comprehensive library of dynamical models in order to increase interoperability and reusability, for instance for rapid prototyping.The library provides different building blocks that users can combine, convolute and plug into different frameworks for visualizing or fitting.
Our approach is similar to that implemented by the SasView [11] developer community for small angle scattering with its SasView Marketplace [12].
The library is written in Python and depends on standard scientific Python modules (i.e., scipy [13] and numpy [14]).It is installed using the package installer for Python, pip.

Software description
The library is developed under an open-source license (BSD 3-Clause) and the source is stored in a GitHub repository at https://github.com/QENSlibrary/QENSmodels/.The models are written in Python facilitating integration with other packages of the large Python eco-system as well as easy integration in Python based workflows.Moreover, Python is a very popular scripting and programming language in science and the Python interface therefore reduces the entry barrier for the many scientists already familiar with Python.
The library comes with examples of how it can be used in practise and in conjunction with existing Python modules for optimization (fitting), visualization, and for adding Graphical User Interface (GUI) elements.
Figure 1 shows a typical QENS data processing workflow.Data are collected during an experiment and then corrected (background subtraction, detector efficiency normalisation, absorption and multiple scattering corrections, etc.) in order to obtain the experimental S (Q, ω) for our sample [3].The latter is then compared to the relevant mathematical models and typically some important parameters characterising the sample dynamics and the motion geometry are obtained by fitting the model parameters to the experimental signal.Data collected from multiple experiments can also be used in this procedure for simultaneous or sequential fittings.Different tools exist to deal with these stages with different levels of coverage of the whole workflow.
For example, MantidWorkbench [15] can deal with data reduction, fitting and plotting.
If we focus on fitting only, the available tools are more universal and not restricted to the QENS technique.There are, for example, bumps [16], lmfit [17] or scipy [13].Therefore, in the present library we provide different models, (corresponding to cell 'Select models(s)' in Fig. 1) that can be combined and plugged in different frameworks.The following subsections detail the architecture of the library and its main functionalities.

Software Architecture
Figure 2 shows the structure of the repository.Each file in the QENSmodels folder contains the implementation of exactly one model in the form of a Python 3 function that returns S (Q, ω).For more complicated models, functions returning the Q-dependence of the half-width at half maximum (HWHM), the elastic incoherent structure factor (EISF) and the quasi-elastic incoherent structure factors (QISF) for the 1D peak are also provided.We refer to [8,18] for definitions of these terms.

QENSmodels repository
QENSmodels/ ...  Usability in a scripting environment, such as Jupyter, is facilitated by providing rich documentation through socalled documentation strings using the Sphinx [19] standard including so-called doctest [20].By adhering to the Sphinx standard, documentation pages can be automatically generated and updated from the code itself.Moreover, to help the interested user and to lower the entry barrier, examples using Jupyter notebooks and Python scripts are provided as well as instructions for scientists wishing to contribute their own models to the library.Online documentation is also available on readthedocs at https://qensmodels.readthedocs.io/.
Code quality and maintainability is facilitated by using git for version control and by implementing unit tests, including the aforementioned doctests,2 , which are used for continuous integration using GiHub Actions.This approach to software development is in alignment with the guidelines outlined in [21].

Software Functionalities
Figure 3 shows the options available for using the library.In order to give an idea of what can be done with the library without any installation, the Jupyter notebooks [22] are available through Binder [23].Users only have to click on the link to be able to run the notebooks and check if the library can answer their needs.
On the other hand, for users only interested in the models, for example, to add them to their fitting pipelines, the installation of the library requires only a command line.In addition, they will have to perform all steps as listed in the third column of Figure 3 in order to use the model for their cases.
As mentioned in the previous section, examples are provided as Jupyter notebooks.They use a few QENS models and a few fitting engines, like lmfit, scipy, or bumps.The notebooks and modules required to make them run can be installed by following the guidelines on the github pages [24].Note that the minimizers used in these notebooks were only to illustrate the specific syntaxes of the fitting engines and not because they were the most optimal engines for the investigated cases.Details about comparison of minimizers can be found at [25].
Physical units used by the models' parameters and variables are specified at the beginning of the Jupyter notebooks.A notebook, Convert_Units.ipynb is also provided to convert between different physical units in case the reference user's data are expressed in different units than the standards chosen for the QENS library.

Toy examples in the library
As tutorials, Jupyter notebooks [22] are provided showing how to (i) build a model using different functions from the QENS library, (ii) choose a fitting engine, (iii) define the settings and run the fit, (iv) extract visual and quantitative information from the outputs.
Since the syntax to build the fitting model, apply constrains and set the initial guesses depends on the chosen fitting engine, different minimizers have been used in the notebooks: scipy [13], bumps [16], lmfit [17].For an easier identification, the notebooks have been named following this convention: "[fitting engine]_[name of QENSmodels]_fit.ipynb",e.g., "scipy_lorentzian_fit.ipynb".
Reference data used in the examples are either generated in the dedicated Jupyter notebook or stored in one of the files in the data sub-folder of the repository.We provide these reference data in binary (hdf5) and ascii formats.The resolution function is either a Gaussian profile or reduced data from a Vanadium run.And the convolution with the sample data is done using methods from numpy [14] or lmfit [17].
We are now going to detail one of these notebooks, bumps_Brownian_Diff_fit.ipynb.Figure 4 details its table of contents.After a short introduction describing the objective of the notebook, we specify the physical units of the refined parameters and import the required Python libraries as well as the reference data for the sample and resolution function.Figure 5 shows the evolution of these functions for different Q values.The convolution between the sample and the resolution functions is done using a method from numpy [14].The fitting model is expressed as: where scale and center are the scale factor and center of the Lorentzian function describing the diffusion, of halfwidth at half-maximum equal to DQ 2 , where D is the selfdiffusion coefficient and Q the momentum transfer.Listing 1 shows how the fitting model was created following the syntax required by the fitting engine, bumps.In order to help less Python savvy users, several GUI widgets are provided in the notebooks, for example, to choose the minimizer, the number of iterations or for interactive plots as shown in Figure 6.After running the fit, the values and errors of the refined parameters and the fit quality are printed and a plot of the fitted model in comparison with the reference data is shown for the value of Q selected by the user via a widget.In addition to these notebooks, we also provide instructions to make the library importable in MantidWorkbench [15] as well as a Python script using one of the (Colour on-line) Graphical User Interface of MantidWorkbench [26] showing the use of the Python script mantid_BrownianDiff_fit.py provided in the library.The Python script is displayed in the editor.After its execution, workspaces, i.e., Mantid data structures, are available for further operations in the Graphical User Interface (left-hand side column) and a separate window displays the fitting result for the 4 Q-values considered in this example.models to fit data and plot and display the output in Man-tidWorkbench (see Figure 7).Reference [27] details the QENS features available in this framework.

Benchmarking with experimental data
One of the notebooks, lmfit_TOFTOF_delta_lorentz.ipynbuses reduced data presented in [28].
In this publication, the authors used QENS, among other techniques, to investigate the microscopic details of the proton motions in two proton conducting, acceptordoped, perovskites.The samples were measured at the time-of-flight spectrometer TOFTOF at MLZ at different temperatures using an incident wavelength of 2.5 Å. Nine "Q-cuts" were retained in the analysis.The reduced data files for one of the investigated samples BaZr 0.8 In 0.
is the Bose factor, and β = (k B T ) −1 is the reciprocal of the thermodynamic temperature.δ( ω) and L(Q, ω) are a Dirac and a Lorentzian peaks, respectively.R(Q, ω) is the resolution function (spectrum of a vanadium standard).bkg(Q) is the constant background, only Q-dependent and is the convolution symbol.
The Jupyter notebook describes how to load the reduced data, build the model using the QENS library, select the minimizer and the range of Q-values to consider, run batch fitting over successive Q-values at different temperatures and extract, store and display results from the fit.Figure 8 shows the comparison between an experimental profile (bullet points with errorbars) and the fitted model (solid line) for Q = 2.3 Å at a temperature of T = 540K together with the initial model (dashed curve).The good agreement between the final fit and the experimental data is clearly evident.Interested readers are encouraged to consult ref. [28] for further details.
This example could be further extended by providing loading of reduced data from different instruments or different data formats to, for example, easily compare the results collected during experiments at different institutes.

Impact
The QENS library helps researchers and scientists by providing a list of 1D functions to fit QENS data making the analysis more FAIR, i.e., Findable Accessible Interoperable Reusable [29] by providing a public reference to fitting models allowing other researchers to reproduce the analysis.
The dynamics observed in QENS experiments are mainly related to the complexities of the samples studied.But collected signals can also contain the signature of the instrument and of the sample environment, which are getting more sophisticated.The combination of both factors may render the extraction and modelling of the experimental S (Q, ω) challenging.But this process can be made easier thanks to the flexibility of customising fitting models with the QENS library and different instrument resolution functions.
The library can be imported in different frameworks as illustrated in Section 3 with MantidWorkbench.This example shows how to use Python scripts.But the library could also be used in Graphical User Interfaces, like the QENS data analysis interface of Mantid described in [27].
Given that the library is installed using pip, it can be included in an automated data processing pipeline (reduction and analysis) or, for example, in a Machine Learning workflow, to build the optimal fitting model with ease, which increases the reach and usability of our development.

Conclusions
We have developed a Python package called QENSmodels, that provides dynamic models of 1D line profiles to fit QENS experimental or simulated data.In order to illustrate how to hook these models to the whole data processing pipeline to newcomers and experts, we provide Python scripts and Jupyter notebooks using different data and fitting engines.In the future, we plan to integrate more models and other examples using experimental data and other fitting engines.Scientists are also encouraged to contribute implementations of their work with additional models or examples.

Figure 1 .
Figure 1.(Colour on-line) Workflow of QENS data processing from raw experimental data to output of fitting.

Figure 3 .
Figure 3. (Colour on-line) Diagram showing the tools provided in the QENSmodels library to help users with different levels of expertise in QENS and in programming.

Figure 4 .Figure 5 .
Figure 4.Table of contents of one of the Jupyter notebooks available in the library: bumps_Brownian_Diff_fit.ipynb

Listing 1 .
Code snippet showing how to create a fitting model using 'bumps' and the QENS library import numpy a s np from QENSmodels import \ s q w B r o w n i a n T r a n s l a t i o n a l D i f f u s i o n import bumps .names a s bmp # F i t t i n g model d e f m o d e l _ c o n v o l ( x , q , s c a l e =1 , c e n t e r =0 , D=1 , r e s o l u t i o n =None ) : model = s q w B r o w n i a n T r a n s l a t i o n a l D i f f u s i o n ( x , q , s c a l e , c e n t e r , D)re t u r n np .c o n v o l v e ( model , r e s o l u t i o n / r e s o l u t i o n .sum ( ) , mode= ' same ' ) # F i t m o d e l _ a l l _ q s = [ ] f o r i i n range ( l e n ( q ) ) : # Bumps f i t t i n g model model_q = bmp .Curve ( m o d e l _ c o n v o l , hw , sqw [ : , i ] , e r r [ : , i ] , name= f ' q_ { q [ i ] : . 2 f } ' , q=q [ i ] , s c a l e =1000 , c e n t e r = 0 .0 , D= 0 . 1 , r e s o l u t i o n = r e s [ : , i ] ) model_q .s c a l e .range ( 0 , 1 e5 ) model_q .c e n t e r .range ( − 0 . 1 , 0 . 1 ) model_q .D .range ( 1 e −12 , 1 ) # Q− i n d e p e n d e n t p a r a m e t e r s i f i == 0 : D_q = model_q .D e l s e : model_q .D = D_q m o d e l _ a l l _ q s .a p p e n d ( model_q ) p r o b l e m = bmp .F i t P r o b l e m ( m o d e l _ a l l _ q s )

Figure 6 .
Figure 6.(Colour on-line) Widget to select the index in the list of available Q-values to plot the fitted model in comparison with the reference data as well as the residual.Here the configuration corresponding to Q = 2 Å is shown.