# Marker Panel Annotation

Assigns cell-type labels to clusters from a protein marker panel (multiplexed imaging...

- Repository: https://github.com/synthetic-sciences/openscience (4321 stars)
- Category: Data and ML
- License: MIT
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add synthetic-sciences/openscience --skill marker-panel-annotation -g -a claude-code -y`
Codex: `npx skills add synthetic-sciences/openscience --skill marker-panel-annotation -g -a codex -y`
Cursor: `npx skills add synthetic-sciences/openscience --skill marker-panel-annotation -g -a cursor -y`
Gemini CLI: `npx skills add synthetic-sciences/openscience --skill marker-panel-annotation -g -a gemini-cli -y`

## Description

Assigns cell-type labels to clusters from a protein marker panel (multiplexed imaging such as MIBI, CODEX, IMC and CyCIF; mass and flow cytometry; CITE-seq protein), where the labels are judged against an expert reference. Within-dataset normalisation of cluster summaries, lineage first by positive defining markers, subtype only as far as the panel can determine it, marker-poor clusters assigned by exclusion, class-coverage sanity checks, and two independent annotators with adjudication. Use when the output is one label per cluster and the grader is agreement with an expert; for gating single cells in FCS data use flow-cytometry-analysis, and for transcript-based annotation use scanpy or scvi-tools.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Marker-panel cluster annotation

An expert annotating clusters from a marker panel gets two things right that a
first-pass reading gets wrong: the *level* at which each label is stated, and
the clusters that carry almost nothing. Both directions cost equally under an
expert-agreement grader: a subtype the panel cannot support scores like a
wrong lineage, and a broad label where the panel determines the subtype
scores like a miss. Everything below follows from that.

## 1. Summarise within the dataset, never across

- Work one dataset (panel, platform, run) at a time. Intensities are not
  comparable across platforms or panels; a threshold or z-score computed on
  the pooled data is wrong for every dataset in it.
- For each cluster and marker compute three summaries: the mean or median
  intensity, the z-score of that cluster's mean across the clusters of the
  same dataset (which marker is *high for this dataset*), and the fraction of
  the cluster's cells above a per-marker positivity cut taken from the
  marker's own distribution (a bimodal split, or a high percentile of the
  whole dataset when the marker is unimodal). Read all three: a marker with a
  modest mean but 80% of cells positive is a positive marker.
- Print the full cluster-by-marker table before labelling anything. Decide
  from the table, not from the first two markers that come to mind.

## 2. Lineage first, by positive defining markers

Assign the broad lineage from the markers that define it positively, in this
order of precedence, each one excluding the ones below unless the panel says
otherwise:

The rest: https://github.com/synthetic-sciences/openscience/blob/HEAD/backend/cli/skills/biology/marker-panel-annotation/SKILL.md
