Update fastq format.

Now we only support FastqSolexa variants.
If the quality scores are presented as characters,
the integer values are obtained by their ascii code subtract 64.
This commit is contained in:
Wen-Yu Chung
2008-06-06 18:52:11 +00:00
parent e767816519
commit 782d7db6be
10 changed files with 70 additions and 132 deletions
@@ -2,7 +2,7 @@
<description>converts Fastq file to Fasta format</description>
<command interpreter="python">fastq_to_fasta_converter.py $input $output</command>
<inputs>
<param name="input" type="data" format="fastq,fastqsolexa" label="Choose Fastq file"/>
<param name="input" type="data" format="fastqsolexa" label="Choose Fastq file"/>
</inputs>
<outputs>
<data name="output" format="fasta"/>
@@ -28,7 +28,7 @@ def __main__():
datatype = sys.argv[3]
qual_title_startswith = ''
seq_title_startswith = ''
default_coding_value = 33
default_coding_value = 64
fastq_block_lines = 0
for i, line in enumerate( file( infile_name ) ):
@@ -75,10 +75,8 @@ def __main__():
if fastq_integer: # digits
qual = line
else: # ascii
if datatype == 'fastqsolexa':
outfile_score.close()
stop_err( "This tool currently only works with the fastq solexa variant if the socres are integers, not ascii." )
else:
# ascii
quality_score_length = len( line )
if quality_score_length == read_length + 1:
quality_score_startswith = ord( line[0:1] )
@@ -88,7 +86,7 @@ def __main__():
else:
stop_err( 'Invalid fastq format at line %d: the number of quality scores ( %d ) is not the same as bases ( %d ).' % ( i + 1, quality_score_length, read_length ) )
for j, char in enumerate( line ):
score = ord( char ) - quality_score_startswith # 33
score = ord( char ) - quality_score_startswith # 64
qual = "%s%s " % ( qual, str( score ) )
outfile_score.write( '%s\n' % qual )
@@ -1,7 +1,7 @@
<tool id="CONVERTER_fastq_to_qual_0" name="Convert Fastq to Qual">
<command interpreter="python">fastq_to_qual_converter.py $input1 $output1 $input1.extension</command>
<inputs>
<param format="fastq,fastqsolexa" name="input1" type="data" label="Choose Fastq file"/>
<param format="fastqsolexa" name="input1" type="data" label="Choose Fastq file"/>
</inputs>
<outputs>
<data format="qual" name="output1" />
+2 -2
View File
@@ -67,7 +67,7 @@ class Registry( object ):
'binseq.zip' : images.Binseq(),
'customtrack' : interval.CustomTrack(),
'fasta' : sequence.Fasta(),
'fastq' : sequence.Fastq(),
'fastqsolexa' : sequence.FastqSolexa(),
'gff' : interval.Gff(),
'gff3' : interval.Gff3(),
'interval' : interval.Interval(),
@@ -89,7 +89,7 @@ class Registry( object ):
'binseq.zip' : 'application/zip',
'customtrack' : 'text/plain',
'fasta' : 'text/plain',
'fastq' : 'text/plain',
'fastqsolexa' : 'text/plain',
'gff' : 'text/plain',
'gff3' : 'text/plain',
'interval' : 'text/plain',
+15 -67
View File
@@ -89,61 +89,6 @@ class Fasta( Sequence ):
except:
return False
class Fastq( Sequence ):
"""Class representing a FASTQ sequence ( the Sanger/Standard variant )"""
file_ext = "fastq"
def set_peek( self, dataset ):
Sequence.set_peek( self, dataset )
count = 0
size = 0
bases_regexp = re.compile("^[NGTAC]*$")
for line in file( dataset.file_name ):
if line and line.startswith( ">" ):
count += 1
elif bases_regexp.match( line ):
line = line.strip()
size += len( line )
if count == 1:
dataset.blurb = '%d bases' % size
else:
dataset.blurb = '%d sequences' % count
def sniff(self, filename):
"""
Determines whether the file is in fastq format ( the Sanger/Standard variant )
For details, see http://maq.sourceforge.net/fastq.shtml
Note: There are two kinds of FASTQ files, known as "Sanger" (sometimes called "Standard") and Solexa
These differ in the representation of the quality scores
>>> fname = get_test_fname( '1.fastq' )
>>> Fastq().sniff( fname )
True
>>> fname = get_test_fname( '1.fastqsolexa' )
>>> Fastq().sniff( fname )
False
"""
headers = get_headers( filename, None )
bases_regexp = re.compile( "^[NGTAC]*$" )
try:
if len( headers ) >= 4 and headers[0][0] and headers[0][0][0] == "@" and headers[2][0] and headers[2][0][0] == "+" and headers[1][0] and headers[3][0]:
# Check the sequence line, make sure it contains only G/C/A/T/N
if not bases_regexp.match( headers[1][0] ):
return False
# The quality score line
qscore = headers[3][0]
# In Standard/Sanger format, the quality score is a single string, whose length should be equal to the length of the sequence
if len( qscore ) != len( headers[1][0] ):
return False
#Check the quality score values - in Sanger/Standard these should be ASCII characters between "!" (0x21) and "~" (0x7E)
for x in qscore:
if ord( x ) < 0x21 or ord( x ) > 0x7e:
return False
return True
return False
except:
return False
class FastqSolexa( Sequence ):
"""Class representing a FASTQ sequence ( the Solexa variant )"""
@@ -154,7 +99,7 @@ class FastqSolexa( Sequence ):
count = size = 0
bases_regexp = re.compile("^[NGTAC]*$")
for line in file( dataset.file_name ):
if line and line[0] == ">":
if line and line[0] == "@":
count += 1
elif bases_regexp.match(line):
line = line.strip()
@@ -174,7 +119,7 @@ class FastqSolexa( Sequence ):
>>> fname = get_test_fname( '1.fastq' )
>>> FastqSolexa().sniff( fname )
False
True
>>> fname = get_test_fname( '1.fastqsolexa' )
>>> FastqSolexa().sniff( fname )
True
@@ -186,17 +131,20 @@ class FastqSolexa( Sequence ):
# Check the sequence line, make sure it contains only G/C/A/T/N
if not bases_regexp.match( headers[1][0] ):
return False
qscore = headers[3]
# In Solexa format, the quality score is a list of numbers, whose length should be equal to the length of the sequence
if len( qscore ) != len( headers[1][0] ):
return False
# Check the quality score values - in Solexa/FASTQ these should be valid decimal numbers
# (if "x" is not a valid number, "int" will raise an exception)
for x in qscore:
try:
check = int( x )
except:
# Check quality score: integer or ascii char.
try:
check = int(headers[3][0])
qscore_int = True
except:
qscore_int = False
if qscore_int:
if len( headers[3] ) != len( headers[1][0] ):
return False
else:
if len( headers[3][0] ) != len( headers[1][0] ):
return False
return True
return False
except: