Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate alignment statistics using samtools flagstat, stats, depth, and coverage. Use when assessing alignment quality, calculating coverage, or generating QC reports.
.claude/skills/bio-alignment-files-bam-statistics/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 209% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 548% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 148% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 311% | 0% |
<!--
#
#
-->
Generate alignment statistics using samtools and pysam.
| Command | Output | Speed | |---------|--------|-------| | flagstat | Read counts by category | Very fast | | idxstats | Per-chromosome counts | Very fast (needs index) | | stats | Comprehensive statistics | Moderate | | depth | Per-position depth | Slow (full scan) | | coverage | Per-region coverage | Fast (needs index) |
Fast summary of alignment flags.
bashsamtools flagstat input.bam
Output:
10000000 + 0 in total (QC-passed reads + QC-failed reads)
0 + 0 secondary
50000 + 0 supplementary
0 + 0 duplicates
9800000 + 0 mapped (98.00% : N/A)
9950000 + 0 paired in sequencing
4975000 + 0 read1
4975000 + 0 read2
9700000 + 0 properly paired (97.49% : N/A)
9750000 + 0 with itself and mate mapped
100000 + 0 singletons (1.01% : N/A)
25000 + 0 with mate mapped to a different chr
10000 + 0 with mate mapped to a different chr (mapQ>=5)bashsamtools flagstat -@ 4 input.bam
bashsamtools flagstat input.bam > flagstat.txt
Per-chromosome read counts (requires index).
bashsamtools idxstats input.bam
Output format: chrom length mapped unmapped
chr1 248956422 5000000 1000
chr2 242193529 4800000 800
chrM 16569 50000 100
* 0 0 150000bash# Total mapped reads samtools idxstats input.bam | awk '{sum += $3} END {print sum}' # Mitochondrial percentage samtools idxstats input.bam | awk ' /^chrM/ {mt = $3} {total += $3} END {print mt/total*100 "% mitochondrial"}'
Comprehensive statistics including insert size, base quality, and more.
bashsamtools stats input.bam > stats.txt
bashsamtools stats input.bam | grep "^SN"
Key summary fields:
raw total sequences - Total readsreads mapped - Mapped readsreads mapped and paired - Properly pairedinsert size average - Mean insert sizeinsert size standard deviation - Insert size spreadaverage length - Mean read lengtherror rate - Mismatch ratebashsamtools stats input.bam > stats.txt plot-bamstats -p plots/ stats.txt
bashsamtools stats input.bam chr1:1000000-2000000 > region_stats.txt
Per-position read depth.
bashsamtools depth input.bam > depth.txt
Output: chrom position depth
bashsamtools depth -r chr1:1000-2000 input.bam
bashsamtools depth -a input.bam > depth_with_zeros.txt
bashsamtools depth -d 0 input.bam # No cap (default 8000)
bashsamtools depth -b regions.bed input.bam
bashsamtools depth input.bam | awk '{sum += $3; n++} END {print sum/n}'
Per-chromosome or per-region coverage statistics (faster than depth).
bashsamtools coverage input.bam
Output columns:
#rname - Reference namestartpos - Start positionendpos - End positionnumreads - Number of readscovbases - Bases with coveragecoverage - Percentage of bases coveredmeandepth - Mean depthmeanbaseq - Mean base qualitymeanmapq - Mean mapping qualitybashsamtools coverage -r chr1:1000000-2000000 input.bam
bashsamtools coverage -b regions.bed input.bam
bashsamtools coverage -m input.bam
pythonimport pysam with pysam.AlignmentFile('input.bam', 'rb') as bam: total = mapped = paired = proper = 0 for read in bam: total += 1 if not read.is_unmapped: mapped += 1 if read.is_paired: paired += 1 if read.is_proper_pair: proper += 1 print(f'Total: {total}') print(f'Mapped: {mapped} ({mapped/total*100:.1f}%)') print(f'Properly paired: {proper} ({proper/paired*100:.1f}%)')
pythonimport pysam with pysam.AlignmentFile('input.bam', 'rb') as bam: for stat in bam.get_index_statistics(): print(f'{stat.contig}: {stat.mapped} mapped, {stat.unmapped} unmapped')
pythonimport pysam with pysam.AlignmentFile('input.bam', 'rb') as bam: for pileup in bam.pileup('chr1', 1000000, 1000001): print(f'Position {pileup.pos}: depth {pileup.n}')
pythonimport pysam def mean_depth(bam_path, chrom, start, end): depths = [] with pysam.AlignmentFile(bam_path, 'rb') as bam: for pileup in bam.pileup(chrom, start, end, truncate=True): depths.append(pileup.n) if depths: return sum(depths) / len(depths) return 0 depth = mean_depth('input.bam', 'chr1', 1000000, 2000000) print(f'Mean depth: {depth:.1f}x')
pythonimport pysam def coverage_stats(bam_path, chrom, start, end): covered = 0 total_depth = 0 with pysam.AlignmentFile(bam_path, 'rb') as bam: for pileup in bam.pileup(chrom, start, end, truncate=True): covered += 1 total_depth += pileup.n length = end - start pct_covered = covered / length * 100 mean_depth = total_depth / length if length > 0 else 0 return { 'length': length, 'covered_bases': covered, 'pct_covered': pct_covered, 'mean_depth': mean_depth } stats = coverage_stats('input.bam', 'chr1', 1000000, 2000000) print(f'Coverage: {stats["pct_covered"]:.1f}%') print(f'Mean depth: {stats["mean_depth"]:.1f}x')
pythonimport pysam from collections import Counter insert_sizes = Counter() with pysam.AlignmentFile('input.bam', 'rb') as bam: for read in bam: if read.is_proper_pair and read.is_read1 and read.template_length > 0: insert_sizes[read.template_length] += 1 sizes = list(insert_sizes.keys()) mean_insert = sum(s * c for s, c in insert_sizes.items()) / sum(insert_sizes.values()) print(f'Mean insert size: {mean_insert:.0f}') print(f'Min: {min(sizes)}, Max: {max(sizes)}')
| Task | Command | |------|---------| | Quick counts | samtools flagstat input.bam | | Per-chrom counts | samtools idxstats input.bam | | Full stats | samtools stats input.bam | | Coverage summary | samtools coverage input.bam | | Per-position depth | samtools depth input.bam | | Mean depth | samtools depth input.bam \| awk '{sum+=$3;n++}END{print sum/n}' |
| Metric | Good | Concerning | |--------|------|------------| | Mapping rate | >95% | <80% | | Proper pair rate | >90% | <70% | | Duplicate rate | <20% | >40% | | Error rate | <1% | >2% | | Coverage uniformity | <2x CV | >3x CV |
<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 14,964 | 8,740 | -42% | 1 | 1 | 0% | 3,166 | 4,368 | +38% | 0 | 0 | — |
case-02 | pass→pass | 6,016 | 3,917 | -35% | 1 | 1 | 0% | 1,040 | 3,215 | +209% | 0 | 0 | — |
case-03 | pass→pass | 2,617 | 1,646 | -37% | 1 | 1 | 0% | 436 | 2,824 | +548% | 0 | 0 | — |
case-04 | pass→pass | 7,278 | 4,771 | -34% | 1 | 1 | 0% | 1,338 | 3,314 | +148% | 0 | 0 | — |
case-05 | fail→fail | 4,638 | 5,162 | +11% | 1 | 1 | 0% | 931 | 3,581 | +285% | 0 | 0 | — |
case-06 | pass→pass | 4,136 | 2,884 | -30% | 1 | 1 | 0% | 730 | 3,003 | +311% | 0 | 0 | — |
case-07 | pass→pass | 7,082 | 5,217 | -26% | 1 | 1 | 0% | 1,409 | 3,558 | +153% | 0 | 0 | — |
case-08 | pass→pass | 7,389 | 2,951 | -60% | 1 | 1 | 0% | 1,283 | 3,059 | +138% | 0 | 0 | — |
case-09 | pass→pass | 3,458 | 2,477 | -28% | 1 | 1 | 0% | 495 | 2,958 | +498% | 0 | 0 | — |
case-10 | pass→pass | 4,498 | 2,875 | -36% | 1 | 1 | 0% | 753 | 3,009 | +300% | 0 | 0 | — |
case-11 | pass→pass | 4,984 | 3,581 | -28% | 1 | 1 | 0% | 962 | 3,233 | +236% | 0 | 0 | — |
case-12 | pass→pass | 5,549 | 1,991 | -64% | 1 | 1 | 0% | 984 | 2,879 | +193% | 0 | 0 | — |
case-13 | pass→pass | 5,037 | 3,831 | -24% | 1 | 1 | 0% | 941 | 3,223 | +243% | 0 | 0 | — |
case-14 | pass→pass | 11,565 | 10,383 | -10% | 1 | 1 | 0% | 2,374 | 4,711 | +98% | 0 | 0 | — |
case-15 | fail→fail | 13,776 | 10,734 | -22% | 1 | 1 | 0% | 2,684 | 4,637 | +73% | 0 | 0 | — |
case-16 | pass→pass | 10,131 | 9,471 | -7% | 1 | 1 | 0% | 1,748 | 4,044 | +131% | 0 | 0 | — |
case-17 | pass→pass | 7,970 | 3,831 | -52% | 1 | 1 | 0% | 1,210 | 3,130 | +159% | 0 | 0 | — |
case-18 | pass→pass | 3,673 | 3,502 | -5% | 1 | 1 | 0% | 636 | 3,187 | +401% | 0 | 0 | — |
case-19 | pass→pass | 5,070 | 3,074 | -39% | 1 | 1 | 0% | 1,023 | 3,136 | +207% | 0 | 0 | — |
case-20 | pass→pass | 6,614 | 5,147 | -22% | 1 | 1 | 0% | 1,271 | 3,501 | +175% | 0 | 0 | — |
case-21 | pass→pass | 5,559 | 4,078 | -27% | 1 | 1 | 0% | 1,106 | 3,172 | +187% | 0 | 0 | — |
case-22 | pass→pass | 7,579 | 5,368 | -29% | 1 | 1 | 0% | 1,460 | 3,511 | +140% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/26/2026 | +4% |
Other measured skills in the registry, with their headline benchmark lift.