Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Quality control for long-read sequencing data using NanoPlot, NanoStat, and chopper. Generate QC reports, filter reads by length and quality, and visualize read characteristics. Use when assessing ONT or PacBio run quality or filtering reads before assembly or alignment.
.claude/skills/bio-longread-qc/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-19 | ✗→✓ | ▲ Improved | — | — |
| case-17 | ✗→✓ | ▲ Improved | — | — |
| case-12 | ✗→✓ | ▲ Improved | — | — |
| case-04 | ✗→✓ | ▲ Improved | — | — |
| case-08 | ✗→✓ | ▲ Improved | — | — |
Reference examples tested with: BioPython 1.83+, numpy 1.26+
Before using code patterns, verify installed versions match. If versions differ:
pip show <package> then help(module.function) to check signatures<tool> --version then <tool> --help to confirm flagsIf code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.
"Check the quality of my Nanopore/PacBio run" → Generate read length distributions, quality score plots, and summary statistics, then filter reads by length and quality thresholds.
NanoPlot --fastq reads.fq.gz -o nanoplot_output/, chopper -q 10 -l 1000 < reads.fq > filtered.fqbash# From FASTQ NanoPlot --fastq reads.fastq.gz -o nanoplot_output -t 4 # From BAM NanoPlot --bam aligned.bam -o nanoplot_output -t 4 # From sequencing summary (fastest) NanoPlot --summary sequencing_summary.txt -o nanoplot_output
bashNanoPlot --fastq reads.fastq.gz \ -o nanoplot_output \ -t 8 \ --N50 \ # Show N50 in plots --title "Sample QC" \ --plots hex dot \ # Plot types --format png pdf \ # Output formats --color darkblue \ --maxlength 50000 \ # Max length for plots --minlength 500 # Min length for plots
bash# Quick statistics (no plots) NanoStat --fastq reads.fastq.gz --threads 4 # From BAM NanoStat --bam aligned.bam --threads 4 # Output to file NanoStat --fastq reads.fastq.gz --threads 4 > qc_stats.txt
bash# Filter by length and quality gunzip -c reads.fastq.gz | chopper -q 10 -l 1000 | gzip > filtered.fastq.gz # Quality >= 10, length >= 1000bp
bashgunzip -c reads.fastq.gz | chopper \ --quality 10 \ # Min quality --minlength 1000 \ # Min length --maxlength 50000 \ # Max length --headcrop 50 \ # Remove from start --tailcrop 50 \ # Remove from end --threads 4 \ | gzip > filtered.fastq.gz
bash# Filter with NanoFilt gunzip -c reads.fastq.gz | NanoFilt -q 10 -l 1000 | gzip > filtered.fastq.gz # With more options gunzip -c reads.fastq.gz | NanoFilt \ --quality 10 \ --length 1000 \ --maxlength 50000 \ --headcrop 50 \ | gzip > filtered.fastq.gz
bash# Trim adapters porechop -i reads.fastq.gz -o trimmed.fastq.gz --threads 8 # With barcode splitting porechop -i reads.fastq.gz -b output_dir/ --threads 8
bash# Quick summary with seqkit seqkit stats reads.fastq.gz # Detailed stats seqkit stats -a reads.fastq.gz # Watch stats during basecalling seqkit watch --fields ReadLen,MeanQual reads.fastq.gz
bash# Generate QC report from sequencing_summary.txt pycoQC -f sequencing_summary.txt -o pycoqc_report.html # With BAM for alignment stats pycoQC -f sequencing_summary.txt -a aligned.bam -o pycoqc_report.html
bash# With seqkit seqkit stats -a reads.fastq.gz | grep N50 # Manual calculation seqkit fx2tab -l reads.fastq.gz | cut -f 2 | sort -rn | \ awk '{sum+=$1; len[NR]=$1} END { target=sum/2; cumsum=0; for(i=1; i<=NR; i++) { cumsum+=len[i]; if(cumsum>=target) {print "N50:", len[i]; break} } }'
Goal: Compute read length and quality distributions from long-read FASTQ for custom QC analysis.
Approach: Iterate records with BioPython, collecting per-read length and mean Phred quality for summary statistics.
pythonimport numpy as np from Bio import SeqIO lengths = [] qualities = [] for record in SeqIO.parse('reads.fastq', 'fastq'): lengths.append(len(record)) qualities.append(np.mean(record.letter_annotations['phred_quality'])) print(f'Total reads: {len(lengths)}') print(f'Total bases: {sum(lengths):,}') print(f'Mean length: {np.mean(lengths):.0f}') print(f'Median length: {np.median(lengths):.0f}') print(f'Mean quality: {np.mean(qualities):.1f}')
| File | Description | |------|-------------| | NanoStats.txt | Summary statistics | | NanoPlot-report.html | Interactive report | | LengthvsQualityScatterPlot | Length vs Q plot | | WeightedHistogramReadlength | Read length distribution | | Yield_By_Length | Cumulative yield |
| Parameter | Description | |-----------|-------------| | --fastq | Input FASTQ | | --bam | Input BAM | | --summary | Sequencing summary | | -o | Output directory | | -t | Threads | | --N50 | Show N50 line | | --plots | Plot types | | --format | Output formats |
| Parameter | Default | Description | |-----------|---------|-------------| | -q | 0 | Min quality | | -l | 0 | Min length | | --maxlength | inf | Max length | | --headcrop | 0 | Trim from start | | --tailcrop | 0 | Trim from end | | -t | 4 | Threads |
| Q Score | Accuracy | Typical Use | |---------|----------|-------------| | Q7 | ~80% | Very low quality | | Q10 | ~90% | Basic filtering | | Q15 | ~97% | Moderate filtering | | Q20 | ~99% | High quality (SUP) | | Q30 | ~99.9% | Very high (HiFi) |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
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 +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.