[Biopython-dev] 454 GSFlex quality score files

Jared Flatow jflatow at northwestern.edu
Tue Oct 16 14:46:53 EDT 2007


Hi Peter,

>>>> I have also needed to create a modified FASTA parser so that I  
>>>> can  read things like quality score files.
>>>
>>> Could you be a little more specific - what exactly do you mean by a
>>> quality score files (links and/or examples).  It may be that this
>>> warrants setting up a new file format in Bio.SeqIO
>> That is what I did. The quality score files I meant are simply  
>> FASTA- like records that indicate the quality of each base pair  
>> read from a  sequencing machine, on a scale of something like 1 to  
>> 64. The values  are tab separated and correspond to 'reads' in  
>> another FASTA file  that contain the actual sequences read. This  
>> is the way the 454  GSFlex machines output their sequencing reads,  
>> so for every set of  reads there will be a pair of 454Reads.fna,  
>> 454Reads.qual files. The  only difference between a parser that  
>> processes these qual files and  one that processes the sequence  
>> files is that it shouldn't get rid of  spaces, and the newlines  
>> should not to be stripped but converted into  spaces (when 454  
>> writes a newline of scores they omit the space).  Essentially I  
>> have made a duplicate of FastaIOs iterator, named it  something  
>> else, made these two small changes and put an entry for it  in the  
>> SeqIO file.
>
> Patches and emails don't do well together.  Could you file an  
> enhancement bug, and then upload your code as an attachment?  If  
> you have a few examples of matched pairs of FASTA files and quality  
> files which you can contribute that would be very helpful too.
>

Yes I'll get on that.

> It looks like you are trying to construct a "sequence" of numerical  
> values (rather than a sequence of letters like nucleotides/amino  
> acids).  As written I don't think it would work for element access/ 
> splicing etc. However, with some extra work I suppose we could  
> stretch the Seq object in this way - and define a new  
> "IntegerAlphabet".
>
> But on balance, I don't think "lists of quality values" should be  
> treated in the same way as sequences (and thus it doesn't seem to  
> belong in Bio.SeqIO).
>

I agree.

> Alternatively you could regard the quality scores as sequence meta- 
> data or annotation.  One idea would be to generate SeqRecord  
> objects containing dummy sequences of the correct length made up of  
> the ambiguous character "N", with the associated quality scores  
> held as a list of integers in the SeqRecord's annotation  
> dictionary.  Then it would fit into the Bio.SeqIO framework [I was  
> thinking of something similar for PTT files, NCBI Protein tables,  
> where again we have annotation but not the actual sequence].

I agree, and this way is most flexible.

>
> Maybe there should just be a separate parser for GSFlex quality  
> records  which returns iterator giving each record name with a list  
> of integers. A more elegant scheme would read in the pair of files  
> together (the FASTA file and the quality file) and generate nicely  
> annotated SeqRecords with the sequence and the quality.  This isn't  
> really possible with the Bio.SeqIO framework.
>

Yes, at first I liked this idea best, but it puts some constraints on  
the way these things are read in. Like if it is to be an iterator,  
you must have a guarantee that these files contain exactly the same  
sequences in exactly the same order. This seems like it could  
potentially be fine for the GSFlex files, but I wonder if there might  
somewhere down the line be use for quality information about  
sequences in other cases. If I am not mistaken, some sources use  
upper/lower case letters now to indicate a bistable degree of  
confidence in a sequence letter. In any event, this seems like an  
unnecessary restriction.

The way I do it now is I load the reads into a database, then update  
the database when I read in a quality score file. I think Biopython  
should have a simple way of implementing something similar which can  
solve both our metadata problems.

In Bio.Fasta there are Parsers which really belong in  
Bio.SeqIO.FastaIO, if anywhere. How about Bio.Fasta becomes the more  
general Fasta reader, nothing to do with sequences. It can iterate  
over a FASTA file using the '>' as the record separator, creating  
Record objects, much like it does now, except without processing them  
at all or assuming they are sequences.

 >Record.header
Record.data

Now Bio.SeqIO.FastaIO can use Bio.Fasta to iterate over the Record  
objects in a file and transform them into SeqRecord object. If you  
like, you can provide it with a function header_todict, which takes a  
string (in this case Record.header) and returns a dictionary, which  
gets unpacked and passed to the SeqRecord initializer. Basically the  
Bio.SeqIO.FastaIO returns a generator that looks something like this:

(SeqRecord(seq=cleanup(record.data), **header_todict(record.header))  
for record in Bio.Fasta.parse(file))

  I can also use the Bio.Fasta.parse function now to parse my quality  
files and add them as metadata:

# I create an initial SeqRecord dictionary using the  
Bio.SeqIO.FastaIO parser
seq_dict = SeqIO.to_dict(SeqIO.FastaIO.parse(seq_file,  
my_header_todict))

# Then I iterate over the sequences in the qual file and look them up  
in the seq_dict using the same header parsing function
# I passed to create my initial SeqRecords, setting the quality  
scores as I find them them
for record in Bio.Fasta.parse(qual_file):
	seq_dict[my_header_todict(record.header)['id']].quality =  
my_qualitycleanup(record.data)

I hope that makes sense. The advantage to doing it this way is that I  
can reuse my header parsing function for both the sequence and the  
metadata, and I can do whatever I want with the fasta record data  
without writing a whole new parser. The SeqIO fasta parsing functions  
just makes some default assumptions (like the data is a sequence).

Let me know what you think.

Jared


More information about the Biopython-dev mailing list