Skip to content

Commit 79a5fda

Browse files
authored
Merge pull request #61 from VirtualFlyBrain/fix/carousel-get-instances
Carousel multi-template query images + collapse multi-dataset rows
2 parents 68c3edc + 9e56149 commit 79a5fda

1 file changed

Lines changed: 52 additions & 9 deletions

File tree

src/vfbquery/vfb_queries.py

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,6 +2461,28 @@ def get_instances(short_form: str, return_dataframe=True, limit: int = -1):
24612461
# Convert the results to a DataFrame
24622462
df = pd.DataFrame.from_records(get_dict_cursor()(results))
24632463

2464+
# The registration + has_source MATCH yields one row per
2465+
# (instance, template, dataset). Collapse to one row per instance:
2466+
# - thumbnail -> the "; "-joined multi-image carousel the V2 Images column
2467+
# renders, DISTINCT (a template's thumbnail is identical across the
2468+
# instance's datasets, so it must not repeat), so the frontend can bring
2469+
# the loaded template's thumbnail to the front;
2470+
# - dataset -> a distinct ", "-joined list (an image from several
2471+
# datasets is one row listing them, not one row per dataset);
2472+
# - other columns take the first (representative) value; ORDER BY id kept.
2473+
if not df.empty and 'id' in df.columns and 'thumbnail' in df.columns:
2474+
def _join_distinct(series, sep):
2475+
seen = []
2476+
for v in series:
2477+
if isinstance(v, str) and v and v not in seen:
2478+
seen.append(v)
2479+
return sep.join(seen)
2480+
agg = {c: 'first' for c in df.columns if c not in ('id', 'thumbnail', 'dataset')}
2481+
agg['thumbnail'] = lambda s: _join_distinct(s, '; ')
2482+
if 'dataset' in df.columns:
2483+
agg['dataset'] = lambda s: _join_distinct(s, ', ')
2484+
df = df.groupby('id', as_index=False, sort=False).agg(agg)
2485+
24642486
columns_to_encode = ['label', 'parent', 'source', 'source_id', 'template', 'dataset', 'license', 'thumbnail']
24652487
df = encode_markdown_links(df, columns_to_encode)
24662488

