crantpy.utils package#

Subpackages#

Submodules#

Module contents#

exception crantpy.utils.FilteringError(message=None)[source]#

Bases: ValueError

Raised if a filtering operation fails.

Parameters:

message (str, optional) – The error message.

Return type:

None

exception crantpy.utils.NoMatchesError(message=None)[source]#

Bases: ValueError

Raised if no matches are found.

Parameters:

message (str, optional) – The error message.

Return type:

None

crantpy.utils.add_annotation_layer(annotations, scene, name=None, connected=False)[source]#

Add annotations as new layer to scene.

Parameters:
  • annotations (array or list) – Coordinates for annotations (in voxel space): - (N, 3): Point annotations at x/y/z coordinates - (N, 2, 3): Line segments with start and end points - (N, 4): Ellipsoids with x/y/z center and radius

  • scene (dict) – Scene to add annotation layer to.

  • name (str, optional) – Name for the annotation layer.

  • connected (bool, default False) – If True, point annotations will be connected as a path (TODO).

Returns:

Modified scene with annotation layer added.

Return type:

dict

Examples

>>> # Add point annotations
>>> points = np.array([[100, 200, 50], [150, 250, 60]])
>>> scene = add_annotation_layer(points, scene, name="my_points")
>>>
>>> # Add line annotations
>>> lines = np.array([
...     [[100, 200, 50], [150, 250, 60]],
...     [[150, 250, 60], [200, 300, 70]]
... ])
>>> scene = add_annotation_layer(lines, scene, name="my_lines")
crantpy.utils.add_skeleton_layer(skeleton, scene, name=None)[source]#

Add skeleton as line annotation layer to scene.

Parameters:
  • skeleton (TreeNeuron or DataFrame) – Neuron skeleton to add. Coordinates must be in nanometers. Will be automatically converted to voxel space.

  • scene (dict) – Scene to add skeleton layer to.

  • name (str, optional) – Name for the skeleton layer.

Returns:

Modified scene with skeleton layer added.

Return type:

dict

Examples

>>> skeleton = crt.viz.get_skeletons([720575940621039145])[0]
>>> scene = construct_scene()
>>> scene = add_skeleton_layer(skeleton, scene)
crantpy.utils.cached_result(cache_name, max_age=7200, key_fn=None, should_cache_fn=None, validate_cache_fn=None)[source]#

Decorator for caching function results.

WARNING: This decorator is not thread-safe. It is recommended to use threading.Lock() to ensure thread safety when using this decorator in a multi-threaded environment.

This decorator provides a flexible caching mechanism for function results. It supports custom cache keys, validation, and conditional caching, making it suitable for a variety of use cases.

The cache stores entries in a dictionary structure: {

‘result’: original_function_result, ‘metadata’: {

‘_created_at’: timestamp

}

}

This approach avoids modifying the original result objects directly, ensuring compatibility with immutable types.

Parameters:
  • cache_name (str) – Name of the global cache to use. This is used to group cached results under a specific namespace.

  • max_age (int, default MAXIMUM_CACHE_DURATION) – Maximum age of cached result in seconds. Cached results older than this duration are considered stale and will be refreshed.

  • key_fn (callable, optional) – Function to generate a unique cache key based on the function’s arguments. Defaults to using the first positional argument or the ‘dataset’ keyword argument. If the function returns None, an error will be raised.

  • should_cache_fn (callable, optional) – Function to determine whether the result of the function should be cached. It takes the function result and arguments as input and returns a boolean.

  • validate_cache_fn (callable, optional) – Function to validate if a cached result is still valid beyond the age check. It takes the cached result and the function arguments as input and returns a boolean.

Returns:

The decorated function with caching capabilities.

Return type:

callable

Examples

>>> # Basic Caching:
>>> @cached_result(cache_name="example_cache")
>>> def expensive_function(x):
>>>     return x ** 2
>>> # Custom Cache Key:
>>> @cached_result(cache_name="example_cache", key_fn=lambda x: f"key_{x}")
>>> def expensive_function(x):
>>>     return x ** 2
>>> # Conditional Caching:
>>> @cached_result(cache_name="example_cache", should_cache_fn=lambda result, *args: result > 10)
>>> def expensive_function(x):
>>>     return x ** 2
>>> # Cache Validation:
>>> def validate_cache(result, *args):
>>>     return result is not None
>>> @cached_result(cache_name="example_cache", validate_cache_fn=validate_cache)
>>> def expensive_function(x):
>>>     return x ** 2

Notes

  • The decorated function gains a clear_cache method to manually clear the cache for the specified cache_name.

  • The check_stale parameter can be used to skip staleness checks when calling the decorated function.

crantpy.utils.clear_all_caches()[source]#

Clears all caches.

Return type:

None

crantpy.utils.clear_cave_client_cache()[source]#

Clears the CAVE client cache.

Return type:

None

crantpy.utils.clear_cloudvolume_cache()[source]#

Clears the cloudvolume cache.

Return type:

None

crantpy.utils.clear_global_cache(cache_name)[source]#

Clear a named global cache.

Parameters:

cache_name (str) – Name of the cache to clear

Return type:

None

