modusa 0.4.29__py3-none-any.whl → 0.4.31__py3-none-any.whl

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.
Files changed (58) hide show
  1. modusa/__init__.py +12 -8
  2. modusa/tools/__init__.py +11 -3
  3. modusa/tools/ann_saver.py +30 -0
  4. modusa/tools/audio_recorder.py +0 -1
  5. modusa/tools/audio_stft.py +72 -0
  6. modusa/tools/youtube_downloader.py +1 -4
  7. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/METADATA +2 -2
  8. modusa-0.4.31.dist-info/RECORD +22 -0
  9. pyproject.toml +2 -2
  10. modusa/config.py +0 -18
  11. modusa/decorators.py +0 -176
  12. modusa/devtools/generate_docs_source.py +0 -92
  13. modusa/devtools/generate_template.py +0 -144
  14. modusa/devtools/list_authors.py +0 -2
  15. modusa/devtools/list_plugins.py +0 -60
  16. modusa/devtools/main.py +0 -45
  17. modusa/devtools/templates/generator.py +0 -24
  18. modusa/devtools/templates/io.py +0 -24
  19. modusa/devtools/templates/model.py +0 -47
  20. modusa/devtools/templates/plugin.py +0 -41
  21. modusa/devtools/templates/test.py +0 -10
  22. modusa/devtools/templates/tool.py +0 -24
  23. modusa/generators/__init__.py +0 -13
  24. modusa/generators/audio.py +0 -188
  25. modusa/generators/audio_waveforms.py +0 -236
  26. modusa/generators/base.py +0 -29
  27. modusa/generators/ftds.py +0 -298
  28. modusa/generators/s1d.py +0 -270
  29. modusa/generators/s2d.py +0 -300
  30. modusa/generators/s_ax.py +0 -102
  31. modusa/generators/t_ax.py +0 -64
  32. modusa/generators/tds.py +0 -267
  33. modusa/models/__init__.py +0 -14
  34. modusa/models/audio.py +0 -90
  35. modusa/models/base.py +0 -70
  36. modusa/models/data.py +0 -457
  37. modusa/models/ftds.py +0 -584
  38. modusa/models/s1d.py +0 -578
  39. modusa/models/s2d.py +0 -619
  40. modusa/models/s_ax.py +0 -448
  41. modusa/models/t_ax.py +0 -335
  42. modusa/models/tds.py +0 -465
  43. modusa/plugins/__init__.py +0 -3
  44. modusa/plugins/base.py +0 -100
  45. modusa/tools/_plotter_old.py +0 -629
  46. modusa/tools/audio_saver.py +0 -30
  47. modusa/tools/base.py +0 -43
  48. modusa/tools/math_ops.py +0 -335
  49. modusa/utils/__init__.py +0 -1
  50. modusa/utils/config.py +0 -25
  51. modusa/utils/excp.py +0 -49
  52. modusa/utils/logger.py +0 -18
  53. modusa/utils/np_func_cat.py +0 -44
  54. modusa/utils/plot.py +0 -142
  55. modusa-0.4.29.dist-info/RECORD +0 -65
  56. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/WHEEL +0 -0
  57. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/entry_points.txt +0 -0
  58. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/licenses/LICENSE.md +0 -0
modusa/models/t_ax.py DELETED
@@ -1,335 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
-
4
- from modusa import excp
5
- from modusa.decorators import immutable_property, validate_args_type
6
- from .s_ax import SAx
7
- from typing import Self, Any, Callable
8
- import numpy as np
9
-
10
- class TAx(SAx):
11
- """
12
- A Space to represent time axis.
13
-
14
- Note
15
- ----
16
- - Use :class:`~modusa.generators.t_ax.TAxGen` API to instantiate this class.
17
- - It must be uniform with a well-defined sampling rate.
18
- - You are likely to be using this axis for most of the cases.
19
- - It is numpy compatible, so you can use numpy methods directly on this class object.
20
- - Since the object of this class represents time axis, any mathematical operations on it will result in another object of :class:`~modusa.models.tds.TDS` class with `y` being the result of the operation and `t` being the axis itself.
21
-
22
- Parameters
23
- ----------
24
- n_points: int
25
- - Number of data points for the time axis.
26
- sr: float
27
- - Sampling rate.
28
- - Default: 1.0
29
- t0: float
30
- - Start timestamp.
31
- - Default: 0.0
32
- label: str
33
- - Label associated with the time axis.
34
- - Default: None => ''
35
- - e.g. (Time (sec))
36
- """
37
-
38
- #--------Meta Information----------
39
- _name = "Time Axis"
40
- _nickname = "axis" # This is to be used in repr/str methods
41
- _description = "A Space to represent time axis."
42
- _author_name = "Ankit Anand"
43
- _author_email = "ankit0.anand0@gmail.com"
44
- _created_at = "2025-07-26"
45
- #----------------------------------
46
-
47
- @validate_args_type()
48
- def __init__(self, n_points, sr=1.0, t0=0.0, label=None):
49
-
50
- # Create `t` time series array
51
- t = t0 + np.arange(n_points) / sr
52
-
53
- super().__init__(values=t, label=label) # Instantiating `SAx` class
54
-
55
- # Storing other parameters so that we can use them.
56
- self._sr = sr
57
- self._t0 = t0
58
-
59
-
60
- #-----------------------------------
61
- # Properties (User Facing)
62
- #-----------------------------------
63
-
64
- @property
65
- def values(self) -> np.ndarray:
66
- return self._values
67
-
68
- @property
69
- def label(self) -> str:
70
- return self._label
71
-
72
- @property
73
- def shape(self) -> tuple:
74
- return self.values.shape
75
-
76
- @property
77
- def ndim(self) -> int:
78
- return self.values.ndim # Should be 1
79
-
80
- @property
81
- def size(self) -> int:
82
- return self.values.size
83
-
84
- @property
85
- def sr(self) -> float:
86
- return self._sr
87
-
88
- @property
89
- def t0(self) -> float:
90
- return self._t0
91
-
92
- @property
93
- def end_time(self) -> float:
94
- return float(self.values[-1])
95
-
96
- @property
97
- def duration(self) -> float:
98
- return float(self.end_time - self.t0)
99
-
100
- def __len__(self) -> int:
101
- return len(self.values)
102
-
103
- #===================================
104
-
105
- #------------------------------------
106
- # Utility methods
107
- #------------------------------------
108
-
109
- def is_same_as(self, other) -> bool:
110
- """
111
- Compare it with another SAx object.
112
-
113
- Parameters
114
- ----------
115
- other: SAx
116
- Another object to compare with.
117
-
118
- Returns
119
- -------
120
- bool
121
- True if same ow False
122
-
123
- Note
124
- ----
125
- - We check the shape and all the values.
126
- - We are not checking the labels for now.
127
- """
128
-
129
- if other.size == 1: # Meaning it is scalar
130
- return True
131
-
132
- axis1_arr = np.asarray(self)
133
- axis2_arr = np.asarray(other)
134
-
135
- if not isinstance(axis2_arr, type(axis1_arr)):
136
- return False
137
- if axis1_arr.shape != axis2_arr.shape:
138
- return False
139
- if not np.allclose(axis1_arr, axis2_arr):
140
- return False
141
-
142
- return True
143
-
144
- def copy(self) -> Self:
145
- """
146
- Return a new copy of SAx object.
147
-
148
- Returns
149
- -------
150
- SAx
151
- A new copy of the SAx object.
152
- """
153
-
154
- return self.__class__(n_points=self.shape[0], sr=self.sr, t0=self.t0, label=self.label)
155
-
156
-
157
- def set_meta_info(self, label):
158
- """
159
- Set meta info for the axis.
160
-
161
- Parameters
162
- ----------
163
- label: str
164
- Label for the axis (e.g. "Time (sec)").
165
- Returns
166
- -------
167
- Self
168
- A new Self instance with new label.
169
-
170
- .. code-block:: python
171
-
172
- import modusa as ms
173
- x = ms.sax.linear(100, 10)
174
- print(x)
175
- x = x.set_meta_info("My Axis (unit)")
176
- print(x)
177
-
178
- # I personally prefer setting it inline
179
- x = ms.sax.linear(100, 10).set_meta_info("My Axis (unit)")
180
- print(x)
181
-
182
- """
183
-
184
- if label is None:
185
- return self
186
- else:
187
- return self.__class__(n_points=self.shape[0], sr=self.sr, t0=self.t0, label=label)
188
-
189
- def translate(self, n_samples):
190
- """
191
- Translate the time axis by `n_samples`.
192
-
193
- Note
194
- ----
195
- - `n_samples` can be both positive and negative.
196
- - You might end up getting -ve time values as we are not checking for the values rn.
197
-
198
- Parameters
199
- ----------
200
- n_samples: int
201
- - Number of samples to move the signal.
202
- - +ve => moving signal forward.
203
- - -ve => moving signal backward.
204
-
205
- Returns
206
- -------
207
- TAx
208
- Translated axis.
209
- """
210
-
211
- new_t0 = self.t0 + (n_samples / self.sr)
212
-
213
- return self.__class__(n_points=self.shape[0], sr=self.sr, t0=new_t0, label=self.label)
214
-
215
- #===================================
216
-
217
-
218
- #-------------------------------
219
- # NumPy Protocol
220
- #-------------------------------
221
- def __array__(self, dtype=None) -> np.ndarray:
222
- return np.asarray(self.values, dtype=dtype)
223
-
224
- def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
225
- """
226
- Provides operation support for the universal functions
227
- on the TAx object.
228
- """
229
- from .tds import TDS
230
- from .data import Data
231
-
232
- raw_inputs = [t.values if isinstance(t, type(self)) else t for t in inputs]
233
-
234
- # Call the actual ufunc
235
- result = getattr(ufunc, method)(*raw_inputs, **kwargs)
236
-
237
- if isinstance(result, (np.ndarray, np.generic)):
238
- y = Data(values=result, label=None)
239
- t = self
240
- return TDS(y=y, t=t, title=None)
241
- else:
242
- return result
243
-
244
- def __array_function__(self, func, types, args, kwargs):
245
- """
246
- Additional numpy function support.
247
- """
248
- from modusa.utils import np_func_cat as nfc
249
- from .data import Data
250
-
251
- if not all(issubclass(t, type(self)) for t in types):
252
- return NotImplemented
253
-
254
- # Not supporting concatenate like operations as axis any random axis can't be concatenated
255
- if func in nfc.CONCAT_FUNCS:
256
- raise NotImplementedError(f"`{func.__name__}` is not yet tested on modusa signal, please create a GitHub issue.")
257
-
258
- # Single signal input expected
259
- t = args[0]
260
- t_arr = np.asarray(t)
261
- result = func(t_arr, **kwargs)
262
-
263
- if func in nfc.REDUCTION_FUNCS:
264
- # If the number of dimensions is reduced
265
- if result.ndim == 0:
266
- return Data(values=result, label=None)
267
- else:
268
- raise RuntimeError(f"Unexpected result: `result` has more than 0 dimensions, {result.ndim}")
269
-
270
- elif func in nfc.X_NEEDS_ADJUSTMENT_FUNCS:
271
- # You must define logic for adjusting x
272
- raise NotImplementedError(f"{func.__name__} requires x-axis adjustment logic.")
273
-
274
- else:
275
- raise NotImplementedError(f"`{func.__name__}` is not yet tested on modusa signal, please create a GitHub issue.")
276
-
277
- #================================
278
-
279
-
280
- #-----------------------------------
281
- # Indexing
282
- #-----------------------------------
283
-
284
- def __getitem__(self, key) -> Self:
285
- """
286
- Defining how to index SAx instance.
287
-
288
- .. code-block:: python
289
-
290
- import modusa as ms
291
- x = ms.sax.linear(100, 10)
292
- print(x)
293
- print(x[10:20])
294
-
295
- Parameters
296
- ----------
297
- key: int | slice
298
- What can go inside the square bracket [] for indexing.
299
-
300
- Returns
301
- -------
302
- SAx:
303
- Sliced instance of the axis.
304
- """
305
- if not isinstance(key, (int, slice, tuple)):
306
- raise TypeError(f"Invalid key type {type(key)}")
307
-
308
- if isinstance(key, int):
309
- sliced_value = self.values[key]
310
- new_t0 = sliced_value
311
- return self.__class__(n_points=1, sr=self.sr, t0=new_t0, label=self.label)
312
-
313
- elif isinstance(key, slice):
314
- step = key.step or 1
315
- if step < 0:
316
- raise ValueError("Reversed slicing of time axis is not allowed.")
317
-
318
- sliced_values = self.values[key]
319
- new_n_points = len(sliced_values)
320
- new_sr = self.sr / step
321
- new_t0 = sliced_values[0]
322
-
323
- return self.__class__(n_points=new_n_points, sr=new_sr, t0=new_t0, label=self.label)
324
-
325
-
326
- def __setitem__(self, key, value):
327
- """
328
- Raises error if trying to set values
329
- of an axis.
330
-
331
- Meaningful axis are not meant to be altered.
332
- """
333
- raise TypeError("Time axis does not support item assignment.")
334
-
335
- #===============================