Skip to content

Commit b729834

Browse files
committed
add validate continuous wavelet trasnform features + forked repo with cwt patches
1 parent df24cf0 commit b729834

6 files changed

Lines changed: 105 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ __09/07:__ 585 partialed functions, 2300 validated features
1010

1111
__11/07:__ 587 partialed functions, 2488 validated features
1212

13-
__13/07:__ 611 partialed functions, 2527 validated features
13+
__13/07:__ 613 partialed functions, 2593 validated features
1414

1515
# Feature Conversion Progress...
1616
![](https://geps.dev/progress/36)

pyhctsa/Configurations/basic.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,20 @@ Wavelet:
13451345
hctsa_name: WL_DetailCoeffs
13461346
ordered_args: ["wname", "maxlevel"]
13471347

1348+
CWT:
1349+
base_name: cwt
1350+
labels:
1351+
- wavelet
1352+
dependencies:
1353+
- pywt
1354+
- PyWavelets
1355+
configs:
1356+
- wname: ['db3', 'sym2']
1357+
maxScale: 32
1358+
zscore: True
1359+
hctsa_name: WL_cwt
1360+
ordered_args: ["wname", "maxScale"]
1361+
13481362
HypothesisTests:
13491363
HypothesisTest:
13501364
base_name: HypothesisTest

pyhctsa/Configurations/wavelet.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ Wavelet:
2727
hctsa_name: WL_DetailCoeffs
2828
ordered_args: ["wname", "maxlevel"]
2929

30+
CWT:
31+
base_name: cwt
32+
labels:
33+
- wavelet
34+
dependencies:
35+
- pywt
36+
- PyWavelets
37+
configs:
38+
- wname: ['db3', 'sym2']
39+
maxScale: 32
40+
zscore: True
41+
hctsa_name: WL_cwt
42+
ordered_args: ["wname", "maxScale"]
43+

pyhctsa/Operations/Wavelet.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,81 @@
11
import numpy as np
22
import pywt
3+
from pywt import cwt
34
from numpy.typing import ArrayLike
45
from typing import Union
6+
from ..Utilities.utils import signChange
7+
8+
def CWT(y : ArrayLike, wname : str = 'db3', maxScale : int = 32) -> dict:
9+
10+
y = np.asarray(y)
11+
N = len(y)
12+
scales = np.arange(1, maxScale+1)
13+
coeffs, _ = cwt(data=y,scales=scales,wavelet=wname)
14+
S = np.abs(coeffs * coeffs)
15+
SC = 100*S/np.sum(S)
16+
17+
# Get statistics from CWT
18+
numEntries = SC.shape[0] * SC.shape[1]
19+
# 1) Coefficients, coeffs
20+
allCoeffs = coeffs if pywt.Wavelet(wname).symmetry == 'asymmetric' else -coeffs
21+
out = {}
22+
out['meanC'] = np.mean(allCoeffs)
23+
24+
out['meanabsC'] = np.mean(abs(allCoeffs))
25+
out['medianabsC'] = np.median(abs(allCoeffs))
26+
out['maxabsC'] = np.max(abs(allCoeffs))
27+
out['maxonmeanC'] = out['maxabsC']/out['meanabsC']
28+
29+
out['maxonmeanSC'] = np.max(SC)/np.mean(SC)
30+
31+
#% Proportion of coeffs matrix over ___ maximum (thresholded)
32+
poverfn = lambda x : np.sum(SC[SC > x * np.max(SC)])/numEntries
33+
out['pover99'] = poverfn(0.99)
34+
out['pover98'] = poverfn(0.88)
35+
out['pover95'] = poverfn(0.95)
36+
out['pover90'] = poverfn(0.90)
37+
out['pover80'] = poverfn(0.80)
38+
39+
# Distribution of scaled power
40+
#shape, loc, scale = gamma.fit(SC, floc=0, method="MM")
41+
# out['gam1'] = shape
42+
# out['gam2'] = scale
43+
# 2D entropy
44+
SC_a = SC/np.sum(SC)
45+
out['SC_h'] = -np.sum(SC_a * np.log(SC_a))
46+
47+
SSC = sum(SC)
48+
out['max_ssc'] = np.max(SSC)
49+
out['min_ssc'] = np.min(SSC)
50+
out['maxonmed_ssc'] = np.max(SSC) / np.median(SSC)
51+
out['pcross_maxssc50'] = np.sum(signChange(SSC - 0.5 * np.max(SSC))) / (N - 1)
52+
out['std_ssc'] = np.std(SSC)
53+
54+
#Stationarity
55+
midpoint = N // 2 # Integer division is equivalent to floor
56+
SC_1 = SC[:, :midpoint]
57+
SC_2 = SC[:, midpoint:]
58+
59+
mean2_1 = SC_1.mean()
60+
mean2_2 = SC_2.mean()
61+
62+
std2_1 = SC_1.std(ddof=1)
63+
std2_2 = SC_2.std(ddof=1)
64+
65+
out['stat_2_m_s'] = np.mean([std2_1, std2_2]) / SC.mean()
66+
out['stat_2_s_m'] = np.std([mean2_1, mean2_2], ddof=1) / SC.std(ddof=1)
67+
out['stat_2_s_s'] = np.std([std2_1, std2_2], ddof=1) / SC.std(ddof=1)
68+
SCs = np.array_split(SC, 5, axis=1)
69+
for i in range(1, 6):
70+
out[f'mean5_{i}'] = np.mean(SCs[i-1])
71+
out[f'std5_{i}'] = np.std(SCs[i-1], ddof=1)
72+
73+
out['stat_5_m_s'] = np.mean([out['std5_1'], out['std5_2'], out['std5_3'], out['std5_4'], out['std5_5']])/np.mean(SC)
74+
out['stat_5_s_m'] = np.std([out['mean5_1'], out['mean5_2'], out['mean5_3'], out['mean5_4'], out['mean5_5']], ddof=1)/np.std(SC, ddof=1)
75+
out['stat_5_s_s'] = np.std([out['std5_1'], out['std5_2'], out['std5_3'], out['std5_4'], out['std5_5']], ddof=1)/np.std(SC, ddof=1)
76+
77+
78+
return out
579

680
def _slosr(xx) -> int:
781
# helper function for DetailCoeffs

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ dependencies = [
2121
"numba",
2222
"scikit-learn",
2323
"antropy",
24-
"PyWavelets"
24+
"PyWavelets @ git+https://github.com/joshuabmoore/pywt.git"
2525
]
2626

2727
classifiers = [
@@ -48,4 +48,3 @@ Repository = "https://github.com/author_name/project_urlname/"
4848

4949
[tool.setuptools.packages.find]
5050
exclude = ["tests*", ".github*"]
51-

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ jpype1 @ git+https://github.com/jpype-project/jpype.git@v1.5.2
77
numba
88
scikit-learn
99
antropy
10-
PyWavelets
10+
PyWavelets @ git+https://github.com/joshuabmoore/pywt.git

0 commit comments

Comments
 (0)