Pushing data to the server ************************** ``pymaid`` does not only let you fetch data *from* a CATMAID server but you can also push data back to the server. Most things you can do with your browers (like placing nodes or adding annotations), you can als do programmatically with ``pymaid``. Notably you can: - add/remove (meta-)annotations - add/remove node tags - rename/reroot/delete existing neurons - upload new skeletons - upload/delete volumes - transfer neurons between CATMAID servers Another quick primer ==================== **First and foremost: be very, very carefull when pushing data to the CATMAID server!** When using ``pymaid`` to manipulate data on the server, the same retrictions (e.g. permission to edit somebody's nodes, annotations, etc.) apply as when you are using a web browser. However, making changes programmatically has the potential to accidentally mess things up at a much larger scale: consider, for example, accidentally renaming 100 neurons instead of 1 because you used the wrong annotation. Should something like this happen and you can't fix it yourself, the last resort is to ask a server admin to revert the accidental transactions. Second: pushing data programmatically requires you to have "API write access". If you get a permission error using below functions, you need to ask an admin to give you the required permissions. Annotations =========== As with the tutorial on fetching data, we won't be able to cover all functions but rather give you a flavour of what's available. If you know what you want to do, head over to the :ref:`API reference ` and search for keywords to find the respective function - they almost always contain examples of how to use them! First, we need to set up the connection to the CATMAID server. This should already look familiar - if not check out the `quickstart tutorial ` first: .. code:: ipython3 import pymaid # We will deactivate caching so that we always have the live data rm = pymaid.connect_catmaid(caching=False) .. raw:: html .. parsed-literal:: INFO : Global CATMAID instance set. Caching is OFF. (pymaid) Let's start by adding an annotation to my favourite neuron (skeleton ID 16) using :func:`pymaid.add_annotations`: .. code:: ipython3 resp = pymaid.add_annotations(16, "favourite neuron of Philipp") ``resp`` is just the server's response which is usually just a confirmation that things have worked: .. code:: ipython3 resp .. parsed-literal:: {'message': 'success', 'annotations': [{'name': 'favourite neuron of Philipp', 'id': 16954141, 'entities': [17]}], 'new_annotations': [16954141], 'existing_annotations': []} Looks like it worked - let's check by querying by annotation using :func:`pymaid.get_skids_by_annotation` .. code:: ipython3 pymaid.get_skids_by_annotation('favourite neuron of Philipp') .. parsed-literal:: [16] It did! But now we want to get rid of it again using :func:`pymaid.remove_annotations`: .. code:: ipython3 resp = pymaid.remove_annotations(16, 'favourite neuron of Philipp') resp .. parsed-literal:: INFO : Removed "favourite neuron of Philipp" from 1 entities (0 uses left) (pymaid) .. parsed-literal:: {'deleted_annotations': {'16954141': {'targetIds': [17]}}, 'deleted_links': [16954142], 'left_uses': {'16954141': 0}} That worked too! Importing neurons ================= How about importing neurons? Nothing easier than that! First, you need to load your neuron via ``pymaid`` (e.g. from another CATMAID server) or ``navis`` (e.g. from an SWC file). Let's create a mock neuron consisting of only two nodes: .. code:: ipython3 import navis import pandas as pd # Create node table node_table = pd.DataFrame([[0, -1, 0, 0, 0, -1], [1, 0, 10, 10, 10, -1]], columns=['node_id', 'parent_id', 'x', 'y', 'z', 'radius']) # Turn node table into navis neuron n = navis.TreeNeuron(node_table) n .. raw:: html
type navis.TreeNeuron
name None
n_nodes 2
n_connectors None
n_branches 0
n_leafs None
cable_length 17.3205
soma None
units 1 dimensionless
Upload the mock neuron via :func:`pymaid.upload_neuron`: .. code:: ipython3 # Upload neuron to our CATMAID server resp = pymaid.upload_neuron(n) resp .. parsed-literal:: {'neuron_id': 16954144, 'skeleton_id': 16954143, 'node_id_map': {0: 66611224, 1: 66611225}} As you can see from the response, our mock neuron was successfully uploaded and now has the skeleton ID ``16954143``. .. code:: ipython3 pymaid.get_neuron(resp['skeleton_id']) .. raw:: html
type CatmaidNeuron
name neuron 16954144
id 16954143
n_nodes 2
n_connectors 0
n_branches 0
n_leafs None
cable_length 17.3205
soma None
units 1 nanometer
How about giving it a better name using :func:`pymaid.rename_neurons`? .. code:: ipython3 _ = pymaid.rename_neurons(resp['skeleton_id'], 'Philipps mock neuron') pymaid.get_names(resp['skeleton_id']) .. parsed-literal:: Current name New name Skeleton ID 0 neuron 16954144 Philipps mock neuron 16954143 Please confirm above renaming [Y/N] y .. parsed-literal:: INFO : All neurons successfully renamed. (pymaid) .. parsed-literal:: {'16954143': 'Philipps mock neuron'} OK that also worked! Let's put that neuron out of its misery and delete it via :func:`pymaid.delete_neuron`: .. code:: ipython3 pymaid.delete_neuron(resp['skeleton_id']) .. parsed-literal:: .. parsed-literal:: Neuron "Philipps mock neuron" (#16954143) has 2 nodes (0 reviewed) and 1 annotation(s) Please confirm deletion [Y/N] y .. parsed-literal:: {'skeleton_ids': [16954143], 'success': 'Deleted neuron #16954144 as well as its skeletons and annotations.'} Again, I cannot stress enough that you have to be careful using these functions! In particular if you have broad permissions to edit other people's tracings. If I had accidentally used the wrong skeleton ID here, I could have deleted a neuron somebody else spent days constructing.