jamescasbon/PyVCF — pull request #156 by gotgenes (2014-05-14 07:05:10+00:00)
Title: Use zero-based, half-open coordinates for Reader.fetch

This pull request currently sits atop PR #155. It includes one commit beyond #155, 98e8d42, that provides the changes for this pull request. Please accept #155 prior to accepting this one.

I have filed this pull request because Reader.fetch currently uses one-based indexing, which is inconsistent with pysam's Tabixfile.fetch (on which Reader.fetch relies). This caused a critical issue in one of my projects where variants were getting included that overlapped what I thought was my zero-based start index. Needless to say, I was less than pleased at the implicit and inconsistent behavior of Reader.fetch; this PR corrects this.

I quote the contents of the commit message containing the changes below

> These changes make the behavior of Reader.fetch consistent with with
pysam.Tabixfile, which uses the zero-based, half-open coordinate system
for Tabixfile.fetch. See
http://www.cgat.org/~andreas/documentation/pysam/api.html#pysam.Tabixfile.fetch
>
> Previously, PyVCF's Reader.fetch declared no particular coordinate
system. Since the method quietly deducted 1 from the start position,
apparently it assumed users were going to input a one-based coordinate
there. However, users familiar with pysam's Tabixfile for other formats
get an unexpected surprise when variants ahead of the start coordinate
start getting returned by Reader.fetch.
>
> As _Call.start and _Call.end are in the ZBHO coordinate system, it adds
to the consistency that fetch take start and end coordinates in ZBHO, so
the same _Call instance could be retrieved using its .CHROM, .start, and
.end coordinates.
>
> This change also removes the prior behavior of fetch of returning a
single _Call instance if given only chrom and start coordinates, by
implicitly doing a Tabixfile.fetch(chrom, start-1, start). The new
behavior when omitting the end parameter is to return an iterator of
_Call instances starting at start and continuing through the end of the
chromosome chrom. Again, this is the behavior consistent with
pysam.Tabixfile.fetch, and is what users ought to expect.
>
> This change also allows the user to omit both the start and end
positions. In this case, an iterable of _Call instances for all records
for the particular chromosome chrom will be returned, which again, is
consistent with Tabixfile.fetch. This behavior also resolves Issue #123
"Cannot fetch() whole chromosome".