phasorpy 0.6__cp312-cp312-win_arm64.whl → 0.8__cp312-cp312-win_arm64.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.
@@ -1,8 +1,8 @@
1
1
  """Select regions of interest (cursors) from phasor coordinates.
2
2
 
3
- The ``phasorpy.cursors`` module provides functions to:
3
+ The ``phasorpy.cursor`` module provides functions to:
4
4
 
5
- - create masks for regions of interests in the phasor space:
5
+ - create masks for regions of interest in the phasor space:
6
6
 
7
7
  - :py:func:`mask_from_circular_cursor`
8
8
  - :py:func:`mask_from_elliptic_cursor`
@@ -26,10 +26,7 @@ __all__ = [
26
26
  from typing import TYPE_CHECKING
27
27
 
28
28
  if TYPE_CHECKING:
29
- from ._typing import (
30
- ArrayLike,
31
- NDArray,
32
- )
29
+ from ._typing import ArrayLike, Literal, NDArray
33
30
 
34
31
  import numpy
35
32
 
@@ -80,12 +77,12 @@ def mask_from_circular_cursor(
80
77
  ------
81
78
  ValueError
82
79
  The array shapes of `real` and `imag` do not match.
83
- The array shapes of `center_*` or `radius` have more than
84
- one dimension.
80
+ The array shapes of `center_real`, `center_imag`, or `radius` have
81
+ more than one dimension.
85
82
 
86
83
  See Also
87
84
  --------
88
- :ref:`sphx_glr_tutorials_api_phasorpy_cursors.py`
85
+ :ref:`sphx_glr_tutorials_api_phasorpy_cursor.py`
89
86
 
90
87
  Examples
91
88
  --------
@@ -139,8 +136,7 @@ def mask_from_elliptic_cursor(
139
136
  *,
140
137
  radius: ArrayLike = 0.05,
141
138
  radius_minor: ArrayLike | None = None,
142
- angle: ArrayLike | None = None,
143
- align_semicircle: bool = False,
139
+ angle: ArrayLike | Literal['phase', 'semicircle'] | str | None = None,
144
140
  ) -> NDArray[numpy.bool_]:
145
141
  """Return masks for elliptic cursors of phasor coordinates.
146
142
 
@@ -159,21 +155,18 @@ def mask_from_elliptic_cursor(
159
155
  radius_minor : array_like, optional, shape (n,)
160
156
  Radii of ellipses along semi-minor axis.
161
157
  By default, the ellipses are circular.
162
- angle : array_like, optional, shape (n,)
163
- Rotation angles of semi-major axes of ellipses in radians.
164
- By default, the ellipses are automatically oriented depending on
165
- `align_semicircle`.
166
- align_semicircle : bool, optional
167
- Determines orientation of ellipses if `angle` is not provided.
168
- If true, align the minor axes of the ellipses with the closest tangent
169
- on the universal semicircle, else the unit circle (default).
158
+ angle : array_like or {'phase', 'semicircle'}, optional
159
+ Rotation angle of semi-major axis of elliptic cursors in radians.
160
+ If None or 'phase', align the minor axes of the ellipses with
161
+ the closest tangent on the unit circle.
162
+ If 'semicircle', align the ellipses with the universal semicircle.
170
163
 
171
164
  Returns
172
165
  -------
173
166
  masks : ndarray
174
167
  Boolean array of shape `(n, *real.shape)`.
175
- The first dimension is omitted if `center*`, `radius*`, and `angle`
176
- are scalars.
168
+ The first dimension is omitted if `center_real`, `center_imag`,
169
+ `radius`, `radius_minor`, and `angle` are scalars.
177
170
  Values are True if phasor coordinates are inside elliptic cursor,
178
171
  else False.
179
172
 
@@ -181,12 +174,12 @@ def mask_from_elliptic_cursor(
181
174
  ------
182
175
  ValueError
183
176
  The array shapes of `real` and `imag` do not match.
184
- The array shapes of `center*`, `radius*`, or `angle` have more than
185
- one dimension.
177
+ The array shapes of `center_real`, `center_imag`, `radius`,
178
+ `radius_minor`, or `angle` have more than one dimension.
186
179
 
187
180
  See Also
188
181
  --------
189
- :ref:`sphx_glr_tutorials_api_phasorpy_cursors.py`
182
+ :ref:`sphx_glr_tutorials_api_phasorpy_cursor.py`
190
183
 
191
184
  Examples
192
185
  --------
@@ -220,12 +213,17 @@ def mask_from_elliptic_cursor(
220
213
  angle = 0.0
221
214
  else:
222
215
  radius_b = numpy.asarray(radius_minor)
216
+
223
217
  if angle is None:
224
- # TODO: vectorize align_semicircle?
225
- if align_semicircle:
218
+ angle = numpy.arctan2(center_imag, center_real)
219
+ elif isinstance(angle, str):
220
+ # TODO: vectorize str type
221
+ if angle == 'phase':
222
+ angle = numpy.arctan2(center_imag, center_real)
223
+ elif angle == 'semicircle':
226
224
  angle = numpy.arctan2(center_imag, center_real - 0.5)
227
225
  else:
228
- angle = numpy.arctan2(center_imag, center_real)
226
+ raise ValueError(f'invalid {angle=}')
229
227
 
230
228
  angle_sin = numpy.sin(angle)
231
229
  angle_cos = numpy.cos(angle)
@@ -320,10 +318,10 @@ def mask_from_polar_cursor(
320
318
 
321
319
  See Also
322
320
  --------
323
- :ref:`sphx_glr_tutorials_api_phasorpy_cursors.py`
321
+ :ref:`sphx_glr_tutorials_api_phasorpy_cursor.py`
324
322
 
325
- Example
326
- -------
323
+ Examples
324
+ --------
327
325
  Create mask from a single polar cursor:
328
326
 
329
327
  >>> mask_from_polar_cursor([0.2, 0.5], [0.4, 0.5], 1.1, 1.2, 0.4, 0.5)
@@ -423,10 +421,10 @@ def pseudo_color(
423
421
 
424
422
  See Also
425
423
  --------
426
- :ref:`sphx_glr_tutorials_api_phasorpy_cursors.py`
424
+ :ref:`sphx_glr_tutorials_api_phasorpy_cursor.py`
427
425
 
428
- Example
429
- -------
426
+ Examples
427
+ --------
430
428
  Create pseudo-color image from single mask:
431
429
 
432
430
  >>> pseudo_color([True, False, True]) # doctest: +NUMBER
phasorpy/datasets.py CHANGED
@@ -2,14 +2,13 @@
2
2
 
3
3
  The ``phasorpy.datasets`` module provides a :py:func:`fetch` function to
4
4
  download data files from remote repositories and cache them in a local
5
- directory. The cache location can be changed by setting the
6
- ``PHASORPY_DATA_DIR`` environment variable.
5
+ directory.
7
6
 
8
7
  Datasets from the following repositories are available:
9
8
 
10
- - `PhasorPy tests <https://zenodo.org/record/8417894>`_
11
- - `LFD Workshop <https://zenodo.org/record/8411056>`_
12
- - `FLUTE <https://zenodo.org/record/8046636>`_
9
+ - `PhasorPy tests <https://zenodo.org/records/8417894>`_
10
+ - `LFD Workshop <https://zenodo.org/records/8411056>`_
11
+ - `FLUTE <https://zenodo.org/records/8046636>`_
13
12
  - `napari-flim-phasor-plotter
14
13
  <https://github.com/zoccoler/napari-flim-phasor-plotter/tree/0.0.6/src/napari_flim_phasor_plotter/data>`_
15
14
  - `Phasor-based multi-harmonic unmixing for in-vivo hyperspectral imaging
@@ -19,10 +18,18 @@ Datasets from the following repositories are available:
19
18
  <https://zenodo.org/records/14026720>`_
20
19
  - `Convallaria FLIM dataset in FLIM LABS JSON format
21
20
  <https://zenodo.org/records/15007900>`_
21
+ - `FLIM and spectral dataset for GSLab
22
+ <https://figshare.com/articles/dataset/FLIM_dataset_for_GSLab/28067108>`_
23
+ - `Hyperspectral and FLIM dataset of LAURDAN-stained NIH-3T3 cells
24
+ <https://zenodo.org/records/16894639>`_
22
25
 
23
26
  The implementation is based on the `Pooch <https://www.fatiando.org/pooch>`_
24
27
  library.
25
28
 
29
+ The default cache location is determined by the Pooch library, but can be
30
+ overridden by setting the ``PHASORPY_DATA_DIR`` environment variable to
31
+ a custom directory path.
32
+
26
33
  """
27
34
 
28
35
  from __future__ import annotations
@@ -397,6 +404,60 @@ FLIMLABS = pooch.create(
397
404
  },
398
405
  )
399
406
 
407
+ FIGSHARE_28067108 = pooch.create(
408
+ path=pooch.os_cache('phasorpy'),
409
+ base_url=(
410
+ 'https://github.com/phasorpy/phasorpy-data/raw/main/figshare_28067108'
411
+ ),
412
+ env=ENV,
413
+ registry={
414
+ '38_Hoechst_Golgi_Mito_Lyso_CellMask_mixture.lsm': (
415
+ 'sha256:'
416
+ '092ac050edf55e26dcda8cba10122408c6f1b81d19accf07214385d6eebfcf3e'
417
+ ),
418
+ '38_Hoechst_Golgi_Mito_Lyso_CellMask_mixture.lsm.zip': (
419
+ 'sha256:'
420
+ '19298d12b16a58c1de3f532398c154d89df3f2286a1a6ee38a29f1fbefac78fc'
421
+ ),
422
+ '40x800fov19LP500p30_4dyes_a1_$CG0T_ch1_h1_h2.R64': (
423
+ 'sha256:'
424
+ 'ad1bae8c3624eecb8927283e333ab5ea3fb864d6c5bb0f155da83c7a8aa40df3'
425
+ ),
426
+ '40x800fov19LP500p30_AcO_a4_$CG0T_ch1_h1_h2.R64': (
427
+ 'sha256:'
428
+ 'd1de46652fbed0626ae6ad6334c41baafb0a5ae9e0e15e49221eb540a666d7e7'
429
+ ),
430
+ '40x800fov19LP500p30_EtBr_a5_$CG0T_ch1_h1_h2.R64': (
431
+ 'sha256:'
432
+ '9f4dd2d328877d2b18e064a3fb20d2a5318c833caa5a3cea15bafbf8df5d588a'
433
+ ),
434
+ '40x800fov19LP500p30_NucB_a6_$CG0T_ch1_h1_h2.R64': (
435
+ 'sha256:'
436
+ '74e378ddae84f6532d7ac05f8639feb42541eecb278c842e9a18565c201242f8'
437
+ ),
438
+ '40x800fov19LP500p30_RoseBx100_a1_$CG0T_ch1_h1_h2.R64': (
439
+ 'sha256:'
440
+ '898e0e7e96f8b6c2ee83940f94026dd9006e6fc46bb7e56c62dd22855079e279'
441
+ ),
442
+ 'Coumarin6.txt': (
443
+ 'sha256:'
444
+ '6a3ae0f886b512c26cea8bc4b4cd9027ee8d4b7dd437a1eeb9621947e19c3c88'
445
+ ),
446
+ 'Hoechst_Lyso_Golgi_MitoTracker_CellMask.csv': (
447
+ 'sha256:'
448
+ '1d000ae6268e6d290ab1cfdf2d31d840f27183cba75b380f116e1049696bb3a4'
449
+ ),
450
+ 'Mosaic04_10x3_FOV600_z95_32A1_t06_uncalibrated.ref': (
451
+ 'sha256:'
452
+ '3c23ca9a21a3ef762765fc81591dd0cf9bdaf3e77fa4faa3bf60da69e6ab1127'
453
+ ),
454
+ 'Mosaic04_10x3_FOV600_z95_32A1_t06_uncalibrated.ref.zip': (
455
+ 'sha256:'
456
+ '001a472d81b3d348ac4680c73de877ee809c2f229f882ef015225e208a7273fb'
457
+ ),
458
+ },
459
+ )
460
+
400
461
  FIGSHARE_22336594 = pooch.create(
401
462
  path=pooch.os_cache('phasorpy'),
402
463
  base_url=(
@@ -447,6 +508,34 @@ FIGSHARE_22336594_EXPORTED = pooch.create(
447
508
  },
448
509
  )
449
510
 
511
+ ZENODO_16894639 = pooch.create(
512
+ path=pooch.os_cache('phasorpy'),
513
+ base_url=(
514
+ 'https://github.com/phasorpy/phasorpy-data/raw/main/zenodo_16894639'
515
+ if DATA_ON_GITHUB
516
+ else 'doi:10.5281/zenodo.16894639'
517
+ ),
518
+ env=ENV,
519
+ registry={
520
+ '04 NIH3T3LAURDAN8meanspectra.lsm': (
521
+ 'sha256:'
522
+ '27173be5b57a1a0f40ad6e89df1fd1d6d20bdd1e0a80e469acb47cf0bc103a1c'
523
+ ),
524
+ '04NIH3T3_LAURDAN_000$CC0Z.fbd': (
525
+ 'sha256:'
526
+ '9c8e7d79ef6ce4cce7366c843d34f5b4544f4123fe88307b8df5954a1fe4a799'
527
+ ),
528
+ 'cumarinech1_780LAURDAN_000$CC0Z.fbd': (
529
+ 'sha256:'
530
+ '1b7b513680973c79df697b9cefdf2104f5d32346e24c9071336f76a7b82e9313'
531
+ ),
532
+ 'cumarinech2_780LAURDAN_000$CC0Z.fbd': (
533
+ 'sha256:'
534
+ '5c9cf9694652cc9c344e67b5650fd49683fa7fdcec39e56ccbf0bdd2f7dadf15'
535
+ ),
536
+ },
537
+ )
538
+
450
539
  MISC = pooch.create(
451
540
  path=pooch.os_cache('phasorpy'),
452
541
  base_url='https://github.com/phasorpy/phasorpy-data/raw/main/misc',
@@ -469,11 +558,18 @@ REPOSITORIES: dict[str, pooch.Pooch] = {
469
558
  'zenodo-14976703': ZENODO_14976703,
470
559
  'convallaria-fbd': CONVALLARIA_FBD,
471
560
  'flimlabs': FLIMLABS,
561
+ 'figshare_28067108': FIGSHARE_28067108,
472
562
  'figshare_22336594': FIGSHARE_22336594,
473
563
  'figshare_22336594_exported': FIGSHARE_22336594_EXPORTED,
564
+ 'zenodo-16894639': ZENODO_16894639,
474
565
  'misc': MISC,
475
566
  }
476
- """Pooch repositories."""
567
+ """Dictionary mapping repository names to Pooch repository objects.
568
+
569
+ Each repository provides access to a specific collection of sample data files
570
+ that can be fetched using the :py:func:`fetch` function.
571
+
572
+ """
477
573
 
478
574
 
479
575
  def fetch(
@@ -489,21 +585,35 @@ def fetch(
489
585
 
490
586
  Parameters
491
587
  ----------
492
- *args : str or iterable of str, optional
588
+ *args : str, iterable of str, or pooch.Pooch
493
589
  Name(s) of file(s) or repositories to fetch from local storage.
590
+ Can be:
591
+
592
+ - File names (for example, 'simfcs.r64')
593
+ - Repository names (for example, 'tests', 'flute')
594
+ - Pooch repository objects
595
+ - Iterables of the above
596
+
494
597
  If omitted, return files in all repositories.
495
598
  extract_dir : str or None, optional
496
599
  Path, relative to cache location, where ZIP files will be unpacked.
497
600
  return_scalar : bool, optional
498
601
  If true (default), return single path as string, else tuple of string.
499
602
  **kwargs
500
- Additional arguments passed to ``pooch.fetch()``.
603
+ Optional arguments passed to :py:func:`pooch.fetch`.
501
604
  For example, ``progressbar=True``.
502
605
 
503
606
  Returns
504
607
  -------
505
608
  str or tuple of str
506
609
  Absolute path(s) of file(s) in local storage.
610
+ Returns a single string if only one file and `return_scalar=True`,
611
+ otherwise returns a tuple of strings.
612
+
613
+ Raises
614
+ ------
615
+ ValueError
616
+ If specified file is not found in any repository.
507
617
 
508
618
  Examples
509
619
  --------
phasorpy/experimental.py CHANGED
@@ -11,26 +11,18 @@ from __future__ import annotations
11
11
  __all__ = [
12
12
  'anscombe_transform',
13
13
  'anscombe_transform_inverse',
14
- 'spectral_vector_denoise',
15
14
  ]
16
15
 
17
- import math
18
16
  from typing import TYPE_CHECKING
19
17
 
20
18
  if TYPE_CHECKING:
21
- from ._typing import Any, NDArray, ArrayLike, DTypeLike, Literal, Sequence
22
-
23
- import numpy
19
+ from ._typing import Any, NDArray, ArrayLike
24
20
 
25
21
  from ._phasorpy import (
26
22
  _anscombe,
27
23
  _anscombe_inverse,
28
24
  _anscombe_inverse_approx,
29
- _phasor_from_signal_vector,
30
- _signal_denoise_vector,
31
25
  )
32
- from ._utils import parse_harmonic
33
- from .utils import number_threads
34
26
 
35
27
 
36
28
  def anscombe_transform(
@@ -68,7 +60,6 @@ def anscombe_transform(
68
60
 
69
61
  References
70
62
  ----------
71
-
72
63
  .. [1] Anscombe FJ.
73
64
  `The transformation of Poisson, binomial and negative-binomial data
74
65
  <https://doi.org/10.2307/2332343>`_.
@@ -124,19 +115,18 @@ def anscombe_transform_inverse(
124
115
  x = 1/4 \cdot z^2
125
116
  + 1/4 \cdot \sqrt{3/2} \cdot z^{-1}
126
117
  - 11/8 \cdot z^{-2}
127
- + 5/8 \cdot \sqrt(3/2) \cdot z^{-3}
118
+ + 5/8 \cdot \sqrt{3/2} \cdot z^{-3}
128
119
  - 1/8
129
120
 
130
121
  References
131
122
  ----------
132
-
133
123
  .. [2] Makitalo M, and Foi A.
134
124
  `A closed-form approximation of the exact unbiased inverse of the
135
125
  Anscombe variance-stabilizing transformation
136
126
  <https://doi.org/10.1109/TIP.2011.2121085>`_.
137
- *IEEE Trans Image Process*, 20(9): 2697-8 (2011).
127
+ *IEEE Trans Image Process*, 20(9): 2697-8 (2011)
138
128
 
139
- .. [3] Makitalo M, and Foi A
129
+ .. [3] Makitalo M, and Foi A.
140
130
  `Optimal inversion of the generalized Anscombe transformation for
141
131
  Poisson-Gaussian noise
142
132
  <https://doi.org/10.1109/TIP.2012.2202675>`_,
@@ -156,157 +146,3 @@ def anscombe_transform_inverse(
156
146
  data, **kwargs
157
147
  )
158
148
  return _anscombe_inverse(data, **kwargs) # type: ignore[no-any-return]
159
-
160
-
161
- def spectral_vector_denoise(
162
- signal: ArrayLike,
163
- /,
164
- spectral_vector: ArrayLike | None = None,
165
- *,
166
- axis: int = -1,
167
- harmonic: int | Sequence[int] | Literal['all'] | str | None = None,
168
- sigma: float = 0.05,
169
- vmin: float | None = None,
170
- dtype: DTypeLike | None = None,
171
- num_threads: int | None = None,
172
- ) -> NDArray[Any]:
173
- """Return spectral-vector-denoised signal.
174
-
175
- The spectral vector denoising algorithm is based on a Gaussian weighted
176
- average calculation, with weights obtained in n-dimensional Chebyshev or
177
- Fourier space [4]_.
178
-
179
- Parameters
180
- ----------
181
- signal : array_like
182
- Hyperspectral data to be denoised.
183
- A minimum of three samples are required along `axis`.
184
- The samples must be uniformly spaced.
185
- spectral_vector : array_like, optional
186
- Spectral vector.
187
- For example, phasor coordinates, PCA projected phasor coordinates,
188
- or Chebyshev coefficients.
189
- Must be of same shape as `signal` with `axis` removed and axis
190
- containing spectral space appended.
191
- If None (default), phasor coordinates are calculated at specified
192
- `harmonic`.
193
- axis : int, optional, default: -1
194
- Axis over which `spectral_vector` is computed if not provided.
195
- The default is the last axis (-1).
196
- harmonic : int, sequence of int, or 'all', optional
197
- Harmonics to include in calculating `spectral_vector`.
198
- If `'all'`, include all harmonics for `signal` samples along `axis`.
199
- Else, harmonics must be at least one and no larger than half the
200
- number of `signal` samples along `axis`.
201
- The default is the first harmonic (fundamental frequency).
202
- A minimum of `harmonic * 2 + 1` samples are required along `axis`
203
- to calculate correct phasor coordinates at `harmonic`.
204
- sigma : float, default: 0.05
205
- Width of Gaussian filter in spectral vector space.
206
- Weighted averages are calculated using the spectra of signal items
207
- within an spectral vector Euclidean distance of `3 * sigma` and
208
- intensity above `vmin`.
209
- vmin : float, optional
210
- Signal intensity along `axis` below which not to include in denoising.
211
- dtype : dtype_like, optional
212
- Data type of output arrays. Either float32 or float64.
213
- The default is float64 unless the `signal` is float32.
214
- num_threads : int, optional
215
- Number of OpenMP threads to use for parallelization.
216
- By default, multi-threading is disabled.
217
- If zero, up to half of logical CPUs are used.
218
- OpenMP may not be available on all platforms.
219
-
220
- Returns
221
- -------
222
- ndarray
223
- Denoised signal of `dtype`.
224
- Spectra with integrated intensity below `vmin` are unchanged.
225
-
226
- References
227
- ----------
228
-
229
- .. [4] Harman RC, Lang RT, Kercher EM, Leven P, and Spring BQ.
230
- `Denoising multiplexed microscopy images in n-dimensional spectral space
231
- <https://doi.org/10.1364/BOE.463979>`_.
232
- *Biomed Opt Express*, 13(8): 4298-4309 (2022)
233
-
234
- Examples
235
- --------
236
- Denoise a hyperspectral image with a Gaussian filter width of 0.1 in
237
- spectral vector space using first and second harmonic:
238
-
239
- >>> signal = numpy.random.randint(0, 255, (8, 16, 16))
240
- >>> spectral_vector_denoise(signal, axis=0, sigma=0.1, harmonic=[1, 2])
241
- array([[[...]]])
242
-
243
- """
244
- num_threads = number_threads(num_threads)
245
-
246
- signal = numpy.asarray(signal)
247
- if axis == -1 or axis == signal.ndim - 1:
248
- axis = -1
249
- else:
250
- signal = numpy.moveaxis(signal, axis, -1)
251
- shape = signal.shape
252
- samples = shape[-1]
253
-
254
- if harmonic is None:
255
- harmonic = 1
256
- harmonic, _ = parse_harmonic(harmonic, samples // 2)
257
- num_harmonics = len(harmonic)
258
-
259
- if vmin is None or vmin < 0.0:
260
- vmin = 0.0
261
-
262
- sincos = numpy.empty((num_harmonics, samples, 2))
263
- for i, h in enumerate(harmonic):
264
- phase = numpy.linspace(
265
- 0,
266
- h * math.pi * 2.0,
267
- samples,
268
- endpoint=False,
269
- dtype=numpy.float64,
270
- )
271
- sincos[i, :, 0] = numpy.cos(phase)
272
- sincos[i, :, 1] = numpy.sin(phase)
273
-
274
- signal = numpy.ascontiguousarray(signal).reshape(-1, samples)
275
- size = signal.shape[0]
276
-
277
- if dtype is None:
278
- if signal.dtype.char == 'f':
279
- dtype = signal.dtype
280
- else:
281
- dtype = numpy.float64
282
- dtype = numpy.dtype(dtype)
283
- if dtype.char not in {'d', 'f'}:
284
- raise ValueError('dtype is not floating point')
285
-
286
- if spectral_vector is None:
287
- spectral_vector = numpy.zeros((size, num_harmonics * 2), dtype=dtype)
288
- _phasor_from_signal_vector(
289
- spectral_vector, signal, sincos, num_threads
290
- )
291
- else:
292
- spectral_vector = numpy.ascontiguousarray(spectral_vector, dtype=dtype)
293
- if spectral_vector.shape[:-1] != shape[:-1]:
294
- raise ValueError('signal and spectral_vector shape mismatch')
295
- spectral_vector = spectral_vector.reshape(
296
- -1, spectral_vector.shape[-1]
297
- )
298
-
299
- if dtype == signal.dtype:
300
- denoised = signal.copy()
301
- else:
302
- denoised = numpy.zeros(signal.shape, dtype=dtype)
303
- denoised[:] = signal
304
- integrated = numpy.zeros(size, dtype=dtype)
305
- _signal_denoise_vector(
306
- denoised, integrated, signal, spectral_vector, sigma, vmin, num_threads
307
- )
308
-
309
- denoised = denoised.reshape(shape)
310
- if axis != -1:
311
- denoised = numpy.moveaxis(denoised, -1, axis)
312
- return denoised