karimox commited on
Commit
13d0b34
·
verified ·
1 Parent(s): 8afbc8f

Rename Lodestar -> PRIMO

Browse files
Files changed (4) hide show
  1. README.md +8 -6
  2. app.py +4 -4
  3. evaluator.py +8 -9
  4. scoring.py +1 -1
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Lodestar Benchmark
3
  emoji: 🧬
4
  colorFrom: indigo
5
  colorTo: blue
@@ -10,7 +10,9 @@ app_file: app.py
10
  pinned: false
11
  ---
12
 
13
- # Lodestarblind benchmark for transcriptomic foundation models
 
 
14
 
15
  Embed **every** dataset with your model and upload **one** file. A fixed linear
16
  probe grades each hidden task (a dataset may be scored on several targets) over
@@ -56,16 +58,16 @@ feedback, they just aren't ranked.
56
 
57
  ```bash
58
  pip install -r requirements.txt
59
- export HF_TOKEN=... # read access to the Lodestar datasets
60
  python evaluator.py --submission my_embeddings.parquet
61
  ```
62
 
63
  ## Space configuration
64
 
65
  - Set an **`HF_TOKEN`** Space secret (fine-grained) with: **read** on
66
- `ScientaLab/lodestar` (the public `datasets.yaml` manifest) and
67
- `ScientaLab/lodestar-labels` (the private `tasks.yaml` registry +
68
- `<task_id>/labels.csv`), and **write** on `ScientaLab/lodestar-results` (the
69
  persisted leaderboard).
70
  - Results persist as one normalized `task_results.csv` (`model_name, task_id,
71
  score, submitted_at`) in the results dataset; the leaderboard is recomputed
 
1
  ---
2
+ title: PRIMO Benchmark
3
  emoji: 🧬
4
  colorFrom: indigo
5
  colorTo: blue
 
10
  pinned: false
11
  ---
12
 
13
+ # PRIMOPatient Representations in Multi-Omics
14
+
15
+ **A blind benchmark for transcriptomic foundation models.**
16
 
17
  Embed **every** dataset with your model and upload **one** file. A fixed linear
18
  probe grades each hidden task (a dataset may be scored on several targets) over
 
58
 
59
  ```bash
60
  pip install -r requirements.txt
61
+ export HF_TOKEN=... # read access to the PRIMO datasets
62
  python evaluator.py --submission my_embeddings.parquet
63
  ```
64
 
65
  ## Space configuration
66
 
67
  - Set an **`HF_TOKEN`** Space secret (fine-grained) with: **read** on
68
+ `ScientaLab/primo` (the public `datasets.yaml` manifest) and
69
+ `ScientaLab/primo-labels` (the private `tasks.yaml` registry +
70
+ `<task_id>/labels.csv`), and **write** on `ScientaLab/primo-results` (the
71
  persisted leaderboard).
72
  - Results persist as one normalized `task_results.csv` (`model_name, task_id,
73
  score, submitted_at`) in the results dataset; the leaderboard is recomputed
app.py CHANGED
@@ -1,4 +1,4 @@
1
- """Gradio front-end for the Lodestar public benchmark.
2
 
3
  Upload one embedding file spanning every dataset (rows keyed by ``dataset_id``
4
  + ``sample_id``); a fixed linear probe scores each task (a dataset may carry
@@ -259,15 +259,15 @@ def evaluate(submission_path: str, model_name: str):
259
 
260
 
261
  def build_demo() -> gr.Blocks:
262
- with gr.Blocks(title="Lodestar Benchmark") as demo:
263
  gr.Markdown(
264
- "# 🧬 Lodestar\n\n"
265
  "A **blind benchmark for transcriptomic foundation models** — grade "
266
  "your model's patient-level embeddings against real clinical signal, "
267
  "without ever seeing the labels.\n\n"
268
  "**Submit in 3 steps:**\n"
269
  "1. **Get the data** → download the opaque datasets from "
270
- "[ScientaLab/lodestar](https://huggingface.co/datasets/ScientaLab/lodestar)"
271
  " (start with its `datasets.yaml`).\n"
272
  "2. **Embed every dataset** → build **one** file: `dataset_id`, "
273
  "`sample_id`, then one column per embedding dim (`e0`, `e1`, …). "
 
1
+ """Gradio front-end for the PRIMO public benchmark.
2
 
3
  Upload one embedding file spanning every dataset (rows keyed by ``dataset_id``
4
  + ``sample_id``); a fixed linear probe scores each task (a dataset may carry
 
259
 
260
 
261
  def build_demo() -> gr.Blocks:
262
+ with gr.Blocks(title="PRIMO Benchmark") as demo:
263
  gr.Markdown(
264
+ "# 🧬 PRIMO\n\n"
265
  "A **blind benchmark for transcriptomic foundation models** — grade "
266
  "your model's patient-level embeddings against real clinical signal, "
267
  "without ever seeing the labels.\n\n"
268
  "**Submit in 3 steps:**\n"
269
  "1. **Get the data** → download the opaque datasets from "
270
+ "[ScientaLab/primo](https://huggingface.co/datasets/ScientaLab/primo)"
271
  " (start with its `datasets.yaml`).\n"
272
  "2. **Embed every dataset** → build **one** file: `dataset_id`, "
273
  "`sample_id`, then one column per embedding dim (`e0`, `e1`, …). "
evaluator.py CHANGED
@@ -1,4 +1,4 @@
1
- """Standalone probe for the Lodestar public benchmark.
2
 
3
  Loads one embedding submission that spans every dataset (rows keyed by
4
  ``dataset_id`` + ``sample_id``), then scores each TASK = (dataset, target): a
@@ -22,6 +22,7 @@ the fetch helpers / CLI, imported lazily.
22
 
23
  import argparse
24
  import logging
 
25
  import time
26
  from collections import defaultdict
27
  from dataclasses import dataclass
@@ -41,9 +42,9 @@ TASK_ID = "task_id"
41
  LABEL = "label"
42
  FOLD = "fold"
43
 
44
- PUBLIC_REPO = "ScientaLab/lodestar"
45
- LABELS_REPO = "ScientaLab/lodestar-labels"
46
- RESULTS_REPO = "ScientaLab/lodestar-results"
47
  MANIFEST_FILENAME = "datasets.yaml"
48
  TASKS_FILENAME = "tasks.yaml"
49
  LABELS_FILENAME = "labels.csv"
@@ -98,7 +99,7 @@ def load_tasks_registry(path: str | Path) -> list[dict]:
98
  with open(path) as handle:
99
  data = yaml.safe_load(handle)
100
  tasks = data.get("tasks", []) if isinstance(data, dict) else (data or [])
101
- ids = [_norm_id(t["task_id"]) for t in tasks]
102
  if len(set(ids)) != len(ids):
103
  raise EvaluatorError(f"duplicate task_id in the registry: {ids}")
104
  return tasks
@@ -109,7 +110,7 @@ def load_labels(path: str | Path) -> pd.DataFrame:
109
  df = pd.read_csv(path)
110
  missing = {SAMPLE_ID, LABEL, FOLD} - set(df.columns)
111
  if missing:
112
- raise SubmissionError(f"labels.csv missing columns: {sorted(missing)}")
113
  return df
114
 
115
 
@@ -497,13 +498,11 @@ def _rollup_datasets(outcomes: list[TaskOutcome]) -> list[dict]:
497
 
498
 
499
  def _cli() -> None:
500
- parser = argparse.ArgumentParser(description="Score a Lodestar submission locally.")
501
  parser.add_argument("--submission", required=True, help="CSV/TSV/Parquet/NPZ file")
502
  parser.add_argument("--token", default=None, help="HF token (else env HF_TOKEN)")
503
  args = parser.parse_args()
504
 
505
- import os
506
-
507
  token = args.token or os.environ.get("HF_TOKEN")
508
  result = score_all(args.submission, token)
509
  print(
 
1
+ """Standalone probe for the PRIMO public benchmark.
2
 
3
  Loads one embedding submission that spans every dataset (rows keyed by
4
  ``dataset_id`` + ``sample_id``), then scores each TASK = (dataset, target): a
 
22
 
23
  import argparse
24
  import logging
25
+ import os
26
  import time
27
  from collections import defaultdict
28
  from dataclasses import dataclass
 
42
  LABEL = "label"
43
  FOLD = "fold"
44
 
45
+ PUBLIC_REPO = "ScientaLab/primo"
46
+ LABELS_REPO = "ScientaLab/primo-labels"
47
+ RESULTS_REPO = "ScientaLab/primo-results"
48
  MANIFEST_FILENAME = "datasets.yaml"
49
  TASKS_FILENAME = "tasks.yaml"
50
  LABELS_FILENAME = "labels.csv"
 
99
  with open(path) as handle:
100
  data = yaml.safe_load(handle)
101
  tasks = data.get("tasks", []) if isinstance(data, dict) else (data or [])
102
+ ids = [_norm_id(t[TASK_ID]) for t in tasks]
103
  if len(set(ids)) != len(ids):
104
  raise EvaluatorError(f"duplicate task_id in the registry: {ids}")
105
  return tasks
 
110
  df = pd.read_csv(path)
111
  missing = {SAMPLE_ID, LABEL, FOLD} - set(df.columns)
112
  if missing:
113
+ raise EvaluatorError(f"labels.csv missing columns: {sorted(missing)}")
114
  return df
115
 
116
 
 
498
 
499
 
500
  def _cli() -> None:
501
+ parser = argparse.ArgumentParser(description="Score a PRIMO submission locally.")
502
  parser.add_argument("--submission", required=True, help="CSV/TSV/Parquet/NPZ file")
503
  parser.add_argument("--token", default=None, help="HF token (else env HF_TOKEN)")
504
  args = parser.parse_args()
505
 
 
 
506
  token = args.token or os.environ.get("HF_TOKEN")
507
  result = score_all(args.submission, token)
508
  print(
scoring.py CHANGED
@@ -1,4 +1,4 @@
1
- """Scoring policy for the Lodestar benchmark: predictions -> final scores.
2
 
3
  Everything that turns a model's out-of-fold predictions into leaderboard
4
  numbers lives here, kept apart from the probe and from any I/O so it stays easy
 
1
+ """Scoring policy for the PRIMO benchmark: predictions -> final scores.
2
 
3
  Everything that turns a model's out-of-fold predictions into leaderboard
4
  numbers lives here, kept apart from the probe and from any I/O so it stays easy