pymaid.replace_skeleton(x, skeleton_id=None, force_mapping=False, cold_run=False, remote_instance=None)[source]

Replace skeleton in CatmaidInstance.

This will override existing skeleton data and tries to map back tags and connectors. Requires user to have import and API token write access privileges!

Connectors are re-connected by: For each connector,

  1. Get node this connector is connected to in current skeleton.

  2. Get distance to the nodes up- and downstream of it as proxy for sampling resolution.

  3. Find the closest node in new skeleton.

  4. Connect automatically if closest node within sampling resolution. Else flag and return connector as “requires manual review”.

Node tags are mapped back by: For each tagged node:

  1. Get distance to the nodes up- and downstream of it as proxy for sampling resolution.

  2. Find the closest node in new skeleton.

  3. Map tag automatically if closest node is within the sampling resolution. Else flag and return connector as “requires manual review”.

Note that this does not respect types of nodes. E.g. an “ends” tag could end up on a non-leaf node.

Any connectors/tags that have not been automatically fixed will be returned as DataFrame for manual review. See examples.


Use this with EXTREME caution as this is irreversible!

  • x (CatmaidNeuron) – Neuron to update.

  • skeleton_id (int, optional) – ID of skeleton to update. If not provided will use .skeleton_id property of input neuron.

  • force_mapping (bool, optional) – If True, will always re-connect connectors and map tags onto the closest node in new skeleton regardless of distance.

  • cold_run (bool, optional) – If True, will only calculate and return table of nodes to fix without actually uploading anything.

  • remote_instance (CatmaidInstance, optional) – If not passed directly, will try using global.


DataFrame listing connectors and node tags that were either fixed automatically or need manual review.

auto_fix type connector_id old_node_id …

0 False ‘connector’ 123456 11111 1 True ‘tag’ None 22222

sugg_node_id relation tags x y z

0 33333 0 None … 1 44444 None [‘ends’] …

In this example node 11111 in the old skeleton was connected presynaptically (relation=0) to a connector. The closest node in the new skeleton is 33333 but it’s too far away to be automatically reconnected.

Node 22222 had an ends tag in the old skeleton and the closest node in the new skeleton is 44444. Because this node was close enough, it was automatically fixed.

x/y/z coordinates always refer to the position of the old node!

Return type



Pull a neuron from CATMAID, smooth it and upload it again:

>>> n = pymaid.get_neuron(16)
>>> n_smoothed = pymaid.smooth_neuron(n, inplace=False)
>>> to_fix = pymaid.replace_skeleton(n_smoothed)
Updating skeleton 16
# of nodes: 12853 -> 12853 (+0)
Cable length:       2904.2 -> 3027.3 (+123.1)
1983 of 2116 connectors will be automatically re-connected
654 of 654 tagged nodes will be automatically mapped back
Remaining connectors/tagged nodes will be returned as DataFramefor manual review
Proceed? [Y/N] Y
>>> # There are 133 items (connectors and tags) to check manually:
>>> to_fix[~to_fix.auto_fix].shape[0]
>>> to_fix[~to_fix.auto_fix].head()
    connector_id  old_node_id  relation  sugg_node_id tags       type       x       y       z
20        304403       125722       NaN        125717  NaN  connector  452034  139101  204160
47        553830       123430       NaN          2698  NaN  connector  437855  165228  216280
77        653778       123637       NaN        123636  NaN  connector  450508  134607  188720
86        666783       127623       NaN        127620  NaN  connector  438700  147328  219840

To facilitate fixing , we can add urls to the positions and then copy the DataFrame to e.g. a spreadsheet:

>>> fix_manual = to_fix[~to_fix.auto_fix]
>>> fix_manual['url'] = pymaid.url_to_coordinates(coords=fix_manual,
...                                               stack_id=5,  # change this according to your projects
...                                               active_skeleton_id=n.skeleton_id,
...                                               active_node_id=fix_manual.sugg_node_id.values)
>>> # Copy to clipboard
>>> fix_manual.to_clipboard()