#!/usr/bin/env python # Copyright 2004 by Michael Hoffman. All rights reserved. # This file is part of the Biopython distribution and governed by your # choice of the "Biopython License Agreement" or the "BSD 3-Clause License". # Please see the LICENSE file that should have been included as part of this # package. """Run and process output from the Wise2 package tool psw. Bio.Wise contains modules for running and processing the output of some of the models in the Wise2 package by Ewan Birney available from: ftp://ftp.ebi.ac.uk/pub/software/unix/wise2/ http://www.ebi.ac.uk/Wise2/ Bio.Wise.psw is for protein Smith-Waterman alignments Bio.Wise.dnal is for Smith-Waterman DNA alignments """ from __future__ import print_function import os import re import sys from Bio import Wise _CMDLINE_PSW = ["psw", "-l", "-F"] _OPTION_GAP_START = "-g" _OPTION_GAP_EXTENSION = "-e" _OPTION_SCORES = "-m" class AlignmentColumnFullException(Exception): pass class Alignment(list): def append(self, column_unit): try: self[-1].append(column_unit) except AlignmentColumnFullException: list.append(self, AlignmentColumn(column_unit)) except IndexError: list.append(self, AlignmentColumn(column_unit)) class AlignmentColumn(list): def _set_kind(self, column_unit): if self.kind == "SEQUENCE": self.kind = column_unit.kind def __init__(self, column_unit): """Initialize the class.""" assert column_unit.unit == 0 self.kind = column_unit.kind list.__init__(self, [column_unit.column, None]) def __repr__(self): return "%s(%s, %s)" % (self.kind, self[0], self[1]) def append(self, column_unit): if self[1] is not None: raise AlignmentColumnFullException assert column_unit.unit == 1 self._set_kind(column_unit) self[1] = column_unit.column class ColumnUnit(object): def __init__(self, unit, column, kind): """Initialize the class.""" self.unit = unit self.column = column self.kind = kind def __str__(self): return "ColumnUnit(unit=%s, column=%s, %s)" % (self.unit, self.column, self.kind) __repr__ = __str__ _re_unit = re.compile(r"^Unit +([01])- \[ *(-?\d+)- *(-?\d+)\] \[(\w+)\]$") def parse_line(line): """Parse a line from psw. >>> print(parse_line("Column 0:")) None >>> parse_line("Unit 0- [ -1- 0] [SEQUENCE]") ColumnUnit(unit=0, column=0, SEQUENCE) >>> parse_line("Unit 1- [ 85- 86] [SEQUENCE]") ColumnUnit(unit=1, column=86, SEQUENCE) """ match = _re_unit.match(line.rstrip()) if not match: return return ColumnUnit(int(match.group(1)), int(match.group(3)), match.group(4)) def parse(iterable): """Parse a file. format Column 0: Unit 0- [ -1- 0] [SEQUENCE] Unit 1- [ 85- 86] [SEQUENCE] means that seq1[0] == seq2[86] (0-based) """ alignment = Alignment() for line in iterable: try: if os.environ["WISE_PY_DEBUG"]: print(line) except KeyError: pass column_unit = parse_line(line) if column_unit: alignment.append(column_unit) return alignment def align(pair, scores=None, gap_start=None, gap_extension=None, *args, **keywds): cmdline = _CMDLINE_PSW[:] if scores: cmdline.extend((_OPTION_SCORES, scores)) if gap_start: cmdline.extend((_OPTION_GAP_START, str(gap_start))) if gap_extension: cmdline.extend((_OPTION_GAP_EXTENSION, str(gap_extension))) temp_file = Wise.align(cmdline, pair, *args, **keywds) return parse(temp_file) def main(): print(align(sys.argv[1:3])) def _test(*args, **keywds): import doctest doctest.testmod(sys.modules[__name__], *args, **keywds) if __name__ == "__main__": if __debug__: _test() """Initialize the class.""" main()