Skip to content

Commit 3ac5787

Browse files
committed
anatScRNAseqQuery: walk SUBCLASSOF so parent classes match subclass Clusters
v1.13.2's get_anatomy_scrnaseq matched (primary {short_form: $id})<-[:composed_primarily_of]-(c:Cluster) which only catches Clusters bound to the exact class. But the indexer sets `hasScRNAseq` on a parent class whenever ANY subclass has a Cluster, so any class queried through anatScRNAseqQuery whose own Clusters all live on subclasses returns 0 - even though the v2 frontend correctly offers the query because the supertype constraint (Class + Anatomy + hasScRNAseq) matches. Canonical case (the one Robbie spotted on v2-dev): pacemaker neuron (FBbt_00006048) -> 0 direct Clusters -> 3 via subclasses: adult pacemaker neuron, LNv neuron, DN1 neuron Fix: walk (primary)<-[:SUBCLASSOF*0..]-(sub:Class) before binding the Cluster match, with a `WITH DISTINCT primary, c, ds` step before the pub gather so DAG-multi-path doesn't duplicate pubs across rows. Same shape as v1.12.8's ListAllAvailableImages fix; the INSTANCEOF-needs-Owlery caveat ([[vfb_neo4j_instanceof_semantics]]) doesn't apply here because Clusters bind to Classes via composed_primarily_of, not the leaf-only INSTANCEOF path. Verified against pdb for six test cases: FBbt_00006048 pacemaker neuron was 0 -> 3 clusters, 1 dataset FBbt_00100163 adult pacemaker neuron 3 clusters, 1 dataset FBbt_00004046 LNv neuron leaf 1 cluster (no regression) FBbt_00003629 DN1 neuron leaf 1 cluster (no regression) FBbt_00003748 medulla 0 (no false hits) FBbt_00003624 adult brain (root) 0 (big walk safe) All sub-0.4s cold. No __version__ bump.
1 parent 6cdba4f commit 3ac5787

1 file changed

Lines changed: 19 additions & 6 deletions

File tree

src/vfbquery/vfb_queries.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4182,25 +4182,38 @@ def get_anatomy_scrnaseq(anatomy_short_form: str, return_dataframe=True, limit:
41824182
:rtype: pandas.DataFrame or dict
41834183
"""
41844184

4185-
# Count query
4185+
# `hasScRNAseq` on a parent class is set by the indexer when ANY
4186+
# subclass has a Cluster composed_primarily_of it, so the
4187+
# narrow MATCH (primary)<-[:composed_primarily_of]-(c:Cluster) pattern
4188+
# returns 0 on parent classes with scRNAseq-bearing subclasses
4189+
# (e.g. pacemaker neuron FBbt_00006048: 0 direct, 3 via subclasses
4190+
# adult pacemaker neuron / LNv neuron / DN1 neuron). Walk SUBCLASSOF*0..
4191+
# so subclass-attached Clusters are included, matching the indexer's
4192+
# propagation semantics. SUBCLASSOF-only is safe here — Clusters bind
4193+
# to Classes via composed_primarily_of (not the leaf-only INSTANCEOF
4194+
# path that needed Owlery in get_instances v1.12.8); the class
4195+
# hierarchy in Neo4j is complete enough for this walk.
41864196
count_query = f"""
41874197
MATCH (primary:Class:Anatomy)
41884198
WHERE primary.short_form = '{anatomy_short_form}'
41894199
WITH primary
4190-
MATCH (primary)<-[:composed_primarily_of]-(c:Cluster)-[:has_source]->(ds:scRNAseq_DataSet)
4191-
RETURN COUNT(c) AS total_count
4200+
MATCH (primary)<-[:SUBCLASSOF*0..]-(sub:Class)
4201+
MATCH (sub)<-[:composed_primarily_of]-(c:Cluster)-[:has_source]->(ds:scRNAseq_DataSet)
4202+
RETURN COUNT(DISTINCT c) AS total_count
41924203
"""
4193-
4204+
41944205
count_results = vc.nc.commit_list([count_query])
41954206
count_df = pd.DataFrame.from_records(get_dict_cursor()(count_results))
41964207
total_count = count_df['total_count'][0] if not count_df.empty else 0
4197-
4208+
41984209
# Main query: get clusters with dataset and publication info
41994210
main_query = f"""
42004211
MATCH (primary:Class:Anatomy)
42014212
WHERE primary.short_form = '{anatomy_short_form}'
42024213
WITH primary
4203-
MATCH (primary)<-[:composed_primarily_of]-(c:Cluster)-[:has_source]->(ds:scRNAseq_DataSet)
4214+
MATCH (primary)<-[:SUBCLASSOF*0..]-(sub:Class)
4215+
MATCH (sub)<-[:composed_primarily_of]-(c:Cluster)-[:has_source]->(ds:scRNAseq_DataSet)
4216+
WITH DISTINCT primary, c, ds
42044217
OPTIONAL MATCH (ds)-[:has_reference]->(p:pub)
42054218
WITH {{
42064219
short_form: c.short_form,

0 commit comments

Comments
 (0)