Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/allpy/file/d87129162eb4/allpy/markups.py
Дата изменения: Unknown
Дата индексирования: Mon Feb 4 05:14:39 2013
Кодировка:
allpy: d87129162eb4 allpy/markups.py

allpy

view allpy/markups.py @ 822:d87129162eb4

Implemented & tested new markup API. See #95 1) Sequences, Alignment and Blocks now have two new methods: - add_markup(name, markup_class=optional, **kwargs=optional) - remove_markup(name) name refers to the same name as in aln.markups[name] or sequence[i].name It is now explicitly denied to create markups any other way. 2) Markups now have `remove()` method that means 'release all memory that would not be released otherwised, if we just remove markup from the dictionary'. For sequences markups it removes markup attribute from each monomer. 3) Added necessary del sequence_markup[monomer] method. 4) Many base classes have attribute `kind`; for Alignments and Blocks it is 'alignment', for Sequences it is 'sequence' for AlignmentMarkups it is 'alignment_markup' for SequenceMarkups it is 'sequence_markup'. This attribute is crucial for new alignment construction API. 5) Common stuff for MarkupContainers (Alignments and Sequences) is in MarkupContainerMixin.
author Daniil Alexeyevsky <dendik@kodomo.fbb.msu.ru>
date Fri, 15 Jul 2011 16:43:03 +0400
parents 91e73fb1ac79
children 4f896db3531d
line source
1 import base
3 by_name = {}
4 """A dictionary of default markup name -> markup class."""
6 def update(*args):
7 """Update `by_name` dictionary.
9 If any arguments are given, add them to markups namespace beforehands.
10 """
11 # Add user classes if necessary
12 for markup_class in args:
13 class_name = markup_class.__name__
14 assert class_name not in globals(), "SameNamed markup already exists!"
15 globals()[class_name] = markup_class
16 # Update `by_name` dictonary
17 global by_name
18 by_name = {}
19 for markup_class in globals().values():
20 if hasattr(markup_class, 'name') and hasattr(markup_class, 'kind'):
21 fullname = markup_class.kind, markup_class.name
22 assert fullname not in by_name, "Samenamed markup already exists!"
23 by_name[fullname] = markup_class
25 class IntMarkupMixin(base.Markup):
27 @classmethod
28 def from_record(cls, container, record, name=None):
29 assert record['io-class'] == 'IntMarkup'
30 result = container.add_markup(name, markup_class=cls)
31 separator = record.get('separator', ',')
32 values = record['markup'].split(separator)
33 assert len(values) == len(result.sorted_keys())
34 for key, value in zip(result.sorted_keys(), values):
35 if value:
36 result[key] = int(value)
37 return result
39 def to_record(self):
40 def fmt(value):
41 if value is None:
42 return ""
43 return str(value)
44 values = [fmt(self.get(key)) for key in self.sorted_keys()]
45 return {'markup': ','.join(values), 'io-class': 'IntMarkup'}
47 class SequenceNumberMarkup(base.SequenceMarkup):
49 name = 'number'
51 def refresh(self):
52 for number, monomer in enumerate(self.sequence, 1):
53 monomer.number = number
55 class SequenceIndexMarkup(base.SequenceMarkup):
57 name = 'index'
59 def refresh(self):
60 for index, monomer in enumerate(self.sequence):
61 monomer.index = index
63 class AlignmentNumberMarkup(base.AlignmentMarkup):
65 name = 'number'
67 def refresh(self):
68 for number, column in enumerate(self.alignment.columns, 1):
69 self[column] = number
71 class AlignmentIndexMarkup(base.AlignmentMarkup):
73 name = 'index'
75 def refresh(self):
76 for index, column in enumerate(self.alignment.columns):
77 self[column] = index
79 class SequenceCaseMarkup(base.SequenceMarkup):
81 name = 'case'
83 def refresh(self):
84 for monomer in self.sequence:
85 if monomer.input_code1.isupper():
86 monomer.case = 'upper'
87 elif monomer.input_code1.islower():
88 monomer.case = 'lower'
90 @classmethod
91 def from_record(cls, container, record, name=None):
92 assert record['io-class'] == 'SequenceCaseMarkup'
93 result = container.add_markup(name, markup_class=cls)
94 markup = record['markup']
95 assert markup[0] == markup[-1] == "'"
96 markup = markup[1:-1]
97 assert len(markup) == len(result.sequence)
98 for monomer, mark in zip(result.sequence, markup):
99 assert monomer.code1 == mark.upper()
100 if mark.isupper():
101 monomer.case = 'upper'
102 if mark.islower():
103 monomer.case = 'lower'
104 return result
106 def to_record(self):
107 markup = ''
108 for monomer in self.sequence:
109 case = self.get(monomer)
110 if case == 'upper':
111 markup += monomer.code1.upper()
112 elif case == 'lower':
113 markup += monomer.code1.lower()
114 return {'markup': "'%s'" % markup, 'io-class': 'SequenceCaseMarkup'}
116 class SequencePdbResiMarkup(base.SequenceMarkup, IntMarkupMixin):
117 name = 'pdb_resi'
119 def from_pdb(self):
120 for monomer in self.sequence:
121 try:
122 monomer.pdb_resi = monomer.pdb_residue.id[1]
123 except Exception:
124 pass
126 def add_pdb(self, download_pdb=None, xyz_only=False):
127 import structure
128 if download_pdb is None:
129 download_pdb = structure.cached_download_pdb
131 match = structure.pdb_id_parse(self.sequence.name)
132 code, model , chain = match['code'], match['model'], match['chain']
133 pdb_file = download_pdb(code)
134 pdb_structure = structure.get_structure(pdb_file, self.sequence.name)
135 pdb_chain = pdb_structure[0][chain]
136 if not xyz_only:
137 self.sequence.pdb_chain = pdb_chain
138 for monomer in self.sequence:
139 if monomer in self:
140 pdb_residue = pdb_chain[' ', monomer.pdb_resi, ' ']
141 monomer.ca_xyz = pdb_residue['CA'].get_vector()
142 if not xyz_only:
143 monomer.pdb_residue = pdb_residue
145 # This MUST be the last statement in this module.
146 update()
148 # vim: set ts=4 sts=4 sw=4 et: