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

allpy

view allpy/markups.py @ 1143:a9d4a06ed103

pair-cores/web: add header "Description" before example and description * * * 1
author Boris Nagaev <bnagaev@gmail.com>
date Mon, 14 Jan 2013 02:44:43 +0400
parents 3c32489fcb3b
children
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 not hasattr(markup_class, 'name') or not markup_class.name:
21 continue
22 if not hasattr(markup_class, 'kind') or not markup_class.kind:
23 continue
24 fullname = markup_class.kind, markup_class.name
25 assert fullname not in by_name, "Markup %s already exists!" % (fullname,)
26 by_name[fullname] = markup_class
28 class MarkupIOMixin(base.Markup):
29 """Standard helper mixin for creating saveable markups."""
31 separator = ','
32 """Separator to use when saving/loading markup."""
34 quotes = ''
35 """Quotation sign used on the markup."""
37 io_class = None
38 """MUST be overloaded when subclassing. io_class in file."""
40 @staticmethod
41 def parse_item(key, value):
42 """Deserialize one item of markup. Overload when subclassing."""
43 return value
45 @staticmethod
46 def repr_item(key, value):
47 """Serialize one item of markup. Overload when subclassing."""
48 return str(value)
50 @classmethod
51 def from_record(cls, container, record, name=None):
52 """Read markup from semi-parsed record from 'markup' file."""
53 assert record['io_class'] == cls.io_class
54 result = container.add_markup(name, markup_class=cls)
55 result.separator = record.get('separator', cls.separator)
56 result.quotes = record.get('quotes', cls.quotes)
57 values = record['markup'].strip(result.quotes)
58 if result.separator:
59 values = values.split(result.separator)
60 assert len(values) == len(result.sorted_keys())
61 for key, value in zip(result.sorted_keys(), values):
62 if value:
63 result[key] = result.parse_item(key, value)
64 return result
66 def to_record(self, keys=None):
67 """Write markup to semi-serialized record for 'markup' file."""
68 values = []
69 for key in keys or self.sorted_keys():
70 if key in self:
71 values.append(self.repr_item(key, self[key]))
72 else:
73 values.append('')
74 markup = self.separator.join(values)
75 return {
76 'markup': markup,
77 'io_class': self.io_class,
78 'separator': self.separator,
79 'quotes': self.quotes,
80 }
82 class IntMarkupMixin(MarkupIOMixin):
83 """Markup that has integer values."""
85 io_class = 'IntMarkup'
87 @staticmethod
88 def parse_item(key, value):
89 return int(value)
91 class FloatMarkupMixin(MarkupIOMixin):
92 """Markup that has float values."""
94 io_class = 'FloatMarkup'
96 @staticmethod
97 def parse_item(key, value):
98 return float(value)
100 class BoolMarkupMixin(MarkupIOMixin):
101 """Markup that has boolean values."""
103 io_class = 'BoolMarkup'
105 @staticmethod
106 def parse_item(key, value):
107 return value == '+'
109 @staticmethod
110 def repr_item(key, value):
111 if value:
112 return '+'
113 else:
114 return '-'
116 class CharMarkupMixin(MarkupIOMixin):
117 """Markup that has one-letter values."""
119 io_class = 'CharMarkup'
121 @staticmethod
122 def parse_item(key, value):
123 assert len(value) == 1
124 return value
126 @staticmethod
127 def repr_item(key, value):
128 assert len(str(value)) == 1
129 return str(value)
131 class StrMarkupMixin(MarkupIOMixin):
132 """Markup that is capable of storing ANY strings."""
134 io_class = 'StrMarkup'
136 def parse_item(self, key, value):
137 return value.replace("%2C", self.separator).replace("%25", "%")
139 def repr_item(self, key, value):
140 return str(value).replace("%", "%25").replace(self.separator, "%2C")
142 class SequenceStrMarkup(base.SequenceMarkup, StrMarkupMixin):
143 """Generic class for string-based markups."""
144 pass
146 class SequenceCharMarkup(base.SequenceMarkup, CharMarkupMixin):
147 """Generic class for one-letter markups."""
148 pass
150 class SequenceIntMarkup(base.SequenceMarkup, IntMarkupMixin):
151 """Generic class for integer number markups."""
152 pass
154 class SequenceFloatMarkup(base.SequenceMarkup, FloatMarkupMixin):
155 """Generic class for floating-point number markups."""
156 pass
158 class SequenceBoolMarkup(base.SequenceMarkup, BoolMarkupMixin):
159 """Generic class for boolean markups."""
160 pass
162 class SequenceNumberMarkup(base.SequenceMarkup):
164 name = 'number'
166 def refresh(self):
167 for number, monomer in enumerate(self.sequence, 1):
168 monomer.number = number
170 class SequenceIndexMarkup(base.SequenceMarkup):
172 name = 'index'
174 def refresh(self):
175 for index, monomer in enumerate(self.sequence):
176 monomer.index = index
178 class AlignmentStrMarkup(base.AlignmentMarkup, StrMarkupMixin):
179 """Generic class for string-based markups."""
180 pass
182 class AlignmentCharMarkup(base.AlignmentMarkup, CharMarkupMixin):
183 """Generic class for one-letter markups."""
184 pass
186 class AlignmentIntMarkup(base.AlignmentMarkup, IntMarkupMixin):
187 """Generic class for integer number markups."""
188 pass
190 class AlignmentFloatMarkup(base.AlignmentMarkup, FloatMarkupMixin):
191 """Generic class for floating-point number markups."""
192 pass
194 class AlignmentBoolMarkup(base.AlignmentMarkup, BoolMarkupMixin):
195 """Generic class for boolean markups."""
196 pass
198 class AlignmentNumberMarkup(base.AlignmentMarkup):
200 name = 'number'
202 def refresh(self):
203 for number, column in enumerate(self.alignment.columns, 1):
204 self[column] = number
206 class AlignmentIndexMarkup(base.AlignmentMarkup):
208 name = 'index'
210 def refresh(self):
211 for index, column in enumerate(self.alignment.columns):
212 self[column] = index
214 class SequenceCaseMarkup(base.SequenceMarkup, MarkupIOMixin):
216 name = 'case'
217 io_class = 'SequenceCaseMarkup'
218 separator = ''
219 quotes = "'"
221 def refresh(self):
222 for monomer in self.sequence:
223 if monomer.input_code1.isupper():
224 monomer.case = 'upper'
225 elif monomer.input_code1.islower():
226 monomer.case = 'lower'
228 @staticmethod
229 def parse_item(monomer, value):
230 assert monomer.code1 == value.upper()
231 if value.isupper():
232 return 'upper'
233 if value.islower():
234 return 'lower'
236 @staticmethod
237 def repr_item(monomer, value):
238 if monomer.case == 'upper':
239 return monomer.code1.upper()
240 if monomer.case == 'lower':
241 return monomer.code1.lower()
242 raise AssertionError("Unknown monomer case")
244 class SequenceQualityMarkup(base.SequenceMarkup, IntMarkupMixin):
245 name = 'quality'
247 class SequencePdbResiMarkup(base.SequenceMarkup, IntMarkupMixin):
248 name = 'pdb_resi'
250 def from_pdb(self):
251 for monomer in self.sequence:
252 try:
253 monomer.pdb_resi = monomer.pdb_residue.id[1]
254 except Exception:
255 pass
257 def add_pdb(self, download_pdb=None, xyz_only=False):
258 import structure
259 if download_pdb is None:
260 download_pdb = structure.cached_download_pdb
262 match = structure.pdb_id_parse(self.sequence.name)
263 code, model , chain = match['code'], match['model'], match['chain']
264 pdb_file = download_pdb(code)
265 pdb_structure = structure.get_structure(pdb_file, self.sequence.name)
266 pdb_chain = pdb_structure[0][chain]
267 if not xyz_only:
268 self.sequence.pdb_chain = pdb_chain
269 for monomer in self.sequence:
270 if monomer in self:
271 pdb_residue = pdb_chain[' ', monomer.pdb_resi, ' ']
272 monomer.ca_xyz = pdb_residue['CA'].get_vector()
273 if not xyz_only:
274 monomer.pdb_residue = pdb_residue
276 # This MUST be the last statement in this module.
277 update()
279 # vim: set ts=4 sts=4 sw=4 et: