dsa-helpers 1.0.7.dev0__tar.gz → 1.0.8.dev0__tar.gz

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.
Files changed (50) hide show
  1. {dsa_helpers-1.0.7.dev0/dsa_helpers.egg-info → dsa_helpers-1.0.8.dev0}/PKG-INFO +1 -1
  2. dsa_helpers-1.0.8.dev0/dsa_helpers/gpd_utils.py +172 -0
  3. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0/dsa_helpers.egg-info}/PKG-INFO +1 -1
  4. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers.egg-info/SOURCES.txt +1 -0
  5. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/pyproject.toml +1 -1
  6. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/.gitignore +0 -0
  7. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/.readthedocs.yaml +0 -0
  8. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/LICENSE +0 -0
  9. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/README.md +0 -0
  10. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/app.py +0 -0
  11. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/docs/requirements.txt +0 -0
  12. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/docs/source/conf.py +0 -0
  13. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/docs/source/index.rst +0 -0
  14. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/__init__.py +0 -0
  15. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/cli_utils.py +0 -0
  16. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/dash/__init__.py +0 -0
  17. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/dash/dash_paperdragon_utils.py +0 -0
  18. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/dash/header.py +0 -0
  19. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/dash/header_callbacks.py +0 -0
  20. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/girder_utils.py +0 -0
  21. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/image_utils.py +0 -0
  22. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/imread.py +0 -0
  23. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/imwrite.py +0 -0
  24. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/__init__.py +0 -0
  25. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/callbacks.py +0 -0
  26. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/datasets/SegFormerSegmentationDataset.py +0 -0
  27. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/datasets/__init__.py +0 -0
  28. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/datasets/utils.py +0 -0
  29. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/evaluate.py +0 -0
  30. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/metrics.py +0 -0
  31. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/object_detection/__init__.py +0 -0
  32. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/object_detection/get_pearce_roi_images.py +0 -0
  33. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/object_detection/tile_image.py +0 -0
  34. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/object_detection/utils.py +0 -0
  35. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/segformer_semantic_segmentation/__init__.py +0 -0
  36. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/segformer_semantic_segmentation/inference.py +0 -0
  37. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/transforms/__init__.py +0 -0
  38. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/ml/transforms/segformer_transforms.py +0 -0
  39. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/mongo_utils.py +0 -0
  40. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/tile_utils.py +0 -0
  41. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/tiling.py +0 -0
  42. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers/utils.py +0 -0
  43. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers.egg-info/dependency_links.txt +0 -0
  44. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers.egg-info/requires.txt +0 -0
  45. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/dsa_helpers.egg-info/top_level.txt +0 -0
  46. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/setup.cfg +0 -0
  47. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/tests/app/Dockerfile +0 -0
  48. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/tests/app/app.py +0 -0
  49. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/tests/docker-compose.yaml +0 -0
  50. {dsa_helpers-1.0.7.dev0 → dsa_helpers-1.0.8.dev0}/tests/test.ipynb +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dsa_helpers
3
- Version: 1.0.7.dev0
3
+ Version: 1.0.8.dev0
4
4
  Summary: Utility functions for working with the DSA girder client.
5
5
  Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
6
6
  Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
@@ -0,0 +1,172 @@
1
+ """
2
+ Utility functions for working with GeoPandas.
3
+
4
+ """
5
+
6
+ import geopandas as gpd
7
+ from shapely.geometry import Polygon
8
+
9
+ import matplotlib.patches as mpatches
10
+ import matplotlib.pyplot as plt
11
+
12
+
13
+ def count_polygon_points(polygon: Polygon) -> int:
14
+ """
15
+ Count the total number of points in a Shapely polygon, including
16
+ exterior and interior rings.
17
+
18
+ Args:
19
+ polygon (shapely.geometry.Polygon): A Shapely polygon object.
20
+
21
+ Returns:
22
+ int: The total number of points in the polygon.
23
+
24
+ """
25
+ # Count exterior points.
26
+ exterior_points = len(polygon.exterior.coords)
27
+
28
+ # Count interior points (holes).
29
+ interior_points = sum(
30
+ len(interior.coords) for interior in polygon.interiors
31
+ )
32
+
33
+ # Total points.
34
+ return exterior_points + interior_points
35
+
36
+
37
+ def total_points_in_gdf(gdf: gpd.GeoDataFrame) -> int:
38
+ """
39
+ Calculate the total number of points in all polygons in a GeoDataFrame.
40
+
41
+ Args:
42
+ gdf (geopandas.GeoDataFrame): GeoDataFrame containing polygons.
43
+
44
+ Returns:
45
+ int: The total number of points in all polygons.
46
+
47
+ """
48
+ return int(gdf.geometry.apply(count_polygon_points).sum())
49
+
50
+
51
+ def plot_gdf(
52
+ gdf: gpd.GeoDataFrame,
53
+ figsize: int | tuple[int, int] | None = None,
54
+ label2color: dict | None = None,
55
+ ):
56
+ """Plot a geopandas dataframe.
57
+
58
+ Args:
59
+ gdf (geopandas.GeoDataFrame): A GeoDataFrame containing
60
+ polygons. Must have a 'label' column.
61
+ figsize (int | tuple[int, int] | None): The size of the figure.
62
+ If None, the figure size will be (5, 5).
63
+ label2color (dict | None): A dictionary mapping labels to
64
+ colors. If None then a legend will not be included and the
65
+ colors will be random. Colors should be an accepted
66
+ matplotlib color.
67
+
68
+ """
69
+ if figsize is None:
70
+ figsize = (5, 5)
71
+ elif isinstance(figsize, int):
72
+ figsize = (figsize, figsize)
73
+
74
+ gdf = gdf.copy()
75
+
76
+ # Blow up any multi-polygons.
77
+ gdf = gdf.explode(index_parts=False).reset_index(drop=True)
78
+
79
+ total_points = total_points_in_gdf(gdf)
80
+
81
+ if label2color is not None:
82
+ gdf["color"] = gdf["label"].map(label2color)
83
+
84
+ # Remove rows where color is nan.
85
+ gdf = gdf.dropna(subset=["color"])
86
+
87
+ # # Create the plot
88
+ ax = plt.subplots(figsize=figsize)[1]
89
+ gdf.plot(color=gdf["color"], ax=ax)
90
+
91
+ if label2color is not None:
92
+ # Add legend.
93
+ handles = [
94
+ mpatches.Patch(color=color, label=key)
95
+ for key, color in label2color.items()
96
+ ]
97
+
98
+ ax.legend(
99
+ handles=handles,
100
+ title="Legend",
101
+ loc="upper left",
102
+ bbox_to_anchor=(
103
+ 1.02,
104
+ 1,
105
+ ), # x > 1 pushes it to the right, y = 1 keeps it top-aligned
106
+ borderaxespad=0,
107
+ )
108
+ plt.title(f"Total points: {total_points:,}")
109
+ plt.show()
110
+
111
+
112
+ def remove_gdf_overlaps(
113
+ gdf: gpd.GeoDataFrame,
114
+ columns: str | list[str],
115
+ ascending: bool | list[bool] = True,
116
+ is_notebook: bool = False,
117
+ ) -> gpd.GeoDataFrame:
118
+ """Remove overlaps from a GeoDataFrame.
119
+
120
+ Args:
121
+ gdf (geopandas.GeoDataFrame): The GeoDataFrame to remove
122
+ overlaps from.
123
+ columns (str | list[str]): The columns to sort dataframe by. The
124
+ order determines the order of removal overlapping polygon
125
+ regions.
126
+ ascending (bool): Whether to remove overlaps in ascending order.
127
+ is_notebook (bool): Switch which tqdm bar to use. Default is
128
+ False, which uses the terminal progress bar.
129
+
130
+ Returns:
131
+ gpd.GeoDataFrame: The GeoDataFrame with overlaps removed.
132
+
133
+ """
134
+ if isinstance(columns, str):
135
+ columns = [columns]
136
+
137
+ if isinstance(ascending, bool):
138
+ ascending = [ascending] * len(columns)
139
+
140
+ # Remove multi-polygons.
141
+ gdf = gdf.explode(index_parts=False).reset_index(drop=True)
142
+
143
+ # Sort the GeoDataFrame by the columns and ascending order.
144
+ gdf = gdf.sort_values(by=columns, ascending=ascending).reset_index(
145
+ drop=True
146
+ )
147
+
148
+ if is_notebook:
149
+ from tqdm.notebook import tqdm
150
+ else:
151
+ from tqdm import tqdm
152
+
153
+ # Loop through each row in the GeoDataFrame.
154
+ for i, row in tqdm(gdf.iterrows(), total=len(gdf)):
155
+ # Check overlap with all following rows.
156
+ other_gdf = gdf[i + 1 :]
157
+
158
+ if len(other_gdf):
159
+ # Get the rows that overlap.
160
+ overlap = row.geometry.overlaps(other_gdf.geometry)
161
+
162
+ # Get the rows that overlap.
163
+ other_rows = other_gdf[overlap]
164
+
165
+ other_gdf.loc[:, "geometry"] = other_gdf.geometry.difference(
166
+ row.geometry
167
+ )
168
+
169
+ # This could have created multiple polygons, explode them.
170
+ gdf = gdf.explode(index_parts=False).reset_index(drop=True)
171
+
172
+ return gdf
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dsa_helpers
3
- Version: 1.0.7.dev0
3
+ Version: 1.0.8.dev0
4
4
  Summary: Utility functions for working with the DSA girder client.
5
5
  Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
6
6
  Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
@@ -10,6 +10,7 @@ docs/source/index.rst
10
10
  dsa_helpers/__init__.py
11
11
  dsa_helpers/cli_utils.py
12
12
  dsa_helpers/girder_utils.py
13
+ dsa_helpers/gpd_utils.py
13
14
  dsa_helpers/image_utils.py
14
15
  dsa_helpers/imread.py
15
16
  dsa_helpers/imwrite.py
@@ -35,7 +35,7 @@ classifiers = [
35
35
  "License :: OSI Approved :: MIT License",
36
36
  ]
37
37
  keywords = ["dsa", "girder", "girder_client"]
38
- version = "v1.0.7.dev0"
38
+ version = "v1.0.8.dev0"
39
39
 
40
40
  [project.urls]
41
41
  Repository = "https://github.com/Gutman-Lab/dsa-python-utils"