Spaces:
Sleeping
Sleeping
| """H1 verification β known-answer check, NOT blind discovery. | |
| Composes the DSL operators over the NAMED expression matrix (real gene symbols) | |
| with hand-picked MMR and immune gene panels, and reports the four numbers the | |
| H1 program should produce on the usable MSI-H-vs-MSS CRC cohort: | |
| 1. medians of `mmr_score` and `immune_score` split by MSI status β MSI-H should | |
| sit LOW on the MMR score and HIGH on the immune score; | |
| 2. `Effect(mmr_score, immune_score, adjust={stage, age})` β the adjusted partial | |
| correlation vs the unadjusted pearson on the same rows, and the n used; | |
| 3. `Fit(state=(mmr_score, immune_score)) β MSI-H` β held-out AUROC and | |
| balanced accuracy. | |
| This module is biology-aware on purpose. The blind-discovery path in | |
| [`engine`](../engine) will instead consume the airgapped view and is forbidden | |
| from importing these gene lists. | |
| """ | |
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| import pandas as pd | |
| from dsl import Cohort, Effect, EffectResult, Fit, FitResult, Load, Reduce, Select | |
| MMR_GENES: list[str] = ["MLH1", "MSH2", "MSH6", "PMS2"] | |
| IMMUNE_GENES: list[str] = ["CD8A", "GZMA", "PRF1"] | |
| LABEL_COL = "msi_status" | |
| POSITIVE_LABEL = "MSI-H" | |
| NEGATIVE_LABEL = "MSS" | |
| def usable_msi_cohort(cohort: Cohort) -> Cohort: | |
| """Restrict to MSI-H vs MSS samples with non-missing stage and age.""" | |
| lab = cohort.labels | |
| clin = cohort.clinical | |
| mask = ( | |
| lab[LABEL_COL].isin([POSITIVE_LABEL, NEGATIVE_LABEL]) | |
| & (clin["stage"] != "NA") | |
| & clin["stage"].notna() | |
| & clin["age"].notna() | |
| ) | |
| return cohort.restrict(mask) | |
| class H1Result: | |
| n_used: int | |
| n_msi_h: int | |
| n_mss: int | |
| mmr_score: pd.Series | |
| immune_score: pd.Series | |
| msi_status: pd.Series | |
| mmr_median_msi_h: float | |
| mmr_median_mss: float | |
| immune_median_msi_h: float | |
| immune_median_mss: float | |
| effect: EffectResult | |
| fit: FitResult | |
| def mmr_separates_correct_direction(self) -> bool: | |
| return self.mmr_median_msi_h < self.mmr_median_mss | |
| def immune_separates_correct_direction(self) -> bool: | |
| return self.immune_median_msi_h > self.immune_median_mss | |
| def run_h1(cohort: Cohort | None = None) -> H1Result: | |
| """Run the full H1 program and return the verification numbers.""" | |
| if cohort is None: | |
| cohort = Load("processed") | |
| cohort = usable_msi_cohort(cohort) | |
| M = cohort.expression | |
| mmr_score = Reduce(Select(M, MMR_GENES), agg="mean") | |
| immune_score = Reduce(Select(M, IMMUNE_GENES), agg="mean") | |
| status = cohort.labels[LABEL_COL] | |
| is_msi_h = status == POSITIVE_LABEL | |
| mmr_medians = mmr_score.groupby(status).median() | |
| immune_medians = immune_score.groupby(status).median() | |
| adjust = pd.DataFrame({ | |
| "stage": cohort.clinical["stage"].astype("category"), | |
| "age": cohort.clinical["age"].astype(float), | |
| }) | |
| effect = Effect(mmr_score, immune_score, adjust) | |
| state = pd.DataFrame({"mmr_score": mmr_score, "immune_score": immune_score}) | |
| fit = Fit(state, is_msi_h.astype(int).values) | |
| return H1Result( | |
| n_used=len(cohort.sample_ids), | |
| n_msi_h=int(is_msi_h.sum()), | |
| n_mss=int((status == NEGATIVE_LABEL).sum()), | |
| mmr_score=mmr_score, | |
| immune_score=immune_score, | |
| msi_status=status, | |
| mmr_median_msi_h=float(mmr_medians.get(POSITIVE_LABEL, float("nan"))), | |
| mmr_median_mss=float(mmr_medians.get(NEGATIVE_LABEL, float("nan"))), | |
| immune_median_msi_h=float(immune_medians.get(POSITIVE_LABEL, float("nan"))), | |
| immune_median_mss=float(immune_medians.get(NEGATIVE_LABEL, float("nan"))), | |
| effect=effect, | |
| fit=fit, | |
| ) | |