File size: 2,674 Bytes
d5e0cb0
0f5d296
d5e0cb0
e202a39
d5e0cb0
eadeaf9
 
 
 
d5e0cb0
e202a39
d5e0cb0
eadeaf9
 
d5e0cb0
e202a39
d5e0cb0
eadeaf9
 
 
d5e0cb0
eadeaf9
 
 
 
 
 
 
 
e202a39
eadeaf9
 
 
 
d5e0cb0
eadeaf9
 
 
 
 
 
 
 
 
 
 
 
 
e202a39
eadeaf9
e202a39
 
eadeaf9
 
e202a39
 
 
 
 
 
 
 
 
eadeaf9
 
 
 
 
 
 
 
 
 
e202a39
eadeaf9
 
 
0f5d296
d5e0cb0
eadeaf9
a392df0
eadeaf9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# mcp/knowledge_graph.py

from streamlit_agraph import Node, Edge, Config
import re

# Set colors for node types
PAPER_COLOR = "#0984e3"
UMLS_COLOR = "#00b894"
DRUG_COLOR = "#d35400"

def build_agraph(papers, umls, drug_safety):
    """
    Build interactive agraph nodes and edges.
    Defensive: handles unexpected types gracefully.
    """
    nodes, edges = [], []

    # UMLS nodes
    for c in umls or []:
        if not isinstance(c, dict):
            continue
        cui = str(c.get("cui", "") or "")
        name = str(c.get("name", "") or "")
        if cui and name:
            nid = f"concept_{cui}"
            nodes.append(Node(
                id=nid, label=name, size=25, color=UMLS_COLOR,
                tooltip=f"UMLS {cui}: {name}"
            ))

    # Drug nodes
    drug_names = []
    for i, dr in enumerate(drug_safety or []):
        if not dr:
            continue
        # Normalize to single dict
        recs = dr if isinstance(dr, list) else [dr]
        for j, rec in enumerate(recs):
            if not isinstance(rec, dict):
                continue
            dn = rec.get("drug_name") \
                or (rec.get("patient", {}) or {}).get("drug", "") \
                or rec.get("medicinalproduct", "")
            dn = str(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=DRUG_COLOR,
                              tooltip=f"Drug: {dn}"))

    # Paper nodes and edges
    for k, p in enumerate(papers or []):
        pid = f"paper_{k}"
        title = str(p.get("title", f"Paper {k+1}"))
        summary = str(p.get("summary", ""))
        label = f"P{k+1}"
        nodes.append(Node(
            id=pid,
            label=label,
            tooltip=title,
            size=14,
            color=PAPER_COLOR,
        ))
        txt = (title + " " + summary).lower()
        # Link to concepts
        for c in umls or []:
            name = str(c.get("name", "") or "")
            cui = str(c.get("cui", "") or "")
            if name and name.lower() in txt and cui:
                edges.append(Edge(source=pid, target=f"concept_{cui}", label="mentions"))
        # Link to drugs
        for did, dn in drug_names:
            if dn and dn.lower() in txt:
                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"},
        link={"labelProperty": "label"},
    )
    return nodes, edges, config