File size: 7,837 Bytes
b7731cd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/env python
#
#      Restriction Analysis Libraries.
#      Copyright (C) 2004. Frederic Sohm.
#
# 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.
#
"""Restriction Digest Enzymes.

Examples
--------
    >>> from Bio.Seq import Seq
    >>> from Bio.Restriction import *
    >>> pBs_mcs = 'GGTACCGGGCCCCCCCTCGAGGTCGACGGTATCGATAAGCTTGATATCGAATTCCTG'
    >>> pBs_mcs += 'CAGCCCGGGGGATCCACTAGTTCTAGAGCGGCCGCCACCGCGGTGGAGCTC'
    >>> seq = Seq(pBs_mcs)  # Multiple-cloning site of pBluescript SK(-)
    >>> a = Analysis(AllEnzymes, seq)
    >>> a.print_that()              # no argument -> print all the results
    AbaSI      :  10, 12, 13, 16, 17, 18, 19, 20, 22, 23, 24, 25, 25, 26, 27...
    BmeDI      :  2, 7, 8, 8, 9, 9, 13, 14, 15, 16, 17, 18, 19, 19, 21, 21...
    YkrI       :  10, 12, 13, 16, 16, 17, 19, 20, 21, 22, 23, 24, 25, 25, 26...

    BmeDI      :  1, 2, 7, 8, 8, 9, 9, 13, 14, 15, 16, 17, 18, 19...
    AccII      :  98.
    AciI       :  86, 90, 96, 98...

    Enzymes which do not cut the sequence.

    AspLEI    BstHHI    CfoI      CviAII    FaeI      FaiI      FatI      GlaI
    HhaI      Hin1II    Hin6I     HinP1I    HpyCH4IV  HpySE526I Hsp92II   HspAI
    MaeII     MseI      NlaIII    SaqAI     TaiI      Tru1I     Tru9I...
    <BLANKLINE>
    >>> b = a.blunt()  # Analysis with blunt enzmyes
    >>> a.print_that(b)  # Print results for blunt cutters
    AccII      :  98.
    AfaI       :  4.
    AluBI      :  40, 106.
    AluI       :  40, 106.
    Bsh1236I   :  98.
    BshFI      :  10, 89.
    BsnI       :  10, 89.
    BspANI     :  10, 89...

    Enzymes which do not cut the sequence.

    FaiI      GlaI      CdiI      MlyI      SchI      SspD5I    AanI...
    <BLANKLINE>

"""  # noqa: W291, W293

from Bio.Restriction.Restriction import *  # noqa (legacy module arrangement)


#
#   OK can't put the following code in Bio.Restriction.__init__ unless
#   I put everything from Restriction in here.
#   or at least the RestrictionBatch class.
#
#   The reason for that is if I do that, I break the __contains__ method of
#   the RestrictionBatch in Restriction, which expect to find the name of
#   the enzymes in the locals() dictionary when evaluating string to see if
#   it is an enzyme.
#
#   This calls for some explanations I guess:
#       When testing for the presence of a Restriction enzyme in a
#       RestrictionBatch, the user can use:
#
#           1) a class of type 'RestrictionType'
#           2) a string of the name of the enzyme (its repr)
#               i.e:
#                   >>> from Bio.Restriction import RestrictionBatch, EcoRI
#                   >>> MyBatch = RestrictionBatch(EcoRI)
#                   >>> EcoRI in MyBatch        # the class EcoRI.
#                   True
#                   >>> 'EcoRI' in MyBatch      # a string representation
#                   True
#
#   OK, that's how it is supposed to work. And I find it quite useful.
#
#   Now if I leave the code here I got:
#                   >>> from Bio.Restriction import RestrictionBatch, EcoRI
#                   >>> MyBatch = RestrictionBatch(EcoRI)
#                   >>> EcoRI in MyBatch # the class EcoRI.
#                   True
#                   >>> 'EcoRI' in MyBatch   # a string.
#                   False

