Skip to content

tool(labfinder): rank labs for a project description, emitted as a forester tree - #46

Open
zubyul wants to merge 1 commit into
mainfrom
tool/labfinder-lab-routing
Open

tool(labfinder): rank labs for a project description, emitted as a forester tree#46
zubyul wants to merge 1 commit into
mainfrom
tool/labfinder-lab-routing

Conversation

@zubyul

@zubyul zubyul commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Someone describes a project at an event — the example that prompted this was unexpected death in prion proteomics — and the useful question isn't "what is known about this" but "whose lab could run it, is running it now, and would take it". Paper search answers the first. labfinder answers the second: it ranks labs (PI × institution), not papers.

What's here

  • bci/tools/labfinder/labfinder.ml — one file of plain OCaml. No dune, no libraries, no build step.
  • trees/lf-0001.tree — a worked result, committed as forest content.
  • trees/bcf-0074.tree — the tool's rationale; linked from the hub in bcf-0001.
ocaml bci/tools/labfinder/labfinder.ml "prion proteomics sudden unexplained death" \
  --facet "prion protein misfolding" \
  --facet "proteomics mass spectrometry brain" \
  --facet "sudden unexplained death" \
  --facet "neuropathology postmortem" \
  --since 2018 --n 10 > trees/lf-0001.tree

It emits .tree source. A ranking is forest content, not a web widget — no JavaScript is added, and the site stays static XML + XSLT. It also compiles if you want a binary (ocamlc 290 KB, ocamlopt 1.6 MB); nothing else is required, the JSON reader is in the file.

Three decisions that carry the ranking

  1. Facet decomposition. OpenAlex ANDs a long phrase: the full description as one query matched 32 papers and ranked an author with h=1, works=1 as a "lab". Four facets searched separately and fused give 798 unique works.
  2. Coverage bonus — score is multiplied by (facets matched)^1.5. The best lab sits at the intersection of a project's facets, not at the most-cited lab touching one of them. This is what puts Devinsky (SUDC/SUDEP and hippocampal proteomics) above labs with far more citations.
  3. Senior/corresponding author = PI. Last and corresponding weigh 1.0, first 0.35, middle 0.12, under a 3-year recency half-life, so the ranking points at labs active now. Evidence floor: ≥2 senior-author and ≥3 on-topic works, so a one-paper author can't rank.

Result for the prion case: Devinsky (NYU) 10.98 → Seyfried (Emory) 5.56 → Johnson (Emory) 4.95 → Bennett (Rush) 3.22 → Levey (Emory) 3.14.

Things a reviewer should know

  • Scope. CONTRIBUTING.md frames contributions as four factory stages; a lab-routing tool doesn't map onto any of them. It's offline analysis outside the 4.0ms decode path — no critical-path latency, no trit-parity obligation. Reject on scope if that's the call.
  • curl dependency. OpenAlex is HTTPS-only and the forester opam switch has cohttp-eio but no tls/ca-certs, so the raw GET is delegated to curl. Parsing, scoring, forester-escaping and emission are all OCaml. Adding tls ca-certs to the switch would close this.
  • Forester escaping. Paper titles contain %, backslashes, # and unbalanced parens — each a fatal parse error. The emitter escapes all of them; that's why escape looks paranoid.
  • Unrelated pre-existing bug, not fixed here. build-bci.sh calls ./forester build --config "$FORESTER_CONFIG", but forester 4.3.1 dropped --config (it's positional now). It fails identically on untouched main, producing zero output files. One-line fix: ./forester build "$FORESTER_CONFIG". Happy to send separately.

Verified: builds green via bci-forest.toml with the opam forester (41,686 files); lf-0001.xml renders and resolves as a first-class addressed tree with backlinks.

Ranks PI x institution rather than papers, so a project described in
conversation can be routed to a lab that could actually host it.

- faceted retrieval: one long phrase ANDs to ~32 works; four facets fuse to 1592
- coverage bonus (facets^1.5): the right lab is at the intersection of facets
- senior/corresponding author = PI, 3y recency half-life, evidence floor
- --trace reconstructs forward lineage from publications, since neurotree
  sits behind a validation wall and Wikidata has identity but not lineage

Offline analysis, outside the 4.0ms decode path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant