glassure.optimization module

glassure.optimization.optimize_density(data_config: DataConfig, calculation_config: CalculationConfig, method: str = 'fr', min_range: tuple[float, float] | None = None, vary_bkg_scaling: bool = True, bkg_limits: tuple[float, float] = (0.9, 1.1), optimization_method: str = 'lsq') tuple[float, float, float, float]

Optimizes the density of the sample using the g(r), F(r) or S(Q) (chosen by the method parameter). The density in the SampleConfig of the DataConfig is taking as starting parameter

For method=’gr’ or method=’fr’ the optimization is based on the g(r) or F(r) function, and the density is optimized to minimize the low g(r) or F(r) region to be close to zero. The Lorch modification function will be applied before calculating the chi square of the low r region if it is applied in the calculation configuration. The general procedure is explained in Eggert et al. 2002 PRB, 65, 174105.

For method=’sq’ the optimization is based on the low Q part of the S(Q) function, and the density is optimized to minimize the difference between the original S(Q) function without any optimization and the optimized S(Q) function. The configuration should have extrapolation enabled for this to work best. For polyatomic systems, finding the density using this procedure is much less susceptible to the Q_max value of the S(Q) than the g(r) based optimization. However, density is not exactly the same for both methods and the method needs to be verified further. (Please us the method=’sq’ with caution.)

The best for both types is to have a reference density to compare it to. Based on this then further calculations of e.g. high pressure or high temperature densities can be performed.

For this procedure to work best, the S(Q) optimization should be enabled in the calculation configuration. The chosen parameters are then used in the find density function.

example usage: ``` from glassure.calc import create_calculate_pdf_configs from glassure.optimization import optimize_density

data_config, calculation_config = create_calculate_pdf_configs(data, composition, density, background) calculation_config.transform.q_min = 1 calculation_config.transform.q_max = 16 calculation_config.transform.extrapolation.method = ExtrapolationMethod.LINEAR calculation_config.optimize = OptimizeConfig(r_cutoff=1.4)

density, density_error, bkg_scaling, bkg_error = optimize_density(data_config, calculation_config, method=’gr’, range=(0.1, 1.2)) ```

Parameters:
  • data_config – Data configuration

  • calculation_config – Calculation configuration

  • method – Method to use for the optimization. Possible values are ‘gr’, ‘fr’ and ‘sq’.

  • min_range – x range of the data to use for the minimization to find the density. For method=’gr’ and ‘fr this is the r-range of the g(r)/F(r) function to minimize. For method=’sq’ this is the Q-range of the S(Q) function to minimize the difference between the original and optimized S(Q) function. Default is None which means that the range is (0, calculation_config.optimize.r_cutoff) for method=’gr’ and ‘fr’ and (0, calculation_config.transform.q_max) for method=’sq’.

  • vary_bkg_scaling – Whether to vary the background scaling during the optimization. Default is True.

  • bkg_limits – relative limits for the background scaling. The background scaling is optimized to be within these limits. Default is (0.9, 1.1) which means that the background scaling is optimized to be within 10% of the starting value.

  • optimization_method – Method to use for the optimization. Possible values are ‘nelder’ and ‘lsq’.

Returns:

a tuple with four values: - the density, its error value, the background scaling and the error value whereby the error value is the standard error of the fit parameter for optimization_method =’lsq’ and the sum of the squared residuals for optimization_method=’nelder’.

glassure.optimization.optimize_sq(sq_pattern: Pattern, r_cutoff: float, iterations: int, atomic_density: float, r_step: float = 0.01, use_modification_fcn: bool = False, attenuation_factor: float = 1, fcn_callback=None, callback_period: int = 2, fourier_transform_method: str = 'fft')

Performs an optimization of the structure factor based on an r_cutoff value as described in Eggert et al. 2002 PRB, 65, 174105. This basically does back and forward transforms between S(Q) and F(r) until the region below the r_cutoff value is a flat line without any oscillations.

Parameters:
  • sq_pattern – original S(Q)

  • r_cutoff – cutoff value below which there is no signal expected (below the first peak in g(r))

  • iterations – number of back and forward transforms

  • atomic_density – density in atoms/A^3

  • r_step

    step size for the r-axis, default is 0.01. Use smaller values for better accuracy (especially if needed for

    fft)

  • use_modification_fcn – Whether to use the Lorch modification function during the Fourier transform. Warning: When using the Lorch modification function, usually more iterations are needed to get to the wanted result.

  • attenuation_factor – Sometimes the initial change during back and forward transformations results in a runaway, by setting the attenuation factor reduces the amount of change during each iteration.

  • fcn_callback – Function which will be called at an iteration period defined by the callback_period parameter. The function should take three arguments: sq_pattern, fr_pattern and gr_pattern. Additionally, the function should return a boolean value, where True continues the optimization and False will stop the optimization.

  • callback_period – determines how frequently the fcn_callback will be called.

  • fourier_transform_method – determines which method will be used for the Fourier transform. Possible values are ‘fft’ and ‘integral’

Returns:

optimized S(Q) pattern

glassure.optimization.optimize_sq_fit(sq_pattern: Pattern, r_cutoff: float) Pattern

Optimizes the S(Q) pattern by fitting a polynomial to the F(Q) = q( S(Q) - 1 ). The order of the polynomial is determined by the q_max and r_cutoff value = r_cutoff * q_max / pi. The zero order term is fixed to 0.

This method is based on the normalization description in the following reference:

Juhás, P., Davis, T., Farrow, C.L., Billinge, S.J.L., 2013. PDFgetX3: a rapid and highly automatable program for processing powder diffraction data into total scattering pair distribution functions. J Appl Crystallogr 46, 560–566. https://doi.org/10.1107/S0021889813005190

In order to try to do a similar procedure as in the above paper, the input S(Q) should be created using a normalization without incoherent scattering. Since it is assume that the polynomial fit, will also remove the incoherent scattering.

Parameters:
  • sq_pattern – original S(Q)

  • r_cutoff – cutoff value below which there is no signal expected (below the first peak in g(r))

Returns:

optimized S(Q) pattern