copick-utils 0.6.1__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.
- 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.0.dist-info}/METADATA +15 -2
- copick_utils-1.0.0.dist-info/RECORD +71 -0
- copick_utils-1.0.0.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.0.dist-info}/WHEEL +0 -0
- {copick_utils-0.6.1.dist-info → copick_utils-1.0.0.dist-info}/licenses/LICENSE +0 -0
copick_utils/cli/util.py
ADDED
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
"""CLI utilities for copick-utils commands."""
|
|
2
|
+
|
|
3
|
+
from typing import Callable
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from click_option_group import optgroup
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def add_clustering_options(func: click.Command) -> click.Command:
|
|
10
|
+
"""
|
|
11
|
+
Add common clustering options for picks-to-mesh conversion commands.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
func (click.Command): The Click command to which the options will be added.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
click.Command: The Click command with the clustering options added.
|
|
18
|
+
"""
|
|
19
|
+
opts = [
|
|
20
|
+
optgroup.option(
|
|
21
|
+
"--use-clustering/--no-use-clustering",
|
|
22
|
+
"-cl",
|
|
23
|
+
is_flag=True,
|
|
24
|
+
default=False,
|
|
25
|
+
help="Cluster points before mesh creation.",
|
|
26
|
+
),
|
|
27
|
+
optgroup.option(
|
|
28
|
+
"--clustering-method",
|
|
29
|
+
type=click.Choice(["dbscan", "kmeans"]),
|
|
30
|
+
default="dbscan",
|
|
31
|
+
help="Clustering method.",
|
|
32
|
+
),
|
|
33
|
+
optgroup.option(
|
|
34
|
+
"--clustering-eps",
|
|
35
|
+
type=float,
|
|
36
|
+
default=1.0,
|
|
37
|
+
help="DBSCAN eps parameter - maximum distance between points in a cluster (in angstroms).",
|
|
38
|
+
),
|
|
39
|
+
optgroup.option(
|
|
40
|
+
"--clustering-min-samples",
|
|
41
|
+
type=int,
|
|
42
|
+
default=3,
|
|
43
|
+
help="DBSCAN min_samples parameter.",
|
|
44
|
+
),
|
|
45
|
+
optgroup.option(
|
|
46
|
+
"--clustering-n-clusters",
|
|
47
|
+
type=int,
|
|
48
|
+
default=1,
|
|
49
|
+
help="K-means n_clusters parameter.",
|
|
50
|
+
),
|
|
51
|
+
optgroup.option(
|
|
52
|
+
"--all-clusters/--largest-cluster-only",
|
|
53
|
+
"-mm",
|
|
54
|
+
is_flag=True,
|
|
55
|
+
default=True,
|
|
56
|
+
help="Use all clusters (True) or only the largest cluster (False).",
|
|
57
|
+
),
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
for opt in reversed(opts):
|
|
61
|
+
func = opt(func)
|
|
62
|
+
|
|
63
|
+
return func
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def add_workers_option(func: click.Command) -> click.Command:
|
|
67
|
+
"""
|
|
68
|
+
Add workers option for parallel processing.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
func (click.Command): The Click command to which the option will be added.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
click.Command: The Click command with the workers option added.
|
|
75
|
+
"""
|
|
76
|
+
opts = [
|
|
77
|
+
optgroup.option(
|
|
78
|
+
"--workers",
|
|
79
|
+
"-w",
|
|
80
|
+
type=int,
|
|
81
|
+
default=8,
|
|
82
|
+
help="Number of worker processes.",
|
|
83
|
+
),
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
for opt in opts:
|
|
87
|
+
func = opt(func)
|
|
88
|
+
|
|
89
|
+
return func
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def add_marching_cubes_options(func: click.Command) -> click.Command:
|
|
93
|
+
"""
|
|
94
|
+
Add marching cubes options for segmentation-to-mesh conversion commands.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
func (click.Command): The Click command to which the options will be added.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
click.Command: The Click command with the marching cubes options added.
|
|
101
|
+
"""
|
|
102
|
+
opts = [
|
|
103
|
+
optgroup.option(
|
|
104
|
+
"--level",
|
|
105
|
+
type=float,
|
|
106
|
+
default=0.5,
|
|
107
|
+
help="Isosurface level for marching cubes.",
|
|
108
|
+
),
|
|
109
|
+
optgroup.option(
|
|
110
|
+
"--step-size",
|
|
111
|
+
type=int,
|
|
112
|
+
default=1,
|
|
113
|
+
help="Step size for marching cubes (higher = coarser mesh).",
|
|
114
|
+
),
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
for opt in reversed(opts):
|
|
118
|
+
func = opt(func)
|
|
119
|
+
|
|
120
|
+
return func
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def add_segmentation_processing_options(func: click.Command) -> click.Command:
|
|
124
|
+
"""
|
|
125
|
+
Add segmentation processing options for segmentation-to-picks conversion commands.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
func (click.Command): The Click command to which the options will be added.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
click.Command: The Click command with the segmentation processing options added.
|
|
132
|
+
"""
|
|
133
|
+
opts = [
|
|
134
|
+
optgroup.option(
|
|
135
|
+
"--segmentation-idx",
|
|
136
|
+
"-si",
|
|
137
|
+
type=int,
|
|
138
|
+
required=True,
|
|
139
|
+
help="Label index to extract from segmentation.",
|
|
140
|
+
),
|
|
141
|
+
optgroup.option(
|
|
142
|
+
"--maxima-filter-size",
|
|
143
|
+
type=int,
|
|
144
|
+
default=9,
|
|
145
|
+
help="Size of maximum detection filter.",
|
|
146
|
+
),
|
|
147
|
+
optgroup.option(
|
|
148
|
+
"--min-particle-size",
|
|
149
|
+
type=int,
|
|
150
|
+
default=1000,
|
|
151
|
+
help="Minimum particle size threshold.",
|
|
152
|
+
),
|
|
153
|
+
optgroup.option(
|
|
154
|
+
"--max-particle-size",
|
|
155
|
+
type=int,
|
|
156
|
+
default=50000,
|
|
157
|
+
help="Maximum particle size threshold.",
|
|
158
|
+
),
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
for opt in reversed(opts):
|
|
162
|
+
func = opt(func)
|
|
163
|
+
|
|
164
|
+
return func
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def add_mesh_voxelization_options(func: click.Command) -> click.Command:
|
|
168
|
+
"""
|
|
169
|
+
Add mesh voxelization options for mesh-to-segmentation conversion commands.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
func (click.Command): The Click command to which the options will be added.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
click.Command: The Click command with the mesh voxelization options added.
|
|
176
|
+
"""
|
|
177
|
+
opts = [
|
|
178
|
+
optgroup.option(
|
|
179
|
+
"--mode",
|
|
180
|
+
type=click.Choice(["watertight", "boundary"]),
|
|
181
|
+
default="watertight",
|
|
182
|
+
help="Voxelization mode: 'watertight' fills the entire mesh interior, 'boundary' only voxelizes the surface.",
|
|
183
|
+
),
|
|
184
|
+
optgroup.option(
|
|
185
|
+
"--boundary-sampling-density",
|
|
186
|
+
type=float,
|
|
187
|
+
default=1.0,
|
|
188
|
+
help="Surface sampling density for boundary mode (samples per voxel edge length).",
|
|
189
|
+
),
|
|
190
|
+
optgroup.option(
|
|
191
|
+
"--invert/--no-invert",
|
|
192
|
+
is_flag=True,
|
|
193
|
+
default=False,
|
|
194
|
+
help="Invert the volume (fill outside instead of inside for watertight mode).",
|
|
195
|
+
),
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
for opt in reversed(opts):
|
|
199
|
+
func = opt(func)
|
|
200
|
+
|
|
201
|
+
return func
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def add_picks_painting_options(func: click.Command) -> click.Command:
|
|
205
|
+
"""
|
|
206
|
+
Add picks painting options for picks-to-segmentation conversion commands.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
func (click.Command): The Click command to which the options will be added.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
click.Command: The Click command with the picks painting options added.
|
|
213
|
+
"""
|
|
214
|
+
opts = [
|
|
215
|
+
optgroup.option(
|
|
216
|
+
"--radius",
|
|
217
|
+
type=float,
|
|
218
|
+
default=10.0,
|
|
219
|
+
help="Radius of spheres to paint at pick locations (in angstroms).",
|
|
220
|
+
),
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
for opt in reversed(opts):
|
|
224
|
+
func = opt(func)
|
|
225
|
+
|
|
226
|
+
return func
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def add_boolean_operation_option(func: click.Command) -> click.Command:
|
|
230
|
+
"""
|
|
231
|
+
Add boolean operation option for logical operation commands.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
func (click.Command): The Click command to which the option will be added.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
click.Command: The Click command with the boolean operation option added.
|
|
238
|
+
"""
|
|
239
|
+
opts = [
|
|
240
|
+
optgroup.option(
|
|
241
|
+
"--operation",
|
|
242
|
+
"-op",
|
|
243
|
+
type=click.Choice(["union", "difference", "intersection", "exclusion", "concatenate"]),
|
|
244
|
+
required=True,
|
|
245
|
+
help="Boolean operation to perform.",
|
|
246
|
+
),
|
|
247
|
+
]
|
|
248
|
+
|
|
249
|
+
for opt in opts:
|
|
250
|
+
func = opt(func)
|
|
251
|
+
|
|
252
|
+
return func
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def add_distance_options(func: click.Command) -> click.Command:
|
|
256
|
+
"""
|
|
257
|
+
Add distance-related options for distance-based logical operations.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
func (click.Command): The Click command to which the options will be added.
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
click.Command: The Click command with the distance options added.
|
|
264
|
+
"""
|
|
265
|
+
opts = [
|
|
266
|
+
optgroup.option(
|
|
267
|
+
"--max-distance",
|
|
268
|
+
"-d",
|
|
269
|
+
type=float,
|
|
270
|
+
default=100.0,
|
|
271
|
+
help="Maximum distance from reference surface (in angstroms).",
|
|
272
|
+
),
|
|
273
|
+
optgroup.option(
|
|
274
|
+
"--mesh-voxel-spacing",
|
|
275
|
+
"-mvs",
|
|
276
|
+
type=float,
|
|
277
|
+
help="Voxel spacing for mesh voxelization when using mesh reference (defaults to target voxel spacing).",
|
|
278
|
+
),
|
|
279
|
+
]
|
|
280
|
+
|
|
281
|
+
for opt in reversed(opts):
|
|
282
|
+
func = opt(func)
|
|
283
|
+
|
|
284
|
+
return func
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# ============================================================================
|
|
288
|
+
# URI-Based Option Decorators (New Simplified Interface)
|
|
289
|
+
# ============================================================================
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def add_input_option(object_type: str, func: click.Command = None) -> Callable:
|
|
293
|
+
"""
|
|
294
|
+
Add --input/-i option for URI-based input selection.
|
|
295
|
+
|
|
296
|
+
Supports copick URI format with pattern matching:
|
|
297
|
+
- Picks/Meshes: object_name:user_id/session_id
|
|
298
|
+
- Segmentations: name:user_id/session_id@voxel_spacing?multilabel=true
|
|
299
|
+
|
|
300
|
+
Args:
|
|
301
|
+
object_type (str): Type of object ('picks', 'mesh', 'segmentation').
|
|
302
|
+
func (click.Command, optional): The Click command to which the option will be added.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
Callable: The Click command with the input option added.
|
|
306
|
+
"""
|
|
307
|
+
|
|
308
|
+
def add_input_option_decorator(_func: click.Command) -> click.Command:
|
|
309
|
+
"""Add --input option to command."""
|
|
310
|
+
# Determine help text based on object type
|
|
311
|
+
format_examples = {
|
|
312
|
+
"picks": "object_name:user_id/session_id",
|
|
313
|
+
"mesh": "object_name:user_id/session_id",
|
|
314
|
+
"segmentation": "name:user_id/session_id@voxel_spacing",
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
help_text = (
|
|
318
|
+
f"Input {object_type} URI (format: {format_examples.get(object_type, 'URI')}). Supports glob patterns."
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
opt = optgroup.option(
|
|
322
|
+
"--input",
|
|
323
|
+
"-i",
|
|
324
|
+
"input_uri",
|
|
325
|
+
required=True,
|
|
326
|
+
help=help_text,
|
|
327
|
+
)
|
|
328
|
+
return opt(_func)
|
|
329
|
+
|
|
330
|
+
if func is None:
|
|
331
|
+
return add_input_option_decorator
|
|
332
|
+
else:
|
|
333
|
+
return add_input_option_decorator(func)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def add_output_option(object_type: str, func: click.Command = None, default_tool: str = None) -> Callable:
|
|
337
|
+
"""
|
|
338
|
+
Add --output/-o option for URI-based output specification with smart defaults.
|
|
339
|
+
|
|
340
|
+
Supports copick URI format with smart defaults and pattern matching:
|
|
341
|
+
- Full format: object_name:user_id/session_id or name:user_id/session_id@voxel_spacing
|
|
342
|
+
- Smart defaults: Omit components to inherit from input (e.g., just "membrane")
|
|
343
|
+
- Templates: session_id can include {input_session_id} or {instance_id}
|
|
344
|
+
|
|
345
|
+
Smart defaults:
|
|
346
|
+
- Name/object omitted → inherits from input
|
|
347
|
+
- user_id omitted → uses command name (e.g., "mesh2seg")
|
|
348
|
+
- session_id omitted → auto-template based on input pattern
|
|
349
|
+
- voxel_spacing omitted → inherits from input (segmentation only)
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
object_type (str): Type of object ('picks', 'mesh', 'segmentation').
|
|
353
|
+
func (click.Command, optional): The Click command to which the option will be added.
|
|
354
|
+
default_tool (str, optional): Default user_id if not specified in URI (deprecated, auto-detected).
|
|
355
|
+
|
|
356
|
+
Returns:
|
|
357
|
+
Callable: The Click command with the output option added.
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
def add_output_option_decorator(_func: click.Command) -> click.Command:
|
|
361
|
+
"""Add --output option to command."""
|
|
362
|
+
# Determine help text based on object type
|
|
363
|
+
shorthand_examples = {
|
|
364
|
+
"picks": '"ribosome", "ribosome/my-session", or "/my-session"',
|
|
365
|
+
"mesh": '"membrane", "membrane/my-session", or "/my-session"',
|
|
366
|
+
"segmentation": '"membrane", "membrane/my-session", or "/my-session"',
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
voxel_suffix = "@voxel_spacing" if object_type == "segmentation" else ""
|
|
370
|
+
help_text = (
|
|
371
|
+
f"Output {object_type} URI. "
|
|
372
|
+
f"Supports smart defaults (e.g., {shorthand_examples.get(object_type, 'shorthand')}). "
|
|
373
|
+
f"Full format: object_name:user_id/session_id{voxel_suffix}."
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
opt = optgroup.option(
|
|
377
|
+
"--output",
|
|
378
|
+
"-o",
|
|
379
|
+
"output_uri",
|
|
380
|
+
required=True,
|
|
381
|
+
help=help_text,
|
|
382
|
+
)
|
|
383
|
+
return opt(_func)
|
|
384
|
+
|
|
385
|
+
if func is None:
|
|
386
|
+
return add_output_option_decorator
|
|
387
|
+
else:
|
|
388
|
+
return add_output_option_decorator(func)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def add_dual_input_options(object_type: str, func: click.Command = None) -> Callable:
|
|
392
|
+
"""
|
|
393
|
+
Add --input1/-i1 and --input2/-i2 options for dual input commands.
|
|
394
|
+
|
|
395
|
+
Supports copick URI format for both inputs:
|
|
396
|
+
- Picks/Meshes: object_name:user_id/session_id
|
|
397
|
+
- Segmentations: name:user_id/session_id@voxel_spacing?multilabel=true
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
object_type (str): Type of object ('mesh', 'segmentation').
|
|
401
|
+
func (click.Command, optional): The Click command to which the options will be added.
|
|
402
|
+
|
|
403
|
+
Returns:
|
|
404
|
+
Callable: The Click command with both input options added.
|
|
405
|
+
"""
|
|
406
|
+
|
|
407
|
+
def add_dual_input_options_decorator(_func: click.Command) -> click.Command:
|
|
408
|
+
"""Add --input1 and --input2 options to command."""
|
|
409
|
+
# Determine help text based on object type
|
|
410
|
+
format_examples = {
|
|
411
|
+
"mesh": "object_name:user_id/session_id",
|
|
412
|
+
"segmentation": "name:user_id/session_id@voxel_spacing",
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
format_str = format_examples.get(object_type, "URI")
|
|
416
|
+
|
|
417
|
+
opts = [
|
|
418
|
+
optgroup.option(
|
|
419
|
+
"--input1",
|
|
420
|
+
"-i1",
|
|
421
|
+
"input1_uri",
|
|
422
|
+
required=True,
|
|
423
|
+
help=f"First input {object_type} URI (format: {format_str}). Supports glob patterns.",
|
|
424
|
+
),
|
|
425
|
+
optgroup.option(
|
|
426
|
+
"--input2",
|
|
427
|
+
"-i2",
|
|
428
|
+
"input2_uri",
|
|
429
|
+
required=True,
|
|
430
|
+
help=f"Second input {object_type} URI (format: {format_str}). Supports glob patterns.",
|
|
431
|
+
),
|
|
432
|
+
]
|
|
433
|
+
|
|
434
|
+
for opt in reversed(opts):
|
|
435
|
+
_func = opt(_func)
|
|
436
|
+
|
|
437
|
+
return _func
|
|
438
|
+
|
|
439
|
+
if func is None:
|
|
440
|
+
return add_dual_input_options_decorator
|
|
441
|
+
else:
|
|
442
|
+
return add_dual_input_options_decorator(func)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def add_multi_input_options(object_type: str, func: click.Command = None) -> Callable:
|
|
446
|
+
"""
|
|
447
|
+
Add --input/-i option for multiple URI-based inputs.
|
|
448
|
+
|
|
449
|
+
Supports specifying the same flag multiple times for N-way operations.
|
|
450
|
+
Example: -i input1 -i input2 -i input3
|
|
451
|
+
|
|
452
|
+
Pattern Support:
|
|
453
|
+
- Glob (default): Use * and ? wildcards (e.g., 'name:user*/session-*')
|
|
454
|
+
- Regex: Prefix with 're:' (e.g., 're:name:user\\d+/session-\\d+')
|
|
455
|
+
|
|
456
|
+
Args:
|
|
457
|
+
object_type (str): Type of object ('mesh', 'segmentation').
|
|
458
|
+
func (click.Command, optional): The Click command to which the option will be added.
|
|
459
|
+
|
|
460
|
+
Returns:
|
|
461
|
+
Callable: The Click command with the multi-input option added.
|
|
462
|
+
"""
|
|
463
|
+
|
|
464
|
+
def add_multi_input_options_decorator(_func: click.Command) -> click.Command:
|
|
465
|
+
"""Add --input option to command."""
|
|
466
|
+
format_examples = {
|
|
467
|
+
"mesh": "object_name:user_id/session_id",
|
|
468
|
+
"segmentation": "name:user_id/session_id@voxel_spacing",
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
help_text = (
|
|
472
|
+
f"Input {object_type} URI (format: {format_examples.get(object_type, 'URI')}). "
|
|
473
|
+
f"Can be specified multiple times for N-way operations. "
|
|
474
|
+
f"Supports glob patterns (default) or regex patterns (re: prefix)."
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
opt = optgroup.option(
|
|
478
|
+
"--input",
|
|
479
|
+
"-i",
|
|
480
|
+
"input_uris",
|
|
481
|
+
multiple=True,
|
|
482
|
+
required=True,
|
|
483
|
+
help=help_text,
|
|
484
|
+
)
|
|
485
|
+
return opt(_func)
|
|
486
|
+
|
|
487
|
+
if func is None:
|
|
488
|
+
return add_multi_input_options_decorator
|
|
489
|
+
else:
|
|
490
|
+
return add_multi_input_options_decorator(func)
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def add_reference_mesh_option(func: click.Command = None, required: bool = False) -> Callable:
|
|
494
|
+
"""
|
|
495
|
+
Add --ref-mesh/-rm option for reference mesh input.
|
|
496
|
+
|
|
497
|
+
Args:
|
|
498
|
+
func (click.Command, optional): The Click command to which the option will be added.
|
|
499
|
+
required (bool): Whether the option is required.
|
|
500
|
+
|
|
501
|
+
Returns:
|
|
502
|
+
Callable: The Click command with the reference mesh option added.
|
|
503
|
+
"""
|
|
504
|
+
|
|
505
|
+
def add_reference_mesh_option_decorator(_func: click.Command) -> click.Command:
|
|
506
|
+
"""Add --ref-mesh option to command."""
|
|
507
|
+
opt = optgroup.option(
|
|
508
|
+
"--ref-mesh",
|
|
509
|
+
"-rm",
|
|
510
|
+
"ref_mesh_uri",
|
|
511
|
+
required=required,
|
|
512
|
+
help="Reference mesh URI (format: object_name:user_id/session_id). Supports glob patterns.",
|
|
513
|
+
)
|
|
514
|
+
return opt(_func)
|
|
515
|
+
|
|
516
|
+
if func is None:
|
|
517
|
+
return add_reference_mesh_option_decorator
|
|
518
|
+
else:
|
|
519
|
+
return add_reference_mesh_option_decorator(func)
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def add_reference_seg_option(func: click.Command = None, required: bool = False) -> Callable:
|
|
523
|
+
"""
|
|
524
|
+
Add --ref-seg/-rs option for reference segmentation input.
|
|
525
|
+
|
|
526
|
+
Args:
|
|
527
|
+
func (click.Command, optional): The Click command to which the option will be added.
|
|
528
|
+
required (bool): Whether the option is required.
|
|
529
|
+
|
|
530
|
+
Returns:
|
|
531
|
+
Callable: The Click command with the reference segmentation option added.
|
|
532
|
+
"""
|
|
533
|
+
|
|
534
|
+
def add_reference_seg_option_decorator(_func: click.Command) -> click.Command:
|
|
535
|
+
"""Add --ref-seg option to command."""
|
|
536
|
+
opt = optgroup.option(
|
|
537
|
+
"--ref-seg",
|
|
538
|
+
"-rs",
|
|
539
|
+
"ref_seg_uri",
|
|
540
|
+
required=required,
|
|
541
|
+
help="Reference segmentation URI (format: name:user_id/session_id@voxel_spacing). Supports glob patterns.",
|
|
542
|
+
)
|
|
543
|
+
return opt(_func)
|
|
544
|
+
|
|
545
|
+
if func is None:
|
|
546
|
+
return add_reference_seg_option_decorator
|
|
547
|
+
else:
|
|
548
|
+
return add_reference_seg_option_decorator(func)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def add_tomogram_option(func: click.Command = None, required: bool = True) -> Callable:
|
|
552
|
+
"""
|
|
553
|
+
Add --tomogram/-t option for tomogram URI specification.
|
|
554
|
+
|
|
555
|
+
Tomogram URI format: tomo_type@voxel_spacing
|
|
556
|
+
Example: "wbp@10.0"
|
|
557
|
+
|
|
558
|
+
Args:
|
|
559
|
+
func (click.Command, optional): The Click command to which the option will be added.
|
|
560
|
+
required (bool): Whether the option is required. Default is True.
|
|
561
|
+
|
|
562
|
+
Returns:
|
|
563
|
+
Callable: The Click command with the tomogram option added.
|
|
564
|
+
"""
|
|
565
|
+
|
|
566
|
+
def add_tomogram_option_decorator(_func: click.Command) -> click.Command:
|
|
567
|
+
"""Add --tomogram option to command."""
|
|
568
|
+
opt = optgroup.option(
|
|
569
|
+
"--tomogram",
|
|
570
|
+
"-t",
|
|
571
|
+
"tomogram_uri",
|
|
572
|
+
required=required,
|
|
573
|
+
help="Tomogram URI (format: tomo_type@voxel_spacing). Example: 'wbp@10.0'",
|
|
574
|
+
)
|
|
575
|
+
return opt(_func)
|
|
576
|
+
|
|
577
|
+
if func is None:
|
|
578
|
+
return add_tomogram_option_decorator
|
|
579
|
+
else:
|
|
580
|
+
return add_tomogram_option_decorator(func)
|