Move lib out of ./simulations

This commit is contained in:
Eric-Teunis de Boone 2022-06-27 16:23:19 +02:00
parent 84b3a6dca9
commit 6763bbc64c
14 changed files with 10 additions and 0 deletions

3
lib/sampling/__init__.py Normal file
View file

@ -0,0 +1,3 @@
from .sampling import *
from .sampler import *
from .digitizer import *

66
lib/sampling/digitizer.py Normal file
View file

@ -0,0 +1,66 @@
import numpy as np
from functools import wraps, partial
from . import sampling as smp
from .sampler import Sampler
class Digitizer(Sampler):
"""
Digitizer that takes in a signal and resamples and quantises the signal.
"""
def __init__(self, resolution=0.1, bias=0, sampling_frequency=None):
"""
Parameters
##########
resolution - float
Resolution of the digitizer
sampling_frequency - float
Frequency this digitizer will sample a signal
"""
super().__init__(sampling_frequency)
self.resolution = resolution
self.bias = bias
def digitise(self, signal, signal_sample_frequency=None):
"""
Digitize signal according to the specs of this digitizer.
Effectively resamples signal
"""
if callable(signal):
# if signal is already a partial,
# try to rebuild it after setting the wrapper
if isinstance(signal, partial):
rebuild_partial = True
p_args = signal.args
p_kwargs = signal.keywords
signal = signal.func
else:
rebuild_partial = False
@wraps(signal)
def wrapper(*args, **kwargs):
return smp.quantise(
self.sample(signal(*args, **kwargs), signal_sample_frequency),
self.resolution,
self.bias
)
# rebuild the partial if applicable
if rebuild_partial:
wrapper = partial(wrapper, *p_args, **p_kwargs)
return wrapper
else:
signal = np.asarray(signal)
return smp.quantise(
self.sample(signal, signal_sample_frequency),
self.resolution,
self.bias
)

29
lib/sampling/sampler.py Normal file
View file

@ -0,0 +1,29 @@
import numpy as np
from . import sampling as smp
class Sampler():
"""
A mechanism to sample signals.
"""
def __init__(self, sampling_frequency=None):
"""
Parameters
##########
sampling_frequency - float
Frequency the signals will be sampled at
"""
self.sampling_frequency = sampling_frequency
def sample(self, signal, signal_fs=None):
"""
Sample signal
"""
# Null operation
if signal_fs is None or self.sampling_frequency is None:
return signal
return smp.resample(signal, signal_fs, self.sampling_frequency)

55
lib/sampling/sampling.py Normal file
View file

@ -0,0 +1,55 @@
"""
Sampling related stuff
Such as a Sampler and Digitizer
"""
import numpy as np
def quantise(signal, resolution, bias=0):
"""
Quantise the signal with resolution
Parameters
##########
signal - arraylike
The signal to be quantised
resolution - float
Resolution for quantising the signal
bias - optional,float
Optional bias applied before quantising
"""
return np.round(signal / resolution - bias) * resolution
def resample(signal, signal_fs, sample_frequency = 1):
"""
Resample signal (sampled at signal_fs) to sample_frequency
Parameters
##########
signal - arraylike
The signal to be resampled
signal_fs - float
Sampling frequency of signal
sample_frequency - float
Wanted sampling frequency for the resampled signal
"""
scale = sample_frequency / signal_fs
return _resample(signal, scale)
def _resample(signal, scale):
"""
Quick resampling algorithm
From: https://github.com/nwhitehead/swmixer/blob/master/swmixer.py
"""
n = round( len(signal) * scale )
return np.interp(
np.linspace(0, 1, n, endpoint=False), # where to interpret
np.linspace(0, 1, len(signal), endpoint=False), # known positions
signal, # known data points
)