def baseDerivative(self, xdata, params): """ Return the derivative df/dx at each xdata (=x). z = ( x - p1 + 1j * p3 ) / ( p2 * sqrt2 ) z0 = 1j * p3 / ( p2 * sqrt2 ) vgt = p0 / wofz0 * re( wofzz ) dvdx = dvdz * dzdx dvdz = p0 / wofz0 * dwdz dwdz = 2j / sqrt(pi) - 2 * z * wofzz dzdx = 1 / ( p2 * sqrt2 ) Parameters ---------- xdata : array_like values at which to calculate the result params : array_like values for the parameters. """ sigma = params[2] * math.sqrt(2.0) gamma = params[3] z0 = 1j * gamma / sigma z = (xdata - params[1]) / sigma + z0 wofz0 = numpy.real(special.wofz(z0)) wofzz = special.wofz(z) dwdz = 2j / math.sqrt(math.pi) - 2 * z * wofzz return numpy.real(params[0] * dwdz / (wofz0 * sigma))
def voigt(mu, fwhm, shape, x): """ Evaluates a Voigt absorption profile across the `x` values with a given local continuum. V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) z = (x+i*gam)/(sig*sqrt(2)) :param mu: The centroid of the line. :param fwhm: The full-width half-maximum of the Gaussian profile. :param shape: The shape parameter. :param x: An array of x-points. """ n = len(x) if not isinstance(x, float) else 1 profile = 1. / wofz(np.zeros((n)) + 1j * np.sqrt(np.log(2.0)) * shape).real return profile * wofz(2*np.sqrt(np.log(2.0)) * (x - mu)/fwhm \ + 1j * np.sqrt(np.log(2.0))*shape).real
def _efieldn_mit(x, y, sig_x, sig_y): '''The charge-normalised electric field components of a two-dimensional Gaussian charge distribution according to M. Bassetti and G. A. Erskine in CERN-ISR-TH/80-06. Return (E_x / Q, E_y / Q). Assumes sig_x > sig_y and mean_x == 0 as well as mean_y == 0. For convergence reasons of the erfc, use only x > 0 and y > 0. Uses FADDEEVA C++ implementation from MIT (via SciPy >= 0.13.0). ''' # timing was ~0.522 ms for: # x = np.arange(-1e-5, 1e-5, 1e-8) # y = np.empty(len(x)) # sig_x = 1.2e-6 # sig_y = 1e-6 sig_sqrt = TransverseGaussianSpaceCharge._sig_sqrt(sig_x, sig_y) w1 = wofz((x + 1j * y) / sig_sqrt) ex = exp(-x**2 / (2 * sig_x**2) + -y**2 / (2 * sig_y**2)) w2 = wofz(x * sig_y/(sig_x*sig_sqrt) + y * sig_x/(sig_y*sig_sqrt) * 1j) val = (w1 - ex * w2) / (2 * epsilon_0 * np.sqrt(pi) * sig_sqrt) return val.imag, val.real
def voigt_profile(x, parameters, continuum): """Evaluates a Voigt absorption profile across the `x` values with a given local continuum. V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) z = (x+i*gam)/(sig*sqrt(2)) Inputs ------ x : `np.array` The values to evaluate the Voigt profile for. parameters : list (length 4) The input parameters for the profile: [pos, fwhm, amp, shape] continuum : `np.array` or callable function The continuum over the given region. """ pos, fwhm, amp, shape = parameters # Is the continuum call-able? if hasattr(continuum, '__call__'): continuum = continuum(x) n = len(x) if not isinstance(x, float) else 1 profile = 1 / wofz(np.zeros((n)) + 1j * np.sqrt(np.log(2.0)) * shape).real profile = profile * amp * wofz(2 * np.sqrt(np.log(2.0)) * (x - pos) / fwhm + 1j * np.sqrt(np.log(2.0)) * shape).real return continuum - profile
def rautian( x, x0=0, # centre S=1, # integrated value ΓL=0, ΓG=0, νvc=0, # nfwhmL=None, # maximum Lorentzian widths to include # nfwhmG=None, # maximum Gaussian widths to include -- pure Lorentzian outside this # yin = None # set to add this line in place to an existing specturm of size matching x ): """Rautian profile. E.g,. schreier2020, 10.1016/j.jqsrt.2020.107385""" # if ζ == 0: # return voigt(x,x0,S,ΓL,ΓG) from scipy import special b = 0.8325546111576 # np.sqrt(np.log(2)) γG, γL = ΓG / 2, ΓL / 2 # FWHM to HWHM if γG == 0: ## hack to prevent divide by zero γG = 1e-10 x = b * (x - x0) / γG y = b * γL / γG z = x + 1j * y ζ = b * νvc / γG retval = (special.wofz(z) / (1 - np.sqrt(constants.pi) * ζ * special.wofz(z))).real ## normalise and scale retval = retval / (1.0644670194312262 * ΓG) * S return retval
def voigt(x, amp, fwhm, pos, shape, B): tmp = 1/special.wofz(np.zeros((len(x))) \ +1j*np.sqrt(np.log(2.0))*shape).real tmp = tmp*amp* \ special.wofz(2*np.sqrt(np.log(2.0))*(x-pos)/fwhm+1j* \ np.sqrt(np.log(2.0))*shape).real return tmp + B
def eps_material(mat, waverange, numosc=5): pen = np.divide(1239.84193E-9, waverange) if numosc <= 0: numosc = 1 m = mats.get(mat) #free electron eps epsf = 1 - np.divide(np.power(np.sqrt(m.get('f')[0]) * m.get('wp'), 2), np.multiply(pen, pen + 1j * m.get('g')[0])) #bound electron eps epsb = 0 + 1j * 0 for i in range(np.min([(m.get('f').size) - 1, numosc])): a = np.sqrt( np.power(pen, 2) + np.multiply(1j * m.get('g')[i + 1], pen)) epsb += np.multiply( np.divide( 1j * np.sqrt(np.pi) * m.get('f')[i + 1] * m.get('wp') * m.get('wp'), np.multiply(2 * np.sqrt(2) * m.get('s')[i + 1], a)), (wofz( np.divide(np.subtract(a, m.get('w')[i + 1]), np.sqrt(2) * m.get('s')[i + 1])) + wofz( np.divide(a + m.get('w')[i + 1], np.sqrt(2) * m.get('s')[i + 1])))) #complex dielectric function return (epsf + epsb)
def two_voigt(x, amp=1, cen=0, sigma=1, gamma=0, c=0, a=0, amp2=0.0, cen2=-1, sig2=0.5, gam2=0): """1 dimensional voigt function. see http://en.wikipedia.org/wiki/Voigt_profile """ # Penalize negative values if sigma <= 0: amp = 1e10 if sig2 <= 0: amp = 1e10 if gamma <= 0: amp = 1e10 if gam2 <= 0: amp = 1e10 if amp <= 0: amp = 1e10 if amp2 <= 0: amp2 = 1e10 z = (x - cen + 1j * gamma) / (sigma * np.sqrt(2.0)) z2 = (x - cen2 + 1j * gam2) / (sig2 * np.sqrt(2.0)) return amp * wofz(z).real / (sigma * np.sqrt( 2 * np.pi)) + c + a * x + amp2 * wofz(z2).real / (sig2 * np.sqrt(2 * np.pi))
def voigt(x,amp,fwhm, pos,shape,B): tmp = 1/special.wofz(np.zeros((len(x))) \ +1j*np.sqrt(np.log(2.0))*shape).real tmp = tmp*amp* \ special.wofz(2*np.sqrt(np.log(2.0))*(x-pos)/fwhm+1j* \ np.sqrt(np.log(2.0))*shape).real return tmp+B
def xs_from_res(ap, A, res_E, J, gn, gg, gfa, gfb, temp, energy, reaction, comp='all'): sigma_pot = 4*pi*ap**2 k_b = 8.6173e-5 #[ev/K] xs = 0 for i in range(len(res_E)): g_tot = gn[i]+gg[i]+gfa[i]+gfb[i] r = 2603911/res_E[i]*(A+1)/A q = 2*(r*sigma_pot)**0.5 x = 2*(energy-res_E[i])/g_tot if temp==0: psi = 1/(1+x**2) chi = x/(1+x**2) else: xi = g_tot*(A/(4*k_b*temp*res_E[i]))**0.5 psi = pi**0.5*np.real(xi*wofz((x+1j)*xi)) chi = pi**0.5*np.imag(xi*wofz((x+1j)*xi)) if comp=='psi': chi = 0 if comp=='chi': psi = 0 if comp=='pot': chi = 0 psi = 0 if reaction=='capture': res_xs = gn[i]*gg[i]/g_tot**2*(res_E[i]/energy)**0.5*r*psi elif reaction=='elastic': res_xs = (gn[i]/g_tot)**2*(r*psi+g_tot/gn[i]*q*chi) xs += res_xs if reaction=='elastic' and comp!='psi' and comp!='chi': xs += sigma_pot return xs
def zeta_from_grid(self, grid): q2 = self.axis_ratio ** 2.0 ind_pos_y = grid[:, 0] >= 0 shape_grid = np.shape(grid) output_grid = np.zeros((shape_grid[0]), dtype=np.complex128) scale_factor = self.axis_ratio / (self.sigma * np.sqrt(2.0 * (1.0 - q2))) xs_0 = grid[:, 1][ind_pos_y] * scale_factor ys_0 = grid[:, 0][ind_pos_y] * scale_factor xs_1 = grid[:, 1][~ind_pos_y] * scale_factor ys_1 = -grid[:, 0][~ind_pos_y] * scale_factor output_grid[ind_pos_y] = -1j * ( wofz(xs_0 + 1j * ys_0) - np.exp(-(xs_0 ** 2.0) * (1.0 - q2) - ys_0 * ys_0 * (1.0 / q2 - 1.0)) * wofz(self.axis_ratio * xs_0 + 1j * ys_0 / self.axis_ratio) ) output_grid[~ind_pos_y] = np.conj( -1j * ( wofz(xs_1 + 1j * ys_1) - np.exp(-(xs_1 ** 2.0) * (1.0 - q2) - ys_1 * ys_1 * (1.0 / q2 - 1.0)) * wofz(self.axis_ratio * xs_1 + 1j * ys_1 / self.axis_ratio) ) ) return output_grid
def voight(x, alpha, gamma): sigma = alpha / np.sqrt(2 * np.log(2)) max_v = np.real(wofz( (1j * gamma) / sigma / np.sqrt(2))) / sigma / np.sqrt( 2 * np.pi) return np.real(wofz( (x + 1j * gamma) / sigma / np.sqrt(2))) / sigma / np.sqrt( 2 * np.pi) / max_v
def voigt(x,amp,pos,fwhm,shape): # Computes Voigt spectral profile. tmp = 1/wofz(np.zeros((len(x))) \ +1j*np.sqrt(np.log(2.0))*shape).real tmp = tmp*amp* \ wofz(2*np.sqrt(np.log(2.0))*(x-pos)/fwhm+1j* \ np.sqrt(np.log(2.0))*shape).real return tmp
def geteps(lambda0): omega=2*pi*constants.c/lambda0 epsf = 1 - omegap**2/(omega*(omega+gamma0*1.0J)) aj = sqrt(omega**2 + 1.0J*omega*gammaj) zplus = (aj+wj)/(sqrt(2)*sigmaj) zminus = (aj-wj)/(sqrt(2)*sigmaj) epsb = (1.0J*sqrt(pi)*fj*wp**2/(2*sqrt(2)*aj*sigmaj))*(wofz(zplus)+wofz(zminus)) eps = epsf + sum(epsb) return eps
def model_voigt_norm(x, alpha, gamma): """ Return the Voigt line shape at x with Lorentzian component HWHM gamma and Gaussian component HWHM alpha. """ sigma = 1 / np.sqrt(2 * alpha) #sigma = alpha / np.sqrt(2 * np.log(2)) return np.real(wofz((x + 1j * gamma) / sigma / np.sqrt(2))) / np.real( wofz((1j * gamma) / sigma / np.sqrt(2)))
def __init__(self, name='', pos=None, ampl=None, fwhm=None, shape=None): pp, pa, pf, psh = self._init_params(name, self.param_names, locals()) # amplitude and fwhms should be positive self.params[1].finalize = abs self.params[2].finalize = abs self.params[3].finalize = abs self.fcn = lambda p, x: \ p[pa] / wofz(1j*sqrt(log(2))*p[psh]).real * \ wofz(2*sqrt(log(2)) * (x-p[pp])/p[pf] + 1j*sqrt(log(2))*p[psh]).real
def hnew(gam1, gam2, gam3, t, tp, wofznu, nu, nu2): c1_1 = 1. / (gam2 + gam1) c1_2 = 1. / (gam3 + gam1) tp_lq = tp / lq t_lq = t / lq dif_t_lq = t_lq - tp_lq #Exponentials #egam1tp = np.exp(-gam1*tp) gam1tp = gam1 * tp egam2t = np.exp(-gam2 * t) egam3t = np.exp(-gam3 * t) #squared exponentials #edif_t_lq = np.exp(-dif_t_lq*dif_t_lq) dif_t_lq2 = dif_t_lq * dif_t_lq #et_lq = np.exp(-t_lq*t_lq) t_lq2 = t_lq * t_lq #etp_lq = np.exp(-tp_lq*tp_lq) tp_lq2 = tp_lq * tp_lq ec = egam2t * c1_1 - egam3t * c1_2 #Terms of h A = dif_t_lq + nu temp = np.zeros(A.shape, dtype=complex) boolT = A.real >= 0. if np.any(boolT): wofzA = wofz(1j * A[boolT]) temp[boolT] = np.exp(np.log(wofzA) - dif_t_lq2[boolT]) boolT = np.logical_not(boolT) if np.any(boolT): dif_t = t[boolT] - tp[boolT] wofzA = wofz(-1j * A[boolT]) temp[boolT] = 2. * np.exp(nu2[boolT] + gam1[boolT] * dif_t) - np.exp( np.log(wofzA) - dif_t_lq2[boolT]) b = t_lq + nu wofzb = wofz(1j * b) e = nu - tp_lq temp2 = np.zeros(e.shape, dtype=complex) boolT = e.real >= 0. if np.any(boolT): wofze = wofz(1j * e[boolT]) temp2[boolT] = np.exp(np.log(wofze) - tp_lq2[boolT]) boolT = np.logical_not(boolT) if np.any(boolT): wofze = wofz(-1j * e[boolT]) temp2[boolT] = 2. * np.exp(nu2[boolT] - gam1tp[boolT]) - np.exp( np.log(wofze) - tp_lq2[boolT]) return (c1_1 - c1_2)*(temp \ - np.exp(np.log(wofzb) - t_lq2 - gam1tp))\ - ec*( temp2 \ - np.exp(np.log(wofznu) - gam1tp))
def voigt(x, amp, pos, fwhm, shape): """ voigt profile V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) z = (x+i*gam)/(sig*sqrt(2)) """ tmp = 1 / special.wofz( N.zeros((len(x))) + 1j * N.sqrt(N.log(2.0)) * shape).real tmp = tmp * amp * special.wofz(2 * N.sqrt(N.log(2.0)) * (x - pos) / fwhm + 1j * N.sqrt(N.log(2.0)) * shape).real return tmp
def voigt(x, amp, pos, fwhm, shape): """ voigt profile V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) z = (x+i*gam)/(sig*sqrt(2)) """ tmp = 1 / special.wofz( N.zeros((len(x))) + 1j * N.sqrt(N.log(2.0)) * shape).real tmp = tmp * amp * special.wofz( 2 * N.sqrt(N.log(2.0)) * (x - pos) / fwhm + 1j * N.sqrt(N.log(2.0)) * shape).real return tmp
def Upsilon(t, t2, gam, l_scale, eval_gradient=False): """ Describe me without a reference? """ # array axes ordering [ t , t2 , gamma, length scales] # pwd of times Dt = t[:, None] - t2[None, :] # u1 = 2exp(arg1) arg1 = .25 * gam[:, None]**2 * l_scale[None, :]**2 arg1 = arg1[None, None, ...] - \ Dt[..., None, None] * gam[None, None, :, None] # u2 = exp(arg2) * wofz(1j * zrq) zrq = Dt[..., None, None] / l_scale - \ .5 * gam[None, None, :, None] * l_scale # easy b.-casting over last axis arg2 = -(Dt**2)[..., None, None] / l_scale**2 # u3 = exp(arg3) * wofz(-1j * zrq0) zrq0 = -t2[None, :, None, None] / l_scale - \ .5 * gam[None, None, :, None] * l_scale arg3 = -(t2**2)[None, :, None, None] / l_scale**2 -\ t[:, None, None, None] * gam[None, None, :, None] if eval_gradient: # gradient of arg1 wrt gam darg1_g = .5 * gam[:, None] * (l_scale**2)[None, :] darg1_g = darg1_g[None, None, ...] - \ Dt[..., None, None] u1 = 2 * np.exp(arg1) # for clarity. du1 = u1 * darg1_g u2 = np.exp(arg2) * wofz(1j * zrq) du2 = -.5 * 1j * wofz_grad(1j * zrq) * np.exp(arg2) * l_scale u3 = np.exp(arg3) * wofz(-1j * zrq0) du3 = np.exp(arg3) * \ (-t[:, None, None, None] * wofz(-1j * zrq0) + \ .5 * 1j * wofz_grad(-1j * zrq0) * l_scale) return u1 - u2 - u3, du1 - du2 - du3 else: return 2*np.exp(arg1) - \ np.exp(arg2)*wofz(1j*zrq) - \ np.exp(arg3)*wofz(-1j*zrq0)
def Upsilon(t, t2, gam, l_scale, eval_gradient=False): """ Describe me without a reference? """ # array axes ordering [ t , t2 , gamma, length scales] # pwd of times Dt = t[:, None] - t2[None, :] # u1 = 2exp(arg1) arg1 = .25*gam[:, None] **2 * l_scale[None, :] ** 2 arg1 = arg1[None, None, ...] - \ Dt[..., None, None] * gam[None, None, :, None] # u2 = exp(arg2) * wofz(1j * zrq) zrq = Dt[..., None, None] / l_scale - \ .5 * gam[None, None, :, None] * l_scale # easy b.-casting over last axis arg2 = - (Dt**2)[..., None, None] / l_scale**2 # u3 = exp(arg3) * wofz(-1j * zrq0) zrq0 = -t2[None, :, None, None] / l_scale - \ .5 * gam[None, None, :, None] * l_scale arg3 = -(t2**2)[None, :, None, None] / l_scale**2 -\ t[:, None, None, None] * gam[None, None, :, None] if eval_gradient: # gradient of arg1 wrt gam darg1_g = .5*gam[:, None] * (l_scale ** 2)[None, :] darg1_g = darg1_g[None, None, ...] - \ Dt[..., None, None] u1 = 2 * np.exp(arg1) # for clarity. du1 = u1 * darg1_g u2 = np.exp(arg2) * wofz(1j * zrq) du2 = -.5*1j * wofz_grad(1j * zrq) * np.exp(arg2) * l_scale u3 = np.exp(arg3) * wofz(-1j*zrq0) du3 = np.exp(arg3) * \ (-t[:, None, None, None] * wofz(-1j * zrq0) + \ .5 * 1j * wofz_grad(-1j * zrq0) * l_scale) return u1 - u2 - u3, du1 - du2 - du3 else: return 2*np.exp(arg1) - \ np.exp(arg2)*wofz(1j*zrq) - \ np.exp(arg3)*wofz(-1j*zrq0)
def voigt(xarr,amp,xcen,Gfwhm,Lfwhm): """ voigt profile V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) z = (x+i*gam)/(sig*sqrt(2)) Converted from http://mail.scipy.org/pipermail/scipy-user/2011-January/028327.html """ from scipy.special import wofz tmp = 1.0/wofz(np.zeros((len(xarr)))+1j*np.sqrt(np.log(2.0))*Lfwhm).real tmp = tmp*amp*wofz(2*np.sqrt(np.log(2.0))*(xarr-xcen)/Gfwhm+1j*np.sqrt(np.log(2.0))*Lfwhm).real return tmp
def qvoigt(x, amp, pos, fwhm, gam): """ analytic approximation for a voigt profile. V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) z = (x+i*gam)/(sig*sqrt(2)) """ tmp = 1 / special.wofz( np.zeros((len(x))) + 1j * np.sqrt(np.log(2.0)) * gam).real tmp = tmp * amp * special.wofz( 2 * np.sqrt(np.log(2.0)) * (x - pos) / fwhm + 1j * np.sqrt(np.log(2.0)) * gam).real return tmp
def voigt(x, x0, FWHM, G): """Calculate an unnormalized Voigt lineshape using Scipy's Faddeeva function `Link to Voigt article on Wikipedia`__ __ https://en.wikipedia.org/wiki/Voigt_profile Parameters ---------- x : array_like or number Input array. x0 : array_like or number Center of lineshape. FHWM : array_like or number Full-width-at-half-maximum of Gaussian part of lineshape. G : array_like or number Half-width-at-half-maximum of Lorentzian part of lineshape. Returns ------- array_like or number Voigt lineshape. """ c = FWHM / (2 * np.sqrt(2 * np.log(2))) arr = (x - x0 + 1j * G) / (c * np.sqrt(2)) w = wofz(arr) return np.real(w) / (c * np.sqrt(2 * np.pi))
def _wofz(x): """Return the fadeeva function for complex argument. wofz = exp(-x**2)*erfc(-i*x) """ return wofz(x)
def add_voigt(d,DoppTemp,atomMass,wavenumber,gamma,voigtwidth, ltransno,lenergy,lstrength,rtransno, renergy,rstrength): xpts = len(d) npts = 2*voigtwidth+1 detune = 2.0*pi*1.0e6*(arange(npts)-voigtwidth) #Angular detuning wavenumber = wavenumber + detune/c #Allow the wavenumber to change u = sqrt(2.0*kB*DoppTemp/atomMass) ku = wavenumber*u a = gamma/ku b = detune/ku y = 1.0j*(0.5*sqrt(pi)/ku)*wofz(b+0.5j*a) ab = y.imag disp = y.real #interpolate lineshape functions f_ab = interp1d(detune,ab) f_disp = interp1d(detune,disp) #Add contributions from all transitions to user defined detuning axis lab = zeros(xpts) ldisp = zeros(xpts) for line in xrange(ltransno+1): xc = lenergy[line] lab += lstrength[line]*f_ab(2.0*pi*(d-xc)*1.0e6) ldisp += lstrength[line]*f_disp(2.0*pi*(d-xc)*1.0e6) rab = zeros(xpts) rdisp = zeros(xpts) for line in xrange(rtransno+1): xc = renergy[line] rab += rstrength[line]*f_ab(2.0*pi*(d-xc)*1.0e6) rdisp += rstrength[line]*f_disp(2.0*pi*(d-xc)*1.0e6) return lab, ldisp, rab, rdisp
def _voigt_profile(x, alpha, mu, sigma, gamma): """Private function to fit a Voigt profile. Parameters ---------- x : ndarray, shape (len(x)) The input data. alpha : float, The amplitude factor. mu : float, The shift of the central value. sigma : float, sigma of the Gaussian. gamma : float, gamma of the Lorentzian. Returns ------- y : ndarray, shape (len(x), ) The Voigt profile. """ # Define z z = ((x - mu) + 1j * gamma) / (sigma * np.sqrt(2)) # Compute the Faddeva function w = wofz(z) return alpha * (np.real(w)) / (sigma * np.sqrt(2. * np.pi))
def voigtianFunc(x, args, useNp=False): if not useNp: x = float(x[0]) a, b = float(args[0]), float(args[1]) sig, mean = float(args[2]), float(args[3]) w, s = float(args[4]), float(args[5]) if sig <= 0 or s <= 0 or w <= 0: if useNp: return [0 for x in range(len(x))] else: return 0 coef = -0.5/(s*s) arg = x-mean # Voigtian c = 1.0/(np.sqrt(2.0)*s) a_ = 0.5*c*w u = c*arg # die RooFit implementation z = 0 if useNp: z = [complex(i, a_) for i in u] else: z = complex(u, a_) v = special.wofz(z) return a*(x-mean) + b + \ sig*step*c*voigtianConst*v.real
def voigt_fwhm(x, A, mu, fwhm, gamma): """ Voigt function using FWHM """ sigma = fwhm/2./np.sqrt(2*np.log(2)) #Convert FWHM to sigma z = ((x-mu) + 1j*gamma) / (sigma *np.sqrt(2.0)) return A * np.real(wofz(z))
def cutoff_denominator(list_x,tol): z = list_x/tol #den = N.imag(SS.wofz(list_x))/tol den = -1j*SS.wofz(z)/tol*N.sqrt(N.pi) return den
def DopplerWind(Temp, FreqGrid, Para, wind_v, shift_direction=False): u"""#doppler width #Para[transient Freq[Hz], relative molecular mass[g/mol]]""" # step1 = Para[0]/c*(2.*R*gct/(Para[1]*1.e-3))**0.5 # outy = np.exp(-(Freq-Para[0])**2/step1**2) / (step1*(np.pi**0.5)) #wind_v = speed[:,10] #Temp=temp[10] #FreqGrid = Fre_range_i[0] wind = wind_v.reshape(wind_v.size, 1) FreqGrid = FreqGrid.reshape(1, FreqGrid.size) deltav = Para[0] * wind / c if shift_direction is 'Red' or 'red' or 'RED': D_effect = (deltav) elif shift_direction is 'Blue' or 'blue' or 'BLUE': D_effect = (-deltav) else: print('Set Direction, red shift or blue shift') # step1 = Para[0]/c*(2.*R*Temp*np.log(2.)/(Para[1]*1.e-3))**0.5 # HWHM # outy = np.exp(-np.log(2.)*(FreqGrid-Para[0])**2/step1**2) *\ # (np.log(2.)/np.pi)**0.5/step1 # outy_d = np.exp(-np.log(2.)*(FreqGrid+D_effect-Para[0])**2/step1**2) *\ # (np.log(2.)/np.pi)**0.5/step1 GD = np.sqrt(2 * k * ac / Para[1] * Temp) / c * Para[0] step1 = GD outy_d = wofz( (FreqGrid + D_effect - Para[0]) / GD).real / np.sqrt(np.pi) / GD #plot(FreqGrid, outy) #plot(FreqGrid, outy_d[:,0]) return outy_d
def voigt(x, a=1, xc=0, wg=1, wl=1, y0=0): """ Voigt Function. Parameters ---------- x : 1d-ndarray Input data. a : float Area. xc : float Center. wg : float FWHM of gaussian. wl : float FWHM of lorentzian. y0 : float Base. Returns ------- result : 1d-ndarray Output data. """ sigma, gamma = wg / (2 * np.sqrt(2 * np.log(2))), wl / 2 y1 = special.wofz((x - xc + 1j * gamma) / (sigma * np.sqrt(2))) return y0 + a / (sigma * np.sqrt(2 * np.pi)) * np.real(y1)
def voigt_shape(x, a): """ Real part of Faddeeva function, where w(z) = exp(-z^2) erfc(jz) """ z = x + 1j * a return wofz(z).real
def ResolutionVectorAsymetric(Q, dQ, points, dLambda, asymmetry, range_=3): ''' Resolution vector for a asymmetric wavelength distribution found in neutron experiments with multilayer monochromator. ''' Qrange=max(range_*dQ, range_*dLambda*Q.max()) Qstep=2*Qrange/points Qres=Q+(arange(points)-(points-1)/2)[:, newaxis]*Qstep Quse=transpose(Q[:, newaxis]) gamma_asym=2.*dLambda*Quse/(1+exp(asymmetry*(Quse-Qres))) z=(Quse-Qres+(abs(gamma_asym)*1j))/abs(dQ)/sqrt(2.) z0=(0.+(abs(gamma_asym)*1j))/abs(dQ)/sqrt(2) weight=wofz(z).real/wofz(z0).real Qret=Qres.flatten() return (Qret, weight)
def voigt_wofz(self, a, u): ''' Compute the Voigt function using Scipy's wofz(). # Code from https://github.com/nhmc/Barak/blob/\ 087602fb372812c0603441ca1ce6820e96963b88/barak/absorb/voigt.py Explanation: https://nhmc.github.io/Barak/generated/barak.voigt.voigt.html#barak.voigt.voigt Parameters ---------- a: float Ratio of Lorentzian to Gaussian linewidths. u: array of floats The frequency or velocity offsets from the line centre, in units of the Gaussian broadening linewidth. See the notes for `voigt` for more details. ''' try: from scipy.special import wofz except ImportError: s = ("Can't find scipy.special.wofz(), can only calculate Voigt " " function for 0 < a < 0.1 (a=%g)" % a) print(s) else: return wofz(u + 1j * a).real
def eval(self, x): """ Evaluate the Voigt profile at the specified coordinates range. Parameters ---------- x: 1D float ndarray Input coordinates where to evaluate the profile. Returns ------- v: 1D float ndarray The line profile at the x locations. """ if self.hwhm_L / self.hwhm_G < 0.1: sigma = self.hwhm_G / np.sqrt(2 * np.log(2)) z = (x + 1j * self.hwhm_L - self.x0) / (sigma * np.sqrt(2)) return self.scale * ss.wofz(z).real / (sigma * np.sqrt(2 * np.pi)) # This is faster than the previous algorithm but it gets inaccurate # and breaks down for HWHM_L / HWHM_G ~< 0.1: X = (x - self.x0) * np.sqrt(np.log(2)) / self.hwhm_G Y = self.hwhm_L * np.sqrt(np.log(2)) / self.hwhm_G A, B, C, D = self._A, self._B, self._C, self._D V = np.sum((C * (Y - A) + D * (X - B)) / ((Y - A)**2 + (X - B)**2), axis=0) V /= np.pi * self.hwhm_L return self.scale * self.hwhm_L / self.hwhm_G * np.sqrt( np.pi * np.log(2)) * V
def voigt(x, amp=1, cen=0, sigma=1, gamma=0): """1 dimensional voigt function. see http://en.wikipedia.org/wiki/Voigt_profile """ from scipy.special import wofz z = (x - cen + 1j * gamma) / (sigma * np.sqrt(2.0)) return amp * wofz(z).real / (sigma * np.sqrt(2 * np.pi))
def evaluate(self, x): """ Evaluates the model for current parameter values. Parameters ---------- x : array Specifies the points at which to evaluate the model. """ try: z = ((x - self["mu"]) + (1.j) * abs(self["al"])) / \ (numpy.sqrt(2.0) * abs(self["ad"])) y = self["A"] * numpy.real(sps.wofz(z)) y /= (abs(self["ad"]) * numpy.sqrt(2.0 * numpy.pi)) y += x * self["lin"] + self["off"] y[numpy.where(numpy.isnan(y))] = 0.0 except FloatingPointError as fpe: raise (PE.PyAFloatingPointError( "The following floating point error occurred:\n " + str(fpe) + "\n" + "Current Parameter values:\n" + str(self.parameters()), solution=[ "Try to rescale/shift your abscissa. For instance, put" + "the spectral line you try to fit at position `0`." ])) return y
def voigt(x, FWHM=1, gamma=1, center=0, scale=1): """ Voigt peak. The voigt peak is the convolution of a Lorentz peak with a Gaussian peak. The formula used to calculate this is:: z(x) = (x + 1j gamma) / (sqrt(2) sigma) w(z) = exp(-z**2) erfc(-1j z) / (sqrt(2 pi) sigma) V(x) = scale Re(w(z(x-center))) :Parameters: gamma : real The half-width half-maximum of the Lorentzian FWHM : real The FWHM of the Gaussian center : real Location of the center of the peak scale : real Value at the highest point of the peak Ref: W.I.F. David, J. Appl. Cryst. (1986). 19, 63-64 Note: adjusted to use stddev and HWHM rather than FWHM parameters """ # wofz function = w(z) = Fad[d][e][y]eva function = exp(-z**2)erfc(-iz) from scipy.special import wofz sigma = FWHM / 2.3548200450309493 z = (np.asarray(x)-center+1j*gamma)/(sigma*math.sqrt(2)) V = wofz(z)/(math.sqrt(2*np.pi)*sigma) return scale*V.real
def voigt(x, amp=1, cen=0, sigma=1, gamma=0): """1 dimensional voigt function. see http://en.wikipedia.org/wiki/Voigt_profile """ from scipy.special import wofz z = (x-cen + 1j*gamma)/ (sigma*np.sqrt(2.0)) return amp * wofz(z).real / (sigma*np.sqrt(2*np.pi))
def return_voigtfunc(x): realvalue = np.sqrt(np.log(2)) / gamma_D * (x - wn) imagvalue = np.sqrt(np.log(2)) * gamma_L / gamma_D complexvalue = realvalue + imagvalue * 1j faddeeva = np.sqrt(np.log(2)) / gamma_D / np.sqrt( np.pi) * special.wofz(complexvalue) return faddeeva.real
def voigt_fwhm(x, A, mu, fwhm, gamma): """ Voigt function using FWHM """ sigma = fwhm / 2. / np.sqrt(2 * np.log(2)) #Convert FWHM to sigma z = ((x - mu) + 1j * gamma) / (sigma * np.sqrt(2.0)) return A * np.real(wofz(z))
def voigt(cls, a, u): from scipy import special x = np.asarray(u).astype(np.float64) y = np.asarray(a).astype(np.float64) return special.wofz(x + 1j * y).real
def evaluate(self, x): """ Evaluates the model for current parameter values. Parameters ---------- x : array Specifies the points at which to evaluate the model. """ try: z = ((x - self["mu"]) + (1.j) * abs(self["al"])) / \ (numpy.sqrt(2.0) * abs(self["ad"])) y = self["A"] * numpy.real(sps.wofz(z)) y /= (abs(self["ad"]) * numpy.sqrt(2.0 * numpy.pi)) y += x * self["lin"] + self["off"] y[numpy.where(numpy.isnan(y))] = 0.0 except FloatingPointError as fpe: raise(PE.PyAFloatingPointError("The following floating point error occurred:\n " + str(fpe) + "\n" + "Current Parameter values:\n" + str(self.parameters()), solution=["Try to rescale/shift your abscissa. For instance, put" + "the spectral line you try to fit at position `0`."])) return y
def Z(arg): ''' Return Plasma Dispersion Function : Normalized Fadeeva function Plasma dispersion function related to Fadeeva function (Summers & Thorne, 1993) by i*sqrt(pi) factor. ''' return 1j * np.sqrt(np.pi) * wofz(arg)
def voigt(x, x0, fwhm_g, fwhm_l): """ Normalised voigt profile """ sigma = voigt.Va * fwhm_g z = ((x - x0) + 0.5j * fwhm_l) / (sigma * voigt.Vb) return wofz(z).real / (sigma * voigt.Vc)
def voigt2(a,u): x = u/a #Define parameters for U function t = 1/(4.0*a**2) # z = (1 - complex(0,1)*x)/(2.0*np.sqrt(t)) # U = np.sqrt(math.pi/(4.0*t))*special.wofz(complex(0,1)*z) #Plug into U(x,t) H = U/(a*math.sqrt(math.pi)) #Voight function return H
def voigt(freq, j, height, vib, HWHM, sigma): '''Return a Voigt line shape over a given domain about a given vib''' # Define what to pass to the complex error function z = ( freq - vib[j] + 1j*HWHM[j] ) / ( SQRT2 * sigma[j] ) # The Voigt is the real part of the complex error function with some # scaling factors. It is multiplied by the height here. return ( height[j].conjugate() * wofz(z) ).real / ( SQRT2PI * sigma[j] )
def voigt(x, amplitude=1.0, center=0.0, sigma=1.0, gamma=None): """1 dimensional voigt function. see http://en.wikipedia.org/wiki/Voigt_profile """ if gamma is None: gamma = sigma z = (x-center + 1j*gamma)/ (sigma*s2) return amplitude*wofz(z).real / (sigma*s2pi)
def model(self, params=None, x=None, **kws): if params is None: params = self.params amp = params['amplitude'].value cen = params['center'].value sig = params['sigma'].value z = (x-cen + 1j*sig) / (sig*SQRT2) return amp*wofz(z).real / (sig*SQRT2PI)
def voigt(x, y): # The Voigt function is also the real part of # w(z) = exp(-z^2) erfc(iz), the complex probability function, # which is also known as the Faddeeva function. Scipy has # implemented this function under the name wofz() z = x + 1j*y I = special.wofz(z).real return I
def voigt(x,amp,pos,fwhm,shape): from scipy import special """ Voigt profile V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) z = (x+i*gam)/(sig*sqrt(2)) http://mail.scipy.org/pipermail/scipy-user/2011-January/028327.html """ tmp = 1/special.wofz(np.zeros((len(x))) \ +1j*np.sqrt(np.log(2.0))*shape).real tmp = tmp*amp* \ special.wofz(2*np.sqrt(np.log(2.0))*(x-pos)/fwhm+1j* \ np.sqrt(np.log(2.0))*shape).real return tmp
def fit_voigt(xx, a, nu, sigma, gamma): """Fit a Voigt function to the line.""" # The Voigt function: # V(x;sigma,gamma) = Re[w(z)] / (sigma * sqrt(2 pi)) # where w(z) = exp(-z**2) * erfc(-i * z), the Faddeeva function # evaluated for z = (x + i*gamma) / (sigma * sqrt(2)) # Use wofz() from scipy z = ((xx - nu) + 1j*gamma) / (sigma * np.sqrt(2.)) return a * np.real(wofz(z)) / (sigma * np.sqrt(2. * np.pi))
def Voigt(x, alpha, gamma): """ Return the Voigt line shape at x with Lorentzian component HWHM gamma and Gaussian component HWHM alpha. """ sigma = alpha / np.sqrt(2 * np.log(2)) return np.real(wofz((x + 1j*gamma)/sigma/np.sqrt(2))) / sigma\ /np.sqrt(2*np.pi)
def _voigt(x, y): ''' The Voigt function is also the real part of w(z) = exp(-z^2) erfc(iz), the complex probability function, which is also known as the Faddeeva function ''' z = x + 1j*y I = wofz(z).real return I
def cutoff_denominator(self,list_x,fadeeva_width): """ This function returns an approximation to 1/(x+i delta) using the Faddeeva function """ z = list_x/fadeeva_width den = -1j*SS.wofz(z)/fadeeva_width*N.sqrt(N.pi) return den