copick-utils 0.6.0__py3-none-any.whl → 1.0.0__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.
Files changed (72) hide show
  1. copick_utils/__init__.py +1 -0
  2. copick_utils/cli/__init__.py +33 -0
  3. copick_utils/cli/clipmesh.py +161 -0
  4. copick_utils/cli/clippicks.py +154 -0
  5. copick_utils/cli/clipseg.py +163 -0
  6. copick_utils/cli/conversion_commands.py +32 -0
  7. copick_utils/cli/enclosed.py +191 -0
  8. copick_utils/cli/filter_components.py +166 -0
  9. copick_utils/cli/fit_spline.py +191 -0
  10. copick_utils/cli/hull.py +138 -0
  11. copick_utils/cli/input_output_selection.py +76 -0
  12. copick_utils/cli/logical_commands.py +29 -0
  13. copick_utils/cli/mesh2picks.py +170 -0
  14. copick_utils/cli/mesh2seg.py +167 -0
  15. copick_utils/cli/meshop.py +262 -0
  16. copick_utils/cli/picks2ellipsoid.py +171 -0
  17. copick_utils/cli/picks2mesh.py +181 -0
  18. copick_utils/cli/picks2plane.py +156 -0
  19. copick_utils/cli/picks2seg.py +134 -0
  20. copick_utils/cli/picks2sphere.py +170 -0
  21. copick_utils/cli/picks2surface.py +164 -0
  22. copick_utils/cli/picksin.py +146 -0
  23. copick_utils/cli/picksout.py +148 -0
  24. copick_utils/cli/processing_commands.py +18 -0
  25. copick_utils/cli/seg2mesh.py +135 -0
  26. copick_utils/cli/seg2picks.py +128 -0
  27. copick_utils/cli/segop.py +248 -0
  28. copick_utils/cli/separate_components.py +155 -0
  29. copick_utils/cli/skeletonize.py +164 -0
  30. copick_utils/cli/util.py +580 -0
  31. copick_utils/cli/validbox.py +155 -0
  32. copick_utils/converters/__init__.py +35 -0
  33. copick_utils/converters/converter_common.py +543 -0
  34. copick_utils/converters/ellipsoid_from_picks.py +335 -0
  35. copick_utils/converters/lazy_converter.py +576 -0
  36. copick_utils/converters/mesh_from_picks.py +209 -0
  37. copick_utils/converters/mesh_from_segmentation.py +119 -0
  38. copick_utils/converters/picks_from_mesh.py +542 -0
  39. copick_utils/converters/picks_from_segmentation.py +168 -0
  40. copick_utils/converters/plane_from_picks.py +251 -0
  41. copick_utils/converters/segmentation_from_mesh.py +291 -0
  42. copick_utils/{segmentation → converters}/segmentation_from_picks.py +151 -15
  43. copick_utils/converters/sphere_from_picks.py +306 -0
  44. copick_utils/converters/surface_from_picks.py +337 -0
  45. copick_utils/features/skimage.py +33 -13
  46. copick_utils/io/readers.py +62 -59
  47. copick_utils/io/writers.py +9 -14
  48. copick_utils/logical/__init__.py +43 -0
  49. copick_utils/logical/distance_operations.py +604 -0
  50. copick_utils/logical/enclosed_operations.py +222 -0
  51. copick_utils/logical/mesh_operations.py +443 -0
  52. copick_utils/logical/point_operations.py +303 -0
  53. copick_utils/logical/segmentation_operations.py +399 -0
  54. copick_utils/pickers/grid_picker.py +5 -4
  55. copick_utils/process/__init__.py +47 -0
  56. copick_utils/process/connected_components.py +360 -0
  57. copick_utils/process/filter_components.py +306 -0
  58. copick_utils/process/hull.py +106 -0
  59. copick_utils/process/skeletonize.py +326 -0
  60. copick_utils/process/spline_fitting.py +648 -0
  61. copick_utils/process/validbox.py +333 -0
  62. copick_utils/util/__init__.py +6 -0
  63. copick_utils/util/config_models.py +614 -0
  64. {copick_utils-0.6.0.dist-info → copick_utils-1.0.0.dist-info}/METADATA +38 -12
  65. copick_utils-1.0.0.dist-info/RECORD +71 -0
  66. {copick_utils-0.6.0.dist-info → copick_utils-1.0.0.dist-info}/WHEEL +1 -1
  67. copick_utils-1.0.0.dist-info/entry_points.txt +29 -0
  68. copick_utils/__about__.py +0 -4
  69. copick_utils/segmentation/picks_from_segmentation.py +0 -67
  70. copick_utils-0.6.0.dist-info/RECORD +0 -15
  71. /copick_utils/{segmentation → io}/__init__.py +0 -0
  72. /copick_utils-0.6.0.dist-info/LICENSE.txt → /copick_utils-1.0.0.dist-info/licenses/LICENSE +0 -0
copick_utils/__init__.py CHANGED
@@ -1,3 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2024-present Kyle Harrington <czi@kyleharrington.com>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
+ __version__ = "1.0.0"
@@ -0,0 +1,33 @@
1
+ """CLI commands for copick-utils."""
2
+
3
+ from .conversion_commands import (
4
+ mesh2picks,
5
+ mesh2seg,
6
+ picks2ellipsoid,
7
+ picks2mesh,
8
+ picks2plane,
9
+ picks2seg,
10
+ picks2sphere,
11
+ picks2surface,
12
+ seg2mesh,
13
+ seg2picks,
14
+ )
15
+ from .processing_commands import fit_spline, separate_components, skeletonize
16
+
17
+ __all__ = [
18
+ # Conversion commands
19
+ "picks2seg",
20
+ "seg2picks",
21
+ "mesh2seg",
22
+ "seg2mesh",
23
+ "picks2mesh",
24
+ "mesh2picks",
25
+ "picks2surface",
26
+ "picks2plane",
27
+ "picks2sphere",
28
+ "picks2ellipsoid",
29
+ # Processing commands
30
+ "separate_components",
31
+ "skeletonize",
32
+ "fit_spline",
33
+ ]
@@ -0,0 +1,161 @@
1
+ import click
2
+ import copick
3
+ from click_option_group import optgroup
4
+ from copick.cli.util import add_config_option, add_debug_option
5
+ from copick.util.log import get_logger
6
+ from copick.util.uri import parse_copick_uri
7
+
8
+ from copick_utils.cli.util import (
9
+ add_distance_options,
10
+ add_input_option,
11
+ add_output_option,
12
+ add_reference_mesh_option,
13
+ add_reference_seg_option,
14
+ add_workers_option,
15
+ )
16
+ from copick_utils.util.config_models import create_reference_config
17
+
18
+
19
+ @click.command(
20
+ context_settings={"show_default": True},
21
+ short_help="Limit meshes to vertices within distance of a reference surface.",
22
+ no_args_is_help=True,
23
+ )
24
+ @add_config_option
25
+ @optgroup.group("\nInput Options", help="Options related to the input meshes.")
26
+ @optgroup.option(
27
+ "--run-names",
28
+ "-r",
29
+ multiple=True,
30
+ help="Specific run names to process (default: all runs).",
31
+ )
32
+ @add_input_option("mesh")
33
+ @optgroup.group("\nReference Options", help="Options for reference surface (provide either mesh or segmentation).")
34
+ @add_reference_mesh_option(required=False)
35
+ @add_reference_seg_option(required=False)
36
+ @optgroup.group("\nTool Options", help="Options related to this tool.")
37
+ @add_distance_options
38
+ @add_workers_option
39
+ @optgroup.group("\nOutput Options", help="Options related to output meshes.")
40
+ @add_output_option("mesh", default_tool="clipmesh")
41
+ @optgroup.option(
42
+ "--individual-meshes/--no-individual-meshes",
43
+ "-im",
44
+ is_flag=True,
45
+ default=False,
46
+ help="Create individual meshes for each instance (enables {instance_id} placeholder).",
47
+ )
48
+ @add_debug_option
49
+ def clipmesh(
50
+ config,
51
+ run_names,
52
+ input_uri,
53
+ ref_mesh_uri,
54
+ ref_seg_uri,
55
+ max_distance,
56
+ mesh_voxel_spacing,
57
+ workers,
58
+ output_uri,
59
+ individual_meshes,
60
+ debug,
61
+ ):
62
+ """
63
+ Limit meshes to vertices within a certain distance of a reference surface.
64
+
65
+ \b
66
+ URI Format:
67
+ Meshes: object_name:user_id/session_id
68
+ Segmentations: name:user_id/session_id@voxel_spacing
69
+
70
+ \b
71
+ The reference surface can be either a mesh or a segmentation.
72
+ Only mesh vertices within the specified distance will be kept.
73
+
74
+ \b
75
+ Examples:
76
+ # Limit mesh to vertices near reference mesh surface
77
+ copick logical clipmesh -i "membrane:user1/full-001" -rm "boundary:user1/boundary-001" -o "membrane:clipmesh/limited-001" --max-distance 50.0
78
+
79
+ # Limit using segmentation as reference
80
+ copick logical clipmesh -i "membrane:user1/full-001" -rs "mask:user1/mask-001@10.0" -o "membrane:clipmesh/limited-001" --max-distance 100.0
81
+ """
82
+ from copick_utils.logical.distance_operations import limit_mesh_by_distance_lazy_batch
83
+
84
+ logger = get_logger(__name__, debug=debug)
85
+
86
+ # Validate that exactly one reference type is provided
87
+ if not ref_mesh_uri and not ref_seg_uri:
88
+ raise click.BadParameter("Must provide either --ref-mesh or --ref-seg")
89
+ if ref_mesh_uri and ref_seg_uri:
90
+ raise click.BadParameter("Cannot provide both --ref-mesh and --ref-seg")
91
+
92
+ root = copick.from_file(config)
93
+ run_names_list = list(run_names) if run_names else None
94
+
95
+ # Determine reference type and URI
96
+ reference_uri = ref_mesh_uri or ref_seg_uri
97
+ reference_type = "mesh" if ref_mesh_uri else "segmentation"
98
+
99
+ # Create config directly from URIs with additional params for distance operations
100
+ try:
101
+ task_config = create_reference_config(
102
+ input_uri=input_uri,
103
+ input_type="mesh",
104
+ output_uri=output_uri,
105
+ output_type="mesh",
106
+ reference_uri=reference_uri,
107
+ reference_type=reference_type,
108
+ additional_params={"max_distance": max_distance, "mesh_voxel_spacing": mesh_voxel_spacing},
109
+ command_name="clipmesh",
110
+ )
111
+ except ValueError as e:
112
+ raise click.BadParameter(str(e)) from e
113
+
114
+ # Extract parameters for logging
115
+ input_params = parse_copick_uri(input_uri, "mesh")
116
+ output_params = parse_copick_uri(output_uri, "mesh")
117
+ ref_params = parse_copick_uri(reference_uri, reference_type)
118
+
119
+ logger.info(f"Limiting meshes by distance for object '{input_params['object_name']}'")
120
+ logger.info(f"Source mesh pattern: {input_params['user_id']}/{input_params['session_id']}")
121
+ if reference_type == "mesh":
122
+ logger.info(f"Reference mesh: {ref_params['object_name']} ({ref_params['user_id']}/{ref_params['session_id']})")
123
+ else:
124
+ logger.info(
125
+ f"Reference segmentation: {ref_params['name']} ({ref_params['user_id']}/{ref_params['session_id']})",
126
+ )
127
+ logger.info(f"Maximum distance: {max_distance} angstroms")
128
+ logger.info(
129
+ f"Target mesh template: {output_params['object_name']} ({output_params['user_id']}/{output_params['session_id']})",
130
+ )
131
+
132
+ # Parallel discovery and processing - no sequential bottleneck!
133
+ results = limit_mesh_by_distance_lazy_batch(
134
+ root=root,
135
+ config=task_config,
136
+ run_names=run_names_list,
137
+ workers=workers,
138
+ )
139
+
140
+ successful = sum(1 for result in results.values() if result and result.get("processed", 0) > 0)
141
+ total_vertices = sum(result.get("vertices_created", 0) for result in results.values() if result)
142
+ total_faces = sum(result.get("faces_created", 0) for result in results.values() if result)
143
+ total_processed = sum(result.get("processed", 0) for result in results.values() if result)
144
+
145
+ # Collect all errors
146
+ all_errors = []
147
+ for result in results.values():
148
+ if result and result.get("errors"):
149
+ all_errors.extend(result["errors"])
150
+
151
+ logger.info(f"Completed: {successful}/{len(results)} runs processed successfully")
152
+ logger.info(f"Total distance limiting operations completed: {total_processed}")
153
+ logger.info(f"Total vertices created: {total_vertices}")
154
+ logger.info(f"Total faces created: {total_faces}")
155
+
156
+ if all_errors:
157
+ logger.warning(f"Encountered {len(all_errors)} errors during processing")
158
+ for error in all_errors[:5]: # Show first 5 errors
159
+ logger.warning(f" - {error}")
160
+ if len(all_errors) > 5:
161
+ logger.warning(f" ... and {len(all_errors) - 5} more errors")
@@ -0,0 +1,154 @@
1
+ """CLI commands for distance-based limiting operations."""
2
+
3
+ import click
4
+ import copick
5
+ from click_option_group import optgroup
6
+ from copick.cli.util import add_config_option, add_debug_option
7
+ from copick.util.log import get_logger
8
+ from copick.util.uri import parse_copick_uri
9
+
10
+ from copick_utils.cli.util import (
11
+ add_distance_options,
12
+ add_input_option,
13
+ add_output_option,
14
+ add_reference_mesh_option,
15
+ add_reference_seg_option,
16
+ add_workers_option,
17
+ )
18
+ from copick_utils.util.config_models import create_reference_config
19
+
20
+
21
+ @click.command(
22
+ context_settings={"show_default": True},
23
+ short_help="Limit picks to those within distance of a reference surface.",
24
+ no_args_is_help=True,
25
+ )
26
+ @add_config_option
27
+ @optgroup.group("\nInput Options", help="Options related to the input picks.")
28
+ @optgroup.option(
29
+ "--run-names",
30
+ "-r",
31
+ multiple=True,
32
+ help="Specific run names to process (default: all runs).",
33
+ )
34
+ @add_input_option("picks")
35
+ @optgroup.group("\nReference Options", help="Options for reference surface (provide either mesh or segmentation).")
36
+ @add_reference_mesh_option(required=False)
37
+ @add_reference_seg_option(required=False)
38
+ @optgroup.group("\nTool Options", help="Options related to this tool.")
39
+ @add_distance_options
40
+ @add_workers_option
41
+ @optgroup.group("\nOutput Options", help="Options related to output picks.")
42
+ @add_output_option("picks", default_tool="clippicks")
43
+ @add_debug_option
44
+ def clippicks(
45
+ config,
46
+ run_names,
47
+ input_uri,
48
+ ref_mesh_uri,
49
+ ref_seg_uri,
50
+ max_distance,
51
+ mesh_voxel_spacing,
52
+ workers,
53
+ output_uri,
54
+ debug,
55
+ ):
56
+ """
57
+ Limit picks to those within a certain distance of a reference surface.
58
+
59
+ \b
60
+ URI Format:
61
+ Picks: object_name:user_id/session_id
62
+ Meshes: object_name:user_id/session_id
63
+ Segmentations: name:user_id/session_id@voxel_spacing
64
+
65
+ \b
66
+ The reference surface can be either a mesh or a segmentation.
67
+ Only picks within the specified distance will be kept.
68
+
69
+ \b
70
+ Examples:
71
+ # Limit picks to those near reference mesh surface
72
+ copick logical clippicks -i "ribosome:user1/all-001" -rm "boundary:user1/boundary-001" -o "ribosome:clippicks/limited-001" --max-distance 50.0
73
+
74
+ # Limit using segmentation as reference
75
+ copick logical clippicks -i "ribosome:user1/all-001" -rs "mask:user1/mask-001@10.0" -o "ribosome:clippicks/limited-001" --max-distance 100.0
76
+ """
77
+ from copick_utils.logical.distance_operations import limit_picks_by_distance_lazy_batch
78
+
79
+ logger = get_logger(__name__, debug=debug)
80
+
81
+ # Validate that exactly one reference type is provided
82
+ if not ref_mesh_uri and not ref_seg_uri:
83
+ raise click.BadParameter("Must provide either --ref-mesh or --ref-seg")
84
+ if ref_mesh_uri and ref_seg_uri:
85
+ raise click.BadParameter("Cannot provide both --ref-mesh and --ref-seg")
86
+
87
+ root = copick.from_file(config)
88
+ run_names_list = list(run_names) if run_names else None
89
+
90
+ # Determine reference type and URI
91
+ reference_uri = ref_mesh_uri or ref_seg_uri
92
+ reference_type = "mesh" if ref_mesh_uri else "segmentation"
93
+
94
+ # Create config directly from URIs with additional params
95
+ try:
96
+ task_config = create_reference_config(
97
+ input_uri=input_uri,
98
+ input_type="picks",
99
+ output_uri=output_uri,
100
+ output_type="picks",
101
+ reference_uri=reference_uri,
102
+ reference_type=reference_type,
103
+ additional_params={"max_distance": max_distance, "mesh_voxel_spacing": mesh_voxel_spacing},
104
+ command_name="clippicks",
105
+ )
106
+ except ValueError as e:
107
+ raise click.BadParameter(str(e)) from e
108
+
109
+ # Extract parameters for logging
110
+ input_params = parse_copick_uri(input_uri, "picks")
111
+ output_params = parse_copick_uri(output_uri, "picks")
112
+ ref_params = parse_copick_uri(reference_uri, reference_type)
113
+
114
+ logger.info(f"Limiting picks by distance for object '{input_params['object_name']}'")
115
+ logger.info(f"Source picks pattern: {input_params['user_id']}/{input_params['session_id']}")
116
+ if reference_type == "mesh":
117
+ logger.info(f"Reference mesh: {ref_params['object_name']} ({ref_params['user_id']}/{ref_params['session_id']})")
118
+ else:
119
+ logger.info(
120
+ f"Reference segmentation: {ref_params['name']} ({ref_params['user_id']}/{ref_params['session_id']})",
121
+ )
122
+ logger.info(f"Maximum distance: {max_distance} angstroms")
123
+ logger.info(
124
+ f"Target picks template: {output_params['object_name']} ({output_params['user_id']}/{output_params['session_id']})",
125
+ )
126
+
127
+ # Parallel discovery and processing - no sequential bottleneck!
128
+ results = limit_picks_by_distance_lazy_batch(
129
+ root=root,
130
+ config=task_config,
131
+ run_names=run_names_list,
132
+ workers=workers,
133
+ )
134
+
135
+ successful = sum(1 for result in results.values() if result and result.get("processed", 0) > 0)
136
+ total_points = sum(result.get("points_created", 0) for result in results.values() if result)
137
+ total_processed = sum(result.get("processed", 0) for result in results.values() if result)
138
+
139
+ # Collect all errors
140
+ all_errors = []
141
+ for result in results.values():
142
+ if result and result.get("errors"):
143
+ all_errors.extend(result["errors"])
144
+
145
+ logger.info(f"Completed: {successful}/{len(results)} runs processed successfully")
146
+ logger.info(f"Total distance limiting operations completed: {total_processed}")
147
+ logger.info(f"Total points created: {total_points}")
148
+
149
+ if all_errors:
150
+ logger.warning(f"Encountered {len(all_errors)} errors during processing")
151
+ for error in all_errors[:5]: # Show first 5 errors
152
+ logger.warning(f" - {error}")
153
+ if len(all_errors) > 5:
154
+ logger.warning(f" ... and {len(all_errors) - 5} more errors")
@@ -0,0 +1,163 @@
1
+ import click
2
+ import copick
3
+ from click_option_group import optgroup
4
+ from copick.cli.util import add_config_option, add_debug_option
5
+ from copick.util.log import get_logger
6
+ from copick.util.uri import parse_copick_uri
7
+
8
+ from copick_utils.cli.util import (
9
+ add_distance_options,
10
+ add_input_option,
11
+ add_output_option,
12
+ add_reference_mesh_option,
13
+ add_reference_seg_option,
14
+ add_workers_option,
15
+ )
16
+ from copick_utils.util.config_models import create_reference_config
17
+
18
+
19
+ @click.command(
20
+ context_settings={"show_default": True},
21
+ short_help="Limit segmentations to voxels within distance of a reference surface.",
22
+ no_args_is_help=True,
23
+ )
24
+ @add_config_option
25
+ @optgroup.group("\nInput Options", help="Options related to the input segmentations.")
26
+ @optgroup.option(
27
+ "--run-names",
28
+ "-r",
29
+ multiple=True,
30
+ help="Specific run names to process (default: all runs).",
31
+ )
32
+ @add_input_option("segmentation")
33
+ @optgroup.group("\nReference Options", help="Options for reference surface (provide either mesh or segmentation).")
34
+ @add_reference_mesh_option(required=False)
35
+ @add_reference_seg_option(required=False)
36
+ @optgroup.group("\nTool Options", help="Options related to this tool.")
37
+ @add_distance_options
38
+ @add_workers_option
39
+ @optgroup.group("\nOutput Options", help="Options related to output segmentations.")
40
+ @add_output_option("segmentation", default_tool="clipseg")
41
+ @add_debug_option
42
+ def clipseg(
43
+ config,
44
+ run_names,
45
+ input_uri,
46
+ ref_mesh_uri,
47
+ ref_seg_uri,
48
+ max_distance,
49
+ mesh_voxel_spacing,
50
+ workers,
51
+ output_uri,
52
+ debug,
53
+ ):
54
+ """
55
+ Limit segmentations to voxels within a certain distance of a reference surface.
56
+
57
+ \b
58
+ URI Format:
59
+ Segmentations: name:user_id/session_id@voxel_spacing
60
+ Meshes: object_name:user_id/session_id
61
+
62
+ \b
63
+ The reference surface can be either a mesh or another segmentation.
64
+ Only segmentation voxels within the specified distance will be kept.
65
+
66
+ \b
67
+ Examples:
68
+ # Limit segmentation to voxels near reference mesh
69
+ copick logical clipseg -i "membrane:user1/full-001@10.0" -rm "boundary:user1/boundary-001" -o "membrane:clipseg/limited-001@10.0" --max-distance 50.0
70
+
71
+ # Limit using another segmentation as reference
72
+ copick logical clipseg -i "membrane:user1/full-001@10.0" -rs "mask:user1/mask-001@10.0" -o "membrane:clipseg/limited-001@10.0" --max-distance 100.0
73
+ """
74
+ from copick_utils.logical.distance_operations import limit_segmentation_by_distance_lazy_batch
75
+
76
+ logger = get_logger(__name__, debug=debug)
77
+
78
+ # Validate that exactly one reference type is provided
79
+ if not ref_mesh_uri and not ref_seg_uri:
80
+ raise click.BadParameter("Must provide either --ref-mesh or --ref-seg")
81
+ if ref_mesh_uri and ref_seg_uri:
82
+ raise click.BadParameter("Cannot provide both --ref-mesh and --ref-seg")
83
+
84
+ root = copick.from_file(config)
85
+ run_names_list = list(run_names) if run_names else None
86
+
87
+ # Determine reference type and URI
88
+ reference_uri = ref_mesh_uri or ref_seg_uri
89
+ reference_type = "mesh" if ref_mesh_uri else "segmentation"
90
+
91
+ # Extract voxel_spacing and multilabel from output for additional_params
92
+ output_params_temp = parse_copick_uri(output_uri, "segmentation")
93
+ voxel_spacing_output = output_params_temp["voxel_spacing"]
94
+ if isinstance(voxel_spacing_output, str):
95
+ voxel_spacing_output = float(voxel_spacing_output)
96
+ multilabel_output = output_params_temp.get("multilabel") or False
97
+
98
+ # Create config directly from URIs with additional params and smart defaults
99
+ try:
100
+ task_config = create_reference_config(
101
+ input_uri=input_uri,
102
+ input_type="segmentation",
103
+ output_uri=output_uri,
104
+ output_type="segmentation",
105
+ reference_uri=reference_uri,
106
+ reference_type=reference_type,
107
+ additional_params={
108
+ "max_distance": max_distance,
109
+ "mesh_voxel_spacing": mesh_voxel_spacing,
110
+ "voxel_spacing": voxel_spacing_output,
111
+ "is_multilabel": multilabel_output,
112
+ },
113
+ command_name="clipseg",
114
+ )
115
+ except ValueError as e:
116
+ raise click.BadParameter(str(e)) from e
117
+
118
+ # Extract parameters for logging
119
+ input_params = parse_copick_uri(input_uri, "segmentation")
120
+ output_params = parse_copick_uri(output_uri, "segmentation")
121
+ ref_params = parse_copick_uri(reference_uri, reference_type)
122
+
123
+ logger.info(f"Limiting segmentations by distance for '{input_params['name']}'")
124
+ logger.info(f"Source segmentation pattern: {input_params['user_id']}/{input_params['session_id']}")
125
+ if reference_type == "mesh":
126
+ logger.info(f"Reference mesh: {ref_params['object_name']} ({ref_params['user_id']}/{ref_params['session_id']})")
127
+ else:
128
+ logger.info(
129
+ f"Reference segmentation: {ref_params['name']} ({ref_params['user_id']}/{ref_params['session_id']})",
130
+ )
131
+ logger.info(f"Maximum distance: {max_distance} angstroms")
132
+ logger.info(
133
+ f"Target segmentation template: {output_params['name']} ({output_params['user_id']}/{output_params['session_id']})",
134
+ )
135
+
136
+ # Parallel discovery and processing - no sequential bottleneck!
137
+ results = limit_segmentation_by_distance_lazy_batch(
138
+ root=root,
139
+ config=task_config,
140
+ run_names=run_names_list,
141
+ workers=workers,
142
+ )
143
+
144
+ successful = sum(1 for result in results.values() if result and result.get("processed", 0) > 0)
145
+ total_voxels = sum(result.get("voxels_created", 0) for result in results.values() if result)
146
+ total_processed = sum(result.get("processed", 0) for result in results.values() if result)
147
+
148
+ # Collect all errors
149
+ all_errors = []
150
+ for result in results.values():
151
+ if result and result.get("errors"):
152
+ all_errors.extend(result["errors"])
153
+
154
+ logger.info(f"Completed: {successful}/{len(results)} runs processed successfully")
155
+ logger.info(f"Total distance limiting operations completed: {total_processed}")
156
+ logger.info(f"Total voxels created: {total_voxels}")
157
+
158
+ if all_errors:
159
+ logger.warning(f"Encountered {len(all_errors)} errors during processing")
160
+ for error in all_errors[:5]: # Show first 5 errors
161
+ logger.warning(f" - {error}")
162
+ if len(all_errors) > 5:
163
+ logger.warning(f" ... and {len(all_errors) - 5} more errors")
@@ -0,0 +1,32 @@
1
+ """CLI commands for data conversion between different copick formats.
2
+
3
+ This module imports all conversion commands from specialized files for better organization.
4
+ """
5
+
6
+ from copick_utils.cli.mesh2picks import mesh2picks
7
+ from copick_utils.cli.mesh2seg import mesh2seg
8
+ from copick_utils.cli.picks2ellipsoid import picks2ellipsoid
9
+ from copick_utils.cli.picks2mesh import picks2mesh
10
+ from copick_utils.cli.picks2plane import picks2plane
11
+ from copick_utils.cli.picks2seg import picks2seg
12
+ from copick_utils.cli.picks2sphere import picks2sphere
13
+ from copick_utils.cli.picks2surface import picks2surface
14
+ from copick_utils.cli.seg2mesh import seg2mesh
15
+ from copick_utils.cli.seg2picks import seg2picks
16
+
17
+ # All commands are now available for import by the main CLI
18
+ __all__ = [
19
+ # Picks to mesh commands
20
+ "picks2mesh",
21
+ "picks2sphere",
22
+ "picks2ellipsoid",
23
+ "picks2plane",
24
+ "picks2surface",
25
+ # Mesh to picks commands
26
+ "mesh2picks",
27
+ # Segmentation conversion commands
28
+ "picks2seg",
29
+ "seg2picks",
30
+ "mesh2seg",
31
+ "seg2mesh",
32
+ ]