SPARC queries
Table of Contents
- Data queries
- Python helper
- SciGraph cypher queries
- neru
- neru-7
- neru-6
- neru-5
- neru-4
- neru-3
- neru-2
- neru-1
- all populations
- neru populations
- neru model populations
- neru model populations and references
- TODO neru regions projected to
- TODO neru regions dendrited to
- TODO neru regions with processes from
- neru projects to
- neru neurites to
- neru population projects to
- neru populations projecting to
- neru populations with axons in
- neru populations dendriting to
- neru populations with dendrites in
- TODO neru populations with neurites in
- neru populations with processes in
- TODO neru populations by phenotype
- TODO neru phenotype by population
- existing
- yaml file
- neru
- ApiNATOMY competency queries
- Simple blaze
- Sanity checks
- General queries
- Use cases
Data queries
Datasets
Dataset Predicates
SELECT DISTINCT ?p # ?pp # ?po WHERE { ?dataset a sparc:Dataset . ?dataset ?p ?o . # ?p ?pp ?po . } ORDER BY ?p
Electrophysiology datasets
SELECT DISTINCT ?d ?label ?approach WHERE { VALUES ?match { "electrophysiology" } ?d a sparc:Dataset ; rdfs:label ?l ; TEMP:hasExperimentalApproach ?approach . FILTER (str(?approach) = str(?match)) BIND(substr(str(?l), 0, 40) AS ?label) # TODO lift and pull filetypes }
Datasets by contents updated time
SELECT DISTINCT ?dataset ?ut (substr(str(?l), 0, 40) as ?label) WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:contentsWereUpdatedAtTime ?ut . ?dataset rdfs:label ?l . } ORDER BY DESC(?ut)
Human dataset queries
import rdflib from pyontutils.core import OntResIri from pyontutils.namespaces import sparc, TEMP, dc, rdfs ori = OntResIri('https://cassava.ucsd.edu/sparc/preview/exports/curation-export.ttl') g = ori.graph gns = g.namespace_manager def fmt(s, u): return f'[[{u}][{s.n3(gns)}]]' species = set([fmt(do, urih) for s, p, o in g if isinstance(o, rdflib.Literal) and ('human' in o.lower() or 'homo' in o.lower()) and p == sparc.animalSubjectIsOfSpecies for do in g[s:TEMP.hasDerivedInformationAsParticipant] for urih in g[do:TEMP.hasUriHuman]]) hlabel = set([fmt(s, urih) for s, p, o in g if isinstance(o, rdflib.Literal) and ('human' in o.lower() or 'homo' in o.lower()) and p == rdfs.label for urih in g[s:TEMP.hasUriHuman]]) htitle = set([fmt(s, urih) for s, p, o in g if isinstance(o, rdflib.Literal) and ('human' in o.lower() or 'homo' in o.lower()) and p == dc.title for urih in g[s:TEMP.hasUriHuman]]) htd = set([fmt(s, urih) for s, p, o in g if isinstance(o, rdflib.Literal) and ('human' in o.lower() or 'homo' in o.lower()) and (p == dc.title or p == dc.description) for urih in g[s:TEMP.hasUriHuman]]) counts = dict(species=len(human), label=len(hlabel), title=len(htitle), title_and_desc=len(htd)) [print(_ + r' \\') for _ in ['species n= ' + str(counts['species'])] + sorted(species) + ['label n= ' + str(counts['label'])] + sorted(hlabel) + ['title n= ' + str(counts['title'])] + sorted(htitle) + ['td n= ' + str(counts['title_and_desc'])] + sorted(htd)]
Test
Originally from sparcur.reports.SparqlQueries
.
- Dataset about
SELECT DISTINCT ?dataset ?about WHERE { ?type rdfs:subClassOf* sparc:Resource . ?dataset rdf:type ?type . ?dataset isAbout: ?about . } LIMIT ?limit
- Dataset subjects
SELECT DISTINCT ?dataset ?subj WHERE { ?startsubj a sparc:Subject . ?startsubj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj a sparc:Subject . ?subj TEMP:hasDerivedInformationAsParticipant ?dataset . } LIMIT ?limit
- Dataset groups
SELECT DISTINCT ?dataset ?group ?subj WHERE { ?startsubj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasAssignedGroup ?group . } LIMIT ?limit
- Dataset bundle
SELECT DISTINCT ?dataset WHERE { ?startdataset TEMP:collectionTitle ?string . ?dataset TEMP:collectionTitle ?string . } LIMIT ?limit
- Dataset subject species
SELECT DISTINCT ?dataset ?species WHERE { ?dataset TEMP:isAboutParticipant ?subject . ?subject sparc:animalSubjectIsOfSpecies ?species . FILTER ( CONTAINS(str(?species), "human") || CONTAINS(str(?species), "homo sapiens") || ?species = NCBITaxon:9606 ) } LIMIT ?limit
- Dataset human subjects and samples
SELECT DISTINCT ?dataset ?subject ?subject_meta ?sample ?sample_meta ?species WHERE { ?dataset TEMP:isAboutParticipant ?subject . ?subject sparc:animalSubjectIsOfSpecies ?species . ?subject ?sup ?subject_meta . FILTER ( CONTAINS(str(?species), "human") || CONTAINS(str(?species), "homo sapiens") || ?species = NCBITaxon:9606 ) ?sample TEMP:wasDerivedFromSubject ?subject . ?sample ?sap ?sample_meta . } LIMIT ?limit
- Dataset milestone completion date
SELECT DISTINCT ?dataset ?date WHERE { ?dataset TEMP:milestoneCompletionDate ?date . } ORDER BY ASC(?date) LIMIT ?limit
- Award affiliations
Can we see the multi-institutional nature of SPARC collaborations?
SELECT DISTINCT ?award ?affiliation (str(?affil_l) as ?al) WHERE { ?dataset TEMP:hasAwardNumber ?award . ?contributor TEMP:contributorTo ?dataset . ?contributor TEMP:hasAffiliation ?affiliation . ?affiliation rdfs:label ?affil_l . # FILTER isUri(?affiliation) } ORDER BY ASC(?award) ASC(?al) LIMIT ?limit
Protocols
Protocol general report
How to interpret this report.
The rows are ordered by
- whether there is a dataset directly associated with the protocol id
- whether the protocol has a human readable uri.
- by the number of protcur annotations that have been made on the protocol
If there are zero protcur annotations it usually means that only the minimal protocol curation workflow was completed. If there the number of protocol annotations is null it means that no annotations of any kind have been made on that protocol. This can only happen for protocols that come from the dataset description file.
If the dataset is null and there are annotations it usually means that the protocol is transitively related to a dataset. There are annotations on the protocols that link them directly to the dataset in question but we are not currently pulling them into the knowledge graph. It also means that the protocol url in question was not listed in the dataset description file but may have been listed in another protocol or in a collection of protocols.
If hasUri
is false and dataset is not null then it usually means that the protocol has been
deleted or that something else has gone wrong. If dataset is null and hasUri
is null it just means
that the protocol is present only in protcur.ttl
and the additional identifiers have not been
processed.
select distinct ?protocol ?n (sample(?dataset) AS ?datasetx) ?doi_protocol (sample(bound(?urih_protocol)) as ?hasUri) (sample(bound(?some_child)) as ?hasComplexAnnos) where { ?protocol a sparc:Protocol . optional { ?protocol TEMP:hasNumberOfProtcurAnnotations ?n } optional { ?dataset TEMP:hasProtocol ?protocol } optional { ?protocol TEMP:hasDoi ?doi_protocol } optional { ?protocol TEMP:hasUriHuman ?urih_protocol } optional { ?protocol ?some_predicate ?annotation . ?annotation TEMP:protcurChildren ?some_child } } group by ?protocol ?n ?doi_protocol ?hasUri order by desc(bound(?datasetx)) asc(?hasUri) desc(?n)
./reports/protocol-report.csv
Total protocols
SELECT (COUNT(DISTINCT ?protocol) AS ?count) WHERE { ?protocol a sparc:Protocol . }
Total protocols with at least one protcur annotation
SELECT (COUNT(*) as ?count) { <<sparql-protocols-at-least-one-protc>> }}
SELECT (COUNT(*) as ?count) { <<sparql-protocols-pio-api-at-least-one-protc>> }
select distinct ?protocol ?anno_count where { values ?some_predicate { TEMP:protocolEmploysTechnique TEMP:protocolInvolvesAction TEMP:protocolInvolvesAspect TEMP:protocolInvolvesBlackBox TEMP:protocolInvolvesBlackBoxComponent TEMP:protocolInvolvesInput TEMP:protocolInvolvesInvariant } ?protocol a sparc:Protocol ; ?some_predicate ?annotation ; # this line an the filter should wind up with the same number TODO add a test to check TEMP:hasNumberOfProtcurAnnotations ?anno_count . FILTER (?anno_count > 0 ) FILTER CONTAINS(str(?protocol), "protocols.io/api") #FILTER CONTAINS(str(?protocol), "protocols.io") }
grep -oE 'TEMP:protocol[^\ ]+' protcur.ttl | sort -u
select distinct ?protocol ?anno_count where { values ?some_predicate { TEMP:protocolEmploysTechnique TEMP:protocolInvolvesAction TEMP:protocolInvolvesAspect TEMP:protocolInvolvesBlackBox TEMP:protocolInvolvesBlackBoxComponent TEMP:protocolInvolvesInput TEMP:protocolInvolvesInvariant } ?protocol a sparc:Protocol ; ?some_predicate ?annotation ; # this line an the filter should wind up with the same number TODO add a test to check TEMP:hasNumberOfProtcurAnnotations ?anno_count . FILTER (?anno_count > 0 )
Published protocols with complex protcur annotations
SELECT (COUNT(*) as ?count) { <<sparql-complex-protocols>> }
SELECT (COUNT(*) as ?count) { <<sparql-complex-protocols-published>> }
<<sparql-complex-protocols>> ?protocol TEMP:hasDoi ?doi . }
select distinct ?protocol ?anno_count where { ?annotation TEMP:protcurChildren ?some_child . ?protocol a sparc:Protocol ; ?some_predicate ?annotation ; TEMP:hasNumberOfProtcurAnnotations ?anno_count .
Conditions studied
Experimental groups
WHERE { ?startsubj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasAssignedGroup ?group . }
SELECT DISTINCT ?dataset ?group ?subj WHERE { ?startsubj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasAssignedGroup ?group . } ORDER BY ASC(?dataset) ASC(?group) LIMIT ?limit
SELECT DISTINCT ?group ?subj WHERE { ?startsubj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasDerivedInformationAsParticipant ?dataset . ?subj TEMP:hasAssignedGroup ?group . } ORDER BY ASC(?group) LIMIT ?limit
Techniques
SELECT DISTINCT ?dataset ?technique # ?protocol # ?technique_p WHERE { { ?dataset a sparc:Dataset . ?dataset TEMP:protocolEmploysTechnique ?technique . # ?technique rdfs:label ?tl } UNION { ?dataset TEMP:hasProtocol ?protocol . ?protocol TEMP:protocolEmploysTechnique ?technique . # ?technique rdfs:label ?tl } } LIMIT ?limit
Test
Originally from sparcur.reports.SparqlQueries
.
- Protocol techniques
SELECT DISTINCT ?protocol ?technique WHERE { ?protocol rdf:type sparc:Protocol . ?protocol TEMP:protocolEmploysTechnique ?technique . } LIMIT ?limit
- Protocol aspects
SELECT DISTINCT ?protocol ?aspect WHERE { ?protocol rdf:type sparc:Protocol . ?protocol TEMP:protocolInvolvesAspect ?ast . ?ast rdf:type protcur:aspect . ?ast TEMP:hasValue ?aspect . } LIMIT ?limit
- Protocol inputs
SELECT DISTINCT ?protocol ?ast_in ?input WHERE { ?protocol rdf:type sparc:Protocol . ?protocol TEMP:protocolInvolvesInput ?ast_in . ?ast_in rdf:type protcur:input . ?ast_in TEMP:hasValue ?input . } LIMIT ?limit
- Protocol species dose
SELECT DISTINCT ?dataset ?protocol (str(?label_drug) as ?l_drug) ?value_lt WHERE { VALUES ?t {protcur:invariant protcur:parameter} . ?ast_inv a ?t . ?ast_inv TEMP:hasValue ?bnode . ?bnode rdf:value ?value_lt . #?bnode TEMP:hasUnit unit:milligram%20%2F%20kilogram . # seems like the %20 etc. break curies? ?bnode TEMP:hasUnit <http://uri.interlex.org/tgbugs/uris/readable/aspect/unit/milligram%20%2F%20kilogram> . FILTER (?value_lt < ?limit) ?ast_drug a protcur:input . ?ast_drug TEMP:hasValue ?drug . ?drug rdfs:label ?label_drug . ?ast_drug TEMP:protcurChildren+ ?ast_child . ?ast_child TEMP:hasValue ?bnode . ?protocol a sparc:Protocol . ?protocol TEMP:protocolInvolvesInput ?ast_drug . ?protocol TEMP:protocolInvolvesInput ?ast_in_sp . ?ast_in_sp rdf:type protcur:input . ?ast_in_sp TEMP:hasValue ?species . OPTIONAL { ?dataset TEMP:hasProtocol ?protocol } . } ORDER BY ?label_input ?value_lt
- Protocols with known anaesthetic or analgesic roles
select distinct ?pro ?ana ?l ?u ?v where { ?pro TEMP:protocolInvolvesInput ?anno . ?anno TEMP:hasValue ?ana . ?anno TEMP:protcurChildren ?ad . ?ad TEMP:hasValue ?asp . ?ad TEMP:protcurChildren ?ai . ?ai TEMP:hasValue ?bn . ?bn TEMP:hasUnit ?u . ?bn rdf:value ?v . ?ana rdfs:label ?l . ?ana ?p ?b . ?b owl:onProperty RO:0000087 . ?b owl:someValuesFrom ?o . ?o rdfs:subClassOf* ?role . values ?asp {asp:dose asp:percent-volume} . values ?role {CHEBI:38867 CHEBI:35480} . } order by ?l
Datasets following same protocol with different subjects
Completeness
SELECT DISTINCT ?dataset ?completeness WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:completenessOfDataset ?completeness . } LIMIT ?limit
Dataset collections
SELECT DISTINCT ?title ?dataset WHERE { ?startdataset TEMP:collectionTitle ?title . ?dataset TEMP:collectionTitle ?title . } ORDER BY ASC(?title) LIMIT ?limit
Subjects
Members
Show me all of the experimental subjects that a dataset contains information about.
SELECT DISTINCT ?dataset ?subject WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:isAboutParticipant ?subject . ?subject a sparc:Subject . } LIMIT ?limit
Total
Show me the total number of subjects in the knowledge graph.
SELECT DISTINCT (COUNT(DISTINCT ?subject) as ?count_subject) WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:isAboutParticipant ?subject . ?subject a sparc:Subject . }
Subject Metadata
Show me a regularized set of metadata for all subjects that includes the following.
- Identifier
- Group
- Species
- Strain
- Sex
- Age Category
- Age
- Mass
SELECT DISTINCT ?local_id ?assigned_group ?l_species ?strain ?l_sex ?age_category ?age_value ?age_unit ?mass_value ?mass_unit WHERE { ?subject a sparc:Subject . ?subject TEMP:localId ?local_id . ?subject sparc:animalSubjectIsOfSpecies ?species . OPTIONAL { ?species rdfs:label ?l_species . } OPTIONAL { ?subject sparc:animalSubjectIsOfStrain ?strain . } # ?strain rdfs:label ?l_strain . OPTIONAL { ?subject TEMP:hasBiologicalSex ?sex . ?sex rdfs:label ?l_sex . } OPTIONAL { ?subject TEMP:hasAgeCategory ?age_category . } OPTIONAL { ?subject TEMP:hasAssignedGroup ?assigned_group . } # OPTIONAL { ?subject TEMP:participantInPerformanceOf ?protocol . } OPTIONAL { # mass ?subject sparc:animalSubjectHasWeight ?bn_mass . ?bn_mass a sparc:Measurement . ?bn_mass TEMP:hasUnit ?mass_unit . ?bn_mass rdf:value ?mass_value . } OPTIONAL { # age ?subject TEMP:hasAge ?bn_age . ?bn_age a sparc:Measurement . ?bn_age TEMP:hasUnit ?age_unit . ?bn_age rdf:value ?age_value . } # VALUES ?l_s {?species ?sex} # doesn't work, if it did it would duplicate rows # ?l_s rdfs:label ?label } LIMIT ?limit
TODO By sex
SELECT DISTINCT (COUNT(DISTINCT ?subject) as ?count_subject) WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:isAboutParticipant ?subject . ?subject a sparc:Subject . }
Samples
Members
Show me all of the experimental samples that a dataset contains information about.
SELECT DISTINCT ?dataset ?sample WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:isAboutParticipant ?sample . ?sample a sparc:Sample . } LIMIT ?limit
Total
Show me the total number of samples in the knowledge graph.
SELECT DISTINCT (COUNT(DISTINCT ?sample) as ?count_sample) WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:isAboutParticipant ?sample . ?sample a sparc:Sample . }
Sample predicates
SELECT DISTINCT ?p WHERE { ?sample a sparc:Sample . ?sample ?p ?o . }
Sample Metadata
Show me a regularized set of metadata for all subjects that includes the following.
- Identifier
- Group
- Anatomical entity
SELECT DISTINCT ?subject_lid ?local_id ?assigned_group (str(?anat_ent_src) as ?aess) WHERE { ?sample a sparc:Sample . ?sample TEMP:localId ?local_id . ?sample TEMP:wasDerivedFromSubject ?subject . ?subject TEMP:localId ?subject_lid . ?subject a sparc:Subject . OPTIONAL { ?sample TEMP:hasAssignedGroup ?assigned_group . } OPTIONAL { ?sample TEMPRAW:wasExtractedFromAnatomicalRegion ?anat_ent_src . } # OPTIONAL { ?sample TEMP:hasAge ?abe . } # OPTIONAL { ?sample TEMP:participantInPerformanceOf ?protocol . } } LIMIT ?limit
Anatomical entities
Dataset
- Involves
SELECT DISTINCT ?dataset ?protocol #?ae (str(?aes) as ?entity) WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:hasProtocol ?protocol . ?protocol TEMPRAW:involvesAnatomicalRegion ?aes . # ?ae rdfs:label ?l_ae . } ORDER BY ASC(?entity) LIMIT ?limit
- About
SELECT DISTINCT ?dataset # ?ae (str(?l_ae) as ?entity) WHERE { ?dataset a sparc:Dataset . ?dataset isAbout: ?ae . # TODO not 100% on the modelling here ?ae rdfs:label ?l_ae . ?ae rdfs:subClassOf* UBERON:0001062 . # have to load uberon for this } ORDER BY ASC(?l_ae) LIMIT ?limit
- Sample Source
SELECT DISTINCT ?dataset (str(?ae) as ?aes) # ?slid WHERE { ?sample TEMP:hasDerivedInformationAsParticipant ?dataset . ?sample TEMPRAW:wasExtractedFromAnatomicalRegion ?ae . ?sample a sparc:Sample . # ?sample TEMP:localId ?slid . ?dataset a sparc:Dataset . } ORDER BY DESC(?ae) # ASC(?slid) LIMIT ?limit
Protocol
- Simple
SELECT (COUNT(*) as ?count) { SELECT DISTINCT ?protocol WHERE { ?protocol a sparc:Protocol . FILTER CONTAINS(str(?protocol), "protocols.io/api") #FILTER CONTAINS(str(?protocol), "protocols.io") } }
SELECT DISTINCT ?protocol WHERE { ?protocol a sparc:Protocol . FILTER CONTAINS(str(?protocol), "protocols.io/api") #FILTER CONTAINS(str(?protocol), "protocols.io") }
- Protocol triples
SELECT DISTINCT ?protocol ?p ?o WHERE { ?protocol a sparc:Protocol . ?protocol ?p ?o FILTER CONTAINS(str(?protocol), "protocols.io") } LIMIT ?limit
- Involves
NOTE In order for these to work with subClassOf
UBERON
uberon must be loaded.SELECT DISTINCT ?protocol ?bb_value (str(?l_bb) as ?ls) WHERE { ?protocol a sparc:Protocol . ?protocol TEMP:protocolInvolvesBlackBox ?ast_bb . ?ast_bb rdf:type protcur:black-box . # TODO need to refine on organ an ingest the new alignment ?ast_bb TEMP:hasValue ?bb_value . ?bb_value rdfs:subClassOf+ UBERON:0001062 . ?bb_value rdfs:label ?l_bb . } LIMIT ?limit
SELECT DISTINCT ?protocol ?bbc_value (str(?l_bbc) as ?bbl) WHERE { ?protocol a sparc:Protocol . ?protocol TEMP:protocolInvolvesBlackBoxComponent ?ast_bbc . ?ast_bbc rdf:type protcur:black-box-component . # TODO need to refine on organ an ingest the new alignment ?ast_bbc TEMP:hasValue ?bbc_value . ?bbc_value rdfs:subClassOf+ UBERON:0001062 . ?bbc_value rdfs:label ?l_bbc . } ORDER BY ?bbl LIMIT ?limit
- Protc annotations
grep -oE 'a\ protcur:[^\ ]+' protcur.ttl | sort -u | cut -d' ' -f2
select (count(*) as ?count) { select distinct ?anno where { # TODO subPropertyOf #values ?anno_predicate {} # this is a bad way to do this # ?s ?anno_predicate ?anno values ?anno_type { protcur:aspect protcur:black-box protcur:black-box-component protcur:executor-verb protcur:input protcur:invariant protcur:output protcur:parameter } ?anno a ?anno_type . }}
select (count(*) as ?count) { select distinct ?anno where { # TODO subPropertyOf #values ?anno_predicate {} # this is a bad way to do this # ?s ?anno_predicate ?anno values ?anno_type { protcur:aspect protcur:black-box protcur:black-box-component protcur:executor-verb protcur:input protcur:invariant protcur:output protcur:parameter } ?anno a ?anno_type . ?protocol a sparc:Protocol . ?protocol ?p ?banno . ?banno TEMP:protcurChildren* ?anno . FILTER CONTAINS(str(?protocol), "protocols.io/api") #FILTER CONTAINS(str(?protocol), "protocols.io") } }
select distinct ?anno where { # TODO subPropertyOf #values ?anno_predicate {} # this is a bad way to do this # ?s ?anno_predicate ?anno values ?anno_type { protcur:aspect protcur:black-box protcur:black-box-component protcur:executor-verb protcur:input protcur:invariant protcur:output protcur:parameter } ?anno a ?anno_type . ?protocol a sparc:Protocol . ?protocol ?p ?banno . ?banno TEMP:protcurChildren* ?anno . FILTER CONTAINS(str(?protocol), "protocols.io/api") #FILTER CONTAINS(str(?protocol), "protocols.io") }
select distinct ?anno where { # TODO subPropertyOf #values ?anno_predicate {} # this is a bad way to do this # ?s ?anno_predicate ?anno values ?anno_type { protcur:aspect protcur:black-box protcur:black-box-component protcur:executor-verb protcur:input protcur:invariant protcur:output protcur:parameter } ?anno a ?anno_type .
Uberon tests
In order to use these you need to load the latest version of uberon into blazegraph.
SELECT DISTINCT ?sc (str(?l) as ?label) WHERE { # BIND("brain" AS ?label) # Well would you look at that! VALUES (?root) { ( UBERON:0001062 ) } ?sc rdfs:subClassOf+ ?root . ?sc rdfs:label ?l . } ORDER BY ASC(?label) LIMIT ?limit
select ?p ?o where { VALUES (?s) { ( UBERON:0001062 ) } ?s ?p ?o . }
Associated scaffolds
Manifest files
A SODA development use case. Find me datasets that have top level manifests with no errors.
SELECT DISTINCT ?dataset WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:hasPart+ ?file . ?file a sparc:File . ?file a sparc:Manifest . ?file TEMP:hasParent ?dataset . # this is the tricky bit, because we conflate the identifier for dataset and the folder ?file TEMP:hasErrors 0 . } LIMIT ?limit
Contributors
Count
SELECT DISTINCT (COUNT(DISTINCT ?person) as ?cp) WHERE { ?person a sparc:Person . } LIMIT ?limit
ORCiD
Count the number of contributors that have ORCiDs.
SELECT DISTINCT (COUNT(DISTINCT ?person) as ?cp) #?fn #?ln WHERE { ?person a sparc:Person . ?person sparc:firstName ?fn . ?person sparc:lastName ?ln . FILTER CONTAINS(str(?person), "orcid.org") } LIMIT ?limit
Other
NOTE These are not yet in the ttl file, the queries written here will not work yet.
File types
In all likelihood we are not going to include the names of each of the individual files in the standard ttl export. We may put it in a named graph and then update the journal, possibly only for released datasets. The use cases for having individual files in the graph is not at all clear, we might have individual folders, or run it in the other direction where a subject could list the folders that contain data about it. Trying to keep the graph in sync with Blackfynn would be quite a pain, essentially we would store/append every single file that ever appears and then mark the deleted ones as deleted or something.
SELECT DISTINCT ?dataset ?file_type WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:containsFileWithType ?file_type . # TODO not 100% on the modelling here } LIMIT ?limit
In the path-metadata
folder of curation-export
.
grep -rh 'mimetype":' | sort | uniq -c | sort -h
This doesn't get coverage for file extensions so in addition we run the following.
grep -rh 'basename":.\+\.\([a-z]\+\)' | grep -o '\.[a-z]\+"' | sort | uniq -c | sort -h
Has Raw Data
SELECT DISTINCT ?dataset ?raw WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:containsFolderForRawData ?raw . # TODO not 100% on the modelling here } LIMIT ?limit
Has Derived Data
SELECT DISTINCT ?dataset ?derived WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:containsFolderForDerivedData ?derived . # TODO not 100% on the modelling here } LIMIT ?limit
Has Code
SELECT DISTINCT ?dataset ?code WHERE { ?dataset a sparc:Dataset . ?dataset TEMP:containsFolderForCode ?code . # TODO not 100% on the modelling here } LIMIT ?limit
Used in simulation
This modeling is extremely preliminary.
SELECT DISTINCT ?dataset ?dataset_sim WHERE { ?dataset a sparc:Dataset . ?dataset_sim a sparc:Dataset . # TODO not 100% on this # the dataset holds the simulation, and is also what references the other datasets # whether we need an explicit type for simulation datasets is not clear, I suspect # that we do not, since datasets are just data, the aboutness or typeness probably # should come from the fact that the dataset specifies or houses a simulation ... # ?dataset_sim a sparc:SimulationDataset . # also not good # ?dataset_sim TEMP:isSubstrateForSomeComputationalSimulation true . # FIXME this is bad bad bad VALUES ?p {TEMP:derivesParametersFrom TEMP:derivesValidationDataFrom ilxtr:hasInformationInput} . ?dataset_sim ?p ?dataset . } LIMIT ?limit
Subject reconciliation
first pass requires that the subject_id be identical
v2
SELECT (COUNT(*) as ?count) { <<pds-v2>> }
SELECT DISTINCT ?s ?dataset (str(?id) as ?local_id) ?award ?species WHERE { ?s a sparc:Subject; TEMP:localId ?id; TEMP:hasDerivedInformationAsParticipant ?dataset ; sparc:animalSubjectIsOfSpecies ?species . ?dataset a sparc:Dataset ; TEMP:hasAwardNumber ?award . { SELECT DISTINCT ?id WHERE { ?s a sparc:Subject ; TEMP:localId ?id ; TEMP:hasDerivedInformationAsParticipant ?dataset . } GROUP BY ?id HAVING (count(?id) > 1) } } ORDER BY ?id
v1
# :results table # RUN:block SELECT distinct ?s1 ?s2 ?id ?dataset1 ?dataset2 ?species1 ?species2 ?award1 ?award2 WHERE { # Give me all subjects with duplicate IDs with unique datasets { SELECT ?id WHERE { ?s1 a owl:NamedIndividual ; TEMP:localId ?id ; TEMP:hasDerivedInformationAsParticipant ?datasetx . ?s2 a owl:NamedIndividual ; TEMP:localId ?id ; TEMP:hasDerivedInformationAsParticipant ?datasety . filter(?datasetx != ?datasety) } GROUP BY ?id having (count(?id) > 1)} # filter out the cases where there can't be a match because species doesn't match ?s1 TEMP:localId ?id ; sparc:animalSubjectIsOfSpecies ?species1; TEMP:hasDerivedInformationAsParticipant ?dataset1 . ?s2 TEMP:localId ?id ; sparc:animalSubjectIsOfSpecies ?species2; TEMP:hasDerivedInformationAsParticipant ?dataset2 . filter(?s1 != ?s2) filter(STR(IRI(?s1)) < STR(IRI(?s2))) # this is a hack to filter out duplicate triples # filter to find non-matching awards # using contact person doesn't make sense as they are 1:1 with award right now ?dataset1 a owl:NamedIndividual ; TEMP:hasAwardNumber ?award1 . ?dataset2 a owl:NamedIndividual ; TEMP:hasAwardNumber ?award2 . } order by ?id limit ?limit
Python helper
call
simple
Python code to simplify neru
and supporting functions to extract terminal regions.
from pyontutils.config import auth from nifstd_tools.simplify import apinat_deblob, sub, pred, obj, ematch from nifstd_tools.simplify import axon, dend, bag, top, ie, ies, iot, iots, ext, fasIn, endIn, layerIn, onts ext = onts # XXX schema change def query(neupop_id): import requests url = ('https://scicrunch.org/api/1/sparc-scigraph/scigraph/dynamic/' f'demos/apinat/neru-7/{neupop_id}?limit=9999999&key={auth.get("scigraph-api-key")}') resp = requests.get(url, headers={'Accept': 'application/json'}) blob = resp.json() return blob def find_terminals(blob, type): return [es for es in blob['edges'] if pred(es, iots) and obj(es, type) and ematch(blob, (lambda e, m: sub(e, m) and pred(e, top) and obj(e, bag)), sub(es))] def find_region(blob, edge): collect = [] def select(e, m, collect=collect): if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) collect.extend([b for b in blob['nodes'] if b['id'] == region]) return region ematch(blob, select, sub(edge)) return collect def find_region_layer(blob, edge, bindex): collect = [] layers = [] layers_iots = [] donel = set() doner = set() def select_term(e, m, layers=layers): if sub(e, m): pprint(e) if (pred(e, onts) or pred(e, iots)): layer = obj(e) if layer not in donel: donel.add(layer) if pred(e, iots): layers_iots.append(bindex[layer]) else: layers.append(bindex[layer]) return layer def select(e, m, collect=collect): if sub(e, m): if pred(e, layerIn): # we're at a layer ematch(blob, select_term, sub(e)) return ematch(blob, select, obj(e)) elif (pred(e, fasIn) or pred(e, endIn)): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) if region not in doner: doner.add(region) collect.append(bindex[region]) return region ematch(blob, select, sub(edge)) if collect and not layers and not layers_iots: layers = [None] elif layers_iots and not layers: layers = layers_iots if len(collect) != len(layers): raise ValueError(f'len not matched {len(collect)} {len(layers)}') return list(zip(collect, layers)) def find_terminal_regions(blob, type): return [region for es in find_terminals(blob, type) for region in find_region(blob, es)] def find_terminal_region_layers(blob, type, bindex): return [(region, layer) for es in find_terminals(blob, type) for region, layer in find_region_layer(blob, es, bindex)] def main(blob=None, blob_string=None, neupop_id=None, remove_converge=remove): # do not call this function unless it is from an org babel block, there are free variables if blob is None and blob_string is not None: import json blob = json.loads(blob_string) neupop_id = neupop_id if neupop_id else 'ilxtr:neuron-type-keast-6' if blob is None: blob = query(neupop_id) blob, edges, somas, externals, ordering_edges = v = apinat_deblob( blob, remove_converge=remove_converge) test_call = False # change to True to test the #+call: expression if test_call: pprint(v) return v
pprint(blob)
terminal regions
Find the ontology identifiers for terminal regions.
from pyontutils.config import auth from nifstd_tools.simplify import apinat_deblob, sub, pred, obj, ematch from nifstd_tools.simplify import axon, dend, bag, top, ie, ies, iot, iots, ext, fasIn, endIn, layerIn, onts ext = onts # XXX schema change def query(neupop_id): import requests url = ('https://scicrunch.org/api/1/sparc-scigraph/scigraph/dynamic/' f'demos/apinat/neru-7/{neupop_id}?limit=9999999&key={auth.get("scigraph-api-key")}') resp = requests.get(url, headers={'Accept': 'application/json'}) blob = resp.json() return blob def find_terminals(blob, type): return [es for es in blob['edges'] if pred(es, iots) and obj(es, type) and ematch(blob, (lambda e, m: sub(e, m) and pred(e, top) and obj(e, bag)), sub(es))] def find_region(blob, edge): collect = [] def select(e, m, collect=collect): if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) collect.extend([b for b in blob['nodes'] if b['id'] == region]) return region ematch(blob, select, sub(edge)) return collect def find_region_layer(blob, edge, bindex): collect = [] layers = [] layers_iots = [] donel = set() doner = set() def select_term(e, m, layers=layers): if sub(e, m): pprint(e) if (pred(e, onts) or pred(e, iots)): layer = obj(e) if layer not in donel: donel.add(layer) if pred(e, iots): layers_iots.append(bindex[layer]) else: layers.append(bindex[layer]) return layer def select(e, m, collect=collect): if sub(e, m): if pred(e, layerIn): # we're at a layer ematch(blob, select_term, sub(e)) return ematch(blob, select, obj(e)) elif (pred(e, fasIn) or pred(e, endIn)): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) if region not in doner: doner.add(region) collect.append(bindex[region]) return region ematch(blob, select, sub(edge)) if collect and not layers and not layers_iots: layers = [None] elif layers_iots and not layers: layers = layers_iots if len(collect) != len(layers): raise ValueError(f'len not matched {len(collect)} {len(layers)}') return list(zip(collect, layers)) def find_terminal_regions(blob, type): return [region for es in find_terminals(blob, type) for region in find_region(blob, es)] def find_terminal_region_layers(blob, type, bindex): return [(region, layer) for es in find_terminals(blob, type) for region, layer in find_region_layer(blob, es, bindex)] def main(blob=None, blob_string=None, neupop_id=None, remove_converge=remove): # do not call this function unless it is from an org babel block, there are free variables if blob is None and blob_string is not None: import json blob = json.loads(blob_string) neupop_id = neupop_id if neupop_id else 'ilxtr:neuron-type-keast-6' if blob is None: blob = query(neupop_id) blob, edges, somas, externals, ordering_edges = v = apinat_deblob( blob, remove_converge=remove_converge) test_call = False # change to True to test the #+call: expression if test_call: pprint(v) return v from pprint import pprint blob, *_ = main(blob_string=result) bindex = {n['id']:n for n in blob['nodes']} # find terminal regions axon_terminal_regions = find_terminal_regions(blob, axon) dend_terminal_regions = find_terminal_regions(blob, dend) #pprint(axon_terminal_regions) #pprint(dend_terminal_regions) axon_terminal_rl = find_terminal_region_layers(blob, axon, bindex) dend_terminal_rl = find_terminal_region_layers(blob, dend, bindex) pprint([(r['id'], (l if l is None else l['id'])) for r, l in axon_terminal_rl]) pprint([(r['id'], (l if l is None else l['id'])) for r, l in dend_terminal_rl])
connectivity pairs
This code produces the basic connectivity of a neuron population.
The result is a list of pairs, the pairs are the subject and object
of the triple subject (or apinatomy:next apinatomy:next*) object
.
Thus they represent the full connectivity of the population.
The contents of each element of the pair tuples with three elements.
- The id for the neuronal process involved in the connection.
- The ontology id for the layer in which the neuronal process is located. This may be None if no layer is specified in the model.
- The ontology id for the region in which the neuronal process is located.
In the example presented here for keast neuron 5 the final entries all have the same start and end location because they are the soma, and the roots of the axon and the dendrite.
intIn = 'apinatomy:internalIn' def isLayer(blob, s): return ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), s) def reclr(blob, start_link): # recurse up the hierarchy until fasIn endIn intIn terminates #print('starting reclr') collect = [] layer = [] col = True def select_ext(e, m, collect=collect): nonlocal col nonlocal layer if sub(e, m): if pred(e, 'apinatomy:cloneOf'): # should be zapped during simplify return ematch(blob, select_ext, obj(e)) if pred(e, onts) or pred(e, iot) or pred(e, iots): #print('select_ext', e) external = obj(e) #print('se', col, layer) if col: if layer: if len(layer) > 1: l, *layer = layer else: l = layer.pop() else: l = None r = [b for b in blob['nodes'] if b['id'] == external][0]['id'] # if this is empty we are in big trouble collect.append((l, r)) else: l = [b for b in blob['nodes'] if b['id'] == external][0]['id'] layer.append(l) #print(layer) return external def select(e, m): nonlocal col if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn) or pred(e, intIn): #print('select', e) col = not isLayer(blob, obj(e)) #print('s', col) ematch(blob, select_ext, obj(e)) ematch(blob, select, obj(e)) ematch(blob, select, start_link) return collect def lay_reg(blob, start): direct = [obj(t) for t in ematch(blob, (lambda e, m: sub(e, m) and (pred(e, intIn) or # XXX why isn't this getting pulled in correctly for somas? answer: missing somas in starts? surely not, ARGH a lyph internalIn a layer pred(e, endIn) or pred(e, fasIn))), start)] layers = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] lregs = [] if layers: ldir = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), d)] lregs = [obj(t) for d in ldir for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or # XXX ie seems to have no hits now pred(e, onts))), d)] regions = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] #if start == 'kblad:snl16': #print(start, direct, layers, regions) # FIXME TODO nested regions and layers lrs = reclr(blob, start) # FIXME doesn't pair regions and layers # FIXME SIGH SIGH SIGH start can be either part of a next >_< #print(lrs) assert not (lregs and regions), (lregs, regions) # not both regions = lregs if lregs else regions #out = start, layers[0] if layers else None, regions[0] if regions else None, tuple([l for l in lrs]) out = start, tuple(lrs) if out: return out def render_blob(blob): starts = [obj(e) for e in blob['edges'] if pred(e, 'apinatomy:lyphs')] nxt = 'apinatomy:next' nxts = 'apinatomy:next*' nexts = [(sub(t), obj(t)) for start in starts for t in ematch(blob, (lambda e, m: pred(e, nxt) or pred(e, nxts)), None)] #pprint(nexts) connected_pairs = sorted(set([tuple([lay_reg(blob, e) for e in p]) for p in nexts])) #pprint(connected_pairs) return connected_pairs
blob, *_ = main(blob_string=result) render_blob(blob)
neru
from pprint import pprint from pyontutils.scigraph import Cypher, Vocabulary from pyontutils.scigraph_codegen import moduleDirect from pyontutils.config import auth scigraphd = moduleDirect(auth.get('scigraph-api'), 'scigraphd') from pyontutils.config import auth from nifstd_tools.simplify import apinat_deblob, sub, pred, obj, ematch from nifstd_tools.simplify import axon, dend, bag, top, ie, ies, iot, iots, ext, fasIn, endIn, layerIn, onts ext = onts # XXX schema change def query(neupop_id): import requests url = ('https://scicrunch.org/api/1/sparc-scigraph/scigraph/dynamic/' f'demos/apinat/neru-7/{neupop_id}?limit=9999999&key={auth.get("scigraph-api-key")}') resp = requests.get(url, headers={'Accept': 'application/json'}) blob = resp.json() return blob def find_terminals(blob, type): return [es for es in blob['edges'] if pred(es, iots) and obj(es, type) and ematch(blob, (lambda e, m: sub(e, m) and pred(e, top) and obj(e, bag)), sub(es))] def find_region(blob, edge): collect = [] def select(e, m, collect=collect): if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) collect.extend([b for b in blob['nodes'] if b['id'] == region]) return region ematch(blob, select, sub(edge)) return collect def find_region_layer(blob, edge, bindex): collect = [] layers = [] layers_iots = [] donel = set() doner = set() def select_term(e, m, layers=layers): if sub(e, m): pprint(e) if (pred(e, onts) or pred(e, iots)): layer = obj(e) if layer not in donel: donel.add(layer) if pred(e, iots): layers_iots.append(bindex[layer]) else: layers.append(bindex[layer]) return layer def select(e, m, collect=collect): if sub(e, m): if pred(e, layerIn): # we're at a layer ematch(blob, select_term, sub(e)) return ematch(blob, select, obj(e)) elif (pred(e, fasIn) or pred(e, endIn)): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) if region not in doner: doner.add(region) collect.append(bindex[region]) return region ematch(blob, select, sub(edge)) if collect and not layers and not layers_iots: layers = [None] elif layers_iots and not layers: layers = layers_iots if len(collect) != len(layers): raise ValueError(f'len not matched {len(collect)} {len(layers)}') return list(zip(collect, layers)) def find_terminal_regions(blob, type): return [region for es in find_terminals(blob, type) for region in find_region(blob, es)] def find_terminal_region_layers(blob, type, bindex): return [(region, layer) for es in find_terminals(blob, type) for region, layer in find_region_layer(blob, es, bindex)] def main(blob=None, blob_string=None, neupop_id=None, remove_converge=remove): # do not call this function unless it is from an org babel block, there are free variables if blob is None and blob_string is not None: import json blob = json.loads(blob_string) neupop_id = neupop_id if neupop_id else 'ilxtr:neuron-type-keast-6' if blob is None: blob = query(neupop_id) blob, edges, somas, externals, ordering_edges = v = apinat_deblob( blob, remove_converge=remove_converge) test_call = False # change to True to test the #+call: expression if test_call: pprint(v) return v intIn = 'apinatomy:internalIn' def isLayer(blob, s): return ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), s) def reclr(blob, start_link): # recurse up the hierarchy until fasIn endIn intIn terminates #print('starting reclr') collect = [] layer = [] col = True def select_ext(e, m, collect=collect): nonlocal col nonlocal layer if sub(e, m): if pred(e, 'apinatomy:cloneOf'): # should be zapped during simplify return ematch(blob, select_ext, obj(e)) if pred(e, onts) or pred(e, iot) or pred(e, iots): #print('select_ext', e) external = obj(e) #print('se', col, layer) if col: if layer: if len(layer) > 1: l, *layer = layer else: l = layer.pop() else: l = None r = [b for b in blob['nodes'] if b['id'] == external][0]['id'] # if this is empty we are in big trouble collect.append((l, r)) else: l = [b for b in blob['nodes'] if b['id'] == external][0]['id'] layer.append(l) #print(layer) return external def select(e, m): nonlocal col if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn) or pred(e, intIn): #print('select', e) col = not isLayer(blob, obj(e)) #print('s', col) ematch(blob, select_ext, obj(e)) ematch(blob, select, obj(e)) ematch(blob, select, start_link) return collect def lay_reg(blob, start): direct = [obj(t) for t in ematch(blob, (lambda e, m: sub(e, m) and (pred(e, intIn) or # XXX why isn't this getting pulled in correctly for somas? answer: missing somas in starts? surely not, ARGH a lyph internalIn a layer pred(e, endIn) or pred(e, fasIn))), start)] layers = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] lregs = [] if layers: ldir = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), d)] lregs = [obj(t) for d in ldir for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or # XXX ie seems to have no hits now pred(e, onts))), d)] regions = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] #if start == 'kblad:snl16': #print(start, direct, layers, regions) # FIXME TODO nested regions and layers lrs = reclr(blob, start) # FIXME doesn't pair regions and layers # FIXME SIGH SIGH SIGH start can be either part of a next >_< #print(lrs) assert not (lregs and regions), (lregs, regions) # not both regions = lregs if lregs else regions #out = start, layers[0] if layers else None, regions[0] if regions else None, tuple([l for l in lrs]) out = start, tuple(lrs) if out: return out def render_blob(blob): starts = [obj(e) for e in blob['edges'] if pred(e, 'apinatomy:lyphs')] nxt = 'apinatomy:next' nxts = 'apinatomy:next*' nexts = [(sub(t), obj(t)) for start in starts for t in ematch(blob, (lambda e, m: pred(e, nxt) or pred(e, nxts)), None)] #pprint(nexts) connected_pairs = sorted(set([tuple([lay_reg(blob, e) for e in p]) for p in nexts])) #pprint(connected_pairs) return connected_pairs sgv = Vocabulary() sgd = scigraphd.Dynamic(cache=True, verbose=True, do_error=True) sgc = scigraphd.Cypher(cache=True, verbose=True) q_neru_6 = """ MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more """ def neupop_blob(neupop_id): # XXX requires a patch to Cypher and CypherBase to support arbitrary kwargs blob = sgc.execute(query=q_neru_6, limit=None, neupop_id=neupop_id, output='application/json') return blob def sigh(): blobs = [neupop_blob(f"ilxtr:neuron-type-keast-{npid}") for npid in range(1, 21)] debs = [main(blob=blob)[0] for blob in blobs] simples = [render_blob(deb) for deb in debs] #[pprint(simple) for simple in simples[:1]] def fbid(id): if id: result = sgv.findById(id) if result['labels']: return result['labels'][0] def fbids(ids): return [(id, fbid(id)) for id in ids] def rendlab(pairs): for pair in pairs: yield tuple((start, *(tuple(fbids(hp)) for hp in housings)) for start, housings in pair) #for (*tstart, sid, sasdf), (*tend, eid, easdf) in pairs: #yield ((*tstart, sid, fbid(sid), fbids(sasdf)) if sid else (*tstart, sid, fbids(sasdf)), #(*tend, eid, fbid(eid), fbids(easdf)) if eid else (*tend, eid, fbids(easdf)))
from copy import deepcopy blobs = [neupop_blob(f"ilxtr:neuron-type-keast-{npid}") for npid in range(1, 21)] debs = [main(blob=deepcopy(blob))[0] for blob in blobs] simples = [render_blob(deb) for deb in debs] sigh = [s for n, si in enumerate(simples) for s in ((f'--------- {n + 1}','---------'), *sorted(rendlab(si)))]
#sigh #pprint(blobs[0]) #pprint(debs[0]) #pprint(simples[0]) #sigh[:200] sigh
asdf
select distinct ?s ?p where { ?s ?p ilxtr:NeuronCUT . }
// MATCH path = (a)-[t]-(:Class) RETURN a //MATCH path = ()-[:apinatomy:conveyingLyph]-() RETURN path // MATCH path = ()-[:TEMPRAW:protocolInvolvesInputInstance]-() RETURN path
heatmaps
TODO get the numbers along the axis, so n populations
TODO color code by process type
TODO costimulation by location
neupop by region
from pprint import pprint from pyontutils.scigraph import Cypher, Vocabulary from pyontutils.scigraph_codegen import moduleDirect from pyontutils.config import auth scigraphd = moduleDirect(auth.get('scigraph-api'), 'scigraphd') from pyontutils.config import auth from nifstd_tools.simplify import apinat_deblob, sub, pred, obj, ematch from nifstd_tools.simplify import axon, dend, bag, top, ie, ies, iot, iots, ext, fasIn, endIn, layerIn, onts ext = onts # XXX schema change def query(neupop_id): import requests url = ('https://scicrunch.org/api/1/sparc-scigraph/scigraph/dynamic/' f'demos/apinat/neru-7/{neupop_id}?limit=9999999&key={auth.get("scigraph-api-key")}') resp = requests.get(url, headers={'Accept': 'application/json'}) blob = resp.json() return blob def find_terminals(blob, type): return [es for es in blob['edges'] if pred(es, iots) and obj(es, type) and ematch(blob, (lambda e, m: sub(e, m) and pred(e, top) and obj(e, bag)), sub(es))] def find_region(blob, edge): collect = [] def select(e, m, collect=collect): if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) collect.extend([b for b in blob['nodes'] if b['id'] == region]) return region ematch(blob, select, sub(edge)) return collect def find_region_layer(blob, edge, bindex): collect = [] layers = [] layers_iots = [] donel = set() doner = set() def select_term(e, m, layers=layers): if sub(e, m): pprint(e) if (pred(e, onts) or pred(e, iots)): layer = obj(e) if layer not in donel: donel.add(layer) if pred(e, iots): layers_iots.append(bindex[layer]) else: layers.append(bindex[layer]) return layer def select(e, m, collect=collect): if sub(e, m): if pred(e, layerIn): # we're at a layer ematch(blob, select_term, sub(e)) return ematch(blob, select, obj(e)) elif (pred(e, fasIn) or pred(e, endIn)): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) if region not in doner: doner.add(region) collect.append(bindex[region]) return region ematch(blob, select, sub(edge)) if collect and not layers and not layers_iots: layers = [None] elif layers_iots and not layers: layers = layers_iots if len(collect) != len(layers): raise ValueError(f'len not matched {len(collect)} {len(layers)}') return list(zip(collect, layers)) def find_terminal_regions(blob, type): return [region for es in find_terminals(blob, type) for region in find_region(blob, es)] def find_terminal_region_layers(blob, type, bindex): return [(region, layer) for es in find_terminals(blob, type) for region, layer in find_region_layer(blob, es, bindex)] def main(blob=None, blob_string=None, neupop_id=None, remove_converge=remove): # do not call this function unless it is from an org babel block, there are free variables if blob is None and blob_string is not None: import json blob = json.loads(blob_string) neupop_id = neupop_id if neupop_id else 'ilxtr:neuron-type-keast-6' if blob is None: blob = query(neupop_id) blob, edges, somas, externals, ordering_edges = v = apinat_deblob( blob, remove_converge=remove_converge) test_call = False # change to True to test the #+call: expression if test_call: pprint(v) return v intIn = 'apinatomy:internalIn' def isLayer(blob, s): return ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), s) def reclr(blob, start_link): # recurse up the hierarchy until fasIn endIn intIn terminates #print('starting reclr') collect = [] layer = [] col = True def select_ext(e, m, collect=collect): nonlocal col nonlocal layer if sub(e, m): if pred(e, 'apinatomy:cloneOf'): # should be zapped during simplify return ematch(blob, select_ext, obj(e)) if pred(e, onts) or pred(e, iot) or pred(e, iots): #print('select_ext', e) external = obj(e) #print('se', col, layer) if col: if layer: if len(layer) > 1: l, *layer = layer else: l = layer.pop() else: l = None r = [b for b in blob['nodes'] if b['id'] == external][0]['id'] # if this is empty we are in big trouble collect.append((l, r)) else: l = [b for b in blob['nodes'] if b['id'] == external][0]['id'] layer.append(l) #print(layer) return external def select(e, m): nonlocal col if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn) or pred(e, intIn): #print('select', e) col = not isLayer(blob, obj(e)) #print('s', col) ematch(blob, select_ext, obj(e)) ematch(blob, select, obj(e)) ematch(blob, select, start_link) return collect def lay_reg(blob, start): direct = [obj(t) for t in ematch(blob, (lambda e, m: sub(e, m) and (pred(e, intIn) or # XXX why isn't this getting pulled in correctly for somas? answer: missing somas in starts? surely not, ARGH a lyph internalIn a layer pred(e, endIn) or pred(e, fasIn))), start)] layers = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] lregs = [] if layers: ldir = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), d)] lregs = [obj(t) for d in ldir for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or # XXX ie seems to have no hits now pred(e, onts))), d)] regions = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] #if start == 'kblad:snl16': #print(start, direct, layers, regions) # FIXME TODO nested regions and layers lrs = reclr(blob, start) # FIXME doesn't pair regions and layers # FIXME SIGH SIGH SIGH start can be either part of a next >_< #print(lrs) assert not (lregs and regions), (lregs, regions) # not both regions = lregs if lregs else regions #out = start, layers[0] if layers else None, regions[0] if regions else None, tuple([l for l in lrs]) out = start, tuple(lrs) if out: return out def render_blob(blob): starts = [obj(e) for e in blob['edges'] if pred(e, 'apinatomy:lyphs')] nxt = 'apinatomy:next' nxts = 'apinatomy:next*' nexts = [(sub(t), obj(t)) for start in starts for t in ematch(blob, (lambda e, m: pred(e, nxt) or pred(e, nxts)), None)] #pprint(nexts) connected_pairs = sorted(set([tuple([lay_reg(blob, e) for e in p]) for p in nexts])) #pprint(connected_pairs) return connected_pairs sgv = Vocabulary() sgd = scigraphd.Dynamic(cache=True, verbose=True, do_error=True) sgc = scigraphd.Cypher(cache=True, verbose=True) q_neru_6 = """ MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more """ def neupop_blob(neupop_id): # XXX requires a patch to Cypher and CypherBase to support arbitrary kwargs blob = sgc.execute(query=q_neru_6, limit=None, neupop_id=neupop_id, output='application/json') return blob def sigh(): blobs = [neupop_blob(f"ilxtr:neuron-type-keast-{npid}") for npid in range(1, 21)] debs = [main(blob=blob)[0] for blob in blobs] simples = [render_blob(deb) for deb in debs] #[pprint(simple) for simple in simples[:1]] def fbid(id): if id: result = sgv.findById(id) if result['labels']: return result['labels'][0] def fbids(ids): return [(id, fbid(id)) for id in ids] def rendlab(pairs): for pair in pairs: yield tuple((start, *(tuple(fbids(hp)) for hp in housings)) for start, housings in pair) #for (*tstart, sid, sasdf), (*tend, eid, easdf) in pairs: #yield ((*tstart, sid, fbid(sid), fbids(sasdf)) if sid else (*tstart, sid, fbids(sasdf)), #(*tend, eid, fbid(eid), fbids(easdf)) if eid else (*tend, eid, fbids(easdf))) from collections import defaultdict q_cnap = """ OPTIONAL MATCH (start:Ontology) <-[:isDefinedBy]-(graph:NamedIndividual) -[:type]->({iri: "https://apinatomy.org/uris/elements/Graph"}) , (start) <-[:isDefinedBy]-(external:Class) -[:subClassOf*]->(:Class {iri: "http://uri.interlex.org/tgbugs/uris/readable/NeuronEBM"}) return external """ def get_label(region): return id_label[region] def get_labels(regions): return [get_label(region) for region in regions] d = sgc.execute(query=q_cnap, limit=99999, output='application/json') ids = [n['id'] for n in d['nodes']] blobs = [neupop_blob(id) for id in ids] id_label = {n['id']:n['lbl'] if 'lbl' in n and n['lbl'] else n['id'] for blob in blobs for n in blob['nodes']}
_ext_all = sorted(set([obj(e) for b in blobs for e in b['edges'] if pred(e, 'apinatomy:ontologyTerms')])) ext_pop = {i:set([obj(e) for e in blob['edges'] if pred(e, 'apinatomy:ontologyTerms')]) for i, blob in zip(ids, blobs)} # TODO popuation, region, process type, terminal pop_by_reg_ads_trm = [] pop_by_reg = defaultdict(list) for i, regs in ext_pop.items(): for reg in regs: pop_by_reg[reg].append(i) def key_allc(region): count = 0 for i, id in enumerate(ids): if region in ext_pop[id]: count += 1 return count _ext_allc = sorted(_ext_all, key=key_allc) def key_pop(pop): return -len(ext_pop[pop]) ids_ord = sorted(ids, key=key_pop) def key_all(region): first = None count = 0 regs = [] iths = [] for i, id in enumerate(ids_ord): if region in ext_pop[id]: regs.append(region) iths.append(i) #count += 1 # wow =+ 1 no error wat #if first is None: #first = i return iths[0], *[-i for i in iths[1:]] ext_all = sorted(_ext_all, key=key_all) n_region = len(ext_all) n_pop = len(ext_pop) header = [['neupop', *ext_all]] # TODO -> label xl = get_labels(header[0][1:]) rows = header + [[id, *[region in ext_pop[id] for region in ext_all]] for id in ids_ord] def jac(a, b): anb, aub = zip(*[(ar and br, ar or br) for ar, br in zip(a, b)]) sanb, saub = sum(anb) , sum(aub) if not sanb and not saub: return sanb # 0 elif not sanb: return saub elif not saub: return sanb else: return sanb / saub def sumjac(rows, norm=False): # actually want distance from .5 ? mat = jac_mat(rows, switch=True) #pprint(mat) return [(sum(r[:-1]) * sum(rows[r[-1] + 1][1:]) if norm else 1, r[-1]) for i, r in enumerate(mat)] def sumjac_norm(rows): return sumjac(rows, norm=True) def jac_mat(rows, switch=False, reverse=False): asdf = [] for i, (_, *rowa) in enumerate(rows[1:]): jacr = [] for j, (_, *rowb) in enumerate(rows[1:]): jci = jac(rowa, rowb) if switch: jacr.append(jci) else: jacr.append((jci, j)) if switch: jacr.append(i) asdf.append(jacr) else: minimized = [i for j, i in sorted(jacr)][1:] # 1: to skip self minimized.append(i) asdf.append(minimized) return asdf def jmc(rows): return jac_mat(rows, switch=True) def jmcr(rows): # XXX broken return jac_mat(rows, switch=True, reverse=True) def jac_sigh(rows): sigh = jmc(rows) return [(np.std(s[:-1]), np.mean(s[:-1]), s[-1]) for s in sigh] def jac_sigh(rows): sigh = jmc(rows) #return [(np.std(s[:-1]), np.mean(s[:-1]), s[-1]) for s in sigh] return [(*[((x - .5) ** 2) ** .5 for x in s[:-1]], s[-1]) for s in sigh] def resort(rows, sortf, reverse=False): asdf_ord = sorted(sortf(rows), reverse=not reverse) # don't think too hard about it ind_rank = {j:i for i, (*_, j) in enumerate(asdf_ord)} def srt(row): ind = rows.index(row) if ind == 0: return 0 else: return ind_rank[ind - 1] return sorted(rows, key=srt) def sumthm(rows): return [[-sum(row[1:]), i] for i, row in enumerate(rows[1:])] def sumth(rows): return [[sum(row[1:]), i] for i, row in enumerate(rows[1:])] def blank(rows): return [[*row[1:], i] for i, row in enumerate(rows[1:])] def sumoth(rows): crank = [sum(col) for col in list(zip(*rows[1:]))[1:]] return [[* #[crank[j] if c and crank[j] == max([crank[x] for x, v in enumerate(row[1:]) if v]) else 0 [crank[j] if c else 0 for j, c in enumerate(row[1:])], i] for i, row in enumerate(rows[1:])] def sumothm(rows): crank = [sum(col) for col in list(zip(*rows[1:]))[1:]] return [[* #[crank[j] if c and crank[j] == max([crank[x] for x, v in enumerate(row[1:]) if v]) else 0 [-crank[j] if c else 0 for j, c in enumerate(row[1:])], i] for i, row in enumerate(rows[1:])] def maxp(rows): crank = [sum(col) for col in list(zip(*rows[1:]))[1:]] return [[ sorted([crank[j] if c else 0 for j, c in enumerate(row[1:])])[0], *[-_ for _ in sorted([crank[j] if c else 0 for j, c in enumerate(row[1:])])[1:]] , i] for i, row in enumerate(rows[1:])] def jacb(rows): a = [row[1:] for row in rows[1:]] aT = list(zip(*a)) # FIXME symmetry rd = [[jac(r1, r2) for r2 in a] for r1 in a] cd = [[jac(c1, c2) for c2 in aT] for c1 in aT] #pprint(rd) #pprint(cd) # output is a 4d matrix, from rc -> to rc dist = np.zeros((len(rd), len(cd), len(rd), len(cd))) for i, row_dists in enumerate(rd): for k, row_dist in enumerate(row_dists): for j, col_dists in enumerate(cd): for l, col_dist in enumerate(col_dists): dist[i, j, k, l] = (row_dist ** 2 + col_dist ** 2) ** .5 #pprint(dist) return dist rows = resort(rows, sumth) rows = list(zip(*resort(list(zip(*rows)), blank, reverse=True))) rows = resort(rows, jmc) if False: import seaborn seaborn.set(rc={'figure.figsize':(50, 50)}) #seaborn.set(rc={'figure.figsize':(5, 5)}) axes = seaborn.heatmap( [r[1:] for r in rows[1:]], xticklabels=xl, yticklabels=[r[0] for r in rows[1:]], cbar=False, square=True, ) # axes.get_figure().savefig('heatmap-pop-reg-test.svg')
import csv csv_path = 'heatmap-pop-reg.csv' with open(csv_path, 'wt') as f: csv.writer(f).writerows(rows)
- generate npo representation of apinatomy population location phenotypes
undifferentiated NPO representation that matches the heatmap above
run the blocks in the section above first
#len(blobs) #pprint(id_label) #pprint(blobs[0]) sorted([[a, *sorted(b)] for a, b in ext_pop.items()])
from neurondm import Neuron, Phenotype, EntailedPhenotype, Config from pyontutils.namespaces import ilxtr, owl, skos, rdfs config = Config('apinatomy-locations') neurons = [Neuron(Phenotype(id), *(EntailedPhenotype(loc, ilxtr.hasLocationPhenotype) for loc in sorted(locs)), id_=id) for id, locs in ext_pop.items()] config.write() to_mod = [(s, skos.altLabel, o) for s, p, o in config._written_graph if p == rdfs.label] to_remove = [t for t in config._written_graph if t[1] in (owl.equivalentClass, ilxtr.genLabel, ilxtr.localLabel, ilxtr.simpleLabel, ilxtr.simpleLocalLabel, rdfs.label, skos.prefLabel)] [config._written_graph.remove(t) for t in to_remove] [config._written_graph.add(t) for t in to_mod] config._written_graph.write() config.write_python()
from pprint import pprint from pyontutils.scigraph import Cypher, Vocabulary from pyontutils.scigraph_codegen import moduleDirect from pyontutils.config import auth scigraphd = moduleDirect(auth.get('scigraph-api'), 'scigraphd') from pyontutils.config import auth from nifstd_tools.simplify import apinat_deblob, sub, pred, obj, ematch from nifstd_tools.simplify import axon, dend, bag, top, ie, ies, iot, iots, ext, fasIn, endIn, layerIn, onts ext = onts # XXX schema change def query(neupop_id): import requests url = ('https://scicrunch.org/api/1/sparc-scigraph/scigraph/dynamic/' f'demos/apinat/neru-7/{neupop_id}?limit=9999999&key={auth.get("scigraph-api-key")}') resp = requests.get(url, headers={'Accept': 'application/json'}) blob = resp.json() return blob def find_terminals(blob, type): return [es for es in blob['edges'] if pred(es, iots) and obj(es, type) and ematch(blob, (lambda e, m: sub(e, m) and pred(e, top) and obj(e, bag)), sub(es))] def find_region(blob, edge): collect = [] def select(e, m, collect=collect): if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) collect.extend([b for b in blob['nodes'] if b['id'] == region]) return region ematch(blob, select, sub(edge)) return collect def find_region_layer(blob, edge, bindex): collect = [] layers = [] layers_iots = [] donel = set() doner = set() def select_term(e, m, layers=layers): if sub(e, m): pprint(e) if (pred(e, onts) or pred(e, iots)): layer = obj(e) if layer not in donel: donel.add(layer) if pred(e, iots): layers_iots.append(bindex[layer]) else: layers.append(bindex[layer]) return layer def select(e, m, collect=collect): if sub(e, m): if pred(e, layerIn): # we're at a layer ematch(blob, select_term, sub(e)) return ematch(blob, select, obj(e)) elif (pred(e, fasIn) or pred(e, endIn)): return ematch(blob, select, obj(e)) elif pred(e, onts): region = obj(e) if region not in doner: doner.add(region) collect.append(bindex[region]) return region ematch(blob, select, sub(edge)) if collect and not layers and not layers_iots: layers = [None] elif layers_iots and not layers: layers = layers_iots if len(collect) != len(layers): raise ValueError(f'len not matched {len(collect)} {len(layers)}') return list(zip(collect, layers)) def find_terminal_regions(blob, type): return [region for es in find_terminals(blob, type) for region in find_region(blob, es)] def find_terminal_region_layers(blob, type, bindex): return [(region, layer) for es in find_terminals(blob, type) for region, layer in find_region_layer(blob, es, bindex)] def main(blob=None, blob_string=None, neupop_id=None, remove_converge=remove): # do not call this function unless it is from an org babel block, there are free variables if blob is None and blob_string is not None: import json blob = json.loads(blob_string) neupop_id = neupop_id if neupop_id else 'ilxtr:neuron-type-keast-6' if blob is None: blob = query(neupop_id) blob, edges, somas, externals, ordering_edges = v = apinat_deblob( blob, remove_converge=remove_converge) test_call = False # change to True to test the #+call: expression if test_call: pprint(v) return v intIn = 'apinatomy:internalIn' def isLayer(blob, s): return ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), s) def reclr(blob, start_link): # recurse up the hierarchy until fasIn endIn intIn terminates #print('starting reclr') collect = [] layer = [] col = True def select_ext(e, m, collect=collect): nonlocal col nonlocal layer if sub(e, m): if pred(e, 'apinatomy:cloneOf'): # should be zapped during simplify return ematch(blob, select_ext, obj(e)) if pred(e, onts) or pred(e, iot) or pred(e, iots): #print('select_ext', e) external = obj(e) #print('se', col, layer) if col: if layer: if len(layer) > 1: l, *layer = layer else: l = layer.pop() else: l = None r = [b for b in blob['nodes'] if b['id'] == external][0]['id'] # if this is empty we are in big trouble collect.append((l, r)) else: l = [b for b in blob['nodes'] if b['id'] == external][0]['id'] layer.append(l) #print(layer) return external def select(e, m): nonlocal col if sub(e, m): #print(e) if pred(e, layerIn) or pred(e, fasIn) or pred(e, endIn) or pred(e, intIn): #print('select', e) col = not isLayer(blob, obj(e)) #print('s', col) ematch(blob, select_ext, obj(e)) ematch(blob, select, obj(e)) ematch(blob, select, start_link) return collect def lay_reg(blob, start): direct = [obj(t) for t in ematch(blob, (lambda e, m: sub(e, m) and (pred(e, intIn) or # XXX why isn't this getting pulled in correctly for somas? answer: missing somas in starts? surely not, ARGH a lyph internalIn a layer pred(e, endIn) or pred(e, fasIn))), start)] layers = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] lregs = [] if layers: ldir = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and pred(e, layerIn)), d)] lregs = [obj(t) for d in ldir for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or # XXX ie seems to have no hits now pred(e, onts))), d)] regions = [obj(t) for d in direct for t in ematch(blob, (lambda e, m: sub(e, m) and not isLayer(blob, m) and (pred(e, iot) or pred(e, iots) or pred(e, onts))), d)] #if start == 'kblad:snl16': #print(start, direct, layers, regions) # FIXME TODO nested regions and layers lrs = reclr(blob, start) # FIXME doesn't pair regions and layers # FIXME SIGH SIGH SIGH start can be either part of a next >_< #print(lrs) assert not (lregs and regions), (lregs, regions) # not both regions = lregs if lregs else regions #out = start, layers[0] if layers else None, regions[0] if regions else None, tuple([l for l in lrs]) out = start, tuple(lrs) if out: return out def render_blob(blob): starts = [obj(e) for e in blob['edges'] if pred(e, 'apinatomy:lyphs')] nxt = 'apinatomy:next' nxts = 'apinatomy:next*' nexts = [(sub(t), obj(t)) for start in starts for t in ematch(blob, (lambda e, m: pred(e, nxt) or pred(e, nxts)), None)] #pprint(nexts) connected_pairs = sorted(set([tuple([lay_reg(blob, e) for e in p]) for p in nexts])) #pprint(connected_pairs) return connected_pairs sgv = Vocabulary() sgd = scigraphd.Dynamic(cache=True, verbose=True, do_error=True) sgc = scigraphd.Cypher(cache=True, verbose=True) q_neru_6 = """ MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more """ def neupop_blob(neupop_id): # XXX requires a patch to Cypher and CypherBase to support arbitrary kwargs blob = sgc.execute(query=q_neru_6, limit=None, neupop_id=neupop_id, output='application/json') return blob def sigh(): blobs = [neupop_blob(f"ilxtr:neuron-type-keast-{npid}") for npid in range(1, 21)] debs = [main(blob=blob)[0] for blob in blobs] simples = [render_blob(deb) for deb in debs] #[pprint(simple) for simple in simples[:1]] def fbid(id): if id: result = sgv.findById(id) if result['labels']: return result['labels'][0] def fbids(ids): return [(id, fbid(id)) for id in ids] def rendlab(pairs): for pair in pairs: yield tuple((start, *(tuple(fbids(hp)) for hp in housings)) for start, housings in pair) #for (*tstart, sid, sasdf), (*tend, eid, easdf) in pairs: #yield ((*tstart, sid, fbid(sid), fbids(sasdf)) if sid else (*tstart, sid, fbids(sasdf)), #(*tend, eid, fbid(eid), fbids(easdf)) if eid else (*tend, eid, fbids(easdf))) from collections import defaultdict q_cnap = """ OPTIONAL MATCH (start:Ontology) <-[:isDefinedBy]-(graph:NamedIndividual) -[:type]->({iri: "https://apinatomy.org/uris/elements/Graph"}) , (start) <-[:isDefinedBy]-(external:Class) -[:subClassOf*]->(:Class {iri: "http://uri.interlex.org/tgbugs/uris/readable/NeuronEBM"}) return external """ def get_label(region): return id_label[region] def get_labels(regions): return [get_label(region) for region in regions] d = sgc.execute(query=q_cnap, limit=99999, output='application/json') ids = [n['id'] for n in d['nodes']] blobs = [neupop_blob(id) for id in ids] id_label = {n['id']:n['lbl'] if 'lbl' in n and n['lbl'] else n['id'] for blob in blobs for n in blob['nodes']} _ext_all = sorted(set([obj(e) for b in blobs for e in b['edges'] if pred(e, 'apinatomy:ontologyTerms')])) ext_pop = {i:set([obj(e) for e in blob['edges'] if pred(e, 'apinatomy:ontologyTerms')]) for i, blob in zip(ids, blobs)} # TODO popuation, region, process type, terminal pop_by_reg_ads_trm = [] pop_by_reg = defaultdict(list) for i, regs in ext_pop.items(): for reg in regs: pop_by_reg[reg].append(i) def key_allc(region): count = 0 for i, id in enumerate(ids): if region in ext_pop[id]: count += 1 return count _ext_allc = sorted(_ext_all, key=key_allc) def key_pop(pop): return -len(ext_pop[pop]) ids_ord = sorted(ids, key=key_pop) def key_all(region): first = None count = 0 regs = [] iths = [] for i, id in enumerate(ids_ord): if region in ext_pop[id]: regs.append(region) iths.append(i) #count += 1 # wow =+ 1 no error wat #if first is None: #first = i return iths[0], *[-i for i in iths[1:]] ext_all = sorted(_ext_all, key=key_all) n_region = len(ext_all) n_pop = len(ext_pop) header = [['neupop', *ext_all]] # TODO -> label xl = get_labels(header[0][1:]) rows = header + [[id, *[region in ext_pop[id] for region in ext_all]] for id in ids_ord] def jac(a, b): anb, aub = zip(*[(ar and br, ar or br) for ar, br in zip(a, b)]) sanb, saub = sum(anb) , sum(aub) if not sanb and not saub: return sanb # 0 elif not sanb: return saub elif not saub: return sanb else: return sanb / saub def sumjac(rows, norm=False): # actually want distance from .5 ? mat = jac_mat(rows, switch=True) #pprint(mat) return [(sum(r[:-1]) * sum(rows[r[-1] + 1][1:]) if norm else 1, r[-1]) for i, r in enumerate(mat)] def sumjac_norm(rows): return sumjac(rows, norm=True) def jac_mat(rows, switch=False, reverse=False): asdf = [] for i, (_, *rowa) in enumerate(rows[1:]): jacr = [] for j, (_, *rowb) in enumerate(rows[1:]): jci = jac(rowa, rowb) if switch: jacr.append(jci) else: jacr.append((jci, j)) if switch: jacr.append(i) asdf.append(jacr) else: minimized = [i for j, i in sorted(jacr)][1:] # 1: to skip self minimized.append(i) asdf.append(minimized) return asdf def jmc(rows): return jac_mat(rows, switch=True) def jmcr(rows): # XXX broken return jac_mat(rows, switch=True, reverse=True) def jac_sigh(rows): sigh = jmc(rows) return [(np.std(s[:-1]), np.mean(s[:-1]), s[-1]) for s in sigh] def jac_sigh(rows): sigh = jmc(rows) #return [(np.std(s[:-1]), np.mean(s[:-1]), s[-1]) for s in sigh] return [(*[((x - .5) ** 2) ** .5 for x in s[:-1]], s[-1]) for s in sigh] def resort(rows, sortf, reverse=False): asdf_ord = sorted(sortf(rows), reverse=not reverse) # don't think too hard about it ind_rank = {j:i for i, (*_, j) in enumerate(asdf_ord)} def srt(row): ind = rows.index(row) if ind == 0: return 0 else: return ind_rank[ind - 1] return sorted(rows, key=srt) def sumthm(rows): return [[-sum(row[1:]), i] for i, row in enumerate(rows[1:])] def sumth(rows): return [[sum(row[1:]), i] for i, row in enumerate(rows[1:])] def blank(rows): return [[*row[1:], i] for i, row in enumerate(rows[1:])] def sumoth(rows): crank = [sum(col) for col in list(zip(*rows[1:]))[1:]] return [[* #[crank[j] if c and crank[j] == max([crank[x] for x, v in enumerate(row[1:]) if v]) else 0 [crank[j] if c else 0 for j, c in enumerate(row[1:])], i] for i, row in enumerate(rows[1:])] def sumothm(rows): crank = [sum(col) for col in list(zip(*rows[1:]))[1:]] return [[* #[crank[j] if c and crank[j] == max([crank[x] for x, v in enumerate(row[1:]) if v]) else 0 [-crank[j] if c else 0 for j, c in enumerate(row[1:])], i] for i, row in enumerate(rows[1:])] def maxp(rows): crank = [sum(col) for col in list(zip(*rows[1:]))[1:]] return [[ sorted([crank[j] if c else 0 for j, c in enumerate(row[1:])])[0], *[-_ for _ in sorted([crank[j] if c else 0 for j, c in enumerate(row[1:])])[1:]] , i] for i, row in enumerate(rows[1:])] def jacb(rows): a = [row[1:] for row in rows[1:]] aT = list(zip(*a)) # FIXME symmetry rd = [[jac(r1, r2) for r2 in a] for r1 in a] cd = [[jac(c1, c2) for c2 in aT] for c1 in aT] #pprint(rd) #pprint(cd) # output is a 4d matrix, from rc -> to rc dist = np.zeros((len(rd), len(cd), len(rd), len(cd))) for i, row_dists in enumerate(rd): for k, row_dist in enumerate(row_dists): for j, col_dists in enumerate(cd): for l, col_dist in enumerate(col_dists): dist[i, j, k, l] = (row_dist ** 2 + col_dist ** 2) ** .5 #pprint(dist) return dist rows = resort(rows, sumth) rows = list(zip(*resort(list(zip(*rows)), blank, reverse=True))) rows = resort(rows, jmc) if False: import seaborn seaborn.set(rc={'figure.figsize':(50, 50)}) #seaborn.set(rc={'figure.figsize':(5, 5)}) axes = seaborn.heatmap( [r[1:] for r in rows[1:]], xticklabels=xl, yticklabels=[r[0] for r in rows[1:]], cbar=False, square=True, ) # axes.get_figure().savefig('heatmap-pop-reg-test.svg') from neurondm import Neuron, Phenotype, EntailedPhenotype, Config from pyontutils.namespaces import ilxtr, owl, skos, rdfs config = Config('apinatomy-locations') neurons = [Neuron(Phenotype(id), *(EntailedPhenotype(loc, ilxtr.hasLocationPhenotype) for loc in sorted(locs)), id_=id) for id, locs in ext_pop.items()] config.write() to_mod = [(s, skos.altLabel, o) for s, p, o in config._written_graph if p == rdfs.label] to_remove = [t for t in config._written_graph if t[1] in (owl.equivalentClass, ilxtr.genLabel, ilxtr.localLabel, ilxtr.simpleLabel, ilxtr.simpleLocalLabel, rdfs.label, skos.prefLabel)] [config._written_graph.remove(t) for t in to_remove] [config._written_graph.add(t) for t in to_mod] config._written_graph.write() config.write_python()
region by region
SciGraph cypher queries
These can be tested against the execute endpoint as well (if the SciGraph server is running the patch to align the behavior).
neru
neru-7
Switch over to apinat:inheritedOntologyTerms
.
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedOntologyTerms]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedOntologyTerms]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedOntologyTerms*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedOntologyTerms]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more
neru-6
The only difference between 5 and 6 is that 6 also traverses apinat:nextChainStartLevels
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more
neru-5
- query
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link)
-[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more
neru-4
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf]->()-[:apinatomy:inheritedOntologyTerms]->() WITH neugrp, link, lyph, a, c, d, layer_ext // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedOntologyTerms*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext
neru-3
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK // publications WITH neugrp, a OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it WITH neugrp, a, path MATCH (neugrp) -[b:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, b, c, d, path // MATCH vs , not all things that match as lyphs have externals MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) // use apinatomy:next to extract ordering information WITH neugrp, link, a, b, c, d, e, path MATCH p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() WITH neugrp, link, a, b, c, d, e, path, p2, cl MATCH (cl) -[x:apinatomy:inheritedOntologyTerms*0..1]->() WITH neugrp, link, a, b, c, d, e, path, p2, x MATCH (link) -[f:apinatomy:next*0..]->() //-[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() // FIXME these should be collapsing into a single relationship -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) RETURN a, b, c, d, e, f, g,h,i, path, p2, x UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) // this variant shows the dead end lyphs that correspond to the fasciculatesIn links above //-[c:apinatomy:internalIn*0..1]->() //-[d:apinatomy:ontologyTerms*0..1]->(region) RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, null as p2, null as x
neru-2
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK // publications WITH neugrp, a OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it WITH neugrp, a, path MATCH (neugrp) -[b:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, b, c, d, path MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) // use apinatomy:next to extract ordering information WITH neugrp, link, a, b, c, d, e, path MATCH (link) -[f:apinatomy:next*0..]->() //-[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() // FIXME these should be collapsing into a single relationship -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) RETURN a, b, c, d, e, f, g,h,i, path UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->(e) // e is a hack to get columns to match -[d:apinatomy:ontologyTerms*0..1]->(region) // this variant shows the dead end lyphs that correspond to the fasciculatesIn links above //-[c:apinatomy:internalIn*0..1]->(e) //-[d:apinatomy:ontologyTerms*0..1]->(region) RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path
MATCH path = (neupop:Class{iri: $neupop_id}) -[:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->() -[:apinatomy:next*0..]->() // -[:apinatomy:nextChainStartLevels*0..]-() //-[:apinatomy:prevChainEndLevels*0..]-() -[:apinatomy:levelIn*0..]->() RETURN path
neru-1
MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK // publications WITH neugrp, a OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it WITH neugrp, a, path MATCH (neugrp) -[b:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH lyph, a, b, c, d, path MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) RETURN a, b, c, d, e, path UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->(e) // e is a hack to get columns to match -[d:apinatomy:ontologyTerms*0..1]->(region) // this variant shows the dead end lyphs that correspond to the fasciculatesIn links above //-[c:apinatomy:internalIn*0..1]->(e) //-[d:apinatomy:ontologyTerms*0..1]->(region) return a, b, c, d, null AS e, null AS path
all populations
OPTIONAL MATCH (start:Ontology) <-[:isDefinedBy]-(graph:NamedIndividual) -[:type]->({iri: "https://apinatomy.org/uris/elements/Graph"}) , (start) <-[:isDefinedBy]-(external:Class) -[:subClassOf*]->(:Class {iri: "http://uri.interlex.org/tgbugs/uris/readable/NeuronEBM"}) return external
neru populations
List all neuron populations that appear in some ApiNATOMY model.
MATCH (start:Ontology) <-[:isDefinedBy]-(external:Class) -[:subClassOf*]->(:Class {iri: "http://uri.interlex.org/tgbugs/uris/readable/NeuronEBM"}) // FIXME , (start:Ontology) <-[:apinat:hasGraph]-(graph:Class {iri: ""}) RETURN external
neru model populations
Given an ApiNATOMY model id return the identifiers for the neuron populations that are present in the model.
MATCH (start:Ontology {iri: $model_id}) <-[:isDefinedBy]-(external:Class) -[:subClassOf*]->(:Class {iri: "http://uri.interlex.org/tgbugs/uris/readable/NeuronEBM"}) // FIXME RETURN external
neru model populations and references
Given an ApiNATOMY model id return the identifiers for the neuron populations that are present in the model and the identifiers for references that provide supporting evidence. Publications and populations can be distingished by checking whether their meta type field is NamedIndividual or Class.
MATCH (start:Ontology {iri: $model_id}) <-[:isDefinedBy]-(external:Class) -[:subClassOf*]->(:Class {iri: "http://uri.interlex.org/tgbugs/uris/readable/NeuronEBM"}) // FIXME , (external) -[e:type]->() RETURN e UNION OPTIONAL MATCH (start:Ontology {iri: $model_id}) <-[:isDefinedBy]-(graph:NamedIndividual) -[:type]->({iri: "https://apinatomy.org/uris/elements/Graph"}) // elements don't have a superclass right now , (graph) -[:apinatomy:references]->(pub) -[e:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) RETURN e
TODO neru regions projected to
TODO neru regions dendrited to
TODO neru regions with processes from
region contains some process part of some neuron population
MATCH (region) -[:apinatomy:annotates]->(lyph) <-[:apinatomy:lyphs]- (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) RETURN region
neru projects to
neru neurites to
MATCH (neupop:Class{iri: $neupop_id}) -[:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:lyphs]->(end_lyph) -[t:apinatomy:topology]->(top) WHERE top.iri IN ["https://apinatomy.org/uris/readable/BAG", "https://apinatomy.org/uris/readable/BAG2"] WITH neugrp, end_lyph, t MATCH (type) // FIXME we need more information in the models <-[x:apinatomy:inheritedOntologyTerms*0..1]-(end_lyph) -[a:apinatomy:conveys]->(link) -[b:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[c:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, lyph, a,b,c,t,x MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) RETURN e, a,b,c,t,x
neru population projects to
neru populations projecting to
Given an anatomical region return a list of neuron types that project to that region.
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) WITH e, neupop, neugrp, link MATCH (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:inheritedOntologyTerms]->(:Class {iri: $type_id}) WITH e, neupop, neugrp, cl MATCH (cl) -[:apinatomy:topology]-(top) WHERE top.iri IN ["https://apinatomy.org/uris/readable/BAG", "https://apinatomy.org/uris/readable/BAG2"] RETURN e, neupop, neugrp
neru populations with axons in
Given an anatomical region return a list of neuron types with axons that are located in that region.
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) WITH e, neupop, neugrp, link MATCH (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:inheritedOntologyTerms]->(:Class {iri: $type_id}) RETURN e, neupop, neugrp
neru populations dendriting to
Given an anatomical region return a list of neuron types that have dendrite terminals in that region.
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) WITH e, neupop, neugrp, link MATCH (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:inheritedOntologyTerms]->(:Class {iri: $type_id}) WITH e, neupop, neugrp, cl MATCH (cl) -[:apinatomy:topology]-(top) WHERE top.iri IN ["https://apinatomy.org/uris/readable/BAG", "https://apinatomy.org/uris/readable/BAG2"] RETURN e, neupop, neugrp
neru populations with dendrites in
Given an anatomical region return a list of neuron types with dendrites that are located in that region.
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) WITH e, neupop, neugrp, link MATCH (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:inheritedOntologyTerms]->(:Class {iri: $type_id}) RETURN e, neupop, neugrp
TODO neru populations with neurites in
neru populations with processes in
Given an anatomical region return a list of neuron types with processes that are located in that region.
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp)
// somas MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:lyphs]->(lyph) -[:apinatomy:internalIn]->() -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp)
TODO Need to expand region_id
using the Uberon partonomy to answer more generic queries.
// dendrites and axons MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) RETURN e, neupop, neugrp UNION // somas MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:lyphs]->(lyph) -[:apinatomy:internalIn]->() -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) RETURN e, neupop, neugrp
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) RETURN neupop UNION // somas MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:lyphs]->(lyph) -[:apinatomy:internalIn]->() -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) RETURN neupop
Helper blocks for more specialized queries.
Filter by process type_id
, where type_id
could be the ontology
identifier for axon or dendrite. The type_id
has to match the
conventions used in ApiNATOMY models.
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) WITH e, neupop, neugrp, link MATCH (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:inheritedOntologyTerms]->(:Class {iri: $type_id})
Filter processes based on their topology. For example, this is used to select processes with bag topology that correspond to axon and dendrite terminals.
MATCH (neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) -[:apinatomy:links]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) -[:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:ontologyTerms*0..1]->(region:Class{iri: $region_id}) WITH neugrp OPTIONAL MATCH (neupop:Class) -[e:apinatomy:annotates*0..1]->(neugrp) WITH e, neupop, neugrp, link MATCH (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:inheritedOntologyTerms]->(:Class {iri: $type_id}) WITH e, neupop, neugrp, cl MATCH (cl) -[:apinatomy:topology]-(top) WHERE top.iri IN ["https://apinatomy.org/uris/readable/BAG", "https://apinatomy.org/uris/readable/BAG2"] RETURN e, neupop, neugrp
TODO neru populations by phenotype
TODO neru phenotype by population
existing
sparc
- organParts
Get the parts list for an organ including nerves and blood vessels
// depth of 6 captures everything, 5 is too shallow, 40 is WAY too deep MATCH path = (start:Class{iri: "${id}"}) <-[:subClassOf|ilxtr:includedForSPARCUnder|fma:regional_part_of|fma:constitutional_part_of|fma:related_part_of*0..6]-(part) <-[:fma:arterial_supply_of|fma:nerve_supply_of|fma:venous_drainage_of|fma:continuous_with*0..1]-(sup) <-[:subClassOf|fma:constitutional_part_of|fma:branch|fma:tributary|fma:branch_of*0..1]-(a_bit_more) RETURN path UNION // for this query UNION seems to be MUCH faster than using WITH MATCH path = (start:Class{iri: "${id}"}) // this one does not need to be inverted ? except for the INCOMING flag <-[:fma:arterial_supply_of|fma:venous_drainage_of]-(vessel) <-[:fma:branch|fma:tributary]-(more_vessel) <-[:fma:branch|fma:tributary|fma:regional_part]-(even_more_vessel) RETURN path
- parcellationArtifacts
MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path
- parcellationArtifacts/{species-id}
MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species:Class{iri: "${species-id}"}) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path
- artifactRoots/{artifact-id}
MATCH path = (root) -[:ilxtr:isDefinedBy]->(a)<-[:subClassOf*0..2] -(artifact:Class{iri: "${artifact-id}"}) RETURN path
- artifactLabels/{artifact-id}
MATCH path = (label) -[:subClassOf]->(root) -[:ilxtr:isDefinedBy]->(a)<-[:subClassOf*0..2] -(artifact:Class{iri: "${artifact-id}"}) WHERE label.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path
- rootLabels/{root-id}
MATCH (label)-[:subClassOf]->(root:Class{iri: "${root-id}"}) , path = (label)-[relation*0..1]-(maybe) WHERE NONE (r in relation WHERE type(r) IN ["isDefinedBy", "subClassOf", "filler"]) AND NOT (label.iri =~ ".*_:.*") AND NOT (maybe.iri =~ ".*_:.*") AND label.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path
- parcellationRoots
MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path UNION MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) RETURN path
- parcellationRoots/{species-id}
MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species:Class{iri: "${species-id}"}) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" return path UNION MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species:Class{iri: "${species-id}"}) RETURN path
- parcellationRoots/{species-id}/{region-id}
MATCH (region:Class{iri: "${region-id}"}) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (artifact) -[:subClassOf*0..2]->(parent) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path UNION MATCH (region:Class{iri: "${region-id}"}) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) RETURN path
- parcellationRootsFMA/{species-id}/{fma-id}
MATCH (fma:Class{iri: "${fma-id}"}) WITH "FMA:" + toString(fma.`http://purl.org/sig/ont/fma/FMAID`) AS curie MATCH (region) -[:subClassOf*]->(start:Class{iri: "http://purl.obolibrary.org/obo/UBERON_0001062"}) WHERE any(x IN region.`http://www.geneontology.org/formats/oboInOwl#hasDbXref` WHERE x =~ curie) WITH region MATCH (region) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (artifact) -[:subClassOf*0..2]->(parent) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path UNION MATCH (fma:Class{iri: "${fma-id}"}) WITH "FMA:" + toString(fma.`http://purl.org/sig/ont/fma/FMAID`) AS curie MATCH (region) -[:subClassOf*]->(start:Class{iri: "http://purl.obolibrary.org/obo/UBERON_0001062"}) WHERE any(x IN region.`http://www.geneontology.org/formats/oboInOwl#hasDbXref` WHERE x =~ curie) WITH region MATCH (region) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) RETURN path
- parcellationGraph
MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" return path UNION MATCH path = (maybe) -[relation*0..1]-(label) -[:subClassOf]->(root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE NONE (r in relation WHERE type(r) IN ["isDefinedBy", "subClassOf", "filler"]) AND NOT (label.iri =~ ".*_:.*") AND NOT (maybe.iri =~ ".*_:.*") AND label.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path
- organList
MATCH (n) WHERE n.iri IN [ "http://purl.org/sig/ont/fma/fma7195", // lung "http://purl.org/sig/ont/fma/fma7088", // heart "http://purl.org/sig/ont/fma/fma7197", // liver "http://purl.org/sig/ont/fma/fma7198", // pancreas "http://purl.org/sig/ont/fma/fma7203", // kidney "http://purl.org/sig/ont/fma/fma7148", // stomach "http://purl.org/sig/ont/fma/fma7196", // spleen "http://purl.org/sig/ont/fma/fma14543", // colon "http://purl.org/sig/ont/fma/fma7201", // large intestine "http://purl.org/sig/ont/fma/fma7200", // small intestine "http://purl.org/sig/ont/fma/fma7199", // intestine "http://purl.org/sig/ont/fma/fma15900", // urinary bladder "http://purl.org/sig/ont/fma/fma45659", // lower urinary tract "http://purl.org/sig/ont/fma/fma7157", // nervous system "http://purl.org/sig/ont/fma/fma9903", // peripheral nervous system "http://purl.org/sig/ont/fma/fma9906", // sympathetic nervous system "http://purl.org/sig/ont/fma/fma7647", // spinal cord "http://purl.org/sig/ont/fma/fma50801", // brain "http://purl.org/sig/ont/fma/fma5889", // autonomic ganglion "http://purl.org/sig/ont/fma/fma19667", // urethra "http://purl.org/sig/ont/fma/fma7131" // esophagus ] RETURN n
- speciesList
MATCH (n) WHERE n.iri IN [ "http://purl.obolibrary.org/obo/NCBITaxon_9378", // Suncus murinus "http://purl.obolibrary.org/obo/NCBITaxon_9606", // Homo sapiens "http://purl.obolibrary.org/obo/NCBITaxon_9685", // Felis catus "http://purl.obolibrary.org/obo/NCBITaxon_9823", // Sus scrofa "http://purl.obolibrary.org/obo/NCBITaxon_10090", // Mus musculus "http://purl.obolibrary.org/obo/NCBITaxon_10116" // Rattus norvegicus ] RETURN n
- sparc community terms
MATCH (t)-[:isDefinedBy]->(graph:Ontology{iri: "http://uri.interlex.org/sparc/ontologies/community-terms"}) RETURN t
- anatomyPhenotypes
Return phenotypes that inhere in some part of an anatomical entity.
MATCH (anatomical_entity:Class{iri: $id}) <-[part_of:subClassOf|BFO:0000050|RO:0002433*0..40]-(subclass_part_ctmo) <-[inheres_in:RO:0000052|RO:0002314!]-(intersection_of_quality_and_anatomy) // inheres in (anon intersection of) <-[has_process_part:BFO:0000051]-() // has part (process) <-[:subClassOf*0..]-(phenotype) // phenotype and all subclasses WHERE // filter out partOf/hasPart cases that induce circularity ALL(e IN part_of WHERE NOT EXISTS(e.owlType) OR e.owlType = "subClassOf" OR e.owlType = "operand") RETURN phenotype
shortestSimple
MATCH (start:Class{iri: '${start_id}'}) WITH start MATCH (end:Class{iri: '${end_id}'}) WITH start, end MATCH path = shortestPath((start)-[:${relationship}*..${max_depth}]->(end)) RETURN path
neurons
- connectivity
MATCH (blank)- [entrytype:ilxtr:hasSomaLocatedIn|ilxtr:hasAxonLocatedIn|ilxtr:hasDendriteLocatedIn|ilxtr:hasPresynapticTerminalsIn] ->(location:Class{iri: '${start_id}'}) WITH location, entrytype, blank MATCH (phenotype)<-[predicate]-(blank)<-[:equivalentClass]-(neuron) WHERE NOT (phenotype.iri =~ ".*_:.*") // RETURN phenotype, (phenotype)-[predicate]-(neuron) as e // WITH location, predicate, phenotype, neuron RETURN location, entrytype, neuron, predicate, phenotype
- connectedRegions
MATCH (blank)- [entrytype:ilxtr:hasSomaLocatedIn|ilxtr:hasAxonLocatedIn|ilxtr:hasDendriteLocatedIn|ilxtr:hasPresynapticTerminalsIn] ->(location:Class{iri: '${start_id}'}) WITH entrytype, blank MATCH (phenotype)<-[:${target_predicate}]-(blank) // WHERE NOT (phenotype.iri =~ ".*_:.*") RETURN phenotype
apinat
- bundles/{start-id}
MATCH path1 = (start:Class{iri: "${start-id}"}) -[:apinatomy:annotates]->(start_housing) -[:apinatomy:subtypes*0..1]->() -[:apinatomy:clones*0..1]->(layer_or_end) -[:apinatomy:layers*0..1]->() -[:apinatomy:bundles]->(linkStart) -[:apinatomy:prevChainEndLevels|apinatomy:prev|apinatomy:source*1..]->(link) -[:apinatomy:targetOf|apinatomy:sourceOf]->(linkSoma) // axon or dendrite root -[:apinatomy:conveyingLyph]->() -[:apinatomy:supertype*0..1]->(soma:NamedIndividual) -[:apinatomy:ontologyTerms]->(c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) WITH path1, link OPTIONAL MATCH path2 = (link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:layerIn*0..1]->(end) -[:apinatomy:ontologyTerms]->(external) RETURN path1, path2
- old-bundles/{start-id}
MATCH path1 = (start:Class{iri: '${start-id}'}) -[:apinatomy:annotates]->(start_housing) -[:apinatomy:bundlesChains]->(chain) -[:apinatomy:root]->(root) -[:apinatomy:internalIn]->(layer_or_end) # this hits a cycle back to start_housing -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(layer_or_end_external) WITH path1, root, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) WITH path1, path2, root MATCH path3 = (root) // in the layer case this hits an additional lyph <-[:apinatomy:target|apinatomy:source]-(link) <-[:apinatomy:conveys]-(soma) <-[:apinatomy:annotates]-(soma_NLX) RETURN path1, path2, path3
- somas
MATCH (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) RETURN soma
- housing-lyphs
MATCH path = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(somaLink) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(root) // axon or dendrite root -[:apinatomy:controlNodes|apinatomy:rootOf*1..2]->(chain) // axon or dendrite tree -[:apinatomy:housingLyphs]->(housing) // list of lyphs housing the trees -[:apinatomy:ontologyTerms*0..1]->(external) // external ids for the housing lyphs WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL RETURN path
- housing-lyphs/{start-id}
MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(somaLink) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(root) // axon or dendrite root -[:apinatomy:internalIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(layer_or_end_external:Class{iri: '${start-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, root MATCH path2 = (root) -[:apinatomy:controlNodes|apinatomy:rootOf*1..2]->(chain) // axon or dendrite tree -[:apinatomy:housingLyphs]->(housing) // list of lyphs housing the trees -[:apinatomy:ontologyTerms*0..1]->(external) // external ids for the housing lyphs RETURN path1, path2 UNION MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(somaLink) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(root) // axon or dendrite root -[:apinatomy:internalIn]->(layer) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external:Class{iri: '${start-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, root MATCH path2 = (root) -[:apinatomy:rootOf]->(chain) // axon or dendrite tree -[:apinatomy:housingLyphs]->(housing) // list of lyphs housing the trees -[:apinatomy:ontologyTerms*0..1]->(external) // external ids for the housing lyphs RETURN path1, path2
- soma-processes
MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) // sourceOf is first and only once -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) WITH path1, path2, nodeRoot MATCH path3 = (nodeRoot) // extract chain for axon vs dendrite -[:apinatomy:rootOf]->(chain) RETURN path1, path2, path3
A sparql version of the query (work in progress).
SELECT DISTINCT ?c ?soma ?linkSoma ?nodeRoot ?link ?layer_or_end ?cloned ?supertype ?external_st ?external_loe ?external_end_housing WHERE { VALUES ?c { NLX:154731 } ?c rdf:type owl:Class . ?c apinatomy:annotates ?soma . ?soma rdf:type owl:NamedIndividual . ?soma apinatomy:conveys ?linkSoma . ?linkSoma apinatomy:target | apinatomy:source ?nodeRoot . ?nodeRoot apinatomy:rootOf ?chain . ?nodeRoot apinatomy:sourceOf | apinatomy:nextChainStartLevels | apinatomy:next+ ?link . ?link apinatomy:fasciculatesIn | apinatomy:endsIn ?layer_or_end . optional { ?layer_or_end apinatomy:cloneOf* ?cloned . } # optional optional { ?cloned apinatomy:supertype* ?supertype . } # optional ?supertype apinatomy:ontologyTerms ?external_st . ?layer_or_end apinatomy:ontologyTerms ?external_loe . optional { ?layer_or_end apinatomy:layerIn ?end_housing . } # optional optional { ?end_housing apinatomy:ontologyTerms ?external_end_housing . } # optional } limit ?limit
- soma-processes/{start-id}
MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:internalIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:layerIn*0..1]->(layerSoma) // don't need to see both layer and housing for soma -[:apinatomy:ontologyTerms]->(externalEndSoma:Class{iri: '${start-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot MATCH path3 = (chain) <-[:apinatomy:rootOf]-(nodeRoot) -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external) WITH path1, path3, nodeRoot, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) RETURN path1, path2, path3
- weird-soma-processes/{process-id}
MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) // sourceOf is first and only once -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external:Class{iri: '${process-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) WITH path1, path2, nodeRoot MATCH path3 = (nodeRoot) // extract chain for axon vs dendrite -[:apinatomy:rootOf]->(chain) RETURN path1, path2, path3 UNION MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) // sourceOf is first and only once -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot, layer_or_end AS layer MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external:Class{iri: '${process-id}'}) WITH path1, path2, nodeRoot MATCH path3 = (nodeRoot) // extract chain for axon vs dendrite -[:apinatomy:rootOf]->(chain) RETURN path1, path2, path3
yaml file
Example template.
cypherResources: - path: operations: &name-ops - summary: <<nonl(desc-name())>> parameters: - name: some-id description: does something paramType: query: &name | <<block-name>>
cypherResources: - path: /dynamic/prod/sparc/anatomyPhenotypes/{id} operations: &anatomyPhenotypes-ops - summary: nil parameters: - name: id description: uberon id of the anatomical entity to search from paramType: path query: &anatomyPhenotypes | MATCH (anatomical_entity:Class{iri: $id}) <-[part_of:subClassOf|BFO:0000050|RO:0002433*0..40]-(subclass_part_ctmo) <-[inheres_in:RO:0000052|RO:0002314!]-(intersection_of_quality_and_anatomy) // inheres in (anon intersection of) <-[has_process_part:BFO:0000051]-() // has part (process) <-[:subClassOf*0..]-(phenotype) // phenotype and all subclasses WHERE // filter out partOf/hasPart cases that induce circularity ALL(e IN part_of WHERE NOT EXISTS(e.owlType) OR e.owlType = "subClassOf" OR e.owlType = "operand") RETURN phenotype - path: /dynamic/test/sparc/anatomyPhenotypes/{id} operations: *anatomyPhenotypes-ops query: *anatomyPhenotypes - path: /dynamic/prod/sparc/organParts/{id} operations: &organParts-ops - summary: nil parameters: - name: id description: ontology id of the organ paramType: path query: &organParts | // depth of 6 captures everything, 5 is too shallow, 40 is WAY too deep MATCH path = (start:Class{iri: "${id}"}) <-[:subClassOf|ilxtr:includedForSPARCUnder|fma:regional_part_of|fma:constitutional_part_of|fma:related_part_of*0..6]-(part) <-[:fma:arterial_supply_of|fma:nerve_supply_of|fma:venous_drainage_of|fma:continuous_with*0..1]-(sup) <-[:subClassOf|fma:constitutional_part_of|fma:branch|fma:tributary|fma:branch_of*0..1]-(a_bit_more) RETURN path UNION // for this query UNION seems to be MUCH faster than using WITH MATCH path = (start:Class{iri: "${id}"}) // this one does not need to be inverted ? except for the INCOMING flag <-[:fma:arterial_supply_of|fma:venous_drainage_of]-(vessel) <-[:fma:branch|fma:tributary]-(more_vessel) <-[:fma:branch|fma:tributary|fma:regional_part]-(even_more_vessel) RETURN path - path: /dynamic/test/sparc/organParts/{id} operations: *organParts-ops query: *organParts - path: /dynamic/prod/sparc/parcellationArtifacts operations: - summary: Get the graph of all parcellation artifacts for all species query: | MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path - path: /dynamic/prod/sparc/parcellationArtifacts/{species-id} operations: - summary: Get the graph of all parcellation artifacts for a single species parameters: - name: species-id description: ontology id of the species paramType: path query: | MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species:Class{iri: "${species-id}"}) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path - path: /dynamic/prod/sparc/artifactRoots/{artifact-id} operations: - summary: Get the graph of all parcellation label roots for a single artifact WARNING this can return no results parameters: - name: artifact-id description: ontology id of the parcellation artifact paramType: path query: | MATCH path = (root) -[:ilxtr:isDefinedBy]->(a)<-[:subClassOf*0..2] -(artifact:Class{iri: "${artifact-id}"}) RETURN path - path: /dynamic/prod/sparc/artifactLabels/{artifact-id} operations: - summary: Get the graph of all parcellation labels for a single artifact WARNING this can return no results parameters: - name: artifact-id description: ontology id of the parcellation artifact paramType: path query: | MATCH path = (label) -[:subClassOf]->(root) -[:ilxtr:isDefinedBy]->(a)<-[:subClassOf*0..2] -(artifact:Class{iri: "${artifact-id}"}) WHERE label.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path - path: /dynamic/prod/sparc/rootLabels/{root-id} operations: &rootLabes-ops - summary: Get the list of all parcellation labels for a single label root parameters: - name: root-id description: ontology id of the parcellation label root paramType: path query: &rootLabels | MATCH (label)-[:subClassOf]->(root:Class{iri: "${root-id}"}) , path = (label)-[relation*0..1]-(maybe) WHERE NONE (r in relation WHERE type(r) IN ["isDefinedBy", "subClassOf", "filler"]) AND NOT (label.iri =~ ".*_:.*") AND NOT (maybe.iri =~ ".*_:.*") AND label.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path - path: /dynamic/test/sparc/rootLabels/{root-id} operations: *rootLabes-ops query: *rootLabels - path: /dynamic/prod/sparc/parcellationRoots operations: - summary: Get the graph of all parcellation label roots for all species query: | MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path UNION MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) RETURN path - path: /dynamic/prod/sparc/parcellationRoots/{species-id} operations: - summary: Get the graph of all parcellation label roots for a single species parameters: - name: species-id description: ontology id of the species paramType: path query: | MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species:Class{iri: "${species-id}"}) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" return path UNION MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species:Class{iri: "${species-id}"}) RETURN path - path: /dynamic/prod/sparc/parcellationRoots/{species-id}/{region-id} operations: - summary: Get the graph of all parcellation label roots for a single species and anatomical region parameters: - name: species-id description: ontology id of the species paramType: path - name: region-id description: ontology id of the anatomical region paramType: path query: | MATCH (region:Class{iri: "${region-id}"}) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (artifact) -[:subClassOf*0..2]->(parent) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path UNION MATCH (region:Class{iri: "${region-id}"}) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) RETURN path - path: /dynamic/prod/sparc/parcellationRootsFMA/{species-id}/{fma-id} operations: &parcellationRootsFMA-ops - summary: Get the graph of all parcellation label roots for a single species and anatomical region parameters: - name: species-id description: ontology id of the species paramType: path - name: fma-id description: ontology id of the anatomical region paramType: path query: &parcellationRootsFMA | MATCH (fma:Class{iri: "${fma-id}"}) WITH "FMA:" + toString(fma.`http://purl.org/sig/ont/fma/FMAID`) AS curie MATCH (region) -[:subClassOf*]->(start:Class{iri: "http://purl.obolibrary.org/obo/UBERON_0001062"}) WHERE any(x IN region.`http://www.geneontology.org/formats/oboInOwl#hasDbXref` WHERE x =~ curie) WITH region MATCH (region) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (artifact) -[:subClassOf*0..2]->(parent) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path UNION MATCH (fma:Class{iri: "${fma-id}"}) WITH "FMA:" + toString(fma.`http://purl.org/sig/ont/fma/FMAID`) AS curie MATCH (region) -[:subClassOf*]->(start:Class{iri: "http://purl.obolibrary.org/obo/UBERON_0001062"}) WHERE any(x IN region.`http://www.geneontology.org/formats/oboInOwl#hasDbXref` WHERE x =~ curie) WITH region MATCH (region) <-[:ilxtr:isDefinedInRegion]- (parent) -[:ilxtr:isDefinedInTaxon]-> (species:Class{iri: "${species-id}"}) WITH parent MATCH path = (root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) RETURN path - path: /dynamic/test/sparc/parcellationRootsFMA/{species-id}/{fma-id} operations: *parcellationRootsFMA-ops query: *parcellationRootsFMA - path: /dynamic/prod/sparc/parcellationGraph operations: - summary: Get the graph of all parcellation labels for all species query: | MATCH path = (artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE artifact.iri <> "http://www.w3.org/2002/07/owl#Nothing" return path UNION MATCH path = (maybe) -[relation*0..1]-(label) -[:subClassOf]->(root) -[:ilxtr:isDefinedBy]->(artifact) -[:subClassOf*0..2]->(parent) -[:ilxtr:isDefinedInTaxon]->(species) WHERE NONE (r in relation WHERE type(r) IN ["isDefinedBy", "subClassOf", "filler"]) AND NOT (label.iri =~ ".*_:.*") AND NOT (maybe.iri =~ ".*_:.*") AND label.iri <> "http://www.w3.org/2002/07/owl#Nothing" RETURN path - path: /dynamic/prod/sparc/organList operations: &organList-ops - summary: Get the list of all FMA organ identifiers relevant to SPARC query: &organList | MATCH (n) WHERE n.iri IN [ "http://purl.org/sig/ont/fma/fma7195", // lung "http://purl.org/sig/ont/fma/fma7088", // heart "http://purl.org/sig/ont/fma/fma7197", // liver "http://purl.org/sig/ont/fma/fma7198", // pancreas "http://purl.org/sig/ont/fma/fma7203", // kidney "http://purl.org/sig/ont/fma/fma7148", // stomach "http://purl.org/sig/ont/fma/fma7196", // spleen "http://purl.org/sig/ont/fma/fma14543", // colon "http://purl.org/sig/ont/fma/fma7201", // large intestine "http://purl.org/sig/ont/fma/fma7200", // small intestine "http://purl.org/sig/ont/fma/fma7199", // intestine "http://purl.org/sig/ont/fma/fma15900", // urinary bladder "http://purl.org/sig/ont/fma/fma45659", // lower urinary tract "http://purl.org/sig/ont/fma/fma7157", // nervous system "http://purl.org/sig/ont/fma/fma9903", // peripheral nervous system "http://purl.org/sig/ont/fma/fma9906", // sympathetic nervous system "http://purl.org/sig/ont/fma/fma7647", // spinal cord "http://purl.org/sig/ont/fma/fma50801", // brain "http://purl.org/sig/ont/fma/fma5889", // autonomic ganglion "http://purl.org/sig/ont/fma/fma19667", // urethra "http://purl.org/sig/ont/fma/fma7131" // esophagus ] RETURN n - path: /dynamic/test/sparc/organList operations: *organList-ops query: *organList - path: /dynamic/prod/sparc/speciesList operations: &speciesList-ops - summary: Get the list of all NCBITaxon species identifiers relevant to SPARC query: &speciesList | MATCH (n) WHERE n.iri IN [ "http://purl.obolibrary.org/obo/NCBITaxon_9378", // Suncus murinus "http://purl.obolibrary.org/obo/NCBITaxon_9606", // Homo sapiens "http://purl.obolibrary.org/obo/NCBITaxon_9685", // Felis catus "http://purl.obolibrary.org/obo/NCBITaxon_9823", // Sus scrofa "http://purl.obolibrary.org/obo/NCBITaxon_10090", // Mus musculus "http://purl.obolibrary.org/obo/NCBITaxon_10116" // Rattus norvegicus ] RETURN n - path: /dynamic/test/sparc/speciesList operations: *speciesList-ops query: *speciesList - path: /dynamic/shortestSimple query: | MATCH (start:Class{iri: '${start_id}'}) WITH start MATCH (end:Class{iri: '${end_id}'}) WITH start, end MATCH path = shortestPath((start)-[:${relationship}*..${max_depth}]->(end)) RETURN path operations: - summary: Get the shortest path between two IDs parameters: - name: start_id description: The starting node (ex UBERON:0005751) paramType: query - name: end_id description: The ending node (ex UBERON:0001255) paramType: query - name: max_depth description: the maximum depth to traverse paramType: query - name: relationship description: The property to traverse (ex subClassOf or subClassOf|partOf|isA) paramType: query required: false - path: /dynamic/neurons/connectivity query: | MATCH (blank)- [entrytype:ilxtr:hasSomaLocatedIn|ilxtr:hasAxonLocatedIn|ilxtr:hasDendriteLocatedIn|ilxtr:hasPresynapticTerminalsIn] ->(location:Class{iri: '${start_id}'}) WITH location, entrytype, blank MATCH (phenotype)<-[predicate]-(blank)<-[:equivalentClass]-(neuron) WHERE NOT (phenotype.iri =~ ".*_:.*") // RETURN phenotype, (phenotype)-[predicate]-(neuron) as e // WITH location, predicate, phenotype, neuron RETURN location, entrytype, neuron, predicate, phenotype operations: - summary: Get connected anatomical regions by neuron type parameters: - name: start_id description: The starting location (eg UBERON:0001759) paramType: query - path: /dynamic/neurons/connectedRegions query: | MATCH (blank)- [entrytype:ilxtr:hasSomaLocatedIn|ilxtr:hasAxonLocatedIn|ilxtr:hasDendriteLocatedIn|ilxtr:hasPresynapticTerminalsIn] ->(location:Class{iri: '${start_id}'}) WITH entrytype, blank MATCH (phenotype)<-[:${target_predicate}]-(blank) // WHERE NOT (phenotype.iri =~ ".*_:.*") RETURN phenotype operations: - summary: Get connected anatomical regions by starting location and target relationship parameters: - name: start_id description: The starting location (eg UBERON:0001759) paramType: query - name: target_predicate description: The predicate for the type of connectivity (eg ilxtr:hasPresynapticTerminalsIn) paramType: query required: false - path: /dynamic/demos/apinat/bundles/{start-id} operations: - summary: Return the paths to somas from an anatomical region (aka connected-somas) parameters: - name: start-id description: ontology id of the starting point paramType: path query: | MATCH path1 = (start:Class{iri: "${start-id}"}) -[:apinatomy:annotates]->(start_housing) -[:apinatomy:subtypes*0..1]->() -[:apinatomy:clones*0..1]->(layer_or_end) -[:apinatomy:layers*0..1]->() -[:apinatomy:bundles]->(linkStart) -[:apinatomy:prevChainEndLevels|apinatomy:prev|apinatomy:source*1..]->(link) -[:apinatomy:targetOf|apinatomy:sourceOf]->(linkSoma) // axon or dendrite root -[:apinatomy:conveyingLyph]->() -[:apinatomy:supertype*0..1]->(soma:NamedIndividual) -[:apinatomy:ontologyTerms]->(c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) WITH path1, link OPTIONAL MATCH path2 = (link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:layerIn*0..1]->(end) -[:apinatomy:ontologyTerms]->(external) RETURN path1, path2 - path: /dynamic/demos/apinat/old-bundles/{start-id} operations: - summary: Return the paths to somas from an anatomical region (aka connected-somas) parameters: - name: start-id description: ontology id of the starting point paramType: path query: | MATCH path1 = (start:Class{iri: '${start-id}'}) -[:apinatomy:annotates]->(start_housing) -[:apinatomy:bundlesChains]->(chain) -[:apinatomy:root]->(root) -[:apinatomy:internalIn]->(layer_or_end) # this hits a cycle back to start_housing -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(layer_or_end_external) WITH path1, root, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) WITH path1, path2, root MATCH path3 = (root) // in the layer case this hits an additional lyph <-[:apinatomy:target|apinatomy:source]-(link) <-[:apinatomy:conveys]-(soma) <-[:apinatomy:annotates]-(soma_NLX) RETURN path1, path2, path3 - path: /dynamic/demos/apinat/somas operations: - summary: List all the somas for a given graph (TODO on the given graph) query: | MATCH (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) RETURN soma - path: /dynamic/demos/apinat/housing-lyphs operations: - summary: List all the housing lyphs (neuronal processes) for all starting points. query: | MATCH path = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(somaLink) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(root) // axon or dendrite root -[:apinatomy:controlNodes|apinatomy:rootOf*1..2]->(chain) // axon or dendrite tree -[:apinatomy:housingLyphs]->(housing) // list of lyphs housing the trees -[:apinatomy:ontologyTerms*0..1]->(external) // external ids for the housing lyphs WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL RETURN path - path: /dynamic/demos/apinat/housing-lyphs/{start-id} operations: - summary: List all the housing lyphs for a starting point. parameters: - name: start-id description: ontology id of the starting point paramType: path query: | MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(somaLink) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(root) // axon or dendrite root -[:apinatomy:internalIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(layer_or_end_external:Class{iri: '${start-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, root MATCH path2 = (root) -[:apinatomy:controlNodes|apinatomy:rootOf*1..2]->(chain) // axon or dendrite tree -[:apinatomy:housingLyphs]->(housing) // list of lyphs housing the trees -[:apinatomy:ontologyTerms*0..1]->(external) // external ids for the housing lyphs RETURN path1, path2 UNION MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(somaLink) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(root) // axon or dendrite root -[:apinatomy:internalIn]->(layer) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external:Class{iri: '${start-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, root MATCH path2 = (root) -[:apinatomy:rootOf]->(chain) // axon or dendrite tree -[:apinatomy:housingLyphs]->(housing) // list of lyphs housing the trees -[:apinatomy:ontologyTerms*0..1]->(external) // external ids for the housing lyphs RETURN path1, path2 - path: /dynamic/demos/apinat/soma-processes operations: - summary: List all the neuronal processes for all somas. query: | MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) // sourceOf is first and only once -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) WITH path1, path2, nodeRoot MATCH path3 = (nodeRoot) // extract chain for axon vs dendrite -[:apinatomy:rootOf]->(chain) RETURN path1, path2, path3 - path: /dynamic/demos/apinat/soma-processes/{start-id} operations: - summary: List all the neuronal processes for somas located in start-id. parameters: - name: start-id description: ontology id of the starting point paramType: path query: | MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:internalIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:layerIn*0..1]->(layerSoma) // don't need to see both layer and housing for soma -[:apinatomy:ontologyTerms]->(externalEndSoma:Class{iri: '${start-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot MATCH path3 = (chain) <-[:apinatomy:rootOf]-(nodeRoot) -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external) WITH path1, path3, nodeRoot, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) RETURN path1, path2, path3 - path: /dynamic/demos/apinat/weird-soma-processes/{process-id} operations: - summary: List all the neuronal processes for somas where some processes is in process-id. parameters: - name: process-id description: ontology id of the starting point paramType: path query: | MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) // sourceOf is first and only once -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external:Class{iri: '${process-id}'}) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot, layer_or_end AS layer OPTIONAL MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external) WITH path1, path2, nodeRoot MATCH path3 = (nodeRoot) // extract chain for axon vs dendrite -[:apinatomy:rootOf]->(chain) RETURN path1, path2, path3 UNION MATCH path1 = (c:Class{iri: "http://uri.neuinfo.org/nif/nifstd/nlx_154731"}) -[:apinatomy:annotates]->(soma:NamedIndividual) // soma lyph -[:apinatomy:conveys]->(linkSoma) // link connecting soma to axon and dendrite -[:apinatomy:target|apinatomy:source]->(nodeRoot) // axon or dendrite root -[:apinatomy:sourceOf|apinatomy:nextChainStartLevels|apinatomy:next*1..]->(link) // sourceOf is first and only once -[:apinatomy:fasciculatesIn|apinatomy:endsIn]->(layer_or_end) -[:apinatomy:cloneOf*0..1]->() -[:apinatomy:supertype*0..1]->() -[:apinatomy:ontologyTerms]->(external) WHERE soma.`https://apinatomy.org/uris/readable/generated` IS NULL WITH path1, nodeRoot, layer_or_end AS layer MATCH path2 = (layer) // if we were in a layer, get the containing lyph as well -[:apinatomy:layerIn]->(end_housing) -[:apinatomy:ontologyTerms]->(end_housing_external:Class{iri: '${process-id}'}) WITH path1, path2, nodeRoot MATCH path3 = (nodeRoot) // extract chain for axon vs dendrite -[:apinatomy:rootOf]->(chain) RETURN path1, path2, path3 - path: /dynamic/demos/apinat/neru-1/{neupop-id} operations: &neru-ops - summary: Return the housing regions and publications for neurulated groups. parameters: - name: neupop-id description: neuron population identifier paramType: path query: | MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK // publications WITH neugrp, a OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it WITH neugrp, a, path MATCH (neugrp) -[b:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH lyph, a, b, c, d, path MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) RETURN a, b, c, d, e, path UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->(e) // e is a hack to get columns to match -[d:apinatomy:ontologyTerms*0..1]->(region) // this variant shows the dead end lyphs that correspond to the fasciculatesIn links above //-[c:apinatomy:internalIn*0..1]->(e) //-[d:apinatomy:ontologyTerms*0..1]->(region) return a, b, c, d, null AS e, null AS path - path: /dynamic/demos/apinat/neru-2/{neupop_id} operations: *neru-ops query: | MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK // publications WITH neugrp, a OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it WITH neugrp, a, path MATCH (neugrp) -[b:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, b, c, d, path MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) // use apinatomy:next to extract ordering information WITH neugrp, link, a, b, c, d, e, path MATCH (link) -[f:apinatomy:next*0..]->() //-[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() // FIXME these should be collapsing into a single relationship -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) RETURN a, b, c, d, e, f, g,h,i, path UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->(e) // e is a hack to get columns to match -[d:apinatomy:ontologyTerms*0..1]->(region) // this variant shows the dead end lyphs that correspond to the fasciculatesIn links above //-[c:apinatomy:internalIn*0..1]->(e) //-[d:apinatomy:ontologyTerms*0..1]->(region) RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path - path: /dynamic/demos/apinat/neru-3/{neupop_id} operations: *neru-ops query: | MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK // publications WITH neugrp, a OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it WITH neugrp, a, path MATCH (neugrp) -[b:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, b, c, d, path // MATCH vs , not all things that match as lyphs have externals MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) // use apinatomy:next to extract ordering information WITH neugrp, link, a, b, c, d, e, path MATCH p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() WITH neugrp, link, a, b, c, d, e, path, p2, cl MATCH (cl) -[x:apinatomy:inheritedOntologyTerms*0..1]->() WITH neugrp, link, a, b, c, d, e, path, p2, x MATCH (link) -[f:apinatomy:next*0..]->() //-[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() // FIXME these should be collapsing into a single relationship -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) RETURN a, b, c, d, e, f, g,h,i, path, p2, x UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) // this variant shows the dead end lyphs that correspond to the fasciculatesIn links above //-[c:apinatomy:internalIn*0..1]->() //-[d:apinatomy:ontologyTerms*0..1]->(region) RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, null as p2, null as x - path: /dynamic/demos/apinat/neru-4/{neupop_id} operations: *neru-ops query: | MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf]->()-[:apinatomy:inheritedOntologyTerms]->() WITH neugrp, link, lyph, a, c, d, layer_ext // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedOntologyTerms*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Publication"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext - path: /dynamic/demos/apinat/neru-5/{neupop_id} operations: *neru-ops query: | MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more - path: /dynamic/demos/apinat/neru-6/{neupop_id} operations: *neru-ops query: | MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedExternal*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedExternal]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more - path: /dynamic/demos/apinat/neru-7/{neupop_id} operations: *neru-ops query: | MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK , (neugrp) -[:apinatomy:links]->(link) -[c:apinatomy:fasciculatesIn|apinatomy:endsIn*0..1]->(lyph_or_layer) // real lyphs convey things, layers do not -[d:apinatomy:layerIn*0..1]->(lyph) -[:apinatomy:conveys*0..1]->() // make sure we are at a real lyph WITH neugrp, link, lyph, a, c, d OPTIONAL MATCH layer_ext = (lyph) <-[d*1]-(layer)-[:apinatomy:cloneOf*0..1]->()-[:apinatomy:inheritedOntologyTerms]->() WITH neugrp, link, lyph, a, c, d, layer_ext OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedOntologyTerms]->() WITH neugrp, link, lyph, a, c, d, layer_ext, more // there is a difference here because the previous match does not require lyphs to have external ids MATCH (lyph) -[e:apinatomy:ontologyTerms]->(region) , p2 = (link) -[:apinatomy:conveyingLyph]->(cl) -[:apinatomy:topology]->() , (cl) -[x:apinatomy:inheritedOntologyTerms*0..1]->() // use apinatomy:next to extract ordering information , (link) -[f:apinatomy:next|apinatomy:nextChainStartLevels*0..]->() -[g:apinatomy:target*0..1]->() -[h:apinatomy:rootOf*0..1]->() -[i:apinatomy:levels*0..1]->() <-[:apinatomy:links]-(neugrp) // publications WITH neugrp, a, c, d, e, f, g,h,i, p2, x, layer_ext, more OPTIONAL MATCH path = (neugrp) -[:apinatomy:references]->(pub) -[:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) // cannot be curied, dynamic endpoints will not expand it RETURN a, null as b, c, d, e, f, g,h,i, path, p2, x, layer_ext, more UNION // this part usually only returns the soma housing lyph MATCH (neupop:Class{iri: $neupop_id}) -[a:apinatomy:annotates]->(neugrp:NamedIndividual{`https://apinatomy.org/uris/readable/description`: "dynamic"}) // FIXME HACK -[b:apinatomy:lyphs]->(lyph) -[c:apinatomy:internalIn]->() -[d:apinatomy:ontologyTerms*0..1]->(region) , p2 = (lyph) -[:apinatomy:conveys]->(soma_link) -[:apinatomy:source|apinatomy:target]->(soma_node) -[:apinatomy:sourceOf]->(chain_link) , (chain_link) -[:apinatomy:levelIn]->(chain) , (soma_node) -[:apinatomy:rootOf]->(chain) WITH lyph, a, b, c, d, p2 OPTIONAL MATCH more = (lyph) -[:apinatomy:layerIn|apinatomy:endsIn|apinatomy:fasciculatesIn|apinatomy:internalIn|apinatomy:cloneOf*1..]->() -[:apinatomy:ontologyTerms|apinatomy:inheritedOntologyTerms]->() RETURN a, b, c, d, null AS e, null AS f, null AS g, null AS h, null AS i, null AS path, p2, null as x, null as layer_ext, more - path: /dynamic/demos/apinat/modelList operations: - summary: nil query: | MATCH ({iri: "https://apinatomy.org/uris/elements/Graph"}) <-[:type]-(g)-[:isDefinedBy]->(o:Ontology) RETURN o - path: /dynamic/demos/apinat/modelPopulationsReferences/{model_id} operations: - summary: nil parameters: - name: model_id description: the identifier for an ApiNATOMY model paramType: path query: | MATCH (start:Ontology {iri: $model_id}) <-[:isDefinedBy]-(external:Class) -[:subClassOf*]->(:Class {iri: "http://uri.interlex.org/tgbugs/uris/readable/NeuronEBM"}) // FIXME , (external) -[e:type]->() RETURN e UNION OPTIONAL MATCH (start:Ontology {iri: $model_id}) <-[:isDefinedBy]-(graph:NamedIndividual) -[:type]->({iri: "https://apinatomy.org/uris/elements/Graph"}) // elements don't have a superclass right now , (graph) -[:apinatomy:references]->(pub) -[e:type]->(:Class{iri: "https://apinatomy.org/uris/elements/Reference"}) RETURN e
ApiNATOMY competency queries
expected counts per model
Expected number of somas and neupops.
model-id | neupops | somas |
---|---|---|
ard-arm-cardiac | 12 | 41 |
bolser-lewis | 29 | 29 |
bronchomotor | 6 | 19 |
keast-bladder | 20 | 34 |
sawg-distal-colon | 17 | 23 |
sawg-stomach | 14 | 14 |
somas
somas >= neupops
The number of somas for distinct populations in a given model.
populations
the number of neuron populations as defined by the neurulator that have an ontology identifier
neuron part per region per model
model-id | diag abbrev | external | somas | axons | axon term | dend | dend term |
---|---|---|---|---|---|---|---|
bolser-lewis | SCG | 17 | |||||
keast-bladder | |||||||
bronchomotor | |||||||
ard-arm-cardiac | |||||||
sawg-distal-colon | |||||||
sawg-stomach |
expected locations
use NPO as a top down constraint on the locations of somas etc.
somas
could do this by population or generically
population process location
soma-processes can also be checked using NPO but not needed for simple cases
model-id | neupop | diag abbrev | external |
---|---|---|---|
bolser-lewis | q | PN | |
bolser-lewis | q | C4 | |
bolser-lewis | q | PHRNIC | |
bolser-lewis | q | DIAPHRAGM |
location process populations
bundles NPO here as well
model-id | diag abbrev | external | neupop |
---|---|---|---|
bolser-lewis | VAGUS | 9 total |
cross model
expect populations from models to have processes in common location
select distinct ?external (str(?el) as ?label) #?p ?model #?region #?link #?neru # ?seed (replace(str(?neru), "^.+-([A-Za-z0-9]+)$", "$1") as ?neuron_number) #?dyn ?neupop where { values ?external { UBERON:0006457 UBERON:0001894 UBERON:0005453 UBERON:0018683 } ?external a owl:Class ; apinatomy:annotates ?region ; rdfs:label ?el . ?region a elements:Lyph . ?model a elements:Graph ; apinatomy:lyphs ?region . ?link ( apinatomy:fasciculatesIn | apinatomy:endsIn | apinatomy:layerIn | apinatomy:internalIn )+ ?region . ?neru apinatomy:links ?link ; apinatomy:description ?dyn ; a elements:Group . filter contains(str(?dyn), "dynamic") optional { ?neru apinatomy:ontologyTerms ?neupop . } optional { ?seed apinatomy:seedIn ?neru . } # seedIn sort of works but misses cases where a dynamic group was created with a seed } order by str(?external) str(?model) xsd:integer(?neuron_number)
Expected.
external | diag abbrev | model-id | neupop |
---|---|---|---|
UBERON:0006457 | T1 | bolser-lewis | 1 2 3 6 7 |
UBERON:0006457 | T1 | keast-bladder | 20 |
UBERON:0001894 | DIENC | bolser-lewis | 1 26 |
UBERON:0001894 | Diencephalon | keast-bladder | 13 14 15 16 17 18 |
UBERON:0005453 | IMG | keast-bladder | 3 6 7 11 |
UBERON:0005453 | IMG | sawg-distal-colon | B D F G H Q |
UBERON:0018683 | LumSplN | keast-bladder | 6 7 11 |
UBERON:0018683 | LumSplN | sawg-distal-colon | B |
vagus
OWL DL query
hasLocationPhenotype some ('part of' some 'vagus nerve') hasLocationPhenotype some ('part of' some 'vagus nerve nucleus') hasLocationPhenotype some ('part of' some 'vagus nerve' or 'part of' some 'vagus nerve nucleus')
// filter out things that project to the vagus nerve not that start in the vagus nerve or something like that (neupop)-[:ilxtr:hasLocationPhenotype]->(:Class{iri: UBERON:0001759}) (neupop)-[:ilxtr:hasAxonPresynapticElementIn]->(axon_locations) (neupop)-[:ilxtr:hasSensorySubcellularElementIn]->(dendrite_locations)
visualize all populations that have some process in the IMG
Images of nerus that have some process in the IMG, from keast-bladder
and sawg-distal-colon
.
kg queries
TODO point people to the query that returns a list of all neuron populations and all populations + papers per model 5 is going to be the easiest
neuron type keast 5 projects to
RETURN region
Expected.
external | label |
---|---|
UBERON:0016508 | pelvic ganglion |
img processes query
Input
UBERON:0005453 | inferior mesenteric ganglion |
Expect
ilxtr:neuron-type-keast-3 |
ilxtr:neuron-type-keast-6 |
ilxtr:neuron-type-keast-7 |
ilxtr:neuron-type-keast-11 |
ilxtr:neuron-type-sdcol-b |
ilxtr:neuron-type-sdcol-d |
ilxtr:neuron-type-sdcol-f |
ilxtr:neuron-type-sdcol-g |
ilxtr:neuron-type-sdcol-h |
ilxtr:neuron-type-sdcol-q |
Simple blaze
simple sckan queries over blazegraph
inserts
insert { ?s ?np ?o } where { { values (?p ?np) { (ilxtr:hasAxonPresynapticElementIn nposimtest:hasAxonPresynapticElementIn) (ilxtr:hasSomaLocatedIn nposimtest:hasSomaLocatedIn) #(ilxtr:hasSomaLocatedIn nposimtest:hasAxonLocatedIn) # add inferred axon locations (decided to exclude) (ilxtr:hasAxonLocatedIn nposimtest:hasAxonLocatedIn) (ilxtr:hasDendriteLocatedIn nposimtest:hasDendriteLocatedIn) (ilxtr:hasAxonSensorySubcellularElementIn nposimtest:hasAxonSensorySubcellularElementIn) #(ilxtr:hasAxonPresynapticElementIn ilxtr:hasAxonTerminalLocation) #(ilxtr:hasSomaLocatedIn ilxtr:hasSomaLocation) #(ilxtr:hasAxonLocatedIn ilxtr:hasAxonLocation) #(ilxtr:hasDendriteLocatedIn ilxtr:hasDendriteLocation) #(ilxtr:hasAxonSensorySubcellularElementIn ilxtr:hasAxonSensoryLocation) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom [ a owl:Restriction ; owl:onProperty partOf: ; owl:someValuesFrom ?o ] ] } union { values (?p ?np) { (ilxtr:hasForwardConnectionPhenotype nposimtest:hasForwardConnectionPhenotype) (ilxtr:hasFunctionalCircuitRolePhenotype nposimtest:hasFunctionalCircuitRolePhenotype) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom ?o ] }}
queries
#select (count(*) as ?c) { select distinct ?s ?o where { #?s nposimtest:hasSomaLocatedIn ?o ?s nposimtest:hasDendriteLocatedIn ?o } order by ?s ?o #}
PREFIX nposimtest: <http://uri.interlex.org/tgbugs/uris/readable/npo-simple-test-1/> SELECT (COUNT(*) as ?count) { #PREFIX nposimtest: <http://uri.interlex.org/tgbugs/uris/readable/npo-simple-test-1/> select distinct ?s ?np ?o where { { values (?p ?np) { (ilxtr:hasAxonPresynapticElementIn nposimtest:hasAxonPresynapticElementIn) (ilxtr:hasSomaLocatedIn nposimtest:hasSomaLocatedIn) #(ilxtr:hasSomaLocatedIn nposimtest:hasAxonLocatedIn) # add inferred axon locations (decided to exclude) (ilxtr:hasAxonLocatedIn nposimtest:hasAxonLocatedIn) (ilxtr:hasDendriteLocatedIn nposimtest:hasDendriteLocatedIn) (ilxtr:hasAxonSensorySubcellularElementIn nposimtest:hasAxonSensorySubcellularElementIn) #(ilxtr:hasAxonPresynapticElementIn ilxtr:hasAxonTerminalLocation) #(ilxtr:hasSomaLocatedIn ilxtr:hasSomaLocation) #(ilxtr:hasAxonLocatedIn ilxtr:hasAxonLocation) #(ilxtr:hasDendriteLocatedIn ilxtr:hasDendriteLocation) #(ilxtr:hasAxonSensorySubcellularElementIn ilxtr:hasAxonSensoryLocation) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom [ a owl:Restriction ; owl:onProperty partOf: ; owl:someValuesFrom ?o ] ] } union { values (?p ?np) { (ilxtr:hasForwardConnectionPhenotype nposimtest:hasForwardConnectionPhenotype) (ilxtr:hasFunctionalCircuitRolePhenotype nposimtest:hasFunctionalCircuitRolePhenotype) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom ?o ] }} order by ?s ?np ?o limit 5000 }
#PREFIX nposimtest: <http://uri.interlex.org/tgbugs/uris/readable/npo-simple-test-1/> select distinct ?s ?np ?o where { { values (?p ?np) { (ilxtr:hasAxonPresynapticElementIn nposimtest:hasAxonPresynapticElementIn) (ilxtr:hasSomaLocatedIn nposimtest:hasSomaLocatedIn) #(ilxtr:hasSomaLocatedIn nposimtest:hasAxonLocatedIn) # add inferred axon locations (decided to exclude) (ilxtr:hasAxonLocatedIn nposimtest:hasAxonLocatedIn) (ilxtr:hasDendriteLocatedIn nposimtest:hasDendriteLocatedIn) (ilxtr:hasAxonSensorySubcellularElementIn nposimtest:hasAxonSensorySubcellularElementIn) #(ilxtr:hasAxonPresynapticElementIn ilxtr:hasAxonTerminalLocation) #(ilxtr:hasSomaLocatedIn ilxtr:hasSomaLocation) #(ilxtr:hasAxonLocatedIn ilxtr:hasAxonLocation) #(ilxtr:hasDendriteLocatedIn ilxtr:hasDendriteLocation) #(ilxtr:hasAxonSensorySubcellularElementIn ilxtr:hasAxonSensoryLocation) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom [ a owl:Restriction ; owl:onProperty partOf: ; owl:someValuesFrom ?o ] ] } union { values (?p ?np) { (ilxtr:hasForwardConnectionPhenotype nposimtest:hasForwardConnectionPhenotype) (ilxtr:hasFunctionalCircuitRolePhenotype nposimtest:hasFunctionalCircuitRolePhenotype) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom ?o ] }} order by ?s ?np ?o limit 5000
where { { values (?p ?np) { (ilxtr:hasAxonPresynapticElementIn nposimtest:hasAxonPresynapticElementIn) (ilxtr:hasSomaLocatedIn nposimtest:hasSomaLocatedIn) #(ilxtr:hasSomaLocatedIn nposimtest:hasAxonLocatedIn) # add inferred axon locations (decided to exclude) (ilxtr:hasAxonLocatedIn nposimtest:hasAxonLocatedIn) (ilxtr:hasDendriteLocatedIn nposimtest:hasDendriteLocatedIn) (ilxtr:hasAxonSensorySubcellularElementIn nposimtest:hasAxonSensorySubcellularElementIn) #(ilxtr:hasAxonPresynapticElementIn ilxtr:hasAxonTerminalLocation) #(ilxtr:hasSomaLocatedIn ilxtr:hasSomaLocation) #(ilxtr:hasAxonLocatedIn ilxtr:hasAxonLocation) #(ilxtr:hasDendriteLocatedIn ilxtr:hasDendriteLocation) #(ilxtr:hasAxonSensorySubcellularElementIn ilxtr:hasAxonSensoryLocation) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom [ a owl:Restriction ; owl:onProperty partOf: ; owl:someValuesFrom ?o ] ] } union { values (?p ?np) { (ilxtr:hasForwardConnectionPhenotype nposimtest:hasForwardConnectionPhenotype) (ilxtr:hasFunctionalCircuitRolePhenotype nposimtest:hasFunctionalCircuitRolePhenotype) } ?s owl:equivalentClass [ rdf:type owl:Class ; owl:intersectionOf ?bn0 ] . ?bn0 rdf:rest*/rdf:first ilxtr:NeuronApinatSimple . ?bn0 rdf:rest*/rdf:first [ rdf:type owl:Restriction ; owl:onProperty ?p ; owl:someValuesFrom ?o ] }}
Sanity checks
Other queries run against various representations of the data.
JSON
jq -c '.datasets | length'
jq -c '[paths | select(.[-1] == "path_metadata")] | length'
function path-metadata-coverage () { local PATH_EXPORT_JSON=$1 local COUNT_T=$(jq -c '.datasets | length' "${PATH_EXPORT_JSON}") local COUNT_PM=$(jq -c '[paths | select(.[-1] == "path_metadata")] | length' "${PATH_EXPORT_JSON}") awk -v t=${COUNT_T} -v pm=${COUNT_PM} 'BEGIN { print ( pm / t ) }' }
General queries
General metadata and housekeeping queries.
List all loaded ontologies
SELECT ?s WHERE { ?s a owl:Ontology }
MATCH (o:Ontology) RETURN o
predicates
select distinct ?p ?l where { ?s ?p ?o . optional { ?p rdfs:label ?l . } } order by ?p
select ?s ?p ?o where { values ?p { prov:startedAtTime prov:wasGeneratedBy dc:date owl:versionInfo TEMP:TimestampExportStart } ?s ?p ?o . } order by desc(str(?o))
versions
Useful version information is not present in all ontology files at the moment.
embedded load provenance record
SELECT ?p ?o WHERE { build:prov ?p ?o . }
MATCH (p)-[i:build:id]-(), (p)-[e]-() RETURN i, e
curation-export.ttl
select ?s ?tes ?vi where { ?s TEMP:TimestampExportStart ?tes ; owl:versionInfo ?vi . }
protcur.ttl
select distinct ?o where { <https://cassava.ucsd.edu/sparc/ontologies/protcur.ttl> owl:versionInfo ?o }
apinat models
MATCH ({iri: "https://apinatomy.org/uris/elements/Graph"})<-[:type]-(g) RETURN g
Use cases
Connectivity dashboard
organs
from pyontutils.core import OntGraph g = OntGraph().parse(data=input, format='ttl') #return [[g.namespace_manager._qhrm(_)] for _ in sorted(set(g.subjects()))] return ' '.join([g.namespace_manager._qhrm(_) for _ in sorted(set(g.subjects()))])
@prefix l: <http://www.w3.org/2000/01/rdf-schema#label> . @prefix e: <http://uri.interlex.org/tgbugs/uris/readable/hasExistingId> . @prefix FMA: <http://purl.org/sig/ont/fma/fma> . @prefix UBERON: <http://purl.obolibrary.org/obo/UBERON_> . # tissue UBERON:0001013 l: "adipose tissue"; e: FMA:20110 . # regions UBERON:0002298 l: "brainstem"; e: FMA:79876 . UBERON:0001016 l: "nervous system"; e: FMA:7157 . UBERON:0000010 l: "peripheral nervous system"; e: FMA:9903 . UBERON:0000013 l: "sympathetic nervous system"; e: FMA:9906 . UBERON:0002005 l: "enteric nervous system"; e: FMA:66070 . # TODO cardiovascular system # e.g. for blood pressure # TODO cardiopulmonary system # organs UBERON:0000955 l: "brain"; e: FMA:50801 . UBERON:0001155 l: "colon"; e: FMA:14543 . UBERON:0002110 l: "gallbladder"; e: FMA:7202 . UBERON:0000948 l: "heart"; e: FMA:7088 . UBERON:0000160 l: "intestine"; e: FMA:7199 . UBERON:0002113 l: "kidney"; e: FMA:7203 . UBERON:0000059 l: "large intestine"; e: FMA:7201 . UBERON:0002107 l: "liver"; e: FMA:7197 . UBERON:0001556 l: "lower urinary tract"; e: FMA:45659 . UBERON:0002048 l: "lung"; e: FMA:68877 . UBERON:0001630 l: "muscle organ"; e: FMA:5022 . UBERON:0001264 l: "pancreas"; e: FMA:7198 . UBERON:0002097 l: "skin of body"; e: FMA:7163 . UBERON:0002108 l: "small intestine"; e: FMA:7200 . UBERON:0002240 l: "spinal cord"; e: FMA:7647 . UBERON:0002106 l: "spleen"; e: FMA:7196 . UBERON:0000945 l: "stomach"; e: FMA:7148 . UBERON:0001255 l: "urinary bladder"; e: FMA:15900 . # granular UBERON:0000057 l: "urethra"; e: FMA:19667 . UBERON:0001043 l: "esophagus"; e: FMA:7131 .
nerves
@prefix l: <http://www.w3.org/2000/01/rdf-schema#label> . @prefix e: <http://uri.interlex.org/tgbugs/uris/readable/hasExistingId> . @prefix FMA: <http://purl.org/sig/ont/fma/fma> . @prefix UBERON: <http://purl.obolibrary.org/obo/UBERON_> . # XXX sciatic nerve is missing from this list # not actually cranial UBERON:0002019 l: "accessory XI nerve"; e: FMA:6720 . # missing from the larger list # nerves missing from the larger list UBERON:0001646 l: "abducens nerve"; e: FMA:50867 . UBERON:0001650 l: "hypoglossal nerve"; e: FMA:50871 . UBERON:0001579 l: "olfactory nerve"; e: FMA:46787 . UBERON:0001644 l: "trochlear nerve"; e: FMA:50865 . UBERON:0003723 l: "vestibulocochlear nerve"; e: FMA:50869 . # the larger list UBERON:0034728 l: "autonomic nerve" . UBERON:0009009 l: "carotid sinus nerve" . UBERON:0009675 l: "chorda tympani branch of facial nerve" . UBERON:0019198 l: "dorsal nerve of clitoris" . UBERON:0019197 l: "dorsal nerve of penis" . UBERON:0010380 l: "enteric nerve" . UBERON:0010406 l: "cholinergic enteric nerve" . UBERON:0001647 l: "facial nerve"; e: FMA:50868 . UBERON:0001649 l: "glossopharyngeal nerve"; e: FMA:50870 . UBERON:0001643 l: "oculomotor nerve"; e: FMA:50864 . UBERON:0002924 l: "terminal nerve" . UBERON:0001645 l: "trigeminal nerve"; e: FMA:50866 . UBERON:0001759 l: "vagus nerve"; e: FMA:5731 . # TODO vagus nerve branches UBERON:0018680 l: "greater splanchnic nerve" . UBERON:0003438 l: "iris nerve" . UBERON:0011096 l: "lacrimal nerve" . UBERON:0035642 l: "laryngeal nerve" . UBERON:0011766 l: "left recurrent laryngeal nerve" . UBERON:0011767 l: "right recurrent laryngeal nerve" . UBERON:0003716 l: "recurrent laryngeal nerve" . UBERON:0011326 l: "superior laryngeal nerve" . UBERON:3010764 l: "laryngeus ventralis" . UBERON:0001964 l: "least splanchnic nerve" . UBERON:0018681 l: "lesser splanchnic nerve" . UBERON:0003721 l: "lingual nerve" . UBERON:0022301 l: "long ciliary nerve" . UBERON:0018683 l: "lumbar splanchnic nerve" . UBERON:0000377 l: "maxillary nerve" . UBERON:0036143 l: "meningeal branch of mandibular nerve" . UBERON:0017641 l: "meningeal branch of spinal nerve" . UBERON:0022300 l: "nasociliary nerve" . UBERON:0008810 l: "nasopalatine nerve" . UBERON:0035650 l: "nerve of clitoris" . UBERON:0035649 l: "nerve of penis" . UBERON:0015162 l: "superior branch of oculomotor nerve" . UBERON:0018675 l: "pelvic splanchnic nerve" . UBERON:0011391 l: "perineal nerve" . UBERON:0001884 l: "phrenic nerve" . UBERON:0034725 l: "pterygopalatine nerve" . UBERON:0011390 l: "pudendal nerve" . UBERON:0009625 l: "sacral nerve" . UBERON:0018684 l: "sacral splanchnic nerve" . UBERON:0022302 l: "short ciliary nerve" . UBERON:0003715 l: "splanchnic nerve" . UBERON:0018679 l: "thoracic splanchnic nerve" . UBERON:0001323 l: "tibial nerve" . UBERON:0036216 l: "tympanic nerve" . UBERON:0018412 l: "vidian nerve" . # cervical nerve UBERON:0000962 l: "nerve of cervical vertebra"; e: FMA:5859 .
plexi
UBERON:0002439 l: "myenteric nerve plexus"; e: FMA:63252 .
distributed ganglion that has not ensheathed there may be significant variablity between individuals in whether a plexius is fully ganglionated/ensheathed
the issue is that from the perspective the cell populations, they are actually the same population regardless of whether they are plexi or ganglia
maybe need to get these to converge onto the neuron populations so that we can merge the two
ganglia
@prefix l: <http://www.w3.org/2000/01/rdf-schema#label> . @prefix e: <http://uri.interlex.org/tgbugs/uris/readable/hasExistingId> . @prefix syn: <http://uri.neuinfo.org/nif/nifstd/readable/synonym> . @prefix FMA: <http://purl.org/sig/ont/fma/fma> . @prefix UBERON: <http://purl.obolibrary.org/obo/UBERON_> . UBERON:0001808 l: "parasympathetic ganglion" . UBERON:0035776 l: "accessory ciliary ganglion" . UBERON:0001805 l: "autonomic ganglion"; e: FMA:5889 . UBERON:0014463 l: "cardiac ganglion" . UBERON:0002262 l: "celiac ganglion" . UBERON:0035783 l: "ganglion of ciliary nerve" . UBERON:0001701 l: "glossopharyngeal ganglion" . UBERON:0005360 l: "inferior glossopharyngeal IX ganglion" . UBERON:0013500 l: "glossopharyngeal-vagus IX-X ganglion complex" . UBERON:0035769 l: "mesenteric ganglion" . UBERON:0005479 l: "superior mesenteric ganglion" . UBERON:0005453 l: "inferior mesenteric ganglion" . UBERON:0001989 l: "superior cervical ganglion" . UBERON:0001990 l: "middle cervical ganglion" . UBERON:0002440 l: "inferior cervical ganglion" . UBERON:0003963 l: "otic ganglion" . UBERON:0001807 l: "paravertebral ganglion" . UBERON:0016508 l: "pelvic ganglion" . UBERON:0003964 l: "prevertebral ganglion" . UBERON:0003962 l: "pterygopalatine ganglion" . UBERON:0005407 l: "sublingual ganglion" . UBERON:0002059 l: "submandibular ganglion" . UBERON:0001806 l: "sympathetic ganglion" . UBERON:0005362 l: "vagus X ganglion" . UBERON:0005364 l: "superior vagus X ganglion" . UBERON:0005363 l: "inferior vagus X ganglion"; syn: "nodose ganglion" . UBERON:0000408 l: "vertebral ganglion" . UBERON:0002441 l: "cervicothoracic ganglion"; e: FMA:6469; syn: "stellate ganglion" .
neuron population by organ
select distinct ?organ_start ?label (count(distinct(?ele)) as ?elements) #?elements ?model #?ele #?type # ?sp #?s #?op_wat #?p #?o where { values ?organ_start { nil nil nil } ?organ_start rdfs:label ?sl . bind(str(?sl) as ?label) # FIXME TODO traverse partonomy optional { values ?type { elements:Lyph elements:Group elements:Material elements:Chain } ?organ ( partOf: | rdfs:subClassOf )* ?organ_start . #?organ apinatomy:annotates ?ele . ?ele apinatomy:ontologyTerms ?organ . ?ele a ?type . ?model ( apinatomy:lyphs | apinatomy:chains | apinatomy:groups | apinatomy:materials ) ?ele . ?model a elements:Graph . #?ele apinatomy:inheritedOntologyTerms ?organ . #?o ?p ?q . } } group by ?organ_start ?label ?model order by ?organ_start #order by ?type ?organ ?model #limit ?limit
./reports/organ-nerve-ganglia.csv
https://docs.google.com/spreadsheets/d/1pgprwTr4bvAaex8cNLeoRLUgt0VU5tilbWi4BCWF1JE/edit#gid=219324374
organ-nerve-ganglia
select distinct ?part_start (str(?sl) as ?start_label) where { ?part_start rdfs:subClassOf+/owl:someValuesFrom+ UBERON:0001255 . ?part_start rdfs:label ?sl . }
the nested version here is massively slow
select distinct ?part (str(?l) as ?label) where { values ?part_0 { UBERON:0001255 } #?part_1 rdfs:label ?l1 . ?part_1 rdfs:subClassOf ?bn0 . ?bn0 a owl:Restriction . ?bn0 owl:onProperty partOf: . ?bn0 owl:someValuesFrom ?part_0 . optional { #?part_2 rdfs:label ?l2 . ?part_2 rdfs:subClassOf ?bn1 . ?bn1 a owl:Restriction . ?bn1 owl:onProperty partOf: . ?bn1 owl:someValuesFrom ?part_1 . optional { #?part_3 rdfs:label ?l3 . ?part_3 rdfs:subClassOf ?bn2 . ?bn2 a owl:Restriction . ?bn2 owl:onProperty partOf: . ?bn2 owl:someValuesFrom ?part_2 . } } #optional { #?part_4 rdfs:label ?l4 . #?part_4 rdfs:subClassOf ?bn3 . #?bn3 a owl:Restriction . #?bn3 owl:onProperty partOf: . #?bn3 owl:someValuesFrom ?part_3 . #} ?part a owl:Class . ?part rdfs:label ?l . filter ( ?part = ?part_0 || ?part = ?part_1 || ?part = ?part_2 || ?part = ?part_3 ) #( || ?part = ?part_4 ) } limit ?limit
select distinct ?part_1 where { values ?part_0 { UBERON:0009958 } ?part_1 rdfs:label ?l . ?part_1 rdfs:subClassOf ?bn0 . ?bn0 a owl:Restriction . ?bn0 owl:onProperty partOf: . ?bn0 owl:someValuesFrom ?part_0 . }
select distinct ?sigh (str(?l) as ?label) #?sigx #(str(?lx) as ?labx) where { ?sigh rdfs:subClassOf+/owl:someValuesFrom+ UBERON:0001255 . # consider also RO:0002433 usually go together ?sigh rdfs:label ?l . # FIXME somehow male and female urethra are still being pulled in :/ #filter ( ?sigh != UBERON:0000057 ) #filter not exists { ?sigh rdfs:subClassOf/owl:someValuesFrom UBERON:0000057 . } ?sigh rdfs:subClassOf/owl:onProperty partOf: . #?sigx rdfs:subClassOf ?bn . #?bn a owl:Restriction . #?bn owl:onProperty partOf: . #?bn owl:someValuesFrom ?sigh . #?sigx rdfs:label ?lx . filter not exists { ?sigh rdfs:subClassOf/owl:onProperty <http://purl.obolibrary.org/obo/uberon/core#channels_into> . } filter not exists { ?sigh rdfs:subClassOf/owl:onProperty <http://purl.obolibrary.org/obo/uberon/core#channels_from> . } filter not exists { ?sigh rdfs:subClassOf/owl:onProperty BFO:0000051 . } filter not exists { ?sigh rdfs:subClassOf/owl:onProperty RO:0002150 . } filter not exists { ?sigh rdfs:subClassOf/owl:onProperty RO:0002221 . } filter not exists { ?sigh rdfs:subClassOf/owl:onProperty RO:0002178 . } } order by ?label
select distinct ?part ?prop (str(?l) as ?label) ?part_start (str(?sl) as ?start_label) where { values ?wat { UBERON:0001255 } # FIXME this is still completely broken because sparql and # transitive queries over over owl restrictions are ... problematic ?part_start rdfs:subClassOf+/owl:someValuesFrom+ ?wat . filter ( ?prop = partOf: ) ?part_start rdfs:label ?sl . ?part_start rdfs:subClassOf ?bny . ?bny owl:onProperty ?prop . ?part rdfs:label ?l . ?part rdfs:subClassOf ?bn0 . ?bn0 a owl:Restriction . ?bn0 owl:onProperty partOf: . ?bn0 owl:someValuesFrom ?part_start . } order by ?start_label
from sparcur.sheets import Reports class ONGRep: _data = data class options: preview = False to_sheets = True @Reports.makeReportSheet('organ_start', sheet_name='organ-nerve-ganglia') def populate(self, ext=None): return self._data, 'organ-nerve-ganglia coverage report' t = ONGRep() #t.populate() return t._data
neuron population by nerve
neuron population by ganglion
devel
1 + 2
from pyontutils.core import OntTerm asdf = ['ILX:0727875', 'ILX:0727396', 'ILX:0727235', 'ILX:0736783', 'ILX:0725331', 'ILX:0724284', 'ILX:0732483', 'ILX:0725803', 'ILX:0723837', 'ILX:0737036', 'ILX:0725086', 'ILX:0736097', 'ILX:0733375', 'ILX:0730739', 'ILX:0734588', 'ILX:0728741', 'ILX:0728157', 'ILX:0724431', 'ILX:0728322', 'ILX:0486534', 'ILX:0731053', 'ILX:0734339', 'ILX:0731969', 'ILX:0726449', 'ILX:0734582', 'ILX:0731914', 'ILX:0729870', 'ILX:0728987', 'ILX:0736712', 'ILX:0735649', 'ILX:0730231', 'ILX:0725969', 'ILX:0725552', 'ILX:0729045', 'ILX:0732611', 'ILX:0724152', 'ILX:0724140', 'ILX:0736057', 'ILX:0726733', 'ILX:0735212', 'ILX:0726145', 'ILX:0736880', 'ILX:0732740', 'ILX:0730942', 'ILX:0736020', 'ILX:0733193', 'ILX:0733995', 'ILX:0503992', 'ILX:0734328', 'ILX:0724764', 'ILX:0729794', 'ILX:0734607', 'ILX:0727602', 'ILX:0735024', 'ILX:0725520', 'ILX:0728778', 'ILX:0726312', 'ILX:0733021', 'ILX:0732970', 'ILX:0725326', 'ILX:0725956', 'ILX:0726454', 'ILX:0734766', 'ILX:0733700', 'ILX:0733004', 'ILX:0732328', 'ILX:0735011', 'ILX:0734057', 'ILX:0730509', 'ILX:0727725', 'ILX:0730966', 'ILX:0729052', 'ILX:0736358', 'ILX:0727970', 'ILX:0736369'] qq = [OntTerm(a) for a in asdf]
[(repr(_), _('ilxtr:hasIlxPreferredId')[0].curie) for _ in qq]
ApiNATOMY
Coverage of FMA by the TOO map.
Unclaimed regions from FMA/UBERON in the TOO map
Define the TOO map as the covering set of terms. It might not actually be, but that is how we will treat it. Probably want to avoid the immaterial entities.
Try to come up with a basis set from FMA as well.
If there are regional hierarchies that have been missed we will see them.
Summary statistics
- debug
SELECT distinct ?o WHERE { ?o a elements:Graph . } order by str(?o)
select distinct ?graph ?lyphs ?label WHERE { # ?model apinatomy:hasGraph ?graph # TODO broken conversion to literal instead of uri at the moment # sadly it seems that no one has managed to write an optimization that converts # into this form when querying multiple predicates in the same expression { ?graph a elements:Graph ; rdfs:label ?label . { select ?graph (count(distinct(?o)) as ?lyphs ) where { ?graph apinatomy:lyphs ?o . } group by ?graph } } union { { select (count(distinct(?graph_)) as ?graph ) where { ?graph_ a elements:Graph } } bind("Total unique" as ?label) { select (count(distinct(?o)) as ?lyphs ) where { ?graph_ apinatomy:lyphs ?o . } } } }
- Dashboard
label graph lyphs lyphs_input externals publications nerus neupops neupops_pat somas ApiNATOMY model of the stomach sstom:sawg-stomach 668 37 77 8 14 14 14 14 Ardell Armour Cardiac Model aacar:ard-arm-cardiac 1827 137 161 2 17 17 17 41 Bolser-Lewis Model of the Physiology of the Superior Cervical Ganglion bolew:bolser-lewis 1151 107 141 239 29 29 29 29 Keast ApiNATOMY model of bladder innervation kblad:keast-bladder 2394 139 174 30 21 20 20 35 SAWG ApiNATOMY model of the descending colon sdcol:sawg-distal-colon 1066 89 135 5 18 18 18 24 SPARC Bronchomotor Flatmap bromo:bronchomotor 623 144 187 6 6 6 6 19 pancreas model pancr:pancreas 452 17 529 1 5 5 5 11 ApiNATOMY model of the spleen splen:spleen 580 47 103 5 5 5 5 8 Total unique 8 8761 717 823 296 115 114 114 181 element count models 8 models scigraph 8 lyphs 8761 lyphs input 717 externals 583 publications 296 nerus 115 neupops 114 neupops pattern 114 prefix count nlx 1 CL 3 GO 5 NCIT 5 CHEBI 11 sao 11 fma 15 tgbugs 114 ilx 179 UBERON 239 :SUM: 583 :TOTAL: 583 select distinct ?label ?graph #?g ?lyphs ?lyphs_input #?links #?nodes #?chains #?coalescences ?externals ?publications #?groups ?nerus ?neupops ?neupops_pat ?somas <<apinat-model-summary-where>>
WHERE { # ?model apinatomy:hasGraph ?graph # TODO broken conversion to literal instead of uri at the moment # sadly it seems that no one has managed to write an optimization that converts # into this form when querying multiple predicates in the same expression { ?graph a elements:Graph ; rdfs:label ?l . bind(str(?l) as ?label) # avoid issues with graphs loaded multiple times { select ?graph (count(distinct(?o)) as ?lyphs ) where { ?graph apinatomy:lyphs ?o . } group by ?graph } { select ?graph (count(distinct(?o)) as ?lyphs_input ) where { ?graph apinatomy:lyphs ?o . filter not exists { ?o apinatomy:isTemplate true . } filter not exists { ?o apinatomy:generated true . } } group by ?graph } { select ?graph (count(distinct(?o)) as ?links ) where { ?graph apinatomy:links ?o . } group by ?graph } { select ?graph (count(distinct(?o)) as ?nodes ) where { ?graph apinatomy:nodes ?o . } group by ?graph } { select ?graph (count(distinct(?o)) as ?chains ) where { ?graph apinatomy:chains ?o . } group by ?graph } { select ?graph (count(distinct(?o)) as ?coalescences) where { ?graph apinatomy:coalescences ?o . } group by ?graph } { select ?graph (count(distinct(?o)) as ?externals ) where { ?graph apinatomy:ontologyTerms ?o . } group by ?graph } optional { select ?graph (count(distinct(?o)) as ?publications) where { ?graph apinatomy:references ?o . } group by ?graph } { select ?graph (count(distinct(?o)) as ?groups ) where { ?graph apinatomy:groups ?o . } group by ?graph } optional { select ?graph (count(distinct(?o)) as ?nerus ) where { ?graph apinatomy:groups ?o . ?o apinatomy:description ?d . filter(contains(str(?d), "dynamic")) } group by ?graph } optional { select ?graph (count(distinct(?o)) as ?neupops ) where { ?graph apinatomy:ontologyTerms ?o . ?o rdfs:subClassOf+ ilxtr:NeuronEBM . } group by ?graph } optional { select ?graph (count(distinct(?o)) as ?neupops_pat ) where { ?graph apinatomy:ontologyTerms ?o . filter contains(str(?o), "/neuron-type-") } group by ?graph } optional { select ?graph (count(distinct(?o)) as ?somas ) where { ?graph apinatomy:lyphs ?o . ?o apinatomy:ontologyTerms NLX:154731 . } group by ?graph } } union { { select (count(distinct(?graph_)) as ?graph ) where { ?graph_ a elements:Graph } } bind("Total unique" as ?label) { select (count(distinct(?o)) as ?lyphs ) where { ?graph_ apinatomy:lyphs ?o . } } { select (count(distinct(?o)) as ?lyphs_input ) where { ?graph_ apinatomy:lyphs ?o . filter not exists { ?o apinatomy:isTemplate true . } filter not exists { ?o apinatomy:generated true . } } } { select (count(distinct(?o)) as ?links ) where { ?graph_ apinatomy:links ?o . } } { select (count(distinct(?o)) as ?nodes ) where { ?graph_ apinatomy:nodes ?o . } } { select (count(distinct(?o)) as ?chains ) where { ?graph_ apinatomy:chains ?o . } } { select (count(distinct(?o)) as ?coalescences) where { ?graph_ apinatomy:coalescences ?o . } } { select (count(distinct(?o)) as ?externals ) where { ?graph_ apinatomy:ontologyTerms ?o . } } { select (count(distinct(?o)) as ?publications) where { ?graph_ apinatomy:references ?o . } } { select (count(distinct(?o)) as ?groups ) where { ?graph_ apinatomy:groups ?o . } } { select (count(distinct(?o)) as ?nerus ) where { ?graph_ apinatomy:groups ?o . ?o apinatomy:description ?d . filter(contains(str(?d), "dynamic")) } } optional { select (count(distinct(?o)) as ?neupops ) where { ?graph_ apinatomy:ontologyTerms ?o . ?o rdfs:subClassOf+ ilxtr:NeuronEBM . } } optional { select (count(distinct(?o)) as ?neupops_pat ) where { ?graph_ apinatomy:ontologyTerms ?o . filter contains(str(?o), "/neuron-type-") } } optional { select (count(distinct(?o)) as ?somas ) where { ?graph_ apinatomy:lyphs ?o . ?o apinatomy:ontologyTerms NLX:154731 . } } } }
- Queries
- ApiNATOMY sourced
- models
SELECT (COUNT(*) as ?count) { <<sparql-apinat-models>> }
SELECT DISTINCT (?s as ?id) (str(?l) as ?label) WHERE { ?s a elements:Graph . ?s rdfs:label ?l. }
SELECT DISTINCT ?o (str(?l) as ?label) (str(?v) as ?version) WHERE { ?o a owl:Ontology ; rdfs:label ?l ; apinatomy:hasGraph ?g . ?g a elements:Graph . ?g apinatomy:version ?v . }
MATCH ({iri: "https://apinatomy.org/uris/elements/Graph"})<-[:type]-(g) RETURN g
Return the list of all ApiNATOMY models in the database.
MATCH ({iri: "https://apinatomy.org/uris/elements/Graph"}) <-[:type]-(g)-[:isDefinedBy]->(o:Ontology) RETURN o
- number of lyphs
SELECT (COUNT(DISTINCT ?s) as ?total_lyphs) WHERE { ?s a elements:Lyph . }
total_lyphs 8162 generated vs input s? rdf:type element:Lyph
SELECT DISTINCT (COUNT(DISTINCT ?s) as ?input_lyphs) #?s #?p #?o WHERE { ?s a elements:Lyph . #?s ?p ?o . FILTER NOT EXISTS { ?s apinatomy:isTemplate true . } FILTER NOT EXISTS { ?s apinatomy:generated true . } #FILTER ( ! ( ?p = apinatomy:isTemplate && ?o = true ) ) #FILTER ( ! ( ?p = apinatomy:generated && ?o = true ) ) #?s apinatomy:generated ?o . } LIMIT ?limit
input_lyphs 742 - publications referenced
apinatomy:references average number of publications per unit? (for now no) will also want the full listing of publications select count distinct o? select distinct o? s? apinat:publication o?
SELECT DISTINCT (COUNT(DISTINCT ?pub) as ?publications) WHERE { ?s apinatomy:references ?pub . }
publications 293 - TODO species
both model level and lyph level
- terms employed in annotation
count of apinatomy:ontologyTerms by prefix UBERON, GO, CHEBI, etc. full listing of terms as well
"UBERON" "EMAPA" "fma" "CHEBI" "GO" "sao" "CL" "nlx" "ilx" "tgbugs" "NCBITaxon" "NCIT" "pubmed" "doi" "ncit"
SELECT ?prefix (COUNT(DISTINCT ?s) AS ?count) WHERE { { VALUES ?prefix { "UBERON" "EMAPA" "fma" "CHEBI" "GO" "sao" "CL" "nlx" "ilx" "tgbugs" "NCBITaxon" "NCIT" "pubmed" "doi" "ncit" } ?s a elements:OntologyTerm . FILTER CONTAINS(str(?s), ?prefix) } UNION { SELECT (":SUM:" AS ?prefix) ?s { VALUES ?pre { "UBERON" "EMAPA" "fma" "CHEBI" "GO" "sao" "CL" "nlx" "ilx" "tgbugs" "NCBITaxon" "NCIT" "pubmed" "doi" "ncit" } ?s a elements:OntologyTerm . FILTER CONTAINS(str(?s), ?pre) } } UNION { BIND(":TOTAL:" AS ?prefix) { SELECT ?s WHERE { ?s a elements:OntologyTerm . } } } } GROUP BY ?prefix ORDER BY ?count
SELECT (COUNT(DISTINCT(?s)) as ?count) WHERE { ?s a elements:OntologyTerm . }
- external issues
publications appearing as external ids, unmapped prefixes etc. FIXME where are these coming from?
SELECT DISTINCT ?l ?s WHERE { ?s a elements:OntologyTerm . ?l ?p ?s . FILTER(CONTAINS(str(?s), "doi") || CONTAINS(str(?s), "pubmed") || CONTAINS(str(?s), "ncit")) } ORDER BY ?l ?s LIMIT ?limit
- external issues
- Number of neurulated groups
Total neuron populations including those that are unidentified or are in error
SELECT (COUNT(*) as ?count) { SELECT DISTINCT ?group (str(?l) as ?label) WHERE { ?group a elements:Group . ?group apinatomy:description ?d filter(contains(str(?d), "dynamic")) ?group rdfs:label ?l . } order by ?group }
count 117 SELECT DISTINCT ?group (str(?l) as ?label) WHERE { ?group a elements:Group . ?group apinatomy:description ?d filter(contains(str(?d), "dynamic")) ?group rdfs:label ?l . } order by ?group
- Number of neuron populations with external ids and correct subClassOf.
SELECT (COUNT(*) as ?count) { SELECT DISTINCT ?neupop (str(?pl) as ?preferred_label) (str(?l) as ?label) WHERE { ?neupop a elements:OntologyTerm . ?neupop rdfs:subClassOf+ ilxtr:NeuronEBM . OPTIONAL { ?neupop skos:prefLabel ?pl . } OPTIONAL { ?neupop rdfs:label ?l . } } }
count 117 SELECT DISTINCT ?neupop (str(?pl) as ?preferred_label) (str(?l) as ?label) WHERE { ?neupop a elements:OntologyTerm . ?neupop rdfs:subClassOf+ ilxtr:NeuronEBM . OPTIONAL { ?neupop skos:prefLabel ?pl . } OPTIONAL { ?neupop rdfs:label ?l . } }
- Number of neuron populations with external ids that match the
neuron-type
pattern.
SELECT (COUNT(*) as ?count) { SELECT DISTINCT ?neupop (str(?pl) as ?preferred_label) (str(?l) as ?label) WHERE { ?neupop a elements:OntologyTerm . FILTER CONTAINS(str(?neupop), "/neuron-type-") OPTIONAL { ?neupop skos:prefLabel ?pl . } OPTIONAL { ?neupop rdfs:label ?l . } } }
count 117 SELECT DISTINCT ?neupop (str(?pl) as ?preferred_label) (str(?l) as ?label) WHERE { ?neupop a elements:OntologyTerm . FILTER CONTAINS(str(?neupop), "/neuron-type-") OPTIONAL { ?neupop skos:prefLabel ?pl . } OPTIONAL { ?neupop rdfs:label ?l . } }
- models
- NPO sourced queries
Keast Bolser Lewis First pass NLP output
- location
experimental
MATCH (neuron:Class{iri: "http://uri.neuinfo.org/nif/nifstd/sao1417703748"})<-[:subClassOf*1..]- (neupop) //(neupop:Class{iri: $neupop_id}) -[e:ilxtr:hasLocationPhenotype!]->(blank) -[q]->(more) //-[q:BFO:0000050]->(more) RETURN e, q
- phenotypes for neuron
MATCH (neupop:Class{iri: $neupop_id})-[e:ilxtr:hasPhenotype!]->(phenotype) RETURN e
from pprint import pprint from pyontutils.scigraph import Cypher, Vocabulary sgc = Cypher() query = """ MATCH (neupop:Class{iri: $neupop_id})-[e:ilxtr:hasPhenotype!]->(phenotype) RETURN e """ def get_phenotypes(neupop_id): d = sgc.execute(query=query, limit=99999, output='application/json', neupop_id=neupop_id) good = [e for e in d['edges'] if 'meta' in e and e['meta']['owlType'] == ['subClassOf'] and not e['obj'].startswith('_:')] return good pprint(get_phenotypes('ilxtr:neuron-type-keast-1'))
- number of neuron populations aka neuron types
SELECT DISTINCT ?s WHERE { ?s rdfs:subClassOf+ SAO:1813327414 . # NOTE this counts cells }
- basic connectivity
- python
from collections import defaultdict from pprint import pprint from neurondm.compiled.common_usage_types import * neurons = config.neurons() #pprint(neurons) #pprint(dir(neurons[0])) # pprint(neurons[0].edges) #pprint([n for n in neurons if ilxtr.hasSomaLocatedIn in n.edges][0]) #pprint([n for n in neurons if ilxtr.hasAxonLocatedIn in n.edges][0]) #pprint([n for n in neurons if ilxtr.hasAxonPresynapticElementIn in n.edges][0]) #pprint([n for n in neurons if ilxtr.hasDendriteLocatedIn in n.edges][0]) x = defaultdict(list) for n in neurons: for somar in [pe.p for pe in n.pes if pe.e == ilxtr.hasSomaLocatedIn]: for axonr in [pe.p for pe in n.pes if pe.e in (ilxtr.hasAxonPresynapticElementIn, ilxtr.hasProjectionPhenotype)]: # via may be incorrect here if an axon location applies only to one collateral for a terminal # this is why we need the partial order x[somar].append(axonr) pprint(dict(x)) # via axon pprint([n for n in neurons if ilxtr.hasAxonLocatedIn in n.edges][:1]) # axon terminal in apinatomy # region A is axonally forward connect to B forward here means soma -> axon terminal pprint([n for n in neurons if ilxtr.hasProjectionPhenotype in n.edges][:1]) pprint([n for n in neurons if ilxtr.hasAxonPresynapticElementIn in n.edges][:1]) # soma pprint([n for n in neurons if ilxtr.hasSomaLocatedIn in n.edges][:1]) pprint([n for n in neurons if ilxtr.hasSomaLocatedInLayer in n.edges][:1]) # via dendrite pprint([n for n in neurons if ilxtr.hasDendriteLocatedIn in n.edges][:1]) # dendrite terminal for sensory neurons in apinatomy # region A is dendritically forward connect to B forward here means dendrite terminal -> soma pprint([n for n in neurons if ilxtr.hasSensorySubcellularElementIn in n.edges][:1]) pprint([n for n in neurons if ilxtr.hasForwardConnectionPhenotype in n.edges][:1]) pprint([n for n in neurons if ilxtr.hasReverseConnectionPhenotype in n.edges][:1]) #pprint([n for n in neurons if EntailedPhenotype('UBERON:0002790', 'ilxtr:hasAxonLocatedIn') in n.pes ]) #pprint([n for n in neurons if ilxtr.hasSomaLocatedIn in n.edges]) #pprint([n for n in neurons if Phenotype('UBERON:0002610', 'ilxtr:hasSomaLocatedIn') in n.pes ])
- cypher
:x a owl:Class ; owl:equivalentClass [ a owl:Restriction ; owl:intersectionOf ( [ a owl:Restriction ; owl:onProperty ilxtr:hasSomaLocatedIn ; owl:someValuesFrom [ a owl:Restriction ; owl:onProperty :partOf ; owl:someValuesFrom ?my-region ; ] ; ] ; ) ]
MATCH (neuron)-[e]-> // (blank)-[:ilxtr:hasPhenotype]->(phenotype) (blanka)-[:ilxtr:hasAxonLocatedIn]->(blankb)-[edge]->(region_or_blank) //(blanka)-[:ilxtr:hasSomaLocatedIn]->(blankb)-[:BFO:0000050]->(region_or_blank) // or_blank happens if it is a union of regions i.e. a population with somas in more than one region //,(region_or_blank: Class{iri: "UBERON:0001950"}) //RETURN region_or_blank //RETURN neuron RETURN edge
select distinct ?p ?o where { # ilxtr:neuron-type-keast-1 ?p ?o ilxtr:neuron-type-keast-1 owl:equivalentClass ?b1 . ?b1 owl:intersectionOf ?b2 . ?b2 ?unkp ?b3 . # lists ?b3 owl:onProperty ?p . ?b3 owl:someValuesFrom ?o . }
select distinct ?neuron ?prop ?value ?prop2 ?value2 # ?p ?ox # ?p2 ?o2 # ?p3 # ?o3 ?p4 ?o4 ?p5 ?o5 ?p6 ?o6 where { #ilxtr:neuron-type-keast-1 owl:equivalentClass ?o . ?neuron a owl:Class . ?neuron ilxtr:simpleLocalLabel ?sll . # XXX hack to filter for neurons ?neuron owl:equivalentClass ?o . # ?o ?p2 ?o2 . ?o owl:intersectionOf ?list . ?list rdf:rest*/rdf:first ?elem . # FIXME at least one elem subClassOf neuron or cell ?elem a owl:Restriction . ?elem owl:onProperty ?prop . ?elem owl:someValuesFrom ?value . OPTIONAL { ?value a owl:Restriction . ?value owl:onProperty ?prop2 . ?value owl:someValuesFrom ?value2 . # ?value ?p ?ox . #OPTIONAL { #?ox ?p2 ?o2 . #?o2 a owl:Class . #} } # then do optional for location vs other types #?o3 ?p4 ?o4 . #?o4 ?p5 ?o5 . # first on property hits here #?o5 ?p6 ?o6 . # TODO list optional ??? } limit 300
MATCH path = (neuron) //MATCH path = (neuron:Class{iri: "ilxtr:neuron-type-keast-1"}) -[:equivalentClass|subClassOf]->(hrm) RETURN path
- python
- number of distinct phenotypes
- number of dimensions
- number of phenotype values per phenotype dimension
- location
- ApiNATOMY sourced