@@ -2898,8 +2920,19 @@ def get_similar_neurons(neuron, similarity_score='NBLAST_score', return_datafram
28982920
WITH n2
28992921
OPTIONAL MATCH (n2)<-[:depicts]-(channel:Individual)-[ri:in_register_with]->(:Template)-[:depicts]->(templ:Template)
29002922
OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class)
2901-
WITH ri, templ, technique LIMIT 1
2902-
RETURN ri, templ, technique
2923+
WITH n2, collect({{ri: ri, templ: templ, technique: technique}}) AS aligns
2924+
WITH n2, [a IN aligns WHERE a.templ IS NOT NULL] AS va
2925+
RETURN
2926+
CASE WHEN size(va)=0 THEN null ELSE head(va).templ END AS templ,
2927+
CASE WHEN size(va)=0 THEN null ELSE head(va).technique END AS technique,
2928+
apoc.text.join([a IN va |
2929+
apoc.text.format("[![%s](%s '%s')](%s)", [
2930+
n2.label + " aligned to " + (CASE WHEN a.templ.symbol[0] <> '' THEN a.templ.symbol[0] ELSE a.templ.label END),
2931+
REPLACE(COALESCE(a.ri.thumbnail[0],''),'thumbnailT.png','thumbnail.png'),
2932+
n2.label + " aligned to " + (CASE WHEN a.templ.symbol[0] <> '' THEN a.templ.symbol[0] ELSE a.templ.label END),
2933+
a.templ.short_form + "," + n2.short_form
2934+
])
2935+
], '; ') AS thumbnails
29032936
}}
29042937
RETURN n2.short_form as id,
29052938
apoc.text.format("[%s](%s)", [n2.label, n2.short_form]) AS name,
@@ -2910,7 +2943,7 @@ def get_similar_neurons(neuron, similarity_score='NBLAST_score', return_datafram
29102943
CASE WHEN site:Deprecated THEN COALESCE(rx.accession[0],'') ELSE REPLACE(apoc.text.format("[%s](%s)",[rx.accession[0], (site.link_base[0] + rx.accession[0])]), '[null](null)', '') END AS source_id,
29112944
REPLACE(apoc.text.format("[%s](%s)",[CASE WHEN templ.symbol[0] <> '' THEN templ.symbol[0] ELSE templ.label END,templ.short_form]), '[null](null)', '') AS template,
29122945
coalesce(technique.label, '') AS technique,
2913-
REPLACE(apoc.text.format("[![%s](%s '%s')](%s)",[n2.label + " aligned to " + CASE WHEN templ.symbol[0] <> '' THEN templ.symbol[0] ELSE templ.label END, REPLACE(COALESCE(ri.thumbnail[0],""),"thumbnailT.png","thumbnail.png"), n2.label + " aligned to " + CASE WHEN templ.symbol[0] <> '' THEN templ.symbol[0] ELSE templ.label END, templ.short_form + "," + n2.short_form]), "[![null]( 'null')](null)", "") as thumbnail
2946+
thumbnails as thumbnail
29142947
ORDER BY score DESC"""
29152948

29162949
if limit != -1:
@@ -3009,9 +3042,9 @@ def get_individual_neuron_inputs(neuron_short_form: str, return_dataframe=True,
30093042
apoc.text.format("[%s](%s)", [b.label, b.short_form]) as Name,
30103043
apoc.text.format("[%s](%s)", [neuronType.label, neuronType.short_form]) as Type,
30113044
apoc.text.join(b.uniqueFacets, '|') as Gross_Type,
3012-
apoc.text.join(collect(apoc.text.format("[%s](%s)", [templ.label, templ.short_form])), ', ') as Template_Space,
3045+
apoc.text.join(collect(DISTINCT apoc.text.format("[%s](%s)", [templ.label, templ.short_form])), ', ') as Template_Space,
30133046
apoc.text.format("[%s](%s)", [imagingTechnique.label, imagingTechnique.short_form]) as Imaging_Technique,
3014-
apoc.text.join(collect(REPLACE(apoc.text.format("[![%s](%s '%s')](%s)",[b.label, REPLACE(COALESCE(image.thumbnail[0],""),"thumbnailT.png","thumbnail.png"), b.label, b.short_form]), "[![null]( 'null')](null)", "")), ' | ') as Images
3047+
apoc.text.join(collect(DISTINCT REPLACE(apoc.text.format("[![%s](%s '%s')](%s)",[b.label + " aligned to " + (CASE WHEN templ.symbol[0] <> '' THEN templ.symbol[0] ELSE templ.label END), REPLACE(COALESCE(image.thumbnail[0],""),"thumbnailT.png","thumbnail.png"), b.label + " aligned to " + (CASE WHEN templ.symbol[0] <> '' THEN templ.symbol[0] ELSE templ.label END), templ.short_form + "," + b.short_form]), "[![null]( 'null')](null)", "")), '; ') as Images
30153048
ORDER BY Weight Desc
30163049
"""
30173050

@@ -3575,9 +3608,19 @@ def get_neuron_neuron_connectivity(short_form: str, return_dataframe=True, limit
35753608
WITH oi
35763609
OPTIONAL MATCH (oi)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual)
35773610
OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class)
3578-
WITH channel, template, template_anat, technique, irw
3579-
LIMIT 1
3580-
RETURN channel, template, template_anat, technique, irw
3611+
WITH oi, collect({{irw: irw, template_anat: template_anat, technique: technique}}) AS aligns
3612+
WITH oi, [a IN aligns WHERE a.template_anat IS NOT NULL] AS va
3613+
RETURN
3614+
CASE WHEN size(va)=0 THEN null ELSE head(va).template_anat END AS template_anat,
3615+
CASE WHEN size(va)=0 THEN null ELSE head(va).technique END AS technique,
3616+
apoc.text.join([a IN va |
3617+
apoc.text.format("[![%s](%s '%s')](%s)", [
3618+
coalesce(oi.label,'image') + " aligned to " + (CASE WHEN a.template_anat.symbol[0] <> '' THEN a.template_anat.symbol[0] ELSE a.template_anat.label END),
3619+
REPLACE(COALESCE(a.irw.thumbnail[0],''),'thumbnailT.png','thumbnail.png'),
3620+
coalesce(oi.label,'image') + " aligned to " + (CASE WHEN a.template_anat.symbol[0] <> '' THEN a.template_anat.symbol[0] ELSE a.template_anat.label END),
3621+
a.template_anat.short_form + "," + oi.short_form
3622+
])
3623+
], '; ') AS thumbnails
35813624
}}
35823625
RETURN
35833626
oi.short_form AS id,
@@ -3588,7 +3631,7 @@ def get_neuron_neuron_connectivity(short_form: str, return_dataframe=True, limit
35883631
apoc.text.join(coalesce(oi.uniqueFacets, []), '|') AS tags,
35893632
REPLACE(apoc.text.format("[%s](%s)", [CASE WHEN template_anat.symbol[0] <> '' THEN template_anat.symbol[0] ELSE template_anat.label END, template_anat.short_form]), '[null](null)', '') AS template,
35903633
coalesce(technique.label, '') AS technique,
3591-
REPLACE(apoc.text.format("[![%s](%s '%s')](%s)", [coalesce(oi.label, 'image') + " aligned to " + CASE WHEN template_anat.symbol[0] <> '' THEN template_anat.symbol[0] ELSE template_anat.label END, REPLACE(COALESCE(irw.thumbnail[0], ''), 'thumbnailT.png', 'thumbnail.png'), coalesce(oi.label, 'image') + " aligned to " + CASE WHEN template_anat.symbol[0] <> '' THEN template_anat.symbol[0] ELSE template_anat.label END, template_anat.short_form + "," + oi.short_form]), "[![null]( 'null')](null)", "") AS thumbnail
3634+
thumbnails AS thumbnail
35923635
"""
35933636

35943637
results = vc.nc.commit_list([main_cypher])

0 commit comments

Comments
 (0)