Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

# Copyright 2008-2013 by Peter Cock.  All rights reserved. 

# This code is part of the Biopython distribution and governed by its 

# license.  Please see the LICENSE file that should have been included 

# as part of this package. 

"""AlignIO support module (not for general use). 

 

Unless you are writing a new parser or writer for Bio.AlignIO, you should not 

use this module.  It provides base classes to try and simplify things. 

""" 

 

from __future__ import print_function 

 

import sys # for checking if Python 2 

 

from Bio.Alphabet import single_letter_alphabet 

 

 

class AlignmentIterator(object): 

    """Base class for building MultipleSeqAlignment iterators. 

 

    You should write a next() method to return Aligment 

    objects.  You may wish to redefine the __init__ 

    method as well. 

    """ 

    #TODO - Should the default be Gapped(single_letter_alphabet) instead? 

    def __init__(self, handle, seq_count=None, 

                 alphabet = single_letter_alphabet): 

        """Create an AlignmentIterator object. 

 

        handle   - input file 

        count    - optional, expected number of records per alignment 

                   Recommend for fasta file format. 

        alphabet - optional, e.g. Bio.Alphabet.generic_protein 

 

        Note when subclassing: 

        - there should be a single non-optional argument, the handle, 

          and optional count and alphabet IN THAT ORDER. 

        - you do not have to require an alphabet (?). 

        - you can add additional optional arguments.""" 

        self.handle = handle 

        self.records_per_alignment = seq_count 

        self.alphabet = alphabet 

        ##################################################### 

        # You may want to subclass this, for example        # 

        # to read through the file to find the first record,# 

        # or if additional arguments are required.          # 

        ##################################################### 

 

    def __next__(self): 

        """Return the next alignment in the file. 

 

        This method should be replaced by any derived class to do something 

        useful.""" 

        raise NotImplementedError("This object should be subclassed") 

        ##################################################### 

        # You SHOULD subclass this, to split the file up    # 

        # into your individual alignments and convert these # 

        # into MultipleSeqAlignment objects.                # 

        ##################################################### 

 

    if sys.version_info[0] < 3: 

        def next(self): 

            """Python 2 style alias for Python 3 style __next__ method.""" 

            return self.__next__() 

 

    def __iter__(self): 

        """Iterate over the entries as MultipleSeqAlignment objects. 

 

        Example usage for (concatenated) PHYLIP files: 

 

        with open("many.phy","r") as myFile: 

            for alignment in PhylipIterator(myFile): 

                print "New alignment:" 

                for record in alignment: 

                    print record.id 

                    print record.seq 

        """ 

        return iter(self.__next__, None) 

 

 

class AlignmentWriter(object): 

    """Base class for building MultipleSeqAlignment writers. 

 

    You should write a write_alignment() method. 

    You may wish to redefine the __init__ method as well""" 

 

    def __init__(self, handle): 

        self.handle = handle 

 

    def write_file(self, alignments): 

        """Use this to write an entire file containing the given alignments. 

 

        alignments - A list or iterator returning MultipleSeqAlignment objects 

 

        In general, this method can only be called once per file. 

 

        This method should be replaced by any derived class to do something 

        useful.  It should return the number of alignments""" 

        raise NotImplementedError("This object should be subclassed") 

        ##################################################### 

        # You SHOULD subclass this, to write the alignment  # 

        # objecta to the file handle                        # 

        ##################################################### 

 

    def clean(self, text): 

        """Use this to avoid getting newlines in the output.""" 

        return text.replace("\n", " ").replace("\r", " ").replace("  ", " ") 

 

 

class SequentialAlignmentWriter(AlignmentWriter): 

    """Base class for building MultipleSeqAlignment writers. 

 

    This assumes each alignment can be simply appended to the file. 

    You should write a write_alignment() method. 

    You may wish to redefine the __init__ method as well""" 

 

    def __init__(self, handle): 

        self.handle = handle 

 

    def write_file(self, alignments): 

        """Use this to write an entire file containing the given alignments. 

 

        alignments - A list or iterator returning MultipleSeqAlignment objects 

 

        In general, this method can only be called once per file.""" 

        self.write_header() 

        count = 0 

        for alignment in alignments: 

            self.write_alignment(alignment) 

            count += 1 

        self.write_footer() 

        return count 

 

    def write_header(self): 

        """Use this to write any header. 

 

        This method should be replaced by any derived class to do something 

        useful.""" 

        pass 

 

    def write_footer(self): 

        """Use this to write any footer. 

 

        This method should be replaced by any derived class to do something 

        useful.""" 

        pass 

 

    def write_alignment(self, alignment): 

        """Use this to write a single alignment. 

 

        This method should be replaced by any derived class to do something 

        useful.""" 

        raise NotImplementedError("This object should be subclassed") 

        ##################################################### 

        # You SHOULD subclass this, to write the alignment  # 

        # objecta to the file handle                        # 

        #####################################################