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:
|
Generate URL to a location. |
|
Retrieves location for a set of nodes or connectors. |