scikit-signal is a Python module for signal processing built on top of SciPy and distributed under the 3-Clause BSD license.
For the working branch of the repository please go to: http://github.com/jaidevd/scikit-signal
A Python module for time-frequency analysis
scikit-signal is a Python module for signal processing built on top of SciPy and distributed under the 3-Clause BSD license.
For the working branch of the repository please go to: http://github.com/jaidevd/scikit-signal
Scalograms seem to render well even without the squared modulus computation
Readthedocs doesn't use the makefile, therefore the change made here 186d710 causes readthedocs to drop api generation altogether.
As of now the files have to be tracked.
These might help:
Should be able to do things like:
model.fit()
model.fit_transform()
model.transform()
where only the model (which is a BaseTFRepresentation
) changes.
Maybe add support for pipelines too.
This function was used like init, no need for it now since mostdistributions have their own classes.
The postprocessing for affine representations is common for Bertrandand D-Flandrin distributions.
Hi,
I'm not quite sure this is the right place to notify that but here I go.
I've been using the Scalogram method recently and noticed two possible improvements that can help it scale (much) better.
In affine.py, line 173 :
the conversion of self.tfr to complex type is probably not needed here, since it's already created as a complex array in base.py, line 52.
In affine.py, line 164 :
No kwargs are passed in the super method. In turn, the AffineDistribution class cannot pass such kwargs to BaseTFRepresentation. This has the consequence to set the self.tfr size to N x N ( base.py, line 38-39) with N being the length of the signal processed. This causes MemoryError for relatively small signal length.
I don't know if these are by design or not, but by modifying the files on my end I see not difference in output and significant performances improvements.
Thanks for you work,
Best,
Victor
As a benchmark, compare TFRs here with those in mne.time_frequency
(http://www.martinos.org/mne/stable/python_reference.html#time-frequency)
^ this makes the install a bit quicker, but I'm not sure if it'll handle pip deps. As an alternative, you could move those to the setup.py? Just an idea.
-Russell
Make a gallery of all plots in the examples. These plots should be entirely compatible with sphinx directives. Each script should produce exactly one plot. Add sufficient description in each plot so that each plot becomes standalone.
I'm using matplotlib 3.1.0, the current stable release. This version does not include a matplotlib.mlab.find function that can be imported. This function is still present in matplotlib 2.2.4, which is the last v2 release.
Instead of tftb.processing.postprocessing.hough_transform, use the Hough transform provided by skimage -
http://scikit-image.org/docs/dev/api/skimage.transform.html?highlight=hough#skimage.transform.hough_line
The spectra for Affine distributions need to be calculated withinterpolation, cannot just use the freqs
parameter in the Baseclass.
Note that extracting peaks with Hough transform is already supported - maybe generalization of the same for any kind of TFR should work.
By default. if timestamps of a signal are not provided, integer indices are used. When they are provided, they cannot be arbitrary timestamps since the signal is sliced using timestamps directly, as follows:
self.tfr[indices, self.ts] = self.fwindow[lh + tau] * self.signal[self.ts + tau] * \
np.conj(self.signal[self.ts - tau])
This needs to be fixed by converting the timestamp indices to intermediate integer indices, and using them to slice the signal.
Since v0.19.0, scipy supports an STFT function: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.stft.html
tftb.processing.linear.ShortTimeFourierTransform
should only be a wrapper around this.
Currently only the analyticity of the analytical QPSK signal is beingtested.
Scalograms seem to render well even without the squared modulus computation
I got two questions and truly hope someone can answer. Thank you in advance!!
1.
Considering the following has been given,
tfr[0, icol] = (g2 * xx).sum()
tf2[0, icol] = (tg2 * xx).sum()
tf3[0, icol] = dh[lh + 1] * tfr[0, icol]
Should tau starts from 1 in "for tau in range(int(taumax)):"? Or, it should be something like
for tau in range(int(taumax)):
points = np.arange(-min([lg, xrow - ti - tau]),
min([lg, ti - tau - 1]) + 1)
g2 = twindow[lg + points]
g2 = g2 / g2.sum()
tg2 = g2 * points
xx = signal[ti + tau - 1 - points] * np.conj(signal[ti - tau - 1 - points])
tfr[1+tau, icol] = (g2 * xx).sum() * fwindow[1+lh + tau]
tf2[1+tau, icol] = fwindow[1+lh + tau] * (tg2 * xx).sum()
tf3[1+tau, icol] = dh[1+lh + tau] * (g2 * xx).sum()
tfr[n_fbins - tau - 1, icol] = (g2 * np.conj(xx)).sum() * fwindow[1+lh - tau]
tf2[n_fbins - tau - 1, icol] = (tg2 * np.conj(xx)).sum() * fwindow[1+lh - tau]
tf3[n_fbins - tau - 1, icol] = dh[1+lh - tau] * (g2 * np.conj(xx)).sum()
Otherwise, tfr will be unequal to SPWVD.
for icol in range(tcol):
for jcol in range(n_fbins):
if np.abs(tfr[jcol, icol]) > threshold:
icolhat = min(max([icol - tf2[jcol, icol], 1]), tcol)
jcolhat = jcol - tf3[jcol, icol]
jcolhat = (((int(jcolhat) - 1) % n_fbins) + n_fbins) % n_fbins + 1
rtfr[jcol, icol] += tfr[jcol, icol]
tf2[jcol, icol] = jcolhat + 1j * icolhat
else:
tf2[jcol, icol] = np.inf * (1 + 1j)
rtfr[jcol, icol] += tfr[jcol, icol]
I don't think it's reassigning the result.
Should it be like following?
for icol in range(tcol):
for jcol in range(n_fbins):
if np.abs(tfr[jcol, icol]) > threshold:
icolhat = icol - np.round(np.abs(tf2[jcol, icol]))
icolhat = min([max([icolhat, 1]), tcol])
jcolhat = jcol - tf3[jcol, icol]
jcolhat = (((int(jcolhat) - 1) % n_fbins) + n_fbins) % n_fbins + 1
rtfr[int(jcolhat) - 1, int(icolhat) - 1] += tfr[jcol, icol]
tf2[jcol, icol] = jcolhat + 1j * icolhat
else:
tf2[jcol, icol] = np.inf * (1 + 1j)
rtfr[jcol, icol] += tfr[jcol, icol]
I'm new to this field, so please forgive me for asking such simple questions.
Like the MATLAB toolbox, the Python API needs to consist of:
Only the monotonicity of the instantaneous frequency law is beingtested.
Only the analyticity of the output is being tested.
The test for it is failing: https://github.com/scikit-signal/pytftb/blob/master/tftb/processing/tests/test_cohen.py#L76
It would help to do detailed profiling and performance comparison of all classes that use loops which can be vectorized.
Most distributions have a lot of common code, that can be refactored. Use a common framework to do the heavy lifting and use it everywhere.
The tftb.processing.cohen.Spectrogram
class should just be a wrapper around scipy's spectrogram.
function smoothed_pseudo_wigner_ville costs high computation compared with WignerVilleDistribution or PseudoWignerVilleDistribution, i'm wondering smoothed_pseudo_wigner_ville be rewritten based on the basic class.
Set up basic sphix documentation, write detailed docstrings with examples, which render plots wherever applicable.
Hello,
This crashes:
import tftb
import numpy as np
signal = np.zeros(13)
wvd = tftb.processing.WignerVilleDistribution(signal)
wvd.run()
and gives:
Traceback (most recent call last):
File "", line 3, in
File "/Users/[...]/opt/anaconda3/envs/tftb/lib/python3.8/site-packages/tftb/processing/cohen.py", line 165, in run
self.tfr[tausec, icol] = self.signal[icol + tausec, 0] *
IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed
but this doesn't
import tftb
import numpy as np
signal = np.zeros(12)
wvd = tftb.processing.WignerVilleDistribution(signal)
wvd.run()
Is there are reason for that?
Function parameters like time_samples
and timestamps
are used in multiple places varyingly, but they mean the same thing. Secondly, many distributions don't accept sampling frequency as an input. This needs to be clarified in all generators and processors.
I am trying to compute the Wigner Ville Distribution for short audio clips. While it works correctly with small premade signals, the situation changes for wav files. The kernel crashes due to memory error. Huge arrays are needed when a NumPy array of zeroes is initiated. I can bypass this by downsampling my signal. The most I can get is around 20000 samples. More samples and the kernel dies due to the memory error. Am I doing something wrong or is the implementation that memory hungry?
All examples containing 3D plots fail with this error:
Traceback (most recent call last):
File "/home/docs/checkouts/readthedocs.org/user_builds/pytftb/envs/latest/local/lib/python2.7/site-packages/sphinx_gallery/gen_rst.py", line 417, in execute_script
exec(code_block, example_globals)
File "<string>", line 18, in <module>
File "/home/docs/checkouts/readthedocs.org/user_builds/pytftb/envs/latest/local/lib/python2.7/site-packages/matplotlib/figure.py", line 1268, in gca
return self.add_subplot(1, 1, 1, **kwargs)
File "/home/docs/checkouts/readthedocs.org/user_builds/pytftb/envs/latest/local/lib/python2.7/site-packages/matplotlib/figure.py", line 958, in add_subplot
a = subplot_class_factory(projection_class)(self, *args, **kwargs)
File "/home/docs/checkouts/readthedocs.org/user_builds/pytftb/envs/latest/local/lib/python2.7/site-packages/matplotlib/axes/_subplots.py", line 78, in __init__
self._axes_class.__init__(self, fig, self.figbox, **kwargs)
File "/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py", line 91, in __init__
*args, **kwargs)
File "/home/docs/checkouts/readthedocs.org/user_builds/pytftb/envs/latest/local/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 436, in __init__
self.cla()
File "/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py", line 1045, in cla
Axes.cla(self)
File "/home/docs/checkouts/readthedocs.org/user_builds/pytftb/envs/latest/local/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 897, in cla
self.grid(self._gridOn, which=rcParams['axes.grid.which'])
File "/usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d/axes3d.py", line 1256, in grid
self._draw_grid = maxes._string_to_bool(b)
AttributeError: 'module' object has no attribute '_string_to_bool'
Many examples in the gallery are still processing the tfr, t, f
matrices to plot the representations, instead of using the plot
method of the respective classes.
The current implementation tftb.processing.ambiguity.wide_band
expectsuser to specify fmin
and fmax
values. It should have defaults.
Hi @jaidevd,
amazing package, thanks very much!
I might find the answer by locating in the code, but if you could answer that would speed it up:
I was wondering if it's possible to get the computed data and plot the results separately? (eg as a subplot of an other big plot...)
wvd = WignerVilleDistribution(sig)
wvd.run()
# get values from wvd
#wvd.plot(kind="contour", scale="log") # replace this with ax.plot(...)
Quite a few methods in frequency_modulated.py contain np.exp(1j *
... And I noticed this in the mfiles of the origina tftb source. Where is j
defined? Did I miss something?
A couple of example depend on the Hough transform, figure out a way to usethe skimage implementation.
Congrats for this library!
I'd like to plot the reassigned spectrogram of an audio frequency sweep (from 100hz to 20khz), available for download here as a WAV file.
from scipy.io import wavfile
from tftb.processing import *
import matplotlib.pyplot as plt
sr, x = wavfile.read('test.wav')
x = x[:1000]
s = reassigned_spectrogram(x)
plt.imshow(s[0])
plt.show()
Problem:
With a length of 1000 samples only (i.e. only 23ms), it already takes nearly one minute to compute!
So it's nearly impossible to test this reassigned spectrogram on a 10 seconds audio file.
How to improve the performance in this specific case (non-complex real audio signal)?
(Some audio editors are able to plot reassigned spectrograms quickly, such as Izotope RX, see here)
Even on the small portion of audio I tested, I couldn't get a nice plot of the reassigned spectrogram. Would you have a code example of plot of a reassigned spectrogram? Thank you in advance!
Result that I'm looking for:
Write a unified framework for plotting various distributions, replace the existing plots with this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.