IMP logo
IMP Reference Guide  2.14.0
The Integrative Modeling Platform
EMageFit/imp_general/representation.py
1 """@namespace IMP.EMageFit.imp_general.representation
2  Utility functions to handle representation.
3 """
4 
5 import IMP
6 import IMP.atom
7 import IMP.core
8 import IMP.algebra
9 import string
10 import logging
11 
12 log = logging.getLogger("representation")
13 
14 #
15 """
16 
17  Functions to deal with the representation of assemblies and managing
18  rigid bodies.
19 
20 """
21 #
22 
23 
24 def create_assembly_from_pdb(model, fn_pdb, names=False):
25  """
26  Builds the assembly setting the chains in the PDB file as components
27  """
28  temp = read_component(model, fn_pdb)
29  hchains = IMP.atom.get_by_type(temp, IMP.atom.CHAIN_TYPE)
30  ids = [IMP.atom.Chain(h).get_id() for h in hchains]
31  log.debug("Creating assembly from pdb %s,names: %s. Chains %s",
32  fn_pdb, names, ids)
33  IMP.atom.add_radii(temp)
34  if(names):
35  for i, h in enumerate(hchains):
36  h.set_name(names[i])
37  assembly = IMP.atom.Molecule.setup_particle(temp)
38  return assembly
39 
40 
41 def create_assembly(model, fn_pdbs, names=False):
42  """ Read all the PDBs given in the list of names fn_pdbs and adds the
43  hierarchies to the model
44  """
46  for i, fn_pdb in enumerate(fn_pdbs):
47  if(names):
48  prot = read_component(model, fn_pdb, names[i])
49  else:
50  prot = read_component(model, fn_pdb)
51  assembly.add_child(prot)
52  return assembly
53 
54 
55 def read_component(model, fn_pdb, name=False):
56  """ Read a PDB molecule, add atoms, and set a name
57  """
58  if name:
59  log.debug("reading component %s from %s", name, fn_pdb)
60  else:
61  log.debug("reading component from %s", fn_pdb)
62 
63  hierarchy = IMP.atom.read_pdb(fn_pdb, model,
65  if name:
66  hierarchy.set_name(name)
67  IMP.atom.add_radii(hierarchy)
68  return hierarchy
69 
70 
71 def create_rigid_bodies(assembly):
72  """ set the children of a molecule type hierarchy as rigid bodies
73  In this case, all the children are the components of the complex.
74  I use the function create_rigid_body(), that creates a lot of
75  sub-rigid bodies.
76 
77  I have changed the function and now build the rigid body directly from
78  the leaves of each of the components. With this I guarantee that the
79  number of rigid members is going to be the same if the components have
80  the same number of atoms.
81  """
82  if not IMP.atom.Molecule.get_is_setup(assembly):
83  raise TypeError("create_rigid_bodies(): The argument is not a valid "
84  "hierarchy")
85  molecule = IMP.atom.Molecule(assembly)
86  rbs = []
87  for c in molecule.get_children():
88  p = IMP.Particle(c.get_model())
90  rb = IMP.core.RigidBody(p)
91 # rb = IMP.atom.create_rigid_body(c)
92  rb.set_name(get_rb_name(c.get_name()))
93  rbs.append(rb)
94  return rbs
95 
96 
97 def rename_chains(assembly):
98  """ Rename all the chains of an assembly so there are no conflicts with
99  the ids. The names are added sequentially.
100  """
101  if not IMP.atom.Molecule.get_is_setup(assembly):
102  raise TypeError("The argument is not a valid hierarchy")
103  m = IMP.atom.Molecule(assembly)
104  all_chains_as_hierarchies = get_all_chains(m.get_children())
105  letters = string.ascii_uppercase
106  n_chains = len(all_chains_as_hierarchies)
107  if(len(letters) < n_chains):
108  raise ValueError("There are more chains than letter ids")
109  ids = letters[0:n_chains]
110  for h, c_id in zip(all_chains_as_hierarchies, ids):
111  chain = IMP.atom.Chain(h.get_particle())
112  chain.set_id(c_id)
113  chain.set_name("chain %s" % c_id)
114 
115 
116 def create_simplified_dna(dna_hierarchy, n_res):
117  """ Gets a hierarchy containing a molecule of DNA and simplifies it,
118  generating a coarse representation of spheres. The function returns
119  a hierarchy with the spheres.
120  n_res - Number of residues to use per sphere.
121  """
122  if not IMP.atom.Chain.get_is_setup(dna_hierarchy):
123  raise TypeError("create_simplified_dna: the hierarchy provided is not a "
124  "chain.")
125 
126  model = dna_hierarchy.get_model()
127  ph = IMP.Particle(model)
128  simplified_h = IMP.atom.Hierarchy.setup_particle(ph)
130 
131  residues = IMP.atom.get_by_type(dna_hierarchy, IMP.atom.RESIDUE_TYPE)
132  l = len(residues)
133  # print "the DNA has ",l,"residues"
134  for i in range(0, l, n_res):
135  xyzrs = []
136  equivalent_mass = 0.0
137  residues_numbers = []
138  for r in residues[i: i + n_res]:
139  rr = IMP.atom.Residue(r)
140  residues_numbers.append(rr.get_index())
141  # print "residue",rr.get_name(),rr.get_index()
142  residue_xyzrs = [IMP.core.XYZ(a.get_particle())
143  for a in rr.get_children()]
144  xyzrs += residue_xyzrs
145 # print "residue",r,"mass",get_residue_mass(r)
146  equivalent_mass += get_residue_mass(r)
147 
149  p = IMP.Particle(model)
151  xyzr.set_radius(s.get_radius())
152  xyzr.set_coordinates(s.get_center())
154  fragment.set_residue_indexes(residues_numbers)
155  IMP.atom.Mass.setup_particle(p, equivalent_mass)
156  simplified_h.add_child(fragment)
157  simplified_h.set_name("DNA")
158 # print "simplified_h is valid:",simplified_h.get_is_valid(True)
159  return simplified_h
160 
161 
162 def get_residue_mass(residue):
163  if not IMP.atom.Residue.get_is_setup(residue):
164  raise TypeError("The argument is not a residue")
165  r = IMP.atom.Residue(residue)
166  mass = 0.0
167  for l in IMP.atom.get_leaves(r):
168  ms = IMP.atom.Mass(l)
169  mass += ms.get_residue_mass()
170  return mass
171 
172 
173 def create_simplified_assembly(assembly, components_rbs, n_res):
174  """ Simplifies an assembly, by creating a hierarchy with one ball per
175  n_res residues. Each of the chains in the new hierarchy are added to
176  the rigid bodies for each of the components.
177  There must be correspondence between the children of the assembly
178  (components) and the rigid bodies. I check for the ids.
179  """
180  if not IMP.atom.Molecule.get_is_setup(assembly):
181  raise TypeError("The argument is not a valid hierarchy")
182  molecule = IMP.atom.Molecule(assembly)
183 
184  model = assembly.get_model()
185  n_children = molecule.get_number_of_children()
186 
187  sh = IMP.Particle(model)
188  simplified_hierarchy = IMP.atom.Molecule.setup_particle(sh)
189 
190  for i in range(n_children): # for all members of the assembly
191  component = molecule.get_child(i)
192  name = component.get_name()
193  rb = components_rbs[i]
194  if(rb.get_name() != get_rb_name(name)):
195  raise ValueError("Rigid body and component do not match")
196 
197  hchains = IMP.atom.get_by_type(component, IMP.atom.CHAIN_TYPE)
198  ch = IMP.Particle(model)
199  coarse_component_h = IMP.atom.Molecule.setup_particle(ch)
200  # simplify all the chains in the member
201  for h in hchains:
202  chain = IMP.atom.Chain(h.get_particle())
203  coarse_h = None
204  if(name == "DNA"):
205  # print "simplifying DNA"
206  coarse_h_particle = create_simplified_dna(h, n_res)
207  coarse_h = IMP.atom.Hierarchy(coarse_h_particle)
208  else:
210  n_res)
211 
212  # does not work for DNA
213  chain_rb = IMP.atom.create_rigid_body(coarse_h)
214  # chain_rb = IMP.atom.setup_as_rigid_body(coarse_h) # works with DNA
215  chain_rb.set_name("sub_rb" + name)
216  rb.add_member(chain_rb)
217 
218  # are required to have excluded volume
219  coarse_component_h.add_child(IMP.atom.Chain(coarse_h))
220  coarse_component_h.set_name(name)
221  simplified_hierarchy.add_child(coarse_component_h)
222  return simplified_hierarchy
223 
224 
225 def get_component(assembly, name):
226  """ Select a component of the assembly using the name """
227  for c in assembly.get_children():
228  if (c.get_name() == name):
229  return c
230  raise ValueError(
231  "The requested component %s is not in the assembly" %
232  name)
233 
234 
235 def get_rigid_body(rigid_bodies, name):
236  """ Select a rigid body from the rigid_bodies using the name """
237  for rb in rigid_bodies:
238  if (rb.get_name() == name):
239  return rb
240  raise ValueError("This rigid body is not in the set: %s" % name)
241 
242 
243 def get_rb_name(name):
244  """ Name to use for the rigid body of a hierarch"""
245  return "rb_" + name
246 
247 
249  """ Build the rigid body for all the particles in the selection S """
250  ps = S.get_selected_particles()
251  xyzrs = [IMP.core.XYZR(p) for p in ps]
252  p_rbS = IMP.Particle(model)
253  rbS = IMP.core.RigidBody.setup_particle(p_rbS, xyzrs)
254  return rbS
255 
256 
257 def get_selection_as_hierarchy(model, S):
258  ph = IMP.Particle(model)
260  for p in S.get_selected_particles():
262  h.add_child(x)
263  return h
264 
265 
267  """ Gets a selection of particles and decorates them as Atoms.
268  Then all of them are put into a big residue. I have this to use
269  with the multifit.create_coarse_molecule_from_molecule() function
270  """
271  ph = IMP.Particle(model)
273  for p in S.get_selected_particles():
274  h.add_child(IMP.atom.Atom(p))
275  return h
276 
277 
278 def get_coarse_selection(coarse_h, residues_numbers):
279  """ The function returns the particles (fragments) in the coarse hierarchy
280  that were created by summarizing the residues_numbers.
281 
282  Coarse hierarchy - Hierarchy formed by a bunch of
283  fragments. Each fragment must have the residue numbers that it contains
284  residue_numbers - list with the number of the residues that need to
285  be recovered.
286  The function returns the set of particles that are IMP.atom.Fragments
287  """
288  particles = []
289  fragments = IMP.atom.get_by_type(coarse_h, IMP.atom.FRAGMENT_TYPE)
290  for f in fragments:
291  ff = IMP.atom.Fragment(f)
292  residues_in_f = ff.get_residue_indexes()
293  for number in residues_in_f:
294  if number in residues_numbers:
295  particles.append(ff.get_particle())
296  break
297  return particles
298 
299 
301  """
302  Rotates the reference frame of a rigid body around the centroid
303  """
304  c = rb.get_coordinates()
305  ref = rb.get_reference_frame()
306  R = ref.get_transformation_to().get_rotation()
307  R2 = IMP.algebra.compose(rot, R)
310  rb.set_reference_frame(ref)
311 
312 
314  """
315  Applies a transformation around the centroid of a rigid body.
316  First does the rotation around the centroid and
317  then applies the transformation.
318  @param rb A IMP.core.RigidBody object
319  @param T a IMP.algebra.Transformation3D object
320  """
321  apply_rotation_around_centroid(rb, T.get_rotation())
322  rb.set_coordinates(rb.get_coordinates() + T.get_translation())
323 
324 
325 def get_residue_particle(h, chain_id=False, res=1):
326  """
327  Get the particle for a residue in a hierarchy.
328  @param h The hierarchy
329  @param chain_id If chain_id == False, just search for the residue
330  @param res Number of residue in the chain
331  """
332 # log.debug("get_residue_particle: chain_id %s, res %s",chain_id, res)
333  if(chain_id):
334  s = IMP.atom.Selection(h, chain=chain_id, residue_index=res)
335  else:
336  s = IMP.atom.Selection(h, residue_index=res)
337  return s.get_selected_particles()[0]
338 
339 
340 def get_residue_coordinates(h, chain_id=False, res=1):
341  """
342  Get the coordinates of a residue (the coordinates of the first particle)
343  @param h Hierarchy
344  @param chain_id See help for get_residue_particle()
345  @param res See help for get_residue_particle()
346  """
347  p = get_residue_particle(h, chain_id, res)
348  return IMP.core.XYZ(p).get_coordinates()
349 
350 
351 def get_residues_distance(hierarchy1, chain_id1, residue1,
352  hierarchy2, chain_id2, residue2):
353  """
354  Distance between two residues. See the help for get_residue_particle()
355  @param hierarchy1
356  @param chain_id1
357  @param residue1
358  @param hierarchy2
359  @param chain_id2
360  @param residue2
361  """
362  coords1 = get_residue_coordinates(hierarchy1, chain_id1, residue1)
363  coords2 = get_residue_coordinates(hierarchy2, chain_id2, residue2)
364  d = IMP.algebra.get_distance(coords1, coords2)
365  return d
366 
367 
368 def get_all_chains(hierarchies):
369  """ Gets all the chains in a set of hierarchies
370  @param hierarchies A set of IMP.atom.Hierarchy objects
371  """
372  chains = []
373  for h in hierarchies:
374  chains_in_h = IMP.atom.get_by_type(h, IMP.atom.CHAIN_TYPE)
375  for ch in chains_in_h:
376  chains.append(IMP.atom.Chain(ch))
377  return chains
378 
379 
380 def set_reference_frames(rigid_bodies, reference_frames):
381  for ref, rb in zip(reference_frames, rigid_bodies):
382  rb.set_reference_frame(ref)
383 
384 
385 def get_nucleic_acid_backbone(hierarchy, backbone='minimal'):
386  """
387  Returns the atoms in the backbone of the nucleic acid contained
388  in the hierarchy.
389  backbone 'minimal' returns the atoms: ["P", "O5'", "C5'", "C4'", "C3'", "O3'"]
390  backbone 'trace' returns the atoms C4'
391  """
392 # log.debug("get_nucleic_acid_backbone")
393  backbone_atoms = []
394  if backbone == 'minimal':
395  backbone_atoms = ["P", "O5'", "C5'", "C4'", "C3'", "O3'"]
396  elif backbone == 'trace':
397  backbone_atoms = ["C4'"]
398  else:
399  raise ValueError("Wrong value for the type of backbone")
400  backbone_atom_types = [IMP.atom.AtomType(t) for t in backbone_atoms]
401  h_chains = IMP.atom.get_by_type(hierarchy, IMP.atom.CHAIN_TYPE)
402  backbone = []
403  if len(h_chains) > 1:
404  raise ValueError("The hierarchy mas more than one chain")
405  h_residues = IMP.atom.get_by_type(hierarchy, IMP.atom.RESIDUE_TYPE)
406  for hr in h_residues:
407  res = IMP.atom.Residue(hr)
408  if not (res.get_is_dna() or res.get_is_rna()):
409  raise ValueError("Residue is not part of a nucleic acid")
410  h_atoms = IMP.atom.get_by_type(hr, IMP.atom.ATOM_TYPE)
411  for at in h_atoms:
412  if IMP.atom.Atom(at).get_atom_type() in backbone_atom_types:
413  backbone.append(at)
414  return backbone
415 
416 
417 def get_calphas(chain_hierarchy):
418  h_residues = IMP.atom.get_by_type(chain_hierarchy, IMP.atom.RESIDUE_TYPE)
420  for r in h_residues]
421  return cas
422 
423 
424 def get_backbone(hierarchy):
425  """
426  Get the backbone atoms for a hierarchy. It can be a protein or a
427  nucleic acid
428  """
429  h_residues = IMP.atom.get_by_type(hierarchy, IMP.atom.RESIDUE_TYPE)
430  if len(h_residues) == 0:
431  raise ValueError("No residues!")
432  atoms = []
433  res = IMP.atom.Residue(h_residues[0])
434  if res.get_is_dna() or res.get_is_rna():
435  atoms = get_nucleic_acid_backbone(hierarchy, 'trace')
436  else:
437  atoms = get_calphas(hierarchy)
438  return atoms
439 
440 
441 def get_all_members(rigid_bodies):
442  """
443  Gets all the members of a set of rigid bodies, removing the subrigid
444  bodies. Returns all the plain atom or bead members
445  """
446 
447  members = []
448  for rb in rigid_bodies:
449  members += get_simple_members(rb)
450  return members
451 
452 
453 def get_simple_members(rb):
454  # Add members if they are not sub-rigid bodies
455  members = [m for m in rb.get_members()
456  if not IMP.core.RigidBody.get_is_setup(m.get_particle())]
457  return members
Select non water and non hydrogen atoms.
Definition: pdb.h:245
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: Molecule.h:35
Add mass to a particle.
Definition: Mass.h:23
Simple 3D transformation class.
def get_selection_as_atom_hierarchy
Gets a selection of particles and decorates them as Atoms.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: Residue.h:156
A decorator to associate a particle with a part of a protein/DNA/RNA.
Definition: Fragment.h:20
def get_nucleic_acid_backbone
Returns the atoms in the backbone of the nucleic acid contained in the hierarchy. ...
static Fragment setup_particle(Model *m, ParticleIndex pi)
Definition: Fragment.h:63
static XYZR setup_particle(Model *m, ParticleIndex pi)
Definition: XYZR.h:48
def create_simplified_assembly
Simplifies an assembly, by creating a hierarchy with one ball per n_res residues. ...
def get_residue_particle
Get the particle for a residue in a hierarchy.
def create_rigid_bodies
set the children of a molecule type hierarchy as rigid bodies In this case, all the children are the ...
void add_radii(Hierarchy d, const ForceFieldParameters *ffp=get_all_atom_CHARMM_parameters(), FloatKey radius_key=FloatKey("radius"))
def get_selection_rigid_body
Build the rigid body for all the particles in the selection S.
def get_component
Select a component of the assembly using the name.
def get_backbone
Get the backbone atoms for a hierarchy.
The type of an atom.
def apply_rotation_around_centroid
Rotates the reference frame of a rigid body around the centroid.
static Residue setup_particle(Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
Definition: Residue.h:158
Atom get_atom(Residue rd, AtomType at)
Return a particle atom from the residue.
def get_all_members
Gets all the members of a set of rigid bodies, removing the subrigid bodies.
def get_all_chains
Gets all the chains in a set of hierarchies.
void read_pdb(TextInput input, int model, Hierarchy h)
A reference frame in 3D.
def get_rb_name
Name to use for the rigid body of a hierarch.
static Molecule setup_particle(Model *m, ParticleIndex pi)
Definition: Molecule.h:37
def apply_transformation_around_centroid
Applies a transformation around the centroid of a rigid body.
def create_assembly_from_pdb
Builds the assembly setting the chains in the PDB file as components.
static Hierarchy setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor children=ParticleIndexesAdaptor())
Create a Hierarchy of level t by adding the needed attributes.
The standard decorator for manipulating molecular structures.
A decorator for a particle representing an atom.
Definition: atom/Atom.h:234
static Mass setup_particle(Model *m, ParticleIndex pi, Float mass)
Definition: Mass.h:48
static Hierarchy setup_particle(Model *m, ParticleIndex pi, DecoratorTraits tr=get_default_decorator_traits())
def create_assembly
Read all the PDBs given in the list of names fn_pdbs and adds the hierarchies to the model...
def get_coarse_selection
The function returns the particles (fragments) in the coarse hierarchy that were created by summarizi...
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
Transformation3D compose(const Transformation3D &a, const Transformation3D &b)
Compose two transformations.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:163
def rename_chains
Rename all the chains of an assembly so there are no conflicts with the ids.
algebra::Sphere3D get_enclosing_sphere(const XYZs &v)
Get a sphere enclosing the set of XYZRs.
A decorator for a residue.
Definition: Residue.h:135
Basic functionality that is expected to be used by a wide variety of IMP users.
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: Chain.h:80
def get_rigid_body
Select a rigid body from the rigid_bodies using the name.
Hierarchy create_simplified_along_backbone(Chain input, const IntRanges &residue_segments, bool keep_detailed=false)
IMP::core::RigidBody create_rigid_body(Hierarchy h)
def get_residue_coordinates
Get the coordinates of a residue (the coordinates of the first particle)
Class to handle individual particles of a Model object.
Definition: Particle.h:41
double get_distance(const VectorD< D > &v1, const VectorD< D > &v2)
Compute the distance between two vectors.
Definition: VectorD.h:209
Store info for a chain of a protein.
Definition: Chain.h:61
A decorator for a rigid body.
Definition: rigid_bodies.h:82
def create_simplified_dna
Gets a hierarchy containing a molecule of DNA and simplifies it, generating a coarse representation o...
Functionality for loading, creating, manipulating and scoring atomic structures.
def read_component
Read a PDB molecule, add atoms, and set a name.
static Chain setup_particle(Model *m, ParticleIndex pi, std::string id)
Definition: Chain.h:81
Hierarchies get_leaves(const Selection &h)
A decorator for a molecule.
Definition: Molecule.h:24
Select hierarchy particles identified by the biological name.
Definition: Selection.h:66
static RigidBody setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor ps)
Definition: rigid_bodies.h:174
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27