Generating CATMAID URLs

This example will demonstrate how to use pymaid to generate URLs to a set of connectors. You can use this, for example, to perform random sampling of up- or downstream partners.

[1]:
import pandas as pd
import pymaid

rm = pymaid.connect_catmaid()

First get your neuron of interest:

[2]:
n = pymaid.get_neuron(16)

A simple example: Downstream sampling by connectors

[3]:
# Get all connectors
cn = n.connectors

# Add a column with the URL to coordinates
cn['URL'] = pymaid.url_to_coordinates(cn,
                                      stack_id=5,
                                      active_node_id=cn.connector_id.values)
cn.head()
[3]:
treenode_id connector_id relation x y z URL
0 127234 999188 0 438817 164242 217440 https://neuropil.janelia.org/tracing/fafb/v14/...
1 2591 97954 0 437120 160998 211920 https://neuropil.janelia.org/tracing/fafb/v14/...
2 2665 98300 0 437184 162324 214880 https://neuropil.janelia.org/tracing/fafb/v14/...
3 2646 98373 0 437042 162452 214120 https://neuropil.janelia.org/tracing/fafb/v14/...
4 2654 98415 0 436761 163690 214440 https://neuropil.janelia.org/tracing/fafb/v14/...

In above example we are using stack_id=5. This is the ID of the image stack for this project and is encoded in the URL as sid0=5.

Now you can export this DataFrame. Two quick examples.

To CSV:

[4]:
cn.to_csv('filename.csv')

To clipboard:

[5]:
cn.to_clipboard()

Randomizing

Randomizing the order e.g. for random sampling of downstream partners is straight forward:

Subset to presynapses:

[6]:
pre = cn[cn.relation == 0]

Randomize order:

[7]:
ran = pre.sample(frac=1)
ran.head()
[7]:
treenode_id connector_id relation x y z URL
868 10350265 10350269 0 358255 151135 167240 https://neuropil.janelia.org/tracing/fafb/v14/...
1423 10366582 10366581 0 336551 159297 177360 https://neuropil.janelia.org/tracing/fafb/v14/...
785 10345534 10345533 0 375162 146617 170760 https://neuropil.janelia.org/tracing/fafb/v14/...
597 10337834 10337835 0 385421 134986 173200 https://neuropil.janelia.org/tracing/fafb/v14/...
1591 10370697 10370695 0 341188 153709 169440 https://neuropil.janelia.org/tracing/fafb/v14/...

A more complex example: sampling inputs by treenode

First we have to get the presynaptic treenode IDs:

