Skip to content
AI & Agents
Skill

/genomic-coordinates

Convert genomic intervals between coordinate conventions, normalise and compare variant representations, and detect assembly or contig-naming mismatches before they corrupt an analysis. Use whenever coordinates cross a format, tool, or assembly boundary - converting between BED,

From plugin
k-dense-ai-scientific-agent-skills
45k165 skills
Install
$ npx -y skills add k-dense-ai/claude-scientific-skills --skill genomic-coordinates --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/genomic-coordinates

Context preview

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

Convert genomic intervals between coordinate conventions, normalise and compare variant representations, and detect assembly or contig-naming mismatches before they corrupt an analysis. Use whenever coordinates cross a format, tool, or assembly boundary - converting between BED,

SKILL.md

genomic-coordinates.SKILL.md
name: genomic-coordinates
description: Convert genomic intervals between coordinate conventions, normalise and compare variant representations, and detect assembly or contig-naming mismatches before they corrupt an analysis. Use whenever coordinates cross a format, tool, or assembly boundary - converting between BED, GFF/GTF, VCF, SAM/BAM, WIG, PSL, genePred, Picard interval_list, or region strings; reconciling 0-based half-open with 1-based inclusive; left-aligning or trimming indels; checking whether two variant records describe the same change; mapping genomic to transcript, CDS, or protein positions; auditing a BED/GTF/VCF for convention violations; or diagnosing GRCh37 vs hg19 vs GRCh38 vs T2T, chr-prefix, and liftover problems. Triggers include "off by one", "0-based", "1-based", "half-open", "coordinate system", "left-align", "normalize variant", "bcftools norm", "chr prefix", "wrong genome build", "liftover", "REF mismatch", and "HGVS".
license: MIT
compatibility: Requires Python 3.11+. Scripts use only the standard library - no third-party packages and no network access. Variant normalisation needs a reference FASTA, and uses its .fai index when one is present.
allowed-tools: Read Write Edit Bash
metadata:
  version: "1.1"
  skill-author: K-Dense Inc.

Genomic Coordinates

When to use

Any time a coordinate crosses a boundary: between two file formats, between two tools, between two assemblies, or between the genome and a transcript.

The rule

**A coordinate is three facts, not one: the number, the convention it is written in, and the assembly it was measured against.** Carry all three or the number is not interpretable.

Coordinate errors are the quietest class of bug in genomics. An off-by-one BED file parses, sorts, and intersects without complaint. A GRCh37 VCF joined against a GRCh38 annotation returns rows. A right-shifted indel simply fails to match its entry in ClinVar, and the result is a variant reported as novel. Nothing raises an error; the answer is just wrong, and it is wrong in a direction that looks plausible.

So: convert with the table, not from memory, and verify against the reference whenever a reference is available.

The two conversions

1-based inclusive  ->  0-based half-open :  start - 1,  end
0-based half-open  ->  1-based inclusive :  start + 1,  end

The end coordinate never moves. If a conversion changed both numbers, it is wrong.

Which format is which

| 0-based, half-open | 1-based, inclusive | | --- | --- | | BED, bedGraph, bigWig, narrowPeak | GFF3, GTF, VCF | | BAM/CRAM (binary POS) | SAM (text POS) | | PSL, genePred, refFlat | WIG, Picard interval_list | | MAF (UCSC multiple alignment) | MAF (TCGA mutation annotation) | | PyRanges, pybedtools | GRanges/IRanges, samtools & UCSC & Ensembl region strings |

Both "MAF" formats exist, they mean different things, and they disagree. UCSC serves 0-based files through a 1-based browser box. `references/format-conventions.md` has the full table with per-format detail.

cd skills/genomic-coordinates/scripts

python3 convert_coords.py --list                          # the table
python3 convert_coords.py --from bed --to gff chr1 999 1000
python3 convert_coords.py --from ucsc --to bed "chr7:5,530,601-5,530,625"
python3 convert_coords.py --from granges --to pyranges --input regions.tsv
contig  input                 output           length  status  detail
chr7    chr7:5530601-5530625  5530600-5530625  25      ok

Zero-length BED features (`chromStart == chromEnd`, a legal insertion point) are reported as `unrepresentable` rather than converted to `end = start - 1`. Exit code is 1 when any interval is degenerate or invalid.

Variants are not intervals

A VCF `POS` for an indel is the **anchor base** — the base *before* the event, itself unchanged. And the same change can be written many ways: `chr1:7:CAC:C`, `chr1:3:CAC:C` and `chr1:2:GCA:G` are one deletion. Joining, deduplicating, or looking up variants before normalising loses real matches silently, and it loses them preferentially in repeats, where indels concentrate.

Normalise — trim to parsimony, then left-align against the reference — before any comparison:

python3 normalize_variant.py --fasta ref.fa chr1 7 CAC C
python3 normalize_variant.py --fasta ref.fa --split --input cohort.vcf
python3 normalize_variant.py --fasta ref.fa --compare chr1:7:CAC:C chr1:2:GCA:G
input         normalized    type      pos_shift  ref_check  changed
chr1:7:CAC:C  chr1:2:GCA:G  deletion  5          ok         yes

Every record's `REF` is checked against the FASTA first. A `MISMATCH` means the variants and the reference are different assemblies — stop and run `check_contigs.py` rather than adjusting coordinates. Multi-allelic records must be split with `--split` **before** normalising, never after.

HGVS shifts indels the opposite way, 3'-most along the transcript. For a minus-strand gene that is the opposite genomic direction from VCF's left-alignment. Details and the full procedure: `references/variant-representation.md`.

Check the assembly before trusting a join

python3 check_contigs.py --identify unknown.fa.fai
python3 check_contigs.py variants.vcf annotation.gtf --genome GRCh38.fa.fai
file          kind    contigs  naming        assembly  detail
ref.fa.fai    sizes   25       plain         GRCh37    24/24 primary chromosome lengths match;
                                                       chrM is 16569 bp, i.e. GRCh37/38 (rCRS MT)

The script reads `.fai`, `.chrom.sizes`, VCF headers, SAM headers, FASTA, BED, and GTF/GFF, identifies the assembly from primary-chromosome lengths, and reports every reason a join between two files would go wrong: naming mismatch, length conflict, coordinates past a contig end, contigs present in one file only. Exit code 1 on any incompatibility.

**GRCh37 and hg19 differ only in the mitochondrion** — 16,569 bp (rCRS) versus 16,571 bp. N

Read more
Ships withk-dense-ai-scientific-agent-skills

🔔 Claude Scientific Skills is now Scientific Agent Skills. Same skills, broader compatibility — now works with any AI agent that supports the open Agent Skills standard, not just Claude.

Get the whole plugin
Stats
44,280
Stars
4,019
Forks
Active
Maintenance
Python
Language
MIT
License
7d ago
Last commit
11mo ago
Created
13d ago
Added

Repo: k-dense-ai/claude-scientific-skills