Skip to content

Commit

Permalink
Merge pull request #60 from VirtualFlyBrain/autodoc-test
Browse files Browse the repository at this point in the history
  • Loading branch information
Robbie1977 authored May 3, 2021
2 parents 0bd0b35 + 1021ef1 commit 62641cd
Show file tree
Hide file tree
Showing 114 changed files with 89,979 additions and 154 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
vfb_connect
navis
python-catmaid
neuprint-python
flybrains
requests
psycopg2
pandas
pandasql
jupyter
nbsphinx
matplotlib
sphinx-autodoc-typehints
ipywidgets
jsonpath_rw
seaborn
30 changes: 30 additions & 0 deletions .github/workflows/test_notebooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Docs
on: [push, release]

jobs:
notebooks:
name: "Build the notebooks for the docs"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8

- name: Install dependencies
run: |
python -m pip install -U pip
python -m pip install -r .github/workflows/requirements.txt
- name: Execute the notebooks
run: |
jupyter nbconvert --to notebook --execute docs/source/tutorials/*.ipynb
- uses: actions/upload-artifact@v2
with:
name: notebooks-for-${{ github.sha }}
path: docs/tutorials


1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ __pycache__
*/*/__pycache__
*.pyc
.DS_store
docs/source/_build
3 changes: 3 additions & 0 deletions build/lib/vfb_connect/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"autoDocstring.docstringFormat": "sphinx"
}
110 changes: 68 additions & 42 deletions build/lib/vfb_connect/cross_server_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ def dequote(string):


class VfbConnect:
"""API wrapper class. By default this wraps connections to the more basal API endpoints (OWL, Neo4j).
"""API wrapper class. By default this wraps connections to the more basal
API endpoints (OWL, Neo4j).
Top level methods combined semantic queries that range across VFB content with neo4j queries, returning detailed
metadata about anatomical classes and individuals that fulfill these queries.
Expand All @@ -35,9 +36,9 @@ class VfbConnect:
Example semantic queries (OWL class expressions). Note quoting scheme (outer `"` + single quotes for entities).
"'GABAergic neuron'"
"'GABAeric neuron' that 'overlaps' some 'antennal lobe'"
"""
def __init__(self, neo_endpoint=get_default_servers()['neo_endpoint'],
neo_credentials=get_default_servers()['neo_credentials'],
Expand Down Expand Up @@ -71,9 +72,8 @@ def lookup_id(self, key, return_short_form=True):


def get_terms_by_region(self, region, cells_only=False, verbose=False, query_by_label=True, summary=True):
"""Generate JSON reports for all terms relevant to
annotating some specific region,
optionally limited by to cells"""
"""Generate JSON reports for all terms relevant to annotating some
specific region, optionally limited by to cells."""
preq = ''
if cells_only:
preq = "'cell' that "
Expand All @@ -99,17 +99,20 @@ def get_superclasses(self, class_expression, query_by_label=True, direct=False,
if not re.search("'", class_expression):
class_expression = "'" + class_expression + "'"
terms = self.oc.get_superclasses("%s" % class_expression, query_by_label=query_by_label)
return self.neo_query_wrapper.get_type_TermInfo(list(map(gen_short_form, terms)),
summary=summary)

def get_instances(self, class_expression, query_by_label=True, direct=False, summary=False):
"""Generate JSON report of all instances of class_expression. Instances are specific examples
of a type/class of structure, e.g. a specific instance of the neuron DA1 adPN from the FAFB_catmaid
database. Instances are typically associated with registered 3D image data and may include
connectomics data."""
"""Generate JSON report of all instances of class_expression.
Instances are specific examples of a type/class of structure,
e.g. a specific instance of the neuron DA1 adPN from the
FAFB_catmaid database. Instances are typically associated with
registered 3D image data and may include connectomics data.
"""
if not re.search("'", class_expression):
if query_by_label:
class_expression = self.lookup[class_expression].replace(':', '_')
class_expression = self.lookup[class_expression].replace(':', '_')
out = self.neo_query_wrapper._get_anatomical_individual_TermInfo_by_type(class_expression,
summary=True)
else:
Expand Down Expand Up @@ -145,8 +148,10 @@ def _get_neurons_connected_to(self, neuron, weight, direction, classification=No
else:
return dc

return dc

def get_similar_neurons(self, neuron, similarity_score='NBLAST_score', cutoff=None, source=None, return_dataframe=True):
"""Get all neurons """
"""Get all neurons."""
query = "MATCH (c1:Class)<-[:INSTANCEOF]-(n1)-[r:has_similar_morphology_to]-(n2)-[:INSTANCEOF]->(c2:Class) " \
"WHERE n1.short_form = '%s' " \
"WITH c1, n1, r, n2, c2 " \
Expand All @@ -162,32 +167,44 @@ def get_similar_neurons(self, neuron, similarity_score='NBLAST_score', cutoff=No
else:
return dc

def get_neurons_downstream_of(self, neuron, weight, classification=None, query_by_label=True,

def get_neurons_downstream_of(self, neuron, weight, classification=None, query_by_label=True,
return_dataframe = True):
"""Get all neurons downstream of individual `neuron` (short_form if query_by_label=False, otherwise label)
with connection strength > threshold. Optionally restrict target neurons to those specified by
`classification = 'class expression' e.g. "'Kenyon cell'" or "'neuron' that overlaps 'lateral horn'"."""
"""Get all neurons downstream of individual `neuron` (short_form if
query_by_label=False, otherwise label) with connection strength >
threshold.
Optionally restrict target neurons to those specified by
`classification = 'class expression' e.g. "'Kenyon cell'" or "'neuron' that overlaps 'lateral horn'".
"""
return self._get_neurons_connected_to(neuron=neuron, weight=weight, direction='upstream',
classification=classification, query_by_label=query_by_label,
return_dataframe=return_dataframe)

def get_neurons_upstream_of(self, neuron, weight, classification=None, query_by_label=True, return_dataframe=True):
"""Get all neurons downstream of individual `neuron` (short_form if query_by_label=False, otherwise label)
with connection strength > threshold. Optionally restrict target neurons to those specified by
`classification = 'class expression' e.g. "'Kenyon cell'" or "'neuron' that overlaps 'lateral horn'"."""
"""Get all neurons downstream of individual `neuron` (short_form if
query_by_label=False, otherwise label) with connection strength >
threshold.
Optionally restrict target neurons to those specified by
`classification = 'class expression' e.g. "'Kenyon cell'" or "'neuron' that overlaps 'lateral horn'".
"""
return self._get_neurons_connected_to(neuron=neuron, weight=weight, direction='downstream',
classification=classification, query_by_label=query_by_label,
return_dataframe=return_dataframe)

def get_connected_neurons_by_type(self, upstream_type, downstream_type, weight, query_by_label=True,
return_dataframe=True):
"""Get all synaptic connections between individual neurons of `upstream_type` and `dowstream_type` where
each synapse count >= `weight`. Warning: Does not support Class Expressions."""
"""Get all synaptic connections between individual neurons of
`upstream_type` and `dowstream_type` where each synapse count >=
`weight`.
Warning: Does not support Class Expressions.
"""

# Note - chose not to do this with class expressions to avoid poor performance and blowing up results.
# This might be confusing tough, given behavior of other, similar methods.
# Might be better to refactor to work out if query is class expression or class & funnel query method
# accordingly.

if query_by_label:
upstream_type = self.lookup_id(dequote(upstream_type))
Expand Down Expand Up @@ -233,25 +250,28 @@ def get_instances_by_dataset(self, dataset, summary=False):

def get_vfb_link(self, short_forms: iter, template):
"""Takes a list of VFB IDs (short_forms) and the name (label) of a template.
Returns a link to VFB loading all available images
of neurons on that template."""
short_forms = list(short_forms)
query = "MATCH (t:Template { label: '%s'}) return t.short_form" % template
dc = self.neo_query_wrapper._query(query)
if not dc:
raise ValueError("Unrecognised template name %s" % template)
return dc
def get_instances_by_dataset(self, dataset, summary=False):
"""Returns metadata for a dataset."""
if dataset:
query = "MATCH (ds:DataSet)<-[:has_source]-(i:Individual) " \
"WHERE ds.short_form = '%s' " \ name %s" % template)
else:
return self.vfb_base + short_forms.pop() + "&i=" + dc[0]['t.short_form'] + ',' + ','.join(short_forms)
def get_images_by_type(self, class_expression, template, image_folder,
image_type='swc', query_by_label=True, direct=False, stomp=False):
"""Retrieve images of instances of `class_expression` registered to `template` and save to disk,
along with manifest and references, to `image_folder`. Default image type = swc. Also supported: obj, nrrd, rds, wlz.
Returns manifest dataframe. If `stomp` is true, overwrites existing template_folder."""
if not re.search("'", class_expression):
class_expression = "'" + class_expression + "'"
instances = self.oc.get_instances(class_expression,
query_by_label=query_by_label,
def get_vfb_link(self, short_forms: iter, template):
"""Takes a list of VFB IDs (short_forms) and the name (label) of a
template.

