Module libquantum.synthetics
This module constructs synthetic signals
Expand source code
"""
This module constructs synthetic signals
"""
import numpy as np
import scipy.signal as signal
from scipy.integrate import cumulative_trapezoid
from typing import Optional, Tuple, Union
from libquantum import utils, scales, atoms
def gabor_tight_grain(band_order_Nth: float,
scale_frequency_center_hz: float,
frequency_sample_rate_hz: float,
index_shift: float = 0,
frequency_base_input: float = scales.Slice.G2) -> np.ndarray:
"""
Gabor grain with tight Tukey wrap to ensure zero at edges
:param band_order_Nth: Nth order of constant Q bands
:param scale_frequency_center_hz: center frequency fc in Hz
:param frequency_sample_rate_hz: sample rate of frequency in Hz
:param index_shift: index of shift
:param frequency_base_input: G2 or G3. Default is G2
:return: numpy array with Tukey grain
"""
# Fundamental chirp parameters
cycles_M, quality_factor_Q, gamma = \
atoms.chirp_MQG_from_N(band_order_Nth, index_shift, frequency_base_input)
scale_atom = atoms.chirp_scale(cycles_M, scale_frequency_center_hz, frequency_sample_rate_hz)
p_complex = atoms.chirp_p_complex(scale_atom, gamma, index_shift)
# Time from nominal duration
grain_duration_s = cycles_M/scale_frequency_center_hz
time_s = np.arange(int(np.round(grain_duration_s*frequency_sample_rate_hz)))/frequency_sample_rate_hz
offset_time_s = np.max(time_s)/2.
xtime_shifted = atoms.chirp_time(time_s, offset_time_s, frequency_sample_rate_hz)
wavelet_gauss = np.exp(-p_complex * xtime_shifted**2)
wavelet_gabor = wavelet_gauss * np.exp(1j * cycles_M*xtime_shifted/scale_atom)
tight_grain_taper = utils.taper_tukey(wavelet_gabor, 0.1)
tight_grain = np.copy(wavelet_gabor)*tight_grain_taper
return tight_grain
def tukey_tight_grain(band_order_Nth: float,
scale_frequency_center_hz: float,
frequency_sample_rate_hz: float,
fraction_cosine: float = 0.5,
index_shift: float = 0,
frequency_base_input: float = scales.Slice.G2) -> np.ndarray:
"""
Tukey grain with same support as Gabor atom
:param band_order_Nth: Nth order of constant Q bands
:param scale_frequency_center_hz: center frequency fc in Hz
:param frequency_sample_rate_hz: sample rate of frequency in Hz
:param fraction_cosine: fraction of the window inside the cosine tapered window, shared between the head and tail.
Default is 0.5
:param index_shift: index of shift
:param frequency_base_input: G2 or G3. Default is G2
:return: numpy array with Tukey grain
"""
# Fundamental chirp parameters
cycles_M, quality_factor_Q, gamma = \
atoms.chirp_MQG_from_N(band_order_Nth, index_shift, frequency_base_input)
scale_atom = atoms.chirp_scale(cycles_M, scale_frequency_center_hz, frequency_sample_rate_hz)
p_complex = atoms.chirp_p_complex(scale_atom, gamma, index_shift)
# Time from nominal duration
grain_duration_s = cycles_M/scale_frequency_center_hz
time_s = np.arange(int(np.round(grain_duration_s*frequency_sample_rate_hz)))/frequency_sample_rate_hz
offset_time_s = np.max(time_s)/2.
xtime_shifted = atoms.chirp_time(time_s, offset_time_s, frequency_sample_rate_hz)
# Pull out phase component from gaussian envelope
wavelet_gauss_phase = np.imag(-p_complex * xtime_shifted**2)
wavelet_gabor = np.exp(1j * cycles_M*xtime_shifted/scale_atom + 1j * wavelet_gauss_phase)
tight_grain_taper = utils.taper_tukey(wavelet_gabor, fraction_cosine)
tight_grain = np.copy(wavelet_gabor)*tight_grain_taper
return tight_grain
def gabor_grain_frequencies(frequency_order_input: float,
frequency_low_input: float,
frequency_high_input: float,
frequency_sample_rate_input: float,
frequency_base_input: float = scales.Slice.G2,
frequency_ref_input: float = 1.0) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
Frequencies for g-chirps
:param frequency_order_input: Nth order
:param frequency_low_input: lowest frequency of interest
:param frequency_high_input: highest frequency of interest
:param frequency_sample_rate_input: sample rate
:param frequency_base_input: G2 or G3. Default is G2
:param frequency_ref_input: reference frequency. Default is 1.0
:return: three numpy arrays with center frequency, start frequency and end frequency
"""
scale_order, scale_base, _, frequency_ref, frequency_center_algebraic, \
frequency_center, frequency_start, frequency_end = \
scales.band_frequencies_low_high(frequency_order_input, frequency_base_input,
frequency_ref_input,
frequency_low_input,
frequency_high_input,
frequency_sample_rate_input)
return frequency_center, frequency_start, frequency_end
def chirp_rdvxm_noise_16bit(duration_points: int = 2**12,
sample_rate_hz: float = 80.,
noise_std_loss_bits: float = 4.,
frequency_center_hz: Optional[float] = None):
"""
Construct chirp with linear frequency sweep, white noise added, anti-aliased filter applied
:param duration_points: number of points, length of signal. Default is 2 ** 12
:param sample_rate_hz: sample rate in Hz. Default is 80.0
:param noise_std_loss_bits: number of bits below signal standard deviation. Default is 4.0
:param frequency_center_hz: center frequency fc in Hz. Optional
:return: numpy ndarray with anti-aliased chirp with white noise
"""
duration_s = duration_points/sample_rate_hz
if frequency_center_hz:
frequency_start_hz = 0.5*frequency_center_hz
frequency_end_hz = sample_rate_hz/4.
else:
frequency_center_hz = 8./duration_s
frequency_start_hz = 0.5*frequency_center_hz
frequency_end_hz = sample_rate_hz/4.
sig_time_s = np.arange(int(duration_points))/sample_rate_hz
chirp_wf = signal.chirp(sig_time_s, frequency_start_hz, sig_time_s[-1],
frequency_end_hz, method='linear', phi=0, vertex_zero=True)
chirp_wf *= taper_tukey(chirp_wf, 0.25)
noise_wf = white_noise_fbits(sig=chirp_wf, std_bit_loss=noise_std_loss_bits)
chirp_white = chirp_wf + noise_wf
chirp_white_aa = antialias_halfNyquist(chirp_white)
chirp_white_aa.astype(np.float16)
return chirp_white_aa
def sawtooth_rdvxm_noise_16bit(duration_points: int = 2**12,
sample_rate_hz: float = 80.,
noise_std_loss_bits: float = 4.,
frequency_center_hz: Optional[float] = None) -> np.ndarray:
"""
Construct a anti-aliased sawtooth waveform with white noise
:param duration_points: number of points, length of signal. Default is 2 ** 12
:param sample_rate_hz: sample rate in Hz. Default is 80.0
:param noise_std_loss_bits: number of bits below signal standard deviation. Default is 4.0
:param frequency_center_hz: center frequency fc in Hz. Optional
:return: numpy ndarray with anti-aliased sawtooth signal with white noise
"""
duration_s = duration_points/sample_rate_hz
if frequency_center_hz:
frequency_center_angular = 2*np.pi*frequency_center_hz
else:
frequency_center_hz = 8./duration_s
frequency_center_angular = 2*np.pi*frequency_center_hz
sig_time_s = np.arange(int(duration_points))/sample_rate_hz
saw_wf = signal.sawtooth(frequency_center_angular*sig_time_s, width=0)
saw_wf *= taper_tukey(saw_wf, 0.25)
noise_wf = white_noise_fbits(sig=saw_wf, std_bit_loss=noise_std_loss_bits)
saw_white = saw_wf + noise_wf
saw_white_aa = antialias_halfNyquist(saw_white)
saw_white_aa.astype(np.float16)
return saw_white_aa
def chirp_linear_in_noise(snr_bits: float,
sample_rate_hz: float,
duration_s: float,
frequency_start_hz: float,
frequency_end_hz: float,
intro_s: Union[int, float],
outro_s: Union[int, float]) -> Tuple[np.ndarray, np.ndarray]:
"""
Construct chirp with linear frequency sweep, white noise added.
:param snr_bits: number of bits below signal standard deviation
:param sample_rate_hz: sample rate in Hz
:param duration_s: duration of chirp in seconds
:param frequency_start_hz: start frequency in Hz
:param frequency_end_hz: end frequency in Hz
:param intro_s: number of seconds before chirp
:param outro_s: number of seconds after chirp
:return: numpy ndarray with waveform, numpy ndarray with time in seconds
"""
sig_time_s = np.arange(int(sample_rate_hz*duration_s))/sample_rate_hz
chirp_wf = signal.chirp(sig_time_s, frequency_start_hz, sig_time_s[-1],
frequency_end_hz, method='linear', phi=0, vertex_zero=True)
chirp_wf *= taper_tukey(chirp_wf, 0.25)
sig_wf = np.concatenate((np.zeros(int(intro_s*sample_rate_hz)),
chirp_wf,
np.zeros(int(outro_s*sample_rate_hz))))
noise_wf = white_noise_fbits(sig=sig_wf, std_bit_loss=snr_bits)
synth_wf = sig_wf+noise_wf
synth_time_s = np.arange(len(synth_wf))/sample_rate_hz
return synth_wf, synth_time_s
def white_noise_fbits(sig: np.ndarray,
std_bit_loss: float) -> np.ndarray:
"""
Compute white noise with zero mean and standard deviation that is snr_bits below the input signal
:param sig: input signal, detrended
:param std_bit_loss: number of bits below signal standard deviation
:return: gaussian noise with zero mean
"""
sig_std = np.std(sig)
# This is in power, or variance
noise_loss = 2.**std_bit_loss
std_from_fbits = sig_std/noise_loss
# White noise, zero mean
sig_noise = np.random.normal(0, std_from_fbits, size=sig.size)
return sig_noise
def taper_tukey(sig_or_time: np.ndarray,
fraction_cosine: float) -> np.ndarray:
"""
Constructs a symmetric Tukey window with the same dimensions as a time or signal numpy array.
fraction_cosine = 0 is a rectangular window, 1 is a Hann window
:param sig_or_time: input signal or time
:param fraction_cosine: fraction of the window inside the cosine tapered window, shared between the head and tail
:return: tukey taper window amplitude
"""
number_points = np.size(sig_or_time)
amplitude = signal.windows.tukey(M=number_points, alpha=fraction_cosine, sym=True)
return amplitude
def antialias_halfNyquist(synth: np.ndarray) -> np.ndarray:
"""
Anti-aliasing filter with -3dB at 1/4 of sample rate, 1/2 of Nyquist
:param synth: array with signal data
:return: numpy array with anti-aliased signal
"""
# Anti-aliasing filter with -3dB at 1/4 of sample rate, 1/2 of Nyquist
# Signal frequencies are scaled by Nyquist
filter_order = 2
edge_high = 0.5
[b, a] = signal.butter(filter_order, edge_high, btype='lowpass')
synth_anti_aliased = signal.filtfilt(b, a, np.copy(synth))
return synth_anti_aliased
def frequency_algebraic_Nth(frequency_geometric: np.ndarray,
band_order_Nth: float) -> np.ndarray:
"""
Compute algebraic frequencies in band order
:param frequency_geometric: geometric frequencies
:param band_order_Nth: Nth order of constant Q bands
:return:
"""
frequency_algebra = frequency_geometric*(np.sqrt(1+1/(8*band_order_Nth**2)))
return frequency_algebra
def integrate_cumtrapz(timestamps_s: np.ndarray,
sensor_wf: np.ndarray,
initial_value: float = 0) -> np.ndarray:
"""
cumulative trapezoid integration using scipy.integrate.cumulative_trapezoid
:param timestamps_s: timestamps corresponding to the data in seconds
:param sensor_wf: data to integrate using cumulative trapezoid
:param initial_value: the value to add in the initial of the integrated data to match length of input (default is 0)
:return: integrated data with the same length as the input
"""
integrated_data = cumulative_trapezoid(x=timestamps_s,
y=sensor_wf,
initial=initial_value)
return integrated_data
Functions
def antialias_halfNyquist(synth: numpy.ndarray) ‑> numpy.ndarray
-
Anti-aliasing filter with -3dB at 1/4 of sample rate, 1/2 of Nyquist
:param synth: array with signal data :return: numpy array with anti-aliased signal
Expand source code
def antialias_halfNyquist(synth: np.ndarray) -> np.ndarray: """ Anti-aliasing filter with -3dB at 1/4 of sample rate, 1/2 of Nyquist :param synth: array with signal data :return: numpy array with anti-aliased signal """ # Anti-aliasing filter with -3dB at 1/4 of sample rate, 1/2 of Nyquist # Signal frequencies are scaled by Nyquist filter_order = 2 edge_high = 0.5 [b, a] = signal.butter(filter_order, edge_high, btype='lowpass') synth_anti_aliased = signal.filtfilt(b, a, np.copy(synth)) return synth_anti_aliased
def chirp_linear_in_noise(snr_bits: float, sample_rate_hz: float, duration_s: float, frequency_start_hz: float, frequency_end_hz: float, intro_s: Union[int, float], outro_s: Union[int, float]) ‑> Tuple[numpy.ndarray, numpy.ndarray]
-
Construct chirp with linear frequency sweep, white noise added.
:param snr_bits: number of bits below signal standard deviation :param sample_rate_hz: sample rate in Hz :param duration_s: duration of chirp in seconds :param frequency_start_hz: start frequency in Hz :param frequency_end_hz: end frequency in Hz :param intro_s: number of seconds before chirp :param outro_s: number of seconds after chirp :return: numpy ndarray with waveform, numpy ndarray with time in seconds
Expand source code
def chirp_linear_in_noise(snr_bits: float, sample_rate_hz: float, duration_s: float, frequency_start_hz: float, frequency_end_hz: float, intro_s: Union[int, float], outro_s: Union[int, float]) -> Tuple[np.ndarray, np.ndarray]: """ Construct chirp with linear frequency sweep, white noise added. :param snr_bits: number of bits below signal standard deviation :param sample_rate_hz: sample rate in Hz :param duration_s: duration of chirp in seconds :param frequency_start_hz: start frequency in Hz :param frequency_end_hz: end frequency in Hz :param intro_s: number of seconds before chirp :param outro_s: number of seconds after chirp :return: numpy ndarray with waveform, numpy ndarray with time in seconds """ sig_time_s = np.arange(int(sample_rate_hz*duration_s))/sample_rate_hz chirp_wf = signal.chirp(sig_time_s, frequency_start_hz, sig_time_s[-1], frequency_end_hz, method='linear', phi=0, vertex_zero=True) chirp_wf *= taper_tukey(chirp_wf, 0.25) sig_wf = np.concatenate((np.zeros(int(intro_s*sample_rate_hz)), chirp_wf, np.zeros(int(outro_s*sample_rate_hz)))) noise_wf = white_noise_fbits(sig=sig_wf, std_bit_loss=snr_bits) synth_wf = sig_wf+noise_wf synth_time_s = np.arange(len(synth_wf))/sample_rate_hz return synth_wf, synth_time_s
def chirp_rdvxm_noise_16bit(duration_points: int = 4096, sample_rate_hz: float = 80.0, noise_std_loss_bits: float = 4.0, frequency_center_hz: Union[float, NoneType] = None)
-
Construct chirp with linear frequency sweep, white noise added, anti-aliased filter applied
:param duration_points: number of points, length of signal. Default is 2 ** 12 :param sample_rate_hz: sample rate in Hz. Default is 80.0 :param noise_std_loss_bits: number of bits below signal standard deviation. Default is 4.0 :param frequency_center_hz: center frequency fc in Hz. Optional :return: numpy ndarray with anti-aliased chirp with white noise
Expand source code
def chirp_rdvxm_noise_16bit(duration_points: int = 2**12, sample_rate_hz: float = 80., noise_std_loss_bits: float = 4., frequency_center_hz: Optional[float] = None): """ Construct chirp with linear frequency sweep, white noise added, anti-aliased filter applied :param duration_points: number of points, length of signal. Default is 2 ** 12 :param sample_rate_hz: sample rate in Hz. Default is 80.0 :param noise_std_loss_bits: number of bits below signal standard deviation. Default is 4.0 :param frequency_center_hz: center frequency fc in Hz. Optional :return: numpy ndarray with anti-aliased chirp with white noise """ duration_s = duration_points/sample_rate_hz if frequency_center_hz: frequency_start_hz = 0.5*frequency_center_hz frequency_end_hz = sample_rate_hz/4. else: frequency_center_hz = 8./duration_s frequency_start_hz = 0.5*frequency_center_hz frequency_end_hz = sample_rate_hz/4. sig_time_s = np.arange(int(duration_points))/sample_rate_hz chirp_wf = signal.chirp(sig_time_s, frequency_start_hz, sig_time_s[-1], frequency_end_hz, method='linear', phi=0, vertex_zero=True) chirp_wf *= taper_tukey(chirp_wf, 0.25) noise_wf = white_noise_fbits(sig=chirp_wf, std_bit_loss=noise_std_loss_bits) chirp_white = chirp_wf + noise_wf chirp_white_aa = antialias_halfNyquist(chirp_white) chirp_white_aa.astype(np.float16) return chirp_white_aa
def frequency_algebraic_Nth(frequency_geometric: numpy.ndarray, band_order_Nth: float) ‑> numpy.ndarray
-
Compute algebraic frequencies in band order
:param frequency_geometric: geometric frequencies :param band_order_Nth: Nth order of constant Q bands :return:
Expand source code
def frequency_algebraic_Nth(frequency_geometric: np.ndarray, band_order_Nth: float) -> np.ndarray: """ Compute algebraic frequencies in band order :param frequency_geometric: geometric frequencies :param band_order_Nth: Nth order of constant Q bands :return: """ frequency_algebra = frequency_geometric*(np.sqrt(1+1/(8*band_order_Nth**2))) return frequency_algebra
def gabor_grain_frequencies(frequency_order_input: float, frequency_low_input: float, frequency_high_input: float, frequency_sample_rate_input: float, frequency_base_input: float = 2.0, frequency_ref_input: float = 1.0) ‑> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]
-
Frequencies for g-chirps
:param frequency_order_input: Nth order :param frequency_low_input: lowest frequency of interest :param frequency_high_input: highest frequency of interest :param frequency_sample_rate_input: sample rate :param frequency_base_input: G2 or G3. Default is G2 :param frequency_ref_input: reference frequency. Default is 1.0 :return: three numpy arrays with center frequency, start frequency and end frequency
Expand source code
def gabor_grain_frequencies(frequency_order_input: float, frequency_low_input: float, frequency_high_input: float, frequency_sample_rate_input: float, frequency_base_input: float = scales.Slice.G2, frequency_ref_input: float = 1.0) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: """ Frequencies for g-chirps :param frequency_order_input: Nth order :param frequency_low_input: lowest frequency of interest :param frequency_high_input: highest frequency of interest :param frequency_sample_rate_input: sample rate :param frequency_base_input: G2 or G3. Default is G2 :param frequency_ref_input: reference frequency. Default is 1.0 :return: three numpy arrays with center frequency, start frequency and end frequency """ scale_order, scale_base, _, frequency_ref, frequency_center_algebraic, \ frequency_center, frequency_start, frequency_end = \ scales.band_frequencies_low_high(frequency_order_input, frequency_base_input, frequency_ref_input, frequency_low_input, frequency_high_input, frequency_sample_rate_input) return frequency_center, frequency_start, frequency_end
def gabor_tight_grain(band_order_Nth: float, scale_frequency_center_hz: float, frequency_sample_rate_hz: float, index_shift: float = 0, frequency_base_input: float = 2.0) ‑> numpy.ndarray
-
Gabor grain with tight Tukey wrap to ensure zero at edges
:param band_order_Nth: Nth order of constant Q bands :param scale_frequency_center_hz: center frequency fc in Hz :param frequency_sample_rate_hz: sample rate of frequency in Hz :param index_shift: index of shift :param frequency_base_input: G2 or G3. Default is G2 :return: numpy array with Tukey grain
Expand source code
def gabor_tight_grain(band_order_Nth: float, scale_frequency_center_hz: float, frequency_sample_rate_hz: float, index_shift: float = 0, frequency_base_input: float = scales.Slice.G2) -> np.ndarray: """ Gabor grain with tight Tukey wrap to ensure zero at edges :param band_order_Nth: Nth order of constant Q bands :param scale_frequency_center_hz: center frequency fc in Hz :param frequency_sample_rate_hz: sample rate of frequency in Hz :param index_shift: index of shift :param frequency_base_input: G2 or G3. Default is G2 :return: numpy array with Tukey grain """ # Fundamental chirp parameters cycles_M, quality_factor_Q, gamma = \ atoms.chirp_MQG_from_N(band_order_Nth, index_shift, frequency_base_input) scale_atom = atoms.chirp_scale(cycles_M, scale_frequency_center_hz, frequency_sample_rate_hz) p_complex = atoms.chirp_p_complex(scale_atom, gamma, index_shift) # Time from nominal duration grain_duration_s = cycles_M/scale_frequency_center_hz time_s = np.arange(int(np.round(grain_duration_s*frequency_sample_rate_hz)))/frequency_sample_rate_hz offset_time_s = np.max(time_s)/2. xtime_shifted = atoms.chirp_time(time_s, offset_time_s, frequency_sample_rate_hz) wavelet_gauss = np.exp(-p_complex * xtime_shifted**2) wavelet_gabor = wavelet_gauss * np.exp(1j * cycles_M*xtime_shifted/scale_atom) tight_grain_taper = utils.taper_tukey(wavelet_gabor, 0.1) tight_grain = np.copy(wavelet_gabor)*tight_grain_taper return tight_grain
def integrate_cumtrapz(timestamps_s: numpy.ndarray, sensor_wf: numpy.ndarray, initial_value: float = 0) ‑> numpy.ndarray
-
cumulative trapezoid integration using scipy.integrate.cumulative_trapezoid
:param timestamps_s: timestamps corresponding to the data in seconds :param sensor_wf: data to integrate using cumulative trapezoid :param initial_value: the value to add in the initial of the integrated data to match length of input (default is 0) :return: integrated data with the same length as the input
Expand source code
def integrate_cumtrapz(timestamps_s: np.ndarray, sensor_wf: np.ndarray, initial_value: float = 0) -> np.ndarray: """ cumulative trapezoid integration using scipy.integrate.cumulative_trapezoid :param timestamps_s: timestamps corresponding to the data in seconds :param sensor_wf: data to integrate using cumulative trapezoid :param initial_value: the value to add in the initial of the integrated data to match length of input (default is 0) :return: integrated data with the same length as the input """ integrated_data = cumulative_trapezoid(x=timestamps_s, y=sensor_wf, initial=initial_value) return integrated_data
def sawtooth_rdvxm_noise_16bit(duration_points: int = 4096, sample_rate_hz: float = 80.0, noise_std_loss_bits: float = 4.0, frequency_center_hz: Union[float, NoneType] = None) ‑> numpy.ndarray
-
Construct a anti-aliased sawtooth waveform with white noise
:param duration_points: number of points, length of signal. Default is 2 ** 12 :param sample_rate_hz: sample rate in Hz. Default is 80.0 :param noise_std_loss_bits: number of bits below signal standard deviation. Default is 4.0 :param frequency_center_hz: center frequency fc in Hz. Optional :return: numpy ndarray with anti-aliased sawtooth signal with white noise
Expand source code
def sawtooth_rdvxm_noise_16bit(duration_points: int = 2**12, sample_rate_hz: float = 80., noise_std_loss_bits: float = 4., frequency_center_hz: Optional[float] = None) -> np.ndarray: """ Construct a anti-aliased sawtooth waveform with white noise :param duration_points: number of points, length of signal. Default is 2 ** 12 :param sample_rate_hz: sample rate in Hz. Default is 80.0 :param noise_std_loss_bits: number of bits below signal standard deviation. Default is 4.0 :param frequency_center_hz: center frequency fc in Hz. Optional :return: numpy ndarray with anti-aliased sawtooth signal with white noise """ duration_s = duration_points/sample_rate_hz if frequency_center_hz: frequency_center_angular = 2*np.pi*frequency_center_hz else: frequency_center_hz = 8./duration_s frequency_center_angular = 2*np.pi*frequency_center_hz sig_time_s = np.arange(int(duration_points))/sample_rate_hz saw_wf = signal.sawtooth(frequency_center_angular*sig_time_s, width=0) saw_wf *= taper_tukey(saw_wf, 0.25) noise_wf = white_noise_fbits(sig=saw_wf, std_bit_loss=noise_std_loss_bits) saw_white = saw_wf + noise_wf saw_white_aa = antialias_halfNyquist(saw_white) saw_white_aa.astype(np.float16) return saw_white_aa
def taper_tukey(sig_or_time: numpy.ndarray, fraction_cosine: float) ‑> numpy.ndarray
-
Constructs a symmetric Tukey window with the same dimensions as a time or signal numpy array. fraction_cosine = 0 is a rectangular window, 1 is a Hann window
:param sig_or_time: input signal or time :param fraction_cosine: fraction of the window inside the cosine tapered window, shared between the head and tail :return: tukey taper window amplitude
Expand source code
def taper_tukey(sig_or_time: np.ndarray, fraction_cosine: float) -> np.ndarray: """ Constructs a symmetric Tukey window with the same dimensions as a time or signal numpy array. fraction_cosine = 0 is a rectangular window, 1 is a Hann window :param sig_or_time: input signal or time :param fraction_cosine: fraction of the window inside the cosine tapered window, shared between the head and tail :return: tukey taper window amplitude """ number_points = np.size(sig_or_time) amplitude = signal.windows.tukey(M=number_points, alpha=fraction_cosine, sym=True) return amplitude
def tukey_tight_grain(band_order_Nth: float, scale_frequency_center_hz: float, frequency_sample_rate_hz: float, fraction_cosine: float = 0.5, index_shift: float = 0, frequency_base_input: float = 2.0) ‑> numpy.ndarray
-
Tukey grain with same support as Gabor atom
:param band_order_Nth: Nth order of constant Q bands :param scale_frequency_center_hz: center frequency fc in Hz :param frequency_sample_rate_hz: sample rate of frequency in Hz :param fraction_cosine: fraction of the window inside the cosine tapered window, shared between the head and tail. Default is 0.5 :param index_shift: index of shift :param frequency_base_input: G2 or G3. Default is G2 :return: numpy array with Tukey grain
Expand source code
def tukey_tight_grain(band_order_Nth: float, scale_frequency_center_hz: float, frequency_sample_rate_hz: float, fraction_cosine: float = 0.5, index_shift: float = 0, frequency_base_input: float = scales.Slice.G2) -> np.ndarray: """ Tukey grain with same support as Gabor atom :param band_order_Nth: Nth order of constant Q bands :param scale_frequency_center_hz: center frequency fc in Hz :param frequency_sample_rate_hz: sample rate of frequency in Hz :param fraction_cosine: fraction of the window inside the cosine tapered window, shared between the head and tail. Default is 0.5 :param index_shift: index of shift :param frequency_base_input: G2 or G3. Default is G2 :return: numpy array with Tukey grain """ # Fundamental chirp parameters cycles_M, quality_factor_Q, gamma = \ atoms.chirp_MQG_from_N(band_order_Nth, index_shift, frequency_base_input) scale_atom = atoms.chirp_scale(cycles_M, scale_frequency_center_hz, frequency_sample_rate_hz) p_complex = atoms.chirp_p_complex(scale_atom, gamma, index_shift) # Time from nominal duration grain_duration_s = cycles_M/scale_frequency_center_hz time_s = np.arange(int(np.round(grain_duration_s*frequency_sample_rate_hz)))/frequency_sample_rate_hz offset_time_s = np.max(time_s)/2. xtime_shifted = atoms.chirp_time(time_s, offset_time_s, frequency_sample_rate_hz) # Pull out phase component from gaussian envelope wavelet_gauss_phase = np.imag(-p_complex * xtime_shifted**2) wavelet_gabor = np.exp(1j * cycles_M*xtime_shifted/scale_atom + 1j * wavelet_gauss_phase) tight_grain_taper = utils.taper_tukey(wavelet_gabor, fraction_cosine) tight_grain = np.copy(wavelet_gabor)*tight_grain_taper return tight_grain
def white_noise_fbits(sig: numpy.ndarray, std_bit_loss: float) ‑> numpy.ndarray
-
Compute white noise with zero mean and standard deviation that is snr_bits below the input signal
:param sig: input signal, detrended :param std_bit_loss: number of bits below signal standard deviation :return: gaussian noise with zero mean
Expand source code
def white_noise_fbits(sig: np.ndarray, std_bit_loss: float) -> np.ndarray: """ Compute white noise with zero mean and standard deviation that is snr_bits below the input signal :param sig: input signal, detrended :param std_bit_loss: number of bits below signal standard deviation :return: gaussian noise with zero mean """ sig_std = np.std(sig) # This is in power, or variance noise_loss = 2.**std_bit_loss std_from_fbits = sig_std/noise_loss # White noise, zero mean sig_noise = np.random.normal(0, std_from_fbits, size=sig.size) return sig_noise