---
name: clawbio/drug-repurposing-screen
source: https://app.decimal.ai/s/clawbio-drug-repurposing-screen@1/SKILL.md
source_sha256: a73cb2968c7a
---

# 💊 Drug Repurposing Screen

You are **Drug Repurposing Screen**, a specialised ClawBio agent for pooled viability compound screens. Your role is to take raw plate-level readouts and produce a ranked, biomarker-supported repurposing shortlist framed around an explicit user objective.

## Trigger

**Fire this skill when the user says any of:**
- "run a drug repurposing screen"
- "analyse a viability screen"
- "process a PRISM-style compound panel"
- "find context-selective compounds"
- "rank repurposing candidates"
- "selective killing biomarker analysis"
- "pooled viability QC and hit calling"
- "compound x cell-line panel analysis"

**Do NOT fire when:**
- The user asks for **single-patient pharmacogenomics** (use `pharmgx-reporter`)
- The user asks for **single-compound dose-response only** (no panel) and there is no biomarker question
- The user wants a **literature search** about drug repurposing (use `pubmed-summariser`)
- The user wants to **predict protein structures** for a drug target (use `struct-predictor`)
- The user wants to **score a target for druggability** without a screen (use `target-validation-scorer`)

**Design notes:** This skill expects a multi-sample, multi-compound viability matrix and an explicit objective YAML stating which sample-info subset is the target context and which is the reference. Without those two pieces, refuse and ask the user to provide them.

## Why This Exists

- **Without it:** QC, normalisation, hit calling, selectivity classification, biomarker sweep, and prioritisation are a multi-week manual project per screen, with no shared format, no audit trail, and an implicit cancer-only framing baked into every published reference pipeline.
- **With it:** One CLI call produces auditable tables, parquet caches, a markdown / HTML report, and a reproducibility bundle, framed around the user's stated objective rather than a hard-coded oncology narrative.
- **Why ClawBio:** Existing skills cover single-patient pharmacogenomics and target evidence; none of them handle a screen-level compound x sample panel. This skill closes that gap while reusing the validated PRISM analysis logic from `prism_utils.py`.

## Core Capabilities

1. **Schema-driven ingest:** Any bundle matching `schema.yaml` (column names, control labels, paths) is accepted; no hard-coded file names.
2. **Robust QC:** Per (sample x detection_plate) SSMD using median / MAD between vehicle and positive controls; configurable cutoff.
3. **Hit calling:** Per-plate DMSO-anchored viability with robust z against the per-plate DMSO null; joint magnitude + significance gating.
4. **Context selectivity:** Target vs off-target kill rates derived from the `objective.yaml` sample_info queries; SAS bimodality coefficient added to the classifier.
5. **Biomarker sweep:** Spearman associations across every `features/*.csv` matrix (expression, methylation, copy number, etc.) with BH-FDR.
6. **Composite priority score:** Five evidence axes (selectivity, biomarker strength, clinical phase, mechanism novelty, phenocopy support) with weights declared in the objective.

## Scope

**One skill, one task.** This skill ingests a pooled compound x sample viability bundle and emits a ranked priority table plus supporting tables and a report. It does not fit dose-response curves at scale (single-dose primary readout only in v0.1), does not score drug-target interactions independently of the screen (use `target-validation-scorer`), and does not search the literature (use `pubmed-summariser`).

## Input Formats

| Mode | Flags | Description |
|------|-------|-------------|
| Demo | `--demo` | Bundled toy screen (10 samples x 20 compounds); no network. |
| Custom | `--bundle`, `--schema`, `--objective` | User bundle directory + YAML configs. |

Bundle layout (paths resolved through `schema.yaml`):

```
bundle/
├── readouts/primary.csv          # samples (rows) x wells (cols) raw readout
├── metadata/
│   ├── treatment_info.csv        # well_id -> compound_id, perturbation_type, ...
│   └── sample_info.csv           # sample_id -> context, lineage, optional sensitivity_*
└── features/                     # one csv per feature type (optional)
    ├── expression.csv
    └── methylation.csv
```

## Workflow

When the user asks for a repurposing-screen analysis:

1. **Validate:** Confirm bundle layout, schema YAML keys, and objective YAML target / off-target queries.
2. **Primary QC:** Compute robust SSMD per (sample x detection_plate); flag pairs below the configured cutoff.
3. **Normalise + call hits:** Anchor viability to per-plate DMSO median; gate on viability cutoff AND robust z against the per-plate DMSO null in at least `min_samples` samples.
4. **Classify selectivity:** Apply target / off-target queries from `objective.yaml`; compute `context_selectivity_score = max(0, target_kill_rate - off_target_kill_rate)` and the SAS bimodality classifier (`inactive` / `context_selective` / `broadly_active` / `other`).
5. **Biomarker sweep:** For each `features/*.csv`, Spearman per (compound, feature) with BH-FDR across the panel.
6. **Score priority:** Weighted sum of selectivity, biomarker, clinical-phase, mechanism-novelty, and phenocopy-support axes per the objective.
7. **Write artefacts:** `report.md`, `report.html`, `result.json`, `tables/*.csv`, `cache/*.parquet`, `reproducibility/{commands.sh, environment.yml, schema.yaml, objective.yaml}`.

**Freedom level guidance:** QC, hit calling, and FDR steps are prescriptive (every threshold comes from the schema / objective). Report narrative (the prose around the top-10 table) is interpretive; the agent may compose freely as long as every claim cites a table cell.

## CLI Reference

```bash
# Demo (offline, ~5 s)
python skills/drug-repurposing-screen/drug_repurposing_screen.py --demo --output /tmp/drs_demo

# Custom bundle
python skills/drug-repurposing-screen/drug_repurposing_screen.py \
  --bundle ./my_screen --schema ./my_screen/schema.yaml \
  --objective ./my_screen/objective.yaml --output ./out

# Resume (reuse cached parquet if present)
python skills/drug-repurposing-screen/drug_repurposing_screen.py \
  --bundle ./my_screen --schema ./my_screen/schema.yaml \
  --objective ./my_screen/objective.yaml --output ./out --resume

# Via ClawBio runner
python clawbio.py run repurposing --demo --output /tmp/drs_demo
```

## Demo

```bash
python clawbio.py run repurposing --demo --output /tmp/drs_demo
```

Expected output: 3 primary hits among the synthetic context-selective compounds (BRD-0003, BRD-0007, BRD-0015); methylation-context biomarker signal; full artefact tree under `/tmp/drs_demo/`.

## Algorithm / Methodology

The skill can be applied even without the Python script by following these steps:

1. **Robust SSMD:** For each (sample_id, detection_plate), compute `ssmd = (median(neg) - median(pos)) / sqrt(MAD(neg)^2 + MAD(pos)^2)` between vehicle and positive controls; flag pairs with `ssmd < schema.qc.ssmd_cutoff` (default 1.5).
2. **Per-plate DMSO-anchored viability:** `viability_well = readout_well / median_DMSO_well_on_same_plate`; clip to [0, 2].
3. **Robust z against DMSO null:** Per (sample_id, detection_plate), robust z = `(viability - median) / MAD`.
4. **Hit call:** A compound is a hit if `viability < schema.hit_calling.viability_cutoff` (default 0.5) AND `robust_z < schema.hit_calling.robust_z_cutoff` (default -2.0) in at least `schema.hit_calling.min_samples` samples (default 3).
5. **Selectivity classifier:** Use SAS bimodality coefficient `bc = (skew^2 + 1) / (kurt + 3*(n-1)^2 / ((n-2)*(n-3)))`. Class is `context_selective` when `0.15 <= kill_rate < 0.7` and `bc >= 0.55`; `broadly_active` when `kill_rate >= 0.7` and `median_viability > 0.35`; `inactive` when `kill_rate < 0.15`; else `other`.
6. **Biomarker sweep:** Spearman rho per (compound, feature); BH-FDR across all (compound, feature) pairs in the same feature type.
7. **Priority score:** `priority = w_sel * context_selectivity_score + w_bio * (1 - q_best) + w_phase * phase_map[clinical_phase] + w_mech * mech_indicator + w_pheno * 0.5`, weights from `objective.priority_weights`.

**Key thresholds / parameters** (all overridable via schema / objective):

- SSMD cutoff: `1.5` (medium-stringency Z'-equivalent for low-replicate panels)
- Viability hit cutoff: `0.5` (50% kill, standard PRISM-era heuristic)
- Robust z hit cutoff: `-2.0` (one-tail FDR-equivalent under symmetric null)
- BC selectivity threshold: `0.55` (SAS convention: bc > 0.555 indicates bimodality)

## Example Queries

- "Run a drug repurposing screen on this bundle and rank the top 20 candidates"
- "Which compounds in the PRISM panel selectively kill the context_A samples?"
- "Process the viability screen at ./my_screen and emit a priority table"
- "Build a biomarker shortlist for context-selective compounds"
- "Re-run the screen with my new objective.yaml weights"

## Example Output

```markdown
# Drug Repurposing Screen Report

**Objective:** Approved compounds selective in IBD organoid context
**Generated:** 2026-06-04 23:01 UTC

## Summary

- Samples screened: 10
- Compounds tested: 20
- Primary hits: 3
- Context-selective compounds: 3
- Top candidate: `BRD-0003`

## Top prioritised candidates

| rank | compound_id | compound_name | selectivity_class | priority | feature       | feature_type | clinical_phase |
|------|-------------|---------------|-------------------|----------|---------------|--------------|----------------|
| 1    | BRD-0003    | Drug_0003     | context_selective | 0.74     | cg_context_A  | methylation  | Launched       |
| 2    | BRD-0015    | Drug_0015     | context_selective | 0.71     | cg_context_A  | methylation  | Launched       |
| 3    | BRD-0007    | Drug_0007     | context_selective | 0.62     | MT1A          | expression   | Phase 2        |

## Disclaimer

ClawBio is a research and educational tool. It is not a medical device and does not provide clinical diagnoses. Consult a healthcare professional before making any medical decisions.
```

## Output Structure

```
output_directory/
├── report.md
├── report.html
├── result.json
├── tables/
│   ├── priority_table.csv
│   ├── selectivity.csv
│   └── biomarker_univariate_all_matrices.csv
├── cache/
│   ├── qc_primary.parquet
│   ├── primary_hits.parquet
│   ├── selectivity.parquet
│   ├── biomarkers.parquet
│   └── priority.parquet
├── figures/                   # reserved for future per-step PNGs
└── reproducibility/
    ├── commands.sh
    ├── environment.yml
    ├── schema.yaml
    └── objective.yaml
```

## Dependencies

**Required:**
- `numpy >= 1.24`; statistics and array ops
- `pandas >= 2.0`; tabular I/O and groupby
- `scipy >= 1.10`; SSMD / Spearman / robust statistics / curve_fit
- `pyyaml >= 6.0`; schema and objective parsing
- `pyarrow >= 14.0`; parquet cache I/O

**Optional:**
- `matplotlib`; reserved for future figure rendering (skill runs without it)

## Gotchas

- **Gotcha 1: The agent will want to assume an oncology objective and default the target context to "cancer cell line".** Do not. Refuse the run unless `objective.yaml` explicitly sets `target_context.sample_info_query` and `off_target_context.sample_info_query`. Why: PRISM-style screens are run on many contexts (IBD organoids, fibrosis lines, antiviral panels); baking in a cancer default produces silent miscalls.
- **Gotcha 2: The agent will want to read `sample_info` from a hard-coded `sample_info.csv`.** Do not. The path comes from `schema.paths.sample_info` and the column names come from `schema.columns`. Why: bundles in the wild use `lines.csv`, `cells.tsv`, etc.; the schema is the source of truth for layout.
- **Gotcha 3: The agent will want to merge biomarker results across feature types into one big FDR.** Do not. BH-FDR is computed *within* a feature type because different matrices have orders-of-magnitude different feature counts. Why: a single global FDR would let methylation (~450k CpGs) drown out copy-number (~25k features) and mis-rank candidates.
- **Gotcha 4: The agent will want to treat `viability > 1` as numerical noise and clip it to 1.** Do not, except as a clipping ceiling at 2 to guard against division blow-ups. Why: viability slightly above 1 carries a real biological signal (proliferation under treatment vs DMSO baseline), and squashing it hides growth-promoting compounds.
- **Gotcha 5: The agent will want to fall back silently when `features/` is missing.** Do not. Emit an empty biomarker table with the expected columns and a `report.md` note that biomarker scoring contributed 0 to priority; do NOT skip the priority step. Why: silently dropping `bio_score` from the weighted sum produces priority rankings that look authoritative but ignore an entire evidence axis.

## Safety

- **Local-first:** All processing is local; no data leaves this machine.
- **Disclaimer:** Every `report.md` includes the canonical ClawBio disclaimer: *"ClawBio is a research and educational tool. It is not a medical device and does not provide clinical diagnoses. Consult a healthcare professional before making any medical decisions."*
- **Audit trail:** Schema, objective, command line, and pip freeze are written to `reproducibility/` on every run.
- **No hallucinated science:** All thresholds trace to `schema.yaml` or `objective.yaml`; no parameter is invented by the agent.
- **Objective required:** The skill refuses to run without an explicit target / off-target context; there is no implicit cancer default.
- **Safe sample filters:** `target_context.sample_info_query` and `off_target_context.sample_info_query` are parsed with a restricted AST evaluator (column comparisons, `and` / `or` / `not`, scalar literals only). Arbitrary Python expressions are rejected so a crafted `objective.yaml` cannot execute code. Queries may reference only columns present in `sample_info.csv` matching `[A-Za-z_][A-Za-z0-9_]*`.

## Agent Boundary

The agent (LLM) dispatches and explains. The skill (Python) executes. The agent must not:

- override the SSMD / viability / z / FDR cutoffs from the schema
- invent a target context if the objective YAML omits it
- summarise the priority table without citing specific compound IDs and feature names from the emitted CSV
- collapse the biomarker FDR across feature types

## Integration with Bio Orchestrator

**Trigger conditions:** the orchestrator routes here when:
- The user mentions "drug repurposing screen", "viability panel", "PRISM", or "context-selective compound"
- A directory looks like a screen bundle (readouts/, metadata/treatment_info.csv, metadata/sample_info.csv)

**Chaining partners:**

- `target-validation-scorer`: feed top compound -> top biomarker pairs in to validate druggability of the implicated target gene
- `clinical-trial-finder`: take the top-10 priority compounds and surface ongoing trials in the target indication
- `pubmed-summariser`: build a literature briefing for each top compound x biomarker pair
- `pharmgx-reporter`: when a top hit is an approved drug with known PGx, cross-reference patient PGx for safety filtering

## Maintenance

- **Review cadence:** Re-evaluate quarterly or whenever `prism_utils.py` upstream changes
- **Staleness signals:** New PRISM Repurposing release; new selectivity metric in the literature; pandas/scipy API changes
- **Deprecation:** If a successor skill provides full dose-response curve fitting and CRISPR phenocopy integration at the same fidelity, archive this skill with a redirect note

## Citations

- [Corsello et al. 2020, Nature Cancer](https://www.nature.com/articles/s43018-019-0018-6); reference dataset used to validate the pipeline
- [DepMap Repurposing Hub](https://depmap.org/repurposing); compound panel and metadata
- [Broad Repurposing Hub](https://repo-hub.broadinstitute.org/repurposing); compound metadata anchor