Skip to content

Commit 5f54c3a

Browse files
committed
Refactor neuron-neuron connectivity query to improve terminology and output structure
1 parent ba94570 commit 5f54c3a

2 files changed

Lines changed: 46 additions & 31 deletions

File tree

VFB_QUERIES_REFERENCE.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -795,12 +795,13 @@ When implementing a new query, ensure:
795795
- Execution: `get_neuron_neuron_connectivity(term_id, return_dataframe=True, limit=-1, min_weight=0, direction='both')`
796796
- Tests: `src/test/test_neuron_neuron_connectivity.py`
797797
- Preview: 5 results
798-
- Preview Columns: id, label, downstream_weight, upstream_weight, tags
798+
- Preview Columns: id, partner_neuron, outputs, inputs, tags
799799
- Test neuron: VFB_jrchk00s (LPC1)
800800
- **Relationship**: Uses `synapsed_to` relationships (NOT `CONNECTED_TO`)
801801
- **Weight Filter**: Configurable via `min_weight` parameter (XMI spec uses > 1, default is 0)
802802
- **Direction Filter**: Optional `direction` parameter ('both', 'upstream', or 'downstream')
803803
- **Caching**: Only caches when all parameters are defaults (complete results)
804+
- **Terminology**: Uses VFB site conventions - "Partner Neuron", "Inputs" (upstream), "Outputs" (downstream)
804805

805806
**Parameters**:
806807
- `term_id`: Short form of the neuron (Individual)
@@ -820,9 +821,9 @@ WITH down, oi, primary
820821
OPTIONAL MATCH (primary)<-[up:synapsed_to]-(oi)
821822
RETURN
822823
oi.short_form AS id,
823-
oi.label AS label,
824-
coalesce(down.weight[0], 0) AS downstream_weight,
825-
coalesce(up.weight[0], 0) AS upstream_weight,
824+
oi.label AS partner_neuron,
825+
coalesce(down.weight[0], 0) AS outputs,
826+
coalesce(up.weight[0], 0) AS inputs,
826827
oi.uniqueFacets AS tags
827828
```
828829

@@ -831,9 +832,9 @@ RETURN
831832
{
832833
'headers': {
833834
'id': {'title': 'Neuron ID', 'type': 'selection_id', 'order': -1},
834-
'label': {'title': 'Neuron Name', 'type': 'markdown', 'order': 0},
835-
'downstream_weight': {'title': 'Downstream Weight', 'type': 'number', 'order': 1},
836-
'upstream_weight': {'title': 'Upstream Weight', 'type': 'number', 'order': 2},
835+
'partner_neuron': {'title': 'Partner Neuron', 'type': 'markdown', 'order': 0},
836+
'outputs': {'title': 'Outputs', 'type': 'number', 'order': 1},
837+
'inputs': {'title': 'Inputs', 'type': 'number', 'order': 2},
837838
'tags': {'title': 'Neuron Types', 'type': 'list', 'order': 3},
838839
},
839840
'data': [...],

src/vfbquery/vfb_queries.py

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,15 +2225,15 @@ def get_neuron_neuron_connectivity(short_form: str, return_dataframe=True, limit
22252225
Query chain (from XMI): Neo4j compound query → process
22262226
Matching criteria: Individual + Connected_neuron
22272227
2228-
Uses synapsed_to relationships to find connected neurons.
2229-
Returns upstream and downstream connection information.
2228+
Uses synapsed_to relationships to find partner neurons.
2229+
Returns inputs (upstream) and outputs (downstream) connection information.
22302230
22312231
:param short_form: short form of the neuron (Individual)
22322232
:param return_dataframe: Returns pandas dataframe if true, otherwise returns formatted dict
22332233
:param limit: maximum number of results to return (default -1, returns all results)
22342234
:param min_weight: minimum connection weight threshold (default 0, XMI spec uses 1)
22352235
:param direction: filter by connection direction - 'both' (default), 'upstream', or 'downstream'
2236-
:return: Neurons connected to the specified neuron with connection weights
2236+
:return: Partner neurons with their input/output connection weights
22372237
22382238
Note: Caching only applies when all parameters are at default values (complete results).
22392239
"""
@@ -2249,9 +2249,9 @@ def get_neuron_neuron_connectivity(short_form: str, return_dataframe=True, limit
22492249
OPTIONAL MATCH (primary)<-[up:synapsed_to]-(oi)
22502250
RETURN
22512251
oi.short_form AS id,
2252-
oi.label AS label,
2253-
coalesce(down.weight[0], 0) AS downstream_weight,
2254-
coalesce(up.weight[0], 0) AS upstream_weight,
2252+
oi.label AS partner_neuron,
2253+
coalesce(down.weight[0], 0) AS outputs,
2254+
coalesce(up.weight[0], 0) AS inputs,
22552255
oi.uniqueFacets AS tags
22562256
"""
22572257
if limit != -1:
@@ -2264,9 +2264,9 @@ def get_neuron_neuron_connectivity(short_form: str, return_dataframe=True, limit
22642264
# Filter by direction if specified
22652265
if direction != 'both':
22662266
if direction == 'upstream':
2267-
rows = [row for row in rows if row.get('upstream_weight', 0) > 0]
2267+
rows = [row for row in rows if row.get('inputs', 0) > 0]
22682268
elif direction == 'downstream':
2269-
rows = [row for row in rows if row.get('downstream_weight', 0) > 0]
2269+
rows = [row for row in rows if row.get('outputs', 0) > 0]
22702270

22712271
# Format output
22722272
if return_dataframe:
@@ -2275,9 +2275,9 @@ def get_neuron_neuron_connectivity(short_form: str, return_dataframe=True, limit
22752275

22762276
headers = {
22772277
'id': {'title': 'Neuron ID', 'type': 'selection_id', 'order': -1},
2278-
'label': {'title': 'Neuron Name', 'type': 'markdown', 'order': 0},
2279-
'downstream_weight': {'title': 'Downstream Weight', 'type': 'number', 'order': 1},
2280-
'upstream_weight': {'title': 'Upstream Weight', 'type': 'number', 'order': 2},
2278+
'partner_neuron': {'title': 'Partner Neuron', 'type': 'markdown', 'order': 0},
2279+
'outputs': {'title': 'Outputs', 'type': 'number', 'order': 1},
2280+
'inputs': {'title': 'Inputs', 'type': 'number', 'order': 2},
22812281
'tags': {'title': 'Neuron Types', 'type': 'list', 'order': 3},
22822282
}
22832283
return {
@@ -2306,7 +2306,8 @@ def get_images_neurons(short_form: str, return_dataframe=True, limit: int = -1):
23062306
:return: Individual neuron images with parts in the specified neuropil
23072307
"""
23082308
owl_query = f"<http://purl.obolibrary.org/obo/FBbt_00005106> and <http://purl.obolibrary.org/obo/RO_0002131> some <{_short_form_to_iri(short_form)}>"
2309-
return _owlery_instances_query_to_results(owl_query, short_form, return_dataframe, limit, solr_field='anat_image_query')
2309+
return _owlery_query_to_results(owl_query, short_form, return_dataframe, limit,
2310+
solr_field='anat_image_query', query_by_label=False, query_instances=True)
23102311

23112312

23122313
@with_solr_cache('images_that_develop_from')
@@ -2328,7 +2329,8 @@ def get_images_that_develop_from(short_form: str, return_dataframe=True, limit:
23282329
:return: Individual neuron images that develop from the specified neuroblast
23292330
"""
23302331
owl_query = f"<http://purl.obolibrary.org/obo/FBbt_00005106> and <http://purl.obolibrary.org/obo/RO_0002202> some <{_short_form_to_iri(short_form)}>"
2331-
return _owlery_instances_query_to_results(owl_query, short_form, return_dataframe, limit, solr_field='anat_image_query')
2332+
return _owlery_query_to_results(owl_query, short_form, return_dataframe, limit,
2333+
solr_field='anat_image_query', query_by_label=False, query_instances=True)
23322334

23332335

23342336
def _short_form_to_iri(short_form: str) -> str:
@@ -2392,7 +2394,8 @@ def get_expression_pattern_fragments(short_form: str, return_dataframe=True, lim
23922394
"""
23932395
iri = _short_form_to_iri(short_form)
23942396
owl_query = f"<http://purl.obolibrary.org/obo/BFO_0000050> some <{iri}>"
2395-
return _owlery_instances_query_to_results(owl_query, short_form, return_dataframe, limit, solr_field='anat_image_query')
2397+
return _owlery_query_to_results(owl_query, short_form, return_dataframe, limit,
2398+
solr_field='anat_image_query', query_by_label=False, query_instances=True)
23962399

23972400

23982401
def _get_neurons_part_here_headers():
@@ -2419,13 +2422,14 @@ def _get_standard_query_headers():
24192422

24202423
def _owlery_query_to_results(owl_query_string: str, short_form: str, return_dataframe: bool = True,
24212424
limit: int = -1, solr_field: str = 'anat_query',
2422-
include_source: bool = False, query_by_label: bool = True):
2425+
include_source: bool = False, query_by_label: bool = True,
2426+
query_instances: bool = False):
24232427
"""
2424-
Shared helper function for Owlery-based queries.
2428+
Unified helper function for Owlery-based queries.
24252429
24262430
This implements the common pattern:
2427-
1. Query Owlery for class IDs matching an OWL pattern
2428-
2. Fetch details from SOLR for each class
2431+
1. Query Owlery for class/instance IDs matching an OWL pattern
2432+
2. Fetch details from SOLR for each result
24292433
3. Format results as DataFrame or dict
24302434
24312435
:param owl_query_string: OWL query string (format depends on query_by_label parameter)
@@ -2435,15 +2439,25 @@ def _owlery_query_to_results(owl_query_string: str, short_form: str, return_data
24352439
:param solr_field: SOLR field to query (default 'anat_query' for Class, 'anat_image_query' for Individuals)
24362440
:param include_source: Whether to include source and source_id columns
24372441
:param query_by_label: If True, use label syntax with quotes. If False, use IRI syntax with angle brackets.
2442+
:param query_instances: If True, query for instances instead of subclasses
24382443
:return: Query results
24392444
"""
24402445
try:
2441-
# Step 1: Query Owlery for classes matching the OWL pattern
2442-
class_ids = vc.vfb.oc.get_subclasses(
2443-
query=owl_query_string,
2444-
query_by_label=query_by_label,
2445-
verbose=False
2446-
)
2446+
# Step 1: Query Owlery for classes or instances matching the OWL pattern
2447+
if query_instances:
2448+
result_ids = vc.vfb.oc.get_instances(
2449+
query=owl_query_string,
2450+
query_by_label=query_by_label,
2451+
verbose=False
2452+
)
2453+
else:
2454+
result_ids = vc.vfb.oc.get_subclasses(
2455+
query=owl_query_string,
2456+
query_by_label=query_by_label,
2457+
verbose=False
2458+
)
2459+
2460+
class_ids = result_ids # Keep variable name for compatibility
24472461

24482462
if not class_ids:
24492463
# No results found - return empty

0 commit comments

Comments
 (0)