def estimate_baresine(self, x_axis, data, params):
""" Bare sine estimator with a frequency and phase.
@param numpy.array x_axis: 1D axis values
@param numpy.array data: 1D data, should have the same dimension as x_axis.
@param lmfit.Parameters params: object includes parameter dictionary which
can be set
@return tuple (error, params):
Explanation of the return parameter:
int error: error code (0:OK, -1:error)
lmfit.Parameters params: derived OrderedDict object contains the initial
values for the fit.
"""
# Convert for safety:
x_axis = np.array(x_axis)
data = np.array(data)
error = self._check_1D_input(x_axis=x_axis, data=data, params=params)
# calculate dft with zeropadding to obtain nicer interpolation between the
# appearing peaks.
dft_x, dft_y = compute_ft(x_axis, data, zeropad_num=1)
stepsize = x_axis[1]-x_axis[0] # for frequency axis
frequency_max = np.abs(dft_x[np.log(dft_y).argmax()])
# find minimal distance to the next meas point in the corresponding time value>
min_x_diff = np.ediff1d(x_axis).min()
# How many points are used to sample the estimated frequency with min_x_diff:
iter_steps = int(1/(frequency_max*min_x_diff))
if iter_steps < 1:
iter_steps = 1
sum_res = np.zeros(iter_steps)
# Procedure: Create sin waves with different phases and perform a summation.
# The sum shows how well the sine was fitting to the actual data.
# The best fitting sine should be a maximum of the summed time
# trace.
for iter_s in range(iter_steps):
func_val = np.sin(2*np.pi*frequency_max*x_axis + iter_s/iter_steps *2*np.pi)
sum_res[iter_s] = np.abs(data - func_val).sum()
# The minimum indicates where the sine function was fittng the worst,
# therefore subtract pi. This will also ensure that the estimated phase will
# be in the interval [-pi,pi].
phase = sum_res.argmax()/iter_steps *2*np.pi - np.pi
params['frequency'].set(value=frequency_max, min=0.0, max=1/(stepsize)*3)
params['phase'].set(value=phase, min=-np.pi, max=np.pi)
return error, params
评论列表
文章目录