Returns a link to VFB loading all available images of neurons on
that template.
"""
short_forms = list(short_forms)
query = "MATCH (t:Template { label: '%s'}) return t.short_form" % template
dc = self.neo_query_wrapper._query(query)y_label=query_by_label,
direct=direct)
return self.neo_query_wrapper.get_images([gen_short_form(i) for i in instances],
template=template,
Expand All @@ -260,9 +280,15 @@ def get_images_by_type(self, class_expression, template, image_folder,
stomp=stomp)
def get_images_by_type(self, class_expression, template, image_folder,
image_type='swc', query_by_label=True, direct=False, stomp=False):
"""Retrieve images of instances of `class_expression` registered to
`template` and save to disk, along with manifest and references, to
`image_folder`.






Default image type = swc. Also supported: obj, nrrd, rds, wlz.
Returns manifest dataframe. If `stomp` is true, overwrites existing template_folder.
"""
if not re.search("'", class_expression):
class_expression = "'" + class_expression + "'"
instances = self.oc.get_instances(class_expression,
23 changes: 15 additions & 8 deletions build/lib/vfb_connect/neo/neo4j_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,11 @@ def chunks(l, n):


class Neo4jConnect:
"""Thin layer over REST API to hold connection details,
handle multi-statement POST queries, return results and report errors."""
"""AI is creating summary for
Returns:
[type]: [description]
"""
# Return results might be better handled in the case of multiple statements - especially when chunked.
# Not connection with original query is kept.

Expand All @@ -83,19 +86,23 @@ def __init__(self, endpoint = get_default_servers()['neo_endpoint'],
self.usr = usr
self.pwd = pwd
self.test_connection()

def commit_list(self, statements, return_graphs = False):
"""Commit a list of statements to neo4J DB via REST API.
Prints requests status and warnings if any problems with commit.
- statements = list of cypher statements as strings
- return_graphs, optionally specify graphs to be returned in JSON results.
Errors prompt warnings, not exceptions, and cause return = FALSE.
Returns results list of results or False if any errors are encountered."""
Args:
statements (List[str]): list of cypher statements as strings
return_graphs (bool, optional): optionally specify graphs to be returned in JSON results. Defaults to False.
Returns:
List[str]: Returns results list of results or False if any errors are encountered. Errors prompt warnings, not exceptions, and cause return = FALSE.
"""
cstatements = []
if return_graphs:
for s in statements:
cstatements.append({'statement': s, "resultDataContents" : [ "row", "graph" ]})
else:
else:
for s in statements:
cstatements.append({'statement': s}) # rows an columns are returned by default.
payload = {'statements': cstatements}
Expand Down
20 changes: 10 additions & 10 deletions build/lib/vfb_connect/owl/owlery_query_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def add_obo_curies(self, prefixes):

