IMP logo
IMP Reference Guide  2.7.0
The Integrative Modeling Platform
pmi/representation.py
1 #!/usr/bin/env python
2 
3 """@namespace IMP.pmi.representation
4  Representation of the system.
5 """
6 
7 from __future__ import print_function
8 import IMP
9 import IMP.core
10 import IMP.algebra
11 import IMP.atom
12 import IMP.display
13 import IMP.isd
14 import IMP.pmi
15 import IMP.pmi.tools
16 import IMP.pmi.output
17 import IMP.rmf
18 import IMP.pmi.topology
19 import RMF
20 from math import pi, sqrt
21 from operator import itemgetter
22 import os
23 import weakref
24 
25 class _Repo(object):
26  def __init__(self, doi, root):
27  self.doi = doi
28  self._root = root
29 
30  def get_fname(self, fname):
31  """Return a path relative to the top of the repository"""
32  return os.path.relpath(fname, self._root)
33 
34 class Representation(object):
35  # Authors: Peter Cimermancic, Riccardo Pellarin, Charles Greenberg
36 
37  '''
38  Set up the representation of all proteins and nucleic acid macromolecules.
39 
40  Create the molecular hierarchies, representation,
41  sequence connectivity for the various involved proteins and
42  nucleic acid macromolecules:
43 
44  Create a protein, DNA or RNA, represent it as a set of connected balls of appropriate
45  radii and number of residues, PDB at given resolution(s), or ideal helices.
46 
47  How to use the SimplifiedModel class (typical use):
48 
49  see test/test_hierarchy_contruction.py
50 
51  examples:
52 
53  1) Create a chain of helices and flexible parts
54 
55  c_1_119 =self.add_component_necklace("prot1",1,119,20)
56  c_120_131 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(120,131))
57  c_132_138 =self.add_component_beads("prot1",[(132,138)])
58  c_139_156 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(139,156))
59  c_157_174 =self.add_component_beads("prot1",[(157,174)])
60  c_175_182 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(175,182))
61  c_183_194 =self.add_component_beads("prot1",[(183,194)])
62  c_195_216 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(195,216))
63  c_217_250 =self.add_component_beads("prot1",[(217,250)])
64 
65 
66  self.set_rigid_body_from_hierarchies(c_120_131)
67  self.set_rigid_body_from_hierarchies(c_139_156)
68  self.set_rigid_body_from_hierarchies(c_175_182)
69  self.set_rigid_body_from_hierarchies(c_195_216)
70 
71  clist=[c_1_119,c_120_131,c_132_138,c_139_156,c_157_174,c_175_182,c_183_194,c_195_216,
72  c_217_250]
73 
74  self.set_chain_of_super_rigid_bodies(clist,2,3)
75 
76  self.set_super_rigid_bodies(["prot1"])
77 
78  '''
79 
80  def __init__(self, m, upperharmonic=True, disorderedlength=True):
81  """Constructor.
82  @param m the model
83  @param upperharmonic This flag uses either harmonic (False)
84  or upperharmonic (True) in the intra-pair
85  connectivity restraint.
86  @param disorderedlength This flag uses either disordered length
87  calculated for random coil peptides (True) or zero
88  surface-to-surface distance between beads (False)
89  as optimal distance for the sequence connectivity
90  restraint.
91  """
92 
93  self._metadata = []
94  self._file_dataset = {}
95  self._protocol_output = []
96 
97  # this flag uses either harmonic (False) or upperharmonic (True)
98  # in the intra-pair connectivity restraint. Harmonic is used whe you want to
99  # remove the intra-ev term from energy calculations, e.g.:
100  # upperharmonic=False
101  # ip=self.get_connected_intra_pairs()
102  # ev.add_excluded_particle_pairs(ip)
103 
104  self.upperharmonic = upperharmonic
105  self.disorderedlength = disorderedlength
106  self.rigid_bodies = []
107  self.fixed_rigid_bodies = []
108  self.fixed_floppy_bodies = []
109  self.floppy_bodies = []
110  # self.super_rigid_bodies is a list of tuples.
111  # each tuple, corresponding to a particular super rigid body
112  # the tuple is (super_rigid_xyzs,super_rigid_rbs)
113  # where super_rigid_xyzs are the flexible xyz particles
114  # and super_rigid_rbs is the list of rigid bodies.
115  self.super_rigid_bodies = []
116  self.rigid_body_symmetries = []
117  self.output_level = "low"
118  self.label = "None"
119 
120  self.maxtrans_rb = 2.0
121  self.maxrot_rb = 0.04
122  self.maxtrans_srb = 2.0
123  self.maxrot_srb = 0.2
124  self.rigidbodiesarefixed = False
125  self.floppybodiesarefixed = False
126  self.maxtrans_fb = 3.0
127  self.resolution = 10.0
128  self.bblenght = 100.0
129  self.kappa = 100.0
130  self.m = m
131 
132  self.representation_is_modified = False
133  self.unmodeledregions_cr_dict = {}
134  self.sortedsegments_cr_dict = {}
136  self.connected_intra_pairs = []
137  self.hier_dict = {}
138  self.color_dict = {}
139  self.sequence_dict = {}
140  self.hier_geometry_pairs = {}
141  self.hier_db = IMP.pmi.tools.HierarchyDatabase()
142  # this dictionary stores the hierarchies by component name and representation type
143  # self.hier_representation[name][representation_type]
144  # where representation type is Res:X, Beads, Densities, Representation,
145  # etc...
146  self.hier_representation = {}
147  self.hier_resolution = {}
148  # reference structures is a dictionary that contains the coordinates of
149  # structures that are used to calculate the rmsd
150  self.reference_structures = {}
151  self.elements = {}
152  self.linker_restraints = IMP.RestraintSet(self.m, "linker_restraints")
153  self.linker_restraints_dict = {}
154  self.threetoone = {'ALA': 'A', 'ARG': 'R', 'ASN': 'N', 'ASP': 'D',
155  'CYS': 'C', 'GLU': 'E', 'GLN': 'Q', 'GLY': 'G',
156  'HIS': 'H', 'ILE': 'I', 'LEU': 'L', 'LYS': 'K',
157  'MET': 'M', 'PHE': 'F', 'PRO': 'P', 'SER': 'S',
158  'THR': 'T', 'TRP': 'W', 'TYR': 'Y', 'VAL': 'V', 'UNK': 'X'}
159 
160  self.onetothree = dict((v, k) for k, v in self.threetoone.items())
161 
162  self.residuenamekey = IMP.StringKey("ResidueName")
163 
164  def add_metadata(self, m):
165  """Associate some metadata with this modeling.
166  @param m an instance of IMP.pmi.metadata.Metadata or a subclass.
167  """
168  self._metadata.append(m)
169 
170  def set_file_dataset(self, fname, dataset):
171  """Associate a dataset with a filename.
172  This can be used to identify how the file was produced (in many
173  cases IMP can determine this automatically from a file header or
174  other metadata, but not always). For example, a manually-produced
175  PDB file (not from the PDB database or Modeller) can be
176  identified this way.
177  @param fname filename
178  @dataset the IMP.pmi.metadata.Dataset object to associate.
179  """
180  self._file_dataset[os.path.abspath(fname)] = dataset
181 
182  def get_file_dataset(self, fname):
183  """Get the dataset associated with a filename, or None.
184  @param fname filename
185  @return an IMP.pmi.metadata.Dataset, or None.
186  """
187  return self._file_dataset.get(os.path.abspath(fname), None)
188 
189  def add_protocol_output(self, p):
190  """Capture details of the modeling protocol.
191  @param p an instance of IMP.pmi.output.ProtocolOutput or a subclass.
192  """
193  self._protocol_output.append(p)
194  p._metadata = self._metadata
195  p._file_dataset = self._file_dataset
196  p.m = self.m
197  p.prot = self.prot
198  # Ugly, but we need to be able to call set_coordinates_from_rmf().
199  p._representation = weakref.proxy(self)
200  protocol_output = property(lambda self: self._protocol_output[:])
201 
202  def set_label(self, label):
203  self.label = label
204 
205  def create_component(self, name, color=0.0):
207  protein_h.set_name(name)
208  self.hier_dict[name] = protein_h
209  self.hier_representation[name] = {}
210  self.hier_db.add_name(name)
211  self.prot.add_child(protein_h)
212  self.color_dict[name] = color
213  self.elements[name] = []
214  for p in self._protocol_output:
215  p.create_component(name, True)
216 
218  """Create a component that isn't used in the modeling.
219  No coordinates or other structural data for this component will
220  be read or written, but a primary sequence can be assigned. This
221  is useful if the input experimental data is of a system larger
222  than that modeled. Any references to these non-modeled components
223  can then be correctly resolved later."""
224  self.elements[name] = []
225  for p in self._protocol_output:
226  p.create_component(name, False)
227 
228  # Deprecation warning
229 
230  @IMP.deprecated_method("2.5", "Use create_component() instead.")
231  def add_component_name(self, *args, **kwargs):
232  self.create_component(*args, **kwargs)
233 
234  def get_component_names(self):
235  return list(self.hier_dict.keys())
236 
237  def add_component_sequence(self, name, filename, id=None, offs=None,
238  format="FASTA"):
239  '''
240  Add the primary sequence for a single component.
241 
242  @param name Human-readable name of the component
243  @param filename Name of the FASTA file
244  @param id Identifier of the sequence in the FASTA file header
245  (if not provided, use `name` instead)
246  '''
247  record_dict = IMP.pmi.topology.Sequences(filename)
248  if id is None:
249  id = name
250  if id not in record_dict:
251  raise KeyError("id %s not found in fasta file" % id)
252  length = len(record_dict[id])
253  self.sequence_dict[name] = str(record_dict[id])
254  if offs is not None:
255  offs_str="-"*offs
256  self.sequence_dict[name]=offs_str+self.sequence_dict[name]
257 
258  self.elements[name].append((length, length, " ", "end"))
259  for p in self._protocol_output:
260  p.add_component_sequence(name, self.sequence_dict[name])
261 
262  def autobuild_model(self, name, pdbname, chain,
263  resolutions=None, resrange=None,
264  missingbeadsize=20,
265  color=None, pdbresrange=None, offset=0,
266  show=False, isnucleicacid=False,
267  attachbeads=False):
268 
269  self.representation_is_modified = True
270  outhiers = []
271 
272  if color is None:
273  color = self.color_dict[name]
274  else:
275  self.color_dict[name] = color
276 
277  if resolutions is None:
278  resolutions = [1]
279  print("autobuild_model: constructing %s from pdb %s and chain %s" % (name, pdbname, str(chain)))
280 
281  # get the initial and end residues of the pdb
282  t = IMP.atom.read_pdb(pdbname, self.m,
284 
285  # find start and end indexes
286 
287  start = IMP.atom.Residue(
288  t.get_children()[0].get_children()[0]).get_index()
289  end = IMP.atom.Residue(
290  t.get_children()[0].get_children()[-1]).get_index()
291 
292  # check if resrange was defined, otherwise
293  # use the sequence, or the pdb resrange
294 
295  if resrange is None:
296  if name in self.sequence_dict:
297  resrange = (1, len(self.sequence_dict[name]))
298  else:
299  resrange = (start + offset, end + offset)
300  else:
301  if resrange[1] in (-1, 'END'):
302  resrange = (resrange[0],end)
303  start = resrange[0] - offset
304  end = resrange[1] - offset
305 
307  t,
308  resrange[0],
309  resrange[1])
310 
312  t,
313  resrange[0],
314  terminus="N")
316  t,
317  resrange[1],
318  terminus="C")
319  # Done with the PDB
320  IMP.atom.destroy(t)
321 
322  # construct pdb fragments and intervening beads
323  for n, g in enumerate(gaps):
324  first = g[0]
325  last = g[1]
326  if g[2] == "cont":
327  print("autobuild_model: constructing fragment %s from pdb" % (str((first, last))))
328  outhiers += self.add_component_pdb(name, pdbname,
329  chain, resolutions=resolutions,
330  color=color, cacenters=True,
331  resrange=(first, last),
332  offset=offset, isnucleicacid=isnucleicacid)
333  elif g[2] == "gap" and n > 0:
334  print("autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
335  parts = self.hier_db.get_particles_at_closest_resolution(name,
336  first + offset - 1,
337  1)
338  xyz = IMP.core.XYZ(parts[0]).get_coordinates()
339  outhiers += self.add_component_necklace(name,
340  first+offset, last+offset, missingbeadsize, incoord=xyz)
341 
342  elif g[2] == "gap" and n == 0:
343  # add pre-beads
344  print("autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
345  outhiers += self.add_component_necklace(name,
346  first+offset, last+offset, missingbeadsize, incoord=xyznter)
347 
348  return outhiers
349 
350  # Deprecation warning
351 
352  @IMP.deprecated_method("2.5", "Use autobuild_model() instead.")
353  def autobuild_pdb_and_intervening_beads(self, *args, **kwargs):
354  r = self.autobuild_model(*args, **kwargs)
355  return r
356 
357  def add_component_pdb(self, name, pdbname, chain, resolutions, color=None,
358  resrange=None, offset=0, cacenters=True, show=False,
359  isnucleicacid=False, readnonwateratoms=False,
360  read_ca_cb_only=False):
361  '''
362  Add a component that has an associated 3D structure in a PDB file.
363 
364  Reads the PDB, and constructs the fragments corresponding to contiguous
365  sequence stretches.
366 
367  @return a list of hierarchies.
368 
369  @param name (string) the name of the component
370  @param pdbname (string) the name of the PDB file
371  @param chain (string or integer) can be either a string (eg, "A")
372  or an integer (eg, 0 or 1) in case you want
373  to get the corresponding chain number in the PDB.
374  @param resolutions (integers) a list of integers that corresponds
375  to the resolutions that have to be generated
376  @param color (float from 0 to 1) the color applied to the
377  hierarchies generated
378  @param resrange (tuple of integers): the residue range to extract
379  from the PDB. It is a tuple (beg,end). If not specified,
380  all residues belonging to the specified chain are read.
381  @param offset (integer) specifies the residue index offset to be
382  applied when reading the PDB (the FASTA sequence is
383  assumed to start from residue 1, so use this parameter
384  if the PDB file does not start at residue 1)
385  @param cacenters (boolean) if True generates resolution=1 beads
386  centered on C-alpha atoms.
387  @param show (boolean) print out the molecular hierarchy at the end.
388  @param isnucleicacid (boolean) use True if you're reading a PDB
389  with nucleic acids.
390  @param readnonwateratoms (boolean) if True fixes some pathological PDB.
391  @param read_ca_cb_only (boolean) if True, only reads CA/CB
392  '''
393 
394  self.representation_is_modified = True
395  if color is None:
396  # if the color is not passed, then get the stored color
397  color = self.color_dict[name]
398  protein_h = self.hier_dict[name]
399  outhiers = []
400 
401  # determine selector
403  if read_ca_cb_only:
404  cacbsel = IMP.atom.OrPDBSelector(
407  sel = IMP.atom.AndPDBSelector(cacbsel, sel)
408  if type(chain) == str:
411  sel)
412  t = IMP.atom.read_pdb(pdbname, self.m, sel)
413 
414  # get the first and last residue
415  start = IMP.atom.Residue(
416  t.get_children()[0].get_children()[0]).get_index()
417  end = IMP.atom.Residue(
418  t.get_children()[0].get_children()[-1]).get_index()
419  c = IMP.atom.Chain(IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[0])
420  else:
421  t = IMP.atom.read_pdb(pdbname, self.m, sel)
422  c = IMP.atom.Chain(
423  IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[chain])
424 
425  # get the first and last residue
426  start = IMP.atom.Residue(c.get_children()[0]).get_index()
427  end = IMP.atom.Residue(c.get_children()[-1]).get_index()
428  chain = c.get_id()
429 
430  if not resrange is None:
431  if resrange[0] > start:
432  start = resrange[0]
433  if resrange[1] < end:
434  end = resrange[1]
435 
436  if not isnucleicacid:
437  # do what you have to do for proteins
438  sel = IMP.atom.Selection(
439  c,
440  residue_indexes=list(range(
441  start,
442  end + 1)),
443  atom_type=IMP.atom.AT_CA)
444 
445  else:
446  # do what you have to do for nucleic-acids
447  # to work, nucleic acids should not be indicated as HETATM in the pdb
448  sel = IMP.atom.Selection(
449  c,
450  residue_indexes=list(range(
451  start,
452  end + 1)),
453  atom_type=IMP.atom.AT_P)
454 
455  ps = sel.get_selected_particles()
456  if len(ps) == 0:
457  raise ValueError("%s no residue found in pdb %s chain %s that overlaps with the queried stretch %s-%s" \
458  % (name, pdbname, str(chain), str(resrange[0]), str(resrange[1])))
460 
461  for p in ps:
462  par = IMP.atom.Atom(p).get_parent()
463  ri = IMP.atom.Residue(par).get_index()
464  # Move residue from original PDB hierarchy to new chain c0
465  IMP.atom.Residue(par).set_index(ri + offset)
466  if par.get_parent() != c0:
467  par.get_parent().remove_child(par)
468  c0.add_child(par)
469  start = start + offset
470  end = end + offset
471 
472  self.elements[name].append(
473  (start, end, pdbname.split("/")[-1] + ":" + chain, "pdb"))
474 
475  hiers = self.coarse_hierarchy(name, start, end,
476  resolutions, isnucleicacid, c0, protein_h, "pdb", color)
477  outhiers += hiers
478  for p in self._protocol_output:
479  p.add_pdb_element(name, start, end, offset, pdbname, chain,
480  hiers[0])
481 
482  if show:
484 
485  # We cannot simply destroy(c0) since it might not be a well-behaved
486  # hierarchy; in some cases it could contain a given residue more than
487  # once (this is surely a bug but we need to keep this behavior for
488  # backwards compatibility).
489  residues = {}
490  for p in ps:
491  par = IMP.atom.Atom(p).get_parent()
492  residues[par] = None
493  for r in residues.keys():
494  IMP.atom.destroy(r)
495  self.m.remove_particle(c0)
496 
497  IMP.atom.destroy(t)
498 
499  return outhiers
500 
501  def add_component_ideal_helix(
502  self,
503  name,
504  resolutions,
505  resrange,
506  color=None,
507  show=False):
508 
509  self.representation_is_modified = True
510  from math import pi, cos, sin
511 
512  protein_h = self.hier_dict[name]
513  outhiers = []
514  if color is None:
515  color = self.color_dict[name]
516 
517  start = resrange[0]
518  end = resrange[1]
519  self.elements[name].append((start, end, " ", "helix"))
521  for n, res in enumerate(range(start, end + 1)):
522  if name in self.sequence_dict:
523  try:
524  rtstr = self.onetothree[
525  self.sequence_dict[name][res-1]]
526  except:
527  rtstr = "UNK"
528  rt = IMP.atom.ResidueType(rtstr)
529  else:
530  rt = IMP.atom.ResidueType("ALA")
531 
532  # get the residue volume
533  try:
535  # mass=IMP.atom.get_mass_from_residue_type(rt)
536  except IMP.ValueException:
538  IMP.atom.ResidueType("ALA"))
539  # mass=IMP.atom.get_mass_from_residue_type(IMP.atom.ResidueType("ALA"))
541 
542  r = IMP.atom.Residue.setup_particle(IMP.Particle(self.m), rt, res)
543  p = IMP.Particle(self.m)
545  x = 2.3 * cos(n * 2 * pi / 3.6)
546  y = 2.3 * sin(n * 2 * pi / 3.6)
547  z = 6.2 / 3.6 / 2 * n * 2 * pi / 3.6
548  d.set_coordinates(IMP.algebra.Vector3D(x, y, z))
549  d.set_radius(radius)
550  # print d
551  a = IMP.atom.Atom.setup_particle(p, IMP.atom.AT_CA)
552  r.add_child(a)
553  c0.add_child(r)
554 
555  outhiers += self.coarse_hierarchy(name, start, end,
556  resolutions, False, c0, protein_h, "helix", color)
557 
558  if show:
560 
561  IMP.atom.destroy(c0)
562  return outhiers
563 
564  def add_component_beads(self, name, ds, colors=None, incoord=None):
565  """ add beads to the representation
566  @param name the component name
567  @param ds a list of tuples corresponding to the residue ranges
568  of the beads
569  @param colors a list of colors associated to the beads
570  @param incoord the coordinate tuple corresponding to the position
571  of the beads
572  """
573 
574  from math import pi
575  self.representation_is_modified = True
576 
577  protein_h = self.hier_dict[name]
578  outhiers = []
579  if colors is None:
580  colors = [self.color_dict[name]]
581 
582 
583  for n, dss in enumerate(ds):
584  ds_frag = (dss[0], dss[1])
585  self.elements[name].append((dss[0], dss[1], " ", "bead"))
586  prt = IMP.Particle(self.m)
587  if ds_frag[0] == ds_frag[1]:
588  # if the bead represent a single residue
589  if name in self.sequence_dict:
590  try:
591  rtstr = self.onetothree[
592  self.sequence_dict[name][ds_frag[0]-1]]
593  except:
594  rtstr = "UNK"
595  rt = IMP.atom.ResidueType(rtstr)
596  else:
597  rt = IMP.atom.ResidueType("ALA")
598  h = IMP.atom.Residue.setup_particle(prt, rt, ds_frag[0])
599  h.set_name(name + '_%i_bead' % (ds_frag[0]))
600  prt.set_name(name + '_%i_bead' % (ds_frag[0]))
601  resolution = 1
602  else:
604  h.set_name(name + '_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
605  prt.set_name(name + '_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
606  h.set_residue_indexes(list(range(ds_frag[0], ds_frag[1] + 1)))
607  resolution = len(h.get_residue_indexes())
608  if "Beads" not in self.hier_representation[name]:
610  root.set_name("Beads")
611  self.hier_representation[name]["Beads"] = root
612  protein_h.add_child(root)
613  self.hier_representation[name]["Beads"].add_child(h)
614 
615  for kk in range(ds_frag[0], ds_frag[1] + 1):
616  self.hier_db.add_particles(name, kk, resolution, [h])
617 
618  try:
619  clr = IMP.display.get_rgb_color(colors[n])
620  except:
621  clr = IMP.display.get_rgb_color(colors[0])
622 
624 
625  # decorate particles according to their resolution
626  IMP.pmi.Resolution.setup_particle(prt, resolution)
627 
629  ptem = IMP.core.XYZR(prt)
631  if resolution == 1:
632  try:
634  except IMP.ValueException:
636  IMP.atom.ResidueType("ALA"))
639  ptem.set_radius(radius)
640  else:
641  volume = IMP.atom.get_volume_from_mass(mass)
642  radius = 0.8 * (3.0 / 4.0 / pi * volume) ** (1.0 / 3.0)
644  ptem.set_radius(radius)
645  try:
646  if not tuple(incoord) is None:
647  ptem.set_coordinates(incoord)
648  except TypeError:
649  pass
652  self.floppy_bodies.append(prt)
653  IMP.core.XYZ(prt).set_coordinates_are_optimized(True)
654  outhiers += [h]
655 
656  for p in self._protocol_output:
657  p.add_bead_element(name, ds[0][0], ds[-1][1], len(ds), outhiers[0])
658 
659  return outhiers
660 
661  def add_component_necklace(self, name, begin, end, length, color=None,
662  incoord=None):
663  '''
664  Generates a string of beads with given length.
665  '''
666  self.representation_is_modified = True
667  outhiers = []
668  if color is None:
669  colors=None
670  else:
671  colors=[color]
672  for chunk in IMP.pmi.tools.list_chunks_iterator(range(begin, end + 1), length):
673  outhiers += self.add_component_beads(name,
674  [(chunk[0], chunk[-1])], colors=colors,incoord=incoord)
675  return outhiers
676 
678  self, name, hierarchies=None, selection_tuples=None,
679  particles=None,
680  resolution=0.0, num_components=10,
681  inputfile=None, outputfile=None,
682  outputmap=None,
683  kernel_type=None,
684  covariance_type='full', voxel_size=1.0,
685  out_hier_name='',
686  sampled_points=1000000, num_iter=100,
687  simulation_res=1.0,
688  multiply_by_total_mass=True,
689  transform=None,
690  intermediate_map_fn=None,
691  density_ps_to_copy=None,
692  use_precomputed_gaussians=False):
693  '''
694  Sets up a Gaussian Mixture Model for this component.
695  Can specify input GMM file or it will be computed.
696  @param name component name
697  @param hierarchies set up GMM for some hierarchies
698  @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
699  @param particles set up GMM for particles directly
700  @param resolution usual PMI resolution for selecting particles from the hierarchies
701  @param inputfile read the GMM from this file
702  @param outputfile fit and write the GMM to this file (text)
703  @param outputmap after fitting, create GMM density file (mrc)
704  @param kernel_type for creating the intermediate density (points are sampled to make GMM). Options are IMP.em.GAUSSIAN, IMP.em.SPHERE, and IMP.em.BINARIZED_SPHERE
705  @param covariance_type for fitting the GMM. options are 'full', 'diagonal' and 'spherical'
706  @param voxel_size for creating the intermediate density map and output map.
707  lower number increases accuracy but also rasterizing time grows
708  @param out_hier_name name of the output density hierarchy
709  @param sampled_points number of points to sample. more will increase accuracy and fitting time
710  @param num_iter num GMM iterations. more will increase accuracy and fitting time
711  @param multiply_by_total_mass multiply the weights of the GMM by this value (only works on creation!)
712  @param transform for input file only, apply a transformation (eg for multiple copies same GMM)
713  @param intermediate_map_fn for debugging, this will write the intermediate (simulated) map
714  @param density_ps_to_copy in case you already created the appropriate GMM (eg, for beads)
715  @param use_precomputed_gaussians Set this flag and pass fragments - will use roughly spherical Gaussian setup
716  '''
717  import numpy as np
718  import sys
719  import IMP.em
720  import IMP.isd.gmm_tools
721 
722  # prepare output
723  self.representation_is_modified = True
724  out_hier = []
725  protein_h = self.hier_dict[name]
726  if "Densities" not in self.hier_representation[name]:
728  root.set_name("Densities")
729  self.hier_representation[name]["Densities"] = root
730  protein_h.add_child(root)
731 
732  # gather passed particles
733  fragment_particles = []
734  if not particles is None:
735  fragment_particles += particles
736  if not hierarchies is None:
737  fragment_particles += IMP.pmi.tools.select(
738  self, resolution=resolution,
739  hierarchies=hierarchies)
740  if not selection_tuples is None:
741  for st in selection_tuples:
742  fragment_particles += IMP.pmi.tools.select_by_tuple(
743  self, tupleselection=st,
744  resolution=resolution,
745  name_is_ambiguous=False)
746 
747  # compute or read gaussians
748  density_particles = []
749  if inputfile:
751  inputfile, density_particles,
752  self.m, transform)
753  elif density_ps_to_copy:
754  for ip in density_ps_to_copy:
755  p = IMP.Particle(self.m)
756  shape = IMP.core.Gaussian(ip).get_gaussian()
757  mass = IMP.atom.Mass(ip).get_mass()
760  density_particles.append(p)
761  elif use_precomputed_gaussians:
762  if len(fragment_particles) == 0:
763  print("add_component_density: no particle was selected")
764  return out_hier
765  for p in fragment_particles:
766  if not (IMP.atom.Fragment.get_is_setup(self.m,p.get_particle_index()) and
767  IMP.core.XYZ.get_is_setup(self.m,p.get_particle_index())):
768  raise Exception("The particles you selected must be Fragments and XYZs")
769  nres=len(IMP.atom.Fragment(self.m,p.get_particle_index()).get_residue_indexes())
770  pos=IMP.core.XYZ(self.m,p.get_particle_index()).get_coordinates()
771  density_particles=[]
772  try:
773  IMP.isd.get_data_path("beads/bead_%i.txt"%nres)
774  except:
775  raise Exception("We haven't created a bead file for",nres,"residues")
776  transform = IMP.algebra.Transformation3D(pos)
778  IMP.isd.get_data_path("beads/bead_%i.txt"%nres), density_particles,
779  self.m, transform)
780  else:
781  #compute the gaussians here
782  if len(fragment_particles) == 0:
783  print("add_component_density: no particle was selected")
784  return out_hier
785 
786  density_particles = IMP.isd.gmm_tools.sample_and_fit_to_particles(
787  self.m,
788  fragment_particles,
789  num_components,
790  sampled_points,
791  simulation_res,
792  voxel_size,
793  num_iter,
794  covariance_type,
795  multiply_by_total_mass,
796  outputmap,
797  outputfile)
798 
799  # prepare output hierarchy
801  s0.set_name(out_hier_name)
802  self.hier_representation[name]["Densities"].add_child(s0)
803  out_hier.append(s0)
804  for nps, p in enumerate(density_particles):
805  s0.add_child(p)
806  p.set_name(s0.get_name() + '_gaussian_%i' % nps)
807  return out_hier
808 
809  def get_component_density(self, name):
810  return self.hier_representation[name]["Densities"]
811 
812  def add_all_atom_densities(self, name, hierarchies=None,
813  selection_tuples=None,
814  particles=None,
815  resolution=0,
816  output_map=None,
817  voxel_size=1.0):
818  '''Decorates all specified particles as Gaussians directly.
819  @param name component name
820  @param hierarchies set up GMM for some hierarchies
821  @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
822  @param particles set up GMM for particles directly
823  @param resolution usual PMI resolution for selecting particles from the hierarchies
824  '''
825 
826  import IMP.em
827  import numpy as np
828  import sys
829  from math import sqrt
830  self.representation_is_modified = True
831 
832  if particles is None:
833  fragment_particles = []
834  else:
835  fragment_particles = particles
836 
837  if not hierarchies is None:
838  fragment_particles += IMP.pmi.tools.select(
839  self, resolution=resolution,
840  hierarchies=hierarchies)
841 
842  if not selection_tuples is None:
843  for st in selection_tuples:
844  fragment_particles += IMP.pmi.tools.select_by_tuple(
845  self, tupleselection=st,
846  resolution=resolution,
847  name_is_ambiguous=False)
848 
849  if len(fragment_particles) == 0:
850  print("add all atom densities: no particle was selected")
851  return
852 
853  # create a spherical gaussian for each particle based on atom type
854  print('setting up all atom gaussians num_particles',len(fragment_particles))
855  for n,p in enumerate(fragment_particles):
856  if IMP.core.Gaussian.get_is_setup(p): continue
857  center=IMP.core.XYZ(p).get_coordinates()
858  rad=IMP.core.XYZR(p).get_radius()
859  mass=IMP.atom.Mass(p).get_mass()
863  print('setting up particle',p.get_name(), " as individual gaussian particle")
864 
865  if not output_map is None:
866  print('writing map to', output_map)
868  fragment_particles,
869  output_map,
870  voxel_size)
871 
872  def add_component_hierarchy_clone(self, name, hierarchy):
873  '''
874  Make a copy of a hierarchy and append it to a component.
875  '''
876  outhier = []
877  self.representation_is_modified = True
878  protein_h = self.hier_dict[name]
879  hierclone = IMP.atom.create_clone(hierarchy)
880  hierclone.set_name(hierclone.get_name() + "_clone")
881  protein_h.add_child(hierclone)
882  outhier.append(hierclone)
883 
884  psmain = IMP.atom.get_leaves(hierarchy)
885  psclone = IMP.atom.get_leaves(hierclone)
886 
887  # copying attributes
888  for n, pmain in enumerate(psmain):
889  pclone = psclone[n]
891  resolution = IMP.pmi.Resolution(pmain).get_resolution()
892  IMP.pmi.Resolution.setup_particle(pclone, resolution)
893  for kk in IMP.pmi.tools.get_residue_indexes(pclone):
894  self.hier_db.add_particles(
895  name,
896  kk,
898  [pclone])
899 
901  uncertainty = IMP.pmi.Uncertainty(pmain).get_uncertainty()
902  IMP.pmi.Uncertainty.setup_particle(pclone, uncertainty)
903 
905  symmetric = IMP.pmi.Symmetric(pmain).get_symmetric()
906  IMP.pmi.Symmetric.setup_particle(pclone, symmetric)
907 
908  return outhier
909 
910  def dump_particle_descriptors(self):
911  import numpy
912  import pickle
913  import IMP.isd
914  import IMP.isd.gmm_tools
915 
916  particles_attributes={}
917  floppy_body_attributes={}
918  gaussians=[]
919  for h in IMP.atom.get_leaves(self.prot):
920  leaf=h
921  name=h.get_name()
922  hroot=self.prot
923  hparent=h.get_parent()
924  while hparent != hroot:
925  hparent=h.get_parent()
926  name+="|"+hparent.get_name()
927  h=hparent
928  particles_attributes[name]={"COORDINATES":numpy.array(IMP.core.XYZR(leaf.get_particle()).get_coordinates()),
929  "RADIUS":IMP.core.XYZR(leaf.get_particle()).get_radius(),
930  "MASS":IMP.atom.Mass(leaf.get_particle()).get_mass()}
931  if IMP.core.Gaussian.get_is_setup(leaf.get_particle()):
932  gaussians.append(IMP.core.Gaussian(leaf.get_particle()))
933 
934  rigid_body_attributes={}
935  for rb in self.rigid_bodies:
936  name=rb.get_name()
937  rf=rb.get_reference_frame()
938  t=rf.get_transformation_to()
939  trans=t.get_translation()
940  rot=t.get_rotation()
941  rigid_body_attributes[name]={"TRANSLATION":numpy.array(trans),
942  "ROTATION":numpy.array(rot.get_quaternion()),
943  "COORDINATES_NONRIGID_MEMBER":{},
944  "COORDINATES_RIGID_MEMBER":{}}
945  for mi in rb.get_member_indexes():
946  rm=self.m.get_particle(mi)
948  name_part=rm.get_name()
949  xyz=[self.m.get_attribute(fk, rm) for fk in [IMP.FloatKey(4), IMP.FloatKey(5), IMP.FloatKey(6)]]
950  rigid_body_attributes[name]["COORDINATES_NONRIGID_MEMBER"][name_part]=numpy.array(xyz)
951  else:
952  name_part=rm.get_name()
953  xyz=IMP.core.XYZ(rm).get_coordinates()
954  rigid_body_attributes[name]["COORDINATES_RIGID_MEMBER"][name_part]=numpy.array(xyz)
955 
956 
957  IMP.isd.gmm_tools.write_gmm_to_text(gaussians,"model_gmm.txt")
958  pickle.dump(particles_attributes,
959  open("particles_attributes.pkl", "wb"))
960  pickle.dump(rigid_body_attributes,
961  open("rigid_body_attributes.pkl", "wb"))
962 
963 
964 
965  def load_particle_descriptors(self):
966  import numpy
967  import pickle
968  import IMP.isd
969  import IMP.isd.gmm_tools
970 
971  particles_attributes = pickle.load(open("particles_attributes.pkl",
972  "rb"))
973  rigid_body_attributes = pickle.load(open("rigid_body_attributes.pkl",
974  "rb"))
975 
976  particles=[]
977  hierarchies=[]
978  gaussians=[]
979  for h in IMP.atom.get_leaves(self.prot):
980  leaf=h
981  name=h.get_name()
982  hroot=self.prot
983  hparent=h.get_parent()
984  while hparent != hroot:
985  hparent=h.get_parent()
986  name+="|"+hparent.get_name()
987  h=hparent
988 
989  xyzr=IMP.core.XYZR(leaf.get_particle())
990  xyzr.set_coordinates(particles_attributes[name]["COORDINATES"])
991  #xyzr.set_radius(particles_attributes[name]["RADIUS"])
992  #IMP.atom.Mass(leaf.get_particle()).set_mass(particles_attributes[name]["MASS"])
993  if IMP.core.Gaussian.get_is_setup(leaf.get_particle()):
994  gaussians.append(IMP.core.Gaussian(leaf.get_particle()))
995 
996  for rb in self.rigid_bodies:
997  name=rb.get_name()
998  trans=rigid_body_attributes[name]["TRANSLATION"]
999  rot=rigid_body_attributes[name]["ROTATION"]
1002  rb.set_reference_frame(rf)
1003  coor_nrm_ref=rigid_body_attributes[name]["COORDINATES_NONRIGID_MEMBER"]
1004  coor_rm_ref_dict=rigid_body_attributes[name]["COORDINATES_RIGID_MEMBER"]
1005  coor_rm_model=[]
1006  coor_rm_ref=[]
1007  for mi in rb.get_member_indexes():
1008  rm=self.m.get_particle(mi)
1010  name_part=rm.get_name()
1011  xyz=coor_nrm_ref[name_part]
1012  for n,fk in enumerate([IMP.FloatKey(4), IMP.FloatKey(5), IMP.FloatKey(6)]):
1013  self.m.set_attribute(fk, rm,xyz[n])
1014  else:
1015  name_part=rm.get_name()
1016  coor_rm_ref.append(IMP.algebra.Vector3D(coor_rm_ref_dict[name_part]))
1017  coor_rm_model.append(IMP.core.XYZ(rm).get_coordinates())
1018  if len(coor_rm_model)==0: continue
1019  t=IMP.algebra.get_transformation_aligning_first_to_second(coor_rm_model,coor_rm_ref)
1020  IMP.core.transform(rb,t)
1021 
1022  IMP.isd.gmm_tools.decorate_gmm_from_text("model_gmm.txt",gaussians,self.m)
1023 
1024  def _compare_rmf_repr_names(self, rmfname, reprname, component_name):
1025  """Print a warning if particle names in RMF and model don't match"""
1026  def match_any_suffix():
1027  # Handle common mismatches like 743 != Nup85_743_pdb
1028  suffixes = ["pdb", "bead_floppy_body_rigid_body_member_floppy_body",
1029  "bead_floppy_body_rigid_body_member",
1030  "bead_floppy_body"]
1031  for s in suffixes:
1032  if "%s_%s_%s" % (component_name, rmfname, s) == reprname:
1033  return True
1034  if rmfname != reprname and not match_any_suffix():
1035  print("set_coordinates_from_rmf: WARNING rmf particle and "
1036  "representation particle names don't match %s %s"
1037  % (rmfname, reprname))
1038 
1039  def set_coordinates_from_rmf(self, component_name, rmf_file_name,
1040  rmf_frame_number,
1041  rmf_component_name=None,
1042  check_number_particles=True,
1043  representation_name_to_rmf_name_map=None,
1044  state_number=0,
1045  skip_gaussian_in_rmf=False,
1046  skip_gaussian_in_representation=False,
1047  save_file=False,
1048  force_rigid_update=False):
1049  '''Read and replace coordinates from an RMF file.
1050  Replace the coordinates of particles with the same name.
1051  It assumes that the RMF and the representation have the particles
1052  in the same order.
1053  @param component_name Component name
1054  @param rmf_component_name Name of the component in the RMF file
1055  (if not specified, use `component_name`)
1056  @param representation_name_to_rmf_name_map a dictionary that map
1057  the original rmf particle name to the recipient particle component name
1058  @param save_file: save a file with the names of particles of the component
1059  @param force_rigid_update: update the coordinates of rigid bodies
1060  (normally this should be called before rigid bodies are set up)
1061  '''
1062  import IMP.pmi.analysis
1063 
1064  prots = IMP.pmi.analysis.get_hiers_from_rmf(
1065  self.m,
1066  rmf_frame_number,
1067  rmf_file_name)
1068 
1069  if not prots:
1070  raise ValueError("cannot read hierarchy from rmf")
1071 
1072  prot=prots[0]
1073  # Make sure coordinates of rigid body members in the RMF are correct
1074  if force_rigid_update:
1075  self.m.update()
1076 
1077  # if len(self.rigid_bodies)!=0:
1078  # print "set_coordinates_from_rmf: cannot proceed if rigid bodies were initialized. Use the function before defining the rigid bodies"
1079  # exit()
1080 
1081  allpsrmf = IMP.atom.get_leaves(prot)
1082  psrmf = []
1083  for p in allpsrmf:
1084  (protname, is_a_bead) = IMP.pmi.tools.get_prot_name_from_particle(
1085  p, self.hier_dict.keys())
1086  if (protname is None) and (rmf_component_name is not None):
1087  (protname, is_a_bead) = IMP.pmi.tools.get_prot_name_from_particle(
1088  p, rmf_component_name)
1089  if (skip_gaussian_in_rmf):
1091  continue
1092  if (rmf_component_name is not None) and (protname == rmf_component_name):
1093  psrmf.append(p)
1094  elif (rmf_component_name is None) and (protname == component_name):
1095  psrmf.append(p)
1096 
1097  psrepr = IMP.atom.get_leaves(self.hier_dict[component_name])
1098  if (skip_gaussian_in_representation):
1099  allpsrepr = psrepr
1100  psrepr = []
1101  for p in allpsrepr:
1102  #(protname, is_a_bead) = IMP.pmi.tools.get_prot_name_from_particle(
1103  # p, self.hier_dict.keys())
1105  continue
1106  psrepr.append(p)
1107 
1108  import itertools
1109  reprnames=[p.get_name() for p in psrepr]
1110  rmfnames=[p.get_name() for p in psrmf]
1111 
1112  if save_file:
1113  fl=open(component_name+".txt","w")
1114  for i in itertools.izip_longest(reprnames,rmfnames): fl.write(str(i[0])+","+str(i[1])+"\n")
1115 
1116 
1117  if check_number_particles and not representation_name_to_rmf_name_map:
1118  if len(psrmf) != len(psrepr):
1119  fl=open(component_name+".txt","w")
1120  for i in itertools.izip_longest(reprnames,rmfnames): fl.write(str(i[0])+","+str(i[1])+"\n")
1121  raise ValueError("%s cannot proceed the rmf and the representation don't have the same number of particles; "
1122  "particles in rmf: %s particles in the representation: %s" % (str(component_name), str(len(psrmf)), str(len(psrepr))))
1123 
1124 
1125  if not representation_name_to_rmf_name_map:
1126  for n, prmf in enumerate(psrmf):
1127 
1128  prmfname = prmf.get_name()
1129  preprname = psrepr[n].get_name()
1130  if force_rigid_update:
1131  if IMP.core.RigidBody.get_is_setup(psrepr[n]) \
1132  and not IMP.core.RigidBodyMember.get_is_setup(psrepr[n]):
1133  continue
1134  else:
1136  raise ValueError("component %s cannot proceed if rigid bodies were initialized. Use the function before defining the rigid bodies" % component_name)
1137 
1138  self._compare_rmf_repr_names(prmfname, preprname,
1139  component_name)
1140  if IMP.core.XYZ.get_is_setup(prmf) and IMP.core.XYZ.get_is_setup(psrepr[n]):
1141  xyz = IMP.core.XYZ(prmf).get_coordinates()
1142  IMP.core.XYZ(psrepr[n]).set_coordinates(xyz)
1144  # Set rigid body so that coordinates are preserved
1145  # on future model updates
1146  rbm = IMP.core.RigidBodyMember(psrepr[n])
1147  rbm.set_internal_coordinates(xyz)
1149  rb = rbm.get_rigid_body()
1151  raise ValueError("Cannot handle nested "
1152  "rigid bodies yet")
1153  rb.set_reference_frame_lazy(tr)
1154  else:
1155  print("set_coordinates_from_rmf: WARNING particles are not XYZ decorated %s %s " % (str(IMP.core.XYZ.get_is_setup(prmf)), str(IMP.core.XYZ.get_is_setup(psrepr[n]))))
1156 
1158  gprmf=IMP.core.Gaussian(prmf)
1159  grepr=IMP.core.Gaussian(psrepr[n])
1160  g=gprmf.get_gaussian()
1161  grepr.set_gaussian(g)
1162 
1163  else:
1164  repr_name_particle_map={}
1165  rmf_name_particle_map={}
1166  for p in psrmf:
1167  rmf_name_particle_map[p.get_name()]=p
1168  #for p in psrepr:
1169  # repr_name_particle_map[p.get_name()]=p
1170 
1171  for prepr in psrepr:
1172  try:
1173  prmf=rmf_name_particle_map[representation_name_to_rmf_name_map[prepr.get_name()]]
1174  except KeyError:
1175  print("set_coordinates_from_rmf: WARNING missing particle name in representation_name_to_rmf_name_map, skipping...")
1176  continue
1177  xyz = IMP.core.XYZ(prmf).get_coordinates()
1178  IMP.core.XYZ(prepr).set_coordinates(xyz)
1179 
1180 
1181  def check_root(self, name, protein_h, resolution):
1182  '''
1183  If the root hierarchy does not exist, construct it.
1184  '''
1185  if "Res:" + str(int(resolution)) not in self.hier_representation[name]:
1187  root.set_name(name + "_Res:" + str(int(resolution)))
1188  self.hier_representation[name][
1189  "Res:" + str(int(resolution))] = root
1190  protein_h.add_child(root)
1191 
1192  def coarse_hierarchy(self, name, start, end, resolutions, isnucleicacid,
1193  input_hierarchy, protein_h, type, color):
1194  '''
1195  Generate all needed coarse grained layers.
1196 
1197  @param name name of the protein
1198  @param resolutions list of resolutions
1199  @param protein_h root hierarchy
1200  @param input_hierarchy hierarchy to coarse grain
1201  @param type a string, typically "pdb" or "helix"
1202  '''
1203  outhiers = []
1204 
1205  if (1 in resolutions) or (0 in resolutions):
1206  # in that case create residues and append atoms
1207 
1208  if 1 in resolutions:
1209  self.check_root(name, protein_h, 1)
1211  s1.set_name('%s_%i-%i_%s' % (name, start, end, type))
1212  # s1.set_residue_indexes(range(start,end+1))
1213  self.hier_representation[name]["Res:1"].add_child(s1)
1214  outhiers += [s1]
1215  if 0 in resolutions:
1216  self.check_root(name, protein_h, 0)
1218  s0.set_name('%s_%i-%i_%s' % (name, start, end, type))
1219  # s0.set_residue_indexes(range(start,end+1))
1220  self.hier_representation[name]["Res:0"].add_child(s0)
1221  outhiers += [s0]
1222 
1223  if not isnucleicacid:
1224  sel = IMP.atom.Selection(
1225  input_hierarchy,
1226  atom_type=IMP.atom.AT_CA)
1227  else:
1228  sel = IMP.atom.Selection(
1229  input_hierarchy,
1230  atom_type=IMP.atom.AT_P)
1231 
1232  for p in sel.get_selected_particles():
1233  resobject = IMP.atom.Residue(IMP.atom.Atom(p).get_parent())
1234  if 0 in resolutions:
1235  # if you ask for atoms
1236  resclone0 = IMP.atom.create_clone(resobject)
1237  resindex = IMP.atom.Residue(resclone0).get_index()
1238  s0.add_child(resclone0)
1239  self.hier_db.add_particles(
1240  name,
1241  resindex,
1242  0,
1243  resclone0.get_children())
1244 
1245  chil = resclone0.get_children()
1246  for ch in chil:
1248  try:
1249  clr = IMP.display.get_rgb_color(color)
1250  except:
1251  clr = IMP.display.get_rgb_color(1.0)
1253 
1254  if 1 in resolutions:
1255  # else clone the residue
1256  resclone1 = IMP.atom.create_clone_one(resobject)
1257  resindex = IMP.atom.Residue(resclone1).get_index()
1258  s1.add_child(resclone1)
1259  self.hier_db.add_particles(name, resindex, 1, [resclone1])
1260 
1261  rt = IMP.atom.Residue(resclone1).get_residue_type()
1262  xyz = IMP.core.XYZ(p).get_coordinates()
1263  prt = resclone1.get_particle()
1264  prt.set_name('%s_%i_%s' % (name, resindex, type))
1265  IMP.core.XYZ.setup_particle(prt).set_coordinates(xyz)
1266 
1267  try:
1269  # mass=IMP.atom.get_mass_from_residue_type(rt)
1270  except IMP.ValueException:
1272  IMP.atom.ResidueType("ALA"))
1273  # mass=IMP.atom.get_mass_from_residue_type(IMP.atom.ResidueType("ALA"))
1275  IMP.core.XYZR.setup_particle(prt).set_radius(radius)
1280  try:
1281  clr = IMP.display.get_rgb_color(color)
1282  except:
1283  clr = IMP.display.get_rgb_color(1.0)
1285 
1286  for r in resolutions:
1287  if r != 0 and r != 1:
1288  self.check_root(name, protein_h, r)
1290  input_hierarchy,
1291  r)
1292 
1293  chil = s.get_children()
1295  s0.set_name('%s_%i-%i_%s' % (name, start, end, type))
1296  # Move all children from s to s0
1297  for ch in chil:
1298  s.remove_child(ch)
1299  s0.add_child(ch)
1300  self.hier_representation[name][
1301  "Res:" + str(int(r))].add_child(s0)
1302  outhiers += [s0]
1303  IMP.atom.destroy(s)
1304 
1305  for prt in IMP.atom.get_leaves(s0):
1306  ri = IMP.atom.Fragment(prt).get_residue_indexes()
1307  first = ri[0]
1308  last = ri[-1]
1309  if first == last:
1310  prt.set_name('%s_%i_%s' % (name, first, type))
1311  else:
1312  prt.set_name('%s_%i_%i_%s' % (name, first, last, type))
1313  for kk in ri:
1314  self.hier_db.add_particles(name, kk, r, [prt])
1315 
1316  radius = IMP.core.XYZR(prt).get_radius()
1320 
1321  # setting up color for each particle in the
1322  # hierarchy, if colors missing in the colors list set it to
1323  # red
1324  try:
1325  clr = IMP.display.get_rgb_color(color)
1326  except:
1327  colors.append(1.0)
1328  clr = IMP.display.get_rgb_color(colors[pdb_part_count])
1330 
1331  return outhiers
1332 
1334  '''
1335  Get the hierarchies at the given resolution.
1336 
1337  The map between resolution and hierarchies is cached to accelerate
1338  the selection algorithm. The cache is invalidated when the
1339  representation was changed by any add_component_xxx.
1340  '''
1341 
1342  if self.representation_is_modified:
1343  rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1344  resolution)
1345  self.hier_resolution[resolution] = rhbr
1346  self.representation_is_modified = False
1347  return rhbr
1348  else:
1349  if resolution in self.hier_resolution:
1350  return self.hier_resolution[resolution]
1351  else:
1352  rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1353  resolution)
1354  self.hier_resolution[resolution] = rhbr
1355  return rhbr
1356 
1358  self, max_translation=300., max_rotation=2.0 * pi,
1359  avoidcollision=True, cutoff=10.0, niterations=100,
1360  bounding_box=None,
1361  excluded_rigid_bodies=None,
1362  ignore_initial_coordinates=False,
1363  hierarchies_excluded_from_collision=None):
1364  '''
1365  Shuffle configuration; used to restart the optimization.
1366 
1367  The configuration of the system is initialized by placing each
1368  rigid body and each bead randomly in a box with a side of
1369  `max_translation` angstroms, and far enough from each other to
1370  prevent any steric clashes. The rigid bodies are also randomly rotated.
1371 
1372  @param avoidcollision check if the particle/rigid body was
1373  placed close to another particle; uses the optional
1374  arguments cutoff and niterations
1375  @param bounding_box defined by ((x1,y1,z1),(x2,y2,z2))
1376  '''
1377 
1378  if excluded_rigid_bodies is None:
1379  excluded_rigid_bodies = []
1380  if hierarchies_excluded_from_collision is None:
1381  hierarchies_excluded_from_collision = []
1382 
1383  if len(self.rigid_bodies) == 0:
1384  print("shuffle_configuration: rigid bodies were not intialized")
1385 
1387  gcpf.set_distance(cutoff)
1388  ps = []
1389  hierarchies_excluded_from_collision_indexes = []
1390  for p in IMP.atom.get_leaves(self.prot):
1392  ps.append(p)
1394  # remove the densities particles out of the calculation
1395  hierarchies_excluded_from_collision_indexes += IMP.get_indexes([p])
1396  allparticleindexes = IMP.get_indexes(ps)
1397 
1398  if bounding_box is not None:
1399  ((x1, y1, z1), (x2, y2, z2)) = bounding_box
1400  lb = IMP.algebra.Vector3D(x1, y1, z1)
1401  ub = IMP.algebra.Vector3D(x2, y2, z2)
1402  bb = IMP.algebra.BoundingBox3D(lb, ub)
1403 
1404  for h in hierarchies_excluded_from_collision:
1405  hierarchies_excluded_from_collision_indexes += IMP.get_indexes(IMP.atom.get_leaves(h))
1406 
1407 
1408  allparticleindexes = list(
1409  set(allparticleindexes) - set(hierarchies_excluded_from_collision_indexes))
1410 
1411  print(hierarchies_excluded_from_collision)
1412  print(len(allparticleindexes),len(hierarchies_excluded_from_collision_indexes))
1413 
1414  print('shuffling', len(self.rigid_bodies) - len(excluded_rigid_bodies), 'rigid bodies')
1415  for rb in self.rigid_bodies:
1416  if rb not in excluded_rigid_bodies:
1417  if avoidcollision:
1418  rbindexes = rb.get_member_particle_indexes()
1419  rbindexes = list(
1420  set(rbindexes) - set(hierarchies_excluded_from_collision_indexes))
1421  otherparticleindexes = list(
1422  set(allparticleindexes) - set(rbindexes))
1423 
1424  if len(otherparticleindexes) is None:
1425  continue
1426 
1427  niter = 0
1428  while niter < niterations:
1429  if (ignore_initial_coordinates):
1430  # Move the particle to the origin
1431  transformation = IMP.algebra.Transformation3D(IMP.algebra.get_identity_rotation_3d(), -IMP.core.XYZ(rb).get_coordinates())
1432  IMP.core.transform(rb, transformation)
1433  rbxyz = IMP.core.XYZ(rb).get_coordinates()
1434 
1435  if bounding_box is not None:
1436  # overrides the perturbation
1437  translation = IMP.algebra.get_random_vector_in(bb)
1439  transformation = IMP.algebra.Transformation3D(rotation, translation-rbxyz)
1440  else:
1442  rbxyz,
1443  max_translation,
1444  max_rotation)
1445 
1446  IMP.core.transform(rb, transformation)
1447 
1448  if avoidcollision:
1449  self.m.update()
1450  npairs = len(
1451  gcpf.get_close_pairs(
1452  self.m,
1453  otherparticleindexes,
1454  rbindexes))
1455  if npairs == 0:
1456  niter = niterations
1457  if (ignore_initial_coordinates):
1458  print (rb.get_name(), IMP.core.XYZ(rb).get_coordinates())
1459  else:
1460  niter += 1
1461  print("shuffle_configuration: rigid body placed close to other %d particles, trying again..." % npairs)
1462  print("shuffle_configuration: rigid body name: " + rb.get_name())
1463  if niter == niterations:
1464  raise ValueError("tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1465  else:
1466  break
1467 
1468  print('shuffling', len(self.floppy_bodies), 'floppy bodies')
1469  for fb in self.floppy_bodies:
1470  if (avoidcollision):
1473  if rm and nrm:
1474  fbindexes = IMP.get_indexes([fb])
1475  otherparticleindexes = list(
1476  set(allparticleindexes) - set(fbindexes))
1477  if len(otherparticleindexes) is None:
1478  continue
1479  else:
1480  continue
1481  else:
1484  if (rm or nrm):
1485  continue
1486 
1488  d=IMP.core.RigidBodyMember(fb).get_rigid_body()
1490  d=IMP.core.RigidBody(fb)
1491  elif IMP.core.XYZ.get_is_setup(fb):
1492  d=IMP.core.XYZ(fb)
1493 
1494  niter = 0
1495  while niter < niterations:
1496  if (ignore_initial_coordinates):
1497  # Move the particle to the origin
1498  transformation = IMP.algebra.Transformation3D(IMP.algebra.get_identity_rotation_3d(), -IMP.core.XYZ(fb).get_coordinates())
1499  IMP.core.transform(d, transformation)
1500  fbxyz = IMP.core.XYZ(fb).get_coordinates()
1501 
1502  if bounding_box is not None:
1503  # overrides the perturbation
1504  translation = IMP.algebra.get_random_vector_in(bb)
1505  transformation = IMP.algebra.Transformation3D(translation-fbxyz)
1506  else:
1508  fbxyz,
1509  max_translation,
1510  max_rotation)
1511 
1512  IMP.core.transform(d, transformation)
1513 
1514  if (avoidcollision):
1515  self.m.update()
1516  npairs = len(
1517  gcpf.get_close_pairs(
1518  self.m,
1519  otherparticleindexes,
1520  fbindexes))
1521  if npairs == 0:
1522  niter = niterations
1523  if (ignore_initial_coordinates):
1524  print (fb.get_name(), IMP.core.XYZ(fb).get_coordinates())
1525  else:
1526  niter += 1
1527  print("shuffle_configuration: floppy body placed close to other %d particles, trying again..." % npairs)
1528  print("shuffle_configuration: floppy body name: " + fb.get_name())
1529  if niter == niterations:
1530  raise ValueError("tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1531  else:
1532  break
1533 
1534  def set_current_coordinates_as_reference_for_rmsd(self, label="None"):
1535  # getting only coordinates from pdb
1536  ps = IMP.pmi.tools.select(self, resolution=1.0)
1537  # storing the reference coordinates and the particles
1538  self.reference_structures[label] = (
1539  [IMP.core.XYZ(p).get_coordinates() for p in ps],
1540  ps)
1541 
1542  def get_all_rmsds(self):
1543  rmsds = {}
1544 
1545  for label in self.reference_structures:
1546 
1547  current_coordinates = [IMP.core.XYZ(p).get_coordinates()
1548  for p in self.reference_structures[label][1]]
1549  reference_coordinates = self.reference_structures[label][0]
1550  if len(reference_coordinates) != len(current_coordinates):
1551  print("calculate_all_rmsds: reference and actual coordinates are not the same")
1552  continue
1554  current_coordinates,
1555  reference_coordinates)
1556  rmsd_global = IMP.algebra.get_rmsd(
1557  reference_coordinates,
1558  current_coordinates)
1559  # warning: temporary we are calculating the drms, and not the rmsd,
1560  # for the relative distance
1561  rmsd_relative = IMP.atom.get_drms(
1562  reference_coordinates,
1563  current_coordinates)
1564  rmsds[label + "_GlobalRMSD"] = rmsd_global
1565  rmsds[label + "_RelativeDRMS"] = rmsd_relative
1566  return rmsds
1567 
1568  def setup_component_geometry(self, name, color=None, resolution=1.0):
1569  if color is None:
1570  color = self.color_dict[name]
1571  # this function stores all particle pairs
1572  # ordered by residue number, to be used
1573  # to construct backbone traces
1574  self.hier_geometry_pairs[name] = []
1575  protein_h = self.hier_dict[name]
1576  pbr = IMP.pmi.tools.select(self, name=name, resolution=resolution)
1577  pbr = IMP.pmi.tools.sort_by_residues(pbr)
1578 
1579  for n in range(len(pbr) - 1):
1580  self.hier_geometry_pairs[name].append((pbr[n], pbr[n + 1], color))
1581 
1583  self, name, resolution=10, scale=1.0):
1584  '''
1585  Generate restraints between contiguous fragments in the hierarchy.
1586  The linkers are generated at resolution 10 by default.
1587 
1588  '''
1589 
1590  unmodeledregions_cr = IMP.RestraintSet(self.m, "unmodeledregions")
1591  sortedsegments_cr = IMP.RestraintSet(self.m, "sortedsegments")
1592 
1593  protein_h = self.hier_dict[name]
1594  SortedSegments = []
1595  frs = self.hier_db.get_preroot_fragments_by_resolution(
1596  name,
1597  resolution)
1598 
1599  for fr in frs:
1600  try:
1601  start = fr.get_children()[0]
1602  except:
1603  start = fr
1604 
1605  try:
1606  end = fr.get_children()[-1]
1607  except:
1608  end = fr
1609 
1610  startres = IMP.pmi.tools.get_residue_indexes(start)[0]
1611  endres = IMP.pmi.tools.get_residue_indexes(end)[-1]
1612  SortedSegments.append((start, end, startres))
1613  SortedSegments = sorted(SortedSegments, key=itemgetter(2))
1614 
1615  # connect the particles
1616  for x in range(len(SortedSegments) - 1):
1617  last = SortedSegments[x][1]
1618  first = SortedSegments[x + 1][0]
1619 
1620  nreslast = len(IMP.pmi.tools.get_residue_indexes(last))
1621  lastresn = IMP.pmi.tools.get_residue_indexes(last)[-1]
1622  nresfirst = len(IMP.pmi.tools.get_residue_indexes(first))
1623  firstresn = IMP.pmi.tools.get_residue_indexes(first)[0]
1624 
1625  residuegap = firstresn - lastresn - 1
1626  if self.disorderedlength and (nreslast / 2 + nresfirst / 2 + residuegap) > 20.0:
1627  # calculate the distance between the sphere centers using Kohn
1628  # PNAS 2004
1629  optdist = sqrt(5 / 3) * 1.93 * \
1630  (nreslast / 2 + nresfirst / 2 + residuegap) ** 0.6
1631  # optdist2=sqrt(5/3)*1.93*((nreslast)**0.6+(nresfirst)**0.6)/2
1632  if self.upperharmonic:
1633  hu = IMP.core.HarmonicUpperBound(optdist, self.kappa)
1634  else:
1635  hu = IMP.core.Harmonic(optdist, self.kappa)
1636  dps = IMP.core.DistancePairScore(hu)
1637  else: # default
1638  optdist = (0.0 + (float(residuegap) + 1.0) * 3.6) * scale
1639  if self.upperharmonic: # default
1640  hu = IMP.core.HarmonicUpperBound(optdist, self.kappa)
1641  else:
1642  hu = IMP.core.Harmonic(optdist, self.kappa)
1644 
1645  pt0 = last.get_particle()
1646  pt1 = first.get_particle()
1647  r = IMP.core.PairRestraint(self.m, dps, (pt0.get_index(), pt1.get_index()))
1648 
1649  print("Adding sequence connectivity restraint between", pt0.get_name(), " and ", pt1.get_name(), 'of distance', optdist)
1650  sortedsegments_cr.add_restraint(r)
1651  self.linker_restraints_dict[
1652  "LinkerRestraint-" + pt0.get_name() + "-" + pt1.get_name()] = r
1653  self.connected_intra_pairs.append((pt0, pt1))
1654  self.connected_intra_pairs.append((pt1, pt0))
1655 
1656  self.linker_restraints.add_restraint(sortedsegments_cr)
1657  self.linker_restraints.add_restraint(unmodeledregions_cr)
1658  IMP.pmi.tools.add_restraint_to_model(self.m, self.linker_restraints)
1659  self.sortedsegments_cr_dict[name] = sortedsegments_cr
1660  self.unmodeledregions_cr_dict[name] = unmodeledregions_cr
1661 
1662  def optimize_floppy_bodies(self, nsteps, temperature=1.0):
1663  import IMP.pmi.samplers
1664  pts = IMP.pmi.tools.ParticleToSampleList()
1665  for n, fb in enumerate(self.floppy_bodies):
1666  pts.add_particle(fb, "Floppy_Bodies", 1.0, "Floppy_Body_" + str(n))
1667  if len(pts.get_particles_to_sample()) > 0:
1668  mc = IMP.pmi.samplers.MonteCarlo(self.m, [pts], temperature)
1669  print("optimize_floppy_bodies: optimizing %i floppy bodies" % len(self.floppy_bodies))
1670  mc.optimize(nsteps)
1671  else:
1672  print("optimize_floppy_bodies: no particle to optimize")
1673 
1674  def create_rotational_symmetry(self, maincopy, copies, rotational_axis=IMP.algebra.Vector3D(0, 0, 1.0),
1675  nSymmetry=None, skip_gaussian_in_clones=False):
1676  '''
1677  The copies must not contain rigid bodies.
1678  The symmetry restraints are applied at each leaf.
1679  '''
1680 
1681  from math import pi
1682  self.representation_is_modified = True
1683  ncopies = len(copies) + 1
1684  main_hiers = IMP.atom.get_leaves(self.hier_dict[maincopy])
1685 
1686  for k in range(len(copies)):
1687  if (nSymmetry is None):
1688  rotation_angle = 2.0 * pi / float(ncopies) * float(k + 1)
1689  else:
1690  if ( k % 2 == 0 ):
1691  rotation_angle = 2.0 * pi / float(nSymmetry) * float((k + 2) / 2)
1692  else:
1693  rotation_angle = -2.0 * pi / float(nSymmetry) * float((k + 1) / 2)
1694 
1695  rotation3D = IMP.algebra.get_rotation_about_axis(rotational_axis, rotation_angle)
1696 
1697  sm = IMP.core.TransformationSymmetry(rotation3D)
1698  clone_hiers = IMP.atom.get_leaves(self.hier_dict[copies[k]])
1699 
1701  for n, p in enumerate(main_hiers):
1702  if (skip_gaussian_in_clones):
1704  continue
1705  pc = clone_hiers[n]
1706  #print("setting " + p.get_name() + " as reference for " + pc.get_name())
1707  IMP.core.Reference.setup_particle(pc.get_particle(), p.get_particle())
1708  lc.add(pc.get_particle().get_index())
1709 
1710  c = IMP.container.SingletonsConstraint(sm, None, lc)
1711  self.m.add_score_state(c)
1712  print("Completed setting " + str(maincopy) + " as a reference for " + str(copies[k]) \
1713  + " by rotating it in " + str(rotation_angle / 2.0 / pi * 360) + " degree around the " + str(rotational_axis) + " axis.")
1714  self.m.update()
1715 
1716  def create_rigid_body_symmetry(self, particles_reference, particles_copy,label="None",
1717  initial_transformation=IMP.algebra.get_identity_transformation_3d()):
1718  from math import pi
1719  self.representation_is_modified = True
1720 
1721  mainparticles = particles_reference
1722 
1723  t=initial_transformation
1724  p=IMP.Particle(self.m)
1725  p.set_name("RigidBody_Symmetry")
1727 
1729 
1730 
1731  copyparticles = particles_copy
1732 
1733  mainpurged = []
1734  copypurged = []
1735  for n, p in enumerate(mainparticles):
1736  print(p.get_name())
1737  pc = copyparticles[n]
1738 
1739  mainpurged.append(p)
1742  else:
1743  IMP.pmi.Symmetric(p).set_symmetric(0)
1744 
1745  copypurged.append(pc)
1746  if not IMP.pmi.Symmetric.get_is_setup(pc):
1748  else:
1749  IMP.pmi.Symmetric(pc).set_symmetric(1)
1750 
1752  for n, p in enumerate(mainpurged):
1753 
1754  pc = copypurged[n]
1755  print("setting " + p.get_name() + " as reference for " + pc.get_name())
1756 
1758  lc.add(pc.get_index())
1759 
1760  c = IMP.container.SingletonsConstraint(sm, None, lc)
1761  self.m.add_score_state(c)
1762 
1763  self.m.update()
1764  self.rigid_bodies.append(rb)
1765  self.rigid_body_symmetries.append(rb)
1766  rb.set_name(label+".rigid_body_symmetry."+str(len(self.rigid_body_symmetries)))
1767 
1768 
1769  def create_amyloid_fibril_symmetry(self, maincopy, axial_copies,
1770  longitudinal_copies, axis=(0, 0, 1), translation_value=4.8):
1771 
1772  from math import pi
1773  self.representation_is_modified = True
1774 
1775  outhiers = []
1776  protein_h = self.hier_dict[maincopy]
1777  mainparts = IMP.atom.get_leaves(protein_h)
1778 
1779  for ilc in range(-longitudinal_copies, longitudinal_copies + 1):
1780  for iac in range(axial_copies):
1781  copyname = maincopy + "_a" + str(ilc) + "_l" + str(iac)
1782  self.create_component(copyname, 0.0)
1783  for hier in protein_h.get_children():
1784  self.add_component_hierarchy_clone(copyname, hier)
1785  copyhier = self.hier_dict[copyname]
1786  outhiers.append(copyhier)
1787  copyparts = IMP.atom.get_leaves(copyhier)
1789  IMP.algebra.Vector3D(axis),
1790  2 * pi / axial_copies * (float(iac)))
1791  translation_vector = tuple(
1792  [translation_value * float(ilc) * x for x in axis])
1793  print(translation_vector)
1794  translation = IMP.algebra.Vector3D(translation_vector)
1796  IMP.algebra.Transformation3D(rotation3D, translation))
1798  for n, p in enumerate(mainparts):
1799  pc = copyparts[n]
1802  if not IMP.pmi.Symmetric.get_is_setup(pc):
1805  lc.add(pc.get_index())
1806  c = IMP.container.SingletonsConstraint(sm, None, lc)
1807  self.m.add_score_state(c)
1808  self.m.update()
1809  return outhiers
1810 
1811  def link_components_to_rmf(self, rmfname, frameindex):
1812  '''
1813  Load coordinates in the current representation.
1814  This should be done only if the hierarchy self.prot is identical
1815  to the one as stored in the rmf i.e. all components were added.
1816  '''
1817  import IMP.rmf
1818  import RMF
1819 
1820  rh = RMF.open_rmf_file_read_only(rmfname)
1821  IMP.rmf.link_hierarchies(rh, [self.prot])
1822  IMP.rmf.load_frame(rh, RMF.FrameID(frameindex))
1823  del rh
1824 
1825  def create_components_from_rmf(self, rmfname, frameindex):
1826  '''
1827  still not working.
1828  create the representation (i.e. hierarchies) from the rmf file.
1829  it will be stored in self.prot, which will be overwritten.
1830  load the coordinates from the rmf file at frameindex.
1831  '''
1832  rh = RMF.open_rmf_file_read_only(rmfname)
1833  self.prot = IMP.rmf.create_hierarchies(rh, self.m)[0]
1835  IMP.rmf.link_hierarchies(rh, [self.prot])
1836  IMP.rmf.load_frame(rh, RMF.FrameID(frameindex))
1837  del rh
1838  for p in self.prot.get_children():
1839  self.create_component(p.get_name())
1840  self.hier_dict[p.get_name()] = p
1841  '''
1842  still missing: save rigid bodies contained in the rmf in self.rigid_bodies
1843  save floppy bodies in self.floppy_bodies
1844  get the connectivity restraints
1845  '''
1846 
1847  def set_rigid_body_from_hierarchies(self, hiers, particles=None):
1848  '''
1849  Construct a rigid body from hierarchies (and optionally particles).
1850 
1851  @param hiers list of hierarchies to make rigid
1852  @param particles list of particles to add to the rigid body
1853  '''
1854 
1855  if particles is None:
1856  rigid_parts = set()
1857  else:
1858  rigid_parts = set(particles)
1859 
1860  name = ""
1861  print("set_rigid_body_from_hierarchies> setting up a new rigid body")
1862  for hier in hiers:
1863  ps = IMP.atom.get_leaves(hier)
1864 
1865  for p in ps:
1867  rb = IMP.core.RigidMember(p).get_rigid_body()
1868  print("set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1869  else:
1870  rigid_parts.add(p)
1871  name += hier.get_name() + "-"
1872  print("set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
1873 
1874  if len(list(rigid_parts)) != 0:
1875  rb = IMP.atom.create_rigid_body(list(rigid_parts))
1876  rb.set_coordinates_are_optimized(True)
1877  rb.set_name(name + "rigid_body")
1878  self.rigid_bodies.append(rb)
1879  return rb
1880 
1881  else:
1882  print("set_rigid_body_from_hierarchies> rigid body could not be setup")
1883 
1884  def set_rigid_bodies(self, subunits):
1885  '''
1886  Construct a rigid body from a list of subunits.
1887 
1888  Each subunit is a tuple that identifies the residue ranges and the
1889  component name (as used in create_component()).
1890 
1891  subunits: [(name_1,(first_residue_1,last_residue_1)),(name_2,(first_residue_2,last_residue_2)),.....]
1892  or
1893  [name_1,name_2,(name_3,(first_residue_3,last_residue_3)),.....]
1894 
1895  example: ["prot1","prot2",("prot3",(1,10))]
1896 
1897  sometimes, we know about structure of an interaction
1898  and here we make such PPIs rigid
1899  '''
1900 
1901  rigid_parts = set()
1902  for s in subunits:
1903  if type(s) == type(tuple()) and len(s) == 2:
1904  sel = IMP.atom.Selection(
1905  self.prot,
1906  molecule=s[0],
1907  residue_indexes=list(range(s[1][0],
1908  s[1][1] + 1)))
1909  if len(sel.get_selected_particles()) == 0:
1910  print("set_rigid_bodies: selected particle does not exist")
1911  for p in sel.get_selected_particles():
1912  # if not p in self.floppy_bodies:
1914  rb = IMP.core.RigidMember(p).get_rigid_body()
1915  print("set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1916  else:
1917  rigid_parts.add(p)
1918 
1919  elif type(s) == type(str()):
1920  sel = IMP.atom.Selection(self.prot, molecule=s)
1921  if len(sel.get_selected_particles()) == 0:
1922  print("set_rigid_bodies: selected particle does not exist")
1923  for p in sel.get_selected_particles():
1924  # if not p in self.floppy_bodies:
1926  rb = IMP.core.RigidMember(p).get_rigid_body()
1927  print("set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1928  else:
1929  rigid_parts.add(p)
1930 
1931  rb = IMP.atom.create_rigid_body(list(rigid_parts))
1932  rb.set_coordinates_are_optimized(True)
1933  rb.set_name(''.join(str(subunits)) + "_rigid_body")
1934  self.rigid_bodies.append(rb)
1935  return rb
1936 
1937  def set_super_rigid_body_from_hierarchies(
1938  self,
1939  hiers,
1940  axis=None,
1941  min_size=1):
1942  # axis is the rotation axis for 2D rotation
1943  super_rigid_xyzs = set()
1944  super_rigid_rbs = set()
1945  name = ""
1946  print("set_super_rigid_body_from_hierarchies> setting up a new SUPER rigid body")
1947 
1948  for hier in hiers:
1949  ps = IMP.atom.get_leaves(hier)
1950  for p in ps:
1952  rb = IMP.core.RigidMember(p).get_rigid_body()
1953  super_rigid_rbs.add(rb)
1954  else:
1955  super_rigid_xyzs.add(p)
1956  print("set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
1957  if len(super_rigid_rbs|super_rigid_xyzs) < min_size:
1958  return
1959  if axis is None:
1960  self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
1961  else:
1962  # these will be 2D rotation SRB or a bond rotamer (axis can be a IMP.algebra.Vector3D or particle Pair)
1963  self.super_rigid_bodies.append(
1964  (super_rigid_xyzs, super_rigid_rbs, axis))
1965 
1966  def fix_rigid_bodies(self, rigid_bodies):
1967  self.fixed_rigid_bodies += rigid_bodies
1968 
1969 
1971  self, hiers, min_length=None, max_length=None, axis=None):
1972  '''
1973  Make a chain of super rigid bodies from a list of hierarchies.
1974 
1975  Takes a linear list of hierarchies (they are supposed to be
1976  sequence-contiguous) and produces a chain of super rigid bodies
1977  with given length range, specified by min_length and max_length.
1978  '''
1979  try:
1980  hiers = IMP.pmi.tools.flatten_list(hiers)
1981  except:
1982  pass
1983  for hs in IMP.pmi.tools.sublist_iterator(hiers, min_length, max_length):
1984  self.set_super_rigid_body_from_hierarchies(hs, axis, min_length)
1985 
1986  def set_super_rigid_bodies(self, subunits, coords=None):
1987  super_rigid_xyzs = set()
1988  super_rigid_rbs = set()
1989 
1990  for s in subunits:
1991  if type(s) == type(tuple()) and len(s) == 3:
1992  sel = IMP.atom.Selection(
1993  self.prot,
1994  molecule=s[2],
1995  residue_indexes=list(range(s[0],
1996  s[1] + 1)))
1997  if len(sel.get_selected_particles()) == 0:
1998  print("set_rigid_bodies: selected particle does not exist")
1999  for p in sel.get_selected_particles():
2001  rb = IMP.core.RigidMember(p).get_rigid_body()
2002  super_rigid_rbs.add(rb)
2003  else:
2004  super_rigid_xyzs.add(p)
2005  elif type(s) == type(str()):
2006  sel = IMP.atom.Selection(self.prot, molecule=s)
2007  if len(sel.get_selected_particles()) == 0:
2008  print("set_rigid_bodies: selected particle does not exist")
2009  for p in sel.get_selected_particles():
2010  # if not p in self.floppy_bodies:
2012  rb = IMP.core.RigidMember(p).get_rigid_body()
2013  super_rigid_rbs.add(rb)
2014  else:
2015  super_rigid_xyzs.add(p)
2016  self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
2017 
2018  def remove_floppy_bodies_from_component(self, component_name):
2019  '''
2020  Remove leaves of hierarchies from the floppy bodies list based
2021  on the component name
2022  '''
2023  hs=IMP.atom.get_leaves(self.hier_dict[component_name])
2024  ps=[h.get_particle() for h in hs]
2025  for p in self.floppy_bodies:
2026  try:
2027  if p in ps: self.floppy_bodies.remove(p)
2028  if p in hs: self.floppy_bodies.remove(p)
2029  except:
2030  continue
2031 
2032 
2033  def remove_floppy_bodies(self, hierarchies):
2034  '''
2035  Remove leaves of hierarchies from the floppy bodies list.
2036 
2037  Given a list of hierarchies, get the leaves and remove the
2038  corresponding particles from the floppy bodies list. We need this
2039  function because sometimes
2040  we want to constrain the floppy bodies in a rigid body - for instance
2041  when you want to associate a bead with a density particle.
2042  '''
2043  for h in hierarchies:
2044  ps = IMP.atom.get_leaves(h)
2045  for p in ps:
2046  if p in self.floppy_bodies:
2047  print("remove_floppy_bodies: removing %s from floppy body list" % p.get_name())
2048  self.floppy_bodies.remove(p)
2049 
2050 
2051  def set_floppy_bodies(self):
2052  for p in self.floppy_bodies:
2053  name = p.get_name()
2054  p.set_name(name + "_floppy_body")
2056  print("I'm trying to make this particle flexible although it was assigned to a rigid body", p.get_name())
2057  rb = IMP.core.RigidMember(p).get_rigid_body()
2058  try:
2059  rb.set_is_rigid_member(p.get_index(), False)
2060  except:
2061  # some IMP versions still work with that
2062  rb.set_is_rigid_member(p.get_particle_index(), False)
2063  p.set_name(p.get_name() + "_rigid_body_member")
2064 
2065  def set_floppy_bodies_from_hierarchies(self, hiers):
2066  for hier in hiers:
2067  ps = IMP.atom.get_leaves(hier)
2068  for p in ps:
2069  IMP.core.XYZ(p).set_coordinates_are_optimized(True)
2070  self.floppy_bodies.append(p)
2071 
2073  self,
2074  selection_tuples,
2075  resolution=None):
2076  '''
2077  selection tuples must be [(r1,r2,"name1"),(r1,r2,"name2"),....]
2078  @return the particles
2079  '''
2080  particles = []
2081  print(selection_tuples)
2082  for s in selection_tuples:
2083  ps = IMP.pmi.tools.select_by_tuple(
2084  representation=self, tupleselection=tuple(s),
2085  resolution=None, name_is_ambiguous=False)
2086  particles += ps
2087  return particles
2088 
2089  def get_connected_intra_pairs(self):
2090  return self.connected_intra_pairs
2091 
2092  def set_rigid_bodies_max_trans(self, maxtrans):
2093  self.maxtrans_rb = maxtrans
2094 
2095  def set_rigid_bodies_max_rot(self, maxrot):
2096  self.maxrot_rb = maxrot
2097 
2098  def set_super_rigid_bodies_max_trans(self, maxtrans):
2099  self.maxtrans_srb = maxtrans
2100 
2101  def set_super_rigid_bodies_max_rot(self, maxrot):
2102  self.maxrot_srb = maxrot
2103 
2104  def set_floppy_bodies_max_trans(self, maxtrans):
2105  self.maxtrans_fb = maxtrans
2106 
2107  def set_rigid_bodies_as_fixed(self, rigidbodiesarefixed=True):
2108  '''
2109  Fix rigid bodies in their actual position.
2110  The get_particles_to_sample() function will return
2111  just the floppy bodies (if they are not fixed).
2112  '''
2113  self.rigidbodiesarefixed = rigidbodiesarefixed
2114 
2115  def set_floppy_bodies_as_fixed(self, floppybodiesarefixed=True):
2116  '''
2117  Fix floppy bodies in their actual position.
2118  The get_particles_to_sample() function will return
2119  just the rigid bodies (if they are not fixed).
2120  '''
2121  self.floppybodiesarefixed=floppybodiesarefixed
2122 
2123  def draw_hierarchy_graph(self):
2124  for c in IMP.atom.Hierarchy(self.prot).get_children():
2125  print("Drawing hierarchy graph for " + c.get_name())
2126  IMP.pmi.output.get_graph_from_hierarchy(c)
2127 
2128  def get_geometries(self):
2129  # create segments at the lowest resolution
2130  seggeos = []
2131  for name in self.hier_geometry_pairs:
2132  for pt in self.hier_geometry_pairs[name]:
2133  p1 = pt[0]
2134  p2 = pt[1]
2135  color = pt[2]
2136  try:
2137  clr = IMP.display.get_rgb_color(color)
2138  except:
2139  clr = IMP.display.get_rgb_color(1.0)
2140  coor1 = IMP.core.XYZ(p1).get_coordinates()
2141  coor2 = IMP.core.XYZ(p2).get_coordinates()
2142  seg = IMP.algebra.Segment3D(coor1, coor2)
2143  seggeos.append(IMP.display.SegmentGeometry(seg, clr))
2144  return seggeos
2145 
2146  def setup_bonds(self):
2147  # create segments at the lowest resolution
2148  seggeos = []
2149  for name in self.hier_geometry_pairs:
2150  for pt in self.hier_geometry_pairs[name]:
2151 
2152  p1 = pt[0]
2153  p2 = pt[1]
2154  if not IMP.atom.Bonded.get_is_setup(p1):
2156  if not IMP.atom.Bonded.get_is_setup(p2):
2158 
2161  IMP.atom.Bonded(p1),
2162  IMP.atom.Bonded(p2),
2163  1)
2164 
2165  def show_component_table(self, name):
2166  if name in self.sequence_dict:
2167  lastresn = len(self.sequence_dict[name])
2168  firstresn = 1
2169  else:
2170  residues = self.hier_db.get_residue_numbers(name)
2171  firstresn = min(residues)
2172  lastresn = max(residues)
2173 
2174  for nres in range(firstresn, lastresn + 1):
2175  try:
2176  resolutions = self.hier_db.get_residue_resolutions(name, nres)
2177  ps = []
2178  for r in resolutions:
2179  ps += self.hier_db.get_particles(name, nres, r)
2180  print("%20s %7s" % (name, nres), " ".join(["%20s %7s" % (str(p.get_name()),
2181  str(IMP.pmi.Resolution(p).get_resolution())) for p in ps]))
2182  except:
2183  print("%20s %20s" % (name, nres), "**** not represented ****")
2184 
2185  def draw_hierarchy_composition(self):
2186 
2187  ks = list(self.elements.keys())
2188  ks.sort()
2189 
2190  max = 0
2191  for k in self.elements:
2192  for l in self.elements[k]:
2193  if l[1] > max:
2194  max = l[1]
2195 
2196  for k in ks:
2197  self.draw_component_composition(k, max)
2198 
2199  def draw_component_composition(self, name, max=1000, draw_pdb_names=False):
2200  from matplotlib import pyplot
2201  import matplotlib as mpl
2202  k = name
2203  tmplist = sorted(self.elements[k], key=itemgetter(0))
2204  try:
2205  endres = tmplist[-1][1]
2206  except:
2207  print("draw_component_composition: missing information for component %s" % name)
2208  return
2209  fig = pyplot.figure(figsize=(26.0 * float(endres) / max + 2, 2))
2210  ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
2211 
2212  # Set the colormap and norm to correspond to the data for which
2213  # the colorbar will be used.
2214  cmap = mpl.cm.cool
2215  norm = mpl.colors.Normalize(vmin=5, vmax=10)
2216  bounds = [1]
2217  colors = []
2218 
2219  for n, l in enumerate(tmplist):
2220  firstres = l[0]
2221  lastres = l[1]
2222  if l[3] != "end":
2223  if bounds[-1] != l[0]:
2224  colors.append("white")
2225  bounds.append(l[0])
2226  if l[3] == "pdb":
2227  colors.append("#99CCFF")
2228  if l[3] == "bead":
2229  colors.append("#FFFF99")
2230  if l[3] == "helix":
2231  colors.append("#33CCCC")
2232  if l[3] != "end":
2233  bounds.append(l[1] + 1)
2234  else:
2235  if l[3] == "pdb":
2236  colors.append("#99CCFF")
2237  if l[3] == "bead":
2238  colors.append("#FFFF99")
2239  if l[3] == "helix":
2240  colors.append("#33CCCC")
2241  if l[3] != "end":
2242  bounds.append(l[1] + 1)
2243  else:
2244  if bounds[-1] - 1 == l[0]:
2245  bounds.pop()
2246  bounds.append(l[0])
2247  else:
2248  colors.append("white")
2249  bounds.append(l[0])
2250 
2251  bounds.append(bounds[-1])
2252  colors.append("white")
2253  cmap = mpl.colors.ListedColormap(colors)
2254  cmap.set_over('0.25')
2255  cmap.set_under('0.75')
2256 
2257  norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
2258  cb2 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
2259  norm=norm,
2260  # to use 'extend', you must
2261  # specify two extra boundaries:
2262  boundaries=bounds,
2263  ticks=bounds, # optional
2264  spacing='proportional',
2265  orientation='horizontal')
2266 
2267  extra_artists = []
2268  npdb = 0
2269 
2270  if draw_pdb_names:
2271  for l in tmplist:
2272  if l[3] == "pdb":
2273  npdb += 1
2274  mid = 1.0 / endres * float(l[0])
2275  # t =ax.text(mid, float(npdb-1)/2.0+1.5, l[2], ha="left", va="center", rotation=0,
2276  # size=10)
2277  # t=ax.annotate(l[0],2)
2278  t = ax.annotate(
2279  l[2], xy=(mid, 1), xycoords='axes fraction',
2280  xytext=(mid + 0.025, float(npdb - 1) / 2.0 + 1.5), textcoords='axes fraction',
2281  arrowprops=dict(arrowstyle="->",
2282  connectionstyle="angle,angleA=0,angleB=90,rad=10"),
2283  )
2284  extra_artists.append(t)
2285 
2286  # set the title of the bar
2287  title = ax.text(-0.005, 0.5, k, ha="right", va="center", rotation=90,
2288  size=20)
2289 
2290  extra_artists.append(title)
2291  # changing the xticks labels
2292  labels = len(bounds) * [" "]
2293  ax.set_xticklabels(labels)
2294  mid = 1.0 / endres * float(bounds[0])
2295  t = ax.annotate(bounds[0], xy=(mid, 0), xycoords='axes fraction',
2296  xytext=(mid - 0.01, -0.5), textcoords='axes fraction',)
2297  extra_artists.append(t)
2298  offsets = [0, -0.5, -1.0]
2299  nclashes = 0
2300  for n in range(1, len(bounds)):
2301  if bounds[n] == bounds[n - 1]:
2302  continue
2303  mid = 1.0 / endres * float(bounds[n])
2304  if (float(bounds[n]) - float(bounds[n - 1])) / max <= 0.01:
2305  nclashes += 1
2306  offset = offsets[nclashes % 3]
2307  else:
2308  nclashes = 0
2309  offset = offsets[0]
2310  if offset > -0.75:
2311  t = ax.annotate(
2312  bounds[n], xy=(mid, 0), xycoords='axes fraction',
2313  xytext=(mid, -0.5 + offset), textcoords='axes fraction')
2314  else:
2315  t = ax.annotate(
2316  bounds[n], xy=(mid, 0), xycoords='axes fraction',
2317  xytext=(mid, -0.5 + offset), textcoords='axes fraction', arrowprops=dict(arrowstyle="-"))
2318  extra_artists.append(t)
2319 
2320  cb2.add_lines(bounds, ["black"] * len(bounds), [1] * len(bounds))
2321  # cb2.set_label(k)
2322 
2323  pyplot.savefig(
2324  k + "structure.pdf",
2325  dpi=150,
2326  transparent="True",
2327  bbox_extra_artists=(extra_artists),
2328  bbox_inches='tight')
2329  pyplot.show()
2330 
2331  def draw_coordinates_projection(self):
2332  import matplotlib.pyplot as pp
2333  xpairs = []
2334  ypairs = []
2335  for name in self.hier_geometry_pairs:
2336  for pt in self.hier_geometry_pairs[name]:
2337  p1 = pt[0]
2338  p2 = pt[1]
2339  color = pt[2]
2340  coor1 = IMP.core.XYZ(p1).get_coordinates()
2341  coor2 = IMP.core.XYZ(p2).get_coordinates()
2342  x1 = coor1[0]
2343  x2 = coor2[0]
2344  y1 = coor1[1]
2345  y2 = coor2[1]
2346  xpairs.append([x1, x2])
2347  ypairs.append([y1, y2])
2348  xlist = []
2349  ylist = []
2350  for xends, yends in zip(xpairs, ypairs):
2351  xlist.extend(xends)
2352  xlist.append(None)
2353  ylist.extend(yends)
2354  ylist.append(None)
2355  pp.plot(xlist, ylist, 'b-', alpha=0.1)
2356  pp.show()
2357 
2358  def get_prot_name_from_particle(self, particle):
2359  names = self.get_component_names()
2360  particle0 = particle
2361  name = None
2362  while not name in names:
2363  h = IMP.atom.Hierarchy(particle0).get_parent()
2364  name = h.get_name()
2365  particle0 = h.get_particle()
2366  return name
2367 
2368 
2369  def get_particles_to_sample(self):
2370  # get the list of samplable particles with their type
2371  # and the mover displacement. Everything wrapped in a dictionary,
2372  # to be used by samplers modules
2373  ps = {}
2374 
2375  # remove symmetric particles: they are not sampled
2376  rbtmp = []
2377  fbtmp = []
2378  srbtmp = []
2379  if not self.rigidbodiesarefixed:
2380  for rb in self.rigid_bodies:
2382  if IMP.pmi.Symmetric(rb).get_symmetric() != 1:
2383  rbtmp.append(rb)
2384  else:
2385  if rb not in self.fixed_rigid_bodies:
2386  rbtmp.append(rb)
2387 
2388  if not self.floppybodiesarefixed:
2389  for fb in self.floppy_bodies:
2391  if IMP.pmi.Symmetric(fb).get_symmetric() != 1:
2392  fbtmp.append(fb)
2393  else:
2394  fbtmp.append(fb)
2395 
2396  for srb in self.super_rigid_bodies:
2397  # going to prune the fixed rigid bodies out
2398  # of the super rigid body list
2399  rigid_bodies = list(srb[1])
2400  filtered_rigid_bodies = []
2401  for rb in rigid_bodies:
2402  if rb not in self.fixed_rigid_bodies:
2403  filtered_rigid_bodies.append(rb)
2404  srbtmp.append((srb[0], filtered_rigid_bodies))
2405 
2406  self.rigid_bodies = rbtmp
2407  self.floppy_bodies = fbtmp
2408  self.super_rigid_bodies = srbtmp
2409 
2410  ps["Rigid_Bodies_SimplifiedModel"] = (
2411  self.rigid_bodies,
2412  self.maxtrans_rb,
2413  self.maxrot_rb)
2414  ps["Floppy_Bodies_SimplifiedModel"] = (
2415  self.floppy_bodies,
2416  self.maxtrans_fb)
2417  ps["SR_Bodies_SimplifiedModel"] = (
2418  self.super_rigid_bodies,
2419  self.maxtrans_srb,
2420  self.maxrot_srb)
2421  return ps
2422 
2423  def set_output_level(self, level):
2424  self.output_level = level
2425 
2426  def _evaluate(self, deriv):
2427  """Evaluate the total score of all added restraints"""
2429  return r.evaluate(deriv)
2430 
2431  def get_output(self):
2432  output = {}
2433  score = 0.0
2434 
2435  output["SimplifiedModel_Total_Score_" +
2436  self.label] = str(self._evaluate(False))
2437  output["SimplifiedModel_Linker_Score_" +
2438  self.label] = str(self.linker_restraints.unprotected_evaluate(None))
2439  for name in self.sortedsegments_cr_dict:
2440  partialscore = self.sortedsegments_cr_dict[name].evaluate(False)
2441  score += partialscore
2442  output[
2443  "SimplifiedModel_Link_SortedSegments_" +
2444  name +
2445  "_" +
2446  self.label] = str(
2447  partialscore)
2448  partialscore = self.unmodeledregions_cr_dict[name].evaluate(False)
2449  score += partialscore
2450  output[
2451  "SimplifiedModel_Link_UnmodeledRegions_" +
2452  name +
2453  "_" +
2454  self.label] = str(
2455  partialscore)
2456  for rb in self.rigid_body_symmetries:
2457  name=rb.get_name()
2458  output[name +"_" +self.label]=str(rb.get_reference_frame().get_transformation_to())
2459  for name in self.linker_restraints_dict:
2460  output[
2461  name +
2462  "_" +
2463  self.label] = str(
2464  self.linker_restraints_dict[
2465  name].unprotected_evaluate(
2466  None))
2467 
2468  if len(self.reference_structures.keys()) != 0:
2469  rmsds = self.get_all_rmsds()
2470  for label in rmsds:
2471  output[
2472  "SimplifiedModel_" +
2473  label +
2474  "_" +
2475  self.label] = rmsds[
2476  label]
2477 
2478  if self.output_level == "high":
2479  for p in IMP.atom.get_leaves(self.prot):
2480  d = IMP.core.XYZR(p)
2481  output["Coordinates_" +
2482  p.get_name() + "_" + self.label] = str(d)
2483 
2484  output["_TotalScore"] = str(score)
2485  return output
2486 
2487  def get_test_output(self):
2488  # this method is called by test functions and return an enriched output
2489  output = self.get_output()
2490  for n, p in enumerate(self.get_particles_to_sample()):
2491  output["Particle_to_sample_" + str(n)] = str(p)
2492  output["Number_of_particles"] = len(IMP.atom.get_leaves(self.prot))
2493  output["Hierarchy_Dictionary"] = list(self.hier_dict.keys())
2494  output["Number_of_floppy_bodies"] = len(self.floppy_bodies)
2495  output["Number_of_rigid_bodies"] = len(self.rigid_bodies)
2496  output["Number_of_super_bodies"] = len(self.super_rigid_bodies)
2497  output["Selection_resolution_1"] = len(
2498  IMP.pmi.tools.select(self, resolution=1))
2499  output["Selection_resolution_5"] = len(
2500  IMP.pmi.tools.select(self, resolution=5))
2501  output["Selection_resolution_7"] = len(
2502  IMP.pmi.tools.select(self, resolution=5))
2503  output["Selection_resolution_10"] = len(
2504  IMP.pmi.tools.select(self, resolution=10))
2505  output["Selection_resolution_100"] = len(
2506  IMP.pmi.tools.select(self, resolution=100))
2507  output["Selection_All"] = len(IMP.pmi.tools.select(self))
2508  output["Selection_resolution=1"] = len(
2509  IMP.pmi.tools.select(self, resolution=1))
2510  output["Selection_resolution=1,resid=10"] = len(
2511  IMP.pmi.tools.select(self, resolution=1, residue=10))
2512  for resolution in self.hier_resolution:
2513  output["Hier_resolution_dictionary" +
2514  str(resolution)] = len(self.hier_resolution[resolution])
2515  for name in self.hier_dict:
2516  output[
2517  "Selection_resolution=1,resid=10,name=" +
2518  name] = len(
2520  self,
2521  resolution=1,
2522  name=name,
2523  residue=10))
2524  output[
2525  "Selection_resolution=1,resid=10,name=" +
2526  name +
2527  ",ambiguous"] = len(
2529  self,
2530  resolution=1,
2531  name=name,
2532  name_is_ambiguous=True,
2533  residue=10))
2534  output[
2535  "Selection_resolution=1,resid=10,name=" +
2536  name +
2537  ",ambiguous"] = len(
2539  self,
2540  resolution=1,
2541  name=name,
2542  name_is_ambiguous=True,
2543  residue=10))
2544  output[
2545  "Selection_resolution=1,resrange=(10,20),name=" +
2546  name] = len(
2548  self,
2549  resolution=1,
2550  name=name,
2551  first_residue=10,
2552  last_residue=20))
2553  output[
2554  "Selection_resolution=1,resrange=(10,20),name=" +
2555  name +
2556  ",ambiguous"] = len(
2558  self,
2559  resolution=1,
2560  name=name,
2561  name_is_ambiguous=True,
2562  first_residue=10,
2563  last_residue=20))
2564  output[
2565  "Selection_resolution=10,resrange=(10,20),name=" +
2566  name] = len(
2568  self,
2569  resolution=10,
2570  name=name,
2571  first_residue=10,
2572  last_residue=20))
2573  output[
2574  "Selection_resolution=10,resrange=(10,20),name=" +
2575  name +
2576  ",ambiguous"] = len(
2578  self,
2579  resolution=10,
2580  name=name,
2581  name_is_ambiguous=True,
2582  first_residue=10,
2583  last_residue=20))
2584  output[
2585  "Selection_resolution=100,resrange=(10,20),name=" +
2586  name] = len(
2588  self,
2589  resolution=100,
2590  name=name,
2591  first_residue=10,
2592  last_residue=20))
2593  output[
2594  "Selection_resolution=100,resrange=(10,20),name=" +
2595  name +
2596  ",ambiguous"] = len(
2598  self,
2599  resolution=100,
2600  name=name,
2601  name_is_ambiguous=True,
2602  first_residue=10,
2603  last_residue=20))
2604 
2605  return output
2606 
2607 
2608 # Deprecation warning for the old SimplifiedModel class
2609 
2610 @IMP.deprecated_object("2.5", "Use Representation instead.")
2611 class SimplifiedModel(Representation):
2612 
2613  def __init__(self, *args, **kwargs):
2614  Representation.__init__(self, *args, **kwargs)
def link_components_to_rmf
Load coordinates in the current representation.
Select non water and non hydrogen atoms.
Definition: pdb.h:243
def list_chunks_iterator
Yield successive length-sized chunks from a list.
Definition: tools.py:1183
Tools for handling Gaussian Mixture Models.
Definition: gmm_tools.py:1
Add mass to a particle.
Definition: Mass.h:23
double get_volume_from_residue_type(ResidueType rt)
Return an estimate for the volume of a given residue.
def add_metadata
Associate some metadata with this modeling.
Simple 3D transformation class.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: Residue.h:155
A decorator to associate a particle with a part of a protein/DNA/RNA.
Definition: Fragment.h:20
static Gaussian setup_particle(Model *m, ParticleIndex pi)
Definition: Gaussian.h:48
void show_molecular_hierarchy(Hierarchy h)
Print out the molecular hierarchy.
double get_drms(const Vector3DsOrXYZs0 &m1, const Vector3DsOrXYZs1 &m2)
def get_restraint_set
Get a RestraintSet containing all PMI restraints added to the model.
Definition: tools.py:49
Apply a SingletonFunction to a SingletonContainer to maintain an invariant.
atom::Hierarchies create_hierarchies(RMF::FileConstHandle fh, Model *m)
Set the coordinates of a particle to be a transformed version of a reference.
Definition: core/symmetry.h:76
Store the representations for a system.
Definition: tools.py:900
def shuffle_configuration
Shuffle configuration; used to restart the optimization.
A member of a rigid body, it has internal (local) coordinates.
Definition: rigid_bodies.h:508
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:509
Set of python classes to create a multi-state, multi-resolution IMP hierarchy.
static Atom setup_particle(Model *m, ParticleIndex pi, Atom other)
Definition: atom/Atom.h:242
static Fragment setup_particle(Model *m, ParticleIndex pi)
Definition: Fragment.h:63
Upper bound harmonic function (non-zero when feature > mean)
static Symmetric setup_particle(Model *m, ParticleIndex pi, Float symmetric)
Definition: Symmetric.h:44
def set_coordinates_from_rmf
Read and replace coordinates from an RMF file.
static XYZR setup_particle(Model *m, ParticleIndex pi)
Definition: XYZR.h:48
A decorator for a particle which has bonds.
Select atoms which are selected by both selectors.
Definition: pdb.h:346
Rotation3D get_random_rotation_3d(const Rotation3D &center, double distance)
Pick a rotation at random near the provided one.
double get_mass(ResidueType c)
Get the mass from the residue type.
def create_non_modeled_component
Create a component that isn't used in the modeling.
Color get_rgb_color(double f)
Return the color for f from the RGB color map.
double get_mass_from_number_of_residues(unsigned int num_aa)
Estimate the mass of a protein from the number of amino acids.
Miscellaneous utilities.
Definition: tools.py:1
def set_rigid_bodies_as_fixed
Fix rigid bodies in their actual position.
def get_particles_from_selection_tuples
selection tuples must be [(r1,r2,"name1"),(r1,r2,"name2"),....
Add symmetric attribute to a particle.
Definition: Symmetric.h:23
double get_ball_radius_from_volume_3d(double volume)
Return the radius of a sphere with a given volume.
Definition: Sphere3D.h:35
def setup_component_sequence_connectivity
Generate restraints between contiguous fragments in the hierarchy.
def create_rotational_symmetry
The copies must not contain rigid bodies.
Add uncertainty to a particle.
Definition: Uncertainty.h:24
A score on the distance between the surfaces of two spheres.
static Residue setup_particle(Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
Definition: Residue.h:157
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:619
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: XYZ.h:49
def get_prot_name_from_particle
Return the component name provided a particle and a list of names.
Definition: tools.py:1048
static XYZ setup_particle(Model *m, ParticleIndex pi)
Definition: XYZ.h:51
void read_pdb(TextInput input, int model, Hierarchy h)
def get_residue_gaps_in_hierarchy
Return the residue index gaps and contiguous segments in the hierarchy.
Definition: tools.py:660
def remove_floppy_bodies
Remove leaves of hierarchies from the floppy bodies list.
Vector3D get_random_vector_in(const Cylinder3D &c)
Generate a random vector in a cylinder with uniform density.
static Uncertainty setup_particle(Model *m, ParticleIndex pi, Float uncertainty)
Definition: Uncertainty.h:45
def remove_floppy_bodies_from_component
Remove leaves of hierarchies from the floppy bodies list based on the component name.
A reference frame in 3D.
Add resolution to a particle.
Definition: Resolution.h:24
Bond create_bond(Bonded a, Bonded b, Bond o)
Connect the two wrapped particles by a custom bond.
Object used to hold a set of restraints.
Definition: RestraintSet.h:36
static Molecule setup_particle(Model *m, ParticleIndex pi)
Definition: Molecule.h:37
Rotation3D get_rotation_about_axis(const Vector3D &axis, double angle)
Generate a Rotation3D object from a rotation around an axis.
Definition: Rotation3D.h:309
Select all CB ATOM records.
Definition: pdb.h:91
A Gaussian distribution in 3D.
Definition: Gaussian3D.h:24
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Fragment.h:46
static Hierarchy setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor children=ParticleIndexesAdaptor())
Create a Hierarchy of level t by adding the needed attributes.
ParticleIndexPairs get_indexes(const ParticlePairsTemp &ps)
def set_rigid_bodies
Construct a rigid body from a list of subunits.
double get_volume_from_mass(double m, ProteinDensityReference ref=ALBER)
Estimate the volume of a protein from its mass.
The standard decorator for manipulating molecular structures.
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
Store a list of ParticleIndexes.
def deprecated_method
Python decorator to mark a method as deprecated.
Definition: __init__.py:9635
A decorator for a particle representing an atom.
Definition: atom/Atom.h:234
void transform(XYZ a, const algebra::Transformation3D &tr)
Apply a transformation to the particle.
static Mass setup_particle(Model *m, ParticleIndex pi, Float mass)
Definition: Mass.h:44
def add_restraint_to_model
Add a PMI restraint to the model.
Definition: tools.py:37
static Bonded setup_particle(Model *m, ParticleIndex pi)
def add_protocol_output
Capture details of the modeling protocol.
The type for a residue.
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Symmetric.h:29
double get_rmsd(const Vector3DsOrXYZs0 &m1, const Vector3DsOrXYZs1 &m2)
def add_all_atom_densities
Decorates all specified particles as Gaussians directly.
def coarse_hierarchy
Generate all needed coarse grained layers.
def add_component_pdb
Add a component that has an associated 3D structure in a PDB file.
Basic utilities for handling cryo-electron microscopy 3D density maps.
void load_frame(RMF::FileConstHandle file, RMF::FrameID frame)
Load the given RMF frame into the state of the linked objects.
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Resolution.h:30
A base class for Keys.
Definition: Key.h:44
static Colored setup_particle(Model *m, ParticleIndex pi, Color color)
Definition: Colored.h:62
def set_chain_of_super_rigid_bodies
Make a chain of super rigid bodies from a list of hierarchies.
def add_component_sequence
Add the primary sequence for a single component.
def write_gmm_to_map
write density map from GMM.
Definition: gmm_tools.py:111
Tools for clustering and cluster analysis.
Definition: pmi/Analysis.py:1
static Resolution setup_particle(Model *m, ParticleIndex pi, Float resolution)
Definition: Resolution.h:45
def create_components_from_rmf
still not working.
def get_closest_residue_position
this function works with plain hierarchies, as read from the pdb, no multi-scale hierarchies ...
Definition: tools.py:544
3D rotation class.
Definition: Rotation3D.h:46
Transformation3D get_identity_transformation_3d()
Return a transformation that does not do anything.
Find all nearby pairs by testing all pairs.
Classes for writing output files and processing them.
Definition: output.py:1
Simple implementation of segments in 3D.
Definition: Segment3D.h:24
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:147
def deprecated_object
Python decorator to mark a class as deprecated.
Definition: __init__.py:9619
A decorator for a residue.
Definition: Residue.h:134
Sampling of the system.
Definition: samplers.py:1
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)
def add_component_density
Sets up a Gaussian Mixture Model for this component.
Sample using Monte Carlo.
Definition: samplers.py:36
The general base class for IMP exceptions.
Definition: exception.h:49
Hierarchy create_simplified_along_backbone(Chain input, const IntRanges &residue_segments, bool keep_detailed=false)
VectorD< 3 > Vector3D
Definition: VectorD.h:395
def get_file_dataset
Get the dataset associated with a filename, or None.
IMP::core::RigidBody create_rigid_body(Hierarchy h)
static Reference setup_particle(Model *m, ParticleIndex pi, ParticleIndexAdaptor reference)
Definition: core/symmetry.h:32
Rotation3D get_identity_rotation_3d()
Return a rotation that does not do anything.
Definition: Rotation3D.h:244
void link_hierarchies(RMF::FileConstHandle fh, const atom::Hierarchies &hs)
Class to handle individual particles of a Model object.
Definition: Particle.h:41
Bond get_bond(Bonded a, Bonded b)
Get the bond between two particles.
std::string get_data_path(std::string file_name)
Return the full path to one of this module's data files.
Select atoms which are selected by either or both selectors.
Definition: pdb.h:369
def get_hierarchies_at_given_resolution
Get the hierarchies at the given resolution.
Store info for a chain of a protein.
Definition: Chain.h:21
Applies a PairScore to a Pair.
Definition: PairRestraint.h:29
def select
this function uses representation=SimplifiedModel it returns the corresponding selected particles rep...
Definition: tools.py:731
Select all CA ATOM records.
Definition: pdb.h:77
Python classes to represent, score, sample and analyze models.
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Uncertainty.h:30
double get_resolution(Model *m, ParticleIndex pi)
Estimate the resolution of the hierarchy as used by Representation.
A decorator for a rigid body.
Definition: rigid_bodies.h:75
Set up the representation of all proteins and nucleic acid macromolecules.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: Gaussian.h:47
A dictionary-like wrapper for reading and storing sequence data.
def write_gmm_to_text
write a list of gaussians to text.
Definition: gmm_tools.py:62
Transformation3D get_transformation_aligning_first_to_second(Vector3Ds a, Vector3Ds b)
Output IMP model data in various file formats.
Functionality for loading, creating, manipulating and scoring atomic structures.
static Chain setup_particle(Model *m, ParticleIndex pi, std::string id)
Definition: Chain.h:41
Hierarchies get_leaves(const Selection &h)
def add_component_necklace
Generates a string of beads with given length.
An exception for an invalid value being passed to IMP.
Definition: exception.h:137
def set_file_dataset
Associate a dataset with a filename.
def set_floppy_bodies_as_fixed
Fix floppy bodies in their actual position.
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:158
Select all ATOM and HETATM records with the given chain ids.
Definition: pdb.h:189
Support for the RMF file format for storing hierarchical molecular data and markup.
def set_rigid_body_from_hierarchies
Construct a rigid body from hierarchies (and optionally particles).
def decorate_gmm_from_text
read the output from write_gmm_to_text, decorate as Gaussian and Mass
Definition: gmm_tools.py:22
def get_residue_indexes
Retrieve the residue indexes for the given particle.
Definition: tools.py:1068
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:640
Transformation3D get_random_local_transformation(Vector3D origin, double max_translation=5., double max_angle_in_rad=0.26)
Get a local transformation.
def check_root
If the root hierarchy does not exist, construct it.
def add_component_beads
add beads to the representation
Inferential scoring building on methods developed as part of the Inferential Structure Determination ...
def sublist_iterator
Yield all sublists of length >= lmin and <= lmax.
Definition: tools.py:1164
def add_component_hierarchy_clone
Make a copy of a hierarchy and append it to a component.
Harmonic function (symmetric about the mean)
Definition: core/Harmonic.h:24
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27