Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/allpy/diff/e3bcb9f8d7b0/allpy/base.py
Дата изменения: Unknown
Дата индексирования: Sat Mar 1 14:27:35 2014
Кодировка:
allpy: allpy/base.py diff

allpy

diff allpy/base.py @ 328:e3bcb9f8d7b0

Got rid of all MonomerType classes
author Daniil Alexeyevsky <me.dendik@gmail.com>
date Fri, 17 Dec 2010 16:28:58 +0300
parents 6fdc4406e2fd
children 9bf144c25dbd
line diff
     1.1 --- a/allpy/base.py	Fri Dec 17 00:58:54 2010 +0300
     1.2 +++ b/allpy/base.py	Fri Dec 17 16:28:58 2010 +0300
     1.3 @@ -7,140 +7,71 @@
     1.4  default_gaps = set((".", "-", "~"))
     1.5  """Set of characters to recoginze as gaps when parsing alignment."""
     1.6  
     1.7 -class MonomerType(object):
     1.8 -    """Class of monomer types.
     1.9 +class Monomer(object):
    1.10 +    """Monomer object."""
    1.11  
    1.12 -    Each MonomerType object represents a known monomer type, e.g. Valine,
    1.13 -    and is referenced to by each instance of monomer in a given sequence.
    1.14 -
    1.15 -    - `name`: full name of monomer type
    1.16 -    - `code1`: one-letter code
    1.17 -    - `code3`: three-letter code
    1.18 -    - `is_modified`: either of True or False
    1.19 -
    1.20 -    class atributes:
    1.21 -
    1.22 -    - `by_code1`: a mapping from one-letter code to MonomerType object
    1.23 -    - `by_code3`: a mapping from three-letter code to MonomerType object
    1.24 -    - `by_name`: a mapping from monomer name to MonomerType object
    1.25 -    - `instance_type`: class of Monomer objects to use when creating new
    1.26 -      objects; this must be redefined in descendent classes
    1.27 -
    1.28 -    All of the class attributes MUST be redefined when subclassing.
    1.29 -    """
    1.30 +    type = None
    1.31 +    """Either of 'dna', 'rna', 'protein'."""
    1.32  
    1.33      by_code1 = {}
    1.34 +    """A mapping from 1-letter code to Monomer subclass."""
    1.35 +
    1.36      by_code3 = {}
    1.37 +    """A mapping from 3-letter code to Monomer subclass."""
    1.38 +
    1.39      by_name = {}
    1.40 -    instance_type = None
    1.41 -
    1.42 -    def __init__(self, name="", code1="", code3="", is_modified=False):
    1.43 -        super(MonomerType, self).__init__()
    1.44 -        self.name = name.capitalize()
    1.45 -        self.code1 = code1.upper()
    1.46 -        self.code3 = code3.upper()
    1.47 -        self.is_modified = bool(is_modified)
    1.48 -        if not is_modified:
    1.49 -            self.by_code1[self.code1] = self
    1.50 -        self.by_code3[code3] = self
    1.51 -        self.by_name[name] = self
    1.52 -        # We duplicate distinguished long names into MonomerType itself,
    1.53 -        # so that we can use MonomerType.from_code3 to create the relevant
    1.54 -        # type of monomer.
    1.55 -        MonomerType.by_code3[code3] = self
    1.56 -        MonomerType.by_name[name] = self
    1.57 +    """A mapping from full monomer name to Monomer subclass."""
    1.58  
    1.59      @classmethod
    1.60 -    def _initialize(cls, type_letter, codes=data.codes.codes):
    1.61 -        """Create all relevant instances of MonomerType.
    1.62 +    def _subclass(cls, name='', code1='', code3='', is_modified=False):
    1.63 +        """Create new subclass of Monomer for given monomer type."""
    1.64 +        class TheMonomer(cls):
    1.65 +            pass
    1.66 +        name = name.strip().capitalize()
    1.67 +        code1 = code1.upper()
    1.68 +        code3 = code3.upper()
    1.69 +        TheMonomer.__name__ = "Monomer"
    1.70 +        TheMonomer.name = name
    1.71 +        TheMonomer.code1 = code1
    1.72 +        TheMonomer.code3 = code3
    1.73 +        TheMonomer.is_modified = is_modified
    1.74 +        if not is_modified:
    1.75 +            cls.by_code1[code1] = TheMonomer
    1.76 +        cls.by_code3[code3] = TheMonomer
    1.77 +        cls.by_name[name] = TheMonomer
    1.78 +        # We duplicate distinguished long names into Monomer itself, so that we
    1.79 +        # can use Monomer.from_code3 to create the relevant type of monomer.
    1.80 +        Monomer.by_code3[code3] = TheMonomer
    1.81 +        Monomer.by_name[name] = TheMonomer
    1.82  
    1.83 -        `type_letter` is either of:
    1.84 -
    1.85 -        - 'p' for protein
    1.86 -        - 'd' for DNA
    1.87 -        - 'r' for RNA
    1.88 -
    1.89 -        `codes` is a table of monomer codes
    1.90 -        """
    1.91 +    @classmethod
    1.92 +    def _initialize(cls, codes=data.codes.codes):
    1.93 +        """Create all relevant subclasses of Monomer."""
    1.94 +        # NB. The table uses letters d, r, p for types,
    1.95 +        # while we use full words; hence, we compare by first letter
    1.96          for type, code1, is_modified, code3, name in codes:
    1.97 -            if type == type_letter:
    1.98 -                cls(name, code1, code3, is_modified)
    1.99 +            if type[0] == cls.type[0]:
   1.100 +                cls._subclass(name, code1, code3, is_modified)
   1.101  
   1.102      @classmethod
   1.103      def from_code1(cls, code1):
   1.104 -        """Return monomer type by one-letter code."""
   1.105 -        return cls.by_code1[code1.upper()]
   1.106 +        """Create new monomer from 1-letter code."""
   1.107 +        return cls.by_code1[code1.upper()]()
   1.108  
   1.109      @classmethod
   1.110      def from_code3(cls, code3):
   1.111 -        """Return monomer type by three-letter code."""
   1.112 -        return cls.by_code3[code3.upper()]
   1.113 +        """Create new monomer from 3-letter code."""
   1.114 +        return cls.by_code3[code3.upper()]()
   1.115  
   1.116      @classmethod
   1.117      def from_name(cls, name):
   1.118 -        """Return monomer type by name."""
   1.119 -        return cls.by_name[name.capitalize()]
   1.120 -
   1.121 -    def instance(self):
   1.122 -        """Create a new monomer of given type."""
   1.123 -        return self.instance_type(self)
   1.124 +        """Create new monomer from full name."""
   1.125 +        return cls.by_name[name.strip().capitalize()]()
   1.126  
   1.127      def __eq__(self, other):
   1.128 -        if hasattr(other, "type"):
   1.129 -            return self is other.type
   1.130 -        return self is other
   1.131 -
   1.132 -class Monomer(object):
   1.133 -    """Monomer object.
   1.134 -
   1.135 -    attributes:
   1.136 -
   1.137 -    - `type`: type of monomer (a MonomerType object)
   1.138 -
   1.139 -    class attributes:
   1.140 -
   1.141 -    - `monomer_type`: either MonomerType or one of it's subclasses, it is used
   1.142 -      when creating new monomers. It SHOULD be redefined when subclassing
   1.143 -      Monomer.
   1.144 -    """
   1.145 -    monomer_type = MonomerType
   1.146 -
   1.147 -    def __init__(self, type):
   1.148 -        super(Monomer, self).__init__()
   1.149 -        self.type = type
   1.150 -
   1.151 -    @classmethod
   1.152 -    def from_code1(cls, code1):
   1.153 -        return cls(cls.monomer_type.by_code1[code1.upper()])
   1.154 -
   1.155 -    @classmethod
   1.156 -    def from_code3(cls, code3):
   1.157 -        return cls(cls.monomer_type.by_code3[code3.upper()])
   1.158 -
   1.159 -    @classmethod
   1.160 -    def from_name(cls, name):
   1.161 -        return cls(cls.monomer_type.by_name[name.capitalize()])
   1.162 -
   1.163 -    @property
   1.164 -    def code1(self):
   1.165 -        return self.type.code1
   1.166 -
   1.167 -    @property
   1.168 -    def code3(self):
   1.169 -        return self.type.code3
   1.170 -
   1.171 -    @property
   1.172 -    def name(self):
   1.173 -        return self.type.name
   1.174 -
   1.175 -    @property
   1.176 -    def is_modified(self):
   1.177 -        return self.type.is_modified
   1.178 -
   1.179 -    def __eq__(self, other):
   1.180 -        if hasattr(other, "type"):
   1.181 -            return self.type is other.type
   1.182 -        return self.type is other
   1.183 +        """Monomers within same monomer type are compared by code1."""
   1.184 +        assert self.type == other.type
   1.185 +        return self.code1 == other.code1
   1.186  
   1.187  class Sequence(list):
   1.188      """Sequence of Monomers.