crantpy.utils.construct_scene(*, image=True, segmentation=True, brain_mesh=True, merge_biased_seg=False, nuclei=False, base_neuroglancer=False, layout='xy-3d', dataset=None)[source]#

Construct a basic neuroglancer scene for CRANT data.

Parameters:
  • image (bool, default True) – Whether to add the aligned EM image layer.

  • segmentation (bool, default True) – Whether to add the proofreadable segmentation layer.

  • brain_mesh (bool, default True) – Whether to add the brain mesh layer.

  • merge_biased_seg (bool, default False) – Whether to add the merge-biased segmentation layer (for proofreading).

  • nuclei (bool, default False) – Whether to add the nuclei segmentation layer.

  • base_neuroglancer (bool, default False) – Whether to use base neuroglancer (affects segmentation layer format).

  • layout (str, default "xy-3d") – Layout to show. Options: “3d”, “xy-3d”, “xy”, “4panel”.

  • dataset (str, optional) – Which dataset to use (“latest” or “sandbox”). If None, uses default.

Returns:

Neuroglancer scene dictionary with requested layers.

Return type:

dict

Examples

>>> # Create a minimal visualization scene
>>> scene = construct_scene(image=True, segmentation=True, brain_mesh=True)
>>>
>>> # Create a full proofreading scene
>>> scene = construct_scene(
...     image=True,
...     segmentation=True,
...     brain_mesh=True,
...     merge_biased_seg=True,
...     nuclei=True
... )
crantpy.utils.create_sql_query(table_name, fields, condition=None, limit=None, start=None)[source]#

Creates a SQL query to get the specified fields from the specified table.

Parameters:
  • table_name (str) – The name of the table to query.

  • fields (List[str]) – The list of field names to include in the query.

  • condition (str, optional) – The WHERE clause of the query.

  • limit (int, optional) – The maximum number of rows to return.

  • start (int, optional) – The number of rows to skip (OFFSET).

Returns:

The constructed SQL query string.

Return type:

str

crantpy.utils.decode_url(url, format='json')[source]#

Decode neuroglancer URL to extract information.

Parameters:
  • url (str or list of str) – Neuroglancer URL(s) to decode.

  • format (str, default "json") – Output format: - “json”: Full scene dictionary - “brief”: Dict with position, selected segments, and annotations - “dataframe”: DataFrame with segment IDs and their layers

Returns:

Decoded information in requested format.

Return type:

dict or DataFrame

Examples

>>> url = "https://spelunker.cave-explorer.org/#!{...}"
>>> info = decode_url(url, format='brief')
>>> print(info['selected'])  # List of selected segment IDs
>>> print(info['position'])  # [x, y, z] coordinates
crantpy.utils.encode_url(segments=None, annotations=None, coords=None, skeletons=None, skeleton_names=None, seg_colors=None, seg_groups=None, invis_segs=None, scene=None, base_neuroglancer=False, layout='xy-3d', open=False, to_clipboard=False, shorten=False, *, dataset=None)[source]#

Encode data as CRANT neuroglancer scene URL.

Parameters:
  • segments (int or list of int, optional) – Segment IDs (root IDs) to have selected in the scene.

  • annotations (array or dict, optional) – Coordinates for annotations: - (N, 3) array: Point annotations at x/y/z coordinates (in voxels) - dict: Multiple annotation layers {name: (N, 3) array}

  • coords ((3,) array, optional) – X, Y, Z coordinates (in voxels) to center the view on.

  • skeletons (TreeNeuron or NeuronList, optional) – Skeleton(s) to add as annotation layer(s). Must be in nanometers.

  • skeleton_names (str or list of str, optional) – Names for the skeleton(s) to display in the UI. If a single string is provided, it will be used for all skeletons. If a list is provided, its length must match the number of skeletons.

  • seg_colors (str, tuple, list, dict, or array, optional) – Colors for segments: - str or tuple: Single color for all segments - list: List of colors matching segments - dict: Mapping of segment IDs to colors - array: Labels that will be converted to colors

  • seg_groups (list or dict, optional) – Group segments into separate layers: - list: Group labels matching segments - dict: {group_name: [seg_id1, seg_id2, …]}

  • invis_segs (int or list, optional) – Segment IDs to select but keep invisible.

  • scene (dict or str, optional) – Existing scene to modify (as dict or URL string).

  • base_neuroglancer (bool, default False) – Whether to use base neuroglancer instead of CAVE Spelunker.

  • layout (str, default "xy-3d") – Layout to show. Options: “3d”, “xy-3d”, “xy”, “4panel”.

  • open (bool, default False) – If True, opens the URL in a web browser.

  • to_clipboard (bool, default False) – If True, copies the URL to clipboard (requires pyperclip).

  • shorten (bool, default False) – If True, creates a shortened URL (requires state server).

  • dataset (str, optional) – Which dataset to use. If None, uses default.

Returns:

Neuroglancer URL.

Return type:

str

Examples

>>> # Simple scene with segments
>>> url = encode_url(segments=[720575940621039145, 720575940621039146])
>>>
>>> # Scene with colored segments
>>> url = encode_url(
...     segments=[720575940621039145, 720575940621039146],
...     seg_colors={720575940621039145: 'red', 720575940621039146: 'blue'}
... )
>>>
>>> # Scene with skeleton and centered view
>>> import navis
>>> skeleton = crt.viz.get_skeletons([720575940621039145])[0]
>>> url = encode_url(
...     segments=[720575940621039145],
...     skeletons=skeleton,
...     coords=[24899, 14436, 3739]
... )
crantpy.utils.filter_df(df, column, value, regex=False, case=False, match_all=False, exact=True)[source]#

This function filters a df based on a column and a value. It can handle string, numeric, and list-containing columns.

Parameters:
  • (pd.DataFrame) (df)

  • (str) (column)

  • (Any) (value)

  • (bool) (exact)

  • (bool)

  • (bool) – if True, requires all filter values to be present in the cell’s list. If False, requires at least one filter value to be present. Defaults to False.

  • (bool)

  • df (pandas.DataFrame)

  • column (str)

  • value (Any)

  • regex (bool)

  • case (bool)

  • match_all (bool)

  • exact (bool)

Returns:

pd.DataFrame

Return type:

The filtered df.

crantpy.utils.find_common_time(root_ids, progress=True, *, dataset=None)[source]#

Find a time at which given root IDs co-existed.

Parameters:
  • root_ids (list | np.ndarray) – Root IDs to check.

  • progress (bool) – If True, shows progress bar.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

A timestamp when all root IDs existed simultaneously.

Return type:

datetime.datetime

Examples

>>> from crantpy.utils.cave.segmentation import find_common_time
>>> common_time = find_common_time([123456789, 987654321])
crantpy.utils.generate_cave_token(save=False)[source]#

Generates a token for the CAVE client. If save is True, the token will be saved (overwriting any existing token).

Parameters:

save (bool, default False) – Whether to save the token after generation.

Return type:

None

crantpy.utils.get_all_seatable_annotations(dataset=None, proofread_only=False, clear_cache=False, check_stale=True)[source]#

Uses Seatable API to get the table object for the CRANTb project. Handles pagination to retrieve all rows even if exceeding the API limit. Caches the result to avoid redundant API calls.

Parameters:
  • proofread_only (bool, default False) – If True, only retrieve annotations marked as proofread.

  • clear_cache (bool, default False) – If True, bypass the cache and fetch fresh data from Seatable.

  • check_stale (bool, default True) – If True, check if the cache is stale before using it based on the maximum cache duration.

  • dataset (str, optional) – The dataset to use. If not provided, uses the default dataset from the environment variable.

Returns:

DataFrame containing the annotations.

Return type:

pd.DataFrame

crantpy.utils.get_cave_client(dataset=None, clear_cache=False, check_stale=True)[source]#

Returns a CAVE client instance. If a token is already set, it will be used for authentication. Otherwise, a new token will be generated.

Parameters:
  • clear_cache (bool, default False) – If True, bypasses the cache and fetches a new client.

  • check_stale (bool, default True) – If True, checks if the cached client is stale based on materialization and maximum cache duration.

  • dataset (str, optional) – The dataset to use. If not provided, uses the default dataset.

Returns:

A CAVE client instance authenticated with the token.

Return type:

CAVEclient

Raises:

ValueError – If no token is found after attempting to generate one.

crantpy.utils.get_cave_datastacks()[source]#

Get available CAVE datastacks.

Return type:

list

crantpy.utils.get_cloudvolume(dataset=None, clear_cache=False, check_stale=True, **kwargs)[source]#

Returns a cloudvolume instance.

Parameters:
  • dataset (str | None)

  • clear_cache (bool)

  • check_stale (bool)

Return type:

caveclient.CAVEclient

crantpy.utils.get_current_cave_token()[source]#

Retrieves the current token from the CAVE client.

Returns:

The current CAVE token.

Return type:

str

Raises:

ValueError – If no token is found.

crantpy.utils.get_dataset_segmentation_source(dataset)[source]#

Get segmentation source for given dataset.

Parameters:

dataset (str)

Return type:

str

crantpy.utils.get_datastack_segmentation_source(datastack)[source]#

Get segmentation source for given CAVE datastack.

Return type:

str

crantpy.utils.get_global_cache(cache_name)[source]#

Get a named global cache dictionary.

Parameters:

cache_name (str) – Name of the cache to retrieve

Returns:

The requested cache dictionary

Return type:

dict

crantpy.utils.get_lineage_graph(x, progress=True, *, dataset=None)[source]#

Get lineage graph for given neuron.

Parameters:
  • x (int) – A single root ID.

  • progress (bool) – If True, show progress bar.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

The lineage graph showing the history of edits for this root ID.

Return type:

networkx.DiGraph

Examples

>>> from crantpy.utils.cave.segmentation import get_lineage_graph
>>> G = get_lineage_graph(720575940621039145)
>>> len(G.nodes())
150
crantpy.utils.get_proofread_neurons(dataset=None, clear_cache=False)[source]#

Get the root IDs of neurons that are proofread.

Parameters:
  • dataset (str, optional) – Dataset to fetch annotations from.

  • clear_cache (bool, default False) – Whether to force reloading annotations from Seatable, bypassing the cache.

Returns:

Array of root IDs of proofread neurons.

Return type:

numpy.ndarray

crantpy.utils.get_seatable_base_object()[source]#

Uses Seatable API to get the base object for the CRANTpy project.

Returns:

The authenticated Seatable Base object.

Return type:

seatable_api.Base

crantpy.utils.get_seatable_cache_name(*args, **kwargs)[source]#

Returns the name of the Seatable cache based on the dataset and proofread_only status.

Return type:

str

crantpy.utils.get_segmentation_cutout(bbox, root_ids=True, mip=0, coordinates='nm', *, dataset=None)[source]#

Fetch cutout of segmentation.

Parameters:
  • bbox (array-like) –

    Bounding box for the cutout::

    [[xmin, xmax], [ymin, ymax], [zmin, zmax]]

  • root_ids (bool) – If True, will return root IDs. If False, will return supervoxel IDs.

  • mip (int) – Scale at which to fetch the cutout.

  • coordinates ("voxel" | "nm") – Units in which your coordinates are in.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

  • cutout (np.ndarray) – (N, M, P) array of segmentation (root or supervoxel) IDs.

  • resolution ((3, ) numpy array) – [x, y, z] resolution of voxel in cutout.

  • nm_offset ((3, ) numpy array) – [x, y, z] offset in nanometers of the cutout with respect to the absolute coordinates.

Examples

>>> from crantpy.utils.cave.segmentation import get_segmentation_cutout
>>> bbox = [[100000, 100100], [50000, 50100], [3000, 3010]]
>>> cutout, resolution, offset = get_segmentation_cutout(bbox)
crantpy.utils.get_voxels(x, mip=0, bounds=None, sv_map=False, thin=False, use_l2_chunks=True, threads=1, progress=True, *, dataset=None)[source]#

Fetch voxels making up a given root ID.

This function has two modes: 1. L2 chunk-based (default): Fetches voxels chunk by chunk using L2 IDs 2. Cutout-based: Downloads entire bounding box and extracts voxels

IMPORTANT - CloudVolume Limitations:

CloudVolume has limited spatial coverage (~360 x 344 x 257 µm) and is missing CAVE’s highest resolution layer. For most use cases, prefer: - get_l2_skeleton() for full neuron morphology - get_mesh() for 3D visualization - This function only for specific voxel-level analysis in small regions

Parameters:
  • x (int) – A single root ID.

  • mip (int) – Scale at which to fetch voxels. For example, mip=0 is at highest resolution (16x16x42 nm/voxel for CloudVolume). Every subsequent mip halves the resolution. Use higher mip for faster queries: mip=1 is often sufficient.

  • bounds ((3, 2) or (2, 3) array, optional) – Bounding box to return voxels in (in nanometers). Format: [[xmin, xmax], [ymin, ymax], [zmin, zmax]] REQUIRED in practice - without bounds, will attempt to fetch entire neuron which may exceed CloudVolume coverage. Use small regions (< 10 µm per dimension) for best results.

  • sv_map (bool) – If True, additionally return a map with the supervoxel ID for each voxel. Useful for detailed connectivity analysis.

  • thin (bool) – If True, will remove voxels at the interface of adjacent supervoxels that are not supposed to be connected according to the L2 graph. Useful for neurons that self-touch. WARNING: This is computationally expensive!

  • use_l2_chunks (bool) – If True (default), fetch voxels chunk by chunk using L2 IDs. Faster and more memory efficient for neurons with L2 metadata. If False, download entire bounding box as single cutout.

  • threads (int) – Number of parallel threads for CloudVolume operations. More threads = faster but more memory usage.

  • progress (bool) – Whether to show a progress bar or not.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

  • voxels ((N, 3) np.ndarray) – Voxel coordinates in voxel space according to mip. Each row is [x, y, z] in voxel coordinates.

  • sv_map ((N, ) np.ndarray) – Supervoxel ID for each voxel. Only if sv_map=True.

Raises:

ValueError – If bounds exceed CloudVolume coverage or if root ID is invalid.

Examples

>>> from crantpy.utils.cave.segmentation import get_voxels
>>> # RECOMMENDED: Always use explicit bounds within CloudVolume coverage
>>> bounds = [[100000, 105000], [50000, 55000], [3000, 3100]]
>>> voxels = get_voxels(720575940621039145, bounds=bounds, mip=1)
>>> print(f"Retrieved {len(voxels)} voxels")
>>> # Get voxels with supervoxel mapping for detailed analysis
>>> voxels, svids = get_voxels(
...     720575940621039145,
...     bounds=bounds,
...     mip=1,
...     sv_map=True
... )
>>> print(f"Voxels from {len(np.unique(svids))} supervoxels")
>>> # Use cutout method for small regions without L2 metadata
>>> voxels = get_voxels(
...     720575940621039145,
...     bounds=bounds,
...     mip=1,
...     use_l2_chunks=False
... )

Notes

Coordinate System: - Input bounds are in nanometers (CAVE standard) - Output voxels are in voxel space at the specified MIP level - CloudVolume resolution at MIP 0: [16, 16, 42] nm/voxel - To convert voxels to nm: voxels * resolution

Performance Tips: - Use mip=1 (32x32x42 nm/voxel) for faster queries when precise

resolution isn’t critical

  • Keep bounds small (< 10 µm per dimension) to avoid timeouts

  • Set use_l2_chunks=True (default) for neurons with L2 metadata

  • Disable sv_map if you don’t need supervoxel IDs (faster)

  • Only use thin=True when absolutely necessary (very slow)

Common Issues: - “Bounds exceed CloudVolume coverage”: Your bounds are outside the

~360 µm cube that CloudVolume contains. Try smaller bounds or check if your neuron is within CloudVolume’s spatial coverage.

  • Slow performance: Reduce bounds size, increase mip level, or use get_l2_skeleton() instead for full neuron morphology.

  • Empty result: The neuron may not have voxels in the specified bounds, or bounds may need adjustment.

See also

get_l2_skeleton

Get skeleton representation (better for full neurons)

get_mesh

Get 3D mesh (better for visualization)

get_segmentation_cutout

Get all segmentation in a region

crantpy.utils.inject_dataset(allowed=None, disallowed=None, param_name='dataset')[source]#

Inject current default dataset.

Parameters:
  • allowed (List[str] or str, optional) – List of allowed datasets or a single allowed dataset.

  • disallowed (List[str] or str, optional) – List of disallowed datasets or a single disallowed dataset.

  • param_name (str, default 'dataset') – Name of the parameter to inject the dataset into.

Returns:

Decorator function that injects the dataset.

Return type:

Callable

crantpy.utils.is_latest_roots(x, timestamp=None, dataset=None, progress=True, batch_size=100000, validate_ids=True, use_http_session=True)[source]#

Check if the given root IDs are the latest based on the timestamp.

Parameters:
  • x (IDs = str | int | np.int64) – The root IDs to check.

  • timestamp (Timestamp = str | int | np.int64 | datetime | np.datetime64 | pd.Timestamp) – The timestamp to compare against. Can also be “mat” for the latest materialization timestamp.

  • dataset (str, optional) – The dataset to use.

  • progress (bool, default True) – Whether to show progress bar for large batches.

  • batch_size (int, default 100_000) – Batch size for processing large numbers of IDs.

  • validate_ids (bool, default True) – Whether to validate root IDs before processing.

  • use_http_session (bool, default True) – Whether to use direct HTTP session for better performance.

Returns:

A boolean array indicating whether each root ID is the latest.

Return type:

np.ndarray

Examples

>>> from crantpy.utils.cave.helpers import is_latest_roots
>>> is_latest_roots([123456789, 987654321])
array([ True, False])
>>> # Check against latest materialization
>>> is_latest_roots([123456789], timestamp="mat")
array([ True])
crantpy.utils.is_valid_root(x, dataset=None, raise_exc=False)[source]#

Check if ID is (potentially) valid root ID.

Parameters:
  • x (IDs = str | int | np.int64) – The root IDs to check.

  • dataset (str, optional) – The dataset to use.

  • raise_exc (bool, default False) – Whether to raise an exception if invalid IDs are found.

Returns:

A boolean array indicating whether each root ID is valid.

Return type:

np.ndarray

Raises:

ValueError – If raise_exc is True and invalid IDs are found.

crantpy.utils.is_valid_supervoxel(x, dataset=None, raise_exc=False)[source]#

Check if ID is (potentially) valid supervoxel ID.

Parameters:
  • x (IDs = str | int | np.int64) – The supervoxel IDs to check.

  • dataset (str, optional) – The dataset to use.

  • raise_exc (bool, default False) – Whether to raise an exception if invalid IDs are found.

Returns:

If x is a single ID, returns bool. If x is iterable, returns array.

Return type:

bool or np.ndarray

Raises:

ValueError – If raise_exc is True and invalid IDs are found.

See also

is_valid_root

Use this function to check if a root ID is valid.

crantpy.utils.locs_to_segments(locs, timestamp=None, coordinates='nm', progress=True, *, dataset=None)[source]#

Retrieve segment (i.e. root) IDs at given location(s).

Parameters:
  • locs (array-like | pandas.DataFrame) – Array of x/y/z coordinates. If DataFrame must contain ‘x’, ‘y’, ‘z’ columns.

  • timestamp (Timestamp, optional) – Get roots at given date (and time). Int must be unix timestamp. String must be ISO 8601 - e.g. ‘2021-11-15’. “mat” will use the timestamp of the most recent materialization.

  • coordinates ("nm" | "voxel") – Units in which your coordinates are in.

  • progress (bool) – If True, show progress bar.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

List of root IDs in the same order as locs.

Return type:

numpy.array

Examples

>>> from crantpy.utils.cave.segmentation import locs_to_segments
>>> locs = [[133131, 55615, 3289], [132802, 55661, 3289]]
>>> locs_to_segments(locs, dataset='latest')
array([720575940631693610, 720575940631693610])
crantpy.utils.locs_to_supervoxels(locs, mip=0, coordinates='nm', progress=True, *, dataset=None)[source]#

Retrieve supervoxel IDs at given location(s).

Parameters:
  • locs (array-like | pandas.DataFrame) – Array of x/y/z coordinates. If DataFrame must contain ‘x’, ‘y’, ‘z’ columns.

  • mip (int) – Scale to query. Lower mip = more precise but slower; higher mip = faster but less precise. The default is 0 which is the highest resolution.

  • coordinates ("nm" | "voxel") – Units in which your coordinates are in. “nm” for nanometers, “voxel” for voxel coordinates.

  • progress (bool) – If True, show progress bar.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

