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)
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}')
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]
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)