#   There is 5 ways to change that:
#       1) abandon the evaluation of string representation.
#       2) leave the code like that and hack something in RestrictionBatch.
#       3) Move back the code in Bio.Restriction.Restriction
#       4) Move RestrictionBatch here.
#       5) Remove Restriction.Restriction and move all the code in here
#
#   1) no fun in that.
#   2) there is a simpler way to do it.
#   3) I prefer to keep all the code together.
#   4) and 5) both are OK. Only a matter of preference.
#
#   So the following code has been moved back to Bio.Restriction.Restriction
#   For the user the results is transparent:
#   from Bio.Restriction import * works as before.
#

# ##
# ##   The restriction enzyme classes are created dynamically when the module
# ##   is imported. Here is the magic which allow the creation of the
# ##   restriction-enzyme classes.
# ##
# ##   The reason for the two dictionaries in Restriction_Dictionary
# ##   one for the types (which will be called pseudo-type as they really
# ##   correspond to the values that instances of RestrictionType can take)
# ##   and one for the enzymes is efficiency as the bases are evaluated
# ##   once per pseudo-type.
# ##
# ##   However Restriction is still a very inefficient module at import. But
# ##   remember that around 660 classes (which is more or less the size of
# ##   Rebase) have to be created dynamically. However, this processing take
# ##   place only once.
# ##   This inefficiency is however largely compensated by the use of metaclass
# ##   which provide a very efficient layout for the class themselves mostly
# ##   alleviating the need of if/else loops in the class methods.
# ##
# ##   It is essential to run Restriction with doc string optimisation (-OO
# ##   switch) as the doc string of 660 classes take a lot of processing.
# ##
# # CommOnly    = RestrictionBatch()    # commercial enzymes
# # NonComm     = RestrictionBatch()    # not available commercially
# # for TYPE, (bases, enzymes) in typedict.items():
# #    #
# #    #   The keys are the pseudo-types TYPE (stored as type1, type2...)
# #    #   The names are not important and are only present to differentiate
# #    #   the keys in the dict. All the pseudo-types are in fact
# #    #   RestrictionType. These names will not be used after and the pseudo-
# #    #   types are not kept in the locals() dictionary. It is therefore
# #    #   impossible to import them.
# #    #   Now, if you have look at the dictionary, you will see that not all
# #    #   the types are present as those without corresponding enzymes have
# #    #   been removed by Dictionary_Builder().
# #    #
# #    #   The values are tuples which contain
# #    #   as first element a tuple of bases (as string) and
# #    #   as second element the names of the enzymes.
# #    #
# #    #   First eval the bases.
# #    #
# #    bases = tuple(eval(x) for x in bases)
# #    #
# #    #   now create the particular value of RestrictionType for the classes
# #    #   in enzymes.
# #    #
# #    T = type.__new__(RestrictionType, 'RestrictionType', bases, {})
# #    for k in enzymes:
# #        #
# #        #   Now, we go through all the enzymes and assign them their type.
# #        #   enzymedict[k] contains the values of the attributes for this
# #        #   particular class (self.site, self.ovhg,....).
# #        #
# #        newenz = T(k, bases, enzymedict[k])
# #        #
# #        #   we add the enzymes to the corresponding batch.
# #        #
# #        #   No need to verify the enzyme is a RestrictionType -> add_nocheck
# #        #
# #        if newenz.is_comm() : CommOnly.add_nocheck(newenz)
# #        else : NonComm.add_nocheck(newenz)
# ##
# ##   AllEnzymes is a RestrictionBatch with all the enzymes from Rebase.
# ##
# # AllEnzymes = CommOnly | NonComm
# ##
# ##   Now, place the enzymes in locals so they can be imported.
# ##
# # names = [str(x) for x in AllEnzymes]
# # locals().update(dict(map(None, names, AllEnzymes)))
# ##
# ##   Limit what can be imported by from Restriction import *
# ##   Most of the classes here will never be used outside this module
# ##   (Defined,Palindromic...). It is still possible to request them
# ##   specifically
# ##
# ##   also delete the variable that are no longer needed.
# ##
# ##
# # __all__= ['Analysis', 'RestrictionBatch','AllEnzymes','CommOnly',
# #           'NonComm']+names
# # del k, x, enzymes, TYPE, bases, names