Commit ccd2701c authored by Christian Schneider's avatar Christian Schneider
Browse files

Implemented all data_surface functions for data_grid

parent dee44cc4
......@@ -10,12 +10,14 @@ from .base import data_module_base
import holoviews as hv
import holoviews.operation.datashader as hd
import scipy.signal as sp_sig
import scipy.interpolate as sp_intp
import matplotlib.pyplot as plt
import numpy as np
import xarray as xr
from .data_table import data_table
from IPython.display import display
from mpl_toolkits.axes_grid1 import make_axes_locatable
from .fit_functions import mode_fit, lorentzian_fit
hv.extension('bokeh')
......@@ -359,4 +361,288 @@ class data_grid(data_module_base):
zsel = self.values
for idx, row in enumerate(zsel.T):
zsel[:, idx] = sp_sig.savgol_filter(row, nnb, polyorder)
return zsel
\ No newline at end of file
return zsel
def interp(self, xnew, ynew, kind='cubic'):
"""Interpolates data to new x, y values `xnew` and `ynew`
Parameters
-----------
xnew : np.array
New x array
ynew : np.array
New y array
kind : str
Chose interpolation kind out of ['linear', 'cubic', 'quintic']
Returns
--------
DataModule
A new data_surface DataModule
"""
# interp2d has a weird structure, therefore we have to transpose
f = sp_intp.interp2d(self.x, self.y, self.values.T, kind=kind)
return data_grid([xnew, ynew, f(xnew, ynew).T], [self.name_x,
self.name_y,
self.name_v])
def extract_min_x(self, argument=True, nnB=21, polyorder=2):
"""Extract minimum z-values sweeping through x.
Smooth data and extract minimum z values sweeping through x.
Note
-----
Return depends on argument.
- If set to True, it will return a new datamodule with (y, x)
- If set to False, it will return a new datamodule with (y, min(z))
Parameters
-----------
argument : bool
Return corresponding x value (True) or corresponding minimum value
nnB : int
Window length for smoothing. Set to 1 to disable
smoothing.
polyorder : int
Polynomial order for smoothing
Returns
--------
DataModule
A `data_line` DataModule. Values depend on argument keyword (see
above)
"""
if nnB == 1:
zsel = self.values
else:
zsel = self.smoothx(nnB, polyorder) # Z data is smoothened along y
tmp = np.zeros_like(self.x, dtype=np.float)
# Get minima
if argument:
# Return y values
for i in range(len(tmp)):
tmp[i] = self.y[np.argmin(zsel[i, :])]
name_tmp = self.name_y
else:
# Return z values
for i in range(len(tmp)):
tmp[i] = np.min(zsel[i, :])
name_tmp = self.name_v
data = data_table([self.x, tmp], [self.name_x, name_tmp])
data.par = self.par
data.temp_start = self.temp_start
data.temp_stop = self.temp_stop
data.time_start = self.time_start
data.time_stop = self.time_stop
return data
def extract_min_y(self, argument=True, nnB=21, polyorder=2):
"""Extract minimum z-values sweeping through y.
Smooth data and extract minimum z values sweeping through y.
Note
-----
Return depends on argument.
- If set to True, it will return a new datamodule with (y, x)
- If set to False, it will return a new datamodule with (y, min(z))
Parameters
-----------
argument : bool
Return corresponding x value (True) or corresponding minimum value
nnB : int
Window length for smoothing. Set to 1 to disable
smoothing.
polyorder : int
Polynomial order for smoothing
Returns
--------
DataModule
A `data_line` DataModule. Values depend on argument keyword (see
above)
"""
if nnB == 1:
zsel = self.values
else:
zsel = self.smoothx(nnB, polyorder) # Z data is smoothened along y
tmp = np.zeros_like(self.y, dtype=np.float)
# Get minima
if argument:
# Return x values
for i in range(len(tmp)):
tmp[i] = self.x[np.argmin(zsel[:, i])]
name_tmp = self.name_x
else:
# Return z values
for i in range(len(tmp)):
tmp[i] = np.min(zsel[:, i])
name_tmp = self.name_v
data = data_table([self.y, tmp], [self.name_y, name_tmp])
data.par = self.par
data.temp_start = self.temp_start
data.temp_stop = self.temp_stop
data.time_start = self.time_start
data.time_stop = self.time_stop
return data
def extract_min_lorentzianfit_y(self, p0=None, argument=True, plot=False,
adapt_p0=False):
"""Use Lorentzian with initial parameters p0 to fit the maximum z-value
while sweeping through y.
Note
-----
Return depends on argument.
- If set to True, it will return a new datamodule with (y, x)
- If set to False, it will return a new datamodule with (y, max(z))
Parameters
-----------
p0 : list
Initial guess for lorentzianfit pars ['center', 'width', 'offset',
'amplitude']
argument : bool
Return x or z values
plot : bool
Plot each iteration
adapt_p0 : bool
Use p0 of last iteration
Returns
--------
DataModule
A `data_line` DataModule. Values depend on argument keyword (see
above)
"""
tmp = np.zeros_like(self.y)
err_bars = []
# Guess initial parameters, if none is given
if p0 is None:
tmp_data = data_table([self.x, self.values[:, 0]])
idx_min = np.argmin(tmp_data.y)
offset = np.mean(tmp_data.y)
center = tmp_data.x[idx_min]
width = center/1e6 # kHz as guess
amplitude = tmp_data.y[idx_min] - offset
p0 = [center, width, offset, amplitude]
# Go through y values and find x coordinate for maximum z value
if argument:
# Return x values
for i in range(len(tmp)):
tmp_dm = data_table([self.x, self.values[:, i]])
fpars, fpars_err, _ = tmp_dm.fit(lorentzian_fit, p0, plot=plot,
plot_init=False,
plot_params=False,
maxfev=10000)
tmp[i] = fpars[0]
err_bars.append(fpars_err[0])
tmp_name = self.name_x
if adapt_p0:
p0 = fpars
else:
# Return z values
for i in range(len(tmp)):
tmp_dm = data_table([self.x, self.values[:, i]])
fpars, fpars_err, _ = tmp_dm.fit(lorentzian_fit, p0, plot=plot,
plot_init=False,
plot_params=False,
maxfev=10000)
tmp[i] = lorentzian_fit(fpars[0], *fpars)
tmp_err_bar = np.sqrt((2*fpars[3]/(np.pi*fpars[1]**2)*fpars_err[1])**2 + fpars_err[2]**2 +
(2/(np.pi*fpars[1])*fpars_err[3])**2)
err_bars.append(tmp_err_bar)
tmp_name = self.name_v
if adapt_p0:
p0 = fpars
data = data_table([self.y, tmp, err_bars],
[self.name_y, tmp_name, '{} Errors'.format(tmp_name)])
data.par = self.par
data.temp_start = self.temp_start
data.temp_stop = self.temp_stop
data.time_start = self.time_start
data.time_stop = self.time_stop
return data
def extract_min_modefit_y(self, p0=None, argument=True, plot=False):
"""Use mode fit with initial parameters p0 to fit the minimum z-value
while sweeping through y.
Note
-----
Return depends on argument.
- If set to True, it will return a new datamodule with (y, x)
- If set to False, it will return a new datamodule with (y, min(z))
Parameters
-----------
p0 : list
Initial guess for modefit pars ['offset', 'Qc', 'df', 'f0', 'Qi']
argument : bool
Return x or z values
Returns
--------
DataModule
A `data_line` DataModule. Values depend on argument keyword (see
above)
"""
tmp = np.zeros_like(self.y)
err_bars = []
# Guess initial parameters, if none is given
if p0 is None:
tmp_data = data_table([self.x, self.values[:, 0]])
idx_min = np.argmin(tmp_data.y)
offset = np.mean(tmp_data.y)
Qc = 1e4 # Medium value
Qi = 1e4 # Medium value
f0 = tmp_data.x[idx_min] # Frequency of minimum
df = f0/1e6 # MHz?
p0 = [offset, Qc, df, f0, Qi]
# Go through y values and find x coordinate for minimum z value
if argument:
# Return x values
for i in range(len(tmp)):
tmp_dm = data_table([self.x, self.values[:, i]])
fpars, fpars_err, _ = tmp_dm.fit(mode_fit, p0, plot=plot,
plot_init=False,
plot_params=False,
maxfev=10000)
tmp[i] = fpars[3]
err_bars.append(fpars_err[3])
tmp_name = self.name_x
else:
# Return z values
for i in range(len(tmp)):
tmp_dm = data_table([self.x, self.values[:, i]])
fpars, _, _ = tmp_dm.fit(mode_fit, p0, plot=plot,
plot_init=False, plot_params=False,
maxfev=10000)
tmp[i] = mode_fit(fpars[3], *fpars)
tmp_name = self.name_v
data = data_table([self.y, tmp, err_bars],
[self.name_y, tmp_name, '{} Errors'.format(tmp_name)])
data.par = self.par
data.temp_start = self.temp_start
data.temp_stop = self.temp_stop
data.time_start = self.time_start
data.time_stop = self.time_stop
return data
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment