Before you start
- You have met the common file formats in File formats.
- Any term new? The Glossary has it.
Learning objectives
By the end of this lesson you will be able to: explain the difference between 0-based and 1-based coordinates, know which file formats use which, convert between them, and avoid the off-by-one bug that silently shifts every feature you work with.
The most common silent bug in bioinformatics
Two different tools can describe the exact same stretch of DNA with different numbers, and both are correct. If you mix the two systems up, every position you compute is shifted by one base. Nothing crashes, no error appears, your results are just quietly wrong. This is the off-by-one bug, and learning to spot it now will save you a genuinely painful afternoon later.
1Two ways to count positions
There are two coordinate systems, and the difference is where counting starts and whether the end position is included.
- 1-based, fully closed: the first base is position 1, and an interval from
starttoendincludes both ends. This is how biologists naturally count, and what you see in papers. - 0-based, half-open: counting starts at 0, and an interval includes the start but not the end. This is how most programming languages count, and it makes interval maths clean (length is simply
end - start).
2Which format uses which
You cannot choose; each format has a fixed convention. Memorising this small table prevents most coordinate bugs.
| Format | System | Remember it as |
|---|---|---|
| BED | 0-based, half-open | "BED starts at 0" |
| GFF / GTF | 1-based, closed | annotation, like a paper |
| VCF | 1-based | variant position as a biologist would say it |
| SAM (the POS column) | 1-based | (BAM stores it as 0-based internally, but tools show you 1-based) |
Quick memory hookThe B in BED is for "begins at zero"
If you remember only one thing: BED is 0-based and half-open; almost everything a biologist reads (GFF, VCF, the POS in a VCF or paper) is 1-based. When you cross between them, expect an off-by-one.
3Converting between them
Going from a 1-based interval (say, a gene in a GTF) to a 0-based BED interval is a one-line rule:
# 1-based closed [start, end] -> 0-based half-open [start-1, end] bed_start = gtf_start - 1 bed_end = gtf_end # the end does not change # a feature at 1-based positions 2..4 becomes BED 1..4
Why the end stays the same
It looks asymmetric, but it works out: in 0-based half-open, the end is "one past the last base," which happens to equal the 1-based end. A handy bonus is that the length is simply end - start with no "+1" to remember.
4What it looks like when it goes wrong
Imagine you have a ChIP-seq peak in a BED file (0-based) and you naively look up that start position in a 1-based genome browser. Every peak is now shifted one base to the left. For a single base that may not matter, but it can change which codon a variant hits, whether a feature overlaps a gene boundary, or which exon a read lands in. The fix is never "nudge the numbers until it looks right"; it is to know which system each file uses and convert deliberately.
