funcnodes-span 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: funcnodes-span
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary:
|
|
5
|
+
Author: Kourosh Rezaei
|
|
6
|
+
Author-email: kouroshrezaei90@gmail.com
|
|
7
|
+
Requires-Python: >=3.11,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Requires-Dist: funcnodes (>=0.2.21,<0.3.0)
|
|
12
|
+
Requires-Dist: funcnodes_numpy (>=0.1.57,<0.2.0)
|
|
13
|
+
Requires-Dist: funcnodes_pandas (>=0.1.9,<0.2.0)
|
|
14
|
+
Requires-Dist: pooch (>=1.8.2,<2.0.0)
|
|
15
|
+
Requires-Dist: scipy (>=1.14.0,<2.0.0)
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import funcnodes as fn
|
|
2
|
+
|
|
3
|
+
from .normalization import NORM_NODE_SHELF as NORM
|
|
4
|
+
# from .basics import SMOOTH_NODE_SHELF as SMOOTH
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
|
|
9
|
+
NODE_SHELF = fn.Shelf(
|
|
10
|
+
name="Spectral Analysis",
|
|
11
|
+
description="Spectral analysis for funcnodes",
|
|
12
|
+
nodes=[],
|
|
13
|
+
subshelves=[
|
|
14
|
+
NORM,
|
|
15
|
+
],
|
|
16
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from funcnodes import NodeDecorator, Shelf
|
|
2
|
+
import numpy as np
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class NormMode(Enum):
|
|
7
|
+
ZERO_ONE = "zero_one"
|
|
8
|
+
MINUS_ONE_ONE = "minus_one_one"
|
|
9
|
+
SUM_ABS = "sum_abs"
|
|
10
|
+
SUM = "sum"
|
|
11
|
+
EUCLIDEAN = "euclidean"
|
|
12
|
+
MEAN_STD = "mean_std"
|
|
13
|
+
MAX = "max"
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def default(cls) -> "NormMode":
|
|
17
|
+
"""Returns the default normalization mode."""
|
|
18
|
+
return cls.ZERO_ONE
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@NodeDecorator(id="span.basics.norm", name="Normalizations")
|
|
22
|
+
def _norm(array: np.ndarray, mode: NormMode = NormMode.default()) -> np.ndarray:
|
|
23
|
+
# """
|
|
24
|
+
# Apply different normalizations to the array.
|
|
25
|
+
|
|
26
|
+
# Args:
|
|
27
|
+
# array (np.ndarray): The input array to be normalized.
|
|
28
|
+
# mode (NormMode): The normalization mode to apply. Defaults to NormMode.ZERO_ONE.
|
|
29
|
+
|
|
30
|
+
# Returns:
|
|
31
|
+
# np.ndarray: The normalized array.
|
|
32
|
+
|
|
33
|
+
# Raises:
|
|
34
|
+
# ValueError: If an unsupported normalization mode is provided.
|
|
35
|
+
# """
|
|
36
|
+
normalization_methods = {
|
|
37
|
+
NormMode.ZERO_ONE: lambda x: (x - np.amin(x)) / (np.amax(x) - np.amin(x)),
|
|
38
|
+
NormMode.MINUS_ONE_ONE: lambda x: 2
|
|
39
|
+
* ((x - np.amin(x)) / (np.amax(x) - np.amin(x)))
|
|
40
|
+
- 1,
|
|
41
|
+
NormMode.SUM_ABS: lambda x: x / np.abs(x).sum(),
|
|
42
|
+
NormMode.SUM: lambda x: x / x.sum(),
|
|
43
|
+
NormMode.EUCLIDEAN: lambda x: x / np.sqrt((x**2).sum()),
|
|
44
|
+
NormMode.MEAN_STD: lambda x: (x - x.mean()) / x.std(),
|
|
45
|
+
NormMode.MAX: lambda x: x / x.max(),
|
|
46
|
+
}
|
|
47
|
+
if mode not in normalization_methods:
|
|
48
|
+
raise ValueError(f"Unsupported normalization mode: {mode}")
|
|
49
|
+
|
|
50
|
+
return normalization_methods[mode](array)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
NORM_NODE_SHELF = Shelf(
|
|
54
|
+
nodes=[_norm],
|
|
55
|
+
subshelves=[],
|
|
56
|
+
name="Normalization",
|
|
57
|
+
description="Normalization of the spectra",
|
|
58
|
+
)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from funcnodes import NodeDecorator, Shelf
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from scipy.signal import savgol_filter, medfilt
|
|
6
|
+
from scipy.ndimage import gaussian_filter1d
|
|
7
|
+
import warnings
|
|
8
|
+
|
|
9
|
+
warnings.filterwarnings("ignore")
|
|
10
|
+
|
|
11
|
+
class SmoothMode(Enum):
|
|
12
|
+
SAVITZKY_GOLAY = "savgol"
|
|
13
|
+
GAUSSIAN = "gaussian"
|
|
14
|
+
MOVING_AVERAGE = "ma"
|
|
15
|
+
EXPONENTIAL_MOVING_AVERAGE = "ema"
|
|
16
|
+
MEDIAN = "median"
|
|
17
|
+
|
|
18
|
+
@classmethod
|
|
19
|
+
def default(cls) -> 'SmoothMode':
|
|
20
|
+
"""Returns the default smoothing mode."""
|
|
21
|
+
return cls.SAVITZKY_GOLAY
|
|
22
|
+
|
|
23
|
+
@NodeDecorator("span.basics.smooth", name="Smoothing")
|
|
24
|
+
|
|
25
|
+
def _smooth(array: np.ndarray, mode: SmoothMode = SmoothMode.default(), window: int = 5) -> np.ndarray:
|
|
26
|
+
# """
|
|
27
|
+
# Apply different smoothing techniques to the input array.
|
|
28
|
+
|
|
29
|
+
# Args:
|
|
30
|
+
# array (np.ndarray): The input array to be smoothed.
|
|
31
|
+
# mode (SmoothMode): The smoothing mode to apply. Defaults to SmoothMode.SAVITZKY_GOLAY.
|
|
32
|
+
# window (int): The window size for the smoothing function. Defaults to 5.
|
|
33
|
+
|
|
34
|
+
# Returns:
|
|
35
|
+
# np.ndarray: The smoothed array.
|
|
36
|
+
|
|
37
|
+
# Raises:
|
|
38
|
+
# ValueError: If an unsupported smoothing mode is provided.
|
|
39
|
+
# """
|
|
40
|
+
|
|
41
|
+
def smooth_savgol(x: np.ndarray) -> np.ndarray:
|
|
42
|
+
return savgol_filter(x, window, 2)
|
|
43
|
+
|
|
44
|
+
def smooth_gaussian(x: np.ndarray) -> np.ndarray:
|
|
45
|
+
return gaussian_filter1d(x, window)
|
|
46
|
+
|
|
47
|
+
def smooth_ma(x: np.ndarray) -> np.ndarray:
|
|
48
|
+
if x.ndim > 1:
|
|
49
|
+
n, m = x.shape
|
|
50
|
+
result = np.zeros((n, m))
|
|
51
|
+
for i in range(n):
|
|
52
|
+
result[i, :] = np.convolve(x[i, :], np.ones(window) / window, mode="same")
|
|
53
|
+
return result
|
|
54
|
+
else:
|
|
55
|
+
return np.convolve(x, np.ones(window) / window, mode="same")
|
|
56
|
+
|
|
57
|
+
def smooth_ema(x: np.ndarray) -> np.ndarray:
|
|
58
|
+
if x.ndim > 1:
|
|
59
|
+
n, m = x.shape
|
|
60
|
+
result = np.zeros((n, m))
|
|
61
|
+
for i in range(n):
|
|
62
|
+
result[i, :] = pd.Series(x[i, :]).ewm(span=window).mean().values
|
|
63
|
+
return result
|
|
64
|
+
else:
|
|
65
|
+
return pd.Series(x).ewm(span=window).mean().values
|
|
66
|
+
|
|
67
|
+
def smooth_median(x: np.ndarray) -> np.ndarray:
|
|
68
|
+
return medfilt(x, window)
|
|
69
|
+
|
|
70
|
+
smoothing_methods = {
|
|
71
|
+
SmoothMode.SAVITZKY_GOLAY: smooth_savgol,
|
|
72
|
+
SmoothMode.GAUSSIAN: smooth_gaussian,
|
|
73
|
+
SmoothMode.MOVING_AVERAGE: smooth_ma,
|
|
74
|
+
SmoothMode.EXPONENTIAL_MOVING_AVERAGE: smooth_ema,
|
|
75
|
+
SmoothMode.MEDIAN: smooth_median
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if mode not in smoothing_methods:
|
|
79
|
+
raise ValueError(f"Unsupported smoothing mode: {mode}")
|
|
80
|
+
|
|
81
|
+
return smoothing_methods[mode](array)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# @NodeDecorator("span.basics.smooth.savgol", name="Savgol")
|
|
85
|
+
# def _smooth_savgol(array: np.array, window: int = 5) -> np.array:
|
|
86
|
+
# """
|
|
87
|
+
# Apply Savitzky-Golay smoothing to the input array.
|
|
88
|
+
|
|
89
|
+
# Args:
|
|
90
|
+
# window (int): Parameter passed to scipy.signal.savgol_filter function
|
|
91
|
+
|
|
92
|
+
# Returns:
|
|
93
|
+
# array_o (np.array): Smoothed array
|
|
94
|
+
# """
|
|
95
|
+
|
|
96
|
+
# array_o = savgol_filter(array, window, 2)
|
|
97
|
+
|
|
98
|
+
# return array_o
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# @NodeDecorator("span.basics.smooth.gaussian", name="Gaussian")
|
|
102
|
+
# def _smooth_gaussian(array: np.array, window: int = 5) -> np.array:
|
|
103
|
+
# """
|
|
104
|
+
# Apply Gaussians moothing to the input array.
|
|
105
|
+
|
|
106
|
+
# Args:
|
|
107
|
+
# window (int): Parameter passed to scipy.signal.savgol_filter function
|
|
108
|
+
|
|
109
|
+
# Returns:
|
|
110
|
+
# array_o (np.array): Smoothed array
|
|
111
|
+
# """
|
|
112
|
+
|
|
113
|
+
# array_o = gaussian_filter1d(array, window)
|
|
114
|
+
|
|
115
|
+
# return array_o
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# @NodeDecorator("span.basics.smooth.ma", name="Moving average")
|
|
119
|
+
# def _smooth_ma(array: np.array, window: int = 5) -> np.array:
|
|
120
|
+
# """
|
|
121
|
+
# Apply Moving Average moothing to the input array.
|
|
122
|
+
|
|
123
|
+
# Args:
|
|
124
|
+
# window (int): Parameter passed to scipy.signal.savgol_filter function
|
|
125
|
+
|
|
126
|
+
# Returns:
|
|
127
|
+
# array_o (np.array): Smoothed array
|
|
128
|
+
# """
|
|
129
|
+
|
|
130
|
+
# if array.ndim > 1:
|
|
131
|
+
# n, m = array.shape
|
|
132
|
+
# array_o = np.zeros((n, m))
|
|
133
|
+
# for i in range(n):
|
|
134
|
+
# array_o[i, :] = np.convolve(
|
|
135
|
+
# array[i, :], np.ones(window) / window, mode="same"
|
|
136
|
+
# )
|
|
137
|
+
# else:
|
|
138
|
+
# array_o = np.convolve(array, np.ones(window) / window, mode="same")
|
|
139
|
+
|
|
140
|
+
# return array_o
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# @NodeDecorator(
|
|
144
|
+
# "span.basics.smooth.ema", name="Exponential moving average"
|
|
145
|
+
# )
|
|
146
|
+
# def _smooth_ema(array: np.array, window: int = 5) -> np.array:
|
|
147
|
+
# """
|
|
148
|
+
# Apply Exponential Moving Average moothing to the input array.
|
|
149
|
+
|
|
150
|
+
# Args:
|
|
151
|
+
# window (int): Parameter passed to scipy.signal.savgol_filter function
|
|
152
|
+
|
|
153
|
+
# Returns:
|
|
154
|
+
# array_o (np.array): Smoothed array
|
|
155
|
+
# """
|
|
156
|
+
# if array.ndim > 1:
|
|
157
|
+
# n, m = array.shape
|
|
158
|
+
# array_o = np.zeros((n, m))
|
|
159
|
+
# for i in range(n):
|
|
160
|
+
# array_o[i, :] = pd.Series(array[i, :]).ewm(span=window).mean().values
|
|
161
|
+
# else:
|
|
162
|
+
# array_o = pd.Series(array).ewm(span=window).mean().values
|
|
163
|
+
|
|
164
|
+
# return array_o
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# @NodeDecorator("span.basics.smooth.median", name="Median")
|
|
168
|
+
# def _smooth_median(array: np.array, window: int = 5) -> np.array:
|
|
169
|
+
# """
|
|
170
|
+
# Apply Median smoothing to the input array.
|
|
171
|
+
|
|
172
|
+
# Args:
|
|
173
|
+
# window (int): Parameter passed to scipy.signal.savgol_filter function
|
|
174
|
+
|
|
175
|
+
# Returns:
|
|
176
|
+
# array_o (np.array): Smoothed array
|
|
177
|
+
# """
|
|
178
|
+
|
|
179
|
+
# array_o = medfilt(array, window)
|
|
180
|
+
|
|
181
|
+
# return array_o
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
SMOOTH_NODE_SHELF = Shelf(
|
|
185
|
+
nodes=[_smooth],
|
|
186
|
+
subshelves=[],
|
|
187
|
+
name="Smoothing",
|
|
188
|
+
description="Smoothing of the spectra",
|
|
189
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "funcnodes-span"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = ""
|
|
5
|
+
authors = ["Kourosh Rezaei <kouroshrezaei90@gmail.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
|
|
8
|
+
[tool.poetry.dependencies]
|
|
9
|
+
python = "^3.11"
|
|
10
|
+
scipy = "^1.14.0"
|
|
11
|
+
funcnodes = "^0.2.21"
|
|
12
|
+
funcnodes_numpy = "^0.1.57"
|
|
13
|
+
funcnodes_pandas = "^0.1.9"
|
|
14
|
+
pooch = "^1.8.2"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
[tool.poetry.group.dev.dependencies]
|
|
18
|
+
pytest = "^8.2.2"
|
|
19
|
+
|
|
20
|
+
[build-system]
|
|
21
|
+
requires = ["poetry-core"]
|
|
22
|
+
build-backend = "poetry.core.masonry.api"
|