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