Skip to content
Development
Skill

/pathml

Computational pathology toolkit for whole-slide images (WSIs): load slides, extract tiles, stain normalization, nuclear segmentation, feature extraction, and ML training. Supports H&E and multiplex. For end-to-end pipelines from raw WSIs to quantitative outputs.

From plugin
sciagent-skills
363200 skills
Install
$ npx -y skills add jaechang-hits/SciAgent-Skills --skill pathml --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/pathml

Context preview

The summary Claude sees to decide when to auto-load this skill.

Computational pathology toolkit for whole-slide images (WSIs): load slides, extract tiles, stain normalization, nuclear segmentation, feature extraction, and ML training. Supports H&E and multiplex. For end-to-end pipelines from raw WSIs to quantitative outputs.

SKILL.md

pathml.SKILL.md
name: "pathml"
description: "Computational pathology toolkit for whole-slide images (WSIs): load slides, extract tiles, stain normalization, nuclear segmentation, feature extraction, and ML training. Supports H&E and multiplex. For end-to-end pipelines from raw WSIs to quantitative outputs."
license: "GPL-2.0"

pathml

Overview

PathML is a Python toolkit designed for computational pathology workflows on whole-slide images (WSIs). It provides a unified pipeline from raw slide files (SVS, NDPI, MRXS, TIFF) through tile extraction, preprocessing (stain normalization, nuclear segmentation, tissue detection), feature extraction, and machine learning. PathML integrates with popular Python ML and image processing libraries while abstracting the complexity of WSI handling through its `SlideData` and `Pipeline` abstractions.

When to Use

  • **Processing whole-slide H&E images**: Tiling a large WSI, normalizing staining variability across slides from different scanners or batches.
  • **Nuclear segmentation on pathology slides**: Detecting and segmenting nuclei in H&E or DAPI-stained WSIs using built-in segmentation pipelines.
  • **Building ML training datasets from WSIs**: Extracting tiles with associated labels for training tissue classifiers, tumor detectors, or survival prediction models.
  • **Multiplex immunofluorescence (mIF) image analysis**: Processing multi-channel IF slides with channel-specific preprocessing and feature extraction.
  • **Stain normalization across cohorts**: Applying Macenko or Vahadane stain normalization to harmonize H&E slides from multiple institutions.
  • **Feature extraction for downstream ML**: Extracting handcrafted or deep learning features from tiles for patient-level prediction tasks.
  • For standard 2D microscopy images (non-WSI), use `scikit-image` or `cellpose` directly without PathML overhead.

Prerequisites

  • **Python packages**: `pathml`, `torch`, `torchvision`, `numpy`, `scikit-image`, `openslide-python`
  • **System**: OpenSlide C library (required for WSI reading)
  • **Data requirements**: WSI files in SVS, NDPI, MRXS, or TIFF format; GPU recommended for segmentation
  • **Environment**: Python 3.8+, CUDA-compatible GPU for deep learning preprocessing
# Install system dependency first
conda install -c conda-forge openslide

# Install PathML
pip install pathml

# For GPU support
pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cu118

Quick Start

from pathml.core import SlideData
from pathml.preprocessing import Pipeline
from pathml.preprocessing.transforms import BoxBlur, TissueDetectionHE

# Load → build pipeline → tile → preprocess
slide = SlideData("tumor.svs", name="demo")
pipeline = Pipeline([BoxBlur(kernel_size=3), TissueDetectionHE(mask_name="tissue")])
slide.run(pipeline, tile_size=256, tile_stride=256)

# Inspect tiles
from pathml.core import Tile
tiles = [t for t in slide.tiles if t.masks["tissue"].any()]
print(f"Tissue tiles: {len(tiles)} of {len(slide.tiles)}")

Workflow

Step 1: Load a Whole-Slide Image

from pathml.core import SlideData

# Load an H&E whole-slide image
slide = SlideData("path/to/slide.svs", name="tumor_slide_001")
print(f"Slide name: {slide.name}")
print(f"Slide shape: {slide.slide.shape}")
print(f"Slide properties: {slide.slide.properties}")

Step 2: Define a Preprocessing Pipeline

from pathml.preprocessing import Pipeline
from pathml.preprocessing.transforms import (
    BoxBlur,
    TissueDetectionHE,
    HEStainNormalization,
)

# Build a preprocessing pipeline for H&E slides
pipeline = Pipeline([
    BoxBlur(kernel_size=5),                       # smooth image
    TissueDetectionHE(mask_name="tissue"),         # detect tissue regions
    HEStainNormalization(target="normalize"),       # normalize H&E staining
])
print(f"Pipeline steps: {len(pipeline.transforms)}")

Step 3: Create a TileDataset

from pathml.core import TileDataset

# Tile the slide into 256x256 patches at 20x magnification
slide.generate_tiles(
    shape=(256, 256),
    stride=(256, 256),
    pad=False,
    level=0,           # pyramid level 0 = highest resolution
    coords_format="fractional",
)
print(f"Total tiles generated: {len(slide.tiles)}")

Step 4: Run the Preprocessing Pipeline

# Apply preprocessing pipeline to all tiles
slide.run(pipeline, distributed=False, tile_pad=False)
print("Pipeline complete — tiles preprocessed")

# Inspect a single tile
tile = slide.tiles[0]
print(f"Tile shape: {tile.image.shape}")      # (256, 256, 3)
print(f"Tile masks: {list(tile.masks.keys())}")

Step 5: Nuclear Segmentation

from pathml.preprocessing.transforms import NuclearSegmentation

# Run Hematoxylin-channel nuclear segmentation
seg_pipeline = Pipeline([
    TissueDetectionHE(mask_name="tissue"),
    NuclearSegmentation(mask_name="nuclei"),
])

slide.run(seg_pipeline, distributed=False)

# Count nuclei per tile
for tile in list(slide.tiles)[:5]:
    n_nuclei = tile.masks["nuclei"].max()
    print(f"Tile {tile.coords}: {n_nuclei} nuclei detected")

Step 6: Feature Extraction

import numpy as np
from pathml.core import SlideDataset

features = []
for tile in slide.tiles:
    if "tissue" in tile.masks and tile.masks["tissue"].any():
        img = tile.image
        feat = {
            "mean_r":    img[:, :, 0].mean(),
            "mean_g":    img[:, :, 1].mean(),
            "mean_b":    img[:, :, 2].mean(),
            "std_r":     img[:, :, 0].std(),
            "n_nuclei":  int(tile.masks["nuclei"].max()) if "nuclei" in tile.masks else 0,
            "tile_x":    tile.coords[0],
            "tile_y":    tile.coords[1],
        }
        features.append(feat)

import pandas as pd
df = pd.DataFrame(features)
df.to_csv("slide_features.csv", index=False)
print(f"Extracted features from {len(df)} tissue tiles -> slide_features.csv")

Step 7: Save and Export Processed Slide

Read more
Ships withsciagent-skills

Turn your AI coding agent into a life sciences expert — 199 bioinformatics skills for Claude Code covering RNA-seq, single-cell analysis, genomics, proteomics, drug discovery, and more. Boosted BixBench from 65% to 92%. Open source.

Get the whole plugin

Other skills on sciagent-skills.