histoseg 0.1.7__py3-none-any.whl → 0.1.8.1__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.
- histoseg/_version.py +2 -2
- histoseg/geometry/__init__.py +5 -0
- histoseg/geometry/tissue_boundary.py +141 -0
- {histoseg-0.1.7.dist-info → histoseg-0.1.8.1.dist-info}/METADATA +1 -2
- {histoseg-0.1.7.dist-info → histoseg-0.1.8.1.dist-info}/RECORD +8 -7
- histoseg-0.1.7.dist-info/licenses/AUTHORS.rst +0 -14
- {histoseg-0.1.7.dist-info → histoseg-0.1.8.1.dist-info}/WHEEL +0 -0
- {histoseg-0.1.7.dist-info → histoseg-0.1.8.1.dist-info}/licenses/LICENSE +0 -0
- {histoseg-0.1.7.dist-info → histoseg-0.1.8.1.dist-info}/top_level.txt +0 -0
histoseg/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.8.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 8, 1)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from shapely.geometry import MultiPoint, Polygon, MultiPolygon
|
|
4
|
+
from shapely.ops import unary_union, triangulate
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _alpha_shape(points, alpha):
|
|
8
|
+
"""
|
|
9
|
+
Compute an alpha shape (concave hull) from a set of 2D points.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
points : np.ndarray of shape (n_points, 2)
|
|
14
|
+
alpha : float
|
|
15
|
+
|
|
16
|
+
Returns
|
|
17
|
+
-------
|
|
18
|
+
shapely.geometry.Polygon or MultiPolygon
|
|
19
|
+
"""
|
|
20
|
+
if len(points) < 4:
|
|
21
|
+
return MultiPoint(points).convex_hull
|
|
22
|
+
|
|
23
|
+
triangles = triangulate(MultiPoint(points))
|
|
24
|
+
kept = []
|
|
25
|
+
|
|
26
|
+
for tri in triangles:
|
|
27
|
+
coords = np.array(tri.exterior.coords[:3])
|
|
28
|
+
a, b, c = coords
|
|
29
|
+
|
|
30
|
+
side_lengths = [
|
|
31
|
+
np.linalg.norm(a - b),
|
|
32
|
+
np.linalg.norm(b - c),
|
|
33
|
+
np.linalg.norm(c - a),
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
s = sum(side_lengths) / 2.0
|
|
37
|
+
area_sq = (
|
|
38
|
+
s
|
|
39
|
+
* (s - side_lengths[0])
|
|
40
|
+
* (s - side_lengths[1])
|
|
41
|
+
* (s - side_lengths[2])
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
if area_sq <= 0:
|
|
45
|
+
continue
|
|
46
|
+
|
|
47
|
+
area = np.sqrt(area_sq)
|
|
48
|
+
circumradius = (
|
|
49
|
+
side_lengths[0] * side_lengths[1] * side_lengths[2]
|
|
50
|
+
) / (4.0 * area)
|
|
51
|
+
|
|
52
|
+
if circumradius < 1.0 / alpha:
|
|
53
|
+
kept.append(tri)
|
|
54
|
+
|
|
55
|
+
if not kept:
|
|
56
|
+
return MultiPoint(points).convex_hull
|
|
57
|
+
|
|
58
|
+
return unary_union(kept)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def generate_tissue_boundary(
|
|
62
|
+
cells_df,
|
|
63
|
+
x_col="x_centroid",
|
|
64
|
+
y_col="y_centroid",
|
|
65
|
+
method="alpha_shape",
|
|
66
|
+
alpha=0.05,
|
|
67
|
+
simplify_tolerance=None,
|
|
68
|
+
output_csv=None,
|
|
69
|
+
):
|
|
70
|
+
"""
|
|
71
|
+
Generate a tissue boundary polygon from cell spatial coordinates.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
cells_df : pandas.DataFrame
|
|
76
|
+
Cell-level table containing spatial coordinates.
|
|
77
|
+
x_col, y_col : str
|
|
78
|
+
Column names for x and y coordinates.
|
|
79
|
+
method : {"alpha_shape", "convex_hull"}
|
|
80
|
+
Geometry method for boundary estimation.
|
|
81
|
+
alpha : float
|
|
82
|
+
Alpha parameter for alpha-shape.
|
|
83
|
+
simplify_tolerance : float or None
|
|
84
|
+
Optional polygon simplification tolerance.
|
|
85
|
+
output_csv : str or Path or None
|
|
86
|
+
If provided, write boundary to CSV.
|
|
87
|
+
|
|
88
|
+
Returns
|
|
89
|
+
-------
|
|
90
|
+
pandas.DataFrame
|
|
91
|
+
Columns: ["x", "y", "order"]
|
|
92
|
+
"""
|
|
93
|
+
if x_col not in cells_df or y_col not in cells_df:
|
|
94
|
+
raise ValueError(
|
|
95
|
+
f"cells_df must contain columns '{x_col}' and '{y_col}'"
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
points = (
|
|
99
|
+
cells_df[[x_col, y_col]]
|
|
100
|
+
.dropna()
|
|
101
|
+
.to_numpy()
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if len(points) == 0:
|
|
105
|
+
raise ValueError("No valid spatial coordinates found.")
|
|
106
|
+
|
|
107
|
+
if method == "convex_hull":
|
|
108
|
+
polygon = MultiPoint(points).convex_hull
|
|
109
|
+
elif method == "alpha_shape":
|
|
110
|
+
polygon = _alpha_shape(points, alpha=alpha)
|
|
111
|
+
else:
|
|
112
|
+
raise ValueError(f"Unknown method: {method}")
|
|
113
|
+
|
|
114
|
+
if simplify_tolerance is not None:
|
|
115
|
+
polygon = polygon.simplify(simplify_tolerance)
|
|
116
|
+
|
|
117
|
+
# ------------------------------------------------------------------
|
|
118
|
+
# Normalize geometry:
|
|
119
|
+
# tissue boundary must be a single outer polygon
|
|
120
|
+
# (consistent with tissueboundary.txt behavior)
|
|
121
|
+
# ------------------------------------------------------------------
|
|
122
|
+
if isinstance(polygon, MultiPolygon):
|
|
123
|
+
polygon = max(polygon.geoms, key=lambda p: p.area)
|
|
124
|
+
|
|
125
|
+
if not isinstance(polygon, Polygon):
|
|
126
|
+
raise TypeError(
|
|
127
|
+
f"Expected Polygon after processing, got {type(polygon)}"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
x, y = polygon.exterior.coords.xy
|
|
131
|
+
|
|
132
|
+
boundary_df = pd.DataFrame({
|
|
133
|
+
"x": x,
|
|
134
|
+
"y": y,
|
|
135
|
+
"order": np.arange(len(x)),
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
if output_csv is not None:
|
|
139
|
+
boundary_df.to_csv(output_csv, index=False)
|
|
140
|
+
|
|
141
|
+
return boundary_df
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: histoseg
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8.1
|
|
4
4
|
Summary: ...
|
|
5
5
|
Author-email: Taobo Hu <taobo.hu@scilifelab.se>
|
|
6
6
|
License: Required Notice: Copyright (c) 2025 SPATHO AB.
|
|
@@ -86,7 +86,6 @@ Project-URL: Documentation, https://histoseg.readthedocs.io
|
|
|
86
86
|
Requires-Python: >=3.10
|
|
87
87
|
Description-Content-Type: text/markdown
|
|
88
88
|
License-File: LICENSE
|
|
89
|
-
License-File: AUTHORS.rst
|
|
90
89
|
Dynamic: license-file
|
|
91
90
|
|
|
92
91
|
<div align="center">
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
histoseg/__init__.py,sha256=ssVwpgspXb7TWi1aAbWYA82FBJhGZH1g-JIvosVocTM,982
|
|
2
|
-
histoseg/_version.py,sha256=
|
|
2
|
+
histoseg/_version.py,sha256=DceX3WwB1oE06QTAMXFaSlGTc9twNCVWkTErPbrlF7o,709
|
|
3
3
|
histoseg/contours/__init__.py,sha256=8YEy98MnGOhJg1BHkVZ_qPtTYUWPoIDAOT60F5EfHgY,32
|
|
4
4
|
histoseg/contours/pattern1_isoline.py,sha256=6JVL26O7AZ0s0YyloDoiUdIHTJ7jp6gEooFWnMoNhSw,19592
|
|
5
|
+
histoseg/geometry/__init__.py,sha256=5Aep5GBj2u4k2415QIECd0vK3y2eVBfQZRIskOgzb78,101
|
|
6
|
+
histoseg/geometry/tissue_boundary.py,sha256=-12lyNYI93JkNlBDT_Fv7SLAeTLKMZ9fPhqpSTowFz0,3680
|
|
5
7
|
histoseg/gui/__init__.py,sha256=SJvM-gRCwQ0X7fufPmdNO43X3wQvlnFHFmFNswt1hlw,133
|
|
6
8
|
histoseg/gui/gui_app.py,sha256=copFjJzMEeg2T4HV4--KHq9GG-v58xeW-eqRQ0-uJww,15259
|
|
7
9
|
histoseg/io/__init__.py,sha256=kH_F15ApTutYbEUGAkV9QxBv8Ho863xvWK0mRmKeOCA,27
|
|
8
10
|
histoseg/io/huggingface.py,sha256=YL_aXAXiHMMk6T6bqX-zPXFFChO83CVhTxI6mX52Z7g,2124
|
|
9
11
|
histoseg/sfplot/Searcher_Findee_Score.py,sha256=Y9UzWrqap029BOyOnFPklvK4v-2wm3r_PkmUh65DEqo,14951
|
|
10
|
-
histoseg-0.1.
|
|
11
|
-
histoseg-0.1.
|
|
12
|
-
histoseg-0.1.
|
|
13
|
-
histoseg-0.1.
|
|
14
|
-
histoseg-0.1.
|
|
15
|
-
histoseg-0.1.7.dist-info/RECORD,,
|
|
12
|
+
histoseg-0.1.8.1.dist-info/licenses/LICENSE,sha256=z7Ztufk460DPfU3rgZEstjCQK3EbwHbD4JSmF_7y0qA,4764
|
|
13
|
+
histoseg-0.1.8.1.dist-info/METADATA,sha256=LQR8kK-wQSM9bqc_8WM0SUmYXYGrsaoHB5_GBFeECSg,13192
|
|
14
|
+
histoseg-0.1.8.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
15
|
+
histoseg-0.1.8.1.dist-info/top_level.txt,sha256=dvphnIeqaZamvJULm-I5qztYoGO8WLLCY85z0xrXsb0,9
|
|
16
|
+
histoseg-0.1.8.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|