Exemple #1
0
def least(func, x, y, sy=None, beta0=[]):
    linear = odrpack.Model(func)
    #mydata = odrpack.Data(x, z[1], wd=1./np.power(z[2],2), we=1./np.power(sy,2))
    if not sy == None:
        mydata = odrpack.RealData(x, y, sy=sy)
    else:
        mydata = odrpack.RealData(x, y)
    myodr = odrpack.ODR(mydata, linear, beta0=beta0)
    myodr.set_job(fit_type=2)
    myoutput = myodr.run()
    myoutput.pprint()
    return myodr.output
Exemple #2
0
def bilinear_Q_regression(freqs_log, Q_list_log):
    freqs_log = array(freqs_log)

    #data = odrpack.RealData(x[12:], y[12:])
    data = odrpack.RealData(freqs_log, Q_list_log)

    #x_range = arange(-0.5, 1.0, step=0.01) # x range

    bilin_reg = odrpack.Model(bilinear_reg_free)
    odr = odrpack.ODR(data, bilin_reg, beta0=[0.4, 3.0, 0.3, -0.5])

    odr.set_job(
        fit_type=2)  #if set fit_type=2, returns the same as least squares
    out = odr.run()
    #print('\nbilinear auto\n')
    #out.pprint()

    a = out.beta[0]
    b = out.beta[1]
    c = out.beta[2]
    hx = out.beta[3]  # x hinge point

    log_q_fit = b + a * freqs_log  # get y values from bilinear
    yhinge = b + a * hx
    idx = freqs_log > hx
    log_q_fit[idx] = c * (freqs_log[idx] - hx) + yhinge

    return log_q_fit
def bilinear_regression(x, y):

    data = odrpack.RealData(x[12:], y[12:])

    x_range = np.arange(-0.5, 1.0, step=0.01) # x range 

    bilin_reg = odrpack.Model(bilinear_reg_free)
    odr = odrpack.ODR(data, bilin_reg, beta0=[0.4, 3.0, 0.3, -0.5])

    odr.set_job(fit_type=2) #if set fit_type=2, returns the same as least squares
    out = odr.run()
    print('\nbilinear auto\n')
    out.pprint()

    a = out.beta[0]
    b = out.beta[1]
    c = out.beta[2]
    hx = out.beta[3] # x hinge point

    y_range = b + a * x_range # get y values from bilinear
    yhinge = b + a * hx
    idx = x_range > hx
    y_range[idx] = c * (x_range[idx]-hx) + yhinge

    return y_range, x_range
Exemple #4
0
def least(func, x, y, sy=None, beta0=None, ifixb=None, fjacb=None):
    linear = odrpack.Model(func, fjacb=fjacb)
    #mydata = odrpack.Data(x, z[1], wd=1./np.power(z[2],2), we=1./np.power(sy,2))
    mydata = odrpack.RealData(x, y, sy=sy)
    myodr = odrpack.ODR(mydata, linear, beta0=beta0, ifixb=ifixb)
    myodr.set_job(fit_type=2)
    myoutput = myodr.run()
#    myoutput.pprint()
    return myodr.output
Exemple #5
0
def ws_correlation_orthoginal_distance_model(data, ref_ws_col='ref', site_ws_col='site', force_through_origin=False):
    """Calculate the slope and offset between two wind speed columns using orthoganal distance regression.

    https://docs.scipy.org/doc/scipy-0.18.1/reference/odr.html

    :Parameters:

    data: DataFrame
        DataFrame with wind speed columns ref and site, and direction data dir

    ref_ws_col: string, default None (primary anemometer assumed)
        Reference anemometer data to use. Extracted from MetMast.data

    site_ws_col: string, default None (primary anemometer assumed)
        Site anemometer data to use. Extracted from MetMast.data

    force_through_origin: boolean, default False
        Force the correlation through the origin (offset equal to zero)

    :Returns:

    out: DataFrame
        slope, offset, R2, uncert, points

    """
    data = data.loc[:, [ref_ws_col, site_ws_col]].dropna().astype(np.float)
    results = return_correlation_results_frame(ref_label=ref_ws_col, site_label=site_ws_col)

    if not valid_ws_correlation_data(data=data, ref_ws_col=ref_ws_col, site_ws_col=site_ws_col):
        return results

    points = data.shape[0]
    R2 = calculate_R2(data=data, ref_ws_col=ref_ws_col, site_ws_col=site_ws_col)
    uncert = calculate_IEC_uncertainty(data=data, ref_ws_col=ref_ws_col, site_ws_col=site_ws_col)

    X = data.loc[:, ref_ws_col].values
    Y = data.loc[:, site_ws_col].values

    data_mean = data.mean()
    slope_estimate_via_ratio = data_mean[site_ws_col] / data_mean[ref_ws_col]

    realdata = odrpack.RealData(X, Y)

    if force_through_origin:
        linear = odrpack.Model(f_without_offset)
        odr = odrpack.ODR(realdata, linear, beta0=[slope_estimate_via_ratio])
        slope = odr.run().beta[0]
        offset = 0
    else:
        linear = odrpack.Model(f_with_offset)
        odr = odrpack.ODR(realdata, linear, beta0=[slope_estimate_via_ratio, 0.0])
        slope, offset = odr.run().beta[0], odr.run().beta[1]

    results.loc[pd.IndexSlice[ref_ws_col, site_ws_col], ['slope', 'offset', 'R2', 'uncert', 'points']] = np.array(
        [slope, offset, R2, uncert, points])
    return results
Exemple #6
0
def fitScipyODR(xdata, ydata, xerr, yerr, func, pInit):
    """ Fit a series of data points with ODR (function must be in from f(beta[n], x))
    """
    model = odrpack.Model(func)
    data = odrpack.RealData(xdata, ydata, sx=xerr, sy=yerr)
    odr = odrpack.ODR(data, model, beta0=pInit)
    out = odr.run()
    popt = out.beta
    pcov = out.cov_beta
    out.pprint()
    print('Chi square = %f' % out.sum_square)
    return popt, pcov
Exemple #7
0
def do_odr(f, x, xe, y, ye, estimates):

    model = odrpack.Model(f)

    # sx and sy should be the covariances
    data = odrpack.RealData(x, y, sx=xe, sy=ye)

    # need to hard-code in estimates for parameters
    odr = odrpack.ODR(data, model, estimates)

    output = odr.run()

    return output
Exemple #8
0
    def estimate_spectra(self):
        from scipy.odr import odrpack as odr

        def ofunc(pars, x, sp_sens, nu, el):
            a, b, dkalpha, tele = pars
            spectra = a * Kalpha_profile(el, nu, dkalpha) + b * ff_profile(
                nu, tele)
            spectra /= np.trapz(spectra, nu)

            spectra = np.tile(spectra, (sp_sens.shape[0], 1))
            comp_tr = np.trapz(sp_sens * spectra, nu, axis=-1)
            return comp_tr

        def ofunc2(pars, thick, nu, el):
            spectra = compute_spectra(pars, nu)

            sp_tr_filters = np.ones(nu.shape)
            for filt_el, filt_thick in self.filters.iteritems():
                sp_tr_filters *= np.exp(-cold_opacity(filt_el, nu=nu) *
                                        filt_thick)
            ip_sens = ip_sensitivity(nu)
            comp_tr = []
            for this_thick in thick:
                sp_sens = np.exp(-cold_opacity(el, nu=nu)*this_thick)\
                        * sp_tr_filters * ip_sens * spectra
                comp_tr.append(np.trapz(sp_sens, nu, axis=0))

            return np.array(comp_tr).reshape((1, -1))
            #return ((comp_tr - exp_tr)**2).sum()

        beta0 = [1, 1, 100, 1000]
        my_data = odr.RealData(self.thick,
                               self.exp_tr,
                               sy=0.05 * np.ones(self.exp_tr.shape))
        my_model = odr.Model(ofunc2, extra_args=(self.nu, 'polystyrene'))
        my_odr = odr.ODR(my_data, my_model, beta0=beta0)
        my_odr.set_job(fit_type=2)
        my_odr.set_iprint(final=2, iter=1, iter_step=1)
        fit = my_odr.run()
        self.beta = fit.beta  #[::-1]
        self.sdbeta = fit.sd_beta  #[::-1]

        print(ofunc2(self.beta, self.thick, self.nu, 'polystyrene'))
        print(self.exp_tr)

        print('\n')
        print(beta0)
        print(self.beta)
