Skip to content

Commit

Permalink
fixups for vcf_filter
Browse files Browse the repository at this point in the history
  • Loading branch information
libor-m committed Apr 5, 2012
1 parent 916ccab commit ea02716
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
38 changes: 24 additions & 14 deletions scripts/vcf_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
parser.add_argument('filters', metavar='filter', type=str, nargs='*', default=None,
help='Filters to use')
parser.add_argument('--no-short-circuit', action='store_true',
help='Do not stop filter processing on a site if a single filter fails.')
help='Do not stop filter processing on a site if a single filter fails')
parser.add_argument('--output', action='store', default=sys.stdout,
help='Filename to output (default stdout)')
help='Filename to output [stdout]')
parser.add_argument('--no-filtered', action='store_true',
help='Remove failed sites')
help='Output only sites passing the filters')
parser.add_argument('--local-script', action='store', default=None,
help='File in current working directory with filter classes (with .py)')
help='Python file in current working directory with the filter classes')


# TODO: allow filter specification by short name
Expand All @@ -35,38 +35,44 @@
def main():
# dynamically build the list of available filters
filters = {}
filter_help = '\n\navailable filters:'
filter_help = ['\navailable filters:']

def addfilt(filt, help):
filters[filt.name] = filt
filt.customize_parser(parser)
help += '\n %s:\t%s' % (filt.name, filt.description)
help.append(' %s:\t%s' % (filt.name, filt.description))

for p in pkg_resources.iter_entry_points('vcf.filters'):
filt = p.load()
addfilt(filt, filter_help)

# parse command line args
# (mainly because of local_script)
args = parser.parse_args()

# add all classes from local script, if present
if args.local_script != None:
import inspect
import sys, os
sys.path.insert(0, os.getcwd())
module_name = args.local_script.replace('.py', '')
mod = __import__(module_name)
classes = inspect.getmembers(mod, inspect.isclass)
for name, cls in classes:
addfilt(cls, filter_help)

parser.description += filter_help

# apply the updated argument definitions
args = parser.parse_args()

parser.description += '\n'.join(filter_help)

# show help after loading of the local module
# so it can include the additional options
if args.help or len(args.filters) == 0 or args.input == None:
parser.print_help()
parser.exit()

inp = vcf.Reader(file(args.input[0]))
inp = vcf.Reader(file(args.input))

# build filter chain
chain = []
Expand All @@ -79,16 +85,20 @@ def addfilt(filt, help):

# apply filters
short_circuit = not args.no_short_circuit
drop_filtered = args.no_filtered

for record in inp:
for filt in chain:
result = filt(record)
if result:
if result != None:
# save some work by skipping the rest of the code
if drop_filtered: break

record.add_filter(filt.filter_name())
if short_circuit:
break

if (not args.no_filtered) or (record.FILTER == '.'):
if short_circuit: break
else:
# use PASS only if other filter names appear in the FILTER column
if record.FILTER == '.' and not drop_filtered: record.FILTER = 'PASS'
oup.write_record(record)

if __name__ == '__main__': main()
4 changes: 3 additions & 1 deletion vcf/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,9 @@ def add_format(self, fmt):
self.FORMAT = self.FORMAT + ':' + fmt

def add_filter(self, flt):
if self.FILTER is None or self.FILTER == 'PASS':
if self.FILTER is None \
or self.FILTER == 'PASS'\
or self.FILTER == '.':
self.FILTER = ''
else:
self.FILTER = self.FILTER + ';'
Expand Down

0 comments on commit ea02716

Please sign in to comment.