List of supervoxel IDs in the same order as locs. Invalid locations will be returned with ID 0.

Return type:

numpy.array

Examples

>>> from crantpy.utils.cave.segmentation import locs_to_supervoxels
>>> locs = [[133131, 55615, 3289], [132802, 55661, 3289]]
>>> locs_to_supervoxels(locs, dataset='latest')
array([79801454835332154, 79731086091150780], dtype=uint64)
crantpy.utils.make_iterable(x, force_type=None)[source]#

Convert input to an numpy array.

Parameters:
  • x (Any) – The input to convert.

  • force_type (Optional[type]) – If specified, the input will be cast to this type.

Returns:

The converted numpy array.

Return type:

np.ndarray

crantpy.utils.match_dtype(value, dtype)[source]#

Match the dtype of a value to a given dtype.

Parameters:
  • value (Any) – The value to convert.

  • dtype (str or type) – The target dtype to convert to.

Returns:

The converted value.

Return type:

Any

Raises:

ValueError – If the dtype is not supported.

crantpy.utils.neuron_to_segments(x, short=False, coordinates='nm', *, dataset=None)[source]#

Get root IDs overlapping with a given neuron.

Parameters:
  • x (Neuron/List) – Neurons for which to return root IDs. Neurons must be in the correct coordinate space for the dataset.

  • short (bool) – If True will only return the top hit for each neuron (including a confidence score).

  • coordinates ("voxel" | "nm") – Units the neuron(s) are in.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

  • overlap_matrix (pandas.DataFrame) – DataFrame of root IDs (rows) and neuron IDs (columns) with overlap in nodes as values.

  • summary (pandas.DataFrame) – If short=True: DataFrame of top hits only.

Examples

>>> from crantpy.utils.cave.segmentation import neuron_to_segments
>>> import navis
>>> # Assuming you have a neuron in the correct space
>>> neuron = navis.TreeNeuron(...)
>>> summary = neuron_to_segments(neuron, short=True)
crantpy.utils.neurons_to_url(neurons, include_skeleton=True, downsample=None, **kwargs)[source]#

Create neuroglancer URLs for a list of neurons.

Parameters:
  • neurons (NeuronList) – List of neurons to create URLs for. Must have root_id attribute.

  • include_skeleton (bool, default True) – Whether to include the skeleton in the URL.

  • downsample (int, optional) – Factor by which to downsample skeletons before adding to scene.

  • **kwargs – Additional arguments passed to encode_url().

Returns:

DataFrame with columns: id, name, url

Return type:

DataFrame

Examples

>>> neurons = crt.viz.get_skeletons([720575940621039145, 720575940621039146])
>>> urls = neurons_to_url(neurons)
>>> print(urls[['id', 'url']])
crantpy.utils.parse_neuroncriteria(allow_empty=False)[source]#

Parse all NeuronCriteria arguments into an array of root IDs.

This decorator automatically converts any NeuronCriteria objects in function arguments to arrays of root IDs. It uses type checking by class name to avoid circular imports.

Parameters:

allow_empty (bool, default False) – Whether to allow the NeuronCriteria to not match any neurons.

Returns:

Decorator function that processes NeuronCriteria arguments.

Return type:

Callable

Examples

>>> @parse_neuroncriteria()
>>> def process_neurons(neurons):
>>>     # neurons will be an array of root IDs
>>>     return neurons
>>>
>>> # Can be called with a NeuronCriteria object
>>> result = process_neurons(NeuronCriteria(cell_class='example'))
crantpy.utils.parse_root_ids(neurons)[source]#

Parse various neuron input types to a list of root ID strings. :param neurons: The neuron(s) to parse. Can be a single root ID (int or str),

a list of root IDs, or a NeuronCriteria object.

Returns:

A list of root ID strings.

Return type:

List[str]

Parameters:

neurons (Union[int, str, List[Union[int, str]], NeuronCriteria])

crantpy.utils.parse_timestamp(x)[source]#

Parse a timestamp string to Unix timestamp.

Parameters:

x (Timestamp) – The timestamp string to parse. Int must be unix timestamp. String must be ISO 8601 - e.g. ‘2021-11-15’. datetime, np.datetime64, pd.Timestamp are also accepted.

Returns:

The Unix timestamp.

Return type:

str

crantpy.utils.plot_em_image(x, y, z, size=1000)[source]#

Fetch and return an EM image slice from the precomputed CloudVolume. Currently only supports slices through the Z axis (i.e. XY plane).

Parameters:
  • x (int) – The x coordinate of the center of the image slice.

  • y (int) – The y coordinate of the center of the image slice.

  • z (int) – The z coordinate of the image slice.

  • size (int, optional) – The size of the image slice (default is 1000).

Returns:

The EM image slice as a numpy array.

Return type:

np.ndarray

crantpy.utils.retry(func, retries=5, cooldown=2)[source]#

Retry function on HTTPError.

This also suppresses UserWarnings (commonly raised by l2 cache requests)

