Skip to content

Instantly share code, notes, and snippets.

@j6k4m8
Last active April 6, 2022 22:00
Show Gist options
  • Save j6k4m8/7da63dc9c049c4263fc2749d4ce880cd to your computer and use it in GitHub Desktop.
Save j6k4m8/7da63dc9c049c4263fc2749d4ce880cd to your computer and use it in GitHub Desktop.
Searching for Motifs in MICrONS Data
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/j6k4m8/7da63dc9c049c4263fc2749d4ce880cd/notebook.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "H0t3b1335AoU"
},
"outputs": [],
"source": [
"!pip3 install dotmotif"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Q18VdUKD5AoY"
},
"source": [
"# Searching for Motifs in the Pinky100 MICrONS Connectome\n",
"\n",
"This notebook illustrates how to search for motifs in the MICrONS Pinky100 connectome edgelist.\n",
"\n",
"Before you start, you will need to install DotMotif:\n",
"\n",
"```shell\n",
"pip3 install dotmotif\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "yfu3Gknq5Aob"
},
"outputs": [],
"source": [
"from dotmotif import Motif, GrandIsoExecutor\n",
"from dotmotif.ingest import EdgelistConverter"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NiRTsDGV5Aoc"
},
"source": [
"Now we can download the edgelist.\n",
"\n",
"This edgelist includes many columns, but the two that we care about in particular are called `pre_root_id` and `post_root_id`. These serve as the edge endpoints for our directed graph.\n",
"\n",
"We can use the `EdgelistConverter` to read in a CSV file. Note that in older versions of DotMotif, this was called `CSVEdgelistConverter` (but in new versions you can read many more table formats, including a Dask/Pandas DataFrame directly)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "J8ROaN-j5Aod"
},
"outputs": [],
"source": [
"graph = EdgelistConverter(\n",
" \"https://zenodo.org/record/3710459/files/soma_subgraph_synapses_spines_v185.csv?download=1\",\n",
" \"pre_root_id\",\n",
" \"post_root_id\",\n",
").to_graph()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qGLgH8qG5Aod"
},
"source": [
"DotMotif stores the graph in an \"executor,\" which handles the logic for motif search. There are many different executors available for searching in a variety of different graph datastores, such as Neo4j, neuPrint, or Python data structures. Here, we'll use the `GrandIsoExecutor`, which is a pure-Python executor (and therefore doesn't require any additional package installations)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "zoHxtH605Aod"
},
"outputs": [],
"source": [
"E = GrandIsoExecutor(graph=graph)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RTT3PGBt5Aoe"
},
"source": [
"Now the fun part: constructing our motif!\n",
"\n",
"A DotMotif motif can be [as simple or as complicated as you like](https://github.com/aplbrain/dotmotif/wiki/Getting-Started). Let's start with a super simple query: looking for directed triangles."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "-RpXqKvx5Aof"
},
"outputs": [],
"source": [
"motif = Motif(\"\"\"\n",
"A -> B\n",
"B -> C\n",
"C -> A\n",
"\"\"\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Bw9IKg035Aog",
"outputId": "21d5844e-77ff-4fe9-9730-b0ab0f123e3d"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"312\n"
]
}
],
"source": [
"results = E.find(motif)\n",
"\n",
"print(len(results))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "V1NiRKwT5Aoj"
},
"source": [
"If all went well, you should see the number `312` appear above. In other words, there are 312 unique triangles in the graph!\n",
"\n",
"Let's look at some of them:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "8_IH3jlV5Aok",
"outputId": "43c61d43-365b-45fc-fe63-d2b280f75cea"
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>A</th>\n",
" <th>C</th>\n",
" <th>B</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>648518346349539437</td>\n",
" <td>648518346349538235</td>\n",
" <td>648518346349537514</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>648518346349531254</td>\n",
" <td>648518346349538410</td>\n",
" <td>648518346349539517</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>648518346349531254</td>\n",
" <td>648518346349536679</td>\n",
" <td>648518346349538462</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>648518346349537978</td>\n",
" <td>648518346349536679</td>\n",
" <td>648518346349538462</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>648518346349537978</td>\n",
" <td>648518346349537160</td>\n",
" <td>648518346349539803</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" A C B\n",
"0 648518346349539437 648518346349538235 648518346349537514\n",
"1 648518346349531254 648518346349538410 648518346349539517\n",
"2 648518346349531254 648518346349536679 648518346349538462\n",
"3 648518346349537978 648518346349536679 648518346349538462\n",
"4 648518346349537978 648518346349537160 648518346349539803"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"\n",
"pd.DataFrame(results).head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "934TOXHS5Aol"
},
"source": [
"Here are three valid mappings of the triangle motif into the connectome graph. The way to read this is that each column (\"A\", \"B\", and \"C\") corresponds to a node in the motif of the same name; each row corresponds to an embedding of that motif in the host connectome. For example, the row \n",
"\n",
"\n",
"| A | C | B |\n",
"|-|-|-|\n",
"| 437 | 235 | 514 |\n",
"...\n",
"\n",
"...means that the connectome node with ID 437 can be assigned to the \"A\" node in the motif, the node 235 can be assigned to the \"C\" node, and 514 can be assigned to \"B.\"\n",
"\n",
"---\n",
"\n",
"Let's try a more complicated motif: \n",
"\n",
"Now, we want to search for all cases where a neuron synapsed onto another neuron with a spine head volume of greater than 0.5μm³, and that second neurong does NOT synapse back on the first neuron:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cHGBIRUY5Aom"
},
"outputs": [],
"source": [
"ffwd_motif = Motif(\"\"\"\n",
"\n",
"# First neuron synapses on the second \n",
"# with a spine head volume of greater \n",
"# than half a cubic micron:\n",
"First -> Second [spine_vol_um3 > 0.5]\n",
"\n",
"# The second neuron does NOT have any\n",
"# synapses back onto the first neuron\n",
"# (note the `!>` edge notation):\n",
"Second !> First\n",
"\"\"\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "GE6-VxpN5Aon",
"outputId": "f1274ab0-9b48-4908-a50a-6eb3f9f6d2fa"
},
"outputs": [
{
"data": {
"text/plain": [
"[{'First': '648518346349537514', 'Second': '648518346349540053'},\n",
" {'First': '648518346349539653', 'Second': '648518346349537716'},\n",
" {'First': '648518346349538787', 'Second': '648518346349539067'}]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"E.find(ffwd_motif)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "57YYMcU85Aoo"
},
"source": [
"Hey! That's interesting; this phenomenon only occurs three times in the whole graph!\n",
"\n",
"---\n",
"\n",
"Finally, let's explore what would have happened had we made a mistake while writing that motif.\n",
"\n",
"Let's imagine that we were distracted by a particularly delicious carrot, and wrote the \"negative\" edge backwards:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "YhxY-hbr5Aop",
"outputId": "4cebadcb-b4cf-4e41-d9df-2554f34069bc"
},
"outputs": [
{
"ename": "VisitError",
"evalue": "Error trying to process rule \"edge\":\n\nTrying to add <First-Second exists=False> but <First-Second exists=True> already in motif.",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mDisagreeingEdgesValidatorError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_call_userfunc\u001b[0;34m(self, tree, new_children)\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 68\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 69\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mGrammarError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mDiscard\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Documents/projects/dotmotif/dotmotif/parsers/v2/__init__.py\u001b[0m in \u001b[0;36medge\u001b[0;34m(self, tup)\u001b[0m\n\u001b[1;32m 145\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mval\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalidators\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 146\u001b[0;31m \u001b[0mval\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalidate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrel\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"type\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrel\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"exists\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 147\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhas_edge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Documents/projects/dotmotif/dotmotif/validators/__init__.py\u001b[0m in \u001b[0;36mvalidate\u001b[0;34m(self, g, u, v, type, exists)\u001b[0m\n\u001b[1;32m 46\u001b[0m raise DisagreeingEdgesValidatorError(\n\u001b[0;32m---> 47\u001b[0;31m \u001b[0;34mf\"Trying to add <{u}-{v} exists={exists}> but \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 48\u001b[0m \u001b[0;34mf\"<{u_}-{v_} exists={attrs['exists']}> already in motif.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDisagreeingEdgesValidatorError\u001b[0m: Trying to add <First-Second exists=False> but <First-Second exists=True> already in motif.",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001b[0;31mVisitError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-9-ce9e6f4ac289>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mFirst\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m!\u001b[0m\u001b[0;34m>\u001b[0m \u001b[0mSecond\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \"\"\")\n\u001b[0m",
"\u001b[0;32m~/Documents/projects/dotmotif/dotmotif/__init__.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, input_motif, **kwargs)\u001b[0m\n\u001b[1;32m 85\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 86\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0minput_motif\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 87\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_motif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput_motif\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 88\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 89\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mfrom_motif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcmd\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Documents/projects/dotmotif/dotmotif/__init__.py\u001b[0m in \u001b[0;36mfrom_motif\u001b[0;34m(self, cmd)\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 105\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 106\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparser\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalidators\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalidators\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 107\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 108\u001b[0m (\n",
"\u001b[0;32m~/Documents/projects/dotmotif/dotmotif/parsers/v2/__init__.py\u001b[0m in \u001b[0;36mparse\u001b[0;34m(self, dm)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0mdynamic_node_constraints\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0mautomorphisms\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m ) = DotMotifTransformer(validators=self.validators).transform(tree)\n\u001b[0m\u001b[1;32m 346\u001b[0m return (\n\u001b[1;32m 347\u001b[0m \u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Documents/projects/dotmotif/dotmotif/parsers/v2/__init__.py\u001b[0m in \u001b[0;36mtransform\u001b[0;34m(self, tree)\u001b[0m\n\u001b[1;32m 31\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 32\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 33\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 34\u001b[0m return (\n\u001b[1;32m 35\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_transform_tree\u001b[0;34m(self, tree)\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 101\u001b[0;31m \u001b[0mchildren\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_children\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 102\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_userfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_transform_children\u001b[0;34m(self, children)\u001b[0m\n\u001b[1;32m 90\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 91\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mTree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 92\u001b[0;31m \u001b[0;32myield\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 93\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__visit_tokens__\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mToken\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 94\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_userfunc_token\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_transform_tree\u001b[0;34m(self, tree)\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 101\u001b[0;31m \u001b[0mchildren\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_children\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 102\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_userfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_transform_children\u001b[0;34m(self, children)\u001b[0m\n\u001b[1;32m 90\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 91\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mTree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 92\u001b[0;31m \u001b[0;32myield\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 93\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__visit_tokens__\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mToken\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 94\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_userfunc_token\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_transform_tree\u001b[0;34m(self, tree)\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 101\u001b[0;31m \u001b[0mchildren\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_children\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 102\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_userfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_transform_children\u001b[0;34m(self, children)\u001b[0m\n\u001b[1;32m 90\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 91\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mTree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 92\u001b[0;31m \u001b[0;32myield\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 93\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__visit_tokens__\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mToken\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 94\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_userfunc_token\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_transform_tree\u001b[0;34m(self, tree)\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_transform_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 101\u001b[0m \u001b[0mchildren\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_transform_children\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 102\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_userfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchildren\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 103\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.7.7/envs/scripting/lib/python3.7/site-packages/lark/visitors.py\u001b[0m in \u001b[0;36m_call_userfunc\u001b[0;34m(self, tree, new_children)\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mraise\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 72\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mVisitError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtree\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtree\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 73\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 74\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_call_userfunc_token\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtoken\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mVisitError\u001b[0m: Error trying to process rule \"edge\":\n\nTrying to add <First-Second exists=False> but <First-Second exists=True> already in motif."
]
}
],
"source": [
"ffwd_motif = Motif(\"\"\"\n",
"\n",
"First -> Second [spine_vol_um3 > 0.5]\n",
"\n",
"First !> Second\n",
"\"\"\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lWMYg-yJ5Aoq"
},
"source": [
"DotMotif won't even let us compile this motif: It's letting us know that we tried to make an invalid motif. Unlike some other query languages, DotMotif will search for mistakes like this and alert you before you spend hours running your database query. Neato :)\n",
"\n",
"---\n",
"\n",
"## Conclusion\n",
"\n",
"To learn more about DotMotif and how to get started writing queries against your own data, see [this getting-started guide](https://github.com/aplbrain/dotmotif/wiki/Getting-Started) at the [DotMotif GitHub repository page](https://github.com/aplbrain/dotmotif).\n",
"\n",
"Please reach out if you encounter any issues! We're excited to see what you find!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "G-_jYECr5Aoq"
},
"outputs": [],
"source": [
""
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.7"
},
"colab": {
"name": "Searching for Motifs in MICrONS Data",
"provenance": [],
"collapsed_sections": [],
"include_colab_link": true
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment