2022-10-31 18:16:03 +01:00
|
|
|
"""
|
|
|
|
Various utilities
|
|
|
|
"""
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
rng = np.random.default_rng()
|
|
|
|
|
|
|
|
|
|
|
|
def phasemod(phase, low=np.pi):
|
|
|
|
"""
|
|
|
|
Modulo phase such that it falls within the
|
|
|
|
interval $[-low, 2\pi - low)$.
|
|
|
|
"""
|
|
|
|
return (phase + low) % (2*np.pi) - low
|
|
|
|
|
2022-11-02 19:05:53 +01:00
|
|
|
# Alias phase_mod to phasemod
|
|
|
|
phase_mod = phasemod
|
|
|
|
|
|
|
|
def sine_fitfunc(t, amp=1, freq=1, phase=0, off=0, t_delay=0):
|
2022-10-31 18:16:03 +01:00
|
|
|
"""Simple sine wave for fitting purposes"""
|
2022-11-02 19:05:53 +01:00
|
|
|
return amp*np.cos( 2*np.pi*freq*(t-t_delay) + phase) + off
|
|
|
|
|
|
|
|
def sin_delay(f, t, phase=0):
|
|
|
|
return sine_fitfunc(t, amp=1, freq=f, phase=phase, off=1, t_delay=0)
|
2022-10-31 18:16:03 +01:00
|
|
|
|
|
|
|
def sampled_time(sample_rate=1, start=0, end=1, offset=0):
|
|
|
|
return offset + np.arange(start, end, 1/sample_rate)
|
|
|
|
|
2022-11-02 19:05:53 +01:00
|
|
|
def normalise_sine_params(params):
|
|
|
|
params[2] = phase_mod(params[2])
|
|
|
|
return params
|
|
|
|
|
2022-10-31 18:16:03 +01:00
|
|
|
def noisy_sine_sampling(time, init_params, noise_sigma=1, rng=rng):
|
|
|
|
if init_params[2] is None:
|
|
|
|
init_params[2] = phasemod(2*np.pi*rng.random())
|
|
|
|
|
|
|
|
samples = sine_fitfunc(time, *init_params)
|
|
|
|
noise = rng.normal(0, noise_sigma, size=len(samples))
|
|
|
|
|
|
|
|
return samples, noise
|
|
|
|
|
2022-11-02 19:05:53 +01:00
|
|
|
# Alias noisy_sine
|
|
|
|
noisy_sine = noisy_sine_sampling
|
|
|
|
|
|
|
|
def find_nearest(value, array, return_idx=True):
|
|
|
|
array = np.asarray(array)
|
|
|
|
idx = (np.abs(array - value)).argmin()
|
|
|
|
|
|
|
|
if return_idx:
|
|
|
|
return idx
|
|
|
|
else:
|
|
|
|
return array[idx]
|
|
|
|
|