def fit_rabi_with_phase_on_linslope(g_f, g_A, g_a, g_b, g_phi, *arg): """ fits (and plots) a cosine on a slope, with offset, y(x) = a + bx + Acos(f*x + phi) Initial guesses (1st args, in this order): g_f : float guess for the frequency g_A : float guess for amplitude g_a : float guess for offset g_b = 0. : float guess for slope g_phi = 0. : float guess for the phase """ fitfunc_str = "a + b*x + A*cos(2pi*f*x + phi)" f = fit.Parameter(g_f, 'frequency') A = fit.Parameter(g_A, 'amplitude') a = fit.Parameter(g_a, 'offset') b = fit.Parameter(g_b, 'slope') phi = fit.Parameter(g_phi, 'phase') p0 = [f, A, a, b, phi] def fitfunc(x): return a() + b() * x + A() * cos(2 * pi * f() * x + phi()) return p0, fitfunc, fitfunc_str
def fit_rabi_simple(g_f, g_A, g_a, g_phi, *arg): """ fits a cosine thats damped exponentially, y(x) = a + A * cos(2pi*f*x) Initial guesses, in this order: g_f : frequency g_A : initial amplitude of the oscillation g_a : offset """ fitfunc_str = "a + A * cos(f*x + phi)" f = fit.Parameter(g_f, 'f') A = fit.Parameter(g_A, 'A') a = fit.Parameter(g_a, 'a') phi = fit.Parameter(g_phi, 'phi') # tau = fit.Parameter(g_tau, 'tau') p0 = [f, A, a, phi] def fitfunc(x): return a() + A() * cos(2 * pi * (f() * x + phi() / 360.)) return p0, fitfunc, fitfunc_str
def fit_rabi_damped_exp(g_f, g_A, g_a, g_tau, *arg): """ fits a cosine thats damped exponentially, y(x) = a + A * exp(-x/tau) * cos(f*x + phi) Initial guesses, in this order: g_f : frequency g_A : initial amplitude of the oscillation g_a : offset ### g_phi : phase g_tau : decay constant """ fitfunc_str = "a + A * exp(-x/tau) * cos(f*x + phi)" f = fit.Parameter(g_f, 'f') A = fit.Parameter(g_A, 'A') a = fit.Parameter(g_a, 'a') phi = fit.Parameter(0., 'phi') tau = fit.Parameter(g_tau, 'tau') p0 = [f, A, a, tau, phi] #print tau def fitfunc(x): return a() + A() * exp(-x / tau()) * cos(2 * pi * (f() * x + phi() / 360.)) return p0, fitfunc, fitfunc_str
def fit_AOM_powerdependence(g_a, g_xc, g_k, *arg): fitfunc_str = 'a * exp(-exp(-k*(x-xc)))' a = fit.Parameter(g_a, 'a') xc = fit.Parameter(g_xc, 'xc') k = fit.Parameter(g_k, 'k') p0 = [a, xc, k] def fitfunc(x): return a() * np.exp(-np.exp(-k() * (x - xc()))) return p0, fitfunc, fitfunc_str
def fit_ramsey_gaussian_decay(g_tau, g_a, *arg): """ fitfunction for a ramsey modulation, with gaussian decay, y(x) = a + A*exp(-(x/tau)**2) * mod, where: mod = sum_i(cos(2pi*f_i*x + phi_i) - 1) Initial guesses (in this order): g_tau : decay const g_A : Amplitude g_a : offset For the modulation: an arbitrary no of tuples, in the form (g_f, g_A, g_phi)[i] = (frequency, Amplitude, phase)[i] """ fitfunc_str = 'y(x) = a + exp(-(x/tau)**2)*(' no_frqs = len(arg) if no_frqs == 0: print 'no modulation frqs supplied' return False tau = fit.Parameter(g_tau, 'tau') # A = fit.Parameter(g_A, 'A') a = fit.Parameter(g_a, 'a') p0 = [tau, a] print 'fitting with %d modulation frequencies' % no_frqs frqs = [] amplitudes = [] phases = [] for i, m in enumerate(arg): fitfunc_str += 'A%d*cos(2pi*f%d*x + phi%d) + ' % (i, i, i) frqs.append(fit.Parameter(m[0], 'f%d'%i)) phases.append(fit.Parameter(m[2], 'phi%d'%i)) amplitudes.append(fit.Parameter(m[1], 'A%d'%i)) p0.append(frqs[i]) p0.append(amplitudes[i]) p0.append(phases[i]) fitfunc_str += ')' def fitfunc(x): prd = exp(-(x/tau())**2) mod = 0 for i in range(no_frqs): mod += amplitudes[i]() * (cos(2*pi*frqs[i]()*x + phases[i]())) return a() + prd*mod return p0, fitfunc, fitfunc_str
def fit_cos(g_f, g_a, g_A, g_phi, *arg): fitfunc_str = 'A * cos(2pi * (f*x + phi/360) ) + a' f = fit.Parameter(g_f, 'f') a = fit.Parameter(g_a, 'a') A = fit.Parameter(g_A, 'A') # phi = fit.Parameter(g_phi, 'phi') p0 = [f, a, A] #, phi] def fitfunc(x): return a() + A() * np.cos(2 * np.pi * (f() * x + 0)) #phi()/360.)) return p0, fitfunc, fitfunc_str
def fit_gauss(g_a, g_A, g_x0, g_sigma): fitfunc_str = 'a + A * exp(-(x-x0)**2/sigma**2)' a = fit.Parameter(g_a, 'a') x0 = fit.Parameter(g_x0, 'x0') A = fit.Parameter(g_A, 'A') sigma = fit.Parameter(g_sigma, 'sigma') p0 = [a, x0, A, sigma] def fitfunc(x): return a() + A() * np.exp(-(x - x0())**2 / sigma()**2) return p0, fitfunc, fitfunc_str
def fit_population_vs_detuning(g_a, g_A, g_F, g_x0, *arg): fitfunc_str = 'a + A * F**2/(F**2+(x-x0)**2) * sin(pi/(2F) * sqrt(F**2+(x-x0)**2))**2' A = fit.Parameter(g_A, 'A') a = fit.Parameter(g_a, 'a') F = fit.Parameter(g_F, 'F') x0 = fit.Parameter(g_x0, 'x0') p0 = [a, A, F, x0] def fitfunc(x): return a() + A() * F()**2 / (F()**2 + (x - x0())**2) * sin( pi / F() / 2. * sqrt(F()**2 + (x - x0())**2))**2 return p0, fitfunc, fitfunc_str
def fit_rabi_multiple_detunings(g_A, g_a, g_F, g_tau, *arg): """ fitfunction for an oscillation that drives several transitions (several nuclear lines, for instance) y(x) = a + A * sum_I[ F**2/(F**2 + delta_i**2) * (cos(sqrt(F**2 + delta_i**2 + phi_i)) - 1) * exp(-x/tau) Initial guesses: g_A : full Rabi amplitude g_a : offset g_F : Rabi frequency g_tau : exp decay constant For the driven levels: all successive args are treated as detunings for additional levels, (delta_i, g_phi_i) -- given as tuples! detuning is not a free param, but is given exactly. """ fitfunc_str = "a + A * sum_I[ F**2/(F**2 + delta_i**2) * (cos(sqrt(F**2 + delta_i**2 + phi_i)) - 1) * exp(-x/tau)" no_detunings = len(arg) A = fit.Parameter(g_A, 'A') a = fit.Parameter(g_a, 'a') F = fit.Parameter(g_F, 'F') tau = fit.Parameter(g_tau, 'tau') p0 = [A, a, F, tau] detunings = [] phases = [] for i, d in enumerate(arg): fitfunc_str += '\ndetuning d%d := %f' % (i, d[0]) detunings.append(d[0]) #phases.append(fit.Parameter(d[1], 'phi%d'%i)) #p0.append(phases[i]) def fitfunc(x): val = a() for i, d in enumerate(detunings): f2 = F()**2 + d**2 val += A() * (F()**2 / f2) * (cos(2 * pi * sqrt(f2) * x + 0.) - 1) return val * exp(-x / tau()) return p0, fitfunc, fitfunc_str
def fit_FID_gauss(g_tau, g_A, g_a, *arg): """ fitfunction for a gaussian decay, y(x) = a + A*exp(-(x/tau)**2) Initial guesses (in this order): g_tau : decay constant g_A : amplitude g_a : offset """ tau = fit.Parameter(g_tau, 'tau') A = fit.Parameter(g_A, 'A') a = fit.Parameter(g_a, 'a') p0 = [tau, A, a] def fitfunc(x): return a() + A()*exp(-(x/tau())**2) return p0, fitfunc, fitfunc_str
def fit_saturation(g_A, g_xsat, *arg): """ fitfunction for a saturation (e.g., the NV PL) y(x) = A * x / (x + xsat) I.g.: g_A : maximum signal (at x=infinity) g_xsat : saturation point """ fitfunc_str = 'A * x / (x + x_sat)' A = fit.Parameter(g_A, 'A') xsat = fit.Parameter(g_xsat, 'xsat') p0 = [A, xsat] def fitfunc(x): return A() * x / (x + xsat()) return p0, fitfunc, fitfunc_str
def fit_echo(g_tau, g_A, g_a, g_k, *arg): """ fitfunction for a gaussian decay, y(x) = a + A*exp(-(x/tau)**k) Initial guesses (in this order): g_tau : decay constant g_A : amplitude g_a : offset g_k : exponent """ fitfunc_str='a() + A()*exp(-(x/tau))**k)' tau = fit.Parameter(g_tau, 'tau') A = fit.Parameter(g_A, 'A') a = fit.Parameter(g_a, 'a') k = fit.Parameter(g_k,'k') p0 = [tau, A, a,k] def fitfunc(x): return a() + A()*exp(-(x/tau())**k()) return p0, fitfunc, fitfunc_str
def fit_rabi_damped_exp_on_linslope(g_f, g_A, g_a, g_b, g_phi, g_tau, *arg): """ fits (and plots) a cosine on a slope, with offset, y(x) = a + bx + Acos(f*x + phi) * exp(-x/tau) Initial guesses (1st args, in this order): g_f : float guess for the frequency g_A : float guess for amplitude g_a : float guess for offset g_b : float guess for slope g_phi : float guess for the phase g_tau : float decay constant """ fitfunc_str = "a + b*x + A*cos(2pi*f*x + phi) * exp(-x/tau)" f = fit.Parameter(g_f, 'frequency') A = fit.Parameter(g_A, 'amplitude') a = fit.Parameter(g_a, 'offset') b = fit.Parameter(g_b, 'slope') phi = fit.Parameter(g_phi, 'phase') tau = fit.Parameter(g_tau, 'tau') p0 = [f, A, a, b, phi, tau] def fitfunc(x): return a() + b() * x + A() * cos(2 * pi * f() * x + phi()) * exp( -x / tau()) return p0, fitfunc, fitfunc_str
def fit_exp_decay_with_offset(g_a, g_A, g_tau, *arg): """ fitfunction for an exponential decay, y(x) = A * exp(-x/tau) + a Initial guesses (in this order): g_a : offset g_A : initial Amplitude g_tau : decay constant """ fitfunc_str = 'A * exp(-x/tau) + a' a = fit.Parameter(g_a, 'a') A = fit.Parameter(g_A, 'A') tau = fit.Parameter(g_tau, 'tau') p0 = [a, A, tau] def fitfunc(x): return a() + A() * np.exp(-x / tau()) return p0, fitfunc, fitfunc_str
def fit_poly(indices, *arg): fitfunc_str = 'sum_n ( a[n] * x[n] )' idx = 0 p0 = [] for i, a in enumerate(indices): p0.append(fit.Parameter(a, 'a%d' % i)) def fitfunc(x): val = 0 for i in range(len(indices)): val += p0[i]() * x**i return val return p0, fitfunc, fitfunc_str
def fit_saturation_with_offset_linslope(g_a, g_b, g_A, g_xsat, *arg): """ fitfunction for a saturation (e.g., the NV PL) y(x) = a + b*x + A * x / (x + xsat) I.g.: g_a : offset g_b : linear slope g_A : maximum signal (at x=infinity) g_xsat : saturation point """ fitfunc_str = 'a + b*x + A * x / (x + x_sat)' a = fit.Parameter(g_a, 'a') b = fit.Parameter(g_b, 'b') A = fit.Parameter(g_A, 'A') xsat = fit.Parameter(g_xsat, 'xsat') p0 = [a, b, A, xsat] def fitfunc(x): return a() + b() * x + A() * x / (x + xsat()) return p0, fitfunc, fitfunc_str
def fit_ESR_gauss(g_a, g_A, g_sigma, g_x0, *arg): """ fitfunction for gaussian esr dips, y(x) = a - A*sum_i(exp(-((x-x0_i)/sigma)**2)) Initial guesses (in this order): g_a : offset g_A : dip depth (all the same) g_sigma : std dev of the dip width (all the same) g_x0 : zero-point of the esr pattern For the splittings: an arbitrary amount of splits, in the form (m, g_s) : where m=multiplicity, g_s=initial guess for the splitting of two neighboring dips Example: giving (2, 2e3), (3, 2e3), would describe two splittings, e.g., the two-fold one for the zeeman splitting of the +/-1 manifolds, and on top of that the 3-fold splitting of the N14. This results in 6 peaks in total, where 4 of them appear, because of the equal splitting in the two cases, on top of each other, yielding 2 low, and two deep dips. """ fitfunc_str = 'a - A*sum_i(exp(-((x-x0_i)/sigma)**2))' no_splits = len(arg) a = fit.Parameter(g_a, 'a') A = fit.Parameter(g_A, 'A') sigma = fit.Parameter(g_sigma, 'sigma') x0 = fit.Parameter(g_x0, 'x0') p0 = [a, A, sigma, x0] print 'fitting with %d splittings' % no_splits splits = [] for i, s in enumerate(arg): fitfunc_str += '\nsplitting s%d with multiplicity %d' % (i, s[0]) splits.append(fit.Parameter(s[1], 's%d'%i)) p0.append(splits[i]) # remove the fixed params from the p0 array # fixedp = [] # for i,p in enumerate(p0): # if i in fixedsplits: # fixedp.append(p) # for p in fixedp: # p0.remove(p) def fitfunc(x): pts = [x0()] pts_next = [] # generate the points where the dips sit for the current param # values for i in range(no_splits): m = arg[i][0] s = arg[i][1] for pt in pts: j = 0 while j < m: split = splits[i]() pts_next.append(pt-split*(m-1.)/2. + j*split) j+=1 pts = pts_next pts_next = [] depth = 0. for p in pts: depth += A() * exp(-((x-p)/sigma())**2) return a() - depth return p0, fitfunc, fitfunc_str
#V_EOM[n_steps+1,0] = 0 #measured_power[n_steps+1,0] = powermeter.get_power() #data.add_data_point(V_EOM[n_steps+1,0],measured_power[n_steps+1,0]) AWG.set_ch4_offset(0) #set EOM channel to back to 0 to avoid drift AWG.set_ch4_marker1_low(0) #set AOM voltage back to zero again data.close_file() # the fitting procedure applies only if fit_calibration_curve is flagged above! if fit_calibration_curve: def num2str(num, precision): return "%0.*f" % (precision, num) A = fit.Parameter(max(measured_power - BG) / 2) B = fit.Parameter(max(measured_power - BG) / 2) f = fit.Parameter(1 / 2.5) phi = fit.Parameter(0) def fit_cos(x): return A() + B() * cos(2 * pi * f() * x + phi()) ret = fit.fit1d(V_EOM.reshape(-1), measured_power.reshape(-1) - BG, None, fitfunc=fit_cos, p0=[A, B, f, phi], do_plot=True, do_print=True, ret=True)