Parameters:
  • cooldown (int | float) – Cooldown period in seconds between attempts.

  • retries (int) – Number of retries before we give up. Every subsequent retry will delay by an additional retry.

crantpy.utils.retry_func(retries=5, cooldown=2)[source]#

Retry decorator for functions on HTTPError. This also suppresses UserWarnings (commonly raised by l2 cache requests) :param cooldown: Cooldown period in seconds between attempts. :type cooldown: int | float :param retries: Number of retries before we give up. Every subsequent retry

will delay by an additional retry.

crantpy.utils.roots_to_supervoxels(neurons, clear_cache=False, progress=True, *, dataset=None)[source]#

Get supervoxels making up given neurons.

Parameters:
  • neurons (Neurons = str | int | np.int64 | navis.BaseNeuron | Iterables of previous types | navis.NeuronList | NeuronCriteria)

  • clear_cache (bool) – If True, bypasses the cache and fetches a new volume.

  • progress (bool) – If True, show progress bar.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

A dictionary mapping neuron IDs to lists of supervoxel IDs.

Return type:

dict

Examples

>>> from crantpy.utils.cave.segmentation import roots_to_supervoxels
>>> roots_to_supervoxels([123456, 789012], dataset='latest')
{123456: [1, 2, 3], 789012: [4, 5, 6]}
crantpy.utils.scene_to_url(scene, base_neuroglancer=False, shorten=False, open=False, to_clipboard=False)[source]#

Convert neuroglancer scene dictionary to URL.

Parameters:
  • scene (dict) – Neuroglancer scene dictionary.

  • base_neuroglancer (bool, default False) – Whether to use base neuroglancer instead of CAVE Spelunker.

  • shorten (bool, default False) – Whether to create a shortened URL (requires state server).

  • open (bool, default False) – If True, opens URL in web browser.

  • to_clipboard (bool, default False) – If True, copies URL to clipboard.

Returns:

Neuroglancer URL.

Return type:

str

crantpy.utils.set_cave_token(token)[source]#

Sets the CAVE token for the CAVE client.

Parameters:

token (str) – The CAVE token to set.

Return type:

None

crantpy.utils.set_default_dataset(dataset)[source]#
Parameters:

dataset (str)

crantpy.utils.set_logging_level(level)[source]#

Sets the logging level for the logger.

Parameters:

level (str) – The logging level to set. Options are ‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’.

Return type:

None

crantpy.utils.snap_to_id(locs, id, snap_zero=False, search_radius=160, coordinates='nm', verbose=True, *, dataset=None)[source]#

Snap locations to the correct segmentation ID.

This function is useful for correcting imprecise coordinate annotations (e.g., from manual annotation, image registration, or synapse detection) to ensure they map to the expected neuron/segment.

How it works:
  1. Check segmentation ID at each location

  2. For locations with wrong ID: search within radius for correct ID

  3. Snap to closest voxel with correct ID

IMPORTANT - CloudVolume Coverage: This function requires CloudVolume segmentation data at the target locations. Locations outside CloudVolume’s spatial coverage (~360 µm cube) cannot be snapped and will be returned as [0, 0, 0].

Parameters:
  • locs ((N, 3) array) – Array of x/y/z coordinates to snap.

  • id (int) – Expected/target segmentation ID at each location. Typically a root ID of the neuron of interest.

  • snap_zero (bool) – If False (default), we will not snap locations that map to segment ID 0 (i.e., no segmentation / background). Set to True to attempt snapping even for background locations.

  • search_radius (int) – Radius [nm] around a location to search for a voxel with the correct ID. Larger radius = more likely to find match but slower. Default 160 nm is usually sufficient for small annotation errors. Increase to 500-1000 nm for larger errors.

  • coordinates ("voxel" | "nm") – Coordinate system of locs. Default “nm” (nanometers).

  • verbose (bool) – If True, will print summary of snapping results and any errors encountered.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

Snapped x/y/z locations guaranteed to map to the correct ID (or [0, 0, 0] for locations that couldn’t be snapped).

Return type:

(N, 3) array

Raises:

ValueError – If search region exceeds CloudVolume coverage for any location.

Examples

>>> from crantpy.utils.cave.segmentation import snap_to_id
>>> import numpy as np
>>>
>>> # Example: Fix slightly misaligned synapse annotations
>>> synapse_locs = np.array([
...     [100050, 50025, 3005],  # Slightly off target
...     [100150, 50125, 3015],
... ])
>>> target_neuron_id = 720575940621039145
>>>
>>> # Snap to nearest voxel on target neuron
>>> corrected_locs = snap_to_id(
...     synapse_locs,
...     id=target_neuron_id,
...     search_radius=200,  # Search within 200nm
...     verbose=True
... )
>>> # Output: 2 of 2 locations needed to be snapped.
>>> #         Of these 0 locations could not be snapped...
>>> # Example: Quality control for traced neuron nodes
>>> import navis
>>> neuron = navis.TreeNeuron(...)  # Your neuron reconstruction
>>> expected_root_id = 720575940621039145
>>>
>>> # Snap all nodes to ensure they're on the correct segment
>>> corrected_nodes = snap_to_id(
...     neuron.nodes[['x', 'y', 'z']].values,
...     id=expected_root_id,
...     search_radius=500,
...     coordinates="nm"
... )
>>>
>>> # Update neuron with corrected coordinates
>>> neuron.nodes[['x', 'y', 'z']] = corrected_nodes
>>> # Example: Handle locations in background (ID 0)
>>> locs_with_background = np.array([
...     [100000, 50000, 3000],  # On neuron
...     [999999, 999999, 9999],  # In background (ID 0)
... ])
>>>
>>> # By default, won't try to snap background locations
>>> snapped = snap_to_id(locs_with_background, id=target_neuron_id)
>>> # Background location will remain unchanged
>>>
>>> # Force snapping even for background (use with caution!)
>>> snapped = snap_to_id(
...     locs_with_background,
...     id=target_neuron_id,
...     snap_zero=True,  # Try to snap background too
...     search_radius=1000  # Larger search needed
... )

Notes

When to use this function: - Synapse annotation QC: Ensure synapses are on correct pre/postsynaptic neurons - Image registration errors: Fix coordinate misalignment after registration - Manual annotation cleanup: Correct imprecise manual annotations - Traced neuron validation: Ensure skeleton nodes are on correct segment

Performance considerations: - Each location requiring snapping fetches a small segmentation cutout - Larger search_radius = slower (more data to fetch and search) - Locations already on correct ID are very fast (no cutout needed) - For many locations, consider parallelizing or batching

Common issues: - “No voxels found in search region”: The target ID doesn’t exist

within search_radius. Try increasing search_radius or verify the expected ID is correct.

  • “Bounds exceed CloudVolume coverage”: Location is outside the ~360 µm region covered by CloudVolume. These locations cannot be snapped.

  • Many failures: Check if your locations and target ID are in the same coordinate space and if the neuron actually exists at those locations.

See also

locs_to_segments

Check which segment IDs are at given locations

get_segmentation_cutout

Get segmentation in a region

crantpy.utils.supervoxels_to_roots(ids, timestamp='mat', clear_cache=False, batch_size=10000, stop_layer=8, retry=True, progress=True, *, dataset=None)[source]#

Get root(s) for given supervoxel(s).

Parameters:
  • ids (IDs = str | int | np.int64 | Iterables of previous types) – Supervoxel ID(s) to find the root(s) for. Also works for e.g. L2 IDs.

  • timestamp (Timestamp = str | int | np.int64 | datetime | np.datetime64 | pd.Timestamp or str starting with "mat") – Get roots at given date (and time). Int must be unix timestamp. String must be ISO 8601 - e.g. ‘2021-11-15’. “mat” will use the timestamp of the most recent materialization. You can also use e.g. “mat_<version>” to get the root ID at a specific materialization.

  • clear_cache (bool) – If True, bypasses the cache and fetches a new volume.

  • batch_size (int) – Max number of supervoxel IDs per query. Reduce batch size if you experience time outs.

  • stop_layer (int) – Set e.g. to 2 to get L2 IDs instead of root IDs.

  • retry (bool) – Whether to retry if a batched query fails.

  • progress (bool) – If True, show progress bar.

  • dataset (str) – The dataset to use. If not provided, uses the default dataset.

Returns:

roots – Roots corresponding to supervoxels in x.

Return type:

numpy array

Examples

>>> from crantpy.utils.cave.segmentation import supervoxels_to_roots
>>> supervoxels_to_roots([123456, 789012], dataset='latest')
[1, 2]
crantpy.utils.update_ids(x, supervoxels=None, timestamp=None, stop_layer=2, progress=True, dataset=None, use_annotations=True, clear_cache=False)[source]#

Update root IDs to their latest versions.

This function prioritizes using supervoxel IDs from annotations when available, falling back to chunkedgraph methods only when necessary.

Parameters:
  • x (Neurons or pd.DataFrame) – Root IDs to update. If DataFrame, must contain ‘root_id’ column and optionally ‘supervoxel_id’ column.

  • supervoxels (IDs, optional) – Supervoxel IDs corresponding to the root IDs. If provided, these will be used instead of looking up annotations.

  • timestamp (Timestamp, optional) – Target timestamp. Can be “mat” for latest materialization.

  • stop_layer (int, default 2) – Stop layer for chunkedgraph operations when supervoxels unavailable.

  • progress (bool, default True) – Whether to show progress bar.

  • dataset (str, optional) – Dataset to use.

  • use_annotations (bool, default True) – Whether to look up supervoxels from annotations when not provided.

  • clear_cache (bool, default False) – Whether to clear annotation cache.

Returns:

DataFrame with columns: old_id, new_id, confidence, changed

Return type:

pd.DataFrame

Examples

>>> from crantpy.utils.cave.segmentation import update_ids
>>> update_ids([123456789, 987654321])
   old_id      new_id  confidence  changed
0  123456789  123456789     1.0     False
1  987654321  999999999     0.85    True
>>> # With supervoxels
>>> update_ids([123456789], supervoxels=[111222333])
   old_id      new_id  confidence  changed
0  123456789  123456789     1.0     False
crantpy.utils.validate_cave_client(client, *args, **kwargs)[source]#

Validate if a cached CAVE client is still valid.