def get_background_model(self, saturation_radius): """Creates a model for the background of the signal. The mean radial profile is fitted with the following three components: * Voigt profile for the central beam * Exponential profile for the diffuse scatter * Linear profile for the background offset and to improve the fit Using the exponential profile and the linear profile, an ElectronDiffraction signal is produced representing the mean background of the signal. This may be used for background subtraction. Parameters ---------- saturation_radius : int The radius of the region about the central beam in which pixels are saturated. Returns ------- ElectronDiffraction The mean background of the signal. """ # TODO: get this done without taking the mean profile = self.get_radial_profile().mean() model = profile.create_model() e1 = saturation_radius * profile.axes_manager.signal_axes[0].scale model.set_signal_range(e1) direct_beam = Voigt() direct_beam.centre.value = 0 direct_beam.centre.free = False direct_beam.FWHM.value = 0.1 direct_beam.area.bmin = 0 model.append(direct_beam) diffuse_scatter = Exponential() diffuse_scatter.A.value = 0 diffuse_scatter.A.bmin = 0 diffuse_scatter.tau.value = 0 diffuse_scatter.tau.bmin = 0 model.append(diffuse_scatter) linear_decay = Polynomial(1) model.append(linear_decay) model.fit(bounded=True) x_axis = self.axes_manager.signal_axes[0].axis y_axis = self.axes_manager.signal_axes[1].axis xs, ys = np.meshgrid(x_axis, y_axis) rs = (xs ** 2 + ys ** 2) ** 0.5 bg = ElectronDiffraction( diffuse_scatter.function(rs) + linear_decay.function(rs)) for i in (0, 1): bg.axes_manager.signal_axes[i].update_from( self.axes_manager.signal_axes[i]) return bg
def _make_radius_vs_angle_model( signal, radial_signal_span, angleN=15, centre_x=None, centre_y=None, prepeak_range=None, show_progressbar=True, ): s_ra = signal.angular_slice_radial_average( angleN=angleN, centre_x=centre_x, centre_y=centre_y, show_progressbar=show_progressbar, ) s_ra = s_ra.isig[radial_signal_span[0]:radial_signal_span[1]] m_ra = s_ra.create_model() # Fit 1 order polynomial to edges of data to account for the background sa = m_ra.axes_manager.signal_axes[0] if prepeak_range is None: prepeak_range = (sa.low_value, sa.index2value(4)) m_ra.set_signal_range(prepeak_range[0], prepeak_range[1]) m_ra.add_signal_range(sa.index2value(-3), sa.high_value) polynomial = Polynomial(1) m_ra.append(polynomial) m_ra.multifit(show_progressbar=show_progressbar) polynomial.set_parameters_not_free() m_ra.reset_signal_range() # Fit Gaussian to diffraction ring centre_initial = (sa.high_value + sa.low_value) * 0.5 sigma = 3 A = (s_ra - s_ra.min(axis=1)).data.max() * 2 * sigma gaussian = Gaussian(A=A, sigma=sigma, centre=centre_initial) gaussian.centre.bmin = sa.low_value gaussian.centre.bmax = sa.high_value m_ra.append(gaussian) return m_ra