[Peter Cock] Filtering tool: Only cast used columns. Fix valid lines and skipped info lines. [Kanwei] Add new testcases to test this behavior. Fixes #537. Fixes #535

This commit is contained in:
Kanwei Li
2011-05-27 10:47:17 +02:00
parent 5432bb543f
commit 34155271b3
4 changed files with 36 additions and 18 deletions
+6
View File
@@ -0,0 +1,6 @@
# Should skip this line
chr22 30120223 30120265 CCDS13897.1_cds_0_0_chr22_30120224_f 0 +
chr22 foo foo foo foo foo
chr22 30160419 30160661 CCDS13898.1_cds_0_0_chr22_30160420_r 0 -
chr22 30665273 30665360 CCDS13901.1_cds_0_0_chr22_30665274_f 0 +
chr22 30939054 30939266 CCDS13903.1_cds_0_0_chr22_30939055_r 0 -
+5
View File
@@ -0,0 +1,5 @@
chr22 30120223 30120265 CCDS13897.1_cds_0_0_chr22_30120224_f 0 +
chr22 foo foo foo foo foo
chr22 30160419 30160661 CCDS13898.1_cds_0_0_chr22_30160420_r 0 -
chr22 30665273 30665360 CCDS13901.1_cds_0_0_chr22_30665274_f 0 +
chr22 30939054 30939266 CCDS13903.1_cds_0_0_chr22_30939055_r 0 -
+19 -16
View File
@@ -32,7 +32,7 @@ out_fname = sys.argv[2]
cond_text = sys.argv[3]
try:
in_columns = int( sys.argv[4] )
assert sys.argv[5] #check to see that the column types varaible isn't null
assert sys.argv[5] #check to see that the column types variable isn't null
in_column_types = sys.argv[5].split( ',' )
except:
stop_err( "Data does not appear to be tabular. This tool can only be used with tab-delimited data." )
@@ -60,22 +60,25 @@ for operand in operands:
except:
if operand in secured:
stop_err( "Illegal value '%s' in condition '%s'" % ( operand, cond_text ) )
# Find the largest column used in the filter.
largest_col_index = -1
for match in re.finditer( 'c(\d)+', cond_text ):
col_index = int( match.group()[1:] )
if col_index > largest_col_index:
largest_col_index = col_index
# Work out which columns are used in the filter (save using 1 based counting)
used_cols = sorted(set(int(match.group()[1:]) \
for match in re.finditer('c(\d)+', cond_text)))
largest_col_index = max(used_cols)
# Prepare the column variable names and wrappers for column data types. Only
# prepare columns up to largest column in condition.
# cast columns used in the filter.
cols, type_casts = [], []
for col in range( 1, largest_col_index + 1 ):
col_name = "c%d" % col
cols.append( col_name )
col_type = in_column_types[ col - 1 ]
type_cast = "%s(%s)" % ( col_type, col_name )
if col in used_cols:
type_cast = "%s(%s)" % ( col_type, col_name )
else:
#If we don't use this column, don't cast it.
#Otherwise we get errors on things like optional integer columns.
type_cast = col_name
type_casts.append( type_cast )
col_str = ', '.join( cols ) # 'c1, c2, c3, c4'
@@ -83,6 +86,7 @@ type_cast_str = ', '.join( type_casts ) # 'str(c1), int(c2), int(c3), str(c4)'
assign = "%s, = line.split( '\\t' )[:%i]" % ( col_str, largest_col_index )
wrap = "%s = %s" % ( col_str, type_cast_str )
skipped_lines = 0
invalid_lines = 0
first_invalid_line = 0
invalid_line = None
lines_kept = 0
@@ -96,9 +100,6 @@ for i, line in enumerate( file( in_fname ) ):
line = line.rstrip( '\\r\\n' )
if not line or line.startswith( '#' ):
skipped_lines += 1
if not invalid_line:
first_invalid_line = i + 1
invalid_line = line
continue
try:
%s
@@ -107,7 +108,7 @@ for i, line in enumerate( file( in_fname ) ):
lines_kept += 1
print >> out, line
except:
skipped_lines += 1
invalid_lines += 1
if not invalid_line:
first_invalid_line = i + 1
invalid_line = line
@@ -132,5 +133,7 @@ if valid_filter:
print 'kept %4.2f%% of %d lines.' % ( 100.0*lines_kept/valid_lines, total_lines )
else:
print 'Possible invalid filter condition "%s" or non-existent column referenced. See tool tips, syntax and examples.' % cond_text
if skipped_lines > 0:
print 'Skipped %d invalid lines starting at line #%d: "%s"' % ( skipped_lines, first_invalid_line, invalid_line )
if invalid_lines:
print 'Skipped %d invalid line(s) starting at line #%d: "%s"' % ( invalid_lines, first_invalid_line, invalid_line )
if skipped_lines:
print 'Skipped %i comment (starting with #) or blank line(s)' % skipped_lines
+6 -2
View File
@@ -1,4 +1,4 @@
<tool id="Filter1" name="Filter" version="1.0.1">
<tool id="Filter1" name="Filter" version="1.1.0">
<description>data on any column using simple expressions</description>
<command interpreter="python">
filtering.py $input $out_file1 "$cond" ${input.metadata.columns} "${input.metadata.column_types}"
@@ -29,7 +29,11 @@
<param name="cond" value="c3=='chr1' and c5>5"/>
<output name="out_file1" file="filter1_test3.sam"/>
</test>
<test>
<param name="input" value="filter1_inbad.bed"/>
<param name="cond" value="c1=='chr22'"/>
<output name="out_file1" file="filter1_test4.bed"/>
</test>
</tests>
<help>