Python/HTSlib workflows for genomic files. Use when reading, querying, filtering, or writing SAM/BAM/CRAM, VCF/BCF, FASTA/FASTQ, or tabix data with pysam, including pileup, coverage, indexing, and CRAM references.
npx skills add https://github.com/K-Dense-AI/scientific-agent-skills --skill pysam
Use pysam for low-level, streaming access to HTSlib-supported genomic formats:
AlignmentFile and AlignedSegment for SAM/BAM/CRAMVariantFile, VariantHeader, and VariantRecord for VCF/BCFFastaFile for indexed FASTA and FastxFile for sequential FASTA/FASTQTabixFile for BGZF-compressed, tabix-indexed BED/GFF/GTF/custom tablespysam.samtools and pysam.bcftools for wrapped command dispatchersCurrent upstream baseline: pysam 0.24.0 (27 April 2026), wrapping
HTSlib/samtools/bcftools 1.23.1. Read references/sources.md before updating
version-specific guidance.
Use the pinned release for reproducible work:
uv pip install "pysam==0.24.0"
Confirm the runtime:
import pysam
print(pysam.__version__) # 0.24.0
print(pysam.__samtools_version__) # 1.23.1
Prebuilt wheels are available for supported macOS and Linux platforms. A
source build needs a C compiler and HTSlib build dependencies; read the
official installation guide linked from references/sources.md.
Before writing code:
string. Do not mix them.
duplicate handling, and pileup depth cap.
For unfamiliar files, start with the bundled read-only inspector:
python scripts/inspect_hts.py sample.bam
python scripts/inspect_hts.py cohort.vcf.gz
python scripts/inspect_hts.py reference.fa
| Script | Purpose | Typical call |
|---|---|---|
| scripts/inspect_hts.py | Metadata-only inspection for alignment, variant, FASTA, FASTQ, and tabix files | python scripts/inspect_hts.py sample.cram --reference ref.fa |
| scripts/alignment_qc.py | Streaming aggregate read/QC counts as JSON | python scripts/alignment_qc.py sample.bam --max-records 100000 |
| scripts/variant_summary.py | Streaming variant, FILTER, and genotype summary as JSON | python scripts/variant_summary.py cohort.vcf.gz --region chr1:1-1000000 |
| scripts/filter_alignments.py | Filter SAM/BAM/CRAM without changing record order | python scripts/filter_alignments.py input.bam output.bam --exclude-secondary |
All scripts refuse to overwrite existing outputs. Run each with --help for
coordinate, index, and privacy notes.
Numeric coordinates accepted by pysam APIs are 0-based, half-open. This
includes numeric AlignmentFile.fetch(), VariantFile.fetch(),
FastaFile.fetch(), TabixFile.fetch(), and pileup() arguments.
Region strings are samtools-style: 1-based and inclusive.
# The same 100 bases:
bam.fetch("chr1", 99, 199) # [99, 199)
bam.fetch(region="chr1:100-199") # 1-based inclusive
VCF text uses 1-based POS, while record properties expose both systems:
record.pos # 1-based
record.start # 0-based inclusive
record.stop # 0-based exclusive
Read references/coordinates_and_indexing.md for format conversions, overlap
semantics, index choices, and contig-name checks.
Use context managers and explicit modes:
import pysam
with pysam.AlignmentFile("sample.bam", "rb", threads=4) as bam:
for read in bam.fetch("chr1", 1_000, 2_000):
if (
not read.is_unmapped
and not read.is_secondary
and not read.is_supplementary
and read.mapping_quality >= 30
):
print(read.query_name, read.reference_start, read.cigarstring)
Use fetch(until_eof=True) to stream every record in file order, including
unplaced unmapped reads, without requiring an index:
with pysam.AlignmentFile("sample.bam", "rb") as bam:
for read in bam.fetch(until_eof=True):
...
Important distinctions:
fetch() returns alignment records overlapping a region.count() counts records and defaults to read_callback="nofilter".count_coverage() returns A/C/G/T base counts and defaults to base quality15 plus read_callback="all".
pileup() exposes per-column reads and has its own filtering, base-quality,overlap, orphan, and max_depth=8000 defaults.
For exact-region pileups, set truncate=True and explicit filters:
with pysam.FastaFile("reference.fa") as fasta, pysam.AlignmentFile(
"sample.bam", "rb"
) as bam:
for column in bam.pileup(
"chr1",
1_000,
2_000,
truncate=True,
stepper="samtools",
fastafile=fasta,
min_mapping_quality=20,
min_base_quality=20,
max_depth=100_000,
):
print(column.reference_pos, column.get_num_aligned())
Read references/alignment_files.md for flags, CIGAR operations, tags,
modified bases, writing records, pileup details, and iterator lifetime.
Input format is auto-detected. Numeric fetch coordinates remain 0-based:
import pysam
with pysam.VariantFile("cohort.vcf.gz", threads=4) as variants:
for record in variants.fetch("chr1", 999_999, 2_000_000):
print(record.contig, record.pos, record.ref, record.alts)
for sample_name, call in record.samples.items():
print(sample_name, call.get("GT"))
Subset samples before retrieving records:
with pysam.VariantFile("cohort.bcf") as variants:
variants.subset_samples(["sample_A", "sample_B"])
for record in variants:
...
When changing a header, copy each record and translate it to the destination
header before assigning newly declared INFO/FORMAT/FILTER fields. Do not
manually clear and rebuild header.samples.
Read references/variant_files.md for safe headers, writing, sample
subsetting, missing genotypes, symbolic alleles, filtering, translation, and
indexing.
Indexed FASTA uses numeric 0-based coordinates:
with pysam.FastaFile("reference.fa") as fasta:
sequence = fasta.fetch("chr1", 999, 1_099)
FastxFile is sequential. persist=False is faster but yielded records become
invalid after iteration advances:
with pysam.FastxFile("reads.fastq.gz", persist=False) as reads:
for read in reads:
qualities = read.get_quality_array()
...
Tabix input must be coordinate-sorted and BGZF-compressed, not ordinary gzip.
Use a non-destructive two-step workflow:
pysam.tabix_compress("regions.bed", "regions.bed.gz")
pysam.tabix_index("regions.bed.gz", preset="bed")
with pysam.TabixFile("regions.bed.gz", parser=pysam.asBed()) as tbx:
for interval in tbx.fetch("chr1", 1_000, 2_000):
print(interval.contig, interval.start, interval.end)
Read references/sequence_files.md for FASTA/FASTQ records and safe tabix
creation.
pysam 0.24 changed inherited HTSlib behavior:
reference_filename="reference.fa" for deterministic local reads andwrites.
with pysam.AlignmentFile(
"sample.cram",
"rc",
reference_filename="reference.fa",
threads=4,
) as cram:
for read in cram.fetch("chr1", 1_000, 2_000):
...
Only configure REF_PATH/REF_CACHE when reference-by-MD5 lookup is
intentional. Do not assume a CRAM is self-contained. threads= accelerates
compression/decompression; it does not parallelize Python analysis.
Read references/cram_and_performance.md before CRAM conversion, remote access,
or concurrent iteration.
Import command modules explicitly. Pass each command-line token as a separate
string:
import pysam.samtools
import pysam.bcftools
pysam.samtools.sort(
"-@", "4", "-o", "sorted.bam", "input.bam", catch_stdout=False
)
pysam.samtools.index("-@", "4", "sorted.bam", catch_stdout=False)
pysam.bcftools.index("--csi", "variants.vcf.gz", catch_stdout=False)
Dispatchers capture stdout by default. For large or binary output, use the
tool's -o option with catch_stdout=False, or save_stdout=..., rather than
returning the complete output in memory.
try:
pysam.samtools.quickcheck("-v", "sample.bam")
except pysam.SamtoolsError as error:
messages = pysam.samtools.quickcheck.get_messages()
raise RuntimeError(messages or str(error)) from error
Use the Python API for record-level logic and dispatchers for mature bulk
operations such as sort, index, merge, view, and normalization. Never compose
dispatcher arguments by splitting an untrusted shell command.
force=True unless replacement is explicit.query_sequence before query_qualities.pysam.CIGAR_OPS enum members; top-level constants such aspysam.CMATCH are compatibility aliases slated for future removal.
pysam.samtools.quickcheck() for alignments and reopenvariant/sequence outputs before downstream use.
index limits.
| Need | Read |
|---|---|
| Alignment API, flags, CIGAR, pileup, modified bases | references/alignment_files.md |
| VCF/BCF headers, records, samples, writing | references/variant_files.md |
| FASTA/FASTQ and tabix-indexed tables | references/sequence_files.md |
| Coordinate conversion and index selection | references/coordinates_and_indexing.md |
| CRAM references, remote I/O, threads, performance | references/cram_and_performance.md |
| Correct integrated analysis patterns | references/common_workflows.md |
| Compact current API signatures and defaults | references/api_reference.md |
| Upgrade notes for existing environments | references/migration_to_0_24.md |
| Official docs, specifications, and release sources | references/sources.md |
VariantFile.fetch() coordinates as 1-basedfetch() includes unplaced unmapped alignmentstruncate=True for an exact pileup intervalAutomatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when the user asks to run Codex CLI (codex exec, codex resume) or references OpenAI Codex for code analysis, refactoring, or automated editing. Uses GPT-5.2 by default for state-of-the-art software engineering.
Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory bugs.
Use when a user asks to debug or fix failing GitHub PR checks that run in GitHub Actions; use `gh` to inspect checks and logs, summarize failure context, draft a fix plan, and implement only after explicit approval. Treat external providers (for example Buildkite) as out of scope and report only the details URL.
> Create, build, deploy, and localize declarative agents for M365 Copilot and Teams. USE THIS SKILL for ANY task involving a declarative agent — including localization, scaffolding, editing manifests, adding capabilities, and deploying. Localization requires tokenized manifests and language files that only this skill knows how to produce. "scaffold an agent", "new agent project", "add a capability", "add a plugin", "configure my agent", "deploy my agent", "fix my agent manifest", "edit my agent", "localize my agent", "add localization", "translate my agent", "multi-language agent", "add an API plugin", "add an MCP plugin", "add OAuth to my plugin", "review instructions", "improve instructions", "fix my instructions"
Documentation generation workflow covering API docs, architecture docs, README files, code comments, and technical writing.
Use when the user wants to translate a repository README, make a repo multilingual, localize docs, add a language switcher, internationalize the README, or update localized README variants in a GitHub-style repository.
Generate user-friendly release notes from git commits. Use this when preparing releases, writing changelogs, or summarizing development progress.
Take k-dense-ai/pysam from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference pip, uv.
Without those the skill loads but fails at the first command.