16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 | class CylindricArray:
def __init__(self, rust_obj: _CylindricArray):
self._rust_obj = rust_obj
def __repr__(self) -> str:
return f"CylindricArray({self._rust_obj.asarray()}, nrise={self.nrise})"
@property
def nrise(self) -> int:
"""The number of rise of the cylindric structure."""
return self._rust_obj.nrise()
def asarray(self, dtype=None) -> NDArray[np.float32]:
"""As a 2D numpy array."""
out = self._rust_obj.asarray()
if dtype is not None:
out = out.astype(dtype, copy=False)
return out
def as1d(self, dtype=None) -> NDArray[np.float32]:
out = self._rust_obj.as1d()
if dtype is not None:
out = out.astype(dtype, copy=False)
return out
def as_series(self, name: str = "", dtype=None) -> pl.Series:
if type(dtype) is type and dtype in pl.DataType:
pl_dtype = dtype
np_dtype = None
else:
pl_dtype = None
np_dtype = dtype
return pl.Series(name, self.as1d(np_dtype), dtype=pl_dtype)
def with_values(self, values: ArrayLike) -> Self:
return CylindricArray(
self._rust_obj.with_values(np.asarray(values, dtype=np.float32))
)
__array__ = asarray
@classmethod
def from_sequences(
cls, nth: ArrayLike, npf: ArrayLike, value: ArrayLike, nrise: int
) -> Self:
nth = np.asarray(nth, dtype=np.int32)
npf = np.asarray(npf, dtype=np.int32)
value = np.asarray(value, dtype=np.float32)
nrise = int(nrise)
return cls(_CylindricArray(nth, npf, value, nrise))
@classmethod
def zeros_like(self, df: pl.DataFrame, nrise: int) -> Self:
nth = df[Mole.nth].to_numpy()
npf = df[Mole.pf].to_numpy()
value = np.zeros(len(df), dtype=np.float32)
return CylindricArray.from_sequences(nth, npf, value, nrise)
@classmethod
def from_dataframe(self, df: pl.DataFrame, target: str, nrise: int) -> Self:
nth = df[Mole.nth].to_numpy()
npf = df[Mole.pf].to_numpy()
value = df[target].to_numpy()
return CylindricArray.from_sequences(nth, npf, value, nrise)
def convolve(self, kernel: ArrayLike) -> Self:
ker = np.asarray(kernel, dtype=np.float32)
return CylindricArray(self._rust_obj.convolve(ker))
def mean_filter(self, kernel: ArrayLike) -> Self:
ker = np.asarray(kernel, dtype=np.bool_)
return CylindricArray(self._rust_obj.mean_filter(ker))
def count_neighbors(self, kernel: ArrayLike) -> Self:
ker = np.asarray(kernel, dtype=np.bool_)
return CylindricArray(self._rust_obj.count_neighbors(ker))
def max_filter(self, kernel: ArrayLike) -> Self:
ker = np.asarray(kernel, dtype=np.bool_)
return CylindricArray(self._rust_obj.max_filter(ker))
def min_filter(self, kernel: ArrayLike) -> Self:
ker = np.asarray(kernel, dtype=np.bool_)
return CylindricArray(self._rust_obj.min_filter(ker))
def median_filter(self, kernel: ArrayLike) -> Self:
ker = np.asarray(kernel, dtype=np.bool_)
return CylindricArray(self._rust_obj.median_filter(ker))
def binarize(self, threshold: float) -> Self:
value = self.as1d()
new_value = value >= threshold
return self.with_values(new_value)
def label(self) -> Self:
return CylindricArray(self._rust_obj.label())
def __neg__(self) -> Self:
return self.with_values(-self.as1d())
@staticmethod
def _make_operator(op) -> Callable[[CylindricArray, Any], CylindricArray]:
def _method(self: CylindricArray, value) -> CylindricArray:
if isinstance(value, CylindricArray):
value = value.as1d()
return self.with_values(op(self.as1d(), value))
_method.__name__ = op.__name__
_method.__qualname__ = f"CylindricArray.{op.__name__}"
return _method
__eq__ = _make_operator(operator.__eq__)
__ne__ = _make_operator(operator.__ne__)
__lt__ = _make_operator(operator.__lt__)
__le__ = _make_operator(operator.__le__)
__gt__ = _make_operator(operator.__gt__)
__ge__ = _make_operator(operator.__ge__)
__add__ = _make_operator(operator.__add__)
__sub__ = _make_operator(operator.__sub__)
__mul__ = _make_operator(operator.__mul__)
__truediv__ = _make_operator(operator.__truediv__)
__pow__ = _make_operator(operator.__pow__)
__and__ = _make_operator(operator.__and__)
__or__ = _make_operator(operator.__or__)
__xor__ = _make_operator(operator.__xor__)
|