Commit ba23e7ec authored by Oscar Gargiulo's avatar Oscar Gargiulo
Browse files

Updates to data_IQ

parent 941fd4e7
This diff is collapsed.
# -*- coding: utf-8 -*-
"""Standard fit functions used in the data module."""
import numpy as np
kb = 1.3806488e-23 #m2 Kg s-2 K-1
hbar = 1.054571726e-34 #Js
bose_par_labels = ['Amplitude', 'Temperature']
def bose(E, A0, T):
"""Bose Einstein distribution for energies in units of GHz"""
return A0*1/(np.exp(E*hbar*2*np.pi*1e9/(kb*T))-1)
boltzmann_par_labels = ['Amplitude', 'Temperature']
def exp_boltzmann(f, A, T):
"""Boltzmann factor, frequency f in units of GHz, temperature in K"""
return A*np.exp(-f*hbar*2*np.pi*1e9/(kb*T))
gaussian2d_fit_labels = ['center_x','center_y','amplitude','sigma']
def gaussian2d(xy,*p):
""""Bidimensional gaussian fit, data must be a matrix:
pars:
- p[0]: x-center
- p[1]: y-center
- p[2]: gaussian height (Gaussian center is at p[2] and goes to zero at infinity)
- p[3]: sigma
"""
x,y = xy
def distance(x,y,x0,y0):
return np.sqrt((x-x0)**2+(y-y0)**2)
def evaluate(x,y):
d = distance(x,y,p[0],p[1])
sigma = p[3]
amp = p[2]
z = np.exp(-d**2/2/sigma**2)#/np.sqrt(2*np.pi)/sigma
return amp*z
z = np.ndarray((len(x),len(y)))
for i in range(len(xy[0])):
for j in range(len(y)):
z[i,j] = evaluate(x[i],y[j])
return z.transpose()
def gaussian2d_multi(xy,*p):
""""Bidimensional gaussian fit, data must be a matrix containing multiple gaussian distributions:
pars:
- p[0+k]: x-center
- p[1+k]: y-center
- p[2+k]: gaussian height (Gaussian center is at p[2] and goes to zero at infinity)
- p[3+k]: sigma
where k is the number of gaussian to fit (for 2 gaussians, 8 parameters must be given, for 3, 12 are needed, etc.).
"""
N_gaussians = int(len(p)/4)
#return p[0],p[1]
z = np.zeros((len(xy[0]),len(xy[1])))
#print('z_size: ({},{})\n'.format(len(z),len(z[0])))
for i in range(N_gaussians):
tmp = gaussian2d(xy,*p[4*i:4+4*i])
#print('tmp_size: ({},{})\n'.format(len(tmp),len(tmp[0])))
z += tmp
return z
mode_fit_pars_labels = ['offset', 'Qc', 'df', 'f0', 'Qi']
def mode_fit(x,*p):
"""Fit for obtaining Quality factors out of resonances.
.. math::
y = p[0] + 20\log(|1 - (1/p[1] - 2i p[2]/p[3])/(1/Ql + 2i(x-p[3]-p[2]\
)/(p[3]+p[2]))
Function parameters:
| p[0]: = offset
| p[1] = Qc
| p[2] = dF
| p[3] = resonance frequency
| p[4] = Qint
Todo
-------
Sources missing
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values
"""
s0 = p[0]
Qext = p[1]
dF = p[2]
Fres = p[3]
Qint = p[4]
F = x
Qtot = 1./(1./Qext + 1./Qint)
Fres2 = Fres+dF
return s0 + 20.*np.log10(np.absolute(1. - (1./Qext - 2*1j*dF/Fres) /
(1./Qtot + 2*1j*(F-Fres2)/Fres2)))
exp_fit_pars_labels = ['offset', 'Amplitude', 'delay', 'tau']
def exp_fit(x, *p):
"""Exponential function
.. math::
y = p[0] + p[1]\exp(-(x-p[2])/p[3])
Function parameters:
| p[0]: = vertical offset
| p[1] = Amplitude
| p[2] = horizontal offset
| p[3] = tau (default exp is negative)
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values
"""
return p[0] + p[1]*np.exp(-(x - p[2])/p[3])
def exp_fit_rev(x, *p):
"""Declining exponential function
.. math::
y= p[0] + p[1](1-\exp(-(x-p[2])/p[3]))
Function parameters:
| p[0] = vertical offset
| p[1] = Amplitude
| p[2] = horizontal offset
| p[3] = tau (default exp is negative)
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values
"""
return p[0] + p[1]*(1.-np.exp(-(x-p[2])/p[3]))
def poly_fit(x, *p):
"""Polynomial function.
.. math::
y = p[0] + p[1]x + p[2]x^2 + ...
Function parameters:
| p[0] = offset
| p[1] = coefficient for x
| p[2] = coefficient for x^2
| ...
Note
-----
Function infers degree of polynom from number if guessed initial
parameters
Example
--------
>>> poly_fit(x,[1.,1.,1.,1.])
p[0]+p[1]*x+p[2]*x**2+p[3]*x**3
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values. List size depends of given number of parameters
"""
pol = 0
for i in range(len(p)):
pol += p[i]*(x**i)
return pol
lorentzian_fit_pars_labels = ['center', 'half-width', 'offset', 'amplitude']
def lorentzian_fit(x,*p):
"""Lorentzian function
.. math::
y(x) = p[1]**2/((x-p[0])**2 +p[1]**2 )
returns p[3]*y+p[2]
Function parameters:
| p[0] = center
| p[1] = half-width
| p[2] = baseline
| p[3] = amplitude
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values. List size depends of given number of parameters
"""
y=p[1]**2/((x-p[0])**2 +p[1]**2 )
return p[3] * y + p[2]
def sqrt_lorentzian_fit(x,*p):
"""Lorentzian function
.. math::
y(x) = y=p[1]**2/((x-p[0])**2 +p[1]**2 )
returns p[3]*np.sqrt(y)+p[2]
Function parameters:
| p[0] = center
| p[1] = half-width
| p[2] = baseline
| p[3] = amplitude
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values. List size depends of given number of parameters
"""
y = p[1]**2/((x-p[0])**2 +p[1]**2 )
return p[3] * np.sqrt(y) + p[2]
gaussian_fit_pars_labels = ['center', 'sigma', 'offset', 'peak']
def gaussian_fit(x,*p):
"""Gaussian function
.. math::
y(x) = N * exp(-0.5*(x-p[0])/p[1])**2) #N is normalization such that the peak is 1
returns p[3]*y+p[2]
Function parameters:
| p[0] = center
| p[1] = sigma
| p[2] = baseline/vertical offset
| p[3] = peak distance from offset
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values. List size depends of given number of parameters
"""
y= np.exp(-0.5*((x-p[0])/p[1])**2)#/(np.sqrt(2*np.pi)*p[1])
return p[3] * y/y.max() + p[2]
cos_fit_pars_labels = ['amplitude', 'period', 'phase', 'offset']
def cos_fit(x, *p):
"""Cosine function
.. math::
y(x) = p[0] \cos(2\pi/p[1] x+p[2])+p[3]
Function parameters:
| p[0] = amplitude
| p[1] = period
| p[2] = phase
| p[3] = offset
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values. List size depends of given number of parameters
"""
return p[0]*np.cos(2*np.pi/p[1]*x+p[2])+p[3]
T2_fit_pars_labels = ['amplitude', 'period', 'phase', 'tau', 'offset']
def T2_fit(x, *p):
"""T2 function
.. math::
y(x) = p[0] \sin(2\pi/p[1] x+p[2]) \exp(-x/p[3])+p[4]
Function parameters:
| p[0] = amplitude
| p[1] = period
| p[2] = phase
| p[3] = tau
| p[4] = offset
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values. List size depends of given number of parameters
"""
return p[0]*np.sin(2*np.pi/p[1]*x+p[2])*np.exp(-x/p[3])+p[4]
T2_beating_fit_pars_labels = ['amplitude', 'period1', 'phase1', 'period2',
'phase2', 'tau', 'offset']
def T2_beating_fit(x,*p):
"""T2 beating function
.. math::
y(x) = p[0] \sin(2\pi/p[1] x + p[2]) \sin(2\pi/p[3] x + p[4]) \
\exp(-x/p[5])+p[6]
Function parameters:
| p[0] = amplitude1
| p[1] = period1
| p[2] = phase1
| p[3] = period2
| p[4] = phase2
| p[5] = tau
| p[6] = offset
Parameters
-----------
x : float
x value
*p : args
Initial parameter guesses
Returns
--------
float, np.array, list
Function values. List size depends of given number of parameters
"""
return p[0]*np.sin(2*np.pi/p[1]*x+p[2])*np.sin(2*np.pi/p[3]*x+p[4]) *\
np.exp(-x/p[5])+p[6]
__version__ = '3.4.0'
"""
Last Updates:
v3.4.0 - OSC:
- updated dataIQ:
- inserted pyplot enginge for plot()
- renamed bins() in create_bins()
- inserted the function get_it_straight() to rotate the plane automatically after fitting 2 "disks"
- fixed a bug with the plot od the function fit_gaussian_2d
- dataIQ.I and dataIQ.Q are now properties, they substitute the functions retur_selI() and return_selQ()
- inserted the properties dataIQ.angle and dataIQ.M, they are connected, changing one changing the second also.
- angle is the rotation angle of the plane, positive is anti-clockwise
- M is the 2x2 rotation matrix, related to angle: [cos(angle),-sin(angle),sin(angle),cos(angle),]
- inserted the functions data_I() and data_Q() that return resp. a data_table I(x) and Q(x), where x is in samples or the time axis
- changed the way the fit results are stored (now is a list of pandas tables, with values and error, like the data_table)
v3.3.0 - CHR.
- Updated to saving to .h5 and .nc files (no pickle any longer)
- implemented mfit module
v3.1.0 - OSC:
- fixed the average_data function, at the moment it works only for data_table
v3.0.0. -CHR:
- Updated to data_table and data_grid structure
v2.6.1 - OSC:
- corrected the amplitude of the lorentzian_fit function
v2.6.0 - OSC:
- reduced data_complex mem usage, dB and phase are now functions, check the
help of these functions for more info
- update the data module conversion function to adapt to the new
data_complex
v2.5.0 - CHR:
- Automatically sort data during upgrade for data_line
- Added function to plot multiple datamodules in one figure dm.plot_multiple
v2.4.1 - CHR:
- Removed Resize Tool in bokeh (depreciated)
v2.4.0 - CHR:
- Added data_IQ class
v2.3.7 - OSC:
- re-launching the exception when a fit failes (inside data_line.fit() function), one has to have the possibility to handle exceptions.
NOTE: This exception handling was added and it is not written in the version.
v2.3.6 - Michael
- Added extract_max_lorentzianfit_y to data_surface
v2.3.5 - CHR:
- Added compatibiltiy to matplotlib quick syntax
v2.3.4 - CHR:
- Some minor improvements and bugfixes
v2.3.3 - CHR:
- Adapted OSC load folder function to datamodule.
v2.3.2 - OSC:
- when saving with the 'save' function, if the file exists it will copy the
old file in the "duplicates" folder and will append a number to it. The new
file will be saved in the current folder with the given name. In this way
if a measurement didn't give the correct result, one can measure it again
using the same name, all the discarded measurements will accumulate in the
"duplicates" folder.
v2.3.1 - OSC:
- the return_min/max of data_surface code has been fixed (nnB=1 disables
interpolation)
v.2.3.0 -CHR:
- Fixed bugs and compatibility of circlefit (thanks to David)
v2.2.1 -CHR:
- Fixed color chosing bug for data_line.plot()
v2.2.0 -CHR:
- Formatted and checked code for Circlefit
- Change structure of circlefit, a data_complex module can now have a subclass
circuit in which everything about the circlefit is stored
v2.1.2 - CHR:
- Adapted upgrade_dm function for new dB and phase subdatamodule of complex
data
- took out 'o' from color names, because for style flag o means circles
v2.1.1 - CHR:
- removed hardcoded axes label in surface plot
v2.1.0 - CHR:
- changes in complex data module for convenient working
- added .dB() and .phase() functions to extract magnitude and phase
- added plot_dB and plot_phase function for plotting magnitude and phase
- modulized plotting
v2.0.7 - OSC:
-added the function T2_beating in fit functions
v2.0.6 (CHR)
- Changed to not automatically show plot if figure is given for data_line
- Formatting HoverTool for data_line
v2.0.5 - OSC:
- small update to the function local_min in data_line
- added the function local_max
v2.0.4 - OSC:
- fixed the function avarage data (it was an old version)
v2.0.3 (DAV, CHR)
- added missing return for load_csv functions
- modified return for data_surface, to return correct data
- fixed bug, now data_line works without error
- Fix in update datamodule function: Upgrade message appears now just one time
if multiple files are upgrade
v2.0.2 (CHR, DAV):
- Bugfix for average function in data_stash_x and combine_data to support
complex values
v2.0.1 (CHR, OSC, DAV):
- Added function to import csv: dm.load_csv(Filename)
- Bugfixes
- Updated upgrade function
v2.0.0 (CHR):
- Implemented folder structure
- Small code corrections
- Added style configuration for plots
- Changed smooth function to more sophisticated filter
- Removed smooth_vec function
- Added bokeh plot function to data_2d
- Added bokeh plot function to data_3d
- fixed norm in data_3d.imshow()
- update color scheme for data_3d.imshow()
- update smooth functions in data_3d to savitzky golay
- fixes in data_line.fit() function
- changed error to chi_squared in fit function
- renamed retur_fit_values to fit_func
- Renamed data.cplx to data.complex()
- Added plot function to data.complex()
- Added aspect ratio to data_surface.plot() functions
- Changed plot function for circlefit to display dB and phase
- Changed extract function to return just one array (f>= value)
- Added function to import csv
v1.6.0 - OSC:
- modified the functions contourf and imshow in data_3d
(check the help function for details)
- imshow now plots correctly (it was flipped before)
- The load_datamodule function will now try as default to upgrade an opened
datamodule, it is possible to toggle this option
v1.5.2 - CHR:
- dm.fit:
added possibility to change fit function parameters for scipys
optimize fitfunction
v1.5.1 - OSC:
- moved the version number inside the class constructor
- printed a conversion note, but it will work only from now on (see above)
v1.5.0 - OSC:
- inserted a common function that tries to convert old data modules in an updated one
- renamed data_2d.__fit_executed in ._fit_executed
v1.4.0 - OSC:
- inserted the functions for errors management in data_2d, plotting errorbars in old datamodule will not work
v1.3.3 - DAV:
- Improved data_cplx to automatically evaluated used parameters when
using reflection config.
v.1.3.2 - CHR:
- Improved .save again
- Print error message if file already exists
- Create subfolder duplicates and saves file there to preven data loss
v1.3.1 - DAZ:
- improved .save, such that it:
- creates directory automatically if it does not exist
- in case file already exists it appends next free int. number
- names measurements 'measurement' by default
v1.3.0 - Oscar:
- re-organized the classes, now every datamodule class inherit a base class
- improved memory usage
- the datamodule doesn't contain a selection of the copy, to obtain a selection use return_xsel(), return_ysel(), return_zsel() and return_vsel() functions
v1.2.6 - DAZ:
- minor updates in complex datamodule for new bokeh plotting engine
prior pyplot is still available, set plot_engine = 'pyplot' when calling circle fit
v1.2.5 - DAZ:
- minor modifications in complex datamodule
v1.2.4 - DAZ:
- minor modifications in complex datamodule
v1.2.3 - OSC + DAZ
- added a save_date_format, saving will not add the time as default, it is always possible to rewrite the save_date_format parameter
- complex datamodule: dc implemented as option in circle fit notch
v1.2.2 - DAZ:
- additional parameter for circle fit (in complex datamodule )to give additional information as string
v1.2.1 - Oscar:
- fixed error bars option in data_2d.plot
v1.2.0 - Oscar:
- changed the function save_OBJ, now a date and time will be automatically added at the begin of the file name (the option can be disabled).
- when saving it is not necessary to specify the .dm extension
- it is possible to load the data when creating a new data module
- added error bars plotting as default
- removed the functions load and save (they will be inserted in the UtilitiesLib eventually), the function save_OBJ is now renamed save
v1.1.2 - Oscar:
- added the offset option in the dm.nice_plot()
- fixed the data_3d print options to make it compatible with nice_plot()
v1.1.1
- added option to set initial fr for circle fit in dm_cplx
v1.1.0
- fixed some problem with the select function in data_2d
- modified the function pcolormesh that was not working before in data_3d
- added the functions extrapolate_x, extrapolate_y , extrapolate_min_x, extrapolate_min_y, extrapolate_max_x, exptrapolate_max_y in data_3d
- added the function copy() in each data module, that returns a copy of it
- in the library now we have nice_plot function that can be called BEFORE plotting data, it will make the plot standard and nicer
- the functions data_2d.plot and data_3d.contourf have been slightly modified
- the functions replot and nice_plot have been removed from data_2d
- added the functions to stack data along the x-axis or y-axis for data_2d and data_3d