Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 43 additions & 15 deletions src/copick_utils/cli/clipmesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
from copick_utils.cli.util import (
add_distance_options,
add_input_option,
add_invert_option,
add_output_option,
add_reference_mesh_option,
add_reference_seg_option,
add_reference_tomogram_option,
add_workers_option,
)
from copick_utils.util.config_models import create_reference_config
Expand All @@ -30,11 +32,13 @@
help="Specific run names to process (default: all runs).",
)
@add_input_option("mesh")
@optgroup.group("\nReference Options", help="Options for reference surface (provide either mesh or segmentation).")
@optgroup.group("\nReference Options", help="Options for reference surface (provide mesh, segmentation, or tomogram).")
@add_reference_mesh_option(required=False)
@add_reference_seg_option(required=False)
@add_reference_tomogram_option(required=False)
@optgroup.group("\nTool Options", help="Options related to this tool.")
@add_distance_options
@add_invert_option
@add_workers_option
@optgroup.group("\nOutput Options", help="Options related to output meshes.")
@add_output_option("mesh", default_tool="clipmesh")
Expand All @@ -52,8 +56,10 @@ def clipmesh(
input_uri,
ref_mesh_uri,
ref_seg_uri,
ref_tomo_uri,
max_distance,
mesh_voxel_spacing,
invert,
workers,
output_uri,
individual_meshes,
Expand All @@ -66,35 +72,50 @@ def clipmesh(
URI Format:
Meshes: object_name:user_id/session_id
Segmentations: name:user_id/session_id@voxel_spacing
Tomograms: tomo_type@voxel_spacing

\b
The reference surface can be either a mesh or a segmentation.
Only mesh vertices within the specified distance will be kept.
The reference surface can be a mesh, segmentation, or tomogram boundary.
By default, vertices within the specified distance will be kept.
Use --invert to keep vertices beyond the specified distance instead.

\b
Examples:
# Limit mesh to vertices near reference mesh surface
copick logical clipmesh -i "membrane:user1/full-001" -rm "boundary:user1/boundary-001" -o "membrane:clipmesh/limited-001" --max-distance 50.0
# Keep vertices within 50Å of mesh reference
copick logical clipmesh -i "membrane:user1/full-001" -rm "boundary:user1/boundary-001" -o "membrane:clipmesh/near-001" --max-distance 50.0

# Limit using segmentation as reference
copick logical clipmesh -i "membrane:user1/full-001" -rs "mask:user1/mask-001@10.0" -o "membrane:clipmesh/limited-001" --max-distance 100.0
# Remove vertices within 50Å of tomogram boundary (keep interior vertices)
copick logical clipmesh -i "membrane:user1/full-001" -rt "wbp@10.0" -o "membrane:clipmesh/interior-001" --max-distance 50.0 --invert

# Keep vertices beyond 100Å from segmentation reference
copick logical clipmesh -i "membrane:user1/full-001" -rs "mask:user1/mask-001@10.0" -o "membrane:clipmesh/far-001" --max-distance 100.0 --invert
"""
from copick_utils.logical.distance_operations import limit_mesh_by_distance_lazy_batch

logger = get_logger(__name__, debug=debug)

# Validate that exactly one reference type is provided
if not ref_mesh_uri and not ref_seg_uri:
raise click.BadParameter("Must provide either --ref-mesh or --ref-seg")
if ref_mesh_uri and ref_seg_uri:
raise click.BadParameter("Cannot provide both --ref-mesh and --ref-seg")
ref_count = sum(1 for ref in [ref_mesh_uri, ref_seg_uri, ref_tomo_uri] if ref)
if ref_count == 0:
raise click.BadParameter("Must provide one of --ref-mesh, --ref-seg, or --ref-tomogram")
if ref_count > 1:
raise click.BadParameter(
"Cannot provide multiple reference options. Choose one of --ref-mesh, --ref-seg, or --ref-tomogram",
)

root = copick.from_file(config)
run_names_list = list(run_names) if run_names else None

# Determine reference type and URI
reference_uri = ref_mesh_uri or ref_seg_uri
reference_type = "mesh" if ref_mesh_uri else "segmentation"
if ref_mesh_uri:
reference_uri = ref_mesh_uri
reference_type = "mesh"
elif ref_seg_uri:
reference_uri = ref_seg_uri
reference_type = "segmentation"
else:
reference_uri = ref_tomo_uri
reference_type = "tomogram"

# Create config directly from URIs with additional params for distance operations
try:
Expand All @@ -105,7 +126,11 @@ def clipmesh(
output_type="mesh",
reference_uri=reference_uri,
reference_type=reference_type,
additional_params={"max_distance": max_distance, "mesh_voxel_spacing": mesh_voxel_spacing},
additional_params={
"max_distance": max_distance,
"mesh_voxel_spacing": mesh_voxel_spacing,
"invert": invert,
},
command_name="clipmesh",
)
except ValueError as e:
Expand All @@ -120,11 +145,14 @@ def clipmesh(
logger.info(f"Source mesh pattern: {input_params['user_id']}/{input_params['session_id']}")
if reference_type == "mesh":
logger.info(f"Reference mesh: {ref_params['object_name']} ({ref_params['user_id']}/{ref_params['session_id']})")
else:
elif reference_type == "segmentation":
logger.info(
f"Reference segmentation: {ref_params['name']} ({ref_params['user_id']}/{ref_params['session_id']})",
)
else:
logger.info(f"Reference tomogram boundary: {ref_params['tomo_type']}@{ref_params['voxel_spacing']}")
logger.info(f"Maximum distance: {max_distance} angstroms")
logger.info(f"Mode: {'keep beyond distance (invert)' if invert else 'keep within distance'}")
logger.info(
f"Target mesh template: {output_params['object_name']} ({output_params['user_id']}/{output_params['session_id']})",
)
Expand Down
58 changes: 43 additions & 15 deletions src/copick_utils/cli/clippicks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
from copick_utils.cli.util import (
add_distance_options,
add_input_option,
add_invert_option,
add_output_option,
add_reference_mesh_option,
add_reference_seg_option,
add_reference_tomogram_option,
add_workers_option,
)
from copick_utils.util.config_models import create_reference_config
Expand All @@ -32,11 +34,13 @@
help="Specific run names to process (default: all runs).",
)
@add_input_option("picks")
@optgroup.group("\nReference Options", help="Options for reference surface (provide either mesh or segmentation).")
@optgroup.group("\nReference Options", help="Options for reference surface (provide mesh, segmentation, or tomogram).")
@add_reference_mesh_option(required=False)
@add_reference_seg_option(required=False)
@add_reference_tomogram_option(required=False)
@optgroup.group("\nTool Options", help="Options related to this tool.")
@add_distance_options
@add_invert_option
@add_workers_option
@optgroup.group("\nOutput Options", help="Options related to output picks.")
@add_output_option("picks", default_tool="clippicks")
Expand All @@ -47,8 +51,10 @@ def clippicks(
input_uri,
ref_mesh_uri,
ref_seg_uri,
ref_tomo_uri,
max_distance,
mesh_voxel_spacing,
invert,
workers,
output_uri,
debug,
Expand All @@ -61,35 +67,50 @@ def clippicks(
Picks: object_name:user_id/session_id
Meshes: object_name:user_id/session_id
Segmentations: name:user_id/session_id@voxel_spacing
Tomograms: tomo_type@voxel_spacing

\b
The reference surface can be either a mesh or a segmentation.
Only picks within the specified distance will be kept.
The reference surface can be a mesh, segmentation, or tomogram boundary.
By default, picks within the specified distance will be kept.
Use --invert to keep picks beyond the specified distance instead.

\b
Examples:
# Limit picks to those near reference mesh surface
copick logical clippicks -i "ribosome:user1/all-001" -rm "boundary:user1/boundary-001" -o "ribosome:clippicks/limited-001" --max-distance 50.0
# Keep picks within 50Å of mesh reference
copick logical clippicks -i "ribosome:user1/all-001" -rm "boundary:user1/boundary-001" -o "ribosome:clippicks/near-001" --max-distance 50.0

# Limit using segmentation as reference
copick logical clippicks -i "ribosome:user1/all-001" -rs "mask:user1/mask-001@10.0" -o "ribosome:clippicks/limited-001" --max-distance 100.0
# Remove picks within 50Å of tomogram boundary (keep interior picks)
copick logical clippicks -i "ribosome:user1/all-001" -rt "wbp@10.0" -o "ribosome:clippicks/interior-001" --max-distance 50.0 --invert

# Keep picks beyond 100Å from segmentation reference
copick logical clippicks -i "ribosome:user1/all-001" -rs "mask:user1/mask-001@10.0" -o "ribosome:clippicks/far-001" --max-distance 100.0 --invert
"""
from copick_utils.logical.distance_operations import limit_picks_by_distance_lazy_batch

logger = get_logger(__name__, debug=debug)

# Validate that exactly one reference type is provided
if not ref_mesh_uri and not ref_seg_uri:
raise click.BadParameter("Must provide either --ref-mesh or --ref-seg")
if ref_mesh_uri and ref_seg_uri:
raise click.BadParameter("Cannot provide both --ref-mesh and --ref-seg")
ref_count = sum(1 for ref in [ref_mesh_uri, ref_seg_uri, ref_tomo_uri] if ref)
if ref_count == 0:
raise click.BadParameter("Must provide one of --ref-mesh, --ref-seg, or --ref-tomogram")
if ref_count > 1:
raise click.BadParameter(
"Cannot provide multiple reference options. Choose one of --ref-mesh, --ref-seg, or --ref-tomogram",
)

root = copick.from_file(config)
run_names_list = list(run_names) if run_names else None

# Determine reference type and URI
reference_uri = ref_mesh_uri or ref_seg_uri
reference_type = "mesh" if ref_mesh_uri else "segmentation"
if ref_mesh_uri:
reference_uri = ref_mesh_uri
reference_type = "mesh"
elif ref_seg_uri:
reference_uri = ref_seg_uri
reference_type = "segmentation"
else:
reference_uri = ref_tomo_uri
reference_type = "tomogram"

# Create config directly from URIs with additional params
try:
Expand All @@ -100,7 +121,11 @@ def clippicks(
output_type="picks",
reference_uri=reference_uri,
reference_type=reference_type,
additional_params={"max_distance": max_distance, "mesh_voxel_spacing": mesh_voxel_spacing},
additional_params={
"max_distance": max_distance,
"mesh_voxel_spacing": mesh_voxel_spacing,
"invert": invert,
},
command_name="clippicks",
)
except ValueError as e:
Expand All @@ -115,11 +140,14 @@ def clippicks(
logger.info(f"Source picks pattern: {input_params['user_id']}/{input_params['session_id']}")
if reference_type == "mesh":
logger.info(f"Reference mesh: {ref_params['object_name']} ({ref_params['user_id']}/{ref_params['session_id']})")
else:
elif reference_type == "segmentation":
logger.info(
f"Reference segmentation: {ref_params['name']} ({ref_params['user_id']}/{ref_params['session_id']})",
)
else:
logger.info(f"Reference tomogram boundary: {ref_params['tomo_type']}@{ref_params['voxel_spacing']}")
logger.info(f"Maximum distance: {max_distance} angstroms")
logger.info(f"Mode: {'keep beyond distance (invert)' if invert else 'keep within distance'}")
logger.info(
f"Target picks template: {output_params['object_name']} ({output_params['user_id']}/{output_params['session_id']})",
)
Expand Down
53 changes: 39 additions & 14 deletions src/copick_utils/cli/clipseg.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
from copick_utils.cli.util import (
add_distance_options,
add_input_option,
add_invert_option,
add_output_option,
add_reference_mesh_option,
add_reference_seg_option,
add_reference_tomogram_option,
add_workers_option,
)
from copick_utils.util.config_models import create_reference_config
Expand All @@ -30,11 +32,13 @@
help="Specific run names to process (default: all runs).",
)
@add_input_option("segmentation")
@optgroup.group("\nReference Options", help="Options for reference surface (provide either mesh or segmentation).")
@optgroup.group("\nReference Options", help="Options for reference surface (provide mesh, segmentation, or tomogram).")
@add_reference_mesh_option(required=False)
@add_reference_seg_option(required=False)
@add_reference_tomogram_option(required=False)
@optgroup.group("\nTool Options", help="Options related to this tool.")
@add_distance_options
@add_invert_option
@add_workers_option
@optgroup.group("\nOutput Options", help="Options related to output segmentations.")
@add_output_option("segmentation", default_tool="clipseg")
Expand All @@ -45,8 +49,10 @@ def clipseg(
input_uri,
ref_mesh_uri,
ref_seg_uri,
ref_tomo_uri,
max_distance,
mesh_voxel_spacing,
invert,
workers,
output_uri,
debug,
Expand All @@ -58,35 +64,50 @@ def clipseg(
URI Format:
Segmentations: name:user_id/session_id@voxel_spacing
Meshes: object_name:user_id/session_id
Tomograms: tomo_type@voxel_spacing

\b
The reference surface can be either a mesh or another segmentation.
Only segmentation voxels within the specified distance will be kept.
The reference surface can be a mesh, segmentation, or tomogram boundary.
By default, voxels within the specified distance will be kept.
Use --invert to keep voxels beyond the specified distance instead.

\b
Examples:
# Limit segmentation to voxels near reference mesh
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
# Keep voxels within 50Å of mesh reference
copick logical clipseg -i "membrane:user1/full-001@10.0" -rm "boundary:user1/boundary-001" -o "membrane:clipseg/near-001@10.0" --max-distance 50.0

# Limit using another segmentation as reference
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
# Remove voxels within 50Å of tomogram boundary (keep interior voxels)
copick logical clipseg -i "membrane:user1/full-001@10.0" -rt "wbp@10.0" -o "membrane:clipseg/interior-001@10.0" --max-distance 50.0 --invert

# Keep voxels beyond 100Å from segmentation reference
copick logical clipseg -i "membrane:user1/full-001@10.0" -rs "mask:user1/mask-001@10.0" -o "membrane:clipseg/far-001@10.0" --max-distance 100.0 --invert
"""
from copick_utils.logical.distance_operations import limit_segmentation_by_distance_lazy_batch

logger = get_logger(__name__, debug=debug)

# Validate that exactly one reference type is provided
if not ref_mesh_uri and not ref_seg_uri:
raise click.BadParameter("Must provide either --ref-mesh or --ref-seg")
if ref_mesh_uri and ref_seg_uri:
raise click.BadParameter("Cannot provide both --ref-mesh and --ref-seg")
ref_count = sum(1 for ref in [ref_mesh_uri, ref_seg_uri, ref_tomo_uri] if ref)
if ref_count == 0:
raise click.BadParameter("Must provide one of --ref-mesh, --ref-seg, or --ref-tomogram")
if ref_count > 1:
raise click.BadParameter(
"Cannot provide multiple reference options. Choose one of --ref-mesh, --ref-seg, or --ref-tomogram",
)

root = copick.from_file(config)
run_names_list = list(run_names) if run_names else None

# Determine reference type and URI
reference_uri = ref_mesh_uri or ref_seg_uri
reference_type = "mesh" if ref_mesh_uri else "segmentation"
if ref_mesh_uri:
reference_uri = ref_mesh_uri
reference_type = "mesh"
elif ref_seg_uri:
reference_uri = ref_seg_uri
reference_type = "segmentation"
else:
reference_uri = ref_tomo_uri
reference_type = "tomogram"

# Extract voxel_spacing and multilabel from output for additional_params
output_params_temp = parse_copick_uri(output_uri, "segmentation")
Expand All @@ -109,6 +130,7 @@ def clipseg(
"mesh_voxel_spacing": mesh_voxel_spacing,
"voxel_spacing": voxel_spacing_output,
"is_multilabel": multilabel_output,
"invert": invert,
},
command_name="clipseg",
)
Expand All @@ -124,11 +146,14 @@ def clipseg(
logger.info(f"Source segmentation pattern: {input_params['user_id']}/{input_params['session_id']}")
if reference_type == "mesh":
logger.info(f"Reference mesh: {ref_params['object_name']} ({ref_params['user_id']}/{ref_params['session_id']})")
else:
elif reference_type == "segmentation":
logger.info(
f"Reference segmentation: {ref_params['name']} ({ref_params['user_id']}/{ref_params['session_id']})",
)
else:
logger.info(f"Reference tomogram boundary: {ref_params['tomo_type']}@{ref_params['voxel_spacing']}")
logger.info(f"Maximum distance: {max_distance} angstroms")
logger.info(f"Mode: {'keep beyond distance (invert)' if invert else 'keep within distance'}")
logger.info(
f"Target segmentation template: {output_params['name']} ({output_params['user_id']}/{output_params['session_id']})",
)
Expand Down
Loading