target-prioritization ยท diff

git:20260519.9983505 to git:20260520.59814e1

12 added, 19 removed. Audit A to A.

---
name: target-prioritization
- description: Prioritize drug targets from a ranked gene list (e.g., scRNA-seq DE output) by orchestrating parallel API queries against UniProt, OpenTargets, and PubMed, then re-ranking by a composite score combining protein localization, druggability, disease genetics, cross-lineage DE convergence, and research maturity. Use whenever the user wants to filter, triage, prioritize, or "do due diligence" on a list of candidate genes for drug discovery, especially after a DE / DEG analysis when they say things like "which of these should I follow up on", "filter for druggable targets", "make a target dossier", "rank these for tractability", "annotate these genes for druggability", or "build a target report". Trigger even when the user says just "filter these candidate genes" or hands over a CSV from a DE pipeline.
- metadata: {"openclaw":{"requires":{"bins":["python3","curl"]},"emoji":"๐ŸŽฏ"},"version":"0.1.0"}
+ description: Prioritize drug targets from a ranked gene list (e.g., scRNA-seq DE output) by orchestrating parallel API queries against UniProt, OpenTargets, and PubMed, then re-ranking by a composite score combining protein localization, druggability, disease genetics, and research maturity. Use whenever the user wants to filter, triage, prioritize, or "do due diligence" on a list of candidate genes for drug discovery, especially after a DE / DEG analysis when they say things like "which of these should I follow up on", "filter for druggable targets", "make a target dossier", "rank these for tractability", "annotate these genes for druggability", or "build a target report". Trigger even when the user says just "filter these candidate genes" or hands over a CSV from a DE pipeline.
+ metadata: {"openclaw":{"requires":{"bins":["python3","curl"]},"emoji":"๐ŸŽฏ"},"version":"0.2.0"}
---
# Target Prioritization
A multi-source drug-target due-diligence pipeline for ranked gene lists.
## When this skill triggers
The user has a list of candidate genes (typically from a DE / DEG / scRNA-seq
analysis) and wants a per-gene dossier across multiple evidence dimensions
plus a composite re-ranking. The DE statistical rank is just the entry
point; the final priority is informed by protein biology, genetics,
druggability, and research maturity.
Common input shapes:
- A CSV with a `gene` column (DE output like `expression_table_pass_either_1s.csv`)
- A plain-text gene list (one symbol per line)
- A list of symbols inline in the user's message
## Output
Three files inside `<output_dir>/`:
1. **`targets_report.md`** โ€” one section per gene, sorted by composite score, with a
short LLM-written rationale and recommended next step
2. **`targets_summary.csv`** โ€” flat table for sorting/filtering in Excel/pandas
3. **`raw_data/<source>.json`** โ€” raw API responses (audit trail, reusable across
future re-scorings)
## Pipeline
```
input gene list
โ”‚
โ–ผ
scripts/orchestrate.py
โ”‚
โ”œโ”€โ–บ fetch_uniprot.py โ†’ protein localization, surface, MHC, coding
โ”œโ”€โ–บ fetch_opentargets.py โ†’ tractability, approved drugs, associated
โ”‚ diseases (subsumes GWAS Catalog via OT's
โ”‚ integrated genetics evidence)
- โ”œโ”€โ–บ fetch_pubmed.py โ†’ paper counts (total + focus_disease + cell_context)
- โ””โ”€โ–บ fetch_local_de.py โ†’ cross-lineage DE in sibling project dirs
- (scans hu_de_*, pert_de_*, cluster_degs* in
- parent project for the same gene)
+ โ””โ”€โ–บ fetch_pubmed.py โ†’ paper counts (total + focus_disease + cell_context)
โ”‚
โ–ผ
scripts/aggregate.py
โ”‚
โ–ผ
output_dir/
โ”œโ”€ raw_data/*.json
โ”œโ”€ targets_summary.csv โ† composite-score-ranked
โ””โ”€ targets_report.md โ† Claude fills the rationale sections
```
## How to invoke
```bash
python3 ~/myagents/myskills/target-prioritization/scripts/orchestrate.py \
--input <gene_list.csv_or_txt> \
--output <output_dir> \
[--gene-col gene] \
- [--project-root <repo_root_for_local_de_scan>] \
[--top 50]
```
- `--input` accepts a CSV (with `--gene-col`, default `gene`), a `.txt`/`.tsv`,
or any file where the first column has gene symbols. Skips header if first
cell is `gene`/`symbol`/case-insensitive.
- - `--project-root` enables the local-evidence scan; if omitted, that
- dimension is skipped and the composite score down-weights accordingly.
- `--top` limits the dossier to the top N input genes (default 50) โ€” input
order is preserved up to that cut, then composite-score re-ranks within.
- `orchestrate.py` runs the five fetchers in parallel (Python threads, since
+ `orchestrate.py` runs the three fetchers in parallel (Python threads, since
all calls are I/O-bound). Each writes a self-contained JSON to
`<output_dir>/raw_data/<source>.json`. Then `aggregate.py` merges them,
computes the composite score using `weights.yaml`, writes
`targets_summary.csv`, and emits a `targets_report.md` skeleton with one
section per gene โ€” the **rationale and risks fields are left blank for
Claude to fill**.
## Composite score
Weights live in `weights.yaml` and can be overridden per-run with `--weights`.
- Defaults aim for "find druggable, genetically supported, cross-lineage-robust
- targets with known biology":
+ Defaults aim for "find druggable, genetically supported targets with known
+ biology":
```
- composite_score = w1 * cross_lineage_score (DE convergence across pipelines/lineages)
- + w2 * druggability_score (approved drugs, tractability, clin trials)
- + w3 * disease_genetics_score (OpenTargets disease associations + focus-disease bonus)
- + w4 * tractability_bonus (surface or secreted vs intracellular)
- + w5 * expression_score (from input DE if present)
- + w6 * novelty_bonus (favors moderately studied)
- - w7 * over_studied_penalty (PubMed total > cap โ†’ diminishing returns)
+ composite_score = w1 * druggability_score (approved drugs, tractability, clin trials)
+ + w2 * disease_genetics_score (OpenTargets disease associations + focus-disease bonus)
+ + w3 * tractability_bonus (surface or secreted vs intracellular)
+ + w4 * expression_score (from input DE if present)
+ + w5 * novelty_bonus (favors moderately studied)
+ - w6 * over_studied_penalty (PubMed total > cap โ†’ diminishing returns)
```
Each component is normalized to [0, 1]. The composite is therefore
roughly in [-w7, sum(w1..w6)] and is min-max rescaled before reporting.
**Read `weights.yaml` for the current defaults.**
## Writing the rationale
After `aggregate.py` produces `targets_report.md` with blank rationale
slots, Claude reads the per-gene dossier rows and writes a 2-3 sentence
rationale per gene. Use the template in `prompts/rationale_template.md` โ€”
it specifies the structure (one line on the most compelling evidence, one
line on the main risk, one line on the suggested next experimental step).
For the top 5โ€“10 genes by composite score, also write a short executive
summary at the top of the report. Keep it factual and grounded in the
dossier data; do not hallucinate beyond what the JSONs contain.
## Data source notes
All free, no API key needed. Rate limits handled in fetchers:
- **UniProt REST** โ€” 100 req/sec, batched via `accession` query
- **OpenTargets GraphQL** โ€” generous, single endpoint; provides disease genetics signal via integrated `associatedDiseases`
- **PubMed E-utilities** โ€” 3 req/sec without key; fetchers respect this
For deeper API details and field mappings, see
`references/api_endpoints.md`.
## Retargeting the focus disease + cell context
The skill ships with an autoimmunity / T-cell default but is intentionally
disease-agnostic. Two edits switch the focus:
- `scripts/fetch_opentargets.py` and `scripts/aggregate.py` โ€” change
`FOCUS_DISEASE_TERMS` to the lowercased substrings that should mark a
drug or disease association as "in-scope" (e.g.
`("cancer", "carcinoma", "lymphoma")` for oncology;
`("alzheimer", "parkinson", "huntington", "als")` for neurodegeneration;
`("diabetes", "obesity", "fatty liver", "nash")` for metabolic disease).
- `scripts/fetch_pubmed.py` โ€” adjust the `focus_disease` and
`cell_context` queries in `CONTEXTS` (e.g.
`"hepatocyte"`, `"neuron"`, `"macrophage"` instead of `"T cell"`).
No other code changes are needed; the CSV column names already use the
neutral `focus_disease_*` / `cell_context` prefixes.
## When NOT to use this skill
- Single-gene look-ups (overkill โ€” just ask Claude to web-search)
- Non-human genes (most APIs are human-only; fetchers will silently return empty)
- Pure literature review without target ambition โ€” use `scholar-deep-research` or `literature-review` instead
## Iteration tips
The pipeline is designed to be re-runnable cheaply:
- Raw JSON cache means re-scoring with different `weights.yaml` is a one-second `aggregate.py` rerun
- To add a new evidence source, add `scripts/fetch_<source>.py` that writes
`raw_data/<source>.json` with the same `{gene: {fields}}` shape, then add
a corresponding term in `aggregate.py::compute_composite_score`.