def query(self, query_type, return_type,
query, query_by_label=False, direct=False, verbose=False):
"""
A wrapper for querying Owlery Endpoints. See
https://owlery.phenoscape.org/api/ for doc
"""A wrapper for querying Owlery Endpoints. See
https://owlery.phenoscape.org/api/ for doc.
:param query_type: Options: subclasses, superclasses,
equivalent, instances, types
:param return_type:
Expand Down Expand Up @@ -74,8 +74,8 @@ def query(self, query_type, return_type,
return False

def get_subclasses(self, query, query_by_label=False, direct=False, return_short_forms=False):
"""Get subclasses satisfying query, where query is an OWL DL is any OWL DL class expression
"""
"""Get subclasses satisfying query, where query is an OWL DL is any
OWL DL class expression."""
out = self.query(query_type='subclasses', return_type='superClassOf',
query=query, query_by_label=query_by_label,
direct=direct)
Expand All @@ -85,8 +85,8 @@ def get_subclasses(self, query, query_by_label=False, direct=False, return_short
return out

def get_instances(self, query, query_by_label=False, direct=False, return_short_forms=False):
"""Get instances satisfying query, where query is an OWL DL is any OWL DL class expression
"""
"""Get instances satisfying query, where query is an OWL DL is any OWL
DL class expression."""
out = self.query(query_type='instances', return_type='hasInstance',
query=query, query_by_label=query_by_label,
direct=direct)
Expand All @@ -96,8 +96,8 @@ def get_instances(self, query, query_by_label=False, direct=False, return_short_
return out

def get_superclasses(self, query, query_by_label=False, direct=False, return_short_forms=False):
"""Get superclasses satisfying `query`, where `query` is any OWL DL class expression.
"""
"""Get superclasses satisfying `query`, where `query` is any OWL DL
class expression."""
out = self.query(query_type='superclasses', return_type='subClassOf',
query=query, query_by_label=query_by_label,
direct=direct)
Expand All @@ -108,7 +108,7 @@ def get_superclasses(self, query, query_by_label=False, direct=False, return_sho


def labels_2_ids(self, query_string):
"""Substitutes labels for IDs in a query string"""
"""Substitutes labels for IDs in a query string."""

def subgp1_or_fail(m):
out = self.lookup.get(m.group(1))
Expand Down
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Binary file not shown.
Binary file added docs/build/doctrees/environment.pickle
Binary file not shown.
Binary file added docs/build/doctrees/index.doctree
Binary file not shown.
Binary file added docs/build/doctrees/modules.doctree
Binary file not shown.
Binary file added docs/build/doctrees/neo.doctree
Binary file not shown.
Binary file added docs/build/doctrees/neo.test.doctree
Binary file not shown.
Binary file added docs/build/doctrees/owl.doctree
Binary file not shown.
Binary file added docs/build/doctrees/setup.doctree
Binary file not shown.
Binary file added docs/build/doctrees/vfb_connect.doctree
Binary file not shown.
Binary file added docs/build/doctrees/vfb_connect.neo.doctree
Binary file not shown.
Binary file added docs/build/doctrees/vfb_connect.neo.test.doctree
Binary file not shown.
Binary file added docs/build/doctrees/vfb_connect.owl.doctree
Binary file not shown.
4 changes: 4 additions & 0 deletions docs/build/html/.buildinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: fa0ef853942b1c558941f28e6e29ba80
tags: 645f666f9bcd5a90fca523b33c5a78b7
7 changes: 7 additions & 0 deletions docs/build/html/_sources/cross_server_tools_test.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cross\_server\_tools\_test module
=================================

.. automodule:: cross_server_tools_test
:members:
:undoc-members:
:show-inheritance:
Loading

0 comments on commit 62641cd

Please sign in to comment.