Skip to content

Commit 9c0348c

Browse files
committed
TransgeneExpressionHere: restore Expressed_in column
v2 prod's legacy ExpressionOverlapsHere result table carried an Expressed_in column listing the anatomy class(es) each EP overlaps (e.g. "pacemaker neuron"). The v1.10.x migration to VFBquery dropped it; the TODO at the top of get_transgene_expression_here flagged the missing column for a follow-up. This is that follow-up. Cypher: - WITH now collects `anat.label + '----' + anat.short_form` per distinct anat per ep (within the Owlery closure from v1.14.0), alongside the existing pub_shorts collection. - RETURN projects `expressed_in` capped at the first 5 entries with a `+N more` suffix so wide closures stay readable. Items joined with `; ` (matching the Reference column's stringDelimiter convention) and entity ids wrapped with `----` (matching the entityDelimiter convention) so the v2 frontend component can extract the click target. Schema: - AnatomyExpressedIn_to_schema gains `expressed_in` in preview_columns (between name and pubs). - get_transgene_expression_here's formatted-dict headers add `expressed_in: {title: "Expressed_in", type: "markdown", order: 1}`, shifting pubs/tags/template/technique orders one slot later. - encode_markdown_links is NOT called on expressed_in: the `; `-joined wire format is already what the V2 QueryLinkArrayComponent expects to receive verbatim; running it through the markdown-link encoder would corrupt the `----`-wrapped entity ids. Companion geppetto-vfb change switches the queryBuilderConfiguration entry for `expressed_in` from QueryLinkComponent (single link) to QueryLinkArrayComponent (clickable chip list), adds stringDelimiter ";", and keeps the existing entityDelimiter ("----"), entityIndex (1), and click action (window.addVfbId('$entity$')). Verified locally against pdb for pacemaker neuron (FBbt_00006048): P{GAL4-per.BS} -> "pacemaker neuron----FBbt_00006048" P{GAL4-tim.E} -> "pacemaker neuron----FBbt_00006048" P{GSV6}GS10340 -> "pacemaker neuron----FBbt_00006048" P{cry-GAL4.E} -> "pacemaker neuron----FBbt_00006048" matching v2 prod's single-value Expressed_in display for the same entity. Patch bump 1.14.2 -> 1.14.3. New column triggers natural cache invalidation via the result shape change.
1 parent a7021c2 commit 9c0348c

2 files changed

Lines changed: 27 additions & 16 deletions

File tree

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
here = path.abspath(path.dirname(__file__))
55

6-
__version__ = "1.14.2"
6+
__version__ = "1.14.3"
77

88
# Get the long description from the README file
99
with open(path.join(here, 'README.md')) as f:

src/vfbquery/vfb_queries.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,7 +1960,7 @@ def TransgeneExpressionHere_to_schema(name, take_default):
19601960
19611961
Query chain: Multi-step Owlery and Neo4j queries
19621962
"""
1963-
return Query(query="TransgeneExpressionHere", label=f"Transgene expression in {name}", function="get_transgene_expression_here", takes={"short_form": {"$and": ["Class", "Nervous_system", "Anatomy"]}, "default": take_default}, preview=5, preview_columns=["id", "name", "pubs", "tags", "template", "technique", "thumbnail"])
1963+
return Query(query="TransgeneExpressionHere", label=f"Transgene expression in {name}", function="get_transgene_expression_here", takes={"short_form": {"$and": ["Class", "Nervous_system", "Anatomy"]}, "default": take_default}, preview=5, preview_columns=["id", "name", "expressed_in", "pubs", "tags", "template", "technique", "thumbnail"])
19641964

19651965

19661966
def FindStocks_to_schema(name, take_default):
@@ -5424,11 +5424,14 @@ def get_transgene_expression_here(anatomy_short_form: str, return_dataframe=True
54245424
INSTANCEOF leaf subclasses, not the parent. Same closure pattern as
54255425
get_instances (v1.12.8).
54265426
5427-
TODO: Expressed_in column. Prod surfaces it from the
5428-
anatomy_channel_image[].anatomy.label list — one chip per
5429-
representative image. Needs a small design decision on how to
5430-
render multiple values in a flat string column; deferred to a
5431-
follow-up so the rest of the columns can ship now.
5427+
v1.14.3: adds Expressed_in column. Each EP row carries the leaf
5428+
anatomy classes its Individuals are INSTANCEOF (within the Owlery
5429+
closure of the queried class), formatted as
5430+
`label----short_form; label----short_form; ...` so the geppetto-vfb
5431+
QueryLinkArrayComponent renders one clickable chip per anat
5432+
(calling window.addVfbId on click). Capped at the first 5 with
5433+
`+N more` overflow so EPs that overlap large closures stay
5434+
readable.
54325435
"""
54335436
# Resolve the full subclass closure of the input anatomy class via
54345437
# Owlery. Owlery handles OWL inference (equivalence classes, defined
@@ -5468,7 +5471,9 @@ def get_transgene_expression_here(anatomy_short_form: str, return_dataframe=True
54685471
main_query = f"""
54695472
MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(:Individual)-[:INSTANCEOF]->(anat:Class)
54705473
WHERE anat.short_form IN {anat_short_forms!r}
5471-
WITH ep, collect(DISTINCT ar.pub[0]) AS pub_shorts
5474+
WITH ep,
5475+
collect(DISTINCT ar.pub[0]) AS pub_shorts,
5476+
collect(DISTINCT anat.label + '----' + anat.short_form) AS anat_pairs
54725477
ORDER BY ep.label
54735478
{limit_clause}
54745479
CALL {{
@@ -5496,6 +5501,11 @@ def get_transgene_expression_here(anatomy_short_form: str, return_dataframe=True
54965501
RETURN
54975502
ep.short_form AS id,
54985503
apoc.text.format("[%s](%s)", [ep.label, ep.short_form]) AS name,
5504+
CASE
5505+
WHEN size(anat_pairs) <= 5
5506+
THEN apoc.text.join(anat_pairs, '; ')
5507+
ELSE apoc.text.join(anat_pairs[0..5], '; ') + '; +' + toString(size(anat_pairs)-5) + ' more'
5508+
END AS expressed_in,
54995509
apoc.text.join(coalesce(ep.uniqueFacets, []), '|') AS tags,
55005510
pubs,
55015511
REPLACE(apoc.text.format("[%s](%s)", [COALESCE(templ.symbol[0], templ.label), templ.short_form]), '[null](null)', '') AS template,
@@ -5512,16 +5522,17 @@ def get_transgene_expression_here(anatomy_short_form: str, return_dataframe=True
55125522
return df
55135523
return {
55145524
"headers": {
5515-
"id": {"title": "ID", "type": "selection_id", "order": -1},
5516-
"name": {"title": "Expression Pattern", "type": "markdown", "order": 0},
5517-
"pubs": {"title": "Publications", "type": "metadata", "order": 1},
5518-
"tags": {"title": "Tags", "type": "tags", "order": 2},
5519-
"template": {"title": "Template", "type": "markdown", "order": 3},
5520-
"technique": {"title": "Imaging Technique", "type": "text", "order": 4},
5521-
"thumbnail": {"title": "Thumbnail", "type": "markdown", "order": 9},
5525+
"id": {"title": "ID", "type": "selection_id", "order": -1},
5526+
"name": {"title": "Expression Pattern","type": "markdown", "order": 0},
5527+
"expressed_in": {"title": "Expressed_in", "type": "markdown", "order": 1},
5528+
"pubs": {"title": "Publications", "type": "metadata", "order": 2},
5529+
"tags": {"title": "Tags", "type": "tags", "order": 3},
5530+
"template": {"title": "Template", "type": "markdown", "order": 4},
5531+
"technique": {"title": "Imaging Technique", "type": "text", "order": 5},
5532+
"thumbnail": {"title": "Thumbnail", "type": "markdown", "order": 9},
55225533
},
55235534
"rows": [
5524-
{k: row[k] for k in ['id', 'name', 'pubs', 'tags', 'template', 'technique', 'thumbnail']}
5535+
{k: row[k] for k in ['id', 'name', 'expressed_in', 'pubs', 'tags', 'template', 'technique', 'thumbnail']}
55255536
for row in safe_to_dict(df, sort_by_id=False)
55265537
],
55275538
"count": total_count,

0 commit comments

Comments
 (0)