SPB Git

spb/wp44_uqo

Public

WP44: taxonomy validation design + raters, emerging-detection framework, category flows, linkage sample (A-003)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Nov 3, 2026) parent f168fc7 Browse files

8 changed files +579 −0

added experiments/emerging_detection.py +122 −0
@@ -0,0 +1,122 @@
1 +#!/usr/bin/env python3
2 +"""WP44 — Phase 6: emerging-research detection framework (RQ10, hypothesis H8), strictly out-of-time.
3 +
4 +Units: OpenAlex topics (T-ids) restricted to those with >= 50 corpus works over 2018–2026 (topic-level series are the
5 +most reproducible unit; semantic clusters are an extension in experiments/emerging_clusters.py).
6 +Monthly panel from the eligible corpus (month-precision records only): n_{k,t} works per topic k and month t; citation
7 +inflow c_{k,t} (internal citations received in month t by works of topic k, from cit_edges_internal with citing first
8 +month); cross-area share x_{k,t}; mean novelty (optional, from embeddings) z_{k,t}.
9 +
10 +Signals at cutoff T (use data <= T only; all means/sd computed on the trailing window ending at T):
11 + g12 growth of 12-month volume vs previous 12 months (log ratio)
12 + acc acceleration: g12 at T minus g12 at T-12
13 + zvol z-score of the last 3 months' volume against the trailing 24-month mean/sd
14 + cit_acc log ratio of citation inflow last 12 months vs previous 12
15 + xshare cross-area share of references in the last 12 months (interdisciplinary connectivity)
16 + share topic share of corpus volume (size control)
17 + age months since first appearance (>= 5 works)
18 +Label at horizon h (12 or 24 months): emerging_{k,T,h} = 1 if the topic's growth g_h over (T, T+h] is in the top decile
19 +among topics with >= 20 works in (T-12, T], AND its absolute volume in (T, T+h] >= 2x the volume in (T-h, T].
20 +Models: z-score baseline (rank by zvol), logistic regression (L2) and gradient boosting trained on cutoffs
21 +<= 2021-12 (labels observed by 2023-12) and tested on cutoffs 2023-01 … 2024-10 (labels observed by 2026-10).
22 +Metrics: AUC, precision@20/50, lead time on the preregistered known-emergence set (protocol P1, H8).
23 +Outputs: results/emerging/{panel.parquet, features.parquet, metrics.json, predictions.csv, known_set_lead_times.csv}.
24 +"""
25 +import argparse, json, os, duckdb, numpy as np, pandas as pd
26 +
27 +KNOWN_SET = { # preregistered (protocol P1, H8): OpenAlex topic ids mapped after taxonomy work; filled by experiments/known_set.csv
28 +}
29 +
30 +
31 +def build_panel(root, con, last_month):
32 + con.execute(f"""CREATE OR REPLACE TABLE em_panel AS
33 + WITH W AS (SELECT c.id, c.first_month AS m, t.topic_id FROM corpus_works c JOIN oa_work_topics t ON t.work_id = c.id AND t.rank = 0
34 + WHERE c.eligible AND c.date_precision = 'month' AND c.first_month BETWEEN '2018-01' AND '{last_month}'),
35 + V AS (SELECT topic_id, m, count(*) n FROM W GROUP BY 1,2),
36 + C AS (SELECT w.topic_id, cw.first_month AS m, count(*) c FROM cit_edges_internal e JOIN W w ON w.id = e.cited_id
37 + JOIN corpus_works cw ON cw.id = e.citing_id WHERE cw.date_precision = 'month' GROUP BY 1,2)
38 + SELECT v.topic_id, v.m, v.n, coalesce(c.c, 0) AS c FROM V v LEFT JOIN C c USING (topic_id, m)""")
39 + df = con.execute("SELECT * FROM em_panel").df()
40 + keep = df.groupby("topic_id")["n"].sum(); keep = keep[keep >= 50].index
41 + df = df[df.topic_id.isin(keep)]
42 + months = pd.period_range("2018-01", last_month, freq="M").strftime("%Y-%m")
43 + P = df.pivot_table(index="topic_id", columns="m", values="n", fill_value=0).reindex(columns=months, fill_value=0)
44 + C = df.pivot_table(index="topic_id", columns="m", values="c", fill_value=0).reindex(columns=months, fill_value=0)
45 + return P, C
46 +
47 +
48 +def features_at(P, C, T_idx):
49 + """Signals computed with columns <= T_idx only."""
50 + n = P.values; c = C.values
51 + def win(a, lo, hi): # sum over columns (lo, hi]
52 + lo = max(lo, -1); return a[:, lo + 1:hi + 1].sum(1)
53 + v12 = win(n, T_idx - 12, T_idx); v12p = win(n, T_idx - 24, T_idx - 12); v12pp = win(n, T_idx - 36, T_idx - 24)
54 + g12 = np.log1p(v12) - np.log1p(v12p); g12p = np.log1p(v12p) - np.log1p(v12pp)
55 + last3 = win(n, T_idx - 3, T_idx) / 3.0
56 + trail = n[:, max(0, T_idx - 27):T_idx - 3 + 1]
57 + zvol = (last3 - trail.mean(1)) / (trail.std(1) + 1e-6)
58 + c12 = win(c, T_idx - 12, T_idx); c12p = win(c, T_idx - 24, T_idx - 12)
59 + cit_acc = np.log1p(c12) - np.log1p(c12p)
60 + cum = n[:, :T_idx + 1].cumsum(1); first = (cum >= 5).argmax(1); age = np.where(cum[:, -1] >= 5, T_idx - first, -1)
61 + share = v12 / max(v12.sum(), 1)
62 + return pd.DataFrame({"topic_id": P.index, "T_idx": T_idx, "v12": v12, "g12": g12, "acc": g12 - g12p, "zvol": zvol, "cit_acc": cit_acc,
63 + "share": share, "age": age, "c12": c12})
64 +
65 +
66 +def labels_at(P, T_idx, h):
67 + n = P.values
68 + pre = n[:, max(0, T_idx - h + 1):T_idx + 1].sum(1); post = n[:, T_idx + 1:T_idx + h + 1].sum(1)
69 + base12 = n[:, max(0, T_idx - 11):T_idx + 1].sum(1)
70 + g = np.log1p(post) - np.log1p(pre)
71 + elig = base12 >= 20
72 + thr = np.quantile(g[elig], 0.9) if elig.sum() > 10 else np.inf
73 + lab = ((g >= thr) & (post >= 2 * np.maximum(pre, 1)) & elig).astype(int)
74 + return pd.DataFrame({"topic_id": P.index, "T_idx": T_idx, "label": lab, "g_future": g, "eligible": elig})
75 +
76 +
77 +def main():
78 + ap = argparse.ArgumentParser(); ap.add_argument("--root", required=True); ap.add_argument("--last-month", default="2026-10")
79 + ap.add_argument("--horizon", type=int, default=12); a = ap.parse_args(); R = a.root
80 + out = os.path.join(R, "results/emerging"); os.makedirs(out, exist_ok=True)
81 + con = duckdb.connect(os.path.join(R, "data/processed/wp44.duckdb")); con.execute("SET threads TO 20; SET memory_limit='60GB';")
82 + P, C = build_panel(R, con, a.last_month); P.to_parquet(f"{out}/panel_volume.parquet"); C.to_parquet(f"{out}/panel_citations.parquet")
83 + months = list(P.columns); h = a.horizon
84 + def idx(m): return months.index(m)
85 + train_cuts = [idx(m) for m in months if "2019-12" <= m <= "2021-12" and idx(m) % 3 == 0]
86 + test_cuts = [idx(m) for m in months if "2023-01" <= m <= "2024-10" and idx(m) % 3 == 0 and idx(m) + h < len(months)]
87 + rows = []
88 + for T in train_cuts + test_cuts:
89 + f = features_at(P, C, T); l = labels_at(P, T, h); rows.append(f.merge(l, on=["topic_id", "T_idx"]))
90 + D = pd.concat(rows); D["split"] = np.where(D.T_idx.isin(train_cuts), "train", "test"); D = D[D.eligible]
91 + D.to_parquet(f"{out}/features.parquet")
92 + feats = ["g12", "acc", "zvol", "cit_acc", "share", "age"]
93 + from sklearn.linear_model import LogisticRegression
94 + from sklearn.ensemble import GradientBoostingClassifier
95 + from sklearn.metrics import roc_auc_score
96 + tr = D[D.split == "train"]; te = D[D.split == "test"]
97 + X = lambda d: d[feats].replace([np.inf, -np.inf], 0).fillna(0).values
98 + models = {"zscore_baseline": None, "logistic": LogisticRegression(C=1.0, max_iter=2000), "gbm": GradientBoostingClassifier(n_estimators=300, max_depth=3, learning_rate=0.05, random_state=44)}
99 + metrics = {"horizon": h, "n_train": int(len(tr)), "n_test": int(len(te)), "pos_rate_train": float(tr.label.mean()), "pos_rate_test": float(te.label.mean()),
100 + "train_cutoffs": [months[i] for i in train_cuts], "test_cutoffs": [months[i] for i in test_cuts]}
101 + preds = te[["topic_id", "T_idx", "label", "g_future"]].copy()
102 + for name, m in models.items():
103 + if m is None:
104 + s = te["zvol"].values
105 + else:
106 + m.fit(X(tr), tr.label); s = m.predict_proba(X(te))[:, 1]
107 + preds[name] = s
108 + res = {"auc": float(roc_auc_score(te.label, s))}
109 + for k in (20, 50):
110 + pk = []
111 + for T, g in preds.groupby("T_idx"):
112 + top = g.nlargest(k, name); pk.append(top.label.mean())
113 + res[f"precision_at_{k}"] = float(np.mean(pk))
114 + metrics[name] = res
115 + # per-cutoff AUC stability
116 + metrics["auc_by_cutoff"] = {months[T]: {n: float(roc_auc_score(g.label, g[n])) if g.label.nunique() > 1 else None for n in models} for T, g in preds.groupby("T_idx")}
117 + preds["month"] = [months[i] for i in preds.T_idx]; preds.to_csv(f"{out}/predictions.csv", index=False)
118 + json.dump(metrics, open(f"{out}/metrics_h{h}.json", "w"), indent=1); print(json.dumps({k: v for k, v in metrics.items() if k != "auc_by_cutoff"}, indent=1))
119 +
120 +
121 +if __name__ == "__main__":
122 + main()
added knowledge_graph/02_category_flows.py +58 −0
@@ -0,0 +1,58 @@
1 +#!/usr/bin/env python3
2 +"""WP44 — RQ4/RQ5 category-level citation flows and co-classification (after taxonomy/classify.py).
3 +
4 +Inputs: cit_edges_internal (knowledge_graph/01), classification tables (work_categories, work_primary), corpus_works.
5 +Outputs (results/graph/): category_flows_yearly.csv (citing year × citing primary category × cited primary category, counts and
6 +row shares), area_flows_yearly.csv (same at area level), cross_area_share_yearly.csv (share of citations leaving the citing
7 +work's area, by citing area), category_cooccurrence_yearly.csv (works carrying both categories), category_counts_yearly.csv
8 +(works per category per year, multi-label and primary), modularity_yearly.csv (modularity of the yearly category citation
9 +network with categories as communities and with areas as communities — Newman–Girvan Q on the directed weighted graph)."""
10 +import argparse, os, json, duckdb, yaml, numpy as np, pandas as pd
11 +
12 +
13 +def modularity(W, groups):
14 + """Newman–Girvan modularity for a weighted directed graph with adjacency W (i→j) and community labels."""
15 + m = W.sum(); kout = W.sum(1); kin = W.sum(0)
16 + g = np.asarray(groups); same = g[:, None] == g[None, :]
17 + return float(((W - np.outer(kout, kin) / m) * same).sum() / m)
18 +
19 +
20 +def main():
21 + ap = argparse.ArgumentParser(); ap.add_argument("--root", required=True); ap.add_argument("--ontology", required=True); a = ap.parse_args(); R = a.root
22 + out = os.path.join(R, "results/graph"); os.makedirs(out, exist_ok=True)
23 + ont = yaml.safe_load(open(a.ontology)); cat_area = {c["id"]: c["area"] for c in ont["categories"]}; cats = [c["id"] for c in ont["categories"]]
24 + con = duckdb.connect(os.path.join(R, "data/processed/wp44.duckdb")); con.execute("SET threads TO 24; SET memory_limit='70GB';")
25 + con.execute(f"CREATE OR REPLACE VIEW work_primary AS SELECT * FROM read_parquet('{R}/data/processed/classification/primary/*.parquet')")
26 + con.execute(f"CREATE OR REPLACE VIEW work_categories AS SELECT * FROM read_parquet('{R}/data/processed/classification/cats/*.parquet')")
27 + con.execute("CREATE OR REPLACE TEMP TABLE area_map AS SELECT * FROM (VALUES " + ",".join(f"('{c}','{cat_area[c]}')" for c in cats) + ") t(category_id, area)")
28 + con.execute("""CREATE OR REPLACE TABLE category_flows_yearly AS
29 + SELECT e.citing_year, pa.primary_category AS citing_cat, pb.primary_category AS cited_cat, count(*) n
30 + FROM cit_edges_internal e JOIN work_primary pa ON pa.work_id = e.citing_id JOIN work_primary pb ON pb.work_id = e.cited_id GROUP BY 1,2,3""")
31 + con.execute(f"COPY (SELECT *, n*1.0/sum(n) OVER (PARTITION BY citing_year, citing_cat) AS row_share FROM category_flows_yearly ORDER BY 1,2,4 DESC) TO '{out}/category_flows_yearly.csv' (HEADER)")
32 + con.execute(f"""COPY (SELECT f.citing_year, a1.area AS citing_area, a2.area AS cited_area, sum(n) n FROM category_flows_yearly f JOIN area_map a1 ON a1.category_id = f.citing_cat JOIN area_map a2 ON a2.category_id = f.cited_cat
33 + GROUP BY 1,2,3 ORDER BY 1,2,4 DESC) TO '{out}/area_flows_yearly.csv' (HEADER)""")
34 + con.execute(f"""COPY (SELECT citing_year, citing_area, sum(n) n, sum(CASE WHEN citing_area <> cited_area THEN n ELSE 0 END) n_cross, round(sum(CASE WHEN citing_area <> cited_area THEN n ELSE 0 END)*1.0/sum(n),4) share_cross
35 + FROM read_csv_auto('{out}/area_flows_yearly.csv') GROUP BY 1,2 ORDER BY 1,2) TO '{out}/cross_area_share_yearly.csv' (HEADER)""")
36 + con.execute(f"""COPY (SELECT c.publication_year AS year, a.category_id AS cat_a, b.category_id AS cat_b, count(*) n FROM work_categories a JOIN work_categories b ON a.work_id = b.work_id AND a.category_id < b.category_id
37 + JOIN corpus_works c ON c.id = a.work_id WHERE c.eligible GROUP BY 1,2,3 ORDER BY 1,4 DESC) TO '{out}/category_cooccurrence_yearly.csv' (HEADER)""")
38 + con.execute(f"""COPY (SELECT c.publication_year AS year, c.period, k.category_id, count(*) n_multilabel, sum((p.primary_category = k.category_id)::int) n_primary
39 + FROM work_categories k JOIN corpus_works c ON c.id = k.work_id JOIN work_primary p ON p.work_id = k.work_id WHERE c.eligible GROUP BY 1,2,3 ORDER BY 1,3) TO '{out}/category_counts_yearly.csv' (HEADER)""")
40 + con.execute(f"""COPY (SELECT c.first_month, c.period, k.category_id, count(*) n_multilabel, sum((p.primary_category = k.category_id)::int) n_primary, sum((c.date_precision='month')::int) n_month_precision
41 + FROM work_categories k JOIN corpus_works c ON c.id = k.work_id JOIN work_primary p ON p.work_id = k.work_id WHERE c.eligible GROUP BY 1,2,3 ORDER BY 1,3) TO '{out}/category_counts_monthly.csv' (HEADER)""")
42 + rows = []
43 + df = pd.read_csv(f"{out}/category_flows_yearly.csv")
44 + idx = {c: i for i, c in enumerate(cats)}
45 + for y, g in df.groupby("citing_year"):
46 + W = np.zeros((len(cats), len(cats)))
47 + for r in g.itertuples():
48 + if r.citing_cat in idx and r.cited_cat in idx:
49 + W[idx[r.citing_cat], idx[r.cited_cat]] += r.n
50 + if W.sum() == 0:
51 + continue
52 + rows.append({"year": int(y), "edges": float(W.sum()), "Q_categories": modularity(W, cats), "Q_areas": modularity(W, [cat_area[c] for c in cats]),
53 + "self_share": float(np.trace(W) / W.sum())})
54 + pd.DataFrame(rows).to_csv(f"{out}/modularity_yearly.csv", index=False); print(pd.DataFrame(rows))
55 +
56 +
57 +if __name__ == "__main__":
58 + main()
modified protocol/amendments.csv +1 −0
@@ -2,3 +2,4 @@ id,date,phase,change,reason,approved_by
2 2 A-000,2026-11-02,0,"§14 of the mandate completed from §1–§13 (paste truncated)","terminal truncation of the pasted mandate",executing agent (pending PI)
3 3 A-001,2026-11-03,1,"Eligibility type list corrected: OpenAlex (2026) types conference-paper and software-paper are research outputs and are kept; DBLP-linked records are kept whatever their OpenAlex type unless in a hard-exclusion list; XPAC records are kept when DBLP-linked (flag xpac_kept_dblp)","first run of define_corpus.py showed 2.5 M conference-paper records (1.09 M DBLP-linked) excluded by an outdated type list; DBLP is the CS gold standard",executing agent (pending PI)
4 4 A-002,2026-11-03,1,"Records whose primary source is a generic deposit platform (Zenodo, Figshare, IRDB, LA Referencia, Dialnet, DOAJ-as-source, OSTI) are excluded unless DBLP- or arXiv-linked (flag e7_generic_deposit); date_precision flag added (publication_date = YYYY-01-01 treated as year precision; monthly series use month-precision records only)","Zenodo alone contributes 138,533 eligible records in 2026 (20,141 in 2025; 1.3% with references) — deposits of slides, datasets and reports typed as articles; 18–28% of records carry a year-only date defaulting to 1 January",executing agent (pending PI)
5 +A-003,2026-11-03,2,"LLM rating budget for taxonomy validation fixed at 25 USD (two raters: claude-haiku-5-5 and claude-sonnet-5-5, structured outputs); knowledge-graph extraction budget fixed separately when designed","mandate §7 requires agent-based validation with human checkpoints; the PI is the third rater on 200 works",executing agent (pending PI)
added systematic_review/linkage_sample.py +35 −0
@@ -0,0 +1,35 @@
1 +#!/usr/bin/env python3
2 +"""WP44 — H-1: draw the record-linkage validation sample (500 DBLP↔OpenAlex pairs stratified by linkage method) with
3 +automatic agreement checks (normalised title similarity, year difference, first-author surname match). The PI reviews a
4 +200-pair subsample (column pi_review = TRUE). Output: data/metadata/linkage_sample.csv and linkage_sample_summary.json."""
5 +import argparse, os, json, duckdb, difflib
6 +
7 +
8 +def main():
9 + ap = argparse.ArgumentParser(); ap.add_argument("--root", required=True); ap.add_argument("--seed", type=int, default=44); a = ap.parse_args(); R = a.root
10 + con = duckdb.connect(os.path.join(R, "data/processed/wp44.duckdb"), read_only=True)
11 + rows = con.execute(f"""
12 + SELECT l.method, l.dblp_key, l.oa_id, d.title AS dblp_title, d.year AS dblp_year, d.authors[1] AS dblp_first_author, d.doi AS dblp_doi,
13 + o.title AS oa_title, o.publication_year AS oa_year, o.doi AS oa_doi,
14 + (SELECT author_name FROM oa_authorships au WHERE au.work_id = o.id ORDER BY position LIMIT 1) AS oa_first_author
15 + FROM (SELECT *, row_number() OVER (PARTITION BY method ORDER BY hash(dblp_key || '{a.seed}')) rn FROM link_dblp_oa) l
16 + JOIN dblp_raw d ON d.key = l.dblp_key JOIN oa_works o ON o.id = l.oa_id
17 + WHERE (l.method = 'doi' AND rn <= 250) OR (l.method = 'title_year' AND rn <= 200) OR (l.method = 'arxiv' AND rn <= 50)""").fetchall()
18 + out = []; agree = {}
19 + for i, r in enumerate(rows):
20 + method, key, oa, dt, dy, da, ddoi, ot, oy, odoi, oa_fa = r
21 + sim = difflib.SequenceMatcher(None, (dt or "").lower(), (ot or "").lower()).ratio()
22 + fa = (da or "").split()[-1].lower() if da else ""; ofa = (oa_fa or "").split()[-1].lower() if oa_fa else ""
23 + auto_ok = sim >= 0.9 and (dy is None or oy is None or abs(dy - oy) <= 1) and (not fa or not ofa or fa == ofa)
24 + out.append(dict(method=method, dblp_key=key, oa_id=oa, dblp_title=dt, oa_title=ot, dblp_year=dy, oa_year=oy, dblp_doi=ddoi, oa_doi=odoi,
25 + dblp_first_author=da, oa_first_author=oa_fa, title_similarity=round(sim, 3), auto_ok=auto_ok, pi_review=(i % 5 < 2), pi_verdict=""))
26 + agree.setdefault(method, [0, 0]); agree[method][0] += 1; agree[method][1] += int(auto_ok)
27 + import csv
28 + with open(os.path.join(R, "data/metadata/linkage_sample.csv"), "w", newline="") as fh:
29 + w = csv.DictWriter(fh, fieldnames=list(out[0].keys())); w.writeheader(); w.writerows(out)
30 + summ = {m: {"n": n, "auto_ok": k, "auto_precision": round(k / n, 4)} for m, (n, k) in agree.items()}
31 + json.dump(summ, open(os.path.join(R, "data/metadata/linkage_sample_summary.json"), "w"), indent=1); print(summ)
32 +
33 +
34 +if __name__ == "__main__":
35 + main()
added taxonomy/VALIDATION.md +16 −0
@@ -0,0 +1,16 @@
1 +# Taxonomy validation design (Phase 2, checkpoint H-2)
2 +
3 +Sample: 2,000 eligible works, stratified = 50 per rule-assigned primary category (40 × 50), drawn with seed 44 from works
4 +with an abstract (month-precision or year-precision alike), plus 200 works with no category assigned (coverage check).
5 +Raters: two independent LLM raters that never see the rule-based assignment — rater A `claude-haiku-5-5`,
6 +rater B `claude-sonnet-5-5` (different model families within Claude; the PI is the third rater on a 200-work
7 +subsample, `pi_review = TRUE`). Each rater receives the 40 category definitions (from `ontology.yaml`) and, per work,
8 +title + abstract + venue + year, and returns, under a JSON schema: `categories` (all applicable ids, 0–5),
9 +`primary` (one id or null), `confidence` (0–1), `rationale` (≤ 30 words).
10 +Metrics (taxonomy/validation/metrics.json): per-category precision/recall/F1 of the rules against each rater and against
11 +the rater consensus (both raters agree); micro/macro F1; Cohen's κ (primary) and Krippendorff's α (multi-label, MASI
12 +distance) between raters; agreement on "no category". Disagreements are exported for the PI (validation/disagreements.csv).
13 +Decision rule fixed in advance: a category with consensus F1 < 0.60 triggers a mapping revision (logged as an amendment)
14 +and a re-run of the classification; the validation sample is then re-rated with the revised rules held out of the rater
15 +prompt (the raters never see rules, so no leakage).
16 +Budget: ≤ 25 USD (A-003).
added taxonomy/src/area_compsci.py +146 −0
@@ -0,0 +1,146 @@
1 +"""Area computational_science: categories 33, 34, 40 (scientific computing, computational biology, autonomous scientific discovery)."""
2 +
3 +CATEGORIES = [
4 +dict(
5 + id="scientific_computing", number=33, name="Scientific Computing", area="computational_science",
6 + definition=("Numerical and computational methods and software for mathematical models of science and engineering: "
7 + "numerical linear algebra, discretisation of differential equations, solvers and preconditioners, simulation "
8 + "frameworks, uncertainty quantification, reduced-order and surrogate models, scientific machine learning "
9 + "(PINNs, neural operators), high-performance scientific software and performance portability, mathematical "
10 + "software, computational physics/chemistry/engineering tooling. Domain biology is computational_biology; "
11 + "parallel systems software is distributed_computing."),
12 + topics=[("T11697", 1.0, "numerical methods and algorithms"), ("T10339", 1.0, "advanced numerical methods in computational mathematics"),
13 + ("T11245", 1.0, "advanced numerical analysis techniques"), ("T11416", 1.0, "numerical methods for differential equations"),
14 + ("T12727", 0.9, "differential equations and numerical methods"), ("T10792", 0.8, "matrix theory and algorithms"),
15 + ("T10514", 0.8, "numerical methods in engineering"), ("T13487", 0.8, "statistical and numerical algorithms"),
16 + ("T13650", 0.8, "computational physics and Python applications"), ("T11205", 0.7, "numerical methods in inverse problems"),
17 + ("T13286", 0.7, "modeling and simulation systems"), ("T11206", 0.7, "model reduction and neural networks"),
18 + ("T12404", 0.6, "mathematical approximation and integration"), ("T11986", 0.6, "scientific computing and data management (workflows)"),
19 + ("T11751", 0.6, "lattice Boltzmann simulation"), ("T11195", 0.6, "simulation techniques and applications"),
20 + ("T10173", 0.5, "computational fluid dynamics"), ("T11263", 0.5, "electromagnetic simulation and numerical methods"),
21 + ("T13806", 0.5, "mathematical and computational methods"), ("T12303", 0.5, "tensor decomposition and applications"),
22 + ("T10545", 0.4, "optimization and variational analysis"), ("T11694", 0.4, "fluid dynamics simulations"),
23 + ("T10591", 0.4, "theoretical and computational physics"), ("T10054", 0.4, "parallel computing (HPC applications)"),
24 + ("T12056", 0.4, "Markov chains and Monte Carlo methods"), ("T13116", 0.3, "heat transfer and numerical methods"),
25 + ("T14270", 0.3, "simulation and modeling applications"), ("T12100", 0.3, "advanced mathematical modeling in engineering"),
26 + ("T10963", 0.3, "advanced optimization algorithms"), ("T11948", 0.3, "machine learning in materials science"),
27 + ("T10029", 0.2, "climate variability and models"), ("T10466", 0.2, "meteorological phenomena and simulations"),
28 + ("T10541", 0.2, "nonlinear differential equations analysis"), ("T10194", 0.2, "nonlinear PDEs"),
29 + ("T12589", 0.2, "differential equations and boundary problems"), ("T10288", 0.2, "fractional differential equations"),
30 + ("T11152", 0.1, "stochastic processes and statistical mechanics"), ("T12809", 0.2, "contact mechanics and variational inequalities"),
31 + ("T13734", 0.1, "advanced computational techniques (expert systems)"), ("T13608", 0.3, "advanced computational techniques in science and engineering")],
32 + subfields=[(1703, 0.1)],
33 + arxiv=[("cs.NA", 1.0), ("cs.MS", 1.0), ("cs.CE", 1.0), ("physics.comp-ph", 0.8), ("math.OC", 0.2), ("cs.DC", 0.1)],
34 + streams=[("journals/siamsc", 1.0), ("journals/jcphy", 1.0), ("journals/cphysics", 1.0), ("journals/jcam", 1.0), ("journals/na", 1.0),
35 + ("journals/siamnum", 1.0), ("journals/toms", 1.0), ("conf/iccS", 1.0), ("journals/jocs", 1.0), ("journals/jscic", 1.0),
36 + ("journals/tomacs", 0.8), ("journals/mcs", 0.8), ("journals/cma", 0.8), ("journals/cam", 0.8), ("journals/ijcm", 0.8),
37 + ("conf/xsede", 0.8), ("journals/amc", 0.7), ("journals/ewc", 0.7), ("conf/wsc", 0.7), ("journals/simpra", 0.7),
38 + ("journals/jcmse", 0.7), ("journals/computation", 0.7), ("journals/ijhpca", 0.6), ("journals/cce", 0.6), ("journals/jcc", 0.6),
39 + ("journals/gandc", 0.6), ("journals/jamc", 0.6), ("conf/sc", 0.5), ("journals/cnsns", 0.5), ("journals/ncs", 0.5),
40 + ("journals/envsoft", 0.5), ("journals/appml", 0.5), ("journals/siamam", 0.5), ("journals/aes", 0.5), ("journals/jossw", 0.5),
41 + ("journals/softx", 0.5), ("journals/mlst", 0.4), ("journals/esi", 0.4), ("journals/cstat", 0.4), ("journals/sac", 0.4),
42 + ("journals/siamma", 0.3), ("journals/cacie", 0.3), ("journals/cmpb", 0.3), ("journals/csda", 0.3), ("journals/cssc", 0.3),
43 + ("journals/cmc", 0.3), ("journals/axioms", 0.2), ("journals/mp", 0.2), ("journals/jota", 0.2), ("conf/ipps", 0.2),
44 + ("journals/ecoi", 0.2), ("journals/jns", 0.2), ("journals/tpds", 0.1), ("journals/jpdc", 0.1), ("journals/siamjo", 0.1),
45 + ("journals/symmetry", 0.1), ("journals/entropy", 0.1), ("journals/mathematics", 0.0)],
46 + keywords=[
47 + (r"(?i)\b(scientific|numerical|high-?performance|computational|simulation) (computing|simulations?|methods?|analysis|modell?ing|software|linear algebra|workflows?|physics|science|fluid dynamics|mechanics|chemistry|materials science|engineering|electromagnetics|acoustics|astrophysics|geoscience|seismology|codes?|libraries|kernels?|applications?|frameworks?|solvers?|schemes?|algorithms?|experiments?|studies)\b|\bscientific (machine learning|ML|software|codes?|applications?|workflows?|visuali[sz]ation)\b|\bSciML\b", 1.0, "both"),
48 + (r"(?i)\b(finite (element|difference|volume) (methods?|schemes?|discreti[sz]ations?|analysis|solvers?|models?|simulations?)|FEM\b|FEA\b|FDM\b|FVM\b|isogeometric|spectral (methods?|elements?)|discontinuous Galerkin|DG methods?|multigrid|algebraic multigrid|AMG\b|domain decomposition|preconditioners?|preconditioning|Krylov|GMRES|BiCGStab|conjugate gradient|CG solvers?|sparse (linear (systems?|solvers?)|matrix|matrices|direct solvers?|factori[sz]ation)|linear solvers?|iterative solvers?|eigenvalue (problems?|solvers?|computations?)|eigensolvers?|Lanczos|Arnoldi|SVD\b|singular value decomposition|QR (factori[sz]ation|decomposition|algorithm)|LU (factori[sz]ation|decomposition)|Cholesky|BLAS|LAPACK|ScaLAPACK|MAGMA|cuBLAS|PETSc|Trilinos|hypre|FEniCS|deal\.II|MFEM|Firedrake|MOOSE|OpenFOAM|LAMMPS|GROMACS|NAMD|AMBER|Quantum ESPRESSO|VASP|CP2K|Gaussian \d\d|ORCA|GAMESS|NWChem|molecular dynamics (simulations?|codes?|software|packages?|engines?)|MD simulations?|Monte Carlo (simulations?|methods?|integration|sampling)|lattice Boltzmann|particle-?in-?cell|PIC (simulations?|codes?)|smoothed particle|SPH\b|N-?body|fast multipole|FMM\b|Barnes-?Hut|adaptive mesh refinement|AMR\b|mesh (generation|refinement|adaptation|quality)|unstructured (meshes?|grids?)|structured grids?|stencil (computations?|codes?)|time[- ]stepping|time integration|Runge-?Kutta|implicit (schemes?|solvers?|time)|ODE solvers?|PDE solvers?|partial differential equations?|PDEs?\b|ordinary differential equations?|ODEs?\b|stiff (systems|equations|ODEs)|boundary value problems?|initial value problems?|uncertainty quantification|UQ\b|polynomial chaos|stochastic (collocation|Galerkin|PDEs?)|sensitivity analysis|Sobol|reduced[- ]order model(s|ing)?|ROM\b|model order reduction|MOR\b|proper orthogonal decomposition|POD\b|dynamic mode decomposition|DMD\b|surrogate model(s|ing)?|emulators?|Gaussian process emulat|Kriging for simulation|physics-?informed (neural|machine learning|deep)|PINNs?\b|neural operators?|Fourier neural operator|FNO\b|DeepONet|operator learning|neural (PDE|ODE) solvers?|differentiable (physics|simulation|programming|solvers?)|automatic differentiation|adjoint (methods?|sensitivity|solvers?)|inverse problems?|data assimilation|Kalman filter for (simulation|assimilation)|ensemble Kalman|4D-?Var|floating-?point (arithmetic|precision|errors?|formats?)|mixed-?precision (arithmetic|solvers?|algorithms?|iterative)|interval arithmetic|verified (numerics|computing)|rounding errors?|numerical (stability|accuracy|precision|errors?)|computer algebra|symbolic computation|symbolic-?numeric|quadrature|cubature|numerical integration|interpolation (schemes?|methods?)|splines?|radial basis functions?|RBF\b|tensor (decompositions?|trains?|networks? for (PDE|simulation)|methods? for)|low-?rank (approximation|tensor)|hierarchical matrices|H-?matrices|fast (solvers?|transforms?)|FFT\b|fast Fourier|HPC (applications?|codes?|software|workflows?|systems? for science)|exascale (computing|applications?|software|codes?)|ECP\b|petascale|supercomput\w+|performance portability|Kokkos|RAJA|SYCL|OpenACC|OpenMP offload|CUDA (for|implementation of) (simulation|solvers?|PDE)|GPU-?accelerated (simulation|solvers?|computing|codes?|linear algebra)|GPU (implementation|acceleration) of (numerical|simulation|solvers?|FEM|molecular)|co-?design of (scientific|HPC)|scientific (workflow|data) management|in[- ]situ (visuali[sz]ation|analysis)|checkpoint(ing)? (for|of) (simulation|HPC)|research software (engineering|sustainability)|RSE\b|reproducib(le|ility) (of|in) (computational|scientific|simulation))\b", 1.0, "both"),
49 + (r"(?i)\b(climate (model(s|ing|ling)?|simulations?|codes?)|earth system model|weather (prediction|forecasting|model)s?|numerical weather|NWP\b|ocean (model|circulation model)|atmospheric (model|dynamics simulation)|seismic (simulation|inversion|imaging|wave propagation)|CFD\b|turbulence (simulation|model(s|ing)?|DNS|LES)|direct numerical simulation|large-?eddy simulation|Navier-?Stokes solvers?|combustion simulation|plasma simulation|magnetohydrodynamic|MHD simulation|astrophysical simulation|cosmological simulation|gravitational (wave|N-?body) simulation|density functional theory|DFT (calculations?|simulations?|codes?)|ab initio (calculations?|molecular dynamics|simulations?)|first-?principles (calculations?|simulations?)|quantum chemistry (calculations?|software|methods?)|electronic structure (calculations?|codes?|methods?)|coupled cluster|Hartree-?Fock|machine learning (interatomic|force field)|neural network potentials?|MLIPs?\b|multiscale (modeling|simulation)|multiphysics|fluid-?structure interaction|FSI\b|structural (analysis|mechanics simulation)|crash simulation|topology optimi[sz]ation|computational (electromagnetics|acoustics|biomechanics|hemodynamics|geomechanics|hydrology|materials)|digital twins? (of|for) (physical|engineering|industrial))\b", 0.8, "both"),
50 + (r"(?i)\b(simulations?|solvers?|numerical|discreti[sz]ation|convergence (rate|order|analysis)|stability analysis|error (estimates?|analysis|bounds?)|a posteriori|a priori|accuracy|computational (cost|efficiency|time)|high-?order|mesh|grid|time step)\b", 0.3, "both"),
51 + ],
52 + exclusions=[],
53 + related=["distributed_computing", "computational_biology", "algorithms", "computer_graphics", "ai_accelerators", "autonomous_scientific_discovery", "compilers", "ml_theory"],
54 + parent_of=[], child_of=[],
55 + provenance=("Numerical topics are split between CS 1703 (T11697, T10792), Mathematics 26 (T11416, T12727, T11205, T13487) and "
56 + "Engineering 22 (T10339, T11245, T10514, CFD); mapped with weights by numerical-method content. SIAM SISC/JCP/CPC/"
57 + "JCAM/ToMS/ICCS/JoCS pure; cs.NA/cs.MS/cs.CE suffice alone."),
58 +),
59 +dict(
60 + id="computational_biology", number=34, name="Computational Biology", area="computational_science",
61 + definition=("Computational methods for biological and biomedical data: bioinformatics and genomics, protein structure "
62 + "and design, molecular modelling and computational drug discovery, single-cell and multi-omics analysis, "
63 + "systems and synthetic biology, biomedical text mining, computational neuroscience, biomedical and health "
64 + "informatics methods, DNA/molecular computing. Medical image analysis is shared with computer_vision; "
65 + "numerical methods as such are scientific_computing."),
66 + topics=[("T10211", 1.0, "computational drug discovery methods"), ("T10887", 1.0, "bioinformatics and genomic networks"),
67 + ("T12254", 1.0, "machine learning in bioinformatics"), ("T13937", 0.9, "genetics, bioinformatics and biomedical research"),
68 + ("T12029", 0.8, "DNA and biological computing"), ("T11710", 0.6, "biomedical text mining and ontologies"),
69 + ("T10044", 0.6, "protein structure and dynamics"), ("T11289", 0.6, "single-cell and spatial transcriptomics"),
70 + ("T10885", 0.6, "gene expression and cancer classification"), ("T10015", 0.5, "genomics and phylogenetic studies"),
71 + ("T12859", 0.5, "cell image analysis"), ("T10222", 0.4, "genomics and chromatin dynamics"),
72 + ("T10862", 0.4, "AI in cancer detection"), ("T11287", 0.4, "cancer genomics and diagnostics"),
73 + ("T11986", 0.4, "scientific computing and data management (bioinformatics pipelines)"), ("T13702", 0.3, "machine learning in healthcare"),
74 + ("T11213", 0.3, "genomic variations and chromosomal abnormalities"), ("T11642", 0.3, "genomics and rare diseases"),
75 + ("T12422", 0.3, "radiomics and ML in medical imaging"), ("T10052", 0.3, "medical image segmentation"),
76 + ("T10429", 0.3, "EEG and brain-computer interfaces"), ("T11601", 0.3, "neuroscience and neural engineering"),
77 + ("T12874", 0.3, "digital imaging for blood diseases"), ("T10120", 0.2, "bacterial genetics and biotechnology"),
78 + ("T11879", 0.2, "protist diversity and phylogeny"), ("T10066", 0.2, "gut microbiota"), ("T11948", 0.2, "ML in materials (molecular ML)"),
79 + ("T10581", 0.2, "neural dynamics and brain function"), ("T11908", 0.2, "protein interaction studies"),
80 + ("T13759", 0.2, "medical imaging and pathology"), ("T11819", 0.3, "data-driven disease surveillance"),
81 + ("T12568", 0.1, "plant taxonomy and phylogenetics"), ("T11636", 0.2, "AI in healthcare and education"),
82 + ("T14400", 0.2, "medical coding and health information")],
83 + subfields=[(1312, 0.2)],
84 + arxiv=[("q-bio.QM", 1.0), ("q-bio.GN", 1.0), ("cs.CE", 0.2)],
85 + streams=[("journals/bioinformatics", 1.0), ("journals/bib", 1.0), ("journals/bmcbi", 1.0), ("journals/ploscb", 1.0),
86 + ("journals/tcbb", 1.0), ("journals/jcb", 1.0), ("conf/recomb", 1.0), ("conf/bcb", 1.0), ("conf/psb", 1.0),
87 + ("journals/jcheminf", 1.0), ("journals/candc", 1.0), ("journals/biodb", 1.0), ("conf/bibm", 0.8), ("journals/jcisd", 0.8),
88 + ("journals/nar", 0.6), ("journals/jbi", 0.6), ("journals/biosystems", 0.6), ("journals/ficn", 0.6), ("journals/cbm", 0.5),
89 + ("journals/cmpb", 0.5), ("journals/jcc", 0.5), ("journals/titb", 0.4), ("journals/artmed", 0.4), ("journals/neuroimage", 0.4),
90 + ("conf/biostec", 0.4), ("journals/jamia", 0.3), ("journals/midm", 0.3), ("conf/amia", 0.3), ("journals/npjdm", 0.3),
91 + ("conf/embc", 0.3), ("journals/tbe", 0.3), ("journals/mbec", 0.3), ("conf/isbi", 0.3), ("conf/cbms", 0.3), ("conf/bmei", 0.3),
92 + ("journals/patterns", 0.3), ("conf/cinc", 0.3), ("journals/ecoi", 0.3), ("journals/jocn", 0.2), ("journals/cars", 0.2),
93 + ("journals/mia", 0.2), ("journals/tmi", 0.2), ("conf/miccai", 0.2), ("journals/bmcmi", 0.2), ("journals/fdgth", 0.2),
94 + ("journals/ijmi", 0.2), ("journals/jdi", 0.2), ("journals/cin", 0.2), ("journals/jmihi", 0.2), ("journals/cmig", 0.2),
95 + ("journals/mlst", 0.2), ("journals/ncs", 0.2), ("journals/jms", 0.1), ("journals/cce", 0.1), ("journals/cogcom", 0.1),
96 + ("journals/natmi", 0.1), ("conf/medinfo", 0.3), ("conf/mie", 0.3), ("journals/bspc", 0.3), ("journals/jmlr", 0.02)],
97 + keywords=[
98 + (r"(?i)\b(bioinformatics?|computational (biology|genomics|neuroscience|chemistry|drug (design|discovery)|biomedicine|pathology|oncology|epidemiology|immunology|proteomics|structural biology|biophysics|medicine|psychiatry|phenotyping|ecology|evolution)|systems biology|synthetic biology|biomedical (informatics|data science|text mining|NLP|knowledge graphs?|ontolog)|cheminformatics|chemoinformatics|health informatics|clinical informatics|medical informatics|neuroinformatics|phylogenetics?|phylogenomics|metagenomics?|pharmacogenomics|immunoinformatics|biostatistics for genomics|biocomputing|DNA computing|molecular computing|biological computing)\b", 1.0, "both"),
99 + (r"(?i)\b(genom(e|es|ic|ics)|transcriptom(e|ic|ics)|proteom(e|ic|ics)|metabolom(e|ic|ics)|epigenom(e|ic|ics)|microbiom(e|ic|ics)|single-?cell (RNA|sequencing|analysis|data|omics|atlas|clustering)|scRNA-?seq|snRNA-?seq|RNA-?seq|ChIP-?seq|ATAC-?seq|Hi-?C\b|DNA (sequencing|methylation|sequences?|barcod)|sequence (alignment|assembly|analysis|motifs?|logos?)|read (alignment|mapping|assembly)|genome (assembly|annotation|wide association|editing|browsers?|graphs?)|pangenom|GWAS|QTL\b|variant (calling|annotation|effect|prioriti[sz]ation)|SNPs?\b|indels?|structural variants?|copy number|gene (expression|regulatory networks?|ontology|set enrichment|prioriti[sz]ation|fusion|annotation)|GRNs?\b|differential expression|enrichment analysis|pathway (analysis|enrichment|databases?)|KEGG|Reactome|protein (structure prediction|folding|design|function prediction|language models?|interactions?|docking|engineering|families|domains|sequences?|contact maps?)|AlphaFold|RoseTTAFold|ESM-?[23]|ESMFold|ProtTrans|molecular (docking|dynamics|property prediction|generation|design|representation|fingerprints?|graphs?|similarity)|drug (discovery|design|repurposing|repositioning|targets?|response prediction|likeness|combination)|virtual screening|QSAR|QSPR|ADMET|binding (affinity|sites?|pockets?)|ligands?|de novo (drug|molecule|molecular|protein|peptide|antibody) (design|generation)|antibod(y|ies) (design|engineering|modeling)|CRISPR (design|guide|screening)|guide RNA design|metagenom|microbiome analysis|multi-?omics|pan-?cancer|biomarker (discovery|identification)|survival (analysis|prediction) (of|for|in) (patients|cancer)|precision (medicine|oncology)|electronic health records?|EHRs?\b|EMRs?\b|clinical (decision support|NLP|prediction models?|text|notes|trials? (matching|design|emulation)|data warehouses?)|medical (coding|ontolog|concept)|UMLS|SNOMED|ICD-?1[01]|FHIR|OMOP|phenotyp(e|ing) (algorithms?|from EHR)|neural (encoding|decoding) of|spike sorting|connectom|brain (networks?|imaging analysis|simulation|atlas|parcellation)|neural (population|circuit) models?|computational (models? of neurons?|psychiatry)|population genetics|coalescent|phylogenetic (trees?|inference|reconstruction|comparative)|molecular evolution|epidemiological model(ing|s)|compartmental models?|SEIR|SIR models?|disease (transmission|spread) model|cell (segmentation|tracking|type annotation|atlas|lineage)|histopatholog|digital pathology|whole-?slide images?|radiomics|radiogenomics|DNA (computing|storage|data storage|origami)|molecular (computing|programming|circuits?)|biological (networks?|sequences?|data(bases?)?|computing|pathways?|systems?)|protein-?protein interaction|PPI networks?|mass spectrometry (data|analysis|proteomics)|peptide identification|flow cytometry analysis|spatial (transcriptomics|omics)|cell-?cell communication|trajectory inference|pseudotime|batch (effect|correction) (in|for) (single|RNA|omics)|dimensionality reduction (of|for) (single-?cell|omics)|UMAP (of|for) (cells|single)|Seurat|Scanpy|Bioconductor|Biopython|BLAST|HMMER|BWA|Bowtie|STAR aligner|GATK|samtools|Nextflow|Snakemake|Galaxy (platform|workflows?)|bioRxiv|GEO datasets?|TCGA|UK Biobank|ENCODE|PDB\b|Protein Data Bank|UniProt|ChEMBL|PubChem|ZINC database|DrugBank|MIMIC-?(III|IV))\b", 1.0, "both"),
100 + (r"(?i)\b(biological|biomedical|clinical|medical|health(care)?|patients?|diseases?|cancer|tumou?rs?|proteins?|genes?|cells?|cellular|neurons?|neuronal|brain|molecular|molecules?|drugs?|pharmac\w+|omics|sequencing|biology|biologists?|physicians?|hospitals?)\b", 0.3, "both"),
101 + ],
102 + exclusions=[],
103 + related=["scientific_computing", "nlp", "computer_vision", "ml_theory", "autonomous_scientific_discovery", "privacy_preserving_computation", "generative_ai"],
104 + parent_of=[], child_of=[],
105 + provenance=("Computational-biology topics live in CS 1703 (T10211 drug discovery) and Biochemistry 13 (T10887, T12254, T11710, "
106 + "T13937, T12029); genomics/protein topics (T10222, T10044, T11289...) are mapped at 0.4-0.6 because only part of their "
107 + "works are computational. Bioinformatics/BIB/BMC Bioinf/PLoS CB/TCBB/JCB/RECOMB/PSB/BCB pure; medical-informatics "
108 + "venues partial."),
109 +),
110 +dict(
111 + id="autonomous_scientific_discovery", number=40, name="Autonomous Scientific Discovery", area="computational_science",
112 + definition=("AI and automation systems that perform or substantially drive the scientific process: AI scientist and "
113 + "research-agent systems, automated hypothesis generation and literature synthesis, self-driving laboratories "
114 + "and closed-loop experimentation, AI-driven discovery of materials, molecules, equations, algorithms or "
115 + "theorems, autonomous experimental design, benchmarks for research agents, and the epistemology and "
116 + "evaluation of machine-generated science. Using ML inside a scientific pipeline without autonomy is "
117 + "scientific_computing or computational_biology; LLM agents in general are ai_agents."),
118 + topics=[("T11948", 0.6, "machine learning in materials science: materials discovery, high-throughput experimentation, materials informatics"),
119 + ("T10211", 0.3, "computational drug discovery"), ("T11986", 0.3, "scientific computing and data management (workflows)"),
120 + ("T13904", 0.3, "artificial intelligence applications (AI in science)"), ("T11937", 0.3, "research data management"),
121 + ("T11975", 0.2, "evolutionary algorithms (symbolic regression)"), ("T11206", 0.2, "model reduction and neural networks (equation discovery)"),
122 + ("T10906", 0.1, "AI planning (experiment planning)"), ("T13126", 0.1, "scientific research and discoveries"),
123 + ("T10778", 0.1, "philosophy and history of science"), ("T14100", 0.1, "scientific research and technology"),
124 + ("T13976", 0.1, "web visibility and informetrics (science of science)")],
125 + subfields=[],
126 + arxiv=[("cs.AI", 0.2), ("cs.LG", 0.1), ("cs.DL", 0.2), ("physics.comp-ph", 0.2), ("q-bio.QM", 0.1), ("cs.CE", 0.2), ("cs.MA", 0.1), ("cs.CY", 0.1)],
127 + streams=[("journals/mlst", 0.7), ("journals/ncs", 0.6), ("journals/natmi", 0.5), ("journals/patterns", 0.4), ("journals/jcheminf", 0.3),
128 + ("journals/jcisd", 0.2), ("journals/scientometrics", 0.2), ("conf/jcdl", 0.2), ("journals/aisy", 0.2), ("journals/dai", 0.2),
129 + ("journals/frai", 0.2), ("journals/jossw", 0.2), ("conf/xsede", 0.2), ("journals/jasis", 0.1), ("journals/softx", 0.1),
130 + ("journals/tai", 0.1), ("journals/ais", 0.1), ("journals/cphysics", 0.1), ("journals/sncs", 0.1), ("journals/ijdsa", 0.1),
131 + ("journals/bdcc", 0.1), ("conf/aaai", 0.05), ("conf/nips", 0.05), ("conf/iclr", 0.05), ("conf/icml", 0.05), ("journals/synthese", 0.1)],
132 + keywords=[
133 + (r"(?i)\b(autonomous|automated|automating|automation of|AI-?driven|AI-?assisted|AI-?enabled|AI-?powered|AI-?based|AI-?generated|AI-?augmented|LLM-?driven|LLM-?based|LLM-?powered|LLM-?assisted|LLM-?generated|agent-?based|agent-?driven|agentic|closed-?loop|self-?driving|robotic|machine-?learning-?driven|ML-?driven|ML-?guided|machine-?guided|data-?driven|algorithmic|computational|end-?to-?end|fully automated|human-?AI) (scientific (discovery|research|experimentation|experiments?|method|process|inquiry|workflows?|reasoning|hypothes\w+|writing|peer review|literature|ideation|insight|knowledge discovery|laborator\w+)|science|discovery (of|in) (materials|molecules|catalysts|drugs|laws|equations|physical laws|governing equations|new (physics|chemistry|mathematics)|proteins|alloys|polymers|reactions|synthesis routes|theorems|algorithms|conjectures)|materials discovery|molecular discovery|drug discovery pipeline|hypothesis (generation|testing|discovery|formulation|ranking)|literature (review|synthesis|mining|survey|search) (at scale|generation|automation)?|theorem (proving|discovery)|conjecture (generation|discovery)|mathematical discovery|experimental (design|planning|campaigns?|loops?)|experiment (design|planning|selection|execution)|research (assistants?|agents?|pipelines?|workflows?|automation|ideas?|ideation|proposals?|questions?)|peer review(ers?)?|paper (writing|generation|reviewing|review)|manuscript (generation|writing)|idea generation|laborator(y|ies)|labs?|chemist|synthesis planning|retrosynthesis|reaction (optimi[sz]ation|discovery)|materials (acceleration|synthesis|design|exploration)|knowledge discovery|scientific knowledge (graph|extraction|synthesis))\b", 1.0, "both"),
134 + (r"(?i)\b(self-?driving lab(s|oratory|oratories)?|SDLs?\b|autonomous (laborator\w+|experiment\w*|research|discovery|exploration of (chemical|materials)|materials (platform|synthesis|research)|synthesis|chemistry|science|scientist|agents? for (science|research|discovery)|workflows? for (science|discovery))|AI scientist|AI co-?scientist|AI (for|in|4) ?science|AI4Science|AI-?enabled science|ML for science|machine learning for (scientific discovery|science)|scientific (machine learning agents?|foundation models?|LLMs?|agents?|discovery (with|using|via|through|by) (AI|machine learning|LLMs?|agents?|deep learning|neural|automated|autonomous)|language models?|reasoning (with|in) LLMs?|data (agents?|discovery agents?))|LLMs? (for|in|and|as) (science|chemistry|biology|materials|physics|mathematics|research|scientific|discovery|experiment)|language models? (for|in|as) (science|chemistry|biology|materials|scientific|scientists?|discovery|experiment)|ChemCrow|Coscientist|FunSearch|AlphaEvolve|AlphaTensor|AlphaProof|AlphaGeometry|AlphaDev|AlphaFold (3|database)|GNoME|Eureka\b|AI Feynman|SINDy|PySR|symbolic regression|equation (discovery|learning|identification)|discover(y|ing|ed) (of )?(governing|physical|scientific|conservation|dynamical) (equations|laws|principles)|law discovery|automated (hypothesis|theory|experiment\w*|discovery|literature|materials|reaction|retrosynthesis|synthesis planning|lab(oratory)?|science|scientific|reasoning for (mathematics|discovery)|conjecturing|proof discovery|data analysis|statistician|machine learning|data science|modeling|model discovery|design of experiments|feature discovery)|high-?throughput (experimentation|screening|computation|virtual screening|materials|synthesis|DFT|simulations?|discovery)|Bayesian optimi[sz]ation (for|of|in|guided) (materials|experiments?|chemistry|synthesis|reactions?|discovery|molecules|design|process)|active learning (for|in|guided) (materials|chemistry|experiments?|molecular|drug|science|discovery|synthesis|catalysts?)|inverse design|generative (models?|design|AI) for (molecules|materials|proteins|catalysts|crystals|drugs|chemistry|discovery)|materials (informatics|genome|acceleration platforms?|project)|cloud lab(s|oratory|oratories)?|lab(oratory)? automation|robotic (chemist\w*|chemistry|synthesis|laborator\w+|experiment\w*|platforms? for (science|chemistry|biology|materials))|mobile robotic chemist|Emerald Cloud Lab|Strateos|AutoML for science|scientific (claim|fact) (verification|checking|extraction)|literature-?based discovery|LBD\b|hypothesis (generation|generators?|machines?)|research (ideation|idea generation)|AI-?generated (research|papers?|hypotheses|reviews?|science)|machine (scientists?|discovery)|robot scientists?|Adam and Eve|Eve robot|discovery (engines?|pipelines?|platforms?|systems?|loops?) (for|of|in) (materials|science|chemistry|drugs?|molecules|biology)|automated (theorem proving|reasoning) (for|in) (mathematics|discover)|AI (for|in) (mathematics|theorem|math research)|LLM (agents?|systems?|pipelines?|frameworks?) for (science|research|discovery|chemistry|biology|materials|experiment|data analysis|literature)|agents? for (scientific|science|research|discovery|chemistry|biology|materials|experiment|lab)|science (of science|agents?|automation|LLMs?|benchmarks?)|SciAgents|ChemAgents|BioPlanner|AI (Scientist|Researcher|Co-?Scientist)|Sakana|Virtual Lab|AI Virtual Cell|AI (lab|laboratory)|closed-?loop (optimi[sz]ation|experiment\w*|discovery|synthesis|materials|learning for))\b", 1.0, "both"),
135 + (r"(?i)\b(benchmarks? for (scientific|AI scientist|research agents?|discovery|science|AI4Science|lab)|ScienceAgentBench|MLAgentBench|MLE-?bench|DiscoveryBench|SciCode|LAB-?Bench|ChemBench|MatSciBench|PaperBench|SciBench|ResearchBench|CORE-?Bench|AAAR|BixBench|SciReplicate|ReplicationBench|SWE-?bench for science|TheoremQA|TPBench|AlgoTune|evaluating (AI|LLM|machine)-?generated (research|papers?|hypotheses|science))\b", 1.0, "both"),
136 + (r"(?i)\b(scientific|science|discovery|experiment(s|al|ation)?|laborator(y|ies)|research|hypothes[ie]s|materials|molecules|chemistry|theorems?|conjectures?)\b", 0.3, "both"),
137 + ],
138 + exclusions=[r"(?is)^(?!.*(AI\b|artificial intelligence|machine learning|deep learning|neural|LLMs?|language models?|agents?|autonomous|automated|automation|robot|Bayesian optimi[sz]ation|active learning|symbolic regression|algorithm|computational|closed-?loop|high-?throughput|self-?driving)).*"],
139 + related=["ai_agents", "llm", "scientific_computing", "computational_biology", "formal_verification", "algorithms", "information_retrieval", "ai_safety"],
140 + parent_of=[], child_of=[],
141 + provenance=("No OpenAlex topic or DBLP stream isolates autonomous discovery; T11948 (materials discovery, high-throughput experimentation) "
142 + "is the closest host and MLST/Nat. Comput. Sci./Nat. Mach. Intell. the closest venues. Keyword patterns on "
143 + "'<automation term> <science term>', named systems (Coscientist, FunSearch, AlphaEvolve, AI Scientist...) and research-agent "
144 + "benchmarks carry the category; a veto removes texts with no AI/automation term at all."),
145 +),
146 +]
added taxonomy/src/area_hardware_b.py +74 −0
@@ -0,0 +1,74 @@
1 +"""Area hardware_emerging, part B: categories 32 and 39 (quantum computing, sustainable computing)."""
2 +
3 +CATEGORIES = [
4 +dict(
5 + id="quantum_computing", number=32, name="Quantum Computing", area="hardware_emerging",
6 + definition=("Computation and information processing exploiting quantum mechanics: quantum algorithms and complexity, "
7 + "quantum error correction and fault tolerance, qubit hardware platforms and control, quantum software, "
8 + "compilers and simulators, variational and NISQ algorithms, quantum machine learning, quantum communication "
9 + "and key distribution, quantum networking. Quantum physics without a computational or information-processing "
10 + "framing is out of scope; post-quantum cryptography is applied_cryptography."),
11 + topics=[("T10020", 1.0, "quantum information and cryptography"), ("T10682", 1.0, "quantum computing algorithms and architecture"),
12 + ("T10622", 0.3, "quantum mechanics and applications"), ("T11803", 0.3, "superconducting and THz device technology"),
13 + ("T11804", 0.3, "quantum many-body systems"), ("T11414", 0.3, "quantum optics and atomic interactions"),
14 + ("T13182", 0.3, "quantum-dot cellular automata"), ("T10382", 0.2, "quantum and electron transport phenomena"),
15 + ("T10425", 0.2, "cold atom physics"), ("T10657", 0.2, "topological materials"), ("T12611", 0.2, "quantum reservoir computing"),
16 + ("T11261", 0.2, "quantum chaos and dynamical systems"), ("T10022", 0.2, "semiconductor quantum structures and devices"),
17 + ("T11130", 0.1, "coding theory (quantum codes)"), ("T12002", 0.1, "computability (quantum complexity)"),
18 + ("T11262", 0.1, "quantum mechanics and non-Hermitian physics")],
19 + subfields=[],
20 + arxiv=[("quant-ph", 1.0), ("cs.ET", 0.3), ("cs.CC", 0.1), ("cs.IT", 0.1), ("math.IT", 0.1), ("physics.comp-ph", 0.1)],
21 + streams=[("journals/quantum", 1.0), ("journals/qip", 1.0), ("conf/qce", 1.0), ("conf/tqc", 1.0), ("journals/entropy", 0.2),
22 + ("journals/tit", 0.1), ("conf/isit", 0.1), ("journals/iacr", 0.1), ("journals/tcad", 0.1), ("conf/dac", 0.1),
23 + ("conf/date", 0.1), ("journals/tc", 0.1), ("conf/isca", 0.1), ("conf/micro", 0.1), ("conf/hpca", 0.1),
24 + ("conf/asplos", 0.1), ("journals/jcphy", 0.1), ("journals/cphysics", 0.1), ("journals/symmetry", 0.1),
25 + ("conf/stoc", 0.1), ("conf/focs", 0.1), ("journals/natmi", 0.05), ("journals/ncs", 0.1), ("journals/mlst", 0.1),
26 + ("conf/sc", 0.1), ("journals/tpds", 0.05), ("conf/ipps", 0.05), ("journals/tqc", 0.0)],
27 + keywords=[
28 + (r"(?i)\bquantum (comput(ing|ers?|ation|ational)|algorithms?|circuits?|gates?|processors?|hardware|supremacy|advantage|error[- ]correct(ion|ing)|error mitigation|codes?|annealing|annealers?|machine learning|neural networks?|kernels?|simulation|simulators?|emulat\w+|information|key distribution|cryptograph\w*|communication|internet|networks?|networking|teleportation|entanglement distribution|repeaters?|memor(y|ies)|sensing|metrology|software|programming|compil(ers?|ation|ing)|control|optimi[sz]ation|chemistry (simulation|algorithms?|on quantum)|walks?|Fourier|phase estimation|approximate optimi[sz]ation|variational|bits?|speed-?ups?|volume|random (circuits?|sampling)|dots? (for|as) qubits?|devices? for computing|technolog(y|ies)|instruction sets?|transpil\w+|benchmark\w*|cloud|service|workflows?|HPC|data (centers?|loading)|RAM|QRAM|generative|reinforcement|transformers?|Boltzmann|support vector|convolutional|federated|language models?|LLMs?|finance|chemistry|many-?body simulation on|advantage experiments?|readout|crosstalk|calibration|characteri[sz]ation|tomography|process tomography|state preparation|amplitude (amplification|estimation|encoding)|linear (systems?|algebra) algorithms?|singular value|eigensolvers?|dynamics simulation|Monte Carlo (acceleration|algorithms)|game theory|secret sharing|money|signatures?|commitment|oblivious|zero-?knowledge|interactive proofs?|complexity|Turing|cellular automata|dot cellular automata|LDPC|surface codes?|resource (estimation|theory for computing)|logic synthesis|layout synthesis|mapping|routing (for|of) qubits?|qubit (mapping|routing|allocation))\b", 1.0, "both"),
29 + (r"(?i)\b(qubits?|qudits?|QAOA|VQE\b|variational quantum|VQAs?\b|NISQ|surface codes?|colou?r codes?|stabili[sz]er codes?|toric codes?|CSS codes?|qLDPC|quantum LDPC|magic state|T-?gates?|T-?count|Clifford\+T|fault-?tolerant quantum|logical qubits?|physical qubits?|transmons?|superconducting qubits?|flux(onium)? qubits?|trapped[- ]ions?|ion[- ]traps?|neutral atoms?|Rydberg (atoms?|arrays?|blockade)|photonic (qubits?|quantum)|boson sampling|Gaussian boson|spin qubits?|silicon qubits?|quantum dots? qubits?|NV cent(er|re)s? qubits?|Majorana (zero modes|qubits?|fermions for)|topological (qubits?|quantum comput)|anyons? (for|in) (computing|braiding)|braiding|Shor'?s algorithm|Grover'?s? (algorithm|search)|HHL\b|Harrow-?Hassidim|quantum Fourier transform|QFT\b|Hamiltonian simulation|Trotteri[sz]ation|Trotter (steps?|error)|qubitization|block encoding|LCU\b|linear combination of unitaries|QSVT|quantum signal processing|amplitude amplification|QKD\b|BB84|E91|B92|decoy state|measurement-?device-?independent|entanglement (swapping|purification|distillation|witnesses?|entropy)|Bell (states?|inequalit(y|ies)|tests?|pairs?)|GHZ states?|cluster states?|measurement-?based quantum|one-?way quantum|decoherence|dephasing|T1\b|T2\b|coherence times?|gate fidelit(y|ies)|two-?qubit gates?|CNOT|CZ gates?|iSWAP|Toffoli|randomized benchmarking|cross-?entropy benchmarking|XEB\b|gate set tomography|quantum (noise|channels?|Shannon|capacity|discord|coherence resource|error channels?)|depolarizing (noise|channel)|Pauli (noise|twirling|frames?)|post-?quantum|quantum-?safe|Qiskit|Cirq|PennyLane|QuTiP|OpenQASM|QASM|Q#\b|Quipper|Silq|Braket|tket|Quantinuum|IonQ|Rigetti|D-?Wave|IBM Quantum|Google Sycamore|Sycamore|Zuchongzhi|Jiuzhang|Quantum Volume|CLOPS|cross-?resonance|ZZ (coupling|crosstalk)|tunable couplers?|Josephson (junctions?|parametric)|dilution refrigerator (for|and) (qubits?|quantum)|cryo-?CMOS|cryogenic control|quantum-?classical (hybrid|interface|co-?design)|hybrid quantum|tensor networks? (simulation|contraction|methods?) (of|for) quantum (circuits?|computing)|matrix product states? (for|and) quantum (circuits?|computing)|Schrödinger-?Feynman|stabili[sz]er simulation|Clifford (circuits?|gates?|group|simulation)|Ising machines?|coherent Ising|quantum-?inspired|annealing (schedules?|hardware)|adiabatic quantum|QUBO\b|quadratic unconstrained binary)\b", 1.0, "both"),
30 + (r"(?i)\bquantum\b|\bentangle(d|ment)\b|\bsuperposition\b|\bHamiltonian\b|\bunitar(y|ies)\b", 0.4, "both"),
31 + ],
32 + exclusions=[r"(?is)^(?!.*(qubits?|quantum (comput\w*|algorithms?|error|circuits?|gates?|information|annealing|key distribution|cryptograph|machine learning|simulat\w+|advantage|supremacy|communication|internet|networks?|sensing|metrology|software|programming|walks?|processors?|hardware|codes?|teleportation|repeaters?|memory)|QKD|NISQ|QAOA|VQE|post-?quantum)).*\b(quantum (dots?|chemistry|mechanics|mechanical|field theory|gravity|Hall|wells?|cascade lasers?|efficiency|yield|chemical|Monte Carlo|phase transitions?|criticality|spin liquids?|materials?|optics|electrodynamics|fluids?|anomalous|oscillations?|confinement|transport|many-?body (physics|localization)|biology|cosmology)|quantum-?confined|quantum (defects|emitters) in)\b"],
33 + related=["applied_cryptography", "computational_complexity", "computer_architecture", "scientific_computing", "compilers"],
34 + parent_of=[], child_of=[],
35 + provenance=("T10020 and T10682 (both CS 1702) are the OpenAlex hosts; Physics 31 topics on qubit platforms (superconducting, "
36 + "cold atoms, many-body, quantum optics) mapped at 0.2-0.3 because only a fraction of their works concern computing. "
37 + "Quantum, QIP, QCE, TQC pure streams; quant-ph alone suffices. Quantum-physics senses without a computing term are vetoed."),
38 +),
39 +dict(
40 + id="sustainable_computing", number=39, name="Sustainable Computing", area="hardware_emerging",
41 + definition=("The energy, carbon, water and material footprint of computing and how to reduce it: energy-efficient and "
42 + "carbon-aware systems, data-centre energy and cooling, Green AI and the cost of training and inference, "
43 + "life-cycle and embodied carbon of hardware, green software engineering and networking, energy harvesting "
44 + "and intermittent computing, computing for sustainability when the object studied is the computing system. "
45 + "Generic low-power circuit design is computer_architecture; energy-efficient communication is computer_networks."),
46 + topics=[("T14098", 1.0, "energy efficiency in computing: data centre energy, server power"), ("T12238", 1.0, "green IT and sustainability: green computing, green AI"),
47 + ("T10080", 0.3, "energy-efficient wireless sensor networks"), ("T10363", 0.3, "low-power VLSI design"),
48 + ("T11392", 0.3, "energy harvesting in wireless networks"), ("T10101", 0.2, "cloud computing (data centres)"),
49 + ("T11954", 0.2, "energy efficiency and management"), ("T10435", 0.2, "environmental impact and sustainability"),
50 + ("T10502", 0.1, "energy-efficient neuromorphic computing"), ("T10933", 0.1, "real-time scheduling (energy-aware)"),
51 + ("T14296", 0.1, "climate change and sustainable development")],
52 + subfields=[],
53 + arxiv=[("cs.CY", 0.2), ("cs.DC", 0.2), ("cs.AR", 0.2), ("cs.NI", 0.1), ("cs.PF", 0.1), ("cs.ET", 0.1)],
54 + streams=[("journals/suscom", 1.0), ("journals/tsusc", 1.0), ("journals/tgcn", 0.8), ("conf/islped", 0.5), ("conf/ithings", 0.3),
55 + ("journals/tcc", 0.2), ("journals/tetc", 0.2), ("journals/fgcs", 0.1), ("journals/jsa", 0.1), ("journals/tpds", 0.1),
56 + ("conf/ccgrid", 0.1), ("journals/cluster", 0.1), ("journals/tjs", 0.1), ("journals/ais", 0.1), ("conf/fat", 0.1),
57 + ("journals/aiethics", 0.1), ("journals/tecs", 0.1), ("journals/computer", 0.1), ("journals/cacm", 0.1),
58 + ("journals/cm", 0.1), ("journals/network", 0.1), ("conf/sc", 0.1), ("journals/tnsm", 0.1), ("journals/tsg", 0.1),
59 + ("journals/patterns", 0.1), ("journals/natmi", 0.05), ("journals/ncs", 0.1), ("journals/jocs", 0.1)],
60 + keywords=[
61 + (r"(?i)\b(sustainable|green|carbon-?aware|carbon-?efficient|carbon-?neutral|carbon-?free|energy-?aware|energy-?efficient|energy-?proportional|low-?carbon|net-?zero|zero-?carbon|climate-?aware|eco-?friendly|environmentally[- ]friendly|frugal|lean) (computing|AI|artificial intelligence|machine learning|deep learning|software( engineering| development| design)?|data ?cent(er|re)s?|cloud|HPC|supercomput\w+|networking|networks?|ICT|IT\b|information technology|communications?|blockchain|mining|LLMs?|language models?|NLP|systems?|hardware|architectures?|scheduling|inference|training|computation|algorithms?|coding|programming|edge|IoT|5G|6G|wireless|datacent(er|re)s?|clusters?|servers?|GPUs?|chips?|processors?|storage|databases?|web|internet|digital)\b", 1.0, "both"),
62 + (r"(?i)\b(carbon (footprints?|emissions?|intensity|accounting|offsets?|costs?|impact|budgets?|aware(ness)?|efficiency|tax(es)? on|neutrality of|credits? for|dioxide emissions? (of|from) (computing|AI|data))|CO2(e|-?eq|-?equivalent)? (emissions?|footprint)|greenhouse gas(es)? (emissions?)? (of|from|and) (computing|AI|data ?cent|ICT|software|training|cloud|blockchain|digital)|embodied (carbon|emissions?|energy|footprint)|operational (carbon|emissions?)|life-?cycle (assessment|analysis|emissions?|carbon) (of|for) (computing|hardware|AI|data ?cent|servers?|smartphones?|ICT|devices?|software|electronics)|LCA of (ICT|hardware|data|AI|computing|electronics)|environmental (impact|footprint|costs?|sustainability|burden|implications?) of (computing|AI|artificial intelligence|machine learning|deep learning|LLMs?|language models?|data ?cent(er|re)s?|training|inference|software|blockchain|cryptocurrenc|Bitcoin|ICT|the internet|digital (technolog|infrastructure|services)|cloud|HPC|GPUs?|neural)|e-?waste|electronic waste|WEEE|rebound effects? (of|in) (ICT|digital|computing|AI)|Jevons|sustainability of (AI|computing|ML|machine learning|software|data ?cent(er|re)s?|HPC|blockchain|digital)|Green500|Top500 (energy|power)|energy (consumption|usage|efficiency|footprint|costs?|demand|requirements?|profiling|measurement|modeling|budget|savings?) (of|for|in|during) (AI|training|inference|LLMs?|large language|deep learning|neural networks?|machine learning|data ?cent(er|re)s?|computing|software|blockchain|Bitcoin|mining|cryptocurrenc|HPC|supercomput|GPUs?|servers?|cloud|mobile apps?|smartphones?|web|video streaming|the internet|ICT|digital|edge|IoT devices?|federated|transformers?|generative)|power (consumption|usage|draw|cap(ping)?|budgets?|management|efficiency|demand) (of|for|in|at) (data ?cent(er|re)s?|GPUs?|servers?|training|inference|HPC|AI|supercomput|clusters?|cloud)|PUE\b|power usage effectiveness|WUE\b|water usage effectiveness|CUE\b|data ?cent(er|re)s? (energy|power|cooling|efficiency|sustainability|water|carbon|emissions|heat reuse|waste heat|renewable|siting|demand response|load shifting|electricity)|cooling (of|for|in) data ?cent|liquid cooling (of|for) (servers|GPUs|data)|immersion cooling|free cooling|waste heat (recovery|reuse) (from|of) data|water (footprint|consumption|usage|use) of (AI|data ?cent|computing|LLMs?|training)|renewable(-?powered| energy (for|in|powered) (data ?cent|computing|cloud|HPC|AI|training|blockchain))|solar-?powered (data|computing|servers?|edge|IoT)|demand response (for|in|and) data ?cent|carbon-?aware (scheduling|computing|workload|training|shifting|load)|temporal (load|workload) shifting for carbon|spatial (load|workload) shifting for carbon|carbon-?intensity (signals?|aware|forecast)|grid carbon|marginal emissions? (factor|rate)|energy harvesting (for|in|powered) (IoT|sensors?|computing|devices?|wearables?)|battery-?free (devices?|computing|sensing|IoT)|batteryless|intermittent computing|energy-?harvesting devices?|ambient (RF|energy) harvesting for|green (software|coding|programming|IT|ICT|networking|cloud|AI|ML|NLP|data ?cent(er|re)s?|HPC|computing|blockchain|mining|5G|6G|edge|IoT|DevOps|software engineering|web|design patterns|metrics|certification|procurement) (practices|metrics|patterns|principles|engineering|movement|initiatives?|standards?|foundation)?|Green Software Foundation|software carbon intensity|SCI\b|CodeCarbon|carbontracker|ML CO2 impact|experiment-?impact-?tracker|energy (labels?|efficiency ratings?) for (software|AI|apps?|models?)|FLOPs? (as|vs\.?|versus) (energy|carbon)|energy (per|per-?)(inference|token|query|FLOP|operation|bit|training run)|joules? per (inference|token|query|operation|bit)|energy-?delay product|EDP\b|performance-?per-?watt|perf/W|FLOPS/W|TOPS/W|GFLOPS/W|GOPS/W|energy-?efficient (scheduling|resource management|virtual machine|VM|consolidation|server|routing|protocols?|MAC|caching|offloading|inference|training|accelerators?|architectures?|processors?|memory|storage|algorithms?|software|coding|code|programming|data processing|query processing|databases?|deep learning|neural|AI|machine learning|LLMs?|computing|HPC|supercomput|data ?cent|cloud|edge|IoT|wireless|networks?|communications?|5G|6G|blockchain|consensus|mining|web|mobile|smartphones?|embedded|FPGA|GPU|hardware|chips?|design))\b", 1.0, "both"),
63 + (r"(?i)\b(energy[- ]efficien(t|cy)|low[- ]power|power[- ]efficient|energy (consumption|saving|savings|optimi[sz]ation|reduction|management|harvesting|usage|cost|budget|constraints?|profile|model|footprint)|DVFS|dynamic voltage and frequency|power (management|capping|gating|budgets?|consumption|efficiency|usage)|thermal (management|efficiency)|cooling|heat dissipation|battery (life|lifetime|drain|consumption)|renewable energy|solar|wind power|smart grid|demand response|electricity (consumption|costs?|prices?|usage))\b", 0.5, "both"),
64 + (r"(?i)\b(sustainab(le|ility)|green|carbon|climate|environmental|emissions?|footprint|ecolog\w+|circular economy|e-?waste|recycl\w+|obsolescence|right to repair|digital sobriety|frugal)\b", 0.3, "both"),
65 + ],
66 + exclusions=[r"(?is)^(?!.*(computing|comput\w+|data ?cent(er|re)|software|AI\b|artificial intelligence|machine learning|deep learning|neural network|LLMs?|language models?|cloud|HPC|GPUs?|servers?|processors?|chips?|hardware|algorithms?|networking|ICT|blockchain|internet|digital|IoT|wireless|smartphones?|electronics|semiconductor|IT\b|information technology|training|inference|code|programming)).*\b(green|sustainable|carbon|energy|climate|environmental)\b"],
67 + related=["cloud_computing", "computer_architecture", "ai_accelerators", "edge_computing", "distributed_computing", "computer_networks", "ai_safety"],
68 + parent_of=[], child_of=[],
69 + provenance=("T14098 (CS 1708, 7k works) and T12238 (Engineering 2208, 27k works) are the only topics centred on the footprint of "
70 + "computing; energy-efficient WSN/VLSI/harvesting topics shared at 0.3. SUSCOM, T-SUSC and T-GCN are the dedicated "
71 + "streams; generic 'energy-efficient' terms are 0.5 and 'green/sustainable' 0.3, with a veto when no computing term "
72 + "appears anywhere in the text."),
73 +),
74 +]
added taxonomy/validate_sample.py +127 −0
@@ -0,0 +1,127 @@
1 +#!/usr/bin/env python3
2 +"""WP44 — taxonomy validation: stratified sample + two independent LLM raters (Anthropic SDK, structured outputs) + metrics.
3 + --draw : sample from DuckDB → taxonomy/validation/sample.parquet (+ sample.csv)
4 + --rate : rate with --model (one rater per run), resumable, batches of 10 works per request → validation/ratings_<model>.jsonl
5 + --metrics : compute agreement metrics → validation/metrics.json, disagreements.csv
6 +API key: read from the file given by --env-file (never from the repository); the key is only used here."""
7 +import argparse, json, os, random, time, re, duckdb, yaml, pandas as pd, numpy as np
8 +
9 +SCHEMA = {"type": "object", "properties": {"ratings": {"type": "array", "items": {"type": "object", "properties": {
10 + "work_id": {"type": "integer"}, "categories": {"type": "array", "items": {"type": "string"}, "maxItems": 5},
11 + "primary": {"type": ["string", "null"]}, "confidence": {"type": "number"}, "rationale": {"type": "string"}},
12 + "required": ["work_id", "categories", "primary", "confidence", "rationale"], "additionalProperties": False}}},
13 + "required": ["ratings"], "additionalProperties": False}
14 +
15 +
16 +def draw(root, seed, per_cat, n_none):
17 + con = duckdb.connect(os.path.join(root, "data/processed/wp44.duckdb"), read_only=True)
18 + con.execute(f"CREATE OR REPLACE VIEW work_primary AS SELECT * FROM read_parquet('{root}/data/processed/classification/primary/*.parquet')")
19 + con.execute(f"CREATE OR REPLACE VIEW work_categories AS SELECT * FROM read_parquet('{root}/data/processed/classification/cats/*.parquet')")
20 + df = con.execute(f"""
21 + WITH base AS (SELECT c.id AS work_id, c.title, a.abstract, c.source_name, c.publication_year AS year, p.primary_category,
22 + (SELECT list(category_id) FROM work_categories k WHERE k.work_id = c.id) AS rule_categories,
23 + hash(c.id || '{seed}') AS h
24 + FROM corpus_works c JOIN oa_abstracts a ON a.work_id = c.id LEFT JOIN work_primary p ON p.work_id = c.id WHERE c.eligible),
25 + ranked AS (SELECT *, row_number() OVER (PARTITION BY primary_category ORDER BY h) rn FROM base)
26 + SELECT * EXCLUDE (h, rn) FROM ranked WHERE (primary_category IS NOT NULL AND rn <= {per_cat}) OR (primary_category IS NULL AND rn <= {n_none})""").df()
27 + rng = random.Random(seed); idx = list(range(len(df))); rng.shuffle(idx)
28 + df["pi_review"] = False; df.loc[df.index[idx[:200]], "pi_review"] = True
29 + d = os.path.join(root, "taxonomy/validation"); os.makedirs(d, exist_ok=True)
30 + df.to_parquet(f"{d}/sample.parquet"); df.drop(columns=["abstract"]).to_csv(f"{d}/sample.csv", index=False)
31 + print("sample", len(df), "works;", df.primary_category.nunique(), "categories;", df.primary_category.isna().sum(), "unassigned")
32 +
33 +
34 +def rate(root, model, env_file, ontology, batch):
35 + import anthropic
36 + key = next(l.split("=", 1)[1].strip() for l in open(os.path.expanduser(env_file)) if l.startswith("ANTHROPIC_API_KEY="))
37 + client = anthropic.Anthropic(api_key=key, max_retries=5)
38 + ont = yaml.safe_load(open(ontology))
39 + defs = "\n".join(f"- {c['id']}: {c['name']} — {c['definition']}" for c in ont["categories"])
40 + system = ("You are an expert classifier of computer-science research papers for a systematic mapping study. Assign each paper to the "
41 + "applicable categories of the ontology below (zero to five; multi-label allowed; choose a primary category when at least one applies). "
42 + "Judge from the title, abstract, venue and year only. Be conservative: assign a category only when the paper's main "
43 + "contribution clearly belongs to it. If the paper is not computer-science research, return no categories.\n\nOntology:\n" + defs)
44 + d = os.path.join(root, "taxonomy/validation"); df = pd.read_parquet(f"{d}/sample.parquet")
45 + out_p = f"{d}/ratings_{model}.jsonl"; done = set()
46 + if os.path.exists(out_p):
47 + done = {json.loads(l)["work_id"] for l in open(out_p)}
48 + todo = df[~df.work_id.isin(done)]; usage = {"in": 0, "out": 0, "calls": 0}
49 + with open(out_p, "a") as fh:
50 + for i in range(0, len(todo), batch):
51 + b = todo.iloc[i:i + batch]
52 + items = "\n\n".join(f"### work_id {r.work_id}\nTitle: {r.title}\nVenue: {r.source_name or 'n/a'} ({r.year})\nAbstract: {(r.abstract or '')[:2500]}" for r in b.itertuples())
53 + for attempt in range(4):
54 + try:
55 + resp = client.messages.create(model=model, max_tokens=8000, system=[{"type": "text", "text": system, "cache_control": {"type": "ephemeral"}}],
56 + messages=[{"role": "user", "content": f"Rate the following {len(b)} papers. Return one rating per work_id.\n\n{items}"}],
57 + output_config={"format": {"type": "json_schema", "schema": SCHEMA}, "effort": "low"})
58 + break
59 + except anthropic.RateLimitError:
60 + time.sleep(20 * (attempt + 1))
61 + if resp.stop_reason == "refusal":
62 + print("refusal on batch", i); continue
63 + text = next(bk.text for bk in resp.content if bk.type == "text"); data = json.loads(text)
64 + usage["in"] += resp.usage.input_tokens + (resp.usage.cache_read_input_tokens or 0); usage["out"] += resp.usage.output_tokens; usage["calls"] += 1
65 + for r in data["ratings"]:
66 + r["model"] = model; fh.write(json.dumps(r) + "\n")
67 + fh.flush()
68 + if usage["calls"] % 20 == 0:
69 + print(f"{usage['calls']} calls, {i+len(b)}/{len(todo)} works, tokens in={usage['in']} out={usage['out']}", flush=True)
70 + json.dump(usage, open(f"{d}/usage_{model}.json", "w"), indent=1); print("done", usage)
71 +
72 +
73 +def metrics(root, ontology):
74 + from sklearn.metrics import cohen_kappa_score
75 + d = os.path.join(root, "taxonomy/validation"); df = pd.read_parquet(f"{d}/sample.parquet")
76 + cats = [c["id"] for c in yaml.safe_load(open(ontology))["categories"]]
77 + raters = {}
78 + for f in sorted(os.listdir(d)):
79 + if f.startswith("ratings_") and f.endswith(".jsonl"):
80 + rows = [json.loads(l) for l in open(os.path.join(d, f))]
81 + raters[f[8:-6]] = {r["work_id"]: r for r in rows}
82 + ids = [w for w in df.work_id if all(w in r for r in raters.values())]
83 + rule = {r.work_id: set(r.rule_categories or []) for r in df.itertuples()}
84 + rule_p = {r.work_id: r.primary_category for r in df.itertuples()}
85 + M = {"n_rated_by_all": len(ids), "raters": list(raters)}
86 + def prf(ref_sets, pred_sets):
87 + out = {}
88 + for c in cats:
89 + tp = sum(1 for w in ids if c in ref_sets[w] and c in pred_sets[w]); fp = sum(1 for w in ids if c not in ref_sets[w] and c in pred_sets[w])
90 + fn = sum(1 for w in ids if c in ref_sets[w] and c not in pred_sets[w])
91 + p = tp / (tp + fp) if tp + fp else None; r = tp / (tp + fn) if tp + fn else None
92 + out[c] = {"tp": tp, "fp": fp, "fn": fn, "precision": p, "recall": r, "f1": (2 * p * r / (p + r)) if p and r else (0.0 if (tp + fp + fn) else None)}
93 + micro_tp = sum(v["tp"] for v in out.values()); micro_fp = sum(v["fp"] for v in out.values()); micro_fn = sum(v["fn"] for v in out.values())
94 + mp = micro_tp / max(micro_tp + micro_fp, 1); mr = micro_tp / max(micro_tp + micro_fn, 1)
95 + f1s = [v["f1"] for v in out.values() if v["f1"] is not None]
96 + return {"per_category": out, "micro_precision": mp, "micro_recall": mr, "micro_f1": 2 * mp * mr / max(mp + mr, 1e-9), "macro_f1": float(np.mean(f1s))}
97 + for name, R in raters.items():
98 + sets = {w: set(x for x in R[w]["categories"] if x in cats) for w in ids}
99 + M[f"rules_vs_{name}"] = prf(sets, rule)
100 + M[f"kappa_primary_rules_vs_{name}"] = float(cohen_kappa_score([rule_p.get(w) or "none" for w in ids], [R[w]["primary"] or "none" for w in ids]))
101 + if len(raters) >= 2:
102 + (a, A), (b, B) = list(raters.items())[:2]
103 + M[f"kappa_primary_{a}_vs_{b}"] = float(cohen_kappa_score([A[w]["primary"] or "none" for w in ids], [B[w]["primary"] or "none" for w in ids]))
104 + cons = {w: set(A[w]["categories"]) & set(B[w]["categories"]) for w in ids}
105 + M["rules_vs_consensus"] = prf(cons, rule)
106 + # Jaccard agreement on multi-label sets between raters
107 + M[f"mean_jaccard_{a}_vs_{b}"] = float(np.mean([len(set(A[w]["categories"]) & set(B[w]["categories"])) / max(len(set(A[w]["categories"]) | set(B[w]["categories"])), 1) for w in ids]))
108 + dis = [{"work_id": w, "title": df.set_index("work_id").title[w], "rules": sorted(rule[w]), "rule_primary": rule_p[w], a: sorted(A[w]["categories"]), b: sorted(B[w]["categories"]),
109 + "pi_review": bool(df.set_index("work_id").pi_review[w])} for w in ids if not (set(A[w]["categories"]) & set(B[w]["categories"]) & rule[w]) and (rule[w] or A[w]["categories"] or B[w]["categories"])]
110 + pd.DataFrame(dis).to_csv(f"{d}/disagreements.csv", index=False); M["n_disagreements"] = len(dis)
111 + json.dump(M, open(f"{d}/metrics.json", "w"), indent=1)
112 + print({k: v for k, v in M.items() if not isinstance(v, dict)}); print({k: (v["micro_f1"], v["macro_f1"]) for k, v in M.items() if isinstance(v, dict) and "micro_f1" in v})
113 +
114 +
115 +def main():
116 + ap = argparse.ArgumentParser(); ap.add_argument("--root", required=True); ap.add_argument("--ontology", default=None)
117 + ap.add_argument("--draw", action="store_true"); ap.add_argument("--rate", action="store_true"); ap.add_argument("--metrics", action="store_true")
118 + ap.add_argument("--model", default="claude-haiku-5-5"); ap.add_argument("--env-file", default="~/wp44_uqo/.env"); ap.add_argument("--seed", type=int, default=44)
119 + ap.add_argument("--per-cat", type=int, default=50); ap.add_argument("--n-none", type=int, default=200); ap.add_argument("--batch", type=int, default=10)
120 + a = ap.parse_args(); ont = a.ontology or os.path.join(a.root, "taxonomy/ontology.yaml")
121 + if a.draw: draw(a.root, a.seed, a.per_cat, a.n_none)
122 + if a.rate: rate(a.root, a.model, a.env_file, ont, a.batch)
123 + if a.metrics: metrics(a.root, ont)
124 +
125 +
126 +if __name__ == "__main__":
127 + main()
128
Menu

Theme