[8]:
post_details = pymaid.get_connector_details(n.postsynapses)
post_details.head()
INFO  : Data for 412 of 412 unique connector IDs retrieved (pymaid)
[8]:
connector_id presynaptic_to postsynaptic_to presynaptic_to_node postsynaptic_to_node
0 474311 203840 [7911576, 8638, 16, 6483677] 474312 [2736161, 474295, 124991, 21109788]
1 573905 54753 [7634, 279469, 30358, 17238, 16, 597080, 39182... 573904 [573902, 1482460, 1670909, 2875768, 127266, 28...
2 1335332 55153 [8408275, 16] 1326548 [27245140, 125650]
3 1482374 203840 [10379190, 9052688, 279469, 597085, 597100, 59... 1277055 [2875773, 30223253, 1482362, 2875771, 2875774,...
4 1510194 288558 [16, 203840] 1510193 [124597, 1510195]

If you have connectors without a presynaptic treenode, you will have to fix that and rerun above code before moving on!

[9]:
post_details[post_details.presynaptic_to_node.isnull()]
[9]:
connector_id presynaptic_to postsynaptic_to presynaptic_to_node postsynaptic_to_node
401 20041670 None [4954519, 16] None [20041667, 18719343]

Next we need to get the coordinates for those treenodes.

[10]:
# Now get the locations
locs = pymaid.get_node_location(post_details.presynaptic_to_node.values)
locs.head()
[10]:
node_id x y z
0 10362880 367320.0 152292.0 177760.0
1 18804742 466093.0 234873.0 38560.0
2 18802702 466727.0 233599.0 33640.0
3 10342419 381419.0 140309.0 180280.0
4 10315798 345150.0 159327.0 186640.0

Now we have to merge the locations into the connector Dataframe

[11]:
cn_merged = pd.merge(post_details.set_index('presynaptic_to_node'),
                     locs.set_index('node_id'),
                     left_index=True, right_index=True)
cn_merged.head()
[11]:
connector_id presynaptic_to postsynaptic_to postsynaptic_to_node x y z
437124 7265239 202541 [8680461, 16, 13782] [28458449, 1786, 22231380] 438062.0 140370.0 203160.0
437172 7265176 202541 [30571, 40637, 16, 4205169] [6428950, 447292, 1819, 7265200] 437010.0 141171.0 204400.0
474312 474311 203840 [7911576, 8638, 16, 6483677] [2736161, 474295, 124991, 21109788] 421574.0 127771.0 194720.0
573904 573905 54753 [7634, 279469, 30358, 17238, 16, 597080, 39182... [573902, 1482460, 1670909, 2875768, 127266, 28... 434460.0 165646.0 216160.0
1275576 2873212 203840 [595239, 16] [2873213, 127687] 436480.0 147325.0 221360.0

Let’s add the url to the presynaptic node and some additional info: the name of the presynaptic neuron and whether it already has a soma

[12]:
cn_merged['url'] = pymaid.url_to_coordinates(cn_merged, stack_id=5)
cn_merged['neuron_name'] = cn_merged.presynaptic_to.astype(str).map(pymaid.get_names(cn_merged.presynaptic_to.values))
cn_merged['has_soma'] = cn_merged.presynaptic_to.map(pymaid.has_soma(cn_merged.presynaptic_to.values))

cn_merged.head()
[12]:
connector_id presynaptic_to postsynaptic_to postsynaptic_to_node x y z url neuron_name has_soma
437124 7265239 202541 [8680461, 16, 13782] [28458449, 1786, 22231380] 438062.0 140370.0 203160.0 https://neuropil.janelia.org/tracing/fafb/v14/... putative Gad1-F-600202 40613 AJ True
437172 7265176 202541 [30571, 40637, 16, 4205169] [6428950, 447292, 1819, 7265200] 437010.0 141171.0 204400.0 https://neuropil.janelia.org/tracing/fafb/v14/... putative Gad1-F-600202 40613 AJ True
474312 474311 203840 [7911576, 8638, 16, 6483677] [2736161, 474295, 124991, 21109788] 421574.0 127771.0 194720.0 https://neuropil.janelia.org/tracing/fafb/v14/... APL 203841 MR JSL True
573904 573905 54753 [7634, 279469, 30358, 17238, 16, 597080, 39182... [573902, 1482460, 1670909, 2875768, 127266, 28... 434460.0 165646.0 216160.0 https://neuropil.janelia.org/tracing/fafb/v14/... neuron 54754 False
1275576 2873212 203840 [595239, 16] [2873213, 127687] 436480.0 147325.0 221360.0 https://neuropil.janelia.org/tracing/fafb/v14/... APL 203841 MR JSL True

OK, nice. Let’s rearrange and get rid of superfluous columns:

[13]:
cn_merged = cn_merged[['presynaptic_to', 'neuron_name', 'has_soma', 'connector_id', 'x', 'y', 'z', 'url']]
cn_merged.head()
[13]:
presynaptic_to neuron_name has_soma connector_id x y z url
437124 202541 putative Gad1-F-600202 40613 AJ True 7265239 438062.0 140370.0 203160.0 https://neuropil.janelia.org/tracing/fafb/v14/...
437172 202541 putative Gad1-F-600202 40613 AJ True 7265176 437010.0 141171.0 204400.0 https://neuropil.janelia.org/tracing/fafb/v14/...
474312 203840 APL 203841 MR JSL True 474311 421574.0 127771.0 194720.0 https://neuropil.janelia.org/tracing/fafb/v14/...
573904 54753 neuron 54754 False 573905 434460.0 165646.0 216160.0 https://neuropil.janelia.org/tracing/fafb/v14/...
1275576 203840 APL 203841 MR JSL True 2873212 436480.0 147325.0 221360.0 https://neuropil.janelia.org/tracing/fafb/v14/...

Now you can randomize this table and start sampling:

[14]:
cn_merged.sample(frac=1).to_clipboard()

These are the relevant functions:

pymaid.url_to_coordinates(coords, stack_id)

Generate URL to a location.

pymaid.get_node_location(x[, sort, …])

Retrieves location for a set of nodes or connectors.