|
|
|
|
|
from streamlit_agraph import Node, Edge, Config |
|
import re |
|
|
|
def build_agraph(papers, umls, drug_safety): |
|
""" |
|
Build interactive agraph nodes and edges. |
|
Handles drug_safety entries that may be dict or list. |
|
""" |
|
|
|
nodes, edges = [], [] |
|
|
|
|
|
for c in umls: |
|
cui = c.get("cui") |
|
name = c.get("name", "") |
|
if cui and name: |
|
nid = f"concept_{cui}" |
|
nodes.append(Node(id=nid, label=name, size=25, color="#00b894")) |
|
|
|
|
|
drug_names = [] |
|
for i, dr in enumerate(drug_safety): |
|
if not dr: |
|
continue |
|
|
|
|
|
recs = dr if isinstance(dr, list) else [dr] |
|
for j, rec in enumerate(recs): |
|
|
|
dn = rec.get("drug_name") or rec.get("patient", {}).get("drug", "") or rec.get("medicinalproduct", "") |
|
dn = dn or f"drug_{i}_{j}" |
|
did = f"drug_{i}_{j}" |
|
drug_names.append((did, dn)) |
|
nodes.append(Node(id=did, label=dn, size=25, color="#d35400")) |
|
|
|
|
|
for pi, p in enumerate(papers): |
|
pid = f"paper_{pi}" |
|
nodes.append(Node(id=pid, label=f"P{pi+1}", tooltip=p["title"], size=15, color="#0984e3")) |
|
|
|
text = f"{p.get('title','')} {p.get('summary','')}".lower() |
|
|
|
for c in umls: |
|
cname = c.get("name", "") |
|
cui = c.get("cui") |
|
if cname and cui and cname.lower() in text: |
|
edges.append(Edge(source=pid, target=f"concept_{cui}", label="mentions")) |
|
|
|
for did, dn in drug_names: |
|
if dn.lower() in text: |
|
edges.append(Edge(source=pid, target=did, label="mentions")) |
|
|
|
config = Config( |
|
width="100%", height="600", directed=False, |
|
nodeHighlightBehavior=True, highlightColor="#f1c40f", |
|
collapsible=True, |
|
node={"labelProperty": "label"} |
|
) |
|
return nodes, edges, config |
|
|