copick-utils 0.6.1__py3-none-any.whl → 1.0.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.
- copick_utils/__init__.py +1 -1
- copick_utils/cli/__init__.py +33 -0
- copick_utils/cli/clipmesh.py +161 -0
- copick_utils/cli/clippicks.py +154 -0
- copick_utils/cli/clipseg.py +163 -0
- copick_utils/cli/conversion_commands.py +32 -0
- copick_utils/cli/enclosed.py +191 -0
- copick_utils/cli/filter_components.py +166 -0
- copick_utils/cli/fit_spline.py +191 -0
- copick_utils/cli/hull.py +138 -0
- copick_utils/cli/input_output_selection.py +76 -0
- copick_utils/cli/logical_commands.py +29 -0
- copick_utils/cli/mesh2picks.py +170 -0
- copick_utils/cli/mesh2seg.py +167 -0
- copick_utils/cli/meshop.py +262 -0
- copick_utils/cli/picks2ellipsoid.py +171 -0
- copick_utils/cli/picks2mesh.py +181 -0
- copick_utils/cli/picks2plane.py +156 -0
- copick_utils/cli/picks2seg.py +134 -0
- copick_utils/cli/picks2sphere.py +170 -0
- copick_utils/cli/picks2surface.py +164 -0
- copick_utils/cli/picksin.py +146 -0
- copick_utils/cli/picksout.py +148 -0
- copick_utils/cli/processing_commands.py +18 -0
- copick_utils/cli/seg2mesh.py +135 -0
- copick_utils/cli/seg2picks.py +128 -0
- copick_utils/cli/segop.py +248 -0
- copick_utils/cli/separate_components.py +155 -0
- copick_utils/cli/skeletonize.py +164 -0
- copick_utils/cli/util.py +580 -0
- copick_utils/cli/validbox.py +155 -0
- copick_utils/converters/__init__.py +35 -0
- copick_utils/converters/converter_common.py +543 -0
- copick_utils/converters/ellipsoid_from_picks.py +335 -0
- copick_utils/converters/lazy_converter.py +576 -0
- copick_utils/converters/mesh_from_picks.py +209 -0
- copick_utils/converters/mesh_from_segmentation.py +119 -0
- copick_utils/converters/picks_from_mesh.py +542 -0
- copick_utils/converters/picks_from_segmentation.py +168 -0
- copick_utils/converters/plane_from_picks.py +251 -0
- copick_utils/converters/segmentation_from_mesh.py +291 -0
- copick_utils/{segmentation → converters}/segmentation_from_picks.py +123 -13
- copick_utils/converters/sphere_from_picks.py +306 -0
- copick_utils/converters/surface_from_picks.py +337 -0
- copick_utils/logical/__init__.py +43 -0
- copick_utils/logical/distance_operations.py +604 -0
- copick_utils/logical/enclosed_operations.py +222 -0
- copick_utils/logical/mesh_operations.py +443 -0
- copick_utils/logical/point_operations.py +303 -0
- copick_utils/logical/segmentation_operations.py +399 -0
- copick_utils/process/__init__.py +47 -0
- copick_utils/process/connected_components.py +360 -0
- copick_utils/process/filter_components.py +306 -0
- copick_utils/process/hull.py +106 -0
- copick_utils/process/skeletonize.py +326 -0
- copick_utils/process/spline_fitting.py +648 -0
- copick_utils/process/validbox.py +333 -0
- copick_utils/util/__init__.py +6 -0
- copick_utils/util/config_models.py +614 -0
- {copick_utils-0.6.1.dist-info → copick_utils-1.0.1.dist-info}/METADATA +15 -2
- copick_utils-1.0.1.dist-info/RECORD +71 -0
- {copick_utils-0.6.1.dist-info → copick_utils-1.0.1.dist-info}/WHEEL +1 -1
- copick_utils-1.0.1.dist-info/entry_points.txt +29 -0
- copick_utils/segmentation/picks_from_segmentation.py +0 -81
- copick_utils-0.6.1.dist-info/RECORD +0 -14
- /copick_utils/{segmentation → io}/__init__.py +0 -0
- {copick_utils-0.6.1.dist-info → copick_utils-1.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Segmentation processing utilities for copick."""
|
|
2
|
+
|
|
3
|
+
from .connected_components import (
|
|
4
|
+
extract_individual_components,
|
|
5
|
+
print_component_stats,
|
|
6
|
+
separate_components_batch,
|
|
7
|
+
separate_connected_components_3d,
|
|
8
|
+
separate_segmentation_components,
|
|
9
|
+
)
|
|
10
|
+
from .skeletonize import (
|
|
11
|
+
TubeSkeletonizer3D,
|
|
12
|
+
find_matching_segmentations,
|
|
13
|
+
skeletonize_batch,
|
|
14
|
+
skeletonize_segmentation,
|
|
15
|
+
)
|
|
16
|
+
from .spline_fitting import (
|
|
17
|
+
SkeletonSplineFitter,
|
|
18
|
+
find_matching_segmentations_for_spline,
|
|
19
|
+
fit_spline_batch,
|
|
20
|
+
fit_spline_to_segmentation,
|
|
21
|
+
fit_spline_to_skeleton,
|
|
22
|
+
)
|
|
23
|
+
from .validbox import (
|
|
24
|
+
create_validbox_mesh,
|
|
25
|
+
generate_validbox,
|
|
26
|
+
validbox_batch,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"separate_connected_components_3d",
|
|
31
|
+
"extract_individual_components",
|
|
32
|
+
"print_component_stats",
|
|
33
|
+
"separate_segmentation_components",
|
|
34
|
+
"separate_components_batch",
|
|
35
|
+
"TubeSkeletonizer3D",
|
|
36
|
+
"skeletonize_segmentation",
|
|
37
|
+
"find_matching_segmentations",
|
|
38
|
+
"skeletonize_batch",
|
|
39
|
+
"SkeletonSplineFitter",
|
|
40
|
+
"fit_spline_to_skeleton",
|
|
41
|
+
"fit_spline_to_segmentation",
|
|
42
|
+
"find_matching_segmentations_for_spline",
|
|
43
|
+
"fit_spline_batch",
|
|
44
|
+
"create_validbox_mesh",
|
|
45
|
+
"generate_validbox",
|
|
46
|
+
"validbox_batch",
|
|
47
|
+
]
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
"""Connected components processing for segmentation volumes."""
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from scipy import ndimage
|
|
7
|
+
from skimage import measure
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from copick.models import CopickRoot, CopickRun, CopickSegmentation
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def separate_connected_components_3d(
|
|
14
|
+
volume: np.ndarray,
|
|
15
|
+
voxel_spacing: float,
|
|
16
|
+
connectivity: Union[int, str] = "all",
|
|
17
|
+
min_size: Optional[float] = None,
|
|
18
|
+
) -> Tuple[np.ndarray, int, Dict[int, Dict[str, Any]]]:
|
|
19
|
+
"""
|
|
20
|
+
Separate connected components in a 3D binary or labeled volume.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
volume: 3D binary or labeled segmentation volume
|
|
24
|
+
voxel_spacing: Voxel spacing in angstroms
|
|
25
|
+
connectivity: Connectivity for connected components (default: "all")
|
|
26
|
+
String format: "face" (6-connected), "face-edge" (18-connected), "all" (26-connected)
|
|
27
|
+
Legacy int format: 6, 18, or 26 (for backward compatibility)
|
|
28
|
+
min_size: Minimum component volume in cubic angstroms (ų) to keep (None = keep all)
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Tuple of (labeled_volume, num_components, component_info):
|
|
32
|
+
- labeled_volume: Volume with each connected component labeled with unique integer
|
|
33
|
+
- num_components: Number of connected components found
|
|
34
|
+
- component_info: Dictionary with information about each component
|
|
35
|
+
"""
|
|
36
|
+
# Convert to binary if not already
|
|
37
|
+
binary_volume = volume > 0 if volume.dtype != bool else volume.copy()
|
|
38
|
+
|
|
39
|
+
# Map connectivity to integer (support both string and legacy int format)
|
|
40
|
+
if isinstance(connectivity, str):
|
|
41
|
+
connectivity_map = {
|
|
42
|
+
"face": 6,
|
|
43
|
+
"face-edge": 18,
|
|
44
|
+
"all": 26,
|
|
45
|
+
}
|
|
46
|
+
connectivity_int = connectivity_map.get(connectivity, 26)
|
|
47
|
+
else:
|
|
48
|
+
connectivity_int = connectivity
|
|
49
|
+
|
|
50
|
+
# Define connectivity structure
|
|
51
|
+
if connectivity_int == 6:
|
|
52
|
+
structure = ndimage.generate_binary_structure(3, 1) # faces only
|
|
53
|
+
elif connectivity_int == 18:
|
|
54
|
+
structure = ndimage.generate_binary_structure(3, 2) # faces + edges
|
|
55
|
+
elif connectivity_int == 26:
|
|
56
|
+
structure = ndimage.generate_binary_structure(3, 3) # all neighbors
|
|
57
|
+
else:
|
|
58
|
+
raise ValueError("Connectivity must be 6, 18, or 26 (or 'face', 'face-edge', 'all')")
|
|
59
|
+
|
|
60
|
+
# Label connected components
|
|
61
|
+
labeled_volume, num_components = ndimage.label(binary_volume, structure=structure)
|
|
62
|
+
|
|
63
|
+
print(f"Found {num_components} connected components")
|
|
64
|
+
|
|
65
|
+
# Get component properties
|
|
66
|
+
component_info = {}
|
|
67
|
+
props = measure.regionprops(labeled_volume)
|
|
68
|
+
|
|
69
|
+
print(f"Found {len(props)} connected components")
|
|
70
|
+
|
|
71
|
+
# Calculate voxel volume in cubic angstroms
|
|
72
|
+
voxel_volume = voxel_spacing**3
|
|
73
|
+
|
|
74
|
+
# Filter by size if specified
|
|
75
|
+
if min_size is not None and min_size > 0:
|
|
76
|
+
for prop in props:
|
|
77
|
+
component_volume = prop.area * voxel_volume
|
|
78
|
+
if component_volume < min_size:
|
|
79
|
+
labeled_volume[labeled_volume == prop.label] = 0
|
|
80
|
+
|
|
81
|
+
# Relabel after filtering
|
|
82
|
+
labeled_volume, num_components = ndimage.label(labeled_volume > 0, structure=structure)
|
|
83
|
+
props = measure.regionprops(labeled_volume)
|
|
84
|
+
print(f"After filtering by size (min={min_size} ų): {num_components} components")
|
|
85
|
+
|
|
86
|
+
# Store component information
|
|
87
|
+
for _i, prop in enumerate(props, 1):
|
|
88
|
+
component_info[prop.label] = {
|
|
89
|
+
"volume": prop.area, # number of voxels
|
|
90
|
+
"centroid": prop.centroid,
|
|
91
|
+
"bbox": prop.bbox, # (min_z, min_y, min_x, max_z, max_y, max_x)
|
|
92
|
+
"extent": prop.extent, # ratio of component area to bounding box area
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return labeled_volume, num_components, component_info
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def extract_individual_components(labeled_volume: np.ndarray) -> List[np.ndarray]:
|
|
99
|
+
"""
|
|
100
|
+
Extract each connected component as a separate binary volume.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
labeled_volume: Volume with labeled connected components
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
List of binary volumes, each containing one component
|
|
107
|
+
"""
|
|
108
|
+
unique_labels = np.unique(labeled_volume)
|
|
109
|
+
unique_labels = unique_labels[unique_labels > 0] # exclude background (0)
|
|
110
|
+
|
|
111
|
+
components = []
|
|
112
|
+
for label in unique_labels:
|
|
113
|
+
component = (labeled_volume == label).astype(np.uint8)
|
|
114
|
+
components.append(component)
|
|
115
|
+
|
|
116
|
+
return components
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def print_component_stats(component_info: Dict[int, Dict[str, Any]]) -> None:
|
|
120
|
+
"""Print statistics about connected components."""
|
|
121
|
+
print("\nComponent Statistics:")
|
|
122
|
+
print("-" * 60)
|
|
123
|
+
print(f"{'Label':<8} {'Volume':<10} {'Centroid (z,y,x)':<25} {'Extent':<10}")
|
|
124
|
+
print("-" * 60)
|
|
125
|
+
|
|
126
|
+
for label, info in component_info.items():
|
|
127
|
+
centroid_str = f"({info['centroid'][0]:.1f},{info['centroid'][1]:.1f},{info['centroid'][2]:.1f})"
|
|
128
|
+
print(f"{label:<8} {info['volume']:<10} {centroid_str:<25} {info['extent']:<10.3f}")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def separate_segmentation_components(
|
|
132
|
+
segmentation: "CopickSegmentation",
|
|
133
|
+
connectivity: Union[int, str] = "all",
|
|
134
|
+
min_size: Optional[float] = None,
|
|
135
|
+
session_id_template: str = "inst-{instance_id}",
|
|
136
|
+
output_user_id: str = "components",
|
|
137
|
+
multilabel: bool = True,
|
|
138
|
+
session_id_prefix: str = None, # Deprecated, kept for backward compatibility
|
|
139
|
+
) -> List["CopickSegmentation"]:
|
|
140
|
+
"""
|
|
141
|
+
Separate connected components in a segmentation into individual segmentations.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
segmentation: Input segmentation to process
|
|
145
|
+
connectivity: Connectivity for connected components (default: "all")
|
|
146
|
+
String format: "face" (6-connected), "face-edge" (18-connected), "all" (26-connected)
|
|
147
|
+
Legacy int format: 6, 18, or 26 (for backward compatibility)
|
|
148
|
+
min_size: Minimum component volume in cubic angstroms (ų) to keep (None = keep all)
|
|
149
|
+
session_id_template: Template for output session IDs with {instance_id} placeholder
|
|
150
|
+
output_user_id: User ID for output segmentations
|
|
151
|
+
multilabel: Whether to treat input as multilabel segmentation
|
|
152
|
+
session_id_prefix: Deprecated. Use session_id_template instead.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
List of created segmentations, one per component
|
|
156
|
+
"""
|
|
157
|
+
# Handle deprecated session_id_prefix parameter
|
|
158
|
+
if session_id_prefix is not None:
|
|
159
|
+
session_id_template = f"{session_id_prefix}{{instance_id}}"
|
|
160
|
+
# Get the segmentation volume
|
|
161
|
+
volume = segmentation.numpy()
|
|
162
|
+
if volume is None:
|
|
163
|
+
raise ValueError("Could not load segmentation data")
|
|
164
|
+
|
|
165
|
+
run = segmentation.run
|
|
166
|
+
voxel_size = segmentation.voxel_size
|
|
167
|
+
name = segmentation.name
|
|
168
|
+
|
|
169
|
+
output_segmentations = []
|
|
170
|
+
component_count = 0
|
|
171
|
+
|
|
172
|
+
if multilabel:
|
|
173
|
+
# Process each label separately
|
|
174
|
+
unique_labels = np.unique(volume)
|
|
175
|
+
unique_labels = unique_labels[unique_labels > 0] # skip background
|
|
176
|
+
|
|
177
|
+
print(f"Processing multilabel segmentation with {len(unique_labels)} labels")
|
|
178
|
+
|
|
179
|
+
for label_value in unique_labels:
|
|
180
|
+
print(f"Processing label {label_value}")
|
|
181
|
+
|
|
182
|
+
# Extract binary volume for this label
|
|
183
|
+
binary_vol = volume == label_value
|
|
184
|
+
|
|
185
|
+
# Separate connected components
|
|
186
|
+
labeled_vol, n_components, component_info = separate_connected_components_3d(
|
|
187
|
+
binary_vol,
|
|
188
|
+
voxel_spacing=voxel_size,
|
|
189
|
+
connectivity=connectivity,
|
|
190
|
+
min_size=min_size,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# Extract individual components
|
|
194
|
+
individual_components = extract_individual_components(labeled_vol)
|
|
195
|
+
|
|
196
|
+
# Create segmentations for each component
|
|
197
|
+
for component_vol in individual_components:
|
|
198
|
+
session_id = session_id_template.replace("{instance_id}", str(component_count))
|
|
199
|
+
|
|
200
|
+
# Create new segmentation
|
|
201
|
+
output_seg = run.new_segmentation(
|
|
202
|
+
voxel_size=voxel_size,
|
|
203
|
+
name=name,
|
|
204
|
+
session_id=session_id,
|
|
205
|
+
is_multilabel=False,
|
|
206
|
+
user_id=output_user_id,
|
|
207
|
+
exist_ok=True,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
# Store the component volume
|
|
211
|
+
output_seg.from_numpy(component_vol)
|
|
212
|
+
output_segmentations.append(output_seg)
|
|
213
|
+
component_count += 1
|
|
214
|
+
|
|
215
|
+
else:
|
|
216
|
+
# Process as binary segmentation
|
|
217
|
+
print("Processing binary segmentation")
|
|
218
|
+
|
|
219
|
+
# Separate connected components
|
|
220
|
+
labeled_vol, n_components, component_info = separate_connected_components_3d(
|
|
221
|
+
volume,
|
|
222
|
+
voxel_spacing=voxel_size,
|
|
223
|
+
connectivity=connectivity,
|
|
224
|
+
min_size=min_size,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
# Extract individual components
|
|
228
|
+
individual_components = extract_individual_components(labeled_vol)
|
|
229
|
+
|
|
230
|
+
# Create segmentations for each component
|
|
231
|
+
for component_vol in individual_components:
|
|
232
|
+
session_id = session_id_template.replace("{instance_id}", str(component_count))
|
|
233
|
+
|
|
234
|
+
# Create new segmentation
|
|
235
|
+
output_seg = run.new_segmentation(
|
|
236
|
+
voxel_size=voxel_size,
|
|
237
|
+
name=name,
|
|
238
|
+
session_id=session_id,
|
|
239
|
+
is_multilabel=False,
|
|
240
|
+
user_id=output_user_id,
|
|
241
|
+
exist_ok=True,
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Store the component volume
|
|
245
|
+
output_seg.from_numpy(component_vol)
|
|
246
|
+
output_segmentations.append(output_seg)
|
|
247
|
+
component_count += 1
|
|
248
|
+
|
|
249
|
+
print(f"Created {len(output_segmentations)} component segmentations")
|
|
250
|
+
return output_segmentations
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def _separate_components_worker(
|
|
254
|
+
run: "CopickRun",
|
|
255
|
+
segmentation_name: str,
|
|
256
|
+
segmentation_user_id: str,
|
|
257
|
+
segmentation_session_id: str,
|
|
258
|
+
connectivity: Union[int, str],
|
|
259
|
+
min_size: Optional[float],
|
|
260
|
+
session_id_template: str,
|
|
261
|
+
output_user_id: str,
|
|
262
|
+
multilabel: bool,
|
|
263
|
+
root: "CopickRoot",
|
|
264
|
+
) -> Dict[str, Any]:
|
|
265
|
+
"""Worker function for batch connected components separation."""
|
|
266
|
+
try:
|
|
267
|
+
# Get segmentation
|
|
268
|
+
segmentations = run.get_segmentations(
|
|
269
|
+
name=segmentation_name,
|
|
270
|
+
user_id=segmentation_user_id,
|
|
271
|
+
session_id=segmentation_session_id,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
if not segmentations:
|
|
275
|
+
return {"processed": 0, "errors": [f"No segmentation found for {run.name}"]}
|
|
276
|
+
|
|
277
|
+
segmentation = segmentations[0]
|
|
278
|
+
|
|
279
|
+
# Separate components
|
|
280
|
+
output_segmentations = separate_segmentation_components(
|
|
281
|
+
segmentation=segmentation,
|
|
282
|
+
connectivity=connectivity,
|
|
283
|
+
min_size=min_size,
|
|
284
|
+
session_id_template=session_id_template,
|
|
285
|
+
output_user_id=output_user_id,
|
|
286
|
+
multilabel=multilabel,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
"processed": 1,
|
|
291
|
+
"errors": [],
|
|
292
|
+
"components_created": len(output_segmentations),
|
|
293
|
+
"segmentations": output_segmentations,
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
except Exception as e:
|
|
297
|
+
return {"processed": 0, "errors": [f"Error processing {run.name}: {e}"]}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def separate_components_batch(
|
|
301
|
+
root: "CopickRoot",
|
|
302
|
+
segmentation_name: str,
|
|
303
|
+
segmentation_user_id: str,
|
|
304
|
+
segmentation_session_id: str,
|
|
305
|
+
connectivity: Union[int, str] = "all",
|
|
306
|
+
min_size: Optional[float] = None,
|
|
307
|
+
session_id_template: str = "inst-{instance_id}",
|
|
308
|
+
output_user_id: str = "components",
|
|
309
|
+
multilabel: bool = True,
|
|
310
|
+
run_names: Optional[List[str]] = None,
|
|
311
|
+
workers: int = 8,
|
|
312
|
+
session_id_prefix: str = None, # Deprecated, kept for backward compatibility
|
|
313
|
+
) -> Dict[str, Any]:
|
|
314
|
+
"""
|
|
315
|
+
Batch separate connected components across multiple runs.
|
|
316
|
+
|
|
317
|
+
Args:
|
|
318
|
+
root: The copick root containing runs to process
|
|
319
|
+
segmentation_name: Name of the segmentation to process
|
|
320
|
+
segmentation_user_id: User ID of the segmentation to process
|
|
321
|
+
segmentation_session_id: Session ID of the segmentation to process
|
|
322
|
+
connectivity: Connectivity for connected components (default: "all")
|
|
323
|
+
String format: "face" (6-connected), "face-edge" (18-connected), "all" (26-connected)
|
|
324
|
+
Legacy int format: 6, 18, or 26 (for backward compatibility)
|
|
325
|
+
min_size: Minimum component volume in cubic angstroms (ų) to keep (None = keep all)
|
|
326
|
+
session_id_template: Template for output session IDs with {instance_id} placeholder. Default is "inst-{instance_id}".
|
|
327
|
+
output_user_id: User ID for output segmentations. Default is "components".
|
|
328
|
+
multilabel: Whether to treat input as multilabel segmentation. Default is True.
|
|
329
|
+
run_names: List of run names to process. If None, processes all runs.
|
|
330
|
+
workers: Number of worker processes. Default is 8.
|
|
331
|
+
session_id_prefix: Deprecated. Use session_id_template instead.
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
Dictionary with processing results and statistics
|
|
335
|
+
"""
|
|
336
|
+
from copick.ops.run import map_runs
|
|
337
|
+
|
|
338
|
+
# Handle deprecated session_id_prefix parameter
|
|
339
|
+
if session_id_prefix is not None:
|
|
340
|
+
session_id_template = f"{session_id_prefix}{{instance_id}}"
|
|
341
|
+
|
|
342
|
+
runs_to_process = [run.name for run in root.runs] if run_names is None else run_names
|
|
343
|
+
|
|
344
|
+
results = map_runs(
|
|
345
|
+
callback=_separate_components_worker,
|
|
346
|
+
root=root,
|
|
347
|
+
runs=runs_to_process,
|
|
348
|
+
workers=workers,
|
|
349
|
+
task_desc="Separating connected components",
|
|
350
|
+
segmentation_name=segmentation_name,
|
|
351
|
+
segmentation_user_id=segmentation_user_id,
|
|
352
|
+
segmentation_session_id=segmentation_session_id,
|
|
353
|
+
connectivity=connectivity,
|
|
354
|
+
min_size=min_size,
|
|
355
|
+
session_id_template=session_id_template,
|
|
356
|
+
output_user_id=output_user_id,
|
|
357
|
+
multilabel=multilabel,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
return results
|