Synchrosqueezing, wavelet transforms, and time-frequency analysis in Python

Overview

Synchrosqueezing in Python

ssqueezepy CI codecov PyPI version Codacy Badge DOI License: MIT

Synchrosqueezing is a powerful reassignment method that focuses time-frequency representations, and allows extraction of instantaneous amplitudes and frequencies. Friendly overview.

Features

  • Continuous Wavelet Transform (CWT), forward & inverse, and its Synchrosqueezing
  • Short-Time Fourier Transform (STFT), forward & inverse, and its Synchrosqueezing
  • Wavelet visualizations and testing suite
  • Generalized Morse Wavelets
  • Ridge extraction
  • Fastest wavelet transforms in Python1, beating MATLAB

1: feel free to open Issue showing otherwise

Installation

pip install ssqueezepy. Or, for latest version (most likely stable):

pip install git+https://github.com/OverLordGoldDragon/ssqueezepy

GPU & CPU acceleration

Multi-threaded execution is enabled by default (disable via os.environ['SSQ_PARALLEL'] = '0'). GPU requires CuPy >= 8.0.0 and PyTorch >= 1.8.0 installed (enable via os.environ['SSQ_GPU'] = '1'). pyfftw optionally supported for maximum CPU FFT speed. See Performance guide.

Benchmarks

Code. Transforms use padding, float32 precision (float64 supported), and output shape (300, len(x)), averaged over 10 runs. pyfftw not used, which'd speed 1-thread & parallel further. Benched on author's i7-7700HQ, GTX 1070.

len(x)-transform 1-thread CPU parallel gpu pywavelets scipy librosa
10k-cwt 0.126 0.0462 0.00393 3.58 0.523 -
10k-stft 0.108 0.0385 0.00534 - 0.118 0.0909
10k-ssq_cwt 0.372 0.148 0.00941 - - -
10k-ssq_stft 0.282 0.147 0.0278 - - -
160k-cwt 2.99 1.25 0.0367 12.7 10.7 -
160k-stft 1.66 0.418 0.0643 - 1.93 1.38
160k-ssq_cwt 8.38 3.16 0.0856 - - -
160k-ssq_stft 4.65 2.48 0.159 - - -

Examples

1. Signal recovery under severe noise

image

2. Medical: EEG

3. Testing suite: CWT vs STFT, reflect-added parallel linear chirp

4. Ridge extraction: cubic polynom. F.M. + pure tone; noiseless & 1.69dB SNR

More

5. Testing suite: GMW vs Morlet, reflect-added hyperbolic chirp (extreme time-loc.)

6. Higher-order GMW CWT, reflect-added parallel linear chirp, 3.06dB SNR

More examples

Introspection

ssqueezepy is equipped with a visualization toolkit, useful for exploring wavelet behavior across scales and configurations. (Also see explanations and code)


Minimal example

import numpy as np
import matplotlib.pyplot as plt
from ssqueezepy import ssq_cwt, ssq_stft

def viz(x, Tx, Wx):
    plt.imshow(np.abs(Wx), aspect='auto', cmap='turbo')
    plt.show()
    plt.imshow(np.abs(Tx), aspect='auto', vmin=0, vmax=.2, cmap='turbo')
    plt.show()

#%%# Define signal ####################################
N = 2048
t = np.linspace(0, 10, N, endpoint=False)
xo = np.cos(2 * np.pi * 2 * (np.exp(t / 2.2) - 1))
xo += xo[::-1]  # add self reflected
x = xo + np.sqrt(2) * np.random.randn(N)  # add noise

plt.plot(xo); plt.show()
plt.plot(x);  plt.show()

#%%# CWT + SSQ CWT ####################################
Twxo, Wxo, *_ = ssq_cwt(xo)
viz(xo, Twxo, Wxo)

Twx, Wx, *_ = ssq_cwt(x)
viz(x, Twx, Wx)

#%%# STFT + SSQ STFT ##################################
Tsxo, Sxo, *_ = ssq_stft(xo)
viz(xo, np.flipud(Tsxo), np.flipud(Sxo))

Tsx, Sx, *_ = ssq_stft(x)
viz(x, np.flipud(Tsx), np.flipud(Sx))

Also see ridge extraction README.

Learning resources

  1. Continuous Wavelet Transform, & vs STFT
  2. Synchrosqueezing's phase transform, intuitively
  3. Wavelet time & frequency resolution visuals
  4. Why oscillations in SSQ of mixed sines? Separability visuals
  5. Zero-padding's effect on spectrum

DSP fundamentals: I recommend starting with 3b1b's Fourier Transform, then proceeding with DSP Guide chapters 7-11. The Discrete Fourier Transform lays the foundation of signal processing with real data. Deeper on DFT coefficients here, also 3b1b.

Contributors (noteworthy)

  • David Bondesson: ridge extraction (ridge_extraction.py; examples/: extracting_ridges.py, ridge_extraction/README.md)

How to cite

Short form:

OverLordGoldDragon, ssqueezepy, 2020. GitHub repository, https://github.com/OverLordGoldDragon/ssqueezepy/. DOI: 10.5281/zenodo.5080514

BibTeX:

@article{OverLordGoldDragon2020ssqueezepy,
  title={ssqueezepy},
  author={OverLordGoldDragon},
  journal={GitHub. Note: https://github.com/OverLordGoldDragon/ssqueezepy/},
  year={2020},
  doi={10.5281/zenodo.5080514},
}

References

ssqueezepy was originally ported from MATLAB's Synchrosqueezing Toolbox, authored by E. Brevdo and G. Thakur [1]. Synchrosqueezed Wavelet Transform was introduced by I. Daubechies and S. Maes [2], which was followed-up in [3], and adapted to STFT in [4]. Many implementation details draw from [5]. Ridge extraction based on [6].

  1. G. Thakur, E. Brevdo, N.-S. Fučkar, and H.-T. Wu. "The Synchrosqueezing algorithm for time-varying spectral analysis: robustness properties and new paleoclimate applications", Signal Processing 93:1079-1094, 2013.
  2. I. Daubechies, S. Maes. "A Nonlinear squeezing of the Continuous Wavelet Transform Based on Auditory Nerve Models".
  3. I. Daubechies, J. Lu, H.T. Wu. "Synchrosqueezed Wavelet Transforms: a Tool for Empirical Mode Decomposition", Applied and Computational Harmonic Analysis 30(2):243-261, 2011.
  4. G. Thakur, H.T. Wu. "Synchrosqueezing-based Recovery of Instantaneous Frequency from Nonuniform Samples", SIAM Journal on Mathematical Analysis, 43(5):2078-2095, 2011.
  5. Mallat, S. "Wavelet Tour of Signal Processing 3rd ed".
  6. D. Iatsenko, P. V. E. McClintock, A. Stefanovska. "On the extraction of instantaneous frequencies from ridges in time-frequency representations of signals".

License

ssqueezepy is MIT licensed, as found in the LICENSE file. Some source functions may be under other authorship/licenses; see NOTICE.txt.

Comments
  • Added time-frequency ridge extraction

    Added time-frequency ridge extraction

    Added folder/files:

    ssqueezepy/ridge_extraction.py test/ridge_extract_test.py test/ridge_extract_readme -->imgs test/ridge_extract_readme -->Readme

    enhancement 
    opened by DavidBondesson 17
  • Pick a license?

    Pick a license?

    Regarding:

    Licensing; unsure how to proceed here; original's says to "Redistributions in binary form must reproduce the above copyright notice" - but I'm not "redistributing" it, I'm distributing my rewriting of it

    The original code is published under a 2-clause BSD, so basically you are free to chose your license. It would be great if you can pick one, because code without a license on GitHub is a gray area (impossible to use / contribute) -- ideally something similar like BSD/MIT/Apache :wink:

    opened by bluenote10 13
  • GPU performance questions, `maprange`

    GPU performance questions, `maprange`

    Hi, it's me again

    Wanted to know if there is some example of maprange around so I can do some quick tests and study it from there ?

    On my tests, I have observed that if a sudden peak of energy while on a window, is much higher than the already "detected" clusters of energy, the first clusters detected of lower energy are marginalized, in the sense that they become dark ( they lose the color they had )

    What is a practical way, if there is any, to tune the scales so this effect does not happen or at least it's less obvious ?

    Thank you very much for this wonderful library

    question 
    opened by chromafunk 12
  • Oscillations in overtones

    Oscillations in overtones

    I have no idea if this is expected behavior in a SST, but at least to me it was a surprise. I noticed this at first when analyzing raw audio material, which revealed oscillations in overtones much more than what my hear would tell. But it is also possible to reproduce the effect synthetically:

    The following example shows a mix of sine waves with frequencies i * f_base. In each plot one more frequency is added; the left side shows the transform of the mix, the right side is the transform of only the last/added harmonic (just as a check how its transform looks in isolation):

    overtones_1 overtones_2 overtones_3 overtones_4 overtones_5 overtones_6 overtones_7 overtones_8

    Full reproduction code
    import numpy as np
    import matplotlib.pyplot as plt
    
    from ssqueezepy import synsq_cwt_fwd
    
    SAMPLE_RATE = 44100
    
    
    def sine(freq, num_samples, amp=1.0):
        ts = np.arange(num_samples) / SAMPLE_RATE
        wave = amp * np.sin(2.0 * np.pi * freq * ts)
        return wave
    
    
    def mix(*waves):
        return np.array(waves).sum(axis=0) / len(waves)
    
    
    def plot(Tx, ax):
        xs = np.arange(Tx.shape[1] + 1)
        ys = np.arange(Tx.shape[0] + 1)
        img = ax.pcolormesh(xs, ys, np.abs(Tx))
        plt.colorbar(img, ax=ax)
    
    
    def plot_overtone_series(num_overtones, freq=440.0, num_samples=SAMPLE_RATE // 4):
        waves = [
            sine(freq * i, num_samples)
            for i in range(1, num_overtones + 1)
        ]
    
        Tx_mix, *_ = synsq_cwt_fwd(mix(*waves), fs=1.0, nv=32)
        Tx_add, *_ = synsq_cwt_fwd(waves[-1], fs=1.0, nv=32)
    
        fig, axes = plt.subplots(1, 2, figsize=(18, 8))
        plot(Tx_mix, axes[0])
        plot(Tx_add, axes[1])
        fig.tight_layout()
        plt.savefig("/tmp/overtones_{}".format(num_overtones))
        plt.show()
    
    
    if __name__ == "__main__":
        for i in range(1, 9):
            plot_overtone_series(i)
    

    Observations:

    • Even though the sine waves have a constant instantaneous frequency, the SST plot shows relatively large oscillations -- each time in the highest harmonic. For instance here is a zoomed in version of the n = 4 case:

      image

      If I understand it correctly there are 32 "voices" per octave. The oscillation covers ~10 bins, which in musical terms would correspond to more than 3 semitones -- which seems a lot for a constant frequency signal.

    • The highest harmonic seems to cover up the harmonics in between. Perhaps this oscillation in the highest harmonic is actually an reassignment artifact of "stealing" energy from the lower harmonics?

    question 
    opened by bluenote10 12
  • Optionally output frequencies rather than scales (or provide a function to convert)

    Optionally output frequencies rather than scales (or provide a function to convert)

    In the Matlab cwt documentation, it gives this useful example (emphasis added by me):

    [wt,f] = cwt(___,fs) specifies the sampling frequency, fs, in Hz as a positive scalar. cwt uses fs to determine the scale-to-frequency conversions and returns the frequencies f in Hz. If you do not specify a sampling frequency, cwt returns f in cycles per sample. If the input x is complex, the scale-to-frequency conversions apply to both pages of wt. If x is a timetable, you cannot specify fs. fs is determined from the RowTimes of the timetable.

    In this example, if you provide the sampling frequency, then the frequencies are returned. It would be really useful if ssqueezepy could do this too (or at least provide a scale2frequency function to do the required conversion with the specified wavelet).

    opened by abudden 11
  • STFT: streaming peformance, output shapes

    STFT: streaming peformance, output shapes

    Hi, for my project https://github.com/falseywinchnet/streamcleaner I have previously been using the librosa stft. However, after i was able to make the ssqueezepy stft behave similar to it by appending 128 samples and then slicing all but the last 127 from the istft output, I switched over to ssqueezepy, believing that for my purposes https://github.com/librosa/librosa/issues/1279 this was an important caveat I should consider.

    However, librosa's stft only consumes ~2% CPU, and the ssqueezepy on a similar workload takes up 25%. I'm concerned this is due to my crude attempt at making the two behave similar, when doing this the STFT representation is MSE very close to librosas.

    Is there a proper way to make the stft of ssqueezepy generate a 257x376 complex representation from 48,000 samples and return 48,000 samples and perform with similar compute requirements?

    question 
    opened by falseywinchnet 8
  • Can I get 0.6.0 `ssq_cwt()` results using 0.6.1 `ssq_cwt`?

    Can I get 0.6.0 `ssq_cwt()` results using 0.6.1 `ssq_cwt`?

    I have used ssq_cwt() to get Tx on 0.6.0 version of ssqueezepy. I would like to use speed improvents of 0.6.1 and get the same Tx of 0.6.0 but using 0.6.1 version. Is it possible? How can it be done?

    Thanks in advance

    EDIT: I have reformulated the question

    opened by srvanrell 7
  • No option to specify a maximum frequency for stft, ssq_stft etc.

    No option to specify a maximum frequency for stft, ssq_stft etc.

    Currently the default for stft and ssq_stft is to return all scales up to the Nyquist frequency, but it would be helpful if there were a simple way to specify a maximum frequency or, better yet, a specific set of scales that should be queried. https://github.com/OverLordGoldDragon/ssqueezepy/blob/master/ssqueezepy/_ssq_stft.py#L241 Particularly in cases where you don't want to query everything up to the Nyquist frequency for efficiency purposes, it would be helpful to have this option.

    opened by scottfleming 7
  • ConceFT

    ConceFT

    Dear Eugene Brevdo and Gaurav Thakur,

    First of all, thank you very much for your python library ssqueezepy. it is very useful and is the first library that really implements very well the icwt in python (at least from my concern). I would like to know if It would be possible to improve the ssq_cwt method applying the ConceFT (Daubechies et al., 2016) algorithm. What is your opinion? is it worth it?

    If that were the case, what wavelet families could be applied? it could be applied an stack of synchrosqueezed scalograms generated by morlet families at different number of cycles or on the contrary morse wavelet have a clear advantage? For the STFT, what is the advantage of the orthonormal Hermite functions over the Discrete Prolate Spheroidal (Slepian) Sequences?

    Thank you very much in advance for your time and for your help

    Best Regards, Roberto Cabieces

    opened by rcabdia 6
  • 0.6.1 - can't input `ssq_freqs` into `ssq_stft`

    0.6.1 - can't input `ssq_freqs` into `ssq_stft`

    Hello,

    You may be aware of this, and I apologize if this is redundant or if I'm using the code improperly. I upgraded from ssqueezepy 0.6.0 to 0.6.1 today but am running into an issue with ssq_stft input parameter ssq_freqs. I am using a numpy ndarray of frequencies of interest, but in 0.6.1 I get the following error:

    File "/home/user/ssqtest.py", line 90, in SSQ_Tvst, Sxo, ssq_freqs, scaleS = ssq.ssq_stft(xo, ssq_freqs=fcm, fs=10, t=time)

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/_ssq_stft.py", line 112, in ssq_stft maprange='maximal', transform='stft')

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/ssqueezing.py", line 204, in ssqueeze _ssqueeze(Tx, w, Wx, dWx, *args)

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/ssqueezing.py", line 143, in _ssqueeze gamma, out=Tx, Sfs=Sfs)

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/ssqueezepy/algos.py", line 149, in ssqueeze_fast fn(*args, **params)

    TypeError: missing argument 'vmin'

    I did some poking around in algos.py and to me it looks like **params has a vlmin and dvl, rather than the vmin and dv required for the _ssq_stft function. However, if I simply change the input parameter names to match (aka vmin --> vlmin and dv --> dvl), I get the same error as above with the added errors:

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/numba/core/dispatcher.py", line 420, in _compile_for_args error_rewrite(e, 'typing')

    File "/home/user/anaconda3/envs/base/lib/python3.7/site-packages/numba/core/dispatcher.py", line 361, in error_rewrite raise e.with_traceback(None)

    TypingError: Cannot determine Numba type of <class 'numba.core.ir.UndefinedType'>

    I wasn't sure what to do with this error. Thanks!

    bug 
    opened by ARBolton96 5
  • Added setup.py

    Added setup.py

    So far the package isn't really pip installable due to lack of a setup.py. I thought I'd add something basic to get you started, including properly specifying dependencies.

    I guess few people in the Python community actually download releases from GitHub. So I guess you can safe you some time, and simply add a pip + git based installation instruction to the README like:

    pip install git+https://github.com/OverLordGoldDragon/ssqueezepy
    

    I could also help with publishing to PyPI in the long term.

    opened by bluenote10 5
  • How to use torch tensors already on GPU?

    How to use torch tensors already on GPU?

    Hi, Thanks for your wonderful work.

    Currently, only NumPy arrays are supported as input. Is there a way to use torch tensors already on the GPU?

    If not, if you give me some pointers, I can work on implementing that feature.

    Best regards Nabarun

    opened by naba89 7
  • Incorrect raising of ValueError(

    Incorrect raising of ValueError("must set `wavelet` if `scales` isn't array") line 220 cwt_utils,py

    Hi,

    I've encountered what i believe to be a bug in a call to ssqueezepy.ssqueeze to synchro-squeeze a continous wavelet transform. I'll try to explain the issue as best i can, because i can't send the exact implementation. This is also my first issue, to bear with me if i get anything wrong in the format or conventions :)

    I'm running ssqueezepy v0.6.3

    The call is of the form:

    Tx, fvec = sq.ssqueeze(
    			Mx, w=phase, ssq_freqs="log", wavelet=wavelet, scales="log", fs=sampleRate, maprange="maximal",
    			transform="cwt"
    		)
    

    where,

    wavelet = sq.Wavelet("morlet") is set before calling the method. and is of type(wavelet) = ssqueezepy.wavelets.Wavelet

    and Mx, phase are the normal matrices of the transform and phase produced by ssqueezepy.cwt()

    In 'squeezing.py/squeeze' after the call to _process_args is completed, the following if statement on line 168 calls the method process_scales if transform == 'cwt'. See below

        if transform == 'cwt':
            scales, cwt_scaletype, _, nv = process_scales(scales, N, get_params=True)
    

    However the call to process_scales does NOT pass the wavelet as an input argument (which it expects and sets to None if not passed). This results in the exception ValueError("must set `wavelet` if `scales` isn't array") being raised on line 220 in cwt_utils.pt/_process_args as called from process_scales.

    The argument wavelet passed to ssqueeze() was in fact set correctly.

    Hopefully that makes sense...

    Thanks, J.

    opened by jelsom 1
  • cc and cw in issq_cwt

    cc and cw in issq_cwt

    Suppose that we have a highly non-sinusoidal wave that is composed of multiple waves. Assuming that we know the frequency range that we are interested in, how should we define cc and cw in issq_cwt so the reconstructed signal only contains the components in he frequency range of interest. An illustrative example will be helpful.

    documentation question 
    opened by zeydabadi 3
  • `center_frequency` yields negative frequency for extreme scale

    `center_frequency` yields negative frequency for extreme scale

    The following example returns wc = -3.1354 but according to the specs it should be nonnegative, unless I'm misunderstanding something.

    from ssqueezepy import wavelets, Wavelet
    wavelet = Wavelet(("morlet", {"mu":14.0}))
    _ = wavelets.center_frequency(
        wavelet,  
        scale=np.array([1.0]),  
        kind='peak',
        N=1024,
        viz=1
    )
    
    bug 
    opened by scottfleming 1
  • Real-world tests

    Real-world tests

    Thread for sharing/discussing applications on real-world data. Feel free to open a separate Issue if needed.

    Comments occasionally cleared to keep focus on examples.

    opened by OverLordGoldDragon 7
Releases(0.6.3)
  • 0.6.3(Jan 23, 2022)

    FEATURES

    • freq_to_scale & scale_to_freq, experimental
    • Improved auto-scales
    • Optional nan_checks
    • Improved default gamma

    BREAKING

    • ssq_freqs now correctly maps frequencies to corresponding rows of Tx for ssq_cwt, no longer requiring [::-1]
    • scales returned as 1D
    • extract_ridges: ridge_f (formerly fridge) now returns scales rather than log(scales)
    • extract_ridges: renamed: fridge -> ridge_f, max_energy -> ridge_e

    FIXES

    • False warning for t & fs
    • Extended scope of astensor to scales, ssq_freqs
    • visuals: improve xticks & yticks handling

    MISC

    • Added citation; README changes; docs changes
    • experimental: remove phase_squeeze, phase_transform
    • visuals.imshow: default cmap='turbo'
    • visuals: added auto_xlims, squeeze
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1b(Jul 7, 2021)

  • 0.6.1(May 5, 2021)

  • 0.6.0(Feb 19, 2021)

    A massive update.

    FEATURES (major)

    • Generalized Morse Wavelets (gmw, morsewave in _gmw.py)
    • Automatic time-frequency ridge extraction, ridge_extraction.py
    • Signal testing suite, _test_signals.py, and examples
    • Higher-order CWT (via GMWs); _cwt.cwt_higher_order
    • configs.ini, used to control function defaults globally
    • scales default improved to not over-represent low frequencies

    FEATURES (other)

    • visuals: added wavelet_filterbank, viz_cwt_higher_order, viz_gmw_orders (first callable as wavelet.viz('filterbank'))
    • visuals.wavelet_tf: autopicks scale for scale=None to give a nice visual for any wavelet
    • ssq_cwt & ssq_stft: added arg preserve_transform to (see docstrings)
    • padsignal: 2D input support, of form (n_signals, signal_length) (i.e. will pad every row vector).
    • cwt: support for padtype=None
    • maprange: tuple of floats now supported (help(_ssq_cwt.ssq_cwt))
    • Wavelet.info() and @propertys of Wavelet revamped for generality; added @propertys: wc_ct, scalec_ct.
    • wavelets.center_frequency: added kind='peak-ct'
    • utils.find_max_scale now simpler and more effective, guaranteeing complete spectral coverage for low frequencies

    BREAKING

    • utils.py -> utils/*: common.py, cwt_utils.py, stft_utils.py
    • The default wavelet has been changed from 'morlet' to 'gmw'
    • Changed Morlet's default parameters to closely match GMW's defaults per time & frequency resolution
    • ssq_cwt(mapkind=) default change: 'maximal' to 'peak'
    • scales default change: implicit preset from 'maximal' to 'minimal' for low scales, 'maximal' for high
    • ssq_cwt return order change: Tx, ssq_freqs, Wx, scales, w to Tx, Wx, ssq_freqs, scales, w, dWx (additionally returning dWx)
    • ssq_stft return order change: Tx, ssq_freqs, Sx, Sfs, dSx, w to Tx, Sx, ssq_freqs, Sfs, w, dSx
    • ssqueezing & ssq_cwt: renamed mapkind to maprange
    • difftype: 'direct' -> 'trig'
    • _infer_scaletype -> infer_scaletype
    • _integrate_analytic -> integrate_analytic
    • find_max_scale -> find_max_scale_alt, but find_max_scale is still (but a different) function

    MISC

    • phase_cwt: takes abs(w) instead of zeroing negatives
    • wavelet in icwt and issq_cwt now defaults to the default wavelet
    • cwt: added args order, average
    • stft & ssq_stft: added t argument
    • stft default window increased frequency resolution
    • visuals.imshow(): cmap now defaults to 'jet' instead of 'bone' for abs=True
    • Added Examples to README, adjusted Minimal Example
    • NOTICE.txt: added jLab
    • setup.py: added short & long description, copyright, keywords

    FIXES

    • visuals.wavelet_heatmap: string scales now functional
    • visuals: w overreached into negative frequencies for odd N in wavelet_tf, wavelet_tf_anim, & wavelet_heatmap
    • icwt: padtype now functional

    FILE CHANGES

    • ssqueezepy/ added: _gmw.py, _test_signals.py, ridge_extraction.py, configs.ini, README.md
    • ssqueezepy/ added utils/, split utils.py into common.py, cwt_utils.py, stft_utils.py, __init__.py, & moved to utils/.
    • tests/ added: gmw_test.py, test_signals_test.py, ridge_extraction_test.py
    • examples/ added: extracting_ridges.py, scales_selection.py, ridge_extract_readme/: README.md, imgs/*
    • Created MANIFEST.in
    Source code(tar.gz)
    Source code(zip)
  • 0.5.5(Jan 14, 2021)

    FEATURES:

    • stft, istft, ssq_stft, and issq_stft implemented and validated
    • Added to utils.py: buffer, unbuffer, window_norm, window_resolution, and window_area
    • Replaced numba.njit with numba.jit(nopython=True, cache=True), accelerating recomputing

    BREAKING:

    • cwt() no longer returns x_mean
    • padsignal now only returns padded input by default; get_params=True for old behavior
    • Moved methods: phase_cwt & phase_cwt_num from ssqueezing to _ssq_cwt
    • In future release: return order of cwt and stft will be changed to have Wx, dWx and Sx, dSx, and ssq_cwt and ssq_stft to have Tx, Wx and Tx, Sx

    MISC:

    • wavelet positional argument in cwt is now a keyword argument that defaults to 'morlet'
    • Support for padsignal(padtype='wrap')
    • Added CHANGELOG.md
    • Docstring, comment cleanups
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Dec 19, 2020)

    Synchrosqueezing arrives to Python:

    • Continuous Wavelet Transform, forward & inverse, beating PyWavelets' & scipy's
    • CWT-based synchrosqueezing, forward & inverse
    • Wavelet visualizations
    • Docs/comments explaining relevant concepts
    • Several important fixes and performance optimizations relative to original MATLAB repository
    • Greater flexibility and improved edge-case handling relative to latest MATLAB implementations

    Planned for v0.6.0:

    • Short-time Fourier Transform, forward & inverse
    • STFT-based synchrosqueezing, forward & inverse
    • Generalized Morse Wavelets

    Existing users: please review code anew; too many changes to note between Prerelease 2 and v0.5.0. This changes onward, with every change explicitly tracked.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.0rc2(Nov 8, 2020)

  • 0.5.0rc(Nov 5, 2020)

    At last, SYNCRHOSQUEEZING is here.

    Relative to MATLAB repo:

    • Several important fixes
    • Possible performance improvements**
    • Formula clarity in code and comments; correct quantity placement prioritized over saving code space
    • Forward CWT and synchrosqueezing fully* fixed & validated
    • Inverse synchrosqueezing fully* fixed & validated
    • Inverse CWT and helper methods ported, partly fixed & validated
    • Added linear scale support to CWT
    • Added support for custom scales
    • Replaced opts with Pythonic argument handling

    *: not every argument config works. I tested every option, and marked in comments what fails to deliver "good" results (marked with # !!! and sometimes # TODO). Unless explicitly stating otherwise, there may be nothing to 'fix' - simply the method is flawed, or thrives in specific settings. **: I initially didn't realize the MATLAB code was jit-compiled; will run tests to compare speed & memory use.

    To-do for first release:

    • Complete docstrings
    • Add examples
    • Revamp README
    • Set license

    Note that majority of code organization is subject to change by v0.6.0. This includes args placement and defaults, variable, function, and module names, and whether wavelets are functions or class instances.


    Not reviewed/validated: synsq_stft.py, stft_transforms.py. I don't plan on reviewing these; others are welcome to, and I'll validate changes.

    Source code(tar.gz)
    Source code(zip)
  • 0.05(Oct 11, 2020)

    Nothing new, just creating tag for sharing persistent URL's.

    To any watchers, I'm actively working on the repo, and CWT should be done soon.

    Source code(tar.gz)
    Source code(zip)
Owner
John Muradeli
John Muradeli
A tool for removing PUPs using signatures

Unwanted program removal tool A tool for removing PUPs using signatures What is the unwanted program removal tool? The unwanted program removal tool i

4 Sep 20, 2022
A Guide for Feature Engineering and Feature Selection, with implementations and examples in Python.

Feature Engineering & Feature Selection A comprehensive guide [pdf] [markdown] for Feature Engineering and Feature Selection, with implementations and

Yimeng.Zhang 968 Dec 29, 2022
Animations made using manim-ce

ManimCE Animations Animations made using manim-ce The code turned out to be a bit complicated than expected.. It can be greatly simplified, will work

sparshg 17 Jan 06, 2023
Data wrangling & common calculations for results from qMem measurement software

qMem Datawrangler This script processes output of qMem measurement software into an Origin ® compatible *.csv files and matplotlib graphs to quickly v

Julian 1 Nov 30, 2021
Brython (Browser Python) is an implementation of Python 3 running in the browser

brython Brython (Browser Python) is an implementation of Python 3 running in the browser, with an interface to the DOM elements and events. Here is a

5.9k Jan 02, 2023
Flask-built web application that simulates a time and cost calculator for charging Electric Vehicles.

ev_charging_calculator Flask-built web application that simulates a time and cost calculator for charging Electric Vehicles. The project aims to simul

1 Nov 03, 2021
Chalice - A tool to facilitate Python based lambda deployment

Chalice is a tool to facilitate Python based lambda deployment. This repo contains the output of my basic exploration of this tool.

Csilla Bessenyei 1 Feb 03, 2022
RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information.

RDFLib RDFLib is a pure Python package for working with RDF. RDFLib contains most things you need to work with RDF, including: parsers and serializers

RDFLib 1.8k Jan 02, 2023
A tutorial presents several practical examples of how to build DAGs in Apache Airflow

Apache Airflow - Python Brasil 2021 Este tutorial apresenta vários exemplos práticos de como construir DAGs no Apache Airflow. Background Apache Airfl

Jusbrasil 14 Jun 03, 2022
Tools for analyzing Java JVM gc log files

gc_log This package consists of two separate utilities useful for : gc_log_visualizer.py regionsize.py GC Log Visualizer This was updated to run under

Brad Schoening 0 Jan 04, 2022
Fast Base64 encoding/decoding in Python

Fast Base64 implementation This project is a wrapper on libbase64. It aims to provide a fast base64 implementation for base64 encoding/decoding. Insta

Matthieu Darbois 96 Dec 26, 2022
ripgrep recursively searches directories for a regex pattern while respecting your gitignore

ripgrep (rg) ripgrep is a line-oriented search tool that recursively searches the current directory for a regex pattern. By default, ripgrep will resp

Andrew Gallant 35k Dec 31, 2022
36 key ergo split keyboard, designed around the Seeeduino Xiao platform

Slice36 Minimalist Split Keyboard 36 key ergo split keyboard, designed around the Seeeduino Xiao platform. Inspired by the Corne, Ferris, Ben Vallack'

54 Dec 21, 2022
A frontend to ease the use of pulseaudio's routing capabilities, mimicking voicemeeter's workflow

Pulsemeeter A frontend to ease the use of pulseaudio's routing capabilities, mimicking voicemeeter's workflow Features Create virtual inputs and outpu

Gabriel Carneiro 164 Jan 04, 2023
The Python Fuzzer that the world deserves 🐍

pip3 install frelatage Current release : 0.0.2 The Python Fuzzer that the world deserves Installation | How it works | Features | Use Frelatage | Conf

Rog3r 219 Dec 21, 2022
Python scripts to interact with Upper Deck ePack online trading card platform

This script should connect to the Upper Deck ePack API using your browser cookies and download a list of your current collection and save it as a CSV.

Adrian Kent 1 Nov 22, 2021
Telegram bot to upload media to telegra.ph

Telegraph @StarkTelegraphBot A star ⭐ from you means a lot to us ! Telegram bot to upload media to telegra.ph Usage Deploy to Heroku Tap on above butt

Stark Bots 24 Dec 29, 2022
This is the course repository for the Spring 2022 iteration of MACS 30123 "Large-Scale Computing for the Social Sciences" at the University of Chicago.

Large-Scale Computing for the Social Sciences Spring 2022 - MACS 30123/MAPS 30123/PLSC 30123 Instructor Information TA Information TA Information Cour

6 May 06, 2022
Anti VirusTotal written in Python.

How it works Most of the anti-viruses on VirusToal uses sandboxes or vms to scan and detect malicious activity. The code checks to see if the devices

cliphd 3 Dec 26, 2021
A professional version for LBS

呐 Yuki Pro~ 懒兵服御用版本,yuki小姐觉得没必要单独造一个仓库,但懒兵觉得有必要并强制执行 将na-yuki框架抽象为模块,功能拆分为独立脚本,使用脚本注释器使其作为py运行 文件结构: na_yuki_pro_example.py 是一个说明脚本,用来直观展示na,yuki! Pro

1 Dec 21, 2021