"""GigaAnalysis - Quantum Oscillations - :mod:`gigaanalysis.qo`
------------------------------------------------------------------
Here is a set of functions and classes that are useful for analysing
quantum oscillation data. The general form that I assume when processing
magnetic field sweeps to look for quantum oscillation are performing a
background subtraction and then Fourier transforming that inverse field.
"""
from .data import *
from . import mfunc, const
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
[docs]def lifshitz_kosevich(temps, field, e_mass, amp=1., as_Data=True):
"""The Lifshitz-Kosevich formula
This formula describes the change the the amplitude of quantum
oscillations as the temperature is changed. This is most commonly used
to calculate the effective mass of a carrier if a temperature dependence
of quantum oscillations are taken.
The equation is of the form
``r_lk = amp*chi/sinh(chi)`` where
``chi = 2*pi*pi*kb*temps*me*e_mass/(hbar*qe*field)``.
Parameters
----------
temps : numpy.ndarray
The value of temperatures to use to produce the LK curve.
field : float
The magnetic field value in Tesla of the applied field.
e_mass : float
The effective mass of the carriers in units of the electron mass.
amp : float, optional
The amplitude of the lowest temperature oscillations, the default
is unity.
as_Data : bool, optional
If the default of `True` the result is returned as a :class:`.Data`
object with the temps as the dependant variable. If false only the
LK amplitudes are returned as a :class:`numpy.ndarray`.
Returns
-------
r_lk : Data, numpy.ndarray
The amplitude of the quantum oscillations as the temperature is
changed.
"""
try:
temps = np.asarray(temps)
except:
raise TypeError(
f"temps need to be an array or be able to be broadcast to one "
f"but was of type {type(temps)}.")
where0 = temps == 0
temps[where0] = 1.
chi = 2*np.pi*np.pi*const.kb()*temps*const.me()*e_mass/(
const.hbar()*const.qe()*field)
r_lk = amp*chi/np.sinh(chi)
temps[where0] = 0.
r_lk[where0] = amp
if as_Data:
return Data(temps, r_lk)
else:
r_lk
[docs]def dingle_damping(fields, frequency, scatting, amp=1., as_Data=True):
"""The Dingle Damping term from the LK formulas
This describes how the amplitude of quantum oscillations changes with
applied field due to the scattering of electrons. The equation is of the
form
``r_d = amp*exp(-sqrt(2*pi*pi*hbar*frequency/qe)/(fields*scatting))``
Parameters
----------
fields : numpy.ndarray
The values of magnetic field to be used when calculating the
amplitude.
frequency : float
The frequency of the quantum oscillation in Tesla.
scatting : float
The scatting given by the mean free path in meters.
amp : float, optional
The amplitude at infinite field, the default is unity.
as_Data : bool, optional
If the default of `True` the result is returned as a :class:`.Data`
object with the fields as the dependant variable. If `False` only
the amplitudes are returned as a :class:`numpy.ndarray`.
Returns
-------
r_d : Data, numpy.ndarray
The amplitude of the quantum oscillations as the field is changed.
"""
try:
fields = np.asarray(fields)
except:
raise TypeError(
f"fields need to be an array or be able to be broadcast to one "
f"but was of type {type(fields)}.")
where0 = fields == 0
fields[where0] = 1.
r_d = amp*np.exp(
-np.sqrt(2*np.pi*np.pi*const.hbar()*frequency/const.qe())/
(fields*scatting))
fields[where0] = 0.
r_d[where0] = 0.
if as_Data:
return Data(fields, r_d)
else:
return r_d
[docs]def quantum_oscilation(fields, frequency, amp, phase, damping,
as_Data=True):
"""Example Quantum Oscillation
This is a simple example quantum oscillation for fitting and such like.
I say simple because the amplitude and the damping term has no frequency
or temperature dependence. This means you need to be more careful when
thinking about the units but also makes fitting easier. The equation is
of the form
``quant_osc =
amp*exp(-damping/fields)*sin(360*frequency/fields + phase)``
Parameters
----------
fields : numpy.ndarray
The fields to produce the form quantum oscillation over.
frequency : float
The frequency of the quantum oscillation in Tesla.
amp : float
The amplitude of the quantum oscillation at infinite field.
phase : float
The phase of the quantum oscillation in degrees.
damping : float
The scatting damping of the quantum oscillation in Tesla.
as_Data : bool, optional
If the default of `True` the result is returned as a :class:`.Data`
object with the fields as the dependant variable. If `False` only
the amplitudes are returned as a :class:`numpy.ndarray`.
Returns
-------
quant_osc : Data, numpy.ndarray
The amplitude of the quantum oscillations as the field is changed.
"""
try:
fields = np.asarray(fields)
except:
raise TypeError(
f"fields need to be an array or be able to be broadcast to one "
f"but was of type {type(fields)}.")
where0 = fields == 0
fields[where0] = 1.
amplitudes = amp*np.exp(-damping/fields)
wave = np.sin(np.radians(360*frequency/fields + phase))
quant_osc = amplitudes*wave
fields[where0] = 0.
quant_osc[where0] = 0.
if as_Data:
return Data(fields, quant_osc)
else:
return quant_osc
[docs]def counting_freq(start_field, end_field, number_peaks):
"""Counting quantum oscillation to obtain a frequency.
This returns the frequency of a quantum oscillation given a range
of field and the number of osscilations that occur in that range.
Performs ``n*B1*B2/(B2 - B1)``
Parameters
----------
start_field : float
The magnetic field to start the counting range.
end_field : float
The magnetic field to end the counting range.
number_peaks : float
The number of peaks in the given range.
Returns
-------
frequency : float
The frequency of the expected quantum oscillation in Tesla.
"""
return number_peaks*start_field*end_field/(end_field-start_field)
[docs]def counting_num(start_field, end_field, frequency):
"""Expected count of quantum oscillation at a given frequency.
This returns the number of quantum oscillations given a range
of field and frequency of quantum oscillations in question.
Performs ``Freq*(B2 - B1)/(B1*B2)``
Parameters
----------
start_field : float
The magnetic field to start the counting range.
end_field : float
The magnetic field to end the counting range.
frequency : float
The quantum oscillation frequency in Tesla.
Returns
-------
number : float
The number of expected peaks in this field range.
"""
return frequency*(end_field-start_field)/(start_field*end_field)
[docs]class QO():
"""Quantum Oscillation object
This takes a sweep in magnetic field and analyses the sweep to check the
presence and properties of quantum oscillations. It uses the
:class:`.Data` objects to hold the information.
This class has an arbitrary subtraction function which is used to remove
the background signal and leave the quantum oscillations. Other ready
made classes exist that have a certain subtraction function
incorporated. This class functions as their parent.
The analysis happens in 4 stages and the data is assessable at each
stage as a :class:`.Data` attribute. The first stage interpolates the
data evenly across the field window of interest. The second stage
performs the background subtraction. The third stage inverts the data in
in field. The final stage Fourier transforms the inverted signal.
Parameters
----------
data : Data
The raw data of the field sweep to look for quantum oscillations in.
min_field : float
The lowest field value of the field range to inspect.
max_field : float
The highest field value of the field range to inspect.
subtract_func : calculable
This should take one :class:`.Data` object and return one
:class:`.Data` of the same length. The input data is the
interpolated sweep, and the output should be the data after the
background has been subtracted.
step_size : float, optional
The size of field steps to interpolate. The default is 4 times the
average step size in the raw data.
fft_cut : float, optional
The maximum frequency to consider in FFT, higher frequencies are
dropped. THe default is to keep all the data.
strip_nan : bool, optional
If `True` non finite values are removed from the raw data. The
default is `False` and this will raise an error is non finite values
are in the raw data.
Attributes
----------
raw : Data
The data originally given to the class.
interp : Data
The sweep cut to the field range and interpolated.
sub : Data
The sweep after the background subtraction.
invert : Data
The subtracted sweep after inverting the field values.
fft : Data
The Fourier transform of the inverted signal.
min_field : float
The minimum field in the range in consideration.
max_field : float
The maximum field in the range in consideration.
step_size : float
The steps in field calculated in the interpolation.
"""
def __init__(self, data, min_field, max_field, subtract_func,
step_size=None, fft_cut=0, strip_nan=False):
# Set up Class
if type(data) != Data:
try:
data = Data(data)
except:
raise TypeError(
f"data was not a Data object nor could it be cast to "
f"one was of type {type(data)}")
self.raw = data
self.min_field = min_field
self.max_field = max_field
self._bg_sub_func = subtract_func
if np.min(self.raw.x) > min_field:
raise ValueError(
"max_field value to interpolate is below data")
if np.max(self.raw.x) < max_field:
raise ValueError(
"max_field value to interpolate is above data")
if strip_nan:
self.raw = self.raw.strip_nan()
else:
if not np.all(np.isfinite(self.raw.values)):
raise ValueError(
f"The data contained non finite values and strip_nan"
f"was set to False.")
if step_size is None:
self.step_size = (self.raw.max_x() - self.raw.min_x()
)/len(self.raw)/4
else:
self.step_size = step_size
self.interp = self.raw.interp_range(min_field, max_field,
self.step_size)
self.sub = subtract_func(self.interp)
self.invert = mfunc.invert_x(self.sub)
self.fft = mfunc.fft(self.invert, freq_cut=fft_cut)
def __len__(self):
return self.interp.x.size
def __repr__(self):
return (
f"Quantum Oscillation object:\n"
f"Field Range {self.min_field:.2f} T to {self.max_field:.2f} T\n"
f"Number of points {self.interp.x.size}")
[docs] def peaks(self, n_peaks=4, as_Data=False, **kwargs):
"""Finds the largest Fourier Transform peaks.
This makes use of :func:`.mfunc.get_peaks` and the ``**kwargs`` are
passed to :func:`scipy.signal.find_peaks`.
Parameters
----------
n_peaks : int, optional
The number of peaks to identify, the default is 4.
as_Data : bool, optional
If `True` the peak info is returned as a :class:`.Data` object.
The default is `False`.
Returns
-------
peak_info : numpy.ndarray
A two column numpy array with the with the location and the
amplitude of each peak.
"""
return mfunc.get_peaks(self.fft, n_peaks, as_Data=as_Data, **kwargs)
[docs] def peak_height(self, position, x_range, x_value=False):
"""Provides the hight of the highest FFT in a given range.
Makes use of the function :func:`.mfunc.peak_height`.
Parameters
----------
position : float
The central position to search for the peak.
x_range : float
The range in x to look for the peak. This is the total range so
will extend half of this from ``position``.
x_value : bool, optional
If `True` the x value and the y value is returned. The default
is `False` which only returns the y value.
Returns
-------
x_peak : float
If x_value is `True` the x position of the peak is returned.
y_peak : float
The y_value of the peak. Which is the highest y value in a given
range of the data.
"""
return mfunc.peak_height(self.fft, position, x_range,
x_value=x_value)
[docs] def FFT_again(self, n=65536, window='hann', freq_cut=0):
"""Recalculates the FFT.
After recalcuating the FFT the new FFT is returned and also the
new FFT is saved to the :attr:`fft` attribute. This makes use of
:func:`.mfunc.fft`.
Parameters
----------
n : int, optional
The number of points to make the FFT extra points will be zero
padded. The default is ``2**16 = 65536``. If the data is longer
than the value of n, n is rounded up to the next power of 2.
window : str, optional
The type of windowing function to use taken from
:func:`scipy.signal.get_window`. The default is 'hann'.
freq_cut : float, optional
The frequency to drop all the higher from. The default is 0
which means that all the frequencies are kept.
Returns
-------
fft_result : Data
A data object with the FFT frequencies in the x values and the
amplitudes in the y values.
"""
self.fft = mfunc.fft(self.invert, n=n, window=window,
freq_cut=freq_cut)
return self.fft
[docs] def to_csv(self, file_name, sep=','):
"""This saves the data contained to a .csv file.
This saves the data in a csv file. It includes the interpolated,
subtracted, inverse signals as well as the FFT. The FFT is
interpolated to be the same length as the interpolated data.
Parameters
----------
file_name : str
The name of the file to save the data to. If the file type is
not one of '.csv', '.txt', or '.dat'; then '.csv' will be
appended on to the end of the name.
sep : str, optional
The character used to the delineate between the data, the
default is ','.
"""
if file_name[-4:] not in ['.csv', '.txt', '.dat']:
file_name += '.csv'
output_data = np.concatenate([
self.interp.values,
self.sub.values,
self.invert.values,
self.fft.interp_number(len(self)).values,
], axis=1)
header_line = 'Field_Interp{0:s}Interp_Signal{0:s}' \
'Field_Sub{0:s}Sub_Signal{0:s}' \
'Inverse_Field{0:s}Inverse_Signal{0:s}' \
'FFT_freq{0:s}FFT_amp'.format(sep)
np.savetxt(file_name, output_data,
delimiter=sep, comments='',
header=header_line)
[docs]class QO_av(QO):
"""Average Quantum Oscillation Class
This class applies a similar process to a set of sweeps in a list as
the :class:`QO` class. For each sweep the background in individually
subtracted. They are then averaged to produce the FFT. The attributes
for this class are also :class:`.Data` objects and these are the average
of all the separately interpolated and subtracted sweeps.
This class is useful as the average of a collection of background
subtractions are not necessarily the same as the subtract of their
average.
One important point with this class is that the :attr:`raw` will be
the given list as opposed to the average of this list. For the average
it is best to use the :attr:`interp` attribute. The step_size if not
given will also use the smallest of the generated step sizes form the
list of raw sweeps.
Parameters
----------
data : list
A list of raw data of the field sweep in the form of a
list of :class:`.Data` objects to look for quantum oscillations in.
min_field : float
The lowest field value of the field range to inspect.
max_field : float
The highest field value of the field range to inspect.
subtract_func : calculable
This should take one :class:`.Data` object and return one
:class:`.Data` of the same length. The input data is the
interpolated sweep, and the output should be the data after the
background has been subtracted.
step_size : float, optional
The size of field steps to interpolate. The default is 4 times the
average step size in the raw data.
fft_cut : float, optional
The maximum frequency to consider in FFT, higher frequencies are
dropped. THe default is to keep all the data.
strip_nan : bool, optional
If `True` non finite values are removed from the raw data. The
default is `False` and this will raise an error is non finite values
are in the raw data.
Attributes
----------
raw : list
The list of data originally given to the class.
interp : Data
The average of the sweeps cut to the field range and interpolated.
sub : Data
The average of the sweeps after the background subtraction.
invert : Data
The average of the subtracted sweeps after inverting the field
values.
fft : Data
The Fourier transform of the inverted average signal.
min_field : float
The minimum field in the range in consideration.
max_field : float
The maximum field in the range in consideration.
step_size : float
The steps in field calculated in the interpolation.
"""
def __init__(self, data_list, min_field, max_field, subtract_func,
step_size=None, fft_cut=0, strip_nan=False):
# Set up class
if type(data_list) != list:
raise TypeError(
f"data_list was not in the form of a list. "
f"It was instead of the type {type(data_list)}.")
self.raw = []
raw_steps = []
for n, raw_sweep in enumerate(data_list):
if type(raw_sweep) != Data:
try:
self.raw.append(Data(raw_sweep))
except:
raise TypeError(
f"data in list positions {n} was not a Data object "
f"nor could it be cast to one. It was of the "
f"type {type(raw_sweep)}.")
else:
self.raw.append(raw_sweep)
if np.min(raw_sweep.x) > min_field:
raise ValueError(
f"max_field value to interpolate is below data."
f"Was was seen in data number {n}")
if np.max(raw_sweep.x) < max_field:
raise ValueError(
f"max_field value to interpolate is above data"
f"Was was seen in data number {n}")
if strip_nan:
self.raw[n] = raw_sweep.strip_nan()
else:
if not np.all(np.isfinite(raw_sweep.values)):
raise ValueError(
f"The data contained non finite values and "
f"strip_nan was set to False."
f"Was was seen in data number {n}")
if step_size is None:
raw_steps.append(
(raw_sweep.max_x() - raw_sweep.min_x()
)/len(raw_sweep)/4)
self.min_field = min_field
self.max_field = max_field
self._bg_sub_func = subtract_func
if step_size is None:
self.step_size = np.min(raw_steps)
else:
self.step_size = step_size
interp_list = []
for data in self.raw:
interp_list.append(data.interp_range(
min_field, max_field, self.step_size))
sub_list = []
for interp in interp_list:
sub_list.append(subtract_func(interp))
self.interp = mean(interp_list)
self.sub = mean(sub_list)
self.invert = mfunc.invert_x(self.sub)
self.fft = mfunc.fft(self.invert, freq_cut=fft_cut)
def __repr__(self):
return (
f"Average Quantum Oscillation object:\n"
f"Number of sweeps averaged {len(self.raw)}\n"
f"Field Range {self.min_field:.2f} T to {self.max_field:.2f} T\n"
f"Number of points {self.interp.x.size}")
[docs] def make_QO(self, raw_num,
step_size=None, fft_cut=None, strip_nan=False):
"""Make a Quantum Oscillation object form a certain sweep.
This return a new quantum oscillation object from a particular
sweep in the raw list given. This will use the same field range
and background subtraction as used in this class.
Parameters
----------
raw_num : int
The number of the sweep to pass to :class:`QO`. Like all python
lists the counting starts at 0.
step_size : float, optional
If given this will be the step size used. If not given the
step_size in the original class is used.
fft_cut : float, optional
If given this will be the FFT cut to used. If not given the
fft_cut in the original class is used. To see the full range of
frequencies set the fft_cut to 0.
strip_nan : bool, optional
This does nothing as in order to make this class there cannot be
any NaNs left in the raw data. It is included for completeness.
Returns
-------
single_QO : QO
A quantum oscillation object with the same parameters as used in
this class but only the data from one of the sweeps.
"""
if not isinstance(raw_num, (int, np.int_)):
raise TypeError(
f"raw_num needs to be a int but is of type "
f"{type(raw_num)}")
elif np.abs(raw_num) >= len(self.raw):
raise ValueError(
f"The raw_num is out of range. It was {raw_num} but there "
f"are only {len(self.raw)} sweeps in the raw data.")
if step_size is not None:
to_step = step_size
else:
to_step = self.step_size
if fft_cut is None:
fft_cut = self.fft.x[-1]
return QO(self.raw[raw_num], self.min_field, self.max_field,
self._bg_sub_func,
step_size=to_step, fft_cut=fft_cut, strip_nan=strip_nan)
[docs]class QO_loess(QO):
"""Quantum Oscillation object with LOESS subtraction
This is a example of the :class:`QO` which the subtraction using
:func:`.mfunc.loess`. The form is the same but with the initialising
function takes the arguments to define the LOESS background subtraction.
Parameters
----------
data : Data
The raw data of the field sweep to look for quantum oscillations in.
min_field : float
The lowest field value of the field range to inspect.
max_field : float
The highest field value of the field range to inspect.
loess_win : float
The length of the window in Tesla to use for the LOESS subtraction.
loess_poly : int
The order of the polynomial to use for the LOESS subtraction.
step_size : float, optional
The size of field steps to interpolate. The default is 4 times the
average step size in the raw data.
fft_cut : float, optional
The maximum frequency to consider in FFT, higher frequencies are
dropped. THe default is to keep all the data.
strip_nan : bool, optional
If `True` non finite values are removed from the raw data. The
default is `False` and this will raise an error is non finite values
are in the raw data.
Attributes
----------
:
This class has the same attributes as the :class:`QO` class but also
with the information about the LOESS subtraction.
loess_win : float
The length of the window in Tesla to use for the LOESS subtraction.
loess_poly : int
The order of the polynomial to use for the LOESS subtraction.
"""
def __init__(self, data, min_field, max_field, loess_win, loess_poly,
step_size=None, fft_cut=0, strip_nan=False):
def bg_sub(interp):
return interp - mfunc.loess(interp, loess_win, loess_poly)
QO.__init__(self, data, min_field, max_field, bg_sub,
step_size=step_size, fft_cut=fft_cut, strip_nan=strip_nan)
self.loess_win = loess_win
self.loess_poly = loess_poly
def __repr__(self):
return (
f"Quantum Oscillation object:\n"
f"LOESS Background Subtraction\n"
f"Field Range {self.min_field:.2f} T to {self.max_field:.2f} T\n"
f"Number of points {self.interp.x.size}\n"
f"LOESS window {self.loess_win:.2f} T\n"
f"LOESS polynomial {self.loess_poly}")
[docs]class QO_loess_av(QO_av):
"""Average Quantum Oscillation object with LOESS subtraction
This is a example of the :class:`QO_av` which the subtraction using
:func:`.mfunc.loess`. The form is the same but with the initialising
function takes the arguments to define the LOESS background subtraction.
Parameters
----------
data : list
A list of raw data of the field sweep in the form of a
list of :class:`.Data` objects to look for quantum oscillations in.
min_field : float
The lowest field value of the field range to inspect.
max_field : float
The highest field value of the field range to inspect.
loess_win : float
The length of the window in Tesla to use for the LOESS subtraction.
loess_poly : int
The order of the polynomial to use for the LOESS subtraction.
step_size : float, optional
The size of field steps to interpolate. The default is 4 times the
average step size in the raw data.
fft_cut : float, optional
The maximum frequency to consider in FFT, higher frequencies are
dropped. THe default is to keep all the data.
strip_nan : bool, optional
If `True` non finite values are removed from the raw data. The
default is `False` and this will raise an error is non finite values
are in the raw data.
Attributes
----------
:
This class has the same attributes as the :class:`QO` class but also
with the information about the LOESS subtraction.
loess_win : float
The length of the window in Tesla to use for the LOESS subtraction.
loess_poly : int
The order of the polynomial to use for the LOESS subtraction.
"""
def __init__(self, data_list, min_field, max_field,
loess_win, loess_poly,
step_size=None, fft_cut=0, strip_nan=False):
def bg_sub(interp):
return interp - mfunc.loess(interp, loess_win, loess_poly)
QO_av.__init__(self, data_list, min_field, max_field, bg_sub,
step_size=step_size, fft_cut=fft_cut, strip_nan=strip_nan)
self.loess_win = loess_win
self.loess_poly = loess_poly
def __repr__(self):
return (
f"Average Quantum Oscillation object:\n"
f"LOESS Background Subtraction\n"
f"Number of sweeps averaged {len(self.raw)}\n"
f"Field Range {self.min_field:.2f} T to {self.max_field:.2f} T\n"
f"Number of points {self.interp.x.size}\n"
f"LOESS window {self.loess_win:.2f} T\n"
f"LOESS polynomial {self.loess_poly}")
[docs]class QO_poly(QO):
"""Quantum Oscillation object with polynomial subtraction
This is a example of the :class:`QO` which the subtraction using
:func:`.mfunc.poly_reg`. The form is the same but with the initialising
function takes the arguments to define the polynomial background
subtraction.
Parameters
----------
data : Data
The raw data of the field sweep to look for quantum oscillations in.
min_field : float
The lowest field value of the field range to inspect.
max_field : float
The highest field value of the field range to inspect.
poly_order : int
The order of the polynomial to use for the subtraction.
step_size : float, optional
The size of field steps to interpolate. The default is 4 times the
average step size in the raw data.
fft_cut : float, optional
The maximum frequency to consider in FFT, higher frequencies are
dropped. THe default is to keep all the data.
strip_nan : bool, optional
If `True` non finite values are removed from the raw data. The
default is `False` and this will raise an error is non finite values
are in the raw data.
Attributes
----------
:
This class has the same attributes as the :class:`QO` class but also
with the information about the polynomial subtraction.
poly_order : int
The order of the polynomial to use for the subtraction.
"""
def __init__(self, data, min_field, max_field, poly_order,
step_size=None, fft_cut=0, strip_nan=False):
def bg_sub(interp):
return interp - mfunc.poly_reg(interp, poly_order)
QO.__init__(self, data, min_field, max_field, bg_sub,
step_size=step_size, fft_cut=fft_cut, strip_nan=strip_nan)
self.poly_order = poly_order
def __repr__(self):
return (
f"Quantum Oscillation object:\n"
f"Polynomial Background Subtraction\n"
f"Field Range {self.min_field:.2f} T to {self.max_field:.2f} T\n"
f"Number of points {self.interp.x.size}\n"
f"Polynomial order {self.poly_order}")
[docs]class QO_poly_av(QO_av):
"""Average Quantum Oscillation object with polynomial subtraction
This is a example of the :class:`QO_av` which the subtraction using
:func:`.mfunc.poly_reg`. The form is the same but with the initialising
function takes the arguments to define the polynomial background
subtraction.
Parameters
----------
data : list
A list of raw data of the field sweep in the form of a
list of :class:`.Data` objects to look for quantum oscillations in.
min_field : float
The lowest field value of the field range to inspect.
max_field : float
The highest field value of the field range to inspect.
poly_order : int
The order of the polynomial to use for the subtraction.
step_size : float, optional
The size of field steps to interpolate. The default is 4 times the
average step size in the raw data.
fft_cut : float, optional
The maximum frequency to consider in FFT, higher frequencies are
dropped. THe default is to keep all the data.
strip_nan : bool, optional
If `True` non finite values are removed from the raw data. The
default is `False` and this will raise an error is non finite values
are in the raw data.
Attributes
----------
:
This class has the same attributes as the :class:`QO` class but also
with the information about the polynomial subtraction.
poly_order : int
The order of the polynomial to use for the subtraction.
"""
def __init__(self, data_list, min_field, max_field,
poly_order,
step_size=None, fft_cut=0, strip_nan=False):
def bg_sub(interp):
return interp - mfunc.poly_reg(interp, poly_order)
QO_av.__init__(self, data_list, min_field, max_field, bg_sub,
step_size=step_size, fft_cut=fft_cut, strip_nan=strip_nan)
self.poly_order = poly_order
def __repr__(self):
return (
f"Average Quantum Oscillation object:\n"
f"Polynomial Background Subtraction\n"
f"Number of sweeps averaged {len(self.raw)}\n"
f"Field Range {self.min_field:.2f} T to {self.max_field:.2f} T\n"
f"Number of points {self.interp.x.size}\n"
f"Polynomial order {self.poly_order}")