phasorpy 0.3__cp312-cp312-win_arm64.whl → 0.5__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.
- phasorpy/_io.py +2655 -0
- phasorpy/_phasorpy.cp312-win_arm64.pyd +0 -0
- phasorpy/_phasorpy.pyx +119 -47
- phasorpy/_utils.py +165 -18
- phasorpy/cli.py +2 -0
- phasorpy/cluster.py +170 -0
- phasorpy/color.py +17 -13
- phasorpy/components.py +18 -18
- phasorpy/conftest.py +2 -0
- phasorpy/cursors.py +9 -9
- phasorpy/datasets.py +169 -10
- phasorpy/io.py +7 -1809
- phasorpy/phasor.py +281 -100
- phasorpy/plot.py +276 -36
- phasorpy/utils.py +12 -7
- phasorpy/version.py +14 -5
- {phasorpy-0.3.dist-info → phasorpy-0.5.dist-info}/METADATA +11 -15
- phasorpy-0.5.dist-info/RECORD +26 -0
- {phasorpy-0.3.dist-info → phasorpy-0.5.dist-info}/WHEEL +1 -1
- {phasorpy-0.3.dist-info → phasorpy-0.5.dist-info/licenses}/LICENSE.txt +1 -1
- phasorpy-0.3.dist-info/RECORD +0 -24
- {phasorpy-0.3.dist-info → phasorpy-0.5.dist-info}/entry_points.txt +0 -0
- {phasorpy-0.3.dist-info → phasorpy-0.5.dist-info}/top_level.txt +0 -0
phasorpy/cluster.py
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
"""Cluster phasor coordinates.
|
2
|
+
|
3
|
+
The `phasorpy.cluster` module provides functions to:
|
4
|
+
|
5
|
+
- fit elliptic clusters to phasor coordinates using
|
6
|
+
Gaussian Mixture Model (GMM):
|
7
|
+
|
8
|
+
- :py:func:`phasor_cluster_gmm`
|
9
|
+
|
10
|
+
"""
|
11
|
+
|
12
|
+
from __future__ import annotations
|
13
|
+
|
14
|
+
__all__ = ['phasor_cluster_gmm']
|
15
|
+
|
16
|
+
from typing import TYPE_CHECKING
|
17
|
+
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from ._typing import Any, ArrayLike
|
20
|
+
|
21
|
+
import math
|
22
|
+
|
23
|
+
import numpy
|
24
|
+
from sklearn.mixture import GaussianMixture
|
25
|
+
|
26
|
+
|
27
|
+
def phasor_cluster_gmm(
|
28
|
+
real: ArrayLike,
|
29
|
+
imag: ArrayLike,
|
30
|
+
/,
|
31
|
+
*,
|
32
|
+
sigma: float = 2.0,
|
33
|
+
clusters: int = 1,
|
34
|
+
**kwargs: Any,
|
35
|
+
) -> tuple[
|
36
|
+
tuple[float, ...],
|
37
|
+
tuple[float, ...],
|
38
|
+
tuple[float, ...],
|
39
|
+
tuple[float, ...],
|
40
|
+
tuple[float, ...],
|
41
|
+
]:
|
42
|
+
"""Return elliptic clusters in phasor coordinates using GMM.
|
43
|
+
|
44
|
+
Fit a Gaussian Mixture Model (GMM) to the provided phasor coordinates and
|
45
|
+
extract the parameters of ellipses that represent each cluster according
|
46
|
+
to [1]_.
|
47
|
+
|
48
|
+
Parameters
|
49
|
+
----------
|
50
|
+
real : array_like
|
51
|
+
Real component of phasor coordinates.
|
52
|
+
imag : array_like
|
53
|
+
Imaginary component of phasor coordinates.
|
54
|
+
sigma: float, default = 2.0
|
55
|
+
Scaling factor for radii of major and minor axes.
|
56
|
+
Defaults to 2, which corresponds to the scaling of eigenvalues for a
|
57
|
+
95% confidence ellipse.
|
58
|
+
clusters : int, optional
|
59
|
+
Number of Gaussian distributions to fit to phasor coordinates.
|
60
|
+
Defaults to 1.
|
61
|
+
**kwargs
|
62
|
+
Additional keyword arguments passed to
|
63
|
+
:py:class:`sklearn.mixture.GaussianMixture`.
|
64
|
+
|
65
|
+
Common options include:
|
66
|
+
|
67
|
+
- covariance_type : {'full', 'tied', 'diag', 'spherical'}
|
68
|
+
- max_iter : int, maximum number of EM iterations
|
69
|
+
- random_state : int, for reproducible results
|
70
|
+
|
71
|
+
Returns
|
72
|
+
-------
|
73
|
+
center_real : tuple of float
|
74
|
+
Real component of ellipse centers.
|
75
|
+
center_imag : tuple of float
|
76
|
+
Imaginary component of ellipse centers.
|
77
|
+
radius_major : tuple of float
|
78
|
+
Major radii of ellipses.
|
79
|
+
radius_minor : tuple of float
|
80
|
+
Minor radii of ellipses.
|
81
|
+
angle : tuple of float
|
82
|
+
Rotation angles of major axes in radians, within range [0, pi].
|
83
|
+
|
84
|
+
Raises
|
85
|
+
------
|
86
|
+
ValueError
|
87
|
+
If the array shapes of `real` and `imag` do not match.
|
88
|
+
If `clusters` is not a positive integer.
|
89
|
+
|
90
|
+
|
91
|
+
References
|
92
|
+
----------
|
93
|
+
.. [1] Vallmitjana A, Torrado B, and Gratton E.
|
94
|
+
`Phasor-based image segmentation: machine learning clustering techniques
|
95
|
+
<https://doi.org/10.1364/BOE.422766>`_.
|
96
|
+
*Biomed Opt Express*, 12(6): 3410-3422 (2021).
|
97
|
+
|
98
|
+
Examples
|
99
|
+
--------
|
100
|
+
Recover the clusters from a synthetic distribution of phasor coordinates
|
101
|
+
with two clusters:
|
102
|
+
|
103
|
+
>>> real1, imag1 = numpy.random.multivariate_normal(
|
104
|
+
... [0.2, 0.3], [[3e-3, 1e-3], [1e-3, 2e-3]], 100
|
105
|
+
... ).T
|
106
|
+
>>> real2, imag2 = numpy.random.multivariate_normal(
|
107
|
+
... [0.4, 0.5], [[2e-3, -1e-3], [-1e-3, 3e-3]], 100
|
108
|
+
... ).T
|
109
|
+
>>> real = numpy.concatenate([real1, real2])
|
110
|
+
>>> imag = numpy.concatenate([imag1, imag2])
|
111
|
+
>>> center_real, center_imag, radius_major, radius_minor, angle = (
|
112
|
+
... phasor_cluster_gmm(real, imag, clusters=2)
|
113
|
+
... )
|
114
|
+
>>> centers_real # doctest: +SKIP
|
115
|
+
(0.2, 0.4)
|
116
|
+
|
117
|
+
"""
|
118
|
+
coords = numpy.stack((real, imag), axis=-1).reshape(-1, 2)
|
119
|
+
|
120
|
+
valid_data = ~numpy.isnan(coords).any(axis=1)
|
121
|
+
coords = coords[valid_data]
|
122
|
+
|
123
|
+
kwargs.pop('n_components', None)
|
124
|
+
|
125
|
+
gmm = GaussianMixture(n_components=clusters, **kwargs)
|
126
|
+
gmm.fit(coords)
|
127
|
+
|
128
|
+
center_real = []
|
129
|
+
center_imag = []
|
130
|
+
radius_major = []
|
131
|
+
radius_minor = []
|
132
|
+
angle = []
|
133
|
+
|
134
|
+
for i in range(clusters):
|
135
|
+
center_real.append(float(gmm.means_[i, 0]))
|
136
|
+
center_imag.append(float(gmm.means_[i, 1]))
|
137
|
+
|
138
|
+
if gmm.covariance_type == 'full':
|
139
|
+
cov = gmm.covariances_[i]
|
140
|
+
elif gmm.covariance_type == 'tied':
|
141
|
+
cov = gmm.covariances_
|
142
|
+
elif gmm.covariance_type == 'diag':
|
143
|
+
cov = numpy.diag(gmm.covariances_[i])
|
144
|
+
else: # 'spherical'
|
145
|
+
cov = numpy.eye(2) * gmm.covariances_[i]
|
146
|
+
|
147
|
+
eigenvalues, eigenvectors = numpy.linalg.eigh(cov[:2, :2])
|
148
|
+
|
149
|
+
idx = eigenvalues.argsort()[::-1]
|
150
|
+
eigenvalues = eigenvalues[idx]
|
151
|
+
eigenvectors = eigenvectors[:, idx]
|
152
|
+
|
153
|
+
major_vector = eigenvectors[:, 0]
|
154
|
+
current_angle = math.atan2(major_vector[1], major_vector[0])
|
155
|
+
|
156
|
+
if current_angle < 0:
|
157
|
+
current_angle += math.pi
|
158
|
+
|
159
|
+
angle.append(float(current_angle))
|
160
|
+
|
161
|
+
radius_major.append(sigma * math.sqrt(2 * eigenvalues[0]))
|
162
|
+
radius_minor.append(sigma * math.sqrt(2 * eigenvalues[1]))
|
163
|
+
|
164
|
+
return (
|
165
|
+
tuple(center_real),
|
166
|
+
tuple(center_imag),
|
167
|
+
tuple(radius_major),
|
168
|
+
tuple(radius_minor),
|
169
|
+
tuple(angle),
|
170
|
+
)
|
phasorpy/color.py
CHANGED
@@ -19,13 +19,13 @@ def wavelength2rgb(
|
|
19
19
|
) -> tuple[float, float, float] | NDArray[Any]:
|
20
20
|
"""Return approximate sRGB color components of visible wavelength(s).
|
21
21
|
|
22
|
-
|
23
|
-
the :py:attr:`SRGB_SPECTRUM` palette.
|
22
|
+
Wavelengths are clipped to range [360, 750] nm, rounded, and used to
|
23
|
+
index the :py:attr:`SRGB_SPECTRUM` palette.
|
24
24
|
|
25
25
|
Parameters
|
26
26
|
----------
|
27
27
|
wavelength : array_like
|
28
|
-
Scalar or array of
|
28
|
+
Scalar or array of wavelengths in nm.
|
29
29
|
dtype : data-type, optional
|
30
30
|
Data-type of return value. The default is ``float32``.
|
31
31
|
|
@@ -33,8 +33,8 @@ def wavelength2rgb(
|
|
33
33
|
-------
|
34
34
|
ndarray or tuple
|
35
35
|
Approximate sRGB color components of visible wavelength.
|
36
|
-
Floating-point
|
37
|
-
Integer
|
36
|
+
Floating-point values are in range [0.0, 1.0].
|
37
|
+
Integer values are scaled to the dtype's maximum value.
|
38
38
|
|
39
39
|
Examples
|
40
40
|
--------
|
@@ -59,8 +59,7 @@ def wavelength2rgb(
|
|
59
59
|
else:
|
60
60
|
rgb = rgb.astype(dtype)
|
61
61
|
if astuple:
|
62
|
-
|
63
|
-
return (rgb_list[0], rgb_list[1], rgb_list[2])
|
62
|
+
return tuple(rgb.tolist()[:3])
|
64
63
|
return rgb
|
65
64
|
|
66
65
|
|
@@ -69,7 +68,7 @@ def float2int(
|
|
69
68
|
/,
|
70
69
|
dtype: DTypeLike = numpy.uint8,
|
71
70
|
) -> NDArray[Any]:
|
72
|
-
"""Return normalized color components as
|
71
|
+
"""Return normalized color components as integers.
|
73
72
|
|
74
73
|
Parameters
|
75
74
|
----------
|
@@ -78,6 +77,11 @@ def float2int(
|
|
78
77
|
dtype : data-type, optional
|
79
78
|
Data type of return value. The default is ``uint8``.
|
80
79
|
|
80
|
+
Returns
|
81
|
+
-------
|
82
|
+
ndarray
|
83
|
+
Color components as integers scaled to dtype's range.
|
84
|
+
|
81
85
|
Examples
|
82
86
|
--------
|
83
87
|
>>> float2int([0.0, 0.5, 1.0])
|
@@ -163,11 +167,11 @@ CATEGORICAL: NDArray[numpy.float32] = numpy.array([
|
|
163
167
|
[0.523809, 0.888889, 0.460317],
|
164
168
|
[0.285714, 0.0, 0.238095],
|
165
169
|
], dtype=numpy.float32)
|
166
|
-
"""Categorical sRGB color palette inspired by C Glasbey.
|
170
|
+
"""Categorical sRGB color palette inspired by C. Glasbey.
|
167
171
|
|
168
|
-
|
172
|
+
Contains 64 maximally distinct colours for visualization.
|
169
173
|
|
170
|
-
Generated
|
174
|
+
Generated using the `glasbey <https://glasbey.readthedocs.io>`_ package::
|
171
175
|
|
172
176
|
import glasbey; numpy.array(glasbey.create_palette(64, as_hex=False))
|
173
177
|
|
@@ -569,11 +573,11 @@ SRGB_SPECTRUM: NDArray[numpy.float32] = numpy.array([
|
|
569
573
|
[0.005006, 0.0, 0.0],
|
570
574
|
[0.004664, 0.0, 0.0],
|
571
575
|
], dtype=numpy.float32)
|
572
|
-
"""sRGB color components for visible light
|
576
|
+
"""sRGB color components for wavelengths of visible light (360-750 nm).
|
573
577
|
|
574
578
|
Based on the CIE 1931 2° Standard Observer.
|
575
579
|
|
576
|
-
Generated
|
580
|
+
Generated using the `colour <https://colour.readthedocs.io>`_ package::
|
577
581
|
|
578
582
|
import colour; colour.plotting.plot_visible_spectrum()
|
579
583
|
|
phasorpy/components.py
CHANGED
@@ -65,10 +65,10 @@ def two_fractions_from_phasor(
|
|
65
65
|
Real component of phasor coordinates.
|
66
66
|
imag : array_like
|
67
67
|
Imaginary component of phasor coordinates.
|
68
|
-
components_real: array_like, shape (2,)
|
69
|
-
Real coordinates of
|
70
|
-
components_imag: array_like, shape (2,)
|
71
|
-
Imaginary coordinates of
|
68
|
+
components_real : array_like, shape (2,)
|
69
|
+
Real coordinates of first and second components.
|
70
|
+
components_imag : array_like, shape (2,)
|
71
|
+
Imaginary coordinates of first and second components.
|
72
72
|
|
73
73
|
Returns
|
74
74
|
-------
|
@@ -78,7 +78,7 @@ def two_fractions_from_phasor(
|
|
78
78
|
Raises
|
79
79
|
------
|
80
80
|
ValueError
|
81
|
-
If the real
|
81
|
+
If the real or imaginary coordinates of the known components are
|
82
82
|
not of size 2.
|
83
83
|
|
84
84
|
See Also
|
@@ -145,13 +145,13 @@ def graphical_component_analysis(
|
|
145
145
|
Real component of phasor coordinates.
|
146
146
|
imag : array_like
|
147
147
|
Imaginary component of phasor coordinates.
|
148
|
-
components_real: array_like, shape (2,) or (3,)
|
148
|
+
components_real : array_like, shape (2,) or (3,)
|
149
149
|
Real coordinates for two or three components.
|
150
|
-
components_imag: array_like, shape (2,) or (3,)
|
150
|
+
components_imag : array_like, shape (2,) or (3,)
|
151
151
|
Imaginary coordinates for two or three components.
|
152
|
-
radius: float, optional, default: 0.05
|
153
|
-
Radius of
|
154
|
-
fractions: array_like or int, optional
|
152
|
+
radius : float, optional, default: 0.05
|
153
|
+
Radius of cursor.
|
154
|
+
fractions : array_like or int, optional
|
155
155
|
Number of equidistant fractions, or 1D array of fraction values.
|
156
156
|
Fraction values must be in range [0.0, 1.0].
|
157
157
|
If an integer, ``numpy.linspace(0.0, 1.0, fractions)`` fraction values
|
@@ -163,8 +163,8 @@ def graphical_component_analysis(
|
|
163
163
|
Returns
|
164
164
|
-------
|
165
165
|
counts : tuple of ndarray
|
166
|
-
Counts along each line segment connecting
|
167
|
-
0-1 (2 components) or 0-1, 0-2, 1-2 (3 components).
|
166
|
+
Counts along each line segment connecting components.
|
167
|
+
Ordered 0-1 (2 components) or 0-1, 0-2, 1-2 (3 components).
|
168
168
|
|
169
169
|
Raises
|
170
170
|
------
|
@@ -172,7 +172,7 @@ def graphical_component_analysis(
|
|
172
172
|
The array shapes of `real` and `imag`, or `components_real` and
|
173
173
|
`components_imag` do not match.
|
174
174
|
The number of components is not 2 or 3.
|
175
|
-
Fraction values are
|
175
|
+
Fraction values are out of range [0.0, 1.0].
|
176
176
|
|
177
177
|
See Also
|
178
178
|
--------
|
@@ -216,7 +216,7 @@ def graphical_component_analysis(
|
|
216
216
|
>>> graphical_component_analysis(
|
217
217
|
... [0.6, 0.3], [0.35, 0.38], [0.2, 0.9], [0.4, 0.3], fractions=6
|
218
218
|
... ) # doctest: +NUMBER
|
219
|
-
(array([0, 0, 1, 0, 1, 0]),)
|
219
|
+
(array([0, 0, 1, 0, 1, 0], dtype=uint64),)
|
220
220
|
|
221
221
|
Count the number of phasors between the combinations of three components:
|
222
222
|
|
@@ -227,9 +227,9 @@ def graphical_component_analysis(
|
|
227
227
|
... [0.0, 0.4, 0.3],
|
228
228
|
... fractions=6,
|
229
229
|
... ) # doctest: +NUMBER +NORMALIZE_WHITESPACE
|
230
|
-
(array([0, 1, 1, 1, 1, 0]),
|
231
|
-
array([0, 1, 0, 0, 0, 0]),
|
232
|
-
array([0, 1, 2, 0, 0, 0]))
|
230
|
+
(array([0, 1, 1, 1, 1, 0], dtype=uint64),
|
231
|
+
array([0, 1, 0, 0, 0, 0], dtype=uint64),
|
232
|
+
array([0, 1, 2, 0, 0, 0], dtype=uint64))
|
233
233
|
|
234
234
|
"""
|
235
235
|
real = numpy.asarray(real)
|
@@ -305,7 +305,7 @@ def graphical_component_analysis(
|
|
305
305
|
components_imag[3 - i - j], # c_imag
|
306
306
|
radius,
|
307
307
|
)
|
308
|
-
fraction_counts = numpy.sum(mask)
|
308
|
+
fraction_counts = numpy.sum(mask, dtype=numpy.uint64)
|
309
309
|
component_counts.append(fraction_counts)
|
310
310
|
|
311
311
|
counts.append(numpy.asarray(component_counts))
|
phasorpy/conftest.py
CHANGED
phasorpy/cursors.py
CHANGED
@@ -291,15 +291,15 @@ def mask_from_polar_cursor(
|
|
291
291
|
imag : array_like
|
292
292
|
Imaginary component of phasor coordinates.
|
293
293
|
phase_min : array_like, shape (n,)
|
294
|
-
|
295
|
-
Values should be
|
294
|
+
Lower bound of angular range of cursors in radians.
|
295
|
+
Values should be in range [-pi, pi].
|
296
296
|
phase_max : array_like, shape (n,)
|
297
|
-
|
298
|
-
Values should be
|
297
|
+
Upper bound of angular range of cursors in radians.
|
298
|
+
Values should be in range [-pi, pi].
|
299
299
|
modulation_min : array_like, shape (n,)
|
300
|
-
|
300
|
+
Lower bound of radial range of cursors.
|
301
301
|
modulation_max : array_like, shape (n,)
|
302
|
-
|
302
|
+
Upper bound of radial range of cursors.
|
303
303
|
|
304
304
|
Returns
|
305
305
|
-------
|
@@ -362,7 +362,7 @@ def mask_from_polar_cursor(
|
|
362
362
|
f'{phase_min.ndim=}, {phase_max.ndim=}, '
|
363
363
|
f'{modulation_min.ndim=}, or {modulation_max.ndim=} > 1'
|
364
364
|
)
|
365
|
-
# TODO: check if angles are
|
365
|
+
# TODO: check if angles are in range [-pi and pi]
|
366
366
|
|
367
367
|
moveaxis = False
|
368
368
|
if real.ndim > 0 and (
|
@@ -406,7 +406,7 @@ def pseudo_color(
|
|
406
406
|
Maximum value to normalize `intensity`.
|
407
407
|
If None, the maximum value of `intensity` is used.
|
408
408
|
colors : array_like, optional, shape (N, 3)
|
409
|
-
|
409
|
+
RGB colors assigned to each cursor.
|
410
410
|
The last dimension contains the normalized RGB floating point values.
|
411
411
|
The default is :py:data:`phasorpy.color.CATEGORICAL`.
|
412
412
|
|
@@ -463,7 +463,7 @@ def pseudo_color(
|
|
463
463
|
shape = numpy.asarray(masks[0]).shape
|
464
464
|
|
465
465
|
if intensity is not None:
|
466
|
-
# normalize intensity to range 0
|
466
|
+
# normalize intensity to range [0, 1]
|
467
467
|
intensity = numpy.array(
|
468
468
|
intensity, dtype=numpy.float32, ndmin=1, copy=True
|
469
469
|
)
|
phasorpy/datasets.py
CHANGED
@@ -14,8 +14,11 @@ Datasets from the following repositories are available:
|
|
14
14
|
<https://github.com/zoccoler/napari-flim-phasor-plotter/tree/0.0.6/src/napari_flim_phasor_plotter/data>`_
|
15
15
|
- `Phasor-based multi-harmonic unmixing for in-vivo hyperspectral imaging
|
16
16
|
<https://zenodo.org/records/13625087>`_
|
17
|
+
(`second record <https://zenodo.org/records/14860228>`_)
|
17
18
|
- `Convallaria slice acquired with time-resolved 2-photon microscope
|
18
19
|
<https://zenodo.org/records/14026720>`_
|
20
|
+
- `Convallaria FLIM dataset in FLIM LABS JSON format
|
21
|
+
<https://zenodo.org/records/15007900>`_
|
19
22
|
|
20
23
|
The implementation is based on the `Pooch <https://www.fatiando.org/pooch>`_
|
21
24
|
library.
|
@@ -266,14 +269,15 @@ ZENODO_13625087 = pooch.create(
|
|
266
269
|
base_url=(
|
267
270
|
'https://github.com/phasorpy/phasorpy-data/raw/main/zenodo_13625087'
|
268
271
|
# if DATA_ON_GITHUB
|
269
|
-
# else 'doi:10.1088/2050-6120/ac9ae9'
|
272
|
+
# else 'doi:10.1088/2050-6120/ac9ae9' # TODO: not working with Pooch
|
270
273
|
),
|
271
274
|
env=ENV,
|
272
275
|
registry={
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
276
|
+
# part of ZENODO_14860228
|
277
|
+
# '33_Hoechst_Golgi_Mito_Lyso_CellMAsk_404_488_561_633_SP.lsm': (
|
278
|
+
# 'sha256:'
|
279
|
+
# '68fcefcad4e750e9ec7068820e455258c986f6a9b724e66744a28bbbb689f986'
|
280
|
+
# ),
|
277
281
|
'34_Hoechst_Golgi_Mito_Lyso_CellMAsk_404_488_561_633_SP.lsm': (
|
278
282
|
'sha256:'
|
279
283
|
'5c0b7d76c274fd64891fca2507013b7c8c9979d8131ce282fac55fd24fbb38bd'
|
@@ -289,9 +293,65 @@ ZENODO_13625087 = pooch.create(
|
|
289
293
|
},
|
290
294
|
)
|
291
295
|
|
296
|
+
ZENODO_14860228 = pooch.create(
|
297
|
+
path=pooch.os_cache('phasorpy'),
|
298
|
+
base_url=(
|
299
|
+
'https://github.com/phasorpy/phasorpy-data/raw/main/zenodo_14860228'
|
300
|
+
if DATA_ON_GITHUB
|
301
|
+
else 'doi:10.5281/zenodo.14860228'
|
302
|
+
),
|
303
|
+
env=ENV,
|
304
|
+
registry={
|
305
|
+
'38_Hoechst_Golgi_Mito_Lyso_CellMAsk_404_488_561_633_SP.lsm': (
|
306
|
+
'sha256:'
|
307
|
+
'092ac050edf55e26dcda8cba10122408c6f1b81d19accf07214385d6eebfcf3e'
|
308
|
+
),
|
309
|
+
'spectral cell mask.lsm': (
|
310
|
+
'sha256:'
|
311
|
+
'c4c2c567bd99ef4930d7278794d4e3daebaad0375c0852a5ab86a2ea056f4fe3'
|
312
|
+
),
|
313
|
+
'spectral golgi.lsm': (
|
314
|
+
'sha256:'
|
315
|
+
'd0a5079d9ed18b1248434f3f6d4b2b240fb034891121262cfe9dfec64d8429cd'
|
316
|
+
),
|
317
|
+
'spectral hoehst.lsm': (
|
318
|
+
'sha256:'
|
319
|
+
'3ee44a7f9f125698bb5e34746d9723669f67c520ffbf21244757d7fc25dbbb88'
|
320
|
+
),
|
321
|
+
'spectral lyso tracker green.lsm': (
|
322
|
+
'sha256:'
|
323
|
+
'0964448649e2c73a57f5ca0c705c86511fb4625c0a2af0d7850dfa39698fcbb9'
|
324
|
+
),
|
325
|
+
'spectral mito tracker.lsm': (
|
326
|
+
'sha256:'
|
327
|
+
'99b9892b247256ebf8a9917c662bc7bb66a8daf3b5db950fbbb191de0cd35b37'
|
328
|
+
),
|
329
|
+
},
|
330
|
+
)
|
331
|
+
|
332
|
+
ZENODO_14976703 = pooch.create(
|
333
|
+
path=pooch.os_cache('phasorpy'),
|
334
|
+
base_url=(
|
335
|
+
'https://github.com/phasorpy/phasorpy-data/raw/main/zenodo_14976703'
|
336
|
+
if DATA_ON_GITHUB
|
337
|
+
else 'doi:10.5281/zenodo.14976703'
|
338
|
+
),
|
339
|
+
env=ENV,
|
340
|
+
registry={
|
341
|
+
'Convalaria_LambdaScan.lif': (
|
342
|
+
'sha256:'
|
343
|
+
'27f1282cf02f87e11f8c7d3064066a4517ad4c9c769c796b32e459774f18c62a'
|
344
|
+
),
|
345
|
+
},
|
346
|
+
)
|
347
|
+
|
292
348
|
CONVALLARIA_FBD = pooch.create(
|
293
349
|
path=pooch.os_cache('phasorpy'),
|
294
|
-
base_url=
|
350
|
+
base_url=(
|
351
|
+
'https://github.com/phasorpy/phasorpy-data/raw/main/zenodo_14026720'
|
352
|
+
if DATA_ON_GITHUB
|
353
|
+
else 'doi:10.5281/zenodo.14026719'
|
354
|
+
),
|
295
355
|
env=ENV,
|
296
356
|
registry={
|
297
357
|
'Convallaria_$EI0S.fbd': (
|
@@ -305,6 +365,99 @@ CONVALLARIA_FBD = pooch.create(
|
|
305
365
|
},
|
306
366
|
)
|
307
367
|
|
368
|
+
FLIMLABS = pooch.create(
|
369
|
+
path=pooch.os_cache('phasorpy'),
|
370
|
+
base_url=(
|
371
|
+
'https://github.com/phasorpy/phasorpy-data/raw/main/flimlabs'
|
372
|
+
if DATA_ON_GITHUB
|
373
|
+
else 'doi:10.5281/zenodo.15007900'
|
374
|
+
),
|
375
|
+
env=ENV,
|
376
|
+
registry={
|
377
|
+
'Convallaria_m2_1740751781_phasor_ch1.json': (
|
378
|
+
'sha256:'
|
379
|
+
'a8bf0179f352ab2c6c78d0bd399545ab1fb6d5537f23dc06e5f12a7ef5af6615'
|
380
|
+
),
|
381
|
+
'Convallaria_m2_1740751781_phasor_ch1.json.zip': (
|
382
|
+
'sha256:'
|
383
|
+
'9c5691f55e85778717ace13607d573bcd00c29e357e063c8db4f173340f72984'
|
384
|
+
),
|
385
|
+
'Fluorescein_Calibration_m2_1740751189_imaging.json': (
|
386
|
+
'sha256:'
|
387
|
+
'aeebb074dbea6bff7578f409c7622b2f7f173bb23e5475d1436adedca7fc2eed'
|
388
|
+
),
|
389
|
+
'Fluorescein_Calibration_m2_1740751189_imaging.json.zip': (
|
390
|
+
'sha256:'
|
391
|
+
'32960bc1dec85fd16ffc7dd74a3cd63041fb3b69054ee6582f913129b0847086'
|
392
|
+
),
|
393
|
+
'Fluorescein_Calibration_m2_1740751189_imaging_calibration.json': (
|
394
|
+
'sha256:'
|
395
|
+
'7fd1b9749789bd139c132602a771a127ea0c76f403d1750e9636cd657cce017a'
|
396
|
+
),
|
397
|
+
},
|
398
|
+
)
|
399
|
+
|
400
|
+
FIGSHARE_22336594 = pooch.create(
|
401
|
+
path=pooch.os_cache('phasorpy'),
|
402
|
+
base_url=(
|
403
|
+
'https://github.com/phasorpy/phasorpy-data/raw/main/figshare_22336594'
|
404
|
+
if DATA_ON_GITHUB
|
405
|
+
else 'doi:10.6084/m9.figshare.22336594.v1'
|
406
|
+
),
|
407
|
+
env=ENV,
|
408
|
+
registry={
|
409
|
+
'FLIM_testdata.lif': (
|
410
|
+
'sha256:'
|
411
|
+
'902d8fa6cd39da7cf062b32d43aab518fa2a851eab72b4bd8b8eca1bad591850'
|
412
|
+
),
|
413
|
+
},
|
414
|
+
)
|
415
|
+
|
416
|
+
FIGSHARE_22336594_EXPORTED = pooch.create(
|
417
|
+
path=pooch.os_cache('phasorpy'),
|
418
|
+
base_url=(
|
419
|
+
'https://github.com/phasorpy/phasorpy-data/raw/main/figshare_22336594'
|
420
|
+
),
|
421
|
+
env=ENV,
|
422
|
+
registry={
|
423
|
+
'FLIM_testdata.lif.ptu': (
|
424
|
+
'sha256:'
|
425
|
+
'c85792b25d0b274f1484e490c99aa19052ab8e48e4e5022aabb1f218cd1123b6'
|
426
|
+
),
|
427
|
+
'FLIM_testdata.lif.ptu.zip': (
|
428
|
+
'sha256:'
|
429
|
+
'c5134c470f6a3e5cb21eabd538cbd5061d9911dad96d58e3a4040cfddadaef33'
|
430
|
+
),
|
431
|
+
'FLIM_testdata.xlef': (
|
432
|
+
'sha256:'
|
433
|
+
'7860ef0847dc9f5534895a9c11b979bb446f67382b577fe63fb166e281e5dc5e'
|
434
|
+
),
|
435
|
+
'FLIM_testdata.xlef.zip': (
|
436
|
+
'sha256:'
|
437
|
+
'ad0ad6389f38dcba6f9809b54934ef3f19da975d9dabeb4c3a248692b959b9cf'
|
438
|
+
),
|
439
|
+
'FLIM_testdata.lif.filtered.ptu': (
|
440
|
+
'sha256:'
|
441
|
+
'a00b84f626a39e79263322c60ae50b64163b36bb977ecc4dc54619097ba7f5b7'
|
442
|
+
),
|
443
|
+
'FLIM_testdata.lif.filtered.ptu.zip': (
|
444
|
+
'sha256:'
|
445
|
+
'717366b231213bfd6e295c3efb7bf1bcd90e720eb28aab3223376087172e93e5'
|
446
|
+
),
|
447
|
+
},
|
448
|
+
)
|
449
|
+
|
450
|
+
MISC = pooch.create(
|
451
|
+
path=pooch.os_cache('phasorpy'),
|
452
|
+
base_url='https://github.com/phasorpy/phasorpy-data/raw/main/misc',
|
453
|
+
env=ENV,
|
454
|
+
registry={
|
455
|
+
'NADHandSHG.ifli': (
|
456
|
+
'sha256:'
|
457
|
+
'dfa65952850b8a222258776a8a14eb1ab7e70ff5f62b58aa2214797c5921b4a3'
|
458
|
+
),
|
459
|
+
},
|
460
|
+
)
|
308
461
|
|
309
462
|
REPOSITORIES: dict[str, pooch.Pooch] = {
|
310
463
|
'tests': TESTS,
|
@@ -312,7 +465,13 @@ REPOSITORIES: dict[str, pooch.Pooch] = {
|
|
312
465
|
'flute': FLUTE,
|
313
466
|
'napari-flim-phasor-plotter': NAPARI_FLIM_PHASOR_PLOTTER,
|
314
467
|
'zenodo-13625087': ZENODO_13625087,
|
468
|
+
'zenodo-14860228': ZENODO_14860228,
|
469
|
+
'zenodo-14976703': ZENODO_14976703,
|
315
470
|
'convallaria-fbd': CONVALLARIA_FBD,
|
471
|
+
'flimlabs': FLIMLABS,
|
472
|
+
'figshare_22336594': FIGSHARE_22336594,
|
473
|
+
'figshare_22336594_exported': FIGSHARE_22336594_EXPORTED,
|
474
|
+
'misc': MISC,
|
316
475
|
}
|
317
476
|
"""Pooch repositories."""
|
318
477
|
|
@@ -325,19 +484,19 @@ def fetch(
|
|
325
484
|
) -> Any: # str | tuple[str, ...]
|
326
485
|
"""Return absolute path(s) to sample file(s) in local storage.
|
327
486
|
|
328
|
-
The files are downloaded from a remote repository if
|
329
|
-
|
487
|
+
The files are downloaded from a remote repository if not present in local
|
488
|
+
storage.
|
330
489
|
|
331
490
|
Parameters
|
332
491
|
----------
|
333
|
-
*args: str or iterable of str, optional
|
492
|
+
*args : str or iterable of str, optional
|
334
493
|
Name(s) of file(s) or repositories to fetch from local storage.
|
335
494
|
If omitted, return files in all repositories.
|
336
495
|
extract_dir : str or None, optional
|
337
496
|
Path, relative to cache location, where ZIP files will be unpacked.
|
338
497
|
return_scalar : bool, optional
|
339
498
|
If true (default), return single path as string, else tuple of string.
|
340
|
-
**kwargs
|
499
|
+
**kwargs
|
341
500
|
Additional arguments passed to ``pooch.fetch()``.
|
342
501
|
For example, ``progressbar=True``.
|
343
502
|
|