Source code for node_wavelets
# This file is part of Sympathy for Data.
# Copyright (c) 2018, Combine Control Systems AB
#
# SYMPATHY FOR DATA COMMERCIAL LICENSE
# You should have received a link to the License with Sympathy for Data.
import numpy as np
import pywt
from sympathy.api import node
from sympathy.api.nodeconfig import Port, Ports, Tag, Tags
wavelets = {
'ricker': 'mexh',
'morlet (real)': 'morl',
}
[docs]
class ContinuousWaveletTransform(node.Node):
"""
Continuous Wavelet Transform (CWT) is similar to
:ref:`Short Time Fourier Transform<com.sympathyfordata.timeseriesanalysis.spectral_transform>`
in that it reveals the frequency contents of a signal, and also shows how
that frequency content changes over time.
"""
name = 'Continuous wavelet transform'
author = 'Mathias Broxvall'
icon = 'fourier.svg'
description = (
'Decompose a signal into multiple different scales/frequencies and show '
'how that frequency component of the signal varies over time.'
)
nodeid = 'com.sympathyfordata.timeseriesanalysis.continous_wavelet_transform'
tags = Tags(Tag.Analysis.SignalProcessing)
related = [
'com.sympathyfordata.timeseriesanalysis.frequency_transform',
'com.sympathyfordata.timeseriesanalysis.spectral_transform',
]
parameters = node.parameters()
parameters.set_string(
'wavelet',
label='Wavelet',
value='ricker',
description='Selects wavelet to apply',
editor=node.editors.combo_editor(
options=list(wavelets.keys())))
parameters.set_integer(
'scales',
label='Number of scales',
value=32,
description='Number of scale values to generate, always start at '
'scale 1')
parameters.set_boolean(
'rescale',
label='Rescale output',
value=False,
description='Multiplies each scale output with 1/scale as a '
'normalization')
inputs = Ports([
Port.Table('time domain', name='time domain')
])
outputs = Ports([
Port.Table('wavelet domain', name='wavelet domain')
])
def execute(self, node_context):
time_tbl = node_context.input['time domain']
out_tbl = node_context.output['wavelet domain']
scales = node_context.parameters['scales'].value
rescale = node_context.parameters['rescale'].value
wavelet = wavelets[node_context.parameters['wavelet'].value]
for col in time_tbl.cols():
name = col.name
widths = np.array(range(1, scales+1))
coefs, _freqs = pywt.cwt(col.data, widths, wavelet)
for i, c in enumerate(coefs):
if rescale:
c = c / widths[i]
out_tbl[f'{name}@{i+1}'] = c