Exemple #9
0
    def nominal_AB(self, K, N, T, explore_mag=10, res_time=100):
        '''
        Estimates matrices A and B
        Args:
            K: The controller gain
            N: number of iterations to be consistent with iterative methods
            T: Rollout length
            explore_mag: noise magnitude for excitement
            res_time: when to reset the dynamics to its initial condition

        Returns: A_nom, B_nom
        '''
        Lin_gain = LinK(K)
        Lin_gain.make_sampling_on(explore_mag)
        if T >= res_time:
            N = int(np.ceil(N * T / res_time))
            T = res_time
        A_nom = np.zeros((self.n, self.n))
        B_nom = np.zeros((self.n, self.m))

        # storage matrices
        states_batch = np.zeros((self.n, N, T))
        next_states_batch = np.zeros((self.n, N, T))
        actions_batch = np.zeros((self.m, N, T))

        # simulate
        for k in range(N):
            # Do one rollout to save data for  model estimation
            states, actions, _, next_states = self.dyn.one_rollout(Lin_gain.sample_lin_policy, T)
            states_batch[:, k, :] = states.T
            actions_batch[:, k, :] = actions.T
            next_states_batch[:, k, :] = next_states.T

        for i in range(self.n):
            linear = odrpack.Model(linear_func)
            data = odrpack.RealData(
                x=np.vstack((states_batch.reshape(self.n, N * T), actions_batch.reshape(self.m, N * T))),
                y=next_states_batch[i, :, :].reshape(1, N * T))
            Myodr = odrpack.ODR(data, linear, np.zeros(self.n + self.m))
            out = Myodr.run()
            tmp = out.beta
            A_nom[i, :] = tmp[0:self.n]
            B_nom[i, :] = tmp[self.n:]

        return A_nom, B_nom
    def fitSingleCrystalBallPeak(self):
        params = np.array([
            self.peak1_paramsEdits[0].value(),
            self.peak1_paramsEdits[1].value(),
            self.peak1_paramsEdits[2].value(),
            self.peak1_paramsEdits[3].value(), 0.9, 4
        ])

        model = odr.Model(lineshape.Single_Crystalball)
        odr_data = odr.RealData(self.x_cut,
                                self.y_cut)  #, sy = np.sqrt(self.y_cut))
        myodr = odr.ODR(odr_data, model, beta0=params)
        myodr.set_job(fit_type=0)
        myoutput = myodr.run()

        self.params = myoutput.beta
        params_cov = myoutput.cov_beta

        params_output = []
        params_red_chi2 = myoutput.res_var

        content, error = integrate.quad(lineshape.Single_Crystalball_integrand,
                                        self.x_fit[0],
                                        self.x_fit[-1],
                                        args=tuple(self.params))

        params_output.append(content)
        params_output.append(params_red_chi2)
        self.params_outputs = np.array(params_output)

        for i in range(len(self.peak1_paramsEdits)):
            self.peak1_paramsEdits[i].setValue(self.params[i])
        self.peak1_contentEdit.setText(str(self.params_outputs[0]))
        self.peak1_chi2Edit.setText(str(self.params_outputs[1]))

        self.plotWidget.plot(clear=True)
        self.plotWidget.plot(self.x, self.y[:-1], stepMode=True)
        fitPen = pg.mkPen(color=(204, 0, 0), width=2)
        self.plotWidget.plot(self.x_fit,
                             lineshape.Single_Crystalball(
                                 self.params, self.x_fit),
                             pen=fitPen)
        self.plotWidget.addItem(self.vLine, ignoreBounds=True)
        self.plotWidget.addItem(self.hLine, ignoreBounds=True)
Exemple #11
0
def fit2(data,interval,init):
    interval.sort()
    nData = data[(data[:,0] > interval[0])&(data[:,0] < interval[1])]
    x=nData[:,0]
    y=nData[:,1]
    sx=None
    sy=None
    try:
        sx = nData[:,2]
        sy = nData[:,3]
    except:
        pass
    def func(B,x):
        return (1/B[0]) * x
    linear = odrpack.Model(func)
    mydata = odrpack.RealData(x, y, sx=sx, sy=sy)
    myodr = odrpack.ODR(mydata, linear, beta0=[init])
    myoutput = myodr.run()
    myoutput.pprint()
    return [myoutput.beta[0],myoutput.sd_beta[0]]
Exemple #12
0
def fit_tls(x: np.ndarray, y: np.ndarray) -> float:
	"""Fit total least squares model to data
	This function fits a total least squares (also known as orthogonal distance regression) model to 2-dimensional data.
	The model has the form `y = m * x`, where m is the "slope". (It has an intercept at y==0).
	See Also:
			At its core, the function uses scipy's `Orthogonal Distance Regression`_ module
			.. _Orthogonal Distance Regression:
					https://docs.scipy.org/doc/scipy/reference/odr.html
			Args:
					x: 1-dimensional Numpy array
					y: 1-dimensional Numpy array of the same size as `x`

			Returns:
					The slope of the fitted model

			"""
	odr_data = odrpack.RealData(x, y)
	model = odrpack.Model(lambda beta, x_: beta[0] * x_)
	odr_container = odrpack.ODR(odr_data, model, beta0=[1.0])
	slope = odr_container.run().beta[0]
	#TODO PLOT SECTOR 0 some pairs (weird results)
	return slope
Exemple #13
0
def ODRfit(model, X, Y, p0, verbose=False):

    if type(p0) != 'numpy.ndarray':
        try:
            p0, up0 = unpack_unarray(p0)
        except TypeError:
            pass

    x, ux = unpack_unarray(X)
    y, uy = unpack_unarray(Y)

    modello = odrpack.Model(model)
    data = odrpack.RealData(x, y, sx=ux, sy=uy)
    engine = odrpack.ODR(data, modello, beta0=p0)
    output = engine.run()

    P = unc.correlated_values(output.beta, output.cov_beta)

    if verbose:
        output.pprint()

    return P, output.sum_square
Exemple #14
0
infile = sys.argv[1]
outfile = sys.argv[2]

dataframe = pd.read_pickle(infile)

def f(params, x):
    rho_per, rho_par, shift = params
    return rho_per + (rho_par - rho_per) * np.cos(x - shift)**2

slice = dataframe.loc[dataframe.current == CURRENT]
R_S = "Sample Resistance, R_S (Ohmns)"
R_S_E = "Error in R_S, alpha_R_S (Ohms)"
A = "Angle, theta (degrees)"
A_E = "Error in theta, alpha_theta (degrees)"
xs = slice[A] * np.pi / 180
ys = slice[R_S]
sx = slice[A_E] * np.pi / 180
sy = slice[R_S_E]
beta0 = [0., 2., 0.]
linear = odrpack.Model(f)
mydata = odrpack.RealData(xs, ys, sx=sx, sy=sy)
myodr = odrpack.ODR(mydata, linear, beta0, maxit=100)
myoutput = myodr.run()

fig, ax = plt.subplots()

ax.scatter(xs, ys, marker="+")
ax.plot(xs, f(myoutput.beta, xs))

fig.savefig(outfile)
Exemple #15
0
##
##    Test orth. regression
##
################################################################################

def f(B, theta1):
    return B[0] * (np.cos((2*np.pi)/360*theta1))**2  + B[1]

x = theta1
y = a1
sx = theta2
sy = a2

linear = odrpack.Model(f)

myData = odrpack.RealData(x, y, sx=sx, sy=sy)
myOdr = odrpack.ODR(myData, linear , beta0=[1,1])
myOdr.set_job(fit_type=2) #if set fit_type=2, returns the same as leastsq
out = myOdr.run()
#out.pprint()

coeff = out.beta[::-1]
err   = out.sd_beta[::-1]

print(coeff[0], err[0])
print(coeff[1], err[1])

################################################################################


Exemple #16
0
    stdp[x, :, :] = np.std(np.fft.ifft(np.fft.fft(temp) * noise_mask), -1)

# Reshape variables into a single column
mag = np.reshape(
    mag, (-1, nt))  # Reshapes variable intro 2D matrix of voxels x timepoints
ph = np.reshape(ph, (-1, nt))
stdm = np.reshape(
    stdm, (-1, ))  # Reshapes variable intro array of length = number of voxels
stdp = np.reshape(stdp, (-1, ))
mask = np.reshape(mask, (-1, ))

for x in range(mag.shape[0]):
    if mask[x]:
        design = ph[x, :]
        ests = [stdm[x] / stdp[x], 1.0]
        mydata = odr.RealData(design, mag[x, :], sx=stdp[x], sy=stdm[x])
        odr_obj = odr.ODR(mydata, linearfit, beta0=ests, maxit=600)
        res = odr_obj.run()
        est = res.y

        r2[x] = 1.0 - (np.sum((mag[x, :] - est)**2) / np.sum((mag[x, :])**2))

        # take out scaled phase signal and re-mean may need correction
        sim[x, :] = ph[x, :] * res.beta[0]
        filt[x, :] = mag[x, :] - est
        # estimate residuals
        residuals[x, :] = np.sign(mag[x, :] - est) * (
            np.sum(res.delta**2, axis=0) + res.eps**2)
        delta[x, :] = np.sum(
            res.delta, axis=0
        )  # res.delta --> Array of estimated errors in input variables (same shape as x)
print(linfit3)

#[ 2.34733290e-07 -6.08446455e-05]
#[ 2.62854976e-07 -8.24342656e-05]
#[ 2.58426791e-07 -7.77971621e-05]


def f(B, x):
    return B[0] * x + B[1]


linear = odrpack.Model(f)

#for i in range(0):
mydata1 = odrpack.RealData(druck[0],
                           brechungsindex[0],
                           sx=Er_druck[0],
                           sy=Er_brech[0])
mydata2 = odrpack.RealData(druck[1],
                           brechungsindex[1],
                           sx=Er_druck[1],
                           sy=Er_brech[1])
mydata3 = odrpack.RealData(druck[2],
                           brechungsindex[2],
                           sx=Er_druck[2],
                           sy=Er_brech[2])
myodr1 = odrpack.ODR(mydata1, linear, beta0=[1., 2.])
myodr2 = odrpack.ODR(mydata2, linear, beta0=[1., 2.])
myodr3 = odrpack.ODR(mydata3, linear, beta0=[1., 2.])
myoutput1 = myodr1.run()
myoutput2 = myodr2.run()
myoutput3 = myodr3.run()
Exemple #18
0
def peak_fit(xdata, ydata, iparams=[], peaktype='Gauss', maxit=300,
             background='constant', plot=False, func_out=False, debug=False):
    """
    fit function using odr-pack wrapper in scipy similar to
    https://github.com/tiagopereira/python_tips/wiki/Scipy%3A-curve-fitting
    for Gauss, Lorentz or Pseudovoigt-functions

    Parameters
    ----------
     xdata:     xcoordinates of the data to be fitted
     ydata:     ycoordinates of the data which should be fit

    keyword parameters:
     iparams:   initial paramters for the fit,
                determined automatically if not specified
     peaktype:  type of peak to fit: 'Gauss', 'Lorentz', 'PseudoVoigt',
                'PseudoVoigtAsym'
     maxit:     maximal iteration number of the fit
     background:    type of background, either 'constant' or 'linear'
     plot:      flag to ask for a plot to visually judge the fit.
                If plot is a string it will be used as figure name, which
                makes reusing the figures easier.
     func_out:  returns the fitted function, which takes the independent
                variables as only argument (f(x))

    Returns
    -------
     params,sd_params,itlim[,fitfunc]

    the parameters as defined in function Gauss1d/Lorentz1d/PseudoVoigt1d/
    PseudoVoigt1dasym(x, *param). In the case of linear background one more
    parameter is included! For every parameter the corresponding errors of the
    fit 'sd_params' are returned. A boolean flag 'itlim', which is False in
    the case of a successful fit is added by default. Further the function
    used in the fit can be returned (see func_out).
    """
    if plot:
        try:
            from matplotlib import pyplot as plt
        except ImportError:
            if config.VERBOSITY >= config.INFO_ALL:
                print("XU.math.peak_fit: Warning: plot "
                      "functionality not available")
            plot = False

    gfunc, gfunc_dx, gfunc_dp = _getfit_func(peaktype, background)

    # determine initial parameters
    _check_iparams(iparams, peaktype, background)
    if not any(iparams):
        iparams = _guess_iparams(xdata, ydata, peaktype, background)
    if config.VERBOSITY >= config.DEBUG:
        print("XU.math.peak_fit: iparams: %s" % str(tuple(iparams)))

    # set up odr fitting
    peak = odr.Model(gfunc, fjacd=gfunc_dx, fjacb=gfunc_dp)

    sy = numpy.sqrt(ydata)
    sy[sy == 0] = 1
    mydata = odr.RealData(xdata, ydata, sy=sy)

    myodr = odr.ODR(mydata, peak, beta0=iparams, maxit=maxit)
    myodr.set_job(fit_type=2)  # use least-square fit

    fit = myodr.run()
    if config.VERBOSITY >= config.DEBUG:
        print('XU.math.peak_fit:')
        fit.pprint()  # prints final message from odrpack

    fparam = fit.beta
    if peaktype in ('PseudoVoigt', 'PseudoVoigtAsym'):
        if background == 'linear':
            etaidx = -2
        else:
            etaidx = -1
        fparam[etaidx] = 0 if fparam[etaidx] < 0 else fparam[etaidx]
        fparam[etaidx] = 1 if fparam[etaidx] > 1 else fparam[etaidx]

    itlim = False
    if fit.stopreason[0] == 'Iteration limit reached':
        itlim = True
        if config.VERBOSITY >= config.INFO_LOW:
            print("XU.math.peak_fit: Iteration limit reached, "
                  "do not trust the result!")

    if plot:
        if isinstance(plot, basestring):
            plt.figure(plot)
        else:
            plt.figure('XU:peak_fit')
        plt.plot(xdata, ydata, 'ko', label='data', mew=2)
        if debug:
            plt.plot(xdata, gfunc(iparams, xdata), '-', color='0.5',
                     label='estimate')
        plt.plot(xdata, gfunc(fparam, xdata), 'r-',
                 label='%s-fit' % peaktype)
        plt.legend()

    if func_out:
        return fparam, fit.sd_beta, itlim, lambda x: gfunc(fparam, x)
    else:
        return fparam, fit.sd_beta, itlim
Exemple #19
0
 medbin = delete(medbin, delidx)
 binstrp = delete(binstrp, delidx)
 stdbin = delete(stdbin, delidx)
 
 
 '''
 if mb == 4.25:
     print(len(mmi[idx]))
     print(log10(rrup[idx]))
     print(medbin, binstrp)
     print(eqname[idx])
     crash
 '''
 if len(medbin < 2) and mb != 4.25:    
     # get intercept
     data = odrpack.RealData(binstrp, medbin)
     intfit = odrpack.Model(linear_fixed_slope)
     odr = odrpack.ODR(data, intfit, beta0=[5.0])
     
     #data = odrpack.RealData(10**binstrp, medbin, meta={'mag':mb})
     #intfit = odrpack.Model(near_src_trunc_fixed_slope)
     #odr = odrpack.ODR(data, intfit, beta0=[5.0])
     
     odr.set_job(fit_type=2) #if set fit_type=2, returns the same as leastsq, 0=ODR
     out = odr.run()
     intercept = out.beta
     intercepts.append(intercept[0])
     meanmagbin.append(mean(mmi[idx]))
     meanmws.append(mean(mw[idx]))
 else:
     intercepts.append(nan)
Exemple #20
0
def peak_fit(xdata, ydata, iparams=[], peaktype='Gauss', maxit=300,
             background='constant', plot=False, func_out=False, debug=False):
    """
    fit function using odr-pack wrapper in scipy similar to
    https://github.com/tiagopereira/python_tips/wiki/Scipy%3A-curve-fitting
    for Gauss, Lorentz or Pseudovoigt-functions

    Parameters
    ----------
    xdata :     array_like
        x-coordinates of the data to be fitted
    ydata :     array_like
        y-coordinates of the data which should be fit

    iparams :   list, optional
        initial paramters, determined automatically if not specified
    peaktype :  {'Gauss', 'Lorentz', 'PseudoVoigt', 'PseudoVoigtAsym', 'PseudoVoigtAsym2'}, optional
        type of peak to fit
    maxit :     int, optional
        maximal iteration number of the fit
    background : {'constant', 'linear'}, optional
        type of background function
    plot :      bool or str, optional
        flag to ask for a plot to visually judge the fit. If plot is a string
        it will be used as figure name, which makes reusing the figures easier.
    func_out :  bool, optional
        returns the fitted function, which takes the independent variables as
        only argument (f(x))

    Returns
    -------
    params :    list
        the parameters as defined in function `Gauss1d/Lorentz1d/PseudoVoigt1d/
        PseudoVoigt1dasym`. In the case of linear background one more parameter
        is included!
    sd_params : list
        For every parameter the corresponding errors are returned.
    itlim :     bool
        flag to tell if the iteration limit was reached, should be False
    fitfunc :   function, optional
        the function used in the fit can be returned (see func_out).
    """
    if plot:
        plot, plt = utilities.import_matplotlib_pyplot('XU.math.peak_fit')

    gfunc, gfunc_dx, gfunc_dp = _getfit_func(peaktype, background)

    # determine initial parameters
    _check_iparams(iparams, peaktype, background)
    if not any(iparams):
        iparams = _guess_iparams(xdata, ydata, peaktype, background)
    if config.VERBOSITY >= config.DEBUG:
        print("XU.math.peak_fit: iparams: %s" % str(tuple(iparams)))

    # set up odr fitting
    peak = odr.Model(gfunc, fjacd=gfunc_dx, fjacb=gfunc_dp)

    sy = numpy.sqrt(ydata)
    sy[sy == 0] = 1
    mydata = odr.RealData(xdata, ydata, sy=sy)

    myodr = odr.ODR(mydata, peak, beta0=iparams, maxit=maxit)
    myodr.set_job(fit_type=2)  # use least-square fit

    fit = myodr.run()
    if config.VERBOSITY >= config.DEBUG:
        print('XU.math.peak_fit:')
        fit.pprint()  # prints final message from odrpack

    fparam = fit.beta
    etaidx = []
    if peaktype in ('PseudoVoigt', 'PseudoVoigtAsym'):
        if background == 'linear':
            etaidx = [-2, ]
        else:
            etaidx = [-1, ]
    elif peaktype == 'PseudoVoigtAsym2':
        etaidx = [5, 6]
    for e in etaidx:
        fparam[e] = 0 if fparam[e] < 0 else fparam[e]
        fparam[e] = 1 if fparam[e] > 1 else fparam[e]

    itlim = False
    if fit.stopreason[0] == 'Iteration limit reached':
        itlim = True
        if config.VERBOSITY >= config.INFO_LOW:
            print("XU.math.peak_fit: Iteration limit reached, "
                  "do not trust the result!")

    if plot:
        if isinstance(plot, str):
            plt.figure(plot)
        else:
            plt.figure('XU:peak_fit')
        plt.plot(xdata, ydata, 'ok', label='data', mew=2)
        if debug:
            plt.plot(xdata, gfunc(iparams, xdata), '-', color='0.5',
                     label='estimate')
        plt.plot(xdata, gfunc(fparam, xdata), '-r',
                 label='%s-fit' % peaktype)
        plt.legend()

    if func_out:
        return fparam, fit.sd_beta, itlim, lambda x: gfunc(fparam, x)
    else:
        return fparam, fit.sd_beta, itlim
ang = np.array([20, 40, 60, 80, 100, 120, 140, 160, 180])
x = np.round(np.sin(np.radians(ang / 2)), 2)
y = (41, 48, 63, 76, 107, 111, 137, 162, 172)
error = np.round(np.sqrt(y), 2)
yerr1 = np.array(error)


def f(p, x):
    B, c = p

    return B * x + c


linear = odrpack.Model(f)

mydata = odrpack.RealData(x, y, sy=yerr1)

myodr = odrpack.ODR(mydata, linear, beta0=[0., 1.])

myoutput = myodr.run()

myoutput.pprint()

x_fit = np.linspace(x[0], x[-1], 100)

y_fit = f(myoutput.beta, x_fit)

plt.plot(x_fit, y_fit, label='ODR', lw=3, color='purple')

plt.xlabel('Sin(Theta/2)[Degrees]')
plt.ylabel('dN')
Exemple #22
0
def multPeakFit(x, data, peakpos, peakwidth, dranges=None,
                peaktype='Gaussian'):
    """
    function to fit multiple Gaussian/Lorentzian peaks with linear background
    to a set of data

    Parameters
    ----------
     x:  x-coordinate of the data
     data:  data array with same length as x
     peakpos:  initial parameters for the peak positions
     peakwidth:  initial values for the peak width
     dranges:  list of tuples with (min,max) value of the data ranges to use.
               does not need to have the same number of entries as peakpos
     peaktype: type of peaks to be used: can be either 'Gaussian' or
               'Lorentzian'

    Returns
    -------
     pos,sigma,amp,background

    pos:  list of peak positions derived by the fit
    sigma:  list of peak width derived by the fit
    amp:  list of amplitudes of the peaks derived by the fit
    background:  array of background values at positions x
    """
    if peaktype == 'Gaussian':
        pfunc = Gauss1d
        pfunc_derx = Gauss1d_der_x
    elif peaktype == 'Lorentzian':
        pfunc = Lorentz1d
        pfunc_derx = Lorentz1d_der_x
    else:
        raise ValueError('wrong value for parameter peaktype was given')

    def deriv_x(p, x):
        """
        function to calculate the derivative of the signal of multiple peaks
        and background w.r.t. the x-coordinate

        p: list of parameters, for every peak there needs to be position,
           sigma, amplitude and at the end two values for the linear background
           function (b0,b1)
        x: x-coordinate
        """
        derx = numpy.zeros(x.size)

        # sum up peak functions contributions
        for i in range(len(p) // 3):
            ldx = pfunc_derx(x, p[3 * i], p[3 * i + 1], p[3 * i + 2], 0)
            derx += ldx

        # background contribution
        k = p[-2]
        d = p[-1]
        b = numpy.ones(x.size) * k

        return derx + b

    def deriv_p(p, x):
        """
        function to calculate the derivative of the signal of multiple peaks
        and background w.r.t. the parameters

        p: list of parameters, for every peak there needs to be position,
           sigma, amplitude and at the end two values for the linear background
           function (b0,b1)
        x: x-coordinate

        returns derivative w.r.t. all the parameters with shape (len(p),x.size)
        """

        derp = numpy.empty(0)
        # peak functions contributions
        for i in range(len(p) // 3):
            lp = (p[3 * i], p[3 * i + 1], p[3 * i + 2], 0)
            if peaktype == 'Gaussian':
                derp = numpy.append(derp, -2 * (lp[0] - x) * pfunc(x, *lp))
                derp = numpy.append(
                    derp, (lp[0] - x) ** 2 / (2 * lp[1] ** 3) * pfunc(x, *lp))
                derp = numpy.append(derp, pfunc(x, *lp) / lp[2])
            else:  # Lorentzian
                derp = numpy.append(derp, 4 * (x - lp[0]) * lp[2] / lp[1] /
                                    (1 + (2 * (x - lp[0]) / lp[1]) ** 2) ** 2)
                derp = numpy.append(derp, 4 * (lp[0] - x) * lp[2] /
                                    lp[1] ** 2 / (1 + (2 * (x - lp[0]) /
                                                  lp[1]) ** 2) ** 2)
                derp = numpy.append(derp,
                                    1 / (1 + (2 * (x - p[0]) / p[1]) ** 2))

        # background contributions
        derp = numpy.append(derp, x)
        derp = numpy.append(derp, numpy.ones(x.size))

        # reshape output
        derp.shape = (len(p),) + x.shape
        return derp

    def fsignal(p, x):
        """
        function to calculate the signal of multiple peaks and background

        p: list of parameters, for every peak there needs to be position,
           sigma, amplitude and at the end two values for the linear background
           function (k,d)
        x: x-coordinate
        """
        f = numpy.zeros(x.size)

        # sum up peak functions
        for i in range(len(p) // 3):
            lf = pfunc(x, p[3 * i], p[3 * i + 1], p[3 * i + 2], 0)
            f += lf

        # background
        k = p[-2]
        d = p[-1]
        b = numpy.polyval((k, d), x)

        return f + b

    ##########################
    # create local data set (extract data ranges)
    if dranges:
        mask = numpy.array([False] * x.size)
        for i in range(len(dranges)):
            lrange = dranges[i]
            lmask = numpy.logical_and(x > lrange[0], x < lrange[1])
            mask = numpy.logical_or(mask, lmask)
        lx = x[mask]
        ldata = data[mask]
    else:
        lx = x
        ldata = data

    # create initial parameter list
    p = []

    # background
    k, d = numpy.polyfit(lx, ldata, 1)

    # peak parameters
    for i in range(len(peakpos)):
        amp = ldata[(lx - peakpos[i]) >= 0][0] - \
            numpy.polyval((k, d), lx)[(lx - peakpos[i]) >= 0][0]
        p += [peakpos[i], peakwidth[i], amp]

    # background parameters
    p += [k, d]

    if(config.VERBOSITY >= config.DEBUG):
        print("XU.math.multGaussFit: intial parameters")
        print(p)

    ##########################
    # fit with odrpack
    model = odr.Model(fsignal, fjacd=deriv_x, fjacb=deriv_p)
    odata = odr.RealData(lx, ldata)
    my_odr = odr.ODR(odata, model, beta0=p)
    # fit type 2 for least squares
    my_odr.set_job(fit_type=2)
    fit = my_odr.run()

    if(config.VERBOSITY >= config.DEBUG):
        print("XU.math.multPeakFit: fitted parameters")
        print(fit.beta)
    try:
        if fit.stopreason[0] not in ['Sum of squares convergence']:
            print("XU.math.multPeakFit: fit NOT converged (%s)"
                  % fit.stopreason[0])
            return None, None, None, None
    except:
        print("XU.math.multPeakFit: fit most probably NOT converged (%s)"
              % str(fit.stopreason))
        return None, None, None, None
    # prepare return values
    fpos = fit.beta[:-2:3]
    fwidth = numpy.abs(fit.beta[1:-2:3])
    famp = fit.beta[2::3]
    background = numpy.polyval((fit.beta[-2], fit.beta[-1]), x)

    return fpos, fwidth, famp, background
Exemple #23
0
def multPeakFit(x, data, peakpos, peakwidth, dranges=None,
                peaktype='Gaussian', returnerror=False):
    """
    function to fit multiple Gaussian/Lorentzian peaks with linear background
    to a set of data

    Parameters
    ----------
    x :     array-like
        x-coordinate of the data
    data :  array-like
        data array with same length as `x`
    peakpos : list
        initial parameters for the peak positions
    peakwidth : list
        initial values for the peak width
    dranges : list of tuples
        list of tuples with (min, max) value of the data ranges to use.  does
        not need to have the same number of entries as peakpos
    peaktype : {'Gaussian', 'Lorentzian'}
        type of peaks to be used
    returnerror : bool
        decides if the fit errors of pos, sigma, and amp are returned (default:
        False)

    Returns
    -------
    pos :       list
        peak positions derived by the fit
    sigma :     list
        peak width derived by the fit
    amp :       list
        amplitudes of the peaks derived by the fit
    background :    array-like
        background values at positions `x`
    if returnerror == True:
     sd_pos :   list
        standard error of peak positions as returned by scipy.odr.Output
     sd_sigma : list
        standard error of the peak width
     sd_amp :   list
        standard error of the peak amplitude
    """
    warnings.warn("deprecated function -> use the lmfit Python packge instead",
                  DeprecationWarning)
    if peaktype == 'Gaussian':
        pfunc = Gauss1d
        pfunc_derx = Gauss1d_der_x
    elif peaktype == 'Lorentzian':
        pfunc = Lorentz1d
        pfunc_derx = Lorentz1d_der_x
    else:
        raise ValueError('wrong value for parameter peaktype was given')

    def deriv_x(p, x):
        """
        function to calculate the derivative of the signal of multiple peaks
        and background w.r.t. the x-coordinate

        Parameters
        ----------
        p :     list
            parameters, for every peak there needs to be position, sigma,
            amplitude and at the end two values for the linear background
            function (b0, b1)
        x :     array-like
            x-coordinate
        """
        derx = numpy.zeros(x.size)

        # sum up peak functions contributions
        for i in range(len(p) // 3):
            ldx = pfunc_derx(x, p[3 * i], p[3 * i + 1], p[3 * i + 2], 0)
            derx += ldx

        # background contribution
        k = p[-2]
        b = numpy.ones(x.size) * k

        return derx + b

    def deriv_p(p, x):
        """
        function to calculate the derivative of the signal of multiple peaks
        and background w.r.t. the parameters

        Parameters
        ----------
        p :     list
            parameters, for every peak there needs to be position, sigma,
            amplitude and at the end two values for the linear background
            function (b0, b1)
        x :     array-like
            x-coordinate

        returns derivative w.r.t. all the parameters with shape (len(p),x.size)
        """

        derp = numpy.empty(0)
        # peak functions contributions
        for i in range(len(p) // 3):
            lp = (p[3 * i], p[3 * i + 1], p[3 * i + 2], 0)
            if peaktype == 'Gaussian':
                derp = numpy.append(derp, -2 * (lp[0] - x) * pfunc(x, *lp))
                derp = numpy.append(
                    derp, (lp[0] - x) ** 2 / (2 * lp[1] ** 3) * pfunc(x, *lp))
                derp = numpy.append(derp, pfunc(x, *lp) / lp[2])
            else:  # Lorentzian
                derp = numpy.append(derp, 4 * (x - lp[0]) * lp[2] / lp[1] /
                                    (1 + (2 * (x - lp[0]) / lp[1]) ** 2) ** 2)
                derp = numpy.append(derp, 4 * (lp[0] - x) * lp[2] /
                                    lp[1] ** 2 / (1 + (2 * (x - lp[0]) /
                                                       lp[1]) ** 2) ** 2)
                derp = numpy.append(derp,
                                    1 / (1 + (2 * (x - p[0]) / p[1]) ** 2))

        # background contributions
        derp = numpy.append(derp, x)
        derp = numpy.append(derp, numpy.ones(x.size))

        # reshape output
        derp.shape = (len(p),) + x.shape
        return derp

    def fsignal(p, x):
        """
        function to calculate the signal of multiple peaks and background

        Parameters
        ----------
        p :     list
            list of parameters, for every peak there needs to be position,
            sigma, amplitude and at the end two values for the linear
            background function (k, d)
        x :     array-like
            x-coordinate
        """
        f = numpy.zeros(x.size)

        # sum up peak functions
        for i in range(len(p) // 3):
            lf = pfunc(x, p[3 * i], p[3 * i + 1], p[3 * i + 2], 0)
            f += lf

        # background
        k = p[-2]
        d = p[-1]
        b = numpy.polyval((k, d), x)

        return f + b

    ##########################
    # create local data set (extract data ranges)
    if dranges:
        mask = numpy.array([False] * x.size)
        for i in range(len(dranges)):
            lrange = dranges[i]
            lmask = numpy.logical_and(x > lrange[0], x < lrange[1])
            mask = numpy.logical_or(mask, lmask)
        lx = x[mask]
        ldata = data[mask]
    else:
        lx = x
        ldata = data

    # create initial parameter list
    p = []

    # background
    # exclude +/-2 peakwidth around the peaks
    bmask = numpy.ones_like(lx, dtype=bool)
    for pp, pw in zip(peakpos, peakwidth):
        bmask = numpy.logical_and(bmask, numpy.logical_or(lx < (pp-2*pw),
                                                          lx > (pp+2*pw)))
    if numpy.any(bmask):
        k, d = numpy.polyfit(lx[bmask], ldata[bmask], 1)
    else:
        if(config.VERBOSITY >= config.DEBUG):
            print("XU.math.multPeakFit: no data outside peak regions!")
        k, d = (0, ldata.min())

    # peak parameters
    for i in range(len(peakpos)):
        amp = ldata[(lx - peakpos[i]) >= 0][0] - \
            numpy.polyval((k, d), lx)[(lx - peakpos[i]) >= 0][0]
        p += [peakpos[i], peakwidth[i], amp]

    # background parameters
    p += [k, d]

    if(config.VERBOSITY >= config.DEBUG):
        print("XU.math.multPeakFit: intial parameters")
        print(p)

    ##########################
    # fit with odrpack
    model = odr.Model(fsignal, fjacd=deriv_x, fjacb=deriv_p)
    odata = odr.RealData(lx, ldata)
    my_odr = odr.ODR(odata, model, beta0=p)
    # fit type 2 for least squares
    my_odr.set_job(fit_type=2)
    fit = my_odr.run()

    if(config.VERBOSITY >= config.DEBUG):
        print("XU.math.multPeakFit: fitted parameters")
        print(fit.beta)
    try:
        if fit.stopreason[0] not in ['Sum of squares convergence']:
            print("XU.math.multPeakFit: fit NOT converged (%s)"
                  % fit.stopreason[0])
            return Nono, None, None, None
    except IndexError:
        print("XU.math.multPeakFit: fit most probably NOT converged (%s)"
              % str(fit.stopreason))
        return None, None, None, None
    # prepare return values
    fpos = fit.beta[:-2:3]
    fwidth = numpy.abs(fit.beta[1:-2:3])
    famp = fit.beta[2::3]
    background = numpy.polyval((fit.beta[-2], fit.beta[-1]), x)
    if returnerror:
        sd_pos = fit.sd_beta[:-2:3]
        sd_width = fit.sd_beta[1:-2:3]
        sd_amp = fit.sd_beta[2::3]
        return fpos, fwidth, famp, background, sd_pos, sd_width, sd_amp
    return fpos, fwidth, famp, background
Exemple #24
0
mb = np.array(mb)
mw = np.array(mw)
idx_src = np.array(idx)

# Mw = np.array([x[3] for x in cat])
# Ml_pre = np.array([x[4] for x in cat])
# Ml_rev = np.array([x[5] for x in cat])
# Mw_ref = np.array([x[6] for x in cat])
#
# idx1 = np.where(Mw_ref=='HG')[0]
# idx2 = np.where(Mw_ref=='TA-SEA')[0]
# idx3 = np.where(Mw_ref=='TA-WA')[0]
# idx4 = np.where(Mw_ref=='other')[0]
############### bilinear auto
data = odrpack.RealData(mb[mb >= 3.5], mw[mb >= 3.5])
sx = np.interp(mw, [min(mw), max(mw)], [0.3, 0.1])
sy = sx
data = odrpack.RealData(mb[mb >= 3.5],
                        mw[mb >= 3.5],
                        sx=sx[mb >= 3.5],
                        sy=sy[mb >= 3.5])

xrng = np.arange(3.5, 6.0, step=0.01)

bilin_reg = odrpack.Model(bilinear_reg_free)
odr = odrpack.ODR(data, bilin_reg, beta0=[0.7, 1.0, 1.0, 3.5])

odr.set_job(fit_type=0)  #if set fit_type=2, returns the same as least squares
out = odr.run()
out.pprint()
    #d1_array.append(d1)
    #d2_array.append(d2)
    #d3_array.append(d3)

    plt.semilogx(10**medx, logmedamp, 'rs', ms=6)
    ax.set_xscale('log')

    ###############################################################################
    # fit data
    ###############################################################################
    def fit_site_amp(c, x):
        return c[0] + c[1] / (x - log10(150))

    #data = odrpack.RealData(medx, logmedamp)
    idx = where(isfinite(Yres))[0]
    data = odrpack.RealData(log10(vs30[idx]), Yres[idx])

    sitefit = odrpack.Model(fit_site_amp)
    odr = odrpack.ODR(data, sitefit, beta0=[0.1, 0.])

    odr.set_job(
        fit_type=2)  #if set fit_type=2, returns the same as leastsq, 0=ODR
    out = odr.run()
    c = out.beta
    print(c)
    coefs1.append(c)

    # plot fit
    dx = arange(2., 3, 0.01)
    dy = c[0] + c[1] / (dx - log10(150))
    #dy = d0 + d1*dx**3 + d2*dx**2 + d3*dx
# plot bi-linear interface
cinter_len = 10**(lenc + lengrd1*mrng)
idx = mrng > lenhmag
ylen = lenc + lengrd1 * lenhmag
cinter_len[idx] = 10**(lengrd2 * (mrng[idx]-lenhmag) + ylen)
'''
h = plt.semilogy(mrng, cinter_len, 'k-', lw=2.0)
hh = [h[0]]

# fit lengths
savec = []
tabtxt = 'Length\nType,a,SEa,b,sig,Range\n'

for i in range(0, len(fmag)):
    data = odrpack.RealData(array(fmag[i]),log10(array(flen[i])))
    grad = grads[0]
    
    lin = odrpack.Model(linear_reg_fix_slope)
    odr = odrpack.ODR(data, lin, beta0=[-2.])
    odr.set_job(fit_type=0) #if set fit_type=2, returns the same as leastsq
    out = odr.run()
    out.pprint()
    c = out.beta[0]
    savec.append(c)
    regmrng = arange(min(fmag[i]), max(fmag[i])+0.01, 0.01)
    clen = 10**(c + grad * regmrng)
    print i
    h = plt.semilogy(regmrng, clen, '-', color=cs2[i+1], lw=2.0)
    hh.append(h[0])
    
Exemple #27
0

def fit_function(w, F0, w0, gamma):
    #gamma = 0.01515
    return F0 / pylab.sqrt((w0**2 - w**2)**2 + 4.0 * (gamma**2) * (w**2))


def fit_function_ODR(pars, w):
    #pars[2] = 0.01515
    return pars[0] / pylab.sqrt((pars[1]**2 - w**2)**2 + 4.0 * (pars[2]**2) *
                                (w**2))


# Run the actual ODR.
model = odrpack.Model(fit_function_ODR)
data = odrpack.RealData(s, x)
odr = odrpack.ODR(data, model, beta0=(53.7, 4.7, 0.064))
out = odr.run()
popt, pcov = out.beta, out.cov_beta
F0, w0, gamma = popt
dF0, dw0, dgamma = numpy.sqrt(pcov.diagonal())
chisq = out.sum_square
# !Run the actual ODR.
# Run the actual ODR.
model = odrpack.Model(fit_function_ODR)
data = odrpack.RealData(s, x)
odr = odrpack.ODR(data, model, beta0=(F0, w0, gamma))
out = odr.run()
popt, pcov = out.beta, out.cov_beta
F0, w0, gamma = popt
dF0, dw0, dgamma = numpy.sqrt(pcov.diagonal())
    def fitDoubleCrystalBallPeak(self):
        params = np.array([
            self.peak1_paramsEdits[0].value(),
            self.peak1_paramsEdits[1].value(),
            self.peak1_paramsEdits[2].value(),
            self.peak1_paramsEdits[3].value(),
            self.peak2_paramsEdits[0].value(),
            self.peak2_paramsEdits[1].value(),
            self.peak2_paramsEdits[2].value(), 0.9, 4
        ])

        model = odr.Model(lineshape.Double_Crystalball)
        odr_data = odr.RealData(self.x_cut,
                                self.y_cut)  #, sy = np.sqrt(self.y_cut))
        myodr = odr.ODR(odr_data, model, beta0=params)
        myodr.set_job(fit_type=0)
        myoutput = myodr.run()

        self.params = myoutput.beta
        params_cov = myoutput.cov_beta

        params_output = []
        params_red_chi2 = myoutput.res_var

        single_index = [0, 1, 2, 3, 7, 8]
        params_single = self.params[single_index]
        double_index = [4, 5, 6, 3, 7, 8]
        params_double = self.params[double_index]

        content1, error1 = integrate.quad(
            lineshape.Single_Crystalball_integrand,
            self.x_fit[0],
            self.x_fit[-1],
            args=tuple(params_single))
        content2, error2 = integrate.quad(
            lineshape.Single_Crystalball_integrand,
            self.x_fit[0],
            self.x_fit[-1],
            args=tuple(params_double))

        params_output.append(content1)
        params_output.append(params_red_chi2)
        params_output.append(content2)
        self.params_outputs = np.array(params_output)

        for i in range(len(self.params)):
            if i < 4:
                self.peak1_paramsEdits[i].setValue(self.params[i])
            if 3 < i < 7:
                self.peak2_paramsEdits[i - 4].setValue(self.params[i])

        self.peak1_contentEdit.setText(str(self.params_outputs[0]))
        self.peak1_chi2Edit.setText(str(self.params_outputs[1]))
        self.peak2_contentEdit.setText(str(self.params_outputs[2]))

        self.plotWidget.plot(clear=True)
        histo = pg.PlotCurveItem(self.x, self.y[:-1], stepMode=True)
        self.plotWidget.addItem(histo)

        if self.PeaksButton.isChecked() == False:
            fitPen = pg.mkPen(color=(204, 0, 0), width=2)
            self.plotWidget.plot(self.x_fit,
                                 lineshape.Double_Crystalball(
                                     self.params, self.x_fit),
                                 pen=fitPen)
        if self.PeaksButton.isChecked() == True:
            fitPen = pg.mkPen(color=(204, 0, 0),
                              width=2,
                              style=QtCore.Qt.DashLine)
            params1 = np.array([
                self.peak1_paramsEdits[0].value(),
                self.peak1_paramsEdits[1].value(),
                self.peak1_paramsEdits[2].value(),
                self.peak1_paramsEdits[3].value(), 0.9, 4
            ])
            params2 = np.array([
                self.peak2_paramsEdits[0].value(),
                self.peak2_paramsEdits[1].value(),
                self.peak2_paramsEdits[2].value(),
                self.peak1_paramsEdits[3].value(), 0.9, 4
            ])
            self.plotWidget.plot(self.x_fit,
                                 lineshape.Single_Crystalball(
                                     params1, self.x_fit),
                                 pen=fitPen)
            self.plotWidget.plot(self.x_fit,
                                 lineshape.Single_Crystalball(
                                     params2, self.x_fit),
                                 pen=fitPen)
        self.plotWidget.addItem(self.vLine, ignoreBounds=True)
        self.plotWidget.addItem(self.hLine, ignoreBounds=True)
Exemple #29
0
        if len(nidx) > 0:

            namps = log10(mamps) - logmedamp[nidx]

            if len(log_norm_amps) == 0:
                log_norm_amps = namps
                norm_rhyps = mrhyps
            else:
                log_norm_amps = hstack((log_norm_amps, namps))
                norm_rhyps = hstack((norm_rhyps, mrhyps))

        # regress mag-dependent data and get intercept
        didx = where((medx >= 2) & (medx <= 3.35))[0]

        data = odrpack.RealData(medx[didx], logmedamp[didx])
        intfit = odrpack.Model(linear_fixed_slope)
        odr = odrpack.ODR(data, intfit, beta0=[5.0])

        odr.set_job(
            fit_type=2)  #if set fit_type=2, returns the same as leastsq, 0=ODR
        out = odr.run()
        intercept = out.beta

        if round(m, 1) != 4.9 and round(m, 1) != 5.5:  #or round(m,1) > 6.6
            m_intercept.append(intercept[0])
            m_reg.append(m)

        xplt = array([2, 3])
        yplt = meanslope * xplt + intercept[0]
Exemple #30
0
def main():
    # make output directory
    if not os.path.exists("output"):
        os.makedirs("output")

    # get data and caluclate reflectance
    n_pix = np.genfromtxt(s_filename, delimiter=",")[:, 0]
    i_s = np.genfromtxt(s_filename, delimiter=",")[:, 1]
    i_p = np.genfromtxt(p_filename, delimiter=",")[:, 1]
    i_bg = np.genfromtxt(bg_filename, delimiter=",")[:, 1]
    ref = (i_p - i_bg) / (i_s - i_bg)

    # find beam edges
    popt, pcov = curve_fit(gaus, n_pix, i_s, p0=[1, 1000, 50])
    i_width = gaus(popt[1], *popt) / np.e**2
    i_max = int(popt[1])
    beam_lim = np.argmax(
        i_s[:i_max] -
        i_width > 0), len(n_pix) - np.argmax(i_s[:-i_max:-1] - i_width > 0)
    idx_centre = int(np.diff(beam_lim) / 2) + beam_lim[0] - 1

    # plot raw data and threshold limits
    plt.figure(figsize=(8, 6))
    plt.plot(n_pix, i_s, label="S polarised")
    plt.plot(n_pix, i_p, label="P polarised")
    plt.plot(n_pix, i_bg, label="Background")
    plt.plot(n_pix, gaus(n_pix, *popt), label="Gaussian")
    plt.plot(n_pix[idx_centre], i_width, "kx", ms=8)
    plt.plot((n_pix[beam_lim[1]], n_pix[beam_lim[0]]),
             (i_s[beam_lim[1]], i_s[beam_lim[0]]),
             "kx",
             ms=8)
    plt.text(n_pix[beam_lim[0]] + 20,
             i_width - 0.01,
             r"$n_{edge, low}$",
             ha="left",
             va="top")
    plt.text(n_pix[beam_lim[1]] + 20,
             i_width - 0.01,
             r"$n_{edge, up}$",
             ha="left",
             va="top")
    plt.text(n_pix[idx_centre] + 20,
             i_width - 0.01,
             r"$n_{centre}$",
             ha="left",
             va="top")
    plt.xlabel("Pixel number")
    plt.ylabel("Intensity")
    plt.title("S and P polarised intensities for sample 21")
    plt.legend()
    plt.show()

    # get range of angles and error
    n_pix_shift = np.arange(0, 2048, 1) - idx_centre
    correct = angle_offset(5)
    theta_range = beam_angle(n_pix_shift) + (t_prism * correct[0] + correct[1])
    n_err = err_edge(np.sqrt(np.diagonal(pcov)), popt, i_width)
    theta_err = err_angle(n_pix_shift, n_err)
    err_red = theta_err[beam_lim[0]:beam_lim[1]]
    ref_red_ = ref[beam_lim[0]:beam_lim[1]]
    theta_red = theta_range[beam_lim[0]:beam_lim[1]]
    ref_red = ref_red_ / max(ref_red_[500:-500])

    # moving average
    ref_av = moving_average(ref_red, n=n_av)
    theta_av = np.linspace(min(theta_red), max(theta_red), len(ref_av))

    # fit whole reflectivity to asymmetric
    asymm = odr.Model(asymmetric)
    data_full = odr.RealData(theta_red, ref_red, sx=err_red)
    fit_asy_full = odr.ODR(data_full,
                           asymm,
                           beta0=[0.9, 0.4, 0.4, t_prism + 6, -0.6],
                           maxit=100).run()
    ref_max = argrelextrema(asymmetric(fit_asy_full.beta, theta_red),
                            np.greater)[0][0]

    # fit right side of reflectivity to asymmetric
    idx_asy = ref_max + delta_3
    data_right = odr.RealData(theta_red[idx_asy:-400],
                              ref_red[idx_asy:-400],
                              sx=err_red[idx_asy:-400])
    fit_asy = odr.ODR(data_right,
                      asymm,
                      beta0=[0.9, 0.4, 0.4, t_prism + 6, -0.6],
                      maxit=100).run()
    r_sq_asy = 1 - fit_asy.res_var / np.var(ref_red[idx_asy:], ddof=1)
    data_asy = asymmetric(fit_asy.beta, theta_red)

    # fit left side of reflectivity to sigmoid
    sig = odr.Model(sigmoid)
    idx_sig = ref_max + delta_2
    data_left = odr.RealData(theta_red[delta_1:idx_sig],
                             ref_red[delta_1:idx_sig],
                             sx=err_red[delta_1:idx_sig])
    fit_sig = odr.ODR(data_left,
                      sig,
                      beta0=[0.15, -2.3, t_prism + 4, 0.8],
                      maxit=100).run()
    r_sq_sig = 1 - fit_sig.res_var / np.var(ref_red[delta_1:idx_sig], ddof=1)
    data_sig = sigmoid(fit_sig.beta, theta_red)
    data_sig_asy = sig_asy(
        (*fit_asy.beta, *fit_sig.beta[:-1]), theta_red) - fit_sig.beta[0]

    # first derrivative of asymmetric-sigmoid
    a, b, c, d, e, f, g, h, x = sym.symbols("a b c d e f g h x")
    sym_fit = a * (1 - (b + c * (x - d)) /
                   ((x - d)**2 + e**2)) + (f / (1 + sym.exp(g * (x - h))))
    fit = sym.lambdify((a, b, c, d, e, f, g, h, x), sym_fit.diff(x), "numpy")
    d_fit = fit(*(*fit_asy.beta, *fit_sig.beta[:-1]), theta_red)

    # spr, critical angle, min reflectance and FWHM
    idx_spr = argrelextrema(data_sig_asy, np.less)[0][0]
    idx_crit = argrelextrema(d_fit, np.greater)[0][0]
    theta_spr = theta_red[idx_spr]
    spr_err = np.sqrt(err_red[idx_spr]**2)
    theta_crit = theta_red[idx_crit]
    crit_err = np.sqrt(err_red[idx_crit]**2)
    min_ref = data_sig_asy[idx_spr]
    err_min_ref = min_ref * np.linalg.norm(
        (*fit_sig.sd_beta / fit_sig.beta, *fit_asy.sd_beta / fit_asy.beta))
    fwhm_1 = find_nearest(data_sig_asy[ref_max:idx_spr],
                          data_sig_asy[ref_max] / 2) + ref_max
    fwhm_2 = find_nearest(data_sig_asy[idx_spr:],
                          data_sig_asy[ref_max] / 2) + idx_spr
    fwhm = np.abs(theta_red[fwhm_2] - theta_red[fwhm_1])
    err_fwhm = np.sqrt(err_red[fwhm_1]**2 + err_red[fwhm_2]**2)

    # plot ratio of s and p intensities, moving average and fitted curves
    if isinstance(prism_no, float):
        prism_no_str = str(int(prism_no)) + "a"
    else:
        prism_no_str = prism_no
    plt.figure(figsize=(8, 6))
    plt.plot(theta_red, ref_red, "silver", label="Reflectance data")
    plt.plot(theta_red, data_sig_asy, label="Asymmetric-sigmoid")
    if details:
        plt.plot(theta_av, ref_av, label="Moving average, $n={}$".format(n_av))
        plt.plot(theta_red, data_asy, label="Asymmetric")
        plt.plot(theta_red, data_sig, label="Sigmoid")
        plt.plot(theta_red,
                 d_fit,
                 label="1st derivative of \n asymmetric-sigmoid")
        plt.plot((theta_red[delta_1], theta_red[idx_sig]),
                 (ref_red[delta_1], ref_red[idx_sig]),
                 "s",
                 label="Sigmoid data range")
        plt.plot((theta_red[idx_asy], theta_red[-1]),
                 (ref_red[idx_asy], ref_red[-1]),
                 "s",
                 label="Asymmetric data range")
        plt.plot((theta_red[fwhm_1], theta_red[fwhm_2]),
                 (ref_red[fwhm_1], ref_red[fwhm_2]),
                 "s",
                 label="FWHM limits")
        plt.plot(theta_crit, d_fit[idx_crit], "kx", ms=8)
        plt.plot(theta_spr, data_asy[idx_spr], "kx", ms=8)
        plt.plot(theta_red[ref_max],
                 asymmetric(fit_asy.beta, theta_red)[ref_max],
                 "kx",
                 ms=8)
        plt.text(theta_crit + 0.2, d_fit[idx_crit] - 0.02, r"$\theta_{crit}$")
        plt.text(theta_spr + 0.2, data_asy[idx_spr] - 0.02, r"$\theta_{spr}$")
        plt.text(theta_red[ref_max] - 0.2,
                 asymmetric(fit_asy.beta, theta_red)[ref_max] - 0.08,
                 r"$\theta_{max}$")
    plt.xlim(theta_red[0], theta_red[-1])
    plt.ylim(-0.1, 1.1)
    plt.xlabel(r"Incidence angle /$^\circ$")
    plt.ylabel("Normalised reflectance")
    plt.title("Reflectance plot for sample {}".format(prism_no_str))
    plt.legend(loc=7)
    # formatted string containing the parameters
    text = """Sample {} on {}: \nprism angle {} deg\nsensor distance {} m\nSPR angle = {} +/- {} deg
Critical angle = {} +/- {} deg \nR squared (asymmetric)= {} \nR squared (sigmoid)= {}
Asymmetric parameters: {} \nAsymmetric parameter errors: {} \nSigmoid parameters: {}
Sigmoid parameter errors: {} \nMinimum reflectance {} +/- {} \nFWHM {} +/- {} deg
delta (1, 2, 3): {}, {}, {}
\n""".format(prism_no_str,
             datetime.datetime.now().strftime("%d/%m/%y %H:%M"), t_prism,
             d_sens, theta_spr, spr_err, theta_crit, crit_err, r_sq_asy,
             r_sq_sig, fit_asy.beta, fit_asy.sd_beta, fit_sig.beta,
             fit_sig.sd_beta, min_ref, err_min_ref, fwhm, err_fwhm, delta_1,
             delta_2, delta_3)
    if export:
        # save figure
        plt.savefig(plotname, dpi=100, bbox_inches="tight")
        # log parameters
        file = open("log.txt", "w")
        file = open("output/log.txt", "a")
        file.write(text)
        file.close()
        # write data to csv
        np.savetxt(txtname,
                   np.vstack((theta_red, ref_red)).T,
                   delimiter=",",
                   fmt="%f",
                   header="theta,R")
        # write parameters to csv
        arr = [
            prism_no, theta_spr, spr_err, theta_crit, crit_err, r_sq_asy,
            r_sq_sig, min_ref, err_min_ref, fwhm, err_fwhm
        ]
        with open("output/param.csv", "ab") as f:
            np.savetxt(f, arr, delimiter=",", newline=",", fmt="%f")
            f.write(b'\n')
    plt.show()
    print(text)