Commit 1badd3be authored by Christian Schneider's avatar Christian Schneider
Browse files

Merged

parents d2461113 822b9026
......@@ -3,6 +3,11 @@
Created on Tue Apr 9 11:33:36 2019
@author: Oscar
v1.2.2 - OSC:
- inserted wait for WFA completion in the acquire data function
v1.2.1 - OSC:
- implemented connection to multiple boards when more than one is in the
chassis
v1.2.0 - OSC:
- removed 'SW' trigger mode (useless and it wasn't implemented correctly in this library) and Trigger function
- removed 'ChannelUsed' and relative function (it is always asked in the AcquireData function)
......@@ -24,8 +29,9 @@ class ADQ14(object):
import ctypes as ct
import numpy as np
import copy
import time
version='1.2.0'
version='1.2.2'
def __init__(self,board_num = 1):
import os
......@@ -48,7 +54,7 @@ class ADQ14(object):
self.ADQAPI.ADQControlUnit_FindDevices.argtypes = [self.ct.c_void_p]
self.Connect(board_num)
self.Print_adq_device_revisions()
self.__ADCSF = 1.0 #GSamples/s
......@@ -129,11 +135,29 @@ class ADQ14(object):
#---------------------------------
def Connect(self,board_num=1):
class stwrapper(self.ct.Structure):
""" creates a struct to match emxArray_real_T """
_fields_ = [('HWIFType', self.ct.c_int),
('ProductID', self.ct.c_int),
('VendorID', self.ct.c_uint),
('AddressField1', self.ct.c_int),
('AddressField2', self.ct.c_int),
('DevFile', (self.ct.c_char*64)),
('DeviceInterfaceOpened', self.ct.c_uint),
('DeviceSetupCompleted', self.ct.c_uint)]
self._adq = self.ct.c_void_p(self.ADQAPI.CreateADQControlUnit())
self.ADQAPI.ADQControlUnit_FindDevices(self._adq)
DEV_NUM=self.ADQAPI.ADQControlUnit_NofADQ(self._adq)
if DEV_NUM==0:
nof_devices = self.ct.c_int(0)
e = stwrapper()
success = self.ADQAPI.ADQControlUnit_ListDevices(self._adq,self.ct.pointer(e),self.ct.pointer(nof_devices))
nof_devices = nof_devices.value
if nof_devices==0:
print("WARNING: No device has been found")
return 0
......@@ -143,15 +167,23 @@ class ADQ14(object):
print('Error: board_num can\'t be negative!')
return 0
if board_num > DEV_NUM:
print("Erro: Selected board number {}, but only {} boards have been found!".format(board_num,DEV_NUM))
if board_num > nof_devices:
print("Erro: Selected board number {}, but only {} boards have been found!".format(board_num,nof_devices))
return 0
self.devnum = board_num
success = success and self.ADQAPI.ADQControlUnit_OpenDeviceInterface(self._adq,board_num-1)
success = success and self.ADQAPI.ADQControlUnit_SetupDevice(self._adq, board_num-1)
self.devnum = 1
self.id = 'ADQ14' #to implement better
# Print ADQAPI revision
print('ADQAPI loaded, revision {:d}.'.format(self.ADQAPI.ADQAPI_GetRevision()))
rev=self.Print_adq_device_revisions()
if rev<30e3:
print('WARNING: FPGA revision is not in the correct range, are you sure you are using the right board?\n')
self.Clock_ref() #ext ref activated by def
......@@ -184,6 +216,10 @@ class ADQ14(object):
else :
print('SVN Updated\n')
return revision[0]
def Blink(self):
self.ADQAPI.ADQ_Blink(self._adq,self.devnum)
def Reset(self,Type='COMM'):
'''function reset([Type='COMM']):
......@@ -721,7 +757,7 @@ http://localhost:8988/edit/python_repo/ADQ14.py# tmp = tm
return data_32bit
"""
def Acquire_data(self,channel_mask = 3,conversion_to_volt=True):
def Acquire_data(self,channel_mask = 3,conversion_to_volt=True,timeout=5):
'''This function start the acquisition, it will wait for the trigger.
'''
......@@ -742,6 +778,13 @@ http://localhost:8988/edit/python_repo/ADQ14.py# tmp = tm
if success == 0:
self.__ADQEXC('STARTERR','ADQ_ATDStartWFA failed!')
#Waiting for WFA
start_time = self.time.time()
while(not self.ADQAPI.ADQ_ATDWaitForWFACompletion(self._adq,self.devnum)):
if (self.time.time()-start_time) > timeout:
self.__BASEEXC('TIMEOUT','WFA failed!')
#getting data
#init only what is necessary:
......
......@@ -4,6 +4,11 @@
Created on Wed Sep 6 18:09:39 2017
@author: oscar
v2.5.3 - OSC:
- when loading waves in memory, the channels queue is cleaned. Now after
calling the function load_waves_in_AWG_memory, they will be re-queued
automatically
v2.5.2 - OSC:
- inserted the stop_multiple function
- inserted ext port setup functions
......@@ -462,7 +467,7 @@ class AWGChannel(object):
##------------------------------------------------------------------------------------------ a00 AWG class --------------------------------
class Awgsigd(object):
version = '2.5.2'
version = '2.5.3'
import keysightSD1 as sigd
import numpy as np
import matplotlib.pyplot as plt
......@@ -1028,6 +1033,8 @@ class Awgsigd(object):
self.__check_command( self._awg.waveformLoad(wave,n))
del wave #bugfix
for i in range(4):
self.__load_waves_in_channel(i)
#self.time.sleep(0.1)
def __change_offset_slow(self,channel):
......@@ -1099,8 +1106,6 @@ class Awgsigd(object):
raise ValueError
def setfunc(Channel):
if load_waves_in_memory:
self.load_waves_in_AWG_memory()
self.__check_channel_number(Channel)
tmp = self.channel(Channel)
......@@ -1121,7 +1126,7 @@ class Awgsigd(object):
pars = pars['PORT'],pars['EDGE'],pars['Sync']
port_sn = tmp.ext_port_list.index(pars[0])
if port_sn>0:
port_sn= int(port_sn+3999)
port_sn= int(port_sn+3999) #flags for ext port
self.__check_command(self._awg.AWGtriggerExternalConfig(Channel,port_sn,tmp.trigger_edge_list.index(pars[1]),int(pars[2])))
......
......@@ -212,9 +212,6 @@ class circuit(object):
display_tables((df, df_kappa),
names=['Main Results', 'Linewidths'])
# Plot of data, raw data and (successfully) fitted data if wanted
if plt_res:
cp.plot_cfit(self)
def plot_steps(self):
"""
......@@ -425,14 +422,14 @@ class Reflection(circuit):
self.phi0 = np.arcsin(self.yc_norm / self.r_norm)
# Fit final circle #####################################################
ftol = kwargs['ftol']
maxfev = kwargs['maxfev']
if not kwargs['final_mag']:
self._cir_fit_pars = ft.fit_model_refl(self.freq,
self.circle_norm,
Ql_est, absQc_est, fr_est,
self.phi0,
self._weights,
ftol=ftol)
max_nfev=maxfev)
# Calculate quality factors
self.Ql, self.absQc, self.fr, self.phi1 = \
np.abs(self._cir_fit_pars[0])
......
......@@ -196,7 +196,7 @@ def fit_model_notch(freq, data, Ql, absQc, fr, phi0, weights, max_nfev=1000):
z1d = np.zeros(data.size * 2, dtype=np.float64)
z1d[0:z1d.size:2] = diff.real ** 2 * weights
z1d[1:z1d.size:2] = diff.imag ** 2 * weights
return z1d.sum()
return z1d
f = spopt.least_squares(res, [np.abs(Ql), np.abs(absQc), fr, phi0],
args=(freq, data),
......@@ -233,8 +233,28 @@ def reflection_model_mag(x, Ql, Qc, x0, c):
return c - (2 * Ql / Qc) ** 2 / (1. + 4 * Ql ** 2 * ((x - x0) / x0) ** 2)
def fit_model_refl(freq, data, Ql, Qc, fr, phi0, weights, ftol=1e-16):
"""Final circle fit of the model to get information about Ql, Qc, fr, phi0
def fit_model_refl(freq, data, Ql, Qc, fr, phi0, weights, max_nfev=1000):
"""Final fit of the model for reflection to get information about Ql,
Qc and fr.
Parameters
-----------
freq : np.array, list
List of frequencies
data : np.array, list
List of complex data points
Ql : float
Guess value for Ql
absQc : float
Guess value for Qc
fr : float
Guess value for resonance frequency
phi0 : float
Guess value for impedance mismatch
weights : np.array, list
Weights for fit.
max_nfev : int
Maximum number of iterations. Increase for increased precision.
"""
def res(params, f, data):
......@@ -245,18 +265,14 @@ def fit_model_refl(freq, data, Ql, Qc, fr, phi0, weights, ftol=1e-16):
z1d[1:z1d.size:2] = diff.imag ** 2 * weights
return z1d
f = spopt.leastsq(res, [Ql, Qc, fr, phi0], args=(freq, data),
full_output=True, xtol=ftol, ftol=ftol)
# f = spopt.least_squares(res, [Ql, Qc, fr, phi0], args=(freq, data),
# bounds=([Ql-.5*Ql, Qc-.5*Qc, fr-10*fr/Ql,
# -np.pi],
# [Ql+0.5*Ql, Qc+0.5*Qc, fr+10*fr/Ql,
# np.pi]),
# xtol=2.3e-16, ftol=2.5e-16, gtol=2.5e-16,
# loss='huber',
# verbose=2)
f = spopt.least_squares(res, [np.abs(Ql), np.abs(Qc), fr, phi0],
args=(freq, data),
verbose=0, max_nfev=max_nfev, xtol=2.3e-16,
ftol=2.3e-16,
bounds=([0, 0, 0, -np.pi],
[10e9, 10e9, 20e9, np.pi]))
return f[0], f[1]
return f.x, f
def fit_mag_refl(freq, data, Ql, Qc, fr, phi0, weights, ftol=1e-16):
......@@ -286,13 +302,21 @@ def subtract_linear_bg(freq, data, fit_range=0.1):
def get_weights(freq, Ql, fr, weight_width):
"""Weighting of the function. In range of FWHM, determined by
(Ql/fr)*weight_width. Outer values are weighted prop. to 1/abs(f-fr)
(Ql/fr)*weight_width. Outer values are weighted prop. to 1/abs(f-fr)^r
"""
width = fr / Ql
weights = np.ones(len(freq))
outer_idx = np.abs(freq - fr) > width * weight_width
weights[outer_idx] = (width * weight_width) / (np.abs(freq[outer_idx] - fr))
left_idx = np.argwhere(outer_idx == 0)[0][0]
right_idx = np.argwhere(outer_idx == 0)[-1][0]
r = 2
weights[right_idx:] = 1 / ((freq[right_idx:] - freq[right_idx]) / (
freq[right_idx] - fr) + 1) ** r
weights[:left_idx] = 1 / ((freq[:left_idx] - freq[left_idx]) / (
freq[left_idx] - fr) + 1) ** r
return weights
......
This diff is collapsed.
......@@ -7,6 +7,7 @@ from CircleFit.plotting import plot_rawdata
import CircleFit.plotting as cp
from CircleFit.circuit import Notch, Reflection
from CircleFit.fit_toolbox import get_delay
from bokeh.plotting import show
class data_complex(data_table):
......@@ -235,11 +236,6 @@ class data_complex(data_table):
f_range=f_range)
self._delayOffset = offset
else:
_, offset = get_delay(self, comb_slopes=comb_slopes,
f_range=f_range)
self._delayOffset = offset
# Save set delay
self.delay = delay
......@@ -254,16 +250,43 @@ class data_complex(data_table):
engine : str
Chose the plot engine between 'bokeh' (default) and 'pyplot'
"""
# TODO Rewrite without try and except
try:
if self.circuit is not None:
self.plot_fitted_data(engine=engine, **kwargs)
except:
else:
self.plot_rawdata(engine=engine, **kwargs)
def plot_rawdata(self, **kwargs):
def plot_rawdata(self, engine='b', **kwargs):
"""Plots plain data"""
plot_rawdata(self.x, self.value, **kwargs)
plot_rawdata(self, engine=engine, **kwargs)
def plot_single(self, type='dB', engine='b', fit=True, **kwargs):
"""Plot a single figure. Choose between 'dB', 'phase', 'ReIm',
'Circle'
Parameters
-----------
type : 'dB', 'phase', 'ReIm', 'Circle'
Choose type of plot.
engine : 'b', 'p'
Bokeh or pyplot
fit : bool
Try to plot fit if possible?
**kwargs
Additional keywords for plot.
"""
if type[0].lower() == 'd':
p = cp.plot_MagFreq(self, engine, fit, **kwargs)
elif type[0].lower() == 'p':
p = cp.plot_PhaseFreq(self, engine, fit, **kwargs)
elif type[0].lower() == 'c':
p = cp.plot_NormCircle(self, engine, fit, **kwargs)
else:
p = cp.plot_ReIm(self, engine, fit, **kwargs)
if engine[0].lower() == 'b':
show(p)
def circle_fit_notch(self, delay=None, a=None, alpha=None, phi0=None,
subtract_bg=True, fr_init=None, Ql_init=None,
......@@ -336,18 +359,21 @@ class data_complex(data_table):
kwargs = {'delay': delay, 'a': a, 'alpha': alpha, 'phi0': phi0,
'subtract_bg': subtract_bg, 'fr_init': fr_init,
'Ql_init': Ql_init, 'weight_width': weight_width,
'print_res': print_res, 'plt_res': plot_res,
'print_res': print_res, 'plt_res':plot_res,
'maxfev': maxfev, 'comb_slopes': comb_slopes,
'final_mag': final_mag, 'ftol': ftol,
'fit_range': fit_range}
self.circuit = Notch(self, **kwargs)
# Plot if wanted
if plot_res:
cp.plot_cfit(self)
# Further save fitresults in data_complex class
self.fitresults = self.circuit.fitresults
def circle_fit_reflection(self, delay=None, a=None, alpha=None, phi0=0,
subtract_bg=True, fr_init=None, Ql_init=None,
weight_width=1, print_res=True, plt_res=True,
weight_width=1, print_res=True, plot_res=True,
comb_slopes=False, final_mag=False, maxfev=1e3,
ftol=1e-16, fit_range=0.15):
"""Circle fit for reflection configuration.
......@@ -418,17 +444,20 @@ class data_complex(data_table):
kwargs = {'delay': delay, 'a': a, 'alpha': alpha, 'phi0': phi0,
'subtract_bg': subtract_bg, 'fr_init': fr_init,
'Ql_init': Ql_init, 'weight_width': weight_width,
'print_res': print_res, 'plt_res': plt_res, 'maxfev': maxfev,
'print_res': print_res, 'plt_res': plot_res, 'maxfev': maxfev,
'comb_slopes': comb_slopes, 'final_mag': final_mag,
'ftol': ftol, 'fit_range': fit_range}
self.circuit = Reflection(self, **kwargs)
# Plot if wanted
if plot_res:
cp.plot_cfit(self)
# Further save fitresults in data_complex class
self.fitresults = self.circuit.fitresults
def plot_fitted_data(self, **kwargs):
def plot_fitted_data(self, engine='b', **kwargs):
"""Plot fitted data"""
cp.plot_cfit(self.circuit, **kwargs)
cp.plot_cfit(self, engine=engine, **kwargs)
def plot_steps(self):
"""Plot each step of the circlefit routine"""
......
......@@ -348,9 +348,10 @@ class data_table(data_module_base):
kws['x_axis_type'] = 'log'
if logy:
kws['y_axis_type'] = 'log'
fig = bp.figure(plot_width=800, plot_height=400, tools=tools,
toolbar_location='above', title=title,
**kws)
fig = bp.figure(tools=tools,
height=300,
sizing_mode='scale_width',
title=title, **kws)
# Empty legend if no legend is given
if legend is None:
......
......@@ -12,8 +12,8 @@ import pickle
import numpy as np
import pandas as pd
from .downwards_compatibility.data_line import data_line
from .downwards_compatibility.data_surface import data_surface
from .downwards_compatibility.data_line import data_line,data_2d
from .downwards_compatibility.data_surface import data_surface,data_3d
from .data_complex import data_complex
from .data_grid import data_grid
......@@ -170,26 +170,9 @@ def plot_multiple(dm_list, label_list, figure=None, colormap=None,
kwargs : keywords
Optional: Keywords for bokeh or pyplot
"""
# Get colors
# Get number of plots
n_plots = len(dm_list)
# Get colormap
if isinstance(colormap, str):
# Get colormap from default library by name
tmp = plt.cm.get_cmap(colormap, n_plots)
colormap = [matplotlib.colors.rgb2hex(tmp(i)) for
i in range(n_plots)]
elif colormap is None:
# Use 8 default colors if less than 8 columns to plot
if n_plots <= len(color_scheme):
# Import default colormap
if colormap is None:
colormap = color_scheme
# Use more colors
else:
tmp = plt.cm.get_cmap('magma', n_plots)
colormap = [matplotlib.colors.rgb2hex(tmp(i)) for
i in range(n_plots)]
# Plot
# Plot in pyplot
......@@ -784,8 +767,8 @@ def upgrade_dm(old_dm):
data_new.idx_min = old_dm.xmin
data_new.idx_max = old_dm.xmax # Selected
except AttributeError:
data_new.idx_min = old_dm.idx_min
data_new.idx_max = old_dm.idx_max
data_new.idx_min = 0#old_dm.idx_min
data_new.idx_max = None#old_dm.idx_max
# For newer datamodules: Update dataframe
try:
......
......@@ -223,7 +223,7 @@ class fit_plugin(object):
# Frequency
# Guess from fft
if f0 is None:
f_guess = freqs[srtd[-1]]
f_guess = np.abs(freqs[srtd[-1]])
else:
f_guess = f0
......@@ -237,6 +237,10 @@ class fit_plugin(object):
amp=amp_guess,
vert_offset=vert_offset_guess,
hor_offset=hor_offset_guess)
# Set boundaries
params['tau'].min = 0
params['f'].min = 0
params['amp'].min = 0
# Fitting ##############################################################
self.fit_routine(gmodel, params, plot, print_results, plot_init)
......@@ -255,7 +259,7 @@ class fit_plugin(object):
\mathrm{offset}
"""
# Guess values ###########################################################
# Guess values #########################################################
# x0
if x0 is None:
......@@ -289,14 +293,18 @@ class fit_plugin(object):
else:
offset_guess = offset
# Create LM Fit model ####################################################
# Create LM Fit model ##################################################
gmodel = Model(lorentz_function)
# Init pars to guess values ##############################################
# Init pars to guess values ############################################
params = gmodel.make_params(x0=x0_guess,
amplitude=amp_guess,
gamma=gamma_guess,
offset=offset_guess)
# Set boundaries
params['x0'].min = 0
params['amplitude'].min = 0
params['gamma'].min = 0
# Fitting ################################################################
# Fitting ##############################################################
self.fit_routine(gmodel, params, plot, print_results, plot_init)
......@@ -22,6 +22,7 @@ import matplotlib.pyplot as plt
import peakutils
from scipy.signal import welch
import matplotlib.pyplot as plt
import bokeh.plotting as bp
......@@ -234,6 +235,8 @@ class DC_SQUID(object):
y_axis_label='V_SQUID (V)')
p = const_plot_xy(self.daq, self.xxf.get_parameters(), fig,
acq_time)
#fig = plt.figure(dpi=200)
p.start()
def stop(b):
......@@ -515,7 +518,7 @@ class DC_SQUID(object):
def acq_spectrum_SA(self, f_start=1e3, f_stop=1e6, BW=1, units='Volts',
averages=1, filename=None, verbose=True, force=False,
get_Rd=True, to_flux=False, **dm_pars):
get_Rd=True, to_flux=False,points=8001, **dm_pars):
"""Acquire spectrum using spectrum analyzer.
In FLL mode, the squid gain is required to normalize the
......@@ -561,10 +564,10 @@ class DC_SQUID(object):
filename=None,
autoplot=False,
print_info=False,
points=8001)
points=points)
xxf_pars = self.xxf.get_parameters()
if units in ['Volts']:
if units in ['Volts', 'V']:
spec.y = spec.y ** 2 # in V^2/Hz
spec.y /= spec.par['BW'] # normalized to BW
spec.rename_y('PSD (V^2/Hz)')
......@@ -627,7 +630,7 @@ class DC_SQUID(object):
def acq_spectrum_both(self, acq_time=1, BW=1, to_flux=False, filename=None,
welch_factor=5, f_start=1e3, f_stop=1e6,
units='Volts', averages=1, force=False,
verbose=False, amp_BW='full'):
verbose=False, amp_BW='full', points=8001):
"""Acquire DAQ and SA spectrum at the same time
Parameters
......@@ -679,7 +682,7 @@ class DC_SQUID(object):
sa_thread = pool.apply_async(self.acq_spectrum_SA,
(f_start, f_stop, BW, units,
averages, fname_sa, verbose, force,
False, to_flux))
False, to_flux, points))
daq = daq_thread.get()
sa = sa_thread.get()
......@@ -1376,7 +1379,7 @@ class const_plot_xy(Process):
x, y = dm.average_duplicates(x, y)
self.fig = fig
self.v_p = self.fig.line(x * self.gen1['PeakPeak'],
v_p = self.fig.line(x * self.gen1['PeakPeak'],
y / self.gain,
line_width=2)
self.handle = bp.show(self.fig, notebook_handle=True)
......@@ -1406,3 +1409,57 @@ class const_plot_xy(Process):
if self.v_p:
del self.v_p
self.exit.set()
class const_plot_xy_pyplot(Process):
"""Continuously plotting xy from DAQ"""
def __init__(self, daq, xxf_pars, fig, acq_time=0.1):
Process.__init__(self)
self.exit = Event()
# Init plot
self.acq_time = acq_time
# Save XXF parameters
self.gen1 = xxf_pars['Gen1']
self.gain = xxf_pars['Amp_Gain']
self.Phib = xxf_pars['Phib']
self.Ib = xxf_pars['Ib']
# Set DAQ
daq.set_channels([3, 7]) # 3 Monitor, 7 signal
x, y = daq.read(acq_time)
x = np.array(x)
y = np.array(y)
self.daq = daq
# Shift by 0.5 if generator is not set to bipolar