Experiment

from library

[1]:
import nexus as nx
import numpy as np
import matplotlib.pyplot as plt

# Lorentzian lineshpae, e.g. a Moessbauer instrument
# loaded from library
# linewidth here is one Gamma
# this definition is enough to be used with the FitMeasurment classes
moessbauer_instrument = nx.lib.instrument.Lorentz(
    fwhm = 1.0,  # can also be a Var object
    relative_truncation_threshold = 0.0,  # default is 1e-3, with 0 no truncation is used
    norm_factor = 1.0)   # default is 1.0

# code to get the actual kernel shape
# grid for the calculation
detuning = np.linspace(-15, 15, 1001)  # detuing in Gamma

# the InstrumentFunction() calls the actual kernel implementation on the provided grid
kernel = moessbauer_instrument.InstrumentFunction(detuning)

# the kernel sum is normalized to the norm_factor
# with 1.0 it keeps the correct intensity of the theoretical curve.
print(np.sum(kernel))

#plotting the kernel
plt.title(moessbauer_instrument.id)
plt.plot(detuning, kernel)
plt.show()
0.9999999999999998
../../_images/tutorial_instrument_nb_instrument_2_1.png

user-defined instrument

[2]:
# definition of the witch of Agnesi function with one fit parameter center_shift and one fixed parameter a
class InstrumentDefinedInPython(nx.Instrument):
    def __init__(self, id, center_shift, a):
        super().__init__(id)

        # register fit variables
        self.fit_variables = [center_shift]

        # make parameters available in functions calls
        self.center_shift = center_shift
        self.a = a

    # implementation of the actual instrumental function
    # Witch of Agnesi function here
    def InstrumentFunction(self, grid):
        # IMPORTANT - Do not remove this steps to get proper center to avoid shifts during convolution
        grid = np.array(grid)
        center = grid[grid.size // 2]

        # implementation of Witch of Agnesi function
        # the center value is important to garantee the correct center point during convolution
        # the center_shift.value is the additional user provided shift from the fit varibale
        kernel = 8 * self.a**3/(np.square(grid - center - self.center_shift.value) + 4 * self.a**2)

        # OPTIONAL - Truncation for faster convolution.
        # DO NOT DO THIS for asymmetric or shifted functions due to possible shifts during convolution.
        # The relative truncation value is important for the kernel type.
        # For Lorentzian it is around 30 gamma ~ 1.1e-3
        # as the curve is possibly shifted by center_shift.value no truncation
        # kernel = self.TruncateKernel(kernel, relative_truncation_threshold = 1e-3)

        # IMPORTANT - normalize kernel
        # keeps the correct intensity of the theoretical curve
        kernel = self.NormalizeKernel(kernel, 1.0)

        return kernel
[3]:
# one fixed and one fit parameter for our user-defined function
shift = nx.Var(value=1, min=0, max=10, fit=True, id="my fit parameter")
a = 0.3

# intilazation of witch of Agnesi function
woa = InstrumentDefinedInPython("Witch of Agnesi", shift, a)

kernel = woa.InstrumentFunction(detuning)

# the kernel is nomralized in sum to norm_factor
print(np.sum(kernel))

#plotting the kernel
plt.title(woa.id)
plt.plot(detuning, kernel)
plt.show()
0.9999999999999999
../../_images/tutorial_instrument_nb_instrument_5_1.png