Commit 6587040
committed
Add get_template_roi_tree: Template ROI Browser endpoint
Replaces the legacy v2 frontend path where VFBTreeConfiguration.js POSTed
a multi-step Cypher with UNWIND nodes(p) AS n UNWIND nodes(p) AS m
straight to pdb.virtualflybrain.org (Basic neo4j:vfb baked in JS source).
That query timed out at 40s on JFRC2 in production; the new endpoint
returns the same tree in ~1.7s.
What this adds:
- get_template_roi_tree(template_short_form) in vfb_queries.py — a
single-statement Cypher (no UNWIND-pairs cartesian) that anchors on
the template's INSTANCEOF root Class, walks through part_of and
SUBCLASSOF (depth 0..20) down to every Class that has a painted-domain
Individual on this template, and returns the nodes / edges / painted
rows needed to assemble a tree in Python. Decorated with
@with_solr_cache('template_roi_tree') for the standard 90-day TTL.
- get_template_roi_tree_cached wrapper in cached_functions.py +
monkey-patch registration in patch_vfbquery_with_caching.
- "TemplateROIBrowser" entry in ha_api.QUERY_TYPE_MAP routing to
get_template_roi_tree.
Response shape — self-describing, single round trip:
{
"template": {"short_form", "label"},
"anatomy_root": {"short_form", "label"} | null,
"summary_md": markdown header / blurb for tooltips,
"tree": [
{
"id": "FBbt_…",
"label": str,
"painted_domain": [{"individual_id", "individual_label"}, ...],
"summary_md": markdown per-node tooltip,
"children": [...]
}
],
"painted_domain_index": {
"<individual_id>": {"class_id", "class_label"},
...
}
}
Design notes:
- painted_domain is always a LIST (empty when none). Adult T1 Leg has
bilateral L/R painted Individuals on the same Class; a single-value
field would silently drop one side.
- FBbt's DAG character is preserved — multi-parent classes (e.g. adult
cerebrum sits under both supraesophageal zone and central brain)
appear under each parent. Matches today's VFBTree behaviour. Cycle
guard via ancestor-chain tracking, not flattening.
- painted_domain_index is the reverse lookup the v2 visibility-toggle
handler needs: scene reports "Individual X just hidden" -> map back
to the Class node to grey the row.
- All IDs are short_form strings; no Neo4j internal ids (those aren't
stable across DB rebuilds, which the legacy query relied on).
- template_short_form is interpolated into a Cypher string literal
(matching every other query in this module — neo4j_client.commit_list
doesn't pass parameters). A new _VFB_SHORT_FORM_RE guard rejects
anything outside [A-Za-z0-9_]+ before interpolation.
Tested against 10 templates (snapshots in
projects/template-roi-browser/PROBE_NOTES.md): JRC2018Unisex, JFRC2,
JRC_FlyEM_Hemibrain, Ito2014, JRC2018UnisexVNC, VNS Court2018, L1 / L3
larval CNS, Adult T1 Leg, Adult Head. All cold-cache runs under 4s.
JFRC2 baseline: 70 unique nodes, 58 painted Individuals, depth 6 —
matches the v2-dev rendered tree byte-for-byte.
No __version__ bump — publish_to_pypi workflow seds the version from
the git tag.1 parent 2f1f2e8 commit 6587040
3 files changed
Lines changed: 239 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
79 | 80 | | |
80 | 81 | | |
81 | 82 | | |
| |||
324 | 325 | | |
325 | 326 | | |
326 | 327 | | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
327 | 351 | | |
328 | 352 | | |
329 | 353 | | |
| |||
737 | 761 | | |
738 | 762 | | |
739 | 763 | | |
| 764 | + | |
740 | 765 | | |
741 | 766 | | |
742 | 767 | | |
| |||
778 | 803 | | |
779 | 804 | | |
780 | 805 | | |
| 806 | + | |
781 | 807 | | |
782 | 808 | | |
783 | 809 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
311 | 311 | | |
312 | 312 | | |
313 | 313 | | |
| 314 | + | |
314 | 315 | | |
315 | 316 | | |
316 | 317 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4875 | 4875 | | |
4876 | 4876 | | |
4877 | 4877 | | |
| 4878 | + | |
| 4879 | + | |
| 4880 | + | |
| 4881 | + | |
| 4882 | + | |
| 4883 | + | |
| 4884 | + | |
| 4885 | + | |
| 4886 | + | |
| 4887 | + | |
| 4888 | + | |
| 4889 | + | |
| 4890 | + | |
| 4891 | + | |
| 4892 | + | |
| 4893 | + | |
| 4894 | + | |
| 4895 | + | |
| 4896 | + | |
| 4897 | + | |
| 4898 | + | |
| 4899 | + | |
| 4900 | + | |
| 4901 | + | |
| 4902 | + | |
| 4903 | + | |
| 4904 | + | |
| 4905 | + | |
| 4906 | + | |
| 4907 | + | |
| 4908 | + | |
| 4909 | + | |
| 4910 | + | |
| 4911 | + | |
| 4912 | + | |
| 4913 | + | |
| 4914 | + | |
| 4915 | + | |
| 4916 | + | |
| 4917 | + | |
| 4918 | + | |
| 4919 | + | |
| 4920 | + | |
| 4921 | + | |
| 4922 | + | |
| 4923 | + | |
| 4924 | + | |
| 4925 | + | |
| 4926 | + | |
| 4927 | + | |
| 4928 | + | |
| 4929 | + | |
| 4930 | + | |
| 4931 | + | |
| 4932 | + | |
| 4933 | + | |
| 4934 | + | |
| 4935 | + | |
| 4936 | + | |
| 4937 | + | |
| 4938 | + | |
| 4939 | + | |
| 4940 | + | |
| 4941 | + | |
| 4942 | + | |
| 4943 | + | |
| 4944 | + | |
| 4945 | + | |
| 4946 | + | |
| 4947 | + | |
| 4948 | + | |
| 4949 | + | |
| 4950 | + | |
| 4951 | + | |
| 4952 | + | |
| 4953 | + | |
| 4954 | + | |
| 4955 | + | |
| 4956 | + | |
| 4957 | + | |
| 4958 | + | |
| 4959 | + | |
| 4960 | + | |
| 4961 | + | |
| 4962 | + | |
| 4963 | + | |
| 4964 | + | |
| 4965 | + | |
| 4966 | + | |
| 4967 | + | |
| 4968 | + | |
| 4969 | + | |
| 4970 | + | |
| 4971 | + | |
| 4972 | + | |
| 4973 | + | |
| 4974 | + | |
| 4975 | + | |
| 4976 | + | |
| 4977 | + | |
| 4978 | + | |
| 4979 | + | |
| 4980 | + | |
| 4981 | + | |
| 4982 | + | |
| 4983 | + | |
| 4984 | + | |
| 4985 | + | |
| 4986 | + | |
| 4987 | + | |
| 4988 | + | |
| 4989 | + | |
| 4990 | + | |
| 4991 | + | |
| 4992 | + | |
| 4993 | + | |
| 4994 | + | |
| 4995 | + | |
| 4996 | + | |
| 4997 | + | |
| 4998 | + | |
| 4999 | + | |
| 5000 | + | |
| 5001 | + | |
| 5002 | + | |
| 5003 | + | |
| 5004 | + | |
| 5005 | + | |
| 5006 | + | |
| 5007 | + | |
| 5008 | + | |
| 5009 | + | |
| 5010 | + | |
| 5011 | + | |
| 5012 | + | |
| 5013 | + | |
| 5014 | + | |
| 5015 | + | |
| 5016 | + | |
| 5017 | + | |
| 5018 | + | |
| 5019 | + | |
| 5020 | + | |
| 5021 | + | |
| 5022 | + | |
| 5023 | + | |
| 5024 | + | |
| 5025 | + | |
| 5026 | + | |
| 5027 | + | |
| 5028 | + | |
| 5029 | + | |
| 5030 | + | |
| 5031 | + | |
| 5032 | + | |
| 5033 | + | |
| 5034 | + | |
| 5035 | + | |
| 5036 | + | |
| 5037 | + | |
| 5038 | + | |
| 5039 | + | |
| 5040 | + | |
| 5041 | + | |
| 5042 | + | |
| 5043 | + | |
| 5044 | + | |
| 5045 | + | |
| 5046 | + | |
| 5047 | + | |
| 5048 | + | |
| 5049 | + | |
| 5050 | + | |
| 5051 | + | |
| 5052 | + | |
| 5053 | + | |
| 5054 | + | |
| 5055 | + | |
| 5056 | + | |
| 5057 | + | |
| 5058 | + | |
| 5059 | + | |
| 5060 | + | |
| 5061 | + | |
| 5062 | + | |
| 5063 | + | |
| 5064 | + | |
| 5065 | + | |
| 5066 | + | |
| 5067 | + | |
| 5068 | + | |
| 5069 | + | |
| 5070 | + | |
| 5071 | + | |
| 5072 | + | |
| 5073 | + | |
| 5074 | + | |
| 5075 | + | |
| 5076 | + | |
| 5077 | + | |
| 5078 | + | |
| 5079 | + | |
| 5080 | + | |
| 5081 | + | |
| 5082 | + | |
| 5083 | + | |
| 5084 | + | |
| 5085 | + | |
| 5086 | + | |
| 5087 | + | |
| 5088 | + | |
| 5089 | + | |
4878 | 5090 | | |
4879 | 5091 | | |
4880 | 5092 | | |
| |||
0 commit comments