IMP  2.4.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.base
11 import IMP.algebra
12 import IMP.atom
13 import IMP.display
14 import IMP.pmi
15 import IMP.isd
16 from math import pi, sqrt
17 
18 from operator import itemgetter
19 import IMP.pmi.tools
20 import IMP.pmi.output
21 import IMP.rmf
22 import RMF
23 import os
24 
25 
26 class Representation(object):
27  # Authors: Peter Cimermancic, Riccardo Pellarin, Charles Greenberg
28 
29  '''
30  Set up the representation of all proteins and nucleic acid macromolecules.
31 
32  Create the molecular hierarchies, representation,
33  sequence connectivity for the various involved proteins and
34  nucleic acid macromolecules:
35 
36  Create a protein, DNA or RNA, represent it as a set of connected balls of appropriate
37  radii and number of residues, PDB at given resolution(s), or ideal helices.
38 
39  How to use the SimplifiedModel class (typical use):
40 
41  see test/test_hierarchy_contruction.py
42 
43  examples:
44 
45  1) Create a chain of helices and flexible parts
46 
47  c_1_119 =self.add_component_necklace("prot1",1,119,20)
48  c_120_131 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(120,131))
49  c_132_138 =self.add_component_beads("prot1",[(132,138)])
50  c_139_156 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(139,156))
51  c_157_174 =self.add_component_beads("prot1",[(157,174)])
52  c_175_182 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(175,182))
53  c_183_194 =self.add_component_beads("prot1",[(183,194)])
54  c_195_216 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(195,216))
55  c_217_250 =self.add_component_beads("prot1",[(217,250)])
56 
57 
58  self.set_rigid_body_from_hierarchies(c_120_131)
59  self.set_rigid_body_from_hierarchies(c_139_156)
60  self.set_rigid_body_from_hierarchies(c_175_182)
61  self.set_rigid_body_from_hierarchies(c_195_216)
62 
63  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,
64  c_217_250]
65 
66  self.set_chain_of_super_rigid_bodies(clist,2,3)
67 
68  self.set_super_rigid_bodies(["prot1"])
69 
70  '''
71 
72  def __init__(self, m, upperharmonic=True, disorderedlength=True):
73  """Constructor.
74  @param m the model
75  @param upperharmonic This flag uses either harmonic (False)
76  or upperharmonic (True) in the intra-pair
77  connectivity restraint.
78  @param disorderedlength This flag uses either disordered length
79  calculated for random coil peptides (True) or zero
80  surface-to-surface distance between beads (False)
81  as optimal distance for the sequence connectivity
82  restraint.
83  """
84 
85  # this flag uses either harmonic (False) or upperharmonic (True)
86  # in the intra-pair connectivity restraint. Harmonic is used whe you want to
87  # remove the intra-ev term from energy calculations, e.g.:
88  # upperharmonic=False
89  # ip=self.get_connected_intra_pairs()
90  # ev.add_excluded_particle_pairs(ip)
91 
92  self.upperharmonic = upperharmonic
93  self.disorderedlength = disorderedlength
94  self.rigid_bodies = []
95  self.fixed_rigid_bodies = []
96  self.fixed_floppy_bodies = []
97  self.floppy_bodies = []
98  # self.super_rigid_bodies is a list of tuples.
99  # each tuple, corresponding to a particular super rigid body
100  # the tuple is (super_rigid_xyzs,super_rigid_rbs)
101  # where super_rigid_xyzs are the flexible xyz particles
102  # and super_rigid_rbs is the list of rigid bodies.
103  self.super_rigid_bodies = []
104  self.output_level = "low"
105  self.label = "None"
106 
107  self.maxtrans_rb = 2.0
108  self.maxrot_rb = 0.04
109  self.maxtrans_srb = 2.0
110  self.maxrot_srb = 0.2
111  self.rigidbodiesarefixed = False
112  self.maxtrans_fb = 3.0
113  self.resolution = 10.0
114  self.bblenght = 100.0
115  self.kappa = 100.0
116  self.m = m
117 
118  self.representation_is_modified = False
119  self.unmodeledregions_cr_dict = {}
120  self.sortedsegments_cr_dict = {}
122  self.connected_intra_pairs = []
123  self.hier_dict = {}
124  self.color_dict = {}
125  self.sequence_dict = {}
126  self.hier_geometry_pairs = {}
127  self.hier_db = IMP.pmi.tools.HierarchyDatabase()
128  # this dictionary stores the hierarchies by component name and representation type
129  # self.hier_representation[name][representation_type]
130  # where representation type is Res:X, Beads, Densities, Representation,
131  # etc...
132  self.hier_representation = {}
133  self.hier_resolution = {}
134  # reference structures is a dictionary that contains the coordinates of
135  # structures that are used to calculate the rmsd
136  self.reference_structures = {}
137  self.elements = {}
138  self.linker_restraints = IMP.RestraintSet(self.m, "linker_restraints")
139  self.linker_restraints_dict = {}
140  self.threetoone = {'ALA': 'A', 'ARG': 'R', 'ASN': 'N', 'ASP': 'D',
141  'CYS': 'C', 'GLU': 'E', 'GLN': 'Q', 'GLY': 'G',
142  'HIS': 'H', 'ILE': 'I', 'LEU': 'L', 'LYS': 'K',
143  'MET': 'M', 'PHE': 'F', 'PRO': 'P', 'SER': 'S',
144  'THR': 'T', 'TRP': 'W', 'TYR': 'Y', 'VAL': 'V', 'UNK': 'X'}
145 
146  self.onetothree = dict((v, k) for k, v in self.threetoone.items())
147 
148  self.residuenamekey = IMP.kernel.StringKey("ResidueName")
149 
150  def set_label(self, label):
151  self.label = label
152 
153  def create_component(self, name, color=0.0):
155  protein_h.set_name(name)
156  self.hier_dict[name] = protein_h
157  self.hier_representation[name] = {}
158  self.hier_db.add_name(name)
159  self.prot.add_child(protein_h)
160  self.color_dict[name] = color
161  self.elements[name] = []
162 
163  # Deprecation warning
164 
165  def add_component_name(self, *args, **kwargs):
166  IMP.pmi.tools.print_deprecation_warning(
167  "add_component_name",
168  "create_component")
169  self.create_component(*args, **kwargs)
170 
171  def get_component_names(self):
172  return list(self.hier_dict.keys())
173 
174  def add_component_sequence(self, name, filename, id=None, offs=None,
175  format="FASTA"):
176  '''
177  Add the primary sequence for a single component.
178 
179  @param name Human-readable name of the component
180  @param filename Name of the FASTA file
181  @param id Identifier of the sequence in the FASTA file header
182  (if not provided, use `name` instead)
183  '''
184  from Bio import SeqIO
185  handle = open(filename, "rU")
186  record_dict = SeqIO.to_dict(SeqIO.parse(handle, "fasta"))
187  handle.close()
188  if id is None:
189  id = name
190  try:
191  length = len(record_dict[id].seq)
192  except KeyError:
193  raise KeyError("id %s not found in fasta file" % id)
194 
195  self.sequence_dict[name] = str(record_dict[id].seq).replace("*", "")
196  if offs is not None:
197  offs_str="-"*offs
198  self.sequence_dict[name]=offs_str+self.sequence_dict[name]
199 
200  self.elements[name].append((length, length, " ", "end"))
201 
202  def autobuild_model(self, name, pdbname, chain,
203  resolutions=None, resrange=None,
204  missingbeadsize=20,
205  beadsize=None, # this is deprecated
206  color=None, pdbresrange=None, offset=0,
207  show=False, isnucleicacid=False,
208  attachbeads=False):
209 
210  if not beadsize is None:
211  IMP.pmi.tools.print_deprecation_warning(
212  "beadsize",
213  "missingbeadsize")
214 
215  self.representation_is_modified = True
216  outhiers = []
217 
218  if color is None:
219  color = self.color_dict[name]
220  else:
221  self.color_dict[name] = color
222 
223  if resolutions is None:
224  resolutions = [1]
225  print("autobuild_model: constructing %s from pdb %s and chain %s" % (name, pdbname, str(chain)))
226 
227  # get the initial and end residues of the pdb
228  t = IMP.atom.read_pdb(pdbname, self.m,
230 
231  # find start and end indexes
232 
233  start = IMP.atom.Residue(
234  t.get_children()[0].get_children()[0]).get_index()
235  end = IMP.atom.Residue(
236  t.get_children()[0].get_children()[-1]).get_index()
237 
238  # check if resrange was defined, otherwise
239  # use the sequence, or the pdb resrange
240 
241  if resrange is None:
242  if name in self.sequence_dict:
243  resrange = (1, len(self.sequence_dict[name]))
244  else:
245  resrange = (start + offset, end + offset)
246  else:
247  start = resrange[0] - offset
248  end = resrange[1] - offset
249 
251  t,
252  resrange[0],
253  resrange[1])
254 
256  t,
257  resrange[0],
258  terminus="N")
260  t,
261  resrange[1],
262  terminus="C")
263 
264  # construct pdb fragments and intervening beads
265  for n, g in enumerate(gaps):
266  first = g[0]
267  last = g[1]
268  if g[2] == "cont":
269  print("autobuild_model: constructing fragment %s from pdb" % (str((first, last))))
270  outhiers += self.add_component_pdb(name, pdbname,
271  chain, resolutions=resolutions,
272  color=color, cacenters=True,
273  resrange=(first, last),
274  offset=offset, isnucleicacid=isnucleicacid)
275  elif g[2] == "gap" and n > 0:
276  print("autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
277  parts = self.hier_db.get_particles_at_closest_resolution(
278  name,
279  first -
280  1,
281  1)
282  xyz = IMP.core.XYZ(parts[0]).get_coordinates()
283  outhiers += self.add_component_necklace(name,
284  first+offset, last+offset, missingbeadsize, incoord=xyz)
285 
286  elif g[2] == "gap" and n == 0:
287  # add pre-beads
288  print("autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
289  outhiers += self.add_component_necklace(name,
290  first+offset, last+offset, missingbeadsize, incoord=xyznter)
291 
292  return outhiers
293 
294  # Deprecation warning
295 
296  def autobuild_pdb_and_intervening_beads(self, *args, **kwargs):
297  IMP.pmi.tools.print_deprecation_warning(
298  "autobuild_pdb_and_intervening_beads",
299  "autobuild_model")
300  r = self.autobuild_model(*args, **kwargs)
301  return r
302 
303  def add_component_pdb(self, name, pdbname, chain, resolutions, color=None,
304  resrange=None, offset=0, cacenters=True, show=False,
305  isnucleicacid=False, readnonwateratoms=False,
306  read_ca_cb_only=False):
307  '''
308  Add a component that has an associated 3D structure in a PDB file.
309 
310  Reads the PDB, and constructs the fragments corresponding to contiguous
311  senquence stretches.
312 
313  @return a list of hierarchies.
314 
315  @param name (string) the name of the component
316  @param pdbname (string) the name of the PDB file
317  @param chain (string or integer) can be either a string (eg, "A")
318  or an integer (eg, 0 or 1) in case you want
319  to get the corresponding chain number in the PDB.
320  @param resolutions (integers) a list of integers that corresponds
321  to the resolutions that have to be generated
322  @param color (float from 0 to 1) the color applied to the
323  hierarchies generated
324  @param resrange (tuple of integers): the residue range to extract
325  from the PDB. It is a tuple (beg,end). If not specified,
326  all residues belonging to the specified chain are read.
327  @param offset (integer) specifies the residue index offset to be
328  applied when reading the PDB (the FASTA sequence is
329  assumed to start from residue 1, so use this parameter
330  if the PDB file does not start at residue 1)
331  @param cacenters (boolean) if True generates resolution=1 beads
332  centered on C-alpha atoms.
333  @param show (boolean) print out the molecular hierarchy at the end.
334  @param isnucleicacid (boolean) use True if you're reading a PDB
335  with nucleic acids.
336  @param readnonwateratoms (boolean) if True fixes some pathological PDB.
337  @param read_ca_cb_only (boolean) if True, only reads CA/CB
338  '''
339 
340  self.representation_is_modified = True
341  if color is None:
342  # if the color is not passed, then get the stored color
343  color = self.color_dict[name]
344  protein_h = self.hier_dict[name]
345  outhiers = []
346 
347  # determine selector
349  if read_ca_cb_only:
350  cacbsel = IMP.atom.OrPDBSelector(
353  sel = IMP.atom.AndPDBSelector(cacbsel, sel)
354  if type(chain) == str:
357  sel)
358  t = IMP.atom.read_pdb(pdbname, self.m, sel)
359 
360  # get the first and last residue
361  start = IMP.atom.Residue(
362  t.get_children()[0].get_children()[0]).get_index()
363  end = IMP.atom.Residue(
364  t.get_children()[0].get_children()[-1]).get_index()
365  c = IMP.atom.Chain(IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[0])
366  else:
367  t = IMP.atom.read_pdb(pdbname, self.m, sel)
368  c = IMP.atom.Chain(
369  IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[chain])
370 
371  # get the first and last residue
372  start = IMP.atom.Residue(c.get_children()[0]).get_index()
373  end = IMP.atom.Residue(c.get_children()[-1]).get_index()
374  chain = c.get_id()
375 
376  if not resrange is None:
377  if resrange[0] > start:
378  start = resrange[0]
379  if resrange[1] < end:
380  end = resrange[1]
381 
382  if not isnucleicacid:
383  # do what you have to do for proteins
384  sel = IMP.atom.Selection(
385  c,
386  residue_indexes=list(range(
387  start,
388  end + 1)),
389  atom_type=IMP.atom.AT_CA)
390 
391  else:
392  # do what you have to do for nucleic-acids
393  sel = IMP.atom.Selection(
394  c,
395  residue_indexes=list(range(
396  start,
397  end + 1)),
398  atom_type=IMP.atom.AT_P)
399 
400  ps = sel.get_selected_particles()
401  if len(ps) == 0:
402  raise ValueError("%s no residue found in pdb %s chain %s that overlaps with the queried stretch %s-%s" \
403  % (name, pdbname, str(chain), str(resrange[0]), str(resrange[1])))
405 
406  for p in ps:
407  par = IMP.atom.Atom(p).get_parent()
408  ri = IMP.atom.Residue(par).get_index()
409  IMP.atom.Residue(par).set_index(ri + offset)
410  c0.add_child(par)
411  start = start + offset
412  end = end + offset
413 
414  self.elements[name].append(
415  (start, end, pdbname.split("/")[-1] + ":" + chain, "pdb"))
416 
417  outhiers += self.coarse_hierarchy(name, start, end,
418  resolutions, isnucleicacid, c0, protein_h, "pdb", color)
419 
420  if show:
422 
423  del c
424  del c0
425  del t
426 
427  return outhiers
428 
429  def add_component_ideal_helix(
430  self,
431  name,
432  resolutions,
433  resrange,
434  color=None,
435  show=False):
436 
437  self.representation_is_modified = True
438  from math import pi, cos, sin
439 
440  protein_h = self.hier_dict[name]
441  outhiers = []
442  if color is None:
443  color = self.color_dict[name]
444 
445  start = resrange[0]
446  end = resrange[1]
447  self.elements[name].append((start, end, " ", "helix"))
449  for n, res in enumerate(range(start, end + 1)):
450  if name in self.sequence_dict:
451  try:
452  rtstr = self.onetothree[
453  self.sequence_dict[name][res-1]]
454  except:
455  rtstr = "UNK"
456  rt = IMP.atom.ResidueType(rtstr)
457  else:
458  rt = IMP.atom.ResidueType("ALA")
459 
460  # get the residue volume
461  try:
463  # mass=IMP.atom.get_mass_from_residue_type(rt)
466  IMP.atom.ResidueType("ALA"))
467  # mass=IMP.atom.get_mass_from_residue_type(IMP.atom.ResidueType("ALA"))
469 
470  r = IMP.atom.Residue.setup_particle(IMP.Particle(self.m), rt, res)
471  p = IMP.Particle(self.m)
473  x = 2.3 * cos(n * 2 * pi / 3.6)
474  y = 2.3 * sin(n * 2 * pi / 3.6)
475  z = 6.2 / 3.6 / 2 * n * 2 * pi / 3.6
476  d.set_coordinates(IMP.algebra.Vector3D(x, y, z))
477  d.set_radius(radius)
478  # print d
479  a = IMP.atom.Atom.setup_particle(p, IMP.atom.AT_CA)
480  r.add_child(a)
481  c0.add_child(r)
482 
483  outhiers += self.coarse_hierarchy(name, start, end,
484  resolutions, False, c0, protein_h, "helix", color)
485 
486  if show:
488 
489  del c0
490  return outhiers
491 
492  def add_component_beads(self, name, ds, colors=None, incoord=None):
493  """ add beads to the representation
494  @name the component name
495  @ds a list of tuples corresponding to the residue ranges of the beads
496  @colors a list of colors associated to the beads
497  @incoord the coordinate tuple correspoding to the position of the beads
498  """
499 
500  from math import pi
501  self.representation_is_modified = True
502 
503  protein_h = self.hier_dict[name]
504  outhiers = []
505  if colors is None:
506  colors = [self.color_dict[name]]
507 
508 
509  for n, dss in enumerate(ds):
510  ds_frag = (dss[0], dss[1])
511  self.elements[name].append((dss[0], dss[1], " ", "bead"))
512  prt = IMP.Particle(self.m)
513  if ds_frag[0] == ds_frag[1]:
514  # if the bead represent a single residue
515  if name in self.sequence_dict:
516  try:
517  rtstr = self.onetothree[
518  self.sequence_dict[name][ds_frag[0]-1]]
519  except:
520  rtstr = "UNK"
521  rt = IMP.atom.ResidueType(rtstr)
522  else:
523  rt = IMP.atom.ResidueType("ALA")
524  h = IMP.atom.Residue.setup_particle(prt, rt, ds_frag[0])
525  h.set_name(name + '_%i_bead' % (ds_frag[0]))
526  prt.set_name(name + '_%i_bead' % (ds_frag[0]))
527  resolution = 1
528  else:
530  h.set_name(name + '_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
531  prt.set_name(name + '_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
532  h.set_residue_indexes(list(range(ds_frag[0], ds_frag[1] + 1)))
533  resolution = len(h.get_residue_indexes())
534  if "Beads" not in self.hier_representation[name]:
536  root.set_name("Beads")
537  self.hier_representation[name]["Beads"] = root
538  protein_h.add_child(root)
539  self.hier_representation[name]["Beads"].add_child(h)
540 
541  for kk in range(ds_frag[0], ds_frag[1] + 1):
542  self.hier_db.add_particles(name, kk, resolution, [h])
543 
544  try:
545  clr = IMP.display.get_rgb_color(colors[n])
546  except:
547  clr = IMP.display.get_rgb_color(colors[0])
548 
550 
551  # decorate particles according to their resolution
552  IMP.pmi.Resolution.setup_particle(prt, resolution)
553 
555  ptem = IMP.core.XYZR(prt)
557  if resolution == 1:
558  try:
562  IMP.atom.ResidueType("ALA"))
565  ptem.set_radius(radius)
566  else:
567  volume = IMP.atom.get_volume_from_mass(mass)
568  radius = 0.8 * (3.0 / 4.0 / pi * volume) ** (1.0 / 3.0)
570  ptem.set_radius(radius)
571  try:
572  if not tuple(incoord) is None:
573  ptem.set_coordinates(incoord)
574  except TypeError:
575  pass
578  self.floppy_bodies.append(prt)
579  IMP.core.XYZ(prt).set_coordinates_are_optimized(True)
580  outhiers += [h]
581 
582  return outhiers
583 
584  def add_component_necklace(self, name, begin, end, length, color=None,
585  incoord=None):
586  '''
587  Generates a string of beads with given length.
588  '''
589  self.representation_is_modified = True
590  outhiers = []
591  if color is None:
592  colors=None
593  else:
594  colors=[color]
595  for chunk in IMP.pmi.tools.list_chunks_iterator(range(begin, end + 1), length):
596  outhiers += self.add_component_beads(name,
597  [(chunk[0], chunk[-1])], colors=colors,incoord=incoord)
598  return outhiers
599 
601  self, name, hierarchies=None, selection_tuples=None,
602  particles=None,
603  resolution=0.0, num_components=10,
604  inputfile=None, outputfile=None,
605  outputmap=None,
606  kernel_type=None,
607  covariance_type='full', voxel_size=1.0,
608  out_hier_name='',
609  sampled_points=1000000, num_iter=100,
610  simulation_res=1.0,
611  multiply_by_total_mass=True,
612  transform=None,
613  intermediate_map_fn=None,
614  density_ps_to_copy=None,
615  use_precomputed_gaussians=False):
616  '''
617  Sets up a Gaussian Mixture Model for this component.
618  Can specify input GMM file or it will be computed.
619  @parm name component name
620  @param hierarchies set up GMM for some hierarchies
621  @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
622  @param particles set up GMM for particles directly
623  @param resolution usual PMI resolution for selecting particles from the hierarchies
624  @param inputfile read the GMM from this file
625  @param outputfile fit and write the GMM to this file (text)
626  @param outputmap after fitting, create GMM density file (mrc)
627  @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
628  @param covariance_type for fitting the GMM. options are 'full', 'diagonal' and 'spherical'
629  @param voxel_size for creating the intermediate density map and output map.
630  lower number increases accuracy but also rasterizing time grows
631  @param out_hier_name name of the output density hierarchy
632  @param sampled_points number of points to sample. more will increase accuracy and fitting time
633  @param num_iter num GMM iterations. more will increase accuracy and fitting time
634  @param multiply_by_total_mass multiply the weights of the GMM by this value (only works on creation!)
635  @param transform for input file only, apply a transformation (eg for multiple copies same GMM)
636  @param intermediate_map_fn for debugging, this will write the itermediate (simulated) map
637  @param density_ps_to_copy in case you already created the appropriate GMM (eg, for beads)
638  @param use_precomputed_gaussians Set this flag and pass fragments - will use roughly spherical Gaussian setup
639  '''
640  import numpy as np
641  import sys
642  import IMP.em
643  import IMP.isd.gmm_tools
644 
645  # prepare output
646  self.representation_is_modified = True
647  out_hier = []
648  protein_h = self.hier_dict[name]
649  if "Densities" not in self.hier_representation[name]:
651  root.set_name("Densities")
652  self.hier_representation[name]["Densities"] = root
653  protein_h.add_child(root)
654 
655  # gather passed particles
656  fragment_particles = []
657  if not particles is None:
658  fragment_particles += particles
659  if not hierarchies is None:
660  fragment_particles += IMP.pmi.tools.select(
661  self, resolution=resolution,
662  hierarchies=hierarchies)
663  if not selection_tuples is None:
664  for st in selection_tuples:
665  fragment_particles += IMP.pmi.tools.select_by_tuple(
666  self, tupleselection=st,
667  resolution=resolution,
668  name_is_ambiguous=False)
669 
670  # compute or read gaussians
671  density_particles = []
672  if inputfile:
674  inputfile, density_particles,
675  self.m, transform)
676  elif density_ps_to_copy:
677  for ip in density_ps_to_copy:
678  p = IMP.Particle(self.m)
679  shape = IMP.core.Gaussian(ip).get_gaussian()
680  mass = IMP.atom.Mass(ip).get_mass()
683  density_particles.append(p)
684  elif use_precomputed_gaussians:
685  if len(fragment_particles) == 0:
686  print("add_component_density: no particle was selected")
687  return out_hier
688  for p in fragment_particles:
689  if not (IMP.atom.Fragment.get_is_setup(self.m,p.get_particle_index()) and
690  IMP.core.XYZ.get_is_setup(self.m,p.get_particle_index())):
691  raise Exception("The particles you selected must be Fragments and XYZs")
692  nres=len(IMP.atom.Fragment(self.m,p.get_particle_index()).get_residue_indexes())
693  pos=IMP.core.XYZ(self.m,p.get_particle_index()).get_coordinates()
694  density_particles=[]
695  try:
696  IMP.isd.get_data_path("beads/bead_%i.txt"%nres)
697  except:
698  raise Exception("We haven't created a bead file for",nres,"residues")
699  transform = IMP.algebra.Transformation3D(pos)
701  IMP.isd.get_data_path("beads/bead_%i.txt"%nres), density_particles,
702  self.m, transform)
703  else:
704  #compute the gaussians here
705  if len(fragment_particles) == 0:
706  print("add_component_density: no particle was selected")
707  return out_hier
708 
709  density_particles = IMP.isd.gmm_tools.sample_and_fit_to_particles(
710  self.m,
711  fragment_particles,
712  num_components,
713  sampled_points,
714  simulation_res,
715  voxel_size,
716  num_iter,
717  covariance_type,
718  multiply_by_total_mass,
719  outputmap,
720  outputfile)
721 
722  # prepare output hierarchy
724  s0.set_name(out_hier_name)
725  self.hier_representation[name]["Densities"].add_child(s0)
726  out_hier.append(s0)
727  for nps, p in enumerate(density_particles):
728  s0.add_child(p)
729  p.set_name(s0.get_name() + '_gaussian_%i' % nps)
730  return out_hier
731 
732  def get_component_density(self, name):
733  return self.hier_representation[name]["Densities"]
734 
735  def add_all_atom_densities(self, name, hierarchies=None,
736  selection_tuples=None,
737  particles=None,
738  resolution=0,
739  output_map=None,
740  voxel_size=1.0):
741  '''Decorates all specified particles as Gaussians directly.
742  @param name component name
743  @param hierarchies set up GMM for some hierarchies
744  @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
745  @param particles set up GMM for particles directly
746  @param resolution usual PMI resolution for selecting particles from the hierarchies
747  @param intermediate_map_fn for debugging, this will write the itermediate (simulated) map
748  '''
749 
750  import IMP.em
751  import numpy as np
752  import sys
753  from math import sqrt
754  self.representation_is_modified = False
755 
756  if particles is None:
757  fragment_particles = []
758  else:
759  fragment_particles = particles
760 
761  if not hierarchies is None:
762  fragment_particles += IMP.pmi.tools.select(
763  self, resolution=resolution,
764  hierarchies=hierarchies)
765 
766  if not selection_tuples is None:
767  for st in selection_tuples:
768  fragment_particles += IMP.pmi.tools.select_by_tuple(
769  self, tupleselection=st,
770  resolution=resolution,
771  name_is_ambiguous=False)
772 
773  if len(fragment_particles) == 0:
774  print("add all atom densities: no particle was selected")
775  return
776 
777  # create a spherical gaussian for each particle based on atom type
778  print('setting up all atom gaussians num_particles',len(fragment_particles))
779  for n,p in enumerate(fragment_particles):
780  center=IMP.core.XYZ(p).get_coordinates()
781  rad=IMP.core.XYZR(p).get_radius()
782  mass=IMP.atom.Mass(p).get_mass()
784  center)
787  print('setting up particle',p.get_name(), " as individual gaussian particle")
788 
789  if not output_map is None:
790  print('writing map to', output_map)
792  fragment_particles,
793  output_map,
794  voxel_size)
795 
796  def add_component_hierarchy_clone(self, name, hierarchy):
797  '''
798  Make a copy of a hierarchy and append it to a component.
799  '''
800  outhier = []
801  self.representation_is_modified = True
802  protein_h = self.hier_dict[name]
803  hierclone = IMP.atom.create_clone(hierarchy)
804  hierclone.set_name(hierclone.get_name() + "_clone")
805  protein_h.add_child(hierclone)
806  outhier.append(hierclone)
807 
808  psmain = IMP.atom.get_leaves(hierarchy)
809  psclone = IMP.atom.get_leaves(hierclone)
810 
811  # copying attributes
812  for n, pmain in enumerate(psmain):
813  pclone = psclone[n]
815  resolution = IMP.pmi.Resolution(pmain).get_resolution()
816  IMP.pmi.Resolution.setup_particle(pclone, resolution)
817  for kk in IMP.pmi.tools.get_residue_indexes(pclone):
818  self.hier_db.add_particles(
819  name,
820  kk,
822  [pclone])
823 
825  uncertainty = IMP.pmi.Uncertainty(pmain).get_uncertainty()
826  IMP.pmi.Uncertainty.setup_particle(pclone, uncertainty)
827 
829  symmetric = IMP.pmi.Symmetric(pmain).get_symmetric()
830  IMP.pmi.Symmetric.setup_particle(pclone, symmetric)
831 
832  return outhier
833 
834  def set_coordinates_from_rmf(self, component_name, rmf_file_name,
835  rmf_frame_number, rmf_component_name=None,check_number_particles=True):
836  '''Read and replace coordinates from an RMF file.
837  Replace the coordinates of particles with the same name.
838  It assumes that the RMF and the representation have the particles
839  in the same order.
840  @param component_name Component name
841  @param rmf_component_name Name of the component in the RMF file
842  (if not specified, use `component_name`)
843  '''
844 
845  import IMP.pmi.analysis
846 
847  prot = IMP.pmi.analysis.get_hier_from_rmf(
848  self.m,
849  rmf_frame_number,
850  rmf_file_name)
851 
852  if not prot:
853  raise ValueError("cannot read hiearchy from rmf")
854  # if len(self.rigid_bodies)!=0:
855  # print "set_coordinates_from_rmf: cannot proceed if rigid bodies were initialized. Use the function before defining the rigid bodies"
856  # exit()
857 
858  allpsrmf = IMP.atom.get_leaves(prot)
859 
860  psrmf = []
861  for p in allpsrmf:
862  (protname, is_a_bead) = IMP.pmi.tools.get_prot_name_from_particle(
863  p, self.hier_dict.keys())
864  if not rmf_component_name is None and protname == rmf_component_name:
865  psrmf.append(p)
866  elif rmf_component_name is None and protname == component_name:
867  psrmf.append(p)
868 
869  psrepr = IMP.atom.get_leaves(self.hier_dict[component_name])
870 
871  if check_number_particles:
872  if len(psrmf) != len(psrepr):
873  raise ValueError("%s cannot proceed the rmf and the representation don't have the same number of particles; "
874  "particles in rmf: %s particles in the representation: %s" % (str(component_name), str(len(psrmf)), str(len(psrepr))))
875 
876  for n, prmf in enumerate(psrmf):
877  prmfname = prmf.get_name()
878  preprname = psrepr[n].get_name()
879  if IMP.core.RigidMember.get_is_setup(psrepr[n]):
880  raise ValueError("component %s cannot proceed if rigid bodies were initialized. Use the function before defining the rigid bodies" % component_name)
882  raise ValueError("component %s cannot proceed if rigid bodies were initialized. Use the function before defining the rigid bodies" % component_name)
883 
884  if prmfname != preprname:
885  print("set_coordinates_from_rmf: WARNING rmf particle and representation particles have not the same name %s %s " % (prmfname, preprname))
887  xyz = IMP.core.XYZ(prmf).get_coordinates()
888  IMP.core.XYZ(psrepr[n]).set_coordinates(xyz)
889  else:
890  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]))))
891 
892  def check_root(self, name, protein_h, resolution):
893  '''
894  If the root hierarchy does not exist, construct it.
895  '''
896  if "Res:" + str(int(resolution)) not in self.hier_representation[name]:
898  root.set_name(name + "_Res:" + str(int(resolution)))
899  self.hier_representation[name][
900  "Res:" + str(int(resolution))] = root
901  protein_h.add_child(root)
902 
903  def coarse_hierarchy(self, name, start, end, resolutions, isnucleicacid,
904  input_hierarchy, protein_h, type, color):
905  '''
906  Generate all needed coarse grained layers.
907 
908  @param name name of the protein
909  @param resolutions list of resolutions
910  @param protein_h root hierarchy
911  @param input_hierarchy hierarchy to coarse grain
912  @param type a string, typically "pdb" or "helix"
913  '''
914  outhiers = []
915 
916  if (1 in resolutions) or (0 in resolutions):
917  # in that case create residues and append atoms
918 
919  if 1 in resolutions:
920  self.check_root(name, protein_h, 1)
922  s1.set_name('%s_%i-%i_%s' % (name, start, end, type))
923  # s1.set_residue_indexes(range(start,end+1))
924  self.hier_representation[name]["Res:1"].add_child(s1)
925  outhiers += [s1]
926  if 0 in resolutions:
927  self.check_root(name, protein_h, 0)
929  s0.set_name('%s_%i-%i_%s' % (name, start, end, type))
930  # s0.set_residue_indexes(range(start,end+1))
931  self.hier_representation[name]["Res:0"].add_child(s0)
932  outhiers += [s0]
933 
934  if not isnucleicacid:
935  sel = IMP.atom.Selection(
936  input_hierarchy,
937  atom_type=IMP.atom.AT_CA)
938  else:
939  sel = IMP.atom.Selection(
940  input_hierarchy,
941  atom_type=IMP.atom.AT_P)
942 
943  for p in sel.get_selected_particles():
944  resobject = IMP.atom.Residue(IMP.atom.Atom(p).get_parent())
945  if 0 in resolutions:
946  # if you ask for atoms
947  resclone0 = IMP.atom.create_clone(resobject)
948  resindex = IMP.atom.Residue(resclone0).get_index()
949  s0.add_child(resclone0)
950  self.hier_db.add_particles(
951  name,
952  resindex,
953  0,
954  resclone0.get_children())
955 
956  chil = resclone0.get_children()
957  for ch in chil:
959  try:
960  clr = IMP.display.get_rgb_color(color)
961  except:
962  clr = IMP.display.get_rgb_color(1.0)
964 
965  if 1 in resolutions:
966  # else clone the residue
967  resclone1 = IMP.atom.create_clone_one(resobject)
968  resindex = IMP.atom.Residue(resclone1).get_index()
969  s1.add_child(resclone1)
970  self.hier_db.add_particles(name, resindex, 1, [resclone1])
971 
972  rt = IMP.atom.Residue(resclone1).get_residue_type()
973  xyz = IMP.core.XYZ(p).get_coordinates()
974  prt = resclone1.get_particle()
975  prt.set_name('%s_%i_%s' % (name, resindex, type))
976  IMP.core.XYZ.setup_particle(prt).set_coordinates(xyz)
977 
978  try:
980  # mass=IMP.atom.get_mass_from_residue_type(rt)
983  IMP.atom.ResidueType("ALA"))
984  # mass=IMP.atom.get_mass_from_residue_type(IMP.atom.ResidueType("ALA"))
986  IMP.core.XYZR.setup_particle(prt).set_radius(radius)
991  try:
992  clr = IMP.display.get_rgb_color(color)
993  except:
994  clr = IMP.display.get_rgb_color(1.0)
996 
997  for r in resolutions:
998  if r != 0 and r != 1:
999  self.check_root(name, protein_h, r)
1001  input_hierarchy,
1002  r)
1003 
1004  chil = s.get_children()
1006  s0.set_name('%s_%i-%i_%s' % (name, start, end, type))
1007  # s0.set_residue_indexes(range(start,end+1))
1008  for ch in chil:
1009  s0.add_child(ch)
1010  self.hier_representation[name][
1011  "Res:" + str(int(r))].add_child(s0)
1012  outhiers += [s0]
1013  del s
1014 
1015  for prt in IMP.atom.get_leaves(s0):
1016  ri = IMP.atom.Fragment(prt).get_residue_indexes()
1017  first = ri[0]
1018  last = ri[-1]
1019  if first == last:
1020  prt.set_name('%s_%i_%s' % (name, first, type))
1021  else:
1022  prt.set_name('%s_%i_%i_%s' % (name, first, last, type))
1023  for kk in ri:
1024  self.hier_db.add_particles(name, kk, r, [prt])
1025 
1026  radius = IMP.core.XYZR(prt).get_radius()
1030 
1031  # setting up color for each particle in the
1032  # hierarchy, if colors missing in the colors list set it to
1033  # red
1034  try:
1035  clr = IMP.display.get_rgb_color(color)
1036  except:
1037  colors.append(1.0)
1038  clr = IMP.display.get_rgb_color(colors[pdb_part_count])
1040 
1041  return outhiers
1042 
1044  '''
1045  Get the hierarchies at the given resolution.
1046 
1047  The map between resolution and hierarchies is cached to accelerate
1048  the selection algorithm. The cache is invalidated when the
1049  representation was changed by any add_component_xxx.
1050  '''
1051 
1052  if self.representation_is_modified:
1053  rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1054  resolution)
1055  self.hier_resolution[resolution] = rhbr
1056  self.representation_is_modified = False
1057  return rhbr
1058  else:
1059  if resolution in self.hier_resolution:
1060  return self.hier_resolution[resolution]
1061  else:
1062  rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1063  resolution)
1064  self.hier_resolution[resolution] = rhbr
1065  return rhbr
1066 
1068  self, max_translation=300., max_rotation=2.0 * pi,
1069  avoidcollision=True, cutoff=10.0, niterations=100,
1070  bounding_box=None,
1071  excluded_rigid_bodies=None,
1072  hierarchies_excluded_from_collision=None):
1073  '''
1074  Shuffle configuration; used to restart the optimization.
1075 
1076  The configuration of the system is initialized by placing each
1077  rigid body and each bead randomly in a box with a side of
1078  `max_translation` angstroms, and far enough from each other to
1079  prevent any steric clashes. The rigid bodies are also randomly rotated.
1080 
1081  @param avoidcollision check if the particle/rigid body was
1082  placed close to another particle; uses the optional
1083  arguments cutoff and niterations
1084  @param bounding_box defined by ((x1,y1,z1),(x2,y2,z2))
1085  '''
1086 
1087  if excluded_rigid_bodies is None:
1088  excluded_rigid_bodies = []
1089  if hierarchies_excluded_from_collision is None:
1090  hierarchies_excluded_from_collision = []
1091 
1092  if len(self.rigid_bodies) == 0:
1093  print("shuffle_configuration: rigid bodies were not intialized")
1094 
1096  gcpf.set_distance(cutoff)
1097  ps = []
1098  hierarchies_excluded_from_collision_indexes = []
1099  for p in IMP.atom.get_leaves(self.prot):
1101  ps.append(p)
1103  # remove the densities particles out of the calculation
1104  hierarchies_excluded_from_collision_indexes += IMP.get_indexes([p])
1105  allparticleindexes = IMP.get_indexes(ps)
1106 
1107  if not bounding_box is None:
1108  ((x1, y1, z1), (x2, y2, z2)) = bounding_box
1109  ub = IMP.algebra.Vector3D(x1, y1, z1)
1110  lb = IMP.algebra.Vector3D(x2, y2, z2)
1111  bb = IMP.algebra.BoundingBox3D(ub, lb)
1112 
1113  for h in hierarchies_excluded_from_collision:
1114  hierarchies_excluded_from_collision_indexes += IMP.get_indexes(IMP.atom.get_leaves(h))
1115 
1116 
1117  allparticleindexes = list(
1118  set(allparticleindexes) - set(hierarchies_excluded_from_collision_indexes))
1119 
1120  print(hierarchies_excluded_from_collision)
1121  print(len(allparticleindexes),len(hierarchies_excluded_from_collision_indexes))
1122 
1123  for rb in self.rigid_bodies:
1124  if rb not in excluded_rigid_bodies:
1125  if avoidcollision:
1126 
1127  rbindexes = rb.get_member_particle_indexes()
1128 
1129  rbindexes = list(
1130  set(rbindexes) - set(hierarchies_excluded_from_collision_indexes))
1131  otherparticleindexes = list(
1132  set(allparticleindexes) - set(rbindexes))
1133 
1134  if len(otherparticleindexes) is None:
1135  continue
1136 
1137  niter = 0
1138  while niter < niterations:
1139  rbxyz = (rb.get_x(), rb.get_y(), rb.get_z())
1140 
1141  if not bounding_box is None:
1142  # overrides the perturbation
1143  translation = IMP.algebra.get_random_vector_in(bb)
1145  transformation = IMP.algebra.Transformation3D(
1146  rotation,
1147  translation)
1148  else:
1150  rbxyz,
1151  max_translation,
1152  max_rotation)
1153 
1154  IMP.core.transform(rb, transformation)
1155 
1156  if avoidcollision:
1157  self.m.update()
1158  npairs = len(
1159  gcpf.get_close_pairs(
1160  self.m,
1161  otherparticleindexes,
1162  rbindexes))
1163  if npairs == 0:
1164  niter = niterations
1165  else:
1166  niter += 1
1167  print("shuffle_configuration: rigid body placed close to other %d particles, trying again..." % npairs)
1168  print("shuffle_configuration: rigid body name: " + rb.get_name())
1169  if niter == niterations:
1170  raise ValueError("tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1171  else:
1172  break
1173 
1174  print('shuffling', len(self.floppy_bodies), 'floppy bodies')
1175  for fb in self.floppy_bodies:
1176  if avoidcollision:
1179  if rm and nrm:
1180  fbindexes = IMP.get_indexes([fb])
1181  otherparticleindexes = list(
1182  set(allparticleindexes) - set(fbindexes))
1183  if len(otherparticleindexes) is None:
1184  continue
1185  else:
1186  continue
1187 
1188  niter = 0
1189  while niter < niterations:
1190  fbxyz = IMP.core.XYZ(fb).get_coordinates()
1191  if not bounding_box is None:
1192  # overrides the perturbation
1193  translation = IMP.algebra.get_random_vector_in(bb)
1194  transformation = IMP.algebra.Transformation3D(translation)
1195  else:
1197  fbxyz,
1198  max_translation,
1199  max_rotation)
1200 
1201  IMP.core.transform(IMP.core.XYZ(fb), transformation)
1202 
1203  if avoidcollision:
1204  self.m.update()
1205  npairs = len(
1206  gcpf.get_close_pairs(
1207  self.m,
1208  otherparticleindexes,
1209  fbindexes))
1210  if npairs == 0:
1211  niter = niterations
1212  else:
1213  niter += 1
1214  print("shuffle_configuration: floppy body placed close to other %d particles, trying again..." % npairs)
1215  if niter == niterations:
1216  raise ValueError("tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1217  else:
1218  break
1219 
1220  def set_current_coordinates_as_reference_for_rmsd(self, label="None"):
1221  # getting only coordinates from pdb
1222  ps = IMP.pmi.tools.select(self, resolution=1.0)
1223  # storing the reference coordinates and the particles
1224  self.reference_structures[label] = (
1225  [IMP.core.XYZ(p).get_coordinates() for p in ps],
1226  ps)
1227 
1228  def get_all_rmsds(self):
1229  rmsds = {}
1230 
1231  for label in self.reference_structures:
1232 
1233  current_coordinates = [IMP.core.XYZ(p).get_coordinates()
1234  for p in self.reference_structures[label][1]]
1235  reference_coordinates = self.reference_structures[label][0]
1236  if len(reference_coordinates) != len(current_coordinates):
1237  print("calculate_all_rmsds: reference and actual coordinates are not the same")
1238  continue
1240  current_coordinates,
1241  reference_coordinates)
1242  rmsd_global = IMP.algebra.get_rmsd(
1243  reference_coordinates,
1244  current_coordinates)
1245  # warning: temporary we are calculating the drms, and not the rmsd,
1246  # for the relative distance
1247  rmsd_relative = IMP.atom.get_drms(
1248  reference_coordinates,
1249  current_coordinates)
1250  rmsds[label + "_GlobalRMSD"] = rmsd_global
1251  rmsds[label + "_RelativeDRMS"] = rmsd_relative
1252  return rmsds
1253 
1254  def setup_component_geometry(self, name, color=None, resolution=1.0):
1255  if color is None:
1256  color = self.color_dict[name]
1257  # this function stores all particle pairs
1258  # ordered by residue number, to be used
1259  # to construct backbone traces
1260  self.hier_geometry_pairs[name] = []
1261  protein_h = self.hier_dict[name]
1262  pbr = IMP.pmi.tools.select(self, name=name, resolution=resolution)
1263  pbr = IMP.pmi.tools.sort_by_residues(pbr)
1264 
1265  for n in range(len(pbr) - 1):
1266  self.hier_geometry_pairs[name].append((pbr[n], pbr[n + 1], color))
1267 
1269  self, name, resolution=10, scale=1.0):
1270  '''
1271  Generate restraints between contiguous fragments in the hierarchy.
1272  The linkers are generated at resolution 10 by default.
1273 
1274  '''
1275 
1276  unmodeledregions_cr = IMP.RestraintSet(self.m, "unmodeledregions")
1277  sortedsegments_cr = IMP.RestraintSet(self.m, "sortedsegments")
1278 
1279  protein_h = self.hier_dict[name]
1280  SortedSegments = []
1281  frs = self.hier_db.get_preroot_fragments_by_resolution(
1282  name,
1283  resolution)
1284 
1285  for fr in frs:
1286  try:
1287  start = fr.get_children()[0]
1288  except:
1289  start = fr
1290 
1291  try:
1292  end = fr.get_children()[-1]
1293  except:
1294  end = fr
1295 
1296  startres = IMP.pmi.tools.get_residue_indexes(start)[0]
1297  endres = IMP.pmi.tools.get_residue_indexes(end)[-1]
1298  SortedSegments.append((start, end, startres))
1299  SortedSegments = sorted(SortedSegments, key=itemgetter(2))
1300 
1301  # connect the particles
1302  for x in range(len(SortedSegments) - 1):
1303  last = SortedSegments[x][1]
1304  first = SortedSegments[x + 1][0]
1305 
1306  nreslast = len(IMP.pmi.tools.get_residue_indexes(last))
1307  lastresn = IMP.pmi.tools.get_residue_indexes(last)[-1]
1308  nresfirst = len(IMP.pmi.tools.get_residue_indexes(first))
1309  firstresn = IMP.pmi.tools.get_residue_indexes(first)[0]
1310 
1311  residuegap = firstresn - lastresn - 1
1312  if self.disorderedlength and (nreslast / 2 + nresfirst / 2 + residuegap) > 20.0:
1313  # calculate the distance between the sphere centers using Kohn
1314  # PNAS 2004
1315  optdist = sqrt(5 / 3) * 1.93 * \
1316  (nreslast / 2 + nresfirst / 2 + residuegap) ** 0.6
1317  # optdist2=sqrt(5/3)*1.93*((nreslast)**0.6+(nresfirst)**0.6)/2
1318  if self.upperharmonic:
1319  hu = IMP.core.HarmonicUpperBound(optdist, self.kappa)
1320  else:
1321  hu = IMP.core.Harmonic(optdist, self.kappa)
1322  dps = IMP.core.DistancePairScore(hu)
1323  else: # default
1324  optdist = (0.0 + (float(residuegap) + 1.0) * 3.6) * scale
1325  if self.upperharmonic: # default
1326  hu = IMP.core.HarmonicUpperBound(optdist, self.kappa)
1327  else:
1328  hu = IMP.core.Harmonic(optdist, self.kappa)
1330 
1331  pt0 = last.get_particle()
1332  pt1 = first.get_particle()
1333  r = IMP.core.PairRestraint(dps, IMP.ParticlePair(pt0, pt1))
1334 
1335  print("Adding sequence connectivity restraint between", pt0.get_name(), " and ", pt1.get_name(), 'of distance', optdist)
1336  sortedsegments_cr.add_restraint(r)
1337  self.linker_restraints_dict[
1338  "LinkerRestraint-" + pt0.get_name() + "-" + pt1.get_name()] = r
1339  self.connected_intra_pairs.append((pt0, pt1))
1340  self.connected_intra_pairs.append((pt1, pt0))
1341 
1342  self.m.add_restraint(sortedsegments_cr)
1343  self.m.add_restraint(unmodeledregions_cr)
1344  self.linker_restraints.add_restraint(sortedsegments_cr)
1345  self.linker_restraints.add_restraint(unmodeledregions_cr)
1346  self.sortedsegments_cr_dict[name] = sortedsegments_cr
1347  self.unmodeledregions_cr_dict[name] = unmodeledregions_cr
1348 
1349  def optimize_floppy_bodies(self, nsteps, temperature=1.0):
1350  import IMP.pmi.samplers
1351  pts = IMP.pmi.tools.ParticleToSampleList()
1352  for n, fb in enumerate(self.floppy_bodies):
1353  pts.add_particle(fb, "Floppy_Bodies", 1.0, "Floppy_Body_" + str(n))
1354  if len(pts.get_particles_to_sample()) > 0:
1355  mc = IMP.pmi.samplers.MonteCarlo(self.m, [pts], temperature)
1356  print("optimize_floppy_bodies: optimizing %i floppy bodies" % len(self.floppy_bodies))
1357  mc.optimize(nsteps)
1358  else:
1359  print("optimize_floppy_bodies: no particle to optimize")
1360 
1361  def create_rotational_symmetry(self, maincopy, copies):
1362  from math import pi
1363  self.representation_is_modified = True
1364  ncopies = len(copies) + 1
1365 
1366  sel = IMP.atom.Selection(self.prot, molecule=maincopy)
1367  mainparticles = sel.get_selected_particles()
1368 
1369  for k in range(len(copies)):
1371  IMP.algebra.Vector3D(0, 0, 1), 2 * pi / ncopies * (k + 1))
1372  sm = IMP.core.TransformationSymmetry(rotation3D)
1373 
1374  sel = IMP.atom.Selection(self.prot, molecule=copies[k])
1375  copyparticles = sel.get_selected_particles()
1376 
1377  mainpurged = []
1378  copypurged = []
1379  for n, p in enumerate(mainparticles):
1380 
1381  pc = copyparticles[n]
1382 
1383  mainpurged.append(p)
1385 
1386  copypurged.append(pc)
1388 
1390  for n, p in enumerate(mainpurged):
1391 
1392  pc = copypurged[n]
1393  print("setting " + p.get_name() + " as reference for " + pc.get_name())
1394 
1396  lc.add_particle(pc)
1397 
1398  c = IMP.container.SingletonsConstraint(sm, None, lc)
1399  self.m.add_score_state(c)
1400 
1401  self.m.update()
1402 
1403  def create_amyloid_fibril_symmetry(self, maincopy, axial_copies,
1404  longitudinal_copies, axis=(0, 0, 1), translation_value=4.8):
1405 
1406  from math import pi
1407  self.representation_is_modified = True
1408 
1409  outhiers = []
1410  protein_h = self.hier_dict[maincopy]
1411  mainparts = IMP.atom.get_leaves(protein_h)
1412 
1413  for ilc in range(-longitudinal_copies, longitudinal_copies + 1):
1414  for iac in range(axial_copies):
1415  copyname = maincopy + "_a" + str(ilc) + "_l" + str(iac)
1416  self.add_component_name(copyname, 0.0)
1417  for hier in protein_h.get_children():
1418  self.add_component_hierarchy_clone(copyname, hier)
1419  copyhier = self.hier_dict[copyname]
1420  outhiers.append(copyhier)
1421  copyparts = IMP.atom.get_leaves(copyhier)
1423  IMP.algebra.Vector3D(axis),
1424  2 * pi / axial_copies * (float(iac)))
1425  translation_vector = tuple(
1426  [translation_value * float(ilc) * x for x in axis])
1427  print(translation_vector)
1428  translation = IMP.algebra.Vector3D(translation_vector)
1430  IMP.algebra.Transformation3D(rotation3D, translation))
1432  for n, p in enumerate(mainparts):
1433  pc = copyparts[n]
1436  if not IMP.pmi.Symmetric.get_is_setup(pc):
1439  lc.add_particle(pc)
1440  c = IMP.container.SingletonsConstraint(sm, None, lc)
1441  self.m.add_score_state(c)
1442  self.m.update()
1443  return outhiers
1444 
1445  def link_components_to_rmf(self, rmfname, frameindex):
1446  '''
1447  Load coordinates in the current representation.
1448  This should be done only if the hierarchy self.prot is identical
1449  to the one as stored in the rmf i.e. all components were added.
1450  '''
1451  import IMP.rmf
1452  import RMF
1453 
1454  rh = RMF.open_rmf_file_read_only(rmfname)
1455  IMP.rmf.link_hierarchies(rh, [self.prot])
1456  IMP.rmf.load_frame(rh, frameindex)
1457  del rh
1458 
1459  def create_components_from_rmf(self, rmfname, frameindex):
1460  '''
1461  still not working.
1462  create the representation (i.e. hierarchies) from the rmf file.
1463  it will be stored in self.prot, which will be overwritten.
1464  load the coordinates from the rmf file at frameindex.
1465  '''
1466  rh = RMF.open_rmf_file(rmfname)
1467  self.prot = IMP.rmf.create_hierarchies(rh, self.m)[0]
1469  IMP.rmf.link_hierarchies(rh, [self.prot])
1470  IMP.rmf.load_frame(rh, frameindex)
1471  del rh
1472  for p in self.prot.get_children():
1473  self.add_component_name(p.get_name())
1474  self.hier_dict[p.get_name()] = p
1475  '''
1476  still missing: save rigid bodies contained in the rmf in self.rigid_bodies
1477  save floppy bodies in self.floppy_bodies
1478  get the connectivity restraints
1479  '''
1480 
1481  def set_rigid_body_from_hierarchies(self, hiers, particles=None):
1482  '''
1483  Construct a rigid body from hierarchies (and optionally particles).
1484 
1485  @param hiers list of hierarchies to make rigid
1486  @parm particles list of particles to add to the rigid body
1487  '''
1488 
1489  if particles is None:
1490  rigid_parts = set()
1491  else:
1492  rigid_parts = set(particles)
1493 
1494  name = ""
1495  print("set_rigid_body_from_hierarchies> setting up a new rigid body")
1496  for hier in hiers:
1497  ps = IMP.atom.get_leaves(hier)
1498 
1499  for p in ps:
1501  rb = IMP.core.RigidMember(p).get_rigid_body()
1502  print("set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1503  else:
1504  rigid_parts.add(p)
1505  name += hier.get_name() + "-"
1506  print("set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
1507 
1508  if len(list(rigid_parts)) != 0:
1509  rb = IMP.atom.create_rigid_body(list(rigid_parts))
1510  rb.set_coordinates_are_optimized(True)
1511  rb.set_name(name + "rigid_body")
1512  self.rigid_bodies.append(rb)
1513  return rb
1514 
1515  else:
1516  print("set_rigid_body_from_hierarchies> rigid body could not be setup")
1517 
1518  def set_rigid_bodies(self, subunits):
1519  '''
1520  Construct a rigid body from a list of subunits.
1521 
1522  Each subunit is a tuple that identifies the residue ranges and the
1523  component name (as used in create_component()).
1524 
1525  subunits: [(name_1,(first_residue_1,last_residue_1)),(name_2,(first_residue_2,last_residue_2)),.....]
1526  or
1527  [name_1,name_2,(name_3,(first_residue_3,last_residue_3)),.....]
1528 
1529  example: ["prot1","prot2",("prot3",(1,10))]
1530 
1531  sometimes, we know about structure of an interaction
1532  and here we make such PPIs rigid
1533  '''
1534 
1535  rigid_parts = set()
1536  for s in subunits:
1537  if type(s) == type(tuple()) and len(s) == 2:
1538  sel = IMP.atom.Selection(
1539  self.prot,
1540  molecule=s[0],
1541  residue_indexes=list(range(s[1][0],
1542  s[1][1] + 1)))
1543  if len(sel.get_selected_particles()) == 0:
1544  print("set_rigid_bodies: selected particle does not exists")
1545  for p in sel.get_selected_particles():
1546  # if not p in self.floppy_bodies:
1548  rb = IMP.core.RigidMember(p).get_rigid_body()
1549  print("set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1550  else:
1551  rigid_parts.add(p)
1552 
1553  elif type(s) == type(str()):
1554  sel = IMP.atom.Selection(self.prot, molecule=s)
1555  if len(sel.get_selected_particles()) == 0:
1556  print("set_rigid_bodies: selected particle does not exists")
1557  for p in sel.get_selected_particles():
1558  # if not p in self.floppy_bodies:
1560  rb = IMP.core.RigidMember(p).get_rigid_body()
1561  print("set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1562  else:
1563  rigid_parts.add(p)
1564 
1565  rb = IMP.atom.create_rigid_body(list(rigid_parts))
1566  rb.set_coordinates_are_optimized(True)
1567  rb.set_name(''.join(str(subunits)) + "_rigid_body")
1568  self.rigid_bodies.append(rb)
1569  return rb
1570 
1571  def set_super_rigid_body_from_hierarchies(
1572  self,
1573  hiers,
1574  axis=None,
1575  min_size=0):
1576  # axis is the rotation axis for 2D rotation
1577  super_rigid_xyzs = set()
1578  super_rigid_rbs = set()
1579  name = ""
1580  print("set_super_rigid_body_from_hierarchies> setting up a new SUPER rigid body")
1581 
1582  for hier in hiers:
1583  ps = IMP.atom.get_leaves(hier)
1584  for p in ps:
1586  rb = IMP.core.RigidMember(p).get_rigid_body()
1587  super_rigid_rbs.add(rb)
1588  else:
1589  super_rigid_xyzs.add(p)
1590  print("set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
1591  if len(super_rigid_rbs) < min_size:
1592  return
1593  if axis is None:
1594  self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
1595  else:
1596  # these will be 2D rotation SRB
1597  self.super_rigid_bodies.append(
1598  (super_rigid_xyzs, super_rigid_rbs, axis))
1599 
1600  def fix_rigid_bodies(self, rigid_bodies):
1601  self.fixed_rigid_bodies += rigid_bodies
1602 
1603 
1605  self, hiers, min_length=None, max_length=None, axis=None):
1606  '''
1607  Make a chain of super rigid bodies from a list of hierarchies.
1608 
1609  Takes a linear list of hierarchies (they are supposed to be
1610  sequence-contiguous) and produces a chain of super rigid bodies
1611  with given length range, specified by min_length and max_length.
1612  '''
1613  try:
1614  hiers = IMP.pmi.tools.flatten_list(hiers)
1615  except:
1616  pass
1617  for hs in IMP.pmi.tools.sublist_iterator(hiers, min_length, max_length):
1618  self.set_super_rigid_body_from_hierarchies(hs, axis, min_length)
1619 
1620  def set_super_rigid_bodies(self, subunits, coords=None):
1621  super_rigid_xyzs = set()
1622  super_rigid_rbs = set()
1623 
1624  for s in subunits:
1625  if type(s) == type(tuple()) and len(s) == 3:
1626  sel = IMP.atom.Selection(
1627  self.prot,
1628  molecule=s[2],
1629  residue_indexes=list(range(s[0],
1630  s[1] + 1)))
1631  if len(sel.get_selected_particles()) == 0:
1632  print("set_rigid_bodies: selected particle does not exists")
1633  for p in sel.get_selected_particles():
1635  rb = IMP.core.RigidMember(p).get_rigid_body()
1636  super_rigid_rbs.add(rb)
1637  else:
1638  super_rigid_xyzs.add(p)
1639  elif type(s) == type(str()):
1640  sel = IMP.atom.Selection(self.prot, molecule=s)
1641  if len(sel.get_selected_particles()) == 0:
1642  print("set_rigid_bodies: selected particle does not exists")
1643  for p in sel.get_selected_particles():
1644  # if not p in self.floppy_bodies:
1646  rb = IMP.core.RigidMember(p).get_rigid_body()
1647  super_rigid_rbs.add(rb)
1648  else:
1649  super_rigid_xyzs.add(p)
1650  self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
1651 
1652  def remove_floppy_bodies(self, hierarchies):
1653  '''
1654  Remove leaves of hierarchies from the floppy bodies list.
1655 
1656  Given a list of hierarchies, get the leaves and remove the
1657  corresponding particles from the floppy bodies list. We need this
1658  function because sometimes
1659  we want to constrain the floppy bodies in a rigid body - for instance
1660  when you want to associate a bead with a density particle.
1661  '''
1662  for h in hierarchies:
1663  ps = IMP.atom.get_leaves(h)
1664  for p in ps:
1665  if p in self.floppy_bodies:
1666  print("remove_floppy_bodies: removing %s from floppy body list" % p.get_name())
1667  self.floppy_bodies.remove(p)
1668 
1669 
1670  def set_floppy_bodies(self):
1671  for p in self.floppy_bodies:
1672  name = p.get_name()
1673  p.set_name(name + "_floppy_body")
1675  print("I'm trying to make this particle flexible although it was assigned to a rigid body", p.get_name())
1676  rb = IMP.core.RigidMember(p).get_rigid_body()
1677  try:
1678  rb.set_is_rigid_member(p.get_index(), False)
1679  except:
1680  # some IMP versions still work with that
1681  rb.set_is_rigid_member(p.get_particle_index(), False)
1682  p.set_name(p.get_name() + "_rigid_body_member")
1683 
1684  def set_floppy_bodies_from_hierarchies(self, hiers):
1685  for hier in hiers:
1686  ps = IMP.atom.get_leaves(hier)
1687  for p in ps:
1688  IMP.core.XYZ(p).set_coordinates_are_optimized(True)
1689  self.floppy_bodies.append(p)
1690 
1692  self,
1693  selection_tuples,
1694  resolution=None):
1695  '''
1696  selection tuples must be [(r1,r2,"name1"),(r1,r2,"name2"),....]
1697  @return the particles
1698  '''
1699  particles = []
1700  print(selection_tuples)
1701  for s in selection_tuples:
1702  ps = IMP.pmi.tools.select_by_tuple(
1703  representation=self, tupleselection=tuple(s),
1704  resolution=None, name_is_ambiguous=False)
1705  particles += ps
1706  return particles
1707 
1708  def get_connected_intra_pairs(self):
1709  return self.connected_intra_pairs
1710 
1711  def set_rigid_bodies_max_trans(self, maxtrans):
1712  self.maxtrans_rb = maxtrans
1713 
1714  def set_rigid_bodies_max_rot(self, maxrot):
1715  self.maxrot_rb = maxrot
1716 
1717  def set_super_rigid_bodies_max_trans(self, maxtrans):
1718  self.maxtrans_srb = maxtrans
1719 
1720  def set_super_rigid_bodies_max_rot(self, maxrot):
1721  self.maxrot_srb = maxrot
1722 
1723  def set_floppy_bodies_max_trans(self, maxtrans):
1724  self.maxtrans_fb = maxtrans
1725 
1726  def set_rigid_bodies_as_fixed(self, rigidbodiesarefixed=True):
1727  '''
1728  Fix rigid bodies in their actual position.
1729  The get_particles_to_sample() function will return
1730  just the floppy bodies.
1731  '''
1732  self.rigidbodiesarefixed = rigidbodiesarefixed
1733 
1734  def draw_hierarchy_graph(self):
1735  for c in IMP.atom.Hierarchy(self.prot).get_children():
1736  print("Drawing hierarchy graph for " + c.get_name())
1737  IMP.pmi.output.get_graph_from_hierarchy(c)
1738 
1739  def get_geometries(self):
1740  # create segments at the lowest resolution
1741  seggeos = []
1742  for name in self.hier_geometry_pairs:
1743  for pt in self.hier_geometry_pairs[name]:
1744  p1 = pt[0]
1745  p2 = pt[1]
1746  color = pt[2]
1747  try:
1748  clr = IMP.display.get_rgb_color(color)
1749  except:
1750  clr = IMP.display.get_rgb_color(1.0)
1751  coor1 = IMP.core.XYZ(p1).get_coordinates()
1752  coor2 = IMP.core.XYZ(p2).get_coordinates()
1753  seg = IMP.algebra.Segment3D(coor1, coor2)
1754  seggeos.append(IMP.display.SegmentGeometry(seg, clr))
1755  return seggeos
1756 
1757  def setup_bonds(self):
1758  # create segments at the lowest resolution
1759  seggeos = []
1760  for name in self.hier_geometry_pairs:
1761  for pt in self.hier_geometry_pairs[name]:
1762 
1763  p1 = pt[0]
1764  p2 = pt[1]
1765  if not IMP.atom.Bonded.get_is_setup(p1):
1767  if not IMP.atom.Bonded.get_is_setup(p2):
1769 
1771  IMP.atom.Bonded(p1),
1772  IMP.atom.Bonded(p2),
1773  1)
1774 
1775  def show_component_table(self, name):
1776  if name in self.sequence_dict:
1777  lastresn = len(self.sequence_dict[name])
1778  firstresn = 1
1779  else:
1780  residues = self.hier_db.get_residue_numbers(name)
1781  firstresn = min(residues)
1782  lastresn = max(residues)
1783 
1784  for nres in range(firstresn, lastresn + 1):
1785  try:
1786  resolutions = self.hier_db.get_residue_resolutions(name, nres)
1787  ps = []
1788  for r in resolutions:
1789  ps += self.hier_db.get_particles(name, nres, r)
1790  print("%20s %7s" % (name, nres), " ".join(["%20s %7s" % (str(p.get_name()),
1791  str(IMP.pmi.Resolution(p).get_resolution())) for p in ps]))
1792  except:
1793  print("%20s %20s" % (name, nres), "**** not represented ****")
1794 
1795  def draw_hierarchy_composition(self):
1796 
1797  ks = list(self.elements.keys())
1798  ks.sort()
1799 
1800  max = 0
1801  for k in self.elements:
1802  for l in self.elements[k]:
1803  if l[1] > max:
1804  max = l[1]
1805 
1806  for k in ks:
1807  self.draw_component_composition(k, max)
1808 
1809  def draw_component_composition(self, name, max=1000, draw_pdb_names=False):
1810  from matplotlib import pyplot
1811  import matplotlib as mpl
1812  k = name
1813  tmplist = sorted(self.elements[k], key=itemgetter(0))
1814  try:
1815  endres = tmplist[-1][1]
1816  except:
1817  print("draw_component_composition: missing information for component %s" % name)
1818  return
1819  fig = pyplot.figure(figsize=(26.0 * float(endres) / max + 2, 2))
1820  ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
1821 
1822  # Set the colormap and norm to correspond to the data for which
1823  # the colorbar will be used.
1824  cmap = mpl.cm.cool
1825  norm = mpl.colors.Normalize(vmin=5, vmax=10)
1826  bounds = [1]
1827  colors = []
1828 
1829  for n, l in enumerate(tmplist):
1830  firstres = l[0]
1831  lastres = l[1]
1832  if l[3] != "end":
1833  if bounds[-1] != l[0]:
1834  colors.append("white")
1835  bounds.append(l[0])
1836  if l[3] == "pdb":
1837  colors.append("#99CCFF")
1838  if l[3] == "bead":
1839  colors.append("#FFFF99")
1840  if l[3] == "helix":
1841  colors.append("#33CCCC")
1842  if l[3] != "end":
1843  bounds.append(l[1] + 1)
1844  else:
1845  if l[3] == "pdb":
1846  colors.append("#99CCFF")
1847  if l[3] == "bead":
1848  colors.append("#FFFF99")
1849  if l[3] == "helix":
1850  colors.append("#33CCCC")
1851  if l[3] != "end":
1852  bounds.append(l[1] + 1)
1853  else:
1854  if bounds[-1] - 1 == l[0]:
1855  bounds.pop()
1856  bounds.append(l[0])
1857  else:
1858  colors.append("white")
1859  bounds.append(l[0])
1860 
1861  bounds.append(bounds[-1])
1862  colors.append("white")
1863  cmap = mpl.colors.ListedColormap(colors)
1864  cmap.set_over('0.25')
1865  cmap.set_under('0.75')
1866 
1867  norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
1868  cb2 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
1869  norm=norm,
1870  # to use 'extend', you must
1871  # specify two extra boundaries:
1872  boundaries=bounds,
1873  ticks=bounds, # optional
1874  spacing='proportional',
1875  orientation='horizontal')
1876 
1877  extra_artists = []
1878  npdb = 0
1879 
1880  if draw_pdb_names:
1881  for l in tmplist:
1882  if l[3] == "pdb":
1883  npdb += 1
1884  mid = 1.0 / endres * float(l[0])
1885  # t =ax.text(mid, float(npdb-1)/2.0+1.5, l[2], ha="left", va="center", rotation=0,
1886  # size=10)
1887  # t=ax.annotate(l[0],2)
1888  t = ax.annotate(
1889  l[2], xy=(mid, 1), xycoords='axes fraction',
1890  xytext=(mid + 0.025, float(npdb - 1) / 2.0 + 1.5), textcoords='axes fraction',
1891  arrowprops=dict(arrowstyle="->",
1892  connectionstyle="angle,angleA=0,angleB=90,rad=10"),
1893  )
1894  extra_artists.append(t)
1895 
1896  # set the title of the bar
1897  title = ax.text(-0.005, 0.5, k, ha="right", va="center", rotation=90,
1898  size=20)
1899 
1900  extra_artists.append(title)
1901  # changing the xticks labels
1902  labels = len(bounds) * [" "]
1903  ax.set_xticklabels(labels)
1904  mid = 1.0 / endres * float(bounds[0])
1905  t = ax.annotate(bounds[0], xy=(mid, 0), xycoords='axes fraction',
1906  xytext=(mid - 0.01, -0.5), textcoords='axes fraction',)
1907  extra_artists.append(t)
1908  offsets = [0, -0.5, -1.0]
1909  nclashes = 0
1910  for n in range(1, len(bounds)):
1911  if bounds[n] == bounds[n - 1]:
1912  continue
1913  mid = 1.0 / endres * float(bounds[n])
1914  if (float(bounds[n]) - float(bounds[n - 1])) / max <= 0.01:
1915  nclashes += 1
1916  offset = offsets[nclashes % 3]
1917  else:
1918  nclashes = 0
1919  offset = offsets[0]
1920  if offset > -0.75:
1921  t = ax.annotate(
1922  bounds[n], xy=(mid, 0), xycoords='axes fraction',
1923  xytext=(mid, -0.5 + offset), textcoords='axes fraction')
1924  else:
1925  t = ax.annotate(
1926  bounds[n], xy=(mid, 0), xycoords='axes fraction',
1927  xytext=(mid, -0.5 + offset), textcoords='axes fraction', arrowprops=dict(arrowstyle="-"))
1928  extra_artists.append(t)
1929 
1930  cb2.add_lines(bounds, ["black"] * len(bounds), [1] * len(bounds))
1931  # cb2.set_label(k)
1932 
1933  pyplot.savefig(
1934  k + "structure.pdf",
1935  dpi=150,
1936  transparent="True",
1937  bbox_extra_artists=(extra_artists),
1938  bbox_inches='tight')
1939  pyplot.show()
1940 
1941  def draw_coordinates_projection(self):
1942  import matplotlib.pyplot as pp
1943  xpairs = []
1944  ypairs = []
1945  for name in self.hier_geometry_pairs:
1946  for pt in self.hier_geometry_pairs[name]:
1947  p1 = pt[0]
1948  p2 = pt[1]
1949  color = pt[2]
1950  coor1 = IMP.core.XYZ(p1).get_coordinates()
1951  coor2 = IMP.core.XYZ(p2).get_coordinates()
1952  x1 = coor1[0]
1953  x2 = coor2[0]
1954  y1 = coor1[1]
1955  y2 = coor2[1]
1956  xpairs.append([x1, x2])
1957  ypairs.append([y1, y2])
1958  xlist = []
1959  ylist = []
1960  for xends, yends in zip(xpairs, ypairs):
1961  xlist.extend(xends)
1962  xlist.append(None)
1963  ylist.extend(yends)
1964  ylist.append(None)
1965  pp.plot(xlist, ylist, 'b-', alpha=0.1)
1966  pp.show()
1967 
1968  def get_prot_name_from_particle(self, particle):
1969  names = self.get_component_names()
1970  particle0 = particle
1971  name = None
1972  while not name in names:
1973  h = IMP.atom.Hierarchy(particle0).get_parent()
1974  name = h.get_name()
1975  particle0 = h.get_particle()
1976  return name
1977 
1978 
1979  def get_particles_to_sample(self):
1980  # get the list of samplable particles with their type
1981  # and the mover displacement. Everything wrapped in a dictionary,
1982  # to be used by samplers modules
1983  ps = {}
1984 
1985  # remove symmetric particles: they are not sampled
1986  rbtmp = []
1987  fbtmp = []
1988  srbtmp = []
1989  if not self.rigidbodiesarefixed:
1990  for rb in self.rigid_bodies:
1992  if IMP.pmi.Symmetric(rb).get_symmetric() != 1:
1993  rbtmp.append(rb)
1994  else:
1995  if rb not in self.fixed_rigid_bodies:
1996  rbtmp.append(rb)
1997 
1998  for fb in self.floppy_bodies:
2000  if IMP.pmi.Symmetric(fb).get_symmetric() != 1:
2001  fbtmp.append(fb)
2002  else:
2003  fbtmp.append(fb)
2004 
2005  for srb in self.super_rigid_bodies:
2006  # going to prune the fixed rigid bodies out
2007  # of the super rigid body list
2008  rigid_bodies = list(srb[1])
2009  filtered_rigid_bodies = []
2010  for rb in rigid_bodies:
2011  if rb not in self.fixed_rigid_bodies:
2012  filtered_rigid_bodies.append(rb)
2013  srbtmp.append((srb[0], filtered_rigid_bodies))
2014 
2015  self.rigid_bodies = rbtmp
2016  self.floppy_bodies = fbtmp
2017  self.super_rigid_bodies = srbtmp
2018 
2019  ps["Rigid_Bodies_SimplifiedModel"] = (
2020  self.rigid_bodies,
2021  self.maxtrans_rb,
2022  self.maxrot_rb)
2023  ps["Floppy_Bodies_SimplifiedModel"] = (
2024  self.floppy_bodies,
2025  self.maxtrans_fb)
2026  ps["SR_Bodies_SimplifiedModel"] = (
2027  self.super_rigid_bodies,
2028  self.maxtrans_srb,
2029  self.maxrot_srb)
2030  return ps
2031 
2032  def set_output_level(self, level):
2033  self.output_level = level
2034 
2035  def get_output(self):
2036  output = {}
2037  score = 0.0
2038 
2039  output["SimplifiedModel_Total_Score_" +
2040  self.label] = str(self.m.evaluate(False))
2041  output["SimplifiedModel_Linker_Score_" +
2042  self.label] = str(self.linker_restraints.unprotected_evaluate(None))
2043  for name in self.sortedsegments_cr_dict:
2044  partialscore = self.sortedsegments_cr_dict[name].evaluate(False)
2045  score += partialscore
2046  output[
2047  "SimplifiedModel_Link_SortedSegments_" +
2048  name +
2049  "_" +
2050  self.label] = str(
2051  partialscore)
2052  partialscore = self.unmodeledregions_cr_dict[name].evaluate(False)
2053  score += partialscore
2054  output[
2055  "SimplifiedModel_Link_UnmodeledRegions_" +
2056  name +
2057  "_" +
2058  self.label] = str(
2059  partialscore)
2060  for name in self.linker_restraints_dict:
2061  output[
2062  name +
2063  "_" +
2064  self.label] = str(
2065  self.linker_restraints_dict[
2066  name].unprotected_evaluate(
2067  None))
2068 
2069  if len(self.reference_structures.keys()) != 0:
2070  rmsds = self.get_all_rmsds()
2071  for label in rmsds:
2072  output[
2073  "SimplifiedModel_" +
2074  label +
2075  "_" +
2076  self.label] = rmsds[
2077  label]
2078 
2079  if self.output_level == "high":
2080  for p in IMP.atom.get_leaves(self.prot):
2081  d = IMP.core.XYZR(p)
2082  output["Coordinates_" +
2083  p.get_name() + "_" + self.label] = str(d)
2084 
2085  output["_TotalScore"] = str(score)
2086  return output
2087 
2088  def get_test_output(self):
2089  # this method is called by test functions and return an enriched output
2090  output = self.get_output()
2091  for n, p in enumerate(self.get_particles_to_sample()):
2092  output["Particle_to_sample_" + str(n)] = str(p)
2093  output["Number_of_particles"] = len(IMP.atom.get_leaves(self.prot))
2094  output["Hierarchy_Dictionary"] = list(self.hier_dict.keys())
2095  output["Number_of_floppy_bodies"] = len(self.floppy_bodies)
2096  output["Number_of_rigid_bodies"] = len(self.rigid_bodies)
2097  output["Number_of_super_bodies"] = len(self.super_rigid_bodies)
2098  output["Selection_resolution_1"] = len(
2099  IMP.pmi.tools.select(self, resolution=1))
2100  output["Selection_resolution_5"] = len(
2101  IMP.pmi.tools.select(self, resolution=5))
2102  output["Selection_resolution_7"] = len(
2103  IMP.pmi.tools.select(self, resolution=5))
2104  output["Selection_resolution_10"] = len(
2105  IMP.pmi.tools.select(self, resolution=10))
2106  output["Selection_resolution_100"] = len(
2107  IMP.pmi.tools.select(self, resolution=100))
2108  output["Selection_All"] = len(IMP.pmi.tools.select(self))
2109  output["Selection_resolution=1"] = len(
2110  IMP.pmi.tools.select(self, resolution=1))
2111  output["Selection_resolution=1,resid=10"] = len(
2112  IMP.pmi.tools.select(self, resolution=1, residue=10))
2113  for resolution in self.hier_resolution:
2114  output["Hier_resolution_dictionary" +
2115  str(resolution)] = len(self.hier_resolution[resolution])
2116  for name in self.hier_dict:
2117  output[
2118  "Selection_resolution=1,resid=10,name=" +
2119  name] = len(
2121  self,
2122  resolution=1,
2123  name=name,
2124  residue=10))
2125  output[
2126  "Selection_resolution=1,resid=10,name=" +
2127  name +
2128  ",ambiguous"] = len(
2130  self,
2131  resolution=1,
2132  name=name,
2133  name_is_ambiguous=True,
2134  residue=10))
2135  output[
2136  "Selection_resolution=1,resid=10,name=" +
2137  name +
2138  ",ambiguous"] = len(
2140  self,
2141  resolution=1,
2142  name=name,
2143  name_is_ambiguous=True,
2144  residue=10))
2145  output[
2146  "Selection_resolution=1,resrange=(10,20),name=" +
2147  name] = len(
2149  self,
2150  resolution=1,
2151  name=name,
2152  first_residue=10,
2153  last_residue=20))
2154  output[
2155  "Selection_resolution=1,resrange=(10,20),name=" +
2156  name +
2157  ",ambiguous"] = len(
2159  self,
2160  resolution=1,
2161  name=name,
2162  name_is_ambiguous=True,
2163  first_residue=10,
2164  last_residue=20))
2165  output[
2166  "Selection_resolution=10,resrange=(10,20),name=" +
2167  name] = len(
2169  self,
2170  resolution=10,
2171  name=name,
2172  first_residue=10,
2173  last_residue=20))
2174  output[
2175  "Selection_resolution=10,resrange=(10,20),name=" +
2176  name +
2177  ",ambiguous"] = len(
2179  self,
2180  resolution=10,
2181  name=name,
2182  name_is_ambiguous=True,
2183  first_residue=10,
2184  last_residue=20))
2185  output[
2186  "Selection_resolution=100,resrange=(10,20),name=" +
2187  name] = len(
2189  self,
2190  resolution=100,
2191  name=name,
2192  first_residue=10,
2193  last_residue=20))
2194  output[
2195  "Selection_resolution=100,resrange=(10,20),name=" +
2196  name +
2197  ",ambiguous"] = len(
2199  self,
2200  resolution=100,
2201  name=name,
2202  name_is_ambiguous=True,
2203  first_residue=10,
2204  last_residue=20))
2205 
2206  return output
2207 
2208 
2209 # Deprecation warning for the old SimplifiedModel class
2210 
2211 class SimplifiedModel(Representation):
2212 
2213  def __init__(self, *args, **kwargs):
2214  Representation.__init__(self, *args, **kwargs)
2215  IMP.pmi.tools.print_deprecation_warning(
2216  "SimplifiedModel",
2217  "Representation")
static Residue setup_particle(kernel::Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
Definition: Residue.h:157
def link_components_to_rmf
Load coordinates in the current representation.
Select non water and non hydrogen atoms.
Definition: pdb.h:197
def list_chunks_iterator
Yield successive length-sized chunks from a list.
Definition: tools.py:1045
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.
Simple 3D transformation class.
A base class for Keys.
Definition: kernel/Key.h:46
atom::Hierarchies create_hierarchies(RMF::FileConstHandle fh, kernel::Model *m)
A decorator to associate a particle with a part of a protein/DNA/RNA.
Definition: Fragment.h:20
void show_molecular_hierarchy(Hierarchy h)
Print out the molecular hierarchy.
double get_drms(const Vector3DsOrXYZs0 &m1, const Vector3DsOrXYZs1 &m2)
Apply a SingletonFunction to a SingletonContainer to maintain an invariant.
Ints get_index(const kernel::ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
Set the coordinates of a particle to be a transformed version of a reference.
Definition: core/symmetry.h:75
Store the representations for a system.
Definition: tools.py:762
def shuffle_configuration
Shuffle configuration; used to restart the optimization.
static Atom setup_particle(kernel::Model *m, ParticleIndex pi, Atom other)
Definition: atom/Atom.h:242
Upper bound harmonic function (non-zero when feature > mean)
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p)
Definition: Gaussian.h:47
def set_coordinates_from_rmf
Read and replace coordinates from an RMF file.
A decorator for a particle which has bonds.
Select atoms which are selected by both selectors.
Definition: pdb.h:275
Hierarchy create_clone(Hierarchy d)
Clone the Hierarchy.
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.
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
double get_resolution(kernel::Model *m, kernel::ParticleIndex pi)
Object used to hold a set of restraints.
Low level functionality (logging, error handling, profiling, command line flags etc) that is used by ...
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
static XYZ setup_particle(kernel::Model *m, ParticleIndex pi)
Definition: XYZ.h:51
def setup_component_sequence_connectivity
Generate restraints between contiguous fragments in the hierarchy.
void load_frame(RMF::FileConstHandle file, unsigned int frame)
Definition: frames.h:27
Add uncertainty to a particle.
Definition: Uncertainty.h:24
A score on the distance between the surfaces of two spheres.
def get_prot_name_from_particle
Return the component name provided a particle and a list of names.
Definition: tools.py:910
def get_residue_gaps_in_hierarchy
Return the residue index gaps and contiguous segments in the hierarchy.
Definition: tools.py:556
def remove_floppy_bodies
Remove leaves of hierarchies from the floppy bodies list.
static Resolution setup_particle(kernel::Model *m, ParticleIndex pi, Float resolution)
Definition: Resolution.h:45
Vector3D get_random_vector_in(const Cylinder3D &c)
Generate a random vector in a cylinder with uniform density.
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p)
Definition: rigid_bodies.h:500
A reference frame in 3D.
Add resolution to a particle.
Definition: Resolution.h:24
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p)
Bond create_bond(Bonded a, Bonded b, Bond o)
Connect the two wrapped particles by a custom bond.
Rotation3D get_rotation_about_axis(const Vector3D &axis, double angle)
Generate a Rotation3D object from a rotation around an axis.
static Reference setup_particle(kernel::Model *m, ParticleIndex pi, kernel::ParticleIndexAdaptor reference)
Definition: core/symmetry.h:31
A class to store an fixed array of same-typed values.
Definition: Array.h:33
Select all CB ATOM records.
Definition: pdb.h:90
A Gaussian distribution in 3D.
Definition: Gaussian3D.h:24
static XYZR setup_particle(kernel::Model *m, ParticleIndex pi)
Definition: XYZR.h:48
static Bonded setup_particle(kernel::Model *m, ParticleIndex pi)
static Molecule setup_particle(kernel::Model *m, ParticleIndex pi)
Definition: Molecule.h:37
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.
static Hierarchy setup_particle(kernel::Model *m, kernel::ParticleIndex pi, kernel::ParticleIndexesAdaptor children=kernel::ParticleIndexesAdaptor())
Store a kernel::ParticleIndexes.
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.
Hierarchies get_by_type(Hierarchy mhd, GetByType t)
static Colored setup_particle(kernel::Model *m, ParticleIndex pi, Color color)
Definition: Colored.h:62
The type for a residue.
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Symmetric.h:29
double get_rmsd(const Vector3DsOrXYZs0 &m1, const Vector3DsOrXYZs1 &m2)
def add_all_atom_densities
Decorates all specified particles as Gaussians directly.
def coarse_hierarchy
Generate all needed coarse grained layers.
def add_component_pdb
Add a component that has an associated 3D structure in a PDB file.
Basic utilities for handling cryo-electron microscopy 3D density maps.
Hierarchy create_clone_one(Hierarchy d)
Clone the node in the Hierarchy.
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
static Chain setup_particle(kernel::Model *m, ParticleIndex pi, std::string id)
Definition: Chain.h:41
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Resolution.h:30
Class to handle individual model particles.
def set_chain_of_super_rigid_bodies
Make a chain of super rigid bodies from a list of hierarchies.
static Uncertainty setup_particle(kernel::Model *m, ParticleIndex pi, Float uncertainty)
Definition: Uncertainty.h:45
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:62
Tools for clustering and cluster analysis.
Definition: pmi/Analysis.py:1
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:493
static Mass setup_particle(kernel::Model *m, ParticleIndex pi, Float mass)
Definition: Mass.h:44
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
A decorator for a residue.
Definition: Residue.h:134
Sampling of the system.
Definition: samplers.py:1
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p)
Definition: XYZ.h:49
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...
def add_component_density
Sets up a Gaussian Mixture Model for this component.
static bool get_is_setup(kernel::Model *m, kernel::ParticleIndex pi)
Definition: Fragment.h:46
Sample using Monte Carlo.
Definition: samplers.py:33
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p)
Definition: rigid_bodies.h:479
Hierarchy create_simplified_along_backbone(Chain input, const IntRanges &residue_segments, bool keep_detailed=false)
VectorD< 3 > Vector3D
Definition: VectorD.h:395
IMP::core::RigidBody create_rigid_body(Hierarchy h)
Rotation3D get_identity_rotation_3d()
Return a rotation that does not do anything.
Definition: Rotation3D.h:236
void link_hierarchies(RMF::FileConstHandle fh, const atom::Hierarchies &hs)
std::string get_data_path(std::string file_name)
Return the full path to installed data.
Select atoms which are selected by either selector.
Definition: pdb.h:293
static Fragment setup_particle(kernel::Model *m, ParticleIndex pi)
Definition: Fragment.h:63
def get_hierarchies_at_given_resolution
Get the hierarchies at the given resolution.
Store info for a chain of a protein.
Definition: Chain.h:21
Applies a PairScore to a Pair.
Definition: PairRestraint.h:29
def select
this function uses representation=SimplifiedModel it returns the corresponding selected particles rep...
Definition: tools.py:633
Select all CA ATOM records.
Definition: pdb.h:76
Python classes to represent, score, sample and analyze models.
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Uncertainty.h:30
Set up the representation of all proteins and nucleic acid macromolecules.
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.
void read_pdb(base::TextInput input, int model, Hierarchy h)
Hierarchies get_leaves(const Selection &h)
def add_component_necklace
Generates a string of beads with given length.
Select hierarchy particles identified by the biological name.
Definition: Selection.h:62
Select all ATOM and HETATM records with the given chain ids.
Definition: pdb.h:143
static Gaussian setup_particle(kernel::Model *m, ParticleIndex pi)
Definition: Gaussian.h:48
Support for the RMF file format for storing hierarchical molecular data and markup.
def set_rigid_body_from_hierarchies
Construct a rigid body from hierarchies (and optionally particles).
def decorate_gmm_from_text
read the output from write_gmm_to_text, decorate as Gaussian and Mass
Definition: gmm_tools.py:22
def get_residue_indexes
Retrieve the residue indexes for the given particle.
Definition: tools.py:930
Transformation3D get_random_local_transformation(Vector3D origin, double max_translation=5., double max_angle_in_rad=0.26)
Get a local transformation.
An exception for an invalid value being passed to IMP.
Definition: exception.h:137
def check_root
If the root hierarchy does not exist, construct it.
static Symmetric setup_particle(kernel::Model *m, ParticleIndex pi, Float symmetric)
Definition: Symmetric.h:44
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:1026
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