Skip to content

Commit 8436abf

Browse files
committed
lower level test class, improve doc, increase timeout
1 parent 92d222a commit 8436abf

2 files changed

Lines changed: 50 additions & 20 deletions

File tree

src/test/test_query_performance.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -352,14 +352,18 @@ def test_07_connectivity_queries(self):
352352
print(f"NeuronRegionConnectivityQuery: {duration:.4f}s {'✅' if success else '❌'}")
353353
self.assertLess(duration, self.THRESHOLD_SLOW, "NeuronRegionConnectivityQuery exceeded threshold")
354354

355-
# FBbt_00001482 = lineage NB3-2 primary interneuron — known to have
356-
# downstream/upstream connectivity data in the vfb_json Solr core.
357-
CLASS_CONNECTIVITY_TEST_CLASS = "FBbt_00001482"
355+
# FBbt_00100234 = MBON01 — a specific mushroom body output neuron type
356+
# with a small instance count (preferred over broad lineage classes for
357+
# bounded test runtime). The class-level connectivity queries are a
358+
# multi-step aggregation (Neo4j + batched Solr + ancestor walk), not a
359+
# single Solr lookup, so cold-cache calls can take tens of seconds even
360+
# on a small class.
361+
CLASS_CONNECTIVITY_TEST_CLASS = "FBbt_00100234"
358362

359363
def test_07b_downstream_class_connectivity(self):
360-
"""Test DownstreamClassConnectivity query (pre-indexed Solr)"""
364+
"""Test DownstreamClassConnectivity query (multi-step aggregation)"""
361365
print("\n" + "="*80)
362-
print("DOWNSTREAM CLASS CONNECTIVITY (Solr pre-indexed)")
366+
print("DOWNSTREAM CLASS CONNECTIVITY (multi-step aggregation)")
363367
print("="*80)
364368

365369
result, duration, success = self._time_query(
@@ -369,12 +373,12 @@ def test_07b_downstream_class_connectivity(self):
369373
return_dataframe=False,
370374
)
371375
print(f"DownstreamClassConnectivity: {duration:.4f}s {'✅' if success else '❌'}")
372-
self.assertLess(duration, self.THRESHOLD_MEDIUM, "DownstreamClassConnectivity exceeded threshold")
376+
self.assertLess(duration, self.THRESHOLD_VERY_SLOW, "DownstreamClassConnectivity exceeded threshold")
373377

374378
def test_07b_upstream_class_connectivity(self):
375-
"""Test UpstreamClassConnectivity query (pre-indexed Solr)"""
379+
"""Test UpstreamClassConnectivity query (multi-step aggregation)"""
376380
print("\n" + "="*80)
377-
print("UPSTREAM CLASS CONNECTIVITY (Solr pre-indexed)")
381+
print("UPSTREAM CLASS CONNECTIVITY (multi-step aggregation)")
378382
print("="*80)
379383

380384
result, duration, success = self._time_query(
@@ -384,7 +388,7 @@ def test_07b_upstream_class_connectivity(self):
384388
return_dataframe=False,
385389
)
386390
print(f"UpstreamClassConnectivity: {duration:.4f}s {'✅' if success else '❌'}")
387-
self.assertLess(duration, self.THRESHOLD_MEDIUM, "UpstreamClassConnectivity exceeded threshold")
391+
self.assertLess(duration, self.THRESHOLD_VERY_SLOW, "UpstreamClassConnectivity exceeded threshold")
388392

389393
def test_07c_cross_dataset_connectivity(self):
390394
"""Test cross-dataset query_connectivity (live, both-end filtered)"""

src/vfbquery/vfb_queries.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,7 +1521,20 @@ def DownstreamClassConnectivity_to_schema(name, take_default):
15211521
Schema for downstream class connectivity query.
15221522
Shows which neuron classes receive synapses from this neuron class.
15231523
Matching criteria: Class + Neuron
1524-
Query chain: Solr downstream_connectivity_query field
1524+
1525+
Implementation: multi-step aggregation, not a single Solr lookup.
1526+
1. Neo4j: instances in the SUBCLASSOF closure of the queried class.
1527+
2. Solr cache (batched): per-instance synaptic partners.
1528+
3. Solr: direct partner classes from the downstream_connectivity_query
1529+
field (seed set for the partner-side ancestor walk).
1530+
4. Neo4j: walk SUBCLASSOF up from each direct partner to the neuron root.
1531+
5. Neo4j (batched): partner_instance -> {class_ids} membership map.
1532+
6. In-memory aggregation with set-union semantics to handle FBbt
1533+
multi-inheritance without double-counting.
1534+
1535+
Results are cached server-side (@with_solr_cache) per queried class, so
1536+
repeat calls return in milliseconds, but cold calls on broad classes can
1537+
take tens of seconds.
15251538
"""
15261539
query = "DownstreamClassConnectivity"
15271540
label = f"Downstream connectivity classes for {name}"
@@ -1540,7 +1553,11 @@ def UpstreamClassConnectivity_to_schema(name, take_default):
15401553
Schema for upstream class connectivity query.
15411554
Shows which neuron classes send synapses to this neuron class.
15421555
Matching criteria: Class + Neuron
1543-
Query chain: Solr upstream_connectivity_query field
1556+
1557+
Implementation: same multi-step aggregation as
1558+
DownstreamClassConnectivity but with the upstream_connectivity_query
1559+
Solr field as the seed for the partner-side ancestor walk. See
1560+
DownstreamClassConnectivity_to_schema for the full pipeline.
15441561
"""
15451562
query = "UpstreamClassConnectivity"
15461563
label = f"Upstream connectivity classes for {name}"
@@ -3404,13 +3421,19 @@ def get_downstream_class_connectivity(short_form: str, return_dataframe=True, li
34043421
"""
34053422
Retrieves downstream connectivity classes for the specified neuron class.
34063423
3407-
Uses OWLERY to expand subclasses of the queried class, fetches per-instance
3424+
Uses a Neo4j SUBCLASSOF traversal to enumerate instances of the queried
3425+
class (Owlery's get_instances was observed to hang for some classes;
3426+
Cypher is equivalent and fast here), bulk-fetches per-instance
34083427
connectivity from the Solr cache, and aggregates by partner class with
34093428
set-union semantics on partner instance memberships. The partner-side
3410-
hierarchy is walked up to ``NEURON_ROOT_SHORT_FORM`` so that connections to
3411-
a child class also count toward each ancestor class's row, without
3429+
hierarchy is walked up to ``NEURON_ROOT_SHORT_FORM`` so that connections
3430+
to a child class also count toward each ancestor class's row, without
34123431
double-counting under FBbt multi-inheritance.
34133432
3433+
Server-side cached via ``@with_solr_cache``; cold calls on broad classes
3434+
can take tens of seconds because of the aggregation work (already batched
3435+
across Solr/Neo4j round-trips).
3436+
34143437
Matching criteria: Class + Neuron
34153438
34163439
:param short_form: short form of the neuron class
@@ -3454,12 +3477,15 @@ def get_upstream_class_connectivity(short_form: str, return_dataframe=True, limi
34543477
"""
34553478
Retrieves upstream connectivity classes for the specified neuron class.
34563479
3457-
Uses OWLERY to expand subclasses of the queried class, fetches per-instance
3458-
connectivity from the Solr cache, and aggregates by partner class with
3459-
set-union semantics on partner instance memberships. The partner-side
3460-
hierarchy is walked up to ``NEURON_ROOT_SHORT_FORM`` so that connections
3461-
from a child class also count toward each ancestor class's row, without
3462-
double-counting under FBbt multi-inheritance.
3480+
Same multi-step aggregation as ``get_downstream_class_connectivity`` but
3481+
walking the upstream side: Neo4j SUBCLASSOF enumerates queried-class
3482+
instances, batched Solr cache fetches their synaptic partners, and the
3483+
partner-side hierarchy is walked up to ``NEURON_ROOT_SHORT_FORM`` with
3484+
set-union semantics to avoid double-counting under FBbt multi-inheritance.
3485+
3486+
Server-side cached via ``@with_solr_cache``; cold calls on broad classes
3487+
can take tens of seconds because of the aggregation work (already batched
3488+
across Solr/Neo4j round-trips).
34633489
34643490
Matching criteria: Class + Neuron
34653491

0 commit comments

Comments
 (0)