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