Spaces:
No application file
No application file
#!/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 | |