phasorpy 0.4__cp312-cp312-win_amd64.whl → 0.6__cp312-cp312-win_amd64.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/__init__.py +2 -3
- phasorpy/_phasorpy.cp312-win_amd64.pyd +0 -0
- phasorpy/_phasorpy.pyx +237 -51
- phasorpy/_utils.py +201 -7
- phasorpy/cli.py +58 -3
- phasorpy/cluster.py +206 -0
- phasorpy/color.py +16 -11
- phasorpy/components.py +240 -69
- phasorpy/conftest.py +2 -0
- phasorpy/cursors.py +9 -9
- phasorpy/datasets.py +129 -51
- phasorpy/experimental.py +312 -0
- phasorpy/io/__init__.py +137 -0
- phasorpy/io/_flimlabs.py +350 -0
- phasorpy/io/_leica.py +329 -0
- phasorpy/io/_ometiff.py +445 -0
- phasorpy/io/_other.py +782 -0
- phasorpy/io/_simfcs.py +627 -0
- phasorpy/phasor.py +572 -97
- phasorpy/plot/__init__.py +27 -0
- phasorpy/plot/_functions.py +717 -0
- phasorpy/plot/_lifetime_plots.py +553 -0
- phasorpy/plot/_phasorplot.py +1119 -0
- phasorpy/plot/_phasorplot_fret.py +559 -0
- phasorpy/utils.py +90 -297
- {phasorpy-0.4.dist-info → phasorpy-0.6.dist-info}/METADATA +11 -16
- phasorpy-0.6.dist-info/RECORD +34 -0
- {phasorpy-0.4.dist-info → phasorpy-0.6.dist-info}/WHEEL +1 -1
- phasorpy/_io.py +0 -2431
- phasorpy/io.py +0 -5
- phasorpy/plot.py +0 -2094
- phasorpy/version.py +0 -72
- phasorpy-0.4.dist-info/RECORD +0 -25
- {phasorpy-0.4.dist-info → phasorpy-0.6.dist-info}/entry_points.txt +0 -0
- {phasorpy-0.4.dist-info → phasorpy-0.6.dist-info/licenses}/LICENSE.txt +0 -0
- {phasorpy-0.4.dist-info → phasorpy-0.6.dist-info}/top_level.txt +0 -0
phasorpy/__init__.py
CHANGED
@@ -2,9 +2,8 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
__all__ = ['__version__'
|
5
|
+
__all__ = ['__version__']
|
6
6
|
|
7
|
-
from .version import __version__, versions
|
8
7
|
|
9
|
-
__version__ =
|
8
|
+
__version__ = '0.6'
|
10
9
|
"""PhasorPy version string."""
|
Binary file
|
phasorpy/_phasorpy.pyx
CHANGED
@@ -4,15 +4,10 @@
|
|
4
4
|
# cython: wraparound = False
|
5
5
|
# cython: cdivision = True
|
6
6
|
# cython: nonecheck = False
|
7
|
+
# cython: freethreading_compatible = True
|
7
8
|
|
8
9
|
"""Cython implementation of low-level functions for the PhasorPy library."""
|
9
10
|
|
10
|
-
# TODO: replace short with unsigned char when Cython supports it
|
11
|
-
# https://github.com/cython/cython/pull/6196#issuecomment-2209509572
|
12
|
-
|
13
|
-
# TODO: use fused return types for functions returning more than two items
|
14
|
-
# https://github.com/cython/cython/issues/6328
|
15
|
-
|
16
11
|
cimport cython
|
17
12
|
|
18
13
|
from cython.parallel import parallel, prange
|
@@ -55,6 +50,12 @@ ctypedef fused uint_t:
|
|
55
50
|
uint32_t
|
56
51
|
uint64_t
|
57
52
|
|
53
|
+
ctypedef fused int_t:
|
54
|
+
int8_t
|
55
|
+
int16_t
|
56
|
+
int32_t
|
57
|
+
int64_t
|
58
|
+
|
58
59
|
ctypedef fused signal_t:
|
59
60
|
uint8_t
|
60
61
|
uint16_t
|
@@ -451,7 +452,7 @@ cdef (double, double) _phasor_from_fret_donor(
|
|
451
452
|
double omega,
|
452
453
|
double donor_lifetime,
|
453
454
|
double fret_efficiency,
|
454
|
-
double
|
455
|
+
double donor_fretting,
|
455
456
|
double donor_background,
|
456
457
|
double background_real,
|
457
458
|
double background_imag,
|
@@ -471,16 +472,16 @@ cdef (double, double) _phasor_from_fret_donor(
|
|
471
472
|
elif fret_efficiency > 1.0:
|
472
473
|
fret_efficiency = 1.0
|
473
474
|
|
474
|
-
if
|
475
|
-
|
476
|
-
elif
|
477
|
-
|
475
|
+
if donor_fretting < 0.0:
|
476
|
+
donor_fretting = 0.0
|
477
|
+
elif donor_fretting > 1.0:
|
478
|
+
donor_fretting = 1.0
|
478
479
|
|
479
480
|
if donor_background < 0.0:
|
480
481
|
donor_background = 0.0
|
481
482
|
|
482
|
-
f_pure = 1.0 -
|
483
|
-
f_quenched = (1.0 - fret_efficiency) *
|
483
|
+
f_pure = 1.0 - donor_fretting
|
484
|
+
f_quenched = (1.0 - fret_efficiency) * donor_fretting
|
484
485
|
sum = f_pure + f_quenched + donor_background
|
485
486
|
if sum < 1e-9:
|
486
487
|
# no signal in donor channel
|
@@ -516,7 +517,7 @@ cdef (double, double) _phasor_from_fret_acceptor(
|
|
516
517
|
double donor_lifetime,
|
517
518
|
double acceptor_lifetime,
|
518
519
|
double fret_efficiency,
|
519
|
-
double
|
520
|
+
double donor_fretting,
|
520
521
|
double donor_bleedthrough,
|
521
522
|
double acceptor_bleedthrough,
|
522
523
|
double acceptor_background,
|
@@ -541,10 +542,10 @@ cdef (double, double) _phasor_from_fret_acceptor(
|
|
541
542
|
elif fret_efficiency > 1.0:
|
542
543
|
fret_efficiency = 1.0
|
543
544
|
|
544
|
-
if
|
545
|
-
|
546
|
-
elif
|
547
|
-
|
545
|
+
if donor_fretting < 0.0:
|
546
|
+
donor_fretting = 0.0
|
547
|
+
elif donor_fretting > 1.0:
|
548
|
+
donor_fretting = 1.0
|
548
549
|
|
549
550
|
if donor_bleedthrough < 0.0:
|
550
551
|
donor_bleedthrough = 0.0
|
@@ -575,7 +576,7 @@ cdef (double, double) _phasor_from_fret_acceptor(
|
|
575
576
|
quenched_imag,
|
576
577
|
1.0,
|
577
578
|
1.0 - fret_efficiency,
|
578
|
-
1.0 -
|
579
|
+
1.0 - donor_fretting
|
579
580
|
)
|
580
581
|
|
581
582
|
# phasor of acceptor at frequency
|
@@ -597,8 +598,8 @@ cdef (double, double) _phasor_from_fret_acceptor(
|
|
597
598
|
sensitized_imag = mod * sin(phi)
|
598
599
|
|
599
600
|
# weighted average
|
600
|
-
f_donor = donor_bleedthrough * (1.0 -
|
601
|
-
f_acceptor =
|
601
|
+
f_donor = donor_bleedthrough * (1.0 - donor_fretting * fret_efficiency)
|
602
|
+
f_acceptor = donor_fretting * fret_efficiency
|
602
603
|
sum = f_donor + f_acceptor + acceptor_bleedthrough + acceptor_background
|
603
604
|
if sum < 1e-9:
|
604
605
|
# no signal in acceptor channel
|
@@ -772,6 +773,33 @@ cdef (float_t, float_t) _phasor_from_apparent_lifetime(
|
|
772
773
|
return <float_t> (mod * cos(phi)), <float_t> (mod * sin(phi))
|
773
774
|
|
774
775
|
|
776
|
+
@cython.ufunc
|
777
|
+
cdef float_t _phasor_to_normal_lifetime(
|
778
|
+
float_t real,
|
779
|
+
float_t imag,
|
780
|
+
float_t omega,
|
781
|
+
) noexcept nogil:
|
782
|
+
"""Return normal lifetimes from phasor coordinates."""
|
783
|
+
cdef:
|
784
|
+
double taunorm = INFINITY
|
785
|
+
double t
|
786
|
+
|
787
|
+
if isnan(real) or isnan(imag):
|
788
|
+
return <float_t> NAN
|
789
|
+
|
790
|
+
omega *= omega
|
791
|
+
if omega > 0.0:
|
792
|
+
t = 0.5 * (1.0 + cos(atan2(imag, real - 0.5)))
|
793
|
+
if t <= 0.0:
|
794
|
+
taunorm = INFINITY
|
795
|
+
elif t > 1.0:
|
796
|
+
taunorm = NAN
|
797
|
+
else:
|
798
|
+
taunorm = sqrt((1.0 - t) / (omega * t))
|
799
|
+
|
800
|
+
return <float_t> taunorm
|
801
|
+
|
802
|
+
|
775
803
|
@cython.ufunc
|
776
804
|
cdef (float_t, float_t) _phasor_from_single_lifetime(
|
777
805
|
float_t lifetime,
|
@@ -919,7 +947,7 @@ cdef (float_t, float_t) _phasor_at_harmonic(
|
|
919
947
|
int harmonic,
|
920
948
|
int other_harmonic,
|
921
949
|
) noexcept nogil:
|
922
|
-
"""Return phasor coordinates on semicircle at other harmonic."""
|
950
|
+
"""Return phasor coordinates on universal semicircle at other harmonic."""
|
923
951
|
if isnan(real):
|
924
952
|
return <float_t> NAN, <float_t> NAN
|
925
953
|
|
@@ -982,7 +1010,7 @@ cdef (float_t, float_t) _phasor_divide(
|
|
982
1010
|
|
983
1011
|
|
984
1012
|
@cython.ufunc
|
985
|
-
cdef
|
1013
|
+
cdef unsigned char _is_inside_range(
|
986
1014
|
float_t x, # point
|
987
1015
|
float_t y,
|
988
1016
|
float_t xmin, # x range
|
@@ -1002,7 +1030,7 @@ cdef short _is_inside_range(
|
|
1002
1030
|
|
1003
1031
|
|
1004
1032
|
@cython.ufunc
|
1005
|
-
cdef
|
1033
|
+
cdef unsigned char _is_inside_rectangle(
|
1006
1034
|
float_t x, # point
|
1007
1035
|
float_t y,
|
1008
1036
|
float_t x0, # segment start
|
@@ -1044,7 +1072,7 @@ cdef short _is_inside_rectangle(
|
|
1044
1072
|
|
1045
1073
|
|
1046
1074
|
@cython.ufunc
|
1047
|
-
cdef
|
1075
|
+
cdef unsigned char _is_inside_polar_rectangle(
|
1048
1076
|
float_t x, # point
|
1049
1077
|
float_t y,
|
1050
1078
|
float_t angle_min, # phase, -pi to pi
|
@@ -1054,7 +1082,7 @@ cdef short _is_inside_polar_rectangle(
|
|
1054
1082
|
) noexcept nogil:
|
1055
1083
|
"""Return whether point is inside polar rectangle.
|
1056
1084
|
|
1057
|
-
Angles should be in range -pi
|
1085
|
+
Angles should be in range [-pi, pi], else performance is degraded.
|
1058
1086
|
|
1059
1087
|
"""
|
1060
1088
|
cdef:
|
@@ -1083,7 +1111,7 @@ cdef short _is_inside_polar_rectangle(
|
|
1083
1111
|
|
1084
1112
|
|
1085
1113
|
@cython.ufunc
|
1086
|
-
cdef
|
1114
|
+
cdef unsigned char _is_inside_circle(
|
1087
1115
|
float_t x, # point
|
1088
1116
|
float_t y,
|
1089
1117
|
float_t x0, # circle center
|
@@ -1100,7 +1128,7 @@ cdef short _is_inside_circle(
|
|
1100
1128
|
|
1101
1129
|
|
1102
1130
|
@cython.ufunc
|
1103
|
-
cdef
|
1131
|
+
cdef unsigned char _is_inside_ellipse(
|
1104
1132
|
float_t x, # point
|
1105
1133
|
float_t y,
|
1106
1134
|
float_t x0, # ellipse center
|
@@ -1135,7 +1163,7 @@ cdef short _is_inside_ellipse(
|
|
1135
1163
|
|
1136
1164
|
|
1137
1165
|
@cython.ufunc
|
1138
|
-
cdef
|
1166
|
+
cdef unsigned char _is_inside_ellipse_(
|
1139
1167
|
float_t x, # point
|
1140
1168
|
float_t y,
|
1141
1169
|
float_t x0, # ellipse center
|
@@ -1164,7 +1192,7 @@ cdef short _is_inside_ellipse_(
|
|
1164
1192
|
|
1165
1193
|
|
1166
1194
|
@cython.ufunc
|
1167
|
-
cdef
|
1195
|
+
cdef unsigned char _is_inside_stadium(
|
1168
1196
|
float_t x, # point
|
1169
1197
|
float_t y,
|
1170
1198
|
float_t x0, # line start
|
@@ -1210,7 +1238,45 @@ _is_near_segment = _is_inside_stadium
|
|
1210
1238
|
|
1211
1239
|
|
1212
1240
|
@cython.ufunc
|
1213
|
-
cdef
|
1241
|
+
cdef unsigned char _is_inside_semicircle(
|
1242
|
+
float_t x, # point
|
1243
|
+
float_t y,
|
1244
|
+
float_t r, # distance
|
1245
|
+
) noexcept nogil:
|
1246
|
+
"""Return whether point is inside universal semicircle."""
|
1247
|
+
if r < 0.0 or isnan(x) or isnan(y):
|
1248
|
+
return False
|
1249
|
+
if y < -r:
|
1250
|
+
return False
|
1251
|
+
if y <= 0.0:
|
1252
|
+
if x >= 0.0 and x <= 1.0:
|
1253
|
+
return True
|
1254
|
+
# near endpoints?
|
1255
|
+
if x > 0.5:
|
1256
|
+
x -= <float_t> 1.0
|
1257
|
+
return x * x + y * y <= r * r
|
1258
|
+
return hypot(x - 0.5, y) <= r + 0.5
|
1259
|
+
|
1260
|
+
|
1261
|
+
@cython.ufunc
|
1262
|
+
cdef unsigned char _is_near_semicircle(
|
1263
|
+
float_t x, # point
|
1264
|
+
float_t y,
|
1265
|
+
float_t r, # distance
|
1266
|
+
) noexcept nogil:
|
1267
|
+
"""Return whether point is near universal semicircle."""
|
1268
|
+
if r < 0.0 or isnan(x) or isnan(y):
|
1269
|
+
return False
|
1270
|
+
if y < 0.0:
|
1271
|
+
# near endpoints?
|
1272
|
+
if x > 0.5:
|
1273
|
+
x -= <float_t> 1.0
|
1274
|
+
return x * x + y * y <= r * r
|
1275
|
+
return fabs(hypot(x - 0.5, y) - 0.5) <= r
|
1276
|
+
|
1277
|
+
|
1278
|
+
@cython.ufunc
|
1279
|
+
cdef unsigned char _is_near_line(
|
1214
1280
|
float_t x, # point
|
1215
1281
|
float_t y,
|
1216
1282
|
float_t x0, # line start
|
@@ -1476,7 +1542,23 @@ cdef float_t _distance_from_line(
|
|
1476
1542
|
|
1477
1543
|
|
1478
1544
|
@cython.ufunc
|
1479
|
-
cdef
|
1545
|
+
cdef float_t _distance_from_semicircle(
|
1546
|
+
float_t x, # point
|
1547
|
+
float_t y,
|
1548
|
+
) noexcept nogil:
|
1549
|
+
"""Return distance from universal semicircle."""
|
1550
|
+
if isnan(x) or isnan(y):
|
1551
|
+
return NAN
|
1552
|
+
if y < 0.0:
|
1553
|
+
# distance to endpoints
|
1554
|
+
if x > 0.5:
|
1555
|
+
x -= <float_t> 1.0
|
1556
|
+
return <float_t> hypot(x, y)
|
1557
|
+
return <float_t> fabs(hypot(x - 0.5, y) - 0.5)
|
1558
|
+
|
1559
|
+
|
1560
|
+
@cython.ufunc
|
1561
|
+
cdef (float_t, float_t, float_t) _segment_direction_and_length(
|
1480
1562
|
float_t x0, # segment start
|
1481
1563
|
float_t y0,
|
1482
1564
|
float_t x1, # segment end
|
@@ -1500,7 +1582,7 @@ cdef (double, double, double) _segment_direction_and_length(
|
|
1500
1582
|
|
1501
1583
|
|
1502
1584
|
@cython.ufunc
|
1503
|
-
cdef (
|
1585
|
+
cdef (float_t, float_t, float_t, float_t) _intersect_circle_circle(
|
1504
1586
|
float_t x0, # circle 0
|
1505
1587
|
float_t y0,
|
1506
1588
|
float_t r0,
|
@@ -1538,15 +1620,15 @@ cdef (double, double, double, double) _intersection_circle_circle(
|
|
1538
1620
|
hd = sqrt(dd) / dr
|
1539
1621
|
ld = ll / dr
|
1540
1622
|
return (
|
1541
|
-
ld * dx + hd * dy + x0,
|
1542
|
-
ld * dy - hd * dx + y0,
|
1543
|
-
ld * dx - hd * dy + x0,
|
1544
|
-
ld * dy + hd * dx + y0,
|
1623
|
+
<float_t> (ld * dx + hd * dy + x0),
|
1624
|
+
<float_t> (ld * dy - hd * dx + y0),
|
1625
|
+
<float_t> (ld * dx - hd * dy + x0),
|
1626
|
+
<float_t> (ld * dy + hd * dx + y0),
|
1545
1627
|
)
|
1546
1628
|
|
1547
1629
|
|
1548
1630
|
@cython.ufunc
|
1549
|
-
cdef (
|
1631
|
+
cdef (float_t, float_t, float_t, float_t) _intersect_circle_line(
|
1550
1632
|
float_t x, # circle
|
1551
1633
|
float_t y,
|
1552
1634
|
float_t r,
|
@@ -1581,17 +1663,113 @@ cdef (double, double, double, double) _intersection_circle_line(
|
|
1581
1663
|
return NAN, NAN, NAN, NAN
|
1582
1664
|
rdd = sqrt(rdd)
|
1583
1665
|
return (
|
1584
|
-
x + (dd * dy + copysign(1.0, dy) * dx * rdd) / dr,
|
1585
|
-
y + (-dd * dx + fabs(dy) * rdd) / dr,
|
1586
|
-
x + (dd * dy - copysign(1.0, dy) * dx * rdd) / dr,
|
1587
|
-
y + (-dd * dx - fabs(dy) * rdd) / dr,
|
1666
|
+
x + <float_t> ((dd * dy + copysign(1.0, dy) * dx * rdd) / dr),
|
1667
|
+
y + <float_t> ((-dd * dx + fabs(dy) * rdd) / dr),
|
1668
|
+
x + <float_t> ((dd * dy - copysign(1.0, dy) * dx * rdd) / dr),
|
1669
|
+
y + <float_t> ((-dd * dx - fabs(dy) * rdd) / dr),
|
1588
1670
|
)
|
1589
1671
|
|
1590
1672
|
|
1673
|
+
@cython.ufunc
|
1674
|
+
cdef (float_t, float_t, float_t, float_t) _intersect_semicircle_line(
|
1675
|
+
float_t x0, # line start
|
1676
|
+
float_t y0,
|
1677
|
+
float_t x1, # line end
|
1678
|
+
float_t y1,
|
1679
|
+
) noexcept nogil:
|
1680
|
+
"""Return coordinates of intersections of line and universal semicircle."""
|
1681
|
+
cdef:
|
1682
|
+
double dx, dy, dr, dd, rdd
|
1683
|
+
|
1684
|
+
if isnan(x0) or isnan(x1) or isnan(y0) or isnan(y1):
|
1685
|
+
return NAN, NAN, NAN, NAN
|
1686
|
+
|
1687
|
+
dx = x1 - x0
|
1688
|
+
dy = y1 - y0
|
1689
|
+
dr = dx * dx + dy * dy
|
1690
|
+
dd = (x0 - 0.5) * y1 - (x1 - 0.5) * y0
|
1691
|
+
rdd = 0.25 * dr - dd * dd # discriminant
|
1692
|
+
if rdd < 0.0 or dr <= 0.0:
|
1693
|
+
# no intersection
|
1694
|
+
return NAN, NAN, NAN, NAN
|
1695
|
+
rdd = sqrt(rdd)
|
1696
|
+
x0 = <float_t> ((dd * dy - copysign(1.0, dy) * dx * rdd) / dr + 0.5)
|
1697
|
+
y0 = <float_t> ((-dd * dx - fabs(dy) * rdd) / dr)
|
1698
|
+
x1 = <float_t> ((dd * dy + copysign(1.0, dy) * dx * rdd) / dr + 0.5)
|
1699
|
+
y1 = <float_t> ((-dd * dx + fabs(dy) * rdd) / dr)
|
1700
|
+
if y0 < 0.0:
|
1701
|
+
x0 = NAN
|
1702
|
+
y0 = NAN
|
1703
|
+
if y1 < 0.0:
|
1704
|
+
x1 = NAN
|
1705
|
+
y1 = NAN
|
1706
|
+
return x0, y0, x1, y1
|
1707
|
+
|
1708
|
+
|
1709
|
+
def _nearest_neighbor_2d(
|
1710
|
+
int_t[::1] indices,
|
1711
|
+
const float_t[::1] x0,
|
1712
|
+
const float_t[::1] y0,
|
1713
|
+
const float_t[::1] x1,
|
1714
|
+
const float_t[::1] y1,
|
1715
|
+
const float_t distance_max,
|
1716
|
+
const int num_threads
|
1717
|
+
):
|
1718
|
+
"""Find nearest neighbors in 2D.
|
1719
|
+
|
1720
|
+
For each point in the first set of arrays (x0, y0) find the nearest point
|
1721
|
+
in the second set of arrays (x1, y1) and store the index of the nearest
|
1722
|
+
point in the second array in the indices array.
|
1723
|
+
If any coordinates are NaN, or the distance to the nearest point
|
1724
|
+
is larger than distance_max, the index is set to -1.
|
1725
|
+
|
1726
|
+
"""
|
1727
|
+
cdef:
|
1728
|
+
ssize_t i, j, index
|
1729
|
+
float_t x, y, dmin
|
1730
|
+
float_t distance_max_squared = distance_max * distance_max
|
1731
|
+
|
1732
|
+
if (
|
1733
|
+
indices.shape[0] != x0.shape[0]
|
1734
|
+
or x0.shape[0] != y0.shape[0]
|
1735
|
+
or x1.shape[0] != y1.shape[0]
|
1736
|
+
):
|
1737
|
+
raise ValueError('input array size mismatch')
|
1738
|
+
|
1739
|
+
with nogil, parallel(num_threads=num_threads):
|
1740
|
+
for i in prange(x0.shape[0]):
|
1741
|
+
x = x0[i]
|
1742
|
+
y = y0[i]
|
1743
|
+
if isnan(x) or isnan(y):
|
1744
|
+
indices[i] = -1
|
1745
|
+
continue
|
1746
|
+
index = -1
|
1747
|
+
dmin = INFINITY
|
1748
|
+
for j in range(x1.shape[0]):
|
1749
|
+
x = x0[i] - x1[j]
|
1750
|
+
y = y0[i] - y1[j]
|
1751
|
+
x = x * x + y * y
|
1752
|
+
if x < dmin:
|
1753
|
+
dmin = x
|
1754
|
+
index = j
|
1755
|
+
indices[i] = -1 if dmin > distance_max_squared else <int_t> index
|
1756
|
+
|
1757
|
+
|
1591
1758
|
###############################################################################
|
1592
1759
|
# Blend ufuncs
|
1593
1760
|
|
1594
1761
|
|
1762
|
+
@cython.ufunc
|
1763
|
+
cdef float_t _blend_and(
|
1764
|
+
float_t a, # base layer
|
1765
|
+
float_t b, # blend layer
|
1766
|
+
) noexcept nogil:
|
1767
|
+
"""Return blended layers using `and` mode."""
|
1768
|
+
if isnan(a):
|
1769
|
+
return NAN
|
1770
|
+
return b
|
1771
|
+
|
1772
|
+
|
1595
1773
|
@cython.ufunc
|
1596
1774
|
cdef float_t _blend_normal(
|
1597
1775
|
float_t a, # base layer
|
@@ -1665,7 +1843,7 @@ cdef float_t _blend_lighten(
|
|
1665
1843
|
|
1666
1844
|
|
1667
1845
|
@cython.ufunc
|
1668
|
-
cdef (
|
1846
|
+
cdef (float_t, float_t, float_t) _phasor_threshold_open(
|
1669
1847
|
float_t mean,
|
1670
1848
|
float_t real,
|
1671
1849
|
float_t imag,
|
@@ -1727,7 +1905,7 @@ cdef (double, double, double) _phasor_threshold_open(
|
|
1727
1905
|
|
1728
1906
|
|
1729
1907
|
@cython.ufunc
|
1730
|
-
cdef (
|
1908
|
+
cdef (float_t, float_t, float_t) _phasor_threshold_closed(
|
1731
1909
|
float_t mean,
|
1732
1910
|
float_t real,
|
1733
1911
|
float_t imag,
|
@@ -1789,7 +1967,7 @@ cdef (double, double, double) _phasor_threshold_closed(
|
|
1789
1967
|
|
1790
1968
|
|
1791
1969
|
@cython.ufunc
|
1792
|
-
cdef (
|
1970
|
+
cdef (float_t, float_t, float_t) _phasor_threshold_mean_open(
|
1793
1971
|
float_t mean,
|
1794
1972
|
float_t real,
|
1795
1973
|
float_t imag,
|
@@ -1809,7 +1987,7 @@ cdef (double, double, double) _phasor_threshold_mean_open(
|
|
1809
1987
|
|
1810
1988
|
|
1811
1989
|
@cython.ufunc
|
1812
|
-
cdef (
|
1990
|
+
cdef (float_t, float_t, float_t) _phasor_threshold_mean_closed(
|
1813
1991
|
float_t mean,
|
1814
1992
|
float_t real,
|
1815
1993
|
float_t imag,
|
@@ -1829,7 +2007,7 @@ cdef (double, double, double) _phasor_threshold_mean_closed(
|
|
1829
2007
|
|
1830
2008
|
|
1831
2009
|
@cython.ufunc
|
1832
|
-
cdef (
|
2010
|
+
cdef (float_t, float_t, float_t) _phasor_threshold_nan(
|
1833
2011
|
float_t mean,
|
1834
2012
|
float_t real,
|
1835
2013
|
float_t imag,
|
@@ -2171,6 +2349,7 @@ def _median_filter_2d(
|
|
2171
2349
|
# Decoder functions
|
2172
2350
|
|
2173
2351
|
|
2352
|
+
@cython.boundscheck(True)
|
2174
2353
|
def _flimlabs_signal(
|
2175
2354
|
uint_t[:, :, ::] signal, # channel, pixel, bin
|
2176
2355
|
list data, # list[list[list[[int, int]]]]
|
@@ -2178,6 +2357,7 @@ def _flimlabs_signal(
|
|
2178
2357
|
):
|
2179
2358
|
"""Return TCSPC histogram image from FLIM LABS JSON intensity data."""
|
2180
2359
|
cdef:
|
2360
|
+
uint_t[::] signal_
|
2181
2361
|
list channels, pixels
|
2182
2362
|
ssize_t c, i, h, count
|
2183
2363
|
|
@@ -2186,18 +2366,21 @@ def _flimlabs_signal(
|
|
2186
2366
|
for channels in data:
|
2187
2367
|
i = 0
|
2188
2368
|
for pixels in channels:
|
2369
|
+
signal_ = signal[c, i]
|
2189
2370
|
for h, count in pixels:
|
2190
|
-
|
2371
|
+
signal_[h] = <uint_t> count
|
2191
2372
|
i += 1
|
2192
2373
|
c += 1
|
2193
2374
|
else:
|
2194
2375
|
i = 0
|
2195
2376
|
for pixels in data[channel]:
|
2377
|
+
signal_ = signal[0, i]
|
2196
2378
|
for h, count in pixels:
|
2197
|
-
|
2379
|
+
signal_[h] = <uint_t> count
|
2198
2380
|
i += 1
|
2199
2381
|
|
2200
2382
|
|
2383
|
+
@cython.boundscheck(True)
|
2201
2384
|
def _flimlabs_mean(
|
2202
2385
|
float_t[:, ::] mean, # channel, pixel
|
2203
2386
|
list data, # list[list[list[[int, int]]]]
|
@@ -2205,6 +2388,7 @@ def _flimlabs_mean(
|
|
2205
2388
|
):
|
2206
2389
|
"""Return mean intensity image from FLIM LABS JSON intensity data."""
|
2207
2390
|
cdef:
|
2391
|
+
float_t[::] mean_
|
2208
2392
|
list channels, pixels
|
2209
2393
|
ssize_t c, i, h, count
|
2210
2394
|
double sum
|
@@ -2212,19 +2396,21 @@ def _flimlabs_mean(
|
|
2212
2396
|
if channel < 0:
|
2213
2397
|
c = 0
|
2214
2398
|
for channels in data:
|
2399
|
+
mean_ = mean[c]
|
2215
2400
|
i = 0
|
2216
2401
|
for pixels in channels:
|
2217
2402
|
sum = 0.0
|
2218
2403
|
for h, count in pixels:
|
2219
2404
|
sum += <double> count
|
2220
|
-
|
2405
|
+
mean_[i] = <float_t> (sum / 256.0)
|
2221
2406
|
i += 1
|
2222
2407
|
c += 1
|
2223
2408
|
else:
|
2224
2409
|
i = 0
|
2410
|
+
mean_ = mean[0]
|
2225
2411
|
for pixels in data[channel]:
|
2226
2412
|
sum = 0.0
|
2227
2413
|
for h, count in pixels:
|
2228
2414
|
sum += <double> count
|
2229
|
-
|
2415
|
+
mean_[i] = <float_t> (sum / 256.0)
|
2230
2416
|
i += 1
|