[Bioperl-l] alignIO::fasta bug
Chris Fields
cjfields at illinois.edu
Sat Jan 24 05:25:16 UTC 2009
On Jan 22, 2009, at 10:54 PM, Mark A. Jensen wrote:
> couple of thoughts...
>
> ----- Original Message ----- From: "Chris Fields" <cjfields at illinois.edu
> >
> To: "Jason Stajich" <jason at bioperl.org>
> Cc: "BioPerl List" <bioperl-l at bioperl.org>
> Sent: Thursday, January 22, 2009 10:54 PM
> Subject: Re: [Bioperl-l] alignIO::fasta bug
>
>> On Jan 22, 2009, at 3:33 PM, Jason Stajich wrote:
>>
>>> FYI - it appears that if the last sequence in a FASTA MSA is all
>>> gaps (which happens in some whole genome synteny+multiple
>>> alignment chunking like Mercator) no alignment is returned.
>>>
>>> yuck. It basically comes down to this bit of code where $end
>>> would equal sequence length.
>>>
>>> # If $end <= 0, we have either reached the end of
>>> # file in <> or we have encountered some other error
>>> if ( $end <= 0 && ) {
>>> undef $aln;
>>> return $aln;
>>> }
> [haven't looked at the code, but] On the surface, this looks like a
> bit more
> responsibility than $end should be expected to handle, so I like
> Jason's
> solution below better, which is only masquerading as a kludge.
>
>>>
>>> This start/end requirement of locatable seq is nice but kind of a
>>> pain where I am managing the map of sequences outside of
>>> alignment chunk.
>>
>> I faced this issue with Mauve parsing (Bio::SeqIO::xmfa). I set it
>> up so LocatableSeqs can now have all gaps, but the alphabet needs
>> to be set (get a warning otherwise) and start and end need to be
>> initiated to 0, which is how I believe Mauve defined these.
>> However, should 0-0 be a valid start/end for such a sequence?
>> Should we change that to automatically allow start = end = X (any
>> position including 0) if a sequence is all gaps or empty?
>
> I don't like any old start==end implying zero length, even under the
> condition
> that the underlying sequence is empty, since in the "1-origin,
> endpoints" model
> that pervades BP (as opposed to the "0-origin, length" model of,
> say, substr),
> the pair ($start, $end) has the strong connotation of "the residue
> at $start"
> if $start==$end. (At least, it does now that we've fixed
> LocatableSeq...)
It could just as easily be undef (no start/end). However, see below...
> What if we consider 0 to be special, the 'sequence anchor', that
> takes up no
> real space? I'm thinking of 'point' and 'mark' in emacs, that
> actually point at
> the interstices between characters, and not the characters
> themselves. Or \G
> for something perly. Then $start means not just the coordinate, but
> the
> 'space' before the residue at $start, and $end means the 'space'
> after the
> residue at $end. If $start==$end > 0, how many residues between
> $start and $end?
> One. If $start == $end == 0, how many residues? None, because the
> anchor
> is special, it doesn't take up residues.
>
> If a sequence is all gaps, what's its length? It has an understood
> anchor at 0,
> then the gap symbols are removed, so its length is the length of the
> anchor
> alone, which is zero, and $start = 0 is the 'space' before the
> anchor, and
> $end = 0 is the 'space' after the anchor.
Where this becomes sticky is taking alignment sections, a problem
encountered when attempting to create interleaved output, for
instance. Let's say (for example) you have a long alignment that has
large gaps (think genome alignment ala MUMmer or Mauve). If you take
a subsection of that alignment, you could very possibly end up with a
sequence that is all gaps. Here is an example from Rfam (note
AE013109.1):
AL596170.1/181975-181872
AG................................................
BA000016.3/1419453-1419329
UU..........................................AAUUAU
AE001437.1/2206791-2206643
AGGAAUUAUUUUGAAGAACUUUAUAGACGUAGAA..........GAAAAA
BA000016.3/1419328-1419245
GG................................................
AE013183.1/26-124
AG.............................................GAU
AE013109.1/12950-12813
GAGA........................................AUAUAG
AE013109.1
/
13583
-13495
..................................................
AF044978.1/176-335
AAUC........................................AUGCAA
X84262.1/148-332
CAGCUCAAAAUCCAUAUAUAA.......................ACAAGA
CR954253.1/898444-898260
UCUCUCAAAGUCUA..............................CUUAAA
So let's say we take the slice above from the alignment and create a
new SimpleAlign. We know the original coordinates for each
LocatableSeq; should we override them and mark the start = end = 0?
Or would we want to have a sequence that is indicated as between the
end of the last known position and the beginning of the next
(500^501)? This also doesn't take into account start/end gaps; maybe
for beginning gaps start = end = 0 and end gaps start = end = length.
For no sequence at all (undef) start = end = undef as well.
> Now this would mean say, $s->subseq(0, $n) eq $s->subseq(1, $n). I
> don't
> think this is too troubling, since 1) it's consistent with the
> concept above, and
> 2) zeros would only show up when the empty sequences are encountered.
Okay.
>> If we come up with some rough ideas of how to handle this we can
>> add some examples to the test suite and try getting LocatableSeq
>> to do the right thing. We can always mark them as TODO.
>>
>>> Why not just check to see that the number of seq characters is 0
>>> - an all-gapped sequence as the last sequence of the file should
>>> still be legal.
>>>
>>> Instead:
>>> if ( length($seqchar) == 0 ) {
>>> undef $aln;
>>> return $aln;
>>> }
>>>
>>> Although that would invalidate an empty alignment like this -- do
>>> we want to still permit these?
>>> >A
>>>
>>> >B
>>>
>>> >C
>>
>> These could be zero-length, empty seqs (start = end = undef). I
>> thought something was added to PrimarySeq recently for empty seqs.
>
> Maybe the above concept would encompass empty sequences (gapped
> or ungapped) without recourse to undef.
>
> cheers, Mark
From this discussion I think it's worth coming up with some kind of
idea on what we expect LocatableSeq to do under various circumstances;
the wiki is a good place to start something up. I don't think that
refactoring everything is necessary, but it might be worth putting out
some variations for consideration.
For instance I have had the idea of making a new RangeI-based
Bio::SeqI that would just delegate the RangeI methods to a 'source'
SeqFeature containing a Bio::LocationI. The PrimarySeqI would be a
simplified LocatableSeq capable of dealing with subseq issues as
discussed previously, but simplified. In fact, it should probably
recognize any PrimarySeqI.
Advantages: can add annotation and features specific for the sequence,
and (beyond simple decorated methods used to make access simple) it is
a Bio::Seq and could be persisted in a BioSQL. Disadvantages: lots of
objects and thus slower.
chris
More information about the Bioperl-l
mailing list