<jupyter_start><jupyter_text>Fitting There are two built in fitting engines, `lmfit` and `bumps`.<jupyter_code># Import all the packages
from easyCore import np
from easyDiffractionLib.sample import Sample
from easyDiffractionLib import Phases
from easyDiffractionLib.interface import InterfaceFactory as Calculator

from easyDiffractionLib.Elements.Experiments.Pattern import Pattern1D
from easyDiffractionLib.Profiles.P1D import Instrument1DCWParameters

from easyCore.Fitting.Fitting import Fitter

import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Preparing the sample and data Load structure from a CIF file<jupyter_code>calculator = Calculator()
phase = Phases.from_cif_file('PbSO4.cif')
sample = Sample(phases=phase, parameters=Instrument1DCWParameters.default(), calculator=calculator)<jupyter_output><empty_output><jupyter_text>Visualise the structure<jupyter_code>import py3Dmol
viewer = py3Dmol.view()
viewer.addModel(phase[0].to_cif_str(),'cif')
viewer.setStyle({'sphere':{'colorscheme':'Jmol','scale':.2},'stick':{'colorscheme':'Jmol', 'radius': 0.1}})
viewer.addUnitCell()
viewer.replicateUnitCell(2,2,1)
viewer.zoomTo()<jupyter_output><empty_output><jupyter_text>Load experimental data from a file<jupyter_code>file_path = 'PbSO4_neutrons_short.xye'
data_x, data_y, data_e = np.loadtxt(file_path, unpack=True)

data_y = data_y/100.0

# Generate the simulation y-data
sim_y_data = calculator.fit_func(data_x)

%matplotlib notebook
plt.plot(data_x, data_y, label='Experimental')
plt.plot(data_x, sim_y_data, label='Starting point')
plt.legend()<jupyter_output><empty_output><jupyter_text>The charts do not match very well, because our simulation did not include any parameters related to the experiment.Let's assign some decent values then.<jupyter_code>sample.parameters.wavelength = 1.912
sample.parameters.u_resolution = 1.4
sample.parameters.v_resolution = -0.42
sample.parameters.w_resolution = 0.38
sample.parameters.x_resolution = 0.0
sample.parameters.y_resolution = 0.0

sim_y_data = calculator.fit_func(data_x)

%matplotlib notebook
plt.plot(data_x, data_y, label='Experimental')
plt.plot(data_x, sim_y_data, label='Starting point')
plt.legend()<jupyter_output><empty_output><jupyter_text>This looks much better now - experimental and theoretical peaks seem to be very close but there is no background included in our simulation.<jupyter_code>from easyDiffractionLib.Elements.Backgrounds.Point import PointBackground, BackgroundPoint

bg = PointBackground(linked_experiment='PbSO4')
bg.append(BackgroundPoint.from_pars(data_x[0], 2))
bg.append(BackgroundPoint.from_pars(data_x[-1], 2))

sample.set_background(bg)
sim_y_data = calculator.fit_func(data_x)
%matplotlib notebook
plt.plot(data_x, data_y, label='Experimental')
plt.plot(data_x, sim_y_data, label='Starting point')
plt.legend()<jupyter_output><empty_output><jupyter_text>These two charts look close enough to attempt fitting.  Fitting to the data Initalize the fitting engine and define parameters to optimize<jupyter_code>f = Fitter(sample, calculator.fit_func)

# Vary the scale and the BG points
sample.pattern.scale.fixed = False
sample.parameters.resolution_u.fixed = False
sample.parameters.resolution_v.fixed = False
sample.parameters.resolution_w.fixed = False
sample.backgrounds[0][0].y.fixed = False
sample.backgrounds[0][1].y.fixed = False<jupyter_output><empty_output><jupyter_text>Perform the fit<jupyter_code>result = f.fit(data_x, data_y, weights=1/data_e)

if result.success:
    print("The fit has been successful: {}".format(result.success))
    print("The gooodness of fit is: {}".format(result.goodness_of_fit))
    
sim_y_data = calculator.fit_func(data_x)
%matplotlib notebook
plt.plot(data_x, data_y, label='Experimental')
plt.plot(data_x, sim_y_data, label='Best Fit')
plt.legend()<jupyter_output><empty_output><jupyter_text>Fitted parameters<jupyter_code>print(f'Scale: {sample.pattern.scale}')
print(f'BG 0: {sample.backgrounds[0][0]}')
print(f'BG 1: {sample.backgrounds[0][1]}')<jupyter_output><empty_output><jupyter_text>**Parameter object with varying accessors**<jupyter_code>print(f'Scale: {sample.pattern.scale}')
print(f'Scale: {sample.pattern.scale.value}')
print(f'Scale: {sample.pattern.scale.raw_value}')<jupyter_output><empty_output><jupyter_text>The fit is quite good, but let's see if we can do better with a different optimizer.  Change the optimizer to `bumps`<jupyter_code>print("available minimizers:", f.available_engines)
print()
print("current minimizer:", f.current_engine.name)
print("available methods of current minimizer:", f.available_methods())
print("switch minimizer")
f.switch_engine('bumps')
f_method = 'lm'
print("current minimizer:", f.current_engine.name)
print("available methods of current minimizer:", f.available_methods())<jupyter_output><empty_output><jupyter_text>**Rerun fitting** (takes a while!)This seems completely broken and needs fixing. The fitting just hangs.<jupyter_code>result = f.fit(data_x, data_y, weights=1/data_e, method=f_method)

if result.success:
    print("The fit has been successful: {}".format(result.success))
    print("The gooodness of fit is: {}".format(result.goodness_of_fit))
    
sim_y_data = calculator.fit_func(data_x)
%matplotlib notebook
plt.plot(data_x, data_y, label='Experimental')
plt.plot(data_x, sim_y_data, label='Best Fit')
plt.legend()
print(f'Scale: {sample.pattern.scale}')
print(f'BG 0: {sample.backgrounds[0][0]}')
print(f'BG 1: {sample.backgrounds[0][1]}')
#print(f'Res U: {sample.parameters.resolution_u}')
#print(f'Res V: {sample.parameters.resolution_v}')
#print(f'Res W: {sample.parameters.resolution_w}')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12372043769855277, 'fraction_numerical': 0.010236498411577833, 'mean_word_length': 8.199675324675324, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '27253', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1997, 'n_tokens_neox': 1903, 'n_words': 396, 'path': 'tests/integration_tests/FittingData.ipynb', 'repo_name': 'arm61/easyDiffractionLib', 'size': '5666'}