IMP  2.0.1
The Integrative Modeling Platform
_representation.py
1 """Interface between XML Representation and IMP Model."""
2 
3 import IMP
4 import IMP.atom
5 import random
6 import math
7 
8 class Representation(object):
9  """Store Representation."""
10 
11  def __init__(self):
12  """ """
13  self._children = list()
14  self._model = None
15 
16  def get_imp_hierarchy_by_id(self, id):
17  """Return an IMP::atom::Hierarchy by particle id.
18  @param id Particle id.
19  @return An IMP::atom::Hierarchy hierarchy."""
20  return self.find_by_id(id).model_decorator
21 
22  def get_root_imp_hierarchy(self):
23  """Return the root of the IMP::atom::Hierarchy"""
24  return self.model_decorator
25 
26  def find_all_by_id(self, id): # assuming there are many obj with the same id
27  """Return a list of all nodes that have the id given by the parameter"""
28 
29  def _find_rec(node):
30  if node.id == id:
31  found.append(node)
32  for child in node._children:
33  _find_rec(child)
34 
35  found = list()
36  for child in self._children:
37  _find_rec(child)
38  return found
39 
40  def find_by_id(self, id): # assuming there is just one obj with the same id
41  """Return a node that have the id given by the parameter"""
42 
43  def _find_rec(node):
44  if node.id == id:
45  return node
46  for child in node._children:
47  r = _find_rec(child)
48  if r:
49  return r
50  return None
51 
52  for child in self._children:
53  r = _find_rec(child)
54  if r:
55  return r
56  return None
57 
58  def get_model(self, model=None):
59  """Return an IMP::Model that contains the representation"""
60  if model is None:
61  model = self._model
62  if model is None:
63  self._model = model = IMP.Model()
64  else:
65  return model
66  else:
67  self._model = model
68  repr_particle = IMP.Particle(model)
69  decorator = IMP.atom.Hierarchy.setup_particle(repr_particle)
70  self.model_decorator = decorator
71  for child in self._children:
72  child.set_parent(self)
73  for child in self._children:
74  child.add_as_child(decorator, model)
75  return model
76 
77  def __str__(self):
78  return '<Representation>\n%s\n</Representation>' %\
79  ('\n'.join([child._to_str(1) for child in self._children]))
80 
81 
82 class _RepresentationNode(object):
83  counter = 0
84  def __init__(self, attributes):
85  id = attributes.get('id')
86  if id:
87  self.id = id
88  else:
89  self.id = 'object_%d' % _RepresentationNode.counter
90  _RepresentationNode.counter += 1
91  self._children = list()
92  self.model_decorator = None
93  self.parent = None
94  self.force_field = 0
95 
96  def set_parent(self, parent):
97  self.parent = parent
98  for child in self._children:
99  child.set_parent(self)
100 
101  def add_as_child(self, particle, model):
102  """Add this node as a child of particle."""
103  #print 'add_as_child', self
104  if not self.model_decorator:
105  decorator = self.to_particle(model)
106  self.model_decorator = decorator
107  #print 'model_decorator:',[self.model_decorator]
108  if decorator:
109  particle.add_child(decorator)
110  else:
111  decorator = particle
112  for child in self._children:
113  child.add_as_child(decorator, model)
114 
115  def to_particle(self, model):
116  self.this_particle = IMP.Particle(model)
117  decorator = IMP.atom.Hierarchy.setup_particle(self.this_particle)
118  return decorator
119 
120  def _attr_to_str(self):
121  return ('RepresentationNode', 'id="%s"' % self.id)
122 
123  def _to_str(self, level):
124  indent = ' '*level
125  name, strattr = self._attr_to_str()
126  if not self._children:
127  return '%s<%s %s/>' % (indent, name, strattr)
128  else:
129  return '%s<%s %s>\n%s\n%s</%s>' %\
130  (indent, name, strattr,
131  '\n'.join([child._to_str(level + 1)
132  for child in self._children]), indent, name)
133 
134  def __str__(self):
135  return self._to_str(0)
136 
137 
138 class _RepUniverse(_RepresentationNode):
139  def __init__(self, attributes):
140  _RepresentationNode.__init__(self, attributes)
141 
142  def _attr_to_str(self):
143  return ('Universe', 'id="%s"' % self.id)
144 
145 
146 class _RepCollection(_RepresentationNode):
147  def __init__(self, attributes):
148  _RepresentationNode.__init__(self, attributes)
149 
150  def _attr_to_str(self):
151  return ('Collection', 'id="%s"' % self.id)
152 
153 
154 class _RepAssembly(_RepresentationNode):
155  def __init__(self, attributes):
156  _RepresentationNode.__init__(self, attributes)
157 
158  def _attr_to_str(self):
159  return ('Assembly', 'id="%s"' % self.id)
160 
161 
162 class _RepSegment(_RepresentationNode):
163  def __init__(self, attributes):
164  _RepresentationNode.__init__(self, attributes)
165 
166  def _attr_to_str(self):
167  return ('Segment', 'id="%s"' % self.id)
168 
169 
170 class _RepMolecule(_RepresentationNode):
171  def __init__(self, attributes):
172  _RepresentationNode.__init__(self, attributes)
173 
174  def _attr_to_str(self):
175  return ('Molecule', 'id="%s"' % self.id)
176 
177 
178 class _RepProtein(_RepresentationNode):
179  def __init__(self, attributes):
180  _RepresentationNode.__init__(self, attributes)
181 
182  def _attr_to_str(self):
183  return ('Protein', 'id="%s"' % self.id)
184 
185 
186 class _RepNucleicAcid(_RepresentationNode):
187  def __init__(self, attributes):
188  _RepresentationNode.__init__(self, attributes)
189 
190  def _attr_to_str(self):
191  return ('NucleicAcid', 'id="%s"' % self.id)
192 
193 
194 class _RepChain(_RepresentationNode):
195  def __init__(self, attributes):
196  _RepresentationNode.__init__(self, attributes)
197  self.filename = attributes.get('filename', '')
198  self.chain_label = attributes.get('chain_label', '')
199  self.selector = attributes.get('selector', '')
200  if self.filename:
201  self.force_field = int(attributes.get('force_field', '1'))
202  else:
203  self.force_field = 0
204  self.topology_file = attributes.get('topology_filename', IMP.atom.get_data_path('top_heav.lib'))
205  self.param_file = attributes.get('param_filename', IMP.atom.get_data_path('par.lib'))
206 
207  def _attr_to_str(self):
208  return ('Chain',
209  'id="%s" filename="%s" chain_label="%s" selector="%s"' %
210  (self.id, self.filename, self.chain_label, self.selector))
211 
212  def to_particle(self, model):
213  if self.filename:
214  if self.selector == 'CAlpha':
215  selector = IMP.atom.CAlphaPDBSelector()
216  elif self.selector == 'CBeta':
217  selector = IMP.atom.CBetaPDBSelector()
218  elif self.selector == 'C':
219  selector = IMP.atom.CPDBSelector()
220  elif self.selector == 'N':
221  selector = IMP.atom.NPDBSelector()
222  elif self.selector == 'All':
224  elif self.selector == 'Chain':
225  selector = IMP.atom.ChainPDBSelector(self.chain_label)
226  elif self.selector == 'Water':
227  selector = IMP.atom.WaterPDBSelector()
228  elif self.selector == 'Hydrogen':
229  selector = IMP.atom.HydrogenPDBSelector()
230  elif self.selector == 'NonWater':
231  selector = IMP.atom.NonWaterPDBSelector()
232  elif self.selector == 'P':
233  selector = IMP.atom.PPDBSelector()
234  elif self.selector == 'NonAlternatives':
235  selector = IMP.atom.NonAlternativesPDBSelector()
236  elif self.selector == 'NonWaterNonHydrogen':
237  selector = IMP.atom.NonWaterPDBSelector()
238  else:
240  decorator = IMP.atom.read_pdb(self.filename, model, selector)
241  IMP.atom.add_radii(decorator)
242  chains = IMP.atom.get_by_type(decorator, IMP.atom.CHAIN_TYPE)
243  self.fragment_decorator = chains[0]
244  parent = self.fragment_decorator.get_parent()
245  parent.remove_child(self.fragment_decorator)
246  if self._children and not self.filename:
247  particle = IMP.Particle(model)
248  decorator = IMP.atom.Chain.setup_particle(particle,
249  self.chain_label)
250  else:
251  if not self.filename and not self._children:
252  raise Exception, "Filename must be present for childless Chain %s" % self.id
253  decorator = self.fragment_decorator
254  return decorator
255 
256 class _RepFragment(_RepresentationNode):
257  def __init__(self, attributes):
258  _RepresentationNode.__init__(self, attributes)
259 
260  def _attr_to_str(self):
261  return ('Fragment', 'id="%s"' % self.id)
262 
263  def to_particle(self, model):
264  if len(self._children) != 1:
265  raise Exception, "Fragment %s must have exactly one child" % self.id
266  particle = IMP.Particle(model)
267  child = self._children[0]
268  child.add_attributes(particle)
269  decorator = IMP.atom.Fragment.setup_particle(particle)
270  if isinstance(child, _RepAtomicRep):
271  if not isinstance(self.parent, _RepChain):
272  raise Exception, "Parent of Fragment %s must be a chain" % self.id
273  if particle.has_attribute(IMP.IntKey('start_residue')):
274  start_residue = particle.get_value(IMP.IntKey('start_residue'))
275  else:
276  raise Exception, "Start residue is required for atomic rep of Fragment %s" % self.id
277  if particle.has_attribute(IMP.IntKey('end_residue')):
278  end_residue = particle.get_value(IMP.IntKey('end_residue'))
279  else:
280  raise Exception, "End residue is required for atomic rep of Fragment %s" % self.id
281  for x in xrange(int(start_residue), int(end_residue) + 1):
282  res_part = IMP.atom.get_residue(self.parent.fragment_decorator, x)
283  if res_part != IMP.atom.Hierarchy():
284  res_parent = res_part.get_parent()
285  res_parent.remove_child(res_part)
286  decorator.add_child(res_part)
287  else:
288  if not particle.has_attribute(IMP.FloatKey('x')):
289  particle.add_attribute(IMP.FloatKey('x'), random.uniform(-300, 300))
290  particle.set_is_optimized(IMP.FloatKey('x'), True)
291  if not particle.has_attribute(IMP.FloatKey('y')):
292  particle.add_attribute(IMP.FloatKey('y'), random.uniform(-300, 300))
293  particle.set_is_optimized(IMP.FloatKey('y'), True)
294  if not particle.has_attribute(IMP.FloatKey('z')):
295  particle.add_attribute(IMP.FloatKey('z'), random.uniform(-300, 300))
296  particle.set_is_optimized(IMP.FloatKey('z'), True)
297 
298  if particle.get_value(IMP.FloatKey('radius')) < 0:
299  particle.set_value(IMP.FloatKey('radius'),
300  particle.get_value(IMP.FloatKey('calc_radius')))
301  return decorator
302 
303 
304 class _RepAtomicRep(_RepresentationNode):
305  def __init__(self, attributes):
306  _RepresentationNode.__init__(self, attributes)
307  self.start_residue = int(attributes.get('start_residue', -1))
308  if not self.start_residue:
309  self.start_residue = int(attributes.get('start_nucleotide', -1))
310  self.end_residue = int(attributes.get('end_residue', -1))
311  if not self.end_residue:
312  self.end_residue = int(attributes.get('end_nucleotide', -1))
313  if self.start_residue < 0 or self.end_residue < 0:
314  raise Exception, "AtomicRep %s must have both start_(residue|nucleotide) and end_(residue|nucleotide)" % self.id
315 
316  def _attr_to_str(self):
317  return ('AtomicRep',
318  'id="%s" start_residue="%s" end_residue="%s"' %
319  (self.id, self.start_residue, self.end_residue))
320 
321  def to_particle(self, model):
322  return None
323 
324  def add_attributes(self, parent):
325  parent.add_attribute(IMP.IntKey("start_residue"), self.start_residue)
326  parent.add_attribute(IMP.IntKey("end_residue"), self.end_residue)
327  for child in self._children:
328  child.add_attributes(parent)
329 
330 class _RepGeometricShapeRep(_RepresentationNode):
331  def __init__(self, attributes):
332  _RepresentationNode.__init__(self, attributes)
333  self.start_residue = int(attributes.get('start_residue', -1))
334  if self.start_residue < 0:
335  self.start_residue = int(attributes.get('start_nucleotide', -1))
336  self.end_residue = int(attributes.get('end_residue', -1))
337  if self.end_residue < 0:
338  self.end_residue = int(attributes.get('end_nucleotide', -1))
339  self.total_residue = int(attributes.get('total_residue', -1))
340  if self.total_residue >= 0 and self.end_residue >= 0 and \
341  self.start_residue >= 0:
342  if self.total_residue != self.end_residue + 1 - self.start_residue:
343  raise Exception, "Total residues dubious consistency in Geometric Shape _Rep %s" % self.id
344 
345  def _attr_to_str(self):
346  return ('GeometricShapeRep',
347  'id="%s" start_residue="%s" end_residue="%s" total_residue="%s"' %
348  (self.id, self.start_residue, self.end_residue, self.total_residue))
349 
350  def to_particle(self, model):
351  return None
352 
353  def add_attributes(self, parent):
354  parent.add_attribute(IMP.IntKey('start_residue'), self.start_residue)
355  parent.add_attribute(IMP.IntKey('end_residue'), self.end_residue)
356  r = -1
357  if self.start_residue < 0 and self.end_residue < 0:
358  total_residue = self.total_residue
359  else:
360  total_residue = self.end_residue-self.start_residue+1
361  if total_residue >= 0:
364  r = (v/(4.0*math.pi)*3.0)**(1.0/3)
365  parent.add_attribute(IMP.FloatKey('calc_radius'), r)
366  for child in self._children:
367  child.add_attributes(parent)
368 
369 
370 class _RepSphere(_RepresentationNode):
371  def __init__(self, attributes):
372  _RepresentationNode.__init__(self, attributes)
373  self.radius = float(attributes.get('radius', -1))
374  self.weight = float(attributes.get('weight', 0))
375  self.__initial_position = None
376 
377  def _attr_to_str(self):
378  return ('Sphere',
379  'id="%s" radius="%s" weight="%s"' %
380  (self.id, self.radius, self.weight))
381 
382  def initial_position(self):
383  if self.__initial_position is None:
384  for child in self._children:
385  if isinstance(child, _RepInitialPosition):
386  self.__initial_position = child
387  break
388  return self.__initial_position
389 
390  def to_particle(self, model):
391  return None
392 
393  def add_attributes(self, parent):
394  parent.add_attribute(IMP.FloatKey("radius"), self.radius)
395  parent.add_attribute(IMP.FloatKey("weight"), self.weight)
396  parent.add_attribute(IMP.FloatKey("mass"), self.weight)
397  for child in self._children:
398  child.add_attributes(parent)
399 
400 class _RepInitialPosition(_RepresentationNode):
401  def __init__(self, attributes):
402  _RepresentationNode.__init__(self, attributes)
403  self.optimize = int(attributes.get('optimize', -1))
404  self.x = float(attributes['x'])
405  self.y = float(attributes['y'])
406  self.z = float(attributes['z'])
407 
408  def _attr_to_str(self):
409  return ('InitialPosition',
410  'id="%s" x="%s" y="%s" z="%s" optimize="%s"' %
411  (self.id, self.x, self.y, self.z, self.optimize))
412 
413  def to_particle(self, model):
414  return None
415 
416  def add_attributes(self, parent):
417  fl_x = IMP.FloatKey("x")
418  fl_y = IMP.FloatKey("y")
419  fl_z = IMP.FloatKey("z")
420  parent.add_attribute(fl_x, self.x)
421  parent.add_attribute(fl_y, self.y)
422  parent.add_attribute(fl_z, self.z)
423  parent.add_attribute(IMP.IntKey("optimize"), self.optimize)
424  if self.optimize == 1:
425  parent.set_is_optimized(fl_x, True)
426  parent.set_is_optimized(fl_y, True)
427  parent.set_is_optimized(fl_z, True)