Beispiel #1
0
def run_snip1d(img):

    from hexrd.ui.hexrd_config import HexrdConfig

    snip_width = snip_width_pixels()
    numiter = HexrdConfig().polar_snip1d_numiter

    # !!!: need a selector between
    # imageutil.fast_snip1d() and imageutil.snip1d()
    return imageutil.snip1d(img, snip_width, numiter)
Beispiel #2
0
def run_snip1d(img):

    from hexrd.ui.hexrd_config import HexrdConfig

    snip_width = snip_width_pixels()
    numiter = HexrdConfig().polar_snip1d_numiter
    algorithm = HexrdConfig().polar_snip1d_algorithm

    if algorithm == SnipAlgorithmType.Fast_SNIP_1D:
        return imageutil.fast_snip1d(img, snip_width, numiter)
    elif algorithm == SnipAlgorithmType.SNIP_1D:
        return imageutil.snip1d(img, snip_width, numiter)
    elif algorithm == SnipAlgorithmType.SNIP_2D:
        return imageutil.snip2d(img, snip_width, numiter)

    # (else:)
    raise RuntimeError(f'Unrecognized polar_snip1d_algorithm {algorithm}')
Beispiel #3
0
def estimate_pk_parms_1d(x, f, pktype='pvoigt'):
    """
    Gives initial guess of parameters for analytic fit of one dimensional peak
    data.

    Required Arguments:
    x -- (n) ndarray of coordinate positions
    f -- (n) ndarray of intensity measurements at coordinate positions x
    pktype -- string, type of analytic function that will be used to fit the
    data, current options are "gaussian", "lorentzian",
    "pvoigt" (psuedo voigt), and "split_pvoigt" (split psuedo voigt)

    Outputs:
    p -- (m) ndarray containing initial guesses for parameters for the input
    peaktype
    (see peak function help for what each parameters corresponds to)
    """
    npts = len(x)
    assert len(f) == npts, "ordinate and data must be same length!"

    # handle background
    # ??? make kernel width a kwarg?
    bkg = snip1d(np.atleast_2d(f), w=int(2*npts/3.)).flatten()

    # fit linear bg and grab params
    bp, _ = optimize.curve_fit(lin_fit_obj, x, bkg, jac=lin_fit_jac)
    bg0 = bp[-1]
    bg1 = bp[0]

    # set remaining params
    pint = f - lin_fit_obj(x, *bp)
    cen_index = np.argmax(pint)
    A = pint[cen_index]
    x0 = x[cen_index]

    # fix center index
    if cen_index > 0 and cen_index < npts - 1:
        left_hm = np.argmin(abs(pint[:cen_index] - 0.5*A))
        right_hm = np.argmin(abs(pint[cen_index:] - 0.5*A))
    elif cen_index == 0:
        right_hm = np.argmin(abs(pint[cen_index:] - 0.5*A))
        left_hm = right_hm
    elif cen_index == npts - 1:
        left_hm = np.argmin(abs(pint[:cen_index] - 0.5*A))
        right_hm = left_hm

    # FWHM estimation
    try:
        FWHM = x[cen_index + right_hm] - x[left_hm]
    except(IndexError):
        FWHM = 0
    if FWHM <= 0 or FWHM > 0.75*npts:
        # something is weird, so punt...
        FWHM = 0.25*(x[-1] - x[0])

    # set params
    if pktype in ['gaussian', 'lorentzian']:
        p = [A, x0, FWHM, bg0, bg1]
    elif pktype == 'pvoigt':
        p = [A, x0, FWHM, 0.5, bg0, bg1]
    elif pktype == 'split_pvoigt':
        p = [A, x0, FWHM, FWHM, 0.5, 0.5, bg0, bg1]
    else:
        raise RuntimeError("pktype '%s' not understood" % pktype)

    return np.r_[p]
Beispiel #4
0
def estimate_mpk_parms_1d(
        pk_pos_0, x, f,
        pktype='pvoigt', bgtype='linear',
        fwhm_guess=0.07, center_bnd=0.02
        ):
    """
    Generate function-specific estimate for multi-peak parameters.

    Parameters
    ----------
    pk_pos_0 : TYPE
        DESCRIPTION.
    x : TYPE
        DESCRIPTION.
    f : TYPE
        DESCRIPTION.
    pktype : TYPE, optional
        DESCRIPTION. The default is 'pvoigt'.
    bgtype : TYPE, optional
        DESCRIPTION. The default is 'linear'.
    fwhm_guess : TYPE, optional
        DESCRIPTION. The default is 0.07.
    center_bnd : TYPE, optional
        DESCRIPTION. The default is 0.02.

    Returns
    -------
    p0 : TYPE
        DESCRIPTION.
    bnds : TYPE
        DESCRIPTION.

    """
    npts = len(x)
    assert len(f) == npts, "ordinate and data must be same length!"

    num_pks = len(pk_pos_0)
    min_val = np.min(f)

    # estimate background with SNIP1d
    bkg = snip1d(np.atleast_2d(f),
                 w=int(np.floor(0.25*len(f)))).flatten()

    # fit linear bg and grab params
    bp, _ = optimize.curve_fit(lin_fit_obj, x, bkg, jac=lin_fit_jac)
    bg0 = bp[-1]
    bg1 = bp[0]

    if pktype == 'gaussian' or pktype == 'lorentzian':
        p0tmp = np.zeros([num_pks, 3])
        p0tmp_lb = np.zeros([num_pks, 3])
        p0tmp_ub = np.zeros([num_pks, 3])

        # x is just 2theta values
        # make guess for the initital parameters
        for ii in np.arange(num_pks):
            pt = np.argmin(np.abs(x - pk_pos_0[ii]))
            p0tmp[ii, :] = [
                (f[pt] - min_val),
                pk_pos_0[ii],
                fwhm_guess
            ]
            p0tmp_lb[ii, :] = [
                (f[pt] - min_val)*0.1,
                pk_pos_0[ii] - center_bnd,
                fwhm_guess*0.5
            ]
            p0tmp_ub[ii, :] = [
                (f[pt] - min_val)*10.0,
                pk_pos_0[ii] + center_bnd,
                fwhm_guess*2.0
            ]
    elif pktype == 'pvoigt':
        p0tmp = np.zeros([num_pks, 4])
        p0tmp_lb = np.zeros([num_pks, 4])
        p0tmp_ub = np.zeros([num_pks, 4])

        # x is just 2theta values
        # make guess for the initital parameters
        for ii in np.arange(num_pks):
            pt = np.argmin(np.abs(x - pk_pos_0[ii]))
            p0tmp[ii, :] = [
                (f[pt] - min_val),
                pk_pos_0[ii],
                fwhm_guess,
                0.5
            ]
            p0tmp_lb[ii, :] = [
                (f[pt] - min_val)*0.1,
                pk_pos_0[ii] - center_bnd,
                fwhm_guess*0.5,
                0.0
            ]
            p0tmp_ub[ii, :] = [
                (f[pt] - min_val+1.)*10.0,
                pk_pos_0[ii] + center_bnd,
                fwhm_guess*2.0,
                1.0
            ]
    elif pktype == 'split_pvoigt':
        p0tmp = np.zeros([num_pks, 6])
        p0tmp_lb = np.zeros([num_pks, 6])
        p0tmp_ub = np.zeros([num_pks, 6])

        # x is just 2theta values
        # make guess for the initital parameters
        for ii in np.arange(num_pks):
            pt = np.argmin(np.abs(x - pk_pos_0[ii]))
            p0tmp[ii, :] = [
                (f[pt] - min_val),
                pk_pos_0[ii],
                fwhm_guess,
                fwhm_guess,
                0.5,
                0.5
            ]
            p0tmp_lb[ii, :] = [
                (f[pt] - min_val)*0.1,
                pk_pos_0[ii] - center_bnd,
                fwhm_guess*0.5,
                fwhm_guess*0.5,
                0.0,
                0.0
            ]
            p0tmp_ub[ii, :] = [
                (f[pt] - min_val)*10.0,
                pk_pos_0[ii] + center_bnd,
                fwhm_guess*2.0,
                fwhm_guess*2.0,
                1.0,
                1.0
            ]

    if bgtype == 'linear':
        num_pk_parms = len(p0tmp.ravel())
        p0 = np.zeros(num_pk_parms+2)
        lb = np.zeros(num_pk_parms+2)
        ub = np.zeros(num_pk_parms+2)
        p0[:num_pk_parms] = p0tmp.ravel()
        lb[:num_pk_parms] = p0tmp_lb.ravel()
        ub[:num_pk_parms] = p0tmp_ub.ravel()

        p0[-2] = bg0
        p0[-1] = bg1

        lb[-2] = minf
        lb[-1] = minf

        ub[-2] = inf
        ub[-1] = inf

    elif bgtype == 'constant':
        num_pk_parms = len(p0tmp.ravel())
        p0 = np.zeros(num_pk_parms+1)
        lb = np.zeros(num_pk_parms+1)
        ub = np.zeros(num_pk_parms+1)
        p0[:num_pk_parms] = p0tmp.ravel()
        lb[:num_pk_parms] = p0tmp_lb.ravel()
        ub[:num_pk_parms] = p0tmp_ub.ravel()

        p0[-1] = np.average(bkg)
        lb[-1] = minf
        ub[-1] = inf

    elif bgtype == 'quadratic':
        num_pk_parms = len(p0tmp.ravel())
        p0 = np.zeros(num_pk_parms+3)
        lb = np.zeros(num_pk_parms+3)
        ub = np.zeros(num_pk_parms+3)
        p0[:num_pk_parms] = p0tmp.ravel()
        lb[:num_pk_parms] = p0tmp_lb.ravel()
        ub[:num_pk_parms] = p0tmp_ub.ravel()

        p0[-3] = bg0
        p0[-2] = bg1
        lb[-3] = minf
        lb[-2] = minf
        lb[-1] = minf
        ub[-3] = inf
        ub[-2] = inf
        ub[-1] = inf

    return p